Skip to content

Commit e0b2a59

Browse files
authored
Implement HTTP Client protocols for sub packages (#42)
* Adopt HTTPClient protocol * Adopt Storage http client * Use DefaultPostgrestHTTPClient * Remove unused autoRefreshToken param * Add support for passing a custom http client on initializer * Fix doc comments for SupabaseClient * Point dependencies to master
1 parent 0424cd0 commit e0b2a59

File tree

3 files changed

+73
-53
lines changed

3 files changed

+73
-53
lines changed

Package.resolved

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ let package = Package(
1616
.library(
1717
name: "Supabase",
1818
targets: ["Supabase"]
19-
)
19+
),
2020
],
2121
dependencies: [
2222
.package(url: "https://github.com/supabase-community/gotrue-swift", from: "0.0.7"),
23-
.package(url: "https://github.com/supabase-community/storage-swift.git", from: "0.0.2"),
23+
.package(url: "https://github.com/supabase-community/storage-swift.git", branch: "master"),
2424
.package(url: "https://github.com/supabase-community/realtime-swift.git", from: "0.0.1"),
25-
.package(url: "https://github.com/supabase-community/postgrest-swift", from: "0.0.6"),
25+
.package(
26+
url: "https://github.com/supabase-community/postgrest-swift",
27+
branch: "master"
28+
),
2629
],
2730
targets: [
2831
.target(
@@ -33,6 +36,6 @@ let package = Package(
3336
.product(name: "Realtime", package: "realtime-swift"),
3437
.product(name: "PostgREST", package: "postgrest-swift"),
3538
]
36-
)
39+
),
3740
]
3841
)

Sources/Supabase/SupabaseClient.swift

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,25 @@ import PostgREST
44
import Realtime
55
import SupabaseStorage
66

7-
/// The main class for accessing Supabase functionality
8-
///
9-
/// Initialize this class using `.init(supabaseURL: String, supabaseKey: String)`
10-
///
11-
/// There are four main classes contained by the `Supabase` class.
12-
/// 1. `auth`
13-
/// 2. `database`
14-
/// 3. `realtime`
15-
/// 4. `storage`
16-
/// Each class listed is available under `Supabase.{name}`, eg: `Supabase.auth`
17-
///
18-
/// For more usage information read the README.md
7+
/// Supabase Client.
198
public class SupabaseClient {
20-
private var supabaseURL: URL
21-
private var supabaseKey: String
22-
private var schema: String
23-
private var restURL: URL
24-
private var realtimeURL: URL
25-
private var authURL: URL
26-
private var storageURL: URL
27-
28-
/// Auth client for Supabase.
9+
private let supabaseURL: URL
10+
private let supabaseKey: String
11+
private let schema: String
12+
private let restURL: URL
13+
private let realtimeURL: URL
14+
private let authURL: URL
15+
private let storageURL: URL
16+
17+
/// Supabase Auth allows you to create and manage user sessions for access to data that is secured
18+
/// by access policies.
2919
public let auth: GoTrueClient
3020

31-
/// Storage client for Supabase.
21+
/// Supabase Storage allows you to manage user-generated content, such as photos or videos.
3222
public var storage: SupabaseStorageClient {
3323
var headers: [String: String] = defaultHeaders
3424
headers["Authorization"] = "Bearer \(auth.session?.accessToken ?? supabaseKey)"
35-
return SupabaseStorageClient(url: storageURL.absoluteString, headers: headers)
25+
return SupabaseStorageClient(url: storageURL.absoluteString, headers: headers, http: self)
3626
}
3727

3828
/// Database client for Supabase.
@@ -43,7 +33,7 @@ public class SupabaseClient {
4333
url: restURL.absoluteString,
4434
headers: headers,
4535
schema: schema,
46-
delegate: self
36+
http: self
4737
)
4838
}
4939

@@ -57,16 +47,18 @@ public class SupabaseClient {
5747
/// - supabaseURL: Unique Supabase project url
5848
/// - supabaseKey: Supabase anonymous API Key
5949
/// - schema: Database schema name, defaults to `public`
60-
/// - autoRefreshToken: Toggles whether `Supabase.auth` automatically refreshes auth tokens. Defaults to `true`
50+
/// - autoRefreshToken: Toggles whether `Supabase.auth` automatically refreshes auth tokens.
51+
/// Defaults to `true`
6152
public init(
6253
supabaseURL: URL,
6354
supabaseKey: String,
6455
schema: String = "public",
65-
autoRefreshToken: Bool = true
56+
httpClient: HTTPClient = HTTPClient()
6657
) {
6758
self.supabaseURL = supabaseURL
6859
self.supabaseKey = supabaseKey
6960
self.schema = schema
61+
self.httpClient = httpClient
7062
restURL = supabaseURL.appendingPathComponent("/rest/v1")
7163
realtimeURL = supabaseURL.appendingPathComponent("/realtime/v1")
7264
authURL = supabaseURL.appendingPathComponent("/auth/v1")
@@ -83,25 +75,50 @@ public class SupabaseClient {
8375
)
8476
realtime = RealtimeClient(endPoint: realtimeURL.absoluteString, params: defaultHeaders)
8577
}
78+
79+
public struct HTTPClient {
80+
public let storage: StorageHTTPClient
81+
public let postgrest: PostgrestHTTPClient
82+
83+
public init(storage: StorageHTTPClient? = nil, postgrest: PostgrestHTTPClient? = nil) {
84+
self.storage = storage ?? DefaultStorageHTTPClient()
85+
self.postgrest = postgrest ?? DefaultPostgrestHTTPClient()
86+
}
87+
}
88+
89+
private let httpClient: HTTPClient
8690
}
8791

88-
extension SupabaseClient: PostgrestClientDelegate {
89-
public func client(
90-
_ client: PostgrestClient,
91-
willSendRequest request: URLRequest,
92-
completion: @escaping (URLRequest) -> Void
93-
) {
94-
Task {
95-
do {
96-
try await auth.refreshCurrentSessionIfNeeded()
97-
var request = request
98-
if let accessToken = auth.session?.accessToken {
99-
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
100-
}
101-
completion(request)
102-
} catch {
103-
completion(request)
104-
}
92+
extension SupabaseClient {
93+
func adapt(request: URLRequest) async throws -> URLRequest {
94+
try await auth.refreshCurrentSessionIfNeeded()
95+
96+
var request = request
97+
if let accessToken = auth.session?.accessToken {
98+
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
10599
}
100+
return request
101+
}
102+
}
103+
104+
extension SupabaseClient: PostgrestHTTPClient {
105+
public func execute(_ request: URLRequest) async throws -> (Data, HTTPURLResponse) {
106+
let request = try await adapt(request: request)
107+
return try await httpClient.postgrest.execute(request)
108+
}
109+
}
110+
111+
extension SupabaseClient: StorageHTTPClient {
112+
public func fetch(_ request: URLRequest) async throws -> (Data, HTTPURLResponse) {
113+
let request = try await adapt(request: request)
114+
return try await httpClient.storage.fetch(request)
115+
}
116+
117+
public func upload(
118+
_ request: URLRequest,
119+
from data: Data
120+
) async throws -> (Data, HTTPURLResponse) {
121+
let request = try await adapt(request: request)
122+
return try await httpClient.storage.upload(request, from: data)
106123
}
107124
}

0 commit comments

Comments
 (0)