@voltro/plugin-storage 0.62.3 → 0.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +104 -0
- package/dist/index.js +279 -270
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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
|
|
3
|
-
import { Chunk as
|
|
4
|
-
import { definePlugin as
|
|
5
|
-
import { readCookie as
|
|
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
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
7
|
import { pluginEnv as le } from "@voltro/env";
|
|
8
8
|
import { createHmac as I, randomBytes as ue, randomUUID as de, scryptSync as fe, timingSafeEqual as L } from "node:crypto";
|
|
@@ -25,18 +25,18 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
25
25
|
}, xe = (e, t = ve) => {
|
|
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
|
-
return
|
|
29
|
-
}, Se = (e) => e.pipe(
|
|
28
|
+
return w.fromIterable(n);
|
|
29
|
+
}, Se = (e) => e.pipe(w.runCollect, b.map((e) => be(y.toReadonlyArray(e)))), Ce = (e, t) => w.suspend(() => w.fromAsyncIterable(t(), (t) => ye(e, `read stream failed: ${String(t?.message ?? t)}`, !0))).pipe(w.map((e) => e instanceof Uint8Array ? e : new Uint8Array(e))), V = async (e) => {
|
|
30
30
|
let { Readable: t } = await import("node:stream");
|
|
31
|
-
return t.fromWeb(
|
|
32
|
-
},
|
|
31
|
+
return t.fromWeb(w.toReadableStream(e));
|
|
32
|
+
}, we = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(b.map((e) => ({
|
|
33
33
|
stream: xe(e.bytes),
|
|
34
34
|
contentType: e.contentType,
|
|
35
35
|
size: e.bytes.byteLength
|
|
36
|
-
}))),
|
|
36
|
+
}))), Te = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : Se(n).pipe(b.flatMap((n) => e.put(t, n, {
|
|
37
37
|
contentType: r.contentType,
|
|
38
38
|
...r.public === void 0 ? {} : { public: r.public }
|
|
39
|
-
}))),
|
|
39
|
+
}))), H = "_voltro_storage_refs", U = "_voltro_storage_grants", W = "_voltro_storage_blobs", G = "_voltro_storage_usage", Ee = N(H, {
|
|
40
40
|
id: A({ prefix: "file" }),
|
|
41
41
|
tenantId: P().nullable(),
|
|
42
42
|
ownerId: P().nullable(),
|
|
@@ -59,7 +59,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
59
59
|
derivedFrom: P().nullable(),
|
|
60
60
|
kind: P().nullable(),
|
|
61
61
|
createdAt: F()
|
|
62
|
-
}).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]),
|
|
62
|
+
}).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]), De = N(U, {
|
|
63
63
|
id: A({ prefix: "sgrant" }),
|
|
64
64
|
refId: P(),
|
|
65
65
|
principalType: P(),
|
|
@@ -68,19 +68,19 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
68
68
|
createdAt: F(),
|
|
69
69
|
expiresAt: F().nullable(),
|
|
70
70
|
createdBy: P().nullable()
|
|
71
|
-
}).index(["refId"]).index(["principalId"]),
|
|
71
|
+
}).index(["refId"]).index(["principalId"]), Oe = N(G, {
|
|
72
72
|
id: A({ prefix: "susage" }),
|
|
73
73
|
tenantId: P().maxLength(191),
|
|
74
74
|
bytes: j().default(0),
|
|
75
75
|
count: j().default(0),
|
|
76
76
|
updatedAt: F()
|
|
77
|
-
}).unique("byStorageUsageTenant", ["tenantId"]),
|
|
77
|
+
}).unique("byStorageUsageTenant", ["tenantId"]), ke = N(W, {
|
|
78
78
|
id: A({ prefix: "blob" }),
|
|
79
79
|
key: P(),
|
|
80
80
|
data: oe(),
|
|
81
81
|
contentType: P(),
|
|
82
82
|
size: j()
|
|
83
|
-
}).index(["key"]),
|
|
83
|
+
}).index(["key"]), K = le([
|
|
84
84
|
{
|
|
85
85
|
name: "STORAGE_PROVIDER",
|
|
86
86
|
required: !1,
|
|
@@ -231,35 +231,35 @@ var ve = 1 << 20, ye = (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
|
-
]),
|
|
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
|
-
}),
|
|
239
|
+
}), Ae = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, je = /* @__PURE__ */ new Map(), Me = (e, t) => je.get(e)?.get(t)?.bytes, Ne = (e) => {
|
|
240
240
|
je.get(e)?.clear();
|
|
241
241
|
}, Pe = (e = "default") => {
|
|
242
242
|
let t = je.get(e) ?? /* @__PURE__ */ new Map();
|
|
243
243
|
return je.set(e, t), {
|
|
244
244
|
name: "memory",
|
|
245
245
|
presigns: !1,
|
|
246
|
-
put: (e, n, r) =>
|
|
246
|
+
put: (e, n, r) => b.sync(() => (t.set(e, {
|
|
247
247
|
bytes: n,
|
|
248
248
|
contentType: r.contentType
|
|
249
249
|
}), { size: n.byteLength })),
|
|
250
|
-
get: (e) =>
|
|
250
|
+
get: (e) => b.suspend(() => {
|
|
251
251
|
let n = t.get(e);
|
|
252
|
-
return n ?
|
|
252
|
+
return n ? b.succeed({
|
|
253
253
|
bytes: n.bytes,
|
|
254
254
|
contentType: n.contentType
|
|
255
|
-
}) :
|
|
255
|
+
}) : b.fail(q("memory", `no object at key '${e}'`, !1, 404));
|
|
256
256
|
}),
|
|
257
|
-
delete: (e) =>
|
|
257
|
+
delete: (e) => b.sync(() => {
|
|
258
258
|
t.delete(e);
|
|
259
259
|
}),
|
|
260
260
|
publicUrl: () => null,
|
|
261
|
-
getUrl: () =>
|
|
262
|
-
head: (e) =>
|
|
261
|
+
getUrl: () => b.succeed(""),
|
|
262
|
+
head: (e) => b.sync(() => {
|
|
263
263
|
let n = t.get(e);
|
|
264
264
|
return n ? { size: n.bytes.byteLength } : null;
|
|
265
265
|
})
|
|
@@ -269,9 +269,9 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
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) =>
|
|
272
|
+
}, r = (e, t, n = !1) => b.tryPromise({
|
|
273
273
|
try: e,
|
|
274
|
-
catch: (e) => e?.code === "ENOENT" ?
|
|
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 ve = 1 << 20, ye = (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: () =>
|
|
303
|
-
head: (e) =>
|
|
302
|
+
getUrl: () => b.succeed(""),
|
|
303
|
+
head: (e) => b.tryPromise({
|
|
304
304
|
try: async () => {
|
|
305
305
|
let t = await import("node:fs/promises");
|
|
306
306
|
try {
|
|
@@ -310,7 +310,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
310
310
|
throw e;
|
|
311
311
|
}
|
|
312
312
|
},
|
|
313
|
-
catch: (e) =>
|
|
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);
|
|
@@ -325,7 +325,7 @@ var ve = 1 << 20, ye = (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
|
|
328
|
+
await s(await V(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) {
|
|
@@ -364,11 +364,11 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
364
364
|
cmds: t,
|
|
365
365
|
presign: n.getSignedUrl
|
|
366
366
|
};
|
|
367
|
-
})(), r), a = (e) =>
|
|
367
|
+
})(), r), a = (e) => b.tryPromise({
|
|
368
368
|
try: e,
|
|
369
369
|
catch: (e) => {
|
|
370
370
|
let n = e?.$metadata?.httpStatusCode;
|
|
371
|
-
return
|
|
371
|
+
return q(t, String(e?.message ?? e), Ae(n), n);
|
|
372
372
|
}
|
|
373
373
|
}), o = async (e) => {
|
|
374
374
|
let t = e;
|
|
@@ -464,7 +464,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
464
464
|
UploadId: n
|
|
465
465
|
}));
|
|
466
466
|
}),
|
|
467
|
-
head: (n) =>
|
|
467
|
+
head: (n) => b.tryPromise({
|
|
468
468
|
try: async () => {
|
|
469
469
|
let { client: t, cmds: r } = await i();
|
|
470
470
|
try {
|
|
@@ -483,7 +483,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
483
483
|
},
|
|
484
484
|
catch: (e) => {
|
|
485
485
|
let n = e?.$metadata?.httpStatusCode;
|
|
486
|
-
return
|
|
486
|
+
return q(t, String(e?.message ?? e), Ae(n), n);
|
|
487
487
|
}
|
|
488
488
|
}),
|
|
489
489
|
getStream: (n) => a(async () => {
|
|
@@ -504,7 +504,7 @@ var ve = 1 << 20, ye = (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
|
|
507
|
+
let l = await V(r);
|
|
508
508
|
return await new c.Upload({
|
|
509
509
|
client: a,
|
|
510
510
|
params: {
|
|
@@ -532,11 +532,11 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
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) =>
|
|
535
|
+
}, n = (e) => b.tryPromise({
|
|
536
536
|
try: e,
|
|
537
|
-
catch: (e) =>
|
|
537
|
+
catch: (e) => q("database", String(e?.message ?? e), !0)
|
|
538
538
|
}), r = async (e) => (await t().query({
|
|
539
|
-
table:
|
|
539
|
+
table: W,
|
|
540
540
|
predicate: {
|
|
541
541
|
column: "key",
|
|
542
542
|
op: "eq",
|
|
@@ -555,31 +555,31 @@ var ve = 1 << 20, ye = (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(
|
|
558
|
+
return n ? await t().update(W, String(n.id), {
|
|
559
559
|
data: i,
|
|
560
560
|
contentType: a.contentType,
|
|
561
561
|
size: i.byteLength
|
|
562
|
-
}) : await t().insert(
|
|
562
|
+
}) : await t().insert(W, {
|
|
563
563
|
id: k({
|
|
564
564
|
kind: "typeid",
|
|
565
565
|
prefix: "blob"
|
|
566
|
-
},
|
|
566
|
+
}, W),
|
|
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) =>
|
|
573
|
+
get: (e) => b.suspend(() => n(() => r(e)).pipe(b.flatMap((t) => t ? b.succeed({
|
|
574
574
|
bytes: Le(t.data),
|
|
575
575
|
contentType: String(t.contentType)
|
|
576
|
-
}) :
|
|
576
|
+
}) : b.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(
|
|
579
|
+
n && await t().delete(W, String(n.id));
|
|
580
580
|
}),
|
|
581
581
|
publicUrl: () => null,
|
|
582
|
-
getUrl: () =>
|
|
582
|
+
getUrl: () => b.succeed(""),
|
|
583
583
|
head: (e) => n(async () => {
|
|
584
584
|
let t = await r(e);
|
|
585
585
|
return t ? { size: Number(t.size) } : null;
|
|
@@ -593,17 +593,17 @@ var ve = 1 << 20, ye = (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 =
|
|
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) =>
|
|
602
|
+
})(), t), r = (e) => b.tryPromise({
|
|
603
603
|
try: e,
|
|
604
604
|
catch: (e) => {
|
|
605
605
|
let t = e?.statusCode;
|
|
606
|
-
return
|
|
606
|
+
return q("azure", String(e?.message ?? e), Ae(t), t);
|
|
607
607
|
}
|
|
608
608
|
}), i = async (e) => {
|
|
609
609
|
if (!e) return /* @__PURE__ */ new Uint8Array();
|
|
@@ -645,7 +645,7 @@ var ve = 1 << 20, ye = (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) =>
|
|
648
|
+
head: (e) => b.tryPromise({
|
|
649
649
|
try: async () => {
|
|
650
650
|
let { container: t } = await n();
|
|
651
651
|
try {
|
|
@@ -661,7 +661,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
661
661
|
},
|
|
662
662
|
catch: (e) => {
|
|
663
663
|
let t = e?.statusCode;
|
|
664
|
-
return
|
|
664
|
+
return q("azure", String(e?.message ?? e), Ae(t), t);
|
|
665
665
|
}
|
|
666
666
|
}),
|
|
667
667
|
getStream: (e) => r(async () => {
|
|
@@ -673,7 +673,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
673
673
|
};
|
|
674
674
|
}),
|
|
675
675
|
putStream: (e, t, i) => r(async () => {
|
|
676
|
-
let { container: r } = await n(), a = await
|
|
676
|
+
let { container: r } = await n(), a = await V(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 () => {
|
|
@@ -754,14 +754,14 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
754
754
|
if (!n || !r) return !1;
|
|
755
755
|
let i = Buffer.from(r, "hex"), a = fe(e, n, i.length);
|
|
756
756
|
return a.length === i.length && L(a, i);
|
|
757
|
-
}, Ye = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], Xe = (e) => Ye(e.metadata?.roles), Ze = (e) => Ye(e.scopes), Qe = (e, t) => e.some((e) => t.includes(e)), $e = (e) => Ye(e.metadata?.groups), et = (e) => typeof e == "boolean" ?
|
|
757
|
+
}, Ye = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], Xe = (e) => Ye(e.metadata?.roles), Ze = (e) => Ye(e.scopes), Qe = (e, t) => e.some((e) => t.includes(e)), $e = (e) => Ye(e.metadata?.groups), et = (e) => typeof e == "boolean" ? b.succeed(e) : b.isEffect(e) ? e : b.promise(() => e), tt = (e, t, n = {}) => b.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*
|
|
761
|
+
let i = n.resolveGroups ? yield* b.promise(async () => await n.resolveGroups(t)) : $e(t);
|
|
762
762
|
for (let a of r) if (yield* nt(a, e, t, i, n)) return !0;
|
|
763
763
|
return !1;
|
|
764
|
-
}), nt = (e, t, n, r, i) =>
|
|
764
|
+
}), nt = (e, t, n, r, i) => b.gen(function* () {
|
|
765
765
|
let a = !1, o = (e) => (a = !0, e);
|
|
766
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(Qe(Xe(n), e.roles)) || e.groups && e.groups.length > 0 && !o(Qe(r, e.groups)) || e.scopes && e.scopes.length > 0 && !o(Qe(Ze(n), e.scopes)) || e.password !== void 0 && e.password && !o(Je(i.password, t.passwordHash))) return !1;
|
|
767
767
|
if (e.guard) {
|
|
@@ -786,7 +786,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
786
786
|
}, it = (e, t, n, r, i) => {
|
|
787
787
|
let a = rt(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
|
-
}, at = (e, t) => t.resolveGroups ?
|
|
789
|
+
}, at = (e, t) => t.resolveGroups ? b.promise(async () => await t.resolveGroups(e)) : b.succeed($e(e)), X = () => K.read("VOLTRO_STORAGE_SECRET") ?? ie(), Z = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), Q = (e) => {
|
|
790
790
|
let t = e.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - e.length % 4) % 4);
|
|
791
791
|
return Buffer.from(t, "base64");
|
|
792
792
|
}, ot = (e, t, n = X()) => {
|
|
@@ -1015,14 +1015,14 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1015
1015
|
}, wt = (e) => e ?? "global", Tt = () => {
|
|
1016
1016
|
let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
|
|
1017
1017
|
return {
|
|
1018
|
-
insert: (t) =>
|
|
1018
|
+
insert: (t) => b.sync(() => {
|
|
1019
1019
|
e.set(t.id, t);
|
|
1020
1020
|
}),
|
|
1021
|
-
getById: (t) =>
|
|
1022
|
-
delete: (t) =>
|
|
1023
|
-
listRecent: (t) =>
|
|
1024
|
-
countByKey: (t, n) =>
|
|
1025
|
-
usageByTenant: (t) =>
|
|
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(() => {
|
|
1026
1026
|
let n = 0, r = 0;
|
|
1027
1027
|
for (let i of e.values()) (i.tenantId ?? null) === (t ?? null) && (n += i.size, r++);
|
|
1028
1028
|
return {
|
|
@@ -1030,7 +1030,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1030
1030
|
count: r
|
|
1031
1031
|
};
|
|
1032
1032
|
}),
|
|
1033
|
-
consumeUsage: (e, n, r) =>
|
|
1033
|
+
consumeUsage: (e, n, r) => b.sync(() => {
|
|
1034
1034
|
let i = wt(e), a = t.get(i) ?? {
|
|
1035
1035
|
bytes: 0,
|
|
1036
1036
|
count: 0
|
|
@@ -1044,15 +1044,15 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1044
1044
|
count: a.count
|
|
1045
1045
|
};
|
|
1046
1046
|
}),
|
|
1047
|
-
releaseUsage: (e, n) =>
|
|
1047
|
+
releaseUsage: (e, n) => b.sync(() => {
|
|
1048
1048
|
let r = wt(e), i = t.get(r);
|
|
1049
1049
|
i && t.set(r, {
|
|
1050
1050
|
bytes: Math.max(0, i.bytes - n.bytes),
|
|
1051
1051
|
count: Math.max(0, i.count - n.count)
|
|
1052
1052
|
});
|
|
1053
1053
|
}),
|
|
1054
|
-
listByDerivedFrom: (t) =>
|
|
1055
|
-
listRefs: (t) =>
|
|
1054
|
+
listByDerivedFrom: (t) => b.sync(() => [...e.values()].filter((e) => (e.derivedFrom ?? null) === t)),
|
|
1055
|
+
listRefs: (t) => b.sync(() => [...e.values()].filter((e) => Ct(e, t)).sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime()).slice(t.offset, t.offset + t.limit))
|
|
1056
1056
|
};
|
|
1057
1057
|
}, Et = (e) => Array.isArray(e) && e.every((e) => typeof e == "string") ? e : null, Dt = (e) => ({
|
|
1058
1058
|
id: String(e.id),
|
|
@@ -1077,7 +1077,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1077
1077
|
caption: e.caption ?? null,
|
|
1078
1078
|
derivedFrom: e.derivedFrom ?? null,
|
|
1079
1079
|
kind: e.kind ?? null
|
|
1080
|
-
}), $ = (e) =>
|
|
1080
|
+
}), $ = (e) => b.tryPromise({
|
|
1081
1081
|
try: e,
|
|
1082
1082
|
catch: (e) => new t({
|
|
1083
1083
|
provider: "refstore",
|
|
@@ -1096,10 +1096,10 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1096
1096
|
skip: void 0,
|
|
1097
1097
|
projection: void 0
|
|
1098
1098
|
}))[0] ?? null, kt = (e) => ({
|
|
1099
|
-
insert: (t) => $(() => e.insert(
|
|
1099
|
+
insert: (t) => $(() => e.insert(H, { ...t })),
|
|
1100
1100
|
getById: (t) => $(async () => {
|
|
1101
1101
|
let n = await e.query({
|
|
1102
|
-
table:
|
|
1102
|
+
table: H,
|
|
1103
1103
|
predicate: {
|
|
1104
1104
|
column: "id",
|
|
1105
1105
|
op: "eq",
|
|
@@ -1112,9 +1112,9 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1112
1112
|
});
|
|
1113
1113
|
return n[0] ? Dt(n[0]) : null;
|
|
1114
1114
|
}),
|
|
1115
|
-
delete: (t) => $(() => e.delete(
|
|
1115
|
+
delete: (t) => $(() => e.delete(H, t)),
|
|
1116
1116
|
listRecent: (t) => $(async () => (await e.query({
|
|
1117
|
-
table:
|
|
1117
|
+
table: H,
|
|
1118
1118
|
predicate: void 0,
|
|
1119
1119
|
order: [{
|
|
1120
1120
|
column: "createdAt",
|
|
@@ -1125,7 +1125,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1125
1125
|
projection: void 0
|
|
1126
1126
|
})).map(Dt)),
|
|
1127
1127
|
countByKey: (t, n) => $(async () => (await e.query({
|
|
1128
|
-
table:
|
|
1128
|
+
table: H,
|
|
1129
1129
|
predicate: { and: [{
|
|
1130
1130
|
column: "bucket",
|
|
1131
1131
|
op: "eq",
|
|
@@ -1142,7 +1142,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1142
1142
|
})).length),
|
|
1143
1143
|
usageByTenant: (t) => $(async () => {
|
|
1144
1144
|
let n = await e.query({
|
|
1145
|
-
table:
|
|
1145
|
+
table: H,
|
|
1146
1146
|
predicate: {
|
|
1147
1147
|
column: "tenantId",
|
|
1148
1148
|
op: "eq",
|
|
@@ -1183,7 +1183,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1183
1183
|
let t = k({
|
|
1184
1184
|
kind: "typeid",
|
|
1185
1185
|
prefix: "susage"
|
|
1186
|
-
},
|
|
1186
|
+
}, G), r = await e.insertIgnore(G, {
|
|
1187
1187
|
id: t,
|
|
1188
1188
|
tenantId: i,
|
|
1189
1189
|
bytes: n.bytes,
|
|
@@ -1215,7 +1215,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1215
1215
|
throw Error(`storage usage release: contention on tenant '${r}' exceeded 32 attempts`);
|
|
1216
1216
|
}),
|
|
1217
1217
|
listByDerivedFrom: (t) => $(async () => (await e.query({
|
|
1218
|
-
table:
|
|
1218
|
+
table: H,
|
|
1219
1219
|
predicate: {
|
|
1220
1220
|
column: "derivedFrom",
|
|
1221
1221
|
op: "eq",
|
|
@@ -1242,7 +1242,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1242
1242
|
});
|
|
1243
1243
|
let r = n.length === 0 ? void 0 : n.length === 1 ? n[0] : { and: n };
|
|
1244
1244
|
return (await e.query({
|
|
1245
|
-
table:
|
|
1245
|
+
table: H,
|
|
1246
1246
|
predicate: r,
|
|
1247
1247
|
order: [{
|
|
1248
1248
|
column: "createdAt",
|
|
@@ -1256,15 +1256,15 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1256
1256
|
}), At = () => {
|
|
1257
1257
|
let e = /* @__PURE__ */ new Map();
|
|
1258
1258
|
return {
|
|
1259
|
-
insert: (t) =>
|
|
1259
|
+
insert: (t) => b.sync(() => {
|
|
1260
1260
|
e.set(t.id, t);
|
|
1261
1261
|
}),
|
|
1262
|
-
delete: (t) =>
|
|
1262
|
+
delete: (t) => b.sync(() => {
|
|
1263
1263
|
e.delete(t);
|
|
1264
1264
|
}),
|
|
1265
|
-
getById: (t) =>
|
|
1266
|
-
listByRef: (t) =>
|
|
1267
|
-
deleteByRef: (t) =>
|
|
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(() => {
|
|
1268
1268
|
for (let [n, r] of e) r.refId === t && e.delete(n);
|
|
1269
1269
|
})
|
|
1270
1270
|
};
|
|
@@ -1278,11 +1278,11 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1278
1278
|
expiresAt: e.expiresAt ? e.expiresAt instanceof Date ? e.expiresAt : new Date(String(e.expiresAt)) : null,
|
|
1279
1279
|
createdBy: e.createdBy ?? null
|
|
1280
1280
|
}), Mt = (e) => ({
|
|
1281
|
-
insert: (t) => $(() => e.insert(
|
|
1282
|
-
delete: (t) => $(() => e.delete(
|
|
1281
|
+
insert: (t) => $(() => e.insert(U, { ...t })),
|
|
1282
|
+
delete: (t) => $(() => e.delete(U, t)),
|
|
1283
1283
|
getById: (t) => $(async () => {
|
|
1284
1284
|
let n = (await e.query({
|
|
1285
|
-
table:
|
|
1285
|
+
table: U,
|
|
1286
1286
|
predicate: {
|
|
1287
1287
|
column: "id",
|
|
1288
1288
|
op: "eq",
|
|
@@ -1296,7 +1296,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1296
1296
|
return n ? jt(n) : null;
|
|
1297
1297
|
}),
|
|
1298
1298
|
listByRef: (t) => $(async () => (await e.query({
|
|
1299
|
-
table:
|
|
1299
|
+
table: U,
|
|
1300
1300
|
predicate: {
|
|
1301
1301
|
column: "refId",
|
|
1302
1302
|
op: "eq",
|
|
@@ -1312,7 +1312,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1312
1312
|
})).map(jt)),
|
|
1313
1313
|
deleteByRef: (t) => $(async () => {
|
|
1314
1314
|
let n = await e.query({
|
|
1315
|
-
table:
|
|
1315
|
+
table: U,
|
|
1316
1316
|
predicate: {
|
|
1317
1317
|
column: "refId",
|
|
1318
1318
|
op: "eq",
|
|
@@ -1323,38 +1323,47 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1323
1323
|
skip: void 0,
|
|
1324
1324
|
projection: void 0
|
|
1325
1325
|
});
|
|
1326
|
-
for (let t of n) await e.delete(
|
|
1326
|
+
for (let t of n) await e.delete(U, String(t.id));
|
|
1327
1327
|
})
|
|
1328
1328
|
}), Nt = () => k({
|
|
1329
1329
|
kind: "typeid",
|
|
1330
1330
|
prefix: "file"
|
|
1331
|
-
},
|
|
1331
|
+
}, H), Pt = () => k({
|
|
1332
1332
|
kind: "typeid",
|
|
1333
1333
|
prefix: "grant"
|
|
1334
|
-
},
|
|
1335
|
-
let { provider: a, refStore: o, grantStore: s, bucket: c } = i, l = i.access ?? {}, u = i.attempts ?? 3, d = i.urlExpiresInSec ?? 3600, f = (e) => St(i.publicBaseUrl, e), p =
|
|
1334
|
+
}, U), Ft = (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) => St(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) => [
|
|
1336
1336
|
i.tenantPrefix,
|
|
1337
1337
|
e ?? "global",
|
|
1338
1338
|
n ?? t
|
|
1339
|
-
].filter(Boolean).join("/"),
|
|
1339
|
+
].filter(Boolean).join("/"), ee = (e) => {
|
|
1340
|
+
if (e === void 0) return b.succeed(void 0);
|
|
1341
|
+
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({
|
|
1343
|
+
provider: a.name,
|
|
1344
|
+
message: `storage key rejected: ${n}`,
|
|
1345
|
+
transient: !1,
|
|
1346
|
+
status: 400
|
|
1347
|
+
}));
|
|
1348
|
+
}, h = (e, t, n) => [
|
|
1340
1349
|
i.tenantPrefix,
|
|
1341
1350
|
e ?? "global",
|
|
1342
1351
|
"_incoming",
|
|
1343
1352
|
t,
|
|
1344
1353
|
String(n).padStart(6, "0")
|
|
1345
|
-
].filter(Boolean).join("/"), g = (e, n) => n !== void 0 && e.tenantId !== n ?
|
|
1354
|
+
].filter(Boolean).join("/"), g = (e, n) => n !== void 0 && e.tenantId !== n ? b.fail(new t({
|
|
1346
1355
|
provider: a.name,
|
|
1347
1356
|
message: "cross-tenant access denied",
|
|
1348
1357
|
transient: !1,
|
|
1349
1358
|
status: 403
|
|
1350
|
-
})) :
|
|
1359
|
+
})) : b.succeed(e), _ = (e, n) => o.getById(e).pipe(b.flatMap((r) => r ? g(r, n) : b.fail(new t({
|
|
1351
1360
|
provider: a.name,
|
|
1352
1361
|
message: `no ref '${e}'`,
|
|
1353
1362
|
transient: !1,
|
|
1354
1363
|
status: 404
|
|
1355
|
-
})))),
|
|
1364
|
+
})))), te = (e) => b.suspend(() => {
|
|
1356
1365
|
let n = i.scan(e);
|
|
1357
|
-
return
|
|
1366
|
+
return b.isEffect(n) ? n : b.tryPromise({
|
|
1358
1367
|
try: () => Promise.resolve(n),
|
|
1359
1368
|
catch: (e) => new t({
|
|
1360
1369
|
provider: "scan",
|
|
@@ -1362,45 +1371,45 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1362
1371
|
transient: !0
|
|
1363
1372
|
})
|
|
1364
1373
|
});
|
|
1365
|
-
}),
|
|
1374
|
+
}), ne = (e) => b.suspend(() => {
|
|
1366
1375
|
let t = e.contentType;
|
|
1367
|
-
if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return
|
|
1376
|
+
if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return b.succeed(null);
|
|
1368
1377
|
let n;
|
|
1369
1378
|
try {
|
|
1370
1379
|
n = i.videoProbe(e);
|
|
1371
1380
|
} catch {
|
|
1372
|
-
return
|
|
1381
|
+
return b.succeed(null);
|
|
1373
1382
|
}
|
|
1374
|
-
return
|
|
1383
|
+
return b.isEffect(n) ? n.pipe(b.catchAll(() => b.succeed(null))) : b.tryPromise({
|
|
1375
1384
|
try: () => Promise.resolve(n),
|
|
1376
1385
|
catch: () => null
|
|
1377
|
-
}).pipe(
|
|
1378
|
-
}), v = (e) =>
|
|
1386
|
+
}).pipe(b.catchAll(() => b.succeed(null)));
|
|
1387
|
+
}), v = (e) => b.gen(function* () {
|
|
1379
1388
|
let t = yt(e.bytes, e.contentType, i.limits);
|
|
1380
|
-
if (t) return yield*
|
|
1389
|
+
if (t) return yield* b.fail(new n(t));
|
|
1381
1390
|
if (i.scan) {
|
|
1382
|
-
let t = yield*
|
|
1391
|
+
let t = yield* te({
|
|
1383
1392
|
bytes: e.bytes,
|
|
1384
1393
|
contentType: e.contentType,
|
|
1385
1394
|
...e.key ? { key: e.key } : {}
|
|
1386
1395
|
});
|
|
1387
|
-
if (!t.clean) return yield*
|
|
1396
|
+
if (!t.clean) return yield* b.fail(new r({ threat: t.threat ?? "unknown" }));
|
|
1388
1397
|
}
|
|
1389
|
-
let s = yield*
|
|
1398
|
+
let s = yield* b.promise(() => bt(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* ne({
|
|
1390
1399
|
bytes: l,
|
|
1391
1400
|
contentType: e.contentType
|
|
1392
|
-
}), d = s.width ?? u?.width, f = s.height ?? u?.height, h = s.placeholder ?? u?.poster, g = e.duration ?? u?.duration, _ = yield*
|
|
1401
|
+
}), d = s.width ?? u?.width, f = s.height ?? u?.height, h = s.placeholder ?? u?.poster, g = e.duration ?? u?.duration, _ = yield* b.promise(() => xt(l)), v = e.tenantId ?? null, y = e.visibility ?? "private", C = m(v, _, yield* ee(e.key)), w = {
|
|
1393
1402
|
bytes: l.byteLength,
|
|
1394
1403
|
count: 1
|
|
1395
1404
|
}, T = yield* o.consumeUsage(v, w, i.quota);
|
|
1396
1405
|
if (!T.allowed) {
|
|
1397
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}`;
|
|
1398
|
-
return yield*
|
|
1407
|
+
return yield* b.fail(new n({
|
|
1399
1408
|
reason: "quota-exceeded",
|
|
1400
1409
|
detail: t
|
|
1401
1410
|
}));
|
|
1402
1411
|
}
|
|
1403
|
-
let
|
|
1412
|
+
let re = e.password ? yield* b.sync(() => qe(e.password)) : null, E = {
|
|
1404
1413
|
id: Nt(),
|
|
1405
1414
|
tenantId: v,
|
|
1406
1415
|
ownerId: e.ownerId ?? null,
|
|
@@ -1411,7 +1420,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1411
1420
|
checksum: _,
|
|
1412
1421
|
visibility: y,
|
|
1413
1422
|
accessPolicy: e.access ?? null,
|
|
1414
|
-
passwordHash:
|
|
1423
|
+
passwordHash: re,
|
|
1415
1424
|
createdAt: /* @__PURE__ */ new Date(),
|
|
1416
1425
|
...d === void 0 ? {} : { width: d },
|
|
1417
1426
|
...f === void 0 ? {} : { height: f },
|
|
@@ -1424,25 +1433,25 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1424
1433
|
...e.derivedFrom === void 0 ? {} : { derivedFrom: e.derivedFrom },
|
|
1425
1434
|
...e.kind === void 0 ? {} : { kind: e.kind }
|
|
1426
1435
|
};
|
|
1427
|
-
return yield* ((e) => e.pipe(
|
|
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, {
|
|
1428
1437
|
contentType: e.contentType,
|
|
1429
1438
|
public: y === "public"
|
|
1430
|
-
}).pipe(
|
|
1431
|
-
}), y = (e) =>
|
|
1432
|
-
if (!i.transcode) return
|
|
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([]);
|
|
1433
1442
|
let t;
|
|
1434
1443
|
try {
|
|
1435
1444
|
t = i.transcode(e);
|
|
1436
1445
|
} catch {
|
|
1437
|
-
return
|
|
1446
|
+
return b.succeed([]);
|
|
1438
1447
|
}
|
|
1439
|
-
return
|
|
1448
|
+
return b.isEffect(t) ? t.pipe(b.catchAll(() => b.succeed([]))) : b.tryPromise({
|
|
1440
1449
|
try: () => Promise.resolve(t),
|
|
1441
1450
|
catch: () => []
|
|
1442
|
-
}).pipe(
|
|
1443
|
-
}),
|
|
1451
|
+
}).pipe(b.catchAll(() => b.succeed([])));
|
|
1452
|
+
}), S = (e) => b.gen(function* () {
|
|
1444
1453
|
if (!i.transcode || e.derivedFrom != null) return [];
|
|
1445
|
-
let t = yield* a.get(e.key).pipe(
|
|
1454
|
+
let t = yield* a.get(e.key).pipe(b.retry(p)), n = yield* y({
|
|
1446
1455
|
bytes: t.bytes,
|
|
1447
1456
|
contentType: e.contentType,
|
|
1448
1457
|
ref: e
|
|
@@ -1461,7 +1470,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1461
1470
|
r.push(n);
|
|
1462
1471
|
}
|
|
1463
1472
|
return r;
|
|
1464
|
-
}),
|
|
1473
|
+
}), w = (e, t, n) => b.gen(function* () {
|
|
1465
1474
|
if (e.visibility === "public" || (yield* tt(e, t, {
|
|
1466
1475
|
...l,
|
|
1467
1476
|
...n?.password === void 0 ? {} : { password: n.password }
|
|
@@ -1477,65 +1486,65 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1477
1486
|
};
|
|
1478
1487
|
return {
|
|
1479
1488
|
put: v,
|
|
1480
|
-
get: (e, t) => _(e, t?.tenantId).pipe(
|
|
1489
|
+
get: (e, t) => _(e, t?.tenantId).pipe(b.flatMap((e) => a.get(e.key).pipe(b.retry(p), b.map((t) => ({
|
|
1481
1490
|
bytes: t.bytes,
|
|
1482
1491
|
ref: e
|
|
1483
1492
|
}))))),
|
|
1484
|
-
getRange: (e, n, r) => _(e, r?.tenantId).pipe(
|
|
1493
|
+
getRange: (e, n, r) => _(e, r?.tenantId).pipe(b.flatMap((e) => {
|
|
1485
1494
|
let r = e.size, i = Math.max(0, Math.trunc(n.start));
|
|
1486
|
-
if (r > 0 && i >= r) return
|
|
1495
|
+
if (r > 0 && i >= r) return b.fail(new t({
|
|
1487
1496
|
provider: a.name,
|
|
1488
1497
|
message: `range start ${i} past end ${r}`,
|
|
1489
1498
|
transient: !1,
|
|
1490
1499
|
status: 416
|
|
1491
1500
|
}));
|
|
1492
1501
|
let o = Math.min(Math.trunc(n.endInclusive), Math.max(0, r - 1));
|
|
1493
|
-
return o < i ?
|
|
1502
|
+
return o < i ? b.fail(new t({
|
|
1494
1503
|
provider: a.name,
|
|
1495
1504
|
message: `empty range ${i}-${o}`,
|
|
1496
1505
|
transient: !1,
|
|
1497
1506
|
status: 416
|
|
1498
|
-
})) : (a.getRange ? a.getRange(e.key, i, o).pipe(
|
|
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) => ({
|
|
1499
1508
|
bytes: t,
|
|
1500
1509
|
ref: e,
|
|
1501
1510
|
totalSize: r
|
|
1502
1511
|
})));
|
|
1503
1512
|
})),
|
|
1504
|
-
getUrl: (e, t) => _(e, t?.tenantId).pipe(
|
|
1505
|
-
head: (e, t) => o.getById(e).pipe(
|
|
1506
|
-
delete: (e, t) => _(e, t?.tenantId).pipe(
|
|
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, {
|
|
1507
1516
|
bytes: t.size,
|
|
1508
1517
|
count: 1
|
|
1509
|
-
}))) :
|
|
1510
|
-
mintUrl: (n, r, i) =>
|
|
1511
|
-
let s = yield* o.getById(n).pipe(
|
|
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({
|
|
1512
1521
|
provider: a.name,
|
|
1513
1522
|
message: `no ref '${n}'`,
|
|
1514
1523
|
transient: !1,
|
|
1515
1524
|
status: 404
|
|
1516
1525
|
}))));
|
|
1517
1526
|
if (s.visibility === "public") return T(s);
|
|
1518
|
-
if (!(yield*
|
|
1527
|
+
if (!(yield* w(s, r, i?.password === void 0 ? {} : { password: i.password }))) return yield* b.fail(new e({
|
|
1519
1528
|
refId: n,
|
|
1520
1529
|
reason: "access denied"
|
|
1521
1530
|
}));
|
|
1522
1531
|
let c = i?.expiresInSec ?? d;
|
|
1523
1532
|
if (a.presigns) return yield* a.getUrl(s.key, c);
|
|
1524
|
-
let l = yield*
|
|
1533
|
+
let l = yield* b.sync(() => ot(s.id, c));
|
|
1525
1534
|
return `${f(s.id)}?t=${l}`;
|
|
1526
1535
|
}),
|
|
1527
|
-
mintUploadUrl: (e) =>
|
|
1528
|
-
if (!a.getUploadUrl) return yield*
|
|
1536
|
+
mintUploadUrl: (e) => b.gen(function* () {
|
|
1537
|
+
if (!a.getUploadUrl) return yield* b.fail(new t({
|
|
1529
1538
|
provider: a.name,
|
|
1530
1539
|
message: `provider '${a.name}' does not support presigned uploads`,
|
|
1531
1540
|
transient: !1,
|
|
1532
1541
|
status: 400
|
|
1533
1542
|
}));
|
|
1534
|
-
let n = m(e.tenantId ?? null, "", e.key);
|
|
1543
|
+
let n = m(e.tenantId ?? null, "", yield* ee(e.key));
|
|
1535
1544
|
return yield* a.getUploadUrl(n, e.expiresInSec ?? d, e.contentType);
|
|
1536
1545
|
}),
|
|
1537
|
-
checkAccess:
|
|
1538
|
-
grant: (e) =>
|
|
1546
|
+
checkAccess: w,
|
|
1547
|
+
grant: (e) => b.gen(function* () {
|
|
1539
1548
|
let t = {
|
|
1540
1549
|
id: Pt(),
|
|
1541
1550
|
refId: e.refId,
|
|
@@ -1548,7 +1557,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1548
1557
|
};
|
|
1549
1558
|
return yield* s.insert(t), t;
|
|
1550
1559
|
}),
|
|
1551
|
-
listRefs: (e) =>
|
|
1560
|
+
listRefs: (e) => b.suspend(() => {
|
|
1552
1561
|
let t = Math.min(500, Math.max(1, Math.trunc(e?.limit ?? 50))), n = Math.max(0, Math.trunc(e?.offset ?? 0)), r = {
|
|
1553
1562
|
tenantId: e && "tenantId" in e ? e.tenantId : void 0,
|
|
1554
1563
|
folder: e?.folder,
|
|
@@ -1558,7 +1567,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1558
1567
|
limit: t + 1,
|
|
1559
1568
|
offset: n
|
|
1560
1569
|
};
|
|
1561
|
-
return o.listRefs(r).pipe(
|
|
1570
|
+
return o.listRefs(r).pipe(b.map((e) => {
|
|
1562
1571
|
let r = e.length > t;
|
|
1563
1572
|
return {
|
|
1564
1573
|
refs: r ? e.slice(0, t) : e,
|
|
@@ -1570,19 +1579,19 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1570
1579
|
getGrant: (e) => s.getById(e),
|
|
1571
1580
|
listGrants: (e) => s.listByRef(e),
|
|
1572
1581
|
usage: (e) => o.usageByTenant(e),
|
|
1573
|
-
sweepOrphans: (e) =>
|
|
1582
|
+
sweepOrphans: (e) => b.gen(function* () {
|
|
1574
1583
|
let t = e?.limit ?? 1e3, n = e?.dryRun ?? !1, r = yield* o.listRecent(t), i = [];
|
|
1575
|
-
for (let e of r) (yield* a.head(e.key).pipe(
|
|
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, {
|
|
1576
1585
|
bytes: e.size,
|
|
1577
1586
|
count: 1
|
|
1578
|
-
}).pipe(
|
|
1587
|
+
}).pipe(b.ignore)), i.push(e.id));
|
|
1579
1588
|
return {
|
|
1580
1589
|
scanned: r.length,
|
|
1581
1590
|
removed: i
|
|
1582
1591
|
};
|
|
1583
1592
|
}),
|
|
1584
|
-
ingestUrl: (e, n) =>
|
|
1585
|
-
let r = yield*
|
|
1593
|
+
ingestUrl: (e, n) => b.gen(function* () {
|
|
1594
|
+
let r = yield* b.tryPromise({
|
|
1586
1595
|
try: () => fetch(e),
|
|
1587
1596
|
catch: (e) => new t({
|
|
1588
1597
|
provider: "ingest",
|
|
@@ -1590,13 +1599,13 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1590
1599
|
transient: !0
|
|
1591
1600
|
})
|
|
1592
1601
|
});
|
|
1593
|
-
if (!r.ok) return yield*
|
|
1602
|
+
if (!r.ok) return yield* b.fail(new t({
|
|
1594
1603
|
provider: "ingest",
|
|
1595
1604
|
message: `fetch ${e} → ${r.status}`,
|
|
1596
1605
|
transient: r.status >= 500,
|
|
1597
1606
|
status: r.status
|
|
1598
1607
|
}));
|
|
1599
|
-
let i = yield*
|
|
1608
|
+
let i = yield* b.tryPromise({
|
|
1600
1609
|
try: () => r.arrayBuffer(),
|
|
1601
1610
|
catch: (e) => new t({
|
|
1602
1611
|
provider: "ingest",
|
|
@@ -1617,8 +1626,8 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1617
1626
|
...n?.caption === void 0 ? {} : { caption: n.caption }
|
|
1618
1627
|
});
|
|
1619
1628
|
}),
|
|
1620
|
-
mintPresignedUpload: (e) =>
|
|
1621
|
-
if (!a.getUploadUrl) return yield*
|
|
1629
|
+
mintPresignedUpload: (e) => b.gen(function* () {
|
|
1630
|
+
if (!a.getUploadUrl) return yield* b.fail(new t({
|
|
1622
1631
|
provider: a.name,
|
|
1623
1632
|
message: `provider '${a.name}' does not support presigned uploads`,
|
|
1624
1633
|
transient: !1,
|
|
@@ -1627,14 +1636,14 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1627
1636
|
let n = e.expiresInSec ?? d, r = `_incoming/${k({
|
|
1628
1637
|
kind: "typeid",
|
|
1629
1638
|
prefix: "up"
|
|
1630
|
-
},
|
|
1639
|
+
}, H)}`, i = m(e.tenantId ?? null, "", r);
|
|
1631
1640
|
return {
|
|
1632
1641
|
uploadUrl: yield* a.getUploadUrl(i, n, e.contentType),
|
|
1633
1642
|
key: i,
|
|
1634
1643
|
expiresInSec: n
|
|
1635
1644
|
};
|
|
1636
1645
|
}),
|
|
1637
|
-
finalizeUpload: (e) => a.get(e.key).pipe(
|
|
1646
|
+
finalizeUpload: (e) => a.get(e.key).pipe(b.retry(p), b.flatMap((t) => v({
|
|
1638
1647
|
bytes: t.bytes,
|
|
1639
1648
|
contentType: e.contentType,
|
|
1640
1649
|
...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
|
|
@@ -1644,12 +1653,12 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1644
1653
|
...e.tags === void 0 ? {} : { tags: e.tags },
|
|
1645
1654
|
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
1646
1655
|
...e.caption === void 0 ? {} : { caption: e.caption }
|
|
1647
|
-
})),
|
|
1648
|
-
putResumableChunk: (e) => a.put(h(e.tenantId ?? null, e.uploadId, e.index), e.bytes, { contentType: "application/octet-stream" }).pipe(
|
|
1649
|
-
resumableStatus: (e) =>
|
|
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* () {
|
|
1650
1659
|
let t = 0, n = 0;
|
|
1651
1660
|
for (; t < 1e6;) {
|
|
1652
|
-
let r = yield* a.head(h(e.tenantId ?? null, e.uploadId, t)).pipe(
|
|
1661
|
+
let r = yield* a.head(h(e.tenantId ?? null, e.uploadId, t)).pipe(b.retry(p), b.catchAll(() => b.succeed(null)));
|
|
1653
1662
|
if (r === null) break;
|
|
1654
1663
|
n += r.size, t += 1;
|
|
1655
1664
|
}
|
|
@@ -1658,15 +1667,15 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1658
1667
|
nextIndex: t
|
|
1659
1668
|
};
|
|
1660
1669
|
}),
|
|
1661
|
-
finalizeResumable: (e) =>
|
|
1670
|
+
finalizeResumable: (e) => b.gen(function* () {
|
|
1662
1671
|
let t = [];
|
|
1663
1672
|
for (let n = 0; n < e.count; n++) {
|
|
1664
|
-
let r = yield* a.get(h(e.tenantId ?? null, e.uploadId, n)).pipe(
|
|
1673
|
+
let r = yield* a.get(h(e.tenantId ?? null, e.uploadId, n)).pipe(b.retry(p));
|
|
1665
1674
|
t.push(r.bytes);
|
|
1666
1675
|
}
|
|
1667
1676
|
let n = t.reduce((e, t) => e + t.byteLength, 0), r = new Uint8Array(n), i = 0;
|
|
1668
1677
|
for (let e of t) r.set(e, i), i += e.byteLength;
|
|
1669
|
-
let o =
|
|
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 });
|
|
1670
1679
|
return yield* v({
|
|
1671
1680
|
bytes: r,
|
|
1672
1681
|
contentType: e.contentType,
|
|
@@ -1677,12 +1686,12 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1677
1686
|
...e.tags === void 0 ? {} : { tags: e.tags },
|
|
1678
1687
|
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
1679
1688
|
...e.caption === void 0 ? {} : { caption: e.caption }
|
|
1680
|
-
}).pipe(
|
|
1689
|
+
}).pipe(b.ensuring(o));
|
|
1681
1690
|
}),
|
|
1682
|
-
transcode: (e, t) => _(e, t?.tenantId).pipe(
|
|
1683
|
-
renditions: (e, t) => _(e, t?.tenantId).pipe(
|
|
1684
|
-
beginMultipartUpload: (e) =>
|
|
1685
|
-
if (!a.createMultipartUpload || !a.presignUploadPart || !a.completeMultipartUpload) return yield*
|
|
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({
|
|
1686
1695
|
provider: a.name,
|
|
1687
1696
|
message: `provider '${a.name}' does not support multipart uploads`,
|
|
1688
1697
|
transient: !1,
|
|
@@ -1691,30 +1700,30 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1691
1700
|
let n = m(e.tenantId ?? null, "", `multipart/${k({
|
|
1692
1701
|
kind: "typeid",
|
|
1693
1702
|
prefix: "mp"
|
|
1694
|
-
},
|
|
1703
|
+
}, H)}`);
|
|
1695
1704
|
return {
|
|
1696
1705
|
uploadId: (yield* a.createMultipartUpload(n, e.contentType, { public: (e.visibility ?? "private") === "public" })).uploadId,
|
|
1697
1706
|
key: n
|
|
1698
1707
|
};
|
|
1699
1708
|
}),
|
|
1700
|
-
signMultipartPart: (e) =>
|
|
1709
|
+
signMultipartPart: (e) => b.suspend(() => a.presignUploadPart ? a.presignUploadPart(e.key, e.uploadId, e.partNumber, e.expiresInSec ?? d) : b.fail(new t({
|
|
1701
1710
|
provider: a.name,
|
|
1702
1711
|
message: "provider does not support multipart uploads",
|
|
1703
1712
|
transient: !1,
|
|
1704
1713
|
status: 400
|
|
1705
1714
|
}))),
|
|
1706
|
-
completeMultipart: (e) =>
|
|
1707
|
-
if (!a.completeMultipartUpload) return yield*
|
|
1715
|
+
completeMultipart: (e) => b.gen(function* () {
|
|
1716
|
+
if (!a.completeMultipartUpload) return yield* b.fail(new t({
|
|
1708
1717
|
provider: a.name,
|
|
1709
1718
|
message: "provider does not support multipart uploads",
|
|
1710
1719
|
transient: !1,
|
|
1711
1720
|
status: 400
|
|
1712
1721
|
}));
|
|
1713
|
-
let r = yield* a.completeMultipartUpload(e.key, e.uploadId, e.parts), s = yield* a.head(e.key).pipe(
|
|
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 = {
|
|
1714
1723
|
bytes: l,
|
|
1715
1724
|
count: 1
|
|
1716
1725
|
};
|
|
1717
|
-
if (!(yield* o.consumeUsage(d, f, i.quota)).allowed) return yield* a.delete(e.key).pipe(
|
|
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({
|
|
1718
1727
|
reason: "quota-exceeded",
|
|
1719
1728
|
detail: `multipart upload of ${l} bytes exceeds tenant quota`
|
|
1720
1729
|
}));
|
|
@@ -1736,11 +1745,11 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1736
1745
|
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
1737
1746
|
...e.caption === void 0 ? {} : { caption: e.caption }
|
|
1738
1747
|
};
|
|
1739
|
-
return yield* o.insert(m).pipe(
|
|
1748
|
+
return yield* o.insert(m).pipe(b.onExit((e) => x.isSuccess(e) ? b.void : o.releaseUsage(d, f).pipe(b.ignore))), m;
|
|
1740
1749
|
}),
|
|
1741
|
-
abortMultipart: (e) =>
|
|
1750
|
+
abortMultipart: (e) => b.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(b.retry(p)) : b.void)
|
|
1742
1751
|
};
|
|
1743
|
-
}, It = (e) =>
|
|
1752
|
+
}, It = (e) => S.succeed(i, Ft(e)), Lt = (e, t = 65536) => {
|
|
1744
1753
|
let n = [Buffer.from("zINSTREAM\0", "utf8")];
|
|
1745
1754
|
for (let r = 0; r < e.length; r += t) {
|
|
1746
1755
|
let i = e.subarray(r, Math.min(r + t, e.length)), a = Buffer.alloc(4);
|
|
@@ -1758,7 +1767,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1758
1767
|
};
|
|
1759
1768
|
throw Error(`clamav: unexpected response: ${t}`);
|
|
1760
1769
|
}, zt = async (e, t) => {
|
|
1761
|
-
let n = await import("node:net"), r =
|
|
1770
|
+
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;
|
|
1762
1771
|
return new Promise((i, s) => {
|
|
1763
1772
|
let c = n.createConnection({
|
|
1764
1773
|
host: r,
|
|
@@ -1830,7 +1839,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1830
1839
|
//#endregion
|
|
1831
1840
|
//#region src/assetRef.ts
|
|
1832
1841
|
function Ut(e = {}) {
|
|
1833
|
-
let t = e.nullable ?? !0, n = e.fk === !1 ? P().externalId() : ce(() =>
|
|
1842
|
+
let t = e.nullable ?? !0, n = e.fk === !1 ? P().externalId() : ce(() => Ee, { onDelete: e.onDelete ?? "setNull" });
|
|
1834
1843
|
return t ? n.nullable() : n;
|
|
1835
1844
|
}
|
|
1836
1845
|
var Wt = () => se({
|
|
@@ -1851,8 +1860,8 @@ var Wt = () => se({
|
|
|
1851
1860
|
bytes: r ? new Uint8Array(Buffer.from(i, "base64")) : new Uint8Array(Buffer.from(decodeURIComponent(i), "utf8")),
|
|
1852
1861
|
contentType: n
|
|
1853
1862
|
};
|
|
1854
|
-
}, qt = (e, n) =>
|
|
1855
|
-
let r = yield*
|
|
1863
|
+
}, qt = (e, n) => b.gen(function* () {
|
|
1864
|
+
let r = yield* b.try({
|
|
1856
1865
|
try: () => Kt(n.dataUri),
|
|
1857
1866
|
catch: (e) => new t({
|
|
1858
1867
|
provider: "avatar",
|
|
@@ -1880,15 +1889,15 @@ var Wt = () => se({
|
|
|
1880
1889
|
if (Jt(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
|
|
1881
1890
|
dies with it — which is the exact failure it exists for. On a development machine this is normal
|
|
1882
1891
|
and can be ignored.`;
|
|
1883
|
-
}, Xt =
|
|
1892
|
+
}, Xt = K.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", Zt, Qt = (e) => {
|
|
1884
1893
|
Zt = e;
|
|
1885
|
-
}, $t = () => Zt ?? tn({}), en = () => Zt === void 0 ?
|
|
1894
|
+
}, $t = () => Zt ?? tn({}), en = () => Zt === void 0 ? K.read("STORAGE_PROVIDER") === void 0 ? void 0 : tn({}) : Zt, tn = (e) => {
|
|
1886
1895
|
if (e.provider && typeof e.provider == "object") return e.provider;
|
|
1887
|
-
let t = (e.provider ??
|
|
1896
|
+
let t = (e.provider ?? K.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = K.read("S3_BUCKET", e.bucket) ?? K.read("STORAGE_BUCKET") ?? "voltro";
|
|
1888
1897
|
switch (t) {
|
|
1889
1898
|
case "s3":
|
|
1890
1899
|
case "minio": {
|
|
1891
|
-
let r =
|
|
1900
|
+
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);
|
|
1892
1901
|
return Ie({
|
|
1893
1902
|
bucket: n,
|
|
1894
1903
|
name: t,
|
|
@@ -1898,13 +1907,13 @@ var Wt = () => se({
|
|
|
1898
1907
|
...o ? { secretAccessKey: o } : {},
|
|
1899
1908
|
...s ? { cdnBaseUrl: s } : {},
|
|
1900
1909
|
...e.publicAcl === void 0 ? {} : { publicAcl: e.publicAcl },
|
|
1901
|
-
...t === "minio" ||
|
|
1910
|
+
...t === "minio" || K.read("S3_FORCE_PATH_STYLE") === "1" ? { forcePathStyle: !0 } : {}
|
|
1902
1911
|
});
|
|
1903
1912
|
}
|
|
1904
1913
|
case "azure": {
|
|
1905
|
-
let t =
|
|
1914
|
+
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);
|
|
1906
1915
|
return ze({
|
|
1907
|
-
container:
|
|
1916
|
+
container: K.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
|
|
1908
1917
|
...t ? { accountName: t } : {},
|
|
1909
1918
|
...r ? { accountKey: r } : {},
|
|
1910
1919
|
...i ? { connectionString: i } : {},
|
|
@@ -1913,12 +1922,12 @@ var Wt = () => se({
|
|
|
1913
1922
|
});
|
|
1914
1923
|
}
|
|
1915
1924
|
case "database": return Re();
|
|
1916
|
-
case "filesystem": return Fe({ root:
|
|
1925
|
+
case "filesystem": return Fe({ root: K.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
|
|
1917
1926
|
default: return Pe(e.name ?? "default");
|
|
1918
1927
|
}
|
|
1919
1928
|
}, nn = (e) => {
|
|
1920
1929
|
if (e !== void 0) return e;
|
|
1921
|
-
let t =
|
|
1930
|
+
let t = K.read("STORAGE_ALLOWED_ORIGINS");
|
|
1922
1931
|
return t ? t.trim() === "*" ? "*" : t.split(",").map((e) => e.trim()).filter(Boolean) : [];
|
|
1923
1932
|
}, rn = (e, t) => {
|
|
1924
1933
|
if (!e || t !== "*" && !t.includes(e)) return {};
|
|
@@ -1960,9 +1969,9 @@ var Wt = () => se({
|
|
|
1960
1969
|
status: 403
|
|
1961
1970
|
}), sn = (e, t, n) => {
|
|
1962
1971
|
let r = n.request.subject;
|
|
1963
|
-
return (r.scopes ?? []).includes("admin:full") ?
|
|
1972
|
+
return (r.scopes ?? []).includes("admin:full") ? b.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(b.catchAll(() => b.fail(on())), b.flatMap((e) => {
|
|
1964
1973
|
let t = e?.ownerId;
|
|
1965
|
-
return t != null && t === r.id ?
|
|
1974
|
+
return t != null && t === r.id ? b.void : b.fail(on());
|
|
1966
1975
|
}));
|
|
1967
1976
|
}, cn = (e) => ({
|
|
1968
1977
|
id: e.id,
|
|
@@ -1974,9 +1983,9 @@ var Wt = () => se({
|
|
|
1974
1983
|
expiresAt: e.expiresAt ? e.expiresAt.toISOString() : null,
|
|
1975
1984
|
createdBy: e.createdBy
|
|
1976
1985
|
}), ln = "@voltro/plugin-storage", un = (i = {}) => {
|
|
1977
|
-
let
|
|
1978
|
-
Qt(
|
|
1979
|
-
let
|
|
1986
|
+
let y = tn(i);
|
|
1987
|
+
Qt(y);
|
|
1988
|
+
let x = K.read("S3_BUCKET", i.bucket) ?? K.read("STORAGE_BUCKET") ?? "voltro", S = K.read("VOLTRO_PUBLIC_URL", i.publicBaseUrl), C = nn(i.allowedOrigins), w = i.limits?.maxBytes, D = 5242880, oe = 21600, O = i.refStore === void 0 || i.refStore === "memory", k = i.grantStore === void 0 || i.grantStore === "memory", A = { current: O ? Tt() : i.refStore }, j = { current: k ? At() : i.grantStore }, M = {
|
|
1980
1989
|
insert: (e) => A.current.insert(e),
|
|
1981
1990
|
getById: (e) => A.current.getById(e),
|
|
1982
1991
|
delete: (e) => A.current.delete(e),
|
|
@@ -1994,10 +2003,10 @@ var Wt = () => se({
|
|
|
1994
2003
|
listByRef: (e) => j.current.listByRef(e),
|
|
1995
2004
|
deleteByRef: (e) => j.current.deleteByRef(e)
|
|
1996
2005
|
}, ce = {
|
|
1997
|
-
provider:
|
|
2006
|
+
provider: y,
|
|
1998
2007
|
refStore: M,
|
|
1999
2008
|
grantStore: se,
|
|
2000
|
-
bucket:
|
|
2009
|
+
bucket: x,
|
|
2001
2010
|
...i.tenantPrefix === void 0 ? {} : { tenantPrefix: i.tenantPrefix },
|
|
2002
2011
|
...i.attempts === void 0 ? {} : { attempts: i.attempts },
|
|
2003
2012
|
...i.urlExpiresInSec === void 0 ? {} : { urlExpiresInSec: i.urlExpiresInSec },
|
|
@@ -2007,10 +2016,10 @@ var Wt = () => se({
|
|
|
2007
2016
|
...i.videoProbe === void 0 ? {} : { videoProbe: i.videoProbe },
|
|
2008
2017
|
...i.transcode === void 0 ? {} : { transcode: i.transcode },
|
|
2009
2018
|
...i.autoTranscode === void 0 ? {} : { autoTranscode: i.autoTranscode },
|
|
2010
|
-
...
|
|
2019
|
+
...S ? { publicBaseUrl: S } : {},
|
|
2011
2020
|
...i.normalizeImages === void 0 ? {} : { normalizeImages: i.normalizeImages },
|
|
2012
2021
|
...i.quota === void 0 ? {} : { quota: i.quota }
|
|
2013
|
-
}, N = It(ce), P = Ft(ce), F = (e) =>
|
|
2022
|
+
}, N = It(ce), P = Ft(ce), F = (e) => b.runPromise(e.pipe(b.catchAll(() => b.succeed(null)))), le = (e, t) => {
|
|
2014
2023
|
if (!e) return "invalid";
|
|
2015
2024
|
let n = /^bytes=(\d*)-(\d*)$/.exec(e.trim());
|
|
2016
2025
|
if (!n) return "invalid";
|
|
@@ -2126,7 +2135,7 @@ var Wt = () => se({
|
|
|
2126
2135
|
};
|
|
2127
2136
|
let r = Ve(e.query), i = e.headers.range;
|
|
2128
2137
|
if (n.visibility === "public") {
|
|
2129
|
-
let e =
|
|
2138
|
+
let e = y.publicUrl?.(n.key) ?? null;
|
|
2130
2139
|
return e && !r ? {
|
|
2131
2140
|
status: 302,
|
|
2132
2141
|
headers: {
|
|
@@ -2141,7 +2150,7 @@ var Wt = () => se({
|
|
|
2141
2150
|
a = !!e && e.refId === t;
|
|
2142
2151
|
}
|
|
2143
2152
|
if (!a) {
|
|
2144
|
-
let t =
|
|
2153
|
+
let t = E(e.headers.cookie, Xt), r = t ? ae(t, ie()) : null;
|
|
2145
2154
|
r && (a = await F(P.checkAccess(n, r)) === !0);
|
|
2146
2155
|
}
|
|
2147
2156
|
if (!a) return {
|
|
@@ -2149,8 +2158,8 @@ var Wt = () => se({
|
|
|
2149
2158
|
body: "forbidden",
|
|
2150
2159
|
contentType: "text/plain"
|
|
2151
2160
|
};
|
|
2152
|
-
if (
|
|
2153
|
-
let e = await F(
|
|
2161
|
+
if (y.presigns && !r) {
|
|
2162
|
+
let e = await F(y.getUrl(n.key, 300));
|
|
2154
2163
|
if (e && /^https?:/.test(e)) return {
|
|
2155
2164
|
status: 302,
|
|
2156
2165
|
headers: {
|
|
@@ -2164,7 +2173,7 @@ var Wt = () => se({
|
|
|
2164
2173
|
method: "GET",
|
|
2165
2174
|
path: "/_voltro/storage",
|
|
2166
2175
|
handle: async (e) => {
|
|
2167
|
-
let t = await L(e), n = rn(e.headers.origin,
|
|
2176
|
+
let t = await L(e), n = rn(e.headers.origin, C);
|
|
2168
2177
|
return Object.keys(n).length === 0 ? t : {
|
|
2169
2178
|
...t,
|
|
2170
2179
|
headers: {
|
|
@@ -2178,7 +2187,7 @@ var Wt = () => se({
|
|
|
2178
2187
|
path: "/_voltro/storage/upload",
|
|
2179
2188
|
originGuard: "exempt",
|
|
2180
2189
|
handle: async (e) => {
|
|
2181
|
-
let t = rn(e.headers.origin,
|
|
2190
|
+
let t = rn(e.headers.origin, C);
|
|
2182
2191
|
if (e.method === "OPTIONS") return {
|
|
2183
2192
|
status: 204,
|
|
2184
2193
|
headers: t
|
|
@@ -2208,7 +2217,7 @@ var Wt = () => se({
|
|
|
2208
2217
|
contentType: "text/plain",
|
|
2209
2218
|
headers: t
|
|
2210
2219
|
};
|
|
2211
|
-
let i = await
|
|
2220
|
+
let i = await b.runPromise(P.put({
|
|
2212
2221
|
bytes: e.rawBody,
|
|
2213
2222
|
contentType: r.ct,
|
|
2214
2223
|
tenantId: r.tenant,
|
|
@@ -2219,21 +2228,21 @@ var Wt = () => se({
|
|
|
2219
2228
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
2220
2229
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
2221
2230
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
2222
|
-
}).pipe(
|
|
2231
|
+
}).pipe(b.flatMap((e) => P.getUrl(e.id).pipe(b.map((t) => ({
|
|
2223
2232
|
kind: "ok",
|
|
2224
2233
|
ref: e,
|
|
2225
2234
|
url: t
|
|
2226
|
-
})))),
|
|
2227
|
-
StorageRejected: (e) =>
|
|
2235
|
+
})))), b.catchTags({
|
|
2236
|
+
StorageRejected: (e) => b.succeed({
|
|
2228
2237
|
kind: "rejected",
|
|
2229
2238
|
status: e.reason === "too-large" ? 413 : 415,
|
|
2230
2239
|
detail: e.detail
|
|
2231
2240
|
}),
|
|
2232
|
-
StorageScanRejected: (e) =>
|
|
2241
|
+
StorageScanRejected: (e) => b.succeed({
|
|
2233
2242
|
kind: "scan",
|
|
2234
2243
|
threat: e.threat
|
|
2235
2244
|
}),
|
|
2236
|
-
StorageError: (e) =>
|
|
2245
|
+
StorageError: (e) => b.succeed({
|
|
2237
2246
|
kind: "error",
|
|
2238
2247
|
message: e.message
|
|
2239
2248
|
})
|
|
@@ -2270,7 +2279,7 @@ var Wt = () => se({
|
|
|
2270
2279
|
path: "/_voltro/storage/upload/resumable",
|
|
2271
2280
|
originGuard: "exempt",
|
|
2272
2281
|
handle: async (e) => {
|
|
2273
|
-
let t = rn(e.headers.origin,
|
|
2282
|
+
let t = rn(e.headers.origin, C);
|
|
2274
2283
|
if (e.method === "OPTIONS") return {
|
|
2275
2284
|
status: 204,
|
|
2276
2285
|
headers: t
|
|
@@ -2283,10 +2292,10 @@ var Wt = () => se({
|
|
|
2283
2292
|
headers: t
|
|
2284
2293
|
};
|
|
2285
2294
|
if (e.method === "GET" || e.method === "HEAD") {
|
|
2286
|
-
let e = await
|
|
2295
|
+
let e = await b.runPromise(P.resumableStatus({
|
|
2287
2296
|
uploadId: r.id,
|
|
2288
2297
|
tenantId: r.tenant
|
|
2289
|
-
}).pipe(
|
|
2298
|
+
}).pipe(b.match({
|
|
2290
2299
|
onFailure: (e) => ({ error: e.message }),
|
|
2291
2300
|
onSuccess: (e) => e
|
|
2292
2301
|
})));
|
|
@@ -2324,12 +2333,12 @@ var Wt = () => se({
|
|
|
2324
2333
|
contentType: "text/plain",
|
|
2325
2334
|
headers: t
|
|
2326
2335
|
};
|
|
2327
|
-
let a = n.get("final") === "1", o = await
|
|
2336
|
+
let a = n.get("final") === "1", o = await b.runPromise(P.putResumableChunk({
|
|
2328
2337
|
uploadId: r.id,
|
|
2329
2338
|
tenantId: r.tenant,
|
|
2330
2339
|
index: i,
|
|
2331
2340
|
bytes: e.rawBody
|
|
2332
|
-
}).pipe(
|
|
2341
|
+
}).pipe(b.flatMap(() => a ? P.finalizeResumable({
|
|
2333
2342
|
uploadId: r.id,
|
|
2334
2343
|
count: i + 1,
|
|
2335
2344
|
contentType: r.ct,
|
|
@@ -2340,21 +2349,21 @@ var Wt = () => se({
|
|
|
2340
2349
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
2341
2350
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
2342
2351
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
2343
|
-
}).pipe(
|
|
2352
|
+
}).pipe(b.flatMap((e) => P.getUrl(e.id).pipe(b.map((t) => ({
|
|
2344
2353
|
kind: "done",
|
|
2345
2354
|
ref: e,
|
|
2346
2355
|
url: t
|
|
2347
|
-
}))))) :
|
|
2348
|
-
StorageRejected: (e) =>
|
|
2356
|
+
}))))) : b.succeed({ kind: "chunk" })), b.catchTags({
|
|
2357
|
+
StorageRejected: (e) => b.succeed({
|
|
2349
2358
|
kind: "rejected",
|
|
2350
2359
|
status: e.reason === "too-large" ? 413 : 415,
|
|
2351
2360
|
detail: e.detail
|
|
2352
2361
|
}),
|
|
2353
|
-
StorageScanRejected: (e) =>
|
|
2362
|
+
StorageScanRejected: (e) => b.succeed({
|
|
2354
2363
|
kind: "scan",
|
|
2355
2364
|
threat: e.threat
|
|
2356
2365
|
}),
|
|
2357
|
-
StorageError: (e) =>
|
|
2366
|
+
StorageError: (e) => b.succeed({
|
|
2358
2367
|
kind: "error",
|
|
2359
2368
|
message: e.message
|
|
2360
2369
|
})
|
|
@@ -2410,13 +2419,13 @@ var Wt = () => se({
|
|
|
2410
2419
|
method: "GET",
|
|
2411
2420
|
path: "/refs",
|
|
2412
2421
|
description: "Recent storage refs (newest first)",
|
|
2413
|
-
handler: () => M.listRecent(100).pipe(
|
|
2422
|
+
handler: () => M.listRecent(100).pipe(b.map((e) => R({ refs: e.map(an) })), b.catchAll((e) => b.succeed(z(500, e.message))))
|
|
2414
2423
|
},
|
|
2415
2424
|
{
|
|
2416
2425
|
method: "GET",
|
|
2417
2426
|
path: "/stats",
|
|
2418
2427
|
description: "Object count + total bytes per tenant + visibility split",
|
|
2419
|
-
handler: () => M.listRecent(1e4).pipe(
|
|
2428
|
+
handler: () => M.listRecent(1e4).pipe(b.map((e) => {
|
|
2420
2429
|
let t = {}, n = 0, r = 0;
|
|
2421
2430
|
for (let i of e) {
|
|
2422
2431
|
let e = i.tenantId ?? "(global)", a = t[e] ?? {
|
|
@@ -2426,15 +2435,15 @@ var Wt = () => se({
|
|
|
2426
2435
|
a.count++, a.bytes += i.size, t[e] = a, i.visibility === "public" ? n++ : r++;
|
|
2427
2436
|
}
|
|
2428
2437
|
return R({
|
|
2429
|
-
provider:
|
|
2430
|
-
bucket:
|
|
2438
|
+
provider: y.name,
|
|
2439
|
+
bucket: x,
|
|
2431
2440
|
byTenant: t,
|
|
2432
2441
|
visibility: {
|
|
2433
2442
|
public: n,
|
|
2434
2443
|
private: r
|
|
2435
2444
|
}
|
|
2436
2445
|
});
|
|
2437
|
-
}),
|
|
2446
|
+
}), b.catchAll((e) => b.succeed(z(500, e.message))))
|
|
2438
2447
|
},
|
|
2439
2448
|
{
|
|
2440
2449
|
method: "GET",
|
|
@@ -2442,15 +2451,15 @@ var Wt = () => se({
|
|
|
2442
2451
|
description: "Grants for a ref (?refId=…)",
|
|
2443
2452
|
handler: (e) => {
|
|
2444
2453
|
let t = ge(e.url, "refId");
|
|
2445
|
-
return t ? se.listByRef(t).pipe(
|
|
2454
|
+
return t ? se.listByRef(t).pipe(b.map((e) => R({ grants: e.map(cn) })), b.catchAll((e) => b.succeed(z(500, e.message)))) : b.succeed(z(400, "refId query param required"));
|
|
2446
2455
|
}
|
|
2447
2456
|
},
|
|
2448
2457
|
{
|
|
2449
2458
|
method: "POST",
|
|
2450
2459
|
path: "/share",
|
|
2451
2460
|
description: "Grant a principal access to a ref",
|
|
2452
|
-
handler: (e) =>
|
|
2453
|
-
let n = yield*
|
|
2461
|
+
handler: (e) => b.gen(function* () {
|
|
2462
|
+
let n = yield* b.try({
|
|
2454
2463
|
try: () => JSON.parse(e.body || "{}"),
|
|
2455
2464
|
catch: () => new t({
|
|
2456
2465
|
provider: "inspect",
|
|
@@ -2468,14 +2477,14 @@ var Wt = () => se({
|
|
|
2468
2477
|
expiresAt: r
|
|
2469
2478
|
});
|
|
2470
2479
|
return R({ grant: cn(i) });
|
|
2471
|
-
}).pipe(
|
|
2480
|
+
}).pipe(b.catchAll((e) => b.succeed(z(e.status ?? 500, e.message ?? "share failed"))))
|
|
2472
2481
|
},
|
|
2473
2482
|
{
|
|
2474
2483
|
method: "POST",
|
|
2475
2484
|
path: "/revoke",
|
|
2476
2485
|
description: "Revoke a grant by id",
|
|
2477
|
-
handler: (e) =>
|
|
2478
|
-
let n = yield*
|
|
2486
|
+
handler: (e) => b.gen(function* () {
|
|
2487
|
+
let n = yield* b.try({
|
|
2479
2488
|
try: () => JSON.parse(e.body || "{}"),
|
|
2480
2489
|
catch: () => new t({
|
|
2481
2490
|
provider: "inspect",
|
|
@@ -2485,21 +2494,21 @@ var Wt = () => se({
|
|
|
2485
2494
|
})
|
|
2486
2495
|
});
|
|
2487
2496
|
return n.grantId ? (yield* P.revoke(n.grantId), R({ ok: !0 })) : z(400, "grantId required");
|
|
2488
|
-
}).pipe(
|
|
2497
|
+
}).pipe(b.catchAll((e) => b.succeed(z(e.status ?? 500, e.message ?? "revoke failed"))))
|
|
2489
2498
|
}
|
|
2490
2499
|
], _e = [
|
|
2491
2500
|
{
|
|
2492
|
-
...
|
|
2501
|
+
...h,
|
|
2493
2502
|
execute: (e, t) => {
|
|
2494
2503
|
let n = e;
|
|
2495
2504
|
return P.mintUrl(n.id, t.request.subject, {
|
|
2496
2505
|
...n.password === void 0 ? {} : { password: n.password },
|
|
2497
2506
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
2498
|
-
}).pipe(
|
|
2507
|
+
}).pipe(b.map((e) => ({ url: e })));
|
|
2499
2508
|
}
|
|
2500
2509
|
},
|
|
2501
2510
|
{
|
|
2502
|
-
...
|
|
2511
|
+
...ee,
|
|
2503
2512
|
execute: (e, t) => {
|
|
2504
2513
|
let n = e;
|
|
2505
2514
|
return P.mintUploadUrl({
|
|
@@ -2507,14 +2516,14 @@ var Wt = () => se({
|
|
|
2507
2516
|
contentType: n.contentType,
|
|
2508
2517
|
tenantId: t.request.subject.tenantId,
|
|
2509
2518
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
2510
|
-
}).pipe(
|
|
2519
|
+
}).pipe(b.map((e) => ({ url: e })));
|
|
2511
2520
|
}
|
|
2512
2521
|
},
|
|
2513
2522
|
{
|
|
2514
2523
|
...m,
|
|
2515
2524
|
execute: (e, t) => {
|
|
2516
2525
|
let n = e;
|
|
2517
|
-
return
|
|
2526
|
+
return b.sync(() => {
|
|
2518
2527
|
let e = n.expiresInSec ?? 900, r = ct({
|
|
2519
2528
|
sub: t.request.subject.id,
|
|
2520
2529
|
tenant: t.request.subject.tenantId,
|
|
@@ -2525,10 +2534,10 @@ var Wt = () => se({
|
|
|
2525
2534
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
2526
2535
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2527
2536
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2528
|
-
...
|
|
2537
|
+
...w === void 0 ? {} : { max: w }
|
|
2529
2538
|
}, e);
|
|
2530
2539
|
return {
|
|
2531
|
-
uploadUrl: `${
|
|
2540
|
+
uploadUrl: `${S ? S.replace(/\/+$/, "") : ""}/_voltro/storage/upload?ticket=${encodeURIComponent(r)}`,
|
|
2532
2541
|
expiresInSec: e
|
|
2533
2542
|
};
|
|
2534
2543
|
});
|
|
@@ -2542,7 +2551,7 @@ var Wt = () => se({
|
|
|
2542
2551
|
contentType: n.contentType,
|
|
2543
2552
|
tenantId: t.request.subject.tenantId,
|
|
2544
2553
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
2545
|
-
}).pipe(
|
|
2554
|
+
}).pipe(b.map((e) => {
|
|
2546
2555
|
let r = ut({
|
|
2547
2556
|
key: e.key,
|
|
2548
2557
|
sub: t.request.subject.id,
|
|
@@ -2553,7 +2562,7 @@ var Wt = () => se({
|
|
|
2553
2562
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
2554
2563
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2555
2564
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2556
|
-
...
|
|
2565
|
+
...w === void 0 ? {} : { max: w }
|
|
2557
2566
|
}, e.expiresInSec);
|
|
2558
2567
|
return {
|
|
2559
2568
|
uploadUrl: e.uploadUrl,
|
|
@@ -2567,7 +2576,7 @@ var Wt = () => se({
|
|
|
2567
2576
|
...l,
|
|
2568
2577
|
execute: (e, n) => {
|
|
2569
2578
|
let r = dt(e.finalizeToken);
|
|
2570
|
-
return r ? r.sub !== null && r.sub !== n.request.subject.id ?
|
|
2579
|
+
return r ? r.sub !== null && r.sub !== n.request.subject.id ? b.fail(new t({
|
|
2571
2580
|
provider: "storage",
|
|
2572
2581
|
message: "finalize token belongs to another subject",
|
|
2573
2582
|
transient: !1,
|
|
@@ -2582,14 +2591,14 @@ var Wt = () => se({
|
|
|
2582
2591
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
2583
2592
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
2584
2593
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
2585
|
-
}).pipe(
|
|
2594
|
+
}).pipe(b.flatMap((e) => P.getUrl(e.id).pipe(b.map((t) => ({
|
|
2586
2595
|
id: e.id,
|
|
2587
2596
|
url: t,
|
|
2588
2597
|
contentType: e.contentType,
|
|
2589
2598
|
size: e.size,
|
|
2590
2599
|
...e.width == null ? {} : { width: e.width },
|
|
2591
2600
|
...e.height == null ? {} : { height: e.height }
|
|
2592
|
-
}))))) :
|
|
2601
|
+
}))))) : b.fail(new t({
|
|
2593
2602
|
provider: "storage",
|
|
2594
2603
|
message: "invalid or expired finalize token",
|
|
2595
2604
|
transient: !1,
|
|
@@ -2601,7 +2610,7 @@ var Wt = () => se({
|
|
|
2601
2610
|
...s,
|
|
2602
2611
|
execute: (e, t) => {
|
|
2603
2612
|
let n = e;
|
|
2604
|
-
return
|
|
2613
|
+
return b.sync(() => {
|
|
2605
2614
|
let e = n.expiresInSec ?? oe, r = de(), i = n.chunkSize && n.chunkSize > 0 ? n.chunkSize : D;
|
|
2606
2615
|
return {
|
|
2607
2616
|
uploadId: r,
|
|
@@ -2616,9 +2625,9 @@ var Wt = () => se({
|
|
|
2616
2625
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
2617
2626
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2618
2627
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2619
|
-
...
|
|
2628
|
+
...w === void 0 ? {} : { max: w }
|
|
2620
2629
|
}, e),
|
|
2621
|
-
uploadUrl: `${
|
|
2630
|
+
uploadUrl: `${S ? S.replace(/\/+$/, "") : ""}/_voltro/storage/upload/resumable`,
|
|
2622
2631
|
chunkSize: i,
|
|
2623
2632
|
expiresInSec: e
|
|
2624
2633
|
};
|
|
@@ -2634,7 +2643,7 @@ var Wt = () => se({
|
|
|
2634
2643
|
tenantId: t.request.subject.tenantId,
|
|
2635
2644
|
visibility: n.visibility ?? "private",
|
|
2636
2645
|
expiresInSec: r
|
|
2637
|
-
}).pipe(
|
|
2646
|
+
}).pipe(b.map((e) => ({
|
|
2638
2647
|
multipartToken: mt({
|
|
2639
2648
|
key: e.key,
|
|
2640
2649
|
uploadId: e.uploadId,
|
|
@@ -2657,7 +2666,7 @@ var Wt = () => se({
|
|
|
2657
2666
|
...te,
|
|
2658
2667
|
execute: (e) => {
|
|
2659
2668
|
let n = e, r = ht(n.multipartToken);
|
|
2660
|
-
return r ? !Number.isInteger(n.partNumber) || n.partNumber < 1 ?
|
|
2669
|
+
return r ? !Number.isInteger(n.partNumber) || n.partNumber < 1 ? b.fail(new t({
|
|
2661
2670
|
provider: "storage",
|
|
2662
2671
|
message: "partNumber must be a positive integer",
|
|
2663
2672
|
transient: !1,
|
|
@@ -2666,7 +2675,7 @@ var Wt = () => se({
|
|
|
2666
2675
|
key: r.key,
|
|
2667
2676
|
uploadId: r.uploadId,
|
|
2668
2677
|
partNumber: n.partNumber
|
|
2669
|
-
}).pipe(
|
|
2678
|
+
}).pipe(b.map((e) => ({ url: e }))) : b.fail(new t({
|
|
2670
2679
|
provider: "storage",
|
|
2671
2680
|
message: "invalid or expired multipart token",
|
|
2672
2681
|
transient: !1,
|
|
@@ -2678,7 +2687,7 @@ var Wt = () => se({
|
|
|
2678
2687
|
...c,
|
|
2679
2688
|
execute: (e, n) => {
|
|
2680
2689
|
let r = e, i = ht(r.multipartToken);
|
|
2681
|
-
return i ? i.sub !== null && i.sub !== n.request.subject.id ?
|
|
2690
|
+
return i ? i.sub !== null && i.sub !== n.request.subject.id ? b.fail(new t({
|
|
2682
2691
|
provider: "storage",
|
|
2683
2692
|
message: "multipart token belongs to another subject",
|
|
2684
2693
|
transient: !1,
|
|
@@ -2695,11 +2704,11 @@ var Wt = () => se({
|
|
|
2695
2704
|
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
2696
2705
|
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
2697
2706
|
...i.caption === void 0 ? {} : { caption: i.caption }
|
|
2698
|
-
}).pipe(
|
|
2707
|
+
}).pipe(b.flatMap((e) => P.getUrl(e.id).pipe(b.map((t) => ({
|
|
2699
2708
|
id: e.id,
|
|
2700
2709
|
url: t,
|
|
2701
2710
|
size: e.size
|
|
2702
|
-
}))))) :
|
|
2711
|
+
}))))) : b.fail(new t({
|
|
2703
2712
|
provider: "storage",
|
|
2704
2713
|
message: "invalid or expired multipart token",
|
|
2705
2714
|
transient: !1,
|
|
@@ -2714,7 +2723,7 @@ var Wt = () => se({
|
|
|
2714
2723
|
return n ? P.abortMultipart({
|
|
2715
2724
|
key: n.key,
|
|
2716
2725
|
uploadId: n.uploadId
|
|
2717
|
-
}).pipe(
|
|
2726
|
+
}).pipe(b.as({ ok: !0 })) : b.fail(new t({
|
|
2718
2727
|
provider: "storage",
|
|
2719
2728
|
message: "invalid or expired multipart token",
|
|
2720
2729
|
transient: !1,
|
|
@@ -2723,7 +2732,7 @@ var Wt = () => se({
|
|
|
2723
2732
|
}
|
|
2724
2733
|
},
|
|
2725
2734
|
{
|
|
2726
|
-
...
|
|
2735
|
+
...v,
|
|
2727
2736
|
execute: (e, t) => {
|
|
2728
2737
|
let n = e, r = new Uint8Array(Buffer.from(n.bytesBase64, "base64"));
|
|
2729
2738
|
return P.put({
|
|
@@ -2734,7 +2743,7 @@ var Wt = () => se({
|
|
|
2734
2743
|
...n.visibility ? { visibility: n.visibility } : {},
|
|
2735
2744
|
...n.key ? { key: n.key } : {},
|
|
2736
2745
|
...n.password ? { password: n.password } : {}
|
|
2737
|
-
}).pipe(
|
|
2746
|
+
}).pipe(b.flatMap((e) => P.getUrl(e.id).pipe(b.map((t) => ({
|
|
2738
2747
|
id: e.id,
|
|
2739
2748
|
url: t
|
|
2740
2749
|
})))));
|
|
@@ -2753,38 +2762,38 @@ var Wt = () => se({
|
|
|
2753
2762
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2754
2763
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2755
2764
|
...n.key === void 0 ? {} : { key: n.key }
|
|
2756
|
-
}).pipe(
|
|
2765
|
+
}).pipe(b.flatMap((e) => P.getUrl(e.id).pipe(b.map((t) => ({
|
|
2757
2766
|
id: e.id,
|
|
2758
2767
|
url: t
|
|
2759
2768
|
})))));
|
|
2760
2769
|
}
|
|
2761
2770
|
},
|
|
2762
2771
|
{
|
|
2763
|
-
...
|
|
2772
|
+
..._,
|
|
2764
2773
|
execute: (e, t) => {
|
|
2765
2774
|
let n = e, r = n.expiresInDays ? new Date(Date.now() + n.expiresInDays * 864e5) : null;
|
|
2766
|
-
return sn(P, n.refId, t).pipe(
|
|
2775
|
+
return sn(P, n.refId, t).pipe(b.flatMap(() => P.grant({
|
|
2767
2776
|
refId: n.refId,
|
|
2768
2777
|
principalType: n.principalType,
|
|
2769
2778
|
principalId: n.principalId,
|
|
2770
2779
|
...n.permission ? { permission: n.permission } : {},
|
|
2771
2780
|
expiresAt: r,
|
|
2772
2781
|
createdBy: t.request.subject.id
|
|
2773
|
-
})),
|
|
2782
|
+
})), b.map((e) => ({ grantId: e.id })));
|
|
2774
2783
|
}
|
|
2775
2784
|
},
|
|
2776
2785
|
{
|
|
2777
|
-
...
|
|
2786
|
+
...g,
|
|
2778
2787
|
execute: (e, t) => {
|
|
2779
2788
|
let n = e;
|
|
2780
|
-
return P.getGrant(n.grantId).pipe(
|
|
2789
|
+
return P.getGrant(n.grantId).pipe(b.flatMap((e) => e === null ? b.fail(on()) : sn(P, e.refId, t)), b.flatMap(() => P.revoke(n.grantId)), b.map(() => ({ ok: !0 })));
|
|
2781
2790
|
}
|
|
2782
2791
|
},
|
|
2783
2792
|
{
|
|
2784
2793
|
...d,
|
|
2785
2794
|
execute: (e, t) => {
|
|
2786
2795
|
let n = e;
|
|
2787
|
-
return sn(P, n.refId, t).pipe(
|
|
2796
|
+
return sn(P, n.refId, t).pipe(b.flatMap(() => P.listGrants(n.refId)), b.map((e) => ({ grants: e.map(cn) })));
|
|
2788
2797
|
}
|
|
2789
2798
|
},
|
|
2790
2799
|
{
|
|
@@ -2799,15 +2808,15 @@ var Wt = () => se({
|
|
|
2799
2808
|
...n.includeDerived === void 0 ? {} : { includeDerived: n.includeDerived },
|
|
2800
2809
|
...n.limit === void 0 ? {} : { limit: n.limit },
|
|
2801
2810
|
...n.offset === void 0 ? {} : { offset: n.offset }
|
|
2802
|
-
}).pipe(
|
|
2811
|
+
}).pipe(b.map((e) => ({
|
|
2803
2812
|
refs: e.refs.map(an),
|
|
2804
2813
|
nextOffset: e.nextOffset
|
|
2805
2814
|
})));
|
|
2806
2815
|
}
|
|
2807
2816
|
}
|
|
2808
2817
|
];
|
|
2809
|
-
return
|
|
2810
|
-
name:
|
|
2818
|
+
return T({
|
|
2819
|
+
name: re({
|
|
2811
2820
|
base: ln,
|
|
2812
2821
|
alias: i.alias,
|
|
2813
2822
|
instance: i.name
|
|
@@ -2819,7 +2828,7 @@ var Wt = () => se({
|
|
|
2819
2828
|
"inspect:read",
|
|
2820
2829
|
"inspect:write"
|
|
2821
2830
|
],
|
|
2822
|
-
declaredEnv:
|
|
2831
|
+
declaredEnv: K.declared,
|
|
2823
2832
|
services: N,
|
|
2824
2833
|
inspectEndpoints: B,
|
|
2825
2834
|
httpRoutes: [
|
|
@@ -2828,7 +2837,7 @@ var Wt = () => se({
|
|
|
2828
2837
|
he
|
|
2829
2838
|
],
|
|
2830
2839
|
routes: _e,
|
|
2831
|
-
rpcClientDescriptors:
|
|
2840
|
+
rpcClientDescriptors: ne,
|
|
2832
2841
|
errorSchemas: [
|
|
2833
2842
|
{
|
|
2834
2843
|
schema: t,
|
|
@@ -2860,18 +2869,18 @@ var Wt = () => se({
|
|
|
2860
2869
|
}
|
|
2861
2870
|
],
|
|
2862
2871
|
bindDataStore: (e) => {
|
|
2863
|
-
O && (A.current = kt(e)), k && (j.current = Mt(e)),
|
|
2872
|
+
O && (A.current = kt(e)), k && (j.current = Mt(e)), y.bindDataStore?.(e);
|
|
2864
2873
|
},
|
|
2865
|
-
onActivate: (e) =>
|
|
2866
|
-
let t = !!
|
|
2867
|
-
e.logger.info(`storage: provider=${
|
|
2868
|
-
provider:
|
|
2869
|
-
bucket:
|
|
2874
|
+
onActivate: (e) => b.sync(() => {
|
|
2875
|
+
let t = !!S || !!K.read("STORAGE_CDN_URL", i.cdnBaseUrl);
|
|
2876
|
+
e.logger.info(`storage: provider=${y.name} presign=${y.presigns ? "yes" : "no"} publicUrl=${t ? "yes" : "no"} transforms=yes`, {
|
|
2877
|
+
provider: y.name,
|
|
2878
|
+
bucket: x,
|
|
2870
2879
|
refStore: O ? "memory" : "custom"
|
|
2871
|
-
}),
|
|
2880
|
+
}), 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.");
|
|
2872
2881
|
}),
|
|
2873
|
-
onDeactivate: () =>
|
|
2882
|
+
onDeactivate: () => b.void
|
|
2874
2883
|
});
|
|
2875
2884
|
};
|
|
2876
2885
|
//#endregion
|
|
2877
|
-
export {
|
|
2886
|
+
export { W as STORAGE_BLOBS_TABLE, U as STORAGE_GRANTS_TABLE, H as STORAGE_REFS_TABLE, G as STORAGE_USAGE_TABLE, e as StorageAccessDenied, t as StorageError, n as StorageRejected, r as StorageScanRejected, i as StorageService, ke as _voltroStorageBlobsTable, De as _voltroStorageGrantsTable, Ee as _voltroStorageRefsTable, Oe as _voltroStorageUsageTable, $t as appStorageProvider, Ut as assetRef, ze as azureProvider, Ft as buildStorageService, xe as bytesToStream, yt as checkLimits, Bt as clamavScanner, Ne as clearStorageBuffer, Se as collectStream, be as concatBytes, en as configuredStorageProvider, gt as contentTypeAllowed, Mt as dataStoreGrantStore, kt as dataStoreRefStore, Re as databaseProvider, Kt as decodeDataUri, Yt as durabilityNotice, Lt as encodeInstream, Ht as ffmpegTranscoder, Fe as filesystemProvider, Ce as fromNodeReadable, we as getObjectStream, qe as hashPassword, At as memoryGrantStore, Pe as memoryProvider, Tt as memoryRefStore, Rt as parseClamavResponse, Ve as parseTransformParams, Jt as pathDurability, qt as putAvatar, Te as putObjectStream, Me as readStorageBuffer, Ct as refMatchesListQuery, tn as resolveStorageProvider, X as resolveStorageSecret, Ie as s3Provider, Qt as setActiveStorageProvider, ut as signFinalizeTicket, ot as signGrant, mt as signMultipartTicket, ft as signResumableTicket, ct as signUploadTicket, vt as sniffMatches, un as storagePlugin, It as storageServiceLayer, V as toNodeReadable, Ke as transformCached, We as transformImage, dt as verifyFinalizeTicket, st as verifyGrant, ht as verifyMultipartTicket, Je as verifyPassword, pt as verifyResumableTicket, lt as verifyUploadTicket, Wt as withStorage };
|