@@ -15,6 +15,12 @@ let DEFAULT_SEARCH_OPTIONS = SearchOptions(
15
15
)
16
16
)
17
17
18
+ private let defaultFileOptions = FileOptions (
19
+ cacheControl: " 3600 " ,
20
+ contentType: " text/plain;charset=UTF-8 " ,
21
+ upsert: false
22
+ )
23
+
18
24
/// Supabase Storage File API
19
25
public class StorageFileApi : StorageApi , @unchecked Sendable {
20
26
/// The bucket id to operate on.
@@ -33,20 +39,37 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
33
39
let signedURL : URL
34
40
}
35
41
42
+ private func encodeMetadata( _ metadata: JSONObject ) -> Data {
43
+ let encoder = AnyJSON . encoder
44
+ return ( try ? encoder. encode ( metadata) ) ?? " {} " . data ( using: . utf8) !
45
+ }
46
+
36
47
func uploadOrUpdate(
37
48
method: HTTPMethod ,
38
49
path: String ,
39
50
formData: MultipartFormData ,
40
- options: FileOptions
51
+ options: FileOptions ?
41
52
) async throws -> FileUploadResponse {
42
53
var headers = HTTPHeaders ( )
43
54
55
+ let options = options ?? defaultFileOptions
56
+ let metadata = options. metadata
57
+
44
58
if method == . post {
45
59
headers. update ( name: " x-upsert " , value: " \( options. upsert) " )
46
60
}
47
61
48
62
headers [ " duplex " ] = options. duplex
49
63
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
+ )
72
+
50
73
struct UploadResponse : Decodable {
51
74
let Key : String
52
75
let Id : String
@@ -404,6 +427,27 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
404
427
. decoded ( decoder: configuration. decoder)
405
428
}
406
429
430
+ /// Checks the existence of file.
431
+ public func exists( path: String ) async throws -> Bool {
432
+ do {
433
+ let response = try await execute (
434
+ HTTPRequest (
435
+ url: configuration. url. appendingPathComponent ( " object/ \( bucketId) / \( path) " ) ,
436
+ method: . head
437
+ )
438
+ )
439
+ return true
440
+ } catch {
441
+ if let error = error as? StorageError , let statusCode = error. statusCode,
442
+ [ " 400 " , " 404 " ] . contains ( statusCode)
443
+ {
444
+ return false
445
+ }
446
+
447
+ throw error
448
+ }
449
+ }
450
+
407
451
/// Returns a public url for an asset.
408
452
/// - Parameters:
409
453
/// - path: The file path to the asset. For example `folder/image.png`.
@@ -517,13 +561,13 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
517
561
_ path: String ,
518
562
token: String ,
519
563
data: Data ,
520
- options: FileOptions = FileOptions ( )
564
+ options: FileOptions ? = nil
521
565
) async throws -> SignedURLUploadResponse {
522
566
let formData = MultipartFormData ( )
523
567
formData. append (
524
568
data,
525
569
withName: path. fileName,
526
- mimeType: options. contentType ?? mimeType ( forPathExtension: path. pathExtension)
570
+ mimeType: options? . contentType ?? mimeType ( forPathExtension: path. pathExtension)
527
571
)
528
572
return try await _uploadToSignedURL (
529
573
path: path,
@@ -545,7 +589,7 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
545
589
_ path: String ,
546
590
token: String ,
547
591
fileURL: Data ,
548
- options: FileOptions = FileOptions ( )
592
+ options: FileOptions ? = nil
549
593
) async throws -> SignedURLUploadResponse {
550
594
let formData = MultipartFormData ( )
551
595
formData. append ( fileURL, withName: path. fileName)
@@ -561,13 +605,20 @@ public class StorageFileApi: StorageApi, @unchecked Sendable {
561
605
path: String ,
562
606
token: String ,
563
607
formData: MultipartFormData ,
564
- options: FileOptions
608
+ options: FileOptions ?
565
609
) async throws -> SignedURLUploadResponse {
610
+ let options = options ?? defaultFileOptions
566
611
var headers = HTTPHeaders ( [
567
612
" x-upsert " : " \( options. upsert) " ,
568
613
] )
569
614
headers [ " duplex " ] = options. duplex
570
615
616
+ if let metadata = options. metadata {
617
+ formData. append ( encodeMetadata ( metadata) , withName: " metadata " )
618
+ }
619
+
620
+ formData. append ( options. cacheControl. data ( using: . utf8) !, withName: " cacheControl " )
621
+
571
622
struct UploadResponse : Decodable {
572
623
let Key : String
573
624
}
0 commit comments