@shad0wz7/nestjs-pdf 3.2.0 → 5.0.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.cjs CHANGED
@@ -1,50 +1,14 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region \0rolldown/runtime.js
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
23
- //#endregion
24
2
  let node_path = require("node:path");
25
3
  let _nestjs_common = require("@nestjs/common");
26
4
  let pdf_lib = require("pdf-lib");
27
5
  let deepmerge_ts = require("deepmerge-ts");
28
- let node_dns_promises = require("node:dns/promises");
29
6
  let node_fs = require("node:fs");
7
+ let node_dns_promises = require("node:dns/promises");
30
8
  let node_net = require("node:net");
31
9
  let node_url = require("node:url");
32
- let puppeteer = require("puppeteer");
33
- let _puppeteer_browsers = require("@puppeteer/browsers");
34
- let ejs = require("ejs");
35
- ejs = __toESM(ejs, 1);
36
- let eta = require("eta");
37
- let handlebars = require("handlebars");
38
- handlebars = __toESM(handlebars, 1);
39
- let mjml = require("mjml");
40
- mjml = __toESM(mjml, 1);
41
- let mustache = require("mustache");
42
- mustache = __toESM(mustache, 1);
43
- let nunjucks = require("nunjucks");
44
- nunjucks = __toESM(nunjucks, 1);
45
- let pug = require("pug");
46
- pug = __toESM(pug, 1);
47
- //#region src/exceptions/nestjs-pdf.exception.ts
10
+ let node_module = require("node:module");
11
+ // src/exceptions/nestjs-pdf.exception.ts
48
12
  let NestjsPdfErrorCode = /* @__PURE__ */ function(NestjsPdfErrorCode) {
49
13
  NestjsPdfErrorCode["ENGINE_NOT_AVAILABLE"] = "ENGINE_NOT_AVAILABLE";
50
14
  NestjsPdfErrorCode["TEMPLATE_CONFIGURATION_ERROR"] = "TEMPLATE_CONFIGURATION_ERROR";
@@ -55,6 +19,7 @@ let NestjsPdfErrorCode = /* @__PURE__ */ function(NestjsPdfErrorCode) {
55
19
  NestjsPdfErrorCode["SIGNATURE_DEPENDENCY_ERROR"] = "SIGNATURE_DEPENDENCY_ERROR";
56
20
  NestjsPdfErrorCode["SIGNATURE_PLACEMENT_ERROR"] = "SIGNATURE_PLACEMENT_ERROR";
57
21
  NestjsPdfErrorCode["WATERMARK_ERROR"] = "WATERMARK_ERROR";
22
+ NestjsPdfErrorCode["RENDERER_CONFIGURATION_ERROR"] = "RENDERER_CONFIGURATION_ERROR";
58
23
  return NestjsPdfErrorCode;
59
24
  }({});
60
25
  var NestjsPdfException = class extends Error {
@@ -63,46 +28,43 @@ var NestjsPdfException = class extends Error {
63
28
  this.name = this.constructor.name;
64
29
  }
65
30
  };
66
- //#endregion
67
- //#region src/exceptions/browser-installation.exception.ts
31
+ // src/exceptions/browser-installation.exception.ts
68
32
  var BrowserInstallationException = class extends NestjsPdfException {
69
33
  code = "BROWSER_INSTALLATION_ERROR";
70
34
  };
71
- //#endregion
72
- //#region src/exceptions/browser-unavailable.exception.ts
35
+ // src/exceptions/browser-unavailable.exception.ts
73
36
  var BrowserUnavailableException = class extends NestjsPdfException {
74
37
  code = "BROWSER_UNAVAILABLE";
75
38
  };
76
- //#endregion
77
- //#region src/exceptions/engine-not-available.exception.ts
39
+ // src/exceptions/engine-not-available.exception.ts
78
40
  var EngineNotAvailableException = class extends NestjsPdfException {
79
41
  code = "ENGINE_NOT_AVAILABLE";
80
- constructor(engineName) {
81
- super(`${engineName} service is not available. If the problem persists, open an issue in the repo.`);
42
+ constructor(engineName, packageName, options) {
43
+ super(packageName ? `${engineName} engine is not available: the '${packageName}' package is not installed. Run \`npm install ${packageName}\` to use it.` : `${engineName} service is not available. If the problem persists, open an issue in the repo.`, options);
82
44
  }
83
45
  };
84
- //#endregion
85
- //#region src/exceptions/pdf-generation.exception.ts
46
+ // src/exceptions/pdf-generation.exception.ts
86
47
  var PdfGenerationException = class extends NestjsPdfException {
87
48
  code = "PDF_GENERATION_ERROR";
88
49
  };
89
- //#endregion
90
- //#region src/exceptions/signature-dependency.exception.ts
50
+ // src/exceptions/renderer-configuration.exception.ts
51
+ /** The PDF provider is misconfigured, or asked for an option it does not support. */
52
+ var RendererConfigurationException = class extends NestjsPdfException {
53
+ code = "RENDERER_CONFIGURATION_ERROR";
54
+ };
55
+ // src/exceptions/signature-dependency.exception.ts
91
56
  var SignatureDependencyException = class extends NestjsPdfException {
92
57
  code = "SIGNATURE_DEPENDENCY_ERROR";
93
58
  };
94
- //#endregion
95
- //#region src/exceptions/signature-placement.exception.ts
59
+ // src/exceptions/signature-placement.exception.ts
96
60
  var SignaturePlacementException = class extends NestjsPdfException {
97
61
  code = "SIGNATURE_PLACEMENT_ERROR";
98
62
  };
99
- //#endregion
100
- //#region src/exceptions/template-configuration.exception.ts
63
+ // src/exceptions/template-configuration.exception.ts
101
64
  var TemplateConfigurationException = class extends NestjsPdfException {
102
65
  code = "TEMPLATE_CONFIGURATION_ERROR";
103
66
  };
104
- //#endregion
105
- //#region src/exceptions/template-render.exception.ts
67
+ // src/exceptions/template-render.exception.ts
106
68
  var TemplateRenderException = class extends NestjsPdfException {
107
69
  engine;
108
70
  code = "TEMPLATE_RENDER_ERROR";
@@ -111,13 +73,11 @@ var TemplateRenderException = class extends NestjsPdfException {
111
73
  this.engine = engine;
112
74
  }
113
75
  };
114
- //#endregion
115
- //#region src/exceptions/watermark.exception.ts
76
+ // src/exceptions/watermark.exception.ts
116
77
  var WatermarkException = class extends NestjsPdfException {
117
78
  code = "WATERMARK_ERROR";
118
79
  };
119
- //#endregion
120
- //#region src/helpers/getRelativePath.helper.ts
80
+ // src/helpers/getRelativePath.helper.ts
121
81
  /**
122
82
  * Get the relative path to a value from the module directory.
123
83
  * @param moduleDir the path of the module, typically __dirname
@@ -131,8 +91,7 @@ function getRelativePathToValue(moduleDir, relativeToModule) {
131
91
  const fullTemplatePath = (0, node_path.resolve)(moduleDir, relativeToModule);
132
92
  return (0, node_path.relative)(process.cwd(), fullTemplatePath);
133
93
  }
134
- //#endregion
135
- //#region src/helpers/signature.helper.ts
94
+ // src/helpers/signature.helper.ts
136
95
  let pdfjsPromise;
137
96
  async function loadPdfjs() {
138
97
  if (!pdfjsPromise) try {
@@ -275,8 +234,7 @@ async function addSignatureFieldUsingAnchor(pdf, fieldName = "SignatureDebtor",
275
234
  }
276
235
  return await pdfDoc.save();
277
236
  }
278
- //#endregion
279
- //#region src/helpers/watermark.helper.ts
237
+ // src/helpers/watermark.helper.ts
280
238
  const DEFAULT_OPACITY = .15;
281
239
  const DEFAULT_ROTATION = 45;
282
240
  const DEFAULT_FONT_SIZE = 60;
@@ -419,8 +377,7 @@ async function addWatermark(pdf, options) {
419
377
  throw new WatermarkException(`Failed to add watermark: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
420
378
  }
421
379
  }
422
- //#endregion
423
- //#region node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
380
+ // node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
424
381
  var Node = class {
425
382
  value;
426
383
  next;
@@ -477,8 +434,7 @@ var Queue = class {
477
434
  while (this.#head) yield this.dequeue();
478
435
  }
479
436
  };
480
- //#endregion
481
- //#region node_modules/.pnpm/p-limit@7.3.2/node_modules/p-limit/index.js
437
+ // node_modules/.pnpm/p-limit@7.3.3/node_modules/p-limit/index.js
482
438
  function pLimit(concurrency) {
483
439
  let rejectOnClear = false;
484
440
  if (typeof concurrency === "object") ({concurrency, rejectOnClear = false} = concurrency);
@@ -537,7 +493,17 @@ function pLimit(concurrency) {
537
493
  }
538
494
  },
539
495
  map: { async value(iterable, function_) {
540
- const promises = Array.from(iterable, (value, index) => generator(function_, value, index));
496
+ const promises = [];
497
+ try {
498
+ Array.from(iterable, (value, index) => {
499
+ const promise = generator(function_, value, index);
500
+ promises.push(promise);
501
+ return promise;
502
+ });
503
+ } catch (error) {
504
+ for (const promise of promises) promise.catch(() => {});
505
+ throw error;
506
+ }
541
507
  return Promise.all(promises);
542
508
  } }
543
509
  });
@@ -546,14 +512,296 @@ function pLimit(concurrency) {
546
512
  function validateConcurrency(concurrency) {
547
513
  if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) throw new TypeError("Expected `concurrency` to be a number from 1 and up");
548
514
  }
549
- //#endregion
550
- //#region src/helpers/deepMergePdfparams.ts
515
+ // src/helpers/deepMergePdfparams.ts
551
516
  function mergePuppeteerParameters(defaults, overrides) {
552
517
  if (!overrides) return { ...defaults };
553
518
  return (0, deepmerge_ts.deepmerge)(defaults, overrides);
554
519
  }
555
- //#endregion
556
- //#region src/helpers/request-guard.helper.ts
520
+ // src/helpers/tokens.ts
521
+ const PDF_PARAMETERS = "PDF_PARAMETERS";
522
+ // src/renderers/pdf-renderer.interface.ts
523
+ const PDF_RENDERER = "PDF_RENDERER";
524
+ // src/renderers/http.utils.ts
525
+ const MAX_ERROR_BODY_LENGTH = 500;
526
+ /** Builds a `PdfGenerationException` from a failed HTTP response, body included. */
527
+ async function httpError(provider, response) {
528
+ let body = "";
529
+ try {
530
+ body = (await response.text()).trim().slice(0, MAX_ERROR_BODY_LENGTH);
531
+ } catch {}
532
+ return new PdfGenerationException(`${provider} responded with HTTP ${response.status}${body ? `: ${body}` : ""}`);
533
+ }
534
+ /** Remote providers render on another machine: the local request guard cannot run there. */
535
+ function assertNoRequestGuard(provider, options, hint) {
536
+ if (options.security) throw new RendererConfigurationException(`The 'security' option is only supported by the puppeteer provider, not by ${provider}. ${hint}`);
537
+ }
538
+ function requireNonEmpty(value, name, provider) {
539
+ if (!value?.trim()) throw new RendererConfigurationException(`The ${provider} provider requires a non-empty '${name}'`);
540
+ return value;
541
+ }
542
+ // src/renderers/pdf-options.mapper.ts
543
+ /** Paper sizes in inches, as Puppeteer defines them. */
544
+ const PAPER_FORMATS = {
545
+ letter: {
546
+ width: 8.5,
547
+ height: 11
548
+ },
549
+ legal: {
550
+ width: 8.5,
551
+ height: 14
552
+ },
553
+ tabloid: {
554
+ width: 11,
555
+ height: 17
556
+ },
557
+ ledger: {
558
+ width: 17,
559
+ height: 11
560
+ },
561
+ a0: {
562
+ width: 33.1102,
563
+ height: 46.811
564
+ },
565
+ a1: {
566
+ width: 23.3858,
567
+ height: 33.1102
568
+ },
569
+ a2: {
570
+ width: 16.5354,
571
+ height: 23.3858
572
+ },
573
+ a3: {
574
+ width: 11.6929,
575
+ height: 16.5354
576
+ },
577
+ a4: {
578
+ width: 8.2677,
579
+ height: 11.6929
580
+ },
581
+ a5: {
582
+ width: 5.8268,
583
+ height: 8.2677
584
+ },
585
+ a6: {
586
+ width: 4.1339,
587
+ height: 5.8268
588
+ }
589
+ };
590
+ const INCHES_PER_UNIT = {
591
+ px: 1 / 96,
592
+ in: 1,
593
+ cm: 1 / 2.54,
594
+ mm: 1 / 25.4
595
+ };
596
+ /**
597
+ * Converts a Puppeteer length (a number of pixels, or a string with a
598
+ * `px`/`in`/`cm`/`mm` unit) to inches.
599
+ */
600
+ function toInches(value) {
601
+ if (typeof value === "number") return value * INCHES_PER_UNIT.px;
602
+ const match = /^\s*(-?\d*\.?\d+)\s*(px|in|cm|mm)?\s*$/i.exec(value);
603
+ if (!match) throw new RendererConfigurationException(`Invalid length '${value}': expected a number of pixels or a value in px, in, cm or mm`);
604
+ const unit = (match[2] ?? "px").toLowerCase();
605
+ return Number(match[1]) * INCHES_PER_UNIT[unit];
606
+ }
607
+ function formatInches(inches) {
608
+ return String(Math.round(inches * 1e4) / 1e4);
609
+ }
610
+ function resolvePrintLayout(pdfOptions) {
611
+ let width;
612
+ let height;
613
+ if (pdfOptions.width !== void 0 || pdfOptions.height !== void 0) {
614
+ const fallback = PAPER_FORMATS.letter;
615
+ width = pdfOptions.width === void 0 ? fallback.width : toInches(pdfOptions.width);
616
+ height = pdfOptions.height === void 0 ? fallback.height : toInches(pdfOptions.height);
617
+ } else {
618
+ const formatName = (pdfOptions.format ?? "letter").toLowerCase();
619
+ const format = PAPER_FORMATS[formatName];
620
+ if (!format) throw new RendererConfigurationException(`Unknown paper format '${pdfOptions.format}'`);
621
+ ({width, height} = format);
622
+ }
623
+ const margin = {};
624
+ for (const side of [
625
+ "top",
626
+ "right",
627
+ "bottom",
628
+ "left"
629
+ ]) {
630
+ const value = pdfOptions.margin?.[side];
631
+ if (value !== void 0) margin[side] = toInches(value);
632
+ }
633
+ return {
634
+ width,
635
+ height,
636
+ margin
637
+ };
638
+ }
639
+ function toHtmlDocument(template) {
640
+ return /<html[\s>]/i.test(template) ? template : `<!DOCTYPE html><html><head></head><body>${template}</body></html>`;
641
+ }
642
+ function toGotenbergForm(pdfOptions) {
643
+ const { width, height, margin } = resolvePrintLayout(pdfOptions);
644
+ const fields = {
645
+ paperWidth: formatInches(width),
646
+ paperHeight: formatInches(height),
647
+ marginTop: formatInches(margin.top ?? 0),
648
+ marginRight: formatInches(margin.right ?? 0),
649
+ marginBottom: formatInches(margin.bottom ?? 0),
650
+ marginLeft: formatInches(margin.left ?? 0),
651
+ emulatedMediaType: "screen",
652
+ skipNetworkIdleEvent: "false"
653
+ };
654
+ if (pdfOptions.landscape !== void 0) fields.landscape = String(pdfOptions.landscape);
655
+ if (pdfOptions.printBackground !== void 0) fields.printBackground = String(pdfOptions.printBackground);
656
+ if (pdfOptions.omitBackground !== void 0) fields.omitBackground = String(pdfOptions.omitBackground);
657
+ if (pdfOptions.scale !== void 0) fields.scale = String(pdfOptions.scale);
658
+ if (pdfOptions.pageRanges) fields.nativePageRanges = pdfOptions.pageRanges;
659
+ if (pdfOptions.preferCSSPageSize !== void 0) fields.preferCssPageSize = String(pdfOptions.preferCSSPageSize);
660
+ if (pdfOptions.tagged !== void 0) fields.generateTaggedPdf = String(pdfOptions.tagged);
661
+ if (pdfOptions.outline !== void 0) fields.generateDocumentOutline = String(pdfOptions.outline);
662
+ const files = {};
663
+ if (pdfOptions.displayHeaderFooter) {
664
+ if (pdfOptions.headerTemplate) files["header.html"] = toHtmlDocument(pdfOptions.headerTemplate);
665
+ if (pdfOptions.footerTemplate) files["footer.html"] = toHtmlDocument(pdfOptions.footerTemplate);
666
+ }
667
+ return {
668
+ fields,
669
+ files
670
+ };
671
+ }
672
+ function toApi2PdfOptions(pdfOptions) {
673
+ const { width, height, margin } = resolvePrintLayout(pdfOptions);
674
+ const options = {
675
+ width: `${formatInches(width)}in`,
676
+ height: `${formatInches(height)}in`,
677
+ marginTop: `${formatInches(margin.top ?? 0)}in`,
678
+ marginRight: `${formatInches(margin.right ?? 0)}in`,
679
+ marginBottom: `${formatInches(margin.bottom ?? 0)}in`,
680
+ marginLeft: `${formatInches(margin.left ?? 0)}in`,
681
+ usePrintCss: false
682
+ };
683
+ for (const key of [
684
+ "landscape",
685
+ "printBackground",
686
+ "omitBackground",
687
+ "scale",
688
+ "pageRanges",
689
+ "displayHeaderFooter",
690
+ "headerTemplate",
691
+ "footerTemplate"
692
+ ]) if (pdfOptions[key] !== void 0) options[key] = pdfOptions[key];
693
+ return options;
694
+ }
695
+ // src/renderers/api2pdf.renderer.ts
696
+ const PROVIDER$1 = "Api2Pdf";
697
+ const DEFAULT_BASE_URL = "https://v2.api2pdf.com";
698
+ const ROUTE$1 = "/chrome/pdf/html";
699
+ function isApi2Pdf(data) {
700
+ return typeof data === "object" && data !== null && ("Success" in data || "Error" in data || "FileUrl" in data);
701
+ }
702
+ var Api2PdfRenderer = class {
703
+ #endpoint;
704
+ #headers;
705
+ constructor(provider) {
706
+ const apiKey = requireNonEmpty(provider.apiKey, "apiKey", PROVIDER$1);
707
+ const baseUrl = requireNonEmpty(provider.baseUrl ?? DEFAULT_BASE_URL, "baseUrl", PROVIDER$1).replace(/\/+$/, "");
708
+ this.#endpoint = `${baseUrl}${ROUTE$1}?outputBinary=true`;
709
+ this.#headers = {
710
+ ...provider.headers,
711
+ Authorization: apiKey,
712
+ "Content-Type": "application/json",
713
+ Accept: "application/pdf, application/json"
714
+ };
715
+ }
716
+ async render(html, options, signal) {
717
+ assertNoRequestGuard(PROVIDER$1, options, "Only render trusted HTML with a remote provider.");
718
+ const body = {
719
+ html,
720
+ inline: false,
721
+ options: {
722
+ ...toApi2PdfOptions(options.pdfOptions ?? { format: "A4" }),
723
+ ...options.api2pdfOptions?.options
724
+ }
725
+ };
726
+ if (options.api2pdfOptions?.fileName) body.fileName = options.api2pdfOptions.fileName;
727
+ const response = await fetch(this.#endpoint, {
728
+ method: "POST",
729
+ headers: this.#headers,
730
+ body: JSON.stringify(body),
731
+ signal
732
+ });
733
+ if (!response.ok) throw await httpError(PROVIDER$1, response);
734
+ if (!response.headers.get("content-type")?.includes("application/json")) return new Uint8Array(await response.arrayBuffer());
735
+ const result = await response.json();
736
+ if (!isApi2Pdf(result)) throw new PdfGenerationException(`${PROVIDER$1} returned an unexpected response: ${JSON.stringify(result)}`);
737
+ if (result.Success === false || !result.FileUrl) throw new PdfGenerationException(`${PROVIDER$1} could not generate the PDF: ${result.Error ?? "no file returned"}`);
738
+ const file = await fetch(result.FileUrl, { signal });
739
+ if (!file.ok) throw await httpError(PROVIDER$1, file);
740
+ return new Uint8Array(await file.arrayBuffer());
741
+ }
742
+ };
743
+ // src/renderers/gotenberg.renderer.ts
744
+ const PROVIDER = "Gotenberg";
745
+ const ROUTE = "/forms/chromium/convert/html";
746
+ var GotenbergRenderer = class {
747
+ #endpoint;
748
+ #headers;
749
+ constructor(provider) {
750
+ const url = requireNonEmpty(provider.url, "url", PROVIDER);
751
+ this.#endpoint = `${url.replace(/\/+$/, "")}${ROUTE}`;
752
+ this.#headers = { ...provider.headers };
753
+ if (provider.basicAuth) {
754
+ const { username, password } = provider.basicAuth;
755
+ this.#headers.Authorization = `Basic ${Buffer.from(`${username}:${password}`).toString("base64")}`;
756
+ }
757
+ }
758
+ async render(html, options, signal) {
759
+ assertNoRequestGuard(PROVIDER, options, "Restrict outbound requests on the Gotenberg server instead, with '--chromium-allow-list' / '--chromium-deny-list'.");
760
+ const { fields, files } = toGotenbergForm(options.pdfOptions ?? { format: "A4" });
761
+ const form = new FormData();
762
+ form.append("files", new Blob([html], { type: "text/html" }), "index.html");
763
+ for (const [name, content] of Object.entries(files)) form.append("files", new Blob([content], { type: "text/html" }), name);
764
+ for (const asset of options.gotenbergOptions?.assets ?? []) form.append("files", new Blob([asset.content], { type: asset.contentType ?? "application/octet-stream" }), asset.filename);
765
+ const allFields = {
766
+ ...fields,
767
+ ...options.gotenbergOptions?.formFields
768
+ };
769
+ for (const [name, value] of Object.entries(allFields)) form.append(name, value);
770
+ const response = await fetch(this.#endpoint, {
771
+ method: "POST",
772
+ headers: this.#headers,
773
+ body: form,
774
+ signal
775
+ });
776
+ if (!response.ok) throw await httpError(PROVIDER, response);
777
+ return new Uint8Array(await response.arrayBuffer());
778
+ }
779
+ };
780
+ // src/puppeteer/libs/loadPuppeteer.utils.ts
781
+ function isMissingPackage(error, packageName) {
782
+ const { code, message } = error;
783
+ return (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") && typeof message === "string" && message.includes(`'${packageName}'`);
784
+ }
785
+ /** Imports an optional peer dependency, turning "not installed" into a clear exception. */
786
+ async function loadOptional(packageName, importer) {
787
+ try {
788
+ return await importer();
789
+ } catch (error) {
790
+ if (isMissingPackage(error, packageName)) throw new EngineNotAvailableException("Puppeteer", packageName, { cause: error });
791
+ throw error;
792
+ }
793
+ }
794
+ /**
795
+ * Puppeteer is an optional peer dependency, only needed by the `puppeteer`
796
+ * provider: it is imported on first use, never when the library loads.
797
+ */
798
+ function loadPuppeteer() {
799
+ return loadOptional("puppeteer", () => import("puppeteer"));
800
+ }
801
+ function loadPuppeteerBrowsers() {
802
+ return loadOptional("@puppeteer/browsers", () => import("@puppeteer/browsers"));
803
+ }
804
+ // src/helpers/request-guard.helper.ts
557
805
  const blockedRanges = new node_net.BlockList();
558
806
  for (const [address, prefix] of [
559
807
  ["0.0.0.0", 8],
@@ -681,8 +929,9 @@ function describe(rawUrl) {
681
929
  * and closes the pop-ups a script could open to escape the filter.
682
930
  */
683
931
  async function installRequestGuard(context, page, options) {
932
+ const { TargetType } = await loadPuppeteer();
684
933
  context.on("targetcreated", (target) => {
685
- if (target.type() === puppeteer.TargetType.PAGE && target.opener()) target.page().then((popup) => popup?.close()).catch(() => void 0);
934
+ if (target.type() === TargetType.PAGE && target.opener()) target.page().then((popup) => popup?.close()).catch(() => void 0);
686
935
  });
687
936
  if (options.javascriptEnabled === false) await page.setJavaScriptEnabled(false);
688
937
  await page.setRequestInterception(true);
@@ -700,31 +949,162 @@ async function installRequestGuard(context, page, options) {
700
949
  })().catch(() => void 0);
701
950
  });
702
951
  }
703
- //#endregion
704
- //#region src/helpers/tokens.ts
705
- const PDF_PARAMETERS = "PDF_PARAMETERS";
706
- //#endregion
707
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorateMetadata.js
952
+ // src/renderers/puppeteer.renderer.ts
953
+ const DEFAULT_ARGS = [
954
+ "--autoplay-policy=user-gesture-required",
955
+ "--disable-background-networking",
956
+ "--disable-background-timer-throttling",
957
+ "--disable-backgrounding-occluded-windows",
958
+ "--disable-breakpad",
959
+ "--disable-client-side-phishing-detection",
960
+ "--disable-component-update",
961
+ "--disable-default-apps",
962
+ "--disable-dev-shm-usage",
963
+ "--disable-domain-reliability",
964
+ "--disable-extensions",
965
+ "--disable-features=AudioServiceOutOfProcess",
966
+ "--disable-hang-monitor",
967
+ "--disable-ipc-flooding-protection",
968
+ "--disable-notifications",
969
+ "--disable-offer-store-unmasked-wallet-cards",
970
+ "--disable-print-preview",
971
+ "--disable-prompt-on-repost",
972
+ "--disable-renderer-backgrounding",
973
+ "--disable-setuid-sandbox",
974
+ "--disable-speech-api",
975
+ "--disable-sync",
976
+ "--hide-scrollbars",
977
+ "--ignore-gpu-blacklist",
978
+ "--metrics-recording-only",
979
+ "--mute-audio",
980
+ "--no-default-browser-check",
981
+ "--no-first-run",
982
+ "--no-pings",
983
+ "--password-store=basic",
984
+ "--use-gl=swiftshader",
985
+ "--use-mock-keychain",
986
+ "--disable-accelerated-2d-canvas",
987
+ "--no-zygote",
988
+ "--disable-gpu"
989
+ ];
990
+ const PDF_OPTION_KEYS = {
991
+ scale: true,
992
+ displayHeaderFooter: true,
993
+ headerTemplate: true,
994
+ footerTemplate: true,
995
+ printBackground: true,
996
+ landscape: true,
997
+ pageRanges: true,
998
+ format: true,
999
+ width: true,
1000
+ height: true,
1001
+ preferCSSPageSize: true,
1002
+ margin: true,
1003
+ path: true,
1004
+ omitBackground: true,
1005
+ tagged: true,
1006
+ outline: true,
1007
+ timeout: true,
1008
+ waitForFonts: true
1009
+ };
1010
+ function toPuppeteerPdfOptions(options) {
1011
+ if (!options) return { format: "A4" };
1012
+ const invalidKeys = Object.keys(options).filter((key) => !Object.hasOwn(PDF_OPTION_KEYS, key));
1013
+ if (invalidKeys.length > 0) throw new RendererConfigurationException(`Invalid PDF options: ${invalidKeys.join(", ")}. Please check the documentation for valid options.`);
1014
+ return options;
1015
+ }
1016
+ var PuppeteerRenderer = class {
1017
+ #browserService;
1018
+ constructor(browserService) {
1019
+ this.#browserService = browserService;
1020
+ }
1021
+ async render(html, options, signal) {
1022
+ if (options.chromiumRevision !== void 0) _nestjs_common.Logger.warn("Using `chromiumRevision` is no longer supported since the puppeteer update.");
1023
+ const pdfOptions = toPuppeteerPdfOptions(options.pdfOptions);
1024
+ const headless = options.headless ?? true;
1025
+ const executablePath = options.executablePath || void 0;
1026
+ const args = options.extraPuppeteerArgs || DEFAULT_ARGS;
1027
+ let context = null;
1028
+ let closing;
1029
+ const onAbort = () => {
1030
+ if (!context) return;
1031
+ closing = context.close();
1032
+ closing.catch(() => void 0);
1033
+ };
1034
+ signal?.addEventListener("abort", onAbort, { once: true });
1035
+ try {
1036
+ context = await this.#browserService.createContext(args, headless, executablePath);
1037
+ signal?.throwIfAborted();
1038
+ const page = await context.newPage();
1039
+ if (options.security) await installRequestGuard(context, page, options.security);
1040
+ await page.setContent(html, { waitUntil: "domcontentloaded" });
1041
+ await page.emulateMediaType("screen");
1042
+ await page.waitForNetworkIdle({
1043
+ idleTime: 500,
1044
+ timeout: 3e4
1045
+ });
1046
+ /* v8 ignore next */
1047
+ await page.evaluate(() => document.fonts.ready);
1048
+ return await page.pdf(pdfOptions);
1049
+ } finally {
1050
+ signal?.removeEventListener("abort", onAbort);
1051
+ if (context) try {
1052
+ if (closing) await closing;
1053
+ else await context.close();
1054
+ } catch (error) {
1055
+ _nestjs_common.Logger.error(error);
1056
+ }
1057
+ }
1058
+ }
1059
+ };
1060
+ // src/renderers/create-renderer.ts
1061
+ /** True when the PDFs are printed by the local Chromium (the default). */
1062
+ function usesPuppeteer(params) {
1063
+ return (params.provider?.type ?? "puppeteer") === "puppeteer";
1064
+ }
1065
+ function createPdfRenderer(params, browserService) {
1066
+ const provider = params.provider ?? { type: "puppeteer" };
1067
+ switch (provider.type) {
1068
+ case "puppeteer": return new PuppeteerRenderer(browserService);
1069
+ case "gotenberg": return new GotenbergRenderer(provider);
1070
+ case "api2pdf": return new Api2PdfRenderer(provider);
1071
+ default: throw new RendererConfigurationException(`Unknown PDF provider '${String(provider.type)}': expected 'puppeteer', 'gotenberg' or 'api2pdf'`);
1072
+ }
1073
+ }
1074
+ // src/puppeteer/libs/enum.utils.ts
1075
+ /**
1076
+ * Converts a string value to an enum member, throwing a RendererConfigurationException if the value is not a valid member of the enum.
1077
+ * @param enumObject
1078
+ * @param value
1079
+ * @param label
1080
+ * @throws RendererConfigurationException
1081
+ */
1082
+ function toEnumMember(enumObject, value, label) {
1083
+ const members = Object.values(enumObject);
1084
+ const isMember = (candidate) => candidate === value;
1085
+ const member = members.find(isMember);
1086
+ if (member === void 0) throw new RendererConfigurationException(`Unsupported ${label} '${value}': expected one of ${members.map((m) => `'${m}'`).join(", ")}`);
1087
+ return member;
1088
+ }
1089
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/decorateMetadata.js
708
1090
  function __decorateMetadata(k, v) {
709
1091
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
710
1092
  }
711
- //#endregion
712
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorateParam.js
1093
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/decorateParam.js
713
1094
  function __decorateParam(paramIndex, decorator) {
714
1095
  return function(target, key) {
715
1096
  decorator(target, key, paramIndex);
716
1097
  };
717
1098
  }
718
- //#endregion
719
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
1099
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/decorate.js
720
1100
  function __decorate(decorators, target, key, desc) {
721
1101
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
722
1102
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
723
1103
  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;
724
1104
  return c > 3 && r && Object.defineProperty(target, key, r), r;
725
1105
  }
726
- //#endregion
727
- //#region src/puppeteer/browser/browser.service.ts
1106
+ // src/puppeteer/browser/browser.service.ts
1107
+ const DEFAULT_BROWSER = "chromium";
728
1108
  async function sleep(ms) {
729
1109
  await new Promise((r) => setTimeout(r, ms));
730
1110
  }
@@ -776,7 +1156,7 @@ let BrowserService = class BrowserService {
776
1156
  } catch (error) {
777
1157
  _nestjs_common.Logger.warn(`Failed to close browser on module destroy: ${error instanceof Error ? error.message : String(error)}`);
778
1158
  }
779
- if (this.#options?.cleanupBrowserCacheOnExit !== false) await this.#cleanupCacheBestEffort();
1159
+ if (this.#options !== void 0 && usesPuppeteer(this.#options) && this.#options.cleanupBrowserCacheOnExit !== false) await this.#cleanupCacheBestEffort();
780
1160
  }
781
1161
  /** Wait until no PDF job is in flight, or until the timeout elapses. */
782
1162
  async #waitForIdle(timeoutMs) {
@@ -858,11 +1238,12 @@ let BrowserService = class BrowserService {
858
1238
  }
859
1239
  }
860
1240
  async #doInstall(lock) {
861
- const browser = this.#browser;
1241
+ const { Browser: BrowserEnum, BrowserPlatform, canDownload, detectBrowserPlatform, install, resolveBuildId } = await loadPuppeteerBrowsers();
1242
+ const browser = toEnumMember(BrowserEnum, this.#browser, "browser");
862
1243
  const versionTag = this.#browserTag;
863
- const browserPlatform = (0, _puppeteer_browsers.detectBrowserPlatform)() ?? _puppeteer_browsers.BrowserPlatform.LINUX;
1244
+ const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;
864
1245
  let buildId;
865
- if (this.#buildId === void 0) buildId = await (0, _puppeteer_browsers.resolveBuildId)(browser, browserPlatform, versionTag);
1246
+ if (this.#buildId === void 0) buildId = await resolveBuildId(browser, browserPlatform, versionTag);
866
1247
  else buildId = this.#buildId;
867
1248
  _nestjs_common.Logger.log(`Browser ${browser} ${versionTag} build id: ${buildId}`, "NestJsPdf");
868
1249
  if (await this.hasBrowserInstalled(browser, buildId)) {
@@ -877,9 +1258,9 @@ let BrowserService = class BrowserService {
877
1258
  buildId,
878
1259
  baseUrl: this.#options?.browserInstallBaseUrl ?? void 0
879
1260
  };
880
- if (await (0, _puppeteer_browsers.canDownload)(installOption)) {
1261
+ if (await canDownload(installOption)) {
881
1262
  _nestjs_common.Logger.log(`Installing ${installOption.browser} ${installOption.buildId}`, "NestJsPdf");
882
- const installedBrowser = await (0, _puppeteer_browsers.install)(installOption);
1263
+ const installedBrowser = await install(installOption);
883
1264
  if (await this.hasBrowserInstalled(browser, buildId)) {
884
1265
  _nestjs_common.Logger.log("Browser installed successfully", "NestJsPdf");
885
1266
  if (lock) this.#writeLockFile(browser, buildId);
@@ -890,10 +1271,7 @@ let BrowserService = class BrowserService {
890
1271
  return null;
891
1272
  }
892
1273
  #loadBrowser() {
893
- let browser;
894
- if (this.#options?.browser === void 0) browser = _puppeteer_browsers.Browser.CHROMIUM;
895
- else browser = this.#options.browser;
896
- this.#browser = browser;
1274
+ this.#browser = this.#options?.browser ?? DEFAULT_BROWSER;
897
1275
  }
898
1276
  getBrowser() {
899
1277
  return this.#browser;
@@ -901,7 +1279,7 @@ let BrowserService = class BrowserService {
901
1279
  #loadBrowserTag() {
902
1280
  let versionTag;
903
1281
  if (this.#options?.browserTag === void 0) {
904
- if (this.#browser === _puppeteer_browsers.Browser.CHROMIUM) versionTag = "latest";
1282
+ if (this.#browser === DEFAULT_BROWSER) versionTag = "latest";
905
1283
  else versionTag = "stable";
906
1284
  } else versionTag = this.#options.browserTag;
907
1285
  this.#browserTag = versionTag;
@@ -928,21 +1306,24 @@ let BrowserService = class BrowserService {
928
1306
  this.#useLockedBrowser = useLockedBrowser;
929
1307
  }
930
1308
  async hasBrowserInstalled(browser, buildId) {
931
- return (await (0, _puppeteer_browsers.getInstalledBrowsers)({ cacheDir: this.#cacheDir })).find((insBrowser) => {
932
- return insBrowser.browser === browser && insBrowser.buildId === buildId;
1309
+ const { Browser: BrowserEnum, getInstalledBrowsers } = await loadPuppeteerBrowsers();
1310
+ const expected = toEnumMember(BrowserEnum, browser, "browser");
1311
+ return (await getInstalledBrowsers({ cacheDir: this.#cacheDir })).find((insBrowser) => {
1312
+ return insBrowser.browser === expected && insBrowser.buildId === buildId;
933
1313
  }) !== void 0;
934
1314
  }
935
1315
  async getExecutablePath() {
936
- const browser = this.#browser;
1316
+ const { Browser: BrowserEnum, BrowserPlatform, detectBrowserPlatform, getInstalledBrowsers, resolveBuildId } = await loadPuppeteerBrowsers();
1317
+ const browser = toEnumMember(BrowserEnum, this.#browser, "browser");
937
1318
  const versionTag = this.#browserTag;
938
- const browserPlatform = (0, _puppeteer_browsers.detectBrowserPlatform)() ?? _puppeteer_browsers.BrowserPlatform.LINUX;
1319
+ const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;
939
1320
  let buildId = null;
940
1321
  if (this.#useLockedBrowser) {
941
1322
  buildId = this.getLockedBuildId(browser);
942
1323
  _nestjs_common.Logger.log(`Using locked browser ${buildId}`, "NestJsPdf");
943
1324
  }
944
- buildId ??= await (0, _puppeteer_browsers.resolveBuildId)(browser, browserPlatform, versionTag);
945
- const installedBrowser = (await (0, _puppeteer_browsers.getInstalledBrowsers)({ cacheDir: this.#cacheDir })).find((insBrowser) => {
1325
+ buildId ??= await resolveBuildId(browser, browserPlatform, versionTag);
1326
+ const installedBrowser = (await getInstalledBrowsers({ cacheDir: this.#cacheDir })).find((insBrowser) => {
946
1327
  return insBrowser.browser === browser && insBrowser.buildId === buildId;
947
1328
  });
948
1329
  if (installedBrowser === void 0) {
@@ -954,7 +1335,8 @@ let BrowserService = class BrowserService {
954
1335
  }
955
1336
  async #launchBrowser(args, headless, executablePathBin) {
956
1337
  const executablePath = executablePathBin ?? await this.getExecutablePath();
957
- const browser = await (0, puppeteer.launch)({
1338
+ const { launch } = await loadPuppeteer();
1339
+ const browser = await launch({
958
1340
  executablePath,
959
1341
  headless,
960
1342
  args,
@@ -990,12 +1372,33 @@ BrowserService = __decorate([
990
1372
  __decorateParam(0, (0, _nestjs_common.Inject)("PDF_PARAMETERS")),
991
1373
  __decorateMetadata("design:paramtypes", [Object])
992
1374
  ], BrowserService);
993
- //#endregion
994
- //#region src/puppeteer/engines/ejs/ejs.service.ts
1375
+ // src/puppeteer/libs/loadEngine.utils.ts
1376
+ const requireEngine = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
1377
+ /**
1378
+ * Load an optional template engine on first use, so the library can be imported
1379
+ * without every engine installed. `require` (not `import()`) is used on purpose:
1380
+ * most engines expose a synchronous render API.
1381
+ */
1382
+ function loadEngine(packageName, engineName) {
1383
+ let mod;
1384
+ try {
1385
+ mod = requireEngine(packageName);
1386
+ } catch (error) {
1387
+ if (error.code === "MODULE_NOT_FOUND") throw new EngineNotAvailableException(engineName, packageName, { cause: error });
1388
+ throw error;
1389
+ }
1390
+ return mod.__esModule && "default" in mod ? mod.default : mod;
1391
+ }
1392
+ // src/puppeteer/engines/ejs/ejs.service.ts
995
1393
  let EjsService = class EjsService {
1394
+ #ejs;
1395
+ get #engine() {
1396
+ return this.#ejs ??= loadEngine("ejs", "EJS");
1397
+ }
996
1398
  async render(template, data = {}, options) {
1399
+ const engine = this.#engine;
997
1400
  try {
998
- return await ejs.default.render(template, data, {
1401
+ return await engine.render(template, data, {
999
1402
  async: true,
1000
1403
  ...options
1001
1404
  });
@@ -1004,8 +1407,9 @@ let EjsService = class EjsService {
1004
1407
  }
1005
1408
  }
1006
1409
  async renderFile(filePath, data = {}, options) {
1410
+ const engine = this.#engine;
1007
1411
  try {
1008
- return await ejs.default.renderFile(filePath, data, {
1412
+ return await engine.renderFile(filePath, data, {
1009
1413
  async: true,
1010
1414
  ...options
1011
1415
  });
@@ -1015,18 +1419,14 @@ let EjsService = class EjsService {
1015
1419
  }
1016
1420
  };
1017
1421
  EjsService = __decorate([(0, _nestjs_common.Injectable)()], EjsService);
1018
- //#endregion
1019
- //#region src/puppeteer/engines/eta/eta.service.ts
1422
+ // src/puppeteer/engines/eta/eta.service.ts
1020
1423
  let EtaService = class EtaService {
1424
+ #etaModule;
1021
1425
  #eta;
1022
1426
  #templateCache = /* @__PURE__ */ new Map();
1023
1427
  #maxCacheSize = 100;
1024
- constructor() {
1025
- this.#eta = new eta.Eta({
1026
- cache: true,
1027
- autoEscape: true,
1028
- useWith: true
1029
- });
1428
+ get #engine() {
1429
+ return this.#etaModule ??= loadEngine("eta", "Eta");
1030
1430
  }
1031
1431
  /**
1032
1432
  * Render an Eta template from a string
@@ -1036,14 +1436,19 @@ let EtaService = class EtaService {
1036
1436
  * @returns The rendered HTML string
1037
1437
  */
1038
1438
  render(template, data = {}, options) {
1439
+ const { Eta } = this.#engine;
1039
1440
  try {
1040
- return (options && Object.keys(options).length > 0 ? new eta.Eta({
1441
+ return (options && Object.keys(options).length > 0 ? new Eta({
1041
1442
  cache: true,
1042
1443
  autoEscape: true,
1043
1444
  useWith: true,
1044
1445
  ...options,
1045
1446
  varName: options.varName ?? "it"
1046
- }) : this.#eta).renderString(template, data);
1447
+ }) : this.#eta ??= new Eta({
1448
+ cache: true,
1449
+ autoEscape: true,
1450
+ useWith: true
1451
+ })).renderString(template, data);
1047
1452
  } catch (error) {
1048
1453
  throw new TemplateRenderException("Eta", `Eta rendering failed: ${String(error)}`, { cause: error });
1049
1454
  }
@@ -1066,6 +1471,7 @@ let EtaService = class EtaService {
1066
1471
  }
1067
1472
  return this.render(template, data, options);
1068
1473
  } catch (error) {
1474
+ if (error instanceof EngineNotAvailableException) throw error;
1069
1475
  throw new TemplateRenderException("Eta", `Eta file rendering failed for ${filePath}: ${String(error)}`, { cause: error });
1070
1476
  }
1071
1477
  }
@@ -1083,12 +1489,15 @@ let EtaService = class EtaService {
1083
1489
  return this.#templateCache.size;
1084
1490
  }
1085
1491
  };
1086
- EtaService = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [])], EtaService);
1087
- //#endregion
1088
- //#region src/puppeteer/engines/handlebars/handlebars.service.ts
1492
+ EtaService = __decorate([(0, _nestjs_common.Injectable)()], EtaService);
1493
+ // src/puppeteer/engines/handlebars/handlebars.service.ts
1089
1494
  let HandlebarsService = class HandlebarsService {
1495
+ #handlebars;
1090
1496
  #cachedOptions;
1091
1497
  #cachedEnv;
1498
+ get #engine() {
1499
+ return this.#handlebars ??= loadEngine("handlebars", "Handlebars");
1500
+ }
1092
1501
  render(template, parameters = {}, options = {}) {
1093
1502
  try {
1094
1503
  return this.#getEnv(options).compile(template, options.compileOptions)(parameters, options.templateOptions);
@@ -1117,7 +1526,7 @@ let HandlebarsService = class HandlebarsService {
1117
1526
  */
1118
1527
  #getEnv(options) {
1119
1528
  if (this.#cachedEnv && this.#cachedOptions === options) return this.#cachedEnv;
1120
- const env = handlebars.default.create();
1529
+ const env = this.#engine.create();
1121
1530
  for (const helper of options.helpers ?? []) env.registerHelper(helper.name, helper.fn);
1122
1531
  this.#registerPartials(env, options.partialDirectory);
1123
1532
  this.#cachedOptions = options;
@@ -1136,12 +1545,77 @@ let HandlebarsService = class HandlebarsService {
1136
1545
  }
1137
1546
  };
1138
1547
  HandlebarsService = __decorate([(0, _nestjs_common.Injectable)()], HandlebarsService);
1139
- //#endregion
1140
- //#region src/puppeteer/engines/mjml/mjml.service.ts
1548
+ // src/puppeteer/engines/liquid/liquid.service.ts
1549
+ let LiquidService = class LiquidService {
1550
+ #liquidModule;
1551
+ #liquid;
1552
+ #templateCache = /* @__PURE__ */ new Map();
1553
+ #maxCacheSize = 100;
1554
+ get #engine() {
1555
+ return this.#liquidModule ??= loadEngine("liquidjs", "Liquid");
1556
+ }
1557
+ /**
1558
+ * Render a Liquid template from a string
1559
+ * @param template The template string to render
1560
+ * @param data The data object to use for rendering
1561
+ * @param options Optional Liquid engine options
1562
+ * @returns The rendered HTML string
1563
+ */
1564
+ render(template, data = {}, options) {
1565
+ const { Liquid } = this.#engine;
1566
+ try {
1567
+ return (options && Object.keys(options).length > 0 ? new Liquid(options) : this.#liquid ??= new Liquid()).parseAndRenderSync(template, data);
1568
+ } catch (error) {
1569
+ throw new TemplateRenderException("Liquid", `Liquid rendering failed: ${String(error)}`, { cause: error });
1570
+ }
1571
+ }
1572
+ /**
1573
+ * Render a Liquid template from a file
1574
+ * @param filePath The path to the template file
1575
+ * @param data The data object to use for rendering
1576
+ * @param options Optional Liquid engine options
1577
+ * @returns The rendered HTML string
1578
+ */
1579
+ renderFile(filePath, data = {}, options) {
1580
+ try {
1581
+ const resolvedPath = (0, node_path.resolve)(filePath);
1582
+ const useCache = options?.cache !== false;
1583
+ let template = useCache ? this.#templateCache.get(resolvedPath) : void 0;
1584
+ if (!template) {
1585
+ template = (0, node_fs.readFileSync)(resolvedPath, "utf-8");
1586
+ if (useCache && this.#templateCache.size < this.#maxCacheSize) this.#templateCache.set(resolvedPath, template);
1587
+ }
1588
+ return this.render(template, data, options);
1589
+ } catch (error) {
1590
+ if (error instanceof EngineNotAvailableException) throw error;
1591
+ throw new TemplateRenderException("Liquid", `Liquid file rendering failed for ${filePath}: ${String(error)}`, { cause: error });
1592
+ }
1593
+ }
1594
+ /**
1595
+ * Clear the template cache
1596
+ */
1597
+ clearCache() {
1598
+ this.#templateCache.clear();
1599
+ }
1600
+ /**
1601
+ * Get the current cache size
1602
+ * @returns The number of cached templates
1603
+ */
1604
+ getCacheSize() {
1605
+ return this.#templateCache.size;
1606
+ }
1607
+ };
1608
+ LiquidService = __decorate([(0, _nestjs_common.Injectable)()], LiquidService);
1609
+ // src/puppeteer/engines/mjml/mjml.service.ts
1141
1610
  let MjmlService = class MjmlService {
1611
+ #mjml;
1612
+ get #engine() {
1613
+ return this.#mjml ??= loadEngine("mjml", "MJML");
1614
+ }
1142
1615
  async render(template, options) {
1616
+ const engine = this.#engine;
1143
1617
  try {
1144
- const { html } = await (0, mjml.default)(template, options);
1618
+ const { html } = await engine(template, options);
1145
1619
  return html;
1146
1620
  } catch (error) {
1147
1621
  throw new TemplateRenderException("MJML", `MJML rendering failed: ${String(error)}`, { cause: error });
@@ -1158,11 +1632,14 @@ let MjmlService = class MjmlService {
1158
1632
  }
1159
1633
  };
1160
1634
  MjmlService = __decorate([(0, _nestjs_common.Injectable)()], MjmlService);
1161
- //#endregion
1162
- //#region src/puppeteer/engines/mustache/mustache.service.ts
1635
+ // src/puppeteer/engines/mustache/mustache.service.ts
1163
1636
  let MustacheService = class MustacheService {
1637
+ #mustache;
1164
1638
  #templateCache = /* @__PURE__ */ new Map();
1165
1639
  #maxCacheSize = 100;
1640
+ get #engine() {
1641
+ return this.#mustache ??= loadEngine("mustache", "Mustache");
1642
+ }
1166
1643
  /**
1167
1644
  * Render a Mustache template from a string
1168
1645
  * @param template The template string to render
@@ -1171,9 +1648,10 @@ let MustacheService = class MustacheService {
1171
1648
  * @returns The rendered HTML string
1172
1649
  */
1173
1650
  render(template, data = {}, options) {
1651
+ const engine = this.#engine;
1174
1652
  try {
1175
1653
  const tags = options?.tags ?? ["{{", "}}"];
1176
- return mustache.default.render(template, data, void 0, {
1654
+ return engine.render(template, data, void 0, {
1177
1655
  tags,
1178
1656
  escape: options?.escape
1179
1657
  });
@@ -1198,6 +1676,7 @@ let MustacheService = class MustacheService {
1198
1676
  }
1199
1677
  return this.render(template, data, options);
1200
1678
  } catch (error) {
1679
+ if (error instanceof EngineNotAvailableException) throw error;
1201
1680
  throw new TemplateRenderException("Mustache", `Mustache file rendering failed for ${filePath}: ${String(error)}`, { cause: error });
1202
1681
  }
1203
1682
  }
@@ -1216,17 +1695,22 @@ let MustacheService = class MustacheService {
1216
1695
  }
1217
1696
  };
1218
1697
  MustacheService = __decorate([(0, _nestjs_common.Injectable)()], MustacheService);
1219
- //#endregion
1220
- //#region src/puppeteer/engines/nunjucks/nunjucks.service.ts
1698
+ // src/puppeteer/engines/nunjucks/nunjucks.service.ts
1221
1699
  let NunjucksService = class NunjucksService {
1222
- constructor() {
1223
- nunjucks.default.configure({
1224
- noCache: true,
1225
- trimBlocks: true,
1226
- lstripBlocks: true
1227
- });
1700
+ #nunjucks;
1701
+ get #engine() {
1702
+ if (!this.#nunjucks) {
1703
+ this.#nunjucks = loadEngine("nunjucks", "Nunjucks");
1704
+ this.#nunjucks.configure({
1705
+ noCache: true,
1706
+ trimBlocks: true,
1707
+ lstripBlocks: true
1708
+ });
1709
+ }
1710
+ return this.#nunjucks;
1228
1711
  }
1229
1712
  render(template, data = {}, options) {
1713
+ const nunjucks = this.#engine;
1230
1714
  try {
1231
1715
  if (options) {
1232
1716
  const configOptions = {
@@ -1236,14 +1720,15 @@ let NunjucksService = class NunjucksService {
1236
1720
  trimBlocks: options.trimBlocks ?? true,
1237
1721
  lstripBlocks: options.lstripBlocks ?? true
1238
1722
  };
1239
- nunjucks.default.configure(configOptions);
1723
+ nunjucks.configure(configOptions);
1240
1724
  }
1241
- return nunjucks.default.renderString(template, data);
1725
+ return nunjucks.renderString(template, data);
1242
1726
  } catch (error) {
1243
1727
  throw new TemplateRenderException("Nunjucks", `Nunjucks rendering failed: ${String(error)}`, { cause: error });
1244
1728
  }
1245
1729
  }
1246
1730
  renderFile(filePath, data = {}, options) {
1731
+ const nunjucks = this.#engine;
1247
1732
  try {
1248
1733
  if (options) {
1249
1734
  const configOptions = {
@@ -1253,21 +1738,25 @@ let NunjucksService = class NunjucksService {
1253
1738
  trimBlocks: options.trimBlocks ?? true,
1254
1739
  lstripBlocks: options.lstripBlocks ?? true
1255
1740
  };
1256
- nunjucks.default.configure(configOptions);
1741
+ nunjucks.configure(configOptions);
1257
1742
  }
1258
- return nunjucks.default.render(filePath, data);
1743
+ return nunjucks.render(filePath, data);
1259
1744
  } catch (error) {
1260
1745
  throw new TemplateRenderException("Nunjucks", `Nunjucks file rendering failed: ${String(error)}`, { cause: error });
1261
1746
  }
1262
1747
  }
1263
1748
  };
1264
- NunjucksService = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [])], NunjucksService);
1265
- //#endregion
1266
- //#region src/puppeteer/engines/pug/pug.service.ts
1749
+ NunjucksService = __decorate([(0, _nestjs_common.Injectable)()], NunjucksService);
1750
+ // src/puppeteer/engines/pug/pug.service.ts
1267
1751
  let PugService = class PugService {
1752
+ #pug;
1753
+ get #engine() {
1754
+ return this.#pug ??= loadEngine("pug", "Pug");
1755
+ }
1268
1756
  render(template, data = {}, options) {
1757
+ const engine = this.#engine;
1269
1758
  try {
1270
- return pug.default.compile(template, { ...options })(data);
1759
+ return engine.compile(template, { ...options })(data);
1271
1760
  } catch (error) {
1272
1761
  throw new TemplateRenderException("Pug", `Pug rendering failed: ${String(error)}`, { cause: error });
1273
1762
  }
@@ -1277,21 +1766,21 @@ let PugService = class PugService {
1277
1766
  const template = (0, node_fs.readFileSync)(filePath, "utf-8");
1278
1767
  return this.render(template, data, options);
1279
1768
  } catch (error) {
1769
+ if (error instanceof EngineNotAvailableException) throw error;
1280
1770
  throw new TemplateRenderException("Pug", `Pug file rendering failed: ${String(error)}`, { cause: error });
1281
1771
  }
1282
1772
  }
1283
1773
  };
1284
1774
  PugService = __decorate([(0, _nestjs_common.Injectable)()], PugService);
1285
- //#endregion
1286
- //#region src/puppeteer/libs/requireService.utils.ts
1775
+ // src/puppeteer/libs/requireService.utils.ts
1287
1776
  function requireService(service, name) {
1288
1777
  if (!service) throw new EngineNotAvailableException(name);
1289
1778
  return service;
1290
1779
  }
1291
- //#endregion
1292
- //#region src/puppeteer/puppeteer.service.ts
1780
+ // src/puppeteer/puppeteer.service.ts
1293
1781
  let PuppeteerService = class PuppeteerService {
1294
- #browserService;
1782
+ #renderer;
1783
+ #jobs;
1295
1784
  #options;
1296
1785
  #hbsService;
1297
1786
  #mjmlService;
@@ -1300,8 +1789,10 @@ let PuppeteerService = class PuppeteerService {
1300
1789
  #nunjucksService;
1301
1790
  #etaService;
1302
1791
  #mustacheService;
1303
- constructor(browserService, options, hbsService, mjmlService, pugService, ejsService, nunjucksService, etaService, mustacheService) {
1304
- this.#browserService = browserService;
1792
+ #liquidService;
1793
+ constructor(renderer, jobs, options, hbsService, mjmlService, pugService, ejsService, nunjucksService, etaService, mustacheService, liquidService) {
1794
+ this.#renderer = renderer;
1795
+ this.#jobs = jobs;
1305
1796
  this.#options = options;
1306
1797
  this.#hbsService = hbsService;
1307
1798
  this.#mjmlService = mjmlService;
@@ -1310,6 +1801,7 @@ let PuppeteerService = class PuppeteerService {
1310
1801
  this.#nunjucksService = nunjucksService;
1311
1802
  this.#etaService = etaService;
1312
1803
  this.#mustacheService = mustacheService;
1804
+ this.#liquidService = liquidService;
1313
1805
  }
1314
1806
  #limit = pLimit(3);
1315
1807
  async generatePdfFromHtml(html, options) {
@@ -1319,87 +1811,19 @@ let PuppeteerService = class PuppeteerService {
1319
1811
  const job = this.#limit(async () => {
1320
1812
  signal?.throwIfAborted();
1321
1813
  started = true;
1322
- const mergePuppeteerOptions = mergePuppeteerParameters(this.#options, options);
1323
- if (mergePuppeteerOptions.chromiumRevision !== void 0) _nestjs_common.Logger.warn("Using `chromiumRevision` is no longer supported since the puppeteer update.");
1324
- const headless = mergePuppeteerOptions.headless ?? true;
1325
- const executablePath = mergePuppeteerOptions.executablePath || void 0;
1326
- const args = mergePuppeteerOptions.extraPuppeteerArgs || [
1327
- "--autoplay-policy=user-gesture-required",
1328
- "--disable-background-networking",
1329
- "--disable-background-timer-throttling",
1330
- "--disable-backgrounding-occluded-windows",
1331
- "--disable-breakpad",
1332
- "--disable-client-side-phishing-detection",
1333
- "--disable-component-update",
1334
- "--disable-default-apps",
1335
- "--disable-dev-shm-usage",
1336
- "--disable-domain-reliability",
1337
- "--disable-extensions",
1338
- "--disable-features=AudioServiceOutOfProcess",
1339
- "--disable-hang-monitor",
1340
- "--disable-ipc-flooding-protection",
1341
- "--disable-notifications",
1342
- "--disable-offer-store-unmasked-wallet-cards",
1343
- "--disable-print-preview",
1344
- "--disable-prompt-on-repost",
1345
- "--disable-renderer-backgrounding",
1346
- "--disable-setuid-sandbox",
1347
- "--disable-speech-api",
1348
- "--disable-sync",
1349
- "--hide-scrollbars",
1350
- "--ignore-gpu-blacklist",
1351
- "--metrics-recording-only",
1352
- "--mute-audio",
1353
- "--no-default-browser-check",
1354
- "--no-first-run",
1355
- "--no-pings",
1356
- "--password-store=basic",
1357
- "--use-gl=swiftshader",
1358
- "--use-mock-keychain",
1359
- "--disable-accelerated-2d-canvas",
1360
- "--no-zygote",
1361
- "--disable-gpu"
1362
- ];
1363
- this.#browserService.markJobStarted();
1364
- let context = null;
1365
- let closing;
1366
- const onAbort = () => {
1367
- if (!context) return;
1368
- closing = context.close();
1369
- closing.catch(() => void 0);
1370
- };
1371
- signal?.addEventListener("abort", onAbort, { once: true });
1814
+ const mergedOptions = mergePuppeteerParameters(this.#options, options);
1815
+ this.#jobs.markJobStarted();
1372
1816
  try {
1373
- context = await this.#browserService.createContext(args, headless, executablePath);
1374
- signal?.throwIfAborted();
1375
- const page = await context.newPage();
1376
- if (mergePuppeteerOptions.security) await installRequestGuard(context, page, mergePuppeteerOptions.security);
1377
- const pdfOptions = mergePuppeteerOptions.pdfOptions ?? { format: "A4" };
1378
- await page.setContent(html, { waitUntil: "domcontentloaded" });
1379
- await page.emulateMediaType("screen");
1380
- await page.waitForNetworkIdle({
1381
- idleTime: 500,
1382
- timeout: 3e4
1383
- });
1384
- /* v8 ignore next */
1385
- await page.evaluate(() => document.fonts.ready);
1386
- const pdf = await page.pdf(pdfOptions);
1817
+ const pdf = await this.#renderer.render(html, mergedOptions, signal);
1387
1818
  signal?.throwIfAborted();
1388
- return mergePuppeteerOptions.watermark ? await addWatermark(pdf, mergePuppeteerOptions.watermark) : pdf;
1819
+ return mergedOptions.watermark ? await addWatermark(pdf, mergedOptions.watermark) : pdf;
1389
1820
  } catch (e) {
1390
1821
  if (signal?.aborted) throw signal.reason;
1391
1822
  _nestjs_common.Logger.error(e);
1392
1823
  if (e instanceof NestjsPdfException) throw e;
1393
1824
  throw new PdfGenerationException(`PDF generation failed: ${String(e)}`, { cause: e });
1394
1825
  } finally {
1395
- signal?.removeEventListener("abort", onAbort);
1396
- if (context) try {
1397
- if (closing) await closing;
1398
- else await context.close();
1399
- } catch (error) {
1400
- _nestjs_common.Logger.error(error);
1401
- }
1402
- await this.#browserService.markJobFinished();
1826
+ await this.#jobs.markJobFinished();
1403
1827
  }
1404
1828
  });
1405
1829
  if (!signal) return job;
@@ -1472,19 +1896,31 @@ let PuppeteerService = class PuppeteerService {
1472
1896
  const html = requireService(this.#mustacheService, "Mustache").renderFile(file, data, options?.mustacheOptions ?? this.#options.mustacheOptions);
1473
1897
  return this.generatePdfFromHtml(html, options);
1474
1898
  }
1899
+ async generatePdfFromLiquidString(template, data = {}, options) {
1900
+ const html = requireService(this.#liquidService, "Liquid").render(template, data, options?.liquidOptions ?? this.#options.liquidOptions);
1901
+ return this.generatePdfFromHtml(html, options);
1902
+ }
1903
+ async generatePdfFromLiquidFile(file, data = {}, options) {
1904
+ const html = requireService(this.#liquidService, "Liquid").renderFile(file, data, options?.liquidOptions ?? this.#options.liquidOptions);
1905
+ return this.generatePdfFromHtml(html, options);
1906
+ }
1475
1907
  };
1476
1908
  PuppeteerService = __decorate([
1477
1909
  (0, _nestjs_common.Injectable)(),
1478
- __decorateParam(1, (0, _nestjs_common.Inject)(PDF_PARAMETERS)),
1479
- __decorateParam(2, (0, _nestjs_common.Optional)()),
1910
+ __decorateParam(0, (0, _nestjs_common.Inject)(PDF_RENDERER)),
1911
+ __decorateParam(1, (0, _nestjs_common.Inject)(BrowserService)),
1912
+ __decorateParam(2, (0, _nestjs_common.Inject)(PDF_PARAMETERS)),
1480
1913
  __decorateParam(3, (0, _nestjs_common.Optional)()),
1481
1914
  __decorateParam(4, (0, _nestjs_common.Optional)()),
1482
1915
  __decorateParam(5, (0, _nestjs_common.Optional)()),
1483
1916
  __decorateParam(6, (0, _nestjs_common.Optional)()),
1484
1917
  __decorateParam(7, (0, _nestjs_common.Optional)()),
1485
1918
  __decorateParam(8, (0, _nestjs_common.Optional)()),
1919
+ __decorateParam(9, (0, _nestjs_common.Optional)()),
1920
+ __decorateParam(10, (0, _nestjs_common.Optional)()),
1486
1921
  __decorateMetadata("design:paramtypes", [
1487
- typeof BrowserService === "undefined" ? Object : BrowserService,
1922
+ Object,
1923
+ Object,
1488
1924
  Object,
1489
1925
  typeof HandlebarsService === "undefined" ? Object : HandlebarsService,
1490
1926
  typeof MjmlService === "undefined" ? Object : MjmlService,
@@ -1492,11 +1928,11 @@ PuppeteerService = __decorate([
1492
1928
  typeof EjsService === "undefined" ? Object : EjsService,
1493
1929
  typeof NunjucksService === "undefined" ? Object : NunjucksService,
1494
1930
  typeof EtaService === "undefined" ? Object : EtaService,
1495
- typeof MustacheService === "undefined" ? Object : MustacheService
1931
+ typeof MustacheService === "undefined" ? Object : MustacheService,
1932
+ typeof LiquidService === "undefined" ? Object : LiquidService
1496
1933
  ])
1497
1934
  ], PuppeteerService);
1498
- //#endregion
1499
- //#region src/nestjs-pdf.service.ts
1935
+ // src/nestjs-pdf.service.ts
1500
1936
  let NestjsPdfService = class NestjsPdfService {
1501
1937
  #puppeteerService;
1502
1938
  constructor(puppeteerService) {
@@ -1650,6 +2086,26 @@ let NestjsPdfService = class NestjsPdfService {
1650
2086
  return this.#puppeteerService.generatePdfFromMustacheFile(file, data, options);
1651
2087
  }
1652
2088
  /**
2089
+ * @param template Liquid template string
2090
+ * @param data Data to inject into the template
2091
+ * @param options PDF generation options (optional)
2092
+ * @returns PDF generated from the provided Liquid template with data applied
2093
+ * @description This method generates a PDF from a Liquid template provided as a string. Liquid is a safe, Shopify-compatible template language with filters, tags, partials and layouts. 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.
2094
+ */
2095
+ generatePdfFromLiquidString(template, data = {}, options) {
2096
+ return this.#puppeteerService.generatePdfFromLiquidString(template, data, options);
2097
+ }
2098
+ /**
2099
+ * @param file Path to the Liquid template file
2100
+ * @param data Data to inject into the template
2101
+ * @param options PDF generation options (optional)
2102
+ * @returns PDF generated from the Liquid template at the provided file path with data applied
2103
+ * @description This method generates a PDF from a Liquid 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.
2104
+ */
2105
+ generatePdfFromLiquidFile(file, data = {}, options) {
2106
+ return this.#puppeteerService.generatePdfFromLiquidFile(file, data, options);
2107
+ }
2108
+ /**
1653
2109
  * @param pdf The PDF bytes to modify
1654
2110
  * @param fieldName The name of the signature field to add (default: 'SignatureDebtor')
1655
2111
  * @param anchorText The text anchor to locate the signature field position (default: '__SIG_DEBTOR_ANCHOR__')
@@ -1696,9 +2152,14 @@ let NestjsPdfService = class NestjsPdfService {
1696
2152
  }
1697
2153
  };
1698
2154
  NestjsPdfService = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [typeof PuppeteerService === "undefined" ? Object : PuppeteerService])], NestjsPdfService);
1699
- //#endregion
1700
- //#region src/puppeteer/puppeteer.module.ts
2155
+ // src/puppeteer/puppeteer.module.ts
1701
2156
  var _PuppeteerModule;
2157
+ /** Builds the renderer of the configured provider, once the parameters are known. */
2158
+ const pdfRendererProvider = {
2159
+ provide: PDF_RENDERER,
2160
+ inject: [PDF_PARAMETERS, BrowserService],
2161
+ useFactory: createPdfRenderer
2162
+ };
1702
2163
  let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
1703
2164
  #browserService;
1704
2165
  #pdfParams;
@@ -1707,7 +2168,12 @@ let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
1707
2168
  this.#pdfParams = pdfParams;
1708
2169
  }
1709
2170
  async onModuleInit() {
1710
- if (!this.#pdfParams.executablePath) await this.#browserService.install(this.#pdfParams.useLockedBrowser ?? false);
2171
+ if (!usesPuppeteer(this.#pdfParams)) return;
2172
+ await loadPuppeteer();
2173
+ if (!this.#pdfParams.executablePath) {
2174
+ await loadPuppeteerBrowsers();
2175
+ await this.#browserService.install(this.#pdfParams.useLockedBrowser ?? false);
2176
+ }
1711
2177
  }
1712
2178
  static forRoot(pdfParameters) {
1713
2179
  return {
@@ -1723,7 +2189,8 @@ let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
1723
2189
  EjsService,
1724
2190
  NunjucksService,
1725
2191
  EtaService,
1726
- MustacheService
2192
+ MustacheService,
2193
+ LiquidService
1727
2194
  ],
1728
2195
  exports: [
1729
2196
  PuppeteerService,
@@ -1732,7 +2199,8 @@ let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
1732
2199
  EjsService,
1733
2200
  NunjucksService,
1734
2201
  EtaService,
1735
- MustacheService
2202
+ MustacheService,
2203
+ LiquidService
1736
2204
  ]
1737
2205
  };
1738
2206
  }
@@ -1749,13 +2217,15 @@ let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
1749
2217
  pdfParamsProvider,
1750
2218
  PuppeteerService,
1751
2219
  BrowserService,
2220
+ pdfRendererProvider,
1752
2221
  HandlebarsService,
1753
2222
  MjmlService,
1754
2223
  PugService,
1755
2224
  EjsService,
1756
2225
  NunjucksService,
1757
2226
  EtaService,
1758
- MustacheService
2227
+ MustacheService,
2228
+ LiquidService
1759
2229
  ],
1760
2230
  exports: [
1761
2231
  PuppeteerService,
@@ -1764,7 +2234,8 @@ let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
1764
2234
  EjsService,
1765
2235
  NunjucksService,
1766
2236
  EtaService,
1767
- MustacheService
2237
+ MustacheService,
2238
+ LiquidService
1768
2239
  ]
1769
2240
  };
1770
2241
  }
@@ -1774,12 +2245,14 @@ PuppeteerModule = _PuppeteerModule = __decorate([
1774
2245
  providers: [
1775
2246
  PuppeteerService,
1776
2247
  BrowserService,
2248
+ pdfRendererProvider,
1777
2249
  MjmlService,
1778
2250
  PugService,
1779
2251
  EjsService,
1780
2252
  NunjucksService,
1781
2253
  EtaService,
1782
- MustacheService
2254
+ MustacheService,
2255
+ LiquidService
1783
2256
  ],
1784
2257
  exports: [
1785
2258
  PuppeteerService,
@@ -1788,14 +2261,15 @@ PuppeteerModule = _PuppeteerModule = __decorate([
1788
2261
  EjsService,
1789
2262
  NunjucksService,
1790
2263
  EtaService,
1791
- MustacheService
2264
+ MustacheService,
2265
+ LiquidService
1792
2266
  ]
1793
2267
  }),
2268
+ __decorateParam(0, (0, _nestjs_common.Inject)(BrowserService)),
1794
2269
  __decorateParam(1, (0, _nestjs_common.Inject)(PDF_PARAMETERS)),
1795
- __decorateMetadata("design:paramtypes", [typeof BrowserService === "undefined" ? Object : BrowserService, Object])
2270
+ __decorateMetadata("design:paramtypes", [Object, Object])
1796
2271
  ], PuppeteerModule);
1797
- //#endregion
1798
- //#region src/nestjs-pdf.module.ts
2272
+ // src/nestjs-pdf.module.ts
1799
2273
  var _NestjsPdfModule;
1800
2274
  let NestjsPdfModule = _NestjsPdfModule = class NestjsPdfModule {
1801
2275
  static forRoot(options) {
@@ -1816,7 +2290,6 @@ let NestjsPdfModule = _NestjsPdfModule = class NestjsPdfModule {
1816
2290
  }
1817
2291
  };
1818
2292
  NestjsPdfModule = _NestjsPdfModule = __decorate([(0, _nestjs_common.Module)({})], NestjsPdfModule);
1819
- //#endregion
1820
2293
  exports.BrowserInstallationException = BrowserInstallationException;
1821
2294
  exports.BrowserUnavailableException = BrowserUnavailableException;
1822
2295
  Object.defineProperty(exports, "EjsService", {
@@ -1838,6 +2311,12 @@ Object.defineProperty(exports, "HandlebarsService", {
1838
2311
  return HandlebarsService;
1839
2312
  }
1840
2313
  });
2314
+ Object.defineProperty(exports, "LiquidService", {
2315
+ enumerable: true,
2316
+ get: function() {
2317
+ return LiquidService;
2318
+ }
2319
+ });
1841
2320
  Object.defineProperty(exports, "MjmlService", {
1842
2321
  enumerable: true,
1843
2322
  get: function() {
@@ -1889,6 +2368,7 @@ Object.defineProperty(exports, "PuppeteerService", {
1889
2368
  return PuppeteerService;
1890
2369
  }
1891
2370
  });
2371
+ exports.RendererConfigurationException = RendererConfigurationException;
1892
2372
  exports.SignatureDependencyException = SignatureDependencyException;
1893
2373
  exports.SignaturePlacementException = SignaturePlacementException;
1894
2374
  exports.TemplateConfigurationException = TemplateConfigurationException;