pretext-pdf 0.9.3 → 1.0.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.
Files changed (106) hide show
  1. package/CHANGELOG.md +141 -1
  2. package/README.md +874 -795
  3. package/dist/allowed-props.d.ts +1 -0
  4. package/dist/allowed-props.d.ts.map +1 -1
  5. package/dist/allowed-props.js +2 -0
  6. package/dist/allowed-props.js.map +1 -1
  7. package/dist/assets.d.ts +4 -2
  8. package/dist/assets.d.ts.map +1 -1
  9. package/dist/assets.js +22 -1
  10. package/dist/assets.js.map +1 -1
  11. package/dist/benchmarks/corpora.d.ts +11 -0
  12. package/dist/benchmarks/corpora.d.ts.map +1 -0
  13. package/dist/benchmarks/corpora.js +228 -0
  14. package/dist/benchmarks/corpora.js.map +1 -0
  15. package/dist/builder.d.ts +10 -2
  16. package/dist/builder.d.ts.map +1 -1
  17. package/dist/builder.js +12 -4
  18. package/dist/builder.js.map +1 -1
  19. package/dist/cli.js +19 -19
  20. package/dist/element-types.d.ts +16 -0
  21. package/dist/element-types.d.ts.map +1 -0
  22. package/dist/element-types.js +16 -0
  23. package/dist/element-types.js.map +1 -0
  24. package/dist/errors.d.ts +8 -1
  25. package/dist/errors.d.ts.map +1 -1
  26. package/dist/errors.js +4 -0
  27. package/dist/errors.js.map +1 -1
  28. package/dist/fonts.d.ts +2 -1
  29. package/dist/fonts.d.ts.map +1 -1
  30. package/dist/fonts.js.map +1 -1
  31. package/dist/index.d.ts +21 -17
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +25 -309
  34. package/dist/index.js.map +1 -1
  35. package/dist/layout-state.d.ts +39 -0
  36. package/dist/layout-state.d.ts.map +1 -0
  37. package/dist/layout-state.js +46 -0
  38. package/dist/layout-state.js.map +1 -0
  39. package/dist/measure-blocks.d.ts +2 -1
  40. package/dist/measure-blocks.d.ts.map +1 -1
  41. package/dist/measure-blocks.js.map +1 -1
  42. package/dist/measure.d.ts +4 -2
  43. package/dist/measure.d.ts.map +1 -1
  44. package/dist/measure.js +15 -5
  45. package/dist/measure.js.map +1 -1
  46. package/dist/page-sizes.d.ts +1 -0
  47. package/dist/page-sizes.d.ts.map +1 -1
  48. package/dist/page-sizes.js.map +1 -1
  49. package/dist/paginate.d.ts +1 -1
  50. package/dist/paginate.d.ts.map +1 -1
  51. package/dist/paginate.js +11 -2
  52. package/dist/paginate.js.map +1 -1
  53. package/dist/pipeline-footnotes.d.ts +18 -0
  54. package/dist/pipeline-footnotes.d.ts.map +1 -0
  55. package/dist/pipeline-footnotes.js +98 -0
  56. package/dist/pipeline-footnotes.js.map +1 -0
  57. package/dist/pipeline-toc.d.ts +11 -0
  58. package/dist/pipeline-toc.d.ts.map +1 -0
  59. package/dist/pipeline-toc.js +28 -0
  60. package/dist/pipeline-toc.js.map +1 -0
  61. package/dist/pipeline.d.ts +24 -0
  62. package/dist/pipeline.d.ts.map +1 -0
  63. package/dist/pipeline.js +116 -0
  64. package/dist/pipeline.js.map +1 -0
  65. package/dist/plugin-registry.d.ts +40 -0
  66. package/dist/plugin-registry.d.ts.map +1 -0
  67. package/dist/plugin-registry.js +104 -0
  68. package/dist/plugin-registry.js.map +1 -0
  69. package/dist/plugin-types.d.ts +185 -0
  70. package/dist/plugin-types.d.ts.map +1 -0
  71. package/dist/plugin-types.js +27 -0
  72. package/dist/plugin-types.js.map +1 -0
  73. package/dist/post-process.d.ts +16 -0
  74. package/dist/post-process.d.ts.map +1 -0
  75. package/dist/post-process.js +80 -0
  76. package/dist/post-process.js.map +1 -0
  77. package/dist/render-blocks.d.ts +2 -1
  78. package/dist/render-blocks.d.ts.map +1 -1
  79. package/dist/render-blocks.js.map +1 -1
  80. package/dist/render-extras.d.ts +2 -2
  81. package/dist/render-extras.d.ts.map +1 -1
  82. package/dist/render-extras.js.map +1 -1
  83. package/dist/render.d.ts +4 -2
  84. package/dist/render.d.ts.map +1 -1
  85. package/dist/render.js +23 -4
  86. package/dist/render.js.map +1 -1
  87. package/dist/types-internal.d.ts +302 -0
  88. package/dist/types-internal.d.ts.map +1 -0
  89. package/dist/types-internal.js +9 -0
  90. package/dist/types-internal.js.map +1 -0
  91. package/dist/types-public.d.ts +1031 -0
  92. package/dist/types-public.d.ts.map +1 -0
  93. package/dist/types-public.js +2 -0
  94. package/dist/types-public.js.map +1 -0
  95. package/dist/types.d.ts +6 -1224
  96. package/dist/types.d.ts.map +1 -1
  97. package/dist/types.js +7 -0
  98. package/dist/types.js.map +1 -1
  99. package/dist/validate.d.ts +6 -4
  100. package/dist/validate.d.ts.map +1 -1
  101. package/dist/validate.js +50 -17
  102. package/dist/validate.js.map +1 -1
  103. package/package.json +192 -184
  104. package/docs/screenshots/showcase-invoice.png +0 -0
  105. package/docs/screenshots/showcase-report.png +0 -0
  106. package/docs/screenshots/showcase-resume.png +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,143 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.0.1] — 2026-05-02
