65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
|
|
// CORS (server missing Access-Control-Allow-* headers)??
|
||
|
|
|
||
|
|
type BlobFileUpload = {
|
||
|
|
file: File | null;
|
||
|
|
opts?: {
|
||
|
|
timeoutMs?: number;
|
||
|
|
fieldName?: string;
|
||
|
|
overrideFileName?: string;
|
||
|
|
uploadUrl: URL | string;
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
export async function sendBlobFileUpload({
|
||
|
|
file,
|
||
|
|
opts,
|
||
|
|
}: BlobFileUpload): Promise<string> {
|
||
|
|
if (!file) throw new Error("No file supplied");
|
||
|
|
if (!opts?.uploadUrl) throw new Error("No URL supplied");
|
||
|
|
|
||
|
|
if (file?.type !== "text/csv") {
|
||
|
|
throw new Error("This file is not supported, please upload a CSV file.");
|
||
|
|
}
|
||
|
|
const timeoutMs = opts?.timeoutMs ?? 30000;
|
||
|
|
const fieldName = opts?.fieldName ?? "upload";
|
||
|
|
const fileName = opts?.overrideFileName ?? file?.name;
|
||
|
|
|
||
|
|
const controller = new AbortController();
|
||
|
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
||
|
|
|
||
|
|
try {
|
||
|
|
const form = new FormData();
|
||
|
|
|
||
|
|
form.append(fieldName, file, fileName);
|
||
|
|
|
||
|
|
const resp = await fetch(opts?.uploadUrl, {
|
||
|
|
method: "POST",
|
||
|
|
body: form,
|
||
|
|
signal: controller.signal,
|
||
|
|
redirect: "follow",
|
||
|
|
});
|
||
|
|
|
||
|
|
const bodyText = await resp.text();
|
||
|
|
|
||
|
|
if (!resp.ok) {
|
||
|
|
throw new Error(
|
||
|
|
`Upload failed (${resp.status} ${resp.statusText}) from ${opts.uploadUrl} — ${bodyText}`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
return bodyText;
|
||
|
|
} catch (err: unknown) {
|
||
|
|
if (err instanceof DOMException && err.name === "AbortError") {
|
||
|
|
throw new Error(`Timeout uploading to ${opts.uploadUrl}.`);
|
||
|
|
}
|
||
|
|
// In browsers, fetch throws TypeError on network-level failures
|
||
|
|
if (err instanceof TypeError) {
|
||
|
|
throw new Error(
|
||
|
|
`HTTP error uploading to ${opts.uploadUrl}: ${err.message}`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
throw new Error("HTTP method POST is not supported by this URL");
|
||
|
|
} finally {
|
||
|
|
clearTimeout(timeout);
|
||
|
|
}
|
||
|
|
}
|