@voltro/plugin-storage 0.85.0 → 0.86.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 +666 -0
- package/README.md +50 -0
- package/THIRD-PARTY-NOTICES.md +5 -33
- package/dist/access.js +47 -0
- package/dist/assetRef.js +13 -0
- package/dist/avatar.js +39 -0
- package/dist/constraints.js +93 -0
- package/dist/derivatives.js +30 -0
- package/dist/env.js +156 -0
- package/dist/grant.js +112 -0
- package/dist/index.d.ts +93 -9
- package/dist/index.js +581 -3185
- package/dist/ingest.js +81 -0
- package/dist/ingestPolicy.js +1 -0
- package/dist/metadataError.js +19 -0
- package/dist/objectLifecycle.js +209 -0
- package/dist/objectMetadata.js +150 -0
- package/dist/objectWriter.js +58 -0
- package/dist/pathDurability.js +16 -0
- package/dist/providers.js +493 -0
- package/dist/referenceCatalogue.js +31 -0
- package/dist/rpc.d.ts +2 -0
- package/dist/rpc.js +3 -1
- package/dist/scanners.js +46 -0
- package/dist/service.js +1084 -0
- package/dist/storageNamespaces.js +56 -0
- package/dist/storageNumbers.js +13 -0
- package/dist/storageObjectNamespaces.js +194 -0
- package/dist/storageReferenceInstances.js +52 -0
- package/dist/streamBridge.js +30 -0
- package/dist/table.js +53 -0
- package/dist/transcodeVideo.js +53 -0
- package/dist/transform.js +90 -0
- package/dist/transformCache.js +31 -0
- package/dist/types.d.ts +4 -0
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,2700 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}, Ve = (e, t) => e.getStream ? e.getStream(t) : e.get(t).pipe(v.map((e) => ({
|
|
35
|
-
stream: Le(e.bytes),
|
|
36
|
-
contentType: e.contentType,
|
|
37
|
-
size: e.bytes.byteLength
|
|
38
|
-
}))), He = (e, t, n, r) => e.putStream ? e.putStream(t, n, r) : Re(n).pipe(v.flatMap((n) => e.put(t, n, {
|
|
39
|
-
contentType: r.contentType,
|
|
40
|
-
...r.public === void 0 ? {} : { public: r.public }
|
|
41
|
-
}))), B = "_voltro_storage_refs", V = "_voltro_storage_grants", H = "_voltro_storage_blobs", Ue = "_voltro_storage_usage", We = P(B, {
|
|
42
|
-
id: j({ prefix: "file" }),
|
|
43
|
-
tenantId: F().nullable(),
|
|
44
|
-
ownerId: F().nullable(),
|
|
45
|
-
bucket: F(),
|
|
46
|
-
key: F(),
|
|
47
|
-
contentType: F(),
|
|
48
|
-
size: E(),
|
|
49
|
-
checksum: F(),
|
|
50
|
-
visibility: F(),
|
|
51
|
-
accessPolicy: ge().nullable(),
|
|
52
|
-
passwordHash: F().nullable(),
|
|
53
|
-
width: M().nullable(),
|
|
54
|
-
height: M().nullable(),
|
|
55
|
-
duration: M().nullable(),
|
|
56
|
-
placeholder: F().nullable(),
|
|
57
|
-
folder: F().nullable(),
|
|
58
|
-
tags: ge().nullable(),
|
|
59
|
-
alt: F().nullable(),
|
|
60
|
-
caption: F().nullable(),
|
|
61
|
-
derivedFrom: F().nullable(),
|
|
62
|
-
kind: F().nullable(),
|
|
63
|
-
createdAt: be()
|
|
64
|
-
}).index(["key"]).index(["tenantId"]).index(["ownerId"]).index(["folder"]).index(["derivedFrom"]), Ge = P(V, {
|
|
65
|
-
id: j({ prefix: "sgrant" }),
|
|
66
|
-
refId: F(),
|
|
67
|
-
principalType: F(),
|
|
68
|
-
principalId: F(),
|
|
69
|
-
permission: F(),
|
|
70
|
-
createdAt: be(),
|
|
71
|
-
expiresAt: be().nullable(),
|
|
72
|
-
createdBy: F().nullable()
|
|
73
|
-
}).index(["refId"]).index(["principalId"]), Ke = P(Ue, {
|
|
74
|
-
id: j({ prefix: "susage" }),
|
|
75
|
-
tenantId: F().maxLength(191),
|
|
76
|
-
bytes: E().default("0"),
|
|
77
|
-
count: E().default("0"),
|
|
78
|
-
updatedAt: be()
|
|
79
|
-
}).unique("byStorageUsageTenant", ["tenantId"]), qe = P(H, {
|
|
80
|
-
id: j({ prefix: "blob" }),
|
|
81
|
-
key: F(),
|
|
82
|
-
data: D(),
|
|
83
|
-
contentType: F(),
|
|
84
|
-
size: E()
|
|
85
|
-
}).index(["key"]), U = Se([
|
|
86
|
-
{
|
|
87
|
-
name: "STORAGE_PROVIDER",
|
|
88
|
-
required: !1,
|
|
89
|
-
secret: !1,
|
|
90
|
-
description: "Provider name: 's3' | 'minio' | 'azure' | 'database' | 'filesystem' | 'memory'. Default 'memory'."
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
name: "S3_BUCKET",
|
|
94
|
-
required: !1,
|
|
95
|
-
secret: !1,
|
|
96
|
-
description: "S3/MinIO bucket name. Default STORAGE_BUCKET, else \"voltro\"."
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: "STORAGE_BUCKET",
|
|
100
|
-
required: !1,
|
|
101
|
-
secret: !1,
|
|
102
|
-
description: "Fallback bucket name when S3_BUCKET is unset."
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: "S3_REGION",
|
|
106
|
-
required: !1,
|
|
107
|
-
secret: !1,
|
|
108
|
-
description: "S3 region. Falls back to AWS_REGION."
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
name: "AWS_REGION",
|
|
112
|
-
required: !1,
|
|
113
|
-
secret: !1,
|
|
114
|
-
description: "AWS region fallback for the S3 provider."
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
name: "S3_ENDPOINT",
|
|
118
|
-
required: !1,
|
|
119
|
-
secret: !1,
|
|
120
|
-
description: "Custom S3 endpoint URL. Falls back to MINIO_ENDPOINT."
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
name: "MINIO_ENDPOINT",
|
|
124
|
-
required: !1,
|
|
125
|
-
secret: !1,
|
|
126
|
-
description: "MinIO endpoint URL fallback for the S3 provider."
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: "S3_ACCESS_KEY_ID",
|
|
130
|
-
required: !1,
|
|
131
|
-
secret: !0,
|
|
132
|
-
description: "S3 access key id. Falls back to AWS_ACCESS_KEY_ID."
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: "AWS_ACCESS_KEY_ID",
|
|
136
|
-
required: !1,
|
|
137
|
-
secret: !0,
|
|
138
|
-
description: "AWS access key id fallback for the S3 provider."
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
name: "S3_SECRET_ACCESS_KEY",
|
|
142
|
-
required: !1,
|
|
143
|
-
secret: !0,
|
|
144
|
-
description: "S3 secret access key. Falls back to AWS_SECRET_ACCESS_KEY."
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
name: "AWS_SECRET_ACCESS_KEY",
|
|
148
|
-
required: !1,
|
|
149
|
-
secret: !0,
|
|
150
|
-
description: "AWS secret access key fallback for the S3 provider."
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
name: "S3_FORCE_PATH_STYLE",
|
|
154
|
-
required: !1,
|
|
155
|
-
secret: !1,
|
|
156
|
-
description: "Set to \"1\" to force path-style S3 addressing."
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
name: "STORAGE_CDN_URL",
|
|
160
|
-
required: !1,
|
|
161
|
-
secret: !1,
|
|
162
|
-
description: "Public base URL (CDN) served in front of the bucket for public objects."
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
name: "VOLTRO_PUBLIC_URL",
|
|
166
|
-
required: !1,
|
|
167
|
-
secret: !1,
|
|
168
|
-
description: "Absolute public base URL of THIS api (scheme://host[:port]) — prepended to the /_voltro/storage/:id serve URL so getUrl/mintUrl/the upload route emit ABSOLUTE URLs. Required when the api is a different origin than the app."
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
name: "STORAGE_ALLOWED_ORIGINS",
|
|
172
|
-
required: !1,
|
|
173
|
-
secret: !1,
|
|
174
|
-
description: "Comma-separated origins allowed to read the serve route + POST the upload route cross-origin (CORS). Use '*' for any. Omit for same-origin only."
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
name: "AZURE_STORAGE_ACCOUNT",
|
|
178
|
-
required: !1,
|
|
179
|
-
secret: !1,
|
|
180
|
-
description: "Azure storage account name (provider \"azure\")."
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
name: "AZURE_STORAGE_KEY",
|
|
184
|
-
required: !1,
|
|
185
|
-
secret: !0,
|
|
186
|
-
description: "Azure account key — needed to mint SAS URLs."
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
name: "AZURE_STORAGE_CONNECTION_STRING",
|
|
190
|
-
required: !1,
|
|
191
|
-
secret: !0,
|
|
192
|
-
description: "Azure connection string (carries the account key)."
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
name: "AZURE_STORAGE_ENDPOINT",
|
|
196
|
-
required: !1,
|
|
197
|
-
secret: !1,
|
|
198
|
-
description: "Custom Azure blob endpoint (e.g. Azurite)."
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
name: "AZURE_STORAGE_CONTAINER",
|
|
202
|
-
required: !1,
|
|
203
|
-
secret: !1,
|
|
204
|
-
description: "Azure blob container name (the \"bucket\")."
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
name: "STORAGE_ROOT",
|
|
208
|
-
required: !1,
|
|
209
|
-
secret: !1,
|
|
210
|
-
description: "Filesystem provider root directory. Default \".voltro-storage\"."
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
name: "VOLTRO_STORAGE_SECRET",
|
|
214
|
-
required: !1,
|
|
215
|
-
secret: !0,
|
|
216
|
-
description: "HMAC secret for signed grant tokens. Falls back to the session secret."
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
name: "VOLTRO_SESSION_COOKIE",
|
|
220
|
-
required: !1,
|
|
221
|
-
secret: !1,
|
|
222
|
-
description: "Session cookie name used to resolve private-object access. Default \"voltro:session\"."
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
name: "CLAMAV_HOST",
|
|
226
|
-
required: !1,
|
|
227
|
-
secret: !1,
|
|
228
|
-
description: "clamd host for the optional clamav virus scanner. Default 127.0.0.1."
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
name: "CLAMAV_PORT",
|
|
232
|
-
required: !1,
|
|
233
|
-
secret: !1,
|
|
234
|
-
description: "clamd port for the optional clamav virus scanner. Default 3310."
|
|
235
|
-
}
|
|
236
|
-
]), W = (e, n) => {
|
|
237
|
-
let r = typeof e == "number" ? e : typeof e == "bigint" || typeof e == "string" && /^\d+$/.test(e) ? Number(e) : NaN;
|
|
238
|
-
if (!Number.isSafeInteger(r) || r < 0) throw new t({
|
|
239
|
-
provider: "metadata",
|
|
240
|
-
message: `Storage ${n} must be a non-negative safe integer at most Number.MAX_SAFE_INTEGER`,
|
|
241
|
-
transient: !1
|
|
242
|
-
});
|
|
243
|
-
return r;
|
|
244
|
-
}, Je = (e, t, n) => W(e + t, n), G = (e, n, r = !1) => {
|
|
245
|
-
let i = O(e).find(S.is(t));
|
|
246
|
-
if (i !== void 0) return i;
|
|
247
|
-
let a = pe(e), o = a.dbCode === "22003" || a.dbSqlState === "22003" || a.dbCode === "ER_WARN_DATA_OUT_OF_RANGE" || a.dbErrno === 1264 || a.dbNumber === 8115 || a.dbNumber === 248, s = new t({
|
|
248
|
-
provider: n,
|
|
249
|
-
message: `${o ? "Storage metadata numeric value out of range: " : ""}${xe(e)}`,
|
|
250
|
-
transient: o ? !1 : he(e) || r
|
|
251
|
-
});
|
|
252
|
-
return Object.defineProperty(s, "cause", {
|
|
253
|
-
value: e,
|
|
254
|
-
configurable: !0
|
|
255
|
-
}), s;
|
|
256
|
-
}, Ye = (e) => O(e).find(S.is(n)), K = (e, n, r, i) => new t({
|
|
257
|
-
provider: e,
|
|
258
|
-
message: n,
|
|
259
|
-
transient: r,
|
|
260
|
-
...i === void 0 ? {} : { status: i }
|
|
261
|
-
}), Xe = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, Ze = /* @__PURE__ */ new Map(), Qe = (e, t) => Ze.get(e)?.get(t)?.bytes, $e = (e) => {
|
|
262
|
-
Ze.get(e)?.clear();
|
|
263
|
-
}, et = (e = "default") => {
|
|
264
|
-
let t = Ze.get(e) ?? /* @__PURE__ */ new Map();
|
|
265
|
-
return Ze.set(e, t), {
|
|
266
|
-
name: "memory",
|
|
267
|
-
presigns: !1,
|
|
268
|
-
put: (e, n, r) => v.sync(() => (t.set(e, {
|
|
269
|
-
bytes: n,
|
|
270
|
-
contentType: r.contentType
|
|
271
|
-
}), { size: n.byteLength })),
|
|
272
|
-
get: (e) => v.suspend(() => {
|
|
273
|
-
let n = t.get(e);
|
|
274
|
-
return n ? v.succeed({
|
|
275
|
-
bytes: n.bytes,
|
|
276
|
-
contentType: n.contentType
|
|
277
|
-
}) : v.fail(K("memory", `no object at key '${e}'`, !1, 404));
|
|
278
|
-
}),
|
|
279
|
-
delete: (e) => v.sync(() => {
|
|
280
|
-
t.delete(e);
|
|
281
|
-
}),
|
|
282
|
-
publicUrl: () => null,
|
|
283
|
-
getUrl: () => v.succeed(""),
|
|
284
|
-
head: (e) => v.sync(() => {
|
|
285
|
-
let n = t.get(e);
|
|
286
|
-
return n ? { size: n.bytes.byteLength } : null;
|
|
287
|
-
})
|
|
288
|
-
};
|
|
289
|
-
}, tt = (e) => {
|
|
290
|
-
let t = e.root, n = async (e) => {
|
|
291
|
-
let { join: n, resolve: r, sep: i } = await import("node:path"), a = r(t), o = r(a, e);
|
|
292
|
-
if (o !== a && !o.startsWith(a + i)) throw Error(`key '${e}' escapes the storage root`);
|
|
293
|
-
return n(o);
|
|
294
|
-
}, r = (e, t, n = !1) => v.tryPromise({
|
|
295
|
-
try: e,
|
|
296
|
-
catch: (e) => e?.code === "ENOENT" ? K("filesystem", `no object at key '${t}'`, !1, 404) : K("filesystem", String(e?.message ?? e), n)
|
|
297
|
-
});
|
|
298
|
-
return {
|
|
299
|
-
root: t,
|
|
300
|
-
name: "filesystem",
|
|
301
|
-
presigns: !1,
|
|
302
|
-
put: (e, t, i) => r(async () => {
|
|
303
|
-
let r = await import("node:fs/promises"), { dirname: i } = await import("node:path"), { randomUUID: a } = await import("node:crypto"), o = await n(e), s = i(o);
|
|
304
|
-
await r.mkdir(s, { recursive: !0 });
|
|
305
|
-
let c = `${o}.tmp-${a()}`;
|
|
306
|
-
try {
|
|
307
|
-
await r.writeFile(c, t), await r.rename(c, o);
|
|
308
|
-
} catch (e) {
|
|
309
|
-
throw await r.rm(c, { force: !0 }).catch(() => {}), e;
|
|
310
|
-
}
|
|
311
|
-
return { size: t.byteLength };
|
|
312
|
-
}, e, !0),
|
|
313
|
-
get: (e) => r(async () => {
|
|
314
|
-
let t = await (await import("node:fs/promises")).readFile(await n(e));
|
|
315
|
-
return {
|
|
316
|
-
bytes: new Uint8Array(t),
|
|
317
|
-
contentType: "application/octet-stream"
|
|
318
|
-
};
|
|
319
|
-
}, e),
|
|
320
|
-
delete: (e) => r(async () => {
|
|
321
|
-
await (await import("node:fs/promises")).rm(await n(e), { force: !0 });
|
|
322
|
-
}, e),
|
|
323
|
-
publicUrl: () => null,
|
|
324
|
-
getUrl: () => v.succeed(""),
|
|
325
|
-
head: (e) => v.tryPromise({
|
|
326
|
-
try: async () => {
|
|
327
|
-
let t = await import("node:fs/promises");
|
|
328
|
-
try {
|
|
329
|
-
return { size: (await t.stat(await n(e))).size };
|
|
330
|
-
} catch (e) {
|
|
331
|
-
if (e?.code === "ENOENT") return null;
|
|
332
|
-
throw e;
|
|
333
|
-
}
|
|
334
|
-
},
|
|
335
|
-
catch: (e) => K("filesystem", String(e?.message ?? e), !1)
|
|
336
|
-
}),
|
|
337
|
-
getStream: (e) => r(async () => {
|
|
338
|
-
let t = await import("node:fs/promises"), { createReadStream: r } = await import("node:fs"), i = await n(e), a = await t.stat(i);
|
|
339
|
-
return {
|
|
340
|
-
stream: ze("filesystem", () => r(i)),
|
|
341
|
-
contentType: "application/octet-stream",
|
|
342
|
-
size: a.size
|
|
343
|
-
};
|
|
344
|
-
}, e),
|
|
345
|
-
putStream: (e, t, i) => r(async () => {
|
|
346
|
-
let r = await import("node:fs/promises"), { dirname: i } = await import("node:path"), { randomUUID: a } = await import("node:crypto"), { createWriteStream: o } = await import("node:fs"), { pipeline: s } = await import("node:stream/promises"), c = await n(e);
|
|
347
|
-
await r.mkdir(i(c), { recursive: !0 });
|
|
348
|
-
let l = `${c}.tmp-${a()}`;
|
|
349
|
-
try {
|
|
350
|
-
await s(await Be(t), o(l));
|
|
351
|
-
let e = await r.stat(l);
|
|
352
|
-
return await r.rename(l, c), { size: e.size };
|
|
353
|
-
} catch (e) {
|
|
354
|
-
throw await r.rm(l, { force: !0 }).catch(() => {}), e;
|
|
355
|
-
}
|
|
356
|
-
}, e, !0),
|
|
357
|
-
getRange: (e, t, i) => r(async () => {
|
|
358
|
-
let { createReadStream: r } = await import("node:fs"), a = await n(e), o = [];
|
|
359
|
-
return await new Promise((e, n) => {
|
|
360
|
-
let s = r(a, {
|
|
361
|
-
start: t,
|
|
362
|
-
end: i
|
|
363
|
-
});
|
|
364
|
-
s.on("data", (e) => o.push(e)), s.on("end", () => e()), s.on("error", n);
|
|
365
|
-
}), Ie(o);
|
|
366
|
-
}, e)
|
|
367
|
-
};
|
|
368
|
-
}, nt = (e) => {
|
|
369
|
-
let t = e.name ?? "s3", n = e.publicAcl ?? !0, r = null, i = () => r || (r = (async () => {
|
|
370
|
-
let t, n;
|
|
371
|
-
try {
|
|
372
|
-
t = await import("@aws-sdk/client-s3"), n = await import("@aws-sdk/s3-request-presigner");
|
|
373
|
-
} catch (e) {
|
|
374
|
-
throw Error("the 's3'/'minio' storage provider requires the '@aws-sdk/client-s3' + '@aws-sdk/s3-request-presigner' optional dependencies. Install them to enable it.", { cause: e });
|
|
375
|
-
}
|
|
376
|
-
return {
|
|
377
|
-
client: new t.S3Client({
|
|
378
|
-
...e.region ? { region: e.region } : { region: "us-east-1" },
|
|
379
|
-
...e.endpoint ? { endpoint: e.endpoint } : {},
|
|
380
|
-
...e.forcePathStyle ? { forcePathStyle: !0 } : {},
|
|
381
|
-
...e.accessKeyId && e.secretAccessKey ? { credentials: {
|
|
382
|
-
accessKeyId: e.accessKeyId,
|
|
383
|
-
secretAccessKey: e.secretAccessKey
|
|
384
|
-
} } : {}
|
|
385
|
-
}),
|
|
386
|
-
cmds: t,
|
|
387
|
-
presign: n.getSignedUrl
|
|
388
|
-
};
|
|
389
|
-
})(), r), a = (e) => v.tryPromise({
|
|
390
|
-
try: e,
|
|
391
|
-
catch: (e) => {
|
|
392
|
-
let n = e?.$metadata?.httpStatusCode;
|
|
393
|
-
return K(t, String(e?.message ?? e), Xe(n), n);
|
|
394
|
-
}
|
|
395
|
-
}), o = async (e) => {
|
|
396
|
-
let t = e;
|
|
397
|
-
if (typeof t.transformToByteArray == "function") return t.transformToByteArray();
|
|
398
|
-
let n = [];
|
|
399
|
-
for await (let e of t) n.push(e);
|
|
400
|
-
let r = n.reduce((e, t) => e + t.byteLength, 0), i = new Uint8Array(r), a = 0;
|
|
401
|
-
for (let e of n) i.set(e, a), a += e.byteLength;
|
|
402
|
-
return i;
|
|
403
|
-
};
|
|
404
|
-
return {
|
|
405
|
-
name: t,
|
|
406
|
-
presigns: !0,
|
|
407
|
-
put: (t, r, o) => a(async () => {
|
|
408
|
-
let { client: a, cmds: s } = await i();
|
|
409
|
-
return await a.send(new s.PutObjectCommand({
|
|
410
|
-
Bucket: e.bucket,
|
|
411
|
-
Key: t,
|
|
412
|
-
Body: r,
|
|
413
|
-
ContentType: o.contentType,
|
|
414
|
-
...o.public && n ? { ACL: "public-read" } : {}
|
|
415
|
-
})), { size: r.byteLength };
|
|
416
|
-
}),
|
|
417
|
-
get: (t) => a(async () => {
|
|
418
|
-
let { client: n, cmds: r } = await i(), a = await n.send(new r.GetObjectCommand({
|
|
419
|
-
Bucket: e.bucket,
|
|
420
|
-
Key: t
|
|
421
|
-
}));
|
|
422
|
-
return {
|
|
423
|
-
bytes: await o(a.Body),
|
|
424
|
-
contentType: a.ContentType ?? "application/octet-stream"
|
|
425
|
-
};
|
|
426
|
-
}),
|
|
427
|
-
delete: (t) => a(async () => {
|
|
428
|
-
let { client: n, cmds: r } = await i();
|
|
429
|
-
await n.send(new r.DeleteObjectCommand({
|
|
430
|
-
Bucket: e.bucket,
|
|
431
|
-
Key: t
|
|
432
|
-
}));
|
|
433
|
-
}),
|
|
434
|
-
publicUrl: (t) => e.cdnBaseUrl ? `${e.cdnBaseUrl.replace(/\/$/, "")}/${t}` : null,
|
|
435
|
-
...n ? { setObjectPublic: (t, n) => a(async () => {
|
|
436
|
-
let { client: r, cmds: a } = await i();
|
|
437
|
-
await r.send(new a.PutObjectAclCommand({
|
|
438
|
-
Bucket: e.bucket,
|
|
439
|
-
Key: t,
|
|
440
|
-
ACL: n ? "public-read" : "private"
|
|
441
|
-
}));
|
|
442
|
-
}) } : {},
|
|
443
|
-
getUrl: (t, n) => a(async () => {
|
|
444
|
-
let { client: r, cmds: a, presign: o } = await i();
|
|
445
|
-
return o(r, new a.GetObjectCommand({
|
|
446
|
-
Bucket: e.bucket,
|
|
447
|
-
Key: t
|
|
448
|
-
}), { expiresIn: n });
|
|
449
|
-
}),
|
|
450
|
-
getUploadUrl: (t, n, r) => a(async () => {
|
|
451
|
-
let { client: a, cmds: o, presign: s } = await i();
|
|
452
|
-
return s(a, new o.PutObjectCommand({
|
|
453
|
-
Bucket: e.bucket,
|
|
454
|
-
Key: t,
|
|
455
|
-
ContentType: r
|
|
456
|
-
}), { expiresIn: n });
|
|
457
|
-
}),
|
|
458
|
-
createMultipartUpload: (t, r, o) => a(async () => {
|
|
459
|
-
let { client: a, cmds: s } = await i(), c = await a.send(new s.CreateMultipartUploadCommand({
|
|
460
|
-
Bucket: e.bucket,
|
|
461
|
-
Key: t,
|
|
462
|
-
ContentType: r,
|
|
463
|
-
...o?.public && n ? { ACL: "public-read" } : {}
|
|
464
|
-
}));
|
|
465
|
-
if (!c.UploadId) throw Error("s3 createMultipartUpload returned no UploadId");
|
|
466
|
-
return { uploadId: c.UploadId };
|
|
467
|
-
}),
|
|
468
|
-
presignUploadPart: (t, n, r, o) => a(async () => {
|
|
469
|
-
let { client: a, cmds: s, presign: c } = await i();
|
|
470
|
-
return c(a, new s.UploadPartCommand({
|
|
471
|
-
Bucket: e.bucket,
|
|
472
|
-
Key: t,
|
|
473
|
-
UploadId: n,
|
|
474
|
-
PartNumber: r
|
|
475
|
-
}), { expiresIn: o });
|
|
476
|
-
}),
|
|
477
|
-
completeMultipartUpload: (t, n, r) => a(async () => {
|
|
478
|
-
let { client: a, cmds: o } = await i(), s = await a.send(new o.CompleteMultipartUploadCommand({
|
|
479
|
-
Bucket: e.bucket,
|
|
480
|
-
Key: t,
|
|
481
|
-
UploadId: n,
|
|
482
|
-
MultipartUpload: { Parts: r.map((e) => ({
|
|
483
|
-
PartNumber: e.partNumber,
|
|
484
|
-
ETag: e.etag
|
|
485
|
-
})) }
|
|
486
|
-
}));
|
|
487
|
-
return s.ETag === void 0 ? {} : { etag: s.ETag };
|
|
488
|
-
}),
|
|
489
|
-
abortMultipartUpload: (t, n) => a(async () => {
|
|
490
|
-
let { client: r, cmds: a } = await i();
|
|
491
|
-
await r.send(new a.AbortMultipartUploadCommand({
|
|
492
|
-
Bucket: e.bucket,
|
|
493
|
-
Key: t,
|
|
494
|
-
UploadId: n
|
|
495
|
-
}));
|
|
496
|
-
}),
|
|
497
|
-
head: (n) => v.tryPromise({
|
|
498
|
-
try: async () => {
|
|
499
|
-
let { client: t, cmds: r } = await i();
|
|
500
|
-
try {
|
|
501
|
-
let i = await t.send(new r.HeadObjectCommand({
|
|
502
|
-
Bucket: e.bucket,
|
|
503
|
-
Key: n
|
|
504
|
-
}));
|
|
505
|
-
return {
|
|
506
|
-
size: i.ContentLength ?? 0,
|
|
507
|
-
...i.ETag === void 0 ? {} : { etag: i.ETag }
|
|
508
|
-
};
|
|
509
|
-
} catch (e) {
|
|
510
|
-
if (e?.$metadata?.httpStatusCode === 404) return null;
|
|
511
|
-
throw e;
|
|
512
|
-
}
|
|
513
|
-
},
|
|
514
|
-
catch: (e) => {
|
|
515
|
-
let n = e?.$metadata?.httpStatusCode;
|
|
516
|
-
return K(t, String(e?.message ?? e), Xe(n), n);
|
|
517
|
-
}
|
|
518
|
-
}),
|
|
519
|
-
getStream: (n) => a(async () => {
|
|
520
|
-
let { client: r, cmds: a } = await i(), o = await r.send(new a.GetObjectCommand({
|
|
521
|
-
Bucket: e.bucket,
|
|
522
|
-
Key: n
|
|
523
|
-
})), s = o.Body;
|
|
524
|
-
return {
|
|
525
|
-
stream: ze(t, () => s),
|
|
526
|
-
contentType: o.ContentType ?? "application/octet-stream",
|
|
527
|
-
...o.ContentLength === void 0 ? {} : { size: o.ContentLength }
|
|
528
|
-
};
|
|
529
|
-
}),
|
|
530
|
-
putStream: (t, r, o) => a(async () => {
|
|
531
|
-
let { client: a, cmds: s } = await i(), c;
|
|
532
|
-
try {
|
|
533
|
-
c = await import("@aws-sdk/lib-storage");
|
|
534
|
-
} catch (e) {
|
|
535
|
-
throw Error("s3/minio `putStream` requires the '@aws-sdk/lib-storage' optional dependency (multipart upload). Install it to enable streamed uploads.", { cause: e });
|
|
536
|
-
}
|
|
537
|
-
let l = await Be(r);
|
|
538
|
-
return await new c.Upload({
|
|
539
|
-
client: a,
|
|
540
|
-
params: {
|
|
541
|
-
Bucket: e.bucket,
|
|
542
|
-
Key: t,
|
|
543
|
-
Body: l,
|
|
544
|
-
ContentType: o.contentType,
|
|
545
|
-
...o.public && n ? { ACL: "public-read" } : {}
|
|
546
|
-
}
|
|
547
|
-
}).done(), { size: o.totalSize ?? (await a.send(new s.HeadObjectCommand({
|
|
548
|
-
Bucket: e.bucket,
|
|
549
|
-
Key: t
|
|
550
|
-
}))).ContentLength ?? 0 };
|
|
551
|
-
}),
|
|
552
|
-
getRange: (t, n, r) => a(async () => {
|
|
553
|
-
let { client: a, cmds: s } = await i(), c = await a.send(new s.GetObjectCommand({
|
|
554
|
-
Bucket: e.bucket,
|
|
555
|
-
Key: t,
|
|
556
|
-
Range: `bytes=${n}-${r}`
|
|
557
|
-
}));
|
|
558
|
-
return o(c.Body);
|
|
559
|
-
})
|
|
560
|
-
};
|
|
561
|
-
}, rt = (e) => e instanceof Uint8Array ? e : typeof e == "string" ? new Uint8Array(Buffer.from(e, "base64")) : new Uint8Array(e), it = () => {
|
|
562
|
-
let e = null, t = () => {
|
|
563
|
-
if (!e) throw T("the 'database' storage provider isn't bound to a DataStore yet");
|
|
564
|
-
return e;
|
|
565
|
-
}, n = (e) => v.tryPromise({
|
|
566
|
-
try: e,
|
|
567
|
-
catch: (e) => G(e, "database", !0)
|
|
568
|
-
}), r = async (e, n) => (await t().query({
|
|
569
|
-
table: H,
|
|
570
|
-
predicate: {
|
|
571
|
-
column: "key",
|
|
572
|
-
op: "eq",
|
|
573
|
-
value: e
|
|
574
|
-
},
|
|
575
|
-
order: [],
|
|
576
|
-
take: 1,
|
|
577
|
-
skip: void 0,
|
|
578
|
-
projection: n
|
|
579
|
-
}))[0];
|
|
580
|
-
return {
|
|
581
|
-
name: "database",
|
|
582
|
-
presigns: !1,
|
|
583
|
-
bindDataStore: (t) => {
|
|
584
|
-
e = t;
|
|
585
|
-
},
|
|
586
|
-
put: (e, i, a) => n(async () => {
|
|
587
|
-
let n = await r(e);
|
|
588
|
-
return n ? await t().update(H, String(n.id), {
|
|
589
|
-
data: i,
|
|
590
|
-
contentType: a.contentType,
|
|
591
|
-
size: String(i.byteLength)
|
|
592
|
-
}) : await t().insert(H, {
|
|
593
|
-
id: A({
|
|
594
|
-
kind: "typeid",
|
|
595
|
-
prefix: "blob"
|
|
596
|
-
}, H),
|
|
597
|
-
key: e,
|
|
598
|
-
data: i,
|
|
599
|
-
contentType: a.contentType,
|
|
600
|
-
size: String(i.byteLength)
|
|
601
|
-
}), { size: i.byteLength };
|
|
602
|
-
}),
|
|
603
|
-
get: (e) => v.suspend(() => n(() => r(e)).pipe(v.flatMap((t) => t ? v.succeed({
|
|
604
|
-
bytes: rt(t.data),
|
|
605
|
-
contentType: String(t.contentType)
|
|
606
|
-
}) : v.fail(K("database", `no object at key '${e}'`, !1, 404))))),
|
|
607
|
-
delete: (e) => n(async () => {
|
|
608
|
-
let n = await r(e, ["id"]);
|
|
609
|
-
n && await t().delete(H, String(n.id));
|
|
610
|
-
}),
|
|
611
|
-
publicUrl: () => null,
|
|
612
|
-
getUrl: () => v.succeed(""),
|
|
613
|
-
head: (e) => n(async () => {
|
|
614
|
-
let t = await r(e, ["size"]);
|
|
615
|
-
return t ? { size: W(t.size, "blob size") } : null;
|
|
616
|
-
})
|
|
617
|
-
};
|
|
618
|
-
}, at = (e) => {
|
|
619
|
-
let t = null, n = () => t || (t = (async () => {
|
|
620
|
-
let t;
|
|
621
|
-
try {
|
|
622
|
-
t = await import("@azure/storage-blob");
|
|
623
|
-
} catch (e) {
|
|
624
|
-
throw Error("the 'azure' storage provider requires the '@azure/storage-blob' optional dependency. Install it to enable it.", { cause: e });
|
|
625
|
-
}
|
|
626
|
-
let n = U.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = U.read("AZURE_STORAGE_KEY", e.accountKey), i = n && r ? new t.StorageSharedKeyCredential(n, r) : null, a = U.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString);
|
|
627
|
-
return {
|
|
628
|
-
container: (a ? t.BlobServiceClient.fromConnectionString(a) : new t.BlobServiceClient(e.endpoint ?? `https://${n}.blob.core.windows.net`, i ?? void 0)).getContainerClient(e.container),
|
|
629
|
-
sdk: t,
|
|
630
|
-
cred: i
|
|
631
|
-
};
|
|
632
|
-
})(), t), r = (e) => v.tryPromise({
|
|
633
|
-
try: e,
|
|
634
|
-
catch: (e) => {
|
|
635
|
-
let t = e?.statusCode;
|
|
636
|
-
return K("azure", String(e?.message ?? e), Xe(t), t);
|
|
637
|
-
}
|
|
638
|
-
}), i = async (e) => {
|
|
639
|
-
if (!e) return /* @__PURE__ */ new Uint8Array();
|
|
640
|
-
let t = [];
|
|
641
|
-
for await (let n of e) t.push(typeof n == "string" ? new TextEncoder().encode(n) : new Uint8Array(n));
|
|
642
|
-
let n = t.reduce((e, t) => e + t.byteLength, 0), r = new Uint8Array(n), i = 0;
|
|
643
|
-
for (let e of t) r.set(e, i), i += e.byteLength;
|
|
644
|
-
return r;
|
|
645
|
-
}, a = async (t, r, i) => {
|
|
646
|
-
let { container: a, sdk: o, cred: s } = await n();
|
|
647
|
-
if (!s) throw Error("azure SAS requires accountName + accountKey (set them or AZURE_STORAGE_ACCOUNT/AZURE_STORAGE_KEY)");
|
|
648
|
-
let c = a.getBlockBlobClient(t), l = o.generateBlobSASQueryParameters({
|
|
649
|
-
containerName: e.container,
|
|
650
|
-
blobName: t,
|
|
651
|
-
permissions: o.BlobSASPermissions.parse(r),
|
|
652
|
-
startsOn: /* @__PURE__ */ new Date(Date.now() - 6e4),
|
|
653
|
-
expiresOn: new Date(Date.now() + i * 1e3)
|
|
654
|
-
}, s).toString();
|
|
655
|
-
return `${c.url}?${l}`;
|
|
656
|
-
};
|
|
657
|
-
return {
|
|
658
|
-
name: "azure",
|
|
659
|
-
presigns: !0,
|
|
660
|
-
put: (e, t, i) => r(async () => {
|
|
661
|
-
let { container: r } = await n();
|
|
662
|
-
return await r.getBlockBlobClient(e).uploadData(Buffer.from(t), { blobHTTPHeaders: { blobContentType: i.contentType } }), { size: t.byteLength };
|
|
663
|
-
}),
|
|
664
|
-
get: (e) => r(async () => {
|
|
665
|
-
let { container: t } = await n(), r = await t.getBlockBlobClient(e).download();
|
|
666
|
-
return {
|
|
667
|
-
bytes: await i(r.readableStreamBody),
|
|
668
|
-
contentType: r.contentType ?? "application/octet-stream"
|
|
669
|
-
};
|
|
670
|
-
}),
|
|
671
|
-
delete: (e) => r(async () => {
|
|
672
|
-
let { container: t } = await n();
|
|
673
|
-
await t.getBlockBlobClient(e).deleteIfExists();
|
|
674
|
-
}),
|
|
675
|
-
publicUrl: (t) => e.cdnBaseUrl ? `${e.cdnBaseUrl.replace(/\/$/, "")}/${t}` : null,
|
|
676
|
-
getUrl: (e, t) => r(() => a(e, "r", t)),
|
|
677
|
-
getUploadUrl: (e, t, n) => r(() => a(e, "cw", t)),
|
|
678
|
-
head: (e) => v.tryPromise({
|
|
679
|
-
try: async () => {
|
|
680
|
-
let { container: t } = await n();
|
|
681
|
-
try {
|
|
682
|
-
let n = await t.getBlockBlobClient(e).getProperties();
|
|
683
|
-
return {
|
|
684
|
-
size: n.contentLength ?? 0,
|
|
685
|
-
...n.etag === void 0 ? {} : { etag: n.etag }
|
|
686
|
-
};
|
|
687
|
-
} catch (e) {
|
|
688
|
-
if (e?.statusCode === 404) return null;
|
|
689
|
-
throw e;
|
|
690
|
-
}
|
|
691
|
-
},
|
|
692
|
-
catch: (e) => {
|
|
693
|
-
let t = e?.statusCode;
|
|
694
|
-
return K("azure", String(e?.message ?? e), Xe(t), t);
|
|
695
|
-
}
|
|
696
|
-
}),
|
|
697
|
-
getStream: (e) => r(async () => {
|
|
698
|
-
let { container: t } = await n(), r = await t.getBlockBlobClient(e).download();
|
|
699
|
-
return {
|
|
700
|
-
stream: ze("azure", () => r.readableStreamBody),
|
|
701
|
-
contentType: r.contentType ?? "application/octet-stream",
|
|
702
|
-
...r.contentLength === void 0 ? {} : { size: r.contentLength }
|
|
703
|
-
};
|
|
704
|
-
}),
|
|
705
|
-
putStream: (e, t, i) => r(async () => {
|
|
706
|
-
let { container: r } = await n(), a = await Be(t);
|
|
707
|
-
return await r.getBlockBlobClient(e).uploadStream(a, 4194304, 5, { blobHTTPHeaders: { blobContentType: i.contentType } }), { size: i.totalSize ?? (await r.getBlockBlobClient(e).getProperties()).contentLength ?? 0 };
|
|
708
|
-
}),
|
|
709
|
-
getRange: (e, t, a) => r(async () => {
|
|
710
|
-
let { container: r } = await n(), o = await r.getBlockBlobClient(e).download(t, a - t + 1);
|
|
711
|
-
return i(o.readableStreamBody);
|
|
712
|
-
})
|
|
713
|
-
};
|
|
714
|
-
}, ot = (e = {
|
|
715
|
-
entries: 200,
|
|
716
|
-
bytes: 67108864,
|
|
717
|
-
pending: 32
|
|
718
|
-
}) => {
|
|
719
|
-
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = 0;
|
|
720
|
-
return { getOrCreate: (i, a) => {
|
|
721
|
-
let o = t.get(i);
|
|
722
|
-
if (o) return Promise.resolve(o);
|
|
723
|
-
let s = n.get(i);
|
|
724
|
-
if (s) return s;
|
|
725
|
-
if (n.size >= e.pending) return Promise.resolve(null);
|
|
726
|
-
let c = Promise.resolve().then(a).then((n) => {
|
|
727
|
-
if (n && e.entries > 0 && n.bytes.byteLength <= e.bytes) {
|
|
728
|
-
for (; t.size >= e.entries || r + n.bytes.byteLength > e.bytes;) {
|
|
729
|
-
let e = t.keys().next().value;
|
|
730
|
-
if (e === void 0) break;
|
|
731
|
-
r -= t.get(e).bytes.byteLength, t.delete(e);
|
|
732
|
-
}
|
|
733
|
-
t.set(i, n), r += n.bytes.byteLength;
|
|
734
|
-
}
|
|
735
|
-
return n;
|
|
736
|
-
}).finally(() => {
|
|
737
|
-
n.delete(i);
|
|
738
|
-
});
|
|
739
|
-
return n.set(i, c), c;
|
|
740
|
-
} };
|
|
741
|
-
}, st = (e, t, n, r, i, a) => {
|
|
742
|
-
let o = n / r, s = Math.min(e, Math.round(t * o)), c = Math.min(t, Math.round(s / o)), l = (e, t) => Math.max(0, Math.min(t, e));
|
|
743
|
-
return {
|
|
744
|
-
left: l(Math.round(i * e - s / 2), e - s),
|
|
745
|
-
top: l(Math.round(a * t - c / 2), t - c),
|
|
746
|
-
width: s,
|
|
747
|
-
height: c
|
|
748
|
-
};
|
|
749
|
-
}, ct = {
|
|
750
|
-
webp: "image/webp",
|
|
751
|
-
avif: "image/avif",
|
|
752
|
-
jpeg: "image/jpeg",
|
|
753
|
-
jpg: "image/jpeg",
|
|
754
|
-
png: "image/png"
|
|
755
|
-
}, lt = (e) => {
|
|
756
|
-
if (!e) return null;
|
|
757
|
-
let t = new URLSearchParams(e), n = (e) => {
|
|
758
|
-
let n = t.get(e);
|
|
759
|
-
if (n == null) return;
|
|
760
|
-
let r = Number(n);
|
|
761
|
-
return Number.isFinite(r) && r > 0 ? Math.floor(r) : void 0;
|
|
762
|
-
}, r = n("w"), i = n("h"), a = n("q"), o = (t.get("format") ?? t.get("fm") ?? void 0)?.toLowerCase(), s = t.get("fit") ?? void 0, c = (t.get("fp") ?? "").split(",").map(Number), l = c.length === 2 && c.every((e) => Number.isFinite(e) && e >= 0 && e <= 1) ? {
|
|
763
|
-
x: c[0],
|
|
764
|
-
y: c[1]
|
|
765
|
-
} : void 0;
|
|
766
|
-
return r === void 0 && i === void 0 && !o && a === void 0 ? null : {
|
|
767
|
-
...r === void 0 ? {} : { w: r },
|
|
768
|
-
...i === void 0 ? {} : { h: i },
|
|
769
|
-
...o ? { format: o } : {},
|
|
770
|
-
...a === void 0 ? {} : { q: a },
|
|
771
|
-
...s ? { fit: s } : {},
|
|
772
|
-
...l ? { fp: l } : {}
|
|
773
|
-
};
|
|
774
|
-
}, ut = (e) => e.startsWith("image/") && !e.includes("svg"), dt, ft = async () => (dt ??= import("sharp").then((e) => e.default ?? e, () => null), dt), pt = async (e, t) => t ? null : ut(e) ? await ft() === null ? "no-sharp" : "failed" : "not-an-image", mt = async (e, t, n) => {
|
|
775
|
-
if (!ut(t)) return null;
|
|
776
|
-
let r = await ft();
|
|
777
|
-
if (!r) return null;
|
|
778
|
-
try {
|
|
779
|
-
let i = r(Buffer.from(e), { failOn: "none" }), a = n.fit ?? "cover";
|
|
780
|
-
if (n.fp !== void 0 && n.w !== void 0 && n.h !== void 0 && a === "cover") {
|
|
781
|
-
let e = await i.metadata();
|
|
782
|
-
e.width !== void 0 && e.height !== void 0 && (i = i.extract(st(e.width, e.height, n.w, n.h, n.fp.x, n.fp.y)));
|
|
783
|
-
}
|
|
784
|
-
(n.w !== void 0 || n.h !== void 0) && (i = i.resize({
|
|
785
|
-
...n.w === void 0 ? {} : { width: n.w },
|
|
786
|
-
...n.h === void 0 ? {} : { height: n.h },
|
|
787
|
-
fit: n.fit ?? "cover",
|
|
788
|
-
withoutEnlargement: !0
|
|
789
|
-
}));
|
|
790
|
-
let o = n.format && ct[n.format] ? n.format : void 0, s = t;
|
|
791
|
-
if (o) {
|
|
792
|
-
let e = o === "jpg" ? "jpeg" : o;
|
|
793
|
-
i = i.toFormat(e, n.q === void 0 ? {} : { quality: n.q }), s = ct[o];
|
|
794
|
-
} else n.q !== void 0 && (t === "image/jpeg" || t === "image/webp") && (i = i.toFormat(t === "image/webp" ? "webp" : "jpeg", { quality: n.q }));
|
|
795
|
-
let c = await i.toBuffer();
|
|
796
|
-
return {
|
|
797
|
-
bytes: new Uint8Array(c),
|
|
798
|
-
contentType: s
|
|
799
|
-
};
|
|
800
|
-
} catch {
|
|
801
|
-
return null;
|
|
802
|
-
}
|
|
803
|
-
}, ht = async (e, t, n) => {
|
|
804
|
-
if (!ut(t) || n.rotate === void 0 && n.flip !== !0 && n.flop !== !0 && n.grayscale !== !0 && n.crop === void 0) return null;
|
|
805
|
-
let r = await ft();
|
|
806
|
-
if (!r) return null;
|
|
807
|
-
try {
|
|
808
|
-
let i = r(Buffer.from(e), { failOn: "none" });
|
|
809
|
-
return n.crop !== void 0 && (i = i.extract(n.crop)), n.rotate !== void 0 && (i = i.rotate(n.rotate)), n.flip === !0 && (i = i.flip()), n.flop === !0 && (i = i.flop()), n.grayscale === !0 && (i = i.grayscale()), {
|
|
810
|
-
bytes: new Uint8Array(await i.toBuffer()),
|
|
811
|
-
contentType: t
|
|
812
|
-
};
|
|
813
|
-
} catch {
|
|
814
|
-
return null;
|
|
815
|
-
}
|
|
816
|
-
}, gt = ot(), _t = (e, t, n) => JSON.stringify([
|
|
817
|
-
e,
|
|
818
|
-
t,
|
|
819
|
-
n.w,
|
|
820
|
-
n.h,
|
|
821
|
-
n.format,
|
|
822
|
-
n.q,
|
|
823
|
-
n.fit,
|
|
824
|
-
n.fp?.x,
|
|
825
|
-
n.fp?.y
|
|
826
|
-
]), vt = async (e, t, n, r) => gt.getOrCreate(_t(e, n, r), () => mt(t, n, r)), yt = (e) => {
|
|
827
|
-
let t = we(16).toString("hex");
|
|
828
|
-
return `${t}:${Ee(e, t, 32).toString("hex")}`;
|
|
829
|
-
}, bt = (e, t) => {
|
|
830
|
-
if (!e || !t) return !1;
|
|
831
|
-
let [n, r] = t.split(":");
|
|
832
|
-
if (!n || !r) return !1;
|
|
833
|
-
let i = Buffer.from(r, "hex"), a = Ee(e, n, i.length);
|
|
834
|
-
return a.length === i.length && L(a, i);
|
|
835
|
-
}, xt = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], St = (e) => xt(e.metadata?.roles), Ct = (e) => xt(e.scopes), wt = (e, t) => e.some((e) => t.includes(e)), Tt = (e) => xt(e.metadata?.groups), Et = (e) => typeof e == "boolean" ? v.succeed(e) : v.isEffect(e) ? e : v.promise(() => e), Dt = (e, t, n = {}) => v.gen(function* () {
|
|
836
|
-
if (t.id && e.ownerId && t.id === e.ownerId) return !0;
|
|
837
|
-
let r = e.accessPolicy ?? [];
|
|
838
|
-
if (r.length === 0) return !1;
|
|
839
|
-
let i = n.resolveGroups ? yield* v.promise(async () => await n.resolveGroups(t)) : Tt(t);
|
|
840
|
-
for (let a of r) if (yield* Ot(a, e, t, i, n)) return !0;
|
|
841
|
-
return !1;
|
|
842
|
-
}), Ot = (e, t, n, r, i) => v.gen(function* () {
|
|
843
|
-
let a = !1, o = (e) => (a = !0, e);
|
|
844
|
-
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(wt(St(n), e.roles)) || e.groups && e.groups.length > 0 && !o(wt(r, e.groups)) || e.scopes && e.scopes.length > 0 && !o(wt(Ct(n), e.scopes)) || e.password !== void 0 && e.password && !o(bt(i.password, t.passwordHash))) return !1;
|
|
845
|
-
if (e.guard) {
|
|
846
|
-
let r = i.guards?.[e.guard];
|
|
847
|
-
if (!o(r ? yield* Et(r({
|
|
848
|
-
subject: n,
|
|
849
|
-
ref: t
|
|
850
|
-
})) : !1)) return !1;
|
|
851
|
-
}
|
|
852
|
-
return a;
|
|
853
|
-
}), kt = (e, t) => {
|
|
854
|
-
let n = [];
|
|
855
|
-
e.id && n.push({
|
|
856
|
-
type: e.type === "apiKey" ? "apiKey" : "user",
|
|
857
|
-
id: e.id
|
|
858
|
-
});
|
|
859
|
-
for (let e of t) n.push({
|
|
860
|
-
type: "group",
|
|
861
|
-
id: e
|
|
862
|
-
});
|
|
863
|
-
return n;
|
|
864
|
-
}, At = (e, t, n, r, i) => {
|
|
865
|
-
let a = kt(t, n);
|
|
866
|
-
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));
|
|
867
|
-
}, jt = (e, t) => t.resolveGroups ? v.promise(async () => await t.resolveGroups(e)) : v.succeed(Tt(e)), q = () => U.read("VOLTRO_STORAGE_SECRET") ?? ce(), J = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), Y = (e) => {
|
|
868
|
-
let t = e.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - e.length % 4) % 4);
|
|
869
|
-
return Buffer.from(t, "base64");
|
|
870
|
-
}, Mt = (e, t, n = q(), r = "/_voltro/storage") => {
|
|
871
|
-
if (!n) throw Error("signGrant: secret must be a non-empty string");
|
|
872
|
-
let i = {
|
|
873
|
-
refId: e,
|
|
874
|
-
audience: r,
|
|
875
|
-
exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
|
|
876
|
-
}, a = J(JSON.stringify(i));
|
|
877
|
-
return `${a}.${J(I("sha256", n).update(a).digest())}`;
|
|
878
|
-
}, Nt = (e, t = q()) => {
|
|
879
|
-
if (!e || !t) return null;
|
|
880
|
-
let n = e.indexOf(".");
|
|
881
|
-
if (n <= 0 || n === e.length - 1) return null;
|
|
882
|
-
let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(r).digest(), o = Y(i);
|
|
883
|
-
if (o.length !== a.length || !L(o, a)) return null;
|
|
884
|
-
try {
|
|
885
|
-
let e = JSON.parse(Y(r).toString("utf8"));
|
|
886
|
-
return typeof e.audience != "string" || !e.audience || typeof e.refId != "string" || typeof e.exp != "number" || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
|
|
887
|
-
} catch {
|
|
888
|
-
return null;
|
|
889
|
-
}
|
|
890
|
-
}, Pt = (e) => e.version === 1 ? e.access === void 0 || e.vis === "private" && y.isSuccess(S.decodeUnknownExit(ae, { onExcessProperty: "error" })(e.access)) : !1, Ft = (e, t, n = q()) => {
|
|
891
|
-
if (!n) throw Error("signUploadTicket: secret must be a non-empty string");
|
|
892
|
-
let r = {
|
|
893
|
-
...e,
|
|
894
|
-
version: 1,
|
|
895
|
-
exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
|
|
896
|
-
}, i = J(JSON.stringify(r));
|
|
897
|
-
return `${i}.${J(I("sha256", n).update(`u:${i}`).digest())}`;
|
|
898
|
-
}, It = (e, t = q()) => {
|
|
899
|
-
if (!e || !t) return null;
|
|
900
|
-
let n = e.indexOf(".");
|
|
901
|
-
if (n <= 0 || n === e.length - 1) return null;
|
|
902
|
-
let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`u:${r}`).digest(), o = Y(i);
|
|
903
|
-
if (o.length !== a.length || !L(o, a)) return null;
|
|
904
|
-
try {
|
|
905
|
-
let e = JSON.parse(Y(r).toString("utf8"));
|
|
906
|
-
return !Pt(e) || e.operationId !== void 0 && (typeof e.operationId != "string" || !e.operationId.trim() || e.operationId.length > 200) || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.replicaId !== void 0 && (typeof e.replicaId != "string" || !e.replicaId.trim()) || e.exp < Math.floor(Date.now() / 1e3) ? null : e;
|
|
907
|
-
} catch {
|
|
908
|
-
return null;
|
|
909
|
-
}
|
|
910
|
-
}, Lt = (e, t, n = q()) => {
|
|
911
|
-
if (!n) throw Error("signFinalizeTicket: secret must be a non-empty string");
|
|
912
|
-
let r = {
|
|
913
|
-
...e,
|
|
914
|
-
version: 1,
|
|
915
|
-
exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
|
|
916
|
-
}, i = J(JSON.stringify(r));
|
|
917
|
-
return `${i}.${J(I("sha256", n).update(`f:${i}`).digest())}`;
|
|
918
|
-
}, Rt = (e, t = q()) => {
|
|
919
|
-
if (!e || !t) return null;
|
|
920
|
-
let n = e.indexOf(".");
|
|
921
|
-
if (n <= 0 || n === e.length - 1) return null;
|
|
922
|
-
let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`f:${r}`).digest(), o = Y(i);
|
|
923
|
-
if (o.length !== a.length || !L(o, a)) return null;
|
|
924
|
-
try {
|
|
925
|
-
let e = JSON.parse(Y(r).toString("utf8"));
|
|
926
|
-
return !Pt(e) || 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;
|
|
927
|
-
} catch {
|
|
928
|
-
return null;
|
|
929
|
-
}
|
|
930
|
-
}, zt = (e, t, n = q()) => {
|
|
931
|
-
if (!n) throw Error("signResumableTicket: secret must be a non-empty string");
|
|
932
|
-
let r = {
|
|
933
|
-
...e,
|
|
934
|
-
version: 1,
|
|
935
|
-
exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
|
|
936
|
-
}, i = J(JSON.stringify(r));
|
|
937
|
-
return `${i}.${J(I("sha256", n).update(`r:${i}`).digest())}`;
|
|
938
|
-
}, Bt = (e, t = q()) => {
|
|
939
|
-
if (!e || !t) return null;
|
|
940
|
-
let n = e.indexOf(".");
|
|
941
|
-
if (n <= 0 || n === e.length - 1) return null;
|
|
942
|
-
let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`r:${r}`).digest(), o = Y(i);
|
|
943
|
-
if (o.length !== a.length || !L(o, a)) return null;
|
|
944
|
-
try {
|
|
945
|
-
let e = JSON.parse(Y(r).toString("utf8"));
|
|
946
|
-
return !Pt(e) || 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;
|
|
947
|
-
} catch {
|
|
948
|
-
return null;
|
|
949
|
-
}
|
|
950
|
-
}, Vt = (e, t, n = q()) => {
|
|
951
|
-
if (!n) throw Error("signMultipartTicket: secret must be a non-empty string");
|
|
952
|
-
let r = {
|
|
953
|
-
...e,
|
|
954
|
-
version: 1,
|
|
955
|
-
exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
|
|
956
|
-
}, i = J(JSON.stringify(r));
|
|
957
|
-
return `${i}.${J(I("sha256", n).update(`m:${i}`).digest())}`;
|
|
958
|
-
}, Ht = (e, t = q()) => {
|
|
959
|
-
if (!e || !t) return null;
|
|
960
|
-
let n = e.indexOf(".");
|
|
961
|
-
if (n <= 0 || n === e.length - 1) return null;
|
|
962
|
-
let r = e.slice(0, n), i = e.slice(n + 1), a = I("sha256", t).update(`m:${r}`).digest(), o = Y(i);
|
|
963
|
-
if (o.length !== a.length || !L(o, a)) return null;
|
|
964
|
-
try {
|
|
965
|
-
let e = JSON.parse(Y(r).toString("utf8"));
|
|
966
|
-
return !Pt(e) || 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;
|
|
967
|
-
} catch {
|
|
968
|
-
return null;
|
|
969
|
-
}
|
|
970
|
-
}, Ut = (e, t) => {
|
|
971
|
-
if (!t || t.length === 0) return !0;
|
|
972
|
-
let n = e.toLowerCase();
|
|
973
|
-
return t.some((e) => {
|
|
974
|
-
let t = e.toLowerCase();
|
|
975
|
-
return t.endsWith("/*") ? n.startsWith(t.slice(0, -1)) : n === t;
|
|
976
|
-
});
|
|
977
|
-
}, Wt = [
|
|
978
|
-
{
|
|
979
|
-
ct: /^image\/png$/,
|
|
980
|
-
offset: 0,
|
|
981
|
-
magic: [
|
|
982
|
-
137,
|
|
983
|
-
80,
|
|
984
|
-
78,
|
|
985
|
-
71
|
|
986
|
-
]
|
|
987
|
-
},
|
|
988
|
-
{
|
|
989
|
-
ct: /^image\/jpe?g$/,
|
|
990
|
-
offset: 0,
|
|
991
|
-
magic: [
|
|
992
|
-
255,
|
|
993
|
-
216,
|
|
994
|
-
255
|
|
995
|
-
]
|
|
996
|
-
},
|
|
997
|
-
{
|
|
998
|
-
ct: /^image\/gif$/,
|
|
999
|
-
offset: 0,
|
|
1000
|
-
magic: [
|
|
1001
|
-
71,
|
|
1002
|
-
73,
|
|
1003
|
-
70,
|
|
1004
|
-
56
|
|
1005
|
-
]
|
|
1006
|
-
},
|
|
1007
|
-
{
|
|
1008
|
-
ct: /^image\/webp$/,
|
|
1009
|
-
offset: 0,
|
|
1010
|
-
magic: [
|
|
1011
|
-
82,
|
|
1012
|
-
73,
|
|
1013
|
-
70,
|
|
1014
|
-
70
|
|
1015
|
-
]
|
|
1016
|
-
},
|
|
1017
|
-
{
|
|
1018
|
-
ct: /^image\/bmp$/,
|
|
1019
|
-
offset: 0,
|
|
1020
|
-
magic: [66, 77]
|
|
1021
|
-
},
|
|
1022
|
-
{
|
|
1023
|
-
ct: /^application\/pdf$/,
|
|
1024
|
-
offset: 0,
|
|
1025
|
-
magic: [
|
|
1026
|
-
37,
|
|
1027
|
-
80,
|
|
1028
|
-
68,
|
|
1029
|
-
70
|
|
1030
|
-
]
|
|
1031
|
-
},
|
|
1032
|
-
{
|
|
1033
|
-
ct: /^application\/zip$/,
|
|
1034
|
-
offset: 0,
|
|
1035
|
-
magic: [
|
|
1036
|
-
80,
|
|
1037
|
-
75,
|
|
1038
|
-
3,
|
|
1039
|
-
4
|
|
1040
|
-
]
|
|
1041
|
-
},
|
|
1042
|
-
{
|
|
1043
|
-
ct: /^application\/gzip$/,
|
|
1044
|
-
offset: 0,
|
|
1045
|
-
magic: [31, 139]
|
|
1046
|
-
}
|
|
1047
|
-
], Gt = (e, t) => {
|
|
1048
|
-
let n = t.toLowerCase(), r = Wt.find((e) => e.ct.test(n));
|
|
1049
|
-
return r ? e.length < r.offset + r.magic.length ? !1 : r.magic.every((t, n) => e[r.offset + n] === t) : !0;
|
|
1050
|
-
}, Kt = (e, t, n) => n ? n.maxBytes !== void 0 && e.byteLength > n.maxBytes ? {
|
|
1051
|
-
reason: "too-large",
|
|
1052
|
-
detail: `${e.byteLength} bytes exceeds the ${n.maxBytes}-byte limit`
|
|
1053
|
-
} : Ut(t, n.allowedContentTypes) ? n.sniff && !Gt(e, t) ? {
|
|
1054
|
-
reason: "content-mismatch",
|
|
1055
|
-
detail: `bytes do not match the declared content type '${t}'`
|
|
1056
|
-
} : null : {
|
|
1057
|
-
reason: "content-type-not-allowed",
|
|
1058
|
-
detail: `content type '${t}' is not in the allow-list`
|
|
1059
|
-
} : null, qt = async (e, t, n) => {
|
|
1060
|
-
if (!ut(t)) return { bytes: e };
|
|
1061
|
-
let r = await ft();
|
|
1062
|
-
if (!r) return { bytes: e };
|
|
1063
|
-
try {
|
|
1064
|
-
let t = e;
|
|
1065
|
-
if (n?.normalize) {
|
|
1066
|
-
let n = await r(Buffer.from(e), { failOn: "none" }).rotate().toBuffer();
|
|
1067
|
-
t = new Uint8Array(n);
|
|
1068
|
-
}
|
|
1069
|
-
let i = await r(Buffer.from(t), { failOn: "none" }).metadata(), a = await r(Buffer.from(t), { failOn: "none" }).resize({
|
|
1070
|
-
width: 24,
|
|
1071
|
-
height: 24,
|
|
1072
|
-
fit: "inside",
|
|
1073
|
-
withoutEnlargement: !0
|
|
1074
|
-
}).webp({ quality: 40 }).toBuffer().catch(() => null);
|
|
1075
|
-
return {
|
|
1076
|
-
bytes: t,
|
|
1077
|
-
...typeof i.width == "number" ? { width: i.width } : {},
|
|
1078
|
-
...typeof i.height == "number" ? { height: i.height } : {},
|
|
1079
|
-
...a ? { placeholder: `data:image/webp;base64,${a.toString("base64")}` } : {}
|
|
1080
|
-
};
|
|
1081
|
-
} catch {
|
|
1082
|
-
return { bytes: e };
|
|
1083
|
-
}
|
|
1084
|
-
}, Jt = 67108864, Yt = (e) => new n({
|
|
1085
|
-
reason: "too-large",
|
|
1086
|
-
detail: `remote body exceeds the ${e}-byte ingest limit`
|
|
1087
|
-
}), Xt = (e, t) => new n({
|
|
1088
|
-
reason: "blocked-source",
|
|
1089
|
-
detail: `will not fetch ${e}: ${t}`
|
|
1090
|
-
}), Zt = (e, r, i = {}) => v.suspend(() => {
|
|
1091
|
-
let a = r ?? Jt;
|
|
1092
|
-
return !Number.isSafeInteger(a) || a < 0 ? v.fail(new t({
|
|
1093
|
-
provider: "ingest",
|
|
1094
|
-
message: "limits.maxBytes must be a non-negative safe integer",
|
|
1095
|
-
transient: !1
|
|
1096
|
-
})) : v.tryPromise({
|
|
1097
|
-
try: async (n) => {
|
|
1098
|
-
let r = e, o;
|
|
1099
|
-
for (let e = 0;; e++) {
|
|
1100
|
-
let t = De(r, { ...i.allowHosts === void 0 ? {} : { allowHosts: i.allowHosts } });
|
|
1101
|
-
if (t !== null) throw Xt(r, t);
|
|
1102
|
-
o = await fetch(r, {
|
|
1103
|
-
signal: n,
|
|
1104
|
-
redirect: "manual"
|
|
1105
|
-
});
|
|
1106
|
-
let a = o.headers.get("location");
|
|
1107
|
-
if (o.status < 300 || o.status >= 400 || a === null) break;
|
|
1108
|
-
if (await o.body?.cancel().catch(() => {}), e >= (i.maxRedirects ?? 5)) throw Xt(r, "too many redirects");
|
|
1109
|
-
r = new URL(a, r).toString();
|
|
1110
|
-
}
|
|
1111
|
-
let s;
|
|
1112
|
-
try {
|
|
1113
|
-
if (!o.ok) throw new t({
|
|
1114
|
-
provider: "ingest",
|
|
1115
|
-
message: `remote server returned HTTP ${o.status}`,
|
|
1116
|
-
transient: o.status === 429 || o.status >= 500,
|
|
1117
|
-
status: o.status
|
|
1118
|
-
});
|
|
1119
|
-
let e = o.headers.get("content-length"), n = o.headers.get("content-encoding")?.trim().toLowerCase();
|
|
1120
|
-
if ((!n || n === "identity") && e !== null && /^\d+$/.test(e) && BigInt(e) > BigInt(a)) throw Yt(a);
|
|
1121
|
-
let r = /* @__PURE__ */ new Uint8Array(), i = 0;
|
|
1122
|
-
if (o.body !== null) for (s = o.body.getReader();;) {
|
|
1123
|
-
let e = await s.read();
|
|
1124
|
-
if (e.done) break;
|
|
1125
|
-
if (e.value.byteLength > a - i) throw Yt(a);
|
|
1126
|
-
if (e.value.byteLength !== 0) {
|
|
1127
|
-
let t = i + e.value.byteLength;
|
|
1128
|
-
if (t > r.byteLength) {
|
|
1129
|
-
let e = Math.min(a, Math.max(65536, r.byteLength * 2, t)), n = new Uint8Array(e);
|
|
1130
|
-
n.set(r), r = n;
|
|
1131
|
-
}
|
|
1132
|
-
r.set(e.value, i), i = t;
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
return {
|
|
1136
|
-
bytes: i === r.byteLength ? r : r.slice(0, i),
|
|
1137
|
-
contentType: o.headers.get("content-type")?.split(";")[0]?.trim() || "application/octet-stream"
|
|
1138
|
-
};
|
|
1139
|
-
} finally {
|
|
1140
|
-
s === void 0 ? await o.body?.cancel().catch(() => {}) : (await s.cancel().catch(() => {}), s.releaseLock());
|
|
1141
|
-
}
|
|
1142
|
-
},
|
|
1143
|
-
catch: (e) => e instanceof n || e instanceof t ? e : new t({
|
|
1144
|
-
provider: "ingest",
|
|
1145
|
-
message: "remote fetch or body read failed",
|
|
1146
|
-
transient: !0
|
|
1147
|
-
})
|
|
1148
|
-
});
|
|
1149
|
-
}), Qt = (e, t) => v.suspend(() => {
|
|
1150
|
-
if (t === void 0) return e;
|
|
1151
|
-
if (t.aborted) return v.interrupt;
|
|
1152
|
-
let n = v.callback((e) => {
|
|
1153
|
-
let n = () => e(v.interrupt);
|
|
1154
|
-
return t.addEventListener("abort", n, { once: !0 }), t.aborted && n(), v.sync(() => t.removeEventListener("abort", n));
|
|
1155
|
-
});
|
|
1156
|
-
return v.raceFirst(e, n);
|
|
1157
|
-
}), $t = (e) => {
|
|
1158
|
-
let r = (e, n) => v.tryPromise({
|
|
1159
|
-
try: n,
|
|
1160
|
-
catch: (n) => {
|
|
1161
|
-
let r = Ye(n);
|
|
1162
|
-
if (r !== void 0) return r;
|
|
1163
|
-
let i = G(n, "metadata"), a = new t({
|
|
1164
|
-
provider: "metadata",
|
|
1165
|
-
message: `Storage ${e} was not confirmed: ${i.message}; retain the operation identity for recovery`,
|
|
1166
|
-
transient: i.transient,
|
|
1167
|
-
...i.status === void 0 ? {} : { status: i.status }
|
|
1168
|
-
});
|
|
1169
|
-
return Object.defineProperty(a, "cause", {
|
|
1170
|
-
value: n,
|
|
1171
|
-
configurable: !0
|
|
1172
|
-
}), a;
|
|
1173
|
-
}
|
|
1174
|
-
});
|
|
1175
|
-
return {
|
|
1176
|
-
put: (t) => v.gen(function* () {
|
|
1177
|
-
if (t.bytes.byteLength !== t.ref.size || Ce("sha256").update(t.bytes).digest("hex") !== t.identity.checksum) return yield* v.fail(new n({
|
|
1178
|
-
reason: "operation-content-mismatch",
|
|
1179
|
-
detail: "Storage operation bytes do not match their reserved identity"
|
|
1180
|
-
}));
|
|
1181
|
-
let i = yield* r("put reservation", () => e.metadata.reserve(t.identity, t.ref, t.quota, t.claim)), a = i.outcome;
|
|
1182
|
-
return i.ready ? {
|
|
1183
|
-
ref: i.ref,
|
|
1184
|
-
outcome: a
|
|
1185
|
-
} : (yield* e.provider.put(i.ref.key, t.bytes, {
|
|
1186
|
-
contentType: i.ref.contentType,
|
|
1187
|
-
public: i.ref.visibility === "public"
|
|
1188
|
-
}), {
|
|
1189
|
-
ref: yield* r("put confirmation", () => e.metadata.confirm(t.identity, t.claim)),
|
|
1190
|
-
outcome: a
|
|
1191
|
-
});
|
|
1192
|
-
}),
|
|
1193
|
-
delete: (t, n, i) => v.gen(function* () {
|
|
1194
|
-
let a = yield* r("delete acceptance", () => e.metadata.beginDelete(t, n, i));
|
|
1195
|
-
"operation" in a && (a.operation.deleteKey !== null && (yield* e.provider.delete(a.operation.deleteKey)), yield* r("delete confirmation", () => e.metadata.confirmDelete(a.identity)));
|
|
1196
|
-
})
|
|
1197
|
-
};
|
|
1198
|
-
}, en = async (e) => {
|
|
1199
|
-
let { createHash: t } = await import("node:crypto");
|
|
1200
|
-
return t("sha256").update(e).digest("hex");
|
|
1201
|
-
}, tn = (e, t, n) => `${e?.replace(/\/+$/, "") ?? ""}${n}/${t}`, nn = (e) => {
|
|
1202
|
-
let t = /* @__PURE__ */ new Map(), n = {
|
|
1203
|
-
public: 0,
|
|
1204
|
-
private: 0
|
|
1205
|
-
};
|
|
1206
|
-
for (let r of e) {
|
|
1207
|
-
let e = r.tenantId ?? "(global)", i = t.get(e) ?? {
|
|
1208
|
-
count: 0,
|
|
1209
|
-
bytes: 0
|
|
1210
|
-
};
|
|
1211
|
-
i.count = Je(i.count, r.count, "ref count"), i.bytes = Je(i.bytes, r.bytes, "usage bytes"), t.set(e, i), r.visibility === "public" ? n.public = Je(n.public, r.count, "public ref count") : n.private = Je(n.private, r.count, "private ref count");
|
|
1212
|
-
}
|
|
1213
|
-
return {
|
|
1214
|
-
byTenant: Object.fromEntries(t),
|
|
1215
|
-
visibility: n
|
|
1216
|
-
};
|
|
1217
|
-
}, rn = (e, t) => {
|
|
1218
|
-
if (t.search && ![
|
|
1219
|
-
e.id,
|
|
1220
|
-
e.key,
|
|
1221
|
-
e.contentType,
|
|
1222
|
-
e.ownerId,
|
|
1223
|
-
e.tenantId
|
|
1224
|
-
].some((e) => e?.toLowerCase().includes(t.search.toLowerCase())) || t.tenantId !== void 0 && (e.tenantId ?? null) !== (t.tenantId ?? null) || t.ownerId !== void 0 && e.ownerId !== t.ownerId || !t.includeDerived && e.derivedFrom != null) return !1;
|
|
1225
|
-
if (t.folder !== void 0) {
|
|
1226
|
-
let n = t.folder.replace(/\/+$/, ""), r = (e.folder ?? "").replace(/\/+$/, "");
|
|
1227
|
-
if (r !== n && !r.startsWith(`${n}/`)) return !1;
|
|
1228
|
-
}
|
|
1229
|
-
if (t.tags.length > 0) {
|
|
1230
|
-
let n = e.tags ?? [];
|
|
1231
|
-
if (!t.tags.every((e) => n.includes(e))) return !1;
|
|
1232
|
-
}
|
|
1233
|
-
return !0;
|
|
1234
|
-
}, an = (e) => e ?? "global", on = () => {
|
|
1235
|
-
let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
|
|
1236
|
-
return {
|
|
1237
|
-
statistics: () => v.try({
|
|
1238
|
-
try: () => nn((function* () {
|
|
1239
|
-
for (let t of e.values()) yield {
|
|
1240
|
-
tenantId: t.tenantId,
|
|
1241
|
-
visibility: t.visibility,
|
|
1242
|
-
count: 1,
|
|
1243
|
-
bytes: t.size
|
|
1244
|
-
};
|
|
1245
|
-
})()),
|
|
1246
|
-
catch: (e) => G(e, "refstore")
|
|
1247
|
-
}),
|
|
1248
|
-
insert: (t) => v.try({
|
|
1249
|
-
try: () => {
|
|
1250
|
-
W(t.size, "ref size"), e.set(t.id, t);
|
|
1251
|
-
},
|
|
1252
|
-
catch: (e) => G(e, "refstore")
|
|
1253
|
-
}),
|
|
1254
|
-
getById: (t) => v.sync(() => e.get(t) ?? null),
|
|
1255
|
-
delete: (t) => v.sync(() => e.delete(t)),
|
|
1256
|
-
listRecent: (t) => v.sync(() => [...e.values()].sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(0, t)),
|
|
1257
|
-
countByKey: (t, n) => v.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n).length),
|
|
1258
|
-
countPublicByKey: (t, n) => v.sync(() => [...e.values()].filter((e) => e.bucket === t && e.key === n && e.visibility === "public").length),
|
|
1259
|
-
setVisibility: (t, n) => v.sync(() => {
|
|
1260
|
-
let r = e.get(t);
|
|
1261
|
-
if (r === void 0) return null;
|
|
1262
|
-
let i = {
|
|
1263
|
-
...r,
|
|
1264
|
-
visibility: n
|
|
1265
|
-
};
|
|
1266
|
-
return e.set(t, i), i;
|
|
1267
|
-
}),
|
|
1268
|
-
usageByTenant: (t) => v.try({
|
|
1269
|
-
try: () => {
|
|
1270
|
-
let n = 0, r = 0;
|
|
1271
|
-
for (let i of e.values()) (i.tenantId ?? null) === (t ?? null) && (n = Je(n, i.size, "usage bytes"), r++);
|
|
1272
|
-
return {
|
|
1273
|
-
bytes: n,
|
|
1274
|
-
count: r
|
|
1275
|
-
};
|
|
1276
|
-
},
|
|
1277
|
-
catch: (e) => G(e, "refstore")
|
|
1278
|
-
}),
|
|
1279
|
-
consumeUsage: (e, n, r) => v.try({
|
|
1280
|
-
try: () => {
|
|
1281
|
-
let i = an(e), a = t.get(i) ?? {
|
|
1282
|
-
bytes: 0,
|
|
1283
|
-
count: 0
|
|
1284
|
-
};
|
|
1285
|
-
W(n.bytes, "usage byte delta"), W(n.count, "usage count delta");
|
|
1286
|
-
let o = Number.isSafeInteger(a.bytes + n.bytes) && Number.isSafeInteger(a.count + n.count) && (r?.maxBytes === void 0 || a.bytes + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || a.count + n.count <= r.maxCount);
|
|
1287
|
-
return o && t.set(i, {
|
|
1288
|
-
bytes: a.bytes + n.bytes,
|
|
1289
|
-
count: a.count + n.count
|
|
1290
|
-
}), {
|
|
1291
|
-
allowed: o,
|
|
1292
|
-
bytes: a.bytes,
|
|
1293
|
-
count: a.count
|
|
1294
|
-
};
|
|
1295
|
-
},
|
|
1296
|
-
catch: (e) => G(e, "refstore")
|
|
1297
|
-
}),
|
|
1298
|
-
releaseUsage: (e, n) => v.try({
|
|
1299
|
-
try: () => {
|
|
1300
|
-
let r = an(e), i = t.get(r);
|
|
1301
|
-
W(n.bytes, "usage byte delta"), W(n.count, "usage count delta"), i && t.set(r, {
|
|
1302
|
-
bytes: Math.max(0, i.bytes - n.bytes),
|
|
1303
|
-
count: Math.max(0, i.count - n.count)
|
|
1304
|
-
});
|
|
1305
|
-
},
|
|
1306
|
-
catch: (e) => G(e, "refstore")
|
|
1307
|
-
}),
|
|
1308
|
-
listByDerivedFrom: (t) => v.sync(() => [...e.values()].filter((e) => (e.derivedFrom ?? null) === t)),
|
|
1309
|
-
listRefs: (t) => v.sync(() => [...e.values()].filter((e) => rn(e, t)).sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime() || t.id.localeCompare(e.id)).slice(t.offset, t.offset + t.limit))
|
|
1310
|
-
};
|
|
1311
|
-
}, sn = (e) => Array.isArray(e) && e.every((e) => typeof e == "string") ? e : null, X = (e) => ({
|
|
1312
|
-
id: String(e.id),
|
|
1313
|
-
tenantId: e.tenantId ?? null,
|
|
1314
|
-
ownerId: e.ownerId ?? null,
|
|
1315
|
-
bucket: String(e.bucket),
|
|
1316
|
-
key: String(e.key),
|
|
1317
|
-
contentType: String(e.contentType),
|
|
1318
|
-
size: W(e.size, "ref size"),
|
|
1319
|
-
checksum: String(e.checksum),
|
|
1320
|
-
visibility: e.visibility === "public" ? "public" : "private",
|
|
1321
|
-
accessPolicy: e.accessPolicy ?? null,
|
|
1322
|
-
passwordHash: e.passwordHash ?? null,
|
|
1323
|
-
createdAt: e.createdAt instanceof Date ? e.createdAt : new Date(String(e.createdAt)),
|
|
1324
|
-
width: e.width ?? null,
|
|
1325
|
-
height: e.height ?? null,
|
|
1326
|
-
duration: e.duration ?? null,
|
|
1327
|
-
placeholder: e.placeholder ?? null,
|
|
1328
|
-
folder: e.folder ?? null,
|
|
1329
|
-
tags: sn(e.tags),
|
|
1330
|
-
alt: e.alt ?? null,
|
|
1331
|
-
caption: e.caption ?? null,
|
|
1332
|
-
derivedFrom: e.derivedFrom ?? null,
|
|
1333
|
-
kind: e.kind ?? null
|
|
1334
|
-
}), Z = (e) => v.tryPromise({
|
|
1335
|
-
try: e,
|
|
1336
|
-
catch: (e) => G(e, "refstore", !0)
|
|
1337
|
-
}), cn = async (e, t) => (await e.query({
|
|
1338
|
-
table: "_voltro_storage_usage",
|
|
1339
|
-
predicate: {
|
|
1340
|
-
column: "tenantId",
|
|
1341
|
-
op: "eq",
|
|
1342
|
-
value: t
|
|
1343
|
-
},
|
|
1344
|
-
order: [],
|
|
1345
|
-
take: 1,
|
|
1346
|
-
skip: void 0,
|
|
1347
|
-
projection: void 0
|
|
1348
|
-
}))[0] ?? null, ln = (e) => ({
|
|
1349
|
-
statistics: () => Z(async () => nn((await e.query({
|
|
1350
|
-
table: B,
|
|
1351
|
-
predicate: void 0,
|
|
1352
|
-
order: [],
|
|
1353
|
-
take: void 0,
|
|
1354
|
-
skip: void 0,
|
|
1355
|
-
projection: void 0,
|
|
1356
|
-
groupBy: ["tenantId", "visibility"],
|
|
1357
|
-
aggregations: [
|
|
1358
|
-
de("tenantId"),
|
|
1359
|
-
de("visibility"),
|
|
1360
|
-
{
|
|
1361
|
-
op: "count",
|
|
1362
|
-
alias: "count"
|
|
1363
|
-
},
|
|
1364
|
-
{
|
|
1365
|
-
op: "sum",
|
|
1366
|
-
column: "size",
|
|
1367
|
-
alias: "bytes"
|
|
1368
|
-
}
|
|
1369
|
-
]
|
|
1370
|
-
})).map((e) => ({
|
|
1371
|
-
tenantId: e.tenantId == null ? null : String(e.tenantId),
|
|
1372
|
-
visibility: String(e.visibility),
|
|
1373
|
-
count: W(e.count, "ref count"),
|
|
1374
|
-
bytes: W(e.bytes ?? 0, "usage bytes")
|
|
1375
|
-
})))),
|
|
1376
|
-
insert: (t) => Z(() => e.insert(B, {
|
|
1377
|
-
...t,
|
|
1378
|
-
size: String(W(t.size, "ref size"))
|
|
1379
|
-
})),
|
|
1380
|
-
getById: (t) => Z(async () => {
|
|
1381
|
-
let n = await e.query({
|
|
1382
|
-
table: B,
|
|
1383
|
-
predicate: {
|
|
1384
|
-
column: "id",
|
|
1385
|
-
op: "eq",
|
|
1386
|
-
value: t
|
|
1387
|
-
},
|
|
1388
|
-
order: [],
|
|
1389
|
-
take: 1,
|
|
1390
|
-
skip: void 0,
|
|
1391
|
-
projection: void 0
|
|
1392
|
-
});
|
|
1393
|
-
return n[0] ? X(n[0]) : null;
|
|
1394
|
-
}),
|
|
1395
|
-
delete: (t) => Z(() => e.delete(B, t)),
|
|
1396
|
-
listRecent: (t) => Z(async () => (await e.query({
|
|
1397
|
-
table: B,
|
|
1398
|
-
predicate: void 0,
|
|
1399
|
-
order: [{
|
|
1400
|
-
column: "createdAt",
|
|
1401
|
-
direction: "desc"
|
|
1402
|
-
}],
|
|
1403
|
-
take: t,
|
|
1404
|
-
skip: void 0,
|
|
1405
|
-
projection: void 0
|
|
1406
|
-
})).map(X)),
|
|
1407
|
-
countByKey: (t, n) => Z(async () => W((await e.query({
|
|
1408
|
-
table: B,
|
|
1409
|
-
predicate: { and: [{
|
|
1410
|
-
column: "bucket",
|
|
1411
|
-
op: "eq",
|
|
1412
|
-
value: t
|
|
1413
|
-
}, {
|
|
1414
|
-
column: "key",
|
|
1415
|
-
op: "eq",
|
|
1416
|
-
value: n
|
|
1417
|
-
}] },
|
|
1418
|
-
order: [],
|
|
1419
|
-
take: void 0,
|
|
1420
|
-
skip: void 0,
|
|
1421
|
-
projection: void 0,
|
|
1422
|
-
aggregations: [{
|
|
1423
|
-
op: "count",
|
|
1424
|
-
alias: "count"
|
|
1425
|
-
}]
|
|
1426
|
-
}))[0]?.count ?? 0, "ref count")),
|
|
1427
|
-
countPublicByKey: (t, n) => Z(async () => W((await e.query({
|
|
1428
|
-
table: B,
|
|
1429
|
-
predicate: { and: [
|
|
1430
|
-
{
|
|
1431
|
-
column: "bucket",
|
|
1432
|
-
op: "eq",
|
|
1433
|
-
value: t
|
|
1434
|
-
},
|
|
1435
|
-
{
|
|
1436
|
-
column: "key",
|
|
1437
|
-
op: "eq",
|
|
1438
|
-
value: n
|
|
1439
|
-
},
|
|
1440
|
-
{
|
|
1441
|
-
column: "visibility",
|
|
1442
|
-
op: "eq",
|
|
1443
|
-
value: "public"
|
|
1444
|
-
}
|
|
1445
|
-
] },
|
|
1446
|
-
order: [],
|
|
1447
|
-
take: void 0,
|
|
1448
|
-
skip: void 0,
|
|
1449
|
-
projection: void 0,
|
|
1450
|
-
aggregations: [{
|
|
1451
|
-
op: "count",
|
|
1452
|
-
alias: "count"
|
|
1453
|
-
}]
|
|
1454
|
-
}))[0]?.count ?? 0, "ref count")),
|
|
1455
|
-
setVisibility: (t, n) => Z(async () => {
|
|
1456
|
-
let r = await e.update(B, t, { visibility: n });
|
|
1457
|
-
return r ? X(r) : null;
|
|
1458
|
-
}),
|
|
1459
|
-
usageByTenant: (t) => Z(async () => {
|
|
1460
|
-
let n = await e.query({
|
|
1461
|
-
table: B,
|
|
1462
|
-
predicate: {
|
|
1463
|
-
column: "tenantId",
|
|
1464
|
-
op: "eq",
|
|
1465
|
-
value: t
|
|
1466
|
-
},
|
|
1467
|
-
order: [],
|
|
1468
|
-
take: void 0,
|
|
1469
|
-
skip: void 0,
|
|
1470
|
-
projection: void 0,
|
|
1471
|
-
aggregations: [
|
|
1472
|
-
{
|
|
1473
|
-
op: "count",
|
|
1474
|
-
alias: "count"
|
|
1475
|
-
},
|
|
1476
|
-
{
|
|
1477
|
-
op: "sum",
|
|
1478
|
-
column: "size",
|
|
1479
|
-
alias: "bytes"
|
|
1480
|
-
},
|
|
1481
|
-
{
|
|
1482
|
-
op: "min",
|
|
1483
|
-
column: "size",
|
|
1484
|
-
alias: "minSize"
|
|
1485
|
-
},
|
|
1486
|
-
{
|
|
1487
|
-
op: "max",
|
|
1488
|
-
column: "size",
|
|
1489
|
-
alias: "maxSize"
|
|
1490
|
-
}
|
|
1491
|
-
]
|
|
1492
|
-
});
|
|
1493
|
-
return W(n[0]?.count ?? 0, "ref count") > 0 && (W(n[0]?.minSize, "ref size"), W(n[0]?.maxSize, "ref size")), {
|
|
1494
|
-
bytes: W(n[0]?.bytes ?? 0, "usage bytes"),
|
|
1495
|
-
count: W(n[0]?.count ?? 0, "ref count")
|
|
1496
|
-
};
|
|
1497
|
-
}),
|
|
1498
|
-
consumeUsage: (t, n, r) => Z(async () => {
|
|
1499
|
-
let i = an(t);
|
|
1500
|
-
W(n.bytes, "usage byte delta"), W(n.count, "usage count delta");
|
|
1501
|
-
for (let t = 0; t < 32; t++) {
|
|
1502
|
-
t > 0 && await new Promise((e) => setTimeout(e, t));
|
|
1503
|
-
let a = await cn(e, i), o = a ? W(a.bytes, "usage bytes") : 0, s = a ? W(a.count, "ref count") : 0;
|
|
1504
|
-
if (!(Number.isSafeInteger(o + n.bytes) && Number.isSafeInteger(s + n.count) && (r?.maxBytes === void 0 || o + n.bytes <= r.maxBytes) && (r?.maxCount === void 0 || s + n.count <= r.maxCount))) return {
|
|
1505
|
-
allowed: !1,
|
|
1506
|
-
bytes: o,
|
|
1507
|
-
count: s
|
|
1508
|
-
};
|
|
1509
|
-
if (a) {
|
|
1510
|
-
if (await e.updateMany("_voltro_storage_usage", {
|
|
1511
|
-
bytes: String(o + n.bytes),
|
|
1512
|
-
count: String(s + n.count),
|
|
1513
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
1514
|
-
}, { where: ue(k("id", String(a.id)), k("bytes", a.bytes), k("count", a.count)) }) === 1) return {
|
|
1515
|
-
allowed: !0,
|
|
1516
|
-
bytes: o,
|
|
1517
|
-
count: s
|
|
1518
|
-
};
|
|
1519
|
-
} else {
|
|
1520
|
-
let t = A({
|
|
1521
|
-
kind: "typeid",
|
|
1522
|
-
prefix: "susage"
|
|
1523
|
-
}, Ue), r = await e.insertIgnore(Ue, {
|
|
1524
|
-
id: t,
|
|
1525
|
-
tenantId: i,
|
|
1526
|
-
bytes: String(n.bytes),
|
|
1527
|
-
count: String(n.count),
|
|
1528
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
1529
|
-
}, { conflictColumns: ["tenantId"] });
|
|
1530
|
-
if (String(r.id) === t) return {
|
|
1531
|
-
allowed: !0,
|
|
1532
|
-
bytes: 0,
|
|
1533
|
-
count: 0
|
|
1534
|
-
};
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
throw T("Storage quota reservation contended after 32 attempts; retry");
|
|
1538
|
-
}),
|
|
1539
|
-
releaseUsage: (t, n) => Z(async () => {
|
|
1540
|
-
let r = an(t);
|
|
1541
|
-
W(n.bytes, "usage byte delta"), W(n.count, "usage count delta");
|
|
1542
|
-
for (let t = 0; t < 32; t++) {
|
|
1543
|
-
t > 0 && await new Promise((e) => setTimeout(e, t));
|
|
1544
|
-
let i = await cn(e, r);
|
|
1545
|
-
if (!i) return;
|
|
1546
|
-
let a = W(i.bytes, "usage bytes"), o = W(i.count, "ref count");
|
|
1547
|
-
if (await e.updateMany("_voltro_storage_usage", {
|
|
1548
|
-
bytes: String(Math.max(0, a - n.bytes)),
|
|
1549
|
-
count: String(Math.max(0, o - n.count)),
|
|
1550
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
1551
|
-
}, { where: ue(k("id", String(i.id)), k("bytes", i.bytes), k("count", i.count)) }) === 1) return;
|
|
1552
|
-
}
|
|
1553
|
-
throw T("Storage quota release contended after 32 attempts; retry");
|
|
1554
|
-
}),
|
|
1555
|
-
listByDerivedFrom: (t) => Z(async () => (await e.query({
|
|
1556
|
-
table: B,
|
|
1557
|
-
predicate: {
|
|
1558
|
-
column: "derivedFrom",
|
|
1559
|
-
op: "eq",
|
|
1560
|
-
value: t
|
|
1561
|
-
},
|
|
1562
|
-
order: [{
|
|
1563
|
-
column: "createdAt",
|
|
1564
|
-
direction: "asc"
|
|
1565
|
-
}],
|
|
1566
|
-
take: void 0,
|
|
1567
|
-
skip: void 0,
|
|
1568
|
-
projection: void 0
|
|
1569
|
-
})).map(X)),
|
|
1570
|
-
listRefs: (t) => Z(async () => {
|
|
1571
|
-
let n = [];
|
|
1572
|
-
t.tenantId !== void 0 && n.push(k("tenantId", t.tenantId)), t.ownerId !== void 0 && n.push(k("ownerId", t.ownerId)), t.search && n.push(N(...[
|
|
1573
|
-
"id",
|
|
1574
|
-
"key",
|
|
1575
|
-
"contentType",
|
|
1576
|
-
"ownerId",
|
|
1577
|
-
"tenantId"
|
|
1578
|
-
].map((e) => fe(e, t.search)))), t.includeDerived || n.push(me("derivedFrom"));
|
|
1579
|
-
let r = t.folder === void 0 && t.tags.length === 0, i = n.length ? ue(...n) : void 0, a = await e.query({
|
|
1580
|
-
table: B,
|
|
1581
|
-
predicate: i,
|
|
1582
|
-
order: [{
|
|
1583
|
-
column: "createdAt",
|
|
1584
|
-
direction: "desc"
|
|
1585
|
-
}, {
|
|
1586
|
-
column: "id",
|
|
1587
|
-
direction: "desc"
|
|
1588
|
-
}],
|
|
1589
|
-
take: r ? t.limit : void 0,
|
|
1590
|
-
skip: r ? t.offset : void 0,
|
|
1591
|
-
projection: void 0
|
|
1592
|
-
});
|
|
1593
|
-
return r ? a.map(X) : a.map(X).filter((e) => rn(e, t)).slice(t.offset, t.offset + t.limit);
|
|
1594
|
-
})
|
|
1595
|
-
}), un = () => {
|
|
1596
|
-
let e = /* @__PURE__ */ new Map();
|
|
1597
|
-
return {
|
|
1598
|
-
insert: (t) => v.sync(() => {
|
|
1599
|
-
e.set(t.id, t);
|
|
1600
|
-
}),
|
|
1601
|
-
delete: (t) => v.sync(() => {
|
|
1602
|
-
e.delete(t);
|
|
1603
|
-
}),
|
|
1604
|
-
getById: (t) => v.sync(() => e.get(t) ?? null),
|
|
1605
|
-
listByRef: (t) => v.sync(() => [...e.values()].filter((e) => e.refId === t)),
|
|
1606
|
-
deleteByRef: (t) => v.sync(() => {
|
|
1607
|
-
for (let [n, r] of e) r.refId === t && e.delete(n);
|
|
1608
|
-
})
|
|
1609
|
-
};
|
|
1610
|
-
}, dn = (e) => ({
|
|
1611
|
-
id: String(e.id),
|
|
1612
|
-
refId: String(e.refId),
|
|
1613
|
-
principalType: e.principalType,
|
|
1614
|
-
principalId: String(e.principalId),
|
|
1615
|
-
permission: e.permission === "write" ? "write" : "read",
|
|
1616
|
-
createdAt: e.createdAt instanceof Date ? e.createdAt : new Date(String(e.createdAt)),
|
|
1617
|
-
expiresAt: e.expiresAt ? e.expiresAt instanceof Date ? e.expiresAt : new Date(String(e.expiresAt)) : null,
|
|
1618
|
-
createdBy: e.createdBy ?? null
|
|
1619
|
-
}), fn = (e) => ({
|
|
1620
|
-
insert: (t) => Z(() => e.insert(V, { ...t })),
|
|
1621
|
-
delete: (t) => Z(() => e.delete(V, t)),
|
|
1622
|
-
getById: (t) => Z(async () => {
|
|
1623
|
-
let n = (await e.query({
|
|
1624
|
-
table: V,
|
|
1625
|
-
predicate: {
|
|
1626
|
-
column: "id",
|
|
1627
|
-
op: "eq",
|
|
1628
|
-
value: t
|
|
1629
|
-
},
|
|
1630
|
-
order: [],
|
|
1631
|
-
take: 1,
|
|
1632
|
-
skip: void 0,
|
|
1633
|
-
projection: void 0
|
|
1634
|
-
}))[0];
|
|
1635
|
-
return n ? dn(n) : null;
|
|
1636
|
-
}),
|
|
1637
|
-
listByRef: (t) => Z(async () => (await e.query({
|
|
1638
|
-
table: V,
|
|
1639
|
-
predicate: {
|
|
1640
|
-
column: "refId",
|
|
1641
|
-
op: "eq",
|
|
1642
|
-
value: t
|
|
1643
|
-
},
|
|
1644
|
-
order: [{
|
|
1645
|
-
column: "createdAt",
|
|
1646
|
-
direction: "desc"
|
|
1647
|
-
}],
|
|
1648
|
-
take: void 0,
|
|
1649
|
-
skip: void 0,
|
|
1650
|
-
projection: void 0
|
|
1651
|
-
})).map(dn)),
|
|
1652
|
-
deleteByRef: (t) => Z(async () => {
|
|
1653
|
-
let n = await e.query({
|
|
1654
|
-
table: V,
|
|
1655
|
-
predicate: {
|
|
1656
|
-
column: "refId",
|
|
1657
|
-
op: "eq",
|
|
1658
|
-
value: t
|
|
1659
|
-
},
|
|
1660
|
-
order: [],
|
|
1661
|
-
take: void 0,
|
|
1662
|
-
skip: void 0,
|
|
1663
|
-
projection: void 0
|
|
1664
|
-
});
|
|
1665
|
-
for (let t of n) await e.delete(V, String(t.id));
|
|
1666
|
-
})
|
|
1667
|
-
}), pn = () => A({
|
|
1668
|
-
kind: "typeid",
|
|
1669
|
-
prefix: "file"
|
|
1670
|
-
}, B), mn = () => A({
|
|
1671
|
-
kind: "typeid",
|
|
1672
|
-
prefix: "grant"
|
|
1673
|
-
}, V), hn = (i) => {
|
|
1674
|
-
let { provider: a, refStore: o, grantStore: s, bucket: c } = i, l = i.access ?? {}, u = i.attempts ?? 3, d = i.urlExpiresInSec ?? 3600, f = (e) => tn(i.publicBaseUrl, e, i.httpPath ?? "/_voltro/storage"), p = x.max([x.recurs(Math.max(0, u - 1)), x.exponential("100 millis")]).pipe(x.while(({ input: e }) => e.transient)), m = (e, t, n) => [
|
|
1675
|
-
i.tenantPrefix,
|
|
1676
|
-
e ?? "global",
|
|
1677
|
-
n ?? t
|
|
1678
|
-
].filter(Boolean).join("/"), ee = (e) => {
|
|
1679
|
-
if (e === void 0) return v.succeed(void 0);
|
|
1680
|
-
let n = e.length === 0 ? "empty" : e.includes("\0") ? "contains NUL" : e.startsWith("/") || e.startsWith("\\") ? "starts with a path separator" : e.includes("\\") ? "contains a backslash" : e.split("/").some((e) => e === "" || e === "." || e === "..") ? "contains an empty, \".\" or \"..\" segment" : void 0;
|
|
1681
|
-
return n === void 0 ? v.succeed(e) : v.fail(new t({
|
|
1682
|
-
provider: a.name,
|
|
1683
|
-
message: `storage key rejected: ${n}`,
|
|
1684
|
-
transient: !1,
|
|
1685
|
-
status: 400
|
|
1686
|
-
}));
|
|
1687
|
-
}, te = (e, t, n) => [
|
|
1688
|
-
i.tenantPrefix,
|
|
1689
|
-
e ?? "global",
|
|
1690
|
-
"_incoming",
|
|
1691
|
-
t,
|
|
1692
|
-
String(n).padStart(6, "0")
|
|
1693
|
-
].filter(Boolean).join("/"), ne = (e, t) => t === void 0 || e.tenantId === t, h = (e, n) => ne(e, n) ? v.succeed(e) : v.fail(new t({
|
|
1694
|
-
provider: a.name,
|
|
1695
|
-
message: "cross-tenant access denied",
|
|
1696
|
-
transient: !1,
|
|
1697
|
-
status: 403
|
|
1698
|
-
})), g = (e, n, r) => v.gen(function* () {
|
|
1699
|
-
let o = i.objects?.(), s = (e) => new t({
|
|
1700
|
-
provider: "metadata",
|
|
1701
|
-
message: e,
|
|
1702
|
-
transient: !1,
|
|
1703
|
-
status: 409
|
|
1704
|
-
});
|
|
1705
|
-
if (o === void 0) return r === void 0 ? !1 : yield* v.fail(s(`claim '${r}' cannot be released: no data store is bound, so ref '${e}' holds no claims`));
|
|
1706
|
-
let c = yield* v.tryPromise({
|
|
1707
|
-
try: () => o.intent(e),
|
|
1708
|
-
catch: (e) => new t({
|
|
1709
|
-
provider: "metadata",
|
|
1710
|
-
message: String(e?.message ?? e),
|
|
1711
|
-
transient: !1
|
|
1712
|
-
})
|
|
1713
|
-
});
|
|
1714
|
-
return c === void 0 ? r === void 0 ? !1 : yield* v.fail(s(`claim '${r}' cannot be released: ref '${e}' was not written through an operation and holds no claims`)) : (yield* h(c.ref, n), yield* $t({
|
|
1715
|
-
metadata: o,
|
|
1716
|
-
provider: {
|
|
1717
|
-
...a,
|
|
1718
|
-
delete: (e) => a.delete(e).pipe(v.retry(p))
|
|
1719
|
-
}
|
|
1720
|
-
}).delete(e, n, r).pipe(v.catchTag("StorageRejected", (e) => v.fail(e.reason === "claim-not-held" ? s(e.detail) : new t({
|
|
1721
|
-
provider: "metadata",
|
|
1722
|
-
message: e.detail,
|
|
1723
|
-
transient: !1
|
|
1724
|
-
})))), !0);
|
|
1725
|
-
}), _ = (e, n) => o.getById(e).pipe(v.flatMap((r) => r ? h(r, n) : v.fail(new t({
|
|
1726
|
-
provider: a.name,
|
|
1727
|
-
message: `no ref '${e}'`,
|
|
1728
|
-
transient: !1,
|
|
1729
|
-
status: 404
|
|
1730
|
-
})))), re = (e) => v.suspend(() => {
|
|
1731
|
-
let n = i.scan(e);
|
|
1732
|
-
return v.isEffect(n) ? n : v.tryPromise({
|
|
1733
|
-
try: () => Promise.resolve(n),
|
|
1734
|
-
catch: (e) => new t({
|
|
1735
|
-
provider: "scan",
|
|
1736
|
-
message: String(e?.message ?? e),
|
|
1737
|
-
transient: !0
|
|
1738
|
-
})
|
|
1739
|
-
});
|
|
1740
|
-
}), ie = (e) => v.suspend(() => {
|
|
1741
|
-
let t = e.contentType;
|
|
1742
|
-
if (!i.videoProbe || !(t.startsWith("video/") || t.startsWith("audio/"))) return v.succeed(null);
|
|
1743
|
-
let n;
|
|
1744
|
-
try {
|
|
1745
|
-
n = i.videoProbe(e);
|
|
1746
|
-
} catch {
|
|
1747
|
-
return v.succeed(null);
|
|
1748
|
-
}
|
|
1749
|
-
return v.isEffect(n) ? n.pipe(v.catch(() => v.succeed(null))) : v.tryPromise({
|
|
1750
|
-
try: () => Promise.resolve(n),
|
|
1751
|
-
catch: () => null
|
|
1752
|
-
}).pipe(v.catch(() => v.succeed(null)));
|
|
1753
|
-
}), b = (e) => v.gen(function* () {
|
|
1754
|
-
let t = Kt(e.bytes, e.contentType, i.limits);
|
|
1755
|
-
if (t) return yield* v.fail(new n(t));
|
|
1756
|
-
if (e.claim !== void 0 && e.operationId === void 0) return yield* v.fail(new n({
|
|
1757
|
-
reason: "claim-without-operation",
|
|
1758
|
-
detail: "a put with a claim needs an operationId; the claim names this caller's hold on that operation's object"
|
|
1759
|
-
}));
|
|
1760
|
-
if (i.scan) {
|
|
1761
|
-
let t = yield* re({
|
|
1762
|
-
bytes: e.bytes,
|
|
1763
|
-
contentType: e.contentType,
|
|
1764
|
-
...e.key ? { key: e.key } : {}
|
|
1765
|
-
});
|
|
1766
|
-
if (!t.clean) return yield* v.fail(new r({ threat: t.threat ?? "unknown" }));
|
|
1767
|
-
}
|
|
1768
|
-
let s = yield* v.promise(() => qt(e.bytes, e.contentType, { normalize: i.normalizeImages ?? !1 })), l = s.bytes, u = yield* ie({
|
|
1769
|
-
bytes: l,
|
|
1770
|
-
contentType: e.contentType
|
|
1771
|
-
}), d = s.width ?? u?.width, f = s.height ?? u?.height, te = s.placeholder ?? u?.poster, ne = e.duration ?? u?.duration, h = yield* v.promise(() => en(l)), g = e.tenantId ?? null, _ = e.visibility ?? "private", b = m(g, h, yield* ee(e.key)), x = e.password ? yield* v.sync(() => yt(e.password)) : null, S = {
|
|
1772
|
-
id: pn(),
|
|
1773
|
-
tenantId: g,
|
|
1774
|
-
ownerId: e.ownerId ?? null,
|
|
1775
|
-
bucket: c,
|
|
1776
|
-
key: b,
|
|
1777
|
-
contentType: e.contentType,
|
|
1778
|
-
size: l.byteLength,
|
|
1779
|
-
checksum: h,
|
|
1780
|
-
visibility: _,
|
|
1781
|
-
accessPolicy: e.access ?? null,
|
|
1782
|
-
passwordHash: x,
|
|
1783
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
1784
|
-
...d === void 0 ? {} : { width: d },
|
|
1785
|
-
...f === void 0 ? {} : { height: f },
|
|
1786
|
-
...te === void 0 ? {} : { placeholder: te },
|
|
1787
|
-
...ne === void 0 ? {} : { duration: ne },
|
|
1788
|
-
...e.folder === void 0 ? {} : { folder: e.folder },
|
|
1789
|
-
...e.tags === void 0 ? {} : { tags: e.tags },
|
|
1790
|
-
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
1791
|
-
...e.caption === void 0 ? {} : { caption: e.caption },
|
|
1792
|
-
...e.derivedFrom === void 0 ? {} : { derivedFrom: e.derivedFrom },
|
|
1793
|
-
...e.kind === void 0 ? {} : { kind: e.kind }
|
|
1794
|
-
}, C = i.transcode !== void 0 && i.autoTranscode !== !1, oe = (t) => C && t.derivedFrom == null && (e.contentType.startsWith("video/") || e.contentType.startsWith("audio/")) ? v.forkDetach(ae(t).pipe(v.ignore)) : v.void;
|
|
1795
|
-
if (e.operationId !== void 0) {
|
|
1796
|
-
let t = i.objects?.();
|
|
1797
|
-
if (t === void 0) return yield* v.fail(new n({
|
|
1798
|
-
reason: "operation-store-unbound",
|
|
1799
|
-
detail: "a put with an operationId needs a bound data store; the in-memory ref store cannot hold operation intents"
|
|
1800
|
-
}));
|
|
1801
|
-
let r = {
|
|
1802
|
-
tenantId: g,
|
|
1803
|
-
bucket: c,
|
|
1804
|
-
operationId: e.operationId,
|
|
1805
|
-
checksum: h,
|
|
1806
|
-
logicalKey: b,
|
|
1807
|
-
fingerprint: yield* v.promise(() => en(new TextEncoder().encode(JSON.stringify([
|
|
1808
|
-
h,
|
|
1809
|
-
e.contentType,
|
|
1810
|
-
_,
|
|
1811
|
-
e.access ?? null,
|
|
1812
|
-
e.key ?? null,
|
|
1813
|
-
e.ownerId ?? null,
|
|
1814
|
-
e.folder ?? null,
|
|
1815
|
-
e.tags ?? null,
|
|
1816
|
-
e.alt ?? null,
|
|
1817
|
-
e.caption ?? null,
|
|
1818
|
-
e.derivedFrom ?? null,
|
|
1819
|
-
e.kind ?? null,
|
|
1820
|
-
ne ?? null,
|
|
1821
|
-
e.password !== void 0
|
|
1822
|
-
]))))
|
|
1823
|
-
}, o = yield* $t({
|
|
1824
|
-
metadata: t,
|
|
1825
|
-
provider: {
|
|
1826
|
-
...a,
|
|
1827
|
-
put: (e, t, n) => a.put(e, t, n).pipe(v.retry(p))
|
|
1828
|
-
}
|
|
1829
|
-
}).put({
|
|
1830
|
-
identity: r,
|
|
1831
|
-
ref: S,
|
|
1832
|
-
bytes: l,
|
|
1833
|
-
...i.quota === void 0 ? {} : { quota: i.quota },
|
|
1834
|
-
...e.claim === void 0 ? {} : { claim: e.claim }
|
|
1835
|
-
});
|
|
1836
|
-
return yield* oe(o.ref), {
|
|
1837
|
-
...o.ref,
|
|
1838
|
-
outcome: o.outcome
|
|
1839
|
-
};
|
|
1840
|
-
}
|
|
1841
|
-
let w = {
|
|
1842
|
-
bytes: l.byteLength,
|
|
1843
|
-
count: 1
|
|
1844
|
-
}, se = yield* o.consumeUsage(g, w, i.quota);
|
|
1845
|
-
if (!se.allowed) {
|
|
1846
|
-
let e = i.quota ?? {}, t = e.maxCount !== void 0 && se.count + 1 > e.maxCount ? `tenant object count ${se.count} + 1 exceeds max ${e.maxCount}` : `tenant usage ${se.bytes} + ${l.byteLength} bytes exceeds max ${e.maxBytes}`;
|
|
1847
|
-
return yield* v.fail(new n({
|
|
1848
|
-
reason: "quota-exceeded",
|
|
1849
|
-
detail: t
|
|
1850
|
-
}));
|
|
1851
|
-
}
|
|
1852
|
-
return yield* ((e) => e.pipe(v.onExit((e) => y.isSuccess(e) ? v.void : o.delete(S.id).pipe(v.andThen(o.releaseUsage(g, w)), v.ignore))))(o.insert(S).pipe(v.andThen(a.put(b, l, {
|
|
1853
|
-
contentType: e.contentType,
|
|
1854
|
-
public: _ === "public"
|
|
1855
|
-
}).pipe(v.retry(p))))), yield* oe(S), {
|
|
1856
|
-
...S,
|
|
1857
|
-
outcome: "created"
|
|
1858
|
-
};
|
|
1859
|
-
}), S = (e) => v.suspend(() => {
|
|
1860
|
-
if (!i.transcode) return v.succeed([]);
|
|
1861
|
-
let t;
|
|
1862
|
-
try {
|
|
1863
|
-
t = i.transcode(e);
|
|
1864
|
-
} catch {
|
|
1865
|
-
return v.succeed([]);
|
|
1866
|
-
}
|
|
1867
|
-
return v.isEffect(t) ? t.pipe(v.catch(() => v.succeed([]))) : v.tryPromise({
|
|
1868
|
-
try: () => Promise.resolve(t),
|
|
1869
|
-
catch: () => []
|
|
1870
|
-
}).pipe(v.catch(() => v.succeed([])));
|
|
1871
|
-
}), ae = (e) => v.gen(function* () {
|
|
1872
|
-
if (!i.transcode || e.derivedFrom != null) return [];
|
|
1873
|
-
let t = yield* a.get(e.key).pipe(v.retry(p)), n = yield* S({
|
|
1874
|
-
bytes: t.bytes,
|
|
1875
|
-
contentType: e.contentType,
|
|
1876
|
-
ref: e
|
|
1877
|
-
}), r = [];
|
|
1878
|
-
for (let t of n) {
|
|
1879
|
-
let n = yield* b({
|
|
1880
|
-
bytes: t.bytes,
|
|
1881
|
-
contentType: t.contentType,
|
|
1882
|
-
tenantId: e.tenantId,
|
|
1883
|
-
ownerId: e.ownerId,
|
|
1884
|
-
visibility: e.visibility,
|
|
1885
|
-
derivedFrom: e.id,
|
|
1886
|
-
kind: t.kind,
|
|
1887
|
-
...t.label === void 0 ? {} : { caption: t.label }
|
|
1888
|
-
});
|
|
1889
|
-
r.push(n);
|
|
1890
|
-
}
|
|
1891
|
-
return r;
|
|
1892
|
-
}), oe = (e, t, n) => v.gen(function* () {
|
|
1893
|
-
if (e.derivedFrom != null) {
|
|
1894
|
-
let r = yield* o.getById(e.derivedFrom);
|
|
1895
|
-
return r === null ? !1 : yield* oe(r, t, n);
|
|
1896
|
-
}
|
|
1897
|
-
if (e.visibility === "public") return !0;
|
|
1898
|
-
if (e.tenantId !== null && !ne(e, t.tenantId ?? null)) return !1;
|
|
1899
|
-
if (yield* Dt(e, t, {
|
|
1900
|
-
...l,
|
|
1901
|
-
...n?.password === void 0 ? {} : { password: n.password }
|
|
1902
|
-
})) return !0;
|
|
1903
|
-
let r = yield* jt(t, l);
|
|
1904
|
-
return At(yield* s.listByRef(e.id), t, r, n?.permission ?? "read", Date.now());
|
|
1905
|
-
}), w = (e) => {
|
|
1906
|
-
if (e.visibility === "public") {
|
|
1907
|
-
let t = a.publicUrl?.(e.key);
|
|
1908
|
-
if (t != null) return t;
|
|
1909
|
-
}
|
|
1910
|
-
return f(e.id);
|
|
1911
|
-
};
|
|
1912
|
-
return {
|
|
1913
|
-
put: b,
|
|
1914
|
-
get: (e, t) => _(e, t?.tenantId).pipe(v.flatMap((e) => a.get(e.key).pipe(v.retry(p), v.map((t) => ({
|
|
1915
|
-
bytes: t.bytes,
|
|
1916
|
-
ref: e
|
|
1917
|
-
}))))),
|
|
1918
|
-
getStream: (e, t) => _(e, t?.tenantId).pipe(v.map((e) => ({
|
|
1919
|
-
ref: e,
|
|
1920
|
-
stream: C.unwrap(v.suspend(() => a.getStream ? a.getStream(e.key).pipe(v.retry(p), v.map((e) => e.stream)) : a.get(e.key).pipe(v.retry(p), v.map((e) => C.make(e.bytes)))))
|
|
1921
|
-
}))),
|
|
1922
|
-
getRange: (e, n, r) => _(e, r?.tenantId).pipe(v.flatMap((e) => {
|
|
1923
|
-
let r = e.size, i = Math.max(0, Math.trunc(n.start));
|
|
1924
|
-
if (r > 0 && i >= r) return v.fail(new t({
|
|
1925
|
-
provider: a.name,
|
|
1926
|
-
message: `range start ${i} past end ${r}`,
|
|
1927
|
-
transient: !1,
|
|
1928
|
-
status: 416
|
|
1929
|
-
}));
|
|
1930
|
-
let o = Math.min(Math.trunc(n.endInclusive), Math.max(0, r - 1));
|
|
1931
|
-
return o < i ? v.fail(new t({
|
|
1932
|
-
provider: a.name,
|
|
1933
|
-
message: `empty range ${i}-${o}`,
|
|
1934
|
-
transient: !1,
|
|
1935
|
-
status: 416
|
|
1936
|
-
})) : (a.getRange ? a.getRange(e.key, i, o).pipe(v.retry(p)) : a.get(e.key).pipe(v.retry(p), v.map((e) => e.bytes.subarray(i, o + 1)))).pipe(v.map((t) => ({
|
|
1937
|
-
bytes: t,
|
|
1938
|
-
ref: e,
|
|
1939
|
-
totalSize: r
|
|
1940
|
-
})));
|
|
1941
|
-
})),
|
|
1942
|
-
getUrl: (e, t) => _(e, t?.tenantId).pipe(v.flatMap((e) => e.visibility === "public" ? v.succeed(w(e)) : a.presigns ? a.getUrl(e.key, t?.expiresInSec ?? d) : v.succeed(f(e.id)))),
|
|
1943
|
-
head: (e, t) => o.getById(e).pipe(v.flatMap((e) => e ? h(e, t?.tenantId).pipe(v.map((e) => e)) : v.succeed(null))),
|
|
1944
|
-
delete: (e, t) => g(e, t?.tenantId, t?.claim).pipe(v.flatMap((n) => n ? v.void : _(e, t?.tenantId).pipe(v.flatMap((t) => s.deleteByRef(e).pipe(v.flatMap(() => o.delete(e)), v.flatMap((e) => e ? o.countByKey(t.bucket, t.key).pipe(v.flatMap((e) => e === 0 ? a.delete(t.key).pipe(v.retry(p)) : v.void), v.flatMap(() => o.releaseUsage(t.tenantId, {
|
|
1945
|
-
bytes: t.size,
|
|
1946
|
-
count: 1
|
|
1947
|
-
}))) : v.void), v.asVoid))))),
|
|
1948
|
-
signedUrl: (e, t) => _(e, t?.tenantId).pipe(v.flatMap((e) => {
|
|
1949
|
-
if (e.visibility === "public") return v.succeed(w(e));
|
|
1950
|
-
let n = t?.expiresInSec ?? d;
|
|
1951
|
-
return a.presigns ? a.getUrl(e.key, n) : v.sync(() => `${f(e.id)}?t=${Mt(e.id, n, void 0, i.httpPath ?? "/_voltro/storage")}`);
|
|
1952
|
-
})),
|
|
1953
|
-
setVisibility: (e, r, i) => v.gen(function* () {
|
|
1954
|
-
let s = yield* _(e, i?.tenantId);
|
|
1955
|
-
if (s.visibility === r) return s;
|
|
1956
|
-
let c = o.setVisibility;
|
|
1957
|
-
if (c === void 0) return yield* v.fail(new n({
|
|
1958
|
-
reason: "visibility-unsupported",
|
|
1959
|
-
detail: "the ref store cannot change a stored object's visibility"
|
|
1960
|
-
}));
|
|
1961
|
-
if (r === "private" && a.publicUrl?.(s.key) != null) return yield* v.fail(new n({
|
|
1962
|
-
reason: "visibility-unsupported",
|
|
1963
|
-
detail: `objects are served from a public base (${a.name} cdnBaseUrl); a public object cannot be made private there`
|
|
1964
|
-
}));
|
|
1965
|
-
if (r === "private" && a.setObjectPublic !== void 0 && o.countPublicByKey === void 0) return yield* v.fail(new n({
|
|
1966
|
-
reason: "visibility-unsupported",
|
|
1967
|
-
detail: "the ref store cannot tell whether other refs keep these bytes public"
|
|
1968
|
-
}));
|
|
1969
|
-
let l = yield* c(s.id, r);
|
|
1970
|
-
if (l === null) return yield* v.fail(new t({
|
|
1971
|
-
provider: a.name,
|
|
1972
|
-
message: `no ref '${e}'`,
|
|
1973
|
-
transient: !1,
|
|
1974
|
-
status: 404
|
|
1975
|
-
}));
|
|
1976
|
-
let u = s.derivedFrom == null ? yield* o.listByDerivedFrom(s.id) : [];
|
|
1977
|
-
for (let e of u) e.visibility !== r && (yield* c(e.id, r));
|
|
1978
|
-
if (a.setObjectPublic !== void 0) {
|
|
1979
|
-
let e = o.countPublicByKey;
|
|
1980
|
-
for (let t of [s, ...u]) {
|
|
1981
|
-
let n = r === "public" || e !== void 0 && (yield* e(t.bucket, t.key)) > 0;
|
|
1982
|
-
yield* a.setObjectPublic(t.key, n);
|
|
1983
|
-
}
|
|
1984
|
-
}
|
|
1985
|
-
return l;
|
|
1986
|
-
}),
|
|
1987
|
-
mintUrl: (n, r, s) => v.gen(function* () {
|
|
1988
|
-
let c = yield* o.getById(n).pipe(v.flatMap((e) => e ? v.succeed(e) : v.fail(new t({
|
|
1989
|
-
provider: a.name,
|
|
1990
|
-
message: `no ref '${n}'`,
|
|
1991
|
-
transient: !1,
|
|
1992
|
-
status: 404
|
|
1993
|
-
}))));
|
|
1994
|
-
if (c.visibility === "public" && c.derivedFrom == null) return w(c);
|
|
1995
|
-
if (!(yield* oe(c, r, s?.password === void 0 ? {} : { password: s.password }))) return yield* v.fail(new e({
|
|
1996
|
-
refId: n,
|
|
1997
|
-
reason: "access denied"
|
|
1998
|
-
}));
|
|
1999
|
-
let l = s?.expiresInSec ?? d;
|
|
2000
|
-
if (a.presigns) return yield* a.getUrl(c.key, l);
|
|
2001
|
-
let u = yield* v.sync(() => Mt(c.id, l, void 0, i.httpPath ?? "/_voltro/storage"));
|
|
2002
|
-
return `${f(c.id)}?t=${u}`;
|
|
2003
|
-
}),
|
|
2004
|
-
mintUploadUrl: (e) => v.gen(function* () {
|
|
2005
|
-
if (!a.getUploadUrl) return yield* v.fail(new t({
|
|
2006
|
-
provider: a.name,
|
|
2007
|
-
message: `provider '${a.name}' does not support presigned uploads`,
|
|
2008
|
-
transient: !1,
|
|
2009
|
-
status: 400
|
|
2010
|
-
}));
|
|
2011
|
-
let n = m(e.tenantId ?? null, "", yield* ee(e.key));
|
|
2012
|
-
return yield* a.getUploadUrl(n, e.expiresInSec ?? d, e.contentType);
|
|
2013
|
-
}),
|
|
2014
|
-
checkAccess: oe,
|
|
2015
|
-
grant: (e) => v.gen(function* () {
|
|
2016
|
-
let t = {
|
|
2017
|
-
id: mn(),
|
|
2018
|
-
refId: e.refId,
|
|
2019
|
-
principalType: e.principalType,
|
|
2020
|
-
principalId: e.principalId,
|
|
2021
|
-
permission: e.permission ?? "read",
|
|
2022
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
2023
|
-
expiresAt: e.expiresAt ?? null,
|
|
2024
|
-
createdBy: e.createdBy ?? null
|
|
2025
|
-
};
|
|
2026
|
-
return yield* s.insert(t), t;
|
|
2027
|
-
}),
|
|
2028
|
-
listRefs: (e) => v.suspend(() => {
|
|
2029
|
-
let t = Math.min(500, Math.max(1, Math.trunc(e?.limit ?? 50))), n = Math.max(0, Math.trunc(e?.offset ?? 0)), r = {
|
|
2030
|
-
tenantId: e && "tenantId" in e ? e.tenantId : void 0,
|
|
2031
|
-
folder: e?.folder,
|
|
2032
|
-
tags: e?.tags ?? [],
|
|
2033
|
-
ownerId: e?.ownerId,
|
|
2034
|
-
includeDerived: e?.includeDerived ?? !1,
|
|
2035
|
-
limit: t + 1,
|
|
2036
|
-
offset: n
|
|
2037
|
-
};
|
|
2038
|
-
return o.listRefs(r).pipe(v.map((e) => {
|
|
2039
|
-
let r = e.length > t;
|
|
2040
|
-
return {
|
|
2041
|
-
refs: r ? e.slice(0, t) : e,
|
|
2042
|
-
nextOffset: r ? n + t : null
|
|
2043
|
-
};
|
|
2044
|
-
}));
|
|
2045
|
-
}),
|
|
2046
|
-
revoke: (e) => s.delete(e),
|
|
2047
|
-
getGrant: (e) => s.getById(e),
|
|
2048
|
-
listGrants: (e) => s.listByRef(e),
|
|
2049
|
-
usage: (e) => o.usageByTenant(e),
|
|
2050
|
-
sweepOrphans: (e) => v.gen(function* () {
|
|
2051
|
-
let t = e?.limit ?? 1e3, n = e?.dryRun ?? !1, r = yield* o.listRecent(t), i = [];
|
|
2052
|
-
for (let e of r) if ((yield* a.head(e.key)) === null) {
|
|
2053
|
-
if (!n) {
|
|
2054
|
-
if (!(yield* o.delete(e.id))) continue;
|
|
2055
|
-
yield* o.releaseUsage(e.tenantId, {
|
|
2056
|
-
bytes: e.size,
|
|
2057
|
-
count: 1
|
|
2058
|
-
});
|
|
2059
|
-
}
|
|
2060
|
-
i.push(e.id);
|
|
2061
|
-
}
|
|
2062
|
-
return {
|
|
2063
|
-
scanned: r.length,
|
|
2064
|
-
removed: i
|
|
2065
|
-
};
|
|
2066
|
-
}),
|
|
2067
|
-
ingestUrl: (e, t) => Qt(v.gen(function* () {
|
|
2068
|
-
let n = yield* Zt(e, i.limits?.maxBytes, i.ingest);
|
|
2069
|
-
return yield* b({
|
|
2070
|
-
bytes: n.bytes,
|
|
2071
|
-
contentType: t?.contentType ?? n.contentType,
|
|
2072
|
-
...t?.tenantId === void 0 ? {} : { tenantId: t.tenantId },
|
|
2073
|
-
...t?.operationId === void 0 ? {} : { operationId: t.operationId },
|
|
2074
|
-
...t?.ownerId === void 0 ? {} : { ownerId: t.ownerId },
|
|
2075
|
-
...t?.visibility === void 0 ? {} : { visibility: t.visibility },
|
|
2076
|
-
...t?.access === void 0 ? {} : { access: t.access },
|
|
2077
|
-
...t?.key === void 0 ? {} : { key: t.key },
|
|
2078
|
-
...t?.folder === void 0 ? {} : { folder: t.folder },
|
|
2079
|
-
...t?.tags === void 0 ? {} : { tags: t.tags },
|
|
2080
|
-
...t?.alt === void 0 ? {} : { alt: t.alt },
|
|
2081
|
-
...t?.caption === void 0 ? {} : { caption: t.caption }
|
|
2082
|
-
});
|
|
2083
|
-
}), t?.abortSignal),
|
|
2084
|
-
mintPresignedUpload: (e) => v.gen(function* () {
|
|
2085
|
-
if (!a.getUploadUrl) return yield* v.fail(new t({
|
|
2086
|
-
provider: a.name,
|
|
2087
|
-
message: `provider '${a.name}' does not support presigned uploads`,
|
|
2088
|
-
transient: !1,
|
|
2089
|
-
status: 400
|
|
2090
|
-
}));
|
|
2091
|
-
let n = e.expiresInSec ?? d, r = `_incoming/${A({
|
|
2092
|
-
kind: "typeid",
|
|
2093
|
-
prefix: "up"
|
|
2094
|
-
}, B)}`, i = m(e.tenantId ?? null, "", r);
|
|
2095
|
-
return {
|
|
2096
|
-
uploadUrl: yield* a.getUploadUrl(i, n, e.contentType),
|
|
2097
|
-
key: i,
|
|
2098
|
-
expiresInSec: n
|
|
2099
|
-
};
|
|
2100
|
-
}),
|
|
2101
|
-
finalizeUpload: (e) => a.get(e.key).pipe(v.retry(p), v.flatMap((t) => b({
|
|
2102
|
-
bytes: t.bytes,
|
|
2103
|
-
contentType: e.contentType,
|
|
2104
|
-
...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
|
|
2105
|
-
...e.ownerId === void 0 ? {} : { ownerId: e.ownerId },
|
|
2106
|
-
...e.visibility === void 0 ? {} : { visibility: e.visibility },
|
|
2107
|
-
...e.access === void 0 ? {} : { access: e.access },
|
|
2108
|
-
...e.folder === void 0 ? {} : { folder: e.folder },
|
|
2109
|
-
...e.tags === void 0 ? {} : { tags: e.tags },
|
|
2110
|
-
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
2111
|
-
...e.caption === void 0 ? {} : { caption: e.caption }
|
|
2112
|
-
})), v.ensuring(a.delete(e.key).pipe(v.retry(p), v.ignore))),
|
|
2113
|
-
putResumableChunk: (e) => a.put(te(e.tenantId ?? null, e.uploadId, e.index), e.bytes, { contentType: "application/octet-stream" }).pipe(v.retry(p), v.asVoid),
|
|
2114
|
-
resumableStatus: (e) => v.gen(function* () {
|
|
2115
|
-
let t = 0, n = 0;
|
|
2116
|
-
for (; t < 1e6;) {
|
|
2117
|
-
let r = yield* a.head(te(e.tenantId ?? null, e.uploadId, t)).pipe(v.retry(p), v.catch(() => v.succeed(null)));
|
|
2118
|
-
if (r === null) break;
|
|
2119
|
-
n += r.size, t += 1;
|
|
2120
|
-
}
|
|
2121
|
-
return {
|
|
2122
|
-
offset: n,
|
|
2123
|
-
nextIndex: t
|
|
2124
|
-
};
|
|
2125
|
-
}),
|
|
2126
|
-
finalizeResumable: (e) => v.gen(function* () {
|
|
2127
|
-
let r = i.limits?.maxBytes ?? 2 ** 53 - 1;
|
|
2128
|
-
if (!Number.isSafeInteger(r) || r < 0 || !Number.isSafeInteger(e.count) || e.count < 0) return yield* v.fail(new t({
|
|
2129
|
-
provider: a.name,
|
|
2130
|
-
message: "resumable count and limits.maxBytes must be non-negative safe integers",
|
|
2131
|
-
transient: !1,
|
|
2132
|
-
status: 400
|
|
2133
|
-
}));
|
|
2134
|
-
let o = (t) => te(e.tenantId ?? null, e.uploadId, t), s = v.gen(function* () {
|
|
2135
|
-
for (let t = 0; t < e.count; t++) yield* a.delete(o(t)).pipe(v.retry(p), v.ignore);
|
|
2136
|
-
}), c = () => new n({
|
|
2137
|
-
reason: "too-large",
|
|
2138
|
-
detail: `resumable upload exceeds ${r}-byte limit`
|
|
2139
|
-
}), l = yield* v.gen(function* () {
|
|
2140
|
-
let n = 0;
|
|
2141
|
-
for (let i = 0; i < e.count; i++) {
|
|
2142
|
-
let e = yield* a.head(o(i)).pipe(v.retry(p));
|
|
2143
|
-
if (e === null) return yield* v.fail(new t({
|
|
2144
|
-
provider: a.name,
|
|
2145
|
-
message: `no resumable chunk at '${o(i)}'`,
|
|
2146
|
-
transient: !1,
|
|
2147
|
-
status: 404
|
|
2148
|
-
}));
|
|
2149
|
-
if (!Number.isSafeInteger(e.size) || e.size < 0) return yield* v.fail(new t({
|
|
2150
|
-
provider: a.name,
|
|
2151
|
-
message: "resumable chunk metadata has an invalid size",
|
|
2152
|
-
transient: !1
|
|
2153
|
-
}));
|
|
2154
|
-
if (e.size > r - n) return yield* v.fail(c());
|
|
2155
|
-
n += e.size;
|
|
2156
|
-
}
|
|
2157
|
-
let i = /* @__PURE__ */ new Uint8Array(), s = 0;
|
|
2158
|
-
for (let t = 0; t < e.count; t++) {
|
|
2159
|
-
let e = yield* Ve(a, o(t)).pipe(v.retry(p));
|
|
2160
|
-
yield* C.runForEach(e.stream, (e) => v.gen(function* () {
|
|
2161
|
-
if (e.byteLength > r - s) return yield* v.fail(c());
|
|
2162
|
-
let t = s + e.byteLength;
|
|
2163
|
-
if (t > i.byteLength) {
|
|
2164
|
-
let e = new Uint8Array(Math.min(r, Math.max(65536, i.byteLength * 2, t)));
|
|
2165
|
-
e.set(i.subarray(0, s)), i = e;
|
|
2166
|
-
}
|
|
2167
|
-
i.set(e, s), s = t;
|
|
2168
|
-
}));
|
|
2169
|
-
}
|
|
2170
|
-
return i.subarray(0, s);
|
|
2171
|
-
}).pipe(v.tapError((e) => e._tag === "StorageRejected" ? s : v.void));
|
|
2172
|
-
return yield* b({
|
|
2173
|
-
bytes: l,
|
|
2174
|
-
contentType: e.contentType,
|
|
2175
|
-
...e.tenantId === void 0 ? {} : { tenantId: e.tenantId },
|
|
2176
|
-
...e.ownerId === void 0 ? {} : { ownerId: e.ownerId },
|
|
2177
|
-
...e.visibility === void 0 ? {} : { visibility: e.visibility },
|
|
2178
|
-
...e.access === void 0 ? {} : { access: e.access },
|
|
2179
|
-
...e.folder === void 0 ? {} : { folder: e.folder },
|
|
2180
|
-
...e.tags === void 0 ? {} : { tags: e.tags },
|
|
2181
|
-
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
2182
|
-
...e.caption === void 0 ? {} : { caption: e.caption }
|
|
2183
|
-
}).pipe(v.ensuring(s));
|
|
2184
|
-
}),
|
|
2185
|
-
transcode: (e, t) => _(e, t?.tenantId).pipe(v.flatMap((e) => ae(e))),
|
|
2186
|
-
renditions: (e, t) => _(e, t?.tenantId).pipe(v.flatMap(() => o.listByDerivedFrom(e))),
|
|
2187
|
-
beginMultipartUpload: (e) => v.gen(function* () {
|
|
2188
|
-
if (!a.createMultipartUpload || !a.presignUploadPart || !a.completeMultipartUpload) return yield* v.fail(new t({
|
|
2189
|
-
provider: a.name,
|
|
2190
|
-
message: `provider '${a.name}' does not support multipart uploads`,
|
|
2191
|
-
transient: !1,
|
|
2192
|
-
status: 400
|
|
2193
|
-
}));
|
|
2194
|
-
let n = m(e.tenantId ?? null, "", `multipart/${A({
|
|
2195
|
-
kind: "typeid",
|
|
2196
|
-
prefix: "mp"
|
|
2197
|
-
}, B)}`);
|
|
2198
|
-
return {
|
|
2199
|
-
uploadId: (yield* a.createMultipartUpload(n, e.contentType, { public: (e.visibility ?? "private") === "public" })).uploadId,
|
|
2200
|
-
key: n
|
|
2201
|
-
};
|
|
2202
|
-
}),
|
|
2203
|
-
signMultipartPart: (e) => v.suspend(() => a.presignUploadPart ? a.presignUploadPart(e.key, e.uploadId, e.partNumber, e.expiresInSec ?? d) : v.fail(new t({
|
|
2204
|
-
provider: a.name,
|
|
2205
|
-
message: "provider does not support multipart uploads",
|
|
2206
|
-
transient: !1,
|
|
2207
|
-
status: 400
|
|
2208
|
-
}))),
|
|
2209
|
-
completeMultipart: (e) => v.gen(function* () {
|
|
2210
|
-
if (!a.completeMultipartUpload) return yield* v.fail(new t({
|
|
2211
|
-
provider: a.name,
|
|
2212
|
-
message: "provider does not support multipart uploads",
|
|
2213
|
-
transient: !1,
|
|
2214
|
-
status: 400
|
|
2215
|
-
}));
|
|
2216
|
-
let r = yield* a.completeMultipartUpload(e.key, e.uploadId, e.parts), s = yield* a.head(e.key).pipe(v.retry(p)), l = s?.size ?? 0, u = (r.etag ?? s?.etag ?? "").replace(/"/g, ""), d = e.tenantId ?? null, f = {
|
|
2217
|
-
bytes: l,
|
|
2218
|
-
count: 1
|
|
2219
|
-
};
|
|
2220
|
-
if (!(yield* o.consumeUsage(d, f, i.quota)).allowed) return yield* a.delete(e.key).pipe(v.retry(p), v.ignore), yield* v.fail(new n({
|
|
2221
|
-
reason: "quota-exceeded",
|
|
2222
|
-
detail: `multipart upload of ${l} bytes exceeds tenant quota`
|
|
2223
|
-
}));
|
|
2224
|
-
let m = {
|
|
2225
|
-
id: pn(),
|
|
2226
|
-
tenantId: e.tenantId ?? null,
|
|
2227
|
-
ownerId: e.ownerId ?? null,
|
|
2228
|
-
bucket: c,
|
|
2229
|
-
key: e.key,
|
|
2230
|
-
contentType: e.contentType,
|
|
2231
|
-
size: l,
|
|
2232
|
-
checksum: u,
|
|
2233
|
-
visibility: e.visibility ?? "private",
|
|
2234
|
-
accessPolicy: e.access ?? null,
|
|
2235
|
-
passwordHash: null,
|
|
2236
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
2237
|
-
...e.folder === void 0 ? {} : { folder: e.folder },
|
|
2238
|
-
...e.tags === void 0 ? {} : { tags: e.tags },
|
|
2239
|
-
...e.alt === void 0 ? {} : { alt: e.alt },
|
|
2240
|
-
...e.caption === void 0 ? {} : { caption: e.caption }
|
|
2241
|
-
};
|
|
2242
|
-
return yield* o.insert(m).pipe(v.onExit((e) => y.isSuccess(e) ? v.void : o.releaseUsage(d, f).pipe(v.ignore))), m;
|
|
2243
|
-
}),
|
|
2244
|
-
abortMultipart: (e) => v.suspend(() => a.abortMultipartUpload ? a.abortMultipartUpload(e.key, e.uploadId).pipe(v.retry(p)) : v.void)
|
|
2245
|
-
};
|
|
2246
|
-
}, gn = (e) => b.succeed(i, hn(e)), _n = "_voltro_storage_operation_locks", Q = "_voltro_storage_object_heads", vn = "_voltro_storage_operations", yn = "_voltro_storage_object_claims", bn = [
|
|
2247
|
-
P(_n, {
|
|
2248
|
-
id: F().maxLength(64),
|
|
2249
|
-
nonce: F()
|
|
2250
|
-
}).primaryKey(["id"]).nonReactive(),
|
|
2251
|
-
P(Q, {
|
|
2252
|
-
id: F().maxLength(64),
|
|
2253
|
-
generation: F(),
|
|
2254
|
-
key: F(),
|
|
2255
|
-
reservations: E()
|
|
2256
|
-
}).primaryKey(["id"]).nonReactive(),
|
|
2257
|
-
P(vn, {
|
|
2258
|
-
id: F().maxLength(64),
|
|
2259
|
-
objectId: F().maxLength(64),
|
|
2260
|
-
fingerprint: F().maxLength(64),
|
|
2261
|
-
generation: F(),
|
|
2262
|
-
key: F(),
|
|
2263
|
-
refId: F(),
|
|
2264
|
-
state: F(),
|
|
2265
|
-
deleteKey: F().nullable()
|
|
2266
|
-
}).primaryKey(["id"]).nonReactive(),
|
|
2267
|
-
P(yn, {
|
|
2268
|
-
id: F().maxLength(64),
|
|
2269
|
-
operationId: F().maxLength(64),
|
|
2270
|
-
claim: F()
|
|
2271
|
-
}).primaryKey(["id"]).nonReactive()
|
|
2272
|
-
], xn = S.Struct({
|
|
2273
|
-
id: S.String,
|
|
2274
|
-
objectId: S.String,
|
|
2275
|
-
fingerprint: S.String,
|
|
2276
|
-
generation: S.String,
|
|
2277
|
-
key: S.String,
|
|
2278
|
-
refId: S.String,
|
|
2279
|
-
state: S.Literals([
|
|
2280
|
-
"reserved",
|
|
2281
|
-
"ready",
|
|
2282
|
-
"deleting",
|
|
2283
|
-
"deleted"
|
|
2284
|
-
]),
|
|
2285
|
-
deleteKey: S.NullOr(S.String)
|
|
2286
|
-
}), Sn = S.Struct({
|
|
2287
|
-
id: S.String,
|
|
2288
|
-
generation: S.String,
|
|
2289
|
-
key: S.String,
|
|
2290
|
-
reservations: S.Int.pipe(S.check(S.isGreaterThanOrEqualTo(0)))
|
|
2291
|
-
}), Cn = (e) => S.decodeUnknownSync(Sn)({
|
|
2292
|
-
...e,
|
|
2293
|
-
reservations: W(e.reservations, "shared-object reservation count")
|
|
2294
|
-
}), wn = (e) => Ce("sha256").update(JSON.stringify(e)).digest("hex"), Tn = (e, t) => wn([e, t]), En = (e) => {
|
|
2295
|
-
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");
|
|
2296
|
-
return {
|
|
2297
|
-
id: wn([
|
|
2298
|
-
e.bucket,
|
|
2299
|
-
e.tenantId,
|
|
2300
|
-
e.operationId
|
|
2301
|
-
]),
|
|
2302
|
-
objectId: wn([
|
|
2303
|
-
e.bucket,
|
|
2304
|
-
e.tenantId,
|
|
2305
|
-
e.logicalKey,
|
|
2306
|
-
e.checksum
|
|
2307
|
-
]),
|
|
2308
|
-
lockId: wn([e.tenantId])
|
|
2309
|
-
};
|
|
2310
|
-
}, Dn = async (e, t, n) => {
|
|
2311
|
-
let { lockId: r } = En(t);
|
|
2312
|
-
return await e.insertIgnoreWithOutcome(_n, {
|
|
2313
|
-
id: r,
|
|
2314
|
-
nonce: Te()
|
|
2315
|
-
}, { conflictColumns: ["id"] }), e.transactional(async (e) => {
|
|
2316
|
-
if ((await e.query({
|
|
2317
|
-
table: _n,
|
|
2318
|
-
predicate: k("id", r),
|
|
2319
|
-
lock: "update",
|
|
2320
|
-
order: [],
|
|
2321
|
-
take: 1,
|
|
2322
|
-
skip: void 0,
|
|
2323
|
-
projection: void 0
|
|
2324
|
-
})).length !== 1 || await e.update(_n, r, { nonce: Te() }) === null) throw Error("Storage operation lock is unavailable");
|
|
2325
|
-
return n(e);
|
|
2326
|
-
});
|
|
2327
|
-
}, $ = async (e, t) => {
|
|
2328
|
-
let r = En(t), i = await e.query({
|
|
2329
|
-
table: vn,
|
|
2330
|
-
predicate: k("id", r.id),
|
|
2331
|
-
order: [],
|
|
2332
|
-
take: 1,
|
|
2333
|
-
skip: void 0,
|
|
2334
|
-
projection: void 0
|
|
2335
|
-
});
|
|
2336
|
-
if (!i[0]) return;
|
|
2337
|
-
let a = S.decodeUnknownSync(xn)(i[0]);
|
|
2338
|
-
if (a.fingerprint !== t.fingerprint || a.objectId !== r.objectId) throw new n({
|
|
2339
|
-
reason: "operation-identity-reused",
|
|
2340
|
-
detail: `storage operation '${t.operationId}' was already used with different inputs`
|
|
2341
|
-
});
|
|
2342
|
-
return a;
|
|
2343
|
-
}, On = async (e, t) => {
|
|
2344
|
-
let n = await $(e, t);
|
|
2345
|
-
if (n) return n;
|
|
2346
|
-
let { id: r, objectId: i } = En(t), a = await e.query({
|
|
2347
|
-
table: Q,
|
|
2348
|
-
predicate: k("id", i),
|
|
2349
|
-
order: [],
|
|
2350
|
-
take: 1,
|
|
2351
|
-
skip: void 0,
|
|
2352
|
-
projection: void 0
|
|
2353
|
-
}), o = a[0] ? Cn(a[0]) : void 0, s = o?.generation ?? Te(), c = o?.key ?? `${t.logicalKey}/g-${s}`;
|
|
2354
|
-
o ? await e.update(Q, i, { reservations: String(Je(o.reservations, 1, "shared-object reservation count")) }) : await e.insert(Q, {
|
|
2355
|
-
id: i,
|
|
2356
|
-
generation: s,
|
|
2357
|
-
key: c,
|
|
2358
|
-
reservations: "1"
|
|
2359
|
-
});
|
|
2360
|
-
let l = {
|
|
2361
|
-
id: r,
|
|
2362
|
-
objectId: i,
|
|
2363
|
-
fingerprint: t.fingerprint,
|
|
2364
|
-
generation: s,
|
|
2365
|
-
key: c,
|
|
2366
|
-
refId: `file_${Te()}`,
|
|
2367
|
-
state: "reserved",
|
|
2368
|
-
deleteKey: null
|
|
2369
|
-
};
|
|
2370
|
-
return await e.insert(vn, l), l;
|
|
2371
|
-
}, kn = async (e, t) => {
|
|
2372
|
-
let n = await $(e, t);
|
|
2373
|
-
if (!n) throw Error("Storage operation is missing");
|
|
2374
|
-
if (n.state === "deleting" || n.state === "deleted") throw Error("Deleted storage operation cannot be confirmed by a late put");
|
|
2375
|
-
return await e.update(vn, n.id, { state: "ready" }), {
|
|
2376
|
-
...n,
|
|
2377
|
-
state: "ready"
|
|
2378
|
-
};
|
|
2379
|
-
}, An = async (e, t) => {
|
|
2380
|
-
let n = await $(e, t);
|
|
2381
|
-
if (!n) throw Error("Storage operation is missing");
|
|
2382
|
-
if (n.state === "deleting" || n.state === "deleted") return n;
|
|
2383
|
-
if (n.state !== "ready") throw Error("An unconfirmed put cannot be deleted");
|
|
2384
|
-
let r = await e.query({
|
|
2385
|
-
table: Q,
|
|
2386
|
-
predicate: k("id", n.objectId),
|
|
2387
|
-
order: [],
|
|
2388
|
-
take: 1,
|
|
2389
|
-
skip: void 0,
|
|
2390
|
-
projection: void 0
|
|
2391
|
-
}), i = r[0] ? Cn(r[0]) : void 0;
|
|
2392
|
-
if (!i || i.generation !== n.generation || i.reservations < 1) throw Error("Storage object generation does not own its reservation");
|
|
2393
|
-
let a = i.reservations === 1 ? i.key : null;
|
|
2394
|
-
return a === null ? await e.update(Q, i.id, { reservations: String(i.reservations - 1) }) : await e.delete(Q, i.id), await e.update(vn, n.id, {
|
|
2395
|
-
state: "deleting",
|
|
2396
|
-
deleteKey: a
|
|
2397
|
-
}), {
|
|
2398
|
-
...n,
|
|
2399
|
-
state: "deleting",
|
|
2400
|
-
deleteKey: a
|
|
2401
|
-
};
|
|
2402
|
-
}, jn = async (e, t) => {
|
|
2403
|
-
let n = await $(e, t);
|
|
2404
|
-
if (!n || n.state !== "deleting" && n.state !== "deleted") throw Error("Storage deletion has not been accepted");
|
|
2405
|
-
return n.state !== "deleted" && (await e.update(vn, n.id, { state: "deleted" }), !0);
|
|
2406
|
-
}, Mn = async (e, t, n) => {
|
|
2407
|
-
if (!n) throw Error("Storage object claim must be a non-empty string");
|
|
2408
|
-
await e.insertIgnoreWithOutcome(yn, {
|
|
2409
|
-
id: Tn(t, n),
|
|
2410
|
-
operationId: t,
|
|
2411
|
-
claim: n
|
|
2412
|
-
}, { conflictColumns: ["id"] });
|
|
2413
|
-
}, Nn = async (e, t, n) => {
|
|
2414
|
-
let r = Tn(t, n);
|
|
2415
|
-
return {
|
|
2416
|
-
held: await e.delete(yn, r),
|
|
2417
|
-
others: (await e.query({
|
|
2418
|
-
table: yn,
|
|
2419
|
-
predicate: ue(k("operationId", t), ve("claim", n)),
|
|
2420
|
-
order: [],
|
|
2421
|
-
take: 1,
|
|
2422
|
-
skip: void 0,
|
|
2423
|
-
projection: void 0
|
|
2424
|
-
})).length > 0
|
|
2425
|
-
};
|
|
2426
|
-
}, Pn = (e, t) => e.deleteMany(yn, { where: k("operationId", t) }), Fn = "_voltro_storage_put_intents", In = P(Fn, {
|
|
2427
|
-
id: F().maxLength(64),
|
|
2428
|
-
refId: F().maxLength(64),
|
|
2429
|
-
identity: ge(),
|
|
2430
|
-
ref: ge()
|
|
2431
|
-
}).primaryKey(["id"]).unique("storagePutRef", ["refId"]).nonReactive(), Ln = S.Struct({
|
|
2432
|
-
tenantId: S.NullOr(S.String),
|
|
2433
|
-
bucket: S.String,
|
|
2434
|
-
operationId: S.String,
|
|
2435
|
-
fingerprint: S.String,
|
|
2436
|
-
checksum: S.String,
|
|
2437
|
-
logicalKey: S.String
|
|
2438
|
-
}), Rn = async (e, t) => {
|
|
2439
|
-
let n = await e.query({
|
|
2440
|
-
table: Fn,
|
|
2441
|
-
predicate: k("refId", t),
|
|
2442
|
-
order: [],
|
|
2443
|
-
take: 2,
|
|
2444
|
-
skip: void 0,
|
|
2445
|
-
projection: void 0
|
|
2446
|
-
});
|
|
2447
|
-
if (n.length === 0) return;
|
|
2448
|
-
if (n.length !== 1) throw Error("Storage reference has ambiguous operation ownership");
|
|
2449
|
-
let r = n[0], i = S.decodeUnknownSync(Ln)(r.identity);
|
|
2450
|
-
if (typeof r.ref != "object" || r.ref === null || Array.isArray(r.ref)) throw Error("Storage operation reference is unreadable");
|
|
2451
|
-
let a = X(r.ref);
|
|
2452
|
-
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");
|
|
2453
|
-
return {
|
|
2454
|
-
identity: i,
|
|
2455
|
-
ref: a
|
|
2456
|
-
};
|
|
2457
|
-
}, zn = (e) => ({
|
|
2458
|
-
intent: (t) => Rn(e, t),
|
|
2459
|
-
reserve: (t, r, i, a) => Dn(e, t, async (e) => {
|
|
2460
|
-
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");
|
|
2461
|
-
let o = await $(e, t);
|
|
2462
|
-
if (o) {
|
|
2463
|
-
if (o.state === "deleting" || o.state === "deleted") throw Error("Storage put identity has already been deleted");
|
|
2464
|
-
let t = await Rn(e, o.refId);
|
|
2465
|
-
if (!t) throw Error("Storage operation lost its put intent");
|
|
2466
|
-
let n = o.state === "ready";
|
|
2467
|
-
return n && a !== void 0 && await Mn(e, o.id, a), {
|
|
2468
|
-
ref: t.ref,
|
|
2469
|
-
ready: n,
|
|
2470
|
-
outcome: n ? "joined" : "resumed"
|
|
2471
|
-
};
|
|
2472
|
-
}
|
|
2473
|
-
let s = await On(e, t), c = ln(e);
|
|
2474
|
-
if (!(await v.runPromise(c.consumeUsage(t.tenantId, {
|
|
2475
|
-
bytes: r.size,
|
|
2476
|
-
count: 1
|
|
2477
|
-
}, i))).allowed) throw new n({
|
|
2478
|
-
reason: "quota-exceeded",
|
|
2479
|
-
detail: "Storage operation exceeds tenant quota"
|
|
2480
|
-
});
|
|
2481
|
-
let l = X({
|
|
2482
|
-
...r,
|
|
2483
|
-
id: s.refId,
|
|
2484
|
-
key: s.key
|
|
2485
|
-
});
|
|
2486
|
-
return await e.insert(Fn, {
|
|
2487
|
-
id: s.id,
|
|
2488
|
-
refId: l.id,
|
|
2489
|
-
identity: t,
|
|
2490
|
-
ref: l
|
|
2491
|
-
}), {
|
|
2492
|
-
ref: l,
|
|
2493
|
-
ready: !1,
|
|
2494
|
-
outcome: "created"
|
|
2495
|
-
};
|
|
2496
|
-
}),
|
|
2497
|
-
confirm: (t, n) => Dn(e, t, async (e) => {
|
|
2498
|
-
let r = await $(e, t);
|
|
2499
|
-
if (!r) throw Error("Storage put operation is missing");
|
|
2500
|
-
let i = await Rn(e, r.refId);
|
|
2501
|
-
if (!i) throw Error("Storage put intent is missing");
|
|
2502
|
-
if (n !== void 0 && await Mn(e, r.id, n), r.state === "ready") {
|
|
2503
|
-
let n = await v.runPromise(ln(e).getById(r.refId));
|
|
2504
|
-
if (!n || n.key !== r.key || n.checksum !== t.checksum) throw Error("Confirmed storage operation lost its reference");
|
|
2505
|
-
return n;
|
|
2506
|
-
}
|
|
2507
|
-
return await kn(e, t), await v.runPromise(ln(e).insert(i.ref)), i.ref;
|
|
2508
|
-
}),
|
|
2509
|
-
beginDelete: async (t, r, i) => {
|
|
2510
|
-
let a = await Rn(e, t);
|
|
2511
|
-
if (!a) throw Error("Storage delete operation is missing");
|
|
2512
|
-
if (r !== void 0 && a.identity.tenantId !== r) throw Error("Storage delete tenant mismatch");
|
|
2513
|
-
return Dn(e, a.identity, async (e) => {
|
|
2514
|
-
let r = await Rn(e, t);
|
|
2515
|
-
if (!r) throw Error("Storage delete intent disappeared");
|
|
2516
|
-
let a = await $(e, r.identity);
|
|
2517
|
-
if (!a) throw Error("Storage delete lost its operation");
|
|
2518
|
-
let o = a.state !== "deleting" && a.state !== "deleted";
|
|
2519
|
-
if (i === void 0) o && await Pn(e, a.id);
|
|
2520
|
-
else if (o) {
|
|
2521
|
-
let o = await Nn(e, a.id, i);
|
|
2522
|
-
if (o.others) return {
|
|
2523
|
-
released: !0,
|
|
2524
|
-
identity: r.identity
|
|
2525
|
-
};
|
|
2526
|
-
if (!o.held) throw new n({
|
|
2527
|
-
reason: "claim-not-held",
|
|
2528
|
-
detail: `claim '${i}' is not held on storage reference '${t}'; a reference put without a claim is deleted as a whole by a delete that names none`
|
|
2529
|
-
});
|
|
2530
|
-
}
|
|
2531
|
-
let s = await An(e, r.identity);
|
|
2532
|
-
if (a.state === "ready") {
|
|
2533
|
-
let n = ln(e);
|
|
2534
|
-
if (await v.runPromise(fn(e).deleteByRef(t)), !await v.runPromise(n.delete(t))) throw Error("Storage deletion lost its confirmed reference");
|
|
2535
|
-
await v.runPromise(n.releaseUsage(r.identity.tenantId, {
|
|
2536
|
-
bytes: r.ref.size,
|
|
2537
|
-
count: 1
|
|
2538
|
-
}));
|
|
2539
|
-
}
|
|
2540
|
-
return {
|
|
2541
|
-
released: !0,
|
|
2542
|
-
operation: s,
|
|
2543
|
-
identity: r.identity
|
|
2544
|
-
};
|
|
2545
|
-
});
|
|
2546
|
-
},
|
|
2547
|
-
confirmDelete: (t) => Dn(e, t, (e) => jn(e, t))
|
|
2548
|
-
}), Bn = (e, t = 65536) => {
|
|
2549
|
-
let n = [Buffer.from("zINSTREAM\0", "utf8")];
|
|
2550
|
-
for (let r = 0; r < e.length; r += t) {
|
|
2551
|
-
let i = e.subarray(r, Math.min(r + t, e.length)), a = Buffer.alloc(4);
|
|
2552
|
-
a.writeUInt32BE(i.length, 0), n.push(a, Buffer.from(i));
|
|
2553
|
-
}
|
|
2554
|
-
let r = Buffer.alloc(4);
|
|
2555
|
-
return r.writeUInt32BE(0, 0), n.push(r), Buffer.concat(n);
|
|
2556
|
-
}, Vn = (e) => {
|
|
2557
|
-
let t = e.replace(/\0+$/, "").trim();
|
|
2558
|
-
if (/\bOK$/.test(t)) return { clean: !0 };
|
|
2559
|
-
let n = /:\s*(.+?)\s+FOUND$/.exec(t);
|
|
2560
|
-
if (n) return {
|
|
2561
|
-
clean: !1,
|
|
2562
|
-
threat: n[1] ?? "unknown"
|
|
2563
|
-
};
|
|
2564
|
-
throw Error(`clamav: unexpected response: ${t}`);
|
|
2565
|
-
}, Hn = async (e, t) => {
|
|
2566
|
-
let n = await import("node:net"), r = U.read("CLAMAV_HOST", t.host) ?? "127.0.0.1", i = U.read("CLAMAV_PORT"), a = t.port ?? (i ? Number(i) : 3310), o = t.timeoutMs ?? 3e4;
|
|
2567
|
-
return new Promise((i, s) => {
|
|
2568
|
-
let c = n.createConnection({
|
|
2569
|
-
host: r,
|
|
2570
|
-
port: a
|
|
2571
|
-
}), l = "", u = setTimeout(() => {
|
|
2572
|
-
c.destroy(), s(/* @__PURE__ */ Error("clamav scan timed out"));
|
|
2573
|
-
}, o);
|
|
2574
|
-
c.on("error", (e) => {
|
|
2575
|
-
clearTimeout(u), s(e);
|
|
2576
|
-
}), c.on("connect", () => {
|
|
2577
|
-
c.end(Bn(e, t.chunkSize));
|
|
2578
|
-
}), c.on("data", (e) => {
|
|
2579
|
-
l += e.toString("utf8");
|
|
2580
|
-
}), c.on("close", () => {
|
|
2581
|
-
clearTimeout(u);
|
|
2582
|
-
try {
|
|
2583
|
-
i(Vn(l));
|
|
2584
|
-
} catch (e) {
|
|
2585
|
-
s(e);
|
|
2586
|
-
}
|
|
2587
|
-
});
|
|
2588
|
-
});
|
|
2589
|
-
}, Un = (e = {}) => (t) => Hn(t.bytes, e), Wn = (e, t, n) => new Promise((r, i) => {
|
|
2590
|
-
let a = Oe(e, [...t], { stdio: [
|
|
2591
|
-
"ignore",
|
|
2592
|
-
"ignore",
|
|
2593
|
-
"pipe"
|
|
2594
|
-
] }), o = "", s = setTimeout(() => {
|
|
2595
|
-
a.kill("SIGKILL"), i(/* @__PURE__ */ Error("ffmpeg timed out"));
|
|
2596
|
-
}, n);
|
|
2597
|
-
a.stderr?.on("data", (e) => {
|
|
2598
|
-
o += String(e);
|
|
2599
|
-
}), a.on("error", (e) => {
|
|
2600
|
-
clearTimeout(s), i(e);
|
|
2601
|
-
}), a.on("close", (e) => {
|
|
2602
|
-
clearTimeout(s), e === 0 ? r() : i(/* @__PURE__ */ Error(`ffmpeg exited ${String(e)}: ${o.slice(-400)}`));
|
|
2603
|
-
});
|
|
2604
|
-
}), Gn = (e) => async ({ bytes: t }) => {
|
|
2605
|
-
let n = e.ffmpegPath ?? "ffmpeg", r = e.timeoutMs ?? 3e5, i = await R(Me(je(), "voltro-tc-")), a = Me(i, "in"), o = [];
|
|
2606
|
-
try {
|
|
2607
|
-
await Ae(a, t);
|
|
2608
|
-
for (let t of e.renditions) {
|
|
2609
|
-
let e = Me(i, `out.${t.ext}`);
|
|
2610
|
-
try {
|
|
2611
|
-
await Wn(n, [
|
|
2612
|
-
"-y",
|
|
2613
|
-
"-i",
|
|
2614
|
-
a,
|
|
2615
|
-
...t.args,
|
|
2616
|
-
e
|
|
2617
|
-
], r);
|
|
2618
|
-
let i = await z(e);
|
|
2619
|
-
o.push({
|
|
2620
|
-
bytes: new Uint8Array(i),
|
|
2621
|
-
contentType: t.contentType,
|
|
2622
|
-
kind: t.kind,
|
|
2623
|
-
...t.label === void 0 ? {} : { label: t.label }
|
|
2624
|
-
}), await ke(e, { force: !0 });
|
|
2625
|
-
} catch {}
|
|
2626
|
-
}
|
|
2627
|
-
} finally {
|
|
2628
|
-
await ke(i, {
|
|
2629
|
-
recursive: !0,
|
|
2630
|
-
force: !0
|
|
2631
|
-
}).catch(() => void 0);
|
|
2632
|
-
}
|
|
2633
|
-
return o;
|
|
2634
|
-
};
|
|
2635
|
-
//#endregion
|
|
2636
|
-
//#region src/assetRef.ts
|
|
2637
|
-
function Kn(e = {}) {
|
|
2638
|
-
let t = e.nullable ?? !0, n = e.fk === !1 ? F().externalId() : ye(() => We, { onDelete: e.onDelete ?? "setNull" });
|
|
2639
|
-
return t ? n.nullable() : n;
|
|
2640
|
-
}
|
|
2641
|
-
var qn = () => _e({
|
|
2642
|
-
id: "@voltro/plugin-storage/withStorage",
|
|
2643
|
-
fields: { asset: Kn() }
|
|
2644
|
-
}), Jn = {
|
|
2645
|
-
"image/png": "png",
|
|
2646
|
-
"image/jpeg": "jpg",
|
|
2647
|
-
"image/jpg": "jpg",
|
|
2648
|
-
"image/gif": "gif",
|
|
2649
|
-
"image/webp": "webp",
|
|
2650
|
-
"image/svg+xml": "svg"
|
|
2651
|
-
}, Yn = (e) => {
|
|
2652
|
-
let t = /^data:([^;,]+)(;base64)?,(.*)$/s.exec(e);
|
|
2653
|
-
if (!t) throw Error("not a data URI");
|
|
2654
|
-
let n = t[1] || "application/octet-stream", r = !!t[2], i = t[3] ?? "";
|
|
2655
|
-
return {
|
|
2656
|
-
bytes: r ? new Uint8Array(Buffer.from(i, "base64")) : new Uint8Array(Buffer.from(decodeURIComponent(i), "utf8")),
|
|
2657
|
-
contentType: n
|
|
2658
|
-
};
|
|
2659
|
-
}, Xn = (e, n) => v.gen(function* () {
|
|
2660
|
-
let r = yield* v.try({
|
|
2661
|
-
try: () => Yn(n.dataUri),
|
|
2662
|
-
catch: (e) => new t({
|
|
2663
|
-
provider: "avatar",
|
|
2664
|
-
message: String(e?.message ?? e),
|
|
2665
|
-
transient: !1,
|
|
2666
|
-
status: 400
|
|
2667
|
-
})
|
|
2668
|
-
}), i = Jn[r.contentType] ?? "bin";
|
|
2669
|
-
return yield* e.put({
|
|
2670
|
-
bytes: r.bytes,
|
|
2671
|
-
contentType: r.contentType,
|
|
2672
|
-
tenantId: n.tenantId,
|
|
2673
|
-
ownerId: n.userId,
|
|
2674
|
-
visibility: "public",
|
|
2675
|
-
key: `avatars/${n.userId}/avatar.${i}`
|
|
2676
|
-
});
|
|
2677
|
-
}), Zn = (e) => {
|
|
2678
|
-
try {
|
|
2679
|
-
let t = Ne(e), n = Ne("/");
|
|
2680
|
-
return typeof t.dev != "number" || typeof n.dev != "number" ? "unknown" : t.dev === n.dev ? "same-device-as-root" : "separate-mount";
|
|
2681
|
-
} catch {
|
|
2682
|
-
return "unknown";
|
|
2683
|
-
}
|
|
2684
|
-
}, Qn = (e) => {
|
|
2685
|
-
if (Zn(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
|
|
2686
|
-
dies with it — which is the exact failure it exists for. On a development machine this is normal
|
|
2687
|
-
and can be ignored.`;
|
|
2688
|
-
}, $n = U.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", er, tr = (e) => {
|
|
2689
|
-
er = e;
|
|
2690
|
-
}, nr = () => er ?? ir({}), rr = () => er === void 0 ? U.read("STORAGE_PROVIDER") === void 0 ? void 0 : ir({}) : er, ir = (e) => {
|
|
1
|
+
import { storageObjectNamespace as e } from "./storageNamespaces.js";
|
|
2
|
+
import { STORAGE_REFERENCE_CATALOGUE_TABLE as t, ensureStorageReferenceCatalogue as n, storageReferenceCatalogueTable as r } from "./referenceCatalogue.js";
|
|
3
|
+
import { STORAGE_BLOBS_TABLE as i, STORAGE_GRANTS_TABLE as a, STORAGE_REFS_TABLE as o, STORAGE_USAGE_TABLE as s, _voltroStorageBlobsTable as c, _voltroStorageGrantsTable as l, _voltroStorageRefsTable as u, _voltroStorageUsageTable as d } from "./table.js";
|
|
4
|
+
import { assignStorageReferenceInstancesInTransaction as f, requireStorageReferenceOwnership as ee } from "./storageReferenceInstances.js";
|
|
5
|
+
import { StorageAccessDenied as te, StorageError as p, StorageRejected as ne, StorageScanRejected as re, StorageService as m } from "./types.js";
|
|
6
|
+
import { storageObjectLifecycleTables as h } from "./objectLifecycle.js";
|
|
7
|
+
import { assignStorageObjectNamespacesInTransaction as g, requireStorageObjectNamespaces as _ } from "./storageObjectNamespaces.js";
|
|
8
|
+
import { bytesToStream as v, collectStream as y, concatBytes as b, fromNodeReadable as x, getObjectStream as S, putObjectStream as ie, toNodeReadable as C } from "./streamBridge.js";
|
|
9
|
+
import { storageEnv as w } from "./env.js";
|
|
10
|
+
import { azureProvider as T, clearStorageBuffer as E, databaseProvider as D, filesystemProvider as O, memoryProvider as k, readStorageBuffer as ae, s3Provider as A } from "./providers.js";
|
|
11
|
+
import { createTransformCache as oe } from "./transformCache.js";
|
|
12
|
+
import { editImage as j, parseTransformParams as se, transformCached as ce, transformFallbackReason as le, transformImage as ue, transformKey as de } from "./transform.js";
|
|
13
|
+
import { hashPassword as M, verifyPassword as fe } from "./access.js";
|
|
14
|
+
import { resolveStorageSecret as pe, signFinalizeTicket as me, signGrant as he, signMultipartTicket as ge, signResumableTicket as _e, signUploadTicket as N, verifyFinalizeTicket as ve, verifyGrant as ye, verifyMultipartTicket as P, verifyResumableTicket as be, verifyUploadTicket as F } from "./grant.js";
|
|
15
|
+
import { checkLimits as I, contentTypeAllowed as L, sniffMatches as R } from "./constraints.js";
|
|
16
|
+
import { fetchIngestBody as z } from "./ingest.js";
|
|
17
|
+
import { buildStorageService as xe, dataStoreGrantStore as Se, dataStoreRefStore as Ce, memoryGrantStore as we, memoryRefStore as B, refMatchesListQuery as V, storageServiceLayer as Te } from "./service.js";
|
|
18
|
+
import { makeStorageObjectMetadata as Ee, storagePutIntentsTable as De } from "./objectMetadata.js";
|
|
19
|
+
import { abortMultipartUploadDescriptor as Oe, beginMultipartUploadDescriptor as ke, beginResumableUploadDescriptor as Ae, completeMultipartUploadDescriptor as je, finalizeUploadDescriptor as Me, ingestUrlDescriptor as Ne, listGrantsDescriptor as Pe, listRefsDescriptor as Fe, mintPresignedUploadDescriptor as Ie, mintUploadTicketDescriptor as Le, mintUploadUrlDescriptor as Re, mintUrlDescriptor as ze, revokeDescriptor as Be, shareDescriptor as Ve, signMultipartPartDescriptor as He, storageRpcClientImports as Ue, uploadDescriptor as We } from "./rpc.js";
|
|
20
|
+
import { clamavScanner as Ge, encodeInstream as Ke, parseClamavResponse as qe } from "./scanners.js";
|
|
21
|
+
import { ffmpegTranscoder as Je } from "./transcodeVideo.js";
|
|
22
|
+
import { assetRef as Ye, withStorage as Xe } from "./assetRef.js";
|
|
23
|
+
import { decodeDataUri as Ze, putAvatar as Qe } from "./avatar.js";
|
|
24
|
+
import { durabilityNotice as $e, pathDurability as et } from "./pathDurability.js";
|
|
25
|
+
import { createHash as tt, randomUUID as H } from "node:crypto";
|
|
26
|
+
import { Effect as U, Schema as W, Stream as nt } from "effect";
|
|
27
|
+
import { processIdentity as rt } from "@voltro/protocol/identity";
|
|
28
|
+
import { StorageAccessPolicySchema as it, definePlugin as at, pluginInstanceName as G } from "@voltro/protocol";
|
|
29
|
+
import { readCookie as ot, resolveSessionSecret as st, verifySession as ct } from "@voltro/protocol/session";
|
|
30
|
+
//#region src/index.ts
|
|
31
|
+
var lt = w.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", K, ut = (e) => {
|
|
32
|
+
K = e;
|
|
33
|
+
}, dt = () => K ?? q({}), ft = () => K === void 0 ? w.read("STORAGE_PROVIDER") === void 0 ? void 0 : q({}) : K, q = (e) => {
|
|
2691
34
|
if (e.provider && typeof e.provider == "object") return e.provider;
|
|
2692
|
-
let t = (e.provider ??
|
|
35
|
+
let t = (e.provider ?? w.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = w.read("S3_BUCKET", e.bucket) ?? w.read("STORAGE_BUCKET") ?? "voltro";
|
|
2693
36
|
switch (t) {
|
|
2694
37
|
case "s3":
|
|
2695
38
|
case "minio": {
|
|
2696
|
-
let r =
|
|
2697
|
-
return nt({
|
|
39
|
+
let r = w.read("S3_REGION", e.region) ?? w.read("AWS_REGION"), i = w.read("S3_ENDPOINT", e.endpoint) ?? w.read("MINIO_ENDPOINT"), a = w.read("S3_ACCESS_KEY_ID", e.accessKeyId) ?? w.read("AWS_ACCESS_KEY_ID"), o = w.read("S3_SECRET_ACCESS_KEY", e.secretAccessKey) ?? w.read("AWS_SECRET_ACCESS_KEY"), s = w.read("STORAGE_CDN_URL", e.cdnBaseUrl), c = {
|
|
2698
40
|
bucket: n,
|
|
2699
41
|
name: t,
|
|
2700
42
|
...r ? { region: r } : {},
|
|
@@ -2703,25 +45,26 @@ var qn = () => _e({
|
|
|
2703
45
|
...o ? { secretAccessKey: o } : {},
|
|
2704
46
|
...s ? { cdnBaseUrl: s } : {},
|
|
2705
47
|
...e.publicAcl === void 0 ? {} : { publicAcl: e.publicAcl },
|
|
2706
|
-
...t === "minio" ||
|
|
2707
|
-
}
|
|
48
|
+
...t === "minio" || w.read("S3_FORCE_PATH_STYLE") === "1" ? { forcePathStyle: !0 } : {}
|
|
49
|
+
};
|
|
50
|
+
return A(c);
|
|
2708
51
|
}
|
|
2709
52
|
case "azure": {
|
|
2710
|
-
let t =
|
|
2711
|
-
|
|
2712
|
-
container: U.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
|
|
53
|
+
let t = w.read("AZURE_STORAGE_ACCOUNT", e.accountName), r = w.read("AZURE_STORAGE_KEY", e.accountKey), i = w.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString), a = w.read("AZURE_STORAGE_ENDPOINT", e.endpoint), o = w.read("STORAGE_CDN_URL", e.cdnBaseUrl), s = {
|
|
54
|
+
container: w.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
|
|
2713
55
|
...t ? { accountName: t } : {},
|
|
2714
56
|
...r ? { accountKey: r } : {},
|
|
2715
57
|
...i ? { connectionString: i } : {},
|
|
2716
58
|
...a ? { endpoint: a } : {},
|
|
2717
59
|
...o ? { cdnBaseUrl: o } : {}
|
|
2718
|
-
}
|
|
60
|
+
};
|
|
61
|
+
return T(s);
|
|
2719
62
|
}
|
|
2720
|
-
case "database": return
|
|
2721
|
-
case "filesystem": return
|
|
2722
|
-
default: return
|
|
63
|
+
case "database": return D();
|
|
64
|
+
case "filesystem": return O({ root: w.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
|
|
65
|
+
default: return k(e.name ?? "default");
|
|
2723
66
|
}
|
|
2724
|
-
},
|
|
67
|
+
}, pt = (e) => {
|
|
2725
68
|
let t = "stored files (uploads, renditions) and their reads", n = "provider 'database' or 'filesystem' keeps the bytes inside the installation";
|
|
2726
69
|
if (e.provider && typeof e.provider == "object") return [{
|
|
2727
70
|
destination: `runtime:the '${e.provider.name}' storage provider`,
|
|
@@ -2729,9 +72,9 @@ var qn = () => _e({
|
|
|
2729
72
|
data: ["files"],
|
|
2730
73
|
disable: n
|
|
2731
74
|
}];
|
|
2732
|
-
let r = (e.provider ??
|
|
75
|
+
let r = (e.provider ?? w.read("STORAGE_PROVIDER") ?? "memory").toLowerCase();
|
|
2733
76
|
if (r === "s3" || r === "minio") {
|
|
2734
|
-
let r =
|
|
77
|
+
let r = w.read("S3_ENDPOINT", e.endpoint) ?? w.read("MINIO_ENDPOINT"), i = w.read("S3_REGION", e.region) ?? w.read("AWS_REGION") ?? "us-east-1";
|
|
2735
78
|
return [{
|
|
2736
79
|
destination: r ?? `s3.${i}.amazonaws.com`,
|
|
2737
80
|
purpose: t,
|
|
@@ -2740,7 +83,7 @@ var qn = () => _e({
|
|
|
2740
83
|
}];
|
|
2741
84
|
}
|
|
2742
85
|
if (r === "azure") {
|
|
2743
|
-
let r =
|
|
86
|
+
let r = w.read("AZURE_STORAGE_ENDPOINT", e.endpoint), i = w.read("AZURE_STORAGE_ACCOUNT", e.accountName);
|
|
2744
87
|
return [{
|
|
2745
88
|
destination: r ?? (i === void 0 ? "runtime:the Azure storage connection string" : `${i}.blob.core.windows.net`),
|
|
2746
89
|
purpose: t,
|
|
@@ -2749,11 +92,11 @@ var qn = () => _e({
|
|
|
2749
92
|
}];
|
|
2750
93
|
}
|
|
2751
94
|
return [];
|
|
2752
|
-
},
|
|
95
|
+
}, mt = (e) => {
|
|
2753
96
|
if (e !== void 0) return e;
|
|
2754
|
-
let t =
|
|
97
|
+
let t = w.read("STORAGE_ALLOWED_ORIGINS");
|
|
2755
98
|
return t ? t.trim() === "*" ? "*" : t.split(",").map((e) => e.trim()).filter(Boolean) : [];
|
|
2756
|
-
},
|
|
99
|
+
}, J = (e, t) => {
|
|
2757
100
|
if (!e || t !== "*" && !t.includes(e)) return {};
|
|
2758
101
|
let n = {
|
|
2759
102
|
"access-control-allow-origin": t === "*" ? "*" : e,
|
|
@@ -2763,7 +106,7 @@ var qn = () => _e({
|
|
|
2763
106
|
vary: "Origin"
|
|
2764
107
|
};
|
|
2765
108
|
return t !== "*" && (n["access-control-allow-credentials"] = "true"), n;
|
|
2766
|
-
},
|
|
109
|
+
}, ht = (e) => ({
|
|
2767
110
|
id: e.id,
|
|
2768
111
|
tenantId: e.tenantId,
|
|
2769
112
|
ownerId: e.ownerId,
|
|
@@ -2786,29 +129,29 @@ var qn = () => _e({
|
|
|
2786
129
|
caption: e.caption ?? null,
|
|
2787
130
|
derivedFrom: e.derivedFrom ?? null,
|
|
2788
131
|
kind: e.kind ?? null
|
|
2789
|
-
}),
|
|
132
|
+
}), Y = () => new p({
|
|
2790
133
|
provider: "storage",
|
|
2791
134
|
message: "not permitted to administer sharing for this object",
|
|
2792
135
|
transient: !1,
|
|
2793
136
|
status: 403
|
|
2794
|
-
}),
|
|
137
|
+
}), X = (e, t, n) => {
|
|
2795
138
|
let r = n.request.subject;
|
|
2796
|
-
return (r.scopes ?? []).includes("admin:full") ?
|
|
139
|
+
return (r.scopes ?? []).includes("admin:full") ? U.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(U.catch(() => U.fail(Y())), U.flatMap((e) => {
|
|
2797
140
|
let t = e?.ownerId;
|
|
2798
|
-
return t != null && t === r.id ?
|
|
141
|
+
return t != null && t === r.id ? U.void : U.fail(Y());
|
|
2799
142
|
}));
|
|
2800
|
-
},
|
|
143
|
+
}, gt = () => new p({
|
|
2801
144
|
provider: "storage",
|
|
2802
145
|
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.",
|
|
2803
146
|
transient: !1,
|
|
2804
147
|
status: 401
|
|
2805
|
-
}),
|
|
148
|
+
}), Z = (e, t) => {
|
|
2806
149
|
let n = e.request.subject.id ?? null, r = e.request.subject.tenantId ?? null;
|
|
2807
|
-
return n === null && !t ?
|
|
150
|
+
return n === null && !t ? U.fail(gt()) : U.succeed({
|
|
2808
151
|
id: n,
|
|
2809
152
|
tenantId: r
|
|
2810
153
|
});
|
|
2811
|
-
},
|
|
154
|
+
}, _t = (e, t) => e !== null && e !== (t ?? null), Q = (e) => ({
|
|
2812
155
|
id: e.id,
|
|
2813
156
|
refId: e.refId,
|
|
2814
157
|
principalType: e.principalType,
|
|
@@ -2817,94 +160,111 @@ var qn = () => _e({
|
|
|
2817
160
|
createdAt: e.createdAt.toISOString(),
|
|
2818
161
|
expiresAt: e.expiresAt ? e.expiresAt.toISOString() : null,
|
|
2819
162
|
createdBy: e.createdBy
|
|
2820
|
-
}),
|
|
2821
|
-
base:
|
|
163
|
+
}), $ = "@voltro/plugin-storage", vt = (e = {}) => G({
|
|
164
|
+
base: $,
|
|
2822
165
|
alias: e.alias,
|
|
2823
166
|
instance: e.name
|
|
2824
|
-
}),
|
|
2825
|
-
let
|
|
2826
|
-
base:
|
|
2827
|
-
alias:
|
|
2828
|
-
instance:
|
|
2829
|
-
}),
|
|
2830
|
-
|
|
2831
|
-
let
|
|
2832
|
-
let r = (e) =>
|
|
167
|
+
}), yt = (e) => e.reason === "too-large" ? 413 : e.reason === "operation-identity-reused" || e.reason === "operation-store-unbound" || e.reason === "claim-not-held" ? 409 : 415, bt = (e = {}) => {
|
|
168
|
+
let t = G({
|
|
169
|
+
base: $,
|
|
170
|
+
alias: e.alias,
|
|
171
|
+
instance: e.name
|
|
172
|
+
}), r = t === $ ? "/_voltro/storage" : `/_voltro/storage/i/${Buffer.from(t).toString("hex")}`, i = q(e);
|
|
173
|
+
ut(i);
|
|
174
|
+
let a = w.read("S3_BUCKET", e.bucket) ?? w.read("STORAGE_BUCKET") ?? "voltro", o = w.read("VOLTRO_PUBLIC_URL", e.publicBaseUrl), s = mt(e.allowedOrigins), c = e.limits?.maxBytes, l = e.anonymousUploads === !0, u = 5242880, d = 21600, f = e.refStore === void 0 || e.refStore === "memory", m = e.grantStore === void 0 || e.grantStore === "memory", h = (t, n) => U.gen(function* () {
|
|
175
|
+
let r = (e) => W.decodeUnknownEffect(it)(e, { onExcessProperty: "error" }).pipe(U.mapError(() => new p({
|
|
2833
176
|
provider: "storage",
|
|
2834
177
|
message: "Invalid upload access policy",
|
|
2835
178
|
transient: !1,
|
|
2836
179
|
status: 400
|
|
2837
|
-
}))),
|
|
2838
|
-
if (
|
|
180
|
+
}))), i = t.access === void 0 ? void 0 : yield* r(t.access), a = t.visibility ?? "private";
|
|
181
|
+
if (i !== void 0 && a === "public") return yield* U.fail(new p({
|
|
2839
182
|
provider: "storage",
|
|
2840
183
|
message: "An access policy requires a private upload",
|
|
2841
184
|
transient: !1,
|
|
2842
185
|
status: 400
|
|
2843
186
|
}));
|
|
2844
|
-
let
|
|
2845
|
-
if (
|
|
187
|
+
let o = e.uploadAccess;
|
|
188
|
+
if (i !== void 0 && typeof o != "function") return yield* U.fail(new p({
|
|
2846
189
|
provider: "storage",
|
|
2847
190
|
message: "Requested upload access requires an uploadAccess authorization function on storagePlugin",
|
|
2848
191
|
transient: !1,
|
|
2849
192
|
status: 403
|
|
2850
193
|
}));
|
|
2851
|
-
let
|
|
194
|
+
let s = typeof o == "function" ? yield* o({
|
|
2852
195
|
subject: n,
|
|
2853
|
-
requested:
|
|
2854
|
-
visibility:
|
|
2855
|
-
contentType:
|
|
2856
|
-
}) :
|
|
2857
|
-
return
|
|
196
|
+
requested: i,
|
|
197
|
+
visibility: a,
|
|
198
|
+
contentType: t.contentType
|
|
199
|
+
}) : a === "private" ? o : void 0, c = s === void 0 ? void 0 : yield* r(s);
|
|
200
|
+
return a === "public" ? c !== void 0 && c.length > 0 ? yield* U.fail(new p({
|
|
2858
201
|
provider: "storage",
|
|
2859
202
|
message: "A public upload cannot carry an access policy",
|
|
2860
203
|
transient: !1,
|
|
2861
204
|
status: 400
|
|
2862
|
-
})) : {} :
|
|
2863
|
-
}),
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
205
|
+
})) : {} : c === void 0 ? {} : { access: c };
|
|
206
|
+
}), g = { current: f ? B() : e.refStore }, v = { current: m ? we() : e.grantStore }, y = { current: void 0 }, b = {
|
|
207
|
+
get catalogueId() {
|
|
208
|
+
return g.current.catalogueId;
|
|
209
|
+
},
|
|
210
|
+
insert: (e) => g.current.insert(e),
|
|
211
|
+
getById: (e) => g.current.getById(e),
|
|
212
|
+
delete: (e) => g.current.delete(e),
|
|
213
|
+
statistics: () => g.current.statistics(),
|
|
214
|
+
listRecent: (e) => g.current.listRecent(e),
|
|
215
|
+
countByKey: (e, t) => g.current.countByKey(e, t),
|
|
216
|
+
usageByTenant: (e) => g.current.usageByTenant(e),
|
|
217
|
+
consumeUsage: (e, t, n) => g.current.consumeUsage(e, t, n),
|
|
218
|
+
releaseUsage: (e, t) => g.current.releaseUsage(e, t),
|
|
219
|
+
listByDerivedFrom: (e) => g.current.listByDerivedFrom(e),
|
|
220
|
+
listRefs: (e) => g.current.listRefs(e),
|
|
2875
221
|
get setVisibility() {
|
|
2876
|
-
return
|
|
222
|
+
return g.current.setVisibility;
|
|
2877
223
|
},
|
|
2878
224
|
get countPublicByKey() {
|
|
2879
|
-
return
|
|
225
|
+
return g.current.countPublicByKey;
|
|
2880
226
|
}
|
|
2881
|
-
},
|
|
2882
|
-
insert: (e) =>
|
|
2883
|
-
delete: (e) =>
|
|
2884
|
-
getById: (e) =>
|
|
2885
|
-
listByRef: (e) =>
|
|
2886
|
-
deleteByRef: (e) =>
|
|
2887
|
-
},
|
|
2888
|
-
httpPath:
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
...
|
|
2895
|
-
...
|
|
2896
|
-
...
|
|
2897
|
-
...
|
|
2898
|
-
...
|
|
2899
|
-
...
|
|
2900
|
-
...
|
|
2901
|
-
...
|
|
2902
|
-
...
|
|
2903
|
-
...
|
|
2904
|
-
...
|
|
2905
|
-
...
|
|
2906
|
-
|
|
2907
|
-
|
|
227
|
+
}, x = {
|
|
228
|
+
insert: (e) => v.current.insert(e),
|
|
229
|
+
delete: (e) => v.current.delete(e),
|
|
230
|
+
getById: (e) => v.current.getById(e),
|
|
231
|
+
listByRef: (e) => v.current.listByRef(e),
|
|
232
|
+
deleteByRef: (e) => v.current.deleteByRef(e)
|
|
233
|
+
}, S = {
|
|
234
|
+
httpPath: r,
|
|
235
|
+
storageInstance: t,
|
|
236
|
+
provider: i,
|
|
237
|
+
refStore: b,
|
|
238
|
+
grantStore: x,
|
|
239
|
+
bucket: a,
|
|
240
|
+
...e.tenantPrefix === void 0 ? {} : { tenantPrefix: e.tenantPrefix },
|
|
241
|
+
...e.attempts === void 0 ? {} : { attempts: e.attempts },
|
|
242
|
+
...e.urlExpiresInSec === void 0 ? {} : { urlExpiresInSec: e.urlExpiresInSec },
|
|
243
|
+
...e.access === void 0 ? {} : { access: e.access },
|
|
244
|
+
...e.limits === void 0 ? {} : { limits: e.limits },
|
|
245
|
+
...e.ingest === void 0 ? {} : { ingest: e.ingest },
|
|
246
|
+
...e.scan === void 0 ? {} : { scan: e.scan },
|
|
247
|
+
...e.videoProbe === void 0 ? {} : { videoProbe: e.videoProbe },
|
|
248
|
+
...e.transcode === void 0 ? {} : { transcode: e.transcode },
|
|
249
|
+
...e.autoTranscode === void 0 ? {} : { autoTranscode: e.autoTranscode },
|
|
250
|
+
...o ? { publicBaseUrl: o } : {},
|
|
251
|
+
...e.normalizeImages === void 0 ? {} : { normalizeImages: e.normalizeImages },
|
|
252
|
+
...e.quota === void 0 ? {} : { quota: e.quota },
|
|
253
|
+
objects: () => y.current
|
|
254
|
+
}, ie = Te(S), C = xe(S), T = (e) => C.uploadTicketScope().pipe(U.flatMap((t) => t === e.writeScope ? U.void : U.fail(new p({
|
|
255
|
+
provider: "storage",
|
|
256
|
+
message: "Upload ticket belongs to another storage destination",
|
|
257
|
+
transient: !1,
|
|
258
|
+
status: 409
|
|
259
|
+
})))), E = (e, t) => U.runPromise(T(e).pipe(U.match({
|
|
260
|
+
onSuccess: () => null,
|
|
261
|
+
onFailure: (e) => ({
|
|
262
|
+
status: e.status ?? 503,
|
|
263
|
+
body: e.status === 409 ? e.message : "Storage upload destination could not be checked",
|
|
264
|
+
contentType: "text/plain",
|
|
265
|
+
headers: t
|
|
266
|
+
})
|
|
267
|
+
}))), D = `${r}/`, O = (e) => U.runPromise(e.pipe(U.catch(() => U.succeed(null)))), k = (e, t) => {
|
|
2908
268
|
if (!e) return "invalid";
|
|
2909
269
|
let n = /^bytes=(\d*)-(\d*)$/.exec(e.trim());
|
|
2910
270
|
if (!n) return "invalid";
|
|
@@ -2925,34 +285,34 @@ var qn = () => _e({
|
|
|
2925
285
|
start: a,
|
|
2926
286
|
endInclusive: o
|
|
2927
287
|
};
|
|
2928
|
-
},
|
|
288
|
+
}, ae = e.publicCacheSeconds === void 0 ? "public, max-age=31536000, immutable" : `public, max-age=${Math.max(0, Math.floor(e.publicCacheSeconds))}`, A = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, j = (e) => ({
|
|
2929
289
|
"x-content-type-options": "nosniff",
|
|
2930
|
-
"content-disposition":
|
|
2931
|
-
}),
|
|
290
|
+
"content-disposition": A.test(e) ? "inline" : "attachment"
|
|
291
|
+
}), ce = oe(), M = async (e, t, n, r) => {
|
|
2932
292
|
if (n) {
|
|
2933
|
-
let r, i = await
|
|
2934
|
-
let t = await
|
|
2935
|
-
return t ? (r = t.bytes,
|
|
293
|
+
let r, i = await ce.getOrCreate(de(JSON.stringify([e.id, e.checksum]), e.contentType, n), async () => {
|
|
294
|
+
let t = await O(C.get(e.id));
|
|
295
|
+
return t ? (r = t.bytes, ue(t.bytes, e.contentType, n)) : null;
|
|
2936
296
|
}).catch(() => null);
|
|
2937
|
-
if (!i && r === void 0 && (r = (await
|
|
297
|
+
if (!i && r === void 0 && (r = (await O(C.get(e.id)))?.bytes), !i && r === void 0) return {
|
|
2938
298
|
status: 404,
|
|
2939
299
|
body: "not found",
|
|
2940
300
|
contentType: "text/plain"
|
|
2941
301
|
};
|
|
2942
|
-
let a = i ? i.bytes : r, o = i ? i.contentType : e.contentType, s = await
|
|
302
|
+
let a = i ? i.bytes : r, o = i ? i.contentType : e.contentType, s = await le(e.contentType, i !== null);
|
|
2943
303
|
return {
|
|
2944
304
|
status: 200,
|
|
2945
305
|
body: a,
|
|
2946
306
|
contentType: o,
|
|
2947
307
|
headers: {
|
|
2948
|
-
...
|
|
308
|
+
...j(o),
|
|
2949
309
|
"cache-control": t,
|
|
2950
310
|
"accept-ranges": "none",
|
|
2951
311
|
...s === null ? {} : { "x-voltro-transform": `original; reason=${s}` }
|
|
2952
312
|
}
|
|
2953
313
|
};
|
|
2954
314
|
}
|
|
2955
|
-
let i = r === void 0 ? "invalid" :
|
|
315
|
+
let i = r === void 0 ? "invalid" : k(r, e.size);
|
|
2956
316
|
if (i === "unsatisfiable") return {
|
|
2957
317
|
status: 416,
|
|
2958
318
|
body: "range not satisfiable",
|
|
@@ -2963,13 +323,13 @@ var qn = () => _e({
|
|
|
2963
323
|
}
|
|
2964
324
|
};
|
|
2965
325
|
if (i !== "invalid") {
|
|
2966
|
-
let n = await
|
|
326
|
+
let n = await O(C.getRange(e.id, i));
|
|
2967
327
|
return n ? {
|
|
2968
328
|
status: 206,
|
|
2969
329
|
body: n.bytes,
|
|
2970
330
|
contentType: e.contentType,
|
|
2971
331
|
headers: {
|
|
2972
|
-
...
|
|
332
|
+
...j(e.contentType),
|
|
2973
333
|
"cache-control": t,
|
|
2974
334
|
"accept-ranges": "bytes",
|
|
2975
335
|
"content-range": `bytes ${i.start}-${i.endInclusive}/${n.totalSize}`
|
|
@@ -2980,69 +340,69 @@ var qn = () => _e({
|
|
|
2980
340
|
contentType: "text/plain"
|
|
2981
341
|
};
|
|
2982
342
|
}
|
|
2983
|
-
let a = await
|
|
343
|
+
let a = await O(C.getStream(e.id));
|
|
2984
344
|
return a ? {
|
|
2985
345
|
status: 200,
|
|
2986
346
|
contentType: e.contentType,
|
|
2987
347
|
headers: {
|
|
2988
|
-
...
|
|
348
|
+
...j(e.contentType),
|
|
2989
349
|
"cache-control": t,
|
|
2990
350
|
"accept-ranges": "bytes"
|
|
2991
351
|
},
|
|
2992
352
|
byteStream: {
|
|
2993
353
|
contentLength: e.size,
|
|
2994
|
-
stream: () =>
|
|
354
|
+
stream: () => nt.toReadableStream(a.stream)
|
|
2995
355
|
}
|
|
2996
356
|
} : {
|
|
2997
357
|
status: 404,
|
|
2998
358
|
body: "not found",
|
|
2999
359
|
contentType: "text/plain"
|
|
3000
360
|
};
|
|
3001
|
-
},
|
|
3002
|
-
let t = e.path.startsWith(
|
|
361
|
+
}, fe = async (e) => {
|
|
362
|
+
let t = e.path.startsWith(D) ? e.path.slice(D.length).split("/")[0] ?? "" : "";
|
|
3003
363
|
if (!t) return {
|
|
3004
364
|
status: 404,
|
|
3005
365
|
body: "not found",
|
|
3006
366
|
contentType: "text/plain"
|
|
3007
367
|
};
|
|
3008
|
-
let n = await
|
|
368
|
+
let n = await O(C.head(t));
|
|
3009
369
|
if (!n) return {
|
|
3010
370
|
status: 404,
|
|
3011
371
|
body: "not found",
|
|
3012
372
|
contentType: "text/plain"
|
|
3013
373
|
};
|
|
3014
|
-
let
|
|
3015
|
-
if (n.derivedFrom != null &&
|
|
374
|
+
let a = se(e.query), o = e.headers.range, s = n.derivedFrom == null ? null : await O(C.head(n.derivedFrom));
|
|
375
|
+
if (n.derivedFrom != null && s === null) return {
|
|
3016
376
|
status: 404,
|
|
3017
377
|
body: "not found",
|
|
3018
378
|
contentType: "text/plain"
|
|
3019
379
|
};
|
|
3020
|
-
if (n.visibility === "public" && (
|
|
3021
|
-
let e =
|
|
3022
|
-
return e && !
|
|
380
|
+
if (n.visibility === "public" && (s === null || s.visibility === "public")) {
|
|
381
|
+
let e = i.publicUrl?.(n.key) ?? null;
|
|
382
|
+
return e && !a ? {
|
|
3023
383
|
status: 302,
|
|
3024
384
|
headers: {
|
|
3025
385
|
location: e,
|
|
3026
386
|
"cache-control": "public, max-age=300"
|
|
3027
387
|
}
|
|
3028
|
-
} :
|
|
388
|
+
} : M(n, ae, a, o);
|
|
3029
389
|
}
|
|
3030
|
-
let
|
|
3031
|
-
if (
|
|
3032
|
-
let e =
|
|
3033
|
-
|
|
390
|
+
let c = !1, l = e.query ? new URLSearchParams(e.query).get("t") : null;
|
|
391
|
+
if (l) {
|
|
392
|
+
let e = ye(l);
|
|
393
|
+
c = !!e && (e.refId === t || s !== null && e.refId === s.id) && e.audience === r;
|
|
3034
394
|
}
|
|
3035
|
-
if (!
|
|
3036
|
-
let t =
|
|
3037
|
-
r && (
|
|
395
|
+
if (!c) {
|
|
396
|
+
let t = ot(e.headers.cookie, lt), r = t ? ct(t, st()) : null;
|
|
397
|
+
r && (c = await O(C.checkAccess(n, r)) === !0);
|
|
3038
398
|
}
|
|
3039
|
-
if (!
|
|
399
|
+
if (!c) return {
|
|
3040
400
|
status: 403,
|
|
3041
401
|
body: "forbidden",
|
|
3042
402
|
contentType: "text/plain"
|
|
3043
403
|
};
|
|
3044
|
-
if (
|
|
3045
|
-
let e = await
|
|
404
|
+
if (i.presigns && !a) {
|
|
405
|
+
let e = await O(i.getUrl(n.key, 300));
|
|
3046
406
|
if (e && /^https?:/.test(e)) return {
|
|
3047
407
|
status: 302,
|
|
3048
408
|
headers: {
|
|
@@ -3051,12 +411,12 @@ var qn = () => _e({
|
|
|
3051
411
|
}
|
|
3052
412
|
};
|
|
3053
413
|
}
|
|
3054
|
-
return
|
|
3055
|
-
},
|
|
414
|
+
return M(n, "private, no-store", a, o);
|
|
415
|
+
}, pe = {
|
|
3056
416
|
method: "GET",
|
|
3057
|
-
path:
|
|
417
|
+
path: r,
|
|
3058
418
|
handle: async (e) => {
|
|
3059
|
-
let t = await
|
|
419
|
+
let t = await fe(e), n = J(e.headers.origin, s);
|
|
3060
420
|
return Object.keys(n).length === 0 ? t : {
|
|
3061
421
|
...t,
|
|
3062
422
|
headers: {
|
|
@@ -3065,128 +425,127 @@ var qn = () => _e({
|
|
|
3065
425
|
}
|
|
3066
426
|
};
|
|
3067
427
|
}
|
|
3068
|
-
},
|
|
428
|
+
}, he = {
|
|
3069
429
|
method: "*",
|
|
3070
|
-
path: `${
|
|
430
|
+
path: `${r}/upload`,
|
|
3071
431
|
originGuard: "exempt",
|
|
3072
432
|
handle: async (e) => {
|
|
3073
|
-
let
|
|
433
|
+
let n = J(e.headers.origin, s);
|
|
3074
434
|
if (e.method === "OPTIONS") return {
|
|
3075
435
|
status: 204,
|
|
3076
|
-
headers:
|
|
436
|
+
headers: n
|
|
3077
437
|
};
|
|
3078
438
|
if (e.method !== "POST") return {
|
|
3079
439
|
status: 405,
|
|
3080
440
|
body: "method not allowed",
|
|
3081
441
|
contentType: "text/plain",
|
|
3082
|
-
headers:
|
|
442
|
+
headers: n
|
|
3083
443
|
};
|
|
3084
|
-
let
|
|
3085
|
-
if (!
|
|
444
|
+
let r = e.query ? new URLSearchParams(e.query).get("ticket") : null, i = r ? F(r) : null;
|
|
445
|
+
if (!i || i.instance !== t) return {
|
|
3086
446
|
status: 401,
|
|
3087
447
|
body: "invalid or expired upload ticket",
|
|
3088
448
|
contentType: "text/plain",
|
|
3089
|
-
headers:
|
|
3090
|
-
};
|
|
3091
|
-
if (r.replicaId !== void 0 && r.replicaId !== ie().replicaId) return {
|
|
3092
|
-
status: 409,
|
|
3093
|
-
body: "upload ticket belongs to another replica",
|
|
3094
|
-
contentType: "text/plain",
|
|
3095
|
-
headers: t
|
|
449
|
+
headers: n
|
|
3096
450
|
};
|
|
451
|
+
let a = await E(i, n);
|
|
452
|
+
if (a) return a;
|
|
3097
453
|
if (e.rawBody.length === 0) return {
|
|
3098
454
|
status: 400,
|
|
3099
455
|
body: "empty body",
|
|
3100
456
|
contentType: "text/plain",
|
|
3101
|
-
headers:
|
|
457
|
+
headers: n
|
|
3102
458
|
};
|
|
3103
|
-
if (
|
|
459
|
+
if (i.max && e.rawBody.length > i.max) return {
|
|
3104
460
|
status: 413,
|
|
3105
461
|
body: "payload too large",
|
|
3106
462
|
contentType: "text/plain",
|
|
3107
|
-
headers:
|
|
463
|
+
headers: n
|
|
3108
464
|
};
|
|
3109
|
-
let
|
|
465
|
+
let o = await U.runPromise(C.put({
|
|
3110
466
|
bytes: e.rawBody,
|
|
3111
|
-
contentType:
|
|
3112
|
-
tenantId:
|
|
3113
|
-
ownerId:
|
|
3114
|
-
visibility:
|
|
3115
|
-
...
|
|
3116
|
-
...
|
|
3117
|
-
...
|
|
3118
|
-
...
|
|
3119
|
-
...
|
|
3120
|
-
...
|
|
3121
|
-
...
|
|
3122
|
-
}).pipe(
|
|
467
|
+
contentType: i.ct,
|
|
468
|
+
tenantId: i.tenant,
|
|
469
|
+
ownerId: i.sub,
|
|
470
|
+
visibility: i.vis,
|
|
471
|
+
...i.access === void 0 ? {} : { access: i.access },
|
|
472
|
+
...i.operationId === void 0 ? {} : { operationId: i.operationId },
|
|
473
|
+
...i.key === void 0 ? {} : { key: i.key },
|
|
474
|
+
...i.folder === void 0 ? {} : { folder: i.folder },
|
|
475
|
+
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
476
|
+
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
477
|
+
...i.caption === void 0 ? {} : { caption: i.caption }
|
|
478
|
+
}).pipe(U.flatMap((e) => C.getUrl(e.id).pipe(U.map((t) => ({
|
|
3123
479
|
kind: "ok",
|
|
3124
480
|
ref: e,
|
|
3125
481
|
url: t
|
|
3126
|
-
})))),
|
|
3127
|
-
StorageRejected: (e) =>
|
|
482
|
+
})))), U.catchTags({
|
|
483
|
+
StorageRejected: (e) => U.succeed({
|
|
3128
484
|
kind: "rejected",
|
|
3129
|
-
status: e
|
|
485
|
+
status: yt(e),
|
|
3130
486
|
detail: e.detail
|
|
3131
487
|
}),
|
|
3132
|
-
StorageScanRejected: (e) =>
|
|
488
|
+
StorageScanRejected: (e) => U.succeed({
|
|
3133
489
|
kind: "scan",
|
|
3134
490
|
threat: e.threat
|
|
3135
491
|
}),
|
|
3136
|
-
StorageError: (e) =>
|
|
492
|
+
StorageError: (e) => U.succeed({
|
|
3137
493
|
kind: "error",
|
|
3138
|
-
message: e.message
|
|
494
|
+
message: e.message,
|
|
495
|
+
status: e.status ?? 500
|
|
3139
496
|
})
|
|
3140
497
|
})));
|
|
3141
|
-
return
|
|
498
|
+
return o.kind === "ok" ? {
|
|
3142
499
|
status: 201,
|
|
3143
500
|
body: JSON.stringify({
|
|
3144
|
-
id:
|
|
3145
|
-
url:
|
|
3146
|
-
contentType:
|
|
3147
|
-
size:
|
|
501
|
+
id: o.ref.id,
|
|
502
|
+
url: o.url,
|
|
503
|
+
contentType: o.ref.contentType,
|
|
504
|
+
size: o.ref.size
|
|
3148
505
|
}),
|
|
3149
506
|
contentType: "application/json",
|
|
3150
|
-
headers:
|
|
3151
|
-
} :
|
|
3152
|
-
status:
|
|
3153
|
-
body:
|
|
507
|
+
headers: n
|
|
508
|
+
} : o.kind === "rejected" ? {
|
|
509
|
+
status: o.status,
|
|
510
|
+
body: o.detail,
|
|
3154
511
|
contentType: "text/plain",
|
|
3155
|
-
headers:
|
|
3156
|
-
} :
|
|
512
|
+
headers: n
|
|
513
|
+
} : o.kind === "scan" ? {
|
|
3157
514
|
status: 422,
|
|
3158
|
-
body: `rejected: ${
|
|
515
|
+
body: `rejected: ${o.threat}`,
|
|
3159
516
|
contentType: "text/plain",
|
|
3160
|
-
headers:
|
|
517
|
+
headers: n
|
|
3161
518
|
} : {
|
|
3162
|
-
status:
|
|
3163
|
-
body:
|
|
519
|
+
status: o.status,
|
|
520
|
+
body: o.message,
|
|
3164
521
|
contentType: "text/plain",
|
|
3165
|
-
headers:
|
|
522
|
+
headers: n
|
|
3166
523
|
};
|
|
3167
524
|
}
|
|
3168
|
-
},
|
|
525
|
+
}, I = {
|
|
3169
526
|
method: "*",
|
|
3170
|
-
path: `${
|
|
527
|
+
path: `${r}/upload/resumable`,
|
|
3171
528
|
originGuard: "exempt",
|
|
3172
529
|
handle: async (e) => {
|
|
3173
|
-
let
|
|
530
|
+
let n = J(e.headers.origin, s);
|
|
3174
531
|
if (e.method === "OPTIONS") return {
|
|
3175
532
|
status: 204,
|
|
3176
|
-
headers:
|
|
533
|
+
headers: n
|
|
3177
534
|
};
|
|
3178
|
-
let
|
|
3179
|
-
if (!
|
|
535
|
+
let r = new URLSearchParams(e.query || ""), i = be(r.get("token") ?? "");
|
|
536
|
+
if (!i || i.instance !== t) return {
|
|
3180
537
|
status: 401,
|
|
3181
538
|
body: "invalid or expired resumable token",
|
|
3182
539
|
contentType: "text/plain",
|
|
3183
|
-
headers:
|
|
540
|
+
headers: n
|
|
3184
541
|
};
|
|
542
|
+
let a = await E(i, n);
|
|
543
|
+
if (a) return a;
|
|
3185
544
|
if (e.method === "GET" || e.method === "HEAD") {
|
|
3186
|
-
let e = await
|
|
3187
|
-
uploadId:
|
|
3188
|
-
tenantId:
|
|
3189
|
-
}).pipe(
|
|
545
|
+
let e = await U.runPromise(C.resumableStatus({
|
|
546
|
+
uploadId: i.id,
|
|
547
|
+
tenantId: i.tenant
|
|
548
|
+
}).pipe(U.match({
|
|
3190
549
|
onFailure: (e) => ({ error: e.message }),
|
|
3191
550
|
onSuccess: (e) => e
|
|
3192
551
|
})));
|
|
@@ -3194,13 +553,13 @@ var qn = () => _e({
|
|
|
3194
553
|
status: 500,
|
|
3195
554
|
body: e.error,
|
|
3196
555
|
contentType: "text/plain",
|
|
3197
|
-
headers:
|
|
556
|
+
headers: n
|
|
3198
557
|
} : {
|
|
3199
558
|
status: 200,
|
|
3200
559
|
body: JSON.stringify(e),
|
|
3201
560
|
contentType: "application/json",
|
|
3202
561
|
headers: {
|
|
3203
|
-
...
|
|
562
|
+
...n,
|
|
3204
563
|
"upload-offset": String(e.offset)
|
|
3205
564
|
}
|
|
3206
565
|
};
|
|
@@ -3209,168 +568,177 @@ var qn = () => _e({
|
|
|
3209
568
|
status: 405,
|
|
3210
569
|
body: "method not allowed",
|
|
3211
570
|
contentType: "text/plain",
|
|
3212
|
-
headers:
|
|
571
|
+
headers: n
|
|
3213
572
|
};
|
|
3214
|
-
let
|
|
3215
|
-
if (!Number.isInteger(
|
|
573
|
+
let o = Number(r.get("index"));
|
|
574
|
+
if (!Number.isInteger(o) || o < 0) return {
|
|
3216
575
|
status: 400,
|
|
3217
576
|
body: "missing/invalid chunk index",
|
|
3218
577
|
contentType: "text/plain",
|
|
3219
|
-
headers:
|
|
578
|
+
headers: n
|
|
3220
579
|
};
|
|
3221
580
|
if (e.rawBody.length === 0) return {
|
|
3222
581
|
status: 400,
|
|
3223
582
|
body: "empty chunk",
|
|
3224
583
|
contentType: "text/plain",
|
|
3225
|
-
headers:
|
|
584
|
+
headers: n
|
|
3226
585
|
};
|
|
3227
|
-
let
|
|
3228
|
-
uploadId:
|
|
3229
|
-
tenantId:
|
|
3230
|
-
index:
|
|
586
|
+
let c = r.get("final") === "1", l = await U.runPromise(C.putResumableChunk({
|
|
587
|
+
uploadId: i.id,
|
|
588
|
+
tenantId: i.tenant,
|
|
589
|
+
index: o,
|
|
3231
590
|
bytes: e.rawBody
|
|
3232
|
-
}).pipe(
|
|
3233
|
-
uploadId:
|
|
3234
|
-
count:
|
|
3235
|
-
contentType:
|
|
3236
|
-
tenantId:
|
|
3237
|
-
ownerId:
|
|
3238
|
-
visibility:
|
|
3239
|
-
...
|
|
3240
|
-
...
|
|
3241
|
-
...
|
|
3242
|
-
...
|
|
3243
|
-
...
|
|
3244
|
-
}).pipe(
|
|
591
|
+
}).pipe(U.flatMap(() => c ? C.finalizeResumable({
|
|
592
|
+
uploadId: i.id,
|
|
593
|
+
count: o + 1,
|
|
594
|
+
contentType: i.ct,
|
|
595
|
+
tenantId: i.tenant,
|
|
596
|
+
ownerId: i.sub,
|
|
597
|
+
visibility: i.vis,
|
|
598
|
+
...i.access === void 0 ? {} : { access: i.access },
|
|
599
|
+
...i.folder === void 0 ? {} : { folder: i.folder },
|
|
600
|
+
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
601
|
+
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
602
|
+
...i.caption === void 0 ? {} : { caption: i.caption }
|
|
603
|
+
}).pipe(U.flatMap((e) => C.getUrl(e.id).pipe(U.map((t) => ({
|
|
3245
604
|
kind: "done",
|
|
3246
605
|
ref: e,
|
|
3247
606
|
url: t
|
|
3248
|
-
}))))) :
|
|
3249
|
-
StorageRejected: (e) =>
|
|
607
|
+
}))))) : U.succeed({ kind: "chunk" })), U.catchTags({
|
|
608
|
+
StorageRejected: (e) => U.succeed({
|
|
3250
609
|
kind: "rejected",
|
|
3251
|
-
status: e
|
|
610
|
+
status: yt(e),
|
|
3252
611
|
detail: e.detail
|
|
3253
612
|
}),
|
|
3254
|
-
StorageScanRejected: (e) =>
|
|
613
|
+
StorageScanRejected: (e) => U.succeed({
|
|
3255
614
|
kind: "scan",
|
|
3256
615
|
threat: e.threat
|
|
3257
616
|
}),
|
|
3258
|
-
StorageError: (e) =>
|
|
617
|
+
StorageError: (e) => U.succeed({
|
|
3259
618
|
kind: "error",
|
|
3260
|
-
message: e.message
|
|
619
|
+
message: e.message,
|
|
620
|
+
status: e.status ?? 500
|
|
3261
621
|
})
|
|
3262
622
|
})));
|
|
3263
|
-
return
|
|
623
|
+
return l.kind === "chunk" ? {
|
|
3264
624
|
status: 204,
|
|
3265
625
|
headers: {
|
|
3266
|
-
...
|
|
3267
|
-
"upload-offset": String(
|
|
626
|
+
...n,
|
|
627
|
+
"upload-offset": String(o + 1)
|
|
3268
628
|
}
|
|
3269
|
-
} :
|
|
629
|
+
} : l.kind === "done" ? {
|
|
3270
630
|
status: 201,
|
|
3271
631
|
body: JSON.stringify({
|
|
3272
|
-
id:
|
|
3273
|
-
url:
|
|
3274
|
-
contentType:
|
|
3275
|
-
size:
|
|
632
|
+
id: l.ref.id,
|
|
633
|
+
url: l.url,
|
|
634
|
+
contentType: l.ref.contentType,
|
|
635
|
+
size: l.ref.size
|
|
3276
636
|
}),
|
|
3277
637
|
contentType: "application/json",
|
|
3278
|
-
headers:
|
|
3279
|
-
} :
|
|
3280
|
-
status:
|
|
3281
|
-
body:
|
|
638
|
+
headers: n
|
|
639
|
+
} : l.kind === "rejected" ? {
|
|
640
|
+
status: l.status,
|
|
641
|
+
body: l.detail,
|
|
3282
642
|
contentType: "text/plain",
|
|
3283
|
-
headers:
|
|
3284
|
-
} :
|
|
643
|
+
headers: n
|
|
644
|
+
} : l.kind === "scan" ? {
|
|
3285
645
|
status: 422,
|
|
3286
|
-
body: `rejected: ${
|
|
646
|
+
body: `rejected: ${l.threat}`,
|
|
3287
647
|
contentType: "text/plain",
|
|
3288
|
-
headers:
|
|
648
|
+
headers: n
|
|
3289
649
|
} : {
|
|
3290
|
-
status:
|
|
3291
|
-
body:
|
|
650
|
+
status: l.status,
|
|
651
|
+
body: l.message,
|
|
3292
652
|
contentType: "text/plain",
|
|
3293
|
-
headers:
|
|
653
|
+
headers: n
|
|
3294
654
|
};
|
|
3295
655
|
}
|
|
3296
|
-
},
|
|
656
|
+
}, L = (e) => ({
|
|
3297
657
|
kind: "json",
|
|
3298
658
|
data: e
|
|
3299
|
-
}),
|
|
659
|
+
}), R = (e, t) => ({
|
|
3300
660
|
kind: "json",
|
|
3301
661
|
status: e,
|
|
3302
662
|
data: { error: t }
|
|
3303
|
-
}),
|
|
663
|
+
}), z = (e, t) => {
|
|
3304
664
|
try {
|
|
3305
665
|
return new URL(e, "http://localhost").searchParams.get(t);
|
|
3306
666
|
} catch {
|
|
3307
667
|
return null;
|
|
3308
668
|
}
|
|
3309
|
-
},
|
|
669
|
+
}, V = U.gen(function* () {
|
|
670
|
+
return {
|
|
671
|
+
catalogueId: yield* b.catalogueId,
|
|
672
|
+
objectNamespace: yield* i.objectNamespace,
|
|
673
|
+
storageInstance: t
|
|
674
|
+
};
|
|
675
|
+
}), De = [
|
|
3310
676
|
{
|
|
3311
677
|
method: "POST",
|
|
3312
678
|
path: "/upload-ticket",
|
|
3313
679
|
description: "Authorize a binary upload with explicit tenant and owner attribution",
|
|
3314
|
-
handler: (
|
|
3315
|
-
let
|
|
3316
|
-
operationId:
|
|
3317
|
-
tenantId:
|
|
3318
|
-
ownerId:
|
|
3319
|
-
key:
|
|
3320
|
-
contentType:
|
|
3321
|
-
size:
|
|
3322
|
-
visibility:
|
|
3323
|
-
})))(
|
|
680
|
+
handler: (n) => U.gen(function* () {
|
|
681
|
+
let i = W.String.pipe(W.check(W.makeFilter((e) => e.trim().length > 0))), a = yield* W.decodeUnknownEffect(W.fromJsonString(W.Struct({
|
|
682
|
+
operationId: W.optional(i.pipe(W.check(W.isMaxLength(200)))),
|
|
683
|
+
tenantId: W.NullOr(i),
|
|
684
|
+
ownerId: W.NullOr(i),
|
|
685
|
+
key: i.pipe(W.check(W.isMaxLength(1024))),
|
|
686
|
+
contentType: i.pipe(W.check(W.isMaxLength(255)), W.check(W.makeFilter((e) => !/[\r\n]/.test(e)))),
|
|
687
|
+
size: W.Number.pipe(W.check(W.isInt()), W.check(W.isGreaterThan(0)), W.check(W.makeFilter(Number.isSafeInteger))),
|
|
688
|
+
visibility: W.optional(W.Literals(["public", "private"]))
|
|
689
|
+
})))(n.body).pipe(U.mapError(() => new p({
|
|
3324
690
|
provider: "inspect",
|
|
3325
691
|
message: "Provide explicit tenantId and ownerId (or null), key, contentType and a positive file size",
|
|
3326
692
|
transient: !1,
|
|
3327
693
|
status: 400
|
|
3328
694
|
})));
|
|
3329
|
-
if (
|
|
3330
|
-
if (
|
|
3331
|
-
let a =
|
|
695
|
+
if (a.operationId !== void 0 && y.current === void 0) return R(409, "Durable uploads require a bound operation store with default reference and grant stores");
|
|
696
|
+
if (c !== void 0 && a.size > c) return R(413, "File exceeds the configured upload limit");
|
|
697
|
+
let o = a.operationId ?? (y.current === void 0 ? void 0 : H()), s = o === void 0 ? void 0 : "inspect-upload:" + tt("sha256").update(JSON.stringify([t, o])).digest("hex"), l = a.visibility !== "public" && Array.isArray(e.uploadAccess) ? yield* W.decodeUnknownEffect(it)(e.uploadAccess, { onExcessProperty: "error" }).pipe(U.mapError(() => new p({
|
|
3332
698
|
provider: "storage",
|
|
3333
699
|
message: "Invalid upload access policy",
|
|
3334
700
|
transient: !1,
|
|
3335
701
|
status: 400
|
|
3336
|
-
}))) : void 0,
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
702
|
+
}))) : void 0, u = yield* C.uploadTicketScope(), d = N({
|
|
703
|
+
writeScope: u,
|
|
704
|
+
instance: t,
|
|
705
|
+
issuerReplicaId: rt().replicaId,
|
|
706
|
+
...l === void 0 ? {} : { access: l },
|
|
707
|
+
...s === void 0 ? {} : { operationId: s },
|
|
708
|
+
sub: a.ownerId,
|
|
709
|
+
tenant: a.tenantId,
|
|
710
|
+
ct: a.contentType,
|
|
711
|
+
key: a.key,
|
|
712
|
+
vis: a.visibility ?? "private",
|
|
713
|
+
max: a.size
|
|
3347
714
|
}, 300);
|
|
3348
|
-
return
|
|
3349
|
-
uploadPath: `${
|
|
715
|
+
return L({
|
|
716
|
+
uploadPath: `${r}/upload?ticket=${encodeURIComponent(d)}`,
|
|
3350
717
|
expiresInSec: 300,
|
|
3351
|
-
maxBytes:
|
|
718
|
+
maxBytes: a.size,
|
|
719
|
+
...o === void 0 ? {} : { operationId: o }
|
|
3352
720
|
});
|
|
3353
|
-
}).pipe(
|
|
721
|
+
}).pipe(U.catch((e) => U.succeed(R(e.status ?? 500, e.message))))
|
|
3354
722
|
},
|
|
3355
723
|
{
|
|
3356
724
|
method: "GET",
|
|
3357
725
|
path: "/download",
|
|
3358
726
|
description: "Stream a stored file as an attachment for authorized inspect readers",
|
|
3359
|
-
handler: (e) =>
|
|
3360
|
-
let t =
|
|
3361
|
-
if (!t?.trim()) return
|
|
3362
|
-
let { ref: n, stream: r } = yield*
|
|
727
|
+
handler: (e) => U.gen(function* () {
|
|
728
|
+
let t = z(e.url, "refId");
|
|
729
|
+
if (!t?.trim()) return R(400, "A non-empty refId is required");
|
|
730
|
+
let { ref: n, stream: r } = yield* C.getStream(t), i = n.key.split("/").pop() || n.id, a = encodeURIComponent(i).replace(/[!'()*]/g, (e) => `%${e.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
3363
731
|
return {
|
|
3364
732
|
kind: "bytes",
|
|
3365
733
|
contentType: n.contentType,
|
|
3366
734
|
byteStream: {
|
|
3367
|
-
stream: () =>
|
|
735
|
+
stream: () => nt.toReadableStream(r),
|
|
3368
736
|
contentLength: n.size,
|
|
3369
737
|
contentDisposition: `attachment; filename="download"; filename*=UTF-8''${a}`
|
|
3370
738
|
},
|
|
3371
739
|
headers: { "cache-control": "no-store" }
|
|
3372
740
|
};
|
|
3373
|
-
}).pipe(
|
|
741
|
+
}).pipe(U.catch((e) => U.succeed(R(e.status ?? 500, e.message))))
|
|
3374
742
|
},
|
|
3375
743
|
{
|
|
3376
744
|
method: "GET",
|
|
@@ -3378,8 +746,8 @@ var qn = () => _e({
|
|
|
3378
746
|
scope: "process",
|
|
3379
747
|
description: "Searchable storage refs, newest first, paginated",
|
|
3380
748
|
handler: (e) => {
|
|
3381
|
-
let t = Number(
|
|
3382
|
-
return
|
|
749
|
+
let t = Number(z(e.url, "offset") ?? 0), n = Number.isSafeInteger(t) && t >= 0 ? t : 0, r = (z(e.url, "search") ?? "").trim().slice(0, 200);
|
|
750
|
+
return b.listRefs({
|
|
3383
751
|
tenantId: void 0,
|
|
3384
752
|
ownerId: void 0,
|
|
3385
753
|
folder: void 0,
|
|
@@ -3388,14 +756,15 @@ var qn = () => _e({
|
|
|
3388
756
|
search: r,
|
|
3389
757
|
limit: 51,
|
|
3390
758
|
offset: n
|
|
3391
|
-
}).pipe(
|
|
3392
|
-
|
|
759
|
+
}).pipe(U.flatMap((e) => V.pipe(U.map((t) => L({
|
|
760
|
+
source: t,
|
|
761
|
+
refs: e.slice(0, 50).map(ht),
|
|
3393
762
|
page: {
|
|
3394
763
|
search: r,
|
|
3395
764
|
offset: n,
|
|
3396
765
|
nextOffset: e.length > 50 ? n + 50 : null
|
|
3397
766
|
}
|
|
3398
|
-
})),
|
|
767
|
+
})))), U.catch((e) => U.succeed(R(500, e.message))));
|
|
3399
768
|
}
|
|
3400
769
|
},
|
|
3401
770
|
{
|
|
@@ -3403,11 +772,12 @@ var qn = () => _e({
|
|
|
3403
772
|
path: "/stats",
|
|
3404
773
|
scope: "process",
|
|
3405
774
|
description: "Object count + total bytes per tenant + visibility split",
|
|
3406
|
-
handler: () =>
|
|
3407
|
-
|
|
3408
|
-
|
|
775
|
+
handler: () => b.statistics().pipe(U.flatMap((e) => V.pipe(U.map((t) => L({
|
|
776
|
+
source: t,
|
|
777
|
+
provider: i.name,
|
|
778
|
+
bucket: a,
|
|
3409
779
|
...e
|
|
3410
|
-
})),
|
|
780
|
+
})))), U.catch((e) => U.succeed(R(500, e.message))))
|
|
3411
781
|
},
|
|
3412
782
|
{
|
|
3413
783
|
method: "GET",
|
|
@@ -3415,171 +785,185 @@ var qn = () => _e({
|
|
|
3415
785
|
scope: "process",
|
|
3416
786
|
description: "Grants for a ref (?refId=…)",
|
|
3417
787
|
handler: (e) => {
|
|
3418
|
-
let t =
|
|
3419
|
-
return t ?
|
|
788
|
+
let t = z(e.url, "refId");
|
|
789
|
+
return t ? x.listByRef(t).pipe(U.map((e) => L({ grants: e.map(Q) })), U.catch((e) => U.succeed(R(500, e.message)))) : U.succeed(R(400, "refId query param required"));
|
|
3420
790
|
}
|
|
3421
791
|
},
|
|
3422
792
|
{
|
|
3423
793
|
method: "POST",
|
|
3424
794
|
path: "/share",
|
|
3425
795
|
description: "Grant a principal access to a ref",
|
|
3426
|
-
handler: (e) =>
|
|
3427
|
-
let
|
|
3428
|
-
refId:
|
|
3429
|
-
principalType:
|
|
796
|
+
handler: (e) => U.gen(function* () {
|
|
797
|
+
let t = yield* W.decodeUnknownEffect(W.fromJsonString(W.Struct({
|
|
798
|
+
refId: W.String.pipe(W.check(W.makeFilter((e) => e.trim().length > 0))),
|
|
799
|
+
principalType: W.Literals([
|
|
3430
800
|
"user",
|
|
3431
801
|
"group",
|
|
3432
802
|
"apiKey"
|
|
3433
803
|
]),
|
|
3434
|
-
principalId:
|
|
3435
|
-
permission:
|
|
3436
|
-
expiresInDays:
|
|
3437
|
-
})))(e.body).pipe(
|
|
804
|
+
principalId: W.String.pipe(W.check(W.makeFilter((e) => e.trim().length > 0))),
|
|
805
|
+
permission: W.optional(W.Literals(["read", "write"])),
|
|
806
|
+
expiresInDays: W.optional(W.Number.pipe(W.check(W.isFinite()), W.check(W.isGreaterThan(0))))
|
|
807
|
+
})))(e.body).pipe(U.mapError(() => new p({
|
|
3438
808
|
provider: "inspect",
|
|
3439
809
|
message: "Invalid share input: provide refId, principalType, principalId, read/write permission and a positive finite expiry if set",
|
|
3440
810
|
transient: !1,
|
|
3441
811
|
status: 400
|
|
3442
|
-
}))),
|
|
3443
|
-
if (
|
|
3444
|
-
let
|
|
3445
|
-
refId:
|
|
3446
|
-
principalType:
|
|
3447
|
-
principalId:
|
|
3448
|
-
...
|
|
3449
|
-
expiresAt:
|
|
812
|
+
}))), n = t.expiresInDays === void 0 ? null : new Date(Date.now() + t.expiresInDays * 864e5);
|
|
813
|
+
if (n !== null && !Number.isFinite(n.getTime())) return R(400, "Expiry exceeds the supported date range");
|
|
814
|
+
let r = yield* C.grant({
|
|
815
|
+
refId: t.refId,
|
|
816
|
+
principalType: t.principalType,
|
|
817
|
+
principalId: t.principalId,
|
|
818
|
+
...t.permission ? { permission: t.permission } : {},
|
|
819
|
+
expiresAt: n
|
|
3450
820
|
});
|
|
3451
|
-
return
|
|
3452
|
-
}).pipe(
|
|
821
|
+
return L({ grant: Q(r) });
|
|
822
|
+
}).pipe(U.catch((e) => U.succeed(R(e.status ?? 500, e.message ?? "share failed"))))
|
|
3453
823
|
},
|
|
3454
824
|
{
|
|
3455
825
|
method: "POST",
|
|
3456
826
|
path: "/delete",
|
|
3457
827
|
description: "Delete an object reference and its grants; release unreferenced bytes",
|
|
3458
|
-
handler: (e) =>
|
|
3459
|
-
let
|
|
828
|
+
handler: (e) => U.gen(function* () {
|
|
829
|
+
let t = yield* W.decodeUnknownEffect(W.fromJsonString(W.Struct({ refId: W.String.pipe(W.check(W.makeFilter((e) => e.trim().length > 0))) })))(e.body).pipe(U.mapError(() => new p({
|
|
3460
830
|
provider: "inspect",
|
|
3461
831
|
message: "A non-empty refId is required",
|
|
3462
832
|
transient: !1,
|
|
3463
833
|
status: 400
|
|
3464
834
|
})));
|
|
3465
|
-
return yield*
|
|
3466
|
-
}).pipe(
|
|
835
|
+
return yield* C.delete(t.refId), L({ ok: !0 });
|
|
836
|
+
}).pipe(U.catch((e) => U.succeed(R(e.status ?? 500, e.message))))
|
|
3467
837
|
},
|
|
3468
838
|
{
|
|
3469
839
|
method: "POST",
|
|
3470
840
|
path: "/revoke",
|
|
3471
841
|
description: "Revoke a grant by id",
|
|
3472
|
-
handler: (e) =>
|
|
3473
|
-
let
|
|
842
|
+
handler: (e) => U.gen(function* () {
|
|
843
|
+
let t = yield* W.decodeUnknownEffect(W.fromJsonString(W.Struct({ grantId: W.String.pipe(W.check(W.makeFilter((e) => e.trim().length > 0))) })))(e.body).pipe(U.mapError(() => new p({
|
|
3474
844
|
provider: "inspect",
|
|
3475
845
|
message: "A non-empty grantId is required",
|
|
3476
846
|
transient: !1,
|
|
3477
847
|
status: 400
|
|
3478
848
|
})));
|
|
3479
|
-
return yield*
|
|
3480
|
-
}).pipe(
|
|
849
|
+
return yield* C.revoke(t.grantId), L({ ok: !0 });
|
|
850
|
+
}).pipe(U.catch((e) => U.succeed(R(e.status ?? 500, e.message ?? "revoke failed"))))
|
|
3481
851
|
}
|
|
3482
|
-
],
|
|
852
|
+
], Ge = [
|
|
3483
853
|
{
|
|
3484
|
-
...
|
|
854
|
+
...ze,
|
|
3485
855
|
execute: (e, t) => {
|
|
3486
856
|
let n = e;
|
|
3487
|
-
return
|
|
857
|
+
return C.mintUrl(n.id, t.request.subject, {
|
|
3488
858
|
...n.password === void 0 ? {} : { password: n.password },
|
|
3489
859
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
3490
|
-
}).pipe(
|
|
860
|
+
}).pipe(U.map((e) => ({ url: e })));
|
|
3491
861
|
}
|
|
3492
862
|
},
|
|
3493
863
|
{
|
|
3494
|
-
...
|
|
864
|
+
...Re,
|
|
3495
865
|
execute: (e, t) => {
|
|
3496
866
|
let n = e;
|
|
3497
|
-
return
|
|
867
|
+
return C.mintUploadUrl({
|
|
3498
868
|
key: n.key,
|
|
3499
869
|
contentType: n.contentType,
|
|
3500
870
|
tenantId: t.request.subject.tenantId,
|
|
3501
871
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
3502
|
-
}).pipe(
|
|
872
|
+
}).pipe(U.map((e) => ({ url: e })));
|
|
3503
873
|
}
|
|
3504
874
|
},
|
|
3505
875
|
{
|
|
3506
|
-
...
|
|
3507
|
-
execute: (e,
|
|
3508
|
-
let
|
|
3509
|
-
return
|
|
876
|
+
...Le,
|
|
877
|
+
execute: (e, n) => {
|
|
878
|
+
let i = e;
|
|
879
|
+
return Z(n, l).pipe(U.flatMap((e) => h(i, n.request.subject).pipe(U.map((t) => ({
|
|
3510
880
|
writer: e,
|
|
3511
881
|
policy: t
|
|
3512
|
-
})))),
|
|
3513
|
-
|
|
3514
|
-
|
|
882
|
+
})))), U.flatMap((e) => i.operationId !== void 0 && y.current === void 0 ? U.fail(new p({
|
|
883
|
+
provider: "storage",
|
|
884
|
+
message: "Durable uploads require a bound operation store with default reference and grant stores",
|
|
885
|
+
transient: !1,
|
|
886
|
+
status: 409
|
|
887
|
+
})) : U.succeed(e)), U.flatMap(({ writer: e, policy: n }) => C.uploadTicketScope().pipe(U.map((a) => {
|
|
888
|
+
let s = i.expiresInSec ?? 900, l = i.operationId ?? (y.current === void 0 ? void 0 : H()), u = l === void 0 ? void 0 : "client-upload:" + tt("sha256").update(JSON.stringify([
|
|
889
|
+
t,
|
|
890
|
+
e.tenantId,
|
|
891
|
+
e.id,
|
|
892
|
+
l
|
|
893
|
+
])).digest("hex"), d = N({
|
|
894
|
+
writeScope: a,
|
|
895
|
+
instance: t,
|
|
896
|
+
...u === void 0 ? {} : { operationId: u },
|
|
3515
897
|
sub: e.id,
|
|
3516
898
|
tenant: e.tenantId,
|
|
3517
|
-
ct:
|
|
3518
|
-
vis:
|
|
3519
|
-
...
|
|
3520
|
-
...
|
|
3521
|
-
...
|
|
3522
|
-
...
|
|
3523
|
-
...
|
|
3524
|
-
...
|
|
3525
|
-
...
|
|
3526
|
-
},
|
|
899
|
+
ct: i.contentType,
|
|
900
|
+
vis: i.visibility ?? "private",
|
|
901
|
+
...n,
|
|
902
|
+
...i.key === void 0 ? {} : { key: i.key },
|
|
903
|
+
...i.folder === void 0 ? {} : { folder: i.folder },
|
|
904
|
+
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
905
|
+
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
906
|
+
...i.caption === void 0 ? {} : { caption: i.caption },
|
|
907
|
+
...c === void 0 ? {} : { max: c }
|
|
908
|
+
}, s);
|
|
3527
909
|
return {
|
|
3528
|
-
uploadUrl: `${
|
|
3529
|
-
expiresInSec:
|
|
910
|
+
uploadUrl: `${o ? o.replace(/\/+$/, "") : ""}${r}/upload?ticket=${encodeURIComponent(d)}`,
|
|
911
|
+
expiresInSec: s,
|
|
912
|
+
...l === void 0 ? {} : { operationId: l }
|
|
3530
913
|
};
|
|
3531
|
-
}));
|
|
914
|
+
}))));
|
|
3532
915
|
}
|
|
3533
916
|
},
|
|
3534
917
|
{
|
|
3535
|
-
...
|
|
3536
|
-
execute: (e,
|
|
3537
|
-
let
|
|
3538
|
-
return
|
|
918
|
+
...Ie,
|
|
919
|
+
execute: (e, n) => {
|
|
920
|
+
let r = e;
|
|
921
|
+
return Z(n, l).pipe(U.flatMap((e) => h(r, n.request.subject).pipe(U.map((t) => ({
|
|
3539
922
|
writer: e,
|
|
3540
923
|
policy: t
|
|
3541
|
-
})))),
|
|
3542
|
-
contentType:
|
|
924
|
+
})))), U.flatMap(({ writer: e, policy: n }) => C.uploadTicketScope().pipe(U.flatMap((i) => C.mintPresignedUpload({
|
|
925
|
+
contentType: r.contentType,
|
|
3543
926
|
tenantId: e.tenantId,
|
|
3544
|
-
...
|
|
3545
|
-
}).pipe(
|
|
3546
|
-
let
|
|
3547
|
-
|
|
3548
|
-
|
|
927
|
+
...r.expiresInSec === void 0 ? {} : { expiresInSec: r.expiresInSec }
|
|
928
|
+
}).pipe(U.map((a) => {
|
|
929
|
+
let o = me({
|
|
930
|
+
writeScope: i,
|
|
931
|
+
instance: t,
|
|
932
|
+
key: a.key,
|
|
3549
933
|
sub: e.id,
|
|
3550
934
|
tenant: e.tenantId,
|
|
3551
|
-
ct:
|
|
3552
|
-
vis:
|
|
3553
|
-
...
|
|
3554
|
-
...
|
|
3555
|
-
...
|
|
3556
|
-
...
|
|
3557
|
-
...
|
|
3558
|
-
...
|
|
3559
|
-
},
|
|
935
|
+
ct: r.contentType,
|
|
936
|
+
vis: r.visibility ?? "private",
|
|
937
|
+
...n,
|
|
938
|
+
...r.folder === void 0 ? {} : { folder: r.folder },
|
|
939
|
+
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
940
|
+
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
941
|
+
...r.caption === void 0 ? {} : { caption: r.caption },
|
|
942
|
+
...c === void 0 ? {} : { max: c }
|
|
943
|
+
}, a.expiresInSec);
|
|
3560
944
|
return {
|
|
3561
|
-
uploadUrl:
|
|
3562
|
-
finalizeToken:
|
|
3563
|
-
expiresInSec:
|
|
945
|
+
uploadUrl: a.uploadUrl,
|
|
946
|
+
finalizeToken: o,
|
|
947
|
+
expiresInSec: a.expiresInSec
|
|
3564
948
|
};
|
|
3565
|
-
}))));
|
|
949
|
+
}))))));
|
|
3566
950
|
}
|
|
3567
951
|
},
|
|
3568
952
|
{
|
|
3569
|
-
...
|
|
953
|
+
...Me,
|
|
3570
954
|
execute: (e, n) => {
|
|
3571
|
-
let r =
|
|
3572
|
-
return !r || r.instance !==
|
|
955
|
+
let r = ve(e.finalizeToken);
|
|
956
|
+
return !r || r.instance !== t ? U.fail(new p({
|
|
3573
957
|
provider: "storage",
|
|
3574
958
|
message: "invalid or expired finalize token",
|
|
3575
959
|
transient: !1,
|
|
3576
960
|
status: 401
|
|
3577
|
-
})) :
|
|
961
|
+
})) : _t(r.sub, n.request.subject.id) ? U.fail(new p({
|
|
3578
962
|
provider: "storage",
|
|
3579
963
|
message: "finalize token belongs to another subject",
|
|
3580
964
|
transient: !1,
|
|
3581
965
|
status: 403
|
|
3582
|
-
})) :
|
|
966
|
+
})) : T(r).pipe(U.flatMap(() => C.finalizeUpload({
|
|
3583
967
|
key: r.key,
|
|
3584
968
|
contentType: r.ct,
|
|
3585
969
|
tenantId: r.tenant,
|
|
@@ -3590,118 +974,120 @@ var qn = () => _e({
|
|
|
3590
974
|
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
3591
975
|
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
3592
976
|
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
3593
|
-
}).pipe(
|
|
977
|
+
}).pipe(U.flatMap((e) => C.getUrl(e.id).pipe(U.map((t) => ({
|
|
3594
978
|
id: e.id,
|
|
3595
979
|
url: t,
|
|
3596
980
|
contentType: e.contentType,
|
|
3597
981
|
size: e.size,
|
|
3598
982
|
...e.width == null ? {} : { width: e.width },
|
|
3599
983
|
...e.height == null ? {} : { height: e.height }
|
|
3600
|
-
})))));
|
|
984
|
+
})))))));
|
|
3601
985
|
}
|
|
3602
986
|
},
|
|
3603
987
|
{
|
|
3604
|
-
...
|
|
3605
|
-
execute: (e,
|
|
3606
|
-
let
|
|
3607
|
-
return
|
|
988
|
+
...Ae,
|
|
989
|
+
execute: (e, n) => {
|
|
990
|
+
let i = e;
|
|
991
|
+
return Z(n, l).pipe(U.flatMap((e) => h(i, n.request.subject).pipe(U.map((t) => ({
|
|
3608
992
|
writer: e,
|
|
3609
993
|
policy: t
|
|
3610
|
-
})))),
|
|
3611
|
-
let
|
|
994
|
+
})))), U.flatMap(({ writer: e, policy: n }) => C.uploadTicketScope().pipe(U.map((a) => {
|
|
995
|
+
let s = i.expiresInSec ?? d, l = H(), f = i.chunkSize && i.chunkSize > 0 ? i.chunkSize : u;
|
|
3612
996
|
return {
|
|
3613
|
-
uploadId:
|
|
3614
|
-
resumableToken:
|
|
3615
|
-
|
|
3616
|
-
|
|
997
|
+
uploadId: l,
|
|
998
|
+
resumableToken: _e({
|
|
999
|
+
writeScope: a,
|
|
1000
|
+
instance: t,
|
|
1001
|
+
id: l,
|
|
3617
1002
|
sub: e.id,
|
|
3618
1003
|
tenant: e.tenantId,
|
|
3619
|
-
ct:
|
|
3620
|
-
vis:
|
|
3621
|
-
...
|
|
3622
|
-
size:
|
|
3623
|
-
...
|
|
3624
|
-
...
|
|
3625
|
-
...
|
|
3626
|
-
...
|
|
3627
|
-
...
|
|
3628
|
-
},
|
|
3629
|
-
uploadUrl: `${
|
|
3630
|
-
chunkSize:
|
|
3631
|
-
expiresInSec:
|
|
1004
|
+
ct: i.contentType,
|
|
1005
|
+
vis: i.visibility ?? "private",
|
|
1006
|
+
...n,
|
|
1007
|
+
size: i.size,
|
|
1008
|
+
...i.folder === void 0 ? {} : { folder: i.folder },
|
|
1009
|
+
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
1010
|
+
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
1011
|
+
...i.caption === void 0 ? {} : { caption: i.caption },
|
|
1012
|
+
...c === void 0 ? {} : { max: c }
|
|
1013
|
+
}, s),
|
|
1014
|
+
uploadUrl: `${o ? o.replace(/\/+$/, "") : ""}${r}/upload/resumable`,
|
|
1015
|
+
chunkSize: f,
|
|
1016
|
+
expiresInSec: s
|
|
3632
1017
|
};
|
|
3633
|
-
}));
|
|
1018
|
+
}))));
|
|
3634
1019
|
}
|
|
3635
1020
|
},
|
|
3636
1021
|
{
|
|
3637
|
-
...
|
|
3638
|
-
execute: (e,
|
|
3639
|
-
let
|
|
3640
|
-
return
|
|
1022
|
+
...ke,
|
|
1023
|
+
execute: (e, n) => {
|
|
1024
|
+
let r = e, i = r.expiresInSec ?? d;
|
|
1025
|
+
return Z(n, l).pipe(U.flatMap((e) => h(r, n.request.subject).pipe(U.map((t) => ({
|
|
3641
1026
|
writer: e,
|
|
3642
1027
|
policy: t
|
|
3643
|
-
})))),
|
|
3644
|
-
contentType:
|
|
1028
|
+
})))), U.flatMap(({ writer: e, policy: n }) => C.uploadTicketScope().pipe(U.flatMap((a) => C.beginMultipartUpload({
|
|
1029
|
+
contentType: r.contentType,
|
|
3645
1030
|
tenantId: e.tenantId,
|
|
3646
|
-
visibility:
|
|
3647
|
-
expiresInSec:
|
|
3648
|
-
}).pipe(
|
|
3649
|
-
multipartToken:
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
1031
|
+
visibility: r.visibility ?? "private",
|
|
1032
|
+
expiresInSec: i
|
|
1033
|
+
}).pipe(U.map((o) => ({
|
|
1034
|
+
multipartToken: ge({
|
|
1035
|
+
writeScope: a,
|
|
1036
|
+
instance: t,
|
|
1037
|
+
key: o.key,
|
|
1038
|
+
uploadId: o.uploadId,
|
|
3653
1039
|
sub: e.id,
|
|
3654
1040
|
tenant: e.tenantId,
|
|
3655
|
-
ct:
|
|
3656
|
-
vis:
|
|
3657
|
-
...
|
|
3658
|
-
size:
|
|
3659
|
-
...
|
|
3660
|
-
...
|
|
3661
|
-
...
|
|
3662
|
-
...
|
|
3663
|
-
},
|
|
3664
|
-
partSize:
|
|
3665
|
-
expiresInSec:
|
|
3666
|
-
})))));
|
|
1041
|
+
ct: r.contentType,
|
|
1042
|
+
vis: r.visibility ?? "private",
|
|
1043
|
+
...n,
|
|
1044
|
+
size: r.size,
|
|
1045
|
+
...r.folder === void 0 ? {} : { folder: r.folder },
|
|
1046
|
+
...r.tags === void 0 ? {} : { tags: r.tags },
|
|
1047
|
+
...r.alt === void 0 ? {} : { alt: r.alt },
|
|
1048
|
+
...r.caption === void 0 ? {} : { caption: r.caption }
|
|
1049
|
+
}, i),
|
|
1050
|
+
partSize: r.partSize && r.partSize >= u ? r.partSize : u,
|
|
1051
|
+
expiresInSec: i
|
|
1052
|
+
})))))));
|
|
3667
1053
|
}
|
|
3668
1054
|
},
|
|
3669
1055
|
{
|
|
3670
|
-
...
|
|
1056
|
+
...He,
|
|
3671
1057
|
execute: (e) => {
|
|
3672
|
-
let n = e, r =
|
|
3673
|
-
return !r || r.instance !==
|
|
1058
|
+
let n = e, r = P(n.multipartToken);
|
|
1059
|
+
return !r || r.instance !== t ? U.fail(new p({
|
|
3674
1060
|
provider: "storage",
|
|
3675
1061
|
message: "invalid or expired multipart token",
|
|
3676
1062
|
transient: !1,
|
|
3677
1063
|
status: 401
|
|
3678
|
-
})) : !Number.isInteger(n.partNumber) || n.partNumber < 1 ?
|
|
1064
|
+
})) : !Number.isInteger(n.partNumber) || n.partNumber < 1 ? U.fail(new p({
|
|
3679
1065
|
provider: "storage",
|
|
3680
1066
|
message: "partNumber must be a positive integer",
|
|
3681
1067
|
transient: !1,
|
|
3682
1068
|
status: 400
|
|
3683
|
-
})) :
|
|
1069
|
+
})) : T(r).pipe(U.flatMap(() => C.signMultipartPart({
|
|
3684
1070
|
key: r.key,
|
|
3685
1071
|
uploadId: r.uploadId,
|
|
3686
1072
|
partNumber: n.partNumber
|
|
3687
|
-
}).pipe(
|
|
1073
|
+
}).pipe(U.map((e) => ({ url: e })))));
|
|
3688
1074
|
}
|
|
3689
1075
|
},
|
|
3690
1076
|
{
|
|
3691
|
-
...
|
|
1077
|
+
...je,
|
|
3692
1078
|
execute: (e, n) => {
|
|
3693
|
-
let r = e, i =
|
|
3694
|
-
return !i || i.instance !==
|
|
1079
|
+
let r = e, i = P(r.multipartToken);
|
|
1080
|
+
return !i || i.instance !== t ? U.fail(new p({
|
|
3695
1081
|
provider: "storage",
|
|
3696
1082
|
message: "invalid or expired multipart token",
|
|
3697
1083
|
transient: !1,
|
|
3698
1084
|
status: 401
|
|
3699
|
-
})) :
|
|
1085
|
+
})) : _t(i.sub, n.request.subject.id) ? U.fail(new p({
|
|
3700
1086
|
provider: "storage",
|
|
3701
1087
|
message: "multipart token belongs to another subject",
|
|
3702
1088
|
transient: !1,
|
|
3703
1089
|
status: 403
|
|
3704
|
-
})) :
|
|
1090
|
+
})) : T(i).pipe(U.flatMap(() => C.completeMultipart({
|
|
3705
1091
|
key: i.key,
|
|
3706
1092
|
uploadId: i.uploadId,
|
|
3707
1093
|
parts: r.parts,
|
|
@@ -3714,36 +1100,36 @@ var qn = () => _e({
|
|
|
3714
1100
|
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
3715
1101
|
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
3716
1102
|
...i.caption === void 0 ? {} : { caption: i.caption }
|
|
3717
|
-
}).pipe(
|
|
1103
|
+
}).pipe(U.flatMap((e) => C.getUrl(e.id).pipe(U.map((t) => ({
|
|
3718
1104
|
id: e.id,
|
|
3719
1105
|
url: t,
|
|
3720
1106
|
size: e.size
|
|
3721
|
-
})))));
|
|
1107
|
+
})))))));
|
|
3722
1108
|
}
|
|
3723
1109
|
},
|
|
3724
1110
|
{
|
|
3725
|
-
...
|
|
1111
|
+
...Oe,
|
|
3726
1112
|
execute: (e) => {
|
|
3727
|
-
let n =
|
|
3728
|
-
return !n || n.instance !==
|
|
1113
|
+
let n = P(e.multipartToken);
|
|
1114
|
+
return !n || n.instance !== t ? U.fail(new p({
|
|
3729
1115
|
provider: "storage",
|
|
3730
1116
|
message: "invalid or expired multipart token",
|
|
3731
1117
|
transient: !1,
|
|
3732
1118
|
status: 401
|
|
3733
|
-
})) :
|
|
1119
|
+
})) : T(n).pipe(U.flatMap(() => C.abortMultipart({
|
|
3734
1120
|
key: n.key,
|
|
3735
1121
|
uploadId: n.uploadId
|
|
3736
|
-
}).pipe(
|
|
1122
|
+
}).pipe(U.as({ ok: !0 }))));
|
|
3737
1123
|
}
|
|
3738
1124
|
},
|
|
3739
1125
|
{
|
|
3740
|
-
...
|
|
1126
|
+
...We,
|
|
3741
1127
|
execute: (e, t) => {
|
|
3742
1128
|
let n = e, r = new Uint8Array(Buffer.from(n.bytesBase64, "base64"));
|
|
3743
|
-
return
|
|
1129
|
+
return Z(t, l).pipe(U.flatMap((e) => h(n, t.request.subject).pipe(U.map((t) => ({
|
|
3744
1130
|
writer: e,
|
|
3745
1131
|
policy: t
|
|
3746
|
-
})))),
|
|
1132
|
+
})))), U.flatMap(({ writer: e, policy: t }) => C.put({
|
|
3747
1133
|
bytes: r,
|
|
3748
1134
|
...t,
|
|
3749
1135
|
contentType: n.contentType,
|
|
@@ -3752,17 +1138,17 @@ var qn = () => _e({
|
|
|
3752
1138
|
...n.visibility ? { visibility: n.visibility } : {},
|
|
3753
1139
|
...n.key ? { key: n.key } : {},
|
|
3754
1140
|
...n.password ? { password: n.password } : {}
|
|
3755
|
-
})),
|
|
1141
|
+
})), U.flatMap((e) => C.getUrl(e.id).pipe(U.map((t) => ({
|
|
3756
1142
|
id: e.id,
|
|
3757
1143
|
url: t
|
|
3758
1144
|
})))));
|
|
3759
1145
|
}
|
|
3760
1146
|
},
|
|
3761
1147
|
{
|
|
3762
|
-
...
|
|
1148
|
+
...Ne,
|
|
3763
1149
|
execute: (e, t) => {
|
|
3764
1150
|
let n = e;
|
|
3765
|
-
return
|
|
1151
|
+
return Z(t, l).pipe(U.flatMap((e) => C.ingestUrl(n.url, {
|
|
3766
1152
|
tenantId: e.tenantId,
|
|
3767
1153
|
ownerId: e.id,
|
|
3768
1154
|
...n.visibility ? { visibility: n.visibility } : {},
|
|
@@ -3771,45 +1157,45 @@ var qn = () => _e({
|
|
|
3771
1157
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
3772
1158
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
3773
1159
|
...n.key === void 0 ? {} : { key: n.key }
|
|
3774
|
-
})),
|
|
1160
|
+
})), U.flatMap((e) => C.getUrl(e.id).pipe(U.map((t) => ({
|
|
3775
1161
|
id: e.id,
|
|
3776
1162
|
url: t
|
|
3777
1163
|
})))));
|
|
3778
1164
|
}
|
|
3779
1165
|
},
|
|
3780
1166
|
{
|
|
3781
|
-
...
|
|
1167
|
+
...Ve,
|
|
3782
1168
|
execute: (e, t) => {
|
|
3783
1169
|
let n = e, r = n.expiresInDays ? new Date(Date.now() + n.expiresInDays * 864e5) : null;
|
|
3784
|
-
return
|
|
1170
|
+
return X(C, n.refId, t).pipe(U.flatMap(() => C.grant({
|
|
3785
1171
|
refId: n.refId,
|
|
3786
1172
|
principalType: n.principalType,
|
|
3787
1173
|
principalId: n.principalId,
|
|
3788
1174
|
...n.permission ? { permission: n.permission } : {},
|
|
3789
1175
|
expiresAt: r,
|
|
3790
1176
|
createdBy: t.request.subject.id
|
|
3791
|
-
})),
|
|
1177
|
+
})), U.map((e) => ({ grantId: e.id })));
|
|
3792
1178
|
}
|
|
3793
1179
|
},
|
|
3794
1180
|
{
|
|
3795
|
-
...
|
|
1181
|
+
...Be,
|
|
3796
1182
|
execute: (e, t) => {
|
|
3797
1183
|
let n = e;
|
|
3798
|
-
return
|
|
1184
|
+
return C.getGrant(n.grantId).pipe(U.flatMap((e) => e === null ? U.fail(Y()) : X(C, e.refId, t)), U.flatMap(() => C.revoke(n.grantId)), U.map(() => ({ ok: !0 })));
|
|
3799
1185
|
}
|
|
3800
1186
|
},
|
|
3801
1187
|
{
|
|
3802
|
-
...
|
|
1188
|
+
...Pe,
|
|
3803
1189
|
execute: (e, t) => {
|
|
3804
1190
|
let n = e;
|
|
3805
|
-
return
|
|
1191
|
+
return X(C, n.refId, t).pipe(U.flatMap(() => C.listGrants(n.refId)), U.map((e) => ({ grants: e.map(Q) })));
|
|
3806
1192
|
}
|
|
3807
1193
|
},
|
|
3808
1194
|
{
|
|
3809
|
-
...
|
|
1195
|
+
...Fe,
|
|
3810
1196
|
execute: (e, t) => {
|
|
3811
1197
|
let n = e;
|
|
3812
|
-
return
|
|
1198
|
+
return C.listRefs({
|
|
3813
1199
|
tenantId: t.request.subject.tenantId,
|
|
3814
1200
|
...n.folder === void 0 ? {} : { folder: n.folder },
|
|
3815
1201
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
@@ -3817,61 +1203,61 @@ var qn = () => _e({
|
|
|
3817
1203
|
...n.includeDerived === void 0 ? {} : { includeDerived: n.includeDerived },
|
|
3818
1204
|
...n.limit === void 0 ? {} : { limit: n.limit },
|
|
3819
1205
|
...n.offset === void 0 ? {} : { offset: n.offset }
|
|
3820
|
-
}).pipe(
|
|
3821
|
-
refs: e.refs.map(
|
|
1206
|
+
}).pipe(U.map((e) => ({
|
|
1207
|
+
refs: e.refs.map(ht),
|
|
3822
1208
|
nextOffset: e.nextOffset
|
|
3823
1209
|
})));
|
|
3824
1210
|
}
|
|
3825
1211
|
}
|
|
3826
1212
|
];
|
|
3827
|
-
return
|
|
3828
|
-
name:
|
|
3829
|
-
base:
|
|
3830
|
-
alias:
|
|
3831
|
-
instance:
|
|
1213
|
+
return at({
|
|
1214
|
+
name: G({
|
|
1215
|
+
base: $,
|
|
1216
|
+
alias: e.alias,
|
|
1217
|
+
instance: e.name
|
|
3832
1218
|
}),
|
|
3833
|
-
baseName:
|
|
1219
|
+
baseName: $,
|
|
3834
1220
|
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.",
|
|
3835
1221
|
permissions: [
|
|
3836
1222
|
"network:outbound:*",
|
|
3837
1223
|
"inspect:read",
|
|
3838
1224
|
"inspect:write"
|
|
3839
1225
|
],
|
|
3840
|
-
declaredEnv:
|
|
3841
|
-
egress:
|
|
3842
|
-
services:
|
|
3843
|
-
inspectEndpoints:
|
|
1226
|
+
declaredEnv: w.declared,
|
|
1227
|
+
egress: pt(e),
|
|
1228
|
+
services: ie,
|
|
1229
|
+
inspectEndpoints: De,
|
|
3844
1230
|
httpRoutes: [
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
1231
|
+
pe,
|
|
1232
|
+
he,
|
|
1233
|
+
I
|
|
3848
1234
|
],
|
|
3849
|
-
routes:
|
|
3850
|
-
rpcClientDescriptors:
|
|
1235
|
+
routes: Ge,
|
|
1236
|
+
rpcClientDescriptors: Ue,
|
|
3851
1237
|
errorSchemas: [
|
|
3852
1238
|
{
|
|
3853
|
-
schema:
|
|
1239
|
+
schema: p,
|
|
3854
1240
|
import: {
|
|
3855
1241
|
module: "@voltro/plugin-storage/errors",
|
|
3856
1242
|
name: "StorageError"
|
|
3857
1243
|
}
|
|
3858
1244
|
},
|
|
3859
1245
|
{
|
|
3860
|
-
schema:
|
|
1246
|
+
schema: te,
|
|
3861
1247
|
import: {
|
|
3862
1248
|
module: "@voltro/plugin-storage/errors",
|
|
3863
1249
|
name: "StorageAccessDenied"
|
|
3864
1250
|
}
|
|
3865
1251
|
},
|
|
3866
1252
|
{
|
|
3867
|
-
schema:
|
|
1253
|
+
schema: ne,
|
|
3868
1254
|
import: {
|
|
3869
1255
|
module: "@voltro/plugin-storage/errors",
|
|
3870
1256
|
name: "StorageRejected"
|
|
3871
1257
|
}
|
|
3872
1258
|
},
|
|
3873
1259
|
{
|
|
3874
|
-
schema:
|
|
1260
|
+
schema: re,
|
|
3875
1261
|
import: {
|
|
3876
1262
|
module: "@voltro/plugin-storage/errors",
|
|
3877
1263
|
name: "StorageScanRejected"
|
|
@@ -3880,7 +1266,7 @@ var qn = () => _e({
|
|
|
3880
1266
|
],
|
|
3881
1267
|
capabilities: { mediaPersist: {
|
|
3882
1268
|
put: async ({ bytes: e, mediaType: t, tenantId: n, operationId: r, ownerId: i, visibility: a, tags: o }) => {
|
|
3883
|
-
let s = await
|
|
1269
|
+
let s = await U.runPromise(C.put({
|
|
3884
1270
|
bytes: e,
|
|
3885
1271
|
contentType: t,
|
|
3886
1272
|
tenantId: n,
|
|
@@ -3888,40 +1274,50 @@ var qn = () => _e({
|
|
|
3888
1274
|
...i === void 0 ? {} : { ownerId: i },
|
|
3889
1275
|
...a === void 0 ? {} : { visibility: a },
|
|
3890
1276
|
...o === void 0 ? {} : { tags: o },
|
|
3891
|
-
...
|
|
1277
|
+
...y.current === void 0 ? {} : { operationId: r }
|
|
3892
1278
|
}));
|
|
3893
1279
|
return {
|
|
3894
|
-
url: await
|
|
1280
|
+
url: await U.runPromise(C.getUrl(s.id, { tenantId: n })),
|
|
3895
1281
|
refId: s.id
|
|
3896
1282
|
};
|
|
3897
1283
|
},
|
|
3898
1284
|
ingestUrl: async ({ url: e, tenantId: t, operationId: n, ownerId: r, visibility: i, tags: a }) => {
|
|
3899
|
-
let o = await
|
|
1285
|
+
let o = await U.runPromise(C.ingestUrl(e, {
|
|
3900
1286
|
tenantId: t,
|
|
3901
1287
|
...r === void 0 ? {} : { ownerId: r },
|
|
3902
1288
|
...i === void 0 ? {} : { visibility: i },
|
|
3903
1289
|
...a === void 0 ? {} : { tags: a },
|
|
3904
|
-
...
|
|
1290
|
+
...y.current === void 0 ? {} : { operationId: n }
|
|
3905
1291
|
}));
|
|
3906
1292
|
return {
|
|
3907
|
-
url: await
|
|
1293
|
+
url: await U.runPromise(C.getUrl(o.id, { tenantId: t })),
|
|
3908
1294
|
refId: o.id
|
|
3909
1295
|
};
|
|
3910
1296
|
}
|
|
3911
1297
|
} },
|
|
3912
|
-
bindDataStore: (e) => {
|
|
3913
|
-
|
|
1298
|
+
bindDataStore: async (e) => {
|
|
1299
|
+
let r = await U.runPromise(i.objectNamespace);
|
|
1300
|
+
(f || m) && await ee(e), (f || m) && await _(e), f && await n(e), f && (g.current = Ce(e, {
|
|
1301
|
+
storageInstance: t,
|
|
1302
|
+
objectNamespace: r
|
|
1303
|
+
})), m && (v.current = Se(e, {
|
|
1304
|
+
storageInstance: t,
|
|
1305
|
+
objectNamespace: r
|
|
1306
|
+
})), f && m && (y.current = Ee(e, {
|
|
1307
|
+
storageInstance: t,
|
|
1308
|
+
objectNamespace: r
|
|
1309
|
+
})), i.bindDataStore?.(e);
|
|
3914
1310
|
},
|
|
3915
|
-
onActivate: (
|
|
3916
|
-
let
|
|
3917
|
-
|
|
3918
|
-
provider:
|
|
3919
|
-
bucket:
|
|
3920
|
-
refStore:
|
|
3921
|
-
}),
|
|
1311
|
+
onActivate: (t) => U.sync(() => {
|
|
1312
|
+
let n = !!o || !!w.read("STORAGE_CDN_URL", e.cdnBaseUrl);
|
|
1313
|
+
t.logger.info(`storage: provider=${i.name} presign=${i.presigns ? "yes" : "no"} publicUrl=${n ? "yes" : "no"} transforms=yes`, {
|
|
1314
|
+
provider: i.name,
|
|
1315
|
+
bucket: a,
|
|
1316
|
+
refStore: f ? "memory" : "custom"
|
|
1317
|
+
}), i.name === "memory" && process.env.NODE_ENV !== "test" && t.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.)"), !n && !i.presigns && t.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.");
|
|
3922
1318
|
}),
|
|
3923
|
-
onDeactivate: () =>
|
|
1319
|
+
onDeactivate: () => U.void
|
|
3924
1320
|
});
|
|
3925
1321
|
};
|
|
3926
1322
|
//#endregion
|
|
3927
|
-
export {
|
|
1323
|
+
export { i as STORAGE_BLOBS_TABLE, a as STORAGE_GRANTS_TABLE, t as STORAGE_REFERENCE_CATALOGUE_TABLE, o as STORAGE_REFS_TABLE, s as STORAGE_USAGE_TABLE, te as StorageAccessDenied, p as StorageError, ne as StorageRejected, re as StorageScanRejected, m as StorageService, c as _voltroStorageBlobsTable, l as _voltroStorageGrantsTable, u as _voltroStorageRefsTable, d as _voltroStorageUsageTable, dt as appStorageProvider, Ye as assetRef, g as assignStorageObjectNamespacesInTransaction, f as assignStorageReferenceInstancesInTransaction, T as azureProvider, xe as buildStorageService, v as bytesToStream, I as checkLimits, Ge as clamavScanner, E as clearStorageBuffer, y as collectStream, b as concatBytes, ft as configuredStorageProvider, L as contentTypeAllowed, Se as dataStoreGrantStore, Ce as dataStoreRefStore, D as databaseProvider, Ze as decodeDataUri, $e as durabilityNotice, j as editImage, Ke as encodeInstream, n as ensureStorageReferenceCatalogue, z as fetchIngestBody, Je as ffmpegTranscoder, O as filesystemProvider, x as fromNodeReadable, S as getObjectStream, M as hashPassword, Ee as makeStorageObjectMetadata, we as memoryGrantStore, k as memoryProvider, B as memoryRefStore, qe as parseClamavResponse, se as parseTransformParams, et as pathDurability, Qe as putAvatar, ie as putObjectStream, ae as readStorageBuffer, V as refMatchesListQuery, _ as requireStorageObjectNamespaces, q as resolveStorageProvider, pe as resolveStorageSecret, A as s3Provider, ut as setActiveStorageProvider, me as signFinalizeTicket, he as signGrant, ge as signMultipartTicket, _e as signResumableTicket, N as signUploadTicket, R as sniffMatches, pt as storageEgressOf, vt as storageInstanceName, h as storageObjectLifecycleTables, e as storageObjectNamespace, bt as storagePlugin, De as storagePutIntentsTable, r as storageReferenceCatalogueTable, Te as storageServiceLayer, C as toNodeReadable, ce as transformCached, le as transformFallbackReason, ue as transformImage, ve as verifyFinalizeTicket, ye as verifyGrant, P as verifyMultipartTicket, fe as verifyPassword, be as verifyResumableTicket, F as verifyUploadTicket, Xe as withStorage };
|