{"_id":"@ariada-org/scan-report-html","_rev":"3-1e0ae4019cacd7df5ae183e1a70501d2","name":"@ariada-org/scan-report-html","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@ariada-org/scan-report-html","version":"0.1.0","keywords":["accessibility","a11y","wcag","wcag22","axe-core","scan-report","html-report","eaa","eupl"],"author":{"url":"Agonist Development AB","name":"Alekszandr Bricskin","email":"git@ariada.org"},"license":"EUPL-1.2","_id":"@ariada-org/scan-report-html@0.1.0","maintainers":[{"name":"agonist","email":"ab@agonist.ai"}],"homepage":"https://ariada.org/packages/scan-report-html","bugs":{"url":"https://github.com/ariada-org/ariada/issues"},"dist":{"shasum":"031d7898d02312f6edd7c670d3fc7012f1450e3b","tarball":"https://registry.npmjs.org/@ariada-org/scan-report-html/-/scan-report-html-0.1.0.tgz","fileCount":53,"integrity":"sha512-Y8LCydTsw8Ogp+bHpxUlK7r0yCsMwOmxTxJAgXeh3NItn9KV2rGSBejvGp/dO96DklnyiB00oetKbE5lywneww==","signatures":[{"sig":"MEQCIFkor/Eb3rGyICUULC8uXVlWNwR8Bvt1LTEh+f0wWOprAiAmN4bEX45eTljaE4jzfwWtYERIapOEkegDYcNQYoburQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ariada-org%2fscan-report-html@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":111257},"main":"./dist/index.js","type":"module","_from":"file:ariada-org-scan-report-html-0.1.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src test","test":"vitest run","build":"tsc -p tsconfig.json","clean":"rimraf dist coverage reports .stryker-tmp","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","test:mutation":"stryker run","test:mutation:report":"open reports/mutation/mutation.html"},"_npmUser":{"name":"agonist","email":"ab@agonist.ai"},"_resolved":"/tmp/102b5777ca3263631ee3b23e9c7af6c5/ariada-org-scan-report-html-0.1.0.tgz","_integrity":"sha512-Y8LCydTsw8Ogp+bHpxUlK7r0yCsMwOmxTxJAgXeh3NItn9KV2rGSBejvGp/dO96DklnyiB00oetKbE5lywneww==","repository":{"url":"git+https://github.com/ariada-org/ariada.git","type":"git","directory":"packages/scan-report-html"},"_npmVersion":"10.9.8","description":"Renders machine-readable accessibility scan artefacts into a single self-contained human-readable HTML report. Closes the gap between scan-results.json and what an auditor / developer / compliance officer can actually read.","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"@ariada-org/core-engine":"0.1.0"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.1","vitest":"^4.1.0","typescript":"^5.7.2","@types/node":"^22.10.2","@stryker-mutator/core":"^9.6.1","@stryker-mutator/vitest-runner":"^9.6.1","@stryker-mutator/typescript-checker":"^9.6.1"},"_npmOperationalInternal":{"tmp":"tmp/scan-report-html_0.1.0_1781536555156_0.32429915952889576","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ariada-org/scan-report-html","version":"0.1.1","keywords":["accessibility","a11y","wcag","wcag22","axe-core","scan-report","html-report","eaa","eupl"],"author":{"url":"Agonist Development AB","name":"Alekszandr Bricskin","email":"git@ariada.org"},"license":"EUPL-1.2","_id":"@ariada-org/scan-report-html@0.1.1","maintainers":[{"name":"agonist","email":"ab@agonist.ai"}],"homepage":"https://ariada.org/packages/scan-report-html","bugs":{"url":"https://github.com/ariada-org/ariada/issues"},"dist":{"shasum":"f088bcd7b520d5d345726de78ca0adb37f0bf2d5","tarball":"https://registry.npmjs.org/@ariada-org/scan-report-html/-/scan-report-html-0.1.1.tgz","fileCount":57,"integrity":"sha512-XJh+xwMDRycxT50JNHsO8iogQbUr6KGfcEbVUYdVzG1QHC3Xp9lFQfkRloGMtc5W+zrTG96FcbHt/TSM9z04vw==","signatures":[{"sig":"MEYCIQCwr7fpZOY8xJKL2b9N7B5ohMU18hp1v9HSeqilN+3QbQIhANRtA+2aRZfIVR6CfB5ivw53oN7NF0f1g2HGqTjNgva8","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":140133},"main":"./dist/index.js","type":"module","_from":"file:ariada-org-scan-report-html-0.1.1.tgz","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src test","test":"vitest run","build":"tsc -p tsconfig.json","clean":"rimraf dist coverage reports .stryker-tmp","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest","test:mutation":"stryker run","test:mutation:report":"open reports/mutation/mutation.html"},"_npmUser":{"name":"agonist","email":"ab@agonist.ai"},"_resolved":"/private/var/folders/2c/_42xj0l179z8yc7wmp5k91s00000gn/T/360a78ffeb483c4ae579b544d5df7599/ariada-org-scan-report-html-0.1.1.tgz","_integrity":"sha512-XJh+xwMDRycxT50JNHsO8iogQbUr6KGfcEbVUYdVzG1QHC3Xp9lFQfkRloGMtc5W+zrTG96FcbHt/TSM9z04vw==","repository":{"url":"git+https://github.com/ariada-org/ariada.git","type":"git","directory":"packages/scan-report-html"},"_npmVersion":"11.17.0","description":"Renders machine-readable accessibility scan artefacts into a single self-contained human-readable HTML report. Closes the gap between scan-results.json and what an auditor / developer / compliance officer can actually read.","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"@ariada-org/core-engine":"0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.1","vitest":"^4.1.0","typescript":"^5.7.2","@types/node":"^22.10.2","@stryker-mutator/core":"^9.6.1","@stryker-mutator/vitest-runner":"^9.6.1","@stryker-mutator/typescript-checker":"^9.6.1"},"_npmOperationalInternal":{"tmp":"tmp/scan-report-html_0.1.1_1784942578240_0.9694664407272611","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@ariada-org/scan-report-html","version":"0.2.0","description":"Renders machine-readable accessibility scan artefacts into a single self-contained human-readable HTML report. Closes the gap between scan-results.json and what an auditor / developer / compliance officer can actually read.","license":"EUPL-1.2","type":"module","sideEffects":false,"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"dependencies":{"@ariada-org/overlay":"0.2.0","@ariada-org/core-engine":"0.3.0"},"devDependencies":{"@stryker-mutator/core":"^9.6.1","@stryker-mutator/typescript-checker":"^9.6.1","@stryker-mutator/vitest-runner":"^9.6.1","@types/node":"^22.10.2","rimraf":"^6.0.1","typescript":"^5.7.2","vitest":"^4.1.0"},"engines":{"node":">=22"},"keywords":["accessibility","a11y","wcag","wcag22","axe-core","scan-report","html-report","eaa","eupl"],"homepage":"https://ariada.org/packages/scan-report-html","repository":{"type":"git","url":"git+https://github.com/ariada-org/ariada.git","directory":"packages/scan-report-html"},"bugs":{"url":"https://github.com/ariada-org/ariada/issues"},"author":{"name":"Alekszandr Bricskin","email":"git@ariada.org","url":"Agonist Development AB"},"publishConfig":{"access":"public"},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","lint":"eslint src test","test":"vitest run","test:watch":"vitest","test:mutation":"stryker run","test:mutation:report":"open reports/mutation/mutation.html","clean":"rimraf dist coverage reports .stryker-tmp"},"_id":"@ariada-org/scan-report-html@0.2.0","_integrity":"sha512-2GnQXq2Nm2qyVNikjvdXzXd6lWlUU4ULqXKqV5dNKzI6ATdwgm0IPbnCqyJ5QIsxNymoRRIDP5gZs4wtcYNmHQ==","_resolved":"/private/var/folders/2c/_42xj0l179z8yc7wmp5k91s00000gn/T/d93e164906900fff798dc100ba895254/ariada-org-scan-report-html-0.2.0.tgz","_from":"file:ariada-org-scan-report-html-0.2.0.tgz","_nodeVersion":"26.5.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-2GnQXq2Nm2qyVNikjvdXzXd6lWlUU4ULqXKqV5dNKzI6ATdwgm0IPbnCqyJ5QIsxNymoRRIDP5gZs4wtcYNmHQ==","shasum":"a70554eda2fe5de058c841497f07b1cea2aabad5","tarball":"https://registry.npmjs.org/@ariada-org/scan-report-html/-/scan-report-html-0.2.0.tgz","fileCount":65,"unpackedSize":191696,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCW4/5G8vtRE0kp97T2/sEn+zzrajcRJJ8wTs/Xo0MfuAIhAP+W42d1hXpE2o2UK71FtW//CKCIvzMbQO5DGSWasSNN"}]},"_npmUser":{"name":"agonist","email":"ab@agonist.ai"},"directories":{},"maintainers":[{"name":"agonist","email":"ab@agonist.ai"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/scan-report-html_0.2.0_1787175996150_0.0677594780705777"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-15T15:15:54.921Z","modified":"2026-08-19T21:46:36.425Z","0.1.0":"2026-06-15T15:15:55.361Z","0.1.1":"2026-07-25T01:22:58.380Z","0.2.0":"2026-08-19T21:46:36.286Z"},"bugs":{"url":"https://github.com/ariada-org/ariada/issues"},"author":{"name":"Alekszandr Bricskin","email":"git@ariada.org","url":"Agonist Development AB"},"license":"EUPL-1.2","homepage":"https://ariada.org/packages/scan-report-html","keywords":["accessibility","a11y","wcag","wcag22","axe-core","scan-report","html-report","eaa","eupl"],"repository":{"type":"git","url":"git+https://github.com/ariada-org/ariada.git","directory":"packages/scan-report-html"},"description":"Renders machine-readable accessibility scan artefacts into a single self-contained human-readable HTML report. Closes the gap between scan-results.json and what an auditor / developer / compliance officer can actually read.","maintainers":[{"name":"agonist","email":"ab@agonist.ai"}],"readme":"# @ariada-org/scan-report-html\n\nRender machine-readable accessibility scan artefacts into a single self-contained human-readable HTML report.\n\nOpen source under [EUPL-1.2](./LICENSE).\n\n## What this package does\n\nConsumes the canonical scan-artefact tuple (`scan-results.json` + optional `screenshot.png`) and produces one `scan-report.html` file that a developer, accessibility auditor, compliance officer, or stakeholder can open directly in a browser — no JSON tooling, no static-site generator, no internet connection required.\n\nThe package is the engineering answer to the «JSON dump is not a report» gap: every output is a single HTML5 file with inline CSS, embedded screenshots (when supplied), severity-coded violation cards, prioritised action items, and a compliance-score gauge.\n\nThe renderer is a pure function. Same input bytes, same output bytes (deterministic — see spec). No telemetry, no remote fetches, no third-party fonts, no CDN references.\n\n## Install\n\n```bash\nnpm install @ariada-org/scan-report-html\n```\n\n## Quick start\n\n```ts\nimport { renderScanReport } from '@ariada-org/scan-report-html';\nimport type { ScanReportInput } from '@ariada-org/scan-report-html';\n\nconst input: ScanReportInput = {\n meta: {\n url: 'https://example.org/checkout',\n timestamp: '2026-05-19T16:05:52.101Z',\n scannerVersion: '0.1.0',\n axeVersion: '4.10.2',\n userAgent: 'Chromium/124',\n viewport: '1280x720',\n },\n findings: [\n {\n id: 'image-alt',\n impact: 'critical',\n description: 'Ensure <img> elements have alternate text',\n help: 'Images must have alt attributes',\n helpUrl: 'https://dequeuniversity.com/rules/axe/4.10/image-alt',\n wcag: ['1.1.1'],\n nodes: [\n {\n selector: 'main > section.hero > img',\n html: '<img src=\"/hero.jpg\" width=\"1200\" height=\"400\">',\n },\n ],\n },\n ],\n};\n\n// Pure call — returns the HTML string.\nconst html: string = renderScanReport(input);\n\n// Or write to disk — returns { path, bytes }.\nconst { path } = await renderScanReport(input, {\n outputDir: 'tests/acceptance/results/example/',\n});\n```\n\n## What the report contains\n\nEach rendered file includes, in order:\n\n1. **Header** — URL, scan timestamp, scanner version.\n2. **Summary dashboard** — compliance score (heuristic) gauge + severity breakdown bars (critical / serious / moderate / minor).\n3. **Empty-state notice** — shown when no findings.\n4. **Findings** — one card per `ScanFinding`, sorted critical → serious → moderate → minor:\n - Severity badge (text + icon — colour is never sole information conveyor; WCAG 1.4.1).\n - Rule ID and primary WCAG 2.2 Success Criterion link (`target=\"_blank\" rel=\"noopener noreferrer\"`).\n - Plain-English description + one-line help.\n - Affected element selector and HTML snippet (escaped, truncated).\n - Help-URL link out to authoritative rule documentation.\n - Element screenshot crop hookpoint (Phase-3 wire-up — empty placeholder in v0.1).\n5. **Action items** — top-10 prioritised by `severity_weight × node_count`, each anchor-linked to the matching card.\n6. **Methodology footer** — scanner version + axe-core version + WCAG version + EN 301 549 version + browser + viewport.\n7. **Identity footer** — bit-exact maintainer attribution + EUPL-1.2 reference.\n\n## Design rules\n\nThe package follows strict output-discipline rules :\n\n- No external CDN reference.\n- No `<script src=\"…\">` — no inline JS either (v0.1).\n- No `<link rel=\"stylesheet\">` — all CSS inlined in one `<style>` block.\n- No third-party fonts — system font stack only.\n- No telemetry, no analytics, no tracking pixel.\n\nThese invariants are enforced by automated tests (`test/unit/render.test.ts` + `test/unit/self-audit.test.ts`).\n\n## Accessibility\n\nThe renderer eats its own dog food. The produced report is built against WCAG 2.2 Level AA:\n\n- Semantic landmarks (`<header>`, `<main>`, `<footer>`).\n- Single `<h1>`, ordered heading hierarchy.\n- Skip-link as the first focusable element.\n- All interactive controls keyboard-reachable with a visible focus ring (3px outline, ≥3:1 contrast).\n- Severity palette pre-verified at ≥4.5:1 contrast against background.\n- `<details>`/`<summary>` for collapsible sections (no ARIA-disclosure trap).\n- No `<iframe>`, no autoplaying media.\n- `<html lang=\"…\">` declared per WCAG 3.1.1.\n\nA full axe-playwright pass against the rendered output lands as the Phase-5 E2E gate (see the per spec). The shipped unit suite enforces the structural invariants that static-HTML analysis can confirm without spawning a browser.\n\n## API\n\n### `renderScanReport(input)` — pure\n\nReturns the HTML string. No I/O.\n\n### `renderScanReport(input, { outputDir })` — disk-write\n\nAsync. Writes `scan-report.html` (or `options.filename`) under `outputDir`, creating the directory if it does not exist. Resolves to `{ path, bytes }`.\n\n### `RenderOptions`\n\n| Field | Type | Default | Meaning |\n|---|---|---|---|\n| `includePenalty` | `boolean` | `false` | Show penalty-exposure block. Off by default — legal hygiene. |\n| `locale` | `'en'` | `'en'` | Static-prose locale. Swedish + German planned for v0.2. |\n| `releaseBuild` | `boolean` | `true` | Strip the cert-block hookpoint HTML comment from output. |\n\n### Re-exports\n\n- Score helpers — `computeComplianceScore`, `bandFromScore`, `topActionItems`, `severityBreakdown`, `ScoreBand`.\n- WCAG SC slug table — `WCAG_22_SC_SLUG`, `wcagSCUrl(sc)`.\n- Escape utilities — `escapeHtml`, `escapeAndTruncate`, `escapeUrl`.\n\n## Engineering reference\n\nThis v0.1 scaffold lands the foundational sections, deterministic rendering, structural self-audit, and CLI-ready API surface. Subsequent commits will land:\n\n- Sharp-based element-crop pipeline (Phase 3).\n- WCAG 2.2 matrix section when VPAT input is provided (Phase 4).\n- Localisation matrix (Swedish + German Phase 5).\n- Rule-fix remediation lookup table (spec, Phase 2-3).\n- Cross-browser E2E (Chromium / Firefox / WebKit) + axe-playwright self-scan (spec, Phase 6).\n- CLI wrapper + wiring into `eaa-pipeline` GitHub Action (spec, Phase 7).\n\n## Maintainer\n\nMaintained by Alekszandr Bricskin (Agonist Development AB, Sweden, org.nr 559452-5726).\n\nLicense: [EUPL-1.2](./LICENSE).\n","readmeFilename":"README.md"}