Skip to content

Commit

Permalink
1.1.4
Browse files Browse the repository at this point in the history
  • Loading branch information
dankinsoid committed Mar 28, 2024
1 parent 5854605 commit 565d9ce
Show file tree
Hide file tree
Showing 9 changed files with 440 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ import PackageDescription
let package = Package(
name: "SomeProject",
dependencies: [
.package(url: "https://github.com/dankinsoid/swift-api-client.git", from: "1.1.3")
.package(url: "https://github.com/dankinsoid/swift-api-client.git", from: "1.1.4")
],
targets: [
.target(
Expand Down
14 changes: 14 additions & 0 deletions SwagGen_Template/APIClient/Coding.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation

public typealias APIModel = Codable & Equatable

public typealias DateTime = Date
public typealias File = Data
public typealias ID = UUID

extension Encodable {

func encode() -> String {
(self as? String) ?? "\(self)"
}
}
21 changes: 21 additions & 0 deletions SwagGen_Template/Includes/Enum.stencil
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% if description %}
/** {{ description }} */
{% endif %}
public enum {{ enumName }}: {{ type }}, Codable, Equatable, CaseIterable{% if type == "String" %}, CustomStringConvertible{% endif %} {
{% for enumCase in enums %}
case {{ enumCase.name }} = {% if type == "String" %}"{% endif %}{{enumCase.value}}{% if type == "String" %}"{% endif %}
{% endfor %}
{% if options.enumUndecodedCase %}
case undecoded

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawValue = try container.decode({{ type }}.self)
self = {{ enumName }}(rawValue: rawValue) ?? .undecoded
}
{% endif %}

{% if type == "String" %}
public var description: String { rawValue }
{% endif %}
}
158 changes: 158 additions & 0 deletions SwagGen_Template/Includes/Model.stencil
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
{% macro propertyType property %}{% if property.type == "DateTime" or property.type == "DateDay" %}Date{% else %}{% if property.raw.format == "timestamp" %}Date{% else %}{{ property.type }}{% endif %}{% endif %}{% if property.optional or property.raw.nullable %}?{% endif %}{% endmacro %}
{% macro propertyName property %}{% if property.value|hasPrefix:"_" %}_{{ property.name }}{% else %}{{ property.name }}{% endif %}{% endmacro %}
{% if options.excludeTypes[type] == true %}

{% else %}
{% if description %}
/** {{ description }} */
{% endif %}
{% if enum %}
{% include "Includes/Enum.stencil" enum %}
{% elif aliasType %}
{% if type != "String" %}
public typealias {{ type }} = {{ aliasType }}
{% endif %}
{% elif additionalPropertiesType and allProperties.count == 0 %}
public typealias {{ type }} = [String: {{ additionalPropertiesType }}]
{% elif discriminatorType %}
public enum {{ type }}: {% if options.modelProtocol %}{{ options.modelProtocol }}{% else %}Codable, Equatable{% endif %} {

{% for subType in discriminatorType.subTypes %}
case {{ subType.name }}({{ subType.type }})
{% endfor %}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: PlainCodingKey.self)
let discriminator: String = try container.decode(path: "{{ discriminatorType.discriminatorProperty }}".components(separatedBy: ".").map { PlainCodingKey($0) })
switch discriminator {
{% for name, subType in discriminatorType.mapping %}
case "{{ name }}":
self = .{{ subType.name}}(try {{ subType.type }}(from: decoder))
{% endfor %}
default:
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Couldn't find type to decode with discriminator \"\(discriminator)\""))
}
}

public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
{% for subType in discriminatorType.subTypes %}
case .{{ subType.name}}(let content):
try container.encode(content)
{% endfor %}
}
}

