diff --git a/.openapi-generator/templates/swift5/Models.mustache b/.openapi-generator/templates/swift5/Models.mustache new file mode 100644 index 0000000..2221b35 --- /dev/null +++ b/.openapi-generator/templates/swift5/Models.mustache @@ -0,0 +1,143 @@ +// Models.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation{{#useAlamofire}} +import Alamofire{{/useAlamofire}} + +protocol JSONEncodable { + func encodeToJSON() -> Any +} + +/// An enum where the last case value can be used as a default catch-all. +protocol CaseIterableDefaultsLast: Decodable & CaseIterable & RawRepresentable +where RawValue: Decodable, AllCases: BidirectionalCollection {} + +extension CaseIterableDefaultsLast { + /// Initializes an enum such that if a known raw value is found, then it is decoded. + /// Otherwise the last case is used. + /// - Parameter decoder: A decoder. + public init(from decoder: Decoder) throws { + if let value = try Self(rawValue: decoder.singleValueContainer().decode(RawValue.self)) { + self = value + } else if let lastValue = Self.allCases.last { + self = lastValue + } else { + throw DecodingError.valueNotFound( + Self.Type.self, + .init(codingPath: decoder.codingPath, debugDescription: "CaseIterableDefaultsLast") + ) + } + } +} + +/// A flexible type that can be encoded (`.encodeNull` or `.encodeValue`) +/// or not encoded (`.encodeNothing`). Intended for request payloads. +public enum NullEncodable: Hashable { + case encodeNothing + case encodeNull + case encodeValue(Wrapped) +} + +extension NullEncodable: Codable where Wrapped: Codable { + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + if let value = try? container.decode(Wrapped.self) { + self = .encodeValue(value) + } else if container.decodeNil() { + self = .encodeNull + } else { + self = .encodeNothing + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + switch self { + case .encodeNothing: return + case .encodeNull: try container.encodeNil() + case .encodeValue(let wrapped): try container.encode(wrapped) + } + } +} + +public enum ErrorResponse: Error { + case error(Int, Data?, URLResponse?, Error) +} + +public enum DownloadException: Error { + case responseDataMissing + case responseFailed + case requestMissing + case requestMissingPath + case requestMissingURL +} + +public enum DecodableRequestBuilderError: Error { + case emptyDataResponse + case nilHTTPResponse + case unsuccessfulHTTPStatusCode + case jsonDecoding(DecodingError) + case generalError(Error) +} + +{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} class Response { + public let statusCode: Int + public let header: [String: String] + public let body: T + + public init(statusCode: Int, header: [String: String], body: T) { + self.statusCode = statusCode + self.header = header + self.body = body + } + + public convenience init(response: HTTPURLResponse, body: T) { + let rawHeader = response.allHeaderFields + var header = [String: String]() + for (key, value) in rawHeader { + if let key = key.base as? String, let value = value as? String { + header[key] = value + } + } + self.init(statusCode: response.statusCode, header: header, body: body) + } +} + +public final class RequestTask{{#useAsyncAwait}}: @unchecked Sendable{{/useAsyncAwait}} { + private var lock = NSRecursiveLock() +{{#useAlamofire}} + private var request: Request? + + internal func set(request: Request) { + lock.lock() + defer { lock.unlock() } + self.request = request + } + + public func cancel() { + lock.lock() + defer { lock.unlock() } + request?.cancel() + request = nil + } +{{/useAlamofire}} +{{^useAlamofire}} + private var task: URLSessionTask? + + internal func set(task: URLSessionTask) { + lock.lock() + defer { lock.unlock() } + self.task = task + } + + public func cancel() { + lock.lock() + defer { lock.unlock() } + task?.cancel() + task = nil + } +{{/useAlamofire}} +} diff --git a/.openapi-generator/templates/swift5/model.mustache b/.openapi-generator/templates/swift5/model.mustache new file mode 100644 index 0000000..4c7442a --- /dev/null +++ b/.openapi-generator/templates/swift5/model.mustache @@ -0,0 +1,30 @@ +{{#models}}{{#model}}// +// {{classname}}.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif{{#useVapor}} +import Vapor{{/useVapor}} +{{#swiftUseApiNamespace}} + +@available(*, deprecated, renamed: "{{projectName}}API.{{classname}}") +public typealias {{classname}} = {{projectName}}API.{{classname}} + +extension {{projectName}}API { +{{/swiftUseApiNamespace}} +{{#description}} + +/** {{.}} */{{/description}}{{#isDeprecated}} +@available(*, deprecated, message: "This schema is deprecated."){{/isDeprecated}}{{#vendorExtensions.x-is-one-of-interface}} +{{> modelOneOf}}{{/vendorExtensions.x-is-one-of-interface}}{{^vendorExtensions.x-is-one-of-interface}}{{#isArray}} +{{> modelArray}}{{/isArray}}{{^isArray}}{{#isEnum}} +{{> modelEnum}}{{/isEnum}}{{^isEnum}} +{{> modelObject}}{{/isEnum}}{{/isArray}}{{/vendorExtensions.x-is-one-of-interface}}{{/model}}{{/models}} +{{#swiftUseApiNamespace}} +} +{{/swiftUseApiNamespace}} \ No newline at end of file diff --git a/.openapi-generator/templates/swift5/modelArray.mustache b/.openapi-generator/templates/swift5/modelArray.mustache new file mode 100644 index 0000000..8436261 --- /dev/null +++ b/.openapi-generator/templates/swift5/modelArray.mustache @@ -0,0 +1 @@ +public typealias {{classname}} = {{parent}} \ No newline at end of file diff --git a/.openapi-generator/templates/swift5/modelEnum.mustache b/.openapi-generator/templates/swift5/modelEnum.mustache new file mode 100644 index 0000000..19634e3 --- /dev/null +++ b/.openapi-generator/templates/swift5/modelEnum.mustache @@ -0,0 +1,7 @@ +public enum {{classname}}: {{dataType}}, {{#useVapor}}Content, Hashable{{/useVapor}}{{^useVapor}}Codable{{^isString}}{{^isInteger}}{{^isFloat}}{{^isDouble}}, JSONEncodable{{/isDouble}}{{/isFloat}}{{/isInteger}}{{/isString}}{{/useVapor}}, CaseIterable{{#enumUnknownDefaultCase}}{{#isInteger}}, CaseIterableDefaultsLast{{/isInteger}}{{#isFloat}}, CaseIterableDefaultsLast{{/isFloat}}{{#isDouble}}, CaseIterableDefaultsLast{{/isDouble}}{{#isString}}, CaseIterableDefaultsLast{{/isString}}{{/enumUnknownDefaultCase}} { +{{#allowableValues}} +{{#enumVars}} + case {{{name}}} = {{{value}}} +{{/enumVars}} +{{/allowableValues}} +} \ No newline at end of file diff --git a/.openapi-generator/templates/swift5/modelInlineEnumDeclaration.mustache b/.openapi-generator/templates/swift5/modelInlineEnumDeclaration.mustache new file mode 100644 index 0000000..11cddd1 --- /dev/null +++ b/.openapi-generator/templates/swift5/modelInlineEnumDeclaration.mustache @@ -0,0 +1,7 @@ + public enum {{enumName}}: {{^isContainer}}{{dataType}}{{/isContainer}}{{#isContainer}}String{{/isContainer}}, {{#useVapor}}Content, Hashable{{/useVapor}}{{^useVapor}}Codable{{^isContainer}}{{^isString}}{{^isInteger}}{{^isFloat}}{{^isDouble}}, JSONEncodable{{/isDouble}}{{/isFloat}}{{/isInteger}}{{/isString}}{{/isContainer}}{{/useVapor}}, CaseIterable{{#enumUnknownDefaultCase}}{{#isInteger}}, CaseIterableDefaultsLast{{/isInteger}}{{#isFloat}}, CaseIterableDefaultsLast{{/isFloat}}{{#isDouble}}, CaseIterableDefaultsLast{{/isDouble}}{{#isString}}, CaseIterableDefaultsLast{{/isString}}{{#isContainer}}, CaseIterableDefaultsLast{{/isContainer}}{{/enumUnknownDefaultCase}} { + {{#allowableValues}} + {{#enumVars}} + case {{{name}}} = {{{value}}} + {{/enumVars}} + {{/allowableValues}} + } \ No newline at end of file diff --git a/.openapi-generator/templates/swift5/modelObject.mustache b/.openapi-generator/templates/swift5/modelObject.mustache new file mode 100644 index 0000000..f22d0ff --- /dev/null +++ b/.openapi-generator/templates/swift5/modelObject.mustache @@ -0,0 +1,122 @@ +{{^objcCompatible}}public {{#useClasses}}final class{{/useClasses}}{{^useClasses}}struct{{/useClasses}} {{{classname}}}: {{#useVapor}}Content{{/useVapor}}{{^useVapor}}Codable{{#useJsonEncodable}}, JSONEncodable{{/useJsonEncodable}}{{/useVapor}}{{#vendorExtensions.x-swift-hashable}}, Hashable{{/vendorExtensions.x-swift-hashable}} { +{{/objcCompatible}}{{#objcCompatible}}@objc public class {{classname}}: NSObject, Codable{{#useJsonEncodable}}, JSONEncodable{{/useJsonEncodable}} { +{{/objcCompatible}} + +{{#allVars}} +{{#isEnum}} +{{> modelInlineEnumDeclaration}} +{{/isEnum}} +{{/allVars}} +{{#allVars}} +{{#isEnum}} + {{#description}}/** {{{.}}} */ + {{/description}}{{#deprecated}}@available(*, deprecated, message: "This property is deprecated.") + {{/deprecated}}public {{#readonlyProperties}}private(set) {{/readonlyProperties}}var {{{name}}}: {{#vendorExtensions.x-null-encodable}}NullEncodable<{{{datatypeWithEnum}}}>{{/vendorExtensions.x-null-encodable}}{{^vendorExtensions.x-null-encodable}}{{{datatypeWithEnum}}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^required}}?{{/required}}{{/vendorExtensions.x-null-encodable}}{{#defaultValue}} = {{#vendorExtensions.x-null-encodable}}{{{vendorExtensions.x-null-encodable-default-value}}}{{/vendorExtensions.x-null-encodable}}{{^vendorExtensions.x-null-encodable}}{{{.}}}{{/vendorExtensions.x-null-encodable}}{{/defaultValue}} +{{/isEnum}} +{{^isEnum}} + {{#description}}/** {{{.}}} */ + {{/description}}{{#deprecated}}@available(*, deprecated, message: "This property is deprecated.") + {{/deprecated}}public {{#readonlyProperties}}private(set) {{/readonlyProperties}}var {{{name}}}: {{#vendorExtensions.x-null-encodable}}NullEncodable<{{{datatype}}}>{{/vendorExtensions.x-null-encodable}}{{^vendorExtensions.x-null-encodable}}{{{datatype}}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^required}}?{{/required}}{{/vendorExtensions.x-null-encodable}}{{#defaultValue}} = {{#vendorExtensions.x-null-encodable}}{{{vendorExtensions.x-null-encodable-default-value}}}{{/vendorExtensions.x-null-encodable}}{{^vendorExtensions.x-null-encodable}}{{{.}}}{{/vendorExtensions.x-null-encodable}}{{/defaultValue}} + {{#objcCompatible}} + {{#vendorExtensions.x-swift-optional-scalar}} + public var {{{name}}}Num: NSNumber? { + get { + {{^vendorExtensions.x-null-encodable}} + return {{{name}}} as NSNumber? + {{/vendorExtensions.x-null-encodable}} + {{#vendorExtensions.x-null-encodable}} + if case .encodeValue(let value) = {{name}} { + return value as NSNumber? + } else { + return nil + } + {{/vendorExtensions.x-null-encodable}} + } + } + {{/vendorExtensions.x-swift-optional-scalar}} + {{/objcCompatible}} +{{/isEnum}} +{{/allVars}} +{{#hasVars}} + + public init({{#allVars}}{{{name}}}: {{#vendorExtensions.x-null-encodable}}NullEncodable<{{{datatypeWithEnum}}}>{{/vendorExtensions.x-null-encodable}}{{^vendorExtensions.x-null-encodable}}{{{datatypeWithEnum}}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^required}}?{{/required}}{{/vendorExtensions.x-null-encodable}}{{#defaultValue}} = {{#vendorExtensions.x-null-encodable}}{{{vendorExtensions.x-null-encodable-default-value}}}{{/vendorExtensions.x-null-encodable}}{{^vendorExtensions.x-null-encodable}}{{{.}}}{{/vendorExtensions.x-null-encodable}}{{/defaultValue}}{{^defaultValue}}{{^required}} = {{#vendorExtensions.x-null-encodable}}.encodeNull{{/vendorExtensions.x-null-encodable}}{{^vendorExtensions.x-null-encodable}}nil{{/vendorExtensions.x-null-encodable}}{{/required}}{{/defaultValue}}{{^-last}}, {{/-last}}{{/allVars}}) { + {{#allVars}} + self.{{{name}}} = {{{name}}} + {{/allVars}} + } +{{/hasVars}} + + public enum CodingKeys: {{#hasVars}}String, {{/hasVars}}CodingKey, CaseIterable { + {{#allVars}} + case {{{name}}}{{#vendorExtensions.x-codegen-escaped-property-name}} = "{{{baseName}}}"{{/vendorExtensions.x-codegen-escaped-property-name}} + {{/allVars}} + }{{#generateModelAdditionalProperties}}{{#additionalPropertiesType}} + + public {{#readonlyProperties}}private(set) {{/readonlyProperties}}var additionalProperties: [String: {{{additionalPropertiesType}}}] = [:] + + public subscript(key: String) -> {{{additionalPropertiesType}}}? { + get { + if let value = additionalProperties[key] { + return value + } + return nil + } + + set { + additionalProperties[key] = newValue + } + }{{/additionalPropertiesType}}{{/generateModelAdditionalProperties}} + + // Encodable protocol methods + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + {{#allVars}} + {{#vendorExtensions.x-null-encodable}} + switch {{{name}}} { + case .encodeNothing: break + case .encodeNull, .encodeValue: try container.encode({{{name}}}, forKey: .{{{name}}}) + } + {{/vendorExtensions.x-null-encodable}} + {{^vendorExtensions.x-null-encodable}} + try container.encode{{^required}}IfPresent{{/required}}({{{name}}}, forKey: .{{{name}}}) + {{/vendorExtensions.x-null-encodable}} + {{/allVars}} + {{#generateModelAdditionalProperties}} + {{#additionalPropertiesType}} + var additionalPropertiesContainer = encoder.container(keyedBy: String.self) + try additionalPropertiesContainer.encodeMap(additionalProperties) + {{/additionalPropertiesType}} + {{/generateModelAdditionalProperties}} + }{{#generateModelAdditionalProperties}}{{#additionalPropertiesType}} + + // Decodable protocol methods + + public{{#objcCompatible}} required{{/objcCompatible}} init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + {{#allVars}} + {{{name}}} = try container.decode{{#required}}{{#isNullable}}IfPresent{{/isNullable}}{{/required}}{{^required}}IfPresent{{/required}}({{{datatypeWithEnum}}}.self, forKey: .{{{name}}}) + {{/allVars}} + var nonAdditionalPropertyKeys = Set() + {{#allVars}} + nonAdditionalPropertyKeys.insert("{{{baseName}}}") + {{/allVars}} + let additionalPropertiesContainer = try decoder.container(keyedBy: String.self) + additionalProperties = try additionalPropertiesContainer.decodeMap({{{additionalPropertiesType}}}.self, excludedKeys: nonAdditionalPropertyKeys) + }{{/additionalPropertiesType}}{{/generateModelAdditionalProperties}}{{^objcCompatible}}{{#useClasses}}{{#vendorExtensions.x-swift-hashable}} + + public static func == (lhs: {{classname}}, rhs: {{classname}}) -> Bool { + {{#allVars}} + lhs.{{{name}}} == rhs.{{{name}}}{{^-last}} &&{{/-last}} + {{/allVars}} + {{#generateModelAdditionalProperties}}{{#additionalPropertiesType}}{{#hasVars}}&& {{/hasVars}}lhs.additionalProperties == rhs.additionalProperties{{/additionalPropertiesType}}{{/generateModelAdditionalProperties}} + } + + public func hash(into hasher: inout Hasher) { + {{#allVars}} + hasher.combine({{{name}}}{{^vendorExtensions.x-null-encodable}}{{^required}}?{{/required}}{{/vendorExtensions.x-null-encodable}}.hashValue) + {{/allVars}} + {{#generateModelAdditionalProperties}}{{#additionalPropertiesType}}hasher.combine(additionalProperties.hashValue){{/additionalPropertiesType}}{{/generateModelAdditionalProperties}} + }{{/vendorExtensions.x-swift-hashable}}{{/useClasses}}{{/objcCompatible}} +}