@@ -4,35 +4,25 @@ import PostgREST
4
4
import Realtime
5
5
import SupabaseStorage
6
6
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.
19
8
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.
29
19
public let auth : GoTrueClient
30
20
31
- /// Storage client for Supabase .
21
+ /// Supabase Storage allows you to manage user-generated content, such as photos or videos .
32
22
public var storage : SupabaseStorageClient {
33
23
var headers : [ String : String ] = defaultHeaders
34
24
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 )
36
26
}
37
27
38
28
/// Database client for Supabase.
@@ -43,7 +33,7 @@ public class SupabaseClient {
43
33
url: restURL. absoluteString,
44
34
headers: headers,
45
35
schema: schema,
46
- delegate : self
36
+ http : self
47
37
)
48
38
}
49
39
@@ -57,16 +47,18 @@ public class SupabaseClient {
57
47
/// - supabaseURL: Unique Supabase project url
58
48
/// - supabaseKey: Supabase anonymous API Key
59
49
/// - 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`
61
52
public init (
62
53
supabaseURL: URL ,
63
54
supabaseKey: String ,
64
55
schema: String = " public " ,
65
- autoRefreshToken : Bool = true
56
+ httpClient : HTTPClient = HTTPClient ( )
66
57
) {
67
58
self . supabaseURL = supabaseURL
68
59
self . supabaseKey = supabaseKey
69
60
self . schema = schema
61
+ self . httpClient = httpClient
70
62
restURL = supabaseURL. appendingPathComponent ( " /rest/v1 " )
71
63
realtimeURL = supabaseURL. appendingPathComponent ( " /realtime/v1 " )
72
64
authURL = supabaseURL. appendingPathComponent ( " /auth/v1 " )
@@ -83,25 +75,50 @@ public class SupabaseClient {
83
75
)
84
76
realtime = RealtimeClient ( endPoint: realtimeURL. absoluteString, params: defaultHeaders)
85
77
}
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
86
90
}
87
91
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 " )
105
99
}
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)
106
123
}
107
124
}
0 commit comments