@sme.up/doc-alchemist 1.5.0-SNAPSHOT-20251017143656 → 1.5.0-SNAPSHOT-20251121152517
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/README.md +39 -48
- package/dist/converters/pdf/form-filler.d.ts +24 -0
- package/dist/converters/pdf/form-filler.js +187 -0
- package/dist/converters/pdf/form-filler.js.map +1 -0
- package/dist/converters/pdf/pdfmake/adapter-processor.d.ts +11 -0
- package/dist/converters/pdf/pdfmake/adapter-processor.js +95 -0
- package/dist/converters/pdf/pdfmake/adapter-processor.js.map +1 -0
- package/dist/converters/pdf/pdfmake/adapter-registry.d.ts +22 -0
- package/dist/converters/pdf/pdfmake/adapter-registry.js +46 -0
- package/dist/converters/pdf/pdfmake/adapter-registry.js.map +1 -0
- package/dist/converters/pdf/pdfmake/pdfmake.types.d.ts +35 -0
- package/dist/converters/pdf/pdfmake/pdfmake.types.js +13 -0
- package/dist/converters/pdf/pdfmake/pdfmake.types.js.map +1 -0
- package/dist/converters/pdf/pdfmake/table-adapter.d.ts +31 -0
- package/dist/converters/pdf/pdfmake/table-adapter.js +118 -0
- package/dist/converters/pdf/pdfmake/table-adapter.js.map +1 -0
- package/dist/converters/pdf/pdfmake-renderer.d.ts +21 -0
- package/dist/converters/pdf/pdfmake-renderer.js +87 -0
- package/dist/converters/pdf/pdfmake-renderer.js.map +1 -0
- package/dist/converters/pdf-converter.d.ts +5 -0
- package/dist/converters/pdf-converter.js +18 -1
- package/dist/converters/pdf-converter.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ A comprehensive TypeScript library for generating documents from SmeupDataTable
|
|
|
9
9
|
- **Chart Generation**: Create interactive charts (bar, line, pie, scatter) from data tables
|
|
10
10
|
- **Data Table Support**: Convert SmeupDataTable structures to multiple formats
|
|
11
11
|
- **Data Tree Support**: Convert SmeupDataTree structures with hierarchical representation
|
|
12
|
-
- **
|
|
12
|
+
- **PdfMake Rendering**: Render `pdfmake` document definitions to PDF including adapter support for SmeUP table formats and FUN-based table resolution (see `pdfmakeDocumentToPdfData`).
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
dataTableToExcelData,
|
|
25
25
|
dataTreeToExcelData,
|
|
26
26
|
dataTableToPdfData,
|
|
27
|
-
schedaToPdfData,
|
|
28
27
|
dataTableToChart,
|
|
29
28
|
} from "@sme.up/doc-alchemist";
|
|
30
29
|
import { SupportedExportFormats } from "@sme.up/doc-alchemist";
|
|
@@ -166,16 +165,45 @@ Converts SmeupDataTable to PDF binary data with professional formatting.
|
|
|
166
165
|
|
|
167
166
|
**Returns:** `Promise<Buffer | Uint8Array>`
|
|
168
167
|
|
|
169
|
-
#### `
|
|
168
|
+
#### `pdfmakeDocumentToPdfData(document, context)`
|
|
170
169
|
|
|
171
|
-
|
|
170
|
+
Renders a `pdfmake` document definition into PDF binary data. This function extends the standard `pdfmake` workflow by supporting:
|
|
171
|
+
|
|
172
|
+
- native `pdfmake` document definitions (tables, columns, text, etc.);
|
|
173
|
+
- SmeUP structured tables (when a `table.data` object uses `SmeupDataTable`/`SmeupDataTree` formats) via the adapter chain;
|
|
174
|
+
- FUN-based table definitions: a `table` node can specify a `fun` string which is resolved by the optional `getSmeupDataStructure` callback in the converter context.
|
|
172
175
|
|
|
173
176
|
**Parameters:**
|
|
174
177
|
|
|
175
|
-
- `
|
|
176
|
-
- `
|
|
178
|
+
- `document`: A `pdfmake`-style document definition object. Table entries may be plain `pdfmake` tables, or adapter-aware objects with `table.data` (Smeup format) or `table.fun` (FUN string).
|
|
179
|
+
- `context` (optional): Partial `PdfMakeConverterContext` including:
|
|
180
|
+
- `webupManagerData`: formatting/localization options (see `WebupManagerData`);
|
|
181
|
+
- `getSmeupDataStructure(fun: string)`: async function used to resolve FUN strings into Smeup data structures when `table.fun` is present.
|
|
182
|
+
|
|
183
|
+
**Returns:** `Promise<Buffer>` — PDF binary data ready to be written to disk.
|
|
184
|
+
|
|
185
|
+
**Example (based on `debug-pdfmake.ts`):**
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { pdfmakeDocumentToPdfData, WebupManagerData } from "./src/index";
|
|
189
|
+
|
|
190
|
+
const webupManagerData: WebupManagerData = { mathLocale: "it-IT", datesLocale: "it-IT" };
|
|
177
191
|
|
|
178
|
-
|
|
192
|
+
// native pdfmake doc
|
|
193
|
+
const tableDoc = { content: [ { text: "Data", fontSize: 20 }, { table: { headerRows: 1, body: [["A","B"],["1","2"]] } } ] };
|
|
194
|
+
const pdf1 = await pdfmakeDocumentToPdfData(tableDoc, { webupManagerData });
|
|
195
|
+
|
|
196
|
+
// smeup table (adapter will convert to pdfmake table)
|
|
197
|
+
const smeupDoc = { content: [ { table: { data: { type: "SmeupDataTable", columns: [...], rows: [...] } } } ] };
|
|
198
|
+
const pdf2 = await pdfmakeDocumentToPdfData(smeupDoc, { webupManagerData });
|
|
199
|
+
|
|
200
|
+
// FUN-based table (adapter will call getSmeupDataStructure to fetch data)
|
|
201
|
+
const funDoc = { content: [ { table: { fun: "F(EXB;SERV;MET)" } } ] };
|
|
202
|
+
const pdf3 = await pdfmakeDocumentToPdfData(funDoc, {
|
|
203
|
+
webupManagerData,
|
|
204
|
+
getSmeupDataStructure: async (fun) => { /* resolve and return SmeupDataTable */ },
|
|
205
|
+
});
|
|
206
|
+
```
|
|
179
207
|
|
|
180
208
|
#### `dataTableToChart(dataTable, chartType, chartOptions)`
|
|
181
209
|
|
|
@@ -260,8 +288,9 @@ npm start
|
|
|
260
288
|
|
|
261
289
|
# Run specific debug examples
|
|
262
290
|
npx tsx debug-charts.ts # Generate chart examples
|
|
263
|
-
npx tsx debug-pdf.ts # Generate PDF examples
|
|
264
|
-
npx tsx debug-
|
|
291
|
+
npx tsx debug-pdf.ts # Generate PDF examples of matrix
|
|
292
|
+
npx tsx debug-pdfmake.ts # Generate PDF examples by using pdfmake
|
|
293
|
+
|
|
265
294
|
|
|
266
295
|
# Output files will be saved to ./output/ directory
|
|
267
296
|
```
|
|
@@ -382,45 +411,6 @@ const barChart = await dataTableToChart(dataTable, "bar", {
|
|
|
382
411
|
});
|
|
383
412
|
```
|
|
384
413
|
|
|
385
|
-
### Scheda PDF with Multiple Charts
|
|
386
|
-
|
|
387
|
-
```typescript
|
|
388
|
-
import { schedaToPdfData } from "@sme.up/doc-alchemist";
|
|
389
|
-
|
|
390
|
-
const scheda = {
|
|
391
|
-
layout: "column",
|
|
392
|
-
sections: [
|
|
393
|
-
{
|
|
394
|
-
layout: "row",
|
|
395
|
-
dim: "50",
|
|
396
|
-
components: [
|
|
397
|
-
{
|
|
398
|
-
type: "EXA",
|
|
399
|
-
title: "Sales Trend",
|
|
400
|
-
data: salesDataTable,
|
|
401
|
-
options: {
|
|
402
|
-
EXA: [
|
|
403
|
-
{
|
|
404
|
-
Width: "800",
|
|
405
|
-
Height: "400",
|
|
406
|
-
Series: "SALES",
|
|
407
|
-
},
|
|
408
|
-
],
|
|
409
|
-
},
|
|
410
|
-
},
|
|
411
|
-
],
|
|
412
|
-
},
|
|
413
|
-
// Additional sections...
|
|
414
|
-
],
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
const schedaPdfBuffer = await schedaToPdfData(scheda, {
|
|
418
|
-
mathLocale: "it-IT",
|
|
419
|
-
datesLocale: "it-IT",
|
|
420
|
-
themeBackground: "",
|
|
421
|
-
});
|
|
422
|
-
```
|
|
423
|
-
|
|
424
414
|
## Dependencies
|
|
425
415
|
|
|
426
416
|
This library includes the following key dependencies:
|
|
@@ -431,6 +421,7 @@ This library includes the following key dependencies:
|
|
|
431
421
|
- **ECharts**: For chart generation
|
|
432
422
|
- **Canvas**: For server-side image rendering
|
|
433
423
|
- **PDF-lib**: For PDF manipulation and merging
|
|
424
|
+
- **pdfmake**: For rendering `pdfmake` document definitions to PDF
|
|
434
425
|
|
|
435
426
|
## Browser vs Node.js Support
|
|
436
427
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for PDF form filling
|
|
3
|
+
*/
|
|
4
|
+
export interface FillPdfFormOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Font size to use for text fields (default: 10)
|
|
7
|
+
* Smaller values help prevent text truncation
|
|
8
|
+
*/
|
|
9
|
+
fontSize?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Whether to flatten the form after filling (default: true)
|
|
12
|
+
* When true, form fields become non-editable
|
|
13
|
+
*/
|
|
14
|
+
flatten?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Fills PDF form fields with provided data and flattens the form
|
|
18
|
+
* @param pdfBuffer - PDF file buffer containing form fields
|
|
19
|
+
* @param formData - Key-value pairs where keys match PDF field names
|
|
20
|
+
* @param options - Optional configuration for form filling
|
|
21
|
+
* @returns Modified PDF buffer with filled and flattened form fields
|
|
22
|
+
* @throws Error if PDF buffer is invalid or cannot be processed
|
|
23
|
+
*/
|
|
24
|
+
export declare function fillPdfForm(pdfBuffer: Buffer, formData: Record<string, string | number | boolean>, options?: FillPdfFormOptions): Promise<Buffer>;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fillPdfForm = fillPdfForm;
|
|
4
|
+
const pdf_lib_1 = require("pdf-lib");
|
|
5
|
+
/**
|
|
6
|
+
* Fills PDF form fields with provided data and flattens the form
|
|
7
|
+
* @param pdfBuffer - PDF file buffer containing form fields
|
|
8
|
+
* @param formData - Key-value pairs where keys match PDF field names
|
|
9
|
+
* @param options - Optional configuration for form filling
|
|
10
|
+
* @returns Modified PDF buffer with filled and flattened form fields
|
|
11
|
+
* @throws Error if PDF buffer is invalid or cannot be processed
|
|
12
|
+
*/
|
|
13
|
+
async function fillPdfForm(pdfBuffer, formData, options) {
|
|
14
|
+
// Set default options
|
|
15
|
+
const fontSize = options?.fontSize ?? 10;
|
|
16
|
+
const flatten = options?.flatten ?? true;
|
|
17
|
+
// Validate input
|
|
18
|
+
if (!pdfBuffer || pdfBuffer.length === 0) {
|
|
19
|
+
throw new Error("Invalid PDF buffer: buffer is empty or undefined");
|
|
20
|
+
}
|
|
21
|
+
if (!formData || typeof formData !== "object") {
|
|
22
|
+
throw new Error("Invalid form data: must be a non-null object");
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
// Load the PDF document
|
|
26
|
+
const pdfDoc = await pdf_lib_1.PDFDocument.load(pdfBuffer);
|
|
27
|
+
// Get the form from the PDF
|
|
28
|
+
const form = pdfDoc.getForm();
|
|
29
|
+
// Get all fields in the form
|
|
30
|
+
const fields = form.getFields();
|
|
31
|
+
// Create a map of field names to fields for quick lookup
|
|
32
|
+
const fieldMap = new Map();
|
|
33
|
+
fields.forEach(field => {
|
|
34
|
+
const fieldName = field.getName();
|
|
35
|
+
fieldMap.set(fieldName, field);
|
|
36
|
+
});
|
|
37
|
+
// Process each entry in the form data
|
|
38
|
+
for (const [fieldName, fieldValue] of Object.entries(formData)) {
|
|
39
|
+
const field = fieldMap.get(fieldName);
|
|
40
|
+
// If field doesn't exist, log warning and continue
|
|
41
|
+
if (!field) {
|
|
42
|
+
console.warn(`Field "${fieldName}" not found in PDF form. Skipping.`);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// Handle null or undefined values
|
|
46
|
+
if (fieldValue === null || fieldValue === undefined) {
|
|
47
|
+
console.warn(`Skipping field "${fieldName}" with null or undefined value.`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
// Fill the field based on its type
|
|
52
|
+
if (field instanceof pdf_lib_1.PDFTextField) {
|
|
53
|
+
fillTextField(field, fieldValue, fontSize);
|
|
54
|
+
}
|
|
55
|
+
else if (field instanceof pdf_lib_1.PDFCheckBox) {
|
|
56
|
+
fillCheckBox(field, fieldValue);
|
|
57
|
+
}
|
|
58
|
+
else if (field instanceof pdf_lib_1.PDFRadioGroup) {
|
|
59
|
+
fillRadioGroup(field, fieldValue);
|
|
60
|
+
}
|
|
61
|
+
else if (field instanceof pdf_lib_1.PDFDropdown) {
|
|
62
|
+
fillDropdown(field, fieldValue);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.warn(`Unsupported field type for "${fieldName}". Skipping.`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.warn(`Error filling field "${fieldName}": ${error instanceof Error ? error.message : String(error)}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Flatten the form to make fields non-editable (if requested)
|
|
73
|
+
if (flatten) {
|
|
74
|
+
form.flatten();
|
|
75
|
+
}
|
|
76
|
+
// Save and return the modified PDF
|
|
77
|
+
const pdfBytes = await pdfDoc.save();
|
|
78
|
+
return Buffer.from(pdfBytes);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
if (error instanceof Error) {
|
|
82
|
+
throw new Error(`Failed to process PDF form: ${error.message}`);
|
|
83
|
+
}
|
|
84
|
+
throw new Error("Failed to process PDF form: Unknown error");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Fills a text field with the provided value
|
|
89
|
+
* @param field - PDF text field to fill
|
|
90
|
+
* @param value - Value to set (converted to string)
|
|
91
|
+
* @param fontSize - Font size to use for the text field
|
|
92
|
+
*/
|
|
93
|
+
function fillTextField(field, value, fontSize) {
|
|
94
|
+
const stringValue = String(value);
|
|
95
|
+
// Set text content
|
|
96
|
+
field.setText(stringValue);
|
|
97
|
+
// Set font size to ensure text fits and is readable
|
|
98
|
+
// Using a smaller font size helps prevent text truncation
|
|
99
|
+
try {
|
|
100
|
+
field.setFontSize(fontSize);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// If setting font size fails, continue without it
|
|
104
|
+
// This can happen if the field has specific formatting restrictions
|
|
105
|
+
}
|
|
106
|
+
// Enable multiline if the field supports it and text is long
|
|
107
|
+
try {
|
|
108
|
+
if (stringValue.length > 50 || stringValue.includes('\n')) {
|
|
109
|
+
field.enableMultiline();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// If enabling multiline fails, continue without it
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Fills a checkbox field with the provided boolean value
|
|
118
|
+
* @param field - PDF checkbox field to fill
|
|
119
|
+
* @param value - Boolean value or string representation
|
|
120
|
+
*/
|
|
121
|
+
function fillCheckBox(field, value) {
|
|
122
|
+
// Handle boolean values
|
|
123
|
+
if (typeof value === "boolean") {
|
|
124
|
+
if (value) {
|
|
125
|
+
field.check();
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
field.uncheck();
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
// Handle string representations of booleans
|
|
133
|
+
if (typeof value === "string") {
|
|
134
|
+
const lowerValue = value.toLowerCase();
|
|
135
|
+
if (lowerValue === "true" || lowerValue === "yes" || lowerValue === "1") {
|
|
136
|
+
field.check();
|
|
137
|
+
}
|
|
138
|
+
else if (lowerValue === "false" || lowerValue === "no" || lowerValue === "0") {
|
|
139
|
+
field.uncheck();
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
throw new Error(`Invalid checkbox value: "${value}". Expected boolean or "true"/"false".`);
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// Handle numeric values (0 = unchecked, non-zero = checked)
|
|
147
|
+
if (typeof value === "number") {
|
|
148
|
+
if (value !== 0) {
|
|
149
|
+
field.check();
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
field.uncheck();
|
|
153
|
+
}
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Fills a radio button group with the provided option value
|
|
159
|
+
* @param field - PDF radio group field to fill
|
|
160
|
+
* @param value - Option value to select
|
|
161
|
+
*/
|
|
162
|
+
function fillRadioGroup(field, value) {
|
|
163
|
+
const stringValue = String(value);
|
|
164
|
+
// Get available options
|
|
165
|
+
const options = field.getOptions();
|
|
166
|
+
// Check if the value matches any available option
|
|
167
|
+
if (!options.includes(stringValue)) {
|
|
168
|
+
throw new Error(`Invalid radio group value: "${stringValue}". Available options: ${options.join(", ")}`);
|
|
169
|
+
}
|
|
170
|
+
field.select(stringValue);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Fills a dropdown field with the provided option value
|
|
174
|
+
* @param field - PDF dropdown field to fill
|
|
175
|
+
* @param value - Option value to select
|
|
176
|
+
*/
|
|
177
|
+
function fillDropdown(field, value) {
|
|
178
|
+
const stringValue = String(value);
|
|
179
|
+
// Get available options
|
|
180
|
+
const options = field.getOptions();
|
|
181
|
+
// Check if the value matches any available option
|
|
182
|
+
if (!options.includes(stringValue)) {
|
|
183
|
+
throw new Error(`Invalid dropdown value: "${stringValue}". Available options: ${options.join(", ")}`);
|
|
184
|
+
}
|
|
185
|
+
field.select(stringValue);
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=form-filler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-filler.js","sourceRoot":"","sources":["../../../src/converters/pdf/form-filler.ts"],"names":[],"mappings":"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","sourcesContent":["import { PDFDocument, PDFTextField, PDFCheckBox, PDFRadioGroup, PDFDropdown } from \"pdf-lib\";\n\n/**\n * Configuration options for PDF form filling\n */\nexport interface FillPdfFormOptions {\n /**\n * Font size to use for text fields (default: 10)\n * Smaller values help prevent text truncation\n */\n fontSize?: number;\n\n /**\n * Whether to flatten the form after filling (default: true)\n * When true, form fields become non-editable\n */\n flatten?: boolean;\n}\n\n/**\n * Fills PDF form fields with provided data and flattens the form\n * @param pdfBuffer - PDF file buffer containing form fields\n * @param formData - Key-value pairs where keys match PDF field names\n * @param options - Optional configuration for form filling\n * @returns Modified PDF buffer with filled and flattened form fields\n * @throws Error if PDF buffer is invalid or cannot be processed\n */\nexport async function fillPdfForm(\n pdfBuffer: Buffer,\n formData: Record<string, string | number | boolean>,\n options?: FillPdfFormOptions,\n): Promise<Buffer> {\n // Set default options\n const fontSize = options?.fontSize ?? 10;\n const flatten = options?.flatten ?? true;\n // Validate input\n if (!pdfBuffer || pdfBuffer.length === 0) {\n throw new Error(\"Invalid PDF buffer: buffer is empty or undefined\");\n }\n\n if (!formData || typeof formData !== \"object\") {\n throw new Error(\"Invalid form data: must be a non-null object\");\n }\n\n try {\n // Load the PDF document\n const pdfDoc = await PDFDocument.load(pdfBuffer);\n\n // Get the form from the PDF\n const form = pdfDoc.getForm();\n\n // Get all fields in the form\n const fields = form.getFields();\n\n // Create a map of field names to fields for quick lookup\n const fieldMap = new Map<string, ReturnType<typeof form.getFields>[number]>();\n fields.forEach(field => {\n const fieldName = field.getName();\n fieldMap.set(fieldName, field);\n });\n\n // Process each entry in the form data\n for (const [fieldName, fieldValue] of Object.entries(formData)) {\n const field = fieldMap.get(fieldName);\n\n // If field doesn't exist, log warning and continue\n if (!field) {\n console.warn(`Field \"${fieldName}\" not found in PDF form. Skipping.`);\n continue;\n }\n\n // Handle null or undefined values\n if (fieldValue === null || fieldValue === undefined) {\n console.warn(`Skipping field \"${fieldName}\" with null or undefined value.`);\n continue;\n }\n\n try {\n // Fill the field based on its type\n if (field instanceof PDFTextField) {\n fillTextField(field, fieldValue, fontSize);\n } else if (field instanceof PDFCheckBox) {\n fillCheckBox(field, fieldValue);\n } else if (field instanceof PDFRadioGroup) {\n fillRadioGroup(field, fieldValue);\n } else if (field instanceof PDFDropdown) {\n fillDropdown(field, fieldValue);\n } else {\n console.warn(`Unsupported field type for \"${fieldName}\". Skipping.`);\n }\n } catch (error) {\n console.warn(`Error filling field \"${fieldName}\": ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n // Flatten the form to make fields non-editable (if requested)\n if (flatten) {\n form.flatten();\n }\n\n // Save and return the modified PDF\n const pdfBytes = await pdfDoc.save();\n return Buffer.from(pdfBytes);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to process PDF form: ${error.message}`);\n }\n throw new Error(\"Failed to process PDF form: Unknown error\");\n }\n}\n\n/**\n * Fills a text field with the provided value\n * @param field - PDF text field to fill\n * @param value - Value to set (converted to string)\n * @param fontSize - Font size to use for the text field\n */\nfunction fillTextField(\n field: PDFTextField,\n value: string | number | boolean,\n fontSize: number,\n): void {\n const stringValue = String(value);\n\n // Set text content\n field.setText(stringValue);\n\n // Set font size to ensure text fits and is readable\n // Using a smaller font size helps prevent text truncation\n try {\n field.setFontSize(fontSize);\n } catch {\n // If setting font size fails, continue without it\n // This can happen if the field has specific formatting restrictions\n }\n\n // Enable multiline if the field supports it and text is long\n try {\n if (stringValue.length > 50 || stringValue.includes('\\n')) {\n field.enableMultiline();\n }\n } catch {\n // If enabling multiline fails, continue without it\n }\n}\n\n/**\n * Fills a checkbox field with the provided boolean value\n * @param field - PDF checkbox field to fill\n * @param value - Boolean value or string representation\n */\nfunction fillCheckBox(\n field: PDFCheckBox,\n value: string | number | boolean,\n): void {\n // Handle boolean values\n if (typeof value === \"boolean\") {\n if (value) {\n field.check();\n } else {\n field.uncheck();\n }\n return;\n }\n\n // Handle string representations of booleans\n if (typeof value === \"string\") {\n const lowerValue = value.toLowerCase();\n if (lowerValue === \"true\" || lowerValue === \"yes\" || lowerValue === \"1\") {\n field.check();\n } else if (lowerValue === \"false\" || lowerValue === \"no\" || lowerValue === \"0\") {\n field.uncheck();\n } else {\n throw new Error(`Invalid checkbox value: \"${value}\". Expected boolean or \"true\"/\"false\".`);\n }\n return;\n }\n\n // Handle numeric values (0 = unchecked, non-zero = checked)\n if (typeof value === \"number\") {\n if (value !== 0) {\n field.check();\n } else {\n field.uncheck();\n }\n return;\n }\n}\n\n/**\n * Fills a radio button group with the provided option value\n * @param field - PDF radio group field to fill\n * @param value - Option value to select\n */\nfunction fillRadioGroup(\n field: PDFRadioGroup,\n value: string | number | boolean,\n): void {\n const stringValue = String(value);\n\n // Get available options\n const options = field.getOptions();\n\n // Check if the value matches any available option\n if (!options.includes(stringValue)) {\n throw new Error(\n `Invalid radio group value: \"${stringValue}\". Available options: ${options.join(\", \")}`,\n );\n }\n\n field.select(stringValue);\n}\n\n/**\n * Fills a dropdown field with the provided option value\n * @param field - PDF dropdown field to fill\n * @param value - Option value to select\n */\nfunction fillDropdown(\n field: PDFDropdown,\n value: string | number | boolean,\n): void {\n const stringValue = String(value);\n\n // Get available options\n const options = field.getOptions();\n\n // Check if the value matches any available option\n if (!options.includes(stringValue)) {\n throw new Error(\n `Invalid dropdown value: \"${stringValue}\". Available options: ${options.join(\", \")}`,\n );\n }\n\n field.select(stringValue);\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PdfMakeConverterContext, PdfmakeAdapter, AdapterRegistry } from "./pdfmake.types";
|
|
2
|
+
/**
|
|
3
|
+
* Processes a document recursively, applying adapters to matching elements.
|
|
4
|
+
*
|
|
5
|
+
* @param element - The current element to process
|
|
6
|
+
* @param adapters - Map of element types to their adapter functions
|
|
7
|
+
* @param context - Current processing context
|
|
8
|
+
* @returns The transformed element
|
|
9
|
+
*/
|
|
10
|
+
export declare function processDocument(element: unknown, adapters: Map<string, PdfmakeAdapter>, context: PdfMakeConverterContext): Promise<unknown>;
|
|
11
|
+
export declare const preProcessPdfMakeDocument: (documentDefinition: Record<string, unknown>, registry?: AdapterRegistry, context?: Partial<PdfMakeConverterContext>) => Promise<Record<string, unknown>>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.preProcessPdfMakeDocument = void 0;
|
|
4
|
+
exports.processDocument = processDocument;
|
|
5
|
+
const pdfmake_types_1 = require("./pdfmake.types");
|
|
6
|
+
/**
|
|
7
|
+
* Helper to check if a value is a plain object
|
|
8
|
+
*/
|
|
9
|
+
function isPlainObject(value) {
|
|
10
|
+
return (typeof value === "object" &&
|
|
11
|
+
value !== null &&
|
|
12
|
+
!Array.isArray(value) &&
|
|
13
|
+
Object.prototype.toString.call(value) === "[object Object]");
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Processes a document recursively, applying adapters to matching elements.
|
|
17
|
+
*
|
|
18
|
+
* @param element - The current element to process
|
|
19
|
+
* @param adapters - Map of element types to their adapter functions
|
|
20
|
+
* @param context - Current processing context
|
|
21
|
+
* @returns The transformed element
|
|
22
|
+
*/
|
|
23
|
+
async function processDocument(element, adapters, context) {
|
|
24
|
+
// Handle null/undefined
|
|
25
|
+
if (element == null) {
|
|
26
|
+
return element;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
// Handle arrays - process each item
|
|
30
|
+
if (Array.isArray(element)) {
|
|
31
|
+
return await Promise.all(element.map((item, index) => processDocument(item, adapters, {
|
|
32
|
+
...context,
|
|
33
|
+
path: [...context.path, String(index)],
|
|
34
|
+
depth: context.depth + 1,
|
|
35
|
+
})));
|
|
36
|
+
}
|
|
37
|
+
// Handle plain objects
|
|
38
|
+
if (isPlainObject(element)) {
|
|
39
|
+
// Try to apply adapters based on element type
|
|
40
|
+
const elementType = element.type;
|
|
41
|
+
if (elementType && adapters.has(elementType)) {
|
|
42
|
+
const adapter = adapters.get(elementType);
|
|
43
|
+
element = await adapter(element, context);
|
|
44
|
+
// After transformation, element might not be a plain object anymore
|
|
45
|
+
if (!isPlainObject(element)) {
|
|
46
|
+
return element;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Also try adapters based on properties (e.g., "table" property)
|
|
50
|
+
for (const [key, adapter] of adapters.entries()) {
|
|
51
|
+
// Skip type-based adapters already processed
|
|
52
|
+
if (key === elementType)
|
|
53
|
+
continue;
|
|
54
|
+
// Apply adapter if it matches a property name
|
|
55
|
+
if (key in element) {
|
|
56
|
+
const transformed = await adapter(element, context);
|
|
57
|
+
// Only accept transformation if adapter actually changed something
|
|
58
|
+
if (transformed !== element) {
|
|
59
|
+
element = transformed;
|
|
60
|
+
// After transformation, element might not be a plain object anymore
|
|
61
|
+
if (!isPlainObject(element)) {
|
|
62
|
+
return element;
|
|
63
|
+
}
|
|
64
|
+
break; // Only apply first matching adapter
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Recursively process all properties
|
|
69
|
+
const processed = {};
|
|
70
|
+
for (const [key, value] of Object.entries(element)) {
|
|
71
|
+
processed[key] = await processDocument(value, adapters, {
|
|
72
|
+
...context,
|
|
73
|
+
path: [...context.path, key],
|
|
74
|
+
depth: context.depth + 1,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return processed;
|
|
78
|
+
}
|
|
79
|
+
// Primitive values - return as-is
|
|
80
|
+
return element;
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
throw new pdfmake_types_1.AdapterError(err, element);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const preProcessPdfMakeDocument = async (documentDefinition, registry, context) => {
|
|
87
|
+
if (!registry) {
|
|
88
|
+
return Promise.resolve(documentDefinition);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
return (await registry?.process(documentDefinition, context));
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
exports.preProcessPdfMakeDocument = preProcessPdfMakeDocument;
|
|
95
|
+
//# sourceMappingURL=adapter-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-processor.js","sourceRoot":"","sources":["../../../../src/converters/pdf/pdfmake/adapter-processor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n PdfMakeConverterContext,\n AdapterError,\n PdfmakeAdapter,\n AdapterRegistry,\n} from \"./pdfmake.types\";\n\n/**\n * Helper to check if a value is a plain object\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === \"[object Object]\"\n );\n}\n\n/**\n * Processes a document recursively, applying adapters to matching elements.\n *\n * @param element - The current element to process\n * @param adapters - Map of element types to their adapter functions\n * @param context - Current processing context\n * @returns The transformed element\n */\nexport async function processDocument(\n element: unknown,\n adapters: Map<string, PdfmakeAdapter>,\n context: PdfMakeConverterContext,\n): Promise<unknown> {\n // Handle null/undefined\n if (element == null) {\n return element;\n }\n try {\n // Handle arrays - process each item\n if (Array.isArray(element)) {\n return await Promise.all(\n element.map((item, index) =>\n processDocument(item, adapters, {\n ...context,\n path: [...context.path, String(index)],\n depth: context.depth + 1,\n }),\n ),\n );\n }\n\n // Handle plain objects\n if (isPlainObject(element)) {\n // Try to apply adapters based on element type\n const elementType = element.type as string | undefined;\n if (elementType && adapters.has(elementType)) {\n const adapter = adapters.get(elementType)!;\n element = await adapter(element, context);\n\n // After transformation, element might not be a plain object anymore\n if (!isPlainObject(element)) {\n return element;\n }\n }\n\n // Also try adapters based on properties (e.g., \"table\" property)\n for (const [key, adapter] of adapters.entries()) {\n // Skip type-based adapters already processed\n if (key === elementType) continue;\n\n // Apply adapter if it matches a property name\n if (key in element) {\n const transformed = await adapter(element, context);\n // Only accept transformation if adapter actually changed something\n if (transformed !== element) {\n element = transformed;\n // After transformation, element might not be a plain object anymore\n if (!isPlainObject(element)) {\n return element;\n }\n break; // Only apply first matching adapter\n }\n }\n }\n\n // Recursively process all properties\n const processed: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(\n element as Record<string, unknown>,\n )) {\n processed[key] = await processDocument(value, adapters, {\n ...context,\n path: [...context.path, key],\n depth: context.depth + 1,\n });\n }\n return processed;\n }\n\n // Primitive values - return as-is\n return element;\n } catch (err) {\n throw new AdapterError(err as string, element);\n }\n}\n\nexport const preProcessPdfMakeDocument = async (\n documentDefinition: Record<string, unknown>,\n registry?: AdapterRegistry,\n context?: Partial<PdfMakeConverterContext>,\n): Promise<Record<string, unknown>> => {\n if (!registry) {\n return Promise.resolve(documentDefinition);\n } else {\n return (await registry?.process(documentDefinition, context)) as Record<\n string,\n unknown\n >;\n }\n};\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { AdapterRegistry } from "./pdfmake.types";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new adapter registry for runtime registration and processing of pdfmake adapters.
|
|
4
|
+
* Each registry is independent and maintains its own set of adapters.
|
|
5
|
+
*
|
|
6
|
+
* @returns A new AdapterRegistry instance
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const registry = createAdapterRegistry();
|
|
11
|
+
*
|
|
12
|
+
* // Register an adapter for tables
|
|
13
|
+
* registry.register('table', (element, context) => {
|
|
14
|
+
* // Transform custom table format to pdfmake format
|
|
15
|
+
* return { table: { body: transformData(element.data) } };
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // Process a document
|
|
19
|
+
* const transformed = registry.process(documentDefinition, { webupManagerData });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function createAdapterRegistry(): AdapterRegistry;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAdapterRegistry = createAdapterRegistry;
|
|
4
|
+
const adapter_processor_1 = require("./adapter-processor");
|
|
5
|
+
/**
|
|
6
|
+
* Creates a new adapter registry for runtime registration and processing of pdfmake adapters.
|
|
7
|
+
* Each registry is independent and maintains its own set of adapters.
|
|
8
|
+
*
|
|
9
|
+
* @returns A new AdapterRegistry instance
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const registry = createAdapterRegistry();
|
|
14
|
+
*
|
|
15
|
+
* // Register an adapter for tables
|
|
16
|
+
* registry.register('table', (element, context) => {
|
|
17
|
+
* // Transform custom table format to pdfmake format
|
|
18
|
+
* return { table: { body: transformData(element.data) } };
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* // Process a document
|
|
22
|
+
* const transformed = registry.process(documentDefinition, { webupManagerData });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function createAdapterRegistry() {
|
|
26
|
+
const adapters = new Map();
|
|
27
|
+
return {
|
|
28
|
+
register(elementType, adapter) {
|
|
29
|
+
adapters.set(elementType, adapter);
|
|
30
|
+
},
|
|
31
|
+
unregister(elementType) {
|
|
32
|
+
adapters.delete(elementType);
|
|
33
|
+
},
|
|
34
|
+
async process(document, context) {
|
|
35
|
+
const fullContext = {
|
|
36
|
+
webupManagerData: context?.webupManagerData,
|
|
37
|
+
getSmeupDataStructure: context?.getSmeupDataStructure,
|
|
38
|
+
path: context?.path ?? [],
|
|
39
|
+
depth: context?.depth ?? 0,
|
|
40
|
+
};
|
|
41
|
+
const processed = await (0, adapter_processor_1.processDocument)(document, adapters, fullContext);
|
|
42
|
+
return processed;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=adapter-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../../../../src/converters/pdf/pdfmake/adapter-registry.ts"],"names":[],"mappings":";;AA2BA,sDA0BC;AAhDD,2DAAsD;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,qBAAqB;IACnC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEnD,OAAO;QACL,QAAQ,CAAC,WAAmB,EAAE,OAAuB;YACnD,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;QAED,UAAU,CAAC,WAAmB;YAC5B,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC/B,CAAC;QAED,KAAK,CAAC,OAAO,CACX,QAAiB,EACjB,OAA0C;YAE1C,MAAM,WAAW,GAA4B;gBAC3C,gBAAgB,EAAE,OAAO,EAAE,gBAAgB;gBAC3C,qBAAqB,EAAE,OAAO,EAAE,qBAAqB;gBACrD,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE;gBACzB,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;aAC3B,CAAC;YACF,MAAM,SAAS,GAAG,MAAM,IAAA,mCAAe,EAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;YACzE,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import {\n AdapterRegistry,\n PdfmakeAdapter,\n PdfMakeConverterContext,\n} from \"./pdfmake.types\";\nimport { processDocument } from \"./adapter-processor\";\n\n/**\n * Creates a new adapter registry for runtime registration and processing of pdfmake adapters.\n * Each registry is independent and maintains its own set of adapters.\n *\n * @returns A new AdapterRegistry instance\n *\n * @example\n * ```typescript\n * const registry = createAdapterRegistry();\n *\n * // Register an adapter for tables\n * registry.register('table', (element, context) => {\n * // Transform custom table format to pdfmake format\n * return { table: { body: transformData(element.data) } };\n * });\n *\n * // Process a document\n * const transformed = registry.process(documentDefinition, { webupManagerData });\n * ```\n */\nexport function createAdapterRegistry(): AdapterRegistry {\n const adapters = new Map<string, PdfmakeAdapter>();\n\n return {\n register(elementType: string, adapter: PdfmakeAdapter): void {\n adapters.set(elementType, adapter);\n },\n\n unregister(elementType: string): void {\n adapters.delete(elementType);\n },\n\n async process(\n document: unknown,\n context?: Partial<PdfMakeConverterContext>,\n ): Promise<unknown> {\n const fullContext: PdfMakeConverterContext = {\n webupManagerData: context?.webupManagerData,\n getSmeupDataStructure: context?.getSmeupDataStructure,\n path: context?.path ?? [],\n depth: context?.depth ?? 0,\n };\n const processed = await processDocument(document, adapters, fullContext);\n return processed;\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { WebupManagerData } from "../../../types";
|
|
2
|
+
import { SmeupDataStructure } from "../../../types/data-structures/smeupDataStructure";
|
|
3
|
+
/**
|
|
4
|
+
* Context passed to adapter functions during document processing.
|
|
5
|
+
*/
|
|
6
|
+
export interface PdfMakeConverterContext<T extends SmeupDataStructure = SmeupDataStructure> {
|
|
7
|
+
/** WebUp manager data containing locale and theme settings */
|
|
8
|
+
webupManagerData?: WebupManagerData;
|
|
9
|
+
/** Path in the document tree (e.g., ['content', 0, 'table']) */
|
|
10
|
+
path: string[];
|
|
11
|
+
/** Current depth in the document tree */
|
|
12
|
+
depth: number;
|
|
13
|
+
getSmeupDataStructure?: (fun: string) => Promise<T>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Function that transforms an element from custom format to pdfmake standard format.
|
|
17
|
+
* Adapters are pure functions that receive an element and context, and return the transformed element.
|
|
18
|
+
* Can be synchronous or asynchronous.
|
|
19
|
+
*/
|
|
20
|
+
export type PdfmakeAdapter = (element: unknown, context: PdfMakeConverterContext) => unknown | Promise<unknown>;
|
|
21
|
+
/**
|
|
22
|
+
* Registry interface for managing pdfmake adapters at runtime.
|
|
23
|
+
*/
|
|
24
|
+
export interface AdapterRegistry {
|
|
25
|
+
/** Register an adapter for a specific element type */
|
|
26
|
+
register: (elementType: string, adapter: PdfmakeAdapter) => void;
|
|
27
|
+
/** Unregister an adapter for a specific element type */
|
|
28
|
+
unregister: (elementType: string) => void;
|
|
29
|
+
/** Process a document by applying registered adapters */
|
|
30
|
+
process: (document: unknown, context?: Partial<PdfMakeConverterContext>) => Promise<unknown>;
|
|
31
|
+
}
|
|
32
|
+
export declare class AdapterError extends Error {
|
|
33
|
+
element: unknown;
|
|
34
|
+
constructor(message: string, element: unknown);
|
|
35
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdapterError = void 0;
|
|
4
|
+
class AdapterError extends Error {
|
|
5
|
+
element;
|
|
6
|
+
constructor(message, element) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.element = element;
|
|
9
|
+
Object.setPrototypeOf(this, AdapterError.prototype);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.AdapterError = AdapterError;
|
|
13
|
+
//# sourceMappingURL=pdfmake.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdfmake.types.js","sourceRoot":"","sources":["../../../../src/converters/pdf/pdfmake/pdfmake.types.ts"],"names":[],"mappings":";;;AA2CA,MAAa,YAAa,SAAQ,KAAK;IACrC,OAAO,CAAU;IACjB,YAAY,OAAe,EAAE,OAAgB;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;CACF;AAPD,oCAOC","sourcesContent":["import { WebupManagerData } from \"../../../types\";\nimport { SmeupDataStructure } from \"../../../types/data-structures/smeupDataStructure\";\n\n/**\n * Context passed to adapter functions during document processing.\n */\nexport interface PdfMakeConverterContext<\n T extends SmeupDataStructure = SmeupDataStructure,\n> {\n /** WebUp manager data containing locale and theme settings */\n webupManagerData?: WebupManagerData;\n /** Path in the document tree (e.g., ['content', 0, 'table']) */\n path: string[];\n /** Current depth in the document tree */\n depth: number;\n getSmeupDataStructure?: (fun: string) => Promise<T>;\n}\n\n/**\n * Function that transforms an element from custom format to pdfmake standard format.\n * Adapters are pure functions that receive an element and context, and return the transformed element.\n * Can be synchronous or asynchronous.\n */\nexport type PdfmakeAdapter = (\n element: unknown,\n context: PdfMakeConverterContext,\n) => unknown | Promise<unknown>;\n\n/**\n * Registry interface for managing pdfmake adapters at runtime.\n */\nexport interface AdapterRegistry {\n /** Register an adapter for a specific element type */\n register: (elementType: string, adapter: PdfmakeAdapter) => void;\n /** Unregister an adapter for a specific element type */\n unregister: (elementType: string) => void;\n /** Process a document by applying registered adapters */\n process: (\n document: unknown,\n context?: Partial<PdfMakeConverterContext>,\n ) => Promise<unknown>;\n}\n\nexport class AdapterError extends Error {\n element: unknown;\n constructor(message: string, element: unknown) {\n super(message);\n this.element = element;\n Object.setPrototypeOf(this, AdapterError.prototype);\n }\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PdfMakeConverterContext } from "./pdfmake.types";
|
|
2
|
+
/**
|
|
3
|
+
* Adapts a Smeup table structure to the PDFMake table format.
|
|
4
|
+
*
|
|
5
|
+
* This adapter function checks if the provided element contains a table with data.
|
|
6
|
+
* If so, it transforms the table's columns and rows into the PDFMake `body` format,
|
|
7
|
+
* where the first row is the header (column titles) and subsequent rows are the data.
|
|
8
|
+
* All properties of the original table except `data` are preserved.
|
|
9
|
+
*
|
|
10
|
+
* @returns A function that takes an element and returns the adapted element for PDFMake,
|
|
11
|
+
* or the original element if it does not contain a valid table with data.
|
|
12
|
+
*/
|
|
13
|
+
export declare function smeupTableToPdfMakeTableAdapter(): (element: unknown) => unknown;
|
|
14
|
+
/**
|
|
15
|
+
* Adapter function for converting a table element with a `fun` property to a Smeup table structure.
|
|
16
|
+
*
|
|
17
|
+
* This function returns an asynchronous converter that checks if the provided element contains
|
|
18
|
+
* a table with a `fun` property. If present, it uses the `getSmeupDataStructure` function from
|
|
19
|
+
* the context to fetch the table data corresponding to the `fun` string, and replaces the original
|
|
20
|
+
* table's `fun` property with the fetched data under the `data` property. All other properties
|
|
21
|
+
* of the table are preserved.
|
|
22
|
+
*
|
|
23
|
+
* @returns An asynchronous function that takes an element and a context, and returns the adapted element.
|
|
24
|
+
*
|
|
25
|
+
* @throws If the context does not provide a `getSmeupDataStructure` function when the `fun` property is used.
|
|
26
|
+
*
|
|
27
|
+
* @param element - The input element to be adapted.
|
|
28
|
+
* @param context - The conversion context, which must provide `getSmeupDataStructure` if the `fun` property is present.
|
|
29
|
+
*/
|
|
30
|
+
export declare function funToSmeupTableAdapter(): (element: unknown, context: PdfMakeConverterContext) => Promise<unknown>;
|
|
31
|
+
export declare function dataTableAdapter(): (element: unknown, context: PdfMakeConverterContext) => Promise<unknown>;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.smeupTableToPdfMakeTableAdapter = smeupTableToPdfMakeTableAdapter;
|
|
4
|
+
exports.funToSmeupTableAdapter = funToSmeupTableAdapter;
|
|
5
|
+
exports.dataTableAdapter = dataTableAdapter;
|
|
6
|
+
const smeupDataStructure_1 = require("../../../types/data-structures/smeupDataStructure");
|
|
7
|
+
function hasData(element) {
|
|
8
|
+
return (typeof element === "object" &&
|
|
9
|
+
element !== null &&
|
|
10
|
+
"table" in element &&
|
|
11
|
+
typeof element.table === "object" &&
|
|
12
|
+
element.table !== null &&
|
|
13
|
+
"data" in element.table);
|
|
14
|
+
}
|
|
15
|
+
function hasTableWithDataTable(element) {
|
|
16
|
+
return (hasData(element) &&
|
|
17
|
+
typeof element.table.data === "object" &&
|
|
18
|
+
element.table.data !== null &&
|
|
19
|
+
"type" in element.table.data &&
|
|
20
|
+
element.table.data.type ===
|
|
21
|
+
smeupDataStructure_1.SmeupDataStructureType.SmeupDataTable &&
|
|
22
|
+
"rows" in element.table.data &&
|
|
23
|
+
"columns" in
|
|
24
|
+
element.table.data);
|
|
25
|
+
}
|
|
26
|
+
function hasTableWithFun(element) {
|
|
27
|
+
return (typeof element.table.fun === "string" &&
|
|
28
|
+
element.table.fun.length > 0);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Adapts a Smeup table structure to the PDFMake table format.
|
|
32
|
+
*
|
|
33
|
+
* This adapter function checks if the provided element contains a table with data.
|
|
34
|
+
* If so, it transforms the table's columns and rows into the PDFMake `body` format,
|
|
35
|
+
* where the first row is the header (column titles) and subsequent rows are the data.
|
|
36
|
+
* All properties of the original table except `data` are preserved.
|
|
37
|
+
*
|
|
38
|
+
* @returns A function that takes an element and returns the adapted element for PDFMake,
|
|
39
|
+
* or the original element if it does not contain a valid table with data.
|
|
40
|
+
*/
|
|
41
|
+
function smeupTableToPdfMakeTableAdapter() {
|
|
42
|
+
return (element) => {
|
|
43
|
+
if (!hasTableWithDataTable(element)) {
|
|
44
|
+
return element;
|
|
45
|
+
}
|
|
46
|
+
const { columns, rows } = element.table.data;
|
|
47
|
+
// Build header row from column titles
|
|
48
|
+
const headerRow = columns.map(col => col.title);
|
|
49
|
+
// Build data rows by extracting values in column order
|
|
50
|
+
const dataRows = rows.map(row => columns.map(col => {
|
|
51
|
+
const cell = row.cells?.[col.name];
|
|
52
|
+
const value = cell?.value;
|
|
53
|
+
// Convert to string representation for PDF
|
|
54
|
+
return value != null ? String(value) : "";
|
|
55
|
+
}));
|
|
56
|
+
// Combine header and data rows
|
|
57
|
+
const body = [headerRow, ...dataRows];
|
|
58
|
+
// Extract all properties except 'data' from the table object
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
60
|
+
const { data, ...tableRest } = element.table;
|
|
61
|
+
return {
|
|
62
|
+
...element,
|
|
63
|
+
table: {
|
|
64
|
+
...tableRest,
|
|
65
|
+
body,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Adapter function for converting a table element with a `fun` property to a Smeup table structure.
|
|
72
|
+
*
|
|
73
|
+
* This function returns an asynchronous converter that checks if the provided element contains
|
|
74
|
+
* a table with a `fun` property. If present, it uses the `getSmeupDataStructure` function from
|
|
75
|
+
* the context to fetch the table data corresponding to the `fun` string, and replaces the original
|
|
76
|
+
* table's `fun` property with the fetched data under the `data` property. All other properties
|
|
77
|
+
* of the table are preserved.
|
|
78
|
+
*
|
|
79
|
+
* @returns An asynchronous function that takes an element and a context, and returns the adapted element.
|
|
80
|
+
*
|
|
81
|
+
* @throws If the context does not provide a `getSmeupDataStructure` function when the `fun` property is used.
|
|
82
|
+
*
|
|
83
|
+
* @param element - The input element to be adapted.
|
|
84
|
+
* @param context - The conversion context, which must provide `getSmeupDataStructure` if the `fun` property is present.
|
|
85
|
+
*/
|
|
86
|
+
function funToSmeupTableAdapter() {
|
|
87
|
+
return async (element, context) => {
|
|
88
|
+
if (!hasTableWithFun(element)) {
|
|
89
|
+
return element;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
if (!context.getSmeupDataStructure) {
|
|
93
|
+
throw new Error("getSmeupDataStructure function is required in context when the fun property is used");
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
const funStr = element.table.fun;
|
|
97
|
+
const dataTable = await context.getSmeupDataStructure(funStr);
|
|
98
|
+
// Extract all properties except 'fun' from the table object
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
100
|
+
const { fun, ...tableRest } = element.table;
|
|
101
|
+
return {
|
|
102
|
+
...element,
|
|
103
|
+
table: {
|
|
104
|
+
...tableRest,
|
|
105
|
+
data: dataTable,
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function dataTableAdapter() {
|
|
113
|
+
return async (element, context) => {
|
|
114
|
+
const adaptedElement = await funToSmeupTableAdapter()(element, context);
|
|
115
|
+
return await smeupTableToPdfMakeTableAdapter()(adaptedElement);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=table-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-adapter.js","sourceRoot":"","sources":["../../../../src/converters/pdf/pdfmake/table-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { SmeupDataStructureType } from \"../../../types/data-structures/smeupDataStructure\";\nimport { SmeupDataTable } from \"../../../types/data-structures/smeupDataTable\";\nimport { PdfMakeConverterContext } from \"./pdfmake.types\";\n\nfunction hasData(element: unknown): element is { table: { data: unknown } } {\n return (\n typeof element === \"object\" &&\n element !== null &&\n \"table\" in element &&\n typeof (element as { table: unknown }).table === \"object\" &&\n (element as { table: unknown }).table !== null &&\n \"data\" in (element as { table: { data: unknown } }).table\n );\n}\n\nfunction hasTableWithDataTable(\n element: unknown,\n): element is { table: { data: SmeupDataTable } } {\n return (\n hasData(element) &&\n typeof (element as { table: { data: unknown } }).table.data === \"object\" &&\n (element as { table: { data: unknown } }).table.data !== null &&\n \"type\" in (element as { table: { data: { type: unknown } } }).table.data &&\n (element as { table: { data: { type: unknown } } }).table.data.type ===\n SmeupDataStructureType.SmeupDataTable &&\n \"rows\" in (element as { table: { data: { rows: unknown } } }).table.data &&\n \"columns\" in\n (element as { table: { data: { columns: unknown } } }).table.data\n );\n}\n\nfunction hasTableWithFun(\n element: unknown,\n): element is { table: { fun: string } } {\n return (\n typeof (element as { table: { fun: string } }).table.fun === \"string\" &&\n (element as { table: { fun: string } }).table.fun.length > 0\n );\n}\n\n/**\n * Adapts a Smeup table structure to the PDFMake table format.\n *\n * This adapter function checks if the provided element contains a table with data.\n * If so, it transforms the table's columns and rows into the PDFMake `body` format,\n * where the first row is the header (column titles) and subsequent rows are the data.\n * All properties of the original table except `data` are preserved.\n *\n * @returns A function that takes an element and returns the adapted element for PDFMake,\n * or the original element if it does not contain a valid table with data.\n */\nexport function smeupTableToPdfMakeTableAdapter() {\n return (element: unknown): unknown => {\n if (!hasTableWithDataTable(element)) {\n return element;\n }\n\n const { columns, rows } = element.table.data;\n\n // Build header row from column titles\n const headerRow = columns.map(col => col.title);\n\n // Build data rows by extracting values in column order\n const dataRows = rows.map(row =>\n columns.map(col => {\n const cell = row.cells?.[col.name];\n const value = cell?.value;\n // Convert to string representation for PDF\n return value != null ? String(value) : \"\";\n }),\n );\n\n // Combine header and data rows\n const body = [headerRow, ...dataRows];\n\n // Extract all properties except 'data' from the table object\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { data, ...tableRest } = element.table;\n\n return {\n ...element,\n table: {\n ...tableRest,\n body,\n },\n };\n };\n}\n\n/**\n * Adapter function for converting a table element with a `fun` property to a Smeup table structure.\n *\n * This function returns an asynchronous converter that checks if the provided element contains\n * a table with a `fun` property. If present, it uses the `getSmeupDataStructure` function from\n * the context to fetch the table data corresponding to the `fun` string, and replaces the original\n * table's `fun` property with the fetched data under the `data` property. All other properties\n * of the table are preserved.\n *\n * @returns An asynchronous function that takes an element and a context, and returns the adapted element.\n *\n * @throws If the context does not provide a `getSmeupDataStructure` function when the `fun` property is used.\n *\n * @param element - The input element to be adapted.\n * @param context - The conversion context, which must provide `getSmeupDataStructure` if the `fun` property is present.\n */\nexport function funToSmeupTableAdapter() {\n return async (\n element: unknown,\n context: PdfMakeConverterContext,\n ): Promise<unknown> => {\n if (!hasTableWithFun(element)) {\n return element;\n } else {\n if (!context.getSmeupDataStructure) {\n throw new Error(\n \"getSmeupDataStructure function is required in context when the fun property is used\",\n );\n } else {\n const funStr = element.table.fun;\n const dataTable = await context.getSmeupDataStructure(funStr);\n // Extract all properties except 'fun' from the table object\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { fun, ...tableRest } = element.table;\n\n return {\n ...element,\n table: {\n ...tableRest,\n data: dataTable,\n },\n };\n }\n }\n };\n}\n\nexport function dataTableAdapter() {\n return async (\n element: unknown,\n context: PdfMakeConverterContext,\n ): Promise<unknown> => {\n const adaptedElement = await funToSmeupTableAdapter()(element, context);\n return await smeupTableToPdfMakeTableAdapter()(adaptedElement);\n };\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { TDocumentDefinitions } from "pdfmake/interfaces";
|
|
2
|
+
/**
|
|
3
|
+
* Renders a pdfmake document definition to a PDF Buffer.
|
|
4
|
+
*
|
|
5
|
+
* @param documentDefinition - The pdfmake document definition object
|
|
6
|
+
* @returns Promise that resolves to a Buffer containing the PDF data
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const docDef = {
|
|
11
|
+
* content: [
|
|
12
|
+
* { text: 'Hello World', fontSize: 20 },
|
|
13
|
+
* { table: { body: [['Cell 1', 'Cell 2']] } }
|
|
14
|
+
* ]
|
|
15
|
+
* };
|
|
16
|
+
*
|
|
17
|
+
* const pdfBuffer = await renderPdfmakeDocument(docDef);
|
|
18
|
+
* await fs.writeFile('output.pdf', pdfBuffer);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function renderPdfMakeDocument(documentDefinition: TDocumentDefinitions): Promise<Buffer>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.renderPdfMakeDocument = renderPdfMakeDocument;
|
|
40
|
+
const pdfmake_1 = __importDefault(require("pdfmake/build/pdfmake"));
|
|
41
|
+
const pdfFonts = __importStar(require("pdfmake/build/vfs_fonts"));
|
|
42
|
+
// Set up default fonts for pdfmake
|
|
43
|
+
pdfmake_1.default.vfs = pdfFonts.vfs;
|
|
44
|
+
/**
|
|
45
|
+
* Renders a pdfmake document definition to a PDF Buffer.
|
|
46
|
+
*
|
|
47
|
+
* @param documentDefinition - The pdfmake document definition object
|
|
48
|
+
* @returns Promise that resolves to a Buffer containing the PDF data
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const docDef = {
|
|
53
|
+
* content: [
|
|
54
|
+
* { text: 'Hello World', fontSize: 20 },
|
|
55
|
+
* { table: { body: [['Cell 1', 'Cell 2']] } }
|
|
56
|
+
* ]
|
|
57
|
+
* };
|
|
58
|
+
*
|
|
59
|
+
* const pdfBuffer = await renderPdfmakeDocument(docDef);
|
|
60
|
+
* await fs.writeFile('output.pdf', pdfBuffer);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
async function renderPdfMakeDocument(documentDefinition) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
let isResolved = false;
|
|
66
|
+
const errorHandler = (error) => {
|
|
67
|
+
if (!isResolved) {
|
|
68
|
+
cleanup();
|
|
69
|
+
reject(error);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const cleanup = () => {
|
|
73
|
+
if (!isResolved) {
|
|
74
|
+
isResolved = true;
|
|
75
|
+
process.off("uncaughtException", errorHandler);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
process.on("uncaughtException", errorHandler);
|
|
79
|
+
const pdfDocGenerator = pdfmake_1.default.createPdf(documentDefinition);
|
|
80
|
+
pdfDocGenerator.getBuffer((buffer) => {
|
|
81
|
+
// Success callback
|
|
82
|
+
cleanup();
|
|
83
|
+
resolve(Buffer.from(buffer));
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=pdfmake-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdfmake-renderer.js","sourceRoot":"","sources":["../../../src/converters/pdf/pdfmake-renderer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,sDA6BC;AAvDD,oEAA4C;AAC5C,kEAAoD;AAGpD,mCAAmC;AACnC,iBAAO,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC;AAE3B;;;;;;;;;;;;;;;;;;GAkBG;AACI,KAAK,UAAU,qBAAqB,CACzC,kBAAwC;IAExC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE;YACpC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,EAAE,CAAC;gBACV,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,UAAU,GAAG,IAAI,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,YAAY,CAAC,CAAC;YACjD,CAAC;QACH,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,YAAY,CAAC,CAAC;QAE9C,MAAM,eAAe,GAAG,iBAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAC9D,eAAe,CAAC,SAAS,CAAC,CAAC,MAAc,EAAE,EAAE;YAC3C,mBAAmB;YACnB,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import pdfMake from \"pdfmake/build/pdfmake\";\nimport * as pdfFonts from \"pdfmake/build/vfs_fonts\";\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\n// Set up default fonts for pdfmake\npdfMake.vfs = pdfFonts.vfs;\n\n/**\n * Renders a pdfmake document definition to a PDF Buffer.\n *\n * @param documentDefinition - The pdfmake document definition object\n * @returns Promise that resolves to a Buffer containing the PDF data\n *\n * @example\n * ```typescript\n * const docDef = {\n * content: [\n * { text: 'Hello World', fontSize: 20 },\n * { table: { body: [['Cell 1', 'Cell 2']] } }\n * ]\n * };\n *\n * const pdfBuffer = await renderPdfmakeDocument(docDef);\n * await fs.writeFile('output.pdf', pdfBuffer);\n * ```\n */\nexport async function renderPdfMakeDocument(\n documentDefinition: TDocumentDefinitions,\n): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n let isResolved = false;\n\n const errorHandler = (error: Error) => {\n if (!isResolved) {\n cleanup();\n reject(error);\n }\n };\n\n const cleanup = () => {\n if (!isResolved) {\n isResolved = true;\n process.off(\"uncaughtException\", errorHandler);\n }\n };\n\n process.on(\"uncaughtException\", errorHandler);\n\n const pdfDocGenerator = pdfMake.createPdf(documentDefinition);\n pdfDocGenerator.getBuffer((buffer: Buffer) => {\n // Success callback\n cleanup();\n resolve(Buffer.from(buffer));\n });\n });\n}\n"]}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { SmeupDataTable } from "../types/data-structures/smeupDataTable";
|
|
2
2
|
import { SmeupSch } from "../types/data-structures/smeupSch";
|
|
3
3
|
import { WebupManagerData, GenericObject } from "../types/index";
|
|
4
|
+
import type { PdfMakeConverterContext } from "./pdf/pdfmake/pdfmake.types";
|
|
5
|
+
import { fillPdfForm, FillPdfFormOptions } from "./pdf/form-filler";
|
|
4
6
|
export declare const schedaToPdfData: (sch: SmeupSch, webupManagerData: WebupManagerData) => Promise<Buffer>;
|
|
5
7
|
export declare const dataTableToPdfData: (component: {
|
|
6
8
|
smeupDataTable: SmeupDataTable;
|
|
7
9
|
props: GenericObject;
|
|
8
10
|
}, webupManagerData: WebupManagerData) => Promise<Buffer | Uint8Array>;
|
|
11
|
+
export declare const pdfmakeDocumentToPdfData: (documentDefinition: Record<string, unknown>, context?: Partial<PdfMakeConverterContext>) => Promise<Buffer>;
|
|
12
|
+
export { fillPdfForm };
|
|
13
|
+
export type { FillPdfFormOptions };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.dataTableToPdfData = exports.schedaToPdfData = void 0;
|
|
4
|
+
exports.fillPdfForm = exports.pdfmakeDocumentToPdfData = exports.dataTableToPdfData = exports.schedaToPdfData = void 0;
|
|
5
5
|
const index_1 = require("../types/index");
|
|
6
6
|
const commons_utility_1 = require("../utils/commons-utility");
|
|
7
7
|
const matrix_converter_1 = require("./excel/matrix-converter");
|
|
@@ -10,6 +10,12 @@ const sch_converter_1 = require("./pdf/sch-converter");
|
|
|
10
10
|
const pdf_lib_1 = require("pdf-lib");
|
|
11
11
|
const cover_renderer_1 = require("./pdf/cover-renderer");
|
|
12
12
|
const gfx_data_1 = require("../assets/gfx-data");
|
|
13
|
+
const pdfmake_renderer_1 = require("./pdf/pdfmake-renderer");
|
|
14
|
+
const form_filler_1 = require("./pdf/form-filler");
|
|
15
|
+
Object.defineProperty(exports, "fillPdfForm", { enumerable: true, get: function () { return form_filler_1.fillPdfForm; } });
|
|
16
|
+
const adapter_processor_1 = require("./pdf/pdfmake/adapter-processor");
|
|
17
|
+
const adapter_registry_1 = require("./pdf/pdfmake/adapter-registry");
|
|
18
|
+
const table_adapter_1 = require("./pdf/pdfmake/table-adapter");
|
|
13
19
|
const schedaToPdfData = async (sch, webupManagerData) => {
|
|
14
20
|
const doc = await (0, sch_converter_1.schedaToPdfDoc)(sch);
|
|
15
21
|
return Buffer.from(doc.output("arraybuffer"));
|
|
@@ -38,6 +44,17 @@ const dataTableToPdfData = async (component, webupManagerData) => {
|
|
|
38
44
|
}
|
|
39
45
|
};
|
|
40
46
|
exports.dataTableToPdfData = dataTableToPdfData;
|
|
47
|
+
const pdfmakeDocumentToPdfData = async (documentDefinition, context) => {
|
|
48
|
+
// Register adapters
|
|
49
|
+
const registry = (0, adapter_registry_1.createAdapterRegistry)();
|
|
50
|
+
registry.register("table", (0, table_adapter_1.dataTableAdapter)());
|
|
51
|
+
// Pre-process document with adapters
|
|
52
|
+
let processedDoc = await (0, adapter_processor_1.preProcessPdfMakeDocument)(documentDefinition, registry, context);
|
|
53
|
+
processedDoc = (await registry.process(documentDefinition, context));
|
|
54
|
+
// Render the document using pdfmake
|
|
55
|
+
return (0, pdfmake_renderer_1.renderPdfMakeDocument)(processedDoc);
|
|
56
|
+
};
|
|
57
|
+
exports.pdfmakeDocumentToPdfData = pdfmakeDocumentToPdfData;
|
|
41
58
|
/**
|
|
42
59
|
* Unisce più PDF (in formato ArrayBuffer/Uint8Array/Buffer) in un unico PDF.
|
|
43
60
|
* @param pdfBuffers Array di buffer PDF (es. ottenuti da jsPDF.output("arraybuffer"))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-converter.js","sourceRoot":"","sources":["../../src/converters/pdf-converter.ts"],"names":[],"mappings":";AAAA,sDAAsD;;;
|
|
1
|
+
{"version":3,"file":"pdf-converter.js","sourceRoot":"","sources":["../../src/converters/pdf-converter.ts"],"names":[],"mappings":";AAAA,sDAAsD;;;AAItD,0CAIwB;AACxB,8DAA2D;AAC3D,+DAAoE;AACpE,6DAA2D;AAC3D,uDAAqD;AACrD,qCAAsC;AACtC,yDAAsD;AACtD,iDAAgD;AAChD,6DAA+D;AAM/D,mDAAoE;AAiG3D,4FAjGA,yBAAW,OAiGA;AAhGpB,uEAA4E;AAC5E,qEAAuE;AACvE,+DAA+D;AAExD,MAAM,eAAe,GAAG,KAAK,EAClC,GAAa,EACb,gBAAkC,EACjB,EAAE;IACnB,MAAM,GAAG,GAAG,MAAM,IAAA,8BAAc,EAAC,GAAG,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC;AANW,QAAA,eAAe,mBAM1B;AAEK,MAAM,kBAAkB,GAAG,KAAK,EACrC,SAGC,EACD,gBAAkC,EACJ,EAAE;IAChC,MAAM,QAAQ,GAAG,IAAA,2CAAwB,EACvC,SAAS,EACT,8BAAsB,CAAC,IAAI,EAC3B,gBAAgB,CACjB,CAAC;IAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3C,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACpE,MAAM,QAAQ,GAAG,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACvE,MAAM,SAAS,GAAG,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACxE,MAAM,KAAK,GAAG,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,IAAI,qBAAU,CAAC;QAChE,MAAM,KAAK,GAAG,IAAA,+BAAc,EAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,MAAM,IAAA,oCAAiB,EAAC,SAAS,EAAE,gBAAgB,EAAE;YAClE,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC/C,OAAO,IAAA,iCAAe,EAAC,MAAM,aAAa,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;AACH,CAAC,CAAC;AA/BW,QAAA,kBAAkB,sBA+B7B;AAEK,MAAM,wBAAwB,GAAG,KAAK,EAC3C,kBAA2C,EAC3C,OAA0C,EACzB,EAAE;IACnB,oBAAoB;IACpB,MAAM,QAAQ,GAAG,IAAA,wCAAqB,GAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAA,gCAAgB,GAAE,CAAC,CAAC;IAE/C,qCAAqC;IACrC,IAAI,YAAY,GAAG,MAAM,IAAA,6CAAyB,EAChD,kBAAkB,EAClB,QAAQ,EACR,OAAO,CACR,CAAC;IAEF,YAAY,GAAG,CAAC,MAAM,QAAQ,CAAC,OAAO,CACpC,kBAAkB,EAClB,OAAO,CACR,CAA4B,CAAC;IAE9B,oCAAoC;IACpC,OAAO,IAAA,wCAAqB,EAAC,YAA+C,CAAC,CAAC;AAChF,CAAC,CAAC;AAtBW,QAAA,wBAAwB,4BAsBnC;AAEF;;;;GAIG;AACH,MAAM,aAAa,GAAG,KAAK,EACzB,UAAiD,EAC5B,EAAE;IACvB,IAAI,CAAC,UAAU,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAEpE,oCAAoC;IACpC,MAAM,SAAS,GAAG,MAAM,qBAAW,CAAC,MAAM,EAAE,CAAC;IAE7C,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,qBAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,SAAS,CAC3C,MAAM,EACN,MAAM,CAAC,cAAc,EAAE,CACxB,CAAC;QACF,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;IAC3C,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\nimport { SmeupDataTable } from \"../types/data-structures/smeupDataTable\";\nimport { SmeupSch } from \"../types/data-structures/smeupSch\";\nimport {\n WebupManagerData,\n GenericObject,\n SupportedExportFormats,\n} from \"../types/index\";\nimport { convertToBuffer } from \"../utils/commons-utility\";\nimport { dataTableToExcelWorkbook } from \"./excel/matrix-converter\";\nimport { dataTableToPdfDoc } from \"./pdf/matrix-converter\";\nimport { schedaToPdfDoc } from \"./pdf/sch-converter\";\nimport { PDFDocument } from \"pdf-lib\";\nimport { createCoverPdf } from \"./pdf/cover-renderer\";\nimport { logoBase64 } from \"../assets/gfx-data\";\nimport { renderPdfMakeDocument } from \"./pdf/pdfmake-renderer\";\nimport type {\n PdfMakeConverterContext,\n AdapterRegistry,\n} from \"./pdf/pdfmake/pdfmake.types\";\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\nimport { fillPdfForm, FillPdfFormOptions } from \"./pdf/form-filler\";\nimport { preProcessPdfMakeDocument } from \"./pdf/pdfmake/adapter-processor\";\nimport { createAdapterRegistry } from \"./pdf/pdfmake/adapter-registry\";\nimport { dataTableAdapter } from \"./pdf/pdfmake/table-adapter\";\n\nexport const schedaToPdfData = async (\n sch: SmeupSch,\n webupManagerData: WebupManagerData,\n): Promise<Buffer> => {\n const doc = await schedaToPdfDoc(sch);\n return Buffer.from(doc.output(\"arraybuffer\"));\n};\n\nexport const dataTableToPdfData = async (\n component: {\n smeupDataTable: SmeupDataTable;\n props: GenericObject;\n },\n webupManagerData: WebupManagerData,\n): Promise<Buffer | Uint8Array> => {\n const workbook = dataTableToExcelWorkbook(\n component,\n SupportedExportFormats.XLSX,\n webupManagerData,\n );\n\n const worksheet = workbook.getWorksheet(1);\n if (worksheet) {\n const title = component.smeupDataTable.cover?.titles?.[\"T01\"] ?? \"\";\n const subtitle = component.smeupDataTable.cover?.titles?.[\"T02\"] ?? \"\";\n const subtitle2 = component.smeupDataTable.cover?.titles?.[\"T03\"] ?? \"\";\n const image = component.smeupDataTable.cover?.image ?? \"\";\n const logo = component.smeupDataTable.cover?.logo ?? logoBase64;\n const cover = createCoverPdf(image, logo, title, subtitle, subtitle2);\n const pdfDoc = await dataTableToPdfDoc(worksheet, webupManagerData, {\n logoBase64: logo,\n title: title,\n subtitle: subtitle,\n });\n const pdfBuffer = pdfDoc.output(\"arraybuffer\");\n return convertToBuffer(await appendPdfDocs([cover, pdfBuffer]));\n } else {\n throw new Error(\"Worksheet not found in the workbook\");\n }\n};\n\nexport const pdfmakeDocumentToPdfData = async (\n documentDefinition: Record<string, unknown>,\n context?: Partial<PdfMakeConverterContext>,\n): Promise<Buffer> => {\n // Register adapters\n const registry = createAdapterRegistry();\n registry.register(\"table\", dataTableAdapter());\n\n // Pre-process document with adapters\n let processedDoc = await preProcessPdfMakeDocument(\n documentDefinition,\n registry,\n context,\n );\n\n processedDoc = (await registry.process(\n documentDefinition,\n context,\n )) as Record<string, unknown>;\n\n // Render the document using pdfmake\n return renderPdfMakeDocument(processedDoc as unknown as TDocumentDefinitions);\n};\n\n/**\n * Unisce più PDF (in formato ArrayBuffer/Uint8Array/Buffer) in un unico PDF.\n * @param pdfBuffers Array di buffer PDF (es. ottenuti da jsPDF.output(\"arraybuffer\"))\n * @returns Buffer del PDF unito\n */\nconst appendPdfDocs = async (\n pdfBuffers: (Uint8Array | ArrayBuffer | Buffer)[],\n): Promise<Uint8Array> => {\n if (!pdfBuffers.length) throw new Error(\"No PDF buffers to append\");\n\n // Crea un nuovo documento PDF vuoto\n const mergedPdf = await PDFDocument.create();\n\n for (const pdfBytes of pdfBuffers) {\n const srcPdf = await PDFDocument.load(pdfBytes);\n const copiedPages = await mergedPdf.copyPages(\n srcPdf,\n srcPdf.getPageIndices(),\n );\n copiedPages.forEach(page => mergedPdf.addPage(page));\n }\n\n const mergedBytes = await mergedPdf.save();\n return mergedBytes;\n};\n\n// Re-export form filler function and types\nexport { fillPdfForm };\nexport type { FillPdfFormOptions };\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
export { dataTableToExcelData, dataTreeToExcelData, } from "./converters/excel-converter";
|
|
2
|
-
export { schedaToPdfData, dataTableToPdfData, } from "./converters/pdf-converter";
|
|
2
|
+
export { schedaToPdfData, dataTableToPdfData, pdfmakeDocumentToPdfData, fillPdfForm, } from "./converters/pdf-converter";
|
|
3
|
+
export type { FillPdfFormOptions } from "./converters/pdf-converter";
|
|
3
4
|
export { dataTableToChart } from "./converters/images/charts-generator";
|
|
5
|
+
export { createAdapterRegistry } from "./converters/pdf/pdfmake/adapter-registry";
|
|
6
|
+
export { funToSmeupTableAdapter } from "./converters/pdf/pdfmake/table-adapter";
|
|
7
|
+
export { smeupTableToPdfMakeTableAdapter } from "./converters/pdf/pdfmake/table-adapter";
|
|
8
|
+
export { preProcessPdfMakeDocument } from "./converters/pdf/pdfmake/adapter-processor";
|
|
9
|
+
export type { PdfmakeAdapter, PdfMakeConverterContext, AdapterRegistry, AdapterError, } from "./converters/pdf/pdfmake/pdfmake.types";
|
|
4
10
|
export type { WebupManagerData, GenericObject } from "./types/index";
|
|
5
11
|
export { SupportedExportFormats } from "./types/index";
|
|
6
12
|
export type { SmeupDataTable } from "./types/data-structures/smeupDataTable";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SupportedExportFormats = exports.dataTableToChart = exports.dataTableToPdfData = exports.schedaToPdfData = exports.dataTreeToExcelData = exports.dataTableToExcelData = void 0;
|
|
3
|
+
exports.SupportedExportFormats = exports.preProcessPdfMakeDocument = exports.smeupTableToPdfMakeTableAdapter = exports.funToSmeupTableAdapter = exports.createAdapterRegistry = exports.dataTableToChart = exports.fillPdfForm = exports.pdfmakeDocumentToPdfData = exports.dataTableToPdfData = exports.schedaToPdfData = exports.dataTreeToExcelData = exports.dataTableToExcelData = void 0;
|
|
4
4
|
// Public API exports
|
|
5
5
|
var excel_converter_1 = require("./converters/excel-converter");
|
|
6
6
|
Object.defineProperty(exports, "dataTableToExcelData", { enumerable: true, get: function () { return excel_converter_1.dataTableToExcelData; } });
|
|
@@ -8,8 +8,19 @@ Object.defineProperty(exports, "dataTreeToExcelData", { enumerable: true, get: f
|
|
|
8
8
|
var pdf_converter_1 = require("./converters/pdf-converter");
|
|
9
9
|
Object.defineProperty(exports, "schedaToPdfData", { enumerable: true, get: function () { return pdf_converter_1.schedaToPdfData; } });
|
|
10
10
|
Object.defineProperty(exports, "dataTableToPdfData", { enumerable: true, get: function () { return pdf_converter_1.dataTableToPdfData; } });
|
|
11
|
+
Object.defineProperty(exports, "pdfmakeDocumentToPdfData", { enumerable: true, get: function () { return pdf_converter_1.pdfmakeDocumentToPdfData; } });
|
|
12
|
+
Object.defineProperty(exports, "fillPdfForm", { enumerable: true, get: function () { return pdf_converter_1.fillPdfForm; } });
|
|
11
13
|
var charts_generator_1 = require("./converters/images/charts-generator");
|
|
12
14
|
Object.defineProperty(exports, "dataTableToChart", { enumerable: true, get: function () { return charts_generator_1.dataTableToChart; } });
|
|
15
|
+
// Pdfmake adapter system
|
|
16
|
+
var adapter_registry_1 = require("./converters/pdf/pdfmake/adapter-registry");
|
|
17
|
+
Object.defineProperty(exports, "createAdapterRegistry", { enumerable: true, get: function () { return adapter_registry_1.createAdapterRegistry; } });
|
|
18
|
+
var table_adapter_1 = require("./converters/pdf/pdfmake/table-adapter");
|
|
19
|
+
Object.defineProperty(exports, "funToSmeupTableAdapter", { enumerable: true, get: function () { return table_adapter_1.funToSmeupTableAdapter; } });
|
|
20
|
+
var table_adapter_2 = require("./converters/pdf/pdfmake/table-adapter");
|
|
21
|
+
Object.defineProperty(exports, "smeupTableToPdfMakeTableAdapter", { enumerable: true, get: function () { return table_adapter_2.smeupTableToPdfMakeTableAdapter; } });
|
|
22
|
+
var adapter_processor_1 = require("./converters/pdf/pdfmake/adapter-processor");
|
|
23
|
+
Object.defineProperty(exports, "preProcessPdfMakeDocument", { enumerable: true, get: function () { return adapter_processor_1.preProcessPdfMakeDocument; } });
|
|
13
24
|
var index_1 = require("./types/index");
|
|
14
25
|
Object.defineProperty(exports, "SupportedExportFormats", { enumerable: true, get: function () { return index_1.SupportedExportFormats; } });
|
|
15
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qBAAqB;AACrB,gEAGsC;AAFpC,uHAAA,oBAAoB,OAAA;AACpB,sHAAA,mBAAmB,OAAA;AAGrB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qBAAqB;AACrB,gEAGsC;AAFpC,uHAAA,oBAAoB,OAAA;AACpB,sHAAA,mBAAmB,OAAA;AAGrB,4DAKoC;AAJlC,gHAAA,eAAe,OAAA;AACf,mHAAA,kBAAkB,OAAA;AAClB,yHAAA,wBAAwB,OAAA;AACxB,4GAAA,WAAW,OAAA;AAIb,yEAAwE;AAA/D,oHAAA,gBAAgB,OAAA;AAEzB,yBAAyB;AACzB,8EAAkF;AAAzE,yHAAA,qBAAqB,OAAA;AAC9B,wEAAgF;AAAvE,uHAAA,sBAAsB,OAAA;AAC/B,wEAAyF;AAAhF,gIAAA,+BAA+B,OAAA;AACxC,gFAAuF;AAA9E,8HAAA,yBAAyB,OAAA;AAWlC,uCAAuD;AAA9C,+GAAA,sBAAsB,OAAA","sourcesContent":["// Public API exports\nexport {\n dataTableToExcelData,\n dataTreeToExcelData,\n} from \"./converters/excel-converter\";\n\nexport {\n schedaToPdfData,\n dataTableToPdfData,\n pdfmakeDocumentToPdfData,\n fillPdfForm,\n} from \"./converters/pdf-converter\";\nexport type { FillPdfFormOptions } from \"./converters/pdf-converter\";\n\nexport { dataTableToChart } from \"./converters/images/charts-generator\";\n\n// Pdfmake adapter system\nexport { createAdapterRegistry } from \"./converters/pdf/pdfmake/adapter-registry\";\nexport { funToSmeupTableAdapter } from \"./converters/pdf/pdfmake/table-adapter\";\nexport { smeupTableToPdfMakeTableAdapter } from \"./converters/pdf/pdfmake/table-adapter\";\nexport { preProcessPdfMakeDocument } from \"./converters/pdf/pdfmake/adapter-processor\";\n\nexport type {\n PdfmakeAdapter,\n PdfMakeConverterContext,\n AdapterRegistry,\n AdapterError,\n} from \"./converters/pdf/pdfmake/pdfmake.types\";\n\n// Export types that users might need\nexport type { WebupManagerData, GenericObject } from \"./types/index\";\nexport { SupportedExportFormats } from \"./types/index\";\nexport type { SmeupDataTable } from \"./types/data-structures/smeupDataTable\";\nexport type { SmeupDataTree } from \"./types/data-structures/smeupDataTree\";\n\nexport type ColumnGroup = {\n column: string;\n visible: boolean;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sme.up/doc-alchemist",
|
|
3
|
-
"version": "1.5.0-SNAPSHOT-
|
|
3
|
+
"version": "1.5.0-SNAPSHOT-20251121152517",
|
|
4
4
|
"description": "Library for generating documents in various formats, including Excel and PDF.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Smeup LAB <info@smeup.com> (https://www.smeup.com/)",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"@eslint/js": "^9.28.0",
|
|
25
25
|
"@types/jest": "^29.5.14",
|
|
26
26
|
"@types/node": "^22.15.30",
|
|
27
|
+
"@types/pdfmake": "^0.2.12",
|
|
27
28
|
"csstype": "^3.1.3",
|
|
28
29
|
"eslint": "^9.28.0",
|
|
29
30
|
"globals": "^16.2.0",
|
|
@@ -44,6 +45,7 @@
|
|
|
44
45
|
"jspdf": "^3.0.1",
|
|
45
46
|
"jspdf-autotable": "^5.0.2",
|
|
46
47
|
"math-expression-evaluator": "^2.0.7",
|
|
47
|
-
"pdf-lib": "^1.17.1"
|
|
48
|
+
"pdf-lib": "^1.17.1",
|
|
49
|
+
"pdfmake": "^0.2.20"
|
|
48
50
|
}
|
|
49
|
-
}
|
|
51
|
+
}
|