@pdfme/generator 6.0.3-dev.0 → 6.0.4-dev.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/dist/constants.d.ts +1 -0
- package/dist/generate.d.ts +3 -0
- package/dist/helper.d.ts +29 -0
- package/{src/index.ts → dist/index.d.ts} +0 -1
- package/dist/index.js +246 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/package.json +5 -1
- package/.vscode/settings.json +0 -5
- package/src/constants.ts +0 -1
- package/src/generate.ts +0 -166
- package/src/helper.ts +0 -172
- package/src/types.ts +0 -5
- package/tsconfig.build.json +0 -14
- package/tsconfig.json +0 -16
- package/vite.config.mts +0 -39
- package/vitest.setup.ts +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TOOL_NAME = "pdfme (https://pdfme.com/)";
|
package/dist/helper.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Schema, Plugins, GeneratorOptions, Template, PDFRenderProps } from '@pdfme/common';
|
|
2
|
+
import { PDFPage, PDFDocument, PDFEmbeddedPage } from '@pdfme/pdf-lib';
|
|
3
|
+
import type { EmbedPdfBox } from './types.js';
|
|
4
|
+
export declare const getEmbedPdfPages: (arg: {
|
|
5
|
+
template: Template;
|
|
6
|
+
pdfDoc: PDFDocument;
|
|
7
|
+
}) => Promise<{
|
|
8
|
+
basePages: (PDFEmbeddedPage | PDFPage)[];
|
|
9
|
+
embedPdfBoxes: EmbedPdfBox[];
|
|
10
|
+
}>;
|
|
11
|
+
export declare const validateRequiredFields: (template: Template, inputs: Record<string, unknown>[]) => void;
|
|
12
|
+
export declare const preprocessing: (arg: {
|
|
13
|
+
template: Template;
|
|
14
|
+
userPlugins: Plugins;
|
|
15
|
+
}) => Promise<{
|
|
16
|
+
pdfDoc: PDFDocument;
|
|
17
|
+
renderObj: Record<string, (arg: PDFRenderProps<Schema & {
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}>) => Promise<void> | void>;
|
|
20
|
+
}>;
|
|
21
|
+
export declare const postProcessing: (props: {
|
|
22
|
+
pdfDoc: PDFDocument;
|
|
23
|
+
options: GeneratorOptions;
|
|
24
|
+
}) => void;
|
|
25
|
+
export declare const insertPage: (arg: {
|
|
26
|
+
basePage: PDFEmbeddedPage | PDFPage;
|
|
27
|
+
embedPdfBox: EmbedPdfBox;
|
|
28
|
+
pdfDoc: PDFDocument;
|
|
29
|
+
}) => PDFPage;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import * as pdfLib from "@pdfme/pdf-lib";
|
|
2
|
+
import { PDFDocument, PDFEmbeddedPage, PDFPage } from "@pdfme/pdf-lib";
|
|
3
|
+
import { checkGenerateProps, cloneDeep, getB64BasePdf, getDynamicTemplate, isBlankPdf, mm2pt, pluginRegistry, pt2mm, replacePlaceholders } from "@pdfme/common";
|
|
4
|
+
import { getDynamicHeightsForTable } from "@pdfme/schemas/tables";
|
|
5
|
+
import * as fontkit from "fontkit";
|
|
6
|
+
import { builtInPlugins } from "@pdfme/schemas/builtins";
|
|
7
|
+
//#region src/constants.ts
|
|
8
|
+
var TOOL_NAME = "pdfme (https://pdfme.com/)";
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/helper.ts
|
|
11
|
+
var getEmbedPdfPages = async (arg) => {
|
|
12
|
+
const { template: { schemas, basePdf }, pdfDoc } = arg;
|
|
13
|
+
let basePages = [];
|
|
14
|
+
let embedPdfBoxes = [];
|
|
15
|
+
if (isBlankPdf(basePdf)) {
|
|
16
|
+
const { width: _width, height: _height } = basePdf;
|
|
17
|
+
const width = mm2pt(_width);
|
|
18
|
+
const height = mm2pt(_height);
|
|
19
|
+
basePages = schemas.map(() => {
|
|
20
|
+
const page = PDFPage.create(pdfDoc);
|
|
21
|
+
page.setSize(width, height);
|
|
22
|
+
return page;
|
|
23
|
+
});
|
|
24
|
+
embedPdfBoxes = schemas.map(() => ({
|
|
25
|
+
mediaBox: {
|
|
26
|
+
x: 0,
|
|
27
|
+
y: 0,
|
|
28
|
+
width,
|
|
29
|
+
height
|
|
30
|
+
},
|
|
31
|
+
bleedBox: {
|
|
32
|
+
x: 0,
|
|
33
|
+
y: 0,
|
|
34
|
+
width,
|
|
35
|
+
height
|
|
36
|
+
},
|
|
37
|
+
trimBox: {
|
|
38
|
+
x: 0,
|
|
39
|
+
y: 0,
|
|
40
|
+
width,
|
|
41
|
+
height
|
|
42
|
+
}
|
|
43
|
+
}));
|
|
44
|
+
} else {
|
|
45
|
+
const willLoadPdf = await getB64BasePdf(basePdf);
|
|
46
|
+
const embedPdfPages = (await PDFDocument.load(willLoadPdf)).getPages();
|
|
47
|
+
embedPdfBoxes = embedPdfPages.map((p) => ({
|
|
48
|
+
mediaBox: p.getMediaBox(),
|
|
49
|
+
bleedBox: p.getBleedBox(),
|
|
50
|
+
trimBox: p.getTrimBox()
|
|
51
|
+
}));
|
|
52
|
+
const boundingBoxes = embedPdfPages.map((p) => {
|
|
53
|
+
const { x, y, width, height } = p.getMediaBox();
|
|
54
|
+
return {
|
|
55
|
+
left: x,
|
|
56
|
+
bottom: y,
|
|
57
|
+
right: width,
|
|
58
|
+
top: height + y
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
const transformationMatrices = embedPdfPages.map(() => [
|
|
62
|
+
1,
|
|
63
|
+
0,
|
|
64
|
+
0,
|
|
65
|
+
1,
|
|
66
|
+
0,
|
|
67
|
+
0
|
|
68
|
+
]);
|
|
69
|
+
basePages = await pdfDoc.embedPages(embedPdfPages, boundingBoxes, transformationMatrices);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
basePages,
|
|
73
|
+
embedPdfBoxes
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
var validateRequiredFields = (template, inputs) => {
|
|
77
|
+
template.schemas.forEach((schemaPage) => schemaPage.forEach((schema) => {
|
|
78
|
+
if (schema.required && !schema.readOnly && !inputs.some((input) => input[schema.name])) throw new Error(`[@pdfme/generator] input for '${schema.name}' is required to generate this PDF`);
|
|
79
|
+
}));
|
|
80
|
+
};
|
|
81
|
+
var preprocessing = async (arg) => {
|
|
82
|
+
const { template, userPlugins } = arg;
|
|
83
|
+
const { schemas, basePdf } = template;
|
|
84
|
+
const staticSchema = isBlankPdf(basePdf) ? basePdf.staticSchema ?? [] : [];
|
|
85
|
+
const pdfDoc = await PDFDocument.create();
|
|
86
|
+
pdfDoc.registerFontkit(fontkit);
|
|
87
|
+
const plugins = pluginRegistry(Object.values(userPlugins).length > 0 ? userPlugins : builtInPlugins);
|
|
88
|
+
return {
|
|
89
|
+
pdfDoc,
|
|
90
|
+
renderObj: Array.from(new Set(schemas.flatMap((schemaPage) => schemaPage.map((schema) => schema.type)).concat(staticSchema.map((schema) => schema.type)))).reduce((acc, type) => {
|
|
91
|
+
const plugin = plugins.findByType(type);
|
|
92
|
+
if (!plugin || !plugin.pdf) throw new Error(`[@pdfme/generator] Plugin or renderer for type ${type} not found.
|
|
93
|
+
Check this document: https://pdfme.com/docs/custom-schemas`);
|
|
94
|
+
return {
|
|
95
|
+
...acc,
|
|
96
|
+
[type]: plugin.pdf
|
|
97
|
+
};
|
|
98
|
+
}, {})
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
var postProcessing = (props) => {
|
|
102
|
+
const { pdfDoc, options } = props;
|
|
103
|
+
const { author = TOOL_NAME, creationDate = /* @__PURE__ */ new Date(), creator = TOOL_NAME, keywords = [], lang = "en", modificationDate = /* @__PURE__ */ new Date(), producer = TOOL_NAME, subject = "", title = "" } = options;
|
|
104
|
+
pdfDoc.setAuthor(author);
|
|
105
|
+
pdfDoc.setCreationDate(creationDate);
|
|
106
|
+
pdfDoc.setCreator(creator);
|
|
107
|
+
pdfDoc.setKeywords(keywords);
|
|
108
|
+
pdfDoc.setLanguage(lang);
|
|
109
|
+
pdfDoc.setModificationDate(modificationDate);
|
|
110
|
+
pdfDoc.setProducer(producer);
|
|
111
|
+
pdfDoc.setSubject(subject);
|
|
112
|
+
pdfDoc.setTitle(title);
|
|
113
|
+
};
|
|
114
|
+
var insertPage = (arg) => {
|
|
115
|
+
const { basePage, embedPdfBox, pdfDoc } = arg;
|
|
116
|
+
const size = basePage instanceof PDFEmbeddedPage ? basePage.size() : basePage.getSize();
|
|
117
|
+
const insertedPage = basePage instanceof PDFEmbeddedPage ? pdfDoc.addPage([size.width, size.height]) : pdfDoc.addPage(basePage);
|
|
118
|
+
if (basePage instanceof PDFEmbeddedPage) {
|
|
119
|
+
insertedPage.drawPage(basePage);
|
|
120
|
+
const { mediaBox, bleedBox, trimBox } = embedPdfBox;
|
|
121
|
+
insertedPage.setMediaBox(mediaBox.x, mediaBox.y, mediaBox.width, mediaBox.height);
|
|
122
|
+
insertedPage.setBleedBox(bleedBox.x, bleedBox.y, bleedBox.width, bleedBox.height);
|
|
123
|
+
insertedPage.setTrimBox(trimBox.x, trimBox.y, trimBox.width, trimBox.height);
|
|
124
|
+
}
|
|
125
|
+
return insertedPage;
|
|
126
|
+
};
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/generate.ts
|
|
129
|
+
var generate = async (props) => {
|
|
130
|
+
checkGenerateProps(props);
|
|
131
|
+
const { inputs, template: _template, options = {}, plugins: userPlugins = {} } = props;
|
|
132
|
+
const template = cloneDeep(_template);
|
|
133
|
+
const basePdf = template.basePdf;
|
|
134
|
+
if (inputs.length === 0) throw new Error("[@pdfme/generator] inputs should not be empty, pass at least an empty object in the array");
|
|
135
|
+
validateRequiredFields(template, inputs);
|
|
136
|
+
const { pdfDoc, renderObj } = await preprocessing({
|
|
137
|
+
template,
|
|
138
|
+
userPlugins
|
|
139
|
+
});
|
|
140
|
+
const _cache = /* @__PURE__ */ new Map();
|
|
141
|
+
for (let i = 0; i < inputs.length; i += 1) {
|
|
142
|
+
const input = inputs[i];
|
|
143
|
+
const dynamicTemplate = await getDynamicTemplate({
|
|
144
|
+
template,
|
|
145
|
+
input,
|
|
146
|
+
options,
|
|
147
|
+
_cache,
|
|
148
|
+
getDynamicHeights: (value, args) => {
|
|
149
|
+
switch (args.schema.type) {
|
|
150
|
+
case "table": return getDynamicHeightsForTable(value, args);
|
|
151
|
+
default: return Promise.resolve([args.schema.height]);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
const { basePages, embedPdfBoxes } = await getEmbedPdfPages({
|
|
156
|
+
template: dynamicTemplate,
|
|
157
|
+
pdfDoc
|
|
158
|
+
});
|
|
159
|
+
const schemas = dynamicTemplate.schemas;
|
|
160
|
+
const schemaNameSet = /* @__PURE__ */ new Set();
|
|
161
|
+
schemas.forEach((page) => {
|
|
162
|
+
page.forEach((schema) => {
|
|
163
|
+
if (schema.name) schemaNameSet.add(schema.name);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
const schemaNames = Array.from(schemaNameSet);
|
|
167
|
+
for (let j = 0; j < basePages.length; j += 1) {
|
|
168
|
+
const basePage = basePages[j];
|
|
169
|
+
const embedPdfBox = embedPdfBoxes[j];
|
|
170
|
+
const boundingBoxLeft = basePage instanceof pdfLib.PDFEmbeddedPage ? pt2mm(embedPdfBox.mediaBox.x) : 0;
|
|
171
|
+
const boundingBoxBottom = basePage instanceof pdfLib.PDFEmbeddedPage ? pt2mm(embedPdfBox.mediaBox.y) : 0;
|
|
172
|
+
const page = insertPage({
|
|
173
|
+
basePage,
|
|
174
|
+
embedPdfBox,
|
|
175
|
+
pdfDoc
|
|
176
|
+
});
|
|
177
|
+
if (isBlankPdf(basePdf) && basePdf.staticSchema) for (let k = 0; k < basePdf.staticSchema.length; k += 1) {
|
|
178
|
+
const staticSchema = basePdf.staticSchema[k];
|
|
179
|
+
const render = renderObj[staticSchema.type];
|
|
180
|
+
if (!render) continue;
|
|
181
|
+
const value = staticSchema.readOnly ? replacePlaceholders({
|
|
182
|
+
content: staticSchema.content || "",
|
|
183
|
+
variables: {
|
|
184
|
+
...input,
|
|
185
|
+
totalPages: basePages.length,
|
|
186
|
+
currentPage: j + 1
|
|
187
|
+
},
|
|
188
|
+
schemas
|
|
189
|
+
}) : staticSchema.content || "";
|
|
190
|
+
staticSchema.position = {
|
|
191
|
+
x: staticSchema.position.x + boundingBoxLeft,
|
|
192
|
+
y: staticSchema.position.y - boundingBoxBottom
|
|
193
|
+
};
|
|
194
|
+
await render({
|
|
195
|
+
value,
|
|
196
|
+
schema: staticSchema,
|
|
197
|
+
basePdf,
|
|
198
|
+
pdfLib,
|
|
199
|
+
pdfDoc,
|
|
200
|
+
page,
|
|
201
|
+
options,
|
|
202
|
+
_cache
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
for (let l = 0; l < schemaNames.length; l += 1) {
|
|
206
|
+
const name = schemaNames[l];
|
|
207
|
+
const schema = (schemas[j] || []).find((s) => s.name == name);
|
|
208
|
+
if (!schema) continue;
|
|
209
|
+
const render = renderObj[schema.type];
|
|
210
|
+
if (!render) continue;
|
|
211
|
+
const value = schema.readOnly ? replacePlaceholders({
|
|
212
|
+
content: schema.content || "",
|
|
213
|
+
variables: {
|
|
214
|
+
...input,
|
|
215
|
+
totalPages: basePages.length,
|
|
216
|
+
currentPage: j + 1
|
|
217
|
+
},
|
|
218
|
+
schemas
|
|
219
|
+
}) : input[name] || "";
|
|
220
|
+
schema.position = {
|
|
221
|
+
x: schema.position.x + boundingBoxLeft,
|
|
222
|
+
y: schema.position.y - boundingBoxBottom
|
|
223
|
+
};
|
|
224
|
+
await render({
|
|
225
|
+
value,
|
|
226
|
+
schema,
|
|
227
|
+
basePdf,
|
|
228
|
+
pdfLib,
|
|
229
|
+
pdfDoc,
|
|
230
|
+
page,
|
|
231
|
+
options,
|
|
232
|
+
_cache
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
postProcessing({
|
|
238
|
+
pdfDoc,
|
|
239
|
+
options
|
|
240
|
+
});
|
|
241
|
+
return pdfDoc.save();
|
|
242
|
+
};
|
|
243
|
+
//#endregion
|
|
244
|
+
export { generate };
|
|
245
|
+
|
|
246
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/constants.ts","../src/helper.ts","../src/generate.ts"],"sourcesContent":["export const TOOL_NAME = 'pdfme (https://pdfme.com/)';\n","import * as fontkit from 'fontkit';\nimport {\n Schema,\n Plugins,\n GeneratorOptions,\n Template,\n PDFRenderProps,\n getB64BasePdf,\n isBlankPdf,\n mm2pt,\n pluginRegistry,\n BasePdf,\n} from '@pdfme/common';\nimport { builtInPlugins } from '@pdfme/schemas/builtins';\nimport { PDFPage, PDFDocument, PDFEmbeddedPage, TransformationMatrix } from '@pdfme/pdf-lib';\nimport { TOOL_NAME } from './constants.js';\nimport type { EmbedPdfBox } from './types.js';\n\nexport const getEmbedPdfPages = async (arg: { template: Template; pdfDoc: PDFDocument }) => {\n const {\n template: { schemas, basePdf },\n pdfDoc,\n } = arg as { template: { schemas: Schema[][]; basePdf: BasePdf }; pdfDoc: PDFDocument };\n let basePages: (PDFEmbeddedPage | PDFPage)[] = [];\n let embedPdfBoxes: EmbedPdfBox[] = [];\n\n if (isBlankPdf(basePdf)) {\n const { width: _width, height: _height } = basePdf;\n const width = mm2pt(_width);\n const height = mm2pt(_height);\n basePages = schemas.map(() => {\n const page = PDFPage.create(pdfDoc);\n page.setSize(width, height);\n return page;\n });\n embedPdfBoxes = schemas.map(() => ({\n mediaBox: { x: 0, y: 0, width, height },\n bleedBox: { x: 0, y: 0, width, height },\n trimBox: { x: 0, y: 0, width, height },\n }));\n } else {\n const willLoadPdf = await getB64BasePdf(basePdf);\n const embedPdf = await PDFDocument.load(willLoadPdf);\n const embedPdfPages = embedPdf.getPages();\n embedPdfBoxes = embedPdfPages.map((p) => ({\n mediaBox: p.getMediaBox(),\n bleedBox: p.getBleedBox(),\n trimBox: p.getTrimBox(),\n }));\n const boundingBoxes = embedPdfPages.map((p) => {\n const { x, y, width, height } = p.getMediaBox();\n return { left: x, bottom: y, right: width, top: height + y };\n });\n const transformationMatrices = embedPdfPages.map(\n () => [1, 0, 0, 1, 0, 0] as TransformationMatrix,\n );\n basePages = await pdfDoc.embedPages(embedPdfPages, boundingBoxes, transformationMatrices);\n }\n return { basePages, embedPdfBoxes };\n};\n\nexport const validateRequiredFields = (template: Template, inputs: Record<string, unknown>[]) => {\n template.schemas.forEach((schemaPage: Schema[]) =>\n schemaPage.forEach((schema: Schema) => {\n if (schema.required && !schema.readOnly && !inputs.some((input) => input[schema.name])) {\n throw new Error(\n `[@pdfme/generator] input for '${schema.name}' is required to generate this PDF`,\n );\n }\n }),\n );\n};\n\nexport const preprocessing = async (arg: { template: Template; userPlugins: Plugins }) => {\n const { template, userPlugins } = arg;\n const { schemas, basePdf } = template as { schemas: Schema[][]; basePdf: BasePdf };\n const staticSchema: Schema[] = isBlankPdf(basePdf) ? (basePdf.staticSchema ?? []) : [];\n\n const pdfDoc = await PDFDocument.create();\n // @ts-expect-error registerFontkit method is not in type definitions but exists at runtime\n pdfDoc.registerFontkit(fontkit);\n\n const plugins = pluginRegistry(\n Object.values(userPlugins).length > 0 ? userPlugins : builtInPlugins,\n );\n\n const schemaTypes = Array.from(\n new Set(\n schemas\n .flatMap((schemaPage: Schema[]) => schemaPage.map((schema: Schema) => schema.type))\n .concat(staticSchema.map((schema: Schema) => schema.type)),\n ),\n );\n\n const renderObj = schemaTypes.reduce(\n (\n acc: Record<\n string,\n (arg: PDFRenderProps<Schema & { [key: string]: unknown }>) => Promise<void> | void\n >,\n type: string,\n ) => {\n const plugin = plugins.findByType(type);\n\n if (!plugin || !plugin.pdf) {\n throw new Error(`[@pdfme/generator] Plugin or renderer for type ${type} not found.\nCheck this document: https://pdfme.com/docs/custom-schemas`);\n }\n\n // Use type assertion to handle the pdf function with schema type\n return {\n ...acc,\n [type]: plugin.pdf as (\n arg: PDFRenderProps<Schema & { [key: string]: unknown }>,\n ) => Promise<void> | void,\n };\n },\n {} as Record<\n string,\n (arg: PDFRenderProps<Schema & { [key: string]: unknown }>) => Promise<void> | void\n >,\n );\n\n return { pdfDoc, renderObj };\n};\n\nexport const postProcessing = (props: { pdfDoc: PDFDocument; options: GeneratorOptions }) => {\n const { pdfDoc, options } = props;\n const {\n author = TOOL_NAME,\n creationDate = new Date(),\n creator = TOOL_NAME,\n keywords = [],\n lang = 'en',\n modificationDate = new Date(),\n producer = TOOL_NAME,\n subject = '',\n title = '',\n } = options;\n pdfDoc.setAuthor(author);\n pdfDoc.setCreationDate(creationDate);\n pdfDoc.setCreator(creator);\n pdfDoc.setKeywords(keywords);\n pdfDoc.setLanguage(lang);\n pdfDoc.setModificationDate(modificationDate);\n pdfDoc.setProducer(producer);\n pdfDoc.setSubject(subject);\n pdfDoc.setTitle(title);\n};\n\nexport const insertPage = (arg: {\n basePage: PDFEmbeddedPage | PDFPage;\n embedPdfBox: EmbedPdfBox;\n pdfDoc: PDFDocument;\n}) => {\n const { basePage, embedPdfBox, pdfDoc } = arg;\n const size = basePage instanceof PDFEmbeddedPage ? basePage.size() : basePage.getSize();\n const insertedPage =\n basePage instanceof PDFEmbeddedPage\n ? pdfDoc.addPage([size.width, size.height])\n : pdfDoc.addPage(basePage);\n\n if (basePage instanceof PDFEmbeddedPage) {\n insertedPage.drawPage(basePage);\n const { mediaBox, bleedBox, trimBox } = embedPdfBox;\n insertedPage.setMediaBox(mediaBox.x, mediaBox.y, mediaBox.width, mediaBox.height);\n insertedPage.setBleedBox(bleedBox.x, bleedBox.y, bleedBox.width, bleedBox.height);\n insertedPage.setTrimBox(trimBox.x, trimBox.y, trimBox.width, trimBox.height);\n }\n\n return insertedPage;\n};\n","import * as pdfLib from '@pdfme/pdf-lib';\nimport type { GenerateProps, Schema, PDFRenderProps, Template } from '@pdfme/common';\nimport {\n checkGenerateProps,\n getDynamicTemplate,\n isBlankPdf,\n replacePlaceholders,\n pt2mm,\n cloneDeep,\n} from '@pdfme/common';\nimport { getDynamicHeightsForTable } from '@pdfme/schemas/tables';\nimport {\n insertPage,\n preprocessing,\n postProcessing,\n getEmbedPdfPages,\n validateRequiredFields,\n} from './helper.js';\n\nconst generate = async (props: GenerateProps): Promise<Uint8Array<ArrayBuffer>> => {\n checkGenerateProps(props);\n const { inputs, template: _template, options = {}, plugins: userPlugins = {} } = props;\n const template = cloneDeep(_template);\n\n const basePdf = template.basePdf;\n\n if (inputs.length === 0) {\n throw new Error(\n '[@pdfme/generator] inputs should not be empty, pass at least an empty object in the array',\n );\n }\n\n validateRequiredFields(template, inputs);\n\n const { pdfDoc, renderObj } = await preprocessing({ template, userPlugins });\n\n const _cache = new Map<string, unknown>();\n\n for (let i = 0; i < inputs.length; i += 1) {\n const input = inputs[i];\n\n // Get the dynamic template with proper typing\n const dynamicTemplate: Template = await getDynamicTemplate({\n template,\n input,\n options,\n _cache,\n getDynamicHeights: (value, args) => {\n switch (args.schema.type) {\n case 'table':\n return getDynamicHeightsForTable(value, args);\n default:\n return Promise.resolve([args.schema.height]);\n }\n },\n });\n const { basePages, embedPdfBoxes } = await getEmbedPdfPages({\n template: dynamicTemplate,\n pdfDoc,\n });\n\n const schemas = dynamicTemplate.schemas;\n // Create a type-safe array of schema names without using Set spread which requires downlevelIteration\n const schemaNameSet = new Set<string>();\n schemas.forEach((page: Schema[]) => {\n page.forEach((schema: Schema) => {\n if (schema.name) {\n schemaNameSet.add(schema.name);\n }\n });\n });\n const schemaNames = Array.from(schemaNameSet);\n\n for (let j = 0; j < basePages.length; j += 1) {\n const basePage = basePages[j];\n const embedPdfBox = embedPdfBoxes[j];\n\n const boundingBoxLeft =\n basePage instanceof pdfLib.PDFEmbeddedPage ? pt2mm(embedPdfBox.mediaBox.x) : 0;\n const boundingBoxBottom =\n basePage instanceof pdfLib.PDFEmbeddedPage ? pt2mm(embedPdfBox.mediaBox.y) : 0;\n\n const page = insertPage({ basePage, embedPdfBox, pdfDoc });\n\n if (isBlankPdf(basePdf) && basePdf.staticSchema) {\n for (let k = 0; k < basePdf.staticSchema.length; k += 1) {\n const staticSchema = basePdf.staticSchema[k];\n const render = renderObj[staticSchema.type];\n if (!render) {\n continue;\n }\n const value = staticSchema.readOnly\n ? replacePlaceholders({\n content: staticSchema.content || '',\n variables: { ...input, totalPages: basePages.length, currentPage: j + 1 },\n schemas: schemas, // Use the properly typed schemas variable\n })\n : staticSchema.content || '';\n\n staticSchema.position = {\n x: staticSchema.position.x + boundingBoxLeft,\n y: staticSchema.position.y - boundingBoxBottom,\n };\n\n // Create properly typed render props for static schema\n const staticRenderProps: PDFRenderProps<Schema> = {\n value,\n schema: staticSchema,\n basePdf,\n pdfLib,\n pdfDoc,\n page,\n options,\n _cache,\n };\n await render(staticRenderProps);\n }\n }\n\n for (let l = 0; l < schemaNames.length; l += 1) {\n const name = schemaNames[l];\n const schemaPage = schemas[j] || [];\n const schema = schemaPage.find((s: Schema) => s.name == name);\n if (!schema) {\n continue;\n }\n\n const render = renderObj[schema.type];\n if (!render) {\n continue;\n }\n const value: string = schema.readOnly\n ? replacePlaceholders({\n content: schema.content || '',\n variables: { ...input, totalPages: basePages.length, currentPage: j + 1 },\n schemas: schemas, // Use the properly typed schemas variable\n })\n : ((input[name] || '') as string);\n\n schema.position = {\n x: schema.position.x + boundingBoxLeft,\n y: schema.position.y - boundingBoxBottom,\n };\n\n // Create properly typed render props\n const renderProps: PDFRenderProps<Schema> = {\n value,\n schema,\n basePdf,\n pdfLib,\n pdfDoc,\n page,\n options,\n _cache,\n };\n await render(renderProps);\n }\n }\n }\n\n postProcessing({ pdfDoc, options });\n\n return pdfDoc.save();\n};\n\nexport default generate;\n"],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type EmbedPdfBox = {
|
|
2
|
+
mediaBox: {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
};
|
|
8
|
+
bleedBox: {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
};
|
|
14
|
+
trimBox: {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pdfme/generator",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.4-dev.1",
|
|
4
4
|
"description": "TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pdf",
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
},
|
|
23
23
|
"type": "module",
|
|
24
24
|
"sideEffects": false,
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
25
29
|
"main": "./dist/index.js",
|
|
26
30
|
"module": "./dist/index.js",
|
|
27
31
|
"types": "./dist/index.d.ts",
|
package/.vscode/settings.json
DELETED
package/src/constants.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const TOOL_NAME = 'pdfme (https://pdfme.com/)';
|
package/src/generate.ts
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import * as pdfLib from '@pdfme/pdf-lib';
|
|
2
|
-
import type { GenerateProps, Schema, PDFRenderProps, Template } from '@pdfme/common';
|
|
3
|
-
import {
|
|
4
|
-
checkGenerateProps,
|
|
5
|
-
getDynamicTemplate,
|
|
6
|
-
isBlankPdf,
|
|
7
|
-
replacePlaceholders,
|
|
8
|
-
pt2mm,
|
|
9
|
-
cloneDeep,
|
|
10
|
-
} from '@pdfme/common';
|
|
11
|
-
import { getDynamicHeightsForTable } from '@pdfme/schemas/tables';
|
|
12
|
-
import {
|
|
13
|
-
insertPage,
|
|
14
|
-
preprocessing,
|
|
15
|
-
postProcessing,
|
|
16
|
-
getEmbedPdfPages,
|
|
17
|
-
validateRequiredFields,
|
|
18
|
-
} from './helper.js';
|
|
19
|
-
|
|
20
|
-
const generate = async (props: GenerateProps): Promise<Uint8Array<ArrayBuffer>> => {
|
|
21
|
-
checkGenerateProps(props);
|
|
22
|
-
const { inputs, template: _template, options = {}, plugins: userPlugins = {} } = props;
|
|
23
|
-
const template = cloneDeep(_template);
|
|
24
|
-
|
|
25
|
-
const basePdf = template.basePdf;
|
|
26
|
-
|
|
27
|
-
if (inputs.length === 0) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
'[@pdfme/generator] inputs should not be empty, pass at least an empty object in the array',
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
validateRequiredFields(template, inputs);
|
|
34
|
-
|
|
35
|
-
const { pdfDoc, renderObj } = await preprocessing({ template, userPlugins });
|
|
36
|
-
|
|
37
|
-
const _cache = new Map<string, unknown>();
|
|
38
|
-
|
|
39
|
-
for (let i = 0; i < inputs.length; i += 1) {
|
|
40
|
-
const input = inputs[i];
|
|
41
|
-
|
|
42
|
-
// Get the dynamic template with proper typing
|
|
43
|
-
const dynamicTemplate: Template = await getDynamicTemplate({
|
|
44
|
-
template,
|
|
45
|
-
input,
|
|
46
|
-
options,
|
|
47
|
-
_cache,
|
|
48
|
-
getDynamicHeights: (value, args) => {
|
|
49
|
-
switch (args.schema.type) {
|
|
50
|
-
case 'table':
|
|
51
|
-
return getDynamicHeightsForTable(value, args);
|
|
52
|
-
default:
|
|
53
|
-
return Promise.resolve([args.schema.height]);
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
const { basePages, embedPdfBoxes } = await getEmbedPdfPages({
|
|
58
|
-
template: dynamicTemplate,
|
|
59
|
-
pdfDoc,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const schemas = dynamicTemplate.schemas;
|
|
63
|
-
// Create a type-safe array of schema names without using Set spread which requires downlevelIteration
|
|
64
|
-
const schemaNameSet = new Set<string>();
|
|
65
|
-
schemas.forEach((page: Schema[]) => {
|
|
66
|
-
page.forEach((schema: Schema) => {
|
|
67
|
-
if (schema.name) {
|
|
68
|
-
schemaNameSet.add(schema.name);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
const schemaNames = Array.from(schemaNameSet);
|
|
73
|
-
|
|
74
|
-
for (let j = 0; j < basePages.length; j += 1) {
|
|
75
|
-
const basePage = basePages[j];
|
|
76
|
-
const embedPdfBox = embedPdfBoxes[j];
|
|
77
|
-
|
|
78
|
-
const boundingBoxLeft =
|
|
79
|
-
basePage instanceof pdfLib.PDFEmbeddedPage ? pt2mm(embedPdfBox.mediaBox.x) : 0;
|
|
80
|
-
const boundingBoxBottom =
|
|
81
|
-
basePage instanceof pdfLib.PDFEmbeddedPage ? pt2mm(embedPdfBox.mediaBox.y) : 0;
|
|
82
|
-
|
|
83
|
-
const page = insertPage({ basePage, embedPdfBox, pdfDoc });
|
|
84
|
-
|
|
85
|
-
if (isBlankPdf(basePdf) && basePdf.staticSchema) {
|
|
86
|
-
for (let k = 0; k < basePdf.staticSchema.length; k += 1) {
|
|
87
|
-
const staticSchema = basePdf.staticSchema[k];
|
|
88
|
-
const render = renderObj[staticSchema.type];
|
|
89
|
-
if (!render) {
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
const value = staticSchema.readOnly
|
|
93
|
-
? replacePlaceholders({
|
|
94
|
-
content: staticSchema.content || '',
|
|
95
|
-
variables: { ...input, totalPages: basePages.length, currentPage: j + 1 },
|
|
96
|
-
schemas: schemas, // Use the properly typed schemas variable
|
|
97
|
-
})
|
|
98
|
-
: staticSchema.content || '';
|
|
99
|
-
|
|
100
|
-
staticSchema.position = {
|
|
101
|
-
x: staticSchema.position.x + boundingBoxLeft,
|
|
102
|
-
y: staticSchema.position.y - boundingBoxBottom,
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// Create properly typed render props for static schema
|
|
106
|
-
const staticRenderProps: PDFRenderProps<Schema> = {
|
|
107
|
-
value,
|
|
108
|
-
schema: staticSchema,
|
|
109
|
-
basePdf,
|
|
110
|
-
pdfLib,
|
|
111
|
-
pdfDoc,
|
|
112
|
-
page,
|
|
113
|
-
options,
|
|
114
|
-
_cache,
|
|
115
|
-
};
|
|
116
|
-
await render(staticRenderProps);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
for (let l = 0; l < schemaNames.length; l += 1) {
|
|
121
|
-
const name = schemaNames[l];
|
|
122
|
-
const schemaPage = schemas[j] || [];
|
|
123
|
-
const schema = schemaPage.find((s: Schema) => s.name == name);
|
|
124
|
-
if (!schema) {
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const render = renderObj[schema.type];
|
|
129
|
-
if (!render) {
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
const value: string = schema.readOnly
|
|
133
|
-
? replacePlaceholders({
|
|
134
|
-
content: schema.content || '',
|
|
135
|
-
variables: { ...input, totalPages: basePages.length, currentPage: j + 1 },
|
|
136
|
-
schemas: schemas, // Use the properly typed schemas variable
|
|
137
|
-
})
|
|
138
|
-
: ((input[name] || '') as string);
|
|
139
|
-
|
|
140
|
-
schema.position = {
|
|
141
|
-
x: schema.position.x + boundingBoxLeft,
|
|
142
|
-
y: schema.position.y - boundingBoxBottom,
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
// Create properly typed render props
|
|
146
|
-
const renderProps: PDFRenderProps<Schema> = {
|
|
147
|
-
value,
|
|
148
|
-
schema,
|
|
149
|
-
basePdf,
|
|
150
|
-
pdfLib,
|
|
151
|
-
pdfDoc,
|
|
152
|
-
page,
|
|
153
|
-
options,
|
|
154
|
-
_cache,
|
|
155
|
-
};
|
|
156
|
-
await render(renderProps);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
postProcessing({ pdfDoc, options });
|
|
162
|
-
|
|
163
|
-
return pdfDoc.save();
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
export default generate;
|
package/src/helper.ts
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import * as fontkit from 'fontkit';
|
|
2
|
-
import {
|
|
3
|
-
Schema,
|
|
4
|
-
Plugins,
|
|
5
|
-
GeneratorOptions,
|
|
6
|
-
Template,
|
|
7
|
-
PDFRenderProps,
|
|
8
|
-
getB64BasePdf,
|
|
9
|
-
isBlankPdf,
|
|
10
|
-
mm2pt,
|
|
11
|
-
pluginRegistry,
|
|
12
|
-
BasePdf,
|
|
13
|
-
} from '@pdfme/common';
|
|
14
|
-
import { builtInPlugins } from '@pdfme/schemas/builtins';
|
|
15
|
-
import { PDFPage, PDFDocument, PDFEmbeddedPage, TransformationMatrix } from '@pdfme/pdf-lib';
|
|
16
|
-
import { TOOL_NAME } from './constants.js';
|
|
17
|
-
import type { EmbedPdfBox } from './types.js';
|
|
18
|
-
|
|
19
|
-
export const getEmbedPdfPages = async (arg: { template: Template; pdfDoc: PDFDocument }) => {
|
|
20
|
-
const {
|
|
21
|
-
template: { schemas, basePdf },
|
|
22
|
-
pdfDoc,
|
|
23
|
-
} = arg as { template: { schemas: Schema[][]; basePdf: BasePdf }; pdfDoc: PDFDocument };
|
|
24
|
-
let basePages: (PDFEmbeddedPage | PDFPage)[] = [];
|
|
25
|
-
let embedPdfBoxes: EmbedPdfBox[] = [];
|
|
26
|
-
|
|
27
|
-
if (isBlankPdf(basePdf)) {
|
|
28
|
-
const { width: _width, height: _height } = basePdf;
|
|
29
|
-
const width = mm2pt(_width);
|
|
30
|
-
const height = mm2pt(_height);
|
|
31
|
-
basePages = schemas.map(() => {
|
|
32
|
-
const page = PDFPage.create(pdfDoc);
|
|
33
|
-
page.setSize(width, height);
|
|
34
|
-
return page;
|
|
35
|
-
});
|
|
36
|
-
embedPdfBoxes = schemas.map(() => ({
|
|
37
|
-
mediaBox: { x: 0, y: 0, width, height },
|
|
38
|
-
bleedBox: { x: 0, y: 0, width, height },
|
|
39
|
-
trimBox: { x: 0, y: 0, width, height },
|
|
40
|
-
}));
|
|
41
|
-
} else {
|
|
42
|
-
const willLoadPdf = await getB64BasePdf(basePdf);
|
|
43
|
-
const embedPdf = await PDFDocument.load(willLoadPdf);
|
|
44
|
-
const embedPdfPages = embedPdf.getPages();
|
|
45
|
-
embedPdfBoxes = embedPdfPages.map((p) => ({
|
|
46
|
-
mediaBox: p.getMediaBox(),
|
|
47
|
-
bleedBox: p.getBleedBox(),
|
|
48
|
-
trimBox: p.getTrimBox(),
|
|
49
|
-
}));
|
|
50
|
-
const boundingBoxes = embedPdfPages.map((p) => {
|
|
51
|
-
const { x, y, width, height } = p.getMediaBox();
|
|
52
|
-
return { left: x, bottom: y, right: width, top: height + y };
|
|
53
|
-
});
|
|
54
|
-
const transformationMatrices = embedPdfPages.map(
|
|
55
|
-
() => [1, 0, 0, 1, 0, 0] as TransformationMatrix,
|
|
56
|
-
);
|
|
57
|
-
basePages = await pdfDoc.embedPages(embedPdfPages, boundingBoxes, transformationMatrices);
|
|
58
|
-
}
|
|
59
|
-
return { basePages, embedPdfBoxes };
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export const validateRequiredFields = (template: Template, inputs: Record<string, unknown>[]) => {
|
|
63
|
-
template.schemas.forEach((schemaPage: Schema[]) =>
|
|
64
|
-
schemaPage.forEach((schema: Schema) => {
|
|
65
|
-
if (schema.required && !schema.readOnly && !inputs.some((input) => input[schema.name])) {
|
|
66
|
-
throw new Error(
|
|
67
|
-
`[@pdfme/generator] input for '${schema.name}' is required to generate this PDF`,
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
}),
|
|
71
|
-
);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export const preprocessing = async (arg: { template: Template; userPlugins: Plugins }) => {
|
|
75
|
-
const { template, userPlugins } = arg;
|
|
76
|
-
const { schemas, basePdf } = template as { schemas: Schema[][]; basePdf: BasePdf };
|
|
77
|
-
const staticSchema: Schema[] = isBlankPdf(basePdf) ? (basePdf.staticSchema ?? []) : [];
|
|
78
|
-
|
|
79
|
-
const pdfDoc = await PDFDocument.create();
|
|
80
|
-
// @ts-expect-error registerFontkit method is not in type definitions but exists at runtime
|
|
81
|
-
pdfDoc.registerFontkit(fontkit);
|
|
82
|
-
|
|
83
|
-
const plugins = pluginRegistry(
|
|
84
|
-
Object.values(userPlugins).length > 0 ? userPlugins : builtInPlugins,
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
const schemaTypes = Array.from(
|
|
88
|
-
new Set(
|
|
89
|
-
schemas
|
|
90
|
-
.flatMap((schemaPage: Schema[]) => schemaPage.map((schema: Schema) => schema.type))
|
|
91
|
-
.concat(staticSchema.map((schema: Schema) => schema.type)),
|
|
92
|
-
),
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const renderObj = schemaTypes.reduce(
|
|
96
|
-
(
|
|
97
|
-
acc: Record<
|
|
98
|
-
string,
|
|
99
|
-
(arg: PDFRenderProps<Schema & { [key: string]: unknown }>) => Promise<void> | void
|
|
100
|
-
>,
|
|
101
|
-
type: string,
|
|
102
|
-
) => {
|
|
103
|
-
const plugin = plugins.findByType(type);
|
|
104
|
-
|
|
105
|
-
if (!plugin || !plugin.pdf) {
|
|
106
|
-
throw new Error(`[@pdfme/generator] Plugin or renderer for type ${type} not found.
|
|
107
|
-
Check this document: https://pdfme.com/docs/custom-schemas`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Use type assertion to handle the pdf function with schema type
|
|
111
|
-
return {
|
|
112
|
-
...acc,
|
|
113
|
-
[type]: plugin.pdf as (
|
|
114
|
-
arg: PDFRenderProps<Schema & { [key: string]: unknown }>,
|
|
115
|
-
) => Promise<void> | void,
|
|
116
|
-
};
|
|
117
|
-
},
|
|
118
|
-
{} as Record<
|
|
119
|
-
string,
|
|
120
|
-
(arg: PDFRenderProps<Schema & { [key: string]: unknown }>) => Promise<void> | void
|
|
121
|
-
>,
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
return { pdfDoc, renderObj };
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export const postProcessing = (props: { pdfDoc: PDFDocument; options: GeneratorOptions }) => {
|
|
128
|
-
const { pdfDoc, options } = props;
|
|
129
|
-
const {
|
|
130
|
-
author = TOOL_NAME,
|
|
131
|
-
creationDate = new Date(),
|
|
132
|
-
creator = TOOL_NAME,
|
|
133
|
-
keywords = [],
|
|
134
|
-
lang = 'en',
|
|
135
|
-
modificationDate = new Date(),
|
|
136
|
-
producer = TOOL_NAME,
|
|
137
|
-
subject = '',
|
|
138
|
-
title = '',
|
|
139
|
-
} = options;
|
|
140
|
-
pdfDoc.setAuthor(author);
|
|
141
|
-
pdfDoc.setCreationDate(creationDate);
|
|
142
|
-
pdfDoc.setCreator(creator);
|
|
143
|
-
pdfDoc.setKeywords(keywords);
|
|
144
|
-
pdfDoc.setLanguage(lang);
|
|
145
|
-
pdfDoc.setModificationDate(modificationDate);
|
|
146
|
-
pdfDoc.setProducer(producer);
|
|
147
|
-
pdfDoc.setSubject(subject);
|
|
148
|
-
pdfDoc.setTitle(title);
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
export const insertPage = (arg: {
|
|
152
|
-
basePage: PDFEmbeddedPage | PDFPage;
|
|
153
|
-
embedPdfBox: EmbedPdfBox;
|
|
154
|
-
pdfDoc: PDFDocument;
|
|
155
|
-
}) => {
|
|
156
|
-
const { basePage, embedPdfBox, pdfDoc } = arg;
|
|
157
|
-
const size = basePage instanceof PDFEmbeddedPage ? basePage.size() : basePage.getSize();
|
|
158
|
-
const insertedPage =
|
|
159
|
-
basePage instanceof PDFEmbeddedPage
|
|
160
|
-
? pdfDoc.addPage([size.width, size.height])
|
|
161
|
-
: pdfDoc.addPage(basePage);
|
|
162
|
-
|
|
163
|
-
if (basePage instanceof PDFEmbeddedPage) {
|
|
164
|
-
insertedPage.drawPage(basePage);
|
|
165
|
-
const { mediaBox, bleedBox, trimBox } = embedPdfBox;
|
|
166
|
-
insertedPage.setMediaBox(mediaBox.x, mediaBox.y, mediaBox.width, mediaBox.height);
|
|
167
|
-
insertedPage.setBleedBox(bleedBox.x, bleedBox.y, bleedBox.width, bleedBox.height);
|
|
168
|
-
insertedPage.setTrimBox(trimBox.x, trimBox.y, trimBox.width, trimBox.height);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return insertedPage;
|
|
172
|
-
};
|
package/src/types.ts
DELETED
package/tsconfig.build.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../tsconfig.build.base.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"declaration": true,
|
|
5
|
-
"declarationDir": "./dist",
|
|
6
|
-
"emitDeclarationOnly": true,
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"moduleResolution": "bundler",
|
|
9
|
-
"outDir": "./dist",
|
|
10
|
-
"rootDir": "./src",
|
|
11
|
-
"skipLibCheck": true
|
|
12
|
-
},
|
|
13
|
-
"include": ["src/**/*.ts"]
|
|
14
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../tsconfig.base.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"composite": true,
|
|
5
|
-
"declaration": true,
|
|
6
|
-
"declarationDir": "./dist/typecheck",
|
|
7
|
-
"emitDeclarationOnly": true,
|
|
8
|
-
"module": "ESNext",
|
|
9
|
-
"moduleResolution": "bundler",
|
|
10
|
-
"outDir": "./dist/typecheck",
|
|
11
|
-
"tsBuildInfoFile": "./dist/typecheck/tsconfig.tsbuildinfo",
|
|
12
|
-
"skipLibCheck": true
|
|
13
|
-
},
|
|
14
|
-
"include": ["src/**/*.ts"],
|
|
15
|
-
"references": [{ "path": "../common" }, { "path": "../pdf-lib" }, { "path": "../schemas" }]
|
|
16
|
-
}
|
package/vite.config.mts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { builtinModules } from 'node:module';
|
|
3
|
-
import { dirname, resolve } from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { defineConfig } from 'vite';
|
|
6
|
-
|
|
7
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const packageJson = JSON.parse(readFileSync(resolve(__dirname, 'package.json'), 'utf8')) as {
|
|
9
|
-
dependencies?: Record<string, string>;
|
|
10
|
-
peerDependencies?: Record<string, string>;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const builtinModuleSet = new Set([
|
|
14
|
-
...builtinModules,
|
|
15
|
-
...builtinModules.map((moduleName) => `node:${moduleName}`),
|
|
16
|
-
]);
|
|
17
|
-
const packageDependencies = [
|
|
18
|
-
...Object.keys(packageJson.dependencies ?? {}),
|
|
19
|
-
...Object.keys(packageJson.peerDependencies ?? {}),
|
|
20
|
-
];
|
|
21
|
-
|
|
22
|
-
const isExternal = (id: string) =>
|
|
23
|
-
builtinModuleSet.has(id) ||
|
|
24
|
-
packageDependencies.some((dependency) => id === dependency || id.startsWith(`${dependency}/`));
|
|
25
|
-
|
|
26
|
-
export default defineConfig({
|
|
27
|
-
build: {
|
|
28
|
-
lib: {
|
|
29
|
-
entry: resolve(__dirname, 'src/index.ts'),
|
|
30
|
-
fileName: 'index',
|
|
31
|
-
formats: ['es'],
|
|
32
|
-
},
|
|
33
|
-
minify: false,
|
|
34
|
-
outDir: 'dist',
|
|
35
|
-
rollupOptions: { external: isExternal },
|
|
36
|
-
sourcemap: true,
|
|
37
|
-
target: 'es2020',
|
|
38
|
-
},
|
|
39
|
-
});
|
package/vitest.setup.ts
DELETED