forked from loafle/openapi-generator-original
Merge remote-tracking branch 'origin' into 7.0.x
This commit is contained in:
@@ -60,6 +60,7 @@ PetstoreClient/Classes/OpenAPIs/Models/User.swift
|
||||
PetstoreClient/Classes/OpenAPIs/OpenISO8601DateFormatter.swift
|
||||
PetstoreClient/Classes/OpenAPIs/SynchronizedDictionary.swift
|
||||
PetstoreClient/Classes/OpenAPIs/URLSessionImplementations.swift
|
||||
PetstoreClient/Classes/OpenAPIs/Validation.swift
|
||||
README.md
|
||||
docs/AdditionalPropertiesClass.md
|
||||
docs/Animal.md
|
||||
|
||||
@@ -1 +1 @@
|
||||
github "Flight-School/AnyCodable" ~> 0.6.1
|
||||
github "Flight-School/AnyCodable" ~> 0.6
|
||||
|
||||
@@ -19,7 +19,7 @@ let package = Package(
|
||||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
.package(url: "https://github.com/Flight-School/AnyCodable", from: "0.6.1"),
|
||||
.package(url: "https://github.com/Flight-School/AnyCodable", .upToNextMajor(from: "0.6.1")),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
|
||||
@@ -11,5 +11,5 @@ Pod::Spec.new do |s|
|
||||
s.homepage = 'https://github.com/openapitools/openapi-generator'
|
||||
s.summary = 'PetstoreClient'
|
||||
s.source_files = 'PetstoreClient/Classes/**/*.swift'
|
||||
s.dependency 'AnyCodable-FlightSchool', '~> 0.6.1'
|
||||
s.dependency 'AnyCodable-FlightSchool', '~> 0.6'
|
||||
end
|
||||
|
||||
@@ -24,13 +24,10 @@ public struct APIHelper {
|
||||
return source.reduce(into: [String: String]()) { result, item in
|
||||
if let collection = item.value as? [Any?] {
|
||||
result[item.key] = collection
|
||||
.compactMap { value in
|
||||
guard let value = value else { return nil }
|
||||
return "\(value)"
|
||||
}
|
||||
.compactMap { value in convertAnyToString(value) }
|
||||
.joined(separator: ",")
|
||||
} else if let value: Any = item.value {
|
||||
result[item.key] = "\(value)"
|
||||
result[item.key] = convertAnyToString(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,13 +47,19 @@ public struct APIHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static func convertAnyToString(_ value: Any?) -> String? {
|
||||
guard let value = value else { return nil }
|
||||
if let value = value as? any RawRepresentable {
|
||||
return "\(value.rawValue)"
|
||||
} else {
|
||||
return "\(value)"
|
||||
}
|
||||
}
|
||||
|
||||
public static func mapValueToPathItem(_ source: Any) -> Any {
|
||||
if let collection = source as? [Any?] {
|
||||
return collection
|
||||
.compactMap { value in
|
||||
guard let value = value else { return nil }
|
||||
return "\(value)"
|
||||
}
|
||||
.compactMap { value in convertAnyToString(value) }
|
||||
.joined(separator: ",")
|
||||
}
|
||||
return source
|
||||
@@ -64,15 +67,12 @@ public struct APIHelper {
|
||||
|
||||
/// maps all values from source to query parameters
|
||||
///
|
||||
/// explode attribute is respected: collection values might be either joined or split up into seperate key value pairs
|
||||
/// explode attribute is respected: collection values might be either joined or split up into separate key value pairs
|
||||
public static func mapValuesToQueryItems(_ source: [String: (wrappedValue: Any?, isExplode: Bool)]) -> [URLQueryItem]? {
|
||||
let destination = source.filter { $0.value.wrappedValue != nil }.reduce(into: [URLQueryItem]()) { result, item in
|
||||
if let collection = item.value.wrappedValue as? [Any?] {
|
||||
|
||||
let collectionValues: [String] = collection.compactMap { value in
|
||||
guard let value = value else { return nil }
|
||||
return "\(value)"
|
||||
}
|
||||
let collectionValues: [String] = collection.compactMap { value in convertAnyToString(value) }
|
||||
|
||||
if !item.value.isExplode {
|
||||
result.append(URLQueryItem(name: item.key, value: collectionValues.joined(separator: ",")))
|
||||
@@ -84,7 +84,7 @@ public struct APIHelper {
|
||||
}
|
||||
|
||||
} else if let value = item.value.wrappedValue {
|
||||
result.append(URLQueryItem(name: item.key, value: "\(value)"))
|
||||
result.append(URLQueryItem(name: item.key, value: convertAnyToString(value)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,16 +101,13 @@ public struct APIHelper {
|
||||
let destination = source.filter { $0.value != nil }.reduce(into: [URLQueryItem]()) { result, item in
|
||||
if let collection = item.value as? [Any?] {
|
||||
collection
|
||||
.compactMap { value in
|
||||
guard let value = value else { return nil }
|
||||
return "\(value)"
|
||||
}
|
||||
.compactMap { value in convertAnyToString(value) }
|
||||
.forEach { value in
|
||||
result.append(URLQueryItem(name: item.key, value: value))
|
||||
}
|
||||
|
||||
} else if let value = item.value {
|
||||
result.append(URLQueryItem(name: item.key, value: "\(value)"))
|
||||
result.append(URLQueryItem(name: item.key, value: convertAnyToString(value)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,12 @@ open class PetAPI {
|
||||
/**
|
||||
Add a new pet to the store
|
||||
- POST /pet
|
||||
- API Key:
|
||||
- type: apiKey api_key_query (QUERY)
|
||||
- name: api_key_query
|
||||
- OAuth:
|
||||
- type: oauth2
|
||||
- name: petstore_auth
|
||||
- API Key:
|
||||
- type: apiKey api_key_query (QUERY)
|
||||
- name: api_key_query
|
||||
- parameter body: (body) Pet object that needs to be added to the store
|
||||
- returns: RequestBuilder<Void>
|
||||
*/
|
||||
@@ -247,7 +247,7 @@ open class PetAPI {
|
||||
- GET /pet/{petId}
|
||||
- Returns a single pet
|
||||
- API Key:
|
||||
- type: apiKey api_key
|
||||
- type: apiKey api_key (HEADER)
|
||||
- name: api_key
|
||||
- parameter petId: (path) ID of pet to return
|
||||
- returns: RequestBuilder<Pet>
|
||||
|
||||
@@ -82,7 +82,7 @@ open class StoreAPI {
|
||||
- GET /store/inventory
|
||||
- Returns a map of status codes to quantities
|
||||
- API Key:
|
||||
- type: apiKey api_key
|
||||
- type: apiKey api_key (HEADER)
|
||||
- name: api_key
|
||||
- returns: RequestBuilder<[String: Int]>
|
||||
*/
|
||||
@@ -126,7 +126,7 @@ open class StoreAPI {
|
||||
/**
|
||||
Find purchase order by ID
|
||||
- GET /store/order/{order_id}
|
||||
- For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
|
||||
- For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions
|
||||
- parameter orderId: (path) ID of pet that needs to be fetched
|
||||
- returns: RequestBuilder<Order>
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,10 @@ extension Double: JSONEncodable {
|
||||
func encodeToJSON() -> Any { self }
|
||||
}
|
||||
|
||||
extension Decimal: JSONEncodable {
|
||||
func encodeToJSON() -> Any { self }
|
||||
}
|
||||
|
||||
extension String: JSONEncodable {
|
||||
func encodeToJSON() -> Any { self }
|
||||
}
|
||||
|
||||
@@ -86,14 +86,16 @@ open class Response<T> {
|
||||
public let statusCode: Int
|
||||
public let header: [String: String]
|
||||
public let body: T
|
||||
public let bodyData: Data?
|
||||
|
||||
public init(statusCode: Int, header: [String: String], body: T) {
|
||||
public init(statusCode: Int, header: [String: String], body: T, bodyData: Data?) {
|
||||
self.statusCode = statusCode
|
||||
self.header = header
|
||||
self.body = body
|
||||
self.bodyData = bodyData
|
||||
}
|
||||
|
||||
public convenience init(response: HTTPURLResponse, body: T) {
|
||||
public convenience init(response: HTTPURLResponse, body: T, bodyData: Data?) {
|
||||
let rawHeader = response.allHeaderFields
|
||||
var header = [String: String]()
|
||||
for (key, value) in rawHeader {
|
||||
@@ -101,7 +103,7 @@ open class Response<T> {
|
||||
header[key] = value
|
||||
}
|
||||
}
|
||||
self.init(statusCode: response.statusCode, header: header, body: body)
|
||||
self.init(statusCode: response.statusCode, header: header, body: body, bodyData: bodyData)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,13 @@ import AnyCodable
|
||||
|
||||
public struct FormatTest: Codable, JSONEncodable {
|
||||
|
||||
static let integerRule = NumericRule<Int>(minimum: 10, exclusiveMinimum: false, maximum: 100, exclusiveMaximum: false, multipleOf: nil)
|
||||
static let int32Rule = NumericRule<Int>(minimum: 20, exclusiveMinimum: false, maximum: 200, exclusiveMaximum: false, multipleOf: nil)
|
||||
static let numberRule = NumericRule<Double>(minimum: 32.1, exclusiveMinimum: false, maximum: 543.2, exclusiveMaximum: false, multipleOf: nil)
|
||||
static let floatRule = NumericRule<Float>(minimum: 54.3, exclusiveMinimum: false, maximum: 987.6, exclusiveMaximum: false, multipleOf: nil)
|
||||
static let doubleRule = NumericRule<Double>(minimum: 67.8, exclusiveMinimum: false, maximum: 123.4, exclusiveMaximum: false, multipleOf: nil)
|
||||
static let stringRule = StringRule(minLength: nil, maxLength: nil, pattern: "/[a-z]/i")
|
||||
static let passwordRule = StringRule(minLength: 10, maxLength: 64, pattern: nil)
|
||||
public var integer: Int?
|
||||
public var int32: Int?
|
||||
public var int64: Int64?
|
||||
|
||||
@@ -10,7 +10,7 @@ import MobileCoreServices
|
||||
#endif
|
||||
|
||||
public protocol URLSessionProtocol {
|
||||
func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
|
||||
func dataTask(with request: URLRequest, completionHandler: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
|
||||
}
|
||||
|
||||
extension URLSession: URLSessionProtocol {}
|
||||
@@ -122,11 +122,11 @@ open class URLSessionRequestBuilder<T>: RequestBuilder<T> {
|
||||
case .options, .post, .put, .patch, .delete, .trace, .connect:
|
||||
let contentType = headers["Content-Type"] ?? "application/json"
|
||||
|
||||
if contentType == "application/json" {
|
||||
if contentType.hasPrefix("application/json") {
|
||||
encoding = JSONDataEncoding()
|
||||
} else if contentType == "multipart/form-data" {
|
||||
} else if contentType.hasPrefix("multipart/form-data") {
|
||||
encoding = FormDataEncoding(contentTypeForFormPart: contentTypeForFormPart(fileURL:))
|
||||
} else if contentType == "application/x-www-form-urlencoded" {
|
||||
} else if contentType.hasPrefix("application/x-www-form-urlencoded") {
|
||||
encoding = FormURLEncoding()
|
||||
} else {
|
||||
fatalError("Unsupported Media Type - \(contentType)")
|
||||
@@ -208,7 +208,7 @@ open class URLSessionRequestBuilder<T>: RequestBuilder<T> {
|
||||
switch T.self {
|
||||
case is Void.Type:
|
||||
|
||||
completion(.success(Response(response: httpResponse, body: () as! T)))
|
||||
completion(.success(Response(response: httpResponse, body: () as! T, bodyData: data)))
|
||||
|
||||
default:
|
||||
fatalError("Unsupported Response Body Type - \(String(describing: T.self))")
|
||||
@@ -303,7 +303,7 @@ open class URLSessionDecodableRequestBuilder<T: Decodable>: URLSessionRequestBui
|
||||
|
||||
let body = data.flatMap { String(data: $0, encoding: .utf8) } ?? ""
|
||||
|
||||
completion(.success(Response<T>(response: httpResponse, body: body as! T)))
|
||||
completion(.success(Response<T>(response: httpResponse, body: body as! T, bodyData: data)))
|
||||
|
||||
case is URL.Type:
|
||||
do {
|
||||
@@ -334,7 +334,7 @@ open class URLSessionDecodableRequestBuilder<T: Decodable>: URLSessionRequestBui
|
||||
try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)
|
||||
try data.write(to: filePath, options: .atomic)
|
||||
|
||||
completion(.success(Response(response: httpResponse, body: filePath as! T)))
|
||||
completion(.success(Response(response: httpResponse, body: filePath as! T, bodyData: data)))
|
||||
|
||||
} catch let requestParserError as DownloadException {
|
||||
completion(.failure(ErrorResponse.error(400, data, response, requestParserError)))
|
||||
@@ -344,30 +344,30 @@ open class URLSessionDecodableRequestBuilder<T: Decodable>: URLSessionRequestBui
|
||||
|
||||
case is Void.Type:
|
||||
|
||||
completion(.success(Response(response: httpResponse, body: () as! T)))
|
||||
completion(.success(Response(response: httpResponse, body: () as! T, bodyData: data)))
|
||||
|
||||
case is Data.Type:
|
||||
|
||||
completion(.success(Response(response: httpResponse, body: data as! T)))
|
||||
completion(.success(Response(response: httpResponse, body: data as! T, bodyData: data)))
|
||||
|
||||
default:
|
||||
|
||||
guard let data = data, !data.isEmpty else {
|
||||
guard let unwrappedData = data, !unwrappedData.isEmpty else {
|
||||
if let E = T.self as? ExpressibleByNilLiteral.Type {
|
||||
completion(.success(Response(response: httpResponse, body: E.init(nilLiteral: ()) as! T)))
|
||||
completion(.success(Response(response: httpResponse, body: E.init(nilLiteral: ()) as! T, bodyData: data)))
|
||||
} else {
|
||||
completion(.failure(ErrorResponse.error(httpResponse.statusCode, nil, response, DecodableRequestBuilderError.emptyDataResponse)))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let decodeResult = CodableHelper.decode(T.self, from: data)
|
||||
let decodeResult = CodableHelper.decode(T.self, from: unwrappedData)
|
||||
|
||||
switch decodeResult {
|
||||
case let .success(decodableObj):
|
||||
completion(.success(Response(response: httpResponse, body: decodableObj)))
|
||||
completion(.success(Response(response: httpResponse, body: decodableObj, bodyData: unwrappedData)))
|
||||
case let .failure(error):
|
||||
completion(.failure(ErrorResponse.error(httpResponse.statusCode, data, response, error)))
|
||||
completion(.failure(ErrorResponse.error(httpResponse.statusCode, unwrappedData, response, error)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
// Validation.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct StringRule {
|
||||
public var minLength: Int?
|
||||
public var maxLength: Int?
|
||||
public var pattern: String?
|
||||
}
|
||||
|
||||
public struct NumericRule<T: Comparable & Numeric> {
|
||||
public var minimum: T?
|
||||
public var exclusiveMinimum = false
|
||||
public var maximum: T?
|
||||
public var exclusiveMaximum = false
|
||||
public var multipleOf: T?
|
||||
}
|
||||
|
||||
public enum StringValidationErrorKind: Error {
|
||||
case minLength, maxLength, pattern
|
||||
}
|
||||
|
||||
public enum NumericValidationErrorKind: Error {
|
||||
case minimum, maximum, multipleOf
|
||||
}
|
||||
|
||||
public struct ValidationError<T: Error & Hashable>: Error {
|
||||
public fileprivate(set) var kinds: Set<T>
|
||||
}
|
||||
|
||||
public struct Validator {
|
||||
/// Validate a string against a rule.
|
||||
/// - Parameter string: The String you wish to validate.
|
||||
/// - Parameter rule: The StringRule you wish to use for validation.
|
||||
/// - Returns: A validated string.
|
||||
/// - Throws: `ValidationError<StringValidationErrorKind>` if the string is invalid against the rule,
|
||||
/// `NSError` if the rule.pattern is invalid.
|
||||
public static func validate(_ string: String, against rule: StringRule) throws -> String {
|
||||
var error = ValidationError<StringValidationErrorKind>(kinds: [])
|
||||
if let minLength = rule.minLength, !(minLength <= string.count) {
|
||||
error.kinds.insert(.minLength)
|
||||
}
|
||||
if let maxLength = rule.maxLength, !(string.count <= maxLength) {
|
||||
error.kinds.insert(.maxLength)
|
||||
}
|
||||
if let pattern = rule.pattern {
|
||||
let matches = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
|
||||
.matches(in: string, range: .init(location: 0, length: string.utf16.count))
|
||||
if matches.isEmpty {
|
||||
error.kinds.insert(.pattern)
|
||||
}
|
||||
}
|
||||
guard error.kinds.isEmpty else {
|
||||
throw error
|
||||
}
|
||||
return string
|
||||
}
|
||||
|
||||
/// Validate a integer against a rule.
|
||||
/// - Parameter numeric: The integer you wish to validate.
|
||||
/// - Parameter rule: The NumericRule you wish to use for validation.
|
||||
/// - Returns: A validated integer.
|
||||
/// - Throws: `ValidationError<NumericValidationErrorKind>` if the numeric is invalid against the rule.
|
||||
public static func validate<T: Comparable & BinaryInteger>(_ numeric: T, against rule: NumericRule<T>) throws -> T {
|
||||
var error = ValidationError<NumericValidationErrorKind>(kinds: [])
|
||||
if let minium = rule.minimum {
|
||||
if !rule.exclusiveMinimum, !(minium <= numeric) {
|
||||
error.kinds.insert(.minimum)
|
||||
}
|
||||
if rule.exclusiveMinimum, !(minium < numeric) {
|
||||
error.kinds.insert(.minimum)
|
||||
}
|
||||
}
|
||||
if let maximum = rule.maximum {
|
||||
if !rule.exclusiveMaximum, !(numeric <= maximum) {
|
||||
error.kinds.insert(.maximum)
|
||||
}
|
||||
if rule.exclusiveMaximum, !(numeric < maximum) {
|
||||
error.kinds.insert(.maximum)
|
||||
}
|
||||
}
|
||||
if let multipleOf = rule.multipleOf, !numeric.isMultiple(of: multipleOf) {
|
||||
error.kinds.insert(.multipleOf)
|
||||
}
|
||||
guard error.kinds.isEmpty else {
|
||||
throw error
|
||||
}
|
||||
return numeric
|
||||
}
|
||||
|
||||
/// Validate a fractional number against a rule.
|
||||
/// - Parameter numeric: The fractional number you wish to validate.
|
||||
/// - Parameter rule: The NumericRule you wish to use for validation.
|
||||
/// - Returns: A validated fractional number.
|
||||
/// - Throws: `ValidationError<NumericValidationErrorKind>` if the numeric is invalid against the rule.
|
||||
public static func validate<T: Comparable & FloatingPoint>(_ numeric: T, against rule: NumericRule<T>) throws -> T {
|
||||
var error = ValidationError<NumericValidationErrorKind>(kinds: [])
|
||||
if let minium = rule.minimum {
|
||||
if !rule.exclusiveMinimum, !(minium <= numeric) {
|
||||
error.kinds.insert(.minimum)
|
||||
}
|
||||
if rule.exclusiveMinimum, !(minium < numeric) {
|
||||
error.kinds.insert(.minimum)
|
||||
}
|
||||
}
|
||||
if let maximum = rule.maximum {
|
||||
if !rule.exclusiveMaximum, !(numeric <= maximum) {
|
||||
error.kinds.insert(.maximum)
|
||||
}
|
||||
if rule.exclusiveMaximum, !(numeric < maximum) {
|
||||
error.kinds.insert(.maximum)
|
||||
}
|
||||
}
|
||||
if let multipleOf = rule.multipleOf, numeric.remainder(dividingBy: multipleOf) != 0 {
|
||||
error.kinds.insert(.multipleOf)
|
||||
}
|
||||
guard error.kinds.isEmpty else {
|
||||
throw error
|
||||
}
|
||||
return numeric
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,15 @@ Class | Method | HTTP request | Description
|
||||
## Documentation For Authorization
|
||||
|
||||
|
||||
## petstore_auth
|
||||
|
||||
- **Type**: OAuth
|
||||
- **Flow**: implicit
|
||||
- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog
|
||||
- **Scopes**:
|
||||
- **write:pets**: modify pets in your account
|
||||
- **read:pets**: read your pets
|
||||
|
||||
## api_key
|
||||
|
||||
- **Type**: API key
|
||||
@@ -125,15 +134,6 @@ Class | Method | HTTP request | Description
|
||||
|
||||
- **Type**: HTTP basic authentication
|
||||
|
||||
## petstore_auth
|
||||
|
||||
- **Type**: OAuth
|
||||
- **Flow**: implicit
|
||||
- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog
|
||||
- **Scopes**:
|
||||
- **write:pets**: modify pets in your account
|
||||
- **read:pets**: read your pets
|
||||
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ Void (empty response body)
|
||||
|
||||
### Authorization
|
||||
|
||||
[api_key_query](../README.md#api_key_query), [petstore_auth](../README.md#petstore_auth)
|
||||
[petstore_auth](../README.md#petstore_auth), [api_key_query](../README.md#api_key_query)
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ This endpoint does not need any parameter.
|
||||
|
||||
Find purchase order by ID
|
||||
|
||||
For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
|
||||
For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions
|
||||
|
||||
### Example
|
||||
```swift
|
||||
|
||||
Reference in New Issue
Block a user