Skip to content

Commit 30955b4

Browse files
committed
fix(storage): cache control
1 parent 8f61141 commit 30955b4

File tree

2 files changed

+75
-65
lines changed

2 files changed

+75
-65
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
"Supabase",
99
"whitespaces",
1010
"xctest"
11-
]
11+
],
12+
"makefile.configureOnOpen": false
1213
}

Sources/Storage/StorageFileApi.swift

Lines changed: 73 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import Foundation
22
import Helpers
3+
34
import class MultipartFormData.MultipartFormData
45

56
#if canImport(FoundationNetworking)
67
import FoundationNetworking
78
#endif
89

9-
let DEFAULT_SEARCH_OPTIONS = SearchOptions(
10+
let defaultSearchOptions = SearchOptions(
1011
limit: 100,
1112
offset: 0,
1213
sortBy: SortBy(
@@ -21,6 +22,40 @@ private let defaultFileOptions = FileOptions(
2122
upsert: false
2223
)
2324

25+
enum FileUpload {
26+
case data(Data)
27+
case url(URL)
28+
29+
func encode(to formData: MultipartFormData, withPath path: String, options: FileOptions) {
30+
formData.append(
31+
options.cacheControl.data(using: .utf8)!,
32+
withName: "cacheControl"
33+
)
34+
35+
if let metadata = options.metadata {
36+
formData.append(encodeMetadata(metadata), withName: "metadata")
37+
}
38+
39+
switch self {
40+
case let .data(data):
41+
formData.append(
42+
data,
43+
withName: "",
44+
fileName: path.fileName,
45+
mimeType: options.contentType ?? mimeType(forPathExtension: path.pathExtension)
46+
)
47+
48+
case let .url(url):
49+
formData.append(url, withName: "")
50+
}
51+
}
52+
53+
private func encodeMetadata(_ metadata: JSONObject) -> Data {
54+
let encoder = AnyJSON.encoder
55+
return (try? encoder.encode(metadata)) ?? "{}".data(using: .utf8)!
56+
}
57+
}
58+
2459
/// Supabase Storage File API
2560
public class StorageFileApi: StorageApi, @unchecked Sendable {
2661
/// The bucket id to operate on.
@@ -39,36 +74,23 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
3974
let signedURL: URL
4075
}
4176

42-
private func encodeMetadata(_ metadata: JSONObject) -> Data {
43-
let encoder = AnyJSON.encoder
44-
return (try? encoder.encode(metadata)) ?? "{}".data(using: .utf8)!
45-
}
46-
4777
private func _uploadOrUpdate(
4878
method: HTTPMethod,
4979
path: String,
50-
formData: MultipartFormData,
80+
file: FileUpload,
5181
options: FileOptions?
5282
) async throws -> FileUploadResponse {
5383
let options = options ?? defaultFileOptions
5484
var headers = options.headers.map { HTTPHeaders($0) } ?? HTTPHeaders()
5585

56-
let metadata = options.metadata
57-
5886
if method == .post {
5987
headers.update(name: "x-upsert", value: "\(options.upsert)")
6088
}
6189

6290
headers["duplex"] = options.duplex
6391

64-
if let metadata {
65-
formData.append(encodeMetadata(metadata), withName: "metadata")
66-
}
67-
68-
formData.append(
69-
options.cacheControl.data(using: .utf8)!,
70-
withName: "cacheControl"
71-
)
92+
let formData = MultipartFormData()
93+
file.encode(to: formData, withPath: path, options: options)
7294

7395
struct UploadResponse: Decodable {
7496
let Key: String
@@ -109,27 +131,26 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
109131
data: Data,
110132
options: FileOptions = FileOptions()
111133
) async throws -> FileUploadResponse {
112-
let fileName = path.fileName
113-
let formData = MultipartFormData()
114-
formData.append(
115-
data,
116-
withName: fileName,
117-
fileName: fileName,
118-
mimeType: options.contentType ?? mimeType(forPathExtension: path.pathExtension)
134+
try await _uploadOrUpdate(
135+
method: .post,
136+
path: path,
137+
file: .data(data),
138+
options: options
119139
)
120-
return try await _uploadOrUpdate(method: .post, path: path, formData: formData, options: options)
121140
}
122141

123142
@discardableResult
124143
public func upload(
125144
_ path: String,
126-
fileURL: Data,
145+
fileURL: URL,
127146
options: FileOptions = FileOptions()
128147
) async throws -> FileUploadResponse {
129-
let fileName = path.fileName
130-
let formData = MultipartFormData()
131-
formData.append(fileURL, withName: fileName, fileName: fileName)
132-
return try await _uploadOrUpdate(method: .post, path: path, formData: formData, options: options)
148+
try await _uploadOrUpdate(
149+
method: .post,
150+
path: path,
151+
file: .url(fileURL),
152+
options: options
153+
)
133154
}
134155

135156
/// Replaces an existing file at the specified path with a new one.
@@ -144,15 +165,12 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
144165
data: Data,
145166
options: FileOptions = FileOptions()
146167
) async throws -> FileUploadResponse {
147-
let fileName = path.fileName
148-
let formData = MultipartFormData()
149-
formData.append(
150-
data,
151-
withName: fileName,
152-
fileName: fileName,
153-
mimeType: options.contentType ?? mimeType(forPathExtension: path.pathExtension)
168+
try await _uploadOrUpdate(
169+
method: .put,
170+
path: path,
171+
file: .data(data),
172+
options: options
154173
)
155-
return try await _uploadOrUpdate(method: .put, path: path, formData: formData, options: options)
156174
}
157175

158176
/// Replaces an existing file at the specified path with a new one.
@@ -167,9 +185,12 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
167185
fileURL: URL,
168186
options: FileOptions = FileOptions()
169187
) async throws -> FileUploadResponse {
170-
let formData = MultipartFormData()
171-
formData.append(fileURL, withName: path.fileName)
172-
return try await _uploadOrUpdate(method: .put, path: path, formData: formData, options: options)
188+
try await _uploadOrUpdate(
189+
method: .put,
190+
path: path,
191+
file: .url(fileURL),
192+
options: options
193+
)
173194
}
174195

175196
/// Moves an existing file, optionally renaming it at the same time.
@@ -388,7 +409,7 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
388409
) async throws -> [FileObject] {
389410
let encoder = JSONEncoder()
390411

391-
var options = options ?? DEFAULT_SEARCH_OPTIONS
412+
var options = options ?? defaultSearchOptions
392413
options.prefix = path ?? ""
393414

394415
return try await execute(
@@ -579,18 +600,10 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
579600
data: Data,
580601
options: FileOptions? = nil
581602
) async throws -> SignedURLUploadResponse {
582-
let fileName = path.fileName
583-
let formData = MultipartFormData()
584-
formData.append(
585-
data,
586-
withName: fileName,
587-
fileName: fileName,
588-
mimeType: options?.contentType ?? mimeType(forPathExtension: path.pathExtension)
589-
)
590-
return try await _uploadToSignedURL(
603+
try await _uploadToSignedURL(
591604
path: path,
592605
token: token,
593-
formData: formData,
606+
file: .data(data),
594607
options: options
595608
)
596609
}
@@ -606,23 +619,21 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
606619
public func uploadToSignedURL(
607620
_ path: String,
608621
token: String,
609-
fileURL: Data,
622+
fileURL: URL,
610623
options: FileOptions? = nil
611624
) async throws -> SignedURLUploadResponse {
612-
let formData = MultipartFormData()
613-
formData.append(fileURL, withName: path.fileName)
614-
return try await _uploadToSignedURL(
625+
try await _uploadToSignedURL(
615626
path: path,
616627
token: token,
617-
formData: formData,
628+
file: .url(fileURL),
618629
options: options
619630
)
620631
}
621632

622633
private func _uploadToSignedURL(
623634
path: String,
624635
token: String,
625-
formData: MultipartFormData,
636+
file: FileUpload,
626637
options: FileOptions?
627638
) async throws -> SignedURLUploadResponse {
628639
let options = options ?? defaultFileOptions
@@ -631,11 +642,8 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
631642
headers["x-upsert"] = "\(options.upsert)"
632643
headers["duplex"] = options.duplex
633644

634-
if let metadata = options.metadata {
635-
formData.append(encodeMetadata(metadata), withName: "metadata")
636-
}
637-
638-
formData.append(options.cacheControl.data(using: .utf8)!, withName: "cacheControl")
645+
let formData = MultipartFormData()
646+
file.encode(to: formData, withPath: path, options: options)
639647

640648
struct UploadResponse: Decodable {
641649
let Key: String
@@ -664,7 +672,8 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
664672

665673
private func _removeEmptyFolders(_ path: String) -> String {
666674
let trimmedPath = path.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
667-
let cleanedPath = trimmedPath.replacingOccurrences(of: "/+", with: "/", options: .regularExpression)
675+
let cleanedPath = trimmedPath.replacingOccurrences(
676+
of: "/+", with: "/", options: .regularExpression)
668677
return cleanedPath
669678
}
670679
}

0 commit comments

Comments
 (0)