- Refactor PDF loading across workflow nodes to use loadPdfDocument utility

- Replaced direct calls to PDFDocument.load with loadPdfDocument in multiple nodes to standardize PDF loading process.
This commit is contained in:
alam00000 committed 2026-03-26 13:40:21 +05:30
1 parent 9d362b1cf8
commit 9278774b8a
110 files changed
+1413 -1196

No files matched your search

+3 -1
View File
@@ -97,7 +97,9 @@ export async function performCondenseCompression(
return { ...result, usedFallback: true };
} catch (fallbackError: any) {
const msg = fallbackError?.message || String(fallbackError);
throw new Error(`PDF compression failed: ${msg}`);
throw new Error(`PDF compression failed: ${msg}`, {
cause: fallbackError,
});
}
}
}
+2 -1
View File
@@ -52,7 +52,8 @@ export async function loadGhostscript(): Promise<GhostscriptInterface> {
} catch (error: any) {
loadPromise = null;
throw new Error(
`Failed to load Ghostscript from ${normalizedUrl}: ${error.message}`
`Failed to load Ghostscript from ${normalizedUrl}: ${error.message}`,
{ cause: error }
);
}
})();
+43 -35
View File
@@ -4,12 +4,9 @@
* Requires user to configure Ghostscript URL in WASM Settings.
*/
import {
getWasmBaseUrl,
fetchWasmFile,
isWasmAvailable,
} from '../config/wasm-cdn-config.js';
import { PDFDocument, PDFDict, PDFName, PDFArray } from 'pdf-lib';
import { getWasmBaseUrl, isWasmAvailable } from '../config/wasm-cdn-config.js';
import { PDFDict, PDFName, PDFArray } from 'pdf-lib';
import { loadPdfDocument } from './load-pdf-document.js';
interface GhostscriptModule {
FS: {
@@ -160,7 +157,9 @@ export async function convertToPdfA(
);
} catch (e) {
console.error('[Ghostscript] Failed to setup PDF/A assets:', e);
throw new Error('Conversion failed: could not create PDF/A definition');
throw new Error('Conversion failed: could not create PDF/A definition', {
cause: e,
});
}
const args = [
@@ -200,7 +199,7 @@ export async function convertToPdfA(
exitCode = gs.callMain(args);
} catch (e) {
console.error('[Ghostscript] Exception:', e);
throw new Error(`Ghostscript threw an exception: ${e}`);
throw new Error(`Ghostscript threw an exception: ${e}`, { cause: e });
}
console.log('[Ghostscript] Exit code:', exitCode);
@@ -208,23 +207,23 @@ export async function convertToPdfA(
if (exitCode !== 0) {
try {
gs.FS.unlink(inputPath);
} catch {
/* ignore */
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
try {
gs.FS.unlink(outputPath);
} catch {
/* ignore */
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
try {
gs.FS.unlink(iccPath);
} catch {
/* ignore */
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
try {
gs.FS.unlink(pdfaDefPath);
} catch {
/* ignore */
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
throw new Error(`Ghostscript conversion failed with exit code ${exitCode}`);
}
@@ -237,29 +236,29 @@ export async function convertToPdfA(
output = gs.FS.readFile(outputPath);
} catch (e) {
console.error('[Ghostscript] Failed to read output:', e);
throw new Error('Ghostscript did not produce output file');
throw new Error('Ghostscript did not produce output file', { cause: e });
}
// Cleanup
try {
gs.FS.unlink(inputPath);
} catch {
/* ignore */
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
try {
gs.FS.unlink(outputPath);
} catch {
/* ignore */
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
try {
gs.FS.unlink(iccPath);
} catch {
/* ignore */
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
try {
gs.FS.unlink(pdfaDefPath);
} catch {
/* ignore */
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
if (level !== 'PDF/A-1b') {
@@ -282,8 +281,7 @@ export async function convertToPdfA(
async function addPageGroupDictionaries(
pdfData: Uint8Array
): Promise<Uint8Array> {
const pdfDoc = await PDFDocument.load(pdfData, {
ignoreEncryption: true,
const pdfDoc = await loadPdfDocument(pdfData, {
updateMetadata: false,
});
@@ -352,7 +350,7 @@ async function addPageGroupDictionaries(
}
if (iccProfileRef) {
pdfDoc.context.enumerateIndirectObjects().forEach(([ref, obj]) => {
pdfDoc.context.enumerateIndirectObjects().forEach(([_ref, obj]) => {
if (
obj instanceof PDFDict ||
(obj && typeof obj === 'object' && 'dict' in obj)
@@ -437,17 +435,23 @@ export async function convertFontsToOutlines(
} catch (e) {
try {
gs.FS.unlink(inputPath);
} catch {}
throw new Error(`Ghostscript threw an exception: ${e}`);
} catch (e2) {
console.warn('[Ghostscript] Failed to clean up temp file:', e2);
}
throw new Error(`Ghostscript threw an exception: ${e}`, { cause: e });
}
if (exitCode !== 0) {
try {
gs.FS.unlink(inputPath);
} catch {}
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
try {
gs.FS.unlink(outputPath);
} catch {}
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
throw new Error(`Ghostscript conversion failed with exit code ${exitCode}`);
}
@@ -455,15 +459,19 @@ export async function convertFontsToOutlines(
try {
output = gs.FS.readFile(outputPath);
} catch (e) {
throw new Error('Ghostscript did not produce output file');
throw new Error('Ghostscript did not produce output file', { cause: e });
}
try {
gs.FS.unlink(inputPath);
} catch {}
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
try {
gs.FS.unlink(outputPath);
} catch {}
} catch (e) {
console.warn('[Ghostscript] Failed to clean up temp file:', e);
}
return output;
}
+14
View File
@@ -0,0 +1,14 @@
import { PDFDocument } from 'pdf-lib';
type LoadOptions = Parameters<typeof PDFDocument.load>[1];
type PDFDocumentInstance = Awaited<ReturnType<typeof PDFDocument.load>>;
export async function loadPdfDocument(
pdf: Uint8Array | ArrayBuffer,
options?: LoadOptions
): Promise<PDFDocumentInstance> {
return PDFDocument.load(pdf, {
ignoreEncryption: true,
...options,
});
}
+10 -9
View File
@@ -1,11 +1,12 @@
import { PDFDocument, degrees, rgb, StandardFonts, PageSizes } from 'pdf-lib';
import { loadPdfDocument } from './load-pdf-document.js';
export async function mergePdfs(
pdfBytesList: Uint8Array[]
): Promise<Uint8Array> {
const mergedDoc = await PDFDocument.create();
for (const bytes of pdfBytesList) {
const srcDoc = await PDFDocument.load(bytes);
const srcDoc = await loadPdfDocument(bytes);
const copiedPages = await mergedDoc.copyPages(
srcDoc,
srcDoc.getPageIndices()
@@ -19,7 +20,7 @@ export async function splitPdf(
pdfBytes: Uint8Array,
pageIndices: number[]
): Promise<Uint8Array> {
const srcDoc = await PDFDocument.load(pdfBytes);
const srcDoc = await loadPdfDocument(pdfBytes);
const newPdf = await PDFDocument.create();
const copiedPages = await newPdf.copyPages(srcDoc, pageIndices);
copiedPages.forEach((page) => newPdf.addPage(page));
@@ -30,7 +31,7 @@ export async function rotatePdfUniform(
pdfBytes: Uint8Array,
angle: number
): Promise<Uint8Array> {
const srcDoc = await PDFDocument.load(pdfBytes);
const srcDoc = await loadPdfDocument(pdfBytes);
const newPdfDoc = await PDFDocument.create();
const pageCount = srcDoc.getPageCount();
@@ -75,7 +76,7 @@ export async function rotatePdfPages(
pdfBytes: Uint8Array,
rotations: number[]
): Promise<Uint8Array> {
const srcDoc = await PDFDocument.load(pdfBytes);
const srcDoc = await loadPdfDocument(pdfBytes);
const newPdfDoc = await PDFDocument.create();
const pageCount = srcDoc.getPageCount();
@@ -121,7 +122,7 @@ export async function deletePdfPages(
pdfBytes: Uint8Array,
pagesToDelete: Set<number>
): Promise<Uint8Array> {
const srcDoc = await PDFDocument.load(pdfBytes);
const srcDoc = await loadPdfDocument(pdfBytes);
const totalPages = srcDoc.getPageCount();
const pagesToKeep: number[] = [];
@@ -196,7 +197,7 @@ export async function addTextWatermark(
pdfBytes: Uint8Array,
options: TextWatermarkOptions
): Promise<Uint8Array> {
const pdfDoc = await PDFDocument.load(pdfBytes);
const pdfDoc = await loadPdfDocument(pdfBytes);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
@@ -274,7 +275,7 @@ export async function addImageWatermark(
pdfBytes: Uint8Array,
options: ImageWatermarkOptions
): Promise<Uint8Array> {
const pdfDoc = await PDFDocument.load(pdfBytes);
const pdfDoc = await loadPdfDocument(pdfBytes);
const image =
options.imageType === 'png'
? await pdfDoc.embedPng(options.imageBytes)
@@ -330,7 +331,7 @@ export async function addPageNumbers(
pdfBytes: Uint8Array,
options: PageNumberOptions
): Promise<Uint8Array> {
const pdfDoc = await PDFDocument.load(pdfBytes);
const pdfDoc = await loadPdfDocument(pdfBytes);
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica);
const pages = pdfDoc.getPages();
const totalPages = pages.length;
@@ -481,7 +482,7 @@ export async function fixPageSize(
[targetWidth, targetHeight] = [targetHeight, targetWidth];
}
const sourceDoc = await PDFDocument.load(pdfBytes);
const sourceDoc = await loadPdfDocument(pdfBytes);
const outputDoc = await PDFDocument.create();
for (const sourcePage of sourceDoc.getPages()) {
+3 -1
View File
@@ -67,7 +67,9 @@ export async function loadPyMuPDF(): Promise<any> {
return cachedPyMuPDF;
} catch (error: any) {
loadPromise = null;
throw new Error(`Failed to load PyMuPDF from CDN: ${error.message}`);
throw new Error(`Failed to load PyMuPDF from CDN: ${error.message}`, {
cause: error,
});
}
})();
+2 -1
View File
@@ -1,4 +1,5 @@
import { PDFDocument, PDFName } from 'pdf-lib';
import { loadPdfDocument } from './load-pdf-document.js';
export interface SanitizeOptions {
flattenForms: boolean;
@@ -503,7 +504,7 @@ export async function sanitizePdf(
pdfBytes: Uint8Array,
options: SanitizeOptions
): Promise<{ pdfDoc: PDFDocument; bytes: Uint8Array }> {
const pdfDoc = await PDFDocument.load(pdfBytes);
const pdfDoc = await loadPdfDocument(pdfBytes);
if (options.flattenForms) {
try {