Skip to content

Commit

Permalink
feat: signed upload URL upsert (#199)
Browse files Browse the repository at this point in the history
  • Loading branch information
fenos authored May 2, 2024
1 parent adb58bb commit f641d5e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
2 changes: 1 addition & 1 deletion infra/storage/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
FROM supabase/storage-api:v1.0.10
FROM supabase/storage-api:v1.2.1

RUN apk add curl --no-cache
12 changes: 10 additions & 2 deletions src/packages/StorageFileApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,11 @@ export default class StorageFileApi {
* Signed upload URLs can be used to upload files to the bucket without further authentication.
* They are valid for 2 hours.
* @param path The file path, including the current file name. For example `folder/image.png`.
* @param options.upsert If set to true, allows the file to be overwritten if it already exists.
*/
async createSignedUploadUrl(
path: string
path: string,
options?: { upsert: boolean }
): Promise<
| {
data: { signedUrl: string; token: string; path: string }
Expand All @@ -236,11 +238,17 @@ export default class StorageFileApi {
try {
let _path = this._getFinalPath(path)

const headers = { ...this.headers }

if (options?.upsert) {
headers['x-upsert'] = 'true'
}

const data = await post(
this.fetch,
`${this.url}/object/upload/sign/${_path}`,
{},
{ headers: this.headers }
{ headers }
)

const url = new URL(this.url + data.url)
Expand Down
21 changes: 21 additions & 0 deletions test/storageFileApi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,26 @@ describe('Object API', () => {
expect(uploadRes.data?.path).toEqual(uploadPath)
})

test('can upload overwriting files with a signed url', async () => {
const { error: uploadErr } = await storage.from(bucketName).upload(uploadPath, file)

expect(uploadErr).toBeNull()

const { data, error } = await storage.from(bucketName).createSignedUploadUrl(uploadPath, {
upsert: true,
})

expect(error).toBeNull()
assert(data?.path)

const uploadRes = await storage
.from(bucketName)
.uploadToSignedUrl(data.path, data.token, file)

expect(uploadRes.error).toBeNull()
expect(uploadRes.data?.path).toEqual(uploadPath)
})

test('cannot upload to a signed url twice', async () => {
const { data, error } = await storage.from(bucketName).createSignedUploadUrl(uploadPath)

Expand All @@ -258,6 +278,7 @@ describe('Object API', () => {
const uploadRes2 = await storage
.from(bucketName)
.uploadToSignedUrl(data.path, data.token, file)

expect(uploadRes2.error).toEqual({
error: 'Duplicate',
message: 'The resource already exists',
Expand Down

0 comments on commit f641d5e

Please sign in to comment.