pretext-pdf 0.1.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 +242 -0
- package/LICENSE +21 -0
- package/README.md +402 -0
- package/dist/assets.d.ts +14 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +182 -0
- package/dist/assets.js.map +1 -0
- package/dist/builder.d.ts +53 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +129 -0
- package/dist/builder.js.map +1 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -0
- package/dist/fonts.d.ts +21 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.js +310 -0
- package/dist/fonts.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +1 -0
- package/dist/measure.d.ts +53 -0
- package/dist/measure.d.ts.map +1 -0
- package/dist/measure.js +1029 -0
- package/dist/measure.js.map +1 -0
- package/dist/node-polyfill.d.ts +7 -0
- package/dist/node-polyfill.d.ts.map +1 -0
- package/dist/node-polyfill.js +82 -0
- package/dist/node-polyfill.js.map +1 -0
- package/dist/page-sizes.d.ts +13 -0
- package/dist/page-sizes.d.ts.map +1 -0
- package/dist/page-sizes.js +24 -0
- package/dist/page-sizes.js.map +1 -0
- package/dist/paginate.d.ts +15 -0
- package/dist/paginate.d.ts.map +1 -0
- package/dist/paginate.js +395 -0
- package/dist/paginate.js.map +1 -0
- package/dist/render.d.ts +12 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +1028 -0
- package/dist/render.js.map +1 -0
- package/dist/rich-text.d.ts +14 -0
- package/dist/rich-text.d.ts.map +1 -0
- package/dist/rich-text.js +183 -0
- package/dist/rich-text.js.map +1 -0
- package/dist/types.d.ts +697 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +3 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +786 -0
- package/dist/validate.js.map +1 -0
- package/package.json +79 -0
package/dist/assets.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { PretextPdfError } from './errors.js';
|
|
2
|
+
// ─── SVG helpers ──────────────────────────────────────────────────────────────
|
|
3
|
+
function parseSvgViewBox(svg) {
|
|
4
|
+
const match = svg.match(/viewBox=["']([^"']+)["']/);
|
|
5
|
+
if (!match)
|
|
6
|
+
return null;
|
|
7
|
+
const parts = match[1].split(/[\s,]+/).map(Number);
|
|
8
|
+
const w = parts[2], h = parts[3];
|
|
9
|
+
if (!w || !h || !isFinite(w) || !isFinite(h) || w <= 0 || h <= 0)
|
|
10
|
+
return null;
|
|
11
|
+
return { width: w, height: h };
|
|
12
|
+
}
|
|
13
|
+
function parseSvgAttributes(svg) {
|
|
14
|
+
const wMatch = svg.match(/<svg[^>]*\swidth=["'](\d+(?:\.\d+)?)["']/);
|
|
15
|
+
const hMatch = svg.match(/<svg[^>]*\sheight=["'](\d+(?:\.\d+)?)["']/);
|
|
16
|
+
if (!wMatch || !hMatch)
|
|
17
|
+
return null;
|
|
18
|
+
const w = Number(wMatch[1]), h = Number(hMatch[1]);
|
|
19
|
+
if (!w || !h || w <= 0 || h <= 0)
|
|
20
|
+
return null;
|
|
21
|
+
return { width: w, height: h };
|
|
22
|
+
}
|
|
23
|
+
function resolveSvgDimensions(el, contentWidth) {
|
|
24
|
+
const viewbox = parseSvgViewBox(el.svg) ?? parseSvgAttributes(el.svg);
|
|
25
|
+
const aspectRatio = viewbox ? viewbox.height / viewbox.width : null;
|
|
26
|
+
if (el.width !== undefined && el.height !== undefined) {
|
|
27
|
+
return { widthPt: el.width, heightPt: el.height };
|
|
28
|
+
}
|
|
29
|
+
if (el.width !== undefined) {
|
|
30
|
+
return { widthPt: el.width, heightPt: aspectRatio !== null ? el.width * aspectRatio : el.width };
|
|
31
|
+
}
|
|
32
|
+
if (el.height !== undefined) {
|
|
33
|
+
return { widthPt: aspectRatio !== null ? el.height / aspectRatio : el.height, heightPt: el.height };
|
|
34
|
+
}
|
|
35
|
+
// No dimensions specified: use full contentWidth, clamped to available space
|
|
36
|
+
const widthPt = Math.min(contentWidth, contentWidth); // Already at contentWidth, but explicit for clarity
|
|
37
|
+
const heightPt = aspectRatio !== null ? widthPt * aspectRatio : 200;
|
|
38
|
+
return { widthPt, heightPt };
|
|
39
|
+
}
|
|
40
|
+
async function loadSvgAsImage(svg, widthPt, heightPt, pdfDoc) {
|
|
41
|
+
let canvasLib;
|
|
42
|
+
try {
|
|
43
|
+
canvasLib = await import('@napi-rs/canvas');
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
throw new PretextPdfError('SVG_RENDER_FAILED', 'SVG rendering requires the optional dependency @napi-rs/canvas. Install it with: pnpm add @napi-rs/canvas');
|
|
47
|
+
}
|
|
48
|
+
const scale = 2; // 2x for retina quality
|
|
49
|
+
const widthPx = Math.round(widthPt * scale);
|
|
50
|
+
const heightPx = Math.round(heightPt * scale);
|
|
51
|
+
try {
|
|
52
|
+
const canvas = canvasLib.createCanvas(widthPx, heightPx);
|
|
53
|
+
const ctx = canvas.getContext('2d');
|
|
54
|
+
const img = new canvasLib.Image();
|
|
55
|
+
img.src = Buffer.from(svg);
|
|
56
|
+
ctx.drawImage(img, 0, 0, widthPx, heightPx);
|
|
57
|
+
const pngBuffer = canvas.toBuffer('image/png');
|
|
58
|
+
return pdfDoc.embedPng(pngBuffer);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
throw new PretextPdfError('SVG_RENDER_FAILED', `Failed to rasterize SVG: ${err instanceof Error ? err.message : String(err)}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Stage 2b: Load and embed all images into pdfDoc.
|
|
66
|
+
* Runs after loadFonts(), receives the same pdfDoc.
|
|
67
|
+
*
|
|
68
|
+
* Image keys are 'img-N' where N is the element's position in doc.content.
|
|
69
|
+
* This makes keys stable and avoids collisions from duplicate src paths.
|
|
70
|
+
*
|
|
71
|
+
* IMPORTANT: pdf-lib image embedding is NOT thread-safe.
|
|
72
|
+
* We load bytes in parallel but embed sequentially.
|
|
73
|
+
*/
|
|
74
|
+
export async function loadImages(doc, pdfDoc, contentWidth) {
|
|
75
|
+
const imageMap = new Map();
|
|
76
|
+
// Collect all ImageElement entries with their content index for stable keys
|
|
77
|
+
const imageEntries = [];
|
|
78
|
+
for (let i = 0; i < doc.content.length; i++) {
|
|
79
|
+
const el = doc.content[i];
|
|
80
|
+
if (el.type === 'image') {
|
|
81
|
+
imageEntries.push({ el, key: `img-${i}` });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Load all image bytes in parallel
|
|
85
|
+
const loadResults = imageEntries.length > 0
|
|
86
|
+
? await Promise.all(imageEntries.map(async ({ el, key }) => {
|
|
87
|
+
const bytes = await loadImageBytes(el, key);
|
|
88
|
+
return { el, key, bytes };
|
|
89
|
+
}))
|
|
90
|
+
: [];
|
|
91
|
+
// Embed sequentially (pdf-lib limitation)
|
|
92
|
+
for (const { el, key, bytes } of loadResults) {
|
|
93
|
+
const resolvedFormat = resolveImageFormat(el, bytes, key);
|
|
94
|
+
try {
|
|
95
|
+
const pdfImage = resolvedFormat === 'png'
|
|
96
|
+
? await pdfDoc.embedPng(bytes)
|
|
97
|
+
: await pdfDoc.embedJpg(bytes);
|
|
98
|
+
imageMap.set(key, pdfImage);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
throw new PretextPdfError('IMAGE_FORMAT_MISMATCH', `Image key "${key}" (format: '${resolvedFormat}'): pdf-lib failed to embed — the bytes may not be a valid ${resolvedFormat.toUpperCase()} file. Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Load SVG elements — rasterize to PNG and embed
|
|
105
|
+
for (let i = 0; i < doc.content.length; i++) {
|
|
106
|
+
const el = doc.content[i];
|
|
107
|
+
if (el.type === 'svg') {
|
|
108
|
+
const key = `svg-${i}`;
|
|
109
|
+
const { widthPt, heightPt } = resolveSvgDimensions(el, contentWidth);
|
|
110
|
+
const pdfImage = await loadSvgAsImage(el.svg, widthPt, heightPt, pdfDoc);
|
|
111
|
+
imageMap.set(key, pdfImage);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Load watermark image if provided
|
|
115
|
+
if (doc.watermark?.image) {
|
|
116
|
+
const src = doc.watermark.image;
|
|
117
|
+
try {
|
|
118
|
+
const bytes = src instanceof Uint8Array
|
|
119
|
+
? src
|
|
120
|
+
: new Uint8Array((await import('fs')).readFileSync(src));
|
|
121
|
+
const isPng = bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4E && bytes[3] === 0x47;
|
|
122
|
+
const pdfImage = isPng
|
|
123
|
+
? await pdfDoc.embedPng(bytes)
|
|
124
|
+
: await pdfDoc.embedJpg(bytes);
|
|
125
|
+
imageMap.set('watermark', pdfImage);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Watermark image load failure is non-fatal — watermark simply won't be rendered
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return imageMap;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Resolve the image format from the element spec, magic bytes, or file extension.
|
|
135
|
+
* Priority: explicit 'png'/'jpg' → magic bytes → file extension → error.
|
|
136
|
+
*/
|
|
137
|
+
function resolveImageFormat(el, bytes, key) {
|
|
138
|
+
// Explicit format — trust the user
|
|
139
|
+
if (el.format === 'png')
|
|
140
|
+
return 'png';
|
|
141
|
+
if (el.format === 'jpg')
|
|
142
|
+
return 'jpg';
|
|
143
|
+
// Auto-detect from magic bytes (most reliable)
|
|
144
|
+
if (bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4E && bytes[3] === 0x47)
|
|
145
|
+
return 'png';
|
|
146
|
+
if (bytes[0] === 0xFF && bytes[1] === 0xD8 && bytes[2] === 0xFF)
|
|
147
|
+
return 'jpg';
|
|
148
|
+
// Fallback: file extension
|
|
149
|
+
if (typeof el.src === 'string') {
|
|
150
|
+
const ext = el.src.toLowerCase().split('.').pop();
|
|
151
|
+
if (ext === 'png')
|
|
152
|
+
return 'png';
|
|
153
|
+
if (ext === 'jpg' || ext === 'jpeg')
|
|
154
|
+
return 'jpg';
|
|
155
|
+
}
|
|
156
|
+
throw new PretextPdfError('IMAGE_FORMAT_MISMATCH', `Image "${key}": format could not be auto-detected. Bytes start with [0x${bytes[0]?.toString(16) ?? '?'}, 0x${bytes[1]?.toString(16) ?? '?'}]. Specify format: 'png' or 'jpg' explicitly.`);
|
|
157
|
+
}
|
|
158
|
+
/** Load image bytes from a file path or Uint8Array */
|
|
159
|
+
async function loadImageBytes(el, key) {
|
|
160
|
+
// Already have bytes — use directly
|
|
161
|
+
if (el.src instanceof Uint8Array) {
|
|
162
|
+
return el.src;
|
|
163
|
+
}
|
|
164
|
+
// String path — load from filesystem
|
|
165
|
+
const filePath = el.src;
|
|
166
|
+
if (!filePath || typeof filePath !== 'string') {
|
|
167
|
+
throw new PretextPdfError('IMAGE_LOAD_FAILED', `Image "${key}": 'src' must be a non-empty string path or Uint8Array`);
|
|
168
|
+
}
|
|
169
|
+
// Dynamic import — tree-shaken in browser builds, only loaded when src is a file path
|
|
170
|
+
const fs = await import('fs');
|
|
171
|
+
if (!fs.existsSync(filePath)) {
|
|
172
|
+
throw new PretextPdfError('IMAGE_LOAD_FAILED', `Image "${key}": file not found at "${filePath}". Check the path in the image element's 'src' field.`);
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
const buffer = fs.readFileSync(filePath);
|
|
176
|
+
return new Uint8Array(buffer);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
throw new PretextPdfError('IMAGE_LOAD_FAILED', `Image "${key}": failed to read file "${filePath}": ${err instanceof Error ? err.message : String(err)}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,iFAAiF;AAEjF,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;IACnD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACnD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;IAChC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC7E,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAA;AAChC,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAA;IACpE,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;IACrE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACnC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IAClD,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC7C,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAA;AAChC,CAAC;AAED,SAAS,oBAAoB,CAAC,EAAc,EAAE,YAAoB;IAChE,MAAM,OAAO,GAAG,eAAe,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACrE,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;IAEnE,IAAI,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACtD,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,MAAM,EAAE,CAAA;IACnD,CAAC;IACD,IAAI,EAAE,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAA;IAClG,CAAC;IACD,IAAI,EAAE,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,MAAM,EAAE,CAAA;IACrG,CAAC;IACD,6EAA6E;IAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA,CAAE,oDAAoD;IAC1G,MAAM,QAAQ,GAAG,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAA;IACnE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;AAC9B,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,GAAW,EACX,OAAe,EACf,QAAgB,EAChB,MAAmB;IAEnB,IAAI,SAAc,CAAA;IAClB,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,MAAM,CAAC,iBAA2B,CAAC,CAAA;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,eAAe,CACvB,mBAAmB,EACnB,2GAA2G,CAC5G,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,CAAA,CAAE,wBAAwB;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAA;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAA;IAE7C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QACxD,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACnC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,KAAK,EAAE,CAAA;QACjC,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC1B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;QAC3C,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QAC9C,OAAO,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,eAAe,CACvB,mBAAmB,EACnB,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC/E,CAAA;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAgB,EAAE,MAAmB,EAAE,YAAoB;IAC1F,MAAM,QAAQ,GAAa,IAAI,GAAG,EAAE,CAAA;IAEpC,4EAA4E;IAC5E,MAAM,YAAY,GAA6C,EAAE,CAAA;IACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAE,CAAA;QAC1B,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC;QACzC,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CACf,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;YAC3C,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;QAC3B,CAAC,CAAC,CACH;QACH,CAAC,CAAC,EAAE,CAAA;IAEN,0CAA0C;IAC1C,KAAK,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,WAAW,EAAE,CAAC;QAC7C,MAAM,cAAc,GAAG,kBAAkB,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QACzD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,cAAc,KAAK,KAAK;gBACvC,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAC9B,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YAChC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,eAAe,CACvB,uBAAuB,EACvB,cAAc,GAAG,eAAe,cAAc,8DAA8D,cAAc,CAAC,WAAW,EAAE,iBAAiB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC5M,CAAA;QACH,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAE,CAAA;QAC1B,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,CAAA;YACtB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAAC,EAAE,EAAE,YAAY,CAAC,CAAA;YACpE,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;YACxE,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QAC7B,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,IAAI,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAA;QAC/B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,GAAG,YAAY,UAAU;gBACrC,CAAC,CAAC,GAAG;gBACL,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAa,CAAC,CAAC,CAAA;YACpE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;YAC9F,MAAM,QAAQ,GAAG,KAAK;gBACpB,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAC9B,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YAChC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,iFAAiF;QACnF,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,EAAgB,EAAE,KAAiB,EAAE,GAAW;IAC1E,mCAAmC;IACnC,IAAI,EAAE,CAAC,MAAM,KAAK,KAAK;QAAE,OAAO,KAAK,CAAA;IACrC,IAAI,EAAE,CAAC,MAAM,KAAK,KAAK;QAAE,OAAO,KAAK,CAAA;IAErC,+CAA+C;IAC/C,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAClG,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAE7E,2BAA2B;IAC3B,IAAI,OAAO,EAAE,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;QACjD,IAAI,GAAG,KAAK,KAAK;YAAE,OAAO,KAAK,CAAA;QAC/B,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM;YAAE,OAAO,KAAK,CAAA;IACnD,CAAC;IAED,MAAM,IAAI,eAAe,CACvB,uBAAuB,EACvB,UAAU,GAAG,6DAA6D,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,GAAG,+CAA+C,CAC3L,CAAA;AACH,CAAC;AAED,sDAAsD;AACtD,KAAK,UAAU,cAAc,CAAC,EAAgB,EAAE,GAAW;IACzD,oCAAoC;IACpC,IAAI,EAAE,CAAC,GAAG,YAAY,UAAU,EAAE,CAAC;QACjC,OAAO,EAAE,CAAC,GAAG,CAAA;IACf,CAAC;IAED,qCAAqC;IACrC,MAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAA;IAEvB,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,IAAI,eAAe,CAAC,mBAAmB,EAAE,UAAU,GAAG,wDAAwD,CAAC,CAAA;IACvH,CAAC;IAED,sFAAsF;IACtF,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;IAE7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,eAAe,CACvB,mBAAmB,EACnB,UAAU,GAAG,yBAAyB,QAAQ,uDAAuD,CACtG,CAAA;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;QACxC,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAA;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,eAAe,CACvB,mBAAmB,EACnB,UAAU,GAAG,2BAA2B,QAAQ,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACzG,CAAA;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builder API for pretext-pdf
|
|
3
|
+
*
|
|
4
|
+
* Provides a fluent, chainable interface for constructing PDF documents.
|
|
5
|
+
* Accumulates ContentElement[] and delegates final rendering to render().
|
|
6
|
+
*/
|
|
7
|
+
import type { PdfDocument, ParagraphElement, HeadingElement, TableElement, ImageElement, ListElement, CodeBlockElement, RichParagraphElement, BlockquoteElement, HorizontalRuleElement, InlineSpan, Margins, FontSpec, HeaderFooterSpec, DocumentMetadata } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Options for initializing the PDF builder.
|
|
10
|
+
* Includes all PdfDocument fields except 'content' (which is managed by the builder).
|
|
11
|
+
*/
|
|
12
|
+
export interface PdfBuilderOptions {
|
|
13
|
+
pageSize?: PdfDocument['pageSize'];
|
|
14
|
+
margins?: Partial<Margins>;
|
|
15
|
+
defaultFont?: string;
|
|
16
|
+
defaultFontSize?: number;
|
|
17
|
+
defaultLineHeight?: number;
|
|
18
|
+
fonts?: FontSpec[];
|
|
19
|
+
header?: HeaderFooterSpec;
|
|
20
|
+
footer?: HeaderFooterSpec;
|
|
21
|
+
metadata?: DocumentMetadata;
|
|
22
|
+
}
|
|
23
|
+
export interface PdfBuilder {
|
|
24
|
+
addText(text: string, opts?: Partial<Omit<ParagraphElement, 'type' | 'text'>>): PdfBuilder;
|
|
25
|
+
addHeading(text: string, opts?: Partial<Omit<HeadingElement, 'type' | 'text' | 'level'>> & {
|
|
26
|
+
level?: number;
|
|
27
|
+
}): PdfBuilder;
|
|
28
|
+
addTable(opts: Omit<TableElement, 'type'>): PdfBuilder;
|
|
29
|
+
addImage(src: ImageElement['src'], opts?: Partial<Omit<ImageElement, 'type' | 'src'>>): PdfBuilder;
|
|
30
|
+
addList(opts: Omit<ListElement, 'type'>): PdfBuilder;
|
|
31
|
+
addCode(text: string, opts: Omit<CodeBlockElement, 'type' | 'text'>): PdfBuilder;
|
|
32
|
+
addRichText(spans: InlineSpan[], opts?: Partial<Omit<RichParagraphElement, 'type' | 'spans'>>): PdfBuilder;
|
|
33
|
+
addBlockquote(text: string, opts?: Partial<Omit<BlockquoteElement, 'type' | 'text'>>): PdfBuilder;
|
|
34
|
+
addHr(opts?: Partial<Omit<HorizontalRuleElement, 'type'>>): PdfBuilder;
|
|
35
|
+
addSpacer(height: number): PdfBuilder;
|
|
36
|
+
addPageBreak(): PdfBuilder;
|
|
37
|
+
toDocument(): PdfDocument;
|
|
38
|
+
build(): Promise<Uint8Array>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a new PDF document using the builder API.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const pdf = await createPdf({ pageSize: 'Letter' })
|
|
46
|
+
* .addHeading('Hello')
|
|
47
|
+
* .addText('This is a paragraph.')
|
|
48
|
+
* .addHr()
|
|
49
|
+
* .build()
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function createPdf(options?: PdfBuilderOptions): PdfBuilder;
|
|
53
|
+
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,WAAW,EAEX,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,OAAO,EACP,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAEnB;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAA;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,QAAQ,CAAC,EAAE,gBAAgB,CAAA;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,UAAU,CAAA;IAC1F,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAAA;IAC1H,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,UAAU,CAAA;IACtD,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,UAAU,CAAA;IAClG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,UAAU,CAAA;IACpD,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,UAAU,CAAA;IAChF,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,UAAU,CAAA;IAC1G,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,UAAU,CAAA;IACjG,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,GAAG,UAAU,CAAA;IACtE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAA;IACrC,YAAY,IAAI,UAAU,CAAA;IAC1B,UAAU,IAAI,WAAW,CAAA;IACzB,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC,CAAA;CAC7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAyHrE"}
|
package/dist/builder.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builder API for pretext-pdf
|
|
3
|
+
*
|
|
4
|
+
* Provides a fluent, chainable interface for constructing PDF documents.
|
|
5
|
+
* Accumulates ContentElement[] and delegates final rendering to render().
|
|
6
|
+
*/
|
|
7
|
+
import { render } from './index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create a new PDF document using the builder API.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const pdf = await createPdf({ pageSize: 'Letter' })
|
|
14
|
+
* .addHeading('Hello')
|
|
15
|
+
* .addText('This is a paragraph.')
|
|
16
|
+
* .addHr()
|
|
17
|
+
* .build()
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export function createPdf(options = {}) {
|
|
21
|
+
const content = [];
|
|
22
|
+
return {
|
|
23
|
+
/**
|
|
24
|
+
* Add a paragraph.
|
|
25
|
+
*/
|
|
26
|
+
addText(text, opts) {
|
|
27
|
+
content.push({ type: 'paragraph', text, ...opts });
|
|
28
|
+
return this;
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Add a heading.
|
|
32
|
+
*/
|
|
33
|
+
addHeading(text, opts) {
|
|
34
|
+
const level = (opts?.level ?? 1);
|
|
35
|
+
const { level: _, ...restOpts } = opts ?? {};
|
|
36
|
+
content.push({ type: 'heading', level, text, ...restOpts });
|
|
37
|
+
return this;
|
|
38
|
+
},
|
|
39
|
+
/**
|
|
40
|
+
* Add a table.
|
|
41
|
+
*/
|
|
42
|
+
addTable(opts) {
|
|
43
|
+
content.push({ type: 'table', ...opts });
|
|
44
|
+
return this;
|
|
45
|
+
},
|
|
46
|
+
/**
|
|
47
|
+
* Add an image.
|
|
48
|
+
*/
|
|
49
|
+
addImage(src, opts) {
|
|
50
|
+
content.push({ type: 'image', src, ...opts });
|
|
51
|
+
return this;
|
|
52
|
+
},
|
|
53
|
+
/**
|
|
54
|
+
* Add a list (ordered or unordered).
|
|
55
|
+
*/
|
|
56
|
+
addList(opts) {
|
|
57
|
+
content.push({ type: 'list', ...opts });
|
|
58
|
+
return this;
|
|
59
|
+
},
|
|
60
|
+
/**
|
|
61
|
+
* Add a code block.
|
|
62
|
+
*/
|
|
63
|
+
addCode(text, opts) {
|
|
64
|
+
content.push({ type: 'code', text, ...opts });
|
|
65
|
+
return this;
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* Add a rich paragraph with mixed formatting (bold, italic, color).
|
|
69
|
+
*/
|
|
70
|
+
addRichText(spans, opts) {
|
|
71
|
+
content.push({ type: 'rich-paragraph', spans, ...opts });
|
|
72
|
+
return this;
|
|
73
|
+
},
|
|
74
|
+
/**
|
|
75
|
+
* Add a blockquote.
|
|
76
|
+
*/
|
|
77
|
+
addBlockquote(text, opts) {
|
|
78
|
+
content.push({ type: 'blockquote', text, ...opts });
|
|
79
|
+
return this;
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* Add a horizontal rule.
|
|
83
|
+
*/
|
|
84
|
+
addHr(opts) {
|
|
85
|
+
content.push({ type: 'hr', ...opts });
|
|
86
|
+
return this;
|
|
87
|
+
},
|
|
88
|
+
/**
|
|
89
|
+
* Add a spacer (vertical whitespace).
|
|
90
|
+
*/
|
|
91
|
+
addSpacer(height) {
|
|
92
|
+
content.push({ type: 'spacer', height });
|
|
93
|
+
return this;
|
|
94
|
+
},
|
|
95
|
+
/**
|
|
96
|
+
* Add a page break.
|
|
97
|
+
*/
|
|
98
|
+
addPageBreak() {
|
|
99
|
+
content.push({ type: 'page-break' });
|
|
100
|
+
return this;
|
|
101
|
+
},
|
|
102
|
+
/**
|
|
103
|
+
* Get the underlying declarative document.
|
|
104
|
+
* Useful for inspection, serialization, or reusing with render().
|
|
105
|
+
*/
|
|
106
|
+
toDocument() {
|
|
107
|
+
return {
|
|
108
|
+
pageSize: options.pageSize,
|
|
109
|
+
margins: options.margins,
|
|
110
|
+
defaultFont: options.defaultFont,
|
|
111
|
+
defaultFontSize: options.defaultFontSize,
|
|
112
|
+
defaultLineHeight: options.defaultLineHeight,
|
|
113
|
+
fonts: options.fonts,
|
|
114
|
+
header: options.header,
|
|
115
|
+
footer: options.footer,
|
|
116
|
+
metadata: options.metadata,
|
|
117
|
+
content,
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
/**
|
|
121
|
+
* Build the PDF and return the bytes.
|
|
122
|
+
* Delegates to render() with the accumulated document.
|
|
123
|
+
*/
|
|
124
|
+
async build() {
|
|
125
|
+
return render(this.toDocument());
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Error codes for PretextPdfError */
|
|
2
|
+
export type ErrorCode = 'VALIDATION_ERROR' | 'FONT_LOAD_FAILED' | 'FONT_EMBED_FAILED' | 'PAGE_TOO_SMALL' | 'CANVAS_UNAVAILABLE' | 'PAGE_LIMIT_EXCEEDED' | 'IMAGE_LOAD_FAILED' | 'IMAGE_FORMAT_MISMATCH' | 'IMAGE_TOO_TALL' | 'TABLE_COLUMN_OVERFLOW' | 'TABLE_COLUMN_TOO_NARROW' | 'MONOSPACE_FONT_REQUIRED' | 'ITALIC_FONT_NOT_LOADED' | 'FONT_NOT_LOADED' | 'COLUMN_WIDTH_TOO_NARROW' | 'COLSPAN_OVERFLOW' | 'ENCRYPTION_NOT_AVAILABLE' | 'UNSUPPORTED_LANGUAGE' | 'SVG_RENDER_FAILED' | 'WATERMARK_ROTATION_OUT_OF_RANGE' | 'SVG_INVALID_MARKUP';
|
|
3
|
+
export declare class PretextPdfError extends Error {
|
|
4
|
+
readonly code: ErrorCode;
|
|
5
|
+
constructor(code: ErrorCode, message: string);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,MAAM,MAAM,SAAS,GACjB,kBAAkB,GAClB,kBAAkB,GAClB,mBAAmB,GACnB,gBAAgB,GAChB,oBAAoB,GACpB,qBAAqB,GACrB,mBAAmB,GACnB,uBAAuB,GACvB,gBAAgB,GAChB,uBAAuB,GACvB,yBAAyB,GACzB,yBAAyB,GACzB,wBAAwB,GACxB,iBAAiB,GACjB,yBAAyB,GACzB,kBAAkB,GAClB,0BAA0B,GAC1B,sBAAsB,GACtB,mBAAmB,GACnB,iCAAiC,GACjC,oBAAoB,CAAA;AAExB,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;gBAEZ,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM;CAS7C"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class PretextPdfError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
constructor(code, message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = 'PretextPdfError';
|
|
6
|
+
this.code = code;
|
|
7
|
+
// Maintains proper stack trace in V8
|
|
8
|
+
if (Error.captureStackTrace) {
|
|
9
|
+
Error.captureStackTrace(this, PretextPdfError);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAwBA,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,IAAI,CAAW;IAExB,YAAY,IAAe,EAAE,OAAe;QAC1C,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,qCAAqC;QACrC,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAA;QAChD,CAAC;IACH,CAAC;CACF"}
|
package/dist/fonts.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PDFDocument } from 'pdf-lib';
|
|
2
|
+
import type { PdfDocument, FontMap } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Stage 2: Load and embed all fonts.
|
|
5
|
+
* - Scans document for all font references
|
|
6
|
+
* - Loads font bytes (file system or Uint8Array)
|
|
7
|
+
* - Embeds each into pdfDoc via fontkit
|
|
8
|
+
* - Returns FontMap for use in measure + render stages
|
|
9
|
+
*
|
|
10
|
+
* NOTE: pdfDoc is already created by the caller. Fonts are embedded into it here.
|
|
11
|
+
* The same pdfDoc is used in Stage 5 (render).
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadFonts(doc: PdfDocument, pdfDoc: PDFDocument): Promise<FontMap>;
|
|
14
|
+
/**
|
|
15
|
+
* Walk all content elements + header/footer and collect text strings grouped by font key.
|
|
16
|
+
* Used by Phase 6D font subsetting to determine which glyphs each font needs.
|
|
17
|
+
*
|
|
18
|
+
* Returns: Map<fontKey, concatenated text string>
|
|
19
|
+
*/
|
|
20
|
+
export declare function collectTextByFont(doc: PdfDocument): Map<string, string>;
|
|
21
|
+
//# sourceMappingURL=fonts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAKrC,OAAO,KAAK,EAAE,WAAW,EAAY,OAAO,EAAE,MAAM,YAAY,CAAA;AA4BhE;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,OAAO,CAAC,CA6DlB;AA6JD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,WAAW,GACf,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAqFrB"}
|