release: WRNexusJS 0.8.0
This commit is contained in:
@@ -31,6 +31,23 @@ export interface UploadOptions {
|
||||
accept?: string[];
|
||||
/** Key prefix, e.g. `"avatars"` → keys become `avatars/<yyyy>/<mm>/<rand>.<ext>`. */
|
||||
prefix?: string;
|
||||
/** Virus/DLP/content scanner invoked before bytes enter storage. Throw or return unsafe to reject. */
|
||||
scan?: (file: UploadScanInput) => UploadScanResult | Promise<UploadScanResult>;
|
||||
/** Image/video/indexing hook invoked after storage. Failure removes the just-written object. */
|
||||
afterStore?: (file: UploadedFile & { bytes: Uint8Array; store: Store }) => void | Promise<void>;
|
||||
}
|
||||
|
||||
export interface UploadScanInput {
|
||||
name: string;
|
||||
type: string;
|
||||
size: number;
|
||||
bytes: Uint8Array;
|
||||
store: Store;
|
||||
}
|
||||
export interface UploadScanResult {
|
||||
safe: boolean;
|
||||
reason?: string;
|
||||
scanner?: string;
|
||||
}
|
||||
|
||||
/** A 4xx-carrying error so `handleUpload` can map it to a status. */
|
||||
@@ -123,14 +140,38 @@ export async function upload(
|
||||
}
|
||||
const key = makeKey({ name: file.name, type }, opts.prefix);
|
||||
const data = new Uint8Array(await file.arrayBuffer());
|
||||
if (opts.scan) {
|
||||
const result = await opts.scan({
|
||||
name: displayName(file.name),
|
||||
type,
|
||||
size: file.size,
|
||||
bytes: data,
|
||||
store,
|
||||
});
|
||||
if (!result.safe)
|
||||
throw new UploadError(
|
||||
`file rejected by ${result.scanner ?? "security scanner"}${result.reason ? `: ${result.reason}` : ""}`,
|
||||
422,
|
||||
);
|
||||
}
|
||||
await store.driver.put(key, data, { contentType: type, filename: displayName(file.name) });
|
||||
files.push({
|
||||
const uploaded: UploadedFile = {
|
||||
key,
|
||||
url: storedUrl(store, key),
|
||||
name: displayName(file.name),
|
||||
type,
|
||||
size: file.size,
|
||||
});
|
||||
};
|
||||
try {
|
||||
await opts.afterStore?.({ ...uploaded, bytes: data, store });
|
||||
} catch (error) {
|
||||
await store.driver.delete(key);
|
||||
throw new UploadError(
|
||||
`post-upload processing failed: ${error instanceof Error ? error.message : String(error)}`,
|
||||
422,
|
||||
);
|
||||
}
|
||||
files.push(uploaded);
|
||||
}
|
||||
return { files };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user