node-poppler 9.0.1 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +2 -1
  2. package/src/index.js +547 -444
  3. package/types/index.d.ts +30 -12
package/src/index.js CHANGED
@@ -5,6 +5,7 @@ const { basename, normalize, resolve: pathResolve } = require("node:path");
5
5
  const { platform } = require("node:process");
6
6
  const { promisify } = require("node:util");
7
7
  const camelCase = require("camelcase");
8
+ const freeze = require("ice-barrage");
8
9
  const { lt } = require("semver");
9
10
 
10
11
  const execFileAsync = promisify(execFile);
@@ -13,7 +14,7 @@ const execFileAsync = promisify(execFile);
13
14
  * @type {Readonly<Record<string, string>>}
14
15
  * @ignore
15
16
  */
16
- const ERROR_MSGS = {
17
+ const ERROR_MSGS = Object.freeze({
17
18
  0: "No Error",
18
19
  1: "Error opening a PDF file",
19
20
  2: "Error opening an output file",
@@ -21,7 +22,7 @@ const ERROR_MSGS = {
21
22
  4: "Error related to ICC profile",
22
23
  99: "Other error",
23
24
  3221226505: "Internal process error",
24
- };
25
+ });
25
26
 
26
27
  // Cache immutable regex as they are expensive to create and garbage collect
27
28
  const POPPLER_VERSION_REG = /(\d{1,2}\.\d{1,2}\.\d{1,2})/u;
@@ -488,6 +489,11 @@ const PDF_INFO_PATH_REG = /(.+)pdfinfo/u;
488
489
  * @property {boolean} [printVersionInfo] Print copyright and version information.
489
490
  */
490
491
 
492
+ /**
493
+ * @typedef {object} PopplerExtraOptions
494
+ * @property {AbortSignal} [signal] An `AbortSignal` that can be used to cancel the operation.
495
+ */
496
+
491
497
  /**
492
498
  * @author Frazer Smith
493
499
  * @description Executes a Poppler binary with the provided arguments and file input.
@@ -497,12 +503,14 @@ const PDF_INFO_PATH_REG = /(.+)pdfinfo/u;
497
503
  * @param {Buffer|string} [file] - File input (Buffer or path).
498
504
  * @param {object} [options] - Object containing execution options.
499
505
  * @param {boolean} [options.binaryOutput] - Set binary encoding for stdout.
506
+ * @param {boolean} [options.ignoreExitCode] - If true, resolve based on stdout presence regardless of exit code.
500
507
  * @param {boolean} [options.preserveWhitespace] - If true, preserves leading and trailing whitespace in the output.
508
+ * @param {AbortSignal} [options.signal] - An `AbortSignal` that can be used to cancel the operation.
501
509
  * @returns {Promise<string>} A promise that resolves with stdout, or rejects with an Error.
502
510
  */
503
- function executeBinary(binary, args, file, options = {}) {
511
+ function execBinary(binary, args, file, options = {}) {
504
512
  return new Promise((resolve, reject) => {
505
- const child = spawn(binary, args);
513
+ const child = spawn(binary, args, { signal: options.signal });
506
514
 
507
515
  if (options.binaryOutput) {
508
516
  child.stdout.setEncoding("binary");
@@ -515,6 +523,7 @@ function executeBinary(binary, args, file, options = {}) {
515
523
 
516
524
  let stdOut = "";
517
525
  let stdErr = "";
526
+ let errorHandled = false;
518
527
 
519
528
  child.stdout.on("data", (data) => {
520
529
  stdOut += data;
@@ -524,8 +533,29 @@ function executeBinary(binary, args, file, options = {}) {
524
533
  stdErr += data;
525
534
  });
526
535
 
536
+ child.on("error", (err) => {
537
+ errorHandled = true;
538
+ reject(err);
539
+ });
540
+
527
541
  child.on("close", (code) => {
528
- /* istanbul ignore else */
542
+ // If an error was already emitted, don't process the close event
543
+ if (errorHandled) {
544
+ return;
545
+ }
546
+
547
+ // For binaries without reliable exit codes, resolve based on stdout presence
548
+ if (options.ignoreExitCode) {
549
+ if (stdOut !== "") {
550
+ resolve(
551
+ options.preserveWhitespace ? stdOut : stdOut.trim()
552
+ );
553
+ } else {
554
+ reject(new Error(stdErr.trim()));
555
+ }
556
+ return;
557
+ }
558
+
529
559
  if (stdOut !== "") {
530
560
  resolve(options.preserveWhitespace ? stdOut : stdOut.trim());
531
561
  } else if (code === 0) {
@@ -654,6 +684,7 @@ class Poppler {
654
684
  if (popplerPath) {
655
685
  this.#popplerPath = popplerPath;
656
686
  }
687
+
657
688
  if (platform === "win32" && !popplerPath) {
658
689
  try {
659
690
  // @ts-ignore: Optional dependency
@@ -665,7 +696,6 @@ class Poppler {
665
696
  }
666
697
  }
667
698
 
668
- /* istanbul ignore next: unable to test due to https://github.com/jestjs/jest/pull/14297 */
669
699
  if (!this.#popplerPath) {
670
700
  throw new Error(
671
701
  `Unable to find ${platform} Poppler binaries, please pass the installation directory as a parameter to the Poppler instance.`
@@ -721,412 +751,472 @@ class Poppler {
721
751
  if (!this.#acceptedOptions.has(functionName)) {
722
752
  switch (functionName) {
723
753
  case "pdfAttach":
724
- this.#acceptedOptions.set("pdfAttach", {
725
- printVersionInfo: { arg: "-v", type: "boolean" },
726
- replace: { arg: "-replace", type: "boolean" },
727
- });
754
+ this.#acceptedOptions.set(
755
+ "pdfAttach",
756
+ freeze({
757
+ printVersionInfo: { arg: "-v", type: "boolean" },
758
+ replace: { arg: "-replace", type: "boolean" },
759
+ })
760
+ );
728
761
  break;
729
762
  case "pdfDetach":
730
- this.#acceptedOptions.set("pdfDetach", {
731
- listEmbedded: { arg: "-list", type: "boolean" },
732
- outputEncoding: { arg: "-enc", type: "string" },
733
- outputPath: { arg: "-o", type: "string" },
734
- ownerPassword: { arg: "-opw", type: "string" },
735
- printVersionInfo: { arg: "-v", type: "boolean" },
736
- saveAllFiles: { arg: "-saveall", type: "boolean" },
737
- saveFile: {
738
- arg: "-savefile",
739
- type: "string",
740
- minVersion: "0.86.0",
741
- },
742
- saveSpecificFile: { arg: "-save", type: "number" },
743
- userPassword: { arg: "-upw", type: "string" },
744
- });
763
+ this.#acceptedOptions.set(
764
+ "pdfDetach",
765
+ freeze({
766
+ listEmbedded: { arg: "-list", type: "boolean" },
767
+ outputEncoding: { arg: "-enc", type: "string" },
768
+ outputPath: { arg: "-o", type: "string" },
769
+ ownerPassword: { arg: "-opw", type: "string" },
770
+ printVersionInfo: { arg: "-v", type: "boolean" },
771
+ saveAllFiles: { arg: "-saveall", type: "boolean" },
772
+ saveFile: {
773
+ arg: "-savefile",
774
+ type: "string",
775
+ minVersion: "0.86.0",
776
+ },
777
+ saveSpecificFile: { arg: "-save", type: "number" },
778
+ userPassword: { arg: "-upw", type: "string" },
779
+ })
780
+ );
745
781
  break;
746
782
  case "pdfFonts":
747
- this.#acceptedOptions.set("pdfFonts", {
748
- firstPageToExamine: { arg: "-f", type: "number" },
749
- lastPageToExamine: { arg: "-l", type: "number" },
750
- listSubstitutes: { arg: "-subst", type: "boolean" },
751
- ownerPassword: { arg: "-opw", type: "string" },
752
- printVersionInfo: { arg: "-v", type: "boolean" },
753
- userPassword: { arg: "-upw", type: "string" },
754
- });
783
+ this.#acceptedOptions.set(
784
+ "pdfFonts",
785
+ freeze({
786
+ firstPageToExamine: { arg: "-f", type: "number" },
787
+ lastPageToExamine: { arg: "-l", type: "number" },
788
+ listSubstitutes: { arg: "-subst", type: "boolean" },
789
+ ownerPassword: { arg: "-opw", type: "string" },
790
+ printVersionInfo: { arg: "-v", type: "boolean" },
791
+ userPassword: { arg: "-upw", type: "string" },
792
+ })
793
+ );
755
794
  break;
756
795
  case "pdfImages":
757
- this.#acceptedOptions.set("pdfImages", {
758
- allFiles: { arg: "-all", type: "boolean" },
759
- ccittFile: { arg: "-ccitt", type: "boolean" },
760
- firstPageToConvert: { arg: "-f", type: "number" },
761
- lastPageToConvert: { arg: "-l", type: "number" },
762
- jbig2File: { arg: "-jbig2", type: "boolean" },
763
- jpeg2000File: { arg: "-jp2", type: "boolean" },
764
- jpegFile: { arg: "-j", type: "boolean" },
765
- list: { arg: "-list", type: "boolean" },
766
- ownerPassword: { arg: "-opw", type: "string" },
767
- pngFile: { arg: "-png", type: "boolean" },
768
- printVersionInfo: { arg: "-v", type: "boolean" },
769
- tiffFile: { arg: "-tiff", type: "boolean" },
770
- userPassword: { arg: "-upw", type: "string" },
771
- });
796
+ this.#acceptedOptions.set(
797
+ "pdfImages",
798
+ freeze({
799
+ allFiles: { arg: "-all", type: "boolean" },
800
+ ccittFile: { arg: "-ccitt", type: "boolean" },
801
+ firstPageToConvert: { arg: "-f", type: "number" },
802
+ lastPageToConvert: { arg: "-l", type: "number" },
803
+ jbig2File: { arg: "-jbig2", type: "boolean" },
804
+ jpeg2000File: { arg: "-jp2", type: "boolean" },
805
+ jpegFile: { arg: "-j", type: "boolean" },
806
+ list: { arg: "-list", type: "boolean" },
807
+ ownerPassword: { arg: "-opw", type: "string" },
808
+ pngFile: { arg: "-png", type: "boolean" },
809
+ printVersionInfo: { arg: "-v", type: "boolean" },
810
+ tiffFile: { arg: "-tiff", type: "boolean" },
811
+ userPassword: { arg: "-upw", type: "string" },
812
+ })
813
+ );
772
814
  break;
773
815
  case "pdfInfo":
774
- this.#acceptedOptions.set("pdfInfo", {
775
- firstPageToConvert: { arg: "-f", type: "number" },
776
- lastPageToConvert: { arg: "-l", type: "number" },
777
- listEncodingOptions: {
778
- arg: "-listenc",
779
- type: "boolean",
780
- },
781
- outputEncoding: { arg: "-enc", type: "string" },
782
- ownerPassword: { arg: "-opw", type: "string" },
783
- printAsJson: { arg: "", type: "boolean" },
784
- printBoundingBoxes: { arg: "-box", type: "boolean" },
785
- printDocStruct: { arg: "-struct", type: "boolean" },
786
- printDocStructText: {
787
- arg: "-struct-text",
788
- type: "boolean",
789
- },
790
- printIsoDates: { arg: "-isodates", type: "boolean" },
791
- printJS: { arg: "-js", type: "boolean" },
792
- printMetadata: { arg: "-meta", type: "boolean" },
793
- printNamedDests: { arg: "-dests", type: "boolean" },
794
- printRawDates: { arg: "-rawdates", type: "boolean" },
795
- printUrls: {
796
- arg: "-url",
797
- type: "boolean",
798
- minVersion: "21.11.0",
799
- },
800
- printVersionInfo: { arg: "-v", type: "boolean" },
801
- userPassword: { arg: "-upw", type: "string" },
802
- });
816
+ this.#acceptedOptions.set(
817
+ "pdfInfo",
818
+ freeze({
819
+ firstPageToConvert: { arg: "-f", type: "number" },
820
+ lastPageToConvert: { arg: "-l", type: "number" },
821
+ listEncodingOptions: {
822
+ arg: "-listenc",
823
+ type: "boolean",
824
+ },
825
+ outputEncoding: { arg: "-enc", type: "string" },
826
+ ownerPassword: { arg: "-opw", type: "string" },
827
+ printAsJson: { arg: "", type: "boolean" },
828
+ printBoundingBoxes: {
829
+ arg: "-box",
830
+ type: "boolean",
831
+ },
832
+ printDocStruct: { arg: "-struct", type: "boolean" },
833
+ printDocStructText: {
834
+ arg: "-struct-text",
835
+ type: "boolean",
836
+ },
837
+ printIsoDates: {
838
+ arg: "-isodates",
839
+ type: "boolean",
840
+ },
841
+ printJS: { arg: "-js", type: "boolean" },
842
+ printMetadata: { arg: "-meta", type: "boolean" },
843
+ printNamedDests: { arg: "-dests", type: "boolean" },
844
+ printRawDates: {
845
+ arg: "-rawdates",
846
+ type: "boolean",
847
+ },
848
+ printUrls: {
849
+ arg: "-url",
850
+ type: "boolean",
851
+ minVersion: "21.11.0",
852
+ },
853
+ printVersionInfo: { arg: "-v", type: "boolean" },
854
+ userPassword: { arg: "-upw", type: "string" },
855
+ })
856
+ );
803
857
  break;
804
858
  case "pdfSeparate":
805
- this.#acceptedOptions.set("pdfSeparate", {
806
- firstPageToExtract: { arg: "-f", type: "number" },
807
- lastPageToExtract: { arg: "-l", type: "number" },
808
- printVersionInfo: { arg: "-v", type: "boolean" },
809
- });
859
+ this.#acceptedOptions.set(
860
+ "pdfSeparate",
861
+ freeze({
862
+ firstPageToExtract: { arg: "-f", type: "number" },
863
+ lastPageToExtract: { arg: "-l", type: "number" },
864
+ printVersionInfo: { arg: "-v", type: "boolean" },
865
+ })
866
+ );
810
867
  break;
