@shad0wz7/nestjs-pdf 4.0.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.mjs CHANGED
@@ -3,13 +3,11 @@ import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep }
3
3
  import { Inject, Injectable, Logger, Module, Optional } from "@nestjs/common";
4
4
  import { PDFArray, PDFDict, PDFDocument, PDFName, PDFNumber, PDFString, StandardFonts, degrees, rgb } from "pdf-lib";
5
5
  import { deepmerge } from "deepmerge-ts";
6
- import { lookup } from "node:dns/promises";
7
6
  import { existsSync, promises, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
7
+ import { lookup } from "node:dns/promises";
8
8
  import { BlockList, isIP } from "node:net";
9
9
  import { fileURLToPath } from "node:url";
10
- import { TargetType, launch } from "puppeteer";
11
- import { Browser as Browser$1, BrowserPlatform, canDownload, detectBrowserPlatform, getInstalledBrowsers, install, resolveBuildId } from "@puppeteer/browsers";
12
- //#region src/exceptions/nestjs-pdf.exception.ts
10
+ // src/exceptions/nestjs-pdf.exception.ts
13
11
  let NestjsPdfErrorCode = /* @__PURE__ */ function(NestjsPdfErrorCode) {
14
12
  NestjsPdfErrorCode["ENGINE_NOT_AVAILABLE"] = "ENGINE_NOT_AVAILABLE";
15
13
  NestjsPdfErrorCode["TEMPLATE_CONFIGURATION_ERROR"] = "TEMPLATE_CONFIGURATION_ERROR";
@@ -20,6 +18,7 @@ let NestjsPdfErrorCode = /* @__PURE__ */ function(NestjsPdfErrorCode) {
20
18
  NestjsPdfErrorCode["SIGNATURE_DEPENDENCY_ERROR"] = "SIGNATURE_DEPENDENCY_ERROR";
21
19
  NestjsPdfErrorCode["SIGNATURE_PLACEMENT_ERROR"] = "SIGNATURE_PLACEMENT_ERROR";
22
20
  NestjsPdfErrorCode["WATERMARK_ERROR"] = "WATERMARK_ERROR";
21
+ NestjsPdfErrorCode["RENDERER_CONFIGURATION_ERROR"] = "RENDERER_CONFIGURATION_ERROR";
23
22
  return NestjsPdfErrorCode;
24
23
  }({});
25
24
  var NestjsPdfException = class extends Error {
@@ -28,46 +27,43 @@ var NestjsPdfException = class extends Error {
28
27
  this.name = this.constructor.name;
29
28
  }
30
29
  };
31
- //#endregion
32
- //#region src/exceptions/browser-installation.exception.ts
30
+ // src/exceptions/browser-installation.exception.ts
33
31
  var BrowserInstallationException = class extends NestjsPdfException {
34
32
  code = "BROWSER_INSTALLATION_ERROR";
35
33
  };
36
- //#endregion
37
- //#region src/exceptions/browser-unavailable.exception.ts
34
+ // src/exceptions/browser-unavailable.exception.ts
38
35
  var BrowserUnavailableException = class extends NestjsPdfException {
39
36
  code = "BROWSER_UNAVAILABLE";
40
37
  };
41
- //#endregion
42
- //#region src/exceptions/engine-not-available.exception.ts
38
+ // src/exceptions/engine-not-available.exception.ts
43
39
  var EngineNotAvailableException = class extends NestjsPdfException {
44
40
  code = "ENGINE_NOT_AVAILABLE";
45
41
  constructor(engineName, packageName, options) {
46
42
  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);
47
43
  }
48
44
  };
49
- //#endregion
50
- //#region src/exceptions/pdf-generation.exception.ts
45
+ // src/exceptions/pdf-generation.exception.ts
51
46
  var PdfGenerationException = class extends NestjsPdfException {
52
47
  code = "PDF_GENERATION_ERROR";
53
48
  };
54
- //#endregion
55
- //#region src/exceptions/signature-dependency.exception.ts
49
+ // src/exceptions/renderer-configuration.exception.ts
50
+ /** The PDF provider is misconfigured, or asked for an option it does not support. */
51
+ var RendererConfigurationException = class extends NestjsPdfException {
52
+ code = "RENDERER_CONFIGURATION_ERROR";
53
+ };
54
+ // src/exceptions/signature-dependency.exception.ts
56
55
  var SignatureDependencyException = class extends NestjsPdfException {
57
56
  code = "SIGNATURE_DEPENDENCY_ERROR";
58
57
  };
59
- //#endregion
60
- //#region src/exceptions/signature-placement.exception.ts
58
+ // src/exceptions/signature-placement.exception.ts
61
59
  var SignaturePlacementException = class extends NestjsPdfException {
62
60
  code = "SIGNATURE_PLACEMENT_ERROR";
63
61
  };
64
- //#endregion
65
- //#region src/exceptions/template-configuration.exception.ts
62
+ // src/exceptions/template-configuration.exception.ts
66
63
  var TemplateConfigurationException = class extends NestjsPdfException {
67
64
  code = "TEMPLATE_CONFIGURATION_ERROR";
68
65
  };
69
- //#endregion
70
- //#region src/exceptions/template-render.exception.ts
66
+ // src/exceptions/template-render.exception.ts
71
67
  var TemplateRenderException = class extends NestjsPdfException {
72
68
  engine;
73
69
  code = "TEMPLATE_RENDER_ERROR";
@@ -76,13 +72,11 @@ var TemplateRenderException = class extends NestjsPdfException {
76
72
  this.engine = engine;
77
73
  }
78
74
  };
79
- //#endregion
80
- //#region src/exceptions/watermark.exception.ts
75
+ // src/exceptions/watermark.exception.ts
81
76
  var WatermarkException = class extends NestjsPdfException {
82
77
  code = "WATERMARK_ERROR";
83
78
  };
84
- //#endregion
85
- //#region src/helpers/getRelativePath.helper.ts
79
+ // src/helpers/getRelativePath.helper.ts
86
80
  /**
87
81
  * Get the relative path to a value from the module directory.
88
82
  * @param moduleDir the path of the module, typically __dirname
@@ -96,8 +90,7 @@ function getRelativePathToValue(moduleDir, relativeToModule) {
96
90
  const fullTemplatePath = resolve(moduleDir, relativeToModule);
97
91
  return relative(process.cwd(), fullTemplatePath);
98
92
  }
99
- //#endregion
100
- //#region src/helpers/signature.helper.ts
93
+ // src/helpers/signature.helper.ts
101
94
  let pdfjsPromise;
102
95
  async function loadPdfjs() {
103
96
  if (!pdfjsPromise) try {
@@ -240,8 +233,7 @@ async function addSignatureFieldUsingAnchor(pdf, fieldName = "SignatureDebtor",
240
233
  }
241
234
  return await pdfDoc.save();
242
235
  }
243
- //#endregion
244
- //#region src/helpers/watermark.helper.ts
236
+ // src/helpers/watermark.helper.ts
245
237
  const DEFAULT_OPACITY = .15;
246
238
  const DEFAULT_ROTATION = 45;
247
239
  const DEFAULT_FONT_SIZE = 60;
@@ -384,8 +376,7 @@ async function addWatermark(pdf, options) {
384
376
  throw new WatermarkException(`Failed to add watermark: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
385
377
  }
386
378
  }
387
- //#endregion
388
- //#region node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
379
+ // node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
389
380
  var Node = class {
390
381
  value;
391
382
  next;
@@ -442,8 +433,7 @@ var Queue = class {
442
433
  while (this.#head) yield this.dequeue();
443
434
  }
444
435
  };
445
- //#endregion
446
- //#region node_modules/.pnpm/p-limit@7.3.3/node_modules/p-limit/index.js
436
+ // node_modules/.pnpm/p-limit@7.3.3/node_modules/p-limit/index.js
447
437
  function pLimit(concurrency) {
448
438
  let rejectOnClear = false;
449
439
  if (typeof concurrency === "object") ({concurrency, rejectOnClear = false} = concurrency);
@@ -521,14 +511,296 @@ function pLimit(concurrency) {
521
511
  function validateConcurrency(concurrency) {
522
512
  if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) throw new TypeError("Expected `concurrency` to be a number from 1 and up");
523
513
  }
524
- //#endregion
525
- //#region src/helpers/deepMergePdfparams.ts
514
+ // src/helpers/deepMergePdfparams.ts
526
515
  function mergePuppeteerParameters(defaults, overrides) {
527
516
  if (!overrides) return { ...defaults };
528
517
  return deepmerge(defaults, overrides);
529
518
  }
530
- //#endregion
531
- //#region src/helpers/request-guard.helper.ts
519
+ // src/helpers/tokens.ts
520
+ const PDF_PARAMETERS = "PDF_PARAMETERS";
521
+ // src/renderers/pdf-renderer.interface.ts
522
+ const PDF_RENDERER = "PDF_RENDERER";
523
+ // src/renderers/http.utils.ts
524
+ const MAX_ERROR_BODY_LENGTH = 500;
525
+ /** Builds a `PdfGenerationException` from a failed HTTP response, body included. */
526
+ async function httpError(provider, response) {
527
+ let body = "";
528
+ try {
529
+ body = (await response.text()).trim().slice(0, MAX_ERROR_BODY_LENGTH);
530
+ } catch {}
531
+ return new PdfGenerationException(`${provider} responded with HTTP ${response.status}${body ? `: ${body}` : ""}`);
532
+ }
533
+ /** Remote providers render on another machine: the local request guard cannot run there. */
534
+ function assertNoRequestGuard(provider, options, hint) {
535
+ if (options.security) throw new RendererConfigurationException(`The 'security' option is only supported by the puppeteer provider, not by ${provider}. ${hint}`);
536
+ }
537
+ function requireNonEmpty(value, name, provider) {
538
+ if (!value?.trim()) throw new RendererConfigurationException(`The ${provider} provider requires a non-empty '${name}'`);
539
+ return value;
540
+ }
541
+ // src/renderers/pdf-options.mapper.ts
542
+ /** Paper sizes in inches, as Puppeteer defines them. */
543
+ const PAPER_FORMATS = {
544
+ letter: {
545
+ width: 8.5,
546
+ height: 11
547
+ },
548
+ legal: {
549
+ width: 8.5,
550
+ height: 14
551
+ },
552
+ tabloid: {
553
+ width: 11,
554
+ height: 17
555
+ },
556
+ ledger: {
557
+ width: 17,
558
+ height: 11
559
+ },
560
+ a0: {
561
+ width: 33.1102,
562
+ height: 46.811
563
+ },
564
+ a1: {
565
+ width: 23.3858,
566
+ height: 33.1102
567
+ },
568
+ a2: {
569
+ width: 16.5354,
570
+ height: 23.3858
571
+ },
572
+ a3: {
573
+ width: 11.6929,
574
+ height: 16.5354
575
+ },
576
+ a4: {
577
+ width: 8.2677,
578
+ height: 11.6929
579
+ },
580
+ a5: {
581
+ width: 5.8268,
582
+ height: 8.2677
583
+ },
584
+ a6: {
585
+ width: 4.1339,
586
+ height: 5.8268
587
+ }
588
+ };
589
+ const INCHES_PER_UNIT = {
590
+ px: 1 / 96,
591
+ in: 1,
592
+ cm: 1 / 2.54,
593
+ mm: 1 / 25.4
594
+ };
595
+ /**
596
+ * Converts a Puppeteer length (a number of pixels, or a string with a
597
+ * `px`/`in`/`cm`/`mm` unit) to inches.
598
+ */
599
+ function toInches(value) {
600
+ if (typeof value === "number") return value * INCHES_PER_UNIT.px;
601
+ const match = /^\s*(-?\d*\.?\d+)\s*(px|in|cm|mm)?\s*$/i.exec(value);
602
+ if (!match) throw new RendererConfigurationException(`Invalid length '${value}': expected a number of pixels or a value in px, in, cm or mm`);
603
+ const unit = (match[2] ?? "px").toLowerCase();
604
+ return Number(match[1]) * INCHES_PER_UNIT[unit];
605
+ }
606
+ function formatInches(inches) {
607
+ return String(Math.round(inches * 1e4) / 1e4);
608
+ }
609
+ function resolvePrintLayout(pdfOptions) {
610
+ let width;
611
+ let height;
612
+ if (pdfOptions.width !== void 0 || pdfOptions.height !== void 0) {
613
+ const fallback = PAPER_FORMATS.letter;
614
+ width = pdfOptions.width === void 0 ? fallback.width : toInches(pdfOptions.width);
615
+ height = pdfOptions.height === void 0 ? fallback.height : toInches(pdfOptions.height);
616
+ } else {
617
+ const formatName = (pdfOptions.format ?? "letter").toLowerCase();
618
+ const format = PAPER_FORMATS[formatName];
619
+ if (!format) throw new RendererConfigurationException(`Unknown paper format '${pdfOptions.format}'`);
620
+ ({width, height} = format);
621
+ }
622
+ const margin = {};
623
+ for (const side of [
624
+ "top",
625
+ "right",
626
+ "bottom",
627
+ "left"
628
+ ]) {
629
+ const value = pdfOptions.margin?.[side];
630
+ if (value !== void 0) margin[side] = toInches(value);
631
+ }
632
+ return {
633
+ width,
634
+ height,
635
+ margin
636
+ };
637
+ }
638
+ function toHtmlDocument(template) {
639
+ return /<html[\s>]/i.test(template) ? template : `<!DOCTYPE html><html><head></head><body>${template}</body></html>`;
640
+ }
641
+ function toGotenbergForm(pdfOptions) {
642
+ const { width, height, margin } = resolvePrintLayout(pdfOptions);
643
+ const fields = {
644
+ paperWidth: formatInches(width),
645
+ paperHeight: formatInches(height),
646
+ marginTop: formatInches(margin.top ?? 0),
647
+ marginRight: formatInches(margin.right ?? 0),
648
+ marginBottom: formatInches(margin.bottom ?? 0),
649
+ marginLeft: formatInches(margin.left ?? 0),
650
+ emulatedMediaType: "screen",
651
+ skipNetworkIdleEvent: "false"
652
+ };
653
+ if (pdfOptions.landscape !== void 0) fields.landscape = String(pdfOptions.landscape);
654
+ if (pdfOptions.printBackground !== void 0) fields.printBackground = String(pdfOptions.printBackground);
655
+ if (pdfOptions.omitBackground !== void 0) fields.omitBackground = String(pdfOptions.omitBackground);
656
+ if (pdfOptions.scale !== void 0) fields.scale = String(pdfOptions.scale);
657
+ if (pdfOptions.pageRanges) fields.nativePageRanges = pdfOptions.pageRanges;
658
+ if (pdfOptions.preferCSSPageSize !== void 0) fields.preferCssPageSize = String(pdfOptions.preferCSSPageSize);
659
+ if (pdfOptions.tagged !== void 0) fields.generateTaggedPdf = String(pdfOptions.tagged);
660
+ if (pdfOptions.outline !== void 0) fields.generateDocumentOutline = String(pdfOptions.outline);
661
+ const files = {};
662
+ if (pdfOptions.displayHeaderFooter) {
663
+ if (pdfOptions.headerTemplate) files["header.html"] = toHtmlDocument(pdfOptions.headerTemplate);
664
+ if (pdfOptions.footerTemplate) files["footer.html"] = toHtmlDocument(pdfOptions.footerTemplate);
665
+ }
666
+ return {
667
+ fields,
668
+ files
669
+ };
670
+ }
671
+ function toApi2PdfOptions(pdfOptions) {
672
+ const { width, height, margin } = resolvePrintLayout(pdfOptions);
673
+ const options = {
674
+ width: `${formatInches(width)}in`,
675
+ height: `${formatInches(height)}in`,
676
+ marginTop: `${formatInches(margin.top ?? 0)}in`,
677
+ marginRight: `${formatInches(margin.right ?? 0)}in`,
678
+ marginBottom: `${formatInches(margin.bottom ?? 0)}in`,
679
+ marginLeft: `${formatInches(margin.left ?? 0)}in`,
680
+ usePrintCss: false
681
+ };
682
+ for (const key of [
683
+ "landscape",
684
+ "printBackground",
685
+ "omitBackground",
686
+ "scale",
687
+ "pageRanges",
688
+ "displayHeaderFooter",
689
+ "headerTemplate",
690
+ "footerTemplate"
691
+ ]) if (pdfOptions[key] !== void 0) options[key] = pdfOptions[key];
692
+ return options;
693
+ }
694
+ // src/renderers/api2pdf.renderer.ts
695
+ const PROVIDER$1 = "Api2Pdf";
696
+ const DEFAULT_BASE_URL = "https://v2.api2pdf.com";
697
+ const ROUTE$1 = "/chrome/pdf/html";
698
+ function isApi2Pdf(data) {
699
+ return typeof data === "object" && data !== null && ("Success" in data || "Error" in data || "FileUrl" in data);
700
+ }
701
+ var Api2PdfRenderer = class {
702
+ #endpoint;
703
+ #headers;
704
+ constructor(provider) {
705
+ const apiKey = requireNonEmpty(provider.apiKey, "apiKey", PROVIDER$1);
706
+ const baseUrl = requireNonEmpty(provider.baseUrl ?? DEFAULT_BASE_URL, "baseUrl", PROVIDER$1).replace(/\/+$/, "");
707
+ this.#endpoint = `${baseUrl}${ROUTE$1}?outputBinary=true`;
708
+ this.#headers = {
709
+ ...provider.headers,
710
+ Authorization: apiKey,
711
+ "Content-Type": "application/json",
712
+ Accept: "application/pdf, application/json"
713
+ };
714
+ }
715
+ async render(html, options, signal) {
716
+ assertNoRequestGuard(PROVIDER$1, options, "Only render trusted HTML with a remote provider.");
717
+ const body = {
718
+ html,
719
+ inline: false,
720
+ options: {
721
+ ...toApi2PdfOptions(options.pdfOptions ?? { format: "A4" }),
722
+ ...options.api2pdfOptions?.options
723
+ }
724
+ };
725
+ if (options.api2pdfOptions?.fileName) body.fileName = options.api2pdfOptions.fileName;
726
+ const response = await fetch(this.#endpoint, {
727
+ method: "POST",
728
+ headers: this.#headers,
729
+ body: JSON.stringify(body),
730
+ signal
731
+ });
732
+ if (!response.ok) throw await httpError(PROVIDER$1, response);
733
+ if (!response.headers.get("content-type")?.includes("application/json")) return new Uint8Array(await response.arrayBuffer());
734
+ const result = await response.json();
735
+ if (!isApi2Pdf(result)) throw new PdfGenerationException(`${PROVIDER$1} returned an unexpected response: ${JSON.stringify(result)}`);
736
+ if (result.Success === false || !result.FileUrl) throw new PdfGenerationException(`${PROVIDER$1} could not generate the PDF: ${result.Error ?? "no file returned"}`);
737
+ const file = await fetch(result.FileUrl, { signal });
738
+ if (!file.ok) throw await httpError(PROVIDER$1, file);
739
+ return new Uint8Array(await file.arrayBuffer());
740
+ }
741
+ };
742
+ // src/renderers/gotenberg.renderer.ts
743
+ const PROVIDER = "Gotenberg";
744
+ const ROUTE = "/forms/chromium/convert/html";
745
+ var GotenbergRenderer = class {
746
+ #endpoint;
747
+ #headers;
748
+ constructor(provider) {
749
+ const url = requireNonEmpty(provider.url, "url", PROVIDER);
750
+ this.#endpoint = `${url.replace(/\/+$/, "")}${ROUTE}`;
751
+ this.#headers = { ...provider.headers };
752
+ if (provider.basicAuth) {
753
+ const { username, password } = provider.basicAuth;
754
+ this.#headers.Authorization = `Basic ${Buffer.from(`${username}:${password}`).toString("base64")}`;
755
+ }
756
+ }
757
+ async render(html, options, signal) {
758
+ assertNoRequestGuard(PROVIDER, options, "Restrict outbound requests on the Gotenberg server instead, with '--chromium-allow-list' / '--chromium-deny-list'.");
759
+ const { fields, files } = toGotenbergForm(options.pdfOptions ?? { format: "A4" });
760
+ const form = new FormData();
761
+ form.append("files", new Blob([html], { type: "text/html" }), "index.html");
762
+ for (const [name, content] of Object.entries(files)) form.append("files", new Blob([content], { type: "text/html" }), name);
763
+ for (const asset of options.gotenbergOptions?.assets ?? []) form.append("files", new Blob([asset.content], { type: asset.contentType ?? "application/octet-stream" }), asset.filename);
764
+ const allFields = {
765
+ ...fields,
766
+ ...options.gotenbergOptions?.formFields
767
+ };
768
+ for (const [name, value] of Object.entries(allFields)) form.append(name, value);
769
+ const response = await fetch(this.#endpoint, {
770
+ method: "POST",
771
+ headers: this.#headers,
772
+ body: form,
773
+ signal
774
+ });
775
+ if (!response.ok) throw await httpError(PROVIDER, response);
776
+ return new Uint8Array(await response.arrayBuffer());
777
+ }
778
+ };
779
+ // src/puppeteer/libs/loadPuppeteer.utils.ts
780
+ function isMissingPackage(error, packageName) {
781
+ const { code, message } = error;
782
+ return (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") && typeof message === "string" && message.includes(`'${packageName}'`);
783
+ }
784
+ /** Imports an optional peer dependency, turning "not installed" into a clear exception. */
785
+ async function loadOptional(packageName, importer) {
786
+ try {
787
+ return await importer();
788
+ } catch (error) {
789
+ if (isMissingPackage(error, packageName)) throw new EngineNotAvailableException("Puppeteer", packageName, { cause: error });
790
+ throw error;
791
+ }
792
+ }
793
+ /**
794
+ * Puppeteer is an optional peer dependency, only needed by the `puppeteer`
795
+ * provider: it is imported on first use, never when the library loads.
796
+ */
797
+ function loadPuppeteer() {
798
+ return loadOptional("puppeteer", () => import("puppeteer"));
799
+ }
800
+ function loadPuppeteerBrowsers() {
801
+ return loadOptional("@puppeteer/browsers", () => import("@puppeteer/browsers"));
802
+ }
803
+ // src/helpers/request-guard.helper.ts
532
804
  const blockedRanges = new BlockList();
533
805
  for (const [address, prefix] of [
534
806
  ["0.0.0.0", 8],
@@ -656,6 +928,7 @@ function describe(rawUrl) {
656
928
  * and closes the pop-ups a script could open to escape the filter.
657
929
  */
658
930
  async function installRequestGuard(context, page, options) {
931
+ const { TargetType } = await loadPuppeteer();
659
932
  context.on("targetcreated", (target) => {
660
933
  if (target.type() === TargetType.PAGE && target.opener()) target.page().then((popup) => popup?.close()).catch(() => void 0);
661
934
  });
@@ -675,31 +948,162 @@ async function installRequestGuard(context, page, options) {
675
948
  })().catch(() => void 0);
676
949
  });
677
950
  }
678
- //#endregion
679
- //#region src/helpers/tokens.ts
680
- const PDF_PARAMETERS = "PDF_PARAMETERS";
681
- //#endregion
682
- //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorateMetadata.js
951
+ // src/renderers/puppeteer.renderer.ts
952
+ const DEFAULT_ARGS = [
953
+ "--autoplay-policy=user-gesture-required",
954
+ "--disable-background-networking",
955
+ "--disable-background-timer-throttling",
956
+ "--disable-backgrounding-occluded-windows",
957
+ "--disable-breakpad",
958
+ "--disable-client-side-phishing-detection",
959
+ "--disable-component-update",
960
+ "--disable-default-apps",
961
+ "--disable-dev-shm-usage",
962
+ "--disable-domain-reliability",
963
+ "--disable-extensions",
964
+ "--disable-features=AudioServiceOutOfProcess",
965
+ "--disable-hang-monitor",
966
+ "--disable-ipc-flooding-protection",
967
+ "--disable-notifications",
968
+ "--disable-offer-store-unmasked-wallet-cards",
969
+ "--disable-print-preview",
970
+ "--disable-prompt-on-repost",
971
+ "--disable-renderer-backgrounding",
972
+ "--disable-setuid-sandbox",
973
+ "--disable-speech-api",
974
+ "--disable-sync",
975
+ "--hide-scrollbars",
976
+ "--ignore-gpu-blacklist",
977
+ "--metrics-recording-only",
978
+ "--mute-audio",
979
+ "--no-default-browser-check",
980
+ "--no-first-run",
981
+ "--no-pings",
982
+ "--password-store=basic",
983
+ "--use-gl=swiftshader",
984
+ "--use-mock-keychain",
985
+ "--disable-accelerated-2d-canvas",
986
+ "--no-zygote",
987
+ "--disable-gpu"
988
+ ];
989
+ const PDF_OPTION_KEYS = {
990
+ scale: true,
991
+ displayHeaderFooter: true,
992
+ headerTemplate: true,
993
+ footerTemplate: true,
994
+ printBackground: true,
995
+ landscape: true,
996
+ pageRanges: true,
997
+ format: true,
998
+ width: true,
999
+ height: true,
1000
+ preferCSSPageSize: true,
1001
+ margin: true,
1002
+ path: true,
1003
+ omitBackground: true,
1004
+ tagged: true,
1005
+ outline: true,
1006
+ timeout: true,
1007
+ waitForFonts: true
1008
+ };
1009
+ function toPuppeteerPdfOptions(options) {
1010
+ if (!options) return { format: "A4" };
1011
+ const invalidKeys = Object.keys(options).filter((key) => !Object.hasOwn(PDF_OPTION_KEYS, key));
1012
+ if (invalidKeys.length > 0) throw new RendererConfigurationException(`Invalid PDF options: ${invalidKeys.join(", ")}. Please check the documentation for valid options.`);
1013
+ return options;
1014
+ }
1015
+ var PuppeteerRenderer = class {
1016
+ #browserService;
1017
+ constructor(browserService) {
1018
+ this.#browserService = browserService;
1019
+ }
1020
+ async render(html, options, signal) {
1021
+ if (options.chromiumRevision !== void 0) Logger.warn("Using `chromiumRevision` is no longer supported since the puppeteer update.");
1022
+ const pdfOptions = toPuppeteerPdfOptions(options.pdfOptions);
1023
+ const headless = options.headless ?? true;
1024
+ const executablePath = options.executablePath || void 0;
1025
+ const args = options.extraPuppeteerArgs || DEFAULT_ARGS;
1026
+ let context = null;
1027
+ let closing;
1028
+ const onAbort = () => {
1029
+ if (!context) return;
1030
+ closing = context.close();
1031
+ closing.catch(() => void 0);
1032
+ };
1033
+ signal?.addEventListener("abort", onAbort, { once: true });
1034
+ try {
1035
+ context = await this.#browserService.createContext(args, headless, executablePath);
1036
+ signal?.throwIfAborted();
1037
+ const page = await context.newPage();
1038
+ if (options.security) await installRequestGuard(context, page, options.security);
1039
+ await page.setContent(html, { waitUntil: "domcontentloaded" });
1040
+ await page.emulateMediaType("screen");
1041
+ await page.waitForNetworkIdle({
1042
+ idleTime: 500,
1043
+ timeout: 3e4
1044
+ });
1045
+ /* v8 ignore next */
1046
+ await page.evaluate(() => document.fonts.ready);
1047
+ return await page.pdf(pdfOptions);
1048
+ } finally {
1049
+ signal?.removeEventListener("abort", onAbort);
1050
+ if (context) try {
1051
+ if (closing) await closing;
1052
+ else await context.close();
1053
+ } catch (error) {
1054
+ Logger.error(error);
1055
+ }
1056
+ }
1057
+ }
1058
+ };
1059
+ // src/renderers/create-renderer.ts
1060
+ /** True when the PDFs are printed by the local Chromium (the default). */
1061
+ function usesPuppeteer(params) {
1062
+ return (params.provider?.type ?? "puppeteer") === "puppeteer";
1063
+ }
1064
+ function createPdfRenderer(params, browserService) {
1065
+ const provider = params.provider ?? { type: "puppeteer" };
1066
+ switch (provider.type) {
1067
+ case "puppeteer": return new PuppeteerRenderer(browserService);
1068
+ case "gotenberg": return new GotenbergRenderer(provider);
1069
+ case "api2pdf": return new Api2PdfRenderer(provider);
1070
+ default: throw new RendererConfigurationException(`Unknown PDF provider '${String(provider.type)}': expected 'puppeteer', 'gotenberg' or 'api2pdf'`);
1071
+ }
1072
+ }
1073
+ // src/puppeteer/libs/enum.utils.ts
1074
+ /**
1075
+ * Converts a string value to an enum member, throwing a RendererConfigurationException if the value is not a valid member of the enum.
1076
+ * @param enumObject
1077
+ * @param value
1078
+ * @param label
1079
+ * @throws RendererConfigurationException
1080
+ */
1081
+ function toEnumMember(enumObject, value, label) {
1082
+ const members = Object.values(enumObject);
1083
+ const isMember = (candidate) => candidate === value;
1084
+ const member = members.find(isMember);
1085
+ if (member === void 0) throw new RendererConfigurationException(`Unsupported ${label} '${value}': expected one of ${members.map((m) => `'${m}'`).join(", ")}`);
1086
+ return member;
1087
+ }
1088
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/decorateMetadata.js
683
1089
  function __decorateMetadata(k, v) {
684
1090
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
685
1091
  }
686
- //#endregion
687
- //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorateParam.js
1092
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/decorateParam.js
688
1093
  function __decorateParam(paramIndex, decorator) {
689
1094
  return function(target, key) {
690
1095
  decorator(target, key, paramIndex);
691
1096
  };
692
1097
  }
693
- //#endregion
694
- //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorate.js
1098
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/decorate.js
695
1099
  function __decorate(decorators, target, key, desc) {
696
1100
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
697
1101
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
698
1102
  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;
699
1103
  return c > 3 && r && Object.defineProperty(target, key, r), r;
700
1104
  }
701
- //#endregion
702
- //#region src/puppeteer/browser/browser.service.ts
1105
+ // src/puppeteer/browser/browser.service.ts
1106
+ const DEFAULT_BROWSER = "chromium";
703
1107
  async function sleep(ms) {
704
1108
  await new Promise((r) => setTimeout(r, ms));
705
1109
  }
@@ -751,7 +1155,7 @@ let BrowserService = class BrowserService {
751
1155
  } catch (error) {
752
1156
  Logger.warn(`Failed to close browser on module destroy: ${error instanceof Error ? error.message : String(error)}`);
753
1157
  }
754
- if (this.#options?.cleanupBrowserCacheOnExit !== false) await this.#cleanupCacheBestEffort();
1158
+ if (this.#options !== void 0 && usesPuppeteer(this.#options) && this.#options.cleanupBrowserCacheOnExit !== false) await this.#cleanupCacheBestEffort();
755
1159
  }
756
1160
  /** Wait until no PDF job is in flight, or until the timeout elapses. */
757
1161
  async #waitForIdle(timeoutMs) {
@@ -833,7 +1237,8 @@ let BrowserService = class BrowserService {
833
1237
  }
834
1238
  }
835
1239
  async #doInstall(lock) {
836
- const browser = this.#browser;
1240
+ const { Browser: BrowserEnum, BrowserPlatform, canDownload, detectBrowserPlatform, install, resolveBuildId } = await loadPuppeteerBrowsers();
1241
+ const browser = toEnumMember(BrowserEnum, this.#browser, "browser");
837
1242
  const versionTag = this.#browserTag;
838
1243
  const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;
839
1244
  let buildId;
@@ -865,10 +1270,7 @@ let BrowserService = class BrowserService {
865
1270
  return null;
866
1271
  }
867
1272
  #loadBrowser() {
868
- let browser;
869
- if (this.#options?.browser === void 0) browser = Browser$1.CHROMIUM;
870
- else browser = this.#options.browser;
871
- this.#browser = browser;
1273
+ this.#browser = this.#options?.browser ?? DEFAULT_BROWSER;
872
1274
  }
873
1275
  getBrowser() {
874
1276
  return this.#browser;
@@ -876,7 +1278,7 @@ let BrowserService = class BrowserService {
876
1278
  #loadBrowserTag() {
877
1279
  let versionTag;
878
1280
  if (this.#options?.browserTag === void 0) {
879
- if (this.#browser === Browser$1.CHROMIUM) versionTag = "latest";
1281
+ if (this.#browser === DEFAULT_BROWSER) versionTag = "latest";
880
1282
  else versionTag = "stable";
881
1283
  } else versionTag = this.#options.browserTag;
882
1284
  this.#browserTag = versionTag;
@@ -903,12 +1305,15 @@ let BrowserService = class BrowserService {
903
1305
  this.#useLockedBrowser = useLockedBrowser;
904
1306
  }
905
1307
  async hasBrowserInstalled(browser, buildId) {
1308
+ const { Browser: BrowserEnum, getInstalledBrowsers } = await loadPuppeteerBrowsers();
1309
+ const expected = toEnumMember(BrowserEnum, browser, "browser");
906
1310
  return (await getInstalledBrowsers({ cacheDir: this.#cacheDir })).find((insBrowser) => {
907
- return insBrowser.browser === browser && insBrowser.buildId === buildId;
1311
+ return insBrowser.browser === expected && insBrowser.buildId === buildId;
908
1312
  }) !== void 0;
909
1313
  }
910
1314
  async getExecutablePath() {
911
- const browser = this.#browser;
1315
+ const { Browser: BrowserEnum, BrowserPlatform, detectBrowserPlatform, getInstalledBrowsers, resolveBuildId } = await loadPuppeteerBrowsers();
1316
+ const browser = toEnumMember(BrowserEnum, this.#browser, "browser");
912
1317
  const versionTag = this.#browserTag;
913
1318
  const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;
914
1319
  let buildId = null;
@@ -929,6 +1334,7 @@ let BrowserService = class BrowserService {
929
1334
  }
930
1335
  async #launchBrowser(args, headless, executablePathBin) {
931
1336
  const executablePath = executablePathBin ?? await this.getExecutablePath();
1337
+ const { launch } = await loadPuppeteer();
932
1338
  const browser = await launch({
933
1339
  executablePath,
934
1340
  headless,
@@ -965,8 +1371,7 @@ BrowserService = __decorate([
965
1371
  __decorateParam(0, Inject("PDF_PARAMETERS")),
966
1372
  __decorateMetadata("design:paramtypes", [Object])
967
1373
  ], BrowserService);
968
- //#endregion
969
- //#region src/puppeteer/libs/loadEngine.utils.ts
1374
+ // src/puppeteer/libs/loadEngine.utils.ts
970
1375
  const requireEngine = createRequire(import.meta.url);
971
1376
  /**
972
1377
  * Load an optional template engine on first use, so the library can be imported
@@ -983,8 +1388,7 @@ function loadEngine(packageName, engineName) {
983
1388
  }
984
1389
  return mod.__esModule && "default" in mod ? mod.default : mod;
985
1390
  }
986
- //#endregion
987
- //#region src/puppeteer/engines/ejs/ejs.service.ts
1391
+ // src/puppeteer/engines/ejs/ejs.service.ts
988
1392
  let EjsService = class EjsService {
989
1393
  #ejs;
990
1394
  get #engine() {
@@ -1014,8 +1418,7 @@ let EjsService = class EjsService {
1014
1418
  }
1015
1419
  };
1016
1420
  EjsService = __decorate([Injectable()], EjsService);
1017
- //#endregion
1018
- //#region src/puppeteer/engines/eta/eta.service.ts
1421
+ // src/puppeteer/engines/eta/eta.service.ts
1019
1422
  let EtaService = class EtaService {
1020
1423
  #etaModule;
1021
1424
  #eta;
@@ -1086,8 +1489,7 @@ let EtaService = class EtaService {
1086
1489
  }
1087
1490
  };
1088
1491
  EtaService = __decorate([Injectable()], EtaService);
1089
- //#endregion
1090
- //#region src/puppeteer/engines/handlebars/handlebars.service.ts
1492
+ // src/puppeteer/engines/handlebars/handlebars.service.ts
1091
1493
  let HandlebarsService = class HandlebarsService {
1092
1494
  #handlebars;
1093
1495
  #cachedOptions;
@@ -1142,8 +1544,7 @@ let HandlebarsService = class HandlebarsService {
1142
1544
  }
1143
1545
  };
1144
1546
  HandlebarsService = __decorate([Injectable()], HandlebarsService);
1145
- //#endregion
1146
- //#region src/puppeteer/engines/liquid/liquid.service.ts
1547
+ // src/puppeteer/engines/liquid/liquid.service.ts
1147
1548
  let LiquidService = class LiquidService {
1148
1549
  #liquidModule;
1149
1550
  #liquid;
@@ -1204,8 +1605,7 @@ let LiquidService = class LiquidService {
1204
1605
  }
1205
1606
  };
1206
1607
  LiquidService = __decorate([Injectable()], LiquidService);
1207
- //#endregion
1208
- //#region src/puppeteer/engines/mjml/mjml.service.ts
1608
+ // src/puppeteer/engines/mjml/mjml.service.ts
1209
1609
  let MjmlService = class MjmlService {
1210
1610
  #mjml;
1211
1611
  get #engine() {
@@ -1231,8 +1631,7 @@ let MjmlService = class MjmlService {
1231
1631
  }
1232
1632
  };
1233
1633
  MjmlService = __decorate([Injectable()], MjmlService);
1234
- //#endregion
1235
- //#region src/puppeteer/engines/mustache/mustache.service.ts
1634
+ // src/puppeteer/engines/mustache/mustache.service.ts
1236
1635
  let MustacheService = class MustacheService {
1237
1636
  #mustache;
1238
1637
  #templateCache = /* @__PURE__ */ new Map();
@@ -1295,8 +1694,7 @@ let MustacheService = class MustacheService {
1295
1694
  }
1296
1695
  };
1297
1696
  MustacheService = __decorate([Injectable()], MustacheService);
1298
- //#endregion
1299
- //#region src/puppeteer/engines/nunjucks/nunjucks.service.ts
1697
+ // src/puppeteer/engines/nunjucks/nunjucks.service.ts
1300
1698
  let NunjucksService = class NunjucksService {
1301
1699
  #nunjucks;
1302
1700
  get #engine() {
@@ -1348,8 +1746,7 @@ let NunjucksService = class NunjucksService {
1348
1746
  }
1349
1747
  };
1350
1748
  NunjucksService = __decorate([Injectable()], NunjucksService);
1351
- //#endregion
1352
- //#region src/puppeteer/engines/pug/pug.service.ts
1749
+ // src/puppeteer/engines/pug/pug.service.ts
1353
1750
  let PugService = class PugService {
1354
1751
  #pug;
1355
1752
  get #engine() {
@@ -1374,16 +1771,15 @@ let PugService = class PugService {
1374
1771
  }
1375
1772
  };
1376
1773
  PugService = __decorate([Injectable()], PugService);
1377
- //#endregion
1378
- //#region src/puppeteer/libs/requireService.utils.ts
1774
+ // src/puppeteer/libs/requireService.utils.ts
1379
1775
  function requireService(service, name) {
1380
1776
  if (!service) throw new EngineNotAvailableException(name);
1381
1777
  return service;
1382
1778
  }
1383
- //#endregion
1384
- //#region src/puppeteer/puppeteer.service.ts
1779
+ // src/puppeteer/puppeteer.service.ts
1385
1780
  let PuppeteerService = class PuppeteerService {
1386
- #browserService;
1781
+ #renderer;
1782
+ #jobs;
1387
1783
  #options;
1388
1784
  #hbsService;
1389
1785
  #mjmlService;
@@ -1393,8 +1789,9 @@ let PuppeteerService = class PuppeteerService {
1393
1789
  #etaService;
1394
1790
  #mustacheService;
1395
1791
  #liquidService;
1396
- constructor(browserService, options, hbsService, mjmlService, pugService, ejsService, nunjucksService, etaService, mustacheService, liquidService) {
1397
- this.#browserService = browserService;
1792
+ constructor(renderer, jobs, options, hbsService, mjmlService, pugService, ejsService, nunjucksService, etaService, mustacheService, liquidService) {
1793
+ this.#renderer = renderer;
1794
+ this.#jobs = jobs;
1398
1795
  this.#options = options;
1399
1796
  this.#hbsService = hbsService;
1400
1797
  this.#mjmlService = mjmlService;
@@ -1413,87 +1810,19 @@ let PuppeteerService = class PuppeteerService {
1413
1810
  const job = this.#limit(async () => {
1414
1811
  signal?.throwIfAborted();
1415
1812
  started = true;
1416
- const mergePuppeteerOptions = mergePuppeteerParameters(this.#options, options);
1417
- if (mergePuppeteerOptions.chromiumRevision !== void 0) Logger.warn("Using `chromiumRevision` is no longer supported since the puppeteer update.");
1418
- const headless = mergePuppeteerOptions.headless ?? true;
1419
- const executablePath = mergePuppeteerOptions.executablePath || void 0;
1420
- const args = mergePuppeteerOptions.extraPuppeteerArgs || [
1421
- "--autoplay-policy=user-gesture-required",
1422
- "--disable-background-networking",
1423
- "--disable-background-timer-throttling",
1424
- "--disable-backgrounding-occluded-windows",
1425
- "--disable-breakpad",
1426
- "--disable-client-side-phishing-detection",
1427
- "--disable-component-update",
1428
- "--disable-default-apps",
1429
- "--disable-dev-shm-usage",
1430
- "--disable-domain-reliability",
1431
- "--disable-extensions",
1432
- "--disable-features=AudioServiceOutOfProcess",
1433
- "--disable-hang-monitor",
1434
- "--disable-ipc-flooding-protection",
1435
- "--disable-notifications",
1436
- "--disable-offer-store-unmasked-wallet-cards",
1437
- "--disable-print-preview",
1438
- "--disable-prompt-on-repost",
1439
- "--disable-renderer-backgrounding",
1440
- "--disable-setuid-sandbox",
1441
- "--disable-speech-api",
1442
- "--disable-sync",
1443
- "--hide-scrollbars",
1444
- "--ignore-gpu-blacklist",
1445
- "--metrics-recording-only",
1446
- "--mute-audio",
1447
- "--no-default-browser-check",
1448
- "--no-first-run",
1449
- "--no-pings",
1450
- "--password-store=basic",
1451
- "--use-gl=swiftshader",
1452
- "--use-mock-keychain",
1453
- "--disable-accelerated-2d-canvas",
1454
- "--no-zygote",
1455
- "--disable-gpu"
1456
- ];
1457
- this.#browserService.markJobStarted();
1458
- let context = null;
1459
- let closing;
1460
- const onAbort = () => {
1461
- if (!context) return;
1462
- closing = context.close();
1463
- closing.catch(() => void 0);
1464
- };
1465
- signal?.addEventListener("abort", onAbort, { once: true });
1813
+ const mergedOptions = mergePuppeteerParameters(this.#options, options);
1814
+ this.#jobs.markJobStarted();
1466
1815
  try {
1467
- context = await this.#browserService.createContext(args, headless, executablePath);
1468
- signal?.throwIfAborted();
1469
- const page = await context.newPage();
1470
- if (mergePuppeteerOptions.security) await installRequestGuard(context, page, mergePuppeteerOptions.security);
1471
- const pdfOptions = mergePuppeteerOptions.pdfOptions ?? { format: "A4" };
1472
- await page.setContent(html, { waitUntil: "domcontentloaded" });
1473
- await page.emulateMediaType("screen");
1474
- await page.waitForNetworkIdle({
1475
- idleTime: 500,
1476
- timeout: 3e4
1477
- });
1478
- /* v8 ignore next */
1479
- await page.evaluate(() => document.fonts.ready);
1480
- const pdf = await page.pdf(pdfOptions);
1816
+ const pdf = await this.#renderer.render(html, mergedOptions, signal);
1481
1817
  signal?.throwIfAborted();
1482
- return mergePuppeteerOptions.watermark ? await addWatermark(pdf, mergePuppeteerOptions.watermark) : pdf;
1818
+ return mergedOptions.watermark ? await addWatermark(pdf, mergedOptions.watermark) : pdf;
1483
1819
  } catch (e) {
1484
1820
  if (signal?.aborted) throw signal.reason;
1485
1821
  Logger.error(e);
1486
1822
  if (e instanceof NestjsPdfException) throw e;
1487
1823
  throw new PdfGenerationException(`PDF generation failed: ${String(e)}`, { cause: e });
1488
1824
  } finally {
1489
- signal?.removeEventListener("abort", onAbort);
1490
- if (context) try {
1491
- if (closing) await closing;
1492
- else await context.close();
1493
- } catch (error) {
1494
- Logger.error(error);
1495
- }
1496
- await this.#browserService.markJobFinished();
1825
+ await this.#jobs.markJobFinished();
1497
1826
  }
1498
1827
  });
1499
1828
  if (!signal) return job;
@@ -1577,8 +1906,9 @@ let PuppeteerService = class PuppeteerService {
1577
1906
  };
1578
1907
  PuppeteerService = __decorate([
1579
1908
  Injectable(),
1580
- __decorateParam(1, Inject(PDF_PARAMETERS)),
1581
- __decorateParam(2, Optional()),
1909
+ __decorateParam(0, Inject(PDF_RENDERER)),
1910
+ __decorateParam(1, Inject(BrowserService)),
1911
+ __decorateParam(2, Inject(PDF_PARAMETERS)),
1582
1912
  __decorateParam(3, Optional()),
1583
1913
  __decorateParam(4, Optional()),
1584
1914
  __decorateParam(5, Optional()),
@@ -1586,8 +1916,10 @@ PuppeteerService = __decorate([
1586
1916
  __decorateParam(7, Optional()),
1587
1917
  __decorateParam(8, Optional()),
1588
1918
  __decorateParam(9, Optional()),
1919
+ __decorateParam(10, Optional()),
1589
1920
  __decorateMetadata("design:paramtypes", [
1590
- typeof BrowserService === "undefined" ? Object : BrowserService,
1921
+ Object,
1922
+ Object,
1591
1923
  Object,
1592
1924
  typeof HandlebarsService === "undefined" ? Object : HandlebarsService,
1593
1925
  typeof MjmlService === "undefined" ? Object : MjmlService,
@@ -1599,8 +1931,7 @@ PuppeteerService = __decorate([
1599
1931
  typeof LiquidService === "undefined" ? Object : LiquidService
1600
1932
  ])
1601
1933
  ], PuppeteerService);
1602
- //#endregion
1603
- //#region src/nestjs-pdf.service.ts
1934
+ // src/nestjs-pdf.service.ts
1604
1935
  let NestjsPdfService = class NestjsPdfService {
1605
1936
  #puppeteerService;
1606
1937
  constructor(puppeteerService) {
@@ -1820,9 +2151,14 @@ let NestjsPdfService = class NestjsPdfService {
1820
2151
  }
1821
2152
  };
1822
2153
  NestjsPdfService = __decorate([Injectable(), __decorateMetadata("design:paramtypes", [typeof PuppeteerService === "undefined" ? Object : PuppeteerService])], NestjsPdfService);
1823
- //#endregion
1824
- //#region src/puppeteer/puppeteer.module.ts
2154
+ // src/puppeteer/puppeteer.module.ts
1825
2155
  var _PuppeteerModule;
2156
+ /** Builds the renderer of the configured provider, once the parameters are known. */
2157
+ const pdfRendererProvider = {
2158
+ provide: PDF_RENDERER,
2159
+ inject: [PDF_PARAMETERS, BrowserService],
2160
+ useFactory: createPdfRenderer
2161
+ };
1826
2162
  let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
1827
2163
  #browserService;
1828
2164
  #pdfParams;
@@ -1831,7 +2167,12 @@ let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
1831
2167
  this.#pdfParams = pdfParams;
1832
2168
  }
1833
2169
  async onModuleInit() {
1834
- if (!this.#pdfParams.executablePath) await this.#browserService.install(this.#pdfParams.useLockedBrowser ?? false);
2170
+ if (!usesPuppeteer(this.#pdfParams)) return;
2171
+ await loadPuppeteer();
2172
+ if (!this.#pdfParams.executablePath) {
2173
+ await loadPuppeteerBrowsers();
2174
+ await this.#browserService.install(this.#pdfParams.useLockedBrowser ?? false);
2175
+ }
1835
2176
  }
1836
2177
  static forRoot(pdfParameters) {
1837
2178
  return {
@@ -1875,6 +2216,7 @@ let PuppeteerModule = _PuppeteerModule = class PuppeteerModule {
1875
2216
  pdfParamsProvider,
1876
2217
  PuppeteerService,
1877
2218
  BrowserService,
2219
+ pdfRendererProvider,
1878
2220
  HandlebarsService,
1879
2221
  MjmlService,
1880
2222
  PugService,
@@ -1902,6 +2244,7 @@ PuppeteerModule = _PuppeteerModule = __decorate([
1902
2244
  providers: [
1903
2245
  PuppeteerService,
1904
2246
  BrowserService,
2247
+ pdfRendererProvider,
1905
2248
  MjmlService,
1906
2249
  PugService,
1907
2250
  EjsService,
@@ -1921,11 +2264,11 @@ PuppeteerModule = _PuppeteerModule = __decorate([
1921
2264
  LiquidService
1922
2265
  ]
1923
2266
  }),
2267
+ __decorateParam(0, Inject(BrowserService)),
1924
2268
  __decorateParam(1, Inject(PDF_PARAMETERS)),
1925
- __decorateMetadata("design:paramtypes", [typeof BrowserService === "undefined" ? Object : BrowserService, Object])
2269
+ __decorateMetadata("design:paramtypes", [Object, Object])
1926
2270
  ], PuppeteerModule);
1927
- //#endregion
1928
- //#region src/nestjs-pdf.module.ts
2271
+ // src/nestjs-pdf.module.ts
1929
2272
  var _NestjsPdfModule;
1930
2273
  let NestjsPdfModule = _NestjsPdfModule = class NestjsPdfModule {
1931
2274
  static forRoot(options) {
@@ -1946,7 +2289,6 @@ let NestjsPdfModule = _NestjsPdfModule = class NestjsPdfModule {
1946
2289
  }
1947
2290
  };
1948
2291
  NestjsPdfModule = _NestjsPdfModule = __decorate([Module({})], NestjsPdfModule);
1949
- //#endregion
1950
- export { BrowserInstallationException, BrowserUnavailableException, EjsService, EngineNotAvailableException, EtaService, HandlebarsService, LiquidService, MjmlService, MustacheService, NestjsPdfErrorCode, NestjsPdfException, NestjsPdfModule, NestjsPdfService, NunjucksService, PdfGenerationException, PugService, PuppeteerModule, PuppeteerService, SignatureDependencyException, SignaturePlacementException, TemplateConfigurationException, TemplateRenderException, WatermarkException, getRelativePathToValue };
2292
+ export { BrowserInstallationException, BrowserUnavailableException, EjsService, EngineNotAvailableException, EtaService, HandlebarsService, LiquidService, MjmlService, MustacheService, NestjsPdfErrorCode, NestjsPdfException, NestjsPdfModule, NestjsPdfService, NunjucksService, PdfGenerationException, PugService, PuppeteerModule, PuppeteerService, RendererConfigurationException, SignatureDependencyException, SignaturePlacementException, TemplateConfigurationException, TemplateRenderException, WatermarkException, getRelativePathToValue };
1951
2293
 
1952
2294
  //# sourceMappingURL=index.mjs.map