{% for subType in discriminatorType.subTypes %}
public var {{ subType.name }}: {{ subType.type }}? {
if case .{{ subType.name }}(let value) = self {
return value
}
return nil
}
{% endfor %}
}
{% else %}
public {{ options.modelType }} {{ type }}: {% if parent %}{{ parent.type }}{% else %}{% if options.modelProtocol %}{{ options.modelProtocol }}{% else %}Codable, Equatable{% endif %}{% endif %} {

{% for property in properties %}
{% if not property.raw.deprecated %}
{% if property.description %}
/// {{ property.description }}
{% endif %}
public {% if options.mutableModels %}var{% else %}let{% endif %} {% call propertyName property %}: {% call propertyType property %}
{% endif %}
{% endfor %}
{% if additionalPropertiesType %}

public {% if options.mutableModels %}var{% else %}let{% endif %} additionalProperties: [String: {{ additionalPropertiesType }}] = [:]
{% endif %}

public enum CodingKeys: String, CodingKey {

{% for property in properties %}
{% if not property.raw.deprecated %}
case {% call propertyName property %}{% if property.name != property.value %} = "{{ property.value }}"{% endif %}
{% endif %}
{% endfor %}
}

public {% if parent %}{% if properties.count == 0 %}override {% endif %}{% endif %}init(
{% for property in allProperties %}
{% if not property.raw.deprecated %}
{% call propertyName property %}: {% call propertyType property %}{% if property.optional or property.raw.nullable %} = nil{% endif %}{% ifnot forloop.last %},{% endif %}
{% endif %}
{% endfor %}
) {
{% for property in properties %}
{% if not property.raw.deprecated %}
self.{% call propertyName property %} = {% call propertyName property %}
{% endif %}
{% endfor %}
{% if parent %}
super.init({% for property in parent.allProperties %}{% call propertyName property %}: {% call propertyName property %}{% ifnot forloop.last %}, {% endif %}{% endfor %})
{% endif %}
}
{% if additionalPropertiesType %}

public subscript(key: String) -> {{ additionalPropertiesType }}? {
get {
return additionalProperties[key]
}
set {
additionalProperties[key] = newValue
}
}
{% endif %}
{% if options.modelType == "class" %}

{% if parent %}override {% endif %}public func isEqual(to object: Any?) -> Bool {
{% if properties.count > 0 or additionalPropertiesType %}
guard let object = object as? {{ type }} else { return false }
{% else %}
guard object is {{ type }} else { return false }
{% endif %}
{% for property in properties %}
{% if property.type == "[String: Any]" %}
guard NSDictionary(dictionary: self.{% call propertyName property %} {% if property.optional %}?? [:]{% endif %}).isEqual(to: object.{% call propertyName property %}{% if property.optional %} ?? [:]{% endif %}) else { return false }
{% else %}
guard self.{% call propertyName property %} == object.{% call propertyName property %} else { return false }
{% endif %}
{% endfor %}
{% if additionalPropertiesType %}
guard NSDictionary(dictionary: self.additionalProperties).isEqual(to: object.additionalProperties) else { return false }
{% endif %}
{% if parent %}
return super.isEqual(to: object)
{% else %}
return true
{% endif %}
}
{% if not parent %}

public static func == (lhs: {{ type }}, rhs: {{ type }}) -> Bool {
return lhs.isEqual(to: rhs)
}
{% endif %}
{% endif %}
{% for enum in enums %}
{% if not enum.isGlobal %}

{% filter indent:4 %}{% include "Includes/Enum.stencil" enum %}{% endfilter %}
{% endif %}
{% endfor %}
{% for schema in schemas %}
{% if options.globals[schema.type] != true %}
{% if options.typealiases[type][schema.type] != null %}

public typealias {{ schema.type }} = {{ options.typealiases[type][schema.type] }}
{% else %}

{% filter indent:4 %}{% include "Includes/Model.stencil" schema %}{% endfilter %}
{% endif %}
{% endif %}
{% endfor %}
}
{% endif %}
{% endif %}
112 changes: 112 additions & 0 deletions SwagGen_Template/Sources/APIModule.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// swiftlint:disable all
import Foundation
import SwiftAPIClient

