diff --git a/README.md b/README.md index 5842ed5..a4a38cc 100644 --- a/README.md +++ b/README.md @@ -326,7 +326,7 @@ import PackageDescription let package = Package( name: "SomeProject", dependencies: [ - .package(url: "https://github.com/dankinsoid/swift-api-client.git", from: "1.7.3") + .package(url: "https://github.com/dankinsoid/swift-api-client.git", from: "1.7.4") ], targets: [ .target( diff --git a/Sources/SwiftAPIClient/Modifiers/RequestModifiers.swift b/Sources/SwiftAPIClient/Modifiers/RequestModifiers.swift index 889eccb..d352715 100644 --- a/Sources/SwiftAPIClient/Modifiers/RequestModifiers.swift +++ b/Sources/SwiftAPIClient/Modifiers/RequestModifiers.swift @@ -275,7 +275,7 @@ public extension RequestBuilder where Request == HTTPRequestComponents { /// - newBaseURL: The new base URL to set. /// - Returns: An instance with the updated base URL. /// - /// - Note: The path, query, and fragment of the original URL are retained, while those of the new URL are ignored. + /// - Note: The query, and fragment of the original URL are retained, while those of the new URL are ignored. func baseURL(_ newBaseURL: URL) -> Self { modifyRequest { $0.urlComponents.scheme = newBaseURL.scheme @@ -284,19 +284,38 @@ public extension RequestBuilder where Request == HTTPRequestComponents { if let host = newBaseURL.host(percentEncoded: false) { $0.urlComponents.host = host } + $0.prependPath(newBaseURL.path(percentEncoded: false)) } else { if let host = newBaseURL.host { $0.urlComponents.percentEncodedHost = host } + if !newBaseURL.path.isEmpty { + $0.prependPath(newBaseURL.path, percentEncoded: true) + } } #else if let host = newBaseURL.host { $0.urlComponents.percentEncodedHost = host } + if !newBaseURL.path.isEmpty { + $0.prependPath(newBaseURL.path, percentEncoded: true) + } #endif $0.urlComponents.port = newBaseURL.port } } + + /// Sets the URL for the request. + /// - Parameter url: The new URL to set. + /// - Returns: An instance with the updated URL. + func url(_ url: URL) -> Self { + modifyRequest { + guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else { + throw Errors.custom("Invalid URL \(url.absoluteString) components") + } + $0.urlComponents = components + } + } /// Sets the scheme for the request. /// diff --git a/Sources/SwiftAPIClient/Types/HTTPRequestComponents.swift b/Sources/SwiftAPIClient/Types/HTTPRequestComponents.swift index 3aaf12a..3293107 100644 --- a/Sources/SwiftAPIClient/Types/HTTPRequestComponents.swift +++ b/Sources/SwiftAPIClient/Types/HTTPRequestComponents.swift @@ -214,6 +214,26 @@ public struct HTTPRequestComponents: Sendable, Hashable { urlComponents.path += "/" } } + + public mutating func prependPath( + _ pathComponent: String, + percentEncoded: Bool = false + ) { + var path = pathComponent + if path.hasSuffix("/"), urlComponents.path.hasPrefix("/") { + path.removeLast() + } else if !path.hasSuffix("/"), !urlComponents.path.hasPrefix("/") { + path += "/" + } + if percentEncoded { + urlComponents.percentEncodedPath = path + urlComponents.percentEncodedPath + } else { + urlComponents.path = path + urlComponents.path + } + if !urlComponents.path.isEmpty, !urlComponents.path.hasSuffix("/") { + urlComponents.path += "/" + } + } } extension HTTPRequestComponents {