@visulima/storage 1.0.0-alpha.31 → 1.0.0-alpha.33
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/CHANGELOG.md +45 -0
- package/README.md +2 -2
- package/dist/adapter/nuxt/module.d.ts +4 -4
- package/dist/ai/ai-sdk/index.d.ts +5 -5
- package/dist/ai/ai-sdk/index.js +1 -1
- package/dist/ai/claude/index.d.ts +4 -4
- package/dist/ai/claude/index.js +1 -1
- package/dist/ai/openai/index.d.ts +5 -5
- package/dist/ai/openai/index.js +1 -1
- package/dist/ai/tanstack/index.d.ts +4 -4
- package/dist/ai/tanstack/index.js +1 -1
- package/dist/handler/http/fetch/index.d.ts +7 -7
- package/dist/handler/http/fetch/index.js +1 -1
- package/dist/handler/http/hono/index.d.ts +4 -4
- package/dist/handler/http/hono/index.js +1 -1
- package/dist/handler/http/nextjs/index.d.ts +4 -4
- package/dist/handler/http/nextjs/index.js +1 -1
- package/dist/handler/http/node/index.d.ts +7 -7
- package/dist/handler/http/node/index.js +1 -1
- package/dist/handler/http/solid-start/index.d.ts +4 -4
- package/dist/handler/http/solid-start/index.js +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +1 -1
- package/dist/packem_shared/{AwsLightMetaStorage-B-iQbToR.js → AwsLightMetaStorage-Cj7ym1qI.js} +1 -1
- package/dist/packem_shared/{AwsLightStorage-DbQrK9m7.js → AwsLightStorage-6Z1ovz9R.js} +1 -1
- package/dist/packem_shared/AzureSMetaStorage-YCj-X8a1.js +1 -0
- package/dist/packem_shared/AzureStorage-CbAN4vPm.js +1 -0
- package/dist/packem_shared/{BoxMetaStorage-DLdXbZaV.js → BoxMetaStorage-BGBPZWoL.js} +1 -1
- package/dist/packem_shared/BoxStorage-DitlyKVB.js +1 -0
- package/dist/packem_shared/{BunS3MetaStorage-Bv_CTTMz.js → BunS3MetaStorage-DAskpG_G.js} +1 -1
- package/dist/packem_shared/BunS3Storage-D1gxh5Tt.js +1 -0
- package/dist/packem_shared/{BunnyMetaStorage-DNMTSeoN.js → BunnyMetaStorage-ByUvvuPc.js} +1 -1
- package/dist/packem_shared/BunnyStorage-r6DptjUt.js +1 -0
- package/dist/packem_shared/{CloudinaryMetaStorage-DEBk5eQy.js → CloudinaryMetaStorage-DsJyN0iQ.js} +1 -1
- package/dist/packem_shared/CloudinaryStorage-BR8CZhlL.js +1 -0
- package/dist/packem_shared/DiskStorage-DHcHDZeO.js +1 -0
- package/dist/packem_shared/DiskStorageWithChecksum--U7zOz-0.js +1 -0
- package/dist/packem_shared/{DropboxMetaStorage-C6vj1QDA.js → DropboxMetaStorage-B7eY16fU.js} +1 -1
- package/dist/packem_shared/DropboxStorage-9-jj7H8C.js +1 -0
- package/dist/packem_shared/ERRORS-vMSqlI69.js +1 -0
- package/dist/packem_shared/{FirebaseMetaStorage-CzyOim-J.js → FirebaseMetaStorage-BpYykWhG.js} +1 -1
- package/dist/packem_shared/FirebaseStorage-DB87abIF.js +2 -0
- package/dist/packem_shared/{FtpMetaStorage-1Njy0DpU.js → FtpMetaStorage-v2wXTwqX.js} +1 -1
- package/dist/packem_shared/FtpStorage-DdRf0Wg6.js +1 -0
- package/dist/packem_shared/{GCSMetaStorage-DFIjFmn-.js → GCSMetaStorage-BMtou9o7.js} +1 -1
- package/dist/packem_shared/GCStorage-CRVpuZ5_.js +1 -0
- package/dist/packem_shared/{GoogleDriveMetaStorage-WGuUZPyx.js → GoogleDriveMetaStorage-BT9N1Wji.js} +1 -1
- package/dist/packem_shared/GoogleDriveStorage-BzuSZZzN.js +1 -0
- package/dist/packem_shared/LocalMetaStorage-BFQz8VPm.js +1 -0
- package/dist/packem_shared/MemoryMetaStorage-DEzfBNgL.js +1 -0
- package/dist/packem_shared/MemoryStorage-BuNY963D.js +1 -0
- package/dist/packem_shared/{Multipart-C6Mw7V9W.js → Multipart-IE3j_gAJ.js} +1 -1
- package/dist/packem_shared/{Multipart-DkH4QwNs.js → Multipart-UIRqOPCf.js} +1 -1
- package/dist/packem_shared/{NetlifyBlobMetaStorage-ClIFdTkT.js → NetlifyBlobMetaStorage-DNgncijZ.js} +1 -1
- package/dist/packem_shared/NetlifyBlobStorage-eP0pkR0o.js +1 -0
- package/dist/packem_shared/{OneDriveMetaStorage-DS4f83X2.js → OneDriveMetaStorage-CkaFJFHe.js} +1 -1
- package/dist/packem_shared/OneDriveStorage-3Iq5vBfd.js +1 -0
- package/dist/packem_shared/{PocketBaseMetaStorage-B6utPncj.js → PocketBaseMetaStorage-CxnGde_n.js} +1 -1
- package/dist/packem_shared/PocketBaseStorage-DHphg8yi.js +1 -0
- package/dist/packem_shared/{Rest-DWrS4Z_j.js → Rest-B_E4TrqF.js} +1 -1
- package/dist/packem_shared/{Rest-DY1neM_3.js → Rest-DItHKz-N.js} +1 -1
- package/dist/packem_shared/S3Storage-Bc9eq5vJ.js +1 -0
- package/dist/packem_shared/{SftpMetaStorage-DYqXwCdM.js → SftpMetaStorage-CBcUhZRU.js} +1 -1
- package/dist/packem_shared/SftpStorage-DSsMhTZC.js +1 -0
- package/dist/packem_shared/{SharePointMetaStorage-DVM5-X6g.js → SharePointMetaStorage-yzxvwgKr.js} +1 -1
- package/dist/packem_shared/{SharePointStorage-r934t5HX.js → SharePointStorage-C6KIGN2r.js} +1 -1
- package/dist/packem_shared/{SupabaseMetaStorage-ivXoYVUu.js → SupabaseMetaStorage-D26wob-R.js} +1 -1
- package/dist/packem_shared/SupabaseStorage-B_knTpFQ.js +1 -0
- package/dist/packem_shared/{Tus-BMd67Cnb.js → Tus-CAestp2j.js} +1 -1
- package/dist/packem_shared/{Tus-d2hPK5nV.js → Tus-KQ8J2WF3.js} +1 -1
- package/dist/packem_shared/UploadControl-Otw_5jxw.js +1 -0
- package/dist/packem_shared/{UploadThingMetaStorage-BvKNzgm7.js → UploadThingMetaStorage-DPIokkHa.js} +1 -1
- package/dist/packem_shared/UploadThingStorage-B3aIKSMh.js +1 -0
- package/dist/packem_shared/{VercelBlobMetaStorage-CwaqWucZ.js → VercelBlobMetaStorage-Bx0l9Xt6.js} +1 -1
- package/dist/packem_shared/VercelBlobStorage-CGxoGkv4.js +1 -0
- package/dist/packem_shared/{agentsListFiles-R-CnGKc4.js → agentsListFiles-Bl2TOnMy.js} +1 -1
- package/dist/packem_shared/{approval.d-CMAYH9GF.d.ts → approval.d-3sw7wbPG.d.ts} +1 -1
- package/dist/packem_shared/aws-light-meta-storage-CXIZfLXR.js +4 -0
- package/dist/packem_shared/{azure-meta-storage-C4SrMtT2.js → azure-meta-storage-B-D-tBVw.js} +1 -1
- package/dist/packem_shared/{base-handler-core-Cwd9uq_E.js → base-handler-core-OdTz4-Pm.js} +1 -1
- package/dist/packem_shared/{base-handler-fetch-_BD4V1W2.js → base-handler-fetch-B0FWPun7.js} +1 -1
- package/dist/packem_shared/{base-handler-node-BDNRnVIc.js → base-handler-node-CR2Bg43M.js} +1 -1
- package/dist/packem_shared/{claudeListFiles-DAezbKEi.js → claudeListFiles-yLqM5iFS.js} +1 -1
- package/dist/packem_shared/{createResponsesFileTools-BCep-qdO.js → createResponsesFileTools-DFFHq35s.js} +1 -1
- package/dist/packem_shared/{defaultCloudStorageFileNameValidation-hWLdEgOD.js → defaultCloudStorageFileNameValidation-De0HFP7m.js} +1 -1
- package/dist/packem_shared/disk-storage-CklneE2m.js +1 -0
- package/dist/packem_shared/{disk-storage-with-checksum.d-Dm4agCey.d.ts → disk-storage-with-checksum.d-Z_Z-OQpm.d.ts} +8 -2
- package/dist/packem_shared/executors-MzQbS9FT.js +1 -0
- package/dist/packem_shared/{executors.d-Cut3Gstb.d.ts → executors.d-CRI3jlk4.d.ts} +2 -2
- package/dist/packem_shared/{gcs-meta-storage-Bwts-MUe.js → gcs-meta-storage-Dh0TAqB_.js} +1 -1
- package/dist/packem_shared/get-file-status-DLS18Zvd.js +1 -0
- package/dist/packem_shared/index.d-C4o9jVLx.d.ts +672 -0
- package/dist/packem_shared/isRetryableError-CBZ65V6T.js +1 -0
- package/dist/packem_shared/{listFiles-BtP6VnUp.js → listFiles-BNGQbV_d.js} +1 -1
- package/dist/packem_shared/{listFiles-B6VF05d-.js → listFiles-BdBngq3i.js} +1 -1
- package/dist/packem_shared/{local-meta-storage-Bi0mK6gD.js → local-meta-storage-Bvl0Flac.js} +1 -1
- package/dist/packem_shared/{local-meta-storage.d-qZQI1JUe.d.ts → local-meta-storage.d-CobcjyWu.d.ts} +1 -1
- package/dist/packem_shared/{media-transformer.d-lQ_RUjb5.d.ts → media-transformer.d-B5cQJz30.d.ts} +2 -2
- package/dist/packem_shared/memory-storage.d-CunLnxmE.d.ts +101 -0
- package/dist/packem_shared/part-match-D_NwyoF3.js +1 -0
- package/dist/packem_shared/{rest-base-C-a7pXUc.js → rest-base-DHkzq0rj.js} +1 -1
- package/dist/packem_shared/s3-base-storage-o_zkj15Y.js +1 -0
- package/dist/packem_shared/{s3-base-storage.d-CDIOMTpp.d.ts → s3-base-storage.d-ByfwKeid.d.ts} +29 -2
- package/dist/packem_shared/storage-z0o24zmZ.js +1 -0
- package/dist/packem_shared/{storage.d-BoJgdi1n.d.ts → storage.d-D5UN5mRz.d.ts} +65 -1
- package/dist/packem_shared/{tus-base.d-C28C_AY9.d.ts → tus-base.d-D7UPhqdW.d.ts} +3 -3
- package/dist/packem_shared/{types.d-DCPQvHDI.d.ts → types.d-BsjUOfBJ.d.ts} +2 -2
- package/dist/packem_shared/{types.d-CPxJpoPH.d.ts → types.d-CPUyyEj9.d.ts} +2 -2
- package/dist/packem_shared/{types.d-C0MDnUYc.d.ts → types.d-GogSTfRh.d.ts} +1 -1
- package/dist/storage/aws/index.d.ts +14 -3
- package/dist/storage/aws/index.js +1 -1
- package/dist/storage/aws-light/index.d.ts +7 -2
- package/dist/storage/aws-light/index.js +1 -1
- package/dist/storage/azure/index.d.ts +26 -7
- package/dist/storage/azure/index.js +1 -1
- package/dist/storage/box/index.d.ts +2 -2
- package/dist/storage/box/index.js +1 -1
- package/dist/storage/bun-s3/index.d.ts +2 -2
- package/dist/storage/bun-s3/index.js +1 -1
- package/dist/storage/bunny/index.d.ts +2 -2
- package/dist/storage/bunny/index.js +1 -1
- package/dist/storage/cloudinary/index.d.ts +2 -2
- package/dist/storage/cloudinary/index.js +1 -1
- package/dist/storage/dropbox/index.d.ts +2 -2
- package/dist/storage/dropbox/index.js +1 -1
- package/dist/storage/firebase/index.d.ts +2 -2
- package/dist/storage/firebase/index.js +1 -1
- package/dist/storage/ftp/index.d.ts +9 -3
- package/dist/storage/ftp/index.js +1 -1
- package/dist/storage/gcs/index.d.ts +15 -1
- package/dist/storage/gcs/index.js +1 -1
- package/dist/storage/google-drive/index.d.ts +2 -2
- package/dist/storage/google-drive/index.js +1 -1
- package/dist/storage/local/index.d.ts +3 -3
- package/dist/storage/local/index.js +1 -1
- package/dist/storage/memory/index.d.ts +6 -0
- package/dist/storage/memory/index.js +1 -0
- package/dist/storage/netlify-blob/index.d.ts +2 -2
- package/dist/storage/netlify-blob/index.js +1 -1
- package/dist/storage/onedrive/index.d.ts +4 -4
- package/dist/storage/onedrive/index.js +1 -1
- package/dist/storage/pocketbase/index.d.ts +2 -2
- package/dist/storage/pocketbase/index.js +1 -1
- package/dist/storage/sftp/index.d.ts +9 -3
- package/dist/storage/sftp/index.js +1 -1
- package/dist/storage/sharepoint/index.d.ts +3 -3
- package/dist/storage/sharepoint/index.js +1 -1
- package/dist/storage/supabase/index.d.ts +3 -3
- package/dist/storage/supabase/index.js +1 -1
- package/dist/storage/uploadthing/index.d.ts +2 -2
- package/dist/storage/uploadthing/index.js +1 -1
- package/dist/storage/vercel-blob/index.d.ts +2 -2
- package/dist/storage/vercel-blob/index.js +1 -1
- package/dist/transformer/audio-transformer.d.ts +2 -2
- package/dist/transformer/image-transformer.d.ts +2 -2
- package/dist/transformer/index.d.ts +3 -3
- package/dist/transformer/video-transformer.d.ts +2 -2
- package/package.json +6 -2
- package/dist/packem_shared/AzureSMetaStorage-CR-lfQNQ.js +0 -1
- package/dist/packem_shared/AzureStorage-Cmr0nPDq.js +0 -1
- package/dist/packem_shared/BoxStorage-DYzAYPIr.js +0 -1
- package/dist/packem_shared/BunS3Storage-BvaFeKeu.js +0 -1
- package/dist/packem_shared/BunnyStorage-DsQndiy5.js +0 -1
- package/dist/packem_shared/CloudinaryStorage-DiK0T7N7.js +0 -1
- package/dist/packem_shared/DiskStorage-RvZNMWe7.js +0 -1
- package/dist/packem_shared/DiskStorageWithChecksum-eGOV3leX.js +0 -1
- package/dist/packem_shared/DropboxStorage-Dfd78aJL.js +0 -1
- package/dist/packem_shared/ERRORS-CyOuSMLY.js +0 -1
- package/dist/packem_shared/Files-CtggibJ-.js +0 -1
- package/dist/packem_shared/FirebaseStorage-C-FwZOYA.js +0 -2
- package/dist/packem_shared/FtpStorage-DzaP89bG.js +0 -1
- package/dist/packem_shared/GCStorage-1vA3xkFO.js +0 -1
- package/dist/packem_shared/GoogleDriveStorage-D_RaKV_j.js +0 -1
- package/dist/packem_shared/LocalMetaStorage-QMKL7McF.js +0 -1
- package/dist/packem_shared/NetlifyBlobStorage-C-IkXF0_.js +0 -1
- package/dist/packem_shared/OneDriveStorage-C7rqK2Wp.js +0 -1
- package/dist/packem_shared/PocketBaseStorage-Cdgr5w88.js +0 -1
- package/dist/packem_shared/S3Storage-Dn3l4WkO.js +0 -1
- package/dist/packem_shared/SftpStorage-CBW6MBLV.js +0 -1
- package/dist/packem_shared/SupabaseStorage-DMRhLPNo.js +0 -1
- package/dist/packem_shared/UploadThingStorage-BjF_gRMY.js +0 -1
- package/dist/packem_shared/VercelBlobStorage-Dx2jywjl.js +0 -1
- package/dist/packem_shared/aws-light-meta-storage-CstQBYXG.js +0 -4
- package/dist/packem_shared/disk-storage-Bmvawf-b.js +0 -1
- package/dist/packem_shared/executors-DG6hGtvm.js +0 -1
- package/dist/packem_shared/index.d-DSZjPbvW.d.ts +0 -230
- package/dist/packem_shared/isRetryableError-BhizNeAz.js +0 -1
- package/dist/packem_shared/part-match-B5fLLmFw.js +0 -1
- package/dist/packem_shared/s3-base-storage-Ek1HinGR.js +0 -1
- package/dist/packem_shared/storage-B-NDsI-o.js +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var m=Object.defineProperty;var p=(t,n)=>m(t,"name",{value:n,configurable:!0});import*as e from"zod";const y=1024*1024,u=e.object({limit:e.int().positive().max(1e3).optional().meta({description:"Maximum number of items to return"}),prefix:e.string().trim().optional().meta({description:"Only return keys that start with this prefix"})}),f=e.object({key:e.string().trim().meta({description:"The object key to inspect"})}),g=e.object({binary:e.boolean().optional().meta({description:"When true, returns base64-encoded bytes instead of UTF-8 text"}),key:e.string().trim().meta({description:"The object key to download"}),maxBytes:e.int().positive().optional().meta({description:`Reject downloads larger than this byte count (default ${y}). Verified via head() before transferring.`})}),b=e.object({expiresIn:e.int().positive().optional().meta({description:"Override the adapter default URL expiry in seconds. Ignored by permanent-CDN adapters."}),key:e.string().trim().meta({description:"The object key to build a URL for"}),responseContentDisposition:e.string().trim().optional().meta({description:`Force a Content-Disposition header on the response (e.g. 'attachment; filename="f.txt"'). Strongly recommended for user-uploaded content to prevent inline rendering of HTML/SVG.`})}),h=e.object({content:e.string().meta({description:'File body. Treated as UTF-8 text unless encoding is "base64".'}),contentType:e.string().trim().optional().meta({description:"MIME type recorded with the object"}),encoding:e.enum(["text","base64"]).optional().meta({description:"How to interpret content (default: text)"}),key:e.string().trim().meta({description:"Destination object key"}),metadata:e.record(e.string().trim(),e.string()).optional().meta({description:"Custom string metadata to attach to the object"})}),F=e.object({key:e.string().trim().meta({description:"Object key to delete"})}),k=e.object({from:e.string().trim().meta({description:"Source object key"}),to:e.string().trim().meta({description:"Destination object key"})}),w=e.object({contentType:e.string().trim().optional().meta({description:"Content-Type that the upload must declare"}),expiresIn:e.int().positive().meta({description:"Lifetime of the presigned URL in seconds"}),key:e.string().trim().meta({description:"Destination object key"})}),M={copyFile:{description:"Copy a file to a new key within the configured bucket. The source remains intact.",input:k},deleteFile:{description:"Permanently delete a file from the configured bucket.",input:F},downloadFile:{description:"Download a file and return its contents. Returns UTF-8 text by default; set binary=true to receive base64-encoded bytes. Files larger than maxBytes are rejected before transfer.",input:g},getFileMetadata:{description:"Fetch metadata for a single file (size, content type, etag, custom metadata) without transferring its body.",input:f},getFileUrl:{description:"Return a signed, time-limited URL the caller can use to fetch a file. Adapters that don't support presigning will throw MethodNotAllowed.",input:b},listFiles:{description:"List files in the configured bucket, optionally filtered by key prefix.",input:u},signUploadUrl:{description:"Issue a presigned URL that lets a client upload directly to the configured bucket. Approval-gated by default — the URL grants upload permission until it expires.",input:w},uploadFile:{description:'Upload a file to the configured bucket. Pass content as UTF-8 text by default, or as base64 with encoding="base64" for binary payloads.',input:h}},T=["uploadFile","deleteFile","copyFile","signUploadUrl"],S=new Set(T);var x=Object.defineProperty,s=p((t,n)=>x(t,"name",{value:n,configurable:!0}),"r");const l=s(t=>{if(t!==void 0)return t instanceof Date?t.toISOString():typeof t=="number"?new Date(t).toISOString():t},"serializeLastModified"),j={copyFile:s(async(t,{from:n,to:i})=>{const o=await t.copy(n,i);return{copied:!0,etag:o.etag,from:n,key:o.key,to:i}},"copyFile"),deleteFile:s(async(t,{key:n})=>(await t.delete(n),{deleted:!0,key:n}),"deleteFile"),downloadFile:s(async(t,{binary:n,key:i,maxBytes:o})=>{const r=o??y,c=await t.head(i);if(typeof c.size=="number"&&c.size>r)throw new RangeError(`downloadFile refused: "${i}" is ${c.size} bytes which exceeds the maxBytes limit of ${r}. Use getFileUrl to delegate to the client, or raise maxBytes.`);const a=await t.download(i);if(a.body.byteLength>r)throw new RangeError(`downloadFile refused: "${i}" returned ${a.body.byteLength} bytes which exceeds the maxBytes limit of ${r}. Use getFileUrl instead.`);return n?{content:a.body.toString("base64"),contentType:a.contentType,encoding:"base64",key:a.key,...typeof a.size=="number"?{size:a.size}:{}}:{content:a.body.toString("utf8"),contentType:a.contentType,encoding:"text",key:a.key,...typeof a.size=="number"?{size:a.size}:{}}},"downloadFile"),getFileMetadata:s(async(t,{key:n})=>{const i=await t.head(n);return{contentType:i.contentType,...i.etag?{etag:i.etag}:{},key:i.key,...l(i.lastModified)?{lastModified:l(i.lastModified)}:{},...i.metadata?{metadata:i.metadata}:{},...typeof i.size=="number"?{size:i.size}:{}}},"getFileMetadata"),getFileUrl:s(async(t,{expiresIn:n,key:i,responseContentDisposition:o})=>{const r=await t.url(i,{expiresIn:n,responseContentDisposition:o});return{key:i,url:r}},"getFileUrl"),listFiles:s(async(t,{limit:n,prefix:i})=>({items:(await t.list({limit:n,prefix:i})).map(o=>({contentType:o.contentType,...o.etag?{etag:o.etag}:{},key:o.key,...l(o.lastModified)?{lastModified:l(o.lastModified)}:{},...typeof o.size=="number"?{size:o.size}:{}}))}),"listFiles"),signUploadUrl:s(async(t,{contentType:n,expiresIn:i,key:o})=>{const r=await t.signedUploadUrl(o,{contentType:n,expiresIn:i});return{key:o,url:r}},"signUploadUrl"),uploadFile:s(async(t,{content:n,contentType:i,encoding:o,key:r,metadata:c})=>{const a=o==="base64"?Buffer.from(n,"base64"):Buffer.from(n,"utf8"),d=await t.upload(r,a,{contentType:i,metadata:c});return{contentType:d.contentType,...d.etag?{etag:d.etag}:{},key:d.key,...l(d.lastModified)?{lastModified:l(d.lastModified)}:{},...typeof d.size=="number"?{size:d.size}:{}}},"uploadFile")};export{M as T,S as W,j as e};
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { O as OperationOptions, B as BaseStorage } from "./storage.d-BoJgdi1n.js";
|
|
2
|
-
/**
|
|
3
|
-
* Web-standard and Node-native body types accepted by {@link Files.upload}.
|
|
4
|
-
*/
|
|
5
|
-
type FileBody = ArrayBuffer | ArrayBufferView | Blob | Buffer | NodeJS.ReadableStream | ReadableStream<Uint8Array> | string;
|
|
6
|
-
interface UploadOptions {
|
|
7
|
-
contentType?: string;
|
|
8
|
-
metadata?: Record<string, unknown>;
|
|
9
|
-
/**
|
|
10
|
-
* Explicit byte length. Required for {@link NodeJS.ReadableStream} and Web `ReadableStream`
|
|
11
|
-
* inputs because their length is not derivable from the value itself; ignored otherwise.
|
|
12
|
-
*/
|
|
13
|
-
size?: number;
|
|
14
|
-
storageClass?: string;
|
|
15
|
-
}
|
|
16
|
-
interface SignedReadUrlOptions {
|
|
17
|
-
expiresIn?: number;
|
|
18
|
-
responseContentDisposition?: string;
|
|
19
|
-
responseContentType?: string;
|
|
20
|
-
}
|
|
21
|
-
interface SignedUploadUrlOptions {
|
|
22
|
-
contentLength?: number;
|
|
23
|
-
contentType?: string;
|
|
24
|
-
expiresIn?: number;
|
|
25
|
-
}
|
|
26
|
-
interface ListOptions {
|
|
27
|
-
limit?: number;
|
|
28
|
-
prefix?: string;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Provider-agnostic metadata-only view of an object.
|
|
32
|
-
*/
|
|
33
|
-
interface FileObject {
|
|
34
|
-
contentType: string;
|
|
35
|
-
etag?: string;
|
|
36
|
-
key: string;
|
|
37
|
-
lastModified?: Date | number | string;
|
|
38
|
-
metadata?: Record<string, unknown>;
|
|
39
|
-
size?: number;
|
|
40
|
-
}
|
|
41
|
-
interface DownloadResult extends FileObject {
|
|
42
|
-
body: Buffer;
|
|
43
|
-
}
|
|
44
|
-
interface FilesOptions<TStorage extends BaseStorage = BaseStorage> {
|
|
45
|
-
adapter: TStorage;
|
|
46
|
-
/**
|
|
47
|
-
* Default {@link OperationOptions} (`signal`, `timeout`, `retries`) merged into every call.
|
|
48
|
-
* Per-call overrides win. The `signal` is combined with any per-call `signal` via
|
|
49
|
-
* `AbortSignal.any`, so either one aborts the operation.
|
|
50
|
-
*/
|
|
51
|
-
defaults?: OperationOptions;
|
|
52
|
-
/**
|
|
53
|
-
* Namespace every key under this prefix. Reads, writes, copies, listings, URLs, and signed
|
|
54
|
-
* uploads all resolve keys as `${prefix}/${key}`; returned keys (including from `list()`) have
|
|
55
|
-
* the prefix stripped back off. Leading/trailing slashes are normalized so `"/users/"` and
|
|
56
|
-
* `"users"` behave identically.
|
|
57
|
-
*
|
|
58
|
-
* `list()` scopes results on a path boundary, so `prefix: "users"` never matches the sibling
|
|
59
|
-
* `users-archive/`.
|
|
60
|
-
*/
|
|
61
|
-
prefix?: string;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* One item in a bulk upload call.
|
|
65
|
-
*/
|
|
66
|
-
interface BulkUploadItem extends UploadOptions {
|
|
67
|
-
body: FileBody;
|
|
68
|
-
key: string;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Per-call options shared by every bulk method (`upload`, `download`, `head`, `exists`, `delete`).
|
|
72
|
-
*/
|
|
73
|
-
interface BulkOptions extends OperationOptions {
|
|
74
|
-
/**
|
|
75
|
-
* Maximum number of in-flight operations.
|
|
76
|
-
* @default 8
|
|
77
|
-
*/
|
|
78
|
-
concurrency?: number;
|
|
79
|
-
/**
|
|
80
|
-
* When `true`, stop dispatching new operations as soon as one fails. The already-issued
|
|
81
|
-
* operations still complete. Defaults to `false`: every key is attempted and per-key failures
|
|
82
|
-
* are collected in `errors`.
|
|
83
|
-
* @default false
|
|
84
|
-
*/
|
|
85
|
-
stopOnError?: boolean;
|
|
86
|
-
}
|
|
87
|
-
interface BulkError {
|
|
88
|
-
error: Error;
|
|
89
|
-
key: string;
|
|
90
|
-
}
|
|
91
|
-
interface BulkUploadResult {
|
|
92
|
-
errors?: BulkError[];
|
|
93
|
-
uploaded: FileObject[];
|
|
94
|
-
}
|
|
95
|
-
interface BulkDownloadResult {
|
|
96
|
-
downloaded: DownloadResult[];
|
|
97
|
-
errors?: BulkError[];
|
|
98
|
-
}
|
|
99
|
-
interface BulkHeadResult {
|
|
100
|
-
errors?: BulkError[];
|
|
101
|
-
files: FileObject[];
|
|
102
|
-
}
|
|
103
|
-
interface BulkExistsResult {
|
|
104
|
-
errors?: BulkError[];
|
|
105
|
-
existing: string[];
|
|
106
|
-
missing: string[];
|
|
107
|
-
}
|
|
108
|
-
interface BulkDeleteResult {
|
|
109
|
-
deleted: string[];
|
|
110
|
-
errors?: BulkError[];
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Provider-agnostic facade over a {@link BaseStorage} instance.
|
|
114
|
-
*
|
|
115
|
-
* Provides a small, consistent surface (`upload`, `download`, `head`, `exists`, `delete`, `copy`,
|
|
116
|
-
* `list`, `url`, `signedUploadUrl`) and a `raw` escape hatch to the adapter's native client.
|
|
117
|
-
*
|
|
118
|
-
* Each operation accepts per-call `signal`, `timeout`, and `retries` via {@link OperationOptions};
|
|
119
|
-
* defaults set on the constructor are merged in (per-call wins). Single-key methods also accept an
|
|
120
|
-
* array of keys (or {@link BulkUploadItem}s for `upload`) to run a bounded-concurrency batch and
|
|
121
|
-
* return a structured `{ ..., errors? }` result instead of throwing on partial failure.
|
|
122
|
-
*
|
|
123
|
-
* When constructed with a `prefix`, every key is resolved relative to the prefix and the prefix is
|
|
124
|
-
* stripped back off the keys returned in results — application code works in its own namespace.
|
|
125
|
-
* @example
|
|
126
|
-
* ```ts
|
|
127
|
-
* import { Files, S3Storage } from "@visulima/storage";
|
|
128
|
-
*
|
|
129
|
-
* const files = new Files({
|
|
130
|
-
* adapter: new S3Storage({ bucket: "uploads", region: "us-east-1" }),
|
|
131
|
-
* prefix: "users",
|
|
132
|
-
* defaults: { timeout: 30_000 },
|
|
133
|
-
* });
|
|
134
|
-
*
|
|
135
|
-
* await files.upload("123/avatar.png", buffer, { contentType: "image/png" });
|
|
136
|
-
* const head = await files.head("123/avatar.png"); // reads users/123/avatar.png
|
|
137
|
-
* const url = await files.url("123/avatar.png", { expiresIn: 900 });
|
|
138
|
-
*
|
|
139
|
-
* const { uploaded, errors } = await files.upload([
|
|
140
|
-
* { key: "a.png", body: a, contentType: "image/png" },
|
|
141
|
-
* { key: "b.png", body: b },
|
|
142
|
-
* ], { concurrency: 4 });
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
declare class Files<TStorage extends BaseStorage = BaseStorage> {
|
|
146
|
-
readonly adapter: TStorage;
|
|
147
|
-
private readonly defaults;
|
|
148
|
-
private readonly prefix;
|
|
149
|
-
constructor(options: FilesOptions<TStorage>);
|
|
150
|
-
/**
|
|
151
|
-
* Escape hatch to the adapter's native client (S3Client, BlobServiceClient, ...).
|
|
152
|
-
* Typed via the `TStorage` parameter, so pinning the adapter type at construction yields a
|
|
153
|
-
* typed view of the native client. Returns `undefined` when the adapter has no native client
|
|
154
|
-
* (e.g. DiskStorage).
|
|
155
|
-
*/
|
|
156
|
-
get raw(): TStorage["raw"];
|
|
157
|
-
/** Resolve a caller-supplied key into the underlying storage key. */
|
|
158
|
-
private resolveKey;
|
|
159
|
-
/**
|
|
160
|
-
* Strip the constructor prefix off a key returned by the adapter. Returns `null` when the key
|
|
161
|
-
* is outside the prefix or is the bare prefix itself (used to filter `list()` results on a path
|
|
162
|
-
* boundary and drop any synthetic directory entry the adapter may emit).
|
|
163
|
-
*/
|
|
164
|
-
private stripPrefix;
|
|
165
|
-
private mergeOptions;
|
|
166
|
-
/**
|
|
167
|
-
* Upload a single object, or — when passed an array of {@link BulkUploadItem}s — bulk-upload
|
|
168
|
-
* many in one call with bounded concurrency.
|
|
169
|
-
*/
|
|
170
|
-
upload(key: string, body: FileBody, options?: OperationOptions & UploadOptions): Promise<FileObject>;
|
|
171
|
-
upload(items: BulkUploadItem[], options?: BulkOptions): Promise<BulkUploadResult>;
|
|
172
|
-
private uploadOne;
|
|
173
|
-
private uploadMany;
|
|
174
|
-
/**
|
|
175
|
-
* Download a single object, or — when passed an array of keys — bulk-download many in one
|
|
176
|
-
* call with bounded concurrency.
|
|
177
|
-
*/
|
|
178
|
-
download(key: string, options?: OperationOptions): Promise<DownloadResult>;
|
|
179
|
-
download(keys: string[], options?: BulkOptions): Promise<BulkDownloadResult>;
|
|
180
|
-
private downloadOne;
|
|
181
|
-
private downloadMany;
|
|
182
|
-
/**
|
|
183
|
-
* Fetch metadata for a single object, or — when passed an array of keys — bulk-head many in
|
|
184
|
-
* one call with bounded concurrency.
|
|
185
|
-
*/
|
|
186
|
-
head(key: string, options?: OperationOptions): Promise<FileObject>;
|
|
187
|
-
head(keys: string[], options?: BulkOptions): Promise<BulkHeadResult>;
|
|
188
|
-
private headOne;
|
|
189
|
-
private headMany;
|
|
190
|
-
/**
|
|
191
|
-
* Resolves to `true`/`false` for a single key, or — when passed an array — splits the keys
|
|
192
|
-
* into `existing` and `missing` arrays. Hard errors (auth, transport) are reported in
|
|
193
|
-
* `errors`. Never throws for a missing object.
|
|
194
|
-
*/
|
|
195
|
-
exists(key: string, options?: OperationOptions): Promise<boolean>;
|
|
196
|
-
exists(keys: string[], options?: BulkOptions): Promise<BulkExistsResult>;
|
|
197
|
-
private existsOne;
|
|
198
|
-
private existsMany;
|
|
199
|
-
/**
|
|
200
|
-
* Delete a single object (resolves to `void`, throws on failure), or — when passed an array
|
|
201
|
-
* of keys — delete many in one call. Adapters with a native bulk-delete primitive (S3's
|
|
202
|
-
* `DeleteObjects`, Supabase's `remove`, UploadThing's `deleteFiles`) use it via
|
|
203
|
-
* {@link BaseStorage.deleteBatch}; otherwise the keys are fanned out with bounded concurrency.
|
|
204
|
-
*/
|
|
205
|
-
delete(key: string, options?: OperationOptions): Promise<void>;
|
|
206
|
-
delete(keys: string[], options?: BulkOptions): Promise<BulkDeleteResult>;
|
|
207
|
-
private deleteOne;
|
|
208
|
-
private deleteMany;
|
|
209
|
-
/**
|
|
210
|
-
* Copy `source` to `destination` (both resolved under any constructor prefix). Returns the
|
|
211
|
-
* destination object's metadata with the caller-facing (un-prefixed) key.
|
|
212
|
-
*/
|
|
213
|
-
copy(source: string, destination: string, options?: OperationOptions & {
|
|
214
|
-
storageClass?: string;
|
|
215
|
-
}): Promise<FileObject>;
|
|
216
|
-
/**
|
|
217
|
-
* List objects in the bucket. Returned keys have any constructor prefix stripped off, and
|
|
218
|
-
* keys outside the prefix namespace (e.g. `users-archive/` when prefix is `users`) are filtered
|
|
219
|
-
* out. The optional `prefix` filter is interpreted *relative to the constructor prefix*.
|
|
220
|
-
*
|
|
221
|
-
* **Caveat with constructor prefix**: `limit` is applied by the underlying adapter *before*
|
|
222
|
-
* the path-boundary filter runs, so the returned array may contain fewer than `limit` items
|
|
223
|
-
* even when more in-namespace objects exist. Page through with adapter-specific APIs when you
|
|
224
|
-
* need an exact in-namespace count.
|
|
225
|
-
*/
|
|
226
|
-
list(options?: ListOptions & OperationOptions): Promise<FileObject[]>;
|
|
227
|
-
url(key: string, options?: OperationOptions & SignedReadUrlOptions): Promise<string>;
|
|
228
|
-
signedUploadUrl(key: string, options?: OperationOptions & SignedUploadUrlOptions): Promise<string>;
|
|
229
|
-
}
|
|
230
|
-
export { BulkDeleteResult as B, DownloadResult as D, Files as F, ListOptions as L, SignedReadUrlOptions as S, UploadOptions as U, BulkDownloadResult as a, BulkError as b, BulkExistsResult as c, BulkHeadResult as d, BulkOptions as e, BulkUploadItem as f, BulkUploadResult as g, FileBody as h, FileObject as i, FilesOptions as j, SignedUploadUrlOptions as k };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var m=Object.defineProperty;var d=(e,t)=>m(e,"name",{value:t,configurable:!0});var b=Object.defineProperty,i=d((e,t)=>b(e,"name",{value:t,configurable:!0}),"u");const l={backoffMultiplier:2,calculateDelay:void 0,initialDelay:1e3,maxDelay:3e4,maxRetries:3,retryableStatusCodes:[408,429,500,502,503,504],shouldRetry:i(()=>!1,"shouldRetry")},p=i((e,t,r,o)=>{const a=Math.min(t*r**e,o);return Math.floor(Math.random()*a)},"calculateExponentialBackoff"),D=i(e=>new Promise(t=>{setTimeout(t,e)}),"sleep"),h=i((e,t=l.retryableStatusCodes)=>{if(e instanceof Error){const r=e.code,o=e.name;if(o==="AbortError"||r==="ABORT_ERR")return!1;if(r==="ECONNRESET"||r==="ETIMEDOUT"||r==="ENOTFOUND"||r==="ECONNREFUSED"||r==="EAI_AGAIN"||o==="NetworkError"||o==="TimeoutError")return!0;const a=e;if(a.$metadata){const u=a.$metadata.httpStatusCode;if(u&&t.includes(u)||a.$fault==="server")return!0}if(a.statusCode&&t.includes(a.statusCode))return!0;const{retryable:s}=a;return s===!0||typeof s=="string"&&s==="true"}return!1},"isRetryableError"),C=i(async(e,t={})=>{const{backoffMultiplier:r=l.backoffMultiplier,calculateDelay:o=l.calculateDelay,initialDelay:a=l.initialDelay,maxDelay:s=l.maxDelay,maxRetries:u=l.maxRetries,retryableStatusCodes:E=l.retryableStatusCodes,shouldRetry:R=l.shouldRetry}=t;let f;for(let n=0;n<=u;n+=1)try{return await e()}catch(c){if(f=c,n>=u)break;if(!(R(c)||h(c,E)))throw c;const y=o?o(n,c):p(n,a,r,s);y!==void 0&&y>0&&await D(y)}throw f},"retry"),N=i((e={})=>t=>C(t,e),"createRetryWrapper");export{N as createRetryWrapper,h as isRetryableError,C as retry};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var i=Object.defineProperty;var r=(e,t)=>i(e,"name",{value:t,configurable:!0});var a=Object.defineProperty,s=r((e,t)=>a(e,"name",{value:t,configurable:!0}),"t");const v=s(e=>e.bytesWritten===e.size?"completed":e.createdAt?"part":"created","getFileStatus");var n=Object.defineProperty,o=r((e,t)=>n(e,"name",{value:t,configurable:!0}),"i");const z=o((e,t)=>e.size!==void 0&&t.size!==void 0&&e.size>0&&t.size>0&&e.size>t.size?!1:t.size===void 0?!0:(e.start||0)+(e.contentLength||0)<=t.size,"partMatch");export{v as o,z as r};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var O=Object.defineProperty;var g=(c,t)=>O(c,"name",{value:t,configurable:!0});import{Readable as b}from"node:stream";import{z as C,B as M,$ as A,t as T}from"./storage-B-NDsI-o.js";import{d as I}from"./detect-file-type-5JhzC9RU.js";import{throwErrorCode as y,ERRORS as f}from"./ERRORS-CyOuSMLY.js";import{createRetryWrapper as R}from"./isRetryableError-BhizNeAz.js";import{v as k}from"./local-meta-storage-Bi0mK6gD.js";import{u as z}from"./update-size-DANV7aa2.js";import{r as v,o as P}from"./part-match-B5fLLmFw.js";import{o as x}from"./has-content-Bx2p8Okx.js";var B=Object.defineProperty,L=g((c,t)=>B(c,"name",{value:t,configurable:!0}),"o$1");const N=L((c,t)=>{const a={};return Object.keys(c).forEach(e=>{a[e]=t(c[e])}),a},"mapValues");var $=Object.defineProperty,K=g((c,t)=>$(c,"name",{value:t,configurable:!0}),"t");const j=K(c=>c===Number(c)?c:(C(c)??0)/1e3,"toSeconds");var D=Object.defineProperty,w=g((c,t)=>D(c,"name",{value:t,configurable:!0}),"m");const F=5*1024*1024,W=16*1024*1024;class S extends M{static{g(this,"S3BaseStorage")}static{w(this,"S3BaseStorage")}checksumTypes=["md5","crc32","crc32c","sha1","sha256"];bucket;meta;MAX_PARTS=1e4;partSize;retry;resolvedRetryConfig;constructor(t){if(super(t),this.bucket=t.bucket,this.partSize=typeof t.partSize=="string"?A(t.partSize):t.partSize||W,this.partSize<F)throw new Error("Minimum allowed partSize value is 5MB");const a={backoffMultiplier:2,initialDelay:1e3,maxDelay:3e4,maxRetries:3,retryableStatusCodes:[408,429,500,502,503,504],shouldRetry:w(i=>{const s=i;return s.statusCode&&[408,429,500,502,503,504].includes(s.statusCode)?!0:s.retryable??!1},"shouldRetry"),...t.retryConfig};this.retry=R(a),this.resolvedRetryConfig=a;const{metaStorage:e,metaStorageConfig:r}=t;if(e)this.meta=e;else{const i={...t,...r,logger:this.logger};"directory"in i?(this.logger?.debug("Using local meta storage"),this.meta=new k(i)):this.meta=new k(i)}this.isReady=!1,this.accessCheck().then(()=>{this.isReady=!0}).catch(i=>{this.logger?.error("Storage access check failed: %O",i)})}getRetryConfig(){return this.resolvedRetryConfig}async create(t,a){return this.instrumentOperation("create",async()=>{const e={...t};if(t.ttl){const n=typeof t.ttl=="string"?T(t.ttl):t.ttl;n!==void 0&&(e.expiredAt=Date.now()+n)}const r=new(this.getFileClass())(e);r.name=this.namingFunction(r),await this.validate(r);try{const n=await this.getMeta(r.id);if(n.bytesWritten>=0)return n}catch{}const i=this.getS3Api();let s;try{s=await this.runOperation(a,n=>i.createMultipartUpload({ACL:this.getAcl(),Bucket:this.bucket,ContentType:r.contentType,Key:r.name,Metadata:N({originalName:r.originalName,...r.metadata},l=>encodeURI(String(l)))},{signal:n}))}catch{return y(f.FILE_ERROR,"s3 create upload error")}const{UploadId:o}=s||{};return o?(r.UploadId=o,r.bytesWritten=0,this.config.clientDirectUpload&&(r.partSize??=this.partSize),await this.saveMeta(r),r.status="created",await this.onCreate(r),this.config.clientDirectUpload?this.buildPresigned(r):r):y(f.FILE_ERROR,"s3 create upload error")})}async write(t,a){return this.instrumentOperation("write",async()=>{let e;if("contentType"in t&&"metadata"in t&&!("body"in t)&&!("start"in t)?e=t:(e=await this.getMeta(t.id),await this.checkIfExpired(e)),e.status==="completed")return e;if(typeof t.size=="number"&&t.size>0&&z(e,t.size),!v(t,e))return y(f.FILE_CONFLICT);if(this.config.clientDirectUpload)return this.buildPresigned(e);e.Parts??=await this.getParts(e),e.bytesWritten=e.Parts.map(i=>i.Size||0).reduce((i,s)=>i+s,0);const r=await this.lock(t.id);try{if(x(t)){if(this.isUnsupportedChecksum(t.checksumAlgorithm))return y(f.UNSUPPORTED_CHECKSUM_ALGORITHM);if(e.Parts.length===0&&(!e.contentType||e.contentType==="application/octet-stream"))try{const p=t.body instanceof b?t.body:b.fromWeb(t.body),{fileType:m,stream:u}=await I(p);m?.mime&&(e.contentType=m.mime),t.body=u}catch{}if(e.Parts.length>this.MAX_PARTS)throw new Error(`Exceeded ${this.MAX_PARTS} as part of the upload to ${this.bucket}.`);const i=e.Parts.length+1,s=this.getS3Api(),o=e.UploadId;if(!o)throw new Error("UploadId is required");const n=t.body,l=n instanceof Uint8Array,{ETag:h}=await this.runOperation(a,p=>s.uploadPart({Body:n,Bucket:this.bucket,ContentLength:t.contentLength||0,Key:e.name,PartNumber:i,UploadId:o,...t.checksumAlgorithm==="md5"?{ContentMD5:t.checksum}:{}},{signal:p}),{replayable:l}),d={ETag:h,PartNumber:i,Size:t.contentLength};e.Parts=[...e.Parts,d],e.bytesWritten+=t.contentLength||0}if(this.cache.set(e.id,e),e.status=P(e),e.status==="completed"){const[i]=await this.internalOnComplete(e);delete e.Parts,e.uri=i.Location,e.ETag=i.ETag}}finally{await this.unlock(t.id,r)}return e})}async delete({id:t},a){return this.instrumentOperation("delete",async()=>{const e=await this.getMeta(t);e.status="deleted",await this.abortMultipartUpload(e,a),await this.deleteMeta(e.id);const r={...e};return await this.onDelete(r),r})}async copy(t,a,e){return this.instrumentOperation("copy",async()=>{S.assertSafeId(t),S.assertSafeId(a);const r=await this.getMeta(t),i=`${this.bucket}/${t}`,s=this.bucket,o=a,n=this.getS3Api();return await this.runOperation(e,l=>n.copyObject({Bucket:s,CopySource:i,Key:o,...e?.storageClass&&{StorageClass:e.storageClass}},{signal:l})),{...r,id:o,name:o}})}async move(t,a,e){return this.instrumentOperation("move",async()=>{await this.copy(t,a,e);const r=this.getS3Api();return await this.runOperation(e,i=>r.deleteObject({Bucket:this.bucket,Key:t},{signal:i})),await this.getMeta(a)})}async list(t=1e3,a){return this.instrumentOperation("list",async()=>{const e=this.getS3Api(),r=Math.min(t,1e3);let i={Bucket:this.bucket,MaxKeys:r};const s=[];let o=!0;for(;o&&s.length<t;)try{const n=await this.runOperation(a,l=>e.listObjectsV2(i,{signal:l}));for(const{Key:l,LastModified:h}of n?.Contents||[]){if(s.length>=t)break;l!==void 0&&s.push({id:l,...h&&{createdAt:h}})}o=n.IsTruncated||!1,o&&n.NextContinuationToken&&s.length<t&&(i={...i,ContinuationToken:n.NextContinuationToken,MaxKeys:Math.min(r,t-s.length)})}catch(n){const l=this.normalizeError(n instanceof Error?n:new Error(String(n)));throw await this.onError(l),n}return s},{limit:t})}async exists({id:t},a){return this.instrumentOperation("exists",async()=>{try{await this.getMeta(t);const e=this.getS3Api();return await this.runOperation(a,r=>e.headObject({Bucket:this.bucket,Key:t},{signal:r})),!0}catch{return!1}})}async get({id:t},a){return this.instrumentOperation("get",async()=>{const e=this.getS3Api(),{Body:r,ContentLength:i,ContentType:s,ETag:o,Expires:n,LastModified:l,Metadata:h}=await this.runOperation(a,u=>e.getObject({Bucket:this.bucket,Key:t},{signal:u}));await this.checkIfExpired({expiredAt:n});const d=[];if(r)if(r instanceof b)for await(const u of r)d.push(u instanceof Uint8Array?u:new Uint8Array(u));else{const u=r.getReader();for(;;){const{done:U,value:E}=await u.read();if(U)break;d.push(E)}}const{originalName:p,...m}=h||{};return{content:Buffer.concat(d),contentType:s,ETag:o,expiredAt:n,id:t,metadata:m,modifiedAt:l,name:t,originalName:p||t,size:Number(i)}})}async buildPresigned(t){const a=t;if(a.Parts?.length||(a.Parts=await this.getParts(t)),a.bytesWritten=a.Parts.map(e=>e.Size||0).reduce((e,r)=>e+r,0),t.status=P(a),a.partsUrls?.length||(a.partsUrls=await this.getPartsPresignedUrls(t)),t.status==="completed"){const[e]=await this.internalOnComplete(t);return delete a.Parts,a.uri=e.Location,t}return t}async getPartsPresignedUrls(t){t.partSize??=this.partSize;const a=t.UploadId;if(!a)throw new Error("UploadId is required for getting presigned URLs");const e=Math.trunc(t.size/this.partSize)+1,r=[],i=Math.trunc(j(this.config.expiration?.maxAge||"6hrs")),s=this.getS3Api();for(let o=0;o<e;o++)r.push(s.getPresignedUrl({Bucket:this.bucket,expiresIn:i,Key:t.name,PartNumber:o+1,UploadId:a}));return Promise.all(r)}async getParts(t){const a=this.getS3Api(),e=t.UploadId;if(!e)throw new Error("UploadId is required");const{Parts:r=[]}=await this.runOperation(void 0,i=>a.listParts({Bucket:this.bucket,Key:t.name,UploadId:e},{signal:i}));return r}completeMultipartUpload(t){const a=this.getS3Api(),e=t.UploadId;if(!e)throw new Error("UploadId is required");const r=t.Parts?.map(({ETag:i,PartNumber:s})=>{if(!i||!s)throw new Error("ETag and PartNumber are required");return{ETag:i,PartNumber:s}})||[];return this.runOperation(void 0,i=>a.completeMultipartUpload({Bucket:this.bucket,Key:t.name,Parts:r,UploadId:e},{signal:i}))}async abortMultipartUpload(t,a){if(t.status!=="completed")try{const e=this.getS3Api(),r=t.UploadId;if(!r)return;await this.runOperation(a,i=>e.abortMultipartUpload({Bucket:this.bucket,Key:t.name,UploadId:r},{signal:i}))}catch(e){this.logger?.error("abortMultipartUploadError: ",e);const r=this.normalizeError(e instanceof Error?e:new Error(String(e)));await this.onError(r)}}internalOnComplete=w(async t=>{const[a]=await Promise.all([this.completeMultipartUpload(t),this.deleteMeta(t.id)]);return[a,t]},"internalOnComplete")}export{S};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var H=Object.defineProperty;var p=(t,e)=>H(t,"name",{value:e,configurable:!0});import{Readable as X}from"node:stream";import{setInterval as J}from"node:timers";import{inspect as Q}from"node:util";import{L as ee,O as I}from"./path-D7rMc9nq-B718mbm6.js";import te from"type-is";import re from"./NoOpMetrics-Dky06sf1.js";import{N as oe}from"./cache-qV_5Umeq.js";import{ErrorMap as M,throwErrorCode as E,ERRORS as $}from"./ERRORS-CyOuSMLY.js";import{randomUUID as se}from"node:crypto";import{LRUCache as ae}from"lru-cache";import{retry as ie}from"./isRetryableError-BhizNeAz.js";import{o as ne}from"./is-expired-1JuZjDtb.js";var ce=Object.defineProperty,le=p((t,e)=>ce(t,"name",{value:e,configurable:!0}),"y$3"),ue=Object.defineProperty,me=le((t,e)=>ue(t,"name",{value:e,configurable:!0}),"y"),ge=Object.defineProperty,C=me((t,e)=>ge(t,"name",{value:e,configurable:!0}),"i");const de=/^(?<value>-?\d+(?:[.,]\d+)*) *(?<type>[a-z]+)?$/i,he=/^KIBI/,pe=/^MIBI/,fe=/^GIBI/,ye=/^TEBI/,be=/^PEBI/,we=/^EXBI/,ve=/^ZEBI/,Ee=/^YIBI/,$e=/^(.)IB$/,_={iec:[{long:"Bytes",short:"B"},{long:"Kibibytes",short:"KiB"},{long:"Mebibytes",short:"MiB"},{long:"Gibibytes",short:"GiB"},{long:"Tebibytes",short:"TiB"},{long:"Pebibytes",short:"PiB"},{long:"Exbibytes",short:"EiB"},{long:"Zebibytes",short:"ZiB"},{long:"Yobibytes",short:"YiB"}],iec_octet:[{long:"Octets",short:"o"},{long:"Kibioctets",short:"Kio"},{long:"Mebioctets",short:"Mio"},{long:"Gibioctets",short:"Gio"},{long:"Tebioctets",short:"Tio"},{long:"Pebioctets",short:"Pio"},{long:"Exbioctets",short:"Eio"},{long:"Zebioctets",short:"Zio"},{long:"Yobioctets",short:"Yio"}],metric:[{long:"Bytes",short:"Bytes"},{long:"Kilobytes",short:"KB"},{long:"Megabytes",short:"MB"},{long:"Gigabytes",short:"GB"},{long:"Terabytes",short:"TB"},{long:"Petabytes",short:"PB"},{long:"Exabytes",short:"EB"},{long:"Zettabytes",short:"ZB"},{long:"Yottabytes",short:"YB"}],metric_octet:[{long:"Octets",short:"o"},{long:"Kilo-octets",short:"ko"},{long:"Mega-octets",short:"Mo"},{long:"Giga-octets",short:"Go"},{long:"Tera-octets",short:"To"},{long:"Peta-octets",short:"Po"},{long:"Exa-octets",short:"Eo"},{long:"Zetta-octets",short:"Zo"},{long:"Yotta-octets",short:"Yo"}]},xe=C((t,e)=>{const r=new Intl.NumberFormat(e).format(11111).replaceAll(new RegExp("\\p{Number}","gu"),""),o=new Intl.NumberFormat(e).format(1.1).replaceAll(new RegExp("\\p{Number}","gu"),"");return Number.parseFloat(t.replaceAll(new RegExp(`\\${r}`,"g"),"").replace(new RegExp(`\\${o}`),"."))},"parseLocalizedNumber"),R=C(t=>{switch(t){case 2:return 1024;case 10:return 1e3;default:throw new Error("Unsupported base.")}},"fromBase"),j=C((t,e)=>{const r={base:2,locale:"en-US",units:"metric",...e};if(typeof t!="string"||t.length===0)throw new TypeError("Value is not a string or is empty.");if(t.length>100)throw new TypeError("Value exceeds the maximum length of 100 characters.");const o=de.exec(t)?.groups;if(!o)return Number.NaN;const s=xe(o.value,r.locale),a=(o.type??"Bytes").toUpperCase().replace(he,"KILO").replace(pe,"MEGA").replace(fe,"GIGA").replace(ye,"TERA").replace(be,"PETA").replace(we,"EXA").replace(ve,"ZETTA").replace(Ee,"YOTTA").replace($e,"$1B"),i=_[r.units].findIndex(u=>u.short[0].toUpperCase()===a[0]),l=R(r.base);return s*l**i},"parseBytes");C((t,e)=>{if(typeof t!="number"||!Number.isFinite(t))throw new TypeError("Bytesize is not a number.");const{base:r,decimals:o,locale:s,long:a,unit:i,units:l,...u}={base:2,decimals:0,locale:"en-US",long:!1,units:"metric",...e},n=R(r),m=Math.abs(t),g=e?.space??!0?" ":"",c=_[l],d=c.findIndex(w=>w.short===i);if(t===0){const w=Math.min(0,Math.max(d,c.length-1));return"0"+g+c[w][a?"long":"short"]}const h=d===-1?Math.min(Math.floor(Math.log(m)/Math.log(n)),c.length-1):d,N=c[h][a?"long":"short"],O=t/n**h,v=o<0?void 0:o;return new Intl.NumberFormat(s,{maximumFractionDigits:v,minimumFractionDigits:v,...u}).format(O)+g+N},"formatBytes");var Me=Object.defineProperty,Ne=p((t,e)=>Me(t,"name",{value:e,configurable:!0}),"u$3"),Oe=Object.defineProperty,Ae=Ne((t,e)=>Oe(t,"name",{value:e,configurable:!0}),"v"),Te=Object.defineProperty,Ce=Ae((t,e)=>Te(t,"name",{value:e,configurable:!0}),"D");const Se=Ce((t,e,r,o,s,a,i,l,u,n,m,g,c,d)=>{const h={d:o,h:s,m:a,mo:e,ms:l,s:i,w:r,y:t};return u!==void 0&&(h.future=u),n!==void 0&&(h.past=n),m!==void 0&&(h.decimal=m),g!==void 0&&(h.unitMap=g),c!==void 0&&(h.groupSeparator=c),d!==void 0&&(h.placeholderSeparator=d),h},"createDurationLanguage"),F={d:"d",day:"d",days:"d",h:"h",hour:"h",hours:"h",hr:"h",hrs:"h",m:"m",millisecond:"ms",milliseconds:"ms",min:"m",mins:"m",minute:"m",minutes:"m",mo:"mo",month:"mo",months:"mo",ms:"ms",s:"s",sec:"s",second:"s",seconds:"s",secs:"s",w:"w",week:"w",weeks:"w",y:"y",year:"y",years:"y",yr:"y",yrs:"y"},Ie=Se(t=>`year${t===1?"":"s"}`,t=>`month${t===1?"":"s"}`,t=>`week${t===1?"":"s"}`,t=>`day${t===1?"":"s"}`,t=>`hour${t===1?"":"s"}`,t=>`minute${t===1?"":"s"}`,t=>`second${t===1?"":"s"}`,t=>`millisecond${t===1?"":"s"}`,"in %s","%s ago",".",F,",","_");var Be=Object.defineProperty,Pe=p((t,e)=>Be(t,"name",{value:e,configurable:!0}),"o"),De=Object.defineProperty,Ue=Pe((t,e)=>De(t,"name",{value:e,configurable:!0}),"o"),ze=Object.defineProperty,je=Ue((t,e)=>ze(t,"name",{value:e,configurable:!0}),"o");const ke=je(t=>{const e=["y","mo","w","d","h","m","s","ms","future","past"];for(const o of e)if(!Object.hasOwn(t,o))throw new TypeError(`Missing required property: ${o}`);if(typeof t.future!="string"||typeof t.past!="string")throw new TypeError("Properties future and past must be of type string");const r=["y","mo","w","d","h","m","s","ms"];for(const o of r)if(typeof t[o]!="string"&&typeof t[o]!="function")throw new TypeError(`Property ${o} must be of type string or function`);if(t.decimal&&typeof t.decimal!="string")throw new TypeError("Property decimal must be of type string");if(t.delimiter&&typeof t.delimiter!="string")throw new TypeError("Property delimiter must be of type string");if(t._digitReplacements&&!Array.isArray(t._digitReplacements))throw new TypeError("Property _digitReplacements must be an array");if(t._numberFirst&&typeof t._numberFirst!="boolean")throw new TypeError("Property _numberFirst must be of type boolean");if(t.unitMap&&typeof t.unitMap!="object")throw new TypeError("Property unitMap must be an object");if(t.unitMap&&Object.values(t.unitMap).some(o=>typeof o!="string"))throw new TypeError("All values in unitMap must be of type string")},"validateDurationLanguage");var _e=Object.defineProperty,Re=p((t,e)=>_e(t,"name",{value:e,configurable:!0}),"w"),Fe=Object.defineProperty,Le=Re((t,e)=>Fe(t,"name",{value:e,configurable:!0}),"S"),Ve=Object.defineProperty,Ge=Le((t,e)=>Ve(t,"name",{value:e,configurable:!0}),"h");const k={d:864e5,h:36e5,m:6e4,mo:2629746e3,ms:1,s:1e3,w:6048e5,y:31556952e3},A=/[-/\\^$*+?.()|[\]{}]/g,Ye=/^PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/i,Ze=/^(?:(\d+):)?(?:(\d+):)?(\d+)$/,Ke=/^[+-]?\d+(?:\.\d+)?$/,We=/^[-+]/,qe=Ge((t,e)=>{if(typeof t!="string"||t.length===0)return;const{defaultUnit:r="ms",language:o=Ie}=e??{};ke(o);const s=o.decimal??".",a=o.groupSeparator??",",i=o.placeholderSeparator??"_",l=s.replaceAll(A,String.raw`\$&`),u=a.replaceAll(A,String.raw`\$&`),n=i.replaceAll(A,String.raw`\$&`),m=o.unitMap??F;let g=t.replaceAll(new RegExp(String.raw`(\d)[${n}${u}](\d)`,"g"),"$1$2");if(s!=="."&&(g=g.replace(l,".")),Ke.test(t)){const f=Number.parseFloat(g.trim());if(!Number.isNaN(f)){const y=m[r];if(y!==void 0)return f*k[y]}return}const c=Ye.exec(t);if(c){const f=Number.parseInt(c[1]??"0",10),y=Number.parseInt(c[2]??"0",10),x=Number.parseInt(c[3]??"0",10);return f*36e5+y*6e4+x*1e3}const d=Ze.exec(t);if(d){let f=0,y=0;d[2]!==void 0?(f=Number.parseInt(d[1]??"0",10),y=Number.parseInt(d[2],10)):d[1]!==void 0&&(y=Number.parseInt(d[1],10));const x=Number.parseInt(d[3]??"0",10);return f*36e5+y*6e4+x*1e3}const h=Object.keys(m).toSorted((f,y)=>y.length-f.length).map(f=>f.replaceAll(A,String.raw`\$&`)).join("|"),N=new RegExp(String.raw`(-?\d*\.?\d+)\s*(${h})`,"gi");let O=0,v,w=!1,P=-1,D=0;for(N.lastIndex=0;(v=N.exec(g))!==null;){w||(P=v.index),w=!0;const f=v[1],y=v[2];if(!f||!y)continue;const x=f.trim(),K=x.startsWith("-")?-1:1,W=x.replace(We,""),U=Number.parseFloat(W),z=m[y.toLowerCase()];if(z===void 0)continue;const q=k[z];if(Number.isNaN(U))return;O+=K*U*q,D=N.lastIndex}const Y=g.slice(0,P).trim(),Z=g.slice(D).trim();if(!(w&&(Y.length>0||Z.length>0))&&w)return O},"parseDuration");var He=Object.defineProperty,Xe=p((t,e)=>He(t,"name",{value:e,configurable:!0}),"n$1");let Je=class extends ae{static{p(this,"u")}static{Xe(this,"Locker")}constructor(e){super({ttl:3e4,ttlAutopurge:!0,...e})}lock(e){if(this.get(e)!==void 0)throw new Error(`${e} is locked`);const r=se();return this.set(e,r),r}unlock(e,r){return this.get(e)!==r?!1:this.delete(e)}};var Qe=Object.defineProperty,et=p((t,e)=>Qe(t,"name",{value:e,configurable:!0}),"e$1");const T=et(t=>{if(t===Number(t))return t;if(!t)return;const e=qe(t);if(e!==void 0)return e},"toMilliseconds");var tt=Object.defineProperty,rt=p((t,e)=>tt(t,"name",{value:e,configurable:!0}),"t");let ot=class extends Error{static{p(this,"d")}static{rt(this,"ValidationError")}code;statusCode;body;headers;name="ValidationError";constructor(e,r,o,s){const a=typeof o=="string"?o:o?.message||"Validation error";super(a),this.code=e,this.statusCode=r,this.body=o,this.headers=s}};var st=Object.defineProperty,S=p((t,e)=>st(t,"name",{value:e,configurable:!0}),"e");const at=S(t=>t&&t[0].toUpperCase()+t.slice(1),"capitalize"),it=S(t=>{if(!Array.isArray(t))return t;const[e,r,o]=t;return{body:r,headers:o,statusCode:e}},"toResponse");class nt{static{p(this,"Validator")}constructor(e="ValidationError"){this.prefix=e}prefix;static{S(this,"Validator")}validators={};add(e){Object.entries(e).forEach(([r,o])=>{const s=`${this.prefix}${at(r)}`;if(this.validators[s]={...this.validators[s],...o},typeof this.validators[s].isValid!="function")throw new TypeError('Validation config "isValid" is missing, or it is not a function!')})}async verify(e){for(const[r,o]of Object.entries(this.validators))if(!await o.isValid(e)){const s=o.response||(r in M?M[r]:M.UnknownError),a=it(s),{body:i,headers:l,message:u,statusCode:n}=a;throw new ot(r,n,i||u,l)}}}const St=S(t=>t.name==="ValidationError","isValidationError");var ct=Object.defineProperty,B=p((t,e)=>ct(t,"name",{value:e,configurable:!0}),"i");const lt=B(t=>{if(typeof t.name=="string")return t.name;if(typeof t.title=="string")return t.title;if(typeof t.originalName=="string")return t.originalName;if(typeof t.filename=="string")return t.filename},"extractOriginalName"),L=B((t,e)=>{const r={...t};return Object.keys(e).forEach(o=>{const s=e[o];if(s!==null&&typeof s=="object"&&!Array.isArray(s)){const a=r[o],i=a&&typeof a=="object"&&!Array.isArray(a)?a:{};r[o]=L(i,s)}else r[o]=s}),r},"deepMerge"),ut=B((t,e)=>{const r=L(t,e);Object.assign(t,r),t.originalName=lt(t.metadata)||t.originalName},"updateMetadata");var mt=Object.defineProperty,b=p((t,e)=>mt(t,"name",{value:e,configurable:!0}),"d");const gt=/(secret|password|passwd|pwd|token|api[_-]?key|credential|authorization|sas|signature|sessiontoken|connectionstring)/i,V=b(t=>{const e={};for(const[r,o]of Object.entries(t))typeof o=="string"&>.test(r)?e[r]="[REDACTED]":o&&typeof o=="object"&&!Array.isArray(o)&&o.constructor===Object?e[r]=V(o):e[r]=o;return e},"redactSecrets"),dt={allowMIME:["*/*"],filename:b(({id:t})=>t,"filename"),maxMetadataSize:"8MB",maxUploadSize:"5TB",onComplete:b(()=>{},"onComplete"),onCreate:b(()=>{},"onCreate"),onDelete:b(()=>{},"onDelete"),onError:b(()=>{},"onError"),onUpdate:b(()=>{},"onUpdate"),useRelativeLocation:!1,validation:{}},ht=b(t=>!t||t.length<3||t.length>255||I(t)?!1:!(t.toUpperCase().includes("../")||t.includes("\0")),"defaultCloudStorageFileNameValidation"),It=b(t=>{if(!t||t.length<3||t.length>255||I(t))return!1;const e=t.toUpperCase();return!['"',"*",":","<",">","?","\\","|","../","\0"].some(r=>e.includes(r))},"defaultFilesystemFileNameValidation");class G{static{p(this,"BaseStorage")}static{b(this,"BaseStorage")}onCreate;onUpdate;onComplete;onDelete;onError;isReady=!0;errorResponses={};cache;logger;metrics;genericConfig;maxMetadataSize;checksumTypes=[];maxUploadSize;expiration;locker;namingFunction;validation=new nt;assetFolder=void 0;concurrency;constructor(e){const r={...dt,...e};this.onCreate=r.onCreate,this.onUpdate=r.onUpdate,this.onComplete=r.onComplete,this.onDelete=r.onDelete,this.onError=r.onError,this.namingFunction=r.filename,this.maxUploadSize=typeof r.maxUploadSize=="string"?j(r.maxUploadSize):r.maxUploadSize,this.maxMetadataSize=typeof r.maxMetadataSize=="string"?j(r.maxMetadataSize):r.maxMetadataSize,this.expiration=r.expiration,this.genericConfig=r,r.assetFolder!==void 0&&(this.assetFolder=ee(r.assetFolder)),this.locker=new Je({max:1e3,ttl:3e4,ttlAutopurge:!0}),this.cache=r.cache??new oe,this.logger=r.logger,this.metrics=r.metrics??new re,this.logger?.debug(`${this.constructor.name} config: ${Q(V({...e,logger:this.logger.constructor}))}`);const o=T(r.expiration?.purgeInterval);o&&this.startAutoPurge(o);const s={isValid(u){if(u.size===void 0)return!0;const n=u.size;if(n==null)return!1;const m=typeof n=="number"?n:Number(n);if(Number.isNaN(m)||m<0)return!1;const g=typeof this.value=="number"?this.value:Number(this.value);return!Number.isNaN(g)&&m<=g},response:M.RequestEntityTooLarge,value:this.maxUploadSize},a={isValid(u){return!!te.is(u.contentType,this.value)},response:M.UnsupportedMediaType,value:r.allowMIME},i=r.fileNameValidation??ht,l={isValid(u){return i(u.name)},response:M.InvalidFileName};this.validation.add({filename:l,mime:a,size:s}),this.validation.add({...r.validation})}get raw(){}async getReadUrl(e,r){return E($.METHOD_NOT_ALLOWED,`${this.constructor.name} does not implement getReadUrl()`)}async getUploadUrl(e,r){return E($.METHOD_NOT_ALLOWED,`${this.constructor.name} does not implement getUploadUrl()`)}get tusExtension(){const e=["creation","creation-with-upload","termination","checksum","creation-defer-length","concatenation"];return this.expiration&&e.push("expiration"),e}async validate(e){await this.validation.verify(e)}async exists(e,r){return this.instrumentOperation("exists",async()=>{try{return await this.getMeta(e.id,r),!0}catch{return!1}})}normalizeError(e){const r={code:e.name,message:e.message,name:e.name,statusCode:500};return{...r,message:`[${this.constructor.name}] ${r.message}`}}get config(){return this.genericConfig}async saveMeta(e){return G.assertSafeId(e.id),this.updateTimestamps(e),this.cache.set(e.id,e),this.meta.save(e.id,e)}static assertSafeId(e){(!e||typeof e!="string"||e.includes("\0")||e.includes("../")||e.includes("..\\")||e===".."||e.startsWith("../")||e.startsWith("..\\")||I(e)||/^[A-Z]:[/\\]/i.test(e))&&E($.INVALID_FILE_NAME,`Invalid file id: "${e}"`)}async deleteMeta(e){return this.cache.delete(e),this.meta.delete(e)}async getMeta(e,r){try{const o=await this.meta.get(e);return this.cache.set(o.id,o),{...o}}catch(o){const s=this.normalizeError(o instanceof Error?o:new Error(String(o)));return await this.onError(s),E($.FILE_NOT_FOUND)}}async checkIfExpired(e){return ne(e)?(this.delete(e).catch(()=>{}),this.deleteMeta(e.id).catch(()=>{}),E($.GONE)):e}async purge(e){return this.instrumentOperation("purge",async()=>{const r=T(e||this.expiration?.maxAge),o={items:[],maxAgeMs:r};if(r){const s=Date.now()-r,a=(await this.list()).filter(i=>Number(new Date(this.expiration?.rolling&&i.modifiedAt||i.createdAt))<s);for await(const{id:i,...l}of a)try{const u=await this.delete({id:i});o.items.push({...u,...l})}catch(u){this.logger?.warn(`Failed to delete file ${i} during purge: ${u instanceof Error?u.message:String(u)}`)}o.items.length>0&&(this.logger?.info(`Purge: removed ${o.items.length} uploads`),this.metrics.gauge("storage.operations.purge.items_count",o.items.length,{storage:this.constructor.name.toLowerCase().replace("storage","")}))}return o})}async getStream({id:e}){return this.instrumentOperation("getStream",async()=>{const r=await this.get({id:e}),o=X.from(r.content);return{headers:{"Content-Length":String(r.size),"Content-Type":r.contentType,...r.ETag&&{ETag:r.ETag},...r.modifiedAt&&{"Last-Modified":r.modifiedAt.toString()}},size:typeof r.size=="number"?r.size:void 0,stream:o}})}async list(e=1e3,r){return this.instrumentOperation("list",async()=>{throw new Error("Not implemented")})}async update({id:e},r){return this.instrumentOperation("update",async()=>{const o=await this.getMeta(e),s={...r};if("ttl"in s&&s.ttl!==void 0){const i=s.ttl,l=typeof i=="string"?T(i):i;l!==void 0&&(s.expiredAt=Date.now()+l),delete s.ttl}ut(o,s),await this.saveMeta(o);const a={...o,status:"updated"};return await this.onUpdate(a),a})}async deleteBatch(e,r){const o=Date.now(),s=this.constructor.name.toLowerCase().replace("storage","");this.metrics.increment("storage.operations.batch.delete.count",1,{batch_size:e.length,storage:s});const a=[],i=[],l=e.map(async m=>{try{return{file:await this.delete({id:m},r),id:m,success:!0}}catch(g){const c=g instanceof Error?g.message:"Delete failed";return this.metrics.increment("storage.operations.delete.error.count",1,{error:c,storage:s}),{error:c,id:m,success:!1}}}),u=await Promise.allSettled(l);for(const m of u)m.status==="fulfilled"?m.value.success?a.push(m.value.file):i.push({error:m.value.error,id:m.value.id}):i.push({error:m.reason?.message||"Delete failed",id:""});const n=Date.now()-o;return this.metrics.timing("storage.operations.batch.delete.duration",n,{batch_size:e.length,storage:s}),this.metrics.gauge("storage.operations.batch.delete.success_count",a.length,{storage:s}),this.metrics.gauge("storage.operations.batch.delete.failed_count",i.length,{storage:s}),{failed:i,failedCount:i.length,successful:a,successfulCount:a.length}}async copyBatch(e){const r=Date.now(),o=this.constructor.name.toLowerCase().replace("storage","");this.metrics.increment("storage.operations.batch.copy.count",1,{batch_size:e.length,storage:o});const s=[],a=[],i=e.map(async({destination:n,options:m,source:g})=>{try{return{file:await this.copy(g,n,m),id:n,success:!0}}catch(c){const d=c instanceof Error?c.message:"Copy failed";return this.metrics.increment("storage.operations.copy.error.count",1,{error:d,storage:o}),{error:d,id:n,success:!1}}}),l=await Promise.allSettled(i);for(const n of l)n.status==="fulfilled"?n.value.success&&n.value.file?s.push(n.value.file):a.push({error:n.value.error||"Copy failed",id:n.value.id}):a.push({error:n.reason?.message||"Copy failed",id:""});const u=Date.now()-r;return this.metrics.timing("storage.operations.batch.copy.duration",u,{batch_size:e.length,storage:o}),this.metrics.gauge("storage.operations.batch.copy.success_count",s.length,{storage:o}),this.metrics.gauge("storage.operations.batch.copy.failed_count",a.length,{storage:o}),{failed:a,failedCount:a.length,successful:s,successfulCount:s.length}}async moveBatch(e){const r=Date.now(),o=this.constructor.name.toLowerCase().replace("storage","");this.metrics.increment("storage.operations.batch.move.count",1,{batch_size:e.length,storage:o});const s=[],a=[],i=e.map(async({destination:n,source:m})=>{try{return{file:await this.move(m,n),id:n,success:!0}}catch(g){const c=g instanceof Error?g.message:"Move failed";return this.metrics.increment("storage.operations.move.error.count",1,{error:c,storage:o}),{error:c,id:n,success:!1}}}),l=await Promise.allSettled(i);for(const n of l)n.status==="fulfilled"?n.value.success&&n.value.file?s.push(n.value.file):a.push({error:n.value.error||"Move failed",id:n.value.id}):a.push({error:n.reason?.message||"Move failed",id:n.reason?.id||""});const u=Date.now()-r;return this.metrics.timing("storage.operations.batch.move.duration",u,{batch_size:e.length,storage:o}),this.metrics.gauge("storage.operations.batch.move.success_count",s.length,{storage:o}),this.metrics.gauge("storage.operations.batch.move.failed_count",a.length,{storage:o}),{failed:a,failedCount:a.length,successful:s,successfulCount:s.length}}async lock(e){const r=[...this.locker.keys()];return r.includes(e)?E($.FILE_LOCKED):this.config.concurrency&&typeof this.config.concurrency=="number"&&this.config.concurrency<r.length?E($.STORAGE_BUSY):this.locker.lock(e)}async unlock(e,r){if(r===void 0){this.locker.delete(e);return}this.locker.unlock(e,r)}async withLock(e,r){const o=await this.lock(e);try{return await r()}finally{await this.unlock(e,o)}}isUnsupportedChecksum(e=""){return!!e&&!this.checksumTypes.includes(e)}startAutoPurge(e){if(e>=2147483647)throw new Error("“purgeInterval” must be less than 2147483647 ms");J(()=>{this.purge().catch(r=>this.logger?.error(r))},e)}updateTimestamps(e){e.createdAt??=new Date().toISOString();const r=T(this.expiration?.maxAge);return r&&!e.expiredAt&&(e.expiredAt=this.expiration?.rolling?Date.now()+r:+new Date(e.createdAt)+r),e}getRetryConfig(){}runOperation(e,r,o){let s;typeof e?.retries=="number"?s={maxRetries:e.retries}:e?.retries&&(s=e.retries);const a={...this.getRetryConfig(),...s};o?.replayable===!1&&(a.maxRetries=0);const i=[];this.genericConfig.defaultSignal&&i.push(this.genericConfig.defaultSignal),e?.signal&&i.push(e.signal);let l;i.length===1?[l]=i:i.length>1&&(l=AbortSignal.any(i));const u=typeof e?.timeout=="number"?e.timeout:this.genericConfig.defaultTimeout,n=typeof u=="number"&&u>0?u:void 0,m=a.shouldRetry;a.shouldRetry=c=>l?.aborted||c instanceof Error&&c.name==="AbortError"?!1:m?m(c):!1;const g=b(c=>{if(c instanceof Error&&c.name==="AbortError")return c;const d=c instanceof Error&&c.message?c.message:"The operation was aborted",h=new Error(d,{cause:c});return h.name="AbortError",h},"toAbortError");return ie(async()=>{if(l?.aborted)throw g(l.reason);let c,d;if(n===void 0)d=l;else{const h=new AbortController;c=setTimeout(()=>{h.abort(new DOMException(`The operation timed out after ${n}ms`,"TimeoutError"))},n),d=l?AbortSignal.any([l,h.signal]):h.signal}try{return await r(d)}catch(h){throw d?.aborted?g(h):h}finally{c&&clearTimeout(c)}},a)}async instrumentOperation(e,r,o){const s=Date.now(),a={storage:this.constructor.name.toLowerCase().replace("storage",""),...o};try{this.metrics.increment(`storage.operations.${e}.count`,1,a);const i=await r(),l=Date.now()-s;return this.metrics.timing(`storage.operations.${e}.duration`,l,a),i&&typeof i=="object"&&"size"in i&&typeof i.size=="number"&&this.metrics.gauge("storage.files.size",i.size,{...a,operation:e}),i}catch(i){const l=Date.now()-s,u=i instanceof Error?i.message:"Unknown error";throw this.metrics.timing(`storage.operations.${e}.duration`,l,{...a,error:"true"}),this.metrics.increment(`storage.operations.${e}.error.count`,1,{...a,error:u}),i}}}export{j as $,G as B,It as a,ot as b,ht as d,St as i,T as t,ut as u,qe as z};
|