mirror of
https://github.com/prdlk/cv.git
synced 2026-08-02 17:31:41 +00:00
58 lines
1.8 KiB
TypeScript
58 lines
1.8 KiB
TypeScript
export class ApiRequestError extends Error {
|
|
readonly log?: string;
|
|
|
|
constructor(message: string, log?: string) {
|
|
super(message);
|
|
this.name = "ApiRequestError";
|
|
this.log = log;
|
|
}
|
|
}
|
|
|
|
async function errorOf(res: Response, fallback: string): Promise<ApiRequestError> {
|
|
let message = fallback;
|
|
let log: string | undefined;
|
|
try {
|
|
const data: unknown = await res.json();
|
|
if (data && typeof data === "object") {
|
|
if ("error" in data && typeof data.error === "string") message = data.error;
|
|
if ("log" in data && typeof data.log === "string") log = data.log;
|
|
}
|
|
} catch {
|
|
/* non-JSON error body */
|
|
}
|
|
return new ApiRequestError(message, log);
|
|
}
|
|
|
|
export async function post<T>(path: string, body: unknown): Promise<T> {
|
|
const res = await fetch(path, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(body),
|
|
});
|
|
if (!res.ok) throw await errorOf(res, `${path} failed (${res.status})`);
|
|
return res.json() as Promise<T>;
|
|
}
|
|
|
|
/**
|
|
* Compile LaTeX to a PDF blob.
|
|
* Dev: the Vite middleware at /local/compile runs the machine's real pdflatex.
|
|
* Deployed: that route 404s and we fall back to the Worker's remote compile proxy.
|
|
*/
|
|
export async function compilePdf(latex: string): Promise<Blob> {
|
|
const local = await fetch("/local/compile", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ latex }),
|
|
});
|
|
if (local.ok) return local.blob();
|
|
if (local.status === 422) throw await errorOf(local, "pdflatex failed");
|
|
|
|
const remote = await fetch("/api/pdf", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ latex }),
|
|
});
|
|
if (remote.ok) return remote.blob();
|
|
throw await errorOf(remote, `PDF compile failed (${remote.status})`);
|
|
}
|