@voltro/plugin-storage 0.70.0 → 0.71.1

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,86 +1,86 @@
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 h, revokeDescriptor as g, shareDescriptor as _, signMultipartPartDescriptor as te, storageRpcClientImports as ne, uploadDescriptor as v } from "./rpc.js";
3
- import { Chunk as y, Effect as b, Exit as x, Layer as S, Schedule as C, Stream as w } from "effect";
4
- import { definePlugin as T, pluginInstanceName as re } from "@voltro/protocol";
5
- import { readCookie as E, resolveSessionSecret as ie, verifySession as ae } from "@voltro/protocol/session";
6
- import { and as D, bytes as oe, eq as O, generateId as k, id as A, integer as j, json as M, mixin as se, reference as ce, table as N, text as P, timestamp as F } from "@voltro/database";
7
- import { pluginEnv as I } from "@voltro/env";
8
- import { createHmac as L, randomBytes as le, randomUUID as ue, scryptSync as R, timingSafeEqual as z } from "node:crypto";
9
- import { spawn as de } from "node:child_process";
10
- import { mkdtemp as fe, readFile as pe, rm as me, writeFile as B } from "node:fs/promises";
11
- import { tmpdir as V } from "node:os";
12
- import { join as he } from "node:path";
13
- import { statSync as ge } 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 h, revokeDescriptor as te, shareDescriptor as g, signMultipartPartDescriptor as ne, storageRpcClientImports as re, uploadDescriptor as _ } from "./rpc.js";
3
+ import { Chunk as v, Effect as y, Exit as b, Layer as x, Schedule as S, Schema as C, Stream as w } from "effect";
4
+ import { definePlugin as ie, pluginInstanceName as T } from "@voltro/protocol";
5
+ import { readCookie as ae, resolveSessionSecret as oe, verifySession as se } from "@voltro/protocol/session";
6
+ import { and as E, bytes as ce, contains as D, eq as O, generateId as k, id as A, integer as j, json as M, mixin as N, or as P, reference as le, table as F, text as I, timestamp as ue } from "@voltro/database";
7
+ import { pluginEnv as L } from "@voltro/env";
8
+ import { createHmac as R, randomBytes as z, randomUUID as de, scryptSync as fe, timingSafeEqual as B } from "node:crypto";
9
+ import { spawn as pe } from "node:child_process";
10
+ import { mkdtemp as me, readFile as he, rm as ge, writeFile as _e } from "node:fs/promises";
11
+ import { tmpdir as ve } from "node:os";
12
+ import { join as V } from "node:path";
13
+ import { statSync as H } from "node:fs";
14
14
  //#region src/streamBridge.ts
15
- var _e = 1 << 20, ve = (e, n, r = !1) => new t({
15
+ var ye = 1 << 20, be = (e, n, r = !1) => new t({
16
16
  provider: e,
17
17
  message: n,
18
18
  transient: r
19
- }), ye = (e) => {
19
+ }), xe = (e) => {
20
20
  let t = 0;
21
21
  for (let n of e) t += n.byteLength;
22
22
  let n = new Uint8Array(t), r = 0;
23
23
  for (let t of e) n.set(t, r), r += t.byteLength;
24
24
  return n;
25
- }, be = (e, t = _e) => {
25
+ }, Se = (e, t = ye) => {
26
26
  let n = [];
27
27
  for (let r = 0; r < e.byteLength; r += t) n.push(e.subarray(r, Math.min(r + t, e.byteLength)));
28
28
  return w.fromIterable(n);
29
- }, xe = (e) => e.pipe(w.runCollect, b.map((e) => ye(y.toReadonlyArray(e)))), Se = (e, t) => w.suspend(() => w.fromAsyncIterable(t(), (t) => ve(e, `read stream failed: ${String(t?.message ?? t)}`, !0))).pipe(w.map((e) => e instanceof Uint8Array ? e : new Uint8Array(e))), Ce = async (e) => {
29
+ }, Ce = (e) => e.pipe(w.runCollect, y.map((e) => xe(v.toReadonlyArray(e)))), we = (e, t) => w.suspend(() => w.fromAsyncIterable(t(), (t) => be(e, `read stream failed: ${String(t?.message ?? t)}`, !0))).pipe(w.map((e) => e instanceof Uint8Array ? e : new Uint8Array(e))), Te = async (e) => {
30
30
  let { Readable: t } = await import("node:stream");
31
31
  return t.fromWeb(w.toReadableStream(e));
32
- }, we = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(b.map((e) => ({
33
- stream: be(e.bytes),
32
+ }, Ee = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(y.map((e) => ({
33
+ stream: Se(e.bytes),
34
34
  contentType: e.contentType,
35
35
  size: e.bytes.byteLength
36
- }))), Te = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : xe(n).pipe(b.flatMap((n) => e.put(t, n, {
36
+ }))), De = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : Ce(n).pipe(y.flatMap((n) => e.put(t, n, {
37
37
  contentType: r.contentType,
38
38
  ...r.public === void 0 ? {} : { public: r.public }
39
- }))), H = "_voltro_storage_refs", U = "_voltro_storage_grants", W = "_voltro_storage_blobs", Ee = "_voltro_storage_usage", De = N(H, {
39
+ }))), U = "_voltro_storage_refs", W = "_voltro_storage_grants", G = "_voltro_storage_blobs", Oe = "_voltro_storage_usage", ke = F(U, {
40
40
  id: A({ prefix: "file" }),
41
- tenantId: P().nullable(),
42
- ownerId: P().nullable(),
43
- bucket: P(),
44
- key: P(),
45
- contentType: P(),
41
+ tenantId: I().nullable(),
42
+ ownerId: I().nullable(),
43
+ bucket: I(),
44
+ key: I(),
45
+ contentType: I(),
46
46
  size: j(),
47
- checksum: P(),
48
- visibility: P(),
47
+ checksum: I(),
48
+ visibility: I(),
49
49
  accessPolicy: M().nullable(),
50
- passwordHash: P().nullable(),
50
+ passwordHash: I().nullable(),
51
51
  width: j().nullable(),
52
52
  height: j().nullable(),
53
53
  duration: j().nullable(),
54
- placeholder: P().nullable(),
55
- folder: P().nullable(),
54
+ placeholder: I().nullable(),
55
+ folder: I().nullable(),
56
56
  tags: M().nullable(),
57
- alt: P().nullable(),
58
- caption: P().nullable(),
59
- derivedFrom: P().nullable(),
60
- kind: P().nullable(),
61
- createdAt: F()
62
- }).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]), Oe = N(U, {
57
+ alt: I().nullable(),
58
+ caption: I().nullable(),
59
+ derivedFrom: I().nullable(),
60
+ kind: I().nullable(),
61
+ createdAt: ue()
62
+ }).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]), Ae = F(W, {
63
63
  id: A({ prefix: "sgrant" }),
64
- refId: P(),
65
- principalType: P(),
66
- principalId: P(),
67
- permission: P(),
68
- createdAt: F(),
69
- expiresAt: F().nullable(),
70
- createdBy: P().nullable()
71
- }).index(["refId"]).index(["principalId"]), ke = N(Ee, {
64
+ refId: I(),
65
+ principalType: I(),
66
+ principalId: I(),
67
+ permission: I(),
68
+ createdAt: ue(),
69
+ expiresAt: ue().nullable(),
70
+ createdBy: I().nullable()
71
+ }).index(["refId"]).index(["principalId"]), je = F(Oe, {
72
72
  id: A({ prefix: "susage" }),
73
- tenantId: P().maxLength(191),
73
+ tenantId: I().maxLength(191),
74
74
  bytes: j().default(0),
75
75
  count: j().default(0),
76
- updatedAt: F()
77
- }).unique("byStorageUsageTenant", ["tenantId"]), Ae = N(W, {
76
+ updatedAt: ue()
77
+ }).unique("byStorageUsageTenant", ["tenantId"]), Me = F(G, {
78
78
  id: A({ prefix: "blob" }),
79
- key: P(),
80
- data: oe(),
81
- contentType: P(),
79
+ key: I(),
80
+ data: ce(),
81
+ contentType: I(),
82
82
  size: j()
83
- }).index(["key"]), G = I([
83
+ }).index(["key"]), K = L([
84
84
  {
85
85
  name: "STORAGE_PROVIDER",
86
86
  required: !1,
@@ -231,47 +231,47 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
231
231
  secret: !1,
232
232
  description: "clamd port for the optional clamav virus scanner. Default 3310."
233
233
  }
234
- ]), K = (e, n, r, i) => new t({
234
+ ]), q = (e, n, r, i) => new t({
235
235
  provider: e,
236
236
  message: n,
237
237
  transient: r,
238
238
  ...i === void 0 ? {} : { status: i }
239
- }), je = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, Me = /* @__PURE__ */ new Map(), Ne = (e, t) => Me.get(e)?.get(t)?.bytes, Pe = (e) => {
240
- Me.get(e)?.clear();
241
- }, Fe = (e = "default") => {
242
- let t = Me.get(e) ?? /* @__PURE__ */ new Map();
243
- return Me.set(e, t), {
239
+ }), Ne = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, Pe = /* @__PURE__ */ new Map(), Fe = (e, t) => Pe.get(e)?.get(t)?.bytes, Ie = (e) => {
240
+ Pe.get(e)?.clear();
241
+ }, Le = (e = "default") => {
242
+ let t = Pe.get(e) ?? /* @__PURE__ */ new Map();
243
+ return Pe.set(e, t), {
244
244
  name: "memory",
245
245
  presigns: !1,
246
- put: (e, n, r) => b.sync(() => (t.set(e, {
246
+ put: (e, n, r) => y.sync(() => (t.set(e, {
247
247
  bytes: n,
248
248
  contentType: r.contentType
249
249
  }), { size: n.byteLength })),
250
- get: (e) => b.suspend(() => {
250
+ get: (e) => y.suspend(() => {
251
251
  let n = t.get(e);
252
- return n ? b.succeed({
252
+ return n ? y.succeed({
253
253
  bytes: n.bytes,
254
254
  contentType: n.contentType
255
- }) : b.fail(K("memory", `no object at key '${e}'`, !1, 404));
255
+ }) : y.fail(q("memory", `no object at key '${e}'`, !1, 404));
256
256
  }),
257
- delete: (e) => b.sync(() => {
257
+ delete: (e) => y.sync(() => {
258
258
  t.delete(e);
259
259
  }),
260
260
  publicUrl: () => null,
261
- getUrl: () => b.succeed(""),
262
- head: (e) => b.sync(() => {
261
+ getUrl: () => y.succeed(""),
262
+ head: (e) => y.sync(() => {
263
263
  let n = t.get(e);
264
264
  return n ? { size: n.bytes.byteLength } : null;
265
265
  })
266
266
  };
267
- }, Ie = (e) => {
267
+ }, Re = (e) => {
268
268
  let t = e.root, n = async (e) => {
269
269
  let { join: n, resolve: r, sep: i } = await import("node:path"), a = r(t), o = r(a, e);
270
270
  if (o !== a && !o.startsWith(a + i)) throw Error(`key '${e}' escapes the storage root`);
271
271
  return n(o);
272
- }, r = (e, t, n = !1) => b.tryPromise({
272
+ }, r = (e, t, n = !1) => y.tryPromise({
273
273
  try: e,
274
- catch: (e) => e?.code === "ENOENT" ? K("filesystem", `no object at key '${t}'`, !1, 404) : K("filesystem", String(e?.message ?? e), n)
274
+ catch: (e) => e?.code === "ENOENT" ? q("filesystem", `no object at key '${t}'`, !1, 404) : q("filesystem", String(e?.message ?? e), n)
275
275
  });
276
276
  return {
277
277
  root: t,
@@ -299,8 +299,8 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
299
299
  await (await import("node:fs/promises")).rm(await n(e), { force: !0 });
300
300
  }, e),
301
301
  publicUrl: () => null,
302
- getUrl: () => b.succeed(""),
303
- head: (e) => b.tryPromise({
302
+ getUrl: () => y.succeed(""),
303
+ head: (e) => y.tryPromise({
304
304
  try: async () => {
305
305
  let t = await import("node:fs/promises");
306
306
  try {
@@ -310,12 +310,12 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
310
310
  throw e;
311
311
  }
312
312
  },
313
- catch: (e) => K("filesystem", String(e?.message ?? e), !1)
313
+ catch: (e) => q("filesystem", String(e?.message ?? e), !1)
314
314
  }),
315
315
  getStream: (e) => r(async () => {
316
316
  let t = await import("node:fs/promises"), { createReadStream: r } = await import("node:fs"), i = await n(e), a = await t.stat(i);
317
317
  return {
318
- stream: Se("filesystem", () => r(i)),
318
+ stream: we("filesystem", () => r(i)),
319
319
  contentType: "application/octet-stream",
320
320
  size: a.size
321
321
  };
@@ -325,7 +325,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
325
325
  await r.mkdir(i(c), { recursive: !0 });
326
326
  let l = `${c}.tmp-${a()}`;
327
327
  try {
328
- await s(await Ce(t), o(l));
328
+ await s(await Te(t), o(l));
329
329
  let e = await r.stat(l);
330
330
  return await r.rename(l, c), { size: e.size };
331
331
  } catch (e) {
@@ -340,10 +340,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
340
340
  end: i
341
341
  });
342
342
  s.on("data", (e) => o.push(e)), s.on("end", () => e()), s.on("error", n);
343
- }), ye(o);
343
+ }), xe(o);
344
344
  }, e)
345
345
  };
346
- }, Le = (e) => {
346
+ }, ze = (e) => {
347
347
  let t = e.name ?? "s3", n = e.publicAcl ?? !0, r = null, i = () => r || (r = (async () => {
348
348
  let t, n;
349
349
  try {
@@ -364,11 +364,11 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
364
364
  cmds: t,
365
365
  presign: n.getSignedUrl
366
366
  };
367
- })(), r), a = (e) => b.tryPromise({
367
+ })(), r), a = (e) => y.tryPromise({
368
368
  try: e,
369
369
  catch: (e) => {
370
370
  let n = e?.$metadata?.httpStatusCode;
371
- return K(t, String(e?.message ?? e), je(n), n);
371
+ return q(t, String(e?.message ?? e), Ne(n), n);
372
372
  }
373
373
  }), o = async (e) => {
374
374
  let t = e;
@@ -464,7 +464,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
464
464
  UploadId: n
465
465
  }));
466
466
  }),
467
- head: (n) => b.tryPromise({
467
+ head: (n) => y.tryPromise({
468
468
  try: async () => {
469
469
  let { client: t, cmds: r } = await i();
470
470
  try {
@@ -483,7 +483,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
483
483
  },
484
484
  catch: (e) => {
485
485
  let n = e?.$metadata?.httpStatusCode;
486
- return K(t, String(e?.message ?? e), je(n), n);
486
+ return q(t, String(e?.message ?? e), Ne(n), n);
487
487
  }
488
488
  }),
489
489
  getStream: (n) => a(async () => {
@@ -492,7 +492,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
492
492
  Key: n
493
493
  })), s = o.Body;
494
494
  return {
495
- stream: Se(t, () => s),
495
+ stream: we(t, () => s),
496
496
  contentType: o.ContentType ?? "application/octet-stream",
497
497
  ...o.ContentLength === void 0 ? {} : { size: o.ContentLength }
498
498
  };
@@ -504,7 +504,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
504
504
  } catch (e) {
505
505
  throw Error("s3/minio `putStream` requires the '@aws-sdk/lib-storage' optional dependency (multipart upload). Install it to enable streamed uploads.", { cause: e });
506
506
  }
507
- let l = await Ce(r);
507
+ let l = await Te(r);
508
508
  return await new c.Upload({
509
509
  client: a,
510
510
  params: {
@@ -528,15 +528,15 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
528
528
  return o(c.Body);
529
529
  })
530
530
  };
531
- }, Re = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), ze = () => {
531
+ }, Be = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), Ve = () => {
532
532
  let e = null, t = () => {
533
533
  if (!e) throw Error("the 'database' storage provider isn't bound to a DataStore yet");
534
534
  return e;
535
- }, n = (e) => b.tryPromise({
535
+ }, n = (e) => y.tryPromise({
536
536
  try: e,
537
- catch: (e) => K("database", String(e?.message ?? e), !0)
537
+ catch: (e) => q("database", String(e?.message ?? e), !0)
538
538
  }), r = async (e) => (await t().query({
539
- table: W,
539
+ table: G,
540
540
  predicate: {
541
541
  column: "key",
542
542
  op: "eq",
@@ -555,37 +555,37 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
555
555
  },
556
556
  put: (e, i, a) => n(async () => {
557
557
  let n = await r(e);
558
- return n ? await t().update(W, String(n.id), {
558
+ return n ? await t().update(G, String(n.id), {
559
559
  data: i,
560
560
  contentType: a.contentType,
561
561
  size: i.byteLength
562
- }) : await t().insert(W, {
562
+ }) : await t().insert(G, {
563
563
  id: k({
564
564
  kind: "typeid",
565
565
  prefix: "blob"
566
- }, W),
566
+ }, G),
567
567
  key: e,
568
568
  data: i,
569
569
  contentType: a.contentType,
570
570
  size: i.byteLength
571
571
  }), { size: i.byteLength };
572
572
  }),
573
- get: (e) => b.suspend(() => n(() => r(e)).pipe(b.flatMap((t) => t ? b.succeed({
574
- bytes: Re(t.data),
573
+ get: (e) => y.suspend(() => n(() => r(e)).pipe(y.flatMap((t) => t ? y.succeed({
574
+ bytes: Be(t.data),
575
575
  contentType: String(t.contentType)
576
- }) : b.fail(K("database", `no object at key '${e}'`, !1, 404))))),
576
+ }) : y.fail(q("database", `no object at key '${e}'`, !1, 404))))),
577
577
  delete: (e) => n(async () => {
578
578
  let n = await r(e);
579
- n && await t().delete(W, String(n.id));
579
+ n && await t().delete(G, String(n.id));
580
580
  }),
581
581
  publicUrl: () => null,
582
- getUrl: () => b.succeed(""),
582
+ getUrl: () => y.succeed(""),
583
583
  head: (e) => n(async () => {
584
584
  let t = await r(e);
585
585
  return t ? { size: Number(t.size) } : null;
586
586
  })
587
587
  };
588
- }, Be = (e) => {
588
+ }, He = (e) => {
589
589
  let t = null, n = () => t || (t = (async () => {
590
590
  let t;
591
591
  try {
@@ -593,17 +593,17 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
593
593
  } catch (e) {
594
594
  throw Error("the 'azure' storage provider requires the '@azure/storage-blob' optional dependency. Install it to enable it.", { cause: e });
595
595
  }
596
- let n = G.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = G.read("AZURE_STORAGE_KEY", e.accountKey), i = n && r ? new t.StorageSharedKeyCredential(n, r) : null, a = G.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString);
596
+ let n = K.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = K.read("AZURE_STORAGE_KEY", e.accountKey), i = n && r ? new t.StorageSharedKeyCredential(n, r) : null, a = K.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString);
597
597
  return {
598
598
  container: (a ? t.BlobServiceClient.fromConnectionString(a) : new t.BlobServiceClient(e.endpoint ?? `https://${n}.blob.core.windows.net`, i ?? void 0)).getContainerClient(e.container),
599
599
  sdk: t,
600
600
  cred: i
601
601
  };
602
- })(), t), r = (e) => b.tryPromise({
602
+ })(), t), r = (e) => y.tryPromise({
603
603
  try: e,
604
604
  catch: (e) => {
605
605
  let t = e?.statusCode;
606
- return K("azure", String(e?.message ?? e), je(t), t);
606
+ return q("azure", String(e?.message ?? e), Ne(t), t);
607
607
  }
608
608
  }), i = async (e) => {
609
609
  if (!e) return /* @__PURE__ */ new Uint8Array();
@@ -645,7 +645,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
645
645
  publicUrl: (t) => e.cdnBaseUrl ? `${e.cdnBaseUrl.replace(/\/$/, "")}/${t}` : null,
646
646
  getUrl: (e, t) => r(() => a(e, "r", t)),
647
647
  getUploadUrl: (e, t, n) => r(() => a(e, "cw", t)),
648
- head: (e) => b.tryPromise({
648
+ head: (e) => y.tryPromise({
649
649
  try: async () => {
650
650
  let { container: t } = await n();
651
651
  try {
@@ -661,19 +661,19 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
661
661
  },
662
662
  catch: (e) => {
663
663
  let t = e?.statusCode;
664
- return K("azure", String(e?.message ?? e), je(t), t);
664
+ return q("azure", String(e?.message ?? e), Ne(t), t);
665
665
  }
666
666
  }),
667
667
  getStream: (e) => r(async () => {
668
668
  let { container: t } = await n(), r = await t.getBlockBlobClient(e).download();
669
669
  return {
670
- stream: Se("azure", () => r.readableStreamBody),
670
+ stream: we("azure", () => r.readableStreamBody),
671
671
  contentType: r.contentType ?? "application/octet-stream",
672
672
  ...r.contentLength === void 0 ? {} : { size: r.contentLength }
673
673
  };
674
674
  }),
675
675
  putStream: (e, t, i) => r(async () => {
676
- let { container: r } = await n(), a = await Ce(t);
676
+ let { container: r } = await n(), a = await Te(t);
677
677
  return await r.getBlockBlobClient(e).uploadStream(a, 4194304, 5, { blobHTTPHeaders: { blobContentType: i.contentType } }), { size: i.totalSize ?? (await r.getBlockBlobClient(e).getProperties()).contentLength ?? 0 };
678
678
  }),
679
679
  getRange: (e, t, a) => r(async () => {
@@ -681,13 +681,13 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
681
681
  return i(o.readableStreamBody);
682
682
  })
683
683
  };
684
- }, Ve = {
684
+ }, Ue = {
685
685
  webp: "image/webp",
686
686
  avif: "image/avif",
687
687
  jpeg: "image/jpeg",
688
688
  jpg: "image/jpeg",
689
689
  png: "image/png"
690
- }, He = (e) => {
690
+ }, We = (e) => {
691
691
  if (!e) return null;
692
692
  let t = new URLSearchParams(e), n = (e) => {
693
693
  let n = t.get(e);
@@ -702,18 +702,18 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
702
702
  ...a === void 0 ? {} : { q: a },
703
703
  ...s ? { fit: s } : {}
704
704
  };
705
- }, Ue = (e) => e.startsWith("image/") && !e.includes("svg"), q, We = async () => {
706
- if (q !== void 0) return q;
705
+ }, Ge = (e) => e.startsWith("image/") && !e.includes("svg"), J, Ke = async () => {
706
+ if (J !== void 0) return J;
707
707
  try {
708
708
  let e = await import("sharp");
709
- q = e.default ?? e;
709
+ J = e.default ?? e;
710
710
  } catch {
711
- q = null;
711
+ J = null;
712
712
  }
713
- return q;
714
- }, Ge = async (e, t, n) => {
715
- if (!Ue(t)) return null;
716
- let r = await We();
713
+ return J;
714
+ }, qe = async (e, t, n) => {
715
+ if (!Ge(t)) return null;
716
+ let r = await Ke();
717
717
  if (!r) return null;
718
718
  try {
719
719
  let i = r(Buffer.from(e), { failOn: "none" });
@@ -723,10 +723,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
723
723
  fit: n.fit ?? "cover",
724
724
  withoutEnlargement: !0
725
725
  }));
726
- let a = n.format && Ve[n.format] ? n.format : void 0, o = t;
726
+ let a = n.format && Ue[n.format] ? n.format : void 0, o = t;
727
727
  if (a) {
728
728
  let e = a === "jpg" ? "jpeg" : a;
729
- i = i.toFormat(e, n.q === void 0 ? {} : { quality: n.q }), o = Ve[a];
729
+ i = i.toFormat(e, n.q === void 0 ? {} : { quality: n.q }), o = Ue[a];
730
730
  } else n.q !== void 0 && (t === "image/jpeg" || t === "image/webp") && (i = i.toFormat(t === "image/webp" ? "webp" : "jpeg", { quality: n.q }));
731
731
  let s = await i.toBuffer();
732
732
  return {
@@ -736,43 +736,43 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
736
736
  } catch {
737
737
  return null;
738
738
  }
739
- }, Ke = 200, J = /* @__PURE__ */ new Map(), qe = async (e, t, n, r) => {
740
- let i = `${e}::${JSON.stringify(r)}`, a = J.get(i);
739
+ }, Je = 200, Ye = /* @__PURE__ */ new Map(), Xe = async (e, t, n, r) => {
740
+ let i = `${e}::${JSON.stringify(r)}`, a = Ye.get(i);
741
741
  if (a) return a;
742
- let o = await Ge(t, n, r);
743
- if (o && (J.set(i, o), J.size > Ke)) {
744
- let e = J.keys().next().value;
745
- e !== void 0 && J.delete(e);
742
+ let o = await qe(t, n, r);
743
+ if (o && (Ye.set(i, o), Ye.size > Je)) {
744
+ let e = Ye.keys().next().value;
745
+ e !== void 0 && Ye.delete(e);
746
746
  }
747
747
  return o;
748
- }, Je = (e) => {
749
- let t = le(16).toString("hex");
750
- return `${t}:${R(e, t, 32).toString("hex")}`;
751
- }, Ye = (e, t) => {
748
+ }, Ze = (e) => {
749
+ let t = z(16).toString("hex");
750
+ return `${t}:${fe(e, t, 32).toString("hex")}`;
751
+ }, Qe = (e, t) => {
752
752
  if (!e || !t) return !1;
753
753
  let [n, r] = t.split(":");
754
754
  if (!n || !r) return !1;
755
- let i = Buffer.from(r, "hex"), a = R(e, n, i.length);
756
- return a.length === i.length && z(a, i);
757
- }, Xe = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], Ze = (e) => Xe(e.metadata?.roles), Qe = (e) => Xe(e.scopes), $e = (e, t) => e.some((e) => t.includes(e)), et = (e) => Xe(e.metadata?.groups), tt = (e) => typeof e == "boolean" ? b.succeed(e) : b.isEffect(e) ? e : b.promise(() => e), nt = (e, t, n = {}) => b.gen(function* () {
755
+ let i = Buffer.from(r, "hex"), a = fe(e, n, i.length);
756
+ return a.length === i.length && B(a, i);
757
+ }, $e = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], et = (e) => $e(e.metadata?.roles), tt = (e) => $e(e.scopes), nt = (e, t) => e.some((e) => t.includes(e)), rt = (e) => $e(e.metadata?.groups), it = (e) => typeof e == "boolean" ? y.succeed(e) : y.isEffect(e) ? e : y.promise(() => e), at = (e, t, n = {}) => y.gen(function* () {
758
758
  if (t.id && e.ownerId && t.id === e.ownerId) return !0;
759
759
  let r = e.accessPolicy ?? [];
760
760
  if (r.length === 0) return !1;
761
- let i = n.resolveGroups ? yield* b.promise(async () => await n.resolveGroups(t)) : et(t);
762
- for (let a of r) if (yield* rt(a, e, t, i, n)) return !0;
761
+ let i = n.resolveGroups ? yield* y.promise(async () => await n.resolveGroups(t)) : rt(t);
762
+ for (let a of r) if (yield* ot(a, e, t, i, n)) return !0;
763
763
  return !1;
764
- }), rt = (e, t, n, r, i) => b.gen(function* () {
764
+ }), ot = (e, t, n, r, i) => y.gen(function* () {
765
765
  let a = !1, o = (e) => (a = !0, e);
766
- 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($e(Ze(n), e.roles)) || e.groups && e.groups.length > 0 && !o($e(r, e.groups)) || e.scopes && e.scopes.length > 0 && !o($e(Qe(n), e.scopes)) || e.password !== void 0 && e.password && !o(Ye(i.password, t.passwordHash))) return !1;
766
+ 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(nt(et(n), e.roles)) || e.groups && e.groups.length > 0 && !o(nt(r, e.groups)) || e.scopes && e.scopes.length > 0 && !o(nt(tt(n), e.scopes)) || e.password !== void 0 && e.password && !o(Qe(i.password, t.passwordHash))) return !1;
767
767
  if (e.guard) {
768
768
  let r = i.guards?.[e.guard];
769
- if (!o(r ? yield* tt(r({
769
+ if (!o(r ? yield* it(r({
770
770
  subject: n,
771
771
  ref: t
772
772
  })) : !1)) return !1;
773
773
  }
774
774
  return a;
775
- }), it = (e, t) => {
775
+ }), st = (e, t) => {
776
776
  let n = [];
777
777
  e.id && n.push({
778
778
  type: e.type === "apiKey" ? "apiKey" : "user",
@@ -783,115 +783,115 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
783
783
  id: e
784
784
  });
785
785
  return n;
786
- }, at = (e, t, n, r, i) => {
787
- let a = it(t, n);
786
+ }, ct = (e, t, n, r, i) => {
787
+ let a = st(t, n);
788
788
  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));
789
- }, ot = (e, t) => t.resolveGroups ? b.promise(async () => await t.resolveGroups(e)) : b.succeed(et(e)), Y = () => G.read("VOLTRO_STORAGE_SECRET") ?? ie(), X = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), Z = (e) => {
789
+ }, lt = (e, t) => t.resolveGroups ? y.promise(async () => await t.resolveGroups(e)) : y.succeed(rt(e)), Y = () => K.read("VOLTRO_STORAGE_SECRET") ?? oe(), X = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), Z = (e) => {
790
790
  let t = e.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - e.length % 4) % 4);
