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