Skip to content

Commit 415fd24

Browse files
committed
clean up and deprecate init with fetch
1 parent 45abd97 commit 415fd24

File tree

2 files changed

+90
-41
lines changed

2 files changed

+90
-41
lines changed

Sources/Functions/FunctionsClient.swift

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,41 @@ import OpenAPIURLSession
1010

1111
let version = Helpers.version
1212

13+
/// A ClientTransport implementation that adapts the old Fetch api.
14+
struct FetchTransportAdapter: ClientTransport {
15+
let fetch: FunctionsClient.FetchHandler
16+
17+
init(fetch: @escaping FunctionsClient.FetchHandler) {
18+
self.fetch = fetch
19+
}
20+
21+
func send(
22+
_ request: HTTPTypes.HTTPRequest,
23+
body: HTTPBody?,
24+
baseURL: URL,
25+
operationID: String
26+
) async throws -> (HTTPTypes.HTTPResponse, HTTPBody?) {
27+
guard var urlRequest = URLRequest(httpRequest: request) else {
28+
throw URLError(.badURL)
29+
}
30+
31+
if let body {
32+
urlRequest.httpBody = try await Data(collecting: body, upTo: .max)
33+
}
34+
35+
let (data, response) = try await fetch(urlRequest)
36+
37+
guard let httpURLResponse = response as? HTTPURLResponse,
38+
let httpResponse = httpURLResponse.httpResponse
39+
else {
40+
throw URLError(.badServerResponse)
41+
}
42+
43+
let body = HTTPBody(data)
44+
return (httpResponse, body)
45+
}
46+
}
47+
1348
/// An actor representing a client for invoking functions.
1449
public final class FunctionsClient: Sendable {
1550
/// Fetch handler used to make requests.
@@ -34,9 +69,7 @@ public final class FunctionsClient: Sendable {
3469
}
3570

3671
private let client: Client
37-
private let http: any HTTPClientType
3872
private let mutableState = LockIsolated(MutableState())
39-
private let sessionConfiguration: URLSessionConfiguration
4073

4174
var headers: HTTPFields {
4275
mutableState.headers
@@ -50,62 +83,51 @@ public final class FunctionsClient: Sendable {
5083
/// - region: The Region to invoke the functions in.
5184
/// - logger: SupabaseLogger instance to use.
5285
/// - fetch: The fetch handler used to make requests. (Default: URLSession.shared.data(for:))
86+
@available(*, deprecated, message: "Fetch handler is deprecated, use init with `transport` instead.")
5387
@_disfavoredOverload
5488
public convenience init(
5589
url: URL,
5690
headers: [String: String] = [:],
5791
region: String? = nil,
5892
logger: (any SupabaseLogger)? = nil,
59-
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) }
93+
fetch: @escaping FetchHandler
6094
) {
6195
self.init(
6296
url: url,
6397
headers: headers,
6498
region: region,
6599
logger: logger,
66-
fetch: fetch,
67-
sessionConfiguration: .default
100+
client: Client(serverURL: url, transport: FetchTransportAdapter(fetch: fetch))
68101
)
69102
}
70103

71-
convenience init(
104+
@_disfavoredOverload
105+
public convenience init(
72106
url: URL,
73107
headers: [String: String] = [:],
74108
region: String? = nil,
75109
logger: (any SupabaseLogger)? = nil,
76-
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) },
77-
sessionConfiguration: URLSessionConfiguration
110+
transport: (any ClientTransport)? = nil
78111
) {
79-
var interceptors: [any HTTPClientInterceptor] = []
80-
if let logger {
81-
interceptors.append(LoggerInterceptor(logger: logger))
82-
}
83-
84-
let http = HTTPClient(fetch: fetch, interceptors: interceptors)
85-
86112
self.init(
87113
url: url,
88114
headers: headers,
89115
region: region,
90-
http: http,
91-
client: Client(serverURL: url, transport: URLSessionTransport()),
92-
sessionConfiguration: sessionConfiguration
116+
logger: logger,
117+
client: Client(serverURL: url, transport: transport ?? URLSessionTransport())
93118
)
94119
}
95120

