@visulima/storage 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/adapter/nuxt/module.d.ts +8 -8
  3. package/dist/ai/ai-sdk/index.d.ts +51 -59
  4. package/dist/ai/claude/index.d.ts +104 -119
  5. package/dist/ai/openai/index.d.ts +86 -99
  6. package/dist/ai/tanstack/index.d.ts +53 -61
  7. package/dist/handler/http/fetch/index.d.ts +201 -201
  8. package/dist/handler/http/hono/index.d.ts +59 -59
  9. package/dist/handler/http/nextjs/index.d.ts +54 -54
  10. package/dist/handler/http/node/index.d.ts +233 -246
  11. package/dist/handler/http/solid-start/index.d.ts +54 -54
  12. package/dist/index.d.ts +70 -70
  13. package/dist/index.js +1 -1
  14. package/dist/packem_shared/{AwsLightStorage-BK-WPL0h.js → AwsLightStorage-EsqkAtU5.js} +1 -1
  15. package/dist/packem_shared/{AzureStorage-1UvDIQZd.js → AzureStorage-DL-U7qFG.js} +1 -1
  16. package/dist/packem_shared/BoxMetaStorage-CHWrhgg2.js +1 -0
  17. package/dist/packem_shared/{BoxStorage-DbGqBLux.js → BoxStorage-B8_oCz27.js} +1 -1
  18. package/dist/packem_shared/BunS3MetaStorage-CHWrhgg2.js +1 -0
  19. package/dist/packem_shared/{BunS3Storage-DNvimm9e.js → BunS3Storage-_PVXu_na.js} +1 -1
  20. package/dist/packem_shared/BunnyMetaStorage-CHWrhgg2.js +1 -0
  21. package/dist/packem_shared/{BunnyStorage-C7d0opLL.js → BunnyStorage-BsoWjScH.js} +1 -1
  22. package/dist/packem_shared/CloudinaryMetaStorage-BI9YXcwU.js +1 -0
  23. package/dist/packem_shared/{CloudinaryStorage-Dc3XA2lP.js → CloudinaryStorage-BNwiLF9V.js} +1 -1
  24. package/dist/packem_shared/{DiskStorage-CI07TVNu.js → DiskStorage-D-NtQDms.js} +1 -1
  25. package/dist/packem_shared/{DiskStorageWithChecksum-vFCubS6K.js → DiskStorageWithChecksum-UnCtyEvs.js} +1 -1
  26. package/dist/packem_shared/DropboxMetaStorage-CHWrhgg2.js +1 -0
  27. package/dist/packem_shared/{DropboxStorage-CY9Ggu3m.js → DropboxStorage-BS9kj0nH.js} +1 -1
  28. package/dist/packem_shared/FirebaseMetaStorage-BI9YXcwU.js +1 -0
  29. package/dist/packem_shared/{FirebaseStorage-D6O9CJXN.js → FirebaseStorage-DNquii2p.js} +1 -1
  30. package/dist/packem_shared/FtpMetaStorage-CHWrhgg2.js +1 -0
  31. package/dist/packem_shared/{FtpStorage-DbEjbq8z.js → FtpStorage-Bd004--s.js} +1 -1
  32. package/dist/packem_shared/{GCSMetaStorage-DT8K6zdm.js → GCSMetaStorage-Bf4qDFB1.js} +1 -1
  33. package/dist/packem_shared/{GCStorage-6BHkFlEs.js → GCStorage-ChqEpgqR.js} +1 -1
  34. package/dist/packem_shared/GoogleDriveMetaStorage-xlHfKwmR.js +1 -0
  35. package/dist/packem_shared/{GoogleDriveStorage-Bklsz7Bh.js → GoogleDriveStorage-v1glykjd.js} +1 -1
  36. package/dist/packem_shared/{LocalMetaStorage-BhicZnNl.js → LocalMetaStorage-YWPBYEe7.js} +1 -1
  37. package/dist/packem_shared/NetlifyBlobMetaStorage-BI9YXcwU.js +1 -0
  38. package/dist/packem_shared/{NetlifyBlobStorage-CkpCCoN1.js → NetlifyBlobStorage-BPyEWSnx.js} +1 -1
  39. package/dist/packem_shared/OneDriveMetaStorage-xlHfKwmR.js +1 -0
  40. package/dist/packem_shared/{OneDriveStorage-CP6MvGAa.js → OneDriveStorage-BJ3Kzxc5.js} +1 -1
  41. package/dist/packem_shared/PocketBaseMetaStorage-DnrxOQhO.js +1 -0
  42. package/dist/packem_shared/{PocketBaseStorage-2qhbI2PW.js → PocketBaseStorage-DqKHbbvn.js} +1 -1
  43. package/dist/packem_shared/{S3Storage-YGeNk3Tt.js → S3Storage-BiI2k6d1.js} +1 -1
  44. package/dist/packem_shared/SftpMetaStorage-CHWrhgg2.js +1 -0
  45. package/dist/packem_shared/{SftpStorage-2Hz396Xr.js → SftpStorage-w8XdtZtw.js} +1 -1
  46. package/dist/packem_shared/SharePointMetaStorage-CHWrhgg2.js +1 -0
  47. package/dist/packem_shared/{SharePointStorage-CrX2Pk6C.js → SharePointStorage-DpDpI7Ln.js} +1 -1
  48. package/dist/packem_shared/SupabaseMetaStorage-xlHfKwmR.js +1 -0
  49. package/dist/packem_shared/{SupabaseStorage-Dc_DBX29.js → SupabaseStorage-B_ugUCs7.js} +1 -1
  50. package/dist/packem_shared/UploadThingMetaStorage-BI9YXcwU.js +1 -0
  51. package/dist/packem_shared/{UploadThingStorage-BChykYSe.js → UploadThingStorage-_H45IVqX.js} +1 -1
  52. package/dist/packem_shared/VercelBlobMetaStorage-CHWrhgg2.js +1 -0
  53. package/dist/packem_shared/{VercelBlobStorage-CsRyPfw3.js → VercelBlobStorage-U1YMKeHs.js} +1 -1
  54. package/dist/packem_shared/{approval.d-CMAYH9GF.d.ts → approval.d-C-d-t94D.d.ts} +6 -6
  55. package/dist/packem_shared/disk-storage-BwPk2IRa.js +1 -0
  56. package/dist/packem_shared/disk-storage-with-checksum.d-CQucFacO.d.ts +146 -0
  57. package/dist/packem_shared/{executors.d-BZP2rWo3.d.ts → executors.d-DeDH3Ilt.d.ts} +2 -2
  58. package/dist/packem_shared/files.d-D8H_ge9Y.d.ts +655 -0
  59. package/dist/packem_shared/{gcs-meta-storage-B7BnctnV.js → gcs-meta-storage-DQGu_cHq.js} +1 -1
  60. package/dist/packem_shared/local-meta-storage-DJDcuxf1.js +11 -0
  61. package/dist/packem_shared/{local-meta-storage.d-D9PBfkn6.d.ts → local-meta-storage.d-DuTEzyii.d.ts} +7 -7
  62. package/dist/packem_shared/media-transformer.d-CvMFjINm.d.ts +331 -0
  63. package/dist/packem_shared/{memory-storage.d-4EU1cMt1.d.ts → memory-storage.d-BRdTiY8y.d.ts} +32 -40
  64. package/dist/packem_shared/{s3-base-storage-BoTyhuzO.js → s3-base-storage-CMUui93V.js} +1 -1
  65. package/dist/packem_shared/{s3-base-storage.d-BQgP5B-t.d.ts → s3-base-storage.d-Cg7m4FuH.d.ts} +64 -70
  66. package/dist/packem_shared/storage.d-DIav_lF1.d.ts +1163 -0
  67. package/dist/packem_shared/tus-base.d-BiEg5t4t.d.ts +102 -0
  68. package/dist/packem_shared/{types.d-CrUWY4On.d.ts → types.d-CAAzKiI6.d.ts} +134 -134
  69. package/dist/packem_shared/types.d-DgHhkCAl.d.ts +104 -0
  70. package/dist/packem_shared/{types.d-CggTCgXr.d.ts → types.d-jAs_Rp_v.d.ts} +3 -3
  71. package/dist/storage/aws/clients/index.d.ts +388 -388
  72. package/dist/storage/aws/index.d.ts +109 -113
  73. package/dist/storage/aws/index.js +1 -1
  74. package/dist/storage/aws-light/index.d.ts +63 -67
  75. package/dist/storage/aws-light/index.js +1 -1
  76. package/dist/storage/azure/index.d.ts +133 -139
  77. package/dist/storage/azure/index.js +1 -1
  78. package/dist/storage/box/index.d.ts +88 -92
  79. package/dist/storage/box/index.js +1 -1
  80. package/dist/storage/bun-s3/index.d.ts +70 -76
  81. package/dist/storage/bun-s3/index.js +1 -1
  82. package/dist/storage/bunny/index.d.ts +51 -55
  83. package/dist/storage/bunny/index.js +1 -1
  84. package/dist/storage/cloudinary/index.d.ts +53 -59
  85. package/dist/storage/cloudinary/index.js +1 -1
  86. package/dist/storage/dropbox/index.d.ts +58 -62
  87. package/dist/storage/dropbox/index.js +1 -1
  88. package/dist/storage/firebase/index.d.ts +73 -79
  89. package/dist/storage/firebase/index.js +1 -1
  90. package/dist/storage/ftp/index.d.ts +37 -43
  91. package/dist/storage/ftp/index.js +1 -1
  92. package/dist/storage/gcs/index.d.ts +89 -95
  93. package/dist/storage/gcs/index.js +1 -1
  94. package/dist/storage/google-drive/index.d.ts +68 -72
  95. package/dist/storage/google-drive/index.js +1 -1
  96. package/dist/storage/local/index.d.ts +3 -3
  97. package/dist/storage/local/index.js +1 -1
  98. package/dist/storage/memory/index.d.ts +2 -2
  99. package/dist/storage/netlify-blob/index.d.ts +85 -93
  100. package/dist/storage/netlify-blob/index.js +1 -1
  101. package/dist/storage/onedrive/index.d.ts +43 -53
  102. package/dist/storage/onedrive/index.js +1 -1
  103. package/dist/storage/pocketbase/index.d.ts +66 -72
  104. package/dist/storage/pocketbase/index.js +1 -1
  105. package/dist/storage/sftp/index.d.ts +39 -45
  106. package/dist/storage/sftp/index.js +1 -1
  107. package/dist/storage/sharepoint/index.d.ts +95 -95
  108. package/dist/storage/sharepoint/index.js +1 -1
  109. package/dist/storage/supabase/index.d.ts +49 -55
  110. package/dist/storage/supabase/index.js +1 -1
  111. package/dist/storage/uploadthing/index.d.ts +33 -37
  112. package/dist/storage/uploadthing/index.js +1 -1
  113. package/dist/storage/vercel-blob/index.d.ts +109 -115
  114. package/dist/storage/vercel-blob/index.js +1 -1
  115. package/dist/transformer/audio-transformer.d.ts +96 -96
  116. package/dist/transformer/image-transformer.d.ts +422 -422
  117. package/dist/transformer/index.d.ts +34 -34
  118. package/dist/transformer/video-transformer.d.ts +111 -111
  119. package/package.json +1 -1
  120. package/dist/packem_shared/BoxMetaStorage-BSn6Qfnf.js +0 -1
  121. package/dist/packem_shared/BunS3MetaStorage-BSn6Qfnf.js +0 -1
  122. package/dist/packem_shared/BunnyMetaStorage-BSn6Qfnf.js +0 -1
  123. package/dist/packem_shared/CloudinaryMetaStorage-DPVnmNe5.js +0 -1
  124. package/dist/packem_shared/DropboxMetaStorage-BSn6Qfnf.js +0 -1
  125. package/dist/packem_shared/FirebaseMetaStorage-DPVnmNe5.js +0 -1
  126. package/dist/packem_shared/FtpMetaStorage-BSn6Qfnf.js +0 -1
  127. package/dist/packem_shared/GoogleDriveMetaStorage-Cbwa1CHV.js +0 -1
  128. package/dist/packem_shared/NetlifyBlobMetaStorage-DPVnmNe5.js +0 -1
  129. package/dist/packem_shared/OneDriveMetaStorage-Cbwa1CHV.js +0 -1
  130. package/dist/packem_shared/PocketBaseMetaStorage-DOTLwVE7.js +0 -1
  131. package/dist/packem_shared/SftpMetaStorage-BSn6Qfnf.js +0 -1
  132. package/dist/packem_shared/SharePointMetaStorage-BSn6Qfnf.js +0 -1
  133. package/dist/packem_shared/SupabaseMetaStorage-Cbwa1CHV.js +0 -1
  134. package/dist/packem_shared/UploadThingMetaStorage-DPVnmNe5.js +0 -1
  135. package/dist/packem_shared/VercelBlobMetaStorage-BSn6Qfnf.js +0 -1
  136. package/dist/packem_shared/disk-storage-CsQcYW3s.js +0 -1
  137. package/dist/packem_shared/disk-storage-with-checksum.d-B-VGEsfl.d.ts +0 -156
  138. package/dist/packem_shared/files.d-CH0iLBNC.d.ts +0 -655
  139. package/dist/packem_shared/local-meta-storage-iuJnu90B.js +0 -11
  140. package/dist/packem_shared/media-transformer.d-Quf4ai47.d.ts +0 -331
  141. package/dist/packem_shared/storage.d-CEM1upWM.d.ts +0 -1176
  142. package/dist/packem_shared/tus-base.d-DLzKE54M.d.ts +0 -106
  143. package/dist/packem_shared/types.d-Bon9GVVe.d.ts +0 -104
