@shad0wz7/nestjs-pdf 3.1.0 → 3.2.0

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