@voltro/plugin-storage 0.83.1 → 0.85.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
@@ -1,88 +1,88 @@
1
1
  import { StorageAccessDenied as e, StorageError as t, StorageRejected as n, StorageScanRejected as r, StorageService as i } from "./types.js";
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
- import { processIdentity as _ } from "@voltro/protocol/identity";
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 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";
14
- import { join as z } from "node:path";
15
- import { statSync as B } from "node:fs";
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 ne, shareDescriptor as h, signMultipartPartDescriptor as g, storageRpcClientImports as _, uploadDescriptor as re } from "./rpc.js";
3
+ import { processIdentity as ie } from "@voltro/protocol/identity";
4
+ import { Effect as v, Exit as y, Layer as b, Schedule as x, Schema as S, Stream as C } from "effect";
5
+ import { StorageAccessPolicySchema as ae, definePlugin as oe, pluginInstanceName as w } from "@voltro/protocol";
6
+ import { readCookie as se, resolveSessionSecret as ce, verifySession as le } from "@voltro/protocol/session";
7
+ import { and as ue, authoredError as T, bigint as E, bytes as D, causeBranches as O, column as de, contains as fe, eq as k, extractDbCause as pe, generateId as A, id as j, integer as M, isNull as me, isTransientContention as he, json as ge, mixin as _e, neq as ve, or as N, reference as ye, table as P, text as F, timestamp as be, wireSafeCause as xe } from "@voltro/database";
8
+ import { pluginEnv as Se } from "@voltro/env";
9
+ import { createHash as Ce, createHmac as I, randomBytes as we, randomUUID as Te, scryptSync as Ee, timingSafeEqual as L } from "node:crypto";
10
+ import { ssrfReason as De } from "@voltro/runtime";
11
+ import { spawn as Oe } from "node:child_process";
12
+ import { mkdtemp as R, readFile as z, rm as ke, writeFile as Ae } from "node:fs/promises";
13
+ import { tmpdir as je } from "node:os";
14
+ import { join as Me } from "node:path";
15
+ import { statSync as Ne } from "node:fs";
16
16
  //#region src/streamBridge.ts
17
- var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
17
+ var Pe = 1 << 20, Fe = (e, n, r = !1) => new t({
18
18
  provider: e,
19
19
  message: n,
20
20
  transient: r
21
- }), De = (e) => {
21
+ }), Ie = (e) => {
22
22
  let t = 0;
23
23
  for (let n of e) t += n.byteLength;
24
24
  let n = new Uint8Array(t), r = 0;
25
25
  for (let t of e) n.set(t, r), r += t.byteLength;
26
26
  return n;
27
- }, Oe = (e, t = Te) => {
27
+ }, Le = (e, t = Pe) => {
28
28
  let n = [];
29
29
  for (let r = 0; r < e.byteLength; r += t) n.push(e.subarray(r, Math.min(r + t, e.byteLength)));
30
- return w.fromIterable(n);
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) => {
30
+ return C.fromIterable(n);
31
+ }, Re = (e) => e.pipe(C.runCollect, v.map((e) => Ie(e))), ze = (e, t) => C.suspend(() => C.fromAsyncIterable(t(), (t) => Fe(e, `read stream failed: ${String(t?.message ?? t)}`, !0))).pipe(C.map((e) => e instanceof Uint8Array ? e : new Uint8Array(e))), Be = async (e) => {
32
32
  let { Readable: t } = await import("node:stream");
33
- return t.fromWeb(w.toReadableStream(e));
34
- }, Me = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(y.map((e) => ({
35
- stream: Oe(e.bytes),
33
+ return t.fromWeb(C.toReadableStream(e));
34
+ }, Ve = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(v.map((e) => ({
35
+ stream: Le(e.bytes),
36
36
  contentType: e.contentType,
37
37
  size: e.bytes.byteLength
38
- }))), Ne = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : ke(n).pipe(y.flatMap((n) => e.put(t, n, {
38
+ }))), He = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : Re(n).pipe(v.flatMap((n) => e.put(t, n, {
39
39
  contentType: r.contentType,
40
40
  ...r.public === void 0 ? {} : { public: r.public }
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" }),
41
+ }))), B = "_voltro_storage_refs", V = "_voltro_storage_grants", H = "_voltro_storage_blobs", Ue = "_voltro_storage_usage", We = P(B, {
42
+ id: j({ prefix: "file" }),
43
43
  tenantId: F().nullable(),
44
44
  ownerId: F().nullable(),
45
45
  bucket: F(),
46
46
  key: F(),
47
47
  contentType: F(),
48
- size: A(),
48
+ size: E(),
49
49
  checksum: F(),
50
50
  visibility: F(),
51
- accessPolicy: j().nullable(),
51
+ accessPolicy: ge().nullable(),
52
52
  passwordHash: F().nullable(),
53
- width: A().nullable(),
54
- height: A().nullable(),
55
- duration: A().nullable(),
53
+ width: M().nullable(),
54
+ height: M().nullable(),
55
+ duration: M().nullable(),
56
56
  placeholder: F().nullable(),
57
57
  folder: F().nullable(),
58
- tags: j().nullable(),
58
+ tags: ge().nullable(),
59
59
  alt: F().nullable(),
60
60
  caption: F().nullable(),
61
61
  derivedFrom: F().nullable(),
62
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" }),
63
+ createdAt: be()
64
+ }).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]), Ge = P(V, {
65
+ id: j({ prefix: "sgrant" }),
66
66
  refId: F(),
67
67
  principalType: F(),
68
68
  principalId: F(),
69
69
  permission: F(),
70
- createdAt: pe(),
71
- expiresAt: pe().nullable(),
70
+ createdAt: be(),
71
+ expiresAt: be().nullable(),
72
72
  createdBy: F().nullable()
73
- }).index(["refId"]).index(["principalId"]), Le = P(Pe, {
74
- id: ue({ prefix: "susage" }),
73
+ }).index(["refId"]).index(["principalId"]), Ke = P(Ue, {
74
+ id: j({ prefix: "susage" }),
75
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" }),
76
+ bytes: E().default("0"),
77
+ count: E().default("0"),
78
+ updatedAt: be()
79
+ }).unique("byStorageUsageTenant", ["tenantId"]), qe = P(H, {
80
+ id: j({ prefix: "blob" }),
81
81
  key: F(),
82
- data: le(),
82
+ data: D(),
83
83
  contentType: F(),
84
- size: A()
85
- }).index(["key"]), W = me([
84
+ size: E()
85
+ }).index(["key"]), U = Se([
86
86
  {
87
87
  name: "STORAGE_PROVIDER",
88
88
  required: !1,
@@ -233,47 +233,67 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
233
233
  secret: !1,
234
234
  description: "clamd port for the optional clamav virus scanner. Default 3310."
235
235
  }
236
- ]), G = (e, n, r, i) => new t({
236
+ ]), W = (e, n) => {
237
+ let r = typeof e == "number" ? e : typeof e == "bigint" || typeof e == "string" && /^\d+$/.test(e) ? Number(e) : NaN;
238
+ if (!Number.isSafeInteger(r) || r < 0) throw new t({
239
+ provider: "metadata",
240
+ message: `Storage ${n} must be a non-negative safe integer at most Number.MAX_SAFE_INTEGER`,
241
+ transient: !1
242
+ });
243
+ return r;
244
+ }, Je = (e, t, n) => W(e + t, n), G = (e, n, r = !1) => {
245
+ let i = O(e).find(S.is(t));
246
+ if (i !== void 0) return i;
247
+ let a = pe(e), o = a.dbCode === "22003" || a.dbSqlState === "22003" || a.dbCode === "ER_WARN_DATA_OUT_OF_RANGE" || a.dbErrno === 1264 || a.dbNumber === 8115 || a.dbNumber === 248, s = new t({
248
+ provider: n,
249
+ message: `${o ? "Storage metadata numeric value out of range: " : ""}${xe(e)}`,
250
+ transient: o ? !1 : he(e) || r
251
+ });
252
+ return Object.defineProperty(s, "cause", {
253
+ value: e,
254
+ configurable: !0
255
+ }), s;
256
+ }, Ye = (e) => O(e).find(S.is(n)), K = (e, n, r, i) => new t({
237
257
  provider: e,
238
258
  message: n,
239
259
  transient: r,
240
260
  ...i === void 0 ? {} : { status: i }
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), {
261
+ }), Xe = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, Ze = /* @__PURE__ */ new Map(), Qe = (e, t) => Ze.get(e)?.get(t)?.bytes, $e = (e) => {
262
+ Ze.get(e)?.clear();
263
+ }, et = (e = "default") => {
264
+ let t = Ze.get(e) ?? /* @__PURE__ */ new Map();
265
+ return Ze.set(e, t), {
246
266
  name: "memory",
247
267
  presigns: !1,
248
- put: (e, n, r) => y.sync(() => (t.set(e, {
268
+ put: (e, n, r) => v.sync(() => (t.set(e, {
249
269
  bytes: n,
250
270
  contentType: r.contentType
251
271
  }), { size: n.byteLength })),
252
- get: (e) => y.suspend(() => {
272
+ get: (e) => v.suspend(() => {
253
273
  let n = t.get(e);
254
- return n ? y.succeed({
274
+ return n ? v.succeed({
255
275
  bytes: n.bytes,
256
276
  contentType: n.contentType
257
- }) : y.fail(G("memory", `no object at key '${e}'`, !1, 404));
277
+ }) : v.fail(K("memory", `no object at key '${e}'`, !1, 404));
258
278
  }),
259
- delete: (e) => y.sync(() => {
279
+ delete: (e) => v.sync(() => {
260
280
  t.delete(e);
261
281
  }),
262
282
  publicUrl: () => null,
263
- getUrl: () => y.succeed(""),
264
- head: (e) => y.sync(() => {
283
+ getUrl: () => v.succeed(""),
284
+ head: (e) => v.sync(() => {
265
285
  let n = t.get(e);
266
286
  return n ? { size: n.bytes.byteLength } : null;
267
287
  })
268
288
  };
269
- }, We = (e) => {
289
+ }, tt = (e) => {
270
290
  let t = e.root, n = async (e) => {
271
291
  let { join: n, resolve: r, sep: i } = await import("node:path"), a = r(t), o = r(a, e);
272
292
  if (o !== a && !o.startsWith(a + i)) throw Error(`key '${e}' escapes the storage root`);
273
293
  return n(o);
274
- }, r = (e, t, n = !1) => y.tryPromise({
294
+ }, r = (e, t, n = !1) => v.tryPromise({
275
295
  try: e,
276
- catch: (e) => e?.code === "ENOENT" ? G("filesystem", `no object at key '${t}'`, !1, 404) : G("filesystem", String(e?.message ?? e), n)
296
+ catch: (e) => e?.code === "ENOENT" ? K("filesystem", `no object at key '${t}'`, !1, 404) : K("filesystem", String(e?.message ?? e), n)
277
297
  });
278
298
  return {
279
299
  root: t,
@@ -301,8 +321,8 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
301
321
  await (await import("node:fs/promises")).rm(await n(e), { force: !0 });
302
322
  }, e),
303
323
  publicUrl: () => null,
304
- getUrl: () => y.succeed(""),
305
- head: (e) => y.tryPromise({
324
+ getUrl: () => v.succeed(""),
325
+ head: (e) => v.tryPromise({
306
326
  try: async () => {
307
327
  let t = await import("node:fs/promises");
308
328
  try {
@@ -312,12 +332,12 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
312
332
  throw e;
313
333
  }
314
334
  },
315
- catch: (e) => G("filesystem", String(e?.message ?? e), !1)
335
+ catch: (e) => K("filesystem", String(e?.message ?? e), !1)
316
336
  }),
317
337
  getStream: (e) => r(async () => {
318
338
  let t = await import("node:fs/promises"), { createReadStream: r } = await import("node:fs"), i = await n(e), a = await t.stat(i);
319
339
  return {
320
- stream: Ae("filesystem", () => r(i)),
340
+ stream: ze("filesystem", () => r(i)),
321
341
  contentType: "application/octet-stream",
322
342
  size: a.size
323
343
  };
@@ -327,7 +347,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
327
347
  await r.mkdir(i(c), { recursive: !0 });
328
348
  let l = `${c}.tmp-${a()}`;
329
349
  try {
330
- await s(await je(t), o(l));
350
+ await s(await Be(t), o(l));
331
351
  let e = await r.stat(l);
332
352
  return await r.rename(l, c), { size: e.size };
333
353
  } catch (e) {
@@ -342,10 +362,10 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
342
362
  end: i
343
363
  });
344
364
  s.on("data", (e) => o.push(e)), s.on("end", () => e()), s.on("error", n);
345
- }), De(o);
365
+ }), Ie(o);
346
366
  }, e)
347
367
  };
348
- }, Ge = (e) => {
368
+ }, nt = (e) => {
349
369
  let t = e.name ?? "s3", n = e.publicAcl ?? !0, r = null, i = () => r || (r = (async () => {
350
370
  let t, n;
351
371
  try {
@@ -366,11 +386,11 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
366
386
  cmds: t,
367
387
  presign: n.getSignedUrl
368
388
  };
369
- })(), r), a = (e) => y.tryPromise({
389
+ })(), r), a = (e) => v.tryPromise({
370
390
  try: e,
371
391
  catch: (e) => {
372
392
  let n = e?.$metadata?.httpStatusCode;
373
- return G(t, String(e?.message ?? e), ze(n), n);
393
+ return K(t, String(e?.message ?? e), Xe(n), n);
374
394
  }
375
395
  }), o = async (e) => {
376
396
  let t = e;
@@ -474,7 +494,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
474
494
  UploadId: n
475
495
  }));
476
496
  }),
477
- head: (n) => y.tryPromise({
497
+ head: (n) => v.tryPromise({
478
498
  try: async () => {
479
499
  let { client: t, cmds: r } = await i();
480
500
  try {
@@ -493,7 +513,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
493
513
  },
494
514
  catch: (e) => {
495
515
  let n = e?.$metadata?.httpStatusCode;
496
- return G(t, String(e?.message ?? e), ze(n), n);
516
+ return K(t, String(e?.message ?? e), Xe(n), n);
497
517
  }
498
518
  }),
499
519
  getStream: (n) => a(async () => {
@@ -502,7 +522,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
502
522
  Key: n
503
523
  })), s = o.Body;
504
524
  return {
505
- stream: Ae(t, () => s),
525
+ stream: ze(t, () => s),
506
526
  contentType: o.ContentType ?? "application/octet-stream",
507
527
  ...o.ContentLength === void 0 ? {} : { size: o.ContentLength }
508
528
  };
@@ -514,7 +534,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
514
534
  } catch (e) {
515
535
  throw Error("s3/minio `putStream` requires the '@aws-sdk/lib-storage' optional dependency (multipart upload). Install it to enable streamed uploads.", { cause: e });
516
536
  }
517
- let l = await je(r);
537
+ let l = await Be(r);
518
538
  return await new c.Upload({
519
539
  client: a,
520
540
  params: {
@@ -538,15 +558,15 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
538
558
  return o(c.Body);
539
559
  })
540
560
  };
541
- }, Ke = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), qe = () => {
561
+ }, rt = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), it = () => {
542
562
  let e = null, t = () => {
543
- if (!e) throw Error("the 'database' storage provider isn't bound to a DataStore yet");
563
+ if (!e) throw T("the 'database' storage provider isn't bound to a DataStore yet");
544
564
  return e;
545
- }, n = (e) => y.tryPromise({
565
+ }, n = (e) => v.tryPromise({
546
566
  try: e,
547
- catch: (e) => G("database", String(e?.message ?? e), !0)
567
+ catch: (e) => G(e, "database", !0)
548
568
  }), r = async (e, n) => (await t().query({
549
- table: U,
569
+ table: H,
550
570
  predicate: {
551
571
  column: "key",
552
572
  op: "eq",
@@ -565,37 +585,37 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
565
585
  },
566
586
  put: (e, i, a) => n(async () => {
567
587
  let n = await r(e);
568
- return n ? await t().update(U, String(n.id), {
588
+ return n ? await t().update(H, String(n.id), {
569
589
  data: i,
570
590
  contentType: a.contentType,
571
- size: i.byteLength
572
- }) : await t().insert(U, {
573
- id: k({
591
+ size: String(i.byteLength)
592
+ }) : await t().insert(H, {
593
+ id: A({
574
594
  kind: "typeid",
575
595
  prefix: "blob"
576
- }, U),
596
+ }, H),
577
597
  key: e,
578
598
  data: i,
579
599
  contentType: a.contentType,
580
- size: i.byteLength
600
+ size: String(i.byteLength)
581
601
  }), { size: i.byteLength };
582
602
  }),
583
- get: (e) => y.suspend(() => n(() => r(e)).pipe(y.flatMap((t) => t ? y.succeed({
584
- bytes: Ke(t.data),
603
+ get: (e) => v.suspend(() => n(() => r(e)).pipe(v.flatMap((t) => t ? v.succeed({
604
+ bytes: rt(t.data),
585
605
  contentType: String(t.contentType)
586
- }) : y.fail(G("database", `no object at key '${e}'`, !1, 404))))),
606
+ }) : v.fail(K("database", `no object at key '${e}'`, !1, 404))))),
587
607
  delete: (e) => n(async () => {
588
608
  let n = await r(e, ["id"]);
589
- n && await t().delete(U, String(n.id));
609
+ n && await t().delete(H, String(n.id));
590
610
  }),
591
611
  publicUrl: () => null,
592
- getUrl: () => y.succeed(""),
612
+ getUrl: () => v.succeed(""),
593
613
  head: (e) => n(async () => {
594
614
  let t = await r(e, ["size"]);
595
- return t ? { size: Number(t.size) } : null;
615
+ return t ? { size: W(t.size, "blob size") } : null;
596
616
  })
597
617
  };
598
- }, Je = (e) => {
618
+ }, at = (e) => {
599
619
  let t = null, n = () => t || (t = (async () => {
600
620
  let t;
601
621
  try {
@@ -603,17 +623,17 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
603
623
  } catch (e) {
604
624
  throw Error("the 'azure' storage provider requires the '@azure/storage-blob' optional dependency. Install it to enable it.", { cause: e });
605
625
  }
606
- let n = W.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = W.read("AZURE_STORAGE_KEY", e.accountKey), i = n && r ? new t.StorageSharedKeyCredential(n, r) : null, a = W.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString);
626
+ let n = U.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = U.read("AZURE_STORAGE_KEY", e.accountKey), i = n && r ? new t.StorageSharedKeyCredential(n, r) : null, a = U.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString);
607
627
  return {
608
628
  container: (a ? t.BlobServiceClient.fromConnectionString(a) : new t.BlobServiceClient(e.endpoint ?? `https://${n}.blob.core.windows.net`, i ?? void 0)).getContainerClient(e.container),
609
629
  sdk: t,
610
630
  cred: i
611
631
  };
612
- })(), t), r = (e) => y.tryPromise({
632
+ })(), t), r = (e) => v.tryPromise({
613
633
  try: e,
614
634
  catch: (e) => {
615
635
  let t = e?.statusCode;
616
- return G("azure", String(e?.message ?? e), ze(t), t);
636
+ return K("azure", String(e?.message ?? e), Xe(t), t);
617
637
  }
618
638
  }), i = async (e) => {
619
639
  if (!e) return /* @__PURE__ */ new Uint8Array();
@@ -655,7 +675,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
655
675
  publicUrl: (t) => e.cdnBaseUrl ? `${e.cdnBaseUrl.replace(/\/$/, "")}/${t}` : null,
656
676
  getUrl: (e, t) => r(() => a(e, "r", t)),
657
677
  getUploadUrl: (e, t, n) => r(() => a(e, "cw", t)),
658
- head: (e) => y.tryPromise({
678
+ head: (e) => v.tryPromise({
659
679
  try: async () => {
660
680
  let { container: t } = await n();
661
681
  try {
@@ -671,19 +691,19 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
671
691
  },
672
692
  catch: (e) => {
673
693
  let t = e?.statusCode;
674
- return G("azure", String(e?.message ?? e), ze(t), t);
694
+ return K("azure", String(e?.message ?? e), Xe(t), t);
675
695
  }
676
696
  }),
677
697
  getStream: (e) => r(async () => {
678
698
  let { container: t } = await n(), r = await t.getBlockBlobClient(e).download();
679
699
  return {
680
- stream: Ae("azure", () => r.readableStreamBody),
700
+ stream: ze("azure", () => r.readableStreamBody),
681
701
  contentType: r.contentType ?? "application/octet-stream",
682
702
  ...r.contentLength === void 0 ? {} : { size: r.contentLength }
683
703
  };
684
704
  }),
685
705
  putStream: (e, t, i) => r(async () => {
686
- let { container: r } = await n(), a = await je(t);
706
+ let { container: r } = await n(), a = await Be(t);
687
707
  return await r.getBlockBlobClient(e).uploadStream(a, 4194304, 5, { blobHTTPHeaders: { blobContentType: i.contentType } }), { size: i.totalSize ?? (await r.getBlockBlobClient(e).getProperties()).contentLength ?? 0 };
688
708
  }),
689
709
  getRange: (e, t, a) => r(async () => {
@@ -691,7 +711,34 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
691
711
  return i(o.readableStreamBody);
692
712
  })
693
713
  };
694
- }, Ye = (e, t, n, r, i, a) => {
714
+ }, ot = (e = {
715
+ entries: 200,
716
+ bytes: 67108864,
717
+ pending: 32
718
+ }) => {
719
+ let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = 0;
720
+ return { getOrCreate: (i, a) => {
721
+ let o = t.get(i);
722
+ if (o) return Promise.resolve(o);
723
+ let s = n.get(i);
724
+ if (s) return s;
725
+ if (n.size >= e.pending) return Promise.resolve(null);
726
+ let c = Promise.resolve().then(a).then((n) => {
727
+ if (n && e.entries > 0 && n.bytes.byteLength <= e.bytes) {
728
+ for (; t.size >= e.entries || r + n.bytes.byteLength > e.bytes;) {
729
+ let e = t.keys().next().value;
730
+ if (e === void 0) break;
731
+ r -= t.get(e).bytes.byteLength, t.delete(e);
732
+ }
733
+ t.set(i, n), r += n.bytes.byteLength;
734
+ }
735
+ return n;
736
+ }).finally(() => {
737
+ n.delete(i);
738
+ });
739
+ return n.set(i, c), c;
740
+ } };
741
+ }, st = (e, t, n, r, i, a) => {
695
742
  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
743
  return {
697
744
  left: l(Math.round(i * e - s / 2), e - s),
@@ -699,13 +746,13 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
699
746
  width: s,
700
747
  height: c
701
748
  };
702
- }, Xe = {
749
+ }, ct = {
703
750
  webp: "image/webp",
704
751
  avif: "image/avif",
705
752
  jpeg: "image/jpeg",
706
753
  jpg: "image/jpeg",
707
754
  png: "image/png"
708
- }, Ze = (e) => {
755
+ }, lt = (e) => {
709
756
  if (!e) return null;
710
757
  let t = new URLSearchParams(e), n = (e) => {
711
758
  let n = t.get(e);
@@ -724,24 +771,15 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
724
771
  ...s ? { fit: s } : {},
725
772
  ...l ? { fp: l } : {}
726
773
  };
727
- }, Qe = (e) => e.startsWith("image/") && !e.includes("svg"), $e, et = async () => {
728
- if ($e !== void 0) return $e;
729
- try {
730
- let e = await import("sharp");
731
- $e = e.default ?? e;
732
- } catch {
733
- $e = null;
734
- }
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();
774
+ }, ut = (e) => e.startsWith("image/") && !e.includes("svg"), dt, ft = async () => (dt ??= import("sharp").then((e) => e.default ?? e, () => null), dt), pt = async (e, t) => t ? null : ut(e) ? await ft() === null ? "no-sharp" : "failed" : "not-an-image", mt = async (e, t, n) => {
775
+ if (!ut(t)) return null;
776
+ let r = await ft();
739
777
  if (!r) return null;
740
778
  try {
741
779
  let i = r(Buffer.from(e), { failOn: "none" }), a = n.fit ?? "cover";
742
780
  if (n.fp !== void 0 && n.w !== void 0 && n.h !== void 0 && a === "cover") {
743
781
  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)));
782
+ e.width !== void 0 && e.height !== void 0 && (i = i.extract(st(e.width, e.height, n.w, n.h, n.fp.x, n.fp.y)));
745
783
  }
746
784
  (n.w !== void 0 || n.h !== void 0) && (i = i.resize({
747
785
  ...n.w === void 0 ? {} : { width: n.w },
@@ -749,10 +787,10 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
749
787
  fit: n.fit ?? "cover",
750
788
  withoutEnlargement: !0
751
789
  }));
752
- let o = n.format && Xe[n.format] ? n.format : void 0, s = t;
790
+ let o = n.format && ct[n.format] ? n.format : void 0, s = t;
753
791
  if (o) {
754
792
  let e = o === "jpg" ? "jpeg" : o;
755
- i = i.toFormat(e, n.q === void 0 ? {} : { quality: n.q }), s = Xe[o];
793
+ i = i.toFormat(e, n.q === void 0 ? {} : { quality: n.q }), s = ct[o];
756
794
  } else n.q !== void 0 && (t === "image/jpeg" || t === "image/webp") && (i = i.toFormat(t === "image/webp" ? "webp" : "jpeg", { quality: n.q }));
757
795
  let c = await i.toBuffer();
758
796
  return {
@@ -762,43 +800,57 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
762
800
  } catch {
763
801
  return null;
764
802
  }
765
- }, rt = 200, it = /* @__PURE__ */ new Map(), at = async (e, t, n, r) => {
766
- let i = `${e}::${JSON.stringify(r)}`, a = it.get(i);
767
- if (a) return a;
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);
803
+ }, ht = async (e, t, n) => {
804
+ if (!ut(t) || n.rotate === void 0 && n.flip !== !0 && n.flop !== !0 && n.grayscale !== !0 && n.crop === void 0) return null;
805
+ let r = await ft();
806
+ if (!r) return null;
807
+ try {
808
+ let i = r(Buffer.from(e), { failOn: "none" });
809
+ return n.crop !== void 0 && (i = i.extract(n.crop)), n.rotate !== void 0 && (i = i.rotate(n.rotate)), n.flip === !0 && (i = i.flip()), n.flop === !0 && (i = i.flop()), n.grayscale === !0 && (i = i.grayscale()), {
810
+ bytes: new Uint8Array(await i.toBuffer()),
811
+ contentType: t
812
+ };
813
+ } catch {
814
+ return null;
772
815
  }
773
- return o;
774
- }, ot = (e) => {
775
- let t = ge(16).toString("hex");
776
- return `${t}:${L(e, t, 32).toString("hex")}`;
777
- }, st = (e, t) => {
816
+ }, gt = ot(), _t = (e, t, n) => JSON.stringify([
817
+ e,
818
+ t,
819
+ n.w,
820
+ n.h,
821
+ n.format,
822
+ n.q,
823
+ n.fit,
824
+ n.fp?.x,
825
+ n.fp?.y
826
+ ]), vt = async (e, t, n, r) => gt.getOrCreate(_t(e, n, r), () => mt(t, n, r)), yt = (e) => {
827
+ let t = we(16).toString("hex");
828
+ return `${t}:${Ee(e, t, 32).toString("hex")}`;
829
+ }, bt = (e, t) => {
778
830
  if (!e || !t) return !1;
779
831
  let [n, r] = t.split(":");
780
832
  if (!n || !r) return !1;
781
- let i = Buffer.from(r, "hex"), a = L(e, n, i.length);
782
- return a.length === i.length && R(a, i);
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* () {
833
+ let i = Buffer.from(r, "hex"), a = Ee(e, n, i.length);
834
+ return a.length === i.length && L(a, i);
835
+ }, xt = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], St = (e) => xt(e.metadata?.roles), Ct = (e) => xt(e.scopes), wt = (e, t) => e.some((e) => t.includes(e)), Tt = (e) => xt(e.metadata?.groups), Et = (e) => typeof e == "boolean" ? v.succeed(e) : v.isEffect(e) ? e : v.promise(() => e), Dt = (e, t, n = {}) => v.gen(function* () {
784
836
  if (t.id && e.ownerId && t.id === e.ownerId) return !0;
785
837
  let r = e.accessPolicy ?? [];
786
838
  if (r.length === 0) return !1;
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;
839
+ let i = n.resolveGroups ? yield* v.promise(async () => await n.resolveGroups(t)) : Tt(t);
840
+ for (let a of r) if (yield* Ot(a, e, t, i, n)) return !0;
789
841
  return !1;
790
- }), ht = (e, t, n, r, i) => y.gen(function* () {
842
+ }), Ot = (e, t, n, r, i) => v.gen(function* () {
791
843
  let a = !1, o = (e) => (a = !0, e);
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;
844
+ 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(wt(St(n), e.roles)) || e.groups && e.groups.length > 0 && !o(wt(r, e.groups)) || e.scopes && e.scopes.length > 0 && !o(wt(Ct(n), e.scopes)) || e.password !== void 0 && e.password && !o(bt(i.password, t.passwordHash))) return !1;
793
845
  if (e.guard) {
794
846
  let r = i.guards?.[e.guard];
795
- if (!o(r ? yield* pt(r({
847
+ if (!o(r ? yield* Et(r({
796
848
  subject: n,
797
849
  ref: t
798
850
  })) : !1)) return !1;
799
851
  }
800
852
  return a;
801
- }), gt = (e, t) => {
853
+ }), kt = (e, t) => {
802
854
  let n = [];
803
855
  e.id && n.push({
804
856
  type: e.type === "apiKey" ? "apiKey" : "user",
@@ -809,116 +861,120 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
809
861
  id: e
810
862
  });
811
863
  return n;
812
- }, _t = (e, t, n, r, i) => {
813
- let a = gt(t, n);
864
+ }, At = (e, t, n, r, i) => {
865
+ let a = kt(t, n);
814
866
  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));
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) => {
867
+ }, jt = (e, t) => t.resolveGroups ? v.promise(async () => await t.resolveGroups(e)) : v.succeed(Tt(e)), q = () => U.read("VOLTRO_STORAGE_SECRET") ?? ce(), J = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), Y = (e) => {
816
868
  let t = e.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - e.length % 4) % 4);
817
869
  return Buffer.from(t, "base64");
818
- }, yt = (e, t, n = K(), r = "/_voltro/storage") => {
870
+ }, Mt = (e, t, n = q(), r = "/_voltro/storage") => {
819
871
  if (!n) throw Error("signGrant: secret must be a non-empty string");
820
872
  let i = {
821
873
  refId: e,
822
874
  audience: r,
823
875
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
824
- }, a = q(JSON.stringify(i));
825
- return `${a}.${q(I("sha256", n).update(a).digest())}`;
826
- }, bt = (e, t = K()) => {
876
+ }, a = J(JSON.stringify(i));
877
+ return `${a}.${J(I("sha256", n).update(a).digest())}`;
878
+ }, Nt = (e, t = q()) => {
827
879
  if (!e || !t) return null;
828
880
  let n = e.indexOf(".");
829
881
  if (n <= 0 || n === e.length - 1) return null;
830
- let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(r).digest(), o = J(i);
831
- if (o.length !== a.length || !R(o, a)) return null;
882
+ let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(r).digest(), o = Y(i);
883
+ if (o.length !== a.length || !L(o, a)) return null;
832
884
  try {
833
- let e = JSON.parse(J(r).toString("utf8"));
885
+ let e = JSON.parse(Y(r).toString("utf8"));
834
886
  return typeof e.audience != "string" || !e.audience || typeof e.refId != "string" || typeof e.exp != "number" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
835
887
  } catch {
836
888
  return null;
837
889
  }
838
- }, xt = (e, t, n = K()) => {
890
+ }, Pt = (e) => e.version === 1 ? e.access === void 0 || e.vis === "private" && y.isSuccess(S.decodeUnknownExit(ae, { onExcessProperty: "error" })(e.access)) : !1, Ft = (e, t, n = q()) => {
839
891
  if (!n) throw Error("signUploadTicket: secret must be a non-empty string");
840
892
  let r = {
841
893
  ...e,
894
+ version: 1,
842
895
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
843
- }, i = q(JSON.stringify(r));
844
- return `${i}.${q(I("sha256", n).update(`u:${i}`).digest())}`;
845
- }, St = (e, t = K()) => {
896
+ }, i = J(JSON.stringify(r));
897
+ return `${i}.${J(I("sha256", n).update(`u:${i}`).digest())}`;
898
+ }, It = (e, t = q()) => {
846
899
  if (!e || !t) return null;
847
900
  let n = e.indexOf(".");
848
901
  if (n <= 0 || n === e.length - 1) return null;
849
- let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`u:${r}`).digest(), o = J(i);
850
- if (o.length !== a.length || !R(o, a)) return null;
902
+ let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`u:${r}`).digest(), o = Y(i);
903
+ if (o.length !== a.length || !L(o, a)) return null;
851
904
  try {
852
- let e = JSON.parse(J(r).toString("utf8"));
853
- return e.operationId !== void 0 && (typeof e.operationId != "string" || !e.operationId.trim() || e.operationId.length > 200) || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.replicaId !== void 0 && (typeof e.replicaId != "string" || !e.replicaId.trim()) || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
905
+ let e = JSON.parse(Y(r).toString("utf8"));
906
+ return !Pt(e) || e.operationId !== void 0 && (typeof e.operationId != "string" || !e.operationId.trim() || e.operationId.length > 200) || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.replicaId !== void 0 && (typeof e.replicaId != "string" || !e.replicaId.trim()) || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
854
907
  } catch {
855
908
  return null;
856
909
  }
