@empline/preflight 1.1.56 → 1.1.58
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.
- package/dist/checks/accessibility/accessibility-validation.d.ts +10 -0
- package/dist/checks/accessibility/accessibility-validation.d.ts.map +1 -0
- package/dist/checks/accessibility/accessibility-validation.js +538 -0
- package/dist/checks/accessibility/accessibility-validation.js.map +1 -0
- package/dist/checks/checkout/checkout-flow-validation.d.ts +10 -0
- package/dist/checks/checkout/checkout-flow-validation.d.ts.map +1 -0
- package/dist/checks/checkout/checkout-flow-validation.js +473 -0
- package/dist/checks/checkout/checkout-flow-validation.js.map +1 -0
- package/dist/checks/database/enum-sync-validation.d.ts +10 -0
- package/dist/checks/database/enum-sync-validation.d.ts.map +1 -0
- package/dist/checks/database/enum-sync-validation.js +409 -0
- package/dist/checks/database/enum-sync-validation.js.map +1 -0
- package/dist/checks/email/email-validation.d.ts +10 -0
- package/dist/checks/email/email-validation.d.ts.map +1 -0
- package/dist/checks/email/email-validation.js +456 -0
- package/dist/checks/email/email-validation.js.map +1 -0
- package/dist/checks/observability/observability-validation.d.ts +10 -0
- package/dist/checks/observability/observability-validation.d.ts.map +1 -0
- package/dist/checks/observability/observability-validation.js +448 -0
- package/dist/checks/observability/observability-validation.js.map +1 -0
- package/dist/checks/seo/seo-validation.d.ts +10 -0
- package/dist/checks/seo/seo-validation.d.ts.map +1 -0
- package/dist/checks/seo/seo-validation.js +497 -0
- package/dist/checks/seo/seo-validation.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { PreflightCheckResult } from "../../core/types";
|
|
3
|
+
export declare const id = "accessibility/accessibility-validation";
|
|
4
|
+
export declare const name = "Accessibility Validation";
|
|
5
|
+
export declare const description = "Validates accessibility best practices (images, forms, ARIA, headings)";
|
|
6
|
+
export declare const category = "accessibility";
|
|
7
|
+
export declare const blocking = true;
|
|
8
|
+
export declare const tags: string[];
|
|
9
|
+
export declare function run(): Promise<PreflightCheckResult>;
|
|
10
|
+
//# sourceMappingURL=accessibility-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessibility-validation.d.ts","sourceRoot":"","sources":["../../../src/checks/accessibility/accessibility-validation.ts"],"names":[],"mappings":";AAiCA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAG1E,eAAO,MAAM,EAAE,2CAA2C,CAAC;AAC3D,eAAO,MAAM,IAAI,6BAA6B,CAAC;AAC/C,eAAO,MAAM,WAAW,2EAA2E,CAAC;AACpG,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AACxC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,IAAI,UAA+D,CAAC;AA+VjF,wBAAsB,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAqEzD"}
|
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.tags = exports.blocking = exports.category = exports.description = exports.name = exports.id = void 0;
|
|
38
|
+
exports.run = run;
|
|
39
|
+
/**
|
|
40
|
+
* Accessibility Validation Preflight (BLOCKING)
|
|
41
|
+
*
|
|
42
|
+
* Validates accessibility best practices in React/Next.js components:
|
|
43
|
+
*
|
|
44
|
+
* 1. Image Accessibility:
|
|
45
|
+
* - All <img> tags must have alt attribute
|
|
46
|
+
* - Next.js <Image> components must have alt attribute
|
|
47
|
+
* - Decorative images should have alt=""
|
|
48
|
+
*
|
|
49
|
+
* 2. Form Accessibility:
|
|
50
|
+
* - Form inputs must have associated labels (htmlFor/id or aria-label)
|
|
51
|
+
* - Buttons must have accessible text (children or aria-label)
|
|
52
|
+
* - Required fields should have aria-required
|
|
53
|
+
*
|
|
54
|
+
* 3. Interactive Element Accessibility:
|
|
55
|
+
* - onClick handlers on non-interactive elements need role and keyboard support
|
|
56
|
+
* - Links must have meaningful text (not just "click here")
|
|
57
|
+
* - Buttons should not be empty
|
|
58
|
+
*
|
|
59
|
+
* 4. ARIA Validation:
|
|
60
|
+
* - aria-* attributes must have valid values
|
|
61
|
+
* - role attributes must be valid ARIA roles
|
|
62
|
+
* - aria-hidden elements should not contain focusable content
|
|
63
|
+
*
|
|
64
|
+
* 5. Heading Structure:
|
|
65
|
+
* - Pages should have h1
|
|
66
|
+
* - Heading levels should not skip (h1 -> h3)
|
|
67
|
+
*/
|
|
68
|
+
const fs = __importStar(require("node:fs"));
|
|
69
|
+
const path = __importStar(require("node:path"));
|
|
70
|
+
const glob_1 = require("glob");
|
|
71
|
+
const console_chars_1 = require("../../utils/console-chars");
|
|
72
|
+
exports.id = "accessibility/accessibility-validation";
|
|
73
|
+
exports.name = "Accessibility Validation";
|
|
74
|
+
exports.description = "Validates accessibility best practices (images, forms, ARIA, headings)";
|
|
75
|
+
exports.category = "accessibility";
|
|
76
|
+
exports.blocking = true;
|
|
77
|
+
exports.tags = ["accessibility", "a11y", "wcag", "aria", "images", "forms"];
|
|
78
|
+
// Valid ARIA roles
|
|
79
|
+
const VALID_ROLES = new Set([
|
|
80
|
+
"alert", "alertdialog", "application", "article", "banner", "button",
|
|
81
|
+
"cell", "checkbox", "columnheader", "combobox", "complementary",
|
|
82
|
+
"contentinfo", "definition", "dialog", "directory", "document",
|
|
83
|
+
"feed", "figure", "form", "grid", "gridcell", "group", "heading",
|
|
84
|
+
"img", "link", "list", "listbox", "listitem", "log", "main",
|
|
85
|
+
"marquee", "math", "menu", "menubar", "menuitem", "menuitemcheckbox",
|
|
86
|
+
"menuitemradio", "navigation", "none", "note", "option", "presentation",
|
|
87
|
+
"progressbar", "radio", "radiogroup", "region", "row", "rowgroup",
|
|
88
|
+
"rowheader", "scrollbar", "search", "searchbox", "separator",
|
|
89
|
+
"slider", "spinbutton", "status", "switch", "tab", "table",
|
|
90
|
+
"tablist", "tabpanel", "term", "textbox", "timer", "toolbar",
|
|
91
|
+
"tooltip", "tree", "treegrid", "treeitem",
|
|
92
|
+
]);
|
|
93
|
+
// Patterns for meaningless link text
|
|
94
|
+
const MEANINGLESS_LINK_TEXT = [
|
|
95
|
+
/^click\s*here$/i,
|
|
96
|
+
/^here$/i,
|
|
97
|
+
/^read\s*more$/i,
|
|
98
|
+
/^learn\s*more$/i,
|
|
99
|
+
/^more$/i,
|
|
100
|
+
/^link$/i,
|
|
101
|
+
];
|
|
102
|
+
function getLineNumber(content, index) {
|
|
103
|
+
return content.substring(0, index).split("\n").length;
|
|
104
|
+
}
|
|
105
|
+
function checkImageAccessibility(content, filePath) {
|
|
106
|
+
const issues = [];
|
|
107
|
+
// Check <img> tags without alt
|
|
108
|
+
const imgRegex = /<img\s+(?![^>]*\balt\s*=)[^>]*>/gi;
|
|
109
|
+
let match;
|
|
110
|
+
while ((match = imgRegex.exec(content)) !== null) {
|
|
111
|
+
issues.push({
|
|
112
|
+
rule: "img-alt-required",
|
|
113
|
+
message: "<img> tag missing alt attribute",
|
|
114
|
+
file: filePath,
|
|
115
|
+
line: getLineNumber(content, match.index),
|
|
116
|
+
severity: "error",
|
|
117
|
+
suggestion: 'Add alt="description" or alt="" for decorative images',
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
// Check Next.js <Image> components without alt
|
|
121
|
+
// Skip if file imports Image from lucide-react (icon, not next/image)
|
|
122
|
+
const hasLucideImageImport = /import\s*\{[^}]*\bImage\b[^}]*\}\s*from\s*["']lucide-react["']/.test(content);
|
|
123
|
+
const hasNextImageImport = /import\s+Image\s+from\s*["']next\/image["']/.test(content);
|
|
124
|
+
// Only check for next/image alt if file imports from next/image
|
|
125
|
+
// or if it's clearly a Next.js Image (has src prop)
|
|
126
|
+
if (hasNextImageImport && !hasLucideImageImport) {
|
|
127
|
+
// For multi-line JSX, find Image components and extract until self-closing />
|
|
128
|
+
const imageStartRegex = /<Image\s/gi;
|
|
129
|
+
while ((match = imageStartRegex.exec(content)) !== null) {
|
|
130
|
+
// Find the closing /> by looking ahead (handles nested generics like Ref<HTMLImageElement>)
|
|
131
|
+
const startIndex = match.index;
|
|
132
|
+
const searchContent = content.substring(startIndex, startIndex + 1000); // Look ahead max 1000 chars
|
|
133
|
+
const closingIndex = searchContent.indexOf("/>");
|
|
134
|
+
if (closingIndex !== -1) {
|
|
135
|
+
const imageTag = searchContent.substring(0, closingIndex + 2);
|
|
136
|
+
// Check if alt is present anywhere in the tag
|
|
137
|
+
if (!/\balt\s*=/.test(imageTag)) {
|
|
138
|
+
issues.push({
|
|
139
|
+
rule: "next-image-alt-required",
|
|
140
|
+
message: "Next.js <Image> component missing alt attribute",
|
|
141
|
+
file: filePath,
|
|
142
|
+
line: getLineNumber(content, match.index),
|
|
143
|
+
severity: "error",
|
|
144
|
+
suggestion: 'Add alt="description" or alt="" for decorative images',
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else if (!hasLucideImageImport) {
|
|
151
|
+
// Fallback: check for Image components with src prop (Next.js pattern)
|
|
152
|
+
const imageStartRegex = /<Image\s/gi;
|
|
153
|
+
while ((match = imageStartRegex.exec(content)) !== null) {
|
|
154
|
+
const startIndex = match.index;
|
|
155
|
+
const searchContent = content.substring(startIndex, startIndex + 1000);
|
|
156
|
+
const closingIndex = searchContent.indexOf("/>");
|
|
157
|
+
if (closingIndex !== -1) {
|
|
158
|
+
const imageTag = searchContent.substring(0, closingIndex + 2);
|
|
159
|
+
// Only flag if it has src (Next.js Image) and no alt
|
|
160
|
+
if (/\bsrc\s*=/.test(imageTag) && !/\balt\s*=/.test(imageTag)) {
|
|
161
|
+
issues.push({
|
|
162
|
+
rule: "next-image-alt-required",
|
|
163
|
+
message: "Next.js <Image> component missing alt attribute",
|
|
164
|
+
file: filePath,
|
|
165
|
+
line: getLineNumber(content, match.index),
|
|
166
|
+
severity: "error",
|
|
167
|
+
suggestion: 'Add alt="description" or alt="" for decorative images',
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return issues;
|
|
174
|
+
}
|
|
175
|
+
function checkFormAccessibility(content, filePath) {
|
|
176
|
+
const issues = [];
|
|
177
|
+
// Check for inputs without labels or aria-label
|
|
178
|
+
// This is a simplified check - looks for <input> not followed by aria-label or aria-labelledby
|
|
179
|
+
const inputRegex = /<input\s+(?![^>]*(?:aria-label|aria-labelledby)\s*=)[^>]*type\s*=\s*["'](?!hidden|submit|button|reset)[^"']*["'][^>]*>/gi;
|
|
180
|
+
let match;
|
|
181
|
+
while ((match = inputRegex.exec(content)) !== null) {
|
|
182
|
+
// Check if there's an id and if content has a matching htmlFor
|
|
183
|
+
const idMatch = match[0].match(/id\s*=\s*["']([^"']+)["']/);
|
|
184
|
+
if (idMatch) {
|
|
185
|
+
const labelRegex = new RegExp(`htmlFor\\s*=\\s*["']${idMatch[1]}["']`, "i");
|
|
186
|
+
if (!labelRegex.test(content)) {
|
|
187
|
+
issues.push({
|
|
188
|
+
rule: "input-label-required",
|
|
189
|
+
message: `Input with id="${idMatch[1]}" has no associated label`,
|
|
190
|
+
file: filePath,
|
|
191
|
+
line: getLineNumber(content, match.index),
|
|
192
|
+
severity: "warning",
|
|
193
|
+
suggestion: `Add <label htmlFor="${idMatch[1]}"> or aria-label attribute`,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else if (!match[0].includes("aria-label")) {
|
|
198
|
+
issues.push({
|
|
199
|
+
rule: "input-label-required",
|
|
200
|
+
message: "Input has no id for label association and no aria-label",
|
|
201
|
+
file: filePath,
|
|
202
|
+
line: getLineNumber(content, match.index),
|
|
203
|
+
severity: "warning",
|
|
204
|
+
suggestion: "Add id with matching label htmlFor, or add aria-label",
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Check for empty buttons
|
|
209
|
+
const emptyButtonRegex = /<button[^>]*>\s*<\/button>/gi;
|
|
210
|
+
while ((match = emptyButtonRegex.exec(content)) !== null) {
|
|
211
|
+
if (!match[0].includes("aria-label")) {
|
|
212
|
+
issues.push({
|
|
213
|
+
rule: "button-text-required",
|
|
214
|
+
message: "Empty button has no accessible text",
|
|
215
|
+
file: filePath,
|
|
216
|
+
line: getLineNumber(content, match.index),
|
|
217
|
+
severity: "error",
|
|
218
|
+
suggestion: "Add button text content or aria-label",
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Check for icon-only buttons without aria-label
|
|
223
|
+
const iconButtonRegex = /<button[^>]*>\s*<(?:svg|Icon|[A-Z]\w*Icon)[^>]*\/?>\s*<\/button>/gi;
|
|
224
|
+
while ((match = iconButtonRegex.exec(content)) !== null) {
|
|
225
|
+
if (!match[0].includes("aria-label") && !match[0].includes("title")) {
|
|
226
|
+
issues.push({
|
|
227
|
+
rule: "icon-button-label-required",
|
|
228
|
+
message: "Icon-only button has no accessible text",
|
|
229
|
+
file: filePath,
|
|
230
|
+
line: getLineNumber(content, match.index),
|
|
231
|
+
severity: "error",
|
|
232
|
+
suggestion: 'Add aria-label="action description"',
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return issues;
|
|
237
|
+
}
|
|
238
|
+
function checkInteractiveElements(content, filePath) {
|
|
239
|
+
const issues = [];
|
|
240
|
+
// Check for onClick on non-interactive elements without role
|
|
241
|
+
const onClickDivRegex = /<div\s+(?![^>]*role\s*=)[^>]*onClick\s*=/gi;
|
|
242
|
+
let match;
|
|
243
|
+
while ((match = onClickDivRegex.exec(content)) !== null) {
|
|
244
|
+
issues.push({
|
|
245
|
+
rule: "div-onclick-needs-role",
|
|
246
|
+
message: "<div> with onClick needs role attribute for accessibility",
|
|
247
|
+
file: filePath,
|
|
248
|
+
line: getLineNumber(content, match.index),
|
|
249
|
+
severity: "warning",
|
|
250
|
+
suggestion: 'Add role="button" and tabIndex={0} and onKeyDown handler',
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
// Check for spans with onClick
|
|
254
|
+
const onClickSpanRegex = /<span\s+(?![^>]*role\s*=)[^>]*onClick\s*=/gi;
|
|
255
|
+
while ((match = onClickSpanRegex.exec(content)) !== null) {
|
|
256
|
+
issues.push({
|
|
257
|
+
rule: "span-onclick-needs-role",
|
|
258
|
+
message: "<span> with onClick needs role attribute for accessibility",
|
|
259
|
+
file: filePath,
|
|
260
|
+
line: getLineNumber(content, match.index),
|
|
261
|
+
severity: "warning",
|
|
262
|
+
suggestion: 'Add role="button" and tabIndex={0} and onKeyDown handler',
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
// Check for meaningless link text
|
|
266
|
+
for (const pattern of MEANINGLESS_LINK_TEXT) {
|
|
267
|
+
const linkRegex = new RegExp(`<(?:a|Link)[^>]*>\\s*${pattern.source}\\s*</(?:a|Link)>`, "gi");
|
|
268
|
+
while ((match = linkRegex.exec(content)) !== null) {
|
|
269
|
+
issues.push({
|
|
270
|
+
rule: "meaningful-link-text",
|
|
271
|
+
message: "Link has non-descriptive text",
|
|
272
|
+
file: filePath,
|
|
273
|
+
line: getLineNumber(content, match.index),
|
|
274
|
+
severity: "warning",
|
|
275
|
+
suggestion: "Use descriptive link text that explains the destination",
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return issues;
|
|
280
|
+
}
|
|
281
|
+
function checkAriaAttributes(content, filePath) {
|
|
282
|
+
const issues = [];
|
|
283
|
+
// Check for invalid role values
|
|
284
|
+
const roleRegex = /role\s*=\s*["']([^"']+)["']/gi;
|
|
285
|
+
let match;
|
|
286
|
+
while ((match = roleRegex.exec(content)) !== null) {
|
|
287
|
+
const role = match[1].toLowerCase();
|
|
288
|
+
if (!VALID_ROLES.has(role)) {
|
|
289
|
+
issues.push({
|
|
290
|
+
rule: "valid-aria-role",
|
|
291
|
+
message: `Invalid ARIA role: "${role}"`,
|
|
292
|
+
file: filePath,
|
|
293
|
+
line: getLineNumber(content, match.index),
|
|
294
|
+
severity: "error",
|
|
295
|
+
suggestion: `Use a valid ARIA role (e.g., button, link, dialog, etc.)`,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// Check for aria-hidden on elements with focusable content
|
|
300
|
+
// This is a conservative check that looks for specific patterns:
|
|
301
|
+
// 1. Self-closing tags with aria-hidden are safe (icons, etc.)
|
|
302
|
+
// 2. Only flag when we find a focusable element before the closing tag
|
|
303
|
+
const ariaHiddenElementRegex = /<(\w+)\s[^>]*aria-hidden\s*=\s*["']true["'][^>]*>/gi;
|
|
304
|
+
while ((match = ariaHiddenElementRegex.exec(content)) !== null) {
|
|
305
|
+
const fullMatch = match[0];
|
|
306
|
+
const tagName = match[1].toLowerCase();
|
|
307
|
+
// Skip self-closing tags (no children possible)
|
|
308
|
+
if (fullMatch.endsWith("/>"))
|
|
309
|
+
continue;
|
|
310
|
+
// Skip known safe elements (icons, separators)
|
|
311
|
+
if (["svg", "path", "span", "i"].includes(tagName))
|
|
312
|
+
continue;
|
|
313
|
+
// Look for the closing tag and check content between
|
|
314
|
+
const startIndex = match.index + fullMatch.length;
|
|
315
|
+
const closingTagRegex = new RegExp(`</${tagName}\\s*>`, "gi");
|
|
316
|
+
closingTagRegex.lastIndex = startIndex;
|
|
317
|
+
const closingMatch = closingTagRegex.exec(content);
|
|
318
|
+
if (closingMatch) {
|
|
319
|
+
// Extract content between opening and closing tags
|
|
320
|
+
const innerContent = content.substring(startIndex, closingMatch.index);
|
|
321
|
+
// Check for focusable elements in the inner content
|
|
322
|
+
// but ignore tabIndex={-1} which makes elements non-focusable
|
|
323
|
+
const hasFocusable = /<(?:button|a|input|select|textarea|Link)\s(?![^>]*tabIndex\s*=\s*\{?\s*-1)[^>]*>/i.test(innerContent);
|
|
324
|
+
if (hasFocusable) {
|
|
325
|
+
issues.push({
|
|
326
|
+
rule: "aria-hidden-focusable",
|
|
327
|
+
message: "aria-hidden element contains focusable content",
|
|
328
|
+
file: filePath,
|
|
329
|
+
line: getLineNumber(content, match.index),
|
|
330
|
+
severity: "error",
|
|
331
|
+
suggestion: "Remove focusable elements from aria-hidden containers or add tabIndex={-1}",
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// Check for aria-label on elements that don't support it (non-interactive)
|
|
337
|
+
// This is a simplified check
|
|
338
|
+
const ariaLabelOnDivRegex = /<div\s+(?![^>]*role\s*=)[^>]*aria-label\s*=/gi;
|
|
339
|
+
while ((match = ariaLabelOnDivRegex.exec(content)) !== null) {
|
|
340
|
+
issues.push({
|
|
341
|
+
rule: "aria-label-valid-element",
|
|
342
|
+
message: "aria-label on <div> without role may not be announced",
|
|
343
|
+
file: filePath,
|
|
344
|
+
line: getLineNumber(content, match.index),
|
|
345
|
+
severity: "warning",
|
|
346
|
+
suggestion: "Add a role attribute or use aria-labelledby instead",
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
return issues;
|
|
350
|
+
}
|
|
351
|
+
function checkHeadingStructure(content, filePath) {
|
|
352
|
+
const issues = [];
|
|
353
|
+
// Find all heading tags
|
|
354
|
+
const headingRegex = /<h([1-6])[^>]*>/gi;
|
|
355
|
+
const headings = [];
|
|
356
|
+
let match;
|
|
357
|
+
while ((match = headingRegex.exec(content)) !== null) {
|
|
358
|
+
headings.push({
|
|
359
|
+
level: parseInt(match[1], 10),
|
|
360
|
+
index: match.index,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
if (headings.length === 0) {
|
|
364
|
+
return issues; // No headings to check
|
|
365
|
+
}
|
|
366
|
+
// Check for skipped heading levels
|
|
367
|
+
for (let i = 1; i < headings.length; i++) {
|
|
368
|
+
const prev = headings[i - 1];
|
|
369
|
+
const curr = headings[i];
|
|
370
|
+
// If going deeper, shouldn't skip levels (h1 -> h3 is bad, h1 -> h2 is fine)
|
|
371
|
+
if (curr.level > prev.level && curr.level - prev.level > 1) {
|
|
372
|
+
issues.push({
|
|
373
|
+
rule: "heading-order",
|
|
374
|
+
message: `Heading level skipped: h${prev.level} to h${curr.level}`,
|
|
375
|
+
file: filePath,
|
|
376
|
+
line: getLineNumber(content, curr.index),
|
|
377
|
+
severity: "warning",
|
|
378
|
+
suggestion: `Use h${prev.level + 1} instead of h${curr.level}`,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return issues;
|
|
383
|
+
}
|
|
384
|
+
async function run() {
|
|
385
|
+
const startTime = Date.now();
|
|
386
|
+
const findings = [];
|
|
387
|
+
// Find all TSX files
|
|
388
|
+
const files = await (0, glob_1.glob)([
|
|
389
|
+
"app/**/*.tsx",
|
|
390
|
+
"components/**/*.tsx",
|
|
391
|
+
"src/**/*.tsx",
|
|
392
|
+
], {
|
|
393
|
+
cwd: process.cwd(),
|
|
394
|
+
ignore: [
|
|
395
|
+
"**/node_modules/**",
|
|
396
|
+
"**/*.test.tsx",
|
|
397
|
+
"**/*.spec.tsx",
|
|
398
|
+
"**/*.stories.tsx",
|
|
399
|
+
],
|
|
400
|
+
});
|
|
401
|
+
let filesChecked = 0;
|
|
402
|
+
const allIssues = [];
|
|
403
|
+
for (const file of files) {
|
|
404
|
+
const filePath = path.join(process.cwd(), file);
|
|
405
|
+
if (!fs.existsSync(filePath))
|
|
406
|
+
continue;
|
|
407
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
408
|
+
// Skip files with accessibility ignore comment
|
|
409
|
+
if (content.includes("a11y-ignore") || content.includes("accessibility-ignore")) {
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
filesChecked++;
|
|
413
|
+
// Run all accessibility checks
|
|
414
|
+
allIssues.push(...checkImageAccessibility(content, file));
|
|
415
|
+
allIssues.push(...checkFormAccessibility(content, file));
|
|
416
|
+
allIssues.push(...checkInteractiveElements(content, file));
|
|
417
|
+
allIssues.push(...checkAriaAttributes(content, file));
|
|
418
|
+
allIssues.push(...checkHeadingStructure(content, file));
|
|
419
|
+
}
|
|
420
|
+
// Convert to findings
|
|
421
|
+
for (const issue of allIssues) {
|
|
422
|
+
findings.push({
|
|
423
|
+
level: issue.severity,
|
|
424
|
+
message: issue.message,
|
|
425
|
+
file: issue.file,
|
|
426
|
+
startLine: issue.line,
|
|
427
|
+
ruleId: issue.rule,
|
|
428
|
+
suggestion: issue.suggestion,
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
const errors = findings.filter(f => f.level === "error");
|
|
432
|
+
const warnings = findings.filter(f => f.level === "warning");
|
|
433
|
+
return {
|
|
434
|
+
passed: errors.length === 0,
|
|
435
|
+
findings,
|
|
436
|
+
duration: Date.now() - startTime,
|
|
437
|
+
metadata: {
|
|
438
|
+
filesChecked,
|
|
439
|
+
totalIssues: allIssues.length,
|
|
440
|
+
errors: errors.length,
|
|
441
|
+
warnings: warnings.length,
|
|
442
|
+
},
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
async function main() {
|
|
446
|
+
console.log(`\n${console_chars_1.emoji.accessibility} ACCESSIBILITY VALIDATION`);
|
|
447
|
+
console.log((0, console_chars_1.createDivider)(65, "heavy"));
|
|
448
|
+
const result = await run();
|
|
449
|
+
const { filesChecked, totalIssues, errors, warnings } = result.metadata || {};
|
|
450
|
+
console.log(`\n${console_chars_1.emoji.search} Checking accessibility...`);
|
|
451
|
+
console.log(` Files checked: ${filesChecked}`);
|
|
452
|
+
console.log(` Total issues: ${totalIssues}`);
|
|
453
|
+
console.log(`\n${console_chars_1.emoji.chart} Summary:`);
|
|
454
|
+
console.log(` Errors: ${errors}`);
|
|
455
|
+
console.log(` Warnings: ${warnings}`);
|
|
456
|
+
if (result.passed && warnings === 0) {
|
|
457
|
+
console.log(`\n${console_chars_1.emoji.success} ACCESSIBILITY VALIDATION PASSED`);
|
|
458
|
+
console.log(`\nAll components follow accessibility best practices.`);
|
|
459
|
+
process.exit(0);
|
|
460
|
+
}
|
|
461
|
+
// Group findings by rule
|
|
462
|
+
const findingsByRule = new Map();
|
|
463
|
+
for (const finding of result.findings) {
|
|
464
|
+
const ruleId = finding.ruleId || "unknown";
|
|
465
|
+
if (!findingsByRule.has(ruleId)) {
|
|
466
|
+
findingsByRule.set(ruleId, []);
|
|
467
|
+
}
|
|
468
|
+
findingsByRule.get(ruleId).push(finding);
|
|
469
|
+
}
|
|
470
|
+
// Print errors
|
|
471
|
+
const errorFindings = result.findings.filter(f => f.level === "error");
|
|
472
|
+
if (errorFindings.length > 0) {
|
|
473
|
+
console.log(`\n${console_chars_1.emoji.error} Errors (blocking):`);
|
|
474
|
+
const errorsByRule = new Map();
|
|
475
|
+
for (const finding of errorFindings) {
|
|
476
|
+
const ruleId = finding.ruleId || "unknown";
|
|
477
|
+
if (!errorsByRule.has(ruleId)) {
|
|
478
|
+
errorsByRule.set(ruleId, []);
|
|
479
|
+
}
|
|
480
|
+
errorsByRule.get(ruleId).push(finding);
|
|
481
|
+
}
|
|
482
|
+
for (const [ruleId, ruleFindings] of errorsByRule) {
|
|
483
|
+
console.log(`\n ${ruleId} (${ruleFindings.length}):`);
|
|
484
|
+
for (const finding of ruleFindings.slice(0, 5)) {
|
|
485
|
+
console.log(` ${finding.file}:${finding.startLine}`);
|
|
486
|
+
console.log(` ${finding.message}`);
|
|
487
|
+
if (finding.suggestion) {
|
|
488
|
+
console.log(` ${console_chars_1.emoji.hint} ${finding.suggestion}`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
if (ruleFindings.length > 5) {
|
|
492
|
+
console.log(` ... and ${ruleFindings.length - 5} more`);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
// Print warnings
|
|
497
|
+
const warningFindings = result.findings.filter(f => f.level === "warning");
|
|
498
|
+
if (warningFindings.length > 0) {
|
|
499
|
+
console.log(`\n${console_chars_1.emoji.warning} Warnings:`);
|
|
500
|
+
const warningsByRule = new Map();
|
|
501
|
+
for (const finding of warningFindings) {
|
|
502
|
+
const ruleId = finding.ruleId || "unknown";
|
|
503
|
+
if (!warningsByRule.has(ruleId)) {
|
|
504
|
+
warningsByRule.set(ruleId, []);
|
|
505
|
+
}
|
|
506
|
+
warningsByRule.get(ruleId).push(finding);
|
|
507
|
+
}
|
|
508
|
+
for (const [ruleId, ruleFindings] of warningsByRule) {
|
|
509
|
+
console.log(`\n ${ruleId} (${ruleFindings.length}):`);
|
|
510
|
+
for (const finding of ruleFindings.slice(0, 3)) {
|
|
511
|
+
console.log(` ${finding.file}:${finding.startLine}`);
|
|
512
|
+
console.log(` ${finding.message}`);
|
|
513
|
+
}
|
|
514
|
+
if (ruleFindings.length > 3) {
|
|
515
|
+
console.log(` ... and ${ruleFindings.length - 3} more`);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
console.log(`\n${console_chars_1.emoji.info} Accessibility Rules:`);
|
|
520
|
+
console.log(` - All images must have alt text`);
|
|
521
|
+
console.log(` - Form inputs need labels or aria-label`);
|
|
522
|
+
console.log(` - Buttons must have accessible text`);
|
|
523
|
+
console.log(` - onClick handlers need role & keyboard support`);
|
|
524
|
+
console.log(` - Heading levels should not skip`);
|
|
525
|
+
if (!result.passed) {
|
|
526
|
+
console.log(`\n${console_chars_1.emoji.error} ACCESSIBILITY VALIDATION FAILED`);
|
|
527
|
+
process.exit(1);
|
|
528
|
+
}
|
|
529
|
+
console.log(`\n${console_chars_1.emoji.warning} ACCESSIBILITY VALIDATION PASSED WITH WARNINGS`);
|
|
530
|
+
process.exit(0);
|
|
531
|
+
}
|
|
532
|
+
if (require.main === module) {
|
|
533
|
+
main().catch((err) => {
|
|
534
|
+
console.error(`${console_chars_1.emoji.error} Preflight failed:`, err);
|
|
535
|
+
process.exit(1);
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
//# sourceMappingURL=accessibility-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessibility-validation.js","sourceRoot":"","sources":["../../../src/checks/accessibility/accessibility-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { PreflightCheckResult } from "../../core/types";
|
|
3
|
+
export declare const id = "checkout/checkout-flow-validation";
|
|
4
|
+
export declare const name = "Checkout Flow Validation";
|
|
5
|
+
export declare const description = "Validates checkout flow security and best practices";
|
|
6
|
+
export declare const category = "checkout";
|
|
7
|
+
export declare const blocking = true;
|
|
8
|
+
export declare const tags: string[];
|
|
9
|
+
export declare function run(): Promise<PreflightCheckResult>;
|
|
10
|
+
//# sourceMappingURL=checkout-flow-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout-flow-validation.d.ts","sourceRoot":"","sources":["../../../src/checks/checkout/checkout-flow-validation.ts"],"names":[],"mappings":";AAkCA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,kBAAkB,CAAC;AAG1E,eAAO,MAAM,EAAE,sCAAsC,CAAC;AACtD,eAAO,MAAM,IAAI,6BAA6B,CAAC;AAC/C,eAAO,MAAM,WAAW,wDAAwD,CAAC;AACjF,eAAO,MAAM,QAAQ,aAAa,CAAC;AACnC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,IAAI,UAAyD,CAAC;AA2V3E,wBAAsB,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAmCzD"}
|