Files
cv/app/client/api.ts
T

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})`);
}