WFDASH-WEBAPP/src/lib/pdf/render.tsx

52 lines
2.2 KiB
TypeScript
Raw Normal View History

import { pdf } from "@react-pdf/renderer";
import { QuoteDocument, type QuoteDocumentProps } from "./quote-document";
import {
PurchaseOrderDocument,
type PurchaseOrderDocumentProps,
} from "./purchase-order-document";
/**
* Server-side render of a `<QuoteDocument>` to a PDF Buffer.
*
* Uses `@react-pdf/renderer`'s Node API (`pdf(<JSX />).toBuffer()`) which
* runs entirely in-process — no headless Chromium, no Playwright/Puppeteer,
* no browser binary in the Docker image.
*
* Always returns a fresh Buffer; never cached. Reads of letterhead,
* quote, items, and customer happen in the API route before this is
* called, so any edit in PB propagates on the next generation.
*/
export async function renderQuotePdf(props: QuoteDocumentProps): Promise<Buffer> {
const instance = pdf(<QuoteDocument {...props} />);
// `toBuffer()` works in pure Node, but under jsdom (Vitest's default
// test environment) it returns a PDFKit document handle instead. We
// funnel through `toString()` which always resolves to a string of
// raw PDF bytes, then convert to a real Node Buffer. The string path
// is ~the same performance as toBuffer in production.
const pdfString = await instance.toString();
return Buffer.from(pdfString, "binary");
}
/**
* Server-side render of a `<PurchaseOrderDocument>` to a PDF Buffer.
*
* Same in-process Node pipeline as `renderQuotePdf` — no headless
* Chromium, no browser binary. The PO PDF document component is a
* pure function of its props, so the API route resolves the PO +
* items + supplier + order + customer + letterhead before calling
* this, then uploads the resulting Buffer to
* `purchase_orders.documents` (the embedded file, multi field on
* the PO record itself — replaced 2026-07-06 the separate
* `purchase_order_pdfs` collection).
*
* `toString()` is used for the same jsdom-test compat reason as the
* quote renderer — both routes are test-covered and we want them to
* produce the same shape regardless of environment.
*/
export async function renderPurchaseOrderPdf(
props: PurchaseOrderDocumentProps
): Promise<Buffer> {
const instance = pdf(<PurchaseOrderDocument {...props} />);
const pdfString = await instance.toString();
return Buffer.from(pdfString, "binary");
}