{% if info.description %}
/** {{ info.description }} */
{% endif %}
public struct {{ options.name }} {

{% if info.version %}
public static let version = "{{ info.version }}"
{% endif %}
public var client: APIClient

public init(client: APIClient) {
self.client = client
}
}
{% if servers %}
extension {{ options.name }} {

public struct Server: Hashable {

/// URL of the server
public var url: URL

public init(_ url: URL) {
self.url = url
}

{% ifnot servers[0].variables %}
public static var `default` = {{ options.name }}.Server.{{ servers[0].name }}
{% endif %}
{% for server in servers %}

{% if server.description %}
/** {{ server.description }} */
{% endif %}
{% if server.variables %}
public static func {{ server.name }}({% for variable in server.variables %}{{ variable.name|replace:'-','_' }}: String = "{{ variable.defaultValue }}"{% ifnot forloop.last %}, {% endif %}{% endfor %}) -> {{ options.name }}.Server {
var urlString = "{{ server.url }}"
{% for variable in server.variables %}
urlString = urlString.replacingOccurrences(of: {{'"{'}}{{variable.name}}{{'}"'}}, with: {{variable.name|replace:'-','_'}})
{% endfor %}
return {{ options.name }}.Server(URL(string: urlString)!)
}
{% else %}
public static let {{ server.name }} = {{ options.name }}.Server(URL(string: "{{ server.url }}")!)
{% endif %}
{% endfor %}
}
}

extension APIClient.Configs {

/// {{ options.name }} server
public var {{ options.name|lowerFirstWord }}Server: {{ options.name }}.Server{% if servers[0].variables %}?{% endif %} {
get { self[\.{{ options.name|lowerFirstWord }}Server]{% ifnot servers[0].variables %} ?? .default{% endif %} }
set { self[\.{{ options.name|lowerFirstWord }}Server] = newValue }
}
}

{% else %}

// No servers defined in swagger. Documentation for adding them: https://swagger.io/specification/#schema
{% endif %}
{% if options.groupingType == "path" %}
{% macro pathTypeName path %}{{ path|basename|upperFirstLetter|replace:"{","By_"|replace:"}",""|swiftIdentifier:"pretty" }}{% endmacro %}
{% macro pathAsType path %}{% if path != "/" and path != "" %}{% call pathAsType path|dirname %}.{% call pathTypeName path %}{% endif %}{% endmacro %}
{% macro pathVarAndType path allPaths definedPath %}
{% set currentPath path|dirname %}
{% if path != "/" and path != "" %}
{% set _path %}|{{path}}|{% endset %}
{% if definedPath|contains:_path == false %}
extension {{ options.name }}{% call pathAsType currentPath %} {
{% set name path|basename %}
/// {{ path }}
{% if name|contains:"{" %}
public func callAsFunction(_ path: String) -> {% call pathTypeName path %} { {% call pathTypeName path %}(client: client(path)) }
{% else %}
public var {{ name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords }}: {% call pathTypeName path %} { {% call pathTypeName path %}(client: client("{{name}}")) }
{% endif %}
public struct {% call pathTypeName path %} { public var client: APIClient }
}
{% set newDefinedPaths %}{{_path}}{{definedPath}}{% endset %}
{% call pathVarAndType currentPath allPaths newDefinedPaths %}
{% else %}
{% call pathVarAndType currentPath allPaths definedPath %}
{% endif %}
{% else %}
{% if allPaths != "/" and allPaths != "" %}
{% set path %}{{ allPaths|basename|replace:"$","/" }}{% endset %}
{% set newAllPaths allPaths|dirname %}
{% call pathVarAndType path newAllPaths definedPath %}
{% endif %}
{% endif %}
{% endmacro %}
{% map paths into pathArray %}{{maploop.item.path|replace:"/","$"}}{% endmap %}
{% set allPaths %}/{{ pathArray|join:"/" }}{% endset %}
{% set path %}{{ allPaths|basename|replace:"$","/" }}{% endset %}
{% call pathVarAndType path allPaths "" %}
{% elif options.groupingType == "tag" and tags %}
{% for tag in tags %}
extension {{ options.name }} {
public var {{ tag|swiftIdentifier|lowerFirstLetter }}: {{ tag|swiftIdentifier }} { {{ tag|swiftIdentifier }}(client: client) }
public struct {{ tag|swiftIdentifier }} { var client: APIClient }
}
{% endfor %}
{% endif %}
1 change: 1 addition & 0 deletions SwagGen_Template/Sources/Enum.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% include "Includes/Enum.stencil" %}
4 changes: 4 additions & 0 deletions SwagGen_Template/Sources/Model.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Foundation
import SwiftAPIClient

{% include "Includes/Model.stencil" %}
Loading

0 comments on commit 565d9ce

Please sign in to comment.