@@ -1 +1 @@
1
- import{Readable as w}from"node:stream";import{C,B as M,X as U,c as O}from"./storage-0j5nCAUp.js";import{d as T}from"./detect-file-type-BA7UBLKA.js";import{throwErrorCode as m,ERRORS as y}from"./ERRORS-BIBxE2oR.js";import{createRetryWrapper as A}from"./createRetryWrapper-CxgiV_hH.js";import{y as k}from"./local-meta-storage-iuJnu90B.js";import{t as x}from"./update-size-DuNuLyxj.js";import{i as I}from"./part-match-D-9dGX42.js";import{e as R}from"./has-content-50BsqrWw.js";import{t as S}from"./get-file-status-y3wTtDQs.js";const z=(u,t)=>{const i={};return Object.keys(u).forEach(e=>{i[e]=t(u[e])}),i},v=u=>u===Number(u)?u:(C(u)??0)/1e3,B=5*1024*1024,L=16*1024*1024,N=u=>{if(u)return`bytes=${Math.max(0,u.start)}-${u.end===void 0?"":u.end}`};class b extends M{checksumTypes=["md5","crc32","crc32c","sha1","sha256"];supportsRange=!0;supportsDelimiter=!0;bucket;meta;MAX_PARTS=1e4;partSize;retry;resolvedRetryConfig;constructor(t){if(super(t),this.bucket=t.bucket,this.partSize=typeof t.partSize=="string"?U(t.partSize):t.partSize||L,this.partSize<B)throw new Error("Minimum allowed partSize value is 5MB");const i={backoffMultiplier:2,initialDelay:1e3,maxDelay:3e4,maxRetries:3,retryableStatusCodes:[408,429,500,502,503,504],shouldRetry:a=>{const s=a;return s.statusCode&&[408,429,500,502,503,504].includes(s.statusCode)?!0:s.retryable??!1},...t.retryConfig};this.retry=A(i),this.resolvedRetryConfig=i;const{metaStorage:e,metaStorageConfig:r}=t;if(e)this.meta=e;else{const a={...t,...r,logger:this.logger};"directory"in a?(this.logger?.debug("Using local meta storage"),this.meta=new k(a)):this.meta=new k(a)}this.isReady=!1,this.accessCheck().then(()=>{this.isReady=!0}).catch(a=>{this.logger?.error("Storage access check failed: %O",a)})}getRetryConfig(){return this.resolvedRetryConfig}async create(t,i){return this.instrumentOperation("create",async()=>{const e={...t};if(t.ttl){const n=typeof t.ttl=="string"?O(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 a=this.getS3Api();let s;try{s=await this.runOperation(i,n=>a.createMultipartUpload({ACL:this.getAcl(),Bucket:this.bucket,ContentType:r.contentType,Key:r.name,Metadata:z({originalName:r.originalName,...r.metadata},o=>encodeURI(String(o)))},{signal:n}))}catch{return m(y.FILE_ERROR,"s3 create upload error")}const{UploadId:c}=s||{};return c?(r.UploadId=c,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):m(y.FILE_ERROR,"s3 create upload error")})}async write(t,i){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&&x(e,t.size),!I(t,e))return m(y.FILE_CONFLICT);if(this.config.clientDirectUpload)return this.buildPresigned(e);e.Parts??=await this.getParts(e),e.bytesWritten=e.Parts.map(a=>a.Size||0).reduce((a,s)=>a+s,0);const r=await this.lock(t.id);try{if(R(t)){if(this.isUnsupportedChecksum(t.checksumAlgorithm))return m(y.UNSUPPORTED_CHECKSUM_ALGORITHM);if(e.Parts.length===0&&(!e.contentType||e.contentType==="application/octet-stream"))try{const d=t.body instanceof w?t.body:w.fromWeb(t.body),{fileType:g,stream:f}=await T(d);g?.mime&&(e.contentType=g.mime),t.body=f}catch{}if(e.Parts.length>this.MAX_PARTS)throw new Error(`Exceeded ${this.MAX_PARTS} as part of the upload to ${this.bucket}.`);const a=e.Parts.length+1,s=this.getS3Api(),c=e.UploadId;if(!c)throw new Error("UploadId is required");const n=t.body,o=n instanceof Uint8Array,{ETag:l}=await this.runOperation(i,d=>s.uploadPart({Body:n,Bucket:this.bucket,ContentLength:t.contentLength||0,Key:e.name,PartNumber:a,UploadId:c,...t.checksumAlgorithm==="md5"?{ContentMD5:t.checksum}:{}},{signal:d}),{replayable:o}),p={ETag:l,PartNumber:a,Size:t.contentLength};e.Parts=[...e.Parts,p],e.bytesWritten+=t.contentLength||0}if(this.cache.set(e.id,e),e.status=S(e),e.status==="completed"){const[a]=await this.internalOnComplete(e);delete e.Parts,e.uri=a.Location,e.ETag=a.ETag}}finally{await this.unlock(t.id,r)}return e})}async delete({id:t},i){return this.instrumentOperation("delete",async()=>{const e=await this.getMeta(t);e.status="deleted",await this.abortMultipartUpload(e,i),await this.deleteMeta(e.id);const r={...e};return await this.onDelete(r),r})}async copy(t,i,e){return this.instrumentOperation("copy",async()=>{b.assertSafeId(t),b.assertSafeId(i);const r=await this.getMeta(t),a=`${this.bucket}/${t}`,s=this.bucket,c=i,n=this.getS3Api();return await this.runOperation(e,o=>n.copyObject({Bucket:s,CopySource:a,Key:c,...e?.storageClass&&{StorageClass:e.storageClass}},{signal:o})),{...r,id:c,name:c}})}async move(t,i,e){return this.instrumentOperation("move",async()=>{await this.copy(t,i,e);const r=this.getS3Api();return await this.runOperation(e,a=>r.deleteObject({Bucket:this.bucket,Key:t},{signal:a})),await this.getMeta(i)})}async list(t=1e3,i){return this.instrumentOperation("list",async()=>{const e=this.getS3Api(),r=Math.min(t,1e3);let a={Bucket:this.bucket,MaxKeys:r};const s=[];let c=!0;for(;c&&s.length<t;)try{const n=await this.runOperation(i,o=>e.listObjectsV2(a,{signal:o}));for(const{Key:o,LastModified:l}of n?.Contents||[]){if(s.length>=t)break;o!==void 0&&s.push({id:o,...l&&{createdAt:l}})}c=n.IsTruncated||!1,c&&n.NextContinuationToken&&s.length<t&&(a={...a,ContinuationToken:n.NextContinuationToken,MaxKeys:Math.min(r,t-s.length)})}catch(n){const o=this.normalizeError(n instanceof Error?n:new Error(String(n)));throw await this.onError(o),n}return s},{limit:t})}async listDirectory(t){return this.instrumentOperation("listDirectory",async()=>{const i=this.getS3Api(),e=t?.limit??1e3,r=Math.min(e,1e3);let a={Bucket:this.bucket,Delimiter:t?.delimiter,MaxKeys:r,...t?.prefix!==void 0&&{Prefix:t.prefix}};const s=[],c=new Set;let n=!0;for(;n&&s.length<e;)try{const o=await this.runOperation(t,l=>i.listObjectsV2(a,{signal:l}));for(const{Prefix:l}of o?.CommonPrefixes||[])l!==void 0&&c.add(l);for(const{Key:l,LastModified:p}of o?.Contents||[]){if(s.length>=e)break;l!==void 0&&s.push({id:l,...p&&{createdAt:p}})}n=o.IsTruncated||!1,n&&o.NextContinuationToken&&s.length<e&&(a={...a,ContinuationToken:o.NextContinuationToken,MaxKeys:Math.min(r,e-s.length)})}catch(o){const l=this.normalizeError(o instanceof Error?o:new Error(String(o)));throw await this.onError(l),o}return{files:s,prefixes:[...c]}},{limit:t?.limit??1e3})}async exists({id:t},i){return this.instrumentOperation("exists",async()=>{try{await this.getMeta(t);const e=this.getS3Api();return await this.runOperation(i,r=>e.headObject({Bucket:this.bucket,Key:t},{signal:r})),!0}catch{return!1}})}async get({id:t},i){return this.instrumentOperation("get",async()=>{const e=this.getS3Api(),r=N(i?.range),{Body:a,ContentLength:s,ContentType:c,ETag:n,Expires:o,LastModified:l,Metadata:p}=await this.runOperation(i,h=>e.getObject({Bucket:this.bucket,Key:t,...r!==void 0&&{Range:r}},{signal:h}));await this.checkIfExpired({expiredAt:o});const d=[];if(a)if(a instanceof w)for await(const h of a)d.push(h instanceof Uint8Array?h:new Uint8Array(h));else{const h=a.getReader();try{for(;;){const{done:P,value:E}=await h.read();if(P)break;d.push(E)}}finally{h.releaseLock()}}const{originalName:g,...f}=p||{};return{content:Buffer.concat(d),contentType:c,ETag:n,expiredAt:o,id:t,metadata:f,modifiedAt:l,name:t,originalName:g||t,size:Number(s)}})}async buildPresigned(t){const i=t;if(i.Parts?.length||(i.Parts=await this.getParts(t)),i.bytesWritten=i.Parts.map(e=>e.Size||0).reduce((e,r)=>e+r,0),t.status=S(i),i.partsUrls?.length||(i.partsUrls=await this.getPartsPresignedUrls(t)),t.status==="completed"){const[e]=await this.internalOnComplete(t);return delete i.Parts,i.uri=e.Location,t}return t}async getPartsPresignedUrls(t){t.partSize??=this.partSize;const i=t.UploadId;if(!i)throw new Error("UploadId is required for getting presigned URLs");const e=Math.trunc(t.size/this.partSize)+1,r=[],a=Math.trunc(v(this.config.expiration?.maxAge||"6hrs")),s=this.getS3Api();for(let c=0;c<e;c++)r.push(s.getPresignedUrl({Bucket:this.bucket,expiresIn:a,Key:t.name,PartNumber:c+1,UploadId:i}));return Promise.all(r)}async getParts(t){const i=this.getS3Api(),e=t.UploadId;if(!e)throw new Error("UploadId is required");const{Parts:r=[]}=await this.runOperation(void 0,a=>i.listParts({Bucket:this.bucket,Key:t.name,UploadId:e},{signal:a}));return r}completeMultipartUpload(t){const i=this.getS3Api(),e=t.UploadId;if(!e)throw new Error("UploadId is required");const r=t.Parts?.map(({ETag:a,PartNumber:s})=>{if(!a||!s)throw new Error("ETag and PartNumber are required");return{ETag:a,PartNumber:s}})||[];return this.runOperation(void 0,a=>i.completeMultipartUpload({Bucket:this.bucket,Key:t.name,Parts:r,UploadId:e},{signal:a}))}async abortMultipartUpload(t,i){if(t.status!=="completed")try{const e=this.getS3Api(),r=t.UploadId;if(!r)return;await this.runOperation(i,a=>e.abortMultipartUpload({Bucket:this.bucket,Key:t.name,UploadId:r},{signal:a}))}catch(e){this.logger?.error("abortMultipartUploadError: ",e);const r=this.normalizeError(e instanceof Error?e:new Error(String(e)));await this.onError(r)}}internalOnComplete=async t=>{const[i]=await Promise.all([this.completeMultipartUpload(t),this.deleteMeta(t.id)]);return[i,t]}}export{b as S,N as b};
1
+ import{Readable as w}from"node:stream";import{C,B as M,X as U,c as O}from"./storage-0j5nCAUp.js";import{d as T}from"./detect-file-type-BA7UBLKA.js";import{throwErrorCode as m,ERRORS as y}from"./ERRORS-BIBxE2oR.js";import{createRetryWrapper as A}from"./createRetryWrapper-CxgiV_hH.js";import{y as k}from"./local-meta-storage-DJDcuxf1.js";import{t as x}from"./update-size-DuNuLyxj.js";import{i as I}from"./part-match-D-9dGX42.js";import{e as R}from"./has-content-50BsqrWw.js";import{t as S}from"./get-file-status-y3wTtDQs.js";const z=(u,t)=>{const i={};return Object.keys(u).forEach(e=>{i[e]=t(u[e])}),i},v=u=>u===Number(u)?u:(C(u)??0)/1e3,B=5*1024*1024,L=16*1024*1024,N=u=>{if(u)return`bytes=${Math.max(0,u.start)}-${u.end===void 0?"":u.end}`};class b extends M{checksumTypes=["md5","crc32","crc32c","sha1","sha256"];supportsRange=!0;supportsDelimiter=!0;bucket;meta;MAX_PARTS=1e4;partSize;retry;resolvedRetryConfig;constructor(t){if(super(t),this.bucket=t.bucket,this.partSize=typeof t.partSize=="string"?U(t.partSize):t.partSize||L,this.partSize<B)throw new Error("Minimum allowed partSize value is 5MB");const i={backoffMultiplier:2,initialDelay:1e3,maxDelay:3e4,maxRetries:3,retryableStatusCodes:[408,429,500,502,503,504],shouldRetry:a=>{const s=a;return s.statusCode&&[408,429,500,502,503,504].includes(s.statusCode)?!0:s.retryable??!1},...t.retryConfig};this.retry=A(i),this.resolvedRetryConfig=i;const{metaStorage:e,metaStorageConfig:r}=t;if(e)this.meta=e;else{const a={...t,...r,logger:this.logger};"directory"in a?(this.logger?.debug("Using local meta storage"),this.meta=new k(a)):this.meta=new k(a)}this.isReady=!1,this.accessCheck().then(()=>{this.isReady=!0}).catch(a=>{this.logger?.error("Storage access check failed: %O",a)})}getRetryConfig(){return this.resolvedRetryConfig}async create(t,i){return this.instrumentOperation("create",async()=>{const e={...t};if(t.ttl){const n=typeof t.ttl=="string"?O(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 a=this.getS3Api();let s;try{s=await this.runOperation(i,n=>a.createMultipartUpload({ACL:this.getAcl(),Bucket:this.bucket,ContentType:r.contentType,Key:r.name,Metadata:z({originalName:r.originalName,...r.metadata},o=>encodeURI(String(o)))},{signal:n}))}catch{return m(y.FILE_ERROR,"s3 create upload error")}const{UploadId:c}=s||{};return c?(r.UploadId=c,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):m(y.FILE_ERROR,"s3 create upload error")})}async write(t,i){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&&x(e,t.size),!I(t,e))return m(y.FILE_CONFLICT);if(this.config.clientDirectUpload)return this.buildPresigned(e);e.Parts??=await this.getParts(e),e.bytesWritten=e.Parts.map(a=>a.Size||0).reduce((a,s)=>a+s,0);const r=await this.lock(t.id);try{if(R(t)){if(this.isUnsupportedChecksum(t.checksumAlgorithm))return m(y.UNSUPPORTED_CHECKSUM_ALGORITHM);if(e.Parts.length===0&&(!e.contentType||e.contentType==="application/octet-stream"))try{const d=t.body instanceof w?t.body:w.fromWeb(t.body),{fileType:g,stream:f}=await T(d);g?.mime&&(e.contentType=g.mime),t.body=f}catch{}if(e.Parts.length>this.MAX_PARTS)throw new Error(`Exceeded ${this.MAX_PARTS} as part of the upload to ${this.bucket}.`);const a=e.Parts.length+1,s=this.getS3Api(),c=e.UploadId;if(!c)throw new Error("UploadId is required");const n=t.body,o=n instanceof Uint8Array,{ETag:l}=await this.runOperation(i,d=>s.uploadPart({Body:n,Bucket:this.bucket,ContentLength:t.contentLength||0,Key:e.name,PartNumber:a,UploadId:c,...t.checksumAlgorithm==="md5"?{ContentMD5:t.checksum}:{}},{signal:d}),{replayable:o}),p={ETag:l,PartNumber:a,Size:t.contentLength};e.Parts=[...e.Parts,p],e.bytesWritten+=t.contentLength||0}if(this.cache.set(e.id,e),e.status=S(e),e.status==="completed"){const[a]=await this.internalOnComplete(e);delete e.Parts,e.uri=a.Location,e.ETag=a.ETag}}finally{await this.unlock(t.id,r)}return e})}async delete({id:t},i){return this.instrumentOperation("delete",async()=>{const e=await this.getMeta(t);e.status="deleted",await this.abortMultipartUpload(e,i),await this.deleteMeta(e.id);const r={...e};return await this.onDelete(r),r})}async copy(t,i,e){return this.instrumentOperation("copy",async()=>{b.assertSafeId(t),b.assertSafeId(i);const r=await this.getMeta(t),a=`${this.bucket}/${t}`,s=this.bucket,c=i,n=this.getS3Api();return await this.runOperation(e,o=>n.copyObject({Bucket:s,CopySource:a,Key:c,...e?.storageClass&&{StorageClass:e.storageClass}},{signal:o})),{...r,id:c,name:c}})}async move(t,i,e){return this.instrumentOperation("move",async()=>{await this.copy(t,i,e);const r=this.getS3Api();return await this.runOperation(e,a=>r.deleteObject({Bucket:this.bucket,Key:t},{signal:a})),await this.getMeta(i)})}async list(t=1e3,i){return this.instrumentOperation("list",async()=>{const e=this.getS3Api(),r=Math.min(t,1e3);let a={Bucket:this.bucket,MaxKeys:r};const s=[];let c=!0;for(;c&&s.length<t;)try{const n=await this.runOperation(i,o=>e.listObjectsV2(a,{signal:o}));for(const{Key:o,LastModified:l}of n?.Contents||[]){if(s.length>=t)break;o!==void 0&&s.push({id:o,...l&&{createdAt:l}})}c=n.IsTruncated||!1,c&&n.NextContinuationToken&&s.length<t&&(a={...a,ContinuationToken:n.NextContinuationToken,MaxKeys:Math.min(r,t-s.length)})}catch(n){const o=this.normalizeError(n instanceof Error?n:new Error(String(n)));throw await this.onError(o),n}return s},{limit:t})}async listDirectory(t){return this.instrumentOperation("listDirectory",async()=>{const i=this.getS3Api(),e=t?.limit??1e3,r=Math.min(e,1e3);let a={Bucket:this.bucket,Delimiter:t?.delimiter,MaxKeys:r,...t?.prefix!==void 0&&{Prefix:t.prefix}};const s=[],c=new Set;let n=!0;for(;n&&s.length<e;)try{const o=await this.runOperation(t,l=>i.listObjectsV2(a,{signal:l}));for(const{Prefix:l}of o?.CommonPrefixes||[])l!==void 0&&c.add(l);for(const{Key:l,LastModified:p}of o?.Contents||[]){if(s.length>=e)break;l!==void 0&&s.push({id:l,...p&&{createdAt:p}})}n=o.IsTruncated||!1,n&&o.NextContinuationToken&&s.length<e&&(a={...a,ContinuationToken:o.NextContinuationToken,MaxKeys:Math.min(r,e-s.length)})}catch(o){const l=this.normalizeError(o instanceof Error?o:new Error(String(o)));throw await this.onError(l),o}return{files:s,prefixes:[...c]}},{limit:t?.limit??1e3})}async exists({id:t},i){return this.instrumentOperation("exists",async()=>{try{await this.getMeta(t);const e=this.getS3Api();return await this.runOperation(i,r=>e.headObject({Bucket:this.bucket,Key:t},{signal:r})),!0}catch{return!1}})}async get({id:t},i){return this.instrumentOperation("get",async()=>{const e=this.getS3Api(),r=N(i?.range),{Body:a,ContentLength:s,ContentType:c,ETag:n,Expires:o,LastModified:l,Metadata:p}=await this.runOperation(i,h=>e.getObject({Bucket:this.bucket,Key:t,...r!==void 0&&{Range:r}},{signal:h}));await this.checkIfExpired({expiredAt:o});const d=[];if(a)if(a instanceof w)for await(const h of a)d.push(h instanceof Uint8Array?h:new Uint8Array(h));else{const h=a.getReader();try{for(;;){const{done:P,value:E}=await h.read();if(P)break;d.push(E)}}finally{h.releaseLock()}}const{originalName:g,...f}=p||{};return{content:Buffer.concat(d),contentType:c,ETag:n,expiredAt:o,id:t,metadata:f,modifiedAt:l,name:t,originalName:g||t,size:Number(s)}})}async buildPresigned(t){const i=t;if(i.Parts?.length||(i.Parts=await this.getParts(t)),i.bytesWritten=i.Parts.map(e=>e.Size||0).reduce((e,r)=>e+r,0),t.status=S(i),i.partsUrls?.length||(i.partsUrls=await this.getPartsPresignedUrls(t)),t.status==="completed"){const[e]=await this.internalOnComplete(t);return delete i.Parts,i.uri=e.Location,t}return t}async getPartsPresignedUrls(t){t.partSize??=this.partSize;const i=t.UploadId;if(!i)throw new Error("UploadId is required for getting presigned URLs");const e=Math.trunc(t.size/this.partSize)+1,r=[],a=Math.trunc(v(this.config.expiration?.maxAge||"6hrs")),s=this.getS3Api();for(let c=0;c<e;c++)r.push(s.getPresignedUrl({Bucket:this.bucket,expiresIn:a,Key:t.name,PartNumber:c+1,UploadId:i}));return Promise.all(r)}async getParts(t){const i=this.getS3Api(),e=t.UploadId;if(!e)throw new Error("UploadId is required");const{Parts:r=[]}=await this.runOperation(void 0,a=>i.listParts({Bucket:this.bucket,Key:t.name,UploadId:e},{signal:a}));return r}completeMultipartUpload(t){const i=this.getS3Api(),e=t.UploadId;if(!e)throw new Error("UploadId is required");const r=t.Parts?.map(({ETag:a,PartNumber:s})=>{if(!a||!s)throw new Error("ETag and PartNumber are required");return{ETag:a,PartNumber:s}})||[];return this.runOperation(void 0,a=>i.completeMultipartUpload({Bucket:this.bucket,Key:t.name,Parts:r,UploadId:e},{signal:a}))}async abortMultipartUpload(t,i){if(t.status!=="completed")try{const e=this.getS3Api(),r=t.UploadId;if(!r)return;await this.runOperation(i,a=>e.abortMultipartUpload({Bucket:this.bucket,Key:t.name,UploadId:r},{signal:a}))}catch(e){this.logger?.error("abortMultipartUploadError: ",e);const r=this.normalizeError(e instanceof Error?e:new Error(String(e)));await this.onError(r)}}internalOnComplete=async t=>{const[i]=await Promise.all([this.completeMultipartUpload(t),this.deleteMeta(t.id)]);return[i,t]}}export{b as S,N as b};
@@ -1,16 +1,16 @@
1
1
  import { Readable } from 'node:stream';
