Skip to content

Commit e1f22a1

Browse files
committed
add _RequestAdapter as a workaround for the invoke with streamed response method
1 parent bd554c5 commit e1f22a1

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

Sources/Functions/FunctionsClient.swift

+52-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import ConcurrencyExtras
22
import Foundation
3-
import Helpers
43
import HTTPTypes
4+
import Helpers
55

66
#if canImport(FoundationNetworking)
77
import FoundationNetworking
@@ -16,6 +16,8 @@ public final class FunctionsClient: Sendable {
1616
Data, URLResponse
1717
)
1818

19+
public typealias _RequestAdapter = @Sendable (URLRequest) async throws -> URLRequest
20+
1921
/// The base URL for the functions.
2022
let url: URL
2123

@@ -29,6 +31,7 @@ public final class FunctionsClient: Sendable {
2931

3032
private let http: any HTTPClientType
3133
private let mutableState = LockIsolated(MutableState())
34+
private let _requestAdapter: _RequestAdapter?
3235

3336
var headers: HTTPFields {
3437
mutableState.headers
@@ -48,27 +51,32 @@ public final class FunctionsClient: Sendable {
4851
headers: [String: String] = [:],
4952
region: String? = nil,
5053
logger: (any SupabaseLogger)? = nil,
51-
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) }
54+
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) },
55+
_requestAdapter: _RequestAdapter? = nil
5256
) {
5357
var interceptors: [any HTTPClientInterceptor] = []
58+
5459
if let logger {
5560
interceptors.append(LoggerInterceptor(logger: logger))
5661
}
5762

5863
let http = HTTPClient(fetch: fetch, interceptors: interceptors)
5964

60-
self.init(url: url, headers: headers, region: region, http: http)
65+
self.init(
66+
url: url, headers: headers, region: region, http: http, _requestAdapter: _requestAdapter)
6167
}
6268

6369
init(
6470
url: URL,
6571
headers: [String: String],
6672
region: String?,
67-
http: any HTTPClientType
73+
http: any HTTPClientType,
74+
_requestAdapter: _RequestAdapter?
6875
) {
6976
self.url = url
7077
self.region = region
7178
self.http = http
79+
self._requestAdapter = _requestAdapter
7280

7381
mutableState.withValue {
7482
$0.headers = HTTPFields(headers)
@@ -91,9 +99,17 @@ public final class FunctionsClient: Sendable {
9199
headers: [String: String] = [:],
92100
region: FunctionRegion? = nil,
93101
logger: (any SupabaseLogger)? = nil,
94-
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) }
102+
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) },
103+
_requestAdapter: _RequestAdapter? = nil
95104
) {
96-
self.init(url: url, headers: headers, region: region?.rawValue, logger: logger, fetch: fetch)
105+
self.init(
106+
url: url,
107+
headers: headers,
108+
region: region?.rawValue,
109+
logger: logger,
110+
fetch: fetch,
111+
_requestAdapter: _requestAdapter
112+
)
97113
}
98114

99115
/// Updates the authorization header.
@@ -164,7 +180,7 @@ public final class FunctionsClient: Sendable {
164180
let request = buildRequest(functionName: functionName, options: invokeOptions)
165181
let response = try await http.send(request)
166182

167-
guard 200 ..< 300 ~= response.statusCode else {
183+
guard 200..<300 ~= response.statusCode else {
168184
throw FunctionsError.httpError(code: response.statusCode, data: response.data)
169185
}
170186

@@ -198,20 +214,37 @@ public final class FunctionsClient: Sendable {
198214

199215
let urlRequest = buildRequest(functionName: functionName, options: invokeOptions).urlRequest
200216

201-
let task = session.dataTask(with: urlRequest)
202-
task.resume()
217+
Task {
218+
let adaptedRequest: URLRequest
203219

204-
continuation.onTermination = { _ in
205-
task.cancel()
220+
if let _requestAdapter {
221+
do {
222+
adaptedRequest = try await _requestAdapter(urlRequest)
223+
} catch {
224+
continuation.finish(throwing: error)
225+
return
226+
}
227+
} else {
228+
adaptedRequest = urlRequest
229+
}
230+
231+
let task = session.dataTask(with: adaptedRequest)
232+
task.resume()
233+
234+
continuation.onTermination = { _ in
235+
task.cancel()
206236

207-
// Hold a strong reference to delegate until continuation terminates.
208-
_ = delegate
237+
// Hold a strong reference to delegate until continuation terminates.
238+
_ = delegate
239+
}
209240
}
210241

211242
return stream
212243
}
213244

214-
private func buildRequest(functionName: String, options: FunctionInvokeOptions) -> Helpers.HTTPRequest {
245+
private func buildRequest(functionName: String, options: FunctionInvokeOptions)
246+
-> Helpers.HTTPRequest
247+
{
215248
var request = HTTPRequest(
216249
url: url.appendingPathComponent(functionName),
217250
method: options.httpMethod ?? .post,
@@ -243,13 +276,16 @@ final class StreamResponseDelegate: NSObject, URLSessionDataDelegate, Sendable {
243276
continuation.finish(throwing: error)
244277
}
245278

246-
func urlSession(_: URLSession, dataTask _: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
279+
func urlSession(
280+
_: URLSession, dataTask _: URLSessionDataTask, didReceive response: URLResponse,
281+
completionHandler: @escaping (URLSession.ResponseDisposition) -> Void
282+
) {
247283
guard let httpResponse = response as? HTTPURLResponse else {
248284
continuation.finish(throwing: URLError(.badServerResponse))
249285
return
250286
}
251287

252-
guard 200 ..< 300 ~= httpResponse.statusCode else {
288+
guard 200..<300 ~= httpResponse.statusCode else {
253289
let error = FunctionsError.httpError(code: httpResponse.statusCode, data: Data())
254290
continuation.finish(throwing: error)
255291
return

Sources/Supabase/SupabaseClient.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ public final class SupabaseClient: Sendable {
9999
headers: headers,
100100
region: options.functions.region,
101101
logger: options.global.logger,
102-
fetch: fetchWithAuth
102+
fetch: fetchWithAuth,
103+
_requestAdapter: adapt
103104
)
104105
}
105106

@@ -347,6 +348,7 @@ public final class SupabaseClient: Sendable {
347348
try await session.upload(for: adapt(request: request), from: data)
348349
}
349350

351+
@Sendable
350352
private func adapt(request: URLRequest) async -> URLRequest {
351353
let token = try? await _getAccessToken()
352354

0 commit comments

Comments
 (0)