@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
@@ -0,0 +1,426 @@
1
+ import { CURRENT_BASELINE_SCHEMA_VERSION, CURRENT_FINGERPRINT_VERSION, } from "@a11yst/types";
2
+ export function escapeHtml(value) {
3
+ return String(value)
4
+ .replaceAll("&", "&")
5
+ .replaceAll("<", "&lt;")
6
+ .replaceAll(">", "&gt;")
7
+ .replaceAll('"', "&quot;")
8
+ .replaceAll("'", "&#39;");
9
+ }
10
+ function compareText(left, right) {
11
+ const a = left ?? "";
12
+ const b = right ?? "";
13
+ return a < b ? -1 : a > b ? 1 : 0;
14
+ }
15
+ function unique(values) {
16
+ return [...new Set(values.filter((value) => Boolean(value)))].sort(compareText);
17
+ }
18
+ function optionList(values) {
19
+ return values
20
+ .map((value) => `<option value="${escapeHtml(value)}">${escapeHtml(value)}</option>`)
21
+ .join("");
22
+ }
23
+ function filter(label, name, values, allLabel) {
24
+ if (values.length === 0)
25
+ return "";
26
+ return `<div class="filter-field">
27
+ <label for="filter-${name}">${escapeHtml(label)}</label>
28
+ <select id="filter-${name}" name="${escapeHtml(name)}">
29
+ <option value="">${escapeHtml(allLabel)}</option>
30
+ ${optionList(values)}
31
+ </select>
32
+ </div>`;
33
+ }
34
+ function detail(label, value) {
35
+ return `<div><dt>${escapeHtml(label)}</dt><dd>${escapeHtml(value || "Not available")}</dd></div>`;
36
+ }
37
+ const dispositionLabels = {
38
+ "false-positive": "False positive",
39
+ "accepted-risk": "Accepted risk",
40
+ "third-party": "Third party",
41
+ "not-applicable": "Not applicable",
42
+ "manual-review": "Manual review",
43
+ };
44
+ const regressionLabels = {
45
+ "severity-increased": "Severity increased",
46
+ "classification-expired": "Classification expired",
47
+ "returned-after-resolution": "Returned after resolution",
48
+ "confidence-increased": "Confidence increased",
49
+ "scope-expanded": "Scope expanded",
50
+ };
51
+ const lifecycleLabels = {
52
+ new: "New",
53
+ known: "Known",
54
+ regressed: "Regressed",
55
+ resolved: "Resolved",
56
+ "not-compared": "Not compared",
57
+ };
58
+ export function buildComparisonCoverage(result) {
59
+ const comparedProjects = new Set();
60
+ const comparedProfiles = new Set();
61
+ const comparedViewports = new Set();
62
+ const comparedRoutes = new Set();
63
+ const comparedFlows = new Map();
64
+ const failedRuns = [];
65
+ const skippedRuns = [];
66
+ const plannedProjects = new Set(result.plan.projects.map((project) => project.name));
67
+ for (const run of result.runs) {
68
+ if (run.status === "failed") {
69
+ failedRuns.push(run.runId);
70
+ continue;
71
+ }
72
+ if (run.status === "skipped") {
73
+ skippedRuns.push(run.runId);
74
+ continue;
75
+ }
76
+ if (run.status !== "completed") {
77
+ continue;
78
+ }
79
+ comparedProjects.add(run.projectName);
80
+ comparedProfiles.add(run.profile);
81
+ if (run.viewport?.name) {
82
+ comparedViewports.add(run.viewport.name);
83
+ }
84
+ if (run.kind === "flow-checkpoint" || run.flowId) {
85
+ if (run.flowId && run.checkpointId) {
86
+ const checkpoints = comparedFlows.get(run.flowId) ?? new Set();
87
+ checkpoints.add(run.checkpointId);
88
+ comparedFlows.set(run.flowId, checkpoints);
89
+ }
90
+ }
91
+ else if (run.route) {
92
+ comparedRoutes.add(run.route);
93
+ }
94
+ }
95
+ const excludedProjects = [...plannedProjects]
96
+ .filter((project) => !comparedProjects.has(project))
97
+ .sort();
98
+ return {
99
+ comparedProjects: [...comparedProjects].sort(),
100
+ comparedProfiles: [...comparedProfiles].sort(),
101
+ comparedViewports: [...comparedViewports].sort(),
102
+ comparedRoutes: [...comparedRoutes].sort(),
103
+ comparedFlows: [...comparedFlows.entries()]
104
+ .map(([flowId, checkpointIds]) => ({
105
+ flowId,
106
+ checkpointIds: [...checkpointIds].sort(),
107
+ }))
108
+ .sort((left, right) => left.flowId.localeCompare(right.flowId)),
109
+ excludedProjects,
110
+ failedRuns: failedRuns.sort(),
111
+ skippedRuns: skippedRuns.sort(),
112
+ };
113
+ }
114
+ export function buildBaselineReportContext(auditResult) {
115
+ const baselineUsed = auditResult.baselineSummary?.baselineUsed ?? false;
116
+ return {
117
+ baselineUsed,
118
+ baselineSummary: auditResult.baselineSummary,
119
+ resolvedFindings: auditResult.resolvedFindings ?? [],
120
+ notComparedFindings: auditResult.notComparedFindings ?? [],
121
+ coverage: baselineUsed ? buildComparisonCoverage(auditResult) : undefined,
122
+ schemaVersion: CURRENT_BASELINE_SCHEMA_VERSION,
123
+ fingerprintVersion: CURRENT_FINGERPRINT_VERSION,
124
+ };
125
+ }
126
+ export function findingLifecycle(finding) {
127
+ return finding.baseline?.status ?? "new";
128
+ }
129
+ export function findingRoute(finding) {
130
+ return finding.route ?? finding.routeName ?? finding.routeId ?? "Not available";
131
+ }
132
+ export function resolvedLocation(resolved) {
133
+ return resolved.location.kind === "flow-checkpoint"
134
+ ? `${resolved.location.flowId}/${resolved.location.checkpointId}`
135
+ : resolved.location.route;
136
+ }
137
+ export function notComparedLocation(notCompared) {
138
+ return notCompared.location.kind === "flow-checkpoint"
139
+ ? `${notCompared.location.flowId}/${notCompared.location.checkpointId}`
140
+ : notCompared.location.route;
141
+ }
142
+ function lifecycleBadge(status) {
143
+ const label = lifecycleLabels[status];
144
+ return `<p class="lifecycle-badge lifecycle-badge--${escapeHtml(status)}" aria-label="Lifecycle status: ${escapeHtml(label)}"><span class="lifecycle-badge__label">Lifecycle:</span> ${escapeHtml(label)}</p>`;
145
+ }
146
+ function dispositionText(disposition) {
147
+ return disposition ? dispositionLabels[disposition] : "";
148
+ }
149
+ function filterDatasetAttributes(values) {
150
+ return `data-finding
151
+ data-lifecycle="${escapeHtml(values.lifecycle)}"
152
+ data-severity="${escapeHtml(values.severity)}"
153
+ data-project="${escapeHtml(values.project)}"
154
+ data-route="${escapeHtml(values.route)}"
155
+ data-flow="${escapeHtml(values.flow)}"
156
+ data-checkpoint="${escapeHtml(values.checkpoint)}"
157
+ data-viewport="${escapeHtml(values.viewport)}"
158
+ data-profile="${escapeHtml(values.profile)}"
159
+ data-source="${escapeHtml(values.source)}"
160
+ data-rule="${escapeHtml(values.rule)}"
161
+ data-disposition="${escapeHtml(values.disposition)}"
162
+ data-expired="${escapeHtml(values.expired)}"
163
+ data-owner="${escapeHtml(values.owner)}"
164
+ data-ticket="${escapeHtml(values.ticket)}"`;
165
+ }
166
+ export function renderBaselineMetadata(finding) {
167
+ const baseline = finding.baseline;
168
+ if (!baseline)
169
+ return "";
170
+ const classification = baseline.classification;
171
+ const rows = [
172
+ lifecycleBadge(findingLifecycle(finding)),
173
+ baseline.previousSeverity
174
+ ? detail("Previous severity", baseline.previousSeverity)
175
+ : "",
176
+ baseline.currentSeverity ? detail("Current severity", baseline.currentSeverity) : "",
177
+ baseline.regressionReason
178
+ ? detail("Regression reason", regressionLabels[baseline.regressionReason])
179
+ : "",
180
+ classification ? detail("Disposition", dispositionText(classification.disposition)) : "",
181
+ classification ? detail("Classification reason", classification.reason) : "",
182
+ classification?.owner ? detail("Owner", classification.owner) : "",
183
+ classification?.ticket ? detail("Ticket", classification.ticket) : "",
184
+ classification?.expiresAt ? detail("Expiry", classification.expiresAt) : "",
185
+ classification?.reviewAt ? detail("Review date", classification.reviewAt) : "",
186
+ baseline.classificationExpired !== undefined
187
+ ? detail("Expired state", baseline.classificationExpired ? "Expired" : "Active")
188
+ : "",
189
+ ].join("");
190
+ return `<div class="baseline-metadata">
191
+ <h4>Baseline comparison</h4>
192
+ <dl class="metadata">${rows}</dl>
193
+ </div>`;
194
+ }
195
+ export function renderBaselineFindingDataAttributes(finding) {
196
+ const baseline = finding.baseline;
197
+ const classification = baseline?.classification;
198
+ const route = findingRoute(finding);
199
+ return filterDatasetAttributes({
200
+ lifecycle: findingLifecycle(finding),
201
+ severity: finding.severity,
202
+ project: finding.projectName,
203
+ route,
204
+ flow: finding.flowId ?? "",
205
+ checkpoint: finding.checkpointId ?? "",
206
+ viewport: finding.viewport ?? "Not available",
207
+ profile: finding.profile,
208
+ source: finding.source,
209
+ rule: finding.ruleId,
210
+ disposition: classification?.disposition ?? "",
211
+ expired: baseline?.classificationExpired ? "yes" : "no",
212
+ owner: classification?.owner ?? "",
213
+ ticket: classification?.ticket ?? "",
214
+ }).concat(` data-fingerprint="${escapeHtml(finding.fingerprint)}"`);
215
+ }
216
+ function renderResolvedFinding(resolved, index) {
217
+ const location = resolvedLocation(resolved);
218
+ const classification = resolved.classification;
219
+ const viewport = resolved.location.viewport ?? "Not available";
220
+ const profile = resolved.location.kind === "flow-checkpoint"
221
+ ? resolved.location.profile
222
+ : resolved.location.profile;
223
+ return `<article class="finding finding--${resolved.previousSeverity} baseline-entry baseline-entry--resolved" ${filterDatasetAttributes({
224
+ lifecycle: "resolved",
225
+ severity: resolved.previousSeverity,
226
+ project: resolved.projectName,
227
+ route: resolved.location.kind === "route" ? resolved.location.route : location,
228
+ flow: resolved.location.kind === "flow-checkpoint" ? resolved.location.flowId : "",
229
+ checkpoint: resolved.location.kind === "flow-checkpoint" ? resolved.location.checkpointId : "",
230
+ viewport,
231
+ profile,
232
+ source: resolved.source,
233
+ rule: resolved.ruleId,
234
+ disposition: classification?.disposition ?? "",
235
+ expired: "no",
236
+ owner: classification?.owner ?? "",
237
+ ticket: classification?.ticket ?? "",
238
+ })} data-fingerprint="${escapeHtml(resolved.fingerprint)}"
239
+ aria-labelledby="resolved-${index}-title">
240
+ <h3 id="resolved-${index}-title">${escapeHtml(resolved.snapshot?.title ?? resolved.ruleId)}</h3>
241
+ ${lifecycleBadge("resolved")}
242
+ <p class="severity">Previous severity: ${escapeHtml(resolved.previousSeverity)}</p>
243
+ <dl class="metadata">
244
+ ${detail("Rule ID", resolved.ruleId)}
245
+ ${detail("Project", resolved.projectName)}
246
+ ${detail("Location", location)}
247
+ ${detail("Viewport", viewport)}
248
+ ${detail("Profile", profile)}
249
+ ${detail("Resolved at", resolved.resolvedAt)}
250
+ ${detail("Fingerprint", resolved.fingerprint)}
251
+ ${classification ? detail("Disposition", dispositionText(classification.disposition)) : ""}
252
+ ${classification ? detail("Classification reason", classification.reason) : ""}
253
+ ${classification?.owner ? detail("Owner", classification.owner) : ""}
254
+ ${classification?.ticket ? detail("Ticket", classification.ticket) : ""}
255
+ ${classification?.expiresAt ? detail("Expiry", classification.expiresAt) : ""}
256
+ ${classification?.reviewAt ? detail("Review date", classification.reviewAt) : ""}
257
+ </dl>
258
+ </article>`;
259
+ }
260
+ function renderNotComparedFinding(notCompared, index) {
261
+ const location = notComparedLocation(notCompared);
262
+ const viewport = notCompared.location.viewport ?? "Not available";
263
+ const profile = notCompared.location.profile;
264
+ const reason = notCompared.reason === "coverage-missing"
265
+ ? "Coverage missing in this audit"
266
+ : "Not compared in this audit";
267
+ return `<article class="finding finding--${notCompared.severity} baseline-entry baseline-entry--not-compared" ${filterDatasetAttributes({
268
+ lifecycle: "not-compared",
269
+ severity: notCompared.severity,
270
+ project: notCompared.projectName,
271
+ route: notCompared.location.kind === "route" ? notCompared.location.route : location,
272
+ flow: notCompared.location.kind === "flow-checkpoint" ? notCompared.location.flowId : "",
273
+ checkpoint: notCompared.location.kind === "flow-checkpoint"
274
+ ? notCompared.location.checkpointId
275
+ : "",
276
+ viewport,
277
+ profile,
278
+ source: notCompared.source,
279
+ rule: notCompared.ruleId,
280
+ disposition: "",
281
+ expired: "no",
282
+ owner: "",
283
+ ticket: "",
284
+ })} data-fingerprint="${escapeHtml(notCompared.fingerprint)}"
285
+ aria-labelledby="not-compared-${index}-title">
286
+ <h3 id="not-compared-${index}-title">${escapeHtml(notCompared.ruleId)}</h3>
287
+ ${lifecycleBadge("not-compared")}
288
+ <p class="severity">Severity: ${escapeHtml(notCompared.severity)}</p>
289
+ <p>${escapeHtml(reason)}</p>
290
+ <dl class="metadata">
291
+ ${detail("Rule ID", notCompared.ruleId)}
292
+ ${detail("Project", notCompared.projectName)}
293
+ ${detail("Location", location)}
294
+ ${detail("Viewport", viewport)}
295
+ ${detail("Profile", profile)}
296
+ ${detail("Reason", notCompared.reason)}
297
+ ${detail("Fingerprint", notCompared.fingerprint)}
298
+ </dl>
299
+ </article>`;
300
+ }
301
+ function renderCoverageList(label, values) {
302
+ if (values.length === 0) {
303
+ return `<p class="muted">No ${escapeHtml(label.toLowerCase())} were compared.</p>`;
304
+ }
305
+ return `<ul class="coverage-list">${values
306
+ .map((value) => `<li>${escapeHtml(value)}</li>`)
307
+ .join("")}</ul>`;
308
+ }
309
+ function renderComparisonCoverage(coverage) {
310
+ const flowRows = coverage.comparedFlows
311
+ .map((flow) => `<li>${escapeHtml(flow.flowId)}: ${escapeHtml(flow.checkpointIds.join(", "))}</li>`)
312
+ .join("");
313
+ return `<div class="baseline-coverage">
314
+ <h3 id="comparison-coverage-title">Comparison coverage</h3>
315
+ <dl class="metadata metadata--inline">
316
+ <div><dt>Compared projects</dt><dd>${coverage.comparedProjects.length}</dd></div>
317
+ <div><dt>Compared profiles</dt><dd>${coverage.comparedProfiles.length}</dd></div>
318
+ <div><dt>Compared viewports</dt><dd>${coverage.comparedViewports.length}</dd></div>
319
+ <div><dt>Compared routes</dt><dd>${coverage.comparedRoutes.length}</dd></div>
320
+ <div><dt>Compared flows</dt><dd>${coverage.comparedFlows.length}</dd></div>
321
+ <div><dt>Excluded projects</dt><dd>${coverage.excludedProjects.length}</dd></div>
322
+ <div><dt>Failed runs</dt><dd>${coverage.failedRuns.length}</dd></div>
323
+ <div><dt>Skipped runs</dt><dd>${coverage.skippedRuns.length}</dd></div>
324
+ </dl>
325
+ <div class="coverage-details">
326
+ <div><h4>Projects</h4>${renderCoverageList("projects", coverage.comparedProjects)}</div>
327
+ <div><h4>Profiles</h4>${renderCoverageList("profiles", coverage.comparedProfiles)}</div>
328
+ <div><h4>Viewports</h4>${renderCoverageList("viewports", coverage.comparedViewports)}</div>
329
+ <div><h4>Routes</h4>${renderCoverageList("routes", coverage.comparedRoutes)}</div>
330
+ <div><h4>Flows</h4>${coverage.comparedFlows.length === 0
331
+ ? `<p class="muted">No flows were compared.</p>`
332
+ : `<ul class="coverage-list">${flowRows}</ul>`}</div>
333
+ </div>
334
+ </div>`;
335
+ }
336
+ function renderSummaryCard(label, value, modifier) {
337
+ const className = modifier ? `summary-card ${modifier}` : "summary-card";
338
+ return `<div class="${className}"><span>${escapeHtml(label)}</span><strong>${value}</strong></div>`;
339
+ }
340
+ export function renderBaselineSummarySection(context) {
341
+ const summary = context.baselineSummary;
342
+ if (!summary?.baselineUsed) {
343
+ return "";
344
+ }
345
+ return `<section id="baseline-summary" aria-labelledby="baseline-summary-title">
346
+ <h2 id="baseline-summary-title">Baseline comparison</h2>
347
+ <dl class="metadata metadata--inline">
348
+ ${detail("Baseline used", summary.baselineUsed ? "Yes" : "No")}
349
+ ${detail("Baseline path", summary.baselinePath)}
350
+ ${detail("Schema version", context.schemaVersion)}
351
+ ${detail("Fingerprint version", context.fingerprintVersion)}
352
+ </dl>
353
+ <div class="summary-grid baseline-summary-grid">
354
+ ${renderSummaryCard("New findings", summary.newFindings, "summary-card--new")}
355
+ ${renderSummaryCard("Known debt", summary.knownFindings, "summary-card--known")}
356
+ ${renderSummaryCard("Regressions", summary.regressedFindings, "summary-card--regressed")}
357
+ ${renderSummaryCard("Resolved", summary.resolvedFindings, "summary-card--resolved")}
358
+ ${renderSummaryCard("Not compared", summary.notComparedFindings, "summary-card--not-compared")}
359
+ ${renderSummaryCard("Expired classifications", summary.expiredClassifications, "summary-card--expired")}
360
+ </div>
361
+ ${context.coverage ? renderComparisonCoverage(context.coverage) : ""}
362
+ <p class="muted">A baseline records known accessibility debt. It does not make that debt accessible or compliant.</p>
363
+ </section>`;
364
+ }
365
+ function renderFindingSection(id, title, items, emptyMessage) {
366
+ return `<section id="${id}" aria-labelledby="${id}-title">
367
+ <h2 id="${id}-title">${escapeHtml(title)}</h2>
368
+ ${items.length === 0
369
+ ? `<div class="empty-state"><p class="muted">${escapeHtml(emptyMessage)}</p></div>`
370
+ : `<div class="findings-list">${items.join("")}</div>`}
371
+ </section>`;
372
+ }
373
+ export function renderBaselineLifecycleSections(context, findings, renderFinding) {
374
+ if (!context.baselineUsed) {
375
+ return "";
376
+ }
377
+ const newFindings = findings.filter((finding) => findingLifecycle(finding) === "new");
378
+ const knownFindings = findings.filter((finding) => findingLifecycle(finding) === "known");
379
+ const regressedFindings = findings.filter((finding) => findingLifecycle(finding) === "regressed");
380
+ const classifiedFindings = findings.filter((finding) => finding.baseline?.classification);
381
+ const expiredFindings = findings.filter((finding) => finding.baseline?.classificationExpired === true);
382
+ return [
383
+ renderFindingSection("baseline-new", "New accessibility findings", newFindings.map((finding, index) => renderFinding(finding, index)), "No new accessibility findings compared to the baseline."),
384
+ renderFindingSection("baseline-known", "Known accessibility debt", knownFindings.map((finding, index) => renderFinding(finding, index)), "No known accessibility debt was matched in this audit."),
385
+ renderFindingSection("baseline-regressed", "Regressions", regressedFindings.map((finding, index) => renderFinding(finding, index)), "No regressions were detected compared to the baseline."),
386
+ renderFindingSection("baseline-resolved", "Resolved since baseline", context.resolvedFindings.map((finding, index) => renderResolvedFinding(finding, index)), "No baseline findings were resolved in compared coverage."),
387
+ renderFindingSection("baseline-not-compared", "Not compared in this audit", context.notComparedFindings.map((finding, index) => renderNotComparedFinding(finding, index)), "All baseline entries were compared in this audit."),
388
+ renderFindingSection("baseline-classified", "Classified findings", classifiedFindings.map((finding, index) => renderFinding(finding, index)), "No classified findings are recorded for this audit."),
389
+ renderFindingSection("baseline-expired", "Expired classifications", expiredFindings.map((finding, index) => renderFinding(finding, index)), "No expired classifications were detected in this audit."),
390
+ ].join("");
391
+ }
392
+ export function renderBaselineNavLinks(context) {
393
+ if (!context.baselineUsed) {
394
+ return "";
395
+ }
396
+ return `<li><a href="#baseline-summary">Baseline comparison</a></li>
397
+ <li><a href="#baseline-new">New findings</a></li>
398
+ <li><a href="#baseline-known">Known debt</a></li>
399
+ <li><a href="#baseline-regressed">Regressions</a></li>
400
+ <li><a href="#baseline-resolved">Resolved</a></li>
401
+ <li><a href="#baseline-not-compared">Not compared</a></li>
402
+ <li><a href="#baseline-classified">Classified</a></li>
403
+ <li><a href="#baseline-expired">Expired</a></li>`;
404
+ }
405
+ export function renderBaselineFilters(findings, context) {
406
+ if (!context.baselineUsed) {
407
+ return "";
408
+ }
409
+ const allFindings = findings;
410
+ const lifecycles = unique([
411
+ ...allFindings.map((finding) => findingLifecycle(finding)),
412
+ ...context.resolvedFindings.map(() => "resolved"),
413
+ ...context.notComparedFindings.map(() => "not-compared"),
414
+ ]);
415
+ const dispositions = unique(allFindings.map((finding) => finding.baseline?.classification?.disposition));
416
+ const owners = unique(allFindings.map((finding) => finding.baseline?.classification?.owner));
417
+ const tickets = unique(allFindings.map((finding) => finding.baseline?.classification?.ticket));
418
+ return [
419
+ filter("Lifecycle", "lifecycle", lifecycles, "All lifecycle states"),
420
+ filter("Disposition", "disposition", dispositions, "All dispositions"),
421
+ filter("Expired", "expired", ["yes", "no"], "Any expiry state"),
422
+ filter("Owner", "owner", owners, "All owners"),
423
+ filter("Ticket", "ticket", tickets, "All tickets"),
424
+ ].join("");
425
+ }
426
+ //# sourceMappingURL=baseline-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline-report.js","sourceRoot":"","sources":["../src/baseline-report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Finding, Severity } from "@a11yst/types";
2
+ import { type FindingRecommendationSummary } from "./finding-source-report.js";
3
+ export type FindingGroup = {
4
+ key: string;
5
+ severity: Severity;
6
+ ruleId: string;
7
+ title: string;
8
+ findings: Finding[];
9
+ recommendation?: FindingRecommendationSummary;
10
+ };
11
+ export declare function buildFindingGroupKey(finding: Finding): string;
12
+ export declare function groupFindings(findings: Finding[]): FindingGroup[];
13
+ export declare function countUniqueIssues(findings: Finding[]): number;
14
+ //# sourceMappingURL=finding-groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-groups.d.ts","sourceRoot":"","sources":["../src/finding-groups.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,4BAA4B,CAAC;AAIpC,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,4BAA4B,CAAC;CAC/C,CAAC;AA4BF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAU7D;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,CAsCjE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAE7D"}
@@ -0,0 +1,77 @@
1
+ import { resolveFindingRecommendationSummary, } from "./finding-source-report.js";
2
+ const SEVERITY_ORDER = ["critical", "high", "medium", "minor"];
3
+ function severityRank(severity) {
4
+ return SEVERITY_ORDER.indexOf(severity);
5
+ }
6
+ function compareFindingsStable(left, right) {
7
+ const routeOrder = (left.route ?? "").localeCompare(right.route ?? "");
8
+ if (routeOrder !== 0) {
9
+ return routeOrder;
10
+ }
11
+ const targetLeft = left.target.join(" ");
12
+ const targetRight = right.target.join(" ");
13
+ const targetOrder = targetLeft.localeCompare(targetRight);
14
+ if (targetOrder !== 0) {
15
+ return targetOrder;
16
+ }
17
+ return left.fingerprint.localeCompare(right.fingerprint);
18
+ }
19
+ function recommendationKey(finding) {
20
+ const summary = resolveFindingRecommendationSummary(finding);
21
+ if (!summary) {
22
+ return "";
23
+ }
24
+ return [summary.title ?? "", summary.summary ?? "", summary.applicability ?? ""].join("\0");
25
+ }
26
+ export function buildFindingGroupKey(finding) {
27
+ return [
28
+ finding.severity,
29
+ finding.ruleId,
30
+ recommendationKey(finding),
31
+ finding.route ?? "",
32
+ finding.profile ?? "",
33
+ finding.flowId ?? "",
34
+ finding.title,
35
+ ].join("\0");
36
+ }
37
+ export function groupFindings(findings) {
38
+ const groups = new Map();
39
+ for (const finding of findings) {
40
+ const key = buildFindingGroupKey(finding);
41
+ const existing = groups.get(key);
42
+ if (existing) {
43
+ existing.findings.push(finding);
44
+ continue;
45
+ }
46
+ groups.set(key, {
47
+ key,
48
+ severity: finding.severity,
49
+ ruleId: finding.ruleId,
50
+ title: finding.title,
51
+ findings: [finding],
52
+ recommendation: resolveFindingRecommendationSummary(finding),
53
+ });
54
+ }
55
+ return [...groups.values()]
56
+ .map((group) => ({
57
+ ...group,
58
+ findings: [...group.findings].sort(compareFindingsStable),
59
+ }))
60
+ .sort((left, right) => {
61
+ const severityOrder = severityRank(left.severity) - severityRank(right.severity);
62
+ if (severityOrder !== 0) {
63
+ return severityOrder;
64
+ }
65
+ const ruleOrder = left.ruleId.localeCompare(right.ruleId);
66
+ if (ruleOrder !== 0) {
67
+ return ruleOrder;
68
+ }
69
+ const routeLeft = left.findings[0]?.route ?? "";
70
+ const routeRight = right.findings[0]?.route ?? "";
71
+ return routeLeft.localeCompare(routeRight);
72
+ });
73
+ }
74
+ export function countUniqueIssues(findings) {
75
+ return groupFindings(findings).length;
76
+ }
77
+ //# sourceMappingURL=finding-groups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-groups.js","sourceRoot":"","sources":["../src/finding-groups.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { Finding, SourceLocation, SourceMappingConfidence, SourceMappingProvenance } from "@a11yst/types";
2
+ export type FindingReportSource = {
3
+ status: "mapped" | "ambiguous" | "unmapped" | "invalid";
4
+ location?: SourceLocation;
5
+ confidence?: SourceMappingConfidence;
6
+ provenance?: SourceMappingProvenance;
7
+ alternatives?: SourceLocation[];
8
+ };
9
+ export type FindingRecommendationSummary = {
10
+ status: string;
11
+ applicability?: string;
12
+ title?: string;
13
+ summary?: string;
14
+ };
15
+ export declare function resolveFindingReportSource(finding: Finding): FindingReportSource;
16
+ export declare function formatReportSourceLocation(location: SourceLocation): string;
17
+ /** Strip absolute or home-like paths from source URIs for human-facing reports. */
18
+ export declare function sanitizeSourceUriForReport(uri: string): string;
19
+ export declare function formatSafeReportSourceLocation(location: SourceLocation): string;
20
+ export declare function resolveFindingRecommendationSummary(finding: Finding): FindingRecommendationSummary | undefined;
21
+ //# sourceMappingURL=finding-source-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-source-report.d.ts","sourceRoot":"","sources":["../src/finding-source-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AA8EF,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,mBAAmB,CAqChF;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAI3E;AAKD,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU9D;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAK/E;AAED,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,OAAO,GACf,4BAA4B,GAAG,SAAS,CAe1C"}