@voltro/plugin-storage 0.80.0 → 0.82.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/index.js CHANGED
@@ -2,86 +2,87 @@ import { StorageAccessDenied as e, StorageError as t, StorageRejected as n, Stor
2
2
  import { abortMultipartUploadDescriptor as a, beginMultipartUploadDescriptor as o, beginResumableUploadDescriptor as s, completeMultipartUploadDescriptor as c, finalizeUploadDescriptor as l, ingestUrlDescriptor as u, listGrantsDescriptor as d, listRefsDescriptor as f, mintPresignedUploadDescriptor as p, mintUploadTicketDescriptor as m, mintUploadUrlDescriptor as ee, mintUrlDescriptor as te, revokeDescriptor as h, shareDescriptor as ne, signMultipartPartDescriptor as g, storageRpcClientImports as re, uploadDescriptor as ie } from "./rpc.js";
3
3
  import { processIdentity as _ } from "@voltro/protocol/identity";
4
4
  import { Chunk as v, Effect as y, Exit as b, Layer as x, Schedule as S, Schema as C, Stream as w } from "effect";
5
- import { definePlugin as ae, pluginInstanceName as oe } from "@voltro/protocol";
6
- import { readCookie as se, resolveSessionSecret as ce, verifySession as le } from "@voltro/protocol/session";
7
- import { and as T, bytes as ue, contains as E, eq as D, generateId as O, id as de, integer as k, json as A, mixin as j, neq as M, or as fe, reference as pe, table as N, text as P, timestamp as me } from "@voltro/database";
8
- import { pluginEnv as F } from "@voltro/env";
9
- import { createHash as he, createHmac as I, randomBytes as L, randomUUID as ge, scryptSync as _e, timingSafeEqual as R } from "node:crypto";
10
- import { spawn as ve } from "node:child_process";
11
- import { mkdtemp as ye, readFile as be, rm as xe, writeFile as Se } from "node:fs/promises";
12
- import { tmpdir as Ce } from "node:os";
5
+ import { definePlugin as T, pluginInstanceName as ae } from "@voltro/protocol";
6
+ import { readCookie as oe, resolveSessionSecret as se, verifySession as ce } from "@voltro/protocol/session";
7
+ import { and as E, bytes as le, contains as D, eq as O, generateId as k, id as ue, integer as A, json as j, mixin as de, neq as M, or as N, reference as fe, table as P, text as F, timestamp as pe } from "@voltro/database";
8
+ import { pluginEnv as me } from "@voltro/env";
9
+ import { createHash as he, createHmac as I, randomBytes as ge, randomUUID as _e, scryptSync as L, timingSafeEqual as R } from "node:crypto";
10
+ import { ssrfReason as ve } from "@voltro/runtime";
11
+ import { spawn as ye } from "node:child_process";
12
+ import { mkdtemp as be, readFile as xe, rm as Se, writeFile as Ce } from "node:fs/promises";
13
+ import { tmpdir as we } from "node:os";
13
14
  import { join as z } from "node:path";
14
15
  import { statSync as B } from "node:fs";
15
16
  //#region src/streamBridge.ts
16
- var we = 1 << 20, Te = (e, n, r = !1) => new t({
17
+ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
17
18
  provider: e,
18
19
  message: n,
19
20
  transient: r
20
- }), Ee = (e) => {
21
+ }), De = (e) => {
21
22
  let t = 0;
22
23
  for (let n of e) t += n.byteLength;
23
24
  let n = new Uint8Array(t), r = 0;
24
25
  for (let t of e) n.set(t, r), r += t.byteLength;
25
26
  return n;
26
- }, De = (e, t = we) => {
27
+ }, Oe = (e, t = Te) => {
27
28
  let n = [];
28
29
  for (let r = 0; r < e.byteLength; r += t) n.push(e.subarray(r, Math.min(r + t, e.byteLength)));
29
30
  return w.fromIterable(n);
30
- }, Oe = (e) => e.pipe(w.runCollect, y.map((e) => Ee(v.toReadonlyArray(e)))), ke = (e, t) => w.suspend(() => w.fromAsyncIterable(t(), (t) => Te(e, `read stream failed: ${String(t?.message ?? t)}`, !0))).pipe(w.map((e) => e instanceof Uint8Array ? e : new Uint8Array(e))), Ae = async (e) => {
31
+ }, ke = (e) => e.pipe(w.runCollect, y.map((e) => De(v.toReadonlyArray(e)))), Ae = (e, t) => w.suspend(() => w.fromAsyncIterable(t(), (t) => Ee(e, `read stream failed: ${String(t?.message ?? t)}`, !0))).pipe(w.map((e) => e instanceof Uint8Array ? e : new Uint8Array(e))), je = async (e) => {
31
32
  let { Readable: t } = await import("node:stream");
32
33
  return t.fromWeb(w.toReadableStream(e));
33
- }, je = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(y.map((e) => ({
34
- stream: De(e.bytes),
34
+ }, Me = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(y.map((e) => ({
35
+ stream: Oe(e.bytes),
35
36
  contentType: e.contentType,
36
37
  size: e.bytes.byteLength
37
- }))), Me = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : Oe(n).pipe(y.flatMap((n) => e.put(t, n, {
38
+ }))), Ne = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : ke(n).pipe(y.flatMap((n) => e.put(t, n, {
38
39
  contentType: r.contentType,
39
40
  ...r.public === void 0 ? {} : { public: r.public }
40
- }))), V = "_voltro_storage_refs", H = "_voltro_storage_grants", U = "_voltro_storage_blobs", Ne = "_voltro_storage_usage", Pe = N(V, {
41
- id: de({ prefix: "file" }),
42
- tenantId: P().nullable(),
43
- ownerId: P().nullable(),
44
- bucket: P(),
45
- key: P(),
46
- contentType: P(),
47
- size: k(),
48
- checksum: P(),
49
- visibility: P(),
50
- accessPolicy: A().nullable(),
51
- passwordHash: P().nullable(),
52
- width: k().nullable(),
53
- height: k().nullable(),
54
- duration: k().nullable(),
55
- placeholder: P().nullable(),
56
- folder: P().nullable(),
57
- tags: A().nullable(),
58
- alt: P().nullable(),
59
- caption: P().nullable(),
60
- derivedFrom: P().nullable(),
61
- kind: P().nullable(),
62
- createdAt: me()
63
- }).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]), Fe = N(H, {
64
- id: de({ prefix: "sgrant" }),
65
- refId: P(),
66
- principalType: P(),
67
- principalId: P(),
68
- permission: P(),
69
- createdAt: me(),
70
- expiresAt: me().nullable(),
71
- createdBy: P().nullable()
72
- }).index(["refId"]).index(["principalId"]), Ie = N(Ne, {
73
- id: de({ prefix: "susage" }),
74
- tenantId: P().maxLength(191),
75
- bytes: k().default(0),
76
- count: k().default(0),
77
- updatedAt: me()
78
- }).unique("byStorageUsageTenant", ["tenantId"]), Le = N(U, {
79
- id: de({ prefix: "blob" }),
80
- key: P(),
81
- data: ue(),
82
- contentType: P(),
83
- size: k()
84
- }).index(["key"]), W = F([
41
+ }))), V = "_voltro_storage_refs", H = "_voltro_storage_grants", U = "_voltro_storage_blobs", Pe = "_voltro_storage_usage", Fe = P(V, {
42
+ id: ue({ prefix: "file" }),
43
+ tenantId: F().nullable(),
44
+ ownerId: F().nullable(),
45
+ bucket: F(),
46
+ key: F(),
47
+ contentType: F(),
48
+ size: A(),
49
+ checksum: F(),
50
+ visibility: F(),
51
+ accessPolicy: j().nullable(),
52
+ passwordHash: F().nullable(),
53
+ width: A().nullable(),
54
+ height: A().nullable(),
55
+ duration: A().nullable(),
56
+ placeholder: F().nullable(),
57
+ folder: F().nullable(),
58
+ tags: j().nullable(),
59
+ alt: F().nullable(),
60
+ caption: F().nullable(),
61
+ derivedFrom: F().nullable(),
62
+ kind: F().nullable(),
63
+ createdAt: pe()
64
+ }).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]), Ie = P(H, {
65
+ id: ue({ prefix: "sgrant" }),
66
+ refId: F(),
67
+ principalType: F(),
68
+ principalId: F(),
69
+ permission: F(),
70
+ createdAt: pe(),
71
+ expiresAt: pe().nullable(),
72
+ createdBy: F().nullable()
73
+ }).index(["refId"]).index(["principalId"]), Le = P(Pe, {
74
+ id: ue({ prefix: "susage" }),
75
+ tenantId: F().maxLength(191),
76
+ bytes: A().default(0),
77
+ count: A().default(0),
78
+ updatedAt: pe()
79
+ }).unique("byStorageUsageTenant", ["tenantId"]), Re = P(U, {
80
+ id: ue({ prefix: "blob" }),
81
+ key: F(),
82
+ data: le(),
83
+ contentType: F(),
84
+ size: A()
85
+ }).index(["key"]), W = me([
85
86
  {
86
87
  name: "STORAGE_PROVIDER",
87
88
  required: !1,
@@ -237,11 +238,11 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
237
238
  message: n,
238
239
  transient: r,
239
240
  ...i === void 0 ? {} : { status: i }
240
- }), Re = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, ze = /* @__PURE__ */ new Map(), Be = (e, t) => ze.get(e)?.get(t)?.bytes, Ve = (e) => {
241
- ze.get(e)?.clear();
242
- }, He = (e = "default") => {
243
- let t = ze.get(e) ?? /* @__PURE__ */ new Map();
244
- return ze.set(e, t), {
241
+ }), ze = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, Be = /* @__PURE__ */ new Map(), Ve = (e, t) => Be.get(e)?.get(t)?.bytes, He = (e) => {
242
+ Be.get(e)?.clear();
243
+ }, Ue = (e = "default") => {
244
+ let t = Be.get(e) ?? /* @__PURE__ */ new Map();
245
+ return Be.set(e, t), {
245
246
  name: "memory",
246
247
  presigns: !1,
247
248
  put: (e, n, r) => y.sync(() => (t.set(e, {
@@ -265,7 +266,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
265
266
  return n ? { size: n.bytes.byteLength } : null;
266
267
  })
267
268
  };
268
- }, Ue = (e) => {
269
+ }, We = (e) => {
269
270
  let t = e.root, n = async (e) => {
270
271
  let { join: n, resolve: r, sep: i } = await import("node:path"), a = r(t), o = r(a, e);
271
272
  if (o !== a && !o.startsWith(a + i)) throw Error(`key '${e}' escapes the storage root`);
@@ -316,7 +317,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
316
317
  getStream: (e) => r(async () => {
317
318
  let t = await import("node:fs/promises"), { createReadStream: r } = await import("node:fs"), i = await n(e), a = await t.stat(i);
318
319
  return {
319
- stream: ke("filesystem", () => r(i)),
320
+ stream: Ae("filesystem", () => r(i)),
320
321
  contentType: "application/octet-stream",
321
322
  size: a.size
322
323
  };
@@ -326,7 +327,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
326
327
  await r.mkdir(i(c), { recursive: !0 });
327
328
  let l = `${c}.tmp-${a()}`;
328
329
  try {
329
- await s(await Ae(t), o(l));
330
+ await s(await je(t), o(l));
330
331
  let e = await r.stat(l);
331
332
  return await r.rename(l, c), { size: e.size };
332
333
  } catch (e) {
@@ -341,10 +342,10 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
341
342
  end: i
342
343
  });
343
344
  s.on("data", (e) => o.push(e)), s.on("end", () => e()), s.on("error", n);
344
- }), Ee(o);
345
+ }), De(o);
345
346
  }, e)
346
347
  };
347
- }, We = (e) => {
348
+ }, Ge = (e) => {
348
349
  let t = e.name ?? "s3", n = e.publicAcl ?? !0, r = null, i = () => r || (r = (async () => {
349
350
  let t, n;
350
351
  try {
@@ -369,7 +370,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
369
370
  try: e,
370
371
  catch: (e) => {
371
372
  let n = e?.$metadata?.httpStatusCode;
372
- return G(t, String(e?.message ?? e), Re(n), n);
373
+ return G(t, String(e?.message ?? e), ze(n), n);
373
374
  }
374
375
  }), o = async (e) => {
375
376
  let t = e;
@@ -411,6 +412,14 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
411
412
  }));
412
413
  }),
413
414
  publicUrl: (t) => e.cdnBaseUrl ? `${e.cdnBaseUrl.replace(/\/$/, "")}/${t}` : null,
415
+ ...n ? { setObjectPublic: (t, n) => a(async () => {
416
+ let { client: r, cmds: a } = await i();
417
+ await r.send(new a.PutObjectAclCommand({
418
+ Bucket: e.bucket,
419
+ Key: t,
420
+ ACL: n ? "public-read" : "private"
421
+ }));
422
+ }) } : {},
414
423
  getUrl: (t, n) => a(async () => {
415
424
  let { client: r, cmds: a, presign: o } = await i();
416
425
  return o(r, new a.GetObjectCommand({
@@ -484,7 +493,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
484
493
  },
485
494
  catch: (e) => {
486
495
  let n = e?.$metadata?.httpStatusCode;
487
- return G(t, String(e?.message ?? e), Re(n), n);
496
+ return G(t, String(e?.message ?? e), ze(n), n);
488
497
  }
489
498
  }),
490
499
  getStream: (n) => a(async () => {
@@ -493,7 +502,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
493
502
  Key: n
494
503
  })), s = o.Body;
495
504
  return {
496
- stream: ke(t, () => s),
505
+ stream: Ae(t, () => s),
497
506
  contentType: o.ContentType ?? "application/octet-stream",
498
507
  ...o.ContentLength === void 0 ? {} : { size: o.ContentLength }
499
508
  };
@@ -505,7 +514,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
505
514
  } catch (e) {
506
515
  throw Error("s3/minio `putStream` requires the '@aws-sdk/lib-storage' optional dependency (multipart upload). Install it to enable streamed uploads.", { cause: e });
507
516
  }
508
- let l = await Ae(r);
517
+ let l = await je(r);
509
518
  return await new c.Upload({
510
519
  client: a,
511
520
  params: {
@@ -529,7 +538,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
529
538
  return o(c.Body);
530
539
  })
531
540
  };
532
- }, Ge = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), Ke = () => {
541
+ }, Ke = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), qe = () => {
533
542
  let e = null, t = () => {
534
543
  if (!e) throw Error("the 'database' storage provider isn't bound to a DataStore yet");
535
544
  return e;
@@ -561,7 +570,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
561
570
  contentType: a.contentType,
562
571
  size: i.byteLength
563
572
  }) : await t().insert(U, {
564
- id: O({
573
+ id: k({
565
574
  kind: "typeid",
566
575
  prefix: "blob"
567
576
  }, U),
@@ -572,7 +581,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
572
581
  }), { size: i.byteLength };
573
582
  }),
574
583
  get: (e) => y.suspend(() => n(() => r(e)).pipe(y.flatMap((t) => t ? y.succeed({
575
- bytes: Ge(t.data),
584
+ bytes: Ke(t.data),
576
585
  contentType: String(t.contentType)
577
586
  }) : y.fail(G("database", `no object at key '${e}'`, !1, 404))))),
578
587
  delete: (e) => n(async () => {
@@ -586,7 +595,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
586
595
  return t ? { size: Number(t.size) } : null;
587
596
  })
588
597
  };
589
- }, qe = (e) => {
598
+ }, Je = (e) => {
590
599
  let t = null, n = () => t || (t = (async () => {
591
600
  let t;
592
601
  try {
@@ -604,7 +613,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
604
613
  try: e,
605
614
  catch: (e) => {
606
615
  let t = e?.statusCode;
607
- return G("azure", String(e?.message ?? e), Re(t), t);
616
+ return G("azure", String(e?.message ?? e), ze(t), t);
608
617
  }
609
618
  }), i = async (e) => {
610
619
  if (!e) return /* @__PURE__ */ new Uint8Array();
@@ -662,19 +671,19 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
662
671
  },
663
672
  catch: (e) => {
664
673
  let t = e?.statusCode;
665
- return G("azure", String(e?.message ?? e), Re(t), t);
674
+ return G("azure", String(e?.message ?? e), ze(t), t);
666
675
  }
667
676
  }),
668
677
  getStream: (e) => r(async () => {
669
678
  let { container: t } = await n(), r = await t.getBlockBlobClient(e).download();
670
679
  return {
671
- stream: ke("azure", () => r.readableStreamBody),
680
+ stream: Ae("azure", () => r.readableStreamBody),
672
681
  contentType: r.contentType ?? "application/octet-stream",
673
682
  ...r.contentLength === void 0 ? {} : { size: r.contentLength }
674
683
  };
675
684
  }),
676
685
  putStream: (e, t, i) => r(async () => {
677
- let { container: r } = await n(), a = await Ae(t);
686
+ let { container: r } = await n(), a = await je(t);
678
687
  return await r.getBlockBlobClient(e).uploadStream(a, 4194304, 5, { blobHTTPHeaders: { blobContentType: i.contentType } }), { size: i.totalSize ?? (await r.getBlockBlobClient(e).getProperties()).contentLength ?? 0 };
679
688
  }),
680
689
  getRange: (e, t, a) => r(async () => {
@@ -682,98 +691,114 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
682
691
  return i(o.readableStreamBody);
683
692
  })
684
693
  };
685
- }, Je = {
694
+ }, Ye = (e, t, n, r, i, a) => {
695
+ let o = n / r, s = Math.min(e, Math.round(t * o)), c = Math.min(t, Math.round(s / o)), l = (e, t) => Math.max(0, Math.min(t, e));
696
+ return {
697
+ left: l(Math.round(i * e - s / 2), e - s),
698
+ top: l(Math.round(a * t - c / 2), t - c),
699
+ width: s,
700
+ height: c
701
+ };
702
+ }, Xe = {
686
703
  webp: "image/webp",
687
704
  avif: "image/avif",
688
705
  jpeg: "image/jpeg",
689
706
  jpg: "image/jpeg",
690
707
  png: "image/png"
691
- }, Ye = (e) => {
708
+ }, Ze = (e) => {
692
709
  if (!e) return null;
693
710
  let t = new URLSearchParams(e), n = (e) => {
694
711
  let n = t.get(e);
695
712
  if (n == null) return;
696
713
  let r = Number(n);
697
714
  return Number.isFinite(r) && r > 0 ? Math.floor(r) : void 0;
698
- }, r = n("w"), i = n("h"), a = n("q"), o = (t.get("format") ?? t.get("fm") ?? void 0)?.toLowerCase(), s = t.get("fit") ?? void 0;
715
+ }, r = n("w"), i = n("h"), a = n("q"), o = (t.get("format") ?? t.get("fm") ?? void 0)?.toLowerCase(), s = t.get("fit") ?? void 0, c = (t.get("fp") ?? "").split(",").map(Number), l = c.length === 2 && c.every((e) => Number.isFinite(e) && e >= 0 && e <= 1) ? {
716
+ x: c[0],
717
+ y: c[1]
718
+ } : void 0;
699
719
  return r === void 0 && i === void 0 && !o && a === void 0 ? null : {
700
720
  ...r === void 0 ? {} : { w: r },
701
721
  ...i === void 0 ? {} : { h: i },
702
722
  ...o ? { format: o } : {},
703
723
  ...a === void 0 ? {} : { q: a },
704
- ...s ? { fit: s } : {}
724
+ ...s ? { fit: s } : {},
725
+ ...l ? { fp: l } : {}
705
726
  };
