@voltro/plugin-storage 0.70.0 → 0.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1289 -111
- package/dist/index.d.ts +55 -2
- package/dist/index.js +749 -561
- 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
2
|
import { abortMultipartUploadDescriptor as a, beginMultipartUploadDescriptor as o, beginResumableUploadDescriptor as s, completeMultipartUploadDescriptor as c, finalizeUploadDescriptor as l, ingestUrlDescriptor as u, listGrantsDescriptor as d, listRefsDescriptor as f, mintPresignedUploadDescriptor as p, mintUploadTicketDescriptor as m, mintUploadUrlDescriptor as ee, mintUrlDescriptor as h, revokeDescriptor as g, shareDescriptor as _, signMultipartPartDescriptor as te, storageRpcClientImports as ne, uploadDescriptor as v } from "./rpc.js";
|
|
3
|
-
import { Chunk as y, Effect as b, Exit as x, Layer as S, Schedule as C,
|
|
4
|
-
import { definePlugin as
|
|
5
|
-
import { readCookie as
|
|
6
|
-
import { and as D, bytes 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
|
|
3
|
+
import { Chunk as y, Effect as b, Exit as x, Layer as S, Schedule as C, Schema as w, Stream as T } from "effect";
|
|
4
|
+
import { definePlugin as re, pluginInstanceName as E } from "@voltro/protocol";
|
|
5
|
+
import { readCookie as ie, resolveSessionSecret as ae, verifySession as oe } from "@voltro/protocol/session";
|
|
6
|
+
import { and as D, bytes as se, contains as O, eq as k, generateId as A, id as j, integer as M, json as N, mixin as P, or as F, reference as ce, table as I, text as L, timestamp as le } from "@voltro/database";
|
|
7
|
+
import { pluginEnv as R } from "@voltro/env";
|
|
8
|
+
import { createHmac as z, randomBytes as B, randomUUID as ue, scryptSync as de, timingSafeEqual as V } from "node:crypto";
|
|
9
|
+
import { spawn as fe } from "node:child_process";
|
|
10
|
+
import { mkdtemp as pe, readFile as me, rm as he, writeFile as ge } from "node:fs/promises";
|
|
11
|
+
import { tmpdir as _e } from "node:os";
|
|
12
|
+
import { join as H } from "node:path";
|
|
13
|
+
import { statSync as U } from "node:fs";
|
|
14
14
|
//#region src/streamBridge.ts
|
|
15
|
-
var
|
|
15
|
+
var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
16
16
|
provider: e,
|
|
17
17
|
message: n,
|
|
18
18
|
transient: r
|
|
19
|
-
}),
|
|
19
|
+
}), be = (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
|
+
}, xe = (e, t = ve) => {
|
|
26
26
|
let n = [];
|
|
27
27
|
for (let r = 0; r < e.byteLength; r += t) n.push(e.subarray(r, Math.min(r + t, e.byteLength)));
|
|
28
|
-
return
|
|
29
|
-
},
|
|
28
|
+
return T.fromIterable(n);
|
|
29
|
+
}, Se = (e) => e.pipe(T.runCollect, b.map((e) => be(y.toReadonlyArray(e)))), Ce = (e, t) => T.suspend(() => T.fromAsyncIterable(t(), (t) => ye(e, `read stream failed: ${String(t?.message ?? t)}`, !0))).pipe(T.map((e) => e instanceof Uint8Array ? e : new Uint8Array(e))), we = async (e) => {
|
|
30
30
|
let { Readable: t } = await import("node:stream");
|
|
31
|
-
return t.fromWeb(
|
|
32
|
-
},
|
|
33
|
-
stream:
|
|
31
|
+
return t.fromWeb(T.toReadableStream(e));
|
|
32
|
+
}, Te = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(b.map((e) => ({
|
|
33
|
+
stream: xe(e.bytes),
|
|
34
34
|
contentType: e.contentType,
|
|
35
35
|
size: e.bytes.byteLength
|
|
36
|
-
}))),
|
|
36
|
+
}))), Ee = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : Se(n).pipe(b.flatMap((n) => e.put(t, n, {
|
|
37
37
|
contentType: r.contentType,
|
|
38
38
|
...r.public === void 0 ? {} : { public: r.public }
|
|
39
|
-
}))),
|
|
40
|
-
id:
|
|
41
|
-
tenantId:
|
|
42
|
-
ownerId:
|
|
43
|
-
bucket:
|
|
44
|
-
key:
|
|
45
|
-
contentType:
|
|
46
|
-
size:
|
|
47
|
-
checksum:
|
|
48
|
-
visibility:
|
|
49
|
-
accessPolicy:
|
|
50
|
-
passwordHash:
|
|
51
|
-
width:
|
|
52
|
-
height:
|
|
53
|
-
duration:
|
|
54
|
-
placeholder:
|
|
55
|
-
folder:
|
|
56
|
-
tags:
|
|
57
|
-
alt:
|
|
58
|
-
caption:
|
|
59
|
-
derivedFrom:
|
|
60
|
-
kind:
|
|
61
|
-
createdAt:
|
|
62
|
-
}).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]),
|
|
63
|
-
id:
|
|
64
|
-
refId:
|
|
65
|
-
principalType:
|
|
66
|
-
principalId:
|
|
67
|
-
permission:
|
|
68
|
-
createdAt:
|
|
69
|
-
expiresAt:
|
|
70
|
-
createdBy:
|
|
71
|
-
}).index(["refId"]).index(["principalId"]),
|
|
72
|
-
id:
|
|
73
|
-
tenantId:
|
|
74
|
-
bytes:
|
|
75
|
-
count:
|
|
76
|
-
updatedAt:
|
|
77
|
-
}).unique("byStorageUsageTenant", ["tenantId"]),
|
|
78
|
-
id:
|
|
79
|
-
key:
|
|
80
|
-
data:
|
|
81
|
-
contentType:
|
|
82
|
-
size:
|
|
83
|
-
}).index(["key"]),
|
|
39
|
+
}))), W = "_voltro_storage_refs", G = "_voltro_storage_grants", K = "_voltro_storage_blobs", De = "_voltro_storage_usage", Oe = I(W, {
|
|
40
|
+
id: j({ prefix: "file" }),
|
|
41
|
+
tenantId: L().nullable(),
|
|
42
|
+
ownerId: L().nullable(),
|
|
43
|
+
bucket: L(),
|
|
44
|
+
key: L(),
|
|
45
|
+
contentType: L(),
|
|
46
|
+
size: M(),
|
|
47
|
+
checksum: L(),
|
|
48
|
+
visibility: L(),
|
|
49
|
+
accessPolicy: N().nullable(),
|
|
50
|
+
passwordHash: L().nullable(),
|
|
51
|
+
width: M().nullable(),
|
|
52
|
+
height: M().nullable(),
|
|
53
|
+
duration: M().nullable(),
|
|
54
|
+
placeholder: L().nullable(),
|
|
55
|
+
folder: L().nullable(),
|
|
56
|
+
tags: N().nullable(),
|
|
57
|
+
alt: L().nullable(),
|
|
58
|
+
caption: L().nullable(),
|
|
59
|
+
derivedFrom: L().nullable(),
|
|
60
|
+
kind: L().nullable(),
|
|
61
|
+
createdAt: le()
|
|
62
|
+
}).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]), ke = I(G, {
|
|
63
|
+
id: j({ prefix: "sgrant" }),
|
|
64
|
+
refId: L(),
|
|
65
|
+
principalType: L(),
|
|
66
|
+
principalId: L(),
|
|
67
|
+
permission: L(),
|
|
68
|
+
createdAt: le(),
|
|
69
|
+
expiresAt: le().nullable(),
|
|
70
|
+
createdBy: L().nullable()
|
|
71
|
+
}).index(["refId"]).index(["principalId"]), Ae = I(De, {
|
|
72
|
+
id: j({ prefix: "susage" }),
|
|
73
|
+
tenantId: L().maxLength(191),
|
|
74
|
+
bytes: M().default(0),
|
|
75
|
+
count: M().default(0),
|
|
76
|
+
updatedAt: le()
|
|
77
|
+
}).unique("byStorageUsageTenant", ["tenantId"]), je = I(K, {
|
|
78
|
+
id: j({ prefix: "blob" }),
|
|
79
|
+
key: L(),
|
|
80
|
+
data: se(),
|
|
81
|
+
contentType: L(),
|
|
82
|
+
size: M()
|
|
83
|
+
}).index(["key"]), q = R([
|
|
84
84
|
{
|
|
85
85
|
name: "STORAGE_PROVIDER",
|
|
86
86
|
required: !1,
|
|
@@ -231,16 +231,16 @@ 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
|
+
]), J = (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
|
+
}), Me = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, Ne = /* @__PURE__ */ new Map(), Pe = (e, t) => Ne.get(e)?.get(t)?.bytes, Fe = (e) => {
|
|
240
|
+
Ne.get(e)?.clear();
|
|
241
|
+
}, Ie = (e = "default") => {
|
|
242
|
+
let t = Ne.get(e) ?? /* @__PURE__ */ new Map();
|
|
243
|
+
return Ne.set(e, t), {
|
|
244
244
|
name: "memory",
|
|
245
245
|
presigns: !1,
|
|
246
246
|
put: (e, n, r) => b.sync(() => (t.set(e, {
|
|
@@ -252,7 +252,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
252
252
|
return n ? b.succeed({
|
|
253
253
|
bytes: n.bytes,
|
|
254
254
|
contentType: n.contentType
|
|
255
|
-
}) : b.fail(
|
|
255
|
+
}) : b.fail(J("memory", `no object at key '${e}'`, !1, 404));
|
|
256
256
|
}),
|
|
257
257
|
delete: (e) => b.sync(() => {
|
|
258
258
|
t.delete(e);
|
|
@@ -264,14 +264,14 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
264
264
|
return n ? { size: n.bytes.byteLength } : null;
|
|
265
265
|
})
|
|
266
266
|
};
|
|
267
|
-
},
|
|
267
|
+
}, Le = (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
272
|
}, r = (e, t, n = !1) => b.tryPromise({
|
|
273
273
|
try: e,
|
|
274
|
-
catch: (e) => e?.code === "ENOENT" ?
|
|
274
|
+
catch: (e) => e?.code === "ENOENT" ? J("filesystem", `no object at key '${t}'`, !1, 404) : J("filesystem", String(e?.message ?? e), n)
|
|
275
275
|
});
|
|
276
276
|
return {
|
|
277
277
|
root: t,
|
|
@@ -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) => J("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: Ce("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 we(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
|
+
}), be(o);
|
|
344
344
|
}, e)
|
|
345
345
|
};
|
|
346
|
-
},
|
|
346
|
+
}, Re = (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 {
|
|
@@ -368,7 +368,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
368
368
|
try: e,
|
|
369
369
|
catch: (e) => {
|
|
370
370
|
let n = e?.$metadata?.httpStatusCode;
|
|
371
|
-
return
|
|
371
|
+
return J(t, String(e?.message ?? e), Me(n), n);
|
|
372
372
|
}
|
|
373
373
|
}), o = async (e) => {
|
|
374
374
|
let t = e;
|
|
@@ -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 J(t, String(e?.message ?? e), Me(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: Ce(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 we(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
|
+
}, ze = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), Be = () => {
|
|
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
535
|
}, n = (e) => b.tryPromise({
|
|
536
536
|
try: e,
|
|
537
|
-
catch: (e) =>
|
|
537
|
+
catch: (e) => J("database", String(e?.message ?? e), !0)
|
|
538
538
|
}), r = async (e) => (await t().query({
|
|
539
|
-
table:
|
|
539
|
+
table: K,
|
|
540
540
|
predicate: {
|
|
541
541
|
column: "key",
|
|
542
542
|
op: "eq",
|
|
@@ -555,15 +555,15 @@ 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(K, String(n.id), {
|
|
559
559
|
data: i,
|
|
560
560
|
contentType: a.contentType,
|
|
561
561
|
size: i.byteLength
|
|
562
|
-
}) : await t().insert(
|
|
563
|
-
id:
|
|
562
|
+
}) : await t().insert(K, {
|
|
563
|
+
id: A({
|
|
564
564
|
kind: "typeid",
|
|
565
565
|
prefix: "blob"
|
|
566
|
-
},
|
|
566
|
+
}, K),
|
|
567
567
|
key: e,
|
|
568
568
|
data: i,
|
|
569
569
|
contentType: a.contentType,
|
|
@@ -571,12 +571,12 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
571
571
|
}), { size: i.byteLength };
|
|
572
572
|
}),
|
|
573
573
|
get: (e) => b.suspend(() => n(() => r(e)).pipe(b.flatMap((t) => t ? b.succeed({
|
|
574
|
-
bytes:
|
|
574
|
+
bytes: ze(t.data),
|
|
575
575
|
contentType: String(t.contentType)
|
|
576
|
-
}) : b.fail(
|
|
576
|
+
}) : b.fail(J("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(K, String(n.id));
|
|
580
580
|
}),
|
|
581
581
|
publicUrl: () => null,
|
|
582
582
|
getUrl: () => b.succeed(""),
|
|
@@ -585,7 +585,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
585
585
|
return t ? { size: Number(t.size) } : null;
|
|
586
586
|
})
|
|
587
587
|
};
|
|
588
|
-
},
|
|
588
|
+
}, Ve = (e) => {
|
|
589
589
|
let t = null, n = () => t || (t = (async () => {
|
|
590
590
|
let t;
|
|
591
591
|
try {
|
|
@@ -593,7 +593,7 @@ 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 = q.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = q.read("AZURE_STORAGE_KEY", e.accountKey), i = n && r ? new t.StorageSharedKeyCredential(n, r) : null, a = q.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,
|
|
@@ -603,7 +603,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
603
603
|
try: e,
|
|
604
604
|
catch: (e) => {
|
|
605
605
|
let t = e?.statusCode;
|
|
606
|
-
return
|
|
606
|
+
return J("azure", String(e?.message ?? e), Me(t), t);
|
|
607
607
|
}
|
|
608
608
|
}), i = async (e) => {
|
|
609
609
|
if (!e) return /* @__PURE__ */ new Uint8Array();
|
|
@@ -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 J("azure", String(e?.message ?? e), Me(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: Ce("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 we(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
|
+
}, He = {
|
|
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
|
+
}, Ue = (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
|
+
}, We = (e) => e.startsWith("image/") && !e.includes("svg"), Ge, Ke = async () => {
|
|
706
|
+
if (Ge !== void 0) return Ge;
|
|
707
707
|
try {
|
|
708
708
|
let e = await import("sharp");
|
|
709
|
-
|
|
709
|
+
Ge = e.default ?? e;
|
|
710
710
|
} catch {
|
|
711
|
-
|
|
711
|
+
Ge = null;
|
|
712
712
|
}
|
|
713
|
-
return
|
|
714
|
-
},
|
|
715
|
-
if (!
|
|
716
|
-
let r = await
|
|
713
|
+
return Ge;
|
|
714
|
+
}, qe = async (e, t, n) => {
|
|
715
|
+
if (!We(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 && He[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 = He[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 = B(16).toString("hex");
|
|
750
|
+
return `${t}:${de(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 = de(e, n, i.length);
|
|
756
|
+
return a.length === i.length && V(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" ? b.succeed(e) : b.isEffect(e) ? e : b.promise(() => e), at = (e, t, n = {}) => b.gen(function* () {
|
|
758
758
|
if (t.id && e.ownerId && t.id === e.ownerId) return !0;
|
|
759
759
|
let r = e.accessPolicy ?? [];
|
|
760
760
|
if (r.length === 0) return !1;
|
|
761
|
-
let i = n.resolveGroups ? yield* b.promise(async () => await n.resolveGroups(t)) :
|
|
762
|
-
for (let a of r) if (yield*
|
|
761
|
+
let i = n.resolveGroups ? yield* b.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) => b.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 ? b.promise(async () => await t.resolveGroups(e)) : b.succeed(rt(e)), Y = () => q.read("VOLTRO_STORAGE_SECRET") ?? ae(), 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(z("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 = z("sha256", t).update(r).digest(), o = Z(i);
|
|
804
|
+
if (o.length !== a.length || !V(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(z("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 = z("sha256", t).update(`u:${r}`).digest(), o = Z(i);
|
|
823
|
+
if (o.length !== a.length || !V(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(z("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 = z("sha256", t).update(`f:${r}`).digest(), o = Z(i);
|
|
842
|
+
if (o.length !== a.length || !V(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(z("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 = z("sha256", t).update(`r:${r}`).digest(), o = Z(i);
|
|
861
|
+
if (o.length !== a.length || !V(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(z("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 = z("sha256", t).update(`m:${r}`).digest(), o = Z(i);
|
|
880
|
+
if (o.length !== a.length || !V(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 (!We(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) => b.suspend(() => {
|
|
1005
|
+
let i = r ?? Tt;
|
|
1006
|
+
return !Number.isSafeInteger(i) || i < 0 ? b.fail(new t({
|
|
1007
|
+
provider: "ingest",
|
|
1008
|
+
message: "limits.maxBytes must be a non-negative safe integer",
|
|
1009
|
+
transient: !1
|
|
1010
|
+
})) : b.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) => b.suspend(() => {
|
|
1051
|
+
if (t === void 0) return e;
|
|
1052
|
+
if (t.aborted) return b.interrupt;
|
|
1053
|
+
let n = b.async((e) => {
|
|
1054
|
+
let n = () => e(b.interrupt);
|
|
1055
|
+
return t.addEventListener("abort", n, { once: !0 }), t.aborted && n(), b.sync(() => t.removeEventListener("abort", n));
|
|
1056
|
+
});
|
|
1057
|
+
return b.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,15 +1091,23 @@ 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 {
|
|
1097
|
+
statistics: () => b.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
|
+
})())),
|
|
1018
1105
|
insert: (t) => b.sync(() => {
|
|
1019
1106
|
e.set(t.id, t);
|
|
1020
1107
|
}),
|
|
1021
1108
|
getById: (t) => b.sync(() => e.get(t) ?? null),
|
|
1022
1109
|
delete: (t) => b.sync(() => e.delete(t)),
|
|
1023
|
-
listRecent: (t) => b.sync(() => [...e.values()].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime()).slice(0, t)),
|
|
1110
|
+
listRecent: (t) => b.sync(() => [...e.values()].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(0, t)),
|
|
1024
1111
|
countByKey: (t, n) => b.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n).length),
|
|
1025
1112
|
usageByTenant: (t) => b.sync(() => {
|
|
1026
1113
|
let n = 0, r = 0;
|
|
@@ -1031,7 +1118,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1031
1118
|
};
|
|
1032
1119
|
}),
|
|
1033
1120
|
consumeUsage: (e, n, r) => b.sync(() => {
|
|
1034
|
-
let i =
|
|
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);
|
|
@@ -1045,16 +1132,16 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1045
1132
|
};
|
|
1046
1133
|
}),
|
|
1047
1134
|
releaseUsage: (e, n) => b.sync(() => {
|
|
1048
|
-
let r =
|
|
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
1141
|
listByDerivedFrom: (t) => b.sync(() => [...e.values()].filter((e) => (e.derivedFrom ?? null) === t)),
|
|
1055
|
-
listRefs: (t) => b.sync(() => [...e.values()].filter((e) =>
|
|
1142
|
+
listRefs: (t) => b.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,7 +1159,7 @@ 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,
|
|
@@ -1084,7 +1171,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
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: W,
|
|
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(W, { ...t })),
|
|
1100
1209
|
getById: (t) => Q(async () => {
|
|
1101
1210
|
let n = await e.query({
|
|
1102
|
-
table:
|
|
1211
|
+
table: W,
|
|
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(W, t)),
|
|
1116
1225
|
listRecent: (t) => Q(async () => (await e.query({
|
|
1117
|
-
table:
|
|
1226
|
+
table: W,
|
|
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: W,
|
|
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: W,
|
|
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,16 +1283,16 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1174
1283
|
bytes: o + n.bytes,
|
|
1175
1284
|
count: s + n.count,
|
|
1176
1285
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1177
|
-
}, { where: D(
|
|
1286
|
+
}, { where: D(k("id", String(a.id)), k("bytes", o), k("count", s)) }) === 1) return {
|
|
1178
1287
|
allowed: !0,
|
|
1179
1288
|
bytes: o,
|
|
1180
1289
|
count: s
|
|
1181
1290
|
};
|
|
1182
1291
|
} else {
|
|
1183
|
-
let t =
|
|
1292
|
+
let t = A({
|
|
1184
1293
|
kind: "typeid",
|
|
1185
1294
|
prefix: "susage"
|
|
1186
|
-
},
|
|
1295
|
+
}, De), r = await e.insertIgnore(De, {
|
|
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: D(
|
|
1322
|
+
}, { where: D(k("id", String(i.id)), k("bytes", a), k("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: W,
|
|
1219
1328
|
predicate: {
|
|
1220
1329
|
column: "derivedFrom",
|
|
1221
1330
|
op: "eq",
|
|
@@ -1228,32 +1337,33 @@ 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(k("tenantId", t.tenantId)), t.ownerId !== void 0 && n.push(k("ownerId", t.ownerId)), t.search && n.push(F(...[
|
|
1344
|
+
"id",
|
|
1345
|
+
"key",
|
|
1346
|
+
"contentType",
|
|
1347
|
+
"ownerId",
|
|
1348
|
+
"tenantId"
|
|
1349
|
+
].map((e) => O(e, t.search))));
|
|
1350
|
+
let r = t.folder === void 0 && t.tags.length === 0 && t.includeDerived, i = n.length ? D(...n) : void 0, a = await e.query({
|
|
1351
|
+
table: W,
|
|
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
1369
|
insert: (t) => b.sync(() => {
|
|
@@ -1268,7 +1378,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
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(G, { ...t })),
|
|
1392
|
+
delete: (t) => Q(() => e.delete(G, t)),
|
|
1283
1393
|
getById: (t) => Q(async () => {
|
|
1284
1394
|
let n = (await e.query({
|
|
1285
|
-
table:
|
|
1395
|
+
table: G,
|
|
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: G,
|
|
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: G,
|
|
1316
1426
|
predicate: {
|
|
1317
1427
|
column: "refId",
|
|
1318
1428
|
op: "eq",
|
|
@@ -1323,16 +1433,16 @@ 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(G, String(t.id));
|
|
1327
1437
|
})
|
|
1328
|
-
}),
|
|
1438
|
+
}), Ht = () => A({
|
|
1329
1439
|
kind: "typeid",
|
|
1330
1440
|
prefix: "file"
|
|
1331
|
-
},
|
|
1441
|
+
}, W), Ut = () => A({
|
|
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
|
+
}, G), 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 = C.recurs(Math.max(0, u - 1)).pipe(C.intersect(C.exponential("100 millis")), C.whileInput((e) => e.transient)), m = (e, t, n) => [
|
|
1336
1446
|
i.tenantPrefix,
|
|
1337
1447
|
e ?? "global",
|
|
1338
1448
|
n ?? t
|
|
@@ -1385,7 +1495,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1385
1495
|
catch: () => null
|
|
1386
1496
|
}).pipe(b.catchAll(() => b.succeed(null)));
|
|
1387
1497
|
}), v = (e) => b.gen(function* () {
|
|
1388
|
-
let t =
|
|
1498
|
+
let t = Ct(e.bytes, e.contentType, i.limits);
|
|
1389
1499
|
if (t) return yield* b.fail(new n(t));
|
|
1390
1500
|
if (i.scan) {
|
|
1391
1501
|
let t = yield* te({
|
|
@@ -1395,10 +1505,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1395
1505
|
});
|
|
1396
1506
|
if (!t.clean) return yield* b.fail(new r({ threat: t.threat ?? "unknown" }));
|
|
1397
1507
|
}
|
|
1398
|
-
let s = yield* b.promise(() =>
|
|
1508
|
+
let s = yield* b.promise(() => wt(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* ne({
|
|
1399
1509
|
bytes: l,
|
|
1400
1510
|
contentType: e.contentType
|
|
1401
|
-
}), d = s.width ?? u?.width, f = s.height ?? u?.height, h = s.placeholder ?? u?.poster, g = e.duration ?? u?.duration, _ = yield* b.promise(() =>
|
|
1511
|
+
}), d = s.width ?? u?.width, f = s.height ?? u?.height, h = s.placeholder ?? u?.poster, g = e.duration ?? u?.duration, _ = yield* b.promise(() => kt(l)), v = e.tenantId ?? null, y = e.visibility ?? "private", C = m(v, _, yield* ee(e.key)), w = {
|
|
1402
1512
|
bytes: l.byteLength,
|
|
1403
1513
|
count: 1
|
|
1404
1514
|
}, T = yield* o.consumeUsage(v, w, i.quota);
|
|
@@ -1409,8 +1519,8 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1409
1519
|
detail: t
|
|
1410
1520
|
}));
|
|
1411
1521
|
}
|
|
1412
|
-
let re = e.password ? yield* b.sync(() =>
|
|
1413
|
-
id:
|
|
1522
|
+
let re = e.password ? yield* b.sync(() => Ze(e.password)) : null, E = {
|
|
1523
|
+
id: Ht(),
|
|
1414
1524
|
tenantId: v,
|
|
1415
1525
|
ownerId: e.ownerId ?? null,
|
|
1416
1526
|
bucket: c,
|
|
@@ -1471,13 +1581,13 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1471
1581
|
}
|
|
1472
1582
|
return r;
|
|
1473
1583
|
}), w = (e, t, n) => b.gen(function* () {
|
|
1474
|
-
if (e.visibility === "public" || (yield*
|
|
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
|
+
}), re = (e) => {
|
|
1481
1591
|
if (e.visibility === "public") {
|
|
1482
1592
|
let t = a.publicUrl?.(e.key);
|
|
1483
1593
|
if (t != null) return t;
|
|
@@ -1490,6 +1600,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1490
1600
|
bytes: t.bytes,
|
|
1491
1601
|
ref: e
|
|
1492
1602
|
}))))),
|
|
1603
|
+
getStream: (e, t) => _(e, t?.tenantId).pipe(b.map((e) => ({
|
|
1604
|
+
ref: e,
|
|
1605
|
+
stream: T.unwrap(b.suspend(() => a.getStream ? a.getStream(e.key).pipe(b.retry(p), b.map((e) => e.stream)) : a.get(e.key).pipe(b.retry(p), b.map((e) => T.make(e.bytes)))))
|
|
1606
|
+
}))),
|
|
1493
1607
|
getRange: (e, n, r) => _(e, r?.tenantId).pipe(b.flatMap((e) => {
|
|
1494
1608
|
let r = e.size, i = Math.max(0, Math.trunc(n.start));
|
|
1495
1609
|
if (r > 0 && i >= r) return b.fail(new t({
|
|
@@ -1510,7 +1624,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1510
1624
|
totalSize: r
|
|
1511
1625
|
})));
|
|
1512
1626
|
})),
|
|
1513
|
-
getUrl: (e, t) => _(e, t?.tenantId).pipe(b.flatMap((e) => e.visibility === "public" ? b.succeed(
|
|
1627
|
+
getUrl: (e, t) => _(e, t?.tenantId).pipe(b.flatMap((e) => e.visibility === "public" ? b.succeed(re(e)) : a.presigns ? a.getUrl(e.key, t?.expiresInSec ?? d) : b.succeed(f(e.id)))),
|
|
1514
1628
|
head: (e, t) => o.getById(e).pipe(b.flatMap((e) => e ? g(e, t?.tenantId).pipe(b.map((e) => e)) : b.succeed(null))),
|
|
1515
1629
|
delete: (e, t) => _(e, t?.tenantId).pipe(b.flatMap((t) => s.deleteByRef(e).pipe(b.flatMap(() => o.delete(e)), b.flatMap((e) => e ? o.countByKey(t.bucket, t.key).pipe(b.flatMap((e) => e === 0 ? a.delete(t.key).pipe(b.retry(p)) : b.void), b.flatMap(() => o.releaseUsage(t.tenantId, {
|
|
1516
1630
|
bytes: t.size,
|
|
@@ -1523,14 +1637,14 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1523
1637
|
transient: !1,
|
|
1524
1638
|
status: 404
|
|
1525
1639
|
}))));
|
|
1526
|
-
if (s.visibility === "public") return
|
|
1640
|
+
if (s.visibility === "public") return re(s);
|
|
1527
1641
|
if (!(yield* w(s, r, i?.password === void 0 ? {} : { password: i.password }))) return yield* b.fail(new e({
|
|
1528
1642
|
refId: n,
|
|
1529
1643
|
reason: "access denied"
|
|
1530
1644
|
}));
|
|
1531
1645
|
let c = i?.expiresInSec ?? d;
|
|
1532
1646
|
if (a.presigns) return yield* a.getUrl(s.key, c);
|
|
1533
|
-
let l = yield* b.sync(() =>
|
|
1647
|
+
let l = yield* b.sync(() => ut(s.id, c));
|
|
1534
1648
|
return `${f(s.id)}?t=${l}`;
|
|
1535
1649
|
}),
|
|
1536
1650
|
mintUploadUrl: (e) => b.gen(function* () {
|
|
@@ -1546,7 +1660,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1546
1660
|
checkAccess: w,
|
|
1547
1661
|
grant: (e) => b.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,
|
|
@@ -1581,51 +1695,36 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1581
1695
|
usage: (e) => o.usageByTenant(e),
|
|
1582
1696
|
sweepOrphans: (e) => b.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
|
-
try: () => fetch(e),
|
|
1596
|
-
catch: (e) => new t({
|
|
1597
|
-
provider: "ingest",
|
|
1598
|
-
message: `fetch failed: ${String(e?.message ?? e)}`,
|
|
1599
|
-
transient: !0
|
|
1600
|
-
})
|
|
1601
|
-
});
|
|
1602
|
-
if (!r.ok) return yield* b.fail(new t({
|
|
1603
|
-
provider: "ingest",
|
|
1604
|
-
message: `fetch ${e} → ${r.status}`,
|
|
1605
|
-
transient: r.status >= 500,
|
|
1606
|
-
status: r.status
|
|
1607
|
-
}));
|
|
1608
|
-
let i = yield* b.tryPromise({
|
|
1609
|
-
try: () => r.arrayBuffer(),
|
|
1610
|
-
catch: (e) => new t({
|
|
1611
|
-
provider: "ingest",
|
|
1612
|
-
message: `read body failed: ${String(e?.message ?? e)}`,
|
|
1613
|
-
transient: !0
|
|
1614
|
-
})
|
|
1615
|
-
}), a = n?.contentType ?? r.headers.get("content-type")?.split(";")[0]?.trim() ?? "application/octet-stream";
|
|
1713
|
+
ingestUrl: (e, t) => Ot(b.gen(function* () {
|
|
1714
|
+
let n = yield* Dt(e, i.limits?.maxBytes);
|
|
1616
1715
|
return yield* v({
|
|
1617
|
-
bytes:
|
|
1618
|
-
contentType:
|
|
1619
|
-
...
|
|
1620
|
-
...
|
|
1621
|
-
...
|
|
1622
|
-
...
|
|
1623
|
-
...
|
|
1624
|
-
...
|
|
1625
|
-
...
|
|
1626
|
-
...
|
|
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
|
-
}),
|
|
1727
|
+
}), t?.abortSignal),
|
|
1629
1728
|
mintPresignedUpload: (e) => b.gen(function* () {
|
|
1630
1729
|
if (!a.getUploadUrl) return yield* b.fail(new t({
|
|
1631
1730
|
provider: a.name,
|
|
@@ -1633,10 +1732,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1633
1732
|
transient: !1,
|
|
1634
1733
|
status: 400
|
|
1635
1734
|
}));
|
|
1636
|
-
let n = e.expiresInSec ?? d, r = `_incoming/${
|
|
1735
|
+
let n = e.expiresInSec ?? d, r = `_incoming/${A({
|
|
1637
1736
|
kind: "typeid",
|
|
1638
1737
|
prefix: "up"
|
|
1639
|
-
},
|
|
1738
|
+
}, W)}`, i = m(e.tenantId ?? null, "", r);
|
|
1640
1739
|
return {
|
|
1641
1740
|
uploadUrl: yield* a.getUploadUrl(i, n, e.contentType),
|
|
1642
1741
|
key: i,
|
|
@@ -1697,10 +1796,10 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1697
1796
|
transient: !1,
|
|
1698
1797
|
status: 400
|
|
1699
1798
|
}));
|
|
1700
|
-
let n = m(e.tenantId ?? null, "", `multipart/${
|
|
1799
|
+
let n = m(e.tenantId ?? null, "", `multipart/${A({
|
|
1701
1800
|
kind: "typeid",
|
|
1702
1801
|
prefix: "mp"
|
|
1703
|
-
},
|
|
1802
|
+
}, W)}`);
|
|
1704
1803
|
return {
|
|
1705
1804
|
uploadId: (yield* a.createMultipartUpload(n, e.contentType, { public: (e.visibility ?? "private") === "public" })).uploadId,
|
|
1706
1805
|
key: n
|
|
@@ -1728,7 +1827,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
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,
|
|
@@ -1749,7 +1848,7 @@ var _e = 1 << 20, ve = (e, n, r = !1) => new t({
|
|
|
1749
1848
|
}),
|
|
1750
1849
|
abortMultipart: (e) => b.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(b.retry(p)) : b.void)
|
|
1751
1850
|
};
|
|
1752
|
-
},
|
|
1851
|
+
}, Gt = (e) => S.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 = q.read("CLAMAV_HOST", t.host) ?? "127.0.0.1", i = q.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 = fe(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 pe(H(_e(), "voltro-tc-")), a = H(i, "in"), o = [];
|
|
1810
1909
|
try {
|
|
1811
|
-
await
|
|
1910
|
+
await ge(a, t);
|
|
1812
1911
|
for (let t of e.renditions) {
|
|
1813
|
-
let e =
|
|
1912
|
+
let e = H(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 me(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 he(e, { force: !0 });
|
|
1829
1928
|
} catch {}
|
|
1830
1929
|
}
|
|
1831
1930
|
} finally {
|
|
1832
|
-
await
|
|
1931
|
+
await he(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 ? L().externalId() : ce(() => Oe, { onDelete: e.onDelete ?? "setNull" });
|
|
1843
1942
|
return t ? n.nullable() : n;
|
|
1844
1943
|
}
|
|
1845
|
-
var
|
|
1944
|
+
var $t = () => P({
|
|
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
|
-
},
|
|
1962
|
+
}, nn = (e, n) => b.gen(function* () {
|
|
1864
1963
|
let r = yield* b.try({
|
|
1865
|
-
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 = I("_voltro_storage_put_intents", {
|
|
1981
|
+
id: L().maxLength(64),
|
|
1982
|
+
refId: L().maxLength(64),
|
|
1983
|
+
identity: N(),
|
|
1984
|
+
ref: N()
|
|
1985
|
+
}).primaryKey(["id"]).unique("storagePutRef", ["refId"]).nonReactive();
|
|
1986
|
+
w.Struct({
|
|
1987
|
+
tenantId: w.NullOr(w.String),
|
|
1988
|
+
bucket: w.String,
|
|
1989
|
+
operationId: w.String,
|
|
1990
|
+
fingerprint: w.String,
|
|
1991
|
+
checksum: w.String,
|
|
1992
|
+
logicalKey: w.String
|
|
1993
|
+
});
|
|
1994
|
+
//#endregion
|
|
1995
|
+
//#region src/pathDurability.ts
|
|
1996
|
+
var an = (e) => {
|
|
1882
1997
|
try {
|
|
1883
|
-
let t =
|
|
1998
|
+
let t = U(e), n = U("/");
|
|
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 = q.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", cn, ln = (e) => {
|
|
2008
|
+
cn = e;
|
|
2009
|
+
}, un = () => cn ?? fn({}), dn = () => cn === void 0 ? q.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 ?? q.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = q.read("S3_BUCKET", e.bucket) ?? q.read("STORAGE_BUCKET") ?? "voltro";
|
|
1897
2012
|
switch (t) {
|
|
1898
2013
|
case "s3":
|
|
1899
2014
|
case "minio": {
|
|
1900
|
-
let r =
|
|
1901
|
-
return
|
|
2015
|
+
let r = q.read("S3_REGION", e.region) ?? q.read("AWS_REGION"), i = q.read("S3_ENDPOINT", e.endpoint) ?? q.read("MINIO_ENDPOINT"), a = q.read("S3_ACCESS_KEY_ID", e.accessKeyId) ?? q.read("AWS_ACCESS_KEY_ID"), o = q.read("S3_SECRET_ACCESS_KEY", e.secretAccessKey) ?? q.read("AWS_SECRET_ACCESS_KEY"), s = q.read("STORAGE_CDN_URL", e.cdnBaseUrl);
|
|
2016
|
+
return Re({
|
|
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" || q.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 = q.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = q.read("AZURE_STORAGE_KEY", e.accountKey), i = q.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString), a = q.read("AZURE_STORAGE_ENDPOINT", e.endpoint), o = q.read("STORAGE_CDN_URL", e.cdnBaseUrl);
|
|
2030
|
+
return Ve({
|
|
2031
|
+
container: q.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 Be();
|
|
2040
|
+
case "filesystem": return Le({ root: q.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
|
|
2041
|
+
default: return Ie(e.name ?? "default");
|
|
1927
2042
|
}
|
|
1928
|
-
},
|
|
2043
|
+
}, pn = (e) => {
|
|
1929
2044
|
if (e !== void 0) return e;
|
|
1930
|
-
let t =
|
|
2045
|
+
let t = q.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") ? b.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(b.catchAll(() => b.fail(
|
|
2087
|
+
return (r.scopes ?? []).includes("admin:full") ? b.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(b.catchAll(() => b.fail(gn())), b.flatMap((e) => {
|
|
1973
2088
|
let t = e?.ownerId;
|
|
1974
|
-
return t != null && t === r.id ? b.void : b.fail(
|
|
2089
|
+
return t != null && t === r.id ? b.void : b.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 ? b.fail(
|
|
2098
|
+
return n === null && !t ? b.fail(vn()) : b.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,37 @@ 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
|
-
let y =
|
|
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 = (i = {}) => {
|
|
2112
|
+
let y = E({
|
|
2113
|
+
base: xn,
|
|
2114
|
+
alias: i.alias,
|
|
2115
|
+
instance: i.name
|
|
2116
|
+
}), x = y === xn ? "/_voltro/storage" : `/_voltro/storage/i/${Buffer.from(y).toString("hex")}`, S = fn(i);
|
|
2117
|
+
ln(S);
|
|
2118
|
+
let C = q.read("S3_BUCKET", i.bucket) ?? q.read("STORAGE_BUCKET") ?? "voltro", D = q.read("VOLTRO_PUBLIC_URL", i.publicBaseUrl), se = pn(i.allowedOrigins), O = i.limits?.maxBytes, k = i.anonymousUploads === !0, A = 5242880, j = 21600, M = i.refStore === void 0 || i.refStore === "memory", N = i.grantStore === void 0 || i.grantStore === "memory", P = { current: M ? Pt() : i.refStore }, F = { current: N ? zt() : i.grantStore }, ce = {
|
|
2119
|
+
insert: (e) => P.current.insert(e),
|
|
2120
|
+
getById: (e) => P.current.getById(e),
|
|
2121
|
+
delete: (e) => P.current.delete(e),
|
|
2122
|
+
statistics: () => P.current.statistics(),
|
|
2123
|
+
listRecent: (e) => P.current.listRecent(e),
|
|
2124
|
+
countByKey: (e, t) => P.current.countByKey(e, t),
|
|
2125
|
+
usageByTenant: (e) => P.current.usageByTenant(e),
|
|
2126
|
+
consumeUsage: (e, t, n) => P.current.consumeUsage(e, t, n),
|
|
2127
|
+
releaseUsage: (e, t) => P.current.releaseUsage(e, t),
|
|
2128
|
+
listByDerivedFrom: (e) => P.current.listByDerivedFrom(e),
|
|
2129
|
+
listRefs: (e) => P.current.listRefs(e)
|
|
2130
|
+
}, I = {
|
|
2131
|
+
insert: (e) => F.current.insert(e),
|
|
2132
|
+
delete: (e) => F.current.delete(e),
|
|
2133
|
+
getById: (e) => F.current.getById(e),
|
|
2134
|
+
listByRef: (e) => F.current.listByRef(e),
|
|
2135
|
+
deleteByRef: (e) => F.current.deleteByRef(e)
|
|
2136
|
+
}, L = {
|
|
2137
|
+
httpPath: x,
|
|
2138
|
+
provider: S,
|
|
2139
|
+
refStore: ce,
|
|
2140
|
+
grantStore: I,
|
|
2141
|
+
bucket: C,
|
|
2021
2142
|
...i.tenantPrefix === void 0 ? {} : { tenantPrefix: i.tenantPrefix },
|
|
2022
2143
|
...i.attempts === void 0 ? {} : { attempts: i.attempts },
|
|
2023
2144
|
...i.urlExpiresInSec === void 0 ? {} : { urlExpiresInSec: i.urlExpiresInSec },
|
|
@@ -2027,10 +2148,10 @@ var Gt = () => se({
|
|
|
2027
2148
|
...i.videoProbe === void 0 ? {} : { videoProbe: i.videoProbe },
|
|
2028
2149
|
...i.transcode === void 0 ? {} : { transcode: i.transcode },
|
|
2029
2150
|
...i.autoTranscode === void 0 ? {} : { autoTranscode: i.autoTranscode },
|
|
2030
|
-
...
|
|
2151
|
+
...D ? { publicBaseUrl: D } : {},
|
|
2031
2152
|
...i.normalizeImages === void 0 ? {} : { normalizeImages: i.normalizeImages },
|
|
2032
2153
|
...i.quota === void 0 ? {} : { quota: i.quota }
|
|
2033
|
-
},
|
|
2154
|
+
}, le = Gt(L), R = Wt(L), z = `${x}/`, B = (e) => b.runPromise(e.pipe(b.catchAll(() => b.succeed(null)))), de = (e, t) => {
|
|
2034
2155
|
if (!e) return "invalid";
|
|
2035
2156
|
let n = /^bytes=(\d*)-(\d*)$/.exec(e.trim());
|
|
2036
2157
|
if (!n) return "invalid";
|
|
@@ -2051,30 +2172,30 @@ var Gt = () => se({
|
|
|
2051
2172
|
start: a,
|
|
2052
2173
|
endInclusive: o
|
|
2053
2174
|
};
|
|
2054
|
-
},
|
|
2175
|
+
}, V = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, fe = (e) => ({
|
|
2055
2176
|
"x-content-type-options": "nosniff",
|
|
2056
|
-
"content-disposition":
|
|
2057
|
-
}),
|
|
2177
|
+
"content-disposition": V.test(e) ? "inline" : "attachment"
|
|
2178
|
+
}), pe = async (e, t, n, r) => {
|
|
2058
2179
|
if (n) {
|
|
2059
|
-
let r = await
|
|
2180
|
+
let r = await B(R.get(e.id));
|
|
2060
2181
|
if (!r) return {
|
|
2061
2182
|
status: 404,
|
|
2062
2183
|
body: "not found",
|
|
2063
2184
|
contentType: "text/plain"
|
|
2064
2185
|
};
|
|
2065
|
-
let i = await
|
|
2186
|
+
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
2187
|
return {
|
|
2067
2188
|
status: 200,
|
|
2068
2189
|
body: a,
|
|
2069
2190
|
contentType: o,
|
|
2070
2191
|
headers: {
|
|
2071
|
-
...
|
|
2192
|
+
...fe(o),
|
|
2072
2193
|
"cache-control": t,
|
|
2073
2194
|
"accept-ranges": "none"
|
|
2074
2195
|
}
|
|
2075
2196
|
};
|
|
2076
2197
|
}
|
|
2077
|
-
let i = r === void 0 ? "invalid" :
|
|
2198
|
+
let i = r === void 0 ? "invalid" : de(r, e.size);
|
|
2078
2199
|
if (i === "unsatisfiable") return {
|
|
2079
2200
|
status: 416,
|
|
2080
2201
|
body: "range not satisfiable",
|
|
@@ -2085,13 +2206,13 @@ var Gt = () => se({
|
|
|
2085
2206
|
}
|
|
2086
2207
|
};
|
|
2087
2208
|
if (i !== "invalid") {
|
|
2088
|
-
let n = await
|
|
2209
|
+
let n = await B(R.getRange(e.id, i));
|
|
2089
2210
|
return n ? {
|
|
2090
2211
|
status: 206,
|
|
2091
2212
|
body: n.bytes,
|
|
2092
2213
|
contentType: e.contentType,
|
|
2093
2214
|
headers: {
|
|
2094
|
-
...
|
|
2215
|
+
...fe(e.contentType),
|
|
2095
2216
|
"cache-control": t,
|
|
2096
2217
|
"accept-ranges": "bytes",
|
|
2097
2218
|
"content-range": `bytes ${i.start}-${i.endInclusive}/${n.totalSize}`
|
|
@@ -2102,75 +2223,64 @@ var Gt = () => se({
|
|
|
2102
2223
|
contentType: "text/plain"
|
|
2103
2224
|
};
|
|
2104
2225
|
}
|
|
2105
|
-
let a = await
|
|
2106
|
-
|
|
2107
|
-
status: 404,
|
|
2108
|
-
body: "not found",
|
|
2109
|
-
contentType: "text/plain"
|
|
2110
|
-
};
|
|
2111
|
-
let o = 1048576;
|
|
2112
|
-
return {
|
|
2226
|
+
let a = await B(R.getStream(e.id));
|
|
2227
|
+
return a ? {
|
|
2113
2228
|
status: 200,
|
|
2114
2229
|
contentType: e.contentType,
|
|
2115
2230
|
headers: {
|
|
2116
|
-
...
|
|
2231
|
+
...fe(e.contentType),
|
|
2117
2232
|
"cache-control": t,
|
|
2118
2233
|
"accept-ranges": "bytes"
|
|
2119
2234
|
},
|
|
2120
2235
|
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
|
-
}
|
|
2236
|
+
contentLength: e.size,
|
|
2237
|
+
stream: () => T.toReadableStream(a.stream)
|
|
2132
2238
|
}
|
|
2239
|
+
} : {
|
|
2240
|
+
status: 404,
|
|
2241
|
+
body: "not found",
|
|
2242
|
+
contentType: "text/plain"
|
|
2133
2243
|
};
|
|
2134
|
-
},
|
|
2135
|
-
let t = e.path.startsWith(
|
|
2244
|
+
}, me = async (e) => {
|
|
2245
|
+
let t = e.path.startsWith(z) ? e.path.slice(z.length).split("/")[0] ?? "" : "";
|
|
2136
2246
|
if (!t) return {
|
|
2137
2247
|
status: 404,
|
|
2138
2248
|
body: "not found",
|
|
2139
2249
|
contentType: "text/plain"
|
|
2140
2250
|
};
|
|
2141
|
-
let n = await
|
|
2251
|
+
let n = await B(R.head(t));
|
|
2142
2252
|
if (!n) return {
|
|
2143
2253
|
status: 404,
|
|
2144
2254
|
body: "not found",
|
|
2145
2255
|
contentType: "text/plain"
|
|
2146
2256
|
};
|
|
2147
|
-
let r =
|
|
2257
|
+
let r = Ue(e.query), i = e.headers.range;
|
|
2148
2258
|
if (n.visibility === "public") {
|
|
2149
|
-
let e =
|
|
2259
|
+
let e = S.publicUrl?.(n.key) ?? null;
|
|
2150
2260
|
return e && !r ? {
|
|
2151
2261
|
status: 302,
|
|
2152
2262
|
headers: {
|
|
2153
2263
|
location: e,
|
|
2154
2264
|
"cache-control": "public, max-age=300"
|
|
2155
2265
|
}
|
|
2156
|
-
} :
|
|
2266
|
+
} : pe(n, "public, max-age=31536000, immutable", r, i);
|
|
2157
2267
|
}
|
|
2158
2268
|
let a = !1, o = e.query ? new URLSearchParams(e.query).get("t") : null;
|
|
2159
2269
|
if (o) {
|
|
2160
|
-
let e =
|
|
2270
|
+
let e = dt(o);
|
|
2161
2271
|
a = !!e && e.refId === t;
|
|
2162
2272
|
}
|
|
2163
2273
|
if (!a) {
|
|
2164
|
-
let t =
|
|
2165
|
-
r && (a = await
|
|
2274
|
+
let t = ie(e.headers.cookie, sn), r = t ? oe(t, ae()) : null;
|
|
2275
|
+
r && (a = await B(R.checkAccess(n, r)) === !0);
|
|
2166
2276
|
}
|
|
2167
2277
|
if (!a) return {
|
|
2168
2278
|
status: 403,
|
|
2169
2279
|
body: "forbidden",
|
|
2170
2280
|
contentType: "text/plain"
|
|
2171
2281
|
};
|
|
2172
|
-
if (
|
|
2173
|
-
let e = await
|
|
2282
|
+
if (S.presigns && !r) {
|
|
2283
|
+
let e = await B(S.getUrl(n.key, 300));
|
|
2174
2284
|
if (e && /^https?:/.test(e)) return {
|
|
2175
2285
|
status: 302,
|
|
2176
2286
|
headers: {
|
|
@@ -2179,12 +2289,12 @@ var Gt = () => se({
|
|
|
2179
2289
|
}
|
|
2180
2290
|
};
|
|
2181
2291
|
}
|
|
2182
|
-
return
|
|
2183
|
-
},
|
|
2292
|
+
return pe(n, "private, no-store", r, i);
|
|
2293
|
+
}, he = {
|
|
2184
2294
|
method: "GET",
|
|
2185
|
-
path:
|
|
2295
|
+
path: x,
|
|
2186
2296
|
handle: async (e) => {
|
|
2187
|
-
let t = await
|
|
2297
|
+
let t = await me(e), n = mn(e.headers.origin, se);
|
|
2188
2298
|
return Object.keys(n).length === 0 ? t : {
|
|
2189
2299
|
...t,
|
|
2190
2300
|
headers: {
|
|
@@ -2193,12 +2303,12 @@ var Gt = () => se({
|
|
|
2193
2303
|
}
|
|
2194
2304
|
};
|
|
2195
2305
|
}
|
|
2196
|
-
},
|
|
2306
|
+
}, ge = {
|
|
2197
2307
|
method: "*",
|
|
2198
|
-
path:
|
|
2308
|
+
path: `${x}/upload`,
|
|
2199
2309
|
originGuard: "exempt",
|
|
2200
2310
|
handle: async (e) => {
|
|
2201
|
-
let t =
|
|
2311
|
+
let t = mn(e.headers.origin, se);
|
|
2202
2312
|
if (e.method === "OPTIONS") return {
|
|
2203
2313
|
status: 204,
|
|
2204
2314
|
headers: t
|
|
@@ -2209,8 +2319,8 @@ var Gt = () => se({
|
|
|
2209
2319
|
contentType: "text/plain",
|
|
2210
2320
|
headers: t
|
|
2211
2321
|
};
|
|
2212
|
-
let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ?
|
|
2213
|
-
if (!r) return {
|
|
2322
|
+
let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ? pt(n) : null;
|
|
2323
|
+
if (!r || r.instance !== y) return {
|
|
2214
2324
|
status: 401,
|
|
2215
2325
|
body: "invalid or expired upload ticket",
|
|
2216
2326
|
contentType: "text/plain",
|
|
@@ -2228,7 +2338,7 @@ var Gt = () => se({
|
|
|
2228
2338
|
contentType: "text/plain",
|
|
2229
2339
|
headers: t
|
|
2230
2340
|
};
|
|
2231
|
-
let i = await b.runPromise(
|
|
2341
|
+
let i = await b.runPromise(R.put({
|
|
2232
2342
|
bytes: e.rawBody,
|
|
2233
2343
|
contentType: r.ct,
|
|
2234
2344
|
tenantId: r.tenant,
|
|
@@ -2239,7 +2349,7 @@ var Gt = () => se({
|
|
|
2239
2349
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
2240
2350
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
2241
2351
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
2242
|
-
}).pipe(b.flatMap((e) =>
|
|
2352
|
+
}).pipe(b.flatMap((e) => R.getUrl(e.id).pipe(b.map((t) => ({
|
|
2243
2353
|
kind: "ok",
|
|
2244
2354
|
ref: e,
|
|
2245
2355
|
url: t
|
|
@@ -2285,25 +2395,25 @@ var Gt = () => se({
|
|
|
2285
2395
|
headers: t
|
|
2286
2396
|
};
|
|
2287
2397
|
}
|
|
2288
|
-
},
|
|
2398
|
+
}, _e = {
|
|
2289
2399
|
method: "*",
|
|
2290
|
-
path:
|
|
2400
|
+
path: `${x}/upload/resumable`,
|
|
2291
2401
|
originGuard: "exempt",
|
|
2292
2402
|
handle: async (e) => {
|
|
2293
|
-
let t =
|
|
2403
|
+
let t = mn(e.headers.origin, se);
|
|
2294
2404
|
if (e.method === "OPTIONS") return {
|
|
2295
2405
|
status: 204,
|
|
2296
2406
|
headers: t
|
|
2297
2407
|
};
|
|
2298
|
-
let n = new URLSearchParams(e.query || ""), r =
|
|
2299
|
-
if (!r) return {
|
|
2408
|
+
let n = new URLSearchParams(e.query || ""), r = _t(n.get("token") ?? "");
|
|
2409
|
+
if (!r || r.instance !== y) return {
|
|
2300
2410
|
status: 401,
|
|
2301
2411
|
body: "invalid or expired resumable token",
|
|
2302
2412
|
contentType: "text/plain",
|
|
2303
2413
|
headers: t
|
|
2304
2414
|
};
|
|
2305
2415
|
if (e.method === "GET" || e.method === "HEAD") {
|
|
2306
|
-
let e = await b.runPromise(
|
|
2416
|
+
let e = await b.runPromise(R.resumableStatus({
|
|
2307
2417
|
uploadId: r.id,
|
|
2308
2418
|
tenantId: r.tenant
|
|
2309
2419
|
}).pipe(b.match({
|
|
@@ -2344,12 +2454,12 @@ var Gt = () => se({
|
|
|
2344
2454
|
contentType: "text/plain",
|
|
2345
2455
|
headers: t
|
|
2346
2456
|
};
|
|
2347
|
-
let a = n.get("final") === "1", o = await b.runPromise(
|
|
2457
|
+
let a = n.get("final") === "1", o = await b.runPromise(R.putResumableChunk({
|
|
2348
2458
|
uploadId: r.id,
|
|
2349
2459
|
tenantId: r.tenant,
|
|
2350
2460
|
index: i,
|
|
2351
2461
|
bytes: e.rawBody
|
|
2352
|
-
}).pipe(b.flatMap(() => a ?
|
|
2462
|
+
}).pipe(b.flatMap(() => a ? R.finalizeResumable({
|
|
2353
2463
|
uploadId: r.id,
|
|
2354
2464
|
count: i + 1,
|
|
2355
2465
|
contentType: r.ct,
|
|
@@ -2360,7 +2470,7 @@ var Gt = () => se({
|
|
|
2360
2470
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
2361
2471
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
2362
2472
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
2363
|
-
}).pipe(b.flatMap((e) =>
|
|
2473
|
+
}).pipe(b.flatMap((e) => R.getUrl(e.id).pipe(b.map((t) => ({
|
|
2364
2474
|
kind: "done",
|
|
2365
2475
|
ref: e,
|
|
2366
2476
|
url: t
|
|
@@ -2412,57 +2522,117 @@ var Gt = () => se({
|
|
|
2412
2522
|
headers: t
|
|
2413
2523
|
};
|
|
2414
2524
|
}
|
|
2415
|
-
},
|
|
2525
|
+
}, H = (e) => ({
|
|
2416
2526
|
kind: "json",
|
|
2417
2527
|
data: e
|
|
2418
|
-
}),
|
|
2528
|
+
}), U = (e, t) => ({
|
|
2419
2529
|
kind: "json",
|
|
2420
2530
|
status: e,
|
|
2421
2531
|
data: { error: t }
|
|
2422
|
-
}),
|
|
2532
|
+
}), ve = (e, t) => {
|
|
2423
2533
|
try {
|
|
2424
2534
|
return new URL(e, "http://localhost").searchParams.get(t);
|
|
2425
2535
|
} catch {
|
|
2426
2536
|
return null;
|
|
2427
2537
|
}
|
|
2428
|
-
},
|
|
2538
|
+
}, ye = [
|
|
2539
|
+
{
|
|
2540
|
+
method: "POST",
|
|
2541
|
+
path: "/upload-ticket",
|
|
2542
|
+
description: "Authorize a binary upload with explicit tenant and owner attribution",
|
|
2543
|
+
handler: (e) => b.gen(function* () {
|
|
2544
|
+
let n = w.String.pipe(w.filter((e) => e.trim().length > 0)), r = yield* w.decodeUnknown(w.parseJson(w.Struct({
|
|
2545
|
+
tenantId: w.NullOr(n),
|
|
2546
|
+
ownerId: w.NullOr(n),
|
|
2547
|
+
key: n.pipe(w.maxLength(1024)),
|
|
2548
|
+
contentType: n.pipe(w.maxLength(255), w.filter((e) => !/[\r\n]/.test(e))),
|
|
2549
|
+
size: w.Number.pipe(w.int(), w.positive(), w.filter(Number.isSafeInteger)),
|
|
2550
|
+
visibility: w.optional(w.Literal("public", "private"))
|
|
2551
|
+
})))(e.body).pipe(b.mapError(() => new t({
|
|
2552
|
+
provider: "inspect",
|
|
2553
|
+
message: "Provide explicit tenantId and ownerId (or null), key, contentType and a positive file size",
|
|
2554
|
+
transient: !1,
|
|
2555
|
+
status: 400
|
|
2556
|
+
})));
|
|
2557
|
+
if (O !== void 0 && r.size > O) return U(413, "File exceeds the configured upload limit");
|
|
2558
|
+
let i = ft({
|
|
2559
|
+
instance: y,
|
|
2560
|
+
sub: r.ownerId,
|
|
2561
|
+
tenant: r.tenantId,
|
|
2562
|
+
ct: r.contentType,
|
|
2563
|
+
key: r.key,
|
|
2564
|
+
vis: r.visibility ?? "private",
|
|
2565
|
+
max: r.size
|
|
2566
|
+
}, 300);
|
|
2567
|
+
return H({
|
|
2568
|
+
uploadPath: `${x}/upload?ticket=${encodeURIComponent(i)}`,
|
|
2569
|
+
expiresInSec: 300,
|
|
2570
|
+
maxBytes: r.size
|
|
2571
|
+
});
|
|
2572
|
+
}).pipe(b.catchAll((e) => b.succeed(U(e.status ?? 500, e.message))))
|
|
2573
|
+
},
|
|
2574
|
+
{
|
|
2575
|
+
method: "GET",
|
|
2576
|
+
path: "/download",
|
|
2577
|
+
description: "Stream a stored file as an attachment for authorized inspect readers",
|
|
2578
|
+
handler: (e) => b.gen(function* () {
|
|
2579
|
+
let t = ve(e.url, "refId");
|
|
2580
|
+
if (!t?.trim()) return U(400, "A non-empty refId is required");
|
|
2581
|
+
let { ref: n, stream: r } = yield* R.getStream(t), i = n.key.split("/").pop() || n.id, a = encodeURIComponent(i).replace(/[!'()*]/g, (e) => `%${e.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
2582
|
+
return {
|
|
2583
|
+
kind: "bytes",
|
|
2584
|
+
contentType: n.contentType,
|
|
2585
|
+
byteStream: {
|
|
2586
|
+
stream: () => T.toReadableStream(r),
|
|
2587
|
+
contentLength: n.size,
|
|
2588
|
+
contentDisposition: `attachment; filename="download"; filename*=UTF-8''${a}`
|
|
2589
|
+
},
|
|
2590
|
+
headers: { "cache-control": "no-store" }
|
|
2591
|
+
};
|
|
2592
|
+
}).pipe(b.catchAll((e) => b.succeed(U(e.status ?? 500, e.message))))
|
|
2593
|
+
},
|
|
2429
2594
|
{
|
|
2430
2595
|
method: "GET",
|
|
2431
2596
|
path: "/refs",
|
|
2432
|
-
description: "
|
|
2433
|
-
handler: (
|
|
2597
|
+
description: "Searchable storage refs, newest first, paginated",
|
|
2598
|
+
handler: (e) => {
|
|
2599
|
+
let t = Number(ve(e.url, "offset") ?? 0), n = Number.isSafeInteger(t) && t >= 0 ? t : 0, r = (ve(e.url, "search") ?? "").trim().slice(0, 200);
|
|
2600
|
+
return ce.listRefs({
|
|
2601
|
+
tenantId: void 0,
|
|
2602
|
+
ownerId: void 0,
|
|
2603
|
+
folder: void 0,
|
|
2604
|
+
tags: [],
|
|
2605
|
+
includeDerived: !0,
|
|
2606
|
+
search: r,
|
|
2607
|
+
limit: 51,
|
|
2608
|
+
offset: n
|
|
2609
|
+
}).pipe(b.map((e) => H({
|
|
2610
|
+
refs: e.slice(0, 50).map(hn),
|
|
2611
|
+
page: {
|
|
2612
|
+
search: r,
|
|
2613
|
+
offset: n,
|
|
2614
|
+
nextOffset: e.length > 50 ? n + 50 : null
|
|
2615
|
+
}
|
|
2616
|
+
})), b.catchAll((e) => b.succeed(U(500, e.message))));
|
|
2617
|
+
}
|
|
2434
2618
|
},
|
|
2435
2619
|
{
|
|
2436
2620
|
method: "GET",
|
|
2437
2621
|
path: "/stats",
|
|
2438
2622
|
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))))
|
|
2623
|
+
handler: () => ce.statistics().pipe(b.map((e) => H({
|
|
2624
|
+
provider: S.name,
|
|
2625
|
+
bucket: C,
|
|
2626
|
+
...e
|
|
2627
|
+
})), b.catchAll((e) => b.succeed(U(500, e.message))))
|
|
2458
2628
|
},
|
|
2459
2629
|
{
|
|
2460
2630
|
method: "GET",
|
|
2461
2631
|
path: "/grants",
|
|
2462
2632
|
description: "Grants for a ref (?refId=…)",
|
|
2463
2633
|
handler: (e) => {
|
|
2464
|
-
let t =
|
|
2465
|
-
return t ?
|
|
2634
|
+
let t = ve(e.url, "refId");
|
|
2635
|
+
return t ? I.listByRef(t).pipe(b.map((e) => H({ grants: e.map(bn) })), b.catchAll((e) => b.succeed(U(500, e.message)))) : b.succeed(U(400, "refId query param required"));
|
|
2466
2636
|
}
|
|
2467
2637
|
},
|
|
2468
2638
|
{
|
|
@@ -2470,49 +2640,63 @@ var Gt = () => se({
|
|
|
2470
2640
|
path: "/share",
|
|
2471
2641
|
description: "Grant a principal access to a ref",
|
|
2472
2642
|
handler: (e) => b.gen(function* () {
|
|
2473
|
-
let n = yield*
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2643
|
+
let n = yield* w.decodeUnknown(w.parseJson(w.Struct({
|
|
2644
|
+
refId: w.String.pipe(w.filter((e) => e.trim().length > 0)),
|
|
2645
|
+
principalType: w.Literal("user", "group", "apiKey"),
|
|
2646
|
+
principalId: w.String.pipe(w.filter((e) => e.trim().length > 0)),
|
|
2647
|
+
permission: w.optional(w.Literal("read", "write")),
|
|
2648
|
+
expiresInDays: w.optional(w.Number.pipe(w.finite(), w.positive()))
|
|
2649
|
+
})))(e.body).pipe(b.mapError(() => new t({
|
|
2650
|
+
provider: "inspect",
|
|
2651
|
+
message: "Invalid share input: provide refId, principalType, principalId, read/write permission and a positive finite expiry if set",
|
|
2652
|
+
transient: !1,
|
|
2653
|
+
status: 400
|
|
2654
|
+
}))), r = n.expiresInDays === void 0 ? null : new Date(Date.now() + n.expiresInDays * 864e5);
|
|
2655
|
+
if (r !== null && !Number.isFinite(r.getTime())) return U(400, "Expiry exceeds the supported date range");
|
|
2656
|
+
let i = yield* R.grant({
|
|
2484
2657
|
refId: n.refId,
|
|
2485
2658
|
principalType: n.principalType,
|
|
2486
2659
|
principalId: n.principalId,
|
|
2487
2660
|
...n.permission ? { permission: n.permission } : {},
|
|
2488
2661
|
expiresAt: r
|
|
2489
2662
|
});
|
|
2490
|
-
return
|
|
2491
|
-
}).pipe(b.catchAll((e) => b.succeed(
|
|
2663
|
+
return H({ grant: bn(i) });
|
|
2664
|
+
}).pipe(b.catchAll((e) => b.succeed(U(e.status ?? 500, e.message ?? "share failed"))))
|
|
2665
|
+
},
|
|
2666
|
+
{
|
|
2667
|
+
method: "POST",
|
|
2668
|
+
path: "/delete",
|
|
2669
|
+
description: "Delete an object reference and its grants; release unreferenced bytes",
|
|
2670
|
+
handler: (e) => b.gen(function* () {
|
|
2671
|
+
let n = yield* w.decodeUnknown(w.parseJson(w.Struct({ refId: w.String.pipe(w.filter((e) => e.trim().length > 0)) })))(e.body).pipe(b.mapError(() => new t({
|
|
2672
|
+
provider: "inspect",
|
|
2673
|
+
message: "A non-empty refId is required",
|
|
2674
|
+
transient: !1,
|
|
2675
|
+
status: 400
|
|
2676
|
+
})));
|
|
2677
|
+
return yield* R.delete(n.refId), H({ ok: !0 });
|
|
2678
|
+
}).pipe(b.catchAll((e) => b.succeed(U(e.status ?? 500, e.message))))
|
|
2492
2679
|
},
|
|
2493
2680
|
{
|
|
2494
2681
|
method: "POST",
|
|
2495
2682
|
path: "/revoke",
|
|
2496
2683
|
description: "Revoke a grant by id",
|
|
2497
2684
|
handler: (e) => b.gen(function* () {
|
|
2498
|
-
let n = yield* b.
|
|
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"))))
|
|
2685
|
+
let n = yield* w.decodeUnknown(w.parseJson(w.Struct({ grantId: w.String.pipe(w.filter((e) => e.trim().length > 0)) })))(e.body).pipe(b.mapError(() => new t({
|
|
2686
|
+
provider: "inspect",
|
|
2687
|
+
message: "A non-empty grantId is required",
|
|
2688
|
+
transient: !1,
|
|
2689
|
+
status: 400
|
|
2690
|
+
})));
|
|
2691
|
+
return yield* R.revoke(n.grantId), H({ ok: !0 });
|
|
2692
|
+
}).pipe(b.catchAll((e) => b.succeed(U(e.status ?? 500, e.message ?? "revoke failed"))))
|
|
2509
2693
|
}
|
|
2510
|
-
],
|
|
2694
|
+
], be = [
|
|
2511
2695
|
{
|
|
2512
2696
|
...h,
|
|
2513
2697
|
execute: (e, t) => {
|
|
2514
2698
|
let n = e;
|
|
2515
|
-
return
|
|
2699
|
+
return R.mintUrl(n.id, t.request.subject, {
|
|
2516
2700
|
...n.password === void 0 ? {} : { password: n.password },
|
|
2517
2701
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
2518
2702
|
}).pipe(b.map((e) => ({ url: e })));
|
|
@@ -2522,7 +2706,7 @@ var Gt = () => se({
|
|
|
2522
2706
|
...ee,
|
|
2523
2707
|
execute: (e, t) => {
|
|
2524
2708
|
let n = e;
|
|
2525
|
-
return
|
|
2709
|
+
return R.mintUploadUrl({
|
|
2526
2710
|
key: n.key,
|
|
2527
2711
|
contentType: n.contentType,
|
|
2528
2712
|
tenantId: t.request.subject.tenantId,
|
|
@@ -2534,8 +2718,9 @@ var Gt = () => se({
|
|
|
2534
2718
|
...m,
|
|
2535
2719
|
execute: (e, t) => {
|
|
2536
2720
|
let n = e;
|
|
2537
|
-
return $(t,
|
|
2538
|
-
let t = n.expiresInSec ?? 900, r =
|
|
2721
|
+
return $(t, k).pipe(b.map((e) => {
|
|
2722
|
+
let t = n.expiresInSec ?? 900, r = ft({
|
|
2723
|
+
instance: y,
|
|
2539
2724
|
sub: e.id,
|
|
2540
2725
|
tenant: e.tenantId,
|
|
2541
2726
|
ct: n.contentType,
|
|
@@ -2545,10 +2730,10 @@ var Gt = () => se({
|
|
|
2545
2730
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
2546
2731
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2547
2732
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2548
|
-
...
|
|
2733
|
+
...O === void 0 ? {} : { max: O }
|
|
2549
2734
|
}, t);
|
|
2550
2735
|
return {
|
|
2551
|
-
uploadUrl: `${
|
|
2736
|
+
uploadUrl: `${D ? D.replace(/\/+$/, "") : ""}${x}/upload?ticket=${encodeURIComponent(r)}`,
|
|
2552
2737
|
expiresInSec: t
|
|
2553
2738
|
};
|
|
2554
2739
|
}));
|
|
@@ -2558,12 +2743,13 @@ var Gt = () => se({
|
|
|
2558
2743
|
...p,
|
|
2559
2744
|
execute: (e, t) => {
|
|
2560
2745
|
let n = e;
|
|
2561
|
-
return $(t,
|
|
2746
|
+
return $(t, k).pipe(b.flatMap((e) => R.mintPresignedUpload({
|
|
2562
2747
|
contentType: n.contentType,
|
|
2563
2748
|
tenantId: e.tenantId,
|
|
2564
2749
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
2565
2750
|
}).pipe(b.map((t) => {
|
|
2566
|
-
let r =
|
|
2751
|
+
let r = mt({
|
|
2752
|
+
instance: y,
|
|
2567
2753
|
key: t.key,
|
|
2568
2754
|
sub: e.id,
|
|
2569
2755
|
tenant: e.tenantId,
|
|
@@ -2573,7 +2759,7 @@ var Gt = () => se({
|
|
|
2573
2759
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
2574
2760
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2575
2761
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2576
|
-
...
|
|
2762
|
+
...O === void 0 ? {} : { max: O }
|
|
2577
2763
|
}, t.expiresInSec);
|
|
2578
2764
|
return {
|
|
2579
2765
|
uploadUrl: t.uploadUrl,
|
|
@@ -2586,13 +2772,18 @@ var Gt = () => se({
|
|
|
2586
2772
|
{
|
|
2587
2773
|
...l,
|
|
2588
2774
|
execute: (e, n) => {
|
|
2589
|
-
let r =
|
|
2590
|
-
return r
|
|
2775
|
+
let r = ht(e.finalizeToken);
|
|
2776
|
+
return !r || r.instance !== y ? b.fail(new t({
|
|
2777
|
+
provider: "storage",
|
|
2778
|
+
message: "invalid or expired finalize token",
|
|
2779
|
+
transient: !1,
|
|
2780
|
+
status: 401
|
|
2781
|
+
})) : yn(r.sub, n.request.subject.id) ? b.fail(new t({
|
|
2591
2782
|
provider: "storage",
|
|
2592
2783
|
message: "finalize token belongs to another subject",
|
|
2593
2784
|
transient: !1,
|
|
2594
2785
|
status: 403
|
|
2595
|
-
})) :
|
|
2786
|
+
})) : R.finalizeUpload({
|
|
2596
2787
|
key: r.key,
|
|
2597
2788
|
contentType: r.ct,
|
|
2598
2789
|
tenantId: r.tenant,
|
|
@@ -2602,30 +2793,26 @@ var Gt = () => se({
|
|
|
2602
2793
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
2603
2794
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
2604
2795
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
2605
|
-
}).pipe(b.flatMap((e) =>
|
|
2796
|
+
}).pipe(b.flatMap((e) => R.getUrl(e.id).pipe(b.map((t) => ({
|
|
2606
2797
|
id: e.id,
|
|
2607
2798
|
url: t,
|
|
2608
2799
|
contentType: e.contentType,
|
|
2609
2800
|
size: e.size,
|
|
2610
2801
|
...e.width == null ? {} : { width: e.width },
|
|
2611
2802
|
...e.height == null ? {} : { height: e.height }
|
|
2612
|
-
})))))
|
|
2613
|
-
provider: "storage",
|
|
2614
|
-
message: "invalid or expired finalize token",
|
|
2615
|
-
transient: !1,
|
|
2616
|
-
status: 401
|
|
2617
|
-
}));
|
|
2803
|
+
})))));
|
|
2618
2804
|
}
|
|
2619
2805
|
},
|
|
2620
2806
|
{
|
|
2621
2807
|
...s,
|
|
2622
2808
|
execute: (e, t) => {
|
|
2623
2809
|
let n = e;
|
|
2624
|
-
return $(t,
|
|
2625
|
-
let t = n.expiresInSec ??
|
|
2810
|
+
return $(t, k).pipe(b.map((e) => {
|
|
2811
|
+
let t = n.expiresInSec ?? j, r = ue(), i = n.chunkSize && n.chunkSize > 0 ? n.chunkSize : A;
|
|
2626
2812
|
return {
|
|
2627
2813
|
uploadId: r,
|
|
2628
|
-
resumableToken:
|
|
2814
|
+
resumableToken: gt({
|
|
2815
|
+
instance: y,
|
|
2629
2816
|
id: r,
|
|
2630
2817
|
sub: e.id,
|
|
2631
2818
|
tenant: e.tenantId,
|
|
@@ -2636,9 +2823,9 @@ var Gt = () => se({
|
|
|
2636
2823
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
2637
2824
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2638
2825
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2639
|
-
...
|
|
2826
|
+
...O === void 0 ? {} : { max: O }
|
|
2640
2827
|
}, t),
|
|
2641
|
-
uploadUrl: `${
|
|
2828
|
+
uploadUrl: `${D ? D.replace(/\/+$/, "") : ""}${x}/upload/resumable`,
|
|
2642
2829
|
chunkSize: i,
|
|
2643
2830
|
expiresInSec: t
|
|
2644
2831
|
};
|
|
@@ -2648,14 +2835,15 @@ var Gt = () => se({
|
|
|
2648
2835
|
{
|
|
2649
2836
|
...o,
|
|
2650
2837
|
execute: (e, t) => {
|
|
2651
|
-
let n = e, r = n.expiresInSec ??
|
|
2652
|
-
return $(t,
|
|
2838
|
+
let n = e, r = n.expiresInSec ?? j;
|
|
2839
|
+
return $(t, k).pipe(b.flatMap((e) => R.beginMultipartUpload({
|
|
2653
2840
|
contentType: n.contentType,
|
|
2654
2841
|
tenantId: e.tenantId,
|
|
2655
2842
|
visibility: n.visibility ?? "private",
|
|
2656
2843
|
expiresInSec: r
|
|
2657
2844
|
}).pipe(b.map((t) => ({
|
|
2658
|
-
multipartToken:
|
|
2845
|
+
multipartToken: vt({
|
|
2846
|
+
instance: y,
|
|
2659
2847
|
key: t.key,
|
|
2660
2848
|
uploadId: t.uploadId,
|
|
2661
2849
|
sub: e.id,
|
|
@@ -2668,7 +2856,7 @@ var Gt = () => se({
|
|
|
2668
2856
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2669
2857
|
...n.caption === void 0 ? {} : { caption: n.caption }
|
|
2670
2858
|
}, r),
|
|
2671
|
-
partSize: n.partSize && n.partSize >=
|
|
2859
|
+
partSize: n.partSize && n.partSize >= A ? n.partSize : A,
|
|
2672
2860
|
expiresInSec: r
|
|
2673
2861
|
})))));
|
|
2674
2862
|
}
|
|
@@ -2676,34 +2864,39 @@ var Gt = () => se({
|
|
|
2676
2864
|
{
|
|
2677
2865
|
...te,
|
|
2678
2866
|
execute: (e) => {
|
|
2679
|
-
let n = e, r =
|
|
2680
|
-
return r
|
|
2867
|
+
let n = e, r = yt(n.multipartToken);
|
|
2868
|
+
return !r || r.instance !== y ? b.fail(new t({
|
|
2869
|
+
provider: "storage",
|
|
2870
|
+
message: "invalid or expired multipart token",
|
|
2871
|
+
transient: !1,
|
|
2872
|
+
status: 401
|
|
2873
|
+
})) : !Number.isInteger(n.partNumber) || n.partNumber < 1 ? b.fail(new t({
|
|
2681
2874
|
provider: "storage",
|
|
2682
2875
|
message: "partNumber must be a positive integer",
|
|
2683
2876
|
transient: !1,
|
|
2684
2877
|
status: 400
|
|
2685
|
-
})) :
|
|
2878
|
+
})) : R.signMultipartPart({
|
|
2686
2879
|
key: r.key,
|
|
2687
2880
|
uploadId: r.uploadId,
|
|
2688
2881
|
partNumber: n.partNumber
|
|
2689
|
-
}).pipe(b.map((e) => ({ url: e })))
|
|
2690
|
-
provider: "storage",
|
|
2691
|
-
message: "invalid or expired multipart token",
|
|
2692
|
-
transient: !1,
|
|
2693
|
-
status: 401
|
|
2694
|
-
}));
|
|
2882
|
+
}).pipe(b.map((e) => ({ url: e })));
|
|
2695
2883
|
}
|
|
2696
2884
|
},
|
|
2697
2885
|
{
|
|
2698
2886
|
...c,
|
|
2699
2887
|
execute: (e, n) => {
|
|
2700
|
-
let r = e, i =
|
|
2701
|
-
return i
|
|
2888
|
+
let r = e, i = yt(r.multipartToken);
|
|
2889
|
+
return !i || i.instance !== y ? b.fail(new t({
|
|
2890
|
+
provider: "storage",
|
|
2891
|
+
message: "invalid or expired multipart token",
|
|
2892
|
+
transient: !1,
|
|
2893
|
+
status: 401
|
|
2894
|
+
})) : yn(i.sub, n.request.subject.id) ? b.fail(new t({
|
|
2702
2895
|
provider: "storage",
|
|
2703
2896
|
message: "multipart token belongs to another subject",
|
|
2704
2897
|
transient: !1,
|
|
2705
2898
|
status: 403
|
|
2706
|
-
})) :
|
|
2899
|
+
})) : R.completeMultipart({
|
|
2707
2900
|
key: i.key,
|
|
2708
2901
|
uploadId: i.uploadId,
|
|
2709
2902
|
parts: r.parts,
|
|
@@ -2715,38 +2908,33 @@ var Gt = () => se({
|
|
|
2715
2908
|
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
2716
2909
|
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
2717
2910
|
...i.caption === void 0 ? {} : { caption: i.caption }
|
|
2718
|
-
}).pipe(b.flatMap((e) =>
|
|
2911
|
+
}).pipe(b.flatMap((e) => R.getUrl(e.id).pipe(b.map((t) => ({
|
|
2719
2912
|
id: e.id,
|
|
2720
2913
|
url: t,
|
|
2721
2914
|
size: e.size
|
|
2722
|
-
})))))
|
|
2723
|
-
provider: "storage",
|
|
2724
|
-
message: "invalid or expired multipart token",
|
|
2725
|
-
transient: !1,
|
|
2726
|
-
status: 401
|
|
2727
|
-
}));
|
|
2915
|
+
})))));
|
|
2728
2916
|
}
|
|
2729
2917
|
},
|
|
2730
2918
|
{
|
|
2731
2919
|
...a,
|
|
2732
2920
|
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({
|
|
2921
|
+
let n = yt(e.multipartToken);
|
|
2922
|
+
return !n || n.instance !== y ? b.fail(new t({
|
|
2738
2923
|
provider: "storage",
|
|
2739
2924
|
message: "invalid or expired multipart token",
|
|
2740
2925
|
transient: !1,
|
|
2741
2926
|
status: 401
|
|
2742
|
-
}))
|
|
2927
|
+
})) : R.abortMultipart({
|
|
2928
|
+
key: n.key,
|
|
2929
|
+
uploadId: n.uploadId
|
|
2930
|
+
}).pipe(b.as({ ok: !0 }));
|
|
2743
2931
|
}
|
|
2744
2932
|
},
|
|
2745
2933
|
{
|
|
2746
2934
|
...v,
|
|
2747
2935
|
execute: (e, t) => {
|
|
2748
2936
|
let n = e, r = new Uint8Array(Buffer.from(n.bytesBase64, "base64"));
|
|
2749
|
-
return $(t,
|
|
2937
|
+
return $(t, k).pipe(b.flatMap((e) => R.put({
|
|
2750
2938
|
bytes: r,
|
|
2751
2939
|
contentType: n.contentType,
|
|
2752
2940
|
tenantId: e.tenantId,
|
|
@@ -2754,7 +2942,7 @@ var Gt = () => se({
|
|
|
2754
2942
|
...n.visibility ? { visibility: n.visibility } : {},
|
|
2755
2943
|
...n.key ? { key: n.key } : {},
|
|
2756
2944
|
...n.password ? { password: n.password } : {}
|
|
2757
|
-
})), b.flatMap((e) =>
|
|
2945
|
+
})), b.flatMap((e) => R.getUrl(e.id).pipe(b.map((t) => ({
|
|
2758
2946
|
id: e.id,
|
|
2759
2947
|
url: t
|
|
2760
2948
|
})))));
|
|
@@ -2764,7 +2952,7 @@ var Gt = () => se({
|
|
|
2764
2952
|
...u,
|
|
2765
2953
|
execute: (e, t) => {
|
|
2766
2954
|
let n = e;
|
|
2767
|
-
return $(t,
|
|
2955
|
+
return $(t, k).pipe(b.flatMap((e) => R.ingestUrl(n.url, {
|
|
2768
2956
|
tenantId: e.tenantId,
|
|
2769
2957
|
ownerId: e.id,
|
|
2770
2958
|
...n.visibility ? { visibility: n.visibility } : {},
|
|
@@ -2773,7 +2961,7 @@ var Gt = () => se({
|
|
|
2773
2961
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2774
2962
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2775
2963
|
...n.key === void 0 ? {} : { key: n.key }
|
|
2776
|
-
})), b.flatMap((e) =>
|
|
2964
|
+
})), b.flatMap((e) => R.getUrl(e.id).pipe(b.map((t) => ({
|
|
2777
2965
|
id: e.id,
|
|
2778
2966
|
url: t
|
|
2779
2967
|
})))));
|
|
@@ -2783,7 +2971,7 @@ var Gt = () => se({
|
|
|
2783
2971
|
..._,
|
|
2784
2972
|
execute: (e, t) => {
|
|
2785
2973
|
let n = e, r = n.expiresInDays ? new Date(Date.now() + n.expiresInDays * 864e5) : null;
|
|
2786
|
-
return
|
|
2974
|
+
return _n(R, n.refId, t).pipe(b.flatMap(() => R.grant({
|
|
2787
2975
|
refId: n.refId,
|
|
2788
2976
|
principalType: n.principalType,
|
|
2789
2977
|
principalId: n.principalId,
|
|
@@ -2797,21 +2985,21 @@ var Gt = () => se({
|
|
|
2797
2985
|
...g,
|
|
2798
2986
|
execute: (e, t) => {
|
|
2799
2987
|
let n = e;
|
|
2800
|
-
return
|
|
2988
|
+
return R.getGrant(n.grantId).pipe(b.flatMap((e) => e === null ? b.fail(gn()) : _n(R, e.refId, t)), b.flatMap(() => R.revoke(n.grantId)), b.map(() => ({ ok: !0 })));
|
|
2801
2989
|
}
|
|
2802
2990
|
},
|
|
2803
2991
|
{
|
|
2804
2992
|
...d,
|
|
2805
2993
|
execute: (e, t) => {
|
|
2806
2994
|
let n = e;
|
|
2807
|
-
return
|
|
2995
|
+
return _n(R, n.refId, t).pipe(b.flatMap(() => R.listGrants(n.refId)), b.map((e) => ({ grants: e.map(bn) })));
|
|
2808
2996
|
}
|
|
2809
2997
|
},
|
|
2810
2998
|
{
|
|
2811
2999
|
...f,
|
|
2812
3000
|
execute: (e, t) => {
|
|
2813
3001
|
let n = e;
|
|
2814
|
-
return
|
|
3002
|
+
return R.listRefs({
|
|
2815
3003
|
tenantId: t.request.subject.tenantId,
|
|
2816
3004
|
...n.folder === void 0 ? {} : { folder: n.folder },
|
|
2817
3005
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
@@ -2820,34 +3008,34 @@ var Gt = () => se({
|
|
|
2820
3008
|
...n.limit === void 0 ? {} : { limit: n.limit },
|
|
2821
3009
|
...n.offset === void 0 ? {} : { offset: n.offset }
|
|
2822
3010
|
}).pipe(b.map((e) => ({
|
|
2823
|
-
refs: e.refs.map(
|
|
3011
|
+
refs: e.refs.map(hn),
|
|
2824
3012
|
nextOffset: e.nextOffset
|
|
2825
3013
|
})));
|
|
2826
3014
|
}
|
|
2827
3015
|
}
|
|
2828
3016
|
];
|
|
2829
|
-
return
|
|
2830
|
-
name:
|
|
2831
|
-
base:
|
|
3017
|
+
return re({
|
|
3018
|
+
name: E({
|
|
3019
|
+
base: xn,
|
|
2832
3020
|
alias: i.alias,
|
|
2833
3021
|
instance: i.name
|
|
2834
3022
|
}),
|
|
2835
|
-
baseName:
|
|
3023
|
+
baseName: xn,
|
|
2836
3024
|
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
3025
|
permissions: [
|
|
2838
3026
|
"network:outbound:*",
|
|
2839
3027
|
"inspect:read",
|
|
2840
3028
|
"inspect:write"
|
|
2841
3029
|
],
|
|
2842
|
-
declaredEnv:
|
|
2843
|
-
services:
|
|
2844
|
-
inspectEndpoints:
|
|
3030
|
+
declaredEnv: q.declared,
|
|
3031
|
+
services: le,
|
|
3032
|
+
inspectEndpoints: ye,
|
|
2845
3033
|
httpRoutes: [
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
3034
|
+
he,
|
|
3035
|
+
ge,
|
|
3036
|
+
_e
|
|
2849
3037
|
],
|
|
2850
|
-
routes:
|
|
3038
|
+
routes: be,
|
|
2851
3039
|
rpcClientDescriptors: ne,
|
|
2852
3040
|
errorSchemas: [
|
|
2853
3041
|
{
|
|
@@ -2880,18 +3068,18 @@ var Gt = () => se({
|
|
|
2880
3068
|
}
|
|
2881
3069
|
],
|
|
2882
3070
|
bindDataStore: (e) => {
|
|
2883
|
-
|
|
3071
|
+
M && (P.current = Rt(e)), N && (F.current = Vt(e)), S.bindDataStore?.(e);
|
|
2884
3072
|
},
|
|
2885
3073
|
onActivate: (e) => b.sync(() => {
|
|
2886
|
-
let t = !!
|
|
2887
|
-
e.logger.info(`storage: provider=${
|
|
2888
|
-
provider:
|
|
2889
|
-
bucket:
|
|
2890
|
-
refStore:
|
|
2891
|
-
}),
|
|
3074
|
+
let t = !!D || !!q.read("STORAGE_CDN_URL", i.cdnBaseUrl);
|
|
3075
|
+
e.logger.info(`storage: provider=${S.name} presign=${S.presigns ? "yes" : "no"} publicUrl=${t ? "yes" : "no"} transforms=yes`, {
|
|
3076
|
+
provider: S.name,
|
|
3077
|
+
bucket: C,
|
|
3078
|
+
refStore: M ? "memory" : "custom"
|
|
3079
|
+
}), S.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 && !S.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
3080
|
}),
|
|
2893
3081
|
onDeactivate: () => b.void
|
|
2894
3082
|
});
|
|
2895
3083
|
};
|
|
2896
3084
|
//#endregion
|
|
2897
|
-
export {
|
|
3085
|
+
export { K as STORAGE_BLOBS_TABLE, G as STORAGE_GRANTS_TABLE, W as STORAGE_REFS_TABLE, De as STORAGE_USAGE_TABLE, e as StorageAccessDenied, t as StorageError, n as StorageRejected, r as StorageScanRejected, i as StorageService, je as _voltroStorageBlobsTable, ke as _voltroStorageGrantsTable, Oe as _voltroStorageRefsTable, Ae as _voltroStorageUsageTable, un as appStorageProvider, Qt as assetRef, Ve as azureProvider, Wt as buildStorageService, xe as bytesToStream, Ct as checkLimits, Yt as clamavScanner, Fe as clearStorageBuffer, Se as collectStream, be as concatBytes, dn as configuredStorageProvider, bt as contentTypeAllowed, Vt as dataStoreGrantStore, Rt as dataStoreRefStore, Be as databaseProvider, tn as decodeDataUri, on as durabilityNotice, Kt as encodeInstream, Zt as ffmpegTranscoder, Le as filesystemProvider, Ce as fromNodeReadable, Te as getObjectStream, Ze as hashPassword, zt as memoryGrantStore, Ie as memoryProvider, Pt as memoryRefStore, qt as parseClamavResponse, Ue as parseTransformParams, an as pathDurability, nn as putAvatar, Ee as putObjectStream, Pe as readStorageBuffer, Mt as refMatchesListQuery, fn as resolveStorageProvider, Y as resolveStorageSecret, Re 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 storagePlugin, rn as storagePutIntentsTable, Gt as storageServiceLayer, we 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 };
|