From 00fb8eb175d937fdadb26f5e95090425c29bfcca Mon Sep 17 00:00:00 2001 From: CMK Date: Wed, 27 Jan 2021 19:24:31 +0800 Subject: [PATCH 1/3] fix: set header date formatter options --- .../MastodonSDK/API/Mastodon+API+Timeline.swift | 6 ------ .../Sources/MastodonSDK/API/Mastodon+API.swift | 6 +++++- .../MastodonSDK/Entity/Mastodon+Entity+Toot.swift | 2 +- .../Sources/MastodonSDK/Extension/Bool.swift | 14 ++++++++++++++ 4 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonSDK/Extension/Bool.swift diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Timeline.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Timeline.swift index eb9271b02..13d0dc141 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Timeline.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Timeline.swift @@ -91,9 +91,3 @@ extension Mastodon.API.Timeline { } } } - -extension Bool { - var queryItemValue: String { - return self ? "true" : "false" - } -} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift index f86e1fc71..8dfc1709c 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift @@ -11,7 +11,11 @@ import enum NIOHTTP1.HTTPResponseStatus extension Mastodon.API { static let timeoutInterval: TimeInterval = 10 - static let httpHeaderDateFormatter = ISO8601DateFormatter() + static let httpHeaderDateFormatter: ISO8601DateFormatter = { + var formatter = ISO8601DateFormatter() + formatter.formatOptions.insert(.withFractionalSeconds) + return formatter + }() static let encoder: JSONEncoder = { let encoder = JSONEncoder() encoder.dateEncodingStrategy = .iso8601 diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Toot.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Toot.swift index 3bf52991f..2adc9a123 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Toot.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Toot.swift @@ -18,7 +18,7 @@ extension Mastodon.Entity { public let content: String public let account: User - public let language: String + public let language: String? public let visibility: String enum CodingKeys: String, CodingKey { diff --git a/MastodonSDK/Sources/MastodonSDK/Extension/Bool.swift b/MastodonSDK/Sources/MastodonSDK/Extension/Bool.swift new file mode 100644 index 000000000..7641f6d9e --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Extension/Bool.swift @@ -0,0 +1,14 @@ +// +// Bool.swift +// +// +// Created by MainasuK Cirno on 2021/1/27. +// + +import Foundation + +extension Bool { + var queryItemValue: String { + return self ? "true" : "false" + } +} From d29f473898f981dfa1c7bfa8577d472b613945a5 Mon Sep 17 00:00:00 2001 From: CMK Date: Thu, 28 Jan 2021 11:57:02 +0800 Subject: [PATCH 2/3] feat: add Instance entity --- .../Entity/Mastodon+Entity+Instance.swift | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift new file mode 100644 index 000000000..69b4c1508 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift @@ -0,0 +1,71 @@ +// +// Mastodon+Entity+Instance.swift +// +// +// Created by MainasuK Cirno on 2021/1/27. +// + +import Foundation + +extension Mastodon.Entity { + public struct Instance: Codable { + + public let uri: String? + public let title: String? + public let description: String? + public let shortDescription: String? + public let email: String? + public let version: String? + public let languages: [String]? // (ISO 639 Part 1-5 language codes) + public let registrations: Bool? + public let approvalRequired: Bool? + public let invitesEnabled: Bool? + public let urls: [InstanceURL]? + public let statistics: Statistics? + + public let thumbnail: String? + public let contactAccount: User? + + enum CodingKeys: String, CodingKey { + case uri + case title + case description + case shortDescription = "short_description" + case email + case version + case languages + case registrations + case approvalRequired = "approval_required" + case invitesEnabled + case urls + case statistics + + case thumbnail = "thumbnail" + case contactAccount = "contact_account" + } + } +} + +extension Mastodon.Entity.Instance { + public struct InstanceURL: Codable { + public let streamingAPI: String + + enum CodingKeys: String, CodingKey { + case streamingAPI = "streaming_api" + } + } +} + +extension Mastodon.Entity.Instance { + public struct Statistics: Codable { + public let userCount: Int + public let statusCount: Int + public let domainCount: Int + + enum CodingKeys: String, CodingKey { + case userCount = "user_count" + case statusCount = "status_count" + case domainCount = "domain_count" + } + } +} From f8718510a6329b34622700113458da64b71c59e7 Mon Sep 17 00:00:00 2001 From: CMK Date: Thu, 28 Jan 2021 14:52:35 +0800 Subject: [PATCH 3/3] feat: add partial Mastodon entities --- .../Mastodon+API+Error+MastodonAPIError.swift | 8 +- .../API/Error/Mastodon+API+Error.swift | 10 +- .../MastodonSDK/API/Mastodon+API+App.swift | 27 +---- .../MastodonSDK/API/Mastodon+API.swift | 26 +++- .../Entity/Mastodon+Entity+Account.swift | 89 ++++++++++++++ .../Entity/Mastodon+Entity+Application.swift | 40 +++++++ .../Entity/Mastodon+Entity+Card.swift | 63 ++++++++++ .../Entity/Mastodon+Entity+Emoji.swift | 35 ++++++ .../Entity/Mastodon+Entity+Error.swift | 28 +++++ .../Entity/Mastodon+Entity+Field.swift | 31 +++++ .../Entity/Mastodon+Entity+History.swift | 25 ++++ .../Entity/Mastodon+Entity+Instance.swift | 16 ++- .../Entity/Mastodon+Entity+Mention.swift | 37 ++++++ .../Entity/Mastodon+Entity+Poll.swift | 62 ++++++++++ .../Entity/Mastodon+Entity+Source.swift | 49 ++++++++ .../Entity/Mastodon+Entity+Status.swift | 112 ++++++++++++++++++ .../Entity/Mastodon+Entity+Tag.swift | 26 ++++ .../Entity/Mastodon+Entity+Toot.swift | 34 ------ .../Entity/Mastodon+Entity+User.swift | 31 ----- .../MastodonSDK/Entity/Mastodon+Entity.swift | 11 ++ .../Mastodon+Response+ErrorResponse.swift | 20 ---- .../MastodonSDKTests/MastodonSDKTests.swift | 33 +++++- 22 files changed, 679 insertions(+), 134 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Account.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Application.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Card.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Emoji.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Error.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Field.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+History.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Mention.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Poll.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Source.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Status.swift create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift delete mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Toot.swift delete mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+User.swift delete mode 100644 MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+ErrorResponse.swift diff --git a/MastodonSDK/Sources/MastodonSDK/API/Error/Mastodon+API+Error+MastodonAPIError.swift b/MastodonSDK/Sources/MastodonSDK/API/Error/Mastodon+API+Error+MastodonAPIError.swift index 47449e79e..edf078109 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Error/Mastodon+API+Error+MastodonAPIError.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Error/Mastodon+API+Error+MastodonAPIError.swift @@ -8,11 +8,11 @@ import Foundation extension Mastodon.API.Error { - public enum MastodonAPIError: Swift.Error { - case generic(errorResponse: Mastodon.Response.ErrorResponse) + public enum MastodonError: Swift.Error { + case generic(error: Mastodon.Entity.Error) - init(errorResponse: Mastodon.Response.ErrorResponse) { - self = .generic(errorResponse: errorResponse) + init(error: Mastodon.Entity.Error) { + self = .generic(error: error) } } } diff --git a/MastodonSDK/Sources/MastodonSDK/API/Error/Mastodon+API+Error.swift b/MastodonSDK/Sources/MastodonSDK/API/Error/Mastodon+API+Error.swift index ad87fe8f3..94d063c40 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Error/Mastodon+API+Error.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Error/Mastodon+API+Error.swift @@ -12,23 +12,23 @@ extension Mastodon.API { public struct Error: Swift.Error { public var httpResponseStatus: HTTPResponseStatus - public var mastodonAPIError: MastodonAPIError? + public var mastodonError: MastodonError? init( httpResponseStatus: HTTPResponseStatus, - mastodonAPIError: Mastodon.API.Error.MastodonAPIError? + mastodonError: Mastodon.API.Error.MastodonError? ) { self.httpResponseStatus = httpResponseStatus - self.mastodonAPIError = mastodonAPIError + self.mastodonError = mastodonError } init( httpResponseStatus: HTTPResponseStatus, - errorResponse: Mastodon.Response.ErrorResponse + error: Mastodon.Entity.Error ) { self.init( httpResponseStatus: httpResponseStatus, - mastodonAPIError: MastodonAPIError(errorResponse: errorResponse) + mastodonError: MastodonError(error: error) ) } diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+App.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+App.swift index 78fd2a39f..987164614 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+App.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+App.swift @@ -18,7 +18,7 @@ extension Mastodon.API.App { session: URLSession, domain: String, query: CreateQuery - ) -> AnyPublisher, Error> { + ) -> AnyPublisher, Error> { let request = Mastodon.API.request( url: appEndpointURL(domain: domain), query: query, @@ -26,7 +26,7 @@ extension Mastodon.API.App { ) return session.dataTaskPublisher(for: request) .tryMap { data, response in - let value = try Mastodon.API.decode(type: Application.self, from: data, response: response) + let value = try Mastodon.API.decode(type: Mastodon.Entity.Application.self, from: data, response: response) return Mastodon.Response.Content(value: value, response: response) } .eraseToAnyPublisher() @@ -36,29 +36,6 @@ extension Mastodon.API.App { extension Mastodon.API.App { - public struct Application: Codable { - - public let id: String - - public let name: String - public let website: String? - public let redirectURI: String - public let clientID: String - public let clientSecret: String - public let vapidKey: String - - enum CodingKeys: String, CodingKey { - case id - - case name - case website - case redirectURI = "redirect_uri" - case clientID = "client_id" - case clientSecret = "client_secret" - case vapidKey = "vapid_key" - } - } - public struct CreateQuery: Codable, PostQuery { public let clientName: String public let redirectURIs: String diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift index 8dfc1709c..9c3fee054 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift @@ -11,11 +11,23 @@ import enum NIOHTTP1.HTTPResponseStatus extension Mastodon.API { static let timeoutInterval: TimeInterval = 10 + static let httpHeaderDateFormatter: ISO8601DateFormatter = { var formatter = ISO8601DateFormatter() formatter.formatOptions.insert(.withFractionalSeconds) return formatter }() + static let fractionalSecondsPreciseISO8601Formatter: ISO8601DateFormatter = { + let formatter = ISO8601DateFormatter() + formatter.formatOptions.insert(.withFractionalSeconds) + return formatter + }() + static let fullDatePreciseISO8601Formatter: ISO8601DateFormatter = { + let formatter = ISO8601DateFormatter() + formatter.formatOptions = [.withFullDate, .withDashSeparatorInDate] + return formatter + }() + static let encoder: JSONEncoder = { let encoder = JSONEncoder() encoder.dateEncodingStrategy = .iso8601 @@ -27,9 +39,11 @@ extension Mastodon.API { let container = try decoder.singleValueContainer() let string = try container.decode(String.self) - let formatter = ISO8601DateFormatter() - formatter.formatOptions.insert(.withFractionalSeconds) - if let date = formatter.date(from: string) { + + if let date = fractionalSecondsPreciseISO8601Formatter.date(from: string) { + return date + } + if let date = fullDatePreciseISO8601Formatter.date(from: string) { return date } @@ -116,11 +130,11 @@ extension Mastodon.API { } let httpResponseStatus = HTTPResponseStatus(statusCode: httpURLResponse.statusCode) - if let errorResponse = try? Mastodon.API.decoder.decode(Mastodon.Response.ErrorResponse.self, from: data) { - throw Mastodon.API.Error(httpResponseStatus: httpResponseStatus, errorResponse: errorResponse) + if let error = try? Mastodon.API.decoder.decode(Mastodon.Entity.Error.self, from: data) { + throw Mastodon.API.Error(httpResponseStatus: httpResponseStatus, error: error) } - throw Mastodon.API.Error(httpResponseStatus: httpResponseStatus, mastodonAPIError: nil) + throw Mastodon.API.Error(httpResponseStatus: httpResponseStatus, mastodonError: nil) } } diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Account.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Account.swift new file mode 100644 index 000000000..f794dabb9 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Account.swift @@ -0,0 +1,89 @@ +// +// Mastodon+Entity+Account.swift +// +// +// Created by MainasuK Cirno on 2021/1/27. +// + +import Foundation + +extension Mastodon.Entity { + + // FIXME: prefer `Account`. `User` will be deprecated + public typealias User = Account + + /// Account + /// + /// - Since: 0.1.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/account/) + public class Account: Codable { + + public typealias ID = String + + // Base + public let id: ID + public let username: String + public let acct: String + public let url: String + + // Display + public let displayName: String + public let note: String + public let avatar: String + public let avatarStatic: String? + public let header: String + public let headerStatic: String? + public let locked: Bool + public let emojis: [Emoji]? + public let discoverable: Bool? + + // Statistical + public let createdAt: Date + public let lastStatusAt: Date? + public let statusesCount: Int + public let followersCount: Int + public let followingCount: Int + + public let moved: User? + public let fields: [Field]? + public let bot: Bool? + public let source: Source? + public let suspended: Bool? + public let muteExpiresAt: Date? + + enum CodingKeys: String, CodingKey { + case id + case username + case acct + case url + + case displayName = "display_name" + case note + case avatar + case avatarStatic = "avatar_static" + case header + case headerStatic = "header_static" + case locked + case emojis + case discoverable + + case createdAt = "created_at" + case lastStatusAt = "last_status_at" + case statusesCount = "statuses_count" + case followersCount = "followers_count" + case followingCount = "following_count" + case moved + + case fields + case bot + case source + case suspended + case muteExpiresAt = "mute_expires_at" + } + } + +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Application.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Application.swift new file mode 100644 index 000000000..d7d4dda4d --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Application.swift @@ -0,0 +1,40 @@ +// +// Mastodon+Entity+Application.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// Application + /// + /// - Since: 0.9.9 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/application/) + public struct Application: Codable { + + public let name: String + + public let website: String? + public let vapidKey: String? + + // Client + public let redirectURI: String? // undocumented + public let clientID: String? + public let clientSecret: String? + + enum CodingKeys: String, CodingKey { + case name + case website + case vapidKey = "vapid_key" + case redirectURI = "redirect_uri" + case clientID = "client_id" + case clientSecret = "client_secret" + } + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Card.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Card.swift new file mode 100644 index 000000000..ba97d1d78 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Card.swift @@ -0,0 +1,63 @@ +// +// Mastodon+Entity+Card.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// Card + /// + /// - Since: 1.0.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/card/) + public struct Card: Codable { + // Base + public let url: String + public let title: String + public let description: String + public let type: Type? + + public let authorName: String? + public let authorURL: String? + public let providerName: String? + public let providerURL: String? + public let html: String? + public let width: Int? + public let height: Int? + public let image: String? + public let embedURL: String? + public let blurhash: String? + + enum CodingKeys: String, CodingKey { + case url + case title + case description + case type + case authorName = "author_name" + case authorURL = "author_url" + case providerName = "provider_name" + case providerURL = "provider_url" + case html + case width + case height + case image + case embedURL = "embed_url" + case blurhash + } + } +} + +extension Mastodon.Entity.Card { + public enum `Type`: String, Codable { + case link + case photo + case video + case rich + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Emoji.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Emoji.swift new file mode 100644 index 000000000..2b4d87879 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Emoji.swift @@ -0,0 +1,35 @@ +// +// Mastodon+Entity+Emoji.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// Emoji + /// + /// - Since: 2.0.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/emoji/) + public struct Emoji: Codable { + public let shortcode: String + public let url: String + public let staticURL: String + public let visibleInPicker: Bool + + public let category: String? + + enum CodingKeys: String, CodingKey { + case shortcode + case url + case staticURL = "static_url" + case visibleInPicker = "visible_in_picker" + case category + } + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Error.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Error.swift new file mode 100644 index 000000000..9d5ae2a50 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Error.swift @@ -0,0 +1,28 @@ +// +// Mastodon+Entity+Error.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// Error + /// + /// - Since: 0.6.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/error/) + public struct Error: Codable { + public let error: String + public let errorDescription: String? + + enum CodingKeys: String, CodingKey { + case error + case errorDescription = "error_description" + } + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Field.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Field.swift new file mode 100644 index 000000000..eb22d6adb --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Field.swift @@ -0,0 +1,31 @@ +// +// Mastodon+Entity+Field.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// Field + /// + /// - Since: 2.4.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/field/) + public struct Field: Codable { + public let name: String + public let value: String + + public let verifiedAt: Date? + + enum CodingKeys: String, CodingKey { + case name + case value + case verifiedAt = "verified_at" + } + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+History.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+History.swift new file mode 100644 index 000000000..9e2f9efb2 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+History.swift @@ -0,0 +1,25 @@ +// +// Mastodon+Entity+History.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// History + /// + /// - Since: 2.4.1 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/history/) + public struct History: Codable { + /// UNIX timestamp on midnight of the given day + public let day: Date + public let uses: Int + public let accounts: Int + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift index 69b4c1508..6cdef7fe6 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift @@ -8,13 +8,21 @@ import Foundation extension Mastodon.Entity { + /// Instance + /// + /// - Since: 1.1.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/instance/) public struct Instance: Codable { - public let uri: String? - public let title: String? - public let description: String? + public let uri: String + public let title: String + public let description: String public let shortDescription: String? - public let email: String? + public let email: String public let version: String? public let languages: [String]? // (ISO 639 Part 1-5 language codes) public let registrations: Bool? diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Mention.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Mention.swift new file mode 100644 index 000000000..07e15f8c4 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Mention.swift @@ -0,0 +1,37 @@ +// +// Mastodon+Entity+Mention.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// Mention + /// + /// - Since: 0.6.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/mention/) + public struct Mention: Codable { + + public typealias ID = String + + public let id: ID + public let username: String + public let acct: String + public let url: String + + + enum CodingKeys: String, CodingKey { + case id + case username + case acct + case url + } + + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Poll.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Poll.swift new file mode 100644 index 000000000..a9ed197fc --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Poll.swift @@ -0,0 +1,62 @@ +// +// Mastodon+Entity+Poll.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// Poll + /// + /// - Since: 2.8.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/poll/) + public struct Poll: Codable { + public typealias ID = String + + public let id: ID + public let expiresAt: Date + public let expired: Bool + public let multiple: Bool + public let votesCount: Int + /// nil if `multiple` is false + public let votersCount: Int? + /// nil if no current user + public let voted: Bool? + /// nil if no current user + public let ownVotes: [Int]? + public let options: [Option] + + enum CodingKeys: String, CodingKey { + case id + case expiresAt = "expires_at" + case expired + case multiple + case votesCount = "votes_count" + case votersCount = "voters_count" + case voted + case ownVotes = "own_votes" + case options + } + } +} + +extension Mastodon.Entity.Poll { + public struct Option: Codable { + public let title: String + /// nil if results are not published yet + public let votesCount: Int? + public let emojis: [Mastodon.Entity.Emoji] + + enum CodingKeys: String, CodingKey { + case title + case votesCount = "votes_count" + case emojis + } + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Source.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Source.swift new file mode 100644 index 000000000..c808fc87c --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Source.swift @@ -0,0 +1,49 @@ +// +// Mastodon+Entity+Source.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// Source + /// + /// - Since: 1.5.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/source/) + public struct Source: Codable { + + // Base + public let note: String + public let fields: [Field]? + + public let privacy: Privacy? + public let sensitive: Bool? + public let language: String? // (ISO 639-1 language two-letter code) + public let followRequestsCount: String + + enum CodingKeys: String, CodingKey { + case note + case fields + + case privacy + case sensitive + case language + case followRequestsCount = "follow_requests_count" + } + } +} + +extension Mastodon.Entity.Source { + public enum Privacy: String, Codable { + case `public` + case unlisted + case `private` + case direct + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Status.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Status.swift new file mode 100644 index 000000000..7fa3f0cb4 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Status.swift @@ -0,0 +1,112 @@ +// +// Mastodon+Entity+Toot.swift +// +// +// Created by MainasuK Cirno on 2021/1/27. +// + +import Foundation + +extension Mastodon.Entity { + + // FIXME: prefer `Status`. `Toot` will be deprecated + public typealias Toot = Status + + /// Status + /// + /// - Since: 0.1.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/status/) + public class Status: Codable { + + public typealias ID = String + + // Base + public let id: ID + public let uri: String + public let createdAt: Date + public let account: Account + public let content: String + + public let visibility: String? + public let sensitive: Bool? + public let spoilerText: String? + public let application: Application? + + // Rendering + public let mentions: [Mention]? + public let tags: [Tag]? + public let emojis: [Emoji]? + + // Informational + public let reblogsCount: Int + public let favouritesCount: Int + public let repliesCount: Int? + + public let url: String? + public let inReplyToID: Status.ID? + public let inReplyToAccountID: Account.ID? + public let reblog: Status? + public let poll: Poll? + public let card: Card? + public let language: String? // (ISO 639 Part 1 two-letter language code) + public let text: String? + + // Authorized user + public let favourited: Bool? + public let reblogged: Bool? + public let muted: Bool? + public let bookmarked: Bool? + public let pinned: Bool? + + + enum CodingKeys: String, CodingKey { + case id + case uri + case createdAt = "created_at" + case account + case content + + case visibility + case sensitive + case spoilerText = "spoiler_text" + case application + + case mentions + case tags + case emojis + + case reblogsCount = "reblogs_count" + case favouritesCount = "favourites_count" + case repliesCount = "replies_count" + + case url + case inReplyToID = "in_reply_to_id" + case inReplyToAccountID = "in_reply_to_account_id" + case reblog + case poll + case card + case language + case text + + case favourited + case reblogged + case muted + case bookmarked + case pinned + } + } + +} + +extension Mastodon.Entity.Status { + public enum Visibility: String, Codable { + case `public` + case unlisted + case `private` + case direct + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift new file mode 100644 index 000000000..61c47ed68 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift @@ -0,0 +1,26 @@ +// +// Mastodon+Entity+Tag.swift +// +// +// Created by MainasuK Cirno on 2021/1/28. +// + +import Foundation + +extension Mastodon.Entity { + /// Tag + /// + /// - Since: 0.9.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/1/28 + /// # Reference + /// [Document](https://docs.joinmastodon.org/entities/tag/) + public struct Tag: Codable { + // Base + public let name: String + public let url: String + + public let history: [History]? + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Toot.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Toot.swift deleted file mode 100644 index 2adc9a123..000000000 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Toot.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// Mastodon+Entity+Toot.swift -// -// -// Created by MainasuK Cirno on 2021/1/27. -// - -import Foundation - -extension Mastodon.Entity { - public struct Toot: Codable { - - public typealias ID = String - - public let id: ID - - public let createdAt: Date - public let content: String - public let account: User - - public let language: String? - public let visibility: String - - enum CodingKeys: String, CodingKey { - case id - case createdAt = "created_at" - case content - case account - case language - case visibility - } - - } -} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+User.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+User.swift deleted file mode 100644 index f1dd4f692..000000000 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+User.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// Mastodon+Entity+User.swift -// -// -// Created by MainasuK Cirno on 2021/1/27. -// - -import Foundation - -extension Mastodon.Entity { - public struct User: Codable { - - public typealias ID = String - - public let id: ID - - public let username: String - public let acct: String - public let displayName: String? - public let avatar: String? - - enum CodingKeys: String, CodingKey { - case id - case username - case acct - case displayName = "display_name" - case avatar - } - - } -} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity.swift index cb8cf240f..77da12ebf 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity.swift @@ -8,3 +8,14 @@ import Foundation extension Mastodon.Entity { } + +// MARK: - Entity Document Template +/// Entity Name +/// +/// - Since: 0.1.0 +/// - Version: x.x.x +/// # Last Update +/// yyyy/MM/dd +/// # Reference +/// [Title](link) + diff --git a/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+ErrorResponse.swift b/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+ErrorResponse.swift deleted file mode 100644 index 48519a5b6..000000000 --- a/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+ErrorResponse.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// Mastodon+Response+ErrorResponse.swift -// -// -// Created by MainasuK Cirno on 2021/1/27. -// - -import Foundation - -extension Mastodon.Response { - public struct ErrorResponse: Codable { - public let error: String - public let errorDescription: String? - - enum CodingKeys: String, CodingKey { - case error - case errorDescription = "error_description" - } - } -} diff --git a/MastodonSDK/Tests/MastodonSDKTests/MastodonSDKTests.swift b/MastodonSDK/Tests/MastodonSDKTests/MastodonSDKTests.swift index 380c7dd41..15d2cee00 100644 --- a/MastodonSDK/Tests/MastodonSDKTests/MastodonSDKTests.swift +++ b/MastodonSDK/Tests/MastodonSDKTests/MastodonSDKTests.swift @@ -6,10 +6,23 @@ final class MastodonSDKTests: XCTestCase { var disposeBag = Set() - let domain = "mstdn.jp" + let mstdnDomain = "mstdn.jp" + let pawooDomain = "pawoo.net" let session = URLSession(configuration: .ephemeral) + +} + +extension MastodonSDKTests { - func testCreateAnAnpplication() throws { + func testCreateAnAnpplication_mstdn() throws { + try _testCreateAnAnpplication(domain: pawooDomain) + } + + func testCreateAnAnpplication_pawoo() throws { + try _testCreateAnAnpplication(domain: pawooDomain) + } + + func _testCreateAnAnpplication(domain: String) throws { let theExpectation = expectation(description: "Create An Application") let query = Mastodon.API.App.CreateQuery( @@ -35,9 +48,20 @@ final class MastodonSDKTests: XCTestCase { wait(for: [theExpectation], timeout: 10.0) } +} + +extension MastodonSDKTests { - func testPublicTimeline() throws { - let theExpectation = expectation(description: "Create An Application") + func testPublicTimeline_mstdn() throws { + try _testPublicTimeline(domain: mstdnDomain) + } + + func testPublicTimeline_pawoo() throws { + try _testPublicTimeline(domain: pawooDomain) + } + + private func _testPublicTimeline(domain: String) throws { + let theExpectation = expectation(description: "Fetch Public Timeline") let query = Mastodon.API.Timeline.PublicTimelineQuery() Mastodon.API.Timeline.public(session: session, domain: domain, query: query) @@ -56,7 +80,6 @@ final class MastodonSDKTests: XCTestCase { .store(in: &disposeBag) wait(for: [theExpectation], timeout: 10.0) - } }