@remix-run/file-storage 0.8.0

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/dist/local.js ADDED
@@ -0,0 +1,867 @@
1
+ // src/lib/local-file-storage.ts
2
+ import * as fs2 from "node:fs";
3
+ import * as fsp from "node:fs/promises";
4
+ import * as path2 from "node:path";
5
+
6
+ // ../lazy-file/src/fs.ts
7
+ import * as fs from "node:fs";
8
+ import * as path from "node:path";
9
+
10
+ // ../../node_modules/.pnpm/mrmime@2.0.0/node_modules/mrmime/index.mjs
11
+ var mimes = {
12
+ "3g2": "video/3gpp2",
13
+ "3gp": "video/3gpp",
14
+ "3gpp": "video/3gpp",
15
+ "3mf": "model/3mf",
16
+ "aac": "audio/aac",
17
+ "ac": "application/pkix-attr-cert",
18
+ "adp": "audio/adpcm",
19
+ "adts": "audio/aac",
20
+ "ai": "application/postscript",
21
+ "aml": "application/automationml-aml+xml",
22
+ "amlx": "application/automationml-amlx+zip",
23
+ "amr": "audio/amr",
24
+ "apng": "image/apng",
25
+ "appcache": "text/cache-manifest",
26
+ "appinstaller": "application/appinstaller",
27
+ "appx": "application/appx",
28
+ "appxbundle": "application/appxbundle",
29
+ "asc": "application/pgp-keys",
30
+ "atom": "application/atom+xml",
31
+ "atomcat": "application/atomcat+xml",
32
+ "atomdeleted": "application/atomdeleted+xml",
33
+ "atomsvc": "application/atomsvc+xml",
34
+ "au": "audio/basic",
35
+ "avci": "image/avci",
36
+ "avcs": "image/avcs",
37
+ "avif": "image/avif",
38
+ "aw": "application/applixware",
39
+ "bdoc": "application/bdoc",
40
+ "bin": "application/octet-stream",
41
+ "bmp": "image/bmp",
42
+ "bpk": "application/octet-stream",
43
+ "btf": "image/prs.btif",
44
+ "btif": "image/prs.btif",
45
+ "buffer": "application/octet-stream",
46
+ "ccxml": "application/ccxml+xml",
47
+ "cdfx": "application/cdfx+xml",
48
+ "cdmia": "application/cdmi-capability",
49
+ "cdmic": "application/cdmi-container",
50
+ "cdmid": "application/cdmi-domain",
51
+ "cdmio": "application/cdmi-object",
52
+ "cdmiq": "application/cdmi-queue",
53
+ "cer": "application/pkix-cert",
54
+ "cgm": "image/cgm",
55
+ "cjs": "application/node",
56
+ "class": "application/java-vm",
57
+ "coffee": "text/coffeescript",
58
+ "conf": "text/plain",
59
+ "cpl": "application/cpl+xml",
60
+ "cpt": "application/mac-compactpro",
61
+ "crl": "application/pkix-crl",
62
+ "css": "text/css",
63
+ "csv": "text/csv",
64
+ "cu": "application/cu-seeme",
65
+ "cwl": "application/cwl",
66
+ "cww": "application/prs.cww",
67
+ "davmount": "application/davmount+xml",
68
+ "dbk": "application/docbook+xml",
69
+ "deb": "application/octet-stream",
70
+ "def": "text/plain",
71
+ "deploy": "application/octet-stream",
72
+ "dib": "image/bmp",
73
+ "disposition-notification": "message/disposition-notification",
74
+ "dist": "application/octet-stream",
75
+ "distz": "application/octet-stream",
76
+ "dll": "application/octet-stream",
77
+ "dmg": "application/octet-stream",
78
+ "dms": "application/octet-stream",
79
+ "doc": "application/msword",
80
+ "dot": "application/msword",
81
+ "dpx": "image/dpx",
82
+ "drle": "image/dicom-rle",
83
+ "dsc": "text/prs.lines.tag",
84
+ "dssc": "application/dssc+der",
85
+ "dtd": "application/xml-dtd",
86
+ "dump": "application/octet-stream",
87
+ "dwd": "application/atsc-dwd+xml",
88
+ "ear": "application/java-archive",
89
+ "ecma": "application/ecmascript",
90
+ "elc": "application/octet-stream",
91
+ "emf": "image/emf",
92
+ "eml": "message/rfc822",
93
+ "emma": "application/emma+xml",
94
+ "emotionml": "application/emotionml+xml",
95
+ "eps": "application/postscript",
96
+ "epub": "application/epub+zip",
97
+ "exe": "application/octet-stream",
98
+ "exi": "application/exi",
99
+ "exp": "application/express",
100
+ "exr": "image/aces",
101
+ "ez": "application/andrew-inset",
102
+ "fdf": "application/fdf",
103
+ "fdt": "application/fdt+xml",
104
+ "fits": "image/fits",
105
+ "g3": "image/g3fax",
106
+ "gbr": "application/rpki-ghostbusters",
107
+ "geojson": "application/geo+json",
108
+ "gif": "image/gif",
109
+ "glb": "model/gltf-binary",
110
+ "gltf": "model/gltf+json",
111
+ "gml": "application/gml+xml",
112
+ "gpx": "application/gpx+xml",
113
+ "gram": "application/srgs",
114
+ "grxml": "application/srgs+xml",
115
+ "gxf": "application/gxf",
116
+ "gz": "application/gzip",
117
+ "h261": "video/h261",
118
+ "h263": "video/h263",
119
+ "h264": "video/h264",
120
+ "heic": "image/heic",
121
+ "heics": "image/heic-sequence",
122
+ "heif": "image/heif",
123
+ "heifs": "image/heif-sequence",
124
+ "hej2": "image/hej2k",
125
+ "held": "application/atsc-held+xml",
126
+ "hjson": "application/hjson",
127
+ "hlp": "application/winhlp",
128
+ "hqx": "application/mac-binhex40",
129
+ "hsj2": "image/hsj2",
130
+ "htm": "text/html",
131
+ "html": "text/html",
132
+ "ics": "text/calendar",
133
+ "ief": "image/ief",
134
+ "ifb": "text/calendar",
135
+ "iges": "model/iges",
136
+ "igs": "model/iges",
137
+ "img": "application/octet-stream",
138
+ "in": "text/plain",
139
+ "ini": "text/plain",
140
+ "ink": "application/inkml+xml",
141
+ "inkml": "application/inkml+xml",
142
+ "ipfix": "application/ipfix",
143
+ "iso": "application/octet-stream",
144
+ "its": "application/its+xml",
145
+ "jade": "text/jade",
146
+ "jar": "application/java-archive",
147
+ "jhc": "image/jphc",
148
+ "jls": "image/jls",
149
+ "jp2": "image/jp2",
150
+ "jpe": "image/jpeg",
151
+ "jpeg": "image/jpeg",
152
+ "jpf": "image/jpx",
153
+ "jpg": "image/jpeg",
154
+ "jpg2": "image/jp2",
155
+ "jpgm": "image/jpm",
156
+ "jpgv": "video/jpeg",
157
+ "jph": "image/jph",
158
+ "jpm": "image/jpm",
159
+ "jpx": "image/jpx",
160
+ "js": "text/javascript",
161
+ "json": "application/json",
162
+ "json5": "application/json5",
163
+ "jsonld": "application/ld+json",
164
+ "jsonml": "application/jsonml+json",
165
+ "jsx": "text/jsx",
166
+ "jt": "model/jt",
167
+ "jxr": "image/jxr",
168
+ "jxra": "image/jxra",
169
+ "jxrs": "image/jxrs",
170
+ "jxs": "image/jxs",
171
+ "jxsc": "image/jxsc",
172
+ "jxsi": "image/jxsi",
173
+ "jxss": "image/jxss",
174
+ "kar": "audio/midi",
175
+ "ktx": "image/ktx",
176
+ "ktx2": "image/ktx2",
177
+ "less": "text/less",
178
+ "lgr": "application/lgr+xml",
179
+ "list": "text/plain",
180
+ "litcoffee": "text/coffeescript",
181
+ "log": "text/plain",
182
+ "lostxml": "application/lost+xml",
183
+ "lrf": "application/octet-stream",
184
+ "m1v": "video/mpeg",
185
+ "m21": "application/mp21",
186
+ "m2a": "audio/mpeg",
187
+ "m2v": "video/mpeg",
188
+ "m3a": "audio/mpeg",
189
+ "m4a": "audio/mp4",
190
+ "m4p": "application/mp4",
191
+ "m4s": "video/iso.segment",
192
+ "ma": "application/mathematica",
193
+ "mads": "application/mads+xml",
194
+ "maei": "application/mmt-aei+xml",
195
+ "man": "text/troff",
196
+ "manifest": "text/cache-manifest",
197
+ "map": "application/json",
198
+ "mar": "application/octet-stream",
199
+ "markdown": "text/markdown",
200
+ "mathml": "application/mathml+xml",
201
+ "mb": "application/mathematica",
202
+ "mbox": "application/mbox",
203
+ "md": "text/markdown",
204
+ "mdx": "text/mdx",
205
+ "me": "text/troff",
206
+ "mesh": "model/mesh",
207
+ "meta4": "application/metalink4+xml",
208
+ "metalink": "application/metalink+xml",
209
+ "mets": "application/mets+xml",
210
+ "mft": "application/rpki-manifest",
211
+ "mid": "audio/midi",
212
+ "midi": "audio/midi",
213
+ "mime": "message/rfc822",
214
+ "mj2": "video/mj2",
215
+ "mjp2": "video/mj2",
216
+ "mjs": "text/javascript",
217
+ "mml": "text/mathml",
218
+ "mods": "application/mods+xml",
219
+ "mov": "video/quicktime",
220
+ "mp2": "audio/mpeg",
221
+ "mp21": "application/mp21",
222
+ "mp2a": "audio/mpeg",
223
+ "mp3": "audio/mpeg",
224
+ "mp4": "video/mp4",
225
+ "mp4a": "audio/mp4",
226
+ "mp4s": "application/mp4",
227
+ "mp4v": "video/mp4",
228
+ "mpd": "application/dash+xml",
229
+ "mpe": "video/mpeg",
230
+ "mpeg": "video/mpeg",
231
+ "mpf": "application/media-policy-dataset+xml",
232
+ "mpg": "video/mpeg",
233
+ "mpg4": "video/mp4",
234
+ "mpga": "audio/mpeg",
235
+ "mpp": "application/dash-patch+xml",
236
+ "mrc": "application/marc",
237
+ "mrcx": "application/marcxml+xml",
238
+ "ms": "text/troff",
239
+ "mscml": "application/mediaservercontrol+xml",
240
+ "msh": "model/mesh",
241
+ "msi": "application/octet-stream",
242
+ "msix": "application/msix",
243
+ "msixbundle": "application/msixbundle",
244
+ "msm": "application/octet-stream",
245
+ "msp": "application/octet-stream",
246
+ "mtl": "model/mtl",
247
+ "musd": "application/mmt-usd+xml",
248
+ "mxf": "application/mxf",
249
+ "mxmf": "audio/mobile-xmf",
250
+ "mxml": "application/xv+xml",
251
+ "n3": "text/n3",
252
+ "nb": "application/mathematica",
253
+ "nq": "application/n-quads",
254
+ "nt": "application/n-triples",
255
+ "obj": "model/obj",
256
+ "oda": "application/oda",
257
+ "oga": "audio/ogg",
258
+ "ogg": "audio/ogg",
259
+ "ogv": "video/ogg",
260
+ "ogx": "application/ogg",
261
+ "omdoc": "application/omdoc+xml",
262
+ "onepkg": "application/onenote",
263
+ "onetmp": "application/onenote",
264
+ "onetoc": "application/onenote",
265
+ "onetoc2": "application/onenote",
266
+ "opf": "application/oebps-package+xml",
267
+ "opus": "audio/ogg",
268
+ "otf": "font/otf",
269
+ "owl": "application/rdf+xml",
270
+ "oxps": "application/oxps",
271
+ "p10": "application/pkcs10",
272
+ "p7c": "application/pkcs7-mime",
273
+ "p7m": "application/pkcs7-mime",
274
+ "p7s": "application/pkcs7-signature",
275
+ "p8": "application/pkcs8",
276
+ "pdf": "application/pdf",
277
+ "pfr": "application/font-tdpfr",
278
+ "pgp": "application/pgp-encrypted",
279
+ "pkg": "application/octet-stream",
280
+ "pki": "application/pkixcmp",
281
+ "pkipath": "application/pkix-pkipath",
282
+ "pls": "application/pls+xml",
283
+ "png": "image/png",
284
+ "prc": "model/prc",
285
+ "prf": "application/pics-rules",
286
+ "provx": "application/provenance+xml",
287
+ "ps": "application/postscript",
288
+ "pskcxml": "application/pskc+xml",
289
+ "pti": "image/prs.pti",
290
+ "qt": "video/quicktime",
291
+ "raml": "application/raml+yaml",
292
+ "rapd": "application/route-apd+xml",
293
+ "rdf": "application/rdf+xml",
294
+ "relo": "application/p2p-overlay+xml",
295
+ "rif": "application/reginfo+xml",
296
+ "rl": "application/resource-lists+xml",
297
+ "rld": "application/resource-lists-diff+xml",
298
+ "rmi": "audio/midi",
299
+ "rnc": "application/relax-ng-compact-syntax",
300
+ "rng": "application/xml",
301
+ "roa": "application/rpki-roa",
302
+ "roff": "text/troff",
303
+ "rq": "application/sparql-query",
304
+ "rs": "application/rls-services+xml",
305
+ "rsat": "application/atsc-rsat+xml",
306
+ "rsd": "application/rsd+xml",
307
+ "rsheet": "application/urc-ressheet+xml",
308
+ "rss": "application/rss+xml",
309
+ "rtf": "text/rtf",
310
+ "rtx": "text/richtext",
311
+ "rusd": "application/route-usd+xml",
312
+ "s3m": "audio/s3m",
313
+ "sbml": "application/sbml+xml",
314
+ "scq": "application/scvp-cv-request",
315
+ "scs": "application/scvp-cv-response",
316
+ "sdp": "application/sdp",
317
+ "senmlx": "application/senml+xml",
318
+ "sensmlx": "application/sensml+xml",
319
+ "ser": "application/java-serialized-object",
320
+ "setpay": "application/set-payment-initiation",
321
+ "setreg": "application/set-registration-initiation",
322
+ "sgi": "image/sgi",
323
+ "sgm": "text/sgml",
324
+ "sgml": "text/sgml",
325
+ "shex": "text/shex",
326
+ "shf": "application/shf+xml",
327
+ "shtml": "text/html",
328
+ "sieve": "application/sieve",
329
+ "sig": "application/pgp-signature",
330
+ "sil": "audio/silk",
331
+ "silo": "model/mesh",
332
+ "siv": "application/sieve",
333
+ "slim": "text/slim",
334
+ "slm": "text/slim",
335
+ "sls": "application/route-s-tsid+xml",
336
+ "smi": "application/smil+xml",
337
+ "smil": "application/smil+xml",
338
+ "snd": "audio/basic",
339
+ "so": "application/octet-stream",
340
+ "spdx": "text/spdx",
341
+ "spp": "application/scvp-vp-response",
342
+ "spq": "application/scvp-vp-request",
343
+ "spx": "audio/ogg",
344
+ "sql": "application/sql",
345
+ "sru": "application/sru+xml",
346
+ "srx": "application/sparql-results+xml",
347
+ "ssdl": "application/ssdl+xml",
348
+ "ssml": "application/ssml+xml",
349
+ "stk": "application/hyperstudio",
350
+ "stl": "model/stl",
351
+ "stpx": "model/step+xml",
352
+ "stpxz": "model/step-xml+zip",
353
+ "stpz": "model/step+zip",
354
+ "styl": "text/stylus",
355
+ "stylus": "text/stylus",
356
+ "svg": "image/svg+xml",
357
+ "svgz": "image/svg+xml",
358
+ "swidtag": "application/swid+xml",
359
+ "t": "text/troff",
360
+ "t38": "image/t38",
361
+ "td": "application/urc-targetdesc+xml",
362
+ "tei": "application/tei+xml",
363
+ "teicorpus": "application/tei+xml",
364
+ "text": "text/plain",
365
+ "tfi": "application/thraud+xml",
366
+ "tfx": "image/tiff-fx",
367
+ "tif": "image/tiff",
368
+ "tiff": "image/tiff",
369
+ "toml": "application/toml",
370
+ "tr": "text/troff",
371
+ "trig": "application/trig",
372
+ "ts": "video/mp2t",
373
+ "tsd": "application/timestamped-data",
374
+ "tsv": "text/tab-separated-values",
375
+ "ttc": "font/collection",
376
+ "ttf": "font/ttf",
377
+ "ttl": "text/turtle",
378
+ "ttml": "application/ttml+xml",
379
+ "txt": "text/plain",
380
+ "u3d": "model/u3d",
381
+ "u8dsn": "message/global-delivery-status",
382
+ "u8hdr": "message/global-headers",
383
+ "u8mdn": "message/global-disposition-notification",
384
+ "u8msg": "message/global",
385
+ "ubj": "application/ubjson",
386
+ "uri": "text/uri-list",
387
+ "uris": "text/uri-list",
388
+ "urls": "text/uri-list",
389
+ "vcard": "text/vcard",
390
+ "vrml": "model/vrml",
391
+ "vtt": "text/vtt",
392
+ "vxml": "application/voicexml+xml",
393
+ "war": "application/java-archive",
394
+ "wasm": "application/wasm",
395
+ "wav": "audio/wav",
396
+ "weba": "audio/webm",
397
+ "webm": "video/webm",
398
+ "webmanifest": "application/manifest+json",
399
+ "webp": "image/webp",
400
+ "wgsl": "text/wgsl",
401
+ "wgt": "application/widget",
402
+ "wif": "application/watcherinfo+xml",
403
+ "wmf": "image/wmf",
404
+ "woff": "font/woff",
405
+ "woff2": "font/woff2",
406
+ "wrl": "model/vrml",
407
+ "wsdl": "application/wsdl+xml",
408
+ "wspolicy": "application/wspolicy+xml",
409
+ "x3d": "model/x3d+xml",
410
+ "x3db": "model/x3d+fastinfoset",
411
+ "x3dbz": "model/x3d+binary",
412
+ "x3dv": "model/x3d-vrml",
413
+ "x3dvz": "model/x3d+vrml",
414
+ "x3dz": "model/x3d+xml",
415
+ "xaml": "application/xaml+xml",
416
+ "xav": "application/xcap-att+xml",
417
+ "xca": "application/xcap-caps+xml",
418
+ "xcs": "application/calendar+xml",
419
+ "xdf": "application/xcap-diff+xml",
420
+ "xdssc": "application/dssc+xml",
421
+ "xel": "application/xcap-el+xml",
422
+ "xenc": "application/xenc+xml",
423
+ "xer": "application/patch-ops-error+xml",
424
+ "xfdf": "application/xfdf",
425
+ "xht": "application/xhtml+xml",
426
+ "xhtml": "application/xhtml+xml",
427
+ "xhvml": "application/xv+xml",
428
+ "xlf": "application/xliff+xml",
429
+ "xm": "audio/xm",
430
+ "xml": "text/xml",
431
+ "xns": "application/xcap-ns+xml",
432
+ "xop": "application/xop+xml",
433
+ "xpl": "application/xproc+xml",
434
+ "xsd": "application/xml",
435
+ "xsf": "application/prs.xsf+xml",
436
+ "xsl": "application/xml",
437
+ "xslt": "application/xml",
438
+ "xspf": "application/xspf+xml",
439
+ "xvm": "application/xv+xml",
440
+ "xvml": "application/xv+xml",
441
+ "yaml": "text/yaml",
442
+ "yang": "application/yang",
443
+ "yin": "application/yin+xml",
444
+ "yml": "text/yaml",
445
+ "zip": "application/zip"
446
+ };
447
+ function lookup(extn) {
448
+ let tmp = ("" + extn).trim().toLowerCase();
449
+ let idx = tmp.lastIndexOf(".");
450
+ return mimes[!~idx ? tmp : tmp.substring(++idx)];
451
+ }
452
+
453
+ // ../lazy-file/src/lib/byte-range.ts
454
+ function getByteLength(range, size) {
455
+ let [start, end] = getIndexes(range, size);
456
+ return end - start;
457
+ }
458
+ function getIndexes(range, size) {
459
+ let start = Math.min(Math.max(0, range.start < 0 ? size + range.start : range.start), size);
460
+ let end = Math.min(Math.max(start, range.end < 0 ? size + range.end : range.end), size);
461
+ return [start, end];
462
+ }
463
+
464
+ // ../lazy-file/src/lib/lazy-file.ts
465
+ var LazyBlob = class extends Blob {
466
+ #content;
467
+ constructor(parts, options) {
468
+ super([], options);
469
+ this.#content = new BlobContent(parts, options);
470
+ }
471
+ /**
472
+ * Returns the blob's contents as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).
473
+ *
474
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer)
475
+ */
476
+ async arrayBuffer() {
477
+ return this.#content.arrayBuffer();
478
+ }
479
+ /**
480
+ * Returns the blob's contents as a byte array.
481
+ *
482
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/bytes)
483
+ */
484
+ async bytes() {
485
+ return this.#content.bytes();
486
+ }
487
+ /**
488
+ * The size of the blob in bytes.
489
+ *
490
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size)
491
+ */
492
+ get size() {
493
+ return this.#content.size;
494
+ }
495
+ /**
496
+ * Returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) that contains the data in the specified range.
497
+ *
498
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice)
499
+ */
500
+ slice(start, end, contentType) {
501
+ return this.#content.slice(start, end, contentType);
502
+ }
503
+ /**
504
+ * Returns a stream that can be used to read the blob's contents.
505
+ *
506
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream)
507
+ */
508
+ stream() {
509
+ return this.#content.stream();
510
+ }
511
+ /**
512
+ * Returns the blob's contents as a string.
513
+ *
514
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/text)
515
+ */
516
+ async text() {
517
+ return this.#content.text();
518
+ }
519
+ };
520
+ var LazyFile = class extends File {
521
+ #content;
522
+ constructor(parts, name, options) {
523
+ super([], name, options);
524
+ this.#content = new BlobContent(parts, options);
525
+ }
526
+ /**
527
+ * Returns the file's content as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).
528
+ *
529
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer)
530
+ */
531
+ async arrayBuffer() {
532
+ return this.#content.arrayBuffer();
533
+ }
534
+ /**
535
+ * Returns the file's contents as a byte array.
536
+ *
537
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/bytes)
538
+ */
539
+ async bytes() {
540
+ return this.#content.bytes();
541
+ }
542
+ /**
543
+ * The size of the file in bytes.
544
+ *
545
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size)
546
+ */
547
+ get size() {
548
+ return this.#content.size;
549
+ }
550
+ /**
551
+ * Returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) that contains the data in the specified range.
552
+ *
553
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice)
554
+ */
555
+ slice(start, end, contentType) {
556
+ return this.#content.slice(start, end, contentType);
557
+ }
558
+ /**
559
+ * Returns a stream that can be used to read the file's contents.
560
+ *
561
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream)
562
+ */
563
+ stream() {
564
+ return this.#content.stream();
565
+ }
566
+ /**
567
+ * Returns the file's contents as a string.
568
+ *
569
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/text)
570
+ */
571
+ async text() {
572
+ return this.#content.text();
573
+ }
574
+ };
575
+ var BlobContent = class {
576
+ source;
577
+ totalSize;
578
+ range;
579
+ type;
580
+ constructor(parts, options) {
581
+ if (Array.isArray(parts)) {
582
+ this.source = [];
583
+ this.totalSize = 0;
584
+ for (let part of parts) {
585
+ if (part instanceof Blob) {
586
+ this.source.push(part);
587
+ this.totalSize += part.size;
588
+ } else {
589
+ let array;
590
+ if (typeof part === "string") {
591
+ array = new TextEncoder().encode(part);
592
+ } else if (ArrayBuffer.isView(part)) {
593
+ array = new Uint8Array(part.buffer, part.byteOffset, part.byteLength);
594
+ } else {
595
+ array = new Uint8Array(part);
596
+ }
597
+ this.source.push(array);
598
+ this.totalSize += array.byteLength;
599
+ }
600
+ }
601
+ } else {
602
+ this.source = parts;
603
+ this.totalSize = parts.byteLength;
604
+ }
605
+ this.range = options?.range;
606
+ this.type = options?.type ?? "";
607
+ }
608
+ async arrayBuffer() {
609
+ return (await this.bytes()).buffer;
610
+ }
611
+ async bytes() {
612
+ let result = new Uint8Array(this.size);
613
+ let offset = 0;
614
+ for await (let chunk of this.stream()) {
615
+ result.set(chunk, offset);
616
+ offset += chunk.length;
617
+ }
618
+ return result;
619
+ }
620
+ get size() {
621
+ return this.range != null ? getByteLength(this.range, this.totalSize) : this.totalSize;
622
+ }
623
+ slice(start = 0, end, contentType = "") {
624
+ let range = this.range != null ? (
625
+ // file.slice().slice() is additive
626
+ { start: this.range.start + start, end: this.range.end + (end ?? 0) }
627
+ ) : { start, end: end ?? this.size };
628
+ return new LazyBlob(this.source, { range, type: contentType });
629
+ }
630
+ stream() {
631
+ if (this.range != null) {
632
+ let [start, end] = getIndexes(this.range, this.totalSize);
633
+ return Array.isArray(this.source) ? streamContentArray(this.source, start, end) : this.source.stream(start, end);
634
+ }
635
+ return Array.isArray(this.source) ? streamContentArray(this.source) : this.source.stream();
636
+ }
637
+ async text() {
638
+ return new TextDecoder("utf-8").decode(await this.bytes());
639
+ }
640
+ };
641
+ function streamContentArray(content, start = 0, end = Infinity) {
642
+ let index = 0;
643
+ let bytesRead = 0;
644
+ return new ReadableStream({
645
+ async pull(controller) {
646
+ if (index >= content.length) {
647
+ controller.close();
648
+ return;
649
+ }
650
+ let hasPushed = false;
651
+ function pushChunk(chunk) {
652
+ let chunkLength = chunk.byteLength;
653
+ if (!(bytesRead + chunkLength < start || bytesRead >= end)) {
654
+ let startIndex = Math.max(start - bytesRead, 0);
655
+ let endIndex = Math.min(end - bytesRead, chunkLength);
656
+ controller.enqueue(chunk.subarray(startIndex, endIndex));
657
+ hasPushed = true;
658
+ }
659
+ bytesRead += chunkLength;
660
+ }
661
+ async function pushPart(part) {
662
+ if (part instanceof Blob) {
663
+ if (bytesRead + part.size <= start) {
664
+ bytesRead += part.size;
665
+ return;
666
+ }
667
+ for await (let chunk of part.stream()) {
668
+ pushChunk(chunk);
669
+ if (bytesRead >= end) {
670
+ break;
671
+ }
672
+ }
673
+ } else {
674
+ pushChunk(part);
675
+ }
676
+ }
677
+ while (!hasPushed && index < content.length) {
678
+ await pushPart(content[index++]);
679
+ if (bytesRead >= end) {
680
+ controller.close();
681
+ break;
682
+ }
683
+ }
684
+ }
685
+ });
686
+ }
687
+
688
+ // ../lazy-file/src/fs.ts
689
+ function openFile(filename, options) {
690
+ let stats = fs.statSync(filename);
691
+ if (!stats.isFile()) {
692
+ throw new Error(`Path "${filename}" is not a file`);
693
+ }
694
+ let content = {
695
+ byteLength: stats.size,
696
+ stream(start, end) {
697
+ return streamFile(filename, start, end);
698
+ }
699
+ };
700
+ return new LazyFile(content, options?.name ?? path.basename(filename), {
701
+ type: options?.type ?? lookup(filename),
702
+ lastModified: options?.lastModified ?? stats.mtimeMs
703
+ });
704
+ }
705
+ function streamFile(filename, start = 0, end = Infinity) {
706
+ let read = fs.createReadStream(filename, { start, end: end - 1 }).iterator();
707
+ return new ReadableStream({
708
+ async pull(controller) {
709
+ let { done, value } = await read.next();
710
+ if (done) {
711
+ controller.close();
712
+ } else {
713
+ controller.enqueue(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
714
+ }
715
+ }
716
+ });
717
+ }
718
+ function writeFile(to, file) {
719
+ return new Promise(async (resolve2, reject) => {
720
+ let writeStream = typeof to === "string" ? fs.createWriteStream(to) : fs.createWriteStream("ignored", { fd: to });
721
+ try {
722
+ for await (let chunk of file.stream()) {
723
+ writeStream.write(chunk);
724
+ }
725
+ writeStream.end(() => {
726
+ resolve2();
727
+ });
728
+ } catch (error) {
729
+ writeStream.end(() => {
730
+ reject(error);
731
+ });
732
+ }
733
+ });
734
+ }
735
+
736
+ // src/lib/local-file-storage.ts
737
+ var LocalFileStorage = class {
738
+ #dirname;
739
+ /**
740
+ * @param directory The directory where files are stored
741
+ */
742
+ constructor(directory) {
743
+ this.#dirname = path2.resolve(directory);
744
+ try {
745
+ let stats = fs2.statSync(this.#dirname);
746
+ if (!stats.isDirectory()) {
747
+ throw new Error(`Path "${this.#dirname}" is not a directory`);
748
+ }
749
+ } catch (error) {
750
+ if (!isNoEntityError(error)) {
751
+ throw error;
752
+ }
753
+ fs2.mkdirSync(this.#dirname, { recursive: true });
754
+ }
755
+ }
756
+ async get(key) {
757
+ let { filePath, metaPath } = await this.#getPaths(key);
758
+ try {
759
+ let meta = await readMetadata(metaPath);
760
+ return openFile(filePath, {
761
+ lastModified: meta.lastModified,
762
+ name: meta.name,
763
+ type: meta.type
764
+ });
765
+ } catch (error) {
766
+ if (!isNoEntityError(error)) {
767
+ throw error;
768
+ }
769
+ return null;
770
+ }
771
+ }
772
+ async has(key) {
773
+ let { metaPath } = await this.#getPaths(key);
774
+ try {
775
+ await fsp.access(metaPath);
776
+ return true;
777
+ } catch {
778
+ return false;
779
+ }
780
+ }
781
+ async list(options) {
782
+ let { cursor, includeMetadata = false, limit = 32, prefix } = options ?? {};
783
+ let files = [];
784
+ let foundCursor = cursor === void 0;
785
+ let nextCursor;
786
+ let lastHash;
787
+ outerLoop: for await (let subdir of await fsp.opendir(this.#dirname)) {
788
+ if (!subdir.isDirectory()) continue;
789
+ for await (let file of await fsp.opendir(path2.join(this.#dirname, subdir.name))) {
790
+ if (!file.isFile() || !file.name.endsWith(".meta.json")) continue;
791
+ let hash = file.name.slice(0, -10);
792
+ if (foundCursor) {
793
+ let meta = await readMetadata(path2.join(this.#dirname, subdir.name, file.name));
794
+ if (prefix != null && !meta.key.startsWith(prefix)) {
795
+ continue;
796
+ }
797
+ if (files.length >= limit) {
798
+ nextCursor = lastHash;
799
+ break outerLoop;
800
+ }
801
+ if (includeMetadata) {
802
+ let size = (await fsp.stat(path2.join(this.#dirname, subdir.name, `${hash}.dat`))).size;
803
+ files.push({ ...meta, size });
804
+ } else {
805
+ files.push({ key: meta.key });
806
+ }
807
+ } else if (hash === cursor) {
808
+ foundCursor = true;
809
+ }
810
+ lastHash = hash;
811
+ }
812
+ }
813
+ return {
814
+ cursor: nextCursor,
815
+ files
816
+ };
817
+ }
818
+ async put(key, file) {
819
+ await this.set(key, file);
820
+ return await this.get(key);
821
+ }
822
+ async remove(key) {
823
+ let { filePath, metaPath } = await this.#getPaths(key);
824
+ try {
825
+ await Promise.all([fsp.unlink(filePath), fsp.unlink(metaPath)]);
826
+ } catch (error) {
827
+ if (!isNoEntityError(error)) {
828
+ throw error;
829
+ }
830
+ }
831
+ }
832
+ async set(key, file) {
833
+ let { directory, filePath, metaPath } = await this.#getPaths(key);
834
+ await fsp.mkdir(directory, { recursive: true });
835
+ await writeFile(filePath, file);
836
+ let meta = {
837
+ key,
838
+ lastModified: file.lastModified,
839
+ name: file.name,
840
+ type: file.type
841
+ };
842
+ await fsp.writeFile(metaPath, JSON.stringify(meta));
843
+ }
844
+ async #getPaths(key) {
845
+ let hash = await computeHash(key);
846
+ let directory = path2.join(this.#dirname, hash.slice(0, 2));
847
+ return {
848
+ directory,
849
+ filePath: path2.join(directory, `${hash}.dat`),
850
+ metaPath: path2.join(directory, `${hash}.meta.json`)
851
+ };
852
+ }
853
+ };
854
+ async function readMetadata(metaPath) {
855
+ return JSON.parse(await fsp.readFile(metaPath, "utf-8"));
856
+ }
857
+ async function computeHash(key, algorithm = "SHA-256") {
858
+ let digest = await crypto.subtle.digest(algorithm, new TextEncoder().encode(key));
859
+ return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
860
+ }
861
+ function isNoEntityError(obj) {
862
+ return obj instanceof Error && "code" in obj && obj.code === "ENOENT";
863
+ }
864
+ export {
865
+ LocalFileStorage
866
+ };
867
+ //# sourceMappingURL=local.js.map