2
- import { F as File, M as MetaStorage, c as createRetryWrapper, R as RetryConfig, d as FileInit, B as BaseStorage, O as OperationOptions, e as FilePart, f as FileQuery, g as FileReturn } from "./storage.d-CEM1upWM.js";
2
+ import { F as File, M as MetaStorage, c as createRetryWrapper, R as RetryConfig, d as FileInit, B as BaseStorage, O as OperationOptions, e as FilePart, f as FileQuery, g as FileReturn } from "./storage.d-DIav_lF1.js";
3
3
  /**
4
- * Part interface for multipart uploads.
5
- */
4
+ * Part interface for multipart uploads.
5
+ */
6
6
  interface Part {
7
7
  ETag?: string;
8
8
  PartNumber: number;
9
9
  Size?: number;
10
10
  }
11
11
  /**
12
- * Base file type for S3-compatible storage.
13
- */
12
+ * Base file type for S3-compatible storage.
13
+ */
14
14
  interface S3CompatibleFile extends File {
15
15
  Parts?: Part[];
16
16
  partSize?: number;
@@ -19,15 +19,15 @@ interface S3CompatibleFile extends File {
19
19
  uri?: string;
20
20
  }
21
21
  /**
22
- * Per-call options forwarded to the underlying AWS SDK send().
23
- */
22
+ * Per-call options forwarded to the underlying AWS SDK send().
23
+ */
24
24
  interface S3CallOptions {
25
25
  /** Forwarded to `client.send(command, { abortSignal })`. */
26
26
  signal?: AbortSignal;
27
27
  }
28
28
  /**
29
- * S3 API operations interface that must be implemented by concrete storage classes.
30
- */
29
+ * S3 API operations interface that must be implemented by concrete storage classes.
30
+ */
31
31
  interface S3ApiOperations {
32
32
  abortMultipartUpload: (params: {
33
33
  Bucket: string;
@@ -136,10 +136,10 @@ interface S3ApiOperations {
136
136
  }>;
137
137
  }
138
138
  /**
139
- * Base class for S3-compatible storage implementations.
140
- * Contains all shared business logic for S3 operations.
141
- * @template TFile The file type used by this storage backend.
142
- */
139
+ * Base class for S3-compatible storage implementations.
140
+ * Contains all shared business logic for S3 operations.
141
+ * @template TFile The file type used by this storage backend.
142
+ */
143
143
  declare abstract class S3BaseStorage<TFile extends S3CompatibleFile = S3CompatibleFile> extends BaseStorage<TFile> {
144
144
  override checksumTypes: string[];
145
145
  override readonly supportsRange: boolean;
@@ -147,27 +147,27 @@ declare abstract class S3BaseStorage<TFile extends S3CompatibleFile = S3Compatib
147
147
  protected bucket: string;
148
148
  protected meta: MetaStorage<TFile>;
149
149
  /**
150
- * S3 multipart upload does not allow more than 10000 parts.
151
- */
150
+ * S3 multipart upload does not allow more than 10000 parts.
151
+ */
152
152
  protected readonly MAX_PARTS = 1e4;
153
153
  protected readonly partSize: number;
154
154
  protected readonly retry: ReturnType<typeof createRetryWrapper>;
155
155
  protected readonly resolvedRetryConfig: RetryConfig;
156
156
  /**
157
- * Abstract method to get S3 API operations implementation.
158
- */
157
+ * Abstract method to get S3 API operations implementation.
158
+ */
159
159
  protected abstract getS3Api(): S3ApiOperations;
160
160
  /**
161
- * Abstract method to get the file class constructor.
162
- */
161
+ * Abstract method to get the file class constructor.
162
+ */
163
163
  protected abstract getFileClass(): new (config: FileInit) => TFile;
164
164
  /**
165
- * Abstract method to get ACL value.
166
- */
165
+ * Abstract method to get ACL value.
166
+ */
167
167
  protected abstract getAcl(): string | undefined;
168
168
  /**
169
- * Abstract method for access check.
170
- */
169
+ * Abstract method for access check.
170
+ */
171
171
  protected abstract accessCheck(maxWaitTime?: number): Promise<void>;
172
172
  constructor(config: {
173
173
  bucket: string;
@@ -184,39 +184,37 @@ declare abstract class S3BaseStorage<TFile extends S3CompatibleFile = S3Compatib
184
184
  });
185
185
  protected override getRetryConfig(): RetryConfig;
186
186
  /**
187
- * Creates a new S3 multipart upload.
188
- */
187
+ * Creates a new S3 multipart upload.
188
+ */
189
189
  create(config: FileInit, options?: OperationOptions): Promise<TFile>;
190
190
  /**
191
- * Writes data to an S3 multipart upload.
192
- */
191
+ * Writes data to an S3 multipart upload.
192
+ */
193
193
  write(part: FilePart | FileQuery | TFile, options?: OperationOptions): Promise<TFile>;
194
194
  /**
195
- * Deletes an upload and its metadata.
196
- */
197
- delete({
198
- id
199
- }: FileQuery, options?: OperationOptions): Promise<TFile>;
195
+ * Deletes an upload and its metadata.
196
+ */
197
+ delete({ id }: FileQuery, options?: OperationOptions): Promise<TFile>;
200
198
  /**
201
- * Copies an upload file to a new location.
202
- */
199
+ * Copies an upload file to a new location.
200
+ */
203
201
  copy(name: string, destination: string, options?: OperationOptions & {
204
202
  storageClass?: string;
205
203
  }): Promise<TFile>;
206
204
  /**
207
- * Moves an upload file to a new location.
208
- */
205
+ * Moves an upload file to a new location.
206
+ */
209
207
  move(name: string, destination: string, options?: OperationOptions): Promise<TFile>;
210
208
  /**
211
- * Lists files in the bucket.
212
- */
209
+ * Lists files in the bucket.
210
+ */
213
211
  override list(limit?: number, options?: OperationOptions): Promise<TFile[]>;
214
212
  /**
215
- * Directory-style listing via S3's native `Delimiter`/`Prefix` — the provider returns the direct
216
- * child objects plus the `CommonPrefixes` ("subdirectories") one delimiter level below `prefix`,
217
- * so the whole subtree never has to be fetched. Pages until exhausted or `limit` direct files
218
- * have been collected; common prefixes are accumulated (deduped) across pages.
219
- */
213
+ * Directory-style listing via S3's native `Delimiter`/`Prefix` — the provider returns the direct
214
+ * child objects plus the `CommonPrefixes` ("subdirectories") one delimiter level below `prefix`,
215
+ * so the whole subtree never has to be fetched. Pages until exhausted or `limit` direct files
216
+ * have been collected; common prefixes are accumulated (deduped) across pages.
217
+ */
220
218
  override listDirectory(options?: OperationOptions & {
221
219
  delimiter: string;
222
220
  limit?: number;
@@ -226,59 +224,55 @@ declare abstract class S3BaseStorage<TFile extends S3CompatibleFile = S3Compatib
226
224
  prefixes: string[];
227
225
  }>;
228
226
  /**
229
- * Checks if a file exists by verifying both metadata and the actual S3 object.
230
- * Returns true only if both the metadata and the S3 object exist.
231
- * @param query File query containing the file ID to check.
232
- * @returns Promise resolving to true if both metadata and S3 object exist, false otherwise.
233
- */
234
- override exists({
235
- id
236
- }: FileQuery, options?: OperationOptions): Promise<boolean>;
227
+ * Checks if a file exists by verifying both metadata and the actual S3 object.
228
+ * Returns true only if both the metadata and the S3 object exist.
229
+ * @param query File query containing the file ID to check.
230
+ * @returns Promise resolving to true if both metadata and S3 object exist, false otherwise.
231
+ */
232
+ override exists({ id }: FileQuery, options?: OperationOptions): Promise<boolean>;
237
233
  /**
238
- * Gets an uploaded file by ID.
239
- */
240
- get({
241
- id
242
- }: FileQuery, options?: OperationOptions & {
234
+ * Gets an uploaded file by ID.
235
+ */
236
+ get({ id }: FileQuery, options?: OperationOptions & {
243
237
  range?: {
244
238
  end?: number;
245
239
  start: number;
246
240
  };
247
241
  }): Promise<FileReturn>;
248
242
  /**
249
- * Gets file stream (abstract - must be implemented by subclasses due to stream differences).
250
- */
243
+ * Gets file stream (abstract - must be implemented by subclasses due to stream differences).
244
+ */
251
245
  abstract override getStream(query: FileQuery, options?: OperationOptions): Promise<{
252
246
  headers?: Record<string, string>;
253
247
  size?: number;
254
248
  stream: Readable;
255
249
  }>;
256
250
  /**
257
- * Builds presigned URLs for client uploads.
258
- */
251
+ * Builds presigned URLs for client uploads.
252
+ */
259
253
  protected buildPresigned(file: TFile): Promise<TFile>;
260
254
  /**
261
- * Gets presigned URLs for all parts.
262
- */
255
+ * Gets presigned URLs for all parts.
256
+ */
263
257
  protected getPartsPresignedUrls(file: TFile): Promise<string[]>;
264
258
  /**
265
- * Gets parts for a multipart upload.
266
- */
259
+ * Gets parts for a multipart upload.
260
+ */
267
261
  protected getParts(file: TFile): Promise<Part[]>;
268
262
  /**
269
- * Completes a multipart upload.
270
- */
263
+ * Completes a multipart upload.
264
+ */
271
265
  protected completeMultipartUpload(file: TFile): Promise<{
272
266
  ETag?: string;
273
267
  Location: string;
274
268
  }>;
275
269
  /**
276
- * Aborts a multipart upload.
277
- */
270
+ * Aborts a multipart upload.
271
+ */
278
272
  protected abortMultipartUpload(file: TFile, options?: OperationOptions): Promise<void>;
279
273
  /**
280
- * Internal onComplete handler.
281
- */
274
+ * Internal onComplete handler.
275
+ */
282
276
  protected internalOnComplete: (file: TFile) => Promise<[{
283
277
  ETag?: string;
284
278
  Location: string;