811
868
  case "pdfToCairo":
812
- this.#acceptedOptions.set("pdfToCairo", {
813
- antialias: { arg: "-antialias", type: "string" },
814
- cropBox: { arg: "-cropbox", type: "boolean" },
815
- cropHeight: { arg: "-H", type: "number" },
816
- cropSize: { arg: "-sz", type: "number" },
817
- cropWidth: { arg: "-W", type: "number" },
818
- cropXAxis: { arg: "-x", type: "number" },
819
- cropYAxis: { arg: "-y", type: "number" },
820
- duplex: { arg: "-duplex", type: "boolean" },
821
- epsFile: { arg: "-eps", type: "boolean" },
822
- evenPagesOnly: { arg: "-e", type: "boolean" },
823
- fillPage: { arg: "-expand", type: "boolean" },
824
- firstPageToConvert: { arg: "-f", type: "number" },
825
- grayscaleFile: { arg: "-gray", type: "boolean" },
826
- iccFile: { arg: "-icc", type: "string" },
827
- jpegFile: { arg: "-jpeg", type: "boolean" },
828
- jpegOptions: { arg: "-jpegopt", type: "string" },
829
- lastPageToConvert: { arg: "-l", type: "number" },
830
- monochromeFile: { arg: "-mono", type: "boolean" },
831
- noCenter: { arg: "-nocenter", type: "boolean" },
832
- noCrop: { arg: "-nocrop", type: "boolean" },
833
- noShrink: { arg: "-noshrink", type: "boolean" },
834
- oddPagesOnly: { arg: "-o", type: "boolean" },
835
- originalPageSizes: {
836
- arg: "-origpagesizes",
837
- type: "boolean",
838
- },
839
- ownerPassword: { arg: "-opw", type: "string" },
840
- paperHeight: { arg: "-paperh", type: "number" },
841
- paperSize: { arg: "-paper", type: "string" },
842
- paperWidth: { arg: "-paperw", type: "number" },
843
- pdfFile: { arg: "-pdf", type: "boolean" },
844
- pngFile: { arg: "-png", type: "boolean" },
845
- printDocStruct: {
846
- arg: "-struct",
847
- type: "boolean",
848
- minVersion: "23.11.0",
849
- },
850
- printVersionInfo: { arg: "-v", type: "boolean" },
851
- psFile: { arg: "-ps", type: "boolean" },
852
- psLevel2: { arg: "-level2", type: "boolean" },
853
- psLevel3: { arg: "-level3", type: "boolean" },
854
- quiet: { arg: "-q", type: "boolean" },
855
- resolutionXAxis: { arg: "-rx", type: "number" },
856
- resolutionXYAxis: { arg: "-r", type: "number" },
857
- resolutionYAxis: { arg: "-ry", type: "number" },
858
- scalePageTo: { arg: "-scale-to", type: "number" },
859
- scalePageToXAxis: {
860
- arg: "-scale-to-x",
861
- type: "number",
862
- },
863
- scalePageToYAxis: {
864
- arg: "-scale-to-y",
865
- type: "number",
866
- },
867
- singleFile: { arg: "-singlefile", type: "boolean" },
868
- svgFile: { arg: "-svg", type: "boolean" },
869
- tiffCompression: {
870
- arg: "-tiffcompression",
871
- type: "string",
872
- },
873
- tiffFile: { arg: "-tiff", type: "boolean" },
874
- transparentPageColor: {
875
- arg: "-transp",
876
- type: "boolean",
877
- },
878
- userPassword: { arg: "-upw", type: "string" },
879
- });
869
+ this.#acceptedOptions.set(
870
+ "pdfToCairo",
871
+ freeze({
872
+ antialias: { arg: "-antialias", type: "string" },
873
+ cropBox: { arg: "-cropbox", type: "boolean" },
874
+ cropHeight: { arg: "-H", type: "number" },
875
+ cropSize: { arg: "-sz", type: "number" },
876
+ cropWidth: { arg: "-W", type: "number" },
877
+ cropXAxis: { arg: "-x", type: "number" },
878
+ cropYAxis: { arg: "-y", type: "number" },
879
+ duplex: { arg: "-duplex", type: "boolean" },
880
+ epsFile: { arg: "-eps", type: "boolean" },
881
+ evenPagesOnly: { arg: "-e", type: "boolean" },
882
+ fillPage: { arg: "-expand", type: "boolean" },
883
+ firstPageToConvert: { arg: "-f", type: "number" },
884
+ grayscaleFile: { arg: "-gray", type: "boolean" },
885
+ iccFile: { arg: "-icc", type: "string" },
886
+ jpegFile: { arg: "-jpeg", type: "boolean" },
887
+ jpegOptions: { arg: "-jpegopt", type: "string" },
888
+ lastPageToConvert: { arg: "-l", type: "number" },
889
+ monochromeFile: { arg: "-mono", type: "boolean" },
890
+ noCenter: { arg: "-nocenter", type: "boolean" },
891
+ noCrop: { arg: "-nocrop", type: "boolean" },
892
+ noShrink: { arg: "-noshrink", type: "boolean" },
893
+ oddPagesOnly: { arg: "-o", type: "boolean" },
894
+ originalPageSizes: {
895
+ arg: "-origpagesizes",
896
+ type: "boolean",
897
+ },
898
+ ownerPassword: { arg: "-opw", type: "string" },
899
+ paperHeight: { arg: "-paperh", type: "number" },
900
+ paperSize: { arg: "-paper", type: "string" },
901
+ paperWidth: { arg: "-paperw", type: "number" },
902
+ pdfFile: { arg: "-pdf", type: "boolean" },
903
+ pngFile: { arg: "-png", type: "boolean" },
904
+ printDocStruct: {
905
+ arg: "-struct",
906
+ type: "boolean",
907
+ minVersion: "23.11.0",
908
+ },
909
+ printVersionInfo: { arg: "-v", type: "boolean" },
910
+ psFile: { arg: "-ps", type: "boolean" },
911
+ psLevel2: { arg: "-level2", type: "boolean" },
912
+ psLevel3: { arg: "-level3", type: "boolean" },
913
+ quiet: { arg: "-q", type: "boolean" },
914
+ resolutionXAxis: { arg: "-rx", type: "number" },
915
+ resolutionXYAxis: { arg: "-r", type: "number" },
916
+ resolutionYAxis: { arg: "-ry", type: "number" },
917
+ scalePageTo: { arg: "-scale-to", type: "number" },
918
+ scalePageToXAxis: {
919
+ arg: "-scale-to-x",
920
+ type: "number",
921
+ },
922
+ scalePageToYAxis: {
923
+ arg: "-scale-to-y",
924
+ type: "number",
925
+ },
926
+ singleFile: { arg: "-singlefile", type: "boolean" },
927
+ svgFile: { arg: "-svg", type: "boolean" },
928
+ tiffCompression: {
929
+ arg: "-tiffcompression",
930
+ type: "string",
931
+ },
932
+ tiffFile: { arg: "-tiff", type: "boolean" },
933
+ transparentPageColor: {
934
+ arg: "-transp",
935
+ type: "boolean",
936
+ },
937
+ userPassword: { arg: "-upw", type: "string" },
938
+ })
939
+ );
880
940
  break;
