2025-09-17 11:39:26 +01:00
|
|
|
// CORS (server missing Access-Control-Allow-* headers)??
|
|
|
|
|
|
|
|
|
|
type BlobFileUpload = {
|
|
|
|
|
file: File | null;
|
|
|
|
|
opts?: {
|
|
|
|
|
timeoutMs?: number;
|
|
|
|
|
fieldName?: string;
|
|
|
|
|
overrideFileName?: string;
|
|
|
|
|
uploadUrl: URL | string;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2025-10-22 11:51:37 +01:00
|
|
|
export async function sendBlobFileUpload({ file, opts }: BlobFileUpload): Promise<string> {
|
2025-09-17 11:39:26 +01:00
|
|
|
if (!file) throw new Error("No file supplied");
|
|
|
|
|
if (!opts?.uploadUrl) throw new Error("No URL supplied");
|
|
|
|
|
|
|
|
|
|
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) {
|
2025-10-22 11:51:37 +01:00
|
|
|
throw new Error(`Upload failed (${resp.status} ${resp.statusText}) from ${opts.uploadUrl} — ${bodyText}`);
|
2025-09-17 11:39:26 +01:00
|
|
|
}
|
2025-09-19 10:09:14 +01:00
|
|
|
|
2025-09-17 11:39:26 +01:00
|
|
|
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) {
|
2025-10-22 11:51:37 +01:00
|
|
|
throw new Error(`HTTP error uploading to ${opts.uploadUrl}: ${err.message}`);
|
2025-09-17 11:39:26 +01:00
|
|
|
}
|
2025-09-19 10:09:14 +01:00
|
|
|
// Todo: fix error message response
|
|
|
|
|
return `Hotlist Load OK`;
|
|
|
|
|
// throw new Error("HTTP method POST is not supported by this URL");
|
2025-09-17 11:39:26 +01:00
|
|
|
} finally {
|
|
|
|
|
clearTimeout(timeout);
|
|
|
|
|
}
|
|
|
|
|
}
|