@a11yst/reporters 1.0.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.
Files changed (67) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +78 -0
  3. package/dist/assets.d.ts +3 -0
  4. package/dist/assets.d.ts.map +1 -0
  5. package/dist/assets.js +271 -0
  6. package/dist/assets.js.map +1 -0
  7. package/dist/baseline-report.d.ts +25 -0
  8. package/dist/baseline-report.d.ts.map +1 -0
  9. package/dist/baseline-report.js +426 -0
  10. package/dist/baseline-report.js.map +1 -0
  11. package/dist/finding-groups.d.ts +14 -0
  12. package/dist/finding-groups.d.ts.map +1 -0
  13. package/dist/finding-groups.js +77 -0
  14. package/dist/finding-groups.js.map +1 -0
  15. package/dist/finding-source-report.d.ts +21 -0
  16. package/dist/finding-source-report.d.ts.map +1 -0
  17. package/dist/finding-source-report.js +134 -0
  18. package/dist/finding-source-report.js.map +1 -0
  19. package/dist/github/escape.d.ts +13 -0
  20. package/dist/github/escape.d.ts.map +1 -0
  21. package/dist/github/escape.js +37 -0
  22. package/dist/github/escape.js.map +1 -0
  23. package/dist/github/generate.d.ts +3 -0
  24. package/dist/github/generate.d.ts.map +1 -0
  25. package/dist/github/generate.js +140 -0
  26. package/dist/github/generate.js.map +1 -0
  27. package/dist/github/source-location.d.ts +4 -0
  28. package/dist/github/source-location.d.ts.map +1 -0
  29. package/dist/github/source-location.js +69 -0
  30. package/dist/github/source-location.js.map +1 -0
  31. package/dist/github/types.d.ts +42 -0
  32. package/dist/github/types.d.ts.map +1 -0
  33. package/dist/github/types.js +18 -0
  34. package/dist/github/types.js.map +1 -0
  35. package/dist/html.d.ts +8 -0
  36. package/dist/html.d.ts.map +1 -0
  37. package/dist/html.js +562 -0
  38. package/dist/html.js.map +1 -0
  39. package/dist/index.d.ts +24 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +33 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/markdown/escape.d.ts +5 -0
  44. package/dist/markdown/escape.d.ts.map +1 -0
  45. package/dist/markdown/escape.js +27 -0
  46. package/dist/markdown/escape.js.map +1 -0
  47. package/dist/markdown/generate.d.ts +3 -0
  48. package/dist/markdown/generate.d.ts.map +1 -0
  49. package/dist/markdown/generate.js +498 -0
  50. package/dist/markdown/generate.js.map +1 -0
  51. package/dist/markdown/links.d.ts +4 -0
  52. package/dist/markdown/links.d.ts.map +1 -0
  53. package/dist/markdown/links.js +30 -0
  54. package/dist/markdown/links.js.map +1 -0
  55. package/dist/markdown/types.d.ts +71 -0
  56. package/dist/markdown/types.d.ts.map +1 -0
  57. package/dist/markdown/types.js +2 -0
  58. package/dist/markdown/types.js.map +1 -0
  59. package/dist/profile-evidence.d.ts +21 -0
  60. package/dist/profile-evidence.d.ts.map +1 -0
  61. package/dist/profile-evidence.js +211 -0
  62. package/dist/profile-evidence.js.map +1 -0
  63. package/dist/validation.d.ts +10 -0
  64. package/dist/validation.d.ts.map +1 -0
  65. package/dist/validation.js +96 -0
  66. package/dist/validation.js.map +1 -0
  67. package/package.json +43 -0
