- API, Mac client

This commit is contained in:
Ty Clifford
2026-07-05 15:58:51 -04:00
parent 9dbd29d8aa
commit 729b29276f
14 changed files with 1682 additions and 1 deletions
@@ -0,0 +1,65 @@
import Foundation
struct DraftRecord: Codable, Identifiable {
var id: String { item.slug.isEmpty ? item.title : item.slug }
var serverURL: String
var savedAt: Date
var item: ContentItem
var markdown: String
}
final class DraftStore {
private let folder: URL
init() {
let base = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first
?? URL(fileURLWithPath: NSTemporaryDirectory())
folder = base.appendingPathComponent("TCMS Mac Client", isDirectory: true)
try? FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
}
func save(item: ContentItem, markdown: String, serverURL: String) throws {
let record = DraftRecord(serverURL: serverURL, savedAt: Date(), item: item, markdown: markdown)
let data = try JSONEncoder.tcms.encode(record)
try data.write(to: fileURL(for: record.id), options: .atomic)
}
func remove(id: String) {
try? FileManager.default.removeItem(at: fileURL(for: id))
}
func loadAll(serverURL: String) -> [DraftRecord] {
let urls = (try? FileManager.default.contentsOfDirectory(at: folder, includingPropertiesForKeys: nil)) ?? []
return urls.compactMap { url in
guard let data = try? Data(contentsOf: url),
let record = try? JSONDecoder.tcms.decode(DraftRecord.self, from: data),
record.serverURL == serverURL else {
return nil
}
return record
}
.sorted { $0.savedAt > $1.savedAt }
}
private func fileURL(for id: String) -> URL {
let safe = id.replacingOccurrences(of: "[^A-Za-z0-9._-]+", with: "-", options: .regularExpression)
return folder.appendingPathComponent(safe.isEmpty ? "untitled" : safe).appendingPathExtension("json")
}
}
private extension JSONEncoder {
static var tcms: JSONEncoder {
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
encoder.dateEncodingStrategy = .iso8601
return encoder
}
}
private extension JSONDecoder {
static var tcms: JSONDecoder {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
return decoder
}
}