857
- }, Ct = (e, t, n = K()) => {
910
+ }, Lt = (e, t, n = q()) => {
858
911
  if (!n) throw Error("signFinalizeTicket: secret must be a non-empty string");
859
912
  let r = {
860
913
  ...e,
914
+ version: 1,
861
915
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
862
- }, i = q(JSON.stringify(r));
863
- return `${i}.${q(I("sha256", n).update(`f:${i}`).digest())}`;
864
- }, wt = (e, t = K()) => {
916
+ }, i = J(JSON.stringify(r));
917
+ return `${i}.${J(I("sha256", n).update(`f:${i}`).digest())}`;
918
+ }, Rt = (e, t = q()) => {
865
919
  if (!e || !t) return null;
866
920
  let n = e.indexOf(".");
867
921
  if (n <= 0 || n === e.length - 1) return null;
868
- let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`f:${r}`).digest(), o = J(i);
869
- if (o.length !== a.length || !R(o, a)) return null;
922
+ let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`f:${r}`).digest(), o = Y(i);
923
+ if (o.length !== a.length || !L(o, a)) return null;
870
924
  try {
871
- let e = JSON.parse(J(r).toString("utf8"));
872
- return typeof e.key != "string" || e.key.length === 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
925
+ let e = JSON.parse(Y(r).toString("utf8"));
926
+ return !Pt(e) || typeof e.key != "string" || e.key.length === 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
873
927
  } catch {
874
928
  return null;
875
929
  }
876
- }, Tt = (e, t, n = K()) => {
930
+ }, zt = (e, t, n = q()) => {
877
931
  if (!n) throw Error("signResumableTicket: secret must be a non-empty string");
878
932
  let r = {
879
933
  ...e,
934
+ version: 1,
880
935
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
881
- }, i = q(JSON.stringify(r));
882
- return `${i}.${q(I("sha256", n).update(`r:${i}`).digest())}`;
883
- }, Et = (e, t = K()) => {
936
+ }, i = J(JSON.stringify(r));
937
+ return `${i}.${J(I("sha256", n).update(`r:${i}`).digest())}`;
938
+ }, Bt = (e, t = q()) => {
884
939
  if (!e || !t) return null;
885
940
  let n = e.indexOf(".");
886
941
  if (n <= 0 || n === e.length - 1) return null;
887
- let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`r:${r}`).digest(), o = J(i);
888
- if (o.length !== a.length || !R(o, a)) return null;
942
+ let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`r:${r}`).digest(), o = Y(i);
943
+ if (o.length !== a.length || !L(o, a)) return null;
889
944
  try {
890
- let e = JSON.parse(J(r).toString("utf8"));
891
- return typeof e.id != "string" || e.id.length === 0 || typeof e.size != "number" || e.size < 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
945
+ let e = JSON.parse(Y(r).toString("utf8"));
946
+ return !Pt(e) || typeof e.id != "string" || e.id.length === 0 || typeof e.size != "number" || e.size < 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
892
947
  } catch {
893
948
  return null;
894
949
  }
895
- }, Dt = (e, t, n = K()) => {
950
+ }, Vt = (e, t, n = q()) => {
896
951
  if (!n) throw Error("signMultipartTicket: secret must be a non-empty string");
897
952
  let r = {
898
953
  ...e,
954
+ version: 1,
899
955
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
900
- }, i = q(JSON.stringify(r));
901
- return `${i}.${q(I("sha256", n).update(`m:${i}`).digest())}`;
902
- }, Ot = (e, t = K()) => {
956
+ }, i = J(JSON.stringify(r));
957
+ return `${i}.${J(I("sha256", n).update(`m:${i}`).digest())}`;
958
+ }, Ht = (e, t = q()) => {
903
959
  if (!e || !t) return null;
904
960
  let n = e.indexOf(".");
905
961
  if (n <= 0 || n === e.length - 1) return null;
906
- let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`m:${r}`).digest(), o = J(i);
907
- if (o.length !== a.length || !R(o, a)) return null;
962
+ let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`m:${r}`).digest(), o = Y(i);
963
+ if (o.length !== a.length || !L(o, a)) return null;
908
964
  try {
909
- let e = JSON.parse(J(r).toString("utf8"));
910
- return typeof e.key != "string" || e.key.length === 0 || typeof e.uploadId != "string" || e.uploadId.length === 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
965
+ let e = JSON.parse(Y(r).toString("utf8"));
966
+ return !Pt(e) || typeof e.key != "string" || e.key.length === 0 || typeof e.uploadId != "string" || e.uploadId.length === 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
911
967
  } catch {
912
968
  return null;
913
969
  }
