@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/CHANGELOG.md +1341 -111
- package/dist/index.d.ts +76 -2
- package/dist/index.js +870 -678
- package/dist/types.d.ts +16 -2
- package/package.json +4 -4
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
|
|
3
|
-
import { Chunk as
|
|
4
|
-
import { definePlugin as
|
|
5
|
-
import { readCookie as
|
|
6
|
-
import { and as
|
|
7
|
-
import { pluginEnv as
|
|
8
|
-
import { createHmac as
|
|
9
|
-
import { spawn as
|
|
10
|
-
import { mkdtemp as
|
|
11
|
-
import { tmpdir as
|
|
12
|
-
import { join as
|
|
13
|
-
import { statSync 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 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
|
|
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
|
-
}),
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
33
|
-
stream:
|
|
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
|
-
}))),
|
|
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
|
-
}))),
|
|
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:
|
|
42
|
-
ownerId:
|
|
43
|
-
bucket:
|
|
44
|
-
key:
|
|
45
|
-
contentType:
|
|
41
|
+
tenantId: I().nullable(),
|
|
42
|
+
ownerId: I().nullable(),
|
|
43
|
+
bucket: I(),
|
|
44
|
+
key: I(),
|
|
45
|
+
contentType: I(),
|
|
46
46
|
size: j(),
|
|
47
|
-
checksum:
|
|
48
|
-
visibility:
|
|
47
|
+
checksum: I(),
|
|
48
|
+
visibility: I(),
|
|
49
49
|
accessPolicy: M().nullable(),
|
|
50
|
-
passwordHash:
|
|
50
|
+
passwordHash: I().nullable(),
|
|
51
51
|
width: j().nullable(),
|
|
52
52
|
height: j().nullable(),
|
|
53
53
|
duration: j().nullable(),
|
|
54
|
-
placeholder:
|
|
55
|
-
folder:
|
|
54
|
+
placeholder: I().nullable(),
|
|
55
|
+
folder: I().nullable(),
|
|
56
56
|
tags: M().nullable(),
|
|
57
|
-
alt:
|
|
58
|
-
caption:
|
|
59
|
-
derivedFrom:
|
|
60
|
-
kind:
|
|
61
|
-
createdAt:
|
|
62
|
-
}).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]),
|
|
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:
|
|
65
|
-
principalType:
|
|
66
|
-
principalId:
|
|
67
|
-
permission:
|
|
68
|
-
createdAt:
|
|
69
|
-
expiresAt:
|
|
70
|
-
createdBy:
|
|
71
|
-
}).index(["refId"]).index(["principalId"]),
|
|
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:
|
|
73
|
+
tenantId: I().maxLength(191),
|
|
74
74
|
bytes: j().default(0),
|
|
75
75
|
count: j().default(0),
|
|
76
|
-
updatedAt:
|
|
77
|
-
}).unique("byStorageUsageTenant", ["tenantId"]),
|
|
76
|
+
updatedAt: ue()
|
|
77
|
+
}).unique("byStorageUsageTenant", ["tenantId"]), Me = F(G, {
|
|
78
78
|
id: A({ prefix: "blob" }),
|
|
79
|
-
key:
|
|
80
|
-
data:
|
|
81
|
-
contentType:
|
|
79
|
+
key: I(),
|
|
80
|
+
data: ce(),
|
|
81
|
+
contentType: I(),
|
|
82
82
|
size: j()
|
|
83
|
-
}).index(["key"]),
|
|
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
|
-
]),
|
|
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
|
-
}),
|
|
240
|
-
|
|
241
|
-
},
|
|
242
|
-
let t =
|
|
243
|
-
return
|
|
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) =>
|
|
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) =>
|
|
250
|
+
get: (e) => y.suspend(() => {
|
|
251
251
|
let n = t.get(e);
|
|
252
|
-
return n ?
|
|
252
|
+
return n ? y.succeed({
|
|
253
253
|
bytes: n.bytes,
|
|
254
254
|
contentType: n.contentType
|
|
255
|
-
}) :
|
|
255
|
+
}) : y.fail(q("memory", `no object at key '${e}'`, !1, 404));
|
|
256
256
|
}),
|
|
257
|
-
delete: (e) =>
|
|
257
|
+
delete: (e) => y.sync(() => {
|
|
258
258
|
t.delete(e);
|
|
259
259
|
}),
|
|
260
260
|
publicUrl: () => null,
|
|
261
|
-
getUrl: () =>
|
|
262
|
-
head: (e) =>
|
|
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
|
-
},
|
|
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) =>
|
|
272
|
+
}, r = (e, t, n = !1) => y.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 _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: () =>
|
|
303
|
-
head: (e) =>
|
|
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) =>
|
|
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:
|
|
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
|
|
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
|
-
}),
|
|
343
|
+
}), xe(o);
|
|
344
344
|
}, e)
|
|
345
345
|
};
|
|
346
|
-
},
|
|
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) =>
|
|
367
|
+
})(), r), a = (e) => y.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), 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) =>
|
|
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
|
|
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:
|
|
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
|
|
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
|
-
},
|
|
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) =>
|
|
535
|
+
}, n = (e) => y.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: 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(
|
|
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(
|
|
562
|
+
}) : await t().insert(G, {
|
|
563
563
|
id: k({
|
|
564
564
|
kind: "typeid",
|
|
565
565
|
prefix: "blob"
|
|
566
|
-
},
|
|
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) =>
|
|
574
|
-
bytes:
|
|
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
|
-
}) :
|
|
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(
|
|
579
|
+
n && await t().delete(G, String(n.id));
|
|
580
580
|
}),
|
|
581
581
|
publicUrl: () => null,
|
|
582
|
-
getUrl: () =>
|
|
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
|
-
},
|
|
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 =
|
|
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) => y.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), 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) =>
|
|
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
|
|
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:
|
|
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
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
706
|
-
if (
|
|
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
|
-
|
|
709
|
+
J = e.default ?? e;
|
|
710
710
|
} catch {
|
|
711
|
-
|
|
711
|
+
J = null;
|
|
712
712
|
}
|
|
713
|
-
return
|
|
714
|
-
},
|
|
715
|
-
if (!
|
|
716
|
-
let r = await
|
|
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 &&
|
|
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 =
|
|
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
|
-
},
|
|
740
|
-
let i = `${e}::${JSON.stringify(r)}`, a =
|
|
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
|
|
743
|
-
if (o && (
|
|
744
|
-
let e =
|
|
745
|
-
e !== void 0 &&
|
|
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
|
-
},
|
|
749
|
-
let t =
|
|
750
|
-
return `${t}:${
|
|
751
|
-
},
|
|
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 =
|
|
756
|
-
return a.length === i.length &&
|
|
757
|
-
},
|
|
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*
|
|
762
|
-
for (let a of r) if (yield*
|
|
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
|
-
}),
|
|
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(
|
|
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*
|
|
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
|
-
}),
|
|
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
|
-
},
|
|
787
|
-
let a =
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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(
|
|
799
|
-
},
|
|
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 =
|
|
804
|
-
if (o.length !== a.length || !
|
|
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
|
-
},
|
|
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(
|
|
818
|
-
},
|
|
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 =
|
|
823
|
-
if (o.length !== a.length || !
|
|
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
|
-
},
|
|
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(
|
|
837
|
-
},
|
|
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 =
|
|
842
|
-
if (o.length !== a.length || !
|
|
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
|
-
},
|
|
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(
|
|
856
|
-
},
|
|
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 =
|
|
861
|
-
if (o.length !== a.length || !
|
|
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
|
-
},
|
|
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(
|
|
875
|
-
},
|
|
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 =
|
|
880
|
-
if (o.length !== a.length || !
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
],
|
|
965
|
-
let n = t.toLowerCase(), r =
|
|
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
|
-
},
|
|
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
|
-
} :
|
|
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,
|
|
977
|
-
if (!
|
|
978
|
-
let r = await
|
|
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
|
-
},
|
|
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
|
-
},
|
|
1005
|
-
|
|
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
|
-
},
|
|
1094
|
+
}, Nt = (e) => e ?? "global", Pt = () => {
|
|
1016
1095
|
let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
|
|
1017
1096
|
return {
|
|
1018
|
-
|
|
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) =>
|
|
1022
|
-
delete: (t) =>
|
|
1023
|
-
listRecent: (t) =>
|
|
1024
|
-
countByKey: (t, n) =>
|
|
1025
|
-
usageByTenant: (t) =>
|
|
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) =>
|
|
1034
|
-
let 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) =>
|
|
1048
|
-
let 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) =>
|
|
1055
|
-
listRefs: (t) =>
|
|
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
|
-
},
|
|
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:
|
|
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) =>
|
|
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
|
-
}),
|
|
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,
|
|
1099
|
-
|
|
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:
|
|
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] ?
|
|
1222
|
+
return n[0] ? It(n[0]) : null;
|
|
1114
1223
|
}),
|
|
1115
|
-
delete: (t) => Q(() => e.delete(
|
|
1224
|
+
delete: (t) => Q(() => e.delete(U, t)),
|
|
1116
1225
|
listRecent: (t) => Q(async () => (await e.query({
|
|
1117
|
-
table:
|
|
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(
|
|
1235
|
+
})).map(It)),
|
|
1127
1236
|
countByKey: (t, n) => Q(async () => (await e.query({
|
|
1128
|
-
table:
|
|
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:
|
|
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 =
|
|
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
|
|
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:
|
|
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
|
-
},
|
|
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 =
|
|
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
|
|
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:
|
|
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:
|
|
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(
|
|
1340
|
+
})).map(It)),
|
|
1232
1341
|
listRefs: (t) => Q(async () => {
|
|
1233
1342
|
let n = [];
|
|
1234
|
-
t.tenantId !== void 0 && n.push(
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
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
|
-
})
|
|
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
|
-
}),
|
|
1366
|
+
}), zt = () => {
|
|
1257
1367
|
let e = /* @__PURE__ */ new Map();
|
|
1258
1368
|
return {
|
|
1259
|
-
insert: (t) =>
|
|
1369
|
+
insert: (t) => y.sync(() => {
|
|
1260
1370
|
e.set(t.id, t);
|
|
1261
1371
|
}),
|
|
1262
|
-
delete: (t) =>
|
|
1372
|
+
delete: (t) => y.sync(() => {
|
|
1263
1373
|
e.delete(t);
|
|
1264
1374
|
}),
|
|
1265
|
-
getById: (t) =>
|
|
1266
|
-
listByRef: (t) =>
|
|
1267
|
-
deleteByRef: (t) =>
|
|
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
|
-
},
|
|
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
|
-
}),
|
|
1281
|
-
insert: (t) => Q(() => e.insert(
|
|
1282
|
-
delete: (t) => Q(() => e.delete(
|
|
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:
|
|
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 ?
|
|
1406
|
+
return n ? Bt(n) : null;
|
|
1297
1407
|
}),
|
|
1298
1408
|
listByRef: (t) => Q(async () => (await e.query({
|
|
1299
|
-
table:
|
|
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(
|
|
1422
|
+
})).map(Bt)),
|
|
1313
1423
|
deleteByRef: (t) => Q(async () => {
|
|
1314
1424
|
let n = await e.query({
|
|
1315
|
-
table:
|
|
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(
|
|
1436
|
+
for (let t of n) await e.delete(W, String(t.id));
|
|
1327
1437
|
})
|
|
1328
|
-
}),
|
|
1438
|
+
}), Ht = () => k({
|
|
1329
1439
|
kind: "typeid",
|
|
1330
1440
|
prefix: "file"
|
|
1331
|
-
},
|
|
1441
|
+
}, U), Ut = () => k({
|
|
1332
1442
|
kind: "typeid",
|
|
1333
1443
|
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) =>
|
|
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
|
|
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 ?
|
|
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("/"),
|
|
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
|
-
})) :
|
|
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
|
-
})))),
|
|
1474
|
+
})))), ne = (e) => y.suspend(() => {
|
|
1365
1475
|
let n = i.scan(e);
|
|
1366
|
-
return
|
|
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
|
-
}),
|
|
1484
|
+
}), re = (e) => y.suspend(() => {
|
|
1375
1485
|
let t = e.contentType;
|
|
1376
|
-
if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return
|
|
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
|
|
1491
|
+
return y.succeed(null);
|
|
1382
1492
|
}
|
|
1383
|
-
return
|
|
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(
|
|
1387
|
-
}),
|
|
1388
|
-
let t =
|
|
1389
|
-
if (t) return yield*
|
|
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*
|
|
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*
|
|
1506
|
+
if (!t.clean) return yield* y.fail(new r({ threat: t.threat ?? "unknown" }));
|
|
1397
1507
|
}
|
|
1398
|
-
let s = yield*
|
|
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,
|
|
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
|
-
},
|
|
1405
|
-
if (!
|
|
1406
|
-
let e = i.quota ?? {}, t = e.maxCount !== void 0 &&
|
|
1407
|
-
return yield*
|
|
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
|
|
1413
|
-
id:
|
|
1414
|
-
tenantId:
|
|
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:
|
|
1527
|
+
key: S,
|
|
1418
1528
|
contentType: e.contentType,
|
|
1419
1529
|
size: l.byteLength,
|
|
1420
|
-
checksum:
|
|
1421
|
-
visibility:
|
|
1530
|
+
checksum: g,
|
|
1531
|
+
visibility: v,
|
|
1422
1532
|
accessPolicy: e.access ?? null,
|
|
1423
|
-
passwordHash:
|
|
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
|
-
...
|
|
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(
|
|
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:
|
|
1439
|
-
}).pipe(
|
|
1440
|
-
}),
|
|
1441
|
-
if (!i.transcode) return
|
|
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
|
|
1556
|
+
return y.succeed([]);
|
|
1447
1557
|
}
|
|
1448
|
-
return
|
|
1558
|
+
return y.isEffect(t) ? t.pipe(y.catchAll(() => y.succeed([]))) : y.tryPromise({
|
|
1449
1559
|
try: () => Promise.resolve(t),
|
|
1450
1560
|
catch: () => []
|
|
1451
|
-
}).pipe(
|
|
1452
|
-
}),
|
|
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(
|
|
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*
|
|
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
|
-
}),
|
|
1474
|
-
if (e.visibility === "public" || (yield*
|
|
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*
|
|
1479
|
-
return
|
|
1480
|
-
}),
|
|
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:
|
|
1489
|
-
get: (e, 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
|
-
|
|
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
|
|
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 ?
|
|
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(
|
|
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) =>
|
|
1514
|
-
head: (e, t) => o.getById(e).pipe(
|
|
1515
|
-
delete: (e, t) =>
|
|
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
|
-
}))) :
|
|
1519
|
-
mintUrl: (n, r, i) =>
|
|
1520
|
-
let s = yield* o.getById(n).pipe(
|
|
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
|
|
1527
|
-
if (!(yield*
|
|
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*
|
|
1647
|
+
let l = yield* y.sync(() => ut(s.id, c));
|
|
1534
1648
|
return `${f(s.id)}?t=${l}`;
|
|
1535
1649
|
}),
|
|
1536
|
-
mintUploadUrl: (e) =>
|
|
1537
|
-
if (!a.getUploadUrl) return yield*
|
|
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:
|
|
1547
|
-
grant: (e) =>
|
|
1660
|
+
checkAccess: C,
|
|
1661
|
+
grant: (e) => y.gen(function* () {
|
|
1548
1662
|
let t = {
|
|
1549
|
-
id:
|
|
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) =>
|
|
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(
|
|
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) =>
|
|
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)
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
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,
|
|
1594
|
-
let
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
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) =>
|
|
1630
|
-
if (!a.getUploadUrl) return yield*
|
|
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
|
-
},
|
|
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(
|
|
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
|
-
})),
|
|
1657
|
-
putResumableChunk: (e) => a.put(h(e.tenantId ?? null, e.uploadId, e.index), e.bytes, { contentType: "application/octet-stream" }).pipe(
|
|
1658
|
-
resumableStatus: (e) =>
|
|
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(
|
|
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) =>
|
|
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(
|
|
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 =
|
|
1679
|
-
return yield*
|
|
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(
|
|
1788
|
+
}).pipe(y.ensuring(o));
|
|
1690
1789
|
}),
|
|
1691
|
-
transcode: (e, t) =>
|
|
1692
|
-
renditions: (e, t) =>
|
|
1693
|
-
beginMultipartUpload: (e) =>
|
|
1694
|
-
if (!a.createMultipartUpload || !a.presignUploadPart || !a.completeMultipartUpload) return yield*
|
|
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
|
-
},
|
|
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) =>
|
|
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) =>
|
|
1716
|
-
if (!a.completeMultipartUpload) return yield*
|
|
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(
|
|
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(
|
|
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:
|
|
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(
|
|
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) =>
|
|
1849
|
+
abortMultipart: (e) => y.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(y.retry(p)) : y.void)
|
|
1751
1850
|
};
|
|
1752
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
1770
|
-
let n = await import("node:net"), r =
|
|
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(
|
|
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(
|
|
1886
|
+
i(qt(l));
|
|
1788
1887
|
} catch (e) {
|
|
1789
1888
|
s(e);
|
|
1790
1889
|
}
|
|
1791
1890
|
});
|
|
1792
1891
|
});
|
|
1793
|
-
},
|
|
1794
|
-
let a =
|
|
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
|
-
}),
|
|
1809
|
-
let n = e.ffmpegPath ?? "ffmpeg", r = e.timeoutMs ?? 3e5, i = await
|
|
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
|
|
1910
|
+
await _e(a, t);
|
|
1812
1911
|
for (let t of e.renditions) {
|
|
1813
|
-
let e =
|
|
1912
|
+
let e = V(i, `out.${t.ext}`);
|
|
1814
1913
|
try {
|
|
1815
|
-
await
|
|
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
|
|
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
|
|
1927
|
+
}), await ge(e, { force: !0 });
|
|
1829
1928
|
} catch {}
|
|
1830
1929
|
}
|
|
1831
1930
|
} finally {
|
|
1832
|
-
await
|
|
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
|
|
1842
|
-
let t = e.nullable ?? !0, n = e.fk === !1 ?
|
|
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
|
|
1944
|
+
var $t = () => N({
|
|
1846
1945
|
id: "@voltro/plugin-storage/withStorage",
|
|
1847
|
-
fields: { asset:
|
|
1848
|
-
}),
|
|
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
|
-
},
|
|
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
|
-
},
|
|
1864
|
-
let r = yield*
|
|
1865
|
-
try: () =>
|
|
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 =
|
|
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
|
-
}),
|
|
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 =
|
|
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
|
-
},
|
|
1889
|
-
if (
|
|
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
|
-
},
|
|
1893
|
-
|
|
1894
|
-
},
|
|
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 ??
|
|
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 =
|
|
1901
|
-
return
|
|
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" ||
|
|
2025
|
+
...t === "minio" || K.read("S3_FORCE_PATH_STYLE") === "1" ? { forcePathStyle: !0 } : {}
|
|
1911
2026
|
});
|
|
1912
2027
|
}
|
|
1913
2028
|
case "azure": {
|
|
1914
|
-
let t =
|
|
1915
|
-
return
|
|
1916
|
-
container:
|
|
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
|
|
1925
|
-
case "filesystem": return
|
|
1926
|
-
default: return
|
|
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
|
-
},
|
|
2043
|
+
}, pn = (e) => {
|
|
1929
2044
|
if (e !== void 0) return e;
|
|
1930
|
-
let t =
|
|
2045
|
+
let t = K.read("STORAGE_ALLOWED_ORIGINS");
|
|
1931
2046
|
return t ? t.trim() === "*" ? "*" : t.split(",").map((e) => e.trim()).filter(Boolean) : [];
|
|
1932
|
-
},
|
|
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
|
-
},
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
2085
|
+
}), _n = (e, t, n) => {
|
|
1971
2086
|
let r = n.request.subject;
|
|
1972
|
-
return (r.scopes ?? []).includes("admin:full") ?
|
|
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 ?
|
|
2089
|
+
return t != null && t === r.id ? y.void : y.fail(gn());
|
|
1975
2090
|
}));
|
|
1976
|
-
},
|
|
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 ?
|
|
2098
|
+
return n === null && !t ? y.fail(vn()) : y.succeed({
|
|
1984
2099
|
id: n,
|
|
1985
2100
|
tenantId: r
|
|
1986
2101
|
});
|
|
1987
|
-
},
|
|
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
|
-
}),
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
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
|
-
...
|
|
2155
|
+
...E ? { publicBaseUrl: E } : {},
|
|
2031
2156
|
...i.normalizeImages === void 0 ? {} : { normalizeImages: i.normalizeImages },
|
|
2032
2157
|
...i.quota === void 0 ? {} : { quota: i.quota }
|
|
2033
|
-
},
|
|
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
|
-
},
|
|
2179
|
+
}, B = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, pe = (e) => ({
|
|
2055
2180
|
"x-content-type-options": "nosniff",
|
|
2056
|
-
"content-disposition":
|
|
2057
|
-
}),
|
|
2181
|
+
"content-disposition": B.test(e) ? "inline" : "attachment"
|
|
2182
|
+
}), me = async (e, t, n, r) => {
|
|
2058
2183
|
if (n) {
|
|
2059
|
-
let r = await
|
|
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
|
|
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
|
-
...
|
|
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" :
|
|
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
|
|
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
|
-
...
|
|
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
|
|
2106
|
-
|
|
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
|
-
...
|
|
2235
|
+
...pe(e.contentType),
|
|
2117
2236
|
"cache-control": t,
|
|
2118
2237
|
"accept-ranges": "bytes"
|
|
2119
2238
|
},
|
|
2120
2239
|
byteStream: {
|
|
2121
|
-
contentLength:
|
|
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
|
-
},
|
|
2135
|
-
let t = e.path.startsWith(
|
|
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
|
|
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 =
|
|
2261
|
+
let r = We(e.query), i = e.headers.range;
|
|
2148
2262
|
if (n.visibility === "public") {
|
|
2149
|
-
let e =
|
|
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
|
-
} :
|
|
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 =
|
|
2274
|
+
let e = dt(o);
|
|
2161
2275
|
a = !!e && e.refId === t;
|
|
2162
2276
|
}
|
|
2163
2277
|
if (!a) {
|
|
2164
|
-
let t =
|
|
2165
|
-
r && (a = await
|
|
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 (
|
|
2173
|
-
let e = await
|
|
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
|
|
2183
|
-
},
|
|
2296
|
+
return me(n, "private, no-store", r, i);
|
|
2297
|
+
}, ge = {
|
|
2184
2298
|
method: "GET",
|
|
2185
|
-
path:
|
|
2299
|
+
path: b,
|
|
2186
2300
|
handle: async (e) => {
|
|
2187
|
-
let t = await
|
|
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
|
-
},
|
|
2310
|
+
}, _e = {
|
|
2197
2311
|
method: "*",
|
|
2198
|
-
path:
|
|
2312
|
+
path: `${b}/upload`,
|
|
2199
2313
|
originGuard: "exempt",
|
|
2200
2314
|
handle: async (e) => {
|
|
2201
|
-
let t =
|
|
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 ?
|
|
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
|
|
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(
|
|
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
|
-
})))),
|
|
2247
|
-
StorageRejected: (e) =>
|
|
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) =>
|
|
2366
|
+
StorageScanRejected: (e) => y.succeed({
|
|
2253
2367
|
kind: "scan",
|
|
2254
2368
|
threat: e.threat
|
|
2255
2369
|
}),
|
|
2256
|
-
StorageError: (e) =>
|
|
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
|
-
},
|
|
2402
|
+
}, ve = {
|
|
2289
2403
|
method: "*",
|
|
2290
|
-
path:
|
|
2404
|
+
path: `${b}/upload/resumable`,
|
|
2291
2405
|
originGuard: "exempt",
|
|
2292
2406
|
handle: async (e) => {
|
|
2293
|
-
let t =
|
|
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 =
|
|
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
|
|
2420
|
+
let e = await y.runPromise(L.resumableStatus({
|
|
2307
2421
|
uploadId: r.id,
|
|
2308
2422
|
tenantId: r.tenant
|
|
2309
|
-
}).pipe(
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
}))))) :
|
|
2368
|
-
StorageRejected: (e) =>
|
|
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) =>
|
|
2487
|
+
StorageScanRejected: (e) => y.succeed({
|
|
2374
2488
|
kind: "scan",
|
|
2375
2489
|
threat: e.threat
|
|
2376
2490
|
}),
|
|
2377
|
-
StorageError: (e) =>
|
|
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
|
-
},
|
|
2529
|
+
}, V = (e) => ({
|
|
2416
2530
|
kind: "json",
|
|
2417
2531
|
data: e
|
|
2418
|
-
}),
|
|
2532
|
+
}), H = (e, t) => ({
|
|
2419
2533
|
kind: "json",
|
|
2420
2534
|
status: e,
|
|
2421
2535
|
data: { error: t }
|
|
2422
|
-
}),
|
|
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
|
-
},
|
|
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: "
|
|
2433
|
-
handler: (
|
|
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: () =>
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
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 =
|
|
2465
|
-
return t ?
|
|
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) =>
|
|
2473
|
-
let n = yield*
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
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
|
|
2491
|
-
}).pipe(
|
|
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) =>
|
|
2498
|
-
let n = yield*
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
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
|
-
],
|
|
2698
|
+
], xe = [
|
|
2511
2699
|
{
|
|
2512
2700
|
...h,
|
|
2513
2701
|
execute: (e, t) => {
|
|
2514
2702
|
let n = e;
|
|
2515
|
-
return
|
|
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(
|
|
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
|
|
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(
|
|
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,
|
|
2538
|
-
let t = n.expiresInSec ?? 900, r =
|
|
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
|
-
...
|
|
2737
|
+
...D === void 0 ? {} : { max: D }
|
|
2549
2738
|
}, t);
|
|
2550
2739
|
return {
|
|
2551
|
-
uploadUrl: `${
|
|
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,
|
|
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(
|
|
2566
|
-
let r =
|
|
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
|
-
...
|
|
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 =
|
|
2590
|
-
return r
|
|
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
|
-
})) :
|
|
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(
|
|
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
|
-
})))))
|
|
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,
|
|
2625
|
-
let t = n.expiresInSec ??
|
|
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:
|
|
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
|
-
...
|
|
2830
|
+
...D === void 0 ? {} : { max: D }
|
|
2640
2831
|
}, t),
|
|
2641
|
-
uploadUrl: `${
|
|
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 ??
|
|
2652
|
-
return $(t,
|
|
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(
|
|
2658
|
-
multipartToken:
|
|
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 >=
|
|
2863
|
+
partSize: n.partSize && n.partSize >= k ? n.partSize : k,
|
|
2672
2864
|
expiresInSec: r
|
|
2673
2865
|
})))));
|
|
2674
2866
|
}
|
|
2675
2867
|
},
|
|
2676
2868
|
{
|
|
2677
|
-
...
|
|
2869
|
+
...ne,
|
|
2678
2870
|
execute: (e) => {
|
|
2679
|
-
let n = e, r =
|
|
2680
|
-
return r
|
|
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
|
-
})) :
|
|
2882
|
+
})) : L.signMultipartPart({
|
|
2686
2883
|
key: r.key,
|
|
2687
2884
|
uploadId: r.uploadId,
|
|
2688
2885
|
partNumber: n.partNumber
|
|
2689
|
-
}).pipe(
|
|
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 =
|
|
2701
|
-
return i
|
|
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
|
-
})) :
|
|
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(
|
|
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
|
-
})))))
|
|
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 =
|
|
2734
|
-
return n ?
|
|
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
|
-
...
|
|
2938
|
+
..._,
|
|
2747
2939
|
execute: (e, t) => {
|
|
2748
2940
|
let n = e, r = new Uint8Array(Buffer.from(n.bytesBase64, "base64"));
|
|
2749
|
-
return $(t,
|
|
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
|
-
})),
|
|
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,
|
|
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
|
-
})),
|
|
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
|
|
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
|
-
})),
|
|
2985
|
+
})), y.map((e) => ({ grantId: e.id })));
|
|
2794
2986
|
}
|
|
2795
2987
|
},
|
|
2796
2988
|
{
|
|
2797
|
-
...
|
|
2989
|
+
...te,
|
|
2798
2990
|
execute: (e, t) => {
|
|
2799
2991
|
let n = e;
|
|
2800
|
-
return
|
|
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
|
|
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
|
|
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(
|
|
2823
|
-
refs: e.refs.map(
|
|
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
|
|
2830
|
-
name:
|
|
2831
|
-
base:
|
|
3021
|
+
return ie({
|
|
3022
|
+
name: T({
|
|
3023
|
+
base: xn,
|
|
2832
3024
|
alias: i.alias,
|
|
2833
3025
|
instance: i.name
|
|
2834
3026
|
}),
|
|
2835
|
-
baseName:
|
|
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:
|
|
2843
|
-
services:
|
|
2844
|
-
inspectEndpoints:
|
|
3034
|
+
declaredEnv: K.declared,
|
|
3035
|
+
services: ue,
|
|
3036
|
+
inspectEndpoints: be,
|
|
2845
3037
|
httpRoutes: [
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
3038
|
+
ge,
|
|
3039
|
+
_e,
|
|
3040
|
+
ve
|
|
2849
3041
|
],
|
|
2850
|
-
routes:
|
|
2851
|
-
rpcClientDescriptors:
|
|
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
|
-
|
|
3075
|
+
j && (N.current = Rt(e)), M && (P.current = Vt(e)), x.bindDataStore?.(e);
|
|
2884
3076
|
},
|
|
2885
|
-
onActivate: (e) =>
|
|
2886
|
-
let t = !!
|
|
2887
|
-
e.logger.info(`storage: provider=${
|
|
2888
|
-
provider:
|
|
2889
|
-
bucket:
|
|
2890
|
-
refStore:
|
|
2891
|
-
}),
|
|
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: () =>
|
|
3085
|
+
onDeactivate: () => y.void
|
|
2894
3086
|
});
|
|
2895
3087
|
};
|
|
2896
3088
|
//#endregion
|
|
2897
|
-
export {
|
|
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 };
|