aria-ease 6.14.0 → 7.0.1

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 (94) hide show
  1. package/README.md +1 -1
  2. package/dist/AccordionComponentStrategy-2SWMNUR6.js +1 -0
  3. package/dist/ComboboxComponentStrategy-YSYLR2U5.js +5 -0
  4. package/dist/MenuComponentStrategy-C22BZEBH.js +5 -0
  5. package/dist/RelativeTargetResolver-T4P25J2M.js +1 -0
  6. package/dist/TabsComponentStrategy-ADEEFJXM.js +1 -0
  7. package/dist/audit-WBKVW7H6.js +9 -0
  8. package/dist/badgeHelper-IB5RTMAG.js +11 -0
  9. package/dist/badgeHelper-JSROP5ML.js +1 -0
  10. package/dist/buildContracts-T4XQZBDU.js +13 -0
  11. package/dist/chunk-52I3INNG.js +11 -0
  12. package/dist/chunk-APUMBDOT.js +1 -0
  13. package/dist/chunk-BHNO4ZI3.js +1 -0
  14. package/dist/chunk-CNU4N4AY.js +1 -0
  15. package/dist/chunk-SM6ZKEDR.js +1 -0
  16. package/dist/chunk-ZNQ5BXVJ.js +1 -0
  17. package/dist/cli.cjs +132 -3560
  18. package/dist/cli.js +19 -161
  19. package/dist/configLoader-ZEJVXLX7.js +1 -0
  20. package/dist/configLoader-ZXTSCIP6.js +1 -0
  21. package/dist/contractTestRunnerPlaywright-FOCQTM4L.js +46 -0
  22. package/dist/contractTestRunnerPlaywright-QPU6HZXG.js +46 -0
  23. package/dist/formatters-H3CPDLG5.js +87 -0
  24. package/dist/index.cjs +64 -5103
  25. package/dist/index.d.cts +4 -6
  26. package/dist/index.d.ts +4 -6
  27. package/dist/index.js +17 -2703
  28. package/dist/src/accordion/index.cjs +1 -183
  29. package/dist/src/accordion/index.js +1 -181
  30. package/dist/src/block/index.cjs +1 -124
  31. package/dist/src/block/index.js +1 -122
  32. package/dist/src/checkbox/index.cjs +1 -109
  33. package/dist/src/checkbox/index.js +1 -107
  34. package/dist/src/combobox/index.cjs +1 -265
  35. package/dist/src/combobox/index.js +1 -263
  36. package/dist/src/menu/index.cjs +1 -339
  37. package/dist/src/menu/index.js +1 -337
  38. package/dist/src/radio/index.cjs +1 -117
  39. package/dist/src/radio/index.js +1 -115
  40. package/dist/src/tabs/index.cjs +1 -265
  41. package/dist/src/tabs/index.js +1 -263
  42. package/dist/src/toggle/index.cjs +1 -119
  43. package/dist/src/toggle/index.js +1 -117
  44. package/dist/src/utils/test/AccordionComponentStrategy-X2GSQ5KT.js +1 -0
  45. package/dist/src/utils/test/ComboboxComponentStrategy-SICWLI27.js +5 -0
  46. package/dist/src/utils/test/MenuComponentStrategy-R4VPAHDE.js +5 -0
  47. package/dist/src/utils/test/RelativeTargetResolver-UQQMZHI6.js +1 -0
  48. package/dist/src/utils/test/TabsComponentStrategy-L2PYNEW6.js +1 -0
  49. package/dist/src/utils/test/badgeHelper-ER5ZOHWF.js +11 -0
  50. package/dist/src/utils/test/chunk-APUMBDOT.js +1 -0
  51. package/dist/src/utils/test/chunk-BHNO4ZI3.js +1 -0
  52. package/dist/src/utils/test/configLoader-NCYRL2O6.js +1 -0
  53. package/dist/src/utils/test/contractTestRunnerPlaywright-YZCMF64Q.js +46 -0
  54. package/dist/src/utils/test/dsl/index.cjs +1 -838
  55. package/dist/src/utils/test/dsl/index.d.cts +2 -4
  56. package/dist/src/utils/test/dsl/index.d.ts +2 -4
  57. package/dist/src/utils/test/dsl/index.js +1 -836
  58. package/dist/src/utils/test/index.cjs +64 -2672
  59. package/dist/src/utils/test/index.d.cts +2 -2
  60. package/dist/src/utils/test/index.d.ts +2 -2
  61. package/dist/src/utils/test/index.js +16 -340
  62. package/dist/test-VXSCSKV5.js +19 -0
  63. package/package.json +8 -10
  64. package/dist/AccordionComponentStrategy-4ZEIQ2V6.js +0 -42
  65. package/dist/ComboboxComponentStrategy-DU342VMB.js +0 -64
  66. package/dist/MenuComponentStrategy-VYCC2XOM.js +0 -81
  67. package/dist/RelativeTargetResolver-DJAITO6D.js +0 -7
  68. package/dist/TabsComponentStrategy-3SQURPMX.js +0 -29
  69. package/dist/audit-JYEPKLHR.js +0 -63
  70. package/dist/badgeHelper-JOWO6RQG.js +0 -15
  71. package/dist/badgeHelper-RDOMCC6E.js +0 -108
  72. package/dist/buildContracts-VIV6GM56.js +0 -437
  73. package/dist/chunk-4DU5Z5BR.js +0 -340
  74. package/dist/chunk-GJGUY643.js +0 -182
  75. package/dist/chunk-GLT43UVH.js +0 -43
  76. package/dist/chunk-I2KLQ2HA.js +0 -22
  77. package/dist/chunk-JJEPLK7L.js +0 -107
  78. package/dist/chunk-PK5L2SAF.js +0 -17
  79. package/dist/configLoader-Q7N5XV4P.js +0 -183
  80. package/dist/configLoader-REHK3S3Q.js +0 -7
  81. package/dist/contractTestRunnerPlaywright-B2HLZKKK.js +0 -1394
  82. package/dist/contractTestRunnerPlaywright-RWK52C7S.js +0 -1394
  83. package/dist/formatters-32KQIIYS.js +0 -183
  84. package/dist/src/utils/test/AccordionComponentStrategy-WRHZOEN6.js +0 -38
  85. package/dist/src/utils/test/ComboboxComponentStrategy-XKQ72RFD.js +0 -60
  86. package/dist/src/utils/test/MenuComponentStrategy-6XWU5KLW.js +0 -77
  87. package/dist/src/utils/test/RelativeTargetResolver-G2XDN2VV.js +0 -1
  88. package/dist/src/utils/test/TabsComponentStrategy-BKG53SEV.js +0 -26
  89. package/dist/src/utils/test/badgeHelper-HZKGOPB4.js +0 -102
  90. package/dist/src/utils/test/chunk-4DU5Z5BR.js +0 -332
  91. package/dist/src/utils/test/chunk-GLT43UVH.js +0 -41
  92. package/dist/src/utils/test/configLoader-NA7IBCS3.js +0 -181
  93. package/dist/src/utils/test/contractTestRunnerPlaywright-5FIGA5G4.js +0 -1372
  94. package/dist/test-WDBS5JWO.js +0 -358
