pdfnative 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -40
- package/dist/index.cjs +1577 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +800 -10
- package/dist/index.d.ts +800 -10
- package/dist/index.js +1566 -67
- package/dist/index.js.map +1 -1
- package/dist/tools/build-emoji-font.js +1139 -0
- package/dist/tools/index.cjs +657 -0
- package/dist/tools/index.cjs.map +1 -0
- package/dist/tools/index.d.cts +110 -0
- package/dist/tools/index.d.ts +110 -0
- package/dist/tools/index.js +654 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/worker/index.cjs +110 -11
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.js +110 -11
- package/dist/worker/index.js.map +1 -1
- package/fonts/noto-sans-math-data.d.ts +13 -0
- package/fonts/noto-sans-math-data.js +64 -0
- package/package.json +45 -5
package/README.md
CHANGED
|
@@ -12,26 +12,29 @@
|
|
|
12
12
|
[](https://pdfnative.dev)
|
|
13
13
|
[](https://www.npmjs.com/package/pdfnative-mcp)
|
|
14
14
|
[](https://www.npmjs.com/package/pdfnative-cli)
|
|
15
|
+
[](https://www.npmjs.com/package/pdfnative-react)
|
|
15
16
|
|
|
16
17
|
Pure native PDF generation library — zero vendor dependencies. ISO 32000-1 (PDF 1.7) compliant.
|
|
17
18
|
|
|
18
19
|
## Ecosystem
|
|
19
20
|
|
|
20
|
-
pdfnative ships as
|
|
21
|
+
pdfnative ships as four coordinated packages — pick whichever entry point fits your workflow:
|
|
21
22
|
|
|
22
23
|
| Package | Latest | Use it for |
|
|
23
24
|
|---|:---:|---|
|
|
24
|
-
| [`pdfnative`](https://www.npmjs.com/package/pdfnative) | **v1.
|
|
25
|
-
| [`pdfnative-cli`](https://www.npmjs.com/package/pdfnative-cli) | **
|
|
26
|
-
| [`pdfnative-mcp`](https://www.npmjs.com/package/pdfnative-mcp) | **
|
|
25
|
+
| [`pdfnative`](https://www.npmjs.com/package/pdfnative) | **v1.5.0** | The library itself — call from Node, browsers, Workers, Deno, Bun. |
|
|
26
|
+
| [`pdfnative-cli`](https://www.npmjs.com/package/pdfnative-cli) | **v1.1.0** | Render JSON → PDF, sign (RSA + ECDSA-SHA256), inspect, verify (PAdES-T + OCSP/CRL), batch, and emit JSON Schemas from the shell. Built on pdfnative 1.3.0: 22 scripts + COLRv1 emoji, `--stream-true`, `--max-blocks`, `inspect --pdfua`, and an agent-native `--json`/`E_*`/`--dry-run`/`--summary` contract. |
|
|
27
|
+
| [`pdfnative-mcp`](https://www.npmjs.com/package/pdfnative-mcp) | **v1.3.0** | Use pdfnative from Claude Desktop, Cursor, Continue, Zed (or any stdio MCP client) — **17 production tools** including the v1.3.0 page-tree trio `merge_pdfs`, `split_pdf`, `extract_pages`, plus `validate_pdf`, `verify_pdf`, `add_attachment`, `extract_attachments`, and `extract_text`; watermark support, Unicode `normalize`, token-frugal read modes (`verbosity` / `fields`), `pdfA` flags, enriched authoring options (`outline`, `pageLabels`, nested lists, `viewerPreferences`, `cellBorders`, `cellVAlign`), a constant-time `node:crypto` signing provider, DNS-rebinding-protected HTTP transport, and per-tool `_meta.apiVersion`. Built on pdfnative 1.4.0. |
|
|
28
|
+
| [`pdfnative-react`](https://www.npmjs.com/package/pdfnative-react) | **v0.2.0** | Write PDFs as declarative JSX — `<Document>`, `<Table>`, `<Barcode>`… compiled on-device to pdfnative blocks by a custom React reconciler. Render hooks (`usePdf`), client components (`PDFViewer`), and a token-frugal `DocSpec` for AI agents. |
|
|
27
29
|
|
|
28
30
|
```bash
|
|
29
31
|
npm install pdfnative # library
|
|
32
|
+
npm install pdfnative-react react # React renderer (React 19 peer)
|
|
30
33
|
npm install -g pdfnative-cli # CLI
|
|
31
34
|
npm install -g pdfnative-mcp # MCP server
|
|
32
35
|
```
|
|
33
36
|
|
|
34
|
-
Detailed docs: [CLI guide](docs/guides/cli.md) · [MCP guide](docs/guides/mcp.md) · [Onboarding cheatsheet](docs/guides/onboarding.md).
|
|
37
|
+
Detailed docs: [CLI guide](docs/guides/cli.md) · [MCP guide](docs/guides/mcp.md) · [React guide](docs/guides/react.md) · [Onboarding cheatsheet](docs/guides/onboarding.md).
|
|
35
38
|
|
|
36
39
|
## Highlights
|
|
37
40
|
|
|
@@ -42,19 +45,26 @@ Detailed docs: [CLI guide](docs/guides/cli.md) · [MCP guide](docs/guides/mcp.md
|
|
|
42
45
|
- **Arabic positional shaping** — GSUB isolated/initial/medial/final forms + lam-alef ligatures
|
|
43
46
|
- **BiDi text layout** — Unicode Bidirectional Algorithm (UAX #9) with glyph mirroring, isolates (LRI/RLI/FSI/PDI), and explicit embeddings (LRE/RLE/LRO/RLO/PDF) including character-level X4–X5 overrides (v1.3.0)
|
|
44
47
|
- **USE-lite shaping** — `classifyUseCategory` / `classifyClusters` drive joiner classification across the Devanagari, Bengali, and Tamil shapers, fixing nukta+virama, half-form, eyelash-ra, and ya-phalaa edge cases (v1.3.0)
|
|
45
|
-
- **Colour emoji (COLRv1)** — opt-in Noto Color Emoji subset; solid + linear + radial gradient layers rendered as native PDF Form XObjects; monochrome fallback when not registered (v1.3.0). Variation selectors, ZWJ/ZWNJ, and skin-tone modifiers no longer leave tofu, and glyph `/BBox` is computed from contour bounds so emoji are never clipped (v1.3.0). [Guide →](docs/guides/colour-emoji.md)
|
|
48
|
+
- **Colour emoji (COLRv1)** — opt-in Noto Color Emoji subset; solid + linear + radial gradient layers rendered as native PDF Form XObjects; monochrome fallback when not registered (v1.3.0). Variation selectors, ZWJ/ZWNJ, and skin-tone modifiers no longer leave tofu, and glyph `/BBox` is computed from contour bounds so emoji are never clipped (v1.3.0). **Advanced compositing** (v1.4.0): COLRv1 sweep (conic) gradients render as native flat-shaded wedges, and `PaintComposite` separable blend modes (Multiply, Screen, Overlay, Darken, Lighten, …) map to PDF `/BM` ExtGState; structural Porter-Duff modes fall back to monochrome. [Guide →](docs/guides/colour-emoji.md)
|
|
46
49
|
- **Multi-font fallback** — automatic cross-script font switching with continuation bias
|
|
47
50
|
- **TTF subsetting** — only used glyphs embedded (dramatic file size reduction)
|
|
48
51
|
- **Tagged PDF / PDF/A** — structure tree, /ActualText, XMP metadata, sRGB OutputIntent (PDF/A-1b, 2b, 2u, 3b with embedded file attachments)
|
|
49
52
|
- **PDF Encryption** — AES-128 (V4/R4) and AES-256 (V5/R6), owner + user passwords, granular permissions
|
|
50
|
-
- **Free-form document builder** — headings, paragraphs, lists, tables, images, barcodes, SVG paths, form fields, spacers, page breaks, table of contents. Configurable block limit via `layout.maxBlocks` (default 100 000) for very large reports (v1.3.0)
|
|
51
|
-
- **Smart tables** — multi-page slicing with repeated headers, auto-wrap on column overflow, zebra striping, captions, and smart auto-fit columns (v1.2.0). [Guide →](docs/guides/tables.md)
|
|
53
|
+
- **Free-form document builder** — headings, paragraphs, lists (incl. **nested / hierarchical** bullet & numbered lists, v1.4.0), tables, images, barcodes, SVG paths, form fields, spacers, page breaks, table of contents. Configurable block limit via `layout.maxBlocks` (default 100 000) for very large reports (v1.3.0)
|
|
54
|
+
- **Smart tables** — multi-page slicing with repeated headers, auto-wrap on column overflow, zebra striping, captions, and smart auto-fit columns (v1.2.0), plus per-cell **borders** (`cellBorders`) and **vertical alignment** (`cellVAlign` / `ColumnDef.vAlign`, v1.4.0). [Guide →](docs/guides/tables.md)
|
|
52
55
|
- **Barcode & QR code generation** — Code 128, EAN-13, QR Code, Data Matrix, PDF417 — pure PDF path operators (no images)
|
|
53
|
-
- **SVG
|
|
56
|
+
- **SVG rendering** — path, rect, circle, ellipse, line, polyline, polygon as native PDF operators, plus `<text>` elements rendered as upright PDF text with `x`/`y` positioning and `text-anchor` (start/middle/end) support (v1.5.0)
|
|
54
57
|
- **AcroForm fields** — text, multiline, checkbox, radio, dropdown, listbox with appearance streams (ISO 32000-1 §12.7)
|
|
55
|
-
- **Digital signatures** — CMS/PKCS#7 detached signatures with RSA + ECDSA, SHA-256/384/512, X.509 parsing (ISO 32000-1 §12.8). One-call placeholder injection via `addSignaturePlaceholder()` (v1.2.0)
|
|
56
|
-
- **Streaming output** — AsyncGenerator-based progressive PDF emission with configurable chunk size, object-boundary page-by-page streaming, and **true constant-memory streaming** (`buildDocumentPDFStreamTrue()`, v1.3.0) where the full PDF binary never materialises. [Guide →](docs/guides/streaming.md)
|
|
57
|
-
- **
|
|
58
|
+
- **Digital signatures** — CMS/PKCS#7 detached signatures with RSA + ECDSA, SHA-256/384/512, X.509 parsing (ISO 32000-1 §12.8). One-call placeholder injection via `addSignaturePlaceholder()` (v1.2.0). Pluggable **native crypto provider** (`setCryptoProvider()` / `PdfSignOptions.provider`, v1.4.0) for constant-time, hardware-backed signing (`node:crypto` / Web Crypto / HSM)
|
|
59
|
+
- **Streaming output** — AsyncGenerator-based progressive PDF emission with configurable chunk size, object-boundary page-by-page streaming, and **true constant-memory streaming** (`buildDocumentPDFStreamTrue()`, v1.3.0) where the full PDF binary never materialises. One-call `streamToFile()` drains any stream to disk with back-pressure and `AbortSignal` support (v1.4.0). [Guide →](docs/guides/streaming.md)
|
|
60
|
+
- **Document outline & page labels** — nested bookmarks (`/Outlines` tree, with bold/italic/colour, collapsible nodes via `open: false`, explicit or `outline: 'auto'` from headings) and logical page numbering (`/PageLabels`: decimal, roman, alpha, prefixes, custom start) (v1.4.0). [Guide →](docs/guides/outlines.md)
|
|
61
|
+
- **Viewer preferences** — `PdfLayoutOptions.viewerPreferences` controls initial `/PageLayout` & `/PageMode` plus the `/ViewerPreferences` dict (hide toolbar/menubar, fit/center window, display doc title, non-full-screen mode, reading direction, print scaling) — PDF/A-safe (v1.4.0). [Guide →](docs/guides/viewer-preferences.md)
|
|
62
|
+
- **Font-data validator** — opt-in `validateFontData()` structurally checks custom font modules (SFNT magic, base64 integrity, cmap coverage, glyph-id range, width array, finite metrics) and returns `{ valid, errors, warnings }` (v1.4.0). [Guide →](docs/guides/font-validation.md)
|
|
63
|
+
- **PDF parser & modifier** — read existing PDFs (tokenizer, xref, object parser, FlateDecode inflate) + incremental modification. Read-only PDF/UA structural checker `validatePdfUA()` (ISO 14289-1: MarkInfo, StructTree, ParentTree, Lang, per-page MCID uniqueness) (v1.3.0). **Page-tree manipulation** (v1.4.0): `mergePdfs()`, `splitPdf()`, `extractPages()` rebuild a clean object graph (inherited attributes resolved, annotations/signatures optionally dropped, deterministic trailer `/ID`, bounded-depth copy, 256 MiB output cap via `maxOutputSize`). **Round-trip readers** (v1.5.0): `getPageLabels()` parses `/PageLabels` back into a typed `PageLabelRange[]`; `getAnnotations()` / `getPageRef()` read page annotations, and `PdfModifier.addAnnotation()` injects new ones incrementally. [Guide →](docs/guides/pdf-manipulation.md)
|
|
64
|
+
- **Markup annotations** — typed annotation model (text, highlight, underline, strikeout, squiggly, square, circle, line, freetext) via `buildAnnotation()` / `buildAnnotationBody()`, plus `PdfReader.getAnnotations()` and `PdfModifier.addAnnotation()` for round-trip read/write (v1.5.0). [Guide →](docs/guides/annotations.md)
|
|
65
|
+
- **Layout debug & inspection** — opt-in `layout: { debug: true }` overlays margin / content / cell boxes for visual layout debugging; `inspectDocumentLayout()` returns a programmatic per-page block-geometry report. Byte-identical when debug is off (v1.5.0). [Guide →](docs/guides/debugging.md)
|
|
66
|
+
- **Math & technical symbols** — bundleable math font under lang `'math'`; mathematical operators, Greek, arrows, and technical symbols route automatically via script detection (v1.5.0)
|
|
67
|
+
- **Font-data tooling** — `pdfnative/tools` exposes `compileFontData()` / `parseFontData()` to build and introspect font-data modules programmatically (v1.5.0)
|
|
58
68
|
- **Image embedding** — JPEG (DCTDecode) and PNG (FlateDecode) with auto-scaling and alignment
|
|
59
69
|
- **Hyperlinks** — PDF link annotations (/URI) with URL validation, blue underlined text, tagged /Link
|
|
60
70
|
- **Header/footer templates** — configurable `PageTemplate` with left/center/right zones and `{page}`/`{pages}`/`{date}`/`{title}` placeholders
|
|
@@ -63,12 +73,13 @@ Detailed docs: [CLI guide](docs/guides/cli.md) · [MCP guide](docs/guides/mcp.md
|
|
|
63
73
|
- **FlateDecode compression** — zlib stream compression (50–90% size reduction), zero-dependency, platform-native
|
|
64
74
|
- **Web Worker support** — off-main-thread generation for large datasets
|
|
65
75
|
- **Tree-shakeable** — ESM + CJS dual build with TypeScript declarations
|
|
66
|
-
- **95%+ test coverage** —
|
|
76
|
+
- **95%+ test coverage** — 2218+ tests across 93 files, fuzz suite, dual-mode visual-regression suite, performance benchmarks
|
|
67
77
|
- **NPM provenance** — signed builds via GitHub Actions OIDC
|
|
68
78
|
- **On-device generation** — runs in Node, browsers, Workers, Deno, Bun. No SaaS round-trip; documents never leave the calling process unless your application explicitly sends them
|
|
69
79
|
- **No telemetry, no network calls** — verifiable in source. The library never opens a socket, fetches remote fonts, or phones home
|
|
70
|
-
- **AI client integration** — use pdfnative from Claude Desktop, Cursor, Continue, and Zed via [`pdfnative-mcp`](https://github.com/Nizoka/pdfnative-mcp)
|
|
71
|
-
- **Command-line interface** — render, sign,
|
|
80
|
+
- **AI client integration** — use pdfnative from Claude Desktop, Cursor, Continue, and Zed via [`pdfnative-mcp`](https://github.com/Nizoka/pdfnative-mcp) — **17 production tools** (generate, tables, barcodes, forms, sign, verify, validate, attachments, extraction, inspect, plus page-tree `merge_pdfs` / `split_pdf` / `extract_pages`)
|
|
81
|
+
- **Command-line interface** — render, sign, verify, inspect, and batch-render PDFs from the shell with [`pdfnative-cli`](https://github.com/Nizoka/pdfnative-cli) — zero-config, scriptable, agent-native (`--json`/`E_*`/`--dry-run`), ideal for CI/CD pipelines
|
|
82
|
+
- **React renderer** — author PDFs as declarative JSX with [`pdfnative-react`](https://github.com/Nizoka/pdfnative-react): `<Document>`/`<Table>`/`<Barcode>` components, `usePdf`/`PDFViewer` client hooks, on-device rendering with no DOM or headless browser
|
|
72
83
|
|
|
73
84
|
## Installation
|
|
74
85
|
|
|
@@ -86,8 +97,8 @@ npm install pdfnative
|
|
|
86
97
|
- ♿ **Accessibility:** [docs/guides/accessibility.md](docs/guides/accessibility.md) — tagged PDF, PDF/UA, PDF/A.
|
|
87
98
|
- ❓ **FAQ:** [docs/guides/faq.md](docs/guides/faq.md) — fonts, encryption, signatures, comparisons.
|
|
88
99
|
- 🛠️ **Troubleshooting:** [docs/guides/troubleshooting.md](docs/guides/troubleshooting.md) — common pitfalls.
|
|
89
|
-
- 🎮 **Playgrounds:** [docs/playgrounds/extreme-scripts
|
|
90
|
-
- 🧪 **Sample PDFs:** [scripts/generators/](scripts/generators/) — ~
|
|
100
|
+
- 🎮 **Playgrounds:** eight interactive demos at [docs/playgrounds/](docs/playgrounds/) — [extreme-scripts](docs/playgrounds/extreme-scripts.html) (live BiDi/Indic stress tests), [all-scripts](docs/playgrounds/all-scripts.html) (every Unicode script), [medical-800](docs/playgrounds/medical-800.html) (800-page Web Worker showcase), [toolkit](docs/playgrounds/toolkit.html) (v1.4.0 bookmarks, page labels, viewer prefs, nested lists, cell borders, merge/split/extract), plus [cli](docs/playgrounds/cli.html), [mcp](docs/playgrounds/mcp.html) and [react](docs/playgrounds/react.html) ecosystem explorers.
|
|
101
|
+
- 🧪 **Sample PDFs:** [scripts/generators/](scripts/generators/) — ~210 sample PDFs across 41 categories (see [Sample PDFs](#sample-pdfs) below).
|
|
91
102
|
|
|
92
103
|
## Why pdfnative?
|
|
93
104
|
|
|
@@ -393,6 +404,28 @@ npx pdfnative-build-font fonts/ttf/MyFont.ttf fonts/my-font-data.js
|
|
|
393
404
|
|
|
394
405
|
The tool extracts cmap, widths, metrics, GSUB, GPOS, and embeds the raw TTF as base64.
|
|
395
406
|
|
|
407
|
+
### Full colour-emoji coverage (`pdfnative-build-emoji-font`)
|
|
408
|
+
|
|
409
|
+
The bundled colour-emoji module (`pdfnative/fonts/noto-color-emoji-data.js`)
|
|
410
|
+
ships a lean curated subset to keep the package small. When you need glyphs
|
|
411
|
+
beyond that subset — up to the **full ~3,600-glyph** Noto Color Emoji set — a
|
|
412
|
+
second bundled binary generates a custom data module on demand, so even
|
|
413
|
+
**pdfnative-only** users get full coverage without the package ever carrying the
|
|
414
|
+
~32 MB source font:
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
# Download the pinned Noto Color Emoji (SHA-256 verified) and emit every glyph
|
|
418
|
+
npx pdfnative-build-emoji-font --download --all --out my-color-emoji-data.js
|
|
419
|
+
|
|
420
|
+
# …or build from a local TTF, selecting only the glyphs you need
|
|
421
|
+
npx pdfnative-build-emoji-font --ttf NotoColorEmoji-Regular.ttf \
|
|
422
|
+
--codepoints "1F600,1F680,2764" --out my-color-emoji-data.js
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Select glyphs with `--all`, `--preset`, `--codepoints`, or `--ranges`, then
|
|
426
|
+
register the generated module under lang `'emoji'`. See the
|
|
427
|
+
[Colour-emoji CLI guide](docs/guides/colour-emoji-cli.md).
|
|
428
|
+
|
|
396
429
|
## Visual PDF Inspection
|
|
397
430
|
|
|
398
431
|
<a id="sample-pdfs"></a>
|
|
@@ -403,7 +436,7 @@ Generate sample PDFs for all supported languages to visually verify output:
|
|
|
403
436
|
npm run test:generate
|
|
404
437
|
```
|
|
405
438
|
|
|
406
|
-
This creates
|
|
439
|
+
This creates **~210 PDF files** in `test-output/` (git-ignored), organized in twenty-nine categories (including `emoji/` and `pdfa-latin/` added in v1.1.0, and `math/`, `svg/`, `debug/`, `annotations/`, `tools/` added in v1.5.0).
|
|
407
440
|
See [scripts/README.md](scripts/README.md) for the modular generator architecture.
|
|
408
441
|
|
|
409
442
|
### Financial Statements (per language)
|
|
@@ -617,6 +650,24 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
617
650
|
| `parser-modified.pdf` | Generated → parsed → modified → incremental save |
|
|
618
651
|
| `parser-document.pdf` | Document builder → parser round-trip verification |
|
|
619
652
|
|
|
653
|
+
### Outline & Page Label Samples (v1.4.0)
|
|
654
|
+
|
|
655
|
+
| File | Content |
|
|
656
|
+
|------|---------|
|
|
657
|
+
| `outline/outline-explicit.pdf` | Nested bookmarks (`/Outlines`) + roman/decimal page labels |
|
|
658
|
+
| `outline/outline-auto.pdf` | `outline: 'auto'` — bookmarks derived from headings |
|
|
659
|
+
| `outline/page-labels.pdf` | Roman front matter + prefixed appendix page labels |
|
|
660
|
+
|
|
661
|
+
### PDF Manipulation Samples (v1.4.0)
|
|
662
|
+
|
|
663
|
+
| File | Content |
|
|
664
|
+
|------|---------|
|
|
665
|
+
| `manipulation/merged.pdf` | `mergePdfs()` — multiple documents combined |
|
|
666
|
+
| `manipulation/split-report.pdf` | `splitPdf()` — first page range |
|
|
667
|
+
| `manipulation/split-invoice.pdf` | `splitPdf()` — second page range |
|
|
668
|
+
| `manipulation/extract-reordered.pdf` | `extractPages()` — selected pages, reordered |
|
|
669
|
+
| `manipulation/streamed.pdf` | `streamToFile()` — document streamed straight to disk |
|
|
670
|
+
|
|
620
671
|
## API Reference
|
|
621
672
|
|
|
622
673
|
### Core
|
|
@@ -680,12 +731,36 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
680
731
|
| `encodePDF417(data, ecLevel?)` | Encode data into PDF417 codewords (ISO 15438) |
|
|
681
732
|
| `renderPDF417(data, x, y, w, h, ecLevel?)` | Render PDF417 barcode as PDF path operators |
|
|
682
733
|
|
|
683
|
-
### SVG
|
|
734
|
+
### SVG Rendering
|
|
684
735
|
|
|
685
736
|
| Function | Description |
|
|
686
737
|
|----------|-------------|
|
|
687
738
|
| `parseSvgPath(d)` | Parse SVG path `d` attribute into segments |
|
|
688
|
-
| `renderSvg(segments, options?)` | Render SVG segments as PDF
|
|
739
|
+
| `renderSvg(segments, options?)` | Render SVG segments (paths + `<text>`) as PDF operators |
|
|
740
|
+
|
|
741
|
+
### Markup Annotations
|
|
742
|
+
|
|
743
|
+
| Function | Description |
|
|
744
|
+
|----------|-------------|
|
|
745
|
+
| `buildAnnotation(annot, objNum)` | Build a full markup annotation indirect object (v1.5.0) |
|
|
746
|
+
| `buildAnnotationBody(annot)` | Build a markup annotation dictionary body (for the modifier) (v1.5.0) |
|
|
747
|
+
|
|
748
|
+
Supported `MarkupAnnotation` types: `text`, `highlight`, `underline`, `strikeout`, `squiggly`, `square`, `circle`, `line`, `freetext`.
|
|
749
|
+
|
|
750
|
+
### Layout Debug & Inspection
|
|
751
|
+
|
|
752
|
+
| Function | Description |
|
|
753
|
+
|----------|-------------|
|
|
754
|
+
| `inspectDocumentLayout(params, layout?)` | Return a programmatic per-page block-geometry `LayoutInspection` (v1.5.0) |
|
|
755
|
+
|
|
756
|
+
Enable the visual overlay via `layout: { debug: true }` or a granular `LayoutDebugOptions` (`showMargins` / `showContentBounds` / `showCells`). Byte-identical when debug is off.
|
|
757
|
+
|
|
758
|
+
### Font-Data Tools (`pdfnative/tools`)
|
|
759
|
+
|
|
760
|
+
| Function | Description |
|
|
761
|
+
|----------|-------------|
|
|
762
|
+
| `compileFontData(buffer, opts?)` | Compile a TTF/OTF `Uint8Array` into a font-data module source string (v1.5.0) |
|
|
763
|
+
| `parseFontData(buffer, opts?)` | Parse a TTF/OTF `Uint8Array` into a `FontDataObject` (metrics, cmap, widths, glyph coverage) (v1.5.0) |
|
|
689
764
|
|
|
690
765
|
### AcroForm Fields
|
|
691
766
|
|
|
@@ -704,6 +779,8 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
704
779
|
| `buildSigDict(options)` | Build `/Sig` dictionary with ByteRange/Contents placeholders |
|
|
705
780
|
| `signPdfBytes(pdf, options)` | Sign a PDF with CMS/PKCS#7 detached signature |
|
|
706
781
|
| `estimateContentsSize(options)` | Estimate hex-encoded `/Contents` size for pre-allocation |
|
|
782
|
+
| `setCryptoProvider(provider)` | Install (or clear with `null`) a global native signature provider (v1.4.0) |
|
|
783
|
+
| `getCryptoProvider()` | Return the current global `CryptoProvider`, or `null` (v1.4.0) |
|
|
707
784
|
|
|
708
785
|
### Streaming Output
|
|
709
786
|
|
|
@@ -720,6 +797,7 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
720
797
|
| `chunkBinaryString(str, chunkSize)` | Split binary string into `Uint8Array` chunks |
|
|
721
798
|
| `concatChunks(chunks)` | Concatenate `Uint8Array` chunks into one |
|
|
722
799
|
| `streamByteLength(stream)` | Count total bytes from an async stream |
|
|
800
|
+
| `streamToFile(stream, filePath, opts?)` | Drain an `AsyncGenerator<Uint8Array>` to disk with back-pressure + `AbortSignal` (Node) — returns `{ bytesWritten, chunks }` (v1.4.0) |
|
|
723
801
|
|
|
724
802
|
### Crypto (Hashing, ASN.1, RSA, ECDSA, X.509, CMS)
|
|
725
803
|
|
|
@@ -749,6 +827,13 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
749
827
|
| `dictGet(dict, key)` / `dictGetName(dict, key)` | Dictionary value accessors |
|
|
750
828
|
| `inflateSync(data)` | Decompress FlateDecode data (zlib inflate) |
|
|
751
829
|
| `validatePdfUA(bytes)` | Read-only PDF/UA structural checker — returns `{ valid, errors, warnings }` (v1.3.0) |
|
|
830
|
+
| `mergePdfs(sources, opts?)` | Merge multiple PDFs into one, rebuilding a clean object graph; `opts.maxOutputSize` caps output at 256 MiB by default (v1.4.0) |
|
|
831
|
+
| `splitPdf(src, ranges, opts?)` | Split a PDF into multiple documents by inclusive 0-based page ranges (v1.4.0) |
|
|
832
|
+
| `extractPages(src, indices, opts?)` | Extract specific pages (0-based) into a new PDF (v1.4.0) |
|
|
833
|
+
| `reader.getPageLabels()` | Parse an existing `/PageLabels` number tree into `PageLabelRange[]` or `null` (v1.5.0) |
|
|
834
|
+
| `reader.getAnnotations(pageIndex)` | Read a page's annotations into `ParsedAnnotation[]` (v1.5.0) |
|
|
835
|
+
| `reader.getPageRef(pageIndex)` | Get the indirect `PdfRef` for a page (v1.5.0) |
|
|
836
|
+
| `modifier.addAnnotation(pageIndex, body)` | Inject a new annotation on a page via incremental update (v1.5.0) |
|
|
752
837
|
|
|
753
838
|
### Document Block Types
|
|
754
839
|
|
|
@@ -757,7 +842,7 @@ See [scripts/README.md](scripts/README.md) for the modular generator architectur
|
|
|
757
842
|
| `HeadingBlock` | H1/H2/H3 with color, auto-wrapped |
|
|
758
843
|
| `ParagraphBlock` | Text with fontSize, lineHeight, align, indent, color |
|
|
759
844
|
| `TableBlock` | Headers + rows using PdfRow/ColumnDef |
|
|
760
|
-
| `ListBlock` | Bullet or numbered items |
|
|
845
|
+
| `ListBlock` | Bullet or numbered items; entries may be plain strings or nested `ListItem` `{ text, items }` for hierarchical lists (v1.4.0) |
|
|
761
846
|
| `ImageBlock` | JPEG/PNG with optional width, height, align, alt text |
|
|
762
847
|
| `LinkBlock` | Hyperlink with URL, blue underline, tagged /Link |
|
|
763
848
|
| `SpacerBlock` | Vertical whitespace |
|
|
@@ -820,6 +905,7 @@ const pdf = buildPDFBytes(params, { compress: true });
|
|
|
820
905
|
| `hasFontLoader(lang)` | Check if loader is registered |
|
|
821
906
|
| `getRegisteredLangs()` | List registered language codes |
|
|
822
907
|
| `createEncodingContext(fontEntries)` | Create encoding context |
|
|
908
|
+
| `validateFontData(data)` | Opt-in structural validation of custom font data — returns `{ valid, errors, warnings }` (v1.4.0) |
|
|
823
909
|
|
|
824
910
|
### Shaping
|
|
825
911
|
|
|
@@ -848,6 +934,7 @@ const pdf = buildPDFBytes(params, { compress: true });
|
|
|
848
934
|
| `isTeluguCodepoint(cp)` | Telugu codepoint predicate (v1.3.0) |
|
|
849
935
|
| `containsSinhala(text)` / `containsTibetan(text)` / `containsKhmer(text)` / `containsMyanmar(text)` / `containsEthiopic(text)` | Detect script content (v1.3.0) |
|
|
850
936
|
| `isSinhalaCodepoint(cp)` / `isTibetanCodepoint(cp)` / `isKhmerCodepoint(cp)` / `isMyanmarCodepoint(cp)` / `isEthiopicCodepoint(cp)` | Codepoint predicates (v1.3.0) |
|
|
937
|
+
| `containsMath(text)` / `isMathCodepoint(cp)` | Detect / test mathematical symbols → lang `'math'` (v1.5.0) |
|
|
851
938
|
|
|
852
939
|
### Layout Constants
|
|
853
940
|
|
|
@@ -864,15 +951,13 @@ const pdf = buildPDFBytes(params, { compress: true });
|
|
|
864
951
|
|
|
865
952
|
## Ecosystem
|
|
866
953
|
|
|
867
|
-
pdfnative ships as a library, but
|
|
954
|
+
pdfnative ships as a library, but three official companion packages cover the most common non-library use cases — a CLI, an MCP server, and a React renderer. All live in separate repositories and depend on `pdfnative` only through the public API, so the core library stays zero-dependency.
|
|
868
955
|
|
|
869
956
|
### pdfnative-cli — command-line interface
|
|
870
957
|
|
|
871
|
-
[`pdfnative-cli`](https://github.com/Nizoka/pdfnative-cli)
|
|
872
|
-
|
|
873
|
-
**New in v0.3.0:** ECDSA-SHA256 (P-256) signing fully wired, real CMS/PKCS#7 verification with RFC 3161 timestamp detection, automatic signature-placeholder injection on `sign`, plus three iteration-friendly `render` flags (`--watch`, `--template`, `--font {latin,emoji}`). **100 % backward-compatible** with v0.2.0.
|
|
958
|
+
[`pdfnative-cli`](https://github.com/Nizoka/pdfnative-cli) v1.1.0 is the **official CLI**, built on `pdfnative` v1.3.0. It exposes six commands — `render`, `sign`, `inspect`, `verify`, `batch`, and `schema` (plus `completion`) — for use in shell scripts, Makefiles, GitHub Actions, and Docker images. Zero extra runtime dependencies, npm-provenance-signed, with a CycloneDX SBOM attached to every release.
|
|
874
959
|
|
|
875
|
-
**
|
|
960
|
+
**New in v1.1.0:** **22 Unicode scripts + COLRv1 colour emoji** through the `--font`/`--lang` shortcuts, **true constant-memory streaming** (`--stream-true`), a `--max-blocks` cap for very large documents, and a **PDF/UA (ISO 14289-1) structural validator** (`inspect --pdfua` / `--check pdfua`). It also adds an **agent-native contract** — a global `--json` status/error envelope, stable `E_*` error codes, a `--dry-run` validation mode, the new **`schema`** command (Draft 2020-12), and token-economy output projection (`--summary` / `--fields` + compact JSON) that cuts agent output ~90 %. **100 % backward-compatible.**
|
|
876
961
|
|
|
877
962
|
```bash
|
|
878
963
|
# render with full layout coverage (encryption + watermark + PDF/A-2b)
|
|
@@ -886,21 +971,27 @@ npx pdfnative-cli sign --input report.pdf --output signed.pdf \
|
|
|
886
971
|
--signing-time 2026-04-28T10:00:00Z \
|
|
887
972
|
--cert-chain intermediate.pem
|
|
888
973
|
|
|
889
|
-
# verify embedded signatures (byte-range + chain + trust)
|
|
974
|
+
# verify embedded signatures (byte-range + chain + trust + revocation)
|
|
890
975
|
npx pdfnative-cli verify --input signed.pdf --strict --trust ca-root.pem
|
|
891
976
|
|
|
892
|
-
# inspect with CI assertions (exit 1 on failure)
|
|
977
|
+
# inspect with CI assertions, incl. PDF/UA accessibility gate (exit 1 on failure)
|
|
893
978
|
npx pdfnative-cli inspect --input signed.pdf \
|
|
894
|
-
--check pdfa --check signed --
|
|
979
|
+
--check pdfa --check signed --check pdfua --json --summary
|
|
895
980
|
```
|
|
896
981
|
|
|
897
|
-
See the [CLI Guide](https://pdfnative.dev/guides/cli.html) for the full
|
|
982
|
+
See the [CLI Guide](https://pdfnative.dev/guides/cli.html) for the full v1.1.0 reference, agent contract, security model, and recipes. Try the [interactive CLI playground](https://pdfnative.dev/playgrounds/cli.html) to build commands without leaving the browser.
|
|
898
983
|
|
|
899
984
|
### pdfnative-mcp — Model Context Protocol server
|
|
900
985
|
|
|
901
|
-
[`pdfnative-mcp`](https://github.com/Nizoka/pdfnative-mcp)
|
|
986
|
+
[`pdfnative-mcp`](https://github.com/Nizoka/pdfnative-mcp) v1.3.0 is a **Model Context Protocol server** that bridges pdfnative to any MCP-compatible AI client. Once configured, your AI assistant can generate PDFs, embed barcodes, create forms, sign and verify documents, validate PDF/UA structure, embed and extract attachments, extract text, render international text, merge, split and extract pages, and inspect existing PDFs — all without writing code.
|
|
902
987
|
|
|
903
|
-
**
|
|
988
|
+
**v1.0.0:** first stable MCP release with 12 tools, `verify_pdf`, `add_attachment` (Factur-X / ZUGFeRD PDF/A-3), `extract_text`, smart-table options, auto-placeholder signing, and `_meta.apiVersion`.
|
|
989
|
+
|
|
990
|
+
**v1.1.0:** adds `validate_pdf`, six additional scripts (Telugu, Sinhala, Tibetan, Khmer, Myanmar, Ethiopic), and COLRv1 colour-emoji support via the pdfnative 1.3.0 engine.
|
|
991
|
+
|
|
992
|
+
**v1.2.0:** adds `extract_attachments`, watermark options on document tools, Unicode `normalize` (NFC/NFD/NFKC/NFKD), token-frugal read modes (`verbosity`/`fields`), and returns base64 PDF bytes once via a `resource` block.
|
|
993
|
+
|
|
994
|
+
**v1.3.0:** adds the page-tree trio `merge_pdfs` / `split_pdf` / `extract_pages` (**17 tools** total), enriched authoring options (`outline`, `pageLabels`, nested lists, `viewerPreferences`, `cellBorders`, `cellVAlign`), a constant-time `node:crypto` signing provider, and DNS-rebinding protection on the HTTP transport — all via the pdfnative 1.4.0 engine.
|
|
904
995
|
|
|
905
996
|
```bash
|
|
906
997
|
npx -y pdfnative-mcp
|
|
@@ -911,14 +1002,22 @@ npx -y pdfnative-mcp
|
|
|
911
1002
|
| Tool | Purpose |
|
|
912
1003
|
|------|---------|
|
|
913
1004
|
| `generate_basic_pdf` | Multi-page documents from structured blocks (headings, paragraphs, lists) |
|
|
914
|
-
| `add_table` |
|
|
1005
|
+
| `add_table` | Smart tables (`wrap`, `repeatHeader`, `zebra`, `caption`, `minRowHeight`, `cellPadding`) |
|
|
915
1006
|
| `add_barcode` | QR Code, Code 128, EAN-13, Data Matrix, PDF417 |
|
|
916
|
-
| `add_international_text` |
|
|
1007
|
+
| `add_international_text` | 24 script/font codes (22 Unicode scripts + `latin` + `emoji`) with BiDi & OpenType shaping |
|
|
917
1008
|
| `add_form` | Interactive AcroForm PDFs (text, checkbox, radio, dropdown) |
|
|
918
1009
|
| `embed_image` | Embed a JPEG or PNG image (base64) |
|
|
919
1010
|
| `prepare_signature_placeholder` | PDF with a `/Sig` field ready to be signed |
|
|
920
1011
|
| `sign_pdf` | CMS/PKCS#7 digital signatures (RSA-SHA256 / ECDSA-SHA256) |
|
|
921
|
-
| `
|
|
1012
|
+
| `validate_pdf` | **v1.1.0** — read-only PDF/UA structural validation |
|
|
1013
|
+
| `verify_pdf` | **v1.0.0** — verify every PAdES signature (integrity + value + optional chain trust) |
|
|
1014
|
+
| `add_attachment` | **v1.0.0** — PDF/A-3 with embedded files (Factur-X / ZUGFeRD) |
|
|
1015
|
+
| `extract_attachments` | **v1.2.0** — extract embedded files (optionally metadata-only) |
|
|
1016
|
+
| `extract_text` | **v1.0.0** — best-effort plain-text extraction from a non-encrypted PDF |
|
|
1017
|
+
| `merge_pdfs` | **v1.3.0** — concatenate 2–50 PDFs into one via the page-tree API |
|
|
1018
|
+
| `split_pdf` | **v1.3.0** — split one PDF into one document per page range (multi-output) |
|
|
1019
|
+
| `extract_pages` | **v1.3.0** — pull an arbitrary, order-preserving page subset (max 5000) into a new PDF |
|
|
1020
|
+
| `inspect_pdf` | Structured PDF report (metadata, pages, signatures, PDF/A, attachments, placeholder state) |
|
|
922
1021
|
|
|
923
1022
|
### Claude Desktop configuration
|
|
924
1023
|
|
|
@@ -929,7 +1028,7 @@ npx -y pdfnative-mcp
|
|
|
929
1028
|
"command": "npx",
|
|
930
1029
|
"args": ["-y", "pdfnative-mcp"],
|
|
931
1030
|
"env": {
|
|
932
|
-
"
|
|
1031
|
+
"PDFNATIVE_MCP_OUTPUT_DIR": "/Users/you/Documents/mcp-pdfs"
|
|
933
1032
|
}
|
|
934
1033
|
}
|
|
935
1034
|
}
|
|
@@ -938,6 +1037,30 @@ npx -y pdfnative-mcp
|
|
|
938
1037
|
|
|
939
1038
|
See the [MCP Integration Guide](https://pdfnative.dev/guides/mcp.html) and the [pdfnative-mcp repository](https://github.com/Nizoka/pdfnative-mcp) for configuration on Cursor, Continue, Zed, and more.
|
|
940
1039
|
|
|
1040
|
+
### pdfnative-react — declarative JSX renderer
|
|
1041
|
+
|
|
1042
|
+
[`pdfnative-react`](https://github.com/Nizoka/pdfnative-react) v0.2.0 turns declarative **JSX** into real, on-device PDFs powered by the zero-dependency pdfnative engine — no DOM, no headless browser, no SaaS round-trips. A custom React reconciler compiles your component tree synchronously into the pdfnative block model. Requires **React 19** and **Node.js ≥ 20** (React is a peer dependency; pdfnative itself stays zero-dependency).
|
|
1043
|
+
|
|
1044
|
+
```tsx
|
|
1045
|
+
import { Document, Heading, Text, Table, renderToBytes } from 'pdfnative-react';
|
|
1046
|
+
|
|
1047
|
+
const bytes = renderToBytes(
|
|
1048
|
+
<Document title="Invoice #1024" footerText="Acme Inc">
|
|
1049
|
+
<Heading level={1}>Invoice #1024</Heading>
|
|
1050
|
+
<Text>Thank you for your business.</Text>
|
|
1051
|
+
<Table
|
|
1052
|
+
headers={['Item', 'Qty', 'Total']}
|
|
1053
|
+
rows={[{ cells: ['Pro plan', '1', '$49.00'], type: 'default', pointed: false }]}
|
|
1054
|
+
zebra
|
|
1055
|
+
/>
|
|
1056
|
+
</Document>,
|
|
1057
|
+
); // → Uint8Array, a valid PDF
|
|
1058
|
+
```
|
|
1059
|
+
|
|
1060
|
+
Every component (`Document`, `Page`, `Heading`, `Paragraph`/`Text`, `List`/`Item`, `Table`/`Row`/`Cell`, `Image`, `Link`, `Spacer`, `PageBreak`, `TableOfContents`, `Barcode`, `Svg`, `FormField`) maps 1:1 onto a pdfnative block. Render with `renderToBytes` / `renderToBlob` / `renderToStream` / `renderToFile`, preview live with the `usePdf` hook and `PDFViewer` / `PDFDownloadLink` / `BlobProvider` client components, or let AI agents author documents with the token-frugal `DocSpec` (terse JSON tuples that compile to the *same* PDF, validated by a versioned JSON Schema).
|
|
1061
|
+
|
|
1062
|
+
See the [React Guide](https://pdfnative.dev/guides/react.html) for the full component reference, and try the [interactive React playground](https://pdfnative.dev/playgrounds/react.html) to render JSX to PDF in your browser.
|
|
1063
|
+
|
|
941
1064
|
## Architecture
|
|
942
1065
|
|
|
943
1066
|
```
|
|
@@ -1000,7 +1123,7 @@ src/
|
|
|
1000
1123
|
|
|
1001
1124
|
fonts/ # Pre-built font data modules (22 scripts)
|
|
1002
1125
|
tools/ # CLI: build-font-data.cjs (TTF → JS module)
|
|
1003
|
-
scripts/ # Modular sample PDF generation (
|
|
1126
|
+
scripts/ # Modular sample PDF generation (41 generators, 210+ PDFs)
|
|
1004
1127
|
tests/ # 1726+ tests (48 files: unit + integration + fuzz + parser)
|
|
1005
1128
|
bench/ # Performance benchmarks (vitest bench)
|
|
1006
1129
|
```
|
|
@@ -1013,9 +1136,9 @@ cd pdfnative
|
|
|
1013
1136
|
npm install
|
|
1014
1137
|
|
|
1015
1138
|
npm run build # tsup → dist/ (ESM + CJS + .d.ts)
|
|
1016
|
-
npm run test # vitest run (
|
|
1139
|
+
npm run test # vitest run (2218+ tests)
|
|
1017
1140
|
npm run test:coverage # vitest with v8 coverage (95%+)
|
|
1018
|
-
npm run test:generate # Generate
|
|
1141
|
+
npm run test:generate # Generate ~210 sample PDFs → test-output/
|
|
1019
1142
|
npm run lint # ESLint 9 + typescript-eslint strict
|
|
1020
1143
|
npm run typecheck # tsc --noEmit (src/)
|
|
1021
1144
|
npm run typecheck:tests # tsc --project tsconfig.test.json
|
|
@@ -1028,7 +1151,7 @@ npm run bench # Performance benchmarks (vitest bench)
|
|
|
1028
1151
|
|
|
1029
1152
|
| Metric | Value |
|
|
1030
1153
|
|--------|-------|
|
|
1031
|
-
| Tests |
|
|
1154
|
+
| Tests | 2218+ (93 files) |
|
|
1032
1155
|
| Statement coverage | 95.41% |
|
|
1033
1156
|
| Branch coverage | 87.79% |
|
|
1034
1157
|
| Function coverage | 98.5% |
|