706
- }, Xe = (e) => e.startsWith("image/") && !e.includes("svg"), Ze, Qe = async () => {
707
- if (Ze !== void 0) return Ze;
727
+ }, Qe = (e) => e.startsWith("image/") && !e.includes("svg"), $e, et = async () => {
728
+ if ($e !== void 0) return $e;
708
729
  try {
709
730
  let e = await import("sharp");
710
- Ze = e.default ?? e;
731
+ $e = e.default ?? e;
711
732
  } catch {
712
- Ze = null;
733
+ $e = null;
713
734
  }
714
- return Ze;
715
- }, $e = async (e, t, n) => {
716
- if (!Xe(t)) return null;
717
- let r = await Qe();
735
+ return $e;
736
+ }, tt = async (e, t) => t ? null : Qe(e) ? await et() === null ? "no-sharp" : "failed" : "not-an-image", nt = async (e, t, n) => {
737
+ if (!Qe(t)) return null;
738
+ let r = await et();
718
739
  if (!r) return null;
719
740
  try {
720
- let i = r(Buffer.from(e), { failOn: "none" });
741
+ let i = r(Buffer.from(e), { failOn: "none" }), a = n.fit ?? "cover";
742
+ if (n.fp !== void 0 && n.w !== void 0 && n.h !== void 0 && a === "cover") {
743
+ let e = await i.metadata();
744
+ e.width !== void 0 && e.height !== void 0 && (i = i.extract(Ye(e.width, e.height, n.w, n.h, n.fp.x, n.fp.y)));
745
+ }
721
746
  (n.w !== void 0 || n.h !== void 0) && (i = i.resize({
722
747
  ...n.w === void 0 ? {} : { width: n.w },
723
748
  ...n.h === void 0 ? {} : { height: n.h },
724
749
  fit: n.fit ?? "cover",
725
750
  withoutEnlargement: !0
726
751
  }));
727
- let a = n.format && Je[n.format] ? n.format : void 0, o = t;
728
- if (a) {
729
- let e = a === "jpg" ? "jpeg" : a;
730
- i = i.toFormat(e, n.q === void 0 ? {} : { quality: n.q }), o = Je[a];
752
+ let o = n.format && Xe[n.format] ? n.format : void 0, s = t;
753
+ if (o) {
754
+ let e = o === "jpg" ? "jpeg" : o;
755
+ i = i.toFormat(e, n.q === void 0 ? {} : { quality: n.q }), s = Xe[o];
731
756
  } else n.q !== void 0 && (t === "image/jpeg" || t === "image/webp") && (i = i.toFormat(t === "image/webp" ? "webp" : "jpeg", { quality: n.q }));
732
- let s = await i.toBuffer();
757
+ let c = await i.toBuffer();
733
758
  return {
734
- bytes: new Uint8Array(s),
735
- contentType: o
759
+ bytes: new Uint8Array(c),
760
+ contentType: s
736
761
  };
737
762
  } catch {
738
763
  return null;
739
764
  }
740
- }, et = 200, tt = /* @__PURE__ */ new Map(), nt = async (e, t, n, r) => {
741
- let i = `${e}::${JSON.stringify(r)}`, a = tt.get(i);
765
+ }, rt = 200, it = /* @__PURE__ */ new Map(), at = async (e, t, n, r) => {
766
+ let i = `${e}::${JSON.stringify(r)}`, a = it.get(i);
742
767
  if (a) return a;
743
- let o = await $e(t, n, r);
744
- if (o && (tt.set(i, o), tt.size > et)) {
745
- let e = tt.keys().next().value;
746
- e !== void 0 && tt.delete(e);
768
+ let o = await nt(t, n, r);
769
+ if (o && (it.set(i, o), it.size > rt)) {
770
+ let e = it.keys().next().value;
771
+ e !== void 0 && it.delete(e);
747
772
  }
748
773
  return o;
749
- }, rt = (e) => {
750
- let t = L(16).toString("hex");
751
- return `${t}:${_e(e, t, 32).toString("hex")}`;
752
- }, it = (e, t) => {
774
+ }, ot = (e) => {
775
+ let t = ge(16).toString("hex");
776
+ return `${t}:${L(e, t, 32).toString("hex")}`;
777
+ }, st = (e, t) => {
753
778
  if (!e || !t) return !1;
754
779
  let [n, r] = t.split(":");
755
780
  if (!n || !r) return !1;
756
- let i = Buffer.from(r, "hex"), a = _e(e, n, i.length);
781
+ let i = Buffer.from(r, "hex"), a = L(e, n, i.length);
757
782
  return a.length === i.length && R(a, i);
758
- }, at = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], ot = (e) => at(e.metadata?.roles), st = (e) => at(e.scopes), ct = (e, t) => e.some((e) => t.includes(e)), lt = (e) => at(e.metadata?.groups), ut = (e) => typeof e == "boolean" ? y.succeed(e) : y.isEffect(e) ? e : y.promise(() => e), dt = (e, t, n = {}) => y.gen(function* () {
783
+ }, ct = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], lt = (e) => ct(e.metadata?.roles), ut = (e) => ct(e.scopes), dt = (e, t) => e.some((e) => t.includes(e)), ft = (e) => ct(e.metadata?.groups), pt = (e) => typeof e == "boolean" ? y.succeed(e) : y.isEffect(e) ? e : y.promise(() => e), mt = (e, t, n = {}) => y.gen(function* () {
759
784
  if (t.id && e.ownerId && t.id === e.ownerId) return !0;
760
785
  let r = e.accessPolicy ?? [];
761
786
  if (r.length === 0) return !1;
762
- let i = n.resolveGroups ? yield* y.promise(async () => await n.resolveGroups(t)) : lt(t);
763
- for (let a of r) if (yield* ft(a, e, t, i, n)) return !0;
787
+ let i = n.resolveGroups ? yield* y.promise(async () => await n.resolveGroups(t)) : ft(t);
788
+ for (let a of r) if (yield* ht(a, e, t, i, n)) return !0;
764
789
  return !1;
765
- }), ft = (e, t, n, r, i) => y.gen(function* () {
790
+ }), ht = (e, t, n, r, i) => y.gen(function* () {
766
791
  let a = !1, o = (e) => (a = !0, e);
767
- if (e.owner !== void 0 && e.owner && !o(!!n.id && !!t.ownerId && n.id === t.ownerId) || e.tenant !== void 0 && e.tenant && !o(!!n.tenantId && n.tenantId === t.tenantId) || e.apiKey !== void 0 && e.apiKey && !o(n.type === "apiKey") || e.roles && e.roles.length > 0 && !o(ct(ot(n), e.roles)) || e.groups && e.groups.length > 0 && !o(ct(r, e.groups)) || e.scopes && e.scopes.length > 0 && !o(ct(st(n), e.scopes)) || e.password !== void 0 && e.password && !o(it(i.password, t.passwordHash))) return !1;
792
+ if (e.owner !== void 0 && e.owner && !o(!!n.id && !!t.ownerId && n.id === t.ownerId) || e.tenant !== void 0 && e.tenant && !o(!!n.tenantId && n.tenantId === t.tenantId) || e.apiKey !== void 0 && e.apiKey && !o(n.type === "apiKey") || e.roles && e.roles.length > 0 && !o(dt(lt(n), e.roles)) || e.groups && e.groups.length > 0 && !o(dt(r, e.groups)) || e.scopes && e.scopes.length > 0 && !o(dt(ut(n), e.scopes)) || e.password !== void 0 && e.password && !o(st(i.password, t.passwordHash))) return !1;
768
793
  if (e.guard) {
769
794
  let r = i.guards?.[e.guard];
770
- if (!o(r ? yield* ut(r({
795
+ if (!o(r ? yield* pt(r({
771
796
  subject: n,
772
797
  ref: t
773
798
  })) : !1)) return !1;
774
799
  }
775
800
  return a;
776
- }), pt = (e, t) => {
801
+ }), gt = (e, t) => {
777
802
  let n = [];
778
803
  e.id && n.push({
779
804
  type: e.type === "apiKey" ? "apiKey" : "user",
@@ -784,13 +809,13 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
784
809
  id: e
785
810
  });
786
811
  return n;
787
- }, mt = (e, t, n, r, i) => {
788
- let a = pt(t, n);
812
+ }, _t = (e, t, n, r, i) => {
813
+ let a = gt(t, n);
789
814
  return e.some((e) => e.expiresAt && e.expiresAt.getTime() < i || r === "write" && e.permission !== "write" ? !1 : a.some((t) => t.type === e.principalType && t.id === e.principalId));
790
- }, ht = (e, t) => t.resolveGroups ? y.promise(async () => await t.resolveGroups(e)) : y.succeed(lt(e)), K = () => W.read("VOLTRO_STORAGE_SECRET") ?? ce(), q = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), J = (e) => {
815
+ }, vt = (e, t) => t.resolveGroups ? y.promise(async () => await t.resolveGroups(e)) : y.succeed(ft(e)), K = () => W.read("VOLTRO_STORAGE_SECRET") ?? se(), q = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), J = (e) => {
791
816
  let t = e.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - e.length % 4) % 4);
792
817
  return Buffer.from(t, "base64");
793
- }, gt = (e, t, n = K(), r = "/_voltro/storage") => {
818
+ }, yt = (e, t, n = K(), r = "/_voltro/storage") => {
794
819
  if (!n) throw Error("signGrant: secret must be a non-empty string");
795
820
  let i = {
796
821
  refId: e,
@@ -798,7 +823,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
798
823
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
799
824
  }, a = q(JSON.stringify(i));
800
825
  return `${a}.${q(I("sha256", n).update(a).digest())}`;
801
- }, _t = (e, t = K()) => {
826
+ }, bt = (e, t = K()) => {
802
827
  if (!e || !t) return null;
803
828
  let n = e.indexOf(".");
804
829
  if (n <= 0 || n === e.length - 1) return null;
@@ -810,14 +835,14 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
810
835
  } catch {
811
836
  return null;
812
837
  }
813
- }, vt = (e, t, n = K()) => {
838
+ }, xt = (e, t, n = K()) => {
814
839
  if (!n) throw Error("signUploadTicket: secret must be a non-empty string");
815
840
  let r = {
816
841
  ...e,
817
842
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
818
843
  }, i = q(JSON.stringify(r));
819
844
  return `${i}.${q(I("sha256", n).update(`u:${i}`).digest())}`;
820
- }, yt = (e, t = K()) => {
845
+ }, St = (e, t = K()) => {
821
846
  if (!e || !t) return null;
822
847
  let n = e.indexOf(".");
823
848
  if (n <= 0 || n === e.length - 1) return null;
@@ -829,14 +854,14 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
829
854
  } catch {
830
855
  return null;
831
856
  }
832
- }, bt = (e, t, n = K()) => {
857
+ }, Ct = (e, t, n = K()) => {
833
858
  if (!n) throw Error("signFinalizeTicket: secret must be a non-empty string");
834
859
  let r = {
835
860
  ...e,
836
861
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
837
862
  }, i = q(JSON.stringify(r));
838
863
  return `${i}.${q(I("sha256", n).update(`f:${i}`).digest())}`;
839
- }, xt = (e, t = K()) => {
864
+ }, wt = (e, t = K()) => {
840
865
  if (!e || !t) return null;
841
866
  let n = e.indexOf(".");
842
867
  if (n <= 0 || n === e.length - 1) return null;
@@ -848,14 +873,14 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
848
873
  } catch {
849
874
  return null;
850
875
  }
851
- }, St = (e, t, n = K()) => {
876
+ }, Tt = (e, t, n = K()) => {
852
877
  if (!n) throw Error("signResumableTicket: secret must be a non-empty string");
853
878
  let r = {
854
879
  ...e,
855
880
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
856
881
  }, i = q(JSON.stringify(r));
857
882
  return `${i}.${q(I("sha256", n).update(`r:${i}`).digest())}`;
858
- }, Ct = (e, t = K()) => {
883
+ }, Et = (e, t = K()) => {
859
884
  if (!e || !t) return null;
860
885
  let n = e.indexOf(".");
861
886
  if (n <= 0 || n === e.length - 1) return null;
@@ -867,14 +892,14 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
867
892
  } catch {
868
893
  return null;
869
894
  }
870
- }, wt = (e, t, n = K()) => {
895
+ }, Dt = (e, t, n = K()) => {
871
896
  if (!n) throw Error("signMultipartTicket: secret must be a non-empty string");
872
897
  let r = {
873
898
  ...e,
874
899
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
875
900
  }, i = q(JSON.stringify(r));
876
901
  return `${i}.${q(I("sha256", n).update(`m:${i}`).digest())}`;
877
- }, Tt = (e, t = K()) => {
902
+ }, Ot = (e, t = K()) => {
878
903
  if (!e || !t) return null;
879
904
  let n = e.indexOf(".");
880
905
  if (n <= 0 || n === e.length - 1) return null;
@@ -886,14 +911,14 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
886
911
  } catch {
887
912
  return null;
888
913
  }
