@voltro/plugin-storage 0.71.0 → 0.72.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 +435 -0
- package/THIRD-PARTY-NOTICES.md +29 -1
- package/dist/index.d.ts +106 -1
- package/dist/index.js +1038 -681
- package/dist/types.d.ts +13 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
1
|
import { StorageAccessDenied as e, StorageError as t, StorageRejected as n, StorageScanRejected as r, StorageService as i } from "./types.js";
|
|
2
|
-
import { abortMultipartUploadDescriptor as a, beginMultipartUploadDescriptor as o, beginResumableUploadDescriptor as s, completeMultipartUploadDescriptor as c, finalizeUploadDescriptor as l, ingestUrlDescriptor as u, listGrantsDescriptor as d, listRefsDescriptor as f, mintPresignedUploadDescriptor as p, mintUploadTicketDescriptor as m, mintUploadUrlDescriptor as ee, mintUrlDescriptor as h, revokeDescriptor as g, shareDescriptor as
|
|
3
|
-
import { Chunk as
|
|
4
|
-
import { definePlugin as
|
|
5
|
-
import { readCookie as
|
|
6
|
-
import { and as
|
|
7
|
-
import { pluginEnv as
|
|
8
|
-
import { createHmac as
|
|
9
|
-
import { spawn as
|
|
10
|
-
import { mkdtemp as
|
|
11
|
-
import { tmpdir as
|
|
12
|
-
import { join as
|
|
13
|
-
import { statSync as
|
|
2
|
+
import { abortMultipartUploadDescriptor as a, beginMultipartUploadDescriptor as o, beginResumableUploadDescriptor as s, completeMultipartUploadDescriptor as c, finalizeUploadDescriptor as l, ingestUrlDescriptor as u, listGrantsDescriptor as d, listRefsDescriptor as f, mintPresignedUploadDescriptor as p, mintUploadTicketDescriptor as m, mintUploadUrlDescriptor as ee, mintUrlDescriptor as h, revokeDescriptor as g, shareDescriptor as te, signMultipartPartDescriptor as _, storageRpcClientImports as ne, uploadDescriptor as re } from "./rpc.js";
|
|
3
|
+
import { Chunk as v, Effect as y, Exit as b, Layer as x, Schedule as S, Schema as C, Stream as w } from "effect";
|
|
4
|
+
import { definePlugin as ie, pluginInstanceName as T } from "@voltro/protocol";
|
|
5
|
+
import { readCookie as ae, resolveSessionSecret as oe, verifySession as se } from "@voltro/protocol/session";
|
|
6
|
+
import { and as E, bytes as ce, contains as D, eq as O, generateId as k, id as le, integer as A, json as j, mixin as M, or as N, reference as ue, table as P, text as F, timestamp as de } from "@voltro/database";
|
|
7
|
+
import { pluginEnv as fe } from "@voltro/env";
|
|
8
|
+
import { createHash as I, createHmac as L, randomBytes as R, randomUUID as pe, scryptSync as me, timingSafeEqual as z } from "node:crypto";
|
|
9
|
+
import { spawn as he } from "node:child_process";
|
|
10
|
+
import { mkdtemp as ge, readFile as _e, rm as ve, writeFile as ye } from "node:fs/promises";
|
|
11
|
+
import { tmpdir as be } from "node:os";
|
|
12
|
+
import { join as B } from "node:path";
|
|
13
|
+
import { statSync as V } from "node:fs";
|
|
14
14
|
//#region src/streamBridge.ts
|
|
15
|
-
var
|
|
15
|
+
var xe = 1 << 20, Se = (e, n, r = !1) => new t({
|
|
16
16
|
provider: e,
|
|
17
17
|
message: n,
|
|
18
18
|
transient: r
|
|
19
|
-
}),
|
|
19
|
+
}), Ce = (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
|
+
}, we = (e, t = xe) => {
|
|
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 w.fromIterable(n);
|
|
29
|
+
}, Te = (e) => e.pipe(w.runCollect, y.map((e) => Ce(v.toReadonlyArray(e)))), Ee = (e, t) => w.suspend(() => w.fromAsyncIterable(t(), (t) => Se(e, `read stream failed: ${String(t?.message ?? t)}`, !0))).pipe(w.map((e) => e instanceof Uint8Array ? e : new Uint8Array(e))), De = async (e) => {
|
|
30
30
|
let { Readable: t } = await import("node:stream");
|
|
31
|
-
return t.fromWeb(
|
|
32
|
-
},
|
|
33
|
-
stream:
|
|
31
|
+
return t.fromWeb(w.toReadableStream(e));
|
|
32
|
+
}, Oe = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(y.map((e) => ({
|
|
33
|
+
stream: we(e.bytes),
|
|
34
34
|
contentType: e.contentType,
|
|
35
35
|
size: e.bytes.byteLength
|
|
36
|
-
}))),
|
|
36
|
+
}))), ke = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : Te(n).pipe(y.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
|
+
}))), H = "_voltro_storage_refs", U = "_voltro_storage_grants", W = "_voltro_storage_blobs", Ae = "_voltro_storage_usage", je = P(H, {
|
|
40
|
+
id: le({ prefix: "file" }),
|
|
41
|
+
tenantId: F().nullable(),
|
|
42
|
+
ownerId: F().nullable(),
|
|
43
|
+
bucket: F(),
|
|
44
|
+
key: F(),
|
|
45
|
+
contentType: F(),
|
|
46
|
+
size: A(),
|
|
47
|
+
checksum: F(),
|
|
48
|
+
visibility: F(),
|
|
49
|
+
accessPolicy: j().nullable(),
|
|
50
|
+
passwordHash: F().nullable(),
|
|
51
|
+
width: A().nullable(),
|
|
52
|
+
height: A().nullable(),
|
|
53
|
+
duration: A().nullable(),
|
|
54
|
+
placeholder: F().nullable(),
|
|
55
|
+
folder: F().nullable(),
|
|
56
|
+
tags: j().nullable(),
|
|
57
|
+
alt: F().nullable(),
|
|
58
|
+
caption: F().nullable(),
|
|
59
|
+
derivedFrom: F().nullable(),
|
|
60
|
+
kind: F().nullable(),
|
|
61
|
+
createdAt: de()
|
|
62
|
+
}).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]), Me = P(U, {
|
|
63
|
+
id: le({ prefix: "sgrant" }),
|
|
64
|
+
refId: F(),
|
|
65
|
+
principalType: F(),
|
|
66
|
+
principalId: F(),
|
|
67
|
+
permission: F(),
|
|
68
|
+
createdAt: de(),
|
|
69
|
+
expiresAt: de().nullable(),
|
|
70
|
+
createdBy: F().nullable()
|
|
71
|
+
}).index(["refId"]).index(["principalId"]), Ne = P(Ae, {
|
|
72
|
+
id: le({ prefix: "susage" }),
|
|
73
|
+
tenantId: F().maxLength(191),
|
|
74
|
+
bytes: A().default(0),
|
|
75
|
+
count: A().default(0),
|
|
76
|
+
updatedAt: de()
|
|
77
|
+
}).unique("byStorageUsageTenant", ["tenantId"]), Pe = P(W, {
|
|
78
|
+
id: le({ prefix: "blob" }),
|
|
79
|
+
key: F(),
|
|
80
|
+
data: ce(),
|
|
81
|
+
contentType: F(),
|
|
82
|
+
size: A()
|
|
83
|
+
}).index(["key"]), G = fe([
|
|
84
84
|
{
|
|
85
85
|
name: "STORAGE_PROVIDER",
|
|
86
86
|
required: !1,
|
|
@@ -231,47 +231,47 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
231
231
|
secret: !1,
|
|
232
232
|
description: "clamd port for the optional clamav virus scanner. Default 3310."
|
|
233
233
|
}
|
|
234
|
-
]),
|
|
234
|
+
]), K = (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
|
+
}), Fe = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, Ie = /* @__PURE__ */ new Map(), Le = (e, t) => Ie.get(e)?.get(t)?.bytes, Re = (e) => {
|
|
240
|
+
Ie.get(e)?.clear();
|
|
241
|
+
}, ze = (e = "default") => {
|
|
242
|
+
let t = Ie.get(e) ?? /* @__PURE__ */ new Map();
|
|
243
|
+
return Ie.set(e, t), {
|
|
244
244
|
name: "memory",
|
|
245
245
|
presigns: !1,
|
|
246
|
-
put: (e, n, r) =>
|
|
246
|
+
put: (e, n, r) => y.sync(() => (t.set(e, {
|
|
247
247
|
bytes: n,
|
|
248
248
|
contentType: r.contentType
|
|
249
249
|
}), { size: n.byteLength })),
|
|
250
|
-
get: (e) =>
|
|
250
|
+
get: (e) => y.suspend(() => {
|
|
251
251
|
let n = t.get(e);
|
|
252
|
-
return n ?
|
|
252
|
+
return n ? y.succeed({
|
|
253
253
|
bytes: n.bytes,
|
|
254
254
|
contentType: n.contentType
|
|
255
|
-
}) :
|
|
255
|
+
}) : y.fail(K("memory", `no object at key '${e}'`, !1, 404));
|
|
256
256
|
}),
|
|
257
|
-
delete: (e) =>
|
|
257
|
+
delete: (e) => y.sync(() => {
|
|
258
258
|
t.delete(e);
|
|
259
259
|
}),
|
|
260
260
|
publicUrl: () => null,
|
|
261
|
-
getUrl: () =>
|
|
262
|
-
head: (e) =>
|
|
261
|
+
getUrl: () => y.succeed(""),
|
|
262
|
+
head: (e) => y.sync(() => {
|
|
263
263
|
let n = t.get(e);
|
|
264
264
|
return n ? { size: n.bytes.byteLength } : null;
|
|
265
265
|
})
|
|
266
266
|
};
|
|
267
|
-
},
|
|
267
|
+
}, Be = (e) => {
|
|
268
268
|
let t = e.root, n = async (e) => {
|
|
269
269
|
let { join: n, resolve: r, sep: i } = await import("node:path"), a = r(t), o = r(a, e);
|
|
270
270
|
if (o !== a && !o.startsWith(a + i)) throw Error(`key '${e}' escapes the storage root`);
|
|
271
271
|
return n(o);
|
|
272
|
-
}, r = (e, t, n = !1) =>
|
|
272
|
+
}, r = (e, t, n = !1) => y.tryPromise({
|
|
273
273
|
try: e,
|
|
274
|
-
catch: (e) => e?.code === "ENOENT" ?
|
|
274
|
+
catch: (e) => e?.code === "ENOENT" ? K("filesystem", `no object at key '${t}'`, !1, 404) : K("filesystem", String(e?.message ?? e), n)
|
|
275
275
|
});
|
|
276
276
|
return {
|
|
277
277
|
root: t,
|
|
@@ -299,8 +299,8 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
299
299
|
await (await import("node:fs/promises")).rm(await n(e), { force: !0 });
|
|
300
300
|
}, e),
|
|
301
301
|
publicUrl: () => null,
|
|
302
|
-
getUrl: () =>
|
|
303
|
-
head: (e) =>
|
|
302
|
+
getUrl: () => y.succeed(""),
|
|
303
|
+
head: (e) => y.tryPromise({
|
|
304
304
|
try: async () => {
|
|
305
305
|
let t = await import("node:fs/promises");
|
|
306
306
|
try {
|
|
@@ -310,12 +310,12 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
310
310
|
throw e;
|
|
311
311
|
}
|
|
312
312
|
},
|
|
313
|
-
catch: (e) =>
|
|
313
|
+
catch: (e) => K("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: Ee("filesystem", () => r(i)),
|
|
319
319
|
contentType: "application/octet-stream",
|
|
320
320
|
size: a.size
|
|
321
321
|
};
|
|
@@ -325,7 +325,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
325
325
|
await r.mkdir(i(c), { recursive: !0 });
|
|
326
326
|
let l = `${c}.tmp-${a()}`;
|
|
327
327
|
try {
|
|
328
|
-
await s(await
|
|
328
|
+
await s(await De(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 ve = 1 << 20, ye = (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
|
+
}), Ce(o);
|
|
344
344
|
}, e)
|
|
345
345
|
};
|
|
346
|
-
},
|
|
346
|
+
}, Ve = (e) => {
|
|
347
347
|
let t = e.name ?? "s3", n = e.publicAcl ?? !0, r = null, i = () => r || (r = (async () => {
|
|
348
348
|
let t, n;
|
|
349
349
|
try {
|
|
@@ -364,11 +364,11 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
364
364
|
cmds: t,
|
|
365
365
|
presign: n.getSignedUrl
|
|
366
366
|
};
|
|
367
|
-
})(), r), a = (e) =>
|
|
367
|
+
})(), r), a = (e) => y.tryPromise({
|
|
368
368
|
try: e,
|
|
369
369
|
catch: (e) => {
|
|
370
370
|
let n = e?.$metadata?.httpStatusCode;
|
|
371
|
-
return
|
|
371
|
+
return K(t, String(e?.message ?? e), Fe(n), n);
|
|
372
372
|
}
|
|
373
373
|
}), o = async (e) => {
|
|
374
374
|
let t = e;
|
|
@@ -464,7 +464,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
464
464
|
UploadId: n
|
|
465
465
|
}));
|
|
466
466
|
}),
|
|
467
|
-
head: (n) =>
|
|
467
|
+
head: (n) => y.tryPromise({
|
|
468
468
|
try: async () => {
|
|
469
469
|
let { client: t, cmds: r } = await i();
|
|
470
470
|
try {
|
|
@@ -483,7 +483,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
483
483
|
},
|
|
484
484
|
catch: (e) => {
|
|
485
485
|
let n = e?.$metadata?.httpStatusCode;
|
|
486
|
-
return
|
|
486
|
+
return K(t, String(e?.message ?? e), Fe(n), n);
|
|
487
487
|
}
|
|
488
488
|
}),
|
|
489
489
|
getStream: (n) => a(async () => {
|
|
@@ -492,7 +492,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
492
492
|
Key: n
|
|
493
493
|
})), s = o.Body;
|
|
494
494
|
return {
|
|
495
|
-
stream:
|
|
495
|
+
stream: Ee(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 ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
504
504
|
} catch (e) {
|
|
505
505
|
throw Error("s3/minio `putStream` requires the '@aws-sdk/lib-storage' optional dependency (multipart upload). Install it to enable streamed uploads.", { cause: e });
|
|
506
506
|
}
|
|
507
|
-
let l = await
|
|
507
|
+
let l = await De(r);
|
|
508
508
|
return await new c.Upload({
|
|
509
509
|
client: a,
|
|
510
510
|
params: {
|
|
@@ -528,15 +528,15 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
528
528
|
return o(c.Body);
|
|
529
529
|
})
|
|
530
530
|
};
|
|
531
|
-
},
|
|
531
|
+
}, He = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), Ue = () => {
|
|
532
532
|
let e = null, t = () => {
|
|
533
533
|
if (!e) throw Error("the 'database' storage provider isn't bound to a DataStore yet");
|
|
534
534
|
return e;
|
|
535
|
-
}, n = (e) =>
|
|
535
|
+
}, n = (e) => y.tryPromise({
|
|
536
536
|
try: e,
|
|
537
|
-
catch: (e) =>
|
|
537
|
+
catch: (e) => K("database", String(e?.message ?? e), !0)
|
|
538
538
|
}), r = async (e) => (await t().query({
|
|
539
|
-
table:
|
|
539
|
+
table: W,
|
|
540
540
|
predicate: {
|
|
541
541
|
column: "key",
|
|
542
542
|
op: "eq",
|
|
@@ -555,37 +555,37 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
555
555
|
},
|
|
556
556
|
put: (e, i, a) => n(async () => {
|
|
557
557
|
let n = await r(e);
|
|
558
|
-
return n ? await t().update(
|
|
558
|
+
return n ? await t().update(W, String(n.id), {
|
|
559
559
|
data: i,
|
|
560
560
|
contentType: a.contentType,
|
|
561
561
|
size: i.byteLength
|
|
562
|
-
}) : await t().insert(
|
|
563
|
-
id:
|
|
562
|
+
}) : await t().insert(W, {
|
|
563
|
+
id: k({
|
|
564
564
|
kind: "typeid",
|
|
565
565
|
prefix: "blob"
|
|
566
|
-
},
|
|
566
|
+
}, W),
|
|
567
567
|
key: e,
|
|
568
568
|
data: i,
|
|
569
569
|
contentType: a.contentType,
|
|
570
570
|
size: i.byteLength
|
|
571
571
|
}), { size: i.byteLength };
|
|
572
572
|
}),
|
|
573
|
-
get: (e) =>
|
|
574
|
-
bytes:
|
|
573
|
+
get: (e) => y.suspend(() => n(() => r(e)).pipe(y.flatMap((t) => t ? y.succeed({
|
|
574
|
+
bytes: He(t.data),
|
|
575
575
|
contentType: String(t.contentType)
|
|
576
|
-
}) :
|
|
576
|
+
}) : y.fail(K("database", `no object at key '${e}'`, !1, 404))))),
|
|
577
577
|
delete: (e) => n(async () => {
|
|
578
578
|
let n = await r(e);
|
|
579
|
-
n && await t().delete(
|
|
579
|
+
n && await t().delete(W, String(n.id));
|
|
580
580
|
}),
|
|
581
581
|
publicUrl: () => null,
|
|
582
|
-
getUrl: () =>
|
|
582
|
+
getUrl: () => y.succeed(""),
|
|
583
583
|
head: (e) => n(async () => {
|
|
584
584
|
let t = await r(e);
|
|
585
585
|
return t ? { size: Number(t.size) } : null;
|
|
586
586
|
})
|
|
587
587
|
};
|
|
588
|
-
},
|
|
588
|
+
}, We = (e) => {
|
|
589
589
|
let t = null, n = () => t || (t = (async () => {
|
|
590
590
|
let t;
|
|
591
591
|
try {
|
|
@@ -593,17 +593,17 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
593
593
|
} catch (e) {
|
|
594
594
|
throw Error("the 'azure' storage provider requires the '@azure/storage-blob' optional dependency. Install it to enable it.", { cause: e });
|
|
595
595
|
}
|
|
596
|
-
let n =
|
|
596
|
+
let n = G.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = G.read("AZURE_STORAGE_KEY", e.accountKey), i = n && r ? new t.StorageSharedKeyCredential(n, r) : null, a = G.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString);
|
|
597
597
|
return {
|
|
598
598
|
container: (a ? t.BlobServiceClient.fromConnectionString(a) : new t.BlobServiceClient(e.endpoint ?? `https://${n}.blob.core.windows.net`, i ?? void 0)).getContainerClient(e.container),
|
|
599
599
|
sdk: t,
|
|
600
600
|
cred: i
|
|
601
601
|
};
|
|
602
|
-
})(), t), r = (e) =>
|
|
602
|
+
})(), t), r = (e) => y.tryPromise({
|
|
603
603
|
try: e,
|
|
604
604
|
catch: (e) => {
|
|
605
605
|
let t = e?.statusCode;
|
|
606
|
-
return
|
|
606
|
+
return K("azure", String(e?.message ?? e), Fe(t), t);
|
|
607
607
|
}
|
|
608
608
|
}), i = async (e) => {
|
|
609
609
|
if (!e) return /* @__PURE__ */ new Uint8Array();
|
|
@@ -645,7 +645,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
645
645
|
publicUrl: (t) => e.cdnBaseUrl ? `${e.cdnBaseUrl.replace(/\/$/, "")}/${t}` : null,
|
|
646
646
|
getUrl: (e, t) => r(() => a(e, "r", t)),
|
|
647
647
|
getUploadUrl: (e, t, n) => r(() => a(e, "cw", t)),
|
|
648
|
-
head: (e) =>
|
|
648
|
+
head: (e) => y.tryPromise({
|
|
649
649
|
try: async () => {
|
|
650
650
|
let { container: t } = await n();
|
|
651
651
|
try {
|
|
@@ -661,19 +661,19 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
661
661
|
},
|
|
662
662
|
catch: (e) => {
|
|
663
663
|
let t = e?.statusCode;
|
|
664
|
-
return
|
|
664
|
+
return K("azure", String(e?.message ?? e), Fe(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: Ee("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 De(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 ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
681
681
|
return i(o.readableStreamBody);
|
|
682
682
|
})
|
|
683
683
|
};
|
|
684
|
-
},
|
|
684
|
+
}, Ge = {
|
|
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
|
+
}, Ke = (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 ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
702
702
|
...a === void 0 ? {} : { q: a },
|
|
703
703
|
...s ? { fit: s } : {}
|
|
704
704
|
};
|
|
705
|
-
},
|
|
706
|
-
if (
|
|
705
|
+
}, qe = (e) => e.startsWith("image/") && !e.includes("svg"), Je, Ye = async () => {
|
|
706
|
+
if (Je !== void 0) return Je;
|
|
707
707
|
try {
|
|
708
708
|
let e = await import("sharp");
|
|
709
|
-
|
|
709
|
+
Je = e.default ?? e;
|
|
710
710
|
} catch {
|
|
711
|
-
|
|
711
|
+
Je = null;
|
|
712
712
|
}
|
|
713
|
-
return
|
|
714
|
-
},
|
|
715
|
-
if (!
|
|
716
|
-
let r = await
|
|
713
|
+
return Je;
|
|
714
|
+
}, Xe = async (e, t, n) => {
|
|
715
|
+
if (!qe(t)) return null;
|
|
716
|
+
let r = await Ye();
|
|
717
717
|
if (!r) return null;
|
|
718
718
|
try {
|
|
719
719
|
let i = r(Buffer.from(e), { failOn: "none" });
|
|
@@ -723,10 +723,10 @@ var ve = 1 << 20, ye = (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 && Ge[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 = Ge[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 ve = 1 << 20, ye = (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
|
+
}, Ze = 200, Qe = /* @__PURE__ */ new Map(), $e = async (e, t, n, r) => {
|
|
740
|
+
let i = `${e}::${JSON.stringify(r)}`, a = Qe.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 Xe(t, n, r);
|
|
743
|
+
if (o && (Qe.set(i, o), Qe.size > Ze)) {
|
|
744
|
+
let e = Qe.keys().next().value;
|
|
745
|
+
e !== void 0 && Qe.delete(e);
|
|
746
746
|
}
|
|
747
747
|
return o;
|
|
748
|
-
},
|
|
749
|
-
let t =
|
|
750
|
-
return `${t}:${
|
|
751
|
-
},
|
|
748
|
+
}, et = (e) => {
|
|
749
|
+
let t = R(16).toString("hex");
|
|
750
|
+
return `${t}:${me(e, t, 32).toString("hex")}`;
|
|
751
|
+
}, tt = (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 = me(e, n, i.length);
|
|
756
|
+
return a.length === i.length && z(a, i);
|
|
757
|
+
}, nt = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], rt = (e) => nt(e.metadata?.roles), it = (e) => nt(e.scopes), at = (e, t) => e.some((e) => t.includes(e)), ot = (e) => nt(e.metadata?.groups), st = (e) => typeof e == "boolean" ? y.succeed(e) : y.isEffect(e) ? e : y.promise(() => e), ct = (e, t, n = {}) => y.gen(function* () {
|
|
758
758
|
if (t.id && e.ownerId && t.id === e.ownerId) return !0;
|
|
759
759
|
let r = e.accessPolicy ?? [];
|
|
760
760
|
if (r.length === 0) return !1;
|
|
761
|
-
let i = n.resolveGroups ? yield*
|
|
762
|
-
for (let a of r) if (yield*
|
|
761
|
+
let i = n.resolveGroups ? yield* y.promise(async () => await n.resolveGroups(t)) : ot(t);
|
|
762
|
+
for (let a of r) if (yield* lt(a, e, t, i, n)) return !0;
|
|
763
763
|
return !1;
|
|
764
|
-
}),
|
|
764
|
+
}), lt = (e, t, n, r, i) => y.gen(function* () {
|
|
765
765
|
let a = !1, o = (e) => (a = !0, e);
|
|
766
|
-
if (e.owner !== void 0 && e.owner && !o(!!n.id && !!t.ownerId && n.id === t.ownerId) || e.tenant !== void 0 && e.tenant && !o(!!n.tenantId && n.tenantId === t.tenantId) || e.apiKey !== void 0 && e.apiKey && !o(n.type === "apiKey") || e.roles && e.roles.length > 0 && !o(
|
|
766
|
+
if (e.owner !== void 0 && e.owner && !o(!!n.id && !!t.ownerId && n.id === t.ownerId) || e.tenant !== void 0 && e.tenant && !o(!!n.tenantId && n.tenantId === t.tenantId) || e.apiKey !== void 0 && e.apiKey && !o(n.type === "apiKey") || e.roles && e.roles.length > 0 && !o(at(rt(n), e.roles)) || e.groups && e.groups.length > 0 && !o(at(r, e.groups)) || e.scopes && e.scopes.length > 0 && !o(at(it(n), e.scopes)) || e.password !== void 0 && e.password && !o(tt(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* st(r({
|
|
770
770
|
subject: n,
|
|
771
771
|
ref: t
|
|
772
772
|
})) : !1)) return !1;
|
|
773
773
|
}
|
|
774
774
|
return a;
|
|
775
|
-
}),
|
|
775
|
+
}), ut = (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 ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
783
783
|
id: e
|
|
784
784
|
});
|
|
785
785
|
return n;
|
|
786
|
-
},
|
|
787
|
-
let a =
|
|
786
|
+
}, dt = (e, t, n, r, i) => {
|
|
787
|
+
let a = ut(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
|
+
}, ft = (e, t) => t.resolveGroups ? y.promise(async () => await t.resolveGroups(e)) : y.succeed(ot(e)), q = () => G.read("VOLTRO_STORAGE_SECRET") ?? oe(), J = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), Y = (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
|
+
}, pt = (e, t, n = q()) => {
|
|
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
|
-
}, i =
|
|
798
|
-
return `${i}.${
|
|
799
|
-
},
|
|
797
|
+
}, i = J(JSON.stringify(r));
|
|
798
|
+
return `${i}.${J(L("sha256", n).update(i).digest())}`;
|
|
799
|
+
}, mt = (e, t = q()) => {
|
|
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 = L("sha256", t).update(r).digest(), o = Y(i);
|
|
804
|
+
if (o.length !== a.length || !z(o, a)) return null;
|
|
805
805
|
try {
|
|
806
|
-
let e = JSON.parse(
|
|
806
|
+
let e = JSON.parse(Y(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
|
+
}, ht = (e, t, n = q()) => {
|
|
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
|
-
}, i =
|
|
817
|
-
return `${i}.${
|
|
818
|
-
},
|
|
816
|
+
}, i = J(JSON.stringify(r));
|
|
817
|
+
return `${i}.${J(L("sha256", n).update(`u:${i}`).digest())}`;
|
|
818
|
+
}, gt = (e, t = q()) => {
|
|
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 = L("sha256", t).update(`u:${r}`).digest(), o = Y(i);
|
|
823
|
+
if (o.length !== a.length || !z(o, a)) return null;
|
|
824
824
|
try {
|
|
825
|
-
let e = JSON.parse(
|
|
825
|
+
let e = JSON.parse(Y(r).toString("utf8"));
|
|
826
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
|
+
}, _t = (e, t, n = q()) => {
|
|
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
|
-
}, i =
|
|
836
|
-
return `${i}.${
|
|
837
|
-
},
|
|
835
|
+
}, i = J(JSON.stringify(r));
|
|
836
|
+
return `${i}.${J(L("sha256", n).update(`f:${i}`).digest())}`;
|
|
837
|
+
}, vt = (e, t = q()) => {
|
|
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 = L("sha256", t).update(`f:${r}`).digest(), o = Y(i);
|
|
842
|
+
if (o.length !== a.length || !z(o, a)) return null;
|
|
843
843
|
try {
|
|
844
|
-
let e = JSON.parse(
|
|
844
|
+
let e = JSON.parse(Y(r).toString("utf8"));
|
|
845
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
|
+
}, yt = (e, t, n = q()) => {
|
|
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
|
-
}, i =
|
|
855
|
-
return `${i}.${
|
|
856
|
-
},
|
|
854
|
+
}, i = J(JSON.stringify(r));
|
|
855
|
+
return `${i}.${J(L("sha256", n).update(`r:${i}`).digest())}`;
|
|
856
|
+
}, bt = (e, t = q()) => {
|
|
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 = L("sha256", t).update(`r:${r}`).digest(), o = Y(i);
|
|
861
|
+
if (o.length !== a.length || !z(o, a)) return null;
|
|
862
862
|
try {
|
|
863
|
-
let e = JSON.parse(
|
|
863
|
+
let e = JSON.parse(Y(r).toString("utf8"));
|
|
864
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
|
+
}, xt = (e, t, n = q()) => {
|
|
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
|
-
}, i =
|
|
874
|
-
return `${i}.${
|
|
875
|
-
},
|
|
873
|
+
}, i = J(JSON.stringify(r));
|
|
874
|
+
return `${i}.${J(L("sha256", n).update(`m:${i}`).digest())}`;
|
|
875
|
+
}, St = (e, t = q()) => {
|
|
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 = L("sha256", t).update(`m:${r}`).digest(), o = Y(i);
|
|
880
|
+
if (o.length !== a.length || !z(o, a)) return null;
|
|
881
881
|
try {
|
|
882
|
-
let e = JSON.parse(
|
|
882
|
+
let e = JSON.parse(Y(r).toString("utf8"));
|
|
883
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
|
+
}, Ct = (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
|
+
}, wt = [
|
|
895
895
|
{
|
|
896
896
|
ct: /^image\/png$/,
|
|
897
897
|
offset: 0,
|
|
@@ -961,21 +961,21 @@ var ve = 1 << 20, ye = (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
|
+
], Tt = (e, t) => {
|
|
965
|
+
let n = t.toLowerCase(), r = wt.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
|
+
}, Et = (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
|
+
} : Ct(t, n.allowedContentTypes) ? n.sniff && !Tt(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, Dt = async (e, t, n) => {
|
|
977
|
+
if (!qe(t)) return { bytes: e };
|
|
978
|
+
let r = await Ye();
|
|
979
979
|
if (!r) return { bytes: e };
|
|
980
980
|
try {
|
|
981
981
|
let t = e;
|
|
@@ -998,16 +998,16 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
998
998
|
} catch {
|
|
999
999
|
return { bytes: e };
|
|
1000
1000
|
}
|
|
1001
|
-
},
|
|
1001
|
+
}, Ot = 67108864, kt = (e) => new n({
|
|
1002
1002
|
reason: "too-large",
|
|
1003
1003
|
detail: `remote body exceeds the ${e}-byte ingest limit`
|
|
1004
|
-
}),
|
|
1005
|
-
let i = r ??
|
|
1006
|
-
return !Number.isSafeInteger(i) || i < 0 ?
|
|
1004
|
+
}), At = (e, r) => y.suspend(() => {
|
|
1005
|
+
let i = r ?? Ot;
|
|
1006
|
+
return !Number.isSafeInteger(i) || i < 0 ? y.fail(new t({
|
|
1007
1007
|
provider: "ingest",
|
|
1008
1008
|
message: "limits.maxBytes must be a non-negative safe integer",
|
|
1009
1009
|
transient: !1
|
|
1010
|
-
})) :
|
|
1010
|
+
})) : y.tryPromise({
|
|
1011
1011
|
try: async (n) => {
|
|
1012
1012
|
let r = await fetch(e, { signal: n }), a;
|
|
1013
1013
|
try {
|
|
@@ -1018,12 +1018,12 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1018
1018
|
status: r.status
|
|
1019
1019
|
});
|
|
1020
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
|
|
1021
|
+
if ((!n || n === "identity") && e !== null && /^\d+$/.test(e) && BigInt(e) > BigInt(i)) throw kt(i);
|
|
1022
1022
|
let o = /* @__PURE__ */ new Uint8Array(), s = 0;
|
|
1023
1023
|
if (r.body !== null) for (a = r.body.getReader();;) {
|
|
1024
1024
|
let e = await a.read();
|
|
1025
1025
|
if (e.done) break;
|
|
1026
|
-
if (e.value.byteLength > i - s) throw
|
|
1026
|
+
if (e.value.byteLength > i - s) throw kt(i);
|
|
1027
1027
|
if (e.value.byteLength !== 0) {
|
|
1028
1028
|
let t = s + e.value.byteLength;
|
|
1029
1029
|
if (t > o.byteLength) {
|
|
@@ -1047,18 +1047,44 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1047
1047
|
transient: !0
|
|
1048
1048
|
})
|
|
1049
1049
|
});
|
|
1050
|
-
}),
|
|
1050
|
+
}), jt = (e, t) => y.suspend(() => {
|
|
1051
1051
|
if (t === void 0) return e;
|
|
1052
|
-
if (t.aborted) return
|
|
1053
|
-
let n =
|
|
1054
|
-
let n = () => e(
|
|
1055
|
-
return t.addEventListener("abort", n, { once: !0 }), t.aborted && n(),
|
|
1052
|
+
if (t.aborted) return y.interrupt;
|
|
1053
|
+
let n = y.async((e) => {
|
|
1054
|
+
let n = () => e(y.interrupt);
|
|
1055
|
+
return t.addEventListener("abort", n, { once: !0 }), t.aborted && n(), y.sync(() => t.removeEventListener("abort", n));
|
|
1056
1056
|
});
|
|
1057
|
-
return
|
|
1058
|
-
}),
|
|
1057
|
+
return y.raceFirst(e, n);
|
|
1058
|
+
}), Mt = (e) => {
|
|
1059
|
+
let r = (e, r) => y.tryPromise({
|
|
1060
|
+
try: r,
|
|
1061
|
+
catch: (r) => C.is(n)(r) ? r : new t({
|
|
1062
|
+
provider: "metadata",
|
|
1063
|
+
message: `Storage ${e} was not confirmed; retain the operation identity for recovery`,
|
|
1064
|
+
transient: !1
|
|
1065
|
+
})
|
|
1066
|
+
});
|
|
1067
|
+
return {
|
|
1068
|
+
put: (t) => y.gen(function* () {
|
|
1069
|
+
if (t.bytes.byteLength !== t.ref.size || I("sha256").update(t.bytes).digest("hex") !== t.identity.checksum) return yield* y.fail(new n({
|
|
1070
|
+
reason: "operation-content-mismatch",
|
|
1071
|
+
detail: "Storage operation bytes do not match their reserved identity"
|
|
1072
|
+
}));
|
|
1073
|
+
let i = yield* r("put reservation", () => e.metadata.reserve(t.identity, t.ref, t.quota));
|
|
1074
|
+
return i.ready ? i.ref : (yield* e.provider.put(i.ref.key, t.bytes, {
|
|
1075
|
+
contentType: i.ref.contentType,
|
|
1076
|
+
public: i.ref.visibility === "public"
|
|
1077
|
+
}), yield* r("put confirmation", () => e.metadata.confirm(t.identity)));
|
|
1078
|
+
}),
|
|
1079
|
+
delete: (t, n) => y.gen(function* () {
|
|
1080
|
+
let i = yield* r("delete acceptance", () => e.metadata.beginDelete(t, n));
|
|
1081
|
+
i.operation.deleteKey !== null && (yield* e.provider.delete(i.operation.deleteKey)), yield* r("delete confirmation", () => e.metadata.confirmDelete(i.identity));
|
|
1082
|
+
})
|
|
1083
|
+
};
|
|
1084
|
+
}, Nt = async (e) => {
|
|
1059
1085
|
let { createHash: t } = await import("node:crypto");
|
|
1060
1086
|
return t("sha256").update(e).digest("hex");
|
|
1061
|
-
},
|
|
1087
|
+
}, Pt = (e, t, n) => `${e?.replace(/\/+$/, "") ?? ""}${n}/${t}`, Ft = (e) => {
|
|
1062
1088
|
let t = /* @__PURE__ */ new Map(), n = {
|
|
1063
1089
|
public: 0,
|
|
1064
1090
|
private: 0
|
|
@@ -1074,7 +1100,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1074
1100
|
byTenant: Object.fromEntries(t),
|
|
1075
1101
|
visibility: n
|
|
1076
1102
|
};
|
|
1077
|
-
},
|
|
1103
|
+
}, It = (e, t) => {
|
|
1078
1104
|
if (t.search && ![
|
|
1079
1105
|
e.id,
|
|
1080
1106
|
e.key,
|
|
@@ -1091,10 +1117,10 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1091
1117
|
if (!t.tags.every((e) => n.includes(e))) return !1;
|
|
1092
1118
|
}
|
|
1093
1119
|
return !0;
|
|
1094
|
-
},
|
|
1120
|
+
}, Lt = (e) => e ?? "global", Rt = () => {
|
|
1095
1121
|
let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
|
|
1096
1122
|
return {
|
|
1097
|
-
statistics: () =>
|
|
1123
|
+
statistics: () => y.sync(() => Ft((function* () {
|
|
1098
1124
|
for (let t of e.values()) yield {
|
|
1099
1125
|
tenantId: t.tenantId,
|
|
1100
1126
|
visibility: t.visibility,
|
|
@@ -1102,14 +1128,14 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1102
1128
|
bytes: t.size
|
|
1103
1129
|
};
|
|
1104
1130
|
})())),
|
|
1105
|
-
insert: (t) =>
|
|
1131
|
+
insert: (t) => y.sync(() => {
|
|
1106
1132
|
e.set(t.id, t);
|
|
1107
1133
|
}),
|
|
1108
|
-
getById: (t) =>
|
|
1109
|
-
delete: (t) =>
|
|
1110
|
-
listRecent: (t) =>
|
|
1111
|
-
countByKey: (t, n) =>
|
|
1112
|
-
usageByTenant: (t) =>
|
|
1134
|
+
getById: (t) => y.sync(() => e.get(t) ?? null),
|
|
1135
|
+
delete: (t) => y.sync(() => e.delete(t)),
|
|
1136
|
+
listRecent: (t) => y.sync(() => [...e.values()].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(0, t)),
|
|
1137
|
+
countByKey: (t, n) => y.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n).length),
|
|
1138
|
+
usageByTenant: (t) => y.sync(() => {
|
|
1113
1139
|
let n = 0, r = 0;
|
|
1114
1140
|
for (let i of e.values()) (i.tenantId ?? null) === (t ?? null) && (n += i.size, r++);
|
|
1115
1141
|
return {
|
|
@@ -1117,8 +1143,8 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1117
1143
|
count: r
|
|
1118
1144
|
};
|
|
1119
1145
|
}),
|
|
1120
|
-
consumeUsage: (e, n, r) =>
|
|
1121
|
-
let i =
|
|
1146
|
+
consumeUsage: (e, n, r) => y.sync(() => {
|
|
1147
|
+
let i = Lt(e), a = t.get(i) ?? {
|
|
1122
1148
|
bytes: 0,
|
|
1123
1149
|
count: 0
|
|
1124
1150
|
}, o = (r?.maxBytes === void 0 || a.bytes + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || a.count + n.count <= r.maxCount);
|
|
@@ -1131,17 +1157,17 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1131
1157
|
count: a.count
|
|
1132
1158
|
};
|
|
1133
1159
|
}),
|
|
1134
|
-
releaseUsage: (e, n) =>
|
|
1135
|
-
let r =
|
|
1160
|
+
releaseUsage: (e, n) => y.sync(() => {
|
|
1161
|
+
let r = Lt(e), i = t.get(r);
|
|
1136
1162
|
i && t.set(r, {
|
|
1137
1163
|
bytes: Math.max(0, i.bytes - n.bytes),
|
|
1138
1164
|
count: Math.max(0, i.count - n.count)
|
|
1139
1165
|
});
|
|
1140
1166
|
}),
|
|
1141
|
-
listByDerivedFrom: (t) =>
|
|
1142
|
-
listRefs: (t) =>
|
|
1167
|
+
listByDerivedFrom: (t) => y.sync(() => [...e.values()].filter((e) => (e.derivedFrom ?? null) === t)),
|
|
1168
|
+
listRefs: (t) => y.sync(() => [...e.values()].filter((e) => It(e, t)).sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(t.offset, t.offset + t.limit))
|
|
1143
1169
|
};
|
|
1144
|
-
},
|
|
1170
|
+
}, zt = (e) => Array.isArray(e) && e.every((e) => typeof e == "string") ? e : null, X = (e) => ({
|
|
1145
1171
|
id: String(e.id),
|
|
1146
1172
|
tenantId: e.tenantId ?? null,
|
|
1147
1173
|
ownerId: e.ownerId ?? null,
|
|
@@ -1159,19 +1185,19 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1159
1185
|
duration: e.duration ?? null,
|
|
1160
1186
|
placeholder: e.placeholder ?? null,
|
|
1161
1187
|
folder: e.folder ?? null,
|
|
1162
|
-
tags:
|
|
1188
|
+
tags: zt(e.tags),
|
|
1163
1189
|
alt: e.alt ?? null,
|
|
1164
1190
|
caption: e.caption ?? null,
|
|
1165
1191
|
derivedFrom: e.derivedFrom ?? null,
|
|
1166
1192
|
kind: e.kind ?? null
|
|
1167
|
-
}),
|
|
1193
|
+
}), Z = (e) => y.tryPromise({
|
|
1168
1194
|
try: e,
|
|
1169
1195
|
catch: (e) => new t({
|
|
1170
1196
|
provider: "refstore",
|
|
1171
1197
|
message: String(e?.message ?? e),
|
|
1172
1198
|
transient: !0
|
|
1173
1199
|
})
|
|
1174
|
-
}),
|
|
1200
|
+
}), Bt = async (e, t) => (await e.query({
|
|
1175
1201
|
table: "_voltro_storage_usage",
|
|
1176
1202
|
predicate: {
|
|
1177
1203
|
column: "tenantId",
|
|
@@ -1182,9 +1208,9 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1182
1208
|
take: 1,
|
|
1183
1209
|
skip: void 0,
|
|
1184
1210
|
projection: void 0
|
|
1185
|
-
}))[0] ?? null,
|
|
1186
|
-
statistics: () =>
|
|
1187
|
-
table:
|
|
1211
|
+
}))[0] ?? null, Vt = (e) => ({
|
|
1212
|
+
statistics: () => Z(async () => Ft((await e.query({
|
|
1213
|
+
table: H,
|
|
1188
1214
|
predicate: void 0,
|
|
1189
1215
|
order: [],
|
|
1190
1216
|
take: void 0,
|
|
@@ -1205,10 +1231,10 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1205
1231
|
count: Number(e.count),
|
|
1206
1232
|
bytes: Number(e.bytes ?? 0)
|
|
1207
1233
|
})))),
|
|
1208
|
-
insert: (t) =>
|
|
1209
|
-
getById: (t) =>
|
|
1234
|
+
insert: (t) => Z(() => e.insert(H, { ...t })),
|
|
1235
|
+
getById: (t) => Z(async () => {
|
|
1210
1236
|
let n = await e.query({
|
|
1211
|
-
table:
|
|
1237
|
+
table: H,
|
|
1212
1238
|
predicate: {
|
|
1213
1239
|
column: "id",
|
|
1214
1240
|
op: "eq",
|
|
@@ -1219,11 +1245,11 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1219
1245
|
skip: void 0,
|
|
1220
1246
|
projection: void 0
|
|
1221
1247
|
});
|
|
1222
|
-
return n[0] ?
|
|
1248
|
+
return n[0] ? X(n[0]) : null;
|
|
1223
1249
|
}),
|
|
1224
|
-
delete: (t) =>
|
|
1225
|
-
listRecent: (t) =>
|
|
1226
|
-
table:
|
|
1250
|
+
delete: (t) => Z(() => e.delete(H, t)),
|
|
1251
|
+
listRecent: (t) => Z(async () => (await e.query({
|
|
1252
|
+
table: H,
|
|
1227
1253
|
predicate: void 0,
|
|
1228
1254
|
order: [{
|
|
1229
1255
|
column: "createdAt",
|
|
@@ -1232,9 +1258,9 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1232
1258
|
take: t,
|
|
1233
1259
|
skip: void 0,
|
|
1234
1260
|
projection: void 0
|
|
1235
|
-
})).map(
|
|
1236
|
-
countByKey: (t, n) =>
|
|
1237
|
-
table:
|
|
1261
|
+
})).map(X)),
|
|
1262
|
+
countByKey: (t, n) => Z(async () => (await e.query({
|
|
1263
|
+
table: H,
|
|
1238
1264
|
predicate: { and: [{
|
|
1239
1265
|
column: "bucket",
|
|
1240
1266
|
op: "eq",
|
|
@@ -1249,9 +1275,9 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1249
1275
|
skip: void 0,
|
|
1250
1276
|
projection: void 0
|
|
1251
1277
|
})).length),
|
|
1252
|
-
usageByTenant: (t) =>
|
|
1278
|
+
usageByTenant: (t) => Z(async () => {
|
|
1253
1279
|
let n = await e.query({
|
|
1254
|
-
table:
|
|
1280
|
+
table: H,
|
|
1255
1281
|
predicate: {
|
|
1256
1282
|
column: "tenantId",
|
|
1257
1283
|
op: "eq",
|
|
@@ -1268,11 +1294,11 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1268
1294
|
count: n.length
|
|
1269
1295
|
};
|
|
1270
1296
|
}),
|
|
1271
|
-
consumeUsage: (t, n, r) =>
|
|
1272
|
-
let i =
|
|
1297
|
+
consumeUsage: (t, n, r) => Z(async () => {
|
|
1298
|
+
let i = Lt(t);
|
|
1273
1299
|
for (let t = 0; t < 32; t++) {
|
|
1274
1300
|
t > 0 && await new Promise((e) => setTimeout(e, t));
|
|
1275
|
-
let a = await
|
|
1301
|
+
let a = await Bt(e, i), o = a ? Number(a.bytes ?? 0) : 0, s = a ? Number(a.count ?? 0) : 0;
|
|
1276
1302
|
if (!((r?.maxBytes === void 0 || o + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || s + n.count <= r.maxCount))) return {
|
|
1277
1303
|
allowed: !1,
|
|
1278
1304
|
bytes: o,
|
|
@@ -1283,16 +1309,16 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1283
1309
|
bytes: o + n.bytes,
|
|
1284
1310
|
count: s + n.count,
|
|
1285
1311
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1286
|
-
}, { where:
|
|
1312
|
+
}, { where: E(O("id", String(a.id)), O("bytes", o), O("count", s)) }) === 1) return {
|
|
1287
1313
|
allowed: !0,
|
|
1288
1314
|
bytes: o,
|
|
1289
1315
|
count: s
|
|
1290
1316
|
};
|
|
1291
1317
|
} else {
|
|
1292
|
-
let t =
|
|
1318
|
+
let t = k({
|
|
1293
1319
|
kind: "typeid",
|
|
1294
1320
|
prefix: "susage"
|
|
1295
|
-
},
|
|
1321
|
+
}, Ae), r = await e.insertIgnore(Ae, {
|
|
1296
1322
|
id: t,
|
|
1297
1323
|
tenantId: i,
|
|
1298
1324
|
bytes: n.bytes,
|
|
@@ -1308,23 +1334,23 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1308
1334
|
}
|
|
1309
1335
|
throw Error(`storage usage consume: contention on tenant '${i}' exceeded 32 attempts`);
|
|
1310
1336
|
}),
|
|
1311
|
-
releaseUsage: (t, n) =>
|
|
1312
|
-
let r =
|
|
1337
|
+
releaseUsage: (t, n) => Z(async () => {
|
|
1338
|
+
let r = Lt(t);
|
|
1313
1339
|
for (let t = 0; t < 32; t++) {
|
|
1314
1340
|
t > 0 && await new Promise((e) => setTimeout(e, t));
|
|
1315
|
-
let i = await
|
|
1341
|
+
let i = await Bt(e, r);
|
|
1316
1342
|
if (!i) return;
|
|
1317
1343
|
let a = Number(i.bytes ?? 0), o = Number(i.count ?? 0);
|
|
1318
1344
|
if (await e.updateMany("_voltro_storage_usage", {
|
|
1319
1345
|
bytes: Math.max(0, a - n.bytes),
|
|
1320
1346
|
count: Math.max(0, o - n.count),
|
|
1321
1347
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1322
|
-
}, { where:
|
|
1348
|
+
}, { where: E(O("id", String(i.id)), O("bytes", a), O("count", o)) }) === 1) return;
|
|
1323
1349
|
}
|
|
1324
1350
|
throw Error(`storage usage release: contention on tenant '${r}' exceeded 32 attempts`);
|
|
1325
1351
|
}),
|
|
1326
|
-
listByDerivedFrom: (t) =>
|
|
1327
|
-
table:
|
|
1352
|
+
listByDerivedFrom: (t) => Z(async () => (await e.query({
|
|
1353
|
+
table: H,
|
|
1328
1354
|
predicate: {
|
|
1329
1355
|
column: "derivedFrom",
|
|
1330
1356
|
op: "eq",
|
|
@@ -1337,18 +1363,18 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1337
1363
|
take: void 0,
|
|
1338
1364
|
skip: void 0,
|
|
1339
1365
|
projection: void 0
|
|
1340
|
-
})).map(
|
|
1341
|
-
listRefs: (t) =>
|
|
1366
|
+
})).map(X)),
|
|
1367
|
+
listRefs: (t) => Z(async () => {
|
|
1342
1368
|
let n = [];
|
|
1343
|
-
t.tenantId !== void 0 && n.push(
|
|
1369
|
+
t.tenantId !== void 0 && n.push(O("tenantId", t.tenantId)), t.ownerId !== void 0 && n.push(O("ownerId", t.ownerId)), t.search && n.push(N(...[
|
|
1344
1370
|
"id",
|
|
1345
1371
|
"key",
|
|
1346
1372
|
"contentType",
|
|
1347
1373
|
"ownerId",
|
|
1348
1374
|
"tenantId"
|
|
1349
|
-
].map((e) =>
|
|
1350
|
-
let r = t.folder === void 0 && t.tags.length === 0 && t.includeDerived, i = n.length ?
|
|
1351
|
-
table:
|
|
1375
|
+
].map((e) => D(e, t.search))));
|
|
1376
|
+
let r = t.folder === void 0 && t.tags.length === 0 && t.includeDerived, i = n.length ? E(...n) : void 0, a = await e.query({
|
|
1377
|
+
table: H,
|
|
1352
1378
|
predicate: i,
|
|
1353
1379
|
order: [{
|
|
1354
1380
|
column: "createdAt",
|
|
@@ -1361,24 +1387,24 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1361
1387
|
skip: r ? t.offset : void 0,
|
|
1362
1388
|
projection: void 0
|
|
1363
1389
|
});
|
|
1364
|
-
return r ? a.map(
|
|
1390
|
+
return r ? a.map(X) : a.map(X).filter((e) => It(e, t)).slice(t.offset, t.offset + t.limit);
|
|
1365
1391
|
})
|
|
1366
|
-
}),
|
|
1392
|
+
}), Ht = () => {
|
|
1367
1393
|
let e = /* @__PURE__ */ new Map();
|
|
1368
1394
|
return {
|
|
1369
|
-
insert: (t) =>
|
|
1395
|
+
insert: (t) => y.sync(() => {
|
|
1370
1396
|
e.set(t.id, t);
|
|
1371
1397
|
}),
|
|
1372
|
-
delete: (t) =>
|
|
1398
|
+
delete: (t) => y.sync(() => {
|
|
1373
1399
|
e.delete(t);
|
|
1374
1400
|
}),
|
|
1375
|
-
getById: (t) =>
|
|
1376
|
-
listByRef: (t) =>
|
|
1377
|
-
deleteByRef: (t) =>
|
|
1401
|
+
getById: (t) => y.sync(() => e.get(t) ?? null),
|
|
1402
|
+
listByRef: (t) => y.sync(() => [...e.values()].filter((e) => e.refId === t)),
|
|
1403
|
+
deleteByRef: (t) => y.sync(() => {
|
|
1378
1404
|
for (let [n, r] of e) r.refId === t && e.delete(n);
|
|
1379
1405
|
})
|
|
1380
1406
|
};
|
|
1381
|
-
},
|
|
1407
|
+
}, Ut = (e) => ({
|
|
1382
1408
|
id: String(e.id),
|
|
1383
1409
|
refId: String(e.refId),
|
|
1384
1410
|
principalType: e.principalType,
|
|
@@ -1387,12 +1413,12 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1387
1413
|
createdAt: e.createdAt instanceof Date ? e.createdAt : new Date(String(e.createdAt)),
|
|
1388
1414
|
expiresAt: e.expiresAt ? e.expiresAt instanceof Date ? e.expiresAt : new Date(String(e.expiresAt)) : null,
|
|
1389
1415
|
createdBy: e.createdBy ?? null
|
|
1390
|
-
}),
|
|
1391
|
-
insert: (t) =>
|
|
1392
|
-
delete: (t) =>
|
|
1393
|
-
getById: (t) =>
|
|
1416
|
+
}), Wt = (e) => ({
|
|
1417
|
+
insert: (t) => Z(() => e.insert(U, { ...t })),
|
|
1418
|
+
delete: (t) => Z(() => e.delete(U, t)),
|
|
1419
|
+
getById: (t) => Z(async () => {
|
|
1394
1420
|
let n = (await e.query({
|
|
1395
|
-
table:
|
|
1421
|
+
table: U,
|
|
1396
1422
|
predicate: {
|
|
1397
1423
|
column: "id",
|
|
1398
1424
|
op: "eq",
|
|
@@ -1403,10 +1429,10 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1403
1429
|
skip: void 0,
|
|
1404
1430
|
projection: void 0
|
|
1405
1431
|
}))[0];
|
|
1406
|
-
return n ?
|
|
1432
|
+
return n ? Ut(n) : null;
|
|
1407
1433
|
}),
|
|
1408
|
-
listByRef: (t) =>
|
|
1409
|
-
table:
|
|
1434
|
+
listByRef: (t) => Z(async () => (await e.query({
|
|
1435
|
+
table: U,
|
|
1410
1436
|
predicate: {
|
|
1411
1437
|
column: "refId",
|
|
1412
1438
|
op: "eq",
|
|
@@ -1419,10 +1445,10 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1419
1445
|
take: void 0,
|
|
1420
1446
|
skip: void 0,
|
|
1421
1447
|
projection: void 0
|
|
1422
|
-
})).map(
|
|
1423
|
-
deleteByRef: (t) =>
|
|
1448
|
+
})).map(Ut)),
|
|
1449
|
+
deleteByRef: (t) => Z(async () => {
|
|
1424
1450
|
let n = await e.query({
|
|
1425
|
-
table:
|
|
1451
|
+
table: U,
|
|
1426
1452
|
predicate: {
|
|
1427
1453
|
column: "refId",
|
|
1428
1454
|
op: "eq",
|
|
@@ -1433,23 +1459,23 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1433
1459
|
skip: void 0,
|
|
1434
1460
|
projection: void 0
|
|
1435
1461
|
});
|
|
1436
|
-
for (let t of n) await e.delete(
|
|
1462
|
+
for (let t of n) await e.delete(U, String(t.id));
|
|
1437
1463
|
})
|
|
1438
|
-
}),
|
|
1464
|
+
}), Gt = () => k({
|
|
1439
1465
|
kind: "typeid",
|
|
1440
1466
|
prefix: "file"
|
|
1441
|
-
},
|
|
1467
|
+
}, H), Kt = () => k({
|
|
1442
1468
|
kind: "typeid",
|
|
1443
1469
|
prefix: "grant"
|
|
1444
|
-
},
|
|
1445
|
-
let { provider: a, refStore: o, grantStore: s, bucket: c } = i, l = i.access ?? {}, u = i.attempts ?? 3, d = i.urlExpiresInSec ?? 3600, f = (e) =>
|
|
1470
|
+
}, U), qt = (i) => {
|
|
1471
|
+
let { provider: a, refStore: o, grantStore: s, bucket: c } = i, l = i.access ?? {}, u = i.attempts ?? 3, d = i.urlExpiresInSec ?? 3600, f = (e) => Pt(i.publicBaseUrl, e, i.httpPath ?? "/_voltro/storage"), p = S.recurs(Math.max(0, u - 1)).pipe(S.intersect(S.exponential("100 millis")), S.whileInput((e) => e.transient)), m = (e, t, n) => [
|
|
1446
1472
|
i.tenantPrefix,
|
|
1447
1473
|
e ?? "global",
|
|
1448
1474
|
n ?? t
|
|
1449
1475
|
].filter(Boolean).join("/"), ee = (e) => {
|
|
1450
|
-
if (e === void 0) return
|
|
1476
|
+
if (e === void 0) return y.succeed(void 0);
|
|
1451
1477
|
let n = e.length === 0 ? "empty" : e.includes("\0") ? "contains NUL" : e.startsWith("/") || e.startsWith("\\") ? "starts with a path separator" : e.includes("\\") ? "contains a backslash" : e.split("/").some((e) => e === "" || e === "." || e === "..") ? "contains an empty, \".\" or \"..\" segment" : void 0;
|
|
1452
|
-
return n === void 0 ?
|
|
1478
|
+
return n === void 0 ? y.succeed(e) : y.fail(new t({
|
|
1453
1479
|
provider: a.name,
|
|
1454
1480
|
message: `storage key rejected: ${n}`,
|
|
1455
1481
|
transient: !1,
|
|
@@ -1461,19 +1487,41 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1461
1487
|
"_incoming",
|
|
1462
1488
|
t,
|
|
1463
1489
|
String(n).padStart(6, "0")
|
|
1464
|
-
].filter(Boolean).join("/"), g = (e, n) => n !== void 0 && e.tenantId !== n ?
|
|
1490
|
+
].filter(Boolean).join("/"), g = (e, n) => n !== void 0 && e.tenantId !== n ? y.fail(new t({
|
|
1465
1491
|
provider: a.name,
|
|
1466
1492
|
message: "cross-tenant access denied",
|
|
1467
1493
|
transient: !1,
|
|
1468
1494
|
status: 403
|
|
1469
|
-
})) :
|
|
1495
|
+
})) : y.succeed(e), te = (e, n) => y.gen(function* () {
|
|
1496
|
+
let r = i.objects?.();
|
|
1497
|
+
if (r === void 0) return !1;
|
|
1498
|
+
let o = yield* y.tryPromise({
|
|
1499
|
+
try: () => r.intent(e),
|
|
1500
|
+
catch: (e) => new t({
|
|
1501
|
+
provider: "metadata",
|
|
1502
|
+
message: String(e?.message ?? e),
|
|
1503
|
+
transient: !1
|
|
1504
|
+
})
|
|
1505
|
+
});
|
|
1506
|
+
return o !== void 0 && (yield* g(o.ref, n), yield* Mt({
|
|
1507
|
+
metadata: r,
|
|
1508
|
+
provider: {
|
|
1509
|
+
...a,
|
|
1510
|
+
delete: (e) => a.delete(e).pipe(y.retry(p))
|
|
1511
|
+
}
|
|
1512
|
+
}).delete(e, n).pipe(y.catchTag("StorageRejected", (e) => y.fail(new t({
|
|
1513
|
+
provider: "metadata",
|
|
1514
|
+
message: e.detail,
|
|
1515
|
+
transient: !1
|
|
1516
|
+
})))), !0);
|
|
1517
|
+
}), _ = (e, n) => o.getById(e).pipe(y.flatMap((r) => r ? g(r, n) : y.fail(new t({
|
|
1470
1518
|
provider: a.name,
|
|
1471
1519
|
message: `no ref '${e}'`,
|
|
1472
1520
|
transient: !1,
|
|
1473
1521
|
status: 404
|
|
1474
|
-
})))),
|
|
1522
|
+
})))), ne = (e) => y.suspend(() => {
|
|
1475
1523
|
let n = i.scan(e);
|
|
1476
|
-
return
|
|
1524
|
+
return y.isEffect(n) ? n : y.tryPromise({
|
|
1477
1525
|
try: () => Promise.resolve(n),
|
|
1478
1526
|
catch: (e) => new t({
|
|
1479
1527
|
provider: "scan",
|
|
@@ -1481,56 +1529,45 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1481
1529
|
transient: !0
|
|
1482
1530
|
})
|
|
1483
1531
|
});
|
|
1484
|
-
}),
|
|
1532
|
+
}), re = (e) => y.suspend(() => {
|
|
1485
1533
|
let t = e.contentType;
|
|
1486
|
-
if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return
|
|
1534
|
+
if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return y.succeed(null);
|
|
1487
1535
|
let n;
|
|
1488
1536
|
try {
|
|
1489
1537
|
n = i.videoProbe(e);
|
|
1490
1538
|
} catch {
|
|
1491
|
-
return
|
|
1539
|
+
return y.succeed(null);
|
|
1492
1540
|
}
|
|
1493
|
-
return
|
|
1541
|
+
return y.isEffect(n) ? n.pipe(y.catchAll(() => y.succeed(null))) : y.tryPromise({
|
|
1494
1542
|
try: () => Promise.resolve(n),
|
|
1495
1543
|
catch: () => null
|
|
1496
|
-
}).pipe(
|
|
1497
|
-
}), v = (e) =>
|
|
1498
|
-
let t =
|
|
1499
|
-
if (t) return yield*
|
|
1544
|
+
}).pipe(y.catchAll(() => y.succeed(null)));
|
|
1545
|
+
}), v = (e) => y.gen(function* () {
|
|
1546
|
+
let t = Et(e.bytes, e.contentType, i.limits);
|
|
1547
|
+
if (t) return yield* y.fail(new n(t));
|
|
1500
1548
|
if (i.scan) {
|
|
1501
|
-
let t = yield*
|
|
1549
|
+
let t = yield* ne({
|
|
1502
1550
|
bytes: e.bytes,
|
|
1503
1551
|
contentType: e.contentType,
|
|
1504
1552
|
...e.key ? { key: e.key } : {}
|
|
1505
1553
|
});
|
|
1506
|
-
if (!t.clean) return yield*
|
|
1554
|
+
if (!t.clean) return yield* y.fail(new r({ threat: t.threat ?? "unknown" }));
|
|
1507
1555
|
}
|
|
1508
|
-
let s = yield*
|
|
1556
|
+
let s = yield* y.promise(() => Dt(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* re({
|
|
1509
1557
|
bytes: l,
|
|
1510
1558
|
contentType: e.contentType
|
|
1511
|
-
}), d = s.width ?? u?.width, f = s.height ?? u?.height, h = s.placeholder ?? u?.poster, g = e.duration ?? u?.duration,
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
}, T = yield* o.consumeUsage(v, w, i.quota);
|
|
1515
|
-
if (!T.allowed) {
|
|
1516
|
-
let e = i.quota ?? {}, t = e.maxCount !== void 0 && T.count + 1 > e.maxCount ? `tenant object count ${T.count} + 1 exceeds max ${e.maxCount}` : `tenant usage ${T.bytes} + ${l.byteLength} bytes exceeds max ${e.maxBytes}`;
|
|
1517
|
-
return yield* b.fail(new n({
|
|
1518
|
-
reason: "quota-exceeded",
|
|
1519
|
-
detail: t
|
|
1520
|
-
}));
|
|
1521
|
-
}
|
|
1522
|
-
let re = e.password ? yield* b.sync(() => Ze(e.password)) : null, E = {
|
|
1523
|
-
id: Ht(),
|
|
1524
|
-
tenantId: v,
|
|
1559
|
+
}), d = s.width ?? u?.width, f = s.height ?? u?.height, h = s.placeholder ?? u?.poster, g = e.duration ?? u?.duration, te = yield* y.promise(() => Nt(l)), _ = e.tenantId ?? null, v = e.visibility ?? "private", x = m(_, te, yield* ee(e.key)), S = e.password ? yield* y.sync(() => et(e.password)) : null, w = {
|
|
1560
|
+
id: Gt(),
|
|
1561
|
+
tenantId: _,
|
|
1525
1562
|
ownerId: e.ownerId ?? null,
|
|
1526
1563
|
bucket: c,
|
|
1527
|
-
key:
|
|
1564
|
+
key: x,
|
|
1528
1565
|
contentType: e.contentType,
|
|
1529
1566
|
size: l.byteLength,
|
|
1530
|
-
checksum:
|
|
1531
|
-
visibility:
|
|
1567
|
+
checksum: te,
|
|
1568
|
+
visibility: v,
|
|
1532
1569
|
accessPolicy: e.access ?? null,
|
|
1533
|
-
passwordHash:
|
|
1570
|
+
passwordHash: S,
|
|
1534
1571
|
createdAt: /* @__PURE__ */ new Date(),
|
|
1535
1572
|
...d === void 0 ? {} : { width: d },
|
|
1536
1573
|
...f === void 0 ? {} : { height: f },
|
|
@@ -1542,26 +1579,79 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1542
1579
|
...e.caption === void 0 ? {} : { caption: e.caption },
|
|
1543
1580
|
...e.derivedFrom === void 0 ? {} : { derivedFrom: e.derivedFrom },
|
|
1544
1581
|
...e.kind === void 0 ? {} : { kind: e.kind }
|
|
1545
|
-
};
|
|
1546
|
-
|
|
1582
|
+
}, ie = i.transcode !== void 0 && i.autoTranscode !== !1, T = (t) => ie && t.derivedFrom == null && (e.contentType.startsWith("video/") || e.contentType.startsWith("audio/")) ? y.forkDaemon(C(t).pipe(y.ignore)) : y.void;
|
|
1583
|
+
if (e.operationId !== void 0) {
|
|
1584
|
+
let t = i.objects?.();
|
|
1585
|
+
if (t === void 0) return yield* y.fail(new n({
|
|
1586
|
+
reason: "operation-store-unbound",
|
|
1587
|
+
detail: "a put with an operationId needs a bound data store; the in-memory ref store cannot hold operation intents"
|
|
1588
|
+
}));
|
|
1589
|
+
let r = {
|
|
1590
|
+
tenantId: _,
|
|
1591
|
+
bucket: c,
|
|
1592
|
+
operationId: e.operationId,
|
|
1593
|
+
checksum: te,
|
|
1594
|
+
logicalKey: x,
|
|
1595
|
+
fingerprint: yield* y.promise(() => Nt(new TextEncoder().encode(JSON.stringify([
|
|
1596
|
+
te,
|
|
1597
|
+
e.contentType,
|
|
1598
|
+
v,
|
|
1599
|
+
e.access ?? null,
|
|
1600
|
+
e.key ?? null,
|
|
1601
|
+
e.ownerId ?? null,
|
|
1602
|
+
e.folder ?? null,
|
|
1603
|
+
e.tags ?? null,
|
|
1604
|
+
e.alt ?? null,
|
|
1605
|
+
e.caption ?? null,
|
|
1606
|
+
e.derivedFrom ?? null,
|
|
1607
|
+
e.kind ?? null,
|
|
1608
|
+
g ?? null,
|
|
1609
|
+
e.password !== void 0
|
|
1610
|
+
]))))
|
|
1611
|
+
}, o = yield* Mt({
|
|
1612
|
+
metadata: t,
|
|
1613
|
+
provider: {
|
|
1614
|
+
...a,
|
|
1615
|
+
put: (e, t, n) => a.put(e, t, n).pipe(y.retry(p))
|
|
1616
|
+
}
|
|
1617
|
+
}).put({
|
|
1618
|
+
identity: r,
|
|
1619
|
+
ref: w,
|
|
1620
|
+
bytes: l,
|
|
1621
|
+
...i.quota === void 0 ? {} : { quota: i.quota }
|
|
1622
|
+
});
|
|
1623
|
+
return yield* T(o), o;
|
|
1624
|
+
}
|
|
1625
|
+
let ae = {
|
|
1626
|
+
bytes: l.byteLength,
|
|
1627
|
+
count: 1
|
|
1628
|
+
}, oe = yield* o.consumeUsage(_, ae, i.quota);
|
|
1629
|
+
if (!oe.allowed) {
|
|
1630
|
+
let e = i.quota ?? {}, t = e.maxCount !== void 0 && oe.count + 1 > e.maxCount ? `tenant object count ${oe.count} + 1 exceeds max ${e.maxCount}` : `tenant usage ${oe.bytes} + ${l.byteLength} bytes exceeds max ${e.maxBytes}`;
|
|
1631
|
+
return yield* y.fail(new n({
|
|
1632
|
+
reason: "quota-exceeded",
|
|
1633
|
+
detail: t
|
|
1634
|
+
}));
|
|
1635
|
+
}
|
|
1636
|
+
return yield* ((e) => e.pipe(y.onExit((e) => b.isSuccess(e) ? y.void : o.delete(w.id).pipe(y.zipRight(o.releaseUsage(_, ae)), y.ignore))))(o.insert(w).pipe(y.zipRight(a.put(x, l, {
|
|
1547
1637
|
contentType: e.contentType,
|
|
1548
|
-
public:
|
|
1549
|
-
}).pipe(
|
|
1550
|
-
}),
|
|
1551
|
-
if (!i.transcode) return
|
|
1638
|
+
public: v === "public"
|
|
1639
|
+
}).pipe(y.retry(p))))), yield* T(w), w;
|
|
1640
|
+
}), x = (e) => y.suspend(() => {
|
|
1641
|
+
if (!i.transcode) return y.succeed([]);
|
|
1552
1642
|
let t;
|
|
1553
1643
|
try {
|
|
1554
1644
|
t = i.transcode(e);
|
|
1555
1645
|
} catch {
|
|
1556
|
-
return
|
|
1646
|
+
return y.succeed([]);
|
|
1557
1647
|
}
|
|
1558
|
-
return
|
|
1648
|
+
return y.isEffect(t) ? t.pipe(y.catchAll(() => y.succeed([]))) : y.tryPromise({
|
|
1559
1649
|
try: () => Promise.resolve(t),
|
|
1560
1650
|
catch: () => []
|
|
1561
|
-
}).pipe(
|
|
1562
|
-
}),
|
|
1651
|
+
}).pipe(y.catchAll(() => y.succeed([])));
|
|
1652
|
+
}), C = (e) => y.gen(function* () {
|
|
1563
1653
|
if (!i.transcode || e.derivedFrom != null) return [];
|
|
1564
|
-
let t = yield* a.get(e.key).pipe(
|
|
1654
|
+
let t = yield* a.get(e.key).pipe(y.retry(p)), n = yield* x({
|
|
1565
1655
|
bytes: t.bytes,
|
|
1566
1656
|
contentType: e.contentType,
|
|
1567
1657
|
ref: e
|
|
@@ -1580,14 +1670,14 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1580
1670
|
r.push(n);
|
|
1581
1671
|
}
|
|
1582
1672
|
return r;
|
|
1583
|
-
}),
|
|
1584
|
-
if (e.visibility === "public" || (yield*
|
|
1673
|
+
}), ie = (e, t, n) => y.gen(function* () {
|
|
1674
|
+
if (e.visibility === "public" || (yield* ct(e, t, {
|
|
1585
1675
|
...l,
|
|
1586
1676
|
...n?.password === void 0 ? {} : { password: n.password }
|
|
1587
1677
|
}))) return !0;
|
|
1588
|
-
let r = yield*
|
|
1589
|
-
return
|
|
1590
|
-
}),
|
|
1678
|
+
let r = yield* ft(t, l);
|
|
1679
|
+
return dt(yield* s.listByRef(e.id), t, r, n?.permission ?? "read", Date.now());
|
|
1680
|
+
}), T = (e) => {
|
|
1591
1681
|
if (e.visibility === "public") {
|
|
1592
1682
|
let t = a.publicUrl?.(e.key);
|
|
1593
1683
|
if (t != null) return t;
|
|
@@ -1596,59 +1686,59 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1596
1686
|
};
|
|
1597
1687
|
return {
|
|
1598
1688
|
put: v,
|
|
1599
|
-
get: (e, t) => _(e, t?.tenantId).pipe(
|
|
1689
|
+
get: (e, t) => _(e, t?.tenantId).pipe(y.flatMap((e) => a.get(e.key).pipe(y.retry(p), y.map((t) => ({
|
|
1600
1690
|
bytes: t.bytes,
|
|
1601
1691
|
ref: e
|
|
1602
1692
|
}))))),
|
|
1603
|
-
getStream: (e, t) => _(e, t?.tenantId).pipe(
|
|
1693
|
+
getStream: (e, t) => _(e, t?.tenantId).pipe(y.map((e) => ({
|
|
1604
1694
|
ref: e,
|
|
1605
|
-
stream:
|
|
1695
|
+
stream: w.unwrap(y.suspend(() => a.getStream ? a.getStream(e.key).pipe(y.retry(p), y.map((e) => e.stream)) : a.get(e.key).pipe(y.retry(p), y.map((e) => w.make(e.bytes)))))
|
|
1606
1696
|
}))),
|
|
1607
|
-
getRange: (e, n, r) => _(e, r?.tenantId).pipe(
|
|
1697
|
+
getRange: (e, n, r) => _(e, r?.tenantId).pipe(y.flatMap((e) => {
|
|
1608
1698
|
let r = e.size, i = Math.max(0, Math.trunc(n.start));
|
|
1609
|
-
if (r > 0 && i >= r) return
|
|
1699
|
+
if (r > 0 && i >= r) return y.fail(new t({
|
|
1610
1700
|
provider: a.name,
|
|
1611
1701
|
message: `range start ${i} past end ${r}`,
|
|
1612
1702
|
transient: !1,
|
|
1613
1703
|
status: 416
|
|
1614
1704
|
}));
|
|
1615
1705
|
let o = Math.min(Math.trunc(n.endInclusive), Math.max(0, r - 1));
|
|
1616
|
-
return o < i ?
|
|
1706
|
+
return o < i ? y.fail(new t({
|
|
1617
1707
|
provider: a.name,
|
|
1618
1708
|
message: `empty range ${i}-${o}`,
|
|
1619
1709
|
transient: !1,
|
|
1620
1710
|
status: 416
|
|
1621
|
-
})) : (a.getRange ? a.getRange(e.key, i, o).pipe(
|
|
1711
|
+
})) : (a.getRange ? a.getRange(e.key, i, o).pipe(y.retry(p)) : a.get(e.key).pipe(y.retry(p), y.map((e) => e.bytes.subarray(i, o + 1)))).pipe(y.map((t) => ({
|
|
1622
1712
|
bytes: t,
|
|
1623
1713
|
ref: e,
|
|
1624
1714
|
totalSize: r
|
|
1625
1715
|
})));
|
|
1626
1716
|
})),
|
|
1627
|
-
getUrl: (e, t) => _(e, t?.tenantId).pipe(
|
|
1628
|
-
head: (e, t) => o.getById(e).pipe(
|
|
1629
|
-
delete: (e, t) => _(e, t?.tenantId).pipe(
|
|
1717
|
+
getUrl: (e, t) => _(e, t?.tenantId).pipe(y.flatMap((e) => e.visibility === "public" ? y.succeed(T(e)) : a.presigns ? a.getUrl(e.key, t?.expiresInSec ?? d) : y.succeed(f(e.id)))),
|
|
1718
|
+
head: (e, t) => o.getById(e).pipe(y.flatMap((e) => e ? g(e, t?.tenantId).pipe(y.map((e) => e)) : y.succeed(null))),
|
|
1719
|
+
delete: (e, t) => te(e, t?.tenantId).pipe(y.flatMap((n) => n ? y.void : _(e, t?.tenantId).pipe(y.flatMap((t) => s.deleteByRef(e).pipe(y.flatMap(() => o.delete(e)), y.flatMap((e) => e ? o.countByKey(t.bucket, t.key).pipe(y.flatMap((e) => e === 0 ? a.delete(t.key).pipe(y.retry(p)) : y.void), y.flatMap(() => o.releaseUsage(t.tenantId, {
|
|
1630
1720
|
bytes: t.size,
|
|
1631
1721
|
count: 1
|
|
1632
|
-
}))) :
|
|
1633
|
-
mintUrl: (n, r, i) =>
|
|
1634
|
-
let s = yield* o.getById(n).pipe(
|
|
1722
|
+
}))) : y.void), y.asVoid))))),
|
|
1723
|
+
mintUrl: (n, r, i) => y.gen(function* () {
|
|
1724
|
+
let s = yield* o.getById(n).pipe(y.flatMap((e) => e ? y.succeed(e) : y.fail(new t({
|
|
1635
1725
|
provider: a.name,
|
|
1636
1726
|
message: `no ref '${n}'`,
|
|
1637
1727
|
transient: !1,
|
|
1638
1728
|
status: 404
|
|
1639
1729
|
}))));
|
|
1640
|
-
if (s.visibility === "public") return
|
|
1641
|
-
if (!(yield*
|
|
1730
|
+
if (s.visibility === "public") return T(s);
|
|
1731
|
+
if (!(yield* ie(s, r, i?.password === void 0 ? {} : { password: i.password }))) return yield* y.fail(new e({
|
|
1642
1732
|
refId: n,
|
|
1643
1733
|
reason: "access denied"
|
|
1644
1734
|
}));
|
|
1645
1735
|
let c = i?.expiresInSec ?? d;
|
|
1646
1736
|
if (a.presigns) return yield* a.getUrl(s.key, c);
|
|
1647
|
-
let l = yield*
|
|
1737
|
+
let l = yield* y.sync(() => pt(s.id, c));
|
|
1648
1738
|
return `${f(s.id)}?t=${l}`;
|
|
1649
1739
|
}),
|
|
1650
|
-
mintUploadUrl: (e) =>
|
|
1651
|
-
if (!a.getUploadUrl) return yield*
|
|
1740
|
+
mintUploadUrl: (e) => y.gen(function* () {
|
|
1741
|
+
if (!a.getUploadUrl) return yield* y.fail(new t({
|
|
1652
1742
|
provider: a.name,
|
|
1653
1743
|
message: `provider '${a.name}' does not support presigned uploads`,
|
|
1654
1744
|
transient: !1,
|
|
@@ -1657,10 +1747,10 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1657
1747
|
let n = m(e.tenantId ?? null, "", yield* ee(e.key));
|
|
1658
1748
|
return yield* a.getUploadUrl(n, e.expiresInSec ?? d, e.contentType);
|
|
1659
1749
|
}),
|
|
1660
|
-
checkAccess:
|
|
1661
|
-
grant: (e) =>
|
|
1750
|
+
checkAccess: ie,
|
|
1751
|
+
grant: (e) => y.gen(function* () {
|
|
1662
1752
|
let t = {
|
|
1663
|
-
id:
|
|
1753
|
+
id: Kt(),
|
|
1664
1754
|
refId: e.refId,
|
|
1665
1755
|
principalType: e.principalType,
|
|
1666
1756
|
principalId: e.principalId,
|
|
@@ -1671,7 +1761,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1671
1761
|
};
|
|
1672
1762
|
return yield* s.insert(t), t;
|
|
1673
1763
|
}),
|
|
1674
|
-
listRefs: (e) =>
|
|
1764
|
+
listRefs: (e) => y.suspend(() => {
|
|
1675
1765
|
let t = Math.min(500, Math.max(1, Math.trunc(e?.limit ?? 50))), n = Math.max(0, Math.trunc(e?.offset ?? 0)), r = {
|
|
1676
1766
|
tenantId: e && "tenantId" in e ? e.tenantId : void 0,
|
|
1677
1767
|
folder: e?.folder,
|
|
@@ -1681,7 +1771,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1681
1771
|
limit: t + 1,
|
|
1682
1772
|
offset: n
|
|
1683
1773
|
};
|
|
1684
|
-
return o.listRefs(r).pipe(
|
|
1774
|
+
return o.listRefs(r).pipe(y.map((e) => {
|
|
1685
1775
|
let r = e.length > t;
|
|
1686
1776
|
return {
|
|
1687
1777
|
refs: r ? e.slice(0, t) : e,
|
|
@@ -1693,7 +1783,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1693
1783
|
getGrant: (e) => s.getById(e),
|
|
1694
1784
|
listGrants: (e) => s.listByRef(e),
|
|
1695
1785
|
usage: (e) => o.usageByTenant(e),
|
|
1696
|
-
sweepOrphans: (e) =>
|
|
1786
|
+
sweepOrphans: (e) => y.gen(function* () {
|
|
1697
1787
|
let t = e?.limit ?? 1e3, n = e?.dryRun ?? !1, r = yield* o.listRecent(t), i = [];
|
|
1698
1788
|
for (let e of r) if ((yield* a.head(e.key)) === null) {
|
|
1699
1789
|
if (!n) {
|
|
@@ -1710,12 +1800,13 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1710
1800
|
removed: i
|
|
1711
1801
|
};
|
|
1712
1802
|
}),
|
|
1713
|
-
ingestUrl: (e, t) =>
|
|
1714
|
-
let n = yield*
|
|
1803
|
+
ingestUrl: (e, t) => jt(y.gen(function* () {
|
|
1804
|
+
let n = yield* At(e, i.limits?.maxBytes);
|
|
1715
1805
|
return yield* v({
|
|
1716
1806
|
bytes: n.bytes,
|
|
1717
1807
|
contentType: t?.contentType ?? n.contentType,
|
|
1718
1808
|
...t?.tenantId === void 0 ? {} : { tenantId: t.tenantId },
|
|
1809
|
+
...t?.operationId === void 0 ? {} : { operationId: t.operationId },
|
|
1719
1810
|
...t?.ownerId === void 0 ? {} : { ownerId: t.ownerId },
|
|
1720
1811
|
...t?.visibility === void 0 ? {} : { visibility: t.visibility },
|
|
1721
1812
|
...t?.key === void 0 ? {} : { key: t.key },
|
|
@@ -1725,24 +1816,24 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1725
1816
|
...t?.caption === void 0 ? {} : { caption: t.caption }
|
|
1726
1817
|
});
|
|
1727
1818
|
}), t?.abortSignal),
|
|
1728
|
-
mintPresignedUpload: (e) =>
|
|
1729
|
-
if (!a.getUploadUrl) return yield*
|
|
1819
|
+
mintPresignedUpload: (e) => y.gen(function* () {
|
|
1820
|
+
if (!a.getUploadUrl) return yield* y.fail(new t({
|
|
1730
1821
|
provider: a.name,
|
|
1731
1822
|
message: `provider '${a.name}' does not support presigned uploads`,
|
|
1732
1823
|
transient: !1,
|
|
1733
1824
|
status: 400
|
|
1734
1825
|
}));
|
|
1735
|
-
let n = e.expiresInSec ?? d, r = `_incoming/${
|
|
1826
|
+
let n = e.expiresInSec ?? d, r = `_incoming/${k({
|
|
1736
1827
|
kind: "typeid",
|
|
1737
1828
|
prefix: "up"
|
|
1738
|
-
},
|
|
1829
|
+
}, H)}`, i = m(e.tenantId ?? null, "", r);
|
|
1739
1830
|
return {
|
|
1740
1831
|
uploadUrl: yield* a.getUploadUrl(i, n, e.contentType),
|
|
1741
1832
|
key: i,
|
|
1742
1833
|
expiresInSec: n
|
|
1743
1834
|
};
|
|
1744
1835
|
}),
|
|
1745
|
-
finalizeUpload: (e) => a.get(e.key).pipe(
|
|
1836
|
+
finalizeUpload: (e) => a.get(e.key).pipe(y.retry(p), y.flatMap((t) => v({
|
|
1746
1837
|
bytes: t.bytes,
|
|
1747
1838
|
contentType: e.contentType,
|
|
1748
1839
|
...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
|
|
@@ -1752,12 +1843,12 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1752
1843
|
...e.tags === void 0 ? {} : { tags: e.tags },
|
|
1753
1844
|
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
1754
1845
|
...e.caption === void 0 ? {} : { caption: e.caption }
|
|
1755
|
-
})),
|
|
1756
|
-
putResumableChunk: (e) => a.put(h(e.tenantId ?? null, e.uploadId, e.index), e.bytes, { contentType: "application/octet-stream" }).pipe(
|
|
1757
|
-
resumableStatus: (e) =>
|
|
1846
|
+
})), y.ensuring(a.delete(e.key).pipe(y.retry(p), y.ignore))),
|
|
1847
|
+
putResumableChunk: (e) => a.put(h(e.tenantId ?? null, e.uploadId, e.index), e.bytes, { contentType: "application/octet-stream" }).pipe(y.retry(p), y.asVoid),
|
|
1848
|
+
resumableStatus: (e) => y.gen(function* () {
|
|
1758
1849
|
let t = 0, n = 0;
|
|
1759
1850
|
for (; t < 1e6;) {
|
|
1760
|
-
let r = yield* a.head(h(e.tenantId ?? null, e.uploadId, t)).pipe(
|
|
1851
|
+
let r = yield* a.head(h(e.tenantId ?? null, e.uploadId, t)).pipe(y.retry(p), y.catchAll(() => y.succeed(null)));
|
|
1761
1852
|
if (r === null) break;
|
|
1762
1853
|
n += r.size, t += 1;
|
|
1763
1854
|
}
|
|
@@ -1766,15 +1857,15 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1766
1857
|
nextIndex: t
|
|
1767
1858
|
};
|
|
1768
1859
|
}),
|
|
1769
|
-
finalizeResumable: (e) =>
|
|
1860
|
+
finalizeResumable: (e) => y.gen(function* () {
|
|
1770
1861
|
let t = [];
|
|
1771
1862
|
for (let n = 0; n < e.count; n++) {
|
|
1772
|
-
let r = yield* a.get(h(e.tenantId ?? null, e.uploadId, n)).pipe(
|
|
1863
|
+
let r = yield* a.get(h(e.tenantId ?? null, e.uploadId, n)).pipe(y.retry(p));
|
|
1773
1864
|
t.push(r.bytes);
|
|
1774
1865
|
}
|
|
1775
1866
|
let n = t.reduce((e, t) => e + t.byteLength, 0), r = new Uint8Array(n), i = 0;
|
|
1776
1867
|
for (let e of t) r.set(e, i), i += e.byteLength;
|
|
1777
|
-
let o =
|
|
1868
|
+
let o = y.forEach(Array.from({ length: e.count }, (e, t) => t), (t) => a.delete(h(e.tenantId ?? null, e.uploadId, t)).pipe(y.retry(p), y.ignore), { discard: !0 });
|
|
1778
1869
|
return yield* v({
|
|
1779
1870
|
bytes: r,
|
|
1780
1871
|
contentType: e.contentType,
|
|
@@ -1785,49 +1876,49 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1785
1876
|
...e.tags === void 0 ? {} : { tags: e.tags },
|
|
1786
1877
|
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
1787
1878
|
...e.caption === void 0 ? {} : { caption: e.caption }
|
|
1788
|
-
}).pipe(
|
|
1879
|
+
}).pipe(y.ensuring(o));
|
|
1789
1880
|
}),
|
|
1790
|
-
transcode: (e, t) => _(e, t?.tenantId).pipe(
|
|
1791
|
-
renditions: (e, t) => _(e, t?.tenantId).pipe(
|
|
1792
|
-
beginMultipartUpload: (e) =>
|
|
1793
|
-
if (!a.createMultipartUpload || !a.presignUploadPart || !a.completeMultipartUpload) return yield*
|
|
1881
|
+
transcode: (e, t) => _(e, t?.tenantId).pipe(y.flatMap((e) => C(e))),
|
|
1882
|
+
renditions: (e, t) => _(e, t?.tenantId).pipe(y.flatMap(() => o.listByDerivedFrom(e))),
|
|
1883
|
+
beginMultipartUpload: (e) => y.gen(function* () {
|
|
1884
|
+
if (!a.createMultipartUpload || !a.presignUploadPart || !a.completeMultipartUpload) return yield* y.fail(new t({
|
|
1794
1885
|
provider: a.name,
|
|
1795
1886
|
message: `provider '${a.name}' does not support multipart uploads`,
|
|
1796
1887
|
transient: !1,
|
|
1797
1888
|
status: 400
|
|
1798
1889
|
}));
|
|
1799
|
-
let n = m(e.tenantId ?? null, "", `multipart/${
|
|
1890
|
+
let n = m(e.tenantId ?? null, "", `multipart/${k({
|
|
1800
1891
|
kind: "typeid",
|
|
1801
1892
|
prefix: "mp"
|
|
1802
|
-
},
|
|
1893
|
+
}, H)}`);
|
|
1803
1894
|
return {
|
|
1804
1895
|
uploadId: (yield* a.createMultipartUpload(n, e.contentType, { public: (e.visibility ?? "private") === "public" })).uploadId,
|
|
1805
1896
|
key: n
|
|
1806
1897
|
};
|
|
1807
1898
|
}),
|
|
1808
|
-
signMultipartPart: (e) =>
|
|
1899
|
+
signMultipartPart: (e) => y.suspend(() => a.presignUploadPart ? a.presignUploadPart(e.key, e.uploadId, e.partNumber, e.expiresInSec ?? d) : y.fail(new t({
|
|
1809
1900
|
provider: a.name,
|
|
1810
1901
|
message: "provider does not support multipart uploads",
|
|
1811
1902
|
transient: !1,
|
|
1812
1903
|
status: 400
|
|
1813
1904
|
}))),
|
|
1814
|
-
completeMultipart: (e) =>
|
|
1815
|
-
if (!a.completeMultipartUpload) return yield*
|
|
1905
|
+
completeMultipart: (e) => y.gen(function* () {
|
|
1906
|
+
if (!a.completeMultipartUpload) return yield* y.fail(new t({
|
|
1816
1907
|
provider: a.name,
|
|
1817
1908
|
message: "provider does not support multipart uploads",
|
|
1818
1909
|
transient: !1,
|
|
1819
1910
|
status: 400
|
|
1820
1911
|
}));
|
|
1821
|
-
let r = yield* a.completeMultipartUpload(e.key, e.uploadId, e.parts), s = yield* a.head(e.key).pipe(
|
|
1912
|
+
let r = yield* a.completeMultipartUpload(e.key, e.uploadId, e.parts), s = yield* a.head(e.key).pipe(y.retry(p)), l = s?.size ?? 0, u = (r.etag ?? s?.etag ?? "").replace(/"/g, ""), d = e.tenantId ?? null, f = {
|
|
1822
1913
|
bytes: l,
|
|
1823
1914
|
count: 1
|
|
1824
1915
|
};
|
|
1825
|
-
if (!(yield* o.consumeUsage(d, f, i.quota)).allowed) return yield* a.delete(e.key).pipe(
|
|
1916
|
+
if (!(yield* o.consumeUsage(d, f, i.quota)).allowed) return yield* a.delete(e.key).pipe(y.retry(p), y.ignore), yield* y.fail(new n({
|
|
1826
1917
|
reason: "quota-exceeded",
|
|
1827
1918
|
detail: `multipart upload of ${l} bytes exceeds tenant quota`
|
|
1828
1919
|
}));
|
|
1829
1920
|
let m = {
|
|
1830
|
-
id:
|
|
1921
|
+
id: Gt(),
|
|
1831
1922
|
tenantId: e.tenantId ?? null,
|
|
1832
1923
|
ownerId: e.ownerId ?? null,
|
|
1833
1924
|
bucket: c,
|
|
@@ -1844,11 +1935,263 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1844
1935
|
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
1845
1936
|
...e.caption === void 0 ? {} : { caption: e.caption }
|
|
1846
1937
|
};
|
|
1847
|
-
return yield* o.insert(m).pipe(
|
|
1938
|
+
return yield* o.insert(m).pipe(y.onExit((e) => b.isSuccess(e) ? y.void : o.releaseUsage(d, f).pipe(y.ignore))), m;
|
|
1848
1939
|
}),
|
|
1849
|
-
abortMultipart: (e) =>
|
|
1940
|
+
abortMultipart: (e) => y.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(y.retry(p)) : y.void)
|
|
1941
|
+
};
|
|
1942
|
+
}, Jt = (e) => x.succeed(i, qt(e)), Yt = "_voltro_storage_operation_locks", Q = "_voltro_storage_object_heads", Xt = "_voltro_storage_operations", Zt = [
|
|
1943
|
+
P(Yt, {
|
|
1944
|
+
id: F().maxLength(64),
|
|
1945
|
+
nonce: F()
|
|
1946
|
+
}).primaryKey(["id"]).nonReactive(),
|
|
1947
|
+
P(Q, {
|
|
1948
|
+
id: F().maxLength(64),
|
|
1949
|
+
generation: F(),
|
|
1950
|
+
key: F(),
|
|
1951
|
+
reservations: A()
|
|
1952
|
+
}).primaryKey(["id"]).nonReactive(),
|
|
1953
|
+
P(Xt, {
|
|
1954
|
+
id: F().maxLength(64),
|
|
1955
|
+
objectId: F().maxLength(64),
|
|
1956
|
+
fingerprint: F().maxLength(64),
|
|
1957
|
+
generation: F(),
|
|
1958
|
+
key: F(),
|
|
1959
|
+
refId: F(),
|
|
1960
|
+
state: F(),
|
|
1961
|
+
deleteKey: F().nullable()
|
|
1962
|
+
}).primaryKey(["id"]).nonReactive()
|
|
1963
|
+
], Qt = C.Struct({
|
|
1964
|
+
id: C.String,
|
|
1965
|
+
objectId: C.String,
|
|
1966
|
+
fingerprint: C.String,
|
|
1967
|
+
generation: C.String,
|
|
1968
|
+
key: C.String,
|
|
1969
|
+
refId: C.String,
|
|
1970
|
+
state: C.Literal("reserved", "ready", "deleting", "deleted"),
|
|
1971
|
+
deleteKey: C.NullOr(C.String)
|
|
1972
|
+
}), $t = C.Struct({
|
|
1973
|
+
id: C.String,
|
|
1974
|
+
generation: C.String,
|
|
1975
|
+
key: C.String,
|
|
1976
|
+
reservations: C.Int.pipe(C.nonNegative())
|
|
1977
|
+
}), en = (e) => I("sha256").update(JSON.stringify(e)).digest("hex"), tn = (e) => {
|
|
1978
|
+
if (!e.bucket || !e.operationId || !e.logicalKey || !/^[a-f0-9]{64}$/.test(e.fingerprint) || !/^[a-f0-9]{64}$/.test(e.checksum)) throw Error("Storage operation requires a bucket, operation identity, key and SHA-256 fingerprint");
|
|
1979
|
+
return {
|
|
1980
|
+
id: en([
|
|
1981
|
+
e.bucket,
|
|
1982
|
+
e.tenantId,
|
|
1983
|
+
e.operationId
|
|
1984
|
+
]),
|
|
1985
|
+
objectId: en([
|
|
1986
|
+
e.bucket,
|
|
1987
|
+
e.tenantId,
|
|
1988
|
+
e.logicalKey,
|
|
1989
|
+
e.checksum
|
|
1990
|
+
]),
|
|
1991
|
+
lockId: en([e.tenantId])
|
|
1992
|
+
};
|
|
1993
|
+
}, nn = async (e, t, n) => {
|
|
1994
|
+
let { lockId: r } = tn(t);
|
|
1995
|
+
return await e.insertIgnoreWithOutcome(Yt, {
|
|
1996
|
+
id: r,
|
|
1997
|
+
nonce: pe()
|
|
1998
|
+
}, { conflictColumns: ["id"] }), e.transactional(async (e) => {
|
|
1999
|
+
if ((await e.query({
|
|
2000
|
+
table: Yt,
|
|
2001
|
+
predicate: O("id", r),
|
|
2002
|
+
lock: "update",
|
|
2003
|
+
order: [],
|
|
2004
|
+
take: 1,
|
|
2005
|
+
skip: void 0,
|
|
2006
|
+
projection: void 0
|
|
2007
|
+
})).length !== 1 || await e.update(Yt, r, { nonce: pe() }) === null) throw Error("Storage operation lock is unavailable");
|
|
2008
|
+
return n(e);
|
|
2009
|
+
});
|
|
2010
|
+
}, $ = async (e, t) => {
|
|
2011
|
+
let r = tn(t), i = await e.query({
|
|
2012
|
+
table: Xt,
|
|
2013
|
+
predicate: O("id", r.id),
|
|
2014
|
+
order: [],
|
|
2015
|
+
take: 1,
|
|
2016
|
+
skip: void 0,
|
|
2017
|
+
projection: void 0
|
|
2018
|
+
});
|
|
2019
|
+
if (!i[0]) return;
|
|
2020
|
+
let a = C.decodeUnknownSync(Qt)(i[0]);
|
|
2021
|
+
if (a.fingerprint !== t.fingerprint || a.objectId !== r.objectId) throw new n({
|
|
2022
|
+
reason: "operation-identity-reused",
|
|
2023
|
+
detail: `storage operation '${t.operationId}' was already used with different inputs`
|
|
2024
|
+
});
|
|
2025
|
+
return a;
|
|
2026
|
+
}, rn = async (e, t) => {
|
|
2027
|
+
let n = await $(e, t);
|
|
2028
|
+
if (n) return n;
|
|
2029
|
+
let { id: r, objectId: i } = tn(t), a = await e.query({
|
|
2030
|
+
table: Q,
|
|
2031
|
+
predicate: O("id", i),
|
|
2032
|
+
order: [],
|
|
2033
|
+
take: 1,
|
|
2034
|
+
skip: void 0,
|
|
2035
|
+
projection: void 0
|
|
2036
|
+
}), o = a[0] ? C.decodeUnknownSync($t)(a[0]) : void 0, s = o?.generation ?? pe(), c = o?.key ?? `${t.logicalKey}/g-${s}`;
|
|
2037
|
+
o ? await e.update(Q, i, { reservations: o.reservations + 1 }) : await e.insert(Q, {
|
|
2038
|
+
id: i,
|
|
2039
|
+
generation: s,
|
|
2040
|
+
key: c,
|
|
2041
|
+
reservations: 1
|
|
2042
|
+
});
|
|
2043
|
+
let l = {
|
|
2044
|
+
id: r,
|
|
2045
|
+
objectId: i,
|
|
2046
|
+
fingerprint: t.fingerprint,
|
|
2047
|
+
generation: s,
|
|
2048
|
+
key: c,
|
|
2049
|
+
refId: `file_${pe()}`,
|
|
2050
|
+
state: "reserved",
|
|
2051
|
+
deleteKey: null
|
|
2052
|
+
};
|
|
2053
|
+
return await e.insert(Xt, l), l;
|
|
2054
|
+
}, an = async (e, t) => {
|
|
2055
|
+
let n = await $(e, t);
|
|
2056
|
+
if (!n) throw Error("Storage operation is missing");
|
|
2057
|
+
if (n.state === "deleting" || n.state === "deleted") throw Error("Deleted storage operation cannot be confirmed by a late put");
|
|
2058
|
+
return await e.update(Xt, n.id, { state: "ready" }), {
|
|
2059
|
+
...n,
|
|
2060
|
+
state: "ready"
|
|
2061
|
+
};
|
|
2062
|
+
}, on = async (e, t) => {
|
|
2063
|
+
let n = await $(e, t);
|
|
2064
|
+
if (!n) throw Error("Storage operation is missing");
|
|
2065
|
+
if (n.state === "deleting" || n.state === "deleted") return n;
|
|
2066
|
+
if (n.state !== "ready") throw Error("An unconfirmed put cannot be deleted");
|
|
2067
|
+
let r = await e.query({
|
|
2068
|
+
table: Q,
|
|
2069
|
+
predicate: O("id", n.objectId),
|
|
2070
|
+
order: [],
|
|
2071
|
+
take: 1,
|
|
2072
|
+
skip: void 0,
|
|
2073
|
+
projection: void 0
|
|
2074
|
+
}), i = r[0] ? C.decodeUnknownSync($t)(r[0]) : void 0;
|
|
2075
|
+
if (!i || i.generation !== n.generation || i.reservations < 1) throw Error("Storage object generation does not own its reservation");
|
|
2076
|
+
let a = i.reservations === 1 ? i.key : null;
|
|
2077
|
+
return a === null ? await e.update(Q, i.id, { reservations: i.reservations - 1 }) : await e.delete(Q, i.id), await e.update(Xt, n.id, {
|
|
2078
|
+
state: "deleting",
|
|
2079
|
+
deleteKey: a
|
|
2080
|
+
}), {
|
|
2081
|
+
...n,
|
|
2082
|
+
state: "deleting",
|
|
2083
|
+
deleteKey: a
|
|
1850
2084
|
};
|
|
1851
|
-
},
|
|
2085
|
+
}, sn = async (e, t) => {
|
|
2086
|
+
let n = await $(e, t);
|
|
2087
|
+
if (!n || n.state !== "deleting" && n.state !== "deleted") throw Error("Storage deletion has not been accepted");
|
|
2088
|
+
return n.state !== "deleted" && (await e.update(Xt, n.id, { state: "deleted" }), !0);
|
|
2089
|
+
}, cn = "_voltro_storage_put_intents", ln = P(cn, {
|
|
2090
|
+
id: F().maxLength(64),
|
|
2091
|
+
refId: F().maxLength(64),
|
|
2092
|
+
identity: j(),
|
|
2093
|
+
ref: j()
|
|
2094
|
+
}).primaryKey(["id"]).unique("storagePutRef", ["refId"]).nonReactive(), un = C.Struct({
|
|
2095
|
+
tenantId: C.NullOr(C.String),
|
|
2096
|
+
bucket: C.String,
|
|
2097
|
+
operationId: C.String,
|
|
2098
|
+
fingerprint: C.String,
|
|
2099
|
+
checksum: C.String,
|
|
2100
|
+
logicalKey: C.String
|
|
2101
|
+
}), dn = async (e, t) => {
|
|
2102
|
+
let n = await e.query({
|
|
2103
|
+
table: cn,
|
|
2104
|
+
predicate: O("refId", t),
|
|
2105
|
+
order: [],
|
|
2106
|
+
take: 2,
|
|
2107
|
+
skip: void 0,
|
|
2108
|
+
projection: void 0
|
|
2109
|
+
});
|
|
2110
|
+
if (n.length === 0) return;
|
|
2111
|
+
if (n.length !== 1) throw Error("Storage reference has ambiguous operation ownership");
|
|
2112
|
+
let r = n[0], i = C.decodeUnknownSync(un)(r.identity);
|
|
2113
|
+
if (typeof r.ref != "object" || r.ref === null || Array.isArray(r.ref)) throw Error("Storage operation reference is unreadable");
|
|
2114
|
+
let a = X(r.ref);
|
|
2115
|
+
if (a.id !== t || a.bucket !== i.bucket || a.tenantId !== i.tenantId || a.checksum !== i.checksum || !Number.isSafeInteger(a.size) || a.size < 0 || !Number.isFinite(a.createdAt.getTime())) throw Error("Storage operation reference does not match its identity");
|
|
2116
|
+
return {
|
|
2117
|
+
identity: i,
|
|
2118
|
+
ref: a
|
|
2119
|
+
};
|
|
2120
|
+
}, fn = (e) => ({
|
|
2121
|
+
intent: (t) => dn(e, t),
|
|
2122
|
+
reserve: (t, r, i) => nn(e, t, async (e) => {
|
|
2123
|
+
if (r.tenantId !== t.tenantId || r.bucket !== t.bucket || r.checksum !== t.checksum || !Number.isSafeInteger(r.size) || r.size < 0) throw Error("Storage put metadata does not match its identity");
|
|
2124
|
+
let a = await $(e, t);
|
|
2125
|
+
if (a) {
|
|
2126
|
+
if (a.state === "deleting" || a.state === "deleted") throw Error("Storage put identity has already been deleted");
|
|
2127
|
+
let t = await dn(e, a.refId);
|
|
2128
|
+
if (!t) throw Error("Storage operation lost its put intent");
|
|
2129
|
+
return {
|
|
2130
|
+
ref: t.ref,
|
|
2131
|
+
ready: a.state === "ready"
|
|
2132
|
+
};
|
|
2133
|
+
}
|
|
2134
|
+
let o = await rn(e, t), s = Vt(e);
|
|
2135
|
+
if (!(await y.runPromise(s.consumeUsage(t.tenantId, {
|
|
2136
|
+
bytes: r.size,
|
|
2137
|
+
count: 1
|
|
2138
|
+
}, i))).allowed) throw new n({
|
|
2139
|
+
reason: "quota-exceeded",
|
|
2140
|
+
detail: "Storage operation exceeds tenant quota"
|
|
2141
|
+
});
|
|
2142
|
+
let c = X({
|
|
2143
|
+
...r,
|
|
2144
|
+
id: o.refId,
|
|
2145
|
+
key: o.key
|
|
2146
|
+
});
|
|
2147
|
+
return await e.insert(cn, {
|
|
2148
|
+
id: o.id,
|
|
2149
|
+
refId: c.id,
|
|
2150
|
+
identity: t,
|
|
2151
|
+
ref: c
|
|
2152
|
+
}), {
|
|
2153
|
+
ref: c,
|
|
2154
|
+
ready: !1
|
|
2155
|
+
};
|
|
2156
|
+
}),
|
|
2157
|
+
confirm: (t) => nn(e, t, async (e) => {
|
|
2158
|
+
let n = await $(e, t);
|
|
2159
|
+
if (!n) throw Error("Storage put operation is missing");
|
|
2160
|
+
let r = await dn(e, n.refId);
|
|
2161
|
+
if (!r) throw Error("Storage put intent is missing");
|
|
2162
|
+
if (n.state === "ready") {
|
|
2163
|
+
let r = await y.runPromise(Vt(e).getById(n.refId));
|
|
2164
|
+
if (!r || r.key !== n.key || r.checksum !== t.checksum) throw Error("Confirmed storage operation lost its reference");
|
|
2165
|
+
return r;
|
|
2166
|
+
}
|
|
2167
|
+
return await an(e, t), await y.runPromise(Vt(e).insert(r.ref)), r.ref;
|
|
2168
|
+
}),
|
|
2169
|
+
beginDelete: async (t, n) => {
|
|
2170
|
+
let r = await dn(e, t);
|
|
2171
|
+
if (!r) throw Error("Storage delete operation is missing");
|
|
2172
|
+
if (n !== void 0 && r.identity.tenantId !== n) throw Error("Storage delete tenant mismatch");
|
|
2173
|
+
return nn(e, r.identity, async (e) => {
|
|
2174
|
+
let n = await dn(e, t);
|
|
2175
|
+
if (!n) throw Error("Storage delete intent disappeared");
|
|
2176
|
+
let r = await $(e, n.identity);
|
|
2177
|
+
if (!r) throw Error("Storage delete lost its operation");
|
|
2178
|
+
let i = await on(e, n.identity);
|
|
2179
|
+
if (r.state === "ready") {
|
|
2180
|
+
let r = Vt(e);
|
|
2181
|
+
if (await y.runPromise(Wt(e).deleteByRef(t)), !await y.runPromise(r.delete(t))) throw Error("Storage deletion lost its confirmed reference");
|
|
2182
|
+
await y.runPromise(r.releaseUsage(n.identity.tenantId, {
|
|
2183
|
+
bytes: n.ref.size,
|
|
2184
|
+
count: 1
|
|
2185
|
+
}));
|
|
2186
|
+
}
|
|
2187
|
+
return {
|
|
2188
|
+
operation: i,
|
|
2189
|
+
identity: n.identity
|
|
2190
|
+
};
|
|
2191
|
+
});
|
|
2192
|
+
},
|
|
2193
|
+
confirmDelete: (t) => nn(e, t, (e) => sn(e, t))
|
|
2194
|
+
}), pn = (e, t = 65536) => {
|
|
1852
2195
|
let n = [Buffer.from("zINSTREAM\0", "utf8")];
|
|
1853
2196
|
for (let r = 0; r < e.length; r += t) {
|
|
1854
2197
|
let i = e.subarray(r, Math.min(r + t, e.length)), a = Buffer.alloc(4);
|
|
@@ -1856,7 +2199,7 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1856
2199
|
}
|
|
1857
2200
|
let r = Buffer.alloc(4);
|
|
1858
2201
|
return r.writeUInt32BE(0, 0), n.push(r), Buffer.concat(n);
|
|
1859
|
-
},
|
|
2202
|
+
}, mn = (e) => {
|
|
1860
2203
|
let t = e.replace(/\0+$/, "").trim();
|
|
1861
2204
|
if (/\bOK$/.test(t)) return { clean: !0 };
|
|
1862
2205
|
let n = /:\s*(.+?)\s+FOUND$/.exec(t);
|
|
@@ -1865,8 +2208,8 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1865
2208
|
threat: n[1] ?? "unknown"
|
|
1866
2209
|
};
|
|
1867
2210
|
throw Error(`clamav: unexpected response: ${t}`);
|
|
1868
|
-
},
|
|
1869
|
-
let n = await import("node:net"), r =
|
|
2211
|
+
}, hn = async (e, t) => {
|
|
2212
|
+
let n = await import("node:net"), r = G.read("CLAMAV_HOST", t.host) ?? "127.0.0.1", i = G.read("CLAMAV_PORT"), a = t.port ?? (i ? Number(i) : 3310), o = t.timeoutMs ?? 3e4;
|
|
1870
2213
|
return new Promise((i, s) => {
|
|
1871
2214
|
let c = n.createConnection({
|
|
1872
2215
|
host: r,
|
|
@@ -1877,20 +2220,20 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1877
2220
|
c.on("error", (e) => {
|
|
1878
2221
|
clearTimeout(u), s(e);
|
|
1879
2222
|
}), c.on("connect", () => {
|
|
1880
|
-
c.end(
|
|
2223
|
+
c.end(pn(e, t.chunkSize));
|
|
1881
2224
|
}), c.on("data", (e) => {
|
|
1882
2225
|
l += e.toString("utf8");
|
|
1883
2226
|
}), c.on("close", () => {
|
|
1884
2227
|
clearTimeout(u);
|
|
1885
2228
|
try {
|
|
1886
|
-
i(
|
|
2229
|
+
i(mn(l));
|
|
1887
2230
|
} catch (e) {
|
|
1888
2231
|
s(e);
|
|
1889
2232
|
}
|
|
1890
2233
|
});
|
|
1891
2234
|
});
|
|
1892
|
-
},
|
|
1893
|
-
let a =
|
|
2235
|
+
}, gn = (e = {}) => (t) => hn(t.bytes, e), _n = (e, t, n) => new Promise((r, i) => {
|
|
2236
|
+
let a = he(e, [...t], { stdio: [
|
|
1894
2237
|
"ignore",
|
|
1895
2238
|
"ignore",
|
|
1896
2239
|
"pipe"
|
|
@@ -1904,31 +2247,31 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1904
2247
|
}), a.on("close", (e) => {
|
|
1905
2248
|
clearTimeout(s), e === 0 ? r() : i(/* @__PURE__ */ Error(`ffmpeg exited ${String(e)}: ${o.slice(-400)}`));
|
|
1906
2249
|
});
|
|
1907
|
-
}),
|
|
1908
|
-
let n = e.ffmpegPath ?? "ffmpeg", r = e.timeoutMs ?? 3e5, i = await
|
|
2250
|
+
}), vn = (e) => async ({ bytes: t }) => {
|
|
2251
|
+
let n = e.ffmpegPath ?? "ffmpeg", r = e.timeoutMs ?? 3e5, i = await ge(B(be(), "voltro-tc-")), a = B(i, "in"), o = [];
|
|
1909
2252
|
try {
|
|
1910
|
-
await
|
|
2253
|
+
await ye(a, t);
|
|
1911
2254
|
for (let t of e.renditions) {
|
|
1912
|
-
let e =
|
|
2255
|
+
let e = B(i, `out.${t.ext}`);
|
|
1913
2256
|
try {
|
|
1914
|
-
await
|
|
2257
|
+
await _n(n, [
|
|
1915
2258
|
"-y",
|
|
1916
2259
|
"-i",
|
|
1917
2260
|
a,
|
|
1918
2261
|
...t.args,
|
|
1919
2262
|
e
|
|
1920
2263
|
], r);
|
|
1921
|
-
let i = await
|
|
2264
|
+
let i = await _e(e);
|
|
1922
2265
|
o.push({
|
|
1923
2266
|
bytes: new Uint8Array(i),
|
|
1924
2267
|
contentType: t.contentType,
|
|
1925
2268
|
kind: t.kind,
|
|
1926
2269
|
...t.label === void 0 ? {} : { label: t.label }
|
|
1927
|
-
}), await
|
|
2270
|
+
}), await ve(e, { force: !0 });
|
|
1928
2271
|
} catch {}
|
|
1929
2272
|
}
|
|
1930
2273
|
} finally {
|
|
1931
|
-
await
|
|
2274
|
+
await ve(i, {
|
|
1932
2275
|
recursive: !0,
|
|
1933
2276
|
force: !0
|
|
1934
2277
|
}).catch(() => void 0);
|
|
@@ -1937,21 +2280,21 @@ var ve = 1 << 20, ye = (e, n, r = !1) => new t({
|
|
|
1937
2280
|
};
|
|
1938
2281
|
//#endregion
|
|
1939
2282
|
//#region src/assetRef.ts
|
|
1940
|
-
function
|
|
1941
|
-
let t = e.nullable ?? !0, n = e.fk === !1 ?
|
|
2283
|
+
function yn(e = {}) {
|
|
2284
|
+
let t = e.nullable ?? !0, n = e.fk === !1 ? F().externalId() : ue(() => je, { onDelete: e.onDelete ?? "setNull" });
|
|
1942
2285
|
return t ? n.nullable() : n;
|
|
1943
2286
|
}
|
|
1944
|
-
var
|
|
2287
|
+
var bn = () => M({
|
|
1945
2288
|
id: "@voltro/plugin-storage/withStorage",
|
|
1946
|
-
fields: { asset:
|
|
1947
|
-
}),
|
|
2289
|
+
fields: { asset: yn() }
|
|
2290
|
+
}), xn = {
|
|
1948
2291
|
"image/png": "png",
|
|
1949
2292
|
"image/jpeg": "jpg",
|
|
1950
2293
|
"image/jpg": "jpg",
|
|
1951
2294
|
"image/gif": "gif",
|
|
1952
2295
|
"image/webp": "webp",
|
|
1953
2296
|
"image/svg+xml": "svg"
|
|
1954
|
-
},
|
|
2297
|
+
}, Sn = (e) => {
|
|
1955
2298
|
let t = /^data:([^;,]+)(;base64)?,(.*)$/s.exec(e);
|
|
1956
2299
|
if (!t) throw Error("not a data URI");
|
|
1957
2300
|
let n = t[1] || "application/octet-stream", r = !!t[2], i = t[3] ?? "";
|
|
@@ -1959,16 +2302,16 @@ var $t = () => P({
|
|
|
1959
2302
|
bytes: r ? new Uint8Array(Buffer.from(i, "base64")) : new Uint8Array(Buffer.from(decodeURIComponent(i), "utf8")),
|
|
1960
2303
|
contentType: n
|
|
1961
2304
|
};
|
|
1962
|
-
},
|
|
1963
|
-
let r = yield*
|
|
1964
|
-
try: () =>
|
|
2305
|
+
}, Cn = (e, n) => y.gen(function* () {
|
|
2306
|
+
let r = yield* y.try({
|
|
2307
|
+
try: () => Sn(n.dataUri),
|
|
1965
2308
|
catch: (e) => new t({
|
|
1966
2309
|
provider: "avatar",
|
|
1967
2310
|
message: String(e?.message ?? e),
|
|
1968
2311
|
transient: !1,
|
|
1969
2312
|
status: 400
|
|
1970
2313
|
})
|
|
1971
|
-
}), i =
|
|
2314
|
+
}), i = xn[r.contentType] ?? "bin";
|
|
1972
2315
|
return yield* e.put({
|
|
1973
2316
|
bytes: r.bytes,
|
|
1974
2317
|
contentType: r.contentType,
|
|
@@ -1977,43 +2320,27 @@ var $t = () => P({
|
|
|
1977
2320
|
visibility: "public",
|
|
1978
2321
|
key: `avatars/${n.userId}/avatar.${i}`
|
|
1979
2322
|
});
|
|
1980
|
-
}),
|
|
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) => {
|
|
2323
|
+
}), wn = (e) => {
|
|
1997
2324
|
try {
|
|
1998
|
-
let t =
|
|
2325
|
+
let t = V(e), n = V("/");
|
|
1999
2326
|
return typeof t.dev != "number" || typeof n.dev != "number" ? "unknown" : t.dev === n.dev ? "same-device-as-root" : "separate-mount";
|
|
2000
2327
|
} catch {
|
|
2001
2328
|
return "unknown";
|
|
2002
2329
|
}
|
|
2003
|
-
},
|
|
2004
|
-
if (
|
|
2330
|
+
}, Tn = (e) => {
|
|
2331
|
+
if (wn(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
|
|
2005
2332
|
dies with it — which is the exact failure it exists for. On a development machine this is normal
|
|
2006
2333
|
and can be ignored.`;
|
|
2007
|
-
},
|
|
2008
|
-
|
|
2009
|
-
},
|
|
2334
|
+
}, En = G.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", Dn, On = (e) => {
|
|
2335
|
+
Dn = e;
|
|
2336
|
+
}, kn = () => Dn ?? jn({}), An = () => Dn === void 0 ? G.read("STORAGE_PROVIDER") === void 0 ? void 0 : jn({}) : Dn, jn = (e) => {
|
|
2010
2337
|
if (e.provider && typeof e.provider == "object") return e.provider;
|
|
2011
|
-
let t = (e.provider ??
|
|
2338
|
+
let t = (e.provider ?? G.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = G.read("S3_BUCKET", e.bucket) ?? G.read("STORAGE_BUCKET") ?? "voltro";
|
|
2012
2339
|
switch (t) {
|
|
2013
2340
|
case "s3":
|
|
2014
2341
|
case "minio": {
|
|
2015
|
-
let r =
|
|
2016
|
-
return
|
|
2342
|
+
let r = G.read("S3_REGION", e.region) ?? G.read("AWS_REGION"), i = G.read("S3_ENDPOINT", e.endpoint) ?? G.read("MINIO_ENDPOINT"), a = G.read("S3_ACCESS_KEY_ID", e.accessKeyId) ?? G.read("AWS_ACCESS_KEY_ID"), o = G.read("S3_SECRET_ACCESS_KEY", e.secretAccessKey) ?? G.read("AWS_SECRET_ACCESS_KEY"), s = G.read("STORAGE_CDN_URL", e.cdnBaseUrl);
|
|
2343
|
+
return Ve({
|
|
2017
2344
|
bucket: n,
|
|
2018
2345
|
name: t,
|
|
2019
2346
|
...r ? { region: r } : {},
|
|
@@ -2022,13 +2349,13 @@ var an = (e) => {
|
|
|
2022
2349
|
...o ? { secretAccessKey: o } : {},
|
|
2023
2350
|
...s ? { cdnBaseUrl: s } : {},
|
|
2024
2351
|
...e.publicAcl === void 0 ? {} : { publicAcl: e.publicAcl },
|
|
2025
|
-
...t === "minio" ||
|
|
2352
|
+
...t === "minio" || G.read("S3_FORCE_PATH_STYLE") === "1" ? { forcePathStyle: !0 } : {}
|
|
2026
2353
|
});
|
|
2027
2354
|
}
|
|
2028
2355
|
case "azure": {
|
|
2029
|
-
let t =
|
|
2030
|
-
return
|
|
2031
|
-
container:
|
|
2356
|
+
let t = G.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = G.read("AZURE_STORAGE_KEY", e.accountKey), i = G.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString), a = G.read("AZURE_STORAGE_ENDPOINT", e.endpoint), o = G.read("STORAGE_CDN_URL", e.cdnBaseUrl);
|
|
2357
|
+
return We({
|
|
2358
|
+
container: G.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
|
|
2032
2359
|
...t ? { accountName: t } : {},
|
|
2033
2360
|
...r ? { accountKey: r } : {},
|
|
2034
2361
|
...i ? { connectionString: i } : {},
|
|
@@ -2036,15 +2363,15 @@ var an = (e) => {
|
|
|
2036
2363
|
...o ? { cdnBaseUrl: o } : {}
|
|
2037
2364
|
});
|
|
2038
2365
|
}
|
|
2039
|
-
case "database": return
|
|
2040
|
-
case "filesystem": return
|
|
2041
|
-
default: return
|
|
2366
|
+
case "database": return Ue();
|
|
2367
|
+
case "filesystem": return Be({ root: G.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
|
|
2368
|
+
default: return ze(e.name ?? "default");
|
|
2042
2369
|
}
|
|
2043
|
-
},
|
|
2370
|
+
}, Mn = (e) => {
|
|
2044
2371
|
if (e !== void 0) return e;
|
|
2045
|
-
let t =
|
|
2372
|
+
let t = G.read("STORAGE_ALLOWED_ORIGINS");
|
|
2046
2373
|
return t ? t.trim() === "*" ? "*" : t.split(",").map((e) => e.trim()).filter(Boolean) : [];
|
|
2047
|
-
},
|
|
2374
|
+
}, Nn = (e, t) => {
|
|
2048
2375
|
if (!e || t !== "*" && !t.includes(e)) return {};
|
|
2049
2376
|
let n = {
|
|
2050
2377
|
"access-control-allow-origin": t === "*" ? "*" : e,
|
|
@@ -2054,7 +2381,7 @@ var an = (e) => {
|
|
|
2054
2381
|
vary: "Origin"
|
|
2055
2382
|
};
|
|
2056
2383
|
return t !== "*" && (n["access-control-allow-credentials"] = "true"), n;
|
|
2057
|
-
},
|
|
2384
|
+
}, Pn = (e) => ({
|
|
2058
2385
|
id: e.id,
|
|
2059
2386
|
tenantId: e.tenantId,
|
|
2060
2387
|
ownerId: e.ownerId,
|
|
@@ -2077,29 +2404,29 @@ var an = (e) => {
|
|
|
2077
2404
|
caption: e.caption ?? null,
|
|
2078
2405
|
derivedFrom: e.derivedFrom ?? null,
|
|
2079
2406
|
kind: e.kind ?? null
|
|
2080
|
-
}),
|
|
2407
|
+
}), Fn = () => new t({
|
|
2081
2408
|
provider: "storage",
|
|
2082
2409
|
message: "not permitted to administer sharing for this object",
|
|
2083
2410
|
transient: !1,
|
|
2084
2411
|
status: 403
|
|
2085
|
-
}),
|
|
2412
|
+
}), In = (e, t, n) => {
|
|
2086
2413
|
let r = n.request.subject;
|
|
2087
|
-
return (r.scopes ?? []).includes("admin:full") ?
|
|
2414
|
+
return (r.scopes ?? []).includes("admin:full") ? y.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(y.catchAll(() => y.fail(Fn())), y.flatMap((e) => {
|
|
2088
2415
|
let t = e?.ownerId;
|
|
2089
|
-
return t != null && t === r.id ?
|
|
2416
|
+
return t != null && t === r.id ? y.void : y.fail(Fn());
|
|
2090
2417
|
}));
|
|
2091
|
-
},
|
|
2418
|
+
}, Ln = () => new t({
|
|
2092
2419
|
provider: "storage",
|
|
2093
2420
|
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.",
|
|
2094
2421
|
transient: !1,
|
|
2095
2422
|
status: 401
|
|
2096
|
-
}),
|
|
2423
|
+
}), Rn = (e, t) => {
|
|
2097
2424
|
let n = e.request.subject.id ?? null, r = e.request.subject.tenantId ?? null;
|
|
2098
|
-
return n === null && !t ?
|
|
2425
|
+
return n === null && !t ? y.fail(Ln()) : y.succeed({
|
|
2099
2426
|
id: n,
|
|
2100
2427
|
tenantId: r
|
|
2101
2428
|
});
|
|
2102
|
-
},
|
|
2429
|
+
}, zn = (e, t) => e !== null && e !== (t ?? null), Bn = (e) => ({
|
|
2103
2430
|
id: e.id,
|
|
2104
2431
|
refId: e.refId,
|
|
2105
2432
|
principalType: e.principalType,
|
|
@@ -2108,37 +2435,41 @@ var an = (e) => {
|
|
|
2108
2435
|
createdAt: e.createdAt.toISOString(),
|
|
2109
2436
|
expiresAt: e.expiresAt ? e.expiresAt.toISOString() : null,
|
|
2110
2437
|
createdBy: e.createdBy
|
|
2111
|
-
}),
|
|
2112
|
-
|
|
2113
|
-
|
|
2438
|
+
}), Vn = "@voltro/plugin-storage", Hn = (e = {}) => T({
|
|
2439
|
+
base: Vn,
|
|
2440
|
+
alias: e.alias,
|
|
2441
|
+
instance: e.name
|
|
2442
|
+
}), Un = (i = {}) => {
|
|
2443
|
+
let v = T({
|
|
2444
|
+
base: Vn,
|
|
2114
2445
|
alias: i.alias,
|
|
2115
2446
|
instance: i.name
|
|
2116
|
-
}),
|
|
2117
|
-
|
|
2118
|
-
let
|
|
2119
|
-
insert: (e) =>
|
|
2120
|
-
getById: (e) =>
|
|
2121
|
-
delete: (e) =>
|
|
2122
|
-
statistics: () =>
|
|
2123
|
-
listRecent: (e) =>
|
|
2124
|
-
countByKey: (e, t) =>
|
|
2125
|
-
usageByTenant: (e) =>
|
|
2126
|
-
consumeUsage: (e, t, n) =>
|
|
2127
|
-
releaseUsage: (e, t) =>
|
|
2128
|
-
listByDerivedFrom: (e) =>
|
|
2129
|
-
listRefs: (e) =>
|
|
2130
|
-
},
|
|
2131
|
-
insert: (e) =>
|
|
2132
|
-
delete: (e) =>
|
|
2133
|
-
getById: (e) =>
|
|
2134
|
-
listByRef: (e) =>
|
|
2135
|
-
deleteByRef: (e) =>
|
|
2136
|
-
},
|
|
2137
|
-
httpPath:
|
|
2138
|
-
provider:
|
|
2139
|
-
refStore:
|
|
2140
|
-
grantStore:
|
|
2141
|
-
bucket:
|
|
2447
|
+
}), b = v === Vn ? "/_voltro/storage" : `/_voltro/storage/i/${Buffer.from(v).toString("hex")}`, x = jn(i);
|
|
2448
|
+
On(x);
|
|
2449
|
+
let S = G.read("S3_BUCKET", i.bucket) ?? G.read("STORAGE_BUCKET") ?? "voltro", E = G.read("VOLTRO_PUBLIC_URL", i.publicBaseUrl), ce = Mn(i.allowedOrigins), D = i.limits?.maxBytes, O = i.anonymousUploads === !0, k = 5242880, le = 21600, A = i.refStore === void 0 || i.refStore === "memory", j = i.grantStore === void 0 || i.grantStore === "memory", M = { current: A ? Rt() : i.refStore }, N = { current: j ? Ht() : i.grantStore }, ue = { current: void 0 }, P = {
|
|
2450
|
+
insert: (e) => M.current.insert(e),
|
|
2451
|
+
getById: (e) => M.current.getById(e),
|
|
2452
|
+
delete: (e) => M.current.delete(e),
|
|
2453
|
+
statistics: () => M.current.statistics(),
|
|
2454
|
+
listRecent: (e) => M.current.listRecent(e),
|
|
2455
|
+
countByKey: (e, t) => M.current.countByKey(e, t),
|
|
2456
|
+
usageByTenant: (e) => M.current.usageByTenant(e),
|
|
2457
|
+
consumeUsage: (e, t, n) => M.current.consumeUsage(e, t, n),
|
|
2458
|
+
releaseUsage: (e, t) => M.current.releaseUsage(e, t),
|
|
2459
|
+
listByDerivedFrom: (e) => M.current.listByDerivedFrom(e),
|
|
2460
|
+
listRefs: (e) => M.current.listRefs(e)
|
|
2461
|
+
}, F = {
|
|
2462
|
+
insert: (e) => N.current.insert(e),
|
|
2463
|
+
delete: (e) => N.current.delete(e),
|
|
2464
|
+
getById: (e) => N.current.getById(e),
|
|
2465
|
+
listByRef: (e) => N.current.listByRef(e),
|
|
2466
|
+
deleteByRef: (e) => N.current.deleteByRef(e)
|
|
2467
|
+
}, de = {
|
|
2468
|
+
httpPath: b,
|
|
2469
|
+
provider: x,
|
|
2470
|
+
refStore: P,
|
|
2471
|
+
grantStore: F,
|
|
2472
|
+
bucket: S,
|
|
2142
2473
|
...i.tenantPrefix === void 0 ? {} : { tenantPrefix: i.tenantPrefix },
|
|
2143
2474
|
...i.attempts === void 0 ? {} : { attempts: i.attempts },
|
|
2144
2475
|
...i.urlExpiresInSec === void 0 ? {} : { urlExpiresInSec: i.urlExpiresInSec },
|
|
@@ -2148,10 +2479,11 @@ var an = (e) => {
|
|
|
2148
2479
|
...i.videoProbe === void 0 ? {} : { videoProbe: i.videoProbe },
|
|
2149
2480
|
...i.transcode === void 0 ? {} : { transcode: i.transcode },
|
|
2150
2481
|
...i.autoTranscode === void 0 ? {} : { autoTranscode: i.autoTranscode },
|
|
2151
|
-
...
|
|
2482
|
+
...E ? { publicBaseUrl: E } : {},
|
|
2152
2483
|
...i.normalizeImages === void 0 ? {} : { normalizeImages: i.normalizeImages },
|
|
2153
|
-
...i.quota === void 0 ? {} : { quota: i.quota }
|
|
2154
|
-
|
|
2484
|
+
...i.quota === void 0 ? {} : { quota: i.quota },
|
|
2485
|
+
objects: () => ue.current
|
|
2486
|
+
}, fe = Jt(de), I = qt(de), L = `${b}/`, R = (e) => y.runPromise(e.pipe(y.catchAll(() => y.succeed(null)))), me = (e, t) => {
|
|
2155
2487
|
if (!e) return "invalid";
|
|
2156
2488
|
let n = /^bytes=(\d*)-(\d*)$/.exec(e.trim());
|
|
2157
2489
|
if (!n) return "invalid";
|
|
@@ -2172,30 +2504,30 @@ var an = (e) => {
|
|
|
2172
2504
|
start: a,
|
|
2173
2505
|
endInclusive: o
|
|
2174
2506
|
};
|
|
2175
|
-
},
|
|
2507
|
+
}, z = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, he = (e) => ({
|
|
2176
2508
|
"x-content-type-options": "nosniff",
|
|
2177
|
-
"content-disposition":
|
|
2178
|
-
}),
|
|
2509
|
+
"content-disposition": z.test(e) ? "inline" : "attachment"
|
|
2510
|
+
}), ge = async (e, t, n, r) => {
|
|
2179
2511
|
if (n) {
|
|
2180
|
-
let r = await
|
|
2512
|
+
let r = await R(I.get(e.id));
|
|
2181
2513
|
if (!r) return {
|
|
2182
2514
|
status: 404,
|
|
2183
2515
|
body: "not found",
|
|
2184
2516
|
contentType: "text/plain"
|
|
2185
2517
|
};
|
|
2186
|
-
let i = await
|
|
2518
|
+
let i = await $e(e.id, r.bytes, e.contentType, n).catch(() => null), a = i ? i.bytes : r.bytes, o = i ? i.contentType : e.contentType;
|
|
2187
2519
|
return {
|
|
2188
2520
|
status: 200,
|
|
2189
2521
|
body: a,
|
|
2190
2522
|
contentType: o,
|
|
2191
2523
|
headers: {
|
|
2192
|
-
...
|
|
2524
|
+
...he(o),
|
|
2193
2525
|
"cache-control": t,
|
|
2194
2526
|
"accept-ranges": "none"
|
|
2195
2527
|
}
|
|
2196
2528
|
};
|
|
2197
2529
|
}
|
|
2198
|
-
let i = r === void 0 ? "invalid" :
|
|
2530
|
+
let i = r === void 0 ? "invalid" : me(r, e.size);
|
|
2199
2531
|
if (i === "unsatisfiable") return {
|
|
2200
2532
|
status: 416,
|
|
2201
2533
|
body: "range not satisfiable",
|
|
@@ -2206,13 +2538,13 @@ var an = (e) => {
|
|
|
2206
2538
|
}
|
|
2207
2539
|
};
|
|
2208
2540
|
if (i !== "invalid") {
|
|
2209
|
-
let n = await
|
|
2541
|
+
let n = await R(I.getRange(e.id, i));
|
|
2210
2542
|
return n ? {
|
|
2211
2543
|
status: 206,
|
|
2212
2544
|
body: n.bytes,
|
|
2213
2545
|
contentType: e.contentType,
|
|
2214
2546
|
headers: {
|
|
2215
|
-
...
|
|
2547
|
+
...he(e.contentType),
|
|
2216
2548
|
"cache-control": t,
|
|
2217
2549
|
"accept-ranges": "bytes",
|
|
2218
2550
|
"content-range": `bytes ${i.start}-${i.endInclusive}/${n.totalSize}`
|
|
@@ -2223,64 +2555,64 @@ var an = (e) => {
|
|
|
2223
2555
|
contentType: "text/plain"
|
|
2224
2556
|
};
|
|
2225
2557
|
}
|
|
2226
|
-
let a = await
|
|
2558
|
+
let a = await R(I.getStream(e.id));
|
|
2227
2559
|
return a ? {
|
|
2228
2560
|
status: 200,
|
|
2229
2561
|
contentType: e.contentType,
|
|
2230
2562
|
headers: {
|
|
2231
|
-
...
|
|
2563
|
+
...he(e.contentType),
|
|
2232
2564
|
"cache-control": t,
|
|
2233
2565
|
"accept-ranges": "bytes"
|
|
2234
2566
|
},
|
|
2235
2567
|
byteStream: {
|
|
2236
2568
|
contentLength: e.size,
|
|
2237
|
-
stream: () =>
|
|
2569
|
+
stream: () => w.toReadableStream(a.stream)
|
|
2238
2570
|
}
|
|
2239
2571
|
} : {
|
|
2240
2572
|
status: 404,
|
|
2241
2573
|
body: "not found",
|
|
2242
2574
|
contentType: "text/plain"
|
|
2243
2575
|
};
|
|
2244
|
-
},
|
|
2245
|
-
let t = e.path.startsWith(
|
|
2576
|
+
}, _e = async (e) => {
|
|
2577
|
+
let t = e.path.startsWith(L) ? e.path.slice(L.length).split("/")[0] ?? "" : "";
|
|
2246
2578
|
if (!t) return {
|
|
2247
2579
|
status: 404,
|
|
2248
2580
|
body: "not found",
|
|
2249
2581
|
contentType: "text/plain"
|
|
2250
2582
|
};
|
|
2251
|
-
let n = await
|
|
2583
|
+
let n = await R(I.head(t));
|
|
2252
2584
|
if (!n) return {
|
|
2253
2585
|
status: 404,
|
|
2254
2586
|
body: "not found",
|
|
2255
2587
|
contentType: "text/plain"
|
|
2256
2588
|
};
|
|
2257
|
-
let r =
|
|
2589
|
+
let r = Ke(e.query), i = e.headers.range;
|
|
2258
2590
|
if (n.visibility === "public") {
|
|
2259
|
-
let e =
|
|
2591
|
+
let e = x.publicUrl?.(n.key) ?? null;
|
|
2260
2592
|
return e && !r ? {
|
|
2261
2593
|
status: 302,
|
|
2262
2594
|
headers: {
|
|
2263
2595
|
location: e,
|
|
2264
2596
|
"cache-control": "public, max-age=300"
|
|
2265
2597
|
}
|
|
2266
|
-
} :
|
|
2598
|
+
} : ge(n, "public, max-age=31536000, immutable", r, i);
|
|
2267
2599
|
}
|
|
2268
2600
|
let a = !1, o = e.query ? new URLSearchParams(e.query).get("t") : null;
|
|
2269
2601
|
if (o) {
|
|
2270
|
-
let e =
|
|
2602
|
+
let e = mt(o);
|
|
2271
2603
|
a = !!e && e.refId === t;
|
|
2272
2604
|
}
|
|
2273
2605
|
if (!a) {
|
|
2274
|
-
let t =
|
|
2275
|
-
r && (a = await
|
|
2606
|
+
let t = ae(e.headers.cookie, En), r = t ? se(t, oe()) : null;
|
|
2607
|
+
r && (a = await R(I.checkAccess(n, r)) === !0);
|
|
2276
2608
|
}
|
|
2277
2609
|
if (!a) return {
|
|
2278
2610
|
status: 403,
|
|
2279
2611
|
body: "forbidden",
|
|
2280
2612
|
contentType: "text/plain"
|
|
2281
2613
|
};
|
|
2282
|
-
if (
|
|
2283
|
-
let e = await
|
|
2614
|
+
if (x.presigns && !r) {
|
|
2615
|
+
let e = await R(x.getUrl(n.key, 300));
|
|
2284
2616
|
if (e && /^https?:/.test(e)) return {
|
|
2285
2617
|
status: 302,
|
|
2286
2618
|
headers: {
|
|
@@ -2289,12 +2621,12 @@ var an = (e) => {
|
|
|
2289
2621
|
}
|
|
2290
2622
|
};
|
|
2291
2623
|
}
|
|
2292
|
-
return
|
|
2293
|
-
},
|
|
2624
|
+
return ge(n, "private, no-store", r, i);
|
|
2625
|
+
}, ve = {
|
|
2294
2626
|
method: "GET",
|
|
2295
|
-
path:
|
|
2627
|
+
path: b,
|
|
2296
2628
|
handle: async (e) => {
|
|
2297
|
-
let t = await
|
|
2629
|
+
let t = await _e(e), n = Nn(e.headers.origin, ce);
|
|
2298
2630
|
return Object.keys(n).length === 0 ? t : {
|
|
2299
2631
|
...t,
|
|
2300
2632
|
headers: {
|
|
@@ -2303,12 +2635,12 @@ var an = (e) => {
|
|
|
2303
2635
|
}
|
|
2304
2636
|
};
|
|
2305
2637
|
}
|
|
2306
|
-
},
|
|
2638
|
+
}, ye = {
|
|
2307
2639
|
method: "*",
|
|
2308
|
-
path: `${
|
|
2640
|
+
path: `${b}/upload`,
|
|
2309
2641
|
originGuard: "exempt",
|
|
2310
2642
|
handle: async (e) => {
|
|
2311
|
-
let t =
|
|
2643
|
+
let t = Nn(e.headers.origin, ce);
|
|
2312
2644
|
if (e.method === "OPTIONS") return {
|
|
2313
2645
|
status: 204,
|
|
2314
2646
|
headers: t
|
|
@@ -2319,8 +2651,8 @@ var an = (e) => {
|
|
|
2319
2651
|
contentType: "text/plain",
|
|
2320
2652
|
headers: t
|
|
2321
2653
|
};
|
|
2322
|
-
let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ?
|
|
2323
|
-
if (!r || r.instance !==
|
|
2654
|
+
let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, r = n ? gt(n) : null;
|
|
2655
|
+
if (!r || r.instance !== v) return {
|
|
2324
2656
|
status: 401,
|
|
2325
2657
|
body: "invalid or expired upload ticket",
|
|
2326
2658
|
contentType: "text/plain",
|
|
@@ -2338,7 +2670,7 @@ var an = (e) => {
|
|
|
2338
2670
|
contentType: "text/plain",
|
|
2339
2671
|
headers: t
|
|
2340
2672
|
};
|
|
2341
|
-
let i = await
|
|
2673
|
+
let i = await y.runPromise(I.put({
|
|
2342
2674
|
bytes: e.rawBody,
|
|
2343
2675
|
contentType: r.ct,
|
|
2344
2676
|
tenantId: r.tenant,
|
|
@@ -2349,21 +2681,21 @@ var an = (e) => {
|
|
|
2349
2681
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
2350
2682
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
2351
2683
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
2352
|
-
}).pipe(
|
|
2684
|
+
}).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
|
|
2353
2685
|
kind: "ok",
|
|
2354
2686
|
ref: e,
|
|
2355
2687
|
url: t
|
|
2356
|
-
})))),
|
|
2357
|
-
StorageRejected: (e) =>
|
|
2688
|
+
})))), y.catchTags({
|
|
2689
|
+
StorageRejected: (e) => y.succeed({
|
|
2358
2690
|
kind: "rejected",
|
|
2359
2691
|
status: e.reason === "too-large" ? 413 : 415,
|
|
2360
2692
|
detail: e.detail
|
|
2361
2693
|
}),
|
|
2362
|
-
StorageScanRejected: (e) =>
|
|
2694
|
+
StorageScanRejected: (e) => y.succeed({
|
|
2363
2695
|
kind: "scan",
|
|
2364
2696
|
threat: e.threat
|
|
2365
2697
|
}),
|
|
2366
|
-
StorageError: (e) =>
|
|
2698
|
+
StorageError: (e) => y.succeed({
|
|
2367
2699
|
kind: "error",
|
|
2368
2700
|
message: e.message
|
|
2369
2701
|
})
|
|
@@ -2395,28 +2727,28 @@ var an = (e) => {
|
|
|
2395
2727
|
headers: t
|
|
2396
2728
|
};
|
|
2397
2729
|
}
|
|
2398
|
-
},
|
|
2730
|
+
}, be = {
|
|
2399
2731
|
method: "*",
|
|
2400
|
-
path: `${
|
|
2732
|
+
path: `${b}/upload/resumable`,
|
|
2401
2733
|
originGuard: "exempt",
|
|
2402
2734
|
handle: async (e) => {
|
|
2403
|
-
let t =
|
|
2735
|
+
let t = Nn(e.headers.origin, ce);
|
|
2404
2736
|
if (e.method === "OPTIONS") return {
|
|
2405
2737
|
status: 204,
|
|
2406
2738
|
headers: t
|
|
2407
2739
|
};
|
|
2408
|
-
let n = new URLSearchParams(e.query || ""), r =
|
|
2409
|
-
if (!r || r.instance !==
|
|
2740
|
+
let n = new URLSearchParams(e.query || ""), r = bt(n.get("token") ?? "");
|
|
2741
|
+
if (!r || r.instance !== v) return {
|
|
2410
2742
|
status: 401,
|
|
2411
2743
|
body: "invalid or expired resumable token",
|
|
2412
2744
|
contentType: "text/plain",
|
|
2413
2745
|
headers: t
|
|
2414
2746
|
};
|
|
2415
2747
|
if (e.method === "GET" || e.method === "HEAD") {
|
|
2416
|
-
let e = await
|
|
2748
|
+
let e = await y.runPromise(I.resumableStatus({
|
|
2417
2749
|
uploadId: r.id,
|
|
2418
2750
|
tenantId: r.tenant
|
|
2419
|
-
}).pipe(
|
|
2751
|
+
}).pipe(y.match({
|
|
2420
2752
|
onFailure: (e) => ({ error: e.message }),
|
|
2421
2753
|
onSuccess: (e) => e
|
|
2422
2754
|
})));
|
|
@@ -2454,12 +2786,12 @@ var an = (e) => {
|
|
|
2454
2786
|
contentType: "text/plain",
|
|
2455
2787
|
headers: t
|
|
2456
2788
|
};
|
|
2457
|
-
let a = n.get("final") === "1", o = await
|
|
2789
|
+
let a = n.get("final") === "1", o = await y.runPromise(I.putResumableChunk({
|
|
2458
2790
|
uploadId: r.id,
|
|
2459
2791
|
tenantId: r.tenant,
|
|
2460
2792
|
index: i,
|
|
2461
2793
|
bytes: e.rawBody
|
|
2462
|
-
}).pipe(
|
|
2794
|
+
}).pipe(y.flatMap(() => a ? I.finalizeResumable({
|
|
2463
2795
|
uploadId: r.id,
|
|
2464
2796
|
count: i + 1,
|
|
2465
2797
|
contentType: r.ct,
|
|
@@ -2470,21 +2802,21 @@ var an = (e) => {
|
|
|
2470
2802
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
2471
2803
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
2472
2804
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
2473
|
-
}).pipe(
|
|
2805
|
+
}).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
|
|
2474
2806
|
kind: "done",
|
|
2475
2807
|
ref: e,
|
|
2476
2808
|
url: t
|
|
2477
|
-
}))))) :
|
|
2478
|
-
StorageRejected: (e) =>
|
|
2809
|
+
}))))) : y.succeed({ kind: "chunk" })), y.catchTags({
|
|
2810
|
+
StorageRejected: (e) => y.succeed({
|
|
2479
2811
|
kind: "rejected",
|
|
2480
2812
|
status: e.reason === "too-large" ? 413 : 415,
|
|
2481
2813
|
detail: e.detail
|
|
2482
2814
|
}),
|
|
2483
|
-
StorageScanRejected: (e) =>
|
|
2815
|
+
StorageScanRejected: (e) => y.succeed({
|
|
2484
2816
|
kind: "scan",
|
|
2485
2817
|
threat: e.threat
|
|
2486
2818
|
}),
|
|
2487
|
-
StorageError: (e) =>
|
|
2819
|
+
StorageError: (e) => y.succeed({
|
|
2488
2820
|
kind: "error",
|
|
2489
2821
|
message: e.message
|
|
2490
2822
|
})
|
|
@@ -2522,41 +2854,41 @@ var an = (e) => {
|
|
|
2522
2854
|
headers: t
|
|
2523
2855
|
};
|
|
2524
2856
|
}
|
|
2525
|
-
},
|
|
2857
|
+
}, B = (e) => ({
|
|
2526
2858
|
kind: "json",
|
|
2527
2859
|
data: e
|
|
2528
|
-
}),
|
|
2860
|
+
}), V = (e, t) => ({
|
|
2529
2861
|
kind: "json",
|
|
2530
2862
|
status: e,
|
|
2531
2863
|
data: { error: t }
|
|
2532
|
-
}),
|
|
2864
|
+
}), xe = (e, t) => {
|
|
2533
2865
|
try {
|
|
2534
2866
|
return new URL(e, "http://localhost").searchParams.get(t);
|
|
2535
2867
|
} catch {
|
|
2536
2868
|
return null;
|
|
2537
2869
|
}
|
|
2538
|
-
},
|
|
2870
|
+
}, Se = [
|
|
2539
2871
|
{
|
|
2540
2872
|
method: "POST",
|
|
2541
2873
|
path: "/upload-ticket",
|
|
2542
2874
|
description: "Authorize a binary upload with explicit tenant and owner attribution",
|
|
2543
|
-
handler: (e) =>
|
|
2544
|
-
let n =
|
|
2545
|
-
tenantId:
|
|
2546
|
-
ownerId:
|
|
2547
|
-
key: n.pipe(
|
|
2548
|
-
contentType: n.pipe(
|
|
2549
|
-
size:
|
|
2550
|
-
visibility:
|
|
2551
|
-
})))(e.body).pipe(
|
|
2875
|
+
handler: (e) => y.gen(function* () {
|
|
2876
|
+
let n = C.String.pipe(C.filter((e) => e.trim().length > 0)), r = yield* C.decodeUnknown(C.parseJson(C.Struct({
|
|
2877
|
+
tenantId: C.NullOr(n),
|
|
2878
|
+
ownerId: C.NullOr(n),
|
|
2879
|
+
key: n.pipe(C.maxLength(1024)),
|
|
2880
|
+
contentType: n.pipe(C.maxLength(255), C.filter((e) => !/[\r\n]/.test(e))),
|
|
2881
|
+
size: C.Number.pipe(C.int(), C.positive(), C.filter(Number.isSafeInteger)),
|
|
2882
|
+
visibility: C.optional(C.Literal("public", "private"))
|
|
2883
|
+
})))(e.body).pipe(y.mapError(() => new t({
|
|
2552
2884
|
provider: "inspect",
|
|
2553
2885
|
message: "Provide explicit tenantId and ownerId (or null), key, contentType and a positive file size",
|
|
2554
2886
|
transient: !1,
|
|
2555
2887
|
status: 400
|
|
2556
2888
|
})));
|
|
2557
|
-
if (
|
|
2558
|
-
let i =
|
|
2559
|
-
instance:
|
|
2889
|
+
if (D !== void 0 && r.size > D) return V(413, "File exceeds the configured upload limit");
|
|
2890
|
+
let i = ht({
|
|
2891
|
+
instance: v,
|
|
2560
2892
|
sub: r.ownerId,
|
|
2561
2893
|
tenant: r.tenantId,
|
|
2562
2894
|
ct: r.contentType,
|
|
@@ -2564,40 +2896,40 @@ var an = (e) => {
|
|
|
2564
2896
|
vis: r.visibility ?? "private",
|
|
2565
2897
|
max: r.size
|
|
2566
2898
|
}, 300);
|
|
2567
|
-
return
|
|
2568
|
-
uploadPath: `${
|
|
2899
|
+
return B({
|
|
2900
|
+
uploadPath: `${b}/upload?ticket=${encodeURIComponent(i)}`,
|
|
2569
2901
|
expiresInSec: 300,
|
|
2570
2902
|
maxBytes: r.size
|
|
2571
2903
|
});
|
|
2572
|
-
}).pipe(
|
|
2904
|
+
}).pipe(y.catchAll((e) => y.succeed(V(e.status ?? 500, e.message))))
|
|
2573
2905
|
},
|
|
2574
2906
|
{
|
|
2575
2907
|
method: "GET",
|
|
2576
2908
|
path: "/download",
|
|
2577
2909
|
description: "Stream a stored file as an attachment for authorized inspect readers",
|
|
2578
|
-
handler: (e) =>
|
|
2579
|
-
let t =
|
|
2580
|
-
if (!t?.trim()) return
|
|
2581
|
-
let { ref: n, stream: r } = yield*
|
|
2910
|
+
handler: (e) => y.gen(function* () {
|
|
2911
|
+
let t = xe(e.url, "refId");
|
|
2912
|
+
if (!t?.trim()) return V(400, "A non-empty refId is required");
|
|
2913
|
+
let { ref: n, stream: r } = yield* I.getStream(t), i = n.key.split("/").pop() || n.id, a = encodeURIComponent(i).replace(/[!'()*]/g, (e) => `%${e.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
2582
2914
|
return {
|
|
2583
2915
|
kind: "bytes",
|
|
2584
2916
|
contentType: n.contentType,
|
|
2585
2917
|
byteStream: {
|
|
2586
|
-
stream: () =>
|
|
2918
|
+
stream: () => w.toReadableStream(r),
|
|
2587
2919
|
contentLength: n.size,
|
|
2588
2920
|
contentDisposition: `attachment; filename="download"; filename*=UTF-8''${a}`
|
|
2589
2921
|
},
|
|
2590
2922
|
headers: { "cache-control": "no-store" }
|
|
2591
2923
|
};
|
|
2592
|
-
}).pipe(
|
|
2924
|
+
}).pipe(y.catchAll((e) => y.succeed(V(e.status ?? 500, e.message))))
|
|
2593
2925
|
},
|
|
2594
2926
|
{
|
|
2595
2927
|
method: "GET",
|
|
2596
2928
|
path: "/refs",
|
|
2597
2929
|
description: "Searchable storage refs, newest first, paginated",
|
|
2598
2930
|
handler: (e) => {
|
|
2599
|
-
let t = Number(
|
|
2600
|
-
return
|
|
2931
|
+
let t = Number(xe(e.url, "offset") ?? 0), n = Number.isSafeInteger(t) && t >= 0 ? t : 0, r = (xe(e.url, "search") ?? "").trim().slice(0, 200);
|
|
2932
|
+
return P.listRefs({
|
|
2601
2933
|
tenantId: void 0,
|
|
2602
2934
|
ownerId: void 0,
|
|
2603
2935
|
folder: void 0,
|
|
@@ -2606,121 +2938,121 @@ var an = (e) => {
|
|
|
2606
2938
|
search: r,
|
|
2607
2939
|
limit: 51,
|
|
2608
2940
|
offset: n
|
|
2609
|
-
}).pipe(
|
|
2610
|
-
refs: e.slice(0, 50).map(
|
|
2941
|
+
}).pipe(y.map((e) => B({
|
|
2942
|
+
refs: e.slice(0, 50).map(Pn),
|
|
2611
2943
|
page: {
|
|
2612
2944
|
search: r,
|
|
2613
2945
|
offset: n,
|
|
2614
2946
|
nextOffset: e.length > 50 ? n + 50 : null
|
|
2615
2947
|
}
|
|
2616
|
-
})),
|
|
2948
|
+
})), y.catchAll((e) => y.succeed(V(500, e.message))));
|
|
2617
2949
|
}
|
|
2618
2950
|
},
|
|
2619
2951
|
{
|
|
2620
2952
|
method: "GET",
|
|
2621
2953
|
path: "/stats",
|
|
2622
2954
|
description: "Object count + total bytes per tenant + visibility split",
|
|
2623
|
-
handler: () =>
|
|
2624
|
-
provider:
|
|
2625
|
-
bucket:
|
|
2955
|
+
handler: () => P.statistics().pipe(y.map((e) => B({
|
|
2956
|
+
provider: x.name,
|
|
2957
|
+
bucket: S,
|
|
2626
2958
|
...e
|
|
2627
|
-
})),
|
|
2959
|
+
})), y.catchAll((e) => y.succeed(V(500, e.message))))
|
|
2628
2960
|
},
|
|
2629
2961
|
{
|
|
2630
2962
|
method: "GET",
|
|
2631
2963
|
path: "/grants",
|
|
2632
2964
|
description: "Grants for a ref (?refId=…)",
|
|
2633
2965
|
handler: (e) => {
|
|
2634
|
-
let t =
|
|
2635
|
-
return t ?
|
|
2966
|
+
let t = xe(e.url, "refId");
|
|
2967
|
+
return t ? F.listByRef(t).pipe(y.map((e) => B({ grants: e.map(Bn) })), y.catchAll((e) => y.succeed(V(500, e.message)))) : y.succeed(V(400, "refId query param required"));
|
|
2636
2968
|
}
|
|
2637
2969
|
},
|
|
2638
2970
|
{
|
|
2639
2971
|
method: "POST",
|
|
2640
2972
|
path: "/share",
|
|
2641
2973
|
description: "Grant a principal access to a ref",
|
|
2642
|
-
handler: (e) =>
|
|
2643
|
-
let n = yield*
|
|
2644
|
-
refId:
|
|
2645
|
-
principalType:
|
|
2646
|
-
principalId:
|
|
2647
|
-
permission:
|
|
2648
|
-
expiresInDays:
|
|
2649
|
-
})))(e.body).pipe(
|
|
2974
|
+
handler: (e) => y.gen(function* () {
|
|
2975
|
+
let n = yield* C.decodeUnknown(C.parseJson(C.Struct({
|
|
2976
|
+
refId: C.String.pipe(C.filter((e) => e.trim().length > 0)),
|
|
2977
|
+
principalType: C.Literal("user", "group", "apiKey"),
|
|
2978
|
+
principalId: C.String.pipe(C.filter((e) => e.trim().length > 0)),
|
|
2979
|
+
permission: C.optional(C.Literal("read", "write")),
|
|
2980
|
+
expiresInDays: C.optional(C.Number.pipe(C.finite(), C.positive()))
|
|
2981
|
+
})))(e.body).pipe(y.mapError(() => new t({
|
|
2650
2982
|
provider: "inspect",
|
|
2651
2983
|
message: "Invalid share input: provide refId, principalType, principalId, read/write permission and a positive finite expiry if set",
|
|
2652
2984
|
transient: !1,
|
|
2653
2985
|
status: 400
|
|
2654
2986
|
}))), r = n.expiresInDays === void 0 ? null : new Date(Date.now() + n.expiresInDays * 864e5);
|
|
2655
|
-
if (r !== null && !Number.isFinite(r.getTime())) return
|
|
2656
|
-
let i = yield*
|
|
2987
|
+
if (r !== null && !Number.isFinite(r.getTime())) return V(400, "Expiry exceeds the supported date range");
|
|
2988
|
+
let i = yield* I.grant({
|
|
2657
2989
|
refId: n.refId,
|
|
2658
2990
|
principalType: n.principalType,
|
|
2659
2991
|
principalId: n.principalId,
|
|
2660
2992
|
...n.permission ? { permission: n.permission } : {},
|
|
2661
2993
|
expiresAt: r
|
|
2662
2994
|
});
|
|
2663
|
-
return
|
|
2664
|
-
}).pipe(
|
|
2995
|
+
return B({ grant: Bn(i) });
|
|
2996
|
+
}).pipe(y.catchAll((e) => y.succeed(V(e.status ?? 500, e.message ?? "share failed"))))
|
|
2665
2997
|
},
|
|
2666
2998
|
{
|
|
2667
2999
|
method: "POST",
|
|
2668
3000
|
path: "/delete",
|
|
2669
3001
|
description: "Delete an object reference and its grants; release unreferenced bytes",
|
|
2670
|
-
handler: (e) =>
|
|
2671
|
-
let n = yield*
|
|
3002
|
+
handler: (e) => y.gen(function* () {
|
|
3003
|
+
let n = yield* C.decodeUnknown(C.parseJson(C.Struct({ refId: C.String.pipe(C.filter((e) => e.trim().length > 0)) })))(e.body).pipe(y.mapError(() => new t({
|
|
2672
3004
|
provider: "inspect",
|
|
2673
3005
|
message: "A non-empty refId is required",
|
|
2674
3006
|
transient: !1,
|
|
2675
3007
|
status: 400
|
|
2676
3008
|
})));
|
|
2677
|
-
return yield*
|
|
2678
|
-
}).pipe(
|
|
3009
|
+
return yield* I.delete(n.refId), B({ ok: !0 });
|
|
3010
|
+
}).pipe(y.catchAll((e) => y.succeed(V(e.status ?? 500, e.message))))
|
|
2679
3011
|
},
|
|
2680
3012
|
{
|
|
2681
3013
|
method: "POST",
|
|
2682
3014
|
path: "/revoke",
|
|
2683
3015
|
description: "Revoke a grant by id",
|
|
2684
|
-
handler: (e) =>
|
|
2685
|
-
let n = yield*
|
|
3016
|
+
handler: (e) => y.gen(function* () {
|
|
3017
|
+
let n = yield* C.decodeUnknown(C.parseJson(C.Struct({ grantId: C.String.pipe(C.filter((e) => e.trim().length > 0)) })))(e.body).pipe(y.mapError(() => new t({
|
|
2686
3018
|
provider: "inspect",
|
|
2687
3019
|
message: "A non-empty grantId is required",
|
|
2688
3020
|
transient: !1,
|
|
2689
3021
|
status: 400
|
|
2690
3022
|
})));
|
|
2691
|
-
return yield*
|
|
2692
|
-
}).pipe(
|
|
3023
|
+
return yield* I.revoke(n.grantId), B({ ok: !0 });
|
|
3024
|
+
}).pipe(y.catchAll((e) => y.succeed(V(e.status ?? 500, e.message ?? "revoke failed"))))
|
|
2693
3025
|
}
|
|
2694
|
-
],
|
|
3026
|
+
], Ce = [
|
|
2695
3027
|
{
|
|
2696
3028
|
...h,
|
|
2697
3029
|
execute: (e, t) => {
|
|
2698
3030
|
let n = e;
|
|
2699
|
-
return
|
|
3031
|
+
return I.mintUrl(n.id, t.request.subject, {
|
|
2700
3032
|
...n.password === void 0 ? {} : { password: n.password },
|
|
2701
3033
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
2702
|
-
}).pipe(
|
|
3034
|
+
}).pipe(y.map((e) => ({ url: e })));
|
|
2703
3035
|
}
|
|
2704
3036
|
},
|
|
2705
3037
|
{
|
|
2706
3038
|
...ee,
|
|
2707
3039
|
execute: (e, t) => {
|
|
2708
3040
|
let n = e;
|
|
2709
|
-
return
|
|
3041
|
+
return I.mintUploadUrl({
|
|
2710
3042
|
key: n.key,
|
|
2711
3043
|
contentType: n.contentType,
|
|
2712
3044
|
tenantId: t.request.subject.tenantId,
|
|
2713
3045
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
2714
|
-
}).pipe(
|
|
3046
|
+
}).pipe(y.map((e) => ({ url: e })));
|
|
2715
3047
|
}
|
|
2716
3048
|
},
|
|
2717
3049
|
{
|
|
2718
3050
|
...m,
|
|
2719
3051
|
execute: (e, t) => {
|
|
2720
3052
|
let n = e;
|
|
2721
|
-
return
|
|
2722
|
-
let t = n.expiresInSec ?? 900, r =
|
|
2723
|
-
instance:
|
|
3053
|
+
return Rn(t, O).pipe(y.map((e) => {
|
|
3054
|
+
let t = n.expiresInSec ?? 900, r = ht({
|
|
3055
|
+
instance: v,
|
|
2724
3056
|
sub: e.id,
|
|
2725
3057
|
tenant: e.tenantId,
|
|
2726
3058
|
ct: n.contentType,
|
|
@@ -2730,10 +3062,10 @@ var an = (e) => {
|
|
|
2730
3062
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
2731
3063
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2732
3064
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2733
|
-
...
|
|
3065
|
+
...D === void 0 ? {} : { max: D }
|
|
2734
3066
|
}, t);
|
|
2735
3067
|
return {
|
|
2736
|
-
uploadUrl: `${
|
|
3068
|
+
uploadUrl: `${E ? E.replace(/\/+$/, "") : ""}${b}/upload?ticket=${encodeURIComponent(r)}`,
|
|
2737
3069
|
expiresInSec: t
|
|
2738
3070
|
};
|
|
2739
3071
|
}));
|
|
@@ -2743,13 +3075,13 @@ var an = (e) => {
|
|
|
2743
3075
|
...p,
|
|
2744
3076
|
execute: (e, t) => {
|
|
2745
3077
|
let n = e;
|
|
2746
|
-
return
|
|
3078
|
+
return Rn(t, O).pipe(y.flatMap((e) => I.mintPresignedUpload({
|
|
2747
3079
|
contentType: n.contentType,
|
|
2748
3080
|
tenantId: e.tenantId,
|
|
2749
3081
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
2750
|
-
}).pipe(
|
|
2751
|
-
let r =
|
|
2752
|
-
instance:
|
|
3082
|
+
}).pipe(y.map((t) => {
|
|
3083
|
+
let r = _t({
|
|
3084
|
+
instance: v,
|
|
2753
3085
|
key: t.key,
|
|
2754
3086
|
sub: e.id,
|
|
2755
3087
|
tenant: e.tenantId,
|
|
@@ -2759,7 +3091,7 @@ var an = (e) => {
|
|
|
2759
3091
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
2760
3092
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2761
3093
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2762
|
-
...
|
|
3094
|
+
...D === void 0 ? {} : { max: D }
|
|
2763
3095
|
}, t.expiresInSec);
|
|
2764
3096
|
return {
|
|
2765
3097
|
uploadUrl: t.uploadUrl,
|
|
@@ -2772,18 +3104,18 @@ var an = (e) => {
|
|
|
2772
3104
|
{
|
|
2773
3105
|
...l,
|
|
2774
3106
|
execute: (e, n) => {
|
|
2775
|
-
let r =
|
|
2776
|
-
return !r || r.instance !==
|
|
3107
|
+
let r = vt(e.finalizeToken);
|
|
3108
|
+
return !r || r.instance !== v ? y.fail(new t({
|
|
2777
3109
|
provider: "storage",
|
|
2778
3110
|
message: "invalid or expired finalize token",
|
|
2779
3111
|
transient: !1,
|
|
2780
3112
|
status: 401
|
|
2781
|
-
})) :
|
|
3113
|
+
})) : zn(r.sub, n.request.subject.id) ? y.fail(new t({
|
|
2782
3114
|
provider: "storage",
|
|
2783
3115
|
message: "finalize token belongs to another subject",
|
|
2784
3116
|
transient: !1,
|
|
2785
3117
|
status: 403
|
|
2786
|
-
})) :
|
|
3118
|
+
})) : I.finalizeUpload({
|
|
2787
3119
|
key: r.key,
|
|
2788
3120
|
contentType: r.ct,
|
|
2789
3121
|
tenantId: r.tenant,
|
|
@@ -2793,7 +3125,7 @@ var an = (e) => {
|
|
|
2793
3125
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
2794
3126
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
2795
3127
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
2796
|
-
}).pipe(
|
|
3128
|
+
}).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
|
|
2797
3129
|
id: e.id,
|
|
2798
3130
|
url: t,
|
|
2799
3131
|
contentType: e.contentType,
|
|
@@ -2807,12 +3139,12 @@ var an = (e) => {
|
|
|
2807
3139
|
...s,
|
|
2808
3140
|
execute: (e, t) => {
|
|
2809
3141
|
let n = e;
|
|
2810
|
-
return
|
|
2811
|
-
let t = n.expiresInSec ??
|
|
3142
|
+
return Rn(t, O).pipe(y.map((e) => {
|
|
3143
|
+
let t = n.expiresInSec ?? le, r = pe(), i = n.chunkSize && n.chunkSize > 0 ? n.chunkSize : k;
|
|
2812
3144
|
return {
|
|
2813
3145
|
uploadId: r,
|
|
2814
|
-
resumableToken:
|
|
2815
|
-
instance:
|
|
3146
|
+
resumableToken: yt({
|
|
3147
|
+
instance: v,
|
|
2816
3148
|
id: r,
|
|
2817
3149
|
sub: e.id,
|
|
2818
3150
|
tenant: e.tenantId,
|
|
@@ -2823,9 +3155,9 @@ var an = (e) => {
|
|
|
2823
3155
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
2824
3156
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2825
3157
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2826
|
-
...
|
|
3158
|
+
...D === void 0 ? {} : { max: D }
|
|
2827
3159
|
}, t),
|
|
2828
|
-
uploadUrl: `${
|
|
3160
|
+
uploadUrl: `${E ? E.replace(/\/+$/, "") : ""}${b}/upload/resumable`,
|
|
2829
3161
|
chunkSize: i,
|
|
2830
3162
|
expiresInSec: t
|
|
2831
3163
|
};
|
|
@@ -2835,15 +3167,15 @@ var an = (e) => {
|
|
|
2835
3167
|
{
|
|
2836
3168
|
...o,
|
|
2837
3169
|
execute: (e, t) => {
|
|
2838
|
-
let n = e, r = n.expiresInSec ??
|
|
2839
|
-
return
|
|
3170
|
+
let n = e, r = n.expiresInSec ?? le;
|
|
3171
|
+
return Rn(t, O).pipe(y.flatMap((e) => I.beginMultipartUpload({
|
|
2840
3172
|
contentType: n.contentType,
|
|
2841
3173
|
tenantId: e.tenantId,
|
|
2842
3174
|
visibility: n.visibility ?? "private",
|
|
2843
3175
|
expiresInSec: r
|
|
2844
|
-
}).pipe(
|
|
2845
|
-
multipartToken:
|
|
2846
|
-
instance:
|
|
3176
|
+
}).pipe(y.map((t) => ({
|
|
3177
|
+
multipartToken: xt({
|
|
3178
|
+
instance: v,
|
|
2847
3179
|
key: t.key,
|
|
2848
3180
|
uploadId: t.uploadId,
|
|
2849
3181
|
sub: e.id,
|
|
@@ -2856,47 +3188,47 @@ var an = (e) => {
|
|
|
2856
3188
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2857
3189
|
...n.caption === void 0 ? {} : { caption: n.caption }
|
|
2858
3190
|
}, r),
|
|
2859
|
-
partSize: n.partSize && n.partSize >=
|
|
3191
|
+
partSize: n.partSize && n.partSize >= k ? n.partSize : k,
|
|
2860
3192
|
expiresInSec: r
|
|
2861
3193
|
})))));
|
|
2862
3194
|
}
|
|
2863
3195
|
},
|
|
2864
3196
|
{
|
|
2865
|
-
...
|
|
3197
|
+
..._,
|
|
2866
3198
|
execute: (e) => {
|
|
2867
|
-
let n = e, r =
|
|
2868
|
-
return !r || r.instance !==
|
|
3199
|
+
let n = e, r = St(n.multipartToken);
|
|
3200
|
+
return !r || r.instance !== v ? y.fail(new t({
|
|
2869
3201
|
provider: "storage",
|
|
2870
3202
|
message: "invalid or expired multipart token",
|
|
2871
3203
|
transient: !1,
|
|
2872
3204
|
status: 401
|
|
2873
|
-
})) : !Number.isInteger(n.partNumber) || n.partNumber < 1 ?
|
|
3205
|
+
})) : !Number.isInteger(n.partNumber) || n.partNumber < 1 ? y.fail(new t({
|
|
2874
3206
|
provider: "storage",
|
|
2875
3207
|
message: "partNumber must be a positive integer",
|
|
2876
3208
|
transient: !1,
|
|
2877
3209
|
status: 400
|
|
2878
|
-
})) :
|
|
3210
|
+
})) : I.signMultipartPart({
|
|
2879
3211
|
key: r.key,
|
|
2880
3212
|
uploadId: r.uploadId,
|
|
2881
3213
|
partNumber: n.partNumber
|
|
2882
|
-
}).pipe(
|
|
3214
|
+
}).pipe(y.map((e) => ({ url: e })));
|
|
2883
3215
|
}
|
|
2884
3216
|
},
|
|
2885
3217
|
{
|
|
2886
3218
|
...c,
|
|
2887
3219
|
execute: (e, n) => {
|
|
2888
|
-
let r = e, i =
|
|
2889
|
-
return !i || i.instance !==
|
|
3220
|
+
let r = e, i = St(r.multipartToken);
|
|
3221
|
+
return !i || i.instance !== v ? y.fail(new t({
|
|
2890
3222
|
provider: "storage",
|
|
2891
3223
|
message: "invalid or expired multipart token",
|
|
2892
3224
|
transient: !1,
|
|
2893
3225
|
status: 401
|
|
2894
|
-
})) :
|
|
3226
|
+
})) : zn(i.sub, n.request.subject.id) ? y.fail(new t({
|
|
2895
3227
|
provider: "storage",
|
|
2896
3228
|
message: "multipart token belongs to another subject",
|
|
2897
3229
|
transient: !1,
|
|
2898
3230
|
status: 403
|
|
2899
|
-
})) :
|
|
3231
|
+
})) : I.completeMultipart({
|
|
2900
3232
|
key: i.key,
|
|
2901
3233
|
uploadId: i.uploadId,
|
|
2902
3234
|
parts: r.parts,
|
|
@@ -2908,7 +3240,7 @@ var an = (e) => {
|
|
|
2908
3240
|
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
2909
3241
|
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
2910
3242
|
...i.caption === void 0 ? {} : { caption: i.caption }
|
|
2911
|
-
}).pipe(
|
|
3243
|
+
}).pipe(y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
|
|
2912
3244
|
id: e.id,
|
|
2913
3245
|
url: t,
|
|
2914
3246
|
size: e.size
|
|
@@ -2918,23 +3250,23 @@ var an = (e) => {
|
|
|
2918
3250
|
{
|
|
2919
3251
|
...a,
|
|
2920
3252
|
execute: (e) => {
|
|
2921
|
-
let n =
|
|
2922
|
-
return !n || n.instance !==
|
|
3253
|
+
let n = St(e.multipartToken);
|
|
3254
|
+
return !n || n.instance !== v ? y.fail(new t({
|
|
2923
3255
|
provider: "storage",
|
|
2924
3256
|
message: "invalid or expired multipart token",
|
|
2925
3257
|
transient: !1,
|
|
2926
3258
|
status: 401
|
|
2927
|
-
})) :
|
|
3259
|
+
})) : I.abortMultipart({
|
|
2928
3260
|
key: n.key,
|
|
2929
3261
|
uploadId: n.uploadId
|
|
2930
|
-
}).pipe(
|
|
3262
|
+
}).pipe(y.as({ ok: !0 }));
|
|
2931
3263
|
}
|
|
2932
3264
|
},
|
|
2933
3265
|
{
|
|
2934
|
-
...
|
|
3266
|
+
...re,
|
|
2935
3267
|
execute: (e, t) => {
|
|
2936
3268
|
let n = e, r = new Uint8Array(Buffer.from(n.bytesBase64, "base64"));
|
|
2937
|
-
return
|
|
3269
|
+
return Rn(t, O).pipe(y.flatMap((e) => I.put({
|
|
2938
3270
|
bytes: r,
|
|
2939
3271
|
contentType: n.contentType,
|
|
2940
3272
|
tenantId: e.tenantId,
|
|
@@ -2942,7 +3274,7 @@ var an = (e) => {
|
|
|
2942
3274
|
...n.visibility ? { visibility: n.visibility } : {},
|
|
2943
3275
|
...n.key ? { key: n.key } : {},
|
|
2944
3276
|
...n.password ? { password: n.password } : {}
|
|
2945
|
-
})),
|
|
3277
|
+
})), y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
|
|
2946
3278
|
id: e.id,
|
|
2947
3279
|
url: t
|
|
2948
3280
|
})))));
|
|
@@ -2952,7 +3284,7 @@ var an = (e) => {
|
|
|
2952
3284
|
...u,
|
|
2953
3285
|
execute: (e, t) => {
|
|
2954
3286
|
let n = e;
|
|
2955
|
-
return
|
|
3287
|
+
return Rn(t, O).pipe(y.flatMap((e) => I.ingestUrl(n.url, {
|
|
2956
3288
|
tenantId: e.tenantId,
|
|
2957
3289
|
ownerId: e.id,
|
|
2958
3290
|
...n.visibility ? { visibility: n.visibility } : {},
|
|
@@ -2961,45 +3293,45 @@ var an = (e) => {
|
|
|
2961
3293
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
2962
3294
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
2963
3295
|
...n.key === void 0 ? {} : { key: n.key }
|
|
2964
|
-
})),
|
|
3296
|
+
})), y.flatMap((e) => I.getUrl(e.id).pipe(y.map((t) => ({
|
|
2965
3297
|
id: e.id,
|
|
2966
3298
|
url: t
|
|
2967
3299
|
})))));
|
|
2968
3300
|
}
|
|
2969
3301
|
},
|
|
2970
3302
|
{
|
|
2971
|
-
...
|
|
3303
|
+
...te,
|
|
2972
3304
|
execute: (e, t) => {
|
|
2973
3305
|
let n = e, r = n.expiresInDays ? new Date(Date.now() + n.expiresInDays * 864e5) : null;
|
|
2974
|
-
return
|
|
3306
|
+
return In(I, n.refId, t).pipe(y.flatMap(() => I.grant({
|
|
2975
3307
|
refId: n.refId,
|
|
2976
3308
|
principalType: n.principalType,
|
|
2977
3309
|
principalId: n.principalId,
|
|
2978
3310
|
...n.permission ? { permission: n.permission } : {},
|
|
2979
3311
|
expiresAt: r,
|
|
2980
3312
|
createdBy: t.request.subject.id
|
|
2981
|
-
})),
|
|
3313
|
+
})), y.map((e) => ({ grantId: e.id })));
|
|
2982
3314
|
}
|
|
2983
3315
|
},
|
|
2984
3316
|
{
|
|
2985
3317
|
...g,
|
|
2986
3318
|
execute: (e, t) => {
|
|
2987
3319
|
let n = e;
|
|
2988
|
-
return
|
|
3320
|
+
return I.getGrant(n.grantId).pipe(y.flatMap((e) => e === null ? y.fail(Fn()) : In(I, e.refId, t)), y.flatMap(() => I.revoke(n.grantId)), y.map(() => ({ ok: !0 })));
|
|
2989
3321
|
}
|
|
2990
3322
|
},
|
|
2991
3323
|
{
|
|
2992
3324
|
...d,
|
|
2993
3325
|
execute: (e, t) => {
|
|
2994
3326
|
let n = e;
|
|
2995
|
-
return
|
|
3327
|
+
return In(I, n.refId, t).pipe(y.flatMap(() => I.listGrants(n.refId)), y.map((e) => ({ grants: e.map(Bn) })));
|
|
2996
3328
|
}
|
|
2997
3329
|
},
|
|
2998
3330
|
{
|
|
2999
3331
|
...f,
|
|
3000
3332
|
execute: (e, t) => {
|
|
3001
3333
|
let n = e;
|
|
3002
|
-
return
|
|
3334
|
+
return I.listRefs({
|
|
3003
3335
|
tenantId: t.request.subject.tenantId,
|
|
3004
3336
|
...n.folder === void 0 ? {} : { folder: n.folder },
|
|
3005
3337
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
@@ -3007,35 +3339,35 @@ var an = (e) => {
|
|
|
3007
3339
|
...n.includeDerived === void 0 ? {} : { includeDerived: n.includeDerived },
|
|
3008
3340
|
...n.limit === void 0 ? {} : { limit: n.limit },
|
|
3009
3341
|
...n.offset === void 0 ? {} : { offset: n.offset }
|
|
3010
|
-
}).pipe(
|
|
3011
|
-
refs: e.refs.map(
|
|
3342
|
+
}).pipe(y.map((e) => ({
|
|
3343
|
+
refs: e.refs.map(Pn),
|
|
3012
3344
|
nextOffset: e.nextOffset
|
|
3013
3345
|
})));
|
|
3014
3346
|
}
|
|
3015
3347
|
}
|
|
3016
3348
|
];
|
|
3017
|
-
return
|
|
3018
|
-
name:
|
|
3019
|
-
base:
|
|
3349
|
+
return ie({
|
|
3350
|
+
name: T({
|
|
3351
|
+
base: Vn,
|
|
3020
3352
|
alias: i.alias,
|
|
3021
3353
|
instance: i.name
|
|
3022
3354
|
}),
|
|
3023
|
-
baseName:
|
|
3355
|
+
baseName: Vn,
|
|
3024
3356
|
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.",
|
|
3025
3357
|
permissions: [
|
|
3026
3358
|
"network:outbound:*",
|
|
3027
3359
|
"inspect:read",
|
|
3028
3360
|
"inspect:write"
|
|
3029
3361
|
],
|
|
3030
|
-
declaredEnv:
|
|
3031
|
-
services:
|
|
3032
|
-
inspectEndpoints:
|
|
3362
|
+
declaredEnv: G.declared,
|
|
3363
|
+
services: fe,
|
|
3364
|
+
inspectEndpoints: Se,
|
|
3033
3365
|
httpRoutes: [
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3366
|
+
ve,
|
|
3367
|
+
ye,
|
|
3368
|
+
be
|
|
3037
3369
|
],
|
|
3038
|
-
routes:
|
|
3370
|
+
routes: Ce,
|
|
3039
3371
|
rpcClientDescriptors: ne,
|
|
3040
3372
|
errorSchemas: [
|
|
3041
3373
|
{
|
|
@@ -3067,19 +3399,44 @@ var an = (e) => {
|
|
|
3067
3399
|
}
|
|
3068
3400
|
}
|
|
3069
3401
|
],
|
|
3402
|
+
capabilities: { mediaPersist: {
|
|
3403
|
+
put: async ({ bytes: e, mediaType: t, tenantId: n, operationId: r }) => {
|
|
3404
|
+
let i = await y.runPromise(I.put({
|
|
3405
|
+
bytes: e,
|
|
3406
|
+
contentType: t,
|
|
3407
|
+
tenantId: n,
|
|
3408
|
+
kind: "media",
|
|
3409
|
+
...ue.current === void 0 ? {} : { operationId: r }
|
|
3410
|
+
}));
|
|
3411
|
+
return {
|
|
3412
|
+
url: await y.runPromise(I.getUrl(i.id, { tenantId: n })),
|
|
3413
|
+
refId: i.id
|
|
3414
|
+
};
|
|
3415
|
+
},
|
|
3416
|
+
ingestUrl: async ({ url: e, tenantId: t, operationId: n }) => {
|
|
3417
|
+
let r = await y.runPromise(I.ingestUrl(e, {
|
|
3418
|
+
tenantId: t,
|
|
3419
|
+
...ue.current === void 0 ? {} : { operationId: n }
|
|
3420
|
+
}));
|
|
3421
|
+
return {
|
|
3422
|
+
url: await y.runPromise(I.getUrl(r.id, { tenantId: t })),
|
|
3423
|
+
refId: r.id
|
|
3424
|
+
};
|
|
3425
|
+
}
|
|
3426
|
+
} },
|
|
3070
3427
|
bindDataStore: (e) => {
|
|
3071
|
-
|
|
3428
|
+
A && (M.current = Vt(e)), j && (N.current = Wt(e)), A && j && (ue.current = fn(e)), x.bindDataStore?.(e);
|
|
3072
3429
|
},
|
|
3073
|
-
onActivate: (e) =>
|
|
3074
|
-
let t = !!
|
|
3075
|
-
e.logger.info(`storage: provider=${
|
|
3076
|
-
provider:
|
|
3077
|
-
bucket:
|
|
3078
|
-
refStore:
|
|
3079
|
-
}),
|
|
3430
|
+
onActivate: (e) => y.sync(() => {
|
|
3431
|
+
let t = !!E || !!G.read("STORAGE_CDN_URL", i.cdnBaseUrl);
|
|
3432
|
+
e.logger.info(`storage: provider=${x.name} presign=${x.presigns ? "yes" : "no"} publicUrl=${t ? "yes" : "no"} transforms=yes`, {
|
|
3433
|
+
provider: x.name,
|
|
3434
|
+
bucket: S,
|
|
3435
|
+
refStore: A ? "memory" : "custom"
|
|
3436
|
+
}), x.name === "memory" && process.env.NODE_ENV !== "test" && e.logger.warn("storage: provider=memory — uploads are IN-MEMORY and LOST on restart. Set STORAGE_PROVIDER (filesystem / s3 / r2 / azure / gcs) for anything but throwaway dev. (Empty/placeholder storage env silently falls back to memory.)"), !t && !x.presigns && e.logger.warn("storage: no VOLTRO_PUBLIC_URL / STORAGE_CDN_URL and this provider can't presign — serve URLs are RELATIVE and will not resolve cross-origin (browser <img> / server-to-server AI fetches). Set VOLTRO_PUBLIC_URL to this api's absolute base URL.");
|
|
3080
3437
|
}),
|
|
3081
|
-
onDeactivate: () =>
|
|
3438
|
+
onDeactivate: () => y.void
|
|
3082
3439
|
});
|
|
3083
3440
|
};
|
|
3084
3441
|
//#endregion
|
|
3085
|
-
export {
|
|
3442
|
+
export { W as STORAGE_BLOBS_TABLE, U as STORAGE_GRANTS_TABLE, H as STORAGE_REFS_TABLE, Ae as STORAGE_USAGE_TABLE, e as StorageAccessDenied, t as StorageError, n as StorageRejected, r as StorageScanRejected, i as StorageService, Pe as _voltroStorageBlobsTable, Me as _voltroStorageGrantsTable, je as _voltroStorageRefsTable, Ne as _voltroStorageUsageTable, kn as appStorageProvider, yn as assetRef, We as azureProvider, qt as buildStorageService, we as bytesToStream, Et as checkLimits, gn as clamavScanner, Re as clearStorageBuffer, Te as collectStream, Ce as concatBytes, An as configuredStorageProvider, Ct as contentTypeAllowed, Wt as dataStoreGrantStore, Vt as dataStoreRefStore, Ue as databaseProvider, Sn as decodeDataUri, Tn as durabilityNotice, pn as encodeInstream, vn as ffmpegTranscoder, Be as filesystemProvider, Ee as fromNodeReadable, Oe as getObjectStream, et as hashPassword, fn as makeStorageObjectMetadata, Ht as memoryGrantStore, ze as memoryProvider, Rt as memoryRefStore, mn as parseClamavResponse, Ke as parseTransformParams, wn as pathDurability, Cn as putAvatar, ke as putObjectStream, Le as readStorageBuffer, It as refMatchesListQuery, jn as resolveStorageProvider, q as resolveStorageSecret, Ve as s3Provider, On as setActiveStorageProvider, _t as signFinalizeTicket, pt as signGrant, xt as signMultipartTicket, yt as signResumableTicket, ht as signUploadTicket, Tt as sniffMatches, Hn as storageInstanceName, Zt as storageObjectLifecycleTables, Un as storagePlugin, ln as storagePutIntentsTable, Jt as storageServiceLayer, De as toNodeReadable, $e as transformCached, Xe as transformImage, vt as verifyFinalizeTicket, mt as verifyGrant, St as verifyMultipartTicket, tt as verifyPassword, bt as verifyResumableTicket, gt as verifyUploadTicket, bn as withStorage };
|