mirror of
https://github.com/prdlk/cv.git
synced 2026-08-02 17:31:41 +00:00
init(app): Setup client package for web api specific logic
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { execFile } from "node:child_process";
|
||||
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
import type { Plugin } from "vite";
|
||||
|
||||
const run = promisify(execFile);
|
||||
|
||||
/**
|
||||
* Dev-only PDF compiler. Uses the same local TeX Live toolchain as the
|
||||
* repository Makefile, so dev output is byte-identical to `make`.
|
||||
* In production the client falls back to the Worker's /api/pdf route.
|
||||
*/
|
||||
export function latexDev(): Plugin {
|
||||
return {
|
||||
name: "latex-dev-compiler",
|
||||
apply: "serve",
|
||||
configureServer(server) {
|
||||
server.middlewares.use("/local/compile", (req, res) => {
|
||||
if (req.method !== "POST") {
|
||||
res.statusCode = 405;
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
const chunks: Buffer[] = [];
|
||||
req.on("data", (c: Buffer) => chunks.push(c));
|
||||
req.on("end", () => {
|
||||
void (async () => {
|
||||
let dir: string | undefined;
|
||||
try {
|
||||
const { latex } = JSON.parse(Buffer.concat(chunks).toString("utf8")) as {
|
||||
latex: string;
|
||||
};
|
||||
dir = await mkdtemp(join(tmpdir(), "cvtex-"));
|
||||
await writeFile(join(dir, "main.tex"), latex, "utf8");
|
||||
await run("pdflatex", ["-interaction=nonstopmode", "-halt-on-error", "main.tex"], {
|
||||
cwd: dir,
|
||||
timeout: 30_000,
|
||||
});
|
||||
const pdf = await readFile(join(dir, "main.pdf"));
|
||||
res.setHeader("Content-Type", "application/pdf");
|
||||
res.end(pdf);
|
||||
} catch (err) {
|
||||
let log = err instanceof Error ? err.message : String(err);
|
||||
if (dir) {
|
||||
try {
|
||||
log = (await readFile(join(dir, "main.log"), "utf8")).slice(-4000);
|
||||
} catch {
|
||||
/* no log written */
|
||||
}
|
||||
}
|
||||
res.statusCode = 422;
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
res.end(JSON.stringify({ error: "pdflatex failed", log }));
|
||||
} finally {
|
||||
if (dir) void rm(dir, { recursive: true, force: true });
|
||||
}
|
||||
})();
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user