Skip to content

Commit aaf0dd1

Browse files
committed
Refactor default initialization values
1 parent 77d9da5 commit aaf0dd1

File tree

8 files changed

+174
-147
lines changed

8 files changed

+174
-147
lines changed

Sources/Auth/AuthClient.swift

+14-22
Original file line numberDiff line numberDiff line change
@@ -33,28 +33,20 @@ public actor AuthClient {
3333
public init(
3434
url: URL,
3535
headers: [String: String] = [:],
36-
flowType: AuthFlowType? = nil,
37-
localStorage: AuthLocalStorage? = nil,
38-
encoder: JSONEncoder? = nil,
39-
decoder: JSONDecoder? = nil,
36+
flowType: AuthFlowType = Configuration.defaultFlowType,
37+
localStorage: AuthLocalStorage = Configuration.defaultLocalStorage,
38+
encoder: JSONEncoder = AuthClient.Configuration.jsonEncoder,
39+
decoder: JSONDecoder = AuthClient.Configuration.jsonDecoder,
4040
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) }
4141
) {
42-
var headers = headers
43-
if headers["X-Client-Info"] == nil {
44-
headers["X-Client-Info"] = "gotrue-swift/\(version)"
45-
}
42+
let headers = headers.merging(Configuration.defaultHeaders) { l, _ in l }
4643

4744
self.url = url
4845
self.headers = headers
49-
self.flowType = flowType ?? .implicit
50-
self.localStorage =
51-
localStorage
52-
?? KeychainLocalStorage(
53-
service: "supabase.gotrue.swift",
54-
accessGroup: nil
55-
)
56-
self.encoder = encoder ?? .auth
57-
self.decoder = decoder ?? .auth
46+
self.flowType = flowType
47+
self.localStorage = localStorage
48+
self.encoder = encoder
49+
self.decoder = decoder
5850
self.fetch = fetch
5951
}
6052
}
@@ -96,18 +88,18 @@ public actor AuthClient {
9688
/// - Parameters:
9789
/// - url: The base URL of the Auth server.
9890
/// - headers: Custom headers to be included in requests.
99-
/// - flowType: The authentication flow type. Default is `.implicit`.
91+
/// - flowType: The authentication flow type..
10092
/// - localStorage: The storage mechanism for local data..
10193
/// - encoder: The JSON encoder to use for encoding requests.
10294
/// - decoder: The JSON decoder to use for decoding responses.
10395
/// - fetch: The asynchronous fetch handler for network requests.
10496
public init(
10597
url: URL,
10698
headers: [String: String] = [:],
107-
flowType: AuthFlowType? = nil,
108-
localStorage: AuthLocalStorage? = nil,
109-
encoder: JSONEncoder? = nil,
110-
decoder: JSONDecoder? = nil,
99+
flowType: AuthFlowType = AuthClient.Configuration.defaultFlowType,
100+
localStorage: AuthLocalStorage = AuthClient.Configuration.defaultLocalStorage,
101+
encoder: JSONEncoder = AuthClient.Configuration.jsonEncoder,
102+
decoder: JSONDecoder = AuthClient.Configuration.jsonDecoder,
111103
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) }
112104
) {
113105
self.init(

Sources/Auth/Defaults.swift

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//
2+
// Defaults.swift
3+
//
4+
//
5+
// Created by Guilherme Souza on 14/12/23.
6+
//
7+
8+
@_spi(Internal) import _Helpers
9+
import Foundation
10+
11+
extension AuthClient.Configuration {
12+
private static let dateFormatterWithFractionalSeconds = { () -> ISO8601DateFormatter in
13+
let formatter = ISO8601DateFormatter()
14+
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
15+
return formatter
16+
}()
17+
18+
private static let dateFormatter = { () -> ISO8601DateFormatter in
19+
let formatter = ISO8601DateFormatter()
20+
formatter.formatOptions = [.withInternetDateTime]
21+
return formatter
22+
}()
23+
24+
/// The default JSONEncoder instance used by the ``AuthClient``.
25+
public static let jsonEncoder: JSONEncoder = {
26+
let encoder = JSONEncoder()
27+
encoder.keyEncodingStrategy = .convertToSnakeCase
28+
encoder.dateEncodingStrategy = .custom { date, encoder in
29+
var container = encoder.singleValueContainer()
30+
let string = dateFormatter.string(from: date)
31+
try container.encode(string)
32+
}
33+
return encoder
34+
}()
35+
36+
/// The default JSONDecoder instance used by the ``AuthClient``.
37+
public static let jsonDecoder: JSONDecoder = {
38+
let decoder = JSONDecoder()
39+
decoder.keyDecodingStrategy = .convertFromSnakeCase
40+
decoder.dateDecodingStrategy = .custom { decoder in
41+
let container = try decoder.singleValueContainer()
42+
let string = try container.decode(String.self)
43+
44+
let supportedFormatters = [dateFormatterWithFractionalSeconds, dateFormatter]
45+
46+
for formatter in supportedFormatters {
47+
if let date = formatter.date(from: string) {
48+
return date
49+
}
50+
}
51+
52+
throw DecodingError.dataCorruptedError(
53+
in: container, debugDescription: "Invalid date format: \(string)"
54+
)
55+
}
56+
return decoder
57+
}()
58+
59+
public static let defaultHeaders: [String: String] = [
60+
"X-Client-Info": "auth-swift/\(version)",
61+
]
62+
63+
/// The default ``AuthFlowType`` used when initializing a ``AuthClient`` instance.
64+
public static let defaultFlowType: AuthFlowType = .pkce
65+
66+
/// The default ``AuthLocalStorage`` instance used by the ``AuthClient``.
67+
public static let defaultLocalStorage: AuthLocalStorage = KeychainLocalStorage(
68+
service: "supabase.gotrue.swift",
69+
accessGroup: nil
70+
)
71+
}

Sources/Auth/Deprecated.swift

+6-4
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,22 @@ extension JSONEncoder {
2626
@available(
2727
*,
2828
deprecated,
29-
message: "Access to the default JSONEncoder instance will be removed on the next major release, please use your own instance of JSONEncoder."
29+
renamed: "AuthClient.Configuration.jsonEncoder",
30+
message: "Access to the default JSONEncoder instance moved to AuthClient.Configuration.jsonEncoder"
3031
)
3132
public static var goTrue: JSONEncoder {
32-
auth
33+
AuthClient.Configuration.jsonEncoder
3334
}
3435
}
3536

3637
extension JSONDecoder {
3738
@available(
3839
*,
3940
deprecated,
40-
message: "Access to the default JSONDecoder instance will be removed on the next major release, please use your own instance of JSONDecoder."
41+
renamed: "AuthClient.Configuration.jsonDecoder",
42+
message: "Access to the default JSONDecoder instance moved to AuthClient.Configuration.jsonDecoder"
4143
)
4244
public static var goTrue: JSONDecoder {
43-
auth
45+
AuthClient.Configuration.jsonDecoder
4446
}
4547
}

Sources/Auth/Internal/SessionStorage.swift

+5-2
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,14 @@ extension SessionStorage {
3838
return Self(
3939
getSession: {
4040
try localStorage.retrieve(key: "supabase.session").flatMap {
41-
try JSONDecoder.auth.decode(StoredSession.self, from: $0)
41+
try AuthClient.Configuration.jsonDecoder.decode(StoredSession.self, from: $0)
4242
}
4343
},
4444
storeSession: {
45-
try localStorage.store(key: "supabase.session", value: JSONEncoder.auth.encode($0))
45+
try localStorage.store(
46+
key: "supabase.session",
47+
value: AuthClient.Configuration.jsonEncoder.encode($0)
48+
)
4649
},
4750
deleteSession: {
4851
try localStorage.remove(key: "supabase.session")

Sources/Auth/Types.swift

-51
Original file line numberDiff line numberDiff line change
@@ -586,54 +586,3 @@ public enum SignOutScope: String, Sendable {
586586
/// session.
587587
case others
588588
}
589-
590-
// MARK: - Encodable & Decodable
591-
592-
private let dateFormatterWithFractionalSeconds = { () -> ISO8601DateFormatter in
593-
let formatter = ISO8601DateFormatter()
594-
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
595-
return formatter
596-
}()
597-
598-
private let dateFormatter = { () -> ISO8601DateFormatter in
599-
let formatter = ISO8601DateFormatter()
600-
formatter.formatOptions = [.withInternetDateTime]
601-
return formatter
602-
}()
603-
604-
extension JSONDecoder {
605-
static let auth = { () -> JSONDecoder in
606-
let decoder = JSONDecoder()
607-
decoder.keyDecodingStrategy = .convertFromSnakeCase
608-
decoder.dateDecodingStrategy = .custom { decoder in
609-
let container = try decoder.singleValueContainer()
610-
let string = try container.decode(String.self)
611-
612-
let supportedFormatters = [dateFormatterWithFractionalSeconds, dateFormatter]
613-
614-
for formatter in supportedFormatters {
615-
if let date = formatter.date(from: string) {
616-
return date
617-
}
618-
}
619-
620-
throw DecodingError.dataCorruptedError(
621-
in: container, debugDescription: "Invalid date format: \(string)"
622-
)
623-
}
624-
return decoder
625-
}()
626-
}
627-
628-
extension JSONEncoder {
629-
static let auth = { () -> JSONEncoder in
630-
let encoder = JSONEncoder()
631-
encoder.keyEncodingStrategy = .convertToSnakeCase
632-
encoder.dateEncodingStrategy = .custom { date, encoder in
633-
var container = encoder.singleValueContainer()
634-
let string = dateFormatter.string(from: date)
635-
try container.encode(string)
636-
}
637-
return encoder
638-
}()
639-
}

Sources/PostgREST/Defaults.swift

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//
2+
// Defaults.swift
3+
//
4+
//
5+
// Created by Guilherme Souza on 14/12/23.
6+
//
7+
8+
import Foundation
9+
@_spi(Internal) import _Helpers
10+
11+
let version = _Helpers.version
12+
13+
extension PostgrestClient.Configuration {
14+
private static let supportedDateFormatters: [ISO8601DateFormatter] = [
15+
{ () -> ISO8601DateFormatter in
16+
let formatter = ISO8601DateFormatter()
17+
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
18+
return formatter
19+
}(),
20+
{ () -> ISO8601DateFormatter in
21+
let formatter = ISO8601DateFormatter()
22+
formatter.formatOptions = [.withInternetDateTime]
23+
return formatter
24+
}(),
25+
]
26+
27+
/// The default `JSONDecoder` instance for ``PostgrestClient`` responses.
28+
public static let jsonDecoder = { () -> JSONDecoder in
29+
let decoder = JSONDecoder()
30+
decoder.dateDecodingStrategy = .custom { decoder in
31+
let container = try decoder.singleValueContainer()
32+
let string = try container.decode(String.self)
33+
34+
for formatter in supportedDateFormatters {
35+
if let date = formatter.date(from: string) {
36+
return date
37+
}
38+
}
39+
40+
throw DecodingError.dataCorruptedError(
41+
in: container, debugDescription: "Invalid date format: \(string)"
42+
)
43+
}
44+
return decoder
45+
}()
46+
47+
/// The default `JSONEncoder` instance for ``PostgrestClient`` requests.
48+
public static let jsonEncoder = { () -> JSONEncoder in
49+
let encoder = JSONEncoder()
50+
encoder.dateEncodingStrategy = .iso8601
51+
return encoder
52+
}()
53+
54+
public static let defaultHeaders: [String: String] = [
55+
"X-Client-Info": "postgrest-swift/\(version)",
56+
]
57+
}

Sources/PostgREST/PostgrestClient.swift

+7-55
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import Foundation
22
@_spi(Internal) import _Helpers
33

4-
let version = _Helpers.version
5-
64
/// PostgREST client.
75
public actor PostgrestClient {
86
public typealias FetchHandler = @Sendable (_ request: URLRequest) async throws -> (
@@ -31,15 +29,15 @@ public actor PostgrestClient {
3129
schema: String? = nil,
3230
headers: [String: String] = [:],
3331
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) },
34-
encoder: JSONEncoder? = nil,
35-
decoder: JSONDecoder? = nil
32+
encoder: JSONEncoder = PostgrestClient.Configuration.jsonEncoder,
33+
decoder: JSONDecoder = PostgrestClient.Configuration.jsonDecoder
3634
) {
3735
self.url = url
3836
self.schema = schema
3937
self.headers = headers
4038
self.fetch = fetch
41-
self.encoder = encoder ?? .postgrest
42-
self.decoder = decoder ?? .postgrest
39+
self.encoder = encoder
40+
self.decoder = decoder
4341
}
4442
}
4543

@@ -49,9 +47,7 @@ public actor PostgrestClient {
4947
/// - Parameter configuration: The configuration for the client.
5048
public init(configuration: Configuration) {
5149
var configuration = configuration
52-
if configuration.headers["X-Client-Info"] == nil {
53-
configuration.headers["X-Client-Info"] = "postgrest-swift/\(version)"
54-
}
50+
configuration.headers.merge(Configuration.defaultHeaders) { l, _ in l }
5551
self.configuration = configuration
5652
}
5753

@@ -68,8 +64,8 @@ public actor PostgrestClient {
6864
schema: String? = nil,
6965
headers: [String: String] = [:],
7066
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) },
71-
encoder: JSONEncoder? = nil,
72-
decoder: JSONDecoder? = nil
67+
encoder: JSONEncoder = PostgrestClient.Configuration.jsonEncoder,
68+
decoder: JSONDecoder = PostgrestClient.Configuration.jsonDecoder
7369
) {
7470
self.init(
7571
configuration: Configuration(
@@ -139,47 +135,3 @@ public actor PostgrestClient {
139135
try rpc(fn, params: NoParams(), count: count)
140136
}
141137
}
142-
143-
private let supportedDateFormatters: [ISO8601DateFormatter] = [
144-
{ () -> ISO8601DateFormatter in
145-
let formatter = ISO8601DateFormatter()
146-
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
147-
return formatter
148-
}(),
149-
{ () -> ISO8601DateFormatter in
150-
let formatter = ISO8601DateFormatter()
151-
formatter.formatOptions = [.withInternetDateTime]
152-
return formatter
153-
}(),
154-
]
155-
156-
extension JSONDecoder {
157-
/// The JSONDecoder instance for PostgREST responses.
158-
public static let postgrest = { () -> JSONDecoder in
159-
let decoder = JSONDecoder()
160-
decoder.dateDecodingStrategy = .custom { decoder in
161-
let container = try decoder.singleValueContainer()
162-
let string = try container.decode(String.self)
163-
164-
for formatter in supportedDateFormatters {
165-
if let date = formatter.date(from: string) {
166-
return date
167-
}
168-
}
169-
170-
throw DecodingError.dataCorruptedError(
171-
in: container, debugDescription: "Invalid date format: \(string)"
172-
)
173-
}
174-
return decoder
175-
}()
176-
}
177-
178-
extension JSONEncoder {
179-
/// The JSONEncoder instance for PostgREST requests.
180-
public static let postgrest = { () -> JSONEncoder in
181-
let encoder = JSONEncoder()
182-
encoder.dateEncodingStrategy = .iso8601
183-
return encoder
184-
}()
185-
}

0 commit comments

Comments
 (0)