UNPKG

safeer-pdf-generator

Version:

Framework-agnostic PDF generation library with chunking, merging, S3 upload, and email delivery

258 lines 10.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.mergePdfs = mergePdfs; exports.mergePdfFiles = mergePdfFiles; exports.analyzePdfs = analyzePdfs; exports.validatePdfs = validatePdfs; exports.splitPdf = splitPdf; exports.extractPages = extractPages; exports.getPdfInfo = getPdfInfo; exports.mergePdfsWithRanges = mergePdfsWithRanges; exports.batchMergePdfs = batchMergePdfs; const MergeService_js_1 = require("../core/MergeService.js"); const guards_js_1 = require("../utils/guards.js"); const errors_js_1 = require("../core/errors.js"); const defaults_js_1 = require("../config/defaults.js"); /** * Merge multiple PDF buffers into a single PDF */ async function mergePdfs(pdfBuffers, options = {}) { const logger = options.logging || defaults_js_1.noOpLogger; // Validate inputs if (!Array.isArray(pdfBuffers) || pdfBuffers.length === 0) { throw new errors_js_1.MergeError('At least one PDF buffer is required'); } // Validate all inputs are buffers for (let i = 0; i < pdfBuffers.length; i++) { if (!(0, guards_js_1.isBuffer)(pdfBuffers[i])) { throw new errors_js_1.MergeError(`Item at index ${i} is not a buffer`); } } const mergeService = new MergeService_js_1.MergeService(logger); return await mergeService.mergePdfs(pdfBuffers, options); } /** * Merge PDF files from file paths */ async function mergePdfFiles(filePaths, options = {}) { const { promises: fs } = await Promise.resolve().then(() => __importStar(require('fs'))); const logger = options.logging || defaults_js_1.noOpLogger; if (!Array.isArray(filePaths) || filePaths.length === 0) { throw new errors_js_1.MergeError('At least one file path is required'); } logger.info(`Loading ${filePaths.length} PDF files for merging`); // Read all files const buffers = []; for (let i = 0; i < filePaths.length; i++) { const filePath = filePaths[i]; try { logger.debug(`Reading file: ${filePath}`); const buffer = await fs.readFile(filePath); buffers.push(buffer); } catch (error) { throw new errors_js_1.MergeError(`Failed to read file at index ${i}: ${filePath}`, filePaths.length, error); } } return await mergePdfs(buffers, options); } /** * Analyze PDF buffers without merging */ async function analyzePdfs(pdfBuffers, options = {}) { const logger = options.logging || defaults_js_1.noOpLogger; if (!Array.isArray(pdfBuffers) || pdfBuffers.length === 0) { throw new errors_js_1.MergeError('At least one PDF buffer is required for analysis'); } const mergeService = new MergeService_js_1.MergeService(logger); return await mergeService.analyzePdfs(pdfBuffers); } /** * Validate PDF buffers */ async function validatePdfs(pdfBuffers, options = {}) { const logger = options.logging || defaults_js_1.noOpLogger; if (!Array.isArray(pdfBuffers)) { return { valid: false, errors: [{ chunkIndex: -1, error: 'Input is not an array' }], }; } if (pdfBuffers.length === 0) { return { valid: false, errors: [{ chunkIndex: -1, error: 'No PDF buffers provided' }], }; } const mergeService = new MergeService_js_1.MergeService(logger); return await mergeService.validatePdfs(pdfBuffers); } /** * Split a PDF into individual page buffers */ async function splitPdf(pdfBuffer, options = {}) { const logger = options.logging || defaults_js_1.noOpLogger; if (!(0, guards_js_1.isBuffer)(pdfBuffer)) { throw new errors_js_1.MergeError('Input must be a buffer'); } if (pdfBuffer.length === 0) { throw new errors_js_1.MergeError('PDF buffer is empty'); } const mergeService = new MergeService_js_1.MergeService(logger); return await mergeService.splitPdf(pdfBuffer); } /** * Extract specific pages from a PDF */ async function extractPages(pdfBuffer, pageIndices, options = {}) { const logger = options.logging || defaults_js_1.noOpLogger; if (!(0, guards_js_1.isBuffer)(pdfBuffer)) { throw new errors_js_1.MergeError('Input must be a buffer'); } if (!Array.isArray(pageIndices) || pageIndices.length === 0) { throw new errors_js_1.MergeError('Page indices must be a non-empty array'); } // Validate page indices are numbers (but allow negative/out-of-range, service will filter) for (const index of pageIndices) { if (typeof index !== 'number' || !Number.isInteger(index)) { throw new errors_js_1.MergeError('All page indices must be integers'); } } const mergeService = new MergeService_js_1.MergeService(logger); return await mergeService.extractPages(pdfBuffer, pageIndices); } /** * Get information about a PDF */ async function getPdfInfo(pdfBuffer, options = {}) { const logger = options.logging || defaults_js_1.noOpLogger; if (!(0, guards_js_1.isBuffer)(pdfBuffer)) { throw new errors_js_1.MergeError('Input must be a buffer'); } if (pdfBuffer.length === 0) { throw new errors_js_1.MergeError('PDF buffer is empty'); } const mergeService = new MergeService_js_1.MergeService(logger); return await mergeService.getPdfInfo(pdfBuffer); } /** * Merge PDFs with custom page ranges */ async function mergePdfsWithRanges(inputs, options = {}) { const logger = options.logging || defaults_js_1.noOpLogger; if (!Array.isArray(inputs) || inputs.length === 0) { throw new errors_js_1.MergeError('At least one input is required'); } logger.info(`Merging ${inputs.length} PDFs with custom page ranges`); const extractedBuffers = []; const mergeService = new MergeService_js_1.MergeService(logger); for (let i = 0; i < inputs.length; i++) { const input = inputs[i]; if (!(0, guards_js_1.isBuffer)(input.buffer)) { throw new errors_js_1.MergeError(`Input at index ${i} must have a buffer property`); } try { let pageIndices; if (input.pages) { // Use specific pages pageIndices = input.pages; } else if (input.startPage !== undefined || input.endPage !== undefined) { // Use page range const pdfInfo = await mergeService.getPdfInfo(input.buffer); const startPage = input.startPage || 0; const endPage = input.endPage !== undefined ? input.endPage : pdfInfo.pages - 1; pageIndices = []; for (let page = startPage; page <= Math.min(endPage, pdfInfo.pages - 1); page++) { pageIndices.push(page); } } else { // Include all pages - just add the buffer as-is extractedBuffers.push(input.buffer); continue; } // Extract the specified pages const extractedBuffer = await mergeService.extractPages(input.buffer, pageIndices); extractedBuffers.push(extractedBuffer); logger.debug(`Processed input ${i + 1}: extracted ${pageIndices.length} pages`); } catch (error) { throw new errors_js_1.MergeError(`Failed to process input at index ${i}`, inputs.length, error); } } // Merge all extracted buffers return await mergePdfs(extractedBuffers, options); } /** * Batch merge multiple sets of PDFs */ async function batchMergePdfs(batches, options = {}) { const logger = options.logging || defaults_js_1.noOpLogger; const concurrency = options.concurrency || 2; if (!Array.isArray(batches) || batches.length === 0) { throw new errors_js_1.MergeError('At least one batch is required'); } logger.info(`Batch merging ${batches.length} PDF sets with concurrency ${concurrency}`); const results = []; let currentIndex = 0; const processBatch = async () => { while (currentIndex < batches.length) { const index = currentIndex++; if (index >= batches.length) return; const batch = batches[index]; const batchName = options.batchNames?.[index] || `batch-${index + 1}`; try { logger.debug(`Processing ${batchName} with ${batch.length} PDFs`); const mergedBuffer = await mergePdfs(batch, options); results[index] = mergedBuffer; logger.debug(`Completed ${batchName}`); } catch (error) { throw new errors_js_1.MergeError(`Failed to merge ${batchName}`, batches.length, error); } } }; // Create worker promises with concurrency limit const workers = Array(Math.min(concurrency, batches.length)) .fill(null) .map(() => processBatch()); await Promise.all(workers); logger.info(`Batch merge completed: ${results.length} merged PDFs`); return results; } //# sourceMappingURL=mergePdfs.js.map