@visulima/storage 1.0.0-alpha.3 → 1.0.0-alpha.30

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 (417) hide show
  1. package/CHANGELOG.md +361 -0
  2. package/LICENSE.md +213 -573
  3. package/README.md +83 -470
  4. package/dist/adapter/nuxt/module.d.ts +41 -34
  5. package/dist/adapter/nuxt/module.js +1 -93
  6. package/dist/adapter/nuxt/node_modules/.bin/nuxi +22 -0
  7. package/dist/adapter/nuxt/node_modules/.bin/nuxt +22 -0
  8. package/dist/adapter/nuxt/package.json +0 -6
  9. package/dist/ai/ai-sdk/index.d.ts +113 -0
  10. package/dist/ai/ai-sdk/index.js +1 -0
  11. package/dist/ai/claude/index.d.ts +177 -0
  12. package/dist/ai/claude/index.js +1 -0
  13. package/dist/ai/openai/index.d.ts +205 -0
  14. package/dist/ai/openai/index.js +1 -0
  15. package/dist/ai/tanstack/index.d.ts +115 -0
  16. package/dist/ai/tanstack/index.js +1 -0
  17. package/dist/handler/http/fetch/index.d.ts +303 -4
  18. package/dist/handler/http/fetch/index.js +1 -4
  19. package/dist/handler/http/hono/index.d.ts +73 -64
  20. package/dist/handler/http/hono/index.js +1 -65
  21. package/dist/handler/http/nextjs/index.d.ts +66 -58
  22. package/dist/handler/http/nextjs/index.js +1 -37
  23. package/dist/handler/http/node/index.d.ts +361 -4
  24. package/dist/handler/http/node/index.js +1 -4
  25. package/dist/handler/http/solid-start/index.d.ts +66 -57
  26. package/dist/handler/http/solid-start/index.js +1 -44
  27. package/dist/index.d.ts +58 -17
  28. package/dist/index.js +1 -13
  29. package/dist/openapi/index.d.ts +24 -5
  30. package/dist/openapi/index.js +1 -5
  31. package/dist/packem_shared/AwsLightFile-BSqjc_rD.js +1 -0
  32. package/dist/packem_shared/AwsLightMetaStorage-B-iQbToR.js +1 -0
  33. package/dist/packem_shared/AwsLightStorage-w21RxjUm.js +1 -0
  34. package/dist/packem_shared/AzureFile-Dgj2Tef4.js +1 -0
  35. package/dist/packem_shared/AzureSMetaStorage-CR-lfQNQ.js +1 -0
  36. package/dist/packem_shared/AzureStorage-2kl7JDXs.js +1 -0
  37. package/dist/packem_shared/BaseTransformer-Fpcuz4kj.js +1 -0
  38. package/dist/packem_shared/BoxFile-Be0S4N1L.js +1 -0
  39. package/dist/packem_shared/BoxMetaStorage-DLdXbZaV.js +1 -0
  40. package/dist/packem_shared/BoxStorage-BUeEJoGL.js +1 -0
  41. package/dist/packem_shared/BunS3File-D-SRiyrm.js +1 -0
  42. package/dist/packem_shared/BunS3MetaStorage-Bv_CTTMz.js +1 -0
  43. package/dist/packem_shared/BunS3Storage-WM3rF6Fw.js +1 -0
  44. package/dist/packem_shared/BunnyFile-Dotl-lO9.js +1 -0
  45. package/dist/packem_shared/BunnyMetaStorage-DNMTSeoN.js +1 -0
  46. package/dist/packem_shared/BunnyStorage-D3s2fRB3.js +1 -0
  47. package/dist/packem_shared/CloudinaryFile-B5-m33eS.js +1 -0
  48. package/dist/packem_shared/CloudinaryMetaStorage-DEBk5eQy.js +1 -0
  49. package/dist/packem_shared/CloudinaryStorage-BBE2-aVz.js +1 -0
  50. package/dist/packem_shared/DiskStorage-DL0GiG6k.js +1 -0
  51. package/dist/packem_shared/DiskStorageWithChecksum-BvUTn7O-.js +1 -0
  52. package/dist/packem_shared/DropboxFile-BGVG2kXM.js +1 -0
  53. package/dist/packem_shared/DropboxMetaStorage-C6vj1QDA.js +1 -0
  54. package/dist/packem_shared/DropboxStorage-BL3OIdE_.js +1 -0
  55. package/dist/packem_shared/ERRORS-CyOuSMLY.js +1 -0
  56. package/dist/packem_shared/File-BhfUgJjs.js +1 -0
  57. package/dist/packem_shared/Files-CJh9_N-9.js +1 -0
  58. package/dist/packem_shared/FirebaseFile-JEu3plMP.js +1 -0
  59. package/dist/packem_shared/FirebaseMetaStorage-CzyOim-J.js +1 -0
  60. package/dist/packem_shared/FirebaseStorage-lXMXy3Pm.js +2 -0
  61. package/dist/packem_shared/FtpFile-B8jaICTB.js +1 -0
  62. package/dist/packem_shared/FtpMetaStorage-1Njy0DpU.js +1 -0
  63. package/dist/packem_shared/FtpStorage-Dw94efNW.js +1 -0
  64. package/dist/packem_shared/GCSConfig-BQ0OpVhe.js +1 -0
  65. package/dist/packem_shared/GCSFile-CDQ6IWAz.js +1 -0
  66. package/dist/packem_shared/GCSMetaStorage-udgXA5ia.js +1 -0
  67. package/dist/packem_shared/GCStorage-ChY6uJuO.js +1 -0
  68. package/dist/packem_shared/GoogleDriveFile-D0aGfGbL.js +1 -0
  69. package/dist/packem_shared/GoogleDriveMetaStorage-WGuUZPyx.js +1 -0
  70. package/dist/packem_shared/GoogleDriveStorage-C0NhBBWH.js +1 -0
  71. package/dist/packem_shared/LocalMetaStorage-QMKL7McF.js +1 -0
  72. package/dist/packem_shared/MediaTransformer-D-1c9Q_k.js +1 -0
  73. package/dist/packem_shared/MetaStorage-Y4m1dWgd.js +1 -0
  74. package/dist/packem_shared/Metadata-B6Ir0KO7.js +1 -0
  75. package/dist/packem_shared/Multipart-CIFfQksD.js +1 -0
  76. package/dist/packem_shared/Multipart-D9WIud9R.js +1 -0
  77. package/dist/packem_shared/NetlifyBlobFile-PMZLJ8AC.js +1 -0
  78. package/dist/packem_shared/NetlifyBlobMetaStorage-ClIFdTkT.js +1 -0
  79. package/dist/packem_shared/NetlifyBlobStorage-CO89TGvF.js +1 -0
  80. package/dist/packem_shared/NoOpMetrics-Dky06sf1.js +1 -0
  81. package/dist/packem_shared/OneDriveFile-XbVVKIJh.js +1 -0
  82. package/dist/packem_shared/OneDriveMetaStorage-DS4f83X2.js +1 -0
  83. package/dist/packem_shared/OneDriveStorage-jAN46vRm.js +1 -0
  84. package/dist/packem_shared/OpenTelemetryMetrics-9uxQMSlg.js +1 -0
  85. package/dist/packem_shared/PocketBaseFile-CkAiSBb0.js +1 -0
  86. package/dist/packem_shared/PocketBaseMetaStorage-B6utPncj.js +1 -0
  87. package/dist/packem_shared/PocketBaseStorage-DpOjOKAt.js +1 -0
  88. package/dist/packem_shared/Rest-BuD3ySAg.js +1 -0
  89. package/dist/packem_shared/Rest-URrQ5FYM.js +1 -0
  90. package/dist/packem_shared/S3File-BfmCOET4.js +1 -0
  91. package/dist/packem_shared/S3MetaStorage-vcriiosn.js +1 -0
  92. package/dist/packem_shared/S3Storage-n1ohEZj4.js +1 -0
  93. package/dist/packem_shared/SftpFile-CQCxZNVq.js +1 -0
  94. package/dist/packem_shared/SftpMetaStorage-DYqXwCdM.js +1 -0
  95. package/dist/packem_shared/SftpStorage-Ban-WN8v.js +1 -0
  96. package/dist/packem_shared/SharePointFile-BA6X9Sxr.js +1 -0
  97. package/dist/packem_shared/SharePointMetaStorage-DVM5-X6g.js +1 -0
  98. package/dist/packem_shared/SharePointStorage-BY90zh1c.js +1 -0
  99. package/dist/packem_shared/SupabaseFile-DZ1iv9gM.js +1 -0
  100. package/dist/packem_shared/SupabaseMetaStorage-ivXoYVUu.js +1 -0
  101. package/dist/packem_shared/SupabaseStorage-pNbHAE1Y.js +1 -0
  102. package/dist/packem_shared/TUS_RESUMABLE-B7KtPVeC.js +1 -0
  103. package/dist/packem_shared/Tus-Fp_hx5ug.js +1 -0
  104. package/dist/packem_shared/Tus-TNG9HAY8.js +1 -0
  105. package/dist/packem_shared/UploadThingFile-BpG9mE8K.js +1 -0
  106. package/dist/packem_shared/UploadThingMetaStorage-BvKNzgm7.js +1 -0
  107. package/dist/packem_shared/UploadThingStorage-BcmIE2dI.js +1 -0
  108. package/dist/packem_shared/ValidationError-D8KKJiKA.js +1 -0
  109. package/dist/packem_shared/VercelBlobFile-Cni_1qwD.js +1 -0
  110. package/dist/packem_shared/VercelBlobMetaStorage-CwaqWucZ.js +1 -0
  111. package/dist/packem_shared/VercelBlobStorage-s260zfFo.js +1 -0
  112. package/dist/packem_shared/_commonjsHelpers-D6W6KoPK.js +1 -0
  113. package/dist/packem_shared/agentsListFiles-R-CnGKc4.js +1 -0
  114. package/dist/packem_shared/akamai-BYS9pP8S.js +1 -0
  115. package/dist/packem_shared/alibaba-BJQ6ijoK.js +1 -0
  116. package/dist/packem_shared/approval-BBeX3o4E.js +1 -0
  117. package/dist/packem_shared/approval.d-CMAYH9GF.d.ts +75 -0
  118. package/dist/packem_shared/aws-light-meta-storage-CstQBYXG.js +4 -0
  119. package/dist/packem_shared/azure-meta-storage-C4SrMtT2.js +1 -0
  120. package/dist/packem_shared/backblaze-CvdtCvJL.js +1 -0
  121. package/dist/packem_shared/base-handler-core-BYDQditz.js +1 -0
  122. package/dist/packem_shared/base-handler-fetch-DWzsPkmV.js +1 -0
  123. package/dist/packem_shared/base-handler-node-Dety2rQB.js +1 -0
  124. package/dist/packem_shared/cache-qV_5Umeq.js +1 -0
  125. package/dist/packem_shared/claudeListFiles-DAezbKEi.js +1 -0
  126. package/dist/packem_shared/cloudflare-Bm_Pg6yx.js +1 -0
  127. package/dist/packem_shared/createResponsesFileTools-BCep-qdO.js +1 -0
  128. package/dist/packem_shared/defaultCloudStorageFileNameValidation-shIZX_7L.js +1 -0
  129. package/dist/packem_shared/detect-file-type-5JhzC9RU.js +1 -0
  130. package/dist/packem_shared/digitalOcean-Lj1NfDzc.js +1 -0
  131. package/dist/packem_shared/disk-storage-CKAJvhcj.js +1 -0
  132. package/dist/packem_shared/disk-storage-with-checksum.d-mHcg2uLw.d.ts +150 -0
  133. package/dist/packem_shared/executors-DG6hGtvm.js +1 -0
  134. package/dist/packem_shared/executors.d-X4hz3zfu.d.ts +65 -0
  135. package/dist/packem_shared/exoscale-O0HzxoDz.js +1 -0
  136. package/dist/packem_shared/filebase-D-urO4Ob.js +1 -0
  137. package/dist/packem_shared/gcs-meta-storage-mZiqlX-9.js +1 -0
  138. package/dist/packem_shared/has-content-Bx2p8Okx.js +1 -0
  139. package/dist/packem_shared/headers-DC2MEOrK.js +27 -0
  140. package/dist/packem_shared/hetzner-DDxE7Gy7.js +1 -0
  141. package/dist/packem_shared/ibmCos-Rx_yku4H.js +1 -0
  142. package/dist/packem_shared/idriveE2-BFhw0Vwy.js +1 -0
  143. package/dist/packem_shared/index-B4ETk0Lu.js +5 -0
  144. package/dist/packem_shared/index.d-C4Fivh4I.d.ts +94 -0
  145. package/dist/packem_shared/is-expired-1JuZjDtb.js +1 -0
  146. package/dist/packem_shared/isRetryableError-BhizNeAz.js +1 -0
  147. package/dist/packem_shared/isValidMediaType-B-2UKjZx.js +1 -0
  148. package/dist/packem_shared/listFiles-B6VF05d-.js +1 -0
  149. package/dist/packem_shared/listFiles-BtP6VnUp.js +1 -0
  150. package/dist/packem_shared/local-meta-storage-Bi0mK6gD.js +1 -0
  151. package/dist/packem_shared/local-meta-storage.d-B11vHYNm.d.ts +21 -0
  152. package/dist/packem_shared/media-transformer.d-C3QvECD7.d.ts +331 -0
  153. package/dist/packem_shared/minio-T_Z3iEy7.js +1 -0
  154. package/dist/packem_shared/multipart-base-BxckfvQf.js +1 -0
  155. package/dist/packem_shared/oauth-refresh-Dg2ybc6_.js +1 -0
  156. package/dist/packem_shared/oracleCloud-D5T9s4JV.js +1 -0
  157. package/dist/packem_shared/ovhCloud-DCwef2fe.js +1 -0
  158. package/dist/packem_shared/part-match-B5fLLmFw.js +1 -0
  159. package/dist/packem_shared/path-D7rMc9nq-B718mbm6.js +1 -0
  160. package/dist/packem_shared/posix-dirname-CiHXPPnw.js +1 -0
  161. package/dist/packem_shared/response-builder-Wdo_fvcF.js +1 -0
  162. package/dist/packem_shared/rest-base-DI7xFXr5.js +1 -0
  163. package/dist/packem_shared/restOpenApiSpec-PaIVbESh.js +1 -0
  164. package/dist/packem_shared/s3-base-storage-Dbexfg7p.js +1 -0
  165. package/dist/packem_shared/s3-base-storage.d-V3N2nKCt.d.ts +260 -0
  166. package/dist/packem_shared/scaleway-ygRXOss9.js +1 -0
  167. package/dist/packem_shared/sharedGet-Ce7WGAsc.js +1 -0
  168. package/dist/packem_shared/storage-Dh0tJh7j.js +1 -0
  169. package/dist/packem_shared/storage.d-RteRC-cG.d.ts +1106 -0
  170. package/dist/packem_shared/storj-CVA9mM-7.js +1 -0
  171. package/dist/packem_shared/tencent-CAcAGaIW.js +1 -0
  172. package/dist/packem_shared/tigris-wmhjfsH2.js +1 -0
  173. package/dist/packem_shared/transformOpenApiSpec-C0vEbDTO.js +1 -0
  174. package/dist/packem_shared/tus-base.d-CygntIPM.d.ts +99 -0
  175. package/dist/packem_shared/tusOpenApiSpec-DF0-hlWV.js +1 -0
  176. package/dist/packem_shared/types.d-ChNXbbHG.d.ts +104 -0
  177. package/dist/packem_shared/types.d-DxonY4XS.d.ts +720 -0
  178. package/dist/packem_shared/types.d-cI_cMxcZ.d.ts +49 -0
  179. package/dist/packem_shared/update-size-DANV7aa2.js +1 -0
  180. package/dist/packem_shared/vultr-lK9L-sFk.js +1 -0
  181. package/dist/packem_shared/waitForStorage-ChSBLhLc.js +1 -0
  182. package/dist/packem_shared/wasabi-JQzxdrFy.js +1 -0
  183. package/dist/packem_shared/xhrOpenApiSpec-nyoboz83.js +1 -0
  184. package/dist/packem_shared/yandex-ZwvE77v4.js +1 -0
  185. package/dist/storage/aws/clients/index.d.ts +612 -6
  186. package/dist/storage/aws/clients/index.js +1 -6
  187. package/dist/storage/aws/index.d.ts +321 -4
  188. package/dist/storage/aws/index.js +1 -3
  189. package/dist/storage/aws-light/index.d.ts +254 -4
  190. package/dist/storage/aws-light/index.js +1 -3
  191. package/dist/storage/azure/index.d.ts +217 -4
  192. package/dist/storage/azure/index.js +1 -3
  193. package/dist/storage/box/index.d.ts +189 -0
  194. package/dist/storage/box/index.js +1 -0
  195. package/dist/storage/bun-s3/index.d.ts +200 -0
  196. package/dist/storage/bun-s3/index.js +1 -0
  197. package/dist/storage/bunny/index.d.ts +119 -0
  198. package/dist/storage/bunny/index.js +1 -0
  199. package/dist/storage/cloudinary/index.d.ts +121 -0
  200. package/dist/storage/cloudinary/index.js +1 -0
  201. package/dist/storage/dropbox/index.d.ts +132 -0
  202. package/dist/storage/dropbox/index.js +1 -0
  203. package/dist/storage/firebase/index.d.ts +192 -0
  204. package/dist/storage/firebase/index.js +1 -0
  205. package/dist/storage/ftp/index.d.ts +85 -0
  206. package/dist/storage/ftp/index.js +1 -0
  207. package/dist/storage/gcs/index.d.ts +181 -5
  208. package/dist/storage/gcs/index.js +1 -4
  209. package/dist/storage/google-drive/index.d.ts +148 -0
  210. package/dist/storage/google-drive/index.js +1 -0
  211. package/dist/storage/local/index.d.ts +7 -4
  212. package/dist/storage/local/index.js +1 -3
  213. package/dist/storage/netlify-blob/index.d.ts +147 -4
  214. package/dist/storage/netlify-blob/index.js +1 -3
  215. package/dist/storage/onedrive/index.d.ts +103 -0
  216. package/dist/storage/onedrive/index.js +1 -0
  217. package/dist/storage/pocketbase/index.d.ts +172 -0
  218. package/dist/storage/pocketbase/index.js +1 -0
  219. package/dist/storage/sftp/index.d.ts +86 -0
  220. package/dist/storage/sftp/index.js +1 -0
  221. package/dist/storage/sharepoint/index.d.ts +180 -0
  222. package/dist/storage/sharepoint/index.js +1 -0
  223. package/dist/storage/supabase/index.d.ts +115 -0
  224. package/dist/storage/supabase/index.js +1 -0
  225. package/dist/storage/uploadthing/index.d.ts +95 -0
  226. package/dist/storage/uploadthing/index.js +1 -0
  227. package/dist/storage/vercel-blob/index.d.ts +189 -4
  228. package/dist/storage/vercel-blob/index.js +1 -3
  229. package/dist/transformer/audio-transformer.d.ts +127 -125
  230. package/dist/transformer/audio-transformer.js +1 -278
  231. package/dist/transformer/image-transformer.d.ts +573 -568
  232. package/dist/transformer/image-transformer.js +1 -1100
  233. package/dist/transformer/index.d.ts +62 -5
  234. package/dist/transformer/index.js +1 -4
  235. package/dist/transformer/video-transformer.d.ts +144 -142
  236. package/dist/transformer/video-transformer.js +1 -310
  237. package/package.json +195 -47
  238. package/dist/handler/base/base-handler-core.d.ts +0 -91
  239. package/dist/handler/base/base-handler-fetch.d.ts +0 -76
  240. package/dist/handler/base/base-handler-node.d.ts +0 -137
  241. package/dist/handler/multipart/multipart-base.d.ts +0 -84
  242. package/dist/handler/multipart/multipart-fetch.d.ts +0 -64
  243. package/dist/handler/multipart/multipart.d.ts +0 -49
  244. package/dist/handler/rest/rest-base.d.ts +0 -106
  245. package/dist/handler/rest/rest-fetch.d.ts +0 -88
  246. package/dist/handler/rest/rest.d.ts +0 -93
  247. package/dist/handler/tus/tus-base.d.ts +0 -152
  248. package/dist/handler/tus/tus-fetch.d.ts +0 -72
  249. package/dist/handler/tus/tus.d.ts +0 -78
  250. package/dist/handler/types.d.ts +0 -53
  251. package/dist/handler/utils/request-parser.d.ts +0 -72
  252. package/dist/handler/utils/response-builder.d.ts +0 -83
  253. package/dist/handler/utils/storage-utils.d.ts +0 -10
  254. package/dist/handler/utils/stream-utils.d.ts +0 -29
  255. package/dist/handler/utils/upload-handlers.d.ts +0 -76
  256. package/dist/metrics/index.d.ts +0 -2
  257. package/dist/metrics/no-op-metrics.d.ts +0 -15
  258. package/dist/metrics/opentelemetry-metrics.d.ts +0 -55
  259. package/dist/openapi/rest.d.ts +0 -7
  260. package/dist/openapi/shared.d.ts +0 -13
  261. package/dist/openapi/transform.d.ts +0 -3
  262. package/dist/openapi/tus.d.ts +0 -7
  263. package/dist/openapi/xhr.d.ts +0 -7
  264. package/dist/packem_shared/AwsLightFile-tTneXZgG.js +0 -11
  265. package/dist/packem_shared/AwsLightMetaStorage-BWSOtVaN.js +0 -4
  266. package/dist/packem_shared/AwsLightStorage-Blv-GP4v.js +0 -133
  267. package/dist/packem_shared/AzureFile-CesgFzps.js +0 -8
  268. package/dist/packem_shared/AzureSMetaStorage-CFs-OYJT.js +0 -88
  269. package/dist/packem_shared/AzureStorage-B0v048hG.js +0 -357
  270. package/dist/packem_shared/BaseTransformer-C2gLib6v.js +0 -82
  271. package/dist/packem_shared/DiskStorage-BlltBst6.js +0 -12
  272. package/dist/packem_shared/DiskStorageWithChecksum-BJTmMklc.js +0 -238
  273. package/dist/packem_shared/ERRORS-D0apMqnc.js +0 -97
  274. package/dist/packem_shared/File-Bb3P23dr.js +0 -69
  275. package/dist/packem_shared/GCSConfig-vPP22kN6.js +0 -11
  276. package/dist/packem_shared/GCSFile-BIEunhAN.js +0 -8
  277. package/dist/packem_shared/GCSMetaStorage-BMFEdzJ7.js +0 -7
  278. package/dist/packem_shared/GCStorage-DnhiwaS9.js +0 -406
  279. package/dist/packem_shared/LocalMetaStorage-CZHhKkMd.js +0 -7
  280. package/dist/packem_shared/MediaTransformer-D6658DL1.js +0 -1197
  281. package/dist/packem_shared/MetaStorage-pECeFOad.js +0 -46
  282. package/dist/packem_shared/Metadata-DRLXeJ0F.js +0 -89
  283. package/dist/packem_shared/Multipart-CNFK_Okz.js +0 -163
  284. package/dist/packem_shared/Multipart-CtUL7BQw.js +0 -128
  285. package/dist/packem_shared/NetlifyBlobFile-CXzyjqrD.js +0 -14
  286. package/dist/packem_shared/NetlifyBlobMetaStorage-DxZ5aDvD.js +0 -9
  287. package/dist/packem_shared/NetlifyBlobStorage-CLPtjHqd.js +0 -376
  288. package/dist/packem_shared/NoOpMetrics-DhAk5rXc.js +0 -10
  289. package/dist/packem_shared/OpenTelemetryMetrics-BnxhqIaH.js +0 -67
  290. package/dist/packem_shared/Rest-CAOAEkOj.js +0 -267
  291. package/dist/packem_shared/Rest-DNuLwBrK.js +0 -228
  292. package/dist/packem_shared/S3File-DZiyk9Qt.js +0 -11
  293. package/dist/packem_shared/S3MetaStorage-Dz9aDabA.js +0 -76
  294. package/dist/packem_shared/S3Storage-DHmTk-hU.js +0 -316
  295. package/dist/packem_shared/TUS_RESUMABLE-GJzZ9R-f.js +0 -434
  296. package/dist/packem_shared/Tus-B8PmlMgR.js +0 -200
  297. package/dist/packem_shared/Tus-C4F1aYOl.js +0 -195
  298. package/dist/packem_shared/ValidationError-BfF1aE4h.js +0 -26
  299. package/dist/packem_shared/VercelBlobFile-BCg4aTEq.js +0 -18
  300. package/dist/packem_shared/VercelBlobMetaStorage-Bd9F-VFm.js +0 -9
  301. package/dist/packem_shared/VercelBlobStorage-DD9LMOS6.js +0 -261
  302. package/dist/packem_shared/_commonjsHelpers-B85MJLTf.js +0 -5
  303. package/dist/packem_shared/aws-light-meta-storage-DKJBgbR6.js +0 -446
  304. package/dist/packem_shared/backblaze-BlMnIcBC.js +0 -20
  305. package/dist/packem_shared/base-handler-core-BKuf4YLT.js +0 -303
  306. package/dist/packem_shared/base-handler-fetch-Cr0hLiqg.js +0 -291
  307. package/dist/packem_shared/base-handler-node-gk5aN9Cx.js +0 -730
  308. package/dist/packem_shared/cache-B88MXQ_2.js +0 -18
  309. package/dist/packem_shared/cloudflare-Bi1q8wXE.js +0 -21
  310. package/dist/packem_shared/defaultCloudStorageFileNameValidation-DUuacjWv.js +0 -11
  311. package/dist/packem_shared/digitalOcean-CWQRJM3L.js +0 -21
  312. package/dist/packem_shared/disk-storage-Bh2wy3YW.js +0 -810
  313. package/dist/packem_shared/gcs-meta-storage-0tgMNnPO.js +0 -158
  314. package/dist/packem_shared/has-content-CY66ehMK.js +0 -3
  315. package/dist/packem_shared/headers-DoS5nwM-.js +0 -3220
  316. package/dist/packem_shared/is-expired-CTThU1q5.js +0 -8
  317. package/dist/packem_shared/isRetryableError-Dycp7127.js +0 -82
  318. package/dist/packem_shared/isValidMediaType-BeDgiObq.js +0 -35
  319. package/dist/packem_shared/local-meta-storage-By-3SNBI.js +0 -649
  320. package/dist/packem_shared/minio-C2YBZQOw.js +0 -22
  321. package/dist/packem_shared/multipart-base-B3i67SSX.js +0 -102
  322. package/dist/packem_shared/part-match-BMNqHDYD.js +0 -96
  323. package/dist/packem_shared/path-CR6YkPXX-7R1-9CMk.js +0 -161
  324. package/dist/packem_shared/response-builder-BtnRiBUI.js +0 -45
  325. package/dist/packem_shared/rest-base-GRCcnan7.js +0 -457
  326. package/dist/packem_shared/restOpenApiSpec-CwcHHY2C.js +0 -800
  327. package/dist/packem_shared/s3-base-storage-C1DIHTYY.js +0 -510
  328. package/dist/packem_shared/sharedGet-Cpo7QUyu.js +0 -1019
  329. package/dist/packem_shared/storage-C6NSXb8h.js +0 -1175
  330. package/dist/packem_shared/tigris-Hac8TKnX.js +0 -21
  331. package/dist/packem_shared/transformOpenApiSpec-DWM5WtnN.js +0 -975
  332. package/dist/packem_shared/tusOpenApiSpec-6ohiToBy.js +0 -740
  333. package/dist/packem_shared/update-size-CCGm6i1J.js +0 -8
  334. package/dist/packem_shared/validator-BeX_lJet.js +0 -78
  335. package/dist/packem_shared/waitForStorage-Cscw85sx.js +0 -18
  336. package/dist/packem_shared/wasabi-DIyflHSd.js +0 -21
  337. package/dist/packem_shared/xhrOpenApiSpec-DS17brnx.js +0 -264
  338. package/dist/storage/aws/clients/backblaze.d.ts +0 -12
  339. package/dist/storage/aws/clients/cloudflare.d.ts +0 -13
  340. package/dist/storage/aws/clients/digital-ocean.d.ts +0 -12
  341. package/dist/storage/aws/clients/minio.d.ts +0 -13
  342. package/dist/storage/aws/clients/tigris.d.ts +0 -12
  343. package/dist/storage/aws/clients/types.d.ts +0 -95
  344. package/dist/storage/aws/clients/wasabi.d.ts +0 -12
  345. package/dist/storage/aws/s3-base-storage.d.ts +0 -248
  346. package/dist/storage/aws/s3-client-adapter.d.ts +0 -110
  347. package/dist/storage/aws/s3-file.d.ts +0 -10
  348. package/dist/storage/aws/s3-meta-storage.d.ts +0 -15
  349. package/dist/storage/aws/s3-storage.d.ts +0 -70
  350. package/dist/storage/aws/types.d.ts +0 -119
  351. package/dist/storage/aws-light/aws-light-api-adapter.d.ts +0 -130
  352. package/dist/storage/aws-light/aws-light-file.d.ts +0 -10
  353. package/dist/storage/aws-light/aws-light-meta-storage.d.ts +0 -19
  354. package/dist/storage/aws-light/aws-light-storage.d.ts +0 -65
  355. package/dist/storage/aws-light/types.d.ts +0 -37
  356. package/dist/storage/azure/azure-file.d.ts +0 -6
  357. package/dist/storage/azure/azure-meta-storage.d.ts +0 -15
  358. package/dist/storage/azure/azure-storage.d.ts +0 -69
  359. package/dist/storage/azure/types.d.ts +0 -62
  360. package/dist/storage/gcs/fetch-error.d.ts +0 -11
  361. package/dist/storage/gcs/gcs-config.d.ts +0 -2
  362. package/dist/storage/gcs/gcs-file.d.ts +0 -6
  363. package/dist/storage/gcs/gcs-meta-storage.d.ts +0 -27
  364. package/dist/storage/gcs/gcs-storage.d.ts +0 -91
  365. package/dist/storage/gcs/types.d.ts +0 -55
  366. package/dist/storage/gcs/utils.d.ts +0 -7
  367. package/dist/storage/local/disk-storage-with-checksum.d.ts +0 -15
  368. package/dist/storage/local/disk-storage.d.ts +0 -135
  369. package/dist/storage/local/local-meta-storage.d.ts +0 -32
  370. package/dist/storage/meta-storage.d.ts +0 -30
  371. package/dist/storage/netlify-blob/netlify-blob-file.d.ts +0 -12
  372. package/dist/storage/netlify-blob/netlify-blob-meta-storage.d.ts +0 -7
  373. package/dist/storage/netlify-blob/netlify-blob-storage.d.ts +0 -93
  374. package/dist/storage/netlify-blob/types.d.ts +0 -30
  375. package/dist/storage/storage.d.ts +0 -353
  376. package/dist/storage/types.d.ts +0 -221
  377. package/dist/storage/utils/file/file.d.ts +0 -25
  378. package/dist/storage/utils/file/get-file-status.d.ts +0 -9
  379. package/dist/storage/utils/file/has-content.d.ts +0 -9
  380. package/dist/storage/utils/file/index.d.ts +0 -10
  381. package/dist/storage/utils/file/is-expired.d.ts +0 -8
  382. package/dist/storage/utils/file/metadata.d.ts +0 -18
  383. package/dist/storage/utils/file/part-match.d.ts +0 -11
  384. package/dist/storage/utils/file/types.d.ts +0 -37
  385. package/dist/storage/utils/file/update-metadata.d.ts +0 -10
  386. package/dist/storage/utils/file/update-size.d.ts +0 -10
  387. package/dist/storage/vercel-blob/types.d.ts +0 -32
  388. package/dist/storage/vercel-blob/vercel-blob-file.d.ts +0 -16
  389. package/dist/storage/vercel-blob/vercel-blob-meta-storage.d.ts +0 -7
  390. package/dist/storage/vercel-blob/vercel-blob-storage.d.ts +0 -76
  391. package/dist/transformer/base-transformer.d.ts +0 -63
  392. package/dist/transformer/media-transformer.d.ts +0 -332
  393. package/dist/transformer/types.d.ts +0 -652
  394. package/dist/transformer/utils.d.ts +0 -33
  395. package/dist/transformer/validation-error.d.ts +0 -23
  396. package/dist/utils/cache.d.ts +0 -32
  397. package/dist/utils/chunked-upload.d.ts +0 -65
  398. package/dist/utils/detect-file-type.d.ts +0 -28
  399. package/dist/utils/errors.d.ts +0 -74
  400. package/dist/utils/file-path-url-matcher.d.ts +0 -18
  401. package/dist/utils/headers.d.ts +0 -111
  402. package/dist/utils/http.d.ts +0 -92
  403. package/dist/utils/locker.d.ts +0 -26
  404. package/dist/utils/pipes/stream-checksum.d.ts +0 -47
  405. package/dist/utils/pipes/stream-length.d.ts +0 -22
  406. package/dist/utils/primitives/get-last-one.d.ts +0 -3
  407. package/dist/utils/primitives/is-record.d.ts +0 -2
  408. package/dist/utils/primitives/map-values.d.ts +0 -9
  409. package/dist/utils/primitives/pick.d.ts +0 -2
  410. package/dist/utils/primitives/to-milliseconds.d.ts +0 -12
  411. package/dist/utils/primitives/to-seconds.d.ts +0 -12
  412. package/dist/utils/range-checksum.d.ts +0 -33
  413. package/dist/utils/range-hasher.d.ts +0 -46
  414. package/dist/utils/retry.d.ts +0 -64
  415. package/dist/utils/types.d.ts +0 -108
  416. package/dist/utils/validation-error.d.ts +0 -22
  417. package/dist/utils/validator.d.ts +0 -36