914
- }, kt = (e, t) => {
970
+ }, Ut = (e, t) => {
915
971
  if (!t || t.length === 0) return !0;
916
972
  let n = e.toLowerCase();
917
973
  return t.some((e) => {
918
974
  let t = e.toLowerCase();
919
975
  return t.endsWith("/*") ? n.startsWith(t.slice(0, -1)) : n === t;
920
976
  });
921
- }, At = [
977
+ }, Wt = [
922
978
  {
923
979
  ct: /^image\/png$/,
924
980
  offset: 0,
@@ -988,21 +1044,21 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
988
1044
  offset: 0,
989
1045
  magic: [31, 139]
990
1046
  }
991
- ], jt = (e, t) => {
992
- let n = t.toLowerCase(), r = At.find((e) => e.ct.test(n));
1047
+ ], Gt = (e, t) => {
1048
+ let n = t.toLowerCase(), r = Wt.find((e) => e.ct.test(n));
993
1049
  return r ? e.length < r.offset + r.magic.length ? !1 : r.magic.every((t, n) => e[r.offset + n] === t) : !0;
994
- }, Mt = (e, t, n) => n ? n.maxBytes !== void 0 && e.byteLength > n.maxBytes ? {
1050
+ }, Kt = (e, t, n) => n ? n.maxBytes !== void 0 && e.byteLength > n.maxBytes ? {
995
1051
  reason: "too-large",
996
1052
  detail: `${e.byteLength} bytes exceeds the ${n.maxBytes}-byte limit`
997
- } : kt(t, n.allowedContentTypes) ? n.sniff && !jt(e, t) ? {
1053
+ } : Ut(t, n.allowedContentTypes) ? n.sniff && !Gt(e, t) ? {
998
1054
  reason: "content-mismatch",
999
1055
  detail: `bytes do not match the declared content type '${t}'`
1000
1056
  } : null : {
1001
1057
  reason: "content-type-not-allowed",
1002
1058
  detail: `content type '${t}' is not in the allow-list`
1003
- } : null, Nt = async (e, t, n) => {
1004
- if (!Qe(t)) return { bytes: e };
1005
- let r = await et();
1059
+ } : null, qt = async (e, t, n) => {
1060
+ if (!ut(t)) return { bytes: e };
1061
+ let r = await ft();
1006
1062
  if (!r) return { bytes: e };
1007
1063
  try {
1008
1064
  let t = e;
@@ -1025,31 +1081,31 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1025
1081
  } catch {
1026
1082
  return { bytes: e };
1027
1083
  }
1028
- }, Pt = 67108864, Ft = (e) => new n({
1084
+ }, Jt = 67108864, Yt = (e) => new n({
1029
1085
  reason: "too-large",
1030
1086
  detail: `remote body exceeds the ${e}-byte ingest limit`
1031
- }), It = (e, t) => new n({
1087
+ }), Xt = (e, t) => new n({
1032
1088
  reason: "blocked-source",
1033
1089
  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({
1090
+ }), Zt = (e, r, i = {}) => v.suspend(() => {
1091
+ let a = r ?? Jt;
1092
+ return !Number.isSafeInteger(a) || a < 0 ? v.fail(new t({
1037
1093
  provider: "ingest",
1038
1094
  message: "limits.maxBytes must be a non-negative safe integer",
1039
1095
  transient: !1
1040
- })) : y.tryPromise({
1096
+ })) : v.tryPromise({
1041
1097
  try: async (n) => {
1042
1098
  let r = e, o;
1043
1099
  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);
1100
+ let t = De(r, { ...i.allowHosts === void 0 ? {} : { allowHosts: i.allowHosts } });
1101
+ if (t !== null) throw Xt(r, t);
1046
1102
  o = await fetch(r, {
1047
1103
  signal: n,
1048
1104
  redirect: "manual"
1049
1105
  });
1050
1106
  let a = o.headers.get("location");
1051
1107
  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");
1108
+ if (await o.body?.cancel().catch(() => {}), e >= (i.maxRedirects ?? 5)) throw Xt(r, "too many redirects");
1053
1109
  r = new URL(a, r).toString();
1054
1110
  }
1055
1111
  let s;
@@ -1061,12 +1117,12 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1061
1117
  status: o.status
1062
1118
  });
1063
1119
  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);
1120
+ if ((!n || n === "identity") && e !== null && /^\d+$/.test(e) && BigInt(e) > BigInt(a)) throw Yt(a);
1065
1121
  let r = /* @__PURE__ */ new Uint8Array(), i = 0;
1066
1122
  if (o.body !== null) for (s = o.body.getReader();;) {
1067
1123
  let e = await s.read();
1068
1124
  if (e.done) break;
1069
- if (e.value.byteLength > a - i) throw Ft(a);
1125
+ if (e.value.byteLength > a - i) throw Yt(a);
1070
1126
  if (e.value.byteLength !== 0) {
1071
1127
  let t = i + e.value.byteLength;
1072
1128
  if (t > r.byteLength) {
@@ -1090,26 +1146,35 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1090
1146
  transient: !0
1091
1147
  })
1092
1148
  });
1093
- }), Rt = (e, t) => y.suspend(() => {
1149
+ }), Qt = (e, t) => v.suspend(() => {
1094
1150
  if (t === void 0) return e;
1095
- if (t.aborted) return y.interrupt;
1096
- let n = y.async((e) => {
1097
- let n = () => e(y.interrupt);
1098
- return t.addEventListener("abort", n, { once: !0 }), t.aborted && n(), y.sync(() => t.removeEventListener("abort", n));
1151
+ if (t.aborted) return v.interrupt;
1152
+ let n = v.callback((e) => {
1153
+ let n = () => e(v.interrupt);
1154
+ return t.addEventListener("abort", n, { once: !0 }), t.aborted && n(), v.sync(() => t.removeEventListener("abort", n));
1099
1155
  });
1100
- return y.raceFirst(e, n);
1101
- }), zt = (e) => {
1102
- let r = (e, r) => y.tryPromise({
1103
- try: r,
1104
- catch: (r) => C.is(n)(r) ? r : new t({
1105
- provider: "metadata",
1106
- message: `Storage ${e} was not confirmed; retain the operation identity for recovery`,
1107
- transient: !1
1108
- })
1156
+ return v.raceFirst(e, n);
1157
+ }), $t = (e) => {
1158
+ let r = (e, n) => v.tryPromise({
1159
+ try: n,
1160
+ catch: (n) => {
1161
+ let r = Ye(n);
1162
+ if (r !== void 0) return r;
1163
+ let i = G(n, "metadata"), a = new t({
1164
+ provider: "metadata",
1165
+ message: `Storage ${e} was not confirmed: ${i.message}; retain the operation identity for recovery`,
1166
+ transient: i.transient,
1167
+ ...i.status === void 0 ? {} : { status: i.status }
1168
+ });
1169
+ return Object.defineProperty(a, "cause", {
1170
+ value: n,
1171
+ configurable: !0
1172
+ }), a;
1173
+ }
1109
1174
  });
1110
1175
  return {
1111
- put: (t) => y.gen(function* () {
1112
- if (t.bytes.byteLength !== t.ref.size || he("sha256").update(t.bytes).digest("hex") !== t.identity.checksum) return yield* y.fail(new n({
1176
+ put: (t) => v.gen(function* () {
1177
+ if (t.bytes.byteLength !== t.ref.size || Ce("sha256").update(t.bytes).digest("hex") !== t.identity.checksum) return yield* v.fail(new n({
1113
1178
  reason: "operation-content-mismatch",
1114
1179
  detail: "Storage operation bytes do not match their reserved identity"
1115
1180
  }));
@@ -1125,15 +1190,15 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1125
1190
  outcome: a
1126
1191
  });
1127
1192
  }),
1128
- delete: (t, n, i) => y.gen(function* () {
1193
+ delete: (t, n, i) => v.gen(function* () {
1129
1194
  let a = yield* r("delete acceptance", () => e.metadata.beginDelete(t, n, i));
1130
1195
  "operation" in a && (a.operation.deleteKey !== null && (yield* e.provider.delete(a.operation.deleteKey)), yield* r("delete confirmation", () => e.metadata.confirmDelete(a.identity)));
1131
1196
  })
1132
1197
  };
1133
- }, Bt = async (e) => {
1198
+ }, en = async (e) => {
1134
1199
  let { createHash: t } = await import("node:crypto");
1135
1200
  return t("sha256").update(e).digest("hex");
1136
- }, Vt = (e, t, n) => `${e?.replace(/\/+$/, "") ?? ""}${n}/${t}`, Ht = (e) => {
1201
+ }, tn = (e, t, n) => `${e?.replace(/\/+$/, "") ?? ""}${n}/${t}`, nn = (e) => {
1137
1202
  let t = /* @__PURE__ */ new Map(), n = {
1138
1203
  public: 0,
1139
1204
  private: 0
@@ -1143,13 +1208,13 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1143
1208
  count: 0,
1144
1209
  bytes: 0
1145
1210
  };
1146
- i.count += r.count, i.bytes += r.bytes, t.set(e, i), r.visibility === "public" ? n.public += r.count : n.private += r.count;
1211
+ i.count = Je(i.count, r.count, "ref count"), i.bytes = Je(i.bytes, r.bytes, "usage bytes"), t.set(e, i), r.visibility === "public" ? n.public = Je(n.public, r.count, "public ref count") : n.private = Je(n.private, r.count, "private ref count");
1147
1212
  }
1148
1213
  return {
1149
1214
  byTenant: Object.fromEntries(t),
1150
1215
  visibility: n
1151
1216
  };
1152
- }, Ut = (e, t) => {
1217
+ }, rn = (e, t) => {
1153
1218
  if (t.search && ![
1154
1219
  e.id,
1155
1220
  e.key,
@@ -1166,26 +1231,32 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1166
1231
  if (!t.tags.every((e) => n.includes(e))) return !1;
1167
1232
  }
1168
1233
  return !0;
1169
- }, Wt = (e) => e ?? "global", Gt = () => {
1234
+ }, an = (e) => e ?? "global", on = () => {
1170
1235
  let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
1171
1236
  return {
1172
- statistics: () => y.sync(() => Ht((function* () {
1173
- for (let t of e.values()) yield {
1174
- tenantId: t.tenantId,
1175
- visibility: t.visibility,
1176
- count: 1,
1177
- bytes: t.size
1178
- };
1179
- })())),
1180
- insert: (t) => y.sync(() => {
1181
- e.set(t.id, t);
1237
+ statistics: () => v.try({
1238
+ try: () => nn((function* () {
1239
+ for (let t of e.values()) yield {
1240
+ tenantId: t.tenantId,
1241
+ visibility: t.visibility,
1242
+ count: 1,
1243
+ bytes: t.size
1244
+ };
1245
+ })()),
1246
+ catch: (e) => G(e, "refstore")
1247
+ }),
1248
+ insert: (t) => v.try({
1249
+ try: () => {
1250
+ W(t.size, "ref size"), e.set(t.id, t);
1251
+ },
1252
+ catch: (e) => G(e, "refstore")
1182
1253
  }),
1183
- getById: (t) => y.sync(() => e.get(t) ?? null),
1184
- delete: (t) => y.sync(() => e.delete(t)),
1185
- listRecent: (t) => y.sync(() => [...e.values()].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(0, t)),
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(() => {
1254
+ getById: (t) => v.sync(() => e.get(t) ?? null),
1255
+ delete: (t) => v.sync(() => e.delete(t)),
1256
+ listRecent: (t) => v.sync(() => [...e.values()].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(0, t)),
1257
+ countByKey: (t, n) => v.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n).length),
1258
+ countPublicByKey: (t, n) => v.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n && e.visibility === "public").length),
1259
+ setVisibility: (t, n) => v.sync(() => {
1189
1260
  let r = e.get(t);
1190
1261
  if (r === void 0) return null;
1191
1262
  let i = {
@@ -1194,46 +1265,57 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1194
1265
  };
1195
1266
  return e.set(t, i), i;
1196
1267
  }),
1197
- usageByTenant: (t) => y.sync(() => {
1198
- let n = 0, r = 0;
1199
- for (let i of e.values()) (i.tenantId ?? null) === (t ?? null) && (n += i.size, r++);
1200
- return {
1201
- bytes: n,
1202
- count: r
1203
- };
1268
+ usageByTenant: (t) => v.try({
1269
+ try: () => {
1270
+ let n = 0, r = 0;
1271
+ for (let i of e.values()) (i.tenantId ?? null) === (t ?? null) && (n = Je(n, i.size, "usage bytes"), r++);
1272
+ return {
1273
+ bytes: n,
1274
+ count: r
1275
+ };
1276
+ },
1277
+ catch: (e) => G(e, "refstore")
1204
1278
  }),
1205
- consumeUsage: (e, n, r) => y.sync(() => {
1206
- let i = Wt(e), a = t.get(i) ?? {
1207
- bytes: 0,
1208
- count: 0
1209
- }, o = (r?.maxBytes === void 0 || a.bytes + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || a.count + n.count <= r.maxCount);
1210
- return o && t.set(i, {
1211
- bytes: a.bytes + n.bytes,
1212
- count: a.count + n.count
1213
- }), {
1214
- allowed: o,
1215
- bytes: a.bytes,
1216
- count: a.count
1217
- };
1279
+ consumeUsage: (e, n, r) => v.try({
1280
+ try: () => {
1281
+ let i = an(e), a = t.get(i) ?? {
1282
+ bytes: 0,
1283
+ count: 0
1284
+ };
1285
+ W(n.bytes, "usage byte delta"), W(n.count, "usage count delta");
1286
+ let o = Number.isSafeInteger(a.bytes + n.bytes) && Number.isSafeInteger(a.count + n.count) && (r?.maxBytes === void 0 || a.bytes + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || a.count + n.count <= r.maxCount);
1287
+ return o && t.set(i, {
1288
+ bytes: a.bytes + n.bytes,
1289
+ count: a.count + n.count
1290
+ }), {
1291
+ allowed: o,
1292
+ bytes: a.bytes,
1293
+ count: a.count
1294
+ };
1295
+ },
1296
+ catch: (e) => G(e, "refstore")
1218
1297
  }),
1219
- releaseUsage: (e, n) => y.sync(() => {
1220
- let r = Wt(e), i = t.get(r);
1221
- i && t.set(r, {
1222
- bytes: Math.max(0, i.bytes - n.bytes),
1223
- count: Math.max(0, i.count - n.count)
1224
- });
1298
+ releaseUsage: (e, n) => v.try({
1299
+ try: () => {
1300
+ let r = an(e), i = t.get(r);
1301
+ W(n.bytes, "usage byte delta"), W(n.count, "usage count delta"), i && t.set(r, {
1302
+ bytes: Math.max(0, i.bytes - n.bytes),
1303
+ count: Math.max(0, i.count - n.count)
1304
+ });
1305
+ },
1306
+ catch: (e) => G(e, "refstore")
1225
1307
  }),
1226
- listByDerivedFrom: (t) => y.sync(() => [...e.values()].filter((e) => (e.derivedFrom ?? null) === t)),
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))
1308
+ listByDerivedFrom: (t) => v.sync(() => [...e.values()].filter((e) => (e.derivedFrom ?? null) === t)),
1309
+ listRefs: (t) => v.sync(() => [...e.values()].filter((e) => rn(e, t)).sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(t.offset, t.offset + t.limit))
1228
1310
  };
1229
- }, Kt = (e) => Array.isArray(e) && e.every((e) => typeof e == "string") ? e : null, Y = (e) => ({
1311
+ }, sn = (e) => Array.isArray(e) && e.every((e) => typeof e == "string") ? e : null, X = (e) => ({
1230
1312
  id: String(e.id),
1231
1313
  tenantId: e.tenantId ?? null,
1232
1314
  ownerId: e.ownerId ?? null,
1233
1315
  bucket: String(e.bucket),
1234
1316
  key: String(e.key),
1235
1317
  contentType: String(e.contentType),
1236
- size: Number(e.size),
1318
+ size: W(e.size, "ref size"),
1237
1319
  checksum: String(e.checksum),
1238
1320
  visibility: e.visibility === "public" ? "public" : "private",
1239
1321
  accessPolicy: e.accessPolicy ?? null,
@@ -1244,19 +1326,15 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1244
1326
  duration: e.duration ?? null,
1245
1327
  placeholder: e.placeholder ?? null,
1246
1328
  folder: e.folder ?? null,
1247
- tags: Kt(e.tags),
1329
+ tags: sn(e.tags),
1248
1330
  alt: e.alt ?? null,
1249
1331
  caption: e.caption ?? null,
1250
1332
  derivedFrom: e.derivedFrom ?? null,
1251
1333
  kind: e.kind ?? null
1252
- }), X = (e) => y.tryPromise({
1334
+ }), Z = (e) => v.tryPromise({
1253
1335
  try: e,
1254
- catch: (e) => new t({
1255
- provider: "refstore",
1256
- message: String(e?.message ?? e),
1257
- transient: !0
1258
- })
1259
- }), qt = async (e, t) => (await e.query({
1336
+ catch: (e) => G(e, "refstore", !0)
1337
+ }), cn = async (e, t) => (await e.query({
1260
1338
  table: "_voltro_storage_usage",
1261
1339
  predicate: {
1262
1340
  column: "tenantId",
@@ -1267,33 +1345,41 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1267
1345
  take: 1,
1268
1346
  skip: void 0,
1269
1347
  projection: void 0
1270
- }))[0] ?? null, Jt = (e) => ({
1271
- statistics: () => X(async () => Ht((await e.query({
1272
- table: V,
1348
+ }))[0] ?? null, ln = (e) => ({
1349
+ statistics: () => Z(async () => nn((await e.query({
1350
+ table: B,
1273
1351
  predicate: void 0,
1274
1352
  order: [],
1275
1353
  take: void 0,
1276
1354
  skip: void 0,
1277
1355
  projection: void 0,
1278
1356
  groupBy: ["tenantId", "visibility"],
1279
- aggregations: [{
1280
- op: "count",
1281
- alias: "count"
1282
- }, {
1283
- op: "sum",
1284
- column: "size",
1285
- alias: "bytes"
1286
- }]
1357
+ aggregations: [
1358
+ de("tenantId"),
1359
+ de("visibility"),
1360
+ {
1361
+ op: "count",
1362
+ alias: "count"
1363
+ },
1364
+ {
1365
+ op: "sum",
1366
+ column: "size",
1367
+ alias: "bytes"
1368
+ }
1369
+ ]
1287
1370
  })).map((e) => ({
1288
1371
  tenantId: e.tenantId == null ? null : String(e.tenantId),
1289
1372
  visibility: String(e.visibility),
1290
- count: Number(e.count),
1291
- bytes: Number(e.bytes ?? 0)
1373
+ count: W(e.count, "ref count"),
1374
+ bytes: W(e.bytes ?? 0, "usage bytes")
1292
1375
  })))),
1293
- insert: (t) => X(() => e.insert(V, { ...t })),
1294
- getById: (t) => X(async () => {
1376
+ insert: (t) => Z(() => e.insert(B, {
1377
+ ...t,
1378
+ size: String(W(t.size, "ref size"))
1379
+ })),
1380
+ getById: (t) => Z(async () => {
1295
1381
  let n = await e.query({
1296
- table: V,
1382
+ table: B,
1297
1383
  predicate: {
1298
1384
  column: "id",
1299
1385
  op: "eq",
@@ -1304,11 +1390,11 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1304
1390
  skip: void 0,
1305
1391
  projection: void 0
1306
1392
  });
1307
- return n[0] ? Y(n[0]) : null;
1393
+ return n[0] ? X(n[0]) : null;
1308
1394
  }),
1309
- delete: (t) => X(() => e.delete(V, t)),
1310
- listRecent: (t) => X(async () => (await e.query({
1311
- table: V,
1395
+ delete: (t) => Z(() => e.delete(B, t)),
1396
+ listRecent: (t) => Z(async () => (await e.query({
1397
+ table: B,
1312
1398
  predicate: void 0,
1313
1399
  order: [{
1314
1400
  column: "createdAt",
@@ -1317,9 +1403,9 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1317
1403
  take: t,
1318
1404
  skip: void 0,
1319
1405
  projection: void 0
1320
- })).map(Y)),
1321
- countByKey: (t, n) => X(async () => (await e.query({
1322
- table: V,
1406
+ })).map(X)),
1407
+ countByKey: (t, n) => Z(async () => W((await e.query({
1408
+ table: B,
1323
1409
  predicate: { and: [{
1324
1410
  column: "bucket",
1325
1411
  op: "eq",
@@ -1332,10 +1418,14 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1332
1418
  order: [],
1333
1419
  take: void 0,
1334
1420
  skip: void 0,
1335
- projection: void 0
1336
- })).length),
1337
- countPublicByKey: (t, n) => X(async () => (await e.query({
1338
- table: V,
1421
+ projection: void 0,
1422
+ aggregations: [{
1423
+ op: "count",
1424
+ alias: "count"
1425
+ }]
1426
+ }))[0]?.count ?? 0, "ref count")),
1427
+ countPublicByKey: (t, n) => Z(async () => W((await e.query({
1428
+ table: B,
1339
1429
  predicate: { and: [
1340
1430
  {
1341
1431
  column: "bucket",
@@ -1356,15 +1446,19 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1356
1446
  order: [],
1357
1447
  take: void 0,
1358
1448
  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;
1449
+ projection: void 0,
1450
+ aggregations: [{
1451
+ op: "count",
1452
+ alias: "count"
1453
+ }]
1454
+ }))[0]?.count ?? 0, "ref count")),
1455
+ setVisibility: (t, n) => Z(async () => {
1456
+ let r = await e.update(B, t, { visibility: n });
1457
+ return r ? X(r) : null;
1364
1458
  }),
1365
- usageByTenant: (t) => X(async () => {
1459
+ usageByTenant: (t) => Z(async () => {
1366
1460
  let n = await e.query({
1367
- table: V,
1461
+ table: B,
1368
1462
  predicate: {
1369
1463
  column: "tenantId",
1370
1464
  op: "eq",
@@ -1373,43 +1467,64 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1373
1467
  order: [],
1374
1468
  take: void 0,
1375
1469
  skip: void 0,
1376
- projection: void 0
1377
- }), r = 0;
1378
- for (let e of n) r += Number(e.size ?? 0);
1379
- return {
1380
- bytes: r,
1381
- count: n.length
1470
+ projection: void 0,
1471
+ aggregations: [
1472
+ {
1473
+ op: "count",
1474
+ alias: "count"
1475
+ },
1476
+ {
1477
+ op: "sum",
1478
+ column: "size",
1479
+ alias: "bytes"
1480
+ },
1481
+ {
1482
+ op: "min",
1483
+ column: "size",
1484
+ alias: "minSize"
1485
+ },
1486
+ {
1487
+ op: "max",
1488
+ column: "size",
1489
+ alias: "maxSize"
1490
+ }
1491
+ ]
1492
+ });
1493
+ return W(n[0]?.count ?? 0, "ref count") > 0 && (W(n[0]?.minSize, "ref size"), W(n[0]?.maxSize, "ref size")), {
1494
+ bytes: W(n[0]?.bytes ?? 0, "usage bytes"),
1495
+ count: W(n[0]?.count ?? 0, "ref count")
1382
1496
  };
1383
1497
  }),
1384
- consumeUsage: (t, n, r) => X(async () => {
1385
- let i = Wt(t);
1498
+ consumeUsage: (t, n, r) => Z(async () => {
1499
+ let i = an(t);
1500
+ W(n.bytes, "usage byte delta"), W(n.count, "usage count delta");
1386
1501
  for (let t = 0; t < 32; t++) {
1387
1502
  t > 0 && await new Promise((e) => setTimeout(e, t));
1388
- let a = await qt(e, i), o = a ? Number(a.bytes ?? 0) : 0, s = a ? Number(a.count ?? 0) : 0;
1389
- if (!((r?.maxBytes === void 0 || o + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || s + n.count <= r.maxCount))) return {
1503
+ let a = await cn(e, i), o = a ? W(a.bytes, "usage bytes") : 0, s = a ? W(a.count, "ref count") : 0;
1504
+ if (!(Number.isSafeInteger(o + n.bytes) && Number.isSafeInteger(s + n.count) && (r?.maxBytes === void 0 || o + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || s + n.count <= r.maxCount))) return {
1390
1505
  allowed: !1,
1391
1506
  bytes: o,
1392
1507
  count: s
1393
1508
  };
1394
1509
  if (a) {
1395
1510
  if (await e.updateMany("_voltro_storage_usage", {
1396
- bytes: o + n.bytes,
1397
- count: s + n.count,
1511
+ bytes: String(o + n.bytes),
1512
+ count: String(s + n.count),
1398
1513
  updatedAt: /* @__PURE__ */ new Date()
1399
- }, { where: E(O("id", String(a.id)), O("bytes", o), O("count", s)) }) === 1) return {
1514
+ }, { where: ue(k("id", String(a.id)), k("bytes", a.bytes), k("count", a.count)) }) === 1) return {
1400
1515
  allowed: !0,
1401
1516
  bytes: o,
1402
1517
  count: s
1403
1518
  };
1404
1519
  } else {
1405
- let t = k({
1520
+ let t = A({
1406
1521
  kind: "typeid",
1407
1522
  prefix: "susage"
1408
- }, Pe), r = await e.insertIgnore(Pe, {
1523
+ }, Ue), r = await e.insertIgnore(Ue, {
1409
1524
  id: t,
1410
1525
  tenantId: i,
1411
- bytes: n.bytes,
1412
- count: n.count,
1526
+ bytes: String(n.bytes),
1527
+ count: String(n.count),
1413
1528
  updatedAt: /* @__PURE__ */ new Date()
1414
1529
  }, { conflictColumns: ["tenantId"] });
1415
1530
  if (String(r.id) === t) return {
@@ -1419,25 +1534,26 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1419
1534
  };
1420
1535
  }
1421
1536
  }
1422
- throw Error(`storage usage consume: contention on tenant '${i}' exceeded 32 attempts`);
1537
+ throw T("Storage quota reservation contended after 32 attempts; retry");
1423
1538
  }),
1424
- releaseUsage: (t, n) => X(async () => {
1425
- let r = Wt(t);
1539
+ releaseUsage: (t, n) => Z(async () => {
1540
+ let r = an(t);
1541
+ W(n.bytes, "usage byte delta"), W(n.count, "usage count delta");
1426
1542
  for (let t = 0; t < 32; t++) {
1427
1543
  t > 0 && await new Promise((e) => setTimeout(e, t));
1428
- let i = await qt(e, r);
1544
+ let i = await cn(e, r);
1429
1545
  if (!i) return;
1430
- let a = Number(i.bytes ?? 0), o = Number(i.count ?? 0);
1546
+ let a = W(i.bytes, "usage bytes"), o = W(i.count, "ref count");
1431
1547
  if (await e.updateMany("_voltro_storage_usage", {
1432
- bytes: Math.max(0, a - n.bytes),
1433
- count: Math.max(0, o - n.count),
1548
+ bytes: String(Math.max(0, a - n.bytes)),
1549
+ count: String(Math.max(0, o - n.count)),
1434
1550
  updatedAt: /* @__PURE__ */ new Date()
1435
- }, { where: E(O("id", String(i.id)), O("bytes", a), O("count", o)) }) === 1) return;
1551
+ }, { where: ue(k("id", String(i.id)), k("bytes", i.bytes), k("count", i.count)) }) === 1) return;
1436
1552
  }
1437
- throw Error(`storage usage release: contention on tenant '${r}' exceeded 32 attempts`);
1553
+ throw T("Storage quota release contended after 32 attempts; retry");
1438
1554
  }),
1439
- listByDerivedFrom: (t) => X(async () => (await e.query({
1440
- table: V,
1555
+ listByDerivedFrom: (t) => Z(async () => (await e.query({
1556
+ table: B,
1441
1557
  predicate: {
1442
1558
  column: "derivedFrom",
1443
1559
  op: "eq",
@@ -1450,18 +1566,18 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1450
1566
  take: void 0,
1451
1567
  skip: void 0,
1452
1568
  projection: void 0
1453
- })).map(Y)),
1454
- listRefs: (t) => X(async () => {
1569
+ })).map(X)),
1570
+ listRefs: (t) => Z(async () => {
1455
1571
  let n = [];
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(...[
1572
+ t.tenantId !== void 0 && n.push(k("tenantId", t.tenantId)), t.ownerId !== void 0 && n.push(k("ownerId", t.ownerId)), t.search && n.push(N(...[
1457
1573
  "id",
1458
1574
  "key",
1459
1575
  "contentType",
1460
1576
  "ownerId",
1461
1577
  "tenantId"
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({
1464
- table: V,
1578
+ ].map((e) => fe(e, t.search)))), t.includeDerived || n.push(me("derivedFrom"));
1579
+ let r = t.folder === void 0 && t.tags.length === 0, i = n.length ? ue(...n) : void 0, a = await e.query({
1580
+ table: B,
1465
1581
  predicate: i,
1466
1582
  order: [{
1467
1583
  column: "createdAt",
@@ -1474,24 +1590,24 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1474
1590
  skip: r ? t.offset : void 0,
1475
1591
  projection: void 0
1476
1592
  });
1477
- return r ? a.map(Y) : a.map(Y).filter((e) => Ut(e, t)).slice(t.offset, t.offset + t.limit);
1593
+ return r ? a.map(X) : a.map(X).filter((e) => rn(e, t)).slice(t.offset, t.offset + t.limit);
1478
1594
  })
1479
- }), Yt = () => {
1595
+ }), un = () => {
1480
1596
  let e = /* @__PURE__ */ new Map();
1481
1597
  return {
1482
- insert: (t) => y.sync(() => {
1598
+ insert: (t) => v.sync(() => {
1483
1599
  e.set(t.id, t);
1484
1600
  }),
1485
- delete: (t) => y.sync(() => {
1601
+ delete: (t) => v.sync(() => {
1486
1602
  e.delete(t);
1487
1603
  }),
1488
- getById: (t) => y.sync(() => e.get(t) ?? null),
1489
- listByRef: (t) => y.sync(() => [...e.values()].filter((e) => e.refId === t)),
1490
- deleteByRef: (t) => y.sync(() => {
1604
+ getById: (t) => v.sync(() => e.get(t) ?? null),
1605
+ listByRef: (t) => v.sync(() => [...e.values()].filter((e) => e.refId === t)),
1606
+ deleteByRef: (t) => v.sync(() => {
1491
1607
  for (let [n, r] of e) r.refId === t && e.delete(n);
1492
1608
  })
1493
1609
  };
1494
- }, Xt = (e) => ({
1610
+ }, dn = (e) => ({
1495
1611
  id: String(e.id),
1496
1612
  refId: String(e.refId),
1497
1613
  principalType: e.principalType,
@@ -1500,12 +1616,12 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1500
1616
  createdAt: e.createdAt instanceof Date ? e.createdAt : new Date(String(e.createdAt)),
1501
1617
  expiresAt: e.expiresAt ? e.expiresAt instanceof Date ? e.expiresAt : new Date(String(e.expiresAt)) : null,
1502
1618
  createdBy: e.createdBy ?? null
1503
- }), Zt = (e) => ({
1504
- insert: (t) => X(() => e.insert(H, { ...t })),
1505
- delete: (t) => X(() => e.delete(H, t)),
1506
- getById: (t) => X(async () => {
1619
+ }), fn = (e) => ({
1620
+ insert: (t) => Z(() => e.insert(V, { ...t })),
1621
+ delete: (t) => Z(() => e.delete(V, t)),
1622
+ getById: (t) => Z(async () => {
1507
1623
  let n = (await e.query({
1508
- table: H,
1624
+ table: V,
1509
1625
  predicate: {
1510
1626
  column: "id",
1511
1627
  op: "eq",
@@ -1516,10 +1632,10 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1516
1632
  skip: void 0,
1517
1633
  projection: void 0
1518
1634
  }))[0];
1519
- return n ? Xt(n) : null;
1635
+ return n ? dn(n) : null;
1520
1636
  }),
1521
- listByRef: (t) => X(async () => (await e.query({
1522
- table: H,
1637
+ listByRef: (t) => Z(async () => (await e.query({
1638
+ table: V,
1523
1639
  predicate: {
1524
1640
  column: "refId",
1525
1641
  op: "eq",
@@ -1532,10 +1648,10 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1532
1648
  take: void 0,
1533
1649
  skip: void 0,
1534
1650
  projection: void 0
1535
- })).map(Xt)),
1536
- deleteByRef: (t) => X(async () => {
1651
+ })).map(dn)),
1652
+ deleteByRef: (t) => Z(async () => {
1537
1653
  let n = await e.query({
1538
- table: H,
1654
+ table: V,
1539
1655
  predicate: {
1540
1656
  column: "refId",
1541
1657
  op: "eq",
@@ -1546,23 +1662,23 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1546
1662
  skip: void 0,
1547
1663
  projection: void 0
1548
1664
  });
1549
- for (let t of n) await e.delete(H, String(t.id));
1665
+ for (let t of n) await e.delete(V, String(t.id));
1550
1666
  })
1551
- }), Qt = () => k({
1667
+ }), pn = () => A({
1552
1668
  kind: "typeid",
1553
1669
  prefix: "file"
1554
- }, V), $t = () => k({
1670
+ }, B), mn = () => A({
1555
1671
  kind: "typeid",
1556
1672
  prefix: "grant"
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) => [
1673
+ }, V), hn = (i) => {
1674
+ let { provider: a, refStore: o, grantStore: s, bucket: c } = i, l = i.access ?? {}, u = i.attempts ?? 3, d = i.urlExpiresInSec ?? 3600, f = (e) => tn(i.publicBaseUrl, e, i.httpPath ?? "/_voltro/storage"), p = x.max([x.recurs(Math.max(0, u - 1)), x.exponential("100 millis")]).pipe(x.while(({ input: e }) => e.transient)), m = (e, t, n) => [
1559
1675
  i.tenantPrefix,
1560
1676
  e ?? "global",
1561
1677
  n ?? t
1562
1678
  ].filter(Boolean).join("/"), ee = (e) => {
1563
- if (e === void 0) return y.succeed(void 0);
1679
+ if (e === void 0) return v.succeed(void 0);
1564
1680
  let n = e.length === 0 ? "empty" : e.includes("\0") ? "contains NUL" : e.startsWith("/") || e.startsWith("\\") ? "starts with a path separator" : e.includes("\\") ? "contains a backslash" : e.split("/").some((e) => e === "" || e === "." || e === "..") ? "contains an empty, \".\" or \"..\" segment" : void 0;
1565
- return n === void 0 ? y.succeed(e) : y.fail(new t({
1681
+ return n === void 0 ? v.succeed(e) : v.fail(new t({
1566
1682
  provider: a.name,
1567
1683
  message: `storage key rejected: ${n}`,
1568
1684
  transient: !1,
@@ -1574,20 +1690,20 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1574
1690
  "_incoming",
1575
1691
  t,
1576
1692
  String(n).padStart(6, "0")
1577
- ].filter(Boolean).join("/"), h = (e, n) => n !== void 0 && e.tenantId !== n ? y.fail(new t({
1693
+ ].filter(Boolean).join("/"), ne = (e, t) => t === void 0 || e.tenantId === t, h = (e, n) => ne(e, n) ? v.succeed(e) : v.fail(new t({
1578
1694
  provider: a.name,
1579
1695
  message: "cross-tenant access denied",
1580
1696
  transient: !1,
1581
1697
  status: 403
1582
- })) : y.succeed(e), ne = (e, n, r) => y.gen(function* () {
1698
+ })), g = (e, n, r) => v.gen(function* () {
1583
1699
  let o = i.objects?.(), s = (e) => new t({
1584
1700
  provider: "metadata",
1585
1701
  message: e,
1586
1702
  transient: !1,
1587
1703
  status: 409
1588
1704
  });
1589
- if (o === void 0) return r === void 0 ? !1 : yield* y.fail(s(`claim '${r}' cannot be released: no data store is bound, so ref '${e}' holds no claims`));
1590
- let c = yield* y.tryPromise({
1705
+ if (o === void 0) return r === void 0 ? !1 : yield* v.fail(s(`claim '${r}' cannot be released: no data store is bound, so ref '${e}' holds no claims`));
1706
+ let c = yield* v.tryPromise({
1591
1707
  try: () => o.intent(e),
1592
1708
  catch: (e) => new t({
1593
1709
  provider: "metadata",
@@ -1595,25 +1711,25 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1595
1711
  transient: !1
1596
1712
  })
1597
1713
  });
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({
1714
+ return c === void 0 ? r === void 0 ? !1 : yield* v.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* $t({
1599
1715
  metadata: o,
1600
1716
  provider: {
1601
1717
  ...a,
1602
- delete: (e) => a.delete(e).pipe(y.retry(p))
1718
+ delete: (e) => a.delete(e).pipe(v.retry(p))
1603
1719
  }
1604
- }).delete(e, n, r).pipe(y.catchTag("StorageRejected", (e) => y.fail(e.reason === "claim-not-held" ? s(e.detail) : new t({
1720
+ }).delete(e, n, r).pipe(v.catchTag("StorageRejected", (e) => v.fail(e.reason === "claim-not-held" ? s(e.detail) : new t({
1605
1721
  provider: "metadata",
1606
1722
  message: e.detail,
1607
1723
  transient: !1
1608
1724
  })))), !0);
1609
- }), g = (e, n) => o.getById(e).pipe(y.flatMap((r) => r ? h(r, n) : y.fail(new t({
1725
+ }), _ = (e, n) => o.getById(e).pipe(v.flatMap((r) => r ? h(r, n) : v.fail(new t({
1610
1726
  provider: a.name,
1611
1727
  message: `no ref '${e}'`,
1612
1728
  transient: !1,
1613
1729
  status: 404
1614
- })))), re = (e) => y.suspend(() => {
1730
+ })))), re = (e) => v.suspend(() => {
1615
1731
  let n = i.scan(e);
1616
- return y.isEffect(n) ? n : y.tryPromise({
1732
+ return v.isEffect(n) ? n : v.tryPromise({
1617
1733
  try: () => Promise.resolve(n),
1618
1734
  catch: (e) => new t({
1619
1735
  provider: "scan",
@@ -1621,23 +1737,23 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1621
1737
  transient: !0
1622
1738
  })
1623
1739
  });
1624
- }), ie = (e) => y.suspend(() => {
1740
+ }), ie = (e) => v.suspend(() => {
1625
1741
  let t = e.contentType;
1626
- if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return y.succeed(null);
1742
+ if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return v.succeed(null);
1627
1743
  let n;
1628
1744
  try {
1629
1745
  n = i.videoProbe(e);
1630
1746
  } catch {
1631
- return y.succeed(null);
1747
+ return v.succeed(null);
1632
1748
  }
1633
- return y.isEffect(n) ? n.pipe(y.catchAll(() => y.succeed(null))) : y.tryPromise({
1749
+ return v.isEffect(n) ? n.pipe(v.catch(() => v.succeed(null))) : v.tryPromise({
1634
1750
  try: () => Promise.resolve(n),
1635
1751
  catch: () => null
1636
- }).pipe(y.catchAll(() => y.succeed(null)));
1637
- }), _ = (e) => y.gen(function* () {
1638
- let t = Mt(e.bytes, e.contentType, i.limits);
1639
- if (t) return yield* y.fail(new n(t));
1640
- if (e.claim !== void 0 && e.operationId === void 0) return yield* y.fail(new n({
1752
+ }).pipe(v.catch(() => v.succeed(null)));
1753
+ }), b = (e) => v.gen(function* () {
1754
+ let t = Kt(e.bytes, e.contentType, i.limits);
1755
+ if (t) return yield* v.fail(new n(t));
1756
+ if (e.claim !== void 0 && e.operationId === void 0) return yield* v.fail(new n({
1641
1757
  reason: "claim-without-operation",
1642
1758
  detail: "a put with a claim needs an operationId; the claim names this caller's hold on that operation's object"
1643
1759
  }));
@@ -1647,38 +1763,38 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1647
1763
  contentType: e.contentType,
1648
1764
  ...e.key ? { key: e.key } : {}
1649
1765
  });
1650
- if (!t.clean) return yield* y.fail(new r({ threat: t.threat ?? "unknown" }));
1766
+ if (!t.clean) return yield* v.fail(new r({ threat: t.threat ?? "unknown" }));
1651
1767
  }
1652
- let s = yield* y.promise(() => Nt(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* ie({
1768
+ let s = yield* v.promise(() => qt(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* ie({
1653
1769
  bytes: l,
1654
1770
  contentType: e.contentType
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(),
1771
+ }), d = s.width ?? u?.width, f = s.height ?? u?.height, te = s.placeholder ?? u?.poster, ne = e.duration ?? u?.duration, h = yield* v.promise(() => en(l)), g = e.tenantId ?? null, _ = e.visibility ?? "private", b = m(g, h, yield* ee(e.key)), x = e.password ? yield* v.sync(() => yt(e.password)) : null, S = {
1772
+ id: pn(),
1657
1773
  tenantId: g,
1658
1774
  ownerId: e.ownerId ?? null,
1659
1775
  bucket: c,
1660
- key: v,
1776
+ key: b,
1661
1777
  contentType: e.contentType,
1662
1778
  size: l.byteLength,
1663
- checksum: ne,
1779
+ checksum: h,
1664
1780
  visibility: _,
1665
1781
  accessPolicy: e.access ?? null,
1666
- passwordHash: S,
1782
+ passwordHash: x,
1667
1783
  createdAt: /* @__PURE__ */ new Date(),
1668
1784
  ...d === void 0 ? {} : { width: d },
1669
1785
  ...f === void 0 ? {} : { height: f },
1670
1786
  ...te === void 0 ? {} : { placeholder: te },
1671
- ...h === void 0 ? {} : { duration: h },
1787
+ ...ne === void 0 ? {} : { duration: ne },
1672
1788
  ...e.folder === void 0 ? {} : { folder: e.folder },
1673
1789
  ...e.tags === void 0 ? {} : { tags: e.tags },
1674
1790
  ...e.alt === void 0 ? {} : { alt: e.alt },
1675
1791
  ...e.caption === void 0 ? {} : { caption: e.caption },
1676
1792
  ...e.derivedFrom === void 0 ? {} : { derivedFrom: e.derivedFrom },
1677
1793
  ...e.kind === void 0 ? {} : { kind: e.kind }
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;
1794
+ }, C = i.transcode !== void 0 && i.autoTranscode !== !1, oe = (t) => C && t.derivedFrom == null && (e.contentType.startsWith("video/") || e.contentType.startsWith("audio/")) ? v.forkDetach(ae(t).pipe(v.ignore)) : v.void;
1679
1795
  if (e.operationId !== void 0) {
1680
1796
  let t = i.objects?.();
1681
- if (t === void 0) return yield* y.fail(new n({
1797
+ if (t === void 0) return yield* v.fail(new n({
1682
1798
  reason: "operation-store-unbound",
1683
1799
  detail: "a put with an operationId needs a bound data store; the in-memory ref store cannot hold operation intents"
1684
1800
  }));
@@ -1686,10 +1802,10 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1686
1802
  tenantId: g,
1687
1803
  bucket: c,
1688
1804
  operationId: e.operationId,
1689
- checksum: ne,
1690
- logicalKey: v,
1691
- fingerprint: yield* y.promise(() => Bt(new TextEncoder().encode(JSON.stringify([
1692
- ne,
1805
+ checksum: h,
1806
+ logicalKey: b,
1807
+ fingerprint: yield* v.promise(() => en(new TextEncoder().encode(JSON.stringify([
1808
+ h,
1693
1809
  e.contentType,
1694
1810
  _,
1695
1811
  e.access ?? null,
@@ -1701,66 +1817,66 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1701
1817
  e.caption ?? null,
1702
1818
  e.derivedFrom ?? null,
1703
1819
  e.kind ?? null,
1704
- h ?? null,
1820
+ ne ?? null,
1705
1821
  e.password !== void 0
1706
1822
  ]))))
1707
- }, o = yield* zt({
1823
+ }, o = yield* $t({
1708
1824
  metadata: t,
1709
1825
  provider: {
1710
1826
  ...a,
1711
- put: (e, t, n) => a.put(e, t, n).pipe(y.retry(p))
1827
+ put: (e, t, n) => a.put(e, t, n).pipe(v.retry(p))
1712
1828
  }
1713
1829
  }).put({
1714
1830
  identity: r,
1715
- ref: C,
1831
+ ref: S,
1716
1832
  bytes: l,
1717
1833
  ...i.quota === void 0 ? {} : { quota: i.quota },
1718
1834
  ...e.claim === void 0 ? {} : { claim: e.claim }
1719
1835
  });
1720
- return yield* T(o.ref), {
1836
+ return yield* oe(o.ref), {
1721
1837
  ...o.ref,
1722
1838
  outcome: o.outcome
1723
1839
  };
1724
1840
  }
1725
- let ae = {
1841
+ let w = {
1726
1842
  bytes: l.byteLength,
1727
1843
  count: 1
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}`;
1731
- return yield* y.fail(new n({
1844
+ }, se = yield* o.consumeUsage(g, w, i.quota);
1845
+ if (!se.allowed) {
1846
+ 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}`;
1847
+ return yield* v.fail(new n({
1732
1848
  reason: "quota-exceeded",
1733
1849
  detail: t
1734
1850
  }));
1735
1851
  }
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, {
1852
+ return yield* ((e) => e.pipe(v.onExit((e) => y.isSuccess(e) ? v.void : o.delete(S.id).pipe(v.andThen(o.releaseUsage(g, w)), v.ignore))))(o.insert(S).pipe(v.andThen(a.put(b, l, {
1737
1853
  contentType: e.contentType,
1738
1854
  public: _ === "public"
1739
- }).pipe(y.retry(p))))), yield* T(C), {
1740
- ...C,
1855
+ }).pipe(v.retry(p))))), yield* oe(S), {
1856
+ ...S,
1741
1857
  outcome: "created"
1742
1858
  };
1743
- }), v = (e) => y.suspend(() => {
1744
- if (!i.transcode) return y.succeed([]);
1859
+ }), S = (e) => v.suspend(() => {
1860
+ if (!i.transcode) return v.succeed([]);
1745
1861
  let t;
1746
1862
  try {
1747
1863
  t = i.transcode(e);
1748
1864
  } catch {
1749
- return y.succeed([]);
1865
+ return v.succeed([]);
1750
1866
  }
1751
- return y.isEffect(t) ? t.pipe(y.catchAll(() => y.succeed([]))) : y.tryPromise({
1867
+ return v.isEffect(t) ? t.pipe(v.catch(() => v.succeed([]))) : v.tryPromise({
1752
1868
  try: () => Promise.resolve(t),
1753
1869
  catch: () => []
1754
- }).pipe(y.catchAll(() => y.succeed([])));
1755
- }), x = (e) => y.gen(function* () {
1870
+ }).pipe(v.catch(() => v.succeed([])));
1871
+ }), ae = (e) => v.gen(function* () {
1756
1872
  if (!i.transcode || e.derivedFrom != null) return [];
1757
- let t = yield* a.get(e.key).pipe(y.retry(p)), n = yield* v({
1873
+ let t = yield* a.get(e.key).pipe(v.retry(p)), n = yield* S({
1758
1874
  bytes: t.bytes,
1759
1875
  contentType: e.contentType,
1760
1876
  ref: e
1761
1877
  }), r = [];
1762
1878
  for (let t of n) {
1763
- let n = yield* _({
1879
+ let n = yield* b({
1764
1880
  bytes: t.bytes,
1765
1881
  contentType: t.contentType,
1766
1882
  tenantId: e.tenantId,
@@ -1773,14 +1889,20 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1773
1889
  r.push(n);
1774
1890
  }
1775
1891
  return r;
1776
- }), C = (e, t, n) => y.gen(function* () {
1777
- if (e.visibility === "public" || (yield* mt(e, t, {
1892
+ }), oe = (e, t, n) => v.gen(function* () {
1893
+ if (e.derivedFrom != null) {
1894
+ let r = yield* o.getById(e.derivedFrom);
1895
+ return r === null ? !1 : yield* oe(r, t, n);
1896
+ }
1897
+ if (e.visibility === "public") return !0;
1898
+ if (e.tenantId !== null && !ne(e, t.tenantId ?? null)) return !1;
1899
+ if (yield* Dt(e, t, {
1778
1900
  ...l,
1779
1901
  ...n?.password === void 0 ? {} : { password: n.password }
1780
- }))) return !0;
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) => {
1902
+ })) return !0;
1903
+ let r = yield* jt(t, l);
1904
+ return At(yield* s.listByRef(e.id), t, r, n?.permission ?? "read", Date.now());
1905
+ }), w = (e) => {
1784
1906
  if (e.visibility === "public") {
1785
1907
  let t = a.publicUrl?.(e.key);
1786
1908
  if (t != null) return t;
@@ -1788,94 +1910,99 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1788
1910
  return f(e.id);
1789
1911
  };
1790
1912
  return {
1791
- put: _,
1792
- get: (e, t) => g(e, t?.tenantId).pipe(y.flatMap((e) => a.get(e.key).pipe(y.retry(p), y.map((t) => ({
1913
+ put: b,
1914
+ get: (e, t) => _(e, t?.tenantId).pipe(v.flatMap((e) => a.get(e.key).pipe(v.retry(p), v.map((t) => ({
1793
1915
  bytes: t.bytes,
1794
1916
  ref: e
1795
1917
  }))))),
1796
- getStream: (e, t) => g(e, t?.tenantId).pipe(y.map((e) => ({
1918
+ getStream: (e, t) => _(e, t?.tenantId).pipe(v.map((e) => ({
1797
1919
  ref: e,
1798
- stream: w.unwrap(y.suspend(() => a.getStream ? a.getStream(e.key).pipe(y.retry(p), y.map((e) => e.stream)) : a.get(e.key).pipe(y.retry(p), y.map((e) => w.make(e.bytes)))))
1920
+ stream: C.unwrap(v.suspend(() => a.getStream ? a.getStream(e.key).pipe(v.retry(p), v.map((e) => e.stream)) : a.get(e.key).pipe(v.retry(p), v.map((e) => C.make(e.bytes)))))
1799
1921
  }))),
1800
- getRange: (e, n, r) => g(e, r?.tenantId).pipe(y.flatMap((e) => {
1922
+ getRange: (e, n, r) => _(e, r?.tenantId).pipe(v.flatMap((e) => {
1801
1923
  let r = e.size, i = Math.max(0, Math.trunc(n.start));
1802
- if (r > 0 && i >= r) return y.fail(new t({
1924
+ if (r > 0 && i >= r) return v.fail(new t({
1803
1925
  provider: a.name,
1804
1926
  message: `range start ${i} past end ${r}`,
1805
1927
  transient: !1,
1806
1928
  status: 416
1807
1929
  }));
1808
1930
  let o = Math.min(Math.trunc(n.endInclusive), Math.max(0, r - 1));
1809
- return o < i ? y.fail(new t({
1931
+ return o < i ? v.fail(new t({
1810
1932
  provider: a.name,
1811
1933
  message: `empty range ${i}-${o}`,
1812
1934
  transient: !1,
1813
1935
  status: 416
1814
- })) : (a.getRange ? a.getRange(e.key, i, o).pipe(y.retry(p)) : a.get(e.key).pipe(y.retry(p), y.map((e) => e.bytes.subarray(i, o + 1)))).pipe(y.map((t) => ({
1936
+ })) : (a.getRange ? a.getRange(e.key, i, o).pipe(v.retry(p)) : a.get(e.key).pipe(v.retry(p), v.map((e) => e.bytes.subarray(i, o + 1)))).pipe(v.map((t) => ({
1815
1937
  bytes: t,
1816
1938
  ref: e,
1817
1939
  totalSize: r
1818
1940
  })));
1819
1941
  })),
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)))),
1821
- head: (e, t) => o.getById(e).pipe(y.flatMap((e) => e ? h(e, t?.tenantId).pipe(y.map((e) => e)) : y.succeed(null))),
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, {
1942
+ getUrl: (e, t) => _(e, t?.tenantId).pipe(v.flatMap((e) => e.visibility === "public" ? v.succeed(w(e)) : a.presigns ? a.getUrl(e.key, t?.expiresInSec ?? d) : v.succeed(f(e.id)))),
1943
+ head: (e, t) => o.getById(e).pipe(v.flatMap((e) => e ? h(e, t?.tenantId).pipe(v.map((e) => e)) : v.succeed(null))),
1944
+ delete: (e, t) => g(e, t?.tenantId, t?.claim).pipe(v.flatMap((n) => n ? v.void : _(e, t?.tenantId).pipe(v.flatMap((t) => s.deleteByRef(e).pipe(v.flatMap(() => o.delete(e)), v.flatMap((e) => e ? o.countByKey(t.bucket, t.key).pipe(v.flatMap((e) => e === 0 ? a.delete(t.key).pipe(v.retry(p)) : v.void), v.flatMap(() => o.releaseUsage(t.tenantId, {
1823
1945
  bytes: t.size,
1824
1946
  count: 1
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));
1947
+ }))) : v.void), v.asVoid))))),
1948
+ signedUrl: (e, t) => _(e, t?.tenantId).pipe(v.flatMap((e) => {
1949
+ if (e.visibility === "public") return v.succeed(w(e));
1828
1950
  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")}`);
1951
+ return a.presigns ? a.getUrl(e.key, n) : v.sync(() => `${f(e.id)}?t=${Mt(e.id, n, void 0, i.httpPath ?? "/_voltro/storage")}`);
1830
1952
  })),
1831
- setVisibility: (e, r, i) => y.gen(function* () {
1832
- let s = yield* g(e, i?.tenantId);
1953
+ setVisibility: (e, r, i) => v.gen(function* () {
1954
+ let s = yield* _(e, i?.tenantId);
1833
1955
  if (s.visibility === r) return s;
1834
1956
  let c = o.setVisibility;
1835
- if (c === void 0) return yield* y.fail(new n({
1957
+ if (c === void 0) return yield* v.fail(new n({
1836
1958
  reason: "visibility-unsupported",
1837
1959
  detail: "the ref store cannot change a stored object's visibility"
1838
1960
  }));
1839
- if (r === "private" && a.publicUrl?.(s.key) != null) return yield* y.fail(new n({
1961
+ if (r === "private" && a.publicUrl?.(s.key) != null) return yield* v.fail(new n({
1840
1962
  reason: "visibility-unsupported",
1841
1963
  detail: `objects are served from a public base (${a.name} cdnBaseUrl); a public object cannot be made private there`
1842
1964
  }));
1843
- if (r === "private" && a.setObjectPublic !== void 0 && o.countPublicByKey === void 0) return yield* y.fail(new n({
1965
+ if (r === "private" && a.setObjectPublic !== void 0 && o.countPublicByKey === void 0) return yield* v.fail(new n({
1844
1966
  reason: "visibility-unsupported",
1845
1967
  detail: "the ref store cannot tell whether other refs keep these bytes public"
1846
1968
  }));
1847
1969
  let l = yield* c(s.id, r);
1848
- if (l === null) return yield* y.fail(new t({
1970
+ if (l === null) return yield* v.fail(new t({
1849
1971
  provider: a.name,
1850
1972
  message: `no ref '${e}'`,
1851
1973
  transient: !1,
1852
1974
  status: 404
1853
1975
  }));
1976
+ let u = s.derivedFrom == null ? yield* o.listByDerivedFrom(s.id) : [];
1977
+ for (let e of u) e.visibility !== r && (yield* c(e.id, r));
1854
1978
  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);
1979
+ let e = o.countPublicByKey;
1980
+ for (let t of [s, ...u]) {
1981
+ let n = r === "public" || e !== void 0 && (yield* e(t.bucket, t.key)) > 0;
1982
+ yield* a.setObjectPublic(t.key, n);
1983
+ }
1857
1984
  }
1858
1985
  return l;
1859
1986
  }),
1860
- mintUrl: (n, r, s) => y.gen(function* () {
1861
- let c = yield* o.getById(n).pipe(y.flatMap((e) => e ? y.succeed(e) : y.fail(new t({
1987
+ mintUrl: (n, r, s) => v.gen(function* () {
1988
+ let c = yield* o.getById(n).pipe(v.flatMap((e) => e ? v.succeed(e) : v.fail(new t({
1862
1989
  provider: a.name,
1863
1990
  message: `no ref '${n}'`,
1864
1991
  transient: !1,
1865
1992
  status: 404
1866
1993
  }))));
1867
- if (c.visibility === "public") return T(c);
1868
- if (!(yield* C(c, r, s?.password === void 0 ? {} : { password: s.password }))) return yield* y.fail(new e({
1994
+ if (c.visibility === "public" && c.derivedFrom == null) return w(c);
1995
+ if (!(yield* oe(c, r, s?.password === void 0 ? {} : { password: s.password }))) return yield* v.fail(new e({
1869
1996
  refId: n,
1870
1997
  reason: "access denied"
1871
1998
  }));
1872
1999
  let l = s?.expiresInSec ?? d;
1873
2000
  if (a.presigns) return yield* a.getUrl(c.key, l);
1874
- let u = yield* y.sync(() => yt(c.id, l, void 0, i.httpPath ?? "/_voltro/storage"));
2001
+ let u = yield* v.sync(() => Mt(c.id, l, void 0, i.httpPath ?? "/_voltro/storage"));
1875
2002
  return `${f(c.id)}?t=${u}`;
1876
2003
  }),
1877
- mintUploadUrl: (e) => y.gen(function* () {
1878
- if (!a.getUploadUrl) return yield* y.fail(new t({
2004
+ mintUploadUrl: (e) => v.gen(function* () {
2005
+ if (!a.getUploadUrl) return yield* v.fail(new t({
1879
2006
  provider: a.name,
1880
2007
  message: `provider '${a.name}' does not support presigned uploads`,
1881
2008
  transient: !1,
@@ -1884,10 +2011,10 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1884
2011
  let n = m(e.tenantId ?? null, "", yield* ee(e.key));
1885
2012
  return yield* a.getUploadUrl(n, e.expiresInSec ?? d, e.contentType);
1886
2013
  }),
1887
- checkAccess: C,
1888
- grant: (e) => y.gen(function* () {
2014
+ checkAccess: oe,
2015
+ grant: (e) => v.gen(function* () {
1889
2016
  let t = {
1890
- id: $t(),
2017
+ id: mn(),
1891
2018
  refId: e.refId,
1892
2019
  principalType: e.principalType,
1893
2020
  principalId: e.principalId,
@@ -1898,7 +2025,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1898
2025
  };
1899
2026
  return yield* s.insert(t), t;
1900
2027
  }),
1901
- listRefs: (e) => y.suspend(() => {
2028
+ listRefs: (e) => v.suspend(() => {
1902
2029
  let t = Math.min(500, Math.max(1, Math.trunc(e?.limit ?? 50))), n = Math.max(0, Math.trunc(e?.offset ?? 0)), r = {
1903
2030
  tenantId: e && "tenantId" in e ? e.tenantId : void 0,
1904
2031
  folder: e?.folder,
@@ -1908,7 +2035,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1908
2035
  limit: t + 1,
1909
2036
  offset: n
1910
2037
  };
1911
- return o.listRefs(r).pipe(y.map((e) => {
2038
+ return o.listRefs(r).pipe(v.map((e) => {
1912
2039
  let r = e.length > t;
1913
2040
  return {
1914
2041
  refs: r ? e.slice(0, t) : e,
@@ -1920,7 +2047,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1920
2047
  getGrant: (e) => s.getById(e),
1921
2048
  listGrants: (e) => s.listByRef(e),
1922
2049
  usage: (e) => o.usageByTenant(e),
1923
- sweepOrphans: (e) => y.gen(function* () {
2050
+ sweepOrphans: (e) => v.gen(function* () {
1924
2051
  let t = e?.limit ?? 1e3, n = e?.dryRun ?? !1, r = yield* o.listRecent(t), i = [];
1925
2052
  for (let e of r) if ((yield* a.head(e.key)) === null) {
1926
2053
  if (!n) {
@@ -1937,9 +2064,9 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1937
2064
  removed: i
1938
2065
  };
1939
2066
  }),
1940
- ingestUrl: (e, t) => Rt(y.gen(function* () {
1941
- let n = yield* Lt(e, i.limits?.maxBytes, i.ingest);
1942
- return yield* _({
2067
+ ingestUrl: (e, t) => Qt(v.gen(function* () {
2068
+ let n = yield* Zt(e, i.limits?.maxBytes, i.ingest);
2069
+ return yield* b({
1943
2070
  bytes: n.bytes,
1944
2071
  contentType: t?.contentType ?? n.contentType,
1945
2072
  ...t?.tenantId === void 0 ? {} : { tenantId: t.tenantId },
@@ -1954,39 +2081,40 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1954
2081
  ...t?.caption === void 0 ? {} : { caption: t.caption }
1955
2082
  });
1956
2083
  }), t?.abortSignal),
1957
- mintPresignedUpload: (e) => y.gen(function* () {
1958
- if (!a.getUploadUrl) return yield* y.fail(new t({
2084
+ mintPresignedUpload: (e) => v.gen(function* () {
2085
+ if (!a.getUploadUrl) return yield* v.fail(new t({
1959
2086
  provider: a.name,
1960
2087
  message: `provider '${a.name}' does not support presigned uploads`,
1961
2088
  transient: !1,
1962
2089
  status: 400
1963
2090
  }));
1964
- let n = e.expiresInSec ?? d, r = `_incoming/${k({
2091
+ let n = e.expiresInSec ?? d, r = `_incoming/${A({
1965
2092
  kind: "typeid",
1966
2093
  prefix: "up"
1967
- }, V)}`, i = m(e.tenantId ?? null, "", r);
2094
+ }, B)}`, i = m(e.tenantId ?? null, "", r);
1968
2095
  return {
1969
2096
  uploadUrl: yield* a.getUploadUrl(i, n, e.contentType),
1970
2097
  key: i,
1971
2098
  expiresInSec: n
1972
2099
  };
1973
2100
  }),
1974
- finalizeUpload: (e) => a.get(e.key).pipe(y.retry(p), y.flatMap((t) => _({
2101
+ finalizeUpload: (e) => a.get(e.key).pipe(v.retry(p), v.flatMap((t) => b({
1975
2102
  bytes: t.bytes,
1976
2103
  contentType: e.contentType,
1977
2104
  ...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
1978
2105
  ...e.ownerId === void 0 ? {} : { ownerId: e.ownerId },
1979
2106
  ...e.visibility === void 0 ? {} : { visibility: e.visibility },
2107
+ ...e.access === void 0 ? {} : { access: e.access },
1980
2108
  ...e.folder === void 0 ? {} : { folder: e.folder },
1981
2109
  ...e.tags === void 0 ? {} : { tags: e.tags },
1982
2110
  ...e.alt === void 0 ? {} : { alt: e.alt },
1983
2111
  ...e.caption === void 0 ? {} : { caption: e.caption }
1984
- })), y.ensuring(a.delete(e.key).pipe(y.retry(p), y.ignore))),
1985
- putResumableChunk: (e) => a.put(te(e.tenantId ?? null, e.uploadId, e.index), e.bytes, { contentType: "application/octet-stream" }).pipe(y.retry(p), y.asVoid),
1986
- resumableStatus: (e) => y.gen(function* () {
2112
+ })), v.ensuring(a.delete(e.key).pipe(v.retry(p), v.ignore))),
2113
+ putResumableChunk: (e) => a.put(te(e.tenantId ?? null, e.uploadId, e.index), e.bytes, { contentType: "application/octet-stream" }).pipe(v.retry(p), v.asVoid),
2114
+ resumableStatus: (e) => v.gen(function* () {
1987
2115
  let t = 0, n = 0;
1988
2116
  for (; t < 1e6;) {
1989
- let r = yield* a.head(te(e.tenantId ?? null, e.uploadId, t)).pipe(y.retry(p), y.catchAll(() => y.succeed(null)));
2117
+ let r = yield* a.head(te(e.tenantId ?? null, e.uploadId, t)).pipe(v.retry(p), v.catch(() => v.succeed(null)));
1990
2118
  if (r === null) break;
1991
2119
  n += r.size, t += 1;
1992
2120
  }
@@ -1995,42 +2123,42 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
1995
2123
  nextIndex: t
1996
2124
  };
1997
2125
  }),
1998
- finalizeResumable: (e) => y.gen(function* () {
2126
+ finalizeResumable: (e) => v.gen(function* () {
1999
2127
  let r = i.limits?.maxBytes ?? 2 ** 53 - 1;
2000
- if (!Number.isSafeInteger(r) || r < 0 || !Number.isSafeInteger(e.count) || e.count < 0) return yield* y.fail(new t({
2128
+ if (!Number.isSafeInteger(r) || r < 0 || !Number.isSafeInteger(e.count) || e.count < 0) return yield* v.fail(new t({
2001
2129
  provider: a.name,
2002
2130
  message: "resumable count and limits.maxBytes must be non-negative safe integers",
2003
2131
  transient: !1,
2004
2132
  status: 400
2005
2133
  }));
2006
- let o = (t) => te(e.tenantId ?? null, e.uploadId, t), s = y.gen(function* () {
2007
- for (let t = 0; t < e.count; t++) yield* a.delete(o(t)).pipe(y.retry(p), y.ignore);
2134
+ let o = (t) => te(e.tenantId ?? null, e.uploadId, t), s = v.gen(function* () {
2135
+ for (let t = 0; t < e.count; t++) yield* a.delete(o(t)).pipe(v.retry(p), v.ignore);
2008
2136
  }), c = () => new n({
2009
2137
  reason: "too-large",
2010
2138
  detail: `resumable upload exceeds ${r}-byte limit`
2011
- }), l = yield* y.gen(function* () {
2139
+ }), l = yield* v.gen(function* () {
2012
2140
  let n = 0;
2013
2141
  for (let i = 0; i < e.count; i++) {
2014
- let e = yield* a.head(o(i)).pipe(y.retry(p));
2015
- if (e === null) return yield* y.fail(new t({
2142
+ let e = yield* a.head(o(i)).pipe(v.retry(p));
2143
+ if (e === null) return yield* v.fail(new t({
2016
2144
  provider: a.name,
2017
2145
  message: `no resumable chunk at '${o(i)}'`,
2018
2146
  transient: !1,
2019
2147
  status: 404
2020
2148
  }));
2021
- if (!Number.isSafeInteger(e.size) || e.size < 0) return yield* y.fail(new t({
2149
+ if (!Number.isSafeInteger(e.size) || e.size < 0) return yield* v.fail(new t({
2022
2150
  provider: a.name,
2023
2151
  message: "resumable chunk metadata has an invalid size",
2024
2152
  transient: !1
2025
2153
  }));
2026
- if (e.size > r - n) return yield* y.fail(c());
2154
+ if (e.size > r - n) return yield* v.fail(c());
2027
2155
  n += e.size;
2028
2156
  }
2029
2157
  let i = /* @__PURE__ */ new Uint8Array(), s = 0;
2030
2158
  for (let t = 0; t < e.count; t++) {
2031
- let e = yield* Me(a, o(t)).pipe(y.retry(p));
2032
- yield* w.runForEach(e.stream, (e) => y.gen(function* () {
2033
- if (e.byteLength > r - s) return yield* y.fail(c());
2159
+ let e = yield* Ve(a, o(t)).pipe(v.retry(p));
2160
+ yield* C.runForEach(e.stream, (e) => v.gen(function* () {
2161
+ if (e.byteLength > r - s) return yield* v.fail(c());
2034
2162
  let t = s + e.byteLength;
2035
2163
  if (t > i.byteLength) {
2036
2164
  let e = new Uint8Array(Math.min(r, Math.max(65536, i.byteLength * 2, t)));
@@ -2040,60 +2168,61 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2040
2168
  }));
2041
2169
  }
2042
2170
  return i.subarray(0, s);
2043
- }).pipe(y.tapError((e) => e._tag === "StorageRejected" ? s : y.void));
2044
- return yield* _({
2171
+ }).pipe(v.tapError((e) => e._tag === "StorageRejected" ? s : v.void));
2172
+ return yield* b({
2045
2173
  bytes: l,
2046
2174
  contentType: e.contentType,
2047
2175
  ...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
2048
2176
  ...e.ownerId === void 0 ? {} : { ownerId: e.ownerId },
2049
2177
  ...e.visibility === void 0 ? {} : { visibility: e.visibility },
2178
+ ...e.access === void 0 ? {} : { access: e.access },
2050
2179
  ...e.folder === void 0 ? {} : { folder: e.folder },
2051
2180
  ...e.tags === void 0 ? {} : { tags: e.tags },
2052
2181
  ...e.alt === void 0 ? {} : { alt: e.alt },
2053
2182
  ...e.caption === void 0 ? {} : { caption: e.caption }
2054
- }).pipe(y.ensuring(s));
2183
+ }).pipe(v.ensuring(s));
2055
2184
  }),
2056
- transcode: (e, t) => g(e, t?.tenantId).pipe(y.flatMap((e) => x(e))),
2057
- renditions: (e, t) => g(e, t?.tenantId).pipe(y.flatMap(() => o.listByDerivedFrom(e))),
2058
- beginMultipartUpload: (e) => y.gen(function* () {
2059
- if (!a.createMultipartUpload || !a.presignUploadPart || !a.completeMultipartUpload) return yield* y.fail(new t({
2185
+ transcode: (e, t) => _(e, t?.tenantId).pipe(v.flatMap((e) => ae(e))),
2186
+ renditions: (e, t) => _(e, t?.tenantId).pipe(v.flatMap(() => o.listByDerivedFrom(e))),
2187
+ beginMultipartUpload: (e) => v.gen(function* () {
2188
+ if (!a.createMultipartUpload || !a.presignUploadPart || !a.completeMultipartUpload) return yield* v.fail(new t({
2060
2189
  provider: a.name,
2061
2190
  message: `provider '${a.name}' does not support multipart uploads`,
2062
2191
  transient: !1,
2063
2192
  status: 400
2064
2193
  }));
2065
- let n = m(e.tenantId ?? null, "", `multipart/${k({
2194
+ let n = m(e.tenantId ?? null, "", `multipart/${A({
2066
2195
  kind: "typeid",
2067
2196
  prefix: "mp"
2068
- }, V)}`);
2197
+ }, B)}`);
2069
2198
  return {
2070
2199
  uploadId: (yield* a.createMultipartUpload(n, e.contentType, { public: (e.visibility ?? "private") === "public" })).uploadId,
2071
2200
  key: n
2072
2201
  };
2073
2202
  }),
2074
- signMultipartPart: (e) => y.suspend(() => a.presignUploadPart ? a.presignUploadPart(e.key, e.uploadId, e.partNumber, e.expiresInSec ?? d) : y.fail(new t({
2203
+ signMultipartPart: (e) => v.suspend(() => a.presignUploadPart ? a.presignUploadPart(e.key, e.uploadId, e.partNumber, e.expiresInSec ?? d) : v.fail(new t({
2075
2204
  provider: a.name,
2076
2205
  message: "provider does not support multipart uploads",
2077
2206
  transient: !1,
2078
2207
  status: 400
2079
2208
  }))),
2080
- completeMultipart: (e) => y.gen(function* () {
2081
- if (!a.completeMultipartUpload) return yield* y.fail(new t({
2209
+ completeMultipart: (e) => v.gen(function* () {
2210
+ if (!a.completeMultipartUpload) return yield* v.fail(new t({
2082
2211
  provider: a.name,
2083
2212
  message: "provider does not support multipart uploads",
2084
2213
  transient: !1,
2085
2214
  status: 400
2086
2215
  }));
2087
- let r = yield* a.completeMultipartUpload(e.key, e.uploadId, e.parts), s = yield* a.head(e.key).pipe(y.retry(p)), l = s?.size ?? 0, u = (r.etag ?? s?.etag ?? "").replace(/"/g, ""), d = e.tenantId ?? null, f = {
2216
+ let r = yield* a.completeMultipartUpload(e.key, e.uploadId, e.parts), s = yield* a.head(e.key).pipe(v.retry(p)), l = s?.size ?? 0, u = (r.etag ?? s?.etag ?? "").replace(/"/g, ""), d = e.tenantId ?? null, f = {
2088
2217
  bytes: l,
2089
2218
  count: 1
2090
2219
  };
2091
- if (!(yield* o.consumeUsage(d, f, i.quota)).allowed) return yield* a.delete(e.key).pipe(y.retry(p), y.ignore), yield* y.fail(new n({
2220
+ if (!(yield* o.consumeUsage(d, f, i.quota)).allowed) return yield* a.delete(e.key).pipe(v.retry(p), v.ignore), yield* v.fail(new n({
2092
2221
  reason: "quota-exceeded",
2093
2222
  detail: `multipart upload of ${l} bytes exceeds tenant quota`
2094
2223
  }));
2095
2224
  let m = {
2096
- id: Qt(),
2225
+ id: pn(),
2097
2226
  tenantId: e.tenantId ?? null,
2098
2227
  ownerId: e.ownerId ?? null,
2099
2228
  bucket: c,
@@ -2102,7 +2231,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2102
2231
  size: l,
2103
2232
  checksum: u,
2104
2233
  visibility: e.visibility ?? "private",
2105
- accessPolicy: null,
2234
+ accessPolicy: e.access ?? null,
2106
2235
  passwordHash: null,
2107
2236
  createdAt: /* @__PURE__ */ new Date(),
2108
2237
  ...e.folder === void 0 ? {} : { folder: e.folder },
@@ -2110,22 +2239,22 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2110
2239
  ...e.alt === void 0 ? {} : { alt: e.alt },
2111
2240
  ...e.caption === void 0 ? {} : { caption: e.caption }
2112
2241
  };
2113
- return yield* o.insert(m).pipe(y.onExit((e) => b.isSuccess(e) ? y.void : o.releaseUsage(d, f).pipe(y.ignore))), m;
2242
+ return yield* o.insert(m).pipe(v.onExit((e) => y.isSuccess(e) ? v.void : o.releaseUsage(d, f).pipe(v.ignore))), m;
2114
2243
  }),
2115
- abortMultipart: (e) => y.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(y.retry(p)) : y.void)
2244
+ abortMultipart: (e) => v.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(v.retry(p)) : v.void)
2116
2245
  };
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, {
2246
+ }, gn = (e) => b.succeed(i, hn(e)), _n = "_voltro_storage_operation_locks", Q = "_voltro_storage_object_heads", vn = "_voltro_storage_operations", yn = "_voltro_storage_object_claims", bn = [
2247
+ P(_n, {
2119
2248
  id: F().maxLength(64),
2120
2249
  nonce: F()
2121
2250
  }).primaryKey(["id"]).nonReactive(),
2122
- P(Z, {
2251
+ P(Q, {
2123
2252
  id: F().maxLength(64),
2124
2253
  generation: F(),
2125
2254
  key: F(),
2126
- reservations: A()
2255
+ reservations: E()
2127
2256
  }).primaryKey(["id"]).nonReactive(),
2128
- P(rn, {
2257
+ P(vn, {
2129
2258
  id: F().maxLength(64),
2130
2259
  objectId: F().maxLength(64),
2131
2260
  fingerprint: F().maxLength(64),
@@ -2135,90 +2264,98 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2135
2264
  state: F(),
2136
2265
  deleteKey: F().nullable()
2137
2266
  }).primaryKey(["id"]).nonReactive(),
2138
- P(an, {
2267
+ P(yn, {
2139
2268
  id: F().maxLength(64),
2140
2269
  operationId: F().maxLength(64),
2141
2270
  claim: F()
2142
2271
  }).primaryKey(["id"]).nonReactive()
2143
- ], sn = C.Struct({
2144
- id: C.String,
2145
- objectId: C.String,
2146
- fingerprint: C.String,
2147
- generation: C.String,
2148
- key: C.String,
2149
- refId: C.String,
2150
- state: C.Literal("reserved", "ready", "deleting", "deleted"),
2151
- deleteKey: C.NullOr(C.String)
2152
- }), cn = C.Struct({
2153
- id: C.String,
2154
- generation: C.String,
2155
- key: C.String,
2156
- reservations: C.Int.pipe(C.nonNegative())
2157
- }), ln = (e) => he("sha256").update(JSON.stringify(e)).digest("hex"), un = (e, t) => ln([e, t]), dn = (e) => {
2272
+ ], xn = S.Struct({
2273
+ id: S.String,
2274
+ objectId: S.String,
2275
+ fingerprint: S.String,
2276
+ generation: S.String,
2277
+ key: S.String,
2278
+ refId: S.String,
2279
+ state: S.Literals([
2280
+ "reserved",
2281
+ "ready",
2282
+ "deleting",
2283
+ "deleted"
2284
+ ]),
2285
+ deleteKey: S.NullOr(S.String)
2286
+ }), Sn = S.Struct({
2287
+ id: S.String,
2288
+ generation: S.String,
2289
+ key: S.String,
2290
+ reservations: S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(0)))
2291
+ }), Cn = (e) => S.decodeUnknownSync(Sn)({
2292
+ ...e,
2293
+ reservations: W(e.reservations, "shared-object reservation count")
2294
+ }), wn = (e) => Ce("sha256").update(JSON.stringify(e)).digest("hex"), Tn = (e, t) => wn([e, t]), En = (e) => {
2158
2295
  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");
2159
2296
  return {
2160
- id: ln([
2297
+ id: wn([
2161
2298
  e.bucket,
2162
2299
  e.tenantId,
2163
2300
  e.operationId
2164
2301
  ]),
2165
- objectId: ln([
2302
+ objectId: wn([
2166
2303
  e.bucket,
2167
2304
  e.tenantId,
2168
2305
  e.logicalKey,
2169
2306
  e.checksum
2170
2307
  ]),
2171
- lockId: ln([e.tenantId])
2308
+ lockId: wn([e.tenantId])
2172
2309
  };
2173
- }, fn = async (e, t, n) => {
2174
- let { lockId: r } = dn(t);
2175
- return await e.insertIgnoreWithOutcome(nn, {
2310
+ }, Dn = async (e, t, n) => {
2311
+ let { lockId: r } = En(t);
2312
+ return await e.insertIgnoreWithOutcome(_n, {
2176
2313
  id: r,
2177
- nonce: _e()
2314
+ nonce: Te()
2178
2315
  }, { conflictColumns: ["id"] }), e.transactional(async (e) => {
2179
2316
  if ((await e.query({
2180
- table: nn,
2181
- predicate: O("id", r),
2317
+ table: _n,
2318
+ predicate: k("id", r),
2182
2319
  lock: "update",
2183
2320
  order: [],
2184
2321
  take: 1,
2185
2322
  skip: void 0,
2186
2323
  projection: void 0
2187
- })).length !== 1 || await e.update(nn, r, { nonce: _e() }) === null) throw Error("Storage operation lock is unavailable");
2324
+ })).length !== 1 || await e.update(_n, r, { nonce: Te() }) === null) throw Error("Storage operation lock is unavailable");
2188
2325
  return n(e);
2189
2326
  });
2190
- }, Q = async (e, t) => {
2191
- let r = dn(t), i = await e.query({
2192
- table: rn,
2193
- predicate: O("id", r.id),
2327
+ }, $ = async (e, t) => {
2328
+ let r = En(t), i = await e.query({
2329
+ table: vn,
2330
+ predicate: k("id", r.id),
2194
2331
  order: [],
2195
2332
  take: 1,
2196
2333
  skip: void 0,
2197
2334
  projection: void 0
2198
2335
  });
2199
2336
  if (!i[0]) return;
2200
- let a = C.decodeUnknownSync(sn)(i[0]);
2337
+ let a = S.decodeUnknownSync(xn)(i[0]);
2201
2338
  if (a.fingerprint !== t.fingerprint || a.objectId !== r.objectId) throw new n({
2202
2339
  reason: "operation-identity-reused",
2203
2340
  detail: `storage operation '${t.operationId}' was already used with different inputs`
2204
2341
  });
2205
2342
  return a;
2206
- }, pn = async (e, t) => {
2207
- let n = await Q(e, t);
2343
+ }, On = async (e, t) => {
2344
+ let n = await $(e, t);
2208
2345
  if (n) return n;
2209
- let { id: r, objectId: i } = dn(t), a = await e.query({
2210
- table: Z,
2211
- predicate: O("id", i),
2346
+ let { id: r, objectId: i } = En(t), a = await e.query({
2347
+ table: Q,
2348
+ predicate: k("id", i),
2212
2349
  order: [],
2213
2350
  take: 1,
2214
2351
  skip: void 0,
2215
2352
  projection: void 0
2216
- }), o = a[0] ? C.decodeUnknownSync(cn)(a[0]) : void 0, s = o?.generation ?? _e(), c = o?.key ?? `${t.logicalKey}/g-${s}`;
2217
- o ? await e.update(Z, i, { reservations: o.reservations + 1 }) : await e.insert(Z, {
2353
+ }), o = a[0] ? Cn(a[0]) : void 0, s = o?.generation ?? Te(), c = o?.key ?? `${t.logicalKey}/g-${s}`;
2354
+ o ? await e.update(Q, i, { reservations: String(Je(o.reservations, 1, "shared-object reservation count")) }) : await e.insert(Q, {
2218
2355
  id: i,
2219
2356
  generation: s,
2220
2357
  key: c,
2221
- reservations: 1
2358
+ reservations: "1"
2222
2359
  });
2223
2360
  let l = {
2224
2361
  id: r,
@@ -2226,35 +2363,35 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2226
2363
  fingerprint: t.fingerprint,
2227
2364
  generation: s,
2228
2365
  key: c,
2229
- refId: `file_${_e()}`,
2366
+ refId: `file_${Te()}`,
2230
2367
  state: "reserved",
2231
2368
  deleteKey: null
2232
2369
  };
2233
- return await e.insert(rn, l), l;
2234
- }, mn = async (e, t) => {
2235
- let n = await Q(e, t);
2370
+ return await e.insert(vn, l), l;
2371
+ }, kn = async (e, t) => {
2372
+ let n = await $(e, t);
2236
2373
  if (!n) throw Error("Storage operation is missing");
2237
2374
  if (n.state === "deleting" || n.state === "deleted") throw Error("Deleted storage operation cannot be confirmed by a late put");
2238
- return await e.update(rn, n.id, { state: "ready" }), {
2375
+ return await e.update(vn, n.id, { state: "ready" }), {
2239
2376
  ...n,
2240
2377
  state: "ready"
2241
2378
  };
2242
- }, hn = async (e, t) => {
2243
- let n = await Q(e, t);
2379
+ }, An = async (e, t) => {
2380
+ let n = await $(e, t);
2244
2381
  if (!n) throw Error("Storage operation is missing");
2245
2382
  if (n.state === "deleting" || n.state === "deleted") return n;
2246
2383
  if (n.state !== "ready") throw Error("An unconfirmed put cannot be deleted");
2247
2384
  let r = await e.query({
2248
- table: Z,
2249
- predicate: O("id", n.objectId),
2385
+ table: Q,
2386
+ predicate: k("id", n.objectId),
2250
2387
  order: [],
2251
2388
  take: 1,
2252
2389
  skip: void 0,
2253
2390
  projection: void 0
2254
- }), i = r[0] ? C.decodeUnknownSync(cn)(r[0]) : void 0;
2391
+ }), i = r[0] ? Cn(r[0]) : void 0;
2255
2392
  if (!i || i.generation !== n.generation || i.reservations < 1) throw Error("Storage object generation does not own its reservation");
2256
2393
  let a = i.reservations === 1 ? i.key : null;
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, {
2394
+ return a === null ? await e.update(Q, i.id, { reservations: String(i.reservations - 1) }) : await e.delete(Q, i.id), await e.update(vn, n.id, {
2258
2395
  state: "deleting",
2259
2396
  deleteKey: a
2260
2397
  }), {
@@ -2262,46 +2399,46 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2262
2399
  state: "deleting",
2263
2400
  deleteKey: a
2264
2401
  };
2265
- }, gn = async (e, t) => {
2266
- let n = await Q(e, t);
2402
+ }, jn = async (e, t) => {
2403
+ let n = await $(e, t);
2267
2404
  if (!n || n.state !== "deleting" && n.state !== "deleted") throw Error("Storage deletion has not been accepted");
2268
- return n.state !== "deleted" && (await e.update(rn, n.id, { state: "deleted" }), !0);
2269
- }, _n = async (e, t, n) => {
2405
+ return n.state !== "deleted" && (await e.update(vn, n.id, { state: "deleted" }), !0);
2406
+ }, Mn = async (e, t, n) => {
2270
2407
  if (!n) throw Error("Storage object claim must be a non-empty string");
2271
- await e.insertIgnoreWithOutcome(an, {
2272
- id: un(t, n),
2408
+ await e.insertIgnoreWithOutcome(yn, {
2409
+ id: Tn(t, n),
2273
2410
  operationId: t,
2274
2411
  claim: n
2275
2412
  }, { conflictColumns: ["id"] });
2276
- }, vn = async (e, t, n) => {
2277
- let r = un(t, n);
2413
+ }, Nn = async (e, t, n) => {
2414
+ let r = Tn(t, n);
2278
2415
  return {
2279
- held: await e.delete(an, r),
2416
+ held: await e.delete(yn, r),
2280
2417
  others: (await e.query({
2281
- table: an,
2282
- predicate: E(O("operationId", t), M("claim", n)),
2418
+ table: yn,
2419
+ predicate: ue(k("operationId", t), ve("claim", n)),
2283
2420
  order: [],
2284
2421
  take: 1,
2285
2422
  skip: void 0,
2286
2423
  projection: void 0
2287
2424
  })).length > 0
2288
2425
  };
2289
- }, yn = (e, t) => e.deleteMany(an, { where: O("operationId", t) }), bn = "_voltro_storage_put_intents", xn = P(bn, {
2426
+ }, Pn = (e, t) => e.deleteMany(yn, { where: k("operationId", t) }), Fn = "_voltro_storage_put_intents", In = P(Fn, {
2290
2427
  id: F().maxLength(64),
2291
2428
  refId: F().maxLength(64),
2292
- identity: j(),
2293
- ref: j()
2294
- }).primaryKey(["id"]).unique("storagePutRef", ["refId"]).nonReactive(), Sn = C.Struct({
2295
- tenantId: C.NullOr(C.String),
2296
- bucket: C.String,
2297
- operationId: C.String,
2298
- fingerprint: C.String,
2299
- checksum: C.String,
2300
- logicalKey: C.String
2301
- }), Cn = async (e, t) => {
2429
+ identity: ge(),
2430
+ ref: ge()
2431
+ }).primaryKey(["id"]).unique("storagePutRef", ["refId"]).nonReactive(), Ln = S.Struct({
2432
+ tenantId: S.NullOr(S.String),
2433
+ bucket: S.String,
2434
+ operationId: S.String,
2435
+ fingerprint: S.String,
2436
+ checksum: S.String,
2437
+ logicalKey: S.String
2438
+ }), Rn = async (e, t) => {
2302
2439
  let n = await e.query({
2303
- table: bn,
2304
- predicate: O("refId", t),
2440
+ table: Fn,
2441
+ predicate: k("refId", t),
2305
2442
  order: [],
2306
2443
  take: 2,
2307
2444
  skip: void 0,
@@ -2309,44 +2446,44 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2309
2446
  });
2310
2447
  if (n.length === 0) return;
2311
2448
  if (n.length !== 1) throw Error("Storage reference has ambiguous operation ownership");
2312
- let r = n[0], i = C.decodeUnknownSync(Sn)(r.identity);
2449
+ let r = n[0], i = S.decodeUnknownSync(Ln)(r.identity);
2313
2450
  if (typeof r.ref != "object" || r.ref === null || Array.isArray(r.ref)) throw Error("Storage operation reference is unreadable");
2314
- let a = Y(r.ref);
2451
+ let a = X(r.ref);
2315
2452
  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");
2316
2453
  return {
2317
2454
  identity: i,
2318
2455
  ref: a
2319
2456
  };
2320
- }, wn = (e) => ({
2321
- intent: (t) => Cn(e, t),
2322
- reserve: (t, r, i, a) => fn(e, t, async (e) => {
2457
+ }, zn = (e) => ({
2458
+ intent: (t) => Rn(e, t),
2459
+ reserve: (t, r, i, a) => Dn(e, t, async (e) => {
2323
2460
  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");
2324
- let o = await Q(e, t);
2461
+ let o = await $(e, t);
2325
2462
  if (o) {
2326
2463
  if (o.state === "deleting" || o.state === "deleted") throw Error("Storage put identity has already been deleted");
2327
- let t = await Cn(e, o.refId);
2464
+ let t = await Rn(e, o.refId);
2328
2465
  if (!t) throw Error("Storage operation lost its put intent");
2329
2466
  let n = o.state === "ready";
2330
- return n && a !== void 0 && await _n(e, o.id, a), {
2467
+ return n && a !== void 0 && await Mn(e, o.id, a), {
2331
2468
  ref: t.ref,
2332
2469
  ready: n,
2333
2470
  outcome: n ? "joined" : "resumed"
2334
2471
  };
2335
2472
  }
2336
- let s = await pn(e, t), c = Jt(e);
2337
- if (!(await y.runPromise(c.consumeUsage(t.tenantId, {
2473
+ let s = await On(e, t), c = ln(e);
2474
+ if (!(await v.runPromise(c.consumeUsage(t.tenantId, {
2338
2475
  bytes: r.size,
2339
2476
  count: 1
2340
2477
  }, i))).allowed) throw new n({
2341
2478
  reason: "quota-exceeded",
2342
2479
  detail: "Storage operation exceeds tenant quota"
2343
2480
  });
2344
- let l = Y({
2481
+ let l = X({
2345
2482
  ...r,
2346
2483
  id: s.refId,
2347
2484
  key: s.key
2348
2485
  });
2349
- return await e.insert(bn, {
2486
+ return await e.insert(Fn, {
2350
2487
  id: s.id,
2351
2488
  refId: l.id,
2352
2489
  identity: t,
@@ -2357,31 +2494,31 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2357
2494
  outcome: "created"
2358
2495
  };
2359
2496
  }),
2360
- confirm: (t, n) => fn(e, t, async (e) => {
2361
- let r = await Q(e, t);
2497
+ confirm: (t, n) => Dn(e, t, async (e) => {
2498
+ let r = await $(e, t);
2362
2499
  if (!r) throw Error("Storage put operation is missing");
2363
- let i = await Cn(e, r.refId);
2500
+ let i = await Rn(e, r.refId);
2364
2501
  if (!i) throw Error("Storage put intent is missing");
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));
2502
+ if (n !== void 0 && await Mn(e, r.id, n), r.state === "ready") {
2503
+ let n = await v.runPromise(ln(e).getById(r.refId));
2367
2504
  if (!n || n.key !== r.key || n.checksum !== t.checksum) throw Error("Confirmed storage operation lost its reference");
2368
2505
  return n;
2369
2506
  }
2370
- return await mn(e, t), await y.runPromise(Jt(e).insert(i.ref)), i.ref;
2507
+ return await kn(e, t), await v.runPromise(ln(e).insert(i.ref)), i.ref;
2371
2508
  }),
2372
2509
  beginDelete: async (t, r, i) => {
2373
- let a = await Cn(e, t);
2510
+ let a = await Rn(e, t);
2374
2511
  if (!a) throw Error("Storage delete operation is missing");
2375
2512
  if (r !== void 0 && a.identity.tenantId !== r) throw Error("Storage delete tenant mismatch");
2376
- return fn(e, a.identity, async (e) => {
2377
- let r = await Cn(e, t);
2513
+ return Dn(e, a.identity, async (e) => {
2514
+ let r = await Rn(e, t);
2378
2515
  if (!r) throw Error("Storage delete intent disappeared");
2379
- let a = await Q(e, r.identity);
2516
+ let a = await $(e, r.identity);
2380
2517
  if (!a) throw Error("Storage delete lost its operation");
2381
2518
  let o = a.state !== "deleting" && a.state !== "deleted";
2382
- if (i === void 0) o && await yn(e, a.id);
2519
+ if (i === void 0) o && await Pn(e, a.id);
2383
2520
  else if (o) {
2384
- let o = await vn(e, a.id, i);
2521
+ let o = await Nn(e, a.id, i);
2385
2522
  if (o.others) return {
2386
2523
  released: !0,
2387
2524
  identity: r.identity
@@ -2391,11 +2528,11 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2391
2528
  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`
2392
2529
  });
2393
2530
  }
2394
- let s = await hn(e, r.identity);
2531
+ let s = await An(e, r.identity);
2395
2532
  if (a.state === "ready") {
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");
2398
- await y.runPromise(n.releaseUsage(r.identity.tenantId, {
2533
+ let n = ln(e);
2534
+ if (await v.runPromise(fn(e).deleteByRef(t)), !await v.runPromise(n.delete(t))) throw Error("Storage deletion lost its confirmed reference");
2535
+ await v.runPromise(n.releaseUsage(r.identity.tenantId, {
2399
2536
  bytes: r.ref.size,
2400
2537
  count: 1
2401
2538
  }));
@@ -2407,8 +2544,8 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2407
2544
  };
2408
2545
  });
2409
2546
  },
2410
- confirmDelete: (t) => fn(e, t, (e) => gn(e, t))
2411
- }), Tn = (e, t = 65536) => {
2547
+ confirmDelete: (t) => Dn(e, t, (e) => jn(e, t))
2548
+ }), Bn = (e, t = 65536) => {
2412
2549
  let n = [Buffer.from("zINSTREAM\0", "utf8")];
2413
2550
  for (let r = 0; r < e.length; r += t) {
2414
2551
  let i = e.subarray(r, Math.min(r + t, e.length)), a = Buffer.alloc(4);
@@ -2416,7 +2553,7 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2416
2553
  }
2417
2554
  let r = Buffer.alloc(4);
2418
2555
  return r.writeUInt32BE(0, 0), n.push(r), Buffer.concat(n);
2419
- }, En = (e) => {
2556
+ }, Vn = (e) => {
2420
2557
  let t = e.replace(/\0+$/, "").trim();
2421
2558
  if (/\bOK$/.test(t)) return { clean: !0 };
2422
2559
  let n = /:\s*(.+?)\s+FOUND$/.exec(t);
@@ -2425,8 +2562,8 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2425
2562
  threat: n[1] ?? "unknown"
2426
2563
  };
2427
2564
  throw Error(`clamav: unexpected response: ${t}`);
2428
- }, Dn = async (e, t) => {
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;
2565
+ }, Hn = async (e, t) => {
2566
+ let n = await import("node:net"), r = U.read("CLAMAV_HOST", t.host) ?? "127.0.0.1", i = U.read("CLAMAV_PORT"), a = t.port ?? (i ? Number(i) : 3310), o = t.timeoutMs ?? 3e4;
2430
2567
  return new Promise((i, s) => {
2431
2568
  let c = n.createConnection({
2432
2569
  host: r,
@@ -2437,20 +2574,20 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2437
2574
  c.on("error", (e) => {
2438
2575
  clearTimeout(u), s(e);
2439
2576
  }), c.on("connect", () => {
2440
- c.end(Tn(e, t.chunkSize));
2577
+ c.end(Bn(e, t.chunkSize));
2441
2578
  }), c.on("data", (e) => {
2442
2579
  l += e.toString("utf8");
2443
2580
  }), c.on("close", () => {
2444
2581
  clearTimeout(u);
2445
2582
  try {
2446
- i(En(l));
2583
+ i(Vn(l));
2447
2584
  } catch (e) {
2448
2585
  s(e);
2449
2586
  }
2450
2587
  });
2451
2588
  });
2452
- }, On = (e = {}) => (t) => Dn(t.bytes, e), kn = (e, t, n) => new Promise((r, i) => {
2453
- let a = ye(e, [...t], { stdio: [
2589
+ }, Un = (e = {}) => (t) => Hn(t.bytes, e), Wn = (e, t, n) => new Promise((r, i) => {
2590
+ let a = Oe(e, [...t], { stdio: [
2454
2591
  "ignore",
2455
2592
  "ignore",
2456
2593
  "pipe"
@@ -2464,31 +2601,31 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2464
2601
  }), a.on("close", (e) => {
2465
2602
  clearTimeout(s), e === 0 ? r() : i(/* @__PURE__ */ Error(`ffmpeg exited ${String(e)}: ${o.slice(-400)}`));
2466
2603
  });
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 = [];
2604
+ }), Gn = (e) => async ({ bytes: t }) => {
2605
+ let n = e.ffmpegPath ?? "ffmpeg", r = e.timeoutMs ?? 3e5, i = await R(Me(je(), "voltro-tc-")), a = Me(i, "in"), o = [];
2469
2606
  try {
2470
- await Ce(a, t);
2607
+ await Ae(a, t);
2471
2608
  for (let t of e.renditions) {
2472
- let e = z(i, `out.${t.ext}`);
2609
+ let e = Me(i, `out.${t.ext}`);
2473
2610
  try {
2474
- await kn(n, [
2611
+ await Wn(n, [
2475
2612
  "-y",
2476
2613
  "-i",
2477
2614
  a,
2478
2615
  ...t.args,
2479
2616
  e
2480
2617
  ], r);
2481
- let i = await xe(e);
2618
+ let i = await z(e);
2482
2619
  o.push({
2483
2620
  bytes: new Uint8Array(i),
2484
2621
  contentType: t.contentType,
2485
2622
  kind: t.kind,
2486
2623
  ...t.label === void 0 ? {} : { label: t.label }
2487
- }), await Se(e, { force: !0 });
2624
+ }), await ke(e, { force: !0 });
2488
2625
  } catch {}
2489
2626
  }
2490
2627
  } finally {
2491
- await Se(i, {
2628
+ await ke(i, {
2492
2629
  recursive: !0,
2493
2630
  force: !0
2494
2631
  }).catch(() => void 0);
@@ -2497,21 +2634,21 @@ var Te = 1 << 20, Ee = (e, n, r = !1) => new t({
2497
2634
  };
2498
2635
  //#endregion
2499
2636
  //#region src/assetRef.ts
2500
- function jn(e = {}) {
2501
- let t = e.nullable ?? !0, n = e.fk === !1 ? F().externalId() : fe(() => Fe, { onDelete: e.onDelete ?? "setNull" });
2637
+ function Kn(e = {}) {
2638
+ let t = e.nullable ?? !0, n = e.fk === !1 ? F().externalId() : ye(() => We, { onDelete: e.onDelete ?? "setNull" });
2502
2639
  return t ? n.nullable() : n;
2503
2640
  }
2504
- var Mn = () => de({
2641
+ var qn = () => _e({
2505
2642
  id: "@voltro/plugin-storage/withStorage",
2506
- fields: { asset: jn() }
2507
- }), Nn = {
2643
+ fields: { asset: Kn() }
2644
+ }), Jn = {
2508
2645
  "image/png": "png",
2509
2646
  "image/jpeg": "jpg",
2510
2647
  "image/jpg": "jpg",
2511
2648
  "image/gif": "gif",
2512
2649
  "image/webp": "webp",
2513
2650
  "image/svg+xml": "svg"
2514
- }, Pn = (e) => {
2651
+ }, Yn = (e) => {
2515
2652
  let t = /^data:([^;,]+)(;base64)?,(.*)$/s.exec(e);
2516
2653
  if (!t) throw Error("not a data URI");
2517
2654
  let n = t[1] || "application/octet-stream", r = !!t[2], i = t[3] ?? "";
@@ -2519,16 +2656,16 @@ var Mn = () => de({
2519
2656
  bytes: r ? new Uint8Array(Buffer.from(i, "base64")) : new Uint8Array(Buffer.from(decodeURIComponent(i), "utf8")),
2520
2657
  contentType: n
2521
2658
  };
2522
- }, Fn = (e, n) => y.gen(function* () {
2523
- let r = yield* y.try({
2524
- try: () => Pn(n.dataUri),
2659
+ }, Xn = (e, n) => v.gen(function* () {
2660
+ let r = yield* v.try({
2661
+ try: () => Yn(n.dataUri),
2525
2662
  catch: (e) => new t({
2526
2663
  provider: "avatar",
2527
2664
  message: String(e?.message ?? e),
2528
2665
  transient: !1,
2529
2666
  status: 400
2530
2667
  })
2531
- }), i = Nn[r.contentType] ?? "bin";
2668
+ }), i = Jn[r.contentType] ?? "bin";
2532
2669
  return yield* e.put({
2533
2670
  bytes: r.bytes,
2534
2671
  contentType: r.contentType,
@@ -2537,27 +2674,27 @@ var Mn = () => de({
2537
2674
  visibility: "public",
2538
2675
  key: `avatars/${n.userId}/avatar.${i}`
2539
2676
  });
2540
- }), In = (e) => {
2677
+ }), Zn = (e) => {
2541
2678
  try {
2542
- let t = B(e), n = B("/");
2679
+ let t = Ne(e), n = Ne("/");
2543
2680
  return typeof t.dev != "number" || typeof n.dev != "number" ? "unknown" : t.dev === n.dev ? "same-device-as-root" : "separate-mount";
2544
2681
  } catch {
2545
2682
  return "unknown";
2546
2683
  }
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
2684
+ }, Qn = (e) => {
2685
+ if (Zn(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
2549
2686
  dies with it — which is the exact failure it exists for. On a development machine this is normal
2550
2687
  and can be ignored.`;
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) => {
2688
+ }, $n = U.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", er, tr = (e) => {
2689
+ er = e;
2690
+ }, nr = () => er ?? ir({}), rr = () => er === void 0 ? U.read("STORAGE_PROVIDER") === void 0 ? void 0 : ir({}) : er, ir = (e) => {
2554
2691
  if (e.provider && typeof e.provider == "object") return e.provider;
2555
- let t = (e.provider ?? W.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = W.read("S3_BUCKET", e.bucket) ?? W.read("STORAGE_BUCKET") ?? "voltro";
2692
+ let t = (e.provider ?? U.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = U.read("S3_BUCKET", e.bucket) ?? U.read("STORAGE_BUCKET") ?? "voltro";
2556
2693
  switch (t) {
2557
2694
  case "s3":
2558
2695
  case "minio": {
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);
2560
- return Ge({
2696
+ let r = U.read("S3_REGION", e.region) ?? U.read("AWS_REGION"), i = U.read("S3_ENDPOINT", e.endpoint) ?? U.read("MINIO_ENDPOINT"), a = U.read("S3_ACCESS_KEY_ID", e.accessKeyId) ?? U.read("AWS_ACCESS_KEY_ID"), o = U.read("S3_SECRET_ACCESS_KEY", e.secretAccessKey) ?? U.read("AWS_SECRET_ACCESS_KEY"), s = U.read("STORAGE_CDN_URL", e.cdnBaseUrl);
2697
+ return nt({
2561
2698
  bucket: n,
2562
2699
  name: t,
2563
2700
  ...r ? { region: r } : {},
@@ -2566,13 +2703,13 @@ var Mn = () => de({
2566
2703
  ...o ? { secretAccessKey: o } : {},
2567
2704
  ...s ? { cdnBaseUrl: s } : {},
2568
2705
  ...e.publicAcl === void 0 ? {} : { publicAcl: e.publicAcl },
2569
- ...t === "minio" || W.read("S3_FORCE_PATH_STYLE") === "1" ? { forcePathStyle: !0 } : {}
2706
+ ...t === "minio" || U.read("S3_FORCE_PATH_STYLE") === "1" ? { forcePathStyle: !0 } : {}
2570
2707
  });
2571
2708
  }
2572
2709
  case "azure": {
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);
2574
- return Je({
2575
- container: W.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
2710
+ let t = U.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = U.read("AZURE_STORAGE_KEY", e.accountKey), i = U.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString), a = U.read("AZURE_STORAGE_ENDPOINT", e.endpoint), o = U.read("STORAGE_CDN_URL", e.cdnBaseUrl);
2711
+ return at({
2712
+ container: U.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
2576
2713
  ...t ? { accountName: t } : {},
2577
2714
  ...r ? { accountKey: r } : {},
2578
2715
  ...i ? { connectionString: i } : {},
@@ -2580,11 +2717,11 @@ var Mn = () => de({
2580
2717
  ...o ? { cdnBaseUrl: o } : {}
2581
2718
  });
2582
2719
  }
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");
2720
+ case "database": return it();
2721
+ case "filesystem": return tt({ root: U.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
2722
+ default: return et(e.name ?? "default");
2586
2723
  }
2587
- }, Wn = (e) => {
2724
+ }, ar = (e) => {
2588
2725
  let t = "stored files (uploads, renditions) and their reads", n = "provider 'database' or 'filesystem' keeps the bytes inside the installation";
2589
2726
  if (e.provider && typeof e.provider == "object") return [{
2590
2727
  destination: `runtime:the '${e.provider.name}' storage provider`,
@@ -2592,9 +2729,9 @@ var Mn = () => de({
2592
2729
  data: ["files"],
2593
2730
  disable: n
2594
2731
  }];
2595
- let r = (e.provider ?? W.read("STORAGE_PROVIDER") ?? "memory").toLowerCase();
2732
+ let r = (e.provider ?? U.read("STORAGE_PROVIDER") ?? "memory").toLowerCase();
2596
2733
  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";
2734
+ let r = U.read("S3_ENDPOINT", e.endpoint) ?? U.read("MINIO_ENDPOINT"), i = U.read("S3_REGION", e.region) ?? U.read("AWS_REGION") ?? "us-east-1";
2598
2735
  return [{
2599
2736
  destination: r ?? `s3.${i}.amazonaws.com`,
2600
2737
  purpose: t,
@@ -2603,7 +2740,7 @@ var Mn = () => de({
2603
2740
  }];
2604
2741
  }
2605
2742
  if (r === "azure") {
2606
- let r = W.read("AZURE_STORAGE_ENDPOINT", e.endpoint), i = W.read("AZURE_STORAGE_ACCOUNT", e.accountName);
2743
+ let r = U.read("AZURE_STORAGE_ENDPOINT", e.endpoint), i = U.read("AZURE_STORAGE_ACCOUNT", e.accountName);
2607
2744
  return [{
2608
2745
  destination: r ?? (i === void 0 ? "runtime:the Azure storage connection string" : `${i}.blob.core.windows.net`),
2609
2746
  purpose: t,
@@ -2612,11 +2749,11 @@ var Mn = () => de({
2612
2749
  }];
2613
2750
  }
2614
2751
  return [];
2615
- }, Gn = (e) => {
2752
+ }, or = (e) => {
2616
2753
  if (e !== void 0) return e;
2617
- let t = W.read("STORAGE_ALLOWED_ORIGINS");
2754
+ let t = U.read("STORAGE_ALLOWED_ORIGINS");
2618
2755
  return t ? t.trim() === "*" ? "*" : t.split(",").map((e) => e.trim()).filter(Boolean) : [];
2619
- }, Kn = (e, t) => {
2756
+ }, sr = (e, t) => {
2620
2757
  if (!e || t !== "*" && !t.includes(e)) return {};
2621
2758
  let n = {
2622
2759
  "access-control-allow-origin": t === "*" ? "*" : e,
@@ -2626,7 +2763,7 @@ var Mn = () => de({
2626
2763
  vary: "Origin"
2627
2764
  };
2628
2765
  return t !== "*" && (n["access-control-allow-credentials"] = "true"), n;
2629
- }, qn = (e) => ({
2766
+ }, cr = (e) => ({
2630
2767
  id: e.id,
2631
2768
  tenantId: e.tenantId,
2632
2769
  ownerId: e.ownerId,
@@ -2649,29 +2786,29 @@ var Mn = () => de({
2649
2786
  caption: e.caption ?? null,
2650
2787
  derivedFrom: e.derivedFrom ?? null,
2651
2788
  kind: e.kind ?? null
2652
- }), Jn = () => new t({
2789
+ }), lr = () => new t({
2653
2790
  provider: "storage",
2654
2791
  message: "not permitted to administer sharing for this object",
2655
2792
  transient: !1,
2656
2793
  status: 403
2657
- }), Yn = (e, t, n) => {
2794
+ }), ur = (e, t, n) => {
2658
2795
  let r = n.request.subject;
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) => {
2796
+ return (r.scopes ?? []).includes("admin:full") ? v.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(v.catch(() => v.fail(lr())), v.flatMap((e) => {
2660
2797
  let t = e?.ownerId;
2661
- return t != null && t === r.id ? y.void : y.fail(Jn());
2798
+ return t != null && t === r.id ? v.void : v.fail(lr());
2662
2799
  }));
2663
- }, Xn = () => new t({
2800
+ }, dr = () => new t({
2664
2801
  provider: "storage",
2665
2802
  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.",
2666
2803
  transient: !1,
2667
2804
  status: 401
2668
- }), $ = (e, t) => {
2805
+ }), fr = (e, t) => {
2669
2806
  let n = e.request.subject.id ?? null, r = e.request.subject.tenantId ?? null;
2670
- return n === null && !t ? y.fail(Xn()) : y.succeed({
2807
+ return n === null && !t ? v.fail(dr()) : v.succeed({
2671
2808
  id: n,
2672
2809
  tenantId: r
2673
2810
  });
2674
- }, Zn = (e, t) => e !== null && e !== (t ?? null), Qn = (e) => ({
2811
+ }, pr = (e, t) => e !== null && e !== (t ?? null), mr = (e) => ({
2675
2812
  id: e.id,
2676
2813
  refId: e.refId,
2677
2814
  principalType: e.principalType,
@@ -2680,47 +2817,79 @@ var Mn = () => de({
2680
2817
  createdAt: e.createdAt.toISOString(),
2681
2818
  expiresAt: e.expiresAt ? e.expiresAt.toISOString() : null,
2682
2819
  createdBy: e.createdBy
2683
- }), $n = "@voltro/plugin-storage", er = (e = {}) => ae({
2684
- base: $n,
2820
+ }), hr = "@voltro/plugin-storage", gr = (e = {}) => w({
2821
+ base: hr,
2685
2822
  alias: e.alias,
2686
2823
  instance: e.name
2687
- }), tr = (i = {}) => {
2688
- let v = ae({
2689
- base: $n,
2824
+ }), _r = (i = {}) => {
2825
+ let y = w({
2826
+ base: hr,
2690
2827
  alias: i.alias,
2691
2828
  instance: i.name
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 = {
2695
- insert: (e) => M.current.insert(e),
2696
- getById: (e) => M.current.getById(e),
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),
2829
+ }), b = y === hr ? "/_voltro/storage" : `/_voltro/storage/i/${Buffer.from(y).toString("hex")}`, x = ir(i);
2830
+ tr(x);
2831
+ let ue = U.read("S3_BUCKET", i.bucket) ?? U.read("STORAGE_BUCKET") ?? "voltro", T = U.read("VOLTRO_PUBLIC_URL", i.publicBaseUrl), E = or(i.allowedOrigins), D = i.limits?.maxBytes, O = i.anonymousUploads === !0, de = 5242880, fe = 21600, k = i.refStore === void 0 || i.refStore === "memory", pe = i.grantStore === void 0 || i.grantStore === "memory", A = (e, n) => v.gen(function* () {
2832
+ let r = (e) => S.decodeUnknownEffect(ae)(e, { onExcessProperty: "error" }).pipe(v.mapError(() => new t({
2833
+ provider: "storage",
2834
+ message: "Invalid upload access policy",
2835
+ transient: !1,
2836
+ status: 400
2837
+ }))), a = e.access === void 0 ? void 0 : yield* r(e.access), o = e.visibility ?? "private";
2838
+ if (a !== void 0 && o === "public") return yield* v.fail(new t({
2839
+ provider: "storage",
2840
+ message: "An access policy requires a private upload",
2841
+ transient: !1,
2842
+ status: 400
2843
+ }));
2844
+ let s = i.uploadAccess;
2845
+ if (a !== void 0 && typeof s != "function") return yield* v.fail(new t({
2846
+ provider: "storage",
2847
+ message: "Requested upload access requires an uploadAccess authorization function on storagePlugin",
2848
+ transient: !1,
2849
+ status: 403
2850
+ }));
2851
+ let c = typeof s == "function" ? yield* s({
2852
+ subject: n,
2853
+ requested: a,
2854
+ visibility: o,
2855
+ contentType: e.contentType
2856
+ }) : o === "private" ? s : void 0, l = c === void 0 ? void 0 : yield* r(c);
2857
+ return o === "public" ? l !== void 0 && l.length > 0 ? yield* v.fail(new t({
2858
+ provider: "storage",
2859
+ message: "A public upload cannot carry an access policy",
2860
+ transient: !1,
2861
+ status: 400
2862
+ })) : {} : l === void 0 ? {} : { access: l };
2863
+ }), j = { current: k ? on() : i.refStore }, M = { current: pe ? un() : i.grantStore }, me = { current: void 0 }, he = {
2864
+ insert: (e) => j.current.insert(e),
2865
+ getById: (e) => j.current.getById(e),
2866
+ delete: (e) => j.current.delete(e),
2867
+ statistics: () => j.current.statistics(),
2868
+ listRecent: (e) => j.current.listRecent(e),
2869
+ countByKey: (e, t) => j.current.countByKey(e, t),
2870
+ usageByTenant: (e) => j.current.usageByTenant(e),
2871
+ consumeUsage: (e, t, n) => j.current.consumeUsage(e, t, n),
2872
+ releaseUsage: (e, t) => j.current.releaseUsage(e, t),
2873
+ listByDerivedFrom: (e) => j.current.listByDerivedFrom(e),
2874
+ listRefs: (e) => j.current.listRefs(e),
2706
2875
  get setVisibility() {
2707
- return M.current.setVisibility;
2876
+ return j.current.setVisibility;
2708
2877
  },
2709
2878
  get countPublicByKey() {
2710
- return M.current.countPublicByKey;
2879
+ return j.current.countPublicByKey;
2711
2880
  }
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 = {
2881
+ }, ge = {
2882
+ insert: (e) => M.current.insert(e),
2883
+ delete: (e) => M.current.delete(e),
2884
+ getById: (e) => M.current.getById(e),
2885
+ listByRef: (e) => M.current.listByRef(e),
2886
+ deleteByRef: (e) => M.current.deleteByRef(e)
2887
+ }, _e = {
2719
2888
  httpPath: b,
2720
2889
  provider: x,
2721
- refStore: P,
2722
- grantStore: F,
2723
- bucket: S,
2890
+ refStore: he,
2891
+ grantStore: ge,
2892
+ bucket: ue,
2724
2893
  ...i.tenantPrefix === void 0 ? {} : { tenantPrefix: i.tenantPrefix },
2725
2894
  ...i.attempts === void 0 ? {} : { attempts: i.attempts },
2726
2895
  ...i.urlExpiresInSec === void 0 ? {} : { urlExpiresInSec: i.urlExpiresInSec },
@@ -2731,11 +2900,11 @@ var Mn = () => de({
2731
2900
  ...i.videoProbe === void 0 ? {} : { videoProbe: i.videoProbe },
2732
2901
  ...i.transcode === void 0 ? {} : { transcode: i.transcode },
2733
2902
  ...i.autoTranscode === void 0 ? {} : { autoTranscode: i.autoTranscode },
2734
- ...E ? { publicBaseUrl: E } : {},
2903
+ ...T ? { publicBaseUrl: T } : {},
2735
2904
  ...i.normalizeImages === void 0 ? {} : { normalizeImages: i.normalizeImages },
2736
2905
  ...i.quota === void 0 ? {} : { quota: i.quota },
2737
- objects: () => fe.current
2738
- }, me = tn(pe), I = en(pe), ge = `${b}/`, L = (e) => y.runPromise(e.pipe(y.catchAll(() => y.succeed(null)))), R = (e, t) => {
2906
+ objects: () => me.current
2907
+ }, ve = gn(_e), N = hn(_e), ye = `${b}/`, P = (e) => v.runPromise(e.pipe(v.catch(() => v.succeed(null)))), F = (e, t) => {
2739
2908
  if (!e) return "invalid";
2740
2909
  let n = /^bytes=(\d*)-(\d*)$/.exec(e.trim());
2741
2910
  if (!n) return "invalid";
@@ -2756,31 +2925,34 @@ var Mn = () => de({
2756
2925
  start: a,
2757
2926
  endInclusive: o
2758
2927
  };
2759
- }, ve = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, ye = (e) => ({
2928
+ }, be = i.publicCacheSeconds === void 0 ? "public, max-age=31536000, immutable" : `public, max-age=${Math.max(0, Math.floor(i.publicCacheSeconds))}`, xe = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, Se = (e) => ({
2760
2929
  "x-content-type-options": "nosniff",
2761
- "content-disposition": ve.test(e) ? "inline" : "attachment"
2762
- }), be = async (e, t, n, r) => {
2930
+ "content-disposition": xe.test(e) ? "inline" : "attachment"
2931
+ }), I = ot(), we = async (e, t, n, r) => {
2763
2932
  if (n) {
2764
- let r = await L(I.get(e.id));
2765
- if (!r) return {
2933
+ let r, i = await I.getOrCreate(_t(JSON.stringify([e.id, e.checksum]), e.contentType, n), async () => {
2934
+ let t = await P(N.get(e.id));
2935
+ return t ? (r = t.bytes, mt(t.bytes, e.contentType, n)) : null;
2936
+ }).catch(() => null);
2937
+ if (!i && r === void 0 && (r = (await P(N.get(e.id)))?.bytes), !i && r === void 0) return {
2766
2938
  status: 404,
2767
2939
  body: "not found",
2768
2940
  contentType: "text/plain"
2769
2941
  };
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);
2942
+ let a = i ? i.bytes : r, o = i ? i.contentType : e.contentType, s = await pt(e.contentType, i !== null);
2771
2943
  return {
2772
2944
  status: 200,
2773
2945
  body: a,
2774
2946
  contentType: o,
2775
2947
  headers: {
2776
- ...ye(o),
2948
+ ...Se(o),
2777
2949
  "cache-control": t,
2778
2950
  "accept-ranges": "none",
2779
2951
  ...s === null ? {} : { "x-voltro-transform": `original; reason=${s}` }
2780
2952
  }
2781
2953
  };
2782
2954
  }
2783
- let i = r === void 0 ? "invalid" : R(r, e.size);
2955
+ let i = r === void 0 ? "invalid" : F(r, e.size);
2784
2956
  if (i === "unsatisfiable") return {
2785
2957
  status: 416,
2786
2958
  body: "range not satisfiable",
@@ -2791,13 +2963,13 @@ var Mn = () => de({
2791
2963
  }
2792
2964
  };
2793
2965
  if (i !== "invalid") {
2794
- let n = await L(I.getRange(e.id, i));
2966
+ let n = await P(N.getRange(e.id, i));
2795
2967
  return n ? {
2796
2968
  status: 206,
2797
2969
  body: n.bytes,
2798
2970
  contentType: e.contentType,
2799
2971
  headers: {
2800
- ...ye(e.contentType),
2972
+ ...Se(e.contentType),
2801
2973
  "cache-control": t,
2802
2974
  "accept-ranges": "bytes",
2803
2975
  "content-range": `bytes ${i.start}-${i.endInclusive}/${n.totalSize}`
@@ -2808,39 +2980,44 @@ var Mn = () => de({
2808
2980
  contentType: "text/plain"
2809
2981
  };
2810
2982
  }
2811
- let a = await L(I.getStream(e.id));
2983
+ let a = await P(N.getStream(e.id));
2812
2984
  return a ? {
2813
2985
  status: 200,
2814
2986
  contentType: e.contentType,
2815
2987
  headers: {
2816
- ...ye(e.contentType),
2988
+ ...Se(e.contentType),
2817
2989
  "cache-control": t,
2818
2990
  "accept-ranges": "bytes"
2819
2991
  },
2820
2992
  byteStream: {
2821
2993
  contentLength: e.size,
2822
- stream: () => w.toReadableStream(a.stream)
2994
+ stream: () => C.toReadableStream(a.stream)
2823
2995
  }
2824
2996
  } : {
2825
2997
  status: 404,
2826
2998
  body: "not found",
2827
2999
  contentType: "text/plain"
2828
3000
  };
2829
- }, xe = async (e) => {
2830
- let t = e.path.startsWith(ge) ? e.path.slice(ge.length).split("/")[0] ?? "" : "";
3001
+ }, Ee = async (e) => {
3002
+ let t = e.path.startsWith(ye) ? e.path.slice(ye.length).split("/")[0] ?? "" : "";
2831
3003
  if (!t) return {
2832
3004
  status: 404,
2833
3005
  body: "not found",
2834
3006
  contentType: "text/plain"
2835
3007
  };
2836
- let n = await L(I.head(t));
3008
+ let n = await P(N.head(t));
2837
3009
  if (!n) return {
2838
3010
  status: 404,
2839
3011
  body: "not found",
2840
3012
  contentType: "text/plain"
2841
3013
  };
2842
- let r = Ze(e.query), i = e.headers.range;
2843
- if (n.visibility === "public") {
3014
+ let r = lt(e.query), i = e.headers.range, a = n.derivedFrom == null ? null : await P(N.head(n.derivedFrom));
3015
+ if (n.derivedFrom != null && a === null) return {
3016
+ status: 404,
3017
+ body: "not found",
3018
+ contentType: "text/plain"
3019
+ };
3020
+ if (n.visibility === "public" && (a === null || a.visibility === "public")) {
2844
3021
  let e = x.publicUrl?.(n.key) ?? null;
2845
3022
  return e && !r ? {
2846
3023
  status: 302,
@@ -2848,24 +3025,24 @@ var Mn = () => de({
2848
3025
  location: e,
2849
3026
  "cache-control": "public, max-age=300"
2850
3027
  }
2851
- } : be(n, "public, max-age=31536000, immutable", r, i);
3028
+ } : we(n, be, r, i);
2852
3029
  }
2853
- let a = !1, o = e.query ? new URLSearchParams(e.query).get("t") : null;
2854
- if (o) {
2855
- let e = bt(o);
2856
- a = !!e && e.refId === t && e.audience === b;
3030
+ let o = !1, s = e.query ? new URLSearchParams(e.query).get("t") : null;
3031
+ if (s) {
3032
+ let e = Nt(s);
3033
+ o = !!e && (e.refId === t || a !== null && e.refId === a.id) && e.audience === b;
2857
3034
  }
2858
- if (!a) {
2859
- let t = oe(e.headers.cookie, Rn), r = t ? ce(t, se()) : null;
2860
- r && (a = await L(I.checkAccess(n, r)) === !0);
3035
+ if (!o) {
3036
+ let t = se(e.headers.cookie, $n), r = t ? le(t, ce()) : null;
3037
+ r && (o = await P(N.checkAccess(n, r)) === !0);
2861
3038
  }
2862
- if (!a) return {
3039
+ if (!o) return {
2863
3040
  status: 403,
2864
3041
  body: "forbidden",
2865
3042
  contentType: "text/plain"
2866
3043
  };
2867
3044
  if (x.presigns && !r) {
2868
- let e = await L(x.getUrl(n.key, 300));
3045
+ let e = await P(x.getUrl(n.key, 300));
2869
3046
  if (e && /^https?:/.test(e)) return {
2870
3047
  status: 302,
2871
3048
  headers: {
@@ -2874,12 +3051,12 @@ var Mn = () => de({
2874
3051
  }
2875
3052
  };
2876
3053
  }
2877
- return be(n, "private, no-store", r, i);
2878
- }, Se = {
3054
+ return we(n, "private, no-store", r, i);
3055
+ }, L = {
2879
3056
  method: "GET",
2880
3057
  path: b,
2881
3058
  handle: async (e) => {
2882
- let t = await xe(e), n = Kn(e.headers.origin, le);
3059
+ let t = await Ee(e), n = sr(e.headers.origin, E);
2883
3060
  return Object.keys(n).length === 0 ? t : {
2884
3061
  ...t,
2885
3062
  headers: {
@@ -2888,12 +3065,12 @@ var Mn = () => de({
2888
3065
  }
2889
3066
  };
2890
3067
  }
2891
- }, Ce = {
3068
+ }, De = {
2892
3069
  method: "*",
2893
3070
  path: `${b}/upload`,
2894
3071
  originGuard: "exempt",
2895
3072
  handle: async (e) => {
2896
- let t = Kn(e.headers.origin, le);
3073
+ let t = sr(e.headers.origin, E);
2897
3074
  if (e.method === "OPTIONS") return {
2898
3075
  status: 204,
2899
3076
  headers: t
@@ -2904,14 +3081,14 @@ var Mn = () => de({
2904
3081
  contentType: "text/plain",
2905
3082
  headers: t
2906
3083
  };
2907
- let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ? St(n) : null;
2908
- if (!r || r.instance !== v) return {
3084
+ let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ? It(n) : null;
3085
+ if (!r || r.instance !== y) return {
2909
3086
  status: 401,
2910
3087
  body: "invalid or expired upload ticket",
2911
3088
  contentType: "text/plain",
2912
3089
  headers: t
2913
3090
  };
2914
- if (r.replicaId !== void 0 && r.replicaId !== _().replicaId) return {
3091
+ if (r.replicaId !== void 0 && r.replicaId !== ie().replicaId) return {
2915
3092
  status: 409,
2916
3093
  body: "upload ticket belongs to another replica",
2917
3094
  contentType: "text/plain",
@@ -2929,34 +3106,34 @@ var Mn = () => de({
2929
3106
  contentType: "text/plain",
2930
3107
  headers: t
2931
3108
  };
2932
- let i = await y.runPromise(I.put({
3109
+ let i = await v.runPromise(N.put({
2933
3110
  bytes: e.rawBody,
2934
3111
  contentType: r.ct,
2935
3112
  tenantId: r.tenant,
2936
3113
  ownerId: r.sub,
2937
3114
  visibility: r.vis,
2938
- ...de(r.vis),
3115
+ ...r.access === void 0 ? {} : { access: r.access },
2939
3116
  ...r.operationId === void 0 ? {} : { operationId: r.operationId },
2940
3117
  ...r.key === void 0 ? {} : { key: r.key },
2941
3118
  ...r.folder === void 0 ? {} : { folder: r.folder },
2942
3119
  ...r.tags === void 0 ? {} : { tags: r.tags },
2943
3120
  ...r.alt === void 0 ? {} : { alt: r.alt },
2944
3121
  ...r.caption === void 0 ? {} : { caption: r.caption }
2945
- }).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3122
+ }).pipe(v.flatMap((e) => N.getUrl(e.id).pipe(v.map((t) => ({
2946
3123
  kind: "ok",
2947
3124
  ref: e,
2948
3125
  url: t
2949
- })))), y.catchTags({
2950
- StorageRejected: (e) => y.succeed({
3126
+ })))), v.catchTags({
3127
+ StorageRejected: (e) => v.succeed({
2951
3128
  kind: "rejected",
2952
3129
  status: e.reason === "too-large" ? 413 : 415,
2953
3130
  detail: e.detail
2954
3131
  }),
2955
- StorageScanRejected: (e) => y.succeed({
3132
+ StorageScanRejected: (e) => v.succeed({
2956
3133
  kind: "scan",
2957
3134
  threat: e.threat
2958
3135
  }),
2959
- StorageError: (e) => y.succeed({
3136
+ StorageError: (e) => v.succeed({
2960
3137
  kind: "error",
2961
3138
  message: e.message
2962
3139
  })
@@ -2988,28 +3165,28 @@ var Mn = () => de({
2988
3165
  headers: t
2989
3166
  };
2990
3167
  }
2991
- }, we = {
3168
+ }, Oe = {
2992
3169
  method: "*",
2993
3170
  path: `${b}/upload/resumable`,
2994
3171
  originGuard: "exempt",
2995
3172
  handle: async (e) => {
2996
- let t = Kn(e.headers.origin, le);
3173
+ let t = sr(e.headers.origin, E);
2997
3174
  if (e.method === "OPTIONS") return {
2998
3175
  status: 204,
2999
3176
  headers: t
3000
3177
  };
3001
- let n = new URLSearchParams(e.query || ""), r = Et(n.get("token") ?? "");
3002
- if (!r || r.instance !== v) return {
3178
+ let n = new URLSearchParams(e.query || ""), r = Bt(n.get("token") ?? "");
3179
+ if (!r || r.instance !== y) return {
3003
3180
  status: 401,
3004
3181
  body: "invalid or expired resumable token",
3005
3182
  contentType: "text/plain",
3006
3183
  headers: t
3007
3184
  };
3008
3185
  if (e.method === "GET" || e.method === "HEAD") {
3009
- let e = await y.runPromise(I.resumableStatus({
3186
+ let e = await v.runPromise(N.resumableStatus({
3010
3187
  uploadId: r.id,
3011
3188
  tenantId: r.tenant
3012
- }).pipe(y.match({
3189
+ }).pipe(v.match({
3013
3190
  onFailure: (e) => ({ error: e.message }),
3014
3191
  onSuccess: (e) => e
3015
3192
  })));
@@ -3047,38 +3224,38 @@ var Mn = () => de({
3047
3224
  contentType: "text/plain",
3048
3225
  headers: t
3049
3226
  };
3050
- let a = n.get("final") === "1", o = await y.runPromise(I.putResumableChunk({
3227
+ let a = n.get("final") === "1", o = await v.runPromise(N.putResumableChunk({
3051
3228
  uploadId: r.id,
3052
3229
  tenantId: r.tenant,
3053
3230
  index: i,
3054
3231
  bytes: e.rawBody
3055
- }).pipe(y.flatMap(() => a ? I.finalizeResumable({
3232
+ }).pipe(v.flatMap(() => a ? N.finalizeResumable({
3056
3233
  uploadId: r.id,
3057
3234
  count: i + 1,
3058
3235
  contentType: r.ct,
3059
3236
  tenantId: r.tenant,
3060
3237
  ownerId: r.sub,
3061
3238
  visibility: r.vis,
3062
- ...de(r.vis),
3239
+ ...r.access === void 0 ? {} : { access: r.access },
3063
3240
  ...r.folder === void 0 ? {} : { folder: r.folder },
3064
3241
  ...r.tags === void 0 ? {} : { tags: r.tags },
3065
3242
  ...r.alt === void 0 ? {} : { alt: r.alt },
3066
3243
  ...r.caption === void 0 ? {} : { caption: r.caption }
3067
- }).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3244
+ }).pipe(v.flatMap((e) => N.getUrl(e.id).pipe(v.map((t) => ({
3068
3245
  kind: "done",
3069
3246
  ref: e,
3070
3247
  url: t
3071
- }))))) : y.succeed({ kind: "chunk" })), y.catchTags({
3072
- StorageRejected: (e) => y.succeed({
3248
+ }))))) : v.succeed({ kind: "chunk" })), v.catchTags({
3249
+ StorageRejected: (e) => v.succeed({
3073
3250
  kind: "rejected",
3074
3251
  status: e.reason === "too-large" ? 413 : 415,
3075
3252
  detail: e.detail
3076
3253
  }),
3077
- StorageScanRejected: (e) => y.succeed({
3254
+ StorageScanRejected: (e) => v.succeed({
3078
3255
  kind: "scan",
3079
3256
  threat: e.threat
3080
3257
  }),
3081
- StorageError: (e) => y.succeed({
3258
+ StorageError: (e) => v.succeed({
3082
3259
  kind: "error",
3083
3260
  message: e.message
3084
3261
  })
@@ -3116,45 +3293,51 @@ var Mn = () => de({
3116
3293
  headers: t
3117
3294
  };
3118
3295
  }
3119
- }, z = (e) => ({
3296
+ }, R = (e) => ({
3120
3297
  kind: "json",
3121
3298
  data: e
3122
- }), B = (e, t) => ({
3299
+ }), z = (e, t) => ({
3123
3300
  kind: "json",
3124
3301
  status: e,
3125
3302
  data: { error: t }
3126
- }), Te = (e, t) => {
3303
+ }), ke = (e, t) => {
3127
3304
  try {
3128
3305
  return new URL(e, "http://localhost").searchParams.get(t);
3129
3306
  } catch {
3130
3307
  return null;
3131
3308
  }
3132
- }, Ee = [
3309
+ }, Ae = [
3133
3310
  {
3134
3311
  method: "POST",
3135
3312
  path: "/upload-ticket",
3136
3313
  description: "Authorize a binary upload with explicit tenant and owner attribution",
3137
- handler: (e) => y.gen(function* () {
3138
- let n = C.String.pipe(C.filter((e) => e.trim().length > 0)), r = yield* C.decodeUnknown(C.parseJson(C.Struct({
3139
- operationId: C.optional(n.pipe(C.maxLength(200))),
3140
- tenantId: C.NullOr(n),
3141
- ownerId: C.NullOr(n),
3142
- key: n.pipe(C.maxLength(1024)),
3143
- contentType: n.pipe(C.maxLength(255), C.filter((e) => !/[\r\n]/.test(e))),
3144
- size: C.Number.pipe(C.int(), C.positive(), C.filter(Number.isSafeInteger)),
3145
- visibility: C.optional(C.Literal("public", "private"))
3146
- })))(e.body).pipe(y.mapError(() => new t({
3314
+ handler: (e) => v.gen(function* () {
3315
+ let n = S.String.pipe(S.check(S.makeFilter((e) => e.trim().length > 0))), r = yield* S.decodeUnknownEffect(S.fromJsonString(S.Struct({
3316
+ operationId: S.optional(n.pipe(S.check(S.isMaxLength(200)))),
3317
+ tenantId: S.NullOr(n),
3318
+ ownerId: S.NullOr(n),
3319
+ key: n.pipe(S.check(S.isMaxLength(1024))),
3320
+ contentType: n.pipe(S.check(S.isMaxLength(255)), S.check(S.makeFilter((e) => !/[\r\n]/.test(e)))),
3321
+ size: S.Number.pipe(S.check(S.isInt()), S.check(S.isGreaterThan(0)), S.check(S.makeFilter(Number.isSafeInteger))),
3322
+ visibility: S.optional(S.Literals(["public", "private"]))
3323
+ })))(e.body).pipe(v.mapError(() => new t({
3147
3324
  provider: "inspect",
3148
3325
  message: "Provide explicit tenantId and ownerId (or null), key, contentType and a positive file size",
3149
3326
  transient: !1,
3150
3327
  status: 400
3151
3328
  })));
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");
3153
- if (D !== void 0 && r.size > D) return B(413, "File exceeds the configured upload limit");
3154
- let i = xt({
3155
- instance: v,
3156
- ...r.operationId === void 0 ? {} : { operationId: `inspect-upload:${he("sha256").update(JSON.stringify([v, r.operationId])).digest("hex")}` },
3157
- replicaId: _().replicaId,
3329
+ if (r.operationId !== void 0 && me.current === void 0) return z(409, "Durable uploads require a bound operation store with default reference and grant stores");
3330
+ if (D !== void 0 && r.size > D) return z(413, "File exceeds the configured upload limit");
3331
+ let a = r.visibility !== "public" && Array.isArray(i.uploadAccess) ? yield* S.decodeUnknownEffect(ae)(i.uploadAccess, { onExcessProperty: "error" }).pipe(v.mapError(() => new t({
3332
+ provider: "storage",
3333
+ message: "Invalid upload access policy",
3334
+ transient: !1,
3335
+ status: 400
3336
+ }))) : void 0, o = Ft({
3337
+ instance: y,
3338
+ ...a === void 0 ? {} : { access: a },
3339
+ ...r.operationId === void 0 ? {} : { operationId: `inspect-upload:${Ce("sha256").update(JSON.stringify([y, r.operationId])).digest("hex")}` },
3340
+ replicaId: ie().replicaId,
3158
3341
  sub: r.ownerId,
3159
3342
  tenant: r.tenantId,
3160
3343
  ct: r.contentType,
@@ -3162,32 +3345,32 @@ var Mn = () => de({
3162
3345
  vis: r.visibility ?? "private",
3163
3346
  max: r.size
3164
3347
  }, 300);
3165
- return z({
3166
- uploadPath: `${b}/upload?ticket=${encodeURIComponent(i)}`,
3348
+ return R({
3349
+ uploadPath: `${b}/upload?ticket=${encodeURIComponent(o)}`,
3167
3350
  expiresInSec: 300,
3168
3351
  maxBytes: r.size
3169
3352
  });
3170
- }).pipe(y.catchAll((e) => y.succeed(B(e.status ?? 500, e.message))))
3353
+ }).pipe(v.catch((e) => v.succeed(z(e.status ?? 500, e.message))))
3171
3354
  },
3172
3355
  {
3173
3356
  method: "GET",
3174
3357
  path: "/download",
3175
3358
  description: "Stream a stored file as an attachment for authorized inspect readers",
3176
- handler: (e) => y.gen(function* () {
3177
- let t = Te(e.url, "refId");
3178
- if (!t?.trim()) return B(400, "A non-empty refId is required");
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()}`);
3359
+ handler: (e) => v.gen(function* () {
3360
+ let t = ke(e.url, "refId");
3361
+ if (!t?.trim()) return z(400, "A non-empty refId is required");
3362
+ let { ref: n, stream: r } = yield* N.getStream(t), i = n.key.split("/").pop() || n.id, a = encodeURIComponent(i).replace(/[!'()*]/g, (e) => `%${e.charCodeAt(0).toString(16).toUpperCase()}`);
3180
3363
  return {
3181
3364
  kind: "bytes",
3182
3365
  contentType: n.contentType,
3183
3366
  byteStream: {
3184
- stream: () => w.toReadableStream(r),
3367
+ stream: () => C.toReadableStream(r),
3185
3368
  contentLength: n.size,
3186
3369
  contentDisposition: `attachment; filename="download"; filename*=UTF-8''${a}`
3187
3370
  },
3188
3371
  headers: { "cache-control": "no-store" }
3189
3372
  };
3190
- }).pipe(y.catchAll((e) => y.succeed(B(e.status ?? 500, e.message))))
3373
+ }).pipe(v.catch((e) => v.succeed(z(e.status ?? 500, e.message))))
3191
3374
  },
3192
3375
  {
3193
3376
  method: "GET",
@@ -3195,8 +3378,8 @@ var Mn = () => de({
3195
3378
  scope: "process",
3196
3379
  description: "Searchable storage refs, newest first, paginated",
3197
3380
  handler: (e) => {
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({
3381
+ let t = Number(ke(e.url, "offset") ?? 0), n = Number.isSafeInteger(t) && t >= 0 ? t : 0, r = (ke(e.url, "search") ?? "").trim().slice(0, 200);
3382
+ return he.listRefs({
3200
3383
  tenantId: void 0,
3201
3384
  ownerId: void 0,
3202
3385
  folder: void 0,
@@ -3205,14 +3388,14 @@ var Mn = () => de({
3205
3388
  search: r,
3206
3389
  limit: 51,
3207
3390
  offset: n
3208
- }).pipe(y.map((e) => z({
3209
- refs: e.slice(0, 50).map(qn),
3391
+ }).pipe(v.map((e) => R({
3392
+ refs: e.slice(0, 50).map(cr),
3210
3393
  page: {
3211
3394
  search: r,
3212
3395
  offset: n,
3213
3396
  nextOffset: e.length > 50 ? n + 50 : null
3214
3397
  }
3215
- })), y.catchAll((e) => y.succeed(B(500, e.message))));
3398
+ })), v.catch((e) => v.succeed(z(500, e.message))));
3216
3399
  }
3217
3400
  },
3218
3401
  {
@@ -3220,11 +3403,11 @@ var Mn = () => de({
3220
3403
  path: "/stats",
3221
3404
  scope: "process",
3222
3405
  description: "Object count + total bytes per tenant + visibility split",
3223
- handler: () => P.statistics().pipe(y.map((e) => z({
3406
+ handler: () => he.statistics().pipe(v.map((e) => R({
3224
3407
  provider: x.name,
3225
- bucket: S,
3408
+ bucket: ue,
3226
3409
  ...e
3227
- })), y.catchAll((e) => y.succeed(B(500, e.message))))
3410
+ })), v.catch((e) => v.succeed(z(500, e.message))))
3228
3411
  },
3229
3412
  {
3230
3413
  method: "GET",
@@ -3232,110 +3415,118 @@ var Mn = () => de({
3232
3415
  scope: "process",
3233
3416
  description: "Grants for a ref (?refId=…)",
3234
3417
  handler: (e) => {
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"));
3418
+ let t = ke(e.url, "refId");
3419
+ return t ? ge.listByRef(t).pipe(v.map((e) => R({ grants: e.map(mr) })), v.catch((e) => v.succeed(z(500, e.message)))) : v.succeed(z(400, "refId query param required"));
3237
3420
  }
3238
3421
  },
3239
3422
  {
3240
3423
  method: "POST",
3241
3424
  path: "/share",
3242
3425
  description: "Grant a principal access to a ref",
3243
- handler: (e) => y.gen(function* () {
3244
- let n = yield* C.decodeUnknown(C.parseJson(C.Struct({
3245
- refId: C.String.pipe(C.filter((e) => e.trim().length > 0)),
3246
- principalType: C.Literal("user", "group", "apiKey"),
3247
- principalId: C.String.pipe(C.filter((e) => e.trim().length > 0)),
3248
- permission: C.optional(C.Literal("read", "write")),
3249
- expiresInDays: C.optional(C.Number.pipe(C.finite(), C.positive()))
3250
- })))(e.body).pipe(y.mapError(() => new t({
3426
+ handler: (e) => v.gen(function* () {
3427
+ let n = yield* S.decodeUnknownEffect(S.fromJsonString(S.Struct({
3428
+ refId: S.String.pipe(S.check(S.makeFilter((e) => e.trim().length > 0))),
3429
+ principalType: S.Literals([
3430
+ "user",
3431
+ "group",
3432
+ "apiKey"
3433
+ ]),
3434
+ principalId: S.String.pipe(S.check(S.makeFilter((e) => e.trim().length > 0))),
3435
+ permission: S.optional(S.Literals(["read", "write"])),
3436
+ expiresInDays: S.optional(S.Number.pipe(S.check(S.isFinite()), S.check(S.isGreaterThan(0))))
3437
+ })))(e.body).pipe(v.mapError(() => new t({
3251
3438
  provider: "inspect",
3252
3439
  message: "Invalid share input: provide refId, principalType, principalId, read/write permission and a positive finite expiry if set",
3253
3440
  transient: !1,
3254
3441
  status: 400
3255
3442
  }))), r = n.expiresInDays === void 0 ? null : new Date(Date.now() + n.expiresInDays * 864e5);
3256
- if (r !== null && !Number.isFinite(r.getTime())) return B(400, "Expiry exceeds the supported date range");
3257
- let i = yield* I.grant({
3443
+ if (r !== null && !Number.isFinite(r.getTime())) return z(400, "Expiry exceeds the supported date range");
3444
+ let i = yield* N.grant({
3258
3445
  refId: n.refId,
3259
3446
  principalType: n.principalType,
3260
3447
  principalId: n.principalId,
3261
3448
  ...n.permission ? { permission: n.permission } : {},
3262
3449
  expiresAt: r
3263
3450
  });
3264
- return z({ grant: Qn(i) });
3265
- }).pipe(y.catchAll((e) => y.succeed(B(e.status ?? 500, e.message ?? "share failed"))))
3451
+ return R({ grant: mr(i) });
3452
+ }).pipe(v.catch((e) => v.succeed(z(e.status ?? 500, e.message ?? "share failed"))))
3266
3453
  },
3267
3454
  {
3268
3455
  method: "POST",
3269
3456
  path: "/delete",
3270
3457
  description: "Delete an object reference and its grants; release unreferenced bytes",
3271
- handler: (e) => y.gen(function* () {
3272
- let n = yield* C.decodeUnknown(C.parseJson(C.Struct({ refId: C.String.pipe(C.filter((e) => e.trim().length > 0)) })))(e.body).pipe(y.mapError(() => new t({
3458
+ handler: (e) => v.gen(function* () {
3459
+ let n = yield* S.decodeUnknownEffect(S.fromJsonString(S.Struct({ refId: S.String.pipe(S.check(S.makeFilter((e) => e.trim().length > 0))) })))(e.body).pipe(v.mapError(() => new t({
3273
3460
  provider: "inspect",
3274
3461
  message: "A non-empty refId is required",
3275
3462
  transient: !1,
3276
3463
  status: 400
3277
3464
  })));
3278
- return yield* I.delete(n.refId), z({ ok: !0 });
3279
- }).pipe(y.catchAll((e) => y.succeed(B(e.status ?? 500, e.message))))
3465
+ return yield* N.delete(n.refId), R({ ok: !0 });
3466
+ }).pipe(v.catch((e) => v.succeed(z(e.status ?? 500, e.message))))
3280
3467
  },
3281
3468
  {
3282
3469
  method: "POST",
3283
3470
  path: "/revoke",
3284
3471
  description: "Revoke a grant by id",
3285
- handler: (e) => y.gen(function* () {
3286
- let n = yield* C.decodeUnknown(C.parseJson(C.Struct({ grantId: C.String.pipe(C.filter((e) => e.trim().length > 0)) })))(e.body).pipe(y.mapError(() => new t({
3472
+ handler: (e) => v.gen(function* () {
3473
+ let n = yield* S.decodeUnknownEffect(S.fromJsonString(S.Struct({ grantId: S.String.pipe(S.check(S.makeFilter((e) => e.trim().length > 0))) })))(e.body).pipe(v.mapError(() => new t({
3287
3474
  provider: "inspect",
3288
3475
  message: "A non-empty grantId is required",
3289
3476
  transient: !1,
3290
3477
  status: 400
3291
3478
  })));
3292
- return yield* I.revoke(n.grantId), z({ ok: !0 });
3293
- }).pipe(y.catchAll((e) => y.succeed(B(e.status ?? 500, e.message ?? "revoke failed"))))
3479
+ return yield* N.revoke(n.grantId), R({ ok: !0 });
3480
+ }).pipe(v.catch((e) => v.succeed(z(e.status ?? 500, e.message ?? "revoke failed"))))
3294
3481
  }
3295
- ], De = [
3482
+ ], je = [
3296
3483
  {
3297
3484
  ...te,
3298
3485
  execute: (e, t) => {
3299
3486
  let n = e;
3300
- return I.mintUrl(n.id, t.request.subject, {
3487
+ return N.mintUrl(n.id, t.request.subject, {
3301
3488
  ...n.password === void 0 ? {} : { password: n.password },
3302
3489
  ...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
3303
- }).pipe(y.map((e) => ({ url: e })));
3490
+ }).pipe(v.map((e) => ({ url: e })));
3304
3491
  }
3305
3492
  },
3306
3493
  {
3307
3494
  ...ee,
3308
3495
  execute: (e, t) => {
3309
3496
  let n = e;
3310
- return I.mintUploadUrl({
3497
+ return N.mintUploadUrl({
3311
3498
  key: n.key,
3312
3499
  contentType: n.contentType,
3313
3500
  tenantId: t.request.subject.tenantId,
3314
3501
  ...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
3315
- }).pipe(y.map((e) => ({ url: e })));
3502
+ }).pipe(v.map((e) => ({ url: e })));
3316
3503
  }
3317
3504
  },
3318
3505
  {
3319
3506
  ...m,
3320
3507
  execute: (e, t) => {
3321
3508
  let n = e;
3322
- return $(t, O).pipe(y.map((e) => {
3323
- let t = n.expiresInSec ?? 900, r = xt({
3324
- instance: v,
3509
+ return fr(t, O).pipe(v.flatMap((e) => A(n, t.request.subject).pipe(v.map((t) => ({
3510
+ writer: e,
3511
+ policy: t
3512
+ })))), v.map(({ writer: e, policy: t }) => {
3513
+ let r = n.expiresInSec ?? 900, i = Ft({
3514
+ instance: y,
3325
3515
  sub: e.id,
3326
3516
  tenant: e.tenantId,
3327
3517
  ct: n.contentType,
3328
3518
  vis: n.visibility ?? "private",
3519
+ ...t,
3329
3520
  ...n.key === void 0 ? {} : { key: n.key },
3330
3521
  ...n.folder === void 0 ? {} : { folder: n.folder },
3331
3522
  ...n.tags === void 0 ? {} : { tags: n.tags },
3332
3523
  ...n.alt === void 0 ? {} : { alt: n.alt },
3333
3524
  ...n.caption === void 0 ? {} : { caption: n.caption },
3334
3525
  ...D === void 0 ? {} : { max: D }
3335
- }, t);
3526
+ }, r);
3336
3527
  return {
3337
- uploadUrl: `${E ? E.replace(/\/+$/, "") : ""}${b}/upload?ticket=${encodeURIComponent(r)}`,
3338
- expiresInSec: t
3528
+ uploadUrl: `${T ? T.replace(/\/+$/, "") : ""}${b}/upload?ticket=${encodeURIComponent(i)}`,
3529
+ expiresInSec: r
3339
3530
  };
3340
3531
  }));
3341
3532
  }
@@ -3344,28 +3535,32 @@ var Mn = () => de({
3344
3535
  ...p,
3345
3536
  execute: (e, t) => {
3346
3537
  let n = e;
3347
- return $(t, O).pipe(y.flatMap((e) => I.mintPresignedUpload({
3538
+ return fr(t, O).pipe(v.flatMap((e) => A(n, t.request.subject).pipe(v.map((t) => ({
3539
+ writer: e,
3540
+ policy: t
3541
+ })))), v.flatMap(({ writer: e, policy: t }) => N.mintPresignedUpload({
3348
3542
  contentType: n.contentType,
3349
3543
  tenantId: e.tenantId,
3350
3544
  ...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
3351
- }).pipe(y.map((t) => {
3352
- let r = Ct({
3353
- instance: v,
3354
- key: t.key,
3545
+ }).pipe(v.map((r) => {
3546
+ let i = Lt({
3547
+ instance: y,
3548
+ key: r.key,
3355
3549
  sub: e.id,
3356
3550
  tenant: e.tenantId,
3357
3551
  ct: n.contentType,
3358
3552
  vis: n.visibility ?? "private",
3553
+ ...t,
3359
3554
  ...n.folder === void 0 ? {} : { folder: n.folder },
3360
3555
  ...n.tags === void 0 ? {} : { tags: n.tags },
3361
3556
  ...n.alt === void 0 ? {} : { alt: n.alt },
3362
3557
  ...n.caption === void 0 ? {} : { caption: n.caption },
3363
3558
  ...D === void 0 ? {} : { max: D }
3364
- }, t.expiresInSec);
3559
+ }, r.expiresInSec);
3365
3560
  return {
3366
- uploadUrl: t.uploadUrl,
3367
- finalizeToken: r,
3368
- expiresInSec: t.expiresInSec
3561
+ uploadUrl: r.uploadUrl,
3562
+ finalizeToken: i,
3563
+ expiresInSec: r.expiresInSec
3369
3564
  };
3370
3565
  }))));
3371
3566
  }
@@ -3373,29 +3568,29 @@ var Mn = () => de({
3373
3568
  {
3374
3569
  ...l,
3375
3570
  execute: (e, n) => {
3376
- let r = wt(e.finalizeToken);
3377
- return !r || r.instance !== v ? y.fail(new t({
3571
+ let r = Rt(e.finalizeToken);
3572
+ return !r || r.instance !== y ? v.fail(new t({
3378
3573
  provider: "storage",
3379
3574
  message: "invalid or expired finalize token",
3380
3575
  transient: !1,
3381
3576
  status: 401
3382
- })) : Zn(r.sub, n.request.subject.id) ? y.fail(new t({
3577
+ })) : pr(r.sub, n.request.subject.id) ? v.fail(new t({
3383
3578
  provider: "storage",
3384
3579
  message: "finalize token belongs to another subject",
3385
3580
  transient: !1,
3386
3581
  status: 403
3387
- })) : I.finalizeUpload({
3582
+ })) : N.finalizeUpload({
3388
3583
  key: r.key,
3389
3584
  contentType: r.ct,
3390
3585
  tenantId: r.tenant,
3391
3586
  ownerId: r.sub,
3392
3587
  visibility: r.vis,
3393
- ...de(r.vis),
3588
+ ...r.access === void 0 ? {} : { access: r.access },
3394
3589
  ...r.folder === void 0 ? {} : { folder: r.folder },
3395
3590
  ...r.tags === void 0 ? {} : { tags: r.tags },
3396
3591
  ...r.alt === void 0 ? {} : { alt: r.alt },
3397
3592
  ...r.caption === void 0 ? {} : { caption: r.caption }
3398
- }).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3593
+ }).pipe(v.flatMap((e) => N.getUrl(e.id).pipe(v.map((t) => ({
3399
3594
  id: e.id,
3400
3595
  url: t,
3401
3596
  contentType: e.contentType,
@@ -3409,27 +3604,31 @@ var Mn = () => de({
3409
3604
  ...s,
3410
3605
  execute: (e, t) => {
3411
3606
  let n = e;
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;
3607
+ return fr(t, O).pipe(v.flatMap((e) => A(n, t.request.subject).pipe(v.map((t) => ({
3608
+ writer: e,
3609
+ policy: t
3610
+ })))), v.map(({ writer: e, policy: t }) => {
3611
+ let r = n.expiresInSec ?? fe, i = Te(), a = n.chunkSize && n.chunkSize > 0 ? n.chunkSize : de;
3414
3612
  return {
3415
- uploadId: r,
3416
- resumableToken: Tt({
3417
- instance: v,
3418
- id: r,
3613
+ uploadId: i,
3614
+ resumableToken: zt({
3615
+ instance: y,
3616
+ id: i,
3419
3617
  sub: e.id,
3420
3618
  tenant: e.tenantId,
3421
3619
  ct: n.contentType,
3422
3620
  vis: n.visibility ?? "private",
3621
+ ...t,
3423
3622
  size: n.size,
3424
3623
  ...n.folder === void 0 ? {} : { folder: n.folder },
3425
3624
  ...n.tags === void 0 ? {} : { tags: n.tags },
3426
3625
  ...n.alt === void 0 ? {} : { alt: n.alt },
3427
3626
  ...n.caption === void 0 ? {} : { caption: n.caption },
3428
3627
  ...D === void 0 ? {} : { max: D }
3429
- }, t),
3430
- uploadUrl: `${E ? E.replace(/\/+$/, "") : ""}${b}/upload/resumable`,
3431
- chunkSize: i,
3432
- expiresInSec: t
3628
+ }, r),
3629
+ uploadUrl: `${T ? T.replace(/\/+$/, "") : ""}${b}/upload/resumable`,
3630
+ chunkSize: a,
3631
+ expiresInSec: r
3433
3632
  };
3434
3633
  }));
3435
3634
  }
@@ -3437,28 +3636,32 @@ var Mn = () => de({
3437
3636
  {
3438
3637
  ...o,
3439
3638
  execute: (e, t) => {
3440
- let n = e, r = n.expiresInSec ?? ue;
3441
- return $(t, O).pipe(y.flatMap((e) => I.beginMultipartUpload({
3639
+ let n = e, r = n.expiresInSec ?? fe;
3640
+ return fr(t, O).pipe(v.flatMap((e) => A(n, t.request.subject).pipe(v.map((t) => ({
3641
+ writer: e,
3642
+ policy: t
3643
+ })))), v.flatMap(({ writer: e, policy: t }) => N.beginMultipartUpload({
3442
3644
  contentType: n.contentType,
3443
3645
  tenantId: e.tenantId,
3444
3646
  visibility: n.visibility ?? "private",
3445
3647
  expiresInSec: r
3446
- }).pipe(y.map((t) => ({
3447
- multipartToken: Dt({
3448
- instance: v,
3449
- key: t.key,
3450
- uploadId: t.uploadId,
3648
+ }).pipe(v.map((i) => ({
3649
+ multipartToken: Vt({
3650
+ instance: y,
3651
+ key: i.key,
3652
+ uploadId: i.uploadId,
3451
3653
  sub: e.id,
3452
3654
  tenant: e.tenantId,
3453
3655
  ct: n.contentType,
3454
3656
  vis: n.visibility ?? "private",
3657
+ ...t,
3455
3658
  size: n.size,
3456
3659
  ...n.folder === void 0 ? {} : { folder: n.folder },
3457
3660
  ...n.tags === void 0 ? {} : { tags: n.tags },
3458
3661
  ...n.alt === void 0 ? {} : { alt: n.alt },
3459
3662
  ...n.caption === void 0 ? {} : { caption: n.caption }
3460
3663
  }, r),
3461
- partSize: n.partSize && n.partSize >= k ? n.partSize : k,
3664
+ partSize: n.partSize && n.partSize >= de ? n.partSize : de,
3462
3665
  expiresInSec: r
3463
3666
  })))));
3464
3667
  }
@@ -3466,39 +3669,39 @@ var Mn = () => de({
3466
3669
  {
3467
3670
  ...g,
3468
3671
  execute: (e) => {
3469
- let n = e, r = Ot(n.multipartToken);
3470
- return !r || r.instance !== v ? y.fail(new t({
3672
+ let n = e, r = Ht(n.multipartToken);
3673
+ return !r || r.instance !== y ? v.fail(new t({
3471
3674
  provider: "storage",
3472
3675
  message: "invalid or expired multipart token",
3473
3676
  transient: !1,
3474
3677
  status: 401
3475
- })) : !Number.isInteger(n.partNumber) || n.partNumber < 1 ? y.fail(new t({
3678
+ })) : !Number.isInteger(n.partNumber) || n.partNumber < 1 ? v.fail(new t({
3476
3679
  provider: "storage",
3477
3680
  message: "partNumber must be a positive integer",
3478
3681
  transient: !1,
3479
3682
  status: 400
3480
- })) : I.signMultipartPart({
3683
+ })) : N.signMultipartPart({
3481
3684
  key: r.key,
3482
3685
  uploadId: r.uploadId,
3483
3686
  partNumber: n.partNumber
3484
- }).pipe(y.map((e) => ({ url: e })));
3687
+ }).pipe(v.map((e) => ({ url: e })));
3485
3688
  }
3486
3689
  },
3487
3690
  {
3488
3691
  ...c,
3489
3692
  execute: (e, n) => {
3490
- let r = e, i = Ot(r.multipartToken);
3491
- return !i || i.instance !== v ? y.fail(new t({
3693
+ let r = e, i = Ht(r.multipartToken);
3694
+ return !i || i.instance !== y ? v.fail(new t({
3492
3695
  provider: "storage",
3493
3696
  message: "invalid or expired multipart token",
3494
3697
  transient: !1,
3495
3698
  status: 401
3496
- })) : Zn(i.sub, n.request.subject.id) ? y.fail(new t({
3699
+ })) : pr(i.sub, n.request.subject.id) ? v.fail(new t({
3497
3700
  provider: "storage",
3498
3701
  message: "multipart token belongs to another subject",
3499
3702
  transient: !1,
3500
3703
  status: 403
3501
- })) : I.completeMultipart({
3704
+ })) : N.completeMultipart({
3502
3705
  key: i.key,
3503
3706
  uploadId: i.uploadId,
3504
3707
  parts: r.parts,
@@ -3506,12 +3709,12 @@ var Mn = () => de({
3506
3709
  tenantId: i.tenant,
3507
3710
  ownerId: i.sub,
3508
3711
  visibility: i.vis,
3509
- ...de(i.vis),
3712
+ ...i.access === void 0 ? {} : { access: i.access },
3510
3713
  ...i.folder === void 0 ? {} : { folder: i.folder },
3511
3714
  ...i.tags === void 0 ? {} : { tags: i.tags },
3512
3715
  ...i.alt === void 0 ? {} : { alt: i.alt },
3513
3716
  ...i.caption === void 0 ? {} : { caption: i.caption }
3514
- }).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3717
+ }).pipe(v.flatMap((e) => N.getUrl(e.id).pipe(v.map((t) => ({
3515
3718
  id: e.id,
3516
3719
  url: t,
3517
3720
  size: e.size
@@ -3521,31 +3724,35 @@ var Mn = () => de({
3521
3724
  {
3522
3725
  ...a,
3523
3726
  execute: (e) => {
3524
- let n = Ot(e.multipartToken);
3525
- return !n || n.instance !== v ? y.fail(new t({
3727
+ let n = Ht(e.multipartToken);
3728
+ return !n || n.instance !== y ? v.fail(new t({
3526
3729
  provider: "storage",
3527
3730
  message: "invalid or expired multipart token",
3528
3731
  transient: !1,
3529
3732
  status: 401
3530
- })) : I.abortMultipart({
3733
+ })) : N.abortMultipart({
3531
3734
  key: n.key,
3532
3735
  uploadId: n.uploadId
3533
- }).pipe(y.as({ ok: !0 }));
3736
+ }).pipe(v.as({ ok: !0 }));
3534
3737
  }
3535
3738
  },
3536
3739
  {
3537
- ...ie,
3740
+ ...re,
3538
3741
  execute: (e, t) => {
3539
3742
  let n = e, r = new Uint8Array(Buffer.from(n.bytesBase64, "base64"));
3540
- return $(t, O).pipe(y.flatMap((e) => I.put({
3743
+ return fr(t, O).pipe(v.flatMap((e) => A(n, t.request.subject).pipe(v.map((t) => ({
3744
+ writer: e,
3745
+ policy: t
3746
+ })))), v.flatMap(({ writer: e, policy: t }) => N.put({
3541
3747
  bytes: r,
3748
+ ...t,
3542
3749
  contentType: n.contentType,
3543
3750
  tenantId: e.tenantId,
3544
3751
  ownerId: e.id,
3545
3752
  ...n.visibility ? { visibility: n.visibility } : {},
3546
3753
  ...n.key ? { key: n.key } : {},
3547
3754
  ...n.password ? { password: n.password } : {}
3548
- })), y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3755
+ })), v.flatMap((e) => N.getUrl(e.id).pipe(v.map((t) => ({
3549
3756
  id: e.id,
3550
3757
  url: t
3551
3758
  })))));
@@ -3555,7 +3762,7 @@ var Mn = () => de({
3555
3762
  ...u,
3556
3763
  execute: (e, t) => {
3557
3764
  let n = e;
3558
- return $(t, O).pipe(y.flatMap((e) => I.ingestUrl(n.url, {
3765
+ return fr(t, O).pipe(v.flatMap((e) => N.ingestUrl(n.url, {
3559
3766
  tenantId: e.tenantId,
3560
3767
  ownerId: e.id,
3561
3768
  ...n.visibility ? { visibility: n.visibility } : {},
@@ -3564,45 +3771,45 @@ var Mn = () => de({
3564
3771
  ...n.alt === void 0 ? {} : { alt: n.alt },
3565
3772
  ...n.caption === void 0 ? {} : { caption: n.caption },
3566
3773
  ...n.key === void 0 ? {} : { key: n.key }
3567
- })), y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
3774
+ })), v.flatMap((e) => N.getUrl(e.id).pipe(v.map((t) => ({
3568
3775
  id: e.id,
3569
3776
  url: t
3570
3777
  })))));
3571
3778
  }
3572
3779
  },
3573
3780
  {
3574
- ...ne,
3781
+ ...h,
3575
3782
  execute: (e, t) => {
3576
3783
  let n = e, r = n.expiresInDays ? new Date(Date.now() + n.expiresInDays * 864e5) : null;
3577
- return Yn(I, n.refId, t).pipe(y.flatMap(() => I.grant({
3784
+ return ur(N, n.refId, t).pipe(v.flatMap(() => N.grant({
3578
3785
  refId: n.refId,
3579
3786
  principalType: n.principalType,
3580
3787
  principalId: n.principalId,
3581
3788
  ...n.permission ? { permission: n.permission } : {},
3582
3789
  expiresAt: r,
3583
3790
  createdBy: t.request.subject.id
3584
- })), y.map((e) => ({ grantId: e.id })));
3791
+ })), v.map((e) => ({ grantId: e.id })));
3585
3792
  }
3586
3793
  },
3587
3794
  {
3588
- ...h,
3795
+ ...ne,
3589
3796
  execute: (e, t) => {
3590
3797
  let n = e;
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 })));
3798
+ return N.getGrant(n.grantId).pipe(v.flatMap((e) => e === null ? v.fail(lr()) : ur(N, e.refId, t)), v.flatMap(() => N.revoke(n.grantId)), v.map(() => ({ ok: !0 })));
3592
3799
  }
3593
3800
  },
3594
3801
  {
3595
3802
  ...d,
3596
3803
  execute: (e, t) => {
3597
3804
  let n = e;
3598
- return Yn(I, n.refId, t).pipe(y.flatMap(() => I.listGrants(n.refId)), y.map((e) => ({ grants: e.map(Qn) })));
3805
+ return ur(N, n.refId, t).pipe(v.flatMap(() => N.listGrants(n.refId)), v.map((e) => ({ grants: e.map(mr) })));
3599
3806
  }
3600
3807
  },
3601
3808
  {
3602
3809
  ...f,
3603
3810
  execute: (e, t) => {
3604
3811
  let n = e;
3605
- return I.listRefs({
3812
+ return N.listRefs({
3606
3813
  tenantId: t.request.subject.tenantId,
3607
3814
  ...n.folder === void 0 ? {} : { folder: n.folder },
3608
3815
  ...n.tags === void 0 ? {} : { tags: n.tags },
@@ -3610,37 +3817,37 @@ var Mn = () => de({
3610
3817
  ...n.includeDerived === void 0 ? {} : { includeDerived: n.includeDerived },
3611
3818
  ...n.limit === void 0 ? {} : { limit: n.limit },
3612
3819
  ...n.offset === void 0 ? {} : { offset: n.offset }
3613
- }).pipe(y.map((e) => ({
3614
- refs: e.refs.map(qn),
3820
+ }).pipe(v.map((e) => ({
3821
+ refs: e.refs.map(cr),
3615
3822
  nextOffset: e.nextOffset
3616
3823
  })));
3617
3824
  }
3618
3825
  }
3619
3826
  ];
3620
- return T({
3621
- name: ae({
3622
- base: $n,
3827
+ return oe({
3828
+ name: w({
3829
+ base: hr,
3623
3830
  alias: i.alias,
3624
3831
  instance: i.name
3625
3832
  }),
3626
- baseName: $n,
3833
+ baseName: hr,
3627
3834
  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.",
3628
3835
  permissions: [
3629
3836
  "network:outbound:*",
3630
3837
  "inspect:read",
3631
3838
  "inspect:write"
3632
3839
  ],
3633
- declaredEnv: W.declared,
3634
- egress: Wn(i),
3635
- services: me,
3636
- inspectEndpoints: Ee,
3840
+ declaredEnv: U.declared,
3841
+ egress: ar(i),
3842
+ services: ve,
3843
+ inspectEndpoints: Ae,
3637
3844
  httpRoutes: [
3638
- Se,
3639
- Ce,
3640
- we
3845
+ L,
3846
+ De,
3847
+ Oe
3641
3848
  ],
3642
- routes: De,
3643
- rpcClientDescriptors: re,
3849
+ routes: je,
3850
+ rpcClientDescriptors: _,
3644
3851
  errorSchemas: [
3645
3852
  {
3646
3853
  schema: t,
@@ -3673,7 +3880,7 @@ var Mn = () => de({
3673
3880
  ],
3674
3881
  capabilities: { mediaPersist: {
3675
3882
  put: async ({ bytes: e, mediaType: t, tenantId: n, operationId: r, ownerId: i, visibility: a, tags: o }) => {
3676
- let s = await y.runPromise(I.put({
3883
+ let s = await v.runPromise(N.put({
3677
3884
  bytes: e,
3678
3885
  contentType: t,
3679
3886
  tenantId: n,
@@ -3681,40 +3888,40 @@ var Mn = () => de({
3681
3888
  ...i === void 0 ? {} : { ownerId: i },
3682
3889
  ...a === void 0 ? {} : { visibility: a },
3683
3890
  ...o === void 0 ? {} : { tags: o },
3684
- ...fe.current === void 0 ? {} : { operationId: r }
3891
+ ...me.current === void 0 ? {} : { operationId: r }
3685
3892
  }));
3686
3893
  return {
3687
- url: await y.runPromise(I.getUrl(s.id, { tenantId: n })),
3894
+ url: await v.runPromise(N.getUrl(s.id, { tenantId: n })),
3688
3895
  refId: s.id
3689
3896
  };
3690
3897
  },
3691
3898
  ingestUrl: async ({ url: e, tenantId: t, operationId: n, ownerId: r, visibility: i, tags: a }) => {
3692
- let o = await y.runPromise(I.ingestUrl(e, {
3899
+ let o = await v.runPromise(N.ingestUrl(e, {
3693
3900
  tenantId: t,
3694
3901
  ...r === void 0 ? {} : { ownerId: r },
3695
3902
  ...i === void 0 ? {} : { visibility: i },
3696
3903
  ...a === void 0 ? {} : { tags: a },
3697
- ...fe.current === void 0 ? {} : { operationId: n }
3904
+ ...me.current === void 0 ? {} : { operationId: n }
3698
3905
  }));
3699
3906
  return {
3700
- url: await y.runPromise(I.getUrl(o.id, { tenantId: t })),
3907
+ url: await v.runPromise(N.getUrl(o.id, { tenantId: t })),
3701
3908
  refId: o.id
3702
3909
  };
3703
3910
  }
3704
3911
  } },
3705
3912
  bindDataStore: (e) => {
3706
- A && (M.current = Jt(e)), j && (N.current = Zt(e)), A && j && (fe.current = wn(e)), x.bindDataStore?.(e);
3913
+ k && (j.current = ln(e)), pe && (M.current = fn(e)), k && pe && (me.current = zn(e)), x.bindDataStore?.(e);
3707
3914
  },
3708
- onActivate: (e) => y.sync(() => {
3709
- let t = !!E || !!W.read("STORAGE_CDN_URL", i.cdnBaseUrl);
3915
+ onActivate: (e) => v.sync(() => {
3916
+ let t = !!T || !!U.read("STORAGE_CDN_URL", i.cdnBaseUrl);
3710
3917
  e.logger.info(`storage: provider=${x.name} presign=${x.presigns ? "yes" : "no"} publicUrl=${t ? "yes" : "no"} transforms=yes`, {
3711
3918
  provider: x.name,
3712
- bucket: S,
3713
- refStore: A ? "memory" : "custom"
3919
+ bucket: ue,
3920
+ refStore: k ? "memory" : "custom"
3714
3921
  }), 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.");
3715
3922
  }),
3716
- onDeactivate: () => y.void
3923
+ onDeactivate: () => v.void
3717
3924
  });
3718
3925
  };
3719
3926
  //#endregion
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 };
3927
+ export { H as STORAGE_BLOBS_TABLE, V as STORAGE_GRANTS_TABLE, B as STORAGE_REFS_TABLE, Ue as STORAGE_USAGE_TABLE, e as StorageAccessDenied, t as StorageError, n as StorageRejected, r as StorageScanRejected, i as StorageService, qe as _voltroStorageBlobsTable, Ge as _voltroStorageGrantsTable, We as _voltroStorageRefsTable, Ke as _voltroStorageUsageTable, nr as appStorageProvider, Kn as assetRef, at as azureProvider, hn as buildStorageService, Le as bytesToStream, Kt as checkLimits, Un as clamavScanner, $e as clearStorageBuffer, Re as collectStream, Ie as concatBytes, rr as configuredStorageProvider, Ut as contentTypeAllowed, fn as dataStoreGrantStore, ln as dataStoreRefStore, it as databaseProvider, Yn as decodeDataUri, Qn as durabilityNotice, ht as editImage, Bn as encodeInstream, Gn as ffmpegTranscoder, tt as filesystemProvider, ze as fromNodeReadable, Ve as getObjectStream, yt as hashPassword, zn as makeStorageObjectMetadata, un as memoryGrantStore, et as memoryProvider, on as memoryRefStore, Vn as parseClamavResponse, lt as parseTransformParams, Zn as pathDurability, Xn as putAvatar, He as putObjectStream, Qe as readStorageBuffer, rn as refMatchesListQuery, ir as resolveStorageProvider, q as resolveStorageSecret, nt as s3Provider, tr as setActiveStorageProvider, Lt as signFinalizeTicket, Mt as signGrant, Vt as signMultipartTicket, zt as signResumableTicket, Ft as signUploadTicket, Gt as sniffMatches, ar as storageEgressOf, gr as storageInstanceName, bn as storageObjectLifecycleTables, _r as storagePlugin, In as storagePutIntentsTable, gn as storageServiceLayer, Be as toNodeReadable, vt as transformCached, pt as transformFallbackReason, mt as transformImage, Rt as verifyFinalizeTicket, Nt as verifyGrant, Ht as verifyMultipartTicket, bt as verifyPassword, Bt as verifyResumableTicket, It as verifyUploadTicket, qn as withStorage };