791
791
  return Buffer.from(t, "base64");
792
- }, st = (e, t, n = Y()) => {
792
+ }, ut = (e, t, n = Y()) => {
793
793
  if (!n) throw Error("signGrant: secret must be a non-empty string");
794
794
  let r = {
795
795
  refId: e,
796
796
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
797
797
  }, i = X(JSON.stringify(r));
798
- return `${i}.${X(L("sha256", n).update(i).digest())}`;
799
- }, ct = (e, t = Y()) => {
798
+ return `${i}.${X(R("sha256", n).update(i).digest())}`;
799
+ }, dt = (e, t = Y()) => {
800
800
  if (!e || !t) return null;
801
801
  let n = e.indexOf(".");
802
802
  if (n <= 0 || n === e.length - 1) return null;
803
- let r = e.slice(0, n), i = e.slice(n + 1), a = L("sha256", t).update(r).digest(), o = Z(i);
804
- if (o.length !== a.length || !z(o, a)) return null;
803
+ let r = e.slice(0, n), i = e.slice(n + 1), a = R("sha256", t).update(r).digest(), o = Z(i);
804
+ if (o.length !== a.length || !B(o, a)) return null;
805
805
  try {
806
806
  let e = JSON.parse(Z(r).toString("utf8"));
807
807
  return typeof e.refId != "string" || typeof e.exp != "number" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
808
808
  } catch {
809
809
  return null;
810
810
  }
811
- }, lt = (e, t, n = Y()) => {
811
+ }, ft = (e, t, n = Y()) => {
812
812
  if (!n) throw Error("signUploadTicket: secret must be a non-empty string");
813
813
  let r = {
814
814
  ...e,
815
815
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
816
816
  }, i = X(JSON.stringify(r));
817
- return `${i}.${X(L("sha256", n).update(`u:${i}`).digest())}`;
818
- }, ut = (e, t = Y()) => {
817
+ return `${i}.${X(R("sha256", n).update(`u:${i}`).digest())}`;
818
+ }, pt = (e, t = Y()) => {
819
819
  if (!e || !t) return null;
820
820
  let n = e.indexOf(".");
821
821
  if (n <= 0 || n === e.length - 1) return null;
822
- let r = e.slice(0, n), i = e.slice(n + 1), a = L("sha256", t).update(`u:${r}`).digest(), o = Z(i);
823
- if (o.length !== a.length || !z(o, a)) return null;
822
+ let r = e.slice(0, n), i = e.slice(n + 1), a = R("sha256", t).update(`u:${r}`).digest(), o = Z(i);
823
+ if (o.length !== a.length || !B(o, a)) return null;
824
824
  try {
825
825
  let e = JSON.parse(Z(r).toString("utf8"));
826
- return typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
826
+ return 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;
827
827
  } catch {
828
828
  return null;
829
829
  }
830
- }, dt = (e, t, n = Y()) => {
830
+ }, mt = (e, t, n = Y()) => {
831
831
  if (!n) throw Error("signFinalizeTicket: secret must be a non-empty string");
832
832
  let r = {
833
833
  ...e,
834
834
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
835
835
  }, i = X(JSON.stringify(r));
836
- return `${i}.${X(L("sha256", n).update(`f:${i}`).digest())}`;
837
- }, ft = (e, t = Y()) => {
836
+ return `${i}.${X(R("sha256", n).update(`f:${i}`).digest())}`;
837
+ }, ht = (e, t = Y()) => {
838
838
  if (!e || !t) return null;
839
839
  let n = e.indexOf(".");
840
840
  if (n <= 0 || n === e.length - 1) return null;
841
- let r = e.slice(0, n), i = e.slice(n + 1), a = L("sha256", t).update(`f:${r}`).digest(), o = Z(i);
842
- if (o.length !== a.length || !z(o, a)) return null;
841
+ let r = e.slice(0, n), i = e.slice(n + 1), a = R("sha256", t).update(`f:${r}`).digest(), o = Z(i);
842
+ if (o.length !== a.length || !B(o, a)) return null;
843
843
  try {
844
844
  let e = JSON.parse(Z(r).toString("utf8"));
845
- return typeof e.key != "string" || e.key.length === 0 || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
845
+ 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;
846
846
  } catch {
847
847
  return null;
848
848
  }
849
- }, pt = (e, t, n = Y()) => {
849
+ }, gt = (e, t, n = Y()) => {
850
850
  if (!n) throw Error("signResumableTicket: secret must be a non-empty string");
851
851
  let r = {
852
852
  ...e,
853
853
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
854
854
  }, i = X(JSON.stringify(r));
855
- return `${i}.${X(L("sha256", n).update(`r:${i}`).digest())}`;
856
- }, mt = (e, t = Y()) => {
855
+ return `${i}.${X(R("sha256", n).update(`r:${i}`).digest())}`;
856
+ }, _t = (e, t = Y()) => {
857
857
  if (!e || !t) return null;
858
858
  let n = e.indexOf(".");
859
859
  if (n <= 0 || n === e.length - 1) return null;
860
- let r = e.slice(0, n), i = e.slice(n + 1), a = L("sha256", t).update(`r:${r}`).digest(), o = Z(i);
861
- if (o.length !== a.length || !z(o, a)) return null;
860
+ let r = e.slice(0, n), i = e.slice(n + 1), a = R("sha256", t).update(`r:${r}`).digest(), o = Z(i);
861
+ if (o.length !== a.length || !B(o, a)) return null;
862
862
  try {
863
863
  let e = JSON.parse(Z(r).toString("utf8"));
864
- return typeof e.id != "string" || e.id.length === 0 || typeof e.size != "number" || e.size < 0 || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
864
+ 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;
865
865
  } catch {
866
866
  return null;
867
867
  }
868
- }, ht = (e, t, n = Y()) => {
868
+ }, vt = (e, t, n = Y()) => {
869
869
  if (!n) throw Error("signMultipartTicket: secret must be a non-empty string");
870
870
  let r = {
871
871
  ...e,
872
872
  exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
873
873
  }, i = X(JSON.stringify(r));
874
- return `${i}.${X(L("sha256", n).update(`m:${i}`).digest())}`;
875
- }, gt = (e, t = Y()) => {
874
+ return `${i}.${X(R("sha256", n).update(`m:${i}`).digest())}`;
875
+ }, yt = (e, t = Y()) => {
876
876
  if (!e || !t) return null;
877
877
  let n = e.indexOf(".");
878
878
  if (n <= 0 || n === e.length - 1) return null;
879
- let r = e.slice(0, n), i = e.slice(n + 1), a = L("sha256", t).update(`m:${r}`).digest(), o = Z(i);
880
- if (o.length !== a.length || !z(o, a)) return null;
879
+ let r = e.slice(0, n), i = e.slice(n + 1), a = R("sha256", t).update(`m:${r}`).digest(), o = Z(i);
880
+ if (o.length !== a.length || !B(o, a)) return null;
881
881
  try {
882
882
  let e = JSON.parse(Z(r).toString("utf8"));
883
- return typeof e.key != "string" || e.key.length === 0 || typeof e.uploadId != "string" || e.uploadId.length === 0 || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
883
+ 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;
884
884
  } catch {
885
885
  return null;
886
886
  }
887
- }, _t = (e, t) => {
887
+ }, bt = (e, t) => {
888
888
  if (!t || t.length === 0) return !0;
889
889
  let n = e.toLowerCase();
890
890
  return t.some((e) => {
891
891
  let t = e.toLowerCase();
892
892
  return t.endsWith("/*") ? n.startsWith(t.slice(0, -1)) : n === t;
893
893
  });
894
- }, vt = [
894
+ }, xt = [
895
895
  {
896
896
  ct: /^image\/png$/,
897
897
  offset: 0,
@@ -961,21 +961,21 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
961
961
  offset: 0,
962
962
  magic: [31, 139]
963
963
  }
964
- ], yt = (e, t) => {
965
- let n = t.toLowerCase(), r = vt.find((e) => e.ct.test(n));
964
+ ], St = (e, t) => {
965
+ let n = t.toLowerCase(), r = xt.find((e) => e.ct.test(n));
966
966
  return r ? e.length < r.offset + r.magic.length ? !1 : r.magic.every((t, n) => e[r.offset + n] === t) : !0;
967
- }, bt = (e, t, n) => n ? n.maxBytes !== void 0 && e.byteLength > n.maxBytes ? {
967
+ }, Ct = (e, t, n) => n ? n.maxBytes !== void 0 && e.byteLength > n.maxBytes ? {
968
968
  reason: "too-large",
969
969
  detail: `${e.byteLength} bytes exceeds the ${n.maxBytes}-byte limit`
970
- } : _t(t, n.allowedContentTypes) ? n.sniff && !yt(e, t) ? {
970
+ } : bt(t, n.allowedContentTypes) ? n.sniff && !St(e, t) ? {
971
971
  reason: "content-mismatch",
972
972
  detail: `bytes do not match the declared content type '${t}'`
973
973
  } : null : {
974
974
  reason: "content-type-not-allowed",
975
975
  detail: `content type '${t}' is not in the allow-list`
976
- } : null, xt = async (e, t, n) => {
977
- if (!Ue(t)) return { bytes: e };
978
- let r = await We();
976
+ } : null, wt = async (e, t, n) => {
977
+ if (!Ge(t)) return { bytes: e };
978
+ let r = await Ke();
979
979
  if (!r) return { bytes: e };
980
980
  try {
981
981
  let t = e;
@@ -998,11 +998,90 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
998
998
  } catch {
999
999
  return { bytes: e };
1000
1000
  }
1001
- }, St = async (e) => {
1001
+ }, Tt = 67108864, Et = (e) => new n({
1002
+ reason: "too-large",
1003
+ detail: `remote body exceeds the ${e}-byte ingest limit`
1004
+ }), Dt = (e, r) => y.suspend(() => {
1005
+ let i = r ?? Tt;
1006
+ return !Number.isSafeInteger(i) || i < 0 ? y.fail(new t({
1007
+ provider: "ingest",
1008
+ message: "limits.maxBytes must be a non-negative safe integer",
1009
+ transient: !1
1010
+ })) : y.tryPromise({
1011
+ try: async (n) => {
1012
+ let r = await fetch(e, { signal: n }), a;
1013
+ try {
1014
+ if (!r.ok) throw new t({
1015
+ provider: "ingest",
1016
+ message: `remote server returned HTTP ${r.status}`,
1017
+ transient: r.status === 429 || r.status >= 500,
1018
+ status: r.status
1019
+ });
1020
+ let e = r.headers.get("content-length"), n = r.headers.get("content-encoding")?.trim().toLowerCase();
1021
+ if ((!n || n === "identity") && e !== null && /^\d+$/.test(e) && BigInt(e) > BigInt(i)) throw Et(i);
1022
+ let o = /* @__PURE__ */ new Uint8Array(), s = 0;
1023
+ if (r.body !== null) for (a = r.body.getReader();;) {
1024
+ let e = await a.read();
1025
+ if (e.done) break;
1026
+ if (e.value.byteLength > i - s) throw Et(i);
1027
+ if (e.value.byteLength !== 0) {
1028
+ let t = s + e.value.byteLength;
1029
+ if (t > o.byteLength) {
1030
+ let e = Math.min(i, Math.max(65536, o.byteLength * 2, t)), n = new Uint8Array(e);
1031
+ n.set(o), o = n;
1032
+ }
1033
+ o.set(e.value, s), s = t;
1034
+ }
1035
+ }
1036
+ return {
1037
+ bytes: s === o.byteLength ? o : o.slice(0, s),
1038
+ contentType: r.headers.get("content-type")?.split(";")[0]?.trim() || "application/octet-stream"
1039
+ };
1040
+ } finally {
1041
+ a === void 0 ? await r.body?.cancel().catch(() => {}) : (await a.cancel().catch(() => {}), a.releaseLock());
1042
+ }
1043
+ },
1044
+ catch: (e) => e instanceof n || e instanceof t ? e : new t({
1045
+ provider: "ingest",
1046
+ message: "remote fetch or body read failed",
1047
+ transient: !0
1048
+ })
1049
+ });
1050
+ }), Ot = (e, t) => y.suspend(() => {
1051
+ if (t === void 0) return e;
1052
+ if (t.aborted) return y.interrupt;
1053
+ let n = y.async((e) => {
1054
+ let n = () => e(y.interrupt);
1055
+ return t.addEventListener("abort", n, { once: !0 }), t.aborted && n(), y.sync(() => t.removeEventListener("abort", n));
1056
+ });
1057
+ return y.raceFirst(e, n);
1058
+ }), kt = async (e) => {
1002
1059
  let { createHash: t } = await import("node:crypto");
1003
1060
  return t("sha256").update(e).digest("hex");
1004
- }, Ct = (e, t) => e ? `${e.replace(/\/+$/, "")}/_voltro/storage/${t}` : `/_voltro/storage/${t}`, wt = (e, t) => {
1005
- if (t.tenantId !== void 0 && (e.tenantId ?? null) !== (t.tenantId ?? null) || t.ownerId !== void 0 && e.ownerId !== t.ownerId || !t.includeDerived && e.derivedFrom != null) return !1;
1061
+ }, At = (e, t, n) => `${e?.replace(/\/+$/, "") ?? ""}${n}/${t}`, jt = (e) => {
1062
+ let t = /* @__PURE__ */ new Map(), n = {
1063
+ public: 0,
1064
+ private: 0
1065
+ };
1066
+ for (let r of e) {
1067
+ let e = r.tenantId ?? "(global)", i = t.get(e) ?? {
1068
+ count: 0,
1069
+ bytes: 0
1070
+ };
1071
+ i.count += r.count, i.bytes += r.bytes, t.set(e, i), r.visibility === "public" ? n.public += r.count : n.private += r.count;
1072
+ }
1073
+ return {
1074
+ byTenant: Object.fromEntries(t),
1075
+ visibility: n
1076
+ };
1077
+ }, Mt = (e, t) => {
1078
+ if (t.search && ![
1079
+ e.id,
1080
+ e.key,
1081
+ e.contentType,
1082
+ e.ownerId,
1083
+ e.tenantId
1084
+ ].some((e) => e?.toLowerCase().includes(t.search.toLowerCase())) || t.tenantId !== void 0 && (e.tenantId ?? null) !== (t.tenantId ?? null) || t.ownerId !== void 0 && e.ownerId !== t.ownerId || !t.includeDerived && e.derivedFrom != null) return !1;
1006
1085
  if (t.folder !== void 0) {
1007
1086
  let n = t.folder.replace(/\/+$/, ""), r = (e.folder ?? "").replace(/\/+$/, "");
1008
1087
  if (r !== n && !r.startsWith(`${n}/`)) return !1;
@@ -1012,17 +1091,25 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1012
1091
  if (!t.tags.every((e) => n.includes(e))) return !1;
1013
1092
  }
1014
1093
  return !0;
1015
- }, Tt = (e) => e ?? "global", Et = () => {
1094
+ }, Nt = (e) => e ?? "global", Pt = () => {
1016
1095
  let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
1017
1096
  return {
1018
- insert: (t) => b.sync(() => {
1097
+ statistics: () => y.sync(() => jt((function* () {
1098
+ for (let t of e.values()) yield {
1099
+ tenantId: t.tenantId,
1100
+ visibility: t.visibility,
1101
+ count: 1,
1102
+ bytes: t.size
1103
+ };
1104
+ })())),
1105
+ insert: (t) => y.sync(() => {
1019
1106
  e.set(t.id, t);
1020
1107
  }),
1021
- getById: (t) => b.sync(() => e.get(t) ?? null),
1022
- delete: (t) => b.sync(() => e.delete(t)),
1023
- listRecent: (t) => b.sync(() => [...e.values()].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime()).slice(0, t)),
1024
- countByKey: (t, n) => b.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n).length),
1025
- usageByTenant: (t) => b.sync(() => {
1108
+ getById: (t) => y.sync(() => e.get(t) ?? null),
1109
+ delete: (t) => y.sync(() => e.delete(t)),
1110
+ listRecent: (t) => y.sync(() => [...e.values()].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(0, t)),
1111
+ countByKey: (t, n) => y.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n).length),
1112
+ usageByTenant: (t) => y.sync(() => {
1026
1113
  let n = 0, r = 0;
1027
1114
  for (let i of e.values()) (i.tenantId ?? null) === (t ?? null) && (n += i.size, r++);
1028
1115
  return {
@@ -1030,8 +1117,8 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1030
1117
  count: r
1031
1118
  };
1032
1119
  }),
1033
- consumeUsage: (e, n, r) => b.sync(() => {
1034
- let i = Tt(e), a = t.get(i) ?? {
1120
+ consumeUsage: (e, n, r) => y.sync(() => {
1121
+ let i = Nt(e), a = t.get(i) ?? {
1035
1122
  bytes: 0,
1036
1123
  count: 0
1037
1124
  }, o = (r?.maxBytes === void 0 || a.bytes + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || a.count + n.count <= r.maxCount);
@@ -1044,17 +1131,17 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1044
1131
  count: a.count
1045
1132
  };
1046
1133
  }),
1047
- releaseUsage: (e, n) => b.sync(() => {
1048
- let r = Tt(e), i = t.get(r);
1134
+ releaseUsage: (e, n) => y.sync(() => {
1135
+ let r = Nt(e), i = t.get(r);
1049
1136
  i && t.set(r, {
1050
1137
  bytes: Math.max(0, i.bytes - n.bytes),
1051
1138
  count: Math.max(0, i.count - n.count)
1052
1139
  });
1053
1140
  }),
1054
- listByDerivedFrom: (t) => b.sync(() => [...e.values()].filter((e) => (e.derivedFrom ?? null) === t)),
1055
- listRefs: (t) => b.sync(() => [...e.values()].filter((e) => wt(e, t)).sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime()).slice(t.offset, t.offset + t.limit))
1141
+ listByDerivedFrom: (t) => y.sync(() => [...e.values()].filter((e) => (e.derivedFrom ?? null) === t)),
1142
+ listRefs: (t) => y.sync(() => [...e.values()].filter((e) => Mt(e, t)).sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(t.offset, t.offset + t.limit))
1056
1143
  };
1057
- }, Dt = (e) => Array.isArray(e) && e.every((e) => typeof e == "string") ? e : null, Ot = (e) => ({
1144
+ }, Ft = (e) => Array.isArray(e) && e.every((e) => typeof e == "string") ? e : null, It = (e) => ({
1058
1145
  id: String(e.id),
1059
1146
  tenantId: e.tenantId ?? null,
1060
1147
  ownerId: e.ownerId ?? null,
@@ -1072,19 +1159,19 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1072
1159
  duration: e.duration ?? null,
1073
1160
  placeholder: e.placeholder ?? null,
1074
1161
  folder: e.folder ?? null,
1075
- tags: Dt(e.tags),
1162
+ tags: Ft(e.tags),
1076
1163
  alt: e.alt ?? null,
1077
1164
  caption: e.caption ?? null,
1078
1165
  derivedFrom: e.derivedFrom ?? null,
1079
1166
  kind: e.kind ?? null
1080
- }), Q = (e) => b.tryPromise({
1167
+ }), Q = (e) => y.tryPromise({
1081
1168
  try: e,
1082
1169
  catch: (e) => new t({
1083
1170
  provider: "refstore",
1084
1171
  message: String(e?.message ?? e),
1085
1172
  transient: !0
1086
1173
  })
1087
- }), kt = async (e, t) => (await e.query({
1174
+ }), Lt = async (e, t) => (await e.query({
1088
1175
  table: "_voltro_storage_usage",
1089
1176
  predicate: {
1090
1177
  column: "tenantId",
@@ -1095,11 +1182,33 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1095
1182
  take: 1,
1096
1183
  skip: void 0,
1097
1184
  projection: void 0
1098
- }))[0] ?? null, At = (e) => ({
1099
- insert: (t) => Q(() => e.insert(H, { ...t })),
1185
+ }))[0] ?? null, Rt = (e) => ({
1186
+ statistics: () => Q(async () => jt((await e.query({
1187
+ table: U,
1188
+ predicate: void 0,
1189
+ order: [],
1190
+ take: void 0,
1191
+ skip: void 0,
1192
+ projection: void 0,
1193
+ groupBy: ["tenantId", "visibility"],
1194
+ aggregations: [{
1195
+ op: "count",
1196
+ alias: "count"
1197
+ }, {
1198
+ op: "sum",
1199
+ column: "size",
1200
+ alias: "bytes"
1201
+ }]
1202
+ })).map((e) => ({
1203
+ tenantId: e.tenantId == null ? null : String(e.tenantId),
1204
+ visibility: String(e.visibility),
1205
+ count: Number(e.count),
1206
+ bytes: Number(e.bytes ?? 0)
1207
+ })))),
1208
+ insert: (t) => Q(() => e.insert(U, { ...t })),
1100
1209
  getById: (t) => Q(async () => {
1101
1210
  let n = await e.query({
1102
- table: H,
1211
+ table: U,
1103
1212
  predicate: {
1104
1213
  column: "id",
1105
1214
  op: "eq",
@@ -1110,11 +1219,11 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1110
1219
  skip: void 0,
1111
1220
  projection: void 0
1112
1221
  });
1113
- return n[0] ? Ot(n[0]) : null;
1222
+ return n[0] ? It(n[0]) : null;
1114
1223
  }),
1115
- delete: (t) => Q(() => e.delete(H, t)),
1224
+ delete: (t) => Q(() => e.delete(U, t)),
1116
1225
  listRecent: (t) => Q(async () => (await e.query({
1117
- table: H,
1226
+ table: U,
1118
1227
  predicate: void 0,
1119
1228
  order: [{
1120
1229
  column: "createdAt",
@@ -1123,9 +1232,9 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1123
1232
  take: t,
1124
1233
  skip: void 0,
1125
1234
  projection: void 0
1126
- })).map(Ot)),
1235
+ })).map(It)),
1127
1236
  countByKey: (t, n) => Q(async () => (await e.query({
1128
- table: H,
1237
+ table: U,
1129
1238
  predicate: { and: [{
1130
1239
  column: "bucket",
1131
1240
  op: "eq",
@@ -1142,7 +1251,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1142
1251
  })).length),
1143
1252
  usageByTenant: (t) => Q(async () => {
1144
1253
  let n = await e.query({
1145
- table: H,
1254
+ table: U,
1146
1255
  predicate: {
1147
1256
  column: "tenantId",
1148
1257
  op: "eq",
@@ -1160,10 +1269,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1160
1269
  };
1161
1270
  }),
1162
1271
  consumeUsage: (t, n, r) => Q(async () => {
1163
- let i = Tt(t);
1272
+ let i = Nt(t);
1164
1273
  for (let t = 0; t < 32; t++) {
1165
1274
  t > 0 && await new Promise((e) => setTimeout(e, t));
1166
- let a = await kt(e, i), o = a ? Number(a.bytes ?? 0) : 0, s = a ? Number(a.count ?? 0) : 0;
1275
+ let a = await Lt(e, i), o = a ? Number(a.bytes ?? 0) : 0, s = a ? Number(a.count ?? 0) : 0;
1167
1276
  if (!((r?.maxBytes === void 0 || o + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || s + n.count <= r.maxCount))) return {
1168
1277
  allowed: !1,
1169
1278
  bytes: o,
@@ -1174,7 +1283,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1174
1283
  bytes: o + n.bytes,
1175
1284
  count: s + n.count,
1176
1285
  updatedAt: /* @__PURE__ */ new Date()
1177
- }, { where: D(O("id", String(a.id)), O("bytes", o), O("count", s)) }) === 1) return {
1286
+ }, { where: E(O("id", String(a.id)), O("bytes", o), O("count", s)) }) === 1) return {
1178
1287
  allowed: !0,
1179
1288
  bytes: o,
1180
1289
  count: s
@@ -1183,7 +1292,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1183
1292
  let t = k({
1184
1293
  kind: "typeid",
1185
1294
  prefix: "susage"
1186
- }, Ee), r = await e.insertIgnore(Ee, {
1295
+ }, Oe), r = await e.insertIgnore(Oe, {
1187
1296
  id: t,
1188
1297
  tenantId: i,
1189
1298
  bytes: n.bytes,
@@ -1200,22 +1309,22 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1200
1309
  throw Error(`storage usage consume: contention on tenant '${i}' exceeded 32 attempts`);
1201
1310
  }),
1202
1311
  releaseUsage: (t, n) => Q(async () => {
1203
- let r = Tt(t);
1312
+ let r = Nt(t);
1204
1313
  for (let t = 0; t < 32; t++) {
1205
1314
  t > 0 && await new Promise((e) => setTimeout(e, t));
1206
- let i = await kt(e, r);
1315
+ let i = await Lt(e, r);
1207
1316
  if (!i) return;
1208
1317
  let a = Number(i.bytes ?? 0), o = Number(i.count ?? 0);
1209
1318
  if (await e.updateMany("_voltro_storage_usage", {
1210
1319
  bytes: Math.max(0, a - n.bytes),
1211
1320
  count: Math.max(0, o - n.count),
1212
1321
  updatedAt: /* @__PURE__ */ new Date()
1213
- }, { where: D(O("id", String(i.id)), O("bytes", a), O("count", o)) }) === 1) return;
1322
+ }, { where: E(O("id", String(i.id)), O("bytes", a), O("count", o)) }) === 1) return;
1214
1323
  }
1215
1324
  throw Error(`storage usage release: contention on tenant '${r}' exceeded 32 attempts`);
1216
1325
  }),
1217
1326
  listByDerivedFrom: (t) => Q(async () => (await e.query({
1218
- table: H,
1327
+ table: U,
1219
1328
  predicate: {
1220
1329
  column: "derivedFrom",
1221
1330
  op: "eq",
@@ -1228,47 +1337,48 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1228
1337
  take: void 0,
1229
1338
  skip: void 0,
1230
1339
  projection: void 0
1231
- })).map(Ot)),
1340
+ })).map(It)),
1232
1341
  listRefs: (t) => Q(async () => {
1233
1342
  let n = [];
1234
- t.tenantId !== void 0 && n.push({
1235
- column: "tenantId",
1236
- op: "eq",
1237
- value: t.tenantId
1238
- }), t.ownerId !== void 0 && n.push({
1239
- column: "ownerId",
1240
- op: "eq",
1241
- value: t.ownerId
1242
- });
1243
- let r = n.length === 0 ? void 0 : n.length === 1 ? n[0] : { and: n };
1244
- return (await e.query({
1245
- table: H,
1246
- predicate: r,
1343
+ t.tenantId !== void 0 && n.push(O("tenantId", t.tenantId)), t.ownerId !== void 0 && n.push(O("ownerId", t.ownerId)), t.search && n.push(P(...[
1344
+ "id",
1345
+ "key",
1346
+ "contentType",
1347
+ "ownerId",
1348
+ "tenantId"
1349
+ ].map((e) => D(e, t.search))));
1350
+ let r = t.folder === void 0 && t.tags.length === 0 && t.includeDerived, i = n.length ? E(...n) : void 0, a = await e.query({
1351
+ table: U,
1352
+ predicate: i,
1247
1353
  order: [{
1248
1354
  column: "createdAt",
1249
1355
  direction: "desc"
1356
+ }, {
1357
+ column: "id",
1358
+ direction: "desc"
1250
1359
  }],
1251
- take: void 0,
1252
- skip: void 0,
1360
+ take: r ? t.limit : void 0,
1361
+ skip: r ? t.offset : void 0,
1253
1362
  projection: void 0
1254
- })).map(Ot).filter((e) => wt(e, t)).slice(t.offset, t.offset + t.limit);
1363
+ });
1364
+ return r ? a.map(It) : a.map(It).filter((e) => Mt(e, t)).slice(t.offset, t.offset + t.limit);
1255
1365
  })
1256
- }), jt = () => {
1366
+ }), zt = () => {
1257
1367
  let e = /* @__PURE__ */ new Map();
1258
1368
  return {
1259
- insert: (t) => b.sync(() => {
1369
+ insert: (t) => y.sync(() => {
1260
1370
  e.set(t.id, t);
1261
1371
  }),
1262
- delete: (t) => b.sync(() => {
1372
+ delete: (t) => y.sync(() => {
1263
1373
  e.delete(t);
1264
1374
  }),
1265
- getById: (t) => b.sync(() => e.get(t) ?? null),
1266
- listByRef: (t) => b.sync(() => [...e.values()].filter((e) => e.refId === t)),
1267
- deleteByRef: (t) => b.sync(() => {
1375
+ getById: (t) => y.sync(() => e.get(t) ?? null),
1376
+ listByRef: (t) => y.sync(() => [...e.values()].filter((e) => e.refId === t)),
1377
+ deleteByRef: (t) => y.sync(() => {
1268
1378
  for (let [n, r] of e) r.refId === t && e.delete(n);
1269
1379
  })
1270
1380
  };
1271
- }, Mt = (e) => ({
1381
+ }, Bt = (e) => ({
1272
1382
  id: String(e.id),
1273
1383
  refId: String(e.refId),
1274
1384
  principalType: e.principalType,
@@ -1277,12 +1387,12 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1277
1387
  createdAt: e.createdAt instanceof Date ? e.createdAt : new Date(String(e.createdAt)),
1278
1388
  expiresAt: e.expiresAt ? e.expiresAt instanceof Date ? e.expiresAt : new Date(String(e.expiresAt)) : null,
1279
1389
  createdBy: e.createdBy ?? null
1280
- }), Nt = (e) => ({
1281
- insert: (t) => Q(() => e.insert(U, { ...t })),
1282
- delete: (t) => Q(() => e.delete(U, t)),
1390
+ }), Vt = (e) => ({
1391
+ insert: (t) => Q(() => e.insert(W, { ...t })),
1392
+ delete: (t) => Q(() => e.delete(W, t)),
1283
1393
  getById: (t) => Q(async () => {
1284
1394
  let n = (await e.query({
1285
- table: U,
1395
+ table: W,
1286
1396
  predicate: {
1287
1397
  column: "id",
1288
1398
  op: "eq",
@@ -1293,10 +1403,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1293
1403
  skip: void 0,
1294
1404
  projection: void 0
1295
1405
  }))[0];
1296
- return n ? Mt(n) : null;
1406
+ return n ? Bt(n) : null;
1297
1407
  }),
1298
1408
  listByRef: (t) => Q(async () => (await e.query({
1299
- table: U,
1409
+ table: W,
1300
1410
  predicate: {
1301
1411
  column: "refId",
1302
1412
  op: "eq",
@@ -1309,10 +1419,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1309
1419
  take: void 0,
1310
1420
  skip: void 0,
1311
1421
  projection: void 0
1312
- })).map(Mt)),
1422
+ })).map(Bt)),
1313
1423
  deleteByRef: (t) => Q(async () => {
1314
1424
  let n = await e.query({
1315
- table: U,
1425
+ table: W,
1316
1426
  predicate: {
1317
1427
  column: "refId",
1318
1428
  op: "eq",
@@ -1323,23 +1433,23 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1323
1433
  skip: void 0,
1324
1434
  projection: void 0
1325
1435
  });
1326
- for (let t of n) await e.delete(U, String(t.id));
1436
+ for (let t of n) await e.delete(W, String(t.id));
1327
1437
  })
1328
- }), Pt = () => k({
1438
+ }), Ht = () => k({
1329
1439
  kind: "typeid",
1330
1440
  prefix: "file"
1331
- }, H), Ft = () => k({
1441
+ }, U), Ut = () => k({
1332
1442
  kind: "typeid",
1333
1443
  prefix: "grant"
1334
- }, U), It = (i) => {
1335
- let { provider: a, refStore: o, grantStore: s, bucket: c } = i, l = i.access ?? {}, u = i.attempts ?? 3, d = i.urlExpiresInSec ?? 3600, f = (e) => Ct(i.publicBaseUrl, e), p = C.recurs(Math.max(0, u - 1)).pipe(C.intersect(C.exponential("100 millis")), C.whileInput((e) => e.transient)), m = (e, t, n) => [
1444
+ }, W), Wt = (i) => {
1445
+ let { provider: a, refStore: o, grantStore: s, bucket: c } = i, l = i.access ?? {}, u = i.attempts ?? 3, d = i.urlExpiresInSec ?? 3600, f = (e) => At(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) => [
1336
1446
  i.tenantPrefix,
1337
1447
  e ?? "global",
1338
1448
  n ?? t
1339
1449
  ].filter(Boolean).join("/"), ee = (e) => {
1340
- if (e === void 0) return b.succeed(void 0);
1450
+ if (e === void 0) return y.succeed(void 0);
1341
1451
  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;
1342
- return n === void 0 ? b.succeed(e) : b.fail(new t({
1452
+ return n === void 0 ? y.succeed(e) : y.fail(new t({
1343
1453
  provider: a.name,
1344
1454
  message: `storage key rejected: ${n}`,
1345
1455
  transient: !1,
@@ -1351,19 +1461,19 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1351
1461
  "_incoming",
1352
1462
  t,
1353
1463
  String(n).padStart(6, "0")
1354
- ].filter(Boolean).join("/"), g = (e, n) => n !== void 0 && e.tenantId !== n ? b.fail(new t({
1464
+ ].filter(Boolean).join("/"), te = (e, n) => n !== void 0 && e.tenantId !== n ? y.fail(new t({
1355
1465
  provider: a.name,
1356
1466
  message: "cross-tenant access denied",
1357
1467
  transient: !1,
1358
1468
  status: 403
1359
- })) : b.succeed(e), _ = (e, n) => o.getById(e).pipe(b.flatMap((r) => r ? g(r, n) : b.fail(new t({
1469
+ })) : y.succeed(e), g = (e, n) => o.getById(e).pipe(y.flatMap((r) => r ? te(r, n) : y.fail(new t({
1360
1470
  provider: a.name,
1361
1471
  message: `no ref '${e}'`,
1362
1472
  transient: !1,
1363
1473
  status: 404
1364
- })))), te = (e) => b.suspend(() => {
1474
+ })))), ne = (e) => y.suspend(() => {
1365
1475
  let n = i.scan(e);
1366
- return b.isEffect(n) ? n : b.tryPromise({
1476
+ return y.isEffect(n) ? n : y.tryPromise({
1367
1477
  try: () => Promise.resolve(n),
1368
1478
  catch: (e) => new t({
1369
1479
  provider: "scan",
@@ -1371,61 +1481,61 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1371
1481
  transient: !0
1372
1482
  })
1373
1483
  });
1374
- }), ne = (e) => b.suspend(() => {
1484
+ }), re = (e) => y.suspend(() => {
1375
1485
  let t = e.contentType;
1376
- if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return b.succeed(null);
1486
+ if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return y.succeed(null);
1377
1487
  let n;
1378
1488
  try {
1379
1489
  n = i.videoProbe(e);
1380
1490
  } catch {
1381
- return b.succeed(null);
1491
+ return y.succeed(null);
1382
1492
  }
1383
- return b.isEffect(n) ? n.pipe(b.catchAll(() => b.succeed(null))) : b.tryPromise({
1493
+ return y.isEffect(n) ? n.pipe(y.catchAll(() => y.succeed(null))) : y.tryPromise({
1384
1494
  try: () => Promise.resolve(n),
1385
1495
  catch: () => null
1386
- }).pipe(b.catchAll(() => b.succeed(null)));
1387
- }), v = (e) => b.gen(function* () {
1388
- let t = bt(e.bytes, e.contentType, i.limits);
1389
- if (t) return yield* b.fail(new n(t));
1496
+ }).pipe(y.catchAll(() => y.succeed(null)));
1497
+ }), _ = (e) => y.gen(function* () {
1498
+ let t = Ct(e.bytes, e.contentType, i.limits);
1499
+ if (t) return yield* y.fail(new n(t));
1390
1500
  if (i.scan) {
1391
- let t = yield* te({
1501
+ let t = yield* ne({
1392
1502
  bytes: e.bytes,
1393
1503
  contentType: e.contentType,
1394
1504
  ...e.key ? { key: e.key } : {}
1395
1505
  });
1396
- if (!t.clean) return yield* b.fail(new r({ threat: t.threat ?? "unknown" }));
1506
+ if (!t.clean) return yield* y.fail(new r({ threat: t.threat ?? "unknown" }));
1397
1507
  }
1398
- let s = yield* b.promise(() => xt(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* ne({
1508
+ let s = yield* y.promise(() => wt(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* re({
1399
1509
  bytes: l,
1400
1510
  contentType: e.contentType
1401
- }), d = s.width ?? u?.width, f = s.height ?? u?.height, h = s.placeholder ?? u?.poster, g = e.duration ?? u?.duration, _ = yield* b.promise(() => St(l)), v = e.tenantId ?? null, y = e.visibility ?? "private", C = m(v, _, yield* ee(e.key)), w = {
1511
+ }), d = s.width ?? u?.width, f = s.height ?? u?.height, h = s.placeholder ?? u?.poster, te = e.duration ?? u?.duration, g = yield* y.promise(() => kt(l)), _ = e.tenantId ?? null, v = e.visibility ?? "private", S = m(_, g, yield* ee(e.key)), C = {
1402
1512
  bytes: l.byteLength,
1403
1513
  count: 1
1404
- }, T = yield* o.consumeUsage(v, w, i.quota);
1405
- if (!T.allowed) {
1406
- let e = i.quota ?? {}, t = e.maxCount !== void 0 && T.count + 1 > e.maxCount ? `tenant object count ${T.count} + 1 exceeds max ${e.maxCount}` : `tenant usage ${T.bytes} + ${l.byteLength} bytes exceeds max ${e.maxBytes}`;
1407
- return yield* b.fail(new n({
1514
+ }, w = yield* o.consumeUsage(_, C, i.quota);
1515
+ if (!w.allowed) {
1516
+ let e = i.quota ?? {}, t = e.maxCount !== void 0 && w.count + 1 > e.maxCount ? `tenant object count ${w.count} + 1 exceeds max ${e.maxCount}` : `tenant usage ${w.bytes} + ${l.byteLength} bytes exceeds max ${e.maxBytes}`;
1517
+ return yield* y.fail(new n({
1408
1518
  reason: "quota-exceeded",
1409
1519
  detail: t
1410
1520
  }));
1411
1521
  }
1412
- let re = e.password ? yield* b.sync(() => Je(e.password)) : null, E = {
1413
- id: Pt(),
1414
- tenantId: v,
1522
+ let ie = e.password ? yield* y.sync(() => Ze(e.password)) : null, T = {
1523
+ id: Ht(),
1524
+ tenantId: _,
1415
1525
  ownerId: e.ownerId ?? null,
1416
1526
  bucket: c,
1417
- key: C,
1527
+ key: S,
1418
1528
  contentType: e.contentType,
1419
1529
  size: l.byteLength,
1420
- checksum: _,
1421
- visibility: y,
1530
+ checksum: g,
1531
+ visibility: v,
1422
1532
  accessPolicy: e.access ?? null,
1423
- passwordHash: re,
1533
+ passwordHash: ie,
1424
1534
  createdAt: /* @__PURE__ */ new Date(),
1425
1535
  ...d === void 0 ? {} : { width: d },
1426
1536
  ...f === void 0 ? {} : { height: f },
1427
1537
  ...h === void 0 ? {} : { placeholder: h },
1428
- ...g === void 0 ? {} : { duration: g },
1538
+ ...te === void 0 ? {} : { duration: te },
1429
1539
  ...e.folder === void 0 ? {} : { folder: e.folder },
1430
1540
  ...e.tags === void 0 ? {} : { tags: e.tags },
1431
1541
  ...e.alt === void 0 ? {} : { alt: e.alt },
@@ -1433,31 +1543,31 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1433
1543
  ...e.derivedFrom === void 0 ? {} : { derivedFrom: e.derivedFrom },
1434
1544
  ...e.kind === void 0 ? {} : { kind: e.kind }
1435
1545
  };
1436
- return yield* ((e) => e.pipe(b.onExit((e) => x.isSuccess(e) ? b.void : o.delete(E.id).pipe(b.zipRight(o.releaseUsage(v, w)), b.ignore))))(o.insert(E).pipe(b.zipRight(a.put(C, l, {
1546
+ return yield* ((e) => e.pipe(y.onExit((e) => b.isSuccess(e) ? y.void : o.delete(T.id).pipe(y.zipRight(o.releaseUsage(_, C)), y.ignore))))(o.insert(T).pipe(y.zipRight(a.put(S, l, {
1437
1547
  contentType: e.contentType,
1438
- public: y === "public"
1439
- }).pipe(b.retry(p))))), i.transcode !== void 0 && i.autoTranscode !== !1 && E.derivedFrom == null && (e.contentType.startsWith("video/") || e.contentType.startsWith("audio/")) && (yield* b.forkDaemon(S(E).pipe(b.ignore))), E;
1440
- }), y = (e) => b.suspend(() => {
1441
- if (!i.transcode) return b.succeed([]);
1548
+ public: v === "public"
1549
+ }).pipe(y.retry(p))))), i.transcode !== void 0 && i.autoTranscode !== !1 && T.derivedFrom == null && (e.contentType.startsWith("video/") || e.contentType.startsWith("audio/")) && (yield* y.forkDaemon(x(T).pipe(y.ignore))), T;
1550
+ }), v = (e) => y.suspend(() => {
1551
+ if (!i.transcode) return y.succeed([]);
1442
1552
  let t;
1443
1553
  try {
1444
1554
  t = i.transcode(e);
1445
1555
  } catch {
1446
- return b.succeed([]);
1556
+ return y.succeed([]);
1447
1557
  }
1448
- return b.isEffect(t) ? t.pipe(b.catchAll(() => b.succeed([]))) : b.tryPromise({
1558
+ return y.isEffect(t) ? t.pipe(y.catchAll(() => y.succeed([]))) : y.tryPromise({
1449
1559
  try: () => Promise.resolve(t),
1450
1560
  catch: () => []
1451
- }).pipe(b.catchAll(() => b.succeed([])));
1452
- }), S = (e) => b.gen(function* () {
1561
+ }).pipe(y.catchAll(() => y.succeed([])));
1562
+ }), x = (e) => y.gen(function* () {
1453
1563
  if (!i.transcode || e.derivedFrom != null) return [];
1454
- let t = yield* a.get(e.key).pipe(b.retry(p)), n = yield* y({
1564
+ let t = yield* a.get(e.key).pipe(y.retry(p)), n = yield* v({
1455
1565
  bytes: t.bytes,
1456
1566
  contentType: e.contentType,
1457
1567
  ref: e
1458
1568
  }), r = [];
1459
1569
  for (let t of n) {
1460
- let n = yield* v({
1570
+ let n = yield* _({
1461
1571
  bytes: t.bytes,
1462
1572
  contentType: t.contentType,
1463
1573
  tenantId: e.tenantId,
@@ -1470,14 +1580,14 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1470
1580
  r.push(n);
1471
1581
  }
1472
1582
  return r;
1473
- }), w = (e, t, n) => b.gen(function* () {
1474
- if (e.visibility === "public" || (yield* nt(e, t, {
1583
+ }), C = (e, t, n) => y.gen(function* () {
1584
+ if (e.visibility === "public" || (yield* at(e, t, {
1475
1585
  ...l,
1476
1586
  ...n?.password === void 0 ? {} : { password: n.password }
1477
1587
  }))) return !0;
1478
- let r = yield* ot(t, l);
1479
- return at(yield* s.listByRef(e.id), t, r, n?.permission ?? "read", Date.now());
1480
- }), T = (e) => {
1588
+ let r = yield* lt(t, l);
1589
+ return ct(yield* s.listByRef(e.id), t, r, n?.permission ?? "read", Date.now());
1590
+ }), ie = (e) => {
1481
1591
  if (e.visibility === "public") {
1482
1592
  let t = a.publicUrl?.(e.key);
1483
1593
  if (t != null) return t;
@@ -1485,56 +1595,60 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1485
1595
  return f(e.id);
1486
1596
  };
1487
1597
  return {
1488
- put: v,
1489
- get: (e, t) => _(e, t?.tenantId).pipe(b.flatMap((e) => a.get(e.key).pipe(b.retry(p), b.map((t) => ({
1598
+ put: _,
1599
+ get: (e, t) => g(e, t?.tenantId).pipe(y.flatMap((e) => a.get(e.key).pipe(y.retry(p), y.map((t) => ({
1490
1600
  bytes: t.bytes,
1491
1601
  ref: e
1492
1602
  }))))),
1493
- getRange: (e, n, r) => _(e, r?.tenantId).pipe(b.flatMap((e) => {
1603
+ getStream: (e, t) => g(e, t?.tenantId).pipe(y.map((e) => ({
1604
+ ref: e,
1605
+ 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)))))
1606
+ }))),
1607
+ getRange: (e, n, r) => g(e, r?.tenantId).pipe(y.flatMap((e) => {
1494
1608
  let r = e.size, i = Math.max(0, Math.trunc(n.start));
1495
- if (r > 0 && i >= r) return b.fail(new t({
1609
+ if (r > 0 && i >= r) return y.fail(new t({
1496
1610
  provider: a.name,
1497
1611
  message: `range start ${i} past end ${r}`,
1498
1612
  transient: !1,
1499
1613
  status: 416
1500
1614
  }));
1501
1615
  let o = Math.min(Math.trunc(n.endInclusive), Math.max(0, r - 1));
1502
- return o < i ? b.fail(new t({
1616
+ return o < i ? y.fail(new t({
1503
1617
  provider: a.name,
1504
1618
  message: `empty range ${i}-${o}`,
1505
1619
  transient: !1,
1506
1620
  status: 416
1507
- })) : (a.getRange ? a.getRange(e.key, i, o).pipe(b.retry(p)) : a.get(e.key).pipe(b.retry(p), b.map((e) => e.bytes.subarray(i, o + 1)))).pipe(b.map((t) => ({
1621
+ })) : (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) => ({
1508
1622
  bytes: t,
1509
1623
  ref: e,
1510
1624
  totalSize: r
1511
1625
  })));
1512
1626
  })),
1513
- getUrl: (e, t) => _(e, t?.tenantId).pipe(b.flatMap((e) => e.visibility === "public" ? b.succeed(T(e)) : a.presigns ? a.getUrl(e.key, t?.expiresInSec ?? d) : b.succeed(f(e.id)))),
1514
- head: (e, t) => o.getById(e).pipe(b.flatMap((e) => e ? g(e, t?.tenantId).pipe(b.map((e) => e)) : b.succeed(null))),
1515
- delete: (e, t) => _(e, t?.tenantId).pipe(b.flatMap((t) => s.deleteByRef(e).pipe(b.flatMap(() => o.delete(e)), b.flatMap((e) => e ? o.countByKey(t.bucket, t.key).pipe(b.flatMap((e) => e === 0 ? a.delete(t.key).pipe(b.retry(p)) : b.void), b.flatMap(() => o.releaseUsage(t.tenantId, {
1627
+ getUrl: (e, t) => g(e, t?.tenantId).pipe(y.flatMap((e) => e.visibility === "public" ? y.succeed(ie(e)) : a.presigns ? a.getUrl(e.key, t?.expiresInSec ?? d) : y.succeed(f(e.id)))),
1628
+ head: (e, t) => o.getById(e).pipe(y.flatMap((e) => e ? te(e, t?.tenantId).pipe(y.map((e) => e)) : y.succeed(null))),
1629
+ delete: (e, t) => 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, {
1516
1630
  bytes: t.size,
1517
1631
  count: 1
1518
- }))) : b.void), b.asVoid))),
1519
- mintUrl: (n, r, i) => b.gen(function* () {
1520
- let s = yield* o.getById(n).pipe(b.flatMap((e) => e ? b.succeed(e) : b.fail(new t({
1632
+ }))) : y.void), y.asVoid))),
1633
+ mintUrl: (n, r, i) => y.gen(function* () {
1634
+ let s = yield* o.getById(n).pipe(y.flatMap((e) => e ? y.succeed(e) : y.fail(new t({
1521
1635
  provider: a.name,
1522
1636
  message: `no ref '${n}'`,
1523
1637
  transient: !1,
1524
1638
  status: 404
1525
1639
  }))));
1526
- if (s.visibility === "public") return T(s);
1527
- if (!(yield* w(s, r, i?.password === void 0 ? {} : { password: i.password }))) return yield* b.fail(new e({
1640
+ if (s.visibility === "public") return ie(s);
1641
+ if (!(yield* C(s, r, i?.password === void 0 ? {} : { password: i.password }))) return yield* y.fail(new e({
1528
1642
  refId: n,
1529
1643
  reason: "access denied"
1530
1644
  }));
1531
1645
  let c = i?.expiresInSec ?? d;
1532
1646
  if (a.presigns) return yield* a.getUrl(s.key, c);
1533
- let l = yield* b.sync(() => st(s.id, c));
1647
+ let l = yield* y.sync(() => ut(s.id, c));
1534
1648
  return `${f(s.id)}?t=${l}`;
1535
1649
  }),
1536
- mintUploadUrl: (e) => b.gen(function* () {
1537
- if (!a.getUploadUrl) return yield* b.fail(new t({
1650
+ mintUploadUrl: (e) => y.gen(function* () {
1651
+ if (!a.getUploadUrl) return yield* y.fail(new t({
1538
1652
  provider: a.name,
1539
1653
  message: `provider '${a.name}' does not support presigned uploads`,
1540
1654
  transient: !1,
@@ -1543,10 +1657,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1543
1657
  let n = m(e.tenantId ?? null, "", yield* ee(e.key));
1544
1658
  return yield* a.getUploadUrl(n, e.expiresInSec ?? d, e.contentType);
1545
1659
  }),
1546
- checkAccess: w,
1547
- grant: (e) => b.gen(function* () {
1660
+ checkAccess: C,
1661
+ grant: (e) => y.gen(function* () {
1548
1662
  let t = {
1549
- id: Ft(),
1663
+ id: Ut(),
1550
1664
  refId: e.refId,
1551
1665
  principalType: e.principalType,
1552
1666
  principalId: e.principalId,
@@ -1557,7 +1671,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1557
1671
  };
1558
1672
  return yield* s.insert(t), t;
1559
1673
  }),
1560
- listRefs: (e) => b.suspend(() => {
1674
+ listRefs: (e) => y.suspend(() => {
1561
1675
  let t = Math.min(500, Math.max(1, Math.trunc(e?.limit ?? 50))), n = Math.max(0, Math.trunc(e?.offset ?? 0)), r = {
1562
1676
  tenantId: e && "tenantId" in e ? e.tenantId : void 0,
1563
1677
  folder: e?.folder,
@@ -1567,7 +1681,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1567
1681
  limit: t + 1,
1568
1682
  offset: n
1569
1683
  };
1570
- return o.listRefs(r).pipe(b.map((e) => {
1684
+ return o.listRefs(r).pipe(y.map((e) => {
1571
1685
  let r = e.length > t;
1572
1686
  return {
1573
1687
  refs: r ? e.slice(0, t) : e,
@@ -1579,55 +1693,40 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1579
1693
  getGrant: (e) => s.getById(e),
1580
1694
  listGrants: (e) => s.listByRef(e),
1581
1695
  usage: (e) => o.usageByTenant(e),
1582
- sweepOrphans: (e) => b.gen(function* () {
1696
+ sweepOrphans: (e) => y.gen(function* () {
1583
1697
  let t = e?.limit ?? 1e3, n = e?.dryRun ?? !1, r = yield* o.listRecent(t), i = [];
1584
- for (let e of r) (yield* a.head(e.key).pipe(b.catchAll(() => b.succeed(null)))) === null && (n || (yield* o.delete(e.id).pipe(b.catchAll(() => b.succeed(!1)))) && (yield* o.releaseUsage(e.tenantId, {
1585
- bytes: e.size,
1586
- count: 1
1587
- }).pipe(b.ignore)), i.push(e.id));
1698
+ for (let e of r) if ((yield* a.head(e.key)) === null) {
1699
+ if (!n) {
1700
+ if (!(yield* o.delete(e.id))) continue;
1701
+ yield* o.releaseUsage(e.tenantId, {
1702
+ bytes: e.size,
1703
+ count: 1
1704
+ });
1705
+ }
1706
+ i.push(e.id);
1707
+ }
1588
1708
  return {
1589
1709
  scanned: r.length,
1590
1710
  removed: i
1591
1711
  };
1592
1712
  }),
1593
- ingestUrl: (e, n) => b.gen(function* () {
1594
- let r = yield* b.tryPromise({
1595
- try: () => fetch(e),
1596
- catch: (e) => new t({
1597
- provider: "ingest",
1598
- message: `fetch failed: ${String(e?.message ?? e)}`,
1599
- transient: !0
1600
- })
1601
- });
1602
- if (!r.ok) return yield* b.fail(new t({
1603
- provider: "ingest",
1604
- message: `fetch ${e} → ${r.status}`,
1605
- transient: r.status >= 500,
1606
- status: r.status
1607
- }));
1608
- let i = yield* b.tryPromise({
1609
- try: () => r.arrayBuffer(),
1610
- catch: (e) => new t({
1611
- provider: "ingest",
1612
- message: `read body failed: ${String(e?.message ?? e)}`,
1613
- transient: !0
1614
- })
1615
- }), a = n?.contentType ?? r.headers.get("content-type")?.split(";")[0]?.trim() ?? "application/octet-stream";
1616
- return yield* v({
1617
- bytes: new Uint8Array(i),
1618
- contentType: a,
1619
- ...n?.tenantId === void 0 ? {} : { tenantId: n.tenantId },
1620
- ...n?.ownerId === void 0 ? {} : { ownerId: n.ownerId },
1621
- ...n?.visibility === void 0 ? {} : { visibility: n.visibility },
1622
- ...n?.key === void 0 ? {} : { key: n.key },
1623
- ...n?.folder === void 0 ? {} : { folder: n.folder },
1624
- ...n?.tags === void 0 ? {} : { tags: n.tags },
1625
- ...n?.alt === void 0 ? {} : { alt: n.alt },
1626
- ...n?.caption === void 0 ? {} : { caption: n.caption }
1713
+ ingestUrl: (e, t) => Ot(y.gen(function* () {
1714
+ let n = yield* Dt(e, i.limits?.maxBytes);
1715
+ return yield* _({
1716
+ bytes: n.bytes,
1717
+ contentType: t?.contentType ?? n.contentType,
1718
+ ...t?.tenantId === void 0 ? {} : { tenantId: t.tenantId },
1719
+ ...t?.ownerId === void 0 ? {} : { ownerId: t.ownerId },
1720
+ ...t?.visibility === void 0 ? {} : { visibility: t.visibility },
1721
+ ...t?.key === void 0 ? {} : { key: t.key },
1722
+ ...t?.folder === void 0 ? {} : { folder: t.folder },
1723
+ ...t?.tags === void 0 ? {} : { tags: t.tags },
1724
+ ...t?.alt === void 0 ? {} : { alt: t.alt },
1725
+ ...t?.caption === void 0 ? {} : { caption: t.caption }
1627
1726
  });
1628
- }),
1629
- mintPresignedUpload: (e) => b.gen(function* () {
1630
- if (!a.getUploadUrl) return yield* b.fail(new t({
1727
+ }), t?.abortSignal),
1728
+ mintPresignedUpload: (e) => y.gen(function* () {
1729
+ if (!a.getUploadUrl) return yield* y.fail(new t({
1631
1730
  provider: a.name,
1632
1731
  message: `provider '${a.name}' does not support presigned uploads`,
1633
1732
  transient: !1,
@@ -1636,14 +1735,14 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1636
1735
  let n = e.expiresInSec ?? d, r = `_incoming/${k({
1637
1736
  kind: "typeid",
1638
1737
  prefix: "up"
1639
- }, H)}`, i = m(e.tenantId ?? null, "", r);
1738
+ }, U)}`, i = m(e.tenantId ?? null, "", r);
1640
1739
  return {
1641
1740
  uploadUrl: yield* a.getUploadUrl(i, n, e.contentType),
1642
1741
  key: i,
1643
1742
  expiresInSec: n
1644
1743
  };
1645
1744
  }),
1646
- finalizeUpload: (e) => a.get(e.key).pipe(b.retry(p), b.flatMap((t) => v({
1745
+ finalizeUpload: (e) => a.get(e.key).pipe(y.retry(p), y.flatMap((t) => _({
1647
1746
  bytes: t.bytes,
1648
1747
  contentType: e.contentType,
1649
1748
  ...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
@@ -1653,12 +1752,12 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1653
1752
  ...e.tags === void 0 ? {} : { tags: e.tags },
1654
1753
  ...e.alt === void 0 ? {} : { alt: e.alt },
1655
1754
  ...e.caption === void 0 ? {} : { caption: e.caption }
1656
- })), b.ensuring(a.delete(e.key).pipe(b.retry(p), b.ignore))),
1657
- putResumableChunk: (e) => a.put(h(e.tenantId ?? null, e.uploadId, e.index), e.bytes, { contentType: "application/octet-stream" }).pipe(b.retry(p), b.asVoid),
1658
- resumableStatus: (e) => b.gen(function* () {
1755
+ })), y.ensuring(a.delete(e.key).pipe(y.retry(p), y.ignore))),
1756
+ putResumableChunk: (e) => a.put(h(e.tenantId ?? null, e.uploadId, e.index), e.bytes, { contentType: "application/octet-stream" }).pipe(y.retry(p), y.asVoid),
1757
+ resumableStatus: (e) => y.gen(function* () {
1659
1758
  let t = 0, n = 0;
1660
1759
  for (; t < 1e6;) {
1661
- let r = yield* a.head(h(e.tenantId ?? null, e.uploadId, t)).pipe(b.retry(p), b.catchAll(() => b.succeed(null)));
1760
+ let r = yield* a.head(h(e.tenantId ?? null, e.uploadId, t)).pipe(y.retry(p), y.catchAll(() => y.succeed(null)));
1662
1761
  if (r === null) break;
1663
1762
  n += r.size, t += 1;
1664
1763
  }
@@ -1667,16 +1766,16 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1667
1766
  nextIndex: t
1668
1767
  };
1669
1768
  }),
1670
- finalizeResumable: (e) => b.gen(function* () {
1769
+ finalizeResumable: (e) => y.gen(function* () {
1671
1770
  let t = [];
1672
1771
  for (let n = 0; n < e.count; n++) {
1673
- let r = yield* a.get(h(e.tenantId ?? null, e.uploadId, n)).pipe(b.retry(p));
1772
+ let r = yield* a.get(h(e.tenantId ?? null, e.uploadId, n)).pipe(y.retry(p));
1674
1773
  t.push(r.bytes);
1675
1774
  }
1676
1775
  let n = t.reduce((e, t) => e + t.byteLength, 0), r = new Uint8Array(n), i = 0;
1677
1776
  for (let e of t) r.set(e, i), i += e.byteLength;
1678
- let o = b.forEach(Array.from({ length: e.count }, (e, t) => t), (t) => a.delete(h(e.tenantId ?? null, e.uploadId, t)).pipe(b.retry(p), b.ignore), { discard: !0 });
1679
- return yield* v({
1777
+ let o = y.forEach(Array.from({ length: e.count }, (e, t) => t), (t) => a.delete(h(e.tenantId ?? null, e.uploadId, t)).pipe(y.retry(p), y.ignore), { discard: !0 });
1778
+ return yield* _({
1680
1779
  bytes: r,
1681
1780
  contentType: e.contentType,
1682
1781
  ...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
@@ -1686,12 +1785,12 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1686
1785
  ...e.tags === void 0 ? {} : { tags: e.tags },
1687
1786
  ...e.alt === void 0 ? {} : { alt: e.alt },
1688
1787
  ...e.caption === void 0 ? {} : { caption: e.caption }
1689
- }).pipe(b.ensuring(o));
1788
+ }).pipe(y.ensuring(o));
1690
1789
  }),
1691
- transcode: (e, t) => _(e, t?.tenantId).pipe(b.flatMap((e) => S(e))),
1692
- renditions: (e, t) => _(e, t?.tenantId).pipe(b.flatMap(() => o.listByDerivedFrom(e))),
1693
- beginMultipartUpload: (e) => b.gen(function* () {
1694
- if (!a.createMultipartUpload || !a.presignUploadPart || !a.completeMultipartUpload) return yield* b.fail(new t({
1790
+ transcode: (e, t) => g(e, t?.tenantId).pipe(y.flatMap((e) => x(e))),
1791
+ renditions: (e, t) => g(e, t?.tenantId).pipe(y.flatMap(() => o.listByDerivedFrom(e))),
1792
+ beginMultipartUpload: (e) => y.gen(function* () {
1793
+ if (!a.createMultipartUpload || !a.presignUploadPart || !a.completeMultipartUpload) return yield* y.fail(new t({
1695
1794
  provider: a.name,
1696
1795
  message: `provider '${a.name}' does not support multipart uploads`,
1697
1796
  transient: !1,
@@ -1700,35 +1799,35 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1700
1799
  let n = m(e.tenantId ?? null, "", `multipart/${k({
1701
1800
  kind: "typeid",
1702
1801
  prefix: "mp"
1703
- }, H)}`);
1802
+ }, U)}`);
1704
1803
  return {
1705
1804
  uploadId: (yield* a.createMultipartUpload(n, e.contentType, { public: (e.visibility ?? "private") === "public" })).uploadId,
1706
1805
  key: n
1707
1806
  };
1708
1807
  }),
1709
- signMultipartPart: (e) => b.suspend(() => a.presignUploadPart ? a.presignUploadPart(e.key, e.uploadId, e.partNumber, e.expiresInSec ?? d) : b.fail(new t({
1808
+ signMultipartPart: (e) => y.suspend(() => a.presignUploadPart ? a.presignUploadPart(e.key, e.uploadId, e.partNumber, e.expiresInSec ?? d) : y.fail(new t({
1710
1809
  provider: a.name,
1711
1810
  message: "provider does not support multipart uploads",
1712
1811
  transient: !1,
1713
1812
  status: 400
1714
1813
  }))),
1715
- completeMultipart: (e) => b.gen(function* () {
1716
- if (!a.completeMultipartUpload) return yield* b.fail(new t({
1814
+ completeMultipart: (e) => y.gen(function* () {
1815
+ if (!a.completeMultipartUpload) return yield* y.fail(new t({
1717
1816
  provider: a.name,
1718
1817
  message: "provider does not support multipart uploads",
1719
1818
  transient: !1,
1720
1819
  status: 400
1721
1820
  }));
1722
- let r = yield* a.completeMultipartUpload(e.key, e.uploadId, e.parts), s = yield* a.head(e.key).pipe(b.retry(p)), l = s?.size ?? 0, u = (r.etag ?? s?.etag ?? "").replace(/"/g, ""), d = e.tenantId ?? null, f = {
1821
+ 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 = {
1723
1822
  bytes: l,
1724
1823
  count: 1
1725
1824
  };
1726
- if (!(yield* o.consumeUsage(d, f, i.quota)).allowed) return yield* a.delete(e.key).pipe(b.retry(p), b.ignore), yield* b.fail(new n({
1825
+ 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({
1727
1826
  reason: "quota-exceeded",
1728
1827
  detail: `multipart upload of ${l} bytes exceeds tenant quota`
1729
1828
  }));
1730
1829
  let m = {
1731
- id: Pt(),
1830
+ id: Ht(),
1732
1831
  tenantId: e.tenantId ?? null,
1733
1832
  ownerId: e.ownerId ?? null,
1734
1833
  bucket: c,
@@ -1745,11 +1844,11 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1745
1844
  ...e.alt === void 0 ? {} : { alt: e.alt },
1746
1845
  ...e.caption === void 0 ? {} : { caption: e.caption }
1747
1846
  };
1748
- return yield* o.insert(m).pipe(b.onExit((e) => x.isSuccess(e) ? b.void : o.releaseUsage(d, f).pipe(b.ignore))), m;
1847
+ return yield* o.insert(m).pipe(y.onExit((e) => b.isSuccess(e) ? y.void : o.releaseUsage(d, f).pipe(y.ignore))), m;
1749
1848
  }),
1750
- abortMultipart: (e) => b.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(b.retry(p)) : b.void)
1849
+ abortMultipart: (e) => y.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(y.retry(p)) : y.void)
1751
1850
  };
1752
- }, Lt = (e) => S.succeed(i, It(e)), Rt = (e, t = 65536) => {
1851
+ }, Gt = (e) => x.succeed(i, Wt(e)), Kt = (e, t = 65536) => {
1753
1852
  let n = [Buffer.from("zINSTREAM\0", "utf8")];
1754
1853
  for (let r = 0; r < e.length; r += t) {
1755
1854
  let i = e.subarray(r, Math.min(r + t, e.length)), a = Buffer.alloc(4);
@@ -1757,7 +1856,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1757
1856
  }
1758
1857
  let r = Buffer.alloc(4);
1759
1858
  return r.writeUInt32BE(0, 0), n.push(r), Buffer.concat(n);
1760
- }, zt = (e) => {
1859
+ }, qt = (e) => {
1761
1860
  let t = e.replace(/\0+$/, "").trim();
1762
1861
  if (/\bOK$/.test(t)) return { clean: !0 };
1763
1862
  let n = /:\s*(.+?)\s+FOUND$/.exec(t);
@@ -1766,8 +1865,8 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1766
1865
  threat: n[1] ?? "unknown"
1767
1866
  };
1768
1867
  throw Error(`clamav: unexpected response: ${t}`);
1769
- }, Bt = async (e, t) => {
1770
- let n = await import("node:net"), r = G.read("CLAMAV_HOST", t.host) ?? "127.0.0.1", i = G.read("CLAMAV_PORT"), a = t.port ?? (i ? Number(i) : 3310), o = t.timeoutMs ?? 3e4;
1868
+ }, Jt = async (e, t) => {
1869
+ let n = await import("node:net"), r = K.read("CLAMAV_HOST", t.host) ?? "127.0.0.1", i = K.read("CLAMAV_PORT"), a = t.port ?? (i ? Number(i) : 3310), o = t.timeoutMs ?? 3e4;
1771
1870
  return new Promise((i, s) => {
1772
1871
  let c = n.createConnection({
1773
1872
  host: r,
@@ -1778,20 +1877,20 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1778
1877
  c.on("error", (e) => {
1779
1878
  clearTimeout(u), s(e);
1780
1879
  }), c.on("connect", () => {
1781
- c.end(Rt(e, t.chunkSize));
1880
+ c.end(Kt(e, t.chunkSize));
1782
1881
  }), c.on("data", (e) => {
1783
1882
  l += e.toString("utf8");
1784
1883
  }), c.on("close", () => {
1785
1884
  clearTimeout(u);
1786
1885
  try {
1787
- i(zt(l));
1886
+ i(qt(l));
1788
1887
  } catch (e) {
1789
1888
  s(e);
1790
1889
  }
1791
1890
  });
1792
1891
  });
1793
- }, Vt = (e = {}) => (t) => Bt(t.bytes, e), Ht = (e, t, n) => new Promise((r, i) => {
1794
- let a = de(e, [...t], { stdio: [
1892
+ }, Yt = (e = {}) => (t) => Jt(t.bytes, e), Xt = (e, t, n) => new Promise((r, i) => {
1893
+ let a = pe(e, [...t], { stdio: [
1795
1894
  "ignore",
1796
1895
  "ignore",
1797
1896
  "pipe"
@@ -1805,31 +1904,31 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1805
1904
  }), a.on("close", (e) => {
1806
1905
  clearTimeout(s), e === 0 ? r() : i(/* @__PURE__ */ Error(`ffmpeg exited ${String(e)}: ${o.slice(-400)}`));
1807
1906
  });
1808
- }), Ut = (e) => async ({ bytes: t }) => {
1809
- let n = e.ffmpegPath ?? "ffmpeg", r = e.timeoutMs ?? 3e5, i = await fe(he(V(), "voltro-tc-")), a = he(i, "in"), o = [];
1907
+ }), Zt = (e) => async ({ bytes: t }) => {
1908
+ let n = e.ffmpegPath ?? "ffmpeg", r = e.timeoutMs ?? 3e5, i = await me(V(ve(), "voltro-tc-")), a = V(i, "in"), o = [];
1810
1909
  try {
1811
- await B(a, t);
1910
+ await _e(a, t);
1812
1911
  for (let t of e.renditions) {
1813
- let e = he(i, `out.${t.ext}`);
1912
+ let e = V(i, `out.${t.ext}`);
1814
1913
  try {
1815
- await Ht(n, [
1914
+ await Xt(n, [
1816
1915
  "-y",
1817
1916
  "-i",
1818
1917
  a,
1819
1918
  ...t.args,
1820
1919
  e
1821
1920
  ], r);
1822
- let i = await pe(e);
1921
+ let i = await he(e);
1823
1922
  o.push({
1824
1923
  bytes: new Uint8Array(i),
1825
1924
  contentType: t.contentType,
1826
1925
  kind: t.kind,
1827
1926
  ...t.label === void 0 ? {} : { label: t.label }
1828
- }), await me(e, { force: !0 });
1927
+ }), await ge(e, { force: !0 });
1829
1928
  } catch {}
1830
1929
  }
1831
1930
  } finally {
1832
- await me(i, {
1931
+ await ge(i, {
1833
1932
  recursive: !0,
1834
1933
  force: !0
1835
1934
  }).catch(() => void 0);
@@ -1838,21 +1937,21 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
1838
1937
  };
1839
1938
  //#endregion
1840
1939
  //#region src/assetRef.ts
1841
- function Wt(e = {}) {
1842
- let t = e.nullable ?? !0, n = e.fk === !1 ? P().externalId() : ce(() => De, { onDelete: e.onDelete ?? "setNull" });
1940
+ function Qt(e = {}) {
1941
+ let t = e.nullable ?? !0, n = e.fk === !1 ? I().externalId() : le(() => ke, { onDelete: e.onDelete ?? "setNull" });
1843
1942
  return t ? n.nullable() : n;
1844
1943
  }
1845
- var Gt = () => se({
1944
+ var $t = () => N({
1846
1945
  id: "@voltro/plugin-storage/withStorage",
1847
- fields: { asset: Wt() }
1848
- }), Kt = {
1946
+ fields: { asset: Qt() }
1947
+ }), en = {
1849
1948
  "image/png": "png",
1850
1949
  "image/jpeg": "jpg",
1851
1950
  "image/jpg": "jpg",
1852
1951
  "image/gif": "gif",
1853
1952
  "image/webp": "webp",
1854
1953
  "image/svg+xml": "svg"
1855
- }, qt = (e) => {
1954
+ }, tn = (e) => {
1856
1955
  let t = /^data:([^;,]+)(;base64)?,(.*)$/s.exec(e);
1857
1956
  if (!t) throw Error("not a data URI");
1858
1957
  let n = t[1] || "application/octet-stream", r = !!t[2], i = t[3] ?? "";
@@ -1860,16 +1959,16 @@ var Gt = () => se({
1860
1959
  bytes: r ? new Uint8Array(Buffer.from(i, "base64")) : new Uint8Array(Buffer.from(decodeURIComponent(i), "utf8")),
1861
1960
  contentType: n
1862
1961
  };
1863
- }, Jt = (e, n) => b.gen(function* () {
1864
- let r = yield* b.try({
1865
- try: () => qt(n.dataUri),
1962
+ }, nn = (e, n) => y.gen(function* () {
1963
+ let r = yield* y.try({
1964
+ try: () => tn(n.dataUri),
1866
1965
  catch: (e) => new t({
1867
1966
  provider: "avatar",
1868
1967
  message: String(e?.message ?? e),
1869
1968
  transient: !1,
1870
1969
  status: 400
1871
1970
  })
1872
- }), i = Kt[r.contentType] ?? "bin";
1971
+ }), i = en[r.contentType] ?? "bin";
1873
1972
  return yield* e.put({
1874
1973
  bytes: r.bytes,
1875
1974
  contentType: r.contentType,
@@ -1878,27 +1977,43 @@ var Gt = () => se({
1878
1977
  visibility: "public",
1879
1978
  key: `avatars/${n.userId}/avatar.${i}`
1880
1979
  });
1881
- }), Yt = (e) => {
1980
+ }), rn = F("_voltro_storage_put_intents", {
1981
+ id: I().maxLength(64),
1982
+ refId: I().maxLength(64),
1983
+ identity: M(),
1984
+ ref: M()
1985
+ }).primaryKey(["id"]).unique("storagePutRef", ["refId"]).nonReactive();
1986
+ C.Struct({
1987
+ tenantId: C.NullOr(C.String),
1988
+ bucket: C.String,
1989
+ operationId: C.String,
1990
+ fingerprint: C.String,
1991
+ checksum: C.String,
1992
+ logicalKey: C.String
1993
+ });
1994
+ //#endregion
1995
+ //#region src/pathDurability.ts
1996
+ var an = (e) => {
1882
1997
  try {
1883
- let t = ge(e), n = ge("/");
1998
+ let t = H(e), n = H("/");
1884
1999
  return typeof t.dev != "number" || typeof n.dev != "number" ? "unknown" : t.dev === n.dev ? "same-device-as-root" : "separate-mount";
1885
2000
  } catch {
1886
2001
  return "unknown";
1887
2002
  }
1888
- }, Xt = (e) => {
1889
- if (Yt(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
2003
+ }, on = (e) => {
2004
+ if (an(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
1890
2005
  dies with it — which is the exact failure it exists for. On a development machine this is normal
1891
2006
  and can be ignored.`;
1892
- }, Zt = G.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", Qt, $t = (e) => {
1893
- Qt = e;
1894
- }, en = () => Qt ?? nn({}), tn = () => Qt === void 0 ? G.read("STORAGE_PROVIDER") === void 0 ? void 0 : nn({}) : Qt, nn = (e) => {
2007
+ }, sn = K.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", cn, ln = (e) => {
2008
+ cn = e;
2009
+ }, un = () => cn ?? fn({}), dn = () => cn === void 0 ? K.read("STORAGE_PROVIDER") === void 0 ? void 0 : fn({}) : cn, fn = (e) => {
1895
2010
  if (e.provider && typeof e.provider == "object") return e.provider;
1896
- let t = (e.provider ?? G.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = G.read("S3_BUCKET", e.bucket) ?? G.read("STORAGE_BUCKET") ?? "voltro";
2011
+ let t = (e.provider ?? K.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = K.read("S3_BUCKET", e.bucket) ?? K.read("STORAGE_BUCKET") ?? "voltro";
1897
2012
  switch (t) {
1898
2013
  case "s3":
1899
2014
  case "minio": {
1900
- let r = G.read("S3_REGION", e.region) ?? G.read("AWS_REGION"), i = G.read("S3_ENDPOINT", e.endpoint) ?? G.read("MINIO_ENDPOINT"), a = G.read("S3_ACCESS_KEY_ID", e.accessKeyId) ?? G.read("AWS_ACCESS_KEY_ID"), o = G.read("S3_SECRET_ACCESS_KEY", e.secretAccessKey) ?? G.read("AWS_SECRET_ACCESS_KEY"), s = G.read("STORAGE_CDN_URL", e.cdnBaseUrl);
1901
- return Le({
2015
+ let r = K.read("S3_REGION", e.region) ?? K.read("AWS_REGION"), i = K.read("S3_ENDPOINT", e.endpoint) ?? K.read("MINIO_ENDPOINT"), a = K.read("S3_ACCESS_KEY_ID", e.accessKeyId) ?? K.read("AWS_ACCESS_KEY_ID"), o = K.read("S3_SECRET_ACCESS_KEY", e.secretAccessKey) ?? K.read("AWS_SECRET_ACCESS_KEY"), s = K.read("STORAGE_CDN_URL", e.cdnBaseUrl);
2016
+ return ze({
1902
2017
  bucket: n,
1903
2018
  name: t,
1904
2019
  ...r ? { region: r } : {},
@@ -1907,13 +2022,13 @@ var Gt = () => se({
1907
2022
  ...o ? { secretAccessKey: o } : {},
1908
2023
  ...s ? { cdnBaseUrl: s } : {},
1909
2024
  ...e.publicAcl === void 0 ? {} : { publicAcl: e.publicAcl },
1910
- ...t === "minio" || G.read("S3_FORCE_PATH_STYLE") === "1" ? { forcePathStyle: !0 } : {}
2025
+ ...t === "minio" || K.read("S3_FORCE_PATH_STYLE") === "1" ? { forcePathStyle: !0 } : {}
1911
2026
  });
1912
2027
  }
1913
2028
  case "azure": {
1914
- let t = G.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = G.read("AZURE_STORAGE_KEY", e.accountKey), i = G.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString), a = G.read("AZURE_STORAGE_ENDPOINT", e.endpoint), o = G.read("STORAGE_CDN_URL", e.cdnBaseUrl);
1915
- return Be({
1916
- container: G.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
2029
+ let t = K.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = K.read("AZURE_STORAGE_KEY", e.accountKey), i = K.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString), a = K.read("AZURE_STORAGE_ENDPOINT", e.endpoint), o = K.read("STORAGE_CDN_URL", e.cdnBaseUrl);
2030
+ return He({
2031
+ container: K.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
1917
2032
  ...t ? { accountName: t } : {},
1918
2033
  ...r ? { accountKey: r } : {},
1919
2034
  ...i ? { connectionString: i } : {},
@@ -1921,15 +2036,15 @@ var Gt = () => se({
1921
2036
  ...o ? { cdnBaseUrl: o } : {}
1922
2037
  });
1923
2038
  }
1924
- case "database": return ze();
1925
- case "filesystem": return Ie({ root: G.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
1926
- default: return Fe(e.name ?? "default");
2039
+ case "database": return Ve();
2040
+ case "filesystem": return Re({ root: K.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
2041
+ default: return Le(e.name ?? "default");
1927
2042
  }
1928
- }, rn = (e) => {
2043
+ }, pn = (e) => {
1929
2044
  if (e !== void 0) return e;
1930
- let t = G.read("STORAGE_ALLOWED_ORIGINS");
2045
+ let t = K.read("STORAGE_ALLOWED_ORIGINS");
1931
2046
  return t ? t.trim() === "*" ? "*" : t.split(",").map((e) => e.trim()).filter(Boolean) : [];
1932
- }, an = (e, t) => {
2047
+ }, mn = (e, t) => {
1933
2048
  if (!e || t !== "*" && !t.includes(e)) return {};
1934
2049
  let n = {
1935
2050
  "access-control-allow-origin": t === "*" ? "*" : e,
@@ -1939,7 +2054,7 @@ var Gt = () => se({
1939
2054
  vary: "Origin"
1940
2055
  };
1941
2056
  return t !== "*" && (n["access-control-allow-credentials"] = "true"), n;
1942
- }, on = (e) => ({
2057
+ }, hn = (e) => ({
1943
2058
  id: e.id,
1944
2059
  tenantId: e.tenantId,
1945
2060
  ownerId: e.ownerId,
@@ -1962,29 +2077,29 @@ var Gt = () => se({
1962
2077
  caption: e.caption ?? null,
1963
2078
  derivedFrom: e.derivedFrom ?? null,
1964
2079
  kind: e.kind ?? null
1965
- }), sn = () => new t({
2080
+ }), gn = () => new t({
1966
2081
  provider: "storage",
1967
2082
  message: "not permitted to administer sharing for this object",
1968
2083
  transient: !1,
1969
2084
  status: 403
1970
- }), cn = (e, t, n) => {
2085
+ }), _n = (e, t, n) => {
1971
2086
  let r = n.request.subject;
1972
- return (r.scopes ?? []).includes("admin:full") ? b.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(b.catchAll(() => b.fail(sn())), b.flatMap((e) => {
2087
+ return (r.scopes ?? []).includes("admin:full") ? y.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(y.catchAll(() => y.fail(gn())), y.flatMap((e) => {
1973
2088
  let t = e?.ownerId;
1974
- return t != null && t === r.id ? b.void : b.fail(sn());
2089
+ return t != null && t === r.id ? y.void : y.fail(gn());
1975
2090
  }));
1976
- }, ln = () => new t({
2091
+ }, vn = () => new t({
1977
2092
  provider: "storage",
1978
2093
  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.",
1979
2094
  transient: !1,
1980
2095
  status: 401
1981
2096
  }), $ = (e, t) => {
1982
2097
  let n = e.request.subject.id ?? null, r = e.request.subject.tenantId ?? null;
1983
- return n === null && !t ? b.fail(ln()) : b.succeed({
2098
+ return n === null && !t ? y.fail(vn()) : y.succeed({
1984
2099
  id: n,
1985
2100
  tenantId: r
1986
2101
  });
1987
- }, un = (e, t) => e !== null && e !== (t ?? null), dn = (e) => ({
2102
+ }, yn = (e, t) => e !== null && e !== (t ?? null), bn = (e) => ({
1988
2103
  id: e.id,
1989
2104
  refId: e.refId,
1990
2105
  principalType: e.principalType,
@@ -1993,31 +2108,41 @@ var Gt = () => se({
1993
2108
  createdAt: e.createdAt.toISOString(),
1994
2109
  expiresAt: e.expiresAt ? e.expiresAt.toISOString() : null,
1995
2110
  createdBy: e.createdBy
1996
- }), fn = "@voltro/plugin-storage", pn = (i = {}) => {
1997
- let y = nn(i);
1998
- $t(y);
1999
- let x = G.read("S3_BUCKET", i.bucket) ?? G.read("STORAGE_BUCKET") ?? "voltro", S = G.read("VOLTRO_PUBLIC_URL", i.publicBaseUrl), C = rn(i.allowedOrigins), w = i.limits?.maxBytes, D = i.anonymousUploads === !0, oe = 5242880, O = 21600, k = i.refStore === void 0 || i.refStore === "memory", A = i.grantStore === void 0 || i.grantStore === "memory", j = { current: k ? Et() : i.refStore }, M = { current: A ? jt() : i.grantStore }, se = {
2000
- insert: (e) => j.current.insert(e),
2001
- getById: (e) => j.current.getById(e),
2002
- delete: (e) => j.current.delete(e),
2003
- listRecent: (e) => j.current.listRecent(e),
2004
- countByKey: (e, t) => j.current.countByKey(e, t),
2005
- usageByTenant: (e) => j.current.usageByTenant(e),
2006
- consumeUsage: (e, t, n) => j.current.consumeUsage(e, t, n),
2007
- releaseUsage: (e, t) => j.current.releaseUsage(e, t),
2008
- listByDerivedFrom: (e) => j.current.listByDerivedFrom(e),
2009
- listRefs: (e) => j.current.listRefs(e)
2010
- }, ce = {
2011
- insert: (e) => M.current.insert(e),
2012
- delete: (e) => M.current.delete(e),
2013
- getById: (e) => M.current.getById(e),
2014
- listByRef: (e) => M.current.listByRef(e),
2015
- deleteByRef: (e) => M.current.deleteByRef(e)
2016
- }, N = {
2017
- provider: y,
2018
- refStore: se,
2019
- grantStore: ce,
2020
- bucket: x,
2111
+ }), xn = "@voltro/plugin-storage", Sn = (e = {}) => T({
2112
+ base: xn,
2113
+ alias: e.alias,
2114
+ instance: e.name
2115
+ }), Cn = (i = {}) => {
2116
+ let v = T({
2117
+ base: xn,
2118
+ alias: i.alias,
2119
+ instance: i.name
2120
+ }), b = v === xn ? "/_voltro/storage" : `/_voltro/storage/i/${Buffer.from(v).toString("hex")}`, x = fn(i);
2121
+ ln(x);
2122
+ let S = K.read("S3_BUCKET", i.bucket) ?? K.read("STORAGE_BUCKET") ?? "voltro", E = K.read("VOLTRO_PUBLIC_URL", i.publicBaseUrl), ce = pn(i.allowedOrigins), D = i.limits?.maxBytes, O = i.anonymousUploads === !0, k = 5242880, A = 21600, j = i.refStore === void 0 || i.refStore === "memory", M = i.grantStore === void 0 || i.grantStore === "memory", N = { current: j ? Pt() : i.refStore }, P = { current: M ? zt() : i.grantStore }, le = {
2123
+ insert: (e) => N.current.insert(e),
2124
+ getById: (e) => N.current.getById(e),
2125
+ delete: (e) => N.current.delete(e),
2126
+ statistics: () => N.current.statistics(),
2127
+ listRecent: (e) => N.current.listRecent(e),
2128
+ countByKey: (e, t) => N.current.countByKey(e, t),
2129
+ usageByTenant: (e) => N.current.usageByTenant(e),
2130
+ consumeUsage: (e, t, n) => N.current.consumeUsage(e, t, n),
2131
+ releaseUsage: (e, t) => N.current.releaseUsage(e, t),
2132
+ listByDerivedFrom: (e) => N.current.listByDerivedFrom(e),
2133
+ listRefs: (e) => N.current.listRefs(e)
2134
+ }, F = {
2135
+ insert: (e) => P.current.insert(e),
2136
+ delete: (e) => P.current.delete(e),
2137
+ getById: (e) => P.current.getById(e),
2138
+ listByRef: (e) => P.current.listByRef(e),
2139
+ deleteByRef: (e) => P.current.deleteByRef(e)
2140
+ }, I = {
2141
+ httpPath: b,
2142
+ provider: x,
2143
+ refStore: le,
2144
+ grantStore: F,
2145
+ bucket: S,
2021
2146
  ...i.tenantPrefix === void 0 ? {} : { tenantPrefix: i.tenantPrefix },
2022
2147
  ...i.attempts === void 0 ? {} : { attempts: i.attempts },
2023
2148
  ...i.urlExpiresInSec === void 0 ? {} : { urlExpiresInSec: i.urlExpiresInSec },
@@ -2027,10 +2152,10 @@ var Gt = () => se({
2027
2152
  ...i.videoProbe === void 0 ? {} : { videoProbe: i.videoProbe },
2028
2153
  ...i.transcode === void 0 ? {} : { transcode: i.transcode },
2029
2154
  ...i.autoTranscode === void 0 ? {} : { autoTranscode: i.autoTranscode },
2030
- ...S ? { publicBaseUrl: S } : {},
2155
+ ...E ? { publicBaseUrl: E } : {},
2031
2156
  ...i.normalizeImages === void 0 ? {} : { normalizeImages: i.normalizeImages },
2032
2157
  ...i.quota === void 0 ? {} : { quota: i.quota }
2033
- }, P = Lt(N), F = It(N), I = (e) => b.runPromise(e.pipe(b.catchAll(() => b.succeed(null)))), L = (e, t) => {
2158
+ }, ue = Gt(I), L = Wt(I), R = `${b}/`, z = (e) => y.runPromise(e.pipe(y.catchAll(() => y.succeed(null)))), fe = (e, t) => {
2034
2159
  if (!e) return "invalid";
2035
2160
  let n = /^bytes=(\d*)-(\d*)$/.exec(e.trim());
2036
2161
  if (!n) return "invalid";
@@ -2051,30 +2176,30 @@ var Gt = () => se({
2051
2176
  start: a,
2052
2177
  endInclusive: o
2053
2178
  };
2054
- }, le = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, R = (e) => ({
2179
+ }, B = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, pe = (e) => ({
2055
2180
  "x-content-type-options": "nosniff",
2056
- "content-disposition": le.test(e) ? "inline" : "attachment"
2057
- }), z = async (e, t, n, r) => {
2181
+ "content-disposition": B.test(e) ? "inline" : "attachment"
2182
+ }), me = async (e, t, n, r) => {
2058
2183
  if (n) {
2059
- let r = await I(F.get(e.id));
2184
+ let r = await z(L.get(e.id));
2060
2185
  if (!r) return {
2061
2186
  status: 404,
2062
2187
  body: "not found",
2063
2188
  contentType: "text/plain"
2064
2189
  };
2065
- let i = await qe(e.id, r.bytes, e.contentType, n).catch(() => null), a = i ? i.bytes : r.bytes, o = i ? i.contentType : e.contentType;
2190
+ let i = await Xe(e.id, r.bytes, e.contentType, n).catch(() => null), a = i ? i.bytes : r.bytes, o = i ? i.contentType : e.contentType;
2066
2191
  return {
2067
2192
  status: 200,
2068
2193
  body: a,
2069
2194
  contentType: o,
2070
2195
  headers: {
2071
- ...R(o),
2196
+ ...pe(o),
2072
2197
  "cache-control": t,
2073
2198
  "accept-ranges": "none"
2074
2199
  }
2075
2200
  };
2076
2201
  }
2077
- let i = r === void 0 ? "invalid" : L(r, e.size);
2202
+ let i = r === void 0 ? "invalid" : fe(r, e.size);
2078
2203
  if (i === "unsatisfiable") return {
2079
2204
  status: 416,
2080
2205
  body: "range not satisfiable",
@@ -2085,13 +2210,13 @@ var Gt = () => se({
2085
2210
  }
2086
2211
  };
2087
2212
  if (i !== "invalid") {
2088
- let n = await I(F.getRange(e.id, i));
2213
+ let n = await z(L.getRange(e.id, i));
2089
2214
  return n ? {
2090
2215
  status: 206,
2091
2216
  body: n.bytes,
2092
2217
  contentType: e.contentType,
2093
2218
  headers: {
2094
- ...R(e.contentType),
2219
+ ...pe(e.contentType),
2095
2220
  "cache-control": t,
2096
2221
  "accept-ranges": "bytes",
2097
2222
  "content-range": `bytes ${i.start}-${i.endInclusive}/${n.totalSize}`
@@ -2102,75 +2227,64 @@ var Gt = () => se({
2102
2227
  contentType: "text/plain"
2103
2228
  };
2104
2229
  }
2105
- let a = await I(F.get(e.id));
2106
- if (!a) return {
2107
- status: 404,
2108
- body: "not found",
2109
- contentType: "text/plain"
2110
- };
2111
- let o = 1048576;
2112
- return {
2230
+ let a = await z(L.getStream(e.id));
2231
+ return a ? {
2113
2232
  status: 200,
2114
2233
  contentType: e.contentType,
2115
2234
  headers: {
2116
- ...R(e.contentType),
2235
+ ...pe(e.contentType),
2117
2236
  "cache-control": t,
2118
2237
  "accept-ranges": "bytes"
2119
2238
  },
2120
2239
  byteStream: {
2121
- contentLength: a.bytes.length,
2122
- stream: () => {
2123
- let e = 0;
2124
- return new ReadableStream({ pull(t) {
2125
- if (e >= a.bytes.length) {
2126
- t.close();
2127
- return;
2128
- }
2129
- t.enqueue(a.bytes.subarray(e, e + o)), e += o;
2130
- } });
2131
- }
2240
+ contentLength: e.size,
2241
+ stream: () => w.toReadableStream(a.stream)
2132
2242
  }
2243
+ } : {
2244
+ status: 404,
2245
+ body: "not found",
2246
+ contentType: "text/plain"
2133
2247
  };
2134
- }, de = async (e) => {
2135
- let t = e.path.startsWith("/_voltro/storage/") ? e.path.slice(17).split("/")[0] ?? "" : "";
2248
+ }, he = async (e) => {
2249
+ let t = e.path.startsWith(R) ? e.path.slice(R.length).split("/")[0] ?? "" : "";
2136
2250
  if (!t) return {
2137
2251
  status: 404,
2138
2252
  body: "not found",
2139
2253
  contentType: "text/plain"
2140
2254
  };
2141
- let n = await I(F.head(t));
2255
+ let n = await z(L.head(t));
2142
2256
  if (!n) return {
2143
2257
  status: 404,
2144
2258
  body: "not found",
2145
2259
  contentType: "text/plain"
2146
2260
  };
2147
- let r = He(e.query), i = e.headers.range;
2261
+ let r = We(e.query), i = e.headers.range;
2148
2262
  if (n.visibility === "public") {
2149
- let e = y.publicUrl?.(n.key) ?? null;
2263
+ let e = x.publicUrl?.(n.key) ?? null;
2150
2264
  return e && !r ? {
2151
2265
  status: 302,
2152
2266
  headers: {
2153
2267
  location: e,
2154
2268
  "cache-control": "public, max-age=300"
2155
2269
  }
2156
- } : z(n, "public, max-age=31536000, immutable", r, i);
2270
+ } : me(n, "public, max-age=31536000, immutable", r, i);
2157
2271
  }
2158
2272
  let a = !1, o = e.query ? new URLSearchParams(e.query).get("t") : null;
2159
2273
  if (o) {
2160
- let e = ct(o);
2274
+ let e = dt(o);
2161
2275
  a = !!e && e.refId === t;
2162
2276
  }
2163
2277
  if (!a) {
2164
- let t = E(e.headers.cookie, Zt), r = t ? ae(t, ie()) : null;
2165
- r && (a = await I(F.checkAccess(n, r)) === !0);
2278
+ let t = ae(e.headers.cookie, sn), r = t ? se(t, oe()) : null;
2279
+ r && (a = await z(L.checkAccess(n, r)) === !0);
2166
2280
  }
2167
2281
  if (!a) return {
2168
2282
  status: 403,
2169
2283
  body: "forbidden",
2170
2284
  contentType: "text/plain"
2171
2285
  };
2172
- if (y.presigns && !r) {
2173
- let e = await I(y.getUrl(n.key, 300));
2286
+ if (x.presigns && !r) {
2287
+ let e = await z(x.getUrl(n.key, 300));
2174
2288
  if (e && /^https?:/.test(e)) return {
2175
2289
  status: 302,
2176
2290
  headers: {
@@ -2179,12 +2293,12 @@ var Gt = () => se({
2179
2293
  }
2180
2294
  };
2181
2295
  }
2182
- return z(n, "private, no-store", r, i);
2183
- }, fe = {
2296
+ return me(n, "private, no-store", r, i);
2297
+ }, ge = {
2184
2298
  method: "GET",
2185
- path: "/_voltro/storage",
2299
+ path: b,
2186
2300
  handle: async (e) => {
2187
- let t = await de(e), n = an(e.headers.origin, C);
2301
+ let t = await he(e), n = mn(e.headers.origin, ce);
2188
2302
  return Object.keys(n).length === 0 ? t : {
2189
2303
  ...t,
2190
2304
  headers: {
@@ -2193,12 +2307,12 @@ var Gt = () => se({
2193
2307
  }
2194
2308
  };
2195
2309
  }
2196
- }, pe = {
2310
+ }, _e = {
2197
2311
  method: "*",
2198
- path: "/_voltro/storage/upload",
2312
+ path: `${b}/upload`,
2199
2313
  originGuard: "exempt",
2200
2314
  handle: async (e) => {
2201
- let t = an(e.headers.origin, C);
2315
+ let t = mn(e.headers.origin, ce);
2202
2316
  if (e.method === "OPTIONS") return {
2203
2317
  status: 204,
2204
2318
  headers: t
@@ -2209,8 +2323,8 @@ var Gt = () => se({
2209
2323
  contentType: "text/plain",
2210
2324
  headers: t
2211
2325
  };
2212
- let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ? ut(n) : null;
2213
- if (!r) return {
2326
+ let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ? pt(n) : null;
2327
+ if (!r || r.instance !== v) return {
2214
2328
  status: 401,
2215
2329
  body: "invalid or expired upload ticket",
2216
2330
  contentType: "text/plain",
@@ -2228,7 +2342,7 @@ var Gt = () => se({
2228
2342
  contentType: "text/plain",
2229
2343
  headers: t
2230
2344
  };
2231
- let i = await b.runPromise(F.put({
2345
+ let i = await y.runPromise(L.put({
2232
2346
  bytes: e.rawBody,
2233
2347
  contentType: r.ct,
2234
2348
  tenantId: r.tenant,
@@ -2239,21 +2353,21 @@ var Gt = () => se({
2239
2353
  ...r.tags === void 0 ? {} : { tags: r.tags },
2240
2354
  ...r.alt === void 0 ? {} : { alt: r.alt },
2241
2355
  ...r.caption === void 0 ? {} : { caption: r.caption }
2242
- }).pipe(b.flatMap((e) => F.getUrl(e.id).pipe(b.map((t) => ({
2356
+ }).pipe(y.flatMap((e) => L.getUrl(e.id).pipe(y.map((t) => ({
2243
2357
  kind: "ok",
2244
2358
  ref: e,
2245
2359
  url: t
2246
- })))), b.catchTags({
2247
- StorageRejected: (e) => b.succeed({
2360
+ })))), y.catchTags({
2361
+ StorageRejected: (e) => y.succeed({
2248
2362
  kind: "rejected",
2249
2363
  status: e.reason === "too-large" ? 413 : 415,
2250
2364
  detail: e.detail
2251
2365
  }),
2252
- StorageScanRejected: (e) => b.succeed({
2366
+ StorageScanRejected: (e) => y.succeed({
2253
2367
  kind: "scan",
2254
2368
  threat: e.threat
2255
2369
  }),
2256
- StorageError: (e) => b.succeed({
2370
+ StorageError: (e) => y.succeed({
2257
2371
  kind: "error",
2258
2372
  message: e.message
2259
2373
  })
@@ -2285,28 +2399,28 @@ var Gt = () => se({
2285
2399
  headers: t
2286
2400
  };
2287
2401
  }
2288
- }, me = {
2402
+ }, ve = {
2289
2403
  method: "*",
2290
- path: "/_voltro/storage/upload/resumable",
2404
+ path: `${b}/upload/resumable`,
2291
2405
  originGuard: "exempt",
2292
2406
  handle: async (e) => {
2293
- let t = an(e.headers.origin, C);
2407
+ let t = mn(e.headers.origin, ce);
2294
2408
  if (e.method === "OPTIONS") return {
2295
2409
  status: 204,
2296
2410
  headers: t
2297
2411
  };
2298
- let n = new URLSearchParams(e.query || ""), r = mt(n.get("token") ?? "");
2299
- if (!r) return {
2412
+ let n = new URLSearchParams(e.query || ""), r = _t(n.get("token") ?? "");
2413
+ if (!r || r.instance !== v) return {
2300
2414
  status: 401,
2301
2415
  body: "invalid or expired resumable token",
2302
2416
  contentType: "text/plain",
2303
2417
  headers: t
2304
2418
  };
2305
2419
  if (e.method === "GET" || e.method === "HEAD") {
2306
- let e = await b.runPromise(F.resumableStatus({
2420
+ let e = await y.runPromise(L.resumableStatus({
2307
2421
  uploadId: r.id,
2308
2422
  tenantId: r.tenant
2309
- }).pipe(b.match({
2423
+ }).pipe(y.match({
2310
2424
  onFailure: (e) => ({ error: e.message }),
2311
2425
  onSuccess: (e) => e
2312
2426
  })));
@@ -2344,12 +2458,12 @@ var Gt = () => se({
2344
2458
  contentType: "text/plain",
2345
2459
  headers: t
2346
2460
  };
2347
- let a = n.get("final") === "1", o = await b.runPromise(F.putResumableChunk({
2461
+ let a = n.get("final") === "1", o = await y.runPromise(L.putResumableChunk({
2348
2462
  uploadId: r.id,
2349
2463
  tenantId: r.tenant,
2350
2464
  index: i,
2351
2465
  bytes: e.rawBody
2352
- }).pipe(b.flatMap(() => a ? F.finalizeResumable({
2466
+ }).pipe(y.flatMap(() => a ? L.finalizeResumable({
2353
2467
  uploadId: r.id,
2354
2468
  count: i + 1,
2355
2469
  contentType: r.ct,
@@ -2360,21 +2474,21 @@ var Gt = () => se({
2360
2474
  ...r.tags === void 0 ? {} : { tags: r.tags },
2361
2475
  ...r.alt === void 0 ? {} : { alt: r.alt },
2362
2476
  ...r.caption === void 0 ? {} : { caption: r.caption }
2363
- }).pipe(b.flatMap((e) => F.getUrl(e.id).pipe(b.map((t) => ({
2477
+ }).pipe(y.flatMap((e) => L.getUrl(e.id).pipe(y.map((t) => ({
2364
2478
  kind: "done",
2365
2479
  ref: e,
2366
2480
  url: t
2367
- }))))) : b.succeed({ kind: "chunk" })), b.catchTags({
2368
- StorageRejected: (e) => b.succeed({
2481
+ }))))) : y.succeed({ kind: "chunk" })), y.catchTags({
2482
+ StorageRejected: (e) => y.succeed({
2369
2483
  kind: "rejected",
2370
2484
  status: e.reason === "too-large" ? 413 : 415,
2371
2485
  detail: e.detail
2372
2486
  }),
2373
- StorageScanRejected: (e) => b.succeed({
2487
+ StorageScanRejected: (e) => y.succeed({
2374
2488
  kind: "scan",
2375
2489
  threat: e.threat
2376
2490
  }),
2377
- StorageError: (e) => b.succeed({
2491
+ StorageError: (e) => y.succeed({
2378
2492
  kind: "error",
2379
2493
  message: e.message
2380
2494
  })
@@ -2412,130 +2526,205 @@ var Gt = () => se({
2412
2526
  headers: t
2413
2527
  };
2414
2528
  }
2415
- }, B = (e) => ({
2529
+ }, V = (e) => ({
2416
2530
  kind: "json",
2417
2531
  data: e
2418
- }), V = (e, t) => ({
2532
+ }), H = (e, t) => ({
2419
2533
  kind: "json",
2420
2534
  status: e,
2421
2535
  data: { error: t }
2422
- }), he = (e, t) => {
2536
+ }), ye = (e, t) => {
2423
2537
  try {
2424
2538
  return new URL(e, "http://localhost").searchParams.get(t);
2425
2539
  } catch {
2426
2540
  return null;
2427
2541
  }
2428
- }, ge = [
2542
+ }, be = [
2543
+ {
2544
+ method: "POST",
2545
+ path: "/upload-ticket",
2546
+ description: "Authorize a binary upload with explicit tenant and owner attribution",
2547
+ handler: (e) => y.gen(function* () {
2548
+ let n = C.String.pipe(C.filter((e) => e.trim().length > 0)), r = yield* C.decodeUnknown(C.parseJson(C.Struct({
2549
+ tenantId: C.NullOr(n),
2550
+ ownerId: C.NullOr(n),
2551
+ key: n.pipe(C.maxLength(1024)),
2552
+ contentType: n.pipe(C.maxLength(255), C.filter((e) => !/[\r\n]/.test(e))),
2553
+ size: C.Number.pipe(C.int(), C.positive(), C.filter(Number.isSafeInteger)),
2554
+ visibility: C.optional(C.Literal("public", "private"))
2555
+ })))(e.body).pipe(y.mapError(() => new t({
2556
+ provider: "inspect",
2557
+ message: "Provide explicit tenantId and ownerId (or null), key, contentType and a positive file size",
2558
+ transient: !1,
2559
+ status: 400
2560
+ })));
2561
+ if (D !== void 0 && r.size > D) return H(413, "File exceeds the configured upload limit");
2562
+ let i = ft({
2563
+ instance: v,
2564
+ sub: r.ownerId,
2565
+ tenant: r.tenantId,
2566
+ ct: r.contentType,
2567
+ key: r.key,
2568
+ vis: r.visibility ?? "private",
2569
+ max: r.size
2570
+ }, 300);
2571
+ return V({
2572
+ uploadPath: `${b}/upload?ticket=${encodeURIComponent(i)}`,
2573
+ expiresInSec: 300,
2574
+ maxBytes: r.size
2575
+ });
2576
+ }).pipe(y.catchAll((e) => y.succeed(H(e.status ?? 500, e.message))))
2577
+ },
2578
+ {
2579
+ method: "GET",
2580
+ path: "/download",
2581
+ description: "Stream a stored file as an attachment for authorized inspect readers",
2582
+ handler: (e) => y.gen(function* () {
2583
+ let t = ye(e.url, "refId");
2584
+ if (!t?.trim()) return H(400, "A non-empty refId is required");
2585
+ let { ref: n, stream: r } = yield* L.getStream(t), i = n.key.split("/").pop() || n.id, a = encodeURIComponent(i).replace(/[!'()*]/g, (e) => `%${e.charCodeAt(0).toString(16).toUpperCase()}`);
2586
+ return {
2587
+ kind: "bytes",
2588
+ contentType: n.contentType,
2589
+ byteStream: {
2590
+ stream: () => w.toReadableStream(r),
2591
+ contentLength: n.size,
2592
+ contentDisposition: `attachment; filename="download"; filename*=UTF-8''${a}`
2593
+ },
2594
+ headers: { "cache-control": "no-store" }
2595
+ };
2596
+ }).pipe(y.catchAll((e) => y.succeed(H(e.status ?? 500, e.message))))
2597
+ },
2429
2598
  {
2430
2599
  method: "GET",
2431
2600
  path: "/refs",
2432
- description: "Recent storage refs (newest first)",
2433
- handler: () => se.listRecent(100).pipe(b.map((e) => B({ refs: e.map(on) })), b.catchAll((e) => b.succeed(V(500, e.message))))
2601
+ description: "Searchable storage refs, newest first, paginated",
2602
+ handler: (e) => {
2603
+ let t = Number(ye(e.url, "offset") ?? 0), n = Number.isSafeInteger(t) && t >= 0 ? t : 0, r = (ye(e.url, "search") ?? "").trim().slice(0, 200);
2604
+ return le.listRefs({
2605
+ tenantId: void 0,
2606
+ ownerId: void 0,
2607
+ folder: void 0,
2608
+ tags: [],
2609
+ includeDerived: !0,
2610
+ search: r,
2611
+ limit: 51,
2612
+ offset: n
2613
+ }).pipe(y.map((e) => V({
2614
+ refs: e.slice(0, 50).map(hn),
2615
+ page: {
2616
+ search: r,
2617
+ offset: n,
2618
+ nextOffset: e.length > 50 ? n + 50 : null
2619
+ }
2620
+ })), y.catchAll((e) => y.succeed(H(500, e.message))));
2621
+ }
2434
2622
  },
2435
2623
  {
2436
2624
  method: "GET",
2437
2625
  path: "/stats",
2438
2626
  description: "Object count + total bytes per tenant + visibility split",
2439
- handler: () => se.listRecent(1e4).pipe(b.map((e) => {
2440
- let t = {}, n = 0, r = 0;
2441
- for (let i of e) {
2442
- let e = i.tenantId ?? "(global)", a = t[e] ?? {
2443
- count: 0,
2444
- bytes: 0
2445
- };
2446
- a.count++, a.bytes += i.size, t[e] = a, i.visibility === "public" ? n++ : r++;
2447
- }
2448
- return B({
2449
- provider: y.name,
2450
- bucket: x,
2451
- byTenant: t,
2452
- visibility: {
2453
- public: n,
2454
- private: r
2455
- }
2456
- });
2457
- }), b.catchAll((e) => b.succeed(V(500, e.message))))
2627
+ handler: () => le.statistics().pipe(y.map((e) => V({
2628
+ provider: x.name,
2629
+ bucket: S,
2630
+ ...e
2631
+ })), y.catchAll((e) => y.succeed(H(500, e.message))))
2458
2632
  },
2459
2633
  {
2460
2634
  method: "GET",
2461
2635
  path: "/grants",
2462
2636
  description: "Grants for a ref (?refId=…)",
2463
2637
  handler: (e) => {
2464
- let t = he(e.url, "refId");
2465
- return t ? ce.listByRef(t).pipe(b.map((e) => B({ grants: e.map(dn) })), b.catchAll((e) => b.succeed(V(500, e.message)))) : b.succeed(V(400, "refId query param required"));
2638
+ let t = ye(e.url, "refId");
2639
+ return t ? F.listByRef(t).pipe(y.map((e) => V({ grants: e.map(bn) })), y.catchAll((e) => y.succeed(H(500, e.message)))) : y.succeed(H(400, "refId query param required"));
2466
2640
  }
2467
2641
  },
2468
2642
  {
2469
2643
  method: "POST",
2470
2644
  path: "/share",
2471
2645
  description: "Grant a principal access to a ref",
2472
- handler: (e) => b.gen(function* () {
2473
- let n = yield* b.try({
2474
- try: () => JSON.parse(e.body || "{}"),
2475
- catch: () => new t({
2476
- provider: "inspect",
2477
- message: "invalid JSON body",
2478
- transient: !1,
2479
- status: 400
2480
- })
2481
- });
2482
- if (!n.refId || !n.principalType || !n.principalId) return V(400, "refId, principalType, principalId required");
2483
- let r = n.expiresInDays ? new Date(Date.now() + n.expiresInDays * 864e5) : null, i = yield* F.grant({
2646
+ handler: (e) => y.gen(function* () {
2647
+ let n = yield* C.decodeUnknown(C.parseJson(C.Struct({
2648
+ refId: C.String.pipe(C.filter((e) => e.trim().length > 0)),
2649
+ principalType: C.Literal("user", "group", "apiKey"),
2650
+ principalId: C.String.pipe(C.filter((e) => e.trim().length > 0)),
2651
+ permission: C.optional(C.Literal("read", "write")),
2652
+ expiresInDays: C.optional(C.Number.pipe(C.finite(), C.positive()))
2653
+ })))(e.body).pipe(y.mapError(() => new t({
2654
+ provider: "inspect",
2655
+ message: "Invalid share input: provide refId, principalType, principalId, read/write permission and a positive finite expiry if set",
2656
+ transient: !1,
2657
+ status: 400
2658
+ }))), r = n.expiresInDays === void 0 ? null : new Date(Date.now() + n.expiresInDays * 864e5);
2659
+ if (r !== null && !Number.isFinite(r.getTime())) return H(400, "Expiry exceeds the supported date range");
2660
+ let i = yield* L.grant({
2484
2661
  refId: n.refId,
2485
2662
  principalType: n.principalType,
2486
2663
  principalId: n.principalId,
2487
2664
  ...n.permission ? { permission: n.permission } : {},
2488
2665
  expiresAt: r
2489
2666
  });
2490
- return B({ grant: dn(i) });
2491
- }).pipe(b.catchAll((e) => b.succeed(V(e.status ?? 500, e.message ?? "share failed"))))
2667
+ return V({ grant: bn(i) });
2668
+ }).pipe(y.catchAll((e) => y.succeed(H(e.status ?? 500, e.message ?? "share failed"))))
2669
+ },
2670
+ {
2671
+ method: "POST",
2672
+ path: "/delete",
2673
+ description: "Delete an object reference and its grants; release unreferenced bytes",
2674
+ handler: (e) => y.gen(function* () {
2675
+ 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({
2676
+ provider: "inspect",
2677
+ message: "A non-empty refId is required",
2678
+ transient: !1,
2679
+ status: 400
2680
+ })));
2681
+ return yield* L.delete(n.refId), V({ ok: !0 });
2682
+ }).pipe(y.catchAll((e) => y.succeed(H(e.status ?? 500, e.message))))
2492
2683
  },
2493
2684
  {
2494
2685
  method: "POST",
2495
2686
  path: "/revoke",
2496
2687
  description: "Revoke a grant by id",
2497
- handler: (e) => b.gen(function* () {
2498
- let n = yield* b.try({
2499
- try: () => JSON.parse(e.body || "{}"),
2500
- catch: () => new t({
2501
- provider: "inspect",
2502
- message: "invalid JSON body",
2503
- transient: !1,
2504
- status: 400
2505
- })
2506
- });
2507
- return n.grantId ? (yield* F.revoke(n.grantId), B({ ok: !0 })) : V(400, "grantId required");
2508
- }).pipe(b.catchAll((e) => b.succeed(V(e.status ?? 500, e.message ?? "revoke failed"))))
2688
+ handler: (e) => y.gen(function* () {
2689
+ 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({
2690
+ provider: "inspect",
2691
+ message: "A non-empty grantId is required",
2692
+ transient: !1,
2693
+ status: 400
2694
+ })));
2695
+ return yield* L.revoke(n.grantId), V({ ok: !0 });
2696
+ }).pipe(y.catchAll((e) => y.succeed(H(e.status ?? 500, e.message ?? "revoke failed"))))
2509
2697
  }
2510
- ], _e = [
2698
+ ], xe = [
2511
2699
  {
2512
2700
  ...h,
2513
2701
  execute: (e, t) => {
2514
2702
  let n = e;
2515
- return F.mintUrl(n.id, t.request.subject, {
2703
+ return L.mintUrl(n.id, t.request.subject, {
2516
2704
  ...n.password === void 0 ? {} : { password: n.password },
2517
2705
  ...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
2518
- }).pipe(b.map((e) => ({ url: e })));
2706
+ }).pipe(y.map((e) => ({ url: e })));
2519
2707
  }
2520
2708
  },
2521
2709
  {
2522
2710
  ...ee,
2523
2711
  execute: (e, t) => {
2524
2712
  let n = e;
2525
- return F.mintUploadUrl({
2713
+ return L.mintUploadUrl({
2526
2714
  key: n.key,
2527
2715
  contentType: n.contentType,
2528
2716
  tenantId: t.request.subject.tenantId,
2529
2717
  ...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
2530
- }).pipe(b.map((e) => ({ url: e })));
2718
+ }).pipe(y.map((e) => ({ url: e })));
2531
2719
  }
2532
2720
  },
2533
2721
  {
2534
2722
  ...m,
2535
2723
  execute: (e, t) => {
2536
2724
  let n = e;
2537
- return $(t, D).pipe(b.map((e) => {
2538
- let t = n.expiresInSec ?? 900, r = lt({
2725
+ return $(t, O).pipe(y.map((e) => {
2726
+ let t = n.expiresInSec ?? 900, r = ft({
2727
+ instance: v,
2539
2728
  sub: e.id,
2540
2729
  tenant: e.tenantId,
2541
2730
  ct: n.contentType,
@@ -2545,10 +2734,10 @@ var Gt = () => se({
2545
2734
  ...n.tags === void 0 ? {} : { tags: n.tags },
2546
2735
  ...n.alt === void 0 ? {} : { alt: n.alt },
2547
2736
  ...n.caption === void 0 ? {} : { caption: n.caption },
2548
- ...w === void 0 ? {} : { max: w }
2737
+ ...D === void 0 ? {} : { max: D }
2549
2738
  }, t);
2550
2739
  return {
2551
- uploadUrl: `${S ? S.replace(/\/+$/, "") : ""}/_voltro/storage/upload?ticket=${encodeURIComponent(r)}`,
2740
+ uploadUrl: `${E ? E.replace(/\/+$/, "") : ""}${b}/upload?ticket=${encodeURIComponent(r)}`,
2552
2741
  expiresInSec: t
2553
2742
  };
2554
2743
  }));
@@ -2558,12 +2747,13 @@ var Gt = () => se({
2558
2747
  ...p,
2559
2748
  execute: (e, t) => {
2560
2749
  let n = e;
2561
- return $(t, D).pipe(b.flatMap((e) => F.mintPresignedUpload({
2750
+ return $(t, O).pipe(y.flatMap((e) => L.mintPresignedUpload({
2562
2751
  contentType: n.contentType,
2563
2752
  tenantId: e.tenantId,
2564
2753
  ...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
2565
- }).pipe(b.map((t) => {
2566
- let r = dt({
2754
+ }).pipe(y.map((t) => {
2755
+ let r = mt({
2756
+ instance: v,
2567
2757
  key: t.key,
2568
2758
  sub: e.id,
2569
2759
  tenant: e.tenantId,
@@ -2573,7 +2763,7 @@ var Gt = () => se({
2573
2763
  ...n.tags === void 0 ? {} : { tags: n.tags },
2574
2764
  ...n.alt === void 0 ? {} : { alt: n.alt },
2575
2765
  ...n.caption === void 0 ? {} : { caption: n.caption },
2576
- ...w === void 0 ? {} : { max: w }
2766
+ ...D === void 0 ? {} : { max: D }
2577
2767
  }, t.expiresInSec);
2578
2768
  return {
2579
2769
  uploadUrl: t.uploadUrl,
@@ -2586,13 +2776,18 @@ var Gt = () => se({
2586
2776
  {
2587
2777
  ...l,
2588
2778
  execute: (e, n) => {
2589
- let r = ft(e.finalizeToken);
2590
- return r ? un(r.sub, n.request.subject.id) ? b.fail(new t({
2779
+ let r = ht(e.finalizeToken);
2780
+ return !r || r.instance !== v ? y.fail(new t({
2781
+ provider: "storage",
2782
+ message: "invalid or expired finalize token",
2783
+ transient: !1,
2784
+ status: 401
2785
+ })) : yn(r.sub, n.request.subject.id) ? y.fail(new t({
2591
2786
  provider: "storage",
2592
2787
  message: "finalize token belongs to another subject",
2593
2788
  transient: !1,
2594
2789
  status: 403
2595
- })) : F.finalizeUpload({
2790
+ })) : L.finalizeUpload({
2596
2791
  key: r.key,
2597
2792
  contentType: r.ct,
2598
2793
  tenantId: r.tenant,
@@ -2602,30 +2797,26 @@ var Gt = () => se({
2602
2797
  ...r.tags === void 0 ? {} : { tags: r.tags },
2603
2798
  ...r.alt === void 0 ? {} : { alt: r.alt },
2604
2799
  ...r.caption === void 0 ? {} : { caption: r.caption }
2605
- }).pipe(b.flatMap((e) => F.getUrl(e.id).pipe(b.map((t) => ({
2800
+ }).pipe(y.flatMap((e) => L.getUrl(e.id).pipe(y.map((t) => ({
2606
2801
  id: e.id,
2607
2802
  url: t,
2608
2803
  contentType: e.contentType,
2609
2804
  size: e.size,
2610
2805
  ...e.width == null ? {} : { width: e.width },
2611
2806
  ...e.height == null ? {} : { height: e.height }
2612
- }))))) : b.fail(new t({
2613
- provider: "storage",
2614
- message: "invalid or expired finalize token",
2615
- transient: !1,
2616
- status: 401
2617
- }));
2807
+ })))));
2618
2808
  }
2619
2809
  },
2620
2810
  {
2621
2811
  ...s,
2622
2812
  execute: (e, t) => {
2623
2813
  let n = e;
2624
- return $(t, D).pipe(b.map((e) => {
2625
- let t = n.expiresInSec ?? O, r = ue(), i = n.chunkSize && n.chunkSize > 0 ? n.chunkSize : oe;
2814
+ return $(t, O).pipe(y.map((e) => {
2815
+ let t = n.expiresInSec ?? A, r = de(), i = n.chunkSize && n.chunkSize > 0 ? n.chunkSize : k;
2626
2816
  return {
2627
2817
  uploadId: r,
2628
- resumableToken: pt({
2818
+ resumableToken: gt({
2819
+ instance: v,
2629
2820
  id: r,
2630
2821
  sub: e.id,
2631
2822
  tenant: e.tenantId,
@@ -2636,9 +2827,9 @@ var Gt = () => se({
2636
2827
  ...n.tags === void 0 ? {} : { tags: n.tags },
2637
2828
  ...n.alt === void 0 ? {} : { alt: n.alt },
2638
2829
  ...n.caption === void 0 ? {} : { caption: n.caption },
2639
- ...w === void 0 ? {} : { max: w }
2830
+ ...D === void 0 ? {} : { max: D }
2640
2831
  }, t),
2641
- uploadUrl: `${S ? S.replace(/\/+$/, "") : ""}/_voltro/storage/upload/resumable`,
2832
+ uploadUrl: `${E ? E.replace(/\/+$/, "") : ""}${b}/upload/resumable`,
2642
2833
  chunkSize: i,
2643
2834
  expiresInSec: t
2644
2835
  };
@@ -2648,14 +2839,15 @@ var Gt = () => se({
2648
2839
  {
2649
2840
  ...o,
2650
2841
  execute: (e, t) => {
2651
- let n = e, r = n.expiresInSec ?? O;
2652
- return $(t, D).pipe(b.flatMap((e) => F.beginMultipartUpload({
2842
+ let n = e, r = n.expiresInSec ?? A;
2843
+ return $(t, O).pipe(y.flatMap((e) => L.beginMultipartUpload({
2653
2844
  contentType: n.contentType,
2654
2845
  tenantId: e.tenantId,
2655
2846
  visibility: n.visibility ?? "private",
2656
2847
  expiresInSec: r
2657
- }).pipe(b.map((t) => ({
2658
- multipartToken: ht({
2848
+ }).pipe(y.map((t) => ({
2849
+ multipartToken: vt({
2850
+ instance: v,
2659
2851
  key: t.key,
2660
2852
  uploadId: t.uploadId,
2661
2853
  sub: e.id,
@@ -2668,42 +2860,47 @@ var Gt = () => se({
2668
2860
  ...n.alt === void 0 ? {} : { alt: n.alt },
2669
2861
  ...n.caption === void 0 ? {} : { caption: n.caption }
2670
2862
  }, r),
2671
- partSize: n.partSize && n.partSize >= oe ? n.partSize : oe,
2863
+ partSize: n.partSize && n.partSize >= k ? n.partSize : k,
2672
2864
  expiresInSec: r
2673
2865
  })))));
2674
2866
  }
2675
2867
  },
2676
2868
  {
2677
- ...te,
2869
+ ...ne,
2678
2870
  execute: (e) => {
2679
- let n = e, r = gt(n.multipartToken);
2680
- return r ? !Number.isInteger(n.partNumber) || n.partNumber < 1 ? b.fail(new t({
2871
+ let n = e, r = yt(n.multipartToken);
2872
+ return !r || r.instance !== v ? y.fail(new t({
2873
+ provider: "storage",
2874
+ message: "invalid or expired multipart token",
2875
+ transient: !1,
2876
+ status: 401
2877
+ })) : !Number.isInteger(n.partNumber) || n.partNumber < 1 ? y.fail(new t({
2681
2878
  provider: "storage",
2682
2879
  message: "partNumber must be a positive integer",
2683
2880
  transient: !1,
2684
2881
  status: 400
2685
- })) : F.signMultipartPart({
2882
+ })) : L.signMultipartPart({
2686
2883
  key: r.key,
2687
2884
  uploadId: r.uploadId,
2688
2885
  partNumber: n.partNumber
2689
- }).pipe(b.map((e) => ({ url: e }))) : b.fail(new t({
2690
- provider: "storage",
2691
- message: "invalid or expired multipart token",
2692
- transient: !1,
2693
- status: 401
2694
- }));
2886
+ }).pipe(y.map((e) => ({ url: e })));
2695
2887
  }
2696
2888
  },
2697
2889
  {
2698
2890
  ...c,
2699
2891
  execute: (e, n) => {
2700
- let r = e, i = gt(r.multipartToken);
2701
- return i ? un(i.sub, n.request.subject.id) ? b.fail(new t({
2892
+ let r = e, i = yt(r.multipartToken);
2893
+ return !i || i.instance !== v ? y.fail(new t({
2894
+ provider: "storage",
2895
+ message: "invalid or expired multipart token",
2896
+ transient: !1,
2897
+ status: 401
2898
+ })) : yn(i.sub, n.request.subject.id) ? y.fail(new t({
2702
2899
  provider: "storage",
2703
2900
  message: "multipart token belongs to another subject",
2704
2901
  transient: !1,
2705
2902
  status: 403
2706
- })) : F.completeMultipart({
2903
+ })) : L.completeMultipart({
2707
2904
  key: i.key,
2708
2905
  uploadId: i.uploadId,
2709
2906
  parts: r.parts,
@@ -2715,38 +2912,33 @@ var Gt = () => se({
2715
2912
  ...i.tags === void 0 ? {} : { tags: i.tags },
2716
2913
  ...i.alt === void 0 ? {} : { alt: i.alt },
2717
2914
  ...i.caption === void 0 ? {} : { caption: i.caption }
2718
- }).pipe(b.flatMap((e) => F.getUrl(e.id).pipe(b.map((t) => ({
2915
+ }).pipe(y.flatMap((e) => L.getUrl(e.id).pipe(y.map((t) => ({
2719
2916
  id: e.id,
2720
2917
  url: t,
2721
2918
  size: e.size
2722
- }))))) : b.fail(new t({
2723
- provider: "storage",
2724
- message: "invalid or expired multipart token",
2725
- transient: !1,
2726
- status: 401
2727
- }));
2919
+ })))));
2728
2920
  }
2729
2921
  },
2730
2922
  {
2731
2923
  ...a,
2732
2924
  execute: (e) => {
2733
- let n = gt(e.multipartToken);
2734
- return n ? F.abortMultipart({
2735
- key: n.key,
2736
- uploadId: n.uploadId
2737
- }).pipe(b.as({ ok: !0 })) : b.fail(new t({
2925
+ let n = yt(e.multipartToken);
2926
+ return !n || n.instance !== v ? y.fail(new t({
2738
2927
  provider: "storage",
2739
2928
  message: "invalid or expired multipart token",
2740
2929
  transient: !1,
2741
2930
  status: 401
2742
- }));
2931
+ })) : L.abortMultipart({
2932
+ key: n.key,
2933
+ uploadId: n.uploadId
2934
+ }).pipe(y.as({ ok: !0 }));
2743
2935
  }
2744
2936
  },
2745
2937
  {
2746
- ...v,
2938
+ ..._,
2747
2939
  execute: (e, t) => {
2748
2940
  let n = e, r = new Uint8Array(Buffer.from(n.bytesBase64, "base64"));
2749
- return $(t, D).pipe(b.flatMap((e) => F.put({
2941
+ return $(t, O).pipe(y.flatMap((e) => L.put({
2750
2942
  bytes: r,
2751
2943
  contentType: n.contentType,
2752
2944
  tenantId: e.tenantId,
@@ -2754,7 +2946,7 @@ var Gt = () => se({
2754
2946
  ...n.visibility ? { visibility: n.visibility } : {},
2755
2947
  ...n.key ? { key: n.key } : {},
2756
2948
  ...n.password ? { password: n.password } : {}
2757
- })), b.flatMap((e) => F.getUrl(e.id).pipe(b.map((t) => ({
2949
+ })), y.flatMap((e) => L.getUrl(e.id).pipe(y.map((t) => ({
2758
2950
  id: e.id,
2759
2951
  url: t
2760
2952
  })))));
@@ -2764,7 +2956,7 @@ var Gt = () => se({
2764
2956
  ...u,
2765
2957
  execute: (e, t) => {
2766
2958
  let n = e;
2767
- return $(t, D).pipe(b.flatMap((e) => F.ingestUrl(n.url, {
2959
+ return $(t, O).pipe(y.flatMap((e) => L.ingestUrl(n.url, {
2768
2960
  tenantId: e.tenantId,
2769
2961
  ownerId: e.id,
2770
2962
  ...n.visibility ? { visibility: n.visibility } : {},
@@ -2773,45 +2965,45 @@ var Gt = () => se({
2773
2965
  ...n.alt === void 0 ? {} : { alt: n.alt },
2774
2966
  ...n.caption === void 0 ? {} : { caption: n.caption },
2775
2967
  ...n.key === void 0 ? {} : { key: n.key }
2776
- })), b.flatMap((e) => F.getUrl(e.id).pipe(b.map((t) => ({
2968
+ })), y.flatMap((e) => L.getUrl(e.id).pipe(y.map((t) => ({
2777
2969
  id: e.id,
2778
2970
  url: t
2779
2971
  })))));
2780
2972
  }
2781
2973
  },
2782
2974
  {
2783
- ..._,
2975
+ ...g,
2784
2976
  execute: (e, t) => {
2785
2977
  let n = e, r = n.expiresInDays ? new Date(Date.now() + n.expiresInDays * 864e5) : null;
2786
- return cn(F, n.refId, t).pipe(b.flatMap(() => F.grant({
2978
+ return _n(L, n.refId, t).pipe(y.flatMap(() => L.grant({
2787
2979
  refId: n.refId,
2788
2980
  principalType: n.principalType,
2789
2981
  principalId: n.principalId,
2790
2982
  ...n.permission ? { permission: n.permission } : {},
2791
2983
  expiresAt: r,
2792
2984
  createdBy: t.request.subject.id
2793
- })), b.map((e) => ({ grantId: e.id })));
2985
+ })), y.map((e) => ({ grantId: e.id })));
2794
2986
  }
2795
2987
  },
2796
2988
  {
2797
- ...g,
2989
+ ...te,
2798
2990
  execute: (e, t) => {
2799
2991
  let n = e;
2800
- return F.getGrant(n.grantId).pipe(b.flatMap((e) => e === null ? b.fail(sn()) : cn(F, e.refId, t)), b.flatMap(() => F.revoke(n.grantId)), b.map(() => ({ ok: !0 })));
2992
+ return L.getGrant(n.grantId).pipe(y.flatMap((e) => e === null ? y.fail(gn()) : _n(L, e.refId, t)), y.flatMap(() => L.revoke(n.grantId)), y.map(() => ({ ok: !0 })));
2801
2993
  }
2802
2994
  },
2803
2995
  {
2804
2996
  ...d,
2805
2997
  execute: (e, t) => {
2806
2998
  let n = e;
2807
- return cn(F, n.refId, t).pipe(b.flatMap(() => F.listGrants(n.refId)), b.map((e) => ({ grants: e.map(dn) })));
2999
+ return _n(L, n.refId, t).pipe(y.flatMap(() => L.listGrants(n.refId)), y.map((e) => ({ grants: e.map(bn) })));
2808
3000
  }
2809
3001
  },
2810
3002
  {
2811
3003
  ...f,
2812
3004
  execute: (e, t) => {
2813
3005
  let n = e;
2814
- return F.listRefs({
3006
+ return L.listRefs({
2815
3007
  tenantId: t.request.subject.tenantId,
2816
3008
  ...n.folder === void 0 ? {} : { folder: n.folder },
2817
3009
  ...n.tags === void 0 ? {} : { tags: n.tags },
@@ -2819,36 +3011,36 @@ var Gt = () => se({
2819
3011
  ...n.includeDerived === void 0 ? {} : { includeDerived: n.includeDerived },
2820
3012
  ...n.limit === void 0 ? {} : { limit: n.limit },
2821
3013
  ...n.offset === void 0 ? {} : { offset: n.offset }
2822
- }).pipe(b.map((e) => ({
2823
- refs: e.refs.map(on),
3014
+ }).pipe(y.map((e) => ({
3015
+ refs: e.refs.map(hn),
2824
3016
  nextOffset: e.nextOffset
2825
3017
  })));
2826
3018
  }
2827
3019
  }
2828
3020
  ];
2829
- return T({
2830
- name: re({
2831
- base: fn,
3021
+ return ie({
3022
+ name: T({
3023
+ base: xn,
2832
3024
  alias: i.alias,
2833
3025
  instance: i.name
2834
3026
  }),
2835
- baseName: fn,
3027
+ baseName: xn,
2836
3028
  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.",
2837
3029
  permissions: [
2838
3030
  "network:outbound:*",
2839
3031
  "inspect:read",
2840
3032
  "inspect:write"
2841
3033
  ],
2842
- declaredEnv: G.declared,
2843
- services: P,
2844
- inspectEndpoints: ge,
3034
+ declaredEnv: K.declared,
3035
+ services: ue,
3036
+ inspectEndpoints: be,
2845
3037
  httpRoutes: [
2846
- fe,
2847
- pe,
2848
- me
3038
+ ge,
3039
+ _e,
3040
+ ve
2849
3041
  ],
2850
- routes: _e,
2851
- rpcClientDescriptors: ne,
3042
+ routes: xe,
3043
+ rpcClientDescriptors: re,
2852
3044
  errorSchemas: [
2853
3045
  {
2854
3046
  schema: t,
@@ -2880,18 +3072,18 @@ var Gt = () => se({
2880
3072
  }
2881
3073
  ],
2882
3074
  bindDataStore: (e) => {
2883
- k && (j.current = At(e)), A && (M.current = Nt(e)), y.bindDataStore?.(e);
3075
+ j && (N.current = Rt(e)), M && (P.current = Vt(e)), x.bindDataStore?.(e);
2884
3076
  },
2885
- onActivate: (e) => b.sync(() => {
2886
- let t = !!S || !!G.read("STORAGE_CDN_URL", i.cdnBaseUrl);
2887
- e.logger.info(`storage: provider=${y.name} presign=${y.presigns ? "yes" : "no"} publicUrl=${t ? "yes" : "no"} transforms=yes`, {
2888
- provider: y.name,
2889
- bucket: x,
2890
- refStore: k ? "memory" : "custom"
2891
- }), y.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 && !y.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.");
3077
+ onActivate: (e) => y.sync(() => {
3078
+ let t = !!E || !!K.read("STORAGE_CDN_URL", i.cdnBaseUrl);
3079
+ e.logger.info(`storage: provider=${x.name} presign=${x.presigns ? "yes" : "no"} publicUrl=${t ? "yes" : "no"} transforms=yes`, {
3080
+ provider: x.name,
3081
+ bucket: S,
3082
+ refStore: j ? "memory" : "custom"
3083
+ }), 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.");
2892
3084
  }),
2893
- onDeactivate: () => b.void
3085
+ onDeactivate: () => y.void
2894
3086
  });
2895
3087
  };
2896
3088
  //#endregion
2897
- export { W as STORAGE_BLOBS_TABLE, U as STORAGE_GRANTS_TABLE, H as STORAGE_REFS_TABLE, Ee as STORAGE_USAGE_TABLE, e as StorageAccessDenied, t as StorageError, n as StorageRejected, r as StorageScanRejected, i as StorageService, Ae as _voltroStorageBlobsTable, Oe as _voltroStorageGrantsTable, De as _voltroStorageRefsTable, ke as _voltroStorageUsageTable, en as appStorageProvider, Wt as assetRef, Be as azureProvider, It as buildStorageService, be as bytesToStream, bt as checkLimits, Vt as clamavScanner, Pe as clearStorageBuffer, xe as collectStream, ye as concatBytes, tn as configuredStorageProvider, _t as contentTypeAllowed, Nt as dataStoreGrantStore, At as dataStoreRefStore, ze as databaseProvider, qt as decodeDataUri, Xt as durabilityNotice, Rt as encodeInstream, Ut as ffmpegTranscoder, Ie as filesystemProvider, Se as fromNodeReadable, we as getObjectStream, Je as hashPassword, jt as memoryGrantStore, Fe as memoryProvider, Et as memoryRefStore, zt as parseClamavResponse, He as parseTransformParams, Yt as pathDurability, Jt as putAvatar, Te as putObjectStream, Ne as readStorageBuffer, wt as refMatchesListQuery, nn as resolveStorageProvider, Y as resolveStorageSecret, Le as s3Provider, $t as setActiveStorageProvider, dt as signFinalizeTicket, st as signGrant, ht as signMultipartTicket, pt as signResumableTicket, lt as signUploadTicket, yt as sniffMatches, pn as storagePlugin, Lt as storageServiceLayer, Ce as toNodeReadable, qe as transformCached, Ge as transformImage, ft as verifyFinalizeTicket, ct as verifyGrant, gt as verifyMultipartTicket, Ye as verifyPassword, mt as verifyResumableTicket, ut as verifyUploadTicket, Gt as withStorage };
3089
+ export { G as STORAGE_BLOBS_TABLE, W as STORAGE_GRANTS_TABLE, U as STORAGE_REFS_TABLE, Oe as STORAGE_USAGE_TABLE, e as StorageAccessDenied, t as StorageError, n as StorageRejected, r as StorageScanRejected, i as StorageService, Me as _voltroStorageBlobsTable, Ae as _voltroStorageGrantsTable, ke as _voltroStorageRefsTable, je as _voltroStorageUsageTable, un as appStorageProvider, Qt as assetRef, He as azureProvider, Wt as buildStorageService, Se as bytesToStream, Ct as checkLimits, Yt as clamavScanner, Ie as clearStorageBuffer, Ce as collectStream, xe as concatBytes, dn as configuredStorageProvider, bt as contentTypeAllowed, Vt as dataStoreGrantStore, Rt as dataStoreRefStore, Ve as databaseProvider, tn as decodeDataUri, on as durabilityNotice, Kt as encodeInstream, Zt as ffmpegTranscoder, Re as filesystemProvider, we as fromNodeReadable, Ee as getObjectStream, Ze as hashPassword, zt as memoryGrantStore, Le as memoryProvider, Pt as memoryRefStore, qt as parseClamavResponse, We as parseTransformParams, an as pathDurability, nn as putAvatar, De as putObjectStream, Fe as readStorageBuffer, Mt as refMatchesListQuery, fn as resolveStorageProvider, Y as resolveStorageSecret, ze as s3Provider, ln as setActiveStorageProvider, mt as signFinalizeTicket, ut as signGrant, vt as signMultipartTicket, gt as signResumableTicket, ft as signUploadTicket, St as sniffMatches, Sn as storageInstanceName, Cn as storagePlugin, rn as storagePutIntentsTable, Gt as storageServiceLayer, Te as toNodeReadable, Xe as transformCached, qe as transformImage, ht as verifyFinalizeTicket, dt as verifyGrant, yt as verifyMultipartTicket, Qe as verifyPassword, _t as verifyResumableTicket, pt as verifyUploadTicket, $t as withStorage };