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