@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/dist/index.mjs CHANGED
@@ -1,11 +1,13 @@
1
- import { createRequire } from "node:module";
2
- import { basename, extname, join, relative, resolve, sep } from "node:path";
3
- import { Global, Inject, Injectable, Logger, Module, Optional } from "@nestjs/common";
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 { Browser, BrowserPlatform, canDownload, detectBrowserPlatform, getInstalledBrowsers, install, resolveBuildId } from "@puppeteer/browsers";
8
- import { launch } from "puppeteer";
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
- import { isObject, isUndefined } from "@nestjs/common/utils/shared.utils.js";
17
- import * as fs$1 from "fs";
18
- import fs from "fs";
19
- import { resolve as resolve$1 } from "path";
20
- import { Subject } from "rxjs";
21
- import { randomUUID } from "crypto";
22
- //#region \0rolldown/runtime.js
23
- var __create = Object.create;
24
- var __defProp = Object.defineProperty;
25
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
26
- var __getOwnPropNames = Object.getOwnPropertyNames;
27
- var __getProtoOf = Object.getPrototypeOf;
28
- var __hasOwnProp = Object.prototype.hasOwnProperty;
29
- var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
30
- var __copyProps = (to, from, except, desc) => {
31
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
32
- key = keys[i];
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
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
41
- value: mod,
42
- enumerable: true
43
- }) : target, mod));
44
- var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
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
- /* v8 ignore next -- import() rejections are always Error instances in practice */
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: ${reason}`
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 Error(`Page ${pageIndex} not found`);
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 Error(`Page ${pageIndex} not found`);
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$3(decorators, target, key, desc) {
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
- _browserInstance = null;
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.cacheDir = resolve(".cache/puppeteer-browser");
401
- this.options = pdfParams;
402
- this.loadBuildId();
403
- this.loadBrowser();
404
- this.loadBrowserTag();
405
- this.loadUseLockedBrowser();
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.shuttingDown = true;
409
- await this.waitForIdle(this.shutdownDrainTimeoutMs);
410
- if (this._browserInstance?.connected) try {
411
- await this._browserInstance.close();
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.options?.cleanupBrowserCacheOnExit !== false) await this.cleanupCacheBestEffort();
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._browserInstance?.connected) this._browserInstance = await this.launchBrowser(args, headless, executablePathBin);
425
- return this._browserInstance;
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._browserInstance = null;
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.shuttingDown) throw new Error("nestjs-pdf is shutting down, refusing new PDF jobs");
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.recycleRequested = true;
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.recycleRequested) return;
450
- if (this.recycling) return;
784
+ if (!this.#recycleRequested) return;
785
+ if (this.#recycling) return;
451
786
  if (this.activeJobs > 0) return;
452
- if (!this._browserInstance) return;
453
- this.recycling = true;
787
+ if (!this.#browserInstance) return;
788
+ this.#recycling = true;
454
789
  try {
455
- if (this._browserInstance.connected) await this._browserInstance.close();
456
- this._browserInstance = null;
790
+ if (this.#browserInstance.connected) await this.#browserInstance.close();
791
+ this.#browserInstance = null;
457
792
  this.totalJobs = 0;
458
- this.recycleRequested = false;
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.recycling = false;
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.cacheDir;
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
- const browser = this.browser;
490
- const versionTag = this.browserTag;
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.buildId === void 0) buildId = await resolveBuildId(browser, browserPlatform, versionTag);
494
- else buildId = this.buildId;
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.writeLockFile(browser, buildId);
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.cacheDir,
846
+ cacheDir: this.#cacheDir,
504
847
  browser,
505
848
  buildId,
506
- baseUrl: this.options?.browserInstallBaseUrl ?? void 0
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.writeLockFile(browser, buildId);
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.options?.browser === void 0) browser = Browser.CHROMIUM;
523
- else browser = this.options.browser;
524
- this.browser = browser;
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.browser;
870
+ return this.#browser;
528
871
  }
529
- loadBrowserTag() {
872
+ #loadBrowserTag() {
530
873
  let versionTag;
531
- if (this.options?.browserTag === void 0) {
532
- if (this.browser === Browser.CHROMIUM) versionTag = "latest";
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.options.browserTag;
535
- this.browserTag = versionTag;
877
+ } else versionTag = this.#options.browserTag;
878
+ this.#browserTag = versionTag;
536
879
  }
537
- loadBuildId() {
880
+ #loadBuildId() {
538
881
  let buildId;
539
- if (this.options?.buildId === void 0) buildId = void 0;
540
- else buildId = this.options.buildId;
541
- this.buildId = buildId;
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.browserTag = browserTag;
887
+ this.#browserTag = browserTag;
545
888
  }
546
889
  getBrowserTag() {
547
- return this.browserTag;
890
+ return this.#browserTag;
548
891
  }
549
892
  getBuildId() {
550
- return this.buildId;
893
+ return this.#buildId;
551
894
  }
552
- loadUseLockedBrowser() {
895
+ #loadUseLockedBrowser() {
553
896
  let useLockedBrowser;
554
- if (this.options?.useLockedBrowser === void 0) useLockedBrowser = false;
555
- else useLockedBrowser = this.options.useLockedBrowser;
556
- this.useLockedBrowser = useLockedBrowser;
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.cacheDir })).find((insBrowser) => {
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.browser;
565
- const versionTag = this.browserTag;
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.useLockedBrowser) {
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.cacheDir })).find((insBrowser) => {
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 Error("Could not install browser");
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._browserInstance === browser) this._browserInstance = null;
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.cacheDir, `${browser}.lock`);
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.cacheDir, `${browser}.lock`);
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$3([
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 Error(`EJS rendering failed: ${String(error)}`, { cause: error });
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 Error(`EJS file rendering failed: ${String(error)}`, { cause: error });
984
+ throw new TemplateRenderException("EJS", `EJS file rendering failed: ${String(error)}`, { cause: error });
641
985
  }
642
986
  }
643
987
  };
644
- EjsService = __decorate$3([Injectable()], EjsService);
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.eta = new Eta({
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.eta).renderString(template, data);
1017
+ }) : this.#eta).renderString(template, data);
674
1018
  } catch (error) {
675
- throw new Error(`Eta rendering failed: ${String(error)}`, { cause: error });
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.templateCache.get(resolvedPath) : void 0;
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.templateCache.size < this.maxCacheSize) this.templateCache.set(resolvedPath, template);
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 Error(`Eta file rendering failed for ${filePath}: ${String(error)}`, { cause: error });
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.templateCache.clear();
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.templateCache.size;
1054
+ return this.#templateCache.size;
711
1055
  }
712
1056
  };
713
- EtaService = __decorate$3([Injectable(), __decorateMetadata("design:paramtypes", [])], EtaService);
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.getEnv(options).compile(template, options.compileOptions)(parameters, options.templateOptions);
1065
+ return this.#getEnv(options).compile(template, options.compileOptions)(parameters, options.templateOptions);
722
1066
  } catch (error) {
723
- throw new Error(`Handlebars rendering failed: ${String(error)}`, { cause: error });
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 Error("Handlebars file rendering failed: option `templateDirectory` is not set");
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 Error(`Handlebars file rendering failed: ’${file}’ resolves outside \`templateDirectory\``);
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 Error(`Handlebars file rendering failed: ${String(error)}`, { cause: error });
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.cachedEnv && this.cachedOptions === options) return this.cachedEnv;
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.registerPartials(env, options.partialDirectory);
749
- this.cachedOptions = options;
750
- this.cachedEnv = env;
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 Error(`Handlebars partial directory does not exist: ${partialPath}`);
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$3([Injectable()], HandlebarsService);
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
- const { html } = await mjml(template, options);
770
- return html;
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
- const template = readFileSync(filePath, "utf-8");
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$3([Injectable()], MjmlService);
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 Error(`Mustache rendering failed: ${String(error)}`, { cause: error });
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.templateCache.get(resolvedPath);
1165
+ let template = this.#templateCache.get(resolvedPath);
812
1166
  if (!template) {
813
1167
  template = readFileSync(resolvedPath, "utf-8");
814
- if (this.templateCache.size < this.maxCacheSize) this.templateCache.set(resolvedPath, template);
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 Error(`Mustache file rendering failed for ${filePath}: ${String(error)}`, { cause: error });
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.templateCache.clear();
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.templateCache.size;
1186
+ return this.#templateCache.size;
833
1187
  }
