@shad0wz7/nestjs-pdf 3.0.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -6
- package/dist/index.cjs +665 -1494
- package/dist/index.d.cts +163 -54
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +163 -54
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +656 -1520
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -21
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { PDFArray, PDFDict, PDFDocument, PDFName, PDFNumber, PDFString } from "pdf-lib";
|
|
1
|
+
import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
2
|
+
import { Inject, Injectable, Logger, Module, Optional } from "@nestjs/common";
|
|
3
|
+
import { PDFArray, PDFDict, PDFDocument, PDFName, PDFNumber, PDFString, StandardFonts, degrees, rgb } from "pdf-lib";
|
|
5
4
|
import { deepmerge } from "deepmerge-ts";
|
|
5
|
+
import { lookup } from "node:dns/promises";
|
|
6
6
|
import { existsSync, promises, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { BlockList, isIP } from "node:net";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { TargetType, launch } from "puppeteer";
|
|
10
|
+
import { Browser as Browser$1, BrowserPlatform, canDownload, detectBrowserPlatform, getInstalledBrowsers, install, resolveBuildId } from "@puppeteer/browsers";
|
|
9
11
|
import ejs from "ejs";
|
|
10
12
|
import { Eta } from "eta";
|
|
11
13
|
import Handlebars from "handlebars";
|
|
@@ -13,35 +15,78 @@ import mjml from "mjml";
|
|
|
13
15
|
import mustache from "mustache";
|
|
14
16
|
import nunjucks from "nunjucks";
|
|
15
17
|
import pug from "pug";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
var
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
34
|
-
get: ((k) => from[k]).bind(null, key),
|
|
35
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
36
|
-
});
|
|
18
|
+
//#region src/exceptions/nestjs-pdf.exception.ts
|
|
19
|
+
let NestjsPdfErrorCode = /* @__PURE__ */ function(NestjsPdfErrorCode) {
|
|
20
|
+
NestjsPdfErrorCode["ENGINE_NOT_AVAILABLE"] = "ENGINE_NOT_AVAILABLE";
|
|
21
|
+
NestjsPdfErrorCode["TEMPLATE_CONFIGURATION_ERROR"] = "TEMPLATE_CONFIGURATION_ERROR";
|
|
22
|
+
NestjsPdfErrorCode["TEMPLATE_RENDER_ERROR"] = "TEMPLATE_RENDER_ERROR";
|
|
23
|
+
NestjsPdfErrorCode["BROWSER_INSTALLATION_ERROR"] = "BROWSER_INSTALLATION_ERROR";
|
|
24
|
+
NestjsPdfErrorCode["BROWSER_UNAVAILABLE"] = "BROWSER_UNAVAILABLE";
|
|
25
|
+
NestjsPdfErrorCode["PDF_GENERATION_ERROR"] = "PDF_GENERATION_ERROR";
|
|
26
|
+
NestjsPdfErrorCode["SIGNATURE_DEPENDENCY_ERROR"] = "SIGNATURE_DEPENDENCY_ERROR";
|
|
27
|
+
NestjsPdfErrorCode["SIGNATURE_PLACEMENT_ERROR"] = "SIGNATURE_PLACEMENT_ERROR";
|
|
28
|
+
NestjsPdfErrorCode["WATERMARK_ERROR"] = "WATERMARK_ERROR";
|
|
29
|
+
return NestjsPdfErrorCode;
|
|
30
|
+
}({});
|
|
31
|
+
var NestjsPdfException = class extends Error {
|
|
32
|
+
constructor(message, options) {
|
|
33
|
+
super(message, options);
|
|
34
|
+
this.name = this.constructor.name;
|
|
37
35
|
}
|
|
38
|
-
return to;
|
|
39
36
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/exceptions/browser-installation.exception.ts
|
|
39
|
+
var BrowserInstallationException = class extends NestjsPdfException {
|
|
40
|
+
code = "BROWSER_INSTALLATION_ERROR";
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/exceptions/browser-unavailable.exception.ts
|
|
44
|
+
var BrowserUnavailableException = class extends NestjsPdfException {
|
|
45
|
+
code = "BROWSER_UNAVAILABLE";
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/exceptions/engine-not-available.exception.ts
|
|
49
|
+
var EngineNotAvailableException = class extends NestjsPdfException {
|
|
50
|
+
code = "ENGINE_NOT_AVAILABLE";
|
|
51
|
+
constructor(engineName) {
|
|
52
|
+
super(`${engineName} service is not available. If the problem persists, open an issue in the repo.`);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/exceptions/pdf-generation.exception.ts
|
|
57
|
+
var PdfGenerationException = class extends NestjsPdfException {
|
|
58
|
+
code = "PDF_GENERATION_ERROR";
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/exceptions/signature-dependency.exception.ts
|
|
62
|
+
var SignatureDependencyException = class extends NestjsPdfException {
|
|
63
|
+
code = "SIGNATURE_DEPENDENCY_ERROR";
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/exceptions/signature-placement.exception.ts
|
|
67
|
+
var SignaturePlacementException = class extends NestjsPdfException {
|
|
68
|
+
code = "SIGNATURE_PLACEMENT_ERROR";
|
|
69
|
+
};
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/exceptions/template-configuration.exception.ts
|
|
72
|
+
var TemplateConfigurationException = class extends NestjsPdfException {
|
|
73
|
+
code = "TEMPLATE_CONFIGURATION_ERROR";
|
|
74
|
+
};
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/exceptions/template-render.exception.ts
|
|
77
|
+
var TemplateRenderException = class extends NestjsPdfException {
|
|
78
|
+
engine;
|
|
79
|
+
code = "TEMPLATE_RENDER_ERROR";
|
|
80
|
+
constructor(engine, message, options) {
|
|
81
|
+
super(message, options);
|
|
82
|
+
this.engine = engine;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/exceptions/watermark.exception.ts
|
|
87
|
+
var WatermarkException = class extends NestjsPdfException {
|
|
88
|
+
code = "WATERMARK_ERROR";
|
|
89
|
+
};
|
|
45
90
|
//#endregion
|
|
46
91
|
//#region src/helpers/getRelativePath.helper.ts
|
|
47
92
|
/**
|
|
@@ -65,14 +110,12 @@ async function loadPdfjs() {
|
|
|
65
110
|
pdfjsPromise = await import("pdfjs-dist/legacy/build/pdf.mjs");
|
|
66
111
|
} catch (error) {
|
|
67
112
|
pdfjsPromise = void 0;
|
|
68
|
-
|
|
69
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
70
|
-
throw new Error([
|
|
113
|
+
throw new SignatureDependencyException([
|
|
71
114
|
"Failed to load pdfjs-dist.",
|
|
72
115
|
"If you use anchor-based signature placement in Node.js, make sure @napi-rs/canvas is installed.",
|
|
73
116
|
"Try: npm install @napi-rs/canvas",
|
|
74
117
|
"",
|
|
75
|
-
`Original error: ${
|
|
118
|
+
`Original error: ${error instanceof Error ? error.message : String(error)}`
|
|
76
119
|
].join("\n"), { cause: error });
|
|
77
120
|
}
|
|
78
121
|
return pdfjsPromise;
|
|
@@ -170,7 +213,7 @@ async function addSignatureFieldUsingAnchor(pdf, fieldName = "SignatureDebtor",
|
|
|
170
213
|
if (anchor) {
|
|
171
214
|
const pageIndex = anchor.pageIndex;
|
|
172
215
|
const page = pdfDoc.getPages()[pageIndex];
|
|
173
|
-
if (!page) throw new
|
|
216
|
+
if (!page) throw new SignaturePlacementException(`Page ${pageIndex} not found`);
|
|
174
217
|
const { width: pw, height: ph } = page.getSize();
|
|
175
218
|
const padX = 40;
|
|
176
219
|
const padY = 7;
|
|
@@ -191,7 +234,7 @@ async function addSignatureFieldUsingAnchor(pdf, fieldName = "SignatureDebtor",
|
|
|
191
234
|
const pageIndex = pages.length - 1;
|
|
192
235
|
const page = pages.at(-1);
|
|
193
236
|
/* v8 ignore next -- pdf-lib always produces at least one page on save/load; only a hand-crafted, malformed PDF could hit this */
|
|
194
|
-
if (!page) throw new
|
|
237
|
+
if (!page) throw new SignaturePlacementException(`Page ${pageIndex} not found`);
|
|
195
238
|
const { width: pageWidth } = page.getSize();
|
|
196
239
|
addSignatureFieldAt(pdfDoc, pageIndex, {
|
|
197
240
|
fieldName,
|
|
@@ -204,6 +247,150 @@ async function addSignatureFieldUsingAnchor(pdf, fieldName = "SignatureDebtor",
|
|
|
204
247
|
return await pdfDoc.save();
|
|
205
248
|
}
|
|
206
249
|
//#endregion
|
|
250
|
+
//#region src/helpers/watermark.helper.ts
|
|
251
|
+
const DEFAULT_OPACITY = .15;
|
|
252
|
+
const DEFAULT_ROTATION = 45;
|
|
253
|
+
const DEFAULT_FONT_SIZE = 60;
|
|
254
|
+
const DEFAULT_FONT = "HelveticaBold";
|
|
255
|
+
const DEFAULT_COLOR = "#808080";
|
|
256
|
+
const DEFAULT_TILE_SPACING = 100;
|
|
257
|
+
function parseHexColor(color) {
|
|
258
|
+
const match = /^#([\da-f]{3}|[\da-f]{6})$/i.exec(color);
|
|
259
|
+
if (!match) throw new WatermarkException(`Invalid watermark color "${color}", expected #rgb or #rrggbb`);
|
|
260
|
+
const hex = match[1].length === 3 ? [...match[1]].map((c) => c + c).join("") : match[1];
|
|
261
|
+
const channel = (i) => Number.parseInt(hex.slice(i, i + 2), 16) / 255;
|
|
262
|
+
return rgb(channel(0), channel(2), channel(4));
|
|
263
|
+
}
|
|
264
|
+
function embedImage(pdfDoc, bytes) {
|
|
265
|
+
const isPng = bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78;
|
|
266
|
+
const isJpeg = bytes[0] === 255 && bytes[1] === 216;
|
|
267
|
+
if (isPng) return pdfDoc.embedPng(bytes);
|
|
268
|
+
if (isJpeg) return pdfDoc.embedJpg(bytes);
|
|
269
|
+
throw new WatermarkException("Watermark image must be a PNG or JPEG");
|
|
270
|
+
}
|
|
271
|
+
function validate(options) {
|
|
272
|
+
const { text, image, opacity, fontSize, imageWidth, tileSpacing } = options;
|
|
273
|
+
if (!text && !image) throw new WatermarkException("A watermark requires at least a `text` or an `image`");
|
|
274
|
+
if (opacity !== void 0 && !(opacity >= 0 && opacity <= 1)) throw new WatermarkException("Watermark `opacity` must be between 0 and 1");
|
|
275
|
+
if (fontSize !== void 0 && !(fontSize > 0)) throw new WatermarkException("Watermark `fontSize` must be greater than 0");
|
|
276
|
+
if (imageWidth !== void 0 && !(imageWidth > 0)) throw new WatermarkException("Watermark `imageWidth` must be greater than 0");
|
|
277
|
+
if (tileSpacing !== void 0 && !(tileSpacing >= 0)) throw new WatermarkException("Watermark `tileSpacing` must be at least 0");
|
|
278
|
+
}
|
|
279
|
+
function resolvePageIndexes(pages, total) {
|
|
280
|
+
if (!pages) return Array.from({ length: total }, (_, i) => i);
|
|
281
|
+
for (const page of pages) if (!Number.isInteger(page) || page < 1 || page > total) throw new WatermarkException(`Watermark page ${page} is out of range (the PDF has ${total} page(s))`);
|
|
282
|
+
return [...new Set(pages)].map((page) => page - 1);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Centers of the marks for one page, in page coordinates. Tiles follow the
|
|
286
|
+
* rotated axes so rotated marks never overlap each other.
|
|
287
|
+
*/
|
|
288
|
+
function markCenters(pageWidth, pageHeight, mark, options) {
|
|
289
|
+
const cx = pageWidth / 2;
|
|
290
|
+
const cy = pageHeight / 2;
|
|
291
|
+
if (options.position === "center") return [{
|
|
292
|
+
x: cx,
|
|
293
|
+
y: cy
|
|
294
|
+
}];
|
|
295
|
+
const theta = options.rotation * Math.PI / 180;
|
|
296
|
+
const cos = Math.cos(theta);
|
|
297
|
+
const sin = Math.sin(theta);
|
|
298
|
+
const stepX = mark.width + options.spacing;
|
|
299
|
+
const stepY = mark.height + options.spacing;
|
|
300
|
+
const reach = Math.hypot(mark.width, mark.height) / 2;
|
|
301
|
+
const n = Math.ceil((Math.hypot(pageWidth, pageHeight) / 2 + reach) / Math.min(stepX, stepY));
|
|
302
|
+
const centers = [];
|
|
303
|
+
for (let i = -n; i <= n; i++) for (let j = -n; j <= n; j++) {
|
|
304
|
+
const x = cx + i * stepX * cos - j * stepY * sin;
|
|
305
|
+
const y = cy + i * stepX * sin + j * stepY * cos;
|
|
306
|
+
if (x >= -reach && x <= pageWidth + reach && y >= -reach && y <= pageHeight + reach) centers.push({
|
|
307
|
+
x,
|
|
308
|
+
y
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
return centers;
|
|
312
|
+
}
|
|
313
|
+
async function buildMark(pdfDoc, options, pageWidth) {
|
|
314
|
+
const opacity = options.opacity ?? DEFAULT_OPACITY;
|
|
315
|
+
const rotate = degrees(options.rotation ?? DEFAULT_ROTATION);
|
|
316
|
+
if (options.image) {
|
|
317
|
+
const image = await embedImage(pdfDoc, new Uint8Array(options.image));
|
|
318
|
+
const width = options.imageWidth ?? pageWidth / 2;
|
|
319
|
+
const height = image.height / image.width * width;
|
|
320
|
+
return {
|
|
321
|
+
width,
|
|
322
|
+
height,
|
|
323
|
+
draw: (page, x, y) => page.drawImage(image, {
|
|
324
|
+
x,
|
|
325
|
+
y,
|
|
326
|
+
width,
|
|
327
|
+
height,
|
|
328
|
+
opacity,
|
|
329
|
+
rotate
|
|
330
|
+
})
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
const font = await pdfDoc.embedFont(StandardFonts[options.font ?? DEFAULT_FONT]);
|
|
334
|
+
const size = options.fontSize ?? DEFAULT_FONT_SIZE;
|
|
335
|
+
const text = options.text;
|
|
336
|
+
const color = parseHexColor(options.color ?? DEFAULT_COLOR);
|
|
337
|
+
let width;
|
|
338
|
+
try {
|
|
339
|
+
width = font.widthOfTextAtSize(text, size);
|
|
340
|
+
} catch (error) {
|
|
341
|
+
throw new WatermarkException(`Watermark text cannot be rendered with the ${options.font ?? DEFAULT_FONT} font (only WinAnsi characters are supported)`, { cause: error });
|
|
342
|
+
}
|
|
343
|
+
return {
|
|
344
|
+
width,
|
|
345
|
+
height: font.heightAtSize(size, { descender: false }),
|
|
346
|
+
draw: (page, x, y) => page.drawText(text, {
|
|
347
|
+
x,
|
|
348
|
+
y,
|
|
349
|
+
size,
|
|
350
|
+
font,
|
|
351
|
+
color,
|
|
352
|
+
opacity,
|
|
353
|
+
rotate
|
|
354
|
+
})
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Stamps a text or image watermark on the pages of an existing PDF.
|
|
359
|
+
*/
|
|
360
|
+
async function addWatermark(pdf, options) {
|
|
361
|
+
validate(options);
|
|
362
|
+
try {
|
|
363
|
+
const pdfDoc = await PDFDocument.load(new Uint8Array(pdf));
|
|
364
|
+
const pages = pdfDoc.getPages();
|
|
365
|
+
const indexes = resolvePageIndexes(options.pages, pages.length);
|
|
366
|
+
const position = options.position ?? "center";
|
|
367
|
+
const rotation = options.rotation ?? DEFAULT_ROTATION;
|
|
368
|
+
const spacing = options.tileSpacing ?? DEFAULT_TILE_SPACING;
|
|
369
|
+
const theta = rotation * Math.PI / 180;
|
|
370
|
+
const cos = Math.cos(theta);
|
|
371
|
+
const sin = Math.sin(theta);
|
|
372
|
+
const marks = /* @__PURE__ */ new Map();
|
|
373
|
+
for (const index of indexes) {
|
|
374
|
+
const page = pages[index];
|
|
375
|
+
const { width: pageWidth, height: pageHeight } = page.getSize();
|
|
376
|
+
let mark = marks.get(pageWidth);
|
|
377
|
+
if (!mark) {
|
|
378
|
+
mark = await buildMark(pdfDoc, options, pageWidth);
|
|
379
|
+
marks.set(pageWidth, mark);
|
|
380
|
+
}
|
|
381
|
+
for (const center of markCenters(pageWidth, pageHeight, mark, {
|
|
382
|
+
position,
|
|
383
|
+
rotation,
|
|
384
|
+
spacing
|
|
385
|
+
})) mark.draw(page, center.x - (mark.width / 2 * cos - mark.height / 2 * sin), center.y - (mark.width / 2 * sin + mark.height / 2 * cos));
|
|
386
|
+
}
|
|
387
|
+
return await pdfDoc.save();
|
|
388
|
+
} catch (error) {
|
|
389
|
+
if (error instanceof WatermarkException) throw error;
|
|
390
|
+
throw new WatermarkException(`Failed to add watermark: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
//#endregion
|
|
207
394
|
//#region node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
|
|
208
395
|
var Node = class {
|
|
209
396
|
value;
|
|
@@ -337,6 +524,154 @@ function mergePuppeteerParameters(defaults, overrides) {
|
|
|
337
524
|
return deepmerge(defaults, overrides);
|
|
338
525
|
}
|
|
339
526
|
//#endregion
|
|
527
|
+
//#region src/helpers/request-guard.helper.ts
|
|
528
|
+
const blockedRanges = new BlockList();
|
|
529
|
+
for (const [address, prefix] of [
|
|
530
|
+
["0.0.0.0", 8],
|
|
531
|
+
["10.0.0.0", 8],
|
|
532
|
+
["100.64.0.0", 10],
|
|
533
|
+
["127.0.0.0", 8],
|
|
534
|
+
["169.254.0.0", 16],
|
|
535
|
+
["172.16.0.0", 12],
|
|
536
|
+
["192.0.0.0", 24],
|
|
537
|
+
["192.168.0.0", 16],
|
|
538
|
+
["198.18.0.0", 15],
|
|
539
|
+
["224.0.0.0", 4],
|
|
540
|
+
["240.0.0.0", 4]
|
|
541
|
+
]) blockedRanges.addSubnet(address, prefix, "ipv4");
|
|
542
|
+
for (const [address, prefix] of [
|
|
543
|
+
["::", 128],
|
|
544
|
+
["::1", 128],
|
|
545
|
+
["64:ff9b::", 96],
|
|
546
|
+
["fc00::", 7],
|
|
547
|
+
["fe80::", 10],
|
|
548
|
+
["ff00::", 8]
|
|
549
|
+
]) blockedRanges.addSubnet(address, prefix, "ipv6");
|
|
550
|
+
const IPV4_MAPPED_IPV6 = /^::ffff:([\da-f]{1,4}):([\da-f]{1,4})$/i;
|
|
551
|
+
/** True for addresses that must not be reachable from a rendered document. */
|
|
552
|
+
function isPrivateAddress(address) {
|
|
553
|
+
const family = isIP(address);
|
|
554
|
+
if (family === 4) return blockedRanges.check(address, "ipv4");
|
|
555
|
+
if (family === 6) {
|
|
556
|
+
const mapped = IPV4_MAPPED_IPV6.exec(address);
|
|
557
|
+
if (mapped) {
|
|
558
|
+
const high = Number.parseInt(mapped[1], 16);
|
|
559
|
+
const low = Number.parseInt(mapped[2], 16);
|
|
560
|
+
return isPrivateAddress([
|
|
561
|
+
high >> 8,
|
|
562
|
+
high & 255,
|
|
563
|
+
low >> 8,
|
|
564
|
+
low & 255
|
|
565
|
+
].join("."));
|
|
566
|
+
}
|
|
567
|
+
return blockedRanges.check(address, "ipv6");
|
|
568
|
+
}
|
|
569
|
+
return true;
|
|
570
|
+
}
|
|
571
|
+
function hostMatches(hostname, pattern) {
|
|
572
|
+
const host = hostname.toLowerCase();
|
|
573
|
+
const rule = pattern.toLowerCase();
|
|
574
|
+
if (rule.startsWith("*.")) return host.endsWith(rule.slice(1));
|
|
575
|
+
return host === rule;
|
|
576
|
+
}
|
|
577
|
+
function isLocalhostName(hostname) {
|
|
578
|
+
return hostname === "localhost" || hostname.endsWith(".localhost");
|
|
579
|
+
}
|
|
580
|
+
async function resolvesToPrivateAddress(hostname) {
|
|
581
|
+
const host = hostname.replace(/^\[|\]$/g, "");
|
|
582
|
+
if (isIP(host)) return isPrivateAddress(host);
|
|
583
|
+
if (isLocalhostName(host)) return true;
|
|
584
|
+
try {
|
|
585
|
+
return (await lookup(host, {
|
|
586
|
+
all: true,
|
|
587
|
+
verbatim: true
|
|
588
|
+
})).some(({ address }) => isPrivateAddress(address));
|
|
589
|
+
} catch {
|
|
590
|
+
return true;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
async function isFileAllowed(url, roots) {
|
|
594
|
+
if (roots.length === 0 || url.hostname !== "" && url.hostname !== "localhost") return false;
|
|
595
|
+
let path;
|
|
596
|
+
try {
|
|
597
|
+
path = fileURLToPath(url);
|
|
598
|
+
} catch {
|
|
599
|
+
return false;
|
|
600
|
+
}
|
|
601
|
+
const real = async (candidate) => {
|
|
602
|
+
const missing = [];
|
|
603
|
+
let current = resolve(candidate);
|
|
604
|
+
for (;;) try {
|
|
605
|
+
return join(await promises.realpath(current), ...missing);
|
|
606
|
+
} catch {
|
|
607
|
+
const parent = dirname(current);
|
|
608
|
+
if (parent === current) return resolve(candidate);
|
|
609
|
+
missing.unshift(basename(current));
|
|
610
|
+
current = parent;
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
const target = await real(path);
|
|
614
|
+
for (const root of roots) {
|
|
615
|
+
const rel = relative(await real(root), target);
|
|
616
|
+
if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) return true;
|
|
617
|
+
}
|
|
618
|
+
return false;
|
|
619
|
+
}
|
|
620
|
+
/** Decides whether the browser may fetch `rawUrl`. */
|
|
621
|
+
async function isRequestAllowed(rawUrl, options) {
|
|
622
|
+
let url;
|
|
623
|
+
try {
|
|
624
|
+
url = new URL(rawUrl);
|
|
625
|
+
} catch {
|
|
626
|
+
return false;
|
|
627
|
+
}
|
|
628
|
+
switch (url.protocol) {
|
|
629
|
+
case "about:":
|
|
630
|
+
case "data:":
|
|
631
|
+
case "blob:": return true;
|
|
632
|
+
case "file:": return isFileAllowed(url, options.allowedFileRoots ?? []);
|
|
633
|
+
case "http:":
|
|
634
|
+
case "https:":
|
|
635
|
+
if (options.allowedHosts) return options.allowedHosts.some((pattern) => hostMatches(url.hostname, pattern));
|
|
636
|
+
if (options.blockPrivateNetworks === false) return true;
|
|
637
|
+
return !await resolvesToPrivateAddress(url.hostname);
|
|
638
|
+
default: return false;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
/** Logs the origin and path only: query strings may carry secrets. */
|
|
642
|
+
function describe(rawUrl) {
|
|
643
|
+
try {
|
|
644
|
+
const url = new URL(rawUrl);
|
|
645
|
+
return `${url.origin === "null" ? `${url.protocol}//` : url.origin}${url.pathname}`;
|
|
646
|
+
} catch {
|
|
647
|
+
return "<invalid url>";
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Filters every request the page (and its frames) makes, redirects included,
|
|
652
|
+
* and closes the pop-ups a script could open to escape the filter.
|
|
653
|
+
*/
|
|
654
|
+
async function installRequestGuard(context, page, options) {
|
|
655
|
+
context.on("targetcreated", (target) => {
|
|
656
|
+
if (target.type() === TargetType.PAGE && target.opener()) target.page().then((popup) => popup?.close()).catch(() => void 0);
|
|
657
|
+
});
|
|
658
|
+
if (options.javascriptEnabled === false) await page.setJavaScriptEnabled(false);
|
|
659
|
+
await page.setRequestInterception(true);
|
|
660
|
+
page.on("request", (request) => {
|
|
661
|
+
(async () => {
|
|
662
|
+
if (request.isInterceptResolutionHandled()) return;
|
|
663
|
+
const url = request.url();
|
|
664
|
+
const allowed = await isRequestAllowed(url, options).catch(() => false);
|
|
665
|
+
if (request.isInterceptResolutionHandled()) return;
|
|
666
|
+
if (allowed) await request.continue();
|
|
667
|
+
else {
|
|
668
|
+
Logger.warn(`Blocked request to ${describe(url)}`, "NestJsPdf");
|
|
669
|
+
await request.abort("blockedbyclient");
|
|
670
|
+
}
|
|
671
|
+
})().catch(() => void 0);
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
//#endregion
|
|
340
675
|
//#region src/helpers/tokens.ts
|
|
341
676
|
const PDF_PARAMETERS = "PDF_PARAMETERS";
|
|
342
677
|
//#endregion
|
|
@@ -353,7 +688,7 @@ function __decorateParam(paramIndex, decorator) {
|
|
|
353
688
|
}
|
|
354
689
|
//#endregion
|
|
355
690
|
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
|
|
356
|
-
function __decorate
|
|
691
|
+
function __decorate(decorators, target, key, desc) {
|
|
357
692
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
358
693
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
359
694
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -382,47 +717,47 @@ function isTargetClosedError(error) {
|
|
|
382
717
|
return error.name === "TargetCloseError" || error.message.includes("Target closed") || error.message.includes("Target.createTarget");
|
|
383
718
|
}
|
|
384
719
|
let BrowserService = class BrowserService {
|
|
385
|
-
cacheDir;
|
|
386
|
-
options;
|
|
387
|
-
|
|
388
|
-
browser;
|
|
720
|
+
#cacheDir;
|
|
721
|
+
#options;
|
|
722
|
+
#browserInstance = null;
|
|
723
|
+
#browser;
|
|
389
724
|
activeJobs = 0;
|
|
390
725
|
totalJobs = 0;
|
|
391
|
-
recycleRequested = false;
|
|
392
|
-
recycling = false;
|
|
393
|
-
shuttingDown = false;
|
|
726
|
+
#recycleRequested = false;
|
|
727
|
+
#recycling = false;
|
|
728
|
+
#shuttingDown = false;
|
|
394
729
|
/** Max time to wait for in-flight PDF jobs to finish before closing the browser on shutdown. */
|
|
395
730
|
shutdownDrainTimeoutMs = 15e3;
|
|
396
|
-
browserTag;
|
|
397
|
-
useLockedBrowser;
|
|
398
|
-
buildId;
|
|
731
|
+
#browserTag;
|
|
732
|
+
#useLockedBrowser;
|
|
733
|
+
#buildId;
|
|
399
734
|
constructor(pdfParams) {
|
|
400
|
-
this
|
|
401
|
-
this
|
|
402
|
-
this
|
|
403
|
-
this
|
|
404
|
-
this
|
|
405
|
-
this
|
|
735
|
+
this.#cacheDir = resolve(".cache/puppeteer-browser");
|
|
736
|
+
this.#options = pdfParams;
|
|
737
|
+
this.#loadBuildId();
|
|
738
|
+
this.#loadBrowser();
|
|
739
|
+
this.#loadBrowserTag();
|
|
740
|
+
this.#loadUseLockedBrowser();
|
|
406
741
|
}
|
|
407
742
|
async onModuleDestroy() {
|
|
408
|
-
this
|
|
409
|
-
await this
|
|
410
|
-
if (this
|
|
411
|
-
await this.
|
|
743
|
+
this.#shuttingDown = true;
|
|
744
|
+
await this.#waitForIdle(this.shutdownDrainTimeoutMs);
|
|
745
|
+
if (this.#browserInstance?.connected) try {
|
|
746
|
+
await this.#browserInstance.close();
|
|
412
747
|
} catch (error) {
|
|
413
748
|
Logger.warn(`Failed to close browser on module destroy: ${error instanceof Error ? error.message : String(error)}`);
|
|
414
749
|
}
|
|
415
|
-
if (this
|
|
750
|
+
if (this.#options?.cleanupBrowserCacheOnExit !== false) await this.#cleanupCacheBestEffort();
|
|
416
751
|
}
|
|
417
752
|
/** Wait until no PDF job is in flight, or until the timeout elapses. */
|
|
418
|
-
async waitForIdle(timeoutMs) {
|
|
753
|
+
async #waitForIdle(timeoutMs) {
|
|
419
754
|
const start = Date.now();
|
|
420
755
|
while (this.activeJobs > 0 && Date.now() - start < timeoutMs) await sleep(50);
|
|
421
756
|
if (this.activeJobs > 0) Logger.warn(`Shutdown: ${this.activeJobs} PDF job(s) still running after ${timeoutMs}ms, closing the browser anyway`);
|
|
422
757
|
}
|
|
423
758
|
async getBrowserInstance(args, headless, executablePathBin) {
|
|
424
|
-
if (!this
|
|
425
|
-
return this
|
|
759
|
+
if (!this.#browserInstance?.connected) this.#browserInstance = await this.#launchBrowser(args, headless, executablePathBin);
|
|
760
|
+
return this.#browserInstance;
|
|
426
761
|
}
|
|
427
762
|
async createContext(args, headless, executablePath) {
|
|
428
763
|
const browser = await this.getBrowserInstance(args, headless, executablePath);
|
|
@@ -431,41 +766,41 @@ let BrowserService = class BrowserService {
|
|
|
431
766
|
} catch (error) {
|
|
432
767
|
if (!isTargetClosedError(error)) throw error;
|
|
433
768
|
Logger.warn("Puppeteer browser closed while creating a context, retrying once");
|
|
434
|
-
this
|
|
769
|
+
this.#browserInstance = null;
|
|
435
770
|
return await (await this.getBrowserInstance(args, headless, executablePath)).createBrowserContext();
|
|
436
771
|
}
|
|
437
772
|
}
|
|
438
773
|
markJobStarted() {
|
|
439
|
-
if (this
|
|
774
|
+
if (this.#shuttingDown) throw new BrowserUnavailableException("nestjs-pdf is shutting down, refusing new PDF jobs");
|
|
440
775
|
this.activeJobs += 1;
|
|
441
776
|
this.totalJobs += 1;
|
|
442
|
-
if (this.totalJobs >= 200) this
|
|
777
|
+
if (this.totalJobs >= 200) this.#recycleRequested = true;
|
|
443
778
|
}
|
|
444
779
|
async markJobFinished() {
|
|
445
780
|
this.activeJobs = Math.max(0, this.activeJobs - 1);
|
|
446
781
|
await this.recycleBrowserIfNeeded();
|
|
447
782
|
}
|
|
448
783
|
async recycleBrowserIfNeeded() {
|
|
449
|
-
if (!this
|
|
450
|
-
if (this
|
|
784
|
+
if (!this.#recycleRequested) return;
|
|
785
|
+
if (this.#recycling) return;
|
|
451
786
|
if (this.activeJobs > 0) return;
|
|
452
|
-
if (!this
|
|
453
|
-
this
|
|
787
|
+
if (!this.#browserInstance) return;
|
|
788
|
+
this.#recycling = true;
|
|
454
789
|
try {
|
|
455
|
-
if (this.
|
|
456
|
-
this
|
|
790
|
+
if (this.#browserInstance.connected) await this.#browserInstance.close();
|
|
791
|
+
this.#browserInstance = null;
|
|
457
792
|
this.totalJobs = 0;
|
|
458
|
-
this
|
|
793
|
+
this.#recycleRequested = false;
|
|
459
794
|
Logger.log("Puppeteer browser recycled successfully");
|
|
460
795
|
} catch (error) {
|
|
461
796
|
Logger.warn(`Failed to recycle browser: ${error instanceof Error ? error.message : String(error)}`);
|
|
462
797
|
} finally {
|
|
463
|
-
this
|
|
798
|
+
this.#recycling = false;
|
|
464
799
|
}
|
|
465
800
|
}
|
|
466
|
-
async cleanupCacheBestEffort() {
|
|
801
|
+
async #cleanupCacheBestEffort() {
|
|
467
802
|
const logger = new Logger("NestJsPdf");
|
|
468
|
-
const dir = this
|
|
803
|
+
const dir = this.#cacheDir;
|
|
469
804
|
try {
|
|
470
805
|
if (!existsSync(dir)) return;
|
|
471
806
|
logger.log(`Cleanup puppeteer cache: ${dir}`);
|
|
@@ -486,115 +821,124 @@ let BrowserService = class BrowserService {
|
|
|
486
821
|
}
|
|
487
822
|
}
|
|
488
823
|
async install(lock = false) {
|
|
489
|
-
|
|
490
|
-
|
|
824
|
+
try {
|
|
825
|
+
return await this.#doInstall(lock);
|
|
826
|
+
} catch (error) {
|
|
827
|
+
if (error instanceof NestjsPdfException) throw error;
|
|
828
|
+
throw new BrowserInstallationException(`Could not install browser: ${String(error)}`, { cause: error });
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
async #doInstall(lock) {
|
|
832
|
+
const browser = this.#browser;
|
|
833
|
+
const versionTag = this.#browserTag;
|
|
491
834
|
const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;
|
|
492
835
|
let buildId;
|
|
493
|
-
if (this
|
|
494
|
-
else buildId = this
|
|
836
|
+
if (this.#buildId === void 0) buildId = await resolveBuildId(browser, browserPlatform, versionTag);
|
|
837
|
+
else buildId = this.#buildId;
|
|
495
838
|
Logger.log(`Browser ${browser} ${versionTag} build id: ${buildId}`, "NestJsPdf");
|
|
496
839
|
if (await this.hasBrowserInstalled(browser, buildId)) {
|
|
497
840
|
Logger.log("Browser already installed", "NestJsPdf");
|
|
498
|
-
if (lock) this
|
|
841
|
+
if (lock) this.#writeLockFile(browser, buildId);
|
|
499
842
|
return;
|
|
500
843
|
} else {
|
|
501
844
|
Logger.log("Starting browser installation", "NestJsPdf");
|
|
502
845
|
const installOption = {
|
|
503
|
-
cacheDir: this
|
|
846
|
+
cacheDir: this.#cacheDir,
|
|
504
847
|
browser,
|
|
505
848
|
buildId,
|
|
506
|
-
baseUrl: this
|
|
849
|
+
baseUrl: this.#options?.browserInstallBaseUrl ?? void 0
|
|
507
850
|
};
|
|
508
851
|
if (await canDownload(installOption)) {
|
|
509
852
|
Logger.log(`Installing ${installOption.browser} ${installOption.buildId}`, "NestJsPdf");
|
|
510
853
|
const installedBrowser = await install(installOption);
|
|
511
854
|
if (await this.hasBrowserInstalled(browser, buildId)) {
|
|
512
855
|
Logger.log("Browser installed successfully", "NestJsPdf");
|
|
513
|
-
if (lock) this
|
|
856
|
+
if (lock) this.#writeLockFile(browser, buildId);
|
|
514
857
|
return installedBrowser;
|
|
515
858
|
} else Logger.error("Browser installation failed", "NestJsPdf");
|
|
516
859
|
} else Logger.error(`Error, can't install ${installOption.browser} ${installOption.buildId}`, "NestJsPdf");
|
|
517
860
|
}
|
|
518
861
|
return null;
|
|
519
862
|
}
|
|
520
|
-
loadBrowser() {
|
|
863
|
+
#loadBrowser() {
|
|
521
864
|
let browser;
|
|
522
|
-
if (this
|
|
523
|
-
else browser = this
|
|
524
|
-
this
|
|
865
|
+
if (this.#options?.browser === void 0) browser = Browser$1.CHROMIUM;
|
|
866
|
+
else browser = this.#options.browser;
|
|
867
|
+
this.#browser = browser;
|
|
525
868
|
}
|
|
526
869
|
getBrowser() {
|
|
527
|
-
return this
|
|
870
|
+
return this.#browser;
|
|
528
871
|
}
|
|
529
|
-
loadBrowserTag() {
|
|
872
|
+
#loadBrowserTag() {
|
|
530
873
|
let versionTag;
|
|
531
|
-
if (this
|
|
532
|
-
if (this
|
|
874
|
+
if (this.#options?.browserTag === void 0) {
|
|
875
|
+
if (this.#browser === Browser$1.CHROMIUM) versionTag = "latest";
|
|
533
876
|
else versionTag = "stable";
|
|
534
|
-
} else versionTag = this
|
|
535
|
-
this
|
|
877
|
+
} else versionTag = this.#options.browserTag;
|
|
878
|
+
this.#browserTag = versionTag;
|
|
536
879
|
}
|
|
537
|
-
loadBuildId() {
|
|
880
|
+
#loadBuildId() {
|
|
538
881
|
let buildId;
|
|
539
|
-
if (this
|
|
540
|
-
else buildId = this
|
|
541
|
-
this
|
|
882
|
+
if (this.#options?.buildId === void 0) buildId = void 0;
|
|
883
|
+
else buildId = this.#options.buildId;
|
|
884
|
+
this.#buildId = buildId;
|
|
542
885
|
}
|
|
543
886
|
setBrowserTag(browserTag) {
|
|
544
|
-
this
|
|
887
|
+
this.#browserTag = browserTag;
|
|
545
888
|
}
|
|
546
889
|
getBrowserTag() {
|
|
547
|
-
return this
|
|
890
|
+
return this.#browserTag;
|
|
548
891
|
}
|
|
549
892
|
getBuildId() {
|
|
550
|
-
return this
|
|
893
|
+
return this.#buildId;
|
|
551
894
|
}
|
|
552
|
-
loadUseLockedBrowser() {
|
|
895
|
+
#loadUseLockedBrowser() {
|
|
553
896
|
let useLockedBrowser;
|
|
554
|
-
if (this
|
|
555
|
-
else useLockedBrowser = this
|
|
556
|
-
this
|
|
897
|
+
if (this.#options?.useLockedBrowser === void 0) useLockedBrowser = false;
|
|
898
|
+
else useLockedBrowser = this.#options.useLockedBrowser;
|
|
899
|
+
this.#useLockedBrowser = useLockedBrowser;
|
|
557
900
|
}
|
|
558
901
|
async hasBrowserInstalled(browser, buildId) {
|
|
559
|
-
return (await getInstalledBrowsers({ cacheDir: this
|
|
902
|
+
return (await getInstalledBrowsers({ cacheDir: this.#cacheDir })).find((insBrowser) => {
|
|
560
903
|
return insBrowser.browser === browser && insBrowser.buildId === buildId;
|
|
561
904
|
}) !== void 0;
|
|
562
905
|
}
|
|
563
906
|
async getExecutablePath() {
|
|
564
|
-
const browser = this
|
|
565
|
-
const versionTag = this
|
|
907
|
+
const browser = this.#browser;
|
|
908
|
+
const versionTag = this.#browserTag;
|
|
566
909
|
const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;
|
|
567
910
|
let buildId = null;
|
|
568
|
-
if (this
|
|
911
|
+
if (this.#useLockedBrowser) {
|
|
569
912
|
buildId = this.getLockedBuildId(browser);
|
|
570
913
|
Logger.log(`Using locked browser ${buildId}`, "NestJsPdf");
|
|
571
914
|
}
|
|
572
915
|
buildId ??= await resolveBuildId(browser, browserPlatform, versionTag);
|
|
573
|
-
const installedBrowser = (await getInstalledBrowsers({ cacheDir: this
|
|
916
|
+
const installedBrowser = (await getInstalledBrowsers({ cacheDir: this.#cacheDir })).find((insBrowser) => {
|
|
574
917
|
return insBrowser.browser === browser && insBrowser.buildId === buildId;
|
|
575
918
|
});
|
|
576
919
|
if (installedBrowser === void 0) {
|
|
577
920
|
const newinstalledBrowser = await this.install();
|
|
578
|
-
if (newinstalledBrowser === null || newinstalledBrowser === void 0) throw new
|
|
921
|
+
if (newinstalledBrowser === null || newinstalledBrowser === void 0) throw new BrowserInstallationException("Could not install browser");
|
|
579
922
|
else return newinstalledBrowser.executablePath;
|
|
580
923
|
}
|
|
581
924
|
return installedBrowser.executablePath;
|
|
582
925
|
}
|
|
583
|
-
async launchBrowser(args, headless, executablePathBin) {
|
|
926
|
+
async #launchBrowser(args, headless, executablePathBin) {
|
|
584
927
|
const executablePath = executablePathBin ?? await this.getExecutablePath();
|
|
585
928
|
const browser = await launch({
|
|
586
929
|
executablePath,
|
|
587
930
|
headless,
|
|
588
|
-
args
|
|
931
|
+
args,
|
|
932
|
+
ignoreDefaultArgs: ["--disable-popup-blocking"]
|
|
589
933
|
});
|
|
590
934
|
browser.on("disconnected", () => {
|
|
591
935
|
Logger.warn("Puppeteer browser disconnected");
|
|
592
|
-
if (this
|
|
936
|
+
if (this.#browserInstance === browser) this.#browserInstance = null;
|
|
593
937
|
});
|
|
594
938
|
return browser;
|
|
595
939
|
}
|
|
596
|
-
writeLockFile(browser, buildId) {
|
|
597
|
-
const lockFile = resolve(this
|
|
940
|
+
#writeLockFile(browser, buildId) {
|
|
941
|
+
const lockFile = resolve(this.#cacheDir, `${browser}.lock`);
|
|
598
942
|
const data = JSON.stringify({
|
|
599
943
|
browser,
|
|
600
944
|
buildId,
|
|
@@ -604,7 +948,7 @@ let BrowserService = class BrowserService {
|
|
|
604
948
|
Logger.log(`Browser ${browser} locked to build ${buildId}`, "NestJsPdf");
|
|
605
949
|
}
|
|
606
950
|
getLockedBuildId(browser) {
|
|
607
|
-
const lockFile = resolve(this
|
|
951
|
+
const lockFile = resolve(this.#cacheDir, `${browser}.lock`);
|
|
608
952
|
if (existsSync(lockFile)) {
|
|
609
953
|
const data = readFileSync(lockFile);
|
|
610
954
|
return JSON.parse(data.toString()).buildId;
|
|
@@ -612,7 +956,7 @@ let BrowserService = class BrowserService {
|
|
|
612
956
|
return null;
|
|
613
957
|
}
|
|
614
958
|
};
|
|
615
|
-
BrowserService = __decorate
|
|
959
|
+
BrowserService = __decorate([
|
|
616
960
|
Injectable(),
|
|
617
961
|
__decorateParam(0, Inject("PDF_PARAMETERS")),
|
|
618
962
|
__decorateMetadata("design:paramtypes", [Object])
|
|
@@ -627,7 +971,7 @@ let EjsService = class EjsService {
|
|
|
627
971
|
...options
|
|
628
972
|
});
|
|
629
973
|
} catch (error) {
|
|
630
|
-
throw new
|
|
974
|
+
throw new TemplateRenderException("EJS", `EJS rendering failed: ${String(error)}`, { cause: error });
|
|
631
975
|
}
|
|
632
976
|
}
|
|
633
977
|
async renderFile(filePath, data = {}, options) {
|
|
@@ -637,19 +981,19 @@ let EjsService = class EjsService {
|
|
|
637
981
|
...options
|
|
638
982
|
});
|
|
639
983
|
} catch (error) {
|
|
640
|
-
throw new
|
|
984
|
+
throw new TemplateRenderException("EJS", `EJS file rendering failed: ${String(error)}`, { cause: error });
|
|
641
985
|
}
|
|
642
986
|
}
|
|
643
987
|
};
|
|
644
|
-
EjsService = __decorate
|
|
988
|
+
EjsService = __decorate([Injectable()], EjsService);
|
|
645
989
|
//#endregion
|
|
646
990
|
//#region src/puppeteer/engines/eta/eta.service.ts
|
|
647
991
|
let EtaService = class EtaService {
|
|
648
|
-
eta;
|
|
649
|
-
templateCache = /* @__PURE__ */ new Map();
|
|
650
|
-
maxCacheSize = 100;
|
|
992
|
+
#eta;
|
|
993
|
+
#templateCache = /* @__PURE__ */ new Map();
|
|
994
|
+
#maxCacheSize = 100;
|
|
651
995
|
constructor() {
|
|
652
|
-
this
|
|
996
|
+
this.#eta = new Eta({
|
|
653
997
|
cache: true,
|
|
654
998
|
autoEscape: true,
|
|
655
999
|
useWith: true
|
|
@@ -670,9 +1014,9 @@ let EtaService = class EtaService {
|
|
|
670
1014
|
useWith: true,
|
|
671
1015
|
...options,
|
|
672
1016
|
varName: options.varName ?? "it"
|
|
673
|
-
}) : this
|
|
1017
|
+
}) : this.#eta).renderString(template, data);
|
|
674
1018
|
} catch (error) {
|
|
675
|
-
throw new
|
|
1019
|
+
throw new TemplateRenderException("Eta", `Eta rendering failed: ${String(error)}`, { cause: error });
|
|
676
1020
|
}
|
|
677
1021
|
}
|
|
678
1022
|
/**
|
|
@@ -686,53 +1030,54 @@ let EtaService = class EtaService {
|
|
|
686
1030
|
try {
|
|
687
1031
|
const resolvedPath = resolve(filePath);
|
|
688
1032
|
const useCache = options?.cache ?? true;
|
|
689
|
-
let template = useCache ? this
|
|
1033
|
+
let template = useCache ? this.#templateCache.get(resolvedPath) : void 0;
|
|
690
1034
|
if (!template) {
|
|
691
1035
|
template = readFileSync(resolvedPath, "utf-8");
|
|
692
|
-
if (useCache && this
|
|
1036
|
+
if (useCache && this.#templateCache.size < this.#maxCacheSize) this.#templateCache.set(resolvedPath, template);
|
|
693
1037
|
}
|
|
694
1038
|
return this.render(template, data, options);
|
|
695
1039
|
} catch (error) {
|
|
696
|
-
throw new
|
|
1040
|
+
throw new TemplateRenderException("Eta", `Eta file rendering failed for ${filePath}: ${String(error)}`, { cause: error });
|
|
697
1041
|
}
|
|
698
1042
|
}
|
|
699
1043
|
/**
|
|
700
1044
|
* Clear the template cache
|
|
701
1045
|
*/
|
|
702
1046
|
clearCache() {
|
|
703
|
-
this
|
|
1047
|
+
this.#templateCache.clear();
|
|
704
1048
|
}
|
|
705
1049
|
/**
|
|
706
1050
|
* Get the current cache size
|
|
707
1051
|
* @returns The number of cached templates
|
|
708
1052
|
*/
|
|
709
1053
|
getCacheSize() {
|
|
710
|
-
return this
|
|
1054
|
+
return this.#templateCache.size;
|
|
711
1055
|
}
|
|
712
1056
|
};
|
|
713
|
-
EtaService = __decorate
|
|
1057
|
+
EtaService = __decorate([Injectable(), __decorateMetadata("design:paramtypes", [])], EtaService);
|
|
714
1058
|
//#endregion
|
|
715
1059
|
//#region src/puppeteer/engines/handlebars/handlebars.service.ts
|
|
716
1060
|
let HandlebarsService = class HandlebarsService {
|
|
717
|
-
cachedOptions;
|
|
718
|
-
cachedEnv;
|
|
1061
|
+
#cachedOptions;
|
|
1062
|
+
#cachedEnv;
|
|
719
1063
|
render(template, parameters = {}, options = {}) {
|
|
720
1064
|
try {
|
|
721
|
-
return this
|
|
1065
|
+
return this.#getEnv(options).compile(template, options.compileOptions)(parameters, options.templateOptions);
|
|
722
1066
|
} catch (error) {
|
|
723
|
-
|
|
1067
|
+
if (error instanceof NestjsPdfException) throw error;
|
|
1068
|
+
throw new TemplateRenderException("Handlebars", `Handlebars rendering failed: ${String(error)}`, { cause: error });
|
|
724
1069
|
}
|
|
725
1070
|
}
|
|
726
1071
|
renderFile(file, parameters = {}, options = {}) {
|
|
727
|
-
if (options.templateDirectory === void 0) throw new
|
|
1072
|
+
if (options.templateDirectory === void 0) throw new TemplateConfigurationException("Handlebars file rendering failed: option `templateDirectory` is not set");
|
|
728
1073
|
const baseDir = resolve(process.cwd(), options.templateDirectory);
|
|
729
1074
|
const templatePath = resolve(baseDir, file);
|
|
730
|
-
if (templatePath !== baseDir && !templatePath.startsWith(baseDir + sep)) throw new
|
|
1075
|
+
if (templatePath !== baseDir && !templatePath.startsWith(baseDir + sep)) throw new TemplateConfigurationException(`Handlebars file rendering failed: ’${file}’ resolves outside \`templateDirectory\``);
|
|
731
1076
|
let template;
|
|
732
1077
|
try {
|
|
733
1078
|
template = readFileSync(templatePath, "utf8");
|
|
734
1079
|
} catch (error) {
|
|
735
|
-
throw new
|
|
1080
|
+
throw new TemplateRenderException("Handlebars", `Handlebars file rendering failed: ${String(error)}`, { cause: error });
|
|
736
1081
|
}
|
|
737
1082
|
return this.render(template, parameters, options);
|
|
738
1083
|
}
|
|
@@ -741,19 +1086,19 @@ let HandlebarsService = class HandlebarsService {
|
|
|
741
1086
|
* nothing leaks into the global Handlebars. Memoised for the common case where
|
|
742
1087
|
* the same options object is reused across calls (e.g. the module `hbsOptions`).
|
|
743
1088
|
*/
|
|
744
|
-
getEnv(options) {
|
|
745
|
-
if (this
|
|
1089
|
+
#getEnv(options) {
|
|
1090
|
+
if (this.#cachedEnv && this.#cachedOptions === options) return this.#cachedEnv;
|
|
746
1091
|
const env = Handlebars.create();
|
|
747
1092
|
for (const helper of options.helpers ?? []) env.registerHelper(helper.name, helper.fn);
|
|
748
|
-
this
|
|
749
|
-
this
|
|
750
|
-
this
|
|
1093
|
+
this.#registerPartials(env, options.partialDirectory);
|
|
1094
|
+
this.#cachedOptions = options;
|
|
1095
|
+
this.#cachedEnv = env;
|
|
751
1096
|
return env;
|
|
752
1097
|
}
|
|
753
|
-
registerPartials(env, partialDirectory) {
|
|
1098
|
+
#registerPartials(env, partialDirectory) {
|
|
754
1099
|
if (partialDirectory === void 0) return;
|
|
755
1100
|
const partialPath = join(process.cwd(), partialDirectory);
|
|
756
|
-
if (!existsSync(partialPath)) throw new
|
|
1101
|
+
if (!existsSync(partialPath)) throw new TemplateConfigurationException(`Handlebars partial directory does not exist: ${partialPath}`);
|
|
757
1102
|
for (const entry of readdirSync(partialPath)) {
|
|
758
1103
|
const filePath = join(partialPath, entry);
|
|
759
1104
|
if (!statSync(filePath).isFile()) continue;
|
|
@@ -761,25 +1106,34 @@ let HandlebarsService = class HandlebarsService {
|
|
|
761
1106
|
}
|
|
762
1107
|
}
|
|
763
1108
|
};
|
|
764
|
-
HandlebarsService = __decorate
|
|
1109
|
+
HandlebarsService = __decorate([Injectable()], HandlebarsService);
|
|
765
1110
|
//#endregion
|
|
766
1111
|
//#region src/puppeteer/engines/mjml/mjml.service.ts
|
|
767
1112
|
let MjmlService = class MjmlService {
|
|
768
1113
|
async render(template, options) {
|
|
769
|
-
|
|
770
|
-
|
|
1114
|
+
try {
|
|
1115
|
+
const { html } = await mjml(template, options);
|
|
1116
|
+
return html;
|
|
1117
|
+
} catch (error) {
|
|
1118
|
+
throw new TemplateRenderException("MJML", `MJML rendering failed: ${String(error)}`, { cause: error });
|
|
1119
|
+
}
|
|
771
1120
|
}
|
|
772
1121
|
async renderFile(filePath, options) {
|
|
773
|
-
|
|
1122
|
+
let template;
|
|
1123
|
+
try {
|
|
1124
|
+
template = readFileSync(filePath, "utf-8");
|
|
1125
|
+
} catch (error) {
|
|
1126
|
+
throw new TemplateRenderException("MJML", `MJML file rendering failed: ${String(error)}`, { cause: error });
|
|
1127
|
+
}
|
|
774
1128
|
return await this.render(template, options);
|
|
775
1129
|
}
|
|
776
1130
|
};
|
|
777
|
-
MjmlService = __decorate
|
|
1131
|
+
MjmlService = __decorate([Injectable()], MjmlService);
|
|
778
1132
|
//#endregion
|
|
779
1133
|
//#region src/puppeteer/engines/mustache/mustache.service.ts
|
|
780
1134
|
let MustacheService = class MustacheService {
|
|
781
|
-
templateCache = /* @__PURE__ */ new Map();
|
|
782
|
-
maxCacheSize = 100;
|
|
1135
|
+
#templateCache = /* @__PURE__ */ new Map();
|
|
1136
|
+
#maxCacheSize = 100;
|
|
783
1137
|
/**
|
|
784
1138
|
* Render a Mustache template from a string
|
|
785
1139
|
* @param template The template string to render
|
|
@@ -795,7 +1149,7 @@ let MustacheService = class MustacheService {
|
|
|
795
1149
|
escape: options?.escape
|
|
796
1150
|
});
|
|
797
1151
|
} catch (error) {
|
|
798
|
-
throw new
|
|
1152
|
+
throw new TemplateRenderException("Mustache", `Mustache rendering failed: ${String(error)}`, { cause: error });
|
|
799
1153
|
}
|
|
800
1154
|
}
|
|
801
1155
|
/**
|
|
@@ -808,31 +1162,31 @@ let MustacheService = class MustacheService {
|
|
|
808
1162
|
renderFile(filePath, data = {}, options) {
|
|
809
1163
|
try {
|
|
810
1164
|
const resolvedPath = resolve(filePath);
|
|
811
|
-
let template = this
|
|
1165
|
+
let template = this.#templateCache.get(resolvedPath);
|
|
812
1166
|
if (!template) {
|
|
813
1167
|
template = readFileSync(resolvedPath, "utf-8");
|
|
814
|
-
if (this
|
|
1168
|
+
if (this.#templateCache.size < this.#maxCacheSize) this.#templateCache.set(resolvedPath, template);
|
|
815
1169
|
}
|
|
816
1170
|
return this.render(template, data, options);
|
|
817
1171
|
} catch (error) {
|
|
818
|
-
throw new
|
|
1172
|
+
throw new TemplateRenderException("Mustache", `Mustache file rendering failed for ${filePath}: ${String(error)}`, { cause: error });
|
|
819
1173
|
}
|
|
820
1174
|
}
|
|
821
1175
|
/**
|
|
822
1176
|
* Clear the template cache
|
|
823
1177
|
*/
|
|
824
1178
|
clearCache() {
|
|
825
|
-
this
|
|
1179
|
+
this.#templateCache.clear();
|
|
826
1180
|
}
|
|
827
1181
|
/**
|
|
828
1182
|
* Get the current cache size
|
|
829
1183
|
* @returns The number of cached templates
|
|
830
1184
|
*/
|
|
831
1185
|
getCacheSize() {
|
|
832
|
-
return this
|
|
1186
|
+
return this.#templateCache.size;
|
|
833
1187
|
}
|
|
834
1188
|
};
|
|
835
|
-
MustacheService = __decorate
|
|
1189
|
+
MustacheService = __decorate([Injectable()], MustacheService);
|
|
836
1190
|
//#endregion
|
|
837
1191
|
//#region src/puppeteer/engines/nunjucks/nunjucks.service.ts
|
|
838
1192
|
let NunjucksService = class NunjucksService {
|
|
@@ -857,7 +1211,7 @@ let NunjucksService = class NunjucksService {
|
|
|
857
1211
|
}
|
|
858
1212
|
return nunjucks.renderString(template, data);
|
|
859
1213
|
} catch (error) {
|
|
860
|
-
throw new
|
|
1214
|
+
throw new TemplateRenderException("Nunjucks", `Nunjucks rendering failed: ${String(error)}`, { cause: error });
|
|
861
1215
|
}
|
|
862
1216
|
}
|
|
863
1217
|
renderFile(filePath, data = {}, options) {
|
|
@@ -874,11 +1228,11 @@ let NunjucksService = class NunjucksService {
|
|
|
874
1228
|
}
|
|
875
1229
|
return nunjucks.render(filePath, data);
|
|
876
1230
|
} catch (error) {
|
|
877
|
-
throw new
|
|
1231
|
+
throw new TemplateRenderException("Nunjucks", `Nunjucks file rendering failed: ${String(error)}`, { cause: error });
|
|
878
1232
|
}
|
|
879
1233
|
}
|
|
880
1234
|
};
|
|
881
|
-
NunjucksService = __decorate
|
|
1235
|
+
NunjucksService = __decorate([Injectable(), __decorateMetadata("design:paramtypes", [])], NunjucksService);
|
|
882
1236
|
//#endregion
|
|
883
1237
|
//#region src/puppeteer/engines/pug/pug.service.ts
|
|
884
1238
|
let PugService = class PugService {
|
|
@@ -886,7 +1240,7 @@ let PugService = class PugService {
|
|
|
886
1240
|
try {
|
|
887
1241
|
return pug.compile(template, { ...options })(data);
|
|
888
1242
|
} catch (error) {
|
|
889
|
-
throw new
|
|
1243
|
+
throw new TemplateRenderException("Pug", `Pug rendering failed: ${String(error)}`, { cause: error });
|
|
890
1244
|
}
|
|
891
1245
|
}
|
|
892
1246
|
renderFile(filePath, data = {}, options) {
|
|
@@ -894,44 +1248,49 @@ let PugService = class PugService {
|
|
|
894
1248
|
const template = readFileSync(filePath, "utf-8");
|
|
895
1249
|
return this.render(template, data, options);
|
|
896
1250
|
} catch (error) {
|
|
897
|
-
throw new
|
|
1251
|
+
throw new TemplateRenderException("Pug", `Pug file rendering failed: ${String(error)}`, { cause: error });
|
|
898
1252
|
}
|
|
899
1253
|
}
|
|
900
1254
|
};
|
|
901
|
-
PugService = __decorate
|
|
1255
|
+
PugService = __decorate([Injectable()], PugService);
|
|
902
1256
|
//#endregion
|
|
903
1257
|
//#region src/puppeteer/libs/requireService.utils.ts
|
|
904
1258
|
function requireService(service, name) {
|
|
905
|
-
if (!service) throw new
|
|
1259
|
+
if (!service) throw new EngineNotAvailableException(name);
|
|
906
1260
|
return service;
|
|
907
1261
|
}
|
|
908
1262
|
//#endregion
|
|
909
1263
|
//#region src/puppeteer/puppeteer.service.ts
|
|
910
1264
|
let PuppeteerService = class PuppeteerService {
|
|
911
|
-
browserService;
|
|
912
|
-
options;
|
|
913
|
-
hbsService;
|
|
914
|
-
mjmlService;
|
|
915
|
-
pugService;
|
|
916
|
-
ejsService;
|
|
917
|
-
nunjucksService;
|
|
918
|
-
etaService;
|
|
919
|
-
mustacheService;
|
|
1265
|
+
#browserService;
|
|
1266
|
+
#options;
|
|
1267
|
+
#hbsService;
|
|
1268
|
+
#mjmlService;
|
|
1269
|
+
#pugService;
|
|
1270
|
+
#ejsService;
|
|
1271
|
+
#nunjucksService;
|
|
1272
|
+
#etaService;
|
|
1273
|
+
#mustacheService;
|
|
920
1274
|
constructor(browserService, options, hbsService, mjmlService, pugService, ejsService, nunjucksService, etaService, mustacheService) {
|
|
921
|
-
this
|
|
922
|
-
this
|
|
923
|
-
this
|
|
924
|
-
this
|
|
925
|
-
this
|
|
926
|
-
this
|
|
927
|
-
this
|
|
928
|
-
this
|
|
929
|
-
this
|
|
930
|
-
}
|
|
931
|
-
limit = pLimit(3);
|
|
1275
|
+
this.#browserService = browserService;
|
|
1276
|
+
this.#options = options;
|
|
1277
|
+
this.#hbsService = hbsService;
|
|
1278
|
+
this.#mjmlService = mjmlService;
|
|
1279
|
+
this.#pugService = pugService;
|
|
1280
|
+
this.#ejsService = ejsService;
|
|
1281
|
+
this.#nunjucksService = nunjucksService;
|
|
1282
|
+
this.#etaService = etaService;
|
|
1283
|
+
this.#mustacheService = mustacheService;
|
|
1284
|
+
}
|
|
1285
|
+
#limit = pLimit(3);
|
|
932
1286
|
async generatePdfFromHtml(html, options) {
|
|
933
|
-
|
|
934
|
-
|
|
1287
|
+
const signal = options?.signal ?? this.#options.signal;
|
|
1288
|
+
signal?.throwIfAborted();
|
|
1289
|
+
let started = false;
|
|
1290
|
+
const job = this.#limit(async () => {
|
|
1291
|
+
signal?.throwIfAborted();
|
|
1292
|
+
started = true;
|
|
1293
|
+
const mergePuppeteerOptions = mergePuppeteerParameters(this.#options, options);
|
|
935
1294
|
if (mergePuppeteerOptions.chromiumRevision !== void 0) Logger.warn("Using `chromiumRevision` is no longer supported since the puppeteer update.");
|
|
936
1295
|
const headless = mergePuppeteerOptions.headless ?? true;
|
|
937
1296
|
const executablePath = mergePuppeteerOptions.executablePath || void 0;
|
|
@@ -952,7 +1311,6 @@ let PuppeteerService = class PuppeteerService {
|
|
|
952
1311
|
"--disable-ipc-flooding-protection",
|
|
953
1312
|
"--disable-notifications",
|
|
954
1313
|
"--disable-offer-store-unmasked-wallet-cards",
|
|
955
|
-
"--disable-popup-blocking",
|
|
956
1314
|
"--disable-print-preview",
|
|
957
1315
|
"--disable-prompt-on-repost",
|
|
958
1316
|
"--disable-renderer-backgrounding",
|
|
@@ -973,11 +1331,20 @@ let PuppeteerService = class PuppeteerService {
|
|
|
973
1331
|
"--no-zygote",
|
|
974
1332
|
"--disable-gpu"
|
|
975
1333
|
];
|
|
976
|
-
this
|
|
1334
|
+
this.#browserService.markJobStarted();
|
|
977
1335
|
let context = null;
|
|
1336
|
+
let closing;
|
|
1337
|
+
const onAbort = () => {
|
|
1338
|
+
if (!context) return;
|
|
1339
|
+
closing = context.close();
|
|
1340
|
+
closing.catch(() => void 0);
|
|
1341
|
+
};
|
|
1342
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
978
1343
|
try {
|
|
979
|
-
context = await this
|
|
1344
|
+
context = await this.#browserService.createContext(args, headless, executablePath);
|
|
1345
|
+
signal?.throwIfAborted();
|
|
980
1346
|
const page = await context.newPage();
|
|
1347
|
+
if (mergePuppeteerOptions.security) await installRequestGuard(context, page, mergePuppeteerOptions.security);
|
|
981
1348
|
const pdfOptions = mergePuppeteerOptions.pdfOptions ?? { format: "A4" };
|
|
982
1349
|
await page.setContent(html, { waitUntil: "domcontentloaded" });
|
|
983
1350
|
await page.emulateMediaType("screen");
|
|
@@ -987,78 +1354,97 @@ let PuppeteerService = class PuppeteerService {
|
|
|
987
1354
|
});
|
|
988
1355
|
/* v8 ignore next */
|
|
989
1356
|
await page.evaluate(() => document.fonts.ready);
|
|
990
|
-
|
|
1357
|
+
const pdf = await page.pdf(pdfOptions);
|
|
1358
|
+
signal?.throwIfAborted();
|
|
1359
|
+
return mergePuppeteerOptions.watermark ? await addWatermark(pdf, mergePuppeteerOptions.watermark) : pdf;
|
|
991
1360
|
} catch (e) {
|
|
1361
|
+
if (signal?.aborted) throw signal.reason;
|
|
992
1362
|
Logger.error(e);
|
|
993
|
-
throw e;
|
|
1363
|
+
if (e instanceof NestjsPdfException) throw e;
|
|
1364
|
+
throw new PdfGenerationException(`PDF generation failed: ${String(e)}`, { cause: e });
|
|
994
1365
|
} finally {
|
|
1366
|
+
signal?.removeEventListener("abort", onAbort);
|
|
995
1367
|
if (context) try {
|
|
996
|
-
|
|
1368
|
+
if (closing) await closing;
|
|
1369
|
+
else await context.close();
|
|
997
1370
|
} catch (error) {
|
|
998
1371
|
Logger.error(error);
|
|
999
1372
|
}
|
|
1000
|
-
await this
|
|
1373
|
+
await this.#browserService.markJobFinished();
|
|
1001
1374
|
}
|
|
1002
1375
|
});
|
|
1376
|
+
if (!signal) return job;
|
|
1377
|
+
let onQueuedAbort;
|
|
1378
|
+
const abortedWhileQueued = new Promise((_, reject) => {
|
|
1379
|
+
onQueuedAbort = () => {
|
|
1380
|
+
if (!started) reject(signal.reason);
|
|
1381
|
+
};
|
|
1382
|
+
signal.addEventListener("abort", onQueuedAbort, { once: true });
|
|
1383
|
+
});
|
|
1384
|
+
try {
|
|
1385
|
+
return await Promise.race([job, abortedWhileQueued]);
|
|
1386
|
+
} finally {
|
|
1387
|
+
signal.removeEventListener("abort", onQueuedAbort);
|
|
1388
|
+
}
|
|
1003
1389
|
}
|
|
1004
1390
|
async generatePdfFromTemplateHbsString(template, parameters = {}, options) {
|
|
1005
|
-
const html = requireService(this
|
|
1391
|
+
const html = requireService(this.#hbsService, "Handlebars").render(template, parameters, options?.hbsOptions ?? this.#options.hbsOptions);
|
|
1006
1392
|
return this.generatePdfFromHtml(html, options);
|
|
1007
1393
|
}
|
|
1008
1394
|
async generatePdfFromTemplateHbsFile(file, parameters = {}, options) {
|
|
1009
|
-
const html = requireService(this
|
|
1395
|
+
const html = requireService(this.#hbsService, "Handlebars").renderFile(file, parameters, options?.hbsOptions ?? this.#options.hbsOptions);
|
|
1010
1396
|
return this.generatePdfFromHtml(html, options);
|
|
1011
1397
|
}
|
|
1012
1398
|
async generatePdfFromMjmlString(template, options) {
|
|
1013
|
-
const html = await requireService(this
|
|
1399
|
+
const html = await requireService(this.#mjmlService, "MJML").render(template, options?.mjmlOptions ?? this.#options.mjmlOptions);
|
|
1014
1400
|
return this.generatePdfFromHtml(html, options);
|
|
1015
1401
|
}
|
|
1016
1402
|
async generatePdfFromMjmlFile(file, options) {
|
|
1017
|
-
const html = await requireService(this
|
|
1403
|
+
const html = await requireService(this.#mjmlService, "MJML").renderFile(file, options?.mjmlOptions ?? this.#options.mjmlOptions);
|
|
1018
1404
|
return this.generatePdfFromHtml(html, options);
|
|
1019
1405
|
}
|
|
1020
1406
|
async generatePdfFromPugString(template, data = {}, options) {
|
|
1021
|
-
const html = requireService(this
|
|
1407
|
+
const html = requireService(this.#pugService, "Pug").render(template, data, options?.pugOptions ?? this.#options.pugOptions);
|
|
1022
1408
|
return this.generatePdfFromHtml(html, options);
|
|
1023
1409
|
}
|
|
1024
1410
|
async generatePdfFromPugFile(file, data = {}, options) {
|
|
1025
|
-
const html = requireService(this
|
|
1411
|
+
const html = requireService(this.#pugService, "Pug").renderFile(file, data, options?.pugOptions ?? this.#options.pugOptions);
|
|
1026
1412
|
return this.generatePdfFromHtml(html, options);
|
|
1027
1413
|
}
|
|
1028
1414
|
async generatePdfFromEjsString(template, data = {}, options) {
|
|
1029
|
-
const html = await requireService(this
|
|
1415
|
+
const html = await requireService(this.#ejsService, "EJS").render(template, data, options?.ejsOptions ?? this.#options.ejsOptions);
|
|
1030
1416
|
return this.generatePdfFromHtml(html, options);
|
|
1031
1417
|
}
|
|
1032
1418
|
async generatePdfFromEjsFile(file, data = {}, options) {
|
|
1033
|
-
const html = await requireService(this
|
|
1419
|
+
const html = await requireService(this.#ejsService, "EJS").renderFile(file, data, options?.ejsOptions ?? this.#options.ejsOptions);
|
|
1034
1420
|
return this.generatePdfFromHtml(html, options);
|
|
1035
1421
|
}
|
|
1036
1422
|
async generatePdfFromNunjucksString(template, data = {}, options) {
|
|
1037
|
-
const html = requireService(this
|
|
1423
|
+
const html = requireService(this.#nunjucksService, "Nunjucks").render(template, data, options?.nunjucksOptions ?? this.#options.nunjucksOptions);
|
|
1038
1424
|
return this.generatePdfFromHtml(html, options);
|
|
1039
1425
|
}
|
|
1040
1426
|
async generatePdfFromNunjucksFile(file, data = {}, options) {
|
|
1041
|
-
const html = requireService(this
|
|
1427
|
+
const html = requireService(this.#nunjucksService, "Nunjucks").renderFile(file, data, options?.nunjucksOptions ?? this.#options.nunjucksOptions);
|
|
1042
1428
|
return this.generatePdfFromHtml(html, options);
|
|
1043
1429
|
}
|
|
1044
1430
|
async generatePdfFromEtaString(template, data = {}, options) {
|
|
1045
|
-
const html = requireService(this
|
|
1431
|
+
const html = requireService(this.#etaService, "Eta").render(template, data, options?.etaOptions ?? this.#options.etaOptions);
|
|
1046
1432
|
return this.generatePdfFromHtml(html, options);
|
|
1047
1433
|
}
|
|
1048
1434
|
async generatePdfFromEtaFile(file, data = {}, options) {
|
|
1049
|
-
const html = requireService(this
|
|
1435
|
+
const html = requireService(this.#etaService, "Eta").renderFile(file, data, options?.etaOptions ?? this.#options.etaOptions);
|
|
1050
1436
|
return this.generatePdfFromHtml(html, options);
|
|
1051
1437
|
}
|
|
1052
1438
|
async generatePdfFromMustacheString(template, data = {}, options) {
|
|
1053
|
-
const html = requireService(this
|
|
1439
|
+
const html = requireService(this.#mustacheService, "Mustache").render(template, data, options?.mustacheOptions ?? this.#options.mustacheOptions);
|
|
1054
1440
|
return this.generatePdfFromHtml(html, options);
|
|
1055
1441
|
}
|
|
1056
1442
|
async generatePdfFromMustacheFile(file, data = {}, options) {
|
|
1057
|
-
const html = requireService(this
|
|
1443
|
+
const html = requireService(this.#mustacheService, "Mustache").renderFile(file, data, options?.mustacheOptions ?? this.#options.mustacheOptions);
|
|
1058
1444
|
return this.generatePdfFromHtml(html, options);
|
|
1059
1445
|
}
|
|
1060
1446
|
};
|
|
1061
|
-
PuppeteerService = __decorate
|
|
1447
|
+
PuppeteerService = __decorate([
|
|
1062
1448
|
Injectable(),
|
|
1063
1449
|
__decorateParam(1, Inject(PDF_PARAMETERS)),
|
|
1064
1450
|
__decorateParam(2, Optional()),
|
|
@@ -1083,9 +1469,9 @@ PuppeteerService = __decorate$3([
|
|
|
1083
1469
|
//#endregion
|
|
1084
1470
|
//#region src/nestjs-pdf.service.ts
|
|
1085
1471
|
let NestjsPdfService = class NestjsPdfService {
|
|
1086
|
-
puppeteerService;
|
|
1472
|
+
#puppeteerService;
|
|
1087
1473
|
constructor(puppeteerService) {
|
|
1088
|
-
this
|
|
1474
|
+
this.#puppeteerService = puppeteerService;
|
|
1089
1475
|
}
|
|
1090
1476
|
/**
|
|
1091
1477
|
* @param html HTML string to convert to PDF
|
|
@@ -1094,7 +1480,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1094
1480
|
* @description This method uses the Puppeteer service to generate a PDF from an HTML string. Generation options can be customized by passing a `PuppeteerParameters` object as the second argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.
|
|
1095
1481
|
*/
|
|
1096
1482
|
generatePdfFromHtml(html, options) {
|
|
1097
|
-
return this
|
|
1483
|
+
return this.#puppeteerService.generatePdfFromHtml(html, options);
|
|
1098
1484
|
}
|
|
1099
1485
|
/**
|
|
1100
1486
|
* @param template Handlebars template string
|
|
@@ -1104,7 +1490,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1104
1490
|
* @description This method generates a PDF from a Handlebars template provided as a string. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.
|
|
1105
1491
|
*/
|
|
1106
1492
|
generatePdfFromTemplateHbsString(template, parameters = {}, options) {
|
|
1107
|
-
return this
|
|
1493
|
+
return this.#puppeteerService.generatePdfFromTemplateHbsString(template, parameters, options);
|
|
1108
1494
|
}
|
|
1109
1495
|
/**
|
|
1110
1496
|
* @param file Path to the Handlebars template file
|
|
@@ -1114,7 +1500,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1114
1500
|
* @description This method generates a PDF from a Handlebars template located at the specified file path. The file path is passed as a string in the `file` parameter. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.
|
|
1115
1501
|
*/
|
|
1116
1502
|
generatePdfFromTemplateHbsFile(file, parameters = {}, options) {
|
|
1117
|
-
return this
|
|
1503
|
+
return this.#puppeteerService.generatePdfFromTemplateHbsFile(file, parameters, options);
|
|
1118
1504
|
}
|
|
1119
1505
|
/**
|
|
1120
1506
|
* @param template MJML template string
|
|
@@ -1123,7 +1509,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1123
1509
|
* @description This method generates a PDF from an MJML template provided as a string. MJML (MJML Markup Language) is a markup language designed to reduce the pain of coding a responsive email. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.
|
|
1124
1510
|
*/
|
|
1125
1511
|
generatePdfFromMjmlString(template, options) {
|
|
1126
|
-
return this
|
|
1512
|
+
return this.#puppeteerService.generatePdfFromMjmlString(template, options);
|
|
1127
1513
|
}
|
|
1128
1514
|
/**
|
|
1129
1515
|
* @param file Path to the MJML template file
|
|
@@ -1132,7 +1518,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1132
1518
|
* @description This method generates a PDF from an MJML template located at the specified file path. The file path is passed as a string in the `file` parameter. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.
|
|
1133
1519
|
*/
|
|
1134
1520
|
generatePdfFromMjmlFile(file, options) {
|
|
1135
|
-
return this
|
|
1521
|
+
return this.#puppeteerService.generatePdfFromMjmlFile(file, options);
|
|
1136
1522
|
}
|
|
1137
1523
|
/**
|
|
1138
1524
|
* @param template EJS template string
|
|
@@ -1142,7 +1528,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1142
1528
|
* @description This method generates a PDF from an EJS (Embedded JavaScript) template provided as a string. EJS is a templating language with a simple, straightforward syntax. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1143
1529
|
*/
|
|
1144
1530
|
generatePdfFromEjsString(template, data = {}, options) {
|
|
1145
|
-
return this
|
|
1531
|
+
return this.#puppeteerService.generatePdfFromEjsString(template, data, options);
|
|
1146
1532
|
}
|
|
1147
1533
|
/**
|
|
1148
1534
|
* @param file Path to the EJS template file
|
|
@@ -1152,7 +1538,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1152
1538
|
* @description This method generates a PDF from an EJS template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1153
1539
|
*/
|
|
1154
1540
|
generatePdfFromEjsFile(file, data = {}, options) {
|
|
1155
|
-
return this
|
|
1541
|
+
return this.#puppeteerService.generatePdfFromEjsFile(file, data, options);
|
|
1156
1542
|
}
|
|
1157
1543
|
/**
|
|
1158
1544
|
* @param template Pug template string
|
|
@@ -1162,7 +1548,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1162
1548
|
* @description This method generates a PDF from a Pug template provided as a string. Pug is a clean, whitespace-sensitive syntax for writing HTML. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1163
1549
|
*/
|
|
1164
1550
|
generatePdfFromPugString(template, data = {}, options) {
|
|
1165
|
-
return this
|
|
1551
|
+
return this.#puppeteerService.generatePdfFromPugString(template, data, options);
|
|
1166
1552
|
}
|
|
1167
1553
|
/**
|
|
1168
1554
|
* @param file Path to the Pug template file
|
|
@@ -1172,7 +1558,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1172
1558
|
* @description This method generates a PDF from a Pug template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1173
1559
|
*/
|
|
1174
1560
|
generatePdfFromPugFile(file, data = {}, options) {
|
|
1175
|
-
return this
|
|
1561
|
+
return this.#puppeteerService.generatePdfFromPugFile(file, data, options);
|
|
1176
1562
|
}
|
|
1177
1563
|
/**
|
|
1178
1564
|
* @param template Nunjucks template string
|
|
@@ -1182,7 +1568,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1182
1568
|
* @description This method generates a PDF from a Nunjucks template provided as a string. Nunjucks is a powerful templating language with support for inheritance, macros, and filters. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1183
1569
|
*/
|
|
1184
1570
|
generatePdfFromNunjucksString(template, data = {}, options) {
|
|
1185
|
-
return this
|
|
1571
|
+
return this.#puppeteerService.generatePdfFromNunjucksString(template, data, options);
|
|
1186
1572
|
}
|
|
1187
1573
|
/**
|
|
1188
1574
|
* @param file Path to the Nunjucks template file
|
|
@@ -1192,7 +1578,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1192
1578
|
* @description This method generates a PDF from a Nunjucks template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1193
1579
|
*/
|
|
1194
1580
|
generatePdfFromNunjucksFile(file, data = {}, options) {
|
|
1195
|
-
return this
|
|
1581
|
+
return this.#puppeteerService.generatePdfFromNunjucksFile(file, data, options);
|
|
1196
1582
|
}
|
|
1197
1583
|
/**
|
|
1198
1584
|
* @param template Eta template string
|
|
@@ -1202,7 +1588,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1202
1588
|
* @description This method generates a PDF from an Eta template provided as a string. Eta is a fast and lightweight embedded templating language with a syntax similar to EJS but with better performance. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1203
1589
|
*/
|
|
1204
1590
|
generatePdfFromEtaString(template, data = {}, options) {
|
|
1205
|
-
return this
|
|
1591
|
+
return this.#puppeteerService.generatePdfFromEtaString(template, data, options);
|
|
1206
1592
|
}
|
|
1207
1593
|
/**
|
|
1208
1594
|
* @param file Path to the Eta template file
|
|
@@ -1212,7 +1598,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1212
1598
|
* @description This method generates a PDF from an Eta template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1213
1599
|
*/
|
|
1214
1600
|
generatePdfFromEtaFile(file, data = {}, options) {
|
|
1215
|
-
return this
|
|
1601
|
+
return this.#puppeteerService.generatePdfFromEtaFile(file, data, options);
|
|
1216
1602
|
}
|
|
1217
1603
|
/**
|
|
1218
1604
|
* @param template Mustache template string
|
|
@@ -1222,7 +1608,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1222
1608
|
* @description This method generates a PDF from a Mustache template provided as a string. Mustache is a logic-less template language that emphasizes readable and simple templates. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1223
1609
|
*/
|
|
1224
1610
|
generatePdfFromMustacheString(template, data = {}, options) {
|
|
1225
|
-
return this
|
|
1611
|
+
return this.#puppeteerService.generatePdfFromMustacheString(template, data, options);
|
|
1226
1612
|
}
|
|
1227
1613
|
/**
|
|
1228
1614
|
* @param file Path to the Mustache template file
|
|
@@ -1232,7 +1618,7 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1232
1618
|
* @description This method generates a PDF from a Mustache template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.
|
|
1233
1619
|
*/
|
|
1234
1620
|
generatePdfFromMustacheFile(file, data = {}, options) {
|
|
1235
|
-
return this
|
|
1621
|
+
return this.#puppeteerService.generatePdfFromMustacheFile(file, data, options);
|
|
1236
1622
|
}
|
|
1237
1623
|
/**
|
|
1238
1624
|
* @param pdf The PDF bytes to modify
|
|
@@ -1259,1307 +1645,57 @@ let NestjsPdfService = class NestjsPdfService {
|
|
|
1259
1645
|
async addSignatureFieldSignatureDebtorRaw(pdf, fieldName = "SignatureDebtor", anchorText = "__SIG_DEBTOR_ANCHOR__") {
|
|
1260
1646
|
return await addSignatureFieldUsingAnchor(pdf, fieldName, anchorText);
|
|
1261
1647
|
}
|
|
1262
|
-
};
|
|
1263
|
-
NestjsPdfService = __decorate$3([Injectable(), __decorateMetadata("design:paramtypes", [typeof PuppeteerService === "undefined" ? Object : PuppeteerService])], NestjsPdfService);
|
|
1264
|
-
//#endregion
|
|
1265
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/config.constants.js
|
|
1266
|
-
var import_main = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1267
|
-
function _resolveEscapeSequences(value) {
|
|
1268
|
-
return value.replace(/\\\$/g, "$");
|
|
1269
|
-
}
|
|
1270
|
-
function expandValue(value, processEnv, runningParsed) {
|
|
1271
|
-
const env = {
|
|
1272
|
-
...runningParsed,
|
|
1273
|
-
...processEnv
|
|
1274
|
-
};
|
|
1275
|
-
const regex = /(?<!\\)\${([^{}]+)}|(?<!\\)\$([A-Za-z_][A-Za-z0-9_]*)/g;
|
|
1276
|
-
let result = value;
|
|
1277
|
-
let match;
|
|
1278
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1279
|
-
while ((match = regex.exec(result)) !== null) {
|
|
1280
|
-
seen.add(result);
|
|
1281
|
-
const [template, bracedExpression, unbracedExpression] = match;
|
|
1282
|
-
const expression = bracedExpression || unbracedExpression;
|
|
1283
|
-
const opMatch = expression.match(/(:\+|\+|:-|-)/);
|
|
1284
|
-
const splitter = opMatch ? opMatch[0] : null;
|
|
1285
|
-
const r = expression.split(splitter);
|
|
1286
|
-
let defaultValue;
|
|
1287
|
-
let value;
|
|
1288
|
-
const key = r.shift();
|
|
1289
|
-
if ([":+", "+"].includes(splitter)) {
|
|
1290
|
-
defaultValue = env[key] ? r.join(splitter) : "";
|
|
1291
|
-
value = null;
|
|
1292
|
-
} else {
|
|
1293
|
-
defaultValue = r.join(splitter);
|
|
1294
|
-
value = env[key];
|
|
1295
|
-
}
|
|
1296
|
-
if (value) {
|
|
1297
|
-
if (seen.has(value)) result = result.replace(template, defaultValue);
|
|
1298
|
-
else result = result.replace(template, value);
|
|
1299
|
-
} else result = result.replace(template, defaultValue);
|
|
1300
|
-
if (result === runningParsed[key]) break;
|
|
1301
|
-
regex.lastIndex = 0;
|
|
1302
|
-
}
|
|
1303
|
-
return result;
|
|
1304
|
-
}
|
|
1305
|
-
function expand(options) {
|
|
1306
|
-
const runningParsed = {};
|
|
1307
|
-
let processEnv = process.env;
|
|
1308
|
-
if (options && options.processEnv != null) processEnv = options.processEnv;
|
|
1309
|
-
for (const key in options.parsed) {
|
|
1310
|
-
let value = options.parsed[key];
|
|
1311
|
-
if (processEnv[key] && processEnv[key] !== value) value = processEnv[key];
|
|
1312
|
-
else value = expandValue(value, processEnv, runningParsed);
|
|
1313
|
-
options.parsed[key] = _resolveEscapeSequences(value);
|
|
1314
|
-
runningParsed[key] = _resolveEscapeSequences(value);
|
|
1315
|
-
}
|
|
1316
|
-
for (const processKey in options.parsed) processEnv[processKey] = options.parsed[processKey];
|
|
1317
|
-
return options;
|
|
1318
|
-
}
|
|
1319
|
-
module.exports.expand = expand;
|
|
1320
|
-
})))();
|
|
1321
|
-
/**
|
|
1322
|
-
* Injection tokens
|
|
1323
|
-
*/
|
|
1324
|
-
const CONFIGURATION_SERVICE_TOKEN = Symbol("CONFIG_SERVICE");
|
|
1325
|
-
const CONFIGURATION_TOKEN = "CONFIGURATION_TOKEN";
|
|
1326
|
-
const CONFIGURATION_LOADER = "CONFIGURATION_LOADER";
|
|
1327
|
-
const VALIDATED_ENV_LOADER = "VALIDATED_ENV_LOADER";
|
|
1328
|
-
const PARTIAL_CONFIGURATION_KEY = "PARTIAL_CONFIGURATION_KEY";
|
|
1329
|
-
const VALIDATED_ENV_PROPNAME = "_PROCESS_ENV_VALIDATED";
|
|
1330
|
-
//#endregion
|
|
1331
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/_internal/isUnsafeProperty.mjs
|
|
1332
|
-
/**
|
|
1333
|
-
* Checks if a property key is unsafe to access or copy directly.
|
|
1334
|
-
*
|
|
1335
|
-
* This function is used in functions like `get`, `unset`, and `merge` to prevent
|
|
1336
|
-
* prototype pollution attacks by identifying `__proto__`, which modifies the object's
|
|
1337
|
-
* prototype chain. `constructor` and `prototype` stay accessible here because lodash
|
|
1338
|
-
* keeps reads of them unrestricted; write paths use `isUnsafeToWriteProperty` instead,
|
|
1339
|
-
* which also blocks those keys.
|
|
1340
|
-
*
|
|
1341
|
-
* @param key - The property key to check
|
|
1342
|
-
* @returns `true` if the property is unsafe to access directly, `false` otherwise
|
|
1343
|
-
* @internal
|
|
1344
|
-
*/
|
|
1345
|
-
function isUnsafeProperty(key) {
|
|
1346
|
-
return key === "__proto__";
|
|
1347
|
-
}
|
|
1348
|
-
//#endregion
|
|
1349
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/_internal/isDeepKey.mjs
|
|
1350
|
-
/** Matches any deep property path. Examples: `a.b`, `a[0]`, `a["b"]` */
|
|
1351
|
-
const regexIsDeepProp$1 = /\.|(\[(?:[^[\]]*|(["'])(?:(?!\2)[^\\]|\\.)*?\2)\])/;
|
|
1352
|
-
/**
|
|
1353
|
-
* Checks if a given key is a deep key.
|
|
1354
|
-
*
|
|
1355
|
-
* A deep key is a string that contains a dot (.) or square brackets with a property accessor.
|
|
1356
|
-
*
|
|
1357
|
-
* @param {PropertyKey} key - The key to check.
|
|
1358
|
-
* @returns {boolean} - Returns true if the key is a deep key, otherwise false.
|
|
1359
|
-
*
|
|
1360
|
-
* Examples:
|
|
1361
|
-
*
|
|
1362
|
-
* isDeepKey('a.b') // true
|
|
1363
|
-
* isDeepKey('a[b]') // true
|
|
1364
|
-
* isDeepKey('a') // false
|
|
1365
|
-
* isDeepKey(123) // false
|
|
1366
|
-
* isDeepKey('a.b.c') // true
|
|
1367
|
-
* isDeepKey('a[b][c]') // true
|
|
1368
|
-
* isDeepKey('a.') // false
|
|
1369
|
-
* isDeepKey('.a') // false
|
|
1370
|
-
* isDeepKey('a[b') // false
|
|
1371
|
-
* isDeepKey('a]b]') // false
|
|
1372
|
-
* isDeepKey('a][b') // false
|
|
1373
|
-
* isDeepKey('') // false
|
|
1374
|
-
* isDeepKey('a[0]') // true
|
|
1375
|
-
*
|
|
1376
|
-
*/
|
|
1377
|
-
function isDeepKey(key) {
|
|
1378
|
-
switch (typeof key) {
|
|
1379
|
-
case "number":
|
|
1380
|
-
case "symbol": return false;
|
|
1381
|
-
case "string":
|
|
1382
|
-
if (key === "" || key.startsWith(".") || key.endsWith(".")) return false;
|
|
1383
|
-
return regexIsDeepProp$1.test(key);
|
|
1384
|
-
default: return false;
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
//#endregion
|
|
1388
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/_internal/toKey.mjs
|
|
1389
|
-
/**
|
|
1390
|
-
* Converts `value` to a string key if it's not a string or symbol.
|
|
1391
|
-
*
|
|
1392
|
-
* @private
|
|
1393
|
-
* @param {unknown} value The value to inspect.
|
|
1394
|
-
* @returns {string|symbol} Returns the key.
|
|
1395
|
-
*/
|
|
1396
|
-
function toKey(value) {
|
|
1397
|
-
if (typeof value === "string" || typeof value === "symbol") return value;
|
|
1398
|
-
if (Object.is(value?.valueOf?.(), -0)) return "-0";
|
|
1399
|
-
return String(value);
|
|
1400
|
-
}
|
|
1401
|
-
//#endregion
|
|
1402
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/util/toString.mjs
|
|
1403
|
-
/**
|
|
1404
|
-
* Converts `value` to a string.
|
|
1405
|
-
*
|
|
1406
|
-
* An empty string is returned for `null` and `undefined` values.
|
|
1407
|
-
* The sign of `-0` is preserved.
|
|
1408
|
-
*
|
|
1409
|
-
* @param value - The value to convert.
|
|
1410
|
-
* @returns Returns the converted string.
|
|
1411
|
-
*
|
|
1412
|
-
* @example
|
|
1413
|
-
* toString(null) // returns ''
|
|
1414
|
-
* toString(undefined) // returns ''
|
|
1415
|
-
* toString(-0) // returns '-0'
|
|
1416
|
-
* toString([1, 2, -0]) // returns '1,2,-0'
|
|
1417
|
-
* toString([Symbol('a'), Symbol('b')]) // returns 'Symbol(a),Symbol(b)'
|
|
1418
|
-
*/
|
|
1419
|
-
function toString(value) {
|
|
1420
|
-
if (value == null) return "";
|
|
1421
|
-
return baseToString(value);
|
|
1422
|
-
}
|
|
1423
|
-
function baseToString(value) {
|
|
1424
|
-
if (typeof value === "string") return value;
|
|
1425
|
-
if (Array.isArray(value)) return value.map(baseToString).join(",");
|
|
1426
|
-
const result = String(value);
|
|
1427
|
-
if (result === "0" && Object.is(Number(value), -0)) return "-0";
|
|
1428
|
-
return result;
|
|
1429
|
-
}
|
|
1430
|
-
//#endregion
|
|
1431
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/util/toPath.mjs
|
|
1432
|
-
/**
|
|
1433
|
-
* Converts a deep key string into an array of path segments.
|
|
1434
|
-
*
|
|
1435
|
-
* This function takes a string representing a deep key (e.g., 'a.b.c' or 'a[b][c]') and breaks it down into an array of strings, each representing a segment of the path.
|
|
1436
|
-
*
|
|
1437
|
-
* @param deepKey - The deep key string to convert.
|
|
1438
|
-
* @returns An array of strings, each representing a segment of the path.
|
|
1439
|
-
*
|
|
1440
|
-
* Examples:
|
|
1441
|
-
*
|
|
1442
|
-
* toPath('a.b.c') // Returns ['a', 'b', 'c']
|
|
1443
|
-
* toPath('a[b][c]') // Returns ['a', 'b', 'c']
|
|
1444
|
-
* toPath('.a.b.c') // Returns ['', 'a', 'b', 'c']
|
|
1445
|
-
* toPath('a["b.c"].d') // Returns ['a', 'b.c', 'd']
|
|
1446
|
-
* toPath('') // Returns []
|
|
1447
|
-
* toPath('.a[b].c.d[e]["f.g"].h') // Returns ['', 'a', 'b', 'c', 'd', 'e', 'f.g', 'h']
|
|
1448
|
-
*/
|
|
1449
|
-
function toPath(deepKey) {
|
|
1450
|
-
if (Array.isArray(deepKey)) return deepKey.map(toKey);
|
|
1451
|
-
if (typeof deepKey === "symbol") return [deepKey];
|
|
1452
|
-
deepKey = toString(deepKey);
|
|
1453
|
-
const result = [];
|
|
1454
|
-
const length = deepKey.length;
|
|
1455
|
-
if (length === 0) return result;
|
|
1456
|
-
let index = 0;
|
|
1457
|
-
let key = "";
|
|
1458
|
-
let quoteChar = "";
|
|
1459
|
-
let bracket = false;
|
|
1460
|
-
let bracketHadQuote = false;
|
|
1461
|
-
const bracketNumberRegex = /^-?\d+(?:\.\d+)?$/;
|
|
1462
|
-
if (deepKey.charCodeAt(0) === 46) result.push("");
|
|
1463
|
-
while (index < length) {
|
|
1464
|
-
const char = deepKey[index];
|
|
1465
|
-
if (quoteChar) if (char === "\\" && index + 1 < length) {
|
|
1466
|
-
index++;
|
|
1467
|
-
key += deepKey[index];
|
|
1468
|
-
} else if (char === quoteChar) quoteChar = "";
|
|
1469
|
-
else key += char;
|
|
1470
|
-
else if (bracket) if (char === "\"" || char === "'") {
|
|
1471
|
-
quoteChar = char;
|
|
1472
|
-
bracketHadQuote = true;
|
|
1473
|
-
} else if (char === "]") {
|
|
1474
|
-
bracket = false;
|
|
1475
|
-
if (!bracketHadQuote && key.includes(".") && !bracketNumberRegex.test(key)) {
|
|
1476
|
-
const segments = key.split(".");
|
|
1477
|
-
for (let i = 0; i < segments.length; i++) if (segments[i] !== "") result.push(segments[i]);
|
|
1478
|
-
} else result.push(key);
|
|
1479
|
-
key = "";
|
|
1480
|
-
} else key += char;
|
|
1481
|
-
else if (char === "[") {
|
|
1482
|
-
bracket = true;
|
|
1483
|
-
bracketHadQuote = false;
|
|
1484
|
-
if (key) {
|
|
1485
|
-
result.push(key);
|
|
1486
|
-
key = "";
|
|
1487
|
-
}
|
|
1488
|
-
} else if (char === ".") {
|
|
1489
|
-
if (key) {
|
|
1490
|
-
result.push(key);
|
|
1491
|
-
key = "";
|
|
1492
|
-
}
|
|
1493
|
-
const next = deepKey[index + 1];
|
|
1494
|
-
if (next === void 0 || next === ".") result.push("");
|
|
1495
|
-
} else key += char;
|
|
1496
|
-
index++;
|
|
1497
|
-
}
|
|
1498
|
-
if (key) result.push(key);
|
|
1499
|
-
return result;
|
|
1500
|
-
}
|
|
1501
|
-
//#endregion
|
|
1502
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/object/get.mjs
|
|
1503
|
-
/**
|
|
1504
|
-
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
|
|
1505
|
-
*
|
|
1506
|
-
* @param object - The object to query.
|
|
1507
|
-
* @param path - The path of the property to get.
|
|
1508
|
-
* @param [defaultValue] - The value returned if the resolved value is undefined.
|
|
1509
|
-
* @returns Returns the resolved value.
|
|
1510
|
-
*
|
|
1511
|
-
* @example
|
|
1512
|
-
* const object = { a: { b: { c: 1 } } };
|
|
1513
|
-
* get(object, 'a.b.c');
|
|
1514
|
-
* // => 1
|
|
1515
|
-
*
|
|
1516
|
-
* get(object, ['a', 'b', 'c']);
|
|
1517
|
-
* // => 1
|
|
1518
|
-
*
|
|
1519
|
-
* get(object, 'a.b.d', 'default');
|
|
1520
|
-
* // => 'default'
|
|
1521
|
-
*/
|
|
1522
|
-
function get(object, path, defaultValue) {
|
|
1523
|
-
if (object == null) return defaultValue;
|
|
1524
|
-
switch (typeof path) {
|
|
1525
|
-
case "string": {
|
|
1526
|
-
if (isUnsafeProperty(path)) return defaultValue;
|
|
1527
|
-
const result = object[path];
|
|
1528
|
-
if (result === void 0) if (isDeepKey(path) && !Object.hasOwn(object, path)) return get(object, toPath(path), defaultValue);
|
|
1529
|
-
else return defaultValue;
|
|
1530
|
-
return result;
|
|
1531
|
-
}
|
|
1532
|
-
case "number":
|
|
1533
|
-
case "symbol": {
|
|
1534
|
-
if (typeof path === "number") path = toKey(path);
|
|
1535
|
-
const result = object[path];
|
|
1536
|
-
if (result === void 0) return defaultValue;
|
|
1537
|
-
return result;
|
|
1538
|
-
}
|
|
1539
|
-
default: {
|
|
1540
|
-
if (Array.isArray(path)) return getWithPath(object, path, defaultValue);
|
|
1541
|
-
if (Object.is(path?.valueOf(), -0)) path = "-0";
|
|
1542
|
-
else path = String(path);
|
|
1543
|
-
if (isUnsafeProperty(path)) return defaultValue;
|
|
1544
|
-
const result = object[path];
|
|
1545
|
-
if (result === void 0) return defaultValue;
|
|
1546
|
-
return result;
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
function getWithPath(object, path, defaultValue) {
|
|
1551
|
-
if (path.length === 0) return defaultValue;
|
|
1552
|
-
let current = object;
|
|
1553
|
-
for (let index = 0; index < path.length; index++) {
|
|
1554
|
-
if (current == null) return defaultValue;
|
|
1555
|
-
if (isUnsafeProperty(path[index])) return defaultValue;
|
|
1556
|
-
current = current[path[index]];
|
|
1557
|
-
}
|
|
1558
|
-
if (current === void 0) return defaultValue;
|
|
1559
|
-
return current;
|
|
1560
|
-
}
|
|
1561
|
-
//#endregion
|
|
1562
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/_internal/isIndex.mjs
|
|
1563
|
-
const IS_UNSIGNED_INTEGER = /^(?:0|[1-9]\d*)$/;
|
|
1564
|
-
function isIndex(value, length = Number.MAX_SAFE_INTEGER) {
|
|
1565
|
-
switch (typeof value) {
|
|
1566
|
-
case "number": return Number.isInteger(value) && value >= 0 && value < length;
|
|
1567
|
-
case "symbol": return false;
|
|
1568
|
-
case "string": return IS_UNSIGNED_INTEGER.test(value);
|
|
1569
|
-
}
|
|
1570
|
-
}
|
|
1571
|
-
//#endregion
|
|
1572
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/_internal/getTag.mjs
|
|
1573
|
-
/**
|
|
1574
|
-
* Gets the `toStringTag` of `value`.
|
|
1575
|
-
*
|
|
1576
|
-
* @private
|
|
1577
|
-
* @param {T} value The value to query.
|
|
1578
|
-
* @returns {string} Returns the `Object.prototype.toString.call` result.
|
|
1579
|
-
*/
|
|
1580
|
-
function getTag(value) {
|
|
1581
|
-
if (value == null) return value === void 0 ? "[object Undefined]" : "[object Null]";
|
|
1582
|
-
return Object.prototype.toString.call(value);
|
|
1583
|
-
}
|
|
1584
|
-
//#endregion
|
|
1585
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/predicate/isArguments.mjs
|
|
1586
|
-
/**
|
|
1587
|
-
* Checks if the given value is an arguments object.
|
|
1588
|
-
*
|
|
1589
|
-
* This function tests whether the provided value is an arguments object or not.
|
|
1590
|
-
* It returns `true` if the value is an arguments object, and `false` otherwise.
|
|
1591
|
-
*
|
|
1592
|
-
* This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to an arguments object.
|
|
1593
|
-
*
|
|
1594
|
-
* @param value - The value to test if it is an arguments object.
|
|
1595
|
-
* @returns `true` if the value is an arguments, `false` otherwise.
|
|
1596
|
-
*
|
|
1597
|
-
* @example
|
|
1598
|
-
* const args = (function() { return arguments; })();
|
|
1599
|
-
* const strictArgs = (function() { 'use strict'; return arguments; })();
|
|
1600
|
-
* const value = [1, 2, 3];
|
|
1601
|
-
*
|
|
1602
|
-
* console.log(isArguments(args)); // true
|
|
1603
|
-
* console.log(isArguments(strictArgs)); // true
|
|
1604
|
-
* console.log(isArguments(value)); // false
|
|
1605
|
-
*/
|
|
1606
|
-
function isArguments(value) {
|
|
1607
|
-
return value !== null && typeof value === "object" && getTag(value) === "[object Arguments]";
|
|
1608
|
-
}
|
|
1609
|
-
//#endregion
|
|
1610
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/object/has.mjs
|
|
1611
|
-
/**
|
|
1612
|
-
* Checks if a given path exists within an object.
|
|
1613
|
-
*
|
|
1614
|
-
* You can provide the path as a single property key, an array of property keys,
|
|
1615
|
-
* or a string representing a deep path.
|
|
1616
|
-
*
|
|
1617
|
-
* If the path is an index and the object is an array or an arguments object, the function will verify
|
|
1618
|
-
* if the index is valid and within the bounds of the array or arguments object, even if the array or
|
|
1619
|
-
* arguments object is sparse (i.e., not all indexes are defined).
|
|
1620
|
-
*
|
|
1621
|
-
* @param object - The object to query.
|
|
1622
|
-
* @param path - The path to check. This can be a single property key,
|
|
1623
|
-
* an array of property keys, or a string representing a deep path.
|
|
1624
|
-
* @returns Returns `true` if the path exists in the object, `false` otherwise.
|
|
1625
|
-
*
|
|
1626
|
-
* @example
|
|
1627
|
-
*
|
|
1628
|
-
* const obj = { a: { b: { c: 3 } } };
|
|
1629
|
-
*
|
|
1630
|
-
* has(obj, 'a'); // true
|
|
1631
|
-
* has(obj, ['a', 'b']); // true
|
|
1632
|
-
* has(obj, ['a', 'b', 'c']); // true
|
|
1633
|
-
* has(obj, 'a.b.c'); // true
|
|
1634
|
-
* has(obj, 'a.b.d'); // false
|
|
1635
|
-
* has(obj, ['a', 'b', 'c', 'd']); // false
|
|
1636
|
-
* has([], 0); // false
|
|
1637
|
-
* has([1, 2, 3], 2); // true
|
|
1638
|
-
* has([1, 2, 3], 5); // false
|
|
1639
|
-
*/
|
|
1640
|
-
function has(object, path) {
|
|
1641
|
-
let resolvedPath;
|
|
1642
|
-
if (Array.isArray(path)) resolvedPath = path;
|
|
1643
|
-
else if (typeof path === "string" && isDeepKey(path) && !(path in Object(object))) resolvedPath = toPath(path);
|
|
1644
|
-
else resolvedPath = [path];
|
|
1645
|
-
if (resolvedPath.length === 0) return false;
|
|
1646
|
-
let current = object;
|
|
1647
|
-
for (let i = 0; i < resolvedPath.length; i++) {
|
|
1648
|
-
const key = resolvedPath[i];
|
|
1649
|
-
if (current == null || !Object.hasOwn(current, key)) {
|
|
1650
|
-
if (!((Array.isArray(current) || isArguments(current)) && isIndex(key) && key < current.length)) return false;
|
|
1651
|
-
}
|
|
1652
|
-
current = current[key];
|
|
1653
|
-
}
|
|
1654
|
-
return true;
|
|
1655
|
-
}
|
|
1656
|
-
//#endregion
|
|
1657
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/predicate/isObject.mjs
|
|
1658
|
-
/**
|
|
1659
|
-
* Checks if the given value is an object. An object is a value that is
|
|
1660
|
-
* not a primitive type (string, number, boolean, symbol, null, or undefined).
|
|
1661
|
-
*
|
|
1662
|
-
* This function tests whether the provided value is an object or not.
|
|
1663
|
-
* It returns `true` if the value is an object, and `false` otherwise.
|
|
1664
|
-
*
|
|
1665
|
-
* This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to an object value.
|
|
1666
|
-
*
|
|
1667
|
-
* @param value - The value to check if it is an object.
|
|
1668
|
-
* @returns `true` if the value is an object, `false` otherwise.
|
|
1669
|
-
*
|
|
1670
|
-
* @example
|
|
1671
|
-
* const value1 = {};
|
|
1672
|
-
* const value2 = [1, 2, 3];
|
|
1673
|
-
* const value3 = () => {};
|
|
1674
|
-
* const value4 = null;
|
|
1675
|
-
*
|
|
1676
|
-
* console.log(isObject(value1)); // true
|
|
1677
|
-
* console.log(isObject(value2)); // true
|
|
1678
|
-
* console.log(isObject(value3)); // true
|
|
1679
|
-
* console.log(isObject(value4)); // false
|
|
1680
|
-
*/
|
|
1681
|
-
function isObject$1(value) {
|
|
1682
|
-
return value !== null && (typeof value === "object" || typeof value === "function");
|
|
1683
|
-
}
|
|
1684
|
-
//#endregion
|
|
1685
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/predicate/isSymbol.mjs
|
|
1686
|
-
/**
|
|
1687
|
-
* Check whether a value is a symbol.
|
|
1688
|
-
*
|
|
1689
|
-
* This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `symbol`.
|
|
1690
|
-
*
|
|
1691
|
-
* @param value The value to check.
|
|
1692
|
-
* @returns Returns `true` if `value` is a symbol, else `false`.
|
|
1693
|
-
* @example
|
|
1694
|
-
* isSymbol(Symbol.iterator);
|
|
1695
|
-
* // => true
|
|
1696
|
-
*
|
|
1697
|
-
* isSymbol('abc');
|
|
1698
|
-
* // => false
|
|
1699
|
-
*/
|
|
1700
|
-
function isSymbol(value) {
|
|
1701
|
-
return typeof value === "symbol" || value instanceof Symbol;
|
|
1702
|
-
}
|
|
1703
|
-
//#endregion
|
|
1704
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/_internal/isKey.mjs
|
|
1705
|
-
/** Matches any deep property path. (e.g. `a.b[0].c`)*/
|
|
1706
|
-
const regexIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
|
|
1707
|
-
/** Matches any word character (alphanumeric & underscore).*/
|
|
1708
|
-
const regexIsPlainProp = /^\w*$/;
|
|
1709
|
-
/**
|
|
1710
|
-
* Checks if `value` is a property name and not a property path. (It's ok that the `value` is not in the keys of the `object`)
|
|
1711
|
-
* @param {unknown} value The value to check.
|
|
1712
|
-
* @param {unknown} object The object to query.
|
|
1713
|
-
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
|
|
1714
|
-
*
|
|
1715
|
-
* @example
|
|
1716
|
-
* isKey('a', { a: 1 });
|
|
1717
|
-
* // => true
|
|
1718
|
-
*
|
|
1719
|
-
* isKey('a.b', { a: { b: 2 } });
|
|
1720
|
-
* // => false
|
|
1721
|
-
*/
|
|
1722
|
-
function isKey(value, object) {
|
|
1723
|
-
if (Array.isArray(value)) return false;
|
|
1724
|
-
if (typeof value === "number" || typeof value === "boolean" || value == null || isSymbol(value)) return true;
|
|
1725
|
-
return typeof value === "string" && (regexIsPlainProp.test(value) || !regexIsDeepProp.test(value)) || object != null && Object.hasOwn(object, value);
|
|
1726
|
-
}
|
|
1727
|
-
//#endregion
|
|
1728
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/util/eq.mjs
|
|
1729
|
-
/**
|
|
1730
|
-
* Performs a `SameValueZero` comparison between two values to determine if they are equivalent.
|
|
1731
|
-
*
|
|
1732
|
-
* @param value The value to compare.
|
|
1733
|
-
* @param other The other value to compare.
|
|
1734
|
-
* @returns Returns `true` if the values are equivalent, else `false`.
|
|
1735
|
-
*
|
|
1736
|
-
* @example
|
|
1737
|
-
* eq(1, 1); // true
|
|
1738
|
-
* eq(0, -0); // true
|
|
1739
|
-
* eq(NaN, NaN); // true
|
|
1740
|
-
* eq('a', Object('a')); // false
|
|
1741
|
-
*/
|
|
1742
|
-
function eq(value, other) {
|
|
1743
|
-
return value === other || Number.isNaN(value) && Number.isNaN(other);
|
|
1744
|
-
}
|
|
1745
|
-
//#endregion
|
|
1746
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/_internal/assignValue.mjs
|
|
1747
|
-
const assignValue = (object, key, value) => {
|
|
1748
|
-
const objValue = object[key];
|
|
1749
|
-
if (!(Object.hasOwn(object, key) && eq(objValue, value)) || value === void 0 && !(key in object)) object[key] = value;
|
|
1750
|
-
};
|
|
1751
|
-
//#endregion
|
|
1752
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/_internal/isUnsafeToWriteProperty.mjs
|
|
1753
|
-
/**
|
|
1754
|
-
* Checks if a property key is unsafe to write to.
|
|
1755
|
-
*
|
|
1756
|
-
* Writing through `__proto__`, `constructor`, or `prototype` can reach
|
|
1757
|
-
* `Object.prototype` and pollute every object, so write paths like `set`,
|
|
1758
|
-
* `update`, and `zipObjectDeep` abort when a path segment matches one of
|
|
1759
|
-
* these keys, matching lodash's behavior.
|
|
1760
|
-
*
|
|
1761
|
-
* Read paths like `get` and `unset` use `isUnsafeProperty` instead, which
|
|
1762
|
-
* only blocks `__proto__`; lodash keeps reads of `constructor` and
|
|
1763
|
-
* `prototype` unrestricted.
|
|
1764
|
-
*
|
|
1765
|
-
* @param key - The property key to check
|
|
1766
|
-
* @returns `true` if the property is unsafe to write to, `false` otherwise
|
|
1767
|
-
* @internal
|
|
1768
|
-
*/
|
|
1769
|
-
function isUnsafeToWriteProperty(key) {
|
|
1770
|
-
return key === "__proto__" || key === "constructor" || key === "prototype";
|
|
1771
|
-
}
|
|
1772
|
-
//#endregion
|
|
1773
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/object/updateWith.mjs
|
|
1774
|
-
/**
|
|
1775
|
-
* Updates the value at the specified path of the given object using an updater function and a customizer.
|
|
1776
|
-
* If any part of the path does not exist, it will be created.
|
|
1777
|
-
*
|
|
1778
|
-
* @template T - The type of the object.
|
|
1779
|
-
* @template R - The type of the return value.
|
|
1780
|
-
* @param obj - The object to modify.
|
|
1781
|
-
* @param path - The path of the property to update.
|
|
1782
|
-
* @param updater - The function to produce the updated value.
|
|
1783
|
-
* @param customizer - The function to customize the update process.
|
|
1784
|
-
* @returns The modified object.
|
|
1785
|
-
*
|
|
1786
|
-
* @example
|
|
1787
|
-
* const object = { 'a': [{ 'b': { 'c': 3 } }] };
|
|
1788
|
-
* updateWith(object, 'a[0].b.c', (n) => n * n);
|
|
1789
|
-
* // => { 'a': [{ 'b': { 'c': 9 } }] }
|
|
1790
|
-
*/
|
|
1791
|
-
function updateWith(obj, path, updater, customizer) {
|
|
1792
|
-
if (obj == null && !isObject$1(obj)) return obj;
|
|
1793
|
-
let resolvedPath;
|
|
1794
|
-
if (isKey(path, obj)) resolvedPath = [path];
|
|
1795
|
-
else if (Array.isArray(path)) resolvedPath = path;
|
|
1796
|
-
else resolvedPath = toPath(path);
|
|
1797
|
-
const updateValue = updater(get(obj, resolvedPath));
|
|
1798
|
-
let current = obj;
|
|
1799
|
-
for (let i = 0; i < resolvedPath.length && current != null; i++) {
|
|
1800
|
-
const key = toKey(resolvedPath[i]);
|
|
1801
|
-
if (isUnsafeToWriteProperty(key)) return obj;
|
|
1802
|
-
let newValue;
|
|
1803
|
-
if (i === resolvedPath.length - 1) newValue = updateValue;
|
|
1804
|
-
else {
|
|
1805
|
-
const objValue = current[key];
|
|
1806
|
-
const customizerResult = customizer?.(objValue, key, obj);
|
|
1807
|
-
newValue = customizerResult !== void 0 ? customizerResult : isObject$1(objValue) ? objValue : isIndex(resolvedPath[i + 1]) ? [] : {};
|
|
1808
|
-
}
|
|
1809
|
-
assignValue(current, key, newValue);
|
|
1810
|
-
current = current[key];
|
|
1811
|
-
}
|
|
1812
|
-
return obj;
|
|
1813
|
-
}
|
|
1814
|
-
//#endregion
|
|
1815
|
-
//#region node_modules/.pnpm/es-toolkit@1.51.0/node_modules/es-toolkit/dist/compat/object/set.mjs
|
|
1816
|
-
/**
|
|
1817
|
-
* Sets the value at the specified path of the given object. If any part of the path does not exist, it will be created.
|
|
1818
|
-
*
|
|
1819
|
-
* @template T - The type of the object.
|
|
1820
|
-
* @param obj - The object to modify.
|
|
1821
|
-
* @param path - The path of the property to set.
|
|
1822
|
-
* @param value - The value to set.
|
|
1823
|
-
* @returns The modified object.
|
|
1824
|
-
*
|
|
1825
|
-
* @example
|
|
1826
|
-
* // Set a value in a nested object
|
|
1827
|
-
* const obj = { a: { b: { c: 3 } } };
|
|
1828
|
-
* set(obj, 'a.b.c', 4);
|
|
1829
|
-
* console.log(obj.a.b.c); // 4
|
|
1830
|
-
*
|
|
1831
|
-
* @example
|
|
1832
|
-
* // Set a value in an array
|
|
1833
|
-
* const arr = [1, 2, 3];
|
|
1834
|
-
* set(arr, 1, 4);
|
|
1835
|
-
* console.log(arr[1]); // 4
|
|
1836
|
-
*
|
|
1837
|
-
* @example
|
|
1838
|
-
* // Create non-existent path and set value
|
|
1839
|
-
* const obj = {};
|
|
1840
|
-
* set(obj, 'a.b.c', 4);
|
|
1841
|
-
* console.log(obj); // { a: { b: { c: 4 } } }
|
|
1842
|
-
*/
|
|
1843
|
-
function set(obj, path, value) {
|
|
1844
|
-
return updateWith(obj, path, () => value, () => void 0);
|
|
1845
|
-
}
|
|
1846
|
-
//#endregion
|
|
1847
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/utils/get-config-token.util.js
|
|
1848
|
-
/**
|
|
1849
|
-
* @publicApi
|
|
1850
|
-
*/
|
|
1851
|
-
function getConfigToken(token) {
|
|
1852
|
-
return `CONFIGURATION(${token.toString()})`;
|
|
1853
|
-
}
|
|
1854
|
-
//#endregion
|
|
1855
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/utils/get-default-parser.util.js
|
|
1856
|
-
var import_main$1 = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1857
|
-
const fs$2 = __require("fs");
|
|
1858
|
-
const path = __require("path");
|
|
1859
|
-
const os = __require("os");
|
|
1860
|
-
const crypto = __require("crypto");
|
|
1861
|
-
const TIPS = [
|
|
1862
|
-
"◈ encrypted .env [www.dotenvx.com]",
|
|
1863
|
-
"◈ secrets for agents [www.dotenvx.com]",
|
|
1864
|
-
"⌁ auth for agents [www.vestauth.com]",
|
|
1865
|
-
"⌘ custom filepath { path: '/custom/path/.env' }",
|
|
1866
|
-
"⌘ enable debugging { debug: true }",
|
|
1867
|
-
"⌘ override existing { override: true }",
|
|
1868
|
-
"⌘ suppress logs { quiet: true }",
|
|
1869
|
-
"⌘ multiple files { path: ['.env.local', '.env'] }"
|
|
1870
|
-
];
|
|
1871
|
-
function _getRandomTip() {
|
|
1872
|
-
return TIPS[Math.floor(Math.random() * TIPS.length)];
|
|
1873
|
-
}
|
|
1874
|
-
function parseBoolean(value) {
|
|
1875
|
-
if (typeof value === "string") return ![
|
|
1876
|
-
"false",
|
|
1877
|
-
"0",
|
|
1878
|
-
"no",
|
|
1879
|
-
"off",
|
|
1880
|
-
""
|
|
1881
|
-
].includes(value.toLowerCase());
|
|
1882
|
-
return Boolean(value);
|
|
1883
|
-
}
|
|
1884
|
-
function supportsAnsi() {
|
|
1885
|
-
return process.stdout.isTTY;
|
|
1886
|
-
}
|
|
1887
|
-
function dim(text) {
|
|
1888
|
-
return supportsAnsi() ? `\x1b[2m${text}\x1b[0m` : text;
|
|
1889
|
-
}
|
|
1890
|
-
const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/gm;
|
|
1891
|
-
function parse(src) {
|
|
1892
|
-
const obj = {};
|
|
1893
|
-
let lines = src.toString();
|
|
1894
|
-
lines = lines.replace(/\r\n?/gm, "\n");
|
|
1895
|
-
let match;
|
|
1896
|
-
while ((match = LINE.exec(lines)) != null) {
|
|
1897
|
-
const key = match[1];
|
|
1898
|
-
let value = match[2] || "";
|
|
1899
|
-
value = value.trim();
|
|
1900
|
-
const maybeQuote = value[0];
|
|
1901
|
-
value = value.replace(/^(['"`])([\s\S]*)\1$/gm, "$2");
|
|
1902
|
-
if (maybeQuote === "\"") {
|
|
1903
|
-
value = value.replace(/\\n/g, "\n");
|
|
1904
|
-
value = value.replace(/\\r/g, "\r");
|
|
1905
|
-
}
|
|
1906
|
-
obj[key] = value;
|
|
1907
|
-
}
|
|
1908
|
-
return obj;
|
|
1909
|
-
}
|
|
1910
|
-
function _parseVault(options) {
|
|
1911
|
-
options = options || {};
|
|
1912
|
-
const vaultPath = _vaultPath(options);
|
|
1913
|
-
options.path = vaultPath;
|
|
1914
|
-
const result = DotenvModule.configDotenv(options);
|
|
1915
|
-
if (!result.parsed) {
|
|
1916
|
-
const err = /* @__PURE__ */ new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
|
|
1917
|
-
err.code = "MISSING_DATA";
|
|
1918
|
-
throw err;
|
|
1919
|
-
}
|
|
1920
|
-
const keys = _dotenvKey(options).split(",");
|
|
1921
|
-
const length = keys.length;
|
|
1922
|
-
let decrypted;
|
|
1923
|
-
for (let i = 0; i < length; i++) try {
|
|
1924
|
-
const attrs = _instructions(result, keys[i].trim());
|
|
1925
|
-
decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
|
|
1926
|
-
break;
|
|
1927
|
-
} catch (error) {
|
|
1928
|
-
if (i + 1 >= length) throw error;
|
|
1929
|
-
}
|
|
1930
|
-
return DotenvModule.parse(decrypted);
|
|
1931
|
-
}
|
|
1932
|
-
function _warn(message) {
|
|
1933
|
-
console.error(`⚠ ${message}`);
|
|
1934
|
-
}
|
|
1935
|
-
function _debug(message) {
|
|
1936
|
-
console.log(`┆ ${message}`);
|
|
1937
|
-
}
|
|
1938
|
-
function _log(message) {
|
|
1939
|
-
console.log(`◇ ${message}`);
|
|
1940
|
-
}
|
|
1941
|
-
function _dotenvKey(options) {
|
|
1942
|
-
if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) return options.DOTENV_KEY;
|
|
1943
|
-
if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) return process.env.DOTENV_KEY;
|
|
1944
|
-
return "";
|
|
1945
|
-
}
|
|
1946
|
-
function _instructions(result, dotenvKey) {
|
|
1947
|
-
let uri;
|
|
1948
|
-
try {
|
|
1949
|
-
uri = new URL(dotenvKey);
|
|
1950
|
-
} catch (error) {
|
|
1951
|
-
if (error.code === "ERR_INVALID_URL") {
|
|
1952
|
-
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
|
|
1953
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
1954
|
-
throw err;
|
|
1955
|
-
}
|
|
1956
|
-
throw error;
|
|
1957
|
-
}
|
|
1958
|
-
const key = uri.password;
|
|
1959
|
-
if (!key) {
|
|
1960
|
-
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: Missing key part");
|
|
1961
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
1962
|
-
throw err;
|
|
1963
|
-
}
|
|
1964
|
-
const environment = uri.searchParams.get("environment");
|
|
1965
|
-
if (!environment) {
|
|
1966
|
-
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: Missing environment part");
|
|
1967
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
1968
|
-
throw err;
|
|
1969
|
-
}
|
|
1970
|
-
const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
|
|
1971
|
-
const ciphertext = result.parsed[environmentKey];
|
|
1972
|
-
if (!ciphertext) {
|
|
1973
|
-
const err = /* @__PURE__ */ new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
|
|
1974
|
-
err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
|
|
1975
|
-
throw err;
|
|
1976
|
-
}
|
|
1977
|
-
return {
|
|
1978
|
-
ciphertext,
|
|
1979
|
-
key
|
|
1980
|
-
};
|
|
1981
|
-
}
|
|
1982
|
-
function _vaultPath(options) {
|
|
1983
|
-
let possibleVaultPath = null;
|
|
1984
|
-
if (options && options.path && options.path.length > 0) {
|
|
1985
|
-
if (Array.isArray(options.path)) {
|
|
1986
|
-
for (const filepath of options.path) if (fs$2.existsSync(filepath)) possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
1987
|
-
} else possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
1988
|
-
} else possibleVaultPath = path.resolve(process.cwd(), ".env.vault");
|
|
1989
|
-
if (fs$2.existsSync(possibleVaultPath)) return possibleVaultPath;
|
|
1990
|
-
return null;
|
|
1991
|
-
}
|
|
1992
|
-
function _resolveHome(envPath) {
|
|
1993
|
-
return envPath[0] === "~" ? path.join(os.homedir(), envPath.slice(1)) : envPath;
|
|
1994
|
-
}
|
|
1995
|
-
function _configVault(options) {
|
|
1996
|
-
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
1997
|
-
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
1998
|
-
if (debug || !quiet) _log("loading env from encrypted .env.vault");
|
|
1999
|
-
const parsed = DotenvModule._parseVault(options);
|
|
2000
|
-
let processEnv = process.env;
|
|
2001
|
-
if (options && options.processEnv != null) processEnv = options.processEnv;
|
|
2002
|
-
DotenvModule.populate(processEnv, parsed, options);
|
|
2003
|
-
return { parsed };
|
|
2004
|
-
}
|
|
2005
|
-
function configDotenv(options) {
|
|
2006
|
-
const dotenvPath = path.resolve(process.cwd(), ".env");
|
|
2007
|
-
let encoding = "utf8";
|
|
2008
|
-
let processEnv = process.env;
|
|
2009
|
-
if (options && options.processEnv != null) processEnv = options.processEnv;
|
|
2010
|
-
let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
2011
|
-
let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
2012
|
-
if (options && options.encoding) encoding = options.encoding;
|
|
2013
|
-
else if (debug) _debug("no encoding is specified (UTF-8 is used by default)");
|
|
2014
|
-
let optionPaths = [dotenvPath];
|
|
2015
|
-
if (options && options.path) {
|
|
2016
|
-
if (!Array.isArray(options.path)) optionPaths = [_resolveHome(options.path)];
|
|
2017
|
-
else {
|
|
2018
|
-
optionPaths = [];
|
|
2019
|
-
for (const filepath of options.path) optionPaths.push(_resolveHome(filepath));
|
|
2020
|
-
}
|
|
2021
|
-
}
|
|
2022
|
-
let lastError;
|
|
2023
|
-
const parsedAll = {};
|
|
2024
|
-
for (const path of optionPaths) try {
|
|
2025
|
-
const parsed = DotenvModule.parse(fs$2.readFileSync(path, { encoding }));
|
|
2026
|
-
DotenvModule.populate(parsedAll, parsed, options);
|
|
2027
|
-
} catch (e) {
|
|
2028
|
-
if (debug) _debug(`failed to load ${path} ${e.message}`);
|
|
2029
|
-
lastError = e;
|
|
2030
|
-
}
|
|
2031
|
-
const populated = DotenvModule.populate(processEnv, parsedAll, options);
|
|
2032
|
-
debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
|
|
2033
|
-
quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
|
|
2034
|
-
if (debug || !quiet) {
|
|
2035
|
-
const keysCount = Object.keys(populated).length;
|
|
2036
|
-
const shortPaths = [];
|
|
2037
|
-
for (const filePath of optionPaths) try {
|
|
2038
|
-
const relative = path.relative(process.cwd(), filePath);
|
|
2039
|
-
shortPaths.push(relative);
|
|
2040
|
-
} catch (e) {
|
|
2041
|
-
if (debug) _debug(`failed to load ${filePath} ${e.message}`);
|
|
2042
|
-
lastError = e;
|
|
2043
|
-
}
|
|
2044
|
-
_log(`injected env (${keysCount}) from ${shortPaths.join(",")} ${dim(`// tip: ${_getRandomTip()}`)}`);
|
|
2045
|
-
}
|
|
2046
|
-
if (lastError) return {
|
|
2047
|
-
parsed: parsedAll,
|
|
2048
|
-
error: lastError
|
|
2049
|
-
};
|
|
2050
|
-
else return { parsed: parsedAll };
|
|
2051
|
-
}
|
|
2052
|
-
function config(options) {
|
|
2053
|
-
if (_dotenvKey(options).length === 0) return DotenvModule.configDotenv(options);
|
|
2054
|
-
const vaultPath = _vaultPath(options);
|
|
2055
|
-
if (!vaultPath) {
|
|
2056
|
-
_warn(`you set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}`);
|
|
2057
|
-
return DotenvModule.configDotenv(options);
|
|
2058
|
-
}
|
|
2059
|
-
return DotenvModule._configVault(options);
|
|
2060
|
-
}
|
|
2061
|
-
function decrypt(encrypted, keyStr) {
|
|
2062
|
-
const key = Buffer.from(keyStr.slice(-64), "hex");
|
|
2063
|
-
let ciphertext = Buffer.from(encrypted, "base64");
|
|
2064
|
-
const nonce = ciphertext.subarray(0, 12);
|
|
2065
|
-
const authTag = ciphertext.subarray(-16);
|
|
2066
|
-
ciphertext = ciphertext.subarray(12, -16);
|
|
2067
|
-
try {
|
|
2068
|
-
const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
|
|
2069
|
-
aesgcm.setAuthTag(authTag);
|
|
2070
|
-
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
2071
|
-
} catch (error) {
|
|
2072
|
-
const isRange = error instanceof RangeError;
|
|
2073
|
-
const invalidKeyLength = error.message === "Invalid key length";
|
|
2074
|
-
const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
|
|
2075
|
-
if (isRange || invalidKeyLength) {
|
|
2076
|
-
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
|
|
2077
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
2078
|
-
throw err;
|
|
2079
|
-
} else if (decryptionFailed) {
|
|
2080
|
-
const err = /* @__PURE__ */ new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
|
|
2081
|
-
err.code = "DECRYPTION_FAILED";
|
|
2082
|
-
throw err;
|
|
2083
|
-
} else throw error;
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2086
|
-
function populate(processEnv, parsed, options = {}) {
|
|
2087
|
-
const debug = Boolean(options && options.debug);
|
|
2088
|
-
const override = Boolean(options && options.override);
|
|
2089
|
-
const populated = {};
|
|
2090
|
-
if (typeof parsed !== "object") {
|
|
2091
|
-
const err = /* @__PURE__ */ new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
2092
|
-
err.code = "OBJECT_REQUIRED";
|
|
2093
|
-
throw err;
|
|
2094
|
-
}
|
|
2095
|
-
for (const key of Object.keys(parsed)) if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
|
|
2096
|
-
if (override === true) {
|
|
2097
|
-
processEnv[key] = parsed[key];
|
|
2098
|
-
populated[key] = parsed[key];
|
|
2099
|
-
}
|
|
2100
|
-
if (debug) {
|
|
2101
|
-
if (override === true) _debug(`"${key}" is already defined and WAS overwritten`);
|
|
2102
|
-
else _debug(`"${key}" is already defined and was NOT overwritten`);
|
|
2103
|
-
}
|
|
2104
|
-
} else {
|
|
2105
|
-
processEnv[key] = parsed[key];
|
|
2106
|
-
populated[key] = parsed[key];
|
|
2107
|
-
}
|
|
2108
|
-
return populated;
|
|
2109
|
-
}
|
|
2110
|
-
const DotenvModule = {
|
|
2111
|
-
configDotenv,
|
|
2112
|
-
_configVault,
|
|
2113
|
-
_parseVault,
|
|
2114
|
-
config,
|
|
2115
|
-
decrypt,
|
|
2116
|
-
parse,
|
|
2117
|
-
populate
|
|
2118
|
-
};
|
|
2119
|
-
module.exports.configDotenv = DotenvModule.configDotenv;
|
|
2120
|
-
module.exports._configVault = DotenvModule._configVault;
|
|
2121
|
-
module.exports._parseVault = DotenvModule._parseVault;
|
|
2122
|
-
module.exports.config = DotenvModule.config;
|
|
2123
|
-
module.exports.decrypt = DotenvModule.decrypt;
|
|
2124
|
-
module.exports.parse = DotenvModule.parse;
|
|
2125
|
-
module.exports.populate = DotenvModule.populate;
|
|
2126
|
-
module.exports = DotenvModule;
|
|
2127
|
-
})))(), 1);
|
|
2128
|
-
const getDefaultParser = () => import_main$1.parse;
|
|
2129
|
-
//#endregion
|
|
2130
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/config.service.js
|
|
2131
|
-
var __decorate$2 = function(decorators, target, key, desc) {
|
|
2132
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2133
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2134
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2135
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2136
|
-
};
|
|
2137
|
-
var __metadata = function(k, v) {
|
|
2138
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2139
|
-
};
|
|
2140
|
-
var __param = function(paramIndex, decorator) {
|
|
2141
|
-
return function(target, key) {
|
|
2142
|
-
decorator(target, key, paramIndex);
|
|
2143
|
-
};
|
|
2144
|
-
};
|
|
2145
|
-
/**
|
|
2146
|
-
* @publicApi
|
|
2147
|
-
*/
|
|
2148
|
-
let ConfigService = class ConfigService {
|
|
2149
|
-
set isCacheEnabled(value) {
|
|
2150
|
-
this._isCacheEnabled = value;
|
|
2151
|
-
}
|
|
2152
|
-
get isCacheEnabled() {
|
|
2153
|
-
return this._isCacheEnabled;
|
|
2154
|
-
}
|
|
2155
|
-
set skipProcessEnv(value) {
|
|
2156
|
-
this._skipProcessEnv = value;
|
|
2157
|
-
}
|
|
2158
|
-
get skipProcessEnv() {
|
|
2159
|
-
return this._skipProcessEnv;
|
|
2160
|
-
}
|
|
2161
|
-
constructor(internalConfig = {}) {
|
|
2162
|
-
this.internalConfig = internalConfig;
|
|
2163
|
-
this.cache = {};
|
|
2164
|
-
this._changes$ = new Subject();
|
|
2165
|
-
this._skipProcessEnv = false;
|
|
2166
|
-
this._isCacheEnabled = false;
|
|
2167
|
-
this.envFilePaths = [];
|
|
2168
|
-
this.parser = getDefaultParser();
|
|
2169
|
-
}
|
|
2170
|
-
/**
|
|
2171
|
-
* Returns a stream of configuration changes.
|
|
2172
|
-
* Each event contains the attribute path, the old value and the new value.
|
|
2173
|
-
*/
|
|
2174
|
-
get changes$() {
|
|
2175
|
-
return this._changes$.asObservable();
|
|
2176
|
-
}
|
|
2177
1648
|
/**
|
|
2178
|
-
*
|
|
2179
|
-
*
|
|
2180
|
-
*
|
|
2181
|
-
* @
|
|
2182
|
-
*
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
}
|
|
2194
|
-
return defaultValue;
|
|
2195
|
-
}
|
|
2196
|
-
/**
|
|
2197
|
-
* Get a configuration value (either custom configuration or process environment variable)
|
|
2198
|
-
* based on property path (you can use dot notation to traverse nested object, e.g. "database.host").
|
|
2199
|
-
* It returns a default value if the key does not exist.
|
|
2200
|
-
* If the default value is undefined an exception will be thrown.
|
|
2201
|
-
* @param propertyPath
|
|
2202
|
-
* @param defaultValueOrOptions
|
|
2203
|
-
*/
|
|
2204
|
-
getOrThrow(propertyPath, defaultValueOrOptions, options) {
|
|
2205
|
-
const value = this.get(propertyPath, defaultValueOrOptions, options);
|
|
2206
|
-
if (isUndefined(value)) throw new TypeError(`Configuration key "${propertyPath.toString()}" does not exist`);
|
|
2207
|
-
return value;
|
|
2208
|
-
}
|
|
2209
|
-
/**
|
|
2210
|
-
* Sets a configuration value based on property path.
|
|
2211
|
-
* @param propertyPath
|
|
2212
|
-
* @param value
|
|
2213
|
-
*/
|
|
2214
|
-
set(propertyPath, value) {
|
|
2215
|
-
const oldValue = this.get(propertyPath);
|
|
2216
|
-
set(this.internalConfig, propertyPath, value);
|
|
2217
|
-
if (typeof propertyPath === "string") {
|
|
2218
|
-
process.env[propertyPath] = String(value);
|
|
2219
|
-
this.updateInterpolatedEnv(propertyPath, String(value));
|
|
2220
|
-
}
|
|
2221
|
-
if (this.isCacheEnabled) this.setInCacheIfDefined(propertyPath, value);
|
|
2222
|
-
this._changes$.next({
|
|
2223
|
-
path: propertyPath,
|
|
2224
|
-
oldValue,
|
|
2225
|
-
newValue: value
|
|
2226
|
-
});
|
|
2227
|
-
}
|
|
2228
|
-
/**
|
|
2229
|
-
* Sets env file paths from `config.module.ts` to parse.
|
|
2230
|
-
* @param paths
|
|
2231
|
-
*/
|
|
2232
|
-
setEnvFilePaths(paths) {
|
|
2233
|
-
this.envFilePaths = paths;
|
|
2234
|
-
}
|
|
2235
|
-
/**
|
|
2236
|
-
* Sets parser from `config.module.ts`.
|
|
2237
|
-
* @param parser
|
|
2238
|
-
*/
|
|
2239
|
-
setParser(parser) {
|
|
2240
|
-
this.parser = parser;
|
|
2241
|
-
}
|
|
2242
|
-
getFromCache(propertyPath, defaultValue) {
|
|
2243
|
-
const cachedValue = get(this.cache, propertyPath);
|
|
2244
|
-
return isUndefined(cachedValue) ? defaultValue : cachedValue;
|
|
2245
|
-
}
|
|
2246
|
-
getFromValidatedEnv(propertyPath) {
|
|
2247
|
-
return get(this.internalConfig[VALIDATED_ENV_PROPNAME], propertyPath);
|
|
2248
|
-
}
|
|
2249
|
-
getFromProcessEnv(propertyPath, defaultValue) {
|
|
2250
|
-
if (this.isCacheEnabled && has(this.cache, propertyPath)) {
|
|
2251
|
-
const cachedValue = this.getFromCache(propertyPath, defaultValue);
|
|
2252
|
-
return !isUndefined(cachedValue) ? cachedValue : defaultValue;
|
|
2253
|
-
}
|
|
2254
|
-
const processValue = get(process.env, propertyPath);
|
|
2255
|
-
this.setInCacheIfDefined(propertyPath, processValue);
|
|
2256
|
-
return processValue;
|
|
2257
|
-
}
|
|
2258
|
-
getFromInternalConfig(propertyPath) {
|
|
2259
|
-
return get(this.internalConfig, propertyPath);
|
|
2260
|
-
}
|
|
2261
|
-
setInCacheIfDefined(propertyPath, value) {
|
|
2262
|
-
if (typeof value === "undefined") return;
|
|
2263
|
-
set(this.cache, propertyPath, value);
|
|
2264
|
-
}
|
|
2265
|
-
isGetOptionsObject(options) {
|
|
2266
|
-
return options && options?.infer && Object.keys(options).length === 1;
|
|
2267
|
-
}
|
|
2268
|
-
updateInterpolatedEnv(propertyPath, value) {
|
|
2269
|
-
let config = {};
|
|
2270
|
-
for (const envFilePath of this.envFilePaths) if (fs.existsSync(envFilePath)) config = Object.assign(this.parser(fs.readFileSync(envFilePath)), config);
|
|
2271
|
-
const regex = new RegExp(`\\$\\{?${propertyPath}\\}?`, "g");
|
|
2272
|
-
for (const [k, v] of Object.entries(config)) if (regex.test(v)) process.env[k] = v.replace(regex, value);
|
|
2273
|
-
}
|
|
2274
|
-
};
|
|
2275
|
-
ConfigService = __decorate$2([
|
|
2276
|
-
Injectable(),
|
|
2277
|
-
__param(0, Optional()),
|
|
2278
|
-
__param(0, Inject(CONFIGURATION_TOKEN)),
|
|
2279
|
-
__metadata("design:paramtypes", [Object])
|
|
2280
|
-
], ConfigService);
|
|
2281
|
-
//#endregion
|
|
2282
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/config-host.module.js
|
|
2283
|
-
var __decorate$1 = function(decorators, target, key, desc) {
|
|
2284
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2285
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2286
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2287
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2288
|
-
};
|
|
2289
|
-
/**
|
|
2290
|
-
* @publicApi
|
|
2291
|
-
*/
|
|
2292
|
-
let ConfigHostModule = class ConfigHostModule {};
|
|
2293
|
-
ConfigHostModule = __decorate$1([Global(), Module({
|
|
2294
|
-
providers: [{
|
|
2295
|
-
provide: CONFIGURATION_TOKEN,
|
|
2296
|
-
useFactory: () => ({})
|
|
2297
|
-
}, {
|
|
2298
|
-
provide: CONFIGURATION_SERVICE_TOKEN,
|
|
2299
|
-
useClass: ConfigService
|
|
2300
|
-
}],
|
|
2301
|
-
exports: [CONFIGURATION_TOKEN, CONFIGURATION_SERVICE_TOKEN]
|
|
2302
|
-
})], ConfigHostModule);
|
|
2303
|
-
//#endregion
|
|
2304
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/utils/create-config-factory.util.js
|
|
2305
|
-
/**
|
|
2306
|
-
* @publicApi
|
|
2307
|
-
*/
|
|
2308
|
-
function createConfigProvider(factory) {
|
|
2309
|
-
return {
|
|
2310
|
-
provide: factory.KEY || getConfigToken(randomUUID()),
|
|
2311
|
-
useFactory: factory,
|
|
2312
|
-
inject: []
|
|
2313
|
-
};
|
|
2314
|
-
}
|
|
2315
|
-
//#endregion
|
|
2316
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/utils/get-registration-token.util.js
|
|
2317
|
-
/**
|
|
2318
|
-
* @publicApi
|
|
2319
|
-
*/
|
|
2320
|
-
function getRegistrationToken(config) {
|
|
2321
|
-
return config[PARTIAL_CONFIGURATION_KEY];
|
|
2322
|
-
}
|
|
2323
|
-
//#endregion
|
|
2324
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/utils/merge-configs.util.js
|
|
2325
|
-
/**
|
|
2326
|
-
* @publicApi
|
|
2327
|
-
*/
|
|
2328
|
-
function mergeConfigObject(host, partial, token) {
|
|
2329
|
-
if (token) {
|
|
2330
|
-
set(host, token, partial);
|
|
2331
|
-
return partial;
|
|
2332
|
-
}
|
|
2333
|
-
Object.assign(host, partial);
|
|
2334
|
-
}
|
|
2335
|
-
//#endregion
|
|
2336
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/utils/validate-with-schema.util.js
|
|
2337
|
-
/**
|
|
2338
|
-
* Joi defaults to `allowUnknown: false` and `abortEarly: true`, which would
|
|
2339
|
-
* reject the unrelated variables that are always present in `process.env` and
|
|
2340
|
-
* report only the first failure. Previous versions of this package overrode
|
|
2341
|
-
* both, so they remain the defaults for Joi schemas unless the user opts out.
|
|
2342
|
-
*/
|
|
2343
|
-
const JOI_DEFAULT_LIBRARY_OPTIONS = {
|
|
2344
|
-
abortEarly: false,
|
|
2345
|
-
allowUnknown: true
|
|
2346
|
-
};
|
|
2347
|
-
/**
|
|
2348
|
-
* Validates config using a Standard Schema (e.g. Zod, Arktype).
|
|
2349
|
-
* @see https://standardschema.dev/
|
|
2350
|
-
*/
|
|
2351
|
-
async function validateWithStandardSchema(schema, config, options) {
|
|
2352
|
-
const result = await schema["~standard"].validate(config, getLibraryOptions(schema, options));
|
|
2353
|
-
if (result.issues) return {
|
|
2354
|
-
error: new Error(formatIssues(result.issues)),
|
|
2355
|
-
value: config
|
|
2356
|
-
};
|
|
2357
|
-
return { value: result.value };
|
|
2358
|
-
}
|
|
2359
|
-
function getLibraryOptions(schema, options) {
|
|
2360
|
-
if (schema["~standard"].vendor !== "joi") return options;
|
|
2361
|
-
return {
|
|
2362
|
-
...options,
|
|
2363
|
-
libraryOptions: {
|
|
2364
|
-
...JOI_DEFAULT_LIBRARY_OPTIONS,
|
|
2365
|
-
...options?.libraryOptions
|
|
2366
|
-
}
|
|
2367
|
-
};
|
|
2368
|
-
}
|
|
2369
|
-
function formatIssues(issues) {
|
|
2370
|
-
return issues.map((issue) => {
|
|
2371
|
-
const path = formatIssuePath(issue.path);
|
|
2372
|
-
return path ? `${path}: ${issue.message}` : issue.message;
|
|
2373
|
-
}).join("\n");
|
|
2374
|
-
}
|
|
2375
|
-
function formatIssuePath(path) {
|
|
2376
|
-
return (path ?? []).map((segment) => typeof segment === "object" && segment !== null ? String(segment.key) : String(segment)).join(".");
|
|
2377
|
-
}
|
|
2378
|
-
//#endregion
|
|
2379
|
-
//#region node_modules/.pnpm/@nestjs+config@12.0.0_@nestjs+common@12.0.1_reflect-metadata@0.2.2_rxjs@7.8.2_supports-color@8.1.1__rxjs@7.8.2/node_modules/@nestjs/config/dist/config.module.js
|
|
2380
|
-
var __decorate = function(decorators, target, key, desc) {
|
|
2381
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2382
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2383
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2384
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2385
|
-
};
|
|
2386
|
-
var ConfigModule_1;
|
|
2387
|
-
/**
|
|
2388
|
-
* @publicApi
|
|
2389
|
-
*/
|
|
2390
|
-
let ConfigModule = ConfigModule_1 = class ConfigModule {
|
|
2391
|
-
/**
|
|
2392
|
-
* This promise resolves when parser completes loading environment variables.
|
|
2393
|
-
* When "ignoreEnvFile" is set to true, then it will resolve immediately after the
|
|
2394
|
-
* "ConfigModule#forRoot" method is called.
|
|
1649
|
+
* @param pdf The PDF bytes to modify
|
|
1650
|
+
* @param options Watermark options (`text` or `image` is required)
|
|
1651
|
+
* @returns Modified PDF with the watermark stamped on the selected pages
|
|
1652
|
+
* @description Stamps a text or image watermark on an existing PDF. By default the mark is centered, rotated by 45° at 15% opacity on every page. Use `position: 'tile'` to repeat it across the page and `pages` to target specific pages (1-based). To watermark a PDF while generating it, pass the same options as `watermark` in the `PuppeteerParameters`.
|
|
1653
|
+
*
|
|
1654
|
+
* ```typescript
|
|
1655
|
+
* const watermarked = await pdfService.addWatermark(pdf, {
|
|
1656
|
+
* text: 'CONFIDENTIAL',
|
|
1657
|
+
* color: '#ff0000',
|
|
1658
|
+
* opacity: 0.2,
|
|
1659
|
+
* });
|
|
1660
|
+
* ```
|
|
1661
|
+
*
|
|
1662
|
+
* Text uses the PDF standard fonts, which only support WinAnsi characters; use an `image` for anything else.
|
|
1663
|
+
* @throws WatermarkException when the options are invalid or the PDF cannot be processed
|
|
2395
1664
|
*/
|
|
2396
|
-
|
|
2397
|
-
return
|
|
2398
|
-
}
|
|
2399
|
-
/**
|
|
2400
|
-
* Loads environment variables based on the "ignoreEnvFile" flag and "envFilePath" value.
|
|
2401
|
-
* Additionally, registers custom configurations globally.
|
|
2402
|
-
* @param options
|
|
2403
|
-
*/
|
|
2404
|
-
static async forRoot(options = {}) {
|
|
2405
|
-
const envFilePaths = Array.isArray(options.envFilePath) ? options.envFilePath : [options.envFilePath || resolve$1(process.cwd(), ".env")];
|
|
2406
|
-
const parser = options.parser ?? getDefaultParser();
|
|
2407
|
-
let validatedEnvConfig = void 0;
|
|
2408
|
-
let config = options.ignoreEnvFile ? {} : this.loadEnvFile(envFilePaths, parser, options);
|
|
2409
|
-
if (!options.ignoreEnvVars && options.validatePredefined !== false) config = options.override ? {
|
|
2410
|
-
...process.env,
|
|
2411
|
-
...config
|
|
2412
|
-
} : {
|
|
2413
|
-
...config,
|
|
2414
|
-
...process.env
|
|
2415
|
-
};
|
|
2416
|
-
if (options.validate) {
|
|
2417
|
-
const validatedConfig = options.validate(config);
|
|
2418
|
-
validatedEnvConfig = validatedConfig;
|
|
2419
|
-
this.assignVariablesToProcess(validatedConfig, options.override);
|
|
2420
|
-
} else if (options.validationSchema) {
|
|
2421
|
-
const { error, value: validatedConfig } = await validateWithStandardSchema(options.validationSchema, config, options.validationOptions);
|
|
2422
|
-
if (error) throw new Error(`Config validation error: ${error.message}`);
|
|
2423
|
-
validatedEnvConfig = {
|
|
2424
|
-
...config,
|
|
2425
|
-
...validatedConfig
|
|
2426
|
-
};
|
|
2427
|
-
this.assignVariablesToProcess(validatedEnvConfig, options.override);
|
|
2428
|
-
} else this.assignVariablesToProcess(config, options.override);
|
|
2429
|
-
const isConfigToLoad = options.load && options.load.length;
|
|
2430
|
-
const providers = (await Promise.all(options.load || [])).map((factory) => createConfigProvider(factory)).filter((item) => item);
|
|
2431
|
-
const configProviderTokens = providers.map((item) => item.provide);
|
|
2432
|
-
const configServiceProvider = {
|
|
2433
|
-
provide: ConfigService,
|
|
2434
|
-
useFactory: (configService) => {
|
|
2435
|
-
const untypedConfigService = configService;
|
|
2436
|
-
if (options.cache) untypedConfigService.isCacheEnabled = true;
|
|
2437
|
-
if (options.skipProcessEnv) untypedConfigService.skipProcessEnv = true;
|
|
2438
|
-
configService.setEnvFilePaths(envFilePaths);
|
|
2439
|
-
configService.setParser(parser);
|
|
2440
|
-
return configService;
|
|
2441
|
-
},
|
|
2442
|
-
inject: [CONFIGURATION_SERVICE_TOKEN, ...configProviderTokens]
|
|
2443
|
-
};
|
|
2444
|
-
providers.push(configServiceProvider);
|
|
2445
|
-
if (validatedEnvConfig) {
|
|
2446
|
-
const validatedEnvConfigLoader = {
|
|
2447
|
-
provide: VALIDATED_ENV_LOADER,
|
|
2448
|
-
useFactory: (host) => {
|
|
2449
|
-
host[VALIDATED_ENV_PROPNAME] = validatedEnvConfig;
|
|
2450
|
-
},
|
|
2451
|
-
inject: [CONFIGURATION_TOKEN]
|
|
2452
|
-
};
|
|
2453
|
-
providers.push(validatedEnvConfigLoader);
|
|
2454
|
-
}
|
|
2455
|
-
this.environmentVariablesLoadedSignal();
|
|
2456
|
-
return {
|
|
2457
|
-
module: ConfigModule_1,
|
|
2458
|
-
global: options.isGlobal,
|
|
2459
|
-
providers: isConfigToLoad ? [...providers, {
|
|
2460
|
-
provide: CONFIGURATION_LOADER,
|
|
2461
|
-
useFactory: (host, ...configurations) => {
|
|
2462
|
-
configurations.forEach((item, index) => this.mergePartial(host, item, providers[index]));
|
|
2463
|
-
},
|
|
2464
|
-
inject: [CONFIGURATION_TOKEN, ...configProviderTokens]
|
|
2465
|
-
}] : providers,
|
|
2466
|
-
exports: [ConfigService, ...configProviderTokens]
|
|
2467
|
-
};
|
|
2468
|
-
}
|
|
2469
|
-
/**
|
|
2470
|
-
* Registers configuration object (partial registration).
|
|
2471
|
-
* @param config
|
|
2472
|
-
*/
|
|
2473
|
-
static forFeature(config) {
|
|
2474
|
-
const configProvider = createConfigProvider(config);
|
|
2475
|
-
const serviceProvider = {
|
|
2476
|
-
provide: ConfigService,
|
|
2477
|
-
useFactory: (configService) => configService,
|
|
2478
|
-
inject: [CONFIGURATION_SERVICE_TOKEN, configProvider.provide]
|
|
2479
|
-
};
|
|
2480
|
-
return {
|
|
2481
|
-
module: ConfigModule_1,
|
|
2482
|
-
providers: [
|
|
2483
|
-
configProvider,
|
|
2484
|
-
serviceProvider,
|
|
2485
|
-
{
|
|
2486
|
-
provide: CONFIGURATION_LOADER,
|
|
2487
|
-
useFactory: (host, partialConfig) => {
|
|
2488
|
-
this.mergePartial(host, partialConfig, configProvider);
|
|
2489
|
-
},
|
|
2490
|
-
inject: [CONFIGURATION_TOKEN, configProvider.provide]
|
|
2491
|
-
}
|
|
2492
|
-
],
|
|
2493
|
-
exports: [ConfigService, configProvider.provide]
|
|
2494
|
-
};
|
|
2495
|
-
}
|
|
2496
|
-
static loadEnvFile(envFilePaths, parser, options) {
|
|
2497
|
-
let config = {};
|
|
2498
|
-
for (const envFilePath of envFilePaths) if (fs$1.existsSync(envFilePath)) {
|
|
2499
|
-
config = Object.assign(parser(fs$1.readFileSync(envFilePath)), config);
|
|
2500
|
-
if (options.expandVariables) {
|
|
2501
|
-
const expandOptions = typeof options.expandVariables === "object" ? options.expandVariables : {};
|
|
2502
|
-
config = (0, import_main.expand)({
|
|
2503
|
-
...expandOptions,
|
|
2504
|
-
parsed: config
|
|
2505
|
-
}).parsed || config;
|
|
2506
|
-
}
|
|
2507
|
-
}
|
|
2508
|
-
return config;
|
|
2509
|
-
}
|
|
2510
|
-
static assignVariablesToProcess(config, override) {
|
|
2511
|
-
if (!isObject(config)) return;
|
|
2512
|
-
(override ? Object.keys(config) : Object.keys(config).filter((key) => !(key in process.env))).forEach((key) => {
|
|
2513
|
-
const value = config[key];
|
|
2514
|
-
if (typeof value === "string") process.env[key] = value;
|
|
2515
|
-
else if (typeof value === "boolean" || typeof value === "number") process.env[key] = `${value}`;
|
|
2516
|
-
});
|
|
2517
|
-
}
|
|
2518
|
-
static mergePartial(host, item, provider) {
|
|
2519
|
-
const factoryRef = provider.useFactory;
|
|
2520
|
-
mergeConfigObject(host, item, getRegistrationToken(factoryRef));
|
|
1665
|
+
async addWatermark(pdf, options) {
|
|
1666
|
+
return await addWatermark(pdf, options);
|
|
2521
1667
|
}
|
|
2522
1668
|
};
|
|
2523
|
-
|
|
2524
|
-
ConfigModule = ConfigModule_1 = __decorate([Module({
|
|
2525
|
-
imports: [ConfigHostModule],
|
|
2526
|
-
providers: [{
|
|
2527
|
-
provide: ConfigService,
|
|
2528
|
-
useExisting: CONFIGURATION_SERVICE_TOKEN
|
|
2529
|
-
}],
|
|
2530
|
-
exports: [ConfigHostModule, ConfigService]
|
|
2531
|
-
})], ConfigModule);
|
|
1669
|
+
NestjsPdfService = __decorate([Injectable(), __decorateMetadata("design:paramtypes", [typeof PuppeteerService === "undefined" ? Object : PuppeteerService])], NestjsPdfService);
|
|
2532
1670
|
//#endregion
|
|
2533
1671
|
//#region src/puppeteer/puppeteer.module.ts
|
|
2534
1672
|
var _PuppeteerModule;
|
|
2535
1673
|
let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
|
|
2536
|
-
browserService;
|
|
2537
|
-
pdfParams;
|
|
1674
|
+
#browserService;
|
|
1675
|
+
#pdfParams;
|
|
2538
1676
|
constructor(browserService, pdfParams) {
|
|
2539
|
-
this
|
|
2540
|
-
this
|
|
1677
|
+
this.#browserService = browserService;
|
|
1678
|
+
this.#pdfParams = pdfParams;
|
|
2541
1679
|
}
|
|
2542
1680
|
async onModuleInit() {
|
|
2543
|
-
if (!this
|
|
1681
|
+
if (!this.#pdfParams.executablePath) await this.#browserService.install(this.#pdfParams.useLockedBrowser ?? false);
|
|
2544
1682
|
}
|
|
2545
1683
|
static forRoot(pdfParameters) {
|
|
2546
|
-
const providers = [
|
|
2547
|
-
{
|
|
2548
|
-
provide: PDF_PARAMETERS,
|
|
2549
|
-
useValue: pdfParameters
|
|
2550
|
-
},
|
|
2551
|
-
HandlebarsService,
|
|
2552
|
-
MjmlService,
|
|
2553
|
-
PugService,
|
|
2554
|
-
EjsService,
|
|
2555
|
-
NunjucksService,
|
|
2556
|
-
EtaService,
|
|
2557
|
-
MustacheService
|
|
2558
|
-
];
|
|
2559
1684
|
return {
|
|
2560
1685
|
module: _PuppeteerModule,
|
|
2561
|
-
|
|
2562
|
-
|
|
1686
|
+
providers: [
|
|
1687
|
+
{
|
|
1688
|
+
provide: PDF_PARAMETERS,
|
|
1689
|
+
useValue: pdfParameters
|
|
1690
|
+
},
|
|
1691
|
+
HandlebarsService,
|
|
1692
|
+
MjmlService,
|
|
1693
|
+
PugService,
|
|
1694
|
+
EjsService,
|
|
1695
|
+
NunjucksService,
|
|
1696
|
+
EtaService,
|
|
1697
|
+
MustacheService
|
|
1698
|
+
],
|
|
2563
1699
|
exports: [
|
|
2564
1700
|
PuppeteerService,
|
|
2565
1701
|
MjmlService,
|
|
@@ -2579,7 +1715,7 @@ let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
|
|
|
2579
1715
|
};
|
|
2580
1716
|
return {
|
|
2581
1717
|
module: _PuppeteerModule,
|
|
2582
|
-
imports:
|
|
1718
|
+
imports: options.imports ?? [],
|
|
2583
1719
|
providers: [
|
|
2584
1720
|
pdfParamsProvider,
|
|
2585
1721
|
PuppeteerService,
|
|
@@ -2604,7 +1740,7 @@ let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
|
|
|
2604
1740
|
};
|
|
2605
1741
|
}
|
|
2606
1742
|
};
|
|
2607
|
-
PuppeteerModule = _PuppeteerModule = __decorate
|
|
1743
|
+
PuppeteerModule = _PuppeteerModule = __decorate([
|
|
2608
1744
|
Module({
|
|
2609
1745
|
providers: [
|
|
2610
1746
|
PuppeteerService,
|
|
@@ -2650,8 +1786,8 @@ let NestjsPdfModule = _NestjsPdfModule = class NestjsPdfModule {
|
|
|
2650
1786
|
};
|
|
2651
1787
|
}
|
|
2652
1788
|
};
|
|
2653
|
-
NestjsPdfModule = _NestjsPdfModule = __decorate
|
|
1789
|
+
NestjsPdfModule = _NestjsPdfModule = __decorate([Module({})], NestjsPdfModule);
|
|
2654
1790
|
//#endregion
|
|
2655
|
-
export { EjsService, EtaService, HandlebarsService, MjmlService, MustacheService, NestjsPdfModule, NestjsPdfService, NunjucksService, PugService, PuppeteerModule, PuppeteerService, getRelativePathToValue };
|
|
1791
|
+
export { BrowserInstallationException, BrowserUnavailableException, EjsService, EngineNotAvailableException, EtaService, HandlebarsService, MjmlService, MustacheService, NestjsPdfErrorCode, NestjsPdfException, NestjsPdfModule, NestjsPdfService, NunjucksService, PdfGenerationException, PugService, PuppeteerModule, PuppeteerService, SignatureDependencyException, SignaturePlacementException, TemplateConfigurationException, TemplateRenderException, WatermarkException, getRelativePathToValue };
|
|
2656
1792
|
|
|
2657
1793
|
//# sourceMappingURL=index.mjs.map
|