emilsoftware-utilities 1.3.50 → 1.3.52
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/ContractGenerator.d.ts +228 -0
- package/dist/ContractGenerator.js +388 -0
- package/dist/accessi-module/AccessiController.d.ts +11 -11
- package/dist/accessi-module/AccessiControllerBase.d.ts +11 -11
- package/dist/accessi-module/AccessiRoutes.js +12 -12
- package/dist/accessi-module/index.d.ts +1 -0
- package/dist/accessi-module/inversify.config.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/tests/contract/test.d.ts +1 -0
- package/dist/tests/contract/test.js +59 -0
- package/package.json +7 -3
- package/dist/logger.d.ts +0 -35
- package/dist/logger.js +0 -283
- package/dist/orm.d.ts +0 -18
- package/dist/orm.js +0 -384
- package/dist/utilities.d.ts +0 -114
- package/dist/utilities.js +0 -245
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface representing the contract parties.
|
|
3
|
+
*/
|
|
4
|
+
export interface IPartiContratto {
|
|
5
|
+
fornitore: {
|
|
6
|
+
denominazione: string;
|
|
7
|
+
codiceFiscale: string;
|
|
8
|
+
indirizzoCompleto: string;
|
|
9
|
+
};
|
|
10
|
+
cliente: {
|
|
11
|
+
denominazione: string;
|
|
12
|
+
codiceFiscale: string;
|
|
13
|
+
indirizzoCompleto: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parameters passed by the user when generating a document.
|
|
18
|
+
*/
|
|
19
|
+
export interface DocumentParams {
|
|
20
|
+
parti: IPartiContratto;
|
|
21
|
+
tipOutput?: 'f' | 'd' | 'u';
|
|
22
|
+
dynamicFields?: {
|
|
23
|
+
[key: string]: string;
|
|
24
|
+
};
|
|
25
|
+
dynamicElements?: {
|
|
26
|
+
[placeholder: string]: DynamicElement;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* DynamicElement supports different types, currently "table".
|
|
31
|
+
*/
|
|
32
|
+
export type DynamicElement = {
|
|
33
|
+
type: 'table';
|
|
34
|
+
config: {
|
|
35
|
+
head: string[];
|
|
36
|
+
body: string[][];
|
|
37
|
+
options?: any;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* A simplified type for the configuration file.
|
|
42
|
+
*/
|
|
43
|
+
interface DocumentConfig {
|
|
44
|
+
fontTitolo: {
|
|
45
|
+
nome: string;
|
|
46
|
+
dimensione: number;
|
|
47
|
+
colore: string;
|
|
48
|
+
installPath?: string;
|
|
49
|
+
};
|
|
50
|
+
fontSottotitolo: {
|
|
51
|
+
nome: string;
|
|
52
|
+
dimensione: number;
|
|
53
|
+
colore: string;
|
|
54
|
+
installPath?: string;
|
|
55
|
+
};
|
|
56
|
+
fontTesto: {
|
|
57
|
+
nome: string;
|
|
58
|
+
dimensione: number;
|
|
59
|
+
colore: string;
|
|
60
|
+
installPath?: string;
|
|
61
|
+
};
|
|
62
|
+
margini: {
|
|
63
|
+
sx: number;
|
|
64
|
+
dx: number;
|
|
65
|
+
alto: number;
|
|
66
|
+
basso: number;
|
|
67
|
+
};
|
|
68
|
+
staccoriga: number;
|
|
69
|
+
rientro: number;
|
|
70
|
+
testi: {
|
|
71
|
+
titolo: string;
|
|
72
|
+
premessa: string;
|
|
73
|
+
Punti: Array<{
|
|
74
|
+
titolo: string;
|
|
75
|
+
Sottopunti: Array<{
|
|
76
|
+
titolo: string;
|
|
77
|
+
contenuto: string;
|
|
78
|
+
}>;
|
|
79
|
+
}>;
|
|
80
|
+
versione: string;
|
|
81
|
+
};
|
|
82
|
+
immagini: Array<{
|
|
83
|
+
path: string;
|
|
84
|
+
posizione: [number, number];
|
|
85
|
+
dimensioni: [number, number];
|
|
86
|
+
coeffDim?: number;
|
|
87
|
+
}>;
|
|
88
|
+
box: {
|
|
89
|
+
backgrund: string;
|
|
90
|
+
raggio: number;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* DocumentGenerator encapsulates the PDF generation logic.
|
|
95
|
+
* It handles text wrapping, dynamic placeholders, image insertion, custom font installation,
|
|
96
|
+
* and rendering text inside a rounded rectangle box or as bold text.
|
|
97
|
+
*/
|
|
98
|
+
export declare class DocumentGenerator {
|
|
99
|
+
private configPath?;
|
|
100
|
+
private config;
|
|
101
|
+
private doc;
|
|
102
|
+
private curX;
|
|
103
|
+
private curY;
|
|
104
|
+
private configLoaded;
|
|
105
|
+
/**
|
|
106
|
+
* Constructor for DocumentGenerator.
|
|
107
|
+
* @param configPath - Optional path to the JSON configuration file.
|
|
108
|
+
*/
|
|
109
|
+
constructor(configPath?: string);
|
|
110
|
+
/**
|
|
111
|
+
* Sets the configuration directly.
|
|
112
|
+
* @param config - The DocumentConfig object.
|
|
113
|
+
*/
|
|
114
|
+
setConfig(config: DocumentConfig): void;
|
|
115
|
+
/**
|
|
116
|
+
* Applies dynamic text templating by replacing markers like $KEY$ with their values.
|
|
117
|
+
* @param template - The template string containing markers.
|
|
118
|
+
* @param dynamicFields - An object mapping marker keys to replacement values.
|
|
119
|
+
* @returns The processed string with replacements.
|
|
120
|
+
*/
|
|
121
|
+
private applyTemplate;
|
|
122
|
+
/**
|
|
123
|
+
* Replaces party-specific placeholders (e.g., $cliente:denominazione$) with corresponding values.
|
|
124
|
+
* @param text - The text containing party placeholders.
|
|
125
|
+
* @param parti - The contract parties.
|
|
126
|
+
* @returns The processed string with party-specific values.
|
|
127
|
+
*/
|
|
128
|
+
private applyPartiPlaceholders;
|
|
129
|
+
/**
|
|
130
|
+
* Loads the configuration JSON from the local filesystem.
|
|
131
|
+
* @throws Error if the configuration file cannot be read.
|
|
132
|
+
*/
|
|
133
|
+
private loadConfig;
|
|
134
|
+
/**
|
|
135
|
+
* Initializes the jsPDF document and sets the cursor to the top-left margin.
|
|
136
|
+
*/
|
|
137
|
+
private initDoc;
|
|
138
|
+
/**
|
|
139
|
+
* Extracts a dynamic element placeholder from text if it is in the form "$PLACEHOLDER$".
|
|
140
|
+
* @param text - The text to check.
|
|
141
|
+
* @returns The placeholder key or null if not found.
|
|
142
|
+
*/
|
|
143
|
+
private extractPlaceholder;
|
|
144
|
+
/**
|
|
145
|
+
* Installs a custom font into jsPDF by reading the font file and adding it to the Virtual File System.
|
|
146
|
+
* @param fontPath - Path to the TTF font file.
|
|
147
|
+
* @param fontName - Name of the font to be used in jsPDF.
|
|
148
|
+
*/
|
|
149
|
+
private installFont;
|
|
150
|
+
/**
|
|
151
|
+
* Core method to write wrapped text with a specified font.
|
|
152
|
+
* Handles text splitting and page-breaks.
|
|
153
|
+
* @param fontName - The name of the font to use.
|
|
154
|
+
* @param fontSize - The font size in points.
|
|
155
|
+
* @param color - The text color.
|
|
156
|
+
* @param text - The text to write.
|
|
157
|
+
* @param x - The X coordinate.
|
|
158
|
+
* @param y - The starting Y coordinate.
|
|
159
|
+
* @param maxWidth - Maximum width for text wrapping.
|
|
160
|
+
* @param lineSpacingFactor - Factor for line spacing.
|
|
161
|
+
* @returns The updated Y position after writing the text.
|
|
162
|
+
*/
|
|
163
|
+
private writeWrappedTextCore;
|
|
164
|
+
/**
|
|
165
|
+
* Writes wrapped text using a custom font.
|
|
166
|
+
* Ensures the font is installed before writing.
|
|
167
|
+
* @param fontConf - Font configuration object.
|
|
168
|
+
* @param text - The text to write.
|
|
169
|
+
* @param x - The X coordinate.
|
|
170
|
+
* @param y - The starting Y coordinate.
|
|
171
|
+
* @param maxWidth - Maximum width for text wrapping.
|
|
172
|
+
* @param lineSpacingFactor - Factor for line spacing.
|
|
173
|
+
*/
|
|
174
|
+
private writeWrappedTextWithFont;
|
|
175
|
+
/**
|
|
176
|
+
* Renders text inside a rounded rectangle box.
|
|
177
|
+
* This method is invoked when text is wrapped in '^' markers.
|
|
178
|
+
* @param text - The text to render (without '^' markers).
|
|
179
|
+
* @param fontConf - Font configuration for the text.
|
|
180
|
+
* @param padding - Padding inside the box.
|
|
181
|
+
* @param borderRadius - Corner radius of the box.
|
|
182
|
+
* @param borderWidth - Border thickness.
|
|
183
|
+
* @param boxColor - Optional background color.
|
|
184
|
+
*/
|
|
185
|
+
scriveTestoBox(text: string, fontConf: {
|
|
186
|
+
nome: string;
|
|
187
|
+
dimensione: number;
|
|
188
|
+
colore: string;
|
|
189
|
+
installPath?: string;
|
|
190
|
+
}, padding?: number, borderRadius?: number, borderWidth?: number, boxColor?: string): Promise<void>;
|
|
191
|
+
/**
|
|
192
|
+
* Checks if a given text is wrapped in '^' markers, indicating it should be rendered in a box.
|
|
193
|
+
* @param text - The text to check.
|
|
194
|
+
* @returns True if text is boxed.
|
|
195
|
+
*/
|
|
196
|
+
private isBoxedText;
|
|
197
|
+
/**
|
|
198
|
+
* Removes the '^' markers from the text.
|
|
199
|
+
* @param text - The boxed text.
|
|
200
|
+
* @returns The text without '^' markers.
|
|
201
|
+
*/
|
|
202
|
+
private stripBoxMarkers;
|
|
203
|
+
/**
|
|
204
|
+
* Checks if a given text is wrapped in '**' markers, indicating bold formatting.
|
|
205
|
+
* @param text - The text to check.
|
|
206
|
+
* @returns True if text is marked as bold.
|
|
207
|
+
*/
|
|
208
|
+
private isBoldText;
|
|
209
|
+
/**
|
|
210
|
+
* Removes the '**' markers from bold text.
|
|
211
|
+
* @param text - The bold text.
|
|
212
|
+
* @returns The text without '**' markers.
|
|
213
|
+
*/
|
|
214
|
+
private stripBoldMarkers;
|
|
215
|
+
/**
|
|
216
|
+
* Inserts images as defined in the configuration.
|
|
217
|
+
* Uses the current cursor position for placement.
|
|
218
|
+
*/
|
|
219
|
+
private inserisciImmagini;
|
|
220
|
+
/**
|
|
221
|
+
* Generates the PDF document based on provided parameters.
|
|
222
|
+
* Processes dynamic fields, images, tables, and text (with optional boxed or bold formatting).
|
|
223
|
+
* Returns the file name if saved or an ArrayBuffer.
|
|
224
|
+
* @param params - The DocumentParams object.
|
|
225
|
+
*/
|
|
226
|
+
generateDocument(params: DocumentParams): Promise<string | ArrayBuffer>;
|
|
227
|
+
}
|
|
228
|
+
export {};
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.DocumentGenerator = void 0;
|
|
16
|
+
const jspdf_1 = require("jspdf");
|
|
17
|
+
const jspdf_autotable_1 = __importDefault(require("jspdf-autotable"));
|
|
18
|
+
const fs_1 = require("fs");
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
/**
|
|
21
|
+
* Reads an image file from the filesystem and returns a Base64-encoded data URL.
|
|
22
|
+
* @param imagePath - Path to the image file.
|
|
23
|
+
* @returns The Base64-encoded data URL of the image.
|
|
24
|
+
*/
|
|
25
|
+
function loadImageAsBase64(imagePath) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
const absolutePath = path_1.default.resolve(imagePath);
|
|
28
|
+
const buffer = yield fs_1.promises.readFile(absolutePath);
|
|
29
|
+
const ext = path_1.default.extname(imagePath).slice(1).toLowerCase();
|
|
30
|
+
const base64 = buffer.toString('base64');
|
|
31
|
+
return `data:image/${ext};base64,${base64}`;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* DocumentGenerator encapsulates the PDF generation logic.
|
|
36
|
+
* It handles text wrapping, dynamic placeholders, image insertion, custom font installation,
|
|
37
|
+
* and rendering text inside a rounded rectangle box or as bold text.
|
|
38
|
+
*/
|
|
39
|
+
class DocumentGenerator {
|
|
40
|
+
/**
|
|
41
|
+
* Constructor for DocumentGenerator.
|
|
42
|
+
* @param configPath - Optional path to the JSON configuration file.
|
|
43
|
+
*/
|
|
44
|
+
constructor(configPath) {
|
|
45
|
+
this.configPath = configPath;
|
|
46
|
+
this.curX = 0;
|
|
47
|
+
this.curY = 0;
|
|
48
|
+
this.configLoaded = false;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Sets the configuration directly.
|
|
52
|
+
* @param config - The DocumentConfig object.
|
|
53
|
+
*/
|
|
54
|
+
setConfig(config) {
|
|
55
|
+
this.config = config;
|
|
56
|
+
this.configLoaded = true;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Applies dynamic text templating by replacing markers like $KEY$ with their values.
|
|
60
|
+
* @param template - The template string containing markers.
|
|
61
|
+
* @param dynamicFields - An object mapping marker keys to replacement values.
|
|
62
|
+
* @returns The processed string with replacements.
|
|
63
|
+
*/
|
|
64
|
+
applyTemplate(template, dynamicFields) {
|
|
65
|
+
if (!dynamicFields)
|
|
66
|
+
return template;
|
|
67
|
+
return template.replace(/\$(\w+)\$/g, (match, key) => dynamicFields[key] !== undefined ? dynamicFields[key] : match);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Replaces party-specific placeholders (e.g., $cliente:denominazione$) with corresponding values.
|
|
71
|
+
* @param text - The text containing party placeholders.
|
|
72
|
+
* @param parti - The contract parties.
|
|
73
|
+
* @returns The processed string with party-specific values.
|
|
74
|
+
*/
|
|
75
|
+
applyPartiPlaceholders(text, parti) {
|
|
76
|
+
return text.replace(/\$(fornitore|cliente):(\w+)\$/g, (match, party, field) => {
|
|
77
|
+
return (parti[party] && parti[party][field]) ? parti[party][field] : match;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Loads the configuration JSON from the local filesystem.
|
|
82
|
+
* @throws Error if the configuration file cannot be read.
|
|
83
|
+
*/
|
|
84
|
+
loadConfig() {
|
|
85
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
if (this.configLoaded)
|
|
87
|
+
return;
|
|
88
|
+
if (!this.configPath)
|
|
89
|
+
throw new Error("No configuration provided. Set a configPath or use setConfig().");
|
|
90
|
+
try {
|
|
91
|
+
const data = yield fs_1.promises.readFile(this.configPath, 'utf8');
|
|
92
|
+
this.config = JSON.parse(data);
|
|
93
|
+
this.configLoaded = true;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw new Error(`Error reading configuration file: ${error}`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Initializes the jsPDF document and sets the cursor to the top-left margin.
|
|
102
|
+
*/
|
|
103
|
+
initDoc() {
|
|
104
|
+
this.doc = new jspdf_1.jsPDF();
|
|
105
|
+
const margins = this.config.margini;
|
|
106
|
+
this.curX = margins.sx;
|
|
107
|
+
this.curY = margins.alto;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Extracts a dynamic element placeholder from text if it is in the form "$PLACEHOLDER$".
|
|
111
|
+
* @param text - The text to check.
|
|
112
|
+
* @returns The placeholder key or null if not found.
|
|
113
|
+
*/
|
|
114
|
+
extractPlaceholder(text) {
|
|
115
|
+
const match = text.match(/^\$(\w+)\$$/);
|
|
116
|
+
return match ? match[1] : null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Installs a custom font into jsPDF by reading the font file and adding it to the Virtual File System.
|
|
120
|
+
* @param fontPath - Path to the TTF font file.
|
|
121
|
+
* @param fontName - Name of the font to be used in jsPDF.
|
|
122
|
+
*/
|
|
123
|
+
installFont(fontPath, fontName) {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
const absolutePath = path_1.default.resolve(fontPath);
|
|
126
|
+
const buffer = yield fs_1.promises.readFile(absolutePath);
|
|
127
|
+
const base64Font = buffer.toString('base64');
|
|
128
|
+
console.log(`Installing font ${fontName} from ${absolutePath}`);
|
|
129
|
+
this.doc.addFileToVFS(`${fontName}.ttf`, base64Font);
|
|
130
|
+
this.doc.addFont(`${fontName}.ttf`, fontName, 'normal');
|
|
131
|
+
this.doc.setFont(fontName);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Core method to write wrapped text with a specified font.
|
|
136
|
+
* Handles text splitting and page-breaks.
|
|
137
|
+
* @param fontName - The name of the font to use.
|
|
138
|
+
* @param fontSize - The font size in points.
|
|
139
|
+
* @param color - The text color.
|
|
140
|
+
* @param text - The text to write.
|
|
141
|
+
* @param x - The X coordinate.
|
|
142
|
+
* @param y - The starting Y coordinate.
|
|
143
|
+
* @param maxWidth - Maximum width for text wrapping.
|
|
144
|
+
* @param lineSpacingFactor - Factor for line spacing.
|
|
145
|
+
* @returns The updated Y position after writing the text.
|
|
146
|
+
*/
|
|
147
|
+
writeWrappedTextCore(fontName_1, fontSize_1, color_1, text_1, x_1, y_1, maxWidth_1) {
|
|
148
|
+
return __awaiter(this, arguments, void 0, function* (fontName, fontSize, color, text, x, y, maxWidth, lineSpacingFactor = 1.15) {
|
|
149
|
+
this.doc.setFont(fontName);
|
|
150
|
+
this.doc.setFontSize(fontSize);
|
|
151
|
+
this.doc.setTextColor(color);
|
|
152
|
+
const lines = this.doc.splitTextToSize(text, maxWidth);
|
|
153
|
+
const lineHeight = (fontSize * lineSpacingFactor / 72) * 25.4;
|
|
154
|
+
for (const line of lines) {
|
|
155
|
+
if (y + lineHeight > (this.doc.internal.pageSize.getHeight() - this.config.margini.basso)) {
|
|
156
|
+
this.doc.addPage();
|
|
157
|
+
y = this.config.margini.alto;
|
|
158
|
+
}
|
|
159
|
+
this.doc.text(line, x, y);
|
|
160
|
+
y += lineHeight;
|
|
161
|
+
}
|
|
162
|
+
return y;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Writes wrapped text using a custom font.
|
|
167
|
+
* Ensures the font is installed before writing.
|
|
168
|
+
* @param fontConf - Font configuration object.
|
|
169
|
+
* @param text - The text to write.
|
|
170
|
+
* @param x - The X coordinate.
|
|
171
|
+
* @param y - The starting Y coordinate.
|
|
172
|
+
* @param maxWidth - Maximum width for text wrapping.
|
|
173
|
+
* @param lineSpacingFactor - Factor for line spacing.
|
|
174
|
+
*/
|
|
175
|
+
writeWrappedTextWithFont(fontConf_1, text_1, x_1, y_1, maxWidth_1) {
|
|
176
|
+
return __awaiter(this, arguments, void 0, function* (fontConf, text, x, y, maxWidth, lineSpacingFactor = 1.15) {
|
|
177
|
+
const fontList = this.doc.getFontList();
|
|
178
|
+
if (!fontList[fontConf.nome]) {
|
|
179
|
+
if (fontConf.installPath)
|
|
180
|
+
yield this.installFont(fontConf.installPath, fontConf.nome);
|
|
181
|
+
else
|
|
182
|
+
throw new Error("Font not present and no installPath provided");
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
this.doc.setFont(fontConf.nome);
|
|
186
|
+
}
|
|
187
|
+
this.curY = yield this.writeWrappedTextCore(fontConf.nome, fontConf.dimensione, fontConf.colore, text, x, y, maxWidth, lineSpacingFactor);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Renders text inside a rounded rectangle box.
|
|
192
|
+
* This method is invoked when text is wrapped in '^' markers.
|
|
193
|
+
* @param text - The text to render (without '^' markers).
|
|
194
|
+
* @param fontConf - Font configuration for the text.
|
|
195
|
+
* @param padding - Padding inside the box.
|
|
196
|
+
* @param borderRadius - Corner radius of the box.
|
|
197
|
+
* @param borderWidth - Border thickness.
|
|
198
|
+
* @param boxColor - Optional background color.
|
|
199
|
+
*/
|
|
200
|
+
scriveTestoBox(text_1, fontConf_1) {
|
|
201
|
+
return __awaiter(this, arguments, void 0, function* (text, fontConf, padding = 5, borderRadius = 5, borderWidth = 1, boxColor) {
|
|
202
|
+
const fontList = this.doc.getFontList();
|
|
203
|
+
if (!fontList[fontConf.nome]) {
|
|
204
|
+
if (fontConf.installPath)
|
|
205
|
+
yield this.installFont(fontConf.installPath, fontConf.nome);
|
|
206
|
+
else
|
|
207
|
+
throw new Error("Font not present and no installPath provided");
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
this.doc.setFont(fontConf.nome);
|
|
211
|
+
}
|
|
212
|
+
this.doc.setFontSize(fontConf.dimensione);
|
|
213
|
+
this.doc.setTextColor(fontConf.colore);
|
|
214
|
+
const pageWidth = this.doc.internal.pageSize.getWidth();
|
|
215
|
+
const maxTextWidth = pageWidth - this.config.margini.sx - this.config.margini.dx - 2 * padding;
|
|
216
|
+
const lines = this.doc.splitTextToSize(text, maxTextWidth);
|
|
217
|
+
const lineHeight = (fontConf.dimensione * 1.15 / 72) * 25.4;
|
|
218
|
+
const textHeight = lines.length * lineHeight;
|
|
219
|
+
const boxX = this.curX;
|
|
220
|
+
const boxY = this.curY;
|
|
221
|
+
const boxWidth = maxTextWidth + 2 * padding;
|
|
222
|
+
const boxHeight = textHeight + 2 * padding;
|
|
223
|
+
if (boxColor) {
|
|
224
|
+
this.doc.setFillColor(boxColor);
|
|
225
|
+
this.doc.roundedRect(boxX, boxY, boxWidth, boxHeight, borderRadius, borderRadius, 'F');
|
|
226
|
+
}
|
|
227
|
+
this.doc.setLineWidth(borderWidth);
|
|
228
|
+
this.doc.roundedRect(boxX, boxY, boxWidth, boxHeight, borderRadius, borderRadius);
|
|
229
|
+
const textX = boxX + padding;
|
|
230
|
+
let textY = boxY + padding + lineHeight;
|
|
231
|
+
for (const line of lines) {
|
|
232
|
+
this.doc.text(line, textX, textY);
|
|
233
|
+
textY += lineHeight;
|
|
234
|
+
}
|
|
235
|
+
this.curY = boxY + boxHeight + this.config.staccoriga;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Checks if a given text is wrapped in '^' markers, indicating it should be rendered in a box.
|
|
240
|
+
* @param text - The text to check.
|
|
241
|
+
* @returns True if text is boxed.
|
|
242
|
+
*/
|
|
243
|
+
isBoxedText(text) {
|
|
244
|
+
return text.startsWith('^') && text.endsWith('^');
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Removes the '^' markers from the text.
|
|
248
|
+
* @param text - The boxed text.
|
|
249
|
+
* @returns The text without '^' markers.
|
|
250
|
+
*/
|
|
251
|
+
stripBoxMarkers(text) {
|
|
252
|
+
return text.substring(1, text.length - 1);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Checks if a given text is wrapped in '**' markers, indicating bold formatting.
|
|
256
|
+
* @param text - The text to check.
|
|
257
|
+
* @returns True if text is marked as bold.
|
|
258
|
+
*/
|
|
259
|
+
isBoldText(text) {
|
|
260
|
+
return text.startsWith('**') && text.endsWith('**');
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Removes the '**' markers from bold text.
|
|
264
|
+
* @param text - The bold text.
|
|
265
|
+
* @returns The text without '**' markers.
|
|
266
|
+
*/
|
|
267
|
+
stripBoldMarkers(text) {
|
|
268
|
+
return text.substring(2, text.length - 2);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Inserts images as defined in the configuration.
|
|
272
|
+
* Uses the current cursor position for placement.
|
|
273
|
+
*/
|
|
274
|
+
inserisciImmagini() {
|
|
275
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
276
|
+
var _a;
|
|
277
|
+
if (this.config.immagini && this.config.immagini.length > 0) {
|
|
278
|
+
const startX = this.curX;
|
|
279
|
+
for (const imgConf of this.config.immagini) {
|
|
280
|
+
const format = ((_a = imgConf.path.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'PNG';
|
|
281
|
+
const base64Image = yield loadImageAsBase64(imgConf.path);
|
|
282
|
+
const startY = this.curY;
|
|
283
|
+
if (startY + imgConf.dimensioni[1] > (this.doc.internal.pageSize.getHeight() - this.config.margini.basso)) {
|
|
284
|
+
this.doc.addPage();
|
|
285
|
+
this.curY = this.config.margini.alto;
|
|
286
|
+
}
|
|
287
|
+
this.doc.addImage(base64Image, format, startX, this.curY, imgConf.dimensioni[0], imgConf.dimensioni[1]);
|
|
288
|
+
console.log(`Image inserted at X: ${startX}, Y: ${this.curY}`);
|
|
289
|
+
this.curY = this.curY + imgConf.dimensioni[1] + this.config.staccoriga;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Generates the PDF document based on provided parameters.
|
|
296
|
+
* Processes dynamic fields, images, tables, and text (with optional boxed or bold formatting).
|
|
297
|
+
* Returns the file name if saved or an ArrayBuffer.
|
|
298
|
+
* @param params - The DocumentParams object.
|
|
299
|
+
*/
|
|
300
|
+
generateDocument(params) {
|
|
301
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
302
|
+
yield this.loadConfig();
|
|
303
|
+
this.initDoc();
|
|
304
|
+
yield this.inserisciImmagini();
|
|
305
|
+
const dynamicFields = params.dynamicFields || {};
|
|
306
|
+
const dynamicElements = params.dynamicElements || {};
|
|
307
|
+
const pageWidth = this.doc.internal.pageSize.getWidth();
|
|
308
|
+
const maxWidth = pageWidth - (this.config.margini.sx + this.config.margini.dx);
|
|
309
|
+
let titolo = this.applyTemplate(this.config.testi.titolo, dynamicFields);
|
|
310
|
+
titolo = this.applyPartiPlaceholders(titolo, params.parti);
|
|
311
|
+
yield this.writeWrappedTextWithFont(this.config.fontTitolo, titolo, this.curX, this.curY, maxWidth);
|
|
312
|
+
this.curY += this.config.staccoriga;
|
|
313
|
+
let premessa = this.applyTemplate(this.config.testi.premessa, dynamicFields);
|
|
314
|
+
premessa = this.applyPartiPlaceholders(premessa, params.parti);
|
|
315
|
+
yield this.writeWrappedTextWithFont(this.config.fontTesto, premessa, this.curX, this.curY, maxWidth);
|
|
316
|
+
this.curY += this.config.staccoriga;
|
|
317
|
+
for (const punto of this.config.testi.Punti) {
|
|
318
|
+
let puntoTitolo = this.applyTemplate(punto.titolo, dynamicFields);
|
|
319
|
+
puntoTitolo = this.applyPartiPlaceholders(puntoTitolo, params.parti);
|
|
320
|
+
yield this.writeWrappedTextWithFont(this.config.fontTitolo, puntoTitolo, this.curX, this.curY, maxWidth);
|
|
321
|
+
this.curY += this.config.staccoriga;
|
|
322
|
+
for (const sub of punto.Sottopunti) {
|
|
323
|
+
const placeholder = this.extractPlaceholder(sub.titolo);
|
|
324
|
+
if (placeholder && dynamicElements[placeholder] && dynamicElements[placeholder].type === 'table') {
|
|
325
|
+
const tableConfig = dynamicElements[placeholder].config;
|
|
326
|
+
(0, jspdf_autotable_1.default)(this.doc, Object.assign({ startY: this.curY, head: [tableConfig.head], body: tableConfig.body }, tableConfig.options));
|
|
327
|
+
this.curY = this.doc.lastAutoTable.finalY + this.config.staccoriga;
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
if (sub.titolo) {
|
|
331
|
+
let titleText = this.applyTemplate(sub.titolo, dynamicFields);
|
|
332
|
+
titleText = this.applyPartiPlaceholders(titleText, params.parti);
|
|
333
|
+
if (this.isBoxedText(titleText)) {
|
|
334
|
+
const boxText = this.stripBoxMarkers(titleText);
|
|
335
|
+
yield this.scriveTestoBox(boxText, this.config.fontSottotitolo);
|
|
336
|
+
}
|
|
337
|
+
else if (this.isBoldText(titleText)) {
|
|
338
|
+
const boldText = this.stripBoldMarkers(titleText);
|
|
339
|
+
yield this.writeWrappedTextWithFont(Object.assign(Object.assign({}, this.config.fontSottotitolo), { nome: "Montserrat-Bold" }), boldText, this.curX + this.config.rientro, this.curY, maxWidth - this.config.rientro);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
yield this.writeWrappedTextWithFont(this.config.fontSottotitolo, titleText, this.curX + this.config.rientro, this.curY, maxWidth - this.config.rientro);
|
|
343
|
+
}
|
|
344
|
+
this.curY += this.config.staccoriga;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
const contentPlaceholder = this.extractPlaceholder(sub.contenuto);
|
|
348
|
+
if (contentPlaceholder && dynamicElements[contentPlaceholder] && dynamicElements[contentPlaceholder].type === 'table') {
|
|
349
|
+
const tableConfig = dynamicElements[contentPlaceholder].config;
|
|
350
|
+
(0, jspdf_autotable_1.default)(this.doc, Object.assign({ startY: this.curY, head: [tableConfig.head], body: tableConfig.body }, tableConfig.options));
|
|
351
|
+
this.curY = this.doc.lastAutoTable.finalY + this.config.staccoriga;
|
|
352
|
+
}
|
|
353
|
+
else if (sub.contenuto) {
|
|
354
|
+
let contenuto = this.applyTemplate(sub.contenuto, dynamicFields);
|
|
355
|
+
contenuto = this.applyPartiPlaceholders(contenuto, params.parti);
|
|
356
|
+
if (this.isBoxedText(contenuto)) {
|
|
357
|
+
const boxText = this.stripBoxMarkers(contenuto);
|
|
358
|
+
yield this.scriveTestoBox(boxText, this.config.fontTesto);
|
|
359
|
+
}
|
|
360
|
+
else if (this.isBoldText(contenuto)) {
|
|
361
|
+
const boldText = this.stripBoldMarkers(contenuto);
|
|
362
|
+
yield this.writeWrappedTextWithFont(Object.assign(Object.assign({}, this.config.fontTesto), { nome: "Montserrat-Bold" }), boldText, this.curX + this.config.rientro, this.curY, maxWidth - this.config.rientro);
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
yield this.writeWrappedTextWithFont(this.config.fontTesto, contenuto, this.curX + this.config.rientro, this.curY, maxWidth - this.config.rientro);
|
|
366
|
+
}
|
|
367
|
+
this.curY += this.config.staccoriga;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
this.curY += this.config.staccoriga;
|
|
371
|
+
}
|
|
372
|
+
const tipOutput = params.tipOutput || 'd';
|
|
373
|
+
const fileName = `Documento_${params.parti.cliente.denominazione}.pdf`;
|
|
374
|
+
if (tipOutput === 'd') {
|
|
375
|
+
const pdfBuffer = this.doc.output('arraybuffer');
|
|
376
|
+
yield fs_1.promises.writeFile(fileName, Buffer.from(pdfBuffer));
|
|
377
|
+
return fileName;
|
|
378
|
+
}
|
|
379
|
+
else if (tipOutput === 'u') {
|
|
380
|
+
return this.doc.output('arraybuffer');
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
return this.doc.output('arraybuffer');
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
exports.DocumentGenerator = DocumentGenerator;
|
|
@@ -16,26 +16,26 @@ export declare class AccessiController implements AccessiControllerBase {
|
|
|
16
16
|
constructor(userService: IUserService, permissionService: IPermissionService, emailService: IEmailService, authService: IAuthService);
|
|
17
17
|
getUserByToken(req: Request<{}, {}, {
|
|
18
18
|
token: string;
|
|
19
|
-
}>, res: Response): Promise<Response
|
|
20
|
-
login(req: Request, res: Response): Promise<Response
|
|
21
|
-
getUsers(req: Request, res: Response): Promise<Response
|
|
22
|
-
deleteUser(req: Request, res: Response): Promise<Response
|
|
23
|
-
register(req: Request, res: Response): Promise<Response
|
|
19
|
+
}>, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
20
|
+
login(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
21
|
+
getUsers(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
22
|
+
deleteUser(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
23
|
+
register(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
24
24
|
encrypt(req: Request<{}, {}, {
|
|
25
25
|
data: string;
|
|
26
|
-
}>, res: Response): Promise<Response
|
|
26
|
+
}>, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
27
27
|
decrypt(req: Request<{}, {}, {
|
|
28
28
|
data: string;
|
|
29
|
-
}>, res: Response): Promise<Response
|
|
29
|
+
}>, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
30
30
|
resetAbilitazioni(req: Request<{}, {}, {
|
|
31
31
|
codiceUtente: string;
|
|
32
|
-
}>, res: Response): Promise<Response
|
|
32
|
+
}>, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
33
33
|
setPassword(req: Request<{}, {}, {
|
|
34
34
|
codiceUtente: string;
|
|
35
35
|
nuovaPassword: string;
|
|
36
|
-
}>, res: Response): Promise<Response
|
|
37
|
-
updateUtente(req: Request, res: Response): Promise<Response
|
|
36
|
+
}>, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
37
|
+
updateUtente(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
38
38
|
setGdpr(req: Request<{}, {}, {
|
|
39
39
|
codiceUtente: string;
|
|
40
|
-
}>, res: Response): Promise<Response
|
|
40
|
+
}>, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
41
41
|
}
|