Merge remote-tracking branch 'origin' into 7.0.x

This commit is contained in:
William Cheng
2023-03-03 21:52:50 +08:00
10595 changed files with 418520 additions and 73194 deletions

View File

@@ -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

View File

@@ -1 +1 @@
github "Flight-School/AnyCodable" ~> 0.6.1
github "Flight-School/AnyCodable" ~> 0.6

View File

@@ -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.

View File

@@ -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

View File

@@ -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)))
}
}

View File

@@ -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>

View File

@@ -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>
*/

View File

@@ -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 }
}

View File

@@ -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)
}
}

View File

@@ -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?

View File

@@ -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)))
}
}
}

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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