a11ylens 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/CHANGELOG.md +6 -0
- package/LICENSE +21 -0
- package/README.md +135 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +162 -0
- package/dist/config/defaults.d.ts +2 -0
- package/dist/config/defaults.js +9 -0
- package/dist/config/loader.d.ts +7 -0
- package/dist/config/loader.js +104 -0
- package/dist/engine/runA11yLens.d.ts +9 -0
- package/dist/engine/runA11yLens.js +158 -0
- package/dist/engine/styleResolver.d.ts +2 -0
- package/dist/engine/styleResolver.js +63 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +8 -0
- package/dist/parser/ast.d.ts +25 -0
- package/dist/parser/ast.js +169 -0
- package/dist/parser/css.d.ts +7 -0
- package/dist/parser/css.js +48 -0
- package/dist/reporters/consoleReporter.d.ts +2 -0
- package/dist/reporters/consoleReporter.js +67 -0
- package/dist/reporters/jsonReporter.d.ts +2 -0
- package/dist/reporters/jsonReporter.js +7 -0
- package/dist/reporters/sarifReporter.d.ts +2 -0
- package/dist/reporters/sarifReporter.js +95 -0
- package/dist/rules/clickableNonsemantic.d.ts +2 -0
- package/dist/rules/clickableNonsemantic.js +43 -0
- package/dist/rules/contrastRatio.d.ts +2 -0
- package/dist/rules/contrastRatio.js +149 -0
- package/dist/rules/engine.d.ts +4 -0
- package/dist/rules/engine.js +22 -0
- package/dist/rules/iconOnlyControl.d.ts +2 -0
- package/dist/rules/iconOnlyControl.js +50 -0
- package/dist/rules/imgAlt.d.ts +2 -0
- package/dist/rules/imgAlt.js +48 -0
- package/dist/rules/registry.d.ts +3 -0
- package/dist/rules/registry.js +19 -0
- package/dist/rules/routerLinkText.d.ts +2 -0
- package/dist/rules/routerLinkText.js +32 -0
- package/dist/rules/utils.d.ts +6 -0
- package/dist/rules/utils.js +51 -0
- package/dist/scanner/fileAnalyzer.d.ts +1 -0
- package/dist/scanner/fileAnalyzer.js +46 -0
- package/dist/scanner/fileSystemWalker.js +122 -0
- package/dist/scanner/fileWalker.d.ts +8 -0
- package/dist/scanner/fileWalker.js +126 -0
- package/dist/scanner/styleExtractor.d.ts +13 -0
- package/dist/scanner/styleExtractor.js +95 -0
- package/dist/scanner/templateExtractor.d.ts +13 -0
- package/dist/scanner/templateExtractor.js +101 -0
- package/dist/types/config.d.ts +9 -0
- package/dist/types/config.js +2 -0
- package/dist/types/results.d.ts +22 -0
- package/dist/types/results.js +2 -0
- package/dist/types/rules.d.ts +14 -0
- package/dist/types/rules.js +2 -0
- package/dist/types/style.d.ts +9 -0
- package/dist/types/style.js +2 -0
- package/package.json +65 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.defaultWalkOptions = exports.fileSystemWalker = void 0;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const fileSystemWalker = (rootDirs, options) => {
|
|
40
|
+
const results = [];
|
|
41
|
+
for (const root of rootDirs) {
|
|
42
|
+
if (!fs.existsSync(root))
|
|
43
|
+
continue;
|
|
44
|
+
let stat;
|
|
45
|
+
try {
|
|
46
|
+
stat = fs.statSync(root);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (!stat.isDirectory())
|
|
52
|
+
continue;
|
|
53
|
+
const resolvedPath = path.resolve(root);
|
|
54
|
+
walkDirectory(resolvedPath, options, results);
|
|
55
|
+
}
|
|
56
|
+
return results;
|
|
57
|
+
};
|
|
58
|
+
exports.fileSystemWalker = fileSystemWalker;
|
|
59
|
+
const defaultWalkOptions = (config) => ({
|
|
60
|
+
includePatterns: config.includePatterns,
|
|
61
|
+
ignoreDirs: config.ignoreDirs,
|
|
62
|
+
ignorePatterns: config.ignorePatterns
|
|
63
|
+
});
|
|
64
|
+
exports.defaultWalkOptions = defaultWalkOptions;
|
|
65
|
+
const walkDirectory = (currentDir, options, results) => {
|
|
66
|
+
if (shouldIgnorePath(currentDir, options))
|
|
67
|
+
return;
|
|
68
|
+
let entries;
|
|
69
|
+
try {
|
|
70
|
+
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
for (const entry of entries) {
|
|
76
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
77
|
+
if (entry.isDirectory()) {
|
|
78
|
+
walkDirectory(fullPath, options, results);
|
|
79
|
+
}
|
|
80
|
+
else if (entry.isFile()) {
|
|
81
|
+
if (matchesPattern(entry.name, options.includePatterns) &&
|
|
82
|
+
!shouldIgnorePath(fullPath, options)) {
|
|
83
|
+
results.push(fullPath);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const shouldIgnorePath = (p, options) => {
|
|
89
|
+
const normalized = path.resolve(p);
|
|
90
|
+
const parts = normalized.split(path.sep);
|
|
91
|
+
for (const dirName of options.ignoreDirs) {
|
|
92
|
+
if (parts.includes(dirName))
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
if (options.ignorePatterns.length > 0) {
|
|
96
|
+
const normalizedPath = normalized.replace(/\\/g, "/");
|
|
97
|
+
for (const pattern of options.ignorePatterns) {
|
|
98
|
+
if (simpleMatch(normalizedPath, pattern) || simpleMatch(path.basename(normalized), pattern)) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
};
|
|
105
|
+
const matchesPattern = (fileName, patterns) => {
|
|
106
|
+
for (const pattern of patterns) {
|
|
107
|
+
if (simpleMatch(fileName, pattern))
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
};
|
|
112
|
+
const simpleMatch = (value, pattern) => {
|
|
113
|
+
if (pattern === "*")
|
|
114
|
+
return true;
|
|
115
|
+
const starIndex = pattern.indexOf("*");
|
|
116
|
+
if (starIndex === -1) {
|
|
117
|
+
return value === pattern || value.endsWith(pattern);
|
|
118
|
+
}
|
|
119
|
+
const first = pattern.slice(0, starIndex);
|
|
120
|
+
const last = pattern.slice(starIndex + 1);
|
|
121
|
+
if (first.length > 0 && !value.startsWith(first))
|
|
122
|
+
return false;
|
|
123
|
+
if (last.length > 0 && !value.endsWith(last))
|
|
124
|
+
return false;
|
|
125
|
+
return true;
|
|
126
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Issue } from "../types/results";
|
|
2
|
+
export interface StyleSource {
|
|
3
|
+
id: string;
|
|
4
|
+
filePath: string;
|
|
5
|
+
content: string;
|
|
6
|
+
kind: "external" | "inline";
|
|
7
|
+
originFilePath: string;
|
|
8
|
+
}
|
|
9
|
+
export interface StyleExtractionResult {
|
|
10
|
+
styles: StyleSource[];
|
|
11
|
+
issues: Issue[];
|
|
12
|
+
}
|
|
13
|
+
export declare const extractStyles: (filePath: string, content: string) => StyleExtractionResult;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.extractStyles = void 0;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fileAnalyzer_1 = require("./fileAnalyzer");
|
|
39
|
+
const extractStringLiterals = (value) => {
|
|
40
|
+
const matches = [];
|
|
41
|
+
const regex = /([`'"])([\s\S]*?)\1/g;
|
|
42
|
+
let match = null;
|
|
43
|
+
while ((match = regex.exec(value)) !== null) {
|
|
44
|
+
matches.push(match[2]);
|
|
45
|
+
}
|
|
46
|
+
return matches;
|
|
47
|
+
};
|
|
48
|
+
const extractStyles = (filePath, content) => {
|
|
49
|
+
const styles = [];
|
|
50
|
+
const issues = [];
|
|
51
|
+
if (!filePath.endsWith(".component.ts")) {
|
|
52
|
+
return { styles, issues };
|
|
53
|
+
}
|
|
54
|
+
const styleUrlsMatch = content.match(/styleUrls\s*:\s*\[([\s\S]*?)\]/);
|
|
55
|
+
if (styleUrlsMatch) {
|
|
56
|
+
const paths = extractStringLiterals(styleUrlsMatch[1]);
|
|
57
|
+
for (const stylePath of paths) {
|
|
58
|
+
const resolved = path.resolve(path.dirname(filePath), stylePath);
|
|
59
|
+
const styleContent = (0, fileAnalyzer_1.readFileContent)(resolved);
|
|
60
|
+
if (!styleContent) {
|
|
61
|
+
issues.push({
|
|
62
|
+
ruleId: "style-extraction",
|
|
63
|
+
message: `Unable to read styleUrl file: ${resolved}`,
|
|
64
|
+
filePath,
|
|
65
|
+
severity: "warn"
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
styles.push({
|
|
70
|
+
id: resolved,
|
|
71
|
+
filePath: resolved,
|
|
72
|
+
content: styleContent,
|
|
73
|
+
kind: "external",
|
|
74
|
+
originFilePath: filePath
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const stylesMatch = content.match(/styles\s*:\s*\[([\s\S]*?)\]/);
|
|
79
|
+
if (stylesMatch) {
|
|
80
|
+
const inlineStyles = extractStringLiterals(stylesMatch[1]);
|
|
81
|
+
let index = 0;
|
|
82
|
+
for (const inline of inlineStyles) {
|
|
83
|
+
styles.push({
|
|
84
|
+
id: `${filePath}#inline-style-${index}`,
|
|
85
|
+
filePath,
|
|
86
|
+
content: inline,
|
|
87
|
+
kind: "inline",
|
|
88
|
+
originFilePath: filePath
|
|
89
|
+
});
|
|
90
|
+
index += 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { styles, issues };
|
|
94
|
+
};
|
|
95
|
+
exports.extractStyles = extractStyles;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Issue } from "../types/results";
|
|
2
|
+
export interface TemplateSource {
|
|
3
|
+
id: string;
|
|
4
|
+
filePath: string;
|
|
5
|
+
content: string;
|
|
6
|
+
kind: "external" | "inline";
|
|
7
|
+
originFilePath: string;
|
|
8
|
+
}
|
|
9
|
+
export interface TemplateExtractionResult {
|
|
10
|
+
templates: TemplateSource[];
|
|
11
|
+
issues: Issue[];
|
|
12
|
+
}
|
|
13
|
+
export declare const extractTemplates: (filePath: string, content: string) => TemplateExtractionResult;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.extractTemplates = void 0;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fileAnalyzer_1 = require("./fileAnalyzer");
|
|
39
|
+
const extractTemplates = (filePath, content) => {
|
|
40
|
+
const templates = [];
|
|
41
|
+
const issues = [];
|
|
42
|
+
if (filePath.endsWith(".component.html")) {
|
|
43
|
+
templates.push({
|
|
44
|
+
id: filePath,
|
|
45
|
+
filePath,
|
|
46
|
+
content,
|
|
47
|
+
kind: "external",
|
|
48
|
+
originFilePath: filePath
|
|
49
|
+
});
|
|
50
|
+
return { templates, issues };
|
|
51
|
+
}
|
|
52
|
+
if (!filePath.endsWith(".component.ts")) {
|
|
53
|
+
return { templates, issues };
|
|
54
|
+
}
|
|
55
|
+
const templateRegex = /template\s*:\s*([`'"])([\s\S]*?)\1/g;
|
|
56
|
+
let match = null;
|
|
57
|
+
let inlineIndex = 0;
|
|
58
|
+
while ((match = templateRegex.exec(content)) !== null) {
|
|
59
|
+
const inlineContent = match[2];
|
|
60
|
+
templates.push({
|
|
61
|
+
id: `${filePath}#inline-${inlineIndex}`,
|
|
62
|
+
filePath,
|
|
63
|
+
content: inlineContent,
|
|
64
|
+
kind: "inline",
|
|
65
|
+
originFilePath: filePath
|
|
66
|
+
});
|
|
67
|
+
inlineIndex += 1;
|
|
68
|
+
}
|
|
69
|
+
const templateUrlRegex = /templateUrl\s*:\s*([`'"])([^`'"]+)\1/g;
|
|
70
|
+
while ((match = templateUrlRegex.exec(content)) !== null) {
|
|
71
|
+
const templateUrl = match[2];
|
|
72
|
+
const resolved = path.resolve(path.dirname(filePath), templateUrl);
|
|
73
|
+
const externalContent = (0, fileAnalyzer_1.readFileContent)(resolved);
|
|
74
|
+
if (!externalContent) {
|
|
75
|
+
issues.push({
|
|
76
|
+
ruleId: "template-extraction",
|
|
77
|
+
message: `Unable to read templateUrl file: ${resolved}`,
|
|
78
|
+
filePath,
|
|
79
|
+
severity: "warn"
|
|
80
|
+
});
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
templates.push({
|
|
84
|
+
id: resolved,
|
|
85
|
+
filePath: resolved,
|
|
86
|
+
content: externalContent,
|
|
87
|
+
kind: "external",
|
|
88
|
+
originFilePath: filePath
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (templates.length === 0) {
|
|
92
|
+
issues.push({
|
|
93
|
+
ruleId: "template-extraction",
|
|
94
|
+
message: "No Angular templates found in component file.",
|
|
95
|
+
filePath,
|
|
96
|
+
severity: "info"
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return { templates, issues };
|
|
100
|
+
};
|
|
101
|
+
exports.extractTemplates = extractTemplates;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type OutputFormat = "console" | "json" | "sarif";
|
|
2
|
+
export interface A11yLensConfig {
|
|
3
|
+
includePatterns: string[];
|
|
4
|
+
ignoreDirs: string[];
|
|
5
|
+
ignorePatterns: string[];
|
|
6
|
+
styleFiles: string[];
|
|
7
|
+
minScore?: number;
|
|
8
|
+
}
|
|
9
|
+
export type A11yLensConfigOverrides = Partial<A11yLensConfig>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type Severity = "info" | "warn" | "error";
|
|
2
|
+
export interface Issue {
|
|
3
|
+
ruleId: string;
|
|
4
|
+
message: string;
|
|
5
|
+
filePath: string;
|
|
6
|
+
line?: number;
|
|
7
|
+
column?: number;
|
|
8
|
+
severity: Severity;
|
|
9
|
+
}
|
|
10
|
+
export interface FileScanResult {
|
|
11
|
+
filePath: string;
|
|
12
|
+
issues: Issue[];
|
|
13
|
+
}
|
|
14
|
+
export interface ProjectScanResult {
|
|
15
|
+
files: FileScanResult[];
|
|
16
|
+
score: number;
|
|
17
|
+
totals: {
|
|
18
|
+
error: number;
|
|
19
|
+
warn: number;
|
|
20
|
+
info: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Issue, Severity } from "./results";
|
|
2
|
+
import type { RootNode } from "../parser/ast";
|
|
3
|
+
import type { StyleLookup } from "./style";
|
|
4
|
+
export interface RuleContext {
|
|
5
|
+
filePath: string;
|
|
6
|
+
source: string;
|
|
7
|
+
styleLookup?: StyleLookup;
|
|
8
|
+
}
|
|
9
|
+
export interface Rule {
|
|
10
|
+
id: string;
|
|
11
|
+
description: string;
|
|
12
|
+
severity: Severity;
|
|
13
|
+
check: (ast: RootNode, context: RuleContext) => Issue[];
|
|
14
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "a11ylens",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Static accessibility scanner for Angular component templates.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"a11ylens": "dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "npm run build -- --watch",
|
|
13
|
+
"test": "npm run build",
|
|
14
|
+
"lint": "echo \"No lint configured\""
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"accessibility",
|
|
18
|
+
"a11y",
|
|
19
|
+
"scanner",
|
|
20
|
+
"audit",
|
|
21
|
+
"angular",
|
|
22
|
+
"html",
|
|
23
|
+
"static-analysis",
|
|
24
|
+
"cli"
|
|
25
|
+
],
|
|
26
|
+
"author": "Madhan Monish Jayakumar",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/madhanmonishj/a11ylens.git"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/madhanmonishj/a11ylens/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/madhanmonishj/a11ylens#readme",
|
|
35
|
+
"files": [
|
|
36
|
+
"dist/index.js",
|
|
37
|
+
"dist/index.d.ts",
|
|
38
|
+
"dist/cli/",
|
|
39
|
+
"dist/config/",
|
|
40
|
+
"dist/engine/",
|
|
41
|
+
"dist/parser/",
|
|
42
|
+
"dist/reporters/",
|
|
43
|
+
"dist/rules/",
|
|
44
|
+
"dist/scanner/",
|
|
45
|
+
"dist/types/",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE",
|
|
48
|
+
"CHANGELOG.md"
|
|
49
|
+
],
|
|
50
|
+
"types": "dist/index.d.ts",
|
|
51
|
+
"exports": {
|
|
52
|
+
".": {
|
|
53
|
+
"types": "./dist/index.d.ts",
|
|
54
|
+
"require": "./dist/index.js",
|
|
55
|
+
"default": "./dist/index.js"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/node": "^24.10.2",
|
|
63
|
+
"typescript": "^5.9.3"
|
|
64
|
+
}
|
|
65
|
+
}
|