import { JSDOM } from 'jsdom'; import type { DecodedHtmlDocument, DecodedXmlDocument, DecodedXmlRow, ImportRuntimeAdapters, MarkupDocumentAdapter, TextDecoderAdapter } from '../src/importers/runtime-adapters'; import { decodeHtmlDocument, decodeHtmlLexically, isHtmlStackOverflow, shouldUseBoundedHtmlExtraction } from '../src/importers/html-extraction'; function walkXml(node: Element, path: string, rows: DecodedXmlRow[]): void { const attributes = [...node.attributes].map(attribute => `${attribute.name}="${attribute.value}"`).join('; '); const attributeValues = Object.fromEntries([...node.attributes].map(attribute => [attribute.name, attribute.value])); const text = [...node.childNodes] .filter(child => child.nodeType === 3 || child.nodeType === 4) .map(child => child.textContent?.trim() ?? '') .filter(Boolean) .join(' '); rows.push({ path, attributes, attributeValues, text }); [...node.children].forEach((child, index) => walkXml(child, `${path}/${child.nodeName}[${index + 1}]`, rows)); } export const nodeMarkupDocumentAdapter: MarkupDocumentAdapter = { decodeHtml(text: string): DecodedHtmlDocument { if (shouldUseBoundedHtmlExtraction(text)) return decodeHtmlLexically(text); try { const documentNode = new JSDOM(text, { contentType: 'text/html' }).window.document; return decodeHtmlDocument(documentNode); } catch (error) { if (isHtmlStackOverflow(error)) return decodeHtmlLexically(text); throw error; } }, decodeXml(text: string): DecodedXmlDocument { if (/