881
941
  case "pdfToHtml":
882
- this.#acceptedOptions.set("pdfToHtml", {
883
- complexOutput: { arg: "-c", type: "boolean" },
884
- dataUrls: {
885
- arg: "-dataurls",
886
- type: "boolean",
887
- minVersion: "0.75.0",
888
- },
889
- exchangePdfLinks: { arg: "-p", type: "boolean" },
890
- extractHidden: { arg: "-hidden", type: "boolean" },
891
- firstPageToConvert: { arg: "-f", type: "number" },
892
- fontFullName: { arg: "-fontfullname", type: "boolean" },
893
- ignoreImages: { arg: "-i", type: "boolean" },
894
- imageFormat: { arg: "-fmt", type: "string" },
895
- lastPageToConvert: { arg: "-l", type: "number" },
896
- noDrm: { arg: "-nodrm", type: "boolean" },
897
- noFrames: { arg: "-noframes", type: "boolean" },
898
- noMergeParagraph: { arg: "-nomerge", type: "boolean" },
899
- noRoundedCoordinates: {
900
- arg: "-noroundcoord",
901
- type: "boolean",
902
- },
903
- outputEncoding: { arg: "-enc", type: "string" },
904
- ownerPassword: { arg: "-opw", type: "string" },
905
- printVersionInfo: { arg: "-v", type: "boolean" },
906
- quiet: { arg: "-q", type: "boolean" },
907
- singlePage: { arg: "-s", type: "boolean" },
908
- stdout: { arg: "-stdout", type: "boolean" },
909
- userPassword: { arg: "-upw", type: "string" },
910
- wordBreakThreshold: { arg: "-wbt", type: "number" },
911
- xmlOutput: { arg: "-xml", type: "boolean" },
912
- zoom: { arg: "-zoom", type: "number" },
913
- });
942
+ this.#acceptedOptions.set(
943
+ "pdfToHtml",
944
+ freeze({
945
+ complexOutput: { arg: "-c", type: "boolean" },
946
+ dataUrls: {
947
+ arg: "-dataurls",
948
+ type: "boolean",
949
+ minVersion: "0.75.0",
950
+ },
951
+ exchangePdfLinks: { arg: "-p", type: "boolean" },
952
+ extractHidden: { arg: "-hidden", type: "boolean" },
953
+ firstPageToConvert: { arg: "-f", type: "number" },
954
+ fontFullName: {
955
+ arg: "-fontfullname",
956
+ type: "boolean",
957
+ },
958
+ ignoreImages: { arg: "-i", type: "boolean" },
959
+ imageFormat: { arg: "-fmt", type: "string" },
960
+ lastPageToConvert: { arg: "-l", type: "number" },
961
+ noDrm: { arg: "-nodrm", type: "boolean" },
962
+ noFrames: { arg: "-noframes", type: "boolean" },
963
+ noMergeParagraph: {
964
+ arg: "-nomerge",
965
+ type: "boolean",
966
+ },
967
+ noRoundedCoordinates: {
968
+ arg: "-noroundcoord",
969
+ type: "boolean",
970
+ },
971
+ outputEncoding: { arg: "-enc", type: "string" },
972
+ ownerPassword: { arg: "-opw", type: "string" },
973
+ printVersionInfo: { arg: "-v", type: "boolean" },
974
+ quiet: { arg: "-q", type: "boolean" },
975
+ singlePage: { arg: "-s", type: "boolean" },
976
+ stdout: { arg: "-stdout", type: "boolean" },
977
+ userPassword: { arg: "-upw", type: "string" },
978
+ wordBreakThreshold: { arg: "-wbt", type: "number" },
979
+ xmlOutput: { arg: "-xml", type: "boolean" },
980
+ zoom: { arg: "-zoom", type: "number" },
981
+ })
982
+ );
914
983
  break;
