Skip to content

Add public config #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Sources/SupabaseStorage/MultipartFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ extension Data {
using: String.Encoding.utf8,
allowLossyConversion: true
)
append(data!)
if data != nil {
append(data!)
}
}
}
4 changes: 4 additions & 0 deletions Sources/SupabaseStorage/StorageAPIConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
public struct StorageApiConfig {
public var url: String
public var headers: [String: String]
}
16 changes: 9 additions & 7 deletions Sources/SupabaseStorage/StorageApi.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import Foundation

public class StorageApi {
var url: String
var headers: [String: String]
public var config: StorageApiConfig

init(url: String, headers: [String: String]) {
self.url = url
self.headers = headers
self.config = StorageApiConfig(url: url, headers: headers)
// self.headers.merge(["Content-Type": "application/json"]) { $1 }
}

init(_ config: StorageApiConfig) {
self.config = config
}

internal enum HTTPMethod: String {
case get = "GET"
Expand All @@ -28,10 +30,10 @@ public class StorageApi {
request.httpMethod = method.rawValue

if var headers = headers {
headers.merge(self.headers) { $1 }
headers.merge(self.config.headers) { $1 }
request.allHTTPHeaderFields = headers
} else {
request.allHTTPHeaderFields = self.headers
request.allHTTPHeaderFields = self.config.headers
}

if let parameters = parameters {
Expand Down Expand Up @@ -83,7 +85,7 @@ public class StorageApi {
request.setValue(fileOptions.cacheControl, forHTTPHeaderField: "cacheControl")
}

var allHTTPHeaderFields = self.headers
var allHTTPHeaderFields = self.config.headers
if let headers = headers {
allHTTPHeaderFields.merge(headers) { $1 }
}
Expand Down
27 changes: 16 additions & 11 deletions Sources/SupabaseStorage/StorageBucketApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,23 @@ public class StorageBucketApi: StorageApi {
/// - headers: HTTP headers.
override init(url: String, headers: [String: String]) {
super.init(url: url, headers: headers)
self.headers.merge(["Content-Type": "application/json"]) { $1 }
self.config.headers.merge(["Content-Type": "application/json"]) { $1 }
}

override init(_ config: StorageApiConfig) {
super.init(config)
self.config.headers.merge(["Content-Type": "application/json"]) { $1 }
}

/// Retrieves the details of all Storage buckets within an existing product.
/// - Parameter completion: Result<[Bucket], Error>
public func listBuckets(completion: @escaping (Result<[Bucket], Error>) -> Void) {
guard let url = URL(string: "\(url)/bucket") else {
guard let url = URL(string: "\(config.url)/bucket") else {
completion(.failure(StorageError(message: "badURL")))
return
}

fetch(url: url, method: .get, parameters: nil, headers: headers) { result in
fetch(url: url, method: .get, parameters: nil, headers: config.headers) { result in
switch result {
case let .success(response):
guard let dict: [[String: Any]] = response as? [[String: Any]] else {
Expand All @@ -38,12 +43,12 @@ public class StorageBucketApi: StorageApi {
/// - id: The unique identifier of the bucket you would like to retrieve.
/// - completion: Result<Bucket, Error>
public func getBucket(id: String, completion: @escaping (Result<Bucket, Error>) -> Void) {
guard let url = URL(string: "\(url)/bucket/\(id)") else {
guard let url = URL(string: "\(config.url)/bucket/\(id)") else {
completion(.failure(StorageError(message: "badURL")))
return
}

fetch(url: url, method: .get, parameters: nil, headers: headers) { result in
fetch(url: url, method: .get, parameters: nil, headers: config.headers) { result in
switch result {
case let .success(response):
guard let dict: [String: Any] = response as? [String: Any], let bucket = Bucket(from: dict) else {
Expand All @@ -62,12 +67,12 @@ public class StorageBucketApi: StorageApi {
/// - id: A unique identifier for the bucket you are creating.
/// - completion: newly created bucket id
public func createBucket(id: String, completion: @escaping (Result<[String: Any], Error>) -> Void) {
guard let url = URL(string: "\(url)/bucket") else {
guard let url = URL(string: "\(config.url)/bucket") else {
completion(.failure(StorageError(message: "badURL")))
return
}

fetch(url: url, method: .post, parameters: ["id": id, "name": id], headers: headers) { result in
fetch(url: url, method: .post, parameters: ["id": id, "name": id], headers: config.headers) { result in
switch result {
case let .success(response):
guard let dict: [String: Any] = response as? [String: Any] else {
Expand All @@ -86,12 +91,12 @@ public class StorageBucketApi: StorageApi {
/// - id: The unique identifier of the bucket you would like to empty.
/// - completion: Result<[String: Any], Error>
public func emptyBucket(id: String, completion: @escaping (Result<[String: Any], Error>) -> Void) {
guard let url = URL(string: "\(url)/bucket/\(id)/empty") else {
guard let url = URL(string: "\(config.url)/bucket/\(id)/empty") else {
completion(.failure(StorageError(message: "badURL")))
return
}

fetch(url: url, method: .post, parameters: [:], headers: headers) { result in
fetch(url: url, method: .post, parameters: [:], headers: config.headers) { result in
switch result {
case let .success(response):
guard let dict: [String: Any] = response as? [String: Any] else {
Expand All @@ -111,12 +116,12 @@ public class StorageBucketApi: StorageApi {
/// - id: The unique identifier of the bucket you would like to delete.
/// - completion: Result<[String: Any], Error>
public func deleteBucket(id: String, completion: @escaping (Result<[String: Any], Error>) -> Void) {
guard let url = URL(string: "\(url)/bucket/\(id)") else {
guard let url = URL(string: "\(config.url)/bucket/\(id)") else {
completion(.failure(StorageError(message: "badURL")))
return
}

fetch(url: url, method: .delete, parameters: [:], headers: headers) { result in
fetch(url: url, method: .delete, parameters: [:], headers: config.headers) { result in
switch result {
case let .success(response):
guard let dict: [String: Any] = response as? [String: Any] else {
Expand Down
26 changes: 13 additions & 13 deletions Sources/SupabaseStorage/StorageFileApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ public class StorageFileApi: StorageApi {
/// - fileOptions: HTTP headers. For example `cacheControl`
/// - completion: Result<Any, Error>
public func upload(path: String, file: File, fileOptions: FileOptions?, completion: @escaping (Result<Any, Error>) -> Void) {
guard let url = URL(string: "\(url)/object/\(bucketId)/\(path)") else {
guard let url = URL(string: "\(config.url)/object/\(bucketId)/\(path)") else {
completion(.failure(StorageError(message: "badURL")))
return
}

let formData = FormData()
formData.append(file: file)

fetch(url: url, method: .post, formData: formData, headers: headers, fileOptions: fileOptions) { result in
fetch(url: url, method: .post, formData: formData, headers: config.headers, fileOptions: fileOptions) { result in
completion(result)
}
}
Expand All @@ -42,15 +42,15 @@ public class StorageFileApi: StorageApi {
/// - fileOptions: HTTP headers. For example `cacheControl`
/// - completion: Result<Any, Error>
public func update(path: String, file: File, fileOptions: FileOptions?, completion: @escaping (Result<Any, Error>) -> Void) {
guard let url = URL(string: "\(url)/object/\(bucketId)/\(path)") else {
guard let url = URL(string: "\(config.url)/object/\(bucketId)/\(path)") else {
completion(.failure(StorageError(message: "badURL")))
return
}

let formData = FormData()
formData.append(file: file)

fetch(url: url, method: .put, formData: formData, headers: headers, fileOptions: fileOptions) { result in
fetch(url: url, method: .put, formData: formData, headers: config.headers, fileOptions: fileOptions) { result in
completion(result)
}
}
Expand All @@ -61,12 +61,12 @@ public class StorageFileApi: StorageApi {
/// - toPath: The new file path, including the new file name. For example `folder/image-copy.png`.
/// - completion: Result<[String: Any], Error>
public func move(fromPath: String, toPath: String, completion: @escaping (Result<[String: Any], Error>) -> Void) {
guard let url = URL(string: "\(url)/object/move") else {
guard let url = URL(string: "\(config.url)/object/move") else {
completion(.failure(StorageError(message: "badURL")))
return
}

fetch(url: url, method: .post, parameters: ["bucketId": bucketId, "sourceKey": fromPath, "destinationKey": toPath], headers: headers) { result in
fetch(url: url, method: .post, parameters: ["bucketId": bucketId, "sourceKey": fromPath, "destinationKey": toPath], headers: config.headers) { result in
switch result {
case let .success(response):
guard let dict: [String: Any] = response as? [String: Any] else {
Expand All @@ -86,12 +86,12 @@ public class StorageFileApi: StorageApi {
/// - expiresIn: The number of seconds until the signed URL expires. For example, `60` for a URL which is valid for one minute.
/// - completion: Result<URL, Error>
public func createSignedUrl(path: String, expiresIn: Int, completion: @escaping (Result<URL, Error>) -> Void) {
guard let url = URL(string: "\(url)/object/sign/\(path)") else {
guard let url = URL(string: "\(config.url)/object/sign/\(path)") else {
completion(.failure(StorageError(message: "badURL")))
return
}

fetch(url: url, method: .post, parameters: ["expiresIn": expiresIn], headers: headers) { result in
fetch(url: url, method: .post, parameters: ["expiresIn": expiresIn], headers: config.headers) { result in
switch result {
case let .success(response):
guard let dict: [String: Any] = response as? [String: Any], let signedURL: String = dict["signedURL"] as? String else {
Expand All @@ -110,12 +110,12 @@ public class StorageFileApi: StorageApi {
/// - paths: An array of files to be deletes, including the path and file name. For example [`folder/image.png`].
/// - completion: Result<[String: Any], Error>
public func remove(paths: [String], completion: @escaping (Result<[String: Any], Error>) -> Void) {
guard let url = URL(string: "\(url)/object/\(bucketId)") else {
guard let url = URL(string: "\(config.url)/object/\(bucketId)") else {
completion(.failure(StorageError(message: "badURL")))
return
}

fetch(url: url, method: .delete, parameters: ["prefixes": paths], headers: headers) { result in
fetch(url: url, method: .delete, parameters: ["prefixes": paths], headers: config.headers) { result in
switch result {
case let .success(response):
guard let dict: [String: Any] = response as? [String: Any] else {
Expand All @@ -135,7 +135,7 @@ public class StorageFileApi: StorageApi {
/// - options: Search options, including `limit`, `offset`, and `sortBy`.
/// - completion: Result<[FileObject], Error>
public func list(path: String? = nil, options: SearchOptions? = nil, completion: @escaping (Result<[FileObject], Error>) -> Void) {
guard let url = URL(string: "\(url)/object/list/\(bucketId)") else {
guard let url = URL(string: "\(config.url)/object/list/\(bucketId)") else {
completion(.failure(StorageError(message: "badURL")))
return
}
Expand All @@ -144,7 +144,7 @@ public class StorageFileApi: StorageApi {
sortBy["column"] = options?.sortBy?.column ?? "name"
sortBy["order"] = options?.sortBy?.order ?? "asc"

fetch(url: url, method: .post, parameters: ["path": path ?? "", "limit": options?.limit ?? 100, "offset": options?.offset ?? 0], headers: headers) { result in
fetch(url: url, method: .post, parameters: ["path": path ?? "", "limit": options?.limit ?? 100, "offset": options?.offset ?? 0], headers: config.headers) { result in
switch result {
case let .success(response):
guard let arr: [[String: Any]] = response as? [[String: Any]] else {
Expand All @@ -165,7 +165,7 @@ public class StorageFileApi: StorageApi {
/// - Returns: URLSessionDataTask or nil
@discardableResult
public func download(path: String, completion: @escaping (Result<Data?, Error>) -> Void) -> URLSessionDataTask? {
guard let url = URL(string: "\(url)/object/\(bucketId)/\(path)") else {
guard let url = URL(string: "\(config.url)/object/\(bucketId)/\(path)") else {
completion(.failure(StorageError(message: "badURL")))
return nil
}
Expand Down
8 changes: 7 additions & 1 deletion Sources/SupabaseStorage/SupabaseStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ public class SupabaseStorageClient: StorageBucketApi {
override public init(url: String, headers: [String: String]) {
super.init(url: url, headers: headers)
}

/// Storage Client initializer
/// - Parameter config: Config object to use
override public init(_ config: StorageApiConfig) {
super.init(config)
}

/// Perform file operation in a bucket.
/// - Parameter id: The bucket id to operate on.
/// - Returns: StorageFileApi object
public func from(id: String) -> StorageFileApi {
return StorageFileApi(url: url, headers: headers, bucketId: id)
return StorageFileApi(url: config.url, headers: config.headers, bucketId: id)
}
}