@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.
Files changed (25) hide show
  1. package/dist/checks/accessibility/accessibility-validation.d.ts +10 -0
  2. package/dist/checks/accessibility/accessibility-validation.d.ts.map +1 -0
  3. package/dist/checks/accessibility/accessibility-validation.js +538 -0
  4. package/dist/checks/accessibility/accessibility-validation.js.map +1 -0
  5. package/dist/checks/checkout/checkout-flow-validation.d.ts +10 -0
  6. package/dist/checks/checkout/checkout-flow-validation.d.ts.map +1 -0
  7. package/dist/checks/checkout/checkout-flow-validation.js +473 -0
  8. package/dist/checks/checkout/checkout-flow-validation.js.map +1 -0
  9. package/dist/checks/database/enum-sync-validation.d.ts +10 -0
  10. package/dist/checks/database/enum-sync-validation.d.ts.map +1 -0
  11. package/dist/checks/database/enum-sync-validation.js +409 -0
  12. package/dist/checks/database/enum-sync-validation.js.map +1 -0
  13. package/dist/checks/email/email-validation.d.ts +10 -0
  14. package/dist/checks/email/email-validation.d.ts.map +1 -0
  15. package/dist/checks/email/email-validation.js +456 -0
  16. package/dist/checks/email/email-validation.js.map +1 -0
  17. package/dist/checks/observability/observability-validation.d.ts +10 -0
  18. package/dist/checks/observability/observability-validation.d.ts.map +1 -0
  19. package/dist/checks/observability/observability-validation.js +448 -0
  20. package/dist/checks/observability/observability-validation.js.map +1 -0
  21. package/dist/checks/seo/seo-validation.d.ts +10 -0
  22. package/dist/checks/seo/seo-validation.d.ts.map +1 -0
  23. package/dist/checks/seo/seo-validation.js +497 -0
  24. package/dist/checks/seo/seo-validation.js.map +1 -0
  25. 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"}