915
984
  case "pdfToPpm":
916
- this.#acceptedOptions.set("pdfToPpm", {
917
- antialiasFonts: { arg: "-aa", type: "string" },
918
- antialiasVectors: { arg: "-aaVector", type: "string" },
919
- cropBox: { arg: "-cropbox", type: "boolean" },
920
- cropHeight: { arg: "-H", type: "number" },
921
- cropSize: { arg: "-sz", type: "number" },
922
- cropWidth: { arg: "-W", type: "number" },
923
- cropXAxis: { arg: "-x", type: "number" },
924
- cropYAxis: { arg: "-y", type: "number" },
925
- defaultCmykProfile: {
926
- arg: "-defaultcmykprofile",
927
- type: "string",
928
- minVersion: "21.01.0",
929
- },
930
- defaultGrayProfile: {
931
- arg: "-defaultgrayprofile",
932
- type: "string",
933
- minVersion: "21.01.0",
934
- },
935
- defaultRgbProfile: {
936
- arg: "-defaultrgbprofile",
937
- type: "string",
938
- minVersion: "21.01.0",
939
- },
940
- displayProfile: {
941
- arg: "-displayprofile",
942
- type: "string",
943
- minVersion: "0.90.0",
944
- },
945
- evenPagesOnly: { arg: "-e", type: "boolean" },
946
- firstPageToConvert: { arg: "-f", type: "number" },
947
- forcePageNumber: {
948
- arg: "-forcenum",
949
- type: "boolean",
950
- minVersion: "0.75.0",
951
- },
952
- freetype: { arg: "-freetype", type: "string" },
953
- grayscaleFile: { arg: "-gray", type: "boolean" },
954
- hideAnnotations: {
955
- arg: "-hide-annotations",
956
- type: "boolean",
957
- minVersion: "0.84.0",
958
- },
959
- jpegFile: { arg: "-jpeg", type: "boolean" },
960
- lastPageToConvert: { arg: "-l", type: "number" },
961
- monochromeFile: { arg: "-mono", type: "boolean" },
962
- oddPagesOnly: { arg: "-o", type: "boolean" },
963
- ownerPassword: { arg: "-opw", type: "string" },
964
- pngFile: { arg: "-png", type: "boolean" },
965
- printProgress: {
966
- arg: "-progress",
967
- type: "boolean",
968
- minVersion: "21.03.0",
969
- },
970
- printVersionInfo: { arg: "-v", type: "boolean" },
971
- quiet: { arg: "-q", type: "boolean" },
972
- resolutionXAxis: { arg: "-rx", type: "number" },
973
- resolutionXYAxis: { arg: "-r", type: "number" },
974
- resolutionYAxis: { arg: "-ry", type: "number" },
975
- scalePageTo: { arg: "-scale-to", type: "number" },
976
- scalePageToXAxis: {
977
- arg: "-scale-to-x",
978
- type: "number",
979
- },
980
- scalePageToYAxis: {
981
- arg: "-scale-to-y",
982
- type: "number",
983
- },
984
- separator: {
985
- arg: "-sep",
986
- type: "string",
987
- minVersion: "0.75.0",
988
- },
989
- singleFile: { arg: "-singlefile", type: "boolean" },
990
- thinLineMode: { arg: "-thinlinemode", type: "string" },
991
- tiffCompression: {
992
- arg: "-tiffcompression",
993
- type: "string",
994
- },
995
- tiffFile: { arg: "-tiff", type: "boolean" },
996
- userPassword: { arg: "-upw", type: "string" },
997
- });
985
+ this.#acceptedOptions.set(
986
+ "pdfToPpm",
987
+ freeze({
988
+ antialiasFonts: { arg: "-aa", type: "string" },
989
+ antialiasVectors: {
990
+ arg: "-aaVector",
991
+ type: "string",
992
+ },
993
+ cropBox: { arg: "-cropbox", type: "boolean" },
994
+ cropHeight: { arg: "-H", type: "number" },
995
+ cropSize: { arg: "-sz", type: "number" },
996
+ cropWidth: { arg: "-W", type: "number" },
997
+ cropXAxis: { arg: "-x", type: "number" },
998
+ cropYAxis: { arg: "-y", type: "number" },
999
+ defaultCmykProfile: {
1000
+ arg: "-defaultcmykprofile",
1001
+ type: "string",
1002
+ minVersion: "21.01.0",
1003
+ },
1004
+ defaultGrayProfile: {
1005
+ arg: "-defaultgrayprofile",
1006
+ type: "string",
1007
+ minVersion: "21.01.0",
1008
+ },
1009
+ defaultRgbProfile: {
1010
+ arg: "-defaultrgbprofile",
1011
+ type: "string",
1012
+ minVersion: "21.01.0",
1013
+ },
1014
+ displayProfile: {
1015
+ arg: "-displayprofile",
1016
+ type: "string",
1017
+ minVersion: "0.90.0",
1018
+ },
1019
+ evenPagesOnly: { arg: "-e", type: "boolean" },
1020
+ firstPageToConvert: { arg: "-f", type: "number" },
1021
+ forcePageNumber: {
1022
+ arg: "-forcenum",
1023
+ type: "boolean",
1024
+ minVersion: "0.75.0",
1025
+ },
1026
+ freetype: { arg: "-freetype", type: "string" },
1027
+ grayscaleFile: { arg: "-gray", type: "boolean" },
1028
+ hideAnnotations: {
1029
+ arg: "-hide-annotations",
1030
+ type: "boolean",
1031
+ minVersion: "0.84.0",
1032
+ },
1033
+ jpegFile: { arg: "-jpeg", type: "boolean" },
1034
+ lastPageToConvert: { arg: "-l", type: "number" },
1035
+ monochromeFile: { arg: "-mono", type: "boolean" },
1036
+ oddPagesOnly: { arg: "-o", type: "boolean" },
1037
+ ownerPassword: { arg: "-opw", type: "string" },
1038
+ pngFile: { arg: "-png", type: "boolean" },
1039
+ printProgress: {
1040
+ arg: "-progress",
1041
+ type: "boolean",
1042
+ minVersion: "21.03.0",
1043
+ },
1044
+ printVersionInfo: { arg: "-v", type: "boolean" },
1045
+ quiet: { arg: "-q", type: "boolean" },
1046
+ resolutionXAxis: { arg: "-rx", type: "number" },
1047
+ resolutionXYAxis: { arg: "-r", type: "number" },
1048
+ resolutionYAxis: { arg: "-ry", type: "number" },
1049
+ scalePageTo: { arg: "-scale-to", type: "number" },
1050
+ scalePageToXAxis: {
1051
+ arg: "-scale-to-x",
1052
+ type: "number",
1053
+ },
1054
+ scalePageToYAxis: {
1055
+ arg: "-scale-to-y",
1056
+ type: "number",
1057
+ },
1058
+ separator: {
1059
+ arg: "-sep",
1060
+ type: "string",
1061
+ minVersion: "0.75.0",
1062
+ },
1063
+ singleFile: { arg: "-singlefile", type: "boolean" },
1064
+ thinLineMode: {
1065
+ arg: "-thinlinemode",
1066
+ type: "string",
1067
+ },
1068
+ tiffCompression: {
1069
+ arg: "-tiffcompression",
1070
+ type: "string",
1071
+ },
1072
+ tiffFile: { arg: "-tiff", type: "boolean" },
1073
+ userPassword: { arg: "-upw", type: "string" },
1074
+ })
1075
+ );
998
1076
  break;
