@voltro/plugin-storage 0.85.0 → 0.87.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 +5987 -0
- package/README.md +77 -0
- package/THIRD-PARTY-NOTICES.md +860 -249
- package/dist/access.js +47 -0
- package/dist/assetRef.js +13 -0
- package/dist/avatar.js +39 -0
- package/dist/byteSecurity.d.ts +3 -0
- package/dist/byteSecurity.js +7 -0
- package/dist/connection.js +99 -0
- package/dist/constraints.js +93 -0
- package/dist/custody.js +132 -0
- package/dist/derivatives.js +30 -0
- package/dist/env.js +162 -0
- package/dist/grant.js +132 -0
- package/dist/index.d.ts +525 -203
- package/dist/index.js +765 -3196
- package/dist/ingest.js +87 -0
- package/dist/ingestPolicy.js +1 -0
- package/dist/metadataError.js +19 -0
- package/dist/objectAbandon.js +16 -0
- package/dist/objectLifecycle.js +243 -0
- package/dist/objectMetadata.js +308 -0
- package/dist/objectWriter.js +87 -0
- package/dist/pathDurability.js +16 -0
- package/dist/physicalReferences.js +54 -0
- package/dist/providers.js +638 -0
- package/dist/referenceCatalogue.js +31 -0
- package/dist/renditionProof.js +82 -0
- package/dist/retainedCapture.js +391 -0
- package/dist/retainedObjects.js +190 -0
- package/dist/rpc.d.ts +3 -15
- package/dist/rpc.js +3 -1
- package/dist/scanners.js +46 -0
- package/dist/server.d.ts +153 -0
- package/dist/server.js +4 -0
- package/dist/service.js +1418 -0
- package/dist/sourceIdentity.js +14 -0
- package/dist/sourcePin.js +35 -0
- package/dist/storageNamespaces.js +80 -0
- package/dist/storageNumbers.js +13 -0
- package/dist/storageObjectNamespaces.js +243 -0
- package/dist/storageReferenceInstances.js +52 -0
- package/dist/storageRequest.js +10 -0
- package/dist/storageRouting.js +46 -0
- package/dist/streamBridge.js +33 -0
- package/dist/table.js +54 -0
- package/dist/transcodeVideo.js +91 -0
- package/dist/transform.js +94 -0
- package/dist/transformCache.js +31 -0
- package/dist/types.d.ts +116 -134
- package/dist/types.js +14 -14
- package/package.json +17 -6
package/dist/index.js
CHANGED
|
@@ -1,2737 +1,128 @@
|
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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`,
|
|
1
|
+
import { appStorageRouter as e, makeStorageDestinationRouter as t } from "./storageRouting.js";
|
|
2
|
+
import { storageByteSecurityHeaders as n } from "./byteSecurity.js";
|
|
3
|
+
import { existingFilesystemObjectNamespace as r, storageObjectNamespace as i } from "./storageNamespaces.js";
|
|
4
|
+
import { STORAGE_REFERENCE_CATALOGUE_TABLE as a, ensureStorageReferenceCatalogue as o, storageReferenceCatalogueTable as s } from "./referenceCatalogue.js";
|
|
5
|
+
import { STORAGE_BLOBS_TABLE as c, STORAGE_GRANTS_TABLE as l, STORAGE_REFS_TABLE as u, STORAGE_USAGE_TABLE as d, _voltroStorageBlobsTable as ee, _voltroStorageGrantsTable as f, _voltroStorageRefsTable as p, _voltroStorageUsageTable as m } from "./table.js";
|
|
6
|
+
import { assignStorageReferenceInstancesInTransaction as h, requireStorageReferenceOwnership as te } from "./storageReferenceInstances.js";
|
|
7
|
+
import { StorageAccessDenied as ne, StorageError as g, StorageRejected as re, StorageScanRejected as ie, StorageService as _, storageAddressIdentity as ae, storageRefAddress as v } from "./types.js";
|
|
8
|
+
import { storageObjectLifecycleTables as oe } from "./objectLifecycle.js";
|
|
9
|
+
import { assignStorageObjectNamespacesInTransaction as y, requireStorageObjectNamespaces as se } from "./storageObjectNamespaces.js";
|
|
10
|
+
import { bytesToStream as b, collectStream as x, concatBytes as S, fromNodeReadable as C, getObjectStream as ce, putObjectStream as w, toNodeReadable as T } from "./streamBridge.js";
|
|
11
|
+
import { storageEnv as E } from "./env.js";
|
|
12
|
+
import { azureProvider as D, clearStorageBuffer as O, databaseProvider as k, filesystemProvider as A, memoryProvider as j, memoryProviderWithState as M, readStorageBuffer as N, s3Provider as P } from "./providers.js";
|
|
13
|
+
import { createTransformCache as le } from "./transformCache.js";
|
|
14
|
+
import { editImage as ue, parseTransformParams as de, transformCached as fe, transformFallbackReason as pe, transformImage as me, transformKey as he } from "./transform.js";
|
|
15
|
+
import { hashPassword as F, verifyPassword as I } from "./access.js";
|
|
16
|
+
import { resolveStorageSecret as L, signFinalizeTicket as ge, signGrant as R, signMultipartTicket as _e, signResumableTicket as ve, signUploadTicket as z, verifyFinalizeTicket as ye, verifyGrant as be, verifyMultipartTicket as B, verifyResumableTicket as xe, verifyUploadTicket as Se } from "./grant.js";
|
|
17
|
+
import { checkLimits as V, contentTypeAllowed as Ce, sniffMatches as we } from "./constraints.js";
|
|
18
|
+
import { fetchIngestBody as H } from "./ingest.js";
|
|
19
|
+
import { buildStorageService as Te, dataStoreGrantStore as Ee, dataStoreRefStore as De, memoryGrantStore as Oe, memoryRefStore as ke, refMatchesListQuery as Ae, storageServiceLayer as je } from "./service.js";
|
|
20
|
+
import { makeStorageObjectMetadata as Me, storagePutIntentsTable as Ne } from "./objectMetadata.js";
|
|
21
|
+
import { retainedCaptureTables as Pe } from "./retainedCapture.js";
|
|
22
|
+
import { StorageCustody as Fe, storageCustodyLayer as Ie } from "./custody.js";
|
|
23
|
+
import { abortMultipartUploadDescriptor as Le, beginMultipartUploadDescriptor as Re, beginResumableUploadDescriptor as ze, completeMultipartUploadDescriptor as Be, finalizeUploadDescriptor as Ve, ingestUrlDescriptor as He, listGrantsDescriptor as Ue, listRefsDescriptor as We, mintPresignedUploadDescriptor as Ge, mintUploadTicketDescriptor as Ke, mintUploadUrlDescriptor as qe, mintUrlDescriptor as Je, revokeDescriptor as Ye, shareDescriptor as Xe, signMultipartPartDescriptor as Ze, storageRpcClientImports as Qe, uploadDescriptor as $e } from "./rpc.js";
|
|
24
|
+
import { clamavScanner as U, encodeInstream as W, parseClamavResponse as G } from "./scanners.js";
|
|
25
|
+
import { ffmpegTranscoder as K } from "./transcodeVideo.js";
|
|
26
|
+
import { assetRef as et, withStorage as tt } from "./assetRef.js";
|
|
27
|
+
import { decodeDataUri as nt, putAvatar as rt } from "./avatar.js";
|
|
28
|
+
import { durabilityNotice as it, pathDurability as at } from "./pathDurability.js";
|
|
29
|
+
import { connectStorage as ot, withStorageKeyPrefix as st } from "./connection.js";
|
|
30
|
+
import { StorageAddress as ct, forwardStorageProvider as lt, isStorageKey as ut, storageAddressIdentity as dt } from "@voltro/kv/storage";
|
|
31
|
+
import { Effect as q, Layer as ft, Schema as J, Stream as pt } from "effect";
|
|
32
|
+
import { createHash as mt, randomUUID as ht } from "node:crypto";
|
|
33
|
+
import { authoredError as gt } from "@voltro/database";
|
|
34
|
+
import { processIdentity as _t } from "@voltro/protocol/identity";
|
|
35
|
+
import { StorageAccessPolicySchema as vt, definePlugin as yt, effectiveScopes as bt, pluginInstanceName as xt } from "@voltro/protocol";
|
|
36
|
+
import { readCookie as St, resolveSessionSecrets as Ct, verifySessionKeyed as wt } from "@voltro/protocol/session";
|
|
37
|
+
import { ifRangeAllowsRange as Tt, parseByteRange as Et } from "@voltro/runtime/http-range";
|
|
38
|
+
//#region src/index.ts
|
|
39
|
+
var Dt = E.read("VOLTRO_SESSION_COOKIE") ?? "voltro:session", Ot = (e) => {
|
|
40
|
+
let t = e.filter((e) => e.capabilities?.storageProvider !== void 0);
|
|
41
|
+
if (t.length > 1) throw new g({
|
|
42
|
+
provider: "storage",
|
|
43
|
+
message: "Storage destination is ambiguous; installed instances: " + t.map((e) => e.name).sort().join(", "),
|
|
241
44
|
transient: !1
|
|
242
45
|
});
|
|
243
|
-
return
|
|
244
|
-
},
|
|
245
|
-
let
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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",
|
|
46
|
+
return t.length === 1 ? t[0].capabilities.storageProvider() : void 0;
|
|
47
|
+
}, kt = (e) => {
|
|
48
|
+
let t = Ot(e);
|
|
49
|
+
return t === void 0 || Y.has(t) ? void 0 : t;
|
|
50
|
+
}, Y = /* @__PURE__ */ new WeakSet(), At = (e) => {
|
|
51
|
+
if (Y.has(e) && process.env.NODE_ENV === "production") throw gt("storage: no provider is configured in this production process — `storagePlugin()` has no `provider` and STORAGE_PROVIDER is unset, so storage would fall back to process memory, which no other replica or later process can see. Set STORAGE_PROVIDER (s3 | minio | azure | filesystem | database) for every process that reaches storage, migrate jobs included, or pass `provider: 'memory'` to choose memory deliberately.");
|
|
52
|
+
return e;
|
|
53
|
+
}, jt = (e) => {
|
|
54
|
+
let t = Ot(e);
|
|
55
|
+
if (t === void 0) throw new g({
|
|
56
|
+
provider: "storage",
|
|
57
|
+
message: "This app has no configured storage destination",
|
|
1095
58
|
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
59
|
});
|
|
1156
|
-
return
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
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
|
-
}
|
|
60
|
+
return At(t);
|
|
61
|
+
}, X = (e) => {
|
|
62
|
+
if (e.provider && typeof e.provider == "object") return e.provider;
|
|
63
|
+
let t = e.provider ?? E.read("STORAGE_PROVIDER");
|
|
64
|
+
if (t === void 0) {
|
|
65
|
+
let t = X({
|
|
66
|
+
...e,
|
|
67
|
+
provider: "memory"
|
|
2587
68
|
});
|
|
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";
|
|
69
|
+
return Y.add(t), t;
|
|
2683
70
|
}
|
|
2684
|
-
|
|
2685
|
-
|
|
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) => {
|
|
2691
|
-
if (e.provider && typeof e.provider == "object") return e.provider;
|
|
2692
|
-
let t = (e.provider ?? U.read("STORAGE_PROVIDER") ?? "memory").toLowerCase(), n = U.read("S3_BUCKET", e.bucket) ?? U.read("STORAGE_BUCKET") ?? "voltro";
|
|
2693
|
-
switch (t) {
|
|
71
|
+
let n = t.toLowerCase(), r = E.read("S3_BUCKET", e.bucket) ?? E.read("STORAGE_BUCKET") ?? "voltro";
|
|
72
|
+
switch (n) {
|
|
2694
73
|
case "s3":
|
|
2695
74
|
case "minio": {
|
|
2696
|
-
let
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
...r ? { region: r } : {},
|
|
75
|
+
let t = E.read("S3_REGION", e.region) ?? E.read("AWS_REGION"), i = E.read("S3_ENDPOINT", e.endpoint) ?? E.read("MINIO_ENDPOINT"), a = E.read("S3_ACCESS_KEY_ID", e.accessKeyId) ?? E.read("AWS_ACCESS_KEY_ID"), o = E.read("S3_SECRET_ACCESS_KEY", e.secretAccessKey) ?? E.read("AWS_SECRET_ACCESS_KEY"), s = E.read("STORAGE_CDN_URL", e.cdnBaseUrl), c = {
|
|
76
|
+
bucket: r,
|
|
77
|
+
name: n,
|
|
78
|
+
...t ? { region: t } : {},
|
|
2701
79
|
...i ? { endpoint: i } : {},
|
|
2702
80
|
...a ? { accessKeyId: a } : {},
|
|
2703
81
|
...o ? { secretAccessKey: o } : {},
|
|
2704
82
|
...s ? { cdnBaseUrl: s } : {},
|
|
2705
83
|
...e.publicAcl === void 0 ? {} : { publicAcl: e.publicAcl },
|
|
2706
|
-
...
|
|
2707
|
-
}
|
|
84
|
+
...n === "minio" || E.read("S3_FORCE_PATH_STYLE") === "1" ? { forcePathStyle: !0 } : {}
|
|
85
|
+
};
|
|
86
|
+
return P(c);
|
|
2708
87
|
}
|
|
2709
88
|
case "azure": {
|
|
2710
|
-
let t =
|
|
2711
|
-
|
|
2712
|
-
container: U.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? n,
|
|
89
|
+
let t = E.read("AZURE_STORAGE_ACCOUNT", e.accountName), n = E.read("AZURE_STORAGE_KEY", e.accountKey), i = E.read("AZURE_STORAGE_CONNECTION_STRING", e.connectionString), a = E.read("AZURE_STORAGE_ENDPOINT", e.endpoint), o = E.read("STORAGE_CDN_URL", e.cdnBaseUrl), s = {
|
|
90
|
+
container: E.read("AZURE_STORAGE_CONTAINER", e.bucket) ?? r,
|
|
2713
91
|
...t ? { accountName: t } : {},
|
|
2714
|
-
...
|
|
92
|
+
...n ? { accountKey: n } : {},
|
|
2715
93
|
...i ? { connectionString: i } : {},
|
|
2716
94
|
...a ? { endpoint: a } : {},
|
|
2717
95
|
...o ? { cdnBaseUrl: o } : {}
|
|
2718
|
-
}
|
|
96
|
+
};
|
|
97
|
+
return D(s);
|
|
2719
98
|
}
|
|
2720
|
-
case "database": return
|
|
2721
|
-
case "filesystem": return
|
|
2722
|
-
|
|
99
|
+
case "database": return k();
|
|
100
|
+
case "filesystem": return A({ root: E.read("STORAGE_ROOT", e.root) ?? ".voltro-storage" });
|
|
101
|
+
case "memory": return M(/* @__PURE__ */ new Map());
|
|
102
|
+
default: throw new g({
|
|
103
|
+
provider: "storage",
|
|
104
|
+
message: "Unknown storage provider; choose memory, filesystem, database, s3, minio or azure",
|
|
105
|
+
transient: !1
|
|
106
|
+
});
|
|
2723
107
|
}
|
|
2724
|
-
},
|
|
2725
|
-
let t = "stored files (uploads, renditions) and their reads"
|
|
108
|
+
}, Mt = (e) => {
|
|
109
|
+
let t = "stored files (uploads, renditions) and their reads";
|
|
110
|
+
if (e.connection !== void 0) return [{
|
|
111
|
+
destination: `runtime:the app-owned ${e.connection} connection`,
|
|
112
|
+
purpose: t,
|
|
113
|
+
data: ["files"],
|
|
114
|
+
disable: "remove the storage connection binding"
|
|
115
|
+
}];
|
|
116
|
+
let n = "provider 'database' or 'filesystem' keeps the bytes inside the installation";
|
|
2726
117
|
if (e.provider && typeof e.provider == "object") return [{
|
|
2727
118
|
destination: `runtime:the '${e.provider.name}' storage provider`,
|
|
2728
119
|
purpose: t,
|
|
2729
120
|
data: ["files"],
|
|
2730
121
|
disable: n
|
|
2731
122
|
}];
|
|
2732
|
-
let r = (e.provider ??
|
|
123
|
+
let r = (e.provider ?? E.read("STORAGE_PROVIDER") ?? "memory").toLowerCase();
|
|
2733
124
|
if (r === "s3" || r === "minio") {
|
|
2734
|
-
let r =
|
|
125
|
+
let r = E.read("S3_ENDPOINT", e.endpoint) ?? E.read("MINIO_ENDPOINT"), i = E.read("S3_REGION", e.region) ?? E.read("AWS_REGION") ?? "us-east-1";
|
|
2735
126
|
return [{
|
|
2736
127
|
destination: r ?? `s3.${i}.amazonaws.com`,
|
|
2737
128
|
purpose: t,
|
|
@@ -2740,7 +131,7 @@ var qn = () => _e({
|
|
|
2740
131
|
}];
|
|
2741
132
|
}
|
|
2742
133
|
if (r === "azure") {
|
|
2743
|
-
let r =
|
|
134
|
+
let r = E.read("AZURE_STORAGE_ENDPOINT", e.endpoint), i = E.read("AZURE_STORAGE_ACCOUNT", e.accountName);
|
|
2744
135
|
return [{
|
|
2745
136
|
destination: r ?? (i === void 0 ? "runtime:the Azure storage connection string" : `${i}.blob.core.windows.net`),
|
|
2746
137
|
purpose: t,
|
|
@@ -2749,11 +140,11 @@ var qn = () => _e({
|
|
|
2749
140
|
}];
|
|
2750
141
|
}
|
|
2751
142
|
return [];
|
|
2752
|
-
},
|
|
143
|
+
}, Nt = (e) => {
|
|
2753
144
|
if (e !== void 0) return e;
|
|
2754
|
-
let t =
|
|
145
|
+
let t = E.read("STORAGE_ALLOWED_ORIGINS");
|
|
2755
146
|
return t ? t.trim() === "*" ? "*" : t.split(",").map((e) => e.trim()).filter(Boolean) : [];
|
|
2756
|
-
},
|
|
147
|
+
}, Pt = (e, t) => {
|
|
2757
148
|
if (!e || t !== "*" && !t.includes(e)) return {};
|
|
2758
149
|
let n = {
|
|
2759
150
|
"access-control-allow-origin": t === "*" ? "*" : e,
|
|
@@ -2763,7 +154,7 @@ var qn = () => _e({
|
|
|
2763
154
|
vary: "Origin"
|
|
2764
155
|
};
|
|
2765
156
|
return t !== "*" && (n["access-control-allow-credentials"] = "true"), n;
|
|
2766
|
-
},
|
|
157
|
+
}, Ft = (e) => ({
|
|
2767
158
|
id: e.id,
|
|
2768
159
|
tenantId: e.tenantId,
|
|
2769
160
|
ownerId: e.ownerId,
|
|
@@ -2786,29 +177,29 @@ var qn = () => _e({
|
|
|
2786
177
|
caption: e.caption ?? null,
|
|
2787
178
|
derivedFrom: e.derivedFrom ?? null,
|
|
2788
179
|
kind: e.kind ?? null
|
|
2789
|
-
}),
|
|
180
|
+
}), It = () => new g({
|
|
2790
181
|
provider: "storage",
|
|
2791
182
|
message: "not permitted to administer sharing for this object",
|
|
2792
183
|
transient: !1,
|
|
2793
184
|
status: 403
|
|
2794
|
-
}),
|
|
185
|
+
}), Lt = (e, t, n) => {
|
|
2795
186
|
let r = n.request.subject;
|
|
2796
|
-
return (r
|
|
187
|
+
return bt(r).includes("admin:full") ? q.void : e.head(t, { tenantId: r.tenantId ?? null }).pipe(q.catch(() => q.fail(It())), q.flatMap((e) => {
|
|
2797
188
|
let t = e?.ownerId;
|
|
2798
|
-
return t != null && t === r.id ?
|
|
189
|
+
return t != null && t === r.id ? q.void : q.fail(It());
|
|
2799
190
|
}));
|
|
2800
|
-
},
|
|
191
|
+
}, Rt = () => new g({
|
|
2801
192
|
provider: "storage",
|
|
2802
193
|
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
194
|
transient: !1,
|
|
2804
195
|
status: 401
|
|
2805
|
-
}),
|
|
196
|
+
}), Z = (e, t) => {
|
|
2806
197
|
let n = e.request.subject.id ?? null, r = e.request.subject.tenantId ?? null;
|
|
2807
|
-
return n === null && !t ?
|
|
198
|
+
return n === null && !t ? q.fail(Rt()) : q.succeed({
|
|
2808
199
|
id: n,
|
|
2809
200
|
tenantId: r
|
|
2810
201
|
});
|
|
2811
|
-
},
|
|
202
|
+
}, zt = (e, t) => e !== null && e !== (t ?? null), Bt = (e) => ({
|
|
2812
203
|
id: e.id,
|
|
2813
204
|
refId: e.refId,
|
|
2814
205
|
principalType: e.principalType,
|
|
@@ -2817,143 +208,208 @@ var qn = () => _e({
|
|
|
2817
208
|
createdAt: e.createdAt.toISOString(),
|
|
2818
209
|
expiresAt: e.expiresAt ? e.expiresAt.toISOString() : null,
|
|
2819
210
|
createdBy: e.createdBy
|
|
2820
|
-
}),
|
|
2821
|
-
base:
|
|
211
|
+
}), Q = "@voltro/plugin-storage", Vt = (e = {}) => xt({
|
|
212
|
+
base: Q,
|
|
2822
213
|
alias: e.alias,
|
|
2823
214
|
instance: e.name
|
|
2824
|
-
}),
|
|
2825
|
-
let
|
|
2826
|
-
base:
|
|
2827
|
-
alias:
|
|
2828
|
-
instance:
|
|
2829
|
-
}),
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
215
|
+
}), Ht = (e) => e.reason === "too-large" ? 413 : e.reason === "operation-identity-reused" || e.reason === "operation-store-unbound" || e.reason === "claim-not-held" ? 409 : 415, Ut = (e = {}) => {
|
|
216
|
+
let r = xt({
|
|
217
|
+
base: Q,
|
|
218
|
+
alias: e.alias,
|
|
219
|
+
instance: e.name
|
|
220
|
+
}), i = r === Q ? "/_voltro/storage" : `/_voltro/storage/i/${Buffer.from(r).toString("hex")}`, a = [
|
|
221
|
+
"provider",
|
|
222
|
+
"bucket",
|
|
223
|
+
"region",
|
|
224
|
+
"endpoint",
|
|
225
|
+
"accessKeyId",
|
|
226
|
+
"secretAccessKey",
|
|
227
|
+
"root",
|
|
228
|
+
"accountName",
|
|
229
|
+
"accountKey",
|
|
230
|
+
"connectionString",
|
|
231
|
+
"cdnBaseUrl"
|
|
232
|
+
].some((t) => e[t] !== void 0);
|
|
233
|
+
if (e.connection !== void 0 && a) throw Error("Storage selects either a named connection or direct transport options");
|
|
234
|
+
let s = e.connection !== void 0 || !a;
|
|
235
|
+
if (e.connection === void 0 && typeof e.provider != "object" && ![
|
|
236
|
+
"memory",
|
|
237
|
+
"filesystem",
|
|
238
|
+
"database",
|
|
239
|
+
"s3",
|
|
240
|
+
"minio",
|
|
241
|
+
"azure"
|
|
242
|
+
].includes((e.provider ?? E.read("STORAGE_PROVIDER") ?? "memory").toLowerCase())) throw new g({
|
|
243
|
+
provider: "storage",
|
|
244
|
+
message: "Unknown storage provider; choose memory, filesystem, database, s3, minio or azure",
|
|
245
|
+
transient: !1
|
|
246
|
+
});
|
|
247
|
+
let c = E.read("S3_BUCKET", e.bucket) ?? E.read("STORAGE_BUCKET") ?? "voltro", l = a ? X(e) : void 0, u = () => (l === void 0 && (l = X(e)), l), d = l, ee = e.connection, f, p = !1, m = s ? lt(() => {
|
|
248
|
+
if (d === void 0) {
|
|
249
|
+
if (ee !== void 0) throw new g({
|
|
250
|
+
provider: "storage",
|
|
251
|
+
message: "Named storage requires a bound tenant-aware destination",
|
|
252
|
+
transient: !1
|
|
253
|
+
});
|
|
254
|
+
d = u();
|
|
255
|
+
}
|
|
256
|
+
return d;
|
|
257
|
+
}) : d;
|
|
258
|
+
e.provider === void 0 && e.connection === void 0 && E.read("STORAGE_PROVIDER") === void 0 && Y.add(m);
|
|
259
|
+
let h = e.connection ?? c, _ = t({
|
|
260
|
+
selected: () => h,
|
|
261
|
+
directDestination: e.connection === void 0 ? c : void 0,
|
|
262
|
+
directProvider: u,
|
|
263
|
+
registry: () => f
|
|
264
|
+
}), oe = (e, t) => q.gen(function* () {
|
|
265
|
+
if (f = e, ee = t, p = !1, h = t ?? c, t === void 0) return;
|
|
266
|
+
if (Y.delete(m), e === void 0) throw Error("Named storage requires the app connection registry");
|
|
267
|
+
let n = yield* e.validate(t);
|
|
268
|
+
p = n.tenantScoped, d = n.tenantScoped ? void 0 : yield* e.storage(t);
|
|
269
|
+
}), y = E.read("VOLTRO_PUBLIC_URL", e.publicBaseUrl), b = Nt(e.allowedOrigins), x = e.limits?.maxBytes, S = e.anonymousUploads === !0, C = 5242880, ce = 21600, w = e.refStore === void 0 || e.refStore === "memory", T = e.grantStore === void 0 || e.grantStore === "memory", D = (t, n) => q.gen(function* () {
|
|
270
|
+
let r = (e) => J.decodeUnknownEffect(vt)(e, { onExcessProperty: "error" }).pipe(q.mapError(() => new g({
|
|
2833
271
|
provider: "storage",
|
|
2834
272
|
message: "Invalid upload access policy",
|
|
2835
273
|
transient: !1,
|
|
2836
274
|
status: 400
|
|
2837
|
-
}))),
|
|
2838
|
-
if (
|
|
275
|
+
}))), i = t.access === void 0 ? void 0 : yield* r(t.access), a = t.visibility ?? "private";
|
|
276
|
+
if (i !== void 0 && a === "public") return yield* q.fail(new g({
|
|
2839
277
|
provider: "storage",
|
|
2840
278
|
message: "An access policy requires a private upload",
|
|
2841
279
|
transient: !1,
|
|
2842
280
|
status: 400
|
|
2843
281
|
}));
|
|
2844
|
-
let
|
|
2845
|
-
if (
|
|
282
|
+
let o = e.uploadAccess;
|
|
283
|
+
if (i !== void 0 && typeof o != "function") return yield* q.fail(new g({
|
|
2846
284
|
provider: "storage",
|
|
2847
285
|
message: "Requested upload access requires an uploadAccess authorization function on storagePlugin",
|
|
2848
286
|
transient: !1,
|
|
2849
287
|
status: 403
|
|
2850
288
|
}));
|
|
2851
|
-
let
|
|
289
|
+
let s = typeof o == "function" ? yield* o({
|
|
2852
290
|
subject: n,
|
|
2853
|
-
requested:
|
|
2854
|
-
visibility:
|
|
2855
|
-
contentType:
|
|
2856
|
-
}) :
|
|
2857
|
-
return
|
|
291
|
+
requested: i,
|
|
292
|
+
visibility: a,
|
|
293
|
+
contentType: t.contentType
|
|
294
|
+
}) : a === "private" ? o : void 0, c = s === void 0 ? void 0 : yield* r(s);
|
|
295
|
+
return a === "public" ? c !== void 0 && c.length > 0 ? yield* q.fail(new g({
|
|
2858
296
|
provider: "storage",
|
|
2859
297
|
message: "A public upload cannot carry an access policy",
|
|
2860
298
|
transient: !1,
|
|
2861
299
|
status: 400
|
|
2862
|
-
})) : {} :
|
|
2863
|
-
}),
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
300
|
+
})) : {} : c === void 0 ? {} : { access: c };
|
|
301
|
+
}), O = { current: w ? ke() : e.refStore }, k = { current: T ? Oe() : e.grantStore }, A = { current: void 0 }, j = { current: void 0 }, M = {
|
|
302
|
+
get catalogueId() {
|
|
303
|
+
return O.current.catalogueId;
|
|
304
|
+
},
|
|
305
|
+
insert: (e) => O.current.insert(e),
|
|
306
|
+
getById: (e) => O.current.getById(e),
|
|
307
|
+
delete: (e) => O.current.delete(e),
|
|
308
|
+
statistics: () => O.current.statistics(),
|
|
309
|
+
listRecent: (e) => O.current.listRecent(e),
|
|
310
|
+
countByAddress: (e) => O.current.countByAddress(e),
|
|
311
|
+
listObjectReferences: () => O.current.listObjectReferences(),
|
|
312
|
+
hasObjectReservation: (e, t) => O.current.hasObjectReservation?.(e, t) ?? q.succeed(!1),
|
|
313
|
+
usageByTenant: (e) => O.current.usageByTenant(e),
|
|
314
|
+
consumeUsage: (e, t, n) => O.current.consumeUsage(e, t, n),
|
|
315
|
+
releaseUsage: (e, t) => O.current.releaseUsage(e, t),
|
|
316
|
+
listByDerivedFrom: (e) => O.current.listByDerivedFrom(e),
|
|
317
|
+
listRefs: (e) => O.current.listRefs(e),
|
|
2875
318
|
get setVisibility() {
|
|
2876
|
-
return
|
|
319
|
+
return O.current.setVisibility;
|
|
2877
320
|
},
|
|
2878
|
-
get
|
|
2879
|
-
return
|
|
321
|
+
get countPublicByAddress() {
|
|
322
|
+
return O.current.countPublicByAddress;
|
|
2880
323
|
}
|
|
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
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
}
|
|
2919
|
-
}
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
324
|
+
}, N = {
|
|
325
|
+
insert: (e) => k.current.insert(e),
|
|
326
|
+
delete: (e) => k.current.delete(e),
|
|
327
|
+
getById: (e) => k.current.getById(e),
|
|
328
|
+
listByRef: (e) => k.current.listByRef(e),
|
|
329
|
+
deleteByRef: (e) => k.current.deleteByRef(e)
|
|
330
|
+
}, P, ue = {
|
|
331
|
+
httpPath: i,
|
|
332
|
+
storageInstance: r,
|
|
333
|
+
provider: m,
|
|
334
|
+
refStore: M,
|
|
335
|
+
grantStore: N,
|
|
336
|
+
get bucket() {
|
|
337
|
+
return h;
|
|
338
|
+
},
|
|
339
|
+
destinations: _,
|
|
340
|
+
resolveObjectReference: (e) => P !== void 0 && e.storageInstance !== void 0 ? P({
|
|
341
|
+
storageInstance: e.storageInstance,
|
|
342
|
+
address: v(e)
|
|
343
|
+
}) : _.resolve(v(e)),
|
|
344
|
+
...e.tenantPrefix === void 0 ? {} : { tenantPrefix: e.tenantPrefix },
|
|
345
|
+
...e.attempts === void 0 ? {} : { attempts: e.attempts },
|
|
346
|
+
...e.urlExpiresInSec === void 0 ? {} : { urlExpiresInSec: e.urlExpiresInSec },
|
|
347
|
+
...e.access === void 0 ? {} : { access: e.access },
|
|
348
|
+
...e.limits === void 0 ? {} : { limits: e.limits },
|
|
349
|
+
...e.ingest === void 0 ? {} : { ingest: e.ingest },
|
|
350
|
+
...e.scan === void 0 ? {} : { scan: e.scan },
|
|
351
|
+
...e.videoProbe === void 0 ? {} : { videoProbe: e.videoProbe },
|
|
352
|
+
...e.transcode === void 0 ? {} : { transcode: e.transcode },
|
|
353
|
+
...e.autoTranscode === void 0 ? {} : { autoTranscode: e.autoTranscode },
|
|
354
|
+
...y ? { publicBaseUrl: y } : {},
|
|
355
|
+
...e.normalizeImages === void 0 ? {} : { normalizeImages: e.normalizeImages },
|
|
356
|
+
...e.quota === void 0 ? {} : { quota: e.quota },
|
|
357
|
+
objects: () => A.current
|
|
358
|
+
}, fe = ft.merge(je(ue), Ie({
|
|
359
|
+
selection: {
|
|
360
|
+
...e.alias === void 0 ? {} : { alias: e.alias },
|
|
361
|
+
...e.name === void 0 ? {} : { name: e.name }
|
|
362
|
+
},
|
|
363
|
+
bucket: h,
|
|
364
|
+
provider: m,
|
|
365
|
+
store: () => j.current,
|
|
366
|
+
...e.quota === void 0 ? {} : { quota: e.quota }
|
|
367
|
+
})), F = Te(ue), I = (e) => F.uploadTicketScope({
|
|
368
|
+
tenantId: e.tenant,
|
|
369
|
+
destination: e.destination
|
|
370
|
+
}).pipe(q.flatMap((t) => t === e.writeScope ? q.void : q.fail(new g({
|
|
371
|
+
provider: "storage",
|
|
372
|
+
message: "Upload ticket belongs to another storage destination",
|
|
373
|
+
transient: !1,
|
|
374
|
+
status: 409
|
|
375
|
+
})))), L = (e, t) => q.runPromise(I(e).pipe(q.match({
|
|
376
|
+
onSuccess: () => null,
|
|
377
|
+
onFailure: (e) => ({
|
|
378
|
+
status: e.status ?? 503,
|
|
379
|
+
body: e.status === 409 ? e.message : "Storage upload destination could not be checked",
|
|
380
|
+
contentType: "text/plain",
|
|
381
|
+
headers: t
|
|
382
|
+
})
|
|
383
|
+
}))), R = `${i}/`, V = (e) => q.runPromise(e.pipe(q.catch(() => q.succeed(null)))), Ce = e.publicCacheSeconds === void 0 ? "public, max-age=31536000, immutable" : `public, max-age=${Math.max(0, Math.floor(e.publicCacheSeconds))}`, we = le(), H = async (e, t, r, i, a) => {
|
|
384
|
+
if (r) {
|
|
385
|
+
let i, a = await we.getOrCreate(he(JSON.stringify([
|
|
386
|
+
ae(v(e)),
|
|
387
|
+
e.id,
|
|
388
|
+
e.checksum
|
|
389
|
+
]), e.contentType, r), async () => {
|
|
390
|
+
let t = await V(F.get(e.id));
|
|
391
|
+
return t ? (i = t.bytes, me(t.bytes, e.contentType, r)) : null;
|
|
2936
392
|
}).catch(() => null);
|
|
2937
|
-
if (!
|
|
393
|
+
if (!a && i === void 0 && (i = (await V(F.get(e.id)))?.bytes), !a && i === void 0) return {
|
|
2938
394
|
status: 404,
|
|
2939
395
|
body: "not found",
|
|
2940
396
|
contentType: "text/plain"
|
|
2941
397
|
};
|
|
2942
|
-
let
|
|
398
|
+
let o = a ? a.bytes : i, s = a ? a.contentType : e.contentType, c = await pe(e.contentType, a !== null);
|
|
2943
399
|
return {
|
|
2944
400
|
status: 200,
|
|
2945
|
-
body:
|
|
2946
|
-
contentType:
|
|
401
|
+
body: o,
|
|
402
|
+
contentType: s,
|
|
2947
403
|
headers: {
|
|
2948
|
-
...
|
|
404
|
+
...n(s),
|
|
2949
405
|
"cache-control": t,
|
|
2950
406
|
"accept-ranges": "none",
|
|
2951
|
-
...
|
|
407
|
+
...c === null ? {} : { "x-voltro-transform": `original; reason=${c}` }
|
|
2952
408
|
}
|
|
2953
409
|
};
|
|
2954
410
|
}
|
|
2955
|
-
let
|
|
2956
|
-
if (
|
|
411
|
+
let o = Tt(a, {}) ? Et(i, e.size) : { _tag: "ignored" };
|
|
412
|
+
if (o._tag === "unsatisfiable") return {
|
|
2957
413
|
status: 416,
|
|
2958
414
|
body: "range not satisfiable",
|
|
2959
415
|
contentType: "text/plain",
|
|
@@ -2962,17 +418,20 @@ var qn = () => _e({
|
|
|
2962
418
|
"accept-ranges": "bytes"
|
|
2963
419
|
}
|
|
2964
420
|
};
|
|
2965
|
-
if (
|
|
2966
|
-
let
|
|
2967
|
-
|
|
421
|
+
if (o._tag === "satisfiable") {
|
|
422
|
+
let r = await V(F.getRange(e.id, {
|
|
423
|
+
start: o.start,
|
|
424
|
+
endInclusive: o.end
|
|
425
|
+
}));
|
|
426
|
+
return r ? {
|
|
2968
427
|
status: 206,
|
|
2969
|
-
body:
|
|
428
|
+
body: r.bytes,
|
|
2970
429
|
contentType: e.contentType,
|
|
2971
430
|
headers: {
|
|
2972
|
-
...
|
|
431
|
+
...n(e.contentType),
|
|
2973
432
|
"cache-control": t,
|
|
2974
433
|
"accept-ranges": "bytes",
|
|
2975
|
-
"content-range": `bytes ${
|
|
434
|
+
"content-range": `bytes ${o.start}-${o.end}/${r.totalSize}`
|
|
2976
435
|
}
|
|
2977
436
|
} : {
|
|
2978
437
|
status: 404,
|
|
@@ -2980,69 +439,81 @@ var qn = () => _e({
|
|
|
2980
439
|
contentType: "text/plain"
|
|
2981
440
|
};
|
|
2982
441
|
}
|
|
2983
|
-
let
|
|
2984
|
-
return
|
|
442
|
+
let s = await V(F.getStream(e.id));
|
|
443
|
+
return s ? {
|
|
2985
444
|
status: 200,
|
|
2986
445
|
contentType: e.contentType,
|
|
2987
446
|
headers: {
|
|
2988
|
-
...
|
|
447
|
+
...n(e.contentType),
|
|
2989
448
|
"cache-control": t,
|
|
2990
449
|
"accept-ranges": "bytes"
|
|
2991
450
|
},
|
|
2992
451
|
byteStream: {
|
|
2993
452
|
contentLength: e.size,
|
|
2994
|
-
stream: () =>
|
|
453
|
+
stream: () => pt.toReadableStream(s.stream)
|
|
2995
454
|
}
|
|
2996
455
|
} : {
|
|
2997
456
|
status: 404,
|
|
2998
457
|
body: "not found",
|
|
2999
458
|
contentType: "text/plain"
|
|
3000
459
|
};
|
|
3001
|
-
},
|
|
3002
|
-
let t = e.path.startsWith(
|
|
460
|
+
}, Ae = async (e) => {
|
|
461
|
+
let t = e.path.startsWith(R) ? e.path.slice(R.length).split("/")[0] ?? "" : "";
|
|
3003
462
|
if (!t) return {
|
|
3004
463
|
status: 404,
|
|
3005
464
|
body: "not found",
|
|
3006
465
|
contentType: "text/plain"
|
|
3007
466
|
};
|
|
3008
|
-
let n = await
|
|
467
|
+
let n = await V(F.head(t));
|
|
3009
468
|
if (!n) return {
|
|
3010
469
|
status: 404,
|
|
3011
470
|
body: "not found",
|
|
3012
471
|
contentType: "text/plain"
|
|
3013
472
|
};
|
|
3014
|
-
let r =
|
|
3015
|
-
if (n.derivedFrom != null &&
|
|
473
|
+
let r = de(e.query), a = e.headers.range, o = e.headers["if-range"], s = n.derivedFrom == null ? null : await V(F.head(n.derivedFrom));
|
|
474
|
+
if (n.derivedFrom != null && s === null) return {
|
|
3016
475
|
status: 404,
|
|
3017
476
|
body: "not found",
|
|
3018
477
|
contentType: "text/plain"
|
|
3019
478
|
};
|
|
3020
|
-
if (n.visibility === "public" && (
|
|
3021
|
-
let e =
|
|
3022
|
-
|
|
479
|
+
if (n.visibility === "public" && (s === null || s.visibility === "public")) {
|
|
480
|
+
let e = await V(_.resolve(v(n)));
|
|
481
|
+
if (!e) return {
|
|
482
|
+
status: 503,
|
|
483
|
+
body: "storage destination unavailable",
|
|
484
|
+
contentType: "text/plain"
|
|
485
|
+
};
|
|
486
|
+
let t = e.publicUrl?.(n.key) ?? null;
|
|
487
|
+
return t && !r ? {
|
|
3023
488
|
status: 302,
|
|
3024
489
|
headers: {
|
|
3025
|
-
location:
|
|
490
|
+
location: t,
|
|
3026
491
|
"cache-control": "public, max-age=300"
|
|
3027
492
|
}
|
|
3028
|
-
} :
|
|
493
|
+
} : H(n, Ce, r, a, o);
|
|
3029
494
|
}
|
|
3030
|
-
let
|
|
3031
|
-
if (
|
|
3032
|
-
let e =
|
|
3033
|
-
|
|
495
|
+
let c = !1, l = e.query ? new URLSearchParams(e.query).get("t") : null;
|
|
496
|
+
if (l) {
|
|
497
|
+
let e = be(l);
|
|
498
|
+
c = !!e && (e.refId === t || s !== null && e.refId === s.id) && e.audience === i;
|
|
3034
499
|
}
|
|
3035
|
-
if (!
|
|
3036
|
-
let t =
|
|
3037
|
-
r && (
|
|
500
|
+
if (!c) {
|
|
501
|
+
let t = St(e.headers.cookie, Dt), r = t ? wt(t, Ct())?.subject ?? null : null;
|
|
502
|
+
r && (c = await V(F.checkAccess(n, r)) === !0);
|
|
3038
503
|
}
|
|
3039
|
-
if (!
|
|
504
|
+
if (!c) return {
|
|
3040
505
|
status: 403,
|
|
3041
506
|
body: "forbidden",
|
|
3042
507
|
contentType: "text/plain"
|
|
3043
508
|
};
|
|
3044
|
-
|
|
3045
|
-
|
|
509
|
+
let u = await V(_.resolve(v(n)));
|
|
510
|
+
if (!u) return {
|
|
511
|
+
status: 503,
|
|
512
|
+
body: "storage destination unavailable",
|
|
513
|
+
contentType: "text/plain"
|
|
514
|
+
};
|
|
515
|
+
if (u.presigns && !r) {
|
|
516
|
+
let e = await V(u.getUrl(n.key, 300));
|
|
3046
517
|
if (e && /^https?:/.test(e)) return {
|
|
3047
518
|
status: 302,
|
|
3048
519
|
headers: {
|
|
@@ -3051,12 +522,12 @@ var qn = () => _e({
|
|
|
3051
522
|
}
|
|
3052
523
|
};
|
|
3053
524
|
}
|
|
3054
|
-
return
|
|
3055
|
-
},
|
|
525
|
+
return H(n, "private, no-store", r, a, o);
|
|
526
|
+
}, Ne = {
|
|
3056
527
|
method: "GET",
|
|
3057
|
-
path:
|
|
528
|
+
path: i,
|
|
3058
529
|
handle: async (e) => {
|
|
3059
|
-
let t = await
|
|
530
|
+
let t = await Ae(e), n = Pt(e.headers.origin, b);
|
|
3060
531
|
return Object.keys(n).length === 0 ? t : {
|
|
3061
532
|
...t,
|
|
3062
533
|
headers: {
|
|
@@ -3065,12 +536,12 @@ var qn = () => _e({
|
|
|
3065
536
|
}
|
|
3066
537
|
};
|
|
3067
538
|
}
|
|
3068
|
-
},
|
|
539
|
+
}, Pe = {
|
|
3069
540
|
method: "*",
|
|
3070
|
-
path: `${
|
|
541
|
+
path: `${i}/upload`,
|
|
3071
542
|
originGuard: "exempt",
|
|
3072
543
|
handle: async (e) => {
|
|
3073
|
-
let t =
|
|
544
|
+
let t = Pt(e.headers.origin, b);
|
|
3074
545
|
if (e.method === "OPTIONS") return {
|
|
3075
546
|
status: 204,
|
|
3076
547
|
headers: t
|
|
@@ -3081,112 +552,113 @@ var qn = () => _e({
|
|
|
3081
552
|
contentType: "text/plain",
|
|
3082
553
|
headers: t
|
|
3083
554
|
};
|
|
3084
|
-
let n = e.query ? new URLSearchParams(e.query).get("ticket") : null,
|
|
3085
|
-
if (!
|
|
555
|
+
let n = e.query ? new URLSearchParams(e.query).get("ticket") : null, i = n ? Se(n) : null;
|
|
556
|
+
if (!i || i.instance !== r) return {
|
|
3086
557
|
status: 401,
|
|
3087
558
|
body: "invalid or expired upload ticket",
|
|
3088
559
|
contentType: "text/plain",
|
|
3089
560
|
headers: t
|
|
3090
561
|
};
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
body: "upload ticket belongs to another replica",
|
|
3094
|
-
contentType: "text/plain",
|
|
3095
|
-
headers: t
|
|
3096
|
-
};
|
|
562
|
+
let a = await L(i, t);
|
|
563
|
+
if (a) return a;
|
|
3097
564
|
if (e.rawBody.length === 0) return {
|
|
3098
565
|
status: 400,
|
|
3099
566
|
body: "empty body",
|
|
3100
567
|
contentType: "text/plain",
|
|
3101
568
|
headers: t
|
|
3102
569
|
};
|
|
3103
|
-
if (
|
|
570
|
+
if (i.max && e.rawBody.length > i.max) return {
|
|
3104
571
|
status: 413,
|
|
3105
572
|
body: "payload too large",
|
|
3106
573
|
contentType: "text/plain",
|
|
3107
574
|
headers: t
|
|
3108
575
|
};
|
|
3109
|
-
let
|
|
576
|
+
let o = await q.runPromise(F.put({
|
|
3110
577
|
bytes: e.rawBody,
|
|
3111
|
-
contentType:
|
|
3112
|
-
tenantId:
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
...
|
|
3117
|
-
...
|
|
3118
|
-
...
|
|
3119
|
-
...
|
|
3120
|
-
...
|
|
3121
|
-
...
|
|
3122
|
-
|
|
578
|
+
contentType: i.ct,
|
|
579
|
+
tenantId: i.tenant,
|
|
580
|
+
destination: i.destination,
|
|
581
|
+
ownerId: i.sub,
|
|
582
|
+
visibility: i.vis,
|
|
583
|
+
...i.access === void 0 ? {} : { access: i.access },
|
|
584
|
+
...i.operationId === void 0 ? {} : { operationId: i.operationId },
|
|
585
|
+
...i.key === void 0 ? {} : { key: i.key },
|
|
586
|
+
...i.folder === void 0 ? {} : { folder: i.folder },
|
|
587
|
+
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
588
|
+
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
589
|
+
...i.caption === void 0 ? {} : { caption: i.caption }
|
|
590
|
+
}).pipe(q.flatMap((e) => F.getUrl(e.id).pipe(q.map((t) => ({
|
|
3123
591
|
kind: "ok",
|
|
3124
592
|
ref: e,
|
|
3125
593
|
url: t
|
|
3126
|
-
})))),
|
|
3127
|
-
StorageRejected: (e) =>
|
|
594
|
+
})))), q.catchTags({
|
|
595
|
+
StorageRejected: (e) => q.succeed({
|
|
3128
596
|
kind: "rejected",
|
|
3129
|
-
status: e
|
|
597
|
+
status: Ht(e),
|
|
3130
598
|
detail: e.detail
|
|
3131
599
|
}),
|
|
3132
|
-
StorageScanRejected: (e) =>
|
|
600
|
+
StorageScanRejected: (e) => q.succeed({
|
|
3133
601
|
kind: "scan",
|
|
3134
602
|
threat: e.threat
|
|
3135
603
|
}),
|
|
3136
|
-
StorageError: (e) =>
|
|
604
|
+
StorageError: (e) => q.succeed({
|
|
3137
605
|
kind: "error",
|
|
3138
|
-
message: e.message
|
|
606
|
+
message: e.message,
|
|
607
|
+
status: e.status ?? 500
|
|
3139
608
|
})
|
|
3140
609
|
})));
|
|
3141
|
-
return
|
|
610
|
+
return o.kind === "ok" ? {
|
|
3142
611
|
status: 201,
|
|
3143
612
|
body: JSON.stringify({
|
|
3144
|
-
id:
|
|
3145
|
-
url:
|
|
3146
|
-
contentType:
|
|
3147
|
-
size:
|
|
613
|
+
id: o.ref.id,
|
|
614
|
+
url: o.url,
|
|
615
|
+
contentType: o.ref.contentType,
|
|
616
|
+
size: o.ref.size
|
|
3148
617
|
}),
|
|
3149
618
|
contentType: "application/json",
|
|
3150
619
|
headers: t
|
|
3151
|
-
} :
|
|
3152
|
-
status:
|
|
3153
|
-
body:
|
|
620
|
+
} : o.kind === "rejected" ? {
|
|
621
|
+
status: o.status,
|
|
622
|
+
body: o.detail,
|
|
3154
623
|
contentType: "text/plain",
|
|
3155
624
|
headers: t
|
|
3156
|
-
} :
|
|
625
|
+
} : o.kind === "scan" ? {
|
|
3157
626
|
status: 422,
|
|
3158
|
-
body: `rejected: ${
|
|
627
|
+
body: `rejected: ${o.threat}`,
|
|
3159
628
|
contentType: "text/plain",
|
|
3160
629
|
headers: t
|
|
3161
630
|
} : {
|
|
3162
|
-
status:
|
|
3163
|
-
body:
|
|
631
|
+
status: o.status,
|
|
632
|
+
body: o.message,
|
|
3164
633
|
contentType: "text/plain",
|
|
3165
634
|
headers: t
|
|
3166
635
|
};
|
|
3167
636
|
}
|
|
3168
|
-
},
|
|
637
|
+
}, Fe = {
|
|
3169
638
|
method: "*",
|
|
3170
|
-
path: `${
|
|
639
|
+
path: `${i}/upload/resumable`,
|
|
3171
640
|
originGuard: "exempt",
|
|
3172
641
|
handle: async (e) => {
|
|
3173
|
-
let t =
|
|
642
|
+
let t = Pt(e.headers.origin, b);
|
|
3174
643
|
if (e.method === "OPTIONS") return {
|
|
3175
644
|
status: 204,
|
|
3176
645
|
headers: t
|
|
3177
646
|
};
|
|
3178
|
-
let n = new URLSearchParams(e.query || ""),
|
|
3179
|
-
if (!
|
|
647
|
+
let n = new URLSearchParams(e.query || ""), i = xe(n.get("token") ?? "");
|
|
648
|
+
if (!i || i.instance !== r) return {
|
|
3180
649
|
status: 401,
|
|
3181
650
|
body: "invalid or expired resumable token",
|
|
3182
651
|
contentType: "text/plain",
|
|
3183
652
|
headers: t
|
|
3184
653
|
};
|
|
654
|
+
let a = await L(i, t);
|
|
655
|
+
if (a) return a;
|
|
3185
656
|
if (e.method === "GET" || e.method === "HEAD") {
|
|
3186
|
-
let e = await
|
|
3187
|
-
uploadId:
|
|
3188
|
-
tenantId:
|
|
3189
|
-
|
|
657
|
+
let e = await q.runPromise(F.resumableStatus({
|
|
658
|
+
uploadId: i.id,
|
|
659
|
+
tenantId: i.tenant,
|
|
660
|
+
destination: i.destination
|
|
661
|
+
}).pipe(q.match({
|
|
3190
662
|
onFailure: (e) => ({ error: e.message }),
|
|
3191
663
|
onSuccess: (e) => e
|
|
3192
664
|
})));
|
|
@@ -3211,8 +683,8 @@ var qn = () => _e({
|
|
|
3211
683
|
contentType: "text/plain",
|
|
3212
684
|
headers: t
|
|
3213
685
|
};
|
|
3214
|
-
let
|
|
3215
|
-
if (!Number.isInteger(
|
|
686
|
+
let o = Number(n.get("index"));
|
|
687
|
+
if (!Number.isInteger(o) || o < 0) return {
|
|
3216
688
|
status: 400,
|
|
3217
689
|
body: "missing/invalid chunk index",
|
|
3218
690
|
contentType: "text/plain",
|
|
@@ -3224,153 +696,173 @@ var qn = () => _e({
|
|
|
3224
696
|
contentType: "text/plain",
|
|
3225
697
|
headers: t
|
|
3226
698
|
};
|
|
3227
|
-
let
|
|
3228
|
-
uploadId:
|
|
3229
|
-
tenantId:
|
|
3230
|
-
|
|
699
|
+
let s = n.get("final") === "1", c = await q.runPromise(F.putResumableChunk({
|
|
700
|
+
uploadId: i.id,
|
|
701
|
+
tenantId: i.tenant,
|
|
702
|
+
destination: i.destination,
|
|
703
|
+
index: o,
|
|
3231
704
|
bytes: e.rawBody
|
|
3232
|
-
}).pipe(
|
|
3233
|
-
uploadId:
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
...
|
|
3241
|
-
...
|
|
3242
|
-
...
|
|
3243
|
-
...
|
|
3244
|
-
|
|
705
|
+
}).pipe(q.flatMap(() => s ? F.finalizeResumable({
|
|
706
|
+
uploadId: i.id,
|
|
707
|
+
destination: i.destination,
|
|
708
|
+
count: o + 1,
|
|
709
|
+
contentType: i.ct,
|
|
710
|
+
tenantId: i.tenant,
|
|
711
|
+
ownerId: i.sub,
|
|
712
|
+
visibility: i.vis,
|
|
713
|
+
...i.access === void 0 ? {} : { access: i.access },
|
|
714
|
+
...i.folder === void 0 ? {} : { folder: i.folder },
|
|
715
|
+
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
716
|
+
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
717
|
+
...i.caption === void 0 ? {} : { caption: i.caption }
|
|
718
|
+
}).pipe(q.flatMap((e) => F.getUrl(e.id).pipe(q.map((t) => ({
|
|
3245
719
|
kind: "done",
|
|
3246
720
|
ref: e,
|
|
3247
721
|
url: t
|
|
3248
|
-
}))))) :
|
|
3249
|
-
StorageRejected: (e) =>
|
|
722
|
+
}))))) : q.succeed({ kind: "chunk" })), q.catchTags({
|
|
723
|
+
StorageRejected: (e) => q.succeed({
|
|
3250
724
|
kind: "rejected",
|
|
3251
|
-
status: e
|
|
725
|
+
status: Ht(e),
|
|
3252
726
|
detail: e.detail
|
|
3253
727
|
}),
|
|
3254
|
-
StorageScanRejected: (e) =>
|
|
728
|
+
StorageScanRejected: (e) => q.succeed({
|
|
3255
729
|
kind: "scan",
|
|
3256
730
|
threat: e.threat
|
|
3257
731
|
}),
|
|
3258
|
-
StorageError: (e) =>
|
|
732
|
+
StorageError: (e) => q.succeed({
|
|
3259
733
|
kind: "error",
|
|
3260
|
-
message: e.message
|
|
734
|
+
message: e.message,
|
|
735
|
+
status: e.status ?? 500
|
|
3261
736
|
})
|
|
3262
737
|
})));
|
|
3263
|
-
return
|
|
738
|
+
return c.kind === "chunk" ? {
|
|
3264
739
|
status: 204,
|
|
3265
740
|
headers: {
|
|
3266
741
|
...t,
|
|
3267
|
-
"upload-offset": String(
|
|
742
|
+
"upload-offset": String(o + 1)
|
|
3268
743
|
}
|
|
3269
|
-
} :
|
|
744
|
+
} : c.kind === "done" ? {
|
|
3270
745
|
status: 201,
|
|
3271
746
|
body: JSON.stringify({
|
|
3272
|
-
id:
|
|
3273
|
-
url:
|
|
3274
|
-
contentType:
|
|
3275
|
-
size:
|
|
747
|
+
id: c.ref.id,
|
|
748
|
+
url: c.url,
|
|
749
|
+
contentType: c.ref.contentType,
|
|
750
|
+
size: c.ref.size
|
|
3276
751
|
}),
|
|
3277
752
|
contentType: "application/json",
|
|
3278
753
|
headers: t
|
|
3279
|
-
} :
|
|
3280
|
-
status:
|
|
3281
|
-
body:
|
|
754
|
+
} : c.kind === "rejected" ? {
|
|
755
|
+
status: c.status,
|
|
756
|
+
body: c.detail,
|
|
3282
757
|
contentType: "text/plain",
|
|
3283
758
|
headers: t
|
|
3284
|
-
} :
|
|
759
|
+
} : c.kind === "scan" ? {
|
|
3285
760
|
status: 422,
|
|
3286
|
-
body: `rejected: ${
|
|
761
|
+
body: `rejected: ${c.threat}`,
|
|
3287
762
|
contentType: "text/plain",
|
|
3288
763
|
headers: t
|
|
3289
764
|
} : {
|
|
3290
|
-
status:
|
|
3291
|
-
body:
|
|
765
|
+
status: c.status,
|
|
766
|
+
body: c.message,
|
|
3292
767
|
contentType: "text/plain",
|
|
3293
768
|
headers: t
|
|
3294
769
|
};
|
|
3295
770
|
}
|
|
3296
|
-
},
|
|
771
|
+
}, U = (e) => ({
|
|
3297
772
|
kind: "json",
|
|
3298
773
|
data: e
|
|
3299
|
-
}),
|
|
774
|
+
}), W = (e, t) => ({
|
|
3300
775
|
kind: "json",
|
|
3301
776
|
status: e,
|
|
3302
777
|
data: { error: t }
|
|
3303
|
-
}),
|
|
778
|
+
}), G = (e, t) => {
|
|
3304
779
|
try {
|
|
3305
780
|
return new URL(e, "http://localhost").searchParams.get(t);
|
|
3306
781
|
} catch {
|
|
3307
782
|
return null;
|
|
3308
783
|
}
|
|
3309
|
-
},
|
|
784
|
+
}, K = q.gen(function* () {
|
|
785
|
+
let e = yield* M.catalogueId;
|
|
786
|
+
return p ? {
|
|
787
|
+
catalogueId: e,
|
|
788
|
+
storageInstance: r,
|
|
789
|
+
tenantScoped: !0
|
|
790
|
+
} : {
|
|
791
|
+
catalogueId: e,
|
|
792
|
+
objectNamespace: yield* m.objectNamespace,
|
|
793
|
+
storageInstance: r
|
|
794
|
+
};
|
|
795
|
+
}), et = [
|
|
3310
796
|
{
|
|
3311
797
|
method: "POST",
|
|
3312
798
|
path: "/upload-ticket",
|
|
3313
799
|
description: "Authorize a binary upload with explicit tenant and owner attribution",
|
|
3314
|
-
handler: (
|
|
3315
|
-
let n =
|
|
3316
|
-
operationId:
|
|
3317
|
-
tenantId:
|
|
3318
|
-
ownerId:
|
|
3319
|
-
key: n.pipe(
|
|
3320
|
-
contentType: n.pipe(
|
|
3321
|
-
size:
|
|
3322
|
-
visibility:
|
|
3323
|
-
})))(
|
|
800
|
+
handler: (t) => q.gen(function* () {
|
|
801
|
+
let n = J.String.pipe(J.check(J.makeFilter((e) => e.trim().length > 0))), a = yield* J.decodeUnknownEffect(J.fromJsonString(J.Struct({
|
|
802
|
+
operationId: J.optional(n.pipe(J.check(J.isMaxLength(200)))),
|
|
803
|
+
tenantId: J.NullOr(n),
|
|
804
|
+
ownerId: J.NullOr(n),
|
|
805
|
+
key: n.pipe(J.check(J.isMaxLength(1024))),
|
|
806
|
+
contentType: n.pipe(J.check(J.isMaxLength(255)), J.check(J.makeFilter((e) => !/[\r\n]/.test(e)))),
|
|
807
|
+
size: J.Number.pipe(J.check(J.isInt()), J.check(J.isGreaterThan(0)), J.check(J.makeFilter(Number.isSafeInteger))),
|
|
808
|
+
visibility: J.optional(J.Literals(["public", "private"]))
|
|
809
|
+
})))(t.body).pipe(q.mapError(() => new g({
|
|
3324
810
|
provider: "inspect",
|
|
3325
811
|
message: "Provide explicit tenantId and ownerId (or null), key, contentType and a positive file size",
|
|
3326
812
|
transient: !1,
|
|
3327
813
|
status: 400
|
|
3328
814
|
})));
|
|
3329
|
-
if (
|
|
3330
|
-
if (
|
|
3331
|
-
let a = r.visibility !== "public" && Array.isArray(
|
|
815
|
+
if (a.operationId !== void 0 && A.current === void 0) return W(409, "Durable uploads require a bound operation store with default reference and grant stores");
|
|
816
|
+
if (x !== void 0 && a.size > x) return W(413, "File exceeds the configured upload limit");
|
|
817
|
+
let o = yield* _.select(a.tenantId), s = a.operationId ?? (A.current === void 0 ? void 0 : ht()), c = s === void 0 ? void 0 : "inspect-upload:" + mt("sha256").update(JSON.stringify([r, s])).digest("hex"), l = a.visibility !== "public" && Array.isArray(e.uploadAccess) ? yield* J.decodeUnknownEffect(vt)(e.uploadAccess, { onExcessProperty: "error" }).pipe(q.mapError(() => new g({
|
|
3332
818
|
provider: "storage",
|
|
3333
819
|
message: "Invalid upload access policy",
|
|
3334
820
|
transient: !1,
|
|
3335
821
|
status: 400
|
|
3336
|
-
}))) : void 0,
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
822
|
+
}))) : void 0, u = yield* F.uploadTicketScope({
|
|
823
|
+
tenantId: a.tenantId,
|
|
824
|
+
destination: o.destination
|
|
825
|
+
}), d = z({
|
|
826
|
+
writeScope: u,
|
|
827
|
+
instance: r,
|
|
828
|
+
destination: o.destination,
|
|
829
|
+
issuerReplicaId: _t().replicaId,
|
|
830
|
+
...l === void 0 ? {} : { access: l },
|
|
831
|
+
...c === void 0 ? {} : { operationId: c },
|
|
832
|
+
sub: a.ownerId,
|
|
833
|
+
tenant: a.tenantId,
|
|
834
|
+
ct: a.contentType,
|
|
835
|
+
key: a.key,
|
|
836
|
+
vis: a.visibility ?? "private",
|
|
837
|
+
max: a.size
|
|
3347
838
|
}, 300);
|
|
3348
|
-
return
|
|
3349
|
-
uploadPath: `${
|
|
839
|
+
return U({
|
|
840
|
+
uploadPath: `${i}/upload?ticket=${encodeURIComponent(d)}`,
|
|
3350
841
|
expiresInSec: 300,
|
|
3351
|
-
maxBytes:
|
|
842
|
+
maxBytes: a.size,
|
|
843
|
+
...s === void 0 ? {} : { operationId: s }
|
|
3352
844
|
});
|
|
3353
|
-
}).pipe(
|
|
845
|
+
}).pipe(q.catch((e) => q.succeed(W(e.status ?? 500, e.message))))
|
|
3354
846
|
},
|
|
3355
847
|
{
|
|
3356
848
|
method: "GET",
|
|
3357
849
|
path: "/download",
|
|
3358
850
|
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*
|
|
851
|
+
handler: (e) => q.gen(function* () {
|
|
852
|
+
let t = G(e.url, "refId");
|
|
853
|
+
if (!t?.trim()) return W(400, "A non-empty refId is required");
|
|
854
|
+
let { ref: n, stream: r } = yield* F.getStream(t), i = n.key.split("/").pop() || n.id, a = encodeURIComponent(i).replace(/[!'()*]/g, (e) => `%${e.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
3363
855
|
return {
|
|
3364
856
|
kind: "bytes",
|
|
3365
857
|
contentType: n.contentType,
|
|
3366
858
|
byteStream: {
|
|
3367
|
-
stream: () =>
|
|
859
|
+
stream: () => pt.toReadableStream(r),
|
|
3368
860
|
contentLength: n.size,
|
|
3369
861
|
contentDisposition: `attachment; filename="download"; filename*=UTF-8''${a}`
|
|
3370
862
|
},
|
|
3371
863
|
headers: { "cache-control": "no-store" }
|
|
3372
864
|
};
|
|
3373
|
-
}).pipe(
|
|
865
|
+
}).pipe(q.catch((e) => q.succeed(W(e.status ?? 500, e.message))))
|
|
3374
866
|
},
|
|
3375
867
|
{
|
|
3376
868
|
method: "GET",
|
|
@@ -3378,8 +870,8 @@ var qn = () => _e({
|
|
|
3378
870
|
scope: "process",
|
|
3379
871
|
description: "Searchable storage refs, newest first, paginated",
|
|
3380
872
|
handler: (e) => {
|
|
3381
|
-
let t = Number(
|
|
3382
|
-
return
|
|
873
|
+
let t = Number(G(e.url, "offset") ?? 0), n = Number.isSafeInteger(t) && t >= 0 ? t : 0, r = (G(e.url, "search") ?? "").trim().slice(0, 200);
|
|
874
|
+
return M.listRefs({
|
|
3383
875
|
tenantId: void 0,
|
|
3384
876
|
ownerId: void 0,
|
|
3385
877
|
folder: void 0,
|
|
@@ -3388,14 +880,15 @@ var qn = () => _e({
|
|
|
3388
880
|
search: r,
|
|
3389
881
|
limit: 51,
|
|
3390
882
|
offset: n
|
|
3391
|
-
}).pipe(
|
|
3392
|
-
|
|
883
|
+
}).pipe(q.flatMap((e) => K.pipe(q.map((t) => U({
|
|
884
|
+
source: t,
|
|
885
|
+
refs: e.slice(0, 50).map(Ft),
|
|
3393
886
|
page: {
|
|
3394
887
|
search: r,
|
|
3395
888
|
offset: n,
|
|
3396
889
|
nextOffset: e.length > 50 ? n + 50 : null
|
|
3397
890
|
}
|
|
3398
|
-
})),
|
|
891
|
+
})))), q.catch((e) => q.succeed(W(500, e.message))));
|
|
3399
892
|
}
|
|
3400
893
|
},
|
|
3401
894
|
{
|
|
@@ -3403,11 +896,12 @@ var qn = () => _e({
|
|
|
3403
896
|
path: "/stats",
|
|
3404
897
|
scope: "process",
|
|
3405
898
|
description: "Object count + total bytes per tenant + visibility split",
|
|
3406
|
-
handler: () =>
|
|
3407
|
-
|
|
3408
|
-
|
|
899
|
+
handler: () => M.statistics().pipe(q.flatMap((e) => K.pipe(q.map((t) => U({
|
|
900
|
+
source: t,
|
|
901
|
+
provider: p ? "tenant-scoped" : m.name,
|
|
902
|
+
bucket: h,
|
|
3409
903
|
...e
|
|
3410
|
-
})),
|
|
904
|
+
})))), q.catch((e) => q.succeed(W(500, e.message))))
|
|
3411
905
|
},
|
|
3412
906
|
{
|
|
3413
907
|
method: "GET",
|
|
@@ -3415,103 +909,119 @@ var qn = () => _e({
|
|
|
3415
909
|
scope: "process",
|
|
3416
910
|
description: "Grants for a ref (?refId=…)",
|
|
3417
911
|
handler: (e) => {
|
|
3418
|
-
let t =
|
|
3419
|
-
return t ?
|
|
912
|
+
let t = G(e.url, "refId");
|
|
913
|
+
return t ? N.listByRef(t).pipe(q.map((e) => U({ grants: e.map(Bt) })), q.catch((e) => q.succeed(W(500, e.message)))) : q.succeed(W(400, "refId query param required"));
|
|
3420
914
|
}
|
|
3421
915
|
},
|
|
3422
916
|
{
|
|
3423
917
|
method: "POST",
|
|
3424
918
|
path: "/share",
|
|
3425
919
|
description: "Grant a principal access to a ref",
|
|
3426
|
-
handler: (e) =>
|
|
3427
|
-
let
|
|
3428
|
-
refId:
|
|
3429
|
-
principalType:
|
|
920
|
+
handler: (e) => q.gen(function* () {
|
|
921
|
+
let t = yield* J.decodeUnknownEffect(J.fromJsonString(J.Struct({
|
|
922
|
+
refId: J.String.pipe(J.check(J.makeFilter((e) => e.trim().length > 0))),
|
|
923
|
+
principalType: J.Literals([
|
|
3430
924
|
"user",
|
|
3431
925
|
"group",
|
|
3432
926
|
"apiKey"
|
|
3433
927
|
]),
|
|
3434
|
-
principalId:
|
|
3435
|
-
permission:
|
|
3436
|
-
expiresInDays:
|
|
3437
|
-
})))(e.body).pipe(
|
|
928
|
+
principalId: J.String.pipe(J.check(J.makeFilter((e) => e.trim().length > 0))),
|
|
929
|
+
permission: J.optional(J.Literals(["read", "write"])),
|
|
930
|
+
expiresInDays: J.optional(J.Number.pipe(J.check(J.isFinite()), J.check(J.isGreaterThan(0))))
|
|
931
|
+
})))(e.body).pipe(q.mapError(() => new g({
|
|
3438
932
|
provider: "inspect",
|
|
3439
933
|
message: "Invalid share input: provide refId, principalType, principalId, read/write permission and a positive finite expiry if set",
|
|
3440
934
|
transient: !1,
|
|
3441
935
|
status: 400
|
|
3442
|
-
}))),
|
|
3443
|
-
if (
|
|
3444
|
-
let
|
|
3445
|
-
refId:
|
|
3446
|
-
principalType:
|
|
3447
|
-
principalId:
|
|
3448
|
-
...
|
|
3449
|
-
expiresAt:
|
|
936
|
+
}))), n = t.expiresInDays === void 0 ? null : new Date(Date.now() + t.expiresInDays * 864e5);
|
|
937
|
+
if (n !== null && !Number.isFinite(n.getTime())) return W(400, "Expiry exceeds the supported date range");
|
|
938
|
+
let r = yield* F.grant({
|
|
939
|
+
refId: t.refId,
|
|
940
|
+
principalType: t.principalType,
|
|
941
|
+
principalId: t.principalId,
|
|
942
|
+
...t.permission ? { permission: t.permission } : {},
|
|
943
|
+
expiresAt: n
|
|
3450
944
|
});
|
|
3451
|
-
return
|
|
3452
|
-
}).pipe(
|
|
945
|
+
return U({ grant: Bt(r) });
|
|
946
|
+
}).pipe(q.catch((e) => q.succeed(W(e.status ?? 500, e.message ?? "share failed"))))
|
|
3453
947
|
},
|
|
3454
948
|
{
|
|
3455
949
|
method: "POST",
|
|
3456
950
|
path: "/delete",
|
|
3457
951
|
description: "Delete an object reference and its grants; release unreferenced bytes",
|
|
3458
|
-
handler: (e) =>
|
|
3459
|
-
let
|
|
952
|
+
handler: (e) => q.gen(function* () {
|
|
953
|
+
let t = yield* J.decodeUnknownEffect(J.fromJsonString(J.Struct({ refId: J.String.pipe(J.check(J.makeFilter((e) => e.trim().length > 0))) })))(e.body).pipe(q.mapError(() => new g({
|
|
3460
954
|
provider: "inspect",
|
|
3461
955
|
message: "A non-empty refId is required",
|
|
3462
956
|
transient: !1,
|
|
3463
957
|
status: 400
|
|
3464
958
|
})));
|
|
3465
|
-
return yield*
|
|
3466
|
-
}).pipe(
|
|
959
|
+
return yield* F.delete(t.refId), U({ ok: !0 });
|
|
960
|
+
}).pipe(q.catch((e) => q.succeed(W(e.status ?? 500, e.message))))
|
|
3467
961
|
},
|
|
3468
962
|
{
|
|
3469
963
|
method: "POST",
|
|
3470
964
|
path: "/revoke",
|
|
3471
965
|
description: "Revoke a grant by id",
|
|
3472
|
-
handler: (e) =>
|
|
3473
|
-
let
|
|
966
|
+
handler: (e) => q.gen(function* () {
|
|
967
|
+
let t = yield* J.decodeUnknownEffect(J.fromJsonString(J.Struct({ grantId: J.String.pipe(J.check(J.makeFilter((e) => e.trim().length > 0))) })))(e.body).pipe(q.mapError(() => new g({
|
|
3474
968
|
provider: "inspect",
|
|
3475
969
|
message: "A non-empty grantId is required",
|
|
3476
970
|
transient: !1,
|
|
3477
971
|
status: 400
|
|
3478
972
|
})));
|
|
3479
|
-
return yield*
|
|
3480
|
-
}).pipe(
|
|
973
|
+
return yield* F.revoke(t.grantId), U({ ok: !0 });
|
|
974
|
+
}).pipe(q.catch((e) => q.succeed(W(e.status ?? 500, e.message ?? "revoke failed"))))
|
|
3481
975
|
}
|
|
3482
|
-
],
|
|
976
|
+
], tt = [
|
|
3483
977
|
{
|
|
3484
|
-
...
|
|
978
|
+
...Je,
|
|
3485
979
|
execute: (e, t) => {
|
|
3486
980
|
let n = e;
|
|
3487
|
-
return
|
|
981
|
+
return F.mintUrl(n.id, t.request.subject, {
|
|
3488
982
|
...n.password === void 0 ? {} : { password: n.password },
|
|
3489
983
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
3490
|
-
}).pipe(
|
|
984
|
+
}).pipe(q.map((e) => ({ url: e })));
|
|
3491
985
|
}
|
|
3492
986
|
},
|
|
3493
987
|
{
|
|
3494
|
-
...
|
|
988
|
+
...qe,
|
|
3495
989
|
execute: (e, t) => {
|
|
3496
990
|
let n = e;
|
|
3497
|
-
return
|
|
991
|
+
return F.mintUploadUrl({
|
|
3498
992
|
key: n.key,
|
|
3499
993
|
contentType: n.contentType,
|
|
3500
994
|
tenantId: t.request.subject.tenantId,
|
|
3501
995
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
3502
|
-
}).pipe(
|
|
996
|
+
}).pipe(q.map((e) => ({ url: e })));
|
|
3503
997
|
}
|
|
3504
998
|
},
|
|
3505
999
|
{
|
|
3506
|
-
...
|
|
1000
|
+
...Ke,
|
|
3507
1001
|
execute: (e, t) => {
|
|
3508
1002
|
let n = e;
|
|
3509
|
-
return
|
|
1003
|
+
return Z(t, S).pipe(q.flatMap((e) => D(n, t.request.subject).pipe(q.map((t) => ({
|
|
3510
1004
|
writer: e,
|
|
3511
1005
|
policy: t
|
|
3512
|
-
})))),
|
|
3513
|
-
|
|
3514
|
-
|
|
1006
|
+
})))), q.flatMap((e) => n.operationId !== void 0 && A.current === void 0 ? q.fail(new g({
|
|
1007
|
+
provider: "storage",
|
|
1008
|
+
message: "Durable uploads require a bound operation store with default reference and grant stores",
|
|
1009
|
+
transient: !1,
|
|
1010
|
+
status: 409
|
|
1011
|
+
})) : q.succeed(e)), q.flatMap(({ writer: e, policy: t }) => _.select(e.tenantId).pipe(q.flatMap((a) => F.uploadTicketScope({
|
|
1012
|
+
tenantId: e.tenantId,
|
|
1013
|
+
destination: a.destination
|
|
1014
|
+
}).pipe(q.map((o) => {
|
|
1015
|
+
let s = n.expiresInSec ?? 900, c = n.operationId ?? (A.current === void 0 ? void 0 : ht()), l = c === void 0 ? void 0 : "client-upload:" + mt("sha256").update(JSON.stringify([
|
|
1016
|
+
r,
|
|
1017
|
+
e.tenantId,
|
|
1018
|
+
e.id,
|
|
1019
|
+
c
|
|
1020
|
+
])).digest("hex"), u = z({
|
|
1021
|
+
writeScope: o,
|
|
1022
|
+
instance: r,
|
|
1023
|
+
destination: a.destination,
|
|
1024
|
+
...l === void 0 ? {} : { operationId: l },
|
|
3515
1025
|
sub: e.id,
|
|
3516
1026
|
tenant: e.tenantId,
|
|
3517
1027
|
ct: n.contentType,
|
|
@@ -3522,30 +1032,33 @@ var qn = () => _e({
|
|
|
3522
1032
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
3523
1033
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
3524
1034
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
3525
|
-
...
|
|
3526
|
-
},
|
|
1035
|
+
...x === void 0 ? {} : { max: x }
|
|
1036
|
+
}, s);
|
|
3527
1037
|
return {
|
|
3528
|
-
uploadUrl: `${
|
|
3529
|
-
expiresInSec:
|
|
1038
|
+
uploadUrl: `${y ? y.replace(/\/+$/, "") : ""}${i}/upload?ticket=${encodeURIComponent(u)}`,
|
|
1039
|
+
expiresInSec: s,
|
|
1040
|
+
...c === void 0 ? {} : { operationId: c }
|
|
3530
1041
|
};
|
|
3531
|
-
}));
|
|
1042
|
+
}))))));
|
|
3532
1043
|
}
|
|
3533
1044
|
},
|
|
3534
1045
|
{
|
|
3535
|
-
...
|
|
1046
|
+
...Ge,
|
|
3536
1047
|
execute: (e, t) => {
|
|
3537
1048
|
let n = e;
|
|
3538
|
-
return
|
|
1049
|
+
return Z(t, S).pipe(q.flatMap((e) => D(n, t.request.subject).pipe(q.map((t) => ({
|
|
3539
1050
|
writer: e,
|
|
3540
1051
|
policy: t
|
|
3541
|
-
})))),
|
|
1052
|
+
})))), q.flatMap(({ writer: e, policy: t }) => F.mintPresignedUpload({
|
|
3542
1053
|
contentType: n.contentType,
|
|
3543
1054
|
tenantId: e.tenantId,
|
|
3544
1055
|
...n.expiresInSec === void 0 ? {} : { expiresInSec: n.expiresInSec }
|
|
3545
|
-
}).pipe(
|
|
3546
|
-
let
|
|
3547
|
-
|
|
3548
|
-
|
|
1056
|
+
}).pipe(q.map((i) => {
|
|
1057
|
+
let a = ge({
|
|
1058
|
+
writeScope: i.writeScope,
|
|
1059
|
+
instance: r,
|
|
1060
|
+
destination: i.destination,
|
|
1061
|
+
key: i.key,
|
|
3549
1062
|
sub: e.id,
|
|
3550
1063
|
tenant: e.tenantId,
|
|
3551
1064
|
ct: n.contentType,
|
|
@@ -3555,65 +1068,71 @@ var qn = () => _e({
|
|
|
3555
1068
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
3556
1069
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
3557
1070
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
3558
|
-
...
|
|
3559
|
-
},
|
|
1071
|
+
...x === void 0 ? {} : { max: x }
|
|
1072
|
+
}, i.expiresInSec);
|
|
3560
1073
|
return {
|
|
3561
|
-
uploadUrl:
|
|
3562
|
-
finalizeToken:
|
|
3563
|
-
expiresInSec:
|
|
1074
|
+
uploadUrl: i.uploadUrl,
|
|
1075
|
+
finalizeToken: a,
|
|
1076
|
+
expiresInSec: i.expiresInSec
|
|
3564
1077
|
};
|
|
3565
1078
|
}))));
|
|
3566
1079
|
}
|
|
3567
1080
|
},
|
|
3568
1081
|
{
|
|
3569
|
-
...
|
|
3570
|
-
execute: (e,
|
|
3571
|
-
let
|
|
3572
|
-
return !
|
|
1082
|
+
...Ve,
|
|
1083
|
+
execute: (e, t) => {
|
|
1084
|
+
let n = ye(e.finalizeToken);
|
|
1085
|
+
return !n || n.instance !== r ? q.fail(new g({
|
|
3573
1086
|
provider: "storage",
|
|
3574
1087
|
message: "invalid or expired finalize token",
|
|
3575
1088
|
transient: !1,
|
|
3576
1089
|
status: 401
|
|
3577
|
-
})) :
|
|
1090
|
+
})) : zt(n.sub, t.request.subject.id) ? q.fail(new g({
|
|
3578
1091
|
provider: "storage",
|
|
3579
1092
|
message: "finalize token belongs to another subject",
|
|
3580
1093
|
transient: !1,
|
|
3581
1094
|
status: 403
|
|
3582
|
-
})) :
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
...
|
|
3590
|
-
...
|
|
3591
|
-
...
|
|
3592
|
-
...
|
|
3593
|
-
|
|
1095
|
+
})) : I(n).pipe(q.flatMap(() => F.finalizeUpload({
|
|
1096
|
+
destination: n.destination,
|
|
1097
|
+
key: n.key,
|
|
1098
|
+
contentType: n.ct,
|
|
1099
|
+
tenantId: n.tenant,
|
|
1100
|
+
ownerId: n.sub,
|
|
1101
|
+
visibility: n.vis,
|
|
1102
|
+
...n.access === void 0 ? {} : { access: n.access },
|
|
1103
|
+
...n.folder === void 0 ? {} : { folder: n.folder },
|
|
1104
|
+
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
1105
|
+
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
1106
|
+
...n.caption === void 0 ? {} : { caption: n.caption }
|
|
1107
|
+
}).pipe(q.flatMap((e) => F.getUrl(e.id).pipe(q.map((t) => ({
|
|
3594
1108
|
id: e.id,
|
|
3595
1109
|
url: t,
|
|
3596
1110
|
contentType: e.contentType,
|
|
3597
1111
|
size: e.size,
|
|
3598
1112
|
...e.width == null ? {} : { width: e.width },
|
|
3599
1113
|
...e.height == null ? {} : { height: e.height }
|
|
3600
|
-
})))));
|
|
1114
|
+
})))))));
|
|
3601
1115
|
}
|
|
3602
1116
|
},
|
|
3603
1117
|
{
|
|
3604
|
-
...
|
|
1118
|
+
...ze,
|
|
3605
1119
|
execute: (e, t) => {
|
|
3606
1120
|
let n = e;
|
|
3607
|
-
return
|
|
1121
|
+
return Z(t, S).pipe(q.flatMap((e) => D(n, t.request.subject).pipe(q.map((t) => ({
|
|
3608
1122
|
writer: e,
|
|
3609
1123
|
policy: t
|
|
3610
|
-
})))),
|
|
3611
|
-
|
|
1124
|
+
})))), q.flatMap(({ writer: e, policy: t }) => _.select(e.tenantId).pipe(q.flatMap((a) => F.uploadTicketScope({
|
|
1125
|
+
tenantId: e.tenantId,
|
|
1126
|
+
destination: a.destination
|
|
1127
|
+
}).pipe(q.map((o) => {
|
|
1128
|
+
let s = n.expiresInSec ?? ce, c = ht(), l = n.chunkSize && n.chunkSize > 0 ? n.chunkSize : C;
|
|
3612
1129
|
return {
|
|
3613
|
-
uploadId:
|
|
3614
|
-
resumableToken:
|
|
3615
|
-
|
|
3616
|
-
|
|
1130
|
+
uploadId: c,
|
|
1131
|
+
resumableToken: ve({
|
|
1132
|
+
writeScope: o,
|
|
1133
|
+
instance: r,
|
|
1134
|
+
destination: a.destination,
|
|
1135
|
+
id: c,
|
|
3617
1136
|
sub: e.id,
|
|
3618
1137
|
tenant: e.tenantId,
|
|
3619
1138
|
ct: n.contentType,
|
|
@@ -3624,32 +1143,34 @@ var qn = () => _e({
|
|
|
3624
1143
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
3625
1144
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
3626
1145
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
3627
|
-
...
|
|
3628
|
-
},
|
|
3629
|
-
uploadUrl: `${
|
|
3630
|
-
chunkSize:
|
|
3631
|
-
expiresInSec:
|
|
1146
|
+
...x === void 0 ? {} : { max: x }
|
|
1147
|
+
}, s),
|
|
1148
|
+
uploadUrl: `${y ? y.replace(/\/+$/, "") : ""}${i}/upload/resumable`,
|
|
1149
|
+
chunkSize: l,
|
|
1150
|
+
expiresInSec: s
|
|
3632
1151
|
};
|
|
3633
|
-
}));
|
|
1152
|
+
}))))));
|
|
3634
1153
|
}
|
|
3635
1154
|
},
|
|
3636
1155
|
{
|
|
3637
|
-
...
|
|
1156
|
+
...Re,
|
|
3638
1157
|
execute: (e, t) => {
|
|
3639
|
-
let n = e,
|
|
3640
|
-
return
|
|
1158
|
+
let n = e, i = n.expiresInSec ?? ce;
|
|
1159
|
+
return Z(t, S).pipe(q.flatMap((e) => D(n, t.request.subject).pipe(q.map((t) => ({
|
|
3641
1160
|
writer: e,
|
|
3642
1161
|
policy: t
|
|
3643
|
-
})))),
|
|
1162
|
+
})))), q.flatMap(({ writer: e, policy: t }) => F.beginMultipartUpload({
|
|
3644
1163
|
contentType: n.contentType,
|
|
3645
1164
|
tenantId: e.tenantId,
|
|
3646
1165
|
visibility: n.visibility ?? "private",
|
|
3647
|
-
expiresInSec:
|
|
3648
|
-
}).pipe(
|
|
3649
|
-
multipartToken:
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
1166
|
+
expiresInSec: i
|
|
1167
|
+
}).pipe(q.map((a) => ({
|
|
1168
|
+
multipartToken: _e({
|
|
1169
|
+
writeScope: a.writeScope,
|
|
1170
|
+
instance: r,
|
|
1171
|
+
destination: a.destination,
|
|
1172
|
+
key: a.key,
|
|
1173
|
+
uploadId: a.uploadId,
|
|
3653
1174
|
sub: e.id,
|
|
3654
1175
|
tenant: e.tenantId,
|
|
3655
1176
|
ct: n.contentType,
|
|
@@ -3660,51 +1181,54 @@ var qn = () => _e({
|
|
|
3660
1181
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
3661
1182
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
3662
1183
|
...n.caption === void 0 ? {} : { caption: n.caption }
|
|
3663
|
-
},
|
|
3664
|
-
partSize: n.partSize && n.partSize >=
|
|
3665
|
-
expiresInSec:
|
|
1184
|
+
}, i),
|
|
1185
|
+
partSize: n.partSize && n.partSize >= C ? n.partSize : C,
|
|
1186
|
+
expiresInSec: i
|
|
3666
1187
|
})))));
|
|
3667
1188
|
}
|
|
3668
1189
|
},
|
|
3669
1190
|
{
|
|
3670
|
-
...
|
|
1191
|
+
...Ze,
|
|
3671
1192
|
execute: (e) => {
|
|
3672
|
-
let
|
|
3673
|
-
return !
|
|
1193
|
+
let t = e, n = B(t.multipartToken);
|
|
1194
|
+
return !n || n.instance !== r ? q.fail(new g({
|
|
3674
1195
|
provider: "storage",
|
|
3675
1196
|
message: "invalid or expired multipart token",
|
|
3676
1197
|
transient: !1,
|
|
3677
1198
|
status: 401
|
|
3678
|
-
})) : !Number.isInteger(
|
|
1199
|
+
})) : !Number.isInteger(t.partNumber) || t.partNumber < 1 ? q.fail(new g({
|
|
3679
1200
|
provider: "storage",
|
|
3680
1201
|
message: "partNumber must be a positive integer",
|
|
3681
1202
|
transient: !1,
|
|
3682
1203
|
status: 400
|
|
3683
|
-
})) :
|
|
3684
|
-
key:
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
1204
|
+
})) : I(n).pipe(q.flatMap(() => F.signMultipartPart({
|
|
1205
|
+
key: n.key,
|
|
1206
|
+
destination: n.destination,
|
|
1207
|
+
tenantId: n.tenant,
|
|
1208
|
+
uploadId: n.uploadId,
|
|
1209
|
+
partNumber: t.partNumber
|
|
1210
|
+
}).pipe(q.map((e) => ({ url: e })))));
|
|
3688
1211
|
}
|
|
3689
1212
|
},
|
|
3690
1213
|
{
|
|
3691
|
-
...
|
|
3692
|
-
execute: (e,
|
|
3693
|
-
let
|
|
3694
|
-
return !i || i.instance !==
|
|
1214
|
+
...Be,
|
|
1215
|
+
execute: (e, t) => {
|
|
1216
|
+
let n = e, i = B(n.multipartToken);
|
|
1217
|
+
return !i || i.instance !== r ? q.fail(new g({
|
|
3695
1218
|
provider: "storage",
|
|
3696
1219
|
message: "invalid or expired multipart token",
|
|
3697
1220
|
transient: !1,
|
|
3698
1221
|
status: 401
|
|
3699
|
-
})) :
|
|
1222
|
+
})) : zt(i.sub, t.request.subject.id) ? q.fail(new g({
|
|
3700
1223
|
provider: "storage",
|
|
3701
1224
|
message: "multipart token belongs to another subject",
|
|
3702
1225
|
transient: !1,
|
|
3703
1226
|
status: 403
|
|
3704
|
-
})) :
|
|
1227
|
+
})) : I(i).pipe(q.flatMap(() => F.completeMultipart({
|
|
1228
|
+
destination: i.destination,
|
|
3705
1229
|
key: i.key,
|
|
3706
1230
|
uploadId: i.uploadId,
|
|
3707
|
-
parts:
|
|
1231
|
+
parts: n.parts,
|
|
3708
1232
|
contentType: i.ct,
|
|
3709
1233
|
tenantId: i.tenant,
|
|
3710
1234
|
ownerId: i.sub,
|
|
@@ -3714,36 +1238,38 @@ var qn = () => _e({
|
|
|
3714
1238
|
...i.tags === void 0 ? {} : { tags: i.tags },
|
|
3715
1239
|
...i.alt === void 0 ? {} : { alt: i.alt },
|
|
3716
1240
|
...i.caption === void 0 ? {} : { caption: i.caption }
|
|
3717
|
-
}).pipe(
|
|
1241
|
+
}).pipe(q.flatMap((e) => F.getUrl(e.id).pipe(q.map((t) => ({
|
|
3718
1242
|
id: e.id,
|
|
3719
1243
|
url: t,
|
|
3720
1244
|
size: e.size
|
|
3721
|
-
})))));
|
|
1245
|
+
})))))));
|
|
3722
1246
|
}
|
|
3723
1247
|
},
|
|
3724
1248
|
{
|
|
3725
|
-
...
|
|
1249
|
+
...Le,
|
|
3726
1250
|
execute: (e) => {
|
|
3727
|
-
let
|
|
3728
|
-
return !
|
|
1251
|
+
let t = B(e.multipartToken);
|
|
1252
|
+
return !t || t.instance !== r ? q.fail(new g({
|
|
3729
1253
|
provider: "storage",
|
|
3730
1254
|
message: "invalid or expired multipart token",
|
|
3731
1255
|
transient: !1,
|
|
3732
1256
|
status: 401
|
|
3733
|
-
})) :
|
|
3734
|
-
key:
|
|
3735
|
-
|
|
3736
|
-
|
|
1257
|
+
})) : I(t).pipe(q.flatMap(() => F.abortMultipart({
|
|
1258
|
+
key: t.key,
|
|
1259
|
+
destination: t.destination,
|
|
1260
|
+
tenantId: t.tenant,
|
|
1261
|
+
uploadId: t.uploadId
|
|
1262
|
+
}).pipe(q.as({ ok: !0 }))));
|
|
3737
1263
|
}
|
|
3738
1264
|
},
|
|
3739
1265
|
{
|
|
3740
|
-
|
|
1266
|
+
...$e,
|
|
3741
1267
|
execute: (e, t) => {
|
|
3742
1268
|
let n = e, r = new Uint8Array(Buffer.from(n.bytesBase64, "base64"));
|
|
3743
|
-
return
|
|
1269
|
+
return Z(t, S).pipe(q.flatMap((e) => D(n, t.request.subject).pipe(q.map((t) => ({
|
|
3744
1270
|
writer: e,
|
|
3745
1271
|
policy: t
|
|
3746
|
-
})))),
|
|
1272
|
+
})))), q.flatMap(({ writer: e, policy: t }) => F.put({
|
|
3747
1273
|
bytes: r,
|
|
3748
1274
|
...t,
|
|
3749
1275
|
contentType: n.contentType,
|
|
@@ -3752,17 +1278,17 @@ var qn = () => _e({
|
|
|
3752
1278
|
...n.visibility ? { visibility: n.visibility } : {},
|
|
3753
1279
|
...n.key ? { key: n.key } : {},
|
|
3754
1280
|
...n.password ? { password: n.password } : {}
|
|
3755
|
-
})),
|
|
1281
|
+
})), q.flatMap((e) => F.getUrl(e.id).pipe(q.map((t) => ({
|
|
3756
1282
|
id: e.id,
|
|
3757
1283
|
url: t
|
|
3758
1284
|
})))));
|
|
3759
1285
|
}
|
|
3760
1286
|
},
|
|
3761
1287
|
{
|
|
3762
|
-
...
|
|
1288
|
+
...He,
|
|
3763
1289
|
execute: (e, t) => {
|
|
3764
1290
|
let n = e;
|
|
3765
|
-
return
|
|
1291
|
+
return Z(t, S).pipe(q.flatMap((e) => F.ingestUrl(n.url, {
|
|
3766
1292
|
tenantId: e.tenantId,
|
|
3767
1293
|
ownerId: e.id,
|
|
3768
1294
|
...n.visibility ? { visibility: n.visibility } : {},
|
|
@@ -3771,45 +1297,45 @@ var qn = () => _e({
|
|
|
3771
1297
|
...n.alt === void 0 ? {} : { alt: n.alt },
|
|
3772
1298
|
...n.caption === void 0 ? {} : { caption: n.caption },
|
|
3773
1299
|
...n.key === void 0 ? {} : { key: n.key }
|
|
3774
|
-
})),
|
|
1300
|
+
})), q.flatMap((e) => F.getUrl(e.id).pipe(q.map((t) => ({
|
|
3775
1301
|
id: e.id,
|
|
3776
1302
|
url: t
|
|
3777
1303
|
})))));
|
|
3778
1304
|
}
|
|
3779
1305
|
},
|
|
3780
1306
|
{
|
|
3781
|
-
...
|
|
1307
|
+
...Xe,
|
|
3782
1308
|
execute: (e, t) => {
|
|
3783
1309
|
let n = e, r = n.expiresInDays ? new Date(Date.now() + n.expiresInDays * 864e5) : null;
|
|
3784
|
-
return
|
|
1310
|
+
return Lt(F, n.refId, t).pipe(q.flatMap(() => F.grant({
|
|
3785
1311
|
refId: n.refId,
|
|
3786
1312
|
principalType: n.principalType,
|
|
3787
1313
|
principalId: n.principalId,
|
|
3788
1314
|
...n.permission ? { permission: n.permission } : {},
|
|
3789
1315
|
expiresAt: r,
|
|
3790
1316
|
createdBy: t.request.subject.id
|
|
3791
|
-
})),
|
|
1317
|
+
})), q.map((e) => ({ grantId: e.id })));
|
|
3792
1318
|
}
|
|
3793
1319
|
},
|
|
3794
1320
|
{
|
|
3795
|
-
...
|
|
1321
|
+
...Ye,
|
|
3796
1322
|
execute: (e, t) => {
|
|
3797
1323
|
let n = e;
|
|
3798
|
-
return
|
|
1324
|
+
return F.getGrant(n.grantId).pipe(q.flatMap((e) => e === null ? q.fail(It()) : Lt(F, e.refId, t)), q.flatMap(() => F.revoke(n.grantId)), q.map(() => ({ ok: !0 })));
|
|
3799
1325
|
}
|
|
3800
1326
|
},
|
|
3801
1327
|
{
|
|
3802
|
-
...
|
|
1328
|
+
...Ue,
|
|
3803
1329
|
execute: (e, t) => {
|
|
3804
1330
|
let n = e;
|
|
3805
|
-
return
|
|
1331
|
+
return Lt(F, n.refId, t).pipe(q.flatMap(() => F.listGrants(n.refId)), q.map((e) => ({ grants: e.map(Bt) })));
|
|
3806
1332
|
}
|
|
3807
1333
|
},
|
|
3808
1334
|
{
|
|
3809
|
-
...
|
|
1335
|
+
...We,
|
|
3810
1336
|
execute: (e, t) => {
|
|
3811
1337
|
let n = e;
|
|
3812
|
-
return
|
|
1338
|
+
return F.listRefs({
|
|
3813
1339
|
tenantId: t.request.subject.tenantId,
|
|
3814
1340
|
...n.folder === void 0 ? {} : { folder: n.folder },
|
|
3815
1341
|
...n.tags === void 0 ? {} : { tags: n.tags },
|
|
@@ -3817,111 +1343,154 @@ var qn = () => _e({
|
|
|
3817
1343
|
...n.includeDerived === void 0 ? {} : { includeDerived: n.includeDerived },
|
|
3818
1344
|
...n.limit === void 0 ? {} : { limit: n.limit },
|
|
3819
1345
|
...n.offset === void 0 ? {} : { offset: n.offset }
|
|
3820
|
-
}).pipe(
|
|
3821
|
-
refs: e.refs.map(
|
|
1346
|
+
}).pipe(q.map((e) => ({
|
|
1347
|
+
refs: e.refs.map(Ft),
|
|
3822
1348
|
nextOffset: e.nextOffset
|
|
3823
1349
|
})));
|
|
3824
1350
|
}
|
|
3825
1351
|
}
|
|
3826
|
-
]
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
instance: i.name
|
|
1352
|
+
], nt = yt({
|
|
1353
|
+
name: xt({
|
|
1354
|
+
base: Q,
|
|
1355
|
+
alias: e.alias,
|
|
1356
|
+
instance: e.name
|
|
3832
1357
|
}),
|
|
3833
|
-
baseName:
|
|
1358
|
+
baseName: Q,
|
|
3834
1359
|
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
1360
|
permissions: [
|
|
3836
1361
|
"network:outbound:*",
|
|
3837
1362
|
"inspect:read",
|
|
3838
1363
|
"inspect:write"
|
|
3839
1364
|
],
|
|
3840
|
-
declaredEnv:
|
|
3841
|
-
egress:
|
|
3842
|
-
services:
|
|
3843
|
-
inspectEndpoints:
|
|
1365
|
+
declaredEnv: E.declared,
|
|
1366
|
+
egress: Mt(e),
|
|
1367
|
+
services: fe,
|
|
1368
|
+
inspectEndpoints: et,
|
|
3844
1369
|
httpRoutes: [
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
1370
|
+
Ne,
|
|
1371
|
+
Pe,
|
|
1372
|
+
Fe
|
|
3848
1373
|
],
|
|
3849
|
-
routes:
|
|
3850
|
-
rpcClientDescriptors:
|
|
1374
|
+
routes: tt,
|
|
1375
|
+
rpcClientDescriptors: Qe,
|
|
3851
1376
|
errorSchemas: [
|
|
3852
1377
|
{
|
|
3853
|
-
schema:
|
|
1378
|
+
schema: g,
|
|
3854
1379
|
import: {
|
|
3855
1380
|
module: "@voltro/plugin-storage/errors",
|
|
3856
1381
|
name: "StorageError"
|
|
3857
1382
|
}
|
|
3858
1383
|
},
|
|
3859
1384
|
{
|
|
3860
|
-
schema:
|
|
1385
|
+
schema: ne,
|
|
3861
1386
|
import: {
|
|
3862
1387
|
module: "@voltro/plugin-storage/errors",
|
|
3863
1388
|
name: "StorageAccessDenied"
|
|
3864
1389
|
}
|
|
3865
1390
|
},
|
|
3866
1391
|
{
|
|
3867
|
-
schema:
|
|
1392
|
+
schema: re,
|
|
3868
1393
|
import: {
|
|
3869
1394
|
module: "@voltro/plugin-storage/errors",
|
|
3870
1395
|
name: "StorageRejected"
|
|
3871
1396
|
}
|
|
3872
1397
|
},
|
|
3873
1398
|
{
|
|
3874
|
-
schema:
|
|
1399
|
+
schema: ie,
|
|
3875
1400
|
import: {
|
|
3876
1401
|
module: "@voltro/plugin-storage/errors",
|
|
3877
1402
|
name: "StorageScanRejected"
|
|
3878
1403
|
}
|
|
3879
1404
|
}
|
|
3880
1405
|
],
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
return {
|
|
3894
|
-
url: await v.runPromise(N.getUrl(s.id, { tenantId: n })),
|
|
3895
|
-
refId: s.id
|
|
3896
|
-
};
|
|
1406
|
+
...s ? { needs: { connections: [{
|
|
1407
|
+
kind: "storage",
|
|
1408
|
+
role: "objects",
|
|
1409
|
+
optional: e.connection === void 0
|
|
1410
|
+
}] } } : {},
|
|
1411
|
+
...e.connection === void 0 ? {} : { connectionBindings: { objects: e.connection } },
|
|
1412
|
+
capabilities: {
|
|
1413
|
+
storageProvider: () => m,
|
|
1414
|
+
storageDestinations: {
|
|
1415
|
+
router: _,
|
|
1416
|
+
directDestination: e.connection === void 0 ? c : void 0,
|
|
1417
|
+
registry: () => f
|
|
3897
1418
|
},
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
1419
|
+
mediaPersist: {
|
|
1420
|
+
put: async ({ bytes: e, mediaType: t, tenantId: n, operationId: r, ownerId: i, visibility: a, tags: o }) => {
|
|
1421
|
+
let s = await q.runPromise(F.put({
|
|
1422
|
+
bytes: e,
|
|
1423
|
+
contentType: t,
|
|
1424
|
+
tenantId: n,
|
|
1425
|
+
kind: "media",
|
|
1426
|
+
...i === void 0 ? {} : { ownerId: i },
|
|
1427
|
+
...a === void 0 ? {} : { visibility: a },
|
|
1428
|
+
...o === void 0 ? {} : { tags: o },
|
|
1429
|
+
...A.current === void 0 ? {} : { operationId: r }
|
|
1430
|
+
}));
|
|
1431
|
+
return {
|
|
1432
|
+
url: await q.runPromise(F.getUrl(s.id, { tenantId: n })),
|
|
1433
|
+
refId: s.id
|
|
1434
|
+
};
|
|
1435
|
+
},
|
|
1436
|
+
ingestUrl: async ({ url: e, tenantId: t, operationId: n, ownerId: r, visibility: i, tags: a }) => {
|
|
1437
|
+
let o = await q.runPromise(F.ingestUrl(e, {
|
|
1438
|
+
tenantId: t,
|
|
1439
|
+
...r === void 0 ? {} : { ownerId: r },
|
|
1440
|
+
...i === void 0 ? {} : { visibility: i },
|
|
1441
|
+
...a === void 0 ? {} : { tags: a },
|
|
1442
|
+
...A.current === void 0 ? {} : { operationId: n }
|
|
1443
|
+
}));
|
|
1444
|
+
return {
|
|
1445
|
+
url: await q.runPromise(F.getUrl(o.id, { tenantId: t })),
|
|
1446
|
+
refId: o.id
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
3910
1449
|
}
|
|
3911
|
-
} },
|
|
3912
|
-
bindDataStore: (e) => {
|
|
3913
|
-
k && (j.current = ln(e)), pe && (M.current = fn(e)), k && pe && (me.current = zn(e)), x.bindDataStore?.(e);
|
|
3914
1450
|
},
|
|
3915
|
-
|
|
3916
|
-
let
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
}
|
|
1451
|
+
bindDataStore: async (t, n) => {
|
|
1452
|
+
let i = s ? n?.connectionReference?.("objects", "storage") || e.connection : void 0;
|
|
1453
|
+
await q.runPromise(oe(n?.connectionRegistry, i)), P = n?.storageReferenceProvider;
|
|
1454
|
+
let a = {
|
|
1455
|
+
storageInstance: r,
|
|
1456
|
+
resolveNamespace: (e) => _.resolve(e).pipe(q.flatMap((e) => e.objectNamespace))
|
|
1457
|
+
};
|
|
1458
|
+
At(m), (w || T) && await te(t), (w || T) && await se(t), (w || !p && m.name === "database") && await o(t), w && (O.current = De(t, a)), T && (k.current = Ee(t, a)), w && T && (A.current = Me(t, a), j.current = t), p || m.bindDataStore?.(t);
|
|
1459
|
+
},
|
|
1460
|
+
onActivate: (t) => q.gen(function* () {
|
|
1461
|
+
let n = s ? t.connectionReference?.("objects", "storage") || e.connection : void 0;
|
|
1462
|
+
if (yield* oe(t.connectionRegistry, n), p) {
|
|
1463
|
+
t.logger.info("storage: tenant-scoped named destination; resolved per request", { destination: h });
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
let r = !!y || !!E.read("STORAGE_CDN_URL", e.cdnBaseUrl);
|
|
1467
|
+
t.logger.info(`storage: provider=${m.name} presign=${m.presigns ? "yes" : "no"} publicUrl=${r ? "yes" : "no"} transforms=yes`, {
|
|
1468
|
+
provider: m.name,
|
|
1469
|
+
bucket: h,
|
|
1470
|
+
refStore: w ? "memory" : "custom"
|
|
1471
|
+
}), m.name === "memory" && process.env.NODE_ENV !== "test" && t.logger.warn("storage: provider=memory — uploads are IN-MEMORY and LOST on restart. Set STORAGE_PROVIDER to filesystem, s3, minio, azure or database and configure a durable destination."), !r && !m.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
1472
|
}),
|
|
3923
|
-
onDeactivate: () =>
|
|
1473
|
+
onDeactivate: () => q.void
|
|
1474
|
+
});
|
|
1475
|
+
return $.set(nt, () => A.current === void 0 ? void 0 : {
|
|
1476
|
+
service: F,
|
|
1477
|
+
metadata: A.current,
|
|
1478
|
+
bucket: h
|
|
1479
|
+
}), nt;
|
|
1480
|
+
}, $ = /* @__PURE__ */ new WeakMap(), Wt = (e) => {
|
|
1481
|
+
let t = e.filter((e) => $.has(e));
|
|
1482
|
+
if (t.length !== 1) throw new g({
|
|
1483
|
+
provider: "storage",
|
|
1484
|
+
message: t.length ? "Storage objects are ambiguous; installed instances: " + t.map((e) => e.name).sort().join(", ") : "This app has no Storage plugin",
|
|
1485
|
+
transient: !1
|
|
3924
1486
|
});
|
|
1487
|
+
let n = $.get(t[0])();
|
|
1488
|
+
if (n === void 0) throw new g({
|
|
1489
|
+
provider: "storage",
|
|
1490
|
+
message: "Storage objects need a bound data store with the default reference and grant stores",
|
|
1491
|
+
transient: !1
|
|
1492
|
+
});
|
|
1493
|
+
return n;
|
|
3925
1494
|
};
|
|
3926
1495
|
//#endregion
|
|
3927
|
-
export {
|
|
1496
|
+
export { c as STORAGE_BLOBS_TABLE, l as STORAGE_GRANTS_TABLE, a as STORAGE_REFERENCE_CATALOGUE_TABLE, u as STORAGE_REFS_TABLE, d as STORAGE_USAGE_TABLE, ne as StorageAccessDenied, ct as StorageAddress, Fe as StorageCustody, g as StorageError, re as StorageRejected, ie as StorageScanRejected, _ as StorageService, ee as _voltroStorageBlobsTable, f as _voltroStorageGrantsTable, p as _voltroStorageRefsTable, m as _voltroStorageUsageTable, Wt as appStorageObjects, jt as appStorageProvider, e as appStorageRouter, et as assetRef, y as assignStorageObjectNamespacesInTransaction, h as assignStorageReferenceInstancesInTransaction, D as azureProvider, Te as buildStorageService, b as bytesToStream, V as checkLimits, U as clamavScanner, O as clearStorageBuffer, x as collectStream, S as concatBytes, kt as configuredStorageProvider, ot as connectStorage, Ce as contentTypeAllowed, Ee as dataStoreGrantStore, De as dataStoreRefStore, k as databaseProvider, nt as decodeDataUri, it as durabilityNotice, ue as editImage, W as encodeInstream, o as ensureStorageReferenceCatalogue, r as existingFilesystemObjectNamespace, H as fetchIngestBody, K as ffmpegTranscoder, A as filesystemProvider, C as fromNodeReadable, ce as getObjectStream, F as hashPassword, ut as isStorageKey, t as makeStorageDestinationRouter, Me as makeStorageObjectMetadata, Oe as memoryGrantStore, j as memoryProvider, ke as memoryRefStore, G as parseClamavResponse, de as parseTransformParams, at as pathDurability, rt as putAvatar, w as putObjectStream, N as readStorageBuffer, Ae as refMatchesListQuery, se as requireStorageObjectNamespaces, X as resolveStorageProvider, L as resolveStorageSecret, Pe as retainedCaptureTables, P as s3Provider, ge as signFinalizeTicket, R as signGrant, _e as signMultipartTicket, ve as signResumableTicket, z as signUploadTicket, we as sniffMatches, dt as storageAddressIdentity, n as storageByteSecurityHeaders, Mt as storageEgressOf, Vt as storageInstanceName, oe as storageObjectLifecycleTables, i as storageObjectNamespace, Ut as storagePlugin, Ne as storagePutIntentsTable, v as storageRefAddress, s as storageReferenceCatalogueTable, je as storageServiceLayer, T as toNodeReadable, fe as transformCached, pe as transformFallbackReason, me as transformImage, ye as verifyFinalizeTicket, be as verifyGrant, B as verifyMultipartTicket, I as verifyPassword, xe as verifyResumableTicket, Se as verifyUploadTicket, tt as withStorage, st as withStorageKeyPrefix };
|