UNPKG

@ironsoftware/ironpdf

Version:

IronPDF for Node

420 lines 19.8 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 (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.getOsArch = exports.ironPdfEngineExecutable = exports.getPlatformName = exports.getOsName = exports.Access = void 0; const path = __importStar(require("path")); const grpc = __importStar(require("@grpc/grpc-js")); const protoLoader = __importStar(require("@grpc/proto-loader")); const Os = __importStar(require("os")); const fs = __importStar(require("fs")); const glob_1 = require("glob"); const https = __importStar(require("https")); const unzipper = __importStar(require("unzipper")); const child_process_1 = require("child_process"); const net = __importStar(require("net")); const util = __importStar(require("util")); const ironpdfglobalconfig_1 = require("../public/ironpdfglobalconfig"); const handshake_1 = require("./grpc_layer/handshake"); const system_1 = require("./grpc_layer/system"); class Access { constructor() { if (Access._instance) { throw new Error("Error: Instantiation failed: Use Access.getInstance() instead of new."); } Access._instance = this; } static get Instance() { return this._instance || (this._instance = new this()); } static forceShutdown() { var _b; if (this.ironPdfEngineProcess) (_b = this.ironPdfEngineProcess) === null || _b === void 0 ? void 0 : _b.kill(); } static downloadFromCDN() { return new Promise((resolve, reject) => { let redirectCount = 0; const zipFilePath = "./ironPdfEngineDownload.zip"; const downloadZip = (url) => { https .get(url, (response) => { if (response.statusCode === 302 || response.statusCode === 301) { if (redirectCount >= 5) { reject("Too many redirects"); return; } redirectCount++; const redirectUrl = response.headers.location; if (!redirectUrl) { reject(`Invalid redirect URL code: ${response.statusCode} : ${redirectUrl}`); } downloadZip(redirectUrl); return; } if (response.statusCode !== 200) { reject(`Invalid status code: ${response.statusCode}`); return; } const totalLength = parseInt(response.headers["content-length"], 10); let downloadedLength = 0; const zipFile = fs.createWriteStream(zipFilePath); let lastLoggedPercent = 0; response.on("data", (data) => { downloadedLength += data.length; const percent = Math.floor(((downloadedLength / totalLength) * 100) / 10) * 10; if (percent > lastLoggedPercent && percent < 100) { console.debug(`Download IronPdfEngine progress: ${percent}%`); lastLoggedPercent = percent; } zipFile.write(data); }); response.on("end", () => { console === null || console === void 0 ? void 0 : console.log(`Download IronPdfEngine complete`); zipFile.end(); }); zipFile.on("finish", () => { console === null || console === void 0 ? void 0 : console.log(`Extract IronPdfEngine Zip to ${this.targetDir}`); const readStream = fs.createReadStream(zipFilePath); readStream.on("open", () => { readStream .pipe(unzipper.Extract({ path: this.targetDir, })) .on("close", () => { try { fs.unlinkSync(zipFilePath); } catch (e) { } resolve(); }) .on("error", (error) => { reject(`Error extracting ZIP file: ${error}`); }); }); readStream.on("error", (error) => { reject(`Error reading ZIP file: ${error}`); }); }); response.on("error", (error) => { reject(`Error downloading ZIP file: ${error}`); }); }) .on("error", (error) => { reject(`Error downloading ZIP file: ${error}`); }); }; const zipUrl = `https://ironpdfengine.azurewebsites.net/api/IronPdfEngineDownload?version=${ironpdfglobalconfig_1.IronPdfGlobalConfig.ironPdfEngineVersion}&platform=${getPlatformName()}&architect=${getOsArch()}`; console.debug("Download IronPdfEngine"); downloadZip(zipUrl); }); } static tryDeleteUnusedEngineBin(baseDir, excludeFolder) { return __awaiter(this, void 0, void 0, function* () { try { //const folders = await glob(path.join(baseDir, 'ironpdf-engine-bin-*')); const wc = path .join(baseDir, "ironpdfenginebin*") .replace(/\\/g, "/"); const folders = yield glob_1.glob.glob(wc, { absolute: true }); // exclude the folder you don't want to delete const foldersToDelete = folders.filter((folder) => path.basename(folder) !== excludeFolder); // delete all other folders yield Promise.all(foldersToDelete.map((folder) => fs.promises.rmdir(folder, { recursive: true }))); } catch (err) { } }); } static getAvailableIronPdfEngineFile() { return __awaiter(this, void 0, void 0, function* () { let dir; try { const ironPdfEnginePackageName = `@ironsoftware/ironpdf-engine-${getOsName()}-${getOsArch()}`; // eslint-disable-next-line @typescript-eslint/no-var-requires const ironPdfEnginePackage = require(ironPdfEnginePackageName); dir = `${ironPdfEnginePackage.dir}${path.sep}ironpdf-engine-bin-${ironPdfEnginePackage.version}`; console.debug(`FOUND ${ironPdfEnginePackageName}:${ironPdfEnginePackage.version} at:${dir}`); } catch (e) { //NOT FOUND ironpdf-engine-windows-x64, ignore //if files exists Locally const isLocalFilesExists = fs.existsSync(`${this.targetDir}${path.sep}${ironPdfEngineExecutable()}`); if (!isLocalFilesExists) { yield this.downloadFromCDN(); } dir = this.targetDir; } yield tryChangePermissions(dir, "777"); return `${dir}${path.sep}${ironPdfEngineExecutable()}`; }); } static startServer() { var _b, _c, _d, _e, _f; return __awaiter(this, void 0, void 0, function* () { const config = ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig(); if (config.debugMode) console.debug("Start IronPdfEngine"); const ironPdfEngineBinPath = yield this.getAvailableIronPdfEngineFile(); if (config.debugMode) console.debug(`IronPdfEngine bin: ${ironPdfEngineBinPath}`); let host = "localhost"; let port = "33350"; if (config.ironPdfEngineAddress) { const splitter = config.ironPdfEngineAddress.lastIndexOf(":"); host = config.ironPdfEngineAddress.substring(0, splitter); port = config.ironPdfEngineAddress.substring(splitter + 1); this.ironPdfEngineAddress = config.ironPdfEngineAddress; } const args = [ `host=${host}`, `port=${port}`, `docker_build=false`, `keep_alive=true`, `linux_and_docker_auto_config=false`, `skip_initialization=false`, `single_process=${(_b = config.singleProcess) !== null && _b !== void 0 ? _b : getOsName() == "macos"}`, `chrome_browser_limit=${(_c = config.chromeBrowserLimit) !== null && _c !== void 0 ? _c : "30"}`, `chrome_gpu_mode=${(_d = config.chromeGpuMode) !== null && _d !== void 0 ? _d : 0}`, `linux_and_docker_auto_config=${(_e = config.autoInstallDependency) !== null && _e !== void 0 ? _e : "true"}`, `programming_language=nodejs` ]; if (config.debugMode) { args.push(`enable_debug=true`); args.push(`log_path=./IronPdfEngine.log`); } else { args.push(`enable_debug=false`); } if (config.chromeBrowserCachePath) { args.push(`chrome_cache_path=${config.chromeBrowserCachePath}`); } if (config.debugMode) { console.debug("args:" + JSON.stringify(args)); } const ironPdfEngineProcess = (0, child_process_1.spawn)(`${ironPdfEngineBinPath}`, args, { detached: false, stdio: ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().debugMode ? ["ignore"] : "ignore", }) .on("error", (err) => console === null || console === void 0 ? void 0 : console.debug(`spawn IRON_PDF_ENGINE error: ${err}`)) .on("message", (err) => console === null || console === void 0 ? void 0 : console.debug(`spawn IRON_PDF_ENGINE message: ${err}`)); this.ironPdfEngineProcess = ironPdfEngineProcess; if (ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().debugMode) { (_f = this.ironPdfEngineProcess.stdout) === null || _f === void 0 ? void 0 : _f.on("data", (data) => { console === null || console === void 0 ? void 0 : console.debug(`[IRON_PDF_ENGINE] ${data}`); }); } process.on("exit", function () { ironPdfEngineProcess.kill(); }); process.on("beforeExit", function () { ironPdfEngineProcess.kill(); }); process.on("disconnect", function () { ironPdfEngineProcess.kill(); }); process.on("SIGINT", () => { ironPdfEngineProcess.kill(); }); process.on("SIGTERM", () => { ironPdfEngineProcess.kill(); }); this.ironPdfEngineProcess.unref(); Access.tryDeleteUnusedEngineBin(path.join(__dirname, `../..`), `ironpdf-engine-bin-${ironpdfglobalconfig_1.IronPdfGlobalConfig.ironPdfEngineVersion}`).then(); if (ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().debugMode) console.debug("wait for IronPdfEngine to start up "); yield this.waitUntilPortIsOpen(+port); yield new Promise((resolve) => setTimeout(resolve, 10000)); }); } static checkPort(port) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { const server = net .createServer() .once("error", (err) => { if (err.name !== "EADDRINUSE") reject(err); }) .once("listening", () => { server.close(); resolve(null); }) .listen(port); }); }); } static waitUntilPortIsOpen(port) { return __awaiter(this, void 0, void 0, function* () { while (true) { try { yield this.checkPort(port); break; } catch (err) { yield new Promise((resolve) => setTimeout(resolve, 1000)); } } }); } static ensureConnection() { var _b; return __awaiter(this, void 0, void 0, function* () { if (!this.client) { if (!ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().ironPdfEngineDockerAddress) { //local mode (non-docker) yield this.startServer(); } else { this.ironPdfEngineAddress = ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().ironPdfEngineDockerAddress; } for (let i = 0; i < 5; i++) { try { this.client = new this.grpcObj.ironpdfengineproto.IronPdfService(this.ironPdfEngineAddress, grpc.credentials.createInsecure()); break; } catch (e) { if (ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().debugMode) console.error(`Attempt ${i + 1} to connect to IronPdfEngine Retrying...`); yield new Promise(r => setTimeout(r, 2000)); // wait for 2 seconds before next try } } const response = yield (0, handshake_1.handshakeWithRetry)(this.client, 20).catch((reason) => __awaiter(this, void 0, void 0, function* () { throw new Error(`Cannot connect to IronPdfEngine: ${reason}`); })); if (response) { if (response.exception) { throw new Error(`${response.exception.exceptionType} ${response.exception.message} \n ${response.exception.remoteStackTrace} \n ${response.exception.rootException}`); } if (response.requiredVersion) { console.warn(`[IronPdf] mismatch version, required: ${ironpdfglobalconfig_1.IronPdfGlobalConfig.ironPdfEngineVersion} found: ${response.requiredVersion}`); } //apply configuration after handshake yield (0, system_1.setIsDebug)(this.client, (_b = ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().debugMode) !== null && _b !== void 0 ? _b : false); const licenseKey = ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().licenseKey; if (licenseKey) { yield (0, system_1.setLicenseKey)(this.client, licenseKey); } if (ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().debugMode) console.debug("Connected to IronPdfEngine"); } } return this.client; }); } } exports.Access = Access; _a = Access; Access.usedDocumentIds = new Set(); Access.PROTO_FILE = "IronPdfEngine.ProtoFiles/iron_pdf_service.proto"; Access.packageDef = protoLoader.loadSync(path.resolve(__dirname, _a.PROTO_FILE)); Access.grpcObj = grpc.loadPackageDefinition(_a.packageDef); Access.targetDir = path.join(__dirname, `../../ironpdf-engine-bin-${ironpdfglobalconfig_1.IronPdfGlobalConfig.ironPdfEngineVersion}`); Access.ironPdfEngineAddress = `127.0.0.1:33350`; function getOsName() { switch (process.platform) { case "win32": return `windows`; case "darwin": return `macos`; case "linux": return `linux`; default: throw new Error(`OS: ${process.platform} are not supported`); } } exports.getOsName = getOsName; function getPlatformName() { switch (process.platform) { case "win32": return `Windows`; case "darwin": return `MacOS`; case "linux": return `Linux`; default: throw new Error(`Platform: ${process.platform} are not supported`); } } exports.getPlatformName = getPlatformName; function ironPdfEngineExecutable() { switch (process.platform) { case "win32": return `IronPdfEngineConsole.exe`; case "darwin": return `IronPdfEngineConsole`; case "linux": return `IronPdfEngineConsole`; default: throw new Error(`OS: ${process.platform} are not supported`); } } exports.ironPdfEngineExecutable = ironPdfEngineExecutable; function getOsArch() { switch (Os.arch()) { case "ppc64": case "x64": case "s390x": return `x64`; case "arm": case "arm64": return `arm64`; default: return "x86"; } } exports.getOsArch = getOsArch; function tryChangePermissions(directoryPath, fileMode) { return __awaiter(this, void 0, void 0, function* () { try { const syncReaddir = util.promisify(fs.readdir); const syncChmod = util.promisify(fs.chmod); const files = yield syncReaddir(directoryPath); // Listing all files using forEach for (const file of files) { const filePath = path.join(directoryPath, file); if (ironpdfglobalconfig_1.IronPdfGlobalConfig.getConfig().debugMode) console.debug(`chmod ${filePath}`); yield syncChmod(filePath, fileMode); } } catch (e) { console.debug(`tryChangePermissions of: ${directoryPath} Error: ${e}`); } }); } //# sourceMappingURL=access.js.map