import Foundation struct IngestPayload: Equatable, Sendable { let url: String let title: String? let notes: String } enum IngestPayloadParser { static func parse(item: Any?, typeIdentifier: String? = nil) -> IngestPayload? { if let url = item as? URL { return payload(from: url.absoluteString, notes: "") } if let attributed = item as? NSAttributedString { return payload(from: attributed.string, notes: attributed.string) } if let string = item as? String { return payload(from: string, notes: shouldKeepNotes(for: typeIdentifier) ? string : "") } if let data = item as? Data, let string = String(data: data, encoding: .utf8) ?? String(data: data, encoding: .ascii) { return payload(from: string, notes: shouldKeepNotes(for: typeIdentifier) ? string : "") } return nil } private static func payload(from text: String, notes: String) -> IngestPayload? { guard let url = firstWebURL(in: text) else { return nil } return IngestPayload(url: url, title: nil, notes: cleanedNotes(notes, excluding: url)) } static func firstWebURL(in text: String) -> String? { if let direct = URL(string: text.trimmingCharacters(in: .whitespacesAndNewlines)), isBookmarkable(direct) { return direct.absoluteString } let decoded = decodeHTML(text) let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) let range = NSRange(decoded.startIndex..\"'.,;:)]】」")) guard let url = URL(string: candidate), isBookmarkable(url) else { return nil } return url.absoluteString } private static func isBookmarkable(_ url: URL) -> Bool { guard let scheme = url.scheme?.lowercased(), scheme == "http" || scheme == "https", url.host?.isEmpty == false else { return false } return true } private static func cleanedNotes(_ notes: String, excluding url: String) -> String { let trimmed = decodeHTML(notes) .replacingOccurrences(of: url, with: "") .components(separatedBy: .newlines) .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } .filter { !$0.isEmpty } .joined(separator: "\n") return String(trimmed.prefix(1800)) } private static func decodeHTML(_ text: String) -> String { text .replacingOccurrences(of: "&", with: "&") .replacingOccurrences(of: "<", with: "<") .replacingOccurrences(of: ">", with: ">") .replacingOccurrences(of: """, with: "\"") .replacingOccurrences(of: "'", with: "'") } private static func shouldKeepNotes(for typeIdentifier: String?) -> Bool { guard let typeIdentifier else { return true } return !typeIdentifier.lowercased().contains("url") } }