@supabase/storage-js 2.88.1-canary.2 → 2.89.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["resolveFetch","resolveResponse","result: Record<string, any>","isPlainObject","_getErrorMessage","handleError","resolveResponse","_getRequestParams","params: { [k: string]: any }","isPlainObject","_handleRequest","post","downloadFn: () => Promise<Response>","shouldThrowOnError: boolean","this","downloadFn: () => Promise<Response>","shouldThrowOnError: boolean","this","DEFAULT_FILE_OPTIONS: FileOptions","resolveFetch","fetch","headers: Record<string, string>","this","post","_queryString: string[]","params: string[]","DEFAULT_HEADERS","DEFAULT_HEADERS","resolveFetch","fetch","this","post","params: Record<string, string>","DEFAULT_HEADERS","resolveFetch","fetch","post","this","IcebergRestCatalog","params: { [k: string]: any }","fetch","this","fetch","this","fetch","this","fetch","this","fetch"],"sources":["../src/lib/errors.ts","../src/lib/helpers.ts","../src/lib/fetch.ts","../src/packages/StreamDownloadBuilder.ts","../src/packages/BlobDownloadBuilder.ts","../src/packages/StorageFileApi.ts","../src/lib/version.ts","../src/lib/constants.ts","../src/packages/StorageBucketApi.ts","../src/packages/StorageAnalyticsClient.ts","../src/lib/vectors/constants.ts","../src/lib/vectors/errors.ts","../src/lib/vectors/helpers.ts","../src/lib/vectors/fetch.ts","../src/lib/vectors/VectorIndexApi.ts","../src/lib/vectors/VectorDataApi.ts","../src/lib/vectors/VectorBucketApi.ts","../src/lib/vectors/StorageVectorsClient.ts","../src/StorageClient.ts"],"sourcesContent":["export class StorageError extends Error {\n protected __isStorageError = true\n\n constructor(message: string) {\n super(message)\n this.name = 'StorageError'\n }\n}\n\nexport function isStorageError(error: unknown): error is StorageError {\n return typeof error === 'object' && error !== null && '__isStorageError' in error\n}\n\nexport class StorageApiError extends StorageError {\n status: number\n statusCode: string\n\n constructor(message: string, status: number, statusCode: string) {\n super(message)\n this.name = 'StorageApiError'\n this.status = status\n this.statusCode = statusCode\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n status: this.status,\n statusCode: this.statusCode,\n }\n }\n}\n\nexport class StorageUnknownError extends StorageError {\n originalError: unknown\n\n constructor(message: string, originalError: unknown) {\n super(message)\n this.name = 'StorageUnknownError'\n this.originalError = originalError\n }\n}\n","type Fetch = typeof fetch\n\nexport const resolveFetch = (customFetch?: Fetch): Fetch => {\n if (customFetch) {\n return (...args) => customFetch(...args)\n }\n return (...args) => fetch(...args)\n}\n\nexport const resolveResponse = (): typeof Response => {\n return Response\n}\n\nexport const recursiveToCamel = (item: Record<string, any>): unknown => {\n if (Array.isArray(item)) {\n return item.map((el) => recursiveToCamel(el))\n } else if (typeof item === 'function' || item !== Object(item)) {\n return item\n }\n\n const result: Record<string, any> = {}\n Object.entries(item).forEach(([key, value]) => {\n const newKey = key.replace(/([-_][a-z])/gi, (c) => c.toUpperCase().replace(/[-_]/g, ''))\n result[newKey] = recursiveToCamel(value)\n })\n\n return result\n}\n\n/**\n * Determine if input is a plain object\n * An object is plain if it's created by either {}, new Object(), or Object.create(null)\n * source: https://github.com/sindresorhus/is-plain-obj\n */\nexport const isPlainObject = (value: object): boolean => {\n if (typeof value !== 'object' || value === null) {\n return false\n }\n\n const prototype = Object.getPrototypeOf(value)\n return (\n (prototype === null ||\n prototype === Object.prototype ||\n Object.getPrototypeOf(prototype) === null) &&\n !(Symbol.toStringTag in value) &&\n !(Symbol.iterator in value)\n )\n}\n\n/**\n * Validates if a given bucket name is valid according to Supabase Storage API rules\n * Mirrors backend validation from: storage/src/storage/limits.ts:isValidBucketName()\n *\n * Rules:\n * - Length: 1-100 characters\n * - Allowed characters: alphanumeric (a-z, A-Z, 0-9), underscore (_), and safe special characters\n * - Safe special characters: ! - . * ' ( ) space & $ @ = ; : + , ?\n * - Forbidden: path separators (/, \\), path traversal (..), leading/trailing whitespace\n *\n * AWS S3 Reference: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html\n *\n * @param bucketName - The bucket name to validate\n * @returns true if valid, false otherwise\n */\nexport const isValidBucketName = (bucketName: string): boolean => {\n if (!bucketName || typeof bucketName !== 'string') {\n return false\n }\n\n // Check length constraints (1-100 characters)\n if (bucketName.length === 0 || bucketName.length > 100) {\n return false\n }\n\n // Check for leading/trailing whitespace\n if (bucketName.trim() !== bucketName) {\n return false\n }\n\n // Explicitly reject path separators (security)\n // Note: Consecutive periods (..) are allowed by backend - the AWS restriction\n // on relative paths applies to object keys, not bucket names\n if (bucketName.includes('/') || bucketName.includes('\\\\')) {\n return false\n }\n\n // Validate against allowed character set\n // Pattern matches backend regex: /^(\\w|!|-|\\.|\\*|'|\\(|\\)| |&|\\$|@|=|;|:|\\+|,|\\?)*$/\n // This explicitly excludes path separators (/, \\) and other problematic characters\n const bucketNameRegex = /^[\\w!.\\*'() &$@=;:+,?-]+$/\n return bucketNameRegex.test(bucketName)\n}\n","import { StorageApiError, StorageUnknownError } from './errors'\nimport { isPlainObject, resolveResponse } from './helpers'\nimport { FetchParameters } from './types'\n\nexport type Fetch = typeof fetch\n\nexport interface FetchOptions {\n headers?: {\n [key: string]: string\n }\n duplex?: string\n noResolveJson?: boolean\n}\n\nexport type RequestMethodType = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD'\n\nconst _getErrorMessage = (err: any): string =>\n err.msg ||\n err.message ||\n err.error_description ||\n (typeof err.error === 'string' ? err.error : err.error?.message) ||\n JSON.stringify(err)\n\nconst handleError = async (\n error: unknown,\n reject: (reason?: any) => void,\n options?: FetchOptions\n) => {\n const Res = await resolveResponse()\n\n if (error instanceof Res && !options?.noResolveJson) {\n error\n .json()\n .then((err) => {\n const status = error.status || 500\n const statusCode = err?.statusCode || status + ''\n reject(new StorageApiError(_getErrorMessage(err), status, statusCode))\n })\n .catch((err) => {\n reject(new StorageUnknownError(_getErrorMessage(err), err))\n })\n } else {\n reject(new StorageUnknownError(_getErrorMessage(error), error))\n }\n}\n\nconst _getRequestParams = (\n method: RequestMethodType,\n options?: FetchOptions,\n parameters?: FetchParameters,\n body?: object\n) => {\n const params: { [k: string]: any } = { method, headers: options?.headers || {} }\n\n if (method === 'GET' || !body) {\n return params\n }\n\n if (isPlainObject(body)) {\n params.headers = { 'Content-Type': 'application/json', ...options?.headers }\n params.body = JSON.stringify(body)\n } else {\n params.body = body\n }\n\n if (options?.duplex) {\n params.duplex = options.duplex\n }\n\n return { ...params, ...parameters }\n}\n\nasync function _handleRequest(\n fetcher: Fetch,\n method: RequestMethodType,\n url: string,\n options?: FetchOptions,\n parameters?: FetchParameters,\n body?: object\n): Promise<any> {\n return new Promise((resolve, reject) => {\n fetcher(url, _getRequestParams(method, options, parameters, body))\n .then((result) => {\n if (!result.ok) throw result\n if (options?.noResolveJson) return result\n return result.json()\n })\n .then((data) => resolve(data))\n .catch((error) => handleError(error, reject, options))\n })\n}\n\nexport async function get(\n fetcher: Fetch,\n url: string,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'GET', url, options, parameters)\n}\n\nexport async function post(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'POST', url, options, parameters, body)\n}\n\nexport async function put(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'PUT', url, options, parameters, body)\n}\n\nexport async function head(\n fetcher: Fetch,\n url: string,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(\n fetcher,\n 'HEAD',\n url,\n {\n ...options,\n noResolveJson: true,\n },\n parameters\n )\n}\n\nexport async function remove(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'DELETE', url, options, parameters, body)\n}\n","import { isStorageError } from '../lib/errors'\nimport { DownloadResult } from '../lib/types'\n\nexport default class StreamDownloadBuilder implements PromiseLike<DownloadResult<ReadableStream>> {\n constructor(\n private downloadFn: () => Promise<Response>,\n private shouldThrowOnError: boolean\n ) {}\n\n then<TResult1 = DownloadResult<ReadableStream>, TResult2 = never>(\n onfulfilled?:\n | ((value: DownloadResult<ReadableStream>) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null\n ): Promise<TResult1 | TResult2> {\n return this.execute().then(onfulfilled, onrejected)\n }\n\n private async execute(): Promise<DownloadResult<ReadableStream>> {\n try {\n const result = await this.downloadFn()\n\n return {\n data: result.body as ReadableStream,\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n}\n","import { isStorageError } from '../lib/errors'\nimport { DownloadResult } from '../lib/types'\nimport StreamDownloadBuilder from './StreamDownloadBuilder'\n\nexport default class BlobDownloadBuilder implements Promise<DownloadResult<Blob>> {\n readonly [Symbol.toStringTag]: string = 'BlobDownloadBuilder'\n private promise: Promise<DownloadResult<Blob>> | null = null\n\n constructor(\n private downloadFn: () => Promise<Response>,\n private shouldThrowOnError: boolean\n ) {}\n\n asStream(): StreamDownloadBuilder {\n return new StreamDownloadBuilder(this.downloadFn, this.shouldThrowOnError)\n }\n\n then<TResult1 = DownloadResult<Blob>, TResult2 = never>(\n onfulfilled?: ((value: DownloadResult<Blob>) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null\n ): Promise<TResult1 | TResult2> {\n return this.getPromise().then(onfulfilled, onrejected)\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null\n ): Promise<DownloadResult<Blob> | TResult> {\n return this.getPromise().catch(onrejected)\n }\n\n finally(onfinally?: (() => void) | null): Promise<DownloadResult<Blob>> {\n return this.getPromise().finally(onfinally)\n }\n\n private getPromise(): Promise<DownloadResult<Blob>> {\n if (!this.promise) {\n this.promise = this.execute()\n }\n return this.promise\n }\n\n private async execute(): Promise<DownloadResult<Blob>> {\n try {\n const result = await this.downloadFn()\n\n return {\n data: await result.blob(),\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n}\n","import { isStorageError, StorageError, StorageUnknownError } from '../lib/errors'\nimport { Fetch, get, head, post, put, remove } from '../lib/fetch'\nimport { recursiveToCamel, resolveFetch } from '../lib/helpers'\nimport {\n FileObject,\n FileOptions,\n SearchOptions,\n FetchParameters,\n TransformOptions,\n DestinationOptions,\n FileObjectV2,\n Camelize,\n SearchV2Options,\n SearchV2Result,\n} from '../lib/types'\nimport BlobDownloadBuilder from './BlobDownloadBuilder'\n\nconst DEFAULT_SEARCH_OPTIONS = {\n limit: 100,\n offset: 0,\n sortBy: {\n column: 'name',\n order: 'asc',\n },\n}\n\nconst DEFAULT_FILE_OPTIONS: FileOptions = {\n cacheControl: '3600',\n contentType: 'text/plain;charset=UTF-8',\n upsert: false,\n}\n\ntype FileBody =\n | ArrayBuffer\n | ArrayBufferView\n | Blob\n | Buffer\n | File\n | FormData\n | NodeJS.ReadableStream\n | ReadableStream<Uint8Array>\n | URLSearchParams\n | string\n\nexport default class StorageFileApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected bucketId?: string\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n constructor(\n url: string,\n headers: { [key: string]: string } = {},\n bucketId?: string,\n fetch?: Fetch\n ) {\n this.url = url\n this.headers = headers\n this.bucketId = bucketId\n this.fetch = resolveFetch(fetch)\n }\n\n /**\n * Enable throwing errors instead of returning them.\n *\n * @category File Buckets\n */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /**\n * Uploads a file to an existing bucket or replaces an existing file at the specified path with a new one.\n *\n * @param method HTTP method.\n * @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.\n * @param fileBody The body of the file to be stored in the bucket.\n */\n private async uploadOrUpdate(\n method: 'POST' | 'PUT',\n path: string,\n fileBody: FileBody,\n fileOptions?: FileOptions\n ): Promise<\n | {\n data: { id: string; path: string; fullPath: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n let body\n const options = { ...DEFAULT_FILE_OPTIONS, ...fileOptions }\n let headers: Record<string, string> = {\n ...this.headers,\n ...(method === 'POST' && { 'x-upsert': String(options.upsert as boolean) }),\n }\n\n const metadata = options.metadata\n\n if (typeof Blob !== 'undefined' && fileBody instanceof Blob) {\n body = new FormData()\n body.append('cacheControl', options.cacheControl as string)\n if (metadata) {\n body.append('metadata', this.encodeMetadata(metadata))\n }\n body.append('', fileBody)\n } else if (typeof FormData !== 'undefined' && fileBody instanceof FormData) {\n body = fileBody\n // Only append if not already present\n if (!body.has('cacheControl')) {\n body.append('cacheControl', options.cacheControl as string)\n }\n if (metadata && !body.has('metadata')) {\n body.append('metadata', this.encodeMetadata(metadata))\n }\n } else {\n body = fileBody\n headers['cache-control'] = `max-age=${options.cacheControl}`\n headers['content-type'] = options.contentType as string\n\n if (metadata) {\n headers['x-metadata'] = this.toBase64(this.encodeMetadata(metadata))\n }\n\n // Node.js streams require duplex option for fetch in Node 20+\n // Check for both web ReadableStream and Node.js streams\n const isStream =\n (typeof ReadableStream !== 'undefined' && body instanceof ReadableStream) ||\n (body && typeof body === 'object' && 'pipe' in body && typeof body.pipe === 'function')\n\n if (isStream && !options.duplex) {\n options.duplex = 'half'\n }\n }\n\n if (fileOptions?.headers) {\n headers = { ...headers, ...fileOptions.headers }\n }\n\n const cleanPath = this._removeEmptyFolders(path)\n const _path = this._getFinalPath(cleanPath)\n const data = await (method == 'PUT' ? put : post)(\n this.fetch,\n `${this.url}/object/${_path}`,\n body as object,\n { headers, ...(options?.duplex ? { duplex: options.duplex } : {}) }\n )\n\n return {\n data: { path: cleanPath, id: data.Id, fullPath: data.Key },\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Uploads a file to an existing bucket.\n *\n * @category File Buckets\n * @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.\n * @param fileBody The body of the file to be stored in the bucket.\n * @param fileOptions Optional file upload options including cacheControl, contentType, upsert, and metadata.\n * @returns Promise with response containing file path, id, and fullPath or error\n *\n * @example Upload file\n * ```js\n * const avatarFile = event.target.files[0]\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .upload('public/avatar1.png', avatarFile, {\n * cacheControl: '3600',\n * upsert: false\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"path\": \"public/avatar1.png\",\n * \"fullPath\": \"avatars/public/avatar1.png\"\n * },\n * \"error\": null\n * }\n * ```\n *\n * @example Upload file using `ArrayBuffer` from base64 file data\n * ```js\n * import { decode } from 'base64-arraybuffer'\n *\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .upload('public/avatar1.png', decode('base64FileData'), {\n * contentType: 'image/png'\n * })\n * ```\n */\n async upload(\n path: string,\n fileBody: FileBody,\n fileOptions?: FileOptions\n ): Promise<\n | {\n data: { id: string; path: string; fullPath: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n return this.uploadOrUpdate('POST', path, fileBody, fileOptions)\n }\n\n /**\n * Upload a file with a token generated from `createSignedUploadUrl`.\n *\n * @category File Buckets\n * @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.\n * @param token The token generated from `createSignedUploadUrl`\n * @param fileBody The body of the file to be stored in the bucket.\n * @param fileOptions HTTP headers (cacheControl, contentType, etc.).\n * **Note:** The `upsert` option has no effect here. To enable upsert behavior,\n * pass `{ upsert: true }` when calling `createSignedUploadUrl()` instead.\n * @returns Promise with response containing file path and fullPath or error\n *\n * @example Upload to a signed URL\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .uploadToSignedUrl('folder/cat.jpg', 'token-from-createSignedUploadUrl', file)\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"path\": \"folder/cat.jpg\",\n * \"fullPath\": \"avatars/folder/cat.jpg\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async uploadToSignedUrl(\n path: string,\n token: string,\n fileBody: FileBody,\n fileOptions?: FileOptions\n ) {\n const cleanPath = this._removeEmptyFolders(path)\n const _path = this._getFinalPath(cleanPath)\n\n const url = new URL(this.url + `/object/upload/sign/${_path}`)\n url.searchParams.set('token', token)\n\n try {\n let body\n const options = { upsert: DEFAULT_FILE_OPTIONS.upsert, ...fileOptions }\n const headers: Record<string, string> = {\n ...this.headers,\n ...{ 'x-upsert': String(options.upsert as boolean) },\n }\n\n if (typeof Blob !== 'undefined' && fileBody instanceof Blob) {\n body = new FormData()\n body.append('cacheControl', options.cacheControl as string)\n body.append('', fileBody)\n } else if (typeof FormData !== 'undefined' && fileBody instanceof FormData) {\n body = fileBody\n body.append('cacheControl', options.cacheControl as string)\n } else {\n body = fileBody\n headers['cache-control'] = `max-age=${options.cacheControl}`\n headers['content-type'] = options.contentType as string\n }\n\n const data = await put(this.fetch, url.toString(), body as object, { headers })\n\n return {\n data: { path: cleanPath, fullPath: data.Key },\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Creates a signed upload URL.\n * Signed upload URLs can be used to upload files to the bucket without further authentication.\n * They are valid for 2 hours.\n *\n * @category File Buckets\n * @param path The file path, including the current file name. For example `folder/image.png`.\n * @param options.upsert If set to true, allows the file to be overwritten if it already exists.\n * @returns Promise with response containing signed upload URL, token, and path or error\n *\n * @example Create Signed Upload URL\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUploadUrl('folder/cat.jpg')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"signedUrl\": \"https://example.supabase.co/storage/v1/object/upload/sign/avatars/folder/cat.jpg?token=<TOKEN>\",\n * \"path\": \"folder/cat.jpg\",\n * \"token\": \"<TOKEN>\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async createSignedUploadUrl(\n path: string,\n options?: { upsert: boolean }\n ): Promise<\n | {\n data: { signedUrl: string; token: string; path: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n let _path = this._getFinalPath(path)\n\n const headers = { ...this.headers }\n\n if (options?.upsert) {\n headers['x-upsert'] = 'true'\n }\n\n const data = await post(\n this.fetch,\n `${this.url}/object/upload/sign/${_path}`,\n {},\n { headers }\n )\n\n const url = new URL(this.url + data.url)\n\n const token = url.searchParams.get('token')\n\n if (!token) {\n throw new StorageError('No token returned by API')\n }\n\n return { data: { signedUrl: url.toString(), path, token }, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Replaces an existing file at the specified path with a new one.\n *\n * @category File Buckets\n * @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to update.\n * @param fileBody The body of the file to be stored in the bucket.\n * @param fileOptions Optional file upload options including cacheControl, contentType, upsert, and metadata.\n * @returns Promise with response containing file path, id, and fullPath or error\n *\n * @example Update file\n * ```js\n * const avatarFile = event.target.files[0]\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .update('public/avatar1.png', avatarFile, {\n * cacheControl: '3600',\n * upsert: true\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"path\": \"public/avatar1.png\",\n * \"fullPath\": \"avatars/public/avatar1.png\"\n * },\n * \"error\": null\n * }\n * ```\n *\n * @example Update file using `ArrayBuffer` from base64 file data\n * ```js\n * import {decode} from 'base64-arraybuffer'\n *\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .update('public/avatar1.png', decode('base64FileData'), {\n * contentType: 'image/png'\n * })\n * ```\n */\n async update(\n path: string,\n fileBody:\n | ArrayBuffer\n | ArrayBufferView\n | Blob\n | Buffer\n | File\n | FormData\n | NodeJS.ReadableStream\n | ReadableStream<Uint8Array>\n | URLSearchParams\n | string,\n fileOptions?: FileOptions\n ): Promise<\n | {\n data: { id: string; path: string; fullPath: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n return this.uploadOrUpdate('PUT', path, fileBody, fileOptions)\n }\n\n /**\n * Moves an existing file to a new path in the same bucket.\n *\n * @category File Buckets\n * @param fromPath The original file path, including the current file name. For example `folder/image.png`.\n * @param toPath The new file path, including the new file name. For example `folder/image-new.png`.\n * @param options The destination options.\n * @returns Promise with response containing success message or error\n *\n * @example Move file\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .move('public/avatar1.png', 'private/avatar2.png')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully moved\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async move(\n fromPath: string,\n toPath: string,\n options?: DestinationOptions\n ): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/object/move`,\n {\n bucketId: this.bucketId,\n sourceKey: fromPath,\n destinationKey: toPath,\n destinationBucket: options?.destinationBucket,\n },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Copies an existing file to a new path in the same bucket.\n *\n * @category File Buckets\n * @param fromPath The original file path, including the current file name. For example `folder/image.png`.\n * @param toPath The new file path, including the new file name. For example `folder/image-copy.png`.\n * @param options The destination options.\n * @returns Promise with response containing copied file path or error\n *\n * @example Copy file\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .copy('public/avatar1.png', 'private/avatar2.png')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"path\": \"avatars/private/avatar2.png\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async copy(\n fromPath: string,\n toPath: string,\n options?: DestinationOptions\n ): Promise<\n | {\n data: { path: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/object/copy`,\n {\n bucketId: this.bucketId,\n sourceKey: fromPath,\n destinationKey: toPath,\n destinationBucket: options?.destinationBucket,\n },\n { headers: this.headers }\n )\n return { data: { path: data.Key }, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Creates a signed URL. Use a signed URL to share a file for a fixed amount of time.\n *\n * @category File Buckets\n * @param path The file path, including the current file name. For example `folder/image.png`.\n * @param expiresIn The number of seconds until the signed URL expires. For example, `60` for a URL which is valid for one minute.\n * @param options.download triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename.\n * @param options.transform Transform the asset before serving it to the client.\n * @returns Promise with response containing signed URL or error\n *\n * @example Create Signed URL\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUrl('folder/avatar1.png', 60)\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"signedUrl\": \"https://example.supabase.co/storage/v1/object/sign/avatars/folder/avatar1.png?token=<TOKEN>\"\n * },\n * \"error\": null\n * }\n * ```\n *\n * @example Create a signed URL for an asset with transformations\n * ```js\n * const { data } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUrl('folder/avatar1.png', 60, {\n * transform: {\n * width: 100,\n * height: 100,\n * }\n * })\n * ```\n *\n * @example Create a signed URL which triggers the download of the asset\n * ```js\n * const { data } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUrl('folder/avatar1.png', 60, {\n * download: true,\n * })\n * ```\n */\n async createSignedUrl(\n path: string,\n expiresIn: number,\n options?: { download?: string | boolean; transform?: TransformOptions }\n ): Promise<\n | {\n data: { signedUrl: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n let _path = this._getFinalPath(path)\n\n let data = await post(\n this.fetch,\n `${this.url}/object/sign/${_path}`,\n { expiresIn, ...(options?.transform ? { transform: options.transform } : {}) },\n { headers: this.headers }\n )\n const downloadQueryParam = options?.download\n ? `&download=${options.download === true ? '' : options.download}`\n : ''\n const signedUrl = encodeURI(`${this.url}${data.signedURL}${downloadQueryParam}`)\n data = { signedUrl }\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Creates multiple signed URLs. Use a signed URL to share a file for a fixed amount of time.\n *\n * @category File Buckets\n * @param paths The file paths to be downloaded, including the current file names. For example `['folder/image.png', 'folder2/image2.png']`.\n * @param expiresIn The number of seconds until the signed URLs expire. For example, `60` for URLs which are valid for one minute.\n * @param options.download triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename.\n * @returns Promise with response containing array of objects with signedUrl, path, and error or error\n *\n * @example Create Signed URLs\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUrls(['folder/avatar1.png', 'folder/avatar2.png'], 60)\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": [\n * {\n * \"error\": null,\n * \"path\": \"folder/avatar1.png\",\n * \"signedURL\": \"/object/sign/avatars/folder/avatar1.png?token=<TOKEN>\",\n * \"signedUrl\": \"https://example.supabase.co/storage/v1/object/sign/avatars/folder/avatar1.png?token=<TOKEN>\"\n * },\n * {\n * \"error\": null,\n * \"path\": \"folder/avatar2.png\",\n * \"signedURL\": \"/object/sign/avatars/folder/avatar2.png?token=<TOKEN>\",\n * \"signedUrl\": \"https://example.supabase.co/storage/v1/object/sign/avatars/folder/avatar2.png?token=<TOKEN>\"\n * }\n * ],\n * \"error\": null\n * }\n * ```\n */\n async createSignedUrls(\n paths: string[],\n expiresIn: number,\n options?: { download: string | boolean }\n ): Promise<\n | {\n data: { error: string | null; path: string | null; signedUrl: string }[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/object/sign/${this.bucketId}`,\n { expiresIn, paths },\n { headers: this.headers }\n )\n\n const downloadQueryParam = options?.download\n ? `&download=${options.download === true ? '' : options.download}`\n : ''\n return {\n data: data.map((datum: { signedURL: string }) => ({\n ...datum,\n signedUrl: datum.signedURL\n ? encodeURI(`${this.url}${datum.signedURL}${downloadQueryParam}`)\n : null,\n })),\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Downloads a file from a private bucket. For public buckets, make a request to the URL returned from `getPublicUrl` instead.\n *\n * @category File Buckets\n * @param path The full path and file name of the file to be downloaded. For example `folder/image.png`.\n * @param options.transform Transform the asset before serving it to the client.\n * @returns BlobDownloadBuilder instance for downloading the file\n *\n * @example Download file\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .download('folder/avatar1.png')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": <BLOB>,\n * \"error\": null\n * }\n * ```\n *\n * @example Download file with transformations\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .download('folder/avatar1.png', {\n * transform: {\n * width: 100,\n * height: 100,\n * quality: 80\n * }\n * })\n * ```\n */\n download<Options extends { transform?: TransformOptions }>(\n path: string,\n options?: Options\n ): BlobDownloadBuilder {\n const wantsTransformation = typeof options?.transform !== 'undefined'\n const renderPath = wantsTransformation ? 'render/image/authenticated' : 'object'\n const transformationQuery = this.transformOptsToQueryString(options?.transform || {})\n const queryString = transformationQuery ? `?${transformationQuery}` : ''\n const _path = this._getFinalPath(path)\n const downloadFn = () =>\n get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString}`, {\n headers: this.headers,\n noResolveJson: true,\n })\n return new BlobDownloadBuilder(downloadFn, this.shouldThrowOnError)\n }\n\n /**\n * Retrieves the details of an existing file.\n *\n * @category File Buckets\n * @param path The file path, including the file name. For example `folder/image.png`.\n * @returns Promise with response containing file metadata or error\n *\n * @example Get file info\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .info('folder/avatar1.png')\n * ```\n */\n async info(path: string): Promise<\n | {\n data: Camelize<FileObjectV2>\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n const _path = this._getFinalPath(path)\n\n try {\n const data = await get(this.fetch, `${this.url}/object/info/${_path}`, {\n headers: this.headers,\n })\n\n return { data: recursiveToCamel(data) as Camelize<FileObjectV2>, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Checks the existence of a file.\n *\n * @category File Buckets\n * @param path The file path, including the file name. For example `folder/image.png`.\n * @returns Promise with response containing boolean indicating file existence or error\n *\n * @example Check file existence\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .exists('folder/avatar1.png')\n * ```\n */\n async exists(path: string): Promise<\n | {\n data: boolean\n error: null\n }\n | {\n data: boolean\n error: StorageError\n }\n > {\n const _path = this._getFinalPath(path)\n\n try {\n await head(this.fetch, `${this.url}/object/${_path}`, {\n headers: this.headers,\n })\n\n return { data: true, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error) && error instanceof StorageUnknownError) {\n const originalError = error.originalError as unknown as { status: number }\n\n if ([400, 404].includes(originalError?.status)) {\n return { data: false, error }\n }\n }\n\n throw error\n }\n }\n\n /**\n * A simple convenience function 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.\n * This function does not verify if the bucket is public. If a public URL is created for a bucket which is not public, you will not be able to download the asset.\n *\n * @category File Buckets\n * @param path The path and name of the file to generate the public URL for. For example `folder/image.png`.\n * @param options.download Triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename.\n * @param options.transform Transform the asset before serving it to the client.\n * @returns Object with public URL\n *\n * @example Returns the URL for an asset in a public bucket\n * ```js\n * const { data } = supabase\n * .storage\n * .from('public-bucket')\n * .getPublicUrl('folder/avatar1.png')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"publicUrl\": \"https://example.supabase.co/storage/v1/object/public/public-bucket/folder/avatar1.png\"\n * }\n * }\n * ```\n *\n * @example Returns the URL for an asset in a public bucket with transformations\n * ```js\n * const { data } = supabase\n * .storage\n * .from('public-bucket')\n * .getPublicUrl('folder/avatar1.png', {\n * transform: {\n * width: 100,\n * height: 100,\n * }\n * })\n * ```\n *\n * @example Returns the URL which triggers the download of an asset in a public bucket\n * ```js\n * const { data } = supabase\n * .storage\n * .from('public-bucket')\n * .getPublicUrl('folder/avatar1.png', {\n * download: true,\n * })\n * ```\n */\n getPublicUrl(\n path: string,\n options?: { download?: string | boolean; transform?: TransformOptions }\n ): { data: { publicUrl: string } } {\n const _path = this._getFinalPath(path)\n const _queryString: string[] = []\n\n const downloadQueryParam = options?.download\n ? `download=${options.download === true ? '' : options.download}`\n : ''\n\n if (downloadQueryParam !== '') {\n _queryString.push(downloadQueryParam)\n }\n\n const wantsTransformation = typeof options?.transform !== 'undefined'\n const renderPath = wantsTransformation ? 'render/image' : 'object'\n const transformationQuery = this.transformOptsToQueryString(options?.transform || {})\n\n if (transformationQuery !== '') {\n _queryString.push(transformationQuery)\n }\n\n let queryString = _queryString.join('&')\n if (queryString !== '') {\n queryString = `?${queryString}`\n }\n\n return {\n data: { publicUrl: encodeURI(`${this.url}/${renderPath}/public/${_path}${queryString}`) },\n }\n }\n\n /**\n * Deletes files within the same bucket\n *\n * @category File Buckets\n * @param paths An array of files to delete, including the path and file name. For example [`'folder/image.png'`].\n * @returns Promise with response containing array of deleted file objects or error\n *\n * @example Delete file\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .remove(['folder/avatar1.png'])\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": [],\n * \"error\": null\n * }\n * ```\n */\n async remove(paths: string[]): Promise<\n | {\n data: FileObject[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await remove(\n this.fetch,\n `${this.url}/object/${this.bucketId}`,\n { prefixes: paths },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Get file metadata\n * @param id the file id to retrieve metadata\n */\n // async getMetadata(\n // id: string\n // ): Promise<\n // | {\n // data: Metadata\n // error: null\n // }\n // | {\n // data: null\n // error: StorageError\n // }\n // > {\n // try {\n // const data = await get(this.fetch, `${this.url}/metadata/${id}`, { headers: this.headers })\n // return { data, error: null }\n // } catch (error) {\n // if (isStorageError(error)) {\n // return { data: null, error }\n // }\n\n // throw error\n // }\n // }\n\n /**\n * Update file metadata\n * @param id the file id to update metadata\n * @param meta the new file metadata\n */\n // async updateMetadata(\n // id: string,\n // meta: Metadata\n // ): Promise<\n // | {\n // data: Metadata\n // error: null\n // }\n // | {\n // data: null\n // error: StorageError\n // }\n // > {\n // try {\n // const data = await post(\n // this.fetch,\n // `${this.url}/metadata/${id}`,\n // { ...meta },\n // { headers: this.headers }\n // )\n // return { data, error: null }\n // } catch (error) {\n // if (isStorageError(error)) {\n // return { data: null, error }\n // }\n\n // throw error\n // }\n // }\n\n /**\n * Lists all the files and folders within a path of the bucket.\n *\n * @category File Buckets\n * @param path The folder path.\n * @param options Search options including limit (defaults to 100), offset, sortBy, and search\n * @param parameters Optional fetch parameters including signal for cancellation\n * @returns Promise with response containing array of files or error\n *\n * @example List files in a bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .list('folder', {\n * limit: 100,\n * offset: 0,\n * sortBy: { column: 'name', order: 'asc' },\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": [\n * {\n * \"name\": \"avatar1.png\",\n * \"id\": \"e668cf7f-821b-4a2f-9dce-7dfa5dd1cfd2\",\n * \"updated_at\": \"2024-05-22T23:06:05.580Z\",\n * \"created_at\": \"2024-05-22T23:04:34.443Z\",\n * \"last_accessed_at\": \"2024-05-22T23:04:34.443Z\",\n * \"metadata\": {\n * \"eTag\": \"\\\"c5e8c553235d9af30ef4f6e280790b92\\\"\",\n * \"size\": 32175,\n * \"mimetype\": \"image/png\",\n * \"cacheControl\": \"max-age=3600\",\n * \"lastModified\": \"2024-05-22T23:06:05.574Z\",\n * \"contentLength\": 32175,\n * \"httpStatusCode\": 200\n * }\n * }\n * ],\n * \"error\": null\n * }\n * ```\n *\n * @example Search files in a bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .list('folder', {\n * limit: 100,\n * offset: 0,\n * sortBy: { column: 'name', order: 'asc' },\n * search: 'jon'\n * })\n * ```\n */\n async list(\n path?: string,\n options?: SearchOptions,\n parameters?: FetchParameters\n ): Promise<\n | {\n data: FileObject[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const body = { ...DEFAULT_SEARCH_OPTIONS, ...options, prefix: path || '' }\n const data = await post(\n this.fetch,\n `${this.url}/object/list/${this.bucketId}`,\n body,\n { headers: this.headers },\n parameters\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * @experimental this method signature might change in the future\n *\n * @category File Buckets\n * @param options search options\n * @param parameters\n */\n async listV2(\n options?: SearchV2Options,\n parameters?: FetchParameters\n ): Promise<\n | {\n data: SearchV2Result\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const body = { ...options }\n const data = await post(\n this.fetch,\n `${this.url}/object/list-v2/${this.bucketId}`,\n body,\n { headers: this.headers },\n parameters\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n protected encodeMetadata(metadata: Record<string, any>) {\n return JSON.stringify(metadata)\n }\n\n toBase64(data: string) {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(data).toString('base64')\n }\n return btoa(data)\n }\n\n private _getFinalPath(path: string) {\n return `${this.bucketId}/${path.replace(/^\\/+/, '')}`\n }\n\n private _removeEmptyFolders(path: string) {\n return path.replace(/^\\/|\\/$/g, '').replace(/\\/+/g, '/')\n }\n\n private transformOptsToQueryString(transform: TransformOptions) {\n const params: string[] = []\n if (transform.width) {\n params.push(`width=${transform.width}`)\n }\n\n if (transform.height) {\n params.push(`height=${transform.height}`)\n }\n\n if (transform.resize) {\n params.push(`resize=${transform.resize}`)\n }\n\n if (transform.format) {\n params.push(`format=${transform.format}`)\n }\n\n if (transform.quality) {\n params.push(`quality=${transform.quality}`)\n }\n\n return params.join('&')\n }\n}\n","// Generated automatically during releases by scripts/update-version-files.ts\n// This file provides runtime access to the package version for:\n// - HTTP request headers (e.g., X-Client-Info header for API requests)\n// - Debugging and support (identifying which version is running)\n// - Telemetry and logging (version reporting in errors/analytics)\n// - Ensuring build artifacts match the published package version\nexport const version = '2.88.1-canary.2'\n","import { version } from './version'\nexport const DEFAULT_HEADERS = {\n 'X-Client-Info': `storage-js/${version}`,\n}\n","import { DEFAULT_HEADERS } from '../lib/constants'\nimport { isStorageError, StorageError } from '../lib/errors'\nimport { Fetch, get, post, put, remove } from '../lib/fetch'\nimport { resolveFetch } from '../lib/helpers'\nimport { Bucket, BucketType, ListBucketOptions } from '../lib/types'\nimport { StorageClientOptions } from '../StorageClient'\n\nexport default class StorageBucketApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n constructor(\n url: string,\n headers: { [key: string]: string } = {},\n fetch?: Fetch,\n opts?: StorageClientOptions\n ) {\n const baseUrl = new URL(url)\n\n // if legacy uri is used, replace with new storage host (disables request buffering to allow > 50GB uploads)\n // \"project-ref.supabase.co\" becomes \"project-ref.storage.supabase.co\"\n if (opts?.useNewHostname) {\n const isSupabaseHost = /supabase\\.(co|in|red)$/.test(baseUrl.hostname)\n if (isSupabaseHost && !baseUrl.hostname.includes('storage.supabase.')) {\n baseUrl.hostname = baseUrl.hostname.replace('supabase.', 'storage.supabase.')\n }\n }\n\n this.url = baseUrl.href.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /**\n * Enable throwing errors instead of returning them.\n *\n * @category File Buckets\n */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /**\n * Retrieves the details of all Storage buckets within an existing project.\n *\n * @category File Buckets\n * @param options Query parameters for listing buckets\n * @param options.limit Maximum number of buckets to return\n * @param options.offset Number of buckets to skip\n * @param options.sortColumn Column to sort by ('id', 'name', 'created_at', 'updated_at')\n * @param options.sortOrder Sort order ('asc' or 'desc')\n * @param options.search Search term to filter bucket names\n * @returns Promise with response containing array of buckets or error\n *\n * @example List buckets\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .listBuckets()\n * ```\n *\n * @example List buckets with options\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .listBuckets({\n * limit: 10,\n * offset: 0,\n * sortColumn: 'created_at',\n * sortOrder: 'desc',\n * search: 'prod'\n * })\n * ```\n */\n async listBuckets(options?: ListBucketOptions): Promise<\n | {\n data: Bucket[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const queryString = this.listBucketOptionsToQueryString(options)\n const data = await get(this.fetch, `${this.url}/bucket${queryString}`, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Retrieves the details of an existing Storage bucket.\n *\n * @category File Buckets\n * @param id The unique identifier of the bucket you would like to retrieve.\n * @returns Promise with response containing bucket details or error\n *\n * @example Get bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .getBucket('avatars')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"id\": \"avatars\",\n * \"name\": \"avatars\",\n * \"owner\": \"\",\n * \"public\": false,\n * \"file_size_limit\": 1024,\n * \"allowed_mime_types\": [\n * \"image/png\"\n * ],\n * \"created_at\": \"2024-05-22T22:26:05.100Z\",\n * \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async getBucket(id: string): Promise<\n | {\n data: Bucket\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await get(this.fetch, `${this.url}/bucket/${id}`, { headers: this.headers })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Creates a new Storage bucket\n *\n * @category File Buckets\n * @param id A unique identifier for the bucket you are creating.\n * @param 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.\n * @param options.fileSizeLimit specifies the max file size in bytes that can be uploaded to this bucket.\n * The global file size limit takes precedence over this value.\n * The default value is null, which doesn't set a per bucket file size limit.\n * @param options.allowedMimeTypes specifies the allowed mime types that this bucket can accept during upload.\n * The default value is null, which allows files with all mime types to be uploaded.\n * Each mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png.\n * @param options.type (private-beta) specifies the bucket type. see `BucketType` for more details.\n * - default bucket type is `STANDARD`\n * @returns Promise with response containing newly created bucket name or error\n *\n * @example Create bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .createBucket('avatars', {\n * public: false,\n * allowedMimeTypes: ['image/png'],\n * fileSizeLimit: 1024\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"name\": \"avatars\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async createBucket(\n id: string,\n options: {\n public: boolean\n fileSizeLimit?: number | string | null\n allowedMimeTypes?: string[] | null\n type?: BucketType\n } = {\n public: false,\n }\n ): Promise<\n | {\n data: Pick<Bucket, 'name'>\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/bucket`,\n {\n id,\n name: id,\n type: options.type,\n public: options.public,\n file_size_limit: options.fileSizeLimit,\n allowed_mime_types: options.allowedMimeTypes,\n },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Updates a Storage bucket\n *\n * @category File Buckets\n * @param id A unique identifier for the bucket you are updating.\n * @param 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.\n * @param options.fileSizeLimit specifies the max file size in bytes that can be uploaded to this bucket.\n * The global file size limit takes precedence over this value.\n * The default value is null, which doesn't set a per bucket file size limit.\n * @param options.allowedMimeTypes specifies the allowed mime types that this bucket can accept during upload.\n * The default value is null, which allows files with all mime types to be uploaded.\n * Each mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png.\n * @returns Promise with response containing success message or error\n *\n * @example Update bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .updateBucket('avatars', {\n * public: false,\n * allowedMimeTypes: ['image/png'],\n * fileSizeLimit: 1024\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully updated\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async updateBucket(\n id: string,\n options: {\n public: boolean\n fileSizeLimit?: number | string | null\n allowedMimeTypes?: string[] | null\n }\n ): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await put(\n this.fetch,\n `${this.url}/bucket/${id}`,\n {\n id,\n name: id,\n public: options.public,\n file_size_limit: options.fileSizeLimit,\n allowed_mime_types: options.allowedMimeTypes,\n },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Removes all objects inside a single bucket.\n *\n * @category File Buckets\n * @param id The unique identifier of the bucket you would like to empty.\n * @returns Promise with success message or error\n *\n * @example Empty bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .emptyBucket('avatars')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully emptied\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async emptyBucket(id: string): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/bucket/${id}/empty`,\n {},\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Deletes an existing bucket. A bucket can't be deleted with existing objects inside it.\n * You must first `empty()` the bucket.\n *\n * @category File Buckets\n * @param id The unique identifier of the bucket you would like to delete.\n * @returns Promise with success message or error\n *\n * @example Delete bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .deleteBucket('avatars')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully deleted\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async deleteBucket(id: string): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await remove(\n this.fetch,\n `${this.url}/bucket/${id}`,\n {},\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n private listBucketOptionsToQueryString(options?: ListBucketOptions): string {\n const params: Record<string, string> = {}\n if (options) {\n if ('limit' in options) {\n params.limit = String(options.limit)\n }\n if ('offset' in options) {\n params.offset = String(options.offset)\n }\n if (options.search) {\n params.search = options.search\n }\n if (options.sortColumn) {\n params.sortColumn = options.sortColumn\n }\n if (options.sortOrder) {\n params.sortOrder = options.sortOrder\n }\n }\n return Object.keys(params).length > 0 ? '?' + new URLSearchParams(params).toString() : ''\n }\n}\n","import { IcebergRestCatalog, IcebergError } from 'iceberg-js'\nimport { DEFAULT_HEADERS } from '../lib/constants'\nimport { isStorageError, StorageError } from '../lib/errors'\nimport { Fetch, get, post, remove } from '../lib/fetch'\nimport { isValidBucketName, resolveFetch } from '../lib/helpers'\nimport { AnalyticBucket } from '../lib/types'\n\ntype WrapAsyncMethod<T> = T extends (...args: infer A) => Promise<infer R>\n ? (...args: A) => Promise<{ data: R; error: null } | { data: null; error: IcebergError }>\n : T\n\nexport type WrappedIcebergRestCatalog = {\n [K in keyof IcebergRestCatalog]: WrapAsyncMethod<IcebergRestCatalog[K]>\n}\n\n/**\n * Client class for managing Analytics Buckets using Iceberg tables\n * Provides methods for creating, listing, and deleting analytics buckets\n */\nexport default class StorageAnalyticsClient {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n /**\n * @alpha\n *\n * Creates a new StorageAnalyticsClient instance\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param url - The base URL for the storage API\n * @param headers - HTTP headers to include in requests\n * @param fetch - Optional custom fetch implementation\n *\n * @example\n * ```typescript\n * const client = new StorageAnalyticsClient(url, headers)\n * ```\n */\n constructor(url: string, headers: { [key: string]: string } = {}, fetch?: Fetch) {\n this.url = url.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /**\n * @alpha\n *\n * Enable throwing errors instead of returning them in the response\n * When enabled, failed operations will throw instead of returning { data: null, error }\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @returns This instance for method chaining\n */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /**\n * @alpha\n *\n * Creates a new analytics bucket using Iceberg tables\n * Analytics buckets are optimized for analytical queries and data processing\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param name A unique name for the bucket you are creating\n * @returns Promise with response containing newly created analytics bucket or error\n *\n * @example Create analytics bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .analytics\n * .createBucket('analytics-data')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"name\": \"analytics-data\",\n * \"type\": \"ANALYTICS\",\n * \"format\": \"iceberg\",\n * \"created_at\": \"2024-05-22T22:26:05.100Z\",\n * \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async createBucket(name: string): Promise<\n | {\n data: AnalyticBucket\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(this.fetch, `${this.url}/bucket`, { name }, { headers: this.headers })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * @alpha\n *\n * Retrieves the details of all Analytics Storage buckets within an existing project\n * Only returns buckets of type 'ANALYTICS'\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param options Query parameters for listing buckets\n * @param options.limit Maximum number of buckets to return\n * @param options.offset Number of buckets to skip\n * @param options.sortColumn Column to sort by ('name', 'created_at', 'updated_at')\n * @param options.sortOrder Sort order ('asc' or 'desc')\n * @param options.search Search term to filter bucket names\n * @returns Promise with response containing array of analytics buckets or error\n *\n * @example List analytics buckets\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .analytics\n * .listBuckets({\n * limit: 10,\n * offset: 0,\n * sortColumn: 'created_at',\n * sortOrder: 'desc'\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": [\n * {\n * \"name\": \"analytics-data\",\n * \"type\": \"ANALYTICS\",\n * \"format\": \"iceberg\",\n * \"created_at\": \"2024-05-22T22:26:05.100Z\",\n * \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n * }\n * ],\n * \"error\": null\n * }\n * ```\n */\n async listBuckets(options?: {\n limit?: number\n offset?: number\n sortColumn?: 'name' | 'created_at' | 'updated_at'\n sortOrder?: 'asc' | 'desc'\n search?: string\n }): Promise<\n | {\n data: AnalyticBucket[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n // Build query string from options\n const queryParams = new URLSearchParams()\n if (options?.limit !== undefined) queryParams.set('limit', options.limit.toString())\n if (options?.offset !== undefined) queryParams.set('offset', options.offset.toString())\n if (options?.sortColumn) queryParams.set('sortColumn', options.sortColumn)\n if (options?.sortOrder) queryParams.set('sortOrder', options.sortOrder)\n if (options?.search) queryParams.set('search', options.search)\n\n const queryString = queryParams.toString()\n const url = queryString ? `${this.url}/bucket?${queryString}` : `${this.url}/bucket`\n\n const data = await get(this.fetch, url, { headers: this.headers })\n\n return { data: data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * @alpha\n *\n * Deletes an existing analytics bucket\n * A bucket can't be deleted with existing objects inside it\n * You must first empty the bucket before deletion\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param bucketName The unique identifier of the bucket you would like to delete\n * @returns Promise with response containing success message or error\n *\n * @example Delete analytics bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .analytics\n * .deleteBucket('analytics-data')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully deleted\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async deleteBucket(bucketName: string): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await remove(\n this.fetch,\n `${this.url}/bucket/${bucketName}`,\n {},\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * @alpha\n *\n * Get an Iceberg REST Catalog client configured for a specific analytics bucket\n * Use this to perform advanced table and namespace operations within the bucket\n * The returned client provides full access to the Apache Iceberg REST Catalog API\n * with the Supabase `{ data, error }` pattern for consistent error handling on all operations.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param bucketName - The name of the analytics bucket (warehouse) to connect to\n * @returns The wrapped Iceberg catalog client\n * @throws {StorageError} If the bucket name is invalid\n *\n * @example Get catalog and create table\n * ```js\n * // First, create an analytics bucket\n * const { data: bucket, error: bucketError } = await supabase\n * .storage\n * .analytics\n * .createBucket('analytics-data')\n *\n * // Get the Iceberg catalog for that bucket\n * const catalog = supabase.storage.analytics.from('analytics-data')\n *\n * // Create a namespace\n * const { error: nsError } = await catalog.createNamespace({ namespace: ['default'] })\n *\n * // Create a table with schema\n * const { data: tableMetadata, error: tableError } = await catalog.createTable(\n * { namespace: ['default'] },\n * {\n * name: 'events',\n * schema: {\n * type: 'struct',\n * fields: [\n * { id: 1, name: 'id', type: 'long', required: true },\n * { id: 2, name: 'timestamp', type: 'timestamp', required: true },\n * { id: 3, name: 'user_id', type: 'string', required: false }\n * ],\n * 'schema-id': 0,\n * 'identifier-field-ids': [1]\n * },\n * 'partition-spec': {\n * 'spec-id': 0,\n * fields: []\n * },\n * 'write-order': {\n * 'order-id': 0,\n * fields: []\n * },\n * properties: {\n * 'write.format.default': 'parquet'\n * }\n * }\n * )\n * ```\n *\n * @example List tables in namespace\n * ```js\n * const catalog = supabase.storage.analytics.from('analytics-data')\n *\n * // List all tables in the default namespace\n * const { data: tables, error: listError } = await catalog.listTables({ namespace: ['default'] })\n * if (listError) {\n * if (listError.isNotFound()) {\n * console.log('Namespace not found')\n * }\n * return\n * }\n * console.log(tables) // [{ namespace: ['default'], name: 'events' }]\n * ```\n *\n * @example Working with namespaces\n * ```js\n * const catalog = supabase.storage.analytics.from('analytics-data')\n *\n * // List all namespaces\n * const { data: namespaces } = await catalog.listNamespaces()\n *\n * // Create namespace with properties\n * await catalog.createNamespace(\n * { namespace: ['production'] },\n * { properties: { owner: 'data-team', env: 'prod' } }\n * )\n * ```\n *\n * @example Cleanup operations\n * ```js\n * const catalog = supabase.storage.analytics.from('analytics-data')\n *\n * // Drop table with purge option (removes all data)\n * const { error: dropError } = await catalog.dropTable(\n * { namespace: ['default'], name: 'events' },\n * { purge: true }\n * )\n *\n * if (dropError?.isNotFound()) {\n * console.log('Table does not exist')\n * }\n *\n * // Drop namespace (must be empty)\n * await catalog.dropNamespace({ namespace: ['default'] })\n * ```\n *\n * @remarks\n * This method provides a bridge between Supabase's bucket management and the standard\n * Apache Iceberg REST Catalog API. The bucket name maps to the Iceberg warehouse parameter.\n * All authentication and configuration is handled automatically using your Supabase credentials.\n *\n * **Error Handling**: Invalid bucket names throw immediately. All catalog\n * operations return `{ data, error }` where errors are `IcebergError` instances from iceberg-js.\n * Use helper methods like `error.isNotFound()` or check `error.status` for specific error handling.\n * Use `.throwOnError()` on the analytics client if you prefer exceptions for catalog operations.\n *\n * **Cleanup Operations**: When using `dropTable`, the `purge: true` option permanently\n * deletes all table data. Without it, the table is marked as deleted but data remains.\n *\n * **Library Dependency**: The returned catalog wraps `IcebergRestCatalog` from iceberg-js.\n * For complete API documentation and advanced usage, refer to the\n * [iceberg-js documentation](https://supabase.github.io/iceberg-js/).\n */\n from(bucketName: string): WrappedIcebergRestCatalog {\n // Validate bucket name using same rules as Supabase Storage API backend\n if (!isValidBucketName(bucketName)) {\n throw new StorageError(\n 'Invalid bucket name: File, folder, and bucket names must follow AWS object key naming guidelines ' +\n 'and should avoid the use of any other characters.'\n )\n }\n\n // Construct the Iceberg REST Catalog URL\n // The base URL is /storage/v1/iceberg\n // Note: IcebergRestCatalog from iceberg-js automatically adds /v1/ prefix to API paths\n // so we should NOT append /v1 here (it would cause double /v1/v1/ in the URL)\n const catalog = new IcebergRestCatalog({\n baseUrl: this.url,\n catalogName: bucketName, // Maps to the warehouse parameter in Supabase's implementation\n auth: {\n type: 'custom',\n getHeaders: async () => this.headers,\n },\n fetch: this.fetch,\n })\n\n const shouldThrowOnError = this.shouldThrowOnError\n\n const wrappedCatalog = new Proxy(catalog, {\n get(target, prop: keyof IcebergRestCatalog) {\n const value = target[prop]\n if (typeof value !== 'function') {\n return value\n }\n\n return async (...args: unknown[]) => {\n try {\n const data = await (value as Function).apply(target, args)\n return { data, error: null }\n } catch (error) {\n if (shouldThrowOnError) {\n throw error\n }\n return { data: null, error: error as IcebergError }\n }\n }\n },\n }) as unknown as WrappedIcebergRestCatalog\n\n return wrappedCatalog\n }\n}\n","import { version } from '../version'\nexport const DEFAULT_HEADERS = {\n 'X-Client-Info': `storage-js/${version}`,\n 'Content-Type': 'application/json',\n}\n","/**\n * Base error class for all Storage Vectors errors\n */\nexport class StorageVectorsError extends Error {\n protected __isStorageVectorsError = true\n\n constructor(message: string) {\n super(message)\n this.name = 'StorageVectorsError'\n }\n}\n\n/**\n * Type guard to check if an error is a StorageVectorsError\n * @param error - The error to check\n * @returns True if the error is a StorageVectorsError\n */\nexport function isStorageVectorsError(error: unknown): error is StorageVectorsError {\n return typeof error === 'object' && error !== null && '__isStorageVectorsError' in error\n}\n\n/**\n * API error returned from S3 Vectors service\n * Includes HTTP status code and service-specific error code\n */\nexport class StorageVectorsApiError extends StorageVectorsError {\n status: number\n statusCode: string\n\n constructor(message: string, status: number, statusCode: string) {\n super(message)\n this.name = 'StorageVectorsApiError'\n this.status = status\n this.statusCode = statusCode\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n status: this.status,\n statusCode: this.statusCode,\n }\n }\n}\n\n/**\n * Unknown error that doesn't match expected error patterns\n * Wraps the original error for debugging\n */\nexport class StorageVectorsUnknownError extends StorageVectorsError {\n originalError: unknown\n\n constructor(message: string, originalError: unknown) {\n super(message)\n this.name = 'StorageVectorsUnknownError'\n this.originalError = originalError\n }\n}\n\n/**\n * Error codes specific to S3 Vectors API\n * Maps AWS service errors to application-friendly error codes\n */\nexport enum StorageVectorsErrorCode {\n /** Internal server fault (HTTP 500) */\n InternalError = 'InternalError',\n /** Resource already exists / conflict (HTTP 409) */\n S3VectorConflictException = 'S3VectorConflictException',\n /** Resource not found (HTTP 404) */\n S3VectorNotFoundException = 'S3VectorNotFoundException',\n /** Delete bucket while not empty (HTTP 400) */\n S3VectorBucketNotEmpty = 'S3VectorBucketNotEmpty',\n /** Exceeds bucket quota/limit (HTTP 400) */\n S3VectorMaxBucketsExceeded = 'S3VectorMaxBucketsExceeded',\n /** Exceeds index quota/limit (HTTP 400) */\n S3VectorMaxIndexesExceeded = 'S3VectorMaxIndexesExceeded',\n}\n","type Fetch = typeof fetch\n\n/**\n * Resolves the fetch implementation to use\n * Uses custom fetch if provided, otherwise uses native fetch\n *\n * @param customFetch - Optional custom fetch implementation\n * @returns Resolved fetch function\n */\nexport const resolveFetch = (customFetch?: Fetch): Fetch => {\n if (customFetch) {\n return (...args) => customFetch(...args)\n }\n return (...args) => fetch(...args)\n}\n\n/**\n * Resolves the Response constructor to use\n * Returns native Response constructor\n *\n * @returns Response constructor\n */\nexport const resolveResponse = (): typeof Response => {\n return Response\n}\n\n/**\n * Determine if input is a plain object\n * An object is plain if it's created by either {}, new Object(), or Object.create(null)\n *\n * @param value - Value to check\n * @returns True if value is a plain object\n * @source https://github.com/sindresorhus/is-plain-obj\n */\nexport const isPlainObject = (value: object): boolean => {\n if (typeof value !== 'object' || value === null) {\n return false\n }\n\n const prototype = Object.getPrototypeOf(value)\n return (\n (prototype === null ||\n prototype === Object.prototype ||\n Object.getPrototypeOf(prototype) === null) &&\n !(Symbol.toStringTag in value) &&\n !(Symbol.iterator in value)\n )\n}\n\n/**\n * Normalizes a number array to float32 format\n * Ensures all vector values are valid 32-bit floats\n *\n * @param values - Array of numbers to normalize\n * @returns Normalized float32 array\n */\nexport const normalizeToFloat32 = (values: number[]): number[] => {\n // Use Float32Array to ensure proper precision\n return Array.from(new Float32Array(values))\n}\n\n/**\n * Validates vector dimensions match expected dimension\n * Throws error if dimensions don't match\n *\n * @param vector - Vector data to validate\n * @param expectedDimension - Expected vector dimension\n * @throws Error if dimensions don't match\n */\nexport const validateVectorDimension = (\n vector: { float32: number[] },\n expectedDimension?: number\n): void => {\n if (expectedDimension !== undefined && vector.float32.length !== expectedDimension) {\n throw new Error(\n `Vector dimension mismatch: expected ${expectedDimension}, got ${vector.float32.length}`\n )\n }\n}\n","import { StorageVectorsApiError, StorageVectorsUnknownError } from './errors'\nimport { isPlainObject, resolveResponse } from './helpers'\nimport { VectorFetchParameters } from './types'\n\nexport type Fetch = typeof fetch\n\n/**\n * Options for fetch requests\n * @property headers - Custom HTTP headers\n * @property noResolveJson - If true, return raw Response instead of parsing JSON\n */\nexport interface FetchOptions {\n headers?: {\n [key: string]: string\n }\n noResolveJson?: boolean\n}\n\n/**\n * HTTP methods supported by the API\n */\nexport type RequestMethodType = 'GET' | 'POST' | 'PUT' | 'DELETE'\n\n/**\n * Extracts error message from various error response formats\n * @param err - Error object from API\n * @returns Human-readable error message\n */\nconst _getErrorMessage = (err: any): string =>\n err.msg || err.message || err.error_description || err.error || JSON.stringify(err)\n\n/**\n * Handles fetch errors and converts them to StorageVectors error types\n * @param error - The error caught from fetch\n * @param reject - Promise rejection function\n * @param options - Fetch options that may affect error handling\n */\nconst handleError = async (\n error: unknown,\n reject: (reason?: any) => void,\n options?: FetchOptions\n) => {\n // Check if error is a Response-like object (has status and ok properties)\n // This is more reliable than instanceof which can fail across realms\n const isResponseLike =\n error &&\n typeof error === 'object' &&\n 'status' in error &&\n 'ok' in error &&\n typeof (error as any).status === 'number'\n\n if (isResponseLike && !options?.noResolveJson) {\n const status = (error as any).status || 500\n const responseError = error as any\n\n // Try to parse JSON body if available\n if (typeof responseError.json === 'function') {\n responseError\n .json()\n .then((err: any) => {\n const statusCode = err?.statusCode || err?.code || status + ''\n reject(new StorageVectorsApiError(_getErrorMessage(err), status, statusCode))\n })\n .catch(() => {\n // If JSON parsing fails, create an ApiError with the HTTP status code\n const statusCode = status + ''\n const message = responseError.statusText || `HTTP ${status} error`\n reject(new StorageVectorsApiError(message, status, statusCode))\n })\n } else {\n // No json() method available, create error from status\n const statusCode = status + ''\n const message = responseError.statusText || `HTTP ${status} error`\n reject(new StorageVectorsApiError(message, status, statusCode))\n }\n } else {\n reject(new StorageVectorsUnknownError(_getErrorMessage(error), error))\n }\n}\n\n/**\n * Builds request parameters for fetch calls\n * @param method - HTTP method\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters like AbortSignal\n * @param body - Request body (will be JSON stringified if plain object)\n * @returns Complete fetch request parameters\n */\nconst _getRequestParams = (\n method: RequestMethodType,\n options?: FetchOptions,\n parameters?: VectorFetchParameters,\n body?: object\n) => {\n const params: { [k: string]: any } = { method, headers: options?.headers || {} }\n\n if (method === 'GET' || !body) {\n return params\n }\n\n if (isPlainObject(body)) {\n params.headers = { 'Content-Type': 'application/json', ...options?.headers }\n params.body = JSON.stringify(body)\n } else {\n params.body = body\n }\n\n return { ...params, ...parameters }\n}\n\n/**\n * Internal request handler that wraps fetch with error handling\n * @param fetcher - Fetch function to use\n * @param method - HTTP method\n * @param url - Request URL\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @param body - Request body\n * @returns Promise with parsed response or error\n */\nasync function _handleRequest(\n fetcher: Fetch,\n method: RequestMethodType,\n url: string,\n options?: FetchOptions,\n parameters?: VectorFetchParameters,\n body?: object\n): Promise<any> {\n return new Promise((resolve, reject) => {\n fetcher(url, _getRequestParams(method, options, parameters, body))\n .then((result) => {\n if (!result.ok) throw result\n if (options?.noResolveJson) return result\n // Handle empty responses (204, empty body)\n const contentType = result.headers.get('content-type')\n if (!contentType || !contentType.includes('application/json')) {\n return {}\n }\n return result.json()\n })\n .then((data) => resolve(data))\n .catch((error) => handleError(error, reject, options))\n })\n}\n\n/**\n * Performs a GET request\n * @param fetcher - Fetch function to use\n * @param url - Request URL\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @returns Promise with parsed response\n */\nexport async function get(\n fetcher: Fetch,\n url: string,\n options?: FetchOptions,\n parameters?: VectorFetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'GET', url, options, parameters)\n}\n\n/**\n * Performs a POST request\n * @param fetcher - Fetch function to use\n * @param url - Request URL\n * @param body - Request body to be JSON stringified\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @returns Promise with parsed response\n */\nexport async function post(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: VectorFetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'POST', url, options, parameters, body)\n}\n\n/**\n * Performs a PUT request\n * @param fetcher - Fetch function to use\n * @param url - Request URL\n * @param body - Request body to be JSON stringified\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @returns Promise with parsed response\n */\nexport async function put(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: VectorFetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'PUT', url, options, parameters, body)\n}\n\n/**\n * Performs a DELETE request\n * @param fetcher - Fetch function to use\n * @param url - Request URL\n * @param body - Request body to be JSON stringified\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @returns Promise with parsed response\n */\nexport async function remove(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: VectorFetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'DELETE', url, options, parameters, body)\n}\n","import { DEFAULT_HEADERS } from './constants'\nimport { isStorageVectorsError } from './errors'\nimport { Fetch, post } from './fetch'\nimport { resolveFetch } from './helpers'\nimport {\n ApiResponse,\n VectorIndex,\n ListIndexesOptions,\n ListIndexesResponse,\n VectorDataType,\n DistanceMetric,\n MetadataConfiguration,\n} from './types'\n\n/**\n * @alpha\n *\n * Options for creating a vector index\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n */\nexport interface CreateIndexOptions {\n vectorBucketName: string\n indexName: string\n dataType: VectorDataType\n dimension: number\n distanceMetric: DistanceMetric\n metadataConfiguration?: MetadataConfiguration\n}\n\n/**\n * @hidden\n * Base implementation for vector index operations.\n * Use {@link VectorBucketScope} via `supabase.storage.vectors.from('bucket')` instead.\n */\nexport default class VectorIndexApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n /** Creates a new VectorIndexApi instance */\n constructor(url: string, headers: { [key: string]: string } = {}, fetch?: Fetch) {\n this.url = url.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /** Enable throwing errors instead of returning them in the response */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /** Creates a new vector index within a bucket */\n async createIndex(options: CreateIndexOptions): Promise<ApiResponse<undefined>> {\n try {\n const data = await post(this.fetch, `${this.url}/CreateIndex`, options, {\n headers: this.headers,\n })\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Retrieves metadata for a specific vector index */\n async getIndex(\n vectorBucketName: string,\n indexName: string\n ): Promise<ApiResponse<{ index: VectorIndex }>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/GetIndex`,\n { vectorBucketName, indexName },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Lists vector indexes within a bucket with optional filtering and pagination */\n async listIndexes(options: ListIndexesOptions): Promise<ApiResponse<ListIndexesResponse>> {\n try {\n const data = await post(this.fetch, `${this.url}/ListIndexes`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Deletes a vector index and all its data */\n async deleteIndex(vectorBucketName: string, indexName: string): Promise<ApiResponse<undefined>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/DeleteIndex`,\n { vectorBucketName, indexName },\n { headers: this.headers }\n )\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n}\n","import { DEFAULT_HEADERS } from './constants'\nimport { isStorageVectorsError } from './errors'\nimport { Fetch, post } from './fetch'\nimport { resolveFetch } from './helpers'\nimport {\n ApiResponse,\n PutVectorsOptions,\n GetVectorsOptions,\n GetVectorsResponse,\n DeleteVectorsOptions,\n ListVectorsOptions,\n ListVectorsResponse,\n QueryVectorsOptions,\n QueryVectorsResponse,\n} from './types'\n\n/**\n * @hidden\n * Base implementation for vector data operations.\n * Use {@link VectorIndexScope} via `supabase.storage.vectors.from('bucket').index('idx')` instead.\n */\nexport default class VectorDataApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n /** Creates a new VectorDataApi instance */\n constructor(url: string, headers: { [key: string]: string } = {}, fetch?: Fetch) {\n this.url = url.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /** Enable throwing errors instead of returning them in the response */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /** Inserts or updates vectors in batch (1-500 per request) */\n async putVectors(options: PutVectorsOptions): Promise<ApiResponse<undefined>> {\n try {\n // Validate batch size\n if (options.vectors.length < 1 || options.vectors.length > 500) {\n throw new Error('Vector batch size must be between 1 and 500 items')\n }\n\n const data = await post(this.fetch, `${this.url}/PutVectors`, options, {\n headers: this.headers,\n })\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Retrieves vectors by their keys in batch */\n async getVectors(options: GetVectorsOptions): Promise<ApiResponse<GetVectorsResponse>> {\n try {\n const data = await post(this.fetch, `${this.url}/GetVectors`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Lists vectors in an index with pagination */\n async listVectors(options: ListVectorsOptions): Promise<ApiResponse<ListVectorsResponse>> {\n try {\n // Validate segment configuration\n if (options.segmentCount !== undefined) {\n if (options.segmentCount < 1 || options.segmentCount > 16) {\n throw new Error('segmentCount must be between 1 and 16')\n }\n if (options.segmentIndex !== undefined) {\n if (options.segmentIndex < 0 || options.segmentIndex >= options.segmentCount) {\n throw new Error(`segmentIndex must be between 0 and ${options.segmentCount - 1}`)\n }\n }\n }\n\n const data = await post(this.fetch, `${this.url}/ListVectors`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Queries for similar vectors using approximate nearest neighbor search */\n async queryVectors(options: QueryVectorsOptions): Promise<ApiResponse<QueryVectorsResponse>> {\n try {\n const data = await post(this.fetch, `${this.url}/QueryVectors`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Deletes vectors by their keys in batch (1-500 per request) */\n async deleteVectors(options: DeleteVectorsOptions): Promise<ApiResponse<undefined>> {\n try {\n // Validate batch size\n if (options.keys.length < 1 || options.keys.length > 500) {\n throw new Error('Keys batch size must be between 1 and 500 items')\n }\n\n const data = await post(this.fetch, `${this.url}/DeleteVectors`, options, {\n headers: this.headers,\n })\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n}\n","import { DEFAULT_HEADERS } from './constants'\nimport { isStorageVectorsError } from './errors'\nimport { Fetch, post } from './fetch'\nimport { resolveFetch } from './helpers'\nimport {\n ApiResponse,\n VectorBucket,\n ListVectorBucketsOptions,\n ListVectorBucketsResponse,\n} from './types'\n\n/**\n * @hidden\n * Base implementation for vector bucket operations.\n * Use {@link StorageVectorsClient} via `supabase.storage.vectors` instead.\n */\nexport default class VectorBucketApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n /** Creates a new VectorBucketApi instance */\n constructor(url: string, headers: { [key: string]: string } = {}, fetch?: Fetch) {\n this.url = url.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /** Enable throwing errors instead of returning them in the response */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /** Creates a new vector bucket */\n async createBucket(vectorBucketName: string): Promise<ApiResponse<undefined>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/CreateVectorBucket`,\n { vectorBucketName },\n { headers: this.headers }\n )\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Retrieves metadata for a specific vector bucket */\n async getBucket(vectorBucketName: string): Promise<ApiResponse<{ vectorBucket: VectorBucket }>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/GetVectorBucket`,\n { vectorBucketName },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Lists vector buckets with optional filtering and pagination */\n async listBuckets(\n options: ListVectorBucketsOptions = {}\n ): Promise<ApiResponse<ListVectorBucketsResponse>> {\n try {\n const data = await post(this.fetch, `${this.url}/ListVectorBuckets`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Deletes a vector bucket (must be empty first) */\n async deleteBucket(vectorBucketName: string): Promise<ApiResponse<undefined>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/DeleteVectorBucket`,\n { vectorBucketName },\n { headers: this.headers }\n )\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n}\n","import VectorIndexApi, { CreateIndexOptions } from './VectorIndexApi'\nimport VectorDataApi from './VectorDataApi'\nimport { Fetch } from './fetch'\nimport VectorBucketApi from './VectorBucketApi'\nimport {\n ApiResponse,\n DeleteVectorsOptions,\n GetVectorsOptions,\n ListIndexesOptions,\n ListVectorsOptions,\n ListVectorBucketsOptions,\n ListVectorBucketsResponse,\n PutVectorsOptions,\n QueryVectorsOptions,\n VectorBucket,\n} from './types'\n\n/**\n *\n * @alpha\n *\n * Configuration options for the Storage Vectors client\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n */\nexport interface StorageVectorsClientOptions {\n /**\n * Custom headers to include in all requests\n */\n headers?: { [key: string]: string }\n /**\n * Custom fetch implementation (optional)\n * Useful for testing or custom request handling\n */\n fetch?: Fetch\n}\n\n/**\n *\n * @alpha\n *\n * Main client for interacting with S3 Vectors API\n * Provides access to bucket, index, and vector data operations\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * **Usage Patterns:**\n *\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .createBucket('embeddings-prod')\n *\n * // Access index operations via buckets\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * await bucket.createIndex({\n * indexName: 'documents',\n * dataType: 'float32',\n * dimension: 1536,\n * distanceMetric: 'cosine'\n * })\n *\n * // Access vector operations via index\n * const index = bucket.index('documents')\n * await index.putVectors({\n * vectors: [\n * { key: 'doc-1', data: { float32: [...] }, metadata: { title: 'Intro' } }\n * ]\n * })\n *\n * // Query similar vectors\n * const { data } = await index.queryVectors({\n * queryVector: { float32: [...] },\n * topK: 5,\n * returnDistance: true\n * })\n * ```\n */\nexport class StorageVectorsClient extends VectorBucketApi {\n /**\n * @alpha\n *\n * Creates a StorageVectorsClient that can manage buckets, indexes, and vectors.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param url - Base URL of the Storage Vectors REST API.\n * @param options.headers - Optional headers (for example `Authorization`) applied to every request.\n * @param options.fetch - Optional custom `fetch` implementation for non-browser runtimes.\n *\n * @example\n * ```typescript\n * const client = new StorageVectorsClient(url, options)\n * ```\n */\n constructor(url: string, options: StorageVectorsClientOptions = {}) {\n super(url, options.headers || {}, options.fetch)\n }\n\n /**\n *\n * @alpha\n *\n * Access operations for a specific vector bucket\n * Returns a scoped client for index and vector operations within the bucket\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param vectorBucketName - Name of the vector bucket\n * @returns Bucket-scoped client with index and vector operations\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * ```\n */\n from(vectorBucketName: string): VectorBucketScope {\n return new VectorBucketScope(this.url, this.headers, vectorBucketName, this.fetch)\n }\n\n /**\n *\n * @alpha\n *\n * Creates a new vector bucket\n * Vector buckets are containers for vector indexes and their data\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param vectorBucketName - Unique name for the vector bucket\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .createBucket('embeddings-prod')\n * ```\n */\n async createBucket(vectorBucketName: string): Promise<ApiResponse<undefined>> {\n return super.createBucket(vectorBucketName)\n }\n\n /**\n *\n * @alpha\n *\n * Retrieves metadata for a specific vector bucket\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param vectorBucketName - Name of the vector bucket\n * @returns Promise with bucket metadata or error\n *\n * @example\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .getBucket('embeddings-prod')\n *\n * console.log('Bucket created:', data?.vectorBucket.creationTime)\n * ```\n */\n async getBucket(vectorBucketName: string): Promise<ApiResponse<{ vectorBucket: VectorBucket }>> {\n return super.getBucket(vectorBucketName)\n }\n\n /**\n *\n * @alpha\n *\n * Lists all vector buckets with optional filtering and pagination\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Optional filters (prefix, maxResults, nextToken)\n * @returns Promise with list of buckets or error\n *\n * @example\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .listBuckets({ prefix: 'embeddings-' })\n *\n * data?.vectorBuckets.forEach(bucket => {\n * console.log(bucket.vectorBucketName)\n * })\n * ```\n */\n async listBuckets(\n options: ListVectorBucketsOptions = {}\n ): Promise<ApiResponse<ListVectorBucketsResponse>> {\n return super.listBuckets(options)\n }\n\n /**\n *\n * @alpha\n *\n * Deletes a vector bucket (bucket must be empty)\n * All indexes must be deleted before deleting the bucket\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param vectorBucketName - Name of the vector bucket to delete\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .deleteBucket('embeddings-old')\n * ```\n */\n async deleteBucket(vectorBucketName: string): Promise<ApiResponse<undefined>> {\n return super.deleteBucket(vectorBucketName)\n }\n}\n\n/**\n *\n * @alpha\n *\n * Scoped client for operations within a specific vector bucket\n * Provides index management and access to vector operations\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n */\nexport class VectorBucketScope extends VectorIndexApi {\n private vectorBucketName: string\n\n /**\n * @alpha\n *\n * Creates a helper that automatically scopes all index operations to the provided bucket.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * ```\n */\n constructor(\n url: string,\n headers: { [key: string]: string },\n vectorBucketName: string,\n fetch?: Fetch\n ) {\n super(url, headers, fetch)\n this.vectorBucketName = vectorBucketName\n }\n\n /**\n *\n * @alpha\n *\n * Creates a new vector index in this bucket\n * Convenience method that automatically includes the bucket name\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Index configuration (vectorBucketName is automatically set)\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * await bucket.createIndex({\n * indexName: 'documents-openai',\n * dataType: 'float32',\n * dimension: 1536,\n * distanceMetric: 'cosine',\n * metadataConfiguration: {\n * nonFilterableMetadataKeys: ['raw_text']\n * }\n * })\n * ```\n */\n override async createIndex(options: Omit<CreateIndexOptions, 'vectorBucketName'>) {\n return super.createIndex({\n ...options,\n vectorBucketName: this.vectorBucketName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Lists indexes in this bucket\n * Convenience method that automatically includes the bucket name\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Listing options (vectorBucketName is automatically set)\n * @returns Promise with response containing indexes array and pagination token or error\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * const { data } = await bucket.listIndexes({ prefix: 'documents-' })\n * ```\n */\n override async listIndexes(options: Omit<ListIndexesOptions, 'vectorBucketName'> = {}) {\n return super.listIndexes({\n ...options,\n vectorBucketName: this.vectorBucketName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Retrieves metadata for a specific index in this bucket\n * Convenience method that automatically includes the bucket name\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param indexName - Name of the index to retrieve\n * @returns Promise with index metadata or error\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * const { data } = await bucket.getIndex('documents-openai')\n * console.log('Dimension:', data?.index.dimension)\n * ```\n */\n override async getIndex(indexName: string) {\n return super.getIndex(this.vectorBucketName, indexName)\n }\n\n /**\n *\n * @alpha\n *\n * Deletes an index from this bucket\n * Convenience method that automatically includes the bucket name\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param indexName - Name of the index to delete\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * await bucket.deleteIndex('old-index')\n * ```\n */\n override async deleteIndex(indexName: string) {\n return super.deleteIndex(this.vectorBucketName, indexName)\n }\n\n /**\n *\n * @alpha\n *\n * Access operations for a specific index within this bucket\n * Returns a scoped client for vector data operations\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param indexName - Name of the index\n * @returns Index-scoped client with vector data operations\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n *\n * // Insert vectors\n * await index.putVectors({\n * vectors: [\n * { key: 'doc-1', data: { float32: [...] }, metadata: { title: 'Intro' } }\n * ]\n * })\n *\n * // Query similar vectors\n * const { data } = await index.queryVectors({\n * queryVector: { float32: [...] },\n * topK: 5\n * })\n * ```\n */\n index(indexName: string): VectorIndexScope {\n return new VectorIndexScope(\n this.url,\n this.headers,\n this.vectorBucketName,\n indexName,\n this.fetch\n )\n }\n}\n\n/**\n *\n * @alpha\n *\n * Scoped client for operations within a specific vector index\n * Provides vector data operations (put, get, list, query, delete)\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n */\nexport class VectorIndexScope extends VectorDataApi {\n private vectorBucketName: string\n private indexName: string\n\n /**\n *\n * @alpha\n *\n * Creates a helper that automatically scopes all vector operations to the provided bucket/index names.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * ```\n */\n constructor(\n url: string,\n headers: { [key: string]: string },\n vectorBucketName: string,\n indexName: string,\n fetch?: Fetch\n ) {\n super(url, headers, fetch)\n this.vectorBucketName = vectorBucketName\n this.indexName = indexName\n }\n\n /**\n *\n * @alpha\n *\n * Inserts or updates vectors in this index\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Vector insertion options (bucket and index names automatically set)\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * await index.putVectors({\n * vectors: [\n * {\n * key: 'doc-1',\n * data: { float32: [0.1, 0.2, ...] },\n * metadata: { title: 'Introduction', page: 1 }\n * }\n * ]\n * })\n * ```\n */\n override async putVectors(options: Omit<PutVectorsOptions, 'vectorBucketName' | 'indexName'>) {\n return super.putVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Retrieves vectors by keys from this index\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Vector retrieval options (bucket and index names automatically set)\n * @returns Promise with response containing vectors array or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * const { data } = await index.getVectors({\n * keys: ['doc-1', 'doc-2'],\n * returnMetadata: true\n * })\n * ```\n */\n override async getVectors(options: Omit<GetVectorsOptions, 'vectorBucketName' | 'indexName'>) {\n return super.getVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Lists vectors in this index with pagination\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Listing options (bucket and index names automatically set)\n * @returns Promise with response containing vectors array and pagination token or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * const { data } = await index.listVectors({\n * maxResults: 500,\n * returnMetadata: true\n * })\n * ```\n */\n override async listVectors(\n options: Omit<ListVectorsOptions, 'vectorBucketName' | 'indexName'> = {}\n ) {\n return super.listVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Queries for similar vectors in this index\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Query options (bucket and index names automatically set)\n * @returns Promise with response containing matches array of similar vectors ordered by distance or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * const { data } = await index.queryVectors({\n * queryVector: { float32: [0.1, 0.2, ...] },\n * topK: 5,\n * filter: { category: 'technical' },\n * returnDistance: true,\n * returnMetadata: true\n * })\n * ```\n */\n override async queryVectors(\n options: Omit<QueryVectorsOptions, 'vectorBucketName' | 'indexName'>\n ) {\n return super.queryVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Deletes vectors by keys from this index\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Deletion options (bucket and index names automatically set)\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * await index.deleteVectors({\n * keys: ['doc-1', 'doc-2', 'doc-3']\n * })\n * ```\n */\n override async deleteVectors(\n options: Omit<DeleteVectorsOptions, 'vectorBucketName' | 'indexName'>\n ) {\n return super.deleteVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n}\n","import StorageFileApi from './packages/StorageFileApi'\nimport StorageBucketApi from './packages/StorageBucketApi'\nimport StorageAnalyticsClient from './packages/StorageAnalyticsClient'\nimport { Fetch } from './lib/fetch'\nimport { StorageVectorsClient } from './lib/vectors'\n\nexport interface StorageClientOptions {\n useNewHostname?: boolean\n}\n\nexport class StorageClient extends StorageBucketApi {\n /**\n * Creates a client for Storage buckets, files, analytics, and vectors.\n *\n * @category File Buckets\n * @example\n * ```ts\n * import { StorageClient } from '@supabase/storage-js'\n *\n * const storage = new StorageClient('https://xyzcompany.supabase.co/storage/v1', {\n * apikey: 'public-anon-key',\n * })\n * const avatars = storage.from('avatars')\n * ```\n */\n constructor(\n url: string,\n headers: { [key: string]: string } = {},\n fetch?: Fetch,\n opts?: StorageClientOptions\n ) {\n super(url, headers, fetch, opts)\n }\n\n /**\n * Perform file operation in a bucket.\n *\n * @category File Buckets\n * @param id The bucket id to operate on.\n *\n * @example\n * ```typescript\n * const avatars = supabase.storage.from('avatars')\n * ```\n */\n from(id: string): StorageFileApi {\n return new StorageFileApi(this.url, this.headers, id, this.fetch)\n }\n\n /**\n *\n * @alpha\n *\n * Access vector storage operations.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @returns A StorageVectorsClient instance configured with the current storage settings.\n */\n get vectors(): StorageVectorsClient {\n return new StorageVectorsClient(this.url + '/vector', {\n headers: this.headers,\n fetch: this.fetch,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Access analytics storage operations using Iceberg tables.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @returns A StorageAnalyticsClient instance configured with the current storage settings.\n */\n get analytics(): StorageAnalyticsClient {\n return new StorageAnalyticsClient(this.url + '/iceberg', this.headers, this.fetch)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["resolveFetch","resolveResponse","result: Record<string, any>","isPlainObject","_getErrorMessage","handleError","resolveResponse","_getRequestParams","params: { [k: string]: any }","isPlainObject","_handleRequest","post","downloadFn: () => Promise<Response>","shouldThrowOnError: boolean","this","downloadFn: () => Promise<Response>","shouldThrowOnError: boolean","this","DEFAULT_FILE_OPTIONS: FileOptions","resolveFetch","fetch","headers: Record<string, string>","this","post","_queryString: string[]","params: string[]","DEFAULT_HEADERS","DEFAULT_HEADERS","resolveFetch","fetch","this","post","params: Record<string, string>","DEFAULT_HEADERS","resolveFetch","fetch","post","this","IcebergRestCatalog","params: { [k: string]: any }","fetch","this","fetch","this","fetch","this","fetch","this","fetch"],"sources":["../src/lib/errors.ts","../src/lib/helpers.ts","../src/lib/fetch.ts","../src/packages/StreamDownloadBuilder.ts","../src/packages/BlobDownloadBuilder.ts","../src/packages/StorageFileApi.ts","../src/lib/version.ts","../src/lib/constants.ts","../src/packages/StorageBucketApi.ts","../src/packages/StorageAnalyticsClient.ts","../src/lib/vectors/constants.ts","../src/lib/vectors/errors.ts","../src/lib/vectors/helpers.ts","../src/lib/vectors/fetch.ts","../src/lib/vectors/VectorIndexApi.ts","../src/lib/vectors/VectorDataApi.ts","../src/lib/vectors/VectorBucketApi.ts","../src/lib/vectors/StorageVectorsClient.ts","../src/StorageClient.ts"],"sourcesContent":["export class StorageError extends Error {\n protected __isStorageError = true\n\n constructor(message: string) {\n super(message)\n this.name = 'StorageError'\n }\n}\n\nexport function isStorageError(error: unknown): error is StorageError {\n return typeof error === 'object' && error !== null && '__isStorageError' in error\n}\n\nexport class StorageApiError extends StorageError {\n status: number\n statusCode: string\n\n constructor(message: string, status: number, statusCode: string) {\n super(message)\n this.name = 'StorageApiError'\n this.status = status\n this.statusCode = statusCode\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n status: this.status,\n statusCode: this.statusCode,\n }\n }\n}\n\nexport class StorageUnknownError extends StorageError {\n originalError: unknown\n\n constructor(message: string, originalError: unknown) {\n super(message)\n this.name = 'StorageUnknownError'\n this.originalError = originalError\n }\n}\n","type Fetch = typeof fetch\n\nexport const resolveFetch = (customFetch?: Fetch): Fetch => {\n if (customFetch) {\n return (...args) => customFetch(...args)\n }\n return (...args) => fetch(...args)\n}\n\nexport const resolveResponse = (): typeof Response => {\n return Response\n}\n\nexport const recursiveToCamel = (item: Record<string, any>): unknown => {\n if (Array.isArray(item)) {\n return item.map((el) => recursiveToCamel(el))\n } else if (typeof item === 'function' || item !== Object(item)) {\n return item\n }\n\n const result: Record<string, any> = {}\n Object.entries(item).forEach(([key, value]) => {\n const newKey = key.replace(/([-_][a-z])/gi, (c) => c.toUpperCase().replace(/[-_]/g, ''))\n result[newKey] = recursiveToCamel(value)\n })\n\n return result\n}\n\n/**\n * Determine if input is a plain object\n * An object is plain if it's created by either {}, new Object(), or Object.create(null)\n * source: https://github.com/sindresorhus/is-plain-obj\n */\nexport const isPlainObject = (value: object): boolean => {\n if (typeof value !== 'object' || value === null) {\n return false\n }\n\n const prototype = Object.getPrototypeOf(value)\n return (\n (prototype === null ||\n prototype === Object.prototype ||\n Object.getPrototypeOf(prototype) === null) &&\n !(Symbol.toStringTag in value) &&\n !(Symbol.iterator in value)\n )\n}\n\n/**\n * Validates if a given bucket name is valid according to Supabase Storage API rules\n * Mirrors backend validation from: storage/src/storage/limits.ts:isValidBucketName()\n *\n * Rules:\n * - Length: 1-100 characters\n * - Allowed characters: alphanumeric (a-z, A-Z, 0-9), underscore (_), and safe special characters\n * - Safe special characters: ! - . * ' ( ) space & $ @ = ; : + , ?\n * - Forbidden: path separators (/, \\), path traversal (..), leading/trailing whitespace\n *\n * AWS S3 Reference: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html\n *\n * @param bucketName - The bucket name to validate\n * @returns true if valid, false otherwise\n */\nexport const isValidBucketName = (bucketName: string): boolean => {\n if (!bucketName || typeof bucketName !== 'string') {\n return false\n }\n\n // Check length constraints (1-100 characters)\n if (bucketName.length === 0 || bucketName.length > 100) {\n return false\n }\n\n // Check for leading/trailing whitespace\n if (bucketName.trim() !== bucketName) {\n return false\n }\n\n // Explicitly reject path separators (security)\n // Note: Consecutive periods (..) are allowed by backend - the AWS restriction\n // on relative paths applies to object keys, not bucket names\n if (bucketName.includes('/') || bucketName.includes('\\\\')) {\n return false\n }\n\n // Validate against allowed character set\n // Pattern matches backend regex: /^(\\w|!|-|\\.|\\*|'|\\(|\\)| |&|\\$|@|=|;|:|\\+|,|\\?)*$/\n // This explicitly excludes path separators (/, \\) and other problematic characters\n const bucketNameRegex = /^[\\w!.\\*'() &$@=;:+,?-]+$/\n return bucketNameRegex.test(bucketName)\n}\n","import { StorageApiError, StorageUnknownError } from './errors'\nimport { isPlainObject, resolveResponse } from './helpers'\nimport { FetchParameters } from './types'\n\nexport type Fetch = typeof fetch\n\nexport interface FetchOptions {\n headers?: {\n [key: string]: string\n }\n duplex?: string\n noResolveJson?: boolean\n}\n\nexport type RequestMethodType = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD'\n\nconst _getErrorMessage = (err: any): string =>\n err.msg ||\n err.message ||\n err.error_description ||\n (typeof err.error === 'string' ? err.error : err.error?.message) ||\n JSON.stringify(err)\n\nconst handleError = async (\n error: unknown,\n reject: (reason?: any) => void,\n options?: FetchOptions\n) => {\n const Res = await resolveResponse()\n\n if (error instanceof Res && !options?.noResolveJson) {\n error\n .json()\n .then((err) => {\n const status = error.status || 500\n const statusCode = err?.statusCode || status + ''\n reject(new StorageApiError(_getErrorMessage(err), status, statusCode))\n })\n .catch((err) => {\n reject(new StorageUnknownError(_getErrorMessage(err), err))\n })\n } else {\n reject(new StorageUnknownError(_getErrorMessage(error), error))\n }\n}\n\nconst _getRequestParams = (\n method: RequestMethodType,\n options?: FetchOptions,\n parameters?: FetchParameters,\n body?: object\n) => {\n const params: { [k: string]: any } = { method, headers: options?.headers || {} }\n\n if (method === 'GET' || !body) {\n return params\n }\n\n if (isPlainObject(body)) {\n params.headers = { 'Content-Type': 'application/json', ...options?.headers }\n params.body = JSON.stringify(body)\n } else {\n params.body = body\n }\n\n if (options?.duplex) {\n params.duplex = options.duplex\n }\n\n return { ...params, ...parameters }\n}\n\nasync function _handleRequest(\n fetcher: Fetch,\n method: RequestMethodType,\n url: string,\n options?: FetchOptions,\n parameters?: FetchParameters,\n body?: object\n): Promise<any> {\n return new Promise((resolve, reject) => {\n fetcher(url, _getRequestParams(method, options, parameters, body))\n .then((result) => {\n if (!result.ok) throw result\n if (options?.noResolveJson) return result\n return result.json()\n })\n .then((data) => resolve(data))\n .catch((error) => handleError(error, reject, options))\n })\n}\n\nexport async function get(\n fetcher: Fetch,\n url: string,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'GET', url, options, parameters)\n}\n\nexport async function post(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'POST', url, options, parameters, body)\n}\n\nexport async function put(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'PUT', url, options, parameters, body)\n}\n\nexport async function head(\n fetcher: Fetch,\n url: string,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(\n fetcher,\n 'HEAD',\n url,\n {\n ...options,\n noResolveJson: true,\n },\n parameters\n )\n}\n\nexport async function remove(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: FetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'DELETE', url, options, parameters, body)\n}\n","import { isStorageError } from '../lib/errors'\nimport { DownloadResult } from '../lib/types'\n\nexport default class StreamDownloadBuilder implements PromiseLike<DownloadResult<ReadableStream>> {\n constructor(\n private downloadFn: () => Promise<Response>,\n private shouldThrowOnError: boolean\n ) {}\n\n then<TResult1 = DownloadResult<ReadableStream>, TResult2 = never>(\n onfulfilled?:\n | ((value: DownloadResult<ReadableStream>) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null\n ): Promise<TResult1 | TResult2> {\n return this.execute().then(onfulfilled, onrejected)\n }\n\n private async execute(): Promise<DownloadResult<ReadableStream>> {\n try {\n const result = await this.downloadFn()\n\n return {\n data: result.body as ReadableStream,\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n}\n","import { isStorageError } from '../lib/errors'\nimport { DownloadResult } from '../lib/types'\nimport StreamDownloadBuilder from './StreamDownloadBuilder'\n\nexport default class BlobDownloadBuilder implements Promise<DownloadResult<Blob>> {\n readonly [Symbol.toStringTag]: string = 'BlobDownloadBuilder'\n private promise: Promise<DownloadResult<Blob>> | null = null\n\n constructor(\n private downloadFn: () => Promise<Response>,\n private shouldThrowOnError: boolean\n ) {}\n\n asStream(): StreamDownloadBuilder {\n return new StreamDownloadBuilder(this.downloadFn, this.shouldThrowOnError)\n }\n\n then<TResult1 = DownloadResult<Blob>, TResult2 = never>(\n onfulfilled?: ((value: DownloadResult<Blob>) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null\n ): Promise<TResult1 | TResult2> {\n return this.getPromise().then(onfulfilled, onrejected)\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null\n ): Promise<DownloadResult<Blob> | TResult> {\n return this.getPromise().catch(onrejected)\n }\n\n finally(onfinally?: (() => void) | null): Promise<DownloadResult<Blob>> {\n return this.getPromise().finally(onfinally)\n }\n\n private getPromise(): Promise<DownloadResult<Blob>> {\n if (!this.promise) {\n this.promise = this.execute()\n }\n return this.promise\n }\n\n private async execute(): Promise<DownloadResult<Blob>> {\n try {\n const result = await this.downloadFn()\n\n return {\n data: await result.blob(),\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n}\n","import { isStorageError, StorageError, StorageUnknownError } from '../lib/errors'\nimport { Fetch, get, head, post, put, remove } from '../lib/fetch'\nimport { recursiveToCamel, resolveFetch } from '../lib/helpers'\nimport {\n FileObject,\n FileOptions,\n SearchOptions,\n FetchParameters,\n TransformOptions,\n DestinationOptions,\n FileObjectV2,\n Camelize,\n SearchV2Options,\n SearchV2Result,\n} from '../lib/types'\nimport BlobDownloadBuilder from './BlobDownloadBuilder'\n\nconst DEFAULT_SEARCH_OPTIONS = {\n limit: 100,\n offset: 0,\n sortBy: {\n column: 'name',\n order: 'asc',\n },\n}\n\nconst DEFAULT_FILE_OPTIONS: FileOptions = {\n cacheControl: '3600',\n contentType: 'text/plain;charset=UTF-8',\n upsert: false,\n}\n\ntype FileBody =\n | ArrayBuffer\n | ArrayBufferView\n | Blob\n | Buffer\n | File\n | FormData\n | NodeJS.ReadableStream\n | ReadableStream<Uint8Array>\n | URLSearchParams\n | string\n\nexport default class StorageFileApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected bucketId?: string\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n constructor(\n url: string,\n headers: { [key: string]: string } = {},\n bucketId?: string,\n fetch?: Fetch\n ) {\n this.url = url\n this.headers = headers\n this.bucketId = bucketId\n this.fetch = resolveFetch(fetch)\n }\n\n /**\n * Enable throwing errors instead of returning them.\n *\n * @category File Buckets\n */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /**\n * Uploads a file to an existing bucket or replaces an existing file at the specified path with a new one.\n *\n * @param method HTTP method.\n * @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.\n * @param fileBody The body of the file to be stored in the bucket.\n */\n private async uploadOrUpdate(\n method: 'POST' | 'PUT',\n path: string,\n fileBody: FileBody,\n fileOptions?: FileOptions\n ): Promise<\n | {\n data: { id: string; path: string; fullPath: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n let body\n const options = { ...DEFAULT_FILE_OPTIONS, ...fileOptions }\n let headers: Record<string, string> = {\n ...this.headers,\n ...(method === 'POST' && { 'x-upsert': String(options.upsert as boolean) }),\n }\n\n const metadata = options.metadata\n\n if (typeof Blob !== 'undefined' && fileBody instanceof Blob) {\n body = new FormData()\n body.append('cacheControl', options.cacheControl as string)\n if (metadata) {\n body.append('metadata', this.encodeMetadata(metadata))\n }\n body.append('', fileBody)\n } else if (typeof FormData !== 'undefined' && fileBody instanceof FormData) {\n body = fileBody\n // Only append if not already present\n if (!body.has('cacheControl')) {\n body.append('cacheControl', options.cacheControl as string)\n }\n if (metadata && !body.has('metadata')) {\n body.append('metadata', this.encodeMetadata(metadata))\n }\n } else {\n body = fileBody\n headers['cache-control'] = `max-age=${options.cacheControl}`\n headers['content-type'] = options.contentType as string\n\n if (metadata) {\n headers['x-metadata'] = this.toBase64(this.encodeMetadata(metadata))\n }\n\n // Node.js streams require duplex option for fetch in Node 20+\n // Check for both web ReadableStream and Node.js streams\n const isStream =\n (typeof ReadableStream !== 'undefined' && body instanceof ReadableStream) ||\n (body && typeof body === 'object' && 'pipe' in body && typeof body.pipe === 'function')\n\n if (isStream && !options.duplex) {\n options.duplex = 'half'\n }\n }\n\n if (fileOptions?.headers) {\n headers = { ...headers, ...fileOptions.headers }\n }\n\n const cleanPath = this._removeEmptyFolders(path)\n const _path = this._getFinalPath(cleanPath)\n const data = await (method == 'PUT' ? put : post)(\n this.fetch,\n `${this.url}/object/${_path}`,\n body as object,\n { headers, ...(options?.duplex ? { duplex: options.duplex } : {}) }\n )\n\n return {\n data: { path: cleanPath, id: data.Id, fullPath: data.Key },\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Uploads a file to an existing bucket.\n *\n * @category File Buckets\n * @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.\n * @param fileBody The body of the file to be stored in the bucket.\n * @param fileOptions Optional file upload options including cacheControl, contentType, upsert, and metadata.\n * @returns Promise with response containing file path, id, and fullPath or error\n *\n * @example Upload file\n * ```js\n * const avatarFile = event.target.files[0]\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .upload('public/avatar1.png', avatarFile, {\n * cacheControl: '3600',\n * upsert: false\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"path\": \"public/avatar1.png\",\n * \"fullPath\": \"avatars/public/avatar1.png\"\n * },\n * \"error\": null\n * }\n * ```\n *\n * @example Upload file using `ArrayBuffer` from base64 file data\n * ```js\n * import { decode } from 'base64-arraybuffer'\n *\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .upload('public/avatar1.png', decode('base64FileData'), {\n * contentType: 'image/png'\n * })\n * ```\n */\n async upload(\n path: string,\n fileBody: FileBody,\n fileOptions?: FileOptions\n ): Promise<\n | {\n data: { id: string; path: string; fullPath: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n return this.uploadOrUpdate('POST', path, fileBody, fileOptions)\n }\n\n /**\n * Upload a file with a token generated from `createSignedUploadUrl`.\n *\n * @category File Buckets\n * @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.\n * @param token The token generated from `createSignedUploadUrl`\n * @param fileBody The body of the file to be stored in the bucket.\n * @param fileOptions HTTP headers (cacheControl, contentType, etc.).\n * **Note:** The `upsert` option has no effect here. To enable upsert behavior,\n * pass `{ upsert: true }` when calling `createSignedUploadUrl()` instead.\n * @returns Promise with response containing file path and fullPath or error\n *\n * @example Upload to a signed URL\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .uploadToSignedUrl('folder/cat.jpg', 'token-from-createSignedUploadUrl', file)\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"path\": \"folder/cat.jpg\",\n * \"fullPath\": \"avatars/folder/cat.jpg\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async uploadToSignedUrl(\n path: string,\n token: string,\n fileBody: FileBody,\n fileOptions?: FileOptions\n ) {\n const cleanPath = this._removeEmptyFolders(path)\n const _path = this._getFinalPath(cleanPath)\n\n const url = new URL(this.url + `/object/upload/sign/${_path}`)\n url.searchParams.set('token', token)\n\n try {\n let body\n const options = { upsert: DEFAULT_FILE_OPTIONS.upsert, ...fileOptions }\n const headers: Record<string, string> = {\n ...this.headers,\n ...{ 'x-upsert': String(options.upsert as boolean) },\n }\n\n if (typeof Blob !== 'undefined' && fileBody instanceof Blob) {\n body = new FormData()\n body.append('cacheControl', options.cacheControl as string)\n body.append('', fileBody)\n } else if (typeof FormData !== 'undefined' && fileBody instanceof FormData) {\n body = fileBody\n body.append('cacheControl', options.cacheControl as string)\n } else {\n body = fileBody\n headers['cache-control'] = `max-age=${options.cacheControl}`\n headers['content-type'] = options.contentType as string\n }\n\n const data = await put(this.fetch, url.toString(), body as object, { headers })\n\n return {\n data: { path: cleanPath, fullPath: data.Key },\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Creates a signed upload URL.\n * Signed upload URLs can be used to upload files to the bucket without further authentication.\n * They are valid for 2 hours.\n *\n * @category File Buckets\n * @param path The file path, including the current file name. For example `folder/image.png`.\n * @param options.upsert If set to true, allows the file to be overwritten if it already exists.\n * @returns Promise with response containing signed upload URL, token, and path or error\n *\n * @example Create Signed Upload URL\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUploadUrl('folder/cat.jpg')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"signedUrl\": \"https://example.supabase.co/storage/v1/object/upload/sign/avatars/folder/cat.jpg?token=<TOKEN>\",\n * \"path\": \"folder/cat.jpg\",\n * \"token\": \"<TOKEN>\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async createSignedUploadUrl(\n path: string,\n options?: { upsert: boolean }\n ): Promise<\n | {\n data: { signedUrl: string; token: string; path: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n let _path = this._getFinalPath(path)\n\n const headers = { ...this.headers }\n\n if (options?.upsert) {\n headers['x-upsert'] = 'true'\n }\n\n const data = await post(\n this.fetch,\n `${this.url}/object/upload/sign/${_path}`,\n {},\n { headers }\n )\n\n const url = new URL(this.url + data.url)\n\n const token = url.searchParams.get('token')\n\n if (!token) {\n throw new StorageError('No token returned by API')\n }\n\n return { data: { signedUrl: url.toString(), path, token }, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Replaces an existing file at the specified path with a new one.\n *\n * @category File Buckets\n * @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to update.\n * @param fileBody The body of the file to be stored in the bucket.\n * @param fileOptions Optional file upload options including cacheControl, contentType, upsert, and metadata.\n * @returns Promise with response containing file path, id, and fullPath or error\n *\n * @example Update file\n * ```js\n * const avatarFile = event.target.files[0]\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .update('public/avatar1.png', avatarFile, {\n * cacheControl: '3600',\n * upsert: true\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"path\": \"public/avatar1.png\",\n * \"fullPath\": \"avatars/public/avatar1.png\"\n * },\n * \"error\": null\n * }\n * ```\n *\n * @example Update file using `ArrayBuffer` from base64 file data\n * ```js\n * import {decode} from 'base64-arraybuffer'\n *\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .update('public/avatar1.png', decode('base64FileData'), {\n * contentType: 'image/png'\n * })\n * ```\n */\n async update(\n path: string,\n fileBody:\n | ArrayBuffer\n | ArrayBufferView\n | Blob\n | Buffer\n | File\n | FormData\n | NodeJS.ReadableStream\n | ReadableStream<Uint8Array>\n | URLSearchParams\n | string,\n fileOptions?: FileOptions\n ): Promise<\n | {\n data: { id: string; path: string; fullPath: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n return this.uploadOrUpdate('PUT', path, fileBody, fileOptions)\n }\n\n /**\n * Moves an existing file to a new path in the same bucket.\n *\n * @category File Buckets\n * @param fromPath The original file path, including the current file name. For example `folder/image.png`.\n * @param toPath The new file path, including the new file name. For example `folder/image-new.png`.\n * @param options The destination options.\n * @returns Promise with response containing success message or error\n *\n * @example Move file\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .move('public/avatar1.png', 'private/avatar2.png')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully moved\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async move(\n fromPath: string,\n toPath: string,\n options?: DestinationOptions\n ): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/object/move`,\n {\n bucketId: this.bucketId,\n sourceKey: fromPath,\n destinationKey: toPath,\n destinationBucket: options?.destinationBucket,\n },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Copies an existing file to a new path in the same bucket.\n *\n * @category File Buckets\n * @param fromPath The original file path, including the current file name. For example `folder/image.png`.\n * @param toPath The new file path, including the new file name. For example `folder/image-copy.png`.\n * @param options The destination options.\n * @returns Promise with response containing copied file path or error\n *\n * @example Copy file\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .copy('public/avatar1.png', 'private/avatar2.png')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"path\": \"avatars/private/avatar2.png\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async copy(\n fromPath: string,\n toPath: string,\n options?: DestinationOptions\n ): Promise<\n | {\n data: { path: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/object/copy`,\n {\n bucketId: this.bucketId,\n sourceKey: fromPath,\n destinationKey: toPath,\n destinationBucket: options?.destinationBucket,\n },\n { headers: this.headers }\n )\n return { data: { path: data.Key }, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Creates a signed URL. Use a signed URL to share a file for a fixed amount of time.\n *\n * @category File Buckets\n * @param path The file path, including the current file name. For example `folder/image.png`.\n * @param expiresIn The number of seconds until the signed URL expires. For example, `60` for a URL which is valid for one minute.\n * @param options.download triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename.\n * @param options.transform Transform the asset before serving it to the client.\n * @returns Promise with response containing signed URL or error\n *\n * @example Create Signed URL\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUrl('folder/avatar1.png', 60)\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"signedUrl\": \"https://example.supabase.co/storage/v1/object/sign/avatars/folder/avatar1.png?token=<TOKEN>\"\n * },\n * \"error\": null\n * }\n * ```\n *\n * @example Create a signed URL for an asset with transformations\n * ```js\n * const { data } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUrl('folder/avatar1.png', 60, {\n * transform: {\n * width: 100,\n * height: 100,\n * }\n * })\n * ```\n *\n * @example Create a signed URL which triggers the download of the asset\n * ```js\n * const { data } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUrl('folder/avatar1.png', 60, {\n * download: true,\n * })\n * ```\n */\n async createSignedUrl(\n path: string,\n expiresIn: number,\n options?: { download?: string | boolean; transform?: TransformOptions }\n ): Promise<\n | {\n data: { signedUrl: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n let _path = this._getFinalPath(path)\n\n let data = await post(\n this.fetch,\n `${this.url}/object/sign/${_path}`,\n { expiresIn, ...(options?.transform ? { transform: options.transform } : {}) },\n { headers: this.headers }\n )\n const downloadQueryParam = options?.download\n ? `&download=${options.download === true ? '' : options.download}`\n : ''\n const signedUrl = encodeURI(`${this.url}${data.signedURL}${downloadQueryParam}`)\n data = { signedUrl }\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Creates multiple signed URLs. Use a signed URL to share a file for a fixed amount of time.\n *\n * @category File Buckets\n * @param paths The file paths to be downloaded, including the current file names. For example `['folder/image.png', 'folder2/image2.png']`.\n * @param expiresIn The number of seconds until the signed URLs expire. For example, `60` for URLs which are valid for one minute.\n * @param options.download triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename.\n * @returns Promise with response containing array of objects with signedUrl, path, and error or error\n *\n * @example Create Signed URLs\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .createSignedUrls(['folder/avatar1.png', 'folder/avatar2.png'], 60)\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": [\n * {\n * \"error\": null,\n * \"path\": \"folder/avatar1.png\",\n * \"signedURL\": \"/object/sign/avatars/folder/avatar1.png?token=<TOKEN>\",\n * \"signedUrl\": \"https://example.supabase.co/storage/v1/object/sign/avatars/folder/avatar1.png?token=<TOKEN>\"\n * },\n * {\n * \"error\": null,\n * \"path\": \"folder/avatar2.png\",\n * \"signedURL\": \"/object/sign/avatars/folder/avatar2.png?token=<TOKEN>\",\n * \"signedUrl\": \"https://example.supabase.co/storage/v1/object/sign/avatars/folder/avatar2.png?token=<TOKEN>\"\n * }\n * ],\n * \"error\": null\n * }\n * ```\n */\n async createSignedUrls(\n paths: string[],\n expiresIn: number,\n options?: { download: string | boolean }\n ): Promise<\n | {\n data: { error: string | null; path: string | null; signedUrl: string }[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/object/sign/${this.bucketId}`,\n { expiresIn, paths },\n { headers: this.headers }\n )\n\n const downloadQueryParam = options?.download\n ? `&download=${options.download === true ? '' : options.download}`\n : ''\n return {\n data: data.map((datum: { signedURL: string }) => ({\n ...datum,\n signedUrl: datum.signedURL\n ? encodeURI(`${this.url}${datum.signedURL}${downloadQueryParam}`)\n : null,\n })),\n error: null,\n }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Downloads a file from a private bucket. For public buckets, make a request to the URL returned from `getPublicUrl` instead.\n *\n * @category File Buckets\n * @param path The full path and file name of the file to be downloaded. For example `folder/image.png`.\n * @param options.transform Transform the asset before serving it to the client.\n * @returns BlobDownloadBuilder instance for downloading the file\n *\n * @example Download file\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .download('folder/avatar1.png')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": <BLOB>,\n * \"error\": null\n * }\n * ```\n *\n * @example Download file with transformations\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .download('folder/avatar1.png', {\n * transform: {\n * width: 100,\n * height: 100,\n * quality: 80\n * }\n * })\n * ```\n */\n download<Options extends { transform?: TransformOptions }>(\n path: string,\n options?: Options\n ): BlobDownloadBuilder {\n const wantsTransformation = typeof options?.transform !== 'undefined'\n const renderPath = wantsTransformation ? 'render/image/authenticated' : 'object'\n const transformationQuery = this.transformOptsToQueryString(options?.transform || {})\n const queryString = transformationQuery ? `?${transformationQuery}` : ''\n const _path = this._getFinalPath(path)\n const downloadFn = () =>\n get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString}`, {\n headers: this.headers,\n noResolveJson: true,\n })\n return new BlobDownloadBuilder(downloadFn, this.shouldThrowOnError)\n }\n\n /**\n * Retrieves the details of an existing file.\n *\n * @category File Buckets\n * @param path The file path, including the file name. For example `folder/image.png`.\n * @returns Promise with response containing file metadata or error\n *\n * @example Get file info\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .info('folder/avatar1.png')\n * ```\n */\n async info(path: string): Promise<\n | {\n data: Camelize<FileObjectV2>\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n const _path = this._getFinalPath(path)\n\n try {\n const data = await get(this.fetch, `${this.url}/object/info/${_path}`, {\n headers: this.headers,\n })\n\n return { data: recursiveToCamel(data) as Camelize<FileObjectV2>, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Checks the existence of a file.\n *\n * @category File Buckets\n * @param path The file path, including the file name. For example `folder/image.png`.\n * @returns Promise with response containing boolean indicating file existence or error\n *\n * @example Check file existence\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .exists('folder/avatar1.png')\n * ```\n */\n async exists(path: string): Promise<\n | {\n data: boolean\n error: null\n }\n | {\n data: boolean\n error: StorageError\n }\n > {\n const _path = this._getFinalPath(path)\n\n try {\n await head(this.fetch, `${this.url}/object/${_path}`, {\n headers: this.headers,\n })\n\n return { data: true, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error) && error instanceof StorageUnknownError) {\n const originalError = error.originalError as unknown as { status: number }\n\n if ([400, 404].includes(originalError?.status)) {\n return { data: false, error }\n }\n }\n\n throw error\n }\n }\n\n /**\n * A simple convenience function 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.\n * This function does not verify if the bucket is public. If a public URL is created for a bucket which is not public, you will not be able to download the asset.\n *\n * @category File Buckets\n * @param path The path and name of the file to generate the public URL for. For example `folder/image.png`.\n * @param options.download Triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename.\n * @param options.transform Transform the asset before serving it to the client.\n * @returns Object with public URL\n *\n * @example Returns the URL for an asset in a public bucket\n * ```js\n * const { data } = supabase\n * .storage\n * .from('public-bucket')\n * .getPublicUrl('folder/avatar1.png')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"publicUrl\": \"https://example.supabase.co/storage/v1/object/public/public-bucket/folder/avatar1.png\"\n * }\n * }\n * ```\n *\n * @example Returns the URL for an asset in a public bucket with transformations\n * ```js\n * const { data } = supabase\n * .storage\n * .from('public-bucket')\n * .getPublicUrl('folder/avatar1.png', {\n * transform: {\n * width: 100,\n * height: 100,\n * }\n * })\n * ```\n *\n * @example Returns the URL which triggers the download of an asset in a public bucket\n * ```js\n * const { data } = supabase\n * .storage\n * .from('public-bucket')\n * .getPublicUrl('folder/avatar1.png', {\n * download: true,\n * })\n * ```\n */\n getPublicUrl(\n path: string,\n options?: { download?: string | boolean; transform?: TransformOptions }\n ): { data: { publicUrl: string } } {\n const _path = this._getFinalPath(path)\n const _queryString: string[] = []\n\n const downloadQueryParam = options?.download\n ? `download=${options.download === true ? '' : options.download}`\n : ''\n\n if (downloadQueryParam !== '') {\n _queryString.push(downloadQueryParam)\n }\n\n const wantsTransformation = typeof options?.transform !== 'undefined'\n const renderPath = wantsTransformation ? 'render/image' : 'object'\n const transformationQuery = this.transformOptsToQueryString(options?.transform || {})\n\n if (transformationQuery !== '') {\n _queryString.push(transformationQuery)\n }\n\n let queryString = _queryString.join('&')\n if (queryString !== '') {\n queryString = `?${queryString}`\n }\n\n return {\n data: { publicUrl: encodeURI(`${this.url}/${renderPath}/public/${_path}${queryString}`) },\n }\n }\n\n /**\n * Deletes files within the same bucket\n *\n * @category File Buckets\n * @param paths An array of files to delete, including the path and file name. For example [`'folder/image.png'`].\n * @returns Promise with response containing array of deleted file objects or error\n *\n * @example Delete file\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .remove(['folder/avatar1.png'])\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": [],\n * \"error\": null\n * }\n * ```\n */\n async remove(paths: string[]): Promise<\n | {\n data: FileObject[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await remove(\n this.fetch,\n `${this.url}/object/${this.bucketId}`,\n { prefixes: paths },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Get file metadata\n * @param id the file id to retrieve metadata\n */\n // async getMetadata(\n // id: string\n // ): Promise<\n // | {\n // data: Metadata\n // error: null\n // }\n // | {\n // data: null\n // error: StorageError\n // }\n // > {\n // try {\n // const data = await get(this.fetch, `${this.url}/metadata/${id}`, { headers: this.headers })\n // return { data, error: null }\n // } catch (error) {\n // if (isStorageError(error)) {\n // return { data: null, error }\n // }\n\n // throw error\n // }\n // }\n\n /**\n * Update file metadata\n * @param id the file id to update metadata\n * @param meta the new file metadata\n */\n // async updateMetadata(\n // id: string,\n // meta: Metadata\n // ): Promise<\n // | {\n // data: Metadata\n // error: null\n // }\n // | {\n // data: null\n // error: StorageError\n // }\n // > {\n // try {\n // const data = await post(\n // this.fetch,\n // `${this.url}/metadata/${id}`,\n // { ...meta },\n // { headers: this.headers }\n // )\n // return { data, error: null }\n // } catch (error) {\n // if (isStorageError(error)) {\n // return { data: null, error }\n // }\n\n // throw error\n // }\n // }\n\n /**\n * Lists all the files and folders within a path of the bucket.\n *\n * @category File Buckets\n * @param path The folder path.\n * @param options Search options including limit (defaults to 100), offset, sortBy, and search\n * @param parameters Optional fetch parameters including signal for cancellation\n * @returns Promise with response containing array of files or error\n *\n * @example List files in a bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .list('folder', {\n * limit: 100,\n * offset: 0,\n * sortBy: { column: 'name', order: 'asc' },\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": [\n * {\n * \"name\": \"avatar1.png\",\n * \"id\": \"e668cf7f-821b-4a2f-9dce-7dfa5dd1cfd2\",\n * \"updated_at\": \"2024-05-22T23:06:05.580Z\",\n * \"created_at\": \"2024-05-22T23:04:34.443Z\",\n * \"last_accessed_at\": \"2024-05-22T23:04:34.443Z\",\n * \"metadata\": {\n * \"eTag\": \"\\\"c5e8c553235d9af30ef4f6e280790b92\\\"\",\n * \"size\": 32175,\n * \"mimetype\": \"image/png\",\n * \"cacheControl\": \"max-age=3600\",\n * \"lastModified\": \"2024-05-22T23:06:05.574Z\",\n * \"contentLength\": 32175,\n * \"httpStatusCode\": 200\n * }\n * }\n * ],\n * \"error\": null\n * }\n * ```\n *\n * @example Search files in a bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .from('avatars')\n * .list('folder', {\n * limit: 100,\n * offset: 0,\n * sortBy: { column: 'name', order: 'asc' },\n * search: 'jon'\n * })\n * ```\n */\n async list(\n path?: string,\n options?: SearchOptions,\n parameters?: FetchParameters\n ): Promise<\n | {\n data: FileObject[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const body = { ...DEFAULT_SEARCH_OPTIONS, ...options, prefix: path || '' }\n const data = await post(\n this.fetch,\n `${this.url}/object/list/${this.bucketId}`,\n body,\n { headers: this.headers },\n parameters\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * @experimental this method signature might change in the future\n *\n * @category File Buckets\n * @param options search options\n * @param parameters\n */\n async listV2(\n options?: SearchV2Options,\n parameters?: FetchParameters\n ): Promise<\n | {\n data: SearchV2Result\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const body = { ...options }\n const data = await post(\n this.fetch,\n `${this.url}/object/list-v2/${this.bucketId}`,\n body,\n { headers: this.headers },\n parameters\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n protected encodeMetadata(metadata: Record<string, any>) {\n return JSON.stringify(metadata)\n }\n\n toBase64(data: string) {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(data).toString('base64')\n }\n return btoa(data)\n }\n\n private _getFinalPath(path: string) {\n return `${this.bucketId}/${path.replace(/^\\/+/, '')}`\n }\n\n private _removeEmptyFolders(path: string) {\n return path.replace(/^\\/|\\/$/g, '').replace(/\\/+/g, '/')\n }\n\n private transformOptsToQueryString(transform: TransformOptions) {\n const params: string[] = []\n if (transform.width) {\n params.push(`width=${transform.width}`)\n }\n\n if (transform.height) {\n params.push(`height=${transform.height}`)\n }\n\n if (transform.resize) {\n params.push(`resize=${transform.resize}`)\n }\n\n if (transform.format) {\n params.push(`format=${transform.format}`)\n }\n\n if (transform.quality) {\n params.push(`quality=${transform.quality}`)\n }\n\n return params.join('&')\n }\n}\n","// Generated automatically during releases by scripts/update-version-files.ts\n// This file provides runtime access to the package version for:\n// - HTTP request headers (e.g., X-Client-Info header for API requests)\n// - Debugging and support (identifying which version is running)\n// - Telemetry and logging (version reporting in errors/analytics)\n// - Ensuring build artifacts match the published package version\nexport const version = '2.89.0'\n","import { version } from './version'\nexport const DEFAULT_HEADERS = {\n 'X-Client-Info': `storage-js/${version}`,\n}\n","import { DEFAULT_HEADERS } from '../lib/constants'\nimport { isStorageError, StorageError } from '../lib/errors'\nimport { Fetch, get, post, put, remove } from '../lib/fetch'\nimport { resolveFetch } from '../lib/helpers'\nimport { Bucket, BucketType, ListBucketOptions } from '../lib/types'\nimport { StorageClientOptions } from '../StorageClient'\n\nexport default class StorageBucketApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n constructor(\n url: string,\n headers: { [key: string]: string } = {},\n fetch?: Fetch,\n opts?: StorageClientOptions\n ) {\n const baseUrl = new URL(url)\n\n // if legacy uri is used, replace with new storage host (disables request buffering to allow > 50GB uploads)\n // \"project-ref.supabase.co\" becomes \"project-ref.storage.supabase.co\"\n if (opts?.useNewHostname) {\n const isSupabaseHost = /supabase\\.(co|in|red)$/.test(baseUrl.hostname)\n if (isSupabaseHost && !baseUrl.hostname.includes('storage.supabase.')) {\n baseUrl.hostname = baseUrl.hostname.replace('supabase.', 'storage.supabase.')\n }\n }\n\n this.url = baseUrl.href.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /**\n * Enable throwing errors instead of returning them.\n *\n * @category File Buckets\n */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /**\n * Retrieves the details of all Storage buckets within an existing project.\n *\n * @category File Buckets\n * @param options Query parameters for listing buckets\n * @param options.limit Maximum number of buckets to return\n * @param options.offset Number of buckets to skip\n * @param options.sortColumn Column to sort by ('id', 'name', 'created_at', 'updated_at')\n * @param options.sortOrder Sort order ('asc' or 'desc')\n * @param options.search Search term to filter bucket names\n * @returns Promise with response containing array of buckets or error\n *\n * @example List buckets\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .listBuckets()\n * ```\n *\n * @example List buckets with options\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .listBuckets({\n * limit: 10,\n * offset: 0,\n * sortColumn: 'created_at',\n * sortOrder: 'desc',\n * search: 'prod'\n * })\n * ```\n */\n async listBuckets(options?: ListBucketOptions): Promise<\n | {\n data: Bucket[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const queryString = this.listBucketOptionsToQueryString(options)\n const data = await get(this.fetch, `${this.url}/bucket${queryString}`, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Retrieves the details of an existing Storage bucket.\n *\n * @category File Buckets\n * @param id The unique identifier of the bucket you would like to retrieve.\n * @returns Promise with response containing bucket details or error\n *\n * @example Get bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .getBucket('avatars')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"id\": \"avatars\",\n * \"name\": \"avatars\",\n * \"owner\": \"\",\n * \"public\": false,\n * \"file_size_limit\": 1024,\n * \"allowed_mime_types\": [\n * \"image/png\"\n * ],\n * \"created_at\": \"2024-05-22T22:26:05.100Z\",\n * \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async getBucket(id: string): Promise<\n | {\n data: Bucket\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await get(this.fetch, `${this.url}/bucket/${id}`, { headers: this.headers })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Creates a new Storage bucket\n *\n * @category File Buckets\n * @param id A unique identifier for the bucket you are creating.\n * @param 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.\n * @param options.fileSizeLimit specifies the max file size in bytes that can be uploaded to this bucket.\n * The global file size limit takes precedence over this value.\n * The default value is null, which doesn't set a per bucket file size limit.\n * @param options.allowedMimeTypes specifies the allowed mime types that this bucket can accept during upload.\n * The default value is null, which allows files with all mime types to be uploaded.\n * Each mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png.\n * @param options.type (private-beta) specifies the bucket type. see `BucketType` for more details.\n * - default bucket type is `STANDARD`\n * @returns Promise with response containing newly created bucket name or error\n *\n * @example Create bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .createBucket('avatars', {\n * public: false,\n * allowedMimeTypes: ['image/png'],\n * fileSizeLimit: 1024\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"name\": \"avatars\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async createBucket(\n id: string,\n options: {\n public: boolean\n fileSizeLimit?: number | string | null\n allowedMimeTypes?: string[] | null\n type?: BucketType\n } = {\n public: false,\n }\n ): Promise<\n | {\n data: Pick<Bucket, 'name'>\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/bucket`,\n {\n id,\n name: id,\n type: options.type,\n public: options.public,\n file_size_limit: options.fileSizeLimit,\n allowed_mime_types: options.allowedMimeTypes,\n },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Updates a Storage bucket\n *\n * @category File Buckets\n * @param id A unique identifier for the bucket you are updating.\n * @param 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.\n * @param options.fileSizeLimit specifies the max file size in bytes that can be uploaded to this bucket.\n * The global file size limit takes precedence over this value.\n * The default value is null, which doesn't set a per bucket file size limit.\n * @param options.allowedMimeTypes specifies the allowed mime types that this bucket can accept during upload.\n * The default value is null, which allows files with all mime types to be uploaded.\n * Each mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png.\n * @returns Promise with response containing success message or error\n *\n * @example Update bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .updateBucket('avatars', {\n * public: false,\n * allowedMimeTypes: ['image/png'],\n * fileSizeLimit: 1024\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully updated\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async updateBucket(\n id: string,\n options: {\n public: boolean\n fileSizeLimit?: number | string | null\n allowedMimeTypes?: string[] | null\n }\n ): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await put(\n this.fetch,\n `${this.url}/bucket/${id}`,\n {\n id,\n name: id,\n public: options.public,\n file_size_limit: options.fileSizeLimit,\n allowed_mime_types: options.allowedMimeTypes,\n },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Removes all objects inside a single bucket.\n *\n * @category File Buckets\n * @param id The unique identifier of the bucket you would like to empty.\n * @returns Promise with success message or error\n *\n * @example Empty bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .emptyBucket('avatars')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully emptied\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async emptyBucket(id: string): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/bucket/${id}/empty`,\n {},\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * Deletes an existing bucket. A bucket can't be deleted with existing objects inside it.\n * You must first `empty()` the bucket.\n *\n * @category File Buckets\n * @param id The unique identifier of the bucket you would like to delete.\n * @returns Promise with success message or error\n *\n * @example Delete bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .deleteBucket('avatars')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully deleted\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async deleteBucket(id: string): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await remove(\n this.fetch,\n `${this.url}/bucket/${id}`,\n {},\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n private listBucketOptionsToQueryString(options?: ListBucketOptions): string {\n const params: Record<string, string> = {}\n if (options) {\n if ('limit' in options) {\n params.limit = String(options.limit)\n }\n if ('offset' in options) {\n params.offset = String(options.offset)\n }\n if (options.search) {\n params.search = options.search\n }\n if (options.sortColumn) {\n params.sortColumn = options.sortColumn\n }\n if (options.sortOrder) {\n params.sortOrder = options.sortOrder\n }\n }\n return Object.keys(params).length > 0 ? '?' + new URLSearchParams(params).toString() : ''\n }\n}\n","import { IcebergRestCatalog, IcebergError } from 'iceberg-js'\nimport { DEFAULT_HEADERS } from '../lib/constants'\nimport { isStorageError, StorageError } from '../lib/errors'\nimport { Fetch, get, post, remove } from '../lib/fetch'\nimport { isValidBucketName, resolveFetch } from '../lib/helpers'\nimport { AnalyticBucket } from '../lib/types'\n\ntype WrapAsyncMethod<T> = T extends (...args: infer A) => Promise<infer R>\n ? (...args: A) => Promise<{ data: R; error: null } | { data: null; error: IcebergError }>\n : T\n\nexport type WrappedIcebergRestCatalog = {\n [K in keyof IcebergRestCatalog]: WrapAsyncMethod<IcebergRestCatalog[K]>\n}\n\n/**\n * Client class for managing Analytics Buckets using Iceberg tables\n * Provides methods for creating, listing, and deleting analytics buckets\n */\nexport default class StorageAnalyticsClient {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n /**\n * @alpha\n *\n * Creates a new StorageAnalyticsClient instance\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param url - The base URL for the storage API\n * @param headers - HTTP headers to include in requests\n * @param fetch - Optional custom fetch implementation\n *\n * @example\n * ```typescript\n * const client = new StorageAnalyticsClient(url, headers)\n * ```\n */\n constructor(url: string, headers: { [key: string]: string } = {}, fetch?: Fetch) {\n this.url = url.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /**\n * @alpha\n *\n * Enable throwing errors instead of returning them in the response\n * When enabled, failed operations will throw instead of returning { data: null, error }\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @returns This instance for method chaining\n */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /**\n * @alpha\n *\n * Creates a new analytics bucket using Iceberg tables\n * Analytics buckets are optimized for analytical queries and data processing\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param name A unique name for the bucket you are creating\n * @returns Promise with response containing newly created analytics bucket or error\n *\n * @example Create analytics bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .analytics\n * .createBucket('analytics-data')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"name\": \"analytics-data\",\n * \"type\": \"ANALYTICS\",\n * \"format\": \"iceberg\",\n * \"created_at\": \"2024-05-22T22:26:05.100Z\",\n * \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async createBucket(name: string): Promise<\n | {\n data: AnalyticBucket\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await post(this.fetch, `${this.url}/bucket`, { name }, { headers: this.headers })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * @alpha\n *\n * Retrieves the details of all Analytics Storage buckets within an existing project\n * Only returns buckets of type 'ANALYTICS'\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param options Query parameters for listing buckets\n * @param options.limit Maximum number of buckets to return\n * @param options.offset Number of buckets to skip\n * @param options.sortColumn Column to sort by ('name', 'created_at', 'updated_at')\n * @param options.sortOrder Sort order ('asc' or 'desc')\n * @param options.search Search term to filter bucket names\n * @returns Promise with response containing array of analytics buckets or error\n *\n * @example List analytics buckets\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .analytics\n * .listBuckets({\n * limit: 10,\n * offset: 0,\n * sortColumn: 'created_at',\n * sortOrder: 'desc'\n * })\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": [\n * {\n * \"name\": \"analytics-data\",\n * \"type\": \"ANALYTICS\",\n * \"format\": \"iceberg\",\n * \"created_at\": \"2024-05-22T22:26:05.100Z\",\n * \"updated_at\": \"2024-05-22T22:26:05.100Z\"\n * }\n * ],\n * \"error\": null\n * }\n * ```\n */\n async listBuckets(options?: {\n limit?: number\n offset?: number\n sortColumn?: 'name' | 'created_at' | 'updated_at'\n sortOrder?: 'asc' | 'desc'\n search?: string\n }): Promise<\n | {\n data: AnalyticBucket[]\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n // Build query string from options\n const queryParams = new URLSearchParams()\n if (options?.limit !== undefined) queryParams.set('limit', options.limit.toString())\n if (options?.offset !== undefined) queryParams.set('offset', options.offset.toString())\n if (options?.sortColumn) queryParams.set('sortColumn', options.sortColumn)\n if (options?.sortOrder) queryParams.set('sortOrder', options.sortOrder)\n if (options?.search) queryParams.set('search', options.search)\n\n const queryString = queryParams.toString()\n const url = queryString ? `${this.url}/bucket?${queryString}` : `${this.url}/bucket`\n\n const data = await get(this.fetch, url, { headers: this.headers })\n\n return { data: data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * @alpha\n *\n * Deletes an existing analytics bucket\n * A bucket can't be deleted with existing objects inside it\n * You must first empty the bucket before deletion\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param bucketName The unique identifier of the bucket you would like to delete\n * @returns Promise with response containing success message or error\n *\n * @example Delete analytics bucket\n * ```js\n * const { data, error } = await supabase\n * .storage\n * .analytics\n * .deleteBucket('analytics-data')\n * ```\n *\n * Response:\n * ```json\n * {\n * \"data\": {\n * \"message\": \"Successfully deleted\"\n * },\n * \"error\": null\n * }\n * ```\n */\n async deleteBucket(bucketName: string): Promise<\n | {\n data: { message: string }\n error: null\n }\n | {\n data: null\n error: StorageError\n }\n > {\n try {\n const data = await remove(\n this.fetch,\n `${this.url}/bucket/${bucketName}`,\n {},\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageError(error)) {\n return { data: null, error }\n }\n\n throw error\n }\n }\n\n /**\n * @alpha\n *\n * Get an Iceberg REST Catalog client configured for a specific analytics bucket\n * Use this to perform advanced table and namespace operations within the bucket\n * The returned client provides full access to the Apache Iceberg REST Catalog API\n * with the Supabase `{ data, error }` pattern for consistent error handling on all operations.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @param bucketName - The name of the analytics bucket (warehouse) to connect to\n * @returns The wrapped Iceberg catalog client\n * @throws {StorageError} If the bucket name is invalid\n *\n * @example Get catalog and create table\n * ```js\n * // First, create an analytics bucket\n * const { data: bucket, error: bucketError } = await supabase\n * .storage\n * .analytics\n * .createBucket('analytics-data')\n *\n * // Get the Iceberg catalog for that bucket\n * const catalog = supabase.storage.analytics.from('analytics-data')\n *\n * // Create a namespace\n * const { error: nsError } = await catalog.createNamespace({ namespace: ['default'] })\n *\n * // Create a table with schema\n * const { data: tableMetadata, error: tableError } = await catalog.createTable(\n * { namespace: ['default'] },\n * {\n * name: 'events',\n * schema: {\n * type: 'struct',\n * fields: [\n * { id: 1, name: 'id', type: 'long', required: true },\n * { id: 2, name: 'timestamp', type: 'timestamp', required: true },\n * { id: 3, name: 'user_id', type: 'string', required: false }\n * ],\n * 'schema-id': 0,\n * 'identifier-field-ids': [1]\n * },\n * 'partition-spec': {\n * 'spec-id': 0,\n * fields: []\n * },\n * 'write-order': {\n * 'order-id': 0,\n * fields: []\n * },\n * properties: {\n * 'write.format.default': 'parquet'\n * }\n * }\n * )\n * ```\n *\n * @example List tables in namespace\n * ```js\n * const catalog = supabase.storage.analytics.from('analytics-data')\n *\n * // List all tables in the default namespace\n * const { data: tables, error: listError } = await catalog.listTables({ namespace: ['default'] })\n * if (listError) {\n * if (listError.isNotFound()) {\n * console.log('Namespace not found')\n * }\n * return\n * }\n * console.log(tables) // [{ namespace: ['default'], name: 'events' }]\n * ```\n *\n * @example Working with namespaces\n * ```js\n * const catalog = supabase.storage.analytics.from('analytics-data')\n *\n * // List all namespaces\n * const { data: namespaces } = await catalog.listNamespaces()\n *\n * // Create namespace with properties\n * await catalog.createNamespace(\n * { namespace: ['production'] },\n * { properties: { owner: 'data-team', env: 'prod' } }\n * )\n * ```\n *\n * @example Cleanup operations\n * ```js\n * const catalog = supabase.storage.analytics.from('analytics-data')\n *\n * // Drop table with purge option (removes all data)\n * const { error: dropError } = await catalog.dropTable(\n * { namespace: ['default'], name: 'events' },\n * { purge: true }\n * )\n *\n * if (dropError?.isNotFound()) {\n * console.log('Table does not exist')\n * }\n *\n * // Drop namespace (must be empty)\n * await catalog.dropNamespace({ namespace: ['default'] })\n * ```\n *\n * @remarks\n * This method provides a bridge between Supabase's bucket management and the standard\n * Apache Iceberg REST Catalog API. The bucket name maps to the Iceberg warehouse parameter.\n * All authentication and configuration is handled automatically using your Supabase credentials.\n *\n * **Error Handling**: Invalid bucket names throw immediately. All catalog\n * operations return `{ data, error }` where errors are `IcebergError` instances from iceberg-js.\n * Use helper methods like `error.isNotFound()` or check `error.status` for specific error handling.\n * Use `.throwOnError()` on the analytics client if you prefer exceptions for catalog operations.\n *\n * **Cleanup Operations**: When using `dropTable`, the `purge: true` option permanently\n * deletes all table data. Without it, the table is marked as deleted but data remains.\n *\n * **Library Dependency**: The returned catalog wraps `IcebergRestCatalog` from iceberg-js.\n * For complete API documentation and advanced usage, refer to the\n * [iceberg-js documentation](https://supabase.github.io/iceberg-js/).\n */\n from(bucketName: string): WrappedIcebergRestCatalog {\n // Validate bucket name using same rules as Supabase Storage API backend\n if (!isValidBucketName(bucketName)) {\n throw new StorageError(\n 'Invalid bucket name: File, folder, and bucket names must follow AWS object key naming guidelines ' +\n 'and should avoid the use of any other characters.'\n )\n }\n\n // Construct the Iceberg REST Catalog URL\n // The base URL is /storage/v1/iceberg\n // Note: IcebergRestCatalog from iceberg-js automatically adds /v1/ prefix to API paths\n // so we should NOT append /v1 here (it would cause double /v1/v1/ in the URL)\n const catalog = new IcebergRestCatalog({\n baseUrl: this.url,\n catalogName: bucketName, // Maps to the warehouse parameter in Supabase's implementation\n auth: {\n type: 'custom',\n getHeaders: async () => this.headers,\n },\n fetch: this.fetch,\n })\n\n const shouldThrowOnError = this.shouldThrowOnError\n\n const wrappedCatalog = new Proxy(catalog, {\n get(target, prop: keyof IcebergRestCatalog) {\n const value = target[prop]\n if (typeof value !== 'function') {\n return value\n }\n\n return async (...args: unknown[]) => {\n try {\n const data = await (value as Function).apply(target, args)\n return { data, error: null }\n } catch (error) {\n if (shouldThrowOnError) {\n throw error\n }\n return { data: null, error: error as IcebergError }\n }\n }\n },\n }) as unknown as WrappedIcebergRestCatalog\n\n return wrappedCatalog\n }\n}\n","import { version } from '../version'\nexport const DEFAULT_HEADERS = {\n 'X-Client-Info': `storage-js/${version}`,\n 'Content-Type': 'application/json',\n}\n","/**\n * Base error class for all Storage Vectors errors\n */\nexport class StorageVectorsError extends Error {\n protected __isStorageVectorsError = true\n\n constructor(message: string) {\n super(message)\n this.name = 'StorageVectorsError'\n }\n}\n\n/**\n * Type guard to check if an error is a StorageVectorsError\n * @param error - The error to check\n * @returns True if the error is a StorageVectorsError\n */\nexport function isStorageVectorsError(error: unknown): error is StorageVectorsError {\n return typeof error === 'object' && error !== null && '__isStorageVectorsError' in error\n}\n\n/**\n * API error returned from S3 Vectors service\n * Includes HTTP status code and service-specific error code\n */\nexport class StorageVectorsApiError extends StorageVectorsError {\n status: number\n statusCode: string\n\n constructor(message: string, status: number, statusCode: string) {\n super(message)\n this.name = 'StorageVectorsApiError'\n this.status = status\n this.statusCode = statusCode\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n status: this.status,\n statusCode: this.statusCode,\n }\n }\n}\n\n/**\n * Unknown error that doesn't match expected error patterns\n * Wraps the original error for debugging\n */\nexport class StorageVectorsUnknownError extends StorageVectorsError {\n originalError: unknown\n\n constructor(message: string, originalError: unknown) {\n super(message)\n this.name = 'StorageVectorsUnknownError'\n this.originalError = originalError\n }\n}\n\n/**\n * Error codes specific to S3 Vectors API\n * Maps AWS service errors to application-friendly error codes\n */\nexport enum StorageVectorsErrorCode {\n /** Internal server fault (HTTP 500) */\n InternalError = 'InternalError',\n /** Resource already exists / conflict (HTTP 409) */\n S3VectorConflictException = 'S3VectorConflictException',\n /** Resource not found (HTTP 404) */\n S3VectorNotFoundException = 'S3VectorNotFoundException',\n /** Delete bucket while not empty (HTTP 400) */\n S3VectorBucketNotEmpty = 'S3VectorBucketNotEmpty',\n /** Exceeds bucket quota/limit (HTTP 400) */\n S3VectorMaxBucketsExceeded = 'S3VectorMaxBucketsExceeded',\n /** Exceeds index quota/limit (HTTP 400) */\n S3VectorMaxIndexesExceeded = 'S3VectorMaxIndexesExceeded',\n}\n","type Fetch = typeof fetch\n\n/**\n * Resolves the fetch implementation to use\n * Uses custom fetch if provided, otherwise uses native fetch\n *\n * @param customFetch - Optional custom fetch implementation\n * @returns Resolved fetch function\n */\nexport const resolveFetch = (customFetch?: Fetch): Fetch => {\n if (customFetch) {\n return (...args) => customFetch(...args)\n }\n return (...args) => fetch(...args)\n}\n\n/**\n * Resolves the Response constructor to use\n * Returns native Response constructor\n *\n * @returns Response constructor\n */\nexport const resolveResponse = (): typeof Response => {\n return Response\n}\n\n/**\n * Determine if input is a plain object\n * An object is plain if it's created by either {}, new Object(), or Object.create(null)\n *\n * @param value - Value to check\n * @returns True if value is a plain object\n * @source https://github.com/sindresorhus/is-plain-obj\n */\nexport const isPlainObject = (value: object): boolean => {\n if (typeof value !== 'object' || value === null) {\n return false\n }\n\n const prototype = Object.getPrototypeOf(value)\n return (\n (prototype === null ||\n prototype === Object.prototype ||\n Object.getPrototypeOf(prototype) === null) &&\n !(Symbol.toStringTag in value) &&\n !(Symbol.iterator in value)\n )\n}\n\n/**\n * Normalizes a number array to float32 format\n * Ensures all vector values are valid 32-bit floats\n *\n * @param values - Array of numbers to normalize\n * @returns Normalized float32 array\n */\nexport const normalizeToFloat32 = (values: number[]): number[] => {\n // Use Float32Array to ensure proper precision\n return Array.from(new Float32Array(values))\n}\n\n/**\n * Validates vector dimensions match expected dimension\n * Throws error if dimensions don't match\n *\n * @param vector - Vector data to validate\n * @param expectedDimension - Expected vector dimension\n * @throws Error if dimensions don't match\n */\nexport const validateVectorDimension = (\n vector: { float32: number[] },\n expectedDimension?: number\n): void => {\n if (expectedDimension !== undefined && vector.float32.length !== expectedDimension) {\n throw new Error(\n `Vector dimension mismatch: expected ${expectedDimension}, got ${vector.float32.length}`\n )\n }\n}\n","import { StorageVectorsApiError, StorageVectorsUnknownError } from './errors'\nimport { isPlainObject, resolveResponse } from './helpers'\nimport { VectorFetchParameters } from './types'\n\nexport type Fetch = typeof fetch\n\n/**\n * Options for fetch requests\n * @property headers - Custom HTTP headers\n * @property noResolveJson - If true, return raw Response instead of parsing JSON\n */\nexport interface FetchOptions {\n headers?: {\n [key: string]: string\n }\n noResolveJson?: boolean\n}\n\n/**\n * HTTP methods supported by the API\n */\nexport type RequestMethodType = 'GET' | 'POST' | 'PUT' | 'DELETE'\n\n/**\n * Extracts error message from various error response formats\n * @param err - Error object from API\n * @returns Human-readable error message\n */\nconst _getErrorMessage = (err: any): string =>\n err.msg || err.message || err.error_description || err.error || JSON.stringify(err)\n\n/**\n * Handles fetch errors and converts them to StorageVectors error types\n * @param error - The error caught from fetch\n * @param reject - Promise rejection function\n * @param options - Fetch options that may affect error handling\n */\nconst handleError = async (\n error: unknown,\n reject: (reason?: any) => void,\n options?: FetchOptions\n) => {\n // Check if error is a Response-like object (has status and ok properties)\n // This is more reliable than instanceof which can fail across realms\n const isResponseLike =\n error &&\n typeof error === 'object' &&\n 'status' in error &&\n 'ok' in error &&\n typeof (error as any).status === 'number'\n\n if (isResponseLike && !options?.noResolveJson) {\n const status = (error as any).status || 500\n const responseError = error as any\n\n // Try to parse JSON body if available\n if (typeof responseError.json === 'function') {\n responseError\n .json()\n .then((err: any) => {\n const statusCode = err?.statusCode || err?.code || status + ''\n reject(new StorageVectorsApiError(_getErrorMessage(err), status, statusCode))\n })\n .catch(() => {\n // If JSON parsing fails, create an ApiError with the HTTP status code\n const statusCode = status + ''\n const message = responseError.statusText || `HTTP ${status} error`\n reject(new StorageVectorsApiError(message, status, statusCode))\n })\n } else {\n // No json() method available, create error from status\n const statusCode = status + ''\n const message = responseError.statusText || `HTTP ${status} error`\n reject(new StorageVectorsApiError(message, status, statusCode))\n }\n } else {\n reject(new StorageVectorsUnknownError(_getErrorMessage(error), error))\n }\n}\n\n/**\n * Builds request parameters for fetch calls\n * @param method - HTTP method\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters like AbortSignal\n * @param body - Request body (will be JSON stringified if plain object)\n * @returns Complete fetch request parameters\n */\nconst _getRequestParams = (\n method: RequestMethodType,\n options?: FetchOptions,\n parameters?: VectorFetchParameters,\n body?: object\n) => {\n const params: { [k: string]: any } = { method, headers: options?.headers || {} }\n\n if (method === 'GET' || !body) {\n return params\n }\n\n if (isPlainObject(body)) {\n params.headers = { 'Content-Type': 'application/json', ...options?.headers }\n params.body = JSON.stringify(body)\n } else {\n params.body = body\n }\n\n return { ...params, ...parameters }\n}\n\n/**\n * Internal request handler that wraps fetch with error handling\n * @param fetcher - Fetch function to use\n * @param method - HTTP method\n * @param url - Request URL\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @param body - Request body\n * @returns Promise with parsed response or error\n */\nasync function _handleRequest(\n fetcher: Fetch,\n method: RequestMethodType,\n url: string,\n options?: FetchOptions,\n parameters?: VectorFetchParameters,\n body?: object\n): Promise<any> {\n return new Promise((resolve, reject) => {\n fetcher(url, _getRequestParams(method, options, parameters, body))\n .then((result) => {\n if (!result.ok) throw result\n if (options?.noResolveJson) return result\n // Handle empty responses (204, empty body)\n const contentType = result.headers.get('content-type')\n if (!contentType || !contentType.includes('application/json')) {\n return {}\n }\n return result.json()\n })\n .then((data) => resolve(data))\n .catch((error) => handleError(error, reject, options))\n })\n}\n\n/**\n * Performs a GET request\n * @param fetcher - Fetch function to use\n * @param url - Request URL\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @returns Promise with parsed response\n */\nexport async function get(\n fetcher: Fetch,\n url: string,\n options?: FetchOptions,\n parameters?: VectorFetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'GET', url, options, parameters)\n}\n\n/**\n * Performs a POST request\n * @param fetcher - Fetch function to use\n * @param url - Request URL\n * @param body - Request body to be JSON stringified\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @returns Promise with parsed response\n */\nexport async function post(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: VectorFetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'POST', url, options, parameters, body)\n}\n\n/**\n * Performs a PUT request\n * @param fetcher - Fetch function to use\n * @param url - Request URL\n * @param body - Request body to be JSON stringified\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @returns Promise with parsed response\n */\nexport async function put(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: VectorFetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'PUT', url, options, parameters, body)\n}\n\n/**\n * Performs a DELETE request\n * @param fetcher - Fetch function to use\n * @param url - Request URL\n * @param body - Request body to be JSON stringified\n * @param options - Custom fetch options\n * @param parameters - Additional fetch parameters\n * @returns Promise with parsed response\n */\nexport async function remove(\n fetcher: Fetch,\n url: string,\n body: object,\n options?: FetchOptions,\n parameters?: VectorFetchParameters\n): Promise<any> {\n return _handleRequest(fetcher, 'DELETE', url, options, parameters, body)\n}\n","import { DEFAULT_HEADERS } from './constants'\nimport { isStorageVectorsError } from './errors'\nimport { Fetch, post } from './fetch'\nimport { resolveFetch } from './helpers'\nimport {\n ApiResponse,\n VectorIndex,\n ListIndexesOptions,\n ListIndexesResponse,\n VectorDataType,\n DistanceMetric,\n MetadataConfiguration,\n} from './types'\n\n/**\n * @alpha\n *\n * Options for creating a vector index\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n */\nexport interface CreateIndexOptions {\n vectorBucketName: string\n indexName: string\n dataType: VectorDataType\n dimension: number\n distanceMetric: DistanceMetric\n metadataConfiguration?: MetadataConfiguration\n}\n\n/**\n * @hidden\n * Base implementation for vector index operations.\n * Use {@link VectorBucketScope} via `supabase.storage.vectors.from('bucket')` instead.\n */\nexport default class VectorIndexApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n /** Creates a new VectorIndexApi instance */\n constructor(url: string, headers: { [key: string]: string } = {}, fetch?: Fetch) {\n this.url = url.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /** Enable throwing errors instead of returning them in the response */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /** Creates a new vector index within a bucket */\n async createIndex(options: CreateIndexOptions): Promise<ApiResponse<undefined>> {\n try {\n const data = await post(this.fetch, `${this.url}/CreateIndex`, options, {\n headers: this.headers,\n })\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Retrieves metadata for a specific vector index */\n async getIndex(\n vectorBucketName: string,\n indexName: string\n ): Promise<ApiResponse<{ index: VectorIndex }>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/GetIndex`,\n { vectorBucketName, indexName },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Lists vector indexes within a bucket with optional filtering and pagination */\n async listIndexes(options: ListIndexesOptions): Promise<ApiResponse<ListIndexesResponse>> {\n try {\n const data = await post(this.fetch, `${this.url}/ListIndexes`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Deletes a vector index and all its data */\n async deleteIndex(vectorBucketName: string, indexName: string): Promise<ApiResponse<undefined>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/DeleteIndex`,\n { vectorBucketName, indexName },\n { headers: this.headers }\n )\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n}\n","import { DEFAULT_HEADERS } from './constants'\nimport { isStorageVectorsError } from './errors'\nimport { Fetch, post } from './fetch'\nimport { resolveFetch } from './helpers'\nimport {\n ApiResponse,\n PutVectorsOptions,\n GetVectorsOptions,\n GetVectorsResponse,\n DeleteVectorsOptions,\n ListVectorsOptions,\n ListVectorsResponse,\n QueryVectorsOptions,\n QueryVectorsResponse,\n} from './types'\n\n/**\n * @hidden\n * Base implementation for vector data operations.\n * Use {@link VectorIndexScope} via `supabase.storage.vectors.from('bucket').index('idx')` instead.\n */\nexport default class VectorDataApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n /** Creates a new VectorDataApi instance */\n constructor(url: string, headers: { [key: string]: string } = {}, fetch?: Fetch) {\n this.url = url.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /** Enable throwing errors instead of returning them in the response */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /** Inserts or updates vectors in batch (1-500 per request) */\n async putVectors(options: PutVectorsOptions): Promise<ApiResponse<undefined>> {\n try {\n // Validate batch size\n if (options.vectors.length < 1 || options.vectors.length > 500) {\n throw new Error('Vector batch size must be between 1 and 500 items')\n }\n\n const data = await post(this.fetch, `${this.url}/PutVectors`, options, {\n headers: this.headers,\n })\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Retrieves vectors by their keys in batch */\n async getVectors(options: GetVectorsOptions): Promise<ApiResponse<GetVectorsResponse>> {\n try {\n const data = await post(this.fetch, `${this.url}/GetVectors`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Lists vectors in an index with pagination */\n async listVectors(options: ListVectorsOptions): Promise<ApiResponse<ListVectorsResponse>> {\n try {\n // Validate segment configuration\n if (options.segmentCount !== undefined) {\n if (options.segmentCount < 1 || options.segmentCount > 16) {\n throw new Error('segmentCount must be between 1 and 16')\n }\n if (options.segmentIndex !== undefined) {\n if (options.segmentIndex < 0 || options.segmentIndex >= options.segmentCount) {\n throw new Error(`segmentIndex must be between 0 and ${options.segmentCount - 1}`)\n }\n }\n }\n\n const data = await post(this.fetch, `${this.url}/ListVectors`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Queries for similar vectors using approximate nearest neighbor search */\n async queryVectors(options: QueryVectorsOptions): Promise<ApiResponse<QueryVectorsResponse>> {\n try {\n const data = await post(this.fetch, `${this.url}/QueryVectors`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Deletes vectors by their keys in batch (1-500 per request) */\n async deleteVectors(options: DeleteVectorsOptions): Promise<ApiResponse<undefined>> {\n try {\n // Validate batch size\n if (options.keys.length < 1 || options.keys.length > 500) {\n throw new Error('Keys batch size must be between 1 and 500 items')\n }\n\n const data = await post(this.fetch, `${this.url}/DeleteVectors`, options, {\n headers: this.headers,\n })\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n}\n","import { DEFAULT_HEADERS } from './constants'\nimport { isStorageVectorsError } from './errors'\nimport { Fetch, post } from './fetch'\nimport { resolveFetch } from './helpers'\nimport {\n ApiResponse,\n VectorBucket,\n ListVectorBucketsOptions,\n ListVectorBucketsResponse,\n} from './types'\n\n/**\n * @hidden\n * Base implementation for vector bucket operations.\n * Use {@link StorageVectorsClient} via `supabase.storage.vectors` instead.\n */\nexport default class VectorBucketApi {\n protected url: string\n protected headers: { [key: string]: string }\n protected fetch: Fetch\n protected shouldThrowOnError = false\n\n /** Creates a new VectorBucketApi instance */\n constructor(url: string, headers: { [key: string]: string } = {}, fetch?: Fetch) {\n this.url = url.replace(/\\/$/, '')\n this.headers = { ...DEFAULT_HEADERS, ...headers }\n this.fetch = resolveFetch(fetch)\n }\n\n /** Enable throwing errors instead of returning them in the response */\n public throwOnError(): this {\n this.shouldThrowOnError = true\n return this\n }\n\n /** Creates a new vector bucket */\n async createBucket(vectorBucketName: string): Promise<ApiResponse<undefined>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/CreateVectorBucket`,\n { vectorBucketName },\n { headers: this.headers }\n )\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Retrieves metadata for a specific vector bucket */\n async getBucket(vectorBucketName: string): Promise<ApiResponse<{ vectorBucket: VectorBucket }>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/GetVectorBucket`,\n { vectorBucketName },\n { headers: this.headers }\n )\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Lists vector buckets with optional filtering and pagination */\n async listBuckets(\n options: ListVectorBucketsOptions = {}\n ): Promise<ApiResponse<ListVectorBucketsResponse>> {\n try {\n const data = await post(this.fetch, `${this.url}/ListVectorBuckets`, options, {\n headers: this.headers,\n })\n return { data, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n\n /** Deletes a vector bucket (must be empty first) */\n async deleteBucket(vectorBucketName: string): Promise<ApiResponse<undefined>> {\n try {\n const data = await post(\n this.fetch,\n `${this.url}/DeleteVectorBucket`,\n { vectorBucketName },\n { headers: this.headers }\n )\n return { data: data || {}, error: null }\n } catch (error) {\n if (this.shouldThrowOnError) {\n throw error\n }\n if (isStorageVectorsError(error)) {\n return { data: null, error }\n }\n throw error\n }\n }\n}\n","import VectorIndexApi, { CreateIndexOptions } from './VectorIndexApi'\nimport VectorDataApi from './VectorDataApi'\nimport { Fetch } from './fetch'\nimport VectorBucketApi from './VectorBucketApi'\nimport {\n ApiResponse,\n DeleteVectorsOptions,\n GetVectorsOptions,\n ListIndexesOptions,\n ListVectorsOptions,\n ListVectorBucketsOptions,\n ListVectorBucketsResponse,\n PutVectorsOptions,\n QueryVectorsOptions,\n VectorBucket,\n} from './types'\n\n/**\n *\n * @alpha\n *\n * Configuration options for the Storage Vectors client\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n */\nexport interface StorageVectorsClientOptions {\n /**\n * Custom headers to include in all requests\n */\n headers?: { [key: string]: string }\n /**\n * Custom fetch implementation (optional)\n * Useful for testing or custom request handling\n */\n fetch?: Fetch\n}\n\n/**\n *\n * @alpha\n *\n * Main client for interacting with S3 Vectors API\n * Provides access to bucket, index, and vector data operations\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * **Usage Patterns:**\n *\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .createBucket('embeddings-prod')\n *\n * // Access index operations via buckets\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * await bucket.createIndex({\n * indexName: 'documents',\n * dataType: 'float32',\n * dimension: 1536,\n * distanceMetric: 'cosine'\n * })\n *\n * // Access vector operations via index\n * const index = bucket.index('documents')\n * await index.putVectors({\n * vectors: [\n * { key: 'doc-1', data: { float32: [...] }, metadata: { title: 'Intro' } }\n * ]\n * })\n *\n * // Query similar vectors\n * const { data } = await index.queryVectors({\n * queryVector: { float32: [...] },\n * topK: 5,\n * returnDistance: true\n * })\n * ```\n */\nexport class StorageVectorsClient extends VectorBucketApi {\n /**\n * @alpha\n *\n * Creates a StorageVectorsClient that can manage buckets, indexes, and vectors.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param url - Base URL of the Storage Vectors REST API.\n * @param options.headers - Optional headers (for example `Authorization`) applied to every request.\n * @param options.fetch - Optional custom `fetch` implementation for non-browser runtimes.\n *\n * @example\n * ```typescript\n * const client = new StorageVectorsClient(url, options)\n * ```\n */\n constructor(url: string, options: StorageVectorsClientOptions = {}) {\n super(url, options.headers || {}, options.fetch)\n }\n\n /**\n *\n * @alpha\n *\n * Access operations for a specific vector bucket\n * Returns a scoped client for index and vector operations within the bucket\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param vectorBucketName - Name of the vector bucket\n * @returns Bucket-scoped client with index and vector operations\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * ```\n */\n from(vectorBucketName: string): VectorBucketScope {\n return new VectorBucketScope(this.url, this.headers, vectorBucketName, this.fetch)\n }\n\n /**\n *\n * @alpha\n *\n * Creates a new vector bucket\n * Vector buckets are containers for vector indexes and their data\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param vectorBucketName - Unique name for the vector bucket\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .createBucket('embeddings-prod')\n * ```\n */\n async createBucket(vectorBucketName: string): Promise<ApiResponse<undefined>> {\n return super.createBucket(vectorBucketName)\n }\n\n /**\n *\n * @alpha\n *\n * Retrieves metadata for a specific vector bucket\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param vectorBucketName - Name of the vector bucket\n * @returns Promise with bucket metadata or error\n *\n * @example\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .getBucket('embeddings-prod')\n *\n * console.log('Bucket created:', data?.vectorBucket.creationTime)\n * ```\n */\n async getBucket(vectorBucketName: string): Promise<ApiResponse<{ vectorBucket: VectorBucket }>> {\n return super.getBucket(vectorBucketName)\n }\n\n /**\n *\n * @alpha\n *\n * Lists all vector buckets with optional filtering and pagination\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Optional filters (prefix, maxResults, nextToken)\n * @returns Promise with list of buckets or error\n *\n * @example\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .listBuckets({ prefix: 'embeddings-' })\n *\n * data?.vectorBuckets.forEach(bucket => {\n * console.log(bucket.vectorBucketName)\n * })\n * ```\n */\n async listBuckets(\n options: ListVectorBucketsOptions = {}\n ): Promise<ApiResponse<ListVectorBucketsResponse>> {\n return super.listBuckets(options)\n }\n\n /**\n *\n * @alpha\n *\n * Deletes a vector bucket (bucket must be empty)\n * All indexes must be deleted before deleting the bucket\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param vectorBucketName - Name of the vector bucket to delete\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const { data, error } = await supabase\n * .storage\n * .vectors\n * .deleteBucket('embeddings-old')\n * ```\n */\n async deleteBucket(vectorBucketName: string): Promise<ApiResponse<undefined>> {\n return super.deleteBucket(vectorBucketName)\n }\n}\n\n/**\n *\n * @alpha\n *\n * Scoped client for operations within a specific vector bucket\n * Provides index management and access to vector operations\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n */\nexport class VectorBucketScope extends VectorIndexApi {\n private vectorBucketName: string\n\n /**\n * @alpha\n *\n * Creates a helper that automatically scopes all index operations to the provided bucket.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * ```\n */\n constructor(\n url: string,\n headers: { [key: string]: string },\n vectorBucketName: string,\n fetch?: Fetch\n ) {\n super(url, headers, fetch)\n this.vectorBucketName = vectorBucketName\n }\n\n /**\n *\n * @alpha\n *\n * Creates a new vector index in this bucket\n * Convenience method that automatically includes the bucket name\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Index configuration (vectorBucketName is automatically set)\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * await bucket.createIndex({\n * indexName: 'documents-openai',\n * dataType: 'float32',\n * dimension: 1536,\n * distanceMetric: 'cosine',\n * metadataConfiguration: {\n * nonFilterableMetadataKeys: ['raw_text']\n * }\n * })\n * ```\n */\n override async createIndex(options: Omit<CreateIndexOptions, 'vectorBucketName'>) {\n return super.createIndex({\n ...options,\n vectorBucketName: this.vectorBucketName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Lists indexes in this bucket\n * Convenience method that automatically includes the bucket name\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Listing options (vectorBucketName is automatically set)\n * @returns Promise with response containing indexes array and pagination token or error\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * const { data } = await bucket.listIndexes({ prefix: 'documents-' })\n * ```\n */\n override async listIndexes(options: Omit<ListIndexesOptions, 'vectorBucketName'> = {}) {\n return super.listIndexes({\n ...options,\n vectorBucketName: this.vectorBucketName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Retrieves metadata for a specific index in this bucket\n * Convenience method that automatically includes the bucket name\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param indexName - Name of the index to retrieve\n * @returns Promise with index metadata or error\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * const { data } = await bucket.getIndex('documents-openai')\n * console.log('Dimension:', data?.index.dimension)\n * ```\n */\n override async getIndex(indexName: string) {\n return super.getIndex(this.vectorBucketName, indexName)\n }\n\n /**\n *\n * @alpha\n *\n * Deletes an index from this bucket\n * Convenience method that automatically includes the bucket name\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param indexName - Name of the index to delete\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const bucket = supabase.storage.vectors.from('embeddings-prod')\n * await bucket.deleteIndex('old-index')\n * ```\n */\n override async deleteIndex(indexName: string) {\n return super.deleteIndex(this.vectorBucketName, indexName)\n }\n\n /**\n *\n * @alpha\n *\n * Access operations for a specific index within this bucket\n * Returns a scoped client for vector data operations\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param indexName - Name of the index\n * @returns Index-scoped client with vector data operations\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n *\n * // Insert vectors\n * await index.putVectors({\n * vectors: [\n * { key: 'doc-1', data: { float32: [...] }, metadata: { title: 'Intro' } }\n * ]\n * })\n *\n * // Query similar vectors\n * const { data } = await index.queryVectors({\n * queryVector: { float32: [...] },\n * topK: 5\n * })\n * ```\n */\n index(indexName: string): VectorIndexScope {\n return new VectorIndexScope(\n this.url,\n this.headers,\n this.vectorBucketName,\n indexName,\n this.fetch\n )\n }\n}\n\n/**\n *\n * @alpha\n *\n * Scoped client for operations within a specific vector index\n * Provides vector data operations (put, get, list, query, delete)\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n */\nexport class VectorIndexScope extends VectorDataApi {\n private vectorBucketName: string\n private indexName: string\n\n /**\n *\n * @alpha\n *\n * Creates a helper that automatically scopes all vector operations to the provided bucket/index names.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * ```\n */\n constructor(\n url: string,\n headers: { [key: string]: string },\n vectorBucketName: string,\n indexName: string,\n fetch?: Fetch\n ) {\n super(url, headers, fetch)\n this.vectorBucketName = vectorBucketName\n this.indexName = indexName\n }\n\n /**\n *\n * @alpha\n *\n * Inserts or updates vectors in this index\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Vector insertion options (bucket and index names automatically set)\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * await index.putVectors({\n * vectors: [\n * {\n * key: 'doc-1',\n * data: { float32: [0.1, 0.2, ...] },\n * metadata: { title: 'Introduction', page: 1 }\n * }\n * ]\n * })\n * ```\n */\n override async putVectors(options: Omit<PutVectorsOptions, 'vectorBucketName' | 'indexName'>) {\n return super.putVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Retrieves vectors by keys from this index\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Vector retrieval options (bucket and index names automatically set)\n * @returns Promise with response containing vectors array or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * const { data } = await index.getVectors({\n * keys: ['doc-1', 'doc-2'],\n * returnMetadata: true\n * })\n * ```\n */\n override async getVectors(options: Omit<GetVectorsOptions, 'vectorBucketName' | 'indexName'>) {\n return super.getVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Lists vectors in this index with pagination\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Listing options (bucket and index names automatically set)\n * @returns Promise with response containing vectors array and pagination token or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * const { data } = await index.listVectors({\n * maxResults: 500,\n * returnMetadata: true\n * })\n * ```\n */\n override async listVectors(\n options: Omit<ListVectorsOptions, 'vectorBucketName' | 'indexName'> = {}\n ) {\n return super.listVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Queries for similar vectors in this index\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Query options (bucket and index names automatically set)\n * @returns Promise with response containing matches array of similar vectors ordered by distance or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * const { data } = await index.queryVectors({\n * queryVector: { float32: [0.1, 0.2, ...] },\n * topK: 5,\n * filter: { category: 'technical' },\n * returnDistance: true,\n * returnMetadata: true\n * })\n * ```\n */\n override async queryVectors(\n options: Omit<QueryVectorsOptions, 'vectorBucketName' | 'indexName'>\n ) {\n return super.queryVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Deletes vectors by keys from this index\n * Convenience method that automatically includes bucket and index names\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @param options - Deletion options (bucket and index names automatically set)\n * @returns Promise with empty response on success or error\n *\n * @example\n * ```typescript\n * const index = supabase.storage.vectors.from('embeddings-prod').index('documents-openai')\n * await index.deleteVectors({\n * keys: ['doc-1', 'doc-2', 'doc-3']\n * })\n * ```\n */\n override async deleteVectors(\n options: Omit<DeleteVectorsOptions, 'vectorBucketName' | 'indexName'>\n ) {\n return super.deleteVectors({\n ...options,\n vectorBucketName: this.vectorBucketName,\n indexName: this.indexName,\n })\n }\n}\n","import StorageFileApi from './packages/StorageFileApi'\nimport StorageBucketApi from './packages/StorageBucketApi'\nimport StorageAnalyticsClient from './packages/StorageAnalyticsClient'\nimport { Fetch } from './lib/fetch'\nimport { StorageVectorsClient } from './lib/vectors'\n\nexport interface StorageClientOptions {\n useNewHostname?: boolean\n}\n\nexport class StorageClient extends StorageBucketApi {\n /**\n * Creates a client for Storage buckets, files, analytics, and vectors.\n *\n * @category File Buckets\n * @example\n * ```ts\n * import { StorageClient } from '@supabase/storage-js'\n *\n * const storage = new StorageClient('https://xyzcompany.supabase.co/storage/v1', {\n * apikey: 'public-anon-key',\n * })\n * const avatars = storage.from('avatars')\n * ```\n */\n constructor(\n url: string,\n headers: { [key: string]: string } = {},\n fetch?: Fetch,\n opts?: StorageClientOptions\n ) {\n super(url, headers, fetch, opts)\n }\n\n /**\n * Perform file operation in a bucket.\n *\n * @category File Buckets\n * @param id The bucket id to operate on.\n *\n * @example\n * ```typescript\n * const avatars = supabase.storage.from('avatars')\n * ```\n */\n from(id: string): StorageFileApi {\n return new StorageFileApi(this.url, this.headers, id, this.fetch)\n }\n\n /**\n *\n * @alpha\n *\n * Access vector storage operations.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Vector Buckets\n * @returns A StorageVectorsClient instance configured with the current storage settings.\n */\n get vectors(): StorageVectorsClient {\n return new StorageVectorsClient(this.url + '/vector', {\n headers: this.headers,\n fetch: this.fetch,\n })\n }\n\n /**\n *\n * @alpha\n *\n * Access analytics storage operations using Iceberg tables.\n *\n * **Public alpha:** This API is part of a public alpha release and may not be available to your account type.\n *\n * @category Analytics Buckets\n * @returns A StorageAnalyticsClient instance configured with the current storage settings.\n */\n get analytics(): StorageAnalyticsClient {\n return new StorageAnalyticsClient(this.url + '/iceberg', this.headers, this.fetch)\n }\n}\n"],"mappings":"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"}