# @suaveplan/pdf - Server-tier PDF 1.4 generation toolkit (Chunks A–D): typed PDF error registry, Zod boundary schemas, OpenTelemetry counters + histograms, unit conversion, hex/RGB colour utilities, page-size + margin types, hand-rolled PDF 1.4 binary writer (with FlateDecode + AbortSignal + injectable Clock), chainable content-stream encoder, document elements (text / table / image / divider) with Zod boundaries and AbortSignal propagation, style cascade with default theme, block-flow layout engine with header/footer slots, fluent DocumentBuilder, and orchestrating renderDocument entry point round-trippable via pdf-parse. Server-tier PDF 1.4 generation toolkit. **Chunk A foundation** — pure utilities + cross-cutting wiring (typed error registry, Zod boundary schemas, OpenTelemetry counters + histograms, unit + colour utilities, page-size + margin types). The low-level writer, element primitives, layout engine, document builder, renderer, templates, and React preview component land in subsequent chunks (B–E). See [`enterprise-pdf/tasks.md`](../../../../docs/design/enterprise-pdf/tasks.md) for the chunk roadmap. ## Documentation tree - [colors](./src/colors/colors.md) — Colour utilities for `@suaveplan/pdf`. The PDF specification stores colours as three floats in the `0`-`1` range (consu… - [colors](./src/colors/colors.md) — Colour utilities for `@suaveplan/pdf`. The PDF specification stores colours as three floats in the `0`-`1` range (consu… - [content-stream](./src/content-stream/content-stream.md) — `ContentStreamEncoder` is the chainable builder for PDF 1.4 content streams used by every page emitted by `@suaveplan/p… - [content-stream](./src/content-stream/content-stream.md) — `ContentStreamEncoder` is the chainable builder for PDF 1.4 content streams used by every page emitted by `@suaveplan/p… - [divider-element](./src/divider-element/divider-element.md) — `DividerElement` renders a horizontal or vertical rule into a PDF content stream. It is the lightweight separator primi… - [divider-element](./src/divider-element/divider-element.md) — `DividerElement` renders a horizontal or vertical rule into a PDF content stream. It is the lightweight separator primi… - [document-builder](./src/document-builder/document-builder.md) — The `DocumentBuilder` provides a chainable, deterministic API for assembling a PDF document tree without touching the l… - [document-builder](./src/document-builder/document-builder.md) — The `DocumentBuilder` provides a chainable, deterministic API for assembling a PDF document tree without touching the l… - [error-codes](./src/error-codes/error-codes.md) — Declares the stable `PDF.*` error-code registry and the `PdfError` class used by every public function in `@suaveplan/p… - [error-codes](./src/error-codes/error-codes.md) — Declares the stable `PDF.*` error-code registry and the `PdfError` class used by every public function in `@suaveplan/p… - [image-element](./src/image-element/image-element.md) — `ImageElement` is the bitmap primitive of `@suaveplan/pdf`. It accepts raw JPEG or PNG bytes, decodes them at construct… - [image-element](./src/image-element/image-element.md) — `ImageElement` is the bitmap primitive of `@suaveplan/pdf`. It accepts raw JPEG or PNG bytes, decodes them at construct… - [image-registry](./src/image-registry/image-registry.md) — The `ImageRegistry` allocates and reuses PDF Image XObjects across the lifetime of a single `renderDocument` call. Each… - [image-registry](./src/image-registry/image-registry.md) — The `ImageRegistry` allocates and reuses PDF Image XObjects across the lifetime of a single `renderDocument` call. Each… - [layout-engine](./src/layout-engine/layout-engine.md) — The `LayoutEngine` owns the block-flow geometry the renderer walks to position each element on the page. It computes ef… - [layout-engine](./src/layout-engine/layout-engine.md) — The `LayoutEngine` owns the block-flow geometry the renderer walks to position each element on the page. It computes ef… - [pdf-writer](./src/pdf-writer/pdf-writer.md) — `PdfWriter` is the low-level binary writer that emits valid PDF 1.4 byte streams. It manages indirect-object allocation… - [pdf-writer](./src/pdf-writer/pdf-writer.md) — `PdfWriter` is the low-level binary writer that emits valid PDF 1.4 byte streams. It manages indirect-object allocation… - [render-pipeline](./src/render-pipeline/render-pipeline.md) — Internal pipeline helpers that the top-level `renderDocument` orchestrator delegates to. Splitting placement and slot-r… - [render-pipeline](./src/render-pipeline/render-pipeline.md) — Internal pipeline helpers that the top-level `renderDocument` orchestrator delegates to. Splitting placement and slot-r… - [renderer](./src/renderer/renderer.md) — `renderDocument` is the top-level orchestrator that turns a `Document` AST (produced by `DocumentBuilder`) into a real… - [renderer](./src/renderer/renderer.md) — `renderDocument` is the top-level orchestrator that turns a `Document` AST (produced by `DocumentBuilder`) into a real… - [schemas](./src/schemas/schemas.md) — Zod boundary schemas for the public surface of `@suaveplan/pdf`. Every value crossing the package boundary from untrust… - [schemas](./src/schemas/schemas.md) — Zod boundary schemas for the public surface of `@suaveplan/pdf`. Every value crossing the package boundary from untrust… - [style-resolver](./src/style-resolver/style-resolver.md) — The `StyleResolver` resolves a fully-populated `PdfStyle` from the package defaults, an active theme, an optional base… - [style-resolver](./src/style-resolver/style-resolver.md) — The `StyleResolver` resolves a fully-populated `PdfStyle` from the package defaults, an active theme, an optional base… - [table-element](./src/table-element/table-element.md) — `TableElement` is the tabular-data primitive of `@suaveplan/pdf`. It accepts a typed column definition + row array and… - [table-element](./src/table-element/table-element.md) — `TableElement` is the tabular-data primitive of `@suaveplan/pdf`. It accepts a typed column definition + row array and… - [telemetry](./src/telemetry/telemetry.md) — OpenTelemetry surface for `@suaveplan/pdf`. PDF generation is a load-bearing primitive in any system that emits invoice… - [telemetry](./src/telemetry/telemetry.md) — OpenTelemetry surface for `@suaveplan/pdf`. PDF generation is a load-bearing primitive in any system that emits invoice… - [invoice-template](./src/templates/invoice-template/invoice-template.md) — `createInvoiceTemplate(data, options?)` converts a typed `InvoiceData` payload into a renderer-ready `Document` for pro… - [invoice-template](./src/templates/invoice-template/invoice-template.md) — `createInvoiceTemplate(data, options?)` converts a typed `InvoiceData` payload into a renderer-ready `Document` for pro… - [receipt-template](./src/templates/receipt-template/receipt-template.md) — `createReceiptTemplate(data, options?)` converts a typed `ReceiptData` payload into a renderer-ready `Document` for com… - [receipt-template](./src/templates/receipt-template/receipt-template.md) — `createReceiptTemplate(data, options?)` converts a typed `ReceiptData` payload into a renderer-ready `Document` for com… - [report-template](./src/templates/report-template/report-template.md) — `createReportTemplate(data, options?)` converts a typed `ReportData` payload into a renderer-ready `Document` for multi… - [report-template](./src/templates/report-template/report-template.md) — `createReportTemplate(data, options?)` converts a typed `ReportData` payload into a renderer-ready `Document` for multi… - [text-element](./src/text-element/text-element.md) — `TextElement` is the flowed-text primitive of `@suaveplan/pdf`. It accepts a content string plus typography options (fo… - [text-element](./src/text-element/text-element.md) — `TextElement` is the flowed-text primitive of `@suaveplan/pdf`. It accepts a content string plus typography options (fo… - [types](./src/types/page-size.md) — Defines the page-size + page-config primitives used across every other module in `@suaveplan/pdf`. PDF measurements are… - [page-size](./src/types/page-size.md) — Defines the page-size + page-config primitives used across every other module in `@suaveplan/pdf`. PDF measurements are… - [units](./src/units/units.md) — Unit-conversion utilities for `@suaveplan/pdf`. PDF's native measurement is the **point** (`1pt = 1/72 inch`); every co… - [units](./src/units/units.md) — Unit-conversion utilities for `@suaveplan/pdf`. PDF's native measurement is the **point** (`1pt = 1/72 inch`); every co… ## Install ```bash bun add @suaveplan/pdf ``` ## Surface (Chunk A) | Subpath | Symbols | | --- | --- | | `@suaveplan/pdf/error-codes` | `PDF_CODES`, `PdfError`, `asPdfError`, `PdfErrorCode` | | `@suaveplan/pdf/schemas` | `UnitSchema`, `HexColorSchema`, `RgbColorSchema`, `MarginsSchema`, `PageConfigSchema`, `DocumentMetadataSchema`, `parseOrThrow`, `parseHexColor` | | `@suaveplan/pdf/telemetry` | `createPdfObservability`, six `record*` helpers, `PdfObservability` | | `@suaveplan/pdf/units` | `Unit`, `toPoints`, `fromPoints`, `convert`, `parseUnit`, `formatUnit` | | `@suaveplan/pdf/colors` | `RgbColor`, `PdfColor`, `hexToRgb`, `rgbToPdfColor`, `hexToPdfColor`, `rgbToHex`, `lighten`, `darken`, `COLORS`, `isTransparent` | | `@suaveplan/pdf/types` | `PageSize`, `PAGE_DIMENSIONS`, `Margins`, `DEFAULT_MARGINS`, `DocumentMetadata`, `PageConfig`, `DEFAULT_PAGE_CONFIG`, `DocumentDefinition`, `PageDefinition`, `ElementNode` | The package barrel `@suaveplan/pdf` re-exports every symbol above. ## Example ```ts import { convert, hexToPdfColor, parseOrThrow, PageConfigSchema, PAGE_DIMENSIONS, PageSize, PDF_CODES, } from "@suaveplan/pdf"; const a4 = PAGE_DIMENSIONS[PageSize.A4]; const inchInMm = convert(1, "in", "mm"); // ≈ 25.4 const accent = hexToPdfColor("#3366cc"); // PDF-native 0-1 triple const page = parseOrThrow( PageConfigSchema, requestBody.page, PDF_CODES.INVALID_PAGE_CONFIG, "bad page config" ); ``` ## Dependencies - `@suaveplan/error` — typed-error base. - `@suaveplan/opentelemetry` — counter / histogram helpers. - `@suaveplan/types` — shared `Clock` etc. for later chunks. - `@opentelemetry/api` — meter / tracer global API. - `zod` — boundary validation. - `tslib` — runtime helpers. No third-party PDF dependency. Chunk B will keep the hand-rolled PDF 1.4 writer the upstream package ships with — the spec is small enough that shipping a custom 200 LOC implementation is preferable to pulling in `pdfkit` (`~600 KB` unpacked, CommonJS-only, includes unrelated PNG and font subsystems). ## Roadmap - **Chunk B** — `pdf-writer/`, `content-stream/` (low-level binary writer + content stream encoder). - **Chunk C** — `text-element/`, `table-element/`, `image-element/`, `divider-element/`. - **Chunk D** — `layout-engine/`, `style-resolver/`, `document-builder/`, `renderer/`. - **Chunk E** — `invoice-template/`, `receipt-template/`, `report-template/`, `pdf-preview/` (React). ## Quality gate ```bash bunx turbo lint typecheck test build --filter=@suaveplan/pdf bunx turbo test:coverage --filter=@suaveplan/pdf ``` 100 / 100 / 100 / 100 Istanbul coverage on every Chunk A module.