@supabase/storage-js 2.75.1 → 2.75.2-canary.1

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.
Files changed (176) hide show
  1. package/README.md +917 -12
  2. package/dist/main/StorageClient.d.ts +28 -0
  3. package/dist/main/StorageClient.d.ts.map +1 -1
  4. package/dist/main/StorageClient.js +38 -5
  5. package/dist/main/StorageClient.js.map +1 -1
  6. package/dist/main/index.d.ts +2 -0
  7. package/dist/main/index.d.ts.map +1 -1
  8. package/dist/main/index.js +7 -17
  9. package/dist/main/index.js.map +1 -1
  10. package/dist/main/lib/constants.d.ts.map +1 -1
  11. package/dist/main/lib/constants.js +3 -1
  12. package/dist/main/lib/constants.js.map +1 -1
  13. package/dist/main/lib/fetch.js +8 -16
  14. package/dist/main/lib/fetch.js.map +1 -1
  15. package/dist/main/lib/helpers.js +4 -45
  16. package/dist/main/lib/helpers.js.map +1 -1
  17. package/dist/main/lib/index.d.ts +1 -0
  18. package/dist/main/lib/index.d.ts.map +1 -1
  19. package/dist/main/lib/index.js +6 -18
  20. package/dist/main/lib/index.js.map +1 -1
  21. package/dist/main/lib/types.d.ts +36 -4
  22. package/dist/main/lib/types.d.ts.map +1 -1
  23. package/dist/main/lib/vectors/StorageVectorsClient.d.ts +310 -0
  24. package/dist/main/lib/vectors/StorageVectorsClient.d.ts.map +1 -0
  25. package/dist/main/lib/vectors/StorageVectorsClient.js +366 -0
  26. package/dist/main/lib/vectors/StorageVectorsClient.js.map +1 -0
  27. package/dist/main/lib/vectors/VectorBucketApi.d.ts +129 -0
  28. package/dist/main/lib/vectors/VectorBucketApi.d.ts.map +1 -0
  29. package/dist/main/lib/vectors/VectorBucketApi.js +199 -0
  30. package/dist/main/lib/vectors/VectorBucketApi.js.map +1 -0
  31. package/dist/main/lib/vectors/VectorDataApi.d.ts +221 -0
  32. package/dist/main/lib/vectors/VectorDataApi.d.ts.map +1 -0
  33. package/dist/main/lib/vectors/VectorDataApi.js +336 -0
  34. package/dist/main/lib/vectors/VectorDataApi.js.map +1 -0
  35. package/dist/main/lib/vectors/VectorIndexApi.d.ts +157 -0
  36. package/dist/main/lib/vectors/VectorIndexApi.d.ts.map +1 -0
  37. package/dist/main/lib/vectors/VectorIndexApi.js +218 -0
  38. package/dist/main/lib/vectors/VectorIndexApi.js.map +1 -0
  39. package/dist/main/lib/vectors/constants.d.ts +5 -0
  40. package/dist/main/lib/vectors/constants.d.ts.map +1 -0
  41. package/dist/main/lib/vectors/constants.js +9 -0
  42. package/dist/main/lib/vectors/constants.js.map +1 -0
  43. package/dist/main/lib/vectors/errors.d.ts +55 -0
  44. package/dist/main/lib/vectors/errors.d.ts.map +1 -0
  45. package/dist/main/lib/vectors/errors.js +76 -0
  46. package/dist/main/lib/vectors/errors.js.map +1 -0
  47. package/dist/main/lib/vectors/fetch.d.ts +57 -0
  48. package/dist/main/lib/vectors/fetch.d.ts.map +1 -0
  49. package/dist/main/lib/vectors/fetch.js +167 -0
  50. package/dist/main/lib/vectors/fetch.js.map +1 -0
  51. package/dist/main/lib/vectors/helpers.d.ts +49 -0
  52. package/dist/main/lib/vectors/helpers.d.ts.map +1 -0
  53. package/dist/main/lib/vectors/helpers.js +89 -0
  54. package/dist/main/lib/vectors/helpers.js.map +1 -0
  55. package/dist/main/lib/vectors/index.d.ts +11 -0
  56. package/dist/main/lib/vectors/index.d.ts.map +1 -0
  57. package/dist/main/lib/vectors/index.js +31 -0
  58. package/dist/main/lib/vectors/index.js.map +1 -0
  59. package/dist/main/lib/vectors/types.d.ts +277 -0
  60. package/dist/main/lib/vectors/types.d.ts.map +1 -0
  61. package/dist/main/lib/vectors/types.js +3 -0
  62. package/dist/main/lib/vectors/types.js.map +1 -0
  63. package/dist/main/lib/version.d.ts +1 -1
  64. package/dist/main/lib/version.d.ts.map +1 -1
  65. package/dist/main/lib/version.js +1 -1
  66. package/dist/main/lib/version.js.map +1 -1
  67. package/dist/main/packages/BlobDownloadBuilder.js +3 -14
  68. package/dist/main/packages/BlobDownloadBuilder.js.map +1 -1
  69. package/dist/main/packages/StorageAnalyticsApi.d.ts +123 -0
  70. package/dist/main/packages/StorageAnalyticsApi.d.ts.map +1 -0
  71. package/dist/main/packages/StorageAnalyticsApi.js +168 -0
  72. package/dist/main/packages/StorageAnalyticsApi.js.map +1 -0
  73. package/dist/main/packages/StorageBucketApi.js +7 -15
  74. package/dist/main/packages/StorageBucketApi.js.map +1 -1
  75. package/dist/main/packages/StorageFileApi.js +16 -27
  76. package/dist/main/packages/StorageFileApi.js.map +1 -1
  77. package/dist/main/packages/StreamDownloadBuilder.js +2 -10
  78. package/dist/main/packages/StreamDownloadBuilder.js.map +1 -1
  79. package/dist/module/StorageClient.d.ts +28 -0
  80. package/dist/module/StorageClient.d.ts.map +1 -1
  81. package/dist/module/StorageClient.js +35 -0
  82. package/dist/module/StorageClient.js.map +1 -1
  83. package/dist/module/index.d.ts +2 -0
  84. package/dist/module/index.d.ts.map +1 -1
  85. package/dist/module/index.js +2 -0
  86. package/dist/module/index.js.map +1 -1
  87. package/dist/module/lib/constants.d.ts.map +1 -1
  88. package/dist/module/lib/constants.js +3 -1
  89. package/dist/module/lib/constants.js.map +1 -1
  90. package/dist/module/lib/fetch.js +1 -9
  91. package/dist/module/lib/fetch.js.map +1 -1
  92. package/dist/module/lib/helpers.js +1 -9
  93. package/dist/module/lib/helpers.js.map +1 -1
  94. package/dist/module/lib/index.d.ts +1 -0
  95. package/dist/module/lib/index.d.ts.map +1 -1
  96. package/dist/module/lib/index.js +1 -0
  97. package/dist/module/lib/index.js.map +1 -1
  98. package/dist/module/lib/types.d.ts +36 -4
  99. package/dist/module/lib/types.d.ts.map +1 -1
  100. package/dist/module/lib/vectors/StorageVectorsClient.d.ts +310 -0
  101. package/dist/module/lib/vectors/StorageVectorsClient.d.ts.map +1 -0
  102. package/dist/module/lib/vectors/StorageVectorsClient.js +360 -0
  103. package/dist/module/lib/vectors/StorageVectorsClient.js.map +1 -0
  104. package/dist/module/lib/vectors/VectorBucketApi.d.ts +129 -0
  105. package/dist/module/lib/vectors/VectorBucketApi.d.ts.map +1 -0
  106. package/dist/module/lib/vectors/VectorBucketApi.js +196 -0
  107. package/dist/module/lib/vectors/VectorBucketApi.js.map +1 -0
  108. package/dist/module/lib/vectors/VectorDataApi.d.ts +221 -0
  109. package/dist/module/lib/vectors/VectorDataApi.d.ts.map +1 -0
  110. package/dist/module/lib/vectors/VectorDataApi.js +333 -0
  111. package/dist/module/lib/vectors/VectorDataApi.js.map +1 -0
  112. package/dist/module/lib/vectors/VectorIndexApi.d.ts +157 -0
  113. package/dist/module/lib/vectors/VectorIndexApi.d.ts.map +1 -0
  114. package/dist/module/lib/vectors/VectorIndexApi.js +215 -0
  115. package/dist/module/lib/vectors/VectorIndexApi.js.map +1 -0
  116. package/dist/module/lib/vectors/constants.d.ts +5 -0
  117. package/dist/module/lib/vectors/constants.d.ts.map +1 -0
  118. package/dist/module/lib/vectors/constants.js +6 -0
  119. package/dist/module/lib/vectors/constants.js.map +1 -0
  120. package/dist/module/lib/vectors/errors.d.ts +55 -0
  121. package/dist/module/lib/vectors/errors.d.ts.map +1 -0
  122. package/dist/module/lib/vectors/errors.js +69 -0
  123. package/dist/module/lib/vectors/errors.js.map +1 -0
  124. package/dist/module/lib/vectors/fetch.d.ts +57 -0
  125. package/dist/module/lib/vectors/fetch.d.ts.map +1 -0
  126. package/dist/module/lib/vectors/fetch.js +161 -0
  127. package/dist/module/lib/vectors/fetch.js.map +1 -0
  128. package/dist/module/lib/vectors/helpers.d.ts +49 -0
  129. package/dist/module/lib/vectors/helpers.d.ts.map +1 -0
  130. package/dist/module/lib/vectors/helpers.js +81 -0
  131. package/dist/module/lib/vectors/helpers.js.map +1 -0
  132. package/dist/module/lib/vectors/index.d.ts +11 -0
  133. package/dist/module/lib/vectors/index.d.ts.map +1 -0
  134. package/dist/module/lib/vectors/index.js +11 -0
  135. package/dist/module/lib/vectors/index.js.map +1 -0
  136. package/dist/module/lib/vectors/types.d.ts +277 -0
  137. package/dist/module/lib/vectors/types.d.ts.map +1 -0
  138. package/dist/module/lib/vectors/types.js +2 -0
  139. package/dist/module/lib/vectors/types.js.map +1 -0
  140. package/dist/module/lib/version.d.ts +1 -1
  141. package/dist/module/lib/version.d.ts.map +1 -1
  142. package/dist/module/lib/version.js +1 -1
  143. package/dist/module/lib/version.js.map +1 -1
  144. package/dist/module/packages/BlobDownloadBuilder.js +1 -9
  145. package/dist/module/packages/BlobDownloadBuilder.js.map +1 -1
  146. package/dist/module/packages/StorageAnalyticsApi.d.ts +123 -0
  147. package/dist/module/packages/StorageAnalyticsApi.d.ts.map +1 -0
  148. package/dist/module/packages/StorageAnalyticsApi.js +165 -0
  149. package/dist/module/packages/StorageAnalyticsApi.js.map +1 -0
  150. package/dist/module/packages/StorageBucketApi.js +1 -9
  151. package/dist/module/packages/StorageBucketApi.js.map +1 -1
  152. package/dist/module/packages/StorageFileApi.js +1 -9
  153. package/dist/module/packages/StorageFileApi.js.map +1 -1
  154. package/dist/module/packages/StreamDownloadBuilder.js +1 -9
  155. package/dist/module/packages/StreamDownloadBuilder.js.map +1 -1
  156. package/dist/tsconfig.module.tsbuildinfo +1 -0
  157. package/dist/tsconfig.tsbuildinfo +1 -0
  158. package/dist/umd/supabase.js +1 -1
  159. package/package.json +2 -2
  160. package/src/StorageClient.ts +37 -0
  161. package/src/index.ts +2 -0
  162. package/src/lib/constants.ts +3 -1
  163. package/src/lib/index.ts +1 -0
  164. package/src/lib/types.ts +39 -2
  165. package/src/lib/vectors/StorageVectorsClient.ts +405 -0
  166. package/src/lib/vectors/VectorBucketApi.ts +217 -0
  167. package/src/lib/vectors/VectorDataApi.ts +341 -0
  168. package/src/lib/vectors/VectorIndexApi.ts +245 -0
  169. package/src/lib/vectors/constants.ts +5 -0
  170. package/src/lib/vectors/errors.ts +78 -0
  171. package/src/lib/vectors/fetch.ts +218 -0
  172. package/src/lib/vectors/helpers.ts +93 -0
  173. package/src/lib/vectors/index.ts +66 -0
  174. package/src/lib/vectors/types.ts +299 -0
  175. package/src/lib/version.ts +1 -1
  176. package/src/packages/StorageAnalyticsApi.ts +202 -0
