186 lines
4.7 KiB
Swift
186 lines
4.7 KiB
Swift
import Foundation
|
|
|
|
public struct AttachmentRecord: Codable, Identifiable {
|
|
public var id: String { hash }
|
|
public let hash: String
|
|
public let originalName: String
|
|
public let contentType: String
|
|
public let sizeBytes: Int
|
|
public let createdAt: Date
|
|
public let url: String
|
|
public let kind: String?
|
|
public let documentPath: String?
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case hash
|
|
case originalName
|
|
case contentType
|
|
case sizeBytes
|
|
case createdAt
|
|
case url
|
|
case kind
|
|
case documentPath
|
|
}
|
|
}
|
|
|
|
public struct UploadResponse: Codable {
|
|
public let hash: String
|
|
public let contentType: String
|
|
public let attachmentUrl: String
|
|
public let url: String?
|
|
public let kind: String?
|
|
}
|
|
|
|
public struct DocumentRecord: Codable, Identifiable {
|
|
public let id: String
|
|
public let path: String
|
|
public let title: String
|
|
public let hash: String
|
|
public let createdAt: Date?
|
|
public let updatedAt: Date?
|
|
}
|
|
|
|
public struct DocumentSaveRequest: Codable {
|
|
public let content: String
|
|
public let baseHash: String?
|
|
}
|
|
|
|
public struct DocumentSaveResponse: Codable {
|
|
public let status: String
|
|
public let path: String
|
|
public let title: String
|
|
public let hash: String
|
|
}
|
|
|
|
public struct SyncInitRequest: Codable {
|
|
public let deviceId: String
|
|
public let rootPath: String
|
|
}
|
|
|
|
public struct SyncInitResponse: Codable {
|
|
public let snapshotId: String
|
|
public let serverSnapshot: [FileEntry]
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case snapshotId
|
|
case serverSnapshot
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
snapshotId = try container.decode(String.self, forKey: .snapshotId)
|
|
serverSnapshot = try container.decodeIfPresent([FileEntry].self, forKey: .serverSnapshot) ?? []
|
|
}
|
|
}
|
|
|
|
public struct FileEntry: Codable {
|
|
public let path: String
|
|
public let hash: String
|
|
public let size: Int64
|
|
public let modified: Date
|
|
}
|
|
|
|
public struct DeltaRequest: Codable {
|
|
public let snapshotId: String
|
|
public let clientDelta: [Change]
|
|
}
|
|
|
|
public struct DeltaResponse: Codable {
|
|
public let serverDelta: [Change]
|
|
public let conflicts: [Conflict]
|
|
public let newSnapshotId: String?
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case serverDelta
|
|
case conflicts
|
|
case newSnapshotId
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
serverDelta = try container.decodeIfPresent([Change].self, forKey: .serverDelta) ?? []
|
|
conflicts = try container.decodeIfPresent([Conflict].self, forKey: .conflicts) ?? []
|
|
newSnapshotId = try container.decodeIfPresent(String.self, forKey: .newSnapshotId)
|
|
}
|
|
}
|
|
|
|
public struct Change: Codable {
|
|
public let type: String
|
|
public let path: String
|
|
public let oldPath: String?
|
|
public let hash: String?
|
|
public let content: String?
|
|
public let size: Int64?
|
|
public let modified: Date?
|
|
|
|
public init(
|
|
type: String,
|
|
path: String,
|
|
oldPath: String?,
|
|
hash: String?,
|
|
content: String? = nil,
|
|
size: Int64?,
|
|
modified: Date?
|
|
) {
|
|
self.type = type
|
|
self.path = path
|
|
self.oldPath = oldPath
|
|
self.hash = hash
|
|
self.content = content
|
|
self.size = size
|
|
self.modified = modified
|
|
}
|
|
}
|
|
|
|
public struct Conflict: Codable {
|
|
public let path: String
|
|
public let serverHash: String
|
|
public let clientHash: String
|
|
public let serverModified: Date
|
|
public let clientModified: Date
|
|
}
|
|
|
|
public struct APIError: Error, Codable {
|
|
public let error: String
|
|
public let conflictType: String?
|
|
public let existingHash: String?
|
|
public let existingPath: String?
|
|
public let existingUrl: String?
|
|
|
|
public init(
|
|
error: String,
|
|
conflictType: String? = nil,
|
|
existingHash: String? = nil,
|
|
existingPath: String? = nil,
|
|
existingUrl: String? = nil
|
|
) {
|
|
self.error = error
|
|
self.conflictType = conflictType
|
|
self.existingHash = existingHash
|
|
self.existingPath = existingPath
|
|
self.existingUrl = existingUrl
|
|
}
|
|
|
|
public var isUploadConflict: Bool {
|
|
conflictType == "document" || conflictType == "attachment"
|
|
}
|
|
}
|
|
|
|
extension APIError: LocalizedError {
|
|
public var errorDescription: String? { error }
|
|
}
|
|
|
|
public struct AttachmentsListResponse: Codable {
|
|
public let attachments: [AttachmentRecord]
|
|
}
|
|
|
|
public struct DocumentsListResponse: Codable {
|
|
public let documents: [DocumentRecord]
|
|
}
|
|
|
|
public enum UploadDuplicateAction: String {
|
|
case overwrite
|
|
case rename
|
|
case reuse
|
|
}
|