999
1077
  case "pdfToPs":
1000
- this.#acceptedOptions.set("pdfToPs", {
1001
- antialias: { arg: "-aaRaster", type: "string" },
1002
- binary: { arg: "-binary", type: "boolean" },
1003
- defaultCmykProfile: {
1004
- arg: "-defaultcmykprofile",
1005
- type: "string",
1006
- minVersion: "21.01.0",
1007
- },
1008
- defaultGrayProfile: {
1009
- arg: "-defaultgrayprofile",
1010
- type: "string",
1011
- minVersion: "21.01.0",
1012
- },
1013
- defaultRgbProfile: {
1014
- arg: "-defaultrgbprofile",
1015
- type: "string",
1016
- minVersion: "21.01.0",
1017
- },
1018
- duplex: { arg: "-duplex", type: "boolean" },
1019
- epsFile: { arg: "-eps", type: "boolean" },
1020
- fillPage: { arg: "-expand", type: "boolean" },
1021
- firstPageToConvert: { arg: "-f", type: "number" },
1022
- form: { arg: "-form", type: "boolean" },
1023
- lastPageToConvert: { arg: "-l", type: "number" },
1024
- level1: { arg: "-level1", type: "boolean" },
1025
- level1Sep: { arg: "-level1sep", type: "boolean" },
1026
- level2: { arg: "-level2", type: "boolean" },
1027
- level2Sep: { arg: "-level2sep", type: "boolean" },
1028
- level3: { arg: "-level3", type: "boolean" },
1029
- level3Sep: { arg: "-level3sep", type: "boolean" },
1030
- noCenter: { arg: "-nocenter", type: "boolean" },
1031
- noCrop: { arg: "-nocrop", type: "boolean" },
1032
- noEmbedCIDFonts: {
1033
- arg: "-noembcidps",
1034
- type: "boolean",
1035
- },
1036
- noEmbedCIDTrueTypeFonts: {
1037
- arg: "-noembcidtt",
1038
- type: "boolean",
1039
- },
1040
- noEmbedTrueTypeFonts: {
1041
- arg: "-noembtt",
1042
- type: "boolean",
1043
- },
1044
- noEmbedType1Fonts: { arg: "-noembt1", type: "boolean" },
1045
- noShrink: { arg: "-noshrink", type: "boolean" },
1046
- opi: { arg: "-opi", type: "boolean" },
1047
- optimizecolorspace: {
1048
- arg: "-optimizecolorspace",
1049
- type: "boolean",
1050
- },
1051
- originalPageSizes: {
1052
- arg: "-origpagesizes",
1053
- type: "boolean",
1054
- },
1055
- overprint: { arg: "-overprint", type: "boolean" },
1056
- ownerPassword: { arg: "-opw", type: "string" },
1057
- paperHeight: { arg: "-paperh", type: "number" },
1058
- paperSize: { arg: "-paper", type: "string" },
1059
- paperWidth: { arg: "-paperw", type: "number" },
1060
- passfonts: { arg: "-passfonts", type: "boolean" },
1061
- preload: { arg: "-preload", type: "boolean" },
1062
- printVersionInfo: { arg: "-v", type: "boolean" },
1063
- processColorFormat: {
1064
- arg: "-processcolorformat",
1065
- type: "string",
1066
- },
1067
- processColorProfile: {
1068
- arg: "-processcolorprofile",
1069
- type: "string",
1070
- },
1071
- quiet: { arg: "-q", type: "boolean" },
1072
- rasterize: {
1073
- arg: "-rasterize",
1074
- type: "string",
1075
- minVersion: "0.90.0",
1076
- },
1077
- resolutionXYAxis: { arg: "-r", type: "number" },
1078
- userPassword: { arg: "-upw", type: "string" },
1079
- });
1078
+ this.#acceptedOptions.set(
1079
+ "pdfToPs",
1080
+ freeze({
1081
+ antialias: { arg: "-aaRaster", type: "string" },
1082
+ binary: { arg: "-binary", type: "boolean" },
1083
+ defaultCmykProfile: {
1084
+ arg: "-defaultcmykprofile",
1085
+ type: "string",
1086
+ minVersion: "21.01.0",
1087
+ },
1088
+ defaultGrayProfile: {
1089
+ arg: "-defaultgrayprofile",
1090
+ type: "string",
1091
+ minVersion: "21.01.0",
1092
+ },
1093
+ defaultRgbProfile: {
1094
+ arg: "-defaultrgbprofile",
1095
+ type: "string",
1096
+ minVersion: "21.01.0",
1097
+ },
1098
+ duplex: { arg: "-duplex", type: "boolean" },
1099
+ epsFile: { arg: "-eps", type: "boolean" },
1100
+ fillPage: { arg: "-expand", type: "boolean" },
1101
+ firstPageToConvert: { arg: "-f", type: "number" },
1102
+ form: { arg: "-form", type: "boolean" },
1103
+ lastPageToConvert: { arg: "-l", type: "number" },
1104
+ level1: { arg: "-level1", type: "boolean" },
1105
+ level1Sep: { arg: "-level1sep", type: "boolean" },
1106
+ level2: { arg: "-level2", type: "boolean" },
1107
+ level2Sep: { arg: "-level2sep", type: "boolean" },
1108
+ level3: { arg: "-level3", type: "boolean" },
1109
+ level3Sep: { arg: "-level3sep", type: "boolean" },
1110
+ noCenter: { arg: "-nocenter", type: "boolean" },
1111
+ noCrop: { arg: "-nocrop", type: "boolean" },
1112
+ noEmbedCIDFonts: {
1113
+ arg: "-noembcidps",
1114
+ type: "boolean",
1115
+ },
1116
+ noEmbedCIDTrueTypeFonts: {
1117
+ arg: "-noembcidtt",
1118
+ type: "boolean",
1119
+ },
1120
+ noEmbedTrueTypeFonts: {
1121
+ arg: "-noembtt",
1122
+ type: "boolean",
1123
+ },
1124
+ noEmbedType1Fonts: {
1125
+ arg: "-noembt1",
1126
+ type: "boolean",
1127
+ },
1128
+ noShrink: { arg: "-noshrink", type: "boolean" },
1129
+ opi: { arg: "-opi", type: "boolean" },
1130
+ optimizecolorspace: {
1131
+ arg: "-optimizecolorspace",
1132
+ type: "boolean",
1133
+ },
1134
+ originalPageSizes: {
1135
+ arg: "-origpagesizes",
1136
+ type: "boolean",
1137
+ },
1138
+ overprint: { arg: "-overprint", type: "boolean" },
1139
+ ownerPassword: { arg: "-opw", type: "string" },
1140
+ paperHeight: { arg: "-paperh", type: "number" },
1141
+ paperSize: { arg: "-paper", type: "string" },
1142
+ paperWidth: { arg: "-paperw", type: "number" },
1143
+ passfonts: { arg: "-passfonts", type: "boolean" },
1144
+ preload: { arg: "-preload", type: "boolean" },
1145
+ printVersionInfo: { arg: "-v", type: "boolean" },
1146
+ processColorFormat: {
1147
+ arg: "-processcolorformat",
1148
+ type: "string",
1149
+ },
1150
+ processColorProfile: {
1151
+ arg: "-processcolorprofile",
1152
+ type: "string",
1153
+ },
1154
+ quiet: { arg: "-q", type: "boolean" },
1155
+ rasterize: {
1156
+ arg: "-rasterize",
1157
+ type: "string",
1158
+ minVersion: "0.90.0",
1159
+ },
1160
+ resolutionXYAxis: { arg: "-r", type: "number" },
1161
+ userPassword: { arg: "-upw", type: "string" },
1162
+ })
1163
+ );
1080
1164
  break;