834
1188
  };
835
- MustacheService = __decorate$3([Injectable()], MustacheService);
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 Error(`Nunjucks rendering failed: ${String(error)}`, { cause: error });
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 Error(`Nunjucks file rendering failed: ${String(error)}`, { cause: error });
1231
+ throw new TemplateRenderException("Nunjucks", `Nunjucks file rendering failed: ${String(error)}`, { cause: error });
878
1232
  }
879
1233
  }
880
1234
  };
881
- NunjucksService = __decorate$3([Injectable(), __decorateMetadata("design:paramtypes", [])], NunjucksService);
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 Error(`Pug rendering failed: ${String(error)}`, { cause: error });
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 Error(`Pug file rendering failed: ${String(error)}`, { cause: error });
1251
+ throw new TemplateRenderException("Pug", `Pug file rendering failed: ${String(error)}`, { cause: error });
898
1252
  }
899
1253
  }
900
1254
  };
901
- PugService = __decorate$3([Injectable()], PugService);
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 Error(`${name} service is not available. If the problem persists, open an issue in the repo.`);
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.browserService = browserService;
922
- this.options = options;
923
- this.hbsService = hbsService;
924
- this.mjmlService = mjmlService;
925
- this.pugService = pugService;
926
- this.ejsService = ejsService;
927
- this.nunjucksService = nunjucksService;
928
- this.etaService = etaService;
929
- this.mustacheService = mustacheService;
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
- return this.limit(async () => {
934
- const mergePuppeteerOptions = mergePuppeteerParameters(this.options, options);
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.browserService.markJobStarted();
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.browserService.createContext(args, headless, executablePath);
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
- return await page.pdf(pdfOptions);
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
- await context.close();
1368
+ if (closing) await closing;
1369
+ else await context.close();
997
1370
  } catch (error) {
998
1371
  Logger.error(error);
999
1372
  }
1000
- await this.browserService.markJobFinished();
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.hbsService, "Handlebars").render(template, parameters, options?.hbsOptions ?? this.options.hbsOptions);
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.hbsService, "Handlebars").renderFile(file, parameters, options?.hbsOptions ?? this.options.hbsOptions);
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.mjmlService, "MJML").render(template, options?.mjmlOptions ?? this.options.mjmlOptions);
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.mjmlService, "MJML").renderFile(file, options?.mjmlOptions ?? this.options.mjmlOptions);
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.pugService, "Pug").render(template, data, options?.pugOptions ?? this.options.pugOptions);
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.pugService, "Pug").renderFile(file, data, options?.pugOptions ?? this.options.pugOptions);
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.ejsService, "EJS").render(template, data, options?.ejsOptions ?? this.options.ejsOptions);
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.ejsService, "EJS").renderFile(file, data, options?.ejsOptions ?? this.options.ejsOptions);
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.nunjucksService, "Nunjucks").render(template, data, options?.nunjucksOptions ?? this.options.nunjucksOptions);
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.nunjucksService, "Nunjucks").renderFile(file, data, options?.nunjucksOptions ?? this.options.nunjucksOptions);
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.etaService, "Eta").render(template, data, options?.etaOptions ?? this.options.etaOptions);
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.etaService, "Eta").renderFile(file, data, options?.etaOptions ?? this.options.etaOptions);
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.mustacheService, "Mustache").render(template, data, options?.mustacheOptions ?? this.options.mustacheOptions);
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.mustacheService, "Mustache").renderFile(file, data, options?.mustacheOptions ?? this.options.mustacheOptions);
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$3([
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.puppeteerService = puppeteerService;
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.puppeteerService.generatePdfFromHtml(html, options);
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.puppeteerService.generatePdfFromTemplateHbsString(template, parameters, options);
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.puppeteerService.generatePdfFromTemplateHbsFile(file, parameters, options);
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.puppeteerService.generatePdfFromMjmlString(template, options);
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.puppeteerService.generatePdfFromMjmlFile(file, options);
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.puppeteerService.generatePdfFromEjsString(template, data, options);
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.puppeteerService.generatePdfFromEjsFile(file, data, options);
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.puppeteerService.generatePdfFromPugString(template, data, options);
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.puppeteerService.generatePdfFromPugFile(file, data, options);
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.puppeteerService.generatePdfFromNunjucksString(template, data, options);
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.puppeteerService.generatePdfFromNunjucksFile(file, data, options);
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.puppeteerService.generatePdfFromEtaString(template, data, options);
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.puppeteerService.generatePdfFromEtaFile(file, data, options);
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.puppeteerService.generatePdfFromMustacheString(template, data, options);
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.puppeteerService.generatePdfFromMustacheFile(file, data, options);
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
- * Get a configuration value (either custom configuration or process environment variable)
2179
- * based on property path (you can use dot notation to traverse nested object, e.g. "database.host").
2180
- * It returns a default value if the key does not exist.
2181
- * @param propertyPath
2182
- * @param defaultValueOrOptions
2183
- */
2184
- get(propertyPath, defaultValueOrOptions, options) {
2185
- const internalValue = this.getFromInternalConfig(propertyPath);
2186
- if (!isUndefined(internalValue)) return internalValue;
2187
- const validatedEnvValue = this.getFromValidatedEnv(propertyPath);
2188
- if (!isUndefined(validatedEnvValue)) return validatedEnvValue;
2189
- const defaultValue = this.isGetOptionsObject(defaultValueOrOptions) && !options ? void 0 : defaultValueOrOptions;
2190
- if (!this._skipProcessEnv) {
2191
- const processEnvValue = this.getFromProcessEnv(propertyPath, defaultValue);
2192
- if (!isUndefined(processEnvValue)) return processEnvValue;
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
- static get envVariablesLoaded() {
2397
- return this._envVariablesLoaded;
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
- ConfigModule._envVariablesLoaded = new Promise((resolve) => ConfigModule_1.environmentVariablesLoadedSignal = resolve);
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.browserService = browserService;
2540
- this.pdfParams = pdfParams;
1677
+ this.#browserService = browserService;
1678
+ this.#pdfParams = pdfParams;
2541
1679
  }
2542
1680
  async onModuleInit() {
2543
- if (!this.pdfParams.executablePath) await this.browserService.install(this.pdfParams.useLockedBrowser ?? false);
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
- imports: [ConfigModule.forRoot()],
2562
- providers,
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: [...options.imports ?? [], ConfigModule.forRoot()],
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$3([
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$3([Module({})], NestjsPdfModule);
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