@voltro/plugin-storage 0.85.0 → 0.87.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +5987 -0
  2. package/README.md +77 -0
  3. package/THIRD-PARTY-NOTICES.md +860 -249
  4. package/dist/access.js +47 -0
  5. package/dist/assetRef.js +13 -0
  6. package/dist/avatar.js +39 -0
  7. package/dist/byteSecurity.d.ts +3 -0
  8. package/dist/byteSecurity.js +7 -0
  9. package/dist/connection.js +99 -0
  10. package/dist/constraints.js +93 -0
  11. package/dist/custody.js +132 -0
  12. package/dist/derivatives.js +30 -0
  13. package/dist/env.js +162 -0
  14. package/dist/grant.js +132 -0
  15. package/dist/index.d.ts +525 -203
  16. package/dist/index.js +765 -3196
  17. package/dist/ingest.js +87 -0
  18. package/dist/ingestPolicy.js +1 -0
  19. package/dist/metadataError.js +19 -0
  20. package/dist/objectAbandon.js +16 -0
  21. package/dist/objectLifecycle.js +243 -0
  22. package/dist/objectMetadata.js +308 -0
  23. package/dist/objectWriter.js +87 -0
  24. package/dist/pathDurability.js +16 -0
  25. package/dist/physicalReferences.js +54 -0
  26. package/dist/providers.js +638 -0
  27. package/dist/referenceCatalogue.js +31 -0
  28. package/dist/renditionProof.js +82 -0
  29. package/dist/retainedCapture.js +391 -0
  30. package/dist/retainedObjects.js +190 -0
  31. package/dist/rpc.d.ts +3 -15
  32. package/dist/rpc.js +3 -1
  33. package/dist/scanners.js +46 -0
  34. package/dist/server.d.ts +153 -0
  35. package/dist/server.js +4 -0
  36. package/dist/service.js +1418 -0
  37. package/dist/sourceIdentity.js +14 -0
  38. package/dist/sourcePin.js +35 -0
  39. package/dist/storageNamespaces.js +80 -0
  40. package/dist/storageNumbers.js +13 -0
  41. package/dist/storageObjectNamespaces.js +243 -0
  42. package/dist/storageReferenceInstances.js +52 -0
  43. package/dist/storageRequest.js +10 -0
  44. package/dist/storageRouting.js +46 -0
  45. package/dist/streamBridge.js +33 -0
  46. package/dist/table.js +54 -0
  47. package/dist/transcodeVideo.js +91 -0
  48. package/dist/transform.js +94 -0
  49. package/dist/transformCache.js +31 -0
  50. package/dist/types.d.ts +116 -134
  51. package/dist/types.js +14 -14
  52. package/package.json +17 -6