1081
1165
  case "pdfToText":
1082
- this.#acceptedOptions.set("pdfToText", {
1083
- boundingBoxXhtml: { arg: "-bbox", type: "boolean" },
1084
- boundingBoxXhtmlLayout: {
1085
- arg: "-bbox-layout",
1086
- type: "boolean",
1087
- },
1088
- cropBox: {
1089
- arg: "-cropbox",
1090
- type: "boolean",
1091
- minVersion: "21.03.0",
1092
- },
1093
- cropHeight: { arg: "-H", type: "number" },
1094
- cropWidth: { arg: "-W", type: "number" },
1095
- cropXAxis: { arg: "-x", type: "number" },
1096
- cropYAxis: { arg: "-y", type: "number" },
1097
- eolConvention: { arg: "-eol", type: "string" },
1098
- firstPageToConvert: { arg: "-f", type: "number" },
1099
- fixedWidthLayout: { arg: "-fixed", type: "number" },
1100
- generateHtmlMetaFile: {
1101
- arg: "-htmlmeta",
1102
- type: "boolean",
1103
- },
1104
- generateTsvFile: { arg: "-tsv", type: "boolean" },
1105
- lastPageToConvert: { arg: "-l", type: "number" },
1106
- listEncodingOptions: {
1107
- arg: "-listenc",
1108
- type: "boolean",
1109
- },
1110
- maintainLayout: { arg: "-layout", type: "boolean" },
1111
- noDiagonalText: {
1112
- arg: "-nodiag",
1113
- type: "boolean",
1114
- minVersion: "0.80.0",
1115
- },
1116
- noPageBreaks: { arg: "-nopgbrk", type: "boolean" },
1117
- outputEncoding: { arg: "-enc", type: "string" },
1118
- ownerPassword: { arg: "-opw", type: "string" },
1119
- printVersionInfo: { arg: "-v", type: "boolean" },
1120
- quiet: { arg: "-q", type: "boolean" },
1121
- rawLayout: { arg: "-raw", type: "boolean" },
1122
- resolution: { arg: "-r", type: "number" },
1123
- userPassword: { arg: "-upw", type: "string" },
1124
- });
1166
+ this.#acceptedOptions.set(
1167
+ "pdfToText",
1168
+ freeze({
1169
+ boundingBoxXhtml: { arg: "-bbox", type: "boolean" },
1170
+ boundingBoxXhtmlLayout: {
1171
+ arg: "-bbox-layout",
1172
+ type: "boolean",
1173
+ },
1174
+ cropBox: {
1175
+ arg: "-cropbox",
1176
+ type: "boolean",
1177
+ minVersion: "21.03.0",
1178
+ },
1179
+ cropHeight: { arg: "-H", type: "number" },
1180
+ cropWidth: { arg: "-W", type: "number" },
1181
+ cropXAxis: { arg: "-x", type: "number" },
1182
+ cropYAxis: { arg: "-y", type: "number" },
1183
+ eolConvention: { arg: "-eol", type: "string" },
1184
+ firstPageToConvert: { arg: "-f", type: "number" },
1185
+ fixedWidthLayout: { arg: "-fixed", type: "number" },
1186
+ generateHtmlMetaFile: {
1187
+ arg: "-htmlmeta",
1188
+ type: "boolean",
1189
+ },
1190
+ generateTsvFile: { arg: "-tsv", type: "boolean" },
1191
+ lastPageToConvert: { arg: "-l", type: "number" },
1192
+ listEncodingOptions: {
1193
+ arg: "-listenc",
1194
+ type: "boolean",
1195
+ },
1196
+ maintainLayout: { arg: "-layout", type: "boolean" },
1197
+ noDiagonalText: {
1198
+ arg: "-nodiag",
1199
+ type: "boolean",
1200
+ minVersion: "0.80.0",
1201
+ },
1202
+ noPageBreaks: { arg: "-nopgbrk", type: "boolean" },
1203
+ outputEncoding: { arg: "-enc", type: "string" },
1204
+ ownerPassword: { arg: "-opw", type: "string" },
1205
+ printVersionInfo: { arg: "-v", type: "boolean" },
1206
+ quiet: { arg: "-q", type: "boolean" },
1207
+ rawLayout: { arg: "-raw", type: "boolean" },
1208
+ resolution: { arg: "-r", type: "number" },
1209
+ userPassword: { arg: "-upw", type: "string" },
1210
+ })
1211
+ );
1125
1212
  break;
1126
1213
  case "pdfUnite":
1127
- this.#acceptedOptions.set("pdfUnite", {
1128
- printVersionInfo: { arg: "-v", type: "boolean" },
1129
- });
1214
+ this.#acceptedOptions.set(
1215
+ "pdfUnite",
1216
+ freeze({
1217
+ printVersionInfo: { arg: "-v", type: "boolean" },
1218
+ })
1219
+ );
1130
1220
  break;
1131
1221
  }
1132
1222
  }
