@lupinum/nuxt-pdf 0.3.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/API_REPORT.md +262 -0
- package/CHANGELOG.md +168 -0
- package/CONFORMANCE.md +496 -0
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/THIRD_PARTY_NOTICES.md +75 -0
- package/dist/module.d.mts +24 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +368 -0
- package/dist/runtime/authoring.d.ts +141 -0
- package/dist/runtime/authoring.js +25 -0
- package/dist/runtime/components/_props.d.ts +196 -0
- package/dist/runtime/components/_props.js +63 -0
- package/dist/runtime/components/document.d.ts +9 -0
- package/dist/runtime/components/document.js +26 -0
- package/dist/runtime/components/index.d.ts +4 -0
- package/dist/runtime/components/index.js +27 -0
- package/dist/runtime/components/svg.d.ts +17 -0
- package/dist/runtime/components/svg.js +50 -0
- package/dist/runtime/composables/index.d.ts +2 -0
- package/dist/runtime/composables/index.js +3 -0
- package/dist/runtime/composables/use-pdf-page-numbers.d.ts +39 -0
- package/dist/runtime/composables/use-pdf-page-numbers.js +17 -0
- package/dist/runtime/define-pdf.d.ts +6 -0
- package/dist/runtime/define-pdf.js +5 -0
- package/dist/runtime/fonts.d.ts +16 -0
- package/dist/runtime/fonts.js +0 -0
- package/dist/runtime/renderer/index.d.ts +3 -0
- package/dist/runtime/renderer/index.js +1 -0
- package/dist/runtime/renderer/node-ops.d.ts +5 -0
- package/dist/runtime/renderer/node-ops.js +281 -0
- package/dist/runtime/renderer/patch-prop.d.ts +3 -0
- package/dist/runtime/renderer/patch-prop.js +223 -0
- package/dist/runtime/renderer/render-component.d.ts +14 -0
- package/dist/runtime/renderer/render-component.js +201 -0
- package/dist/runtime/renderer/types.d.ts +33 -0
- package/dist/runtime/renderer/types.js +56 -0
- package/dist/runtime/renderer/validate-tree.d.ts +3 -0
- package/dist/runtime/renderer/validate-tree.js +428 -0
- package/dist/runtime/server/assets/errors.d.ts +12 -0
- package/dist/runtime/server/assets/errors.js +15 -0
- package/dist/runtime/server/assets/remote.d.ts +48 -0
- package/dist/runtime/server/assets/remote.js +234 -0
- package/dist/runtime/server/assets/resolve-asset.d.ts +53 -0
- package/dist/runtime/server/assets/resolve-asset.js +482 -0
- package/dist/runtime/server/engine/CONTRACTS.md +386 -0
- package/dist/runtime/server/engine/fonts.d.ts +8 -0
- package/dist/runtime/server/engine/fonts.js +19 -0
- package/dist/runtime/server/engine/layout-passes.d.ts +42 -0
- package/dist/runtime/server/engine/layout-passes.js +58 -0
- package/dist/runtime/server/engine/react-pdf-pdfkit.d.ts +7 -0
- package/dist/runtime/server/engine/render-document.d.ts +31 -0
- package/dist/runtime/server/engine/render-document.js +236 -0
- package/dist/runtime/server/index.d.ts +5 -0
- package/dist/runtime/server/index.js +9 -0
- package/dist/runtime/server/preview.d.ts +17 -0
- package/dist/runtime/server/preview.js +332 -0
- package/dist/runtime/server/registry.d.ts +41 -0
- package/dist/runtime/server/registry.js +270 -0
- package/dist/runtime/server/render-limits.d.ts +51 -0
- package/dist/runtime/server/render-limits.js +143 -0
- package/dist/runtime/server/result.d.ts +6 -0
- package/dist/runtime/server/result.js +81 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/shared/errors.d.ts +22 -0
- package/dist/runtime/shared/errors.js +22 -0
- package/dist/runtime/shared/index.d.ts +4 -0
- package/dist/runtime/shared/index.js +7 -0
- package/dist/runtime/shared/template.d.ts +63 -0
- package/dist/runtime/shared/template.js +1 -0
- package/dist/shared/nuxt-pdf.D2ZziYn4.mjs +1132 -0
- package/dist/test.d.mts +198 -0
- package/dist/test.mjs +696 -0
- package/dist/types.d.mts +13 -0
- package/package.json +135 -0
package/API_REPORT.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# Public API declaration report
|
|
2
|
+
|
|
3
|
+
This file is derived from the built declarations and is intentionally checked
|
|
4
|
+
in. Rebuild with `pnpm build && pnpm api:write`; CI verifies it with
|
|
5
|
+
`pnpm test:api`. Package code and generated `#pdf` registries remain the
|
|
6
|
+
canonical sources.
|
|
7
|
+
|
|
8
|
+
## Package root
|
|
9
|
+
|
|
10
|
+
Source: `dist/types.d.mts`
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
export { type RemoteAssetOptions } from '../dist/runtime/server/assets/remote.js'
|
|
14
|
+
|
|
15
|
+
export { type PdfLimitsOptions } from '../dist/runtime/server/render-limits.js'
|
|
16
|
+
|
|
17
|
+
export { type PdfFontDeclaration, type PdfFontStyle, type PdfFontWeight, type PdfFontWeightName } from '../dist/runtime/fonts.js'
|
|
18
|
+
|
|
19
|
+
export { type PdfLength, type PdfLengthOrPercentage, type PdfPercentage, type PdfStyle, type PdfStyleEntry, type PdfStyleValue } from '../dist/runtime/authoring.js'
|
|
20
|
+
|
|
21
|
+
export { type PdfBaseProps, type PdfBookmark, type PdfCircleProps, type PdfClipPathProps, type PdfDefsProps, type PdfDocumentProps, type PdfEllipseProps, type PdfGProps, type PdfImageProps, type PdfImageSource, type PdfLineProps, type PdfLinearGradientProps, type PdfLinkProps, type PdfNoteProps, type PdfPageDimension, type PdfPageProps, type PdfPageSize, type PdfPageSizeName, type PdfPageUnit, type PdfPathProps, type PdfPolygonProps, type PdfPolylineProps, type PdfRadialGradientProps, type PdfRectProps, type PdfStopProps, type PdfSvgLength, type PdfSvgNumber, type PdfSvgPresentationProps, type PdfSvgProps, type PdfSvgTransform, type PdfSvgTransformOperation, type PdfTextProps, type PdfTspanProps, type PdfViewProps } from '../dist/runtime/components/index.js'
|
|
22
|
+
|
|
23
|
+
export { default } from './module.mjs'
|
|
24
|
+
|
|
25
|
+
export { type ModuleOptions } from './module.mjs'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Nuxt module
|
|
29
|
+
|
|
30
|
+
Source: `dist/module.d.mts`
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
34
|
+
import { RemoteAssetOptions } from '../dist/runtime/server/assets/remote.js';
|
|
35
|
+
export { RemoteAssetOptions } from '../dist/runtime/server/assets/remote.js';
|
|
36
|
+
import { PdfLimitsOptions } from '../dist/runtime/server/render-limits.js';
|
|
37
|
+
export { PdfLimitsOptions } from '../dist/runtime/server/render-limits.js';
|
|
38
|
+
import { PdfFontDeclaration } from '../dist/runtime/fonts.js';
|
|
39
|
+
export { PdfFontDeclaration, PdfFontStyle, PdfFontWeight, PdfFontWeightName } from '../dist/runtime/fonts.js';
|
|
40
|
+
export { PdfLength, PdfLengthOrPercentage, PdfPercentage, PdfStyle, PdfStyleEntry, PdfStyleValue } from '../dist/runtime/authoring.js';
|
|
41
|
+
export { PdfBaseProps, PdfBookmark, PdfCircleProps, PdfClipPathProps, PdfDefsProps, PdfDocumentProps, PdfEllipseProps, PdfGProps, PdfImageProps, PdfImageSource, PdfLineProps, PdfLinearGradientProps, PdfLinkProps, PdfNoteProps, PdfPageDimension, PdfPageProps, PdfPageSize, PdfPageSizeName, PdfPageUnit, PdfPathProps, PdfPolygonProps, PdfPolylineProps, PdfRadialGradientProps, PdfRectProps, PdfStopProps, PdfSvgLength, PdfSvgNumber, PdfSvgPresentationProps, PdfSvgProps, PdfSvgTransform, PdfSvgTransformOperation, PdfTextProps, PdfTspanProps, PdfViewProps } from '../dist/runtime/components/index.js';
|
|
42
|
+
|
|
43
|
+
interface ModuleOptions {
|
|
44
|
+
fonts?: readonly PdfFontDeclaration[];
|
|
45
|
+
remote?: RemoteAssetOptions;
|
|
46
|
+
/**
|
|
47
|
+
* Canonical render, tree, image, remote-request, and output budgets. Every
|
|
48
|
+
* field is an optional positive safe integer; omitted fields use the
|
|
49
|
+
* documented built-in defaults.
|
|
50
|
+
*/
|
|
51
|
+
limits?: PdfLimitsOptions;
|
|
52
|
+
}
|
|
53
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
54
|
+
|
|
55
|
+
export { _default as default };
|
|
56
|
+
export type { ModuleOptions };
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Test entry
|
|
60
|
+
|
|
61
|
+
Source: `dist/test.d.mts`
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { PdfRenderResult, PdfComponentProps } from '../dist/runtime/shared/template.js';
|
|
65
|
+
export { PdfComponentProps } from '../dist/runtime/shared/template.js';
|
|
66
|
+
import { Component } from 'vue';
|
|
67
|
+
import { ModuleOptions } from './module.mjs';
|
|
68
|
+
import '@nuxt/schema';
|
|
69
|
+
import '../dist/runtime/server/assets/remote.js';
|
|
70
|
+
import '../dist/runtime/server/render-limits.js';
|
|
71
|
+
import '../dist/runtime/fonts.js';
|
|
72
|
+
import '../dist/runtime/authoring.js';
|
|
73
|
+
import '../dist/runtime/components/index.js';
|
|
74
|
+
|
|
75
|
+
/** Raw PDF (or PNG) bytes accepted by the low-level readers. */
|
|
76
|
+
type PdfData = ArrayBuffer | Uint8Array;
|
|
77
|
+
/** Anything the public `parsePdf`/`rasterizePdf` accept: bytes or a render result. */
|
|
78
|
+
type PdfInput = PdfData | PdfRenderResult;
|
|
79
|
+
interface PdfAnnotationReference {
|
|
80
|
+
generation: number;
|
|
81
|
+
number: number;
|
|
82
|
+
}
|
|
83
|
+
type PdfAnnotationDestination = string | Array<string | number | null | PdfAnnotationReference>;
|
|
84
|
+
interface PdfAnnotation {
|
|
85
|
+
annotationType?: number;
|
|
86
|
+
destination?: PdfAnnotationDestination;
|
|
87
|
+
rect?: number[];
|
|
88
|
+
subtype: string;
|
|
89
|
+
unsafeUrl?: string;
|
|
90
|
+
url?: string;
|
|
91
|
+
}
|
|
92
|
+
/** A link annotation flattened to the fields users assert against. */
|
|
93
|
+
interface ParsedPdfLink {
|
|
94
|
+
/** 1-based page the link sits on. */
|
|
95
|
+
page: number;
|
|
96
|
+
/** Named internal destination (e.g. a `#id` target), when the link is internal. */
|
|
97
|
+
destination?: string;
|
|
98
|
+
/** External URL, when the link points outside the document. */
|
|
99
|
+
url?: string;
|
|
100
|
+
}
|
|
101
|
+
/** A normalized PDF.js text run for tolerant layout and typography assertions. */
|
|
102
|
+
interface ParsedPdfTextRun {
|
|
103
|
+
direction: string;
|
|
104
|
+
fontName: string;
|
|
105
|
+
fontSize: number;
|
|
106
|
+
height: number;
|
|
107
|
+
text: string;
|
|
108
|
+
width: number;
|
|
109
|
+
x: number;
|
|
110
|
+
y: number;
|
|
111
|
+
}
|
|
112
|
+
interface ParsedPdfPage {
|
|
113
|
+
annotations: PdfAnnotation[];
|
|
114
|
+
height: number;
|
|
115
|
+
number: number;
|
|
116
|
+
rawText: string;
|
|
117
|
+
text: string;
|
|
118
|
+
textItems: string[];
|
|
119
|
+
textRuns: ParsedPdfTextRun[];
|
|
120
|
+
width: number;
|
|
121
|
+
}
|
|
122
|
+
interface PdfOutlineItem {
|
|
123
|
+
title: string;
|
|
124
|
+
/** Initial viewer state for entries with children. Absent on leaf entries. */
|
|
125
|
+
expanded?: boolean;
|
|
126
|
+
children: PdfOutlineItem[];
|
|
127
|
+
}
|
|
128
|
+
interface ParsedPdf {
|
|
129
|
+
pageCount: number;
|
|
130
|
+
pages: ParsedPdfPage[];
|
|
131
|
+
/** Every link annotation in the document, flattened across pages. */
|
|
132
|
+
links: ParsedPdfLink[];
|
|
133
|
+
/** The bookmark tree (outline), including initial expansion state. */
|
|
134
|
+
outline: PdfOutlineItem[];
|
|
135
|
+
}
|
|
136
|
+
interface RasterizePdfOptions {
|
|
137
|
+
background?: string;
|
|
138
|
+
scale?: number;
|
|
139
|
+
}
|
|
140
|
+
interface PdfPageImage {
|
|
141
|
+
height: number;
|
|
142
|
+
number: number;
|
|
143
|
+
pixels: Uint8ClampedArray;
|
|
144
|
+
png: Uint8Array;
|
|
145
|
+
width: number;
|
|
146
|
+
}
|
|
147
|
+
interface PageImageComparison {
|
|
148
|
+
changedPixelRatio: number;
|
|
149
|
+
changedPixels: number;
|
|
150
|
+
dimensionsMatch: boolean;
|
|
151
|
+
matches: boolean;
|
|
152
|
+
maxChannelDifference: number;
|
|
153
|
+
pageNumbersMatch: boolean;
|
|
154
|
+
totalPixels: number;
|
|
155
|
+
}
|
|
156
|
+
/** Resolve any accepted input (bytes or a `PdfRenderResult`) to raw PDF bytes. */
|
|
157
|
+
declare function toPdfBytes(input: PdfInput): Promise<Uint8Array>;
|
|
158
|
+
/** Parse stable, semantic information from every page of a PDF. */
|
|
159
|
+
declare function parsePdf(input: PdfInput): Promise<ParsedPdf>;
|
|
160
|
+
/** Rasterize every PDF page independently for deterministic page-level diffs. */
|
|
161
|
+
declare function rasterizePdf(input: PdfInput, options?: RasterizePdfOptions): Promise<PdfPageImage[]>;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Error thrown by the `expectPdf` helpers. Named so test runners surface it like
|
|
165
|
+
* their own assertion errors, without this module depending on any runner.
|
|
166
|
+
*/
|
|
167
|
+
declare class PdfAssertionError extends Error {
|
|
168
|
+
constructor(message: string);
|
|
169
|
+
}
|
|
170
|
+
interface ToContainTextOptions {
|
|
171
|
+
/** Restrict the search to a single 1-based page. */
|
|
172
|
+
page?: number;
|
|
173
|
+
}
|
|
174
|
+
type LinkQuery = {
|
|
175
|
+
destination: string;
|
|
176
|
+
page?: number;
|
|
177
|
+
} | {
|
|
178
|
+
url: string;
|
|
179
|
+
page?: number;
|
|
180
|
+
} | {
|
|
181
|
+
destination: string;
|
|
182
|
+
url: string;
|
|
183
|
+
page?: number;
|
|
184
|
+
};
|
|
185
|
+
/** A partial outline shape: title is required; state and children are optional. */
|
|
186
|
+
interface OutlineShape {
|
|
187
|
+
title: string;
|
|
188
|
+
expanded?: boolean;
|
|
189
|
+
children?: OutlineShape[];
|
|
190
|
+
}
|
|
191
|
+
interface PdfExpectation {
|
|
192
|
+
toHavePageCount(count: number): PdfExpectation;
|
|
193
|
+
toContainText(text: string, options?: ToContainTextOptions): PdfExpectation;
|
|
194
|
+
toHaveLink(query: LinkQuery): PdfExpectation;
|
|
195
|
+
toHaveOutline(shape: OutlineShape[]): PdfExpectation;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Fluent, runner-agnostic assertions over a `ParsedPdf`. Every method returns the
|
|
199
|
+
* same expectation so calls chain, and throws a `PdfAssertionError` on failure
|
|
200
|
+
* with a message naming what was expected and what the document actually holds.
|
|
201
|
+
*/
|
|
202
|
+
declare function expectPdf(parsed: ParsedPdf): PdfExpectation;
|
|
203
|
+
|
|
204
|
+
/** User-shaped render policy, matching the corresponding Nuxt module options. */
|
|
205
|
+
type RenderPdfTemplateOptions = Pick<ModuleOptions, 'limits' | 'remote'>;
|
|
206
|
+
interface RenderedPdfTemplate {
|
|
207
|
+
/** The rendered PDF bytes. */
|
|
208
|
+
bytes: Uint8Array;
|
|
209
|
+
/** The parsed document, ready for `expectPdf`. */
|
|
210
|
+
parsed: ParsedPdf;
|
|
211
|
+
/** The underlying completed result (diagnostics, bytes, buffer, and response). */
|
|
212
|
+
result: PdfRenderResult;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Render a Vue PDF component through the real Nuxt PDF pipeline — mount, asset
|
|
216
|
+
* resolution, font registration, single- or multi-pass layout — without booting
|
|
217
|
+
* Nuxt, then parse the bytes so a test can assert against them immediately.
|
|
218
|
+
*/
|
|
219
|
+
declare function renderPdfTemplate<C extends Component>(component: C, props: PdfComponentProps<C>, options?: RenderPdfTemplateOptions): Promise<RenderedPdfTemplate>;
|
|
220
|
+
|
|
221
|
+
/** User-shaped SFC render configuration, matching the Nuxt module options. */
|
|
222
|
+
type RenderPdfSfcOptions = RenderPdfTemplateOptions & Pick<ModuleOptions, 'fonts'>;
|
|
223
|
+
/** Compile a real PDF SFC graph with the same compiler used by the Nuxt module. */
|
|
224
|
+
declare function loadPdfSfc(filename: string): Promise<Component>;
|
|
225
|
+
/** Compile and render a real `pdfs/*.vue` template with production resource handling. */
|
|
226
|
+
declare function renderPdfSfc<Props extends object>(filename: string, props: Props, options?: RenderPdfSfcOptions): Promise<RenderedPdfTemplate>;
|
|
227
|
+
|
|
228
|
+
interface ComparePdfSnapshotOptions {
|
|
229
|
+
/** Directory for expected, actual, diff, and JSON failure artifacts. */
|
|
230
|
+
artifactDir?: string;
|
|
231
|
+
/** Maximum ratio of changed pixels allowed per page (default 0.005). */
|
|
232
|
+
threshold?: number;
|
|
233
|
+
/** Maximum per-channel RGBA difference for a matching pixel (default 25). */
|
|
234
|
+
channelThreshold?: number;
|
|
235
|
+
/** Raster scale (default 1). */
|
|
236
|
+
scale?: number;
|
|
237
|
+
/**
|
|
238
|
+
* Write the current render as the reviewed baseline instead of comparing.
|
|
239
|
+
* Defaults to `process.env.UPDATE_PDF_BASELINES === '1'`.
|
|
240
|
+
*/
|
|
241
|
+
update?: boolean;
|
|
242
|
+
}
|
|
243
|
+
interface PdfSnapshotResult {
|
|
244
|
+
/** Whether the render matched the reviewed baseline. */
|
|
245
|
+
matches: boolean;
|
|
246
|
+
/** Whether the baseline was (re)written this run. */
|
|
247
|
+
updated: boolean;
|
|
248
|
+
/** Per-page comparison detail (empty when the baseline was written). */
|
|
249
|
+
pages: PageImageComparison[];
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Compare a rendered PDF against a directory of reviewed per-page PNG baselines,
|
|
253
|
+
* following the `UPDATE_PDF_BASELINES` review policy. With `update` (or the env
|
|
254
|
+
* flag) set, it (re)writes the baselines and returns; otherwise it rasterizes the
|
|
255
|
+
* document, checks every page against `baselineDir/page-N.png`, and throws a
|
|
256
|
+
* `PdfAssertionError` on any mismatch.
|
|
257
|
+
*/
|
|
258
|
+
declare function comparePdfSnapshot(input: PdfInput, baselineDir: string, options?: ComparePdfSnapshotOptions): Promise<PdfSnapshotResult>;
|
|
259
|
+
|
|
260
|
+
export { PdfAssertionError, comparePdfSnapshot, expectPdf, loadPdfSfc, parsePdf, rasterizePdf, renderPdfSfc, renderPdfTemplate, toPdfBytes };
|
|
261
|
+
export type { ComparePdfSnapshotOptions, LinkQuery, OutlineShape, ParsedPdf, ParsedPdfLink, ParsedPdfPage, ParsedPdfTextRun, PdfExpectation, PdfInput, PdfOutlineItem, PdfPageImage, PdfSnapshotResult, RasterizePdfOptions, RenderPdfSfcOptions, RenderPdfTemplateOptions, RenderedPdfTemplate, ToContainTextOptions };
|
|
262
|
+
```
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@lupinum/nuxt-pdf` are recorded here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres
|
|
5
|
+
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## Unreleased
|
|
8
|
+
|
|
9
|
+
## 0.3.0 - 2026-08-11
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Public font configuration types (`PdfFontDeclaration`, `PdfFontStyle`,
|
|
14
|
+
`PdfFontWeight`, and `PdfFontWeightName`) are now exported from the package
|
|
15
|
+
root instead of leaking through a private server implementation path.
|
|
16
|
+
- `PdfLimitsOptions` is now a named package-root export backed by the same
|
|
17
|
+
canonical option shape used by the Nuxt module.
|
|
18
|
+
- `RemoteAssetOptions` is now a named package-root export for callers that
|
|
19
|
+
share remote-image policy between Nuxt configuration and test helpers.
|
|
20
|
+
- One canonical `pdf.limits` budget covering tree nodes/depth/text, pages,
|
|
21
|
+
image count/source bytes/decoded pixels, remote request count/concurrency,
|
|
22
|
+
the whole-render deadline, and completed output bytes.
|
|
23
|
+
- Structural PNG/JPEG dimension validation before engine admission, aggregate
|
|
24
|
+
per-render image accounting, atomic output-cap failure, and fatal sibling
|
|
25
|
+
request cancellation.
|
|
26
|
+
- Structural SFNT table-directory validation for local TTF/OTF files plus mixed
|
|
27
|
+
20-render concurrency, 100 sequential-render, and 100-page isolation suites.
|
|
28
|
+
- Immutable resolved render metadata, development-only preview sidecars, stale
|
|
29
|
+
preview state after render failures, and automatic SFC preview refresh.
|
|
30
|
+
- Normalized PDF text-run geometry and complete raster failure artifacts with
|
|
31
|
+
expected, actual, diff, and JSON metrics for every changed page.
|
|
32
|
+
- One-tarball npm/pnpm consumer verification, pinned CI/release workflows,
|
|
33
|
+
CycloneDX SBOM and checksum generation, and registry post-publish smoke tests.
|
|
34
|
+
- Safe registered-font-face diagnostics and an international typography
|
|
35
|
+
calibration fixture that classifies CJK, bidi text, combining marks, variable
|
|
36
|
+
fonts, emoji, fallback, and hyphenation from semantic and raster evidence.
|
|
37
|
+
- Scope-aware Vue Composition API and `usePdfPageNumbers` auto-imports inside
|
|
38
|
+
PDF SFCs, without pretending that the isolated renderer has Nuxt app context.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Failed Vue mounts are transactional, component effects are always disposed,
|
|
43
|
+
and unhandled production errors fail the render instead of returning an
|
|
44
|
+
incomplete PDF.
|
|
45
|
+
- PDF SFC compilation rejects async setup, top-level `await`, `Teleport`, and
|
|
46
|
+
`v-show` with targeted diagnostics; unsupported PDF styles fail closed.
|
|
47
|
+
- Generated registry and test-helper types expose authored component props
|
|
48
|
+
instead of Vue framework props, and misplaced `definePdf()` calls fail with a
|
|
49
|
+
focused runtime explanation.
|
|
50
|
+
- Script-setup source maps now compose the Vue compiler, auto-import, and
|
|
51
|
+
TypeScript transforms back to the original `.vue` source.
|
|
52
|
+
- Nuxt discovery honors `.nuxtignore` and configured ignore rules. Structural
|
|
53
|
+
PDF/component changes and embedded image/font changes restart Nuxt so the
|
|
54
|
+
registry, declarations, and bundled resources cannot become stale.
|
|
55
|
+
- Preview HMR derives its Vite client path from `app.baseURL` and
|
|
56
|
+
`app.buildAssetsDir`; project and layer resource precedence is covered by
|
|
57
|
+
integration tests.
|
|
58
|
+
- Documentation now states the Node runtime-core lifecycle, synchronous
|
|
59
|
+
authoring contract, isolated Vue app boundary, and PDF-specific styling model.
|
|
60
|
+
|
|
61
|
+
### Breaking changes
|
|
62
|
+
|
|
63
|
+
- `renderPdfTemplate` options now mirror user-facing `pdf.remote` and
|
|
64
|
+
`pdf.limits` configuration. Generated asset maps, embedded font descriptors,
|
|
65
|
+
and template attribution fields are internal. `renderPdfSfc` additionally
|
|
66
|
+
accepts `pdf.fonts` declarations and always infers the application root from
|
|
67
|
+
the `pdfs/*.vue` path; its `rootDir` override is removed.
|
|
68
|
+
- Root render props are now limited to props authored by the Vue component;
|
|
69
|
+
renderer-owned `class`, `style`, VNode, and reserved props are no longer
|
|
70
|
+
accepted by the generated registry or `renderPdfTemplate`.
|
|
71
|
+
- Previously unsupported async components, top-level `await`, `Teleport`,
|
|
72
|
+
`v-show`, and unrecognized style properties now fail explicitly instead of
|
|
73
|
+
being silently omitted or admitted as no-ops.
|
|
74
|
+
- Template keys now use one slash-separated vocabulary everywhere. A nested
|
|
75
|
+
template such as `pdfs/reports/monthly.vue` is registered as
|
|
76
|
+
`pdf['reports/monthly']`; camel-cased aliases such as `pdf.reportsMonthly`
|
|
77
|
+
are removed.
|
|
78
|
+
- The inert `diagnostics.warnings` field and preview warning plumbing are
|
|
79
|
+
removed. Render failures remain typed errors; diagnostics report only
|
|
80
|
+
measured facts about a completed render.
|
|
81
|
+
- `pdf.remote` now permits images only and contains only `allow` plus
|
|
82
|
+
`timeoutMs`. Move former `maxImageBytes` configuration to
|
|
83
|
+
`pdf.limits.maxImageBytes`; remote fonts must become local `pdfs/fonts`
|
|
84
|
+
inputs.
|
|
85
|
+
- Allowlist entries must be exact `https://host/path/` prefixes. Wildcard hosts
|
|
86
|
+
and prefixes without a trailing slash are rejected. Redirects are capped at
|
|
87
|
+
three hops.
|
|
88
|
+
|
|
89
|
+
## 0.2.0
|
|
90
|
+
|
|
91
|
+
The contract widens from 0.1.0's core layout primitives to vector graphics, a
|
|
92
|
+
table of contents, internal links, bookmarks, opt-in remote resources, shipped
|
|
93
|
+
testing utilities, and enforced render limits — each backed by an executable
|
|
94
|
+
conformance fixture. Everything is additive: no 0.1.0 public API changed.
|
|
95
|
+
|
|
96
|
+
### Added
|
|
97
|
+
|
|
98
|
+
- **SVG drawing primitives.** `PdfSvg`, `PdfG`, `PdfPath`, `PdfRect`,
|
|
99
|
+
`PdfCircle`, `PdfEllipse`, `PdfLine`, `PdfPolyline`, `PdfPolygon`, `PdfDefs`,
|
|
100
|
+
`PdfClipPath`, `PdfLinearGradient`, `PdfRadialGradient`, `PdfStop`, and
|
|
101
|
+
`PdfTspan`, with enforced nesting rules and `url(#id)` def references. Verified
|
|
102
|
+
by a paired React/Vue raster fixture.
|
|
103
|
+
- **Table of contents via `usePdfPageNumbers()`.** An auto-imported composable
|
|
104
|
+
returning a readonly, reactive `id → 1-based page` map. Reading it activates a
|
|
105
|
+
fixed-point multi-pass layout that converges (an ordinary TOC settles in two
|
|
106
|
+
passes); a document whose geometry depends on the numbers it prints fails
|
|
107
|
+
closed with `PDF_LIMIT_EXCEEDED`.
|
|
108
|
+
- **Internal `#id` links and bookmarks.** Any primitive `id` becomes a named
|
|
109
|
+
destination reachable with `<PdfLink src="#id">`; a `bookmark` prop builds a
|
|
110
|
+
nested PDF outline following the component tree. Internal links stay
|
|
111
|
+
single-pass (they resolve by name).
|
|
112
|
+
- **Opt-in remote images and fonts.** Off by default. `pdf.remote.allow`
|
|
113
|
+
configures an explicit `https`-only host + path-prefix allowlist enforced by
|
|
114
|
+
the module (never the engine) with per-hop redirect re-checks, byte caps,
|
|
115
|
+
signature validation, and timeouts; admitted bytes take the same embedded path
|
|
116
|
+
as local assets.
|
|
117
|
+
- **`@lupinum/nuxt-pdf/test` utilities.** The helpers this package is tested with
|
|
118
|
+
now ship: `renderPdfTemplate`, `parsePdf`, `expectPdf`, `rasterizePdf`, and
|
|
119
|
+
`comparePdfSnapshot` (reviewed-baseline policy). `pdfjs-dist` and
|
|
120
|
+
`@napi-rs/canvas` are new **optional** peer dependencies, loaded lazily only by
|
|
121
|
+
this entry.
|
|
122
|
+
- **Render limits.** Every render is bounded by `pdf.limits.maxPages` (default
|
|
123
|
+
2000) and `pdf.limits.timeoutMs` (default 30000), validated at setup and
|
|
124
|
+
enforced on both the single- and multi-pass paths; breaches fail with
|
|
125
|
+
`PDF_LIMIT_EXCEEDED`. Defaults apply even with no `pdf.limits` configured.
|
|
126
|
+
- **`NuxtPdfError` and `PDF_ERROR_CODES`** exported from `#pdf`, and
|
|
127
|
+
template-attributed errors: every failure from a template's `render()` carries
|
|
128
|
+
`templateKey`/`templateFile` and a message prefixed with the source file.
|
|
129
|
+
- **Development preview workbench** at `/_pdf`: scenario tabs, a per-render
|
|
130
|
+
diagnostics strip (duration, size, page count, and layout passes), and a
|
|
131
|
+
readable error panel. Server-rendered, absent from production builds.
|
|
132
|
+
- **Documentation site** under `docs/` and a `playground/pdfs/report.vue`
|
|
133
|
+
demonstrating the TOC, bookmarks, and page numbers end to end.
|
|
134
|
+
- **Serverless build proof.** The module is verified to build under the Vercel
|
|
135
|
+
Nitro preset (execution remains verified on node-server).
|
|
136
|
+
|
|
137
|
+
### Improvements (deliberate divergences from React PDF)
|
|
138
|
+
|
|
139
|
+
- **Dynamic-text line spacing.** Page-number footers now render at correct
|
|
140
|
+
page-bottom geometry even when a `lineHeight` reaches the dynamic node
|
|
141
|
+
(inherited, percentage, or its own). Upstream React PDF produces invalid
|
|
142
|
+
geometry for that combination and silently drops such footers; Nuxt PDF
|
|
143
|
+
neutralizes the un-carryable `lineHeight` and renders them.
|
|
144
|
+
- **Named-destination anchoring.** Internal links and TOC page numbers resolve to
|
|
145
|
+
the **first** page a section starts on, even when the section spans pages.
|
|
146
|
+
React PDF's last-writer-wins destination table points at the last page; Nuxt
|
|
147
|
+
PDF anchors at the first, copy-on-write so a `fixed` node repeated across pages
|
|
148
|
+
keeps its first-page destination.
|
|
149
|
+
|
|
150
|
+
### Breaking changes
|
|
151
|
+
|
|
152
|
+
One type-level narrowing: the `bookmark` prop is no longer **typed** on
|
|
153
|
+
`PdfLink` and `PdfNote`. It was never tested or claimed there, and outline
|
|
154
|
+
entries are verified only on `PdfPage`/`PdfView`/`PdfText`/`PdfImage`, so the
|
|
155
|
+
types now match the tested contract. Runtime behavior is unchanged.
|
|
156
|
+
|
|
157
|
+
Everything else in the 0.1.0 public surface — module options, `#pdf` registry,
|
|
158
|
+
components, and `definePdf` — is unchanged; every 0.2.0 addition is opt-in.
|
|
159
|
+
`pdfjs-dist` and `@napi-rs/canvas` are added only as **optional** peer
|
|
160
|
+
dependencies for the new `/test` entry.
|
|
161
|
+
|
|
162
|
+
## 0.1.0
|
|
163
|
+
|
|
164
|
+
Initial external alpha: one Nuxt module, one Vue document tree, one Node server
|
|
165
|
+
renderer over exact-pinned React PDF engine packages, and a small set of tested
|
|
166
|
+
layout primitives (`PdfDocument`, `PdfPage`, `PdfView`, `PdfText`, `PdfImage`,
|
|
167
|
+
`PdfLink`, `PdfNote`) with local image and font embedding and a typed `#pdf`
|
|
168
|
+
server registry.
|