@@ -1,183 +0,0 @@
1
- import "./chunk-I2KLQ2HA.js";
2
-
3
- // src/utils/audit/src/formatters/formatters.ts
4
- function formatResults(allResults, format) {
5
- switch (format) {
6
- case "json":
7
- return JSON.stringify(
8
- allResults.flatMap(
9
- ({ url, result }) => result ? result.violations.flatMap(
10
- (v) => v.nodes.map((n) => ({
11
- URL: url,
12
- Rule: v.id,
13
- Impact: v.impact,
14
- Description: v.description,
15
- Target: n.target,
16
- FailureSummary: n.failureSummary
17
- }))
18
- ) : []
19
- ),
20
- null,
21
- 2
22
- );
23
- case "csv":
24
- return toCSV(allResults);
25
- case "html":
26
- return toHTML(allResults);
27
- default:
28
- return "";
29
- }
30
- }
31
- function toCSV(allResults) {
32
- const rows = ["URL,Rule,Impact,Description,Target,FailureSummary"];
33
- allResults.forEach(({ url, result }) => {
34
- if (result) {
35
- result.violations.forEach((v) => {
36
- v.nodes.forEach((n) => {
37
- rows.push(
38
- escapeCSV(url) + "," + escapeCSV(v.id) + "," + escapeCSV(v.impact) + "," + escapeCSV(v.description) + "," + escapeCSV(Array.isArray(n.target) ? n.target.join("; ") : String(n.target)) + "," + escapeCSV(n.failureSummary ?? "")
39
- );
40
- });
41
- });
42
- }
43
- });
44
- return rows.join("\n");
45
- }
46
- function escapeCSV(value) {
47
- const s = String(value ?? "");
48
- return `"${s.replace(/"/g, '""')}"`;
49
- }
50
- function toHTML(allResults) {
51
- const summary = {
52
- pagesAudited: 0,
53
- pagesWithViolations: 0,
54
- totalViolations: 0,
55
- distinctRules: /* @__PURE__ */ new Set(),
56
- impactCounts: /* @__PURE__ */ new Map()
57
- };
58
- allResults.forEach(({ result }) => {
59
- if (!result) return;
60
- summary.pagesAudited++;
61
- const pageViolations = result.violations.reduce((acc, v) => {
62
- const nodesCount = (v.nodes || []).length;
63
- if (nodesCount > 0) {
64
- summary.distinctRules.add(v.id);
65
- summary.totalViolations += nodesCount;
66
- acc += nodesCount;
67
- const impact = String(v.impact ?? "unknown");
68
- summary.impactCounts.set(impact, (summary.impactCounts.get(impact) || 0) + nodesCount);
69
- }
70
- return acc;
71
- }, 0);
72
- if (pageViolations > 0) summary.pagesWithViolations++;
73
- });
74
- const rows = [];
75
- allResults.forEach(({ url, result }) => {
76
- if (!result) return;
77
- result.violations.forEach((v) => {
78
- v.nodes.forEach((n) => {
79
- const target = Array.isArray(n.target) ? n.target.join("; ") : String(n.target);
80
- rows.push(`
81
- <tr>
82
- <td class="nowrap">${escapeHTML(url)}</td>
83
- <td class="nowrap">${escapeHTML(v.id)}</td>
84
- <td class="impact ${escapeClass(String(v.impact ?? "unknown"))}">${escapeHTML(String(v.impact ?? ""))}</td>
85
- <td class="desc">${escapeHTML(v.description ?? "")}</td>
86
- <td class="target"><code>${escapeHTML(target)}</code></td>
87
- <td class="fail">${escapeHTML(n.failureSummary ?? "").split(/\r?\n/).join("<br/>")}</td>
88
- </tr>
89
- `);
90
- });
91
- });
92
- });
93
- const impactSummary = Array.from(summary.impactCounts.entries()).map(([impact, count]) => `<li><strong class="impact ${escapeClass(impact)}">${escapeHTML(impact)}</strong>: ${count}</li>`).join("\n");
94
- const d = /* @__PURE__ */ new Date();
95
- const pad = (n) => String(n).padStart(2, "0");
96
- const reportDateTime = `${pad(d.getDate())}-${pad(d.getMonth() + 1)}-${d.getFullYear()} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
97
- const headerSummary = `
98
- <section class="summary">
99
- <h2>Report summary</h2>
100
- <ul>
101
- <li><strong>Date:</strong> ${reportDateTime}</li>
102
- <li><strong>Pages audited:</strong> ${summary.pagesAudited}</li>
103
- <li><strong>Pages with violations:</strong> ${summary.pagesWithViolations}</li>
104
- <li><strong>Total violations:</strong> ${summary.totalViolations}</li>
105
- <li><strong>Distinct rules:</strong> ${summary.distinctRules.size}</li>
106
- </ul>
107
- <div class="impact-summary">
108
- <h3>By impact</h3>
109
- <ul class="summary-list">
110
- ${impactSummary || "<li>None</li>"}
111
- </ul>
112
- </div>
113
- </section>
114
- `.trim();
115
- const html = `
116
- <!DOCTYPE html>
117
- <html lang="en">
118
- <head>
119
- <meta charset="utf-8"/>
120
- <title>Aria-Ease Accessibility Audit Report</title>
121
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
122
- <style>
123
- :root{
124
- --bg:#ffffff; --muted:#6b7280; --border:#e6e9ee;
125
- --impact-critical: red; --impact-moderate:#fff4dd; --impact-serious:rgb(255, 123, 0);
126
- }
127
- body{font-family:Inter,ui-sans-serif,system-ui,Segoe UI,Roboto,Helvetica,Arial; background:var(--bg); color:#111827; padding:24px; line-height:1.4}
128
- h1{margin:0 0 8px}
129
- .summary{background:#f8fafc;border:1px solid var(--border);padding:12px 16px;border-radius:8px;margin-bottom:18px}
130
- .summary ul{margin:6px 0 0 0;padding:0 18px}
131
- .impact-summary h3{margin:12px 0 6px}
132
- table{width:100%; border-collapse:collapse; margin-top:12px}
133
- th,td{border:1px solid var(--border); padding:10px; text-align:left; vertical-align:top}
134
- th{background:#f3f4f6; font-weight:600; position:sticky; top:0; z-index:1}
135
- .nowrap{white-space:nowrap}
136
- .target code{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, "Roboto Mono", "Courier New", monospace; white-space:pre-wrap}
137
- .desc{max-width:380px}
138
- tr:nth-child(even){background:#fbfbfb}
139
- td.fail{color:#7b1e1e}
140
- .impact.critical{background:var(--impact-critical); font-weight:600}
141
- .impact.moderate{background:var(--impact-moderate); font-weight:600}
142
- .impact.serious{background:var(--impact-serious); font-weight:600}
143
- @media (max-width:900px){
144
- .desc{max-width:200px}
145
- table, thead, tbody, th, td, tr{display:block}
146
- thead{display:none}
147
- tr{margin-bottom:10px; border: 1px solid var(--border);}
148
- td{border:1px solid var(--border); padding:6px}
149
- td::before{font-weight:600; display:inline-block; width:120px}
150
- }
151
- .summary-list strong,
152
- .summary-list li {
153
- padding: 2px 4px;
154
- }
155
- </style>
156
- </head>
157
- <body>
158
- <h1>Aria-Ease Accessibility Audit Report</h1>
159
- ${headerSummary}
160
- <table>
161
- <thead>
162
- <tr>
163
- <th>URL</th><th>Rule</th><th>Impact</th><th>Description</th><th>Target</th><th>FailureSummary</th>
164
- </tr>
165
- </thead>
166
- <tbody>
167
- ${rows.join("\n") || '<tr><td colspan="6"><em>No violations found.</em></td></tr>'}
168
- </tbody>
169
- </table>
170
- </body>
171
- </html>
172
- `.trim();
173
- return html;
174
- }
175
- function escapeHTML(str) {
176
- return String(str ?? "").replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
177
- }
178
- function escapeClass(s) {
179
- return String(s ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-");
180
- }
181
- export {
182
- formatResults
183
- };
@@ -1,38 +0,0 @@
1
- import { expect } from '@playwright/test';
2
-
3
- // src/utils/test/src/component-strategies/AccordionComponentStrategy.ts
4
- var AccordionComponentStrategy = class {
5
- constructor(mainSelector, selectors, actionTimeoutMs = 400, assertionTimeoutMs = 400) {
6
- this.mainSelector = mainSelector;
7
- this.selectors = selectors;
8
- this.actionTimeoutMs = actionTimeoutMs;
9
- this.assertionTimeoutMs = assertionTimeoutMs;
10
- }
11
- async resetState(page) {
12
- if (!this.selectors.panel || !this.selectors.trigger || this.selectors.popup) {
13
- return;
14
- }
15
- const triggerSelector = this.selectors.trigger;
16
- const panelSelector = this.selectors.panel;
17
- if (!triggerSelector || !panelSelector) return;
18
- const allTriggers = await page.locator(triggerSelector).all();
19
- for (const trigger of allTriggers) {
20
- const isExpanded = await trigger.getAttribute("aria-expanded") === "true";
21
- const triggerPanel = await trigger.getAttribute("aria-controls");
22
- if (isExpanded && triggerPanel) {
23
- await trigger.click({ timeout: this.actionTimeoutMs });
24
- const panel = page.locator(`#${triggerPanel}`);
25
- await expect(panel).toBeHidden({ timeout: this.assertionTimeoutMs }).catch(() => {
26
- });
27
- }
28
- }
29
- }
30
- async shouldSkipTest() {
31
- return false;
32
- }
33
- getMainSelector() {
34
- return this.mainSelector;
35
- }
36
- };
37
-
38
- export { AccordionComponentStrategy };
@@ -1,60 +0,0 @@
1
- import { expect } from '@playwright/test';
2
-
3
- // src/utils/test/src/component-strategies/ComboboxComponentStrategy.ts
4
- var ComboboxComponentStrategy = class {
5
- constructor(mainSelector, selectors, actionTimeoutMs = 400, assertionTimeoutMs = 400) {
6
- this.mainSelector = mainSelector;
7
- this.selectors = selectors;
8
- this.actionTimeoutMs = actionTimeoutMs;
9
- this.assertionTimeoutMs = assertionTimeoutMs;
10
- }
11
- async resetState(page) {
12
- if (!this.selectors.popup) return;
13
- const popupSelector = this.selectors.popup;
14
- const popupElement = page.locator(popupSelector).first();
15
- const isPopupVisible = await popupElement.isVisible().catch(() => false);
16
- if (!isPopupVisible) return;
17
- let popupClosed = false;
18
- let closeSelector = this.selectors.input;
19
- if (!closeSelector && this.selectors.focusable) {
20
- closeSelector = this.selectors.focusable;
21
- } else if (!closeSelector) {
22
- closeSelector = this.selectors.button;
23
- }
24
- if (closeSelector) {
25
- const closeElement = page.locator(closeSelector).first();
26
- await closeElement.focus();
27
- await page.keyboard.press("Escape");
28
- popupClosed = await expect(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
29
- }
30
- if (!popupClosed && this.selectors.button) {
31
- const buttonElement = page.locator(this.selectors.button).first();
32
- await buttonElement.click({ timeout: this.actionTimeoutMs });
33
- popupClosed = await expect(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
34
- }
35
- if (!popupClosed) {
36
- await page.mouse.click(10, 10);
37
- popupClosed = await expect(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
38
- }
39
- if (!popupClosed) {
40
- throw new Error(
41
- `\u274C FATAL: Cannot close combobox popup between tests. Popup remains visible after trying:
42
- 1. Escape key
43
- 2. Clicking button
44
- 3. Clicking outside
45
- This indicates a problem with the combobox component's close functionality.`
46
- );
47
- }
48
- if (this.selectors.input) {
49
- await page.locator(this.selectors.input).first().clear();
50
- }
51
- }
52
- async shouldSkipTest() {
53
- return false;
54
- }
55
- getMainSelector() {
56
- return this.mainSelector;
57
- }
58
- };
59
-
60
- export { ComboboxComponentStrategy };
@@ -1,77 +0,0 @@
1
- import { expect } from '@playwright/test';
2
-
3
- // src/utils/test/src/component-strategies/MenuComponentStrategy.ts
4
- var MenuComponentStrategy = class {
5
- constructor(mainSelector, selectors, actionTimeoutMs = 400, assertionTimeoutMs = 400) {
6
- this.mainSelector = mainSelector;
7
- this.selectors = selectors;
8
- this.actionTimeoutMs = actionTimeoutMs;
9
- this.assertionTimeoutMs = assertionTimeoutMs;
10
- }
11
- async resetState(page) {
12
- if (!this.selectors.popup) return;
13
- const popupSelector = this.selectors.popup;
14
- const popupElement = page.locator(popupSelector).first();
15
- const isPopupVisible = await popupElement.isVisible().catch(() => false);
16
- if (!isPopupVisible) return;
17
- let menuClosed = false;
18
- let closeSelector = this.selectors.input;
19
- if (!closeSelector && this.selectors.focusable) {
20
- closeSelector = this.selectors.focusable;
21
- } else if (!closeSelector) {
22
- closeSelector = this.selectors.main;
23
- }
24
- if (closeSelector) {
25
- const closeElement = page.locator(closeSelector).first();
26
- await closeElement.focus();
27
- await page.keyboard.press("Escape");
28
- menuClosed = await expect(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
29
- }
30
- if (!menuClosed && this.selectors.main) {
31
- const triggerElement = page.locator(this.selectors.main).first();
32
- await triggerElement.click({ timeout: this.actionTimeoutMs });
33
- menuClosed = await expect(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
34
- }
35
- if (!menuClosed) {
36
- await page.mouse.click(10, 10);
37
- menuClosed = await expect(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
38
- }
39
- if (!menuClosed) {
40
- throw new Error(
41
- `\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
42
- 1. Escape key
43
- 2. Clicking trigger
44
- 3. Clicking outside
45
- This indicates a problem with the menu component's close functionality.`
46
- );
47
- }
48
- if (this.selectors.input) {
49
- await page.locator(this.selectors.input).first().clear();
50
- }
51
- if (this.selectors.main) {
52
- const triggerElement = page.locator(this.selectors.main).first();
53
- await triggerElement.focus();
54
- }
55
- }
56
- async shouldSkipTest(test, page) {
57
- const requiresSubmenu = test.action.some(
58
- (act) => act.target === "submenu" || act.target === "submenuTrigger" || act.target === "submenuItems"
59
- ) || test.assertions.some(
60
- (assertion) => assertion.target === "submenu" || assertion.target === "submenuTrigger" || assertion.target === "submenuItems"
61
- );
62
- if (!requiresSubmenu) {
63
- return false;
64
- }
65
- const submenuTriggerSelector = this.selectors.submenuTrigger;
66
- if (!submenuTriggerSelector) {
67
- return true;
68
- }
69
- const submenuTriggerCount = await page.locator(submenuTriggerSelector).count();
70
- return submenuTriggerCount === 0;
71
- }
72
- getMainSelector() {
73
- return this.mainSelector;
74
- }
75
- };
76
-
77
- export { MenuComponentStrategy };
@@ -1 +0,0 @@
1
- export { RelativeTargetResolver } from './chunk-GLT43UVH.js';
@@ -1,26 +0,0 @@
1
- // src/utils/test/src/component-strategies/TabsComponentStrategy.ts
2
- var TabsComponentStrategy = class {
3
- constructor(mainSelector, selectors) {
4
- this.mainSelector = mainSelector;
5
- this.selectors = selectors;
6
- }
7
- async resetState() {
8
- }
9
- async shouldSkipTest(test, page) {
10
- if (test.isVertical !== void 0 && this.selectors.tablist) {
11
- const tablistSelector = this.selectors.tablist;
12
- const tablist = page.locator(tablistSelector).first();
13
- const orientation = await tablist.getAttribute("aria-orientation");
14
- const isVertical = orientation === "vertical";
15
- if (test.isVertical !== isVertical) {
16
- return true;
17
- }
18
- }
19
- return false;
20
- }
21
- getMainSelector() {
22
- return this.mainSelector;
23
- }
24
- };
25
-
26
- export { TabsComponentStrategy };
@@ -1,102 +0,0 @@
1
- import fs from 'fs-extra';
2
- import path from 'path';
3
- import chalk from 'chalk';
4
- import readline from 'readline';
5
-
6
- // src/utils/cli/badgeHelper.ts
7
- var BADGE_CONFIGS = {
8
- audit: {
9
- type: "audit",
10
- fileName: "audited-by-aria-ease.svg",
11
- label: "Audited by aria-ease",
12
- markdownUrl: "https://cdn.jsdelivr.net/gh/aria-ease/aria-ease@main/badges/audited-by-aria-ease.svg"
13
- },
14
- component: {
15
- type: "component",
16
- fileName: "components-tested-aria-ease.svg",
17
- label: "Components tested: aria-ease",
18
- markdownUrl: "https://cdn.jsdelivr.net/gh/aria-ease/aria-ease@main/badges/components-tested-aria-ease.svg"
19
- },
20
- verified: {
21
- type: "verified",
22
- fileName: "verified-by-aria-ease.svg",
23
- label: "Verified by aria-ease",
24
- markdownUrl: "https://cdn.jsdelivr.net/gh/aria-ease/aria-ease@main/badges/verified-by-aria-ease.svg"
25
- }
26
- };
27
- function getBadgeMarkdown(badgeType) {
28
- const config = BADGE_CONFIGS[badgeType];
29
- return `[![${config.label}](${config.markdownUrl})](https://github.com/aria-ease/aria-ease)`;
30
- }
31
- function displayBadgeInfo(badgeType) {
32
- const markdown = getBadgeMarkdown(badgeType);
33
- console.log(chalk.cyan("\n\u{1F3C5} Show your accessibility commitment!"));
34
- console.log(chalk.white(" Add this badge to your README.md:\n"));
35
- console.log(chalk.green(" " + markdown));
36
- console.log(chalk.dim("\n This helps others discover accessibility tools and shows you care!\n"));
37
- }
38
- async function promptAddBadge(badgeType, cwd = process.cwd()) {
39
- const readmePath = path.join(cwd, "README.md");
40
- const readmeExists = await fs.pathExists(readmePath);
41
- if (!readmeExists) {
42
- console.log(chalk.yellow(" \u2139\uFE0F No README.md found in current directory"));
43
- return;
44
- }
45
- const readmeContent = await fs.readFile(readmePath, "utf-8");
46
- const markdown = getBadgeMarkdown(badgeType);
47
- if (readmeContent.includes(markdown) || readmeContent.includes(BADGE_CONFIGS[badgeType].fileName)) {
48
- console.log(chalk.gray(" \u2713 Badge already in README.md"));
49
- return;
50
- }
51
- const rl = readline.createInterface({
52
- input: process.stdin,
53
- output: process.stdout
54
- });
55
- const answer = await new Promise((resolve) => {
56
- rl.question(chalk.cyan(" Add badge to README.md now? (y/n): "), (ans) => {
57
- rl.close();
58
- resolve(ans.toLowerCase().trim());
59
- });
60
- });
61
- if (answer === "y" || answer === "yes") {
62
- await addBadgeToReadme(readmePath, readmeContent, markdown);
63
- console.log(chalk.green(" \u2713 Badge added to README.md!"));
64
- } else {
65
- console.log(chalk.gray(" Skipped. You can add it manually anytime."));
66
- }
67
- }
68
- async function addBadgeToReadme(readmePath, content, badge) {
69
- const lines = content.split("\n");
70
- let insertIndex = 0;
71
- for (let i = 0; i < lines.length; i++) {
72
- const line = lines[i].trim();
73
- if (line.startsWith("[![") || line.startsWith("[!")) {
74
- insertIndex = i + 1;
75
- continue;
76
- }
77
- if (insertIndex > 0 && !line.startsWith("[![") && !line.startsWith("[!") && line.length > 0) {
78
- break;
79
- }
80
- if (insertIndex === 0 && line.startsWith("#")) {
81
- insertIndex = i + 2;
82
- break;
83
- }
84
- }
85
- if (insertIndex === 0) {
86
- insertIndex = 1;
87
- }
88
- lines.splice(insertIndex, 0, badge);
89
- await fs.writeFile(readmePath, lines.join("\n"), "utf-8");
90
- }
91
- function displayAllBadges() {
92
- console.log(chalk.cyan("\n\u{1F4CD} Available badges:"));
93
- console.log(chalk.white("\n For audits:"));
94
- console.log(chalk.green(" " + getBadgeMarkdown("audit")));
95
- console.log(chalk.white("\n For component testing:"));
96
- console.log(chalk.green(" " + getBadgeMarkdown("component")));
97
- console.log(chalk.white("\n For both (verified):"));
98
- console.log(chalk.green(" " + getBadgeMarkdown("verified")));
99
- console.log("");
100
- }
101
-
102
- export { BADGE_CONFIGS, displayAllBadges, displayBadgeInfo, getBadgeMarkdown, promptAddBadge };