-
Notifications
You must be signed in to change notification settings - Fork 27
Support for exploded params - self contained patch #1075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,137 @@ | ||||||
// | ||||||
// CommonClient+ExplodedParameters.swift | ||||||
// | ||||||
// Generated by openapi-generator | ||||||
// https://openapi-generator.tech | ||||||
// | ||||||
|
||||||
|
||||||
import Foundation | ||||||
import Backbase | ||||||
import ClientCommonGen2 | ||||||
|
||||||
/// ArrayParam wrapper for controlling OpenAPI array parameter encoding | ||||||
public struct ArrayParam { | ||||||
public init(_ value: [Any?], exploded: Bool) { | ||||||
self.value = value | ||||||
self.explode = exploded | ||||||
} | ||||||
|
||||||
public let value: [Any?] | ||||||
public let explode: Bool | ||||||
|
||||||
/// Returns URLQueryItems based on explode setting | ||||||
func queryItems(for key: String) -> [URLQueryItem] { | ||||||
if explode { | ||||||
return value.compactMap { $0 }.map { URLQueryItem(name: key, value: "\($0)") } | ||||||
} else { | ||||||
let joined = value.compactMap { $0 }.map { "\($0)" }.joined(separator: ",") | ||||||
return [URLQueryItem(name: key, value: joined)] | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
// MARK: - URLEncoding Extension with exploded arguments support | ||||||
public extension URLEncoding { | ||||||
/// Creates a URL request by encoding parameters with exploded array support | ||||||
/// and applying them onto an existing request url. | ||||||
/// | ||||||
/// This method supports the ArrayParam type for controlling exploded vs comma-separated arrays | ||||||
/// according to OpenAPI specification. | ||||||
/// | ||||||
/// - parameter urlRequest: The request to have parameters applied. | ||||||
/// - parameter parameters: The parameters to apply. Can include ArrayParam instances. | ||||||
/// | ||||||
/// - throws: An `Error` if the encoding process encounters an error. | ||||||
/// | ||||||
/// - returns: The encoded request. | ||||||
static func encodeWithExplodedSupport(_ urlRequest: URLRequest, with parameters: [String: Any]?) throws -> URLRequest { | ||||||
var urlRequest = urlRequest | ||||||
guard let parameters = parameters else { return urlRequest } | ||||||
|
||||||
guard let url = urlRequest.url else { | ||||||
throw CallError.requestMissingUrl | ||||||
} | ||||||
|
||||||
if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty { | ||||||
urlComponents.queryItems = mapValuesToQueryItemsWithExplodedSupport(parameters) | ||||||
urlRequest.url = urlComponents.url | ||||||
} | ||||||
|
||||||
return urlRequest | ||||||
} | ||||||
|
||||||
private static func mapValuesToQueryItemsWithExplodedSupport(_ source: [String: Any?]) -> [URLQueryItem]? { | ||||||
let items = source.compactMap { key, value -> [URLQueryItem]? in | ||||||
guard let value else { | ||||||
return nil | ||||||
} | ||||||
|
||||||
switch value { | ||||||
case let array as [Any?]: | ||||||
return ArrayParam(array, exploded: true) | ||||||
.queryItems(for: key) | ||||||
|
||||||
case let arrayParam as ArrayParam: | ||||||
return arrayParam | ||||||
.queryItems(for: key) | ||||||
|
||||||
default: | ||||||
return [URLQueryItem(name: key, value: "\(value)")] | ||||||
} | ||||||
}.flatMap { $0 } | ||||||
|
||||||
return items.isEmpty ? nil : items | ||||||
} | ||||||
} | ||||||
|
||||||
// Helper extensions for easier ArrayParam creation | ||||||
public extension Array { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's need to handle dictionaries as well. |
||||||
/// Creates an ArrayParam with exploded=true for OpenAPI query parameter encoding | ||||||
/// Example: ["a", "b"].exploded -> ?param=a¶m=b | ||||||
var exploded: ArrayParam { | ||||||
ArrayParam(self, exploded: true) | ||||||
} | ||||||
|
||||||
/// Creates an ArrayParam with exploded=false for OpenAPI query parameter encoding | ||||||
/// Example: ["a", "b"].commaSeparated -> ?param=a,b | ||||||
var commaSeparated: ArrayParam { | ||||||
ArrayParam(self, exploded: false) | ||||||
} | ||||||
} | ||||||
|
||||||
// MARK: - RequestBuilder Extension with Custom Encoding | ||||||
public extension RequestBuilder { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
/// createURLRequest with exploded support | ||||||
/// - Parameters: | ||||||
/// - requestUrl: request URL | ||||||
/// - method: method | ||||||
/// - queryParameters: query parameters | ||||||
/// - bodyParameters: body parameters | ||||||
/// - bodyType: BodyType | ||||||
/// - headers: an object of type [String: String] | ||||||
/// - Returns: URLRequest with exploded parameter support | ||||||
static func createURLRequestWithExplodedSupport(requestUrl: URL, | ||||||
method: String, | ||||||
queryParameters: [String: Any]?, | ||||||
bodyParameters: [String: Any]?, | ||||||
bodyType: BodyType, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which |
||||||
headers: [String: String] = [:]) throws -> URLRequest { | ||||||
var modifiedRequest = try URLEncoding.encodeWithExplodedSupport(.init(url: requestUrl), with: queryParameters) | ||||||
modifiedRequest.httpMethod = method | ||||||
headers.forEach { modifiedRequest.setValue($0.value, forHTTPHeaderField: $0.key) } | ||||||
Backbase.authClient().tokens().forEach { modifiedRequest.setValue($0.value, forHTTPHeaderField: $0.key) } | ||||||
|
||||||
switch bodyType { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This switch statement is missing a |
||||||
case .none: | ||||||
break | ||||||
case .json: | ||||||
modifiedRequest = JSONDataEncoding.encode(modifiedRequest, with: bodyParameters) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can't call the |
||||||
case .multipartForm: | ||||||
modifiedRequest = try FileUploadEncoding.encode(modifiedRequest, with: bodyParameters) | ||||||
} | ||||||
|
||||||
return modifiedRequest | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
"{{baseName}}": {{#isFreeFormObject}}(params.{{paramName}} as{{^required}}?{{/required}} String){{^required}}?{{/required}}.encodeToJSON(){{/isFreeFormObject}}{{^isFreeFormObject}}params.{{paramName}}{{^required}}?{{/required}}.{{#isDateTime}}encodeToJSONDateTime{{/isDateTime}}{{^isDateTime}}encodeToJSON{{/isDateTime}}(){{/isFreeFormObject}} | ||
"{{baseName}}": {{#isContainer}}params.{{paramName}}.{{#isExplode}}exploded{{/isExplode}}{{^isExplode}}commaSeparated{{/isExplode}}{{/isContainer}}{{^isContainer}}{{#isFreeFormObject}}(params.{{paramName}} as{{^required}}?{{/required}} String){{^required}}?{{/required}}.encodeToJSON(){{/isFreeFormObject}}{{^isFreeFormObject}}{{#isEnum}}params.{{paramName}}{{^required}}?{{/required}}.rawValue{{/isEnum}}{{^isEnum}}params.{{paramName}}{{^required}}?{{/required}}.{{#isDateTime}}encodeToJSONDateTime{{/isDateTime}}{{^isDateTime}}encodeToJSON{{/isDateTime}}(){{/isEnum}}{{/isFreeFormObject}}{{/isContainer}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a check for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're missing an import statement.
import ClientCommonGen2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing my PR, I added missing import