@supabase/storage-js 2.3.1 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,6 +24,18 @@ const DEFAULT_FILE_OPTIONS: FileOptions = {
24
24
  upsert: false,
25
25
  }
26
26
 
27
+ type FileBody =
28
+ | ArrayBuffer
29
+ | ArrayBufferView
30
+ | Blob
31
+ | Buffer
32
+ | File
33
+ | FormData
34
+ | NodeJS.ReadableStream
35
+ | ReadableStream<Uint8Array>
36
+ | URLSearchParams
37
+ | string
38
+
27
39
  export default class StorageFileApi {
28
40
  protected url: string
29
41
  protected headers: { [key: string]: string }
@@ -52,17 +64,7 @@ export default class StorageFileApi {
52
64
  private async uploadOrUpdate(
53
65
  method: 'POST' | 'PUT',
54
66
  path: string,
55
- fileBody:
56
- | ArrayBuffer
57
- | ArrayBufferView
58
- | Blob
59
- | Buffer
60
- | File
61
- | FormData
62
- | NodeJS.ReadableStream
63
- | ReadableStream<Uint8Array>
64
- | URLSearchParams
65
- | string,
67
+ fileBody: FileBody,
66
68
  fileOptions?: FileOptions
67
69
  ): Promise<
68
70
  | {
@@ -101,6 +103,7 @@ export default class StorageFileApi {
101
103
  method,
102
104
  body: body as BodyInit,
103
105
  headers,
106
+ ...(options?.duplex ? { duplex: options.duplex } : {}),
104
107
  })
105
108
 
106
109
  if (res.ok) {
@@ -129,17 +132,7 @@ export default class StorageFileApi {
129
132
  */
130
133
  async upload(
131
134
  path: string,
132
- fileBody:
133
- | ArrayBuffer
134
- | ArrayBufferView
135
- | Blob
136
- | Buffer
137
- | File
138
- | FormData
139
- | NodeJS.ReadableStream
140
- | ReadableStream<Uint8Array>
141
- | URLSearchParams
142
- | string,
135
+ fileBody: FileBody,
143
136
  fileOptions?: FileOptions
144
137
  ): Promise<
145
138
  | {
@@ -154,6 +147,115 @@ export default class StorageFileApi {
154
147
  return this.uploadOrUpdate('POST', path, fileBody, fileOptions)
155
148
  }
156
149
 
150
+ /**
151
+ * Upload a file with a token generated from `createUploadSignedUrl`.
152
+ * @param path The file path, including the file name. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.
153
+ * @param token The token generated from `createUploadSignedUrl`
154
+ * @param fileBody The body of the file to be stored in the bucket.
155
+ */
156
+ async uploadToSignedUrl(
157
+ path: string,
158
+ token: string,
159
+ fileBody: FileBody,
160
+ fileOptions?: FileOptions
161
+ ) {
162
+ const cleanPath = this._removeEmptyFolders(path)
163
+ const _path = this._getFinalPath(cleanPath)
164
+
165
+ const url = new URL(this.url + `/object/upload/sign/${_path}`)
166
+ url.searchParams.set('token', token)
167
+
168
+ try {
169
+ let body
170
+ const options = { upsert: DEFAULT_FILE_OPTIONS.upsert, ...fileOptions }
171
+ const headers: Record<string, string> = {
172
+ ...this.headers,
173
+ ...{ 'x-upsert': String(options.upsert as boolean) },
174
+ }
175
+
176
+ if (typeof Blob !== 'undefined' && fileBody instanceof Blob) {
177
+ body = new FormData()
178
+ body.append('cacheControl', options.cacheControl as string)
179
+ body.append('', fileBody)
180
+ } else if (typeof FormData !== 'undefined' && fileBody instanceof FormData) {
181
+ body = fileBody
182
+ body.append('cacheControl', options.cacheControl as string)
183
+ } else {
184
+ body = fileBody
185
+ headers['cache-control'] = `max-age=${options.cacheControl}`
186
+ headers['content-type'] = options.contentType as string
187
+ }
188
+
189
+ const res = await this.fetch(url.toString(), {
190
+ method: 'PUT',
191
+ body: body as BodyInit,
192
+ headers,
193
+ })
194
+
195
+ if (res.ok) {
196
+ return {
197
+ data: { path: cleanPath },
198
+ error: null,
199
+ }
200
+ } else {
201
+ const error = await res.json()
202
+ return { data: null, error }
203
+ }
204
+ } catch (error) {
205
+ if (isStorageError(error)) {
206
+ return { data: null, error }
207
+ }
208
+
209
+ throw error
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Creates a signed upload URL.
215
+ * Signed upload URLs can be used upload files to the bucket without further authentication.
216
+ * They are valid for one minute.
217
+ * @param path The file path, including the current file name. For example `folder/image.png`.
218
+ */
219
+ async createSignedUploadUrl(
220
+ path: string
221
+ ): Promise<
222
+ | {
223
+ data: { signedUrl: string; token: string; path: string }
224
+ error: null
225
+ }
226
+ | {
227
+ data: null
228
+ error: StorageError
229
+ }
230
+ > {
231
+ try {
232
+ let _path = this._getFinalPath(path)
233
+
234
+ const data = await post(
235
+ this.fetch,
236
+ `${this.url}/object/upload/sign/${_path}`,
237
+ {},
238
+ { headers: this.headers }
239
+ )
240
+
241
+ const url = new URL(this.url + data.url)
242
+
243
+ const token = url.searchParams.get('token')
244
+
245
+ if (!token) {
246
+ throw new StorageError('No token returned by API')
247
+ }
248
+
249
+ return { data: { signedUrl: url.toString(), path, token }, error: null }
250
+ } catch (error) {
251
+ if (isStorageError(error)) {
252
+ return { data: null, error }
253
+ }
254
+
255
+ throw error
256
+ }
257
+ }
258
+
157
259
  /**
158
260
  * Replaces an existing file at the specified path with a new one.
159
261
  *