@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
@@ -0,0 +1,1163 @@
1
+ import { Transform, Readable } from 'node:stream';
2
+ import { BinaryToTextEncoding, Hash } from 'node:crypto';
3
+ import { IncomingMessage } from 'node:http';
4
+ import { LRUCache } from 'lru-cache';
5
+ /**
6
+ * Simple cache interface that any cache implementation can follow
7
+ */
8
+ interface Cache<K = string, V = unknown> {
9
+ /** Clear all cache entries */
10
+ clear: () => void | Promise<void>;
11
+ /** Delete a value from cache */
12
+ delete: (key: K) => boolean | Promise<boolean>;
13
+ /** Get a value from cache */
14
+ get: (key: K) => V | undefined | Promise<V | undefined>;
15
+ /** Check if a key exists in cache */
16
+ has: (key: K) => boolean | Promise<boolean>;
17
+ /**
18
+ * Optional. Iterate over the cache's current keys. Required for prefix-based
19
+ * eviction (`clearCache(fileId)` in transformers) — when absent, per-file
20
+ * clear falls back to a full `clear()`. `LRUCache` from `lru-cache`
21
+ * satisfies this out of the box.
22
+ */
23
+ keys?: () => Iterable<K>;
24
+ /** Set a value in cache */
25
+ set: (key: K, value: V, options?: CacheOptions) => boolean | Promise<boolean>;
26
+ }
27
+ /**
28
+ * Options for cache operations
29
+ */
30
+ interface CacheOptions {
31
+ /** TTL in milliseconds */
32
+ ttl?: number;
33
+ }
34
+ /**
35
+ * Transform that computes a rolling checksum for a stream while passing
36
+ * data through unchanged.
37
+ */
38
+ interface RangeChecksum extends Transform {
39
+ /** Return the current digest in the selected encoding. */
40
+ digest: (encoding: BinaryToTextEncoding) => string;
41
+ hash: Hash;
42
+ path: string;
43
+ reset: () => void;
44
+ }
45
+ /**
46
+ * LRU-backed map of rolling hashers keyed by file path. Used to compute
47
+ * hex/base64 digests and resume hashing from an offset.
48
+ */
49
+ interface RangeHasher extends LRUCache<string, Hash> {
50
+ algorithm: "md5" | "sha1";
51
+ base64: (path: string) => string;
52
+ digester: (path: string) => RangeChecksum;
53
+ hex: (path: string) => string;
54
+ init: (path: string, start: number) => Promise<Hash>;
55
+ updateFromFs: (path: string, start: number, initial?: Hash) => Promise<Hash>;
56
+ }
57
+ /**
58
+ * Normalized HTTP error payload returned by handlers and storage backends.
59
+ */
60
+ interface HttpErrorBody {
61
+ code: string;
62
+ detail?: Record<string, unknown> | string;
63
+ message: string;
64
+ name?: string;
65
+ retryable?: boolean;
66
+ UploadErrorCode?: string;
67
+ }
68
+ /**
69
+ * Rich HTTP error including status code and optional headers/body.
70
+ */
71
+ interface HttpError<T = HttpErrorBody> extends UploadResponse<T> {
72
+ statusCode: number;
73
+ }
74
+ /**
75
+ * Node.js IncomingMessage with an optional parsed body attached.
76
+ */
77
+ interface IncomingMessageWithBody<T = unknown> extends IncomingMessage {
78
+ _body?: boolean;
79
+ body?: T;
80
+ }
81
+ type Header = string[] | number | string;
82
+ type Headers = Record<string, Header>;
83
+ type ResponseBody = Record<string, unknown> | string | Buffer | Uint8Array;
84
+ type ResponseBodyType = "json" | "text";
85
+ /**
86
+ * Tuple form for quick response definitions: [status, body, headers].
87
+ */
88
+ type ResponseTuple<T = ResponseBody> = [statusCode: number, body?: T, headers?: Headers];
89
+ /**
90
+ * Structured response used across handlers and storage operations.
91
+ */
92
+ interface UploadResponse<T = ResponseBody> extends Record<string, unknown> {
93
+ body?: T;
94
+ headers?: Headers;
95
+ statusCode?: number;
96
+ }
97
+ /**
98
+ * Declarative validator configuration for a single rule.
99
+ */
100
+ interface ValidatorConfig<T> {
101
+ isValid?: (t: T) => Promise<boolean> | boolean;
102
+ response?: HttpError | ResponseTuple;
103
+ value?: unknown;
104
+ }
105
+ /** Map of rule-name -> validator configuration. */
106
+ type Validation<T> = Record<string, ValidatorConfig<T>>;
107
+ /** Narrowed error response shape for validation failures. */
108
+ interface ValidationError extends HttpError {
109
+ code: string;
110
+ }
111
+ /**
112
+ * Metrics interface for observability.
113
+ * Provides counters, timers, and gauges for tracking storage operations.
114
+ */
115
+ interface Metrics {
116
+ /**
117
+ * Set a gauge metric value.
118
+ * @param name Metric name (e.g., "storage.files.size")
119
+ * @param value Gauge value
120
+ * @param attributes Optional attributes/labels
121
+ */
122
+ gauge: (name: string, value: number, attributes?: Record<string, string | number>) => void;
123
+ /**
124
+ * Increment a counter metric.
125
+ * @param name Metric name (e.g., "storage.operations.create.count")
126
+ * @param value Increment value (default: 1)
127
+ * @param attributes Optional attributes/labels (e.g., { storage: "s3", operation: "create" })
128
+ */
129
+ increment: (name: string, value?: number, attributes?: Record<string, string | number>) => void;
130
+ /**
131
+ * Record a duration/timing metric in milliseconds.
132
+ * @param name Metric name (e.g., "storage.operations.write.duration")
133
+ * @param duration Duration in milliseconds
134
+ * @param attributes Optional attributes/labels
135
+ */
136
+ timing: (name: string, duration: number, attributes?: Record<string, string | number>) => void;
137
+ }
138
+ /**
139
+ * Canonical error codes used across handlers and storage adapters.
140
+ * These codes map to standardized HTTP status codes and error messages.
141
+ */
142
+ declare enum ERRORS {
143
+ BAD_REQUEST = "BadRequest",
144
+ CHECKSUM_MISMATCH = "ChecksumMismatch",
145
+ FILE_CONFLICT = "FileConflict",
146
+ FILE_ERROR = "FileError",
147
+ FILE_LOCKED = "FileLocked",
148
+ FILE_NOT_ALLOWED = "FileNotAllowed",
149
+ FILE_NOT_FOUND = "FileNotFound",
150
+ FORBIDDEN = "Forbidden",
151
+ GONE = "Gone",
152
+ INVALID_FILE_NAME = "InvalidFileName",
153
+ INVALID_FILE_SIZE = "InvalidFileSize",
154
+ INVALID_RANGE = "InvalidRange",
155
+ INVALID_TYPE = "Invalidtype",
156
+ METHOD_NOT_ALLOWED = "MethodNotAllowed",
157
+ READ_ONLY = "ReadOnly",
158
+ REQUEST_ABORTED = "RequestAborted",
159
+ REQUEST_ENTITY_TOO_LARGE = "RequestEntityTooLarge",
160
+ STORAGE_BUSY = "StorageBusy",
161
+ STORAGE_ERROR = "StorageError",
162
+ TOO_MANY_REQUESTS = "TooManyRequests",
163
+ UNKNOWN_ERROR = "UnknownError",
164
+ UNPROCESSABLE_ENTITY = "UnprocessableEntity",
165
+ UNSUPPORTED_CHECKSUM_ALGORITHM = "UnsupportedChecksumAlgorithm",
166
+ UNSUPPORTED_MEDIA_TYPE = "UnsupportedMediaType"
167
+ }
168
+ /**
169
+ * Type mapping of error codes to standardized HTTP error responses.
170
+ * @template T - The error code type (defaults to string)
171
+ */
172
+ type ErrorResponses<T extends string = string> = { [K in T]: HttpError; };
173
+ /**
174
+ * Mapping of error codes to HttpError response objects.
175
+ * @returns Map of error codes to standardized HTTP error responses
176
+ */
177
+ declare const ErrorMap: ErrorResponses<ERRORS>;
178
+ /**
179
+ * Error subclass carrying a stable error code and optional detail.
180
+ * Provides structured error information for upload operations.
181
+ */
182
+ declare class UploadError extends Error {
183
+ override name: string;
184
+ /** The standardized error code from the ERRORS enum */
185
+ UploadErrorCode: ERRORS;
186
+ /** Optional additional error details */
187
+ detail?: unknown;
188
+ /**
189
+ * Creates a new UploadError instance.
190
+ * @param code Standardized error code (defaults to UNKNOWN_ERROR)
191
+ * @param message Human-readable error message (defaults to the code)
192
+ * @param detail Optional additional error details
193
+ */
194
+ constructor(code?: ERRORS, message?: string, detail?: unknown);
195
+ }
196
+ /**
197
+ * Type guard to check if an error is an UploadError instance.
198
+ * @param error Error to check
199
+ * @returns True if the error is an UploadError with a valid error code
200
+ */
201
+ declare const isUploadError: (error: unknown) => error is UploadError;
202
+ /**
203
+ * Best-effort extraction of an HTTP status from a native SDK error.
204
+ *
205
+ * Covers the shapes used by the consumer-provider SDKs:
206
+ * - Dropbox `DropboxResponseError` → `error.status`
207
+ * - Box `BoxAPIError` / Microsoft Graph errors → `error.statusCode`
208
+ * - googleapis errors → `error.code` (numeric) or `error.response.status`
209
+ * - Supabase / fetch-style errors → `error.status` or `error.response.status`
210
+ */
211
+ declare const extractHttpStatus: (error: unknown) => number | undefined;
212
+ /**
213
+ * Map an HTTP status code to the closest canonical ERRORS value.
214
+ *
215
+ * Returns STORAGE_ERROR for unknown/5xx and BAD_REQUEST for unmapped 4xx.
216
+ * 401 (unauthenticated) collapses to FORBIDDEN because the ERRORS enum has
217
+ * no dedicated UNAUTHORIZED value; callers needing to distinguish the two
218
+ * should inspect the native error on `UploadError.detail`.
219
+ */
220
+ declare const mapStatusToErrorCode: (status?: number) => ERRORS;
221
+ /**
222
+ * Normalize a native storage-SDK error into an `UploadError`.
223
+ *
224
+ * The native error is preserved on `.detail` so advanced callers can drop down
225
+ * to provider-specific shapes when needed. Already-wrapped `UploadError`
226
+ * instances pass through unchanged.
227
+ * @example
228
+ * ```ts
229
+ * try {
230
+ * await client.filesCopyV2({ from_path, to_path });
231
+ * } catch (error) {
232
+ * throw wrapStorageError(error, { adapter: "Dropbox", operation: "copy" });
233
+ * }
234
+ * ```
235
+ */
236
+ declare const wrapStorageError: (error: unknown, options: {
237
+ adapter: string;
238
+ code?: ERRORS;
239
+ message?: string;
240
+ operation: string;
241
+ status?: number;
242
+ }) => UploadError;
243
+ /**
244
+ * Convenience function to throw an UploadError from a string error code.
245
+ * Looks up the appropriate error message from ErrorMap.
246
+ * @param UploadErrorCode String error code to convert to UploadError
247
+ * @param detail Optional additional error details
248
+ * @throws UploadError with the specified code and message
249
+ */
250
+ declare const throwErrorCode: (UploadErrorCode: ERRORS | string, detail?: string) => never;
251
+ /**
252
+ * A simple lock map keyed by strings, backed by LRUCache. Locks
253
+ * automatically expire according to the configured TTL preventing deadlocks.
254
+ *
255
+ * Each successful `lock()` returns a unique token; the corresponding `unlock(key, token)`
256
+ * call only releases the lock when the token matches the current holder. This prevents a
257
+ * stale lock owner (e.g. one whose entry TTL'd out and was re-acquired by another caller)
258
+ * from releasing another caller's lock by accident.
259
+ */
260
+ declare class Locker<K extends string = string> extends LRUCache<K, string, number> {
261
+ constructor(options?: LRUCache.Options<K, string, number>);
262
+ /**
263
+ * Acquires a lock for the specified key.
264
+ * @returns A unique token identifying the lock holder.
265
+ * @throws Error if the key is already locked.
266
+ */
267
+ lock(key: K): string;
268
+ /**
269
+ * Releases the lock for the specified key, but only if the token matches the current holder.
270
+ * Silently no-ops when the lock has expired or is owned by someone else — releasing somebody
271
+ * else's lock is worse than leaving a stale entry to TTL out on its own.
272
+ * @returns true if the lock was released, false if it was already gone or owned by another caller.
273
+ */
274
+ unlock(key: K, token: string): boolean;
275
+ }
276
+ /**
277
+ * Retry configuration options for storage operations
278
+ */
279
+ interface RetryConfig {
280
+ /**
281
+ * Multiplier for exponential backoff (e.g., 2 means delays double each retry)
282
+ * @default 2
283
+ */
284
+ backoffMultiplier?: number;
285
+ /**
286
+ * Custom function to calculate delay for a specific retry attempt
287
+ * @param attempt The current retry attempt (0-indexed)
288
+ * @param error The error that occurred
289
+ * @returns Delay in milliseconds, or undefined to use default exponential backoff
290
+ */
291
+ calculateDelay?: (attempt: number, error: unknown) => number | undefined;
292
+ /**
293
+ * Initial delay in milliseconds before first retry
294
+ * @default 1000
295
+ */
296
+ initialDelay?: number;
297
+ /**
298
+ * Maximum delay in milliseconds between retries
299
+ * @default 30000
300
+ */
301
+ maxDelay?: number;
302
+ /**
303
+ * Maximum number of retry attempts
304
+ * @default 3
305
+ */
306
+ maxRetries?: number;
307
+ /**
308
+ * Fire-and-forget hook invoked **before** each retry attempt's backoff sleep.
309
+ * `attempt` is 1-based (1 = first retry, i.e. after the initial call failed).
310
+ * Exceptions thrown by this callback are swallowed so an observability hook
311
+ * can never fail the underlying operation.
312
+ */
313
+ onRetry?: (attempt: number, error: unknown) => void;
314
+ /**
315
+ * HTTP status codes that should trigger a retry
316
+ * @default [408, 429, 500, 502, 503, 504]
317
+ */
318
+ retryableStatusCodes?: number[];
319
+ /**
320
+ * Custom function to determine if an error should be retried
321
+ * @param error The error that occurred
322
+ * @returns true if the error should be retried, false otherwise
323
+ */
324
+ shouldRetry?: (error: unknown) => boolean;
325
+ }
326
+ /**
327
+ * Determines if an error is retryable based on common patterns
328
+ * @param error The error to check
329
+ * @param retryableStatusCodes HTTP status codes that should trigger retry
330
+ * @returns true if the error is retryable
331
+ */
332
+ declare const isRetryableError: (error: unknown, retryableStatusCodes?: number[]) => boolean;
333
+ /**
334
+ * Retry an async operation with exponential backoff
335
+ * @param fn The async function to retry
336
+ * @param config Retry configuration
337
+ * @returns The result of the function
338
+ * @throws The last error if all retries are exhausted
339
+ */
340
+ declare const retry: <T>(function_: () => Promise<T>, config?: RetryConfig) => Promise<T>;
341
+ /**
342
+ * Create a retry wrapper function with pre-configured settings.
343
+ * @param config Retry configuration
344
+ * @returns A function that wraps async operations with retry logic
345
+ */
346
+ declare const createRetryWrapper: (config?: RetryConfig) => <T>(function_: () => Promise<T>) => Promise<T>;
347
+ /**
348
+ * Configurable validation system for file upload constraints.
349
+ * Supports multiple validation rules with custom error responses.
350
+ * @template T - The type being validated
351
+ */
352
+ declare class Validator<T> {
353
+ private prefix;
354
+ private validators;
355
+ /**
356
+ * Creates a new Validator instance.
357
+ * @param prefix Prefix for generated error codes (default: "ValidationError")
358
+ */
359
+ constructor(prefix?: string);
360
+ /**
361
+ * Adds validation rules to the validator.
362
+ * Each rule must include an `isValid` function.
363
+ * @param config Validation configuration object
364
+ * @throws TypeError if any validator is missing the isValid function
365
+ */
366
+ add(config: Validation<T>): void;
367
+ /**
368
+ * Verifies an object against all configured validation rules.
369
+ * Throws ValidationError on first validation failure.
370
+ * @param t Object to validate
371
+ * @throws ValidationError if validation fails
372
+ */
373
+ verify(t: T): Promise<never | void>;
374
+ }
375
+ interface MetaStorageOptions {
376
+ logger?: Console;
377
+ prefix?: string;
378
+ suffix?: string;
379
+ }
380
+ interface LocalMetaStorageOptions extends MetaStorageOptions {
381
+ /**
382
+ * Where the upload metadata should be stored
383
+ */
384
+ directory?: string;
385
+ }
386
+ declare class Metadata {
387
+ [key: string]: unknown;
388
+ psize?: number | string;
389
+ pname?: string;
390
+ pfiletype?: string;
391
+ ptype?: string;
392
+ pmimeType?: string;
393
+ pcontentType?: string;
394
+ ptitle?: string;
395
+ pfilename?: string;
396
+ poriginalName?: string;
397
+ plastModified?: number | string;
398
+ }
399
+ interface FileInit {
400
+ contentType?: string;
401
+ expiredAt?: Date | number | string;
402
+ /**
403
+ * Explicit identifier. When provided, the File constructor uses it directly
404
+ * instead of deriving an id from originalName/size/mtime. Lets callers map a
405
+ * user-chosen storage key (e.g. `"avatars/abc.png"`) onto the metadata id.
406
+ */
407
+ id?: string;
408
+ metadata: Metadata;
409
+ originalName?: string;
410
+ size?: number | string;
411
+ storageClass?: string;
412
+ ttl?: number | string;
413
+ }
414
+ interface FileReturn extends Omit<Required<FileInit>, "id" | "storageClass" | "ttl" | "expiredAt"> {
415
+ content: Buffer;
416
+ ETag?: string;
417
+ expiredAt?: Date | number | string;
418
+ id: string;
419
+ modifiedAt?: Date | number | string;
420
+ name: string;
421
+ storageClass?: string;
422
+ }
423
+ type UploadEventTypeValue = "completed" | "created" | "deleted" | "part" | "updated";
424
+ type UploadEventType = UploadEventTypeValue;
425
+ interface FileQuery {
426
+ id: string;
427
+ name?: string;
428
+ size?: number;
429
+ }
430
+ interface Checksum {
431
+ checksum?: string;
432
+ checksumAlgorithm?: string;
433
+ }
434
+ interface FilePart extends Checksum, FileQuery {
435
+ body: Readable;
436
+ contentLength?: number;
437
+ start: number;
438
+ }
439
+ type DateType = Date | number | string;
440
+ declare class File implements FileInit {
441
+ bytesWritten: number;
442
+ contentType: string;
443
+ originalName: string;
444
+ id: string;
445
+ metadata: Metadata;
446
+ name: string;
447
+ size?: number;
448
+ status?: UploadEventType;
449
+ expiredAt?: DateType;
450
+ createdAt?: DateType;
451
+ modifiedAt?: DateType;
452
+ hash?: {
453
+ algorithm: string;
454
+ value: string;
455
+ };
456
+ content?: Buffer;
457
+ ETag?: string;
458
+ constructor({ contentType, expiredAt, id, metadata, originalName, size }: FileInit);
459
+ }
460
+ type UploadFile = Readonly<File>;
461
+ /**
462
+ * Stores upload metadata.
463
+ */
464
+ declare class MetaStorage<T extends File = File> {
465
+ prefix: string;
466
+ suffix: string;
467
+ protected readonly logger?: Console;
468
+ constructor(config?: MetaStorageOptions);
469
+ /**
470
+ * Saves upload metadata.
471
+ */
472
+ save(_id: string, file: T): Promise<T>;
473
+ /**
474
+ * Deletes an upload metadata.
475
+ */
476
+ delete(_id: string): Promise<void>;
477
+ /**
478
+ * Retrieves upload metadata.
479
+ */
480
+ get(_id: string): Promise<T>;
481
+ /**
482
+ * Marks upload active.
483
+ */
484
+ touch(_id: string, _file: T): Promise<T>;
485
+ getMetaName(id: string): string;
486
+ getIdFromMetaName(name: string): string;
487
+ }
488
+ type OnCreate<TFile extends File = File> = (file: TFile) => Promise<void> | void;
489
+ type OnUpdate<TFile extends File = File> = (file: TFile) => Promise<void> | void;
490
+ type OnComplete<TFile extends File = File, TResponse = unknown, TRequest = unknown> = (file: TFile, response: TResponse, request?: TRequest) => Promise<void> | void;
491
+ type OnDelete<TFile extends File = File> = (file: TFile) => Promise<void> | void;
492
+ type OnError<TBody = HttpErrorBody> = (error: HttpError<TBody>) => Promise<void> | void;
493
+ interface PurgeList {
494
+ items: UploadFile[];
495
+ maxAgeMs: number;
496
+ }
497
+ interface ExpirationOptions {
498
+ /**
499
+ * Age of the upload, after which it is considered expired and can be deleted
500
+ */
501
+ maxAge: number | string;
502
+ /**
503
+ * Auto purging interval for expired upload
504
+ */
505
+ purgeInterval?: number | string;
506
+ /**
507
+ * Auto prolong expiring upload
508
+ */
509
+ rolling?: boolean;
510
+ }
511
+ interface BaseStorageOptions<T extends File = File> extends GenericStorageConfig {
512
+ /** Allowed MIME types */
513
+ allowMIME?: string[];
514
+ /** The full path of the folder where the uploaded asset will be stored. */
515
+ assetFolder?: string;
516
+ /** Cache instance to use for caching */
517
+ cache?: Cache;
518
+ /**
519
+ * Automatic cleaning of abandoned and completed upload
520
+ * @example
521
+ * ```ts
522
+ * app.use(
523
+ * '/upload',
524
+ * Upload.upload({
525
+ * directory: 'upload',
526
+ * expiration: { maxAge: '6h', purgeInterval: '30min' },
527
+ * onComplete
528
+ * })
529
+ * );
530
+ * ```
531
+ */
532
+ expiration?: ExpirationOptions;
533
+ /** File naming function */
534
+ filename?: (file: T) => string;
535
+ /**
536
+ * File name validation function.
537
+ * Returns true if the filename is valid, false otherwise.
538
+ * @default Cloud storage platforms: permissive (only blocks path traversal and null bytes)
539
+ * @default DiskStorage: strict (blocks filesystem-incompatible characters)
540
+ * @example
541
+ * ```ts
542
+ * fileNameValidation: (name: string) => {
543
+ * // Custom validation logic
544
+ * return name.length > 0 && !name.includes('../');
545
+ * }
546
+ * ```
547
+ */
548
+ fileNameValidation?: (name: string) => boolean;
549
+ /** Logger injection */
550
+ logger?: Console;
551
+ /** Limiting the size of custom metadata */
552
+ maxMetadataSize?: number | string;
553
+ /** File size limit */
554
+ maxUploadSize?: number | string;
555
+ /** Provide custom meta storage */
556
+ metaStorage?: MetaStorage<T>;
557
+ /** Metrics injection for observability */
558
+ metrics?: Metrics;
559
+ /** Callback function that is called when an upload is completed */
560
+ onComplete?: OnComplete<T>;
561
+ /** Callback function that is called when a new upload is created */
562
+ onCreate?: OnCreate<T>;
563
+ /** Callback function that is called when an upload is cancelled */
564
+ onDelete?: OnDelete<T>;
565
+ /** Customize error response */
566
+ onError?: OnError;
567
+ /** Callback function that is called when an upload is updated */
568
+ onUpdate?: OnUpdate<T>;
569
+ /** Force relative URI in Location header */
570
+ useRelativeLocation?: boolean;
571
+ /** Upload validation options */
572
+ validation?: Validation<T>;
573
+ }
574
+ type DiskStorageOptions<T extends File> = BaseStorageOptions<T> & {
575
+ /**
576
+ * Uploads directory.
577
+ */
578
+ directory: string;
579
+ /**
580
+ * Configuring metafile storage on the local disk
581
+ * @example
582
+ * ```ts
583
+ * const storage = new DiskStorage({
584
+ * directory: 'upload',
585
+ * metaStorageConfig: { directory: '/tmp/upload-metafiles', prefix: '.' }
586
+ * });
587
+ * ```
588
+ */
589
+ metaStorageConfig?: LocalMetaStorageOptions;
590
+ };
591
+ type DiskStorageWithChecksumOptions<T extends File> = DiskStorageOptions<T> & {
592
+ /**
593
+ * Enable/disable file/range checksum calculation
594
+ */
595
+ checksum?: boolean | "md5" | "sha1";
596
+ };
597
+ /**
598
+ * Unified storage configuration
599
+ */
600
+ interface GenericStorageConfig {
601
+ /** Allow additional properties for specific storage backends */
602
+ [key: string]: unknown;
603
+ /** Base path/prefix for all operations */
604
+ basePath?: string;
605
+ /** Cache TTL */
606
+ cacheTTL?: number;
607
+ /** Supported checksum algorithms */
608
+ checksumTypes?: string[];
609
+ /**
610
+ * Default abort signal merged into every operation. A per-call
611
+ * `OperationOptions.signal` is combined with this, not replaced — either
612
+ * one aborts the call. Note this signal lives for the storage instance's
613
+ * lifetime: once it aborts, every subsequent operation fails fast.
614
+ */
615
+ defaultSignal?: AbortSignal;
616
+ /**
617
+ * Default per-operation timeout in milliseconds, applied per retry
618
+ * attempt when a call omits `OperationOptions.timeout`. A per-call
619
+ * `timeout` (including `0` to explicitly disable) takes precedence.
620
+ */
621
+ defaultTimeout?: number;
622
+ /** Logger instance */
623
+ logger?: Console;
624
+ /** Maximum file size */
625
+ maxFileSize?: number | string;
626
+ /** Metrics instance for observability */
627
+ metrics?: Metrics;
628
+ /** Retry configuration for transient failures */
629
+ retryConfig?: RetryConfig;
630
+ }
631
+ /**
632
+ * Per-operation overrides for cancellation, deadlines and retries.
633
+ *
634
+ * Threaded through the public storage operations down to the backend SDK call.
635
+ * Backends that wrap an SDK with native cancellation honour `signal`/`timeout`
636
+ * directly; backends without a cancellation primitive still fail fast at the
637
+ * storage layer, but the provider request may continue in the background.
638
+ */
639
+ interface OperationOptions {
640
+ /**
641
+ * Retry override for this call. A number is treated as `maxRetries`; an
642
+ * object is shallow-merged over the backend's configured `RetryConfig`.
643
+ * Aborted and timed-out operations are never retried regardless of this.
644
+ */
645
+ retries?: number | RetryConfig;
646
+ /**
647
+ * Abort the operation when this signal fires. Merged with any
648
+ * per-call `timeout` via `AbortSignal.any`.
649
+ */
650
+ signal?: AbortSignal;
651
+ /**
652
+ * Per-operation timeout in milliseconds. `0` or a negative value
653
+ * disables the timeout. Applied per retry attempt.
654
+ */
655
+ timeout?: number;
656
+ }
657
+ /**
658
+ * Batch operation result for a single file
659
+ */
660
+ interface BatchOperationResult<T extends File = File> {
661
+ /** Error message if operation failed */
662
+ error?: string;
663
+ /** File that was successfully operated on */
664
+ file?: T;
665
+ /** File ID */
666
+ id: string;
667
+ /** Whether the operation was successful */
668
+ success: boolean;
669
+ }
670
+ /**
671
+ * Response from batch operations (deleteBatch, copyBatch, moveBatch)
672
+ */
673
+ interface BatchOperationResponse<T extends File = File> {
674
+ /** Failed operations with error details */
675
+ failed: {
676
+ error: string;
677
+ id: string;
678
+ }[];
679
+ /** Total number of failed operations */
680
+ failedCount: number;
681
+ /** Successfully processed files */
682
+ successful: T[];
683
+ /** Total number of successful operations */
684
+ successfulCount: number;
685
+ }
686
+ /**
687
+ * Default filename validation for cloud storage platforms.
688
+ * Permissive validation that only blocks dangerous patterns (path traversal, null bytes).
689
+ * Cloud storage platforms (S3, Azure, GCS) accept most special characters and handle URL encoding automatically.
690
+ */
691
+ declare const defaultCloudStorageFileNameValidation: (name: string) => boolean;
692
+ /**
693
+ * Default filename validation for local filesystems.
694
+ * Stricter validation that blocks filesystem-incompatible characters.
695
+ */
696
+ declare const defaultFilesystemFileNameValidation: (name: string) => boolean;
697
+ /**
698
+ * Abstract base class for all storage backends.
699
+ * @template TFile The file type used by this storage backend.
700
+ * @template TFileReturn The return type for file retrieval operations.
701
+ * @remarks
702
+ * ## Error Handling
703
+ *
704
+ * All storage operations follow consistent error handling patterns:
705
+ * - Operations throw `UploadError` with specific error codes (see ERRORS enum)
706
+ * - Common error codes: FILE_NOT_FOUND, GONE (expired), FILE_LOCKED, STORAGE_BUSY
707
+ * - Errors are normalized with storage class context via `normalizeError()`
708
+ * - Batch operations capture individual failures without stopping the batch
709
+ *
710
+ * ## Retry Behavior
711
+ *
712
+ * Storage implementations handle retries differently:
713
+ *
714
+ * ### Cloud Storage (S3, GCS, Azure, Netlify Blob)
715
+ * - Use configurable retry wrappers via `retryConfig` option
716
+ * - Default retryable status codes: 408, 429, 500, 502, 503, 504
717
+ * - Retry logic handles transient network errors and rate limiting
718
+ * - Custom `shouldRetry` functions can be provided for advanced retry logic
719
+ *
720
+ * ### Local Storage (DiskStorage)
721
+ * - No automatic retries (filesystem operations are typically immediate)
722
+ * - Errors are thrown directly for immediate feedback
723
+ *
724
+ * ## Operation Instrumentation
725
+ *
726
+ * All public operations are automatically instrumented via `instrumentOperation()`:
727
+ * - Metrics are recorded for operation count, duration, and errors
728
+ * - File sizes are tracked for operations that return file objects
729
+ * - Error metrics include error messages for debugging
730
+ *
731
+ * ## Metadata Caching
732
+ *
733
+ * File metadata is automatically cached to reduce storage API calls:
734
+ * - Cache is updated on save, delete, and get operations
735
+ * - Cache is invalidated when metadata is deleted
736
+ * - Implementations can override caching behavior if needed
737
+ */
738
+ declare abstract class BaseStorage<TFile extends File = File, TFileReturn extends FileReturn = FileReturn> {
739
+ /**
740
+ * Hook called when a new file is created.
741
+ * @param file The newly created file object.
742
+ * @remarks This hook is called after file metadata is saved but before returning the file.
743
+ * Can be used for side effects like logging, notifications, or custom processing.
744
+ */
745
+ onCreate: (file: TFile) => Promise<void> | void;
746
+ /**
747
+ * Hook called when file metadata is updated.
748
+ * @param file The updated file object.
749
+ * @remarks This hook is called after metadata is updated and saved.
750
+ * Can be used for side effects like logging or custom processing.
751
+ */
752
+ onUpdate: (file: TFile) => Promise<void> | void;
753
+ /**
754
+ * Hook called when a file upload is completed.
755
+ * @param file The completed file object.
756
+ * @param response The response object that can be modified in place (headers, statusCode, body).
757
+ * @param request Optional request object for additional context.
758
+ * @remarks This hook is called when file status becomes "completed".
759
+ * The response object can be modified directly to add headers or change the status code.
760
+ */
761
+ onComplete: (file: TFile, response: unknown, request?: unknown) => Promise<void> | void;
762
+ /**
763
+ * Hook called when a file is deleted.
764
+ * @param file The deleted file object.
765
+ * @remarks This hook is called after the file is deleted but before returning.
766
+ * Can be used for side effects like cleanup or logging.
767
+ */
768
+ onDelete: (file: TFile) => Promise<void> | void;
769
+ /**
770
+ * Hook called when an error occurs during storage operations.
771
+ * @param error The HTTP error object that can be modified in place.
772
+ * @remarks This hook allows customizing error responses by modifying the error object.
773
+ * The error object can be modified to change headers, statusCode, or body properties.
774
+ * Error formatting happens in handlers after this hook is called.
775
+ */
776
+ onError: (error: HttpError) => Promise<void> | void;
777
+ isReady: boolean;
778
+ errorResponses: ErrorResponses;
779
+ cache: Cache<string, TFile>;
780
+ readonly logger?: Console;
781
+ readonly metrics: Metrics;
782
+ readonly genericConfig: BaseStorageOptions<TFile>;
783
+ maxMetadataSize: number;
784
+ checksumTypes: string[];
785
+ /**
786
+ * Adapter capability flag: when `true`, the adapter honours
787
+ * `OperationOptions.range` on {@link BaseStorage.get} and
788
+ * {@link BaseStorage.getStream}, returning only the requested byte slice.
789
+ * The `Files` facade gates `download({ range })` on this flag and throws
790
+ * `METHOD_NOT_ALLOWED` for adapters that haven't opted in.
791
+ */
792
+ readonly supportsRange: boolean;
793
+ /**
794
+ * Adapter capability flag: when `true`, the adapter persists user-supplied
795
+ * key/value metadata alongside the object and returns it on `get`/`head`.
796
+ * Defaults to `true` — most backends carry metadata. Adapters that drop or
797
+ * ignore custom metadata override this to `false`; the `Files` facade reads
798
+ * it via {@link Files.capabilities} so callers can fail fast instead of
799
+ * silently losing metadata.
800
+ */
801
+ readonly supportsMetadata: boolean;
802
+ /**
803
+ * Adapter capability flag: when `true`, the adapter honours an object
804
+ * `cacheControl` directive on write. Defaults to `false` — most backends
805
+ * have no cache-control concept. Exposed through {@link Files.capabilities}.
806
+ */
807
+ readonly supportsCacheControl: boolean;
808
+ /**
809
+ * Adapter capability flag: when `true`, the adapter implements
810
+ * {@link BaseStorage.listDirectory} so the provider collapses keys into
811
+ * common prefixes server-side. The `Files` facade prefers this native path
812
+ * for `list({ delimiter })`; adapters that leave it `false` fall back to
813
+ * synthesizing the directory view from a full listing in the facade.
814
+ */
815
+ readonly supportsDelimiter: boolean;
816
+ /**
817
+ * Adapter capability flag: when `true`, the adapter reports its own
818
+ * byte-level `onProgress` events during `write`. The `Files` facade skips
819
+ * its coarse "start/done" emission for adapters that report progress
820
+ * natively, so callers see one consistent stream of events.
821
+ */
822
+ readonly reportsUploadProgress: boolean;
823
+ maxUploadSize: number;
824
+ protected expiration?: {
825
+ maxAge?: string | number;
826
+ purgeInterval?: string | number;
827
+ rolling?: boolean;
828
+ };
829
+ protected locker: Locker;
830
+ protected namingFunction: (file: TFile) => string;
831
+ protected validation: Validator<TFile>;
832
+ protected abstract meta: MetaStorage<TFile>;
833
+ protected assetFolder: string | undefined;
834
+ /**
835
+ * Limits the number of concurrent upload requests
836
+ */
837
+ protected concurrency?: number;
838
+ protected constructor(config: BaseStorageOptions<TFile>);
839
+ /**
840
+ * Escape hatch returning the underlying native client (S3Client, BlobServiceClient, etc.)
841
+ * for provider-specific operations not covered by the unified API.
842
+ * Returns `undefined` when no native client is available (e.g. DiskStorage).
843
+ */
844
+ get raw(): unknown;
845
+ /**
846
+ * Returns a presigned URL for downloading the object at `key`.
847
+ * Throws `ERRORS.METHOD_NOT_ALLOWED` when the adapter has no native presign support.
848
+ * @param _key Storage key.
849
+ * @param _options Optional expiry and response overrides.
850
+ */
851
+ getReadUrl(_key: string, _options?: OperationOptions & {
852
+ expiresIn?: number;
853
+ responseContentDisposition?: string;
854
+ responseContentType?: string;
855
+ }): Promise<string>;
856
+ /**
857
+ * Returns a presigned URL for uploading a single object to `key`.
858
+ * Throws `ERRORS.METHOD_NOT_ALLOWED` when the adapter has no native presign support.
859
+ * @param _key Storage key.
860
+ * @param _options Optional content type, expiry, and content length hints, plus per-call signal/timeout/retries.
861
+ */
862
+ getUploadUrl(_key: string, _options?: OperationOptions & {
863
+ contentLength?: number;
864
+ contentType?: string;
865
+ expiresIn?: number;
866
+ }): Promise<string>;
867
+ get tusExtension(): string[];
868
+ /**
869
+ * Validates a file against configured validation rules.
870
+ * @param file File object to validate.
871
+ * @returns Promise resolving to undefined if file is valid, throws ValidationError otherwise.
872
+ * @throws {ValidationError} If validation fails
873
+ */
874
+ validate(file: TFile): Promise<void>;
875
+ /**
876
+ * Checks if a file exists by querying its metadata.
877
+ * @param query File query containing the file ID to check.
878
+ * @param query.id File ID to check.
879
+ * @returns Promise resolving to true if file exists, false otherwise.
880
+ * @remarks This method does not throw errors - it returns false if the file is not found.
881
+ */
882
+ exists(query: FileQuery, options?: OperationOptions): Promise<boolean>;
883
+ /**
884
+ * Normalizes errors with storage-specific context.
885
+ * @param error The error to normalize.
886
+ * @returns Normalized HTTP error with storage class context added to the message.
887
+ * @remarks Errors are enhanced with the storage class name for better debugging.
888
+ */
889
+ normalizeError(error: Error): HttpError;
890
+ /**
891
+ * Gets the storage configuration.
892
+ * @returns The current storage configuration options.
893
+ */
894
+ get config(): BaseStorageOptions<TFile>;
895
+ /**
896
+ * Saves upload metadata to the metadata storage.
897
+ * @param file File object containing metadata to save.
898
+ * @returns Promise resolving to the saved file object.
899
+ * @remarks Updates timestamps and caches the file metadata.
900
+ * @throws {UploadError} If `file.id` contains path-traversal sequences, null bytes, or is an absolute path — patterns that could let a local MetaStorage implementation write outside its directory.
901
+ */
902
+ saveMeta(file: TFile): Promise<TFile>;
903
+ /**
904
+ * Rejects ids containing `..` segments, null bytes, or absolute paths — defense-in-depth
905
+ * so any MetaStorage / facade / handler that uses `id` as part of a filesystem path or
906
+ * cross-bucket lookup can't be escaped. Public so the `Files` facade and Fetch handlers
907
+ * can validate user-supplied keys before any adapter call.
908
+ */
909
+ static assertSafeId(id: string): void;
910
+ /**
911
+ * Deletes upload metadata from the metadata storage.
912
+ * @param id File ID whose metadata should be deleted.
913
+ * @returns Promise resolving when metadata is deleted.
914
+ * @remarks Also removes the file from the cache.
915
+ */
916
+ deleteMeta(id: string): Promise<void>;
917
+ /**
918
+ * Retrieves upload metadata by file ID.
919
+ * @param id File ID to retrieve metadata for.
920
+ * @returns Promise resolving to the file metadata object.
921
+ * @throws {UploadError} If the file metadata cannot be found (ERRORS.FILE_NOT_FOUND).
922
+ * @remarks Caches the retrieved metadata for faster subsequent access.
923
+ */
924
+ getMeta(id: string, _options?: OperationOptions): Promise<TFile>;
925
+ /**
926
+ * Checks if a file has expired and deletes it if so.
927
+ * @param file File object to check for expiration.
928
+ * @returns Promise resolving to the file object if not expired.
929
+ * @throws {UploadError} If the file has expired (ERRORS.GONE).
930
+ * @remarks If the file is expired, it is automatically deleted and the metadata is removed.
931
+ */
932
+ checkIfExpired(file: TFile): Promise<TFile>;
933
+ /**
934
+ * Searches for and purges expired uploads.
935
+ * @param maxAge Maximum age of files to keep (files older than this will be purged).
936
+ * Can be a number (milliseconds) or string (e.g., "1h", "30m", "7d").
937
+ * If not provided, uses the expiration.maxAge from configuration.
938
+ * @returns Promise resolving to a list of purged files.
939
+ * @remarks
940
+ * Errors during individual file deletions are logged but do not stop the purge process.
941
+ * Files with corrupted metadata are skipped with a warning.
942
+ * Uses rolling expiration if configured (based on modifiedAt) or fixed expiration (based on createdAt).
943
+ */
944
+ purge(maxAge?: number | string): Promise<PurgeList>;
945
+ /**
946
+ * Gets an uploaded file by ID.
947
+ * @param query File query containing the file ID to retrieve.
948
+ * @param query.id File ID to retrieve.
949
+ * @param options Optional per-call signal/timeout/retries.
950
+ * @returns Promise resolving to the file data including content.
951
+ * @throws {UploadError} If the file cannot be found (ERRORS.FILE_NOT_FOUND) or has expired (ERRORS.GONE).
952
+ * @remarks This method loads the entire file content into memory. For large files, use getStream() instead.
953
+ */
954
+ abstract get({ id }: FileQuery, options?: OperationOptions): Promise<TFileReturn>;
955
+ /**
956
+ * Gets an uploaded file as a readable stream for efficient large file handling.
957
+ * @param query File query containing the file ID to stream.
958
+ * @param query.id File ID to stream.
959
+ * @param options Optional per-call signal/timeout/retries (and, on range-capable adapters, a `range`).
960
+ * @returns Promise resolving to an object containing the stream, headers, and size.
961
+ * @throws {UploadError} If the file cannot be found (ERRORS.FILE_NOT_FOUND) or has expired (ERRORS.GONE).
962
+ * @remarks
963
+ * Default implementation falls back to get() and creates a stream from the buffer.
964
+ * Storage implementations should override this for better streaming performance.
965
+ * Headers include Content-Type, Content-Length, ETag, and Last-Modified.
966
+ */
967
+ getStream({ id }: FileQuery, options?: OperationOptions): Promise<{
968
+ headers?: Record<string, string>;
969
+ size?: number;
970
+ stream: Readable;
971
+ }>;
972
+ /**
973
+ * Retrieves a list of uploaded files.
974
+ * @param _limit Maximum number of files to return (default: 1000).
975
+ * @returns Promise resolving to an array of file metadata objects.
976
+ * @throws {Error} If not implemented by the storage backend.
977
+ * @remarks Storage implementations must override this method.
978
+ */
979
+ list(_limit?: number, _options?: OperationOptions): Promise<TFile[]>;
980
+ /**
981
+ * Directory-style listing: collapse keys that share a path segment into common prefixes,
982
+ * server-side, instead of returning every object. Adapters that can push the `delimiter` down to
983
+ * the provider (S3 family, GCS, Azure) override this and set
984
+ * {@link BaseStorage.supportsDelimiter} to `true`; the default throws so the `Files` facade knows
985
+ * to fall back to synthesizing the view from {@link BaseStorage.list}.
986
+ * @param _options Listing options — `delimiter` (required), plus optional `prefix`/`limit` and the usual per-call signal/timeout/retries.
987
+ * @returns Direct-child files and the common prefixes one delimiter level below `prefix`.
988
+ * @throws {UploadError} `METHOD_NOT_ALLOWED` when the adapter has no native delimiter support.
989
+ */
990
+ listDirectory(_options?: OperationOptions & {
991
+ delimiter: string;
992
+ limit?: number;
993
+ prefix?: string;
994
+ }): Promise<{
995
+ files: TFile[];
996
+ prefixes: string[];
997
+ }>;
998
+ /**
999
+ * Updates file metadata with user-provided key-value pairs.
1000
+ * @param query File query containing the file ID to update.
1001
+ * @param query.id File ID to update.
1002
+ * @param metadata Partial file object containing fields to update.
1003
+ * @returns Promise resolving to the updated file object.
1004
+ * @throws {UploadError} If the file cannot be found (ERRORS.FILE_NOT_FOUND).
1005
+ * @remarks
1006
+ * Supports TTL (time-to-live) option: if metadata contains a 'ttl' field,
1007
+ * it will be converted to an 'expiredAt' timestamp.
1008
+ * TTL can be a number (milliseconds) or string (e.g., "1h", "30m", "7d").
1009
+ */
1010
+ update({ id }: FileQuery, metadata: Partial<File>): Promise<TFile>;
1011
+ /**
1012
+ * Creates a new upload and saves its metadata.
1013
+ * @param file File initialization configuration.
1014
+ * @param options Optional per-call signal/timeout/retries.
1015
+ * @returns Promise resolving to the created file object.
1016
+ */
1017
+ abstract create(file: FileInit, options?: OperationOptions): Promise<TFile>;
1018
+ /**
1019
+ * Writes part and/or returns status of an upload.
1020
+ * @param part File part, query, or full file object to write.
1021
+ * @param options Optional per-call signal/timeout/retries.
1022
+ * @returns Promise resolving to the updated file object.
1023
+ */
1024
+ abstract write(part: FilePart | FileQuery | TFile, options?: OperationOptions): Promise<TFile>;
1025
+ /**
1026
+ * Deletes an upload and its metadata.
1027
+ * @param query File query containing the file ID to delete.
1028
+ * @param query.id File ID to delete.
1029
+ * @param options Optional per-call signal/timeout/retries.
1030
+ * @returns Promise resolving to the deleted file object with status: "deleted".
1031
+ * @throws {UploadError} If the file metadata cannot be found.
1032
+ */
1033
+ abstract delete(query: FileQuery, options?: OperationOptions): Promise<TFile>;
1034
+ /**
1035
+ * Copies an upload file to a new location.
1036
+ * @param name Source file name/ID.
1037
+ * @param destination Destination file name/ID.
1038
+ * @param options Optional copy options including storage class plus per-call signal/timeout/retries.
1039
+ * @returns Promise resolving to the copied file object.
1040
+ * @throws {UploadError} If the source file cannot be found.
1041
+ */
1042
+ abstract copy(name: string, destination: string, options?: OperationOptions & {
1043
+ storageClass?: string;
1044
+ }): Promise<TFile>;
1045
+ /**
1046
+ * Moves an upload file to a new location.
1047
+ * @param name Source file name/ID.
1048
+ * @param destination Destination file name/ID.
1049
+ * @param options Optional per-call signal/timeout/retries.
1050
+ * @returns Promise resolving to the moved file object.
1051
+ * @throws {UploadError} If the source file cannot be found.
1052
+ */
1053
+ abstract move(name: string, destination: string, options?: OperationOptions): Promise<TFile>;
1054
+ /**
1055
+ * Deletes multiple files in a single batch operation.
1056
+ * @param ids Array of file IDs to delete.
1057
+ * @returns Promise resolving to batch operation response with successful and failed deletions.
1058
+ * @remarks
1059
+ * Processes all deletions in parallel using Promise.allSettled.
1060
+ * Individual failures do not stop the batch operation.
1061
+ * Each deletion is wrapped in error handling to capture failures.
1062
+ * Metrics are recorded for the batch operation and individual failures.
1063
+ * Returns both successful and failed operations with detailed error information.
1064
+ */
1065
+ deleteBatch(ids: string[], options?: OperationOptions): Promise<BatchOperationResponse<TFile>>;
1066
+ /**
1067
+ * Copies multiple files in a single batch operation.
1068
+ * @param operations Array of copy operations, each containing:
1069
+ * source: Source file ID.
1070
+ * destination: Destination file ID or path.
1071
+ * options: Optional copy options including storage class.
1072
+ * @returns Promise resolving to batch operation response with successful and failed copies.
1073
+ * @remarks
1074
+ * Processes all copies in parallel using Promise.allSettled.
1075
+ * Individual failures do not stop the batch operation.
1076
+ * Each copy operation is wrapped in error handling to capture failures.
1077
+ * Metrics are recorded for the batch operation and individual failures.
1078
+ * Returns both successful and failed operations with detailed error information.
1079
+ */
1080
+ copyBatch(operations: {
1081
+ destination: string;
1082
+ options?: {
1083
+ storageClass?: string;
1084
+ };
1085
+ source: string;
1086
+ }[]): Promise<BatchOperationResponse<TFile>>;
1087
+ /**
1088
+ * Moves multiple files in a single batch operation.
1089
+ * @param operations Array of move operations, each containing:
1090
+ * source: Source file ID.
1091
+ * destination: Destination file ID or path.
1092
+ * @returns Promise resolving to batch operation response with successful and failed moves.
1093
+ * @remarks
1094
+ * Processes all moves in parallel using Promise.allSettled.
1095
+ * Individual failures do not stop the batch operation.
1096
+ * Each move operation is wrapped in error handling to capture failures.
1097
+ * Metrics are recorded for the batch operation and individual failures.
1098
+ * Returns both successful and failed operations with detailed error information.
1099
+ */
1100
+ moveBatch(operations: {
1101
+ destination: string;
1102
+ source: string;
1103
+ }[]): Promise<BatchOperationResponse<TFile>>;
1104
+ /**
1105
+ * Prevent upload from being accessed by multiple requests.
1106
+ * Returns a unique token that must be passed back to `unlock()` so a caller whose lock TTL'd
1107
+ * out cannot accidentally release a newly-acquired lock held by another request.
1108
+ */
1109
+ protected lock(key: string): Promise<string>;
1110
+ protected unlock(key: string, token?: string): Promise<void>;
1111
+ /**
1112
+ * Run a function while holding the lock for `key`. The lock is released even if `fn` throws,
1113
+ * and only released when the caller still owns the lock (token-verified). Public so that
1114
+ * handlers can serialize cross-call read-modify-write sequences on the same upload (e.g.
1115
+ * appending to `_chunks` during chunked PATCH).
1116
+ */
1117
+ withLock<R>(key: string, function_: () => Promise<R>): Promise<R>;
1118
+ protected isUnsupportedChecksum(algorithm?: string): boolean;
1119
+ protected startAutoPurge(purgeInterval: number): void;
1120
+ protected updateTimestamps(file: TFile): TFile;
1121
+ /**
1122
+ * Backend-resolved retry configuration that {@link runOperation} layers
1123
+ * per-call overrides on top of. Subclasses that build a `RetryConfig`
1124
+ * (S3, Azure, Netlify, …) override this; the default (`undefined`) makes
1125
+ * `runOperation` fall back to the retry engine's own defaults.
1126
+ */
1127
+ protected getRetryConfig(): RetryConfig | undefined;
1128
+ /**
1129
+ * Runs a backend SDK call with per-operation cancellation, timeout and
1130
+ * retry handling.
1131
+ *
1132
+ * The provided `signal` is the merge of the caller's `options.signal` and
1133
+ * a fresh per-attempt `options.timeout` deadline (via `AbortSignal.any` /
1134
+ * `AbortSignal.timeout`). Pass it to the underlying SDK so the provider
1135
+ * request is actually cancelled rather than merely abandoned.
1136
+ *
1137
+ * Aborted or timed-out calls are never retried. Pass
1138
+ * `{ replayable: false }` for operations whose body is a one-shot stream —
1139
+ * a consumed `Readable`/`ReadableStream` cannot be safely re-sent, so the
1140
+ * retry count is forced to zero.
1141
+ * @param options Per-call overrides (`signal`, `timeout`, `retries`).
1142
+ * @param function_ Receives the merged abort signal for the attempt.
1143
+ * @param operationConfig `replayable: false` disables retries for non-replayable bodies.
1144
+ */
1145
+ protected runOperation<T>(options: OperationOptions | undefined, function_: (signal: AbortSignal | undefined) => Promise<T>, operationConfig?: {
1146
+ replayable?: boolean;
1147
+ }): Promise<T>;
1148
+ /**
1149
+ * Instruments a storage operation with metrics and error tracking.
1150
+ * @param operation Operation name (e.g., "create", "delete", "copy").
1151
+ * @param function_ The operation function to execute.
1152
+ * @param attributes Additional attributes to include in metrics.
1153
+ * @returns Promise resolving to the operation result.
1154
+ * @throws Re-throws any errors from the operation function.
1155
+ * @remarks
1156
+ * Records operation count, duration, and error metrics.
1157
+ * Tracks file sizes for operations returning file objects.
1158
+ * Error metrics include error messages for debugging.
1159
+ * All public methods should use this wrapper for consistent instrumentation.
1160
+ */
1161
+ protected instrumentOperation<T>(operation: string, function_: () => Promise<T>, attributes?: Record<string, string | number>): Promise<T>;
1162
+ }
1163
+ export { retry as $, OnUpdate as A, BaseStorage as B, Cache as C, DiskStorageOptions as D, ErrorResponses as E, File as F, RangeChecksum as G, HttpError as H, IncomingMessageWithBody as I, RangeHasher as J, ResponseBody as K, LocalMetaStorageOptions as L, MetaStorage as M, ResponseTuple as N, OperationOptions as O, PurgeList as P, ValidationError as Q, RetryConfig as R, ValidatorConfig as S, defaultCloudStorageFileNameValidation as T, UploadFile as U, Validation as V, defaultFilesystemFileNameValidation as W, extractHttpStatus as X, isRetryableError as Y, isUploadError as Z, mapStatusToErrorCode as _, UploadError as a, throwErrorCode as a0, wrapStorageError as a1, UploadEventType as b, createRetryWrapper as c, FileInit as d, FilePart as e, FileQuery as f, FileReturn as g, ResponseBodyType as h, ERRORS as i, DiskStorageWithChecksumOptions as j, MetaStorageOptions as k, BaseStorageOptions as l, UploadResponse as m, Metrics as n, BatchOperationResponse as o, BatchOperationResult as p, ErrorMap as q, ExpirationOptions as r, Header as s, Headers as t, HttpErrorBody as u, Metadata as v, OnComplete as w, OnCreate as x, OnDelete as y, OnError as z };