@hypoth-ui/a11y-audit 0.1.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.
- package/LICENSE +21 -0
- package/README.md +47 -0
- package/dist/audit-Q3UXBYIW.js +266 -0
- package/dist/chunk-AMA6KCPL.js +39 -0
- package/dist/chunk-KLSGW6PX.js +515 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +36 -0
- package/dist/index.d.ts +156 -0
- package/dist/index.js +24 -0
- package/dist/report-6GBLBDLV.js +587 -0
- package/dist/validate-MQQMU57I.js +112 -0
- package/package.json +56 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateChecklist,
|
|
3
|
+
validateRecord
|
|
4
|
+
} from "./chunk-KLSGW6PX.js";
|
|
5
|
+
|
|
6
|
+
// src/cli/validate.ts
|
|
7
|
+
import * as fs from "fs";
|
|
8
|
+
import * as path from "path";
|
|
9
|
+
function findJsonFiles(dir) {
|
|
10
|
+
if (!fs.existsSync(dir)) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
const files = [];
|
|
14
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
const fullPath = path.join(dir, entry.name);
|
|
17
|
+
if (entry.isDirectory()) {
|
|
18
|
+
files.push(...findJsonFiles(fullPath));
|
|
19
|
+
} else if (entry.name.endsWith(".json") && !entry.name.includes(".backup")) {
|
|
20
|
+
files.push(fullPath);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return files;
|
|
24
|
+
}
|
|
25
|
+
function getFileType(filepath) {
|
|
26
|
+
if (filepath.includes("/templates/")) {
|
|
27
|
+
return "checklist";
|
|
28
|
+
}
|
|
29
|
+
if (filepath.includes("/records/")) {
|
|
30
|
+
return "record";
|
|
31
|
+
}
|
|
32
|
+
return "unknown";
|
|
33
|
+
}
|
|
34
|
+
async function validate(options) {
|
|
35
|
+
const { path: recordsPath, strict } = options;
|
|
36
|
+
const fullPath = path.resolve(process.cwd(), recordsPath);
|
|
37
|
+
console.info("\n\u{1F50D} Validating accessibility audit artifacts...");
|
|
38
|
+
console.info(` Path: ${fullPath}`);
|
|
39
|
+
console.info(` Mode: ${strict ? "Strict" : "Standard"}
|
|
40
|
+
`);
|
|
41
|
+
const files = findJsonFiles(fullPath);
|
|
42
|
+
if (files.length === 0) {
|
|
43
|
+
console.info("\u26A0\uFE0F No JSON files found to validate.");
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
const summary = {
|
|
47
|
+
total: files.length,
|
|
48
|
+
valid: 0,
|
|
49
|
+
invalid: 0,
|
|
50
|
+
warnings: 0,
|
|
51
|
+
errors: []
|
|
52
|
+
};
|
|
53
|
+
for (const file of files) {
|
|
54
|
+
const relativePath = path.relative(process.cwd(), file);
|
|
55
|
+
const fileType = getFileType(file);
|
|
56
|
+
try {
|
|
57
|
+
const content = fs.readFileSync(file, "utf-8");
|
|
58
|
+
const data = JSON.parse(content);
|
|
59
|
+
let result;
|
|
60
|
+
if (fileType === "checklist") {
|
|
61
|
+
result = validateChecklist(data);
|
|
62
|
+
} else if (fileType === "record") {
|
|
63
|
+
result = validateRecord(data);
|
|
64
|
+
} else {
|
|
65
|
+
result = validateRecord(data);
|
|
66
|
+
if (!result.valid) {
|
|
67
|
+
result = validateChecklist(data);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (result.valid) {
|
|
71
|
+
console.info(` \u2705 ${relativePath}`);
|
|
72
|
+
summary.valid++;
|
|
73
|
+
} else {
|
|
74
|
+
console.info(` \u274C ${relativePath}`);
|
|
75
|
+
for (const error of result.errors) {
|
|
76
|
+
console.info(` - ${error}`);
|
|
77
|
+
}
|
|
78
|
+
summary.invalid++;
|
|
79
|
+
summary.errors.push({ file: relativePath, errors: result.errors });
|
|
80
|
+
}
|
|
81
|
+
} catch (error) {
|
|
82
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
83
|
+
console.info(` \u274C ${relativePath}`);
|
|
84
|
+
console.info(` - Parse error: ${message}`);
|
|
85
|
+
summary.invalid++;
|
|
86
|
+
summary.errors.push({ file: relativePath, errors: [`Parse error: ${message}`] });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
console.info(`
|
|
90
|
+
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
91
|
+
VALIDATION SUMMARY
|
|
92
|
+
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
93
|
+
|
|
94
|
+
Total files: ${summary.total}
|
|
95
|
+
Valid: ${summary.valid}
|
|
96
|
+
Invalid: ${summary.invalid}
|
|
97
|
+
|
|
98
|
+
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
99
|
+
`);
|
|
100
|
+
if (summary.invalid > 0) {
|
|
101
|
+
console.error(`\u274C Validation failed: ${summary.invalid} file(s) have errors`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
if (strict && summary.warnings > 0) {
|
|
105
|
+
console.error(`\u274C Strict mode: ${summary.warnings} warning(s) treated as errors`);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
console.info("\u2705 All files validated successfully");
|
|
109
|
+
}
|
|
110
|
+
export {
|
|
111
|
+
validate
|
|
112
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hypoth-ui/a11y-audit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Accessibility audit and conformance reporting for the hypoth-ui design system (Alpha)",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/hypoth-ui/hypoth-ui.git",
|
|
10
|
+
"directory": "packages/a11y-audit"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/hypoth-ui/hypoth-ui#readme",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"accessibility",
|
|
15
|
+
"a11y",
|
|
16
|
+
"wcag",
|
|
17
|
+
"audit",
|
|
18
|
+
"hypoth-ui"
|
|
19
|
+
],
|
|
20
|
+
"bin": {
|
|
21
|
+
"a11y-audit": "./dist/cli/index.js"
|
|
22
|
+
},
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./schemas/*": "./dist/schemas/*",
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"tsup": "^8.0.0",
|
|
36
|
+
"typescript": "^5.3.0",
|
|
37
|
+
"vitest": "^1.0.0",
|
|
38
|
+
"tsx": "^4.7.0"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"ajv": "^8.12.0",
|
|
42
|
+
"ajv-formats": "^3.0.0",
|
|
43
|
+
"commander": "^12.0.0",
|
|
44
|
+
"handlebars": "^4.7.8"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsup src/index.ts src/cli/index.ts --format esm --dts",
|
|
48
|
+
"clean": "rm -rf dist",
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:unit": "vitest run tests/unit",
|
|
52
|
+
"audit": "tsx src/cli/index.ts audit",
|
|
53
|
+
"validate": "tsx src/cli/index.ts validate",
|
|
54
|
+
"report": "tsx src/cli/index.ts report"
|
|
55
|
+
}
|
|
56
|
+
}
|