release: WRNexusJS 0.8.0
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-02 23:18:51 +05:30
parent 87507edf59
commit 586a6db8ff
625 changed files with 243608 additions and 11210 deletions
+43 -2
View File
@@ -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 };
}