swift-combine.api.mustache Maven / Gradle / Ivy
{{#operations}}//
// {{classname}}.swift
//
// Generated by openapi-generator
// https://openapi-generator.tech
import Foundation
import Combine
import OpenAPITransport
{{#description}}
/// {{{.}}} {{/description}}
open class {{classname}} {
private let transport: OpenAPITransport
public var encoder: JSONEncoder = {
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .formatted(OpenISO8601DateFormatter())
return encoder
}()
public var decoder: JSONDecoder = {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(OpenISO8601DateFormatter())
return decoder
}()
public var baseURL = URL(string: "{{{basePath}}}")
public init(_ transport: OpenAPITransport) {
self.transport = transport
}
{{#operation}}
{{#allParams}}
{{#isEnum}}
///
/// Enum for parameter {{paramName}}
///
public enum {{{vendorExtensions.x-swift-nested-enum-type}}}: {{{baseType}}}, Codable, CaseIterable {
{{#allowableValues}}
{{#enumVars}}
case {{name}} = {{{value}}}
{{/enumVars}}
{{/allowableValues}}
}
{{/isEnum}}
{{/allParams}}
{{#vendorExtensions.x-swift-custom-error-type}}
public enum {{{vendorExtensions.x-swift-custom-error-type}}}: Error, CustomStringConvertible {
{{#responses}}
{{#vendorExtensions.x-swift-has-custom-error-type}}
// {{{message}}}
case code{{{code}}}Error{{#dataType}}({{{dataType}}}){{/dataType}}
{{/vendorExtensions.x-swift-has-custom-error-type}}
{{/responses}}
public var description: String {
switch self {
{{#responses}}
{{#vendorExtensions.x-swift-has-custom-error-type}}
case .code{{{code}}}Error{{#dataType}}(let object){{/dataType}}:
return "{{{vendorExtensions.x-swift-custom-error-type}}}: {{{message}}}{{#dataType}}: \(object){{/dataType}}"
{{/vendorExtensions.x-swift-has-custom-error-type}}
{{/responses}}
}
}
}
{{/vendorExtensions.x-swift-custom-error-type}}
{{#summary}}
/// {{{.}}}
{{/summary}}
/// - {{httpMethod}} {{{path}}}{{#notes}}
/// - {{{.}}}{{/notes}}{{#subresourceOperation}}
/// - subresourceOperation: {{.}}{{/subresourceOperation}}{{#defaultResponse}}
/// - defaultResponse: {{.}}{{/defaultResponse}}
{{#authMethods}}
/// - {{#isBasicBasic}}BASIC{{/isBasicBasic}}{{#isOAuth}}OAuth{{/isOAuth}}{{#isApiKey}}API Key{{/isApiKey}}:
/// - type: {{type}}{{#keyParamName}} {{keyParamName}} {{#isKeyInQuery}}(QUERY){{/isKeyInQuery}}{{#isKeyInHeaer}}(HEADER){{/isKeyInHeaer}}{{/keyParamName}}
/// - name: {{name}}
{{/authMethods}}
{{#hasResponseHeaders}}
/// - responseHeaders: [{{#responseHeaders}}{{{baseName}}}({{{dataType}}}){{^-last}}, {{/-last}}{{/responseHeaders}}]
{{/hasResponseHeaders}}
{{#externalDocs}}
/// - externalDocs:
{{#url}}
/// url: {{.}}
{{/url}}
{{#description}}
/// description: {{.}}
{{/description}}
{{/externalDocs}}
{{#allParams}}
/// - parameter {{paramName}}: ({{#isFormParam}}form{{/isFormParam}}{{#isQueryParam}}query{{/isQueryParam}}{{#isPathParam}}path{{/isPathParam}}{{#isHeaderParam}}header{{/isHeaderParam}}{{#isBodyParam}}body{{/isBodyParam}}) {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
/// - returns: AnyPublisher<{{{returnType}}}{{^returnType}}Void{{/returnType}}, Error> {{description}}
{{#isDeprecated}}
@available(*, deprecated, message: "Deprecated API operation")
{{/isDeprecated}}
open func {{operationId}}({{#allParams}}{{paramName}}: {{{dataType}}}{{^required}}? = nil{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> AnyPublisher<{{{returnType}}}{{^returnType}}Void{{/returnType}}, Error> {
Deferred {
Result {
guard let baseURL = self.transport.baseURL ?? self.baseURL else {
throw OpenAPITransportError.badURLError()
}
{{#pathParams}}{{#-last}}var{{/-last}}{{/pathParams}}{{^pathParams}}let{{/pathParams}} path = "{{path}}"
{{#pathParams}}
{{#required}}path = path.replacingOccurrences(of: "{{=<% %>=}}{<%baseName%>}<%={{ }}=%>", with: {{> toString}}){{/required}}{{^required}}if let {{paramName}} = {{paramName}} { path = path.replacingOccurrences(of: "{{=<% %>=}}{<%baseName%>}<%={{ }}=%>", with: {{> toString}}) } {{/required}}
{{/pathParams}}
let url = baseURL.appendingPathComponent(path)
{{#hasQueryParams}}var{{/hasQueryParams}}{{^hasQueryParams}}let{{/hasQueryParams}} components = URLComponents(url: url, resolvingAgainstBaseURL: false)
{{#hasQueryParams}}
var queryItems: [URLQueryItem] = []
{{#queryParams}}
{{#required}}queryItems.append(URLQueryItem(name: "{{baseName}}", value: {{> toString}})){{/required}}{{^required}}if let {{paramName}} = {{paramName}} { queryItems.append(URLQueryItem(name: "{{baseName}}", value: {{> toString}})) } {{/required}}
{{/queryParams}}
components?.queryItems = queryItems
{{/hasQueryParams}}
guard let requestURL = components?.url else {
throw OpenAPITransportError.badURLError()
}
var request = URLRequest(url: requestURL)
request.httpMethod = "{{httpMethod}}"
{{! Begin headers }}
{{#headerParams}}
{{#-last}}
var headers = [String: String]()
{{/-last}}
{{/headerParams}}
{{#headerParams}}
{{#required}}headers["{{baseName}}"] = {{> toString}}{{/required}}{{^required}}if let {{paramName}} = {{paramName}} { headers["{{baseName}}"] = {{> toString}} }{{/required}}
{{/headerParams}}
{{#headerParams}}
{{#-last}}
request.allHTTPHeaderFields = headers
{{/-last}}
{{/headerParams}}
{{! Begin body }}
{{#hasBodyParam}}
{{#bodyParam}}
request.httpBody = try self.encoder.encode({{paramName}})
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
{{/bodyParam}}
{{/hasBodyParam}}
{{! Begin multipart form }}
{{#hasFormParams}}
{{#isMultipart}}
let multipartBoundary = String(format: "Boundary+%08X%08X", arc4random(), arc4random())
var multipartData = Data()
{{#formParams}}
{{> toMultipartFormDataAppend}}
{{/formParams}}
multipartData.append("\r\n--\(multipartBoundary)--\r\n".data(using: .utf8) ?? Data())
request.httpBody = multipartData
request.setValue("\(multipartData.count)", forHTTPHeaderField: "Content-Length")
request.setValue("multipart/form-data; boundary=\(multipartBoundary)", forHTTPHeaderField: "Content-Type")
{{/isMultipart}}
{{^isMultipart}}
{{! Begin form urlencoded }}
var formEncodedItems: [String] = []
{{#formParams}}
{{#required}}formEncodedItems.append("{{baseName}}=\({{> toString}})"){{/required}}{{^required}}if let {{paramName}} = {{paramName}} { formEncodedItems.append("{{baseName}}=\({{> toString}})") } {{/required}}
{{/formParams}}
request.httpBody = formEncodedItems.joined(separator: "&").data(using: .utf8)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
{{/isMultipart}}
{{/hasFormParams}}
return request
}.publisher
}.flatMap { request -> AnyPublisher<{{{returnType}}}{{^returnType}}Void{{/returnType}}, Error> in
return self.transport.send(request: request)
{{#vendorExtensions.x-swift-custom-error-type}}
.mapError { transportError -> Error in
{{#responses}}
{{#vendorExtensions.x-swift-has-custom-error-type}}
if transportError.statusCode == {{{code}}} {
{{#dataType}}
do {
let error = try self.decoder.decode({{{dataType}}}.self, from: transportError.data)
return {{{vendorExtensions.x-swift-custom-error-type}}}.code{{{code}}}Error(error)
} catch {
return error
}
{{/dataType}}
{{^dataType}}
return {{{vendorExtensions.x-swift-custom-error-type}}}.code{{{code}}}Error
{{/dataType}}
}
{{/vendorExtensions.x-swift-has-custom-error-type}}
{{/responses}}
return transportError
}
{{/vendorExtensions.x-swift-custom-error-type}}
.tryMap { response in
{{#returnType}}
{{#vendorExtensions.x-swift-is-not-codable}}
if let object = try JSONSerialization.jsonObject(with: response.data, options: []) as? {{{returnType}}} {
return object
} else {
throw OpenAPITransportError.invalidResponseMappingError(data: response.data)
}
{{/vendorExtensions.x-swift-is-not-codable}}
{{^vendorExtensions.x-swift-is-not-codable}}
try self.decoder.decode({{{returnType}}}.self, from: response.data)
{{/vendorExtensions.x-swift-is-not-codable}}
{{/returnType}}
{{^returnType}}
return ()
{{/returnType}}
}
.eraseToAnyPublisher()
}.eraseToAnyPublisher()
}
{{/operation}}
}
{{/operations}}