pretext-pdf 0.5.3 → 0.8.1
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/CHANGELOG.md +115 -0
- package/README.md +366 -276
- package/dist/assets.d.ts +5 -0
- package/dist/assets.d.ts.map +1 -1
- package/dist/assets.js +248 -43
- package/dist/assets.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/fonts.d.ts.map +1 -1
- package/dist/fonts.js +88 -16
- package/dist/fonts.js.map +1 -1
- package/dist/index.d.ts +29 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -2
- package/dist/index.js.map +1 -1
- package/dist/markdown.d.ts +28 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +222 -0
- package/dist/markdown.js.map +1 -0
- package/dist/measure-blocks.d.ts.map +1 -1
- package/dist/measure-blocks.js +347 -62
- package/dist/measure-blocks.js.map +1 -1
- package/dist/measure-text.d.ts.map +1 -1
- package/dist/measure-text.js +1 -8
- package/dist/measure-text.js.map +1 -1
- package/dist/measure.d.ts.map +1 -1
- package/dist/measure.js +13 -21
- package/dist/measure.js.map +1 -1
- package/dist/render-blocks.d.ts +4 -1
- package/dist/render-blocks.d.ts.map +1 -1
- package/dist/render-blocks.js +227 -105
- package/dist/render-blocks.js.map +1 -1
- package/dist/render-extras.d.ts.map +1 -1
- package/dist/render-extras.js +72 -71
- package/dist/render-extras.js.map +1 -1
- package/dist/render-utils.d.ts +9 -2
- package/dist/render-utils.d.ts.map +1 -1
- package/dist/render-utils.js +24 -13
- package/dist/render-utils.js.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +27 -3
- package/dist/render.js.map +1 -1
- package/dist/rich-text.d.ts +0 -4
- package/dist/rich-text.d.ts.map +1 -1
- package/dist/rich-text.js +15 -9
- package/dist/rich-text.js.map +1 -1
- package/dist/templates.d.ts +79 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +201 -0
- package/dist/templates.js.map +1 -0
- package/dist/types.d.ts +139 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +241 -28
- package/dist/validate.js.map +1 -1
- package/package.json +57 -12
package/CHANGELOG.md
CHANGED
|
@@ -7,8 +7,71 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.8.1] — 2026-04-20
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Browser support** — `pretext-pdf` now imports cleanly in browsers. Module-init in `src/fonts.ts` previously called `fileURLToPath(import.meta.url)` and `createRequire(import.meta.url)` eagerly, which threw `"The URL must be of scheme file"` whenever the module was loaded from a non-`file://` URL (esm.sh, jsdelivr, Vite dev server). Both calls are now gated on a runtime `IS_NODE` check, and the bundled-Inter `BUNDLED_INTER_PATHS` arrays are constructed only in Node.
|
|
15
|
+
- **Browser font-loading errors** — `loadFontBytes` now throws clear `FONT_LOAD_FAILED` messages when bundled Inter or string font paths are requested in a browser, pointing the consumer at the correct workaround (supply `Uint8Array` bytes via `doc.fonts`).
|
|
16
|
+
|
|
17
|
+
### Notes for browser users
|
|
18
|
+
|
|
19
|
+
- Always supply Inter (or your default font) explicitly via `doc.fonts: [{ family: 'Inter', weight: 400, src: <Uint8Array> }, { family: 'Inter', weight: 700, src: <Uint8Array> }]`. The library cannot read local font files in the browser.
|
|
20
|
+
- SVG / chart / qr-code / barcode elements still depend on `@napi-rs/canvas` at runtime; in the browser, the native `OffscreenCanvas` is used instead and the polyfill is skipped automatically.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## [0.8.0] — 2026-04-19
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- **`qr-code` element** — generate QR codes as inline PDF content using the `qrcode` optional peer dependency. Supports `data`, `size`, `errorCorrectionLevel` (L/M/Q/H), `foreground`/`background` hex colours, `margin`, `align`, `spaceBefore`/`spaceAfter`. Fully serverless — pure JS, no canvas required.
|
|
29
|
+
- **`barcode` element** — generate 100+ barcode symbologies (EAN-13, Code128, PDF417, QR, DataMatrix, etc.) via the `bwip-js` optional peer dependency. Supports `symbology`, `data`, `width`, `height`, `includeText`, `align`, `spaceBefore`/`spaceAfter`. Pure JS, Lambda/Edge safe.
|
|
30
|
+
- **`chart` element** — embed Vega-Lite charts as vector SVG using `vega` + `vega-lite` optional peer deps. Accepts any Vega-Lite `spec`, `width`, `height`, `caption`, `align`. Rendered with `renderer: 'none'` — zero canvas/puppeteer dependency.
|
|
31
|
+
- **`pretext-pdf/markdown` entry point** — `markdownToContent(md, options?)` converts a Markdown string to `ContentElement[]`. Requires optional `marked` peer dep. Supports headings, bold/italic/links (→ rich-paragraph), lists (2 levels), blockquotes, code blocks, and HR.
|
|
32
|
+
- **`pretext-pdf/templates` entry point** — three typed template functions with zero extra dependencies: `createInvoice(data)` (generic invoice with currency, tax, discount, QR payment), `createGstInvoice(data)` (GST-compliant Indian tax invoice with IGST/CGST+SGST, UPI QR, bank details, amount in words), `createReport(data)` (structured business report with optional TOC).
|
|
33
|
+
- **New error codes** — `QR_DEP_MISSING`, `QR_GENERATE_FAILED`, `BARCODE_DEP_MISSING`, `BARCODE_GENERATE_FAILED`, `BARCODE_SYMBOLOGY_INVALID`, `CHART_DEP_MISSING`, `CHART_SPEC_INVALID`, `CHART_RENDER_FAILED`, `MARKDOWN_DEP_MISSING`.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## [0.7.1] — 2026-04-19
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- **Upstream pretext pinned to `f2014338487a`** — picks up unreleased CJK opening-bracket annotation fix, Hangul jamo line-walker alignment fix, and two internal line-object churn reductions. No public API changes.
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- **List nesting depth enforced at validation** — `ListItem.items` (2nd-level items) now correctly rejects any further `.items` property, matching the documented 2-level maximum. Previously the validation silently passed 3-level data which could cause undefined render behaviour.
|
|
46
|
+
- **3 phase-11 list tests corrected** — test data incorrectly contained 3-level nesting while named "2-level"; data trimmed to match documented contract.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
10
50
|
## [Unreleased]
|
|
11
51
|
|
|
52
|
+
### Added (Phase 11 — Cross-cutting Enhancements)
|
|
53
|
+
|
|
54
|
+
- **`floatSpans` on image elements** — rich-text alternative to plain `floatText`. Accepts `InlineSpan[]` for mixed bold/italic/color/link captions beside float images. Mutually exclusive with `floatText` (validated).
|
|
55
|
+
- **2-level list nesting** — `ListItem.items` now supports one further level of nesting (depth 0 → 1 → 2). Unordered marker: `▪`. Ordered: inherits parent counter or restarts via `nestedNumberingStyle: 'restart'`.
|
|
56
|
+
- **Table `rowspan`** — `TableCell.rowspan` spans a cell across multiple rows. Works alongside `colspan`. Origin cell draws background over full span height; continuation rows automatically receive placeholder cells.
|
|
57
|
+
- **`onFormFieldError` callback** — `doc.onFormFieldError: (name, err) => 'skip' | 'throw'` mirrors `onImageLoadError`. Controls render behaviour when a form field fails.
|
|
58
|
+
- **`createFootnoteSet(defs)`** — helper exported from `pretext-pdf` that generates footnote definition/reference pairs with globally unique IDs. Returns `Array<{ id, def }>`.
|
|
59
|
+
- **`renderDate` field** — `doc.renderDate: Date | string` overrides the PDF creation date. Useful for reproducible builds and testing.
|
|
60
|
+
- **`{{date}}` and `{{author}}` tokens** in header/footer text — join existing `{{pageNumber}}` / `{{totalPages}}`. `{{date}}` resolves from `renderDate`; `{{author}}` resolves from `doc.metadata.author`.
|
|
61
|
+
- **`tabularNumbers`** on `rich-paragraph` — digits rendered at uniform slot width (widest digit in font), so columns of numbers align without OpenType TNUM feature.
|
|
62
|
+
- **`smallCaps` + `letterSpacing` per span** — `InlineSpan.smallCaps` and `InlineSpan.letterSpacing` now respected in `rich-paragraph` rendering.
|
|
63
|
+
- **Per-span `fontSize`** — `InlineSpan.fontSize` overrides the element-level font size for that span. Enables mixed-size text in a single paragraph.
|
|
64
|
+
|
|
65
|
+
### Fixed (Phase 11)
|
|
66
|
+
|
|
67
|
+
- `resolveTokens()` used `.replace()` (replaces first occurrence only) — changed to `.replaceAll()` for all four tokens.
|
|
68
|
+
- Table span grid: continuation-row cursor was advancing by 1 instead of `colspan` when skipping a spanned column — now advances by full span width.
|
|
69
|
+
- Font family names now validated for safe characters (`/^[a-zA-Z0-9 _-]+$/`) in `requireFamily()` — rejects null bytes and control characters.
|
|
70
|
+
- Annotation `color` and `author` fields now validated in `validateElement()` for both `paragraph` and `heading` annotations.
|
|
71
|
+
- `buildOutlineTree` memoizes `parentIdxOf()` into a pre-computed array — eliminates O(n²) scan for documents with large heading counts.
|
|
72
|
+
- Table grid-line renderer pre-computes active boundary set — eliminates O(rows × cols) inner loop for large tables.
|
|
73
|
+
- `addLinkAnnotation()` re-validates URL scheme at render time (defense-in-depth; `validate.ts` is the primary gate).
|
|
74
|
+
|
|
12
75
|
### Planned (Phase 9+)
|
|
13
76
|
|
|
14
77
|
- Phase 9A: Digital signatures (cryptographic PKCS#7 via `@signpdf/signpdf`)
|
|
@@ -17,6 +80,29 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
17
80
|
|
|
18
81
|
---
|
|
19
82
|
|
|
83
|
+
## [0.7.0] — 2026-04-17
|
|
84
|
+
|
|
85
|
+
### Added
|
|
86
|
+
|
|
87
|
+
- **6 production templates** (`templates/`) — GST invoice, international invoice, resume, multi-section report, NDA, and meeting minutes. Each is a self-contained `.ts` file outputting a valid PDF. Smoke-tested in Phase 2F Block D.
|
|
88
|
+
- **StackBlitz live demo** (`demo/stackblitz/`) — 4-tab UI (Invoice, Report, Resume, Custom) backed by a Node.js render server. Edit JSON and generate PDFs instantly, no install required. Accessible at the StackBlitz link in the README.
|
|
89
|
+
- **`## Performance` section in README** — measured render times and PDF sizes for 1-page, 10-page, and mixed-element documents. Font subsetting behaviour documented.
|
|
90
|
+
- **Stress tests and benchmarks** (`test/phase-2f-stress.test.ts`) — 32 tests across 4 blocks: large document stress (400-element, 200-row table), edge case stress (CJK, RTL, empty arrays, extreme sizes), timing benchmarks (1-page < 500 ms, 10-page < 5,000 ms), and template smoke tests.
|
|
91
|
+
- **Error code coverage** — new tests for `COLUMN_WIDTH_TOO_NARROW`, `IMAGE_LOAD_FAILED`, `SVG_LOAD_FAILED`, and `ASSEMBLY_FAILED`. 16 of 19 error codes now have direct test coverage.
|
|
92
|
+
|
|
93
|
+
### Changed
|
|
94
|
+
|
|
95
|
+
- **`as any` audit** — eliminated 10 casts in `validate.ts` by introducing a typed `FormFieldElement` local binding. The remaining 8 instances (pdf-lib interop, dynamic import, internal back-references) are now documented with one-line comments explaining the constraint.
|
|
96
|
+
- **Comparison article** (`docs/articles/pretext-pdf-vs-pdfmake-2026.md`) — 2,200-word draft covering feature matrix, typography quality, API design, performance, and migration quick-start. Marked `published: false` pending live demo.
|
|
97
|
+
- **Migration guide** (`docs/MIGRATION_FROM_PDFMAKE.md`) — 30+ pdfmake → pretext-pdf mappings, complete before/after invoice example, and a quick-start checklist. Linked from README.
|
|
98
|
+
|
|
99
|
+
### Fixed
|
|
100
|
+
|
|
101
|
+
- **Phase 2F test types** — `fontWeight: 700 as 700` cast in pre-constructed rows array; removed non-existent `creationDate` from `DocumentMetadata`; replaced `allowCopying: false` with correct `encryption: { permissions: { copying: false } }`.
|
|
102
|
+
- **StackBlitz integration** — added `.stackblitzrc` so WebContainer auto-runs `npm start` and opens the browser preview on port 3000.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
20
106
|
## [0.5.3] — 2026-04-16
|
|
21
107
|
|
|
22
108
|
### Changed
|
|
@@ -46,17 +132,21 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
46
132
|
## [0.4.0] — 2026-04-08
|
|
47
133
|
|
|
48
134
|
### Breaking Changes
|
|
135
|
+
|
|
49
136
|
- **Migrated from `pdf-lib` to `@cantoo/pdf-lib`** — `@cantoo/pdf-lib` is now a direct `dependency` (always installed). Previously it was an optional peer dependency required only for encryption. This removes the `ENCRYPTION_NOT_AVAILABLE` error code and the separate `npm install @cantoo/pdf-lib` installation step. Encryption now works out of the box.
|
|
50
137
|
- **`ENCRYPTION_NOT_AVAILABLE` error code removed** — encryption is now always available. Update any `switch` statements that handled this code.
|
|
51
138
|
|
|
52
139
|
### Why this change
|
|
140
|
+
|
|
53
141
|
`pdf-lib` (the original) has not received a meaningful commit since November 2021. `@cantoo/pdf-lib` is the actively maintained fork (v2.6.5, 107+ releases, MIT license). pretext-pdf was already using `@cantoo/pdf-lib` for encryption — this commit makes it the single source of truth for all PDF operations.
|
|
54
142
|
|
|
55
143
|
### Added
|
|
144
|
+
|
|
56
145
|
- `test/pretext-api-contract.test.ts` — canary test that asserts `@chenglou/pretext` exports the exact functions pretext-pdf depends on. Breaks loudly if pretext changes its API.
|
|
57
146
|
- `docs/ROADMAP.md` — public multi-phase development plan
|
|
58
147
|
|
|
59
148
|
### Changed
|
|
149
|
+
|
|
60
150
|
- `@chenglou/pretext` version pinned to exact `0.0.3` (no caret) — prevents surprise breaking changes from upstream auto-updates
|
|
61
151
|
- `test:contract` script added — runs the pretext API contract test before the full test suite
|
|
62
152
|
- All internal comments updated from `pdf-lib` to `@cantoo/pdf-lib`
|
|
@@ -66,6 +156,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
66
156
|
## [0.3.1] — 2026-04-08
|
|
67
157
|
|
|
68
158
|
### Fixed
|
|
159
|
+
|
|
69
160
|
- **Critical: Font resolution when installed as npm package** — `@fontsource/inter` is now resolved via `createRequire(import.meta.url)` instead of a hardcoded relative path. Previously, `path.join(__dirname, '..', 'node_modules', '@fontsource', 'inter', ...)` failed when npm hoisted the dependency to the consumer's top-level `node_modules`, causing `FONT_LOAD_FAILED` on every install. Now resolves correctly regardless of npm hoisting behavior.
|
|
70
161
|
|
|
71
162
|
---
|
|
@@ -73,6 +164,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
73
164
|
## [0.3.0] — 2026-04-08
|
|
74
165
|
|
|
75
166
|
### Added (Phase 8B — Interactive Forms)
|
|
167
|
+
|
|
76
168
|
- New `form-field` element type — creates interactive AcroForm fields in PDFs
|
|
77
169
|
- `fieldType: 'text' | 'checkbox' | 'radio' | 'dropdown' | 'button'`
|
|
78
170
|
- `label` renders above the field as static text
|
|
@@ -86,6 +178,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
86
178
|
- 10 comprehensive tests covering all form field types
|
|
87
179
|
|
|
88
180
|
### Added (Phase 8E — Signature Placeholder)
|
|
181
|
+
|
|
89
182
|
- `doc.signature` — visual signature box drawn on a specified page
|
|
90
183
|
- Fields: `signerName`, `reason`, `location`, `x`, `y`, `width`, `height`, `page`, `borderColor`, `fontSize`
|
|
91
184
|
- Draws signature line, date line, and optional text inside a bordered rectangle
|
|
@@ -93,6 +186,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
93
186
|
- 6 comprehensive tests
|
|
94
187
|
|
|
95
188
|
### Added (Phase 8D — Callout Boxes)
|
|
189
|
+
|
|
96
190
|
- New `callout` element type — styled highlight box with optional title
|
|
97
191
|
- Preset styles: `style: 'info'` (blue), `'warning'` (amber), `'tip'` (green), `'note'` (gray)
|
|
98
192
|
- Optional `title` rendered bold above content with left border accent
|
|
@@ -101,6 +195,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
101
195
|
- 8 comprehensive tests
|
|
102
196
|
|
|
103
197
|
### Added (Phase 8F — Document Metadata Extensions)
|
|
198
|
+
|
|
104
199
|
- `doc.metadata.language` — sets PDF `/Lang` catalog entry (BCP47 tag e.g. `'en-US'`, `'hi'`)
|
|
105
200
|
- `doc.metadata.producer` — sets PDF producer field (e.g. `'MyApp v2.1'`)
|
|
106
201
|
- Both fields validate as non-empty strings
|
|
@@ -111,6 +206,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
111
206
|
## [0.2.0] — 2026-04-08
|
|
112
207
|
|
|
113
208
|
### Added (Phase 8H — Inline Formatting)
|
|
209
|
+
|
|
114
210
|
- `verticalAlign: 'superscript' | 'subscript'` on `InlineSpan` in rich-paragraphs
|
|
115
211
|
- Superscript renders at 65% font size, baseline shifted up by 40% of font size
|
|
116
212
|
- Subscript renders at 65% font size, baseline shifted down by 20% of font size
|
|
@@ -120,6 +216,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
120
216
|
- 8 comprehensive tests covering all inline formatting functionality
|
|
121
217
|
|
|
122
218
|
### Added (Phase 8A — Annotations/Comments)
|
|
219
|
+
|
|
123
220
|
- New `comment` element type — sticky note annotation at position in document
|
|
124
221
|
- `annotation?: AnnotationSpec` on `ParagraphElement` and `HeadingElement` — attach note to element
|
|
125
222
|
- Supports: `contents`, `author`, `color` (hex), `open` (popup default state)
|
|
@@ -127,6 +224,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
127
224
|
- 8 comprehensive tests covering all annotation functionality
|
|
128
225
|
|
|
129
226
|
### Added (Phase 8C — Document Assembly)
|
|
227
|
+
|
|
130
228
|
- New `merge(pdfs: Uint8Array[])` exported function — combine pre-rendered PDFs
|
|
131
229
|
- New `assemble(parts: AssemblyPart[])` exported function — mix rendered docs + existing PDFs
|
|
132
230
|
- `AssemblyPart` interface: `{ doc?: PdfDocument, pdf?: Uint8Array }`
|
|
@@ -134,6 +232,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
134
232
|
- 8 comprehensive tests covering all assembly functionality
|
|
135
233
|
|
|
136
234
|
### Fixed
|
|
235
|
+
|
|
137
236
|
- **CI case-sensitivity bug**: `test/phase-7-integration.test.ts` used `'en-US'` (uppercase) for hyphenation language. On Linux CI (case-sensitive filesystem) this failed with `UNSUPPORTED_LANGUAGE`. Changed to `'en-us'` to match package name `hyphenation.en-us`.
|
|
138
237
|
|
|
139
238
|
---
|
|
@@ -141,6 +240,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
141
240
|
## [0.1.1] — 2026-04-08
|
|
142
241
|
|
|
143
242
|
### Added
|
|
243
|
+
|
|
144
244
|
- **Phase 8G: Hyperlinks** — Complete link annotation support:
|
|
145
245
|
- `paragraph.url` for external URI links on paragraphs
|
|
146
246
|
- `heading.url` for external URI links on headings
|
|
@@ -151,6 +251,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
151
251
|
- 9 comprehensive tests covering all hyperlink functionality
|
|
152
252
|
|
|
153
253
|
### Fixed
|
|
254
|
+
|
|
154
255
|
- **Memory leak in test suite**: Removed module-level `_hypherCache` in `src/measure.ts` that accumulated ~188KB per language across 255+ test runs. Changed from cached Hypher instances to fresh instances per call (negligible performance impact, massive memory savings).
|
|
155
256
|
- **Node.js version compatibility**: Replaced `--experimental-strip-types` with `tsx` runner to support Node.js 18.x, 20.x, and 22.x in CI
|
|
156
257
|
- **Broken CI examples**: Removed references to non-existent Phase 8 example scripts from GitHub Actions workflow
|
|
@@ -158,12 +259,14 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
158
259
|
- **Test suite OOM issues**: Split large test files (paginate.test.ts) into paginate-basic.test.ts to work around Node.js `--experimental-strip-types` heap exhaustion bug on files >17KB
|
|
159
260
|
|
|
160
261
|
### Changed
|
|
262
|
+
|
|
161
263
|
- `test:unit` now runs only `test/paginate-basic.test.ts` (fast, no canvas overhead)
|
|
162
264
|
- Reorganized test scripts: `test:unit`, `test:validate`, `test:e2e`, `test:phases` for better memory management
|
|
163
265
|
- Moved internal planning documentation to archive (preserved, not published)
|
|
164
266
|
- `devDependencies`: Added `@napi-rs/canvas` explicitly (was missing, causing CI failures)
|
|
165
267
|
|
|
166
268
|
### Added
|
|
269
|
+
|
|
167
270
|
- `CONTRIBUTING.md`: Development setup, TDD workflow, PR process guide
|
|
168
271
|
- `CHENG_LOU_EMAIL_DRAFT.md`: Template for requesting endorsement from pretext creator
|
|
169
272
|
- `examples/comparison-pdfmake.ts`: pdfmake version of invoice for typography comparison
|
|
@@ -173,6 +276,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
173
276
|
## [0.1.0] — 2026-04-07
|
|
174
277
|
|
|
175
278
|
### Added (Phase 7G — Encryption)
|
|
279
|
+
|
|
176
280
|
- `doc.encryption` configuration for password-protecting PDFs
|
|
177
281
|
- User password and owner password support
|
|
178
282
|
- Granular permission restrictions: printing, copying, modifying, annotating
|
|
@@ -180,6 +284,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
180
284
|
- Error code: `ENCRYPTION_NOT_AVAILABLE` when encryption is requested but dependency not installed
|
|
181
285
|
|
|
182
286
|
### Added (Phase 7F — RTL Text Support)
|
|
287
|
+
|
|
183
288
|
- Right-to-left text support for Arabic, Hebrew, and other RTL languages
|
|
184
289
|
- Unicode bidirectional text algorithm via `bidi-js`
|
|
185
290
|
- `dir` attribute on text elements: `'ltr'` | `'rtl'` | `'auto'` for per-element control
|
|
@@ -187,6 +292,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
187
292
|
- Automatic detection of mixed LTR/RTL content
|
|
188
293
|
|
|
189
294
|
### Added (Phase 7E — SVG Support)
|
|
295
|
+
|
|
190
296
|
- `{ type: 'svg', svg: '<...' }` element for embedding SVG graphics
|
|
191
297
|
- SVG rasterization via `@napi-rs/canvas`
|
|
192
298
|
- ViewBox auto-sizing: automatic height calculation from viewBox aspect ratio
|
|
@@ -196,6 +302,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
196
302
|
- Error code: `SVG_RENDER_FAILED` for SVG rasterization errors
|
|
197
303
|
|
|
198
304
|
### Added (Phase 7D — Table of Contents)
|
|
305
|
+
|
|
199
306
|
- `{ type: 'toc' }` element for automatic TOC generation
|
|
200
307
|
- Two-pass rendering pipeline ensures accurate page numbers
|
|
201
308
|
- Configurable: `title`, `showTitle`, `minLevel`/`maxLevel`, dot leaders, level indentation
|
|
@@ -203,6 +310,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
203
310
|
- Supports custom formatting via `fontSize`, `color`, `spaceAfter` parameters
|
|
204
311
|
|
|
205
312
|
### Added (Phase 7C — Hyphenation)
|
|
313
|
+
|
|
206
314
|
- Automatic word hyphenation for better justified text layout
|
|
207
315
|
- `doc.hyphenation: { language: 'en-US' }` for document-level config
|
|
208
316
|
- Liang's algorithm via `hypher` package for accurate break points
|
|
@@ -211,6 +319,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
211
319
|
- Error code: `UNSUPPORTED_LANGUAGE` when language not available
|
|
212
320
|
|
|
213
321
|
### Added (Phase 7B — Watermarks)
|
|
322
|
+
|
|
214
323
|
- `doc.watermark` for text or image watermarks on every page
|
|
215
324
|
- Text watermarks: `text`, `fontSize`, `fontWeight`, `color`, `opacity`, `rotation`
|
|
216
325
|
- Image watermarks: `image` (Uint8Array), `opacity`, `rotation`, `color` (tint)
|
|
@@ -219,6 +328,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
219
328
|
- Validation: must provide either text or image, never both required
|
|
220
329
|
|
|
221
330
|
### Added (Phase 7A — Bookmarks / PDF Outline)
|
|
331
|
+
|
|
222
332
|
- PDF sidebar bookmarks auto-generated from heading structure
|
|
223
333
|
- Enabled by default: `bookmarks: true` or `bookmarks: { minLevel: 1, maxLevel: 3 }`
|
|
224
334
|
- Level filtering: include/exclude heading levels from outline
|
|
@@ -226,6 +336,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
226
336
|
- Keyboard navigation: Cmd/Ctrl+Opt/Alt+O in PDF readers to toggle bookmark sidebar
|
|
227
337
|
|
|
228
338
|
### Added (Phase 6 — Advanced Features)
|
|
339
|
+
|
|
229
340
|
- Header and footer support with {{pageNumber}} and {{totalPages}} tokens
|
|
230
341
|
- Text decoration: strikethrough, underline
|
|
231
342
|
- Text alignment: left, center, right, justify
|
|
@@ -234,6 +345,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
234
345
|
- Tables with colspan/rowspan support
|
|
235
346
|
|
|
236
347
|
### Added (Phase 5 — Rich Text / Builder API)
|
|
348
|
+
|
|
237
349
|
- Fluent builder API for programmatic document construction
|
|
238
350
|
- Rich text element with nested formatting (bold, italic, links)
|
|
239
351
|
- Inline code and code blocks with syntax highlighting
|
|
@@ -242,6 +354,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
|
|
|
242
354
|
- Numbered and bulleted lists with nesting
|
|
243
355
|
|
|
244
356
|
### Added (Phases 1–4 — Core Engine)
|
|
357
|
+
|
|
245
358
|
- Core PDF generation via `pdf-lib`
|
|
246
359
|
- Element types: paragraph, heading, table, image, list, code, blockquote
|
|
247
360
|
- Font support: Inter bundled, custom TTF embedding
|
|
@@ -305,6 +418,7 @@ npm run test:visual # Visual regression tests
|
|
|
305
418
|
## Dependencies
|
|
306
419
|
|
|
307
420
|
### Required
|
|
421
|
+
|
|
308
422
|
- `@chenglou/pretext` — Pretext text layout engine
|
|
309
423
|
- `pdf-lib` — PDF document manipulation
|
|
310
424
|
- `@fontsource/inter` — Font: Inter (bundled)
|
|
@@ -313,6 +427,7 @@ npm run test:visual # Visual regression tests
|
|
|
313
427
|
- `hyphenation.en-us` — English hyphenation patterns (Phase 7C)
|
|
314
428
|
|
|
315
429
|
### Optional (Peer)
|
|
430
|
+
|
|
316
431
|
- `@napi-rs/canvas` — SVG rasterization (Phase 7E)
|
|
317
432
|
- `@cantoo/pdf-lib` — PDF encryption (Phase 7G)
|
|
318
433
|
|