- 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,194 @@
import Foundation
struct ContentItem: Codable, Identifiable, Hashable {
var id: String { slug.isEmpty ? title : slug }
var slug: String
var title: String
var type: String
var status: String
var date: String
var modified: String
var category: String
var tags: [String]
var summary: String
var author: String
var cover: String
var allowComments: Bool
var menuOrder: Int
var url: String
var excerpt: String
var markdown: String
init(
slug: String = "",
title: String = "Untitled",
type: String = "post",
status: String = "draft",
date: String = ISO8601DateFormatter().string(from: Date()),
modified: String = "",
category: String = "Notes",
tags: [String] = [],
summary: String = "",
author: String = "Editor",
cover: String = "",
allowComments: Bool = true,
menuOrder: Int = 0,
url: String = "",
excerpt: String = "",
markdown: String = "# Untitled\n\nStart writing here."
) {
self.slug = slug
self.title = title
self.type = type
self.status = status
self.date = date
self.modified = modified
self.category = category
self.tags = tags
self.summary = summary
self.author = author
self.cover = cover
self.allowComments = allowComments
self.menuOrder = menuOrder
self.url = url
self.excerpt = excerpt
self.markdown = markdown
}
enum CodingKeys: String, CodingKey {
case slug, title, type, status, date, modified, category, tags, summary, author, cover, url, excerpt, markdown
case allowComments = "allow_comments"
case menuOrder = "menu_order"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
slug = try container.decodeIfPresent(String.self, forKey: .slug) ?? ""
title = try container.decodeIfPresent(String.self, forKey: .title) ?? "Untitled"
type = try container.decodeIfPresent(String.self, forKey: .type) ?? "post"
status = try container.decodeIfPresent(String.self, forKey: .status) ?? "draft"
date = try container.decodeIfPresent(String.self, forKey: .date) ?? ""
modified = try container.decodeIfPresent(String.self, forKey: .modified) ?? ""
category = try container.decodeIfPresent(String.self, forKey: .category) ?? "Notes"
tags = try container.decodeIfPresent([String].self, forKey: .tags) ?? []
summary = try container.decodeIfPresent(String.self, forKey: .summary) ?? ""
author = try container.decodeIfPresent(String.self, forKey: .author) ?? "Editor"
cover = try container.decodeIfPresent(String.self, forKey: .cover) ?? ""
allowComments = try container.decodeIfPresent(Bool.self, forKey: .allowComments) ?? true
menuOrder = try container.decodeIfPresent(Int.self, forKey: .menuOrder) ?? 0
url = try container.decodeIfPresent(String.self, forKey: .url) ?? ""
excerpt = try container.decodeIfPresent(String.self, forKey: .excerpt) ?? ""
markdown = try container.decodeIfPresent(String.self, forKey: .markdown) ?? ""
}
}
struct ContentMetadata: Codable {
var title: String
var slug: String
var type: String
var status: String
var date: String
var category: String
var tags: [String]
var summary: String
var author: String
var cover: String
var allowComments: Bool
var menuOrder: Int
init(item: ContentItem) {
title = item.title
slug = item.slug
type = item.type
status = item.status
date = item.date
category = item.category
tags = item.tags
summary = item.summary
author = item.author
cover = item.cover
allowComments = item.allowComments
menuOrder = item.menuOrder
}
enum CodingKeys: String, CodingKey {
case title, slug, type, status, date, category, tags, summary, author, cover
case allowComments = "allow_comments"
case menuOrder = "menu_order"
}
}
struct MediaItem: Codable, Identifiable, Hashable {
var id: String { path }
var name: String
var path: String
var url: String
var size: Int
var modified: String
var mime: String
}
struct CommentItem: Codable, Identifiable, Hashable {
var id: Int
var slug: String
var author: String
var email: String
var website: String
var body: String
var status: String
var createdAt: String
var updatedAt: String
enum CodingKeys: String, CodingKey {
case id, slug, author, email, website, body, status
case createdAt = "created_at"
case updatedAt = "updated_at"
}
}
struct PingResponse: Codable {
var ok: Bool
var name: String
var authenticated: Bool
var tokenConfigured: Bool
enum CodingKeys: String, CodingKey {
case ok, name, authenticated
case tokenConfigured = "token_configured"
}
}
struct ContentListResponse: Codable {
var ok: Bool
var items: [ContentItem]
}
struct ContentItemResponse: Codable {
var ok: Bool
var item: ContentItem
}
struct MediaListResponse: Codable {
var ok: Bool
var items: [MediaItem]
}
struct MediaItemResponse: Codable {
var ok: Bool
var item: MediaItem
}
struct CommentListResponse: Codable {
var ok: Bool
var items: [CommentItem]
}
struct BasicResponse: Codable {
var ok: Bool
var error: String?
}
struct APIErrorResponse: Codable {
var ok: Bool?
var error: String?
}