import { Buffer } from "buffer"; import path from "path"; import { RemoteExceptionP__Output } from "../generated_proto/ironpdfengineproto/RemoteExceptionP"; import { ImageBuffer, ImageFilePath, PageInfo, PdfInput, PdfPageSelection, } from "../../public/types"; import { ImageInput, PdfInputType } from "../internalType"; import { PdfDocument } from "../../public/pdfDocument"; import { PdfDocumentResultP__Output } from "../generated_proto/ironpdfengineproto/PdfDocumentResultP"; import { EmptyResultP__Output } from "../generated_proto/ironpdfengineproto/EmptyResultP"; import { ImageType } from "../../public/image"; import { getPageInfo } from "./pdfium/page"; export function handleRemoteException( proto: RemoteExceptionP__Output, reject: (errorMsg: string) => void ): void { reject( `${proto.exceptionType} ${proto.message} \n ${proto.remoteStackTrace} \n ${proto.rootException}` ); } export const CHUNK_SIZE = 65536; export function chunkString(str: string): Array | null { return str.match(/.{1,65536}/g); } export function chunkBuffer(buffer: Buffer): Buffer[] { const chunks: Buffer[] = []; for (let i = 0; i < buffer.length; i += CHUNK_SIZE) { const chunk = buffer.subarray(i, i + CHUNK_SIZE); chunks.push(chunk); } return chunks; } const urlPattern = new RegExp( "^(https?:\\/\\/)?" + // validate protocol "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // validate domain name "((\\d{1,3}\\.){3}\\d{1,3}))" + // validate OR ip (v4) address "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // validate port and path "(\\?[;&a-z\\d%_.~+=-]*)?" + // validate query string "(\\#[-a-z\\d_]*)?$", "i" ); // validate fragment locator function isValidUrl(urlString: string) { return urlPattern.test(urlString); } export function separatePdfInput(input: PdfInput): PdfInputType { if (typeof input === "string") { if (input.endsWith(".html") || input.endsWith(".htm")) { return { type: "htmlFile", htmlFile: input }; } else if (input.endsWith(".pdf")) { return { type: "pdfFile", pdfFile: input }; } else if (input.endsWith(".zip")) { return { type: "zipFile", zipFile: input }; } else if (input.indexOf("<") > -1) { return { type: "htmlString", htmlString: input }; } else if (isValidUrl(input)) { return { type: "url", url: new URL(input) }; } else { return { type: "htmlString", htmlString: input }; } } else if (input instanceof Buffer) { return { type: "buffer", buffer: input }; } else if (input instanceof URL) { return { type: "url", url: input }; } else if (input instanceof PdfDocument) return { type: "pdfDocument", pdfDocument: input }; throw new Error(`unknown input : ${input}`); } export function separateImageBufferOrImagePathInput( input: ImageFilePath | ImageBuffer ): ImageInput { if (typeof input === "string") { return { type: "imageFilePath", imageFilePath: input }; } else if (input instanceof Buffer) { return { type: "imageBuffer", imageBuffer: input }; } throw new Error(`unknown input : ${input}`); } export function handlePdfDocumentResultP__Output( proto: PdfDocumentResultP__Output | undefined, resolve: (_: string) => void, reject: (errorMsg: string) => void ) { if (proto) { if (proto?.exception) { handleRemoteException(proto.exception, reject); } if (proto.result) { resolve(proto.result.documentId!); } } // throw new Error("Error empty message"); } export function handleEmptyResultP__Output( proto: EmptyResultP__Output | undefined, reject: (errorMsg: string) => void ): void { if (proto?.exception) { handleRemoteException(proto.exception, reject); } } export async function AsyncPdfPageSelectionToIndexes( documentId: string, pdfPageSelection?: PdfPageSelection | undefined ): Promise { const result = pdfPageSelection ? typeof pdfPageSelection === "number" ? [pdfPageSelection] : Array.isArray(pdfPageSelection) ? pdfPageSelection : [] : []; if (result.length == 0) { return Array.from({ length: (await getPageInfo(documentId)).length, }).map((_, index) => index); } return result; } export function PdfPageSelectionToIndexes( pagesInfo: PageInfo[], pdfPageSelection?: PdfPageSelection | undefined ): number[] { const result = pdfPageSelection ? typeof pdfPageSelection === "number" ? [pdfPageSelection] : Array.isArray(pdfPageSelection) ? pdfPageSelection : [] : []; if (result.length == 0) { return Array.from({ length: pagesInfo.length, }).map((_, index) => index); } return result; } export function getFileNames( filePath: string, fileCount: number, specificFileExt?: string | undefined, defaultName = "output" ): string[] { const directory = path.dirname(filePath); const extensionFromString = path.extname(filePath); const baseName = path.basename(filePath, extensionFromString) ?? defaultName; let finalExtension = extensionFromString; if (specificFileExt && specificFileExt != extensionFromString) { finalExtension = extensionFromString + specificFileExt; // appended e.g. "c:/tmp/aa.jpg" -> "c:/tmp/aa.jpg.png" } if (fileCount == 1) { return [path.join(directory, `${baseName}${finalExtension}`)]; } else { return Array.from({ length: fileCount }, (_, i) => i).map((index) => { return path.join( directory, `${baseName}_${index}${finalExtension}` ); }); } } export function getFileName( filePath: string, fileSuffix: string, specificFileExt?: string | undefined, defaultName = "output" ): string { const directory = path.dirname(filePath); const extensionFromString = path.extname(filePath); const baseName = path.basename(filePath, extensionFromString) ?? defaultName; let finalExtension = extensionFromString; if (specificFileExt && specificFileExt != extensionFromString) { finalExtension = extensionFromString + specificFileExt; // appended e.g. "c:/tmp/aa.jpg" -> "c:/tmp/aa.jpg.png" } return path.join(directory, `${baseName}_${fileSuffix}${finalExtension}`); } export function getImageExtType(imageType?: ImageType | undefined): string | undefined { switch (imageType) { case ImageType.JPG: return ".jpg"; case ImageType.BMP: return ".bmp"; case ImageType.PNG: return ".png"; default: return undefined; } } // export function notNullOrEmpty(obj: T | null | undefined): obj is T { // return obj !== undefined && obj !== null; // // } export function isNullOrUndefined(obj: T | null | undefined): obj is null | undefined { return obj === undefined || obj === null; }