aria-ease 6.14.0 → 7.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 (93) hide show
  1. package/dist/AccordionComponentStrategy-2SWMNUR6.js +1 -0
  2. package/dist/ComboboxComponentStrategy-YSYLR2U5.js +5 -0
  3. package/dist/MenuComponentStrategy-C22BZEBH.js +5 -0
  4. package/dist/RelativeTargetResolver-T4P25J2M.js +1 -0
  5. package/dist/TabsComponentStrategy-ADEEFJXM.js +1 -0
  6. package/dist/audit-APAPHXRO.js +9 -0
  7. package/dist/badgeHelper-IB5RTMAG.js +11 -0
  8. package/dist/badgeHelper-JSROP5ML.js +1 -0
  9. package/dist/buildContracts-T4XQZBDU.js +13 -0
  10. package/dist/chunk-52I3INNG.js +11 -0
  11. package/dist/chunk-APUMBDOT.js +1 -0
  12. package/dist/chunk-BHNO4ZI3.js +1 -0
  13. package/dist/chunk-CNU4N4AY.js +1 -0
  14. package/dist/chunk-SM6ZKEDR.js +1 -0
  15. package/dist/chunk-ZNQ5BXVJ.js +1 -0
  16. package/dist/cli.cjs +132 -3560
  17. package/dist/cli.js +19 -161
  18. package/dist/configLoader-ZEJVXLX7.js +1 -0
  19. package/dist/configLoader-ZXTSCIP6.js +1 -0
  20. package/dist/contractTestRunnerPlaywright-FOCQTM4L.js +46 -0
  21. package/dist/contractTestRunnerPlaywright-QPU6HZXG.js +46 -0
  22. package/dist/formatters-H3CPDLG5.js +87 -0
  23. package/dist/index.cjs +64 -5103
  24. package/dist/index.d.cts +4 -6
  25. package/dist/index.d.ts +4 -6
  26. package/dist/index.js +17 -2703
  27. package/dist/src/accordion/index.cjs +1 -183
  28. package/dist/src/accordion/index.js +1 -181
  29. package/dist/src/block/index.cjs +1 -124
  30. package/dist/src/block/index.js +1 -122
  31. package/dist/src/checkbox/index.cjs +1 -109
  32. package/dist/src/checkbox/index.js +1 -107
  33. package/dist/src/combobox/index.cjs +1 -265
  34. package/dist/src/combobox/index.js +1 -263
  35. package/dist/src/menu/index.cjs +1 -339
  36. package/dist/src/menu/index.js +1 -337
  37. package/dist/src/radio/index.cjs +1 -117
  38. package/dist/src/radio/index.js +1 -115
  39. package/dist/src/tabs/index.cjs +1 -265
  40. package/dist/src/tabs/index.js +1 -263
  41. package/dist/src/toggle/index.cjs +1 -119
  42. package/dist/src/toggle/index.js +1 -117
  43. package/dist/src/utils/test/AccordionComponentStrategy-X2GSQ5KT.js +1 -0
  44. package/dist/src/utils/test/ComboboxComponentStrategy-SICWLI27.js +5 -0
  45. package/dist/src/utils/test/MenuComponentStrategy-R4VPAHDE.js +5 -0
  46. package/dist/src/utils/test/RelativeTargetResolver-UQQMZHI6.js +1 -0
  47. package/dist/src/utils/test/TabsComponentStrategy-L2PYNEW6.js +1 -0
  48. package/dist/src/utils/test/badgeHelper-ER5ZOHWF.js +11 -0
  49. package/dist/src/utils/test/chunk-APUMBDOT.js +1 -0
  50. package/dist/src/utils/test/chunk-BHNO4ZI3.js +1 -0
  51. package/dist/src/utils/test/configLoader-NCYRL2O6.js +1 -0
  52. package/dist/src/utils/test/contractTestRunnerPlaywright-YZCMF64Q.js +46 -0
  53. package/dist/src/utils/test/dsl/index.cjs +1 -838
  54. package/dist/src/utils/test/dsl/index.d.cts +2 -4
  55. package/dist/src/utils/test/dsl/index.d.ts +2 -4
  56. package/dist/src/utils/test/dsl/index.js +1 -836
  57. package/dist/src/utils/test/index.cjs +64 -2672
  58. package/dist/src/utils/test/index.d.cts +2 -2
  59. package/dist/src/utils/test/index.d.ts +2 -2
  60. package/dist/src/utils/test/index.js +16 -340
  61. package/dist/test-VXSCSKV5.js +19 -0
  62. package/package.json +7 -9
  63. package/dist/AccordionComponentStrategy-4ZEIQ2V6.js +0 -42
  64. package/dist/ComboboxComponentStrategy-DU342VMB.js +0 -64
  65. package/dist/MenuComponentStrategy-VYCC2XOM.js +0 -81
  66. package/dist/RelativeTargetResolver-DJAITO6D.js +0 -7
  67. package/dist/TabsComponentStrategy-3SQURPMX.js +0 -29
  68. package/dist/audit-JYEPKLHR.js +0 -63
  69. package/dist/badgeHelper-JOWO6RQG.js +0 -15
  70. package/dist/badgeHelper-RDOMCC6E.js +0 -108
  71. package/dist/buildContracts-VIV6GM56.js +0 -437
  72. package/dist/chunk-4DU5Z5BR.js +0 -340
  73. package/dist/chunk-GJGUY643.js +0 -182
  74. package/dist/chunk-GLT43UVH.js +0 -43
  75. package/dist/chunk-I2KLQ2HA.js +0 -22
  76. package/dist/chunk-JJEPLK7L.js +0 -107
  77. package/dist/chunk-PK5L2SAF.js +0 -17
  78. package/dist/configLoader-Q7N5XV4P.js +0 -183
  79. package/dist/configLoader-REHK3S3Q.js +0 -7
  80. package/dist/contractTestRunnerPlaywright-B2HLZKKK.js +0 -1394
  81. package/dist/contractTestRunnerPlaywright-RWK52C7S.js +0 -1394
  82. package/dist/formatters-32KQIIYS.js +0 -183
  83. package/dist/src/utils/test/AccordionComponentStrategy-WRHZOEN6.js +0 -38
  84. package/dist/src/utils/test/ComboboxComponentStrategy-XKQ72RFD.js +0 -60
  85. package/dist/src/utils/test/MenuComponentStrategy-6XWU5KLW.js +0 -77
  86. package/dist/src/utils/test/RelativeTargetResolver-G2XDN2VV.js +0 -1
  87. package/dist/src/utils/test/TabsComponentStrategy-BKG53SEV.js +0 -26
  88. package/dist/src/utils/test/badgeHelper-HZKGOPB4.js +0 -102
  89. package/dist/src/utils/test/chunk-4DU5Z5BR.js +0 -332
  90. package/dist/src/utils/test/chunk-GLT43UVH.js +0 -41
  91. package/dist/src/utils/test/configLoader-NA7IBCS3.js +0 -181
  92. package/dist/src/utils/test/contractTestRunnerPlaywright-5FIGA5G4.js +0 -1372
  93. 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 };