diff --git a/bucket.go b/bucket.go index 65e652c..2889573 100644 --- a/bucket.go +++ b/bucket.go @@ -1,55 +1,51 @@ package storage_go import ( - "bytes" "encoding/json" - "io" "net/http" ) -func (c *Client) ListBuckets() ([]Bucket, BucketResponseError) { - res, err := c.session.Get(c.clientTransport.baseUrl.String() + "/bucket") +// ListBuckets retrieves the details of all Storage buckets within an existing project. +func (c *Client) ListBuckets() ([]Bucket, error) { + bucketsURL := c.clientTransport.baseUrl.String() + "/bucket" + req, err := c.NewRequest(http.MethodGet, bucketsURL, nil) if err != nil { - panic(err) + return nil, err } - defer func(Body io.ReadCloser) { - err := Body.Close() - if err != nil { - panic(err) - } - }(res.Body) - - body, err := io.ReadAll(res.Body) + var buckets []Bucket + _, err = c.Do(req, &buckets) if err != nil { - panic(err) + return nil, err } - var data []Bucket - err = json.Unmarshal(body, &data) - - var respError BucketResponseError - err = json.Unmarshal(body, &respError) - - return data, respError + return buckets, nil } -func (c *Client) GetBucket(id string) (Bucket, BucketResponseError) { - res, err := c.session.Get(c.clientTransport.baseUrl.String() + "/bucket/" + id) +// GetBucket retrieves the details of an existing Storage bucket. +func (c *Client) GetBucket(id string) (Bucket, error) { + bucketURL := c.clientTransport.baseUrl.String() + "/bucket/" + id + req, err := c.NewRequest(http.MethodGet, bucketURL, nil) if err != nil { - panic(err) + return Bucket{}, err } - body, err := io.ReadAll(res.Body) - var data Bucket - var error_ BucketResponseError - err = json.Unmarshal(body, &data) - err = json.Unmarshal(body, &error_) + var bucket Bucket + _, err = c.Do(req, &bucket) + if err != nil { + return Bucket{}, err + } - return data, error_ + return bucket, nil } -func (c *Client) CreateBucket(id string, options BucketOptions) (Bucket, BucketResponseError) { +// CreateBucket creates a new Storage bucket +// options.public The visibility of the bucket. Public buckets don't require an authorization token to download objects, but still require a valid token for all other operations. By default, buckets are private. +// options.fileSizeLimit The maximum file size in bytes allowed in the bucket. By default, there is no limit. +// options.allowedMimeTypes The list of allowed MIME types. By default, all MIME types are allowed. +// return newly created bucket id +func (c *Client) CreateBucket(id string, options BucketOptions) (Bucket, error) { + createBucketURL := c.clientTransport.baseUrl.String() + "/bucket" bodyData := map[string]interface{}{ "id": id, "name": id, @@ -63,25 +59,28 @@ func (c *Client) CreateBucket(id string, options BucketOptions) (Bucket, BucketR if len(options.AllowedMimeTypes) > 0 { bodyData["allowed_mime_types"] = options.AllowedMimeTypes } - jsonBody, _ := json.Marshal(bodyData) - res, err := c.session.Post(c.clientTransport.baseUrl.String()+"/bucket", - "application/json", - bytes.NewBuffer(jsonBody)) + // jsonBody, _ := json.Marshal(bodyData) + req, err := c.NewRequest(http.MethodPost, createBucketURL, &bodyData) if err != nil { - panic(err) + return Bucket{}, err } - body, err := io.ReadAll(res.Body) - var data Bucket - var error_ BucketResponseError - err = json.Unmarshal(body, &data) - data.Public = options.Public - err = json.Unmarshal(body, &error_) + var bucket Bucket + _, err = c.Do(req, &bucket) + if err != nil { + return Bucket{}, err + } - return data, error_ + return bucket, nil } -func (c *Client) UpdateBucket(id string, options BucketOptions) (MessageResponse, BucketResponseError) { +// UpdateBucket creates a new Storage bucket +// options.public The visibility of the bucket. Public buckets don't require an authorization token to download objects, but still require a valid token for all other operations. By default, buckets are private. +// options.fileSizeLimit The maximum file size in bytes allowed in the bucket. By default, there is no limit. +// options.allowedMimeTypes The list of allowed MIME types. By default, all MIME types are allowed. +// return newly updated bucket id +func (c *Client) UpdateBucket(id string, options BucketOptions) (MessageResponse, error) { + bucketURL := c.clientTransport.baseUrl.String() + "/bucket/" + id bodyData := map[string]interface{}{ "id": id, "name": id, @@ -95,51 +94,45 @@ func (c *Client) UpdateBucket(id string, options BucketOptions) (MessageResponse if len(options.AllowedMimeTypes) > 0 { bodyData["allowed_mime_types"] = options.AllowedMimeTypes } - jsonBody, _ := json.Marshal(bodyData) - request, err := http.NewRequest(http.MethodPut, c.clientTransport.baseUrl.String()+"/bucket/"+id, bytes.NewBuffer(jsonBody)) - res, err := c.session.Do(request) + req, err := c.NewRequest(http.MethodPut, bucketURL, &bodyData) if err != nil { - panic(err) + return MessageResponse{}, err + } + var message MessageResponse + _, err = c.Do(req, &message) + if err != nil { + return MessageResponse{}, err } - body, err := io.ReadAll(res.Body) - var data MessageResponse - var error_ BucketResponseError - err = json.Unmarshal(body, &data) - err = json.Unmarshal(body, &error_) - - return data, error_ + return message, nil } -func (c *Client) EmptyBucket(id string) (MessageResponse, BucketResponseError) { +// EmptyBucket removes all objects inside a single bucket. +func (c *Client) EmptyBucket(id string) (MessageResponse, error) { + bucketURL := c.clientTransport.baseUrl.String() + "/bucket/" + id + "/empty" jsonBody, _ := json.Marshal(map[string]interface{}{}) - res, err := c.session.Post(c.clientTransport.baseUrl.String()+"/bucket/"+id+"/empty", "application/json", bytes.NewBuffer(jsonBody)) + req, err := c.NewRequest(http.MethodPost, bucketURL, &jsonBody) if err != nil { - panic(err) + return MessageResponse{}, err } - body, err := io.ReadAll(res.Body) - var data MessageResponse - var error_ BucketResponseError - err = json.Unmarshal(body, &data) - err = json.Unmarshal(body, &error_) + var message MessageResponse + _, err = c.Do(req, &message) - return data, error_ + return message, err } -func (c *Client) DeleteBucket(id string) (MessageResponse, BucketResponseError) { +// DeleteBucket deletes an existing bucket. A bucket must be empty before it can be deleted. +func (c *Client) DeleteBucket(id string) (MessageResponse, error) { + bucketURL := c.clientTransport.baseUrl.String() + "/bucket/" + id jsonBody, _ := json.Marshal(map[string]interface{}{}) - request, err := http.NewRequest(http.MethodDelete, c.clientTransport.baseUrl.String()+"/bucket/"+id, bytes.NewBuffer(jsonBody)) - res, err := c.session.Do(request) + req, err := c.NewRequest(http.MethodDelete, bucketURL, &jsonBody) if err != nil { - panic(err) + return MessageResponse{}, err } - body, err := io.ReadAll(res.Body) - var data MessageResponse - var error_ BucketResponseError - err = json.Unmarshal(body, &data) - err = json.Unmarshal(body, &error_) + var message MessageResponse + _, err = c.Do(req, &message) - return data, error_ + return message, err } diff --git a/client.go b/client.go index 373e3b3..a0fe3a6 100644 --- a/client.go +++ b/client.go @@ -1,6 +1,9 @@ package storage_go import ( + "bytes" + "encoding/json" + "io" "net/http" "net/url" ) @@ -59,3 +62,67 @@ func NewClient(rawUrl string, token string, headers map[string]string) *Client { return &c } + +// NewRequest will create new request with method, url and body +// If body is not nil, it will be marshalled into json +func (c *Client) NewRequest(method, url string, body ...interface{}) (*http.Request, error) { + var buf io.ReadWriter + if len(body) > 0 && body[0] != nil { + buf = &bytes.Buffer{} + enc := json.NewEncoder(buf) + enc.SetEscapeHTML(false) + err := enc.Encode(body[0]) + if err != nil { + return nil, err + } + } + req, err := http.NewRequest(method, url, buf) + if err != nil { + return nil, err + } + return req, nil +} + +// Do will send request using the c.sessionon which it is called +// If response contains body, it will be unmarshalled into v +// If response has err, it will be returned +func (c *Client) Do(req *http.Request, v interface{}) (*http.Response, error) { + resp, err := c.session.Do(req) + if err != nil { + return nil, err + } + + err = checkForError(resp) + if err != nil { + return resp, err + } + + if resp.Body != nil && v != nil { + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return resp, err + } + err = json.Unmarshal(body, &v) + if err != nil { + return resp, err + } + } + + return resp, nil +} + +func checkForError(resp *http.Response) error { + if c := resp.StatusCode; 200 <= c && c < 400 { + return nil + } + + errorResponse := &StorageError{} + + data, err := io.ReadAll(resp.Body) + if err == nil && data != nil { + _ = json.Unmarshal(data, errorResponse) + } + + return errorResponse +} diff --git a/error.go b/error.go new file mode 100644 index 0000000..3472aac --- /dev/null +++ b/error.go @@ -0,0 +1,17 @@ +package storage_go + +type StorageError struct { + Status int `json:"status"` + Message string `json:"message"` +} + +func (e *StorageError) Error() string { + return e.Message +} + +func NewStorageError(err error, statusCode int) StorageError { + return StorageError{ + Status: statusCode, + Message: err.Error(), + } +} diff --git a/storage.go b/storage.go index ce8785b..7a11df3 100644 --- a/storage.go +++ b/storage.go @@ -2,8 +2,6 @@ package storage_go import ( "bufio" - "bytes" - "encoding/json" "io" "net/http" "net/url" @@ -21,117 +19,139 @@ const ( defaultSortOrder = "asc" ) -func (c *Client) UploadOrUpdateFile(bucketId string, relativePath string, data io.Reader, update bool) FileUploadResponse { - c.clientTransport.header.Set("cache-control", defaultFileCacheControl) - if c.clientTransport.header.Get("content-type") == "" { - c.clientTransport.header.Set("content-type", defaultFileContentType) +func (c *Client) UploadOrUpdateFile( + bucketId string, + relativePath string, + data io.Reader, + update bool, + options ...FileOptions, +) (FileUploadResponse, error) { + path := removeEmptyFolderName(bucketId + "/" + relativePath) + uploadURL := c.clientTransport.baseUrl.String() + "/object/" + path + + // Check on file options + if len(options) > 0 { + if options[0].CacheControl != nil { + c.clientTransport.header.Set("cache-control", *options[0].CacheControl) + } + if options[0].ContentType != nil { + c.clientTransport.header.Set("content-type", *options[0].ContentType) + } + if options[0].Upsert != nil { + c.clientTransport.header.Set("x-upsert", strconv.FormatBool(*options[0].Upsert)) + } } - c.clientTransport.header.Set("x-upsert", strconv.FormatBool(defaultFileUpsert)) - body := bufio.NewReader(data) - _path := removeEmptyFolderName(bucketId + "/" + relativePath) - - var ( - res *http.Response - err error - request *http.Request - method = http.MethodPost - ) - + method := http.MethodPost if update { method = http.MethodPut } - - request, err = http.NewRequest(method, c.clientTransport.baseUrl.String()+"/object/"+_path, body) - res, err = c.session.Do(request) + bodyData := bufio.NewReader(data) + req, err := http.NewRequest(method, uploadURL, bodyData) if err != nil { - panic(err) + return FileUploadResponse{}, err } - body_, err := io.ReadAll(res.Body) var response FileUploadResponse - err = json.Unmarshal(body_, &response) + _, err = c.Do(req, &response) + if err != nil { + return FileUploadResponse{}, err + } - return response + return response, nil } -func (c *Client) UpdateFile(bucketId string, relativePath string, data io.Reader) FileUploadResponse { - return c.UploadOrUpdateFile(bucketId, relativePath, data, true) +// UploadFile will upload file to an existing bucket. +// bucketId string The bucket id +// relativePath path The file path, including the file name. Should be of the format `folder/subfolder/filename.png` +// data io.Reader The file data +func (c *Client) UpdateFile(bucketId string, relativePath string, data io.Reader, fileOptions ...FileOptions) (FileUploadResponse, error) { + return c.UploadOrUpdateFile(bucketId, relativePath, data, true, fileOptions...) } -func (c *Client) UploadFile(bucketId string, relativePath string, data io.Reader) FileUploadResponse { - return c.UploadOrUpdateFile(bucketId, relativePath, data, false) +// UploadFile replace an existing file at the specified path. +// bucketId string The bucket id +// relativePath path The file path, including the file name. Should be of the format `folder/subfolder/filename.png` +// data io.Reader The file data +func (c *Client) UploadFile(bucketId string, relativePath string, data io.Reader, fileOptions ...FileOptions) (FileUploadResponse, error) { + return c.UploadOrUpdateFile(bucketId, relativePath, data, false, fileOptions...) } -func (c *Client) MoveFile(bucketId string, sourceKey string, destinationKey string) FileUploadResponse { - jsonBody, _ := json.Marshal(map[string]interface{}{ +// MoveFile will move an existing file to new path in the same bucket. +// bucketId string The bucket id +// sourceKey path The file path, including the file name. Should be of the format `folder/subfolder/filename.png` +// destinationKey path The file path, including the file name. Should be of the format `folder/subfolder/new-filename.png` +func (c *Client) MoveFile(bucketId string, sourceKey string, destinationKey string) (FileUploadResponse, error) { + jsonBody := map[string]interface{}{ "bucketId": bucketId, "sourceKey": sourceKey, "destinationKey": destinationKey, - }) - - request, err := http.NewRequest( - http.MethodPost, - c.clientTransport.baseUrl.String()+"/object/move", - bytes.NewBuffer(jsonBody)) + } - res, err := c.session.Do(request) + moveURL := c.clientTransport.baseUrl.String() + "/object/move" + req, err := c.NewRequest(http.MethodPost, moveURL, &jsonBody) if err != nil { - panic(err) + return FileUploadResponse{}, err } - body, err := io.ReadAll(res.Body) var response FileUploadResponse - err = json.Unmarshal(body, &response) + _, err = c.Do(req, &response) + if err != nil { + return FileUploadResponse{}, err + } - return response + return response, err } -func (c *Client) CreateSignedUrl(bucketId string, filePath string, expiresIn int) SignedUrlResponse { - jsonBody, _ := json.Marshal(map[string]interface{}{ +// CreateSignedUrl create a signed URL. Use a signed URL to share a file for a fixed amount of time. +// bucketId string The bucket id +// filePath path The file path, including the file name. Should be of the format `folder/subfolder/filename.png` +// expiresIn int The number of seconds before the signed URL expires. Defaults to 60 seconds. +func (c *Client) CreateSignedUrl(bucketId string, filePath string, expiresIn int) (SignedUrlResponse, error) { + signedURL := c.clientTransport.baseUrl.String() + "/object/sign/" + bucketId + "/" + filePath + jsonBody := map[string]interface{}{ "expiresIn": expiresIn, - }) - - request, err := http.NewRequest( - http.MethodPost, - c.clientTransport.baseUrl.String()+"/object/sign/"+bucketId+"/"+filePath, - bytes.NewBuffer(jsonBody)) + } - res, err := c.session.Do(request) + req, err := c.NewRequest(http.MethodPost, signedURL, &jsonBody) if err != nil { - panic(err) + return SignedUrlResponse{}, err } - body, err := io.ReadAll(res.Body) var response SignedUrlResponse - err = json.Unmarshal(body, &response) + _, err = c.Do(req, &response) + if err != nil { + return SignedUrlResponse{}, err + } + response.SignedURL = c.clientTransport.baseUrl.String() + response.SignedURL - return response + return response, nil } +// CreateSignedUploadUrl create a signed URL for uploading a file. Use a signed URL to upload a file directly to a bucket. +// bucketId string The bucket id +// filePath path The file path, including the file name. Should be of the format `folder/subfolder/filename.png` func (c *Client) CreateSignedUploadUrl(bucketId string, filePath string) (SignedUploadUrlResponse, error) { - emptyBody, _ := json.Marshal(struct{}{}) - request, err := http.NewRequest( - http.MethodPost, - c.clientTransport.baseUrl.String()+"/object/upload/sign/"+bucketId+"/"+filePath, bytes.NewBuffer(emptyBody)) - if err != nil { - return SignedUploadUrlResponse{}, err - } - res, err := c.session.Do(request) + signUploadURL := c.clientTransport.baseUrl.String() + "/object/upload/sign/" + bucketId + "/" + filePath + emptyBody := struct{}{} + + req, err := c.NewRequest(http.MethodPost, signUploadURL, &emptyBody) if err != nil { return SignedUploadUrlResponse{}, err } - body, err := io.ReadAll(res.Body) + var response SignedUploadUrlResponse + _, err = c.Do(req, &response) if err != nil { return SignedUploadUrlResponse{}, err } - var response SignedUploadUrlResponse - err = json.Unmarshal(body, &response) return response, err } +// UploadToSignedUrl upload a file to a signed URL. +// filePath string The file path, including the file name. Should be of the format `folder/subfolder/filename.png` +// fileBody io.Reader The file data func (c *Client) UploadToSignedUrl(filePath string, fileBody io.Reader) (*UploadToSignedUrlResponse, error) { c.clientTransport.header.Set("cache-control", defaultFileCacheControl) c.clientTransport.header.Set("content-type", defaultFileContentType) @@ -139,22 +159,15 @@ func (c *Client) UploadToSignedUrl(filePath string, fileBody io.Reader) (*Upload bodyRequest := bufio.NewReader(fileBody) path := removeEmptyFolderName(filePath) + uploadToSignedURL := c.clientTransport.baseUrl.String() + path - request, err := http.NewRequest(http.MethodPut, c.clientTransport.baseUrl.String()+path, bodyRequest) - if err != nil { - return nil, err - } - resp, err := c.session.Do(request) + req, err := http.NewRequest(http.MethodPut, uploadToSignedURL, bodyRequest) if err != nil { return nil, err } - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, err - } var response UploadToSignedUrlResponse - err = json.Unmarshal(body, &response) + _, err = c.Do(req, &response) if err != nil { return nil, err } @@ -162,6 +175,10 @@ func (c *Client) UploadToSignedUrl(filePath string, fileBody io.Reader) (*Upload return &response, err } +// GetPublicUrl use to to get the URL for an asset in a public bucket. If you do not want to use this function, you can construct the public URL by concatenating the bucket URL with the path to the asset. +// bucketId string The bucket id +// filePath path The file path, including the file name. Should be of the format `folder/subfolder/filename.png` +// urlOptions UrlOptions The URL options func (c *Client) GetPublicUrl(bucketId string, filePath string, urlOptions ...UrlOptions) SignedUrlResponse { var response SignedUrlResponse renderPath := "object" @@ -178,30 +195,34 @@ func (c *Client) GetPublicUrl(bucketId string, filePath string, urlOptions ...Ur return response } -func (c *Client) RemoveFile(bucketId string, paths []string) FileUploadResponse { - jsonBody, _ := json.Marshal(map[string]interface{}{ +// RemoveFile remove a file from an existing bucket. +// bucketId string The bucket id. +// paths []string The file paths, including the file name. Should be of the format `folder/subfolder/filename.png` +func (c *Client) RemoveFile(bucketId string, paths []string) ([]FileUploadResponse, error) { + removeURL := c.clientTransport.baseUrl.String() + "/object/" + bucketId + jsonBody := map[string]interface{}{ "prefixes": paths, - }) - - request, err := http.NewRequest( - http.MethodDelete, - c.clientTransport.baseUrl.String()+"/object/"+bucketId, - bytes.NewBuffer(jsonBody)) + } - res, err := c.session.Do(request) + req, err := c.NewRequest(http.MethodDelete, removeURL, &jsonBody) if err != nil { - panic(err) + return []FileUploadResponse{}, err } - body, err := io.ReadAll(res.Body) - var response FileUploadResponse - err = json.Unmarshal(body, &response) - response.Data = body + var response []FileUploadResponse + _, err = c.Do(req, &response) + if err != nil { + return []FileUploadResponse{}, err + } - return response + return response, err } -func (c *Client) ListFiles(bucketId string, queryPath string, options FileSearchOptions) []FileObject { +// ListFiles list files in an existing bucket. +// bucketId string The bucket id. +// queryPath string The file path, including the file name. Should be of the format `folder/subfolder/filename.png` +// options FileSearchOptions The file search options +func (c *Client) ListFiles(bucketId string, queryPath string, options FileSearchOptions) ([]FileObject, error) { if options.Offset == 0 { options.Offset = defaultOffset } @@ -218,7 +239,7 @@ func (c *Client) ListFiles(bucketId string, queryPath string, options FileSearch options.SortByOptions.Column = defaultSortColumn } - body_ := ListFileRequestBody{ + body := ListFileRequestBody{ Limit: options.Limit, Offset: options.Offset, SortByOptions: SortBy{ @@ -227,26 +248,26 @@ func (c *Client) ListFiles(bucketId string, queryPath string, options FileSearch }, Prefix: queryPath, } - jsonBody, _ := json.Marshal(body_) - - request, err := http.NewRequest( - http.MethodPost, - c.clientTransport.baseUrl.String()+"/object/list/"+bucketId, - bytes.NewBuffer(jsonBody)) - res, err := c.session.Do(request) + listFileURL := c.clientTransport.baseUrl.String() + "/object/list/" + bucketId + req, err := c.NewRequest(http.MethodPost, listFileURL, &body) if err != nil { - panic(err) + return []FileObject{}, err } - body, err := io.ReadAll(res.Body) var response []FileObject + _, err = c.Do(req, &response) + if err != nil { + return []FileObject{}, err + } - err = json.Unmarshal(body, &response) - - return response + return response, nil } +// DownloadFile download a file from an existing bucket. +// bucketId string The bucket id. +// filePath string The file path, including the file name. Should be of the format `folder/subfolder/filename.png` +// urlOptions UrlOptions The URL options func (c *Client) DownloadFile(bucketId string, filePath string, urlOptions ...UrlOptions) ([]byte, error) { var options UrlOptions renderPath := "object" @@ -257,18 +278,17 @@ func (c *Client) DownloadFile(bucketId string, filePath string, urlOptions ...Ur } } urlStr := c.clientTransport.baseUrl.String() + "/" + renderPath + "/" + bucketId + "/" + filePath - request, err := http.NewRequest( - http.MethodGet, - buildUrlWithOption(urlStr, options), - nil) + req, err := c.NewRequest(http.MethodGet, buildUrlWithOption(urlStr, options), nil) if err != nil { return nil, err } - res, err := c.session.Do(request) + + res, err := c.Do(req, nil) if err != nil { return nil, err } defer res.Body.Close() + body, err := io.ReadAll(res.Body) return body, err } diff --git a/test/fileupload_test.go b/test/fileupload_test.go index 2881299..c8bd272 100644 --- a/test/fileupload_test.go +++ b/test/fileupload_test.go @@ -19,11 +19,11 @@ func TestUpload(t *testing.T) { panic(err) } c := storage_go.NewClient(rawUrl, token, map[string]string{}) - resp := c.UploadFile("test1", "test.txt", file) - fmt.Println(resp) + resp, err := c.UploadFile("test", "test.txt", file) + fmt.Println(resp, err) - // resp = c.UploadFile("test1", "hola.txt", []byte("hello world")) - // fmt.Println(resp) + // resp, err = c.UploadFile("test", "hola.txt", []byte("hello world")) + // fmt.Println(resp, err) } func TestUpdate(t *testing.T) { @@ -32,23 +32,23 @@ func TestUpdate(t *testing.T) { panic(err) } c := storage_go.NewClient(rawUrl, token, map[string]string{}) - resp := c.UpdateFile("test1", "test.txt", file) + resp, err := c.UpdateFile("test", "test.txt", file) - fmt.Println(resp) + fmt.Println(resp, err) } func TestMoveFile(t *testing.T) { c := storage_go.NewClient(rawUrl, token, map[string]string{}) - resp := c.MoveFile("test1", "test.txt", "random/test.txt") + resp, err := c.MoveFile("test", "test.txt", "random/test.txt") - fmt.Println(resp) + fmt.Println(resp, err) } func TestSignedUrl(t *testing.T) { c := storage_go.NewClient(rawUrl, token, map[string]string{}) - resp := c.CreateSignedUrl("test1", "file_example_MP4_480_1_5MG.mp4", 120) + resp, err := c.CreateSignedUrl("test", "file_example_MP4_480_1_5MG.mp4", 120) - fmt.Println(resp) + fmt.Println(resp, err) } func TestPublicUrl(t *testing.T) { @@ -60,14 +60,14 @@ func TestPublicUrl(t *testing.T) { func TestDeleteFile(t *testing.T) { c := storage_go.NewClient(rawUrl, token, map[string]string{}) - resp := c.RemoveFile("shield", []string{"book.pdf"}) + resp, err := c.RemoveFile("shield", []string{"book.pdf"}) - fmt.Println(resp) + fmt.Println(resp, err) } func TestListFile(t *testing.T) { c := storage_go.NewClient(rawUrl, token, map[string]string{}) - resp := c.ListFiles("test1", "", storage_go.FileSearchOptions{ + resp, err := c.ListFiles("shield", "", storage_go.FileSearchOptions{ Limit: 10, Offset: 0, SortByOptions: storage_go.SortBy{ @@ -76,7 +76,7 @@ func TestListFile(t *testing.T) { }, }) - fmt.Println(resp) + fmt.Println(resp, err) } func TestCreateUploadSignedUrl(t *testing.T) { @@ -92,14 +92,14 @@ func TestUploadToSignedUrl(t *testing.T) { if err != nil { panic(err) } - resp, err := c.UploadToSignedUrl("signed-url-response", file) - - fmt.Println(resp, err) + // resp, err := c.CreateSignedUploadUrl("test", "vu.txt") + res, err := c.UploadToSignedUrl("your-response-url", file) + fmt.Println(res, err) } func TestDownloadFile(t *testing.T) { c := storage_go.NewClient(rawUrl, token, map[string]string{}) - resp, err := c.DownloadFile("your-bucket-id", "book.pdf") + resp, err := c.DownloadFile("test", "book.pdf") if err != nil { t.Fatalf("DownloadFile failed: %v", err) } diff --git a/test/storage_test.go b/test/storage_test.go index 4fa145e..fe58ea1 100644 --- a/test/storage_test.go +++ b/test/storage_test.go @@ -8,31 +8,42 @@ import ( ) func TestBucketListAll(t *testing.T) { - c := storage_go.NewClient("https://abc.supabase.co/storage/v1", "", map[string]string{}) - c.ListBuckets() + c := storage_go.NewClient(rawUrl, token, map[string]string{}) + resp, err := c.ListBuckets() + fmt.Println(resp, err) } func TestBucketFetchById(t *testing.T) { - c := storage_go.NewClient("https://abc.supabase.co/storage/v1", "", map[string]string{}) - fmt.Println(c.GetBucket("shield")) + c := storage_go.NewClient(rawUrl, token, map[string]string{}) + fmt.Println(c.GetBucket("test")) } func TestBucketCreate(t *testing.T) { - c := storage_go.NewClient("https://abc.supabase.co/storage/v1", "", map[string]string{}) - fmt.Println(c.CreateBucket("test1", storage_go.BucketOptions{ + c := storage_go.NewClient(rawUrl, token, map[string]string{}) + fmt.Println(c.CreateBucket("test", storage_go.BucketOptions{ Public: true, })) } func TestBucketUpdate(t *testing.T) { - c := storage_go.NewClient("https://abc.supabase.co/storage/v1", "", map[string]string{}) - c.UpdateBucket("test1", storage_go.BucketOptions{ + c := storage_go.NewClient(rawUrl, token, map[string]string{}) + _, _ = c.UpdateBucket("test", storage_go.BucketOptions{ Public: false, }) - bucket, _ := c.GetBucket("test1") + bucket, _ := c.GetBucket("test") if bucket.Public { t.Errorf("Should have been private bucket after updating") } } + +func TestEmptyBucket(t *testing.T) { + c := storage_go.NewClient(rawUrl, token, map[string]string{}) + fmt.Println(c.EmptyBucket("test")) +} + +func TestDeleteBucket(t *testing.T) { + c := storage_go.NewClient(rawUrl, token, map[string]string{}) + fmt.Println(c.DeleteBucket("test")) +} diff --git a/types.go b/types.go index b754409..3b68d56 100644 --- a/types.go +++ b/types.go @@ -15,12 +15,13 @@ type Bucket struct { Name string `json:"name"` Owner string `json:"owner"` Public bool `json:"public"` - FileSizeLimit string `json:"file_size_limit"` + FileSizeLimit *int64 `json:"file_size_limit"` AllowedMimeTypes []string `json:"allowed_mine_types"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } +// BucketOptions is used to create or update a Bucket with option type BucketOptions struct { Public bool FileSizeLimit string @@ -89,3 +90,16 @@ type SignedUploadUrlResponse struct { type UploadToSignedUrlResponse struct { Key string `json:"key"` } + +type FileOptions struct { + // The number of seconds the asset is cached in the browser and in the Supabase CDN. + // This is set in the `Cache-Control: max-age=` header. Defaults to 3600 seconds. + CacheControl *string + // The `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`. + ContentType *string + // The duplex option is a string parameter that enables or disables duplex streaming, allowing for both reading and writing data in the same stream. It can be passed as an option to the fetch() method. + Duplex *string + // When upsert is set to true, the file is overwritten if it exists. When set to false, an error is thrown if the object already exists. + // Defaults to false. + Upsert *bool +}