@shad0wz7/nestjs-pdf 3.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["BrowserType"],"sources":["../src/exceptions/nestjs-pdf.exception.ts","../src/exceptions/browser-installation.exception.ts","../src/exceptions/browser-unavailable.exception.ts","../src/exceptions/engine-not-available.exception.ts","../src/exceptions/pdf-generation.exception.ts","../src/exceptions/signature-dependency.exception.ts","../src/exceptions/signature-placement.exception.ts","../src/exceptions/template-configuration.exception.ts","../src/exceptions/template-render.exception.ts","../src/exceptions/watermark.exception.ts","../src/helpers/getRelativePath.helper.ts","../src/helpers/signature.helper.ts","../src/helpers/watermark.helper.ts","../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js","../node_modules/.pnpm/p-limit@7.3.2/node_modules/p-limit/index.js","../src/helpers/deepMergePdfparams.ts","../src/helpers/request-guard.helper.ts","../src/helpers/tokens.ts","../src/puppeteer/browser/browser.service.ts","../src/puppeteer/engines/ejs/ejs.service.ts","../src/puppeteer/engines/eta/eta.service.ts","../src/puppeteer/engines/handlebars/handlebars.service.ts","../src/puppeteer/engines/mjml/mjml.service.ts","../src/puppeteer/engines/mustache/mustache.service.ts","../src/puppeteer/engines/nunjucks/nunjucks.service.ts","../src/puppeteer/engines/pug/pug.service.ts","../src/puppeteer/libs/requireService.utils.ts","../src/puppeteer/puppeteer.service.ts","../src/nestjs-pdf.service.ts","../src/puppeteer/puppeteer.module.ts","../src/nestjs-pdf.module.ts"],"sourcesContent":["export enum NestjsPdfErrorCode {\n ENGINE_NOT_AVAILABLE = 'ENGINE_NOT_AVAILABLE',\n TEMPLATE_CONFIGURATION_ERROR = 'TEMPLATE_CONFIGURATION_ERROR',\n TEMPLATE_RENDER_ERROR = 'TEMPLATE_RENDER_ERROR',\n BROWSER_INSTALLATION_ERROR = 'BROWSER_INSTALLATION_ERROR',\n BROWSER_UNAVAILABLE = 'BROWSER_UNAVAILABLE',\n PDF_GENERATION_ERROR = 'PDF_GENERATION_ERROR',\n SIGNATURE_DEPENDENCY_ERROR = 'SIGNATURE_DEPENDENCY_ERROR',\n SIGNATURE_PLACEMENT_ERROR = 'SIGNATURE_PLACEMENT_ERROR',\n WATERMARK_ERROR = 'WATERMARK_ERROR',\n}\n\nexport abstract class NestjsPdfException extends Error {\n abstract readonly code: NestjsPdfErrorCode;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = this.constructor.name;\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class BrowserInstallationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.BROWSER_INSTALLATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class BrowserUnavailableException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.BROWSER_UNAVAILABLE;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class EngineNotAvailableException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.ENGINE_NOT_AVAILABLE;\n\n constructor(engineName: string) {\n super(\n `${engineName} service is not available. If the problem persists, open an issue in the repo.`,\n );\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class PdfGenerationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.PDF_GENERATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class SignatureDependencyException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.SIGNATURE_DEPENDENCY_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class SignaturePlacementException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.SIGNATURE_PLACEMENT_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class TemplateConfigurationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.TEMPLATE_CONFIGURATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class TemplateRenderException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.TEMPLATE_RENDER_ERROR;\n\n constructor(\n public readonly engine: string,\n message: string,\n options?: { cause?: unknown },\n ) {\n super(message, options);\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class WatermarkException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.WATERMARK_ERROR;\n}\n","import { relative, resolve } from 'node:path';\n\n/**\n * Get the relative path to a value from the module directory.\n * @param moduleDir the path of the module, typically __dirname\n * @param relativeToModule the path to the value relative to the module directory\n * @returns the relative path from the current working directory to the value\n * @example\n * getRelativePathToValue(__dirname, './templates/my-template.hbs');\n * // returns 'context/pdf/templates/my-template.hbs' if the current working directory is '/\n */\nexport function getRelativePathToValue(\n moduleDir: string,\n relativeToModule: string,\n): string {\n const fullTemplatePath = resolve(moduleDir, relativeToModule);\n return relative(process.cwd(), fullTemplatePath);\n}\n","import {\n PDFArray,\n PDFDict,\n PDFDocument,\n PDFName,\n PDFNumber,\n PDFString,\n} from 'pdf-lib';\nimport type { TextItem } from 'pdfjs-dist/types/src/display/api';\n\nimport {\n SignatureDependencyException,\n SignaturePlacementException,\n} from '../exceptions';\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet pdfjsPromise: typeof import('pdfjs-dist/legacy/build/pdf.mjs') | undefined;\n\nasync function loadPdfjs() {\n if (!pdfjsPromise) {\n try {\n pdfjsPromise = await import('pdfjs-dist/legacy/build/pdf.mjs');\n } catch (error) {\n pdfjsPromise = undefined;\n /* v8 ignore next -- import() rejections are always Error instances in practice */\n const reason = error instanceof Error ? error.message : String(error);\n throw new SignatureDependencyException(\n [\n 'Failed to load pdfjs-dist.',\n 'If you use anchor-based signature placement in Node.js, make sure @napi-rs/canvas is installed.',\n 'Try: npm install @napi-rs/canvas',\n '',\n `Original error: ${reason}`,\n ].join('\\n'),\n { cause: error },\n );\n }\n }\n return pdfjsPromise;\n}\n\nfunction toU8(input: Uint8Array | Buffer): Uint8Array {\n return new Uint8Array(input);\n}\n\nasync function findAnchorPosition(\n pdfBytes: Uint8Array,\n anchorText: string,\n): Promise<null | {\n pageIndex: number;\n x: number;\n y: number;\n pageWidth: number;\n pageHeight: number;\n}> {\n const pdfjsLib = await loadPdfjs();\n const loadingTask = pdfjsLib.getDocument({ data: pdfBytes });\n\n try {\n const pdf = await loadingTask.promise;\n\n for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\n const page = await pdf.getPage(pageNum);\n const viewport = page.getViewport({ scale: 1 });\n const textContent = await page.getTextContent();\n\n for (const itemRaw of textContent.items) {\n const item = itemRaw as TextItem;\n const str = item.str;\n if (!str?.includes(anchorText)) continue;\n\n const t = pdfjsLib.Util.transform(viewport.transform, item.transform);\n const [_a, _b, _c, _d, e, f] = t as Array<number>;\n\n const x = e;\n const y = viewport.height - f;\n\n return {\n pageIndex: pageNum - 1,\n x,\n y,\n pageWidth: viewport.width,\n pageHeight: viewport.height,\n };\n }\n }\n return null;\n } finally {\n await loadingTask.destroy();\n }\n}\n\nfunction addSignatureFieldAt(\n pdfDoc: PDFDocument,\n pageIndex: number,\n opts: {\n fieldName: string;\n x: number;\n y: number;\n width: number;\n height: number;\n },\n) {\n const { fieldName, x, y, width, height } = opts;\n const context = pdfDoc.context;\n\n const page = pdfDoc.getPages()[pageIndex];\n\n const rectArray = context.obj([\n PDFNumber.of(x),\n PDFNumber.of(y),\n PDFNumber.of(x + width),\n PDFNumber.of(y + height),\n ]);\n\n const widgetDict = context.obj({\n Type: PDFName.of('Annot'),\n Subtype: PDFName.of('Widget'),\n Rect: rectArray,\n F: PDFNumber.of(4),\n P: page.ref,\n });\n const widgetRef = context.register(widgetDict);\n\n const fieldDict = context.obj({\n FT: PDFName.of('Sig'),\n T: PDFString.of(fieldName),\n Ff: PDFNumber.of(0),\n Kids: context.obj([widgetRef]),\n });\n const fieldRef = context.register(fieldDict);\n\n widgetDict.set(PDFName.of('Parent'), fieldRef);\n\n let annots = page.node.lookupMaybe(PDFName.of('Annots'), PDFArray);\n if (!annots) {\n annots = context.obj([]);\n page.node.set(PDFName.of('Annots'), annots);\n }\n annots.push(widgetRef);\n\n let acroForm = pdfDoc.catalog.lookupMaybe(PDFName.of('AcroForm'), PDFDict);\n if (!acroForm) {\n acroForm = context.obj({\n Fields: context.obj([]),\n SigFlags: PDFNumber.of(3),\n });\n const acroFormRef = context.register(acroForm);\n pdfDoc.catalog.set(PDFName.of('AcroForm'), acroFormRef);\n }\n\n let fields = acroForm.lookupMaybe(PDFName.of('Fields'), PDFArray);\n if (!fields) {\n fields = context.obj([]);\n acroForm.set(PDFName.of('Fields'), fields);\n }\n fields.push(fieldRef);\n\n return { fieldRef, widgetRef };\n}\n\nexport async function addSignatureFieldUsingAnchor(\n pdf: Uint8Array | Buffer,\n fieldName = 'SignatureDebtor',\n anchorText = '__SIG_DEBTOR_ANCHOR__',\n) {\n const bytes = toU8(pdf);\n\n const anchor = await findAnchorPosition(bytes.slice(), anchorText);\n\n const pdfDoc = await PDFDocument.load(bytes);\n\n const sigWidth = 240;\n const sigHeight = 50;\n\n if (anchor) {\n const pageIndex = anchor.pageIndex;\n const page = pdfDoc.getPages()[pageIndex];\n if (!page) {\n throw new SignaturePlacementException(`Page ${pageIndex} not found`);\n }\n const { width: pw, height: ph } = page.getSize();\n\n const padX = 40;\n const padY = 7;\n let x = anchor.x - sigWidth / 2 + padX;\n\n let y = anchor.y - sigHeight + padY;\n\n const margin = 10;\n\n x = Math.max(margin, Math.min(x, pw - sigWidth - margin));\n y = Math.max(margin, Math.min(y, ph - sigHeight - margin));\n\n addSignatureFieldAt(pdfDoc, anchor.pageIndex, {\n fieldName,\n x,\n y,\n width: sigWidth,\n height: sigHeight,\n });\n } else {\n const pages = pdfDoc.getPages();\n const pageIndex = pages.length - 1;\n const page = pages.at(-1);\n /* v8 ignore next -- pdf-lib always produces at least one page on save/load; only a hand-crafted, malformed PDF could hit this */\n if (!page) {\n throw new SignaturePlacementException(`Page ${pageIndex} not found`);\n }\n const { width: pageWidth } = page.getSize();\n const x = (pageWidth - sigWidth) / 2;\n const y = 90;\n\n addSignatureFieldAt(pdfDoc, pageIndex, {\n fieldName,\n x,\n y,\n width: sigWidth,\n height: sigHeight,\n });\n }\n\n return await pdfDoc.save();\n}\n\n// Test helper to inject a mocked pdfjs implementation and avoid dynamic import in tests\n// This helper throws outside of tests to avoid exposing a test-only API in production.\nexport function __setPdfjsForTests(p: any) {\n if (process.env.NODE_ENV !== 'test') {\n throw new Error('__setPdfjsForTests is only available in test environment');\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n pdfjsPromise = p;\n}\n","import {\n degrees,\n PDFDocument,\n type PDFImage,\n type PDFPage,\n rgb,\n StandardFonts,\n} from 'pdf-lib';\n\nimport { WatermarkException } from '../exceptions';\n\nexport interface WatermarkOptions {\n /** Text to stamp. At least one of `text` or `image` is required. */\n text?: string;\n /** PNG or JPEG bytes to stamp. At least one of `text` or `image` is required. */\n image?: Uint8Array | Buffer;\n /** Opacity between 0 (invisible) and 1 (opaque). Default: 0.15 */\n opacity?: number;\n /** Counter-clockwise rotation in degrees. Default: 45 */\n rotation?: number;\n /** Text font size in points. Default: 60 */\n fontSize?: number;\n /** One of the PDF standard fonts (WinAnsi characters only). Default: 'HelveticaBold' */\n font?: keyof typeof StandardFonts;\n /** Text color as `#rgb` or `#rrggbb`. Default: '#808080' */\n color?: string;\n /** Rendered image width in points (aspect ratio preserved). Default: 50% of the page width */\n imageWidth?: number;\n /** `center` stamps once per page, `tile` repeats the mark across the page. Default: 'center' */\n position?: 'center' | 'tile';\n /** Gap in points between two marks when `position` is `tile`. Default: 100 */\n tileSpacing?: number;\n /** 1-based page numbers to watermark. Default: all pages */\n pages?: Array<number>;\n}\n\nconst DEFAULT_OPACITY = 0.15;\nconst DEFAULT_ROTATION = 45;\nconst DEFAULT_FONT_SIZE = 60;\nconst DEFAULT_FONT: keyof typeof StandardFonts = 'HelveticaBold';\nconst DEFAULT_COLOR = '#808080';\nconst DEFAULT_TILE_SPACING = 100;\n\ninterface Mark {\n width: number;\n height: number;\n draw: (page: PDFPage, x: number, y: number) => void;\n}\n\nfunction parseHexColor(color: string) {\n const match = /^#([\\da-f]{3}|[\\da-f]{6})$/i.exec(color);\n if (!match) {\n throw new WatermarkException(\n `Invalid watermark color \"${color}\", expected #rgb or #rrggbb`,\n );\n }\n const hex =\n match[1].length === 3 ? [...match[1]].map((c) => c + c).join('') : match[1];\n const channel = (i: number) => Number.parseInt(hex.slice(i, i + 2), 16) / 255;\n return rgb(channel(0), channel(2), channel(4));\n}\n\nfunction embedImage(pdfDoc: PDFDocument, bytes: Uint8Array): Promise<PDFImage> {\n const isPng = bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e;\n const isJpeg = bytes[0] === 0xff && bytes[1] === 0xd8;\n if (isPng) return pdfDoc.embedPng(bytes);\n if (isJpeg) return pdfDoc.embedJpg(bytes);\n throw new WatermarkException('Watermark image must be a PNG or JPEG');\n}\n\nfunction validate(options: WatermarkOptions) {\n const { text, image, opacity, fontSize, imageWidth, tileSpacing } = options;\n if (!text && !image) {\n throw new WatermarkException(\n 'A watermark requires at least a `text` or an `image`',\n );\n }\n if (opacity !== undefined && !(opacity >= 0 && opacity <= 1)) {\n throw new WatermarkException('Watermark `opacity` must be between 0 and 1');\n }\n if (fontSize !== undefined && !(fontSize > 0)) {\n throw new WatermarkException('Watermark `fontSize` must be greater than 0');\n }\n if (imageWidth !== undefined && !(imageWidth > 0)) {\n throw new WatermarkException(\n 'Watermark `imageWidth` must be greater than 0',\n );\n }\n if (tileSpacing !== undefined && !(tileSpacing >= 0)) {\n throw new WatermarkException('Watermark `tileSpacing` must be at least 0');\n }\n}\n\nfunction resolvePageIndexes(pages: Array<number> | undefined, total: number) {\n if (!pages) {\n return Array.from({ length: total }, (_, i) => i);\n }\n for (const page of pages) {\n if (!Number.isInteger(page) || page < 1 || page > total) {\n throw new WatermarkException(\n `Watermark page ${page} is out of range (the PDF has ${total} page(s))`,\n );\n }\n }\n return [...new Set(pages)].map((page) => page - 1);\n}\n\n/**\n * Centers of the marks for one page, in page coordinates. Tiles follow the\n * rotated axes so rotated marks never overlap each other.\n */\nfunction markCenters(\n pageWidth: number,\n pageHeight: number,\n mark: Mark,\n options: { position: 'center' | 'tile'; rotation: number; spacing: number },\n) {\n const cx = pageWidth / 2;\n const cy = pageHeight / 2;\n if (options.position === 'center') {\n return [{ x: cx, y: cy }];\n }\n\n const theta = (options.rotation * Math.PI) / 180;\n const cos = Math.cos(theta);\n const sin = Math.sin(theta);\n const stepX = mark.width + options.spacing;\n const stepY = mark.height + options.spacing;\n const reach = Math.hypot(mark.width, mark.height) / 2;\n const n = Math.ceil(\n (Math.hypot(pageWidth, pageHeight) / 2 + reach) / Math.min(stepX, stepY),\n );\n\n const centers: Array<{ x: number; y: number }> = [];\n for (let i = -n; i <= n; i++) {\n for (let j = -n; j <= n; j++) {\n const x = cx + i * stepX * cos - j * stepY * sin;\n const y = cy + i * stepX * sin + j * stepY * cos;\n if (\n x >= -reach &&\n x <= pageWidth + reach &&\n y >= -reach &&\n y <= pageHeight + reach\n ) {\n centers.push({ x, y });\n }\n }\n }\n return centers;\n}\n\nasync function buildMark(\n pdfDoc: PDFDocument,\n options: WatermarkOptions,\n pageWidth: number,\n): Promise<Mark> {\n const opacity = options.opacity ?? DEFAULT_OPACITY;\n const rotate = degrees(options.rotation ?? DEFAULT_ROTATION);\n\n if (options.image) {\n const image = await embedImage(pdfDoc, new Uint8Array(options.image));\n const width = options.imageWidth ?? pageWidth / 2;\n const height = (image.height / image.width) * width;\n return {\n width,\n height,\n draw: (page, x, y) =>\n page.drawImage(image, { x, y, width, height, opacity, rotate }),\n };\n }\n\n const font = await pdfDoc.embedFont(\n StandardFonts[options.font ?? DEFAULT_FONT],\n );\n const size = options.fontSize ?? DEFAULT_FONT_SIZE;\n const text = options.text!;\n const color = parseHexColor(options.color ?? DEFAULT_COLOR);\n let width: number;\n try {\n width = font.widthOfTextAtSize(text, size);\n } catch (error) {\n throw new WatermarkException(\n `Watermark text cannot be rendered with the ${options.font ?? DEFAULT_FONT} font (only WinAnsi characters are supported)`,\n { cause: error },\n );\n }\n return {\n width,\n height: font.heightAtSize(size, { descender: false }),\n draw: (page, x, y) =>\n page.drawText(text, { x, y, size, font, color, opacity, rotate }),\n };\n}\n\n/**\n * Stamps a text or image watermark on the pages of an existing PDF.\n */\nexport async function addWatermark(\n pdf: Uint8Array | Buffer,\n options: WatermarkOptions,\n): Promise<Uint8Array> {\n validate(options);\n\n try {\n const pdfDoc = await PDFDocument.load(new Uint8Array(pdf));\n const pages = pdfDoc.getPages();\n const indexes = resolvePageIndexes(options.pages, pages.length);\n\n const position = options.position ?? 'center';\n const rotation = options.rotation ?? DEFAULT_ROTATION;\n const spacing = options.tileSpacing ?? DEFAULT_TILE_SPACING;\n const theta = (rotation * Math.PI) / 180;\n const cos = Math.cos(theta);\n const sin = Math.sin(theta);\n\n // The image width depends on the page width, so marks are cached per width.\n const marks = new Map<number, Mark>();\n\n for (const index of indexes) {\n const page = pages[index];\n const { width: pageWidth, height: pageHeight } = page.getSize();\n\n let mark = marks.get(pageWidth);\n if (!mark) {\n mark = await buildMark(pdfDoc, options, pageWidth);\n marks.set(pageWidth, mark);\n }\n\n for (const center of markCenters(pageWidth, pageHeight, mark, {\n position,\n rotation,\n spacing,\n })) {\n // drawText/drawImage rotate around the bottom-left corner, so shift\n // the origin to make the mark's own center land on `center`.\n mark.draw(\n page,\n center.x - ((mark.width / 2) * cos - (mark.height / 2) * sin),\n center.y - ((mark.width / 2) * sin + (mark.height / 2) * cos),\n );\n }\n }\n\n return await pdfDoc.save();\n } catch (error) {\n if (error instanceof WatermarkException) throw error;\n throw new WatermarkException(\n `Failed to add watermark: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n}\n","/*\nHow it works:\n`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.\n*/\n\nclass Node {\n\tvalue;\n\tnext;\n\n\tconstructor(value) {\n\t\tthis.value = value;\n\t}\n}\n\nexport default class Queue {\n\t#head;\n\t#tail;\n\t#size;\n\n\tconstructor() {\n\t\tthis.clear();\n\t}\n\n\tenqueue(value) {\n\t\tconst node = new Node(value);\n\n\t\tif (this.#head) {\n\t\t\tthis.#tail.next = node;\n\t\t\tthis.#tail = node;\n\t\t} else {\n\t\t\tthis.#head = node;\n\t\t\tthis.#tail = node;\n\t\t}\n\n\t\tthis.#size++;\n\t}\n\n\tdequeue() {\n\t\tconst current = this.#head;\n\t\tif (!current) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#head = this.#head.next;\n\t\tthis.#size--;\n\n\t\t// Clean up tail reference when queue becomes empty\n\t\tif (!this.#head) {\n\t\t\tthis.#tail = undefined;\n\t\t}\n\n\t\treturn current.value;\n\t}\n\n\tpeek() {\n\t\tif (!this.#head) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this.#head.value;\n\n\t\t// TODO: Node.js 18.\n\t\t// return this.#head?.value;\n\t}\n\n\tclear() {\n\t\tthis.#head = undefined;\n\t\tthis.#tail = undefined;\n\t\tthis.#size = 0;\n\t}\n\n\tget size() {\n\t\treturn this.#size;\n\t}\n\n\t* [Symbol.iterator]() {\n\t\tlet current = this.#head;\n\n\t\twhile (current) {\n\t\t\tyield current.value;\n\t\t\tcurrent = current.next;\n\t\t}\n\t}\n\n\t* drain() {\n\t\twhile (this.#head) {\n\t\t\tyield this.dequeue();\n\t\t}\n\t}\n}\n","import Queue from 'yocto-queue';\n\nexport default function pLimit(concurrency) {\n\tlet rejectOnClear = false;\n\n\tif (typeof concurrency === 'object') {\n\t\t({concurrency, rejectOnClear = false} = concurrency);\n\t}\n\n\tvalidateConcurrency(concurrency);\n\n\tif (typeof rejectOnClear !== 'boolean') {\n\t\tthrow new TypeError('Expected `rejectOnClear` to be a boolean');\n\t}\n\n\tconst queue = new Queue();\n\tlet activeCount = 0;\n\n\tconst resumeNext = () => {\n\t\t// Process the next queued function if we're under the concurrency limit\n\t\tif (activeCount < concurrency && queue.size > 0) {\n\t\t\tactiveCount++;\n\t\t\tqueue.dequeue().run();\n\t\t}\n\t};\n\n\tconst next = () => {\n\t\tactiveCount--;\n\t\tresumeNext();\n\t};\n\n\tconst run = async (function_, resolve, arguments_) => {\n\t\t// Execute the function and capture the result promise\n\t\tconst result = (async () => function_(...arguments_))();\n\n\t\t// Resolve immediately with the promise (don't wait for completion)\n\t\tresolve(result);\n\n\t\t// Wait for the function to complete (success or failure)\n\t\t// We catch errors here to prevent unhandled rejections,\n\t\t// but the original promise rejection is preserved for the caller\n\t\ttry {\n\t\t\tawait result;\n\t\t} catch {}\n\n\t\t// Decrement active count and process next queued function\n\t\tnext();\n\t};\n\n\tconst enqueue = (function_, resolve, reject, arguments_) => {\n\t\tconst queueItem = {reject};\n\n\t\t// Queue the internal resolve function instead of the run function\n\t\t// to preserve the asynchronous execution context.\n\t\tnew Promise(internalResolve => { // eslint-disable-line promise/param-names\n\t\t\tqueueItem.run = internalResolve;\n\t\t\tqueue.enqueue(queueItem);\n\t\t}).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then\n\n\t\t// Start processing immediately if we haven't reached the concurrency limit\n\t\tif (activeCount < concurrency) {\n\t\t\tresumeNext();\n\t\t}\n\t};\n\n\tconst generator = (function_, ...arguments_) => new Promise((resolve, reject) => {\n\t\tenqueue(function_, resolve, reject, arguments_);\n\t});\n\n\tObject.defineProperties(generator, {\n\t\tactiveCount: {\n\t\t\tget: () => activeCount,\n\t\t},\n\t\tpendingCount: {\n\t\t\tget: () => queue.size,\n\t\t},\n\t\tclearQueue: {\n\t\t\tvalue() {\n\t\t\t\tif (!rejectOnClear) {\n\t\t\t\t\tqueue.clear();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst abortError = AbortSignal.abort().reason;\n\n\t\t\t\twhile (queue.size > 0) {\n\t\t\t\t\tqueue.dequeue().reject(abortError);\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\tconcurrency: {\n\t\t\tget: () => concurrency,\n\n\t\t\tset(newConcurrency) {\n\t\t\t\tvalidateConcurrency(newConcurrency);\n\t\t\t\tconcurrency = newConcurrency;\n\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\t// eslint-disable-next-line no-unmodified-loop-condition\n\t\t\t\t\twhile (activeCount < concurrency && queue.size > 0) {\n\t\t\t\t\t\tresumeNext();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t\tmap: {\n\t\t\tasync value(iterable, function_) {\n\t\t\t\tconst promises = Array.from(iterable, (value, index) => generator(function_, value, index));\n\t\t\t\treturn Promise.all(promises);\n\t\t\t},\n\t\t},\n\t});\n\n\treturn generator;\n}\n\nexport function limitFunction(function_, options) {\n\tconst limit = pLimit(options);\n\n\tconst limitedFunction = (...arguments_) => limit(() => function_(...arguments_));\n\tObject.defineProperty(limitedFunction, 'clearQueue', {\n\t\tvalue: limit.clearQueue,\n\t});\n\n\treturn limitedFunction;\n}\n\nfunction validateConcurrency(concurrency) {\n\tif (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {\n\t\tthrow new TypeError('Expected `concurrency` to be a number from 1 and up');\n\t}\n}\n","import { deepmerge } from 'deepmerge-ts';\n\nimport { type PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\n\nexport function mergePuppeteerParameters(\n defaults: PuppeteerParameters,\n overrides?: PuppeteerParameters,\n): PuppeteerParameters {\n if (!overrides) {\n return { ...defaults };\n }\n\n return deepmerge(defaults, overrides);\n}\n","import { lookup } from 'node:dns/promises';\nimport { promises } from 'node:fs';\nimport { BlockList, isIP } from 'node:net';\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { Logger } from '@nestjs/common';\nimport {\n type BrowserContext,\n type HTTPRequest,\n type Page,\n TargetType,\n} from 'puppeteer';\n\n/**\n * Filters what the rendered HTML may load (SSRF protection). Disabled unless set:\n * pass `{}` for the defaults (private networks and `file:` blocked).\n */\nexport interface PdfSecurityOptions {\n /**\n * Refuse http(s) requests that resolve to a loopback, private, link-local\n * (cloud metadata included) or otherwise non-public address. Default: true\n */\n blockPrivateNetworks?: boolean;\n /**\n * When set, http(s) requests are only allowed to these hosts (`example.com`\n * or `*.example.com`). Listed hosts are trusted, even on a private address.\n */\n allowedHosts?: Array<string>;\n /**\n * `file:` requests are refused unless the file is inside one of these\n * directories (symbolic links are resolved).\n */\n allowedFileRoots?: Array<string>;\n /** Set to false to disable JavaScript in the rendered page. Default: true */\n javascriptEnabled?: boolean;\n}\n\nconst blockedRanges = new BlockList();\nfor (const [address, prefix] of [\n ['0.0.0.0', 8],\n ['10.0.0.0', 8],\n ['100.64.0.0', 10],\n ['127.0.0.0', 8],\n ['169.254.0.0', 16],\n ['172.16.0.0', 12],\n ['192.0.0.0', 24],\n ['192.168.0.0', 16],\n ['198.18.0.0', 15],\n ['224.0.0.0', 4],\n ['240.0.0.0', 4],\n] as const) {\n blockedRanges.addSubnet(address, prefix, 'ipv4');\n}\nfor (const [address, prefix] of [\n ['::', 128],\n ['::1', 128],\n ['64:ff9b::', 96],\n ['fc00::', 7],\n ['fe80::', 10],\n ['ff00::', 8],\n] as const) {\n blockedRanges.addSubnet(address, prefix, 'ipv6');\n}\n\nconst IPV4_MAPPED_IPV6 = /^::ffff:([\\da-f]{1,4}):([\\da-f]{1,4})$/i;\n\n/** True for addresses that must not be reachable from a rendered document. */\nexport function isPrivateAddress(address: string): boolean {\n const family = isIP(address);\n if (family === 4) {\n return blockedRanges.check(address, 'ipv4');\n }\n if (family === 6) {\n // WHATWG URL serialises ::ffff:127.0.0.1 as ::ffff:7f00:1\n const mapped = IPV4_MAPPED_IPV6.exec(address);\n if (mapped) {\n const high = Number.parseInt(mapped[1], 16);\n const low = Number.parseInt(mapped[2], 16);\n return isPrivateAddress(\n [high >> 8, high & 0xff, low >> 8, low & 0xff].join('.'),\n );\n }\n return blockedRanges.check(address, 'ipv6');\n }\n // Not an IP: unknown format, refuse.\n return true;\n}\n\nfunction hostMatches(hostname: string, pattern: string): boolean {\n const host = hostname.toLowerCase();\n const rule = pattern.toLowerCase();\n if (rule.startsWith('*.')) {\n return host.endsWith(rule.slice(1));\n }\n return host === rule;\n}\n\nfunction isLocalhostName(hostname: string): boolean {\n return hostname === 'localhost' || hostname.endsWith('.localhost');\n}\n\nasync function resolvesToPrivateAddress(hostname: string): Promise<boolean> {\n // IPv6 literals come bracketed from URL.hostname\n const host = hostname.replace(/^\\[|\\]$/g, '');\n if (isIP(host)) {\n return isPrivateAddress(host);\n }\n if (isLocalhostName(host)) {\n return true;\n }\n try {\n const addresses = await lookup(host, { all: true, verbatim: true });\n return addresses.some(({ address }) => isPrivateAddress(address));\n } catch {\n // Unresolvable: the browser would fail too, and we cannot vouch for it.\n return true;\n }\n}\n\nasync function isFileAllowed(url: URL, roots: Array<string>): Promise<boolean> {\n // file://server/share is a network path (SMB), never a local file\n if (\n roots.length === 0 ||\n (url.hostname !== '' && url.hostname !== 'localhost')\n ) {\n return false;\n }\n\n let path: string;\n try {\n path = fileURLToPath(url);\n } catch {\n return false;\n }\n\n // Missing file: nothing to leak, but resolve its closest existing ancestor\n // so symlinks (e.g. macOS /var -> /private/var) match the resolved roots.\n const real = async (candidate: string) => {\n const missing: Array<string> = [];\n let current = resolve(candidate);\n for (;;) {\n try {\n return join(await promises.realpath(current), ...missing);\n } catch {\n const parent = dirname(current);\n if (parent === current) return resolve(candidate);\n missing.unshift(basename(current));\n current = parent;\n }\n }\n };\n\n const target = await real(path);\n for (const root of roots) {\n const rel = relative(await real(root), target);\n if (rel === '' || (!rel.startsWith('..') && !isAbsolute(rel))) {\n return true;\n }\n }\n return false;\n}\n\n/** Decides whether the browser may fetch `rawUrl`. */\nexport async function isRequestAllowed(\n rawUrl: string,\n options: PdfSecurityOptions,\n): Promise<boolean> {\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n return false;\n }\n\n switch (url.protocol) {\n case 'about:':\n case 'data:':\n case 'blob:':\n return true;\n case 'file:':\n return isFileAllowed(url, options.allowedFileRoots ?? []);\n case 'http:':\n case 'https:': {\n if (options.allowedHosts) {\n return options.allowedHosts.some((pattern) =>\n hostMatches(url.hostname, pattern),\n );\n }\n if (options.blockPrivateNetworks === false) {\n return true;\n }\n return !(await resolvesToPrivateAddress(url.hostname));\n }\n default:\n return false;\n }\n}\n\n/** Logs the origin and path only: query strings may carry secrets. */\nfunction describe(rawUrl: string) {\n try {\n const url = new URL(rawUrl);\n return `${url.origin === 'null' ? `${url.protocol}//` : url.origin}${url.pathname}`;\n } catch {\n return '<invalid url>';\n }\n}\n\n/**\n * Filters every request the page (and its frames) makes, redirects included,\n * and closes the pop-ups a script could open to escape the filter.\n */\nexport async function installRequestGuard(\n context: BrowserContext,\n page: Page,\n options: PdfSecurityOptions,\n) {\n context.on('targetcreated', (target) => {\n if (target.type() === TargetType.PAGE && target.opener()) {\n void target\n .page()\n .then((popup) => popup?.close())\n .catch(() => undefined);\n }\n });\n\n if (options.javascriptEnabled === false) {\n await page.setJavaScriptEnabled(false);\n }\n\n await page.setRequestInterception(true);\n page.on('request', (request: HTTPRequest) => {\n void (async () => {\n if (request.isInterceptResolutionHandled()) return;\n const url = request.url();\n const allowed = await isRequestAllowed(url, options).catch(() => false);\n if (request.isInterceptResolutionHandled()) return;\n if (allowed) {\n await request.continue();\n } else {\n Logger.warn(`Blocked request to ${describe(url)}`, 'NestJsPdf');\n await request.abort('blockedbyclient');\n }\n })().catch(() => undefined);\n });\n}\n","export const PDF_PARAMETERS = 'PDF_PARAMETERS' as const;\n","import { existsSync, promises, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Inject, Injectable, Logger, OnModuleDestroy } from '@nestjs/common';\nimport {\n Browser as BrowserType,\n BrowserPlatform,\n canDownload,\n detectBrowserPlatform,\n getInstalledBrowsers,\n install,\n resolveBuildId,\n} from '@puppeteer/browsers';\nimport { Browser, BrowserContext, launch } from 'puppeteer';\n\nimport {\n BrowserInstallationException,\n BrowserUnavailableException,\n NestjsPdfException,\n} from '../../exceptions';\nimport type { PuppeteerParameters } from '../puppeteer-parameters.interface';\n\nexport enum BrowserTag {\n LATEST = 'latest',\n BETA = 'beta',\n DEV = 'dev',\n STABLE = 'stable',\n CANARY = 'canary',\n}\n\nexport type Headless = boolean | 'shell' | undefined;\n\nasync function sleep(ms: number) {\n await new Promise((r) => setTimeout(r, ms));\n}\n\nasync function rmWithRetries(dir: string, retries = 5): Promise<void> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n await promises.rm(dir, { recursive: true, force: true });\n return;\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException)?.code;\n\n const retryable =\n code === 'EPERM' || code === 'EBUSY' || code === 'ENOTEMPTY';\n\n if (!retryable || attempt === retries) {\n throw err;\n }\n\n await sleep(50 * 2 ** (attempt - 1));\n }\n }\n}\n\nfunction isTargetClosedError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n\n return (\n error.name === 'TargetCloseError' ||\n error.message.includes('Target closed') ||\n error.message.includes('Target.createTarget')\n );\n}\n\n@Injectable()\nexport class BrowserService implements OnModuleDestroy {\n readonly #cacheDir: string;\n readonly #options?: PuppeteerParameters;\n\n #browserInstance: Browser | null = null;\n #browser: BrowserType;\n\n public activeJobs = 0;\n public totalJobs = 0;\n\n #recycleRequested = false;\n #recycling = false;\n\n #shuttingDown = false;\n /** Max time to wait for in-flight PDF jobs to finish before closing the browser on shutdown. */\n public shutdownDrainTimeoutMs = 15_000;\n\n #browserTag: BrowserTag;\n #useLockedBrowser: boolean;\n #buildId: string | undefined;\n\n constructor(@Inject('PDF_PARAMETERS') pdfParams: PuppeteerParameters) {\n this.#cacheDir = resolve('.cache/puppeteer-browser');\n this.#options = pdfParams;\n\n this.#loadBuildId();\n this.#loadBrowser();\n this.#loadBrowserTag();\n this.#loadUseLockedBrowser();\n }\n\n async onModuleDestroy() {\n this.#shuttingDown = true;\n await this.#waitForIdle(this.shutdownDrainTimeoutMs);\n\n if (this.#browserInstance?.connected) {\n try {\n await this.#browserInstance.close();\n } catch (error) {\n Logger.warn(\n `Failed to close browser on module destroy: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n if (this.#options?.cleanupBrowserCacheOnExit !== false) {\n await this.#cleanupCacheBestEffort();\n }\n }\n\n /** Wait until no PDF job is in flight, or until the timeout elapses. */\n async #waitForIdle(timeoutMs: number): Promise<void> {\n const start = Date.now();\n while (this.activeJobs > 0 && Date.now() - start < timeoutMs) {\n await sleep(50);\n }\n\n if (this.activeJobs > 0) {\n Logger.warn(\n `Shutdown: ${this.activeJobs} PDF job(s) still running after ${timeoutMs}ms, closing the browser anyway`,\n );\n }\n }\n\n async getBrowserInstance(\n args: Array<string>,\n headless: boolean | 'shell' | undefined,\n executablePathBin: string | undefined,\n ) {\n if (!this.#browserInstance?.connected) {\n this.#browserInstance = await this.#launchBrowser(\n args,\n headless,\n executablePathBin,\n );\n }\n\n return this.#browserInstance;\n }\n\n async createContext(\n args: Array<string>,\n headless: Headless,\n executablePath?: string,\n ): Promise<BrowserContext> {\n const browser = await this.getBrowserInstance(\n args,\n headless,\n executablePath,\n );\n try {\n return await browser.createBrowserContext();\n } catch (error) {\n if (!isTargetClosedError(error)) {\n throw error;\n }\n\n Logger.warn(\n 'Puppeteer browser closed while creating a context, retrying once',\n );\n\n this.#browserInstance = null;\n const freshBrowser = await this.getBrowserInstance(\n args,\n headless,\n executablePath,\n );\n return await freshBrowser.createBrowserContext();\n }\n }\n\n markJobStarted() {\n if (this.#shuttingDown) {\n throw new BrowserUnavailableException(\n 'nestjs-pdf is shutting down, refusing new PDF jobs',\n );\n }\n\n this.activeJobs += 1;\n this.totalJobs += 1;\n\n if (this.totalJobs >= 200) {\n this.#recycleRequested = true;\n }\n }\n\n async markJobFinished() {\n this.activeJobs = Math.max(0, this.activeJobs - 1);\n await this.recycleBrowserIfNeeded();\n }\n\n async recycleBrowserIfNeeded() {\n if (!this.#recycleRequested) return;\n if (this.#recycling) return;\n if (this.activeJobs > 0) return;\n if (!this.#browserInstance) return;\n\n this.#recycling = true;\n\n try {\n if (this.#browserInstance.connected) {\n await this.#browserInstance.close();\n }\n\n this.#browserInstance = null;\n this.totalJobs = 0;\n this.#recycleRequested = false;\n\n Logger.log('Puppeteer browser recycled successfully');\n } catch (error) {\n Logger.warn(\n `Failed to recycle browser: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n } finally {\n this.#recycling = false;\n }\n }\n\n async #cleanupCacheBestEffort() {\n const logger = new Logger('NestJsPdf');\n const dir = this.#cacheDir;\n try {\n if (!existsSync(dir)) return;\n\n logger.log(`Cleanup puppeteer cache: ${dir}`);\n\n await rmWithRetries(dir, 6);\n if (existsSync(dir)) {\n await sleep(100);\n await rmWithRetries(dir, 3);\n }\n\n logger.log('Cleanup done');\n } catch (err) {\n logger.error(\n `Cleanup failed for ${dir}`,\n err instanceof Error ? err.stack : String(err),\n );\n }\n try {\n const leftover = await promises.readdir(dir, { recursive: true });\n logger.warn(`Leftover files: ${leftover.slice(0, 20).join(', ')}...`);\n } catch {\n logger.log(`No leftover files in ${dir}`);\n }\n }\n\n async install(lock: boolean = false) {\n try {\n return await this.#doInstall(lock);\n } catch (error) {\n if (error instanceof NestjsPdfException) {\n throw error;\n }\n throw new BrowserInstallationException(\n `Could not install browser: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async #doInstall(lock: boolean) {\n const browser: BrowserType = this.#browser;\n const versionTag: BrowserTag = this.#browserTag;\n\n const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;\n\n let buildId: string;\n if (this.#buildId === undefined) {\n buildId = await resolveBuildId(browser, browserPlatform, versionTag);\n } else {\n buildId = this.#buildId;\n }\n\n Logger.log(\n `Browser ${browser} ${versionTag} build id: ${buildId}`,\n 'NestJsPdf',\n );\n\n if (await this.hasBrowserInstalled(browser, buildId)) {\n Logger.log('Browser already installed', 'NestJsPdf');\n if (lock) {\n this.#writeLockFile(browser, buildId);\n }\n return;\n } else {\n Logger.log('Starting browser installation', 'NestJsPdf');\n\n const installOption = {\n cacheDir: this.#cacheDir,\n browser: browser,\n buildId: buildId,\n baseUrl: this.#options?.browserInstallBaseUrl ?? undefined,\n };\n\n if (await canDownload(installOption)) {\n Logger.log(\n `Installing ${installOption.browser} ${installOption.buildId}`,\n 'NestJsPdf',\n );\n const installedBrowser = await install(installOption);\n if (await this.hasBrowserInstalled(browser, buildId)) {\n Logger.log('Browser installed successfully', 'NestJsPdf');\n if (lock) {\n this.#writeLockFile(browser, buildId);\n }\n return installedBrowser;\n } else {\n Logger.error('Browser installation failed', 'NestJsPdf');\n }\n } else {\n Logger.error(\n `Error, can't install ${installOption.browser} ${installOption.buildId}`,\n 'NestJsPdf',\n );\n }\n }\n return null;\n }\n\n #loadBrowser(): void {\n let browser: BrowserType;\n if (this.#options?.browser === undefined) {\n browser = BrowserType.CHROMIUM;\n } else {\n browser = this.#options.browser;\n }\n this.#browser = browser;\n }\n\n public getBrowser(): BrowserType {\n return this.#browser;\n }\n\n #loadBrowserTag(): void {\n let versionTag: BrowserTag;\n if (this.#options?.browserTag === undefined) {\n if (this.#browser === BrowserType.CHROMIUM) {\n versionTag = BrowserTag.LATEST;\n } else {\n versionTag = BrowserTag.STABLE;\n }\n } else {\n versionTag = this.#options.browserTag;\n }\n this.#browserTag = versionTag;\n }\n\n #loadBuildId(): void {\n let buildId: string | undefined;\n if (this.#options?.buildId === undefined) {\n buildId = undefined;\n } else {\n buildId = this.#options.buildId;\n }\n this.#buildId = buildId;\n }\n\n public setBrowserTag(browserTag: BrowserTag): void {\n this.#browserTag = browserTag;\n }\n\n public getBrowserTag(): BrowserTag {\n return this.#browserTag;\n }\n\n getBuildId(): string | undefined {\n return this.#buildId;\n }\n\n #loadUseLockedBrowser(): void {\n let useLockedBrowser: boolean;\n if (this.#options?.useLockedBrowser === undefined) {\n useLockedBrowser = false;\n } else {\n useLockedBrowser = this.#options.useLockedBrowser;\n }\n this.#useLockedBrowser = useLockedBrowser;\n }\n\n async hasBrowserInstalled(browser: BrowserType, buildId: string) {\n const installedBrowserlist = await getInstalledBrowsers({\n cacheDir: this.#cacheDir,\n });\n\n const installedBrowser = installedBrowserlist.find((insBrowser) => {\n return insBrowser.browser === browser && insBrowser.buildId === buildId;\n });\n return installedBrowser !== undefined;\n }\n\n async getExecutablePath(): Promise<string> {\n const browser: BrowserType = this.#browser;\n const versionTag: BrowserTag = this.#browserTag;\n const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;\n let buildId: string | null = null;\n if (this.#useLockedBrowser) {\n buildId = this.getLockedBuildId(browser);\n Logger.log(`Using locked browser ${buildId}`, 'NestJsPdf');\n }\n buildId ??= await resolveBuildId(browser, browserPlatform, versionTag);\n const installedBrowserlist = await getInstalledBrowsers({\n cacheDir: this.#cacheDir,\n });\n const installedBrowser = installedBrowserlist.find((insBrowser) => {\n return insBrowser.browser === browser && insBrowser.buildId === buildId;\n });\n if (installedBrowser === undefined) {\n const newinstalledBrowser = await this.install();\n if (newinstalledBrowser === null || newinstalledBrowser === undefined) {\n throw new BrowserInstallationException('Could not install browser');\n } else {\n return newinstalledBrowser.executablePath;\n }\n }\n return installedBrowser.executablePath;\n }\n\n async #launchBrowser(\n args: Array<string>,\n headless: Headless,\n executablePathBin: string | undefined,\n ) {\n const executablePath =\n executablePathBin ?? (await this.getExecutablePath());\n\n const browser = await launch({\n executablePath,\n headless,\n args,\n // Puppeteer disables Chrome's popup blocker by default, which lets a\n // script open a window that escapes the request filter.\n ignoreDefaultArgs: ['--disable-popup-blocking'],\n });\n\n browser.on('disconnected', () => {\n Logger.warn('Puppeteer browser disconnected');\n if (this.#browserInstance === browser) {\n this.#browserInstance = null;\n }\n });\n\n return browser;\n }\n\n #writeLockFile(browser: BrowserType, buildId: string) {\n const lockFile = resolve(this.#cacheDir, `${browser}.lock`);\n const data = JSON.stringify({\n browser: browser,\n buildId: buildId,\n date: new Date().toISOString(),\n });\n writeFileSync(lockFile, data);\n\n Logger.log(`Browser ${browser} locked to build ${buildId}`, 'NestJsPdf');\n }\n\n getLockedBuildId(browser: BrowserType): string | null {\n const lockFile = resolve(this.#cacheDir, `${browser}.lock`);\n if (existsSync(lockFile)) {\n const data = readFileSync(lockFile);\n const lock = JSON.parse(data.toString()) as {\n browser: Browser;\n buildId: string;\n date: string;\n };\n return lock.buildId;\n }\n return null;\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport ejs, { type Data, type Options } from 'ejs';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport interface EjsOptions extends Omit<Options, 'async'> {\n async?: boolean;\n}\n\n@Injectable()\nexport class EjsService {\n async render(template: string, data: Data = {}, options?: EjsOptions) {\n try {\n return await ejs.render(template, data, {\n async: true,\n ...options,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'EJS',\n `EJS rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async renderFile(filePath: string, data: Data = {}, options?: EjsOptions) {\n try {\n return await ejs.renderFile(filePath, data, {\n async: true,\n ...options,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'EJS',\n `EJS file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport { Eta, EtaConfig } from 'eta';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport interface EtaOptions extends Partial<EtaConfig> {\n cache?: boolean;\n autoEscape?: boolean;\n varName?: string;\n views?: string;\n useWith?: boolean;\n plugins?: Array<any>;\n}\n\n@Injectable()\nexport class EtaService {\n readonly #eta: Eta;\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n constructor() {\n this.#eta = new Eta({\n cache: true,\n autoEscape: true,\n useWith: true,\n });\n }\n\n /**\n * Render an Eta template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Eta rendering options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: EtaOptions,\n ): string {\n try {\n const eta =\n options && Object.keys(options).length > 0\n ? new Eta({\n cache: true,\n autoEscape: true,\n useWith: true,\n ...options,\n varName: options.varName ?? 'it',\n })\n : this.#eta;\n\n return eta.renderString(template, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Eta',\n `Eta rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render an Eta template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Eta rendering options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: EtaOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n const useCache = options?.cache ?? true;\n let template = useCache\n ? this.#templateCache.get(resolvedPath)\n : undefined;\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (useCache && this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n return this.render(template, data, options);\n } catch (error) {\n throw new TemplateRenderException(\n 'Eta',\n `Eta file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { basename, extname, join, resolve, sep } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport Handlebars from 'handlebars';\n\nimport {\n NestjsPdfException,\n TemplateConfigurationException,\n TemplateRenderException,\n} from '../../../exceptions';\n\nexport type HandlebarsHelper = {\n name: string;\n fn: Handlebars.HelperDelegate;\n};\n\nexport interface HandlebarsOptions {\n /** Base directory (relative to `process.cwd()`) used to resolve files passed to `renderFile`. */\n templateDirectory?: string;\n /** Directory (relative to `process.cwd()`) whose files are each registered as a partial. */\n partialDirectory?: string;\n /**\n * Runtime options forwarded to the compiled template function.\n * `helpers` and `partials` are excluded on purpose: register helpers via\n * `helpers` and partials via `partialDirectory`.\n */\n templateOptions?: Omit<Handlebars.RuntimeOptions, 'helpers' | 'partials'>;\n /** Options forwarded to `Handlebars.compile`. */\n compileOptions?: CompileOptions;\n /** Custom helpers registered on the isolated Handlebars environment for this render. */\n helpers?: Array<HandlebarsHelper>;\n}\n\n@Injectable()\nexport class HandlebarsService {\n #cachedOptions?: HandlebarsOptions;\n #cachedEnv?: typeof Handlebars;\n\n render(\n template: string,\n parameters: unknown = {},\n options: HandlebarsOptions = {},\n ): string {\n try {\n const compiled = this.#getEnv(options).compile(\n template,\n options.compileOptions,\n );\n return compiled(parameters, options.templateOptions);\n } catch (error) {\n if (error instanceof NestjsPdfException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Handlebars',\n `Handlebars rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n file: string,\n parameters: unknown = {},\n options: HandlebarsOptions = {},\n ): string {\n if (options.templateDirectory === undefined) {\n throw new TemplateConfigurationException(\n 'Handlebars file rendering failed: option `templateDirectory` is not set',\n );\n }\n\n const baseDir = resolve(process.cwd(), options.templateDirectory);\n const templatePath = resolve(baseDir, file);\n if (templatePath !== baseDir && !templatePath.startsWith(baseDir + sep)) {\n throw new TemplateConfigurationException(\n `Handlebars file rendering failed: ’${file}’ resolves outside \\`templateDirectory\\``,\n );\n }\n\n let template: string;\n try {\n template = readFileSync(templatePath, 'utf8');\n } catch (error) {\n throw new TemplateRenderException(\n 'Handlebars',\n `Handlebars file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n\n return this.render(template, parameters, options);\n }\n\n /**\n * Build an isolated Handlebars environment with the given helpers/partials so\n * nothing leaks into the global Handlebars. Memoised for the common case where\n * the same options object is reused across calls (e.g. the module `hbsOptions`).\n */\n #getEnv(options: HandlebarsOptions): typeof Handlebars {\n if (this.#cachedEnv && this.#cachedOptions === options) {\n return this.#cachedEnv;\n }\n\n const env = Handlebars.create();\n\n for (const helper of options.helpers ?? []) {\n env.registerHelper(helper.name, helper.fn);\n }\n this.#registerPartials(env, options.partialDirectory);\n\n this.#cachedOptions = options;\n this.#cachedEnv = env;\n return env;\n }\n\n #registerPartials(\n env: typeof Handlebars,\n partialDirectory: string | undefined,\n ): void {\n if (partialDirectory === undefined) return;\n\n const partialPath = join(process.cwd(), partialDirectory);\n if (!existsSync(partialPath)) {\n throw new TemplateConfigurationException(\n `Handlebars partial directory does not exist: ${partialPath}`,\n );\n }\n\n for (const entry of readdirSync(partialPath)) {\n const filePath = join(partialPath, entry);\n if (!statSync(filePath).isFile()) continue;\n\n env.registerPartial(\n basename(entry, extname(entry)),\n readFileSync(filePath, 'utf8'),\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\n\nimport { Injectable } from '@nestjs/common';\nimport mjml from 'mjml';\nimport { type MJMLParsingOptions } from 'mjml-core';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\n@Injectable()\nexport class MjmlService {\n async render(\n template: string,\n options?: MJMLParsingOptions,\n ): Promise<string> {\n try {\n const { html } = await mjml(template, options);\n return html;\n } catch (error) {\n throw new TemplateRenderException(\n 'MJML',\n `MJML rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async renderFile(\n filePath: string,\n options?: MJMLParsingOptions,\n ): Promise<string> {\n let template: string;\n try {\n template = readFileSync(filePath, 'utf-8');\n } catch (error) {\n throw new TemplateRenderException(\n 'MJML',\n `MJML file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n return await this.render(template, options);\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport mustache, { EscapeFunction } from 'mustache';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport interface MustacheOptions {\n tags?: [string, string];\n escape?: EscapeFunction;\n}\n\n@Injectable()\nexport class MustacheService {\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n /**\n * Render a Mustache template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Mustache rendering options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: MustacheOptions,\n ): string {\n try {\n const tags = options?.tags ?? ['{{', '}}'];\n return mustache.render(template, data, undefined, {\n tags: tags,\n escape: options?.escape,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'Mustache',\n `Mustache rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render a Mustache template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Mustache rendering options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: MustacheOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n let template = this.#templateCache.get(resolvedPath);\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n\n return this.render(template, data, options);\n } catch (error) {\n throw new TemplateRenderException(\n 'Mustache',\n `Mustache file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport nunjucks, { type ConfigureOptions } from 'nunjucks';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport interface NunjucksOptions extends Partial<ConfigureOptions> {\n noCache?: boolean;\n watch?: boolean;\n throwOnUndefined?: boolean;\n trimBlocks?: boolean;\n lstripBlocks?: boolean;\n}\n\n@Injectable()\nexport class NunjucksService {\n constructor() {\n // Configure default Nunjucks environment\n nunjucks.configure({\n noCache: true,\n trimBlocks: true,\n lstripBlocks: true,\n });\n }\n\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: NunjucksOptions,\n ) {\n try {\n if (options) {\n const configOptions: Record<string, unknown> = {\n noCache: options.noCache ?? true,\n watch: options.watch ?? false,\n throwOnUndefined: options.throwOnUndefined ?? false,\n trimBlocks: options.trimBlocks ?? true,\n lstripBlocks: options.lstripBlocks ?? true,\n };\n nunjucks.configure(configOptions as ConfigureOptions);\n }\n return nunjucks.renderString(template, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Nunjucks',\n `Nunjucks rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: NunjucksOptions,\n ) {\n try {\n if (options) {\n const configOptions: Record<string, unknown> = {\n noCache: options.noCache ?? true,\n watch: options.watch ?? false,\n throwOnUndefined: options.throwOnUndefined ?? false,\n trimBlocks: options.trimBlocks ?? true,\n lstripBlocks: options.lstripBlocks ?? true,\n };\n nunjucks.configure(configOptions as ConfigureOptions);\n }\n return nunjucks.render(filePath, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Nunjucks',\n `Nunjucks file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\n\nimport { Injectable } from '@nestjs/common';\nimport pug, { type LocalsObject, type Options } from 'pug';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport type PugOptions = Options;\n\n@Injectable()\nexport class PugService {\n render(\n template: string,\n data: LocalsObject = {},\n options?: PugOptions,\n ): string {\n try {\n const compiledFn = pug.compile(template, {\n ...options,\n });\n return compiledFn(data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Pug',\n `Pug rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n filePath: string,\n data: LocalsObject = {},\n options?: PugOptions,\n ): string {\n try {\n const template = readFileSync(filePath, 'utf-8');\n return this.render(template, data, options);\n } catch (error) {\n throw new TemplateRenderException(\n 'Pug',\n `Pug file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { EngineNotAvailableException } from '../../exceptions';\n\nexport function requireService<T>(service: T | undefined, name: string): T {\n if (!service) {\n throw new EngineNotAvailableException(name);\n }\n\n return service;\n}\n","import { Inject, Injectable, Logger, Optional } from '@nestjs/common';\nimport { Data } from 'ejs';\nimport pLimit from 'p-limit';\nimport { LocalsObject } from 'pug';\nimport { PDFOptions } from 'puppeteer';\n\nimport { NestjsPdfException, PdfGenerationException } from '../exceptions';\nimport { mergePuppeteerParameters } from '../helpers/deepMergePdfparams';\nimport { installRequestGuard } from '../helpers/request-guard.helper';\nimport { PDF_PARAMETERS } from '../helpers/tokens';\nimport { addWatermark } from '../helpers/watermark.helper';\nimport { BrowserService } from './browser/browser.service';\nimport { EjsService } from './engines/ejs/ejs.service';\nimport { EtaService } from './engines/eta/eta.service';\nimport { HandlebarsService } from './engines/handlebars/handlebars.service';\nimport { MjmlService } from './engines/mjml/mjml.service';\nimport { MustacheService } from './engines/mustache/mustache.service';\nimport { NunjucksService } from './engines/nunjucks/nunjucks.service';\nimport { PugService } from './engines/pug/pug.service';\nimport { requireService } from './libs/requireService.utils';\nimport type { PuppeteerParameters } from './puppeteer-parameters.interface';\n\n@Injectable()\nexport class PuppeteerService {\n readonly #browserService: BrowserService;\n readonly #options: PuppeteerParameters;\n readonly #hbsService?: HandlebarsService;\n readonly #mjmlService?: MjmlService;\n readonly #pugService?: PugService;\n readonly #ejsService?: EjsService;\n readonly #nunjucksService?: NunjucksService;\n readonly #etaService?: EtaService;\n readonly #mustacheService?: MustacheService;\n\n constructor(\n browserService: BrowserService,\n @Inject(PDF_PARAMETERS) options: PuppeteerParameters,\n @Optional() hbsService?: HandlebarsService,\n @Optional() mjmlService?: MjmlService,\n @Optional() pugService?: PugService,\n @Optional() ejsService?: EjsService,\n @Optional() nunjucksService?: NunjucksService,\n @Optional() etaService?: EtaService,\n @Optional() mustacheService?: MustacheService,\n ) {\n this.#browserService = browserService;\n this.#options = options;\n this.#hbsService = hbsService;\n this.#mjmlService = mjmlService;\n this.#pugService = pugService;\n this.#ejsService = ejsService;\n this.#nunjucksService = nunjucksService;\n this.#etaService = etaService;\n this.#mustacheService = mustacheService;\n }\n\n readonly #limit = pLimit(3);\n\n async generatePdfFromHtml(\n html: string,\n options?: PuppeteerParameters,\n ): Promise<Uint8Array> {\n const signal = options?.signal ?? this.#options.signal;\n signal?.throwIfAborted();\n\n let started = false;\n const job = this.#limit(async () => {\n signal?.throwIfAborted();\n started = true;\n\n const mergePuppeteerOptions = mergePuppeteerParameters(\n this.#options,\n options,\n );\n if (mergePuppeteerOptions.chromiumRevision !== undefined) {\n Logger.warn(\n 'Using `chromiumRevision` is no longer supported since the puppeteer update.',\n );\n }\n\n const headless: boolean | 'shell' =\n mergePuppeteerOptions.headless ?? true;\n\n const executablePath = mergePuppeteerOptions.executablePath || undefined;\n\n //src: https://www.bannerbear.com/blog/ways-to-speed-up-puppeteer-screenshots/\n const args = mergePuppeteerOptions.extraPuppeteerArgs || [\n '--autoplay-policy=user-gesture-required',\n '--disable-background-networking',\n '--disable-background-timer-throttling',\n '--disable-backgrounding-occluded-windows',\n '--disable-breakpad',\n '--disable-client-side-phishing-detection',\n '--disable-component-update',\n '--disable-default-apps',\n '--disable-dev-shm-usage',\n '--disable-domain-reliability',\n '--disable-extensions',\n '--disable-features=AudioServiceOutOfProcess',\n '--disable-hang-monitor',\n '--disable-ipc-flooding-protection',\n '--disable-notifications',\n '--disable-offer-store-unmasked-wallet-cards',\n '--disable-print-preview',\n '--disable-prompt-on-repost',\n '--disable-renderer-backgrounding',\n '--disable-setuid-sandbox',\n '--disable-speech-api',\n '--disable-sync',\n '--hide-scrollbars',\n '--ignore-gpu-blacklist',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-default-browser-check',\n '--no-first-run',\n '--no-pings',\n '--password-store=basic',\n '--use-gl=swiftshader',\n '--use-mock-keychain',\n '--disable-accelerated-2d-canvas',\n '--no-zygote',\n '--disable-gpu',\n ];\n\n this.#browserService.markJobStarted();\n let context: Awaited<ReturnType<BrowserService['createContext']>> | null =\n null;\n\n let closing: Promise<void> | undefined;\n const onAbort = () => {\n if (!context) return;\n closing = context.close();\n closing.catch(() => undefined);\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n context = await this.#browserService.createContext(\n args,\n headless,\n executablePath,\n );\n signal?.throwIfAborted();\n const page = await context.newPage();\n if (mergePuppeteerOptions.security) {\n await installRequestGuard(\n context,\n page,\n mergePuppeteerOptions.security,\n );\n }\n\n const pdfOptions: PDFOptions = mergePuppeteerOptions.pdfOptions ?? {\n format: 'A4',\n };\n\n await page.setContent(html, { waitUntil: 'domcontentloaded' });\n await page.emulateMediaType('screen');\n await page.waitForNetworkIdle({ idleTime: 500, timeout: 30000 });\n // Executes inside the browser page context via Puppeteer, not in Node — unreachable by unit tests.\n /* v8 ignore next */\n await page.evaluate(() => document.fonts.ready);\n\n const pdf = await page.pdf(pdfOptions);\n signal?.throwIfAborted();\n return mergePuppeteerOptions.watermark\n ? await addWatermark(pdf, mergePuppeteerOptions.watermark)\n : pdf;\n } catch (e) {\n if (signal?.aborted) {\n throw signal.reason;\n }\n Logger.error(e);\n if (e instanceof NestjsPdfException) {\n throw e;\n }\n throw new PdfGenerationException(\n `PDF generation failed: ${String(e)}`,\n { cause: e },\n );\n } finally {\n signal?.removeEventListener('abort', onAbort);\n if (context) {\n try {\n if (closing) await closing;\n else await context.close();\n } catch (error) {\n Logger.error(error);\n }\n }\n await this.#browserService.markJobFinished();\n }\n });\n\n if (!signal) {\n return job;\n }\n\n let onQueuedAbort!: () => void;\n const abortedWhileQueued = new Promise<never>((_, reject) => {\n onQueuedAbort = () => {\n // An abort reason can be any value; callers expect the exact one they passed.\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n if (!started) reject(signal.reason);\n };\n signal.addEventListener('abort', onQueuedAbort, { once: true });\n });\n try {\n return await Promise.race([job, abortedWhileQueued]);\n } finally {\n signal.removeEventListener('abort', onQueuedAbort);\n }\n }\n\n async generatePdfFromTemplateHbsString(\n template: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n const hbsService = requireService(this.#hbsService, 'Handlebars');\n const html = hbsService.render(\n template,\n parameters,\n options?.hbsOptions ?? this.#options.hbsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromTemplateHbsFile(\n file: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n const hbsService = requireService(this.#hbsService, 'Handlebars');\n const html = hbsService.renderFile(\n file,\n parameters,\n options?.hbsOptions ?? this.#options.hbsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMjmlString(\n template: string,\n options?: PuppeteerParameters,\n ) {\n const mjmlService = requireService(this.#mjmlService, 'MJML');\n const html = await mjmlService.render(\n template,\n options?.mjmlOptions ?? this.#options.mjmlOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMjmlFile(file: string, options?: PuppeteerParameters) {\n const mjmlService = requireService(this.#mjmlService, 'MJML');\n const html = await mjmlService.renderFile(\n file,\n options?.mjmlOptions ?? this.#options.mjmlOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromPugString(\n template: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n const pugService = requireService(this.#pugService, 'Pug');\n const html = pugService.render(\n template,\n data,\n options?.pugOptions ?? this.#options.pugOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromPugFile(\n file: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n const pugService = requireService(this.#pugService, 'Pug');\n const html = pugService.renderFile(\n file,\n data,\n options?.pugOptions ?? this.#options.pugOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEjsString(\n template: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n const ejsService = requireService(this.#ejsService, 'EJS');\n const html = await ejsService.render(\n template,\n data,\n options?.ejsOptions ?? this.#options.ejsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEjsFile(\n file: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n const ejsService = requireService(this.#ejsService, 'EJS');\n const html = await ejsService.renderFile(\n file,\n data,\n options?.ejsOptions ?? this.#options.ejsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromNunjucksString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const nunjucksService = requireService(this.#nunjucksService, 'Nunjucks');\n const html = nunjucksService.render(\n template,\n data,\n options?.nunjucksOptions ?? this.#options.nunjucksOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromNunjucksFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const nunjucksService = requireService(this.#nunjucksService, 'Nunjucks');\n const html = nunjucksService.renderFile(\n file,\n data,\n options?.nunjucksOptions ?? this.#options.nunjucksOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEtaString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const etaService = requireService(this.#etaService, 'Eta');\n const html = etaService.render(\n template,\n data,\n options?.etaOptions ?? this.#options.etaOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEtaFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const etaService = requireService(this.#etaService, 'Eta');\n const html = etaService.renderFile(\n file,\n data,\n options?.etaOptions ?? this.#options.etaOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMustacheString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const mustacheService = requireService(this.#mustacheService, 'Mustache');\n const html = mustacheService.render(\n template,\n data,\n options?.mustacheOptions ?? this.#options.mustacheOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMustacheFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const mustacheService = requireService(this.#mustacheService, 'Mustache');\n const html = mustacheService.renderFile(\n file,\n data,\n options?.mustacheOptions ?? this.#options.mustacheOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { Data } from 'ejs';\nimport { LocalsObject } from 'pug';\n\nimport { addSignatureFieldUsingAnchor } from './helpers/signature.helper';\nimport {\n addWatermark,\n type WatermarkOptions,\n} from './helpers/watermark.helper';\nimport { PuppeteerService } from './puppeteer/puppeteer.service';\nimport { PuppeteerParameters } from './puppeteer/puppeteer-parameters.interface';\n\n@Injectable()\nexport class NestjsPdfService {\n readonly #puppeteerService: PuppeteerService;\n\n constructor(puppeteerService: PuppeteerService) {\n this.#puppeteerService = puppeteerService;\n }\n\n /**\n * @param html HTML string to convert to PDF\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided HTML\n * @description This method uses the Puppeteer service to generate a PDF from an HTML string. Generation options can be customized by passing a `PuppeteerParameters` object as the second argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromHtml(html: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromHtml(html, options);\n }\n\n /**\n * @param template Handlebars template string\n * @param parameters Data parameters to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Handlebars template with parameters applied\n * @description This method generates a PDF from a Handlebars template provided as a string. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromTemplateHbsString(\n template: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromTemplateHbsString(\n template,\n parameters,\n options,\n );\n }\n\n /**\n * @param file Path to the Handlebars template file\n * @param parameters Data parameters to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Handlebars template at the provided file path with parameters applied\n * @description This method generates a PDF from a Handlebars template located at the specified file path. The file path is passed as a string in the `file` parameter. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromTemplateHbsFile(\n file: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromTemplateHbsFile(\n file,\n parameters,\n options,\n );\n }\n\n /**\n * @param template MJML template string\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided MJML template\n * @description This method generates a PDF from an MJML template provided as a string. MJML (MJML Markup Language) is a markup language designed to reduce the pain of coding a responsive email. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.\n */\n generatePdfFromMjmlString(template: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromMjmlString(template, options);\n }\n\n /**\n * @param file Path to the MJML template file\n * @param options PDF generation options (optional)\n * @returns PDF generated from the MJML template at the provided file path\n * @description This method generates a PDF from an MJML template located at the specified file path. The file path is passed as a string in the `file` parameter. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.\n */\n generatePdfFromMjmlFile(file: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromMjmlFile(file, options);\n }\n\n /**\n * @param template EJS template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided EJS template with data applied\n * @description This method generates a PDF from an EJS (Embedded JavaScript) template provided as a string. EJS is a templating language with a simple, straightforward syntax. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEjsString(\n template: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEjsString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the EJS template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the EJS template at the provided file path with data applied\n * @description This method generates a PDF from an EJS template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEjsFile(\n file: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEjsFile(file, data, options);\n }\n\n /**\n * @param template Pug template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Pug template with data applied\n * @description This method generates a PDF from a Pug template provided as a string. Pug is a clean, whitespace-sensitive syntax for writing HTML. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromPugString(\n template: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromPugString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Pug template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Pug template at the provided file path with data applied\n * @description This method generates a PDF from a Pug template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromPugFile(\n file: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromPugFile(file, data, options);\n }\n\n /**\n * @param template Nunjucks template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Nunjucks template with data applied\n * @description This method generates a PDF from a Nunjucks template provided as a string. Nunjucks is a powerful templating language with support for inheritance, macros, and filters. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromNunjucksString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromNunjucksString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Nunjucks template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Nunjucks template at the provided file path with data applied\n * @description This method generates a PDF from a Nunjucks template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromNunjucksFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromNunjucksFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param template Eta template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Eta template with data applied\n * @description This method generates a PDF from an Eta template provided as a string. Eta is a fast and lightweight embedded templating language with a syntax similar to EJS but with better performance. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEtaString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEtaString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Eta template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Eta template at the provided file path with data applied\n * @description This method generates a PDF from an Eta template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEtaFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEtaFile(file, data, options);\n }\n\n /**\n * @param template Mustache template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Mustache template with data applied\n * @description This method generates a PDF from a Mustache template provided as a string. Mustache is a logic-less template language that emphasizes readable and simple templates. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromMustacheString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromMustacheString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Mustache template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Mustache template at the provided file path with data applied\n * @description This method generates a PDF from a Mustache template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromMustacheFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromMustacheFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param pdf The PDF bytes to modify\n * @param fieldName The name of the signature field to add (default: 'SignatureDebtor')\n * @param anchorText The text anchor to locate the signature field position (default: '__SIG_DEBTOR_ANCHOR__')\n * @returns Modified PDF with a signature field added at the anchor position\n * @description This method adds a signature field to a PDF using a text anchor as a reference for the field position. It uses the `addSignatureFieldUsingAnchor` function which finds the anchor in the PDF and inserts a signature field at that location. The signature field is named according to the `fieldName` parameter and the anchor is defined by `anchorText`.\n *\n * Usage example:\n * ```typescript\n * const modifiedPdf = await pdfService.addSignatureFieldSignatureDebtorRaw(\n * originalPdfBytes,\n * 'SignatureDebtor',\n * '__SIG_DEBTOR_ANCHOR__'\n * );\n * ```\n *\n * In this example, `originalPdfBytes` is a byte array representing the original PDF, `SignatureDebtor` is the name of the signature field to add, and `__SIG_DEBTOR_ANCHOR__` is the anchor text used to position the signature field in the PDF.\n *\n * If the anchor is not found, the signature field will be added at a default position (centered at the bottom of the last page).\n *\n * Note: Ensure that the input PDF contains the anchor defined by `anchorText` for the signature field to be positioned correctly. Otherwise, it will be added at a default position.\n */\n async addSignatureFieldSignatureDebtorRaw(\n pdf: Uint8Array | Buffer,\n fieldName: string = 'SignatureDebtor',\n anchorText: string = '__SIG_DEBTOR_ANCHOR__',\n ) {\n return await addSignatureFieldUsingAnchor(pdf, fieldName, anchorText);\n }\n\n /**\n * @param pdf The PDF bytes to modify\n * @param options Watermark options (`text` or `image` is required)\n * @returns Modified PDF with the watermark stamped on the selected pages\n * @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`.\n *\n * ```typescript\n * const watermarked = await pdfService.addWatermark(pdf, {\n * text: 'CONFIDENTIAL',\n * color: '#ff0000',\n * opacity: 0.2,\n * });\n * ```\n *\n * Text uses the PDF standard fonts, which only support WinAnsi characters; use an `image` for anything else.\n * @throws WatermarkException when the options are invalid or the PDF cannot be processed\n */\n async addWatermark(pdf: Uint8Array | Buffer, options: WatermarkOptions) {\n return await addWatermark(pdf, options);\n }\n}\n","import {\n DynamicModule,\n Inject,\n InjectionToken,\n Module,\n ModuleMetadata,\n OnModuleInit,\n OptionalFactoryDependency,\n Provider,\n} from '@nestjs/common';\n\nimport { PDF_PARAMETERS } from '../helpers/tokens';\nimport { BrowserService } from './browser/browser.service';\nimport { EjsService } from './engines/ejs/ejs.service';\nimport { EtaService } from './engines/eta/eta.service';\nimport { HandlebarsService } from './engines/handlebars/handlebars.service';\nimport { MjmlService } from './engines/mjml/mjml.service';\nimport { MustacheService } from './engines/mustache/mustache.service';\nimport { NunjucksService } from './engines/nunjucks/nunjucks.service';\nimport { PugService } from './engines/pug/pug.service';\nimport { PuppeteerService } from './puppeteer.service';\nimport type { PuppeteerParameters } from './puppeteer-parameters.interface';\n\nexport interface PuppeteerModuleAsyncOptions extends Pick<\n ModuleMetadata,\n 'imports'\n> {\n inject?: Array<InjectionToken | OptionalFactoryDependency>;\n useFactory: (\n ...args: Array<any>\n ) => Promise<PuppeteerParameters> | PuppeteerParameters;\n}\n\n@Module({\n providers: [\n PuppeteerService,\n BrowserService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n})\nexport class PuppeteerModule implements OnModuleInit {\n readonly #browserService: BrowserService;\n readonly #pdfParams: PuppeteerParameters;\n\n constructor(\n browserService: BrowserService,\n @Inject(PDF_PARAMETERS) pdfParams: PuppeteerParameters,\n ) {\n this.#browserService = browserService;\n this.#pdfParams = pdfParams;\n }\n\n async onModuleInit() {\n if (!this.#pdfParams.executablePath) {\n await this.#browserService.install(\n this.#pdfParams.useLockedBrowser ?? false,\n );\n }\n }\n\n static forRoot(pdfParameters: PuppeteerParameters): DynamicModule {\n const providers: Array<Provider> = [\n {\n provide: PDF_PARAMETERS,\n useValue: pdfParameters,\n },\n HandlebarsService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ];\n\n return {\n module: PuppeteerModule,\n providers,\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n };\n }\n\n static forRootAsync(options: PuppeteerModuleAsyncOptions): DynamicModule {\n const pdfParamsProvider: Provider = {\n provide: PDF_PARAMETERS,\n inject: options.inject ?? [],\n useFactory: async (...args: Array<unknown>) =>\n options.useFactory(...args),\n };\n\n return {\n module: PuppeteerModule,\n imports: options.imports ?? [],\n providers: [\n pdfParamsProvider,\n PuppeteerService,\n BrowserService,\n HandlebarsService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n };\n }\n}\n","import { DynamicModule, Module, ModuleMetadata } from '@nestjs/common';\n\nimport { NestjsPdfService } from './nestjs-pdf.service';\nimport { PuppeteerModule } from './puppeteer/puppeteer.module';\nimport { PuppeteerParameters } from './puppeteer/puppeteer-parameters.interface';\n\nexport interface PdfLibModuleAsyncOptions extends Pick<\n ModuleMetadata,\n 'imports'\n> {\n inject?: Array<any>;\n useFactory: (...args: Array<any>) => any;\n}\n\n@Module({})\nexport class NestjsPdfModule {\n static forRoot(options: PuppeteerParameters): DynamicModule {\n return {\n module: NestjsPdfModule,\n imports: [PuppeteerModule.forRoot(options)],\n providers: [NestjsPdfService],\n exports: [NestjsPdfService],\n };\n }\n\n static forRootAsync(options: PdfLibModuleAsyncOptions): DynamicModule {\n return {\n module: NestjsPdfModule,\n imports: [PuppeteerModule.forRootAsync(options)],\n providers: [NestjsPdfService],\n exports: [NestjsPdfService],\n };\n }\n}\n"],"x_google_ignoreList":[13,14],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["BrowserType"],"sources":["../src/exceptions/nestjs-pdf.exception.ts","../src/exceptions/browser-installation.exception.ts","../src/exceptions/browser-unavailable.exception.ts","../src/exceptions/engine-not-available.exception.ts","../src/exceptions/pdf-generation.exception.ts","../src/exceptions/signature-dependency.exception.ts","../src/exceptions/signature-placement.exception.ts","../src/exceptions/template-configuration.exception.ts","../src/exceptions/template-render.exception.ts","../src/exceptions/watermark.exception.ts","../src/helpers/getRelativePath.helper.ts","../src/helpers/signature.helper.ts","../src/helpers/watermark.helper.ts","../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js","../node_modules/.pnpm/p-limit@7.3.3/node_modules/p-limit/index.js","../src/helpers/deepMergePdfparams.ts","../src/helpers/request-guard.helper.ts","../src/helpers/tokens.ts","../src/puppeteer/browser/browser.service.ts","../src/puppeteer/libs/loadEngine.utils.ts","../src/puppeteer/engines/ejs/ejs.service.ts","../src/puppeteer/engines/eta/eta.service.ts","../src/puppeteer/engines/handlebars/handlebars.service.ts","../src/puppeteer/engines/liquid/liquid.service.ts","../src/puppeteer/engines/mjml/mjml.service.ts","../src/puppeteer/engines/mustache/mustache.service.ts","../src/puppeteer/engines/nunjucks/nunjucks.service.ts","../src/puppeteer/engines/pug/pug.service.ts","../src/puppeteer/libs/requireService.utils.ts","../src/puppeteer/puppeteer.service.ts","../src/nestjs-pdf.service.ts","../src/puppeteer/puppeteer.module.ts","../src/nestjs-pdf.module.ts"],"sourcesContent":["export enum NestjsPdfErrorCode {\n ENGINE_NOT_AVAILABLE = 'ENGINE_NOT_AVAILABLE',\n TEMPLATE_CONFIGURATION_ERROR = 'TEMPLATE_CONFIGURATION_ERROR',\n TEMPLATE_RENDER_ERROR = 'TEMPLATE_RENDER_ERROR',\n BROWSER_INSTALLATION_ERROR = 'BROWSER_INSTALLATION_ERROR',\n BROWSER_UNAVAILABLE = 'BROWSER_UNAVAILABLE',\n PDF_GENERATION_ERROR = 'PDF_GENERATION_ERROR',\n SIGNATURE_DEPENDENCY_ERROR = 'SIGNATURE_DEPENDENCY_ERROR',\n SIGNATURE_PLACEMENT_ERROR = 'SIGNATURE_PLACEMENT_ERROR',\n WATERMARK_ERROR = 'WATERMARK_ERROR',\n}\n\nexport abstract class NestjsPdfException extends Error {\n abstract readonly code: NestjsPdfErrorCode;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = this.constructor.name;\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class BrowserInstallationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.BROWSER_INSTALLATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class BrowserUnavailableException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.BROWSER_UNAVAILABLE;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class EngineNotAvailableException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.ENGINE_NOT_AVAILABLE;\n\n constructor(\n engineName: string,\n packageName?: string,\n options?: { cause?: unknown },\n ) {\n super(\n packageName\n ? `${engineName} engine is not available: the '${packageName}' package is not installed. Run \\`npm install ${packageName}\\` to use it.`\n : `${engineName} service is not available. If the problem persists, open an issue in the repo.`,\n options,\n );\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class PdfGenerationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.PDF_GENERATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class SignatureDependencyException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.SIGNATURE_DEPENDENCY_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class SignaturePlacementException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.SIGNATURE_PLACEMENT_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class TemplateConfigurationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.TEMPLATE_CONFIGURATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class TemplateRenderException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.TEMPLATE_RENDER_ERROR;\n\n constructor(\n public readonly engine: string,\n message: string,\n options?: { cause?: unknown },\n ) {\n super(message, options);\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class WatermarkException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.WATERMARK_ERROR;\n}\n","import { relative, resolve } from 'node:path';\n\n/**\n * Get the relative path to a value from the module directory.\n * @param moduleDir the path of the module, typically __dirname\n * @param relativeToModule the path to the value relative to the module directory\n * @returns the relative path from the current working directory to the value\n * @example\n * getRelativePathToValue(__dirname, './templates/my-template.hbs');\n * // returns 'context/pdf/templates/my-template.hbs' if the current working directory is '/\n */\nexport function getRelativePathToValue(\n moduleDir: string,\n relativeToModule: string,\n): string {\n const fullTemplatePath = resolve(moduleDir, relativeToModule);\n return relative(process.cwd(), fullTemplatePath);\n}\n","import {\n PDFArray,\n PDFDict,\n PDFDocument,\n PDFName,\n PDFNumber,\n PDFString,\n} from 'pdf-lib';\nimport type { TextItem } from 'pdfjs-dist/types/src/display/api';\n\nimport {\n SignatureDependencyException,\n SignaturePlacementException,\n} from '../exceptions';\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet pdfjsPromise: typeof import('pdfjs-dist/legacy/build/pdf.mjs') | undefined;\n\nasync function loadPdfjs() {\n if (!pdfjsPromise) {\n try {\n pdfjsPromise = await import('pdfjs-dist/legacy/build/pdf.mjs');\n } catch (error) {\n pdfjsPromise = undefined;\n /* v8 ignore next -- import() rejections are always Error instances in practice */\n const reason = error instanceof Error ? error.message : String(error);\n throw new SignatureDependencyException(\n [\n 'Failed to load pdfjs-dist.',\n 'If you use anchor-based signature placement in Node.js, make sure @napi-rs/canvas is installed.',\n 'Try: npm install @napi-rs/canvas',\n '',\n `Original error: ${reason}`,\n ].join('\\n'),\n { cause: error },\n );\n }\n }\n return pdfjsPromise;\n}\n\nfunction toU8(input: Uint8Array | Buffer): Uint8Array {\n return new Uint8Array(input);\n}\n\nasync function findAnchorPosition(\n pdfBytes: Uint8Array,\n anchorText: string,\n): Promise<null | {\n pageIndex: number;\n x: number;\n y: number;\n pageWidth: number;\n pageHeight: number;\n}> {\n const pdfjsLib = await loadPdfjs();\n const loadingTask = pdfjsLib.getDocument({ data: pdfBytes });\n\n try {\n const pdf = await loadingTask.promise;\n\n for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\n const page = await pdf.getPage(pageNum);\n const viewport = page.getViewport({ scale: 1 });\n const textContent = await page.getTextContent();\n\n for (const itemRaw of textContent.items) {\n const item = itemRaw as TextItem;\n const str = item.str;\n if (!str?.includes(anchorText)) continue;\n\n const t = pdfjsLib.Util.transform(viewport.transform, item.transform);\n const [_a, _b, _c, _d, e, f] = t as Array<number>;\n\n const x = e;\n const y = viewport.height - f;\n\n return {\n pageIndex: pageNum - 1,\n x,\n y,\n pageWidth: viewport.width,\n pageHeight: viewport.height,\n };\n }\n }\n return null;\n } finally {\n await loadingTask.destroy();\n }\n}\n\nfunction addSignatureFieldAt(\n pdfDoc: PDFDocument,\n pageIndex: number,\n opts: {\n fieldName: string;\n x: number;\n y: number;\n width: number;\n height: number;\n },\n) {\n const { fieldName, x, y, width, height } = opts;\n const context = pdfDoc.context;\n\n const page = pdfDoc.getPages()[pageIndex];\n\n const rectArray = context.obj([\n PDFNumber.of(x),\n PDFNumber.of(y),\n PDFNumber.of(x + width),\n PDFNumber.of(y + height),\n ]);\n\n const widgetDict = context.obj({\n Type: PDFName.of('Annot'),\n Subtype: PDFName.of('Widget'),\n Rect: rectArray,\n F: PDFNumber.of(4),\n P: page.ref,\n });\n const widgetRef = context.register(widgetDict);\n\n const fieldDict = context.obj({\n FT: PDFName.of('Sig'),\n T: PDFString.of(fieldName),\n Ff: PDFNumber.of(0),\n Kids: context.obj([widgetRef]),\n });\n const fieldRef = context.register(fieldDict);\n\n widgetDict.set(PDFName.of('Parent'), fieldRef);\n\n let annots = page.node.lookupMaybe(PDFName.of('Annots'), PDFArray);\n if (!annots) {\n annots = context.obj([]);\n page.node.set(PDFName.of('Annots'), annots);\n }\n annots.push(widgetRef);\n\n let acroForm = pdfDoc.catalog.lookupMaybe(PDFName.of('AcroForm'), PDFDict);\n if (!acroForm) {\n acroForm = context.obj({\n Fields: context.obj([]),\n SigFlags: PDFNumber.of(3),\n });\n const acroFormRef = context.register(acroForm);\n pdfDoc.catalog.set(PDFName.of('AcroForm'), acroFormRef);\n }\n\n let fields = acroForm.lookupMaybe(PDFName.of('Fields'), PDFArray);\n if (!fields) {\n fields = context.obj([]);\n acroForm.set(PDFName.of('Fields'), fields);\n }\n fields.push(fieldRef);\n\n return { fieldRef, widgetRef };\n}\n\nexport async function addSignatureFieldUsingAnchor(\n pdf: Uint8Array | Buffer,\n fieldName = 'SignatureDebtor',\n anchorText = '__SIG_DEBTOR_ANCHOR__',\n) {\n const bytes = toU8(pdf);\n\n const anchor = await findAnchorPosition(bytes.slice(), anchorText);\n\n const pdfDoc = await PDFDocument.load(bytes);\n\n const sigWidth = 240;\n const sigHeight = 50;\n\n if (anchor) {\n const pageIndex = anchor.pageIndex;\n const page = pdfDoc.getPages()[pageIndex];\n if (!page) {\n throw new SignaturePlacementException(`Page ${pageIndex} not found`);\n }\n const { width: pw, height: ph } = page.getSize();\n\n const padX = 40;\n const padY = 7;\n let x = anchor.x - sigWidth / 2 + padX;\n\n let y = anchor.y - sigHeight + padY;\n\n const margin = 10;\n\n x = Math.max(margin, Math.min(x, pw - sigWidth - margin));\n y = Math.max(margin, Math.min(y, ph - sigHeight - margin));\n\n addSignatureFieldAt(pdfDoc, anchor.pageIndex, {\n fieldName,\n x,\n y,\n width: sigWidth,\n height: sigHeight,\n });\n } else {\n const pages = pdfDoc.getPages();\n const pageIndex = pages.length - 1;\n const page = pages.at(-1);\n /* v8 ignore next -- pdf-lib always produces at least one page on save/load; only a hand-crafted, malformed PDF could hit this */\n if (!page) {\n throw new SignaturePlacementException(`Page ${pageIndex} not found`);\n }\n const { width: pageWidth } = page.getSize();\n const x = (pageWidth - sigWidth) / 2;\n const y = 90;\n\n addSignatureFieldAt(pdfDoc, pageIndex, {\n fieldName,\n x,\n y,\n width: sigWidth,\n height: sigHeight,\n });\n }\n\n return await pdfDoc.save();\n}\n\n// Test helper to inject a mocked pdfjs implementation and avoid dynamic import in tests\n// This helper throws outside of tests to avoid exposing a test-only API in production.\nexport function __setPdfjsForTests(p: any) {\n if (process.env.NODE_ENV !== 'test') {\n throw new Error('__setPdfjsForTests is only available in test environment');\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n pdfjsPromise = p;\n}\n","import {\n degrees,\n PDFDocument,\n type PDFImage,\n type PDFPage,\n rgb,\n StandardFonts,\n} from 'pdf-lib';\n\nimport { WatermarkException } from '../exceptions';\n\nexport interface WatermarkOptions {\n /** Text to stamp. At least one of `text` or `image` is required. */\n text?: string;\n /** PNG or JPEG bytes to stamp. At least one of `text` or `image` is required. */\n image?: Uint8Array | Buffer;\n /** Opacity between 0 (invisible) and 1 (opaque). Default: 0.15 */\n opacity?: number;\n /** Counter-clockwise rotation in degrees. Default: 45 */\n rotation?: number;\n /** Text font size in points. Default: 60 */\n fontSize?: number;\n /** One of the PDF standard fonts (WinAnsi characters only). Default: 'HelveticaBold' */\n font?: keyof typeof StandardFonts;\n /** Text color as `#rgb` or `#rrggbb`. Default: '#808080' */\n color?: string;\n /** Rendered image width in points (aspect ratio preserved). Default: 50% of the page width */\n imageWidth?: number;\n /** `center` stamps once per page, `tile` repeats the mark across the page. Default: 'center' */\n position?: 'center' | 'tile';\n /** Gap in points between two marks when `position` is `tile`. Default: 100 */\n tileSpacing?: number;\n /** 1-based page numbers to watermark. Default: all pages */\n pages?: Array<number>;\n}\n\nconst DEFAULT_OPACITY = 0.15;\nconst DEFAULT_ROTATION = 45;\nconst DEFAULT_FONT_SIZE = 60;\nconst DEFAULT_FONT: keyof typeof StandardFonts = 'HelveticaBold';\nconst DEFAULT_COLOR = '#808080';\nconst DEFAULT_TILE_SPACING = 100;\n\ninterface Mark {\n width: number;\n height: number;\n draw: (page: PDFPage, x: number, y: number) => void;\n}\n\nfunction parseHexColor(color: string) {\n const match = /^#([\\da-f]{3}|[\\da-f]{6})$/i.exec(color);\n if (!match) {\n throw new WatermarkException(\n `Invalid watermark color \"${color}\", expected #rgb or #rrggbb`,\n );\n }\n const hex =\n match[1].length === 3 ? [...match[1]].map((c) => c + c).join('') : match[1];\n const channel = (i: number) => Number.parseInt(hex.slice(i, i + 2), 16) / 255;\n return rgb(channel(0), channel(2), channel(4));\n}\n\nfunction embedImage(pdfDoc: PDFDocument, bytes: Uint8Array): Promise<PDFImage> {\n const isPng = bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e;\n const isJpeg = bytes[0] === 0xff && bytes[1] === 0xd8;\n if (isPng) return pdfDoc.embedPng(bytes);\n if (isJpeg) return pdfDoc.embedJpg(bytes);\n throw new WatermarkException('Watermark image must be a PNG or JPEG');\n}\n\nfunction validate(options: WatermarkOptions) {\n const { text, image, opacity, fontSize, imageWidth, tileSpacing } = options;\n if (!text && !image) {\n throw new WatermarkException(\n 'A watermark requires at least a `text` or an `image`',\n );\n }\n if (opacity !== undefined && !(opacity >= 0 && opacity <= 1)) {\n throw new WatermarkException('Watermark `opacity` must be between 0 and 1');\n }\n if (fontSize !== undefined && !(fontSize > 0)) {\n throw new WatermarkException('Watermark `fontSize` must be greater than 0');\n }\n if (imageWidth !== undefined && !(imageWidth > 0)) {\n throw new WatermarkException(\n 'Watermark `imageWidth` must be greater than 0',\n );\n }\n if (tileSpacing !== undefined && !(tileSpacing >= 0)) {\n throw new WatermarkException('Watermark `tileSpacing` must be at least 0');\n }\n}\n\nfunction resolvePageIndexes(pages: Array<number> | undefined, total: number) {\n if (!pages) {\n return Array.from({ length: total }, (_, i) => i);\n }\n for (const page of pages) {\n if (!Number.isInteger(page) || page < 1 || page > total) {\n throw new WatermarkException(\n `Watermark page ${page} is out of range (the PDF has ${total} page(s))`,\n );\n }\n }\n return [...new Set(pages)].map((page) => page - 1);\n}\n\n/**\n * Centers of the marks for one page, in page coordinates. Tiles follow the\n * rotated axes so rotated marks never overlap each other.\n */\nfunction markCenters(\n pageWidth: number,\n pageHeight: number,\n mark: Mark,\n options: { position: 'center' | 'tile'; rotation: number; spacing: number },\n) {\n const cx = pageWidth / 2;\n const cy = pageHeight / 2;\n if (options.position === 'center') {\n return [{ x: cx, y: cy }];\n }\n\n const theta = (options.rotation * Math.PI) / 180;\n const cos = Math.cos(theta);\n const sin = Math.sin(theta);\n const stepX = mark.width + options.spacing;\n const stepY = mark.height + options.spacing;\n const reach = Math.hypot(mark.width, mark.height) / 2;\n const n = Math.ceil(\n (Math.hypot(pageWidth, pageHeight) / 2 + reach) / Math.min(stepX, stepY),\n );\n\n const centers: Array<{ x: number; y: number }> = [];\n for (let i = -n; i <= n; i++) {\n for (let j = -n; j <= n; j++) {\n const x = cx + i * stepX * cos - j * stepY * sin;\n const y = cy + i * stepX * sin + j * stepY * cos;\n if (\n x >= -reach &&\n x <= pageWidth + reach &&\n y >= -reach &&\n y <= pageHeight + reach\n ) {\n centers.push({ x, y });\n }\n }\n }\n return centers;\n}\n\nasync function buildMark(\n pdfDoc: PDFDocument,\n options: WatermarkOptions,\n pageWidth: number,\n): Promise<Mark> {\n const opacity = options.opacity ?? DEFAULT_OPACITY;\n const rotate = degrees(options.rotation ?? DEFAULT_ROTATION);\n\n if (options.image) {\n const image = await embedImage(pdfDoc, new Uint8Array(options.image));\n const width = options.imageWidth ?? pageWidth / 2;\n const height = (image.height / image.width) * width;\n return {\n width,\n height,\n draw: (page, x, y) =>\n page.drawImage(image, { x, y, width, height, opacity, rotate }),\n };\n }\n\n const font = await pdfDoc.embedFont(\n StandardFonts[options.font ?? DEFAULT_FONT],\n );\n const size = options.fontSize ?? DEFAULT_FONT_SIZE;\n const text = options.text!;\n const color = parseHexColor(options.color ?? DEFAULT_COLOR);\n let width: number;\n try {\n width = font.widthOfTextAtSize(text, size);\n } catch (error) {\n throw new WatermarkException(\n `Watermark text cannot be rendered with the ${options.font ?? DEFAULT_FONT} font (only WinAnsi characters are supported)`,\n { cause: error },\n );\n }\n return {\n width,\n height: font.heightAtSize(size, { descender: false }),\n draw: (page, x, y) =>\n page.drawText(text, { x, y, size, font, color, opacity, rotate }),\n };\n}\n\n/**\n * Stamps a text or image watermark on the pages of an existing PDF.\n */\nexport async function addWatermark(\n pdf: Uint8Array | Buffer,\n options: WatermarkOptions,\n): Promise<Uint8Array> {\n validate(options);\n\n try {\n const pdfDoc = await PDFDocument.load(new Uint8Array(pdf));\n const pages = pdfDoc.getPages();\n const indexes = resolvePageIndexes(options.pages, pages.length);\n\n const position = options.position ?? 'center';\n const rotation = options.rotation ?? DEFAULT_ROTATION;\n const spacing = options.tileSpacing ?? DEFAULT_TILE_SPACING;\n const theta = (rotation * Math.PI) / 180;\n const cos = Math.cos(theta);\n const sin = Math.sin(theta);\n\n // The image width depends on the page width, so marks are cached per width.\n const marks = new Map<number, Mark>();\n\n for (const index of indexes) {\n const page = pages[index];\n const { width: pageWidth, height: pageHeight } = page.getSize();\n\n let mark = marks.get(pageWidth);\n if (!mark) {\n mark = await buildMark(pdfDoc, options, pageWidth);\n marks.set(pageWidth, mark);\n }\n\n for (const center of markCenters(pageWidth, pageHeight, mark, {\n position,\n rotation,\n spacing,\n })) {\n // drawText/drawImage rotate around the bottom-left corner, so shift\n // the origin to make the mark's own center land on `center`.\n mark.draw(\n page,\n center.x - ((mark.width / 2) * cos - (mark.height / 2) * sin),\n center.y - ((mark.width / 2) * sin + (mark.height / 2) * cos),\n );\n }\n }\n\n return await pdfDoc.save();\n } catch (error) {\n if (error instanceof WatermarkException) throw error;\n throw new WatermarkException(\n `Failed to add watermark: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n}\n","/*\nHow it works:\n`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.\n*/\n\nclass Node {\n\tvalue;\n\tnext;\n\n\tconstructor(value) {\n\t\tthis.value = value;\n\t}\n}\n\nexport default class Queue {\n\t#head;\n\t#tail;\n\t#size;\n\n\tconstructor() {\n\t\tthis.clear();\n\t}\n\n\tenqueue(value) {\n\t\tconst node = new Node(value);\n\n\t\tif (this.#head) {\n\t\t\tthis.#tail.next = node;\n\t\t\tthis.#tail = node;\n\t\t} else {\n\t\t\tthis.#head = node;\n\t\t\tthis.#tail = node;\n\t\t}\n\n\t\tthis.#size++;\n\t}\n\n\tdequeue() {\n\t\tconst current = this.#head;\n\t\tif (!current) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#head = this.#head.next;\n\t\tthis.#size--;\n\n\t\t// Clean up tail reference when queue becomes empty\n\t\tif (!this.#head) {\n\t\t\tthis.#tail = undefined;\n\t\t}\n\n\t\treturn current.value;\n\t}\n\n\tpeek() {\n\t\tif (!this.#head) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this.#head.value;\n\n\t\t// TODO: Node.js 18.\n\t\t// return this.#head?.value;\n\t}\n\n\tclear() {\n\t\tthis.#head = undefined;\n\t\tthis.#tail = undefined;\n\t\tthis.#size = 0;\n\t}\n\n\tget size() {\n\t\treturn this.#size;\n\t}\n\n\t* [Symbol.iterator]() {\n\t\tlet current = this.#head;\n\n\t\twhile (current) {\n\t\t\tyield current.value;\n\t\t\tcurrent = current.next;\n\t\t}\n\t}\n\n\t* drain() {\n\t\twhile (this.#head) {\n\t\t\tyield this.dequeue();\n\t\t}\n\t}\n}\n","import Queue from 'yocto-queue';\n\nexport default function pLimit(concurrency) {\n\tlet rejectOnClear = false;\n\n\tif (typeof concurrency === 'object') {\n\t\t({concurrency, rejectOnClear = false} = concurrency);\n\t}\n\n\tvalidateConcurrency(concurrency);\n\n\tif (typeof rejectOnClear !== 'boolean') {\n\t\tthrow new TypeError('Expected `rejectOnClear` to be a boolean');\n\t}\n\n\tconst queue = new Queue();\n\tlet activeCount = 0;\n\n\tconst resumeNext = () => {\n\t\t// Process the next queued function if we're under the concurrency limit\n\t\tif (activeCount < concurrency && queue.size > 0) {\n\t\t\tactiveCount++;\n\t\t\tqueue.dequeue().run();\n\t\t}\n\t};\n\n\tconst next = () => {\n\t\tactiveCount--;\n\t\tresumeNext();\n\t};\n\n\tconst run = async (function_, resolve, arguments_) => {\n\t\t// Execute the function and capture the result promise\n\t\tconst result = (async () => function_(...arguments_))();\n\n\t\t// Resolve immediately with the promise (don't wait for completion)\n\t\tresolve(result);\n\n\t\t// Wait for the function to complete (success or failure)\n\t\t// We catch errors here to prevent unhandled rejections,\n\t\t// but the original promise rejection is preserved for the caller\n\t\ttry {\n\t\t\tawait result;\n\t\t} catch {}\n\n\t\t// Decrement active count and process next queued function\n\t\tnext();\n\t};\n\n\tconst enqueue = (function_, resolve, reject, arguments_) => {\n\t\tconst queueItem = {reject};\n\n\t\t// Queue the internal resolve function instead of the run function\n\t\t// to preserve the asynchronous execution context.\n\t\tnew Promise(internalResolve => { // eslint-disable-line promise/param-names\n\t\t\tqueueItem.run = internalResolve;\n\t\t\tqueue.enqueue(queueItem);\n\t\t}).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then\n\n\t\t// Start processing immediately if we haven't reached the concurrency limit\n\t\tif (activeCount < concurrency) {\n\t\t\tresumeNext();\n\t\t}\n\t};\n\n\tconst generator = (function_, ...arguments_) => new Promise((resolve, reject) => {\n\t\tenqueue(function_, resolve, reject, arguments_);\n\t});\n\n\tObject.defineProperties(generator, {\n\t\tactiveCount: {\n\t\t\tget: () => activeCount,\n\t\t},\n\t\tpendingCount: {\n\t\t\tget: () => queue.size,\n\t\t},\n\t\tclearQueue: {\n\t\t\tvalue() {\n\t\t\t\tif (!rejectOnClear) {\n\t\t\t\t\tqueue.clear();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst abortError = AbortSignal.abort().reason;\n\n\t\t\t\twhile (queue.size > 0) {\n\t\t\t\t\tqueue.dequeue().reject(abortError);\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\tconcurrency: {\n\t\t\tget: () => concurrency,\n\n\t\t\tset(newConcurrency) {\n\t\t\t\tvalidateConcurrency(newConcurrency);\n\t\t\t\tconcurrency = newConcurrency;\n\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\t// eslint-disable-next-line no-unmodified-loop-condition\n\t\t\t\t\twhile (activeCount < concurrency && queue.size > 0) {\n\t\t\t\t\t\tresumeNext();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t\tmap: {\n\t\t\tasync value(iterable, function_) {\n\t\t\t\tconst promises = [];\n\n\t\t\t\ttry {\n\t\t\t\t\tArray.from(iterable, (value, index) => {\n\t\t\t\t\t\tconst promise = generator(function_, value, index);\n\t\t\t\t\t\tpromises.push(promise);\n\t\t\t\t\t\treturn promise;\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// The iterable threw, so `Promise.all` never observes the already scheduled promises. Observe them here to avoid unhandled rejections.\n\t\t\t\t\tfor (const promise of promises) {\n\t\t\t\t\t\tpromise.catch(() => {}); // eslint-disable-line promise/prefer-await-to-then\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\treturn Promise.all(promises);\n\t\t\t},\n\t\t},\n\t});\n\n\treturn generator;\n}\n\nexport function limitFunction(function_, options) {\n\tconst limit = pLimit(options);\n\n\tconst limitedFunction = (...arguments_) => limit(() => function_(...arguments_));\n\tObject.defineProperty(limitedFunction, 'clearQueue', {\n\t\tvalue: limit.clearQueue,\n\t});\n\n\treturn limitedFunction;\n}\n\nfunction validateConcurrency(concurrency) {\n\tif (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {\n\t\tthrow new TypeError('Expected `concurrency` to be a number from 1 and up');\n\t}\n}\n","import { deepmerge } from 'deepmerge-ts';\n\nimport { type PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\n\nexport function mergePuppeteerParameters(\n defaults: PuppeteerParameters,\n overrides?: PuppeteerParameters,\n): PuppeteerParameters {\n if (!overrides) {\n return { ...defaults };\n }\n\n return deepmerge(defaults, overrides);\n}\n","import { lookup } from 'node:dns/promises';\nimport { promises } from 'node:fs';\nimport { BlockList, isIP } from 'node:net';\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { Logger } from '@nestjs/common';\nimport {\n type BrowserContext,\n type HTTPRequest,\n type Page,\n TargetType,\n} from 'puppeteer';\n\n/**\n * Filters what the rendered HTML may load (SSRF protection). Disabled unless set:\n * pass `{}` for the defaults (private networks and `file:` blocked).\n */\nexport interface PdfSecurityOptions {\n /**\n * Refuse http(s) requests that resolve to a loopback, private, link-local\n * (cloud metadata included) or otherwise non-public address. Default: true\n */\n blockPrivateNetworks?: boolean;\n /**\n * When set, http(s) requests are only allowed to these hosts (`example.com`\n * or `*.example.com`). Listed hosts are trusted, even on a private address.\n */\n allowedHosts?: Array<string>;\n /**\n * `file:` requests are refused unless the file is inside one of these\n * directories (symbolic links are resolved).\n */\n allowedFileRoots?: Array<string>;\n /** Set to false to disable JavaScript in the rendered page. Default: true */\n javascriptEnabled?: boolean;\n}\n\nconst blockedRanges = new BlockList();\nfor (const [address, prefix] of [\n ['0.0.0.0', 8],\n ['10.0.0.0', 8],\n ['100.64.0.0', 10],\n ['127.0.0.0', 8],\n ['169.254.0.0', 16],\n ['172.16.0.0', 12],\n ['192.0.0.0', 24],\n ['192.168.0.0', 16],\n ['198.18.0.0', 15],\n ['224.0.0.0', 4],\n ['240.0.0.0', 4],\n] as const) {\n blockedRanges.addSubnet(address, prefix, 'ipv4');\n}\nfor (const [address, prefix] of [\n ['::', 128],\n ['::1', 128],\n ['64:ff9b::', 96],\n ['fc00::', 7],\n ['fe80::', 10],\n ['ff00::', 8],\n] as const) {\n blockedRanges.addSubnet(address, prefix, 'ipv6');\n}\n\nconst IPV4_MAPPED_IPV6 = /^::ffff:([\\da-f]{1,4}):([\\da-f]{1,4})$/i;\n\n/** True for addresses that must not be reachable from a rendered document. */\nexport function isPrivateAddress(address: string): boolean {\n const family = isIP(address);\n if (family === 4) {\n return blockedRanges.check(address, 'ipv4');\n }\n if (family === 6) {\n // WHATWG URL serialises ::ffff:127.0.0.1 as ::ffff:7f00:1\n const mapped = IPV4_MAPPED_IPV6.exec(address);\n if (mapped) {\n const high = Number.parseInt(mapped[1], 16);\n const low = Number.parseInt(mapped[2], 16);\n return isPrivateAddress(\n [high >> 8, high & 0xff, low >> 8, low & 0xff].join('.'),\n );\n }\n return blockedRanges.check(address, 'ipv6');\n }\n // Not an IP: unknown format, refuse.\n return true;\n}\n\nfunction hostMatches(hostname: string, pattern: string): boolean {\n const host = hostname.toLowerCase();\n const rule = pattern.toLowerCase();\n if (rule.startsWith('*.')) {\n return host.endsWith(rule.slice(1));\n }\n return host === rule;\n}\n\nfunction isLocalhostName(hostname: string): boolean {\n return hostname === 'localhost' || hostname.endsWith('.localhost');\n}\n\nasync function resolvesToPrivateAddress(hostname: string): Promise<boolean> {\n // IPv6 literals come bracketed from URL.hostname\n const host = hostname.replace(/^\\[|\\]$/g, '');\n if (isIP(host)) {\n return isPrivateAddress(host);\n }\n if (isLocalhostName(host)) {\n return true;\n }\n try {\n const addresses = await lookup(host, { all: true, verbatim: true });\n return addresses.some(({ address }) => isPrivateAddress(address));\n } catch {\n // Unresolvable: the browser would fail too, and we cannot vouch for it.\n return true;\n }\n}\n\nasync function isFileAllowed(url: URL, roots: Array<string>): Promise<boolean> {\n // file://server/share is a network path (SMB), never a local file\n if (\n roots.length === 0 ||\n (url.hostname !== '' && url.hostname !== 'localhost')\n ) {\n return false;\n }\n\n let path: string;\n try {\n path = fileURLToPath(url);\n } catch {\n return false;\n }\n\n // Missing file: nothing to leak, but resolve its closest existing ancestor\n // so symlinks (e.g. macOS /var -> /private/var) match the resolved roots.\n const real = async (candidate: string) => {\n const missing: Array<string> = [];\n let current = resolve(candidate);\n for (;;) {\n try {\n return join(await promises.realpath(current), ...missing);\n } catch {\n const parent = dirname(current);\n if (parent === current) return resolve(candidate);\n missing.unshift(basename(current));\n current = parent;\n }\n }\n };\n\n const target = await real(path);\n for (const root of roots) {\n const rel = relative(await real(root), target);\n if (rel === '' || (!rel.startsWith('..') && !isAbsolute(rel))) {\n return true;\n }\n }\n return false;\n}\n\n/** Decides whether the browser may fetch `rawUrl`. */\nexport async function isRequestAllowed(\n rawUrl: string,\n options: PdfSecurityOptions,\n): Promise<boolean> {\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n return false;\n }\n\n switch (url.protocol) {\n case 'about:':\n case 'data:':\n case 'blob:':\n return true;\n case 'file:':\n return isFileAllowed(url, options.allowedFileRoots ?? []);\n case 'http:':\n case 'https:': {\n if (options.allowedHosts) {\n return options.allowedHosts.some((pattern) =>\n hostMatches(url.hostname, pattern),\n );\n }\n if (options.blockPrivateNetworks === false) {\n return true;\n }\n return !(await resolvesToPrivateAddress(url.hostname));\n }\n default:\n return false;\n }\n}\n\n/** Logs the origin and path only: query strings may carry secrets. */\nfunction describe(rawUrl: string) {\n try {\n const url = new URL(rawUrl);\n return `${url.origin === 'null' ? `${url.protocol}//` : url.origin}${url.pathname}`;\n } catch {\n return '<invalid url>';\n }\n}\n\n/**\n * Filters every request the page (and its frames) makes, redirects included,\n * and closes the pop-ups a script could open to escape the filter.\n */\nexport async function installRequestGuard(\n context: BrowserContext,\n page: Page,\n options: PdfSecurityOptions,\n) {\n context.on('targetcreated', (target) => {\n if (target.type() === TargetType.PAGE && target.opener()) {\n void target\n .page()\n .then((popup) => popup?.close())\n .catch(() => undefined);\n }\n });\n\n if (options.javascriptEnabled === false) {\n await page.setJavaScriptEnabled(false);\n }\n\n await page.setRequestInterception(true);\n page.on('request', (request: HTTPRequest) => {\n void (async () => {\n if (request.isInterceptResolutionHandled()) return;\n const url = request.url();\n const allowed = await isRequestAllowed(url, options).catch(() => false);\n if (request.isInterceptResolutionHandled()) return;\n if (allowed) {\n await request.continue();\n } else {\n Logger.warn(`Blocked request to ${describe(url)}`, 'NestJsPdf');\n await request.abort('blockedbyclient');\n }\n })().catch(() => undefined);\n });\n}\n","export const PDF_PARAMETERS = 'PDF_PARAMETERS' as const;\n","import { existsSync, promises, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Inject, Injectable, Logger, OnModuleDestroy } from '@nestjs/common';\nimport {\n Browser as BrowserType,\n BrowserPlatform,\n canDownload,\n detectBrowserPlatform,\n getInstalledBrowsers,\n install,\n resolveBuildId,\n} from '@puppeteer/browsers';\nimport { Browser, BrowserContext, launch } from 'puppeteer';\n\nimport {\n BrowserInstallationException,\n BrowserUnavailableException,\n NestjsPdfException,\n} from '../../exceptions';\nimport type { PuppeteerParameters } from '../puppeteer-parameters.interface';\n\nexport enum BrowserTag {\n LATEST = 'latest',\n BETA = 'beta',\n DEV = 'dev',\n STABLE = 'stable',\n CANARY = 'canary',\n}\n\nexport type Headless = boolean | 'shell' | undefined;\n\nasync function sleep(ms: number) {\n await new Promise((r) => setTimeout(r, ms));\n}\n\nasync function rmWithRetries(dir: string, retries = 5): Promise<void> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n await promises.rm(dir, { recursive: true, force: true });\n return;\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException)?.code;\n\n const retryable =\n code === 'EPERM' || code === 'EBUSY' || code === 'ENOTEMPTY';\n\n if (!retryable || attempt === retries) {\n throw err;\n }\n\n await sleep(50 * 2 ** (attempt - 1));\n }\n }\n}\n\nfunction isTargetClosedError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n\n return (\n error.name === 'TargetCloseError' ||\n error.message.includes('Target closed') ||\n error.message.includes('Target.createTarget')\n );\n}\n\n@Injectable()\nexport class BrowserService implements OnModuleDestroy {\n readonly #cacheDir: string;\n readonly #options?: PuppeteerParameters;\n\n #browserInstance: Browser | null = null;\n #browser: BrowserType;\n\n public activeJobs = 0;\n public totalJobs = 0;\n\n #recycleRequested = false;\n #recycling = false;\n\n #shuttingDown = false;\n /** Max time to wait for in-flight PDF jobs to finish before closing the browser on shutdown. */\n public shutdownDrainTimeoutMs = 15_000;\n\n #browserTag: BrowserTag;\n #useLockedBrowser: boolean;\n #buildId: string | undefined;\n\n constructor(@Inject('PDF_PARAMETERS') pdfParams: PuppeteerParameters) {\n this.#cacheDir = resolve('.cache/puppeteer-browser');\n this.#options = pdfParams;\n\n this.#loadBuildId();\n this.#loadBrowser();\n this.#loadBrowserTag();\n this.#loadUseLockedBrowser();\n }\n\n async onModuleDestroy() {\n this.#shuttingDown = true;\n await this.#waitForIdle(this.shutdownDrainTimeoutMs);\n\n if (this.#browserInstance?.connected) {\n try {\n await this.#browserInstance.close();\n } catch (error) {\n Logger.warn(\n `Failed to close browser on module destroy: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n if (this.#options?.cleanupBrowserCacheOnExit !== false) {\n await this.#cleanupCacheBestEffort();\n }\n }\n\n /** Wait until no PDF job is in flight, or until the timeout elapses. */\n async #waitForIdle(timeoutMs: number): Promise<void> {\n const start = Date.now();\n while (this.activeJobs > 0 && Date.now() - start < timeoutMs) {\n await sleep(50);\n }\n\n if (this.activeJobs > 0) {\n Logger.warn(\n `Shutdown: ${this.activeJobs} PDF job(s) still running after ${timeoutMs}ms, closing the browser anyway`,\n );\n }\n }\n\n async getBrowserInstance(\n args: Array<string>,\n headless: boolean | 'shell' | undefined,\n executablePathBin: string | undefined,\n ) {\n if (!this.#browserInstance?.connected) {\n this.#browserInstance = await this.#launchBrowser(\n args,\n headless,\n executablePathBin,\n );\n }\n\n return this.#browserInstance;\n }\n\n async createContext(\n args: Array<string>,\n headless: Headless,\n executablePath?: string,\n ): Promise<BrowserContext> {\n const browser = await this.getBrowserInstance(\n args,\n headless,\n executablePath,\n );\n try {\n return await browser.createBrowserContext();\n } catch (error) {\n if (!isTargetClosedError(error)) {\n throw error;\n }\n\n Logger.warn(\n 'Puppeteer browser closed while creating a context, retrying once',\n );\n\n this.#browserInstance = null;\n const freshBrowser = await this.getBrowserInstance(\n args,\n headless,\n executablePath,\n );\n return await freshBrowser.createBrowserContext();\n }\n }\n\n markJobStarted() {\n if (this.#shuttingDown) {\n throw new BrowserUnavailableException(\n 'nestjs-pdf is shutting down, refusing new PDF jobs',\n );\n }\n\n this.activeJobs += 1;\n this.totalJobs += 1;\n\n if (this.totalJobs >= 200) {\n this.#recycleRequested = true;\n }\n }\n\n async markJobFinished() {\n this.activeJobs = Math.max(0, this.activeJobs - 1);\n await this.recycleBrowserIfNeeded();\n }\n\n async recycleBrowserIfNeeded() {\n if (!this.#recycleRequested) return;\n if (this.#recycling) return;\n if (this.activeJobs > 0) return;\n if (!this.#browserInstance) return;\n\n this.#recycling = true;\n\n try {\n if (this.#browserInstance.connected) {\n await this.#browserInstance.close();\n }\n\n this.#browserInstance = null;\n this.totalJobs = 0;\n this.#recycleRequested = false;\n\n Logger.log('Puppeteer browser recycled successfully');\n } catch (error) {\n Logger.warn(\n `Failed to recycle browser: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n } finally {\n this.#recycling = false;\n }\n }\n\n async #cleanupCacheBestEffort() {\n const logger = new Logger('NestJsPdf');\n const dir = this.#cacheDir;\n try {\n if (!existsSync(dir)) return;\n\n logger.log(`Cleanup puppeteer cache: ${dir}`);\n\n await rmWithRetries(dir, 6);\n if (existsSync(dir)) {\n await sleep(100);\n await rmWithRetries(dir, 3);\n }\n\n logger.log('Cleanup done');\n } catch (err) {\n logger.error(\n `Cleanup failed for ${dir}`,\n err instanceof Error ? err.stack : String(err),\n );\n }\n try {\n const leftover = await promises.readdir(dir, { recursive: true });\n logger.warn(`Leftover files: ${leftover.slice(0, 20).join(', ')}...`);\n } catch {\n logger.log(`No leftover files in ${dir}`);\n }\n }\n\n async install(lock: boolean = false) {\n try {\n return await this.#doInstall(lock);\n } catch (error) {\n if (error instanceof NestjsPdfException) {\n throw error;\n }\n throw new BrowserInstallationException(\n `Could not install browser: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async #doInstall(lock: boolean) {\n const browser: BrowserType = this.#browser;\n const versionTag: BrowserTag = this.#browserTag;\n\n const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;\n\n let buildId: string;\n if (this.#buildId === undefined) {\n buildId = await resolveBuildId(browser, browserPlatform, versionTag);\n } else {\n buildId = this.#buildId;\n }\n\n Logger.log(\n `Browser ${browser} ${versionTag} build id: ${buildId}`,\n 'NestJsPdf',\n );\n\n if (await this.hasBrowserInstalled(browser, buildId)) {\n Logger.log('Browser already installed', 'NestJsPdf');\n if (lock) {\n this.#writeLockFile(browser, buildId);\n }\n return;\n } else {\n Logger.log('Starting browser installation', 'NestJsPdf');\n\n const installOption = {\n cacheDir: this.#cacheDir,\n browser: browser,\n buildId: buildId,\n baseUrl: this.#options?.browserInstallBaseUrl ?? undefined,\n };\n\n if (await canDownload(installOption)) {\n Logger.log(\n `Installing ${installOption.browser} ${installOption.buildId}`,\n 'NestJsPdf',\n );\n const installedBrowser = await install(installOption);\n if (await this.hasBrowserInstalled(browser, buildId)) {\n Logger.log('Browser installed successfully', 'NestJsPdf');\n if (lock) {\n this.#writeLockFile(browser, buildId);\n }\n return installedBrowser;\n } else {\n Logger.error('Browser installation failed', 'NestJsPdf');\n }\n } else {\n Logger.error(\n `Error, can't install ${installOption.browser} ${installOption.buildId}`,\n 'NestJsPdf',\n );\n }\n }\n return null;\n }\n\n #loadBrowser(): void {\n let browser: BrowserType;\n if (this.#options?.browser === undefined) {\n browser = BrowserType.CHROMIUM;\n } else {\n browser = this.#options.browser;\n }\n this.#browser = browser;\n }\n\n public getBrowser(): BrowserType {\n return this.#browser;\n }\n\n #loadBrowserTag(): void {\n let versionTag: BrowserTag;\n if (this.#options?.browserTag === undefined) {\n if (this.#browser === BrowserType.CHROMIUM) {\n versionTag = BrowserTag.LATEST;\n } else {\n versionTag = BrowserTag.STABLE;\n }\n } else {\n versionTag = this.#options.browserTag;\n }\n this.#browserTag = versionTag;\n }\n\n #loadBuildId(): void {\n let buildId: string | undefined;\n if (this.#options?.buildId === undefined) {\n buildId = undefined;\n } else {\n buildId = this.#options.buildId;\n }\n this.#buildId = buildId;\n }\n\n public setBrowserTag(browserTag: BrowserTag): void {\n this.#browserTag = browserTag;\n }\n\n public getBrowserTag(): BrowserTag {\n return this.#browserTag;\n }\n\n getBuildId(): string | undefined {\n return this.#buildId;\n }\n\n #loadUseLockedBrowser(): void {\n let useLockedBrowser: boolean;\n if (this.#options?.useLockedBrowser === undefined) {\n useLockedBrowser = false;\n } else {\n useLockedBrowser = this.#options.useLockedBrowser;\n }\n this.#useLockedBrowser = useLockedBrowser;\n }\n\n async hasBrowserInstalled(browser: BrowserType, buildId: string) {\n const installedBrowserlist = await getInstalledBrowsers({\n cacheDir: this.#cacheDir,\n });\n\n const installedBrowser = installedBrowserlist.find((insBrowser) => {\n return insBrowser.browser === browser && insBrowser.buildId === buildId;\n });\n return installedBrowser !== undefined;\n }\n\n async getExecutablePath(): Promise<string> {\n const browser: BrowserType = this.#browser;\n const versionTag: BrowserTag = this.#browserTag;\n const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;\n let buildId: string | null = null;\n if (this.#useLockedBrowser) {\n buildId = this.getLockedBuildId(browser);\n Logger.log(`Using locked browser ${buildId}`, 'NestJsPdf');\n }\n buildId ??= await resolveBuildId(browser, browserPlatform, versionTag);\n const installedBrowserlist = await getInstalledBrowsers({\n cacheDir: this.#cacheDir,\n });\n const installedBrowser = installedBrowserlist.find((insBrowser) => {\n return insBrowser.browser === browser && insBrowser.buildId === buildId;\n });\n if (installedBrowser === undefined) {\n const newinstalledBrowser = await this.install();\n if (newinstalledBrowser === null || newinstalledBrowser === undefined) {\n throw new BrowserInstallationException('Could not install browser');\n } else {\n return newinstalledBrowser.executablePath;\n }\n }\n return installedBrowser.executablePath;\n }\n\n async #launchBrowser(\n args: Array<string>,\n headless: Headless,\n executablePathBin: string | undefined,\n ) {\n const executablePath =\n executablePathBin ?? (await this.getExecutablePath());\n\n const browser = await launch({\n executablePath,\n headless,\n args,\n // Puppeteer disables Chrome's popup blocker by default, which lets a\n // script open a window that escapes the request filter.\n ignoreDefaultArgs: ['--disable-popup-blocking'],\n });\n\n browser.on('disconnected', () => {\n Logger.warn('Puppeteer browser disconnected');\n if (this.#browserInstance === browser) {\n this.#browserInstance = null;\n }\n });\n\n return browser;\n }\n\n #writeLockFile(browser: BrowserType, buildId: string) {\n const lockFile = resolve(this.#cacheDir, `${browser}.lock`);\n const data = JSON.stringify({\n browser: browser,\n buildId: buildId,\n date: new Date().toISOString(),\n });\n writeFileSync(lockFile, data);\n\n Logger.log(`Browser ${browser} locked to build ${buildId}`, 'NestJsPdf');\n }\n\n getLockedBuildId(browser: BrowserType): string | null {\n const lockFile = resolve(this.#cacheDir, `${browser}.lock`);\n if (existsSync(lockFile)) {\n const data = readFileSync(lockFile);\n const lock = JSON.parse(data.toString()) as {\n browser: Browser;\n buildId: string;\n date: string;\n };\n return lock.buildId;\n }\n return null;\n }\n}\n","import { createRequire } from 'node:module';\n\nimport { EngineNotAvailableException } from '../../exceptions';\n\nconst requireEngine = createRequire(import.meta.url);\n\n/**\n * Load an optional template engine on first use, so the library can be imported\n * without every engine installed. `require` (not `import()`) is used on purpose:\n * most engines expose a synchronous render API.\n */\nexport function loadEngine<T>(packageName: string, engineName: string): T {\n let mod: { __esModule?: boolean; default?: unknown };\n try {\n mod = requireEngine(packageName) as typeof mod;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n throw new EngineNotAvailableException(engineName, packageName, {\n cause: error,\n });\n }\n throw error;\n }\n\n return (mod.__esModule && 'default' in mod ? mod.default : mod) as T;\n}\n","import { Injectable } from '@nestjs/common';\nimport type ejs from 'ejs';\nimport type { Data, Options } from 'ejs';\n\nimport { TemplateRenderException } from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport interface EjsOptions extends Omit<Options, 'async'> {\n async?: boolean;\n}\n\n@Injectable()\nexport class EjsService {\n #ejs?: typeof ejs;\n\n get #engine(): typeof ejs {\n return (this.#ejs ??= loadEngine<typeof ejs>('ejs', 'EJS'));\n }\n\n async render(template: string, data: Data = {}, options?: EjsOptions) {\n const engine = this.#engine;\n try {\n return await engine.render(template, data, {\n async: true,\n ...options,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'EJS',\n `EJS rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async renderFile(filePath: string, data: Data = {}, options?: EjsOptions) {\n const engine = this.#engine;\n try {\n return await engine.renderFile(filePath, data, {\n async: true,\n ...options,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'EJS',\n `EJS file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport type * as EtaModule from 'eta';\nimport type { Eta, EtaConfig } from 'eta';\n\nimport {\n EngineNotAvailableException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport interface EtaOptions extends Partial<EtaConfig> {\n cache?: boolean;\n autoEscape?: boolean;\n varName?: string;\n views?: string;\n useWith?: boolean;\n plugins?: Array<any>;\n}\n\n@Injectable()\nexport class EtaService {\n #etaModule?: typeof EtaModule;\n #eta?: Eta;\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n get #engine(): typeof EtaModule {\n return (this.#etaModule ??= loadEngine<typeof EtaModule>('eta', 'Eta'));\n }\n\n /**\n * Render an Eta template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Eta rendering options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: EtaOptions,\n ): string {\n const { Eta } = this.#engine;\n try {\n const eta =\n options && Object.keys(options).length > 0\n ? new Eta({\n cache: true,\n autoEscape: true,\n useWith: true,\n ...options,\n varName: options.varName ?? 'it',\n })\n : (this.#eta ??= new Eta({\n cache: true,\n autoEscape: true,\n useWith: true,\n }));\n\n return eta.renderString(template, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Eta',\n `Eta rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render an Eta template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Eta rendering options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: EtaOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n const useCache = options?.cache ?? true;\n let template = useCache\n ? this.#templateCache.get(resolvedPath)\n : undefined;\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (useCache && this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n return this.render(template, data, options);\n } catch (error) {\n if (error instanceof EngineNotAvailableException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Eta',\n `Eta file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { basename, extname, join, resolve, sep } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport type Handlebars from 'handlebars';\n\nimport {\n NestjsPdfException,\n TemplateConfigurationException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport type HandlebarsHelper = {\n name: string;\n fn: Handlebars.HelperDelegate;\n};\n\nexport interface HandlebarsOptions {\n /** Base directory (relative to `process.cwd()`) used to resolve files passed to `renderFile`. */\n templateDirectory?: string;\n /** Directory (relative to `process.cwd()`) whose files are each registered as a partial. */\n partialDirectory?: string;\n /**\n * Runtime options forwarded to the compiled template function.\n * `helpers` and `partials` are excluded on purpose: register helpers via\n * `helpers` and partials via `partialDirectory`.\n */\n templateOptions?: Omit<Handlebars.RuntimeOptions, 'helpers' | 'partials'>;\n /** Options forwarded to `Handlebars.compile`. */\n compileOptions?: CompileOptions;\n /** Custom helpers registered on the isolated Handlebars environment for this render. */\n helpers?: Array<HandlebarsHelper>;\n}\n\n@Injectable()\nexport class HandlebarsService {\n #handlebars?: typeof Handlebars;\n #cachedOptions?: HandlebarsOptions;\n #cachedEnv?: typeof Handlebars;\n\n get #engine(): typeof Handlebars {\n return (this.#handlebars ??= loadEngine<typeof Handlebars>(\n 'handlebars',\n 'Handlebars',\n ));\n }\n\n render(\n template: string,\n parameters: unknown = {},\n options: HandlebarsOptions = {},\n ): string {\n try {\n const compiled = this.#getEnv(options).compile(\n template,\n options.compileOptions,\n );\n return compiled(parameters, options.templateOptions);\n } catch (error) {\n if (error instanceof NestjsPdfException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Handlebars',\n `Handlebars rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n file: string,\n parameters: unknown = {},\n options: HandlebarsOptions = {},\n ): string {\n if (options.templateDirectory === undefined) {\n throw new TemplateConfigurationException(\n 'Handlebars file rendering failed: option `templateDirectory` is not set',\n );\n }\n\n const baseDir = resolve(process.cwd(), options.templateDirectory);\n const templatePath = resolve(baseDir, file);\n if (templatePath !== baseDir && !templatePath.startsWith(baseDir + sep)) {\n throw new TemplateConfigurationException(\n `Handlebars file rendering failed: ’${file}’ resolves outside \\`templateDirectory\\``,\n );\n }\n\n let template: string;\n try {\n template = readFileSync(templatePath, 'utf8');\n } catch (error) {\n throw new TemplateRenderException(\n 'Handlebars',\n `Handlebars file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n\n return this.render(template, parameters, options);\n }\n\n /**\n * Build an isolated Handlebars environment with the given helpers/partials so\n * nothing leaks into the global Handlebars. Memoised for the common case where\n * the same options object is reused across calls (e.g. the module `hbsOptions`).\n */\n #getEnv(options: HandlebarsOptions): typeof Handlebars {\n if (this.#cachedEnv && this.#cachedOptions === options) {\n return this.#cachedEnv;\n }\n\n const env = this.#engine.create();\n\n for (const helper of options.helpers ?? []) {\n env.registerHelper(helper.name, helper.fn);\n }\n this.#registerPartials(env, options.partialDirectory);\n\n this.#cachedOptions = options;\n this.#cachedEnv = env;\n return env;\n }\n\n #registerPartials(\n env: typeof Handlebars,\n partialDirectory: string | undefined,\n ): void {\n if (partialDirectory === undefined) return;\n\n const partialPath = join(process.cwd(), partialDirectory);\n if (!existsSync(partialPath)) {\n throw new TemplateConfigurationException(\n `Handlebars partial directory does not exist: ${partialPath}`,\n );\n }\n\n for (const entry of readdirSync(partialPath)) {\n const filePath = join(partialPath, entry);\n if (!statSync(filePath).isFile()) continue;\n\n env.registerPartial(\n basename(entry, extname(entry)),\n readFileSync(filePath, 'utf8'),\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport type * as LiquidModule from 'liquidjs';\nimport type { Liquid, LiquidOptions as LiquidJsOptions } from 'liquidjs';\n\nimport {\n EngineNotAvailableException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport type LiquidOptions = LiquidJsOptions;\n\n@Injectable()\nexport class LiquidService {\n #liquidModule?: typeof LiquidModule;\n #liquid?: Liquid;\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n get #engine(): typeof LiquidModule {\n return (this.#liquidModule ??= loadEngine<typeof LiquidModule>(\n 'liquidjs',\n 'Liquid',\n ));\n }\n\n /**\n * Render a Liquid template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Liquid engine options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: LiquidOptions,\n ): string {\n const { Liquid } = this.#engine;\n try {\n const liquid =\n options && Object.keys(options).length > 0\n ? new Liquid(options)\n : (this.#liquid ??= new Liquid());\n\n return liquid.parseAndRenderSync(template, data) as string;\n } catch (error) {\n throw new TemplateRenderException(\n 'Liquid',\n `Liquid rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render a Liquid template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Liquid engine options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: LiquidOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n const useCache = options?.cache !== false;\n let template = useCache\n ? this.#templateCache.get(resolvedPath)\n : undefined;\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (useCache && this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n return this.render(template, data, options);\n } catch (error) {\n if (error instanceof EngineNotAvailableException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Liquid',\n `Liquid file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { readFileSync } from 'node:fs';\n\nimport { Injectable } from '@nestjs/common';\nimport type mjml from 'mjml';\nimport type { MJMLParsingOptions } from 'mjml-core';\n\nimport { TemplateRenderException } from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\n@Injectable()\nexport class MjmlService {\n #mjml?: typeof mjml;\n\n get #engine(): typeof mjml {\n return (this.#mjml ??= loadEngine<typeof mjml>('mjml', 'MJML'));\n }\n\n async render(\n template: string,\n options?: MJMLParsingOptions,\n ): Promise<string> {\n const engine = this.#engine;\n try {\n const { html } = await engine(template, options);\n return html;\n } catch (error) {\n throw new TemplateRenderException(\n 'MJML',\n `MJML rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async renderFile(\n filePath: string,\n options?: MJMLParsingOptions,\n ): Promise<string> {\n let template: string;\n try {\n template = readFileSync(filePath, 'utf-8');\n } catch (error) {\n throw new TemplateRenderException(\n 'MJML',\n `MJML file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n return await this.render(template, options);\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport type mustache from 'mustache';\nimport type { EscapeFunction } from 'mustache';\n\nimport {\n EngineNotAvailableException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport interface MustacheOptions {\n tags?: [string, string];\n escape?: EscapeFunction;\n}\n\n@Injectable()\nexport class MustacheService {\n #mustache?: typeof mustache;\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n get #engine(): typeof mustache {\n return (this.#mustache ??= loadEngine<typeof mustache>(\n 'mustache',\n 'Mustache',\n ));\n }\n\n /**\n * Render a Mustache template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Mustache rendering options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: MustacheOptions,\n ): string {\n const engine = this.#engine;\n try {\n const tags = options?.tags ?? ['{{', '}}'];\n return engine.render(template, data, undefined, {\n tags: tags,\n escape: options?.escape,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'Mustache',\n `Mustache rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render a Mustache template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Mustache rendering options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: MustacheOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n let template = this.#templateCache.get(resolvedPath);\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n\n return this.render(template, data, options);\n } catch (error) {\n if (error instanceof EngineNotAvailableException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Mustache',\n `Mustache file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport type nunjucks from 'nunjucks';\nimport type { ConfigureOptions } from 'nunjucks';\n\nimport { TemplateRenderException } from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport interface NunjucksOptions extends Partial<ConfigureOptions> {\n noCache?: boolean;\n watch?: boolean;\n throwOnUndefined?: boolean;\n trimBlocks?: boolean;\n lstripBlocks?: boolean;\n}\n\n@Injectable()\nexport class NunjucksService {\n #nunjucks?: typeof nunjucks;\n\n get #engine(): typeof nunjucks {\n if (!this.#nunjucks) {\n this.#nunjucks = loadEngine<typeof nunjucks>('nunjucks', 'Nunjucks');\n // Configure default Nunjucks environment\n this.#nunjucks.configure({\n noCache: true,\n trimBlocks: true,\n lstripBlocks: true,\n });\n }\n return this.#nunjucks;\n }\n\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: NunjucksOptions,\n ) {\n const nunjucks = this.#engine;\n try {\n if (options) {\n const configOptions: Record<string, unknown> = {\n noCache: options.noCache ?? true,\n watch: options.watch ?? false,\n throwOnUndefined: options.throwOnUndefined ?? false,\n trimBlocks: options.trimBlocks ?? true,\n lstripBlocks: options.lstripBlocks ?? true,\n };\n nunjucks.configure(configOptions as ConfigureOptions);\n }\n return nunjucks.renderString(template, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Nunjucks',\n `Nunjucks rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: NunjucksOptions,\n ) {\n const nunjucks = this.#engine;\n try {\n if (options) {\n const configOptions: Record<string, unknown> = {\n noCache: options.noCache ?? true,\n watch: options.watch ?? false,\n throwOnUndefined: options.throwOnUndefined ?? false,\n trimBlocks: options.trimBlocks ?? true,\n lstripBlocks: options.lstripBlocks ?? true,\n };\n nunjucks.configure(configOptions as ConfigureOptions);\n }\n return nunjucks.render(filePath, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Nunjucks',\n `Nunjucks file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\n\nimport { Injectable } from '@nestjs/common';\nimport type pug from 'pug';\nimport type { LocalsObject, Options } from 'pug';\n\nimport {\n EngineNotAvailableException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport type PugOptions = Options;\n\n@Injectable()\nexport class PugService {\n #pug?: typeof pug;\n\n get #engine(): typeof pug {\n return (this.#pug ??= loadEngine<typeof pug>('pug', 'Pug'));\n }\n\n render(\n template: string,\n data: LocalsObject = {},\n options?: PugOptions,\n ): string {\n const engine = this.#engine;\n try {\n const compiledFn = engine.compile(template, {\n ...options,\n });\n return compiledFn(data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Pug',\n `Pug rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n filePath: string,\n data: LocalsObject = {},\n options?: PugOptions,\n ): string {\n try {\n const template = readFileSync(filePath, 'utf-8');\n return this.render(template, data, options);\n } catch (error) {\n if (error instanceof EngineNotAvailableException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Pug',\n `Pug file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { EngineNotAvailableException } from '../../exceptions';\n\nexport function requireService<T>(service: T | undefined, name: string): T {\n if (!service) {\n throw new EngineNotAvailableException(name);\n }\n\n return service;\n}\n","import { Inject, Injectable, Logger, Optional } from '@nestjs/common';\nimport type { Data } from 'ejs';\nimport pLimit from 'p-limit';\nimport type { LocalsObject } from 'pug';\nimport { PDFOptions } from 'puppeteer';\n\nimport { NestjsPdfException, PdfGenerationException } from '../exceptions';\nimport { mergePuppeteerParameters } from '../helpers/deepMergePdfparams';\nimport { installRequestGuard } from '../helpers/request-guard.helper';\nimport { PDF_PARAMETERS } from '../helpers/tokens';\nimport { addWatermark } from '../helpers/watermark.helper';\nimport { BrowserService } from './browser/browser.service';\nimport { EjsService } from './engines/ejs/ejs.service';\nimport { EtaService } from './engines/eta/eta.service';\nimport { HandlebarsService } from './engines/handlebars/handlebars.service';\nimport { LiquidService } from './engines/liquid/liquid.service';\nimport { MjmlService } from './engines/mjml/mjml.service';\nimport { MustacheService } from './engines/mustache/mustache.service';\nimport { NunjucksService } from './engines/nunjucks/nunjucks.service';\nimport { PugService } from './engines/pug/pug.service';\nimport { requireService } from './libs/requireService.utils';\nimport type { PuppeteerParameters } from './puppeteer-parameters.interface';\n\n@Injectable()\nexport class PuppeteerService {\n readonly #browserService: BrowserService;\n readonly #options: PuppeteerParameters;\n readonly #hbsService?: HandlebarsService;\n readonly #mjmlService?: MjmlService;\n readonly #pugService?: PugService;\n readonly #ejsService?: EjsService;\n readonly #nunjucksService?: NunjucksService;\n readonly #etaService?: EtaService;\n readonly #mustacheService?: MustacheService;\n readonly #liquidService?: LiquidService;\n\n constructor(\n browserService: BrowserService,\n @Inject(PDF_PARAMETERS) options: PuppeteerParameters,\n @Optional() hbsService?: HandlebarsService,\n @Optional() mjmlService?: MjmlService,\n @Optional() pugService?: PugService,\n @Optional() ejsService?: EjsService,\n @Optional() nunjucksService?: NunjucksService,\n @Optional() etaService?: EtaService,\n @Optional() mustacheService?: MustacheService,\n @Optional() liquidService?: LiquidService,\n ) {\n this.#browserService = browserService;\n this.#options = options;\n this.#hbsService = hbsService;\n this.#mjmlService = mjmlService;\n this.#pugService = pugService;\n this.#ejsService = ejsService;\n this.#nunjucksService = nunjucksService;\n this.#etaService = etaService;\n this.#mustacheService = mustacheService;\n this.#liquidService = liquidService;\n }\n\n readonly #limit = pLimit(3);\n\n async generatePdfFromHtml(\n html: string,\n options?: PuppeteerParameters,\n ): Promise<Uint8Array> {\n const signal = options?.signal ?? this.#options.signal;\n signal?.throwIfAborted();\n\n let started = false;\n const job = this.#limit(async () => {\n signal?.throwIfAborted();\n started = true;\n\n const mergePuppeteerOptions = mergePuppeteerParameters(\n this.#options,\n options,\n );\n if (mergePuppeteerOptions.chromiumRevision !== undefined) {\n Logger.warn(\n 'Using `chromiumRevision` is no longer supported since the puppeteer update.',\n );\n }\n\n const headless: boolean | 'shell' =\n mergePuppeteerOptions.headless ?? true;\n\n const executablePath = mergePuppeteerOptions.executablePath || undefined;\n\n //src: https://www.bannerbear.com/blog/ways-to-speed-up-puppeteer-screenshots/\n const args = mergePuppeteerOptions.extraPuppeteerArgs || [\n '--autoplay-policy=user-gesture-required',\n '--disable-background-networking',\n '--disable-background-timer-throttling',\n '--disable-backgrounding-occluded-windows',\n '--disable-breakpad',\n '--disable-client-side-phishing-detection',\n '--disable-component-update',\n '--disable-default-apps',\n '--disable-dev-shm-usage',\n '--disable-domain-reliability',\n '--disable-extensions',\n '--disable-features=AudioServiceOutOfProcess',\n '--disable-hang-monitor',\n '--disable-ipc-flooding-protection',\n '--disable-notifications',\n '--disable-offer-store-unmasked-wallet-cards',\n '--disable-print-preview',\n '--disable-prompt-on-repost',\n '--disable-renderer-backgrounding',\n '--disable-setuid-sandbox',\n '--disable-speech-api',\n '--disable-sync',\n '--hide-scrollbars',\n '--ignore-gpu-blacklist',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-default-browser-check',\n '--no-first-run',\n '--no-pings',\n '--password-store=basic',\n '--use-gl=swiftshader',\n '--use-mock-keychain',\n '--disable-accelerated-2d-canvas',\n '--no-zygote',\n '--disable-gpu',\n ];\n\n this.#browserService.markJobStarted();\n let context: Awaited<ReturnType<BrowserService['createContext']>> | null =\n null;\n\n let closing: Promise<void> | undefined;\n const onAbort = () => {\n if (!context) return;\n closing = context.close();\n closing.catch(() => undefined);\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n context = await this.#browserService.createContext(\n args,\n headless,\n executablePath,\n );\n signal?.throwIfAborted();\n const page = await context.newPage();\n if (mergePuppeteerOptions.security) {\n await installRequestGuard(\n context,\n page,\n mergePuppeteerOptions.security,\n );\n }\n\n const pdfOptions: PDFOptions = mergePuppeteerOptions.pdfOptions ?? {\n format: 'A4',\n };\n\n await page.setContent(html, { waitUntil: 'domcontentloaded' });\n await page.emulateMediaType('screen');\n await page.waitForNetworkIdle({ idleTime: 500, timeout: 30000 });\n // Executes inside the browser page context via Puppeteer, not in Node — unreachable by unit tests.\n /* v8 ignore next */\n await page.evaluate(() => document.fonts.ready);\n\n const pdf = await page.pdf(pdfOptions);\n signal?.throwIfAborted();\n return mergePuppeteerOptions.watermark\n ? await addWatermark(pdf, mergePuppeteerOptions.watermark)\n : pdf;\n } catch (e) {\n if (signal?.aborted) {\n throw signal.reason;\n }\n Logger.error(e);\n if (e instanceof NestjsPdfException) {\n throw e;\n }\n throw new PdfGenerationException(\n `PDF generation failed: ${String(e)}`,\n { cause: e },\n );\n } finally {\n signal?.removeEventListener('abort', onAbort);\n if (context) {\n try {\n if (closing) await closing;\n else await context.close();\n } catch (error) {\n Logger.error(error);\n }\n }\n await this.#browserService.markJobFinished();\n }\n });\n\n if (!signal) {\n return job;\n }\n\n let onQueuedAbort!: () => void;\n const abortedWhileQueued = new Promise<never>((_, reject) => {\n onQueuedAbort = () => {\n // An abort reason can be any value; callers expect the exact one they passed.\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n if (!started) reject(signal.reason);\n };\n signal.addEventListener('abort', onQueuedAbort, { once: true });\n });\n try {\n return await Promise.race([job, abortedWhileQueued]);\n } finally {\n signal.removeEventListener('abort', onQueuedAbort);\n }\n }\n\n async generatePdfFromTemplateHbsString(\n template: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n const hbsService = requireService(this.#hbsService, 'Handlebars');\n const html = hbsService.render(\n template,\n parameters,\n options?.hbsOptions ?? this.#options.hbsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromTemplateHbsFile(\n file: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n const hbsService = requireService(this.#hbsService, 'Handlebars');\n const html = hbsService.renderFile(\n file,\n parameters,\n options?.hbsOptions ?? this.#options.hbsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMjmlString(\n template: string,\n options?: PuppeteerParameters,\n ) {\n const mjmlService = requireService(this.#mjmlService, 'MJML');\n const html = await mjmlService.render(\n template,\n options?.mjmlOptions ?? this.#options.mjmlOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMjmlFile(file: string, options?: PuppeteerParameters) {\n const mjmlService = requireService(this.#mjmlService, 'MJML');\n const html = await mjmlService.renderFile(\n file,\n options?.mjmlOptions ?? this.#options.mjmlOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromPugString(\n template: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n const pugService = requireService(this.#pugService, 'Pug');\n const html = pugService.render(\n template,\n data,\n options?.pugOptions ?? this.#options.pugOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromPugFile(\n file: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n const pugService = requireService(this.#pugService, 'Pug');\n const html = pugService.renderFile(\n file,\n data,\n options?.pugOptions ?? this.#options.pugOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEjsString(\n template: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n const ejsService = requireService(this.#ejsService, 'EJS');\n const html = await ejsService.render(\n template,\n data,\n options?.ejsOptions ?? this.#options.ejsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEjsFile(\n file: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n const ejsService = requireService(this.#ejsService, 'EJS');\n const html = await ejsService.renderFile(\n file,\n data,\n options?.ejsOptions ?? this.#options.ejsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromNunjucksString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const nunjucksService = requireService(this.#nunjucksService, 'Nunjucks');\n const html = nunjucksService.render(\n template,\n data,\n options?.nunjucksOptions ?? this.#options.nunjucksOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromNunjucksFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const nunjucksService = requireService(this.#nunjucksService, 'Nunjucks');\n const html = nunjucksService.renderFile(\n file,\n data,\n options?.nunjucksOptions ?? this.#options.nunjucksOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEtaString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const etaService = requireService(this.#etaService, 'Eta');\n const html = etaService.render(\n template,\n data,\n options?.etaOptions ?? this.#options.etaOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEtaFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const etaService = requireService(this.#etaService, 'Eta');\n const html = etaService.renderFile(\n file,\n data,\n options?.etaOptions ?? this.#options.etaOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMustacheString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const mustacheService = requireService(this.#mustacheService, 'Mustache');\n const html = mustacheService.render(\n template,\n data,\n options?.mustacheOptions ?? this.#options.mustacheOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMustacheFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const mustacheService = requireService(this.#mustacheService, 'Mustache');\n const html = mustacheService.renderFile(\n file,\n data,\n options?.mustacheOptions ?? this.#options.mustacheOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromLiquidString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const liquidService = requireService(this.#liquidService, 'Liquid');\n const html = liquidService.render(\n template,\n data,\n options?.liquidOptions ?? this.#options.liquidOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromLiquidFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const liquidService = requireService(this.#liquidService, 'Liquid');\n const html = liquidService.renderFile(\n file,\n data,\n options?.liquidOptions ?? this.#options.liquidOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport type { Data } from 'ejs';\nimport type { LocalsObject } from 'pug';\n\nimport { addSignatureFieldUsingAnchor } from './helpers/signature.helper';\nimport {\n addWatermark,\n type WatermarkOptions,\n} from './helpers/watermark.helper';\nimport { PuppeteerService } from './puppeteer/puppeteer.service';\nimport { PuppeteerParameters } from './puppeteer/puppeteer-parameters.interface';\n\n@Injectable()\nexport class NestjsPdfService {\n readonly #puppeteerService: PuppeteerService;\n\n constructor(puppeteerService: PuppeteerService) {\n this.#puppeteerService = puppeteerService;\n }\n\n /**\n * @param html HTML string to convert to PDF\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided HTML\n * @description This method uses the Puppeteer service to generate a PDF from an HTML string. Generation options can be customized by passing a `PuppeteerParameters` object as the second argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromHtml(html: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromHtml(html, options);\n }\n\n /**\n * @param template Handlebars template string\n * @param parameters Data parameters to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Handlebars template with parameters applied\n * @description This method generates a PDF from a Handlebars template provided as a string. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromTemplateHbsString(\n template: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromTemplateHbsString(\n template,\n parameters,\n options,\n );\n }\n\n /**\n * @param file Path to the Handlebars template file\n * @param parameters Data parameters to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Handlebars template at the provided file path with parameters applied\n * @description This method generates a PDF from a Handlebars template located at the specified file path. The file path is passed as a string in the `file` parameter. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromTemplateHbsFile(\n file: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromTemplateHbsFile(\n file,\n parameters,\n options,\n );\n }\n\n /**\n * @param template MJML template string\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided MJML template\n * @description This method generates a PDF from an MJML template provided as a string. MJML (MJML Markup Language) is a markup language designed to reduce the pain of coding a responsive email. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.\n */\n generatePdfFromMjmlString(template: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromMjmlString(template, options);\n }\n\n /**\n * @param file Path to the MJML template file\n * @param options PDF generation options (optional)\n * @returns PDF generated from the MJML template at the provided file path\n * @description This method generates a PDF from an MJML template located at the specified file path. The file path is passed as a string in the `file` parameter. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.\n */\n generatePdfFromMjmlFile(file: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromMjmlFile(file, options);\n }\n\n /**\n * @param template EJS template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided EJS template with data applied\n * @description This method generates a PDF from an EJS (Embedded JavaScript) template provided as a string. EJS is a templating language with a simple, straightforward syntax. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEjsString(\n template: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEjsString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the EJS template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the EJS template at the provided file path with data applied\n * @description This method generates a PDF from an EJS template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEjsFile(\n file: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEjsFile(file, data, options);\n }\n\n /**\n * @param template Pug template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Pug template with data applied\n * @description This method generates a PDF from a Pug template provided as a string. Pug is a clean, whitespace-sensitive syntax for writing HTML. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromPugString(\n template: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromPugString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Pug template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Pug template at the provided file path with data applied\n * @description This method generates a PDF from a Pug template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromPugFile(\n file: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromPugFile(file, data, options);\n }\n\n /**\n * @param template Nunjucks template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Nunjucks template with data applied\n * @description This method generates a PDF from a Nunjucks template provided as a string. Nunjucks is a powerful templating language with support for inheritance, macros, and filters. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromNunjucksString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromNunjucksString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Nunjucks template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Nunjucks template at the provided file path with data applied\n * @description This method generates a PDF from a Nunjucks template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromNunjucksFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromNunjucksFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param template Eta template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Eta template with data applied\n * @description This method generates a PDF from an Eta template provided as a string. Eta is a fast and lightweight embedded templating language with a syntax similar to EJS but with better performance. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEtaString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEtaString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Eta template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Eta template at the provided file path with data applied\n * @description This method generates a PDF from an Eta template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEtaFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEtaFile(file, data, options);\n }\n\n /**\n * @param template Mustache template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Mustache template with data applied\n * @description This method generates a PDF from a Mustache template provided as a string. Mustache is a logic-less template language that emphasizes readable and simple templates. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromMustacheString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromMustacheString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Mustache template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Mustache template at the provided file path with data applied\n * @description This method generates a PDF from a Mustache template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromMustacheFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromMustacheFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param template Liquid template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Liquid template with data applied\n * @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.\n */\n generatePdfFromLiquidString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromLiquidString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Liquid template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Liquid template at the provided file path with data applied\n * @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.\n */\n generatePdfFromLiquidFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromLiquidFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param pdf The PDF bytes to modify\n * @param fieldName The name of the signature field to add (default: 'SignatureDebtor')\n * @param anchorText The text anchor to locate the signature field position (default: '__SIG_DEBTOR_ANCHOR__')\n * @returns Modified PDF with a signature field added at the anchor position\n * @description This method adds a signature field to a PDF using a text anchor as a reference for the field position. It uses the `addSignatureFieldUsingAnchor` function which finds the anchor in the PDF and inserts a signature field at that location. The signature field is named according to the `fieldName` parameter and the anchor is defined by `anchorText`.\n *\n * Usage example:\n * ```typescript\n * const modifiedPdf = await pdfService.addSignatureFieldSignatureDebtorRaw(\n * originalPdfBytes,\n * 'SignatureDebtor',\n * '__SIG_DEBTOR_ANCHOR__'\n * );\n * ```\n *\n * In this example, `originalPdfBytes` is a byte array representing the original PDF, `SignatureDebtor` is the name of the signature field to add, and `__SIG_DEBTOR_ANCHOR__` is the anchor text used to position the signature field in the PDF.\n *\n * If the anchor is not found, the signature field will be added at a default position (centered at the bottom of the last page).\n *\n * Note: Ensure that the input PDF contains the anchor defined by `anchorText` for the signature field to be positioned correctly. Otherwise, it will be added at a default position.\n */\n async addSignatureFieldSignatureDebtorRaw(\n pdf: Uint8Array | Buffer,\n fieldName: string = 'SignatureDebtor',\n anchorText: string = '__SIG_DEBTOR_ANCHOR__',\n ) {\n return await addSignatureFieldUsingAnchor(pdf, fieldName, anchorText);\n }\n\n /**\n * @param pdf The PDF bytes to modify\n * @param options Watermark options (`text` or `image` is required)\n * @returns Modified PDF with the watermark stamped on the selected pages\n * @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`.\n *\n * ```typescript\n * const watermarked = await pdfService.addWatermark(pdf, {\n * text: 'CONFIDENTIAL',\n * color: '#ff0000',\n * opacity: 0.2,\n * });\n * ```\n *\n * Text uses the PDF standard fonts, which only support WinAnsi characters; use an `image` for anything else.\n * @throws WatermarkException when the options are invalid or the PDF cannot be processed\n */\n async addWatermark(pdf: Uint8Array | Buffer, options: WatermarkOptions) {\n return await addWatermark(pdf, options);\n }\n}\n","import {\n DynamicModule,\n Inject,\n InjectionToken,\n Module,\n ModuleMetadata,\n OnModuleInit,\n OptionalFactoryDependency,\n Provider,\n} from '@nestjs/common';\n\nimport { PDF_PARAMETERS } from '../helpers/tokens';\nimport { BrowserService } from './browser/browser.service';\nimport { EjsService } from './engines/ejs/ejs.service';\nimport { EtaService } from './engines/eta/eta.service';\nimport { HandlebarsService } from './engines/handlebars/handlebars.service';\nimport { LiquidService } from './engines/liquid/liquid.service';\nimport { MjmlService } from './engines/mjml/mjml.service';\nimport { MustacheService } from './engines/mustache/mustache.service';\nimport { NunjucksService } from './engines/nunjucks/nunjucks.service';\nimport { PugService } from './engines/pug/pug.service';\nimport { PuppeteerService } from './puppeteer.service';\nimport type { PuppeteerParameters } from './puppeteer-parameters.interface';\n\nexport interface PuppeteerModuleAsyncOptions extends Pick<\n ModuleMetadata,\n 'imports'\n> {\n inject?: Array<InjectionToken | OptionalFactoryDependency>;\n useFactory: (\n ...args: Array<any>\n ) => Promise<PuppeteerParameters> | PuppeteerParameters;\n}\n\n@Module({\n providers: [\n PuppeteerService,\n BrowserService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n})\nexport class PuppeteerModule implements OnModuleInit {\n readonly #browserService: BrowserService;\n readonly #pdfParams: PuppeteerParameters;\n\n constructor(\n browserService: BrowserService,\n @Inject(PDF_PARAMETERS) pdfParams: PuppeteerParameters,\n ) {\n this.#browserService = browserService;\n this.#pdfParams = pdfParams;\n }\n\n async onModuleInit() {\n if (!this.#pdfParams.executablePath) {\n await this.#browserService.install(\n this.#pdfParams.useLockedBrowser ?? false,\n );\n }\n }\n\n static forRoot(pdfParameters: PuppeteerParameters): DynamicModule {\n const providers: Array<Provider> = [\n {\n provide: PDF_PARAMETERS,\n useValue: pdfParameters,\n },\n HandlebarsService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ];\n\n return {\n module: PuppeteerModule,\n providers,\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n };\n }\n\n static forRootAsync(options: PuppeteerModuleAsyncOptions): DynamicModule {\n const pdfParamsProvider: Provider = {\n provide: PDF_PARAMETERS,\n inject: options.inject ?? [],\n useFactory: async (...args: Array<unknown>) =>\n options.useFactory(...args),\n };\n\n return {\n module: PuppeteerModule,\n imports: options.imports ?? [],\n providers: [\n pdfParamsProvider,\n PuppeteerService,\n BrowserService,\n HandlebarsService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n };\n }\n}\n","import { DynamicModule, Module, ModuleMetadata } from '@nestjs/common';\n\nimport { NestjsPdfService } from './nestjs-pdf.service';\nimport { PuppeteerModule } from './puppeteer/puppeteer.module';\nimport { PuppeteerParameters } from './puppeteer/puppeteer-parameters.interface';\n\nexport interface PdfLibModuleAsyncOptions extends Pick<\n ModuleMetadata,\n 'imports'\n> {\n inject?: Array<any>;\n useFactory: (...args: Array<any>) => any;\n}\n\n@Module({})\nexport class NestjsPdfModule {\n static forRoot(options: PuppeteerParameters): DynamicModule {\n return {\n module: NestjsPdfModule,\n imports: [PuppeteerModule.forRoot(options)],\n providers: [NestjsPdfService],\n exports: [NestjsPdfService],\n };\n }\n\n static forRootAsync(options: PdfLibModuleAsyncOptions): DynamicModule {\n return {\n module: NestjsPdfModule,\n imports: [PuppeteerModule.forRootAsync(options)],\n providers: [NestjsPdfService],\n exports: [NestjsPdfService],\n };\n }\n}\n"],"ignoreList":[13,14],"mappings":"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"}