import { readFileSync } from 'fs' import * as parser from 'string-interpolation-parser' import { Injectable } from '@nestjs/common' import { Browser } from 'puppeteer-core' import { StorageService } from '../storage' import { sleep } from '../../utils/async' // eslint-disable-next-line @typescript-eslint/no-var-requires const chromium = require('chrome-aws-lambda') export type DynamicData = { [key: string]: any } export type PDFOptions = { filePath?: string; html?: string; dynamicData?: DynamicData } @Injectable() export class PDFService { constructor(private readonly storageService: StorageService) {} async generatePDFAndUpload(pdfOptions: PDFOptions, path: string): Promise { const pdf = await this.generatePDF(pdfOptions) return this.storageService.upload(path, pdf, 'application/pdf') } async generatePDF({ filePath, html, dynamicData }: PDFOptions): Promise { let file = filePath ? readFileSync(filePath, 'utf-8').toString() : html if (dynamicData) { const { body } = parser({ body: file }, dynamicData) file = body } const browser: Browser = await chromium.puppeteer.launch({ args: chromium.args, defaultViewport: chromium.defaultViewport, executablePath: await chromium.executablePath, headless: chromium.headless || process.env.IS_LOCAL, ignoreHTTPSErrors: true, }) const page = await browser.newPage() await page.setContent(file) await sleep(1000) const buffer = await page.pdf({ printBackground: true, format: 'a4', margin: { bottom: 47, top: 47, right: 72, left: 72, }, }) browser.close() return buffer } }