import type { ReactElement } from 'react'; import { type AttachmentOptions, type FacturXOptions } from './attachments.js'; export interface Color { r: number; g: number; b: number; a: number; } export interface EdgeValues { top: T; right: T; bottom: T; left: T; } export interface CornerValues { top_left: number; top_right: number; bottom_right: number; bottom_left: number; } export type ElementFlexDirection = 'Row' | 'Column' | 'RowReverse' | 'ColumnReverse'; export type ElementJustifyContent = 'FlexStart' | 'FlexEnd' | 'Center' | 'SpaceBetween' | 'SpaceAround' | 'SpaceEvenly'; export type ElementAlignItems = 'FlexStart' | 'FlexEnd' | 'Center' | 'Stretch' | 'Baseline'; export type ElementAlignContent = 'FlexStart' | 'FlexEnd' | 'Center' | 'SpaceBetween' | 'SpaceAround' | 'SpaceEvenly' | 'Stretch'; export type ElementFlexWrap = 'NoWrap' | 'Wrap' | 'WrapReverse'; export type ElementFontStyle = 'Normal' | 'Italic' | 'Oblique'; export type ElementTextAlign = 'Left' | 'Right' | 'Center' | 'Justify'; export type ElementTextDecoration = 'None' | 'Underline' | 'LineThrough'; export type ElementTextTransform = 'None' | 'Uppercase' | 'Lowercase' | 'Capitalize'; export type ElementOverflow = 'Visible' | 'Hidden'; export type ElementPosition = 'Relative' | 'Absolute'; /** * Semantic role of a layout node. Note the specific transforms below * (also documented on `ElementInfo`) — this union describes what the * runtime actually emits, not what the JSX author wrote: * * - Six discrete heading tags (`H1`–`H6`) — NO generic `'Heading'` * - `Table` wrapper containing `TableRow` / `TableCell` — one wrapper per * page fragment when the table breaks across pages (clone semantics, * like `View`). Before engine 0.14 layout unwrapped tables to sibling * rows; the wrapper was added so table-level border/background paint * and structural consumers get a real table node. * - `List` + `ListItem` + `Lbl` — from `` / `` * - `FixedHeader` / `FixedFooter` — NO single `Fixed` (split by position) * - `Bookmark` — zero-height marker from `bookmark` on a container, emitted * on every container path (fits or overflowing) and the sole carrier of * the outline entry * - `TextLine` — leaf lines under `Text` blocks (holds `textContent`) * - Inline ``/``/``/`` do not appear here; * they contribute style runs within `TextLine` * * ### When adding a new value here * * Also add a `` that produces the new nodeType to * `RICH_FIXTURE` in `packages/core/tests/layout-shape.test.ts`. * A coverage tripwire in that file fails otherwise ("declared but * never rendered"), on the exact drift risk this whole file exists * to prevent. */ export type ElementNodeType = 'View' | 'Text' | 'TextLine' | 'H1' | 'H2' | 'H3' | 'H4' | 'H5' | 'H6' | 'Table' | 'TableRow' | 'TableCell' | 'List' | 'ListItem' | 'Lbl' | 'FixedHeader' | 'FixedFooter' | 'Bookmark' | 'Image' | 'Svg' | 'QrCode' | 'Barcode' | 'Canvas' | 'Watermark' | 'BarChart' | 'LineChart' | 'PieChart' | 'AreaChart' | 'DotPlot' | 'TextField' | 'Checkbox' | 'Dropdown' | 'RadioButton'; /** * Drawing kind for the node. Governs the PDF operator the serializer * emits; NOT the same as `nodeType`, which describes semantic role. */ export type ElementKind = 'None' | 'Rect' | 'Text' | 'Image' | 'Svg' | 'QrCode' | 'Barcode' | 'Chart' | 'FormField' | 'Watermark'; export interface ElementStyleInfo { flexDirection: ElementFlexDirection; justifyContent: ElementJustifyContent; alignItems: ElementAlignItems; alignContent: ElementAlignContent; flexWrap: ElementFlexWrap; flexGrow: number; flexShrink: number; gap: number; columnGap: number; rowGap: number; position: ElementPosition; /** Offset from parent, in points. Only meaningful when `position === 'Absolute'`. */ top?: number; right?: number; bottom?: number; left?: number; margin: EdgeValues; padding: EdgeValues; borderWidth: EdgeValues; borderColor: EdgeValues; borderRadius: CornerValues; /** * Explicit `style.width` from the source. May be a number (points) or * a stringified value (e.g. percentage) — the layout engine formats * some dimension variants as strings in the JSON output. Prefer the * top-level `ElementInfo.width` for the resolved rendered width. */ width?: number | string; /** Explicit `style.height`. See `width` for shape notes. */ height?: number | string; fontFamily: string; fontSize: number; fontWeight: number; fontStyle: ElementFontStyle; lineHeight: number; letterSpacing: number; textAlign: ElementTextAlign; textDecoration: ElementTextDecoration; textTransform: ElementTextTransform; color: Color; backgroundColor: Color | null; opacity: number; overflow: ElementOverflow; breakBefore: boolean; breakable: boolean; minOrphanLines: number; minWidowLines: number; } /** * A single node in the layout tree returned by * `renderDocumentWithLayout()`. The tree does NOT mirror the JSX * source — several transforms happen during layout: * * - `` is unwrapped. Its `` children appear as sibling * `TableRow` nodes at the containing page/View level. There is no * `Table` wrapper node. * - `` and `` both produce a `List` node * containing `ListItem` children. Each `ListItem` has a `Lbl` child * (the marker "1." / "•") followed by the item's own content children. * - `` produces a `FixedHeader` nodeType and * `` produces `FixedFooter`. There is no * single `Fixed` nodeType. * - Headings render as six discrete `H1` … `H6` nodeTypes. There is * no generic `Heading` nodeType with a `level` field. * - `` block content is split into `TextLine` leaf children. * The actual text lives on `TextLine.textContent`; on non-`TextLine` * nodes (including the parent `Text` block), `textContent` is `null`. * - Inline elements (``, ``, ``, ``) do NOT * appear as their own nodes — they contribute style runs within * `TextLine` leaves. * - `` produces no node. It triggers a page break at * layout time and is otherwise invisible. * - `bookmark` on a container (``, ``, and bare `` / * `` / ``) produces a zero-height `Bookmark` marker * node (no rect, draws nothing) so the entry reaches the PDF outline. * The marker is emitted whether or not the container overflows a page, * and it is the ONLY element carrying that `bookmark` — one marker, one * outline entry. * Caveat: `bookmark` on a NON-container (``, ``, ``, * charts, form fields) still rides on that node's own element, and rows * or cells laid out inside a `
` carry it on the row/cell element. * So `Bookmark` nodes are not an exhaustive index of the document's * bookmarks — scan the `bookmark` field for that. * * The runtime-conformance test in this package asserts every one of * these transforms explicitly. If it breaks, update this JSDoc first. */ export interface ElementInfo { x: number; y: number; width: number; height: number; kind: ElementKind; nodeType: ElementNodeType; style: ElementStyleInfo; children: ElementInfo[]; /** * Rendered text for this line. Present ONLY on `TextLine` nodeType * leaves — every non-`TextLine` node (including the parent `Text` * block) emits `null` here at runtime. If you need the text of a * `Text` block, concatenate its `TextLine` children's `textContent`. */ textContent?: string | null; /** * Source file / line / column of the JSX that produced this node. * Populated only when the render pipeline seeds * `globalThis.__formeSourceMap` — currently only the CLI dev server * does that. Production `renderDocument` / `renderDocumentWithLayout` * calls never populate this field. */ sourceLocation?: { file: string; line: number; column: number; }; } export interface PageInfo { width: number; height: number; contentX: number; contentY: number; contentWidth: number; contentHeight: number; elements: ElementInfo[]; } export interface LayoutInfo { pages: PageInfo[]; } export interface RenderWithLayoutResult { pdf: Uint8Array; layout: LayoutInfo; /** * Non-fatal warnings raised during rendering (e.g. `pdfUa: true` was * requested but no embeddable font was registered, so a standard font * was left unembedded). Empty when nothing went wrong. */ warnings: string[]; } export declare function renderPdf(json: string): Promise; export declare function renderPdfWithLayout(json: string, options?: RenderDocumentOptions): Promise; export interface CertificationConfig { certificatePem: string; privateKeyPem: string; reason?: string; location?: string; contact?: string; visible?: boolean; page?: number; x?: number; y?: number; width?: number; height?: number; } /** @deprecated Use CertificationConfig */ export type SignatureConfig = CertificationConfig; export interface RenderDocumentOptions { /** Data to embed as a hidden JSON attachment in the PDF. */ embedData?: unknown; /** When true, form field values are rendered as static text. No interactive fields in output. */ flattenForms?: boolean; /** * Files to embed as PDF attachments (associated files). Under a * PDF/A-3 level each becomes a conformant associated file; PDF/A-2 * refuses attachments (it only allows other PDF/A files). */ attachments?: AttachmentOptions[]; /** * Factur-X / ZUGFeRD e-invoice container: embeds the caller-supplied * invoice XML with the spec filename, MIME type, `/AFRelationship`, * and XMP identification. Requires `pdfa: "3b"` (or 3a/3u) on the * ``. Forme does not generate or validate the XML itself. */ facturX?: FacturXOptions; /** * Opt-in post-render content audit (mirrors the HTML path's * `auditContent`): after layout, the engine verifies the laid-out * pages against the input document and reports content that was * dropped, rendered fully off-page, painted in exactly its * background's colour, or clipped to a zero-size box — as * `render defect:` entries in the result's `warnings`. Findings need * a warnings channel, so the flag is honored by * `renderDocumentWithLayout` / `renderSerializedDocWithLayout` * (`renderDocument` returns bare bytes and has nowhere to report). * Off by default; when off the render takes the exact historical * code path and output is byte-identical. */ auditContent?: boolean; } export declare function renderDocument(element: ReactElement, options?: RenderDocumentOptions): Promise; export declare function renderDocumentWithLayout(element: ReactElement, options?: RenderDocumentOptions): Promise; /** * Render a pre-serialized document object (from `serialize()`) to PDF, * resolving font sources (file paths, byte arrays) and HTTP image URLs * first. * * Use this when you have a serialized doc (e.g. from a non-react * adapter that calls its own `serialize()`) and need font/image * resolution without going through the React element-based * `renderDocument()`. The browser and worker entries export the same * pair. */ export declare function renderSerializedDoc(doc: Record, options?: RenderDocumentOptions): Promise; /** * Like `renderSerializedDoc` but also returns layout info for overlays. */ export declare function renderSerializedDocWithLayout(doc: Record, options?: RenderDocumentOptions): Promise; export declare function renderTemplate(templateJson: string, dataJson: string): Promise; export declare function renderTemplateWithLayout(templateJson: string, dataJson: string): Promise; export declare function certifyPdf(pdfBytes: Uint8Array, config: CertificationConfig): Promise; /** @deprecated Use certifyPdf */ export declare const signPdf: typeof certifyPdf; export interface RedactionRegion { /** 0-indexed page number. */ page: number; /** X coordinate in points from the left edge. */ x: number; /** Y coordinate in points from the top edge (web/screen coordinates). */ y: number; /** Width of the redaction rectangle in points. */ width: number; /** Height of the redaction rectangle in points. */ height: number; /** Fill color as hex string (e.g. "#000000"). Defaults to black. */ color?: string; } export declare function redactPdf(pdfBytes: Uint8Array, regions: RedactionRegion[]): Promise; export interface RedactionPattern { /** The text or regex pattern to search for. */ pattern: string; /** 'Literal' for exact text match (case-insensitive), 'Regex' for regex. */ pattern_type: 'Literal' | 'Regex'; /** Optional 0-indexed page to restrict search to. */ page?: number; /** Fill color as hex string (e.g. "#000000"). Defaults to black. */ color?: string; } /** * Find text regions matching patterns in a PDF. * * Searches PDF content streams for literal or regex patterns and returns * redaction regions (in web top-origin coordinates) for each match. */ export declare function findTextRegions(pdfBytes: Uint8Array, patterns: RedactionPattern[]): Promise; /** * Redact text matching patterns from a PDF. * * Convenience wrapper: finds all text matching the patterns, then * applies coordinate-based redaction to each match. */ export declare function redactText(pdfBytes: Uint8Array, patterns: RedactionPattern[]): Promise; /** * Merge multiple PDF documents into a single PDF. * * @param pdfs - Array of PDF byte arrays to merge in order. * @returns The merged PDF as a Uint8Array. */ export declare function mergePdfs(pdfs: Uint8Array[]): Promise; export { extractData } from './extract.js'; export type { AttachmentOptions, FacturXOptions, AfRelationship, FacturXProfile } from './attachments.js';