feat: use Typst for pdf generation, detach pipeline from browser - #1687
Draft
shivoomiess wants to merge 6 commits into
Draft
feat: use Typst for pdf generation, detach pipeline from browser#1687shivoomiess wants to merge 6 commits into
shivoomiess wants to merge 6 commits into
Conversation
Adds apps/pdf-renderer with handlebars, dom-typst and the typst.ts node compiler. No source yet, only the package skeleton and the migration plan. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Implements the four stages of the renderer: handlebars template + data -> HTML dom-typst HTML -> Typst markup assembly fragments -> one Typst document typst.ts Typst -> PDF bytes Nothing in this package needs a browser, a subprocess or the network. The Typst compiler is a native addon and assets are passed to it as in-memory shadow files. Handling around the converter keeps parity with the old Chromium engine: - data: URL images become Typst assets, so header logos still render - the pageNumber and totalPages spans become Typst page counters - CSS colour functions are tightened, which the converter otherwise mis-parses inside shorthand declarations - image sizing falls back to the intrinsic size read from the file header Includes a CLI so the pipeline can run with no server or database, and 64 tests covering each stage plus end-to-end renders of the templates the frontend seeds a new PDF template with. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Routes the two PDF types that use a user-officer defined template through the local typst renderer instead of the browser-based factory service. XLSX, ZIP, sample and shipment-label documents are untouched. sendPdf is the single decision point. It renders locally when every entity in the request carries a template, and delegates to the factory service otherwise or if a local render throws, so a template the new engine cannot handle still produces a PDF. PDF_ENGINE=factory pins every request back to the old service. Also adds multi-document rendering to the renderer, so a bulk download of several proposals becomes one Typst document with a per-entity running header, replacing the old merge of separately generated PDFs. Page numbers now run continuously across such a collection. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds documentation/docs/developer-guide/pdf_generation.md with the pipeline for each flow, the library used at every step, what still goes to the factory service, and the behaviour differences against the browser engine. Corrects the factory description in architecture.md, which claimed it generates all PDFs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
||
| const scale = options.targetPageWidthPt / options.canvasWidthPx; | ||
|
|
||
| let processed = normalizeStyles(html.replace(NON_RENDERABLE, '')); |
localRenderer imported the renderer package at module scope, and index.ts reaches that module through the factory middleware. A missing build output or a native addon that fails to load therefore stopped the whole backend from starting, which shows up in the UI as a blank page everywhere, not just a missing PDF. The renderer is now loaded on first use. If it cannot be loaded the backend starts normally, logs why, and every PDF goes to the factory service. canRenderLocally is split into isLocallyRenderable, which is about the request, and the availability check, so the request logic stays testable. Also adds a prepare script to the renderer so npm install in that package always leaves a build behind, and passes factoryBaseUrl to templates, which the factory service used to inject. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR introduces Typst for PDF generation, completely detaching the PDF rendering pipeline from the browser dependency.
Motivation and Context
This change was necessary to remove the dependency on Chromium for PDF rendering, which was causing performance and security concerns. It also simplifies the PDF rendering process by introducing Typst, a standalone package for PDF rendering with no express, no database, no DOM, and no Chromium. This results in a more efficient and secure PDF rendering pipeline.
Changes
.github/workflows/test-build.ymlto cache the pdf-renderer node_modules and to install and build the pdf-renderer before the backend installs.PDF_TYPST_MIGRATION_PLAN.mdthat contains a comprehensive plan to replace the browser-based PDF engine with Typst.{ templates, data }as input and outputs a PDFBuffer.--dump-typstand--dump-htmloptions.apps/backend/src/factory/pdf/sendPdf.tsas the single dispatch point for PDF rendering.PDF_ENGINEandPDF_PAGE_SIZEvariables, documented inapps/backend/example.development.env.How Has This Been Tested?
Fixes Jira Issue
https://jira.ess.eu//browse/
Depends On
Tests included/Docs Updated?