@cedarjs/uploads 8.0.0-canary.3429 → 8.0.0-canary.3433
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/README.md +7 -6
- package/dist/cleanupStaleUploads.d.ts +3 -4
- package/dist/cleanupStaleUploads.d.ts.map +1 -1
- package/dist/cleanupStaleUploads.js +2 -8
- package/dist/deleteFile.d.ts +15 -16
- package/dist/deleteFile.d.ts.map +1 -1
- package/dist/deleteFile.js +10 -49
- package/dist/derivedFiles.d.ts +189 -0
- package/dist/derivedFiles.d.ts.map +1 -0
- package/dist/derivedFiles.js +376 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/types.d.ts +56 -75
- package/dist/types.d.ts.map +1 -1
- package/package.json +9 -9
- package/dist/variants.d.ts +0 -212
- package/dist/variants.d.ts.map +0 -1
- package/dist/variants.js +0 -500
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import mime from "mime-types";
|
|
3
|
+
import { deleteFile } from "./deleteFile.js";
|
|
4
|
+
import { UploadError } from "./errors.js";
|
|
5
|
+
import { storeFile } from "./storeFile.js";
|
|
6
|
+
import { resolveTarget } from "./targets.js";
|
|
7
|
+
const MINUTE = 60 * 1e3;
|
|
8
|
+
const HOUR = 60 * MINUTE;
|
|
9
|
+
const VARIANT_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
10
|
+
const SOURCE_NAME = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
|
|
11
|
+
const uploadSources = /* @__PURE__ */ new WeakSet();
|
|
12
|
+
class SourceGone extends Error {
|
|
13
|
+
}
|
|
14
|
+
const DEFAULT_RETRY_DELAYS = [
|
|
15
|
+
MINUTE,
|
|
16
|
+
5 * MINUTE,
|
|
17
|
+
30 * MINUTE,
|
|
18
|
+
2 * HOUR,
|
|
19
|
+
6 * HOUR
|
|
20
|
+
];
|
|
21
|
+
const PENDING = { status: "pending" };
|
|
22
|
+
const FAILED = { status: "failed" };
|
|
23
|
+
async function readBytes(db, targets, upload) {
|
|
24
|
+
const target = resolveTarget(targets, upload.target);
|
|
25
|
+
const data = target.providerType === "db" ? upload.data ?? (await db.upload.findUnique({ where: { id: upload.id } }))?.data : upload.storageKey && await target.read(upload.storageKey);
|
|
26
|
+
if (!data) {
|
|
27
|
+
throw new UploadError("NOT_FOUND", `Upload '${upload.id}' has no bytes.`);
|
|
28
|
+
}
|
|
29
|
+
return Buffer.from(data);
|
|
30
|
+
}
|
|
31
|
+
function uploadSource({
|
|
32
|
+
db,
|
|
33
|
+
targets
|
|
34
|
+
}) {
|
|
35
|
+
const source = {
|
|
36
|
+
key: (ref) => typeof ref === "string" ? ref : ref.id,
|
|
37
|
+
read: async (ref) => {
|
|
38
|
+
const id = typeof ref === "string" ? ref : ref.id;
|
|
39
|
+
const upload = await db.upload.findUnique({ where: { id } });
|
|
40
|
+
if (upload && upload.status !== "completed") {
|
|
41
|
+
throw new UploadError("NOT_FOUND", `Upload '${id}' is not completed.`);
|
|
42
|
+
}
|
|
43
|
+
return upload && { ...upload, data: await readBytes(db, targets, upload) };
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
uploadSources.add(source);
|
|
47
|
+
return source;
|
|
48
|
+
}
|
|
49
|
+
function defineDerivedFiles(options) {
|
|
50
|
+
const {
|
|
51
|
+
db,
|
|
52
|
+
targets,
|
|
53
|
+
sources,
|
|
54
|
+
retryDelays = DEFAULT_RETRY_DELAYS,
|
|
55
|
+
claimTimeout = 10 * MINUTE,
|
|
56
|
+
onError = (error, { source, variant }) => console.error(
|
|
57
|
+
`[cedar uploads] could not make '${variant}' of ${source}:`,
|
|
58
|
+
error
|
|
59
|
+
)
|
|
60
|
+
} = options;
|
|
61
|
+
const maxAttempts = retryDelays.length + 1;
|
|
62
|
+
const sourceNames = Object.keys(sources);
|
|
63
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
64
|
+
for (const name of sourceNames) {
|
|
65
|
+
if (!SOURCE_NAME.test(name) || typeof sources[name]?.read !== "function") {
|
|
66
|
+
throw new UploadError(
|
|
67
|
+
"CONFIGURATION",
|
|
68
|
+
`Invalid derived-file source '${name}'. A source has a read() function and a name of letters, digits, '_' and '-'.`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (const [name, value] of Object.entries(options.variants)) {
|
|
73
|
+
const definition = typeof value === "function" ? { generate: value } : value;
|
|
74
|
+
const target = definition.target ?? options.target;
|
|
75
|
+
if (!VARIANT_NAME.test(name)) {
|
|
76
|
+
throw new UploadError(
|
|
77
|
+
"CONFIGURATION",
|
|
78
|
+
`Invalid variant name '${name}'. Use letters, digits, '.', '_' and '-', starting with a letter or digit.`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
if (targets[target.name] !== target) {
|
|
82
|
+
throw new UploadError(
|
|
83
|
+
"CONFIGURATION",
|
|
84
|
+
`Variant '${name}' uses a storage target that isn't in \`targets\`.`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
definitions.set(name, { generate: definition.generate, target });
|
|
88
|
+
}
|
|
89
|
+
const names = [...definitions.keys()];
|
|
90
|
+
const inFlight = /* @__PURE__ */ new Map();
|
|
91
|
+
const definitionOf = (name) => {
|
|
92
|
+
const definition = definitions.get(name);
|
|
93
|
+
if (!definition) {
|
|
94
|
+
throw new UploadError(
|
|
95
|
+
"CONFIGURATION",
|
|
96
|
+
`Unknown variant '${name}'. Configured variants: ${names.join(", ") || "(none)"}.`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
return definition;
|
|
100
|
+
};
|
|
101
|
+
const sourceOf = (ref) => {
|
|
102
|
+
const entries = Object.entries(ref);
|
|
103
|
+
const [name, value] = entries[0] ?? [];
|
|
104
|
+
if (entries.length !== 1 || !name || !Object.hasOwn(sources, name)) {
|
|
105
|
+
throw new UploadError(
|
|
106
|
+
"CONFIGURATION",
|
|
107
|
+
`Name exactly one configured source, such as \`{ upload: id }\`. Configured sources: ${sourceNames.join(", ") || "(none)"}.`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
const source = sources[name];
|
|
111
|
+
const id = source.key ? source.key(value) : value;
|
|
112
|
+
if (typeof id !== "string" || id === "") {
|
|
113
|
+
throw new UploadError(
|
|
114
|
+
"CONFIGURATION",
|
|
115
|
+
`Source '${name}' got a reference that is not a string. Give the source a key() function that turns its references into strings, or pass string references.`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
const read = (ref2) => source.read(ref2);
|
|
119
|
+
return { name, ref: value, key: `${name}:${id}`, read };
|
|
120
|
+
};
|
|
121
|
+
const findUpload = (id) => db.upload.findFirst({ where: { id }, omit: { data: true } });
|
|
122
|
+
const deleteUpload = async (id) => {
|
|
123
|
+
const upload = await findUpload(id);
|
|
124
|
+
if (upload) {
|
|
125
|
+
await deleteFile(resolveTarget(targets, upload.target), { db, upload });
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const deleteRow = async (row) => {
|
|
129
|
+
for (let current = row; current; ) {
|
|
130
|
+
if (current.uploadId) {
|
|
131
|
+
await deleteUpload(current.uploadId);
|
|
132
|
+
}
|
|
133
|
+
const { id, status, claimId, uploadId } = current;
|
|
134
|
+
const { count } = await db.derivedFile.deleteMany({
|
|
135
|
+
where: { id, status, claimId, uploadId }
|
|
136
|
+
});
|
|
137
|
+
current = count ? null : await db.derivedFile.findFirst({ where: { id } });
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
const make = async (source, name, id, claimId, attempts) => {
|
|
141
|
+
const { generate, target } = definitionOf(name);
|
|
142
|
+
const info = { source: source.key, variant: name };
|
|
143
|
+
const settle = async (status) => {
|
|
144
|
+
await db.derivedFile.updateMany({
|
|
145
|
+
where: { id, claimId },
|
|
146
|
+
data: { status, claimId: null }
|
|
147
|
+
});
|
|
148
|
+
return status === "failed" ? FAILED : PENDING;
|
|
149
|
+
};
|
|
150
|
+
let gone = false;
|
|
151
|
+
const notFound = async () => {
|
|
152
|
+
await db.derivedFile.deleteMany({ where: { id, claimId } });
|
|
153
|
+
throw new UploadError(
|
|
154
|
+
"NOT_FOUND",
|
|
155
|
+
`Can't make '${name}' of ${source.key}: the source file doesn't exist (its source's read() returned null). Pass a reference to an existing file, or catch this error where the file may have been deleted. Nothing was recorded, so a later acquire tries again.`
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
let read;
|
|
159
|
+
const readSource = () => read ??= Promise.resolve(source.read(source.ref)).then((file) => {
|
|
160
|
+
if (!file) {
|
|
161
|
+
gone = true;
|
|
162
|
+
throw new SourceGone();
|
|
163
|
+
}
|
|
164
|
+
const { buffer, byteOffset, byteLength } = file.data;
|
|
165
|
+
return { ...file, data: Buffer.from(buffer, byteOffset, byteLength) };
|
|
166
|
+
});
|
|
167
|
+
let made;
|
|
168
|
+
try {
|
|
169
|
+
const file = await generate({
|
|
170
|
+
source: { name: source.name, key: source.key, ref: source.ref },
|
|
171
|
+
variant: name,
|
|
172
|
+
readSource
|
|
173
|
+
});
|
|
174
|
+
if (file) {
|
|
175
|
+
const from = await readSource();
|
|
176
|
+
const base = from.filename?.replace(/\.[^./\\]*$/, "") || "file";
|
|
177
|
+
const ext = mime.extension(file.mimeType.split(";")[0].trim());
|
|
178
|
+
made = await storeFile(target, {
|
|
179
|
+
db,
|
|
180
|
+
filename: file.filename ?? `${base}-${name}${ext ? `.${ext}` : ""}`,
|
|
181
|
+
mimeType: file.mimeType,
|
|
182
|
+
data: file.data,
|
|
183
|
+
userId: from.userId ?? void 0,
|
|
184
|
+
organizationId: from.organizationId ?? void 0
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
} catch (e) {
|
|
188
|
+
if (gone) {
|
|
189
|
+
return notFound();
|
|
190
|
+
}
|
|
191
|
+
onError(e, info);
|
|
192
|
+
const refused = e instanceof UploadError && (e.code === "MIME_TYPE_NOT_ALLOWED" || e.code === "FILE_TOO_LARGE");
|
|
193
|
+
return settle(refused || attempts >= maxAttempts ? "failed" : "pending");
|
|
194
|
+
}
|
|
195
|
+
if (!made) {
|
|
196
|
+
return gone ? notFound() : settle("failed");
|
|
197
|
+
}
|
|
198
|
+
const madeId = made.id;
|
|
199
|
+
const dropMade = () => deleteUpload(madeId).catch((e) => onError(e, info));
|
|
200
|
+
const { count } = await db.derivedFile.updateMany({
|
|
201
|
+
where: { id, claimId },
|
|
202
|
+
data: { status: "completed", uploadId: madeId, claimId: null }
|
|
203
|
+
}).catch(async (e) => {
|
|
204
|
+
await dropMade();
|
|
205
|
+
await settle(attempts >= maxAttempts ? "failed" : "pending").catch(
|
|
206
|
+
() => void 0
|
|
207
|
+
);
|
|
208
|
+
throw e;
|
|
209
|
+
});
|
|
210
|
+
if (count !== 1) {
|
|
211
|
+
await dropMade();
|
|
212
|
+
return PENDING;
|
|
213
|
+
}
|
|
214
|
+
const upload = await findUpload(madeId);
|
|
215
|
+
return upload ? { status: "completed", upload } : PENDING;
|
|
216
|
+
};
|
|
217
|
+
const obtain = async (source, name) => {
|
|
218
|
+
const row = await db.derivedFile.findFirst({
|
|
219
|
+
where: { source: source.key, variant: name }
|
|
220
|
+
});
|
|
221
|
+
const claimId = randomUUID();
|
|
222
|
+
const claim = async (current, attempts) => {
|
|
223
|
+
const { id, status, uploadId, attempts: before } = current;
|
|
224
|
+
const { count: count2 } = await db.derivedFile.updateMany({
|
|
225
|
+
// All of it, so a row remade or retried meanwhile isn't claimed again
|
|
226
|
+
where: {
|
|
227
|
+
id,
|
|
228
|
+
status,
|
|
229
|
+
uploadId,
|
|
230
|
+
claimId: current.claimId,
|
|
231
|
+
attempts: before
|
|
232
|
+
},
|
|
233
|
+
data: { status: "pending", claimId, attempts, uploadId: null }
|
|
234
|
+
});
|
|
235
|
+
return count2 ? make(source, name, id, claimId, attempts) : PENDING;
|
|
236
|
+
};
|
|
237
|
+
if (!row) {
|
|
238
|
+
try {
|
|
239
|
+
const { id } = await db.derivedFile.create({
|
|
240
|
+
data: {
|
|
241
|
+
source: source.key,
|
|
242
|
+
variant: name,
|
|
243
|
+
status: "pending",
|
|
244
|
+
claimId,
|
|
245
|
+
attempts: 1
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
return await make(source, name, id, claimId, 1);
|
|
249
|
+
} catch (e) {
|
|
250
|
+
if (typeof e === "object" && e && "code" in e && e.code === "P2002") {
|
|
251
|
+
return PENDING;
|
|
252
|
+
}
|
|
253
|
+
throw e;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (row.status === "completed") {
|
|
257
|
+
const upload = row.uploadId ? await findUpload(row.uploadId) : null;
|
|
258
|
+
return upload ? { status: "completed", upload } : claim(row, 1);
|
|
259
|
+
}
|
|
260
|
+
const age = Date.now() - row.updatedAt.getTime();
|
|
261
|
+
if (row.status === "failed") {
|
|
262
|
+
return FAILED;
|
|
263
|
+
} else if (row.claimId === null) {
|
|
264
|
+
const wait = retryDelays[row.attempts - 1] ?? 0;
|
|
265
|
+
return age < wait ? PENDING : claim(row, row.attempts + 1);
|
|
266
|
+
} else if (age < claimTimeout) {
|
|
267
|
+
return PENDING;
|
|
268
|
+
} else if (row.attempts < maxAttempts) {
|
|
269
|
+
return claim(row, row.attempts + 1);
|
|
270
|
+
}
|
|
271
|
+
const { count } = await db.derivedFile.updateMany({
|
|
272
|
+
where: { id: row.id, claimId: row.claimId },
|
|
273
|
+
data: { status: "failed", claimId: null }
|
|
274
|
+
});
|
|
275
|
+
return count ? FAILED : PENDING;
|
|
276
|
+
};
|
|
277
|
+
const acquireVariant = async (ref, name) => {
|
|
278
|
+
definitionOf(name);
|
|
279
|
+
const source = sourceOf(ref);
|
|
280
|
+
const key = `${source.key}\0${name}`;
|
|
281
|
+
const attempt = inFlight.get(key) ?? obtain(source, name);
|
|
282
|
+
if (!inFlight.has(key)) {
|
|
283
|
+
inFlight.set(key, attempt);
|
|
284
|
+
await attempt.catch(() => null);
|
|
285
|
+
inFlight.delete(key);
|
|
286
|
+
}
|
|
287
|
+
return attempt;
|
|
288
|
+
};
|
|
289
|
+
const findVariants = async (refs, name) => {
|
|
290
|
+
definitionOf(name);
|
|
291
|
+
const keys = refs.map((ref) => sourceOf(ref).key);
|
|
292
|
+
const rows = keys.length ? await db.derivedFile.findMany({
|
|
293
|
+
where: { source: { in: keys }, variant: name, status: "completed" }
|
|
294
|
+
}) : [];
|
|
295
|
+
const ids = rows.flatMap((row) => row.uploadId ? [row.uploadId] : []);
|
|
296
|
+
const uploads = ids.length ? await db.upload.findMany({
|
|
297
|
+
where: { id: { in: ids } },
|
|
298
|
+
omit: { data: true }
|
|
299
|
+
}) : [];
|
|
300
|
+
const bySource = new Map(
|
|
301
|
+
rows.map((row) => [
|
|
302
|
+
row.source,
|
|
303
|
+
uploads.find((upload) => upload.id === row.uploadId) ?? null
|
|
304
|
+
])
|
|
305
|
+
);
|
|
306
|
+
return keys.map((key) => bySource.get(key) ?? null);
|
|
307
|
+
};
|
|
308
|
+
const deleteFor = async (ref) => {
|
|
309
|
+
const rows = await db.derivedFile.findMany({
|
|
310
|
+
where: { source: sourceOf(ref).key }
|
|
311
|
+
});
|
|
312
|
+
for (const row of rows) {
|
|
313
|
+
await deleteRow(row);
|
|
314
|
+
}
|
|
315
|
+
return rows.length;
|
|
316
|
+
};
|
|
317
|
+
return {
|
|
318
|
+
names,
|
|
319
|
+
acquireVariant,
|
|
320
|
+
acquireVariantData: async (ref, name) => {
|
|
321
|
+
const result = await acquireVariant(ref, name);
|
|
322
|
+
return result.status === "completed" ? {
|
|
323
|
+
upload: result.upload,
|
|
324
|
+
data: await readBytes(db, targets, result.upload)
|
|
325
|
+
} : null;
|
|
326
|
+
},
|
|
327
|
+
findVariant: async (ref, name) => (await findVariants([ref], name))[0],
|
|
328
|
+
findVariants,
|
|
329
|
+
resetVariants: async (name, { batchSize = 100 } = {}) => {
|
|
330
|
+
definitionOf(name);
|
|
331
|
+
const result = { deleted: 0, errors: 0 };
|
|
332
|
+
let after;
|
|
333
|
+
for (; ; ) {
|
|
334
|
+
const rows = await db.derivedFile.findMany({
|
|
335
|
+
where: { variant: name, ...after && { id: { gt: after } } },
|
|
336
|
+
orderBy: { id: "asc" },
|
|
337
|
+
take: batchSize
|
|
338
|
+
});
|
|
339
|
+
if (rows.length === 0) {
|
|
340
|
+
return result;
|
|
341
|
+
}
|
|
342
|
+
for (const row of rows) {
|
|
343
|
+
try {
|
|
344
|
+
await deleteRow(row);
|
|
345
|
+
result.deleted += 1;
|
|
346
|
+
} catch (e) {
|
|
347
|
+
result.errors += 1;
|
|
348
|
+
onError(e, { source: row.source, variant: name });
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
after = rows[rows.length - 1].id;
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
deleteFor,
|
|
355
|
+
deleteForUpload: async (upload) => {
|
|
356
|
+
const uploadNames = sourceNames.filter(
|
|
357
|
+
(n) => uploadSources.has(sources[n])
|
|
358
|
+
);
|
|
359
|
+
if (uploadNames.length === 0) {
|
|
360
|
+
throw new UploadError(
|
|
361
|
+
"CONFIGURATION",
|
|
362
|
+
"These derived files have no upload source, so none can be deleted for an upload. Add `upload: uploadSource({ db, targets })` to `sources`, or call deleteFile() without `derivedFiles`."
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
let deleted = 0;
|
|
366
|
+
for (const name of uploadNames) {
|
|
367
|
+
deleted += await deleteFor({ [name]: upload });
|
|
368
|
+
}
|
|
369
|
+
return deleted;
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
export {
|
|
374
|
+
defineDerivedFiles,
|
|
375
|
+
uploadSource
|
|
376
|
+
};
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type UploadErrorCode = 'CONFIGURATION' | 'UNKNOWN_TARGET' | 'UNKNOWN_PROFILE' | 'UNAUTHENTICATED' | 'INVALID_TOKEN' | 'TOKEN_USER_MISMATCH' | 'TOKEN_ORGANIZATION_MISMATCH' | 'MIME_TYPE_NOT_ALLOWED' | 'FILE_TOO_LARGE' | 'TOO_MANY_FILES' | 'PRESIGN_NOT_SUPPORTED' | 'NOT_SUPPORTED' | 'NOT_FOUND' | 'FORBIDDEN' | 'NOT_PENDING' | 'NOT_IN_STORAGE' | 'SIZE_MISMATCH' | 'INVALID_KEY'
|
|
1
|
+
export type UploadErrorCode = 'CONFIGURATION' | 'UNKNOWN_TARGET' | 'UNKNOWN_PROFILE' | 'UNAUTHENTICATED' | 'INVALID_TOKEN' | 'TOKEN_USER_MISMATCH' | 'TOKEN_ORGANIZATION_MISMATCH' | 'MIME_TYPE_NOT_ALLOWED' | 'FILE_TOO_LARGE' | 'TOO_MANY_FILES' | 'PRESIGN_NOT_SUPPORTED' | 'NOT_SUPPORTED' | 'NOT_FOUND' | 'FORBIDDEN' | 'NOT_PENDING' | 'NOT_IN_STORAGE' | 'SIZE_MISMATCH' | 'INVALID_KEY';
|
|
2
2
|
/**
|
|
3
3
|
* Thrown by every part of the uploads package when a request cannot be
|
|
4
4
|
* honored. `code` is stable for programmatic handling and `statusCode` is the
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,eAAe,GACf,qBAAqB,GACrB,6BAA6B,GAC7B,uBAAuB,GACvB,gBAAgB,GAChB,gBAAgB,GAChB,uBAAuB,GACvB,eAAe,GACf,WAAW,GACX,WAAW,GACX,aAAa,GACb,gBAAgB,GAChB,eAAe,GACf,aAAa,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,eAAe,GACf,qBAAqB,GACrB,6BAA6B,GAC7B,uBAAuB,GACvB,gBAAgB,GAChB,gBAAgB,GAChB,uBAAuB,GACvB,eAAe,GACf,WAAW,GACX,WAAW,GACX,aAAa,GACb,gBAAgB,GAChB,eAAe,GACf,aAAa,CAAA;AAuBjB;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACpC,IAAI,EAAE,eAAe,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;gBAEN,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAMpE"}
|
package/dist/errors.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -15,8 +15,8 @@ export { storeFile } from './storeFile.js';
|
|
|
15
15
|
export type { StoreFileOptions } from './storeFile.js';
|
|
16
16
|
export { deleteFile } from './deleteFile.js';
|
|
17
17
|
export type { DeleteFileOptions } from './deleteFile.js';
|
|
18
|
-
export {
|
|
19
|
-
export type {
|
|
18
|
+
export { defineDerivedFiles, uploadSource } from './derivedFiles.js';
|
|
19
|
+
export type { DefineDerivedFilesOptions, DerivedFileContext, DerivedFileDefinition, DerivedFileGenerator, DerivedFileOutput, DerivedFileResult, DerivedFiles, DerivedFileSource, DerivedFileSourceFile, DerivedFileSourceRef, } from './derivedFiles.js';
|
|
20
20
|
export { cleanupStaleUploads } from './cleanupStaleUploads.js';
|
|
21
21
|
export type { CleanupStaleUploadsOptions, CleanupStaleUploadsResult, } from './cleanupStaleUploads.js';
|
|
22
22
|
export { createUploadToken, UPLOAD_TOKEN_HEADER, UPLOAD_TOKEN_PURPOSE, verifyUploadToken, } from './uploadToken.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAClE,OAAO,EACL,gBAAgB,EAChB,+BAA+B,EAC/B,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,GACf,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,cAAc,GACf,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,8BAA8B,EAC9B,wBAAwB,EACxB,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AACtE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { createDbProvider } from "./providers/db.js";
|
|
|
31
31
|
import { generateStorageKey } from "./keys.js";
|
|
32
32
|
import { storeFile } from "./storeFile.js";
|
|
33
33
|
import { deleteFile } from "./deleteFile.js";
|
|
34
|
-
import {
|
|
34
|
+
import { defineDerivedFiles, uploadSource } from "./derivedFiles.js";
|
|
35
35
|
import { cleanupStaleUploads } from "./cleanupStaleUploads.js";
|
|
36
36
|
import {
|
|
37
37
|
createUploadToken,
|
|
@@ -93,11 +93,10 @@ export {
|
|
|
93
93
|
createUploadToken,
|
|
94
94
|
createWithDataUriDirective,
|
|
95
95
|
createWithSignedUrlDirective,
|
|
96
|
+
defineDerivedFiles,
|
|
96
97
|
defineStorageTargets,
|
|
97
98
|
defineUploadProfiles,
|
|
98
|
-
defineUploadVariants,
|
|
99
99
|
deleteFile,
|
|
100
|
-
deleteVariants,
|
|
101
100
|
detectContentType,
|
|
102
101
|
findZipCentralDirectory,
|
|
103
102
|
generateStorageKey,
|
|
@@ -115,6 +114,7 @@ export {
|
|
|
115
114
|
serializeUpload,
|
|
116
115
|
storeFile,
|
|
117
116
|
toDataUri,
|
|
117
|
+
uploadSource,
|
|
118
118
|
verifyServeToken,
|
|
119
119
|
verifySnsMessage,
|
|
120
120
|
verifyUploadToken,
|
package/dist/types.d.ts
CHANGED
|
@@ -43,11 +43,6 @@ export interface UploadWhere {
|
|
|
43
43
|
id?: string | {
|
|
44
44
|
in: string[];
|
|
45
45
|
};
|
|
46
|
-
/**
|
|
47
|
-
* Only exists when the `Upload` model has the variant columns. A query
|
|
48
|
-
* that uses it must handle the error Prisma raises without them.
|
|
49
|
-
*/
|
|
50
|
-
sourceId?: string;
|
|
51
46
|
target?: string;
|
|
52
47
|
status?: string | {
|
|
53
48
|
in: string[];
|
|
@@ -225,104 +220,90 @@ export interface SerializedUpload {
|
|
|
225
220
|
updatedAt: string;
|
|
226
221
|
}
|
|
227
222
|
/**
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
* it was made from and whose `variant` names what it is (`'thumb-164'`,
|
|
232
|
-
* `'preview'`). Original files have both set to `null`.
|
|
223
|
+
* One row of the opt-in `DerivedFile` table: the bookkeeping for one derived
|
|
224
|
+
* file (a thumbnail, a preview, a poster frame) of one source. The made file
|
|
225
|
+
* itself is an ordinary `Upload` row, referenced by `uploadId`.
|
|
233
226
|
*/
|
|
234
|
-
export interface
|
|
235
|
-
|
|
236
|
-
|
|
227
|
+
export interface DerivedFileRecord {
|
|
228
|
+
id: string;
|
|
229
|
+
/** The source's key, such as `upload:<id>` or `remote:<org>/<doc>`. */
|
|
230
|
+
source: string;
|
|
231
|
+
/** Name of the derived file, such as `thumb-164` or `preview`. */
|
|
232
|
+
variant: string;
|
|
233
|
+
/** The made file's `Upload` id, once it is made. */
|
|
234
|
+
uploadId: string | null;
|
|
235
|
+
/** `pending` while being made or waiting to retry, then `completed` or `failed`. */
|
|
236
|
+
status: string;
|
|
237
|
+
/** Id of the attempt making the file right now, or `null`. */
|
|
238
|
+
claimId: string | null;
|
|
239
|
+
/** How many attempts have been started. */
|
|
240
|
+
attempts: number;
|
|
241
|
+
updatedAt: Date;
|
|
237
242
|
}
|
|
238
|
-
export interface
|
|
243
|
+
export interface DerivedFileWhere {
|
|
239
244
|
id?: string | {
|
|
240
|
-
|
|
241
|
-
notIn?: string[];
|
|
245
|
+
gt: string;
|
|
242
246
|
};
|
|
243
|
-
|
|
247
|
+
source?: string | {
|
|
244
248
|
in: string[];
|
|
245
249
|
};
|
|
246
|
-
variant?: string
|
|
250
|
+
variant?: string;
|
|
247
251
|
status?: string;
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
252
|
+
claimId?: string | null;
|
|
253
|
+
uploadId?: string | null;
|
|
254
|
+
attempts?: number;
|
|
255
|
+
updatedAt?: Date | {
|
|
256
|
+
lt: Date;
|
|
253
257
|
};
|
|
254
|
-
updatedAt?: {
|
|
255
|
-
lt?: Date;
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
export interface UploadVariantCreateData extends UploadCreateData {
|
|
259
|
-
sourceId: string;
|
|
260
|
-
variant: string;
|
|
261
|
-
}
|
|
262
|
-
export interface UploadVariantUpdateData {
|
|
263
|
-
status?: UploadStatus;
|
|
264
|
-
target?: string;
|
|
265
|
-
size?: bigint;
|
|
266
|
-
storageKey?: string | null;
|
|
267
|
-
filename?: string;
|
|
268
|
-
mimeType?: string;
|
|
269
|
-
data?: Uint8Array<ArrayBuffer> | null;
|
|
270
|
-
tokenId?: string | null;
|
|
271
258
|
}
|
|
272
259
|
/**
|
|
273
|
-
* The subset of Prisma's generated `
|
|
274
|
-
*
|
|
275
|
-
*
|
|
260
|
+
* The subset of Prisma's generated `DerivedFile` delegate that derived files
|
|
261
|
+
* need. A generated client satisfies it once the schema has the
|
|
262
|
+
* `DerivedFile` model described in the uploads docs.
|
|
276
263
|
*/
|
|
277
|
-
export interface
|
|
264
|
+
export interface DerivedFileDelegate {
|
|
278
265
|
create(args: {
|
|
279
|
-
data:
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
266
|
+
data: {
|
|
267
|
+
source: string;
|
|
268
|
+
variant: string;
|
|
269
|
+
status: string;
|
|
270
|
+
claimId: string;
|
|
271
|
+
attempts: number;
|
|
284
272
|
};
|
|
285
|
-
|
|
286
|
-
data?: boolean;
|
|
287
|
-
};
|
|
288
|
-
}): Promise<UploadVariantRecord | null>;
|
|
273
|
+
}): Promise<DerivedFileRecord>;
|
|
289
274
|
findFirst(args: {
|
|
290
|
-
where:
|
|
291
|
-
|
|
292
|
-
data?: boolean;
|
|
293
|
-
};
|
|
294
|
-
orderBy?: {
|
|
295
|
-
createdAt: 'asc' | 'desc';
|
|
296
|
-
};
|
|
297
|
-
}): Promise<UploadVariantRecord | null>;
|
|
275
|
+
where: DerivedFileWhere;
|
|
276
|
+
}): Promise<DerivedFileRecord | null>;
|
|
298
277
|
findMany(args: {
|
|
299
|
-
where:
|
|
300
|
-
omit?: {
|
|
301
|
-
data?: boolean;
|
|
302
|
-
};
|
|
278
|
+
where: DerivedFileWhere;
|
|
303
279
|
orderBy?: {
|
|
304
|
-
|
|
280
|
+
id: 'asc' | 'desc';
|
|
305
281
|
};
|
|
306
282
|
take?: number;
|
|
307
|
-
}): Promise<
|
|
283
|
+
}): Promise<DerivedFileRecord[]>;
|
|
308
284
|
updateMany(args: {
|
|
309
|
-
where:
|
|
310
|
-
data:
|
|
285
|
+
where: DerivedFileWhere;
|
|
286
|
+
data: {
|
|
287
|
+
status?: string;
|
|
288
|
+
claimId?: string | null;
|
|
289
|
+
uploadId?: string | null;
|
|
290
|
+
attempts?: number;
|
|
291
|
+
};
|
|
311
292
|
}): Promise<{
|
|
312
293
|
count: number;
|
|
313
294
|
}>;
|
|
314
295
|
deleteMany(args: {
|
|
315
|
-
where:
|
|
296
|
+
where: DerivedFileWhere;
|
|
316
297
|
}): Promise<{
|
|
317
298
|
count: number;
|
|
318
299
|
}>;
|
|
319
300
|
}
|
|
320
301
|
/**
|
|
321
|
-
* The subset of a Prisma client that derived files
|
|
322
|
-
*
|
|
323
|
-
*
|
|
302
|
+
* The subset of a Prisma client that derived files need: the `Upload`
|
|
303
|
+
* delegate for the made files, and the `DerivedFile` delegate for their
|
|
304
|
+
* bookkeeping.
|
|
324
305
|
*/
|
|
325
|
-
export interface
|
|
326
|
-
|
|
306
|
+
export interface DerivedFileDatabase extends UploadDatabase {
|
|
307
|
+
derivedFile: DerivedFileDelegate;
|
|
327
308
|
}
|
|
328
309
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,0CAA0C;AAC1C,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAA;AAE7D;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,QAAQ,CAAA;AAExD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,YAAY,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAG1B,IAAI,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,IAAI,CAAA;IACrC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,GAAG;QAAE,EAAE,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC9B
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|