@@ -1141,15 +1231,16 @@ class Poppler {
1141
1231
  * @param {string} fileToAttach - Filepath of the attachment to be embedded into the PDF file.
1142
1232
  * @param {string} outputFile - Filepath of the file to output the results to.
1143
1233
  * @param {PdfAttachOptions} [options] - Options to pass to pdfattach binary.
1234
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1144
1235
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1145
1236
  */
1146
- async pdfAttach(file, fileToAttach, outputFile, options = {}) {
1237
+ async pdfAttach(file, fileToAttach, outputFile, options = {}, extras = {}) {
1238
+ const { signal } = extras;
1147
1239
  const acceptedOptions = this.#getAcceptedOptions("pdfAttach");
1148
1240
  const args = parseOptions(acceptedOptions, options);
1149
1241
  args.push(file, fileToAttach, outputFile);
1150
1242
 
1151
- const { stdout } = await execFileAsync(this.#pdfAttachBin, args);
1152
- return stdout;
1243
+ return execBinary(this.#pdfAttachBin, args, undefined, { signal });
1153
1244
  }
1154
1245
 
1155
1246
  /**
@@ -1157,14 +1248,18 @@ class Poppler {
1157
1248
  * @description Lists or extracts embedded files (attachments) from a PDF file.
1158
1249
  * @param {string} file - Filepath of the PDF file to read.
1159
1250
  * @param {PdfDetachOptions} [options] - Options to pass to pdfdetach binary.
1251
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1160
1252
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1161
1253
  */
1162
- async pdfDetach(file, options = {}) {
1254
+ async pdfDetach(file, options = {}, extras = {}) {
1255
+ const { signal } = extras;
1163
1256
  const acceptedOptions = this.#getAcceptedOptions("pdfDetach");
1164
1257
  const args = parseOptions(acceptedOptions, options);
1165
1258
  args.push(file);
1166
1259
 
1167
- const { stdout } = await execFileAsync(this.#pdfDetachBin, args);
1260
+ const { stdout } = await execFileAsync(this.#pdfDetachBin, args, {
1261
+ signal,
1262
+ });
1168
1263
  return stdout;
1169
1264
  }
1170
1265
 
@@ -1173,15 +1268,17 @@ class Poppler {
1173
1268
  * @description Lists the fonts used in a PDF file along with various information for each font.
1174
1269
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
1175
1270
  * @param {PdfFontsOptions} [options] - Options to pass to pdffonts binary.
1271
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1176
1272
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1177
1273
  */
1178
- async pdfFonts(file, options = {}) {
1274
+ async pdfFonts(file, options = {}, extras = {}) {
1275
+ const { signal } = extras;
1179
1276
  const acceptedOptions = this.#getAcceptedOptions("pdfFonts");
1180
1277
  const versionInfo = await this.#getVersion(this.#pdfFontsBin);
1181
1278
  const args = parseOptions(acceptedOptions, options, versionInfo);
1182
1279
  args.push(Buffer.isBuffer(file) ? "-" : file);
1183
1280
 
1184
- return executeBinary(this.#pdfFontsBin, args, file);
1281
+ return execBinary(this.#pdfFontsBin, args, file, { signal });
1185
1282
  }
1186
1283
 
1187
1284
  /**
@@ -1190,9 +1287,11 @@ class Poppler {
1190
1287
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
1191
1288
  * @param {string} [outputPrefix] - Filename prefix of output files.
1192
1289
  * @param {PdfImagesOptions} [options] - Options to pass to pdfimages binary.
1290
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1193
1291
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1194
1292
  */
1195
- async pdfImages(file, outputPrefix, options = {}) {
1293
+ async pdfImages(file, outputPrefix, options = {}, extras = {}) {
1294
+ const { signal } = extras;
1196
1295
  const acceptedOptions = this.#getAcceptedOptions("pdfImages");
1197
1296
  const versionInfo = await this.#getVersion(this.#pdfImagesBin);
1198
1297
  const args = parseOptions(acceptedOptions, options, versionInfo);
@@ -1203,7 +1302,7 @@ class Poppler {
1203
1302
  args.push(outputPrefix);
1204
1303
  }
1205
1304
 
1206
- return executeBinary(this.#pdfImagesBin, args, file);
1305
+ return execBinary(this.#pdfImagesBin, args, file, { signal });
1207
1306
  }
1208
1307
 
1209
1308
  /**
@@ -1211,10 +1310,12 @@ class Poppler {
1211
1310
  * @description Prints the contents of the `Info` dictionary from a PDF file.
1212
1311
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
1213
1312
  * @param {PdfInfoOptions} [options] - Options to pass to pdfinfo binary.
1313
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1214
1314
  * @returns {Promise<object|string>} A promise that resolves with a stdout string or JSON object if
1215
1315
  * `options.printAsJson` is `true`, or rejects with an `Error` object.
1216
1316
  */
1217
- async pdfInfo(file, options = {}) {
1317
+ async pdfInfo(file, options = {}, extras = {}) {
1318
+ const { signal } = extras;
1218
1319
  const acceptedOptions = this.#getAcceptedOptions("pdfInfo");
1219
1320
  const versionInfo = await this.#getVersion(this.#pdfInfoBin);
1220
1321
  const args = parseOptions(acceptedOptions, options, versionInfo);
@@ -1231,7 +1332,7 @@ class Poppler {
1231
1332
  }
1232
1333
 
1233
1334
  return new Promise((resolve, reject) => {
1234
- const child = spawn(this.#pdfInfoBin, args);
1335
+ const child = spawn(this.#pdfInfoBin, args, { signal });
1235
1336
 
1236
1337
  if (Buffer.isBuffer(file)) {
1237
1338
  child.stdin.write(file);
@@ -1240,6 +1341,7 @@ class Poppler {
1240
1341
 
1241
1342
  let stdOut = "";
1242
1343
  let stdErr = "";
1344
+ let errorHandled = false;
1243
1345
 
1244
1346
  child.stdout.on("data", (data) => {
1245
1347
  stdOut += data;
@@ -1249,8 +1351,17 @@ class Poppler {
1249
1351
  stdErr += data;
1250
1352
  });
1251
1353
 
1354
+ child.on("error", (err) => {
1355
+ errorHandled = true;
1356
+ reject(err);
1357
+ });
1358
+
1252
1359
  child.on("close", (code) => {
1253
- /* istanbul ignore else */
1360
+ // If an error was already emitted, don't process the close event
1361
+ if (errorHandled) {
1362
+ return;
1363
+ }
1364
+
1254
1365
  if (stdOut !== "") {
1255
1366
  if (fileSize) {
1256
1367
  stdOut = stdOut.replace(
@@ -1303,16 +1414,17 @@ class Poppler {
1303
1414
  * since %d is replaced by the page number.
1304
1415
  * As an example, `sample-%d.pdf` will produce `sample-1.pdf` for a single page document.
1305
1416
  * @param {PdfSeparateOptions} [options] - Options to pass to pdfseparate binary.
1417
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1306
1418
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1307
1419
  */
1308
- async pdfSeparate(file, outputPattern, options = {}) {
1420
+ async pdfSeparate(file, outputPattern, options = {}, extras = {}) {
1421
+ const { signal } = extras;
1309
1422
  const acceptedOptions = this.#getAcceptedOptions("pdfSeparate");
1310
1423
  const versionInfo = await this.#getVersion(this.#pdfSeparateBin);
1311
1424
  const args = parseOptions(acceptedOptions, options, versionInfo);
1312
1425
  args.push(file, outputPattern);
1313
1426
 
1314
- const { stdout } = await execFileAsync(this.#pdfSeparateBin, args);
1315
- return stdout;
1427
+ return execBinary(this.#pdfSeparateBin, args, undefined, { signal });
1316
1428
  }
1317
1429
 
1318
1430
  /**
@@ -1327,9 +1439,11 @@ class Poppler {
1327
1439
  *
1328
1440
  * If not set then the output filename will be derived from the PDF file name.
1329
1441
  * @param {PdfToCairoOptions} [options] - Options to pass to pdftocairo binary.
1442
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1330
1443
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1331
1444
  */
1332
- async pdfToCairo(file, outputFile, options = {}) {
1445
+ async pdfToCairo(file, outputFile, options = {}, extras = {}) {
1446
+ const { signal } = extras;
1333
1447
  const acceptedOptions = this.#getAcceptedOptions("pdfToCairo");
1334
1448
  const versionInfo = await this.#getVersion(this.#pdfToCairoBin);
1335
1449
  const args = parseOptions(acceptedOptions, options, versionInfo);
@@ -1339,7 +1453,10 @@ class Poppler {
1339
1453
  outputFile === undefined &&
1340
1454
  args.some((arg) => ["-singlefile", "-pdf"].includes(arg));
1341
1455
 
1342
- return executeBinary(this.#pdfToCairoBin, args, file, { binaryOutput });
1456
+ return execBinary(this.#pdfToCairoBin, args, file, {
1457
+ binaryOutput,
1458
+ signal,
1459
+ });
1343
1460
  }
1344
1461
 
1345
1462
  /**
@@ -1352,9 +1469,11 @@ class Poppler {
1352
1469
  *
1353
1470
  * Required if `file` is a Buffer.
1354
1471
  * @param {PdfToHtmlOptions} [options] - Options to pass to pdftohtml binary.
1472
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1355
1473
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1356
1474
  */
1357
- async pdfToHtml(file, outputFile, options = {}) {
1475
+ async pdfToHtml(file, outputFile, options = {}, extras = {}) {
1476
+ const { signal } = extras;
1358
1477
  const acceptedOptions = this.#getAcceptedOptions("pdfToHtml");
1359
1478
  const versionInfo = await this.#getVersion(this.#pdfToHtmlBin);
1360
1479
  const args = parseOptions(acceptedOptions, options, versionInfo);
@@ -1364,33 +1483,9 @@ class Poppler {
1364
1483
  args.push(outputFile);
1365
1484
  }
1366
1485
 
1367
- return new Promise((resolve, reject) => {
1368
- const child = spawn(this.#pdfToHtmlBin, args);
1369
-
1370
- if (Buffer.isBuffer(file)) {
1371
- child.stdin.write(file);
1372
- child.stdin.end();
1373
- }
1374
-
1375
- let stdOut = "";
1376
- let stdErr = "";
1377
-
1378
- child.stdout.on("data", (data) => {
1379
- stdOut += data;
1380
- });
1381
-
1382
- child.stderr.on("data", (data) => {
1383
- stdErr += data;
1384
- });
1385
-
1386
- // PdfToHtml has no exit code; check output for success
1387
- child.on("close", () => {
1388
- if (stdOut !== "") {
1389
- resolve(stdOut.trim());
1390
- } else {
1391
- reject(new Error(stdErr ? stdErr.trim() : undefined));
1392
- }
1393
- });
1486
+ return execBinary(this.#pdfToHtmlBin, args, file, {
1487
+ ignoreExitCode: true,
1488
+ signal,
1394
1489
  });
1395
1490
  }
1396
1491
 
@@ -1402,15 +1497,17 @@ class Poppler {
1402
1497
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
1403
1498
  * @param {string} outputPath - Filepath to output the results to.
1404
1499
  * @param {PdfToPpmOptions} [options] - Options to pass to pdftoppm binary.
1500
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1405
1501
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1406
1502
  */
1407
- async pdfToPpm(file, outputPath, options = {}) {
1503
+ async pdfToPpm(file, outputPath, options = {}, extras = {}) {
1504
+ const { signal } = extras;
1408
1505
  const acceptedOptions = this.#getAcceptedOptions("pdfToPpm");
1409
1506
  const versionInfo = await this.#getVersion(this.#pdfToPpmBin);
1410
1507
  const args = parseOptions(acceptedOptions, options, versionInfo);
1411
1508
  args.push(Buffer.isBuffer(file) ? "-" : file, outputPath);
1412
1509
 
1413
- return executeBinary(this.#pdfToPpmBin, args, file);
1510
+ return execBinary(this.#pdfToPpmBin, args, file, { signal });
1414
1511
  }
1415
1512
 
1416
1513
  /**
@@ -1420,15 +1517,17 @@ class Poppler {
1420
1517
  * @param {string} [outputFile] - Filepath of the file to output the results to.
1421
1518
  * If `undefined` then will write output to stdout.
1422
1519
  * @param {PdfToPsOptions} [options] - Options to pass to pdftops binary.
1520
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1423
1521
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1424
1522
  */
1425
- async pdfToPs(file, outputFile, options = {}) {
1523
+ async pdfToPs(file, outputFile, options = {}, extras = {}) {
1524
+ const { signal } = extras;
1426
1525
  const acceptedOptions = this.#getAcceptedOptions("pdfToPs");
1427
1526
  const versionInfo = await this.#getVersion(this.#pdfToPsBin);
1428
1527
  const args = parseOptions(acceptedOptions, options, versionInfo);
1429
1528
  args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
1430
1529
 
1431
- return executeBinary(this.#pdfToPsBin, args, file);
1530
+ return execBinary(this.#pdfToPsBin, args, file, { signal });
1432
1531
  }
1433
1532
 
1434
1533
  /**
@@ -1438,16 +1537,19 @@ class Poppler {
1438
1537
  * @param {string} [outputFile] - Filepath of the file to output the results to.
1439
1538
  * If `undefined` then will write output to stdout.
1440
1539
  * @param {PdfToTextOptions} [options] - Options to pass to pdftotext binary.
1540
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1441
1541
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1442
1542
  */
1443
- async pdfToText(file, outputFile, options = {}) {
1543
+ async pdfToText(file, outputFile, options = {}, extras = {}) {
1544
+ const { signal } = extras;
1444
1545
  const acceptedOptions = this.#getAcceptedOptions("pdfToText");
1445
1546
  const versionInfo = await this.#getVersion(this.#pdfToTextBin);
1446
1547
  const args = parseOptions(acceptedOptions, options, versionInfo);
1447
1548
  args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
1448
1549
 
1449
- return executeBinary(this.#pdfToTextBin, args, file, {
1550
+ return execBinary(this.#pdfToTextBin, args, file, {
1450
1551
  preserveWhitespace: options.maintainLayout,
1552
+ signal,
1451
1553
  });
1452
1554
  }
1453
1555
 
@@ -1459,16 +1561,17 @@ class Poppler {
1459
1561
  * An entire directory of PDF files can be merged like so: `path/to/directory/*.pdf`.
1460
1562
  * @param {string} outputFile - Filepath of the file to output the resulting merged PDF to.
1461
1563
  * @param {PdfUniteOptions} [options] - Options to pass to pdfunite binary.
1564
+ * @param {PopplerExtraOptions} [extras] - Extra options.
1462
1565
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1463
1566
  */
1464
- async pdfUnite(files, outputFile, options = {}) {
1567
+ async pdfUnite(files, outputFile, options = {}, extras = {}) {
1568
+ const { signal } = extras;
1465
1569
  const acceptedOptions = this.#getAcceptedOptions("pdfUnite");
1466
1570
  const versionInfo = await this.#getVersion(this.#pdfUniteBin);
1467
1571
  const args = parseOptions(acceptedOptions, options, versionInfo);
1468
1572
  args.push(...files, outputFile);
1469
1573
 
1470
- const { stdout } = await execFileAsync(this.#pdfUniteBin, args);
1471
- return stdout;
1574
+ return execBinary(this.#pdfUniteBin, args, undefined, { signal });
1472
1575
  }
1473
1576
  }
1474
1577