11
+
12
+ Patch: strict mode correctness fixes. No API changes.
13
+
14
+ ### Fixed
15
+
16
+ - **`levenshteinDist` early-exit bug** — per-cell `if (curr[j]! > 2) return 999` inside
17
+ the inner DP loop fired on intermediate cells, causing d=1 pairs like `hrefs→href` and
18
+ `spaceafter→spaceAfter` to incorrectly return 999 instead of 1. Fix: removed the per-cell
19
+ guard; final check only (`prev[n]! > 2 ? 999 : prev[n]!`).
20
+ - **Seven path-prefix annotations** — strict-mode error paths had `(type)` suffixes
21
+ (e.g. `doc(table).rows[0]`) that no other validator used and that tests didn't expect.
22
+ All seven removed so paths are plain dot-notation.
23
+ - **`encryption` block not strict-checked** — unknown props inside `doc.encryption`
24
+ were silently accepted in strict mode. Now validated against `ALLOWED_PROPS_SUB['encryption']`.
25
+ - **Root path was `'document'` not `'doc'`** — top-level `assertUnknownProps` was called
26
+ with `'document'` as the path prefix, producing paths like `document.content[0]` instead
27
+ of `doc.content[0]`. Corrected to `'doc'`.
28
+ - **Suggestion format mismatched** — `Did you mean 'x'?` → `did you mean "x"` (lowercase,
29
+ double-quotes) to match the format tests asserted.
30
+ - **`formatErrors` missing header** — multi-error output now begins with
31
+ `Strict validation failed (N issues):\n` so callers can detect strict vs. regular errors.
32
+
33
+ ### Tests
34
+
35
+ - Added `test/validate-strict.test.ts` (35 tests) to `test:unit` script — these tests were
36
+ written but not wired into CI in v1.0.0.
37
+
38
+ ---
39
+
40
+ ## [1.0.0] — 2026-05-02
41
+
42
+ First stable release. Completes the plugin extension API, closes all v1.0 gate requirements,
43
+ and ships a fully verified public surface with zero breaking changes from 0.9.x.
44
+
45
+ ### Added
46
+
47
+ - **Plugin extension API** — Register custom element types via `RenderOptions.plugins`.
48
+ Each `PluginDefinition` participates in all four pipeline stages: `validate`, `loadAsset`,
49
+ `measure`, and `render`. Plugins are fully typed and tree-shaken from documents
50
+ that don't use them. See README § Custom element types (plugins) and
51
+ `examples/plugin-custom-element.ts` for a runnable example.
52
+ - **`PluginDefinition`, `PluginMeasureContext`, `PluginMeasureResult`, `PluginRenderContext`**
53
+ exported from `pretext-pdf` public surface (previously internal).
54
+ - **`PdfBuilder` and `PdfBuilderOptions`** exported from `pretext-pdf` (enables type-safe
55
+ builder construction in downstream code without re-declaring the interface).
56
+ - **`TocEntryElement`** exported from `pretext-pdf` public surface (was in the `ContentElement`
57
+ union but not individually importable).
58
+ - **`plugins` option on `createPdf()`** — `PdfBuilderOptions.plugins` threads plugins through
59
+ the builder's `build()` call automatically.
60
+ - **`Intl.Segmenter` pre-flight guard** in `render()` — throws `RENDER_FAILED` with a clear
61
+ message on Node.js < 16 or runtimes without full-ICU data, instead of silently producing
62
+ incorrect line breaks.
63
+ - **`PluginRenderContext.pageWidth/pageHeight/margins`** — render hooks now receive full page
64
+ geometry for layout calculations (page-relative positioning, bleed boxes, etc.).
65
+ - **`render` context Y-coordinate docs** — expanded JSDoc with multi-line text example showing
66
+ how to position text baselines relative to `context.y`.
67
+ - **Benchmark corpora manifest** and **smoke staging** tests wired into `npm test`
68
+ (previously orphaned).
69
+ - **`test/table-determinism.test.ts`** — asserts that table pagination produces identical
70
+ layout traces across repeated invocations of `prepareLayoutState`.
71
+ - **`test/validate-strict.test.ts`** (35 tests) — comprehensive contract for `strict: true`
72
+ validation covering all element types, nested structures, Levenshtein suggestions, error
73
+ message format, doc-level and sub-structure prop checks. Total test count: 676.
74
+ - `examples/plugin-custom-element.ts` — runnable plugin example (`npm run example:plugin`).
75
+
76
+ ### Fixed
77
+
78
+ - **`SIGNATURE_CERT_AND_ENCRYPTION` error code** — was declared in the `ErrorCode` union
79
+ but never thrown; validate.ts now uses it correctly when a document specifies both
80
+ signatures and encryption (previously threw a generic `VALIDATION_ERROR`).
81
+ - **Build break under `exactOptionalPropertyTypes: true`** — `PdfBuilder.build()` no longer
82
+ passes `{ plugins: undefined }` to `runPipeline` when no plugins are configured.
83
+ - **Plugin `validate` hook empty-string normalization** — `plugin.validate()` returning `''`
84
+ now correctly accepts the element (was previously treated as a rejection message).
85
+ - **`toc` element reaching render default arm** — `render.ts` now has an explicit
86
+ `case 'toc': return` guard before the default arm; TOC elements are pre-processed
87
+ during pagination and should never reach the renderer.
88
+ - **`RichLine` and `RichFragment`** demoted from `@public` to `@internal`; these are
89
+ implementation details of the rich-text pipeline, not intended for external use.
90
+ - **Sentinel value documentation** — `MeasuredBlock` comment now explicitly states that
91
+ `lines: []`, `fontSize: 0`, `lineHeight: 0`, `fontKey: ''` applies to spacers, tables,
92
+ images, hr, *and plugin blocks* — not a bug but a documented convention.
93
+
94
+ ### Internal
95
+
96
+ - `src/plugin-registry.ts` (new): Pure orchestration helpers for the four plugin injection
97
+ points (`findPlugin`, `runPluginValidate`, `runPluginLoadAsset`, `runPluginMeasure`,
98
+ `runPluginRender`).
99
+ - `src/plugin-types.ts` (new): `PluginDefinition` interface and context/result types.
100
+ - `src/layout-state.ts`: `prepareLayoutState` now accepts `options?: RenderOptions` and
101
+ threads plugins to `stageValidate`, `stageLoadAssets`, and `stageMeasure`.
102
+ - `docs/V1.0-RUNBOOK.md`: Full release runbook with first-principles audit, anti-hallucination
103
+ protocol, verified-facts table, and phase-by-phase plan.
104
+
105
+ ---
106
+
107
+ ## [0.9.4] — 2026-05-02
108
+
109
+ > **Note:** This release was never published to npm as a standalone tag. All changes listed
110
+ > here shipped as part of [1.0.0] on the same date.
111
+
112
+ Architecture hardening + API surface snapshot. No public API changes; internal
113
+ restructuring to eliminate circular dependencies and add drift guards before v1.0 freeze.
114
+
115
+ ### Added
116
+
117
+ - **API surface snapshot** (`etc/pretext-pdf.api.md`) checked into source control as
118
+ the v1.0 baseline. The `api:check` CI step will fail on unintentional public-API drift.
119
+ - **`src/layout-state.ts`** — `prepareLayoutState()` and `summarizeLayoutState()` extracted
120
+ from the pipeline for testability; `layout-contract` and `hard-text-contract` tests
121
+ wired into `test:unit`.
122
+ - **`src/benchmarks/corpora.ts`** — benchmark corpus manifest (`getBenchmarkCorpora()`)
123
+ restored from git history; `benchmark-baseline.test.ts` wired into `test:contract`.
124
+ - **Drift guards** (`test/drift-guards.test.ts`) — asserts that `ELEMENT_TYPES`,
125
+ `ALLOWED_PROPS`, `validate.ts` cases, and `render.ts` cases all agree at test time.
126
+ Catches any future element-type addition that isn't plumbed through all four places.
127
+ - **`render.ts` default arm** — unknown element types now throw immediately instead of
128
+ silently producing a blank block.
129
+
130
+ ### Refactored
131
+
132
+ - **Circular dependency broken**: `src/post-process.ts` extracted so `builder.ts` and
133
+ `index.ts` no longer form a cycle through each other.
134
+ - **`ELEMENT_TYPES` extracted** to `src/element-types.ts` as single source of truth;
135
+ re-exported from `index.ts`, imported by `validate.ts` — eliminates the previous
136
+ per-file string-literal duplication.
137
+
138
+ ### Fixed
139
+
140
+ - `post-process.ts`: drop raw signing library error message from `SIGNATURE_FAILED`
141
+ to avoid leaking certificate or passphrase details in error output.
142
+ - `layout-state.ts`: polyfill install wrapped in try/catch; throws `CANVAS_UNAVAILABLE`
143
+ on failure instead of an untyped exception.
144
+
145
+ ---
146
+
10
147
  ## [0.9.3] — 2026-04-23
11
148
 
12
149
  Strict validation release. Opt-in property validation to catch unknown properties on elements and sub-structures via typo detection and precise JSONPath error reporting.
@@ -192,7 +329,10 @@ Three additive enhancements that broaden the package's surface without growing i
192
329
 
193
330
  ---
194
331
 
195
- ## [Unreleased]
332
+ ## [0.7.2] — 2026-04-20
333
+
334
+ Phase 11 cross-cutting enhancements. This section was left as `[Unreleased]` in earlier
335
+ entries and is being attributed retroactively to 0.7.2 for historical accuracy.
196
336
 
197
337
  ### Added (Phase 11 — Cross-cutting Enhancements)
198
338