@@ -1,1175 +0,0 @@
1
- import { Readable } from 'node:stream';
2
- import { setInterval } from 'node:timers';
3
- import { inspect } from 'node:util';
4
- import typeis from 'type-is';
5
- import NoOpMetrics from './NoOpMetrics-DhAk5rXc.js';
6
- import { N as NoOpCache } from './cache-B88MXQ_2.js';
7
- import { ErrorMap, throwErrorCode, ERRORS } from './ERRORS-D0apMqnc.js';
8
- import { LRUCache } from 'lru-cache';
9
- import { a as Validator } from './validator-BeX_lJet.js';
10
- import { n as normalize, i as isAbsolute } from './path-CR6YkPXX-7R1-9CMk.js';
11
- import { i as isExpired } from './is-expired-CTThU1q5.js';
12
-
13
- const BYTE_SIZES = {
14
- iec: [
15
- {
16
- long: "Bytes",
17
- short: "B"
18
- },
19
- {
20
- long: "Kibibytes",
21
- short: "KiB"
22
- },
23
- {
24
- long: "Mebibytes",
25
- short: "MiB"
26
- },
27
- {
28
- long: "Gibibytes",
29
- short: "GiB"
30
- },
31
- {
32
- long: "Tebibytes",
33
- short: "TiB"
34
- },
35
- {
36
- long: "Pebibytes",
37
- short: "PiB"
38
- },
39
- {
40
- long: "Exbibytes",
41
- short: "EiB"
42
- },
43
- {
44
- long: "Zebibytes",
45
- short: "ZiB"
46
- },
47
- {
48
- long: "Yobibytes",
49
- short: "YiB"
50
- }
51
- ],
52
- iec_octet: [
53
- {
54
- long: "Octets",
55
- short: "o"
56
- },
57
- {
58
- long: "Kibioctets",
59
- short: "Kio"
60
- },
61
- {
62
- long: "Mebioctets",
63
- short: "Mio"
64
- },
65
- {
66
- long: "Gibioctets",
67
- short: "Gio"
68
- },
69
- {
70
- long: "Tebioctets",
71
- short: "Tio"
72
- },
73
- {
74
- long: "Pebioctets",
75
- short: "Pio"
76
- },
77
- {
78
- long: "Exbioctets",
79
- short: "Eio"
80
- },
81
- {
82
- long: "Zebioctets",
83
- short: "Zio"
84
- },
85
- {
86
- long: "Yobioctets",
87
- short: "Yio"
88
- }
89
- ],
90
- metric: [
91
- {
92
- long: "Bytes",
93
- short: "Bytes"
94
- },
95
- {
96
- long: "Kilobytes",
97
- short: "KB"
98
- },
99
- {
100
- long: "Megabytes",
101
- short: "MB"
102
- },
103
- {
104
- long: "Gigabytes",
105
- short: "GB"
106
- },
107
- {
108
- long: "Terabytes",
109
- short: "TB"
110
- },
111
- {
112
- long: "Petabytes",
113
- short: "PB"
114
- },
115
- {
116
- long: "Exabytes",
117
- short: "EB"
118
- },
119
- {
120
- long: "Zettabytes",
121
- short: "ZB"
122
- },
123
- {
124
- long: "Yottabytes",
125
- short: "YB"
126
- }
127
- ],
128
- metric_octet: [
129
- {
130
- long: "Octets",
131
- short: "o"
132
- },
133
- {
134
- long: "Kilo-octets",
135
- short: "ko"
136
- },
137
- {
138
- long: "Mega-octets",
139
- short: "Mo"
140
- },
141
- {
142
- long: "Giga-octets",
143
- short: "Go"
144
- },
145
- {
146
- long: "Tera-octets",
147
- short: "To"
148
- },
149
- {
150
- long: "Peta-octets",
151
- short: "Po"
152
- },
153
- {
154
- long: "Exa-octets",
155
- short: "Eo"
156
- },
157
- {
158
- long: "Zetta-octets",
159
- short: "Zo"
160
- },
161
- {
162
- long: "Yotta-octets",
163
- short: "Yo"
164
- }
165
- ]
166
- };
167
- const parseLocalizedNumber = (stringNumber, locale) => {
168
- const thousandSeparator = new Intl.NumberFormat(locale).format(11111).replaceAll(new RegExp("\\p{Number}", "gu"), "");
169
- const decimalSeparator = new Intl.NumberFormat(locale).format(1.1).replaceAll(new RegExp("\\p{Number}", "gu"), "");
170
- return Number.parseFloat(stringNumber.replaceAll(new RegExp(`\\${thousandSeparator}`, "g"), "").replace(new RegExp(`\\${decimalSeparator}`), "."));
171
- };
172
- const fromBase = (base) => {
173
- if (base === 2) {
174
- return 1024;
175
- }
176
- if (base === 10) {
177
- return 1e3;
178
- }
179
- throw new TypeError(`Unsupported base.`);
180
- };
181
- const parseBytes = (value, options) => {
182
- const config = {
183
- base: 2,
184
- locale: "en-US",
185
- units: "metric",
186
- ...options
187
- };
188
- if (typeof value !== "string" || value.length === 0) {
189
- throw new TypeError("Value is not a string or is empty.");
190
- }
191
- if (value.length > 100) {
192
- throw new TypeError("Value exceeds the maximum length of 100 characters.");
193
- }
194
- const match = /^(?<value>-?(?:\d+(([.,])\d+)*)?[.,]?\d+) *(?<type>bytes?|b|kb|kib|mb|mib|gb|gib|tb|tib|pb|pib|eb|eib|zb|zib|yb|yib|(kilo|kibi|mega|mebi|giga|gibi|tera|tebi|peta|pebi|exa|exbi|zetta|zebi|yotta|yobi)?bytes)?$/i.exec(
195
- value
196
- );
197
- const groups = match?.groups;
198
- if (!groups) {
199
- return Number.NaN;
200
- }
201
- const localizedNumber = parseLocalizedNumber(groups.value, config.locale);
202
- const type = (groups.type ?? "Bytes").toUpperCase().replace(/^KIBI/, "KILO").replace(/^MIBI/, "MEGA").replace(/^GIBI/, "GIGA").replace(/^TEBI/, "TERA").replace(/^PEBI/, "PETA").replace(/^EXBI/, "EXA").replace(/^ZEBI/, "ZETTA").replace(/^YIBI/, "YOTTA").replace(/^(.)IB$/, "$1B");
203
- const level = BYTE_SIZES[config.units].findIndex((unit) => unit.short[0].toUpperCase() === type[0]);
204
- const base = fromBase(config.base);
205
- return localizedNumber * base ** level;
206
- };
207
-
208
- const createDurationLanguage = (y, mo, w, d, h, m, s, ms, future, past, decimal, unitMap, groupSeparator, placeholderSeparator) => {
209
- const result = {
210
- d,
211
- h,
212
- m,
213
- mo,
214
- ms,
215
- s,
216
- w,
217
- y
218
- };
219
- {
220
- result.future = future;
221
- }
222
- {
223
- result.past = past;
224
- }
225
- {
226
- result.decimal = decimal;
227
- }
228
- if (unitMap !== void 0) {
229
- result.unitMap = unitMap;
230
- }
231
- {
232
- result.groupSeparator = groupSeparator;
233
- }
234
- {
235
- result.placeholderSeparator = placeholderSeparator;
236
- }
237
- return result;
238
- };
239
-
240
- const englishUnitMap = {
241
- d: "d",
242
- day: "d",
243
- days: "d",
244
- h: "h",
245
- hour: "h",
246
- hours: "h",
247
- hr: "h",
248
- hrs: "h",
249
- m: "m",
250
- millisecond: "ms",
251
- milliseconds: "ms",
252
- min: "m",
253
- mins: "m",
254
- minute: "m",
255
- minutes: "m",
256
- mo: "mo",
257
- month: "mo",
258
- months: "mo",
259
- ms: "ms",
260
- s: "s",
261
- sec: "s",
262
- second: "s",
263
- seconds: "s",
264
- secs: "s",
265
- w: "w",
266
- week: "w",
267
- weeks: "w",
268
- y: "y",
269
- year: "y",
270
- years: "y",
271
- yr: "y",
272
- yrs: "y"
273
- };
274
- const durationLanguage = createDurationLanguage(
275
- (counter) => `year${counter === 1 ? "" : "s"}`,
276
- (counter) => `month${counter === 1 ? "" : "s"}`,
277
- (counter) => `week${counter === 1 ? "" : "s"}`,
278
- (counter) => `day${counter === 1 ? "" : "s"}`,
279
- (counter) => `hour${counter === 1 ? "" : "s"}`,
280
- (counter) => `minute${counter === 1 ? "" : "s"}`,
281
- (counter) => `second${counter === 1 ? "" : "s"}`,
282
- (counter) => `millisecond${counter === 1 ? "" : "s"}`,
283
- "in %s",
284
- "%s ago",
285
- ".",
286
- // decimal
287
- englishUnitMap,
288
- ",",
289
- // groupSeparator
290
- "_"
291
- // placeholderSeparator
292
- );
293
-
294
- const validateDurationLanguage = (language) => {
295
- const requiredProperties = ["y", "mo", "w", "d", "h", "m", "s", "ms", "future", "past"];
296
- for (const property of requiredProperties) {
297
- if (!Object.prototype.hasOwnProperty.call(language, property)) {
298
- throw new TypeError(`Missing required property: ${property}`);
299
- }
300
- }
301
- if (typeof language.future !== "string" || typeof language.past !== "string") {
302
- throw new TypeError("Properties future and past must be of type string");
303
- }
304
- for (const property of ["y", "mo", "w", "d", "h", "m", "s", "ms"]) {
305
- if (typeof language[property] !== "string" && typeof language[property] !== "function") {
306
- throw new TypeError(`Property ${property} must be of type string or function`);
307
- }
308
- }
309
- if (language.decimal && typeof language.decimal !== "string") {
310
- throw new TypeError("Property decimal must be of type string");
311
- }
312
- if (language.delimiter && typeof language.delimiter !== "string") {
313
- throw new TypeError("Property delimiter must be of type string");
314
- }
315
- if (language._digitReplacements && !Array.isArray(language._digitReplacements)) {
316
- throw new TypeError("Property _digitReplacements must be an array");
317
- }
318
- if (language._numberFirst && typeof language._numberFirst !== "boolean") {
319
- throw new TypeError("Property _numberFirst must be of type boolean");
320
- }
321
- if (language.unitMap && typeof language.unitMap !== "object") {
322
- throw new TypeError("Property unitMap must be an object");
323
- }
324
- if (language.unitMap && Object.values(language.unitMap).some((value) => typeof value !== "string")) {
325
- throw new TypeError("All values in unitMap must be of type string");
326
- }
327
- };
328
-
329
- const STANDARD_UNIT_MEASURES = {
330
- d: 864e5,
331
- h: 36e5,
332
- m: 6e4,
333
- mo: 2629746e3,
334
- ms: 1,
335
- s: 1e3,
336
- w: 6048e5,
337
- y: 31556952e3
338
- };
339
- const ESCAPE_REGEX = /[-/\\^$*+?.()|[\]{}]/g;
340
- const ISO_FORMAT = /^PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/i;
341
- const COLON_FORMAT = /^(?:(\d+):)?(?:(\d+):)?(\d+)$/;
342
- const NUMERIC_STRING_REGEX = /^[+-]?\d+(?:\.\d+)?$/;
343
- const parseDuration = (value, options) => {
344
- if (typeof value !== "string" || value.length === 0) {
345
- return void 0;
346
- }
347
- const { defaultUnit = "ms", language = durationLanguage } = {};
348
- validateDurationLanguage(language);
349
- const decimalSeparator = language.decimal ?? ".";
350
- const groupSeparator = language.groupSeparator ?? ",";
351
- const placeholderSeparator = language.placeholderSeparator ?? "_";
352
- const escapedDecimal = decimalSeparator.replaceAll(ESCAPE_REGEX, String.raw`\$&`);
353
- const escapedGroup = groupSeparator.replaceAll(ESCAPE_REGEX, String.raw`\$&`);
354
- const escapedPlaceholder = placeholderSeparator.replaceAll(ESCAPE_REGEX, String.raw`\$&`);
355
- const currentUnitMap = language.unitMap ?? englishUnitMap;
356
- let processedValue = value.replaceAll(new RegExp(String.raw`(\d)[${escapedPlaceholder}${escapedGroup}](\d)`, "g"), "$1$2");
357
- if (decimalSeparator !== ".") {
358
- processedValue = processedValue.replace(escapedDecimal, ".");
359
- }
360
- if (NUMERIC_STRING_REGEX.test(value)) {
361
- const numberOnly = Number.parseFloat(processedValue.trim());
362
- if (!Number.isNaN(numberOnly)) {
363
- const unitKey = currentUnitMap[defaultUnit];
364
- if (unitKey !== void 0) {
365
- return numberOnly * STANDARD_UNIT_MEASURES[unitKey];
366
- }
367
- }
368
- return void 0;
369
- }
370
- const isoMatch = ISO_FORMAT.exec(value);
371
- if (isoMatch) {
372
- const hours = Number.parseInt(isoMatch[1] ?? "0", 10);
373
- const minutes = Number.parseInt(isoMatch[2] ?? "0", 10);
374
- const seconds = Number.parseInt(isoMatch[3] ?? "0", 10);
375
- return hours * 36e5 + minutes * 6e4 + seconds * 1e3;
376
- }
377
- const colonMatch = COLON_FORMAT.exec(value);
378
- if (colonMatch) {
379
- let hours = 0;
380
- let minutes = 0;
381
- let seconds = 0;
382
- if (colonMatch[2] !== void 0) {
383
- hours = Number.parseInt(colonMatch[1] ?? "0", 10);
384
- minutes = Number.parseInt(colonMatch[2], 10);
385
- } else if (colonMatch[1] !== void 0) {
386
- minutes = Number.parseInt(colonMatch[1], 10);
387
- }
388
- seconds = Number.parseInt(colonMatch[3] ?? "0", 10);
389
- return hours * 36e5 + minutes * 6e4 + seconds * 1e3;
390
- }
391
- const currentUnitMapKeys = Object.keys(currentUnitMap);
392
- const regexKeys = currentUnitMapKeys.toSorted((a, b) => b.length - a.length).map((k) => k.replaceAll(ESCAPE_REGEX, String.raw`\$&`)).join("|");
393
- const durationRegex = new RegExp(String.raw`(-?\d*\.?\d+)\s*(${regexKeys})`, "gi");
394
- let totalMs = 0;
395
- let match;
396
- let unitsFound = false;
397
- let firstMatchIndex = -1;
398
- let lastMatchEndIndex = 0;
399
- durationRegex.lastIndex = 0;
400
- while ((match = durationRegex.exec(processedValue)) !== null) {
401
- if (!unitsFound) {
402
- firstMatchIndex = match.index;
403
- }
404
- unitsFound = true;
405
- const numberString = match[1];
406
- const unitString = match[2];
407
- if (!numberString || !unitString) {
408
- continue;
409
- }
410
- const trimmedNumberString = numberString.trim();
411
- const sign = trimmedNumberString.startsWith("-") ? -1 : 1;
412
- const absNumberString = trimmedNumberString.replace(/^[-+]/, "");
413
- const parsedNumber = Number.parseFloat(absNumberString);
414
- const unitKey = currentUnitMap[unitString.toLowerCase()];
415
- if (unitKey === void 0) {
416
- continue;
417
- }
418
- const unitValue = STANDARD_UNIT_MEASURES[unitKey];
419
- if (Number.isNaN(parsedNumber)) {
420
- return void 0;
421
- }
422
- totalMs += sign * parsedNumber * unitValue;
423
- lastMatchEndIndex = durationRegex.lastIndex;
424
- }
425
- const leadingText = processedValue.slice(0, firstMatchIndex).trim();
426
- const trailingText = processedValue.slice(lastMatchEndIndex).trim();
427
- if (unitsFound && (leadingText.length > 0 || trailingText.length > 0)) {
428
- return void 0;
429
- }
430
- if (!unitsFound) {
431
- return void 0;
432
- }
433
- return totalMs;
434
- };
435
-
436
- const toMilliseconds = (value) => {
437
- if (value === Number(value)) {
438
- return value;
439
- }
440
- if (!value) {
441
- return void 0;
442
- }
443
- const parsed = parseDuration(value);
444
- if (parsed === void 0) {
445
- return void 0;
446
- }
447
- return parsed;
448
- };
449
-
450
- class Locker extends LRUCache {
451
- /**
452
- * Creates a new Locker instance with configurable TTL and cache options.
453
- * @param options LRU cache configuration options
454
- */
455
- constructor(options) {
456
- super({
457
- ttl: 1e3,
458
- ttlAutopurge: true,
459
- ...options
460
- });
461
- }
462
- /**
463
- * Acquires a lock for the specified key.
464
- * Throws an error if the key is already locked.
465
- * @param key The key to lock
466
- * @returns The lock token (same as the key)
467
- * @throws Error if the key is already locked
468
- */
469
- lock(key) {
470
- const locked = this.get(key);
471
- if (locked) {
472
- throw new Error(`${key} is locked`);
473
- }
474
- this.set(key, key);
475
- return key;
476
- }
477
- /**
478
- * Releases the lock for the specified key.
479
- * @param key The key to unlock
480
- */
481
- unlock(key) {
482
- this.delete(key);
483
- }
484
- }
485
-
486
- const extractOriginalName = (meta) => {
487
- if (typeof meta.name === "string") {
488
- return meta.name;
489
- }
490
- if (typeof meta.title === "string") {
491
- return meta.title;
492
- }
493
- if (typeof meta.originalName === "string") {
494
- return meta.originalName;
495
- }
496
- if (typeof meta.filename === "string") {
497
- return meta.filename;
498
- }
499
- return void 0;
500
- };
501
- const deepMerge = (target, source) => {
502
- const result = { ...target };
503
- Object.keys(source).forEach((key) => {
504
- const sourceValue = source[key];
505
- if (sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
506
- const targetValue = result[key];
507
- const targetObject = targetValue && typeof targetValue === "object" && !Array.isArray(targetValue) ? targetValue : {};
508
- result[key] = deepMerge(targetObject, sourceValue);
509
- } else {
510
- result[key] = sourceValue;
511
- }
512
- });
513
- return result;
514
- };
515
- const updateMetadata = (file, metadata) => {
516
- const merged = deepMerge(file, metadata);
517
- Object.assign(file, merged);
518
- file.originalName = extractOriginalName(file.metadata) || file.originalName;
519
- };
520
-
521
- const defaults = {
522
- allowMIME: ["*/*"],
523
- filename: ({ id }) => id,
524
- maxMetadataSize: "8MB",
525
- maxUploadSize: "5TB",
526
- onComplete: () => {
527
- },
528
- onCreate: () => {
529
- },
530
- onDelete: () => {
531
- },
532
- onError: () => {
533
- },
534
- onUpdate: () => {
535
- },
536
- useRelativeLocation: false,
537
- validation: {}
538
- };
539
- const defaultCloudStorageFileNameValidation = (name) => {
540
- if (!name || name.length < 3 || name.length > 255 || isAbsolute(name)) {
541
- return false;
542
- }
543
- const upperCase = name.toUpperCase();
544
- return !(upperCase.includes("../") || name.includes("\0"));
545
- };
546
- const defaultFilesystemFileNameValidation = (name) => {
547
- if (!name || name.length < 3 || name.length > 255 || isAbsolute(name)) {
548
- return false;
549
- }
550
- const upperCase = name.toUpperCase();
551
- const filesystemInvalidChars = ['"', "*", ":", "<", ">", "?", "\\", "|", "../", "\0"];
552
- return !filesystemInvalidChars.some((char) => upperCase.includes(char));
553
- };
554
- class BaseStorage {
555
- /**
556
- * Hook called when a new file is created.
557
- * @param file The newly created file object.
558
- * @remarks This hook is called after file metadata is saved but before returning the file.
559
- * Can be used for side effects like logging, notifications, or custom processing.
560
- */
561
- onCreate;
562
- /**
563
- * Hook called when file metadata is updated.
564
- * @param file The updated file object.
565
- * @remarks This hook is called after metadata is updated and saved.
566
- * Can be used for side effects like logging or custom processing.
567
- */
568
- onUpdate;
569
- /**
570
- * Hook called when a file upload is completed.
571
- * @param file The completed file object.
572
- * @param response The response object that can be modified in place (headers, statusCode, body).
573
- * @param request Optional request object for additional context.
574
- * @remarks This hook is called when file status becomes "completed".
575
- * The response object can be modified directly to add headers or change the status code.
576
- */
577
- onComplete;
578
- /**
579
- * Hook called when a file is deleted.
580
- * @param file The deleted file object.
581
- * @remarks This hook is called after the file is deleted but before returning.
582
- * Can be used for side effects like cleanup or logging.
583
- */
584
- onDelete;
585
- /**
586
- * Hook called when an error occurs during storage operations.
587
- * @param error The HTTP error object that can be modified in place.
588
- * @remarks This hook allows customizing error responses by modifying the error object.
589
- * The error object can be modified to change headers, statusCode, or body properties.
590
- * Error formatting happens in handlers after this hook is called.
591
- */
592
- onError;
593
- isReady = true;
594
- errorResponses = {};
595
- cache;
596
- logger;
597
- metrics;
598
- genericConfig;
599
- maxMetadataSize;
600
- checksumTypes = [];
601
- maxUploadSize;
602
- expiration;
603
- locker;
604
- namingFunction;
605
- validation = new Validator();
606
- assetFolder = void 0;
607
- /**
608
- * Limits the number of concurrent upload requests
609
- */
610
- concurrency;
611
- constructor(config) {
612
- const options = { ...defaults, ...config };
613
- this.onCreate = options.onCreate;
614
- this.onUpdate = options.onUpdate;
615
- this.onComplete = options.onComplete;
616
- this.onDelete = options.onDelete;
617
- this.onError = options.onError;
618
- this.namingFunction = options.filename;
619
- this.maxUploadSize = typeof options.maxUploadSize === "string" ? parseBytes(options.maxUploadSize) : options.maxUploadSize;
620
- this.maxMetadataSize = typeof options.maxMetadataSize === "string" ? parseBytes(options.maxMetadataSize) : options.maxMetadataSize;
621
- this.expiration = options.expiration;
622
- this.genericConfig = options;
623
- if (options.assetFolder !== void 0) {
624
- this.assetFolder = normalize(options.assetFolder);
625
- }
626
- this.locker = new Locker({
627
- max: 1e3,
628
- ttl: 3e4,
629
- ttlAutopurge: true
630
- });
631
- this.cache = options.cache ?? new NoOpCache();
632
- this.logger = options.logger;
633
- this.metrics = options.metrics ?? new NoOpMetrics();
634
- this.logger?.debug(`${this.constructor.name} config: ${inspect({ ...config, logger: this.logger.constructor })}`);
635
- const purgeInterval = toMilliseconds(options.expiration?.purgeInterval);
636
- if (purgeInterval) {
637
- this.startAutoPurge(purgeInterval);
638
- }
639
- const size = {
640
- isValid(file) {
641
- if (file.size === void 0) {
642
- return true;
643
- }
644
- const fileSizeValue = file.size;
645
- if (fileSizeValue === void 0 || fileSizeValue === null) {
646
- return false;
647
- }
648
- const fileSize = typeof fileSizeValue === "number" ? fileSizeValue : Number(fileSizeValue);
649
- if (Number.isNaN(fileSize) || fileSize < 0) {
650
- return false;
651
- }
652
- const maxSize = typeof this.value === "number" ? this.value : Number(this.value);
653
- return !Number.isNaN(maxSize) && fileSize <= maxSize;
654
- },
655
- response: ErrorMap.RequestEntityTooLarge,
656
- value: this.maxUploadSize
657
- };
658
- const mime = {
659
- isValid(file) {
660
- return !!typeis.is(file.contentType, this.value);
661
- },
662
- // @TODO: add better error handling for mime types
663
- response: ErrorMap.UnsupportedMediaType,
664
- value: options.allowMIME
665
- };
666
- const fileNameValidation = options.fileNameValidation ?? defaultCloudStorageFileNameValidation;
667
- const filename = {
668
- isValid(file) {
669
- return fileNameValidation(file.name);
670
- },
671
- response: ErrorMap.InvalidFileName
672
- };
673
- this.validation.add({ filename, mime, size });
674
- this.validation.add({ ...options.validation });
675
- }
676
- get tusExtension() {
677
- const extensions = ["creation", "creation-with-upload", "termination", "checksum", "creation-defer-length", "concatenation"];
678
- if (this.expiration) {
679
- extensions.push("expiration");
680
- }
681
- return extensions;
682
- }
683
- /**
684
- * Validates a file against configured validation rules.
685
- * @param file File object to validate.
686
- * @returns Promise resolving to undefined if file is valid, throws ValidationError otherwise.
687
- * @throws {ValidationError} If validation fails
688
- */
689
- async validate(file) {
690
- await this.validation.verify(file);
691
- }
692
- /**
693
- * Checks if a file exists by querying its metadata.
694
- * @param query File query containing the file ID to check.
695
- * @param query.id File ID to check.
696
- * @returns Promise resolving to true if file exists, false otherwise.
697
- * @remarks This method does not throw errors - it returns false if the file is not found.
698
- */
699
- async exists(query) {
700
- return this.instrumentOperation("exists", async () => {
701
- try {
702
- await this.getMeta(query.id);
703
- return true;
704
- } catch {
705
- return false;
706
- }
707
- });
708
- }
709
- /**
710
- * Normalizes errors with storage-specific context.
711
- * @param error The error to normalize.
712
- * @returns Normalized HTTP error with storage class context added to the message.
713
- * @remarks Errors are enhanced with the storage class name for better debugging.
714
- */
715
- normalizeError(error) {
716
- const baseError = {
717
- code: error.name,
718
- message: error.message,
719
- name: error.name,
720
- statusCode: 500
721
- };
722
- return {
723
- ...baseError,
724
- message: `[${this.constructor.name}] ${baseError.message}`
725
- };
726
- }
727
- /**
728
- * Gets the storage configuration.
729
- * @returns The current storage configuration options.
730
- */
731
- get config() {
732
- return this.genericConfig;
733
- }
734
- /**
735
- * Saves upload metadata to the metadata storage.
736
- * @param file File object containing metadata to save.
737
- * @returns Promise resolving to the saved file object.
738
- * @remarks Updates timestamps and caches the file metadata.
739
- */
740
- async saveMeta(file) {
741
- this.updateTimestamps(file);
742
- this.cache.set(file.id, file);
743
- return this.meta.save(file.id, file);
744
- }
745
- /**
746
- * Deletes upload metadata from the metadata storage.
747
- * @param id File ID whose metadata should be deleted.
748
- * @returns Promise resolving when metadata is deleted.
749
- * @remarks Also removes the file from the cache.
750
- */
751
- async deleteMeta(id) {
752
- this.cache.delete(id);
753
- return this.meta.delete(id);
754
- }
755
- /**
756
- * Retrieves upload metadata by file ID.
757
- * @param id File ID to retrieve metadata for.
758
- * @returns Promise resolving to the file metadata object.
759
- * @throws {UploadError} If the file metadata cannot be found (ERRORS.FILE_NOT_FOUND).
760
- * @remarks Caches the retrieved metadata for faster subsequent access.
761
- */
762
- async getMeta(id) {
763
- try {
764
- const file = await this.meta.get(id);
765
- this.cache.set(file.id, file);
766
- return { ...file };
767
- } catch (error) {
768
- const httpError = this.normalizeError(error instanceof Error ? error : new Error(String(error)));
769
- await this.onError(httpError);
770
- return throwErrorCode(ERRORS.FILE_NOT_FOUND);
771
- }
772
- }
773
- /**
774
- * Checks if a file has expired and deletes it if so.
775
- * @param file File object to check for expiration.
776
- * @returns Promise resolving to the file object if not expired.
777
- * @throws {UploadError} If the file has expired (ERRORS.GONE).
778
- * @remarks If the file is expired, it is automatically deleted and the metadata is removed.
779
- */
780
- async checkIfExpired(file) {
781
- if (isExpired(file)) {
782
- this.delete(file).catch(() => void 0);
783
- this.deleteMeta(file.id).catch(() => void 0);
784
- return throwErrorCode(ERRORS.GONE);
785
- }
786
- return file;
787
- }
788
- /**
789
- * Searches for and purges expired uploads.
790
- * @param maxAge Maximum age of files to keep (files older than this will be purged).
791
- * Can be a number (milliseconds) or string (e.g., "1h", "30m", "7d").
792
- * If not provided, uses the expiration.maxAge from configuration.
793
- * @returns Promise resolving to a list of purged files.
794
- * @remarks
795
- * Errors during individual file deletions are logged but do not stop the purge process.
796
- * Files with corrupted metadata are skipped with a warning.
797
- * Uses rolling expiration if configured (based on modifiedAt) or fixed expiration (based on createdAt).
798
- */
799
- async purge(maxAge) {
800
- return this.instrumentOperation("purge", async () => {
801
- const maxAgeMs = toMilliseconds(maxAge || this.expiration?.maxAge);
802
- const purged = { items: [], maxAgeMs };
803
- if (maxAgeMs) {
804
- const before = Date.now() - maxAgeMs;
805
- const list = await this.list();
806
- const expired = list.filter(
807
- (item) => Number(new Date(this.expiration?.rolling ? item.modifiedAt || item.createdAt : item.createdAt)) < before
808
- );
809
- for await (const { id, ...rest } of expired) {
810
- try {
811
- const deleted = await this.delete({ id });
812
- purged.items.push({ ...deleted, ...rest });
813
- } catch (error) {
814
- this.logger?.warn(`Failed to delete file ${id} during purge: ${error instanceof Error ? error.message : String(error)}`);
815
- }
816
- }
817
- if (purged.items.length > 0) {
818
- this.logger?.info(`Purge: removed ${purged.items.length} uploads`);
819
- this.metrics.gauge("storage.operations.purge.items_count", purged.items.length, {
820
- storage: this.constructor.name.toLowerCase().replace("storage", "")
821
- });
822
- }
823
- }
824
- return purged;
825
- });
826
- }
827
- /**
828
- * Gets an uploaded file as a readable stream for efficient large file handling.
829
- * @param query File query containing the file ID to stream.
830
- * @param query.id File ID to stream.
831
- * @returns Promise resolving to an object containing the stream, headers, and size.
832
- * @throws {UploadError} If the file cannot be found (ERRORS.FILE_NOT_FOUND) or has expired (ERRORS.GONE).
833
- * @remarks
834
- * Default implementation falls back to get() and creates a stream from the buffer.
835
- * Storage implementations should override this for better streaming performance.
836
- * Headers include Content-Type, Content-Length, ETag, and Last-Modified.
837
- */
838
- async getStream({ id }) {
839
- return this.instrumentOperation("getStream", async () => {
840
- const file = await this.get({ id });
841
- const stream = Readable.from(file.content);
842
- return {
843
- headers: {
844
- "Content-Length": String(file.size),
845
- "Content-Type": file.contentType,
846
- ...file.ETag && { ETag: file.ETag },
847
- ...file.modifiedAt && { "Last-Modified": file.modifiedAt.toString() }
848
- },
849
- size: typeof file.size === "number" ? file.size : void 0,
850
- stream
851
- };
852
- });
853
- }
854
- /**
855
- * Retrieves a list of uploaded files.
856
- * @param _limit Maximum number of files to return (default: 1000).
857
- * @returns Promise resolving to an array of file metadata objects.
858
- * @throws {Error} If not implemented by the storage backend.
859
- * @remarks Storage implementations must override this method.
860
- */
861
- async list(_limit = 1e3) {
862
- return this.instrumentOperation("list", async () => {
863
- throw new Error("Not implemented");
864
- });
865
- }
866
- /**
867
- * Updates file metadata with user-provided key-value pairs.
868
- * @param query File query containing the file ID to update.
869
- * @param query.id File ID to update.
870
- * @param metadata Partial file object containing fields to update.
871
- * @returns Promise resolving to the updated file object.
872
- * @throws {UploadError} If the file cannot be found (ERRORS.FILE_NOT_FOUND).
873
- * @remarks
874
- * Supports TTL (time-to-live) option: if metadata contains a 'ttl' field,
875
- * it will be converted to an 'expiredAt' timestamp.
876
- * TTL can be a number (milliseconds) or string (e.g., "1h", "30m", "7d").
877
- */
878
- async update({ id }, metadata) {
879
- return this.instrumentOperation("update", async () => {
880
- const file = await this.getMeta(id);
881
- const processedMetadata = { ...metadata };
882
- if ("ttl" in processedMetadata && processedMetadata.ttl !== void 0) {
883
- const ttlValue = processedMetadata.ttl;
884
- const ttlMs = typeof ttlValue === "string" ? toMilliseconds(ttlValue) : ttlValue;
885
- if (ttlMs !== void 0) {
886
- processedMetadata.expiredAt = Date.now() + ttlMs;
887
- }
888
- delete processedMetadata.ttl;
889
- }
890
- updateMetadata(file, processedMetadata);
891
- await this.saveMeta(file);
892
- const updatedFile = { ...file, status: "updated" };
893
- await this.onUpdate(updatedFile);
894
- return updatedFile;
895
- });
896
- }
897
- /**
898
- * Deletes multiple files in a single batch operation.
899
- * @param ids Array of file IDs to delete.
900
- * @returns Promise resolving to batch operation response with successful and failed deletions.
901
- * @remarks
902
- * Processes all deletions in parallel using Promise.allSettled.
903
- * Individual failures do not stop the batch operation.
904
- * Each deletion is wrapped in error handling to capture failures.
905
- * Metrics are recorded for the batch operation and individual failures.
906
- * Returns both successful and failed operations with detailed error information.
907
- */
908
- async deleteBatch(ids) {
909
- const startTime = Date.now();
910
- const storageType = this.constructor.name.toLowerCase().replace("storage", "");
911
- this.metrics.increment("storage.operations.batch.delete.count", 1, {
912
- batch_size: ids.length,
913
- storage: storageType
914
- });
915
- const successful = [];
916
- const failed = [];
917
- const deletePromises = ids.map(async (id) => {
918
- try {
919
- const file = await this.delete({ id });
920
- return { file, id, success: true };
921
- } catch (error) {
922
- const errorMessage = error instanceof Error ? error.message : "Delete failed";
923
- this.metrics.increment("storage.operations.delete.error.count", 1, {
924
- error: errorMessage,
925
- storage: storageType
926
- });
927
- return { error: errorMessage, id, success: false };
928
- }
929
- });
930
- const results = await Promise.allSettled(deletePromises);
931
- for (const result of results) {
932
- if (result.status === "fulfilled") {
933
- if (result.value.success) {
934
- successful.push(result.value.file);
935
- } else {
936
- failed.push({ error: result.value.error, id: result.value.id });
937
- }
938
- } else {
939
- failed.push({ error: result.reason?.message || "Delete failed", id: "" });
940
- }
941
- }
942
- const duration = Date.now() - startTime;
943
- this.metrics.timing("storage.operations.batch.delete.duration", duration, {
944
- batch_size: ids.length,
945
- storage: storageType
946
- });
947
- this.metrics.gauge("storage.operations.batch.delete.success_count", successful.length, {
948
- storage: storageType
949
- });
950
- this.metrics.gauge("storage.operations.batch.delete.failed_count", failed.length, {
951
- storage: storageType
952
- });
953
- return {
954
- failed,
955
- failedCount: failed.length,
956
- successful,
957
- successfulCount: successful.length
958
- };
959
- }
960
- /**
961
- * Copies multiple files in a single batch operation.
962
- * @param operations Array of copy operations, each containing:
963
- * source: Source file ID.
964
- * destination: Destination file ID or path.
965
- * options: Optional copy options including storage class.
966
- * @returns Promise resolving to batch operation response with successful and failed copies.
967
- * @remarks
968
- * Processes all copies in parallel using Promise.allSettled.
969
- * Individual failures do not stop the batch operation.
970
- * Each copy operation is wrapped in error handling to capture failures.
971
- * Metrics are recorded for the batch operation and individual failures.
972
- * Returns both successful and failed operations with detailed error information.
973
- */
974
- async copyBatch(operations) {
975
- const startTime = Date.now();
976
- const storageType = this.constructor.name.toLowerCase().replace("storage", "");
977
- this.metrics.increment("storage.operations.batch.copy.count", 1, {
978
- batch_size: operations.length,
979
- storage: storageType
980
- });
981
- const successful = [];
982
- const failed = [];
983
- const copyPromises = operations.map(async ({ destination, options, source }) => {
984
- try {
985
- const copiedFile = await this.copy(source, destination, options);
986
- return { file: copiedFile, id: destination, success: true };
987
- } catch (error) {
988
- const errorMessage = error instanceof Error ? error.message : "Copy failed";
989
- this.metrics.increment("storage.operations.copy.error.count", 1, {
990
- error: errorMessage,
991
- storage: storageType
992
- });
993
- return { error: errorMessage, id: destination, success: false };
994
- }
995
- });
996
- const results = await Promise.allSettled(copyPromises);
997
- for (const result of results) {
998
- if (result.status === "fulfilled") {
999
- if (result.value.success && result.value.file) {
1000
- successful.push(result.value.file);
1001
- } else {
1002
- failed.push({ error: result.value.error || "Copy failed", id: result.value.id });
1003
- }
1004
- } else {
1005
- failed.push({ error: result.reason?.message || "Copy failed", id: "" });
1006
- }
1007
- }
1008
- const duration = Date.now() - startTime;
1009
- this.metrics.timing("storage.operations.batch.copy.duration", duration, {
1010
- batch_size: operations.length,
1011
- storage: storageType
1012
- });
1013
- this.metrics.gauge("storage.operations.batch.copy.success_count", successful.length, {
1014
- storage: storageType
1015
- });
1016
- this.metrics.gauge("storage.operations.batch.copy.failed_count", failed.length, {
1017
- storage: storageType
1018
- });
1019
- return {
1020
- failed,
1021
- failedCount: failed.length,
1022
- successful,
1023
- successfulCount: successful.length
1024
- };
1025
- }
1026
- /**
1027
- * Moves multiple files in a single batch operation.
1028
- * @param operations Array of move operations, each containing:
1029
- * source: Source file ID.
1030
- * destination: Destination file ID or path.
1031
- * @returns Promise resolving to batch operation response with successful and failed moves.
1032
- * @remarks
1033
- * Processes all moves in parallel using Promise.allSettled.
1034
- * Individual failures do not stop the batch operation.
1035
- * Each move operation is wrapped in error handling to capture failures.
1036
- * Metrics are recorded for the batch operation and individual failures.
1037
- * Returns both successful and failed operations with detailed error information.
1038
- */
1039
- async moveBatch(operations) {
1040
- const startTime = Date.now();
1041
- const storageType = this.constructor.name.toLowerCase().replace("storage", "");
1042
- this.metrics.increment("storage.operations.batch.move.count", 1, {
1043
- batch_size: operations.length,
1044
- storage: storageType
1045
- });
1046
- const successful = [];
1047
- const failed = [];
1048
- const movePromises = operations.map(async ({ destination, source }) => {
1049
- try {
1050
- const movedFile = await this.move(source, destination);
1051
- return { file: movedFile, id: destination, success: true };
1052
- } catch (error) {
1053
- const errorMessage = error instanceof Error ? error.message : "Move failed";
1054
- this.metrics.increment("storage.operations.move.error.count", 1, {
1055
- error: errorMessage,
1056
- storage: storageType
1057
- });
1058
- return { error: errorMessage, id: destination, success: false };
1059
- }
1060
- });
1061
- const results = await Promise.allSettled(movePromises);
1062
- for (const result of results) {
1063
- if (result.status === "fulfilled") {
1064
- if (result.value.success && result.value.file) {
1065
- successful.push(result.value.file);
1066
- } else {
1067
- failed.push({ error: result.value.error || "Move failed", id: result.value.id });
1068
- }
1069
- } else {
1070
- failed.push({ error: result.reason?.message || "Move failed", id: result.reason?.id || "" });
1071
- }
1072
- }
1073
- const duration = Date.now() - startTime;
1074
- this.metrics.timing("storage.operations.batch.move.duration", duration, {
1075
- batch_size: operations.length,
1076
- storage: storageType
1077
- });
1078
- this.metrics.gauge("storage.operations.batch.move.success_count", successful.length, {
1079
- storage: storageType
1080
- });
1081
- this.metrics.gauge("storage.operations.batch.move.failed_count", failed.length, {
1082
- storage: storageType
1083
- });
1084
- return {
1085
- failed,
1086
- failedCount: failed.length,
1087
- successful,
1088
- successfulCount: successful.length
1089
- };
1090
- }
1091
- /**
1092
- * Prevent upload from being accessed by multiple requests
1093
- */
1094
- async lock(key) {
1095
- const activeUploads = [...this.locker.keys()];
1096
- if (activeUploads.includes(key)) {
1097
- return throwErrorCode(ERRORS.FILE_LOCKED);
1098
- }
1099
- if (this.config.concurrency && typeof this.config.concurrency === "number" && this.config.concurrency < activeUploads.length) {
1100
- return throwErrorCode(ERRORS.STORAGE_BUSY);
1101
- }
1102
- this.locker.set(key, key);
1103
- return key;
1104
- }
1105
- async unlock(key) {
1106
- this.locker.unlock(key);
1107
- }
1108
- isUnsupportedChecksum(algorithm = "") {
1109
- return !!algorithm && !this.checksumTypes.includes(algorithm);
1110
- }
1111
- startAutoPurge(purgeInterval) {
1112
- if (purgeInterval >= 2147483647) {
1113
- throw new Error("“purgeInterval” must be less than 2147483647 ms");
1114
- }
1115
- setInterval(() => {
1116
- this.purge().catch((error) => this.logger?.error(error));
1117
- }, purgeInterval);
1118
- }
1119
- updateTimestamps(file) {
1120
- file.createdAt ??= (/* @__PURE__ */ new Date()).toISOString();
1121
- const maxAgeMs = toMilliseconds(this.expiration?.maxAge);
1122
- if (maxAgeMs && !file.expiredAt) {
1123
- file.expiredAt = this.expiration?.rolling ? Date.now() + maxAgeMs : +new Date(file.createdAt) + maxAgeMs;
1124
- }
1125
- return file;
1126
- }
1127
- /**
1128
- * Instruments a storage operation with metrics and error tracking.
1129
- * @param operation Operation name (e.g., "create", "delete", "copy").
1130
- * @param function_ The operation function to execute.
1131
- * @param attributes Additional attributes to include in metrics.
1132
- * @returns Promise resolving to the operation result.
1133
- * @throws Re-throws any errors from the operation function.
1134
- * @remarks
1135
- * Records operation count, duration, and error metrics.
1136
- * Tracks file sizes for operations returning file objects.
1137
- * Error metrics include error messages for debugging.
1138
- * All public methods should use this wrapper for consistent instrumentation.
1139
- */
1140
- async instrumentOperation(operation, function_, attributes) {
1141
- const startTime = Date.now();
1142
- const storageType = this.constructor.name.toLowerCase().replace("storage", "");
1143
- const baseAttributes = {
1144
- storage: storageType,
1145
- ...attributes
1146
- };
1147
- try {
1148
- this.metrics.increment(`storage.operations.${operation}.count`, 1, baseAttributes);
1149
- const result = await function_();
1150
- const duration = Date.now() - startTime;
1151
- this.metrics.timing(`storage.operations.${operation}.duration`, duration, baseAttributes);
1152
- if (result && typeof result === "object" && "size" in result && typeof result.size === "number") {
1153
- this.metrics.gauge("storage.files.size", result.size, {
1154
- ...baseAttributes,
1155
- operation
1156
- });
1157
- }
1158
- return result;
1159
- } catch (error) {
1160
- const duration = Date.now() - startTime;
1161
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
1162
- this.metrics.timing(`storage.operations.${operation}.duration`, duration, {
1163
- ...baseAttributes,
1164
- error: "true"
1165
- });
1166
- this.metrics.increment(`storage.operations.${operation}.error.count`, 1, {
1167
- ...baseAttributes,
1168
- error: errorMessage
1169
- });
1170
- throw error;
1171
- }
1172
- }
1173
- }
1174
-
1175
- export { BaseStorage as B, defaultFilesystemFileNameValidation as a, parseBytes as b, defaultCloudStorageFileNameValidation as d, parseDuration as p, toMilliseconds as t, updateMetadata as u };