{"_id":"@advance-labs/html-parser","_rev":"3-8615e940085cc442579d329da7a3b663","name":"@advance-labs/html-parser","dist-tags":{"latest":"0.2.2"},"versions":{"0.2.0":{"name":"@advance-labs/html-parser","version":"0.2.0","license":"MIT","_id":"@advance-labs/html-parser@0.2.0","maintainers":[{"name":"zordhalo","email":"lucas@advancelabs.dev"}],"homepage":"https://github.com/Advance-Labs/aeo-toolkit#readme","bugs":{"url":"https://github.com/Advance-Labs/aeo-toolkit/issues"},"dist":{"shasum":"ba4a28bb2409bb1c4403bcb578ac28cdfb2cdefa","tarball":"https://registry.npmjs.org/@advance-labs/html-parser/-/html-parser-0.2.0.tgz","fileCount":6,"integrity":"sha512-C4Xhm7Qlm4REf5/lJO1B0FdKEeapSzN5TOSdlM2OCR8k/si3YXCQJxlTSuvMpOuc4EmESt+4sEmk25UDLKB9Kg==","signatures":[{"sig":"MEQCICnHgPShgIRemFEpBhCsrJUa65C3iwmyAQSqZMFBuKTmAiAD/7n93k6e7F3SpPL5mHn0CF/CNiCCKFDKUu4fl+ZYKg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":59686},"main":"./dist/index.js","type":"module","_from":"file:advance-labs-html-parser-0.2.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"tsup --watch","lint":"eslint src","test":"vitest run","build":"tsup","clean":"rimraf dist .turbo","typecheck":"tsc --noEmit"},"_npmUser":{"name":"zordhalo","email":"lucas@advancelabs.dev"},"_resolved":"/private/var/folders/lc/qg6736_d3pxb5ds7q4x5gtf80000gn/T/dfba30a75bf83266e01f6d5f10096389/advance-labs-html-parser-0.2.0.tgz","_integrity":"sha512-C4Xhm7Qlm4REf5/lJO1B0FdKEeapSzN5TOSdlM2OCR8k/si3YXCQJxlTSuvMpOuc4EmESt+4sEmk25UDLKB9Kg==","repository":{"url":"git+https://github.com/Advance-Labs/aeo-toolkit.git","type":"git","directory":"packages/html-parser"},"_npmVersion":"11.18.0","description":"Pure HTML extraction for the AEO Toolkit — meta/OG/Twitter, headings, images, links, content signals, and raw structured-data blocks. No network.","directories":{},"_nodeVersion":"25.8.1","dependencies":{"cheerio":"^1.0.0","@advance-labs/types":"0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","rimraf":"^6.0.1","vitest":"^3.2.6","typescript":"^5.7.2","@advance-labs/config":"0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/html-parser_0.2.0_1788059627496_0.177283866204907","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@advance-labs/html-parser","version":"0.2.1","keywords":["html","parser","meta-tags","open-graph","twitter-cards","json-ld","structured-data","seo"],"license":"Apache-2.0","_id":"@advance-labs/html-parser@0.2.1","maintainers":[{"name":"zordhalo","email":"lucas@advancelabs.dev"}],"homepage":"https://github.com/Advance-Labs/aeo-toolkit#readme","bugs":{"url":"https://github.com/Advance-Labs/aeo-toolkit/issues"},"dist":{"shasum":"dab12dbd0d7c482f3f9d5f9af6991f003eccc9df","tarball":"https://registry.npmjs.org/@advance-labs/html-parser/-/html-parser-0.2.1.tgz","fileCount":6,"integrity":"sha512-8TkUrBIAD+hpYU5zk8JUMcv1guvSmXdBhMpjLzlrpkFdxlfCkWdgIUzqRZ17as7exj6jtjlr0D66whxlVYXtAA==","signatures":[{"sig":"MEQCIEVRV68XwP7OocoKVcGOKYuFd+DDPQA+hXIkEyOFVw1GAiBRdtvXAw0dI1WYhQyLImxtUDVL4FpHd+/ssnSO7YTrQA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":71614},"main":"./dist/index.js","type":"module","_from":"file:advance-labs-html-parser-0.2.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"tsup --watch","lint":"eslint src","test":"vitest run","build":"tsup","clean":"rimraf dist .turbo","typecheck":"tsc --noEmit"},"_npmUser":{"name":"zordhalo","email":"lucas@advancelabs.dev"},"_resolved":"/tmp/c7ee836d3a5b529de472c19a2d5cbb9a/advance-labs-html-parser-0.2.1.tgz","_integrity":"sha512-8TkUrBIAD+hpYU5zk8JUMcv1guvSmXdBhMpjLzlrpkFdxlfCkWdgIUzqRZ17as7exj6jtjlr0D66whxlVYXtAA==","repository":{"url":"git+https://github.com/Advance-Labs/aeo-toolkit.git","type":"git","directory":"packages/html-parser"},"_npmVersion":"11.19.0","description":"Pure HTML extraction for the AEO Toolkit — meta/OG/Twitter, headings, images, links, content signals, and raw structured-data blocks. No network.","directories":{},"_nodeVersion":"24.20.0","dependencies":{"cheerio":"^1.0.0","@advance-labs/types":"0.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","rimraf":"^6.0.1","vitest":"^3.2.6","typescript":"^5.7.2","@advance-labs/config":"0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/html-parser_0.2.1_1789019425656_0.26151014349901214","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@advance-labs/html-parser","version":"0.2.2","type":"module","description":"Pure HTML extraction for the AEO Toolkit — meta/OG/Twitter, headings, images, links, content signals, and raw structured-data blocks. No network.","keywords":["html","parser","meta-tags","open-graph","twitter-cards","json-ld","structured-data","seo"],"license":"Apache-2.0","author":{"name":"Lucas Krawczak","email":"lucas@advancelabs.dev","url":"https://advancelabs.dev/lucas"},"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"dependencies":{"cheerio":"^1.0.0","@advance-labs/types":"0.2.2"},"devDependencies":{"rimraf":"^6.0.1","tsup":"^8.3.5","typescript":"^5.7.2","vitest":"^3.2.6","@advance-labs/config":"0.1.0"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/Advance-Labs/aeo-toolkit.git","directory":"packages/html-parser"},"homepage":"https://docs.advancelabs.dev/aeo-toolkit","scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","lint":"eslint src","test":"vitest run","clean":"rimraf dist .turbo"},"_id":"@advance-labs/html-parser@0.2.2","bugs":{"url":"https://github.com/Advance-Labs/aeo-toolkit/issues"},"_integrity":"sha512-oW51/koGq4OQNUTpraAL66LkwxxR/9wv/ZDTiSZaXmJNjaWZ4YYlSh6vkqGLQVvZBx7K4eUEyq0zOK/AErsw3g==","_resolved":"/tmp/8057103d39dd8ef6542c788dd59029ec/advance-labs-html-parser-0.2.2.tgz","_from":"file:advance-labs-html-parser-0.2.2.tgz","_nodeVersion":"24.20.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-oW51/koGq4OQNUTpraAL66LkwxxR/9wv/ZDTiSZaXmJNjaWZ4YYlSh6vkqGLQVvZBx7K4eUEyq0zOK/AErsw3g==","shasum":"22145f9e46fba027fbc7995972de574cfe781e6e","tarball":"https://registry.npmjs.org/@advance-labs/html-parser/-/html-parser-0.2.2.tgz","fileCount":6,"unpackedSize":71690,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFphHhlMf5vysUZrei3PdqylxbWk7vlh6uDgf/8Y1w+MAiBf843uSrRpaFJ2hZXwx9gZ5/lWUMsHq8JnMVkH/S+1Qw=="}]},"_npmUser":{"name":"zordhalo","email":"lucas@advancelabs.dev"},"directories":{},"maintainers":[{"name":"zordhalo","email":"lucas@advancelabs.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/html-parser_0.2.2_1789020711118_0.8295661655735711"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-30T03:13:47.348Z","modified":"2026-09-10T06:11:51.468Z","0.2.0":"2026-08-30T03:13:47.654Z","0.2.1":"2026-09-10T05:50:25.794Z","0.2.2":"2026-09-10T06:11:51.288Z"},"bugs":{"url":"https://github.com/Advance-Labs/aeo-toolkit/issues"},"license":"Apache-2.0","homepage":"https://docs.advancelabs.dev/aeo-toolkit","keywords":["html","parser","meta-tags","open-graph","twitter-cards","json-ld","structured-data","seo"],"repository":{"type":"git","url":"git+https://github.com/Advance-Labs/aeo-toolkit.git","directory":"packages/html-parser"},"description":"Pure HTML extraction for the AEO Toolkit — meta/OG/Twitter, headings, images, links, content signals, and raw structured-data blocks. No network.","maintainers":[{"name":"zordhalo","email":"lucas@advancelabs.dev"}],"readme":"# @advance-labs/html-parser\n\nPure, synchronous HTML extraction for the AEO Toolkit. Given an HTML string and the\nURL it came from, it produces the shared `ParsedHtml` shape: document meta, OpenGraph\nand Twitter cards, the heading tree, images with alt coverage, internal/external links,\ncontent-quality signals (word count, FAQ/HowTo, question headings, structure counts),\nand raw structured-data blocks. **No network and no filesystem access** — fetching is\nthe job of `@advance-labs/crawler`, and full schema.org validation is the job of\n`@advance-labs/schema-validator`; this package only collects the raw blocks they need.\n\n## Usage\n\n```ts\nimport { parseHtml } from '@advance-labs/html-parser';\n\nconst parsed = parseHtml(htmlString, 'https://example.com/page');\n\nconsole.log(parsed.meta.title, parsed.meta.titleLength);\nconsole.log(parsed.openGraph.complete);\nconsole.log(parsed.imageAltCoverage); // 0..1\nconsole.log(parsed.content.hasFaq, parsed.content.questionHeadingCount);\nconsole.log(parsed.rawStructuredData); // [{ format: 'json-ld', data: {...} }, ...]\n```\n\nEach extractor is also exported standalone (accepting an HTML string), so a consumer\ncan pull a single signal without parsing the whole document:\n\n```ts\nimport { extractMeta, extractHeadings } from '@advance-labs/html-parser';\n\nconst meta = extractMeta(htmlString, url);\nconst headings = extractHeadings(htmlString);\n```\n\n## Public API\n\n| Export | Signature | Purpose |\n| --- | --- | --- |\n| `parseHtml` | `(html: string, url: string) => ParsedHtml` | Full extraction into the shared shape. |\n| `extractMeta` | `(html: string, url: string) => MetaTags` | Title/description (+lengths), canonical, robots, viewport, charset, lang, theme-color. |\n| `extractOpenGraph` | `(html: string, url: string) => OpenGraph` | OG tags; `complete` requires the og title/description/image/url quartet. |\n| `extractTwitter` | `(html: string, url: string) => TwitterCard` | Twitter card tags (accepts `name=` and `property=`). |\n| `extractHeadings` | `(html: string) => HeadingNode[]` | Heading tree h1–h6 in document order. |\n| `extractImages` | `(html: string, url: string) => ImageInfo[]` | `<img>` with resolved `src`, `hasAlt`, dimensions. |\n| `extractLinks` | `(html: string, url: string) => LinkInfo[]` | Anchors classified internal/external + nofollow. |\n| `computeContentSignals` | `(html: string) => ContentSignals` | Word count, FAQ/HowTo, question headings, paragraph/list/table counts. |\n| `extractRawStructuredData` | `(html: string) => RawStructuredDataBlock[]` | JSON-LD parsed; microdata/RDFa presence markers. |\n| `isHeadingHierarchyValid` | `(headings: HeadingNode[]) => boolean` | True when headings never skip a level downward. |\n| `imageAltCoverage` | `(images: ImageInfo[]) => number` | Fraction of images with alt text, 0..1. |\n| `internalLinkCount` / `externalLinkCount` | `(links: LinkInfo[]) => number` | Link counts by classification. |\n| `isQuestionHeading` | `(text: string) => boolean` | Whether a heading reads as a question. |\n| `jsonLdHasType` / `collectJsonLdTypes` | see source | JSON-LD `@type` inspection helpers. |\n\nAll shapes are imported from `@advance-labs/types`; this package never redefines them.\n\n## Notes\n\n- `hasFaq` is set when an FAQ-flavored heading is present **or** an FAQPage/QAPage\n  JSON-LD block exists. `hasHowTo` likewise combines headings and HowTo JSON-LD.\n- An empty `alt=\"\"` counts as **not** having descriptive alt text.\n- Relative URLs in `canonical`, `og:image`, `twitter:image`, `<img src>`, and `<a href>`\n  are resolved against the supplied page URL. Fragment-only (`#...`) anchors are skipped.\n- Malformed JSON-LD is silently skipped (it surfaces as a validation finding downstream,\n  not a parser crash).\n\n## Status\n\n**Implemented.** All extractors are real (cheerio-backed) with no network/filesystem\ndependency and no stubs. Unit-tested with rich-page and sparse-page fixtures.\n","readmeFilename":"README.md","author":{"name":"Lucas Krawczak","email":"lucas@advancelabs.dev","url":"https://advancelabs.dev/lucas"}}