package/README.md CHANGED
@@ -1,15 +1,43 @@
1
- # `storage-js`
1
+ <br />
2
+ <p align="center">
3
+ <a href="https://supabase.io">
4
+ <picture>
5
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--dark.svg">
6
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--light.svg">
7
+ <img alt="Supabase Logo" width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/logo-preview.jpg">
8
+ </picture>
9
+ </a>
10
+
11
+ <h1 align="center">Supabase Storage JS SDK</h1>
12
+
13
+ <h3 align="center">JavaScript SDK to interact with Supabase Storage, including file storage and vector embeddings.</h3>
14
+
15
+ <p align="center">
16
+ <a href="https://supabase.com/docs/guides/storage">Guides</a>
17
+ ·
18
+ <a href="https://supabase.com/docs/reference/javascript/storage-createbucket">Reference Docs</a>
19
+ ·
20
+ <a href="https://supabase.github.io/supabase-js/storage-js/v2/spec.json">TypeDoc</a>
21
+ </p>
22
+ </p>
2
23
 
3
24
  <div align="center">
4
25
 
26
+ [![Build](https://github.com/supabase/supabase-js/workflows/CI/badge.svg)](https://github.com/supabase/supabase-js/actions?query=branch%3Amaster)
27
+ [![Package](https://img.shields.io/npm/v/@supabase/storage-js)](https://www.npmjs.com/package/@supabase/storage-js)
28
+ [![License: MIT](https://img.shields.io/npm/l/@supabase/supabase-js)](#license)
5
29
  [![pkg.pr.new](https://pkg.pr.new/badge/supabase/storage-js)](https://pkg.pr.new/~/supabase/storage-js)
6
30
 
7
31
  </div>
8
32
 
9
- JS Client library to interact with Supabase Storage.
33
+ ## Features
10
34
 
11
- - Documentation: https://supabase.io/docs/reference/javascript/storage-createbucket
12
- - Typedoc: https://supabase.github.io/supabase-js/storage-js/v2/spec.json
35
+ - **File Storage**: Upload, download, list, move, and delete files
36
+ - **Access Control**: Public and private buckets with fine-grained permissions
37
+ - **Signed URLs**: Generate time-limited URLs for secure file access
38
+ - **Image Transformations**: On-the-fly image resizing and optimization
39
+ - **Vector Embeddings**: Store and query high-dimensional embeddings with similarity search
40
+ - **Analytics Buckets**: Iceberg table-based buckets optimized for analytical queries and data processing
13
41
 
14
42
  ## Quick Start Guide
15
43
 
@@ -21,6 +49,33 @@ npm install @supabase/storage-js
21
49
 
22
50
  ### Connecting to the storage backend
23
51
 
52
+ There are two ways to use the Storage SDK:
53
+
54
+ #### Option 1: Via Supabase Client (Recommended)
55
+
56
+ If you're already using `@supabase/supabase-js`, access storage through the client:
57
+
58
+ ```js
59
+ import { createClient } from '@supabase/supabase-js'
60
+
61
+ const supabase = createClient(
62
+ 'https://<project_ref>.supabase.co',
63
+ '<your-anon-key>'
64
+ )
65
+
66
+ // Access storage
67
+ const storage = supabase.storage
68
+
69
+ // Access different bucket types
70
+ const regularBucket = storage.from('my-bucket')
71
+ const vectorBucket = storage.vectors.from('embeddings-bucket')
72
+ const analyticsBucket = storage.analytics // Analytics API
73
+ ```
74
+
75
+ #### Option 2: Standalone StorageClient
76
+
77
+ For applications that only need storage functionality:
78
+
24
79
  ```js
25
80
  import { StorageClient } from '@supabase/storage-js'
26
81
 
@@ -31,8 +86,79 @@ const storageClient = new StorageClient(STORAGE_URL, {
31
86
  apikey: SERVICE_KEY,
32
87
  Authorization: `Bearer ${SERVICE_KEY}`,
33
88
  })
89
+
90
+ // Access different bucket types
91
+ const regularBucket = storageClient.from('my-bucket')
92
+ const vectorBucket = storageClient.vectors.from('embeddings-bucket')
93
+ const analyticsBucket = storageClient.analytics // Analytics API
94
+ ```
95
+
96
+ > **When to use each approach:**
97
+ > - Use `supabase.storage` when working with other Supabase features (auth, database, etc.)
98
+ > - Use `new StorageClient()` for storage-only applications or when you need fine-grained control
99
+
100
+ ### Understanding Bucket Types
101
+
102
+ Supabase Storage supports three types of buckets, each optimized for different use cases:
103
+
104
+ #### 1. Regular Storage Buckets (File Storage)
105
+
106
+ Standard buckets for storing files, images, videos, and other assets.
107
+
108
+ ```js
109
+ // Create regular storage bucket
110
+ const { data, error } = await storageClient.createBucket('my-files', {
111
+ public: false
112
+ })
113
+
114
+ // Upload files
115
+ await storageClient.from('my-files').upload('avatar.png', file)
116
+ ```
117
+
118
+ **Use cases:** User uploads, media assets, documents, backups
119
+
120
+ #### 2. Vector Buckets (Embeddings Storage)
121
+
122
+ Specialized buckets for storing and querying high-dimensional vector embeddings.
123
+
124
+ ```js
125
+ // Create vector bucket
126
+ await storageClient.vectors.createBucket('embeddings-prod')
127
+
128
+ // Create index and insert vectors
129
+ const bucket = storageClient.vectors.from('embeddings-prod')
130
+ await bucket.createIndex({
131
+ indexName: 'documents',
132
+ dimension: 1536,
133
+ distanceMetric: 'cosine'
134
+ })
135
+ ```
136
+
137
+ **Use cases:** Semantic search, AI-powered recommendations, similarity matching
138
+
139
+ **[See full Vector Embeddings documentation below](#vector-embeddings)**
140
+
141
+ #### 3. Analytics Buckets
142
+
143
+ Specialized buckets using Apache Iceberg table format, optimized for analytical queries and large-scale data processing.
144
+
145
+ ```js
146
+ // Create analytics bucket
147
+ await storageClient.analytics.createBucket('analytics-data')
148
+
149
+ // List analytics buckets
150
+ const { data, error } = await storageClient.analytics.listBuckets()
151
+
152
+ // Delete analytics bucket
153
+ await storageClient.analytics.deleteBucket('analytics-data')
34
154
  ```
35
155
 
156
+ **Use cases:** Time-series data, analytical queries, data lakes, large-scale data processing, business intelligence
157
+
158
+ **[See full Analytics Buckets documentation below](#analytics-buckets)**
159
+
160
+ ---
161
+
36
162
  ### Handling resources
37
163
 
38
164
  #### Handling Storage Buckets
@@ -157,6 +283,791 @@ const storageClient = new StorageClient(STORAGE_URL, {
157
283
  const { data, error } = await storageClient.from('public-bucket').getPublicUrl('path/to/file')
158
284
  ```
159
285
 
286
+ ## Analytics Buckets
287
+
288
+ Supabase Storage provides specialized analytics buckets using Apache Iceberg table format, optimized for analytical workloads and large-scale data processing. These buckets are designed for data lake architectures, time-series data, and business intelligence applications.
289
+
290
+ ### What are Analytics Buckets?
291
+
292
+ Analytics buckets use the Apache Iceberg open table format, providing:
293
+ - **ACID transactions** for data consistency
294
+ - **Schema evolution** without data rewrites
295
+ - **Time travel** to query historical data
296
+ - **Efficient metadata management** for large datasets
297
+ - **Optimized for analytical queries** rather than individual file operations
298
+
299
+ ### When to Use Analytics Buckets
300
+
301
+ **Use analytics buckets for:**
302
+ - Time-series data (logs, metrics, events)
303
+ - Data lake architectures
304
+ - Business intelligence and reporting
305
+ - Large-scale batch processing
306
+ - Analytical workloads requiring ACID guarantees
307
+
308
+ **Use regular storage buckets for:**
309
+ - User file uploads (images, documents, videos)
310
+ - Individual file management
311
+ - Content delivery
312
+ - Simple object storage needs
313
+
314
+ ### Quick Start
315
+
316
+ You can access analytics functionality through the `analytics` property on your storage client:
317
+
318
+ #### Via Supabase Client
319
+
320
+ ```typescript
321
+ import { createClient } from '@supabase/supabase-js'
322
+
323
+ const supabase = createClient(
324
+ 'https://your-project.supabase.co',
325
+ 'your-anon-key'
326
+ )
327
+
328
+ // Access analytics operations
329
+ const analytics = supabase.storage.analytics
330
+
331
+ // Create an analytics bucket
332
+ const { data, error } = await analytics.createBucket('analytics-data')
333
+ if (error) {
334
+ console.error('Failed to create analytics bucket:', error.message)
335
+ } else {
336
+ console.log('Created bucket:', data.name)
337
+ }
338
+ ```
339
+
340
+ #### Via StorageClient
341
+
342
+ ```typescript
343
+ import { StorageClient } from '@supabase/storage-js'
344
+
345
+ const storageClient = new StorageClient('https://your-project.supabase.co/storage/v1', {
346
+ apikey: 'YOUR_API_KEY',
347
+ Authorization: 'Bearer YOUR_TOKEN',
348
+ })
349
+
350
+ // Access analytics operations
351
+ const analytics = storageClient.analytics
352
+
353
+ // Create an analytics bucket
354
+ await analytics.createBucket('analytics-data')
355
+ ```
356
+
357
+ ### API Reference
358
+
359
+ #### Create Analytics Bucket
360
+
361
+ Creates a new analytics bucket using Iceberg table format:
362
+
363
+ ```typescript
364
+ const { data, error } = await analytics.createBucket('my-analytics-bucket')
365
+
366
+ if (error) {
367
+ console.error('Error:', error.message)
368
+ } else {
369
+ console.log('Created bucket:', data)
370
+ }
371
+ ```
372
+
373
+ **Returns:**
374
+ ```typescript
375
+ {
376
+ data: {
377
+ id: string
378
+ type: 'ANALYTICS'
379
+ format: string
380
+ created_at: string
381
+ updated_at: string
382
+ } | null
383
+ error: StorageError | null
384
+ }
385
+ ```
386
+
387
+ #### List Analytics Buckets
388
+
389
+ Retrieves all analytics buckets in your project with optional filtering and pagination:
390
+
391
+ ```typescript
392
+ const { data, error } = await analytics.listBuckets({
393
+ limit: 10,
394
+ offset: 0,
395
+ sortColumn: 'created_at',
396
+ sortOrder: 'desc',
397
+ search: 'prod'
398
+ })
399
+
400
+ if (data) {
401
+ console.log(`Found ${data.length} analytics buckets`)
402
+ data.forEach(bucket => {
403
+ console.log(`- ${bucket.id} (created: ${bucket.created_at})`)
404
+ })
405
+ }
406
+ ```
407
+
408
+ **Parameters:**
409
+ - `limit?: number` - Maximum number of buckets to return
410
+ - `offset?: number` - Number of buckets to skip (for pagination)
411
+ - `sortColumn?: 'id' | 'name' | 'created_at' | 'updated_at'` - Column to sort by
412
+ - `sortOrder?: 'asc' | 'desc'` - Sort direction
413
+ - `search?: string` - Search term to filter bucket names
414
+
415
+ **Returns:**
416
+ ```typescript
417
+ {
418
+ data: AnalyticBucket[] | null
419
+ error: StorageError | null
420
+ }
421
+ ```
422
+
423
+ **Example with Pagination:**
424
+
425
+ ```typescript
426
+ // Fetch first page
427
+ const firstPage = await analytics.listBuckets({
428
+ limit: 100,
429
+ offset: 0,
430
+ sortColumn: 'created_at',
431
+ sortOrder: 'desc'
432
+ })
433
+
434
+ // Fetch second page
435
+ const secondPage = await analytics.listBuckets({
436
+ limit: 100,
437
+ offset: 100,
438
+ sortColumn: 'created_at',
439
+ sortOrder: 'desc'
440
+ })
441
+ ```
442
+
443
+ #### Delete Analytics Bucket
444
+
445
+ Deletes an analytics bucket. The bucket must be empty before deletion.
446
+
447
+ ```typescript
448
+ const { data, error } = await analytics.deleteBucket('old-analytics-bucket')
449
+
450
+ if (error) {
451
+ console.error('Failed to delete:', error.message)
452
+ } else {
453
+ console.log('Bucket deleted:', data.message)
454
+ }
455
+ ```
456
+
457
+ **Returns:**
458
+ ```typescript
459
+ {
460
+ data: { message: string } | null
461
+ error: StorageError | null
462
+ }
463
+ ```
464
+
465
+ > **Note:** A bucket cannot be deleted if it contains data. You must empty the bucket first.
466
+
467
+ ### Error Handling
468
+
469
+ Analytics buckets use the same error handling pattern as the rest of the Storage SDK:
470
+
471
+ ```typescript
472
+ const { data, error } = await analytics.createBucket('my-bucket')
473
+
474
+ if (error) {
475
+ console.error('Error:', error.message)
476
+ console.error('Status:', error.status)
477
+ console.error('Status Code:', error.statusCode)
478
+ // Handle error appropriately
479
+ }
480
+ ```
481
+
482
+ #### Throwing Errors
483
+
484
+ You can configure the client to throw errors instead of returning them:
485
+
486
+ ```typescript
487
+ const analytics = storageClient.analytics
488
+ analytics.throwOnError()
489
+
490
+ try {
491
+ const { data } = await analytics.createBucket('my-bucket')
492
+ // data is guaranteed to be present
493
+ console.log('Success:', data)
494
+ } catch (error) {
495
+ if (error instanceof StorageApiError) {
496
+ console.error('API Error:', error.statusCode, error.message)
497
+ }
498
+ }
499
+ ```
500
+
501
+ ### TypeScript Types
502
+
503
+ The library exports TypeScript types for analytics buckets:
504
+
505
+ ```typescript
506
+ import type {
507
+ AnalyticBucket,
508
+ BucketType,
509
+ StorageError,
510
+ } from '@supabase/storage-js'
511
+
512
+ // AnalyticBucket type
513
+ interface AnalyticBucket {
514
+ id: string
515
+ type: 'ANALYTICS'
516
+ format: string
517
+ created_at: string
518
+ updated_at: string
519
+ }
520
+ ```
521
+
522
+ ### Common Patterns
523
+
524
+ #### Checking if a Bucket Exists
525
+
526
+ ```typescript
527
+ async function bucketExists(bucketName: string): Promise<boolean> {
528
+ const { data, error } = await analytics.listBuckets({
529
+ search: bucketName
530
+ })
531
+
532
+ if (error) {
533
+ console.error('Error checking bucket:', error.message)
534
+ return false
535
+ }
536
+
537
+ return data?.some(bucket => bucket.id === bucketName) ?? false
538
+ }
539
+ ```
540
+
541
+ #### Creating Bucket with Error Handling
542
+
543
+ ```typescript
544
+ async function ensureAnalyticsBucket(bucketName: string) {
545
+ // Try to create the bucket
546
+ const { data, error } = await analytics.createBucket(bucketName)
547
+
548
+ if (error) {
549
+ // Check if bucket already exists (conflict error)
550
+ if (error.statusCode === '409') {
551
+ console.log(`Bucket '${bucketName}' already exists`)
552
+ return { success: true, created: false }
553
+ }
554
+
555
+ // Other error occurred
556
+ console.error('Failed to create bucket:', error.message)
557
+ return { success: false, error }
558
+ }
559
+
560
+ console.log(`Created new bucket: '${bucketName}'`)
561
+ return { success: true, created: true, data }
562
+ }
563
+ ```
564
+
565
+ #### Listing All Buckets with Pagination
566
+
567
+ ```typescript
568
+ async function getAllAnalyticsBuckets() {
569
+ const allBuckets: AnalyticBucket[] = []
570
+ let offset = 0
571
+ const limit = 100
572
+
573
+ while (true) {
574
+ const { data, error } = await analytics.listBuckets({
575
+ limit,
576
+ offset,
577
+ sortColumn: 'created_at',
578
+ sortOrder: 'desc'
579
+ })
580
+
581
+ if (error) {
582
+ console.error('Error fetching buckets:', error.message)
583
+ break
584
+ }
585
+
586
+ if (!data || data.length === 0) {
587
+ break
588
+ }
589
+
590
+ allBuckets.push(...data)
591
+
592
+ // If we got fewer results than the limit, we've reached the end
593
+ if (data.length < limit) {
594
+ break
595
+ }
596
+
597
+ offset += limit
598
+ }
599
+
600
+ return allBuckets
601
+ }
602
+ ```
603
+
604
+ ## Vector Embeddings
605
+
606
+ Supabase Storage provides built-in support for storing and querying high-dimensional vector embeddings, powered by S3 Vectors. This enables semantic search, similarity matching, and AI-powered applications without needing a separate vector database.
607
+
608
+ > **Note:** Vector embeddings functionality is available in `@supabase/storage-js` v2.76 and later.
609
+
610
+ ### Features
611
+
612
+ - **Vector Buckets**: Organize vector indexes into logical containers
613
+ - **Vector Indexes**: Define schemas with configurable dimensions and distance metrics
614
+ - **Batch Operations**: Insert/update/delete up to 500 vectors per request
615
+ - **Similarity Search**: Query for nearest neighbors using cosine, euclidean, or dot product distance
616
+ - **Metadata Filtering**: Store and filter vectors by arbitrary JSON metadata
617
+ - **Pagination**: Efficiently scan large vector datasets
618
+ - **Parallel Scanning**: Distribute scans across multiple workers for high throughput
619
+ - **Cross-platform**: Works in Node.js, browsers, and edge runtimes
620
+
621
+ ### Quick Start
622
+
623
+ You can access vector functionality in three ways, depending on your use case:
624
+
625
+ #### Option 1: Via Supabase Client (Most Common)
626
+
627
+ If you're using the full Supabase client:
628
+
629
+ ```typescript
630
+ import { createClient } from '@supabase/supabase-js'
631
+
632
+ const supabase = createClient(
633
+ 'https://your-project.supabase.co',
634
+ 'your-anon-key'
635
+ )
636
+
637
+ // Access vector operations through storage
638
+ const vectors = supabase.storage.vectors
639
+
640
+ // Create a vector bucket
641
+ await vectors.createBucket('embeddings-prod')
642
+
643
+ // Create an index
644
+ const bucket = vectors.from('embeddings-prod')
645
+ await bucket.createIndex({
646
+ indexName: 'documents-openai',
647
+ dataType: 'float32',
648
+ dimension: 1536,
649
+ distanceMetric: 'cosine',
650
+ })
651
+
652
+ // Insert vectors
653
+ const index = bucket.index('documents-openai')
654
+ await index.putVectors({
655
+ vectors: [
656
+ {
657
+ key: 'doc-1',
658
+ data: { float32: [0.1, 0.2, 0.3 /* ...1536 dimensions */] },
659
+ metadata: { title: 'Introduction', category: 'docs' },
660
+ },
661
+ ],
662
+ })
663
+
664
+ // Query similar vectors
665
+ const { data, error } = await index.queryVectors({
666
+ queryVector: { float32: [0.15, 0.25, 0.35 /* ...1536 dimensions */] },
667
+ topK: 5,
668
+ returnDistance: true,
669
+ returnMetadata: true,
670
+ })
671
+
672
+ if (data) {
673
+ data.matches.forEach((match) => {
674
+ console.log(`${match.key}: distance=${match.distance}`)
675
+ console.log('Metadata:', match.metadata)
676
+ })
677
+ }
678
+ ```
679
+
680
+ #### Option 2: Via StorageClient
681
+
682
+ If you're using the standalone `StorageClient` for storage operations, access vectors through the `vectors` property:
683
+
684
+ ```typescript
685
+ import { StorageClient } from '@supabase/storage-js'
686
+
687
+ const storageClient = new StorageClient('https://your-project.supabase.co/storage/v1', {
688
+ apikey: 'YOUR_API_KEY',
689
+ Authorization: 'Bearer YOUR_TOKEN',
690
+ })
691
+
692
+ // Access vector operations
693
+ const vectors = storageClient.vectors
694
+
695
+ // Use the same API as shown in Option 1
696
+ await vectors.createBucket('embeddings-prod')
697
+ const bucket = vectors.from('embeddings-prod')
698
+ // ... rest of operations
699
+ ```
700
+
701
+ #### Option 3: Standalone Vector Client
702
+
703
+ For vector-only applications that don't need regular file storage operations:
704
+
705
+ ```typescript
706
+ import { StorageVectorsClient } from '@supabase/storage-js'
707
+
708
+ // Initialize standalone vector client
709
+ const vectorClient = new StorageVectorsClient('https://your-project.supabase.co/storage/v1', {
710
+ headers: { Authorization: 'Bearer YOUR_TOKEN' },
711
+ })
712
+
713
+ // Use the same API as shown in Option 1
714
+ await vectorClient.createBucket('embeddings-prod')
715
+ const bucket = vectorClient.from('embeddings-prod')
716
+ // ... rest of operations
717
+ ```
718
+
719
+ > **When to use each approach:**
720
+ >
721
+ > - **Option 1**: When using other Supabase features (auth, database, realtime)
722
+ > - **Option 2**: When working with both file storage and vectors
723
+ > - **Option 3**: For dedicated vector-only applications without file storage
724
+
725
+ ### API Reference
726
+
727
+ #### Client Initialization
728
+
729
+ ```typescript
730
+ const vectorClient = new StorageVectorsClient(url, options?)
731
+ ```
732
+
733
+ **Options:**
734
+
735
+ - `headers?: Record<string, string>` - Custom HTTP headers (e.g., Authorization)
736
+ - `fetch?: Fetch` - Custom fetch implementation
737
+
738
+ #### Vector Buckets
739
+
740
+ Vector buckets are top-level containers for organizing vector indexes.
741
+
742
+ ##### Create Bucket
743
+
744
+ ```typescript
745
+ const { data, error } = await vectorClient.createBucket('my-bucket')
746
+ ```
747
+
748
+ ##### Get Bucket
749
+
750
+ ```typescript
751
+ const { data, error } = await vectorClient.getBucket('my-bucket')
752
+ console.log('Created at:', new Date(data.vectorBucket.creationTime! * 1000))
753
+ ```
754
+
755
+ ##### List Buckets
756
+
757
+ ```typescript
758
+ const { data, error } = await vectorClient.listBuckets({
759
+ prefix: 'prod-',
760
+ maxResults: 100,
761
+ })
762
+
763
+ // Pagination
764
+ if (data?.nextToken) {
765
+ const next = await vectorClient.listBuckets({ nextToken: data.nextToken })
766
+ }
767
+ ```
768
+
769
+ ##### Delete Bucket
770
+
771
+ ```typescript
772
+ // Bucket must be empty (all indexes deleted first)
773
+ const { error } = await vectorClient.deleteBucket('my-bucket')
774
+ ```
775
+
776
+ #### Vector Indexes
777
+
778
+ Vector indexes define the schema for embeddings including dimension and distance metric.
779
+
780
+ ##### Create Index
781
+
782
+ ```typescript
783
+ const bucket = vectorClient.from('my-bucket')
784
+
785
+ await bucket.createIndex({
786
+ indexName: 'my-index',
787
+ dataType: 'float32',
788
+ dimension: 1536,
789
+ distanceMetric: 'cosine', // 'cosine' | 'euclidean' | 'dotproduct'
790
+ metadataConfiguration: {
791
+ nonFilterableMetadataKeys: ['raw_text', 'internal_id'],
792
+ },
793
+ })
794
+ ```
795
+
796
+ **Distance Metrics:**
797
+
798
+ - `cosine` - Cosine similarity (normalized dot product)
799
+ - `euclidean` - Euclidean distance (L2 norm)
800
+ - `dotproduct` - Dot product similarity
801
+
802
+ ##### Get Index
803
+
804
+ ```typescript
805
+ const { data, error } = await bucket.getIndex('my-index')
806
+ console.log('Dimension:', data?.index.dimension)
807
+ console.log('Distance metric:', data?.index.distanceMetric)
808
+ ```
809
+
810
+ ##### List Indexes
811
+
812
+ ```typescript
813
+ const { data, error } = await bucket.listIndexes({
814
+ prefix: 'documents-',
815
+ maxResults: 100,
816
+ })
817
+ ```
818
+
819
+ ##### Delete Index
820
+
821
+ ```typescript
822
+ // Deletes index and all its vectors
823
+ await bucket.deleteIndex('my-index')
824
+ ```
825
+
826
+ #### Vector Operations
827
+
828
+ ##### Insert/Update Vectors (Upsert)
829
+
830
+ ```typescript
831
+ const index = vectorClient.from('my-bucket').index('my-index')
832
+
833
+ await index.putVectors({
834
+ vectors: [
835
+ {
836
+ key: 'unique-id-1',
837
+ data: {
838
+ float32: [
839
+ /* 1536 numbers */
840
+ ],
841
+ },
842
+ metadata: {
843
+ title: 'Document Title',
844
+ category: 'technical',
845
+ page: 1,
846
+ },
847
+ },
848
+ // ... up to 500 vectors per request
849
+ ],
850
+ })
851
+ ```
852
+
853
+ **Limitations:**
854
+
855
+ - 1-500 vectors per request
856
+ - Vectors must match index dimension
857
+ - Keys must be unique within index
858
+
859
+ ##### Get Vectors by Key
860
+
861
+ ```typescript
862
+ const { data, error } = await index.getVectors({
863
+ keys: ['doc-1', 'doc-2', 'doc-3'],
864
+ returnData: true, // Include embeddings
865
+ returnMetadata: true, // Include metadata
866
+ })
867
+
868
+ data?.vectors.forEach((v) => {
869
+ console.log(v.key, v.metadata)
870
+ })
871
+ ```
872
+
873
+ ##### Query Similar Vectors (ANN Search)
874
+
875
+ ```typescript
876
+ const { data, error } = await index.queryVectors({
877
+ queryVector: {
878
+ float32: [
879
+ /* 1536 numbers */
880
+ ],
881
+ },
882
+ topK: 10,
883
+ filter: {
884
+ category: 'technical',
885
+ published: true,
886
+ },
887
+ returnDistance: true,
888
+ returnMetadata: true,
889
+ })
890
+
891
+ // Results ordered by similarity
892
+ data?.matches.forEach((match) => {
893
+ console.log(`${match.key}: distance=${match.distance}`)
894
+ })
895
+ ```
896
+
897
+ **Filter Syntax:**
898
+ The `filter` parameter accepts arbitrary JSON for metadata filtering. Non-filterable keys (configured at index creation) cannot be used in filters but can still be returned.
899
+
900
+ ##### List/Scan Vectors
901
+
902
+ ```typescript
903
+ // Simple pagination
904
+ let nextToken: string | undefined
905
+ do {
906
+ const { data } = await index.listVectors({
907
+ maxResults: 500,
908
+ nextToken,
909
+ returnMetadata: true,
910
+ })
911
+
912
+ console.log('Batch:', data?.vectors.length)
913
+ nextToken = data?.nextToken
914
+ } while (nextToken)
915
+
916
+ // Parallel scanning (4 workers)
917
+ const workers = [0, 1, 2, 3].map(async (segmentIndex) => {
918
+ const { data } = await index.listVectors({
919
+ segmentCount: 4,
920
+ segmentIndex,
921
+ returnMetadata: true,
922
+ })
923
+ return data?.vectors || []
924
+ })
925
+
926
+ const results = await Promise.all(workers)
927
+ const allVectors = results.flat()
928
+ ```
929
+
930
+ **Limitations:**
931
+
932
+ - `maxResults`: 1-1000 (default: 500)
933
+ - `segmentCount`: 1-16
934
+ - Response may be limited by 1MB size
935
+
936
+ ##### Delete Vectors
937
+
938
+ ```typescript
939
+ await index.deleteVectors({
940
+ keys: ['doc-1', 'doc-2', 'doc-3'],
941
+ // ... up to 500 keys per request
942
+ })
943
+ ```
944
+
945
+ ### Error Handling
946
+
947
+ The library uses a consistent error handling pattern:
948
+
949
+ ```typescript
950
+ const { data, error } = await vectorClient.createBucket('my-bucket')
951
+
952
+ if (error) {
953
+ console.error('Error:', error.message)
954
+ console.error('Status:', error.status)
955
+ console.error('Code:', error.statusCode)
956
+ }
957
+ ```
958
+
959
+ #### Error Codes
960
+
961
+ | Code | HTTP | Description |
962
+ | ---------------------------- | ---- | ----------------------- |
963
+ | `InternalError` | 500 | Internal server error |
964
+ | `S3VectorConflictException` | 409 | Resource already exists |
965
+ | `S3VectorNotFoundException` | 404 | Resource not found |
966
+ | `S3VectorBucketNotEmpty` | 400 | Bucket contains indexes |
967
+ | `S3VectorMaxBucketsExceeded` | 400 | Bucket quota exceeded |
968
+ | `S3VectorMaxIndexesExceeded` | 400 | Index quota exceeded |
969
+
970
+ #### Throwing Errors
971
+
972
+ You can configure the client to throw errors instead:
973
+
974
+ ```typescript
975
+ const vectorClient = new StorageVectorsClient(url, options)
976
+ vectorClient.throwOnError()
977
+
978
+ try {
979
+ const { data } = await vectorClient.createBucket('my-bucket')
980
+ // data is guaranteed to be present
981
+ } catch (error) {
982
+ if (error instanceof StorageVectorsApiError) {
983
+ console.error('API Error:', error.statusCode)
984
+ }
985
+ }
986
+ ```
987
+
988
+ ### Advanced Usage
989
+
990
+ #### Scoped Clients
991
+
992
+ Create scoped clients for cleaner code:
993
+
994
+ ```typescript
995
+ // Bucket-scoped operations
996
+ const bucket = vectorClient.from('embeddings-prod')
997
+ await bucket.createIndex({
998
+ /* ... */
999
+ })
1000
+ await bucket.listIndexes()
1001
+
1002
+ // Index-scoped operations
1003
+ const index = bucket.index('documents-openai')
1004
+ await index.putVectors({
1005
+ /* ... */
1006
+ })
1007
+ await index.queryVectors({
1008
+ /* ... */
1009
+ })
1010
+ ```
1011
+
1012
+ #### Custom Fetch
1013
+
1014
+ Provide a custom fetch implementation:
1015
+
1016
+ ```typescript
1017
+ import { StorageVectorsClient } from '@supabase/storage-js'
1018
+
1019
+ const vectorClient = new StorageVectorsClient(url, {
1020
+ fetch: customFetch,
1021
+ headers: {
1022
+ /* ... */
1023
+ },
1024
+ })
1025
+ ```
1026
+
1027
+ #### Batch Processing
1028
+
1029
+ Process large datasets in batches:
1030
+
1031
+ ```typescript
1032
+ async function insertLargeDataset(vectors: VectorObject[]) {
1033
+ const batchSize = 500
1034
+
1035
+ for (let i = 0; i < vectors.length; i += batchSize) {
1036
+ const batch = vectors.slice(i, i + batchSize)
1037
+ await index.putVectors({ vectors: batch })
1038
+ console.log(`Inserted ${i + batch.length}/${vectors.length}`)
1039
+ }
1040
+ }
1041
+ ```
1042
+
1043
+ #### Float32 Validation
1044
+
1045
+ Ensure vectors are properly normalized to float32:
1046
+
1047
+ ```typescript
1048
+ import { normalizeToFloat32 } from '@supabase/storage-js'
1049
+
1050
+ const vector = normalizeToFloat32([0.1, 0.2, 0.3 /* ... */])
1051
+ ```
1052
+
1053
+ ### Type Definitions
1054
+
1055
+ The library exports comprehensive TypeScript types:
1056
+
1057
+ ```typescript
1058
+ import type {
1059
+ VectorBucket,
1060
+ VectorIndex,
1061
+ VectorData,
1062
+ VectorObject,
1063
+ VectorMatch,
1064
+ VectorMetadata,
1065
+ DistanceMetric,
1066
+ ApiResponse,
1067
+ StorageVectorsError,
1068
+ } from '@supabase/storage-js'
1069
+ ```
1070
+
160
1071
  ## Development
161
1072
 
162
1073
  This package is part of the [Supabase JavaScript monorepo](https://github.com/supabase/supabase-js). To work on this package:
@@ -393,7 +1304,7 @@ The test infrastructure (`infra/docker-compose.yml`) includes:
393
1304
 
394
1305
  #### What About Supabase CLI?
395
1306
 
396
- **No**, you don't need `supabase start` or a regular Supabase instance for these tests. The storage-js tests use their own specialized Docker setup that's lighter and focused specifically on testing the storage client library. This test infrastructure:
1307
+ **No**, you don't need `supabase start` or a regular Supabase instance for these tests. The storage-js tests use their own specialized Docker setup that's lighter and focused specifically on testing the storage SDK. This test infrastructure:
397
1308
 
398
1309
  - Is completely independent from any Supabase CLI projects
399
1310
  - Uses fixed test authentication keys
@@ -405,10 +1316,4 @@ The test infrastructure (`infra/docker-compose.yml`) includes:
405
1316
 
406
1317
  We welcome contributions! Please see our [Contributing Guide](../../../CONTRIBUTING.md) for details on how to get started.
407
1318
 
408
- For major changes or if you're unsure about something, please open an issue first to discuss your proposed changes.
409
-
410
- ## Sponsors
411
-
412
- We are building the features of Firebase using enterprise-grade, open source products. We support existing communities wherever possible, and if the products don’t exist we build them and open source them ourselves. Thanks to these sponsors who are making the OSS ecosystem better for everyone.
413
-
414
- [![New Sponsor](https://user-images.githubusercontent.com/10214025/90518111-e74bbb00-e198-11ea-8f88-c9e3c1aa4b5b.png)](https://github.com/sponsors/supabase)
1319
+ For major changes or if you're unsure about something, please open an issue first to discuss your proposed changes.