@supabase/storage-js 2.104.0-canary.0 → 2.104.0-canary.2
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.
- package/dist/index.cjs +184 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +52 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +184 -107
- package/dist/index.mjs.map +1 -1
- package/dist/umd/supabase.js +1 -1
- package/package.json +1 -1
- package/src/StorageClient.ts +10 -2
- package/src/lib/common/BaseApiClient.ts +3 -2
- package/src/lib/common/errors.ts +21 -5
- package/src/lib/common/fetch.ts +11 -1
- package/src/lib/common/headers.ts +43 -0
- package/src/lib/version.ts +1 -1
- package/src/packages/StorageAnalyticsClient.ts +11 -1
- package/src/packages/StorageFileApi.ts +80 -68
- package/src/packages/StorageVectorsClient.ts +11 -1
package/dist/umd/supabase.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var supabase=(function(e){var t=class extends Error{constructor(e,t=`storage`,n,r){super(e),this.__isStorageError=!0,this.namespace=t,this.name=t===`vectors`?`StorageVectorsError`:`StorageError`,this.status=n,this.statusCode=r}};function n(e){return typeof e==`object`&&!!e&&`__isStorageError`in e}var r=class extends t{constructor(e,t,n,r=`storage`){super(e,r,t,n),this.name=r===`vectors`?`StorageVectorsApiError`:`StorageApiError`,this.status=t,this.statusCode=n}toJSON(){return{name:this.name,message:this.message,status:this.status,statusCode:this.statusCode}}},i=class extends t{constructor(e,t,n=`storage`){super(e,n),this.name=n===`vectors`?`StorageVectorsUnknownError`:`StorageUnknownError`,this.originalError=t}},a=class extends t{constructor(e){super(e,`vectors`)}};function o(e){return n(e)&&e.namespace===`vectors`}var s=class extends r{constructor(e,t,n){super(e,t,n,`vectors`)}},c=class extends i{constructor(e,t){super(e,t,`vectors`)}};let l=function(e){return e.InternalError=`InternalError`,e.S3VectorConflictException=`S3VectorConflictException`,e.S3VectorNotFoundException=`S3VectorNotFoundException`,e.S3VectorBucketNotEmpty=`S3VectorBucketNotEmpty`,e.S3VectorMaxBucketsExceeded=`S3VectorMaxBucketsExceeded`,e.S3VectorMaxIndexesExceeded=`S3VectorMaxIndexesExceeded`,e}({}),u=e=>e?(...t)=>e(...t):(...e)=>fetch(...e),d=e=>{if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)},f=e=>{if(Array.isArray(e))return e.map(e=>f(e));if(typeof e==`function`||e!==Object(e))return e;let t={};return Object.entries(e).forEach(([e,n])=>{let r=e.replace(/([-_][a-z])/gi,e=>e.toUpperCase().replace(/[-_]/g,``));t[r]=f(n)}),t},p=e=>!e||typeof e!=`string`||e.length===0||e.length>100||e.trim()!==e||e.includes(`/`)||e.includes(`\\`)?!1:/^[\w!.\*'() &$@=;:+,?-]+$/.test(e),m=e=>e.msg||e.message||e.error_description||(typeof e.error==`string`?e.error:e.error?.message)||JSON.stringify(e),h=async(e,t,n,a)=>{if(typeof e==`object`&&e&&typeof e.json==`function`){let n=e,i=parseInt(n.status,10);Number.isFinite(i)||(i=500),n.json().then(e=>{let n=e?.statusCode||e?.code||i+``;t(new r(m(e),i,n,a))}).catch(()=>{let e=i+``;t(new r(n.statusText||`HTTP ${i} error`,i,e,a))})}else t(new i(m(e),e,a))},g=(e,t,n,r)=>{let i={method:e,headers:t?.headers||{}};return e===`GET`||e===`HEAD`||!r?{...i,...n}:(d(r)?(i.headers={"Content-Type":`application/json`,...t?.headers},i.body=JSON.stringify(r)):i.body=r,t?.duplex&&(i.duplex=t.duplex),{...i,...n})};async function _(e,t,n,r,i,a,o){return new Promise((s,c)=>{e(n,g(t,r,i,a)).then(e=>{if(!e.ok)throw e;if(r?.noResolveJson)return e;if(o===`vectors`){let t=e.headers.get(`content-type`);if(e.headers.get(`content-length`)===`0`||e.status===204||!t||!t.includes(`application/json`))return{}}return e.json()}).then(e=>s(e)).catch(e=>h(e,c,r,o))})}function v(e=`storage`){return{get:async(t,n,r,i)=>_(t,`GET`,n,r,i,void 0,e),post:async(t,n,r,i,a)=>_(t,`POST`,n,i,a,r,e),put:async(t,n,r,i,a)=>_(t,`PUT`,n,i,a,r,e),head:async(t,n,r,i)=>_(t,`HEAD`,n,{...r,noResolveJson:!0},i,void 0,e),remove:async(t,n,r,i,a)=>_(t,`DELETE`,n,i,a,r,e)}}let{get:y,post:b,put:x,head:S,remove:C}=v(`storage`),w=v(`vectors`);var T=class{constructor(e,t={},n,r=`storage`){this.shouldThrowOnError=!1,this.url=e,this.headers=t,this.fetch=u(n),this.namespace=r}throwOnError(){return this.shouldThrowOnError=!0,this}setHeader(e,t){return this.headers={...this.headers,[e]:t},this}async handleOperation(e){try{return{data:await e(),error:null}}catch(e){if(this.shouldThrowOnError)throw e;if(n(e))return{data:null,error:e};throw e}}},E=class{constructor(e,t){this.downloadFn=e,this.shouldThrowOnError=t}then(e,t){return this.execute().then(e,t)}async execute(){try{return{data:(await this.downloadFn()).body,error:null}}catch(e){if(this.shouldThrowOnError)throw e;if(n(e))return{data:null,error:e};throw e}}};let D;var O=class{static{D=Symbol.toStringTag}constructor(e,t){this.downloadFn=e,this.shouldThrowOnError=t,this[D]=`BlobDownloadBuilder`,this.promise=null}asStream(){return new E(this.downloadFn,this.shouldThrowOnError)}then(e,t){return this.getPromise().then(e,t)}catch(e){return this.getPromise().catch(e)}finally(e){return this.getPromise().finally(e)}getPromise(){return this.promise||=this.execute(),this.promise}async execute(){try{return{data:await(await this.downloadFn()).blob(),error:null}}catch(e){if(this.shouldThrowOnError)throw e;if(n(e))return{data:null,error:e};throw e}}};let k={limit:100,offset:0,sortBy:{column:`name`,order:`asc`}},A={cacheControl:`3600`,contentType:`text/plain;charset=UTF-8`,upsert:!1};var j=class extends T{constructor(e,t={},n,r){super(e,t,r,`storage`),this.bucketId=n}async uploadOrUpdate(e,t,n,r){return this.handleOperation(async()=>{let i,a={...A,...r},o={...this.headers,...e===`POST`&&{"x-upsert":String(a.upsert)}},s=a.metadata;typeof Blob<`u`&&n instanceof Blob?(i=new FormData,i.append(`cacheControl`,a.cacheControl),s&&i.append(`metadata`,this.encodeMetadata(s)),i.append(``,n)):typeof FormData<`u`&&n instanceof FormData?(i=n,i.has(`cacheControl`)||i.append(`cacheControl`,a.cacheControl),s&&!i.has(`metadata`)&&i.append(`metadata`,this.encodeMetadata(s))):(i=n,o[`cache-control`]=`max-age=${a.cacheControl}`,o[`content-type`]=a.contentType,s&&(o[`x-metadata`]=this.toBase64(this.encodeMetadata(s))),(typeof ReadableStream<`u`&&i instanceof ReadableStream||i&&typeof i==`object`&&`pipe`in i&&typeof i.pipe==`function`)&&!a.duplex&&(a.duplex=`half`)),r?.headers&&(o={...o,...r.headers});let c=this._removeEmptyFolders(t),l=this._getFinalPath(c),u=await(e==`PUT`?x:b)(this.fetch,`${this.url}/object/${l}`,i,{headers:o,...a?.duplex?{duplex:a.duplex}:{}});return{path:c,id:u.Id,fullPath:u.Key}})}async upload(e,t,n){return this.uploadOrUpdate(`POST`,e,t,n)}async uploadToSignedUrl(e,t,n,r){let i=this._removeEmptyFolders(e),a=this._getFinalPath(i),o=new URL(this.url+`/object/upload/sign/${a}`);return o.searchParams.set(`token`,t),this.handleOperation(async()=>{let e,t={...A,...r},a={...this.headers,"x-upsert":String(t.upsert)};return typeof Blob<`u`&&n instanceof Blob?(e=new FormData,e.append(`cacheControl`,t.cacheControl),e.append(``,n)):typeof FormData<`u`&&n instanceof FormData?(e=n,e.append(`cacheControl`,t.cacheControl)):(e=n,a[`cache-control`]=`max-age=${t.cacheControl}`,a[`content-type`]=t.contentType),{path:i,fullPath:(await x(this.fetch,o.toString(),e,{headers:a})).Key}})}async createSignedUploadUrl(e,n){return this.handleOperation(async()=>{let r=this._getFinalPath(e),i={...this.headers};n?.upsert&&(i[`x-upsert`]=`true`);let a=await b(this.fetch,`${this.url}/object/upload/sign/${r}`,{},{headers:i}),o=new URL(this.url+a.url),s=o.searchParams.get(`token`);if(!s)throw new t(`No token returned by API`);return{signedUrl:o.toString(),path:e,token:s}})}async update(e,t,n){return this.uploadOrUpdate(`PUT`,e,t,n)}async move(e,t,n){return this.handleOperation(async()=>await b(this.fetch,`${this.url}/object/move`,{bucketId:this.bucketId,sourceKey:e,destinationKey:t,destinationBucket:n?.destinationBucket},{headers:this.headers}))}async copy(e,t,n){return this.handleOperation(async()=>({path:(await b(this.fetch,`${this.url}/object/copy`,{bucketId:this.bucketId,sourceKey:e,destinationKey:t,destinationBucket:n?.destinationBucket},{headers:this.headers})).Key}))}async createSignedUrl(e,t,n){return this.handleOperation(async()=>{let r=this._getFinalPath(e),i=typeof n?.transform==`object`&&n.transform!==null&&Object.keys(n.transform).length>0,a=await b(this.fetch,`${this.url}/object/sign/${r}`,{expiresIn:t,...i?{transform:n.transform}:{}},{headers:this.headers}),o=n?.download?`&download=${n.download===!0?``:n.download}`:``,s=i&&a.signedURL.includes(`/object/sign/`)?a.signedURL.replace(`/object/sign/`,`/render/image/sign/`):a.signedURL;return{signedUrl:encodeURI(`${this.url}${s}${o}`)}})}async createSignedUrls(e,t,n){return this.handleOperation(async()=>{let r=await b(this.fetch,`${this.url}/object/sign/${this.bucketId}`,{expiresIn:t,paths:e},{headers:this.headers}),i=n?.download?`&download=${n.download===!0?``:n.download}`:``;return r.map(e=>({...e,signedUrl:e.signedURL?encodeURI(`${this.url}${e.signedURL}${i}`):null}))})}download(e,t,n){let r=t?.transform===void 0?`object`:`render/image/authenticated`,i=this.transformOptsToQueryString(t?.transform||{}),a=i?`?${i}`:``,o=this._getFinalPath(e);return new O(()=>y(this.fetch,`${this.url}/${r}/${o}${a}`,{headers:this.headers,noResolveJson:!0},n),this.shouldThrowOnError)}async info(e){let t=this._getFinalPath(e);return this.handleOperation(async()=>f(await y(this.fetch,`${this.url}/object/info/${t}`,{headers:this.headers})))}async exists(e){let t=this._getFinalPath(e);try{return await S(this.fetch,`${this.url}/object/${t}`,{headers:this.headers}),{data:!0,error:null}}catch(e){if(this.shouldThrowOnError)throw e;if(n(e)){let t=e instanceof r?e.status:e instanceof i?e.originalError?.status:void 0;if(t!==void 0&&[400,404].includes(t))return{data:!1,error:e}}throw e}}getPublicUrl(e,t){let n=this._getFinalPath(e),r=[],i=t?.download?`download=${t.download===!0?``:t.download}`:``;i!==``&&r.push(i);let a=t?.transform===void 0?`object`:`render/image`,o=this.transformOptsToQueryString(t?.transform||{});o!==``&&r.push(o);let s=r.join(`&`);return s!==``&&(s=`?${s}`),{data:{publicUrl:encodeURI(`${this.url}/${a}/public/${n}${s}`)}}}async remove(e){return this.handleOperation(async()=>await C(this.fetch,`${this.url}/object/${this.bucketId}`,{prefixes:e},{headers:this.headers}))}async list(e,t,n){return this.handleOperation(async()=>{let r={...k,...t,prefix:e||``};return await b(this.fetch,`${this.url}/object/list/${this.bucketId}`,r,{headers:this.headers},n)})}async listV2(e,t){return this.handleOperation(async()=>{let n={...e};return await b(this.fetch,`${this.url}/object/list-v2/${this.bucketId}`,n,{headers:this.headers},t)})}encodeMetadata(e){return JSON.stringify(e)}toBase64(e){return typeof Buffer<`u`?Buffer.from(e).toString(`base64`):btoa(e)}_getFinalPath(e){return`${this.bucketId}/${e.replace(/^\/+/,``)}`}_removeEmptyFolders(e){return e.replace(/^\/|\/$/g,``).replace(/\/+/g,`/`)}transformOptsToQueryString(e){let t=[];return e.width&&t.push(`width=${e.width}`),e.height&&t.push(`height=${e.height}`),e.resize&&t.push(`resize=${e.resize}`),e.format&&t.push(`format=${e.format}`),e.quality&&t.push(`quality=${e.quality}`),t.join(`&`)}};let M={"X-Client-Info":`storage-js/2.104.0-canary.0`};var N=class extends T{constructor(e,t={},n,r){let i=new URL(e);r?.useNewHostname&&/supabase\.(co|in|red)$/.test(i.hostname)&&!i.hostname.includes(`storage.supabase.`)&&(i.hostname=i.hostname.replace(`supabase.`,`storage.supabase.`));let a=i.href.replace(/\/$/,``),o={...M,...t};super(a,o,n,`storage`)}async listBuckets(e){return this.handleOperation(async()=>{let t=this.listBucketOptionsToQueryString(e);return await y(this.fetch,`${this.url}/bucket${t}`,{headers:this.headers})})}async getBucket(e){return this.handleOperation(async()=>await y(this.fetch,`${this.url}/bucket/${e}`,{headers:this.headers}))}async createBucket(e,t={public:!1}){return this.handleOperation(async()=>await b(this.fetch,`${this.url}/bucket`,{id:e,name:e,type:t.type,public:t.public,file_size_limit:t.fileSizeLimit,allowed_mime_types:t.allowedMimeTypes},{headers:this.headers}))}async updateBucket(e,t){return this.handleOperation(async()=>await x(this.fetch,`${this.url}/bucket/${e}`,{id:e,name:e,public:t.public,file_size_limit:t.fileSizeLimit,allowed_mime_types:t.allowedMimeTypes},{headers:this.headers}))}async emptyBucket(e){return this.handleOperation(async()=>await b(this.fetch,`${this.url}/bucket/${e}/empty`,{},{headers:this.headers}))}async deleteBucket(e){return this.handleOperation(async()=>await C(this.fetch,`${this.url}/bucket/${e}`,{},{headers:this.headers}))}listBucketOptionsToQueryString(e){let t={};return e&&(`limit`in e&&(t.limit=String(e.limit)),`offset`in e&&(t.offset=String(e.offset)),e.search&&(t.search=e.search),e.sortColumn&&(t.sortColumn=e.sortColumn),e.sortOrder&&(t.sortOrder=e.sortOrder)),Object.keys(t).length>0?`?`+new URLSearchParams(t).toString():``}},P=class extends Error{constructor(e,t){super(e),this.name=`IcebergError`,this.status=t.status,this.icebergType=t.icebergType,this.icebergCode=t.icebergCode,this.details=t.details,this.isCommitStateUnknown=t.icebergType===`CommitStateUnknownException`||[500,502,504].includes(t.status)&&t.icebergType?.includes(`CommitState`)===!0}isNotFound(){return this.status===404}isConflict(){return this.status===409}isAuthenticationTimeout(){return this.status===419}};function F(e,t,n){let r=new URL(t,e);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&r.searchParams.set(e,t);return r.toString()}async function I(e){return!e||e.type===`none`?{}:e.type===`bearer`?{Authorization:`Bearer ${e.token}`}:e.type===`header`?{[e.name]:e.value}:e.type===`custom`?await e.getHeaders():{}}function L(e){let t=e.fetchImpl??globalThis.fetch;return{async request({method:n,path:r,query:i,body:a,headers:o}){let s=F(e.baseUrl,r,i),c=await I(e.auth),l=await t(s,{method:n,headers:{...a?{"Content-Type":`application/json`}:{},...c,...o},body:a?JSON.stringify(a):void 0}),u=await l.text(),d=(l.headers.get(`content-type`)||``).includes(`application/json`),f=d&&u?JSON.parse(u):u;if(!l.ok){let e=d?f:void 0,t=e?.error;throw new P(t?.message??`Request failed with status ${l.status}`,{status:l.status,icebergType:t?.type,icebergCode:t?.code,details:e})}return{status:l.status,headers:l.headers,data:f}}}}function R(e){return e.join(``)}var z=class{constructor(e,t=``){this.client=e,this.prefix=t}async listNamespaces(e){let t=e?{parent:R(e.namespace)}:void 0;return(await this.client.request({method:`GET`,path:`${this.prefix}/namespaces`,query:t})).data.namespaces.map(e=>({namespace:e}))}async createNamespace(e,t){let n={namespace:e.namespace,properties:t?.properties};return(await this.client.request({method:`POST`,path:`${this.prefix}/namespaces`,body:n})).data}async dropNamespace(e){await this.client.request({method:`DELETE`,path:`${this.prefix}/namespaces/${R(e.namespace)}`})}async loadNamespaceMetadata(e){return{properties:(await this.client.request({method:`GET`,path:`${this.prefix}/namespaces/${R(e.namespace)}`})).data.properties}}async namespaceExists(e){try{return await this.client.request({method:`HEAD`,path:`${this.prefix}/namespaces/${R(e.namespace)}`}),!0}catch(e){if(e instanceof P&&e.status===404)return!1;throw e}}async createNamespaceIfNotExists(e,t){try{return await this.createNamespace(e,t)}catch(e){if(e instanceof P&&e.status===409)return;throw e}}};function B(e){return e.join(``)}var V=class{constructor(e,t=``,n){this.client=e,this.prefix=t,this.accessDelegation=n}async listTables(e){return(await this.client.request({method:`GET`,path:`${this.prefix}/namespaces/${B(e.namespace)}/tables`})).data.identifiers}async createTable(e,t){let n={};return this.accessDelegation&&(n[`X-Iceberg-Access-Delegation`]=this.accessDelegation),(await this.client.request({method:`POST`,path:`${this.prefix}/namespaces/${B(e.namespace)}/tables`,body:t,headers:n})).data.metadata}async updateTable(e,t){let n=await this.client.request({method:`POST`,path:`${this.prefix}/namespaces/${B(e.namespace)}/tables/${e.name}`,body:t});return{"metadata-location":n.data[`metadata-location`],metadata:n.data.metadata}}async dropTable(e,t){await this.client.request({method:`DELETE`,path:`${this.prefix}/namespaces/${B(e.namespace)}/tables/${e.name}`,query:{purgeRequested:String(t?.purge??!1)}})}async loadTable(e){let t={};return this.accessDelegation&&(t[`X-Iceberg-Access-Delegation`]=this.accessDelegation),(await this.client.request({method:`GET`,path:`${this.prefix}/namespaces/${B(e.namespace)}/tables/${e.name}`,headers:t})).data.metadata}async tableExists(e){let t={};this.accessDelegation&&(t[`X-Iceberg-Access-Delegation`]=this.accessDelegation);try{return await this.client.request({method:`HEAD`,path:`${this.prefix}/namespaces/${B(e.namespace)}/tables/${e.name}`,headers:t}),!0}catch(e){if(e instanceof P&&e.status===404)return!1;throw e}}async createTableIfNotExists(e,t){try{return await this.createTable(e,t)}catch(n){if(n instanceof P&&n.status===409)return await this.loadTable({namespace:e.namespace,name:t.name});throw n}}},H=class{constructor(e){let t=`v1`;e.catalogName&&(t+=`/${e.catalogName}`),this.client=L({baseUrl:e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,auth:e.auth,fetchImpl:e.fetch}),this.accessDelegation=e.accessDelegation?.join(`,`),this.namespaceOps=new z(this.client,t),this.tableOps=new V(this.client,t,this.accessDelegation)}async listNamespaces(e){return this.namespaceOps.listNamespaces(e)}async createNamespace(e,t){return this.namespaceOps.createNamespace(e,t)}async dropNamespace(e){await this.namespaceOps.dropNamespace(e)}async loadNamespaceMetadata(e){return this.namespaceOps.loadNamespaceMetadata(e)}async listTables(e){return this.tableOps.listTables(e)}async createTable(e,t){return this.tableOps.createTable(e,t)}async updateTable(e,t){return this.tableOps.updateTable(e,t)}async dropTable(e,t){await this.tableOps.dropTable(e,t)}async loadTable(e){return this.tableOps.loadTable(e)}async namespaceExists(e){return this.namespaceOps.namespaceExists(e)}async tableExists(e){return this.tableOps.tableExists(e)}async createNamespaceIfNotExists(e,t){return this.namespaceOps.createNamespaceIfNotExists(e,t)}async createTableIfNotExists(e,t){return this.tableOps.createTableIfNotExists(e,t)}},U=class extends T{constructor(e,t={},n){let r=e.replace(/\/$/,``),i={...M,...t};super(r,i,n,`storage`)}async createBucket(e){return this.handleOperation(async()=>await b(this.fetch,`${this.url}/bucket`,{name:e},{headers:this.headers}))}async listBuckets(e){return this.handleOperation(async()=>{let t=new URLSearchParams;e?.limit!==void 0&&t.set(`limit`,e.limit.toString()),e?.offset!==void 0&&t.set(`offset`,e.offset.toString()),e?.sortColumn&&t.set(`sortColumn`,e.sortColumn),e?.sortOrder&&t.set(`sortOrder`,e.sortOrder),e?.search&&t.set(`search`,e.search);let n=t.toString(),r=n?`${this.url}/bucket?${n}`:`${this.url}/bucket`;return await y(this.fetch,r,{headers:this.headers})})}async deleteBucket(e){return this.handleOperation(async()=>await C(this.fetch,`${this.url}/bucket/${e}`,{},{headers:this.headers}))}from(e){if(!p(e))throw new t(`Invalid bucket name: File, folder, and bucket names must follow AWS object key naming guidelines and should avoid the use of any other characters.`);let n=new H({baseUrl:this.url,catalogName:e,auth:{type:`custom`,getHeaders:async()=>this.headers},fetch:this.fetch}),r=this.shouldThrowOnError;return new Proxy(n,{get(e,t){let n=e[t];return typeof n==`function`?async(...t)=>{try{return{data:await n.apply(e,t),error:null}}catch(e){if(r)throw e;return{data:null,error:e}}}:n}})}},W=class extends T{constructor(e,t={},n){let r=e.replace(/\/$/,``),i={...M,"Content-Type":`application/json`,...t};super(r,i,n,`vectors`)}async createIndex(e){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/CreateIndex`,e,{headers:this.headers})||{})}async getIndex(e,t){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/GetIndex`,{vectorBucketName:e,indexName:t},{headers:this.headers}))}async listIndexes(e){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/ListIndexes`,e,{headers:this.headers}))}async deleteIndex(e,t){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/DeleteIndex`,{vectorBucketName:e,indexName:t},{headers:this.headers})||{})}},G=class extends T{constructor(e,t={},n){let r=e.replace(/\/$/,``),i={...M,"Content-Type":`application/json`,...t};super(r,i,n,`vectors`)}async putVectors(e){if(e.vectors.length<1||e.vectors.length>500)throw Error(`Vector batch size must be between 1 and 500 items`);return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/PutVectors`,e,{headers:this.headers})||{})}async getVectors(e){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/GetVectors`,e,{headers:this.headers}))}async listVectors(e){if(e.segmentCount!==void 0){if(e.segmentCount<1||e.segmentCount>16)throw Error(`segmentCount must be between 1 and 16`);if(e.segmentIndex!==void 0&&(e.segmentIndex<0||e.segmentIndex>=e.segmentCount))throw Error(`segmentIndex must be between 0 and ${e.segmentCount-1}`)}return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/ListVectors`,e,{headers:this.headers}))}async queryVectors(e){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/QueryVectors`,e,{headers:this.headers}))}async deleteVectors(e){if(e.keys.length<1||e.keys.length>500)throw Error(`Keys batch size must be between 1 and 500 items`);return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/DeleteVectors`,e,{headers:this.headers})||{})}},K=class extends T{constructor(e,t={},n){let r=e.replace(/\/$/,``),i={...M,"Content-Type":`application/json`,...t};super(r,i,n,`vectors`)}async createBucket(e){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/CreateVectorBucket`,{vectorBucketName:e},{headers:this.headers})||{})}async getBucket(e){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/GetVectorBucket`,{vectorBucketName:e},{headers:this.headers}))}async listBuckets(e={}){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/ListVectorBuckets`,e,{headers:this.headers}))}async deleteBucket(e){return this.handleOperation(async()=>await w.post(this.fetch,`${this.url}/DeleteVectorBucket`,{vectorBucketName:e},{headers:this.headers})||{})}},q=class extends K{constructor(e,t={}){super(e,t.headers||{},t.fetch)}from(e){return new J(this.url,this.headers,e,this.fetch)}async createBucket(e){return super.createBucket(e)}async getBucket(e){return super.getBucket(e)}async listBuckets(e={}){return super.listBuckets(e)}async deleteBucket(e){return super.deleteBucket(e)}},J=class extends W{constructor(e,t,n,r){super(e,t,r),this.vectorBucketName=n}async createIndex(e){return super.createIndex({...e,vectorBucketName:this.vectorBucketName})}async listIndexes(e={}){return super.listIndexes({...e,vectorBucketName:this.vectorBucketName})}async getIndex(e){return super.getIndex(this.vectorBucketName,e)}async deleteIndex(e){return super.deleteIndex(this.vectorBucketName,e)}index(e){return new Y(this.url,this.headers,this.vectorBucketName,e,this.fetch)}},Y=class extends G{constructor(e,t,n,r,i){super(e,t,i),this.vectorBucketName=n,this.indexName=r}async putVectors(e){return super.putVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}async getVectors(e){return super.getVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}async listVectors(e={}){return super.listVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}async queryVectors(e){return super.queryVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}async deleteVectors(e){return super.deleteVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}},X=class extends N{constructor(e,t={},n,r){super(e,t,n,r)}from(e){return new j(this.url,this.headers,e,this.fetch)}get vectors(){return new q(this.url+`/vector`,{headers:this.headers,fetch:this.fetch})}get analytics(){return new U(this.url+`/iceberg`,this.headers,this.fetch)}};return e.StorageAnalyticsClient=U,e.StorageApiError=r,e.StorageClient=X,e.StorageError=t,e.StorageUnknownError=i,e.StorageVectorsApiError=s,e.StorageVectorsClient=q,e.StorageVectorsError=a,e.StorageVectorsErrorCode=l,e.StorageVectorsUnknownError=c,e.VectorBucketApi=K,e.VectorBucketScope=J,e.VectorDataApi=G,e.VectorIndexApi=W,e.VectorIndexScope=Y,e.isStorageError=n,e.isStorageVectorsError=o,e})({});
|
|
1
|
+
var supabase=(function(e){var t=class extends Error{constructor(e,t=`storage`,n,r){super(e),this.__isStorageError=!0,this.namespace=t,this.name=t===`vectors`?`StorageVectorsError`:`StorageError`,this.status=n,this.statusCode=r}toJSON(){return{name:this.name,message:this.message,status:this.status,statusCode:this.statusCode}}};function n(e){return typeof e==`object`&&!!e&&`__isStorageError`in e}var r=class extends t{constructor(e,t,n,r=`storage`){super(e,r,t,n),this.name=r===`vectors`?`StorageVectorsApiError`:`StorageApiError`,this.status=t,this.statusCode=n}toJSON(){return{...super.toJSON()}}},i=class extends t{constructor(e,t,n=`storage`){super(e,n),this.name=n===`vectors`?`StorageVectorsUnknownError`:`StorageUnknownError`,this.originalError=t}},a=class extends t{constructor(e){super(e,`vectors`)}};function o(e){return n(e)&&e.namespace===`vectors`}var s=class extends r{constructor(e,t,n){super(e,t,n,`vectors`)}},c=class extends i{constructor(e,t){super(e,t,`vectors`)}};let l=function(e){return e.InternalError=`InternalError`,e.S3VectorConflictException=`S3VectorConflictException`,e.S3VectorNotFoundException=`S3VectorNotFoundException`,e.S3VectorBucketNotEmpty=`S3VectorBucketNotEmpty`,e.S3VectorMaxBucketsExceeded=`S3VectorMaxBucketsExceeded`,e.S3VectorMaxIndexesExceeded=`S3VectorMaxIndexesExceeded`,e}({});function u(e,t,n){let r={...e},i=t.toLowerCase();for(let e of Object.keys(r))e.toLowerCase()===i&&delete r[e];return r[i]=n,r}function d(e){let t={};for(let[n,r]of Object.entries(e))t[n.toLowerCase()]=r;return t}let f=e=>e?(...t)=>e(...t):(...e)=>fetch(...e),p=e=>{if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)},m=e=>{if(Array.isArray(e))return e.map(e=>m(e));if(typeof e==`function`||e!==Object(e))return e;let t={};return Object.entries(e).forEach(([e,n])=>{let r=e.replace(/([-_][a-z])/gi,e=>e.toUpperCase().replace(/[-_]/g,``));t[r]=m(n)}),t},h=e=>!e||typeof e!=`string`||e.length===0||e.length>100||e.trim()!==e||e.includes(`/`)||e.includes(`\\`)?!1:/^[\w!.\*'() &$@=;:+,?-]+$/.test(e),g=e=>e.msg||e.message||e.error_description||(typeof e.error==`string`?e.error:e.error?.message)||JSON.stringify(e),_=async(e,t,n,a)=>{if(typeof e==`object`&&e&&typeof e.json==`function`){let n=e,i=parseInt(n.status,10);Number.isFinite(i)||(i=500),n.json().then(e=>{let n=e?.statusCode||e?.code||i+``;t(new r(g(e),i,n,a))}).catch(()=>{let e=i+``;t(new r(n.statusText||`HTTP ${i} error`,i,e,a))})}else t(new i(g(e),e,a))},v=(e,t,n,r)=>{let i={method:e,headers:t?.headers||{}};if(e===`GET`||e===`HEAD`||!r)return{...i,...n};if(p(r)){let e=t?.headers||{},n;for(let[t,r]of Object.entries(e))t.toLowerCase()===`content-type`&&(n=r);i.headers=u(e,`Content-Type`,n??`application/json`),i.body=JSON.stringify(r)}else i.body=r;return t?.duplex&&(i.duplex=t.duplex),{...i,...n}};async function y(e,t,n,r,i,a,o){return new Promise((s,c)=>{e(n,v(t,r,i,a)).then(e=>{if(!e.ok)throw e;if(r?.noResolveJson)return e;if(o===`vectors`){let t=e.headers.get(`content-type`);if(e.headers.get(`content-length`)===`0`||e.status===204||!t||!t.includes(`application/json`))return{}}return e.json()}).then(e=>s(e)).catch(e=>_(e,c,r,o))})}function b(e=`storage`){return{get:async(t,n,r,i)=>y(t,`GET`,n,r,i,void 0,e),post:async(t,n,r,i,a)=>y(t,`POST`,n,i,a,r,e),put:async(t,n,r,i,a)=>y(t,`PUT`,n,i,a,r,e),head:async(t,n,r,i)=>y(t,`HEAD`,n,{...r,noResolveJson:!0},i,void 0,e),remove:async(t,n,r,i,a)=>y(t,`DELETE`,n,i,a,r,e)}}let{get:x,post:S,put:C,head:w,remove:T}=b(`storage`),E=b(`vectors`);var D=class{constructor(e,t={},n,r=`storage`){this.shouldThrowOnError=!1,this.url=e,this.headers=d(t),this.fetch=f(n),this.namespace=r}throwOnError(){return this.shouldThrowOnError=!0,this}setHeader(e,t){return this.headers=u(this.headers,e,t),this}async handleOperation(e){try{return{data:await e(),error:null}}catch(e){if(this.shouldThrowOnError)throw e;if(n(e))return{data:null,error:e};throw e}}},O=class{constructor(e,t){this.downloadFn=e,this.shouldThrowOnError=t}then(e,t){return this.execute().then(e,t)}async execute(){try{return{data:(await this.downloadFn()).body,error:null}}catch(e){if(this.shouldThrowOnError)throw e;if(n(e))return{data:null,error:e};throw e}}};let k;var A=class{static{k=Symbol.toStringTag}constructor(e,t){this.downloadFn=e,this.shouldThrowOnError=t,this[k]=`BlobDownloadBuilder`,this.promise=null}asStream(){return new O(this.downloadFn,this.shouldThrowOnError)}then(e,t){return this.getPromise().then(e,t)}catch(e){return this.getPromise().catch(e)}finally(e){return this.getPromise().finally(e)}getPromise(){return this.promise||=this.execute(),this.promise}async execute(){try{return{data:await(await this.downloadFn()).blob(),error:null}}catch(e){if(this.shouldThrowOnError)throw e;if(n(e))return{data:null,error:e};throw e}}};let j={limit:100,offset:0,sortBy:{column:`name`,order:`asc`}},M={cacheControl:`3600`,contentType:`text/plain;charset=UTF-8`,upsert:!1};var N=class extends D{constructor(e,t={},n,r){super(e,t,r,`storage`),this.bucketId=n}async uploadOrUpdate(e,t,n,r){return this.handleOperation(async()=>{let i,a={...M,...r},o={...this.headers,...e===`POST`&&{"x-upsert":String(a.upsert)}},s=a.metadata;if(typeof Blob<`u`&&n instanceof Blob?(i=new FormData,i.append(`cacheControl`,a.cacheControl),s&&i.append(`metadata`,this.encodeMetadata(s)),i.append(``,n)):typeof FormData<`u`&&n instanceof FormData?(i=n,i.has(`cacheControl`)||i.append(`cacheControl`,a.cacheControl),s&&!i.has(`metadata`)&&i.append(`metadata`,this.encodeMetadata(s))):(i=n,o[`cache-control`]=`max-age=${a.cacheControl}`,o[`content-type`]=a.contentType,s&&(o[`x-metadata`]=this.toBase64(this.encodeMetadata(s))),(typeof ReadableStream<`u`&&i instanceof ReadableStream||i&&typeof i==`object`&&`pipe`in i&&typeof i.pipe==`function`)&&!a.duplex&&(a.duplex=`half`)),r?.headers)for(let[e,t]of Object.entries(r.headers))o=u(o,e,t);let c=this._removeEmptyFolders(t),l=this._getFinalPath(c),d=await(e==`PUT`?C:S)(this.fetch,`${this.url}/object/${l}`,i,{headers:o,...a?.duplex?{duplex:a.duplex}:{}});return{path:c,id:d.Id,fullPath:d.Key}})}async upload(e,t,n){return this.uploadOrUpdate(`POST`,e,t,n)}async uploadToSignedUrl(e,t,n,r){let i=this._removeEmptyFolders(e),a=this._getFinalPath(i),o=new URL(this.url+`/object/upload/sign/${a}`);return o.searchParams.set(`token`,t),this.handleOperation(async()=>{let e,t={...M,...r},a={...this.headers,"x-upsert":String(t.upsert)};return typeof Blob<`u`&&n instanceof Blob?(e=new FormData,e.append(`cacheControl`,t.cacheControl),e.append(``,n)):typeof FormData<`u`&&n instanceof FormData?(e=n,e.append(`cacheControl`,t.cacheControl)):(e=n,a[`cache-control`]=`max-age=${t.cacheControl}`,a[`content-type`]=t.contentType),{path:i,fullPath:(await C(this.fetch,o.toString(),e,{headers:a})).Key}})}async createSignedUploadUrl(e,n){return this.handleOperation(async()=>{let r=this._getFinalPath(e),i={...this.headers};n?.upsert&&(i[`x-upsert`]=`true`);let a=await S(this.fetch,`${this.url}/object/upload/sign/${r}`,{},{headers:i}),o=new URL(this.url+a.url),s=o.searchParams.get(`token`);if(!s)throw new t(`No token returned by API`);return{signedUrl:o.toString(),path:e,token:s}})}async update(e,t,n){return this.uploadOrUpdate(`PUT`,e,t,n)}async move(e,t,n){return this.handleOperation(async()=>await S(this.fetch,`${this.url}/object/move`,{bucketId:this.bucketId,sourceKey:e,destinationKey:t,destinationBucket:n?.destinationBucket},{headers:this.headers}))}async copy(e,t,n){return this.handleOperation(async()=>({path:(await S(this.fetch,`${this.url}/object/copy`,{bucketId:this.bucketId,sourceKey:e,destinationKey:t,destinationBucket:n?.destinationBucket},{headers:this.headers})).Key}))}async createSignedUrl(e,t,n){return this.handleOperation(async()=>{let r=this._getFinalPath(e),i=typeof n?.transform==`object`&&n.transform!==null&&Object.keys(n.transform).length>0,a=await S(this.fetch,`${this.url}/object/sign/${r}`,{expiresIn:t,...i?{transform:n.transform}:{}},{headers:this.headers}),o=new URLSearchParams;n?.download&&o.set(`download`,n.download===!0?``:n.download),n?.cacheNonce!=null&&o.set(`cacheNonce`,String(n.cacheNonce));let s=o.toString();return{signedUrl:encodeURI(`${this.url}${a.signedURL}${s?`&${s}`:``}`)}})}async createSignedUrls(e,t,n){return this.handleOperation(async()=>{let r=await S(this.fetch,`${this.url}/object/sign/${this.bucketId}`,{expiresIn:t,paths:e},{headers:this.headers}),i=new URLSearchParams;n?.download&&i.set(`download`,n.download===!0?``:n.download),n?.cacheNonce!=null&&i.set(`cacheNonce`,String(n.cacheNonce));let a=i.toString();return r.map(e=>({...e,signedUrl:e.signedURL?encodeURI(`${this.url}${e.signedURL}${a?`&${a}`:``}`):null}))})}download(e,t,n){let r=typeof t?.transform==`object`&&t.transform!==null&&Object.keys(t.transform).length>0?`render/image/authenticated`:`object`,i=new URLSearchParams;t?.transform&&this.applyTransformOptsToQuery(i,t.transform),t?.cacheNonce!=null&&i.set(`cacheNonce`,String(t.cacheNonce));let a=i.toString(),o=this._getFinalPath(e);return new A(()=>x(this.fetch,`${this.url}/${r}/${o}${a?`?${a}`:``}`,{headers:this.headers,noResolveJson:!0},n),this.shouldThrowOnError)}async info(e){let t=this._getFinalPath(e);return this.handleOperation(async()=>m(await x(this.fetch,`${this.url}/object/info/${t}`,{headers:this.headers})))}async exists(e){let t=this._getFinalPath(e);try{return await w(this.fetch,`${this.url}/object/${t}`,{headers:this.headers}),{data:!0,error:null}}catch(e){if(this.shouldThrowOnError)throw e;if(n(e)){let t=e instanceof r?e.status:e instanceof i?e.originalError?.status:void 0;if(t!==void 0&&[400,404].includes(t))return{data:!1,error:e}}throw e}}getPublicUrl(e,t){let n=this._getFinalPath(e),r=new URLSearchParams;t?.download&&r.set(`download`,t.download===!0?``:t.download),t?.transform&&this.applyTransformOptsToQuery(r,t.transform),t?.cacheNonce!=null&&r.set(`cacheNonce`,String(t.cacheNonce));let i=r.toString(),a=typeof t?.transform==`object`&&t.transform!==null&&Object.keys(t.transform).length>0?`render/image`:`object`;return{data:{publicUrl:encodeURI(`${this.url}/${a}/public/${n}`)+(i?`?${i}`:``)}}}async remove(e){return this.handleOperation(async()=>await T(this.fetch,`${this.url}/object/${this.bucketId}`,{prefixes:e},{headers:this.headers}))}async list(e,t,n){return this.handleOperation(async()=>{let r={...j,...t,prefix:e||``};return await S(this.fetch,`${this.url}/object/list/${this.bucketId}`,r,{headers:this.headers},n)})}async listV2(e,t){return this.handleOperation(async()=>{let n={...e};return await S(this.fetch,`${this.url}/object/list-v2/${this.bucketId}`,n,{headers:this.headers},t)})}encodeMetadata(e){return JSON.stringify(e)}toBase64(e){return typeof Buffer<`u`?Buffer.from(e).toString(`base64`):btoa(e)}_getFinalPath(e){return`${this.bucketId}/${e.replace(/^\/+/,``)}`}_removeEmptyFolders(e){return e.replace(/^\/|\/$/g,``).replace(/\/+/g,`/`)}applyTransformOptsToQuery(e,t){return t.width&&e.set(`width`,t.width.toString()),t.height&&e.set(`height`,t.height.toString()),t.resize&&e.set(`resize`,t.resize),t.format&&e.set(`format`,t.format),t.quality&&e.set(`quality`,t.quality.toString()),e}};let P={"X-Client-Info":`storage-js/2.104.0-canary.2`};var F=class extends D{constructor(e,t={},n,r){let i=new URL(e);r?.useNewHostname&&/supabase\.(co|in|red)$/.test(i.hostname)&&!i.hostname.includes(`storage.supabase.`)&&(i.hostname=i.hostname.replace(`supabase.`,`storage.supabase.`));let a=i.href.replace(/\/$/,``),o={...P,...t};super(a,o,n,`storage`)}async listBuckets(e){return this.handleOperation(async()=>{let t=this.listBucketOptionsToQueryString(e);return await x(this.fetch,`${this.url}/bucket${t}`,{headers:this.headers})})}async getBucket(e){return this.handleOperation(async()=>await x(this.fetch,`${this.url}/bucket/${e}`,{headers:this.headers}))}async createBucket(e,t={public:!1}){return this.handleOperation(async()=>await S(this.fetch,`${this.url}/bucket`,{id:e,name:e,type:t.type,public:t.public,file_size_limit:t.fileSizeLimit,allowed_mime_types:t.allowedMimeTypes},{headers:this.headers}))}async updateBucket(e,t){return this.handleOperation(async()=>await C(this.fetch,`${this.url}/bucket/${e}`,{id:e,name:e,public:t.public,file_size_limit:t.fileSizeLimit,allowed_mime_types:t.allowedMimeTypes},{headers:this.headers}))}async emptyBucket(e){return this.handleOperation(async()=>await S(this.fetch,`${this.url}/bucket/${e}/empty`,{},{headers:this.headers}))}async deleteBucket(e){return this.handleOperation(async()=>await T(this.fetch,`${this.url}/bucket/${e}`,{},{headers:this.headers}))}listBucketOptionsToQueryString(e){let t={};return e&&(`limit`in e&&(t.limit=String(e.limit)),`offset`in e&&(t.offset=String(e.offset)),e.search&&(t.search=e.search),e.sortColumn&&(t.sortColumn=e.sortColumn),e.sortOrder&&(t.sortOrder=e.sortOrder)),Object.keys(t).length>0?`?`+new URLSearchParams(t).toString():``}},I=class extends Error{constructor(e,t){super(e),this.name=`IcebergError`,this.status=t.status,this.icebergType=t.icebergType,this.icebergCode=t.icebergCode,this.details=t.details,this.isCommitStateUnknown=t.icebergType===`CommitStateUnknownException`||[500,502,504].includes(t.status)&&t.icebergType?.includes(`CommitState`)===!0}isNotFound(){return this.status===404}isConflict(){return this.status===409}isAuthenticationTimeout(){return this.status===419}};function L(e,t,n){let r=new URL(t,e);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&r.searchParams.set(e,t);return r.toString()}async function R(e){return!e||e.type===`none`?{}:e.type===`bearer`?{Authorization:`Bearer ${e.token}`}:e.type===`header`?{[e.name]:e.value}:e.type===`custom`?await e.getHeaders():{}}function z(e){let t=e.fetchImpl??globalThis.fetch;return{async request({method:n,path:r,query:i,body:a,headers:o}){let s=L(e.baseUrl,r,i),c=await R(e.auth),l=await t(s,{method:n,headers:{...a?{"Content-Type":`application/json`}:{},...c,...o},body:a?JSON.stringify(a):void 0}),u=await l.text(),d=(l.headers.get(`content-type`)||``).includes(`application/json`),f=d&&u?JSON.parse(u):u;if(!l.ok){let e=d?f:void 0,t=e?.error;throw new I(t?.message??`Request failed with status ${l.status}`,{status:l.status,icebergType:t?.type,icebergCode:t?.code,details:e})}return{status:l.status,headers:l.headers,data:f}}}}function B(e){return e.join(``)}var V=class{constructor(e,t=``){this.client=e,this.prefix=t}async listNamespaces(e){let t=e?{parent:B(e.namespace)}:void 0;return(await this.client.request({method:`GET`,path:`${this.prefix}/namespaces`,query:t})).data.namespaces.map(e=>({namespace:e}))}async createNamespace(e,t){let n={namespace:e.namespace,properties:t?.properties};return(await this.client.request({method:`POST`,path:`${this.prefix}/namespaces`,body:n})).data}async dropNamespace(e){await this.client.request({method:`DELETE`,path:`${this.prefix}/namespaces/${B(e.namespace)}`})}async loadNamespaceMetadata(e){return{properties:(await this.client.request({method:`GET`,path:`${this.prefix}/namespaces/${B(e.namespace)}`})).data.properties}}async namespaceExists(e){try{return await this.client.request({method:`HEAD`,path:`${this.prefix}/namespaces/${B(e.namespace)}`}),!0}catch(e){if(e instanceof I&&e.status===404)return!1;throw e}}async createNamespaceIfNotExists(e,t){try{return await this.createNamespace(e,t)}catch(e){if(e instanceof I&&e.status===409)return;throw e}}};function H(e){return e.join(``)}var U=class{constructor(e,t=``,n){this.client=e,this.prefix=t,this.accessDelegation=n}async listTables(e){return(await this.client.request({method:`GET`,path:`${this.prefix}/namespaces/${H(e.namespace)}/tables`})).data.identifiers}async createTable(e,t){let n={};return this.accessDelegation&&(n[`X-Iceberg-Access-Delegation`]=this.accessDelegation),(await this.client.request({method:`POST`,path:`${this.prefix}/namespaces/${H(e.namespace)}/tables`,body:t,headers:n})).data.metadata}async updateTable(e,t){let n=await this.client.request({method:`POST`,path:`${this.prefix}/namespaces/${H(e.namespace)}/tables/${e.name}`,body:t});return{"metadata-location":n.data[`metadata-location`],metadata:n.data.metadata}}async dropTable(e,t){await this.client.request({method:`DELETE`,path:`${this.prefix}/namespaces/${H(e.namespace)}/tables/${e.name}`,query:{purgeRequested:String(t?.purge??!1)}})}async loadTable(e){let t={};return this.accessDelegation&&(t[`X-Iceberg-Access-Delegation`]=this.accessDelegation),(await this.client.request({method:`GET`,path:`${this.prefix}/namespaces/${H(e.namespace)}/tables/${e.name}`,headers:t})).data.metadata}async tableExists(e){let t={};this.accessDelegation&&(t[`X-Iceberg-Access-Delegation`]=this.accessDelegation);try{return await this.client.request({method:`HEAD`,path:`${this.prefix}/namespaces/${H(e.namespace)}/tables/${e.name}`,headers:t}),!0}catch(e){if(e instanceof I&&e.status===404)return!1;throw e}}async createTableIfNotExists(e,t){try{return await this.createTable(e,t)}catch(n){if(n instanceof I&&n.status===409)return await this.loadTable({namespace:e.namespace,name:t.name});throw n}}},W=class{constructor(e){let t=`v1`;e.catalogName&&(t+=`/${e.catalogName}`),this.client=z({baseUrl:e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,auth:e.auth,fetchImpl:e.fetch}),this.accessDelegation=e.accessDelegation?.join(`,`),this.namespaceOps=new V(this.client,t),this.tableOps=new U(this.client,t,this.accessDelegation)}async listNamespaces(e){return this.namespaceOps.listNamespaces(e)}async createNamespace(e,t){return this.namespaceOps.createNamespace(e,t)}async dropNamespace(e){await this.namespaceOps.dropNamespace(e)}async loadNamespaceMetadata(e){return this.namespaceOps.loadNamespaceMetadata(e)}async listTables(e){return this.tableOps.listTables(e)}async createTable(e,t){return this.tableOps.createTable(e,t)}async updateTable(e,t){return this.tableOps.updateTable(e,t)}async dropTable(e,t){await this.tableOps.dropTable(e,t)}async loadTable(e){return this.tableOps.loadTable(e)}async namespaceExists(e){return this.namespaceOps.namespaceExists(e)}async tableExists(e){return this.tableOps.tableExists(e)}async createNamespaceIfNotExists(e,t){return this.namespaceOps.createNamespaceIfNotExists(e,t)}async createTableIfNotExists(e,t){return this.tableOps.createTableIfNotExists(e,t)}},G=class extends D{constructor(e,t={},n){let r=e.replace(/\/$/,``),i={...P,...t};super(r,i,n,`storage`)}async createBucket(e){return this.handleOperation(async()=>await S(this.fetch,`${this.url}/bucket`,{name:e},{headers:this.headers}))}async listBuckets(e){return this.handleOperation(async()=>{let t=new URLSearchParams;e?.limit!==void 0&&t.set(`limit`,e.limit.toString()),e?.offset!==void 0&&t.set(`offset`,e.offset.toString()),e?.sortColumn&&t.set(`sortColumn`,e.sortColumn),e?.sortOrder&&t.set(`sortOrder`,e.sortOrder),e?.search&&t.set(`search`,e.search);let n=t.toString(),r=n?`${this.url}/bucket?${n}`:`${this.url}/bucket`;return await x(this.fetch,r,{headers:this.headers})})}async deleteBucket(e){return this.handleOperation(async()=>await T(this.fetch,`${this.url}/bucket/${e}`,{},{headers:this.headers}))}from(e){if(!h(e))throw new t(`Invalid bucket name: File, folder, and bucket names must follow AWS object key naming guidelines and should avoid the use of any other characters.`);let n=new W({baseUrl:this.url,catalogName:e,auth:{type:`custom`,getHeaders:async()=>this.headers},fetch:this.fetch}),r=this.shouldThrowOnError;return new Proxy(n,{get(e,t){let n=e[t];return typeof n==`function`?async(...t)=>{try{return{data:await n.apply(e,t),error:null}}catch(e){if(r)throw e;return{data:null,error:e}}}:n}})}},K=class extends D{constructor(e,t={},n){let r=e.replace(/\/$/,``),i={...P,"Content-Type":`application/json`,...t};super(r,i,n,`vectors`)}async createIndex(e){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/CreateIndex`,e,{headers:this.headers})||{})}async getIndex(e,t){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/GetIndex`,{vectorBucketName:e,indexName:t},{headers:this.headers}))}async listIndexes(e){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/ListIndexes`,e,{headers:this.headers}))}async deleteIndex(e,t){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/DeleteIndex`,{vectorBucketName:e,indexName:t},{headers:this.headers})||{})}},q=class extends D{constructor(e,t={},n){let r=e.replace(/\/$/,``),i={...P,"Content-Type":`application/json`,...t};super(r,i,n,`vectors`)}async putVectors(e){if(e.vectors.length<1||e.vectors.length>500)throw Error(`Vector batch size must be between 1 and 500 items`);return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/PutVectors`,e,{headers:this.headers})||{})}async getVectors(e){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/GetVectors`,e,{headers:this.headers}))}async listVectors(e){if(e.segmentCount!==void 0){if(e.segmentCount<1||e.segmentCount>16)throw Error(`segmentCount must be between 1 and 16`);if(e.segmentIndex!==void 0&&(e.segmentIndex<0||e.segmentIndex>=e.segmentCount))throw Error(`segmentIndex must be between 0 and ${e.segmentCount-1}`)}return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/ListVectors`,e,{headers:this.headers}))}async queryVectors(e){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/QueryVectors`,e,{headers:this.headers}))}async deleteVectors(e){if(e.keys.length<1||e.keys.length>500)throw Error(`Keys batch size must be between 1 and 500 items`);return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/DeleteVectors`,e,{headers:this.headers})||{})}},J=class extends D{constructor(e,t={},n){let r=e.replace(/\/$/,``),i={...P,"Content-Type":`application/json`,...t};super(r,i,n,`vectors`)}async createBucket(e){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/CreateVectorBucket`,{vectorBucketName:e},{headers:this.headers})||{})}async getBucket(e){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/GetVectorBucket`,{vectorBucketName:e},{headers:this.headers}))}async listBuckets(e={}){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/ListVectorBuckets`,e,{headers:this.headers}))}async deleteBucket(e){return this.handleOperation(async()=>await E.post(this.fetch,`${this.url}/DeleteVectorBucket`,{vectorBucketName:e},{headers:this.headers})||{})}},Y=class extends J{constructor(e,t={}){super(e,t.headers||{},t.fetch)}from(e){return new X(this.url,this.headers,e,this.fetch)}async createBucket(e){return super.createBucket(e)}async getBucket(e){return super.getBucket(e)}async listBuckets(e={}){return super.listBuckets(e)}async deleteBucket(e){return super.deleteBucket(e)}},X=class extends K{constructor(e,t,n,r){super(e,t,r),this.vectorBucketName=n}async createIndex(e){return super.createIndex({...e,vectorBucketName:this.vectorBucketName})}async listIndexes(e={}){return super.listIndexes({...e,vectorBucketName:this.vectorBucketName})}async getIndex(e){return super.getIndex(this.vectorBucketName,e)}async deleteIndex(e){return super.deleteIndex(this.vectorBucketName,e)}index(e){return new Z(this.url,this.headers,this.vectorBucketName,e,this.fetch)}},Z=class extends q{constructor(e,t,n,r,i){super(e,t,i),this.vectorBucketName=n,this.indexName=r}async putVectors(e){return super.putVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}async getVectors(e){return super.getVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}async listVectors(e={}){return super.listVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}async queryVectors(e){return super.queryVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}async deleteVectors(e){return super.deleteVectors({...e,vectorBucketName:this.vectorBucketName,indexName:this.indexName})}},Q=class extends F{constructor(e,t={},n,r){super(e,t,n,r)}from(e){return new N(this.url,this.headers,e,this.fetch)}get vectors(){return new Y(this.url+`/vector`,{headers:this.headers,fetch:this.fetch})}get analytics(){return new G(this.url+`/iceberg`,this.headers,this.fetch)}};return e.StorageAnalyticsClient=G,e.StorageApiError=r,e.StorageClient=Q,e.StorageError=t,e.StorageUnknownError=i,e.StorageVectorsApiError=s,e.StorageVectorsClient=Y,e.StorageVectorsError=a,e.StorageVectorsErrorCode=l,e.StorageVectorsUnknownError=c,e.VectorBucketApi=J,e.VectorBucketScope=X,e.VectorDataApi=q,e.VectorIndexApi=K,e.VectorIndexScope=Z,e.isStorageError=n,e.isStorageVectorsError=o,e})({});
|
package/package.json
CHANGED
package/src/StorageClient.ts
CHANGED
|
@@ -13,12 +13,20 @@ export class StorageClient extends StorageBucketApi {
|
|
|
13
13
|
* Creates a client for Storage buckets, files, analytics, and vectors.
|
|
14
14
|
*
|
|
15
15
|
* @category File Buckets
|
|
16
|
-
* @example
|
|
16
|
+
* @example Using supabase-js (recommended)
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { createClient } from '@supabase/supabase-js'
|
|
19
|
+
*
|
|
20
|
+
* const supabase = createClient('https://xyzcompany.supabase.co', 'publishable-or-anon-key')
|
|
21
|
+
* const avatars = supabase.storage.from('avatars')
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example Standalone import for bundle-sensitive environments
|
|
17
25
|
* ```ts
|
|
18
26
|
* import { StorageClient } from '@supabase/storage-js'
|
|
19
27
|
*
|
|
20
28
|
* const storage = new StorageClient('https://xyzcompany.supabase.co/storage/v1', {
|
|
21
|
-
* apikey: '
|
|
29
|
+
* apikey: 'publishable-or-anon-key',
|
|
22
30
|
* })
|
|
23
31
|
* const avatars = storage.from('avatars')
|
|
24
32
|
* ```
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ErrorNamespace, isStorageError, StorageError } from './errors'
|
|
2
2
|
import { Fetch } from './fetch'
|
|
3
|
+
import { normalizeHeaders, setHeader as setHeaderUtil } from './headers'
|
|
3
4
|
import { resolveFetch } from './helpers'
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -30,7 +31,7 @@ export default abstract class BaseApiClient<TError extends StorageError = Storag
|
|
|
30
31
|
namespace: ErrorNamespace = 'storage'
|
|
31
32
|
) {
|
|
32
33
|
this.url = url
|
|
33
|
-
this.headers = headers
|
|
34
|
+
this.headers = normalizeHeaders(headers)
|
|
34
35
|
this.fetch = resolveFetch(fetch)
|
|
35
36
|
this.namespace = namespace
|
|
36
37
|
}
|
|
@@ -55,7 +56,7 @@ export default abstract class BaseApiClient<TError extends StorageError = Storag
|
|
|
55
56
|
* @returns this - For method chaining
|
|
56
57
|
*/
|
|
57
58
|
public setHeader(name: string, value: string): this {
|
|
58
|
-
this.headers =
|
|
59
|
+
this.headers = setHeaderUtil(this.headers, name, value)
|
|
59
60
|
return this
|
|
60
61
|
}
|
|
61
62
|
|
package/src/lib/common/errors.ts
CHANGED
|
@@ -26,6 +26,20 @@ export class StorageError extends Error {
|
|
|
26
26
|
this.status = status
|
|
27
27
|
this.statusCode = statusCode
|
|
28
28
|
}
|
|
29
|
+
|
|
30
|
+
toJSON(): {
|
|
31
|
+
name: string
|
|
32
|
+
message: string
|
|
33
|
+
status: number | undefined
|
|
34
|
+
statusCode: string | undefined
|
|
35
|
+
} {
|
|
36
|
+
return {
|
|
37
|
+
name: this.name,
|
|
38
|
+
message: this.message,
|
|
39
|
+
status: this.status,
|
|
40
|
+
statusCode: this.statusCode,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
29
43
|
}
|
|
30
44
|
|
|
31
45
|
/**
|
|
@@ -57,12 +71,14 @@ export class StorageApiError extends StorageError {
|
|
|
57
71
|
this.statusCode = statusCode
|
|
58
72
|
}
|
|
59
73
|
|
|
60
|
-
toJSON() {
|
|
74
|
+
toJSON(): {
|
|
75
|
+
name: string
|
|
76
|
+
message: string
|
|
77
|
+
status: number | undefined
|
|
78
|
+
statusCode: string | undefined
|
|
79
|
+
} {
|
|
61
80
|
return {
|
|
62
|
-
|
|
63
|
-
message: this.message,
|
|
64
|
-
status: this.status,
|
|
65
|
-
statusCode: this.statusCode,
|
|
81
|
+
...super.toJSON(),
|
|
66
82
|
}
|
|
67
83
|
}
|
|
68
84
|
}
|
package/src/lib/common/fetch.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StorageApiError, StorageUnknownError, ErrorNamespace } from './errors'
|
|
2
|
+
import { setHeader } from './headers'
|
|
2
3
|
import { isPlainObject, resolveResponse } from './helpers'
|
|
3
4
|
import { FetchParameters } from '../types'
|
|
4
5
|
|
|
@@ -95,7 +96,16 @@ const _getRequestParams = (
|
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
if (isPlainObject(body)) {
|
|
98
|
-
|
|
99
|
+
const headers = options?.headers || {}
|
|
100
|
+
let contentType: string | undefined
|
|
101
|
+
|
|
102
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
103
|
+
if (key.toLowerCase() === 'content-type') {
|
|
104
|
+
contentType = value
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
params.headers = setHeader(headers, 'Content-Type', contentType ?? 'application/json')
|
|
99
109
|
params.body = JSON.stringify(body)
|
|
100
110
|
} else {
|
|
101
111
|
params.body = body
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sets a header with case-insensitive deduplication.
|
|
3
|
+
* Removes any existing headers whose name matches (case-insensitive),
|
|
4
|
+
* then sets the value under the lowercase key. Does not mutate the input object.
|
|
5
|
+
*
|
|
6
|
+
* @param headers - Existing headers object
|
|
7
|
+
* @param name - Header name to set (stored as lowercase)
|
|
8
|
+
* @param value - Header value
|
|
9
|
+
* @returns New headers object with the header set
|
|
10
|
+
*/
|
|
11
|
+
export function setHeader(
|
|
12
|
+
headers: Record<string, string>,
|
|
13
|
+
name: string,
|
|
14
|
+
value: string
|
|
15
|
+
): Record<string, string> {
|
|
16
|
+
const result = { ...headers }
|
|
17
|
+
const nameLower = name.toLowerCase()
|
|
18
|
+
|
|
19
|
+
for (const key of Object.keys(result)) {
|
|
20
|
+
if (key.toLowerCase() === nameLower) {
|
|
21
|
+
delete result[key]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
result[nameLower] = value
|
|
26
|
+
return result
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Normalizes all header keys to lowercase with case-insensitive deduplication.
|
|
31
|
+
* When duplicate keys exist (differing only in case), the last value wins.
|
|
32
|
+
* Does not mutate the input object.
|
|
33
|
+
*
|
|
34
|
+
* @param headers - Headers object to normalize
|
|
35
|
+
* @returns New headers object with all keys lowercased
|
|
36
|
+
*/
|
|
37
|
+
export function normalizeHeaders(headers: Record<string, string>): Record<string, string> {
|
|
38
|
+
const result: Record<string, string> = {}
|
|
39
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
40
|
+
result[key.toLowerCase()] = value
|
|
41
|
+
}
|
|
42
|
+
return result
|
|
43
|
+
}
|
package/src/lib/version.ts
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
// - Debugging and support (identifying which version is running)
|
|
5
5
|
// - Telemetry and logging (version reporting in errors/analytics)
|
|
6
6
|
// - Ensuring build artifacts match the published package version
|
|
7
|
-
export const version = '2.104.0-canary.
|
|
7
|
+
export const version = '2.104.0-canary.2'
|
|
@@ -31,8 +31,18 @@ export default class StorageAnalyticsClient extends BaseApiClient<StorageError>
|
|
|
31
31
|
* @param headers - HTTP headers to include in requests
|
|
32
32
|
* @param fetch - Optional custom fetch implementation
|
|
33
33
|
*
|
|
34
|
-
* @example
|
|
34
|
+
* @example Using supabase-js (recommended)
|
|
35
35
|
* ```typescript
|
|
36
|
+
* import { createClient } from '@supabase/supabase-js'
|
|
37
|
+
*
|
|
38
|
+
* const supabase = createClient('https://xyzcompany.supabase.co', 'publishable-or-anon-key')
|
|
39
|
+
* const { data, error } = await supabase.storage.analytics.listBuckets()
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example Standalone import for bundle-sensitive environments
|
|
43
|
+
* ```typescript
|
|
44
|
+
* import { StorageAnalyticsClient } from '@supabase/storage-js'
|
|
45
|
+
*
|
|
36
46
|
* const client = new StorageAnalyticsClient(url, headers)
|
|
37
47
|
* ```
|
|
38
48
|
*/
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
isStorageError,
|
|
6
6
|
} from '../lib/common/errors'
|
|
7
7
|
import { get, head, post, put, remove, Fetch } from '../lib/common/fetch'
|
|
8
|
+
import { setHeader } from '../lib/common/headers'
|
|
8
9
|
import { recursiveToCamel } from '../lib/common/helpers'
|
|
9
10
|
import BaseApiClient from '../lib/common/BaseApiClient'
|
|
10
11
|
import {
|
|
@@ -130,7 +131,9 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
130
131
|
}
|
|
131
132
|
|
|
132
133
|
if (fileOptions?.headers) {
|
|
133
|
-
|
|
134
|
+
for (const [key, value] of Object.entries(fileOptions.headers)) {
|
|
135
|
+
headers = setHeader(headers, key, value)
|
|
136
|
+
}
|
|
134
137
|
}
|
|
135
138
|
|
|
136
139
|
const cleanPath = this._removeEmptyFolders(path)
|
|
@@ -578,6 +581,7 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
578
581
|
* @param expiresIn The number of seconds until the signed URL expires. For example, `60` for a URL which is valid for one minute.
|
|
579
582
|
* @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.
|
|
580
583
|
* @param options.transform Transform the asset before serving it to the client.
|
|
584
|
+
* @param options.cacheNonce Append a cache nonce parameter to the URL to invalidate the cache.
|
|
581
585
|
* @returns Promise with response containing signed URL or error
|
|
582
586
|
*
|
|
583
587
|
* @example Create Signed URL
|
|
@@ -630,7 +634,11 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
630
634
|
async createSignedUrl(
|
|
631
635
|
path: string,
|
|
632
636
|
expiresIn: number,
|
|
633
|
-
options?: {
|
|
637
|
+
options?: {
|
|
638
|
+
download?: string | boolean
|
|
639
|
+
transform?: TransformOptions
|
|
640
|
+
cacheNonce?: string
|
|
641
|
+
}
|
|
634
642
|
): Promise<
|
|
635
643
|
| {
|
|
636
644
|
data: { signedUrl: string }
|
|
@@ -655,17 +663,19 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
655
663
|
{ expiresIn, ...(hasTransform ? { transform: options!.transform } : {}) },
|
|
656
664
|
{ headers: this.headers }
|
|
657
665
|
)
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
666
|
+
|
|
667
|
+
const query = new URLSearchParams()
|
|
668
|
+
if (options?.download)
|
|
669
|
+
query.set('download', options.download === true ? '' : options.download)
|
|
670
|
+
if (options?.cacheNonce != null) query.set('cacheNonce', String(options.cacheNonce))
|
|
671
|
+
const queryString = query.toString()
|
|
672
|
+
|
|
673
|
+
// `data.signedURL` contains a `token` query parameter, so append extra params with `&`
|
|
674
|
+
// only when we actually have something to add.
|
|
675
|
+
const signedUrl = encodeURI(
|
|
676
|
+
`${this.url}${data.signedURL}${queryString ? `&${queryString}` : ''}`
|
|
677
|
+
)
|
|
678
|
+
|
|
669
679
|
return { signedUrl }
|
|
670
680
|
})
|
|
671
681
|
}
|
|
@@ -677,6 +687,7 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
677
687
|
* @param paths The file paths to be downloaded, including the current file names. For example `['folder/image.png', 'folder2/image2.png']`.
|
|
678
688
|
* @param expiresIn The number of seconds until the signed URLs expire. For example, `60` for URLs which are valid for one minute.
|
|
679
689
|
* @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.
|
|
690
|
+
* @param options.cacheNonce Append a cache nonce parameter to the URL to invalidate the cache.
|
|
680
691
|
* @returns Promise with response containing array of objects with signedUrl, path, and error or error
|
|
681
692
|
*
|
|
682
693
|
* @example Create Signed URLs
|
|
@@ -717,10 +728,10 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
717
728
|
async createSignedUrls(
|
|
718
729
|
paths: string[],
|
|
719
730
|
expiresIn: number,
|
|
720
|
-
options?: { download
|
|
731
|
+
options?: { download?: string | boolean; cacheNonce?: string }
|
|
721
732
|
): Promise<
|
|
722
733
|
| {
|
|
723
|
-
data: { error: string | null; path: string | null; signedUrl: string }[]
|
|
734
|
+
data: { error: string | null; path: string | null; signedUrl: string | null }[]
|
|
724
735
|
error: null
|
|
725
736
|
}
|
|
726
737
|
| {
|
|
@@ -736,13 +747,18 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
736
747
|
{ headers: this.headers }
|
|
737
748
|
)
|
|
738
749
|
|
|
739
|
-
const
|
|
740
|
-
|
|
741
|
-
|
|
750
|
+
const query = new URLSearchParams()
|
|
751
|
+
|
|
752
|
+
if (options?.download)
|
|
753
|
+
query.set('download', options.download === true ? '' : options.download)
|
|
754
|
+
if (options?.cacheNonce != null) query.set('cacheNonce', String(options.cacheNonce))
|
|
755
|
+
|
|
756
|
+
const queryString = query.toString()
|
|
757
|
+
|
|
742
758
|
return data.map((datum: { signedURL: string }) => ({
|
|
743
759
|
...datum,
|
|
744
760
|
signedUrl: datum.signedURL
|
|
745
|
-
? encodeURI(`${this.url}${datum.signedURL}${
|
|
761
|
+
? encodeURI(`${this.url}${datum.signedURL}${queryString ? `&${queryString}` : ''}`)
|
|
746
762
|
: null,
|
|
747
763
|
}))
|
|
748
764
|
})
|
|
@@ -754,6 +770,7 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
754
770
|
* @category File Buckets
|
|
755
771
|
* @param path The full path and file name of the file to be downloaded. For example `folder/image.png`.
|
|
756
772
|
* @param options.transform Transform the asset before serving it to the client.
|
|
773
|
+
* @param options.cacheNonce Append a cache nonce parameter to the URL to invalidate the cache.
|
|
757
774
|
* @param parameters Additional fetch parameters like signal for cancellation. Supports standard fetch options including cache control.
|
|
758
775
|
* @returns BlobDownloadBuilder instance for downloading the file
|
|
759
776
|
*
|
|
@@ -812,20 +829,27 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
812
829
|
* - `objects` table permissions: `select`
|
|
813
830
|
* - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
814
831
|
*/
|
|
815
|
-
download<Options extends { transform?: TransformOptions }>(
|
|
832
|
+
download<Options extends { transform?: TransformOptions; cacheNonce?: string }>(
|
|
816
833
|
path: string,
|
|
817
834
|
options?: Options,
|
|
818
835
|
parameters?: FetchParameters
|
|
819
836
|
): BlobDownloadBuilder {
|
|
820
|
-
const wantsTransformation =
|
|
837
|
+
const wantsTransformation =
|
|
838
|
+
typeof options?.transform === 'object' &&
|
|
839
|
+
options.transform !== null &&
|
|
840
|
+
Object.keys(options.transform).length > 0
|
|
821
841
|
const renderPath = wantsTransformation ? 'render/image/authenticated' : 'object'
|
|
822
|
-
|
|
823
|
-
const
|
|
842
|
+
|
|
843
|
+
const query = new URLSearchParams()
|
|
844
|
+
if (options?.transform) this.applyTransformOptsToQuery(query, options.transform)
|
|
845
|
+
if (options?.cacheNonce != null) query.set('cacheNonce', String(options.cacheNonce))
|
|
846
|
+
const queryString = query.toString()
|
|
847
|
+
|
|
824
848
|
const _path = this._getFinalPath(path)
|
|
825
849
|
const downloadFn = () =>
|
|
826
850
|
get(
|
|
827
851
|
this.fetch,
|
|
828
|
-
`${this.url}/${renderPath}/${_path}${queryString}`,
|
|
852
|
+
`${this.url}/${renderPath}/${_path}${queryString ? `?${queryString}` : ''}`,
|
|
829
853
|
{
|
|
830
854
|
headers: this.headers,
|
|
831
855
|
noResolveJson: true,
|
|
@@ -942,6 +966,7 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
942
966
|
* @param path The path and name of the file to generate the public URL for. For example `folder/image.png`.
|
|
943
967
|
* @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.
|
|
944
968
|
* @param options.transform Transform the asset before serving it to the client.
|
|
969
|
+
* @param options.cacheNonce Append a cache nonce parameter to the URL to invalidate the cache.
|
|
945
970
|
* @returns Object with public URL
|
|
946
971
|
*
|
|
947
972
|
* @example Returns the URL for an asset in a public bucket
|
|
@@ -993,34 +1018,32 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
993
1018
|
*/
|
|
994
1019
|
getPublicUrl(
|
|
995
1020
|
path: string,
|
|
996
|
-
options?: {
|
|
1021
|
+
options?: {
|
|
1022
|
+
download?: string | boolean
|
|
1023
|
+
transform?: TransformOptions
|
|
1024
|
+
cacheNonce?: string
|
|
1025
|
+
}
|
|
997
1026
|
): { data: { publicUrl: string } } {
|
|
998
1027
|
const _path = this._getFinalPath(path)
|
|
999
|
-
const _queryString: string[] = []
|
|
1000
|
-
|
|
1001
|
-
const downloadQueryParam = options?.download
|
|
1002
|
-
? `download=${options.download === true ? '' : options.download}`
|
|
1003
|
-
: ''
|
|
1004
1028
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1029
|
+
const query = new URLSearchParams()
|
|
1030
|
+
if (options?.download) query.set('download', options.download === true ? '' : options.download)
|
|
1031
|
+
if (options?.transform) this.applyTransformOptsToQuery(query, options.transform)
|
|
1032
|
+
if (options?.cacheNonce != null) query.set('cacheNonce', String(options.cacheNonce))
|
|
1033
|
+
const queryString = query.toString()
|
|
1008
1034
|
|
|
1009
|
-
const wantsTransformation =
|
|
1035
|
+
const wantsTransformation =
|
|
1036
|
+
typeof options?.transform === 'object' &&
|
|
1037
|
+
options.transform !== null &&
|
|
1038
|
+
Object.keys(options.transform).length > 0
|
|
1010
1039
|
const renderPath = wantsTransformation ? 'render/image' : 'object'
|
|
1011
|
-
const transformationQuery = this.transformOptsToQueryString(options?.transform || {})
|
|
1012
|
-
|
|
1013
|
-
if (transformationQuery !== '') {
|
|
1014
|
-
_queryString.push(transformationQuery)
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
let queryString = _queryString.join('&')
|
|
1018
|
-
if (queryString !== '') {
|
|
1019
|
-
queryString = `?${queryString}`
|
|
1020
|
-
}
|
|
1021
1040
|
|
|
1022
1041
|
return {
|
|
1023
|
-
data: {
|
|
1042
|
+
data: {
|
|
1043
|
+
publicUrl:
|
|
1044
|
+
encodeURI(`${this.url}/${renderPath}/public/${_path}`) +
|
|
1045
|
+
(queryString ? `?${queryString}` : ''),
|
|
1046
|
+
},
|
|
1024
1047
|
}
|
|
1025
1048
|
}
|
|
1026
1049
|
|
|
@@ -1336,28 +1359,17 @@ export default class StorageFileApi extends BaseApiClient<StorageError> {
|
|
|
1336
1359
|
return path.replace(/^\/|\/$/g, '').replace(/\/+/g, '/')
|
|
1337
1360
|
}
|
|
1338
1361
|
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
if (transform.height)
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
}
|
|
1352
|
-
|
|
1353
|
-
if (transform.format) {
|
|
1354
|
-
params.push(`format=${transform.format}`)
|
|
1355
|
-
}
|
|
1356
|
-
|
|
1357
|
-
if (transform.quality) {
|
|
1358
|
-
params.push(`quality=${transform.quality}`)
|
|
1359
|
-
}
|
|
1360
|
-
|
|
1361
|
-
return params.join('&')
|
|
1362
|
+
/** Modifies the `query`, appending values the from `transform` */
|
|
1363
|
+
private applyTransformOptsToQuery(
|
|
1364
|
+
query: URLSearchParams,
|
|
1365
|
+
transform: TransformOptions
|
|
1366
|
+
): URLSearchParams {
|
|
1367
|
+
if (transform.width) query.set('width', transform.width.toString())
|
|
1368
|
+
if (transform.height) query.set('height', transform.height.toString())
|
|
1369
|
+
if (transform.resize) query.set('resize', transform.resize)
|
|
1370
|
+
if (transform.format) query.set('format', transform.format)
|
|
1371
|
+
if (transform.quality) query.set('quality', transform.quality.toString())
|
|
1372
|
+
|
|
1373
|
+
return query
|
|
1362
1374
|
}
|
|
1363
1375
|
}
|
|
@@ -90,8 +90,18 @@ export class StorageVectorsClient extends VectorBucketApi {
|
|
|
90
90
|
* @param options.headers - Optional headers (for example `Authorization`) applied to every request.
|
|
91
91
|
* @param options.fetch - Optional custom `fetch` implementation for non-browser runtimes.
|
|
92
92
|
*
|
|
93
|
-
* @example
|
|
93
|
+
* @example Using supabase-js (recommended)
|
|
94
94
|
* ```typescript
|
|
95
|
+
* import { createClient } from '@supabase/supabase-js'
|
|
96
|
+
*
|
|
97
|
+
* const supabase = createClient('https://xyzcompany.supabase.co', 'publishable-or-anon-key')
|
|
98
|
+
* const bucket = supabase.storage.vectors.from('embeddings-prod')
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @example Standalone import for bundle-sensitive environments
|
|
102
|
+
* ```typescript
|
|
103
|
+
* import { StorageVectorsClient } from '@supabase/storage-js'
|
|
104
|
+
*
|
|
95
105
|
* const client = new StorageVectorsClient(url, options)
|
|
96
106
|
* ```
|
|
97
107
|
*/
|