import { PDFDocument } from 'pdf-lib'; import fontkit from '@pdf-lib/fontkit'; import type { GenerateProps, Template, Font } from '@pdfme/common'; import { getDefaultFont, getFallbackFontName, checkGenerateProps } from '@pdfme/common'; import { getEmbeddedPagesAndEmbedPdfBoxes, drawInputByTemplateSchema, drawEmbeddedPage, embedAndGetFontObj, InputImageCache, } from './helper'; import { TOOL_NAME } from './constants'; const preprocessing = async (arg: { inputs: { [key: string]: string }[]; template: Template; font: Font; }) => { const { template, font } = arg; const { basePdf } = template; const pdfDoc = await PDFDocument.create(); pdfDoc.registerFontkit(fontkit); const fallbackFontName = getFallbackFontName(font); const fontObj = await embedAndGetFontObj({ pdfDoc, font }); const pagesAndBoxes = await getEmbeddedPagesAndEmbedPdfBoxes({ pdfDoc, basePdf }); const { embeddedPages, embedPdfBoxes } = pagesAndBoxes; return { pdfDoc, fontObj, fallbackFontName, embeddedPages, embedPdfBoxes }; }; const postProcessing = (pdfDoc: PDFDocument) => { pdfDoc.setProducer(TOOL_NAME); pdfDoc.setCreator(TOOL_NAME); }; const generate = async (props: GenerateProps) => { checkGenerateProps(props); const { inputs, template, options = {} } = props; const { font = getDefaultFont(), splitThreshold = 3 } = options; const { schemas } = template; const preRes = await preprocessing({ inputs, template, font }); const { pdfDoc, fontObj, fallbackFontName, embeddedPages, embedPdfBoxes } = preRes; const inputImageCache: InputImageCache = {}; for (let i = 0; i < inputs.length; i += 1) { const inputObj = inputs[i]; const keys = Object.keys(inputObj); for (let j = 0; j < embeddedPages.length; j += 1) { const embeddedPage = embeddedPages[j]; const { width: pageWidth, height: pageHeight } = embeddedPage; const embedPdfBox = embedPdfBoxes[j]; const page = pdfDoc.addPage([pageWidth, pageHeight]); drawEmbeddedPage({ page, embeddedPage, embedPdfBox }); for (let l = 0; l < keys.length; l += 1) { const key = keys[l]; const schema = schemas[j]; const templateSchema = schema[key]; const input = inputObj[key]; const textSchemaSetting = { fontObj, fallbackFontName, splitThreshold }; // eslint-disable-next-line no-await-in-loop await drawInputByTemplateSchema({ input, templateSchema, pdfDoc, page, pageHeight, textSchemaSetting, inputImageCache, }); } } } postProcessing(pdfDoc); return pdfDoc.save(); }; export default generate;