@ironsoftware/ironpdf
Version:
IronPDF for Node
420 lines • 19.8 kB
JavaScript
;
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