Skip to content

Commit 83016b7

Browse files
committed
feat: add standard client headers
1 parent e2ca290 commit 83016b7

File tree

5 files changed

+93
-14
lines changed

5 files changed

+93
-14
lines changed

Package.swift

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ let package = Package(
181181
name: "SupabaseTests",
182182
dependencies: [
183183
.product(name: "CustomDump", package: "swift-custom-dump"),
184+
.product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"),
184185
"Supabase",
185186
]
186187
),

Sources/Helpers/Version.swift

+47
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Foundation
12
import XCTestDynamicOverlay
23

34
private let _version = "2.26.0" // {x-release-please-version}
@@ -7,3 +8,49 @@ private let _version = "2.26.0" // {x-release-please-version}
78
#else
89
package let version = _version
910
#endif
11+
12+
private let _platform: String? = {
13+
#if os(macOS)
14+
return "macOS"
15+
#elseif os(iOS)
16+
return "iOS"
17+
#elseif os(tvOS)
18+
return "tvOS"
19+
#elseif os(watchOS)
20+
return "watchOS"
21+
#elseif os(Android)
22+
return "Android"
23+
#elseif os(Linux)
24+
return "Linux"
25+
#elseif os(Windows)
26+
return "Windows"
27+
#else
28+
return nil
29+
#endif
30+
}()
31+
32+
private let _platformVersion: String? = {
33+
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(Windows)
34+
ProcessInfo.processInfo.operatingSystemVersionString
35+
#elseif os(Linux) || os(Android)
36+
if let version = try? String(contentsOfFile: "/proc/version") {
37+
version.trimmingCharacters(in: .whitespacesAndNewlines)
38+
} else {
39+
nil
40+
}
41+
#else
42+
nil
43+
#endif
44+
}()
45+
46+
#if DEBUG
47+
package let platform = isTesting ? "macOS" : _platform
48+
#else
49+
package let platform = _platform
50+
#endif
51+
52+
#if DEBUG
53+
package let platformVersion = isTesting ? "0.0.0" : _platformVersion
54+
#else
55+
package let platformVersion = _platformVersion
56+
#endif

Sources/Supabase/Constants.swift

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// Constants.swift
3+
// Supabase
4+
//
5+
// Created by Guilherme Souza on 06/03/25.
6+
//
7+
8+
import Foundation
9+
import Helpers
10+
11+
let defaultHeaders: [String: String] = {
12+
var headers = [
13+
"X-Client-Info": "supabase-swift/\(version)"
14+
]
15+
16+
if let platform {
17+
headers["X-Supabase-Client-Platform"] = platform
18+
}
19+
20+
if let platformVersion {
21+
headers["X-Supabase-Client-Platform-Version"] = platformVersion
22+
}
23+
24+
return headers
25+
}()

Sources/Supabase/SupabaseClient.swift

+10-8
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ public typealias SupabaseLogger = Helpers.SupabaseLogger
1717
public typealias SupabaseLogLevel = Helpers.SupabaseLogLevel
1818
public typealias SupabaseLogMessage = Helpers.SupabaseLogMessage
1919

20-
let version = Helpers.version
21-
2220
/// Supabase Client.
2321
public final class SupabaseClient: Sendable {
2422
let options: SupabaseClientOptions
@@ -163,12 +161,16 @@ public final class SupabaseClient: Sendable {
163161
databaseURL = supabaseURL.appendingPathComponent("/rest/v1")
164162
functionsURL = supabaseURL.appendingPathComponent("/functions/v1")
165163

166-
_headers = HTTPFields([
167-
"X-Client-Info": "supabase-swift/\(version)",
168-
"Authorization": "Bearer \(supabaseKey)",
169-
"Apikey": supabaseKey,
170-
])
171-
.merging(with: HTTPFields(options.global.headers))
164+
_headers = HTTPFields(defaultHeaders)
165+
.merging(
166+
with: HTTPFields(
167+
[
168+
"Authorization": "Bearer \(supabaseKey)",
169+
"Apikey": supabaseKey,
170+
]
171+
)
172+
)
173+
.merging(with: HTTPFields(options.global.headers))
172174

173175
// default storage key uses the supabase project ref as a namespace
174176
let defaultStorageKey = "sb-\(supabaseURL.host!.split(separator: ".")[0])-auth-token"

Tests/SupabaseTests/SupabaseClientTests.swift

+10-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import IssueReporting
55
@testable import Realtime
66
@testable import Supabase
77
import XCTest
8+
import InlineSnapshotTesting
9+
import SnapshotTestingCustomDump
810

911
final class AuthLocalStorageMock: AuthLocalStorage {
1012
func store(key _: String, value _: Data) throws {}
@@ -61,16 +63,18 @@ final class SupabaseClientTests: XCTestCase {
6163
"https://project-ref.supabase.co/functions/v1"
6264
)
6365

64-
XCTAssertEqual(
65-
client.headers,
66+
assertInlineSnapshot(of: client.headers, as: .customDump) {
67+
"""
6668
[
67-
"X-Client-Info": "supabase-swift/\(Supabase.version)",
6869
"Apikey": "ANON_KEY",
69-
"header_field": "header_value",
7070
"Authorization": "Bearer ANON_KEY",
71+
"X-Client-Info": "supabase-swift/0.0.0",
72+
"X-Supabase-Client-Platform": "macOS",
73+
"X-Supabase-Client-Platform-Version": "0.0.0",
74+
"header_field": "header_value"
7175
]
72-
)
73-
expectNoDifference(client._headers.dictionary, client.headers)
76+
"""
77+
}
7478

7579
XCTAssertEqual(client.functions.region, "ap-northeast-1")
7680

0 commit comments

Comments
 (0)