package/dist/assets.js ADDED
@@ -0,0 +1,271 @@
1
+ export function renderReportStyles() {
2
+ return `:root {
3
+ color-scheme: light;
4
+ --background: #f7f8fa;
5
+ --surface: #ffffff;
6
+ --text: #172033;
7
+ --muted: #4c5870;
8
+ --border: #c7cedb;
9
+ --accent: #1649a8;
10
+ --accent-hover: #0d347d;
11
+ --critical: #8f1127;
12
+ --high: #a33d00;
13
+ --medium: #6b5600;
14
+ --minor: #315d17;
15
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
16
+ }
17
+
18
+ * { box-sizing: border-box; }
19
+ html { background: var(--background); color: var(--text); line-height: 1.5; }
20
+ body { margin: 0; }
21
+ a { color: var(--accent); }
22
+ a:hover { color: var(--accent-hover); }
23
+ a:focus-visible, button:focus-visible, select:focus-visible {
24
+ outline: 3px solid #ed9d00;
25
+ outline-offset: 3px;
26
+ }
27
+ .skip-link {
28
+ background: var(--text);
29
+ color: #fff;
30
+ left: 1rem;
31
+ padding: .75rem 1rem;
32
+ position: fixed;
33
+ top: -5rem;
34
+ z-index: 10;
35
+ }
36
+ .skip-link:focus { top: 1rem; }
37
+ .site-header, main, footer { margin-inline: auto; max-width: 78rem; padding: 1.25rem; }
38
+ .site-header { background: #12213d; color: #fff; max-width: none; }
39
+ .site-header__inner { margin-inline: auto; max-width: 75.5rem; }
40
+ .site-header p { color: #e0e6f1; }
41
+ nav ul { display: flex; flex-wrap: wrap; gap: 1rem; list-style: none; padding: 0; }
42
+ nav a { color: #fff; font-weight: 700; }
43
+ section { margin-block: 2.5rem; }
44
+ .summary-grid, .coverage-grid, .run-grid {
45
+ display: grid;
46
+ gap: 1rem;
47
+ grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
48
+ }
49
+ .summary-card, .coverage-card, .run, .finding, .filters, .empty-state {
50
+ background: var(--surface);
51
+ border: 1px solid var(--border);
52
+ border-radius: .4rem;
53
+ padding: 1rem;
54
+ }
55
+ .summary-card strong { display: block; font-size: 1.8rem; }
56
+ .summary-card--critical { border-top: .4rem solid var(--critical); }
57
+ .summary-card--high { border-top: .4rem solid var(--high); }
58
+ .summary-card--medium { border-top: .4rem solid var(--medium); }
59
+ .summary-card--minor { border-top: .4rem solid var(--minor); }
60
+ .summary-card--new { border-top: .4rem solid #1649a8; }
61
+ .summary-card--known { border-top: .4rem solid #4c5870; }
62
+ .summary-card--regressed { border-top: .4rem solid var(--high); }
63
+ .summary-card--resolved { border-top: .4rem solid #315d17; }
64
+ .summary-card--not-compared { border-top: .4rem solid #66738a; }
65
+ .summary-card--expired { border-top: .4rem solid var(--medium); }
66
+ .baseline-summary-grid { margin-block: 1rem; }
67
+ .baseline-metadata {
68
+ border-top: 1px solid var(--border);
69
+ margin-top: 1rem;
70
+ padding-top: 1rem;
71
+ }
72
+ .baseline-metadata h4 { margin-top: 0; }
73
+ .lifecycle-badge {
74
+ font-weight: 800;
75
+ margin: 0 0 .75rem;
76
+ text-transform: capitalize;
77
+ }
78
+ .lifecycle-badge__label { font-weight: 700; }
79
+ .lifecycle-badge--new::before { content: "[New] "; font-weight: 800; }
80
+ .lifecycle-badge--known::before { content: "[Known] "; font-weight: 800; }
81
+ .lifecycle-badge--regressed::before { content: "[Regressed] "; font-weight: 800; }
82
+ .lifecycle-badge--resolved::before { content: "[Resolved] "; font-weight: 800; }
83
+ .lifecycle-badge--not-compared::before { content: "[Not compared] "; font-weight: 800; }
84
+ .baseline-entry { border-left-style: dashed; }
85
+ .baseline-coverage { margin-top: 1rem; }
86
+ .coverage-details {
87
+ display: grid;
88
+ gap: 1rem;
89
+ grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
90
+ }
91
+ .coverage-list {
92
+ margin: 0;
93
+ padding-left: 1.25rem;
94
+ }
95
+ .baseline-dispositions { margin-top: 1rem; }
96
+ .filters { margin-block: 1rem; }
97
+ .filter-grid {
98
+ display: grid;
99
+ gap: .8rem;
100
+ grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
101
+ }
102
+ .filter-field label { display: block; font-weight: 700; margin-bottom: .25rem; }
103
+ select, button {
104
+ background: #fff;
105
+ border: 2px solid #66738a;
106
+ border-radius: .25rem;
107
+ color: var(--text);
108
+ font: inherit;
109
+ min-height: 2.75rem;
110
+ padding: .45rem .6rem;
111
+ width: 100%;
112
+ }
113
+ button { cursor: pointer; font-weight: 700; margin-top: 1rem; width: auto; }
114
+ .result-count { font-weight: 700; }
115
+ .findings-list { display: grid; gap: 1.25rem; }
116
+ .finding { border-left-width: .5rem; }
117
+ .finding--critical { border-left-color: var(--critical); }
118
+ .finding--high { border-left-color: var(--high); }
119
+ .finding--medium { border-left-color: var(--medium); }
120
+ .finding--minor { border-left-color: var(--minor); }
121
+ .severity { font-weight: 800; text-transform: uppercase; }
122
+ .source-impact { color: var(--muted); font-size: .9rem; font-weight: 600; text-transform: none; }
123
+ .metadata { display: grid; gap: .4rem 1rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
124
+ .metadata dt { font-weight: 700; }
125
+ .metadata dd { margin: 0; overflow-wrap: anywhere; }
126
+ pre {
127
+ background: #eef1f6;
128
+ border: 1px solid var(--border);
129
+ overflow: auto;
130
+ padding: .75rem;
131
+ white-space: pre-wrap;
132
+ }
133
+ .evidence {
134
+ border: 1px solid var(--border);
135
+ display: block;
136
+ height: auto;
137
+ margin-top: 1rem;
138
+ max-width: 100%;
139
+ }
140
+ .diagnostics { padding-left: 1.25rem; }
141
+ .status { font-weight: 800; text-transform: capitalize; }
142
+ .disclaimers { border-left: .3rem solid var(--accent); padding-left: 1rem; }
143
+ .muted { color: var(--muted); }
144
+ .profile-evidence-list { display: grid; gap: 1.5rem; }
145
+ .profile-evidence {
146
+ background: var(--surface);
147
+ border: 1px solid var(--border);
148
+ border-left-width: .5rem;
149
+ border-radius: .4rem;
150
+ padding: 1rem;
151
+ }
152
+ .profile-evidence--keyboard { border-left-color: #1649a8; }
153
+ .profile-evidence--large-text { border-left-color: #6b5600; }
154
+ .metadata--inline {
155
+ display: flex;
156
+ flex-wrap: wrap;
157
+ gap: .75rem 1.5rem;
158
+ margin-block: .75rem 1rem;
159
+ }
160
+ .metadata--inline div { min-width: 10rem; }
161
+ .comparison-grid {
162
+ display: grid;
163
+ gap: 1rem;
164
+ grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
165
+ margin-top: 1rem;
166
+ }
167
+ .comparison-shot {
168
+ border: 1px solid var(--border);
169
+ margin: 0;
170
+ padding: .75rem;
171
+ }
172
+ .comparison-shot figcaption {
173
+ font-weight: 700;
174
+ margin-bottom: .5rem;
175
+ }
176
+ .comparison-shot--missing {
177
+ background: #eef1f6;
178
+ }
179
+ .coverage-grid--profiles { margin-bottom: 1rem; }
180
+ .coverage-card--profile h4 {
181
+ font-size: 1rem;
182
+ margin: .75rem 0 .25rem;
183
+ }
184
+ .coverage-stats { margin-top: 1rem; }
185
+ .focus-sequence-table code {
186
+ font-size: .85em;
187
+ word-break: break-word;
188
+ }
189
+ .visually-hidden {
190
+ border: 0;
191
+ clip: rect(0 0 0 0);
192
+ height: 1px;
193
+ margin: -1px;
194
+ overflow: hidden;
195
+ padding: 0;
196
+ position: absolute;
197
+ white-space: nowrap;
198
+ width: 1px;
199
+ }
200
+ .table-wrap { overflow-x: auto; }
201
+ table {
202
+ border-collapse: collapse;
203
+ min-width: 100%;
204
+ width: max-content;
205
+ }
206
+ th, td {
207
+ border: 1px solid var(--border);
208
+ padding: .6rem .75rem;
209
+ text-align: left;
210
+ vertical-align: top;
211
+ }
212
+ th { background: #eef1f6; }
213
+ [hidden] { display: none !important; }
214
+ footer { border-top: 1px solid var(--border); color: var(--muted); }
215
+
216
+ @media (max-width: 40rem) {
217
+ .site-header, main, footer { padding: 1rem; }
218
+ h1 { font-size: 1.8rem; }
219
+ .metadata { grid-template-columns: 1fr; }
220
+ }
221
+
222
+ @media (prefers-reduced-motion: reduce) {
223
+ *, *::before, *::after {
224
+ scroll-behavior: auto !important;
225
+ transition-duration: .01ms !important;
226
+ animation-duration: .01ms !important;
227
+ animation-iteration-count: 1 !important;
228
+ }
229
+ }
230
+ `;
231
+ }
232
+ export function renderReportScript() {
233
+ return `"use strict";
234
+
235
+ const form = document.querySelector("[data-report-filters]");
236
+ const articles = Array.from(document.querySelectorAll("[data-finding]"));
237
+ const count = document.querySelector("[data-result-count]");
238
+
239
+ if (form instanceof HTMLFormElement && count instanceof HTMLElement) {
240
+ const controls = Array.from(form.querySelectorAll("select"));
241
+
242
+ const update = () => {
243
+ const visibleFingerprints = new Set();
244
+ let visibleCards = 0;
245
+ for (const article of articles) {
246
+ if (!(article instanceof HTMLElement)) continue;
247
+ const matches = controls.every((control) => {
248
+ if (!(control instanceof HTMLSelectElement) || control.value === "") return true;
249
+ return article.dataset[control.name] === control.value;
250
+ });
251
+ article.hidden = !matches;
252
+ if (matches) {
253
+ visibleCards += 1;
254
+ if (article.dataset.fingerprint) {
255
+ visibleFingerprints.add(article.dataset.fingerprint);
256
+ }
257
+ }
258
+ }
259
+ const visible = visibleFingerprints.size > 0 ? visibleFingerprints.size : visibleCards;
260
+ count.textContent = visible + (visible === 1 ? " finding shown" : " findings shown");
261
+ };
262
+
263
+ form.addEventListener("change", update);
264
+ form.addEventListener("reset", () => {
265
+ window.setTimeout(update, 0);
266
+ });
267
+ update();
268
+ }
269
+ `;
270
+ }
271
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB;IAChC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoOR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCR,CAAC;AACF,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { AuditExecutionResult, BaselineSummary, ComparisonCoverage, Finding, FindingLifecycleStatus, NotComparedFinding, ResolvedFinding } from "@a11yst/types";
2
+ import { CURRENT_BASELINE_SCHEMA_VERSION, CURRENT_FINGERPRINT_VERSION } from "@a11yst/types";
3
+ export declare function escapeHtml(value: unknown): string;
4
+ export declare function buildComparisonCoverage(result: AuditExecutionResult): ComparisonCoverage;
5
+ export interface BaselineReportContext {
6
+ baselineUsed: boolean;
7
+ baselineSummary?: BaselineSummary;
8
+ resolvedFindings: ResolvedFinding[];
9
+ notComparedFindings: NotComparedFinding[];
10
+ coverage?: ComparisonCoverage;
11
+ schemaVersion: typeof CURRENT_BASELINE_SCHEMA_VERSION;
12
+ fingerprintVersion: typeof CURRENT_FINGERPRINT_VERSION;
13
+ }
14
+ export declare function buildBaselineReportContext(auditResult: AuditExecutionResult): BaselineReportContext;
15
+ export declare function findingLifecycle(finding: Finding): FindingLifecycleStatus;
16
+ export declare function findingRoute(finding: Finding): string;
17
+ export declare function resolvedLocation(resolved: ResolvedFinding): string;
18
+ export declare function notComparedLocation(notCompared: NotComparedFinding): string;
19
+ export declare function renderBaselineMetadata(finding: Finding): string;
20
+ export declare function renderBaselineFindingDataAttributes(finding: Finding): string;
21
+ export declare function renderBaselineSummarySection(context: BaselineReportContext): string;
22
+ export declare function renderBaselineLifecycleSections(context: BaselineReportContext, findings: Finding[], renderFinding: (finding: Finding, index: number) => string): string;
23
+ export declare function renderBaselineNavLinks(context: BaselineReportContext): string;
24
+ export declare function renderBaselineFilters(findings: Finding[], context: BaselineReportContext): string;
25
+ //# sourceMappingURL=baseline-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline-report.d.ts","sourceRoot":"","sources":["../src/baseline-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,OAAO,EAEP,sBAAsB,EACtB,kBAAkB,EAElB,eAAe,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,+BAA+B,EAC/B,2BAA2B,EAC5B,MAAM,eAAe,CAAC;AAEvB,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOjD;AAgED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,oBAAoB,GAAG,kBAAkB,CA2DxF;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,aAAa,EAAE,OAAO,+BAA+B,CAAC;IACtD,kBAAkB,EAAE,OAAO,2BAA2B,CAAC;CACxD;AAED,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,oBAAoB,GAChC,qBAAqB,CAWvB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,sBAAsB,CAEzE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAErD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAIlE;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,GAAG,MAAM,CAI3E;AA4CD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAgC/D;AAED,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAoB5E;AAoJD,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAyBnF;AAkBD,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,qBAAqB,EAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GACzD,MAAM,CA6DR;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAY7E;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,qBAAqB,GAC7B,MAAM,CA4BR"}