889
- }, Et = (e, t) => {
914
+ }, kt = (e, t) => {
890
915
  if (!t || t.length === 0) return !0;
891
916
  let n = e.toLowerCase();
892
917
  return t.some((e) => {
893
918
  let t = e.toLowerCase();
894
919
  return t.endsWith("/*") ? n.startsWith(t.slice(0, -1)) : n === t;
895
920
  });
896
- }, Dt = [
921
+ }, At = [
897
922
  {
898
923
  ct: /^image\/png$/,
899
924
  offset: 0,
@@ -963,21 +988,21 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
963
988
  offset: 0,
964
989
  magic: [31, 139]
965
990
  }
966
- ], Ot = (e, t) => {
967
- let n = t.toLowerCase(), r = Dt.find((e) => e.ct.test(n));
991
+ ], jt = (e, t) => {
992
+ let n = t.toLowerCase(), r = At.find((e) => e.ct.test(n));
968
993
  return r ? e.length < r.offset + r.magic.length ? !1 : r.magic.every((t, n) => e[r.offset + n] === t) : !0;
969
- }, kt = (e, t, n) => n ? n.maxBytes !== void 0 && e.byteLength > n.maxBytes ? {
994
+ }, Mt = (e, t, n) => n ? n.maxBytes !== void 0 && e.byteLength > n.maxBytes ? {
970
995
  reason: "too-large",
971
996
  detail: `${e.byteLength} bytes exceeds the ${n.maxBytes}-byte limit`
972
- } : Et(t, n.allowedContentTypes) ? n.sniff && !Ot(e, t) ? {
997
+ } : kt(t, n.allowedContentTypes) ? n.sniff && !jt(e, t) ? {
973
998
  reason: "content-mismatch",
974
999
  detail: `bytes do not match the declared content type '${t}'`
975
1000
  } : null : {
976
1001
  reason: "content-type-not-allowed",
977
1002
  detail: `content type '${t}' is not in the allow-list`
978
- } : null, At = async (e, t, n) => {
979
- if (!Xe(t)) return { bytes: e };
980
- let r = await Qe();
1003
+ } : null, Nt = async (e, t, n) => {
1004
+ if (!Qe(t)) return { bytes: e };
1005
+ let r = await et();
981
1006
  if (!r) return { bytes: e };
982
1007
  try {
983
1008
  let t = e;
@@ -1000,47 +1025,63 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1000
1025
  } catch {
1001
1026
  return { bytes: e };
1002
1027
  }
1003
- }, jt = 67108864, Mt = (e) => new n({
1028
+ }, Pt = 67108864, Ft = (e) => new n({
1004
1029
  reason: "too-large",
1005
1030
  detail: `remote body exceeds the ${e}-byte ingest limit`
1006
- }), Nt = (e, r) => y.suspend(() => {
1007
- let i = r ?? jt;
1008
- return !Number.isSafeInteger(i) || i < 0 ? y.fail(new t({
1031
+ }), It = (e, t) => new n({
1032
+ reason: "blocked-source",
1033
+ detail: `will not fetch ${e}: ${t}`
1034
+ }), Lt = (e, r, i = {}) => y.suspend(() => {
1035
+ let a = r ?? Pt;
1036
+ return !Number.isSafeInteger(a) || a < 0 ? y.fail(new t({
1009
1037
  provider: "ingest",
1010
1038
  message: "limits.maxBytes must be a non-negative safe integer",
1011
1039
  transient: !1
1012
1040
  })) : y.tryPromise({
1013
1041
  try: async (n) => {
1014
- let r = await fetch(e, { signal: n }), a;
1042
+ let r = e, o;
1043
+ for (let e = 0;; e++) {
1044
+ let t = ve(r, { ...i.allowHosts === void 0 ? {} : { allowHosts: i.allowHosts } });
1045
+ if (t !== null) throw It(r, t);
1046
+ o = await fetch(r, {
1047
+ signal: n,
1048
+ redirect: "manual"
1049
+ });
1050
+ let a = o.headers.get("location");
1051
+ if (o.status < 300 || o.status >= 400 || a === null) break;
1052
+ if (await o.body?.cancel().catch(() => {}), e >= (i.maxRedirects ?? 5)) throw It(r, "too many redirects");
1053
+ r = new URL(a, r).toString();
1054
+ }
1055
+ let s;
1015
1056
  try {
1016
- if (!r.ok) throw new t({
1057
+ if (!o.ok) throw new t({
1017
1058
  provider: "ingest",
1018
- message: `remote server returned HTTP ${r.status}`,
1019
- transient: r.status === 429 || r.status >= 500,
1020
- status: r.status
1059
+ message: `remote server returned HTTP ${o.status}`,
1060
+ transient: o.status === 429 || o.status >= 500,
1061
+ status: o.status
1021
1062
  });
1022
- let e = r.headers.get("content-length"), n = r.headers.get("content-encoding")?.trim().toLowerCase();
1023
- if ((!n || n === "identity") && e !== null && /^\d+$/.test(e) && BigInt(e) > BigInt(i)) throw Mt(i);
1024
- let o = /* @__PURE__ */ new Uint8Array(), s = 0;
1025
- if (r.body !== null) for (a = r.body.getReader();;) {
1026
- let e = await a.read();
1063
+ let e = o.headers.get("content-length"), n = o.headers.get("content-encoding")?.trim().toLowerCase();
1064
+ if ((!n || n === "identity") && e !== null && /^\d+$/.test(e) && BigInt(e) > BigInt(a)) throw Ft(a);
1065
+ let r = /* @__PURE__ */ new Uint8Array(), i = 0;
1066
+ if (o.body !== null) for (s = o.body.getReader();;) {
1067
+ let e = await s.read();
1027
1068
  if (e.done) break;
1028
- if (e.value.byteLength > i - s) throw Mt(i);
1069
+ if (e.value.byteLength > a - i) throw Ft(a);
1029
1070
  if (e.value.byteLength !== 0) {
1030
- let t = s + e.value.byteLength;
1031
- if (t > o.byteLength) {
1032
- let e = Math.min(i, Math.max(65536, o.byteLength * 2, t)), n = new Uint8Array(e);
1033
- n.set(o), o = n;
1071
+ let t = i + e.value.byteLength;
1072
+ if (t > r.byteLength) {
1073
+ let e = Math.min(a, Math.max(65536, r.byteLength * 2, t)), n = new Uint8Array(e);
1074
+ n.set(r), r = n;
1034
1075
  }
1035
- o.set(e.value, s), s = t;
1076
+ r.set(e.value, i), i = t;
1036
1077
  }
1037
1078
  }
1038
1079
  return {
1039
- bytes: s === o.byteLength ? o : o.slice(0, s),
1040
- contentType: r.headers.get("content-type")?.split(";")[0]?.trim() || "application/octet-stream"
1080
+ bytes: i === r.byteLength ? r : r.slice(0, i),
1081
+ contentType: o.headers.get("content-type")?.split(";")[0]?.trim() || "application/octet-stream"
1041
1082
  };
1042
1083
  } finally {
1043
- a === void 0 ? await r.body?.cancel().catch(() => {}) : (await a.cancel().catch(() => {}), a.releaseLock());
1084
+ s === void 0 ? await o.body?.cancel().catch(() => {}) : (await s.cancel().catch(() => {}), s.releaseLock());
1044
1085
  }
1045
1086
  },
1046
1087
  catch: (e) => e instanceof n || e instanceof t ? e : new t({
@@ -1049,7 +1090,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1049
1090
  transient: !0
1050
1091
  })
1051
1092
  });
1052
- }), Pt = (e, t) => y.suspend(() => {
1093
+ }), Rt = (e, t) => y.suspend(() => {
1053
1094
  if (t === void 0) return e;
1054
1095
  if (t.aborted) return y.interrupt;
1055
1096
  let n = y.async((e) => {
@@ -1057,7 +1098,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1057
1098
  return t.addEventListener("abort", n, { once: !0 }), t.aborted && n(), y.sync(() => t.removeEventListener("abort", n));
1058
1099
  });
1059
1100
  return y.raceFirst(e, n);
1060
- }), Ft = (e) => {
1101
+ }), zt = (e) => {
1061
1102
  let r = (e, r) => y.tryPromise({
1062
1103
  try: r,
1063
1104
  catch: (r) => C.is(n)(r) ? r : new t({
@@ -1089,10 +1130,10 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1089
1130
  "operation" in a && (a.operation.deleteKey !== null && (yield* e.provider.delete(a.operation.deleteKey)), yield* r("delete confirmation", () => e.metadata.confirmDelete(a.identity)));
1090
1131
  })
1091
1132
  };
1092
- }, It = async (e) => {
1133
+ }, Bt = async (e) => {
1093
1134
  let { createHash: t } = await import("node:crypto");
1094
1135
  return t("sha256").update(e).digest("hex");
1095
- }, Lt = (e, t, n) => `${e?.replace(/\/+$/, "") ?? ""}${n}/${t}`, Rt = (e) => {
1136
+ }, Vt = (e, t, n) => `${e?.replace(/\/+$/, "") ?? ""}${n}/${t}`, Ht = (e) => {
1096
1137
  let t = /* @__PURE__ */ new Map(), n = {
1097
1138
  public: 0,
1098
1139
  private: 0
@@ -1108,7 +1149,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1108
1149
  byTenant: Object.fromEntries(t),
1109
1150
  visibility: n
1110
1151
  };
1111
- }, zt = (e, t) => {
1152
+ }, Ut = (e, t) => {
1112
1153
  if (t.search && ![
1113
1154
  e.id,
1114
1155
  e.key,
@@ -1125,10 +1166,10 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1125
1166
  if (!t.tags.every((e) => n.includes(e))) return !1;
1126
1167
  }
1127
1168
  return !0;
1128
- }, Bt = (e) => e ?? "global", Vt = () => {
1169
+ }, Wt = (e) => e ?? "global", Gt = () => {
1129
1170
  let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
1130
1171
  return {
1131
- statistics: () => y.sync(() => Rt((function* () {
1172
+ statistics: () => y.sync(() => Ht((function* () {
1132
1173
  for (let t of e.values()) yield {
1133
1174
  tenantId: t.tenantId,
1134
1175
  visibility: t.visibility,
@@ -1143,6 +1184,16 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1143
1184
  delete: (t) => y.sync(() => e.delete(t)),
1144
1185
  listRecent: (t) => y.sync(() => [...e.values()].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(0, t)),
1145
1186
  countByKey: (t, n) => y.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n).length),
1187
+ countPublicByKey: (t, n) => y.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n && e.visibility === "public").length),
1188
+ setVisibility: (t, n) => y.sync(() => {
1189
+ let r = e.get(t);
1190
+ if (r === void 0) return null;
1191
+ let i = {
1192
+ ...r,
1193
+ visibility: n
1194
+ };
1195
+ return e.set(t, i), i;
1196
+ }),
1146
1197
  usageByTenant: (t) => y.sync(() => {
1147
1198
  let n = 0, r = 0;
1148
1199
  for (let i of e.values()) (i.tenantId ?? null) === (t ?? null) && (n += i.size, r++);
@@ -1152,7 +1203,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1152
1203
  };
1153
1204
  }),
1154
1205
  consumeUsage: (e, n, r) => y.sync(() => {
1155
- let i = Bt(e), a = t.get(i) ?? {
1206
+ let i = Wt(e), a = t.get(i) ?? {
1156
1207
  bytes: 0,
1157
1208
  count: 0
1158
1209
  }, o = (r?.maxBytes === void 0 || a.bytes + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || a.count + n.count <= r.maxCount);
@@ -1166,16 +1217,16 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1166
1217
  };
1167
1218
  }),
1168
1219
  releaseUsage: (e, n) => y.sync(() => {
1169
- let r = Bt(e), i = t.get(r);
1220
+ let r = Wt(e), i = t.get(r);
1170
1221
  i && t.set(r, {
1171
1222
  bytes: Math.max(0, i.bytes - n.bytes),
1172
1223
  count: Math.max(0, i.count - n.count)
1173
1224
  });
1174
1225
  }),
1175
1226
  listByDerivedFrom: (t) => y.sync(() => [...e.values()].filter((e) => (e.derivedFrom ?? null) === t)),
1176
- listRefs: (t) => y.sync(() => [...e.values()].filter((e) => zt(e, t)).sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(t.offset, t.offset + t.limit))
1227
+ listRefs: (t) => y.sync(() => [...e.values()].filter((e) => Ut(e, t)).sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(t.offset, t.offset + t.limit))
1177
1228
  };
1178
- }, Ht = (e) => Array.isArray(e) && e.every((e) => typeof e == "string") ? e : null, Y = (e) => ({
1229
+ }, Kt = (e) => Array.isArray(e) && e.every((e) => typeof e == "string") ? e : null, Y = (e) => ({
1179
1230
  id: String(e.id),
1180
1231
  tenantId: e.tenantId ?? null,
1181
1232
  ownerId: e.ownerId ?? null,
@@ -1193,7 +1244,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1193
1244
  duration: e.duration ?? null,
1194
1245
  placeholder: e.placeholder ?? null,
1195
1246
  folder: e.folder ?? null,
1196
- tags: Ht(e.tags),
1247
+ tags: Kt(e.tags),
1197
1248
  alt: e.alt ?? null,
1198
1249
  caption: e.caption ?? null,
1199
1250
  derivedFrom: e.derivedFrom ?? null,
@@ -1205,7 +1256,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1205
1256
  message: String(e?.message ?? e),
1206
1257
  transient: !0
1207
1258
  })
1208
- }), Ut = async (e, t) => (await e.query({
1259
+ }), qt = async (e, t) => (await e.query({
1209
1260
  table: "_voltro_storage_usage",
1210
1261
  predicate: {
1211
1262
  column: "tenantId",
@@ -1216,8 +1267,8 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1216
1267
  take: 1,
1217
1268
  skip: void 0,
1218
1269
  projection: void 0
1219
- }))[0] ?? null, Wt = (e) => ({
1220
- statistics: () => X(async () => Rt((await e.query({
1270
+ }))[0] ?? null, Jt = (e) => ({
1271
+ statistics: () => X(async () => Ht((await e.query({
1221
1272
  table: V,
1222
1273
  predicate: void 0,
1223
1274
  order: [],
@@ -1283,6 +1334,34 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1283
1334
  skip: void 0,
1284
1335
  projection: void 0
1285
1336
  })).length),
1337
+ countPublicByKey: (t, n) => X(async () => (await e.query({
1338
+ table: V,
1339
+ predicate: { and: [
1340
+ {
1341
+ column: "bucket",
1342
+ op: "eq",
1343
+ value: t
1344
+ },
1345
+ {
1346
+ column: "key",
1347
+ op: "eq",
1348
+ value: n
1349
+ },
1350
+ {
1351
+ column: "visibility",
1352
+ op: "eq",
1353
+ value: "public"
1354
+ }
1355
+ ] },
1356
+ order: [],
1357
+ take: void 0,
1358
+ skip: void 0,
1359
+ projection: ["id"]
1360
+ })).length),
1361
+ setVisibility: (t, n) => X(async () => {
1362
+ let r = await e.update(V, t, { visibility: n });
1363
+ return r ? Y(r) : null;
1364
+ }),
1286
1365
  usageByTenant: (t) => X(async () => {
1287
1366
  let n = await e.query({
1288
1367
  table: V,
@@ -1303,10 +1382,10 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1303
1382
  };
1304
1383
  }),
1305
1384
  consumeUsage: (t, n, r) => X(async () => {
1306
- let i = Bt(t);
1385
+ let i = Wt(t);
1307
1386
  for (let t = 0; t < 32; t++) {
1308
1387
  t > 0 && await new Promise((e) => setTimeout(e, t));
1309
- let a = await Ut(e, i), o = a ? Number(a.bytes ?? 0) : 0, s = a ? Number(a.count ?? 0) : 0;
1388
+ let a = await qt(e, i), o = a ? Number(a.bytes ?? 0) : 0, s = a ? Number(a.count ?? 0) : 0;
1310
1389
  if (!((r?.maxBytes === void 0 || o + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || s + n.count <= r.maxCount))) return {
1311
1390
  allowed: !1,
1312
1391
  bytes: o,
@@ -1317,16 +1396,16 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1317
1396
  bytes: o + n.bytes,
1318
1397
  count: s + n.count,
1319
1398
  updatedAt: /* @__PURE__ */ new Date()
1320
- }, { where: T(D("id", String(a.id)), D("bytes", o), D("count", s)) }) === 1) return {
1399
+ }, { where: E(O("id", String(a.id)), O("bytes", o), O("count", s)) }) === 1) return {
1321
1400
  allowed: !0,
1322
1401
  bytes: o,
1323
1402
  count: s
1324
1403
  };
1325
1404
  } else {
1326
- let t = O({
1405
+ let t = k({
1327
1406
  kind: "typeid",
1328
1407
  prefix: "susage"
1329
- }, Ne), r = await e.insertIgnore(Ne, {
1408
+ }, Pe), r = await e.insertIgnore(Pe, {
1330
1409
  id: t,
1331
1410
  tenantId: i,
1332
1411
  bytes: n.bytes,
@@ -1343,17 +1422,17 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1343
1422
  throw Error(`storage usage consume: contention on tenant '${i}' exceeded 32 attempts`);
1344
1423
  }),
1345
1424
  releaseUsage: (t, n) => X(async () => {
1346
- let r = Bt(t);
1425
+ let r = Wt(t);
1347
1426
  for (let t = 0; t < 32; t++) {
1348
1427
  t > 0 && await new Promise((e) => setTimeout(e, t));
1349
- let i = await Ut(e, r);
1428
+ let i = await qt(e, r);
1350
1429
  if (!i) return;
1351
1430
  let a = Number(i.bytes ?? 0), o = Number(i.count ?? 0);
1352
1431
  if (await e.updateMany("_voltro_storage_usage", {
1353
1432
  bytes: Math.max(0, a - n.bytes),
1354
1433
  count: Math.max(0, o - n.count),
1355
1434
  updatedAt: /* @__PURE__ */ new Date()
1356
- }, { where: T(D("id", String(i.id)), D("bytes", a), D("count", o)) }) === 1) return;
1435
+ }, { where: E(O("id", String(i.id)), O("bytes", a), O("count", o)) }) === 1) return;
1357
1436
  }
1358
1437
  throw Error(`storage usage release: contention on tenant '${r}' exceeded 32 attempts`);
1359
1438
  }),
@@ -1374,14 +1453,14 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1374
1453
  })).map(Y)),
1375
1454
  listRefs: (t) => X(async () => {
1376
1455
  let n = [];
1377
- t.tenantId !== void 0 && n.push(D("tenantId", t.tenantId)), t.ownerId !== void 0 && n.push(D("ownerId", t.ownerId)), t.search && n.push(fe(...[
1456
+ t.tenantId !== void 0 && n.push(O("tenantId", t.tenantId)), t.ownerId !== void 0 && n.push(O("ownerId", t.ownerId)), t.search && n.push(N(...[
1378
1457
  "id",
1379
1458
  "key",
1380
1459
  "contentType",
1381
1460
  "ownerId",
1382
1461
  "tenantId"
1383
- ].map((e) => E(e, t.search))));
1384
- let r = t.folder === void 0 && t.tags.length === 0 && t.includeDerived, i = n.length ? T(...n) : void 0, a = await e.query({
1462
+ ].map((e) => D(e, t.search))));
1463
+ let r = t.folder === void 0 && t.tags.length === 0 && t.includeDerived, i = n.length ? E(...n) : void 0, a = await e.query({
1385
1464
  table: V,
1386
1465
  predicate: i,
1387
1466
  order: [{
@@ -1395,9 +1474,9 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1395
1474
  skip: r ? t.offset : void 0,
1396
1475
  projection: void 0
1397
1476
  });
1398
- return r ? a.map(Y) : a.map(Y).filter((e) => zt(e, t)).slice(t.offset, t.offset + t.limit);
1477
+ return r ? a.map(Y) : a.map(Y).filter((e) => Ut(e, t)).slice(t.offset, t.offset + t.limit);
1399
1478
  })
1400
- }), Gt = () => {
1479
+ }), Yt = () => {
1401
1480
  let e = /* @__PURE__ */ new Map();
1402
1481
  return {
1403
1482
  insert: (t) => y.sync(() => {
@@ -1412,7 +1491,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1412
1491
  for (let [n, r] of e) r.refId === t && e.delete(n);
1413
1492
  })
1414
1493
  };
1415
- }, Kt = (e) => ({
1494
+ }, Xt = (e) => ({
1416
1495
  id: String(e.id),
1417
1496
  refId: String(e.refId),
1418
1497
  principalType: e.principalType,
@@ -1421,7 +1500,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1421
1500
  createdAt: e.createdAt instanceof Date ? e.createdAt : new Date(String(e.createdAt)),
1422
1501
  expiresAt: e.expiresAt ? e.expiresAt instanceof Date ? e.expiresAt : new Date(String(e.expiresAt)) : null,
1423
1502
  createdBy: e.createdBy ?? null
1424
- }), qt = (e) => ({
1503
+ }), Zt = (e) => ({
1425
1504
  insert: (t) => X(() => e.insert(H, { ...t })),
1426
1505
  delete: (t) => X(() => e.delete(H, t)),
1427
1506
  getById: (t) => X(async () => {
@@ -1437,7 +1516,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1437
1516
  skip: void 0,
1438
1517
  projection: void 0
1439
1518
  }))[0];
1440
- return n ? Kt(n) : null;
1519
+ return n ? Xt(n) : null;
1441
1520
  }),
1442
1521
  listByRef: (t) => X(async () => (await e.query({
1443
1522
  table: H,
@@ -1453,7 +1532,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1453
1532
  take: void 0,
1454
1533
  skip: void 0,
1455
1534
  projection: void 0
1456
- })).map(Kt)),
1535
+ })).map(Xt)),
1457
1536
  deleteByRef: (t) => X(async () => {
1458
1537
  let n = await e.query({
1459
1538
  table: H,
@@ -1469,14 +1548,14 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1469
1548
  });
1470
1549
  for (let t of n) await e.delete(H, String(t.id));
1471
1550
  })
1472
- }), Jt = () => O({
1551
+ }), Qt = () => k({
1473
1552
  kind: "typeid",
1474
1553
  prefix: "file"
1475
- }, V), Yt = () => O({
1554
+ }, V), $t = () => k({
1476
1555
  kind: "typeid",
1477
1556
  prefix: "grant"
1478
- }, H), Xt = (i) => {
1479
- let { provider: a, refStore: o, grantStore: s, bucket: c } = i, l = i.access ?? {}, u = i.attempts ?? 3, d = i.urlExpiresInSec ?? 3600, f = (e) => Lt(i.publicBaseUrl, e, i.httpPath ?? "/_voltro/storage"), p = S.recurs(Math.max(0, u - 1)).pipe(S.intersect(S.exponential("100 millis")), S.whileInput((e) => e.transient)), m = (e, t, n) => [
1557
+ }, H), en = (i) => {
1558
+ let { provider: a, refStore: o, grantStore: s, bucket: c } = i, l = i.access ?? {}, u = i.attempts ?? 3, d = i.urlExpiresInSec ?? 3600, f = (e) => Vt(i.publicBaseUrl, e, i.httpPath ?? "/_voltro/storage"), p = S.recurs(Math.max(0, u - 1)).pipe(S.intersect(S.exponential("100 millis")), S.whileInput((e) => e.transient)), m = (e, t, n) => [
1480
1559
  i.tenantPrefix,
1481
1560
  e ?? "global",
1482
1561
  n ?? t
@@ -1516,7 +1595,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1516
1595
  transient: !1
1517
1596
  })
1518
1597
  });
1519
- return c === void 0 ? r === void 0 ? !1 : yield* y.fail(s(`claim '${r}' cannot be released: ref '${e}' was not written through an operation and holds no claims`)) : (yield* h(c.ref, n), yield* Ft({
1598
+ return c === void 0 ? r === void 0 ? !1 : yield* y.fail(s(`claim '${r}' cannot be released: ref '${e}' was not written through an operation and holds no claims`)) : (yield* h(c.ref, n), yield* zt({
1520
1599
  metadata: o,
1521
1600
  provider: {
1522
1601
  ...a,
@@ -1556,7 +1635,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1556
1635
  catch: () => null
1557
1636
  }).pipe(y.catchAll(() => y.succeed(null)));
1558
1637
  }), _ = (e) => y.gen(function* () {
1559
- let t = kt(e.bytes, e.contentType, i.limits);
1638
+ let t = Mt(e.bytes, e.contentType, i.limits);
1560
1639
  if (t) return yield* y.fail(new n(t));
1561
1640
  if (e.claim !== void 0 && e.operationId === void 0) return yield* y.fail(new n({
1562
1641
  reason: "claim-without-operation",
@@ -1570,11 +1649,11 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1570
1649
  });
1571
1650
  if (!t.clean) return yield* y.fail(new r({ threat: t.threat ?? "unknown" }));
1572
1651
  }
1573
- let s = yield* y.promise(() => At(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* ie({
1652
+ let s = yield* y.promise(() => Nt(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* ie({
1574
1653
  bytes: l,
1575
1654
  contentType: e.contentType
1576
- }), d = s.width ?? u?.width, f = s.height ?? u?.height, te = s.placeholder ?? u?.poster, h = e.duration ?? u?.duration, ne = yield* y.promise(() => It(l)), g = e.tenantId ?? null, _ = e.visibility ?? "private", v = m(g, ne, yield* ee(e.key)), S = e.password ? yield* y.sync(() => rt(e.password)) : null, C = {
1577
- id: Jt(),
1655
+ }), d = s.width ?? u?.width, f = s.height ?? u?.height, te = s.placeholder ?? u?.poster, h = e.duration ?? u?.duration, ne = yield* y.promise(() => Bt(l)), g = e.tenantId ?? null, _ = e.visibility ?? "private", v = m(g, ne, yield* ee(e.key)), S = e.password ? yield* y.sync(() => ot(e.password)) : null, C = {
1656
+ id: Qt(),
1578
1657
  tenantId: g,
1579
1658
  ownerId: e.ownerId ?? null,
1580
1659
  bucket: c,
@@ -1596,7 +1675,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1596
1675
  ...e.caption === void 0 ? {} : { caption: e.caption },
1597
1676
  ...e.derivedFrom === void 0 ? {} : { derivedFrom: e.derivedFrom },
1598
1677
  ...e.kind === void 0 ? {} : { kind: e.kind }
1599
- }, w = i.transcode !== void 0 && i.autoTranscode !== !1, ae = (t) => w && t.derivedFrom == null && (e.contentType.startsWith("video/") || e.contentType.startsWith("audio/")) ? y.forkDaemon(x(t).pipe(y.ignore)) : y.void;
1678
+ }, w = i.transcode !== void 0 && i.autoTranscode !== !1, T = (t) => w && t.derivedFrom == null && (e.contentType.startsWith("video/") || e.contentType.startsWith("audio/")) ? y.forkDaemon(x(t).pipe(y.ignore)) : y.void;
1600
1679
  if (e.operationId !== void 0) {
1601
1680
  let t = i.objects?.();
1602
1681
  if (t === void 0) return yield* y.fail(new n({
@@ -1609,7 +1688,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1609
1688
  operationId: e.operationId,
1610
1689
  checksum: ne,
1611
1690
  logicalKey: v,
1612
- fingerprint: yield* y.promise(() => It(new TextEncoder().encode(JSON.stringify([
1691
+ fingerprint: yield* y.promise(() => Bt(new TextEncoder().encode(JSON.stringify([
1613
1692
  ne,
1614
1693
  e.contentType,
1615
1694
  _,
@@ -1625,7 +1704,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1625
1704
  h ?? null,
1626
1705
  e.password !== void 0
1627
1706
  ]))))
1628
- }, o = yield* Ft({
1707
+ }, o = yield* zt({
1629
1708
  metadata: t,
1630
1709
  provider: {
1631
1710
  ...a,
@@ -1638,26 +1717,26 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1638
1717
  ...i.quota === void 0 ? {} : { quota: i.quota },
1639
1718
  ...e.claim === void 0 ? {} : { claim: e.claim }
1640
1719
  });
1641
- return yield* ae(o.ref), {
1720
+ return yield* T(o.ref), {
1642
1721
  ...o.ref,
1643
1722
  outcome: o.outcome
1644
1723
  };
1645
1724
  }
1646
- let oe = {
1725
+ let ae = {
1647
1726
  bytes: l.byteLength,
1648
1727
  count: 1
1649
- }, se = yield* o.consumeUsage(g, oe, i.quota);
1650
- if (!se.allowed) {
1651
- let e = i.quota ?? {}, t = e.maxCount !== void 0 && se.count + 1 > e.maxCount ? `tenant object count ${se.count} + 1 exceeds max ${e.maxCount}` : `tenant usage ${se.bytes} + ${l.byteLength} bytes exceeds max ${e.maxBytes}`;
1728
+ }, oe = yield* o.consumeUsage(g, ae, i.quota);
1729
+ if (!oe.allowed) {
1730
+ let e = i.quota ?? {}, t = e.maxCount !== void 0 && oe.count + 1 > e.maxCount ? `tenant object count ${oe.count} + 1 exceeds max ${e.maxCount}` : `tenant usage ${oe.bytes} + ${l.byteLength} bytes exceeds max ${e.maxBytes}`;
1652
1731
  return yield* y.fail(new n({
1653
1732
  reason: "quota-exceeded",
1654
1733
  detail: t
1655
1734
  }));
1656
1735
  }
1657
- return yield* ((e) => e.pipe(y.onExit((e) => b.isSuccess(e) ? y.void : o.delete(C.id).pipe(y.zipRight(o.releaseUsage(g, oe)), y.ignore))))(o.insert(C).pipe(y.zipRight(a.put(v, l, {
1736
+ return yield* ((e) => e.pipe(y.onExit((e) => b.isSuccess(e) ? y.void : o.delete(C.id).pipe(y.zipRight(o.releaseUsage(g, ae)), y.ignore))))(o.insert(C).pipe(y.zipRight(a.put(v, l, {
1658
1737
  contentType: e.contentType,
1659
1738
  public: _ === "public"
1660
- }).pipe(y.retry(p))))), yield* ae(C), {
1739
+ }).pipe(y.retry(p))))), yield* T(C), {
1661
1740
  ...C,
1662
1741
  outcome: "created"
1663
1742
  };
@@ -1695,13 +1774,13 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1695
1774
  }
1696
1775
  return r;
1697
1776
  }), C = (e, t, n) => y.gen(function* () {
1698
- if (e.visibility === "public" || (yield* dt(e, t, {
1777
+ if (e.visibility === "public" || (yield* mt(e, t, {
1699
1778
  ...l,
1700
1779
  ...n?.password === void 0 ? {} : { password: n.password }
1701
1780
  }))) return !0;
1702
- let r = yield* ht(t, l);
1703
- return mt(yield* s.listByRef(e.id), t, r, n?.permission ?? "read", Date.now());
1704
- }), ae = (e) => {
1781
+ let r = yield* vt(t, l);
1782
+ return _t(yield* s.listByRef(e.id), t, r, n?.permission ?? "read", Date.now());
1783
+ }), T = (e) => {
1705
1784
  if (e.visibility === "public") {
1706
1785
  let t = a.publicUrl?.(e.key);
1707
1786
  if (t != null) return t;
@@ -1738,12 +1817,46 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1738
1817
  totalSize: r
1739
1818
  })));
1740
1819
  })),
1741
- getUrl: (e, t) => g(e, t?.tenantId).pipe(y.flatMap((e) => e.visibility === "public" ? y.succeed(ae(e)) : a.presigns ? a.getUrl(e.key, t?.expiresInSec ?? d) : y.succeed(f(e.id)))),
1820
+ getUrl: (e, t) => g(e, t?.tenantId).pipe(y.flatMap((e) => e.visibility === "public" ? y.succeed(T(e)) : a.presigns ? a.getUrl(e.key, t?.expiresInSec ?? d) : y.succeed(f(e.id)))),
1742
1821
  head: (e, t) => o.getById(e).pipe(y.flatMap((e) => e ? h(e, t?.tenantId).pipe(y.map((e) => e)) : y.succeed(null))),
1743
1822
  delete: (e, t) => ne(e, t?.tenantId, t?.claim).pipe(y.flatMap((n) => n ? y.void : g(e, t?.tenantId).pipe(y.flatMap((t) => s.deleteByRef(e).pipe(y.flatMap(() => o.delete(e)), y.flatMap((e) => e ? o.countByKey(t.bucket, t.key).pipe(y.flatMap((e) => e === 0 ? a.delete(t.key).pipe(y.retry(p)) : y.void), y.flatMap(() => o.releaseUsage(t.tenantId, {
1744
1823
  bytes: t.size,
1745
1824
  count: 1
1746
1825
  }))) : y.void), y.asVoid))))),
1826
+ signedUrl: (e, t) => g(e, t?.tenantId).pipe(y.flatMap((e) => {
1827
+ if (e.visibility === "public") return y.succeed(T(e));
1828
+ let n = t?.expiresInSec ?? d;
1829
+ return a.presigns ? a.getUrl(e.key, n) : y.sync(() => `${f(e.id)}?t=${yt(e.id, n, void 0, i.httpPath ?? "/_voltro/storage")}`);
1830
+ })),
1831
+ setVisibility: (e, r, i) => y.gen(function* () {
1832
+ let s = yield* g(e, i?.tenantId);
1833
+ if (s.visibility === r) return s;
1834
+ let c = o.setVisibility;
1835
+ if (c === void 0) return yield* y.fail(new n({
1836
+ reason: "visibility-unsupported",
1837
+ detail: "the ref store cannot change a stored object's visibility"
1838
+ }));
1839
+ if (r === "private" && a.publicUrl?.(s.key) != null) return yield* y.fail(new n({
1840
+ reason: "visibility-unsupported",
1841
+ detail: `objects are served from a public base (${a.name} cdnBaseUrl); a public object cannot be made private there`
1842
+ }));
1843
+ if (r === "private" && a.setObjectPublic !== void 0 && o.countPublicByKey === void 0) return yield* y.fail(new n({
1844
+ reason: "visibility-unsupported",
1845
+ detail: "the ref store cannot tell whether other refs keep these bytes public"
1846
+ }));
1847
+ let l = yield* c(s.id, r);
1848
+ if (l === null) return yield* y.fail(new t({
1849
+ provider: a.name,
1850
+ message: `no ref '${e}'`,
1851
+ transient: !1,
1852
+ status: 404
1853
+ }));
1854
+ if (a.setObjectPublic !== void 0) {
1855
+ let e = o.countPublicByKey, t = r === "public" || e !== void 0 && (yield* e(s.bucket, s.key)) > 0;
1856
+ yield* a.setObjectPublic(s.key, t);
1857
+ }
1858
+ return l;
1859
+ }),
1747
1860
  mintUrl: (n, r, s) => y.gen(function* () {
1748
1861
  let c = yield* o.getById(n).pipe(y.flatMap((e) => e ? y.succeed(e) : y.fail(new t({
1749
1862
  provider: a.name,
@@ -1751,14 +1864,14 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1751
1864
  transient: !1,
1752
1865
  status: 404
1753
1866
  }))));
1754
- if (c.visibility === "public") return ae(c);
1867
+ if (c.visibility === "public") return T(c);
1755
1868
  if (!(yield* C(c, r, s?.password === void 0 ? {} : { password: s.password }))) return yield* y.fail(new e({
1756
1869
  refId: n,
1757
1870
  reason: "access denied"
1758
1871
  }));
1759
1872
  let l = s?.expiresInSec ?? d;
1760
1873
  if (a.presigns) return yield* a.getUrl(c.key, l);
1761
- let u = yield* y.sync(() => gt(c.id, l, void 0, i.httpPath ?? "/_voltro/storage"));
1874
+ let u = yield* y.sync(() => yt(c.id, l, void 0, i.httpPath ?? "/_voltro/storage"));
1762
1875
  return `${f(c.id)}?t=${u}`;
1763
1876
  }),
1764
1877
  mintUploadUrl: (e) => y.gen(function* () {
@@ -1774,7 +1887,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1774
1887
  checkAccess: C,
1775
1888
  grant: (e) => y.gen(function* () {
1776
1889
  let t = {
1777
- id: Yt(),
1890
+ id: $t(),
1778
1891
  refId: e.refId,
1779
1892
  principalType: e.principalType,
1780
1893
  principalId: e.principalId,
@@ -1824,8 +1937,8 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1824
1937
  removed: i
1825
1938
  };
1826
1939
  }),
1827
- ingestUrl: (e, t) => Pt(y.gen(function* () {
1828
- let n = yield* Nt(e, i.limits?.maxBytes);
1940
+ ingestUrl: (e, t) => Rt(y.gen(function* () {
1941
+ let n = yield* Lt(e, i.limits?.maxBytes, i.ingest);
1829
1942
  return yield* _({
1830
1943
  bytes: n.bytes,
1831
1944
  contentType: t?.contentType ?? n.contentType,
@@ -1833,6 +1946,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1833
1946
  ...t?.operationId === void 0 ? {} : { operationId: t.operationId },
1834
1947
  ...t?.ownerId === void 0 ? {} : { ownerId: t.ownerId },
1835
1948
  ...t?.visibility === void 0 ? {} : { visibility: t.visibility },
1949
+ ...t?.access === void 0 ? {} : { access: t.access },
1836
1950
  ...t?.key === void 0 ? {} : { key: t.key },
1837
1951
  ...t?.folder === void 0 ? {} : { folder: t.folder },
1838
1952
  ...t?.tags === void 0 ? {} : { tags: t.tags },
@@ -1847,7 +1961,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1847
1961
  transient: !1,
1848
1962
  status: 400
1849
1963
  }));
1850
- let n = e.expiresInSec ?? d, r = `_incoming/${O({
1964
+ let n = e.expiresInSec ?? d, r = `_incoming/${k({
1851
1965
  kind: "typeid",
1852
1966
  prefix: "up"
1853
1967
  }, V)}`, i = m(e.tenantId ?? null, "", r);
@@ -1914,7 +2028,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1914
2028
  }
1915
2029
  let i = /* @__PURE__ */ new Uint8Array(), s = 0;
1916
2030
  for (let t = 0; t < e.count; t++) {
1917
- let e = yield* je(a, o(t)).pipe(y.retry(p));
2031
+ let e = yield* Me(a, o(t)).pipe(y.retry(p));
1918
2032
  yield* w.runForEach(e.stream, (e) => y.gen(function* () {
1919
2033
  if (e.byteLength > r - s) return yield* y.fail(c());
1920
2034
  let t = s + e.byteLength;
@@ -1948,7 +2062,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1948
2062
  transient: !1,
1949
2063
  status: 400
1950
2064
  }));
1951
- let n = m(e.tenantId ?? null, "", `multipart/${O({
2065
+ let n = m(e.tenantId ?? null, "", `multipart/${k({
1952
2066
  kind: "typeid",
1953
2067
  prefix: "mp"
1954
2068
  }, V)}`);
@@ -1979,7 +2093,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
1979
2093
  detail: `multipart upload of ${l} bytes exceeds tenant quota`
1980
2094
  }));
1981
2095
  let m = {
1982
- id: Jt(),
2096
+ id: Qt(),
1983
2097
  tenantId: e.tenantId ?? null,
1984
2098
  ownerId: e.ownerId ?? null,
1985
2099
  bucket: c,
@@ -2000,33 +2114,33 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2000
2114
  }),
2001
2115
  abortMultipart: (e) => y.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(y.retry(p)) : y.void)
2002
2116
  };
2003
- }, Zt = (e) => x.succeed(i, Xt(e)), Qt = "_voltro_storage_operation_locks", Z = "_voltro_storage_object_heads", Q = "_voltro_storage_operations", $t = "_voltro_storage_object_claims", en = [
2004
- N(Qt, {
2005
- id: P().maxLength(64),
2006
- nonce: P()
2117
+ }, tn = (e) => x.succeed(i, en(e)), nn = "_voltro_storage_operation_locks", Z = "_voltro_storage_object_heads", rn = "_voltro_storage_operations", an = "_voltro_storage_object_claims", on = [
2118
+ P(nn, {
2119
+ id: F().maxLength(64),
2120
+ nonce: F()
2007
2121
  }).primaryKey(["id"]).nonReactive(),
2008
- N(Z, {
2009
- id: P().maxLength(64),
2010
- generation: P(),
2011
- key: P(),
2012
- reservations: k()
2122
+ P(Z, {
2123
+ id: F().maxLength(64),
2124
+ generation: F(),
2125
+ key: F(),
2126
+ reservations: A()
2013
2127
  }).primaryKey(["id"]).nonReactive(),
2014
- N(Q, {
2015
- id: P().maxLength(64),
2016
- objectId: P().maxLength(64),
2017
- fingerprint: P().maxLength(64),
2018
- generation: P(),
2019
- key: P(),
2020
- refId: P(),
2021
- state: P(),
2022
- deleteKey: P().nullable()
2128
+ P(rn, {
2129
+ id: F().maxLength(64),
2130
+ objectId: F().maxLength(64),
2131
+ fingerprint: F().maxLength(64),
2132
+ generation: F(),
2133
+ key: F(),
2134
+ refId: F(),
2135
+ state: F(),
2136
+ deleteKey: F().nullable()
2023
2137
  }).primaryKey(["id"]).nonReactive(),
2024
- N($t, {
2025
- id: P().maxLength(64),
2026
- operationId: P().maxLength(64),
2027
- claim: P()
2138
+ P(an, {
2139
+ id: F().maxLength(64),
2140
+ operationId: F().maxLength(64),
2141
+ claim: F()
2028
2142
  }).primaryKey(["id"]).nonReactive()
2029
- ], tn = C.Struct({
2143
+ ], sn = C.Struct({
2030
2144
  id: C.String,
2031
2145
  objectId: C.String,
2032
2146
  fingerprint: C.String,
@@ -2035,71 +2149,71 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2035
2149
  refId: C.String,
2036
2150
  state: C.Literal("reserved", "ready", "deleting", "deleted"),
2037
2151
  deleteKey: C.NullOr(C.String)
2038
- }), nn = C.Struct({
2152
+ }), cn = C.Struct({
2039
2153
  id: C.String,
2040
2154
  generation: C.String,
2041
2155
  key: C.String,
2042
2156
  reservations: C.Int.pipe(C.nonNegative())
2043
- }), rn = (e) => he("sha256").update(JSON.stringify(e)).digest("hex"), an = (e, t) => rn([e, t]), on = (e) => {
2157
+ }), ln = (e) => he("sha256").update(JSON.stringify(e)).digest("hex"), un = (e, t) => ln([e, t]), dn = (e) => {
2044
2158
  if (!e.bucket || !e.operationId || !e.logicalKey || !/^[a-f0-9]{64}$/.test(e.fingerprint) || !/^[a-f0-9]{64}$/.test(e.checksum)) throw Error("Storage operation requires a bucket, operation identity, key and SHA-256 fingerprint");
2045
2159
  return {
2046
- id: rn([
2160
+ id: ln([
2047
2161
  e.bucket,
2048
2162
  e.tenantId,
2049
2163
  e.operationId
2050
2164
  ]),
2051
- objectId: rn([
2165
+ objectId: ln([
2052
2166
  e.bucket,
2053
2167
  e.tenantId,
2054
2168
  e.logicalKey,
2055
2169
  e.checksum
2056
2170
  ]),
2057
- lockId: rn([e.tenantId])
2171
+ lockId: ln([e.tenantId])
2058
2172
  };
2059
- }, sn = async (e, t, n) => {
2060
- let { lockId: r } = on(t);
2061
- return await e.insertIgnoreWithOutcome(Qt, {
2173
+ }, fn = async (e, t, n) => {
2174
+ let { lockId: r } = dn(t);
2175
+ return await e.insertIgnoreWithOutcome(nn, {
2062
2176
  id: r,
2063
- nonce: ge()
2177
+ nonce: _e()
2064
2178
  }, { conflictColumns: ["id"] }), e.transactional(async (e) => {
2065
2179
  if ((await e.query({
2066
- table: Qt,
2067
- predicate: D("id", r),
2180
+ table: nn,
2181
+ predicate: O("id", r),
2068
2182
  lock: "update",
2069
2183
  order: [],
2070
2184
  take: 1,
2071
2185
  skip: void 0,
2072
2186
  projection: void 0
2073
- })).length !== 1 || await e.update(Qt, r, { nonce: ge() }) === null) throw Error("Storage operation lock is unavailable");
2187
+ })).length !== 1 || await e.update(nn, r, { nonce: _e() }) === null) throw Error("Storage operation lock is unavailable");
2074
2188
  return n(e);
2075
2189
  });
2076
- }, $ = async (e, t) => {
2077
- let r = on(t), i = await e.query({
2078
- table: Q,
2079
- predicate: D("id", r.id),
2190
+ }, Q = async (e, t) => {
2191
+ let r = dn(t), i = await e.query({
2192
+ table: rn,
2193
+ predicate: O("id", r.id),
2080
2194
  order: [],
2081
2195
  take: 1,
2082
2196
  skip: void 0,
2083
2197
  projection: void 0
2084
2198
  });
2085
2199
  if (!i[0]) return;
2086
- let a = C.decodeUnknownSync(tn)(i[0]);
2200
+ let a = C.decodeUnknownSync(sn)(i[0]);
2087
2201
  if (a.fingerprint !== t.fingerprint || a.objectId !== r.objectId) throw new n({
2088
2202
  reason: "operation-identity-reused",
2089
2203
  detail: `storage operation '${t.operationId}' was already used with different inputs`
2090
2204
  });
2091
2205
  return a;
2092
- }, cn = async (e, t) => {
2093
- let n = await $(e, t);
2206
+ }, pn = async (e, t) => {
2207
+ let n = await Q(e, t);
2094
2208
  if (n) return n;
2095
- let { id: r, objectId: i } = on(t), a = await e.query({
2209
+ let { id: r, objectId: i } = dn(t), a = await e.query({
2096
2210
  table: Z,
2097
- predicate: D("id", i),
2211
+ predicate: O("id", i),
2098
2212
  order: [],
2099
2213
  take: 1,
2100
2214
  skip: void 0,
2101
2215
  projection: void 0
2102
- }), o = a[0] ? C.decodeUnknownSync(nn)(a[0]) : void 0, s = o?.generation ?? ge(), c = o?.key ?? `${t.logicalKey}/g-${s}`;
2216
+ }), o = a[0] ? C.decodeUnknownSync(cn)(a[0]) : void 0, s = o?.generation ?? _e(), c = o?.key ?? `${t.logicalKey}/g-${s}`;
2103
2217
  o ? await e.update(Z, i, { reservations: o.reservations + 1 }) : await e.insert(Z, {
2104
2218
  id: i,
2105
2219
  generation: s,
@@ -2112,35 +2226,35 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2112
2226
  fingerprint: t.fingerprint,
2113
2227
  generation: s,
2114
2228
  key: c,
2115
- refId: `file_${ge()}`,
2229
+ refId: `file_${_e()}`,
2116
2230
  state: "reserved",
2117
2231
  deleteKey: null
2118
2232
  };
2119
- return await e.insert(Q, l), l;
2120
- }, ln = async (e, t) => {
2121
- let n = await $(e, t);
2233
+ return await e.insert(rn, l), l;
2234
+ }, mn = async (e, t) => {
2235
+ let n = await Q(e, t);
2122
2236
  if (!n) throw Error("Storage operation is missing");
2123
2237
  if (n.state === "deleting" || n.state === "deleted") throw Error("Deleted storage operation cannot be confirmed by a late put");
2124
- return await e.update(Q, n.id, { state: "ready" }), {
2238
+ return await e.update(rn, n.id, { state: "ready" }), {
2125
2239
  ...n,
2126
2240
  state: "ready"
2127
2241
  };
2128
- }, un = async (e, t) => {
2129
- let n = await $(e, t);
2242
+ }, hn = async (e, t) => {
2243
+ let n = await Q(e, t);
2130
2244
  if (!n) throw Error("Storage operation is missing");
2131
2245
  if (n.state === "deleting" || n.state === "deleted") return n;
2132
2246
  if (n.state !== "ready") throw Error("An unconfirmed put cannot be deleted");
2133
2247
  let r = await e.query({
2134
2248
  table: Z,
2135
- predicate: D("id", n.objectId),
2249
+ predicate: O("id", n.objectId),
2136
2250
  order: [],
2137
2251
  take: 1,
2138
2252
  skip: void 0,
2139
2253
  projection: void 0
2140
- }), i = r[0] ? C.decodeUnknownSync(nn)(r[0]) : void 0;
2254
+ }), i = r[0] ? C.decodeUnknownSync(cn)(r[0]) : void 0;
2141
2255
  if (!i || i.generation !== n.generation || i.reservations < 1) throw Error("Storage object generation does not own its reservation");
2142
2256
  let a = i.reservations === 1 ? i.key : null;
2143
- return a === null ? await e.update(Z, i.id, { reservations: i.reservations - 1 }) : await e.delete(Z, i.id), await e.update(Q, n.id, {
2257
+ return a === null ? await e.update(Z, i.id, { reservations: i.reservations - 1 }) : await e.delete(Z, i.id), await e.update(rn, n.id, {
2144
2258
  state: "deleting",
2145
2259
  deleteKey: a
2146
2260
  }), {
@@ -2148,46 +2262,46 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2148
2262
  state: "deleting",
2149
2263
  deleteKey: a
2150
2264
  };
2151
- }, dn = async (e, t) => {
2152
- let n = await $(e, t);
2265
+ }, gn = async (e, t) => {
2266
+ let n = await Q(e, t);
2153
2267
  if (!n || n.state !== "deleting" && n.state !== "deleted") throw Error("Storage deletion has not been accepted");
2154
- return n.state !== "deleted" && (await e.update(Q, n.id, { state: "deleted" }), !0);
2155
- }, fn = async (e, t, n) => {
2268
+ return n.state !== "deleted" && (await e.update(rn, n.id, { state: "deleted" }), !0);
2269
+ }, _n = async (e, t, n) => {
2156
2270
  if (!n) throw Error("Storage object claim must be a non-empty string");
2157
- await e.insertIgnoreWithOutcome($t, {
2158
- id: an(t, n),
2271
+ await e.insertIgnoreWithOutcome(an, {
2272
+ id: un(t, n),
2159
2273
  operationId: t,
2160
2274
  claim: n
2161
2275
  }, { conflictColumns: ["id"] });
2162
- }, pn = async (e, t, n) => {
2163
- let r = an(t, n);
2276
+ }, vn = async (e, t, n) => {
2277
+ let r = un(t, n);
2164
2278
  return {
2165
- held: await e.delete($t, r),
2279
+ held: await e.delete(an, r),
2166
2280
  others: (await e.query({
2167
- table: $t,
2168
- predicate: T(D("operationId", t), M("claim", n)),
2281
+ table: an,
2282
+ predicate: E(O("operationId", t), M("claim", n)),
2169
2283
  order: [],
2170
2284
  take: 1,
2171
2285
  skip: void 0,
2172
2286
  projection: void 0
2173
2287
  })).length > 0
2174
2288
  };
2175
- }, mn = (e, t) => e.deleteMany($t, { where: D("operationId", t) }), hn = "_voltro_storage_put_intents", gn = N(hn, {
2176
- id: P().maxLength(64),
2177
- refId: P().maxLength(64),
2178
- identity: A(),
2179
- ref: A()
2180
- }).primaryKey(["id"]).unique("storagePutRef", ["refId"]).nonReactive(), _n = C.Struct({
2289
+ }, yn = (e, t) => e.deleteMany(an, { where: O("operationId", t) }), bn = "_voltro_storage_put_intents", xn = P(bn, {
2290
+ id: F().maxLength(64),
2291
+ refId: F().maxLength(64),
2292
+ identity: j(),
2293
+ ref: j()
2294
+ }).primaryKey(["id"]).unique("storagePutRef", ["refId"]).nonReactive(), Sn = C.Struct({
2181
2295
  tenantId: C.NullOr(C.String),
2182
2296
  bucket: C.String,
2183
2297
  operationId: C.String,
2184
2298
  fingerprint: C.String,
2185
2299
  checksum: C.String,
2186
2300
  logicalKey: C.String
2187
- }), vn = async (e, t) => {
2301
+ }), Cn = async (e, t) => {
2188
2302
  let n = await e.query({
2189
- table: hn,
2190
- predicate: D("refId", t),
2303
+ table: bn,
2304
+ predicate: O("refId", t),
2191
2305
  order: [],
2192
2306
  take: 2,
2193
2307
  skip: void 0,
@@ -2195,7 +2309,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2195
2309
  });
2196
2310
  if (n.length === 0) return;
2197
2311
  if (n.length !== 1) throw Error("Storage reference has ambiguous operation ownership");
2198
- let r = n[0], i = C.decodeUnknownSync(_n)(r.identity);
2312
+ let r = n[0], i = C.decodeUnknownSync(Sn)(r.identity);
2199
2313
  if (typeof r.ref != "object" || r.ref === null || Array.isArray(r.ref)) throw Error("Storage operation reference is unreadable");
2200
2314
  let a = Y(r.ref);
2201
2315
  if (a.id !== t || a.bucket !== i.bucket || a.tenantId !== i.tenantId || a.checksum !== i.checksum || !Number.isSafeInteger(a.size) || a.size < 0 || !Number.isFinite(a.createdAt.getTime())) throw Error("Storage operation reference does not match its identity");
@@ -2203,23 +2317,23 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2203
2317
  identity: i,
2204
2318
  ref: a
2205
2319
  };
2206
- }, yn = (e) => ({
2207
- intent: (t) => vn(e, t),
2208
- reserve: (t, r, i, a) => sn(e, t, async (e) => {
2320
+ }, wn = (e) => ({
2321
+ intent: (t) => Cn(e, t),
2322
+ reserve: (t, r, i, a) => fn(e, t, async (e) => {
2209
2323
  if (r.tenantId !== t.tenantId || r.bucket !== t.bucket || r.checksum !== t.checksum || !Number.isSafeInteger(r.size) || r.size < 0) throw Error("Storage put metadata does not match its identity");
2210
- let o = await $(e, t);
2324
+ let o = await Q(e, t);
2211
2325
  if (o) {
2212
2326
  if (o.state === "deleting" || o.state === "deleted") throw Error("Storage put identity has already been deleted");
2213
- let t = await vn(e, o.refId);
2327
+ let t = await Cn(e, o.refId);
2214
2328
  if (!t) throw Error("Storage operation lost its put intent");
2215
2329
  let n = o.state === "ready";
2216
- return n && a !== void 0 && await fn(e, o.id, a), {
2330
+ return n && a !== void 0 && await _n(e, o.id, a), {
2217
2331
  ref: t.ref,
2218
2332
  ready: n,
2219
2333
  outcome: n ? "joined" : "resumed"
2220
2334
  };
2221
2335
  }
2222
- let s = await cn(e, t), c = Wt(e);
2336
+ let s = await pn(e, t), c = Jt(e);
2223
2337
  if (!(await y.runPromise(c.consumeUsage(t.tenantId, {
2224
2338
  bytes: r.size,
2225
2339
  count: 1
@@ -2232,7 +2346,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2232
2346
  id: s.refId,
2233
2347
  key: s.key
2234
2348
  });
2235
- return await e.insert(hn, {
2349
+ return await e.insert(bn, {
2236
2350
  id: s.id,
2237
2351
  refId: l.id,
2238
2352
  identity: t,
@@ -2243,31 +2357,31 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2243
2357
  outcome: "created"
2244
2358
  };
2245
2359
  }),
2246
- confirm: (t, n) => sn(e, t, async (e) => {
2247
- let r = await $(e, t);
2360
+ confirm: (t, n) => fn(e, t, async (e) => {
2361
+ let r = await Q(e, t);
2248
2362
  if (!r) throw Error("Storage put operation is missing");
2249
- let i = await vn(e, r.refId);
2363
+ let i = await Cn(e, r.refId);
2250
2364
  if (!i) throw Error("Storage put intent is missing");
2251
- if (n !== void 0 && await fn(e, r.id, n), r.state === "ready") {
2252
- let n = await y.runPromise(Wt(e).getById(r.refId));
2365
+ if (n !== void 0 && await _n(e, r.id, n), r.state === "ready") {
2366
+ let n = await y.runPromise(Jt(e).getById(r.refId));
2253
2367
  if (!n || n.key !== r.key || n.checksum !== t.checksum) throw Error("Confirmed storage operation lost its reference");
2254
2368
  return n;
2255
2369
  }
2256
- return await ln(e, t), await y.runPromise(Wt(e).insert(i.ref)), i.ref;
2370
+ return await mn(e, t), await y.runPromise(Jt(e).insert(i.ref)), i.ref;
2257
2371
  }),
2258
2372
  beginDelete: async (t, r, i) => {
2259
- let a = await vn(e, t);
2373
+ let a = await Cn(e, t);
2260
2374
  if (!a) throw Error("Storage delete operation is missing");
2261
2375
  if (r !== void 0 && a.identity.tenantId !== r) throw Error("Storage delete tenant mismatch");
2262
- return sn(e, a.identity, async (e) => {
2263
- let r = await vn(e, t);
2376
+ return fn(e, a.identity, async (e) => {
2377
+ let r = await Cn(e, t);
2264
2378
  if (!r) throw Error("Storage delete intent disappeared");
2265
- let a = await $(e, r.identity);
2379
+ let a = await Q(e, r.identity);
2266
2380
  if (!a) throw Error("Storage delete lost its operation");
2267
2381
  let o = a.state !== "deleting" && a.state !== "deleted";
2268
- if (i === void 0) o && await mn(e, a.id);
2382
+ if (i === void 0) o && await yn(e, a.id);
2269
2383
  else if (o) {
2270
- let o = await pn(e, a.id, i);
2384
+ let o = await vn(e, a.id, i);
2271
2385
  if (o.others) return {
2272
2386
  released: !0,
2273
2387
  identity: r.identity
@@ -2277,10 +2391,10 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2277
2391
  detail: `claim '${i}' is not held on storage reference '${t}'; a reference put without a claim is deleted as a whole by a delete that names none`
2278
2392
  });
2279
2393
  }
2280
- let s = await un(e, r.identity);
2394
+ let s = await hn(e, r.identity);
2281
2395
  if (a.state === "ready") {
2282
- let n = Wt(e);
2283
- if (await y.runPromise(qt(e).deleteByRef(t)), !await y.runPromise(n.delete(t))) throw Error("Storage deletion lost its confirmed reference");
2396
+ let n = Jt(e);
2397
+ if (await y.runPromise(Zt(e).deleteByRef(t)), !await y.runPromise(n.delete(t))) throw Error("Storage deletion lost its confirmed reference");
2284
2398
  await y.runPromise(n.releaseUsage(r.identity.tenantId, {
2285
2399
  bytes: r.ref.size,
2286
2400
  count: 1
@@ -2293,8 +2407,8 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2293
2407
  };
2294
2408
  });
2295
2409
  },
2296
- confirmDelete: (t) => sn(e, t, (e) => dn(e, t))
2297
- }), bn = (e, t = 65536) => {
2410
+ confirmDelete: (t) => fn(e, t, (e) => gn(e, t))
2411
+ }), Tn = (e, t = 65536) => {
2298
2412
  let n = [Buffer.from("zINSTREAM\0", "utf8")];
2299
2413
  for (let r = 0; r < e.length; r += t) {
2300
2414
  let i = e.subarray(r, Math.min(r + t, e.length)), a = Buffer.alloc(4);
@@ -2302,7 +2416,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2302
2416
  }
2303
2417
  let r = Buffer.alloc(4);
2304
2418
  return r.writeUInt32BE(0, 0), n.push(r), Buffer.concat(n);
2305
- }, xn = (e) => {
2419
+ }, En = (e) => {
2306
2420
  let t = e.replace(/\0+$/, "").trim();
2307
2421
  if (/\bOK$/.test(t)) return { clean: !0 };
2308
2422
  let n = /:\s*(.+?)\s+FOUND$/.exec(t);
@@ -2311,7 +2425,7 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2311
2425
  threat: n[1] ?? "unknown"
2312
2426
  };
2313
2427
  throw Error(`clamav: unexpected response: ${t}`);
2314
- }, Sn = async (e, t) => {
2428
+ }, Dn = async (e, t) => {
2315
2429
  let n = await import("node:net"), r = W.read("CLAMAV_HOST", t.host) ?? "127.0.0.1", i = W.read("CLAMAV_PORT"), a = t.port ?? (i ? Number(i) : 3310), o = t.timeoutMs ?? 3e4;
2316
2430
  return new Promise((i, s) => {
2317
2431
  let c = n.createConnection({
@@ -2323,20 +2437,20 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2323
2437
  c.on("error", (e) => {
2324
2438
  clearTimeout(u), s(e);
2325
2439
  }), c.on("connect", () => {
2326
- c.end(bn(e, t.chunkSize));
2440
+ c.end(Tn(e, t.chunkSize));
2327
2441
  }), c.on("data", (e) => {
2328
2442
  l += e.toString("utf8");
2329
2443
  }), c.on("close", () => {
2330
2444
  clearTimeout(u);
2331
2445
  try {
2332
- i(xn(l));
2446
+ i(En(l));
2333
2447
  } catch (e) {
2334
2448
  s(e);
2335
2449
  }
2336
2450
  });
2337
2451
  });
2338
- }, Cn = (e = {}) => (t) => Sn(t.bytes, e), wn = (e, t, n) => new Promise((r, i) => {
2339
- let a = ve(e, [...t], { stdio: [
2452
+ }, On = (e = {}) => (t) => Dn(t.bytes, e), kn = (e, t, n) => new Promise((r, i) => {
2453
+ let a = ye(e, [...t], { stdio: [
2340
2454
  "ignore",
2341
2455
  "ignore",
2342
2456
  "pipe"
@@ -2350,31 +2464,31 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2350
2464
  }), a.on("close", (e) => {
2351
2465
  clearTimeout(s), e === 0 ? r() : i(/* @__PURE__ */ Error(`ffmpeg exited ${String(e)}: ${o.slice(-400)}`));
2352
2466
  });
2353
- }), Tn = (e) => async ({ bytes: t }) => {
2354
- let n = e.ffmpegPath ?? "ffmpeg", r = e.timeoutMs ?? 3e5, i = await ye(z(Ce(), "voltro-tc-")), a = z(i, "in"), o = [];
2467
+ }), An = (e) => async ({ bytes: t }) => {
2468
+ let n = e.ffmpegPath ?? "ffmpeg", r = e.timeoutMs ?? 3e5, i = await be(z(we(), "voltro-tc-")), a = z(i, "in"), o = [];
2355
2469
  try {
2356
- await Se(a, t);
2470
+ await Ce(a, t);
2357
2471
  for (let t of e.renditions) {
2358
2472
  let e = z(i, `out.${t.ext}`);
2359
2473
  try {
2360
- await wn(n, [
2474
+ await kn(n, [
2361
2475
  "-y",
2362
2476
  "-i",
2363
2477
  a,
2364
2478
  ...t.args,
2365
2479
  e
2366
2480
  ], r);
2367
- let i = await be(e);
2481
+ let i = await xe(e);
2368
2482
  o.push({
2369
2483
  bytes: new Uint8Array(i),
2370
2484
  contentType: t.contentType,
2371
2485
  kind: t.kind,
2372
2486
  ...t.label === void 0 ? {} : { label: t.label }
2373
- }), await xe(e, { force: !0 });
2487
+ }), await Se(e, { force: !0 });
2374
2488
  } catch {}
2375
2489
  }
2376
2490
  } finally {
2377
- await xe(i, {
2491
+ await Se(i, {
2378
2492
  recursive: !0,
2379
2493
  force: !0
2380
2494
  }).catch(() => void 0);
@@ -2383,21 +2497,21 @@ var we = 1 << 20, Te = (e, n, r = !1) => new t({
2383
2497
  };
2384
2498
  //#endregion
2385
2499
  //#region src/assetRef.ts
2386
- function En(e = {}) {
2387
- let t = e.nullable ?? !0, n = e.fk === !1 ? P().externalId() : pe(() => Pe, { onDelete: e.onDelete ?? "setNull" });
2500
+ function jn(e = {}) {
2501
+ let t = e.nullable ?? !0, n = e.fk === !1 ? F().externalId() : fe(() => Fe, { onDelete: e.onDelete ?? "setNull" });
2388
2502
  return t ? n.nullable() : n;
2389
2503
  }
2390
- var Dn = () => j({
2504
+ var Mn = () => de({
2391
2505
  id: "@voltro/plugin-storage/withStorage",
2392
- fields: { asset: En() }
2393
- }), On = {
2506
+ fields: { asset: jn() }
2507
+ }), Nn = {
2394
2508
  "image/png": "png",
2395
2509
  "image/jpeg": "jpg",
2396
2510
  "image/jpg": "jpg",
2397
2511
  "image/gif": "gif",
2398
2512
  "image/webp": "webp",
2399
2513
  "image/svg+xml": "svg"
2400
- }, kn = (e) => {
2514
+ }, Pn = (e) => {
2401
2515
  let t = /^data:([^;,]+)(;base64)?,(.*)$/s.exec(e);
2402
2516
  if (!t) throw Error("not a data URI");
2403
2517
  let n = t[1] || "application/octet-stream", r = !!t[2], i = t[3] ?? "";
@@ -2405,16 +2519,16 @@ var Dn = () => j({
2405
2519
  bytes: r ? new Uint8Array(Buffer.from(i, "base64")) : new Uint8Array(Buffer.from(decodeURIComponent(i), "utf8")),
2406
2520
  contentType: n
2407
2521
  };
2408
- }, An = (e, n) => y.gen(function* () {
2522
+ }, Fn = (e, n) => y.gen(function* () {
2409
2523
  let r = yield* y.try({
2410
- try: () => kn(n.dataUri),
2524
+ try: () => Pn(n.dataUri),
2411
2525
  catch: (e) => new t({
2412
2526
  provider: "avatar",
2413
2527
  message: String(e?.message ?? e),
2414
2528
  transient: !1,
2415
2529
  status: 400
2416
2530
  })
2417
- }), i = On[r.contentType] ?? "bin";
2531
+ }), i = Nn[r.contentType] ?? "bin";
2418
2532
  return yield* e.put({
2419
2533
  bytes: r.bytes,
2420
2534
  contentType: r.contentType,
@@ -2423,27 +2537,27 @@ var Dn = () => j({
2423
2537
  visibility: "public",
2424
2538
  key: `avatars/${n.userId}/avatar.${i}`
2425
2539
  });
2426
- }), jn = (e) => {
2540
+ }), In = (e) => {
2427
2541
  try {
2428
2542
  let t = B(e), n = B("/");
2429
2543
  return typeof t.dev != "number" || typeof n.dev != "number" ? "unknown" : t.dev === n.dev ? "same-device-as-root" : "separate-mount";
2430
2544
  } catch {
2431
2545
  return "unknown";
2432
2546
  }
2433
- }, Mn = (e) => {
2434
- if (jn(e) === "same-device-as-root") return `the capture is going to ${e}, which is on the SAME filesystem as \`/\`.\n A mounted volume would be a separate one. If this process is a container, that means the capture
2547
+ }, Ln = (e) => {
2548
+ if (In(e) === "same-device-as-root") return `the capture is going to ${e}, which is on the SAME filesystem as \`/\`.\n A mounted volume would be a separate one. If this process is a container, that means the capture
2435
2549
  dies with it — which is the exact failure it exists for. On a development machine this is normal
2436
2550
  and can be ignored.`;
2437
- }, Nn = W.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", Pn, Fn = (e) => {
2438
- Pn = e;
2439
- }, In = () => Pn ?? Rn({}), Ln = () => Pn === void 0 ? W.read("STORAGE_PROVIDER") === void 0 ? void 0 : Rn({}) : Pn, Rn = (e) => {
2551
+ }, Rn = W.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", zn, Bn = (e) => {
2552
+ zn = e;
2553
+ }, Vn = () => zn ?? Un({}), Hn = () => zn === void 0 ? W.read("STORAGE_PROVIDER") === void 0 ? void 0 : Un({}) : zn, Un = (e) => {
2440
2554
  if (e.provider && typeof e.provider == "object") return e.provider;
2441
2555
  let t = (e.provider ?? W.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = W.read("S3_BUCKET", e.bucket) ?? W.read("STORAGE_BUCKET") ?? "voltro";
2442
2556
  switch (t) {
2443
2557
  case "s3":
2444
2558
  case "minio": {
2445
2559
  let r = W.read("S3_REGION", e.region) ?? W.read("AWS_REGION"), i = W.read("S3_ENDPOINT", e.endpoint) ?? W.read("MINIO_ENDPOINT"), a = W.read("S3_ACCESS_KEY_ID", e.accessKeyId) ?? W.read("AWS_ACCESS_KEY_ID"), o = W.read("S3_SECRET_ACCESS_KEY", e.secretAccessKey) ?? W.read("AWS_SECRET_ACCESS_KEY"), s = W.read("STORAGE_CDN_URL", e.cdnBaseUrl);
2446
- return We({
2560
+ return Ge({
2447
2561
  bucket: n,
2448
2562
  name: t,
2449
2563
  ...r ? { region: r } : {},
@@ -2457,7 +2571,7 @@ var Dn = () => j({
2457
2571
  }
2458
2572
  case "azure": {
2459
2573
  let t = W.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = W.read("AZURE_STORAGE_KEY", e.accountKey), i = W.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString), a = W.read("AZURE_STORAGE_ENDPOINT", e.endpoint), o = W.read("STORAGE_CDN_URL", e.cdnBaseUrl);
2460
- return qe({
2574
+ return Je({
2461
2575
  container: W.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
2462
2576
  ...t ? { accountName: t } : {},
2463
2577
  ...r ? { accountKey: r } : {},
@@ -2466,15 +2580,43 @@ var Dn = () => j({
2466
2580
  ...o ? { cdnBaseUrl: o } : {}
2467
2581
  });
2468
2582
  }
2469
- case "database": return Ke();
2470
- case "filesystem": return Ue({ root: W.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
2471
- default: return He(e.name ?? "default");
2583
+ case "database": return qe();
2584
+ case "filesystem": return We({ root: W.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
2585
+ default: return Ue(e.name ?? "default");
2586
+ }
2587
+ }, Wn = (e) => {
2588
+ let t = "stored files (uploads, renditions) and their reads", n = "provider 'database' or 'filesystem' keeps the bytes inside the installation";
2589
+ if (e.provider && typeof e.provider == "object") return [{
2590
+ destination: `runtime:the '${e.provider.name}' storage provider`,
2591
+ purpose: t,
2592
+ data: ["files"],
2593
+ disable: n
2594
+ }];
2595
+ let r = (e.provider ?? W.read("STORAGE_PROVIDER") ?? "memory").toLowerCase();
2596
+ if (r === "s3" || r === "minio") {
2597
+ let r = W.read("S3_ENDPOINT", e.endpoint) ?? W.read("MINIO_ENDPOINT"), i = W.read("S3_REGION", e.region) ?? W.read("AWS_REGION") ?? "us-east-1";
2598
+ return [{
2599
+ destination: r ?? `s3.${i}.amazonaws.com`,
2600
+ purpose: t,
2601
+ data: ["files"],
2602
+ disable: n
2603
+ }];
2472
2604
  }
2473
- }, zn = (e) => {
2605
+ if (r === "azure") {
2606
+ let r = W.read("AZURE_STORAGE_ENDPOINT", e.endpoint), i = W.read("AZURE_STORAGE_ACCOUNT", e.accountName);
2607
+ return [{
2608
+ destination: r ?? (i === void 0 ? "runtime:the Azure storage connection string" : `${i}.blob.core.windows.net`),
2609
+ purpose: t,
2610
+ data: ["files"],
2611
+ disable: n
2612
+ }];
2613
+ }
2614
+ return [];
2615
+ }, Gn = (e) => {
2474
2616
  if (e !== void 0) return e;
2475
2617
  let t = W.read("STORAGE_ALLOWED_ORIGINS");
2476
2618
  return t ? t.trim() === "*" ? "*" : t.split(",").map((e) => e.trim()).filter(Boolean) : [];
2477
- }, Bn = (e, t) => {
2619
+ }, Kn = (e, t) => {
2478
2620
  if (!e || t !== "*" && !t.includes(e)) return {};
2479
2621
  let n = {
2480
2622
  "access-control-allow-origin": t === "*" ? "*" : e,
@@ -2484,7 +2626,7 @@ var Dn = () => j({
2484
2626
  vary: "Origin"
2485
2627
  };
2486
2628
  return t !== "*" && (n["access-control-allow-credentials"] = "true"), n;
2487
- }, Vn = (e) => ({
2629
+ }, qn = (e) => ({
2488
2630
  id: e.id,
2489
2631
  tenantId: e.tenantId,
2490
2632
  ownerId: e.ownerId,
@@ -2507,29 +2649,29 @@ var Dn = () => j({
2507
2649
  caption: e.caption ?? null,
2508
2650
  derivedFrom: e.derivedFrom ?? null,
2509
2651
  kind: e.kind ?? null
2510
- }), Hn = () => new t({
2652
+ }), Jn = () => new t({
2511
2653
  provider: "storage",
2512
2654
  message: "not permitted to administer sharing for this object",
2513
2655
  transient: !1,
2514
2656
  status: 403
2515
- }), Un = (e, t, n) => {
2657
+ }), Yn = (e, t, n) => {
2516
2658
  let r = n.request.subject;
2517
- return (r.scopes ?? []).includes("admin:full") ? y.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(y.catchAll(() => y.fail(Hn())), y.flatMap((e) => {
2659
+ return (r.scopes ?? []).includes("admin:full") ? y.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(y.catchAll(() => y.fail(Jn())), y.flatMap((e) => {
2518
2660
  let t = e?.ownerId;
2519
- return t != null && t === r.id ? y.void : y.fail(Hn());
2661
+ return t != null && t === r.id ? y.void : y.fail(Jn());
2520
2662
  }));
2521
- }, Wn = () => new t({
2663
+ }, Xn = () => new t({
2522
2664
  provider: "storage",
2523
2665
  message: "an upload needs an identified caller: this request carries no subject, and the app has not set `anonymousUploads: true` on storagePlugin. The ticket attributes the object to whoever minted it — with no subject there is nobody to attribute it to, so the finalized object would carry no owner and no tenant and no later owner check, tenant filter or quota could reach it.",
2524
2666
  transient: !1,
2525
2667
  status: 401
2526
- }), Gn = (e, t) => {
2668
+ }), $ = (e, t) => {
2527
2669
  let n = e.request.subject.id ?? null, r = e.request.subject.tenantId ?? null;
2528
- return n === null && !t ? y.fail(Wn()) : y.succeed({
2670
+ return n === null && !t ? y.fail(Xn()) : y.succeed({
2529
2671
  id: n,
2530
2672
  tenantId: r
2531
2673
  });
2532
- }, Kn = (e, t) => e !== null && e !== (t ?? null), qn = (e) => ({
2674
+ }, Zn = (e, t) => e !== null && e !== (t ?? null), Qn = (e) => ({
2533
2675
  id: e.id,
2534
2676
  refId: e.refId,
2535
2677
  principalType: e.principalType,
@@ -2538,55 +2680,62 @@ var Dn = () => j({
2538
2680
  createdAt: e.createdAt.toISOString(),
2539
2681
  expiresAt: e.expiresAt ? e.expiresAt.toISOString() : null,
2540
2682
  createdBy: e.createdBy
2541
- }), Jn = "@voltro/plugin-storage", Yn = (e = {}) => oe({
2542
- base: Jn,
2683
+ }), $n = "@voltro/plugin-storage", er = (e = {}) => ae({
2684
+ base: $n,
2543
2685
  alias: e.alias,
2544
2686
  instance: e.name
2545
- }), Xn = (i = {}) => {
2546
- let v = oe({
2547
- base: Jn,
2687
+ }), tr = (i = {}) => {
2688
+ let v = ae({
2689
+ base: $n,
2548
2690
  alias: i.alias,
2549
2691
  instance: i.name
2550
- }), b = v === Jn ? "/_voltro/storage" : `/_voltro/storage/i/${Buffer.from(v).toString("hex")}`, x = Rn(i);
2551
- Fn(x);
2552
- let S = W.read("S3_BUCKET", i.bucket) ?? W.read("STORAGE_BUCKET") ?? "voltro", T = W.read("VOLTRO_PUBLIC_URL", i.publicBaseUrl), ue = zn(i.allowedOrigins), E = i.limits?.maxBytes, D = i.anonymousUploads === !0, O = 5242880, de = 21600, k = i.refStore === void 0 || i.refStore === "memory", A = i.grantStore === void 0 || i.grantStore === "memory", j = { current: k ? Vt() : i.refStore }, M = { current: A ? Gt() : i.grantStore }, fe = { current: void 0 }, pe = {
2553
- insert: (e) => j.current.insert(e),
2554
- getById: (e) => j.current.getById(e),
2555
- delete: (e) => j.current.delete(e),
2556
- statistics: () => j.current.statistics(),
2557
- listRecent: (e) => j.current.listRecent(e),
2558
- countByKey: (e, t) => j.current.countByKey(e, t),
2559
- usageByTenant: (e) => j.current.usageByTenant(e),
2560
- consumeUsage: (e, t, n) => j.current.consumeUsage(e, t, n),
2561
- releaseUsage: (e, t) => j.current.releaseUsage(e, t),
2562
- listByDerivedFrom: (e) => j.current.listByDerivedFrom(e),
2563
- listRefs: (e) => j.current.listRefs(e)
2564
- }, N = {
2692
+ }), b = v === $n ? "/_voltro/storage" : `/_voltro/storage/i/${Buffer.from(v).toString("hex")}`, x = Un(i);
2693
+ Bn(x);
2694
+ let S = W.read("S3_BUCKET", i.bucket) ?? W.read("STORAGE_BUCKET") ?? "voltro", E = W.read("VOLTRO_PUBLIC_URL", i.publicBaseUrl), le = Gn(i.allowedOrigins), D = i.limits?.maxBytes, O = i.anonymousUploads === !0, k = 5242880, ue = 21600, A = i.refStore === void 0 || i.refStore === "memory", j = i.grantStore === void 0 || i.grantStore === "memory", de = (e) => e !== "public" && i.uploadAccess !== void 0 ? { access: i.uploadAccess } : {}, M = { current: A ? Gt() : i.refStore }, N = { current: j ? Yt() : i.grantStore }, fe = { current: void 0 }, P = {
2565
2695
  insert: (e) => M.current.insert(e),
2566
- delete: (e) => M.current.delete(e),
2567
2696
  getById: (e) => M.current.getById(e),
2568
- listByRef: (e) => M.current.listByRef(e),
2569
- deleteByRef: (e) => M.current.deleteByRef(e)
2570
- }, P = {
2697
+ delete: (e) => M.current.delete(e),
2698
+ statistics: () => M.current.statistics(),
2699
+ listRecent: (e) => M.current.listRecent(e),
2700
+ countByKey: (e, t) => M.current.countByKey(e, t),
2701
+ usageByTenant: (e) => M.current.usageByTenant(e),
2702
+ consumeUsage: (e, t, n) => M.current.consumeUsage(e, t, n),
2703
+ releaseUsage: (e, t) => M.current.releaseUsage(e, t),
2704
+ listByDerivedFrom: (e) => M.current.listByDerivedFrom(e),
2705
+ listRefs: (e) => M.current.listRefs(e),
2706
+ get setVisibility() {
2707
+ return M.current.setVisibility;
2708
+ },
2709
+ get countPublicByKey() {
2710
+ return M.current.countPublicByKey;
2711
+ }
2712
+ }, F = {
2713
+ insert: (e) => N.current.insert(e),
2714
+ delete: (e) => N.current.delete(e),
2715
+ getById: (e) => N.current.getById(e),
2716
+ listByRef: (e) => N.current.listByRef(e),
2717
+ deleteByRef: (e) => N.current.deleteByRef(e)
2718
+ }, pe = {
2571
2719
  httpPath: b,
2572
2720
  provider: x,
2573
- refStore: pe,
2574
- grantStore: N,
2721
+ refStore: P,
2722
+ grantStore: F,
2575
2723
  bucket: S,
2576
2724
  ...i.tenantPrefix === void 0 ? {} : { tenantPrefix: i.tenantPrefix },
2577
2725
  ...i.attempts === void 0 ? {} : { attempts: i.attempts },
2578
2726
  ...i.urlExpiresInSec === void 0 ? {} : { urlExpiresInSec: i.urlExpiresInSec },
2579
2727
  ...i.access === void 0 ? {} : { access: i.access },
2580
2728
  ...i.limits === void 0 ? {} : { limits: i.limits },
2729
+ ...i.ingest === void 0 ? {} : { ingest: i.ingest },
2581
2730
  ...i.scan === void 0 ? {} : { scan: i.scan },
2582
2731
  ...i.videoProbe === void 0 ? {} : { videoProbe: i.videoProbe },
2583
2732
  ...i.transcode === void 0 ? {} : { transcode: i.transcode },
2584
2733
  ...i.autoTranscode === void 0 ? {} : { autoTranscode: i.autoTranscode },
2585
- ...T ? { publicBaseUrl: T } : {},
2734
+ ...E ? { publicBaseUrl: E } : {},
2586
2735
  ...i.normalizeImages === void 0 ? {} : { normalizeImages: i.normalizeImages },
2587
2736
  ...i.quota === void 0 ? {} : { quota: i.quota },
2588
2737
  objects: () => fe.current
2589
- }, me = Zt(P), F = Xt(P), I = `${b}/`, L = (e) => y.runPromise(e.pipe(y.catchAll(() => y.succeed(null)))), _e = (e, t) => {
2738
+ }, me = tn(pe), I = en(pe), ge = `${b}/`, L = (e) => y.runPromise(e.pipe(y.catchAll(() => y.succeed(null)))), R = (e, t) => {
2590
2739
  if (!e) return "invalid";
2591
2740
  let n = /^bytes=(\d*)-(\d*)$/.exec(e.trim());
2592
2741
  if (!n) return "invalid";
@@ -2607,30 +2756,31 @@ var Dn = () => j({
2607
2756
  start: a,
2608
2757
  endInclusive: o
2609
2758
  };
2610
- }, R = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, ve = (e) => ({
2759
+ }, ve = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, ye = (e) => ({
2611
2760
  "x-content-type-options": "nosniff",
2612
- "content-disposition": R.test(e) ? "inline" : "attachment"
2613
- }), ye = async (e, t, n, r) => {
2761
+ "content-disposition": ve.test(e) ? "inline" : "attachment"
2762
+ }), be = async (e, t, n, r) => {
2614
2763
  if (n) {
2615
- let r = await L(F.get(e.id));
2764
+ let r = await L(I.get(e.id));
2616
2765
  if (!r) return {
2617
2766
  status: 404,
2618
2767
  body: "not found",
2619
2768
  contentType: "text/plain"
2620
2769
  };
2621
- let i = await nt(e.id, r.bytes, e.contentType, n).catch(() => null), a = i ? i.bytes : r.bytes, o = i ? i.contentType : e.contentType;
2770
+ let i = await at(e.id, r.bytes, e.contentType, n).catch(() => null), a = i ? i.bytes : r.bytes, o = i ? i.contentType : e.contentType, s = await tt(e.contentType, i !== null);
2622
2771
  return {
2623
2772
  status: 200,
2624
2773
  body: a,
2625
2774
  contentType: o,
2626
2775
  headers: {
2627
- ...ve(o),
2776
+ ...ye(o),
2628
2777
  "cache-control": t,
2629
- "accept-ranges": "none"
2778
+ "accept-ranges": "none",
2779
+ ...s === null ? {} : { "x-voltro-transform": `original; reason=${s}` }
2630
2780
  }
2631
2781
  };
2632
2782
  }
2633
- let i = r === void 0 ? "invalid" : _e(r, e.size);
2783
+ let i = r === void 0 ? "invalid" : R(r, e.size);
2634
2784
  if (i === "unsatisfiable") return {
2635
2785
  status: 416,
2636
2786
  body: "range not satisfiable",
@@ -2641,13 +2791,13 @@ var Dn = () => j({
2641
2791
  }
2642
2792
  };
2643
2793
  if (i !== "invalid") {
2644
- let n = await L(F.getRange(e.id, i));
2794
+ let n = await L(I.getRange(e.id, i));
2645
2795
  return n ? {
2646
2796
  status: 206,
2647
2797
  body: n.bytes,
2648
2798
  contentType: e.contentType,
2649
2799
  headers: {
2650
- ...ve(e.contentType),
2800
+ ...ye(e.contentType),
2651
2801
  "cache-control": t,
2652
2802
  "accept-ranges": "bytes",
2653
2803
  "content-range": `bytes ${i.start}-${i.endInclusive}/${n.totalSize}`
@@ -2658,12 +2808,12 @@ var Dn = () => j({
2658
2808
  contentType: "text/plain"
2659
2809
  };
2660
2810
  }
2661
- let a = await L(F.getStream(e.id));
2811
+ let a = await L(I.getStream(e.id));
2662
2812
  return a ? {
2663
2813
  status: 200,
2664
2814
  contentType: e.contentType,
2665
2815
  headers: {
2666
- ...ve(e.contentType),
2816
+ ...ye(e.contentType),
2667
2817
  "cache-control": t,
2668
2818
  "accept-ranges": "bytes"
2669
2819
  },
@@ -2676,20 +2826,20 @@ var Dn = () => j({
2676
2826
  body: "not found",
2677
2827
  contentType: "text/plain"
2678
2828
  };
2679
- }, be = async (e) => {
2680
- let t = e.path.startsWith(I) ? e.path.slice(I.length).split("/")[0] ?? "" : "";
2829
+ }, xe = async (e) => {
2830
+ let t = e.path.startsWith(ge) ? e.path.slice(ge.length).split("/")[0] ?? "" : "";
2681
2831
  if (!t) return {
2682
2832
  status: 404,
2683
2833
  body: "not found",
2684
2834
  contentType: "text/plain"
2685
2835
  };
2686
- let n = await L(F.head(t));
2836
+ let n = await L(I.head(t));
2687
2837
  if (!n) return {
2688
2838
  status: 404,
2689
2839
  body: "not found",
2690
2840
  contentType: "text/plain"
2691
2841
  };
2692
- let r = Ye(e.query), i = e.headers.range;
2842
+ let r = Ze(e.query), i = e.headers.range;
2693
2843
  if (n.visibility === "public") {
2694
2844
  let e = x.publicUrl?.(n.key) ?? null;
2695
2845
  return e && !r ? {
@@ -2698,16 +2848,16 @@ var Dn = () => j({
2698
2848
  location: e,
2699
2849
  "cache-control": "public, max-age=300"
2700
2850
  }
2701
- } : ye(n, "public, max-age=31536000, immutable", r, i);
2851
+ } : be(n, "public, max-age=31536000, immutable", r, i);
2702
2852
  }
2703
2853
  let a = !1, o = e.query ? new URLSearchParams(e.query).get("t") : null;
2704
2854
  if (o) {
2705
- let e = _t(o);
2855
+ let e = bt(o);
2706
2856
  a = !!e && e.refId === t && e.audience === b;
2707
2857
  }
2708
2858
  if (!a) {
2709
- let t = se(e.headers.cookie, Nn), r = t ? le(t, ce()) : null;
2710
- r && (a = await L(F.checkAccess(n, r)) === !0);
2859
+ let t = oe(e.headers.cookie, Rn), r = t ? ce(t, se()) : null;
2860
+ r && (a = await L(I.checkAccess(n, r)) === !0);
2711
2861
  }
2712
2862
  if (!a) return {
2713
2863
  status: 403,
@@ -2724,12 +2874,12 @@ var Dn = () => j({
2724
2874
  }
2725
2875
  };
2726
2876
  }
2727
- return ye(n, "private, no-store", r, i);
2728
- }, xe = {
2877
+ return be(n, "private, no-store", r, i);
2878
+ }, Se = {
2729
2879
  method: "GET",
2730
2880
  path: b,
2731
2881
  handle: async (e) => {
2732
- let t = await be(e), n = Bn(e.headers.origin, ue);
2882
+ let t = await xe(e), n = Kn(e.headers.origin, le);
2733
2883
  return Object.keys(n).length === 0 ? t : {
2734
2884
  ...t,
2735
2885
  headers: {
@@ -2738,12 +2888,12 @@ var Dn = () => j({
2738
2888
  }
2739
2889
  };
2740
2890
  }
2741
- }, Se = {
2891
+ }, Ce = {
2742
2892
  method: "*",
2743
2893
  path: `${b}/upload`,
2744
2894
  originGuard: "exempt",
2745
2895
  handle: async (e) => {
2746
- let t = Bn(e.headers.origin, ue);
2896
+ let t = Kn(e.headers.origin, le);
2747
2897
  if (e.method === "OPTIONS") return {
2748
2898
  status: 204,
2749
2899
  headers: t
@@ -2754,7 +2904,7 @@ var Dn = () => j({
2754
2904
  contentType: "text/plain",
2755
2905
  headers: t
2756
2906
  };
2757
- let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ? yt(n) : null;
2907
+ let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ? St(n) : null;
2758
2908
  if (!r || r.instance !== v) return {
2759
2909
  status: 401,
2760
2910
  body: "invalid or expired upload ticket",
@@ -2779,19 +2929,20 @@ var Dn = () => j({
2779
2929
  contentType: "text/plain",
2780
2930
  headers: t
2781
2931
  };
2782
- let i = await y.runPromise(F.put({
2932
+ let i = await y.runPromise(I.put({
2783
2933
  bytes: e.rawBody,
2784
2934
  contentType: r.ct,
2785
2935
  tenantId: r.tenant,
2786
2936
  ownerId: r.sub,
2787
2937
  visibility: r.vis,
2938
+ ...de(r.vis),
2788
2939
  ...r.operationId === void 0 ? {} : { operationId: r.operationId },
2789
2940
  ...r.key === void 0 ? {} : { key: r.key },
2790
2941
  ...r.folder === void 0 ? {} : { folder: r.folder },
2791
2942
  ...r.tags === void 0 ? {} : { tags: r.tags },
2792
2943
  ...r.alt === void 0 ? {} : { alt: r.alt },
2793
2944
  ...r.caption === void 0 ? {} : { caption: r.caption }
2794
- }).pipe(y.flatMap((e) => F.getUrl(e.id).pipe(y.map((t) => ({
2945
+ }).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
2795
2946
  kind: "ok",
2796
2947
  ref: e,
2797
2948
  url: t
@@ -2837,17 +2988,17 @@ var Dn = () => j({
2837
2988
  headers: t
2838
2989
  };
2839
2990
  }
2840
- }, Ce = {
2991
+ }, we = {
2841
2992
  method: "*",
2842
2993
  path: `${b}/upload/resumable`,
2843
2994
  originGuard: "exempt",
2844
2995
  handle: async (e) => {
2845
- let t = Bn(e.headers.origin, ue);
2996
+ let t = Kn(e.headers.origin, le);
2846
2997
  if (e.method === "OPTIONS") return {
2847
2998
  status: 204,
2848
2999
  headers: t
2849
3000
  };
2850
- let n = new URLSearchParams(e.query || ""), r = Ct(n.get("token") ?? "");
3001
+ let n = new URLSearchParams(e.query || ""), r = Et(n.get("token") ?? "");
2851
3002
  if (!r || r.instance !== v) return {
2852
3003
  status: 401,
2853
3004
  body: "invalid or expired resumable token",
@@ -2855,7 +3006,7 @@ var Dn = () => j({
2855
3006
  headers: t
2856
3007
  };
2857
3008
  if (e.method === "GET" || e.method === "HEAD") {
2858
- let e = await y.runPromise(F.resumableStatus({
3009
+ let e = await y.runPromise(I.resumableStatus({
2859
3010
  uploadId: r.id,
2860
3011
  tenantId: r.tenant
2861
3012
  }).pipe(y.match({
@@ -2896,23 +3047,24 @@ var Dn = () => j({
2896
3047
  contentType: "text/plain",
2897
3048
  headers: t
2898
3049
  };
2899
- let a = n.get("final") === "1", o = await y.runPromise(F.putResumableChunk({
3050
+ let a = n.get("final") === "1", o = await y.runPromise(I.putResumableChunk({
2900
3051
  uploadId: r.id,
2901
3052
  tenantId: r.tenant,
2902
3053
  index: i,
2903
3054
  bytes: e.rawBody
2904
- }).pipe(y.flatMap(() => a ? F.finalizeResumable({
3055
+ }).pipe(y.flatMap(() => a ? I.finalizeResumable({
2905
3056
  uploadId: r.id,
2906
3057
  count: i + 1,
2907
3058
  contentType: r.ct,
2908
3059
  tenantId: r.tenant,
2909
3060
  ownerId: r.sub,
2910
3061
  visibility: r.vis,
3062
+ ...de(r.vis),
2911
3063
  ...r.folder === void 0 ? {} : { folder: r.folder },
2912
3064
  ...r.tags === void 0 ? {} : { tags: r.tags },
2913
3065
  ...r.alt === void 0 ? {} : { alt: r.alt },
2914
3066
  ...r.caption === void 0 ? {} : { caption: r.caption }
2915
- }).pipe(y.flatMap((e) => F.getUrl(e.id).pipe(y.map((t) => ({
3067
+ }).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
2916
3068
  kind: "done",
2917
3069
  ref: e,
2918
3070
  url: t
@@ -2971,13 +3123,13 @@ var Dn = () => j({
2971
3123
  kind: "json",
2972
3124
  status: e,
2973
3125
  data: { error: t }
2974
- }), we = (e, t) => {
3126
+ }), Te = (e, t) => {
2975
3127
  try {
2976
3128
  return new URL(e, "http://localhost").searchParams.get(t);
2977
3129
  } catch {
2978
3130
  return null;
2979
3131
  }
2980
- }, Te = [
3132
+ }, Ee = [
2981
3133
  {
2982
3134
  method: "POST",
2983
3135
  path: "/upload-ticket",
@@ -2998,8 +3150,8 @@ var Dn = () => j({
2998
3150
  status: 400
2999
3151
  })));
3000
3152
  if (r.operationId !== void 0 && fe.current === void 0) return B(409, "Durable uploads require a bound operation store with default reference and grant stores");
3001
- if (E !== void 0 && r.size > E) return B(413, "File exceeds the configured upload limit");
3002
- let i = vt({
3153
+ if (D !== void 0 && r.size > D) return B(413, "File exceeds the configured upload limit");
3154
+ let i = xt({
3003
3155
  instance: v,
3004
3156
  ...r.operationId === void 0 ? {} : { operationId: `inspect-upload:${he("sha256").update(JSON.stringify([v, r.operationId])).digest("hex")}` },
3005
3157
  replicaId: _().replicaId,
@@ -3022,9 +3174,9 @@ var Dn = () => j({
3022
3174
  path: "/download",
3023
3175
  description: "Stream a stored file as an attachment for authorized inspect readers",
3024
3176
  handler: (e) => y.gen(function* () {
3025
- let t = we(e.url, "refId");
3177
+ let t = Te(e.url, "refId");
3026
3178
  if (!t?.trim()) return B(400, "A non-empty refId is required");
3027
- let { ref: n, stream: r } = yield* F.getStream(t), i = n.key.split("/").pop() || n.id, a = encodeURIComponent(i).replace(/[!'()*]/g, (e) => `%${e.charCodeAt(0).toString(16).toUpperCase()}`);
3179
+ let { ref: n, stream: r } = yield* I.getStream(t), i = n.key.split("/").pop() || n.id, a = encodeURIComponent(i).replace(/[!'()*]/g, (e) => `%${e.charCodeAt(0).toString(16).toUpperCase()}`);
3028
3180
  return {
3029
3181
  kind: "bytes",
3030
3182
  contentType: n.contentType,
@@ -3043,8 +3195,8 @@ var Dn = () => j({
3043
3195
  scope: "process",
3044
3196
  description: "Searchable storage refs, newest first, paginated",
3045
3197
  handler: (e) => {
3046
- let t = Number(we(e.url, "offset") ?? 0), n = Number.isSafeInteger(t) && t >= 0 ? t : 0, r = (we(e.url, "search") ?? "").trim().slice(0, 200);
3047
- return pe.listRefs({
3198
+ let t = Number(Te(e.url, "offset") ?? 0), n = Number.isSafeInteger(t) && t >= 0 ? t : 0, r = (Te(e.url, "search") ?? "").trim().slice(0, 200);
3199
+ return P.listRefs({
3048
3200
  tenantId: void 0,
3049
3201
  ownerId: void 0,
3050
3202
  folder: void 0,
@@ -3054,7 +3206,7 @@ var Dn = () => j({
3054
3206
  limit: 51,
3055
3207
  offset: n
3056
3208
  }).pipe(y.map((e) => z({
3057
- refs: e.slice(0, 50).map(Vn),
3209
+ refs: e.slice(0, 50).map(qn),
3058
3210
  page: {
3059
3211
  search: r,
3060
3212
  offset: n,
@@ -3068,7 +3220,7 @@ var Dn = () => j({
3068
3220
  path: "/stats",
3069
3221
  scope: "process",
3070
3222
  description: "Object count + total bytes per tenant + visibility split",
3071
- handler: () => pe.statistics().pipe(y.map((e) => z({
3223
+ handler: () => P.statistics().pipe(y.map((e) => z({
3072
3224
  provider: x.name,
3073
3225
  bucket: S,
3074
3226
  ...e
@@ -3080,8 +3232,8 @@ var Dn = () => j({
3080
3232
  scope: "process",
3081
3233
  description: "Grants for a ref (?refId=…)",
3082
3234
  handler: (e) => {
3083
- let t = we(e.url, "refId");
3084
- return t ? N.listByRef(t).pipe(y.map((e) => z({ grants: e.map(qn) })), y.catchAll((e) => y.succeed(B(500, e.message)))) : y.succeed(B(400, "refId query param required"));
3235
+ let t = Te(e.url, "refId");
3236
+ return t ? F.listByRef(t).pipe(y.map((e) => z({ grants: e.map(Qn) })), y.catchAll((e) => y.succeed(B(500, e.message)))) : y.succeed(B(400, "refId query param required"));
3085
3237
  }
3086
3238
  },
3087
3239
  {
@@ -3102,14 +3254,14 @@ var Dn = () => j({
3102
3254
  status: 400
3103
3255
  }))), r = n.expiresInDays === void 0 ? null : new Date(Date.now() + n.expiresInDays * 864e5);
3104
3256
  if (r !== null && !Number.isFinite(r.getTime())) return B(400, "Expiry exceeds the supported date range");
3105
- let i = yield* F.grant({
3257
+ let i = yield* I.grant({
3106
3258
  refId: n.refId,
3107
3259
  principalType: n.principalType,
3108
3260
  principalId: n.principalId,
3109
3261
  ...n.permission ? { permission: n.permission } : {},
3110
3262
  expiresAt: r
3111
3263
  });
3112
- return z({ grant: qn(i) });
3264
+ return z({ grant: Qn(i) });
3113
3265
  }).pipe(y.catchAll((e) => y.succeed(B(e.status ?? 500, e.message ?? "share failed"))))
3114
3266
  },
3115
3267
  {
@@ -3123,7 +3275,7 @@ var Dn = () => j({
3123
3275
  transient: !1,
3124
3276
  status: 400
3125
3277
  })));
3126
- return yield* F.delete(n.refId), z({ ok: !0 });
3278
+ return yield* I.delete(n.refId), z({ ok: !0 });
3127
3279
  }).pipe(y.catchAll((e) => y.succeed(B(e.status ?? 500, e.message))))
3128
3280
  },
3129
3281
  {
@@ -3137,15 +3289,15 @@ var Dn = () => j({
3137
3289
  transient: !1,
3138
3290
  status: 400
3139
3291
  })));
3140
- return yield* F.revoke(n.grantId), z({ ok: !0 });
3292
+ return yield* I.revoke(n.grantId), z({ ok: !0 });
3141
3293
  }).pipe(y.catchAll((e) => y.succeed(B(e.status ?? 500, e.message ?? "revoke failed"))))
3142
3294
  }
3143
- ], Ee = [
3295
+ ], De = [
3144
3296
  {
3145
3297
  ...te,
3146
3298
  execute: (e, t) => {
3147
3299
  let n = e;
3148
- return F.mintUrl(n.id, t.request.subject, {
3300
+ return I.mintUrl(n.id, t.request.subject, {
3149
3301
  ...n.password === void 0 ? {} : { password: n.password },
3150
3302
  ...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
3151
3303
  }).pipe(y.map((e) => ({ url: e })));
@@ -3155,7 +3307,7 @@ var Dn = () => j({
3155
3307
  ...ee,
3156
3308
  execute: (e, t) => {
3157
3309
  let n = e;
3158
- return F.mintUploadUrl({
3310
+ return I.mintUploadUrl({
3159
3311
  key: n.key,
3160
3312
  contentType: n.contentType,
3161
3313
  tenantId: t.request.subject.tenantId,
@@ -3167,8 +3319,8 @@ var Dn = () => j({
3167
3319
  ...m,
3168
3320
  execute: (e, t) => {
3169
3321
  let n = e;
3170
- return Gn(t, D).pipe(y.map((e) => {
3171
- let t = n.expiresInSec ?? 900, r = vt({
3322
+ return $(t, O).pipe(y.map((e) => {
3323
+ let t = n.expiresInSec ?? 900, r = xt({
3172
3324
  instance: v,
3173
3325
  sub: e.id,
3174
3326
  tenant: e.tenantId,
@@ -3179,10 +3331,10 @@ var Dn = () => j({
3179
3331
  ...n.tags === void 0 ? {} : { tags: n.tags },
3180
3332
  ...n.alt === void 0 ? {} : { alt: n.alt },
3181
3333
  ...n.caption === void 0 ? {} : { caption: n.caption },
3182
- ...E === void 0 ? {} : { max: E }
3334
+ ...D === void 0 ? {} : { max: D }
3183
3335
  }, t);
3184
3336
  return {
3185
- uploadUrl: `${T ? T.replace(/\/+$/, "") : ""}${b}/upload?ticket=${encodeURIComponent(r)}`,
3337
+ uploadUrl: `${E ? E.replace(/\/+$/, "") : ""}${b}/upload?ticket=${encodeURIComponent(r)}`,
3186
3338
  expiresInSec: t
3187
3339
  };
3188
3340
  }));
@@ -3192,12 +3344,12 @@ var Dn = () => j({
3192
3344
  ...p,
3193
3345
  execute: (e, t) => {
3194
3346
  let n = e;
3195
- return Gn(t, D).pipe(y.flatMap((e) => F.mintPresignedUpload({
3347
+ return $(t, O).pipe(y.flatMap((e) => I.mintPresignedUpload({
3196
3348
  contentType: n.contentType,
3197
3349
  tenantId: e.tenantId,
3198
3350
  ...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
3199
3351
  }).pipe(y.map((t) => {
3200
- let r = bt({
3352
+ let r = Ct({
3201
3353
  instance: v,
3202
3354
  key: t.key,
3203
3355
  sub: e.id,
@@ -3208,7 +3360,7 @@ var Dn = () => j({
3208
3360
  ...n.tags === void 0 ? {} : { tags: n.tags },
3209
3361
  ...n.alt === void 0 ? {} : { alt: n.alt },
3210
3362
  ...n.caption === void 0 ? {} : { caption: n.caption },
3211
- ...E === void 0 ? {} : { max: E }
3363
+ ...D === void 0 ? {} : { max: D }
3212
3364
  }, t.expiresInSec);
3213
3365
  return {
3214
3366
  uploadUrl: t.uploadUrl,
@@ -3221,28 +3373,29 @@ var Dn = () => j({
3221
3373
  {
3222
3374
  ...l,
3223
3375
  execute: (e, n) => {
3224
- let r = xt(e.finalizeToken);
3376
+ let r = wt(e.finalizeToken);
3225
3377
  return !r || r.instance !== v ? y.fail(new t({
3226
3378
  provider: "storage",
3227
3379
  message: "invalid or expired finalize token",
3228
3380
  transient: !1,
3229
3381
  status: 401
3230
- })) : Kn(r.sub, n.request.subject.id) ? y.fail(new t({
3382
+ })) : Zn(r.sub, n.request.subject.id) ? y.fail(new t({
3231
3383
  provider: "storage",
3232
3384
  message: "finalize token belongs to another subject",
3233
3385
  transient: !1,
3234
3386
  status: 403
3235
- })) : F.finalizeUpload({
3387
+ })) : I.finalizeUpload({
3236
3388
  key: r.key,
3237
3389
  contentType: r.ct,
3238
3390
  tenantId: r.tenant,
3239
3391
  ownerId: r.sub,
3240
3392
  visibility: r.vis,
3393
+ ...de(r.vis),
3241
3394
  ...r.folder === void 0 ? {} : { folder: r.folder },
3242
3395
  ...r.tags === void 0 ? {} : { tags: r.tags },
3243
3396
  ...r.alt === void 0 ? {} : { alt: r.alt },
3244
3397
  ...r.caption === void 0 ? {} : { caption: r.caption }
3245
- }).pipe(y.flatMap((e) => F.getUrl(e.id).pipe(y.map((t) => ({
3398
+ }).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3246
3399
  id: e.id,
3247
3400
  url: t,
3248
3401
  contentType: e.contentType,
@@ -3256,11 +3409,11 @@ var Dn = () => j({
3256
3409
  ...s,
3257
3410
  execute: (e, t) => {
3258
3411
  let n = e;
3259
- return Gn(t, D).pipe(y.map((e) => {
3260
- let t = n.expiresInSec ?? de, r = ge(), i = n.chunkSize && n.chunkSize > 0 ? n.chunkSize : O;
3412
+ return $(t, O).pipe(y.map((e) => {
3413
+ let t = n.expiresInSec ?? ue, r = _e(), i = n.chunkSize && n.chunkSize > 0 ? n.chunkSize : k;
3261
3414
  return {
3262
3415
  uploadId: r,
3263
- resumableToken: St({
3416
+ resumableToken: Tt({
3264
3417
  instance: v,
3265
3418
  id: r,
3266
3419
  sub: e.id,
@@ -3272,9 +3425,9 @@ var Dn = () => j({
3272
3425
  ...n.tags === void 0 ? {} : { tags: n.tags },
3273
3426
  ...n.alt === void 0 ? {} : { alt: n.alt },
3274
3427
  ...n.caption === void 0 ? {} : { caption: n.caption },
3275
- ...E === void 0 ? {} : { max: E }
3428
+ ...D === void 0 ? {} : { max: D }
3276
3429
  }, t),
3277
- uploadUrl: `${T ? T.replace(/\/+$/, "") : ""}${b}/upload/resumable`,
3430
+ uploadUrl: `${E ? E.replace(/\/+$/, "") : ""}${b}/upload/resumable`,
3278
3431
  chunkSize: i,
3279
3432
  expiresInSec: t
3280
3433
  };
@@ -3284,14 +3437,14 @@ var Dn = () => j({
3284
3437
  {
3285
3438
  ...o,
3286
3439
  execute: (e, t) => {
3287
- let n = e, r = n.expiresInSec ?? de;
3288
- return Gn(t, D).pipe(y.flatMap((e) => F.beginMultipartUpload({
3440
+ let n = e, r = n.expiresInSec ?? ue;
3441
+ return $(t, O).pipe(y.flatMap((e) => I.beginMultipartUpload({
3289
3442
  contentType: n.contentType,
3290
3443
  tenantId: e.tenantId,
3291
3444
  visibility: n.visibility ?? "private",
3292
3445
  expiresInSec: r
3293
3446
  }).pipe(y.map((t) => ({
3294
- multipartToken: wt({
3447
+ multipartToken: Dt({
3295
3448
  instance: v,
3296
3449
  key: t.key,
3297
3450
  uploadId: t.uploadId,
@@ -3305,7 +3458,7 @@ var Dn = () => j({
3305
3458
  ...n.alt === void 0 ? {} : { alt: n.alt },
3306
3459
  ...n.caption === void 0 ? {} : { caption: n.caption }
3307
3460
  }, r),
3308
- partSize: n.partSize && n.partSize >= O ? n.partSize : O,
3461
+ partSize: n.partSize && n.partSize >= k ? n.partSize : k,
3309
3462
  expiresInSec: r
3310
3463
  })))));
3311
3464
  }
@@ -3313,7 +3466,7 @@ var Dn = () => j({
3313
3466
  {
3314
3467
  ...g,
3315
3468
  execute: (e) => {
3316
- let n = e, r = Tt(n.multipartToken);
3469
+ let n = e, r = Ot(n.multipartToken);
3317
3470
  return !r || r.instance !== v ? y.fail(new t({
3318
3471
  provider: "storage",
3319
3472
  message: "invalid or expired multipart token",
@@ -3324,7 +3477,7 @@ var Dn = () => j({
3324
3477
  message: "partNumber must be a positive integer",
3325
3478
  transient: !1,
3326
3479
  status: 400
3327
- })) : F.signMultipartPart({
3480
+ })) : I.signMultipartPart({
3328
3481
  key: r.key,
3329
3482
  uploadId: r.uploadId,
3330
3483
  partNumber: n.partNumber
@@ -3334,18 +3487,18 @@ var Dn = () => j({
3334
3487
  {
3335
3488
  ...c,
3336
3489
  execute: (e, n) => {
3337
- let r = e, i = Tt(r.multipartToken);
3490
+ let r = e, i = Ot(r.multipartToken);
3338
3491
  return !i || i.instance !== v ? y.fail(new t({
3339
3492
  provider: "storage",
3340
3493
  message: "invalid or expired multipart token",
3341
3494
  transient: !1,
3342
3495
  status: 401
3343
- })) : Kn(i.sub, n.request.subject.id) ? y.fail(new t({
3496
+ })) : Zn(i.sub, n.request.subject.id) ? y.fail(new t({
3344
3497
  provider: "storage",
3345
3498
  message: "multipart token belongs to another subject",
3346
3499
  transient: !1,
3347
3500
  status: 403
3348
- })) : F.completeMultipart({
3501
+ })) : I.completeMultipart({
3349
3502
  key: i.key,
3350
3503
  uploadId: i.uploadId,
3351
3504
  parts: r.parts,
@@ -3353,11 +3506,12 @@ var Dn = () => j({
3353
3506
  tenantId: i.tenant,
3354
3507
  ownerId: i.sub,
3355
3508
  visibility: i.vis,
3509
+ ...de(i.vis),
3356
3510
  ...i.folder === void 0 ? {} : { folder: i.folder },
3357
3511
  ...i.tags === void 0 ? {} : { tags: i.tags },
3358
3512
  ...i.alt === void 0 ? {} : { alt: i.alt },
3359
3513
  ...i.caption === void 0 ? {} : { caption: i.caption }
3360
- }).pipe(y.flatMap((e) => F.getUrl(e.id).pipe(y.map((t) => ({
3514
+ }).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3361
3515
  id: e.id,
3362
3516
  url: t,
3363
3517
  size: e.size
@@ -3367,13 +3521,13 @@ var Dn = () => j({
3367
3521
  {
3368
3522
  ...a,
3369
3523
  execute: (e) => {
3370
- let n = Tt(e.multipartToken);
3524
+ let n = Ot(e.multipartToken);
3371
3525
  return !n || n.instance !== v ? y.fail(new t({
3372
3526
  provider: "storage",
3373
3527
  message: "invalid or expired multipart token",
3374
3528
  transient: !1,
3375
3529
  status: 401
3376
- })) : F.abortMultipart({
3530
+ })) : I.abortMultipart({
3377
3531
  key: n.key,
3378
3532
  uploadId: n.uploadId
3379
3533
  }).pipe(y.as({ ok: !0 }));
@@ -3383,7 +3537,7 @@ var Dn = () => j({
3383
3537
  ...ie,
3384
3538
  execute: (e, t) => {
3385
3539
  let n = e, r = new Uint8Array(Buffer.from(n.bytesBase64, "base64"));
3386
- return Gn(t, D).pipe(y.flatMap((e) => F.put({
3540
+ return $(t, O).pipe(y.flatMap((e) => I.put({
3387
3541
  bytes: r,
3388
3542
  contentType: n.contentType,
3389
3543
  tenantId: e.tenantId,
@@ -3391,7 +3545,7 @@ var Dn = () => j({
3391
3545
  ...n.visibility ? { visibility: n.visibility } : {},
3392
3546
  ...n.key ? { key: n.key } : {},
3393
3547
  ...n.password ? { password: n.password } : {}
3394
- })), y.flatMap((e) => F.getUrl(e.id).pipe(y.map((t) => ({
3548
+ })), y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3395
3549
  id: e.id,
3396
3550
  url: t
3397
3551
  })))));
@@ -3401,7 +3555,7 @@ var Dn = () => j({
3401
3555
  ...u,
3402
3556
  execute: (e, t) => {
3403
3557
  let n = e;
3404
- return Gn(t, D).pipe(y.flatMap((e) => F.ingestUrl(n.url, {
3558
+ return $(t, O).pipe(y.flatMap((e) => I.ingestUrl(n.url, {
3405
3559
  tenantId: e.tenantId,
3406
3560
  ownerId: e.id,
3407
3561
  ...n.visibility ? { visibility: n.visibility } : {},
@@ -3410,7 +3564,7 @@ var Dn = () => j({
3410
3564
  ...n.alt === void 0 ? {} : { alt: n.alt },
3411
3565
  ...n.caption === void 0 ? {} : { caption: n.caption },
3412
3566
  ...n.key === void 0 ? {} : { key: n.key }
3413
- })), y.flatMap((e) => F.getUrl(e.id).pipe(y.map((t) => ({
3567
+ })), y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3414
3568
  id: e.id,
3415
3569
  url: t
3416
3570
  })))));
@@ -3420,7 +3574,7 @@ var Dn = () => j({
3420
3574
  ...ne,
3421
3575
  execute: (e, t) => {
3422
3576
  let n = e, r = n.expiresInDays ? new Date(Date.now() + n.expiresInDays * 864e5) : null;
3423
- return Un(F, n.refId, t).pipe(y.flatMap(() => F.grant({
3577
+ return Yn(I, n.refId, t).pipe(y.flatMap(() => I.grant({
3424
3578
  refId: n.refId,
3425
3579
  principalType: n.principalType,
3426
3580
  principalId: n.principalId,
@@ -3434,21 +3588,21 @@ var Dn = () => j({
3434
3588
  ...h,
3435
3589
  execute: (e, t) => {
3436
3590
  let n = e;
3437
- return F.getGrant(n.grantId).pipe(y.flatMap((e) => e === null ? y.fail(Hn()) : Un(F, e.refId, t)), y.flatMap(() => F.revoke(n.grantId)), y.map(() => ({ ok: !0 })));
3591
+ return I.getGrant(n.grantId).pipe(y.flatMap((e) => e === null ? y.fail(Jn()) : Yn(I, e.refId, t)), y.flatMap(() => I.revoke(n.grantId)), y.map(() => ({ ok: !0 })));
3438
3592
  }
3439
3593
  },
3440
3594
  {
3441
3595
  ...d,
3442
3596
  execute: (e, t) => {
3443
3597
  let n = e;
3444
- return Un(F, n.refId, t).pipe(y.flatMap(() => F.listGrants(n.refId)), y.map((e) => ({ grants: e.map(qn) })));
3598
+ return Yn(I, n.refId, t).pipe(y.flatMap(() => I.listGrants(n.refId)), y.map((e) => ({ grants: e.map(Qn) })));
3445
3599
  }
3446
3600
  },
3447
3601
  {
3448
3602
  ...f,
3449
3603
  execute: (e, t) => {
3450
3604
  let n = e;
3451
- return F.listRefs({
3605
+ return I.listRefs({
3452
3606
  tenantId: t.request.subject.tenantId,
3453
3607
  ...n.folder === void 0 ? {} : { folder: n.folder },
3454
3608
  ...n.tags === void 0 ? {} : { tags: n.tags },
@@ -3457,19 +3611,19 @@ var Dn = () => j({
3457
3611
  ...n.limit === void 0 ? {} : { limit: n.limit },
3458
3612
  ...n.offset === void 0 ? {} : { offset: n.offset }
3459
3613
  }).pipe(y.map((e) => ({
3460
- refs: e.refs.map(Vn),
3614
+ refs: e.refs.map(qn),
3461
3615
  nextOffset: e.nextOffset
3462
3616
  })));
3463
3617
  }
3464
3618
  }
3465
3619
  ];
3466
- return ae({
3467
- name: oe({
3468
- base: Jn,
3620
+ return T({
3621
+ name: ae({
3622
+ base: $n,
3469
3623
  alias: i.alias,
3470
3624
  instance: i.name
3471
3625
  }),
3472
- baseName: Jn,
3626
+ baseName: $n,
3473
3627
  description: "File storage — StorageService over S3 / MinIO / filesystem / memory. Public objects served direct from bucket/CDN; private objects gated by an access policy + per-object grants. Checksums, tenant key-prefixing, _voltro_storage_refs + _voltro_storage_grants, retry.",
3474
3628
  permissions: [
3475
3629
  "network:outbound:*",
@@ -3477,14 +3631,15 @@ var Dn = () => j({
3477
3631
  "inspect:write"
3478
3632
  ],
3479
3633
  declaredEnv: W.declared,
3634
+ egress: Wn(i),
3480
3635
  services: me,
3481
- inspectEndpoints: Te,
3636
+ inspectEndpoints: Ee,
3482
3637
  httpRoutes: [
3483
- xe,
3484
3638
  Se,
3485
- Ce
3639
+ Ce,
3640
+ we
3486
3641
  ],
3487
- routes: Ee,
3642
+ routes: De,
3488
3643
  rpcClientDescriptors: re,
3489
3644
  errorSchemas: [
3490
3645
  {
@@ -3518,7 +3673,7 @@ var Dn = () => j({
3518
3673
  ],
3519
3674
  capabilities: { mediaPersist: {
3520
3675
  put: async ({ bytes: e, mediaType: t, tenantId: n, operationId: r, ownerId: i, visibility: a, tags: o }) => {
3521
- let s = await y.runPromise(F.put({
3676
+ let s = await y.runPromise(I.put({
3522
3677
  bytes: e,
3523
3678
  contentType: t,
3524
3679
  tenantId: n,
@@ -3529,12 +3684,12 @@ var Dn = () => j({
3529
3684
  ...fe.current === void 0 ? {} : { operationId: r }
3530
3685
  }));
3531
3686
  return {
3532
- url: await y.runPromise(F.getUrl(s.id, { tenantId: n })),
3687
+ url: await y.runPromise(I.getUrl(s.id, { tenantId: n })),
3533
3688
  refId: s.id
3534
3689
  };
3535
3690
  },
3536
3691
  ingestUrl: async ({ url: e, tenantId: t, operationId: n, ownerId: r, visibility: i, tags: a }) => {
3537
- let o = await y.runPromise(F.ingestUrl(e, {
3692
+ let o = await y.runPromise(I.ingestUrl(e, {
3538
3693
  tenantId: t,
3539
3694
  ...r === void 0 ? {} : { ownerId: r },
3540
3695
  ...i === void 0 ? {} : { visibility: i },
@@ -3542,24 +3697,24 @@ var Dn = () => j({
3542
3697
  ...fe.current === void 0 ? {} : { operationId: n }
3543
3698
  }));
3544
3699
  return {
3545
- url: await y.runPromise(F.getUrl(o.id, { tenantId: t })),
3700
+ url: await y.runPromise(I.getUrl(o.id, { tenantId: t })),
3546
3701
  refId: o.id
3547
3702
  };
3548
3703
  }
3549
3704
  } },
3550
3705
  bindDataStore: (e) => {
3551
- k && (j.current = Wt(e)), A && (M.current = qt(e)), k && A && (fe.current = yn(e)), x.bindDataStore?.(e);
3706
+ A && (M.current = Jt(e)), j && (N.current = Zt(e)), A && j && (fe.current = wn(e)), x.bindDataStore?.(e);
3552
3707
  },
3553
3708
  onActivate: (e) => y.sync(() => {
3554
- let t = !!T || !!W.read("STORAGE_CDN_URL", i.cdnBaseUrl);
3709
+ let t = !!E || !!W.read("STORAGE_CDN_URL", i.cdnBaseUrl);
3555
3710
  e.logger.info(`storage: provider=${x.name} presign=${x.presigns ? "yes" : "no"} publicUrl=${t ? "yes" : "no"} transforms=yes`, {
3556
3711
  provider: x.name,
3557
3712
  bucket: S,
3558
- refStore: k ? "memory" : "custom"
3713
+ refStore: A ? "memory" : "custom"
3559
3714
  }), x.name === "memory" && process.env.NODE_ENV !== "test" && e.logger.warn("storage: provider=memory — uploads are IN-MEMORY and LOST on restart. Set STORAGE_PROVIDER (filesystem / s3 / r2 / azure / gcs) for anything but throwaway dev. (Empty/placeholder storage env silently falls back to memory.)"), !t && !x.presigns && e.logger.warn("storage: no VOLTRO_PUBLIC_URL / STORAGE_CDN_URL and this provider can't presign — serve URLs are RELATIVE and will not resolve cross-origin (browser <img> / server-to-server AI fetches). Set VOLTRO_PUBLIC_URL to this api's absolute base URL.");
3560
3715
  }),
3561
3716
  onDeactivate: () => y.void
3562
3717
  });
3563
3718
  };
3564
3719
  //#endregion
3565
- export { U as STORAGE_BLOBS_TABLE, H as STORAGE_GRANTS_TABLE, V as STORAGE_REFS_TABLE, Ne as STORAGE_USAGE_TABLE, e as StorageAccessDenied, t as StorageError, n as StorageRejected, r as StorageScanRejected, i as StorageService, Le as _voltroStorageBlobsTable, Fe as _voltroStorageGrantsTable, Pe as _voltroStorageRefsTable, Ie as _voltroStorageUsageTable, In as appStorageProvider, En as assetRef, qe as azureProvider, Xt as buildStorageService, De as bytesToStream, kt as checkLimits, Cn as clamavScanner, Ve as clearStorageBuffer, Oe as collectStream, Ee as concatBytes, Ln as configuredStorageProvider, Et as contentTypeAllowed, qt as dataStoreGrantStore, Wt as dataStoreRefStore, Ke as databaseProvider, kn as decodeDataUri, Mn as durabilityNotice, bn as encodeInstream, Tn as ffmpegTranscoder, Ue as filesystemProvider, ke as fromNodeReadable, je as getObjectStream, rt as hashPassword, yn as makeStorageObjectMetadata, Gt as memoryGrantStore, He as memoryProvider, Vt as memoryRefStore, xn as parseClamavResponse, Ye as parseTransformParams, jn as pathDurability, An as putAvatar, Me as putObjectStream, Be as readStorageBuffer, zt as refMatchesListQuery, Rn as resolveStorageProvider, K as resolveStorageSecret, We as s3Provider, Fn as setActiveStorageProvider, bt as signFinalizeTicket, gt as signGrant, wt as signMultipartTicket, St as signResumableTicket, vt as signUploadTicket, Ot as sniffMatches, Yn as storageInstanceName, en as storageObjectLifecycleTables, Xn as storagePlugin, gn as storagePutIntentsTable, Zt as storageServiceLayer, Ae as toNodeReadable, nt as transformCached, $e as transformImage, xt as verifyFinalizeTicket, _t as verifyGrant, Tt as verifyMultipartTicket, it as verifyPassword, Ct as verifyResumableTicket, yt as verifyUploadTicket, Dn as withStorage };
3720
+ export { U as STORAGE_BLOBS_TABLE, H as STORAGE_GRANTS_TABLE, V as STORAGE_REFS_TABLE, Pe as STORAGE_USAGE_TABLE, e as StorageAccessDenied, t as StorageError, n as StorageRejected, r as StorageScanRejected, i as StorageService, Re as _voltroStorageBlobsTable, Ie as _voltroStorageGrantsTable, Fe as _voltroStorageRefsTable, Le as _voltroStorageUsageTable, Vn as appStorageProvider, jn as assetRef, Je as azureProvider, en as buildStorageService, Oe as bytesToStream, Mt as checkLimits, On as clamavScanner, He as clearStorageBuffer, ke as collectStream, De as concatBytes, Hn as configuredStorageProvider, kt as contentTypeAllowed, Zt as dataStoreGrantStore, Jt as dataStoreRefStore, qe as databaseProvider, Pn as decodeDataUri, Ln as durabilityNotice, Tn as encodeInstream, An as ffmpegTranscoder, We as filesystemProvider, Ae as fromNodeReadable, Me as getObjectStream, ot as hashPassword, wn as makeStorageObjectMetadata, Yt as memoryGrantStore, Ue as memoryProvider, Gt as memoryRefStore, En as parseClamavResponse, Ze as parseTransformParams, In as pathDurability, Fn as putAvatar, Ne as putObjectStream, Ve as readStorageBuffer, Ut as refMatchesListQuery, Un as resolveStorageProvider, K as resolveStorageSecret, Ge as s3Provider, Bn as setActiveStorageProvider, Ct as signFinalizeTicket, yt as signGrant, Dt as signMultipartTicket, Tt as signResumableTicket, xt as signUploadTicket, jt as sniffMatches, Wn as storageEgressOf, er as storageInstanceName, on as storageObjectLifecycleTables, tr as storagePlugin, xn as storagePutIntentsTable, tn as storageServiceLayer, je as toNodeReadable, at as transformCached, tt as transformFallbackReason, nt as transformImage, wt as verifyFinalizeTicket, bt as verifyGrant, Ot as verifyMultipartTicket, st as verifyPassword, Et as verifyResumableTicket, St as verifyUploadTicket, Mn as withStorage };