mirror of
https://github.com/Fdawgs/node-poppler.git
synced 2026-07-02 00:17:43 +08:00
refactor(index): consolidate duplicate spawn executions (#672)
* refactor(index): remove duplicate spawn execution code * refactor(index): use `executeBinary` in `pdfToPs` * refactor(index): consistent styling * refactor(index): use `executeBinary` in `pdfToPpm`
This commit is contained in:
+88
-260
@@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const { execFile, spawn, spawnSync } = require("node:child_process");
|
||||
const { normalize, resolve: pathResolve } = require("node:path");
|
||||
const { basename, normalize, resolve: pathResolve } = require("node:path");
|
||||
const { platform } = require("node:process");
|
||||
const { promisify } = require("node:util");
|
||||
const camelCase = require("camelcase");
|
||||
@@ -488,6 +488,62 @@ const PDF_INFO_PATH_REG = /(.+)pdfinfo/u;
|
||||
* @property {boolean} [printVersionInfo] Print copyright and version information.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Frazer Smith
|
||||
* @description Executes a Poppler binary with the provided arguments and file input.
|
||||
* @ignore
|
||||
* @param {string} binary - Path to the binary to execute.
|
||||
* @param {string[]} args - Array of CLI arguments to pass to the binary.
|
||||
* @param {Buffer|string} [file] - File input (Buffer or path).
|
||||
* @param {object} [options] - Object containing execution options.
|
||||
* @param {boolean} [options.binaryOutput] - Set binary encoding for stdout.
|
||||
* @param {boolean} [options.preserveWhitespace] - If true, preserves leading and trailing whitespace in the output.
|
||||
* @returns {Promise<string>} A promise that resolves with stdout, or rejects with an Error.
|
||||
*/
|
||||
function executeBinary(binary, args, file, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn(binary, args);
|
||||
|
||||
if (options.binaryOutput) {
|
||||
child.stdout.setEncoding("binary");
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(file)) {
|
||||
child.stdin.write(file);
|
||||
child.stdin.end();
|
||||
}
|
||||
|
||||
let stdOut = "";
|
||||
let stdErr = "";
|
||||
|
||||
child.stdout.on("data", (data) => {
|
||||
stdOut += data;
|
||||
});
|
||||
|
||||
child.stderr.on("data", (data) => {
|
||||
stdErr += data;
|
||||
});
|
||||
|
||||
child.on("close", (code) => {
|
||||
/* istanbul ignore else */
|
||||
if (stdOut !== "") {
|
||||
resolve(options.preserveWhitespace ? stdOut : stdOut.trim());
|
||||
} else if (code === 0) {
|
||||
resolve(ERROR_MSGS[code]);
|
||||
} else if (stdErr !== "") {
|
||||
reject(new Error(stdErr.trim()));
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
ERROR_MSGS[code ?? -1] ||
|
||||
`${basename(binary)} ${args.join(" ")} exited with code ${code}`
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Frazer Smith
|
||||
* @description Checks each option provided is valid, of the correct type, and can be used by specified
|
||||
@@ -1124,48 +1180,9 @@ class Poppler {
|
||||
const acceptedOptions = this.#getAcceptedOptions("pdfFonts");
|
||||
const versionInfo = await this.#getVersion(this.#pdfFontsBin);
|
||||
const args = parseOptions(acceptedOptions, options, versionInfo);
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file);
|
||||
|
||||
const child = spawn(this.#pdfFontsBin, args);
|
||||
|
||||
if (Buffer.isBuffer(file)) {
|
||||
child.stdin.write(file);
|
||||
child.stdin.end();
|
||||
}
|
||||
|
||||
let stdOut = "";
|
||||
let stdErr = "";
|
||||
|
||||
child.stdout.on("data", (data) => {
|
||||
stdOut += data;
|
||||
});
|
||||
|
||||
child.stderr.on("data", (data) => {
|
||||
stdErr += data;
|
||||
});
|
||||
|
||||
child.on("close", (code) => {
|
||||
/* istanbul ignore else */
|
||||
if (stdOut !== "") {
|
||||
resolve(stdOut.trim());
|
||||
} else if (code === 0) {
|
||||
resolve(ERROR_MSGS[code]);
|
||||
} else if (stdErr !== "") {
|
||||
reject(new Error(stdErr.trim()));
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
ERROR_MSGS[code ?? -1] ||
|
||||
`pdffonts ${args.join(
|
||||
" "
|
||||
)} exited with code ${code}`
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
return executeBinary(this.#pdfFontsBin, args, file);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1181,51 +1198,13 @@ class Poppler {
|
||||
const versionInfo = await this.#getVersion(this.#pdfImagesBin);
|
||||
const args = parseOptions(acceptedOptions, options, versionInfo);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file);
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file);
|
||||
|
||||
if (outputPrefix) {
|
||||
args.push(outputPrefix);
|
||||
}
|
||||
if (outputPrefix) {
|
||||
args.push(outputPrefix);
|
||||
}
|
||||
|
||||
const child = spawn(this.#pdfImagesBin, args);
|
||||
|
||||
if (Buffer.isBuffer(file)) {
|
||||
child.stdin.write(file);
|
||||
child.stdin.end();
|
||||
}
|
||||
|
||||
let stdOut = "";
|
||||
let stdErr = "";
|
||||
|
||||
child.stdout.on("data", (data) => {
|
||||
stdOut += data;
|
||||
});
|
||||
|
||||
child.stderr.on("data", (data) => {
|
||||
stdErr += data;
|
||||
});
|
||||
|
||||
child.on("close", (code) => {
|
||||
/* istanbul ignore else */
|
||||
if (stdOut !== "") {
|
||||
resolve(stdOut.trim());
|
||||
} else if (code === 0) {
|
||||
resolve(ERROR_MSGS[code]);
|
||||
} else if (stdErr !== "") {
|
||||
reject(new Error(stdErr.trim()));
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
ERROR_MSGS[code ?? -1] ||
|
||||
`pdfimages ${args.join(
|
||||
" "
|
||||
)} exited with code ${code}`
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
return executeBinary(this.#pdfImagesBin, args, file);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1245,14 +1224,14 @@ class Poppler {
|
||||
/** @type {number} */
|
||||
let fileSize;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (Buffer.isBuffer(file)) {
|
||||
args.push("-");
|
||||
fileSize = file.length;
|
||||
} else {
|
||||
args.push(file);
|
||||
}
|
||||
if (Buffer.isBuffer(file)) {
|
||||
args.push("-");
|
||||
fileSize = file.length;
|
||||
} else {
|
||||
args.push(file);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn(this.#pdfInfoBin, args);
|
||||
|
||||
if (Buffer.isBuffer(file)) {
|
||||
@@ -1355,55 +1334,13 @@ class Poppler {
|
||||
const acceptedOptions = this.#getAcceptedOptions("pdfToCairo");
|
||||
const versionInfo = await this.#getVersion(this.#pdfToCairoBin);
|
||||
const args = parseOptions(acceptedOptions, options, versionInfo);
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
|
||||
const binaryOutput =
|
||||
outputFile === undefined &&
|
||||
args.some((arg) => ["-singlefile", "-pdf"].includes(arg));
|
||||
|
||||
const child = spawn(this.#pdfToCairoBin, args);
|
||||
|
||||
if (
|
||||
outputFile === undefined &&
|
||||
args.some((arg) => ["-singlefile", "-pdf"].includes(arg))
|
||||
) {
|
||||
child.stdout.setEncoding("binary");
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(file)) {
|
||||
child.stdin.write(file);
|
||||
child.stdin.end();
|
||||
}
|
||||
|
||||
let stdOut = "";
|
||||
let stdErr = "";
|
||||
|
||||
child.stdout.on("data", (data) => {
|
||||
stdOut += data;
|
||||
});
|
||||
|
||||
child.stderr.on("data", (data) => {
|
||||
stdErr += data;
|
||||
});
|
||||
|
||||
child.on("close", (code) => {
|
||||
/* istanbul ignore else */
|
||||
if (stdOut !== "") {
|
||||
resolve(stdOut.trim());
|
||||
} else if (code === 0) {
|
||||
resolve(ERROR_MSGS[code]);
|
||||
} else if (stdErr !== "") {
|
||||
reject(new Error(stdErr.trim()));
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
ERROR_MSGS[code ?? -1] ||
|
||||
`pdftocairo ${args.join(
|
||||
" "
|
||||
)} exited with code ${code}`
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
return executeBinary(this.#pdfToCairoBin, args, file, { binaryOutput });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1422,14 +1359,13 @@ class Poppler {
|
||||
const acceptedOptions = this.#getAcceptedOptions("pdfToHtml");
|
||||
const versionInfo = await this.#getVersion(this.#pdfToHtmlBin);
|
||||
const args = parseOptions(acceptedOptions, options, versionInfo);
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file);
|
||||
|
||||
if (outputFile) {
|
||||
args.push(outputFile);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file);
|
||||
|
||||
if (outputFile) {
|
||||
args.push(outputFile);
|
||||
}
|
||||
|
||||
const child = spawn(this.#pdfToHtmlBin, args);
|
||||
|
||||
if (Buffer.isBuffer(file)) {
|
||||
@@ -1473,41 +1409,9 @@ class Poppler {
|
||||
const acceptedOptions = this.#getAcceptedOptions("pdfToPpm");
|
||||
const versionInfo = await this.#getVersion(this.#pdfToPpmBin);
|
||||
const args = parseOptions(acceptedOptions, options, versionInfo);
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file, outputPath);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file, outputPath);
|
||||
|
||||
const child = spawn(this.#pdfToPpmBin, args);
|
||||
|
||||
if (Buffer.isBuffer(file)) {
|
||||
child.stdin.write(file);
|
||||
child.stdin.end();
|
||||
}
|
||||
|
||||
let stdErr = "";
|
||||
|
||||
child.stderr.on("data", (data) => {
|
||||
stdErr += data;
|
||||
});
|
||||
|
||||
child.on("close", (code) => {
|
||||
/* istanbul ignore else */
|
||||
if (stdErr !== "") {
|
||||
reject(new Error(stdErr.trim()));
|
||||
} else if (code === 0) {
|
||||
resolve(ERROR_MSGS[code]);
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
ERROR_MSGS[code ?? -1] ||
|
||||
`pdftoppm ${args.join(
|
||||
" "
|
||||
)} exited with code ${code}`
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
return executeBinary(this.#pdfToPpmBin, args, file);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1523,48 +1427,9 @@ class Poppler {
|
||||
const acceptedOptions = this.#getAcceptedOptions("pdfToPs");
|
||||
const versionInfo = await this.#getVersion(this.#pdfToPsBin);
|
||||
const args = parseOptions(acceptedOptions, options, versionInfo);
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
|
||||
|
||||
const child = spawn(this.#pdfToPsBin, args);
|
||||
|
||||
if (Buffer.isBuffer(file)) {
|
||||
child.stdin.write(file);
|
||||
child.stdin.end();
|
||||
}
|
||||
|
||||
let stdOut = "";
|
||||
let stdErr = "";
|
||||
|
||||
child.stdout.on("data", (data) => {
|
||||
stdOut += data;
|
||||
});
|
||||
|
||||
child.stderr.on("data", (data) => {
|
||||
stdErr += data;
|
||||
});
|
||||
|
||||
child.on("close", (code) => {
|
||||
/* istanbul ignore else */
|
||||
if (stdOut !== "") {
|
||||
resolve(stdOut.trim());
|
||||
} else if (code === 0) {
|
||||
resolve(ERROR_MSGS[code]);
|
||||
} else if (stdErr !== "") {
|
||||
reject(new Error(stdErr.trim()));
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
ERROR_MSGS[code ?? -1] ||
|
||||
`pdftops ${args.join(
|
||||
" "
|
||||
)} exited with code ${code}`
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
return executeBinary(this.#pdfToPsBin, args, file);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1580,47 +1445,10 @@ class Poppler {
|
||||
const acceptedOptions = this.#getAcceptedOptions("pdfToText");
|
||||
const versionInfo = await this.#getVersion(this.#pdfToTextBin);
|
||||
const args = parseOptions(acceptedOptions, options, versionInfo);
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
|
||||
|
||||
const child = spawn(this.#pdfToTextBin, args);
|
||||
|
||||
if (Buffer.isBuffer(file)) {
|
||||
child.stdin.write(file);
|
||||
child.stdin.end();
|
||||
}
|
||||
|
||||
let stdOut = "";
|
||||
let stdErr = "";
|
||||
|
||||
child.stdout.on("data", (data) => {
|
||||
stdOut += data;
|
||||
});
|
||||
|
||||
child.stderr.on("data", (data) => {
|
||||
stdErr += data;
|
||||
});
|
||||
|
||||
child.on("close", (code) => {
|
||||
/* istanbul ignore else */
|
||||
if (stdOut !== "") {
|
||||
resolve(options.maintainLayout ? stdOut : stdOut.trim());
|
||||
} else if (code === 0) {
|
||||
resolve(ERROR_MSGS[code]);
|
||||
} else if (stdErr !== "") {
|
||||
reject(new Error(stdErr.trim()));
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
ERROR_MSGS[code ?? -1] ||
|
||||
`pdftotext ${args.join(
|
||||
" "
|
||||
)} exited with code ${code}`
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
return executeBinary(this.#pdfToTextBin, args, file, {
|
||||
preserveWhitespace: options.maintainLayout,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user