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