33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
|
|
import { renderToBuffer, renderToStream, type DocumentProps } from '@react-pdf/renderer';
|
||
|
|
import type { ReactElement } from 'react';
|
||
|
|
|
||
|
|
import { logger } from '@/lib/logger';
|
||
|
|
|
||
|
|
type DocumentElement = ReactElement<DocumentProps>;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Render a react-pdf element tree to PDF bytes. Use for one-shot PDFs that
|
||
|
|
* fit in memory comfortably (reports, record exports, parent-company exports).
|
||
|
|
*
|
||
|
|
* For photo-heavy or hundreds-of-entries PDFs, see `renderPdfStream` or use
|
||
|
|
* `expense-pdf.service.ts` (pdfkit streaming).
|
||
|
|
*/
|
||
|
|
export async function renderPdf(element: DocumentElement): Promise<Buffer> {
|
||
|
|
try {
|
||
|
|
const buf = await renderToBuffer(element);
|
||
|
|
return buf;
|
||
|
|
} catch (err) {
|
||
|
|
logger.error({ err }, 'PDF render failed');
|
||
|
|
throw new Error('Failed to render PDF');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Stream-render a react-pdf element tree. Pages are emitted incrementally so
|
||
|
|
* memory peaks are bounded. Caller should pipe the stream to the response
|
||
|
|
* (or convert via `Readable.toWeb` for a Web Response).
|
||
|
|
*/
|
||
|
|
export async function renderPdfStream(element: DocumentElement): Promise<NodeJS.ReadableStream> {
|
||
|
|
return renderToStream(element);
|
||
|
|
}
|