@visulima/storage 1.0.0-alpha.30 → 1.0.0-alpha.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/adapter/nuxt/module.d.ts +4 -4
- package/dist/adapter/nuxt/node_modules/.bin/nuxi +2 -2
- package/dist/adapter/nuxt/node_modules/.bin/nuxt +2 -2
- package/dist/ai/ai-sdk/index.d.ts +3 -3
- package/dist/ai/claude/index.d.ts +2 -2
- package/dist/ai/openai/index.d.ts +3 -3
- package/dist/ai/tanstack/index.d.ts +2 -2
- package/dist/handler/http/fetch/index.d.ts +7 -7
- package/dist/handler/http/fetch/index.js +1 -1
- package/dist/handler/http/hono/index.d.ts +4 -4
- package/dist/handler/http/hono/index.js +1 -1
- package/dist/handler/http/nextjs/index.d.ts +4 -4
- package/dist/handler/http/nextjs/index.js +1 -1
- package/dist/handler/http/node/index.d.ts +7 -7
- package/dist/handler/http/node/index.js +1 -1
- package/dist/handler/http/solid-start/index.d.ts +4 -4
- package/dist/handler/http/solid-start/index.js +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +1 -1
- package/dist/packem_shared/{AwsLightStorage-w21RxjUm.js → AwsLightStorage-DbQrK9m7.js} +1 -1
- package/dist/packem_shared/{AzureStorage-2kl7JDXs.js → AzureStorage-Cmr0nPDq.js} +1 -1
- package/dist/packem_shared/{BoxStorage-BUeEJoGL.js → BoxStorage-DYzAYPIr.js} +1 -1
- package/dist/packem_shared/{BunS3Storage-WM3rF6Fw.js → BunS3Storage-BvaFeKeu.js} +1 -1
- package/dist/packem_shared/{BunnyStorage-D3s2fRB3.js → BunnyStorage-DsQndiy5.js} +1 -1
- package/dist/packem_shared/{CloudinaryStorage-BBE2-aVz.js → CloudinaryStorage-DiK0T7N7.js} +1 -1
- package/dist/packem_shared/{DiskStorage-DL0GiG6k.js → DiskStorage-RvZNMWe7.js} +1 -1
- package/dist/packem_shared/{DiskStorageWithChecksum-BvUTn7O-.js → DiskStorageWithChecksum-eGOV3leX.js} +1 -1
- package/dist/packem_shared/{DropboxStorage-BL3OIdE_.js → DropboxStorage-Dfd78aJL.js} +1 -1
- package/dist/packem_shared/Files-CtggibJ-.js +1 -0
- package/dist/packem_shared/{FirebaseStorage-lXMXy3Pm.js → FirebaseStorage-C-FwZOYA.js} +1 -1
- package/dist/packem_shared/{FtpStorage-Dw94efNW.js → FtpStorage-DzaP89bG.js} +1 -1
- package/dist/packem_shared/{GCSMetaStorage-udgXA5ia.js → GCSMetaStorage-DFIjFmn-.js} +1 -1
- package/dist/packem_shared/{GCStorage-ChY6uJuO.js → GCStorage-1vA3xkFO.js} +1 -1
- package/dist/packem_shared/{GoogleDriveStorage-C0NhBBWH.js → GoogleDriveStorage-D_RaKV_j.js} +1 -1
- package/dist/packem_shared/{Multipart-D9WIud9R.js → Multipart-C6Mw7V9W.js} +1 -1
- package/dist/packem_shared/{Multipart-CIFfQksD.js → Multipart-DkH4QwNs.js} +1 -1
- package/dist/packem_shared/{NetlifyBlobStorage-CO89TGvF.js → NetlifyBlobStorage-C-IkXF0_.js} +1 -1
- package/dist/packem_shared/{OneDriveStorage-jAN46vRm.js → OneDriveStorage-C7rqK2Wp.js} +1 -1
- package/dist/packem_shared/{PocketBaseStorage-DpOjOKAt.js → PocketBaseStorage-Cdgr5w88.js} +1 -1
- package/dist/packem_shared/{Rest-BuD3ySAg.js → Rest-DWrS4Z_j.js} +1 -1
- package/dist/packem_shared/{Rest-URrQ5FYM.js → Rest-DY1neM_3.js} +1 -1
- package/dist/packem_shared/{S3Storage-n1ohEZj4.js → S3Storage-Dn3l4WkO.js} +1 -1
- package/dist/packem_shared/{SftpStorage-Ban-WN8v.js → SftpStorage-CBW6MBLV.js} +1 -1
- package/dist/packem_shared/{SharePointStorage-BY90zh1c.js → SharePointStorage-r934t5HX.js} +1 -1
- package/dist/packem_shared/{SupabaseStorage-pNbHAE1Y.js → SupabaseStorage-DMRhLPNo.js} +1 -1
- package/dist/packem_shared/{Tus-TNG9HAY8.js → Tus-BMd67Cnb.js} +1 -1
- package/dist/packem_shared/{Tus-Fp_hx5ug.js → Tus-d2hPK5nV.js} +1 -1
- package/dist/packem_shared/{UploadThingStorage-BcmIE2dI.js → UploadThingStorage-BjF_gRMY.js} +1 -1
- package/dist/packem_shared/{VercelBlobStorage-s260zfFo.js → VercelBlobStorage-Dx2jywjl.js} +1 -1
- package/dist/packem_shared/{base-handler-core-BYDQditz.js → base-handler-core-Cwd9uq_E.js} +1 -1
- package/dist/packem_shared/{base-handler-fetch-DWzsPkmV.js → base-handler-fetch-_BD4V1W2.js} +1 -1
- package/dist/packem_shared/{base-handler-node-Dety2rQB.js → base-handler-node-BDNRnVIc.js} +1 -1
- package/dist/packem_shared/{defaultCloudStorageFileNameValidation-shIZX_7L.js → defaultCloudStorageFileNameValidation-hWLdEgOD.js} +1 -1
- package/dist/packem_shared/disk-storage-Bmvawf-b.js +1 -0
- package/dist/packem_shared/{disk-storage-with-checksum.d-mHcg2uLw.d.ts → disk-storage-with-checksum.d-Dm4agCey.d.ts} +1 -1
- package/dist/packem_shared/{executors.d-X4hz3zfu.d.ts → executors.d-Cut3Gstb.d.ts} +1 -1
- package/dist/packem_shared/{gcs-meta-storage-mZiqlX-9.js → gcs-meta-storage-Bwts-MUe.js} +1 -1
- package/dist/packem_shared/index.d-DSZjPbvW.d.ts +230 -0
- package/dist/packem_shared/{local-meta-storage.d-B11vHYNm.d.ts → local-meta-storage.d-qZQI1JUe.d.ts} +1 -1
- package/dist/packem_shared/{media-transformer.d-C3QvECD7.d.ts → media-transformer.d-lQ_RUjb5.d.ts} +2 -2
- package/dist/packem_shared/{rest-base-DI7xFXr5.js → rest-base-C-a7pXUc.js} +1 -1
- package/dist/packem_shared/{s3-base-storage-Dbexfg7p.js → s3-base-storage-Ek1HinGR.js} +1 -1
- package/dist/packem_shared/{s3-base-storage.d-V3N2nKCt.d.ts → s3-base-storage.d-CDIOMTpp.d.ts} +1 -1
- package/dist/packem_shared/storage-B-NDsI-o.js +1 -0
- package/dist/packem_shared/{storage.d-RteRC-cG.d.ts → storage.d-BoJgdi1n.d.ts} +19 -14
- package/dist/packem_shared/{tus-base.d-CygntIPM.d.ts → tus-base.d-C28C_AY9.d.ts} +3 -3
- package/dist/packem_shared/{types.d-ChNXbbHG.d.ts → types.d-C0MDnUYc.d.ts} +1 -1
- package/dist/packem_shared/{types.d-cI_cMxcZ.d.ts → types.d-CPxJpoPH.d.ts} +2 -2
- package/dist/packem_shared/{types.d-DxonY4XS.d.ts → types.d-DCPQvHDI.d.ts} +2 -2
- package/dist/storage/aws/index.d.ts +2 -2
- package/dist/storage/aws/index.js +1 -1
- package/dist/storage/aws-light/index.d.ts +2 -2
- package/dist/storage/aws-light/index.js +1 -1
- package/dist/storage/azure/index.d.ts +1 -1
- package/dist/storage/azure/index.js +1 -1
- package/dist/storage/box/index.d.ts +2 -2
- package/dist/storage/box/index.js +1 -1
- package/dist/storage/bun-s3/index.d.ts +2 -2
- package/dist/storage/bun-s3/index.js +1 -1
- package/dist/storage/bunny/index.d.ts +2 -2
- package/dist/storage/bunny/index.js +1 -1
- package/dist/storage/cloudinary/index.d.ts +2 -2
- package/dist/storage/cloudinary/index.js +1 -1
- package/dist/storage/dropbox/index.d.ts +2 -2
- package/dist/storage/dropbox/index.js +1 -1
- package/dist/storage/firebase/index.d.ts +2 -2
- package/dist/storage/firebase/index.js +1 -1
- package/dist/storage/ftp/index.d.ts +2 -2
- package/dist/storage/ftp/index.js +1 -1
- package/dist/storage/gcs/index.d.ts +1 -1
- package/dist/storage/gcs/index.js +1 -1
- package/dist/storage/google-drive/index.d.ts +2 -2
- package/dist/storage/google-drive/index.js +1 -1
- package/dist/storage/local/index.d.ts +3 -3
- package/dist/storage/local/index.js +1 -1
- package/dist/storage/netlify-blob/index.d.ts +2 -2
- package/dist/storage/netlify-blob/index.js +1 -1
- package/dist/storage/onedrive/index.d.ts +4 -4
- package/dist/storage/onedrive/index.js +1 -1
- package/dist/storage/pocketbase/index.d.ts +2 -2
- package/dist/storage/pocketbase/index.js +1 -1
- package/dist/storage/sftp/index.d.ts +2 -2
- package/dist/storage/sftp/index.js +1 -1
- package/dist/storage/sharepoint/index.d.ts +3 -3
- package/dist/storage/sharepoint/index.js +1 -1
- package/dist/storage/supabase/index.d.ts +2 -2
- package/dist/storage/supabase/index.js +1 -1
- package/dist/storage/uploadthing/index.d.ts +2 -2
- package/dist/storage/uploadthing/index.js +1 -1
- package/dist/storage/vercel-blob/index.d.ts +2 -2
- package/dist/storage/vercel-blob/index.js +1 -1
- package/dist/transformer/audio-transformer.d.ts +2 -2
- package/dist/transformer/image-transformer.d.ts +2 -2
- package/dist/transformer/index.d.ts +3 -3
- package/dist/transformer/video-transformer.d.ts +2 -2
- package/package.json +1 -1
- package/dist/packem_shared/Files-CJh9_N-9.js +0 -1
- package/dist/packem_shared/disk-storage-CKAJvhcj.js +0 -1
- package/dist/packem_shared/index.d-C4Fivh4I.d.ts +0 -94
- package/dist/packem_shared/storage-Dh0tJh7j.js +0 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { O as OperationOptions, B as BaseStorage } from "./storage.d-BoJgdi1n.js";
|
|
2
|
+
/**
|
|
3
|
+
* Web-standard and Node-native body types accepted by {@link Files.upload}.
|
|
4
|
+
*/
|
|
5
|
+
type FileBody = ArrayBuffer | ArrayBufferView | Blob | Buffer | NodeJS.ReadableStream | ReadableStream<Uint8Array> | string;
|
|
6
|
+
interface UploadOptions {
|
|
7
|
+
contentType?: string;
|
|
8
|
+
metadata?: Record<string, unknown>;
|
|
9
|
+
/**
|
|
10
|
+
* Explicit byte length. Required for {@link NodeJS.ReadableStream} and Web `ReadableStream`
|
|
11
|
+
* inputs because their length is not derivable from the value itself; ignored otherwise.
|
|
12
|
+
*/
|
|
13
|
+
size?: number;
|
|
14
|
+
storageClass?: string;
|
|
15
|
+
}
|
|
16
|
+
interface SignedReadUrlOptions {
|
|
17
|
+
expiresIn?: number;
|
|
18
|
+
responseContentDisposition?: string;
|
|
19
|
+
responseContentType?: string;
|
|
20
|
+
}
|
|
21
|
+
interface SignedUploadUrlOptions {
|
|
22
|
+
contentLength?: number;
|
|
23
|
+
contentType?: string;
|
|
24
|
+
expiresIn?: number;
|
|
25
|
+
}
|
|
26
|
+
interface ListOptions {
|
|
27
|
+
limit?: number;
|
|
28
|
+
prefix?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Provider-agnostic metadata-only view of an object.
|
|
32
|
+
*/
|
|
33
|
+
interface FileObject {
|
|
34
|
+
contentType: string;
|
|
35
|
+
etag?: string;
|
|
36
|
+
key: string;
|
|
37
|
+
lastModified?: Date | number | string;
|
|
38
|
+
metadata?: Record<string, unknown>;
|
|
39
|
+
size?: number;
|
|
40
|
+
}
|
|
41
|
+
interface DownloadResult extends FileObject {
|
|
42
|
+
body: Buffer;
|
|
43
|
+
}
|
|
44
|
+
interface FilesOptions<TStorage extends BaseStorage = BaseStorage> {
|
|
45
|
+
adapter: TStorage;
|
|
46
|
+
/**
|
|
47
|
+
* Default {@link OperationOptions} (`signal`, `timeout`, `retries`) merged into every call.
|
|
48
|
+
* Per-call overrides win. The `signal` is combined with any per-call `signal` via
|
|
49
|
+
* `AbortSignal.any`, so either one aborts the operation.
|
|
50
|
+
*/
|
|
51
|
+
defaults?: OperationOptions;
|
|
52
|
+
/**
|
|
53
|
+
* Namespace every key under this prefix. Reads, writes, copies, listings, URLs, and signed
|
|
54
|
+
* uploads all resolve keys as `${prefix}/${key}`; returned keys (including from `list()`) have
|
|
55
|
+
* the prefix stripped back off. Leading/trailing slashes are normalized so `"/users/"` and
|
|
56
|
+
* `"users"` behave identically.
|
|
57
|
+
*
|
|
58
|
+
* `list()` scopes results on a path boundary, so `prefix: "users"` never matches the sibling
|
|
59
|
+
* `users-archive/`.
|
|
60
|
+
*/
|
|
61
|
+
prefix?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* One item in a bulk upload call.
|
|
65
|
+
*/
|
|
66
|
+
interface BulkUploadItem extends UploadOptions {
|
|
67
|
+
body: FileBody;
|
|
68
|
+
key: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Per-call options shared by every bulk method (`upload`, `download`, `head`, `exists`, `delete`).
|
|
72
|
+
*/
|
|
73
|
+
interface BulkOptions extends OperationOptions {
|
|
74
|
+
/**
|
|
75
|
+
* Maximum number of in-flight operations.
|
|
76
|
+
* @default 8
|
|
77
|
+
*/
|
|
78
|
+
concurrency?: number;
|
|
79
|
+
/**
|
|
80
|
+
* When `true`, stop dispatching new operations as soon as one fails. The already-issued
|
|
81
|
+
* operations still complete. Defaults to `false`: every key is attempted and per-key failures
|
|
82
|
+
* are collected in `errors`.
|
|
83
|
+
* @default false
|
|
84
|
+
*/
|
|
85
|
+
stopOnError?: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface BulkError {
|
|
88
|
+
error: Error;
|
|
89
|
+
key: string;
|
|
90
|
+
}
|
|
91
|
+
interface BulkUploadResult {
|
|
92
|
+
errors?: BulkError[];
|
|
93
|
+
uploaded: FileObject[];
|
|
94
|
+
}
|
|
95
|
+
interface BulkDownloadResult {
|
|
96
|
+
downloaded: DownloadResult[];
|
|
97
|
+
errors?: BulkError[];
|
|
98
|
+
}
|
|
99
|
+
interface BulkHeadResult {
|
|
100
|
+
errors?: BulkError[];
|
|
101
|
+
files: FileObject[];
|
|
102
|
+
}
|
|
103
|
+
interface BulkExistsResult {
|
|
104
|
+
errors?: BulkError[];
|
|
105
|
+
existing: string[];
|
|
106
|
+
missing: string[];
|
|
107
|
+
}
|
|
108
|
+
interface BulkDeleteResult {
|
|
109
|
+
deleted: string[];
|
|
110
|
+
errors?: BulkError[];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Provider-agnostic facade over a {@link BaseStorage} instance.
|
|
114
|
+
*
|
|
115
|
+
* Provides a small, consistent surface (`upload`, `download`, `head`, `exists`, `delete`, `copy`,
|
|
116
|
+
* `list`, `url`, `signedUploadUrl`) and a `raw` escape hatch to the adapter's native client.
|
|
117
|
+
*
|
|
118
|
+
* Each operation accepts per-call `signal`, `timeout`, and `retries` via {@link OperationOptions};
|
|
119
|
+
* defaults set on the constructor are merged in (per-call wins). Single-key methods also accept an
|
|
120
|
+
* array of keys (or {@link BulkUploadItem}s for `upload`) to run a bounded-concurrency batch and
|
|
121
|
+
* return a structured `{ ..., errors? }` result instead of throwing on partial failure.
|
|
122
|
+
*
|
|
123
|
+
* When constructed with a `prefix`, every key is resolved relative to the prefix and the prefix is
|
|
124
|
+
* stripped back off the keys returned in results — application code works in its own namespace.
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* import { Files, S3Storage } from "@visulima/storage";
|
|
128
|
+
*
|
|
129
|
+
* const files = new Files({
|
|
130
|
+
* adapter: new S3Storage({ bucket: "uploads", region: "us-east-1" }),
|
|
131
|
+
* prefix: "users",
|
|
132
|
+
* defaults: { timeout: 30_000 },
|
|
133
|
+
* });
|
|
134
|
+
*
|
|
135
|
+
* await files.upload("123/avatar.png", buffer, { contentType: "image/png" });
|
|
136
|
+
* const head = await files.head("123/avatar.png"); // reads users/123/avatar.png
|
|
137
|
+
* const url = await files.url("123/avatar.png", { expiresIn: 900 });
|
|
138
|
+
*
|
|
139
|
+
* const { uploaded, errors } = await files.upload([
|
|
140
|
+
* { key: "a.png", body: a, contentType: "image/png" },
|
|
141
|
+
* { key: "b.png", body: b },
|
|
142
|
+
* ], { concurrency: 4 });
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
declare class Files<TStorage extends BaseStorage = BaseStorage> {
|
|
146
|
+
readonly adapter: TStorage;
|
|
147
|
+
private readonly defaults;
|
|
148
|
+
private readonly prefix;
|
|
149
|
+
constructor(options: FilesOptions<TStorage>);
|
|
150
|
+
/**
|
|
151
|
+
* Escape hatch to the adapter's native client (S3Client, BlobServiceClient, ...).
|
|
152
|
+
* Typed via the `TStorage` parameter, so pinning the adapter type at construction yields a
|
|
153
|
+
* typed view of the native client. Returns `undefined` when the adapter has no native client
|
|
154
|
+
* (e.g. DiskStorage).
|
|
155
|
+
*/
|
|
156
|
+
get raw(): TStorage["raw"];
|
|
157
|
+
/** Resolve a caller-supplied key into the underlying storage key. */
|
|
158
|
+
private resolveKey;
|
|
159
|
+
/**
|
|
160
|
+
* Strip the constructor prefix off a key returned by the adapter. Returns `null` when the key
|
|
161
|
+
* is outside the prefix or is the bare prefix itself (used to filter `list()` results on a path
|
|
162
|
+
* boundary and drop any synthetic directory entry the adapter may emit).
|
|
163
|
+
*/
|
|
164
|
+
private stripPrefix;
|
|
165
|
+
private mergeOptions;
|
|
166
|
+
/**
|
|
167
|
+
* Upload a single object, or — when passed an array of {@link BulkUploadItem}s — bulk-upload
|
|
168
|
+
* many in one call with bounded concurrency.
|
|
169
|
+
*/
|
|
170
|
+
upload(key: string, body: FileBody, options?: OperationOptions & UploadOptions): Promise<FileObject>;
|
|
171
|
+
upload(items: BulkUploadItem[], options?: BulkOptions): Promise<BulkUploadResult>;
|
|
172
|
+
private uploadOne;
|
|
173
|
+
private uploadMany;
|
|
174
|
+
/**
|
|
175
|
+
* Download a single object, or — when passed an array of keys — bulk-download many in one
|
|
176
|
+
* call with bounded concurrency.
|
|
177
|
+
*/
|
|
178
|
+
download(key: string, options?: OperationOptions): Promise<DownloadResult>;
|
|
179
|
+
download(keys: string[], options?: BulkOptions): Promise<BulkDownloadResult>;
|
|
180
|
+
private downloadOne;
|
|
181
|
+
private downloadMany;
|
|
182
|
+
/**
|
|
183
|
+
* Fetch metadata for a single object, or — when passed an array of keys — bulk-head many in
|
|
184
|
+
* one call with bounded concurrency.
|
|
185
|
+
*/
|
|
186
|
+
head(key: string, options?: OperationOptions): Promise<FileObject>;
|
|
187
|
+
head(keys: string[], options?: BulkOptions): Promise<BulkHeadResult>;
|
|
188
|
+
private headOne;
|
|
189
|
+
private headMany;
|
|
190
|
+
/**
|
|
191
|
+
* Resolves to `true`/`false` for a single key, or — when passed an array — splits the keys
|
|
192
|
+
* into `existing` and `missing` arrays. Hard errors (auth, transport) are reported in
|
|
193
|
+
* `errors`. Never throws for a missing object.
|
|
194
|
+
*/
|
|
195
|
+
exists(key: string, options?: OperationOptions): Promise<boolean>;
|
|
196
|
+
exists(keys: string[], options?: BulkOptions): Promise<BulkExistsResult>;
|
|
197
|
+
private existsOne;
|
|
198
|
+
private existsMany;
|
|
199
|
+
/**
|
|
200
|
+
* Delete a single object (resolves to `void`, throws on failure), or — when passed an array
|
|
201
|
+
* of keys — delete many in one call. Adapters with a native bulk-delete primitive (S3's
|
|
202
|
+
* `DeleteObjects`, Supabase's `remove`, UploadThing's `deleteFiles`) use it via
|
|
203
|
+
* {@link BaseStorage.deleteBatch}; otherwise the keys are fanned out with bounded concurrency.
|
|
204
|
+
*/
|
|
205
|
+
delete(key: string, options?: OperationOptions): Promise<void>;
|
|
206
|
+
delete(keys: string[], options?: BulkOptions): Promise<BulkDeleteResult>;
|
|
207
|
+
private deleteOne;
|
|
208
|
+
private deleteMany;
|
|
209
|
+
/**
|
|
210
|
+
* Copy `source` to `destination` (both resolved under any constructor prefix). Returns the
|
|
211
|
+
* destination object's metadata with the caller-facing (un-prefixed) key.
|
|
212
|
+
*/
|
|
213
|
+
copy(source: string, destination: string, options?: OperationOptions & {
|
|
214
|
+
storageClass?: string;
|
|
215
|
+
}): Promise<FileObject>;
|
|
216
|
+
/**
|
|
217
|
+
* List objects in the bucket. Returned keys have any constructor prefix stripped off, and
|
|
218
|
+
* keys outside the prefix namespace (e.g. `users-archive/` when prefix is `users`) are filtered
|
|
219
|
+
* out. The optional `prefix` filter is interpreted *relative to the constructor prefix*.
|
|
220
|
+
*
|
|
221
|
+
* **Caveat with constructor prefix**: `limit` is applied by the underlying adapter *before*
|
|
222
|
+
* the path-boundary filter runs, so the returned array may contain fewer than `limit` items
|
|
223
|
+
* even when more in-namespace objects exist. Page through with adapter-specific APIs when you
|
|
224
|
+
* need an exact in-namespace count.
|
|
225
|
+
*/
|
|
226
|
+
list(options?: ListOptions & OperationOptions): Promise<FileObject[]>;
|
|
227
|
+
url(key: string, options?: OperationOptions & SignedReadUrlOptions): Promise<string>;
|
|
228
|
+
signedUploadUrl(key: string, options?: OperationOptions & SignedUploadUrlOptions): Promise<string>;
|
|
229
|
+
}
|
|
230
|
+
export { BulkDeleteResult as B, DownloadResult as D, Files as F, ListOptions as L, SignedReadUrlOptions as S, UploadOptions as U, BulkDownloadResult as a, BulkError as b, BulkExistsResult as c, BulkHeadResult as d, BulkOptions as e, BulkUploadItem as f, BulkUploadResult as g, FileBody as h, FileObject as i, FilesOptions as j, SignedUploadUrlOptions as k };
|
package/dist/packem_shared/{local-meta-storage.d-B11vHYNm.d.ts → local-meta-storage.d-qZQI1JUe.d.ts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as File, L as LocalMetaStorageOptions, M as MetaStorage } from "./storage.d-
|
|
1
|
+
import { F as File, L as LocalMetaStorageOptions, M as MetaStorage } from "./storage.d-BoJgdi1n.js";
|
|
2
2
|
import 'node:stream';
|
|
3
3
|
/**
|
|
4
4
|
* Stores upload metafiles on local disk
|
package/dist/packem_shared/{media-transformer.d-C3QvECD7.d.ts → media-transformer.d-lQ_RUjb5.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as File, a as FileReturn, B as BaseStorage } from "./storage.d-
|
|
2
|
-
import {
|
|
1
|
+
import { F as File, a as FileReturn, B as BaseStorage } from "./storage.d-BoJgdi1n.js";
|
|
2
|
+
import { O as MediaTransformerConfig, Q as MediaTransformResult } from "./types.d-DCPQvHDI.js";
|
|
3
3
|
/**
|
|
4
4
|
* Unified media transformer that automatically detects media type and routes to appropriate transformer.
|
|
5
5
|
* @template TFile The file type used by this transformer.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var E=Object.defineProperty;var y=(a,t)=>E(a,"name",{value:t,configurable:!0});import{n as u}from"./headers-DC2MEOrK.js";import{hasBody as X}from"type-is";import{a as c}from"./base-handler-core-
|
|
1
|
+
var E=Object.defineProperty;var y=(a,t)=>E(a,"name",{value:t,configurable:!0});import{n as u}from"./headers-DC2MEOrK.js";import{hasBody as X}from"type-is";import{a as c}from"./base-handler-core-Cwd9uq_E.js";import{ERRORS as A}from"./ERRORS-CyOuSMLY.js";import{b,a as z,c as v,d as L}from"./response-builder-Wdo_fvcF.js";var T=Object.defineProperty,f=y((a,t)=>T(a,"name",{value:t,configurable:!0}),"a$1");const D=f((a,t={})=>{const e=c(a,"x-file-metadata",!0);if(!e)return t;try{return{...t,...JSON.parse(e)}}catch{return t}},"parseMetadata"),P=f(a=>{if(!a)return;const t=2e3,e=a.length>t?a.slice(0,Math.max(0,t)):a,r=e.toLowerCase().indexOf("filename");if(r===-1)return;let s=r+8;for(;s<e.length&&(e[s]==="*"||e[s]===" "||e[s]===" ");)s++;if(s>=e.length||e[s]!=="=")return;for(s++;s<e.length&&(e[s]===" "||e[s]===" ");)s++;if(s>=e.length)return;let n=s,o;const i=e[s];return i==='"'||i==="'"?(n=s+1,o=e.indexOf(i,n),o===-1&&(o=e.indexOf(";",n),o===-1&&(o=e.length))):(o=e.indexOf(";",n),o===-1&&(o=e.length)),n>=o?void 0:e.substring(n,o).trim()||void 0},"parseContentDispositionValue"),I=f(a=>{const t=c(a,"content-disposition",!0);return P(t)},"parseContentDisposition"),R=f(a=>{const t=c(a,"x-chunked-upload",!0)==="true",e=c(a,"x-chunk-offset",!0),r=c(a,"x-total-size",!0),s={isChunkedUpload:t};if(e){const n=Number.parseInt(e,10);!Number.isNaN(n)&&n>=0&&(s.chunkOffset=n)}if(r){const n=Number.parseInt(r,10);!Number.isNaN(n)&&n>0&&(s.totalSize=n)}return s},"parseChunkHeaders"),Z=f((a,t=!1)=>{const e=c(a,"x-chunked-upload",!0)==="true";if(!(t&&e)){if(!X(a))throw u(400,"Request body is required");if(Number.parseInt(c(a,"content-length")||"0",10)===0&&!e)throw u(400,"Content-Length is required and must be greater than 0")}},"validateRequestBody"),ee=f((a,t=!1,e)=>{const r=c(a,"x-chunked-upload",!0)==="true",s=Number.parseInt(c(a,"content-length")||"0",10);if(!t&&!r&&s===0)throw u(400,"Content-Length is required and must be greater than 0");if(e!==void 0&&s>e)throw u(413,`File size exceeds maximum allowed size of ${e} bytes`);return s},"validateContentLength"),te=f((a,t,e="application/octet-stream")=>{const r=I(a),s=D(a),{isChunkedUpload:n,totalSize:o}=R(a),i=n&&o?o:t;return n&&o&&(s._chunkedUpload=!0,s._chunks=[],s._totalSize=o),{contentType:e,metadata:s,originalName:r,size:i}},"extractFileInit");f((a,t,e)=>{if(Number.isNaN(a)||a<0)throw u(400,"X-Chunk-Offset must be a valid non-negative number");if(a+t>e)throw u(400,`Chunk exceeds file size. Offset: ${a}, Size: ${t}, Total: ${e}`)},"validateChunk");f((a,t="application/octet-stream")=>c(a,"content-type")||t,"getContentType");var W=Object.defineProperty,g=y((a,t)=>W(a,"name",{value:t,configurable:!0}),"a");const N=g((a,t)=>{if(a.length===0)return!1;const e=[...a].toSorted((n,o)=>n.offset-o.offset),r=e[0];if(r?.offset!==0)return!1;let s=r.length;for(let n=1;n<e.length;n+=1){const o=e[n];if(o){if(o.offset>s)return!1;s=Math.max(s,o.offset+o.length)}}return s>=t},"isUploadComplete"),H=g((a,t,e,r)=>{if(Number.isNaN(a)||a<0)throw new Error("Chunk offset must be a valid non-negative number");if(t<=0)throw new Error("Chunk length must be greater than 0");if(r!==void 0&&t>r)throw new Error(`Chunk size exceeds maximum allowed size of ${r} bytes`);if(a+t>e)throw new Error(`Chunk exceeds file size. Offset: ${a}, Size: ${t}, Total: ${e}`)},"validateChunk"),B=g((a,t)=>{const e=a.find(r=>r.offset===t.offset&&r.length===t.length);return e?t.checksum&&e.checksum!==t.checksum?a.map(r=>r.offset===t.offset?{...r,checksum:t.checksum}:r):a:[...a,t]},"trackChunk"),j=g((a,t)=>{if(a.length===0||t===0)return{bytesWritten:0,percentage:0};const e=[...a].toSorted((o,i)=>o.offset-i.offset);let r=0,s=0;for(const o of e){const i=o.offset+o.length;o.offset<=s?r=Math.max(r,i):r+=o.length,s=Math.max(s,i)}r=Math.min(r,t);const n=t>0?r/t*100:0;return{bytesWritten:r,percentage:n}},"calculateUploadProgress");g(a=>{const t=a.metadata||{};if(t._chunkedUpload===!0&&Array.isArray(t._chunks)){const e=typeof t._totalSize=="number"?t._totalSize:a.size||0;return j(t._chunks,e).bytesWritten}return a.bytesWritten||0},"getBytesWritten");const _=g(a=>(a.metadata||{})._chunkedUpload===!0,"isChunkedUpload"),U=g(a=>{const t=a.metadata||{};if(t._chunkedUpload===!0&&typeof t._totalSize=="number")return t._totalSize},"getTotalSize");var q=Object.defineProperty,$=y((a,t)=>q(a,"name",{value:t,configurable:!0}),"y");class ae{static{y(this,"M")}static{$(this,"RestBase")}async deleteSingle(t){const e=await this.storage.delete({id:t});if(e.status===void 0)throw u(404,"File not found");return{...e,headers:{},statusCode:204}}async handlePost(t,e,r,s,n){if(e&&t.size!==void 0){const d=typeof t.size=="number"?t.size:Number.parseInt(String(t.size),10);if(d>0&&d>this.storage.maxUploadSize)throw u(413,`File size exceeds maximum allowed size of ${this.storage.maxUploadSize} bytes`)}const o=await this.storage.create(t);if(e){const d=this.buildFileUrl(r,o);return b(o,{...z(o,d),"X-Chunked-Upload":"true","X-Upload-ID":o.id},201)}const i=await this.storage.write({body:s,contentLength:n,id:o.id,start:0}),h=this.buildFileUrl(r,i);return b(i,z(i,h),201)}async handlePut(t,e,r,s,n,o){let i,h=!1;try{await this.storage.getMeta(t),h=!0,o&&await this.storage.update({id:t},{metadata:o}),i=await this.storage.write({body:s,contentLength:n,id:t,start:0})}catch(m){const S=m;if(S.UploadErrorCode===A.FILE_NOT_FOUND||S.code==="ENOENT")try{const w=await this.storage.create(e);i=await this.storage.write({body:s,contentLength:n,id:w.id,start:0})}catch(w){throw w}else throw m}const d=this.buildFileUrl(r,i);return b(i,z(i,d),h?200:201)}async handlePatch(t,e,r,s,n,o){let i=await this.storage.getMeta(t);const h=i.metadata||{},d=_(i);if(d){const l=U(i);l&&i.size!==l&&(i={...i,size:l})}const m=typeof h._totalSize=="number"?h._totalSize:i.size||0;if(!d)throw u(400,"File is not a chunked upload. Use POST or PUT for full file uploads.");const S=100*1024*1024;try{H(e,r,m,S)}catch(l){throw l instanceof Error&&l.message.includes("exceeds maximum")?u(413,l.message):u(400,l instanceof Error?l.message:String(l))}if(i.status==="completed"){const l=this.buildFileUrl(n,i);return b(i,{...z(i,l),"X-Upload-Complete":"true"},200)}const w=await this.storage.withLock(`chunks:${t}`,async()=>{const l=(await this.storage.getMeta(t)).metadata??{},M=Array.isArray(l._chunks)?l._chunks:[],x=B(M,{checksum:s,length:r,offset:e});return await this.storage.update({id:t},{metadata:{...l,_chunks:x}}),x});let p=await this.storage.write({body:o,contentLength:r,id:t,start:e}),C=p.bytesWritten>=m;d&&(C=N(w,m),p.status==="completed"&&!C&&(await this.storage.update({id:t},{status:"part"}),p={...p,status:"part"}));const k=C&&p.bytesWritten!==m?{...p,bytesWritten:m}:p,F=this.buildFileUrl(n,k),O={...z(k,F),...v(k,C),"x-upload-offset":String(k.bytesWritten||0)};return b(k,O,C?200:202)}async handleHead(t){let e=await this.storage.getMeta(t);const r=_(e);if(r){const n=U(e);n&&e.size!==n&&(e={...e,size:n})}const s={...L(e)};if(r){const n=e.metadata||{},o=U(e)||e.size||0,i=Array.isArray(n._chunks)?n._chunks:[],h=N(i,o);Object.assign(s,v(e,h))}return b(e,s,200)}handleOptions(t,e){return{headers:{"Access-Control-Allow-Headers":"Authorization, Content-Type, Content-Length, Content-Disposition, X-File-Metadata, X-Chunked-Upload, X-Total-Size, X-Chunk-Offset, X-Chunk-Checksum","Access-Control-Allow-Methods":t.map(r=>r.toUpperCase()).join(", "),"Access-Control-Max-Age":86400,"X-Max-Upload-Size":String(e)},statusCode:204}}async deleteBatch(t){const e=await this.storage.deleteBatch(t);if(e.successfulCount===0&&e.failedCount>0){const r=e.failed.map(s=>s.id).join(", ");throw u(404,`Failed to delete files: ${r}`)}return{data:e.successful,headers:e.failedCount>0?{"X-Delete-Errors":JSON.stringify(e.failed),"X-Delete-Failed":String(e.failedCount),"X-Delete-Successful":String(e.successfulCount)}:{"X-Delete-Successful":String(e.successfulCount)},statusCode:e.successfulCount===t.length?204:207}}get storage(){throw new Error("storage must be implemented")}buildFileUrl(t,e){throw new Error("buildFileUrl must be implemented")}}export{ae as M,ee as a,R as b,P as c,te as e,I as p,Z as v};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var O=Object.defineProperty;var g=(c,t)=>O(c,"name",{value:t,configurable:!0});import{Readable as b}from"node:stream";import{z as C,B as M,$ as A,t as T}from"./storage-
|
|
1
|
+
var O=Object.defineProperty;var g=(c,t)=>O(c,"name",{value:t,configurable:!0});import{Readable as b}from"node:stream";import{z as C,B as M,$ as A,t as T}from"./storage-B-NDsI-o.js";import{d as I}from"./detect-file-type-5JhzC9RU.js";import{throwErrorCode as y,ERRORS as f}from"./ERRORS-CyOuSMLY.js";import{createRetryWrapper as R}from"./isRetryableError-BhizNeAz.js";import{v as k}from"./local-meta-storage-Bi0mK6gD.js";import{u as z}from"./update-size-DANV7aa2.js";import{r as v,o as P}from"./part-match-B5fLLmFw.js";import{o as x}from"./has-content-Bx2p8Okx.js";var B=Object.defineProperty,L=g((c,t)=>B(c,"name",{value:t,configurable:!0}),"o$1");const N=L((c,t)=>{const a={};return Object.keys(c).forEach(e=>{a[e]=t(c[e])}),a},"mapValues");var $=Object.defineProperty,K=g((c,t)=>$(c,"name",{value:t,configurable:!0}),"t");const j=K(c=>c===Number(c)?c:(C(c)??0)/1e3,"toSeconds");var D=Object.defineProperty,w=g((c,t)=>D(c,"name",{value:t,configurable:!0}),"m");const F=5*1024*1024,W=16*1024*1024;class S extends M{static{g(this,"S3BaseStorage")}static{w(this,"S3BaseStorage")}checksumTypes=["md5","crc32","crc32c","sha1","sha256"];bucket;meta;MAX_PARTS=1e4;partSize;retry;resolvedRetryConfig;constructor(t){if(super(t),this.bucket=t.bucket,this.partSize=typeof t.partSize=="string"?A(t.partSize):t.partSize||W,this.partSize<F)throw new Error("Minimum allowed partSize value is 5MB");const a={backoffMultiplier:2,initialDelay:1e3,maxDelay:3e4,maxRetries:3,retryableStatusCodes:[408,429,500,502,503,504],shouldRetry:w(i=>{const s=i;return s.statusCode&&[408,429,500,502,503,504].includes(s.statusCode)?!0:s.retryable??!1},"shouldRetry"),...t.retryConfig};this.retry=R(a),this.resolvedRetryConfig=a;const{metaStorage:e,metaStorageConfig:r}=t;if(e)this.meta=e;else{const i={...t,...r,logger:this.logger};"directory"in i?(this.logger?.debug("Using local meta storage"),this.meta=new k(i)):this.meta=new k(i)}this.isReady=!1,this.accessCheck().then(()=>{this.isReady=!0}).catch(i=>{this.logger?.error("Storage access check failed: %O",i)})}getRetryConfig(){return this.resolvedRetryConfig}async create(t,a){return this.instrumentOperation("create",async()=>{const e={...t};if(t.ttl){const n=typeof t.ttl=="string"?T(t.ttl):t.ttl;n!==void 0&&(e.expiredAt=Date.now()+n)}const r=new(this.getFileClass())(e);r.name=this.namingFunction(r),await this.validate(r);try{const n=await this.getMeta(r.id);if(n.bytesWritten>=0)return n}catch{}const i=this.getS3Api();let s;try{s=await this.runOperation(a,n=>i.createMultipartUpload({ACL:this.getAcl(),Bucket:this.bucket,ContentType:r.contentType,Key:r.name,Metadata:N({originalName:r.originalName,...r.metadata},l=>encodeURI(String(l)))},{signal:n}))}catch{return y(f.FILE_ERROR,"s3 create upload error")}const{UploadId:o}=s||{};return o?(r.UploadId=o,r.bytesWritten=0,this.config.clientDirectUpload&&(r.partSize??=this.partSize),await this.saveMeta(r),r.status="created",await this.onCreate(r),this.config.clientDirectUpload?this.buildPresigned(r):r):y(f.FILE_ERROR,"s3 create upload error")})}async write(t,a){return this.instrumentOperation("write",async()=>{let e;if("contentType"in t&&"metadata"in t&&!("body"in t)&&!("start"in t)?e=t:(e=await this.getMeta(t.id),await this.checkIfExpired(e)),e.status==="completed")return e;if(typeof t.size=="number"&&t.size>0&&z(e,t.size),!v(t,e))return y(f.FILE_CONFLICT);if(this.config.clientDirectUpload)return this.buildPresigned(e);e.Parts??=await this.getParts(e),e.bytesWritten=e.Parts.map(i=>i.Size||0).reduce((i,s)=>i+s,0);const r=await this.lock(t.id);try{if(x(t)){if(this.isUnsupportedChecksum(t.checksumAlgorithm))return y(f.UNSUPPORTED_CHECKSUM_ALGORITHM);if(e.Parts.length===0&&(!e.contentType||e.contentType==="application/octet-stream"))try{const p=t.body instanceof b?t.body:b.fromWeb(t.body),{fileType:m,stream:u}=await I(p);m?.mime&&(e.contentType=m.mime),t.body=u}catch{}if(e.Parts.length>this.MAX_PARTS)throw new Error(`Exceeded ${this.MAX_PARTS} as part of the upload to ${this.bucket}.`);const i=e.Parts.length+1,s=this.getS3Api(),o=e.UploadId;if(!o)throw new Error("UploadId is required");const n=t.body,l=n instanceof Uint8Array,{ETag:h}=await this.runOperation(a,p=>s.uploadPart({Body:n,Bucket:this.bucket,ContentLength:t.contentLength||0,Key:e.name,PartNumber:i,UploadId:o,...t.checksumAlgorithm==="md5"?{ContentMD5:t.checksum}:{}},{signal:p}),{replayable:l}),d={ETag:h,PartNumber:i,Size:t.contentLength};e.Parts=[...e.Parts,d],e.bytesWritten+=t.contentLength||0}if(this.cache.set(e.id,e),e.status=P(e),e.status==="completed"){const[i]=await this.internalOnComplete(e);delete e.Parts,e.uri=i.Location,e.ETag=i.ETag}}finally{await this.unlock(t.id,r)}return e})}async delete({id:t},a){return this.instrumentOperation("delete",async()=>{const e=await this.getMeta(t);e.status="deleted",await this.abortMultipartUpload(e,a),await this.deleteMeta(e.id);const r={...e};return await this.onDelete(r),r})}async copy(t,a,e){return this.instrumentOperation("copy",async()=>{S.assertSafeId(t),S.assertSafeId(a);const r=await this.getMeta(t),i=`${this.bucket}/${t}`,s=this.bucket,o=a,n=this.getS3Api();return await this.runOperation(e,l=>n.copyObject({Bucket:s,CopySource:i,Key:o,...e?.storageClass&&{StorageClass:e.storageClass}},{signal:l})),{...r,id:o,name:o}})}async move(t,a,e){return this.instrumentOperation("move",async()=>{await this.copy(t,a,e);const r=this.getS3Api();return await this.runOperation(e,i=>r.deleteObject({Bucket:this.bucket,Key:t},{signal:i})),await this.getMeta(a)})}async list(t=1e3,a){return this.instrumentOperation("list",async()=>{const e=this.getS3Api(),r=Math.min(t,1e3);let i={Bucket:this.bucket,MaxKeys:r};const s=[];let o=!0;for(;o&&s.length<t;)try{const n=await this.runOperation(a,l=>e.listObjectsV2(i,{signal:l}));for(const{Key:l,LastModified:h}of n?.Contents||[]){if(s.length>=t)break;l!==void 0&&s.push({id:l,...h&&{createdAt:h}})}o=n.IsTruncated||!1,o&&n.NextContinuationToken&&s.length<t&&(i={...i,ContinuationToken:n.NextContinuationToken,MaxKeys:Math.min(r,t-s.length)})}catch(n){const l=this.normalizeError(n instanceof Error?n:new Error(String(n)));throw await this.onError(l),n}return s},{limit:t})}async exists({id:t},a){return this.instrumentOperation("exists",async()=>{try{await this.getMeta(t);const e=this.getS3Api();return await this.runOperation(a,r=>e.headObject({Bucket:this.bucket,Key:t},{signal:r})),!0}catch{return!1}})}async get({id:t},a){return this.instrumentOperation("get",async()=>{const e=this.getS3Api(),{Body:r,ContentLength:i,ContentType:s,ETag:o,Expires:n,LastModified:l,Metadata:h}=await this.runOperation(a,u=>e.getObject({Bucket:this.bucket,Key:t},{signal:u}));await this.checkIfExpired({expiredAt:n});const d=[];if(r)if(r instanceof b)for await(const u of r)d.push(u instanceof Uint8Array?u:new Uint8Array(u));else{const u=r.getReader();for(;;){const{done:U,value:E}=await u.read();if(U)break;d.push(E)}}const{originalName:p,...m}=h||{};return{content:Buffer.concat(d),contentType:s,ETag:o,expiredAt:n,id:t,metadata:m,modifiedAt:l,name:t,originalName:p||t,size:Number(i)}})}async buildPresigned(t){const a=t;if(a.Parts?.length||(a.Parts=await this.getParts(t)),a.bytesWritten=a.Parts.map(e=>e.Size||0).reduce((e,r)=>e+r,0),t.status=P(a),a.partsUrls?.length||(a.partsUrls=await this.getPartsPresignedUrls(t)),t.status==="completed"){const[e]=await this.internalOnComplete(t);return delete a.Parts,a.uri=e.Location,t}return t}async getPartsPresignedUrls(t){t.partSize??=this.partSize;const a=t.UploadId;if(!a)throw new Error("UploadId is required for getting presigned URLs");const e=Math.trunc(t.size/this.partSize)+1,r=[],i=Math.trunc(j(this.config.expiration?.maxAge||"6hrs")),s=this.getS3Api();for(let o=0;o<e;o++)r.push(s.getPresignedUrl({Bucket:this.bucket,expiresIn:i,Key:t.name,PartNumber:o+1,UploadId:a}));return Promise.all(r)}async getParts(t){const a=this.getS3Api(),e=t.UploadId;if(!e)throw new Error("UploadId is required");const{Parts:r=[]}=await this.runOperation(void 0,i=>a.listParts({Bucket:this.bucket,Key:t.name,UploadId:e},{signal:i}));return r}completeMultipartUpload(t){const a=this.getS3Api(),e=t.UploadId;if(!e)throw new Error("UploadId is required");const r=t.Parts?.map(({ETag:i,PartNumber:s})=>{if(!i||!s)throw new Error("ETag and PartNumber are required");return{ETag:i,PartNumber:s}})||[];return this.runOperation(void 0,i=>a.completeMultipartUpload({Bucket:this.bucket,Key:t.name,Parts:r,UploadId:e},{signal:i}))}async abortMultipartUpload(t,a){if(t.status!=="completed")try{const e=this.getS3Api(),r=t.UploadId;if(!r)return;await this.runOperation(a,i=>e.abortMultipartUpload({Bucket:this.bucket,Key:t.name,UploadId:r},{signal:i}))}catch(e){this.logger?.error("abortMultipartUploadError: ",e);const r=this.normalizeError(e instanceof Error?e:new Error(String(e)));await this.onError(r)}}internalOnComplete=w(async t=>{const[a]=await Promise.all([this.completeMultipartUpload(t),this.deleteMeta(t.id)]);return[a,t]},"internalOnComplete")}export{S};
|
package/dist/packem_shared/{s3-base-storage.d-V3N2nKCt.d.ts → s3-base-storage.d-CDIOMTpp.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
|
-
import { F as File, M as MetaStorage, d as createRetryWrapper, R as RetryConfig, e as FileInit, B as BaseStorage, O as OperationOptions, f as FilePart, g as FileQuery, a as FileReturn } from "./storage.d-
|
|
2
|
+
import { F as File, M as MetaStorage, d as createRetryWrapper, R as RetryConfig, e as FileInit, B as BaseStorage, O as OperationOptions, f as FilePart, g as FileQuery, a as FileReturn } from "./storage.d-BoJgdi1n.js";
|
|
3
3
|
/**
|
|
4
4
|
* Part interface for multipart uploads.
|
|
5
5
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var H=Object.defineProperty;var p=(t,e)=>H(t,"name",{value:e,configurable:!0});import{Readable as X}from"node:stream";import{setInterval as J}from"node:timers";import{inspect as Q}from"node:util";import{L as ee,O as I}from"./path-D7rMc9nq-B718mbm6.js";import te from"type-is";import re from"./NoOpMetrics-Dky06sf1.js";import{N as oe}from"./cache-qV_5Umeq.js";import{ErrorMap as M,throwErrorCode as E,ERRORS as $}from"./ERRORS-CyOuSMLY.js";import{randomUUID as se}from"node:crypto";import{LRUCache as ae}from"lru-cache";import{retry as ie}from"./isRetryableError-BhizNeAz.js";import{o as ne}from"./is-expired-1JuZjDtb.js";var ce=Object.defineProperty,le=p((t,e)=>ce(t,"name",{value:e,configurable:!0}),"y$3"),ue=Object.defineProperty,me=le((t,e)=>ue(t,"name",{value:e,configurable:!0}),"y"),ge=Object.defineProperty,C=me((t,e)=>ge(t,"name",{value:e,configurable:!0}),"i");const de=/^(?<value>-?\d+(?:[.,]\d+)*) *(?<type>[a-z]+)?$/i,he=/^KIBI/,pe=/^MIBI/,fe=/^GIBI/,ye=/^TEBI/,be=/^PEBI/,we=/^EXBI/,ve=/^ZEBI/,Ee=/^YIBI/,$e=/^(.)IB$/,_={iec:[{long:"Bytes",short:"B"},{long:"Kibibytes",short:"KiB"},{long:"Mebibytes",short:"MiB"},{long:"Gibibytes",short:"GiB"},{long:"Tebibytes",short:"TiB"},{long:"Pebibytes",short:"PiB"},{long:"Exbibytes",short:"EiB"},{long:"Zebibytes",short:"ZiB"},{long:"Yobibytes",short:"YiB"}],iec_octet:[{long:"Octets",short:"o"},{long:"Kibioctets",short:"Kio"},{long:"Mebioctets",short:"Mio"},{long:"Gibioctets",short:"Gio"},{long:"Tebioctets",short:"Tio"},{long:"Pebioctets",short:"Pio"},{long:"Exbioctets",short:"Eio"},{long:"Zebioctets",short:"Zio"},{long:"Yobioctets",short:"Yio"}],metric:[{long:"Bytes",short:"Bytes"},{long:"Kilobytes",short:"KB"},{long:"Megabytes",short:"MB"},{long:"Gigabytes",short:"GB"},{long:"Terabytes",short:"TB"},{long:"Petabytes",short:"PB"},{long:"Exabytes",short:"EB"},{long:"Zettabytes",short:"ZB"},{long:"Yottabytes",short:"YB"}],metric_octet:[{long:"Octets",short:"o"},{long:"Kilo-octets",short:"ko"},{long:"Mega-octets",short:"Mo"},{long:"Giga-octets",short:"Go"},{long:"Tera-octets",short:"To"},{long:"Peta-octets",short:"Po"},{long:"Exa-octets",short:"Eo"},{long:"Zetta-octets",short:"Zo"},{long:"Yotta-octets",short:"Yo"}]},xe=C((t,e)=>{const r=new Intl.NumberFormat(e).format(11111).replaceAll(new RegExp("\\p{Number}","gu"),""),o=new Intl.NumberFormat(e).format(1.1).replaceAll(new RegExp("\\p{Number}","gu"),"");return Number.parseFloat(t.replaceAll(new RegExp(`\\${r}`,"g"),"").replace(new RegExp(`\\${o}`),"."))},"parseLocalizedNumber"),R=C(t=>{switch(t){case 2:return 1024;case 10:return 1e3;default:throw new Error("Unsupported base.")}},"fromBase"),j=C((t,e)=>{const r={base:2,locale:"en-US",units:"metric",...e};if(typeof t!="string"||t.length===0)throw new TypeError("Value is not a string or is empty.");if(t.length>100)throw new TypeError("Value exceeds the maximum length of 100 characters.");const o=de.exec(t)?.groups;if(!o)return Number.NaN;const s=xe(o.value,r.locale),a=(o.type??"Bytes").toUpperCase().replace(he,"KILO").replace(pe,"MEGA").replace(fe,"GIGA").replace(ye,"TERA").replace(be,"PETA").replace(we,"EXA").replace(ve,"ZETTA").replace(Ee,"YOTTA").replace($e,"$1B"),i=_[r.units].findIndex(u=>u.short[0].toUpperCase()===a[0]),l=R(r.base);return s*l**i},"parseBytes");C((t,e)=>{if(typeof t!="number"||!Number.isFinite(t))throw new TypeError("Bytesize is not a number.");const{base:r,decimals:o,locale:s,long:a,unit:i,units:l,...u}={base:2,decimals:0,locale:"en-US",long:!1,units:"metric",...e},n=R(r),m=Math.abs(t),g=e?.space??!0?" ":"",c=_[l],d=c.findIndex(w=>w.short===i);if(t===0){const w=Math.min(0,Math.max(d,c.length-1));return"0"+g+c[w][a?"long":"short"]}const h=d===-1?Math.min(Math.floor(Math.log(m)/Math.log(n)),c.length-1):d,N=c[h][a?"long":"short"],O=t/n**h,v=o<0?void 0:o;return new Intl.NumberFormat(s,{maximumFractionDigits:v,minimumFractionDigits:v,...u}).format(O)+g+N},"formatBytes");var Me=Object.defineProperty,Ne=p((t,e)=>Me(t,"name",{value:e,configurable:!0}),"u$3"),Oe=Object.defineProperty,Ae=Ne((t,e)=>Oe(t,"name",{value:e,configurable:!0}),"v"),Te=Object.defineProperty,Ce=Ae((t,e)=>Te(t,"name",{value:e,configurable:!0}),"D");const Se=Ce((t,e,r,o,s,a,i,l,u,n,m,g,c,d)=>{const h={d:o,h:s,m:a,mo:e,ms:l,s:i,w:r,y:t};return u!==void 0&&(h.future=u),n!==void 0&&(h.past=n),m!==void 0&&(h.decimal=m),g!==void 0&&(h.unitMap=g),c!==void 0&&(h.groupSeparator=c),d!==void 0&&(h.placeholderSeparator=d),h},"createDurationLanguage"),F={d:"d",day:"d",days:"d",h:"h",hour:"h",hours:"h",hr:"h",hrs:"h",m:"m",millisecond:"ms",milliseconds:"ms",min:"m",mins:"m",minute:"m",minutes:"m",mo:"mo",month:"mo",months:"mo",ms:"ms",s:"s",sec:"s",second:"s",seconds:"s",secs:"s",w:"w",week:"w",weeks:"w",y:"y",year:"y",years:"y",yr:"y",yrs:"y"},Ie=Se(t=>`year${t===1?"":"s"}`,t=>`month${t===1?"":"s"}`,t=>`week${t===1?"":"s"}`,t=>`day${t===1?"":"s"}`,t=>`hour${t===1?"":"s"}`,t=>`minute${t===1?"":"s"}`,t=>`second${t===1?"":"s"}`,t=>`millisecond${t===1?"":"s"}`,"in %s","%s ago",".",F,",","_");var Be=Object.defineProperty,Pe=p((t,e)=>Be(t,"name",{value:e,configurable:!0}),"o"),De=Object.defineProperty,Ue=Pe((t,e)=>De(t,"name",{value:e,configurable:!0}),"o"),ze=Object.defineProperty,je=Ue((t,e)=>ze(t,"name",{value:e,configurable:!0}),"o");const ke=je(t=>{const e=["y","mo","w","d","h","m","s","ms","future","past"];for(const o of e)if(!Object.hasOwn(t,o))throw new TypeError(`Missing required property: ${o}`);if(typeof t.future!="string"||typeof t.past!="string")throw new TypeError("Properties future and past must be of type string");const r=["y","mo","w","d","h","m","s","ms"];for(const o of r)if(typeof t[o]!="string"&&typeof t[o]!="function")throw new TypeError(`Property ${o} must be of type string or function`);if(t.decimal&&typeof t.decimal!="string")throw new TypeError("Property decimal must be of type string");if(t.delimiter&&typeof t.delimiter!="string")throw new TypeError("Property delimiter must be of type string");if(t._digitReplacements&&!Array.isArray(t._digitReplacements))throw new TypeError("Property _digitReplacements must be an array");if(t._numberFirst&&typeof t._numberFirst!="boolean")throw new TypeError("Property _numberFirst must be of type boolean");if(t.unitMap&&typeof t.unitMap!="object")throw new TypeError("Property unitMap must be an object");if(t.unitMap&&Object.values(t.unitMap).some(o=>typeof o!="string"))throw new TypeError("All values in unitMap must be of type string")},"validateDurationLanguage");var _e=Object.defineProperty,Re=p((t,e)=>_e(t,"name",{value:e,configurable:!0}),"w"),Fe=Object.defineProperty,Le=Re((t,e)=>Fe(t,"name",{value:e,configurable:!0}),"S"),Ve=Object.defineProperty,Ge=Le((t,e)=>Ve(t,"name",{value:e,configurable:!0}),"h");const k={d:864e5,h:36e5,m:6e4,mo:2629746e3,ms:1,s:1e3,w:6048e5,y:31556952e3},A=/[-/\\^$*+?.()|[\]{}]/g,Ye=/^PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/i,Ze=/^(?:(\d+):)?(?:(\d+):)?(\d+)$/,Ke=/^[+-]?\d+(?:\.\d+)?$/,We=/^[-+]/,qe=Ge((t,e)=>{if(typeof t!="string"||t.length===0)return;const{defaultUnit:r="ms",language:o=Ie}=e??{};ke(o);const s=o.decimal??".",a=o.groupSeparator??",",i=o.placeholderSeparator??"_",l=s.replaceAll(A,String.raw`\$&`),u=a.replaceAll(A,String.raw`\$&`),n=i.replaceAll(A,String.raw`\$&`),m=o.unitMap??F;let g=t.replaceAll(new RegExp(String.raw`(\d)[${n}${u}](\d)`,"g"),"$1$2");if(s!=="."&&(g=g.replace(l,".")),Ke.test(t)){const f=Number.parseFloat(g.trim());if(!Number.isNaN(f)){const y=m[r];if(y!==void 0)return f*k[y]}return}const c=Ye.exec(t);if(c){const f=Number.parseInt(c[1]??"0",10),y=Number.parseInt(c[2]??"0",10),x=Number.parseInt(c[3]??"0",10);return f*36e5+y*6e4+x*1e3}const d=Ze.exec(t);if(d){let f=0,y=0;d[2]!==void 0?(f=Number.parseInt(d[1]??"0",10),y=Number.parseInt(d[2],10)):d[1]!==void 0&&(y=Number.parseInt(d[1],10));const x=Number.parseInt(d[3]??"0",10);return f*36e5+y*6e4+x*1e3}const h=Object.keys(m).toSorted((f,y)=>y.length-f.length).map(f=>f.replaceAll(A,String.raw`\$&`)).join("|"),N=new RegExp(String.raw`(-?\d*\.?\d+)\s*(${h})`,"gi");let O=0,v,w=!1,P=-1,D=0;for(N.lastIndex=0;(v=N.exec(g))!==null;){w||(P=v.index),w=!0;const f=v[1],y=v[2];if(!f||!y)continue;const x=f.trim(),K=x.startsWith("-")?-1:1,W=x.replace(We,""),U=Number.parseFloat(W),z=m[y.toLowerCase()];if(z===void 0)continue;const q=k[z];if(Number.isNaN(U))return;O+=K*U*q,D=N.lastIndex}const Y=g.slice(0,P).trim(),Z=g.slice(D).trim();if(!(w&&(Y.length>0||Z.length>0))&&w)return O},"parseDuration");var He=Object.defineProperty,Xe=p((t,e)=>He(t,"name",{value:e,configurable:!0}),"n$1");let Je=class extends ae{static{p(this,"u")}static{Xe(this,"Locker")}constructor(e){super({ttl:3e4,ttlAutopurge:!0,...e})}lock(e){if(this.get(e)!==void 0)throw new Error(`${e} is locked`);const r=se();return this.set(e,r),r}unlock(e,r){return this.get(e)!==r?!1:this.delete(e)}};var Qe=Object.defineProperty,et=p((t,e)=>Qe(t,"name",{value:e,configurable:!0}),"e$1");const T=et(t=>{if(t===Number(t))return t;if(!t)return;const e=qe(t);if(e!==void 0)return e},"toMilliseconds");var tt=Object.defineProperty,rt=p((t,e)=>tt(t,"name",{value:e,configurable:!0}),"t");let ot=class extends Error{static{p(this,"d")}static{rt(this,"ValidationError")}code;statusCode;body;headers;name="ValidationError";constructor(e,r,o,s){const a=typeof o=="string"?o:o?.message||"Validation error";super(a),this.code=e,this.statusCode=r,this.body=o,this.headers=s}};var st=Object.defineProperty,S=p((t,e)=>st(t,"name",{value:e,configurable:!0}),"e");const at=S(t=>t&&t[0].toUpperCase()+t.slice(1),"capitalize"),it=S(t=>{if(!Array.isArray(t))return t;const[e,r,o]=t;return{body:r,headers:o,statusCode:e}},"toResponse");class nt{static{p(this,"Validator")}constructor(e="ValidationError"){this.prefix=e}prefix;static{S(this,"Validator")}validators={};add(e){Object.entries(e).forEach(([r,o])=>{const s=`${this.prefix}${at(r)}`;if(this.validators[s]={...this.validators[s],...o},typeof this.validators[s].isValid!="function")throw new TypeError('Validation config "isValid" is missing, or it is not a function!')})}async verify(e){for(const[r,o]of Object.entries(this.validators))if(!await o.isValid(e)){const s=o.response||(r in M?M[r]:M.UnknownError),a=it(s),{body:i,headers:l,message:u,statusCode:n}=a;throw new ot(r,n,i||u,l)}}}const St=S(t=>t.name==="ValidationError","isValidationError");var ct=Object.defineProperty,B=p((t,e)=>ct(t,"name",{value:e,configurable:!0}),"i");const lt=B(t=>{if(typeof t.name=="string")return t.name;if(typeof t.title=="string")return t.title;if(typeof t.originalName=="string")return t.originalName;if(typeof t.filename=="string")return t.filename},"extractOriginalName"),L=B((t,e)=>{const r={...t};return Object.keys(e).forEach(o=>{const s=e[o];if(s!==null&&typeof s=="object"&&!Array.isArray(s)){const a=r[o],i=a&&typeof a=="object"&&!Array.isArray(a)?a:{};r[o]=L(i,s)}else r[o]=s}),r},"deepMerge"),ut=B((t,e)=>{const r=L(t,e);Object.assign(t,r),t.originalName=lt(t.metadata)||t.originalName},"updateMetadata");var mt=Object.defineProperty,b=p((t,e)=>mt(t,"name",{value:e,configurable:!0}),"d");const gt=/(secret|password|passwd|pwd|token|api[_-]?key|credential|authorization|sas|signature|sessiontoken|connectionstring)/i,V=b(t=>{const e={};for(const[r,o]of Object.entries(t))typeof o=="string"&>.test(r)?e[r]="[REDACTED]":o&&typeof o=="object"&&!Array.isArray(o)&&o.constructor===Object?e[r]=V(o):e[r]=o;return e},"redactSecrets"),dt={allowMIME:["*/*"],filename:b(({id:t})=>t,"filename"),maxMetadataSize:"8MB",maxUploadSize:"5TB",onComplete:b(()=>{},"onComplete"),onCreate:b(()=>{},"onCreate"),onDelete:b(()=>{},"onDelete"),onError:b(()=>{},"onError"),onUpdate:b(()=>{},"onUpdate"),useRelativeLocation:!1,validation:{}},ht=b(t=>!t||t.length<3||t.length>255||I(t)?!1:!(t.toUpperCase().includes("../")||t.includes("\0")),"defaultCloudStorageFileNameValidation"),It=b(t=>{if(!t||t.length<3||t.length>255||I(t))return!1;const e=t.toUpperCase();return!['"',"*",":","<",">","?","\\","|","../","\0"].some(r=>e.includes(r))},"defaultFilesystemFileNameValidation");class G{static{p(this,"BaseStorage")}static{b(this,"BaseStorage")}onCreate;onUpdate;onComplete;onDelete;onError;isReady=!0;errorResponses={};cache;logger;metrics;genericConfig;maxMetadataSize;checksumTypes=[];maxUploadSize;expiration;locker;namingFunction;validation=new nt;assetFolder=void 0;concurrency;constructor(e){const r={...dt,...e};this.onCreate=r.onCreate,this.onUpdate=r.onUpdate,this.onComplete=r.onComplete,this.onDelete=r.onDelete,this.onError=r.onError,this.namingFunction=r.filename,this.maxUploadSize=typeof r.maxUploadSize=="string"?j(r.maxUploadSize):r.maxUploadSize,this.maxMetadataSize=typeof r.maxMetadataSize=="string"?j(r.maxMetadataSize):r.maxMetadataSize,this.expiration=r.expiration,this.genericConfig=r,r.assetFolder!==void 0&&(this.assetFolder=ee(r.assetFolder)),this.locker=new Je({max:1e3,ttl:3e4,ttlAutopurge:!0}),this.cache=r.cache??new oe,this.logger=r.logger,this.metrics=r.metrics??new re,this.logger?.debug(`${this.constructor.name} config: ${Q(V({...e,logger:this.logger.constructor}))}`);const o=T(r.expiration?.purgeInterval);o&&this.startAutoPurge(o);const s={isValid(u){if(u.size===void 0)return!0;const n=u.size;if(n==null)return!1;const m=typeof n=="number"?n:Number(n);if(Number.isNaN(m)||m<0)return!1;const g=typeof this.value=="number"?this.value:Number(this.value);return!Number.isNaN(g)&&m<=g},response:M.RequestEntityTooLarge,value:this.maxUploadSize},a={isValid(u){return!!te.is(u.contentType,this.value)},response:M.UnsupportedMediaType,value:r.allowMIME},i=r.fileNameValidation??ht,l={isValid(u){return i(u.name)},response:M.InvalidFileName};this.validation.add({filename:l,mime:a,size:s}),this.validation.add({...r.validation})}get raw(){}async getReadUrl(e,r){return E($.METHOD_NOT_ALLOWED,`${this.constructor.name} does not implement getReadUrl()`)}async getUploadUrl(e,r){return E($.METHOD_NOT_ALLOWED,`${this.constructor.name} does not implement getUploadUrl()`)}get tusExtension(){const e=["creation","creation-with-upload","termination","checksum","creation-defer-length","concatenation"];return this.expiration&&e.push("expiration"),e}async validate(e){await this.validation.verify(e)}async exists(e,r){return this.instrumentOperation("exists",async()=>{try{return await this.getMeta(e.id,r),!0}catch{return!1}})}normalizeError(e){const r={code:e.name,message:e.message,name:e.name,statusCode:500};return{...r,message:`[${this.constructor.name}] ${r.message}`}}get config(){return this.genericConfig}async saveMeta(e){return G.assertSafeId(e.id),this.updateTimestamps(e),this.cache.set(e.id,e),this.meta.save(e.id,e)}static assertSafeId(e){(!e||typeof e!="string"||e.includes("\0")||e.includes("../")||e.includes("..\\")||e===".."||e.startsWith("../")||e.startsWith("..\\")||I(e)||/^[A-Z]:[/\\]/i.test(e))&&E($.INVALID_FILE_NAME,`Invalid file id: "${e}"`)}async deleteMeta(e){return this.cache.delete(e),this.meta.delete(e)}async getMeta(e,r){try{const o=await this.meta.get(e);return this.cache.set(o.id,o),{...o}}catch(o){const s=this.normalizeError(o instanceof Error?o:new Error(String(o)));return await this.onError(s),E($.FILE_NOT_FOUND)}}async checkIfExpired(e){return ne(e)?(this.delete(e).catch(()=>{}),this.deleteMeta(e.id).catch(()=>{}),E($.GONE)):e}async purge(e){return this.instrumentOperation("purge",async()=>{const r=T(e||this.expiration?.maxAge),o={items:[],maxAgeMs:r};if(r){const s=Date.now()-r,a=(await this.list()).filter(i=>Number(new Date(this.expiration?.rolling&&i.modifiedAt||i.createdAt))<s);for await(const{id:i,...l}of a)try{const u=await this.delete({id:i});o.items.push({...u,...l})}catch(u){this.logger?.warn(`Failed to delete file ${i} during purge: ${u instanceof Error?u.message:String(u)}`)}o.items.length>0&&(this.logger?.info(`Purge: removed ${o.items.length} uploads`),this.metrics.gauge("storage.operations.purge.items_count",o.items.length,{storage:this.constructor.name.toLowerCase().replace("storage","")}))}return o})}async getStream({id:e}){return this.instrumentOperation("getStream",async()=>{const r=await this.get({id:e}),o=X.from(r.content);return{headers:{"Content-Length":String(r.size),"Content-Type":r.contentType,...r.ETag&&{ETag:r.ETag},...r.modifiedAt&&{"Last-Modified":r.modifiedAt.toString()}},size:typeof r.size=="number"?r.size:void 0,stream:o}})}async list(e=1e3,r){return this.instrumentOperation("list",async()=>{throw new Error("Not implemented")})}async update({id:e},r){return this.instrumentOperation("update",async()=>{const o=await this.getMeta(e),s={...r};if("ttl"in s&&s.ttl!==void 0){const i=s.ttl,l=typeof i=="string"?T(i):i;l!==void 0&&(s.expiredAt=Date.now()+l),delete s.ttl}ut(o,s),await this.saveMeta(o);const a={...o,status:"updated"};return await this.onUpdate(a),a})}async deleteBatch(e,r){const o=Date.now(),s=this.constructor.name.toLowerCase().replace("storage","");this.metrics.increment("storage.operations.batch.delete.count",1,{batch_size:e.length,storage:s});const a=[],i=[],l=e.map(async m=>{try{return{file:await this.delete({id:m},r),id:m,success:!0}}catch(g){const c=g instanceof Error?g.message:"Delete failed";return this.metrics.increment("storage.operations.delete.error.count",1,{error:c,storage:s}),{error:c,id:m,success:!1}}}),u=await Promise.allSettled(l);for(const m of u)m.status==="fulfilled"?m.value.success?a.push(m.value.file):i.push({error:m.value.error,id:m.value.id}):i.push({error:m.reason?.message||"Delete failed",id:""});const n=Date.now()-o;return this.metrics.timing("storage.operations.batch.delete.duration",n,{batch_size:e.length,storage:s}),this.metrics.gauge("storage.operations.batch.delete.success_count",a.length,{storage:s}),this.metrics.gauge("storage.operations.batch.delete.failed_count",i.length,{storage:s}),{failed:i,failedCount:i.length,successful:a,successfulCount:a.length}}async copyBatch(e){const r=Date.now(),o=this.constructor.name.toLowerCase().replace("storage","");this.metrics.increment("storage.operations.batch.copy.count",1,{batch_size:e.length,storage:o});const s=[],a=[],i=e.map(async({destination:n,options:m,source:g})=>{try{return{file:await this.copy(g,n,m),id:n,success:!0}}catch(c){const d=c instanceof Error?c.message:"Copy failed";return this.metrics.increment("storage.operations.copy.error.count",1,{error:d,storage:o}),{error:d,id:n,success:!1}}}),l=await Promise.allSettled(i);for(const n of l)n.status==="fulfilled"?n.value.success&&n.value.file?s.push(n.value.file):a.push({error:n.value.error||"Copy failed",id:n.value.id}):a.push({error:n.reason?.message||"Copy failed",id:""});const u=Date.now()-r;return this.metrics.timing("storage.operations.batch.copy.duration",u,{batch_size:e.length,storage:o}),this.metrics.gauge("storage.operations.batch.copy.success_count",s.length,{storage:o}),this.metrics.gauge("storage.operations.batch.copy.failed_count",a.length,{storage:o}),{failed:a,failedCount:a.length,successful:s,successfulCount:s.length}}async moveBatch(e){const r=Date.now(),o=this.constructor.name.toLowerCase().replace("storage","");this.metrics.increment("storage.operations.batch.move.count",1,{batch_size:e.length,storage:o});const s=[],a=[],i=e.map(async({destination:n,source:m})=>{try{return{file:await this.move(m,n),id:n,success:!0}}catch(g){const c=g instanceof Error?g.message:"Move failed";return this.metrics.increment("storage.operations.move.error.count",1,{error:c,storage:o}),{error:c,id:n,success:!1}}}),l=await Promise.allSettled(i);for(const n of l)n.status==="fulfilled"?n.value.success&&n.value.file?s.push(n.value.file):a.push({error:n.value.error||"Move failed",id:n.value.id}):a.push({error:n.reason?.message||"Move failed",id:n.reason?.id||""});const u=Date.now()-r;return this.metrics.timing("storage.operations.batch.move.duration",u,{batch_size:e.length,storage:o}),this.metrics.gauge("storage.operations.batch.move.success_count",s.length,{storage:o}),this.metrics.gauge("storage.operations.batch.move.failed_count",a.length,{storage:o}),{failed:a,failedCount:a.length,successful:s,successfulCount:s.length}}async lock(e){const r=[...this.locker.keys()];return r.includes(e)?E($.FILE_LOCKED):this.config.concurrency&&typeof this.config.concurrency=="number"&&this.config.concurrency<r.length?E($.STORAGE_BUSY):this.locker.lock(e)}async unlock(e,r){if(r===void 0){this.locker.delete(e);return}this.locker.unlock(e,r)}async withLock(e,r){const o=await this.lock(e);try{return await r()}finally{await this.unlock(e,o)}}isUnsupportedChecksum(e=""){return!!e&&!this.checksumTypes.includes(e)}startAutoPurge(e){if(e>=2147483647)throw new Error("“purgeInterval” must be less than 2147483647 ms");J(()=>{this.purge().catch(r=>this.logger?.error(r))},e)}updateTimestamps(e){e.createdAt??=new Date().toISOString();const r=T(this.expiration?.maxAge);return r&&!e.expiredAt&&(e.expiredAt=this.expiration?.rolling?Date.now()+r:+new Date(e.createdAt)+r),e}getRetryConfig(){}runOperation(e,r,o){let s;typeof e?.retries=="number"?s={maxRetries:e.retries}:e?.retries&&(s=e.retries);const a={...this.getRetryConfig(),...s};o?.replayable===!1&&(a.maxRetries=0);const i=[];this.genericConfig.defaultSignal&&i.push(this.genericConfig.defaultSignal),e?.signal&&i.push(e.signal);let l;i.length===1?[l]=i:i.length>1&&(l=AbortSignal.any(i));const u=typeof e?.timeout=="number"?e.timeout:this.genericConfig.defaultTimeout,n=typeof u=="number"&&u>0?u:void 0,m=a.shouldRetry;a.shouldRetry=c=>l?.aborted||c instanceof Error&&c.name==="AbortError"?!1:m?m(c):!1;const g=b(c=>{if(c instanceof Error&&c.name==="AbortError")return c;const d=c instanceof Error&&c.message?c.message:"The operation was aborted",h=new Error(d,{cause:c});return h.name="AbortError",h},"toAbortError");return ie(async()=>{if(l?.aborted)throw g(l.reason);let c,d;if(n===void 0)d=l;else{const h=new AbortController;c=setTimeout(()=>{h.abort(new DOMException(`The operation timed out after ${n}ms`,"TimeoutError"))},n),d=l?AbortSignal.any([l,h.signal]):h.signal}try{return await r(d)}catch(h){throw d?.aborted?g(h):h}finally{c&&clearTimeout(c)}},a)}async instrumentOperation(e,r,o){const s=Date.now(),a={storage:this.constructor.name.toLowerCase().replace("storage",""),...o};try{this.metrics.increment(`storage.operations.${e}.count`,1,a);const i=await r(),l=Date.now()-s;return this.metrics.timing(`storage.operations.${e}.duration`,l,a),i&&typeof i=="object"&&"size"in i&&typeof i.size=="number"&&this.metrics.gauge("storage.files.size",i.size,{...a,operation:e}),i}catch(i){const l=Date.now()-s,u=i instanceof Error?i.message:"Unknown error";throw this.metrics.timing(`storage.operations.${e}.duration`,l,{...a,error:"true"}),this.metrics.increment(`storage.operations.${e}.error.count`,1,{...a,error:u}),i}}}export{j as $,G as B,It as a,ot as b,ht as d,St as i,T as t,ut as u,qe as z};
|
|
@@ -809,7 +809,7 @@ declare abstract class BaseStorage<TFile extends File = File, TFileReturn extend
|
|
|
809
809
|
* @param _key Storage key.
|
|
810
810
|
* @param _options Optional expiry and response overrides.
|
|
811
811
|
*/
|
|
812
|
-
getReadUrl(_key: string, _options?: {
|
|
812
|
+
getReadUrl(_key: string, _options?: OperationOptions & {
|
|
813
813
|
expiresIn?: number;
|
|
814
814
|
responseContentDisposition?: string;
|
|
815
815
|
responseContentType?: string;
|
|
@@ -818,9 +818,9 @@ declare abstract class BaseStorage<TFile extends File = File, TFileReturn extend
|
|
|
818
818
|
* Returns a presigned URL for uploading a single object to `key`.
|
|
819
819
|
* Throws `ERRORS.METHOD_NOT_ALLOWED` when the adapter has no native presign support.
|
|
820
820
|
* @param _key Storage key.
|
|
821
|
-
* @param _options Optional content type, expiry, and content length hints.
|
|
821
|
+
* @param _options Optional content type, expiry, and content length hints, plus per-call signal/timeout/retries.
|
|
822
822
|
*/
|
|
823
|
-
getUploadUrl(_key: string, _options?: {
|
|
823
|
+
getUploadUrl(_key: string, _options?: OperationOptions & {
|
|
824
824
|
contentLength?: number;
|
|
825
825
|
contentType?: string;
|
|
826
826
|
expiresIn?: number;
|
|
@@ -840,7 +840,7 @@ declare abstract class BaseStorage<TFile extends File = File, TFileReturn extend
|
|
|
840
840
|
* @returns Promise resolving to true if file exists, false otherwise.
|
|
841
841
|
* @remarks This method does not throw errors - it returns false if the file is not found.
|
|
842
842
|
*/
|
|
843
|
-
exists(query: FileQuery): Promise<boolean>;
|
|
843
|
+
exists(query: FileQuery, options?: OperationOptions): Promise<boolean>;
|
|
844
844
|
/**
|
|
845
845
|
* Normalizes errors with storage-specific context.
|
|
846
846
|
* @param error The error to normalize.
|
|
@@ -882,7 +882,7 @@ declare abstract class BaseStorage<TFile extends File = File, TFileReturn extend
|
|
|
882
882
|
* @throws {UploadError} If the file metadata cannot be found (ERRORS.FILE_NOT_FOUND).
|
|
883
883
|
* @remarks Caches the retrieved metadata for faster subsequent access.
|
|
884
884
|
*/
|
|
885
|
-
getMeta(id: string): Promise<TFile>;
|
|
885
|
+
getMeta(id: string, _options?: OperationOptions): Promise<TFile>;
|
|
886
886
|
/**
|
|
887
887
|
* Checks if a file has expired and deletes it if so.
|
|
888
888
|
* @param file File object to check for expiration.
|
|
@@ -907,13 +907,14 @@ declare abstract class BaseStorage<TFile extends File = File, TFileReturn extend
|
|
|
907
907
|
* Gets an uploaded file by ID.
|
|
908
908
|
* @param query File query containing the file ID to retrieve.
|
|
909
909
|
* @param query.id File ID to retrieve.
|
|
910
|
+
* @param options Optional per-call signal/timeout/retries.
|
|
910
911
|
* @returns Promise resolving to the file data including content.
|
|
911
912
|
* @throws {UploadError} If the file cannot be found (ERRORS.FILE_NOT_FOUND) or has expired (ERRORS.GONE).
|
|
912
913
|
* @remarks This method loads the entire file content into memory. For large files, use getStream() instead.
|
|
913
914
|
*/
|
|
914
915
|
abstract get({
|
|
915
916
|
id
|
|
916
|
-
}: FileQuery): Promise<TFileReturn>;
|
|
917
|
+
}: FileQuery, options?: OperationOptions): Promise<TFileReturn>;
|
|
917
918
|
/**
|
|
918
919
|
* Gets an uploaded file as a readable stream for efficient large file handling.
|
|
919
920
|
* @param query File query containing the file ID to stream.
|
|
@@ -939,7 +940,7 @@ declare abstract class BaseStorage<TFile extends File = File, TFileReturn extend
|
|
|
939
940
|
* @throws {Error} If not implemented by the storage backend.
|
|
940
941
|
* @remarks Storage implementations must override this method.
|
|
941
942
|
*/
|
|
942
|
-
list(_limit?: number): Promise<TFile[]>;
|
|
943
|
+
list(_limit?: number, _options?: OperationOptions): Promise<TFile[]>;
|
|
943
944
|
/**
|
|
944
945
|
* Updates file metadata with user-provided key-value pairs.
|
|
945
946
|
* @param query File query containing the file ID to update.
|
|
@@ -958,42 +959,46 @@ declare abstract class BaseStorage<TFile extends File = File, TFileReturn extend
|
|
|
958
959
|
/**
|
|
959
960
|
* Creates a new upload and saves its metadata.
|
|
960
961
|
* @param file File initialization configuration.
|
|
962
|
+
* @param options Optional per-call signal/timeout/retries.
|
|
961
963
|
* @returns Promise resolving to the created file object.
|
|
962
964
|
*/
|
|
963
|
-
abstract create(file: FileInit): Promise<TFile>;
|
|
965
|
+
abstract create(file: FileInit, options?: OperationOptions): Promise<TFile>;
|
|
964
966
|
/**
|
|
965
967
|
* Writes part and/or returns status of an upload.
|
|
966
968
|
* @param part File part, query, or full file object to write.
|
|
969
|
+
* @param options Optional per-call signal/timeout/retries.
|
|
967
970
|
* @returns Promise resolving to the updated file object.
|
|
968
971
|
*/
|
|
969
|
-
abstract write(part: FilePart | FileQuery | TFile): Promise<TFile>;
|
|
972
|
+
abstract write(part: FilePart | FileQuery | TFile, options?: OperationOptions): Promise<TFile>;
|
|
970
973
|
/**
|
|
971
974
|
* Deletes an upload and its metadata.
|
|
972
975
|
* @param query File query containing the file ID to delete.
|
|
973
976
|
* @param query.id File ID to delete.
|
|
977
|
+
* @param options Optional per-call signal/timeout/retries.
|
|
974
978
|
* @returns Promise resolving to the deleted file object with status: "deleted".
|
|
975
979
|
* @throws {UploadError} If the file metadata cannot be found.
|
|
976
980
|
*/
|
|
977
|
-
abstract delete(query: FileQuery): Promise<TFile>;
|
|
981
|
+
abstract delete(query: FileQuery, options?: OperationOptions): Promise<TFile>;
|
|
978
982
|
/**
|
|
979
983
|
* Copies an upload file to a new location.
|
|
980
984
|
* @param name Source file name/ID.
|
|
981
985
|
* @param destination Destination file name/ID.
|
|
982
|
-
* @param options Optional copy options including storage class.
|
|
986
|
+
* @param options Optional copy options including storage class plus per-call signal/timeout/retries.
|
|
983
987
|
* @returns Promise resolving to the copied file object.
|
|
984
988
|
* @throws {UploadError} If the source file cannot be found.
|
|
985
989
|
*/
|
|
986
|
-
abstract copy(name: string, destination: string, options?: {
|
|
990
|
+
abstract copy(name: string, destination: string, options?: OperationOptions & {
|
|
987
991
|
storageClass?: string;
|
|
988
992
|
}): Promise<TFile>;
|
|
989
993
|
/**
|
|
990
994
|
* Moves an upload file to a new location.
|
|
991
995
|
* @param name Source file name/ID.
|
|
992
996
|
* @param destination Destination file name/ID.
|
|
997
|
+
* @param options Optional per-call signal/timeout/retries.
|
|
993
998
|
* @returns Promise resolving to the moved file object.
|
|
994
999
|
* @throws {UploadError} If the source file cannot be found.
|
|
995
1000
|
*/
|
|
996
|
-
abstract move(name: string, destination: string): Promise<TFile>;
|
|
1001
|
+
abstract move(name: string, destination: string, options?: OperationOptions): Promise<TFile>;
|
|
997
1002
|
/**
|
|
998
1003
|
* Deletes multiple files in a single batch operation.
|
|
999
1004
|
* @param ids Array of file IDs to delete.
|
|
@@ -1005,7 +1010,7 @@ declare abstract class BaseStorage<TFile extends File = File, TFileReturn extend
|
|
|
1005
1010
|
* Metrics are recorded for the batch operation and individual failures.
|
|
1006
1011
|
* Returns both successful and failed operations with detailed error information.
|
|
1007
1012
|
*/
|
|
1008
|
-
deleteBatch(ids: string[]): Promise<BatchOperationResponse<TFile>>;
|
|
1013
|
+
deleteBatch(ids: string[], options?: OperationOptions): Promise<BatchOperationResponse<TFile>>;
|
|
1009
1014
|
/**
|
|
1010
1015
|
* Copies multiple files in a single batch operation.
|
|
1011
1016
|
* @param operations Array of copy operations, each containing:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
|
-
import { U as UploadFile, j as ResponseBodyType, B as BaseStorage, k as ErrorResponses } from "./storage.d-
|
|
2
|
+
import { U as UploadFile, j as ResponseBodyType, B as BaseStorage, k as ErrorResponses } from "./storage.d-BoJgdi1n.js";
|
|
3
3
|
import 'node:stream';
|
|
4
|
-
import { M as MediaTransformer } from "./media-transformer.d-
|
|
5
|
-
import { U as UploadOptions } from "./types.d-
|
|
4
|
+
import { M as MediaTransformer } from "./media-transformer.d-lQ_RUjb5.js";
|
|
5
|
+
import { U as UploadOptions } from "./types.d-CPxJpoPH.js";
|
|
6
6
|
import 'node:crypto';
|
|
7
7
|
import 'node:http';
|
|
8
8
|
import 'lru-cache';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as File, L as LocalMetaStorageOptions, i as BaseStorageOptions } from "./storage.d-
|
|
1
|
+
import { F as File, L as LocalMetaStorageOptions, i as BaseStorageOptions } from "./storage.d-BoJgdi1n.js";
|
|
2
2
|
import 'node:stream';
|
|
3
3
|
import { Client } from '@microsoft/microsoft-graph-client';
|
|
4
4
|
declare class OneDriveFile extends File {
|
|
@@ -2,8 +2,8 @@ import { EventEmitter } from 'node:events';
|
|
|
2
2
|
import { IncomingMessage } from 'node:http';
|
|
3
3
|
import { Readable } from 'node:stream';
|
|
4
4
|
import { PaginationResult } from '@visulima/pagination';
|
|
5
|
-
import { U as UploadFile, B as BaseStorage, b as UploadError, c as UploadEventType } from "./storage.d-
|
|
6
|
-
import { M as MediaTransformer } from "./media-transformer.d-
|
|
5
|
+
import { U as UploadFile, B as BaseStorage, b as UploadError, c as UploadEventType } from "./storage.d-BoJgdi1n.js";
|
|
6
|
+
import { M as MediaTransformer } from "./media-transformer.d-lQ_RUjb5.js";
|
|
7
7
|
type WebRequest = globalThis.Request;
|
|
8
8
|
type WebResponse = globalThis.Response;
|
|
9
9
|
interface BaseResponse {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a1 as Cache, F as File, a as FileReturn, B as BaseStorage } from "./storage.d-
|
|
1
|
+
import { a1 as Cache, F as File, a as FileReturn, B as BaseStorage } from "./storage.d-BoJgdi1n.js";
|
|
2
2
|
import { Readable } from 'node:stream';
|
|
3
3
|
/**
|
|
4
4
|
* Base transformer configuration with common properties
|
|
@@ -717,4 +717,4 @@ interface AudioTransformerConfig extends BaseTransformerConfig {
|
|
|
717
717
|
/** Maximum audio size to process (in bytes) */
|
|
718
718
|
maxAudioSize?: number;
|
|
719
719
|
}
|
|
720
|
-
export {
|
|
720
|
+
export { AffineOptions as A, BlurOptions as B, CropOptions as C, DilateOptions as D, ExtractChannelOptions as E, VideoCropOptions as F, GreyscaleOptions as G, VideoRotateOptions as H, ImageTransformerConfig as I, JoinChannelOptions as J, VideoTransformOptions as K, LinearOptions as L, MedianOptions as M, VideoTransformationStep as N, MediaTransformerConfig as O, PipelineColourspaceOptions as P, MediaTransformResult as Q, ResizeOptions as R, SharpenOptions as S, TransformResult as T, MediaTransformQuery as U, VideoTransformerConfig as V, MediaTransformationStep as W, RotateOptions as a, ImageFormat as b, TransformOptions as c, CLAHEOptions as d, ConvolveOptions as e, ThresholdOptions as f, BooleanOptions as g, RecombineOptions as h, ModulateOptions as i, TintOptions as j, ColourspaceOptions as k, BandboolOptions as l, ErodeOptions as m, ToColourspaceOptions as n, RemoveAlphaOptions as o, EnsureAlphaOptions as p, TransformationStep as q, BaseTransformer as r, AudioTransformerConfig as s, AudioTransformResult as t, AudioResampleOptions as u, AudioChannelMixOptions as v, AudioTransformOptions as w, AudioTransformationStep as x, VideoTransformResult as y, VideoResizeOptions as z };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { F as File, t as MetaStorageOptions, i as BaseStorageOptions, L as LocalMetaStorageOptions, M as MetaStorage, H as HttpError, g as FileQuery, O as OperationOptions, e as FileInit } from "../../packem_shared/storage.d-
|
|
1
|
+
import { F as File, t as MetaStorageOptions, i as BaseStorageOptions, L as LocalMetaStorageOptions, M as MetaStorage, H as HttpError, g as FileQuery, O as OperationOptions, e as FileInit } from "../../packem_shared/storage.d-BoJgdi1n.js";
|
|
2
2
|
import { Readable } from 'node:stream';
|
|
3
|
-
import { P as Part, S as S3CallOptions, a as S3ApiOperations, b as S3BaseStorage } from "../../packem_shared/s3-base-storage.d-
|
|
3
|
+
import { P as Part, S as S3CallOptions, a as S3ApiOperations, b as S3BaseStorage } from "../../packem_shared/s3-base-storage.d-CDIOMTpp.js";
|
|
4
4
|
import { S3ClientConfig, ObjectCannedACL, S3Client } from '@aws-sdk/client-s3';
|
|
5
5
|
import { ResponseMetadata } from '@aws-sdk/types';
|
|
6
6
|
import 'node:crypto';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as t}from"../../packem_shared/S3File-BfmCOET4.js";import{default as r}from"../../packem_shared/S3MetaStorage-vcriiosn.js";import{default as S}from"../../packem_shared/S3Storage-
|
|
1
|
+
import{default as t}from"../../packem_shared/S3File-BfmCOET4.js";import{default as r}from"../../packem_shared/S3MetaStorage-vcriiosn.js";import{default as S}from"../../packem_shared/S3Storage-Dn3l4WkO.js";export{t as S3File,r as S3MetaStorage,S as S3Storage};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as Part, S as S3CallOptions, a as S3ApiOperations, b as S3BaseStorage } from "../../packem_shared/s3-base-storage.d-
|
|
2
|
-
import { F as File, t as MetaStorageOptions, i as BaseStorageOptions, M as MetaStorage, H as HttpError, g as FileQuery, O as OperationOptions, e as FileInit } from "../../packem_shared/storage.d-
|
|
1
|
+
import { P as Part, S as S3CallOptions, a as S3ApiOperations, b as S3BaseStorage } from "../../packem_shared/s3-base-storage.d-CDIOMTpp.js";
|
|
2
|
+
import { F as File, t as MetaStorageOptions, i as BaseStorageOptions, M as MetaStorage, H as HttpError, g as FileQuery, O as OperationOptions, e as FileInit } from "../../packem_shared/storage.d-BoJgdi1n.js";
|
|
3
3
|
import { Readable } from 'node:stream';
|
|
4
4
|
import { AwsClient } from 'aws4fetch';
|
|
5
5
|
import 'node:crypto';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as a}from"../../packem_shared/AwsLightFile-BSqjc_rD.js";import{l as r}from"../../packem_shared/aws-light-meta-storage-CstQBYXG.js";import{default as f}from"../../packem_shared/AwsLightStorage-
|
|
1
|
+
import{default as a}from"../../packem_shared/AwsLightFile-BSqjc_rD.js";import{l as r}from"../../packem_shared/aws-light-meta-storage-CstQBYXG.js";import{default as f}from"../../packem_shared/AwsLightStorage-DbQrK9m7.js";export{a as AwsLightFile,r as AwsLightMetaStorage,f as AwsLightStorage};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as File, t as MetaStorageOptions, L as LocalMetaStorageOptions, i as BaseStorageOptions, M as MetaStorage, R as RetryConfig, e as FileInit, O as OperationOptions, g as FileQuery, f as FilePart, a as FileReturn, B as BaseStorage } from "../../packem_shared/storage.d-
|
|
1
|
+
import { F as File, t as MetaStorageOptions, L as LocalMetaStorageOptions, i as BaseStorageOptions, M as MetaStorage, R as RetryConfig, e as FileInit, O as OperationOptions, g as FileQuery, f as FilePart, a as FileReturn, B as BaseStorage } from "../../packem_shared/storage.d-BoJgdi1n.js";
|
|
2
2
|
import 'node:stream';
|
|
3
3
|
import { TokenCredential } from '@azure/core-auth';
|
|
4
4
|
import { BlobServiceClient } from '@azure/storage-blob';
|