- HTML/Markdown to PDF conversion via Puppeteer - Invoice and receipt templates - API key auth + rate limiting - Dockerfile for deployment
43 lines
1.4 KiB
TypeScript
43 lines
1.4 KiB
TypeScript
import { Router, Request, Response } from "express";
|
|
import { renderPdf } from "../services/browser.js";
|
|
import { templates, renderTemplate } from "../services/templates.js";
|
|
|
|
export const templatesRouter = Router();
|
|
|
|
// GET /v1/templates — list available templates
|
|
templatesRouter.get("/", (_req: Request, res: Response) => {
|
|
const list = Object.entries(templates).map(([id, t]) => ({
|
|
id,
|
|
name: t.name,
|
|
description: t.description,
|
|
fields: t.fields,
|
|
}));
|
|
res.json({ templates: list });
|
|
});
|
|
|
|
// POST /v1/templates/:id/render — render template to PDF
|
|
templatesRouter.post("/:id/render", async (req: Request, res: Response) => {
|
|
try {
|
|
const id = req.params.id as string;
|
|
const template = templates[id];
|
|
if (!template) {
|
|
res.status(404).json({ error: `Template '${id}' not found` });
|
|
return;
|
|
}
|
|
|
|
const data = req.body;
|
|
const html = renderTemplate(id, data);
|
|
const pdf = await renderPdf(html, {
|
|
format: data._format || "A4",
|
|
margin: data._margin,
|
|
});
|
|
|
|
const filename = data._filename || `${id}.pdf`;
|
|
res.setHeader("Content-Type", "application/pdf");
|
|
res.setHeader("Content-Disposition", `inline; filename="${filename}"`);
|
|
res.send(pdf);
|
|
} catch (err: any) {
|
|
console.error("Template render error:", err);
|
|
res.status(500).json({ error: "Template rendering failed", detail: err.message });
|
|
}
|
|
});
|