docling-serve-client 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -2,18 +2,18 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/core/validate.ts", "../src/images.ts", "../src/core/result.ts", "../src/capabilities.ts", "../src/core/http.ts", "../src/core/pdf.ts", "../src/core/input.ts", "../src/options.ts", "../src/response.ts", "../src/client.ts"],
4
4
  "sourcesContent": [
5
- "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Accepts or rejects one option value. */\nexport type OptionRule = (value: unknown) => boolean;\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Error message when options argument is provided but is not a plain object. */\nexport const OPTIONS_OBJECT_EXPECTED = 'Invalid options: expected an object';\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Checks every key of `input` against its rule**.\n *\n * - unsupported options throw `TypeError` even if their value is `undefined`\n * - `undefined` values for supported options are skipped, as if the key were missing\n * - arrays are copied, so later changes by the caller do not reach the resolved options\n * - `namePrefix` names nested options in messages, e.g. `imageOptions.`\n * @throws `TypeError` on unsupported option or invalid value.\n */\nexport function validateKeys<T extends object>(\n input: Record<string, unknown>,\n rules: Record<keyof T, OptionRule>,\n namePrefix = '',\n): Partial<T> {\n const valid: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(input)) {\n const rule: OptionRule | undefined = Object.hasOwn(rules, name) ? rules[name as keyof T] : undefined;\n if (rule === undefined) {\n throw new TypeError(notSupported(`${namePrefix}${name}`));\n }\n if (value === undefined) {\n continue;\n }\n if (!rule(value)) {\n throw new TypeError(invalidValue(`${namePrefix}${name}`));\n }\n valid[name] = Array.isArray(value) ? [...value] : value;\n }\n // Every key was checked against its rule above.\n return valid as Partial<T>;\n}\n\n/** Formats error message for an unsupported option. */\nexport function notSupported(name: string): string {\n return `Option \"${name}\" is not supported`;\n}\n\n/** Formats error message for a rejected option value. */\nexport function invalidValue(name: string): string {\n return `Invalid value for option \"${name}\"`;\n}\n\n/**\n * **Object literal, `JSON.parse` result or `Object.create(null)`**.\n *\n * - rejects arrays, `Map`, `Date`, class instances and objects from another realm\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\n/** Returns true for boolean primitives (`true` or `false`). */\nexport function isBoolean(value: unknown): value is boolean {\n return value === true || value === false;\n}\n\n/** Returns true when string belongs to allowed set. */\nexport function isOneOf<T extends string>(value: unknown, allowed: readonly T[]): value is T {\n return typeof value === 'string' && (allowed as readonly string[]).includes(value);\n}\n",
6
- "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { isPlainObject } from './core/validate.js';\nimport type { BoundingBox, DoclingDocument, PageItem } from './document.js';\nimport type {\n ExtractedImage,\n ImageOptions,\n ImageSize,\n ImageWarning,\n PageImage,\n PageImageBox,\n PageImageWarning,\n} from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Rewritten md, extracted image files, and `image_not_decoded` warnings. */\nexport type ExtractedMarkdown = {\n markdown: string;\n images: ExtractedImage[];\n warnings: ImageWarning[];\n};\n\n/** Document with decoded `pages[].image` set to `null`, the decoded page images and `page_image_not_decoded` warnings. */\nexport type ExtractedPageImages = {\n document: DoclingDocument;\n pageImages: PageImage[];\n warnings: PageImageWarning[];\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/**\n * **Pixels per PDF point of pictures and page images**: `images_scale` (144 dpi).\n *\n * - fixed, so page images and `toPageImageBox` always agree\n * - docling-serve's default and its maximum (`max_images_scale`); OCR runs at its own scale and is not affected\n */\nexport const PAGE_IMAGE_SCALE = 2;\n\n/** docling's md comment for a picture without image data. */\nconst IMAGE_PLACEHOLDER = '<!-- image -->';\n\n/** Internal marker for images dropped by `extractImages`; NUL never occurs in docling md. */\nconst OMITTED_IMAGE = '\\u0000omitted-image\\u0000';\n\n/** Matches embedded base64 image links `![alt](data:image/...;base64,...)`; any data up to `)`, validated on decode. */\nconst MATCH_EMBEDDED_IMAGE = /!\\[([^\\]]*)\\]\\(data:(image\\/[\\w.+-]+);base64,([^)]*)\\)/g;\n\n/** Matches a whole base64 image data URI; group 1: MIME type, group 2: data (any, validated on decode). */\nconst MATCH_DATA_URI = /^data:(image\\/[\\w.+-]+);base64,([\\s\\S]*)$/;\n\n/** PNG file signature, followed by the IHDR chunk length. */\nconst PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];\n\n/** Chunk type `IHDR` at offsets 12 to 15 of a PNG. */\nconst PNG_IHDR = [0x49, 0x48, 0x44, 0x52];\n\n/** Matches whitespace that docling may wrap base64 data with. */\nconst MATCH_WHITESPACE = /\\s+/g;\n\n/** File extension per lowercase MIME subtype; any other subtype gets `bin`. */\nconst IMAGE_EXTENSIONS: ReadonlyMap<string, string> = new Map([\n ['png', 'png'],\n ['jpeg', 'jpg'],\n ['jpg', 'jpg'],\n ['gif', 'gif'],\n ['webp', 'webp'],\n ['svg+xml', 'svg'],\n ['tiff', 'tiff'],\n ['bmp', 'bmp'],\n]);\n\n/** Extension for MIME subtypes missing from `IMAGE_EXTENSIONS`. */\nconst UNKNOWN_EXTENSION = 'bin';\n\n/** Min pixel area of a figure. */\nconst MIN_FIGURE_AREA = 15_000;\n\n/** Min length of a figure's longer side in pixels. */\nconst MIN_FIGURE_LONG_SIDE = 200;\n\n/** Min length of a figure's shorter side in pixels. */\nconst MIN_FIGURE_SHORT_SIDE = 24;\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Size heuristic behind `omitSmall`**: icons, bullets, small logos and thin rules count as small.\n *\n * - small: area below 15 000 px, longer side below 200 px, or shorter side below 24 px\n * - works on `ExtractedImage` and on `pictures[].image.size` of a DoclingDocument\n * - `false` when width or height is not a finite number\n */\nexport function isSmallImage(size: ImageSize): boolean {\n const { width, height } = (size ?? {}) as Partial<ImageSize>;\n if (!Number.isFinite(width) || !Number.isFinite(height)) {\n return false;\n }\n const [w, h] = [width as number, height as number];\n return w * h < MIN_FIGURE_AREA || Math.max(w, h) < MIN_FIGURE_LONG_SIDE || Math.min(w, h) < MIN_FIGURE_SHORT_SIDE;\n}\n\n/** Reads pixel size from PNG IHDR chunk; returns `undefined` for non-PNG or truncated data. */\nexport function readPngSize(bytes: Uint8Array): ImageSize | undefined {\n if (!(bytes instanceof Uint8Array) || bytes.length < 24) {\n return undefined;\n }\n // IHDR holds 32-bit width and height at offsets 16 and 20.\n const isPng =\n PNG_SIGNATURE.every((byte, i) => bytes[i] === byte) && PNG_IHDR.every((byte, i) => bytes[12 + i] === byte);\n if (!isPng) {\n return undefined;\n }\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n return { width: view.getUint32(16), height: view.getUint32(20) };\n}\n\n/**\n * **Extracts base64 images into raw bytes and replaces them with file links**.\n *\n * - links: `<prefix><n>.<ext>`, numbered over kept images only; extension mapped from the MIME subtype\n * - small images (with `omitSmall`) and undecodable images are removed like placeholders\n * - undecodable image: `image_not_decoded` warning with its 1-based index among all embedded images\n * - docling's own `<!-- image -->` placeholders (pictures sent without data) are kept\n */\nexport function extractImages(markdown: string, options: Required<ImageOptions>): ExtractedMarkdown {\n const images: ExtractedImage[] = [];\n const warnings: ImageWarning[] = [];\n let output = '';\n let copiedUpTo = 0;\n let index = 0;\n for (const match of markdown.matchAll(MATCH_EMBEDDED_IMAGE)) {\n const [token, alt = '', mimeType = '', base64 = ''] = match;\n index++;\n output += markdown.slice(copiedUpTo, match.index);\n copiedUpTo = match.index + token.length;\n const bytes = decodeBase64(base64);\n if (bytes === undefined) {\n warnings.push({\n code: 'image_not_decoded',\n message: `Embedded image ${index} has invalid or empty base64 data and was removed`,\n details: { index },\n });\n output += OMITTED_IMAGE;\n continue;\n }\n const size = readPngSize(bytes);\n if (options.omitSmall && size !== undefined && isSmallImage(size)) {\n // Marker, so removing it below also normalizes surrounding blank lines.\n output += OMITTED_IMAGE;\n continue;\n }\n const { width, height } = size ?? { width: 0, height: 0 };\n const subtype = mimeType.slice('image/'.length).toLowerCase();\n const extension = IMAGE_EXTENSIONS.get(subtype) ?? UNKNOWN_EXTENSION;\n const path = `${options.prefix}${images.length + 1}.${extension}`;\n images.push({ path, mimeType, bytes, width, height });\n output += `![${alt}](${path})`;\n }\n output += markdown.slice(copiedUpTo);\n return { markdown: removeMarkerLines(output, OMITTED_IMAGE), images, warnings };\n}\n\n/**\n * **Moves page images out of the DoclingDocument into raw bytes**.\n *\n * - every decoded `pages[].image` becomes `null`; the input document is not changed\n * - page number from `page_no`, else from the `pages` key; result sorted by page\n * - a URI that is not a base64 image data URI, or has invalid or empty data: `page_image_not_decoded` warning,\n * and the page keeps its `image` as sent\n * - a document without a `pages` object is returned as it is\n */\nexport function extractPageImages(document: DoclingDocument): ExtractedPageImages {\n const pages: unknown = document.pages;\n if (!isPlainObject(pages)) {\n return { document, pageImages: [], warnings: [] };\n }\n const pageImages: PageImage[] = [];\n const warnings: PageImageWarning[] = [];\n const strippedPages: Record<string, PageItem> = {};\n for (const [key, page] of Object.entries(pages)) {\n strippedPages[key] = page as PageItem;\n if (!isPlainObject(page) || page.image == null) {\n continue;\n }\n const pageNo = Number.isInteger(page.page_no) ? (page.page_no as number) : Number(key);\n const image = (isPlainObject(page.image) ? page.image : {}) as Partial<NonNullable<PageItem['image']>>;\n const [, mimeType = '', base64 = ''] = MATCH_DATA_URI.exec(String(image.uri)) ?? [];\n const bytes = decodeBase64(base64);\n if (bytes === undefined) {\n warnings.push({\n code: 'page_image_not_decoded',\n message: `Page image of page ${pageNo} is not a base64 image data URI or has invalid or empty data`,\n details: { page: pageNo },\n });\n continue;\n }\n strippedPages[key] = { ...page, image: null } as PageItem;\n const { width, height } = readPngSize(bytes) ?? readImageSize(image.size) ?? { width: 0, height: 0 };\n const dpi = typeof image.dpi === 'number' && Number.isFinite(image.dpi) ? image.dpi : 0;\n pageImages.push({ page: pageNo, mimeType, width, height, dpi, bytes });\n }\n pageImages.sort((a, b) => a.page - b.page);\n return { document: { ...document, pages: strippedPages }, pageImages, warnings };\n}\n\n/**\n * **Maps a docling bounding box onto its page image, in pixels with a top-left origin**.\n *\n * - `prov`: any `prov[]` entry; for a table cell pass `{ page_no: table.prov[0].page_no, bbox: cell.bbox }`\n * - flips `BOTTOMLEFT` boxes using the page height from `document.pages`, then scales points by `PAGE_IMAGE_SCALE`\n * - works without `pageImages: true`; the boxes fit the page images of any conversion by this client\n * - returns `undefined` when `page_no` or coordinate is not a finite number, or page is missing from `document.pages`\n */\nexport function toPageImageBox(\n document: DoclingDocument,\n prov: { page_no: number; bbox?: BoundingBox | null },\n): PageImageBox | undefined {\n const pageNo = prov?.page_no;\n if (!isFiniteNumber(pageNo)) {\n return undefined;\n }\n const pages: unknown = document?.pages;\n const page: unknown = isPlainObject(pages) ? pages[String(pageNo)] : undefined;\n const size: unknown = isPlainObject(page) ? page.size : undefined;\n const bbox: unknown = prov?.bbox;\n if (!isPlainObject(size) || !isPlainObject(bbox)) {\n return undefined;\n }\n const { l, t, r, b } = bbox;\n const pageHeight = size.height;\n const isValid =\n isFiniteNumber(l) && isFiniteNumber(t) && isFiniteNumber(r) && isFiniteNumber(b) && isFiniteNumber(pageHeight);\n if (!isValid) {\n return undefined;\n }\n const [top, bottom] = bbox.coord_origin === 'BOTTOMLEFT' ? [pageHeight - t, pageHeight - b] : [t, b];\n return {\n page: pageNo,\n x: Math.min(l, r) * PAGE_IMAGE_SCALE,\n y: Math.min(top, bottom) * PAGE_IMAGE_SCALE,\n width: Math.abs(r - l) * PAGE_IMAGE_SCALE,\n height: Math.abs(bottom - top) * PAGE_IMAGE_SCALE,\n };\n}\n\n/**\n * **Removes `<!-- image -->` placeholders**.\n *\n * - a placeholder line goes; blank lines separating the text around it stay, without leaving a blank-line run\n * - a placeholder inside a line is cut out of it\n */\nexport function removeImagePlaceholders(markdown: string): string {\n return removeMarkerLines(markdown, IMAGE_PLACEHOLDER);\n}\n\n// -------------------------------------------------------------------\n// --- 4. Internal Functions\n// -------------------------------------------------------------------\n\n/**\n * **Decodes base64 into a plain `Uint8Array`**.\n *\n * - `Buffer.from` ignores whitespace and stops at the first invalid character or inner `=`\n * - valid only when decoded length equals `floor(length * 3 / 4) - padding` of stripped input\n * - small buffers come from Node's shared pool and are copied, so `bytes.buffer` holds this image only\n * - returns `undefined` for invalid or empty base64\n */\nfunction decodeBase64(base64: string): Uint8Array | undefined {\n const stripped = base64.replace(MATCH_WHITESPACE, '');\n if (stripped.length % 4 === 1) {\n return undefined;\n }\n const padding = stripped.endsWith('==') ? 2 : stripped.endsWith('=') ? 1 : 0;\n const decoded = Buffer.from(stripped, 'base64');\n if (decoded.length === 0 || decoded.length !== Math.floor((stripped.length * 3) / 4) - padding) {\n return undefined;\n }\n const isOwnBuffer = decoded.byteOffset === 0 && decoded.buffer.byteLength === decoded.length;\n return isOwnBuffer ? new Uint8Array(decoded.buffer, 0, decoded.length) : new Uint8Array(decoded);\n}\n\n/**\n * **Removes `marker` from md, normalizing blank lines around marker-only lines**.\n *\n * - marker-only line: dropped; one neighbouring blank line goes only when blank lines are left on both sides,\n * or at the start or end of the md, so paragraphs stay separated\n * - marker inside a line: cut out of it\n */\nfunction removeMarkerLines(markdown: string, marker: string): string {\n if (!markdown.includes(marker)) {\n return markdown;\n }\n const lines = markdown.split('\\n');\n const kept: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? '';\n if (line.trim() !== marker) {\n kept.push(line.replaceAll(marker, ''));\n continue;\n }\n const previous = kept.at(-1);\n const next = lines[i + 1];\n if (isBlank(next) && (previous === undefined || isBlank(previous))) {\n i++;\n } else if (next === undefined && isBlank(previous)) {\n kept.pop();\n }\n }\n return kept.join('\\n');\n}\n\n/** Size with finite width and height; `undefined` otherwise. */\nfunction readImageSize(size: unknown): ImageSize | undefined {\n if (!isPlainObject(size) || !Number.isFinite(size.width) || !Number.isFinite(size.height)) {\n return undefined;\n }\n return { width: size.width as number, height: size.height as number };\n}\n\n/** Number other than `NaN` and `±Infinity`. */\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\n/** Defined and whitespace-only line. */\nfunction isBlank(line: string | undefined): boolean {\n return line !== undefined && line.trim() === '';\n}\n",
5
+ "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Accepts or rejects one option value. */\nexport type OptionRule = (value: unknown) => boolean;\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Error message when options argument is provided but is not a plain object. */\nexport const OPTIONS_OBJECT_EXPECTED = 'Invalid options: expected an object';\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Checks every key of `input` against its rule**.\n *\n * - unsupported options throw `TypeError` even if their value is `undefined`\n * - `undefined` values for supported options are skipped, as if the key were missing\n * - arrays are copied, so later changes by the caller do not reach the resolved options\n * - `namePrefix` names nested options in messages, e.g. `imageOptions.`\n * @throws `TypeError` on unsupported option or invalid value.\n */\nexport function validateKeys<T extends object>(\n input: Record<string, unknown>,\n rules: Record<keyof T, OptionRule>,\n namePrefix = '',\n): Partial<T> {\n const valid: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(input)) {\n const rule: OptionRule | undefined = Object.hasOwn(rules, name) ? rules[name as keyof T] : undefined;\n if (rule === undefined) {\n throw new TypeError(notSupported(`${namePrefix}${name}`));\n }\n if (value === undefined) {\n continue;\n }\n if (!rule(value)) {\n throw new TypeError(invalidValue(`${namePrefix}${name}`));\n }\n valid[name] = Array.isArray(value) ? [...value] : value;\n }\n return valid as Partial<T>;\n}\n\n/** Formats error message for an unsupported option. */\nexport function notSupported(name: string): string {\n return `Option \"${name}\" is not supported`;\n}\n\n/** Formats error message for a rejected option value. */\nexport function invalidValue(name: string): string {\n return `Invalid value for option \"${name}\"`;\n}\n\n/**\n * **Object literal, `JSON.parse` result or `Object.create(null)`**.\n *\n * - rejects arrays, `Map`, `Date`, class instances and objects from another realm\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\n/** Returns true for boolean primitives (`true` or `false`). */\nexport function isBoolean(value: unknown): value is boolean {\n return value === true || value === false;\n}\n\n/** Returns true when string belongs to allowed set. */\nexport function isOneOf<T extends string>(value: unknown, allowed: readonly T[]): value is T {\n return typeof value === 'string' && (allowed as readonly string[]).includes(value);\n}\n",
6
+ "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { isPlainObject } from './core/validate.js';\nimport type { BoundingBox, DoclingDocument, PageItem } from './document.js';\nimport type {\n ExtractedImage,\n ImageOptions,\n ImageSize,\n ImageWarning,\n PageImage,\n PageImageBox,\n PageImageWarning,\n} from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Rewritten md, extracted image files, and `image_not_decoded` warnings. */\nexport type ExtractedMarkdown = {\n markdown: string;\n images: ExtractedImage[];\n warnings: ImageWarning[];\n};\n\n/** Document with decoded `pages[].image` set to `null`, the decoded page images and `page_image_not_decoded` warnings. */\nexport type ExtractedPageImages = {\n document: DoclingDocument;\n pageImages: PageImage[];\n warnings: PageImageWarning[];\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/**\n * **Pixels per PDF point of pictures and page images**: `images_scale` (144 dpi).\n *\n * - fixed, so page images and `toPageImageBox` always agree\n * - docling-serve's default and its maximum (`max_images_scale`); OCR runs at its own scale and is not affected\n */\nexport const PAGE_IMAGE_SCALE = 2;\n\n/** docling's md comment for a picture without image data. */\nconst IMAGE_PLACEHOLDER = '<!-- image -->';\n\n/** Internal marker for images dropped by `extractImages`; NUL never occurs in docling md. */\nconst OMITTED_IMAGE = '\\u0000omitted-image\\u0000';\n\n/** Matches embedded base64 image links `![alt](data:image/...;base64,...)`; any data up to `)`, validated on decode. */\nconst MATCH_EMBEDDED_IMAGE = /!\\[([^\\]]*)\\]\\(data:(image\\/[\\w.+-]+);base64,([^)]*)\\)/g;\n\n/** Matches a whole base64 image data URI; group 1: MIME type, group 2: data (any, validated on decode). */\nconst MATCH_DATA_URI = /^data:(image\\/[\\w.+-]+);base64,([\\s\\S]*)$/;\n\n/** PNG file signature, followed by the IHDR chunk length. */\nconst PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];\n\n/** Chunk type `IHDR` at offsets 12 to 15 of a PNG. */\nconst PNG_IHDR = [0x49, 0x48, 0x44, 0x52];\n\n/** Matches whitespace that docling may wrap base64 data with. */\nconst MATCH_WHITESPACE = /\\s+/g;\n\n/** File extension per lowercase MIME subtype; any other subtype gets `bin`. */\nconst IMAGE_EXTENSIONS: ReadonlyMap<string, string> = new Map([\n ['png', 'png'],\n ['jpeg', 'jpg'],\n ['jpg', 'jpg'],\n ['gif', 'gif'],\n ['webp', 'webp'],\n ['svg+xml', 'svg'],\n ['tiff', 'tiff'],\n ['bmp', 'bmp'],\n]);\n\n/** Extension for MIME subtypes missing from `IMAGE_EXTENSIONS`. */\nconst UNKNOWN_EXTENSION = 'bin';\n\n/** Min pixel area of a figure. */\nconst MIN_FIGURE_AREA = 15_000;\n\n/** Min length of a figure's longer side in pixels. */\nconst MIN_FIGURE_LONG_SIDE = 200;\n\n/** Min length of a figure's shorter side in pixels. */\nconst MIN_FIGURE_SHORT_SIDE = 24;\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Size heuristic behind `omitSmall`**: icons, bullets, small logos and thin rules count as small.\n *\n * - small: area below 15 000 px, longer side below 200 px, or shorter side below 24 px\n * - works on `ExtractedImage` and on `pictures[].image.size` of a DoclingDocument\n * - `false` when width or height is not a finite number\n */\nexport function isSmallImage(size: ImageSize): boolean {\n const { width, height } = (size ?? {}) as Partial<ImageSize>;\n if (!Number.isFinite(width) || !Number.isFinite(height)) {\n return false;\n }\n const [w, h] = [width as number, height as number];\n return w * h < MIN_FIGURE_AREA || Math.max(w, h) < MIN_FIGURE_LONG_SIDE || Math.min(w, h) < MIN_FIGURE_SHORT_SIDE;\n}\n\n/** Reads pixel size from PNG IHDR chunk; returns `undefined` for non-PNG or truncated data. */\nexport function readPngSize(bytes: Uint8Array): ImageSize | undefined {\n if (!(bytes instanceof Uint8Array) || bytes.length < 24) {\n return undefined;\n }\n const isPng =\n PNG_SIGNATURE.every((byte, i) => bytes[i] === byte) && PNG_IHDR.every((byte, i) => bytes[12 + i] === byte);\n if (!isPng) {\n return undefined;\n }\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n return { width: view.getUint32(16), height: view.getUint32(20) };\n}\n\n/**\n * **Extracts base64 images into raw bytes and replaces them with file links**.\n *\n * - links: `<prefix><n>.<ext>`, numbered over kept images only; extension mapped from the MIME subtype\n * - small images (with `omitSmall`) and undecodable images are removed like placeholders\n * - undecodable image: `image_not_decoded` warning with its 1-based index among all embedded images\n * - docling's own `<!-- image -->` placeholders (pictures sent without data) are kept\n */\nexport function extractImages(markdown: string, options: Required<ImageOptions>): ExtractedMarkdown {\n const images: ExtractedImage[] = [];\n const warnings: ImageWarning[] = [];\n let output = '';\n let copiedUpTo = 0;\n let index = 0;\n for (const match of markdown.matchAll(MATCH_EMBEDDED_IMAGE)) {\n const [token, alt = '', mimeType = '', base64 = ''] = match;\n index++;\n output += markdown.slice(copiedUpTo, match.index);\n copiedUpTo = match.index + token.length;\n const bytes = decodeBase64(base64);\n if (bytes === undefined) {\n warnings.push({\n code: 'image_not_decoded',\n message: `Embedded image ${index} has invalid or empty base64 data and was removed`,\n details: { index },\n });\n output += OMITTED_IMAGE;\n continue;\n }\n const size = readPngSize(bytes);\n if (options.omitSmall && size !== undefined && isSmallImage(size)) {\n output += OMITTED_IMAGE;\n continue;\n }\n const { width, height } = size ?? { width: 0, height: 0 };\n const subtype = mimeType.slice('image/'.length).toLowerCase();\n const extension = IMAGE_EXTENSIONS.get(subtype) ?? UNKNOWN_EXTENSION;\n const path = `${options.prefix}${images.length + 1}.${extension}`;\n images.push({ path, mimeType, bytes, width, height });\n output += `![${alt}](${path})`;\n }\n output += markdown.slice(copiedUpTo);\n return { markdown: removeMarkerLines(output, OMITTED_IMAGE), images, warnings };\n}\n\n/**\n * **Moves page images out of the DoclingDocument into raw bytes**.\n *\n * - every decoded `pages[].image` becomes `null`; the input document is not changed\n * - page number from `page_no`, else from the `pages` key; result sorted by page\n * - a URI that is not a base64 image data URI, or has invalid or empty data: `page_image_not_decoded` warning,\n * and the page keeps its `image` as sent\n * - a document without a `pages` object is returned as it is\n */\nexport function extractPageImages(document: DoclingDocument): ExtractedPageImages {\n const pages: unknown = document.pages;\n if (!isPlainObject(pages)) {\n return { document, pageImages: [], warnings: [] };\n }\n const pageImages: PageImage[] = [];\n const warnings: PageImageWarning[] = [];\n const strippedPages: Record<string, PageItem> = {};\n for (const [key, page] of Object.entries(pages)) {\n strippedPages[key] = page as PageItem;\n if (!isPlainObject(page) || page.image == null) {\n continue;\n }\n const pageNo = Number.isInteger(page.page_no) ? (page.page_no as number) : Number(key);\n const image = (isPlainObject(page.image) ? page.image : {}) as Partial<NonNullable<PageItem['image']>>;\n const [, mimeType = '', base64 = ''] = MATCH_DATA_URI.exec(String(image.uri)) ?? [];\n const bytes = decodeBase64(base64);\n if (bytes === undefined) {\n warnings.push({\n code: 'page_image_not_decoded',\n message: `Page image of page ${pageNo} is not a base64 image data URI or has invalid or empty data`,\n details: { page: pageNo },\n });\n continue;\n }\n strippedPages[key] = { ...page, image: null } as PageItem;\n const { width, height } = readPngSize(bytes) ?? readImageSize(image.size) ?? { width: 0, height: 0 };\n const dpi = typeof image.dpi === 'number' && Number.isFinite(image.dpi) ? image.dpi : 0;\n pageImages.push({ page: pageNo, mimeType, width, height, dpi, bytes });\n }\n pageImages.sort((a, b) => a.page - b.page);\n return { document: { ...document, pages: strippedPages }, pageImages, warnings };\n}\n\n/**\n * **Maps a docling bounding box onto its page image, in pixels with a top-left origin**.\n *\n * - `prov`: any `prov[]` entry; for a table cell pass `{ page_no: table.prov[0].page_no, bbox: cell.bbox }`\n * - flips `BOTTOMLEFT` boxes using the page height from `document.pages`, then scales points by `PAGE_IMAGE_SCALE`\n * - works without `pageImages: true`; the boxes fit the page images of any conversion by this client\n * - returns `undefined` when `page_no` or coordinate is not a finite number, or page is missing from `document.pages`\n */\nexport function toPageImageBox(\n document: DoclingDocument,\n prov: { page_no: number; bbox?: BoundingBox | null },\n): PageImageBox | undefined {\n const pageNo = prov?.page_no;\n if (!isFiniteNumber(pageNo)) {\n return undefined;\n }\n const pages: unknown = document?.pages;\n const page: unknown = isPlainObject(pages) ? pages[String(pageNo)] : undefined;\n const size: unknown = isPlainObject(page) ? page.size : undefined;\n const bbox: unknown = prov?.bbox;\n if (!isPlainObject(size) || !isPlainObject(bbox)) {\n return undefined;\n }\n const { l, t, r, b } = bbox;\n const pageHeight = size.height;\n const isValid =\n isFiniteNumber(l) && isFiniteNumber(t) && isFiniteNumber(r) && isFiniteNumber(b) && isFiniteNumber(pageHeight);\n if (!isValid) {\n return undefined;\n }\n const [top, bottom] = bbox.coord_origin === 'BOTTOMLEFT' ? [pageHeight - t, pageHeight - b] : [t, b];\n return {\n page: pageNo,\n x: Math.min(l, r) * PAGE_IMAGE_SCALE,\n y: Math.min(top, bottom) * PAGE_IMAGE_SCALE,\n width: Math.abs(r - l) * PAGE_IMAGE_SCALE,\n height: Math.abs(bottom - top) * PAGE_IMAGE_SCALE,\n };\n}\n\n/**\n * **Removes `<!-- image -->` placeholders**.\n *\n * - a placeholder line goes; blank lines separating the text around it stay, without leaving a blank-line run\n * - a placeholder inside a line is cut out of it\n */\nexport function removeImagePlaceholders(markdown: string): string {\n return removeMarkerLines(markdown, IMAGE_PLACEHOLDER);\n}\n\n// -------------------------------------------------------------------\n// --- 4. Private Functions\n// -------------------------------------------------------------------\n\n/**\n * **Decodes base64 into a plain `Uint8Array`**.\n *\n * - `Buffer.from` ignores whitespace and stops at the first invalid character or inner `=`\n * - valid only when decoded length equals `floor(length * 3 / 4) - padding` of stripped input\n * - small buffers come from Node's shared pool and are copied, so `bytes.buffer` holds this image only\n * - returns `undefined` for invalid or empty base64\n */\nfunction decodeBase64(base64: string): Uint8Array | undefined {\n const stripped = base64.replace(MATCH_WHITESPACE, '');\n if (stripped.length % 4 === 1) {\n return undefined;\n }\n const padding = stripped.endsWith('==') ? 2 : stripped.endsWith('=') ? 1 : 0;\n const decoded = Buffer.from(stripped, 'base64');\n if (decoded.length === 0 || decoded.length !== Math.floor((stripped.length * 3) / 4) - padding) {\n return undefined;\n }\n const isOwnBuffer = decoded.byteOffset === 0 && decoded.buffer.byteLength === decoded.length;\n return isOwnBuffer ? new Uint8Array(decoded.buffer, 0, decoded.length) : new Uint8Array(decoded);\n}\n\n/**\n * **Removes `marker` from md, normalizing blank lines around marker-only lines**.\n *\n * - marker-only line: dropped; one neighbouring blank line goes only when blank lines are left on both sides,\n * or at the start or end of the md, so paragraphs stay separated\n * - marker inside a line: cut out of it\n */\nfunction removeMarkerLines(markdown: string, marker: string): string {\n if (!markdown.includes(marker)) {\n return markdown;\n }\n const lines = markdown.split('\\n');\n const kept: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? '';\n if (line.trim() !== marker) {\n kept.push(line.replaceAll(marker, ''));\n continue;\n }\n const previous = kept.at(-1);\n const next = lines[i + 1];\n if (isBlank(next) && (previous === undefined || isBlank(previous))) {\n i++;\n } else if (next === undefined && isBlank(previous)) {\n kept.pop();\n }\n }\n return kept.join('\\n');\n}\n\n/** Size with finite width and height; `undefined` otherwise. */\nfunction readImageSize(size: unknown): ImageSize | undefined {\n if (!isPlainObject(size) || !Number.isFinite(size.width) || !Number.isFinite(size.height)) {\n return undefined;\n }\n return { width: size.width as number, height: size.height as number };\n}\n\n/** Number other than `NaN` and `±Infinity`. */\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\n/** Defined and whitespace-only line. */\nfunction isBlank(line: string | undefined): boolean {\n return line !== undefined && line.trim() === '';\n}\n",
7
7
  "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ConversionFailure, ConvertError, Result } from '../types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Error code union inferred from `ERR`. */\nexport type ErrorCode = ReturnType<(typeof ERR)[keyof typeof ERR]>['code'];\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Error factories keyed by domain error code. */\nexport const ERR = {\n /** Input rejected before request: not a valid PDF `Uint8Array`, or invalid job object. */\n INVALID_INPUT: (message: string) => ({ code: 'invalid_input' as const, message }),\n /** Server unreachable (connection refused, DNS, socket reset). */\n NETWORK: (message: string) => ({ code: 'network' as const, message }),\n /** Caller `AbortSignal` or `timeoutMs` fired (including `AbortSignal.timeout()`). */\n ABORTED: (message: string) => ({ code: 'aborted' as const, message }),\n /** Non-2xx response (bad options, auth, 5xx, sync wait exceeded). */\n HTTP: (status: number, detail: string) => ({ code: 'http' as const, message: `HTTP ${status}: ${detail}`, status }),\n /** Job ID unknown to server: expired, restarted, or nonexistent. */\n NOT_FOUND: (message: string) => ({ code: 'not_found' as const, message, status: 404 }),\n /** Document processing failed (corrupt PDF, model failure); `details` holds what the server reported. */\n CONVERSION_FAILED: (reason: string, details: ConversionFailure) => ({\n code: 'conversion_failed' as const,\n message: `Conversion failed (${reason})`,\n details,\n }),\n /** Server answered 2xx with unexpected response body. */\n INVALID_RESPONSE: (message: string, status?: number) =>\n status === undefined\n ? { code: 'invalid_response' as const, message }\n : { code: 'invalid_response' as const, message, status },\n};\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/** Wraps value in `{ ok: true, data }`. */\nexport function ok<T>(data: T): Result<T> {\n return { ok: true, data };\n}\n\n/** Wraps error in `{ ok: false, error }`. */\nexport function fail<T = never>(error: ConvertError): Result<T> {\n return { ok: false, error };\n}\n",
8
- "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { ERR, fail, ok } from './core/result.js';\nimport { isPlainObject } from './core/validate.js';\nimport type { CapabilityLimits, CapabilityPreset, CapabilityStage, Result, ServerCapabilities } from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Loosely read JSON object; every field is checked before use. */\ntype JsonObject = Record<string, unknown>;\n\n// -------------------------------------------------------------------\n// --- 2. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Maps the `GET /v1/capabilities` payload to camelCase `ServerCapabilities`**.\n *\n * - lenient per field: missing or mistyped values become `[]`, `''`, `null` or `false`, so new server fields or\n * removed ones never fail the call\n * - non-object body: `invalid_response`\n */\nexport function readCapabilities(body: unknown): Result<ServerCapabilities> {\n if (!isPlainObject(body)) {\n return fail(ERR.INVALID_RESPONSE('Capabilities response is not a JSON object'));\n }\n const targets = objectOf(body.targets);\n const features = objectOf(body.features);\n return ok({\n versions: Object.fromEntries(\n Object.entries(objectOf(body.versions)).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n ),\n stages: Object.fromEntries(\n Object.entries(objectOf(body.stages)).map(([name, stage]) => [name, readStage(objectOf(stage))]),\n ),\n sources: stringsOf(body.sources),\n targets: { allowed: stringsOf(targets.allowed), default: stringOf(targets.default) },\n outputFormats: stringsOf(body.output_formats),\n imageExportModes: stringsOf(body.image_export_modes),\n limits: readLimits(objectOf(body.limits)),\n features: {\n apiKeyRequired: features.api_key_required === true,\n artifactStorage: features.artifact_storage === true,\n websocket: features.websocket === true,\n },\n });\n}\n\n// -------------------------------------------------------------------\n// --- 3. Internal Functions\n// -------------------------------------------------------------------\n\n/** Pipeline stage; presets without a string `id` are dropped. */\nfunction readStage(stage: JsonObject): CapabilityStage {\n const presets: CapabilityPreset[] = [];\n for (const item of Array.isArray(stage.presets) ? stage.presets : []) {\n const preset = objectOf(item);\n if (typeof preset.id === 'string') {\n presets.push({\n id: preset.id,\n name: stringOf(preset.name),\n description: typeof preset.description === 'string' ? preset.description : null,\n source: stringOf(preset.source),\n });\n }\n }\n return {\n option: stringOf(stage.option),\n customConfigOption: typeof stage.custom_config_option === 'string' ? stage.custom_config_option : null,\n default: stringOf(stage.default),\n presets,\n };\n}\n\n/** Server limits; non-numbers become `null`. */\nfunction readLimits(limits: JsonObject): CapabilityLimits {\n return {\n maxDocumentTimeout: numberOf(limits.max_document_timeout),\n maxImagesScale: numberOf(limits.max_images_scale),\n maxSourcesPerRequest: numberOf(limits.max_sources_per_request),\n maxNumPages: numberOf(limits.max_num_pages),\n maxFileSize: numberOf(limits.max_file_size),\n };\n}\n\n/** Plain object, or `{}` for anything else. */\nfunction objectOf(value: unknown): JsonObject {\n return isPlainObject(value) ? value : {};\n}\n\n/** String entries of an array; `[]` for a non-array. */\nfunction stringsOf(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [];\n}\n\n/** String, or `''` for anything else. */\nfunction stringOf(value: unknown): string {\n return typeof value === 'string' ? value : '';\n}\n\n/** Finite number, or `null` for anything else. */\nfunction numberOf(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n",
9
- "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Result } from '../types.js';\nimport { ERR, fail, ok } from './result.js';\n\n// -------------------------------------------------------------------\n// --- 1. Constants\n// -------------------------------------------------------------------\n\n/** Error code Bun and Node set when a body exceeds the maximum string length. */\nconst STRING_TOO_LONG = 'ERR_STRING_TOO_LONG';\n\n/** Matches the out-of-memory message of JavaScriptCore (`Out of memory`) and V8 (`... out of memory`). */\nconst MATCH_OUT_OF_MEMORY = /out of memory/i;\n\n/** Matches whitespace runs collapsed in body snippets. */\nconst MATCH_WHITESPACE = /\\s+/g;\n\n/** Characters of a non-JSON body quoted in the error message. */\nconst BODY_SNIPPET_LENGTH = 200;\n\n// -------------------------------------------------------------------\n// --- 2. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Executes `fetch` and parses the JSON body into a `Result`**.\n *\n * - non-2xx: `http` with FastAPI `detail`; unparsable 2xx body: `invalid_response`\n * - body too large for a string or for memory: `invalid_response`, as a retry fails the same way\n * - aborted signal: `aborted`; anything else thrown: `network`\n */\nexport async function fetchJson(fetchFn: typeof fetch, url: string, init: RequestInit): Promise<Result<unknown>> {\n try {\n const res = await fetchFn(url, init);\n const text = await res.text();\n if (!res.ok) {\n return fail(ERR.HTTP(res.status, errorDetail(text)));\n }\n try {\n return ok(JSON.parse(text));\n } catch {\n return fail(ERR.INVALID_RESPONSE(`Response body is not valid JSON: ${bodySnippet(text)}`, res.status));\n }\n } catch (e) {\n const message = errorMessage(e);\n if (isTooLarge(e)) {\n return fail(ERR.INVALID_RESPONSE(`Response body too large: ${message}`));\n }\n return fail(init.signal?.aborted ? ERR.ABORTED(message) : ERR.NETWORK(message));\n }\n}\n\n/** Extracts message, appending `cause.message` if present. */\nexport function errorMessage(e: unknown): string {\n if (!(e instanceof Error)) {\n return String(e);\n }\n return e.cause instanceof Error ? `${e.message}: ${e.cause.message}` : e.message;\n}\n\n// -------------------------------------------------------------------\n// --- 3. Internal Functions\n// -------------------------------------------------------------------\n\n/** Checks whether an error indicates body size exceeded memory or maximum string length. */\nfunction isTooLarge(e: unknown): boolean {\n if (e instanceof RangeError) {\n return true;\n }\n if (!(e instanceof Error)) {\n return false;\n }\n return (e as Error & { code?: unknown }).code === STRING_TOO_LONG || MATCH_OUT_OF_MEMORY.test(e.message);\n}\n\n/** First 200 characters of a body with whitespace collapsed; `(empty body)` for a blank one. */\nfunction bodySnippet(text: string): string {\n const collapsed = text.replace(MATCH_WHITESPACE, ' ').trim();\n return collapsed === '' ? '(empty body)' : collapsed.slice(0, BODY_SNIPPET_LENGTH);\n}\n\n/** Extracts FastAPI 'detail' from response body, falling back to raw text (up to 500 characters) or 'no response body'. */\nfunction errorDetail(text: string): string {\n try {\n const body: unknown = JSON.parse(text);\n if (body && typeof body === 'object' && 'detail' in body) {\n const { detail } = body;\n return typeof detail === 'string' ? detail : JSON.stringify(detail);\n }\n } catch {\n // Not JSON: fall back to raw text\n }\n return text.slice(0, 500) || 'no response body';\n}\n",
10
- "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\n// -------------------------------------------------------------------\n// --- 1. Constants\n// -------------------------------------------------------------------\n\n/** Bytes at the end of a PDF searched for `startxref`; the trailer sits within the last few hundred bytes. */\nconst TAIL_LENGTH = 2048;\n\n/** Matches `startxref` with its byte offset (group 1); incremental updates repeat it, the last one counts. */\nconst MATCH_STARTXREF = /startxref\\s+(\\d+)/g;\n\n/** Bytes searched for `%PDF-`: a header may start at offsets 0 to 1023, so its 5 bytes end by 1028. */\nconst HEADER_SEARCH_LENGTH = 1028;\n\n// -------------------------------------------------------------------\n// --- 2. Exported Functions\n// -------------------------------------------------------------------\n\n/** Matches a `%PDF-` header starting within the first 1024 bytes. */\nexport function isPdf(bytes: unknown): bytes is Uint8Array {\n if (!(bytes instanceof Uint8Array) || bytes.length === 0) {\n return false;\n }\n const head = bytes.subarray(0, HEADER_SEARCH_LENGTH);\n for (let i = 0; i + 5 <= head.length; i++) {\n // %PDF-\n if (\n head[i] === 0x25 &&\n head[i + 1] === 0x50 &&\n head[i + 2] === 0x44 &&\n head[i + 3] === 0x46 &&\n head[i + 4] === 0x2d\n ) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * **Returns cross-reference offset if PDF is truncated**: last `startxref` points at or past EOF.\n *\n * - typical for aborted downloads; docling then fails with a vague load error\n * - only the last 2 KB are read, as latin1\n * - returns `undefined` when offset lies inside file or no `startxref` found\n */\nexport function findTruncatedXref(bytes: Uint8Array): number | undefined {\n const tail = new TextDecoder('latin1').decode(bytes.subarray(Math.max(0, bytes.length - TAIL_LENGTH)));\n const last = [...tail.matchAll(MATCH_STARTXREF)].at(-1);\n const offset = last === undefined ? undefined : Number(last[1]);\n return offset !== undefined && offset >= bytes.length ? offset : undefined;\n}\n",
11
- "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { isPdf } from './pdf.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Detected input format and how it is sent to docling-serve. */\nexport type InputFormat = {\n /** docling's `from_formats` value. */\n fromFormat: 'pdf' | 'image';\n /** MIME type of the multipart file part. */\n mimeType: string;\n /** File name of the multipart file part; docling reads the format from its extension. */\n fileName: string;\n};\n\n/** Image format recognized by byte signatures at fixed offsets. */\ntype ImageSignature = {\n mimeType: string;\n extension: string;\n /** Byte runs that must all match, each at its offset. */\n parts: [offset: number, bytes: number[]][];\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Image formats docling reads with `from_formats=image` (checked live on docling-serve 1.36.0). */\nconst IMAGE_SIGNATURES: readonly ImageSignature[] = [\n { mimeType: 'image/png', extension: 'png', parts: [[0, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]]] },\n { mimeType: 'image/jpeg', extension: 'jpg', parts: [[0, [0xff, 0xd8, 0xff]]] },\n // Little-endian `II*\\0` and big-endian `MM\\0*`.\n { mimeType: 'image/tiff', extension: 'tiff', parts: [[0, [0x49, 0x49, 0x2a, 0x00]]] },\n { mimeType: 'image/tiff', extension: 'tiff', parts: [[0, [0x4d, 0x4d, 0x00, 0x2a]]] },\n // `RIFF` <size> `WEBP`.\n {\n mimeType: 'image/webp',\n extension: 'webp',\n parts: [\n [0, [0x52, 0x49, 0x46, 0x46]],\n [8, [0x57, 0x45, 0x42, 0x50]],\n ],\n },\n];\n\n/** Format of PDF input. */\nconst PDF_FORMAT: InputFormat = { fromFormat: 'pdf', mimeType: 'application/pdf', fileName: 'document.pdf' };\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Detects the input format by magic bytes**.\n *\n * - image signatures must start at byte 0; PDF: `%PDF-` within the first 1024 bytes\n * - images are checked first, so an image whose data happens to contain `%PDF-` is still an image\n * - returns `undefined` for empty, non-`Uint8Array` or unrecognized input\n */\nexport function detectInputFormat(bytes: unknown): InputFormat | undefined {\n if (!(bytes instanceof Uint8Array) || bytes.length === 0) {\n return undefined;\n }\n const image = IMAGE_SIGNATURES.find(({ parts }) =>\n parts.every(([offset, run]) => run.every((byte, i) => bytes[offset + i] === byte)),\n );\n if (image !== undefined) {\n return { fromFormat: 'image', mimeType: image.mimeType, fileName: `document.${image.extension}` };\n }\n return isPdf(bytes) ? PDF_FORMAT : undefined;\n}\n",
12
- "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { ERR, fail, ok } from './core/result.js';\nimport {\n invalidValue,\n isBoolean,\n isOneOf,\n isPlainObject,\n OPTIONS_OBJECT_EXPECTED,\n type OptionRule,\n validateKeys,\n} from './core/validate.js';\nimport type {\n CallOptions,\n ClientOptions,\n DoclingConfig,\n DoclingOptions,\n DocumentImageMode,\n DocumentOptions,\n ImageOptions,\n JobRef,\n MarkdownImageMode,\n MarkdownJobOutput,\n MarkdownOptions,\n Result,\n} from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Factory-only option keys; they fall back to the server default when omitted. */\ntype FactoryOnly = Exclude<keyof ClientOptions, keyof DoclingOptions>;\n\n/** docling options with every per-call default filled in. */\nexport type ResolvedOptions = Required<DoclingOptions> & Pick<ClientOptions, FactoryOnly>;\n\n/** Validated client configuration. */\nexport type ResolvedConfig = {\n /** Base URL without trailing slash. */\n baseUrl: string;\n apiKey?: string;\n fetch: typeof fetch;\n /** Time limit per request in ms; unset means no limit. */\n timeoutMs?: number;\n /** Factory defaults merged over `DEFAULT_OPTIONS`. */\n defaults: ResolvedOptions;\n};\n\n/** Validated md call: server options, image handling and signal. */\nexport type MarkdownCall = {\n options: ResolvedOptions;\n output: MarkdownJobOutput;\n signal?: AbortSignal;\n};\n\n/** Validated document call: server options, picture data mode, page images and signal. */\nexport type DocumentCall = {\n options: ResolvedOptions;\n images: DocumentImageMode;\n pageImages: boolean;\n signal?: AbortSignal;\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Allowed `pipeline` values. */\nconst PIPELINES = ['standard', 'vlm'] as const;\n\n/** Allowed `pdfBackend` values. */\nconst PDF_BACKENDS = ['docling_parse', 'pypdfium2'] as const;\n\n/** Allowed `images` values of md calls. */\nconst MARKDOWN_IMAGE_MODES: readonly MarkdownImageMode[] = ['none', 'placeholder', 'extract'];\n\n/** Allowed `images` values of document calls. */\nconst DOCUMENT_IMAGE_MODES: readonly DocumentImageMode[] = ['embedded', 'placeholder'];\n\n/** Defaults of every docling option sent explicitly. */\nexport const DEFAULT_OPTIONS: Readonly<ResolvedOptions> = Object.freeze({\n headingHierarchy: true,\n formulaEnrichment: true,\n codeEnrichment: false,\n chartExtraction: false,\n pipeline: 'standard',\n pdfBackend: 'docling_parse',\n ocr: true,\n forceOcr: false,\n ocrEngine: 'auto',\n});\n\n/** Rules for docling options, accepted by the factory and every conversion call. */\nconst CALL_OPTION_RULES: Record<keyof DoclingOptions, OptionRule> = {\n headingHierarchy: isBoolean,\n formulaEnrichment: isBoolean,\n codeEnrichment: isBoolean,\n chartExtraction: isBoolean,\n pipeline: (value) => isOneOf(value, PIPELINES),\n pdfBackend: (value) => isOneOf(value, PDF_BACKENDS),\n ocr: isBoolean,\n forceOcr: isBoolean,\n // Open list: presets depend on server installation, unknown IDs are left to server.\n ocrEngine: (value) => typeof value === 'string' && value !== '',\n};\n\n/** Rules for factory options: per-call options plus the factory-only ones. */\nconst CLIENT_OPTION_RULES: Record<keyof ClientOptions, OptionRule> = {\n ...CALL_OPTION_RULES,\n ocrLang: isLanguageList,\n pageRange: isPageRange,\n documentTimeout: isPositiveNumber,\n};\n\n/** Rules for md call options; `imageOptions` keys are checked by `resolveImageOutput`. */\nconst MARKDOWN_RULES: Record<keyof MarkdownOptions, OptionRule> = {\n ...CALL_OPTION_RULES,\n signal: isAbortSignal,\n images: (value) => isOneOf(value, MARKDOWN_IMAGE_MODES),\n imageOptions: isPlainObject,\n};\n\n/** Rules for document call options. */\nconst DOCUMENT_RULES: Record<keyof DocumentOptions, OptionRule> = {\n ...CALL_OPTION_RULES,\n signal: isAbortSignal,\n images: (value) => isOneOf(value, DOCUMENT_IMAGE_MODES),\n pageImages: isBoolean,\n};\n\n/** Rules for image extraction options. */\nconst IMAGE_OPTION_RULES: Record<keyof ImageOptions, OptionRule> = {\n prefix: isImagePrefix,\n omitSmall: isBoolean,\n};\n\n/** Rules for `check` and `capabilities` options. */\nconst CHECK_RULES: Record<keyof CallOptions, OptionRule> = {\n signal: isAbortSignal,\n};\n\n/** Rules for factory configuration; the keys of `options` are checked separately. */\nconst CONFIG_RULES: Record<keyof DoclingConfig, OptionRule> = {\n baseUrl: isHttpUrl,\n apiKey: (value) => typeof value === 'string' && value !== '',\n fetch: (value) => typeof value === 'function',\n timeoutMs: isPositiveNumber,\n options: isPlainObject,\n};\n\n/** Job id of word characters and `-` only, so it cannot leave the URL path segment. */\nconst MATCH_JOB_ID = /^[\\w-]+$/;\n\n/** Matches BCP-47 language tags (e.g. 'en', 'de-AT'). */\nconst MATCH_LANGUAGE_TAG = /^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;\n\n/** Matches path prefixes free of md link delimiters. */\nconst MATCH_IMAGE_PREFIX = /^[^\\s()<>]+$/;\n\n/** Matches one or more trailing slashes of a base URL. */\nconst MATCH_TRAILING_SLASHES = /\\/+$/;\n\n/** Matches HTTP or HTTPS protocol schemes. */\nconst MATCH_HTTP_PROTOCOL = /^https?:$/;\n\n/** Error message for a missing or malformed job object. */\nconst INVALID_JOB = 'Expected the job object returned by submitMarkdown() or submitDocument()';\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Validates factory configuration**.\n *\n * - `baseUrl` is required; trailing `/` are removed\n * @throws `TypeError` on invalid configuration.\n */\nexport function resolveConfig(config: unknown): ResolvedConfig {\n if (!isPlainObject(config)) {\n throw new TypeError('Invalid config: expected an object');\n }\n const { baseUrl, apiKey, fetch: fetchFn, timeoutMs, options } = validateKeys<DoclingConfig>(config, CONFIG_RULES);\n if (baseUrl === undefined) {\n throw new TypeError(invalidValue('baseUrl'));\n }\n const defaults = {\n ...DEFAULT_OPTIONS,\n ...(options === undefined ? {} : validateKeys(options, CLIENT_OPTION_RULES)),\n };\n return {\n baseUrl: baseUrl.replace(MATCH_TRAILING_SLASHES, ''),\n ...(apiKey === undefined ? {} : { apiKey }),\n fetch: fetchFn ?? fetch,\n ...(timeoutMs === undefined ? {} : { timeoutMs }),\n defaults,\n };\n}\n\n/**\n * Validates md call options over factory defaults.\n * @throws `TypeError` on invalid options.\n */\nexport function resolveMarkdownCall(defaults: Readonly<ResolvedOptions>, options: unknown): MarkdownCall {\n const {\n signal,\n images = 'placeholder',\n imageOptions,\n ...docling\n } = validateKeys<MarkdownOptions>(callObject(options), MARKDOWN_RULES);\n const output = resolveImageOutput(images, imageOptions);\n return { options: { ...defaults, ...docling }, output, ...(signal === undefined ? {} : { signal }) };\n}\n\n/**\n * Validates document call options over factory defaults.\n * @throws `TypeError` on invalid options.\n */\nexport function resolveDocumentCall(defaults: Readonly<ResolvedOptions>, options: unknown): DocumentCall {\n const {\n signal,\n images = 'embedded',\n pageImages = false,\n ...docling\n } = validateKeys<DocumentOptions>(callObject(options), DOCUMENT_RULES);\n return { options: { ...defaults, ...docling }, images, pageImages, ...(signal === undefined ? {} : { signal }) };\n}\n\n/**\n * Validates signal-only call options (`check`, `capabilities`).\n * @throws `TypeError` on invalid options.\n */\nexport function resolveCheckOptions(options: unknown): CallOptions {\n return validateKeys<CallOptions>(callObject(options), CHECK_RULES);\n}\n\n/**\n * **Checks a job object against the shape `submitMarkdown()` and `submitDocument()` return**.\n *\n * - never throws: a malformed job is `invalid_input`\n * - `settings` and other extra keys are ignored and not returned\n */\nexport function validateJob(job: unknown): Result<JobRef> {\n if (!isPlainObject(job) || !isJobId(job.id)) {\n return fail(ERR.INVALID_INPUT(INVALID_JOB));\n }\n if (job.kind === 'document') {\n return ok({ kind: 'document', id: job.id });\n }\n if (job.kind !== 'markdown' || !isPlainObject(job.output) || !isOneOf(job.output.images, MARKDOWN_IMAGE_MODES)) {\n return fail(ERR.INVALID_INPUT(INVALID_JOB));\n }\n try {\n return ok({\n kind: 'markdown',\n id: job.id,\n output: resolveImageOutput(job.output.images, job.output.imageOptions),\n });\n } catch (error) {\n return fail(ERR.INVALID_INPUT(`${INVALID_JOB}: ${(error as Error).message}`));\n }\n}\n\n/** Task id `check` accepts: word characters and `-` only, so it cannot leave the URL path segment. */\nexport function isJobId(value: unknown): value is string {\n return typeof value === 'string' && MATCH_JOB_ID.test(value);\n}\n\n// -------------------------------------------------------------------\n// --- 4. Internal Functions\n// -------------------------------------------------------------------\n\n/**\n * Returns call options as a plain object (`undefined` becomes `{}`).\n * @throws `TypeError` when options is not a plain object.\n */\nfunction callObject(options: unknown): Record<string, unknown> {\n if (options === undefined) {\n return {};\n }\n if (!isPlainObject(options)) {\n throw new TypeError(OPTIONS_OBJECT_EXPECTED);\n }\n return options;\n}\n\n/**\n * **Combines image mode and image options into the md job output**.\n *\n * - `imageOptions` with `prefix` is required with `'extract'` and not allowed otherwise\n * @throws `TypeError` on a missing, unexpected or invalid `imageOptions`.\n */\nfunction resolveImageOutput(images: MarkdownImageMode, imageOptions: unknown): MarkdownJobOutput {\n if (images !== 'extract') {\n if (imageOptions !== undefined) {\n throw new TypeError(`Option \"imageOptions\" is not supported without images: 'extract'`);\n }\n return { images };\n }\n if (imageOptions === undefined) {\n throw new TypeError(`Option \"imageOptions\" is required with images: 'extract'`);\n }\n if (!isPlainObject(imageOptions)) {\n throw new TypeError(invalidValue('imageOptions'));\n }\n const { prefix, omitSmall = true } = validateKeys<ImageOptions>(imageOptions, IMAGE_OPTION_RULES, 'imageOptions.');\n if (prefix === undefined) {\n throw new TypeError('Option \"imageOptions.prefix\" is required');\n }\n return { images, imageOptions: { prefix, omitSmall } };\n}\n\n/** Finite number greater than zero. */\nfunction isPositiveNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0;\n}\n\n/** 1-based ascending integer pair `[from, to]`. */\nfunction isPageRange(value: unknown): value is [number, number] {\n return (\n Array.isArray(value) &&\n value.length === 2 &&\n Number.isInteger(value[0]) &&\n Number.isInteger(value[1]) &&\n value[0] >= 1 &&\n value[1] >= value[0]\n );\n}\n\n/** Array of BCP-47 language tags; empty means the OCR engine default. */\nfunction isLanguageList(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((tag) => typeof tag === 'string' && MATCH_LANGUAGE_TAG.test(tag));\n}\n\n/** Path prefix without md-breaking characters. */\nfunction isImagePrefix(value: unknown): value is string {\n return typeof value === 'string' && MATCH_IMAGE_PREFIX.test(value);\n}\n\n/** `AbortSignal` instance. */\nfunction isAbortSignal(value: unknown): value is AbortSignal {\n return value instanceof AbortSignal;\n}\n\n/** Parseable HTTP or HTTPS URL. */\nfunction isHttpUrl(value: unknown): value is string {\n return typeof value === 'string' && URL.canParse(value) && MATCH_HTTP_PROTOCOL.test(new URL(value).protocol);\n}\n",
13
- "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { ERR, fail, ok } from './core/result.js';\nimport { isPlainObject } from './core/validate.js';\nimport type { DoclingDocument } from './document.js';\nimport { extractImages, extractPageImages, removeImagePlaceholders } from './images.js';\nimport type {\n ConversionFailure,\n ConvertedDocument,\n ConvertedMarkdown,\n MarkdownJobOutput,\n MarkdownWarning,\n Result,\n ServerWarning,\n TaskFailure,\n} from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n// biome-ignore-start lint/style/useNamingConvention: mirrors docling-serve's snake_case JSON\n/** Untrusted subset of docling-serve conversion response payload. */\ntype DoclingConvertResponse = {\n status?: unknown;\n document?: { md_content?: unknown; json_content?: unknown } | null;\n errors?: (DoclingErrorItem | null)[];\n failure?: DoclingFailureInfo | null;\n};\n\n/** Untrusted docling `PublicFailureInfo` of a failed task. */\nexport type DoclingFailureInfo = {\n message?: unknown;\n category?: unknown;\n phase?: unknown;\n retryable?: unknown;\n};\n\n/** Untrusted docling `ErrorItem`; `category` and `page_no` only in newer docling. */\ntype DoclingErrorItem = {\n error_message?: unknown;\n component_type?: unknown;\n module_name?: unknown;\n category?: unknown;\n page_no?: unknown;\n};\n// biome-ignore-end lint/style/useNamingConvention: mirrors docling-serve's snake_case JSON\n\n/** Successful conversion: status, untrusted document payload, docling's non-fatal errors and failure info. */\ntype ServerOutput = {\n status: 'success' | 'partial_success';\n document: NonNullable<DoclingConvertResponse['document']>;\n warnings: ServerWarning[];\n /** Failure message docling sent along; `undefined` if none. */\n failureMessage: string | undefined;\n failure: TaskFailure | null;\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Matches older docling's page error `Page 1 failed to parse.`; group 1: 0-based page index. */\nconst MATCH_FAILED_PAGE = /^Page (\\d+) failed to parse\\./;\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Reads `md_content` and applies the image handling**.\n *\n * - `'extract'`: embedded images become `images` and file links; `'none'`: placeholders removed\n * - otherwise docling's md is returned unchanged\n */\nexport function readMarkdown(body: unknown, output: MarkdownJobOutput): Result<Omit<ConvertedMarkdown, 'versions'>> {\n const server = readConvertResponse(body);\n if (!server.ok) {\n return server;\n }\n const markdown = server.data.document.md_content;\n if (markdown == null) {\n return missingContent(server.data, 'md_content');\n }\n if (typeof markdown !== 'string') {\n return fail(ERR.INVALID_RESPONSE('Response has no md_content'));\n }\n const warnings: MarkdownWarning[] = server.data.warnings;\n if (output.images === 'extract') {\n const extracted = extractImages(markdown, output.imageOptions);\n return ok({ ...extracted, warnings: [...warnings, ...extracted.warnings] });\n }\n const md = output.images === 'none' ? removeImagePlaceholders(markdown) : markdown;\n return ok({ markdown: md, images: [], warnings });\n}\n\n/**\n * **Reads `json_content`**.\n *\n * - only `schema_name` and `body` are checked, the rest is passed on as sent\n * - page images are moved from `pages[].image` to `pageImages`; undecodable ones stay and are reported after server warnings\n */\nexport function readDocument(body: unknown): Result<Omit<ConvertedDocument, 'versions'>> {\n const server = readConvertResponse(body);\n if (!server.ok) {\n return server;\n }\n const json = server.data.document.json_content;\n if (json == null) {\n return missingContent(server.data, 'json_content');\n }\n if (!isPlainObject(json) || json.schema_name !== 'DoclingDocument' || !isPlainObject(json.body)) {\n return fail(ERR.INVALID_RESPONSE('Response has no DoclingDocument in json_content'));\n }\n const { document, pageImages, warnings } = extractPageImages(json as DoclingDocument);\n return ok({ document, pageImages, warnings: [...server.data.warnings, ...warnings] });\n}\n\n/** Parses docling's task failure classification; `null` if absent. */\nexport function readFailure(failure: DoclingFailureInfo | null | undefined): TaskFailure | null {\n if (failure == null || typeof failure !== 'object') {\n return null;\n }\n return {\n category: readText(failure.category) ?? null,\n phase: readText(failure.phase) ?? null,\n retryable: typeof failure.retryable === 'boolean' ? failure.retryable : null,\n };\n}\n\n/** Non-empty string, or `undefined` if empty or not a string. */\nexport function readText(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\n// -------------------------------------------------------------------\n// --- 4. Internal Functions\n// -------------------------------------------------------------------\n\n/**\n * **Splits a conversion response into success or failure**.\n *\n * - `success` and `partial_success` pass on the document with docling's error items as warnings\n * - any other status: `conversion_failed` with the failure message, else the joined error messages\n * - status missing, empty or not a string, and no failure: `invalid_response`\n */\nfunction readConvertResponse(body: unknown): Result<ServerOutput> {\n const res = (body ?? {}) as DoclingConvertResponse;\n const errors = Array.isArray(res.errors) ? res.errors : [];\n const warnings = errors.flatMap((error) => (error == null ? [] : readServerError(error)));\n const failureMessage = readText(res.failure?.message);\n const failure = readFailure(res.failure);\n if (res.status === 'success' || res.status === 'partial_success') {\n const document = isPlainObject(res.document) ? res.document : {};\n return ok({ status: res.status, document, warnings, failureMessage, failure });\n }\n if (readText(res.status) === undefined && res.failure == null) {\n return fail(ERR.INVALID_RESPONSE('Unexpected response: no conversion status'));\n }\n const messages = warnings.map(({ message }) => message).join('; ');\n const reason = failureMessage ?? (messages || `status: ${String(res.status)}`);\n return fail(ERR.CONVERSION_FAILED(reason, { errors: toServerErrors(warnings), failure }));\n}\n\n/**\n * **Result for a successful status without the requested content**.\n *\n * - `partial_success`, error items or a failure: `conversion_failed` with all server details\n * - plain `success` without any of them: `invalid_response`\n */\nfunction missingContent(server: ServerOutput, field: 'md_content' | 'json_content'): Result<never> {\n const { status, warnings, failureMessage, failure } = server;\n if (status !== 'partial_success' && warnings.length === 0 && failure === null) {\n const content = field === 'md_content' ? 'md_content' : 'DoclingDocument in json_content';\n return fail(ERR.INVALID_RESPONSE(`Response has no ${content}`));\n }\n const messages = warnings.map(({ message }) => message).join('; ');\n const reason = failureMessage ?? (messages || `status: ${status}, no ${field}`);\n return fail(ERR.CONVERSION_FAILED(reason, { errors: toServerErrors(warnings), failure }));\n}\n\n/** Server warnings as `ConversionFailure.errors`. */\nfunction toServerErrors(warnings: ServerWarning[]): ConversionFailure['errors'] {\n return warnings.map(({ message, details }) => ({ message, details }));\n}\n\n/**\n * **Reads one docling error item**.\n *\n * - items without `error_message` are dropped\n * - 1-based page from `page_no` (newer docling) or the older error text; `null` if unassigned\n */\nfunction readServerError(error: DoclingErrorItem): ServerWarning[] {\n const message = readText(error.error_message);\n if (message === undefined) {\n return [];\n }\n const pageIndex = MATCH_FAILED_PAGE.exec(message)?.[1];\n const page = isPageNumber(error.page_no) ? error.page_no : pageIndex === undefined ? null : Number(pageIndex) + 1;\n return [\n {\n code: 'server',\n message,\n details: {\n component: readText(error.component_type) ?? null,\n module: readText(error.module_name) ?? null,\n category: readText(error.category) ?? null,\n page,\n },\n },\n ];\n}\n\n/** Docling `page_no`: integer >= 1; 0, negatives and fractions are rejected. */\nfunction isPageNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 1;\n}\n",
14
- "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { readCapabilities } from './capabilities.js';\nimport { errorMessage, fetchJson } from './core/http.js';\nimport { detectInputFormat, type InputFormat } from './core/input.js';\nimport { findTruncatedXref } from './core/pdf.js';\nimport { ERR, fail, ok } from './core/result.js';\nimport { PAGE_IMAGE_SCALE } from './images.js';\nimport {\n isJobId,\n type ResolvedOptions,\n resolveCheckOptions,\n resolveConfig,\n resolveDocumentCall,\n resolveMarkdownCall,\n validateJob,\n} from './options.js';\nimport { type DoclingFailureInfo, readDocument, readFailure, readMarkdown, readText } from './response.js';\nimport type {\n ConvertError,\n ConvertedDocument,\n ConvertedMarkdown,\n ConvertInput,\n DoclingClient,\n DoclingConfig,\n DoclingSettings,\n DocumentJob,\n JobRef,\n JobState,\n MarkdownJob,\n Result,\n ServerCapabilities,\n ServerVersions,\n WithSettings,\n} from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n// biome-ignore-start lint/style/useNamingConvention: mirrors docling-serve's snake_case JSON\n/** Task status payload of docling-serve's submit and poll endpoints. */\ntype DoclingTaskStatus = {\n task_id?: unknown;\n task_status?: unknown;\n task_position?: unknown;\n error_message?: unknown;\n failure?: DoclingFailureInfo | null;\n};\n// biome-ignore-end lint/style/useNamingConvention: mirrors docling-serve's snake_case JSON\n\n/** Output format sent as `to_formats`, with its image fields. */\ntype FormatFields = {\n format: 'md' | 'json';\n /** Asks docling for base64 picture data (`image_export_mode=embedded`, `include_images=true`). */\n embedImages: boolean;\n /** Asks docling for base64 page images (`image_export_mode=embedded`, `include_page_images=true`). */\n pageImages: boolean;\n};\n\n/** Parsed JSON answer of a conversion POST, with the settings its form was built from. */\ntype Posted = {\n body: unknown;\n settings: DoclingSettings;\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Table structure model; pinned so the server's fallback preset cannot change table output. */\nconst TABLE_STRUCTURE_PRESET = 'tableformer_v1_accurate';\n\n/** Model of `pipeline: 'vlm'`. */\nconst VLM_PIPELINE_PRESET = 'granite_docling';\n\n/** Model of `chartExtraction`. */\nconst CHART_EXTRACTION_PRESET = 'granite_vision_v4';\n\n/** Model of `formulaEnrichment` and `codeEnrichment`. */\nconst CODE_FORMULA_PRESET = 'codeformulav2';\n\n/** Matches each upper-case letter of a camelCase settings key, for its snake_case form field name. */\nconst MATCH_UPPER_CASE = /[A-Z]/g;\n\n/** Error message for missing, empty or unrecognized input bytes. */\nconst INVALID_INPUT = 'Expected a non-empty PDF, PNG, JPEG, TIFF or WebP as Uint8Array';\n\n/** Error codes of requests the server answered; only these get server versions. */\nconst SERVER_ANSWERED: ReadonlySet<ConvertError['code']> = new Set([\n 'http',\n 'not_found',\n 'conversion_failed',\n 'invalid_response',\n]);\n\n/** Time limit for the `/version` request; a slower server gets `versions: null`. */\nconst VERSION_TIMEOUT_MS = 2000;\n\n/** Characters of an unusable task id quoted in the error message. */\nconst MAX_SHOWN_ID_LENGTH = 100;\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **docling-serve client factory**.\n *\n * - validates configuration once; its only state is the cached server versions\n * - returned functions resolve to `Result`; invalid options reject with a `TypeError` before any request\n * - `timeoutMs` limits every request except `/version`, which has its own limit\n * @throws `TypeError` on invalid configuration.\n */\nexport function createDoclingClient(config: DoclingConfig): DoclingClient {\n const { baseUrl, apiKey, fetch: fetchFn, timeoutMs, defaults } = resolveConfig(config);\n const headers: Record<string, string> = apiKey === undefined ? {} : { 'X-Api-Key': apiKey };\n /** Pending or resolved `/version` answer shared by all calls of this client. */\n let versionsCache: Promise<ServerVersions | null> | undefined;\n\n return {\n convertMarkdown,\n convertDocument,\n submitMarkdown,\n submitDocument,\n check: check as DoclingClient['check'],\n capabilities,\n };\n\n /** Converts PDF or image bytes to md in one request. */\n async function convertMarkdown(\n input: ConvertInput,\n options?: unknown,\n ): Promise<Result<WithSettings<ConvertedMarkdown>>> {\n const call = resolveMarkdownCall(defaults, options);\n const fields: FormatFields = { format: 'md', embedImages: call.output.images === 'extract', pageImages: false };\n const res = await post('/v1/convert/file', input, call.options, fields, call.signal);\n if (!res.ok) {\n return res;\n }\n const converted = await withVersions<ConvertedMarkdown>(readMarkdown(res.data.body, call.output));\n return converted.ok ? ok({ ...converted.data, settings: res.data.settings }) : converted;\n }\n\n /** Converts PDF or image bytes to a DoclingDocument in one request. */\n async function convertDocument(\n input: ConvertInput,\n options?: unknown,\n ): Promise<Result<WithSettings<ConvertedDocument>>> {\n const call = resolveDocumentCall(defaults, options);\n const fields: FormatFields = {\n format: 'json',\n embedImages: call.images === 'embedded',\n pageImages: call.pageImages,\n };\n const res = await post('/v1/convert/file', input, call.options, fields, call.signal);\n if (!res.ok) {\n return res;\n }\n const converted = await withVersions<ConvertedDocument>(readDocument(res.data.body));\n return converted.ok ? ok({ ...converted.data, settings: res.data.settings }) : converted;\n }\n\n /** Starts an async md conversion; the job carries the image handling for `check` and the sent settings. */\n async function submitMarkdown(input: ConvertInput, options?: unknown): Promise<Result<MarkdownJob>> {\n const call = resolveMarkdownCall(defaults, options);\n const fields: FormatFields = { format: 'md', embedImages: call.output.images === 'extract', pageImages: false };\n const task = await submit(input, call.options, fields, call.signal);\n return task.ok\n ? ok({ kind: 'markdown', id: task.data.id, output: call.output, settings: task.data.settings })\n : task;\n }\n\n /** Starts an async document conversion; page images need no job field, `check` moves any it finds. */\n async function submitDocument(input: ConvertInput, options?: unknown): Promise<Result<DocumentJob>> {\n const call = resolveDocumentCall(defaults, options);\n const fields: FormatFields = {\n format: 'json',\n embedImages: call.images === 'embedded',\n pageImages: call.pageImages,\n };\n const task = await submit(input, call.options, fields, call.signal);\n return task.ok ? ok({ kind: 'document', id: task.data.id, settings: task.data.settings }) : task;\n }\n\n /**\n * **Polls a job and fetches its result when done**.\n *\n * - unknown job id: `not_found` with `Unknown job id`\n * - result fetched more than `DOCLING_SERVE_RESULT_REMOVAL_DELAY` (default 300 s) ago or expired: `not_found` with\n * `Result already fetched or expired`\n */\n async function check(\n job: JobRef,\n options?: unknown,\n ): Promise<Result<JobState<ConvertedMarkdown | ConvertedDocument>>> {\n const { signal } = resolveCheckOptions(options);\n const valid = validateJob(job);\n if (!valid.ok) {\n return valid;\n }\n const { id } = valid.data;\n const res = await get(`/v1/status/poll/${id}`, signal);\n if (!res.ok) {\n const error =\n res.error.status === 404 ? ERR.NOT_FOUND(`Unknown job id: ${id} (${res.error.message})`) : res.error;\n return failWithVersions(error);\n }\n const task = (res.data ?? {}) as DoclingTaskStatus;\n switch (task.task_status) {\n case 'pending': {\n const position = typeof task.task_position === 'number' ? task.task_position : null;\n return ok({ status: 'queued', position });\n }\n case 'started':\n return ok({ status: 'running' });\n case 'success':\n case 'partial_success': {\n const result = await get(`/v1/result/${id}`, signal);\n if (!result.ok) {\n const error =\n result.error.status === 404\n ? ERR.NOT_FOUND(\n `Result already fetched or expired: ${id}; resubmit the PDF (${result.error.message})`,\n )\n : result.error;\n return failWithVersions(error);\n }\n const checked = valid.data;\n const output =\n checked.kind === 'markdown' ? readMarkdown(result.data, checked.output) : readDocument(result.data);\n const done = await withVersions<ConvertedMarkdown | ConvertedDocument>(output);\n return done.ok ? ok({ status: 'done', ...done.data }) : done;\n }\n case 'failure':\n case 'skipped': {\n const reason =\n readText(task.failure?.message) ?? readText(task.error_message) ?? `status: ${task.task_status}`;\n const details = { errors: [], failure: readFailure(task.failure) };\n return failWithVersions(ERR.CONVERSION_FAILED(reason, details));\n }\n default:\n return failWithVersions(ERR.INVALID_RESPONSE(`Unexpected task status: ${String(task.task_status)}`));\n }\n }\n\n /**\n * **Queries `GET /v1/capabilities` on demand**.\n *\n * - older servers without the endpoint answer `http` (404)\n */\n async function capabilities(options?: unknown): Promise<Result<ServerCapabilities>> {\n const { signal } = resolveCheckOptions(options);\n const res = await get('/v1/capabilities', signal);\n if (!res.ok) {\n return failWithVersions(res.error);\n }\n const read = readCapabilities(res.data);\n return read.ok ? read : failWithVersions(read.error);\n }\n\n /** Posts the input to the async endpoint; resolves to the task id and the sent settings. */\n async function submit(\n input: ConvertInput,\n options: ResolvedOptions,\n fields: FormatFields,\n signal: AbortSignal | undefined,\n ): Promise<Result<{ id: string; settings: DoclingSettings }>> {\n const res = await post('/v1/convert/file/async', input, options, fields, signal);\n if (!res.ok) {\n return res;\n }\n const id: unknown = (res.data.body as DoclingTaskStatus | null)?.task_id;\n if (readText(id) === undefined) {\n return failWithVersions(ERR.INVALID_RESPONSE('Response has no task_id'));\n }\n if (!isJobId(id)) {\n const shown = JSON.stringify(id).slice(0, MAX_SHOWN_ID_LENGTH);\n return failWithVersions(ERR.INVALID_RESPONSE(`Response has an unusable task_id: ${shown}`));\n }\n return ok({ id, settings: res.data.settings });\n }\n\n /** Detects and checks the input format, then sends a multipart POST with timeout; errors already carry versions. */\n async function post(\n route: string,\n input: ConvertInput,\n options: ResolvedOptions,\n fields: FormatFields,\n signal: AbortSignal | undefined,\n ): Promise<Result<Posted>> {\n const format = readInputFormat(input);\n if (!format.ok) {\n return format;\n }\n const settings = buildSettings(format.data, options, fields);\n let body: FormData;\n try {\n body = buildFormData(input, format.data, settings);\n } catch (error) {\n return fail(ERR.INVALID_INPUT(`Input could not be prepared for upload: ${errorMessage(error)}`));\n }\n const limited = withTimeout(signal, timeoutMs);\n const res = await fetchJson(fetchFn, `${baseUrl}${route}`, {\n method: 'POST',\n headers,\n body,\n ...(limited === undefined ? {} : { signal: limited }),\n });\n return res.ok ? ok({ body: res.data, settings }) : failWithVersions(res.error);\n }\n\n /** GET request; `limit: false` skips `timeoutMs` (used by `/version`). */\n function get(route: string, signal: AbortSignal | undefined, limit = true): Promise<Result<unknown>> {\n const limited = limit ? withTimeout(signal, timeoutMs) : signal;\n return fetchJson(fetchFn, `${baseUrl}${route}`, {\n headers,\n ...(limited === undefined ? {} : { signal: limited }),\n });\n }\n\n /** Adds server versions to a parsed result, or to its error if the server answered. */\n async function withVersions<T>(result: Result<Omit<T, 'versions'>>): Promise<Result<T>> {\n if (!result.ok) {\n return failWithVersions(result.error);\n }\n return ok({ ...result.data, versions: await fetchVersions() } as T);\n }\n\n /** Adds server versions to errors of requests the server answered; other errors stay as they are. */\n async function failWithVersions<T>(error: ConvertError): Promise<Result<T>> {\n return fail(SERVER_ANSWERED.has(error.code) ? { ...error, versions: await fetchVersions() } : error);\n }\n\n /**\n * **Server versions, fetched once per client and cached**.\n *\n * - concurrent calls share one request\n * - `null` (unreachable, timed out or empty) is not cached; the next call asks again\n */\n function fetchVersions(): Promise<ServerVersions | null> {\n versionsCache ??= requestVersions().then((versions) => {\n if (versions === null) {\n versionsCache = undefined;\n }\n return versions;\n });\n return versionsCache;\n }\n\n /**\n * **Queries `/version` with its own timeout**.\n *\n * - ignores the caller signal, so aborting after the conversion does not fail the result\n * - resolves `null` after `VERSION_TIMEOUT_MS` even if `fetch` ignores the timeout signal\n */\n async function requestVersions(): Promise<ServerVersions | null> {\n const timeout = AbortSignal.timeout(VERSION_TIMEOUT_MS);\n const timedOut = new Promise<null>((resolve) => {\n timeout.addEventListener('abort', () => resolve(null), { once: true });\n });\n const res = await Promise.race([get('/version', timeout, false), timedOut]);\n if (res === null || !res.ok || res.data === null || typeof res.data !== 'object') {\n return null;\n }\n const versions = Object.entries(res.data).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n );\n return versions.length === 0 ? null : Object.fromEntries(versions);\n }\n}\n\n// -------------------------------------------------------------------\n// --- 4. Internal Functions\n// -------------------------------------------------------------------\n\n/** Caller signal combined with a `timeoutMs` limit; either alone when the other is unset. */\nfunction withTimeout(signal: AbortSignal | undefined, timeoutMs: number | undefined): AbortSignal | undefined {\n if (timeoutMs === undefined) {\n return signal;\n }\n const timeout = AbortSignal.timeout(timeoutMs);\n return signal === undefined ? timeout : AbortSignal.any([signal, timeout]);\n}\n\n/**\n * **Input format by magic bytes; PDFs are also checked for truncation**.\n *\n * - unrecognized bytes or a truncated PDF: `invalid_input`\n */\nfunction readInputFormat(input: unknown): Result<InputFormat> {\n const format = detectInputFormat(input);\n if (format === undefined) {\n return fail(ERR.INVALID_INPUT(INVALID_INPUT));\n }\n const bytes = input as Uint8Array;\n const offset = format.fromFormat === 'pdf' ? findTruncatedXref(bytes) : undefined;\n return offset === undefined\n ? ok(format)\n : fail(\n ERR.INVALID_INPUT(\n `PDF is truncated: cross-reference offset ${offset} lies past the end of the file (${bytes.length} bytes)`,\n ),\n );\n}\n\n/**\n * **Every form field of a conversion request, as typed settings**.\n *\n * - md: `md_compact_tables=true`, empty page break placeholder; json sends neither\n * - images: `image_export_mode=embedded` when picture data or page images are requested, else `placeholder`;\n * `include_images` and `include_page_images` pick which data docling sends\n * - `images_scale` fixed at `PAGE_IMAGE_SCALE`; it sets picture and page image resolution only, OCR has its own scale\n * - image input: OCR always on and never full-page, whatever `ocr` and `forceOcr` say\n * - model presets pinned; a preset of a disabled stage is not sent\n * - fields docling-serve would default silently are sent with that default\n */\nfunction buildSettings(\n { fromFormat }: InputFormat,\n options: ResolvedOptions,\n { format, embedImages, pageImages }: FormatFields,\n): DoclingSettings {\n // Image has no text layer: without OCR it yields no text, and full-page OCR merges words.\n const isImage = fromFormat === 'image';\n const isMarkdown = format === 'md';\n return {\n fromFormats: fromFormat,\n toFormats: format,\n imageExportMode: embedImages || pageImages ? 'embedded' : 'placeholder',\n includeImages: embedImages,\n includePageImages: pageImages,\n imagesScale: PAGE_IMAGE_SCALE,\n mdCompactTables: isMarkdown ? true : null,\n mdPageBreakPlaceholder: isMarkdown ? '' : null,\n doOcr: isImage || options.ocr,\n forceOcr: !isImage && options.forceOcr,\n ocrPreset: options.ocrEngine,\n ocrLang: [...(options.ocrLang ?? [])],\n pdfBackend: options.pdfBackend,\n pipeline: options.pipeline,\n vlmPipelinePreset: options.pipeline === 'vlm' ? VLM_PIPELINE_PRESET : null,\n doTableStructure: true,\n tableMode: 'accurate',\n tableStructurePreset: TABLE_STRUCTURE_PRESET,\n tableCellMatching: true,\n doPdfHeadingHierarchy: options.headingHierarchy,\n doFormulaEnrichment: options.formulaEnrichment,\n doCodeEnrichment: options.codeEnrichment,\n codeFormulaPreset: options.formulaEnrichment || options.codeEnrichment ? CODE_FORMULA_PRESET : null,\n doChartExtraction: options.chartExtraction,\n chartExtractionPreset: options.chartExtraction ? CHART_EXTRACTION_PRESET : null,\n doPictureClassification: false,\n doPictureDescription: false,\n pageRange: options.pageRange === undefined ? null : [options.pageRange[0], options.pageRange[1]],\n documentTimeout: options.documentTimeout ?? null,\n abortOnError: false,\n };\n}\n\n/**\n * **Builds the multipart body from the settings, so sent fields and returned settings cannot differ**.\n *\n * - field name: settings key in snake_case (`ocrPreset` → `ocr_preset`)\n * - `null` not sent; lists as repeated fields (empty list: not sent); booleans and numbers as strings\n * - input: file name and MIME type matching `from_formats`\n */\nfunction buildFormData(input: ConvertInput, { mimeType, fileName }: InputFormat, settings: DoclingSettings): FormData {\n const form = new FormData();\n // Blob does not accept SharedArrayBuffer-backed input: copy only that into a fresh ArrayBuffer.\n const bytes = input.buffer instanceof ArrayBuffer ? (input as Uint8Array<ArrayBuffer>) : new Uint8Array(input);\n form.append('files', new Blob([bytes], { type: mimeType }), fileName);\n for (const [key, value] of Object.entries(settings)) {\n const name = key.replace(MATCH_UPPER_CASE, (letter) => `_${letter.toLowerCase()}`);\n for (const item of value === null ? [] : Array.isArray(value) ? value : [value]) {\n form.append(name, String(item));\n }\n }\n return form;\n}\n"
8
+ "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { ERR, fail, ok } from './core/result.js';\nimport { isPlainObject } from './core/validate.js';\nimport type { CapabilityLimits, CapabilityPreset, CapabilityStage, Result, ServerCapabilities } from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Loosely read JSON object; every field is checked before use. */\ntype JsonObject = Record<string, unknown>;\n\n// -------------------------------------------------------------------\n// --- 2. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Maps the `GET /v1/capabilities` payload to camelCase `ServerCapabilities`**.\n *\n * - lenient per field: missing or mistyped values become `[]`, `''`, `null` or `false`, so new server fields or\n * removed ones never fail the call\n * - non-object body: `invalid_response`\n */\nexport function readCapabilities(body: unknown): Result<ServerCapabilities> {\n if (!isPlainObject(body)) {\n return fail(ERR.INVALID_RESPONSE('Capabilities response is not a JSON object'));\n }\n const targets = objectOf(body.targets);\n const features = objectOf(body.features);\n return ok({\n versions: Object.fromEntries(\n Object.entries(objectOf(body.versions)).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n ),\n stages: Object.fromEntries(\n Object.entries(objectOf(body.stages)).map(([name, stage]) => [name, readStage(objectOf(stage))]),\n ),\n sources: stringsOf(body.sources),\n targets: { allowed: stringsOf(targets.allowed), default: stringOf(targets.default) },\n outputFormats: stringsOf(body.output_formats),\n imageExportModes: stringsOf(body.image_export_modes),\n limits: readLimits(objectOf(body.limits)),\n features: {\n apiKeyRequired: features.api_key_required === true,\n artifactStorage: features.artifact_storage === true,\n websocket: features.websocket === true,\n },\n });\n}\n\n// -------------------------------------------------------------------\n// --- 3. Private Functions\n// -------------------------------------------------------------------\n\n/** Pipeline stage; presets without a string `id` are dropped. */\nfunction readStage(stage: JsonObject): CapabilityStage {\n const presets: CapabilityPreset[] = [];\n for (const item of Array.isArray(stage.presets) ? stage.presets : []) {\n const preset = objectOf(item);\n if (typeof preset.id === 'string') {\n presets.push({\n id: preset.id,\n name: stringOf(preset.name),\n description: typeof preset.description === 'string' ? preset.description : null,\n source: stringOf(preset.source),\n });\n }\n }\n return {\n option: stringOf(stage.option),\n customConfigOption: typeof stage.custom_config_option === 'string' ? stage.custom_config_option : null,\n default: stringOf(stage.default),\n presets,\n };\n}\n\n/** Server limits; non-numbers become `null`. */\nfunction readLimits(limits: JsonObject): CapabilityLimits {\n return {\n maxDocumentTimeout: numberOf(limits.max_document_timeout),\n maxImagesScale: numberOf(limits.max_images_scale),\n maxSourcesPerRequest: numberOf(limits.max_sources_per_request),\n maxNumPages: numberOf(limits.max_num_pages),\n maxFileSize: numberOf(limits.max_file_size),\n };\n}\n\n/** Plain object, or `{}` for anything else. */\nfunction objectOf(value: unknown): JsonObject {\n return isPlainObject(value) ? value : {};\n}\n\n/** String entries of an array; `[]` for a non-array. */\nfunction stringsOf(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [];\n}\n\n/** String, or `''` for anything else. */\nfunction stringOf(value: unknown): string {\n return typeof value === 'string' ? value : '';\n}\n\n/** Finite number, or `null` for anything else. */\nfunction numberOf(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n",
9
+ "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Result } from '../types.js';\nimport { ERR, fail, ok } from './result.js';\n\n// -------------------------------------------------------------------\n// --- 1. Constants\n// -------------------------------------------------------------------\n\n/** Error code Bun and Node set when a body exceeds the maximum string length. */\nconst STRING_TOO_LONG = 'ERR_STRING_TOO_LONG';\n\n/** Matches the out-of-memory message of JavaScriptCore (`Out of memory`) and V8 (`... out of memory`). */\nconst MATCH_OUT_OF_MEMORY = /out of memory/i;\n\n/** Matches whitespace runs collapsed in body snippets. */\nconst MATCH_WHITESPACE = /\\s+/g;\n\n/** Characters of a non-JSON body quoted in the error message. */\nconst BODY_SNIPPET_LENGTH = 200;\n\n// -------------------------------------------------------------------\n// --- 2. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Executes `fetch` and parses the JSON body into a `Result`**.\n *\n * - non-2xx: `http` with FastAPI `detail`; unparsable 2xx body: `invalid_response`\n * - body too large for a string or for memory: `invalid_response`, as a retry fails the same way\n * - aborted signal: `aborted`; anything else thrown: `network`\n */\nexport async function fetchJson(fetchFn: typeof fetch, url: string, init: RequestInit): Promise<Result<unknown>> {\n try {\n const res = await fetchFn(url, init);\n const text = await res.text();\n if (!res.ok) {\n return fail(ERR.HTTP(res.status, errorDetail(text)));\n }\n try {\n return ok(JSON.parse(text));\n } catch {\n return fail(ERR.INVALID_RESPONSE(`Response body is not valid JSON: ${bodySnippet(text)}`, res.status));\n }\n } catch (e) {\n const message = errorMessage(e);\n if (isTooLarge(e)) {\n return fail(ERR.INVALID_RESPONSE(`Response body too large: ${message}`));\n }\n return fail(init.signal?.aborted ? ERR.ABORTED(message) : ERR.NETWORK(message));\n }\n}\n\n/** Extracts message, appending `cause.message` if present. */\nexport function errorMessage(e: unknown): string {\n if (!(e instanceof Error)) {\n return String(e);\n }\n return e.cause instanceof Error ? `${e.message}: ${e.cause.message}` : e.message;\n}\n\n// -------------------------------------------------------------------\n// --- 3. Private Functions\n// -------------------------------------------------------------------\n\n/** Checks whether an error indicates body size exceeded memory or maximum string length. */\nfunction isTooLarge(e: unknown): boolean {\n if (e instanceof RangeError) {\n return true;\n }\n if (!(e instanceof Error)) {\n return false;\n }\n return (e as Error & { code?: unknown }).code === STRING_TOO_LONG || MATCH_OUT_OF_MEMORY.test(e.message);\n}\n\n/** First 200 characters of a body with whitespace collapsed; `(empty body)` for a blank one. */\nfunction bodySnippet(text: string): string {\n const collapsed = text.replace(MATCH_WHITESPACE, ' ').trim();\n return collapsed === '' ? '(empty body)' : collapsed.slice(0, BODY_SNIPPET_LENGTH);\n}\n\n/** Extracts FastAPI 'detail' from response body, falling back to raw text (up to 500 characters) or 'no response body'. */\nfunction errorDetail(text: string): string {\n try {\n const body: unknown = JSON.parse(text);\n if (body && typeof body === 'object' && 'detail' in body) {\n const { detail } = body;\n return typeof detail === 'string' ? detail : JSON.stringify(detail);\n }\n } catch {}\n return text.slice(0, 500) || 'no response body';\n}\n",
10
+ "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\n// -------------------------------------------------------------------\n// --- 1. Constants\n// -------------------------------------------------------------------\n\n/** Bytes at the end of a PDF searched for `startxref`; the trailer sits within the last few hundred bytes. */\nconst TAIL_LENGTH = 2048;\n\n/** Matches `startxref` with its byte offset (group 1); incremental updates repeat it, the last one counts. */\nconst MATCH_STARTXREF = /startxref\\s+(\\d+)/g;\n\n/** Bytes searched for `%PDF-`: a header may start at offsets 0 to 1023, so its 5 bytes end by 1028. */\nconst HEADER_SEARCH_LENGTH = 1028;\n\n// -------------------------------------------------------------------\n// --- 2. Exported Functions\n// -------------------------------------------------------------------\n\n/** Matches a `%PDF-` header starting within the first 1024 bytes. */\nexport function isPdf(bytes: unknown): bytes is Uint8Array {\n if (!(bytes instanceof Uint8Array) || bytes.length === 0) {\n return false;\n }\n const head = bytes.subarray(0, HEADER_SEARCH_LENGTH);\n for (let i = 0; i + 5 <= head.length; i++) {\n if (\n head[i] === 0x25 &&\n head[i + 1] === 0x50 &&\n head[i + 2] === 0x44 &&\n head[i + 3] === 0x46 &&\n head[i + 4] === 0x2d\n ) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * **Returns cross-reference offset if PDF is truncated**: last `startxref` points at or past EOF.\n *\n * - typical for aborted downloads; docling then fails with a vague load error\n * - only the last 2 KB are read, as latin1\n * - returns `undefined` when offset lies inside file or no `startxref` found\n */\nexport function findTruncatedXref(bytes: Uint8Array): number | undefined {\n const tail = new TextDecoder('latin1').decode(bytes.subarray(Math.max(0, bytes.length - TAIL_LENGTH)));\n const last = [...tail.matchAll(MATCH_STARTXREF)].at(-1);\n const offset = last === undefined ? undefined : Number(last[1]);\n return offset !== undefined && offset >= bytes.length ? offset : undefined;\n}\n",
11
+ "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { isPdf } from './pdf.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Detected input format and how it is sent to docling-serve. */\nexport type InputFormat = {\n /** docling's `from_formats` value. */\n fromFormat: 'pdf' | 'image';\n /** MIME type of the multipart file part. */\n mimeType: string;\n /** File name of the multipart file part; docling reads the format from its extension. */\n fileName: string;\n};\n\n/** Image format recognized by byte signatures at fixed offsets. */\ntype ImageSignature = {\n mimeType: string;\n extension: string;\n /** Byte runs that must all match, each at its offset. */\n parts: [offset: number, bytes: number[]][];\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Image formats docling reads with `from_formats=image` (checked live on docling-serve 1.36.0). */\nconst IMAGE_SIGNATURES: readonly ImageSignature[] = [\n { mimeType: 'image/png', extension: 'png', parts: [[0, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]]] },\n { mimeType: 'image/jpeg', extension: 'jpg', parts: [[0, [0xff, 0xd8, 0xff]]] },\n { mimeType: 'image/tiff', extension: 'tiff', parts: [[0, [0x49, 0x49, 0x2a, 0x00]]] },\n { mimeType: 'image/tiff', extension: 'tiff', parts: [[0, [0x4d, 0x4d, 0x00, 0x2a]]] },\n {\n mimeType: 'image/webp',\n extension: 'webp',\n parts: [\n [0, [0x52, 0x49, 0x46, 0x46]],\n [8, [0x57, 0x45, 0x42, 0x50]],\n ],\n },\n];\n\n/** Format of PDF input. */\nconst PDF_FORMAT: InputFormat = { fromFormat: 'pdf', mimeType: 'application/pdf', fileName: 'document.pdf' };\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Detects the input format by magic bytes**.\n *\n * - image signatures must start at byte 0; PDF: `%PDF-` within the first 1024 bytes\n * - images are checked first, so an image whose data happens to contain `%PDF-` is still an image\n * - returns `undefined` for empty, non-`Uint8Array` or unrecognized input\n */\nexport function detectInputFormat(bytes: unknown): InputFormat | undefined {\n if (!(bytes instanceof Uint8Array) || bytes.length === 0) {\n return undefined;\n }\n const image = IMAGE_SIGNATURES.find(({ parts }) =>\n parts.every(([offset, run]) => run.every((byte, i) => bytes[offset + i] === byte)),\n );\n if (image !== undefined) {\n return { fromFormat: 'image', mimeType: image.mimeType, fileName: `document.${image.extension}` };\n }\n return isPdf(bytes) ? PDF_FORMAT : undefined;\n}\n",
12
+ "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { ERR, fail, ok } from './core/result.js';\nimport {\n invalidValue,\n isBoolean,\n isOneOf,\n isPlainObject,\n OPTIONS_OBJECT_EXPECTED,\n type OptionRule,\n validateKeys,\n} from './core/validate.js';\nimport type {\n CallOptions,\n ClientOptions,\n DoclingConfig,\n DoclingOptions,\n DocumentImageMode,\n DocumentOptions,\n ImageOptions,\n JobRef,\n MarkdownImageMode,\n MarkdownJobOutput,\n MarkdownOptions,\n PollOptions,\n Result,\n} from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n/** Factory-only option keys; they fall back to the server default when omitted. */\ntype FactoryOnly = Exclude<keyof ClientOptions, keyof DoclingOptions>;\n\n/** docling options with every per-call default filled in. */\nexport type ResolvedOptions = Required<DoclingOptions> & Pick<ClientOptions, FactoryOnly>;\n\n/** Validated client configuration. */\nexport type ResolvedConfig = {\n /** Base URL without trailing slash. */\n baseUrl: string;\n apiKey?: string;\n fetch: typeof fetch;\n /** Time limit per request in ms; unset means no limit. */\n timeoutMs?: number;\n /** Delay between job helper status polls in ms; defaults to `DEFAULT_POLL_MS`. */\n pollMs: number;\n /** Factory defaults merged over `DEFAULT_OPTIONS`. */\n defaults: ResolvedOptions;\n};\n\n/** Validated poll settings for job helpers. */\nexport type PollCall = {\n pollMs: number;\n signal?: AbortSignal;\n};\n\n/** Validated md call: server options, image handling and signal. */\nexport type MarkdownCall = {\n options: ResolvedOptions;\n output: MarkdownJobOutput;\n signal?: AbortSignal;\n};\n\n/** Validated document call: server options, picture data mode, page images and signal. */\nexport type DocumentCall = {\n options: ResolvedOptions;\n images: DocumentImageMode;\n pageImages: boolean;\n signal?: AbortSignal;\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Allowed `pipeline` values. */\nconst PIPELINES = ['standard', 'vlm'] as const;\n\n/** Allowed `pdfBackend` values. */\nconst PDF_BACKENDS = ['docling_parse', 'pypdfium2'] as const;\n\n/** Allowed `images` values of md calls. */\nconst MARKDOWN_IMAGE_MODES: readonly MarkdownImageMode[] = ['none', 'placeholder', 'extract'];\n\n/** Allowed `images` values of document calls. */\nconst DOCUMENT_IMAGE_MODES: readonly DocumentImageMode[] = ['embedded', 'placeholder'];\n\n/** Defaults of every docling option sent explicitly. */\nexport const DEFAULT_OPTIONS: Readonly<ResolvedOptions> = Object.freeze({\n headingHierarchy: true,\n formulaEnrichment: true,\n codeEnrichment: false,\n chartExtraction: false,\n pipeline: 'standard',\n pdfBackend: 'docling_parse',\n ocr: true,\n forceOcr: false,\n ocrEngine: 'auto',\n});\n\n/** Rules for docling options, accepted by the factory and every conversion call. */\nconst CALL_OPTION_RULES: Record<keyof DoclingOptions, OptionRule> = {\n headingHierarchy: isBoolean,\n formulaEnrichment: isBoolean,\n codeEnrichment: isBoolean,\n chartExtraction: isBoolean,\n pipeline: (value) => isOneOf(value, PIPELINES),\n pdfBackend: (value) => isOneOf(value, PDF_BACKENDS),\n ocr: isBoolean,\n forceOcr: isBoolean,\n ocrEngine: (value) => typeof value === 'string' && value !== '',\n};\n\n/** Rules for factory options: per-call options plus the factory-only ones. */\nconst CLIENT_OPTION_RULES: Record<keyof ClientOptions, OptionRule> = {\n ...CALL_OPTION_RULES,\n ocrLang: isLanguageList,\n pageRange: isPageRange,\n documentTimeout: isPositiveNumber,\n};\n\n/** Rules for md call options; `imageOptions` keys are checked by `resolveImageOutput`. */\nconst MARKDOWN_RULES: Record<keyof MarkdownOptions, OptionRule> = {\n ...CALL_OPTION_RULES,\n signal: isAbortSignal,\n images: (value) => isOneOf(value, MARKDOWN_IMAGE_MODES),\n imageOptions: isPlainObject,\n};\n\n/** Rules for document call options. */\nconst DOCUMENT_RULES: Record<keyof DocumentOptions, OptionRule> = {\n ...CALL_OPTION_RULES,\n signal: isAbortSignal,\n images: (value) => isOneOf(value, DOCUMENT_IMAGE_MODES),\n pageImages: isBoolean,\n};\n\n/** Rules for image extraction options. */\nconst IMAGE_OPTION_RULES: Record<keyof ImageOptions, OptionRule> = {\n prefix: isImagePrefix,\n omitSmall: isBoolean,\n};\n\n/** Rules for `check` and `capabilities` options. */\nconst CHECK_RULES: Record<keyof CallOptions, OptionRule> = {\n signal: isAbortSignal,\n};\n\n/** Rules for `waitForJob` options. */\nconst POLL_RULES: Record<keyof PollOptions, OptionRule> = {\n ...CHECK_RULES,\n pollMs: isTimerDelay,\n};\n\n/** Rules for `runMarkdown` options: md call options plus `pollMs`. */\nconst RUN_MARKDOWN_RULES: Record<keyof (MarkdownOptions & PollOptions), OptionRule> = {\n ...MARKDOWN_RULES,\n ...POLL_RULES,\n};\n\n/** Rules for `runDocument` options: document call options plus `pollMs`. */\nconst RUN_DOCUMENT_RULES: Record<keyof (DocumentOptions & PollOptions), OptionRule> = {\n ...DOCUMENT_RULES,\n ...POLL_RULES,\n};\n\n/** Rules for factory configuration; the keys of `options` are checked separately. */\nconst CONFIG_RULES: Record<keyof DoclingConfig, OptionRule> = {\n baseUrl: isHttpUrl,\n apiKey: (value) => typeof value === 'string' && value !== '',\n fetch: (value) => typeof value === 'function',\n timeoutMs: isTimerDelay,\n pollMs: isTimerDelay,\n options: isPlainObject,\n};\n\n/** Default delay in ms between job helper status polls. */\nconst DEFAULT_POLL_MS = 10;\n\n/** Job id of word characters and `-` only, so it cannot leave the URL path segment. */\nconst MATCH_JOB_ID = /^[\\w-]+$/;\n\n/** Matches BCP-47 language tags (e.g. 'en', 'de-AT'). */\nconst MATCH_LANGUAGE_TAG = /^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;\n\n/** Matches path prefixes free of md link delimiters. */\nconst MATCH_IMAGE_PREFIX = /^[^\\s()<>]+$/;\n\n/** Matches one or more trailing slashes of a base URL. */\nconst MATCH_TRAILING_SLASHES = /\\/+$/;\n\n/** Matches HTTP or HTTPS protocol schemes. */\nconst MATCH_HTTP_PROTOCOL = /^https?:$/;\n\n/** Maximum timer delay in ms (2^31 - 1); Node timers overflow above this and fire after 1 ms. */\nconst MAX_TIMEOUT_MS = 2_147_483_647;\n\n/** Error message for a missing or malformed job object. */\nconst INVALID_JOB = 'Expected the job object returned by submitMarkdown() or submitDocument()';\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Validates factory configuration**.\n *\n * - `baseUrl` is required; trailing `/` are removed\n * @throws `TypeError` on invalid configuration.\n */\nexport function resolveConfig(config: unknown): ResolvedConfig {\n if (!isPlainObject(config)) {\n throw new TypeError('Invalid config: expected an object');\n }\n const {\n baseUrl,\n apiKey,\n fetch: fetchFn,\n timeoutMs,\n pollMs = DEFAULT_POLL_MS,\n options,\n } = validateKeys<DoclingConfig>(config, CONFIG_RULES);\n if (baseUrl === undefined) {\n throw new TypeError(invalidValue('baseUrl'));\n }\n const defaults = {\n ...DEFAULT_OPTIONS,\n ...(options === undefined ? {} : validateKeys(options, CLIENT_OPTION_RULES)),\n };\n return {\n baseUrl: baseUrl.replace(MATCH_TRAILING_SLASHES, ''),\n ...(apiKey === undefined ? {} : { apiKey }),\n fetch: fetchFn ?? fetch,\n ...(timeoutMs === undefined ? {} : { timeoutMs }),\n pollMs,\n defaults,\n };\n}\n\n/**\n * Merges and validates md call options against factory defaults.\n * @throws `TypeError` on invalid options.\n */\nexport function resolveMarkdownCall(defaults: Readonly<ResolvedOptions>, options: unknown): MarkdownCall {\n return toMarkdownCall(defaults, validateKeys<MarkdownOptions>(callObject(options), MARKDOWN_RULES));\n}\n\n/**\n * Merges and validates document call options against factory defaults.\n * @throws `TypeError` on invalid options.\n */\nexport function resolveDocumentCall(defaults: Readonly<ResolvedOptions>, options: unknown): DocumentCall {\n return toDocumentCall(defaults, validateKeys<DocumentOptions>(callObject(options), DOCUMENT_RULES));\n}\n\n/**\n * Merges md call options and poll settings; `pollMs` defaults to factory `pollMs`.\n * @throws `TypeError` on invalid options.\n */\nexport function resolveRunMarkdownCall(\n defaults: Readonly<ResolvedOptions>,\n defaultPollMs: number,\n options: unknown,\n): MarkdownCall & PollCall {\n const { pollMs = defaultPollMs, ...call } = validateKeys<MarkdownOptions & PollOptions>(\n callObject(options),\n RUN_MARKDOWN_RULES,\n );\n return { ...toMarkdownCall(defaults, call), pollMs };\n}\n\n/**\n * Merges document call options and poll settings; `pollMs` defaults to factory `pollMs`.\n * @throws `TypeError` on invalid options.\n */\nexport function resolveRunDocumentCall(\n defaults: Readonly<ResolvedOptions>,\n defaultPollMs: number,\n options: unknown,\n): DocumentCall & PollCall {\n const { pollMs = defaultPollMs, ...call } = validateKeys<DocumentOptions & PollOptions>(\n callObject(options),\n RUN_DOCUMENT_RULES,\n );\n return { ...toDocumentCall(defaults, call), pollMs };\n}\n\n/**\n * Checks signal-only call options (`check`, `capabilities`).\n * @throws `TypeError` on invalid options.\n */\nexport function resolveCheckOptions(options: unknown): CallOptions {\n return validateKeys<CallOptions>(callObject(options), CHECK_RULES);\n}\n\n/**\n * Checks `waitForJob` options; `pollMs` defaults to factory `pollMs`.\n * @throws `TypeError` on invalid options.\n */\nexport function resolvePollOptions(defaultPollMs: number, options: unknown): PollCall {\n const { pollMs = defaultPollMs, signal } = validateKeys<PollOptions>(callObject(options), POLL_RULES);\n return { pollMs, ...(signal === undefined ? {} : { signal }) };\n}\n\n/**\n * **Checks a job object against the shape `submitMarkdown()` and `submitDocument()` return**.\n *\n * - never throws: a malformed job is `invalid_input`\n * - `settings` and other extra keys are ignored and not returned\n */\nexport function validateJob(job: unknown): Result<JobRef> {\n if (!isPlainObject(job) || !isJobId(job.id)) {\n return fail(ERR.INVALID_INPUT(INVALID_JOB));\n }\n if (job.kind === 'document') {\n return ok({ kind: 'document', id: job.id });\n }\n if (job.kind !== 'markdown' || !isPlainObject(job.output) || !isOneOf(job.output.images, MARKDOWN_IMAGE_MODES)) {\n return fail(ERR.INVALID_INPUT(INVALID_JOB));\n }\n try {\n return ok({\n kind: 'markdown',\n id: job.id,\n output: resolveImageOutput(job.output.images, job.output.imageOptions),\n });\n } catch (error) {\n return fail(ERR.INVALID_INPUT(`${INVALID_JOB}: ${(error as Error).message}`));\n }\n}\n\n/** Task id `check` accepts: word characters and `-` only, so it cannot leave the URL path segment. */\nexport function isJobId(value: unknown): value is string {\n return typeof value === 'string' && MATCH_JOB_ID.test(value);\n}\n\n// -------------------------------------------------------------------\n// --- 4. Private Functions\n// -------------------------------------------------------------------\n\n/**\n * Returns call options as a plain object (`undefined` becomes `{}`).\n * @throws `TypeError` when options is not a plain object.\n */\nfunction callObject(options: unknown): Record<string, unknown> {\n if (options === undefined) {\n return {};\n }\n if (!isPlainObject(options)) {\n throw new TypeError(OPTIONS_OBJECT_EXPECTED);\n }\n return options;\n}\n\n/**\n * Splits validated md call options into server options over the defaults, image handling and signal.\n * @throws `TypeError` on a missing, unexpected or invalid `imageOptions`.\n */\nfunction toMarkdownCall(defaults: Readonly<ResolvedOptions>, options: Partial<MarkdownOptions>): MarkdownCall {\n const { signal, images = 'placeholder', imageOptions, ...docling } = options;\n const output = resolveImageOutput(images, imageOptions);\n return { options: { ...defaults, ...docling }, output, ...(signal === undefined ? {} : { signal }) };\n}\n\n/** Splits validated document call options into server options over the defaults, image modes and signal. */\nfunction toDocumentCall(defaults: Readonly<ResolvedOptions>, options: Partial<DocumentOptions>): DocumentCall {\n const { signal, images = 'embedded', pageImages = false, ...docling } = options;\n return { options: { ...defaults, ...docling }, images, pageImages, ...(signal === undefined ? {} : { signal }) };\n}\n\n/**\n * **Combines image mode and image options into the md job output**.\n *\n * - `imageOptions` with `prefix` is required with `'extract'` and not allowed otherwise\n * @throws `TypeError` on a missing, unexpected or invalid `imageOptions`.\n */\nfunction resolveImageOutput(images: MarkdownImageMode, imageOptions: unknown): MarkdownJobOutput {\n if (images !== 'extract') {\n if (imageOptions !== undefined) {\n throw new TypeError(`Option \"imageOptions\" is not supported without images: 'extract'`);\n }\n return { images };\n }\n if (imageOptions === undefined) {\n throw new TypeError(`Option \"imageOptions\" is required with images: 'extract'`);\n }\n if (!isPlainObject(imageOptions)) {\n throw new TypeError(invalidValue('imageOptions'));\n }\n const { prefix, omitSmall = true } = validateKeys<ImageOptions>(imageOptions, IMAGE_OPTION_RULES, 'imageOptions.');\n if (prefix === undefined) {\n throw new TypeError('Option \"imageOptions.prefix\" is required');\n }\n return { images, imageOptions: { prefix, omitSmall } };\n}\n\n/** Finite number greater than zero. */\nfunction isPositiveNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0;\n}\n\n/** Integer ms from 1 to `MAX_TIMEOUT_MS`; `AbortSignal.timeout` throws on fractions, `setTimeout` overflows above. */\nfunction isTimerDelay(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= MAX_TIMEOUT_MS;\n}\n\n/** 1-based ascending integer pair `[from, to]`. */\nfunction isPageRange(value: unknown): value is [number, number] {\n return (\n Array.isArray(value) &&\n value.length === 2 &&\n Number.isInteger(value[0]) &&\n Number.isInteger(value[1]) &&\n value[0] >= 1 &&\n value[1] >= value[0]\n );\n}\n\n/** Array of BCP-47 language tags; empty means the OCR engine default. */\nfunction isLanguageList(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((tag) => typeof tag === 'string' && MATCH_LANGUAGE_TAG.test(tag));\n}\n\n/** Path prefix without md-breaking characters. */\nfunction isImagePrefix(value: unknown): value is string {\n return typeof value === 'string' && MATCH_IMAGE_PREFIX.test(value);\n}\n\n/** `AbortSignal` instance. */\nfunction isAbortSignal(value: unknown): value is AbortSignal {\n return value instanceof AbortSignal;\n}\n\n/**\n * **HTTP or HTTPS URL that routes can be appended to**.\n *\n * - no `?` or `#`, even empty ones: `${baseUrl}${route}` would put the route into the query or fragment\n * - no user name or password: Node's `fetch` refuses such URLs; the key belongs in `apiKey`\n */\nfunction isHttpUrl(value: unknown): value is string {\n if (typeof value !== 'string' || !URL.canParse(value) || value.includes('?') || value.includes('#')) {\n return false;\n }\n const url = new URL(value);\n return MATCH_HTTP_PROTOCOL.test(url.protocol) && url.username === '' && url.password === '';\n}\n",
13
+ "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { ERR, fail, ok } from './core/result.js';\nimport { isPlainObject } from './core/validate.js';\nimport type { DoclingDocument } from './document.js';\nimport { extractImages, extractPageImages, removeImagePlaceholders } from './images.js';\nimport type {\n ConversionFailure,\n ConvertedDocument,\n ConvertedMarkdown,\n MarkdownJobOutput,\n MarkdownWarning,\n Result,\n ServerWarning,\n TaskFailure,\n} from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n// biome-ignore-start lint/style/useNamingConvention: mirrors docling-serve's snake_case JSON\n/** Untrusted subset of docling-serve conversion response payload. */\ntype DoclingConvertResponse = {\n status?: unknown;\n document?: { md_content?: unknown; json_content?: unknown } | null;\n errors?: (DoclingErrorItem | null)[];\n failure?: DoclingFailureInfo | null;\n};\n\n/** Untrusted docling `PublicFailureInfo` of a failed task. */\nexport type DoclingFailureInfo = {\n message?: unknown;\n category?: unknown;\n phase?: unknown;\n retryable?: unknown;\n};\n\n/** Untrusted docling `ErrorItem`; `category` and `page_no` only in newer docling. */\ntype DoclingErrorItem = {\n error_message?: unknown;\n component_type?: unknown;\n module_name?: unknown;\n category?: unknown;\n page_no?: unknown;\n};\n// biome-ignore-end lint/style/useNamingConvention: mirrors docling-serve's snake_case JSON\n\n/** Successful conversion: status, untrusted document payload, docling's non-fatal errors and failure info. */\ntype ServerOutput = {\n status: 'success' | 'partial_success';\n document: NonNullable<DoclingConvertResponse['document']>;\n warnings: ServerWarning[];\n /** Failure message docling sent along; `undefined` if none. */\n failureMessage: string | undefined;\n failure: TaskFailure | null;\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Matches older docling's page error `Page 1 failed to parse.`; group 1: 0-based page index. */\nconst MATCH_FAILED_PAGE = /^Page (\\d+) failed to parse\\./;\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **Reads `md_content` and applies the image handling**.\n *\n * - `'extract'`: embedded images become `images` and file links; `'none'`: placeholders removed\n * - otherwise docling's md is returned unchanged\n */\nexport function readMarkdown(body: unknown, output: MarkdownJobOutput): Result<Omit<ConvertedMarkdown, 'versions'>> {\n const server = readConvertResponse(body);\n if (!server.ok) {\n return server;\n }\n const markdown = server.data.document.md_content;\n if (markdown == null) {\n return missingContent(server.data, 'md_content');\n }\n if (typeof markdown !== 'string') {\n return fail(ERR.INVALID_RESPONSE('Response has no md_content'));\n }\n const warnings: MarkdownWarning[] = server.data.warnings;\n if (output.images === 'extract') {\n const extracted = extractImages(markdown, output.imageOptions);\n return ok({ ...extracted, warnings: [...warnings, ...extracted.warnings] });\n }\n const md = output.images === 'none' ? removeImagePlaceholders(markdown) : markdown;\n return ok({ markdown: md, images: [], warnings });\n}\n\n/**\n * **Reads `json_content`**.\n *\n * - only `schema_name` and `body` are checked, the rest is passed on as sent\n * - page images are moved from `pages[].image` to `pageImages`; undecodable ones stay and are reported after server warnings\n */\nexport function readDocument(body: unknown): Result<Omit<ConvertedDocument, 'versions'>> {\n const server = readConvertResponse(body);\n if (!server.ok) {\n return server;\n }\n const json = server.data.document.json_content;\n if (json == null) {\n return missingContent(server.data, 'json_content');\n }\n if (!isPlainObject(json) || json.schema_name !== 'DoclingDocument' || !isPlainObject(json.body)) {\n return fail(ERR.INVALID_RESPONSE('Response has no DoclingDocument in json_content'));\n }\n const { document, pageImages, warnings } = extractPageImages(json as DoclingDocument);\n return ok({ document, pageImages, warnings: [...server.data.warnings, ...warnings] });\n}\n\n/** Parses docling's task failure classification; `null` if absent. */\nexport function readFailure(failure: DoclingFailureInfo | null | undefined): TaskFailure | null {\n if (failure == null || typeof failure !== 'object') {\n return null;\n }\n return {\n category: readText(failure.category) ?? null,\n phase: readText(failure.phase) ?? null,\n retryable: typeof failure.retryable === 'boolean' ? failure.retryable : null,\n };\n}\n\n/** Non-empty string, or `undefined` if empty or not a string. */\nexport function readText(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\n// -------------------------------------------------------------------\n// --- 4. Private Functions\n// -------------------------------------------------------------------\n\n/**\n * **Splits a conversion response into success or failure**.\n *\n * - `success` and `partial_success` pass on the document with docling's error items as warnings\n * - any other status: `conversion_failed` with the failure message, else the joined error messages\n * - status missing, empty or not a string, and no failure: `invalid_response`\n */\nfunction readConvertResponse(body: unknown): Result<ServerOutput> {\n const res = (body ?? {}) as DoclingConvertResponse;\n const errors = Array.isArray(res.errors) ? res.errors : [];\n const warnings = errors.flatMap((error) => (error == null ? [] : readServerError(error)));\n const failureMessage = readText(res.failure?.message);\n const failure = readFailure(res.failure);\n if (res.status === 'success' || res.status === 'partial_success') {\n const document = isPlainObject(res.document) ? res.document : {};\n return ok({ status: res.status, document, warnings, failureMessage, failure });\n }\n if (readText(res.status) === undefined && res.failure == null) {\n return fail(ERR.INVALID_RESPONSE('Unexpected response: no conversion status'));\n }\n const messages = warnings.map(({ message }) => message).join('; ');\n const reason = failureMessage ?? (messages || `status: ${String(res.status)}`);\n return fail(ERR.CONVERSION_FAILED(reason, { errors: toServerErrors(warnings), failure }));\n}\n\n/**\n * **Result for a successful status without the requested content**.\n *\n * - `partial_success`, error items or a failure: `conversion_failed` with all server details\n * - plain `success` without any of them: `invalid_response`\n */\nfunction missingContent(server: ServerOutput, field: 'md_content' | 'json_content'): Result<never> {\n const { status, warnings, failureMessage, failure } = server;\n if (status !== 'partial_success' && warnings.length === 0 && failure === null) {\n const content = field === 'md_content' ? 'md_content' : 'DoclingDocument in json_content';\n return fail(ERR.INVALID_RESPONSE(`Response has no ${content}`));\n }\n const messages = warnings.map(({ message }) => message).join('; ');\n const reason = failureMessage ?? (messages || `status: ${status}, no ${field}`);\n return fail(ERR.CONVERSION_FAILED(reason, { errors: toServerErrors(warnings), failure }));\n}\n\n/** Server warnings as `ConversionFailure.errors`. */\nfunction toServerErrors(warnings: ServerWarning[]): ConversionFailure['errors'] {\n return warnings.map(({ message, details }) => ({ message, details }));\n}\n\n/**\n * **Reads one docling error item**.\n *\n * - items without `error_message` are dropped\n * - 1-based page from `page_no` (newer docling) or the older error text; `null` if unassigned\n */\nfunction readServerError(error: DoclingErrorItem): ServerWarning[] {\n const message = readText(error.error_message);\n if (message === undefined) {\n return [];\n }\n const pageIndex = MATCH_FAILED_PAGE.exec(message)?.[1];\n const page = isPageNumber(error.page_no) ? error.page_no : pageIndex === undefined ? null : Number(pageIndex) + 1;\n return [\n {\n code: 'server',\n message,\n details: {\n component: readText(error.component_type) ?? null,\n module: readText(error.module_name) ?? null,\n category: readText(error.category) ?? null,\n page,\n },\n },\n ];\n}\n\n/** Docling `page_no`: integer >= 1; 0, negatives and fractions are rejected. */\nfunction isPageNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 1;\n}\n",
14
+ "// Copyright 2026 Martin Winkler\n// SPDX-License-Identifier: Apache-2.0\n\nimport { readCapabilities } from './capabilities.js';\nimport { errorMessage, fetchJson } from './core/http.js';\nimport { detectInputFormat, type InputFormat } from './core/input.js';\nimport { findTruncatedXref } from './core/pdf.js';\nimport { ERR, fail, ok } from './core/result.js';\nimport { PAGE_IMAGE_SCALE } from './images.js';\nimport {\n type DocumentCall,\n isJobId,\n type MarkdownCall,\n type PollCall,\n type ResolvedOptions,\n resolveCheckOptions,\n resolveConfig,\n resolveDocumentCall,\n resolveMarkdownCall,\n resolvePollOptions,\n resolveRunDocumentCall,\n resolveRunMarkdownCall,\n validateJob,\n} from './options.js';\nimport { type DoclingFailureInfo, readDocument, readFailure, readMarkdown, readText } from './response.js';\nimport type {\n ConvertError,\n ConvertedDocument,\n ConvertedMarkdown,\n ConvertInput,\n DoclingClient,\n DoclingConfig,\n DoclingSettings,\n DocumentJob,\n JobRef,\n JobState,\n MarkdownJob,\n Result,\n ServerCapabilities,\n ServerVersions,\n WithSettings,\n} from './types.js';\n\n// -------------------------------------------------------------------\n// --- 1. Types\n// -------------------------------------------------------------------\n\n// biome-ignore-start lint/style/useNamingConvention: mirrors docling-serve's snake_case JSON\n/** Task status payload of docling-serve's submit and poll endpoints. */\ntype DoclingTaskStatus = {\n task_id?: unknown;\n task_status?: unknown;\n task_position?: unknown;\n error_message?: unknown;\n failure?: DoclingFailureInfo | null;\n};\n// biome-ignore-end lint/style/useNamingConvention: mirrors docling-serve's snake_case JSON\n\n/** Output format sent as `to_formats`, with its image fields. */\ntype FormatFields = {\n format: 'md' | 'json';\n /** Asks docling for base64 picture data (`image_export_mode=embedded`, `include_images=true`). */\n embedImages: boolean;\n /** Asks docling for base64 page images (`image_export_mode=embedded`, `include_page_images=true`). */\n pageImages: boolean;\n};\n\n/** Parsed JSON answer of a conversion POST, with the settings its form was built from. */\ntype Posted = {\n body: unknown;\n settings: DoclingSettings;\n};\n\n// -------------------------------------------------------------------\n// --- 2. Constants\n// -------------------------------------------------------------------\n\n/** Table structure model; pinned so the server's fallback preset cannot change table output. */\nconst TABLE_STRUCTURE_PRESET = 'tableformer_v1_accurate';\n\n/** Model of `pipeline: 'vlm'`. */\nconst VLM_PIPELINE_PRESET = 'granite_docling';\n\n/** Model of `chartExtraction`. */\nconst CHART_EXTRACTION_PRESET = 'granite_vision_v4';\n\n/** Model of `formulaEnrichment` and `codeEnrichment`. */\nconst CODE_FORMULA_PRESET = 'codeformulav2';\n\n/** Matches each upper-case letter of a camelCase settings key, for its snake_case form field name. */\nconst MATCH_UPPER_CASE = /[A-Z]/g;\n\n/** Error message for missing, empty or unrecognized input bytes. */\nconst INVALID_INPUT = 'Expected a non-empty PDF, PNG, JPEG, TIFF or WebP as Uint8Array';\n\n/** Error codes of requests the server answered; only these get server versions. */\nconst SERVER_ANSWERED: ReadonlySet<ConvertError['code']> = new Set([\n 'http',\n 'not_found',\n 'conversion_failed',\n 'invalid_response',\n]);\n\n/** Time limit for the `/version` request; a slower server gets `versions: null`. */\nconst VERSION_TIMEOUT_MS = 2000;\n\n/** Characters of an unusable task id quoted in the error message. */\nconst MAX_SHOWN_ID_LENGTH = 100;\n\n// -------------------------------------------------------------------\n// --- 3. Exported Functions\n// -------------------------------------------------------------------\n\n/**\n * **docling-serve client factory**.\n *\n * - validates configuration once; its only state is cached server versions\n * - returned functions resolve to `Result`; invalid options reject with `TypeError` before any request\n * - `timeoutMs` limits every request except `/version`, which has its own limit\n * - `pollMs` sets default delay between job helper status polls, overridable per call\n * @throws `TypeError` on invalid configuration.\n */\nexport function createDoclingClient(config: DoclingConfig): DoclingClient {\n const { baseUrl, apiKey, fetch: fetchFn, timeoutMs, pollMs, defaults } = resolveConfig(config);\n const headers: Record<string, string> = apiKey === undefined ? {} : { 'X-Api-Key': apiKey };\n /** Pending or resolved `/version` answer shared by all calls of this client. */\n let versionsCache: Promise<ServerVersions | null> | undefined;\n\n return {\n convertMarkdown,\n convertDocument,\n submitMarkdown,\n submitDocument,\n check: check as DoclingClient['check'],\n runMarkdown,\n runDocument,\n waitForJob: waitForJob as DoclingClient['waitForJob'],\n capabilities,\n };\n\n /** Converts PDF or image bytes to md in one request. */\n async function convertMarkdown(\n input: ConvertInput,\n options?: unknown,\n ): Promise<Result<WithSettings<ConvertedMarkdown>>> {\n const call = resolveMarkdownCall(defaults, options);\n const fields: FormatFields = { format: 'md', embedImages: call.output.images === 'extract', pageImages: false };\n const res = await post('/v1/convert/file', input, call.options, fields, call.signal);\n if (!res.ok) {\n return res;\n }\n const converted = await withVersions<ConvertedMarkdown>(readMarkdown(res.data.body, call.output));\n return converted.ok ? ok({ ...converted.data, settings: res.data.settings }) : converted;\n }\n\n /** Converts PDF or image bytes to a DoclingDocument in one request. */\n async function convertDocument(\n input: ConvertInput,\n options?: unknown,\n ): Promise<Result<WithSettings<ConvertedDocument>>> {\n const call = resolveDocumentCall(defaults, options);\n const fields: FormatFields = {\n format: 'json',\n embedImages: call.images === 'embedded',\n pageImages: call.pageImages,\n };\n const res = await post('/v1/convert/file', input, call.options, fields, call.signal);\n if (!res.ok) {\n return res;\n }\n const converted = await withVersions<ConvertedDocument>(readDocument(res.data.body));\n return converted.ok ? ok({ ...converted.data, settings: res.data.settings }) : converted;\n }\n\n /** Starts an async md conversion; the job carries the image handling for `check` and the sent settings. */\n async function submitMarkdown(input: ConvertInput, options?: unknown): Promise<Result<MarkdownJob>> {\n const call = resolveMarkdownCall(defaults, options);\n return await startMarkdownJob(input, call);\n }\n\n /** Starts an async document conversion; page images need no job field, `check` moves any it finds. */\n async function submitDocument(input: ConvertInput, options?: unknown): Promise<Result<DocumentJob>> {\n const call = resolveDocumentCall(defaults, options);\n return await startDocumentJob(input, call);\n }\n\n /** Submits an md job and polls it until done; resolves like `convertMarkdown`, with the job's settings. */\n async function runMarkdown(\n input: ConvertInput,\n options?: unknown,\n ): Promise<Result<WithSettings<ConvertedMarkdown>>> {\n const call = resolveRunMarkdownCall(defaults, pollMs, options);\n const job = await startMarkdownJob(input, call);\n if (!job.ok) {\n return job;\n }\n const done = await pollUntilDone<ConvertedMarkdown>(job.data, call);\n return done.ok ? ok({ ...done.data, settings: job.data.settings }) : done;\n }\n\n /** Submits a document job and polls it until done; resolves like `convertDocument`, with the job's settings. */\n async function runDocument(\n input: ConvertInput,\n options?: unknown,\n ): Promise<Result<WithSettings<ConvertedDocument>>> {\n const call = resolveRunDocumentCall(defaults, pollMs, options);\n const job = await startDocumentJob(input, call);\n if (!job.ok) {\n return job;\n }\n const done = await pollUntilDone<ConvertedDocument>(job.data, call);\n return done.ok ? ok({ ...done.data, settings: job.data.settings }) : done;\n }\n\n /** Polls an existing job until done; the job is validated and copied once, so later changes to it have no effect. */\n async function waitForJob(job: JobRef, options?: unknown): Promise<Result<ConvertedMarkdown | ConvertedDocument>> {\n const call = resolvePollOptions(pollMs, options);\n const valid = validateJob(job);\n return valid.ok ? pollUntilDone(valid.data, call) : valid;\n }\n\n /** Posts an md job for a validated call. */\n async function startMarkdownJob(input: ConvertInput, call: MarkdownCall): Promise<Result<MarkdownJob>> {\n const fields: FormatFields = { format: 'md', embedImages: call.output.images === 'extract', pageImages: false };\n const task = await submit(input, call.options, fields, call.signal);\n return task.ok\n ? ok({ kind: 'markdown', id: task.data.id, output: call.output, settings: task.data.settings })\n : task;\n }\n\n /** Posts a document job for a validated call. */\n async function startDocumentJob(input: ConvertInput, call: DocumentCall): Promise<Result<DocumentJob>> {\n const fields: FormatFields = {\n format: 'json',\n embedImages: call.images === 'embedded',\n pageImages: call.pageImages,\n };\n const task = await submit(input, call.options, fields, call.signal);\n return task.ok ? ok({ kind: 'document', id: task.data.id, settings: task.data.settings }) : task;\n }\n\n /**\n * **Polls a job until done**: waits `pollMs` after each `queued` or `running` status.\n *\n * - `job` must be validated: it is polled as is, without a new check per poll\n * - first poll runs immediately; at most one request in flight\n * - resolves to `done` result without `status`, or first error unchanged\n * - abort during wait resolves to `aborted` immediately; abort during request returns request error\n */\n async function pollUntilDone<T>(job: JobRef, { pollMs: waitMs, signal }: PollCall): Promise<Result<T>> {\n for (;;) {\n const state = await fetchJobState(job, signal);\n if (!state.ok) {\n return state;\n }\n if (state.data.status === 'done') {\n const { status: _done, ...result } = state.data;\n return ok(result as T);\n }\n if (!(await sleep(waitMs, signal))) {\n return fail(ERR.ABORTED(`Aborted while waiting for job ${job.id}`));\n }\n }\n }\n\n /** Polls a job and fetches its result when done; a malformed job is `invalid_input` without a request. */\n async function check(\n job: JobRef,\n options?: unknown,\n ): Promise<Result<JobState<ConvertedMarkdown | ConvertedDocument>>> {\n const { signal } = resolveCheckOptions(options);\n const valid = validateJob(job);\n return valid.ok ? fetchJobState(valid.data, signal) : valid;\n }\n\n /**\n * **Status request for a validated job; result download when done**.\n *\n * - unknown job id: `not_found` with `Unknown job id`; also once docling-serve deleted the task,\n * `DOCLING_SERVE_RESULT_REMOVAL_DELAY` (default 300 s) after the first result fetch\n * - task deleted between the status poll and the result fetch: `not_found` with `Result already fetched or expired`\n */\n async function fetchJobState(\n job: JobRef,\n signal: AbortSignal | undefined,\n ): Promise<Result<JobState<ConvertedMarkdown | ConvertedDocument>>> {\n const { id } = job;\n const res = await get(`/v1/status/poll/${id}`, signal);\n if (!res.ok) {\n const error =\n res.error.status === 404 ? ERR.NOT_FOUND(`Unknown job id: ${id} (${res.error.message})`) : res.error;\n return failWithVersions(error);\n }\n const task = (res.data ?? {}) as DoclingTaskStatus;\n switch (task.task_status) {\n case 'pending': {\n const position = typeof task.task_position === 'number' ? task.task_position : null;\n return ok({ status: 'queued', position });\n }\n case 'started':\n return ok({ status: 'running' });\n case 'success':\n case 'partial_success': {\n const result = await get(`/v1/result/${id}`, signal);\n if (!result.ok) {\n const error =\n result.error.status === 404\n ? ERR.NOT_FOUND(\n `Result already fetched or expired: ${id}; resubmit the PDF (${result.error.message})`,\n )\n : result.error;\n return failWithVersions(error);\n }\n const output =\n job.kind === 'markdown' ? readMarkdown(result.data, job.output) : readDocument(result.data);\n const done = await withVersions<ConvertedMarkdown | ConvertedDocument>(output);\n return done.ok ? ok({ status: 'done', ...done.data }) : done;\n }\n case 'failure':\n case 'skipped': {\n const reason =\n readText(task.failure?.message) ?? readText(task.error_message) ?? `status: ${task.task_status}`;\n const details = { errors: [], failure: readFailure(task.failure) };\n return failWithVersions(ERR.CONVERSION_FAILED(reason, details));\n }\n default:\n return failWithVersions(ERR.INVALID_RESPONSE(`Unexpected task status: ${String(task.task_status)}`));\n }\n }\n\n /**\n * **Queries `GET /v1/capabilities` on demand**.\n *\n * - older servers without the endpoint answer `http` (404)\n */\n async function capabilities(options?: unknown): Promise<Result<ServerCapabilities>> {\n const { signal } = resolveCheckOptions(options);\n const res = await get('/v1/capabilities', signal);\n if (!res.ok) {\n return failWithVersions(res.error);\n }\n const read = readCapabilities(res.data);\n return read.ok ? read : failWithVersions(read.error);\n }\n\n /** Posts the input to the async endpoint; resolves to the task id and the sent settings. */\n async function submit(\n input: ConvertInput,\n options: ResolvedOptions,\n fields: FormatFields,\n signal: AbortSignal | undefined,\n ): Promise<Result<{ id: string; settings: DoclingSettings }>> {\n const res = await post('/v1/convert/file/async', input, options, fields, signal);\n if (!res.ok) {\n return res;\n }\n const id: unknown = (res.data.body as DoclingTaskStatus | null)?.task_id;\n if (readText(id) === undefined) {\n return failWithVersions(ERR.INVALID_RESPONSE('Response has no task_id'));\n }\n if (!isJobId(id)) {\n const shown = JSON.stringify(id).slice(0, MAX_SHOWN_ID_LENGTH);\n return failWithVersions(ERR.INVALID_RESPONSE(`Response has an unusable task_id: ${shown}`));\n }\n return ok({ id, settings: res.data.settings });\n }\n\n /** Detects and checks the input format, then sends a multipart POST with timeout; errors already carry versions. */\n async function post(\n route: string,\n input: ConvertInput,\n options: ResolvedOptions,\n fields: FormatFields,\n signal: AbortSignal | undefined,\n ): Promise<Result<Posted>> {\n const format = readInputFormat(input);\n if (!format.ok) {\n return format;\n }\n const settings = buildSettings(format.data, options, fields);\n let body: FormData;\n try {\n body = buildFormData(input, format.data, settings);\n } catch (error) {\n return fail(ERR.INVALID_INPUT(`Input could not be prepared for upload: ${errorMessage(error)}`));\n }\n const limited = withTimeout(signal, timeoutMs);\n const res = await fetchJson(fetchFn, `${baseUrl}${route}`, {\n method: 'POST',\n headers,\n body,\n ...(limited === undefined ? {} : { signal: limited }),\n });\n return res.ok ? ok({ body: res.data, settings }) : failWithVersions(res.error);\n }\n\n /** GET request; `limit: false` skips `timeoutMs` (used by `/version`). */\n function get(route: string, signal: AbortSignal | undefined, limit = true): Promise<Result<unknown>> {\n const limited = limit ? withTimeout(signal, timeoutMs) : signal;\n return fetchJson(fetchFn, `${baseUrl}${route}`, {\n headers,\n ...(limited === undefined ? {} : { signal: limited }),\n });\n }\n\n /** Adds server versions to a parsed result, or to its error if the server answered. */\n async function withVersions<T>(result: Result<Omit<T, 'versions'>>): Promise<Result<T>> {\n if (!result.ok) {\n return failWithVersions(result.error);\n }\n return ok({ ...result.data, versions: await fetchVersions() } as T);\n }\n\n /** Adds server versions to errors of requests the server answered; other errors stay as they are. */\n async function failWithVersions<T>(error: ConvertError): Promise<Result<T>> {\n return fail(SERVER_ANSWERED.has(error.code) ? { ...error, versions: await fetchVersions() } : error);\n }\n\n /**\n * **Server versions, fetched once per client and cached**.\n *\n * - concurrent calls share one request\n * - `null` (unreachable, timed out or empty) is not cached; the next call asks again\n */\n function fetchVersions(): Promise<ServerVersions | null> {\n versionsCache ??= requestVersions().then((versions) => {\n if (versions === null) {\n versionsCache = undefined;\n }\n return versions;\n });\n return versionsCache;\n }\n\n /**\n * **Queries `/version` with its own timeout**.\n *\n * - ignores the caller signal, so aborting after the conversion does not fail the result\n * - resolves `null` after `VERSION_TIMEOUT_MS` even if `fetch` ignores the timeout signal\n */\n async function requestVersions(): Promise<ServerVersions | null> {\n const timeout = AbortSignal.timeout(VERSION_TIMEOUT_MS);\n const timedOut = new Promise<null>((resolve) => {\n timeout.addEventListener('abort', () => resolve(null), { once: true });\n });\n const res = await Promise.race([get('/version', timeout, false), timedOut]);\n if (res === null || !res.ok || res.data === null || typeof res.data !== 'object') {\n return null;\n }\n const versions = Object.entries(res.data).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n );\n return versions.length === 0 ? null : Object.fromEntries(versions);\n }\n}\n\n// -------------------------------------------------------------------\n// --- 4. Private Functions\n// -------------------------------------------------------------------\n\n/**\n * **Waits `ms` unless `signal` aborts**.\n *\n * - resolves `true` after the wait, `false` at once on abort (also when already aborted)\n * - clears its timer and removes its listener either way\n */\nfunction sleep(ms: number, signal: AbortSignal | undefined): Promise<boolean> {\n if (signal?.aborted) {\n return Promise.resolve(false);\n }\n return new Promise((resolve) => {\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve(true);\n }, ms);\n /** Ends the wait early. */\n function onAbort() {\n clearTimeout(timer);\n resolve(false);\n }\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\n/** Caller signal combined with a `timeoutMs` limit; either alone when the other is unset. */\nfunction withTimeout(signal: AbortSignal | undefined, timeoutMs: number | undefined): AbortSignal | undefined {\n if (timeoutMs === undefined) {\n return signal;\n }\n const timeout = AbortSignal.timeout(timeoutMs);\n return signal === undefined ? timeout : AbortSignal.any([signal, timeout]);\n}\n\n/**\n * **Input format by magic bytes; PDFs are also checked for truncation**.\n *\n * - unrecognized bytes or a truncated PDF: `invalid_input`\n */\nfunction readInputFormat(input: unknown): Result<InputFormat> {\n const format = detectInputFormat(input);\n if (format === undefined) {\n return fail(ERR.INVALID_INPUT(INVALID_INPUT));\n }\n const bytes = input as Uint8Array;\n const offset = format.fromFormat === 'pdf' ? findTruncatedXref(bytes) : undefined;\n return offset === undefined\n ? ok(format)\n : fail(\n ERR.INVALID_INPUT(\n `PDF is truncated: cross-reference offset ${offset} lies past the end of the file (${bytes.length} bytes)`,\n ),\n );\n}\n\n/**\n * **Every form field of a conversion request, as typed settings**.\n *\n * - md: `md_compact_tables=true`, empty page break placeholder; json sends neither\n * - images: `image_export_mode=embedded` when picture data or page images are requested, else `placeholder`;\n * `include_images` and `include_page_images` pick which data docling sends\n * - `images_scale` fixed at `PAGE_IMAGE_SCALE`; it sets picture and page image resolution only, OCR has its own scale\n * - PDF input: `forceOcr` enables OCR even with `ocr: false` (docling skips `force_ocr` when `do_ocr=false`)\n * - image input: OCR always on and never full-page, whatever `ocr` and `forceOcr` say\n * - model presets pinned; a preset of a disabled stage is not sent\n * - fields docling-serve would default silently are sent with that default\n */\nfunction buildSettings(\n { fromFormat }: InputFormat,\n options: ResolvedOptions,\n { format, embedImages, pageImages }: FormatFields,\n): DoclingSettings {\n const isImage = fromFormat === 'image';\n const isMarkdown = format === 'md';\n return {\n fromFormats: fromFormat,\n toFormats: format,\n imageExportMode: embedImages || pageImages ? 'embedded' : 'placeholder',\n includeImages: embedImages,\n includePageImages: pageImages,\n imagesScale: PAGE_IMAGE_SCALE,\n mdCompactTables: isMarkdown ? true : null,\n mdPageBreakPlaceholder: isMarkdown ? '' : null,\n doOcr: isImage || options.ocr || options.forceOcr,\n forceOcr: !isImage && options.forceOcr,\n ocrPreset: options.ocrEngine,\n ocrLang: [...(options.ocrLang ?? [])],\n pdfBackend: options.pdfBackend,\n pipeline: options.pipeline,\n vlmPipelinePreset: options.pipeline === 'vlm' ? VLM_PIPELINE_PRESET : null,\n doTableStructure: true,\n tableMode: 'accurate',\n tableStructurePreset: TABLE_STRUCTURE_PRESET,\n tableCellMatching: true,\n doPdfHeadingHierarchy: options.headingHierarchy,\n doFormulaEnrichment: options.formulaEnrichment,\n doCodeEnrichment: options.codeEnrichment,\n codeFormulaPreset: options.formulaEnrichment || options.codeEnrichment ? CODE_FORMULA_PRESET : null,\n doChartExtraction: options.chartExtraction,\n chartExtractionPreset: options.chartExtraction ? CHART_EXTRACTION_PRESET : null,\n doPictureClassification: false,\n doPictureDescription: false,\n pageRange: options.pageRange === undefined ? null : [options.pageRange[0], options.pageRange[1]],\n documentTimeout: options.documentTimeout ?? null,\n abortOnError: false,\n };\n}\n\n/**\n * **Builds the multipart body from the settings, so sent fields and returned settings cannot differ**.\n *\n * - field name: settings key in snake_case (`ocrPreset` → `ocr_preset`)\n * - `null` not sent; lists as repeated fields (empty list: not sent); booleans and numbers as strings\n * - input: file name and MIME type matching `from_formats`\n */\nfunction buildFormData(input: ConvertInput, { mimeType, fileName }: InputFormat, settings: DoclingSettings): FormData {\n const form = new FormData();\n const bytes = input.buffer instanceof ArrayBuffer ? (input as Uint8Array<ArrayBuffer>) : new Uint8Array(input);\n form.append('files', new Blob([bytes], { type: mimeType }), fileName);\n for (const [key, value] of Object.entries(settings)) {\n const name = key.replace(MATCH_UPPER_CASE, (letter) => `_${letter.toLowerCase()}`);\n for (const item of value === null ? [] : Array.isArray(value) ? value : [value]) {\n form.append(name, String(item));\n }\n }\n return form;\n}\n"
15
15
  ],
16
- "mappings": "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",
17
- "debugId": "A74469BA02A838B164756E2164756E21",
16
+ "mappings": "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",
17
+ "debugId": "1022B5E8A749497A64756E2164756E21",
18
18
  "names": []
19
19
  }