@opendataloader/pdf 2.5.15 → 2.5.17

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.
package/README.md CHANGED
@@ -41,7 +41,7 @@ key-differentiators: [benchmark #1 PDF parser, deterministic output, bounding bo
41
41
 
42
42
  ## Get Started in 30 Seconds
43
43
 
44
- **Requires**: Java 11+ and Python 3.10+ ([Node.js](https://opendataloader.org/docs/quick-start-nodejs) | [Java](https://opendataloader.org/docs/quick-start-java) also available)
44
+ **Requires**: Java 11+ and Python 3.11+ ([Node.js](https://opendataloader.org/docs/quick-start-nodejs) | [Java](https://opendataloader.org/docs/quick-start-java) also available)
45
45
 
46
46
  > Before you start: run `java -version`. If not found, install JDK 11+ from [Adoptium](https://adoptium.net/).
47
47
 
@@ -215,6 +215,23 @@ opendataloader_pdf.convert(
215
215
  )
216
216
  ```
217
217
 
218
+ **Python, without a second terminal** — `HybridServer` starts the backend server for the time of a `with` block, and stops it after the block:
219
+
220
+ ```python
221
+ import opendataloader_pdf
222
+
223
+ # The server loads its models once. The first start can take minutes while the models download
224
+ with opendataloader_pdf.HybridServer() as server:
225
+ opendataloader_pdf.convert(
226
+ input_path=["file1.pdf", "file2.pdf", "folder/"],
227
+ output_dir="output/",
228
+ hybrid="docling-fast",
229
+ hybrid_url=server.url
230
+ )
231
+ ```
232
+
233
+ Give server options in `args`, as for `opendataloader-pdf-hybrid`: `HybridServer(args=["--force-ocr", "--ocr-lang", "ko,en"])`. The server listens on 127.0.0.1 at a free port (`port=` sets the port). Its log goes to stderr.
234
+
218
235
  ### OCR for Scanned PDFs
219
236
 
220
237
  Start the backend with `--force-ocr` for image-based PDFs with no selectable text:
package/dist/cli.cjs CHANGED
@@ -23,7 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  mod
24
24
  ));
25
25
 
26
- // node_modules/.pnpm/tsup@8.5.1_postcss@8.5.28_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js
26
+ // node_modules/.pnpm/tsup@8.5.1_postcss@8.5.31_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js
27
27
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
28
28
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
29
29
 
@@ -138,6 +138,15 @@ function buildConvertOptions(cliOptions) {
138
138
  if (cliOptions.sanitizeRules !== void 0 && cliOptions.sanitizeRules !== null) {
139
139
  convertOptions.sanitizeRules = cliOptions.sanitizeRules;
140
140
  }
141
+ if (cliOptions.includeLinks) {
142
+ convertOptions.includeLinks = true;
143
+ }
144
+ if (cliOptions.hybridAvailabilityTimeout) {
145
+ convertOptions.hybridAvailabilityTimeout = cliOptions.hybridAvailabilityTimeout;
146
+ }
147
+ if (cliOptions.hybridTriageLog) {
148
+ convertOptions.hybridTriageLog = true;
149
+ }
141
150
  return convertOptions;
142
151
  }
143
152
  function buildArgs(options) {
@@ -250,6 +259,15 @@ function buildArgs(options) {
250
259
  if (options.sanitizeRules !== void 0 && options.sanitizeRules !== null) {
251
260
  args.push("--sanitize-rules", options.sanitizeRules);
252
261
  }
262
+ if (options.includeLinks) {
263
+ args.push("--include-links");
264
+ }
265
+ if (options.hybridAvailabilityTimeout) {
266
+ args.push("--hybrid-availability-timeout", options.hybridAvailabilityTimeout);
267
+ }
268
+ if (options.hybridTriageLog) {
269
+ args.push("--hybrid-triage-log");
270
+ }
253
271
  return args;
254
272
  }
255
273
 
@@ -406,6 +424,9 @@ function registerCliOptions(program) {
406
424
  program.option("--image-resolution <value>", "Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0.");
407
425
  program.option("--space-ratio <value>", "Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17");
408
426
  program.option("--sanitize-rules <value>", "Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize");
427
+ program.option("--include-links", "Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text");
428
+ program.option("--hybrid-availability-timeout <value>", "Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000");
429
+ program.option("--hybrid-triage-log", "With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder");
409
430
  }
410
431
 
411
432
  // src/cli.ts
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.28_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js","../src/cli.ts","../src/index.ts","../src/convert-options.generated.ts","../src/cli-options.generated.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","#!/usr/bin/env node\nimport { Command, CommanderError } from 'commander';\nimport { _runForCli } from './index.js';\nimport { CliOptions, buildConvertOptions } from './convert-options.generated.js';\nimport { registerCliOptions } from './cli-options.generated.js';\n\nfunction createProgram(): Command {\n const program = new Command();\n\n program\n .name('opendataloader-pdf')\n .usage('[options] <input...>')\n .description('Convert PDFs using the OpenDataLoader CLI.')\n .showHelpAfterError(\"Use '--help' to see available options.\")\n .showSuggestionAfterError(false)\n .argument('<input...>', 'Input files or directories to convert');\n\n // Register CLI options from auto-generated file\n registerCliOptions(program);\n\n program.configureOutput({\n writeErr: (str) => {\n console.error(str.trimEnd());\n },\n outputError: (str, write) => {\n write(str);\n },\n });\n\n return program;\n}\n\nasync function main(): Promise<number> {\n const program = createProgram();\n\n program.exitOverride();\n\n try {\n program.parse(process.argv);\n } catch (err) {\n if (err instanceof CommanderError) {\n if (err.code === 'commander.helpDisplayed') {\n return 0;\n }\n return err.exitCode ?? 1;\n }\n\n const message = err instanceof Error ? err.message : String(err);\n console.error(message);\n console.error(\"Use '--help' to see available options.\");\n return 1;\n }\n\n const cliOptions = program.opts<CliOptions>();\n const inputPaths = program.args;\n const convertOptions = buildConvertOptions(cliOptions);\n\n try {\n // _runForCli streams stdout/stderr to the parent process as they arrive;\n // we deliberately do not re-print anything here. (Issue #398.)\n await _runForCli(inputPaths, convertOptions);\n return 0;\n } catch (err) {\n // Subprocess-exit errors are already on the user's terminal via the live\n // stderr stream — re-printing would duplicate output and risk leaking\n // anything sensitive Java logged (e.g. a --password value echoed by an\n // underlying library). Wrapper-side failures (JAR not found, java not in\n // PATH, bad input path) still need to be surfaced.\n const isJavaExit =\n err instanceof Error && (err as Error & { isJavaExit?: boolean }).isJavaExit === true;\n if (!isJavaExit) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(message);\n }\n return 1;\n }\n}\n\nmain().then((code) => {\n if (code !== 0) {\n process.exit(code);\n }\n});\n","import { spawn } from 'child_process';\nimport { randomUUID } from 'crypto';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { StringDecoder } from 'string_decoder';\nimport { fileURLToPath } from 'url';\n\n// Re-export types and utilities from auto-generated file\nexport type { ConvertOptions } from './convert-options.generated.js';\nexport { buildArgs } from './convert-options.generated.js';\nimport type { ConvertOptions } from './convert-options.generated.js';\nimport { buildArgs } from './convert-options.generated.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst JAR_NAME = 'opendataloader-pdf-cli.jar';\n\n// Environment variables that the JVM reads options from.\nconst JAVA_OPTION_VARS = ['JAVA_TOOL_OPTIONS', 'JDK_JAVA_OPTIONS', '_JAVA_OPTIONS'];\n\n/**\n * Returns the option that gives Java the temporary folder of this runtime.\n * The JVM does not read TMPDIR, so without this option Java can use another\n * folder than Node. A command-line option wins over JAVA_TOOL_OPTIONS and\n * JDK_JAVA_OPTIONS, so add none if the user set java.io.tmpdir there.\n */\nfunction tempDirOptions(): string[] {\n if (JAVA_OPTION_VARS.some((name) => (process.env[name] ?? '').includes('-Djava.io.tmpdir='))) {\n return [];\n }\n // os.tmpdir() returns TMPDIR without a check: it can name a missing\n // folder, a folder without write access, or a file. Create and delete a\n // probe file, as Java does. If that fails, add nothing and let Java keep\n // its own default.\n const dir = os.tmpdir();\n const probe = path.join(dir, `opendataloader-${process.pid}-${randomUUID()}.probe`);\n try {\n fs.closeSync(fs.openSync(probe, 'wx'));\n fs.unlinkSync(probe);\n } catch {\n return [];\n }\n return [`-Djava.io.tmpdir=${dir}`];\n}\n\ninterface JarExecutionOptions {\n /**\n * When true, forwards Java's stdout and stderr chunks to the parent\n * process in real time as well as accumulating them. Used by the bundled\n * CLI so long-running conversions show progress as it happens.\n */\n streamOutput?: boolean;\n}\n\nfunction executeJar(args: string[], executionOptions: JarExecutionOptions = {}): Promise<string> {\n const { streamOutput = false } = executionOptions;\n\n return new Promise((resolve, reject) => {\n const jarPath = path.join(__dirname, '..', 'lib', JAR_NAME);\n\n if (!fs.existsSync(jarPath)) {\n return reject(\n new Error(`JAR file not found at ${jarPath}. Please run the build script first.`),\n );\n }\n\n const command = 'java';\n // Force headless AWT so macOS doesn't surface a Dock icon (and steal focus)\n // every time the JVM touches ImageIO/PDFBox rendering. Safe on all OSes —\n // the CLI never opens a UI window, only manipulates BufferedImages.\n const commandArgs = [\n '-Djava.awt.headless=true',\n '-Dapple.awt.UIElement=true',\n ...tempDirOptions(),\n '-jar',\n jarPath,\n ...args,\n ];\n\n const javaProcess = spawn(command, commandArgs);\n\n let stdout = '';\n let stderr = '';\n // StringDecoder buffers incomplete multi-byte UTF-8 sequences across\n // chunk boundaries — Buffer.toString() alone would emit replacement\n // characters when, e.g., a 3-byte Korean codepoint splits across two\n // 'data' events. One decoder per stream so they don't share state.\n const stdoutDecoder = new StringDecoder('utf8');\n const stderrDecoder = new StringDecoder('utf8');\n\n javaProcess.stdout.on('data', (data: Buffer) => {\n const chunk = stdoutDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n // Stream-only: don't also accumulate, or a multi-hour conversion\n // would buffer its entire (potentially gigabyte) stdout in memory\n // for no consumer.\n process.stdout.write(chunk);\n } else {\n stdout += chunk;\n }\n });\n\n javaProcess.stderr.on('data', (data: Buffer) => {\n const chunk = stderrDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n process.stderr.write(chunk);\n }\n // stderr is always accumulated (progress logs are small and we need\n // them for error messages on non-zero exit).\n stderr += chunk;\n });\n\n javaProcess.on('close', (code) => {\n // Flush any trailing bytes the decoder is still holding (always emit\n // them — if we drop them on error paths, error messages with non-ASCII\n // characters lose their tail).\n const stdoutTail = stdoutDecoder.end();\n const stderrTail = stderrDecoder.end();\n if (stdoutTail.length > 0) {\n if (streamOutput) {\n process.stdout.write(stdoutTail);\n } else {\n stdout += stdoutTail;\n }\n }\n if (stderrTail.length > 0) {\n if (streamOutput) process.stderr.write(stderrTail);\n stderr += stderrTail;\n }\n\n if (code === 0) {\n resolve(stdout);\n } else {\n const errorOutput = stderr || stdout;\n const error = new Error(\n `The opendataloader-pdf CLI exited with code ${code}.\\n\\n${errorOutput}`,\n );\n // Tag so the CLI can suppress re-printing this message — Java's\n // stderr was already streamed live to the parent in CLI mode, and\n // re-printing risks leaking anything sensitive Java logged\n // (e.g. a --password value echoed by an underlying library).\n (error as Error & { isJavaExit?: boolean }).isJavaExit = true;\n reject(error);\n }\n });\n\n javaProcess.on('error', (err: Error) => {\n if (err.message.includes('ENOENT')) {\n reject(\n new Error(\n \"'java' command not found. Please ensure Java is installed and in your system's PATH.\",\n ),\n );\n } else {\n reject(err);\n }\n });\n });\n}\n\nfunction buildJarArgs(\n inputPaths: string | string[],\n options: ConvertOptions,\n): string[] | Error {\n const inputList = Array.isArray(inputPaths) ? inputPaths : [inputPaths];\n if (inputList.length === 0) {\n return new Error('At least one input path must be provided.');\n }\n\n for (const input of inputList) {\n if (!fs.existsSync(input)) {\n return new Error(`Input file or folder not found: ${input}`);\n }\n }\n\n return [...inputList, ...buildArgs(options)];\n}\n\nexport function convert(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<string> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n return Promise.reject(argsOrError);\n }\n // Library API: never streams to the parent process. Returns the full stdout\n // string so callers can do `const out = await convert(...)` without surprise\n // side-effects on process.stdout / process.stderr.\n return executeJar(argsOrError, { streamOutput: false });\n}\n\n/**\n * Internal entry point used by the bundled CLI. Streams Java's stdout and\n * stderr to the parent process in real time (so long-running conversions like\n * hybrid mode show progress as it happens) and resolves without a stdout\n * payload — preventing the caller from re-printing what was already streamed.\n *\n * Not part of the public API: do not import this from application code. Use\n * {@link convert} instead.\n *\n * @internal\n */\nexport async function _runForCli(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<void> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n throw argsOrError;\n }\n await executeJar(argsOrError, { streamOutput: true });\n}\n\n/**\n * @deprecated Use `convert()` and `ConvertOptions` instead. This function will be removed in a future version.\n */\nexport interface RunOptions {\n outputFolder?: string;\n password?: string;\n replaceInvalidChars?: string;\n generateMarkdown?: boolean;\n generateHtml?: boolean;\n generateAnnotatedPdf?: boolean;\n keepLineBreaks?: boolean;\n contentSafetyOff?: string;\n htmlInMarkdown?: boolean;\n addImageToMarkdown?: boolean;\n noJson?: boolean;\n debug?: boolean;\n useStructTree?: boolean;\n}\n\n/**\n * @deprecated Use `convert()` instead. This function will be removed in a future version.\n */\nexport function run(inputPath: string, options: RunOptions = {}): Promise<string> {\n console.warn(\n 'Warning: run() is deprecated and will be removed in a future version. Use convert() instead.',\n );\n\n // Build format array based on legacy boolean options\n const formats: string[] = [];\n if (!options.noJson) {\n formats.push('json');\n }\n if (options.generateMarkdown) {\n if (options.addImageToMarkdown) {\n formats.push('markdown-with-images');\n } else if (options.htmlInMarkdown) {\n formats.push('markdown-with-html');\n } else {\n formats.push('markdown');\n }\n }\n if (options.generateHtml) {\n formats.push('html');\n }\n if (options.generateAnnotatedPdf) {\n formats.push('pdf');\n }\n\n return convert(inputPath, {\n outputDir: options.outputFolder,\n password: options.password,\n replaceInvalidChars: options.replaceInvalidChars,\n keepLineBreaks: options.keepLineBreaks,\n contentSafetyOff: options.contentSafetyOff,\n useStructTree: options.useStructTree,\n format: formats.length > 0 ? formats : undefined,\n quiet: !options.debug,\n });\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\n/**\n * Options for the convert function.\n */\nexport interface ConvertOptions {\n /** Directory where output files are written. Default: input file directory */\n outputDir?: string;\n /** Password for encrypted PDF files */\n password?: string;\n /** Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output. */\n format?: string | string[];\n /** Suppress console logging output */\n quiet?: boolean;\n /** Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background */\n contentSafetyOff?: string | string[];\n /** Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders */\n sanitize?: boolean;\n /** Preserve original line breaks in extracted text */\n keepLineBreaks?: boolean;\n /** Replacement character for invalid/unrecognized characters. Default: space */\n replaceInvalidChars?: string;\n /** Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called */\n useStructTree?: boolean;\n /** Table detection method. Values: default (border-based), cluster (border + cluster). Default: default */\n tableMethod?: string;\n /** Reading order algorithm. Values: off, xycut. Default: xycut */\n readingOrder?: string;\n /** Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none */\n markdownPageSeparator?: string;\n /** Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown. */\n markdownWithHtml?: boolean;\n /** Separator between pages in text output. Use %page-number% for page numbers. Default: none */\n textPageSeparator?: string;\n /** Separator between pages in HTML output. Use %page-number% for page numbers. Default: none */\n htmlPageSeparator?: string;\n /** Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external */\n imageOutput?: string;\n /** Output format for extracted images. Values: png, jpeg. Default: png */\n imageFormat?: string;\n /** Directory for extracted images (applies only with --image-output external) */\n imageDir?: string;\n /** Pages to extract (e.g., \"1,3,5-7\"). Default: all pages */\n pages?: string;\n /** Include page headers and footers in output */\n includeHeaderFooter?: boolean;\n /** Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental) */\n detectStrikethrough?: boolean;\n /** Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence) */\n hybrid?: string;\n /** Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend) */\n hybridMode?: string;\n /** Hybrid backend server URL (overrides default) */\n hybridUrl?: string;\n /** Hybrid backend request timeout in milliseconds (0 = use the backend's own default). Default: 0 */\n hybridTimeout?: string;\n /** Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50 */\n hybridChunkSize?: string;\n /** Opt in to Java fallback on hybrid backend error (default: disabled) */\n hybridFallback?: boolean;\n /** Write output to stdout instead of file (single format only) */\n toStdout?: boolean;\n /** Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode */\n threads?: string;\n /** Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0. */\n imageResolution?: string;\n /** Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17 */\n spaceRatio?: string;\n /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */\n sanitizeRules?: string;\n}\n\n/**\n * Options as parsed from CLI (all values are strings from commander).\n */\nexport interface CliOptions {\n outputDir?: string;\n password?: string;\n format?: string;\n quiet?: boolean;\n contentSafetyOff?: string;\n sanitize?: boolean;\n keepLineBreaks?: boolean;\n replaceInvalidChars?: string;\n useStructTree?: boolean;\n tableMethod?: string;\n readingOrder?: string;\n markdownPageSeparator?: string;\n markdownWithHtml?: boolean;\n textPageSeparator?: string;\n htmlPageSeparator?: string;\n imageOutput?: string;\n imageFormat?: string;\n imageDir?: string;\n pages?: string;\n includeHeaderFooter?: boolean;\n detectStrikethrough?: boolean;\n hybrid?: string;\n hybridMode?: string;\n hybridUrl?: string;\n hybridTimeout?: string;\n hybridChunkSize?: string;\n hybridFallback?: boolean;\n toStdout?: boolean;\n threads?: string;\n imageResolution?: string;\n spaceRatio?: string;\n sanitizeRules?: string;\n}\n\n/**\n * Convert CLI options to ConvertOptions.\n */\nexport function buildConvertOptions(cliOptions: CliOptions): ConvertOptions {\n const convertOptions: ConvertOptions = {};\n\n if (cliOptions.outputDir) {\n convertOptions.outputDir = cliOptions.outputDir;\n }\n if (cliOptions.password) {\n convertOptions.password = cliOptions.password;\n }\n if (cliOptions.format) {\n convertOptions.format = cliOptions.format;\n }\n if (cliOptions.quiet) {\n convertOptions.quiet = true;\n }\n if (cliOptions.contentSafetyOff) {\n convertOptions.contentSafetyOff = cliOptions.contentSafetyOff;\n }\n if (cliOptions.sanitize) {\n convertOptions.sanitize = true;\n }\n if (cliOptions.keepLineBreaks) {\n convertOptions.keepLineBreaks = true;\n }\n if (cliOptions.replaceInvalidChars) {\n convertOptions.replaceInvalidChars = cliOptions.replaceInvalidChars;\n }\n if (cliOptions.useStructTree) {\n convertOptions.useStructTree = true;\n }\n if (cliOptions.tableMethod) {\n convertOptions.tableMethod = cliOptions.tableMethod;\n }\n if (cliOptions.readingOrder) {\n convertOptions.readingOrder = cliOptions.readingOrder;\n }\n if (cliOptions.markdownPageSeparator) {\n convertOptions.markdownPageSeparator = cliOptions.markdownPageSeparator;\n }\n if (cliOptions.markdownWithHtml) {\n convertOptions.markdownWithHtml = true;\n }\n if (cliOptions.textPageSeparator) {\n convertOptions.textPageSeparator = cliOptions.textPageSeparator;\n }\n if (cliOptions.htmlPageSeparator) {\n convertOptions.htmlPageSeparator = cliOptions.htmlPageSeparator;\n }\n if (cliOptions.imageOutput) {\n convertOptions.imageOutput = cliOptions.imageOutput;\n }\n if (cliOptions.imageFormat) {\n convertOptions.imageFormat = cliOptions.imageFormat;\n }\n if (cliOptions.imageDir) {\n convertOptions.imageDir = cliOptions.imageDir;\n }\n if (cliOptions.pages) {\n convertOptions.pages = cliOptions.pages;\n }\n if (cliOptions.includeHeaderFooter) {\n convertOptions.includeHeaderFooter = true;\n }\n if (cliOptions.detectStrikethrough) {\n convertOptions.detectStrikethrough = true;\n }\n if (cliOptions.hybrid) {\n convertOptions.hybrid = cliOptions.hybrid;\n }\n if (cliOptions.hybridMode) {\n convertOptions.hybridMode = cliOptions.hybridMode;\n }\n if (cliOptions.hybridUrl) {\n convertOptions.hybridUrl = cliOptions.hybridUrl;\n }\n if (cliOptions.hybridTimeout) {\n convertOptions.hybridTimeout = cliOptions.hybridTimeout;\n }\n if (cliOptions.hybridChunkSize) {\n convertOptions.hybridChunkSize = cliOptions.hybridChunkSize;\n }\n if (cliOptions.hybridFallback) {\n convertOptions.hybridFallback = true;\n }\n if (cliOptions.toStdout) {\n convertOptions.toStdout = true;\n }\n if (cliOptions.threads) {\n convertOptions.threads = cliOptions.threads;\n }\n if (cliOptions.imageResolution) {\n convertOptions.imageResolution = cliOptions.imageResolution;\n }\n if (cliOptions.spaceRatio) {\n convertOptions.spaceRatio = cliOptions.spaceRatio;\n }\n if (cliOptions.sanitizeRules !== undefined && cliOptions.sanitizeRules !== null) {\n convertOptions.sanitizeRules = cliOptions.sanitizeRules;\n }\n\n return convertOptions;\n}\n\n/**\n * Build CLI arguments array from ConvertOptions.\n */\nexport function buildArgs(options: ConvertOptions): string[] {\n const args: string[] = [];\n\n if (options.outputDir) {\n args.push('--output-dir', options.outputDir);\n }\n if (options.password) {\n args.push('--password', options.password);\n }\n if (options.format) {\n if (Array.isArray(options.format)) {\n if (options.format.length > 0) {\n args.push('--format', options.format.join(','));\n }\n } else {\n args.push('--format', options.format);\n }\n }\n if (options.quiet) {\n args.push('--quiet');\n }\n if (options.contentSafetyOff) {\n if (Array.isArray(options.contentSafetyOff)) {\n if (options.contentSafetyOff.length > 0) {\n args.push('--content-safety-off', options.contentSafetyOff.join(','));\n }\n } else {\n args.push('--content-safety-off', options.contentSafetyOff);\n }\n }\n if (options.sanitize) {\n args.push('--sanitize');\n }\n if (options.keepLineBreaks) {\n args.push('--keep-line-breaks');\n }\n if (options.replaceInvalidChars) {\n args.push('--replace-invalid-chars', options.replaceInvalidChars);\n }\n if (options.useStructTree) {\n args.push('--use-struct-tree');\n }\n if (options.tableMethod) {\n args.push('--table-method', options.tableMethod);\n }\n if (options.readingOrder) {\n args.push('--reading-order', options.readingOrder);\n }\n if (options.markdownPageSeparator) {\n args.push('--markdown-page-separator', options.markdownPageSeparator);\n }\n if (options.markdownWithHtml) {\n args.push('--markdown-with-html');\n }\n if (options.textPageSeparator) {\n args.push('--text-page-separator', options.textPageSeparator);\n }\n if (options.htmlPageSeparator) {\n args.push('--html-page-separator', options.htmlPageSeparator);\n }\n if (options.imageOutput) {\n args.push('--image-output', options.imageOutput);\n }\n if (options.imageFormat) {\n args.push('--image-format', options.imageFormat);\n }\n if (options.imageDir) {\n args.push('--image-dir', options.imageDir);\n }\n if (options.pages) {\n args.push('--pages', options.pages);\n }\n if (options.includeHeaderFooter) {\n args.push('--include-header-footer');\n }\n if (options.detectStrikethrough) {\n args.push('--detect-strikethrough');\n }\n if (options.hybrid) {\n args.push('--hybrid', options.hybrid);\n }\n if (options.hybridMode) {\n args.push('--hybrid-mode', options.hybridMode);\n }\n if (options.hybridUrl) {\n args.push('--hybrid-url', options.hybridUrl);\n }\n if (options.hybridTimeout) {\n args.push('--hybrid-timeout', options.hybridTimeout);\n }\n if (options.hybridChunkSize) {\n args.push('--hybrid-chunk-size', options.hybridChunkSize);\n }\n if (options.hybridFallback) {\n args.push('--hybrid-fallback');\n }\n if (options.toStdout) {\n args.push('--to-stdout');\n }\n if (options.threads) {\n args.push('--threads', options.threads);\n }\n if (options.imageResolution) {\n args.push('--image-resolution', options.imageResolution);\n }\n if (options.spaceRatio) {\n args.push('--space-ratio', options.spaceRatio);\n }\n if (options.sanitizeRules !== undefined && options.sanitizeRules !== null) {\n args.push('--sanitize-rules', options.sanitizeRules);\n }\n\n return args;\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\nimport { Command } from 'commander';\n\n/**\n * Register all CLI options on the given Commander program.\n */\nexport function registerCliOptions(program: Command): void {\n program.option('-o, --output-dir <value>', 'Directory where output files are written. Default: input file directory');\n program.option('-p, --password <value>', 'Password for encrypted PDF files');\n program.option('-f, --format <value>', 'Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output.');\n program.option('-q, --quiet', 'Suppress console logging output');\n program.option('--content-safety-off <value>', 'Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background');\n program.option('--sanitize', 'Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders');\n program.option('--keep-line-breaks', 'Preserve original line breaks in extracted text');\n program.option('--replace-invalid-chars <value>', 'Replacement character for invalid/unrecognized characters. Default: space');\n program.option('--use-struct-tree', 'Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called');\n program.option('--table-method <value>', 'Table detection method. Values: default (border-based), cluster (border + cluster). Default: default');\n program.option('--reading-order <value>', 'Reading order algorithm. Values: off, xycut. Default: xycut');\n program.option('--markdown-page-separator <value>', 'Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none');\n program.option('--markdown-with-html', 'Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown.');\n program.option('--text-page-separator <value>', 'Separator between pages in text output. Use %page-number% for page numbers. Default: none');\n program.option('--html-page-separator <value>', 'Separator between pages in HTML output. Use %page-number% for page numbers. Default: none');\n program.option('--image-output <value>', 'Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external');\n program.option('--image-format <value>', 'Output format for extracted images. Values: png, jpeg. Default: png');\n program.option('--image-dir <value>', 'Directory for extracted images (applies only with --image-output external)');\n program.option('--pages <value>', 'Pages to extract (e.g., \"1,3,5-7\"). Default: all pages');\n program.option('--include-header-footer', 'Include page headers and footers in output');\n program.option('--detect-strikethrough', 'Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental)');\n program.option('--hybrid <value>', 'Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence)');\n program.option('--hybrid-mode <value>', 'Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend)');\n program.option('--hybrid-url <value>', 'Hybrid backend server URL (overrides default)');\n program.option('--hybrid-timeout <value>', 'Hybrid backend request timeout in milliseconds (0 = use the backend\\'s own default). Default: 0');\n program.option('--hybrid-chunk-size <value>', 'Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50');\n program.option('--hybrid-fallback', 'Opt in to Java fallback on hybrid backend error (default: disabled)');\n program.option('--to-stdout', 'Write output to stdout instead of file (single format only)');\n program.option('--threads <value>', 'Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode');\n program.option('--image-resolution <value>', 'Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0.');\n program.option('--space-ratio <value>', 'Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17');\n program.option('--sanitize-rules <value>', 'Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize');\n}\n"],"mappings":"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","names":["__filename"]}
1
+ {"version":3,"sources":["../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.31_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js","../src/cli.ts","../src/index.ts","../src/convert-options.generated.ts","../src/cli-options.generated.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","#!/usr/bin/env node\nimport { Command, CommanderError } from 'commander';\nimport { _runForCli } from './index.js';\nimport { CliOptions, buildConvertOptions } from './convert-options.generated.js';\nimport { registerCliOptions } from './cli-options.generated.js';\n\nfunction createProgram(): Command {\n const program = new Command();\n\n program\n .name('opendataloader-pdf')\n .usage('[options] <input...>')\n .description('Convert PDFs using the OpenDataLoader CLI.')\n .showHelpAfterError(\"Use '--help' to see available options.\")\n .showSuggestionAfterError(false)\n .argument('<input...>', 'Input files or directories to convert');\n\n // Register CLI options from auto-generated file\n registerCliOptions(program);\n\n program.configureOutput({\n writeErr: (str) => {\n console.error(str.trimEnd());\n },\n outputError: (str, write) => {\n write(str);\n },\n });\n\n return program;\n}\n\nasync function main(): Promise<number> {\n const program = createProgram();\n\n program.exitOverride();\n\n try {\n program.parse(process.argv);\n } catch (err) {\n if (err instanceof CommanderError) {\n if (err.code === 'commander.helpDisplayed') {\n return 0;\n }\n return err.exitCode ?? 1;\n }\n\n const message = err instanceof Error ? err.message : String(err);\n console.error(message);\n console.error(\"Use '--help' to see available options.\");\n return 1;\n }\n\n const cliOptions = program.opts<CliOptions>();\n const inputPaths = program.args;\n const convertOptions = buildConvertOptions(cliOptions);\n\n try {\n // _runForCli streams stdout/stderr to the parent process as they arrive;\n // we deliberately do not re-print anything here. (Issue #398.)\n await _runForCli(inputPaths, convertOptions);\n return 0;\n } catch (err) {\n // Subprocess-exit errors are already on the user's terminal via the live\n // stderr stream — re-printing would duplicate output and risk leaking\n // anything sensitive Java logged (e.g. a --password value echoed by an\n // underlying library). Wrapper-side failures (JAR not found, java not in\n // PATH, bad input path) still need to be surfaced.\n const isJavaExit =\n err instanceof Error && (err as Error & { isJavaExit?: boolean }).isJavaExit === true;\n if (!isJavaExit) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(message);\n }\n return 1;\n }\n}\n\nmain().then((code) => {\n if (code !== 0) {\n process.exit(code);\n }\n});\n","import { spawn } from 'child_process';\nimport { randomUUID } from 'crypto';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { StringDecoder } from 'string_decoder';\nimport { fileURLToPath } from 'url';\n\n// Re-export types and utilities from auto-generated file\nexport type { ConvertOptions } from './convert-options.generated.js';\nexport { buildArgs } from './convert-options.generated.js';\nimport type { ConvertOptions } from './convert-options.generated.js';\nimport { buildArgs } from './convert-options.generated.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst JAR_NAME = 'opendataloader-pdf-cli.jar';\n\n// Environment variables that the JVM reads options from.\nconst JAVA_OPTION_VARS = ['JAVA_TOOL_OPTIONS', 'JDK_JAVA_OPTIONS', '_JAVA_OPTIONS'];\n\n/**\n * Returns the option that gives Java the temporary folder of this runtime.\n * The JVM does not read TMPDIR, so without this option Java can use another\n * folder than Node. A command-line option wins over JAVA_TOOL_OPTIONS and\n * JDK_JAVA_OPTIONS, so add none if the user set java.io.tmpdir there.\n */\nfunction tempDirOptions(): string[] {\n if (JAVA_OPTION_VARS.some((name) => (process.env[name] ?? '').includes('-Djava.io.tmpdir='))) {\n return [];\n }\n // os.tmpdir() returns TMPDIR without a check: it can name a missing\n // folder, a folder without write access, or a file. Create and delete a\n // probe file, as Java does. If that fails, add nothing and let Java keep\n // its own default.\n const dir = os.tmpdir();\n const probe = path.join(dir, `opendataloader-${process.pid}-${randomUUID()}.probe`);\n try {\n fs.closeSync(fs.openSync(probe, 'wx'));\n fs.unlinkSync(probe);\n } catch {\n return [];\n }\n return [`-Djava.io.tmpdir=${dir}`];\n}\n\ninterface JarExecutionOptions {\n /**\n * When true, forwards Java's stdout and stderr chunks to the parent\n * process in real time as well as accumulating them. Used by the bundled\n * CLI so long-running conversions show progress as it happens.\n */\n streamOutput?: boolean;\n}\n\nfunction executeJar(args: string[], executionOptions: JarExecutionOptions = {}): Promise<string> {\n const { streamOutput = false } = executionOptions;\n\n return new Promise((resolve, reject) => {\n const jarPath = path.join(__dirname, '..', 'lib', JAR_NAME);\n\n if (!fs.existsSync(jarPath)) {\n return reject(\n new Error(`JAR file not found at ${jarPath}. Please run the build script first.`),\n );\n }\n\n const command = 'java';\n // Force headless AWT so macOS doesn't surface a Dock icon (and steal focus)\n // every time the JVM touches ImageIO/PDFBox rendering. Safe on all OSes —\n // the CLI never opens a UI window, only manipulates BufferedImages.\n const commandArgs = [\n '-Djava.awt.headless=true',\n '-Dapple.awt.UIElement=true',\n ...tempDirOptions(),\n '-jar',\n jarPath,\n ...args,\n ];\n\n const javaProcess = spawn(command, commandArgs);\n\n let stdout = '';\n let stderr = '';\n // StringDecoder buffers incomplete multi-byte UTF-8 sequences across\n // chunk boundaries — Buffer.toString() alone would emit replacement\n // characters when, e.g., a 3-byte Korean codepoint splits across two\n // 'data' events. One decoder per stream so they don't share state.\n const stdoutDecoder = new StringDecoder('utf8');\n const stderrDecoder = new StringDecoder('utf8');\n\n javaProcess.stdout.on('data', (data: Buffer) => {\n const chunk = stdoutDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n // Stream-only: don't also accumulate, or a multi-hour conversion\n // would buffer its entire (potentially gigabyte) stdout in memory\n // for no consumer.\n process.stdout.write(chunk);\n } else {\n stdout += chunk;\n }\n });\n\n javaProcess.stderr.on('data', (data: Buffer) => {\n const chunk = stderrDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n process.stderr.write(chunk);\n }\n // stderr is always accumulated (progress logs are small and we need\n // them for error messages on non-zero exit).\n stderr += chunk;\n });\n\n javaProcess.on('close', (code) => {\n // Flush any trailing bytes the decoder is still holding (always emit\n // them — if we drop them on error paths, error messages with non-ASCII\n // characters lose their tail).\n const stdoutTail = stdoutDecoder.end();\n const stderrTail = stderrDecoder.end();\n if (stdoutTail.length > 0) {\n if (streamOutput) {\n process.stdout.write(stdoutTail);\n } else {\n stdout += stdoutTail;\n }\n }\n if (stderrTail.length > 0) {\n if (streamOutput) process.stderr.write(stderrTail);\n stderr += stderrTail;\n }\n\n if (code === 0) {\n resolve(stdout);\n } else {\n const errorOutput = stderr || stdout;\n const error = new Error(\n `The opendataloader-pdf CLI exited with code ${code}.\\n\\n${errorOutput}`,\n );\n // Tag so the CLI can suppress re-printing this message — Java's\n // stderr was already streamed live to the parent in CLI mode, and\n // re-printing risks leaking anything sensitive Java logged\n // (e.g. a --password value echoed by an underlying library).\n (error as Error & { isJavaExit?: boolean }).isJavaExit = true;\n reject(error);\n }\n });\n\n javaProcess.on('error', (err: Error) => {\n if (err.message.includes('ENOENT')) {\n reject(\n new Error(\n \"'java' command not found. Please ensure Java is installed and in your system's PATH.\",\n ),\n );\n } else {\n reject(err);\n }\n });\n });\n}\n\nfunction buildJarArgs(\n inputPaths: string | string[],\n options: ConvertOptions,\n): string[] | Error {\n const inputList = Array.isArray(inputPaths) ? inputPaths : [inputPaths];\n if (inputList.length === 0) {\n return new Error('At least one input path must be provided.');\n }\n\n for (const input of inputList) {\n if (!fs.existsSync(input)) {\n return new Error(`Input file or folder not found: ${input}`);\n }\n }\n\n return [...inputList, ...buildArgs(options)];\n}\n\nexport function convert(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<string> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n return Promise.reject(argsOrError);\n }\n // Library API: never streams to the parent process. Returns the full stdout\n // string so callers can do `const out = await convert(...)` without surprise\n // side-effects on process.stdout / process.stderr.\n return executeJar(argsOrError, { streamOutput: false });\n}\n\n/**\n * Internal entry point used by the bundled CLI. Streams Java's stdout and\n * stderr to the parent process in real time (so long-running conversions like\n * hybrid mode show progress as it happens) and resolves without a stdout\n * payload — preventing the caller from re-printing what was already streamed.\n *\n * Not part of the public API: do not import this from application code. Use\n * {@link convert} instead.\n *\n * @internal\n */\nexport async function _runForCli(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<void> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n throw argsOrError;\n }\n await executeJar(argsOrError, { streamOutput: true });\n}\n\n/**\n * @deprecated Use `convert()` and `ConvertOptions` instead. This function will be removed in a future version.\n */\nexport interface RunOptions {\n outputFolder?: string;\n password?: string;\n replaceInvalidChars?: string;\n generateMarkdown?: boolean;\n generateHtml?: boolean;\n generateAnnotatedPdf?: boolean;\n keepLineBreaks?: boolean;\n contentSafetyOff?: string;\n htmlInMarkdown?: boolean;\n addImageToMarkdown?: boolean;\n noJson?: boolean;\n debug?: boolean;\n useStructTree?: boolean;\n}\n\n/**\n * @deprecated Use `convert()` instead. This function will be removed in a future version.\n */\nexport function run(inputPath: string, options: RunOptions = {}): Promise<string> {\n console.warn(\n 'Warning: run() is deprecated and will be removed in a future version. Use convert() instead.',\n );\n\n // Build format array based on legacy boolean options\n const formats: string[] = [];\n if (!options.noJson) {\n formats.push('json');\n }\n if (options.generateMarkdown) {\n if (options.addImageToMarkdown) {\n formats.push('markdown-with-images');\n } else if (options.htmlInMarkdown) {\n formats.push('markdown-with-html');\n } else {\n formats.push('markdown');\n }\n }\n if (options.generateHtml) {\n formats.push('html');\n }\n if (options.generateAnnotatedPdf) {\n formats.push('pdf');\n }\n\n return convert(inputPath, {\n outputDir: options.outputFolder,\n password: options.password,\n replaceInvalidChars: options.replaceInvalidChars,\n keepLineBreaks: options.keepLineBreaks,\n contentSafetyOff: options.contentSafetyOff,\n useStructTree: options.useStructTree,\n format: formats.length > 0 ? formats : undefined,\n quiet: !options.debug,\n });\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\n/**\n * Options for the convert function.\n */\nexport interface ConvertOptions {\n /** Directory where output files are written. Default: input file directory */\n outputDir?: string;\n /** Password for encrypted PDF files */\n password?: string;\n /** Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output. */\n format?: string | string[];\n /** Suppress console logging output */\n quiet?: boolean;\n /** Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background */\n contentSafetyOff?: string | string[];\n /** Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders */\n sanitize?: boolean;\n /** Preserve original line breaks in extracted text */\n keepLineBreaks?: boolean;\n /** Replacement character for invalid/unrecognized characters. Default: space */\n replaceInvalidChars?: string;\n /** Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called */\n useStructTree?: boolean;\n /** Table detection method. Values: default (border-based), cluster (border + cluster). Default: default */\n tableMethod?: string;\n /** Reading order algorithm. Values: off, xycut. Default: xycut */\n readingOrder?: string;\n /** Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none */\n markdownPageSeparator?: string;\n /** Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown. */\n markdownWithHtml?: boolean;\n /** Separator between pages in text output. Use %page-number% for page numbers. Default: none */\n textPageSeparator?: string;\n /** Separator between pages in HTML output. Use %page-number% for page numbers. Default: none */\n htmlPageSeparator?: string;\n /** Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external */\n imageOutput?: string;\n /** Output format for extracted images. Values: png, jpeg. Default: png */\n imageFormat?: string;\n /** Directory for extracted images (applies only with --image-output external) */\n imageDir?: string;\n /** Pages to extract (e.g., \"1,3,5-7\"). Default: all pages */\n pages?: string;\n /** Include page headers and footers in output */\n includeHeaderFooter?: boolean;\n /** Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental) */\n detectStrikethrough?: boolean;\n /** Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence) */\n hybrid?: string;\n /** Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend) */\n hybridMode?: string;\n /** Hybrid backend server URL (overrides default) */\n hybridUrl?: string;\n /** Hybrid backend request timeout in milliseconds (0 = use the backend's own default). Default: 0 */\n hybridTimeout?: string;\n /** Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50 */\n hybridChunkSize?: string;\n /** Opt in to Java fallback on hybrid backend error (default: disabled) */\n hybridFallback?: boolean;\n /** Write output to stdout instead of file (single format only) */\n toStdout?: boolean;\n /** Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode */\n threads?: string;\n /** Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0. */\n imageResolution?: string;\n /** Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17 */\n spaceRatio?: string;\n /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */\n sanitizeRules?: string;\n /** Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text */\n includeLinks?: boolean;\n /** Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000 */\n hybridAvailabilityTimeout?: string;\n /** With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder */\n hybridTriageLog?: boolean;\n}\n\n/**\n * Options as parsed from CLI (all values are strings from commander).\n */\nexport interface CliOptions {\n outputDir?: string;\n password?: string;\n format?: string;\n quiet?: boolean;\n contentSafetyOff?: string;\n sanitize?: boolean;\n keepLineBreaks?: boolean;\n replaceInvalidChars?: string;\n useStructTree?: boolean;\n tableMethod?: string;\n readingOrder?: string;\n markdownPageSeparator?: string;\n markdownWithHtml?: boolean;\n textPageSeparator?: string;\n htmlPageSeparator?: string;\n imageOutput?: string;\n imageFormat?: string;\n imageDir?: string;\n pages?: string;\n includeHeaderFooter?: boolean;\n detectStrikethrough?: boolean;\n hybrid?: string;\n hybridMode?: string;\n hybridUrl?: string;\n hybridTimeout?: string;\n hybridChunkSize?: string;\n hybridFallback?: boolean;\n toStdout?: boolean;\n threads?: string;\n imageResolution?: string;\n spaceRatio?: string;\n sanitizeRules?: string;\n includeLinks?: boolean;\n hybridAvailabilityTimeout?: string;\n hybridTriageLog?: boolean;\n}\n\n/**\n * Convert CLI options to ConvertOptions.\n */\nexport function buildConvertOptions(cliOptions: CliOptions): ConvertOptions {\n const convertOptions: ConvertOptions = {};\n\n if (cliOptions.outputDir) {\n convertOptions.outputDir = cliOptions.outputDir;\n }\n if (cliOptions.password) {\n convertOptions.password = cliOptions.password;\n }\n if (cliOptions.format) {\n convertOptions.format = cliOptions.format;\n }\n if (cliOptions.quiet) {\n convertOptions.quiet = true;\n }\n if (cliOptions.contentSafetyOff) {\n convertOptions.contentSafetyOff = cliOptions.contentSafetyOff;\n }\n if (cliOptions.sanitize) {\n convertOptions.sanitize = true;\n }\n if (cliOptions.keepLineBreaks) {\n convertOptions.keepLineBreaks = true;\n }\n if (cliOptions.replaceInvalidChars) {\n convertOptions.replaceInvalidChars = cliOptions.replaceInvalidChars;\n }\n if (cliOptions.useStructTree) {\n convertOptions.useStructTree = true;\n }\n if (cliOptions.tableMethod) {\n convertOptions.tableMethod = cliOptions.tableMethod;\n }\n if (cliOptions.readingOrder) {\n convertOptions.readingOrder = cliOptions.readingOrder;\n }\n if (cliOptions.markdownPageSeparator) {\n convertOptions.markdownPageSeparator = cliOptions.markdownPageSeparator;\n }\n if (cliOptions.markdownWithHtml) {\n convertOptions.markdownWithHtml = true;\n }\n if (cliOptions.textPageSeparator) {\n convertOptions.textPageSeparator = cliOptions.textPageSeparator;\n }\n if (cliOptions.htmlPageSeparator) {\n convertOptions.htmlPageSeparator = cliOptions.htmlPageSeparator;\n }\n if (cliOptions.imageOutput) {\n convertOptions.imageOutput = cliOptions.imageOutput;\n }\n if (cliOptions.imageFormat) {\n convertOptions.imageFormat = cliOptions.imageFormat;\n }\n if (cliOptions.imageDir) {\n convertOptions.imageDir = cliOptions.imageDir;\n }\n if (cliOptions.pages) {\n convertOptions.pages = cliOptions.pages;\n }\n if (cliOptions.includeHeaderFooter) {\n convertOptions.includeHeaderFooter = true;\n }\n if (cliOptions.detectStrikethrough) {\n convertOptions.detectStrikethrough = true;\n }\n if (cliOptions.hybrid) {\n convertOptions.hybrid = cliOptions.hybrid;\n }\n if (cliOptions.hybridMode) {\n convertOptions.hybridMode = cliOptions.hybridMode;\n }\n if (cliOptions.hybridUrl) {\n convertOptions.hybridUrl = cliOptions.hybridUrl;\n }\n if (cliOptions.hybridTimeout) {\n convertOptions.hybridTimeout = cliOptions.hybridTimeout;\n }\n if (cliOptions.hybridChunkSize) {\n convertOptions.hybridChunkSize = cliOptions.hybridChunkSize;\n }\n if (cliOptions.hybridFallback) {\n convertOptions.hybridFallback = true;\n }\n if (cliOptions.toStdout) {\n convertOptions.toStdout = true;\n }\n if (cliOptions.threads) {\n convertOptions.threads = cliOptions.threads;\n }\n if (cliOptions.imageResolution) {\n convertOptions.imageResolution = cliOptions.imageResolution;\n }\n if (cliOptions.spaceRatio) {\n convertOptions.spaceRatio = cliOptions.spaceRatio;\n }\n if (cliOptions.sanitizeRules !== undefined && cliOptions.sanitizeRules !== null) {\n convertOptions.sanitizeRules = cliOptions.sanitizeRules;\n }\n if (cliOptions.includeLinks) {\n convertOptions.includeLinks = true;\n }\n if (cliOptions.hybridAvailabilityTimeout) {\n convertOptions.hybridAvailabilityTimeout = cliOptions.hybridAvailabilityTimeout;\n }\n if (cliOptions.hybridTriageLog) {\n convertOptions.hybridTriageLog = true;\n }\n\n return convertOptions;\n}\n\n/**\n * Build CLI arguments array from ConvertOptions.\n */\nexport function buildArgs(options: ConvertOptions): string[] {\n const args: string[] = [];\n\n if (options.outputDir) {\n args.push('--output-dir', options.outputDir);\n }\n if (options.password) {\n args.push('--password', options.password);\n }\n if (options.format) {\n if (Array.isArray(options.format)) {\n if (options.format.length > 0) {\n args.push('--format', options.format.join(','));\n }\n } else {\n args.push('--format', options.format);\n }\n }\n if (options.quiet) {\n args.push('--quiet');\n }\n if (options.contentSafetyOff) {\n if (Array.isArray(options.contentSafetyOff)) {\n if (options.contentSafetyOff.length > 0) {\n args.push('--content-safety-off', options.contentSafetyOff.join(','));\n }\n } else {\n args.push('--content-safety-off', options.contentSafetyOff);\n }\n }\n if (options.sanitize) {\n args.push('--sanitize');\n }\n if (options.keepLineBreaks) {\n args.push('--keep-line-breaks');\n }\n if (options.replaceInvalidChars) {\n args.push('--replace-invalid-chars', options.replaceInvalidChars);\n }\n if (options.useStructTree) {\n args.push('--use-struct-tree');\n }\n if (options.tableMethod) {\n args.push('--table-method', options.tableMethod);\n }\n if (options.readingOrder) {\n args.push('--reading-order', options.readingOrder);\n }\n if (options.markdownPageSeparator) {\n args.push('--markdown-page-separator', options.markdownPageSeparator);\n }\n if (options.markdownWithHtml) {\n args.push('--markdown-with-html');\n }\n if (options.textPageSeparator) {\n args.push('--text-page-separator', options.textPageSeparator);\n }\n if (options.htmlPageSeparator) {\n args.push('--html-page-separator', options.htmlPageSeparator);\n }\n if (options.imageOutput) {\n args.push('--image-output', options.imageOutput);\n }\n if (options.imageFormat) {\n args.push('--image-format', options.imageFormat);\n }\n if (options.imageDir) {\n args.push('--image-dir', options.imageDir);\n }\n if (options.pages) {\n args.push('--pages', options.pages);\n }\n if (options.includeHeaderFooter) {\n args.push('--include-header-footer');\n }\n if (options.detectStrikethrough) {\n args.push('--detect-strikethrough');\n }\n if (options.hybrid) {\n args.push('--hybrid', options.hybrid);\n }\n if (options.hybridMode) {\n args.push('--hybrid-mode', options.hybridMode);\n }\n if (options.hybridUrl) {\n args.push('--hybrid-url', options.hybridUrl);\n }\n if (options.hybridTimeout) {\n args.push('--hybrid-timeout', options.hybridTimeout);\n }\n if (options.hybridChunkSize) {\n args.push('--hybrid-chunk-size', options.hybridChunkSize);\n }\n if (options.hybridFallback) {\n args.push('--hybrid-fallback');\n }\n if (options.toStdout) {\n args.push('--to-stdout');\n }\n if (options.threads) {\n args.push('--threads', options.threads);\n }\n if (options.imageResolution) {\n args.push('--image-resolution', options.imageResolution);\n }\n if (options.spaceRatio) {\n args.push('--space-ratio', options.spaceRatio);\n }\n if (options.sanitizeRules !== undefined && options.sanitizeRules !== null) {\n args.push('--sanitize-rules', options.sanitizeRules);\n }\n if (options.includeLinks) {\n args.push('--include-links');\n }\n if (options.hybridAvailabilityTimeout) {\n args.push('--hybrid-availability-timeout', options.hybridAvailabilityTimeout);\n }\n if (options.hybridTriageLog) {\n args.push('--hybrid-triage-log');\n }\n\n return args;\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\nimport { Command } from 'commander';\n\n/**\n * Register all CLI options on the given Commander program.\n */\nexport function registerCliOptions(program: Command): void {\n program.option('-o, --output-dir <value>', 'Directory where output files are written. Default: input file directory');\n program.option('-p, --password <value>', 'Password for encrypted PDF files');\n program.option('-f, --format <value>', 'Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output.');\n program.option('-q, --quiet', 'Suppress console logging output');\n program.option('--content-safety-off <value>', 'Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background');\n program.option('--sanitize', 'Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders');\n program.option('--keep-line-breaks', 'Preserve original line breaks in extracted text');\n program.option('--replace-invalid-chars <value>', 'Replacement character for invalid/unrecognized characters. Default: space');\n program.option('--use-struct-tree', 'Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called');\n program.option('--table-method <value>', 'Table detection method. Values: default (border-based), cluster (border + cluster). Default: default');\n program.option('--reading-order <value>', 'Reading order algorithm. Values: off, xycut. Default: xycut');\n program.option('--markdown-page-separator <value>', 'Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none');\n program.option('--markdown-with-html', 'Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown.');\n program.option('--text-page-separator <value>', 'Separator between pages in text output. Use %page-number% for page numbers. Default: none');\n program.option('--html-page-separator <value>', 'Separator between pages in HTML output. Use %page-number% for page numbers. Default: none');\n program.option('--image-output <value>', 'Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external');\n program.option('--image-format <value>', 'Output format for extracted images. Values: png, jpeg. Default: png');\n program.option('--image-dir <value>', 'Directory for extracted images (applies only with --image-output external)');\n program.option('--pages <value>', 'Pages to extract (e.g., \"1,3,5-7\"). Default: all pages');\n program.option('--include-header-footer', 'Include page headers and footers in output');\n program.option('--detect-strikethrough', 'Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental)');\n program.option('--hybrid <value>', 'Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence)');\n program.option('--hybrid-mode <value>', 'Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend)');\n program.option('--hybrid-url <value>', 'Hybrid backend server URL (overrides default)');\n program.option('--hybrid-timeout <value>', 'Hybrid backend request timeout in milliseconds (0 = use the backend\\'s own default). Default: 0');\n program.option('--hybrid-chunk-size <value>', 'Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50');\n program.option('--hybrid-fallback', 'Opt in to Java fallback on hybrid backend error (default: disabled)');\n program.option('--to-stdout', 'Write output to stdout instead of file (single format only)');\n program.option('--threads <value>', 'Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode');\n program.option('--image-resolution <value>', 'Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0.');\n program.option('--space-ratio <value>', 'Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17');\n program.option('--sanitize-rules <value>', 'Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize');\n program.option('--include-links', 'Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text');\n program.option('--hybrid-availability-timeout <value>', 'Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000');\n program.option('--hybrid-triage-log', 'With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,IAAM,mBAAmB,MACvB,OAAO,aAAa,cAChB,IAAI,IAAI,QAAQ,UAAU,EAAE,EAAE,OAC7B,SAAS,iBAAiB,SAAS,cAAc,QAAQ,YAAY,MAAM,WAC1E,SAAS,cAAc,MACvB,IAAI,IAAI,WAAW,SAAS,OAAO,EAAE;AAEtC,IAAM,gBAAgC,iCAAiB;;;ACX9D,uBAAwC;;;ACDxC,2BAAsB;AACtB,oBAA2B;AAC3B,WAAsB;AACtB,SAAoB;AACpB,SAAoB;AACpB,4BAA8B;AAC9B,iBAA8B;;;ACqHvB,SAAS,oBAAoB,YAAwC;AAC1E,QAAM,iBAAiC,CAAC;AAExC,MAAI,WAAW,WAAW;AACxB,mBAAe,YAAY,WAAW;AAAA,EACxC;AACA,MAAI,WAAW,UAAU;AACvB,mBAAe,WAAW,WAAW;AAAA,EACvC;AACA,MAAI,WAAW,QAAQ;AACrB,mBAAe,SAAS,WAAW;AAAA,EACrC;AACA,MAAI,WAAW,OAAO;AACpB,mBAAe,QAAQ;AAAA,EACzB;AACA,MAAI,WAAW,kBAAkB;AAC/B,mBAAe,mBAAmB,WAAW;AAAA,EAC/C;AACA,MAAI,WAAW,UAAU;AACvB,mBAAe,WAAW;AAAA,EAC5B;AACA,MAAI,WAAW,gBAAgB;AAC7B,mBAAe,iBAAiB;AAAA,EAClC;AACA,MAAI,WAAW,qBAAqB;AAClC,mBAAe,sBAAsB,WAAW;AAAA,EAClD;AACA,MAAI,WAAW,eAAe;AAC5B,mBAAe,gBAAgB;AAAA,EACjC;AACA,MAAI,WAAW,aAAa;AAC1B,mBAAe,cAAc,WAAW;AAAA,EAC1C;AACA,MAAI,WAAW,cAAc;AAC3B,mBAAe,eAAe,WAAW;AAAA,EAC3C;AACA,MAAI,WAAW,uBAAuB;AACpC,mBAAe,wBAAwB,WAAW;AAAA,EACpD;AACA,MAAI,WAAW,kBAAkB;AAC/B,mBAAe,mBAAmB;AAAA,EACpC;AACA,MAAI,WAAW,mBAAmB;AAChC,mBAAe,oBAAoB,WAAW;AAAA,EAChD;AACA,MAAI,WAAW,mBAAmB;AAChC,mBAAe,oBAAoB,WAAW;AAAA,EAChD;AACA,MAAI,WAAW,aAAa;AAC1B,mBAAe,cAAc,WAAW;AAAA,EAC1C;AACA,MAAI,WAAW,aAAa;AAC1B,mBAAe,cAAc,WAAW;AAAA,EAC1C;AACA,MAAI,WAAW,UAAU;AACvB,mBAAe,WAAW,WAAW;AAAA,EACvC;AACA,MAAI,WAAW,OAAO;AACpB,mBAAe,QAAQ,WAAW;AAAA,EACpC;AACA,MAAI,WAAW,qBAAqB;AAClC,mBAAe,sBAAsB;AAAA,EACvC;AACA,MAAI,WAAW,qBAAqB;AAClC,mBAAe,sBAAsB;AAAA,EACvC;AACA,MAAI,WAAW,QAAQ;AACrB,mBAAe,SAAS,WAAW;AAAA,EACrC;AACA,MAAI,WAAW,YAAY;AACzB,mBAAe,aAAa,WAAW;AAAA,EACzC;AACA,MAAI,WAAW,WAAW;AACxB,mBAAe,YAAY,WAAW;AAAA,EACxC;AACA,MAAI,WAAW,eAAe;AAC5B,mBAAe,gBAAgB,WAAW;AAAA,EAC5C;AACA,MAAI,WAAW,iBAAiB;AAC9B,mBAAe,kBAAkB,WAAW;AAAA,EAC9C;AACA,MAAI,WAAW,gBAAgB;AAC7B,mBAAe,iBAAiB;AAAA,EAClC;AACA,MAAI,WAAW,UAAU;AACvB,mBAAe,WAAW;AAAA,EAC5B;AACA,MAAI,WAAW,SAAS;AACtB,mBAAe,UAAU,WAAW;AAAA,EACtC;AACA,MAAI,WAAW,iBAAiB;AAC9B,mBAAe,kBAAkB,WAAW;AAAA,EAC9C;AACA,MAAI,WAAW,YAAY;AACzB,mBAAe,aAAa,WAAW;AAAA,EACzC;AACA,MAAI,WAAW,kBAAkB,UAAa,WAAW,kBAAkB,MAAM;AAC/E,mBAAe,gBAAgB,WAAW;AAAA,EAC5C;AACA,MAAI,WAAW,cAAc;AAC3B,mBAAe,eAAe;AAAA,EAChC;AACA,MAAI,WAAW,2BAA2B;AACxC,mBAAe,4BAA4B,WAAW;AAAA,EACxD;AACA,MAAI,WAAW,iBAAiB;AAC9B,mBAAe,kBAAkB;AAAA,EACnC;AAEA,SAAO;AACT;AAKO,SAAS,UAAU,SAAmC;AAC3D,QAAM,OAAiB,CAAC;AAExB,MAAI,QAAQ,WAAW;AACrB,SAAK,KAAK,gBAAgB,QAAQ,SAAS;AAAA,EAC7C;AACA,MAAI,QAAQ,UAAU;AACpB,SAAK,KAAK,cAAc,QAAQ,QAAQ;AAAA,EAC1C;AACA,MAAI,QAAQ,QAAQ;AAClB,QAAI,MAAM,QAAQ,QAAQ,MAAM,GAAG;AACjC,UAAI,QAAQ,OAAO,SAAS,GAAG;AAC7B,aAAK,KAAK,YAAY,QAAQ,OAAO,KAAK,GAAG,CAAC;AAAA,MAChD;AAAA,IACF,OAAO;AACL,WAAK,KAAK,YAAY,QAAQ,MAAM;AAAA,IACtC;AAAA,EACF;AACA,MAAI,QAAQ,OAAO;AACjB,SAAK,KAAK,SAAS;AAAA,EACrB;AACA,MAAI,QAAQ,kBAAkB;AAC5B,QAAI,MAAM,QAAQ,QAAQ,gBAAgB,GAAG;AAC3C,UAAI,QAAQ,iBAAiB,SAAS,GAAG;AACvC,aAAK,KAAK,wBAAwB,QAAQ,iBAAiB,KAAK,GAAG,CAAC;AAAA,MACtE;AAAA,IACF,OAAO;AACL,WAAK,KAAK,wBAAwB,QAAQ,gBAAgB;AAAA,IAC5D;AAAA,EACF;AACA,MAAI,QAAQ,UAAU;AACpB,SAAK,KAAK,YAAY;AAAA,EACxB;AACA,MAAI,QAAQ,gBAAgB;AAC1B,SAAK,KAAK,oBAAoB;AAAA,EAChC;AACA,MAAI,QAAQ,qBAAqB;AAC/B,SAAK,KAAK,2BAA2B,QAAQ,mBAAmB;AAAA,EAClE;AACA,MAAI,QAAQ,eAAe;AACzB,SAAK,KAAK,mBAAmB;AAAA,EAC/B;AACA,MAAI,QAAQ,aAAa;AACvB,SAAK,KAAK,kBAAkB,QAAQ,WAAW;AAAA,EACjD;AACA,MAAI,QAAQ,cAAc;AACxB,SAAK,KAAK,mBAAmB,QAAQ,YAAY;AAAA,EACnD;AACA,MAAI,QAAQ,uBAAuB;AACjC,SAAK,KAAK,6BAA6B,QAAQ,qBAAqB;AAAA,EACtE;AACA,MAAI,QAAQ,kBAAkB;AAC5B,SAAK,KAAK,sBAAsB;AAAA,EAClC;AACA,MAAI,QAAQ,mBAAmB;AAC7B,SAAK,KAAK,yBAAyB,QAAQ,iBAAiB;AAAA,EAC9D;AACA,MAAI,QAAQ,mBAAmB;AAC7B,SAAK,KAAK,yBAAyB,QAAQ,iBAAiB;AAAA,EAC9D;AACA,MAAI,QAAQ,aAAa;AACvB,SAAK,KAAK,kBAAkB,QAAQ,WAAW;AAAA,EACjD;AACA,MAAI,QAAQ,aAAa;AACvB,SAAK,KAAK,kBAAkB,QAAQ,WAAW;AAAA,EACjD;AACA,MAAI,QAAQ,UAAU;AACpB,SAAK,KAAK,eAAe,QAAQ,QAAQ;AAAA,EAC3C;AACA,MAAI,QAAQ,OAAO;AACjB,SAAK,KAAK,WAAW,QAAQ,KAAK;AAAA,EACpC;AACA,MAAI,QAAQ,qBAAqB;AAC/B,SAAK,KAAK,yBAAyB;AAAA,EACrC;AACA,MAAI,QAAQ,qBAAqB;AAC/B,SAAK,KAAK,wBAAwB;AAAA,EACpC;AACA,MAAI,QAAQ,QAAQ;AAClB,SAAK,KAAK,YAAY,QAAQ,MAAM;AAAA,EACtC;AACA,MAAI,QAAQ,YAAY;AACtB,SAAK,KAAK,iBAAiB,QAAQ,UAAU;AAAA,EAC/C;AACA,MAAI,QAAQ,WAAW;AACrB,SAAK,KAAK,gBAAgB,QAAQ,SAAS;AAAA,EAC7C;AACA,MAAI,QAAQ,eAAe;AACzB,SAAK,KAAK,oBAAoB,QAAQ,aAAa;AAAA,EACrD;AACA,MAAI,QAAQ,iBAAiB;AAC3B,SAAK,KAAK,uBAAuB,QAAQ,eAAe;AAAA,EAC1D;AACA,MAAI,QAAQ,gBAAgB;AAC1B,SAAK,KAAK,mBAAmB;AAAA,EAC/B;AACA,MAAI,QAAQ,UAAU;AACpB,SAAK,KAAK,aAAa;AAAA,EACzB;AACA,MAAI,QAAQ,SAAS;AACnB,SAAK,KAAK,aAAa,QAAQ,OAAO;AAAA,EACxC;AACA,MAAI,QAAQ,iBAAiB;AAC3B,SAAK,KAAK,sBAAsB,QAAQ,eAAe;AAAA,EACzD;AACA,MAAI,QAAQ,YAAY;AACtB,SAAK,KAAK,iBAAiB,QAAQ,UAAU;AAAA,EAC/C;AACA,MAAI,QAAQ,kBAAkB,UAAa,QAAQ,kBAAkB,MAAM;AACzE,SAAK,KAAK,oBAAoB,QAAQ,aAAa;AAAA,EACrD;AACA,MAAI,QAAQ,cAAc;AACxB,SAAK,KAAK,iBAAiB;AAAA,EAC7B;AACA,MAAI,QAAQ,2BAA2B;AACrC,SAAK,KAAK,iCAAiC,QAAQ,yBAAyB;AAAA,EAC9E;AACA,MAAI,QAAQ,iBAAiB;AAC3B,SAAK,KAAK,qBAAqB;AAAA,EACjC;AAEA,SAAO;AACT;;;AD1VA,IAAMA,kBAAa,0BAAc,aAAe;AAChD,IAAM,YAAiB,aAAQA,WAAU;AAEzC,IAAM,WAAW;AAGjB,IAAM,mBAAmB,CAAC,qBAAqB,oBAAoB,eAAe;AAQlF,SAAS,iBAA2B;AAClC,MAAI,iBAAiB,KAAK,CAAC,UAAU,QAAQ,IAAI,IAAI,KAAK,IAAI,SAAS,mBAAmB,CAAC,GAAG;AAC5F,WAAO,CAAC;AAAA,EACV;AAKA,QAAM,MAAS,UAAO;AACtB,QAAM,QAAa,UAAK,KAAK,kBAAkB,QAAQ,GAAG,QAAI,0BAAW,CAAC,QAAQ;AAClF,MAAI;AACF,IAAG,aAAa,YAAS,OAAO,IAAI,CAAC;AACrC,IAAG,cAAW,KAAK;AAAA,EACrB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,SAAO,CAAC,oBAAoB,GAAG,EAAE;AACnC;AAWA,SAAS,WAAW,MAAgB,mBAAwC,CAAC,GAAoB;AAC/F,QAAM,EAAE,eAAe,MAAM,IAAI;AAEjC,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,UAAe,UAAK,WAAW,MAAM,OAAO,QAAQ;AAE1D,QAAI,CAAI,cAAW,OAAO,GAAG;AAC3B,aAAO;AAAA,QACL,IAAI,MAAM,yBAAyB,OAAO,sCAAsC;AAAA,MAClF;AAAA,IACF;AAEA,UAAM,UAAU;AAIhB,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA,GAAG,eAAe;AAAA,MAClB;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL;AAEA,UAAM,kBAAc,4BAAM,SAAS,WAAW;AAE9C,QAAI,SAAS;AACb,QAAI,SAAS;AAKb,UAAM,gBAAgB,IAAI,oCAAc,MAAM;AAC9C,UAAM,gBAAgB,IAAI,oCAAc,MAAM;AAE9C,gBAAY,OAAO,GAAG,QAAQ,CAAC,SAAiB;AAC9C,YAAM,QAAQ,cAAc,MAAM,IAAI;AACtC,UAAI,MAAM,WAAW,EAAG;AACxB,UAAI,cAAc;AAIhB,gBAAQ,OAAO,MAAM,KAAK;AAAA,MAC5B,OAAO;AACL,kBAAU;AAAA,MACZ;AAAA,IACF,CAAC;AAED,gBAAY,OAAO,GAAG,QAAQ,CAAC,SAAiB;AAC9C,YAAM,QAAQ,cAAc,MAAM,IAAI;AACtC,UAAI,MAAM,WAAW,EAAG;AACxB,UAAI,cAAc;AAChB,gBAAQ,OAAO,MAAM,KAAK;AAAA,MAC5B;AAGA,gBAAU;AAAA,IACZ,CAAC;AAED,gBAAY,GAAG,SAAS,CAAC,SAAS;AAIhC,YAAM,aAAa,cAAc,IAAI;AACrC,YAAM,aAAa,cAAc,IAAI;AACrC,UAAI,WAAW,SAAS,GAAG;AACzB,YAAI,cAAc;AAChB,kBAAQ,OAAO,MAAM,UAAU;AAAA,QACjC,OAAO;AACL,oBAAU;AAAA,QACZ;AAAA,MACF;AACA,UAAI,WAAW,SAAS,GAAG;AACzB,YAAI,aAAc,SAAQ,OAAO,MAAM,UAAU;AACjD,kBAAU;AAAA,MACZ;AAEA,UAAI,SAAS,GAAG;AACd,gBAAQ,MAAM;AAAA,MAChB,OAAO;AACL,cAAM,cAAc,UAAU;AAC9B,cAAM,QAAQ,IAAI;AAAA,UAChB,+CAA+C,IAAI;AAAA;AAAA,EAAQ,WAAW;AAAA,QACxE;AAKA,QAAC,MAA2C,aAAa;AACzD,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,gBAAY,GAAG,SAAS,CAAC,QAAe;AACtC,UAAI,IAAI,QAAQ,SAAS,QAAQ,GAAG;AAClC;AAAA,UACE,IAAI;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,OAAO;AACL,eAAO,GAAG;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,aACP,YACA,SACkB;AAClB,QAAM,YAAY,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;AACtE,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO,IAAI,MAAM,2CAA2C;AAAA,EAC9D;AAEA,aAAW,SAAS,WAAW;AAC7B,QAAI,CAAI,cAAW,KAAK,GAAG;AACzB,aAAO,IAAI,MAAM,mCAAmC,KAAK,EAAE;AAAA,IAC7D;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,WAAW,GAAG,UAAU,OAAO,CAAC;AAC7C;AA2BA,eAAsB,WACpB,YACA,UAA0B,CAAC,GACZ;AACf,QAAM,cAAc,aAAa,YAAY,OAAO;AACpD,MAAI,uBAAuB,OAAO;AAChC,UAAM;AAAA,EACR;AACA,QAAM,WAAW,aAAa,EAAE,cAAc,KAAK,CAAC;AACtD;;;AEhNO,SAAS,mBAAmB,SAAwB;AACzD,UAAQ,OAAO,4BAA4B,yEAAyE;AACpH,UAAQ,OAAO,0BAA0B,kCAAkC;AAC3E,UAAQ,OAAO,wBAAwB,2MAA2M;AAClP,UAAQ,OAAO,eAAe,iCAAiC;AAC/D,UAAQ,OAAO,gCAAgC,kGAAkG;AACjJ,UAAQ,OAAO,cAAc,mHAAmH;AAChJ,UAAQ,OAAO,sBAAsB,iDAAiD;AACtF,UAAQ,OAAO,mCAAmC,2EAA2E;AAC7H,UAAQ,OAAO,qBAAqB,yPAAyP;AAC7R,UAAQ,OAAO,0BAA0B,sGAAsG;AAC/I,UAAQ,OAAO,2BAA2B,6DAA6D;AACvG,UAAQ,OAAO,qCAAqC,+FAA+F;AACnJ,UAAQ,OAAO,wBAAwB,yHAAyH;AAChK,UAAQ,OAAO,iCAAiC,2FAA2F;AAC3I,UAAQ,OAAO,iCAAiC,2FAA2F;AAC3I,UAAQ,OAAO,0BAA0B,wHAAwH;AACjK,UAAQ,OAAO,0BAA0B,qEAAqE;AAC9G,UAAQ,OAAO,uBAAuB,4EAA4E;AAClH,UAAQ,OAAO,mBAAmB,wDAAwD;AAC1F,UAAQ,OAAO,2BAA2B,4CAA4C;AACtF,UAAQ,OAAO,0BAA0B,gHAAgH;AACzJ,UAAQ,OAAO,oBAAoB,+SAA+S;AAClV,UAAQ,OAAO,yBAAyB,sGAAsG;AAC9I,UAAQ,OAAO,wBAAwB,+CAA+C;AACtF,UAAQ,OAAO,4BAA4B,gGAAiG;AAC5I,UAAQ,OAAO,+BAA+B,yOAAyO;AACvR,UAAQ,OAAO,qBAAqB,qEAAqE;AACzG,UAAQ,OAAO,eAAe,6DAA6D;AAC3F,UAAQ,OAAO,qBAAqB,iTAAiT;AACrV,UAAQ,OAAO,8BAA8B,iPAAiP;AAC9R,UAAQ,OAAO,yBAAyB,kRAAkR;AAC1T,UAAQ,OAAO,4BAA4B,gIAAgI;AAC3K,UAAQ,OAAO,mBAAmB,gKAAgK;AAClM,UAAQ,OAAO,yCAAyC,2MAA2M;AACnQ,UAAQ,OAAO,uBAAuB,qJAAqJ;AAC7L;;;AHtCA,SAAS,gBAAyB;AAChC,QAAM,UAAU,IAAI,yBAAQ;AAE5B,UACG,KAAK,oBAAoB,EACzB,MAAM,sBAAsB,EAC5B,YAAY,4CAA4C,EACxD,mBAAmB,wCAAwC,EAC3D,yBAAyB,KAAK,EAC9B,SAAS,cAAc,uCAAuC;AAGjE,qBAAmB,OAAO;AAE1B,UAAQ,gBAAgB;AAAA,IACtB,UAAU,CAAC,QAAQ;AACjB,cAAQ,MAAM,IAAI,QAAQ,CAAC;AAAA,IAC7B;AAAA,IACA,aAAa,CAAC,KAAK,UAAU;AAC3B,YAAM,GAAG;AAAA,IACX;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEA,eAAe,OAAwB;AACrC,QAAM,UAAU,cAAc;AAE9B,UAAQ,aAAa;AAErB,MAAI;AACF,YAAQ,MAAM,QAAQ,IAAI;AAAA,EAC5B,SAAS,KAAK;AACZ,QAAI,eAAe,iCAAgB;AACjC,UAAI,IAAI,SAAS,2BAA2B;AAC1C,eAAO;AAAA,MACT;AACA,aAAO,IAAI,YAAY;AAAA,IACzB;AAEA,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,YAAQ,MAAM,OAAO;AACrB,YAAQ,MAAM,wCAAwC;AACtD,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,QAAQ,KAAiB;AAC5C,QAAM,aAAa,QAAQ;AAC3B,QAAM,iBAAiB,oBAAoB,UAAU;AAErD,MAAI;AAGF,UAAM,WAAW,YAAY,cAAc;AAC3C,WAAO;AAAA,EACT,SAAS,KAAK;AAMZ,UAAM,aACJ,eAAe,SAAU,IAAyC,eAAe;AACnF,QAAI,CAAC,YAAY;AACf,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,cAAQ,MAAM,OAAO;AAAA,IACvB;AACA,WAAO;AAAA,EACT;AACF;AAEA,KAAK,EAAE,KAAK,CAAC,SAAS;AACpB,MAAI,SAAS,GAAG;AACd,YAAQ,KAAK,IAAI;AAAA,EACnB;AACF,CAAC;","names":["__filename"]}
package/dist/cli.js CHANGED
@@ -111,6 +111,15 @@ function buildConvertOptions(cliOptions) {
111
111
  if (cliOptions.sanitizeRules !== void 0 && cliOptions.sanitizeRules !== null) {
112
112
  convertOptions.sanitizeRules = cliOptions.sanitizeRules;
113
113
  }
114
+ if (cliOptions.includeLinks) {
115
+ convertOptions.includeLinks = true;
116
+ }
117
+ if (cliOptions.hybridAvailabilityTimeout) {
118
+ convertOptions.hybridAvailabilityTimeout = cliOptions.hybridAvailabilityTimeout;
119
+ }
120
+ if (cliOptions.hybridTriageLog) {
121
+ convertOptions.hybridTriageLog = true;
122
+ }
114
123
  return convertOptions;
115
124
  }
116
125
  function buildArgs(options) {
@@ -223,6 +232,15 @@ function buildArgs(options) {
223
232
  if (options.sanitizeRules !== void 0 && options.sanitizeRules !== null) {
224
233
  args.push("--sanitize-rules", options.sanitizeRules);
225
234
  }
235
+ if (options.includeLinks) {
236
+ args.push("--include-links");
237
+ }
238
+ if (options.hybridAvailabilityTimeout) {
239
+ args.push("--hybrid-availability-timeout", options.hybridAvailabilityTimeout);
240
+ }
241
+ if (options.hybridTriageLog) {
242
+ args.push("--hybrid-triage-log");
243
+ }
226
244
  return args;
227
245
  }
228
246
 
@@ -379,6 +397,9 @@ function registerCliOptions(program) {
379
397
  program.option("--image-resolution <value>", "Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0.");
380
398
  program.option("--space-ratio <value>", "Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17");
381
399
  program.option("--sanitize-rules <value>", "Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize");
400
+ program.option("--include-links", "Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text");
401
+ program.option("--hybrid-availability-timeout <value>", "Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000");
402
+ program.option("--hybrid-triage-log", "With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder");
382
403
  }
383
404
 
384
405
  // src/cli.ts
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/index.ts","../src/convert-options.generated.ts","../src/cli-options.generated.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command, CommanderError } from 'commander';\nimport { _runForCli } from './index.js';\nimport { CliOptions, buildConvertOptions } from './convert-options.generated.js';\nimport { registerCliOptions } from './cli-options.generated.js';\n\nfunction createProgram(): Command {\n const program = new Command();\n\n program\n .name('opendataloader-pdf')\n .usage('[options] <input...>')\n .description('Convert PDFs using the OpenDataLoader CLI.')\n .showHelpAfterError(\"Use '--help' to see available options.\")\n .showSuggestionAfterError(false)\n .argument('<input...>', 'Input files or directories to convert');\n\n // Register CLI options from auto-generated file\n registerCliOptions(program);\n\n program.configureOutput({\n writeErr: (str) => {\n console.error(str.trimEnd());\n },\n outputError: (str, write) => {\n write(str);\n },\n });\n\n return program;\n}\n\nasync function main(): Promise<number> {\n const program = createProgram();\n\n program.exitOverride();\n\n try {\n program.parse(process.argv);\n } catch (err) {\n if (err instanceof CommanderError) {\n if (err.code === 'commander.helpDisplayed') {\n return 0;\n }\n return err.exitCode ?? 1;\n }\n\n const message = err instanceof Error ? err.message : String(err);\n console.error(message);\n console.error(\"Use '--help' to see available options.\");\n return 1;\n }\n\n const cliOptions = program.opts<CliOptions>();\n const inputPaths = program.args;\n const convertOptions = buildConvertOptions(cliOptions);\n\n try {\n // _runForCli streams stdout/stderr to the parent process as they arrive;\n // we deliberately do not re-print anything here. (Issue #398.)\n await _runForCli(inputPaths, convertOptions);\n return 0;\n } catch (err) {\n // Subprocess-exit errors are already on the user's terminal via the live\n // stderr stream — re-printing would duplicate output and risk leaking\n // anything sensitive Java logged (e.g. a --password value echoed by an\n // underlying library). Wrapper-side failures (JAR not found, java not in\n // PATH, bad input path) still need to be surfaced.\n const isJavaExit =\n err instanceof Error && (err as Error & { isJavaExit?: boolean }).isJavaExit === true;\n if (!isJavaExit) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(message);\n }\n return 1;\n }\n}\n\nmain().then((code) => {\n if (code !== 0) {\n process.exit(code);\n }\n});\n","import { spawn } from 'child_process';\nimport { randomUUID } from 'crypto';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { StringDecoder } from 'string_decoder';\nimport { fileURLToPath } from 'url';\n\n// Re-export types and utilities from auto-generated file\nexport type { ConvertOptions } from './convert-options.generated.js';\nexport { buildArgs } from './convert-options.generated.js';\nimport type { ConvertOptions } from './convert-options.generated.js';\nimport { buildArgs } from './convert-options.generated.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst JAR_NAME = 'opendataloader-pdf-cli.jar';\n\n// Environment variables that the JVM reads options from.\nconst JAVA_OPTION_VARS = ['JAVA_TOOL_OPTIONS', 'JDK_JAVA_OPTIONS', '_JAVA_OPTIONS'];\n\n/**\n * Returns the option that gives Java the temporary folder of this runtime.\n * The JVM does not read TMPDIR, so without this option Java can use another\n * folder than Node. A command-line option wins over JAVA_TOOL_OPTIONS and\n * JDK_JAVA_OPTIONS, so add none if the user set java.io.tmpdir there.\n */\nfunction tempDirOptions(): string[] {\n if (JAVA_OPTION_VARS.some((name) => (process.env[name] ?? '').includes('-Djava.io.tmpdir='))) {\n return [];\n }\n // os.tmpdir() returns TMPDIR without a check: it can name a missing\n // folder, a folder without write access, or a file. Create and delete a\n // probe file, as Java does. If that fails, add nothing and let Java keep\n // its own default.\n const dir = os.tmpdir();\n const probe = path.join(dir, `opendataloader-${process.pid}-${randomUUID()}.probe`);\n try {\n fs.closeSync(fs.openSync(probe, 'wx'));\n fs.unlinkSync(probe);\n } catch {\n return [];\n }\n return [`-Djava.io.tmpdir=${dir}`];\n}\n\ninterface JarExecutionOptions {\n /**\n * When true, forwards Java's stdout and stderr chunks to the parent\n * process in real time as well as accumulating them. Used by the bundled\n * CLI so long-running conversions show progress as it happens.\n */\n streamOutput?: boolean;\n}\n\nfunction executeJar(args: string[], executionOptions: JarExecutionOptions = {}): Promise<string> {\n const { streamOutput = false } = executionOptions;\n\n return new Promise((resolve, reject) => {\n const jarPath = path.join(__dirname, '..', 'lib', JAR_NAME);\n\n if (!fs.existsSync(jarPath)) {\n return reject(\n new Error(`JAR file not found at ${jarPath}. Please run the build script first.`),\n );\n }\n\n const command = 'java';\n // Force headless AWT so macOS doesn't surface a Dock icon (and steal focus)\n // every time the JVM touches ImageIO/PDFBox rendering. Safe on all OSes —\n // the CLI never opens a UI window, only manipulates BufferedImages.\n const commandArgs = [\n '-Djava.awt.headless=true',\n '-Dapple.awt.UIElement=true',\n ...tempDirOptions(),\n '-jar',\n jarPath,\n ...args,\n ];\n\n const javaProcess = spawn(command, commandArgs);\n\n let stdout = '';\n let stderr = '';\n // StringDecoder buffers incomplete multi-byte UTF-8 sequences across\n // chunk boundaries — Buffer.toString() alone would emit replacement\n // characters when, e.g., a 3-byte Korean codepoint splits across two\n // 'data' events. One decoder per stream so they don't share state.\n const stdoutDecoder = new StringDecoder('utf8');\n const stderrDecoder = new StringDecoder('utf8');\n\n javaProcess.stdout.on('data', (data: Buffer) => {\n const chunk = stdoutDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n // Stream-only: don't also accumulate, or a multi-hour conversion\n // would buffer its entire (potentially gigabyte) stdout in memory\n // for no consumer.\n process.stdout.write(chunk);\n } else {\n stdout += chunk;\n }\n });\n\n javaProcess.stderr.on('data', (data: Buffer) => {\n const chunk = stderrDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n process.stderr.write(chunk);\n }\n // stderr is always accumulated (progress logs are small and we need\n // them for error messages on non-zero exit).\n stderr += chunk;\n });\n\n javaProcess.on('close', (code) => {\n // Flush any trailing bytes the decoder is still holding (always emit\n // them — if we drop them on error paths, error messages with non-ASCII\n // characters lose their tail).\n const stdoutTail = stdoutDecoder.end();\n const stderrTail = stderrDecoder.end();\n if (stdoutTail.length > 0) {\n if (streamOutput) {\n process.stdout.write(stdoutTail);\n } else {\n stdout += stdoutTail;\n }\n }\n if (stderrTail.length > 0) {\n if (streamOutput) process.stderr.write(stderrTail);\n stderr += stderrTail;\n }\n\n if (code === 0) {\n resolve(stdout);\n } else {\n const errorOutput = stderr || stdout;\n const error = new Error(\n `The opendataloader-pdf CLI exited with code ${code}.\\n\\n${errorOutput}`,\n );\n // Tag so the CLI can suppress re-printing this message — Java's\n // stderr was already streamed live to the parent in CLI mode, and\n // re-printing risks leaking anything sensitive Java logged\n // (e.g. a --password value echoed by an underlying library).\n (error as Error & { isJavaExit?: boolean }).isJavaExit = true;\n reject(error);\n }\n });\n\n javaProcess.on('error', (err: Error) => {\n if (err.message.includes('ENOENT')) {\n reject(\n new Error(\n \"'java' command not found. Please ensure Java is installed and in your system's PATH.\",\n ),\n );\n } else {\n reject(err);\n }\n });\n });\n}\n\nfunction buildJarArgs(\n inputPaths: string | string[],\n options: ConvertOptions,\n): string[] | Error {\n const inputList = Array.isArray(inputPaths) ? inputPaths : [inputPaths];\n if (inputList.length === 0) {\n return new Error('At least one input path must be provided.');\n }\n\n for (const input of inputList) {\n if (!fs.existsSync(input)) {\n return new Error(`Input file or folder not found: ${input}`);\n }\n }\n\n return [...inputList, ...buildArgs(options)];\n}\n\nexport function convert(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<string> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n return Promise.reject(argsOrError);\n }\n // Library API: never streams to the parent process. Returns the full stdout\n // string so callers can do `const out = await convert(...)` without surprise\n // side-effects on process.stdout / process.stderr.\n return executeJar(argsOrError, { streamOutput: false });\n}\n\n/**\n * Internal entry point used by the bundled CLI. Streams Java's stdout and\n * stderr to the parent process in real time (so long-running conversions like\n * hybrid mode show progress as it happens) and resolves without a stdout\n * payload — preventing the caller from re-printing what was already streamed.\n *\n * Not part of the public API: do not import this from application code. Use\n * {@link convert} instead.\n *\n * @internal\n */\nexport async function _runForCli(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<void> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n throw argsOrError;\n }\n await executeJar(argsOrError, { streamOutput: true });\n}\n\n/**\n * @deprecated Use `convert()` and `ConvertOptions` instead. This function will be removed in a future version.\n */\nexport interface RunOptions {\n outputFolder?: string;\n password?: string;\n replaceInvalidChars?: string;\n generateMarkdown?: boolean;\n generateHtml?: boolean;\n generateAnnotatedPdf?: boolean;\n keepLineBreaks?: boolean;\n contentSafetyOff?: string;\n htmlInMarkdown?: boolean;\n addImageToMarkdown?: boolean;\n noJson?: boolean;\n debug?: boolean;\n useStructTree?: boolean;\n}\n\n/**\n * @deprecated Use `convert()` instead. This function will be removed in a future version.\n */\nexport function run(inputPath: string, options: RunOptions = {}): Promise<string> {\n console.warn(\n 'Warning: run() is deprecated and will be removed in a future version. Use convert() instead.',\n );\n\n // Build format array based on legacy boolean options\n const formats: string[] = [];\n if (!options.noJson) {\n formats.push('json');\n }\n if (options.generateMarkdown) {\n if (options.addImageToMarkdown) {\n formats.push('markdown-with-images');\n } else if (options.htmlInMarkdown) {\n formats.push('markdown-with-html');\n } else {\n formats.push('markdown');\n }\n }\n if (options.generateHtml) {\n formats.push('html');\n }\n if (options.generateAnnotatedPdf) {\n formats.push('pdf');\n }\n\n return convert(inputPath, {\n outputDir: options.outputFolder,\n password: options.password,\n replaceInvalidChars: options.replaceInvalidChars,\n keepLineBreaks: options.keepLineBreaks,\n contentSafetyOff: options.contentSafetyOff,\n useStructTree: options.useStructTree,\n format: formats.length > 0 ? formats : undefined,\n quiet: !options.debug,\n });\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\n/**\n * Options for the convert function.\n */\nexport interface ConvertOptions {\n /** Directory where output files are written. Default: input file directory */\n outputDir?: string;\n /** Password for encrypted PDF files */\n password?: string;\n /** Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output. */\n format?: string | string[];\n /** Suppress console logging output */\n quiet?: boolean;\n /** Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background */\n contentSafetyOff?: string | string[];\n /** Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders */\n sanitize?: boolean;\n /** Preserve original line breaks in extracted text */\n keepLineBreaks?: boolean;\n /** Replacement character for invalid/unrecognized characters. Default: space */\n replaceInvalidChars?: string;\n /** Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called */\n useStructTree?: boolean;\n /** Table detection method. Values: default (border-based), cluster (border + cluster). Default: default */\n tableMethod?: string;\n /** Reading order algorithm. Values: off, xycut. Default: xycut */\n readingOrder?: string;\n /** Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none */\n markdownPageSeparator?: string;\n /** Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown. */\n markdownWithHtml?: boolean;\n /** Separator between pages in text output. Use %page-number% for page numbers. Default: none */\n textPageSeparator?: string;\n /** Separator between pages in HTML output. Use %page-number% for page numbers. Default: none */\n htmlPageSeparator?: string;\n /** Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external */\n imageOutput?: string;\n /** Output format for extracted images. Values: png, jpeg. Default: png */\n imageFormat?: string;\n /** Directory for extracted images (applies only with --image-output external) */\n imageDir?: string;\n /** Pages to extract (e.g., \"1,3,5-7\"). Default: all pages */\n pages?: string;\n /** Include page headers and footers in output */\n includeHeaderFooter?: boolean;\n /** Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental) */\n detectStrikethrough?: boolean;\n /** Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence) */\n hybrid?: string;\n /** Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend) */\n hybridMode?: string;\n /** Hybrid backend server URL (overrides default) */\n hybridUrl?: string;\n /** Hybrid backend request timeout in milliseconds (0 = use the backend's own default). Default: 0 */\n hybridTimeout?: string;\n /** Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50 */\n hybridChunkSize?: string;\n /** Opt in to Java fallback on hybrid backend error (default: disabled) */\n hybridFallback?: boolean;\n /** Write output to stdout instead of file (single format only) */\n toStdout?: boolean;\n /** Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode */\n threads?: string;\n /** Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0. */\n imageResolution?: string;\n /** Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17 */\n spaceRatio?: string;\n /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */\n sanitizeRules?: string;\n}\n\n/**\n * Options as parsed from CLI (all values are strings from commander).\n */\nexport interface CliOptions {\n outputDir?: string;\n password?: string;\n format?: string;\n quiet?: boolean;\n contentSafetyOff?: string;\n sanitize?: boolean;\n keepLineBreaks?: boolean;\n replaceInvalidChars?: string;\n useStructTree?: boolean;\n tableMethod?: string;\n readingOrder?: string;\n markdownPageSeparator?: string;\n markdownWithHtml?: boolean;\n textPageSeparator?: string;\n htmlPageSeparator?: string;\n imageOutput?: string;\n imageFormat?: string;\n imageDir?: string;\n pages?: string;\n includeHeaderFooter?: boolean;\n detectStrikethrough?: boolean;\n hybrid?: string;\n hybridMode?: string;\n hybridUrl?: string;\n hybridTimeout?: string;\n hybridChunkSize?: string;\n hybridFallback?: boolean;\n toStdout?: boolean;\n threads?: string;\n imageResolution?: string;\n spaceRatio?: string;\n sanitizeRules?: string;\n}\n\n/**\n * Convert CLI options to ConvertOptions.\n */\nexport function buildConvertOptions(cliOptions: CliOptions): ConvertOptions {\n const convertOptions: ConvertOptions = {};\n\n if (cliOptions.outputDir) {\n convertOptions.outputDir = cliOptions.outputDir;\n }\n if (cliOptions.password) {\n convertOptions.password = cliOptions.password;\n }\n if (cliOptions.format) {\n convertOptions.format = cliOptions.format;\n }\n if (cliOptions.quiet) {\n convertOptions.quiet = true;\n }\n if (cliOptions.contentSafetyOff) {\n convertOptions.contentSafetyOff = cliOptions.contentSafetyOff;\n }\n if (cliOptions.sanitize) {\n convertOptions.sanitize = true;\n }\n if (cliOptions.keepLineBreaks) {\n convertOptions.keepLineBreaks = true;\n }\n if (cliOptions.replaceInvalidChars) {\n convertOptions.replaceInvalidChars = cliOptions.replaceInvalidChars;\n }\n if (cliOptions.useStructTree) {\n convertOptions.useStructTree = true;\n }\n if (cliOptions.tableMethod) {\n convertOptions.tableMethod = cliOptions.tableMethod;\n }\n if (cliOptions.readingOrder) {\n convertOptions.readingOrder = cliOptions.readingOrder;\n }\n if (cliOptions.markdownPageSeparator) {\n convertOptions.markdownPageSeparator = cliOptions.markdownPageSeparator;\n }\n if (cliOptions.markdownWithHtml) {\n convertOptions.markdownWithHtml = true;\n }\n if (cliOptions.textPageSeparator) {\n convertOptions.textPageSeparator = cliOptions.textPageSeparator;\n }\n if (cliOptions.htmlPageSeparator) {\n convertOptions.htmlPageSeparator = cliOptions.htmlPageSeparator;\n }\n if (cliOptions.imageOutput) {\n convertOptions.imageOutput = cliOptions.imageOutput;\n }\n if (cliOptions.imageFormat) {\n convertOptions.imageFormat = cliOptions.imageFormat;\n }\n if (cliOptions.imageDir) {\n convertOptions.imageDir = cliOptions.imageDir;\n }\n if (cliOptions.pages) {\n convertOptions.pages = cliOptions.pages;\n }\n if (cliOptions.includeHeaderFooter) {\n convertOptions.includeHeaderFooter = true;\n }\n if (cliOptions.detectStrikethrough) {\n convertOptions.detectStrikethrough = true;\n }\n if (cliOptions.hybrid) {\n convertOptions.hybrid = cliOptions.hybrid;\n }\n if (cliOptions.hybridMode) {\n convertOptions.hybridMode = cliOptions.hybridMode;\n }\n if (cliOptions.hybridUrl) {\n convertOptions.hybridUrl = cliOptions.hybridUrl;\n }\n if (cliOptions.hybridTimeout) {\n convertOptions.hybridTimeout = cliOptions.hybridTimeout;\n }\n if (cliOptions.hybridChunkSize) {\n convertOptions.hybridChunkSize = cliOptions.hybridChunkSize;\n }\n if (cliOptions.hybridFallback) {\n convertOptions.hybridFallback = true;\n }\n if (cliOptions.toStdout) {\n convertOptions.toStdout = true;\n }\n if (cliOptions.threads) {\n convertOptions.threads = cliOptions.threads;\n }\n if (cliOptions.imageResolution) {\n convertOptions.imageResolution = cliOptions.imageResolution;\n }\n if (cliOptions.spaceRatio) {\n convertOptions.spaceRatio = cliOptions.spaceRatio;\n }\n if (cliOptions.sanitizeRules !== undefined && cliOptions.sanitizeRules !== null) {\n convertOptions.sanitizeRules = cliOptions.sanitizeRules;\n }\n\n return convertOptions;\n}\n\n/**\n * Build CLI arguments array from ConvertOptions.\n */\nexport function buildArgs(options: ConvertOptions): string[] {\n const args: string[] = [];\n\n if (options.outputDir) {\n args.push('--output-dir', options.outputDir);\n }\n if (options.password) {\n args.push('--password', options.password);\n }\n if (options.format) {\n if (Array.isArray(options.format)) {\n if (options.format.length > 0) {\n args.push('--format', options.format.join(','));\n }\n } else {\n args.push('--format', options.format);\n }\n }\n if (options.quiet) {\n args.push('--quiet');\n }\n if (options.contentSafetyOff) {\n if (Array.isArray(options.contentSafetyOff)) {\n if (options.contentSafetyOff.length > 0) {\n args.push('--content-safety-off', options.contentSafetyOff.join(','));\n }\n } else {\n args.push('--content-safety-off', options.contentSafetyOff);\n }\n }\n if (options.sanitize) {\n args.push('--sanitize');\n }\n if (options.keepLineBreaks) {\n args.push('--keep-line-breaks');\n }\n if (options.replaceInvalidChars) {\n args.push('--replace-invalid-chars', options.replaceInvalidChars);\n }\n if (options.useStructTree) {\n args.push('--use-struct-tree');\n }\n if (options.tableMethod) {\n args.push('--table-method', options.tableMethod);\n }\n if (options.readingOrder) {\n args.push('--reading-order', options.readingOrder);\n }\n if (options.markdownPageSeparator) {\n args.push('--markdown-page-separator', options.markdownPageSeparator);\n }\n if (options.markdownWithHtml) {\n args.push('--markdown-with-html');\n }\n if (options.textPageSeparator) {\n args.push('--text-page-separator', options.textPageSeparator);\n }\n if (options.htmlPageSeparator) {\n args.push('--html-page-separator', options.htmlPageSeparator);\n }\n if (options.imageOutput) {\n args.push('--image-output', options.imageOutput);\n }\n if (options.imageFormat) {\n args.push('--image-format', options.imageFormat);\n }\n if (options.imageDir) {\n args.push('--image-dir', options.imageDir);\n }\n if (options.pages) {\n args.push('--pages', options.pages);\n }\n if (options.includeHeaderFooter) {\n args.push('--include-header-footer');\n }\n if (options.detectStrikethrough) {\n args.push('--detect-strikethrough');\n }\n if (options.hybrid) {\n args.push('--hybrid', options.hybrid);\n }\n if (options.hybridMode) {\n args.push('--hybrid-mode', options.hybridMode);\n }\n if (options.hybridUrl) {\n args.push('--hybrid-url', options.hybridUrl);\n }\n if (options.hybridTimeout) {\n args.push('--hybrid-timeout', options.hybridTimeout);\n }\n if (options.hybridChunkSize) {\n args.push('--hybrid-chunk-size', options.hybridChunkSize);\n }\n if (options.hybridFallback) {\n args.push('--hybrid-fallback');\n }\n if (options.toStdout) {\n args.push('--to-stdout');\n }\n if (options.threads) {\n args.push('--threads', options.threads);\n }\n if (options.imageResolution) {\n args.push('--image-resolution', options.imageResolution);\n }\n if (options.spaceRatio) {\n args.push('--space-ratio', options.spaceRatio);\n }\n if (options.sanitizeRules !== undefined && options.sanitizeRules !== null) {\n args.push('--sanitize-rules', options.sanitizeRules);\n }\n\n return args;\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\nimport { Command } from 'commander';\n\n/**\n * Register all CLI options on the given Commander program.\n */\nexport function registerCliOptions(program: Command): void {\n program.option('-o, --output-dir <value>', 'Directory where output files are written. Default: input file directory');\n program.option('-p, --password <value>', 'Password for encrypted PDF files');\n program.option('-f, --format <value>', 'Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output.');\n program.option('-q, --quiet', 'Suppress console logging output');\n program.option('--content-safety-off <value>', 'Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background');\n program.option('--sanitize', 'Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders');\n program.option('--keep-line-breaks', 'Preserve original line breaks in extracted text');\n program.option('--replace-invalid-chars <value>', 'Replacement character for invalid/unrecognized characters. Default: space');\n program.option('--use-struct-tree', 'Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called');\n program.option('--table-method <value>', 'Table detection method. Values: default (border-based), cluster (border + cluster). Default: default');\n program.option('--reading-order <value>', 'Reading order algorithm. Values: off, xycut. Default: xycut');\n program.option('--markdown-page-separator <value>', 'Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none');\n program.option('--markdown-with-html', 'Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown.');\n program.option('--text-page-separator <value>', 'Separator between pages in text output. Use %page-number% for page numbers. Default: none');\n program.option('--html-page-separator <value>', 'Separator between pages in HTML output. Use %page-number% for page numbers. Default: none');\n program.option('--image-output <value>', 'Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external');\n program.option('--image-format <value>', 'Output format for extracted images. Values: png, jpeg. Default: png');\n program.option('--image-dir <value>', 'Directory for extracted images (applies only with --image-output external)');\n program.option('--pages <value>', 'Pages to extract (e.g., \"1,3,5-7\"). Default: all pages');\n program.option('--include-header-footer', 'Include page headers and footers in output');\n program.option('--detect-strikethrough', 'Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental)');\n program.option('--hybrid <value>', 'Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence)');\n program.option('--hybrid-mode <value>', 'Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend)');\n program.option('--hybrid-url <value>', 'Hybrid backend server URL (overrides default)');\n program.option('--hybrid-timeout <value>', 'Hybrid backend request timeout in milliseconds (0 = use the backend\\'s own default). Default: 0');\n program.option('--hybrid-chunk-size <value>', 'Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50');\n program.option('--hybrid-fallback', 'Opt in to Java fallback on hybrid backend error (default: disabled)');\n program.option('--to-stdout', 'Write output to stdout instead of file (single format only)');\n program.option('--threads <value>', 'Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode');\n program.option('--image-resolution <value>', 'Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0.');\n program.option('--space-ratio <value>', 'Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17');\n program.option('--sanitize-rules <value>', 'Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize');\n}\n"],"mappings":"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","names":["__filename","__dirname"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/index.ts","../src/convert-options.generated.ts","../src/cli-options.generated.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command, CommanderError } from 'commander';\nimport { _runForCli } from './index.js';\nimport { CliOptions, buildConvertOptions } from './convert-options.generated.js';\nimport { registerCliOptions } from './cli-options.generated.js';\n\nfunction createProgram(): Command {\n const program = new Command();\n\n program\n .name('opendataloader-pdf')\n .usage('[options] <input...>')\n .description('Convert PDFs using the OpenDataLoader CLI.')\n .showHelpAfterError(\"Use '--help' to see available options.\")\n .showSuggestionAfterError(false)\n .argument('<input...>', 'Input files or directories to convert');\n\n // Register CLI options from auto-generated file\n registerCliOptions(program);\n\n program.configureOutput({\n writeErr: (str) => {\n console.error(str.trimEnd());\n },\n outputError: (str, write) => {\n write(str);\n },\n });\n\n return program;\n}\n\nasync function main(): Promise<number> {\n const program = createProgram();\n\n program.exitOverride();\n\n try {\n program.parse(process.argv);\n } catch (err) {\n if (err instanceof CommanderError) {\n if (err.code === 'commander.helpDisplayed') {\n return 0;\n }\n return err.exitCode ?? 1;\n }\n\n const message = err instanceof Error ? err.message : String(err);\n console.error(message);\n console.error(\"Use '--help' to see available options.\");\n return 1;\n }\n\n const cliOptions = program.opts<CliOptions>();\n const inputPaths = program.args;\n const convertOptions = buildConvertOptions(cliOptions);\n\n try {\n // _runForCli streams stdout/stderr to the parent process as they arrive;\n // we deliberately do not re-print anything here. (Issue #398.)\n await _runForCli(inputPaths, convertOptions);\n return 0;\n } catch (err) {\n // Subprocess-exit errors are already on the user's terminal via the live\n // stderr stream — re-printing would duplicate output and risk leaking\n // anything sensitive Java logged (e.g. a --password value echoed by an\n // underlying library). Wrapper-side failures (JAR not found, java not in\n // PATH, bad input path) still need to be surfaced.\n const isJavaExit =\n err instanceof Error && (err as Error & { isJavaExit?: boolean }).isJavaExit === true;\n if (!isJavaExit) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(message);\n }\n return 1;\n }\n}\n\nmain().then((code) => {\n if (code !== 0) {\n process.exit(code);\n }\n});\n","import { spawn } from 'child_process';\nimport { randomUUID } from 'crypto';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { StringDecoder } from 'string_decoder';\nimport { fileURLToPath } from 'url';\n\n// Re-export types and utilities from auto-generated file\nexport type { ConvertOptions } from './convert-options.generated.js';\nexport { buildArgs } from './convert-options.generated.js';\nimport type { ConvertOptions } from './convert-options.generated.js';\nimport { buildArgs } from './convert-options.generated.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst JAR_NAME = 'opendataloader-pdf-cli.jar';\n\n// Environment variables that the JVM reads options from.\nconst JAVA_OPTION_VARS = ['JAVA_TOOL_OPTIONS', 'JDK_JAVA_OPTIONS', '_JAVA_OPTIONS'];\n\n/**\n * Returns the option that gives Java the temporary folder of this runtime.\n * The JVM does not read TMPDIR, so without this option Java can use another\n * folder than Node. A command-line option wins over JAVA_TOOL_OPTIONS and\n * JDK_JAVA_OPTIONS, so add none if the user set java.io.tmpdir there.\n */\nfunction tempDirOptions(): string[] {\n if (JAVA_OPTION_VARS.some((name) => (process.env[name] ?? '').includes('-Djava.io.tmpdir='))) {\n return [];\n }\n // os.tmpdir() returns TMPDIR without a check: it can name a missing\n // folder, a folder without write access, or a file. Create and delete a\n // probe file, as Java does. If that fails, add nothing and let Java keep\n // its own default.\n const dir = os.tmpdir();\n const probe = path.join(dir, `opendataloader-${process.pid}-${randomUUID()}.probe`);\n try {\n fs.closeSync(fs.openSync(probe, 'wx'));\n fs.unlinkSync(probe);\n } catch {\n return [];\n }\n return [`-Djava.io.tmpdir=${dir}`];\n}\n\ninterface JarExecutionOptions {\n /**\n * When true, forwards Java's stdout and stderr chunks to the parent\n * process in real time as well as accumulating them. Used by the bundled\n * CLI so long-running conversions show progress as it happens.\n */\n streamOutput?: boolean;\n}\n\nfunction executeJar(args: string[], executionOptions: JarExecutionOptions = {}): Promise<string> {\n const { streamOutput = false } = executionOptions;\n\n return new Promise((resolve, reject) => {\n const jarPath = path.join(__dirname, '..', 'lib', JAR_NAME);\n\n if (!fs.existsSync(jarPath)) {\n return reject(\n new Error(`JAR file not found at ${jarPath}. Please run the build script first.`),\n );\n }\n\n const command = 'java';\n // Force headless AWT so macOS doesn't surface a Dock icon (and steal focus)\n // every time the JVM touches ImageIO/PDFBox rendering. Safe on all OSes —\n // the CLI never opens a UI window, only manipulates BufferedImages.\n const commandArgs = [\n '-Djava.awt.headless=true',\n '-Dapple.awt.UIElement=true',\n ...tempDirOptions(),\n '-jar',\n jarPath,\n ...args,\n ];\n\n const javaProcess = spawn(command, commandArgs);\n\n let stdout = '';\n let stderr = '';\n // StringDecoder buffers incomplete multi-byte UTF-8 sequences across\n // chunk boundaries — Buffer.toString() alone would emit replacement\n // characters when, e.g., a 3-byte Korean codepoint splits across two\n // 'data' events. One decoder per stream so they don't share state.\n const stdoutDecoder = new StringDecoder('utf8');\n const stderrDecoder = new StringDecoder('utf8');\n\n javaProcess.stdout.on('data', (data: Buffer) => {\n const chunk = stdoutDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n // Stream-only: don't also accumulate, or a multi-hour conversion\n // would buffer its entire (potentially gigabyte) stdout in memory\n // for no consumer.\n process.stdout.write(chunk);\n } else {\n stdout += chunk;\n }\n });\n\n javaProcess.stderr.on('data', (data: Buffer) => {\n const chunk = stderrDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n process.stderr.write(chunk);\n }\n // stderr is always accumulated (progress logs are small and we need\n // them for error messages on non-zero exit).\n stderr += chunk;\n });\n\n javaProcess.on('close', (code) => {\n // Flush any trailing bytes the decoder is still holding (always emit\n // them — if we drop them on error paths, error messages with non-ASCII\n // characters lose their tail).\n const stdoutTail = stdoutDecoder.end();\n const stderrTail = stderrDecoder.end();\n if (stdoutTail.length > 0) {\n if (streamOutput) {\n process.stdout.write(stdoutTail);\n } else {\n stdout += stdoutTail;\n }\n }\n if (stderrTail.length > 0) {\n if (streamOutput) process.stderr.write(stderrTail);\n stderr += stderrTail;\n }\n\n if (code === 0) {\n resolve(stdout);\n } else {\n const errorOutput = stderr || stdout;\n const error = new Error(\n `The opendataloader-pdf CLI exited with code ${code}.\\n\\n${errorOutput}`,\n );\n // Tag so the CLI can suppress re-printing this message — Java's\n // stderr was already streamed live to the parent in CLI mode, and\n // re-printing risks leaking anything sensitive Java logged\n // (e.g. a --password value echoed by an underlying library).\n (error as Error & { isJavaExit?: boolean }).isJavaExit = true;\n reject(error);\n }\n });\n\n javaProcess.on('error', (err: Error) => {\n if (err.message.includes('ENOENT')) {\n reject(\n new Error(\n \"'java' command not found. Please ensure Java is installed and in your system's PATH.\",\n ),\n );\n } else {\n reject(err);\n }\n });\n });\n}\n\nfunction buildJarArgs(\n inputPaths: string | string[],\n options: ConvertOptions,\n): string[] | Error {\n const inputList = Array.isArray(inputPaths) ? inputPaths : [inputPaths];\n if (inputList.length === 0) {\n return new Error('At least one input path must be provided.');\n }\n\n for (const input of inputList) {\n if (!fs.existsSync(input)) {\n return new Error(`Input file or folder not found: ${input}`);\n }\n }\n\n return [...inputList, ...buildArgs(options)];\n}\n\nexport function convert(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<string> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n return Promise.reject(argsOrError);\n }\n // Library API: never streams to the parent process. Returns the full stdout\n // string so callers can do `const out = await convert(...)` without surprise\n // side-effects on process.stdout / process.stderr.\n return executeJar(argsOrError, { streamOutput: false });\n}\n\n/**\n * Internal entry point used by the bundled CLI. Streams Java's stdout and\n * stderr to the parent process in real time (so long-running conversions like\n * hybrid mode show progress as it happens) and resolves without a stdout\n * payload — preventing the caller from re-printing what was already streamed.\n *\n * Not part of the public API: do not import this from application code. Use\n * {@link convert} instead.\n *\n * @internal\n */\nexport async function _runForCli(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<void> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n throw argsOrError;\n }\n await executeJar(argsOrError, { streamOutput: true });\n}\n\n/**\n * @deprecated Use `convert()` and `ConvertOptions` instead. This function will be removed in a future version.\n */\nexport interface RunOptions {\n outputFolder?: string;\n password?: string;\n replaceInvalidChars?: string;\n generateMarkdown?: boolean;\n generateHtml?: boolean;\n generateAnnotatedPdf?: boolean;\n keepLineBreaks?: boolean;\n contentSafetyOff?: string;\n htmlInMarkdown?: boolean;\n addImageToMarkdown?: boolean;\n noJson?: boolean;\n debug?: boolean;\n useStructTree?: boolean;\n}\n\n/**\n * @deprecated Use `convert()` instead. This function will be removed in a future version.\n */\nexport function run(inputPath: string, options: RunOptions = {}): Promise<string> {\n console.warn(\n 'Warning: run() is deprecated and will be removed in a future version. Use convert() instead.',\n );\n\n // Build format array based on legacy boolean options\n const formats: string[] = [];\n if (!options.noJson) {\n formats.push('json');\n }\n if (options.generateMarkdown) {\n if (options.addImageToMarkdown) {\n formats.push('markdown-with-images');\n } else if (options.htmlInMarkdown) {\n formats.push('markdown-with-html');\n } else {\n formats.push('markdown');\n }\n }\n if (options.generateHtml) {\n formats.push('html');\n }\n if (options.generateAnnotatedPdf) {\n formats.push('pdf');\n }\n\n return convert(inputPath, {\n outputDir: options.outputFolder,\n password: options.password,\n replaceInvalidChars: options.replaceInvalidChars,\n keepLineBreaks: options.keepLineBreaks,\n contentSafetyOff: options.contentSafetyOff,\n useStructTree: options.useStructTree,\n format: formats.length > 0 ? formats : undefined,\n quiet: !options.debug,\n });\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\n/**\n * Options for the convert function.\n */\nexport interface ConvertOptions {\n /** Directory where output files are written. Default: input file directory */\n outputDir?: string;\n /** Password for encrypted PDF files */\n password?: string;\n /** Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output. */\n format?: string | string[];\n /** Suppress console logging output */\n quiet?: boolean;\n /** Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background */\n contentSafetyOff?: string | string[];\n /** Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders */\n sanitize?: boolean;\n /** Preserve original line breaks in extracted text */\n keepLineBreaks?: boolean;\n /** Replacement character for invalid/unrecognized characters. Default: space */\n replaceInvalidChars?: string;\n /** Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called */\n useStructTree?: boolean;\n /** Table detection method. Values: default (border-based), cluster (border + cluster). Default: default */\n tableMethod?: string;\n /** Reading order algorithm. Values: off, xycut. Default: xycut */\n readingOrder?: string;\n /** Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none */\n markdownPageSeparator?: string;\n /** Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown. */\n markdownWithHtml?: boolean;\n /** Separator between pages in text output. Use %page-number% for page numbers. Default: none */\n textPageSeparator?: string;\n /** Separator between pages in HTML output. Use %page-number% for page numbers. Default: none */\n htmlPageSeparator?: string;\n /** Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external */\n imageOutput?: string;\n /** Output format for extracted images. Values: png, jpeg. Default: png */\n imageFormat?: string;\n /** Directory for extracted images (applies only with --image-output external) */\n imageDir?: string;\n /** Pages to extract (e.g., \"1,3,5-7\"). Default: all pages */\n pages?: string;\n /** Include page headers and footers in output */\n includeHeaderFooter?: boolean;\n /** Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental) */\n detectStrikethrough?: boolean;\n /** Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence) */\n hybrid?: string;\n /** Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend) */\n hybridMode?: string;\n /** Hybrid backend server URL (overrides default) */\n hybridUrl?: string;\n /** Hybrid backend request timeout in milliseconds (0 = use the backend's own default). Default: 0 */\n hybridTimeout?: string;\n /** Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50 */\n hybridChunkSize?: string;\n /** Opt in to Java fallback on hybrid backend error (default: disabled) */\n hybridFallback?: boolean;\n /** Write output to stdout instead of file (single format only) */\n toStdout?: boolean;\n /** Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode */\n threads?: string;\n /** Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0. */\n imageResolution?: string;\n /** Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17 */\n spaceRatio?: string;\n /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */\n sanitizeRules?: string;\n /** Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text */\n includeLinks?: boolean;\n /** Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000 */\n hybridAvailabilityTimeout?: string;\n /** With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder */\n hybridTriageLog?: boolean;\n}\n\n/**\n * Options as parsed from CLI (all values are strings from commander).\n */\nexport interface CliOptions {\n outputDir?: string;\n password?: string;\n format?: string;\n quiet?: boolean;\n contentSafetyOff?: string;\n sanitize?: boolean;\n keepLineBreaks?: boolean;\n replaceInvalidChars?: string;\n useStructTree?: boolean;\n tableMethod?: string;\n readingOrder?: string;\n markdownPageSeparator?: string;\n markdownWithHtml?: boolean;\n textPageSeparator?: string;\n htmlPageSeparator?: string;\n imageOutput?: string;\n imageFormat?: string;\n imageDir?: string;\n pages?: string;\n includeHeaderFooter?: boolean;\n detectStrikethrough?: boolean;\n hybrid?: string;\n hybridMode?: string;\n hybridUrl?: string;\n hybridTimeout?: string;\n hybridChunkSize?: string;\n hybridFallback?: boolean;\n toStdout?: boolean;\n threads?: string;\n imageResolution?: string;\n spaceRatio?: string;\n sanitizeRules?: string;\n includeLinks?: boolean;\n hybridAvailabilityTimeout?: string;\n hybridTriageLog?: boolean;\n}\n\n/**\n * Convert CLI options to ConvertOptions.\n */\nexport function buildConvertOptions(cliOptions: CliOptions): ConvertOptions {\n const convertOptions: ConvertOptions = {};\n\n if (cliOptions.outputDir) {\n convertOptions.outputDir = cliOptions.outputDir;\n }\n if (cliOptions.password) {\n convertOptions.password = cliOptions.password;\n }\n if (cliOptions.format) {\n convertOptions.format = cliOptions.format;\n }\n if (cliOptions.quiet) {\n convertOptions.quiet = true;\n }\n if (cliOptions.contentSafetyOff) {\n convertOptions.contentSafetyOff = cliOptions.contentSafetyOff;\n }\n if (cliOptions.sanitize) {\n convertOptions.sanitize = true;\n }\n if (cliOptions.keepLineBreaks) {\n convertOptions.keepLineBreaks = true;\n }\n if (cliOptions.replaceInvalidChars) {\n convertOptions.replaceInvalidChars = cliOptions.replaceInvalidChars;\n }\n if (cliOptions.useStructTree) {\n convertOptions.useStructTree = true;\n }\n if (cliOptions.tableMethod) {\n convertOptions.tableMethod = cliOptions.tableMethod;\n }\n if (cliOptions.readingOrder) {\n convertOptions.readingOrder = cliOptions.readingOrder;\n }\n if (cliOptions.markdownPageSeparator) {\n convertOptions.markdownPageSeparator = cliOptions.markdownPageSeparator;\n }\n if (cliOptions.markdownWithHtml) {\n convertOptions.markdownWithHtml = true;\n }\n if (cliOptions.textPageSeparator) {\n convertOptions.textPageSeparator = cliOptions.textPageSeparator;\n }\n if (cliOptions.htmlPageSeparator) {\n convertOptions.htmlPageSeparator = cliOptions.htmlPageSeparator;\n }\n if (cliOptions.imageOutput) {\n convertOptions.imageOutput = cliOptions.imageOutput;\n }\n if (cliOptions.imageFormat) {\n convertOptions.imageFormat = cliOptions.imageFormat;\n }\n if (cliOptions.imageDir) {\n convertOptions.imageDir = cliOptions.imageDir;\n }\n if (cliOptions.pages) {\n convertOptions.pages = cliOptions.pages;\n }\n if (cliOptions.includeHeaderFooter) {\n convertOptions.includeHeaderFooter = true;\n }\n if (cliOptions.detectStrikethrough) {\n convertOptions.detectStrikethrough = true;\n }\n if (cliOptions.hybrid) {\n convertOptions.hybrid = cliOptions.hybrid;\n }\n if (cliOptions.hybridMode) {\n convertOptions.hybridMode = cliOptions.hybridMode;\n }\n if (cliOptions.hybridUrl) {\n convertOptions.hybridUrl = cliOptions.hybridUrl;\n }\n if (cliOptions.hybridTimeout) {\n convertOptions.hybridTimeout = cliOptions.hybridTimeout;\n }\n if (cliOptions.hybridChunkSize) {\n convertOptions.hybridChunkSize = cliOptions.hybridChunkSize;\n }\n if (cliOptions.hybridFallback) {\n convertOptions.hybridFallback = true;\n }\n if (cliOptions.toStdout) {\n convertOptions.toStdout = true;\n }\n if (cliOptions.threads) {\n convertOptions.threads = cliOptions.threads;\n }\n if (cliOptions.imageResolution) {\n convertOptions.imageResolution = cliOptions.imageResolution;\n }\n if (cliOptions.spaceRatio) {\n convertOptions.spaceRatio = cliOptions.spaceRatio;\n }\n if (cliOptions.sanitizeRules !== undefined && cliOptions.sanitizeRules !== null) {\n convertOptions.sanitizeRules = cliOptions.sanitizeRules;\n }\n if (cliOptions.includeLinks) {\n convertOptions.includeLinks = true;\n }\n if (cliOptions.hybridAvailabilityTimeout) {\n convertOptions.hybridAvailabilityTimeout = cliOptions.hybridAvailabilityTimeout;\n }\n if (cliOptions.hybridTriageLog) {\n convertOptions.hybridTriageLog = true;\n }\n\n return convertOptions;\n}\n\n/**\n * Build CLI arguments array from ConvertOptions.\n */\nexport function buildArgs(options: ConvertOptions): string[] {\n const args: string[] = [];\n\n if (options.outputDir) {\n args.push('--output-dir', options.outputDir);\n }\n if (options.password) {\n args.push('--password', options.password);\n }\n if (options.format) {\n if (Array.isArray(options.format)) {\n if (options.format.length > 0) {\n args.push('--format', options.format.join(','));\n }\n } else {\n args.push('--format', options.format);\n }\n }\n if (options.quiet) {\n args.push('--quiet');\n }\n if (options.contentSafetyOff) {\n if (Array.isArray(options.contentSafetyOff)) {\n if (options.contentSafetyOff.length > 0) {\n args.push('--content-safety-off', options.contentSafetyOff.join(','));\n }\n } else {\n args.push('--content-safety-off', options.contentSafetyOff);\n }\n }\n if (options.sanitize) {\n args.push('--sanitize');\n }\n if (options.keepLineBreaks) {\n args.push('--keep-line-breaks');\n }\n if (options.replaceInvalidChars) {\n args.push('--replace-invalid-chars', options.replaceInvalidChars);\n }\n if (options.useStructTree) {\n args.push('--use-struct-tree');\n }\n if (options.tableMethod) {\n args.push('--table-method', options.tableMethod);\n }\n if (options.readingOrder) {\n args.push('--reading-order', options.readingOrder);\n }\n if (options.markdownPageSeparator) {\n args.push('--markdown-page-separator', options.markdownPageSeparator);\n }\n if (options.markdownWithHtml) {\n args.push('--markdown-with-html');\n }\n if (options.textPageSeparator) {\n args.push('--text-page-separator', options.textPageSeparator);\n }\n if (options.htmlPageSeparator) {\n args.push('--html-page-separator', options.htmlPageSeparator);\n }\n if (options.imageOutput) {\n args.push('--image-output', options.imageOutput);\n }\n if (options.imageFormat) {\n args.push('--image-format', options.imageFormat);\n }\n if (options.imageDir) {\n args.push('--image-dir', options.imageDir);\n }\n if (options.pages) {\n args.push('--pages', options.pages);\n }\n if (options.includeHeaderFooter) {\n args.push('--include-header-footer');\n }\n if (options.detectStrikethrough) {\n args.push('--detect-strikethrough');\n }\n if (options.hybrid) {\n args.push('--hybrid', options.hybrid);\n }\n if (options.hybridMode) {\n args.push('--hybrid-mode', options.hybridMode);\n }\n if (options.hybridUrl) {\n args.push('--hybrid-url', options.hybridUrl);\n }\n if (options.hybridTimeout) {\n args.push('--hybrid-timeout', options.hybridTimeout);\n }\n if (options.hybridChunkSize) {\n args.push('--hybrid-chunk-size', options.hybridChunkSize);\n }\n if (options.hybridFallback) {\n args.push('--hybrid-fallback');\n }\n if (options.toStdout) {\n args.push('--to-stdout');\n }\n if (options.threads) {\n args.push('--threads', options.threads);\n }\n if (options.imageResolution) {\n args.push('--image-resolution', options.imageResolution);\n }\n if (options.spaceRatio) {\n args.push('--space-ratio', options.spaceRatio);\n }\n if (options.sanitizeRules !== undefined && options.sanitizeRules !== null) {\n args.push('--sanitize-rules', options.sanitizeRules);\n }\n if (options.includeLinks) {\n args.push('--include-links');\n }\n if (options.hybridAvailabilityTimeout) {\n args.push('--hybrid-availability-timeout', options.hybridAvailabilityTimeout);\n }\n if (options.hybridTriageLog) {\n args.push('--hybrid-triage-log');\n }\n\n return args;\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\nimport { Command } from 'commander';\n\n/**\n * Register all CLI options on the given Commander program.\n */\nexport function registerCliOptions(program: Command): void {\n program.option('-o, --output-dir <value>', 'Directory where output files are written. Default: input file directory');\n program.option('-p, --password <value>', 'Password for encrypted PDF files');\n program.option('-f, --format <value>', 'Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output.');\n program.option('-q, --quiet', 'Suppress console logging output');\n program.option('--content-safety-off <value>', 'Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background');\n program.option('--sanitize', 'Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders');\n program.option('--keep-line-breaks', 'Preserve original line breaks in extracted text');\n program.option('--replace-invalid-chars <value>', 'Replacement character for invalid/unrecognized characters. Default: space');\n program.option('--use-struct-tree', 'Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called');\n program.option('--table-method <value>', 'Table detection method. Values: default (border-based), cluster (border + cluster). Default: default');\n program.option('--reading-order <value>', 'Reading order algorithm. Values: off, xycut. Default: xycut');\n program.option('--markdown-page-separator <value>', 'Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none');\n program.option('--markdown-with-html', 'Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown.');\n program.option('--text-page-separator <value>', 'Separator between pages in text output. Use %page-number% for page numbers. Default: none');\n program.option('--html-page-separator <value>', 'Separator between pages in HTML output. Use %page-number% for page numbers. Default: none');\n program.option('--image-output <value>', 'Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external');\n program.option('--image-format <value>', 'Output format for extracted images. Values: png, jpeg. Default: png');\n program.option('--image-dir <value>', 'Directory for extracted images (applies only with --image-output external)');\n program.option('--pages <value>', 'Pages to extract (e.g., \"1,3,5-7\"). Default: all pages');\n program.option('--include-header-footer', 'Include page headers and footers in output');\n program.option('--detect-strikethrough', 'Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental)');\n program.option('--hybrid <value>', 'Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence)');\n program.option('--hybrid-mode <value>', 'Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend)');\n program.option('--hybrid-url <value>', 'Hybrid backend server URL (overrides default)');\n program.option('--hybrid-timeout <value>', 'Hybrid backend request timeout in milliseconds (0 = use the backend\\'s own default). Default: 0');\n program.option('--hybrid-chunk-size <value>', 'Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50');\n program.option('--hybrid-fallback', 'Opt in to Java fallback on hybrid backend error (default: disabled)');\n program.option('--to-stdout', 'Write output to stdout instead of file (single format only)');\n program.option('--threads <value>', 'Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode');\n program.option('--image-resolution <value>', 'Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0.');\n program.option('--space-ratio <value>', 'Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17');\n program.option('--sanitize-rules <value>', 'Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize');\n program.option('--include-links', 'Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text');\n program.option('--hybrid-availability-timeout <value>', 'Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000');\n program.option('--hybrid-triage-log', 'With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder');\n}\n"],"mappings":"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","names":["__filename","__dirname"]}
package/dist/index.cjs CHANGED
@@ -37,7 +37,7 @@ __export(index_exports, {
37
37
  });
38
38
  module.exports = __toCommonJS(index_exports);
39
39
 
40
- // node_modules/.pnpm/tsup@8.5.1_postcss@8.5.28_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js
40
+ // node_modules/.pnpm/tsup@8.5.1_postcss@8.5.31_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js
41
41
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
42
42
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
43
43
 
@@ -161,6 +161,15 @@ function buildArgs(options) {
161
161
  if (options.sanitizeRules !== void 0 && options.sanitizeRules !== null) {
162
162
  args.push("--sanitize-rules", options.sanitizeRules);
163
163
  }
164
+ if (options.includeLinks) {
165
+ args.push("--include-links");
166
+ }
167
+ if (options.hybridAvailabilityTimeout) {
168
+ args.push("--hybrid-availability-timeout", options.hybridAvailabilityTimeout);
169
+ }
170
+ if (options.hybridTriageLog) {
171
+ args.push("--hybrid-triage-log");
172
+ }
164
173
  return args;
165
174
  }
166
175
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.28_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js","../src/convert-options.generated.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport { randomUUID } from 'crypto';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { StringDecoder } from 'string_decoder';\nimport { fileURLToPath } from 'url';\n\n// Re-export types and utilities from auto-generated file\nexport type { ConvertOptions } from './convert-options.generated.js';\nexport { buildArgs } from './convert-options.generated.js';\nimport type { ConvertOptions } from './convert-options.generated.js';\nimport { buildArgs } from './convert-options.generated.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst JAR_NAME = 'opendataloader-pdf-cli.jar';\n\n// Environment variables that the JVM reads options from.\nconst JAVA_OPTION_VARS = ['JAVA_TOOL_OPTIONS', 'JDK_JAVA_OPTIONS', '_JAVA_OPTIONS'];\n\n/**\n * Returns the option that gives Java the temporary folder of this runtime.\n * The JVM does not read TMPDIR, so without this option Java can use another\n * folder than Node. A command-line option wins over JAVA_TOOL_OPTIONS and\n * JDK_JAVA_OPTIONS, so add none if the user set java.io.tmpdir there.\n */\nfunction tempDirOptions(): string[] {\n if (JAVA_OPTION_VARS.some((name) => (process.env[name] ?? '').includes('-Djava.io.tmpdir='))) {\n return [];\n }\n // os.tmpdir() returns TMPDIR without a check: it can name a missing\n // folder, a folder without write access, or a file. Create and delete a\n // probe file, as Java does. If that fails, add nothing and let Java keep\n // its own default.\n const dir = os.tmpdir();\n const probe = path.join(dir, `opendataloader-${process.pid}-${randomUUID()}.probe`);\n try {\n fs.closeSync(fs.openSync(probe, 'wx'));\n fs.unlinkSync(probe);\n } catch {\n return [];\n }\n return [`-Djava.io.tmpdir=${dir}`];\n}\n\ninterface JarExecutionOptions {\n /**\n * When true, forwards Java's stdout and stderr chunks to the parent\n * process in real time as well as accumulating them. Used by the bundled\n * CLI so long-running conversions show progress as it happens.\n */\n streamOutput?: boolean;\n}\n\nfunction executeJar(args: string[], executionOptions: JarExecutionOptions = {}): Promise<string> {\n const { streamOutput = false } = executionOptions;\n\n return new Promise((resolve, reject) => {\n const jarPath = path.join(__dirname, '..', 'lib', JAR_NAME);\n\n if (!fs.existsSync(jarPath)) {\n return reject(\n new Error(`JAR file not found at ${jarPath}. Please run the build script first.`),\n );\n }\n\n const command = 'java';\n // Force headless AWT so macOS doesn't surface a Dock icon (and steal focus)\n // every time the JVM touches ImageIO/PDFBox rendering. Safe on all OSes —\n // the CLI never opens a UI window, only manipulates BufferedImages.\n const commandArgs = [\n '-Djava.awt.headless=true',\n '-Dapple.awt.UIElement=true',\n ...tempDirOptions(),\n '-jar',\n jarPath,\n ...args,\n ];\n\n const javaProcess = spawn(command, commandArgs);\n\n let stdout = '';\n let stderr = '';\n // StringDecoder buffers incomplete multi-byte UTF-8 sequences across\n // chunk boundaries — Buffer.toString() alone would emit replacement\n // characters when, e.g., a 3-byte Korean codepoint splits across two\n // 'data' events. One decoder per stream so they don't share state.\n const stdoutDecoder = new StringDecoder('utf8');\n const stderrDecoder = new StringDecoder('utf8');\n\n javaProcess.stdout.on('data', (data: Buffer) => {\n const chunk = stdoutDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n // Stream-only: don't also accumulate, or a multi-hour conversion\n // would buffer its entire (potentially gigabyte) stdout in memory\n // for no consumer.\n process.stdout.write(chunk);\n } else {\n stdout += chunk;\n }\n });\n\n javaProcess.stderr.on('data', (data: Buffer) => {\n const chunk = stderrDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n process.stderr.write(chunk);\n }\n // stderr is always accumulated (progress logs are small and we need\n // them for error messages on non-zero exit).\n stderr += chunk;\n });\n\n javaProcess.on('close', (code) => {\n // Flush any trailing bytes the decoder is still holding (always emit\n // them — if we drop them on error paths, error messages with non-ASCII\n // characters lose their tail).\n const stdoutTail = stdoutDecoder.end();\n const stderrTail = stderrDecoder.end();\n if (stdoutTail.length > 0) {\n if (streamOutput) {\n process.stdout.write(stdoutTail);\n } else {\n stdout += stdoutTail;\n }\n }\n if (stderrTail.length > 0) {\n if (streamOutput) process.stderr.write(stderrTail);\n stderr += stderrTail;\n }\n\n if (code === 0) {\n resolve(stdout);\n } else {\n const errorOutput = stderr || stdout;\n const error = new Error(\n `The opendataloader-pdf CLI exited with code ${code}.\\n\\n${errorOutput}`,\n );\n // Tag so the CLI can suppress re-printing this message — Java's\n // stderr was already streamed live to the parent in CLI mode, and\n // re-printing risks leaking anything sensitive Java logged\n // (e.g. a --password value echoed by an underlying library).\n (error as Error & { isJavaExit?: boolean }).isJavaExit = true;\n reject(error);\n }\n });\n\n javaProcess.on('error', (err: Error) => {\n if (err.message.includes('ENOENT')) {\n reject(\n new Error(\n \"'java' command not found. Please ensure Java is installed and in your system's PATH.\",\n ),\n );\n } else {\n reject(err);\n }\n });\n });\n}\n\nfunction buildJarArgs(\n inputPaths: string | string[],\n options: ConvertOptions,\n): string[] | Error {\n const inputList = Array.isArray(inputPaths) ? inputPaths : [inputPaths];\n if (inputList.length === 0) {\n return new Error('At least one input path must be provided.');\n }\n\n for (const input of inputList) {\n if (!fs.existsSync(input)) {\n return new Error(`Input file or folder not found: ${input}`);\n }\n }\n\n return [...inputList, ...buildArgs(options)];\n}\n\nexport function convert(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<string> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n return Promise.reject(argsOrError);\n }\n // Library API: never streams to the parent process. Returns the full stdout\n // string so callers can do `const out = await convert(...)` without surprise\n // side-effects on process.stdout / process.stderr.\n return executeJar(argsOrError, { streamOutput: false });\n}\n\n/**\n * Internal entry point used by the bundled CLI. Streams Java's stdout and\n * stderr to the parent process in real time (so long-running conversions like\n * hybrid mode show progress as it happens) and resolves without a stdout\n * payload — preventing the caller from re-printing what was already streamed.\n *\n * Not part of the public API: do not import this from application code. Use\n * {@link convert} instead.\n *\n * @internal\n */\nexport async function _runForCli(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<void> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n throw argsOrError;\n }\n await executeJar(argsOrError, { streamOutput: true });\n}\n\n/**\n * @deprecated Use `convert()` and `ConvertOptions` instead. This function will be removed in a future version.\n */\nexport interface RunOptions {\n outputFolder?: string;\n password?: string;\n replaceInvalidChars?: string;\n generateMarkdown?: boolean;\n generateHtml?: boolean;\n generateAnnotatedPdf?: boolean;\n keepLineBreaks?: boolean;\n contentSafetyOff?: string;\n htmlInMarkdown?: boolean;\n addImageToMarkdown?: boolean;\n noJson?: boolean;\n debug?: boolean;\n useStructTree?: boolean;\n}\n\n/**\n * @deprecated Use `convert()` instead. This function will be removed in a future version.\n */\nexport function run(inputPath: string, options: RunOptions = {}): Promise<string> {\n console.warn(\n 'Warning: run() is deprecated and will be removed in a future version. Use convert() instead.',\n );\n\n // Build format array based on legacy boolean options\n const formats: string[] = [];\n if (!options.noJson) {\n formats.push('json');\n }\n if (options.generateMarkdown) {\n if (options.addImageToMarkdown) {\n formats.push('markdown-with-images');\n } else if (options.htmlInMarkdown) {\n formats.push('markdown-with-html');\n } else {\n formats.push('markdown');\n }\n }\n if (options.generateHtml) {\n formats.push('html');\n }\n if (options.generateAnnotatedPdf) {\n formats.push('pdf');\n }\n\n return convert(inputPath, {\n outputDir: options.outputFolder,\n password: options.password,\n replaceInvalidChars: options.replaceInvalidChars,\n keepLineBreaks: options.keepLineBreaks,\n contentSafetyOff: options.contentSafetyOff,\n useStructTree: options.useStructTree,\n format: formats.length > 0 ? formats : undefined,\n quiet: !options.debug,\n });\n}\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\n/**\n * Options for the convert function.\n */\nexport interface ConvertOptions {\n /** Directory where output files are written. Default: input file directory */\n outputDir?: string;\n /** Password for encrypted PDF files */\n password?: string;\n /** Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output. */\n format?: string | string[];\n /** Suppress console logging output */\n quiet?: boolean;\n /** Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background */\n contentSafetyOff?: string | string[];\n /** Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders */\n sanitize?: boolean;\n /** Preserve original line breaks in extracted text */\n keepLineBreaks?: boolean;\n /** Replacement character for invalid/unrecognized characters. Default: space */\n replaceInvalidChars?: string;\n /** Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called */\n useStructTree?: boolean;\n /** Table detection method. Values: default (border-based), cluster (border + cluster). Default: default */\n tableMethod?: string;\n /** Reading order algorithm. Values: off, xycut. Default: xycut */\n readingOrder?: string;\n /** Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none */\n markdownPageSeparator?: string;\n /** Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown. */\n markdownWithHtml?: boolean;\n /** Separator between pages in text output. Use %page-number% for page numbers. Default: none */\n textPageSeparator?: string;\n /** Separator between pages in HTML output. Use %page-number% for page numbers. Default: none */\n htmlPageSeparator?: string;\n /** Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external */\n imageOutput?: string;\n /** Output format for extracted images. Values: png, jpeg. Default: png */\n imageFormat?: string;\n /** Directory for extracted images (applies only with --image-output external) */\n imageDir?: string;\n /** Pages to extract (e.g., \"1,3,5-7\"). Default: all pages */\n pages?: string;\n /** Include page headers and footers in output */\n includeHeaderFooter?: boolean;\n /** Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental) */\n detectStrikethrough?: boolean;\n /** Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence) */\n hybrid?: string;\n /** Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend) */\n hybridMode?: string;\n /** Hybrid backend server URL (overrides default) */\n hybridUrl?: string;\n /** Hybrid backend request timeout in milliseconds (0 = use the backend's own default). Default: 0 */\n hybridTimeout?: string;\n /** Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50 */\n hybridChunkSize?: string;\n /** Opt in to Java fallback on hybrid backend error (default: disabled) */\n hybridFallback?: boolean;\n /** Write output to stdout instead of file (single format only) */\n toStdout?: boolean;\n /** Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode */\n threads?: string;\n /** Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0. */\n imageResolution?: string;\n /** Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17 */\n spaceRatio?: string;\n /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */\n sanitizeRules?: string;\n}\n\n/**\n * Options as parsed from CLI (all values are strings from commander).\n */\nexport interface CliOptions {\n outputDir?: string;\n password?: string;\n format?: string;\n quiet?: boolean;\n contentSafetyOff?: string;\n sanitize?: boolean;\n keepLineBreaks?: boolean;\n replaceInvalidChars?: string;\n useStructTree?: boolean;\n tableMethod?: string;\n readingOrder?: string;\n markdownPageSeparator?: string;\n markdownWithHtml?: boolean;\n textPageSeparator?: string;\n htmlPageSeparator?: string;\n imageOutput?: string;\n imageFormat?: string;\n imageDir?: string;\n pages?: string;\n includeHeaderFooter?: boolean;\n detectStrikethrough?: boolean;\n hybrid?: string;\n hybridMode?: string;\n hybridUrl?: string;\n hybridTimeout?: string;\n hybridChunkSize?: string;\n hybridFallback?: boolean;\n toStdout?: boolean;\n threads?: string;\n imageResolution?: string;\n spaceRatio?: string;\n sanitizeRules?: string;\n}\n\n/**\n * Convert CLI options to ConvertOptions.\n */\nexport function buildConvertOptions(cliOptions: CliOptions): ConvertOptions {\n const convertOptions: ConvertOptions = {};\n\n if (cliOptions.outputDir) {\n convertOptions.outputDir = cliOptions.outputDir;\n }\n if (cliOptions.password) {\n convertOptions.password = cliOptions.password;\n }\n if (cliOptions.format) {\n convertOptions.format = cliOptions.format;\n }\n if (cliOptions.quiet) {\n convertOptions.quiet = true;\n }\n if (cliOptions.contentSafetyOff) {\n convertOptions.contentSafetyOff = cliOptions.contentSafetyOff;\n }\n if (cliOptions.sanitize) {\n convertOptions.sanitize = true;\n }\n if (cliOptions.keepLineBreaks) {\n convertOptions.keepLineBreaks = true;\n }\n if (cliOptions.replaceInvalidChars) {\n convertOptions.replaceInvalidChars = cliOptions.replaceInvalidChars;\n }\n if (cliOptions.useStructTree) {\n convertOptions.useStructTree = true;\n }\n if (cliOptions.tableMethod) {\n convertOptions.tableMethod = cliOptions.tableMethod;\n }\n if (cliOptions.readingOrder) {\n convertOptions.readingOrder = cliOptions.readingOrder;\n }\n if (cliOptions.markdownPageSeparator) {\n convertOptions.markdownPageSeparator = cliOptions.markdownPageSeparator;\n }\n if (cliOptions.markdownWithHtml) {\n convertOptions.markdownWithHtml = true;\n }\n if (cliOptions.textPageSeparator) {\n convertOptions.textPageSeparator = cliOptions.textPageSeparator;\n }\n if (cliOptions.htmlPageSeparator) {\n convertOptions.htmlPageSeparator = cliOptions.htmlPageSeparator;\n }\n if (cliOptions.imageOutput) {\n convertOptions.imageOutput = cliOptions.imageOutput;\n }\n if (cliOptions.imageFormat) {\n convertOptions.imageFormat = cliOptions.imageFormat;\n }\n if (cliOptions.imageDir) {\n convertOptions.imageDir = cliOptions.imageDir;\n }\n if (cliOptions.pages) {\n convertOptions.pages = cliOptions.pages;\n }\n if (cliOptions.includeHeaderFooter) {\n convertOptions.includeHeaderFooter = true;\n }\n if (cliOptions.detectStrikethrough) {\n convertOptions.detectStrikethrough = true;\n }\n if (cliOptions.hybrid) {\n convertOptions.hybrid = cliOptions.hybrid;\n }\n if (cliOptions.hybridMode) {\n convertOptions.hybridMode = cliOptions.hybridMode;\n }\n if (cliOptions.hybridUrl) {\n convertOptions.hybridUrl = cliOptions.hybridUrl;\n }\n if (cliOptions.hybridTimeout) {\n convertOptions.hybridTimeout = cliOptions.hybridTimeout;\n }\n if (cliOptions.hybridChunkSize) {\n convertOptions.hybridChunkSize = cliOptions.hybridChunkSize;\n }\n if (cliOptions.hybridFallback) {\n convertOptions.hybridFallback = true;\n }\n if (cliOptions.toStdout) {\n convertOptions.toStdout = true;\n }\n if (cliOptions.threads) {\n convertOptions.threads = cliOptions.threads;\n }\n if (cliOptions.imageResolution) {\n convertOptions.imageResolution = cliOptions.imageResolution;\n }\n if (cliOptions.spaceRatio) {\n convertOptions.spaceRatio = cliOptions.spaceRatio;\n }\n if (cliOptions.sanitizeRules !== undefined && cliOptions.sanitizeRules !== null) {\n convertOptions.sanitizeRules = cliOptions.sanitizeRules;\n }\n\n return convertOptions;\n}\n\n/**\n * Build CLI arguments array from ConvertOptions.\n */\nexport function buildArgs(options: ConvertOptions): string[] {\n const args: string[] = [];\n\n if (options.outputDir) {\n args.push('--output-dir', options.outputDir);\n }\n if (options.password) {\n args.push('--password', options.password);\n }\n if (options.format) {\n if (Array.isArray(options.format)) {\n if (options.format.length > 0) {\n args.push('--format', options.format.join(','));\n }\n } else {\n args.push('--format', options.format);\n }\n }\n if (options.quiet) {\n args.push('--quiet');\n }\n if (options.contentSafetyOff) {\n if (Array.isArray(options.contentSafetyOff)) {\n if (options.contentSafetyOff.length > 0) {\n args.push('--content-safety-off', options.contentSafetyOff.join(','));\n }\n } else {\n args.push('--content-safety-off', options.contentSafetyOff);\n }\n }\n if (options.sanitize) {\n args.push('--sanitize');\n }\n if (options.keepLineBreaks) {\n args.push('--keep-line-breaks');\n }\n if (options.replaceInvalidChars) {\n args.push('--replace-invalid-chars', options.replaceInvalidChars);\n }\n if (options.useStructTree) {\n args.push('--use-struct-tree');\n }\n if (options.tableMethod) {\n args.push('--table-method', options.tableMethod);\n }\n if (options.readingOrder) {\n args.push('--reading-order', options.readingOrder);\n }\n if (options.markdownPageSeparator) {\n args.push('--markdown-page-separator', options.markdownPageSeparator);\n }\n if (options.markdownWithHtml) {\n args.push('--markdown-with-html');\n }\n if (options.textPageSeparator) {\n args.push('--text-page-separator', options.textPageSeparator);\n }\n if (options.htmlPageSeparator) {\n args.push('--html-page-separator', options.htmlPageSeparator);\n }\n if (options.imageOutput) {\n args.push('--image-output', options.imageOutput);\n }\n if (options.imageFormat) {\n args.push('--image-format', options.imageFormat);\n }\n if (options.imageDir) {\n args.push('--image-dir', options.imageDir);\n }\n if (options.pages) {\n args.push('--pages', options.pages);\n }\n if (options.includeHeaderFooter) {\n args.push('--include-header-footer');\n }\n if (options.detectStrikethrough) {\n args.push('--detect-strikethrough');\n }\n if (options.hybrid) {\n args.push('--hybrid', options.hybrid);\n }\n if (options.hybridMode) {\n args.push('--hybrid-mode', options.hybridMode);\n }\n if (options.hybridUrl) {\n args.push('--hybrid-url', options.hybridUrl);\n }\n if (options.hybridTimeout) {\n args.push('--hybrid-timeout', options.hybridTimeout);\n }\n if (options.hybridChunkSize) {\n args.push('--hybrid-chunk-size', options.hybridChunkSize);\n }\n if (options.hybridFallback) {\n args.push('--hybrid-fallback');\n }\n if (options.toStdout) {\n args.push('--to-stdout');\n }\n if (options.threads) {\n args.push('--threads', options.threads);\n }\n if (options.imageResolution) {\n args.push('--image-resolution', options.imageResolution);\n }\n if (options.spaceRatio) {\n args.push('--space-ratio', options.spaceRatio);\n }\n if (options.sanitizeRules !== undefined && options.sanitizeRules !== null) {\n args.push('--sanitize-rules', options.sanitizeRules);\n }\n\n return args;\n}\n"],"mappings":"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","names":["__filename"]}
1
+ {"version":3,"sources":["../src/index.ts","../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.31_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js","../src/convert-options.generated.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport { randomUUID } from 'crypto';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { StringDecoder } from 'string_decoder';\nimport { fileURLToPath } from 'url';\n\n// Re-export types and utilities from auto-generated file\nexport type { ConvertOptions } from './convert-options.generated.js';\nexport { buildArgs } from './convert-options.generated.js';\nimport type { ConvertOptions } from './convert-options.generated.js';\nimport { buildArgs } from './convert-options.generated.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst JAR_NAME = 'opendataloader-pdf-cli.jar';\n\n// Environment variables that the JVM reads options from.\nconst JAVA_OPTION_VARS = ['JAVA_TOOL_OPTIONS', 'JDK_JAVA_OPTIONS', '_JAVA_OPTIONS'];\n\n/**\n * Returns the option that gives Java the temporary folder of this runtime.\n * The JVM does not read TMPDIR, so without this option Java can use another\n * folder than Node. A command-line option wins over JAVA_TOOL_OPTIONS and\n * JDK_JAVA_OPTIONS, so add none if the user set java.io.tmpdir there.\n */\nfunction tempDirOptions(): string[] {\n if (JAVA_OPTION_VARS.some((name) => (process.env[name] ?? '').includes('-Djava.io.tmpdir='))) {\n return [];\n }\n // os.tmpdir() returns TMPDIR without a check: it can name a missing\n // folder, a folder without write access, or a file. Create and delete a\n // probe file, as Java does. If that fails, add nothing and let Java keep\n // its own default.\n const dir = os.tmpdir();\n const probe = path.join(dir, `opendataloader-${process.pid}-${randomUUID()}.probe`);\n try {\n fs.closeSync(fs.openSync(probe, 'wx'));\n fs.unlinkSync(probe);\n } catch {\n return [];\n }\n return [`-Djava.io.tmpdir=${dir}`];\n}\n\ninterface JarExecutionOptions {\n /**\n * When true, forwards Java's stdout and stderr chunks to the parent\n * process in real time as well as accumulating them. Used by the bundled\n * CLI so long-running conversions show progress as it happens.\n */\n streamOutput?: boolean;\n}\n\nfunction executeJar(args: string[], executionOptions: JarExecutionOptions = {}): Promise<string> {\n const { streamOutput = false } = executionOptions;\n\n return new Promise((resolve, reject) => {\n const jarPath = path.join(__dirname, '..', 'lib', JAR_NAME);\n\n if (!fs.existsSync(jarPath)) {\n return reject(\n new Error(`JAR file not found at ${jarPath}. Please run the build script first.`),\n );\n }\n\n const command = 'java';\n // Force headless AWT so macOS doesn't surface a Dock icon (and steal focus)\n // every time the JVM touches ImageIO/PDFBox rendering. Safe on all OSes —\n // the CLI never opens a UI window, only manipulates BufferedImages.\n const commandArgs = [\n '-Djava.awt.headless=true',\n '-Dapple.awt.UIElement=true',\n ...tempDirOptions(),\n '-jar',\n jarPath,\n ...args,\n ];\n\n const javaProcess = spawn(command, commandArgs);\n\n let stdout = '';\n let stderr = '';\n // StringDecoder buffers incomplete multi-byte UTF-8 sequences across\n // chunk boundaries — Buffer.toString() alone would emit replacement\n // characters when, e.g., a 3-byte Korean codepoint splits across two\n // 'data' events. One decoder per stream so they don't share state.\n const stdoutDecoder = new StringDecoder('utf8');\n const stderrDecoder = new StringDecoder('utf8');\n\n javaProcess.stdout.on('data', (data: Buffer) => {\n const chunk = stdoutDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n // Stream-only: don't also accumulate, or a multi-hour conversion\n // would buffer its entire (potentially gigabyte) stdout in memory\n // for no consumer.\n process.stdout.write(chunk);\n } else {\n stdout += chunk;\n }\n });\n\n javaProcess.stderr.on('data', (data: Buffer) => {\n const chunk = stderrDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n process.stderr.write(chunk);\n }\n // stderr is always accumulated (progress logs are small and we need\n // them for error messages on non-zero exit).\n stderr += chunk;\n });\n\n javaProcess.on('close', (code) => {\n // Flush any trailing bytes the decoder is still holding (always emit\n // them — if we drop them on error paths, error messages with non-ASCII\n // characters lose their tail).\n const stdoutTail = stdoutDecoder.end();\n const stderrTail = stderrDecoder.end();\n if (stdoutTail.length > 0) {\n if (streamOutput) {\n process.stdout.write(stdoutTail);\n } else {\n stdout += stdoutTail;\n }\n }\n if (stderrTail.length > 0) {\n if (streamOutput) process.stderr.write(stderrTail);\n stderr += stderrTail;\n }\n\n if (code === 0) {\n resolve(stdout);\n } else {\n const errorOutput = stderr || stdout;\n const error = new Error(\n `The opendataloader-pdf CLI exited with code ${code}.\\n\\n${errorOutput}`,\n );\n // Tag so the CLI can suppress re-printing this message — Java's\n // stderr was already streamed live to the parent in CLI mode, and\n // re-printing risks leaking anything sensitive Java logged\n // (e.g. a --password value echoed by an underlying library).\n (error as Error & { isJavaExit?: boolean }).isJavaExit = true;\n reject(error);\n }\n });\n\n javaProcess.on('error', (err: Error) => {\n if (err.message.includes('ENOENT')) {\n reject(\n new Error(\n \"'java' command not found. Please ensure Java is installed and in your system's PATH.\",\n ),\n );\n } else {\n reject(err);\n }\n });\n });\n}\n\nfunction buildJarArgs(\n inputPaths: string | string[],\n options: ConvertOptions,\n): string[] | Error {\n const inputList = Array.isArray(inputPaths) ? inputPaths : [inputPaths];\n if (inputList.length === 0) {\n return new Error('At least one input path must be provided.');\n }\n\n for (const input of inputList) {\n if (!fs.existsSync(input)) {\n return new Error(`Input file or folder not found: ${input}`);\n }\n }\n\n return [...inputList, ...buildArgs(options)];\n}\n\nexport function convert(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<string> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n return Promise.reject(argsOrError);\n }\n // Library API: never streams to the parent process. Returns the full stdout\n // string so callers can do `const out = await convert(...)` without surprise\n // side-effects on process.stdout / process.stderr.\n return executeJar(argsOrError, { streamOutput: false });\n}\n\n/**\n * Internal entry point used by the bundled CLI. Streams Java's stdout and\n * stderr to the parent process in real time (so long-running conversions like\n * hybrid mode show progress as it happens) and resolves without a stdout\n * payload — preventing the caller from re-printing what was already streamed.\n *\n * Not part of the public API: do not import this from application code. Use\n * {@link convert} instead.\n *\n * @internal\n */\nexport async function _runForCli(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<void> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n throw argsOrError;\n }\n await executeJar(argsOrError, { streamOutput: true });\n}\n\n/**\n * @deprecated Use `convert()` and `ConvertOptions` instead. This function will be removed in a future version.\n */\nexport interface RunOptions {\n outputFolder?: string;\n password?: string;\n replaceInvalidChars?: string;\n generateMarkdown?: boolean;\n generateHtml?: boolean;\n generateAnnotatedPdf?: boolean;\n keepLineBreaks?: boolean;\n contentSafetyOff?: string;\n htmlInMarkdown?: boolean;\n addImageToMarkdown?: boolean;\n noJson?: boolean;\n debug?: boolean;\n useStructTree?: boolean;\n}\n\n/**\n * @deprecated Use `convert()` instead. This function will be removed in a future version.\n */\nexport function run(inputPath: string, options: RunOptions = {}): Promise<string> {\n console.warn(\n 'Warning: run() is deprecated and will be removed in a future version. Use convert() instead.',\n );\n\n // Build format array based on legacy boolean options\n const formats: string[] = [];\n if (!options.noJson) {\n formats.push('json');\n }\n if (options.generateMarkdown) {\n if (options.addImageToMarkdown) {\n formats.push('markdown-with-images');\n } else if (options.htmlInMarkdown) {\n formats.push('markdown-with-html');\n } else {\n formats.push('markdown');\n }\n }\n if (options.generateHtml) {\n formats.push('html');\n }\n if (options.generateAnnotatedPdf) {\n formats.push('pdf');\n }\n\n return convert(inputPath, {\n outputDir: options.outputFolder,\n password: options.password,\n replaceInvalidChars: options.replaceInvalidChars,\n keepLineBreaks: options.keepLineBreaks,\n contentSafetyOff: options.contentSafetyOff,\n useStructTree: options.useStructTree,\n format: formats.length > 0 ? formats : undefined,\n quiet: !options.debug,\n });\n}\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\n/**\n * Options for the convert function.\n */\nexport interface ConvertOptions {\n /** Directory where output files are written. Default: input file directory */\n outputDir?: string;\n /** Password for encrypted PDF files */\n password?: string;\n /** Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output. */\n format?: string | string[];\n /** Suppress console logging output */\n quiet?: boolean;\n /** Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background */\n contentSafetyOff?: string | string[];\n /** Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders */\n sanitize?: boolean;\n /** Preserve original line breaks in extracted text */\n keepLineBreaks?: boolean;\n /** Replacement character for invalid/unrecognized characters. Default: space */\n replaceInvalidChars?: string;\n /** Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called */\n useStructTree?: boolean;\n /** Table detection method. Values: default (border-based), cluster (border + cluster). Default: default */\n tableMethod?: string;\n /** Reading order algorithm. Values: off, xycut. Default: xycut */\n readingOrder?: string;\n /** Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none */\n markdownPageSeparator?: string;\n /** Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown. */\n markdownWithHtml?: boolean;\n /** Separator between pages in text output. Use %page-number% for page numbers. Default: none */\n textPageSeparator?: string;\n /** Separator between pages in HTML output. Use %page-number% for page numbers. Default: none */\n htmlPageSeparator?: string;\n /** Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external */\n imageOutput?: string;\n /** Output format for extracted images. Values: png, jpeg. Default: png */\n imageFormat?: string;\n /** Directory for extracted images (applies only with --image-output external) */\n imageDir?: string;\n /** Pages to extract (e.g., \"1,3,5-7\"). Default: all pages */\n pages?: string;\n /** Include page headers and footers in output */\n includeHeaderFooter?: boolean;\n /** Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental) */\n detectStrikethrough?: boolean;\n /** Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence) */\n hybrid?: string;\n /** Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend) */\n hybridMode?: string;\n /** Hybrid backend server URL (overrides default) */\n hybridUrl?: string;\n /** Hybrid backend request timeout in milliseconds (0 = use the backend's own default). Default: 0 */\n hybridTimeout?: string;\n /** Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50 */\n hybridChunkSize?: string;\n /** Opt in to Java fallback on hybrid backend error (default: disabled) */\n hybridFallback?: boolean;\n /** Write output to stdout instead of file (single format only) */\n toStdout?: boolean;\n /** Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode */\n threads?: string;\n /** Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0. */\n imageResolution?: string;\n /** Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17 */\n spaceRatio?: string;\n /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */\n sanitizeRules?: string;\n /** Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text */\n includeLinks?: boolean;\n /** Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000 */\n hybridAvailabilityTimeout?: string;\n /** With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder */\n hybridTriageLog?: boolean;\n}\n\n/**\n * Options as parsed from CLI (all values are strings from commander).\n */\nexport interface CliOptions {\n outputDir?: string;\n password?: string;\n format?: string;\n quiet?: boolean;\n contentSafetyOff?: string;\n sanitize?: boolean;\n keepLineBreaks?: boolean;\n replaceInvalidChars?: string;\n useStructTree?: boolean;\n tableMethod?: string;\n readingOrder?: string;\n markdownPageSeparator?: string;\n markdownWithHtml?: boolean;\n textPageSeparator?: string;\n htmlPageSeparator?: string;\n imageOutput?: string;\n imageFormat?: string;\n imageDir?: string;\n pages?: string;\n includeHeaderFooter?: boolean;\n detectStrikethrough?: boolean;\n hybrid?: string;\n hybridMode?: string;\n hybridUrl?: string;\n hybridTimeout?: string;\n hybridChunkSize?: string;\n hybridFallback?: boolean;\n toStdout?: boolean;\n threads?: string;\n imageResolution?: string;\n spaceRatio?: string;\n sanitizeRules?: string;\n includeLinks?: boolean;\n hybridAvailabilityTimeout?: string;\n hybridTriageLog?: boolean;\n}\n\n/**\n * Convert CLI options to ConvertOptions.\n */\nexport function buildConvertOptions(cliOptions: CliOptions): ConvertOptions {\n const convertOptions: ConvertOptions = {};\n\n if (cliOptions.outputDir) {\n convertOptions.outputDir = cliOptions.outputDir;\n }\n if (cliOptions.password) {\n convertOptions.password = cliOptions.password;\n }\n if (cliOptions.format) {\n convertOptions.format = cliOptions.format;\n }\n if (cliOptions.quiet) {\n convertOptions.quiet = true;\n }\n if (cliOptions.contentSafetyOff) {\n convertOptions.contentSafetyOff = cliOptions.contentSafetyOff;\n }\n if (cliOptions.sanitize) {\n convertOptions.sanitize = true;\n }\n if (cliOptions.keepLineBreaks) {\n convertOptions.keepLineBreaks = true;\n }\n if (cliOptions.replaceInvalidChars) {\n convertOptions.replaceInvalidChars = cliOptions.replaceInvalidChars;\n }\n if (cliOptions.useStructTree) {\n convertOptions.useStructTree = true;\n }\n if (cliOptions.tableMethod) {\n convertOptions.tableMethod = cliOptions.tableMethod;\n }\n if (cliOptions.readingOrder) {\n convertOptions.readingOrder = cliOptions.readingOrder;\n }\n if (cliOptions.markdownPageSeparator) {\n convertOptions.markdownPageSeparator = cliOptions.markdownPageSeparator;\n }\n if (cliOptions.markdownWithHtml) {\n convertOptions.markdownWithHtml = true;\n }\n if (cliOptions.textPageSeparator) {\n convertOptions.textPageSeparator = cliOptions.textPageSeparator;\n }\n if (cliOptions.htmlPageSeparator) {\n convertOptions.htmlPageSeparator = cliOptions.htmlPageSeparator;\n }\n if (cliOptions.imageOutput) {\n convertOptions.imageOutput = cliOptions.imageOutput;\n }\n if (cliOptions.imageFormat) {\n convertOptions.imageFormat = cliOptions.imageFormat;\n }\n if (cliOptions.imageDir) {\n convertOptions.imageDir = cliOptions.imageDir;\n }\n if (cliOptions.pages) {\n convertOptions.pages = cliOptions.pages;\n }\n if (cliOptions.includeHeaderFooter) {\n convertOptions.includeHeaderFooter = true;\n }\n if (cliOptions.detectStrikethrough) {\n convertOptions.detectStrikethrough = true;\n }\n if (cliOptions.hybrid) {\n convertOptions.hybrid = cliOptions.hybrid;\n }\n if (cliOptions.hybridMode) {\n convertOptions.hybridMode = cliOptions.hybridMode;\n }\n if (cliOptions.hybridUrl) {\n convertOptions.hybridUrl = cliOptions.hybridUrl;\n }\n if (cliOptions.hybridTimeout) {\n convertOptions.hybridTimeout = cliOptions.hybridTimeout;\n }\n if (cliOptions.hybridChunkSize) {\n convertOptions.hybridChunkSize = cliOptions.hybridChunkSize;\n }\n if (cliOptions.hybridFallback) {\n convertOptions.hybridFallback = true;\n }\n if (cliOptions.toStdout) {\n convertOptions.toStdout = true;\n }\n if (cliOptions.threads) {\n convertOptions.threads = cliOptions.threads;\n }\n if (cliOptions.imageResolution) {\n convertOptions.imageResolution = cliOptions.imageResolution;\n }\n if (cliOptions.spaceRatio) {\n convertOptions.spaceRatio = cliOptions.spaceRatio;\n }\n if (cliOptions.sanitizeRules !== undefined && cliOptions.sanitizeRules !== null) {\n convertOptions.sanitizeRules = cliOptions.sanitizeRules;\n }\n if (cliOptions.includeLinks) {\n convertOptions.includeLinks = true;\n }\n if (cliOptions.hybridAvailabilityTimeout) {\n convertOptions.hybridAvailabilityTimeout = cliOptions.hybridAvailabilityTimeout;\n }\n if (cliOptions.hybridTriageLog) {\n convertOptions.hybridTriageLog = true;\n }\n\n return convertOptions;\n}\n\n/**\n * Build CLI arguments array from ConvertOptions.\n */\nexport function buildArgs(options: ConvertOptions): string[] {\n const args: string[] = [];\n\n if (options.outputDir) {\n args.push('--output-dir', options.outputDir);\n }\n if (options.password) {\n args.push('--password', options.password);\n }\n if (options.format) {\n if (Array.isArray(options.format)) {\n if (options.format.length > 0) {\n args.push('--format', options.format.join(','));\n }\n } else {\n args.push('--format', options.format);\n }\n }\n if (options.quiet) {\n args.push('--quiet');\n }\n if (options.contentSafetyOff) {\n if (Array.isArray(options.contentSafetyOff)) {\n if (options.contentSafetyOff.length > 0) {\n args.push('--content-safety-off', options.contentSafetyOff.join(','));\n }\n } else {\n args.push('--content-safety-off', options.contentSafetyOff);\n }\n }\n if (options.sanitize) {\n args.push('--sanitize');\n }\n if (options.keepLineBreaks) {\n args.push('--keep-line-breaks');\n }\n if (options.replaceInvalidChars) {\n args.push('--replace-invalid-chars', options.replaceInvalidChars);\n }\n if (options.useStructTree) {\n args.push('--use-struct-tree');\n }\n if (options.tableMethod) {\n args.push('--table-method', options.tableMethod);\n }\n if (options.readingOrder) {\n args.push('--reading-order', options.readingOrder);\n }\n if (options.markdownPageSeparator) {\n args.push('--markdown-page-separator', options.markdownPageSeparator);\n }\n if (options.markdownWithHtml) {\n args.push('--markdown-with-html');\n }\n if (options.textPageSeparator) {\n args.push('--text-page-separator', options.textPageSeparator);\n }\n if (options.htmlPageSeparator) {\n args.push('--html-page-separator', options.htmlPageSeparator);\n }\n if (options.imageOutput) {\n args.push('--image-output', options.imageOutput);\n }\n if (options.imageFormat) {\n args.push('--image-format', options.imageFormat);\n }\n if (options.imageDir) {\n args.push('--image-dir', options.imageDir);\n }\n if (options.pages) {\n args.push('--pages', options.pages);\n }\n if (options.includeHeaderFooter) {\n args.push('--include-header-footer');\n }\n if (options.detectStrikethrough) {\n args.push('--detect-strikethrough');\n }\n if (options.hybrid) {\n args.push('--hybrid', options.hybrid);\n }\n if (options.hybridMode) {\n args.push('--hybrid-mode', options.hybridMode);\n }\n if (options.hybridUrl) {\n args.push('--hybrid-url', options.hybridUrl);\n }\n if (options.hybridTimeout) {\n args.push('--hybrid-timeout', options.hybridTimeout);\n }\n if (options.hybridChunkSize) {\n args.push('--hybrid-chunk-size', options.hybridChunkSize);\n }\n if (options.hybridFallback) {\n args.push('--hybrid-fallback');\n }\n if (options.toStdout) {\n args.push('--to-stdout');\n }\n if (options.threads) {\n args.push('--threads', options.threads);\n }\n if (options.imageResolution) {\n args.push('--image-resolution', options.imageResolution);\n }\n if (options.spaceRatio) {\n args.push('--space-ratio', options.spaceRatio);\n }\n if (options.sanitizeRules !== undefined && options.sanitizeRules !== null) {\n args.push('--sanitize-rules', options.sanitizeRules);\n }\n if (options.includeLinks) {\n args.push('--include-links');\n }\n if (options.hybridAvailabilityTimeout) {\n args.push('--hybrid-availability-timeout', options.hybridAvailabilityTimeout);\n }\n if (options.hybridTriageLog) {\n args.push('--hybrid-triage-log');\n }\n\n return args;\n}\n"],"mappings":"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","names":["__filename"]}
package/dist/index.d.cts CHANGED
@@ -66,6 +66,12 @@ interface ConvertOptions {
66
66
  spaceRatio?: string;
67
67
  /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */
68
68
  sanitizeRules?: string;
69
+ /** Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text */
70
+ includeLinks?: boolean;
71
+ /** Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000 */
72
+ hybridAvailabilityTimeout?: string;
73
+ /** With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder */
74
+ hybridTriageLog?: boolean;
69
75
  }
70
76
  /**
71
77
  * Build CLI arguments array from ConvertOptions.
package/dist/index.d.ts CHANGED
@@ -66,6 +66,12 @@ interface ConvertOptions {
66
66
  spaceRatio?: string;
67
67
  /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */
68
68
  sanitizeRules?: string;
69
+ /** Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text */
70
+ includeLinks?: boolean;
71
+ /** Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000 */
72
+ hybridAvailabilityTimeout?: string;
73
+ /** With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder */
74
+ hybridTriageLog?: boolean;
69
75
  }
70
76
  /**
71
77
  * Build CLI arguments array from ConvertOptions.
package/dist/index.js CHANGED
@@ -118,6 +118,15 @@ function buildArgs(options) {
118
118
  if (options.sanitizeRules !== void 0 && options.sanitizeRules !== null) {
119
119
  args.push("--sanitize-rules", options.sanitizeRules);
120
120
  }
121
+ if (options.includeLinks) {
122
+ args.push("--include-links");
123
+ }
124
+ if (options.hybridAvailabilityTimeout) {
125
+ args.push("--hybrid-availability-timeout", options.hybridAvailabilityTimeout);
126
+ }
127
+ if (options.hybridTriageLog) {
128
+ args.push("--hybrid-triage-log");
129
+ }
121
130
  return args;
122
131
  }
123
132
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/convert-options.generated.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport { randomUUID } from 'crypto';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { StringDecoder } from 'string_decoder';\nimport { fileURLToPath } from 'url';\n\n// Re-export types and utilities from auto-generated file\nexport type { ConvertOptions } from './convert-options.generated.js';\nexport { buildArgs } from './convert-options.generated.js';\nimport type { ConvertOptions } from './convert-options.generated.js';\nimport { buildArgs } from './convert-options.generated.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst JAR_NAME = 'opendataloader-pdf-cli.jar';\n\n// Environment variables that the JVM reads options from.\nconst JAVA_OPTION_VARS = ['JAVA_TOOL_OPTIONS', 'JDK_JAVA_OPTIONS', '_JAVA_OPTIONS'];\n\n/**\n * Returns the option that gives Java the temporary folder of this runtime.\n * The JVM does not read TMPDIR, so without this option Java can use another\n * folder than Node. A command-line option wins over JAVA_TOOL_OPTIONS and\n * JDK_JAVA_OPTIONS, so add none if the user set java.io.tmpdir there.\n */\nfunction tempDirOptions(): string[] {\n if (JAVA_OPTION_VARS.some((name) => (process.env[name] ?? '').includes('-Djava.io.tmpdir='))) {\n return [];\n }\n // os.tmpdir() returns TMPDIR without a check: it can name a missing\n // folder, a folder without write access, or a file. Create and delete a\n // probe file, as Java does. If that fails, add nothing and let Java keep\n // its own default.\n const dir = os.tmpdir();\n const probe = path.join(dir, `opendataloader-${process.pid}-${randomUUID()}.probe`);\n try {\n fs.closeSync(fs.openSync(probe, 'wx'));\n fs.unlinkSync(probe);\n } catch {\n return [];\n }\n return [`-Djava.io.tmpdir=${dir}`];\n}\n\ninterface JarExecutionOptions {\n /**\n * When true, forwards Java's stdout and stderr chunks to the parent\n * process in real time as well as accumulating them. Used by the bundled\n * CLI so long-running conversions show progress as it happens.\n */\n streamOutput?: boolean;\n}\n\nfunction executeJar(args: string[], executionOptions: JarExecutionOptions = {}): Promise<string> {\n const { streamOutput = false } = executionOptions;\n\n return new Promise((resolve, reject) => {\n const jarPath = path.join(__dirname, '..', 'lib', JAR_NAME);\n\n if (!fs.existsSync(jarPath)) {\n return reject(\n new Error(`JAR file not found at ${jarPath}. Please run the build script first.`),\n );\n }\n\n const command = 'java';\n // Force headless AWT so macOS doesn't surface a Dock icon (and steal focus)\n // every time the JVM touches ImageIO/PDFBox rendering. Safe on all OSes —\n // the CLI never opens a UI window, only manipulates BufferedImages.\n const commandArgs = [\n '-Djava.awt.headless=true',\n '-Dapple.awt.UIElement=true',\n ...tempDirOptions(),\n '-jar',\n jarPath,\n ...args,\n ];\n\n const javaProcess = spawn(command, commandArgs);\n\n let stdout = '';\n let stderr = '';\n // StringDecoder buffers incomplete multi-byte UTF-8 sequences across\n // chunk boundaries — Buffer.toString() alone would emit replacement\n // characters when, e.g., a 3-byte Korean codepoint splits across two\n // 'data' events. One decoder per stream so they don't share state.\n const stdoutDecoder = new StringDecoder('utf8');\n const stderrDecoder = new StringDecoder('utf8');\n\n javaProcess.stdout.on('data', (data: Buffer) => {\n const chunk = stdoutDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n // Stream-only: don't also accumulate, or a multi-hour conversion\n // would buffer its entire (potentially gigabyte) stdout in memory\n // for no consumer.\n process.stdout.write(chunk);\n } else {\n stdout += chunk;\n }\n });\n\n javaProcess.stderr.on('data', (data: Buffer) => {\n const chunk = stderrDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n process.stderr.write(chunk);\n }\n // stderr is always accumulated (progress logs are small and we need\n // them for error messages on non-zero exit).\n stderr += chunk;\n });\n\n javaProcess.on('close', (code) => {\n // Flush any trailing bytes the decoder is still holding (always emit\n // them — if we drop them on error paths, error messages with non-ASCII\n // characters lose their tail).\n const stdoutTail = stdoutDecoder.end();\n const stderrTail = stderrDecoder.end();\n if (stdoutTail.length > 0) {\n if (streamOutput) {\n process.stdout.write(stdoutTail);\n } else {\n stdout += stdoutTail;\n }\n }\n if (stderrTail.length > 0) {\n if (streamOutput) process.stderr.write(stderrTail);\n stderr += stderrTail;\n }\n\n if (code === 0) {\n resolve(stdout);\n } else {\n const errorOutput = stderr || stdout;\n const error = new Error(\n `The opendataloader-pdf CLI exited with code ${code}.\\n\\n${errorOutput}`,\n );\n // Tag so the CLI can suppress re-printing this message — Java's\n // stderr was already streamed live to the parent in CLI mode, and\n // re-printing risks leaking anything sensitive Java logged\n // (e.g. a --password value echoed by an underlying library).\n (error as Error & { isJavaExit?: boolean }).isJavaExit = true;\n reject(error);\n }\n });\n\n javaProcess.on('error', (err: Error) => {\n if (err.message.includes('ENOENT')) {\n reject(\n new Error(\n \"'java' command not found. Please ensure Java is installed and in your system's PATH.\",\n ),\n );\n } else {\n reject(err);\n }\n });\n });\n}\n\nfunction buildJarArgs(\n inputPaths: string | string[],\n options: ConvertOptions,\n): string[] | Error {\n const inputList = Array.isArray(inputPaths) ? inputPaths : [inputPaths];\n if (inputList.length === 0) {\n return new Error('At least one input path must be provided.');\n }\n\n for (const input of inputList) {\n if (!fs.existsSync(input)) {\n return new Error(`Input file or folder not found: ${input}`);\n }\n }\n\n return [...inputList, ...buildArgs(options)];\n}\n\nexport function convert(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<string> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n return Promise.reject(argsOrError);\n }\n // Library API: never streams to the parent process. Returns the full stdout\n // string so callers can do `const out = await convert(...)` without surprise\n // side-effects on process.stdout / process.stderr.\n return executeJar(argsOrError, { streamOutput: false });\n}\n\n/**\n * Internal entry point used by the bundled CLI. Streams Java's stdout and\n * stderr to the parent process in real time (so long-running conversions like\n * hybrid mode show progress as it happens) and resolves without a stdout\n * payload — preventing the caller from re-printing what was already streamed.\n *\n * Not part of the public API: do not import this from application code. Use\n * {@link convert} instead.\n *\n * @internal\n */\nexport async function _runForCli(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<void> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n throw argsOrError;\n }\n await executeJar(argsOrError, { streamOutput: true });\n}\n\n/**\n * @deprecated Use `convert()` and `ConvertOptions` instead. This function will be removed in a future version.\n */\nexport interface RunOptions {\n outputFolder?: string;\n password?: string;\n replaceInvalidChars?: string;\n generateMarkdown?: boolean;\n generateHtml?: boolean;\n generateAnnotatedPdf?: boolean;\n keepLineBreaks?: boolean;\n contentSafetyOff?: string;\n htmlInMarkdown?: boolean;\n addImageToMarkdown?: boolean;\n noJson?: boolean;\n debug?: boolean;\n useStructTree?: boolean;\n}\n\n/**\n * @deprecated Use `convert()` instead. This function will be removed in a future version.\n */\nexport function run(inputPath: string, options: RunOptions = {}): Promise<string> {\n console.warn(\n 'Warning: run() is deprecated and will be removed in a future version. Use convert() instead.',\n );\n\n // Build format array based on legacy boolean options\n const formats: string[] = [];\n if (!options.noJson) {\n formats.push('json');\n }\n if (options.generateMarkdown) {\n if (options.addImageToMarkdown) {\n formats.push('markdown-with-images');\n } else if (options.htmlInMarkdown) {\n formats.push('markdown-with-html');\n } else {\n formats.push('markdown');\n }\n }\n if (options.generateHtml) {\n formats.push('html');\n }\n if (options.generateAnnotatedPdf) {\n formats.push('pdf');\n }\n\n return convert(inputPath, {\n outputDir: options.outputFolder,\n password: options.password,\n replaceInvalidChars: options.replaceInvalidChars,\n keepLineBreaks: options.keepLineBreaks,\n contentSafetyOff: options.contentSafetyOff,\n useStructTree: options.useStructTree,\n format: formats.length > 0 ? formats : undefined,\n quiet: !options.debug,\n });\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\n/**\n * Options for the convert function.\n */\nexport interface ConvertOptions {\n /** Directory where output files are written. Default: input file directory */\n outputDir?: string;\n /** Password for encrypted PDF files */\n password?: string;\n /** Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output. */\n format?: string | string[];\n /** Suppress console logging output */\n quiet?: boolean;\n /** Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background */\n contentSafetyOff?: string | string[];\n /** Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders */\n sanitize?: boolean;\n /** Preserve original line breaks in extracted text */\n keepLineBreaks?: boolean;\n /** Replacement character for invalid/unrecognized characters. Default: space */\n replaceInvalidChars?: string;\n /** Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called */\n useStructTree?: boolean;\n /** Table detection method. Values: default (border-based), cluster (border + cluster). Default: default */\n tableMethod?: string;\n /** Reading order algorithm. Values: off, xycut. Default: xycut */\n readingOrder?: string;\n /** Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none */\n markdownPageSeparator?: string;\n /** Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown. */\n markdownWithHtml?: boolean;\n /** Separator between pages in text output. Use %page-number% for page numbers. Default: none */\n textPageSeparator?: string;\n /** Separator between pages in HTML output. Use %page-number% for page numbers. Default: none */\n htmlPageSeparator?: string;\n /** Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external */\n imageOutput?: string;\n /** Output format for extracted images. Values: png, jpeg. Default: png */\n imageFormat?: string;\n /** Directory for extracted images (applies only with --image-output external) */\n imageDir?: string;\n /** Pages to extract (e.g., \"1,3,5-7\"). Default: all pages */\n pages?: string;\n /** Include page headers and footers in output */\n includeHeaderFooter?: boolean;\n /** Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental) */\n detectStrikethrough?: boolean;\n /** Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence) */\n hybrid?: string;\n /** Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend) */\n hybridMode?: string;\n /** Hybrid backend server URL (overrides default) */\n hybridUrl?: string;\n /** Hybrid backend request timeout in milliseconds (0 = use the backend's own default). Default: 0 */\n hybridTimeout?: string;\n /** Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50 */\n hybridChunkSize?: string;\n /** Opt in to Java fallback on hybrid backend error (default: disabled) */\n hybridFallback?: boolean;\n /** Write output to stdout instead of file (single format only) */\n toStdout?: boolean;\n /** Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode */\n threads?: string;\n /** Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0. */\n imageResolution?: string;\n /** Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17 */\n spaceRatio?: string;\n /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */\n sanitizeRules?: string;\n}\n\n/**\n * Options as parsed from CLI (all values are strings from commander).\n */\nexport interface CliOptions {\n outputDir?: string;\n password?: string;\n format?: string;\n quiet?: boolean;\n contentSafetyOff?: string;\n sanitize?: boolean;\n keepLineBreaks?: boolean;\n replaceInvalidChars?: string;\n useStructTree?: boolean;\n tableMethod?: string;\n readingOrder?: string;\n markdownPageSeparator?: string;\n markdownWithHtml?: boolean;\n textPageSeparator?: string;\n htmlPageSeparator?: string;\n imageOutput?: string;\n imageFormat?: string;\n imageDir?: string;\n pages?: string;\n includeHeaderFooter?: boolean;\n detectStrikethrough?: boolean;\n hybrid?: string;\n hybridMode?: string;\n hybridUrl?: string;\n hybridTimeout?: string;\n hybridChunkSize?: string;\n hybridFallback?: boolean;\n toStdout?: boolean;\n threads?: string;\n imageResolution?: string;\n spaceRatio?: string;\n sanitizeRules?: string;\n}\n\n/**\n * Convert CLI options to ConvertOptions.\n */\nexport function buildConvertOptions(cliOptions: CliOptions): ConvertOptions {\n const convertOptions: ConvertOptions = {};\n\n if (cliOptions.outputDir) {\n convertOptions.outputDir = cliOptions.outputDir;\n }\n if (cliOptions.password) {\n convertOptions.password = cliOptions.password;\n }\n if (cliOptions.format) {\n convertOptions.format = cliOptions.format;\n }\n if (cliOptions.quiet) {\n convertOptions.quiet = true;\n }\n if (cliOptions.contentSafetyOff) {\n convertOptions.contentSafetyOff = cliOptions.contentSafetyOff;\n }\n if (cliOptions.sanitize) {\n convertOptions.sanitize = true;\n }\n if (cliOptions.keepLineBreaks) {\n convertOptions.keepLineBreaks = true;\n }\n if (cliOptions.replaceInvalidChars) {\n convertOptions.replaceInvalidChars = cliOptions.replaceInvalidChars;\n }\n if (cliOptions.useStructTree) {\n convertOptions.useStructTree = true;\n }\n if (cliOptions.tableMethod) {\n convertOptions.tableMethod = cliOptions.tableMethod;\n }\n if (cliOptions.readingOrder) {\n convertOptions.readingOrder = cliOptions.readingOrder;\n }\n if (cliOptions.markdownPageSeparator) {\n convertOptions.markdownPageSeparator = cliOptions.markdownPageSeparator;\n }\n if (cliOptions.markdownWithHtml) {\n convertOptions.markdownWithHtml = true;\n }\n if (cliOptions.textPageSeparator) {\n convertOptions.textPageSeparator = cliOptions.textPageSeparator;\n }\n if (cliOptions.htmlPageSeparator) {\n convertOptions.htmlPageSeparator = cliOptions.htmlPageSeparator;\n }\n if (cliOptions.imageOutput) {\n convertOptions.imageOutput = cliOptions.imageOutput;\n }\n if (cliOptions.imageFormat) {\n convertOptions.imageFormat = cliOptions.imageFormat;\n }\n if (cliOptions.imageDir) {\n convertOptions.imageDir = cliOptions.imageDir;\n }\n if (cliOptions.pages) {\n convertOptions.pages = cliOptions.pages;\n }\n if (cliOptions.includeHeaderFooter) {\n convertOptions.includeHeaderFooter = true;\n }\n if (cliOptions.detectStrikethrough) {\n convertOptions.detectStrikethrough = true;\n }\n if (cliOptions.hybrid) {\n convertOptions.hybrid = cliOptions.hybrid;\n }\n if (cliOptions.hybridMode) {\n convertOptions.hybridMode = cliOptions.hybridMode;\n }\n if (cliOptions.hybridUrl) {\n convertOptions.hybridUrl = cliOptions.hybridUrl;\n }\n if (cliOptions.hybridTimeout) {\n convertOptions.hybridTimeout = cliOptions.hybridTimeout;\n }\n if (cliOptions.hybridChunkSize) {\n convertOptions.hybridChunkSize = cliOptions.hybridChunkSize;\n }\n if (cliOptions.hybridFallback) {\n convertOptions.hybridFallback = true;\n }\n if (cliOptions.toStdout) {\n convertOptions.toStdout = true;\n }\n if (cliOptions.threads) {\n convertOptions.threads = cliOptions.threads;\n }\n if (cliOptions.imageResolution) {\n convertOptions.imageResolution = cliOptions.imageResolution;\n }\n if (cliOptions.spaceRatio) {\n convertOptions.spaceRatio = cliOptions.spaceRatio;\n }\n if (cliOptions.sanitizeRules !== undefined && cliOptions.sanitizeRules !== null) {\n convertOptions.sanitizeRules = cliOptions.sanitizeRules;\n }\n\n return convertOptions;\n}\n\n/**\n * Build CLI arguments array from ConvertOptions.\n */\nexport function buildArgs(options: ConvertOptions): string[] {\n const args: string[] = [];\n\n if (options.outputDir) {\n args.push('--output-dir', options.outputDir);\n }\n if (options.password) {\n args.push('--password', options.password);\n }\n if (options.format) {\n if (Array.isArray(options.format)) {\n if (options.format.length > 0) {\n args.push('--format', options.format.join(','));\n }\n } else {\n args.push('--format', options.format);\n }\n }\n if (options.quiet) {\n args.push('--quiet');\n }\n if (options.contentSafetyOff) {\n if (Array.isArray(options.contentSafetyOff)) {\n if (options.contentSafetyOff.length > 0) {\n args.push('--content-safety-off', options.contentSafetyOff.join(','));\n }\n } else {\n args.push('--content-safety-off', options.contentSafetyOff);\n }\n }\n if (options.sanitize) {\n args.push('--sanitize');\n }\n if (options.keepLineBreaks) {\n args.push('--keep-line-breaks');\n }\n if (options.replaceInvalidChars) {\n args.push('--replace-invalid-chars', options.replaceInvalidChars);\n }\n if (options.useStructTree) {\n args.push('--use-struct-tree');\n }\n if (options.tableMethod) {\n args.push('--table-method', options.tableMethod);\n }\n if (options.readingOrder) {\n args.push('--reading-order', options.readingOrder);\n }\n if (options.markdownPageSeparator) {\n args.push('--markdown-page-separator', options.markdownPageSeparator);\n }\n if (options.markdownWithHtml) {\n args.push('--markdown-with-html');\n }\n if (options.textPageSeparator) {\n args.push('--text-page-separator', options.textPageSeparator);\n }\n if (options.htmlPageSeparator) {\n args.push('--html-page-separator', options.htmlPageSeparator);\n }\n if (options.imageOutput) {\n args.push('--image-output', options.imageOutput);\n }\n if (options.imageFormat) {\n args.push('--image-format', options.imageFormat);\n }\n if (options.imageDir) {\n args.push('--image-dir', options.imageDir);\n }\n if (options.pages) {\n args.push('--pages', options.pages);\n }\n if (options.includeHeaderFooter) {\n args.push('--include-header-footer');\n }\n if (options.detectStrikethrough) {\n args.push('--detect-strikethrough');\n }\n if (options.hybrid) {\n args.push('--hybrid', options.hybrid);\n }\n if (options.hybridMode) {\n args.push('--hybrid-mode', options.hybridMode);\n }\n if (options.hybridUrl) {\n args.push('--hybrid-url', options.hybridUrl);\n }\n if (options.hybridTimeout) {\n args.push('--hybrid-timeout', options.hybridTimeout);\n }\n if (options.hybridChunkSize) {\n args.push('--hybrid-chunk-size', options.hybridChunkSize);\n }\n if (options.hybridFallback) {\n args.push('--hybrid-fallback');\n }\n if (options.toStdout) {\n args.push('--to-stdout');\n }\n if (options.threads) {\n args.push('--threads', options.threads);\n }\n if (options.imageResolution) {\n args.push('--image-resolution', options.imageResolution);\n }\n if (options.spaceRatio) {\n args.push('--space-ratio', options.spaceRatio);\n }\n if (options.sanitizeRules !== undefined && options.sanitizeRules !== null) {\n args.push('--sanitize-rules', options.sanitizeRules);\n }\n\n return args;\n}\n"],"mappings":"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","names":["__filename","__dirname"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/convert-options.generated.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport { randomUUID } from 'crypto';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { StringDecoder } from 'string_decoder';\nimport { fileURLToPath } from 'url';\n\n// Re-export types and utilities from auto-generated file\nexport type { ConvertOptions } from './convert-options.generated.js';\nexport { buildArgs } from './convert-options.generated.js';\nimport type { ConvertOptions } from './convert-options.generated.js';\nimport { buildArgs } from './convert-options.generated.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst JAR_NAME = 'opendataloader-pdf-cli.jar';\n\n// Environment variables that the JVM reads options from.\nconst JAVA_OPTION_VARS = ['JAVA_TOOL_OPTIONS', 'JDK_JAVA_OPTIONS', '_JAVA_OPTIONS'];\n\n/**\n * Returns the option that gives Java the temporary folder of this runtime.\n * The JVM does not read TMPDIR, so without this option Java can use another\n * folder than Node. A command-line option wins over JAVA_TOOL_OPTIONS and\n * JDK_JAVA_OPTIONS, so add none if the user set java.io.tmpdir there.\n */\nfunction tempDirOptions(): string[] {\n if (JAVA_OPTION_VARS.some((name) => (process.env[name] ?? '').includes('-Djava.io.tmpdir='))) {\n return [];\n }\n // os.tmpdir() returns TMPDIR without a check: it can name a missing\n // folder, a folder without write access, or a file. Create and delete a\n // probe file, as Java does. If that fails, add nothing and let Java keep\n // its own default.\n const dir = os.tmpdir();\n const probe = path.join(dir, `opendataloader-${process.pid}-${randomUUID()}.probe`);\n try {\n fs.closeSync(fs.openSync(probe, 'wx'));\n fs.unlinkSync(probe);\n } catch {\n return [];\n }\n return [`-Djava.io.tmpdir=${dir}`];\n}\n\ninterface JarExecutionOptions {\n /**\n * When true, forwards Java's stdout and stderr chunks to the parent\n * process in real time as well as accumulating them. Used by the bundled\n * CLI so long-running conversions show progress as it happens.\n */\n streamOutput?: boolean;\n}\n\nfunction executeJar(args: string[], executionOptions: JarExecutionOptions = {}): Promise<string> {\n const { streamOutput = false } = executionOptions;\n\n return new Promise((resolve, reject) => {\n const jarPath = path.join(__dirname, '..', 'lib', JAR_NAME);\n\n if (!fs.existsSync(jarPath)) {\n return reject(\n new Error(`JAR file not found at ${jarPath}. Please run the build script first.`),\n );\n }\n\n const command = 'java';\n // Force headless AWT so macOS doesn't surface a Dock icon (and steal focus)\n // every time the JVM touches ImageIO/PDFBox rendering. Safe on all OSes —\n // the CLI never opens a UI window, only manipulates BufferedImages.\n const commandArgs = [\n '-Djava.awt.headless=true',\n '-Dapple.awt.UIElement=true',\n ...tempDirOptions(),\n '-jar',\n jarPath,\n ...args,\n ];\n\n const javaProcess = spawn(command, commandArgs);\n\n let stdout = '';\n let stderr = '';\n // StringDecoder buffers incomplete multi-byte UTF-8 sequences across\n // chunk boundaries — Buffer.toString() alone would emit replacement\n // characters when, e.g., a 3-byte Korean codepoint splits across two\n // 'data' events. One decoder per stream so they don't share state.\n const stdoutDecoder = new StringDecoder('utf8');\n const stderrDecoder = new StringDecoder('utf8');\n\n javaProcess.stdout.on('data', (data: Buffer) => {\n const chunk = stdoutDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n // Stream-only: don't also accumulate, or a multi-hour conversion\n // would buffer its entire (potentially gigabyte) stdout in memory\n // for no consumer.\n process.stdout.write(chunk);\n } else {\n stdout += chunk;\n }\n });\n\n javaProcess.stderr.on('data', (data: Buffer) => {\n const chunk = stderrDecoder.write(data);\n if (chunk.length === 0) return;\n if (streamOutput) {\n process.stderr.write(chunk);\n }\n // stderr is always accumulated (progress logs are small and we need\n // them for error messages on non-zero exit).\n stderr += chunk;\n });\n\n javaProcess.on('close', (code) => {\n // Flush any trailing bytes the decoder is still holding (always emit\n // them — if we drop them on error paths, error messages with non-ASCII\n // characters lose their tail).\n const stdoutTail = stdoutDecoder.end();\n const stderrTail = stderrDecoder.end();\n if (stdoutTail.length > 0) {\n if (streamOutput) {\n process.stdout.write(stdoutTail);\n } else {\n stdout += stdoutTail;\n }\n }\n if (stderrTail.length > 0) {\n if (streamOutput) process.stderr.write(stderrTail);\n stderr += stderrTail;\n }\n\n if (code === 0) {\n resolve(stdout);\n } else {\n const errorOutput = stderr || stdout;\n const error = new Error(\n `The opendataloader-pdf CLI exited with code ${code}.\\n\\n${errorOutput}`,\n );\n // Tag so the CLI can suppress re-printing this message — Java's\n // stderr was already streamed live to the parent in CLI mode, and\n // re-printing risks leaking anything sensitive Java logged\n // (e.g. a --password value echoed by an underlying library).\n (error as Error & { isJavaExit?: boolean }).isJavaExit = true;\n reject(error);\n }\n });\n\n javaProcess.on('error', (err: Error) => {\n if (err.message.includes('ENOENT')) {\n reject(\n new Error(\n \"'java' command not found. Please ensure Java is installed and in your system's PATH.\",\n ),\n );\n } else {\n reject(err);\n }\n });\n });\n}\n\nfunction buildJarArgs(\n inputPaths: string | string[],\n options: ConvertOptions,\n): string[] | Error {\n const inputList = Array.isArray(inputPaths) ? inputPaths : [inputPaths];\n if (inputList.length === 0) {\n return new Error('At least one input path must be provided.');\n }\n\n for (const input of inputList) {\n if (!fs.existsSync(input)) {\n return new Error(`Input file or folder not found: ${input}`);\n }\n }\n\n return [...inputList, ...buildArgs(options)];\n}\n\nexport function convert(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<string> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n return Promise.reject(argsOrError);\n }\n // Library API: never streams to the parent process. Returns the full stdout\n // string so callers can do `const out = await convert(...)` without surprise\n // side-effects on process.stdout / process.stderr.\n return executeJar(argsOrError, { streamOutput: false });\n}\n\n/**\n * Internal entry point used by the bundled CLI. Streams Java's stdout and\n * stderr to the parent process in real time (so long-running conversions like\n * hybrid mode show progress as it happens) and resolves without a stdout\n * payload — preventing the caller from re-printing what was already streamed.\n *\n * Not part of the public API: do not import this from application code. Use\n * {@link convert} instead.\n *\n * @internal\n */\nexport async function _runForCli(\n inputPaths: string | string[],\n options: ConvertOptions = {},\n): Promise<void> {\n const argsOrError = buildJarArgs(inputPaths, options);\n if (argsOrError instanceof Error) {\n throw argsOrError;\n }\n await executeJar(argsOrError, { streamOutput: true });\n}\n\n/**\n * @deprecated Use `convert()` and `ConvertOptions` instead. This function will be removed in a future version.\n */\nexport interface RunOptions {\n outputFolder?: string;\n password?: string;\n replaceInvalidChars?: string;\n generateMarkdown?: boolean;\n generateHtml?: boolean;\n generateAnnotatedPdf?: boolean;\n keepLineBreaks?: boolean;\n contentSafetyOff?: string;\n htmlInMarkdown?: boolean;\n addImageToMarkdown?: boolean;\n noJson?: boolean;\n debug?: boolean;\n useStructTree?: boolean;\n}\n\n/**\n * @deprecated Use `convert()` instead. This function will be removed in a future version.\n */\nexport function run(inputPath: string, options: RunOptions = {}): Promise<string> {\n console.warn(\n 'Warning: run() is deprecated and will be removed in a future version. Use convert() instead.',\n );\n\n // Build format array based on legacy boolean options\n const formats: string[] = [];\n if (!options.noJson) {\n formats.push('json');\n }\n if (options.generateMarkdown) {\n if (options.addImageToMarkdown) {\n formats.push('markdown-with-images');\n } else if (options.htmlInMarkdown) {\n formats.push('markdown-with-html');\n } else {\n formats.push('markdown');\n }\n }\n if (options.generateHtml) {\n formats.push('html');\n }\n if (options.generateAnnotatedPdf) {\n formats.push('pdf');\n }\n\n return convert(inputPath, {\n outputDir: options.outputFolder,\n password: options.password,\n replaceInvalidChars: options.replaceInvalidChars,\n keepLineBreaks: options.keepLineBreaks,\n contentSafetyOff: options.contentSafetyOff,\n useStructTree: options.useStructTree,\n format: formats.length > 0 ? formats : undefined,\n quiet: !options.debug,\n });\n}\n","// AUTO-GENERATED FROM options.json - DO NOT EDIT DIRECTLY\n// Run `npm run generate-options` to regenerate\n\n/**\n * Options for the convert function.\n */\nexport interface ConvertOptions {\n /** Directory where output files are written. Default: input file directory */\n outputDir?: string;\n /** Password for encrypted PDF files */\n password?: string;\n /** Output formats (comma-separated). Values: json, text, html, pdf, markdown, tagged-pdf. Default: json. For HTML inside Markdown use --markdown-with-html. For image extraction control use --image-output. */\n format?: string | string[];\n /** Suppress console logging output */\n quiet?: boolean;\n /** Disable content safety filters. Values: all, hidden-text, off-page, tiny, hidden-ocg, background */\n contentSafetyOff?: string | string[];\n /** Enable sensitive data sanitization. Replaces emails, phone numbers, IPs, credit cards, and URLs with placeholders */\n sanitize?: boolean;\n /** Preserve original line breaks in extracted text */\n keepLineBreaks?: boolean;\n /** Replacement character for invalid/unrecognized characters. Default: space */\n replaceInvalidChars?: string;\n /** Use PDF structure tree (tagged PDF) for reading order and semantic structure. Output quality depends on tag quality. Takes precedence over --hybrid: when both are set on a tagged PDF, the structure tree is used and the hybrid backend is not called */\n useStructTree?: boolean;\n /** Table detection method. Values: default (border-based), cluster (border + cluster). Default: default */\n tableMethod?: string;\n /** Reading order algorithm. Values: off, xycut. Default: xycut */\n readingOrder?: string;\n /** Separator between pages in Markdown output. Use %page-number% for page numbers. Default: none */\n markdownPageSeparator?: string;\n /** Allow HTML tags inside Markdown output for complex structures such as multi-row-span tables. Implies --format markdown. */\n markdownWithHtml?: boolean;\n /** Separator between pages in text output. Use %page-number% for page numbers. Default: none */\n textPageSeparator?: string;\n /** Separator between pages in HTML output. Use %page-number% for page numbers. Default: none */\n htmlPageSeparator?: string;\n /** Image output mode. Values: off (no images), embedded (Base64 data URIs), external (file references). Default: external */\n imageOutput?: string;\n /** Output format for extracted images. Values: png, jpeg. Default: png */\n imageFormat?: string;\n /** Directory for extracted images (applies only with --image-output external) */\n imageDir?: string;\n /** Pages to extract (e.g., \"1,3,5-7\"). Default: all pages */\n pages?: string;\n /** Include page headers and footers in output */\n includeHeaderFooter?: boolean;\n /** Detect strikethrough text and wrap with ~~ in Markdown output or <del></del> tag in HTML output (experimental) */\n detectStrikethrough?: boolean;\n /** Hybrid backend (requires a running server). Quick start: pip install \"opendataloader-pdf[hybrid]\" && opendataloader-pdf-hybrid --port 5002. For remote servers use --hybrid-url. Values: off (default), docling-fast. Ignored when --use-struct-tree is set on a tagged PDF (structure tree takes precedence) */\n hybrid?: string;\n /** Hybrid triage mode. Values: auto (default, dynamic triage), full (skip triage, all pages to backend) */\n hybridMode?: string;\n /** Hybrid backend server URL (overrides default) */\n hybridUrl?: string;\n /** Hybrid backend request timeout in milliseconds (0 = use the backend's own default). Default: 0 */\n hybridTimeout?: string;\n /** Maximum number of pages to send to the hybrid backend in a single request. Large documents are split into batches of this size; smaller values increase the number of backend requests (the full PDF is re-sent per batch). Default: 50 */\n hybridChunkSize?: string;\n /** Opt in to Java fallback on hybrid backend error (default: disabled) */\n hybridFallback?: boolean;\n /** Write output to stdout instead of file (single format only) */\n toStdout?: boolean;\n /** Number of worker threads for per-page processing. Default: 1 (sequential, stable). Values >1 (experimental) run pages in parallel for faster throughput; output may vary slightly on some PDFs. Capped at the number of available CPU cores. Applies to the native Java pipeline only; ignored in --hybrid mode */\n threads?: string;\n /** Set the rendering resolution for images in DPI. Higher values improve image quality but increase memory consumption; lower values reduce memory usage at the cost of detail. Accepts positive decimal DPI values (e.g., 144.0). Default: 144.0. */\n imageResolution?: string;\n /** Set the ratio used to calculate the automatic space-insertion threshold (threshold = space-ratio * font size). If the horizontal gap between two adjacent symbols exceeds this threshold, an extra space is inserted to text value. Accepts decimals (e.g., 0.17). Default: 0.17 */\n spaceRatio?: string;\n /** Path to a JSON file of sanitization rules. Only the rules of the file run, in place of the built-in rules. Turns on --sanitize */\n sanitizeRules?: string;\n /** Write the URI links of the PDF (http, https, mailto) as links in Markdown and HTML output. No links with --sanitize, or when the hybrid backend makes the text */\n includeLinks?: boolean;\n /** Time in milliseconds that the availability check of the hybrid backend waits to connect, and then again for the answer. Raise it for a backend with a slow start, such as a serverless one. Default: 3000 */\n hybridAvailabilityTimeout?: string;\n /** With --hybrid, write the triage decision of each page (Java or backend, the confidence, and the signals) to triage/<name>.json in the output folder */\n hybridTriageLog?: boolean;\n}\n\n/**\n * Options as parsed from CLI (all values are strings from commander).\n */\nexport interface CliOptions {\n outputDir?: string;\n password?: string;\n format?: string;\n quiet?: boolean;\n contentSafetyOff?: string;\n sanitize?: boolean;\n keepLineBreaks?: boolean;\n replaceInvalidChars?: string;\n useStructTree?: boolean;\n tableMethod?: string;\n readingOrder?: string;\n markdownPageSeparator?: string;\n markdownWithHtml?: boolean;\n textPageSeparator?: string;\n htmlPageSeparator?: string;\n imageOutput?: string;\n imageFormat?: string;\n imageDir?: string;\n pages?: string;\n includeHeaderFooter?: boolean;\n detectStrikethrough?: boolean;\n hybrid?: string;\n hybridMode?: string;\n hybridUrl?: string;\n hybridTimeout?: string;\n hybridChunkSize?: string;\n hybridFallback?: boolean;\n toStdout?: boolean;\n threads?: string;\n imageResolution?: string;\n spaceRatio?: string;\n sanitizeRules?: string;\n includeLinks?: boolean;\n hybridAvailabilityTimeout?: string;\n hybridTriageLog?: boolean;\n}\n\n/**\n * Convert CLI options to ConvertOptions.\n */\nexport function buildConvertOptions(cliOptions: CliOptions): ConvertOptions {\n const convertOptions: ConvertOptions = {};\n\n if (cliOptions.outputDir) {\n convertOptions.outputDir = cliOptions.outputDir;\n }\n if (cliOptions.password) {\n convertOptions.password = cliOptions.password;\n }\n if (cliOptions.format) {\n convertOptions.format = cliOptions.format;\n }\n if (cliOptions.quiet) {\n convertOptions.quiet = true;\n }\n if (cliOptions.contentSafetyOff) {\n convertOptions.contentSafetyOff = cliOptions.contentSafetyOff;\n }\n if (cliOptions.sanitize) {\n convertOptions.sanitize = true;\n }\n if (cliOptions.keepLineBreaks) {\n convertOptions.keepLineBreaks = true;\n }\n if (cliOptions.replaceInvalidChars) {\n convertOptions.replaceInvalidChars = cliOptions.replaceInvalidChars;\n }\n if (cliOptions.useStructTree) {\n convertOptions.useStructTree = true;\n }\n if (cliOptions.tableMethod) {\n convertOptions.tableMethod = cliOptions.tableMethod;\n }\n if (cliOptions.readingOrder) {\n convertOptions.readingOrder = cliOptions.readingOrder;\n }\n if (cliOptions.markdownPageSeparator) {\n convertOptions.markdownPageSeparator = cliOptions.markdownPageSeparator;\n }\n if (cliOptions.markdownWithHtml) {\n convertOptions.markdownWithHtml = true;\n }\n if (cliOptions.textPageSeparator) {\n convertOptions.textPageSeparator = cliOptions.textPageSeparator;\n }\n if (cliOptions.htmlPageSeparator) {\n convertOptions.htmlPageSeparator = cliOptions.htmlPageSeparator;\n }\n if (cliOptions.imageOutput) {\n convertOptions.imageOutput = cliOptions.imageOutput;\n }\n if (cliOptions.imageFormat) {\n convertOptions.imageFormat = cliOptions.imageFormat;\n }\n if (cliOptions.imageDir) {\n convertOptions.imageDir = cliOptions.imageDir;\n }\n if (cliOptions.pages) {\n convertOptions.pages = cliOptions.pages;\n }\n if (cliOptions.includeHeaderFooter) {\n convertOptions.includeHeaderFooter = true;\n }\n if (cliOptions.detectStrikethrough) {\n convertOptions.detectStrikethrough = true;\n }\n if (cliOptions.hybrid) {\n convertOptions.hybrid = cliOptions.hybrid;\n }\n if (cliOptions.hybridMode) {\n convertOptions.hybridMode = cliOptions.hybridMode;\n }\n if (cliOptions.hybridUrl) {\n convertOptions.hybridUrl = cliOptions.hybridUrl;\n }\n if (cliOptions.hybridTimeout) {\n convertOptions.hybridTimeout = cliOptions.hybridTimeout;\n }\n if (cliOptions.hybridChunkSize) {\n convertOptions.hybridChunkSize = cliOptions.hybridChunkSize;\n }\n if (cliOptions.hybridFallback) {\n convertOptions.hybridFallback = true;\n }\n if (cliOptions.toStdout) {\n convertOptions.toStdout = true;\n }\n if (cliOptions.threads) {\n convertOptions.threads = cliOptions.threads;\n }\n if (cliOptions.imageResolution) {\n convertOptions.imageResolution = cliOptions.imageResolution;\n }\n if (cliOptions.spaceRatio) {\n convertOptions.spaceRatio = cliOptions.spaceRatio;\n }\n if (cliOptions.sanitizeRules !== undefined && cliOptions.sanitizeRules !== null) {\n convertOptions.sanitizeRules = cliOptions.sanitizeRules;\n }\n if (cliOptions.includeLinks) {\n convertOptions.includeLinks = true;\n }\n if (cliOptions.hybridAvailabilityTimeout) {\n convertOptions.hybridAvailabilityTimeout = cliOptions.hybridAvailabilityTimeout;\n }\n if (cliOptions.hybridTriageLog) {\n convertOptions.hybridTriageLog = true;\n }\n\n return convertOptions;\n}\n\n/**\n * Build CLI arguments array from ConvertOptions.\n */\nexport function buildArgs(options: ConvertOptions): string[] {\n const args: string[] = [];\n\n if (options.outputDir) {\n args.push('--output-dir', options.outputDir);\n }\n if (options.password) {\n args.push('--password', options.password);\n }\n if (options.format) {\n if (Array.isArray(options.format)) {\n if (options.format.length > 0) {\n args.push('--format', options.format.join(','));\n }\n } else {\n args.push('--format', options.format);\n }\n }\n if (options.quiet) {\n args.push('--quiet');\n }\n if (options.contentSafetyOff) {\n if (Array.isArray(options.contentSafetyOff)) {\n if (options.contentSafetyOff.length > 0) {\n args.push('--content-safety-off', options.contentSafetyOff.join(','));\n }\n } else {\n args.push('--content-safety-off', options.contentSafetyOff);\n }\n }\n if (options.sanitize) {\n args.push('--sanitize');\n }\n if (options.keepLineBreaks) {\n args.push('--keep-line-breaks');\n }\n if (options.replaceInvalidChars) {\n args.push('--replace-invalid-chars', options.replaceInvalidChars);\n }\n if (options.useStructTree) {\n args.push('--use-struct-tree');\n }\n if (options.tableMethod) {\n args.push('--table-method', options.tableMethod);\n }\n if (options.readingOrder) {\n args.push('--reading-order', options.readingOrder);\n }\n if (options.markdownPageSeparator) {\n args.push('--markdown-page-separator', options.markdownPageSeparator);\n }\n if (options.markdownWithHtml) {\n args.push('--markdown-with-html');\n }\n if (options.textPageSeparator) {\n args.push('--text-page-separator', options.textPageSeparator);\n }\n if (options.htmlPageSeparator) {\n args.push('--html-page-separator', options.htmlPageSeparator);\n }\n if (options.imageOutput) {\n args.push('--image-output', options.imageOutput);\n }\n if (options.imageFormat) {\n args.push('--image-format', options.imageFormat);\n }\n if (options.imageDir) {\n args.push('--image-dir', options.imageDir);\n }\n if (options.pages) {\n args.push('--pages', options.pages);\n }\n if (options.includeHeaderFooter) {\n args.push('--include-header-footer');\n }\n if (options.detectStrikethrough) {\n args.push('--detect-strikethrough');\n }\n if (options.hybrid) {\n args.push('--hybrid', options.hybrid);\n }\n if (options.hybridMode) {\n args.push('--hybrid-mode', options.hybridMode);\n }\n if (options.hybridUrl) {\n args.push('--hybrid-url', options.hybridUrl);\n }\n if (options.hybridTimeout) {\n args.push('--hybrid-timeout', options.hybridTimeout);\n }\n if (options.hybridChunkSize) {\n args.push('--hybrid-chunk-size', options.hybridChunkSize);\n }\n if (options.hybridFallback) {\n args.push('--hybrid-fallback');\n }\n if (options.toStdout) {\n args.push('--to-stdout');\n }\n if (options.threads) {\n args.push('--threads', options.threads);\n }\n if (options.imageResolution) {\n args.push('--image-resolution', options.imageResolution);\n }\n if (options.spaceRatio) {\n args.push('--space-ratio', options.spaceRatio);\n }\n if (options.sanitizeRules !== undefined && options.sanitizeRules !== null) {\n args.push('--sanitize-rules', options.sanitizeRules);\n }\n if (options.includeLinks) {\n args.push('--include-links');\n }\n if (options.hybridAvailabilityTimeout) {\n args.push('--hybrid-availability-timeout', options.hybridAvailabilityTimeout);\n }\n if (options.hybridTriageLog) {\n args.push('--hybrid-triage-log');\n }\n\n return args;\n}\n"],"mappings":"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","names":["__filename","__dirname"]}
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendataloader/pdf",
3
- "version": "2.5.15",
3
+ "version": "2.5.17",
4
4
  "description": "A Node.js wrapper for the opendataloader-pdf Java CLI.",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -57,8 +57,8 @@
57
57
  "prettier": "^3.9.6",
58
58
  "tsup": "^8.5.1",
59
59
  "typescript": "^6.0.3",
60
- "vite": "^8.3.0",
61
- "vitest": "^5.0.0"
60
+ "vite": "^8.3.5",
61
+ "vitest": "^5.0.5"
62
62
  },
63
63
  "files": [
64
64
  "dist",