96121
init(
97122
url: URL,
98-
headers: [String: String],
99-
region: String?,
100-
http: any HTTPClientType,
101-
client: Client,
102-
sessionConfiguration: URLSessionConfiguration = .default
123+
headers: [String: String] = [:],
124+
region: String? = nil,
125+
logger: (any SupabaseLogger)? = nil,
126+
client: Client
103127
) {
104128
self.url = url
105129
self.region = region
106-
self.http = http
107130
self.client = client
108-
self.sessionConfiguration = sessionConfiguration
109131

110132
mutableState.withValue {
111133
$0.headers = HTTPFields(headers)
@@ -123,14 +145,38 @@ public final class FunctionsClient: Sendable {
123145
/// - region: The Region to invoke the functions in.
124146
/// - logger: SupabaseLogger instance to use.
125147
/// - fetch: The fetch handler used to make requests. (Default: URLSession.shared.data(for:))
148+
149+
@available(*, deprecated, message: "Fetch handler is deprecated, use init with `transport` instead.")
150+
public convenience init(
151+
url: URL,
152+
headers: [String: String] = [:],
153+
region: FunctionRegion? = nil,
154+
logger: (any SupabaseLogger)? = nil,
155+
fetch: @escaping FetchHandler
156+
) {
157+
self.init(
158+
url: url,
159+
headers: headers,
160+
region: region?.rawValue,
161+
logger: logger,
162+
fetch: fetch
163+
)
164+
}
165+
126166
public convenience init(
127167
url: URL,
128168
headers: [String: String] = [:],
129169
region: FunctionRegion? = nil,
130170
logger: (any SupabaseLogger)? = nil,
131-
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) }
171+
transport: (any ClientTransport)? = nil
132172
) {
133-
self.init(url: url, headers: headers, region: region?.rawValue, logger: logger, fetch: fetch)
173+
self.init(
174+
url: url,
175+
headers: headers,
176+
region: region?.rawValue,
177+
logger: logger,
178+
transport: transport
179+
)
134180
}
135181

136182
/// Updates the authorization header.

Tests/FunctionsTests/FunctionsClientTests.swift

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import ConcurrencyExtras
22
import HTTPTypes
33
import InlineSnapshotTesting
44
import Mocker
5+
import OpenAPIURLSession
56
import TestHelpers
67
import XCTest
78

@@ -11,19 +12,19 @@ import XCTest
1112
import FoundationNetworking
1213
#endif
1314

15+
extension URLSessionConfiguration {
16+
static var mocking: URLSessionConfiguration {
17+
let configuration = URLSessionConfiguration.ephemeral
18+
configuration.protocolClasses = [MockingURLProtocol.self]
19+
return configuration
20+
}
21+
}
22+
1423
final class FunctionsClientTests: XCTestCase {
1524
let url = URL(string: "http://localhost:5432/functions/v1")!
1625
let apiKey =
1726
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0"
1827

19-
let sessionConfiguration: URLSessionConfiguration = {
20-
let sessionConfiguration = URLSessionConfiguration.default
21-
sessionConfiguration.protocolClasses = [MockingURLProtocol.self]
22-
return sessionConfiguration
23-
}()
24-
25-
lazy var session = URLSession(configuration: sessionConfiguration)
26-
2728
var region: String?
2829

2930
lazy var sut = FunctionsClient(
@@ -32,15 +33,18 @@ final class FunctionsClientTests: XCTestCase {
3233
"apikey": apiKey
3334
],
3435
region: region,
35-
fetch: { request in
36-
try await self.session.data(for: request)
37-
},
38-
sessionConfiguration: sessionConfiguration
36+
client: Client(
37+
serverURL: URL(string: "http://localhost:5432")!,
38+
transport: URLSessionTransport(
39+
configuration: URLSessionTransport.Configuration(
40+
session: URLSession(configuration: .mocking)
41+
)
42+
)
43+
)
3944
)
4045

4146
override func setUp() {
4247
super.setUp()
43-
// isRecording = true
4448
}
4549

4650
func testInit() async {
@@ -65,7 +69,6 @@ final class FunctionsClientTests: XCTestCase {
6569
#"""
6670
curl \
6771
--request POST \
68-
--header "Content-Length: 19" \
6972
--header "Content-Type: application/json" \
7073
--header "X-Client-Info: functions-swift/0.0.0" \
7174
--header "X-Custom-Key: value" \

0 commit comments

Comments
 (0)