@@ -0,0 +1,638 @@
1
+ import { canonicalStorageRoot as e, filesystemObjectNamespace as t, storageEndpointIdentity as n, storageObjectNamespace as r } from "./storageNamespaces.js";
2
+ import { storageReferenceCatalogueId as i } from "./referenceCatalogue.js";
3
+ import { STORAGE_BLOBS_TABLE as a } from "./table.js";
4
+ import { StorageError as o } from "./types.js";
5
+ import { storageInteger as s } from "./storageNumbers.js";
6
+ import { concatBytes as c, fromNodeReadable as l, toNodeReadable as u } from "./streamBridge.js";
7
+ import { storageEnv as d } from "./env.js";
8
+ import { storageMetadataError as f } from "./metadataError.js";
9
+ import { storageRequest as p } from "./storageRequest.js";
10
+ import { Effect as m } from "effect";
11
+ import { randomUUID as h } from "node:crypto";
12
+ import { authoredError as g, generateId as _ } from "@voltro/database";
13
+ //#region src/providers.ts
14
+ var v = (e, t, n, r) => new o({
15
+ provider: e,
16
+ message: t,
17
+ transient: n,
18
+ ...r === void 0 ? {} : { status: r }
19
+ }), y = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, b = h(), x = /* @__PURE__ */ new WeakMap(), S = /* @__PURE__ */ new Map(), C = (e, t) => S.get(e)?.get(t)?.bytes, w = (e) => {
20
+ S.get(e)?.clear();
21
+ }, T = (e = "default") => {
22
+ let t = S.get(e) ?? /* @__PURE__ */ new Map();
23
+ return S.set(e, t), E(t);
24
+ }, E = (e) => {
25
+ let t = x.get(e);
26
+ return t === void 0 && (t = r([
27
+ "memory",
28
+ b,
29
+ h()
30
+ ]), x.set(e, t)), {
31
+ objectLocation: (t) => m.succeed({
32
+ namespace: e,
33
+ key: t
34
+ }),
35
+ name: "memory",
36
+ objectNamespace: m.succeed(t),
37
+ presigns: !1,
38
+ put: (t, n, r) => m.sync(() => (e.set(t, {
39
+ bytes: n,
40
+ contentType: r.contentType
41
+ }), { size: n.byteLength })),
42
+ get: (t) => m.suspend(() => {
43
+ let n = e.get(t);
44
+ return n ? m.succeed({
45
+ bytes: n.bytes,
46
+ contentType: n.contentType
47
+ }) : m.fail(v("memory", `no object at key '${t}'`, !1, 404));
48
+ }),
49
+ delete: (t) => m.sync(() => {
50
+ e.delete(t);
51
+ }),
52
+ publicUrl: () => null,
53
+ getUrl: () => m.succeed(""),
54
+ head: (t) => m.sync(() => {
55
+ let n = e.get(t);
56
+ return n ? {
57
+ size: n.bytes.byteLength,
58
+ contentType: n.contentType
59
+ } : null;
60
+ })
61
+ };
62
+ }, D = (n) => {
63
+ let r = e(n.root), i = async (e) => {
64
+ if (e.split("/")[0]?.startsWith(".voltro-object-namespace")) throw Error("Storage namespace metadata is not an object key");
65
+ let { join: t, resolve: n, sep: i } = await import("node:path"), a = n(r), o = n(a, e);
66
+ if (o.startsWith(n(a, ".voltro-object-namespace"))) throw Error("Storage namespace metadata is not an object key");
67
+ if (o !== a && !o.startsWith(a + i)) throw Error(`key '${e}' escapes the storage root`);
68
+ return t(o);
69
+ }, a = (e, t, n = !1) => m.tryPromise({
70
+ try: e,
71
+ catch: (e) => e?.code === "ENOENT" ? v("filesystem", `no object at key '${t}'`, !1, 404) : v("filesystem", String(e?.message ?? e), n)
72
+ });
73
+ return {
74
+ root: r,
75
+ objectLocation: (e) => a(async () => {
76
+ let t = await import("node:fs/promises"), { dirname: n, basename: r, join: a } = await import("node:path"), o = await i(e), s = [];
77
+ for (;;) try {
78
+ return {
79
+ namespace: "filesystem",
80
+ key: a(await t.realpath(o), ...s)
81
+ };
82
+ } catch (e) {
83
+ if (e.code !== "ENOENT") throw e;
84
+ let t = n(o);
85
+ if (t === o) throw e;
86
+ s.unshift(r(o)), o = t;
87
+ }
88
+ }, e),
89
+ name: "filesystem",
90
+ objectNamespace: m.try({
91
+ try: () => t(r),
92
+ catch: (e) => v("filesystem", String(e instanceof Error ? e.message : e), !1)
93
+ }),
94
+ presigns: !1,
95
+ put: (e, t, n) => a(async () => {
96
+ let n = await import("node:fs/promises"), { dirname: r } = await import("node:path"), { randomUUID: a } = await import("node:crypto"), o = await i(e), s = r(o);
97
+ await n.mkdir(s, { recursive: !0 });
98
+ let c = `${o}.tmp-${a()}`;
99
+ try {
100
+ await n.writeFile(c, t), await n.rename(c, o);
101
+ } catch (e) {
102
+ throw await n.rm(c, { force: !0 }).catch(() => {}), e;
103
+ }
104
+ return { size: t.byteLength };
105
+ }, e, !0),
106
+ get: (e) => a(async () => {
107
+ let t = await (await import("node:fs/promises")).readFile(await i(e));
108
+ return {
109
+ bytes: new Uint8Array(t),
110
+ contentType: "application/octet-stream"
111
+ };
112
+ }, e),
113
+ delete: (e) => a(async () => {
114
+ await (await import("node:fs/promises")).rm(await i(e), { force: !0 });
115
+ }, e),
116
+ publicUrl: () => null,
117
+ getUrl: () => m.succeed(""),
118
+ head: (e) => m.tryPromise({
119
+ try: async () => {
120
+ let t = await import("node:fs/promises");
121
+ try {
122
+ return { size: (await t.stat(await i(e))).size };
123
+ } catch (e) {
124
+ if (e?.code === "ENOENT") return null;
125
+ throw e;
126
+ }
127
+ },
128
+ catch: (e) => v("filesystem", String(e?.message ?? e), !1)
129
+ }),
130
+ getStream: (e) => a(async () => {
131
+ let t = await import("node:fs/promises"), { createReadStream: n } = await import("node:fs"), r = await i(e), a = await t.stat(r);
132
+ return {
133
+ stream: l("filesystem", () => n(r)),
134
+ contentType: "application/octet-stream",
135
+ size: a.size
136
+ };
137
+ }, e),
138
+ putStream: (e, t, n) => a(async (n) => {
139
+ let r = await import("node:fs/promises"), { dirname: a } = await import("node:path"), { randomUUID: o } = await import("node:crypto"), { createWriteStream: s } = await import("node:fs"), { pipeline: c } = await import("node:stream/promises"), l = await i(e);
140
+ n.throwIfAborted(), await r.mkdir(a(l), { recursive: !0 });
141
+ let d = `${l}.tmp-${o()}`;
142
+ try {
143
+ await c(await u(t), s(d), { signal: n });
144
+ let e = await r.stat(d);
145
+ return n.throwIfAborted(), await r.rename(d, l), { size: e.size };
146
+ } catch (e) {
147
+ throw await r.rm(d, { force: !0 }).catch(() => {}), e;
148
+ }
149
+ }, e, !0),
150
+ getRange: (e, t, n) => a(async () => {
151
+ let { createReadStream: r } = await import("node:fs"), a = await i(e), o = [];
152
+ return await new Promise((e, i) => {
153
+ let s = r(a, {
154
+ start: t,
155
+ end: n
156
+ });
157
+ s.on("data", (e) => o.push(e)), s.on("end", () => e()), s.on("error", i);
158
+ }), c(o);
159
+ }, e)
160
+ };
161
+ }, O = (e) => k(e).provider, k = (e) => {
162
+ let t = e.name ?? "s3", i = e.publicAcl ?? !0, a = null, s = () => a || (a = (async () => {
163
+ let t, n;
164
+ try {
165
+ t = await import("@aws-sdk/client-s3"), n = await import("@aws-sdk/s3-request-presigner");
166
+ } catch (e) {
167
+ throw Error("the 's3'/'minio' storage provider requires the '@aws-sdk/client-s3' + '@aws-sdk/s3-request-presigner' optional dependencies. Install them to enable it.", { cause: e });
168
+ }
169
+ return {
170
+ client: new t.S3Client({
171
+ maxAttempts: 1,
172
+ ...e.region ? { region: e.region } : { region: "us-east-1" },
173
+ ...e.endpoint ? { endpoint: e.endpoint } : {},
174
+ ...e.forcePathStyle ? { forcePathStyle: !0 } : {},
175
+ ...e.accessKeyId && e.secretAccessKey ? { credentials: {
176
+ accessKeyId: e.accessKeyId,
177
+ secretAccessKey: e.secretAccessKey
178
+ } } : {}
179
+ }),
180
+ cmds: t,
181
+ presign: n.getSignedUrl
182
+ };
183
+ })(), a), c = (e, n) => p(e, (e) => {
184
+ if (e instanceof o) return e;
185
+ let n = e?.$metadata?.httpStatusCode;
186
+ return v(t, String(e?.message ?? e), y(n), n);
187
+ }, n), d = async (e, t) => {
188
+ let n = e, r = () => {
189
+ n.destroy?.();
190
+ };
191
+ t.addEventListener("abort", r, { once: !0 });
192
+ try {
193
+ if (t.aborted) throw r(), Error("Storage read interrupted");
194
+ if (typeof n.transformToByteArray == "function") return await n.transformToByteArray();
195
+ let e = [];
196
+ for await (let t of n) e.push(t);
197
+ let i = e.reduce((e, t) => e + t.byteLength, 0), a = new Uint8Array(i), o = 0;
198
+ for (let t of e) a.set(t, o), o += t.byteLength;
199
+ return a;
200
+ } finally {
201
+ t.removeEventListener("abort", r);
202
+ }
203
+ };
204
+ return {
205
+ provider: {
206
+ name: t,
207
+ objectLocation: (n) => m.try({
208
+ try: () => ({
209
+ namespace: JSON.stringify([
210
+ "s3",
211
+ e.endpoint === void 0 ? "aws" : new URL(e.endpoint).href.replace(/\/+$/, ""),
212
+ e.bucket
213
+ ]),
214
+ key: n
215
+ }),
216
+ catch: () => v(t, "Storage endpoint cannot identify its physical namespace", !1)
217
+ }),
218
+ objectNamespace: m.succeed(r([
219
+ "s3",
220
+ e.endpoint ? n(e.endpoint) : "aws-s3",
221
+ e.bucket
222
+ ])),
223
+ presigns: !0,
224
+ put: (t, n, r) => c(async (a) => {
225
+ let { client: o, cmds: c } = await s();
226
+ return await o.send(new c.PutObjectCommand({
227
+ Bucket: e.bucket,
228
+ Key: t,
229
+ Body: n,
230
+ ContentType: r.contentType,
231
+ ...r.public && i ? { ACL: "public-read" } : {}
232
+ }), { abortSignal: a }), { size: n.byteLength };
233
+ }),
234
+ get: (t) => c(async (n) => {
235
+ let { client: r, cmds: i } = await s(), a = await r.send(new i.GetObjectCommand({
236
+ Bucket: e.bucket,
237
+ Key: t
238
+ }), { abortSignal: n });
239
+ return {
240
+ bytes: await d(a.Body, n),
241
+ contentType: a.ContentType ?? "application/octet-stream"
242
+ };
243
+ }),
244
+ delete: (t) => c(async (n) => {
245
+ let { client: r, cmds: i } = await s();
246
+ await r.send(new i.DeleteObjectCommand({
247
+ Bucket: e.bucket,
248
+ Key: t
249
+ }), { abortSignal: n });
250
+ }),
251
+ publicUrl: (t) => e.cdnBaseUrl ? `${e.cdnBaseUrl.replace(/\/$/, "")}/${t}` : null,
252
+ ...i ? { setObjectPublic: (t, n) => c(async (r) => {
253
+ let { client: i, cmds: a } = await s();
254
+ await i.send(new a.PutObjectAclCommand({
255
+ Bucket: e.bucket,
256
+ Key: t,
257
+ ACL: n ? "public-read" : "private"
258
+ }), { abortSignal: r });
259
+ }) } : {},
260
+ getUrl: (t, n) => c(async (r) => {
261
+ let { client: i, cmds: a, presign: o } = await s();
262
+ return o(i, new a.GetObjectCommand({
263
+ Bucket: e.bucket,
264
+ Key: t
265
+ }), { expiresIn: n });
266
+ }),
267
+ getUploadUrl: (t, n, r) => c(async (i) => {
268
+ let { client: a, cmds: o, presign: c } = await s();
269
+ return c(a, new o.PutObjectCommand({
270
+ Bucket: e.bucket,
271
+ Key: t,
272
+ ContentType: r
273
+ }), { expiresIn: n });
274
+ }),
275
+ createMultipartUpload: (t, n, r) => c(async (a) => {
276
+ let { client: o, cmds: c } = await s(), l = await o.send(new c.CreateMultipartUploadCommand({
277
+ Bucket: e.bucket,
278
+ Key: t,
279
+ ContentType: n,
280
+ ...r?.public && i ? { ACL: "public-read" } : {}
281
+ }), { abortSignal: a });
282
+ if (!l.UploadId) throw Error("s3 createMultipartUpload returned no UploadId");
283
+ return { uploadId: l.UploadId };
284
+ }),
285
+ presignUploadPart: (t, n, r, i) => c(async (a) => {
286
+ let { client: o, cmds: c, presign: l } = await s();
287
+ return l(o, new c.UploadPartCommand({
288
+ Bucket: e.bucket,
289
+ Key: t,
290
+ UploadId: n,
291
+ PartNumber: r
292
+ }), { expiresIn: i });
293
+ }),
294
+ completeMultipartUpload: (t, n, r) => c(async (i) => {
295
+ let { client: a, cmds: o } = await s(), c = await a.send(new o.CompleteMultipartUploadCommand({
296
+ Bucket: e.bucket,
297
+ Key: t,
298
+ UploadId: n,
299
+ MultipartUpload: { Parts: r.map((e) => ({
300
+ PartNumber: e.partNumber,
301
+ ETag: e.etag
302
+ })) }
303
+ }), { abortSignal: i });
304
+ return c.ETag === void 0 ? {} : { etag: c.ETag };
305
+ }),
306
+ abortMultipartUpload: (t, n) => c(async (r) => {
307
+ let { client: i, cmds: a } = await s();
308
+ await i.send(new a.AbortMultipartUploadCommand({
309
+ Bucket: e.bucket,
310
+ Key: t,
311
+ UploadId: n
312
+ }), { abortSignal: r });
313
+ }),
314
+ head: (t) => c(async (n) => {
315
+ let { client: r, cmds: i } = await s();
316
+ try {
317
+ let a = await r.send(new i.HeadObjectCommand({
318
+ Bucket: e.bucket,
319
+ Key: t
320
+ }), { abortSignal: n });
321
+ return {
322
+ size: a.ContentLength ?? 0,
323
+ contentType: a.ContentType ?? "application/octet-stream",
324
+ ...a.ETag === void 0 ? {} : { etag: a.ETag }
325
+ };
326
+ } catch (e) {
327
+ if (e?.$metadata?.httpStatusCode === 404) return null;
328
+ throw e;
329
+ }
330
+ }),
331
+ getStream: (n) => c(async (r) => {
332
+ let { client: i, cmds: a } = await s(), o = await i.send(new a.GetObjectCommand({
333
+ Bucket: e.bucket,
334
+ Key: n
335
+ }), { abortSignal: r }), c = o.Body;
336
+ return {
337
+ stream: l(t, () => c),
338
+ close: m.sync(() => {
339
+ c.destroy();
340
+ }),
341
+ contentType: o.ContentType ?? "application/octet-stream",
342
+ ...o.ContentLength === void 0 ? {} : { size: o.ContentLength }
343
+ };
344
+ }, (e) => e.close ?? m.void),
345
+ putStream: (n, r, a) => c(async (c) => {
346
+ let { client: l, cmds: d } = await s(), f;
347
+ try {
348
+ f = await import("@aws-sdk/lib-storage");
349
+ } catch (e) {
350
+ throw Error("s3/minio `putStream` requires the '@aws-sdk/lib-storage' optional dependency (multipart upload). Install it to enable streamed uploads.", { cause: e });
351
+ }
352
+ c.throwIfAborted();
353
+ let p = await u(r), m = new AbortController(), h = AbortSignal.any([c, m.signal]), g = () => {
354
+ p.destroy(/* @__PURE__ */ Error("Storage upload interrupted"));
355
+ }, _ = (e) => {
356
+ m.abort(e);
357
+ }, v = new Proxy(l, { get(e, t, n) {
358
+ return t === "send" ? (e) => l.send(e, { abortSignal: h }).then((t) => {
359
+ if (e instanceof d.UploadPartCommand && (!("ETag" in t) || !t.ETag)) throw Error("Storage upload part acknowledgement omitted its ETag");
360
+ return t;
361
+ }).catch((e) => {
362
+ throw m.abort(e), e;
363
+ }) : Reflect.get(e, t, n);
364
+ } }), y = new f.Upload({
365
+ client: v,
366
+ leavePartsOnError: !0,
367
+ params: {
368
+ Bucket: e.bucket,
369
+ Key: n,
370
+ Body: p,
371
+ ContentType: a.contentType,
372
+ ...a.public && i ? { ACL: "public-read" } : {}
373
+ }
374
+ });
375
+ p.once("error", _), h.addEventListener("abort", g, { once: !0 });
376
+ try {
377
+ h.aborted && g(), await y.done();
378
+ } catch (r) {
379
+ if (y.uploadId !== void 0) try {
380
+ await l.send(new d.AbortMultipartUploadCommand({
381
+ Bucket: e.bucket,
382
+ Key: n,
383
+ UploadId: y.uploadId
384
+ }), { abortSignal: AbortSignal.timeout(5e3) });
385
+ } catch {
386
+ throw new o({
387
+ provider: t,
388
+ message: "Multipart cleanup was not confirmed; object outcome is unknown",
389
+ transient: !1,
390
+ outcome: "unknown"
391
+ });
392
+ }
393
+ throw r;
394
+ } finally {
395
+ h.removeEventListener("abort", g), p.removeListener("error", _), p.destroy();
396
+ }
397
+ return { size: a.totalSize ?? (await l.send(new d.HeadObjectCommand({
398
+ Bucket: e.bucket,
399
+ Key: n
400
+ }), { abortSignal: c })).ContentLength ?? 0 };
401
+ }),
402
+ getRange: (t, n, r) => c(async (i) => {
403
+ let { client: a, cmds: o } = await s(), c = await a.send(new o.GetObjectCommand({
404
+ Bucket: e.bucket,
405
+ Key: t,
406
+ Range: `bytes=${n}-${r}`
407
+ }), { abortSignal: i });
408
+ return d(c.Body, i);
409
+ })
410
+ },
411
+ probe: c(async (t) => {
412
+ let { client: n, cmds: r } = await s();
413
+ await n.send(new r.HeadBucketCommand({ Bucket: e.bucket }), { abortSignal: t });
414
+ }),
415
+ close: m.promise(async () => {
416
+ a !== null && (await a.catch(() => null))?.client.destroy();
417
+ })
418
+ };
419
+ }, A = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), j = () => {
420
+ let e = null, t = () => {
421
+ if (!e) throw g("the 'database' storage provider isn't bound to a DataStore yet");
422
+ return e;
423
+ }, n = (e) => m.tryPromise({
424
+ try: e,
425
+ catch: (e) => f(e, "database", !0)
426
+ }), o = async (e, n) => (await t().query({
427
+ table: a,
428
+ predicate: {
429
+ column: "key",
430
+ op: "eq",
431
+ value: e
432
+ },
433
+ order: [],
434
+ take: 1,
435
+ skip: void 0,
436
+ projection: n
437
+ }))[0];
438
+ return {
439
+ name: "database",
440
+ objectLocation: (e) => n(async () => ({
441
+ namespace: r([
442
+ "database",
443
+ await i(t()),
444
+ a
445
+ ]),
446
+ key: e
447
+ })),
448
+ objectNamespace: n(async () => r([
449
+ "database",
450
+ await i(t()),
451
+ a
452
+ ])),
453
+ presigns: !1,
454
+ bindDataStore: (t) => {
455
+ e = t;
456
+ },
457
+ put: (e, r, i) => n(async () => {
458
+ let n = await o(e);
459
+ return n ? await t().update(a, String(n.id), {
460
+ data: r,
461
+ contentType: i.contentType,
462
+ size: String(r.byteLength)
463
+ }) : await t().insert(a, {
464
+ id: _({
465
+ kind: "typeid",
466
+ prefix: "blob"
467
+ }, a),
468
+ key: e,
469
+ data: r,
470
+ contentType: i.contentType,
471
+ size: String(r.byteLength)
472
+ }), { size: r.byteLength };
473
+ }),
474
+ get: (e) => m.suspend(() => n(() => o(e)).pipe(m.flatMap((t) => t ? m.succeed({
475
+ bytes: A(t.data),
476
+ contentType: String(t.contentType)
477
+ }) : m.fail(v("database", `no object at key '${e}'`, !1, 404))))),
478
+ delete: (e) => n(async () => {
479
+ let n = await o(e, ["id"]);
480
+ n && await t().delete(a, String(n.id));
481
+ }),
482
+ publicUrl: () => null,
483
+ getUrl: () => m.succeed(""),
484
+ head: (e) => n(async () => {
485
+ let t = await o(e, ["size", "contentType"]);
486
+ return t ? {
487
+ size: s(t.size, "blob size"),
488
+ contentType: String(t.contentType)
489
+ } : null;
490
+ })
491
+ };
492
+ }, M = (e) => {
493
+ let t = d.read("AZURE_STORAGE_ACCOUNT", e.accountName), n = d.read("AZURE_STORAGE_KEY", e.accountKey), r = d.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString);
494
+ return N({
495
+ ...e,
496
+ ...t === void 0 ? {} : { accountName: t },
497
+ ...n === void 0 ? {} : { accountKey: n },
498
+ ...r === void 0 ? {} : { connectionString: r }
499
+ }).provider;
500
+ }, N = (e) => {
501
+ let t = new AbortController(), i = null, a = () => i || (i = (async () => {
502
+ let t;
503
+ try {
504
+ t = await import("@azure/storage-blob");
505
+ } catch (e) {
506
+ throw Error("the 'azure' storage provider requires the '@azure/storage-blob' optional dependency. Install it to enable it.", { cause: e });
507
+ }
508
+ let n = e.accountName, r = e.accountKey, i = n && r ? new t.StorageSharedKeyCredential(n, r) : null, a = e.connectionString;
509
+ return {
510
+ container: (a ? t.BlobServiceClient.fromConnectionString(a, { retryOptions: { maxTries: 1 } }) : new t.BlobServiceClient(e.endpoint ?? `https://${n}.blob.core.windows.net`, i ?? void 0, { retryOptions: { maxTries: 1 } })).getContainerClient(e.container),
511
+ sdk: t,
512
+ cred: i
513
+ };
514
+ })(), i), o = (e, n) => p((n) => e(AbortSignal.any([n, t.signal])), (e) => {
515
+ let t = e?.statusCode;
516
+ return v("azure", String(e?.message ?? e), y(t), t);
517
+ }, n), s = async (e, t) => {
518
+ if (!e) return /* @__PURE__ */ new Uint8Array();
519
+ let n = () => {
520
+ e.destroy();
521
+ };
522
+ t.addEventListener("abort", n, { once: !0 });
523
+ try {
524
+ if (t.aborted) throw n(), Error("Storage read interrupted");
525
+ let r = [];
526
+ for await (let t of e) r.push(typeof t == "string" ? new TextEncoder().encode(t) : new Uint8Array(t));
527
+ let i = r.reduce((e, t) => e + t.byteLength, 0), a = new Uint8Array(i), o = 0;
528
+ for (let e of r) a.set(e, o), o += e.byteLength;
529
+ return a;
530
+ } finally {
531
+ t.removeEventListener("abort", n);
532
+ }
533
+ }, c = async (t, n, r) => {
534
+ let { container: i, sdk: o, cred: s } = await a();
535
+ if (!s) throw Error("azure SAS requires accountName + accountKey (set them or AZURE_STORAGE_ACCOUNT/AZURE_STORAGE_KEY)");
536
+ let c = i.getBlockBlobClient(t), l = o.generateBlobSASQueryParameters({
537
+ containerName: e.container,
538
+ blobName: t,
539
+ permissions: o.BlobSASPermissions.parse(n),
540
+ startsOn: /* @__PURE__ */ new Date(Date.now() - 6e4),
541
+ expiresOn: new Date(Date.now() + r * 1e3)
542
+ }, s).toString();
543
+ return `${c.url}?${l}`;
544
+ };
545
+ return {
546
+ provider: {
547
+ name: "azure",
548
+ objectLocation: (e) => o(async () => {
549
+ let t = (await a()).container, n = new URL(t.url);
550
+ return n.search = "", n.hash = "", {
551
+ namespace: JSON.stringify(["azure", n.href.replace(/\/+$/, "")]),
552
+ key: e
553
+ };
554
+ }),
555
+ objectNamespace: o(async () => {
556
+ let { container: e } = await a();
557
+ return r(["azure", n(e.url)]);
558
+ }),
559
+ presigns: !0,
560
+ put: (e, t, n) => o(async (r) => {
561
+ let { container: i } = await a();
562
+ return await i.getBlockBlobClient(e).uploadData(Buffer.from(t), {
563
+ blobHTTPHeaders: { blobContentType: n.contentType },
564
+ abortSignal: r
565
+ }), { size: t.byteLength };
566
+ }),
567
+ get: (e) => o(async (t) => {
568
+ let { container: n } = await a(), r = await n.getBlockBlobClient(e).download(0, void 0, { abortSignal: t });
569
+ return {
570
+ bytes: await s(r.readableStreamBody, t),
571
+ contentType: r.contentType ?? "application/octet-stream"
572
+ };
573
+ }),
574
+ delete: (e) => o(async (t) => {
575
+ let { container: n } = await a();
576
+ await n.getBlockBlobClient(e).deleteIfExists({ abortSignal: t });
577
+ }),
578
+ publicUrl: (t) => e.cdnBaseUrl ? `${e.cdnBaseUrl.replace(/\/$/, "")}/${t}` : null,
579
+ getUrl: (e, t) => o(() => c(e, "r", t)),
580
+ getUploadUrl: (e, t, n) => o(() => c(e, "cw", t)),
581
+ head: (e) => o(async (t) => {
582
+ let { container: n } = await a();
583
+ try {
584
+ let r = await n.getBlockBlobClient(e).getProperties({ abortSignal: t });
585
+ return {
586
+ size: r.contentLength ?? 0,
587
+ contentType: r.contentType ?? "application/octet-stream",
588
+ ...r.etag === void 0 ? {} : { etag: r.etag }
589
+ };
590
+ } catch (e) {
591
+ if (e?.statusCode === 404) return null;
592
+ throw e;
593
+ }
594
+ }),
595
+ getStream: (e) => o(async (t) => {
596
+ let { container: n } = await a(), r = await n.getBlockBlobClient(e).download(0, void 0, { abortSignal: t });
597
+ return {
598
+ stream: l("azure", () => r.readableStreamBody),
599
+ close: m.sync(() => {
600
+ r.readableStreamBody?.destroy();
601
+ }),
602
+ contentType: r.contentType ?? "application/octet-stream",
603
+ ...r.contentLength === void 0 ? {} : { size: r.contentLength }
604
+ };
605
+ }, (e) => e.close ?? m.void),
606
+ putStream: (e, n, r) => o(async (i) => {
607
+ let { container: o } = await a();
608
+ i.throwIfAborted();
609
+ let s = await u(n), c = () => {
610
+ s.destroy();
611
+ };
612
+ i.addEventListener("abort", c, { once: !0 });
613
+ try {
614
+ if (i.aborted) throw c(), Error("Storage upload interrupted");
615
+ await o.getBlockBlobClient(e).uploadStream(s, 4194304, 5, {
616
+ blobHTTPHeaders: { blobContentType: r.contentType },
617
+ abortSignal: i
618
+ });
619
+ } finally {
620
+ i.removeEventListener("abort", c), s.destroy();
621
+ }
622
+ return { size: r.totalSize ?? (await o.getBlockBlobClient(e).getProperties({ abortSignal: AbortSignal.any([i, t.signal]) })).contentLength ?? 0 };
623
+ }),
624
+ getRange: (e, t, n) => o(async (r) => {
625
+ let { container: i } = await a(), o = await i.getBlockBlobClient(e).download(t, n - t + 1, { abortSignal: r });
626
+ return s(o.readableStreamBody, r);
627
+ })
628
+ },
629
+ probe: o(async (e) => {
630
+ await (await a()).container.getProperties({ abortSignal: e });
631
+ }),
632
+ close: m.sync(() => {
633
+ t.abort();
634
+ })
635
+ };
636
+ };
637
+ //#endregion
638
+ export { N as azureConnectionTransport, M as azureProvider, w as clearStorageBuffer, j as databaseProvider, D as filesystemProvider, T as memoryProvider, E as memoryProviderWithState, C as readStorageBuffer, k as s3ConnectionTransport, O as s3Provider };
@@ -0,0 +1,31 @@
1
+ import { storageObjectNamespace as e } from "./storageNamespaces.js";
2
+ import { randomUUID as t } from "node:crypto";
3
+ import { authoredError as n, eq as r, table as i, text as a } from "@voltro/database";
4
+ //#region src/referenceCatalogue.ts
5
+ var o = "_voltro_storage_reference_catalogue", s = i(o, {
6
+ id: a().maxLength(64),
7
+ namespace: a().maxLength(64)
8
+ }).primaryKey(["id"]).nonReactive(), c = async (n) => {
9
+ await n.insertIgnoreWithOutcome(o, {
10
+ id: "catalogue",
11
+ namespace: e(["reference-catalogue", t()])
12
+ }, { conflictColumns: ["id"] }), await l(n);
13
+ }, l = async (t, i) => {
14
+ let a = await t.query({
15
+ table: o,
16
+ predicate: r("id", "catalogue"),
17
+ order: [],
18
+ take: 2,
19
+ skip: void 0,
20
+ projection: void 0
21
+ }), s = a[0]?.namespace;
22
+ if (a.length !== 1 || typeof s != "string" || !/^[a-f0-9]{64}$/.test(s)) throw n("Storage reference catalogue identity is missing or invalid; initialize it after normal schema reconciliation before serving inspection");
23
+ return i ? e([
24
+ "reference-view",
25
+ s,
26
+ i.storageInstance,
27
+ i.objectNamespace
28
+ ]) : s;
29
+ };
30
+ //#endregion
31
+ export { o as STORAGE_REFERENCE_CATALOGUE_TABLE, c as ensureStorageReferenceCatalogue, l as storageReferenceCatalogueId, s as storageReferenceCatalogueTable };