qualm-a11y 1.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.
- package/README.md +201 -0
- package/RESEARCH.md +139 -0
- package/dist/analyser.d.ts +3 -0
- package/dist/analyser.d.ts.map +1 -0
- package/dist/analyser.js +77 -0
- package/dist/analyser.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +128 -0
- package/dist/cli.js.map +1 -0
- package/dist/diff.d.ts +3 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +60 -0
- package/dist/diff.js.map +1 -0
- package/dist/parser.d.ts +3 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +22 -0
- package/dist/parser.js.map +1 -0
- package/dist/reporters/json.d.ts +4 -0
- package/dist/reporters/json.d.ts.map +1 -0
- package/dist/reporters/json.js +20 -0
- package/dist/reporters/json.js.map +1 -0
- package/dist/reporters/sarif.d.ts +3 -0
- package/dist/reporters/sarif.d.ts.map +1 -0
- package/dist/reporters/sarif.js +40 -0
- package/dist/reporters/sarif.js.map +1 -0
- package/dist/reporters/terminal.d.ts +5 -0
- package/dist/reporters/terminal.d.ts.map +1 -0
- package/dist/reporters/terminal.js +83 -0
- package/dist/reporters/terminal.js.map +1 -0
- package/dist/rules/aria-correctness.d.ts +3 -0
- package/dist/rules/aria-correctness.d.ts.map +1 -0
- package/dist/rules/aria-correctness.js +52 -0
- package/dist/rules/aria-correctness.js.map +1 -0
- package/dist/rules/complexity.d.ts +4 -0
- package/dist/rules/complexity.d.ts.map +1 -0
- package/dist/rules/complexity.js +86 -0
- package/dist/rules/complexity.js.map +1 -0
- package/dist/rules/document-structure.d.ts +3 -0
- package/dist/rules/document-structure.d.ts.map +1 -0
- package/dist/rules/document-structure.js +51 -0
- package/dist/rules/document-structure.js.map +1 -0
- package/dist/rules/form-semantics.d.ts +3 -0
- package/dist/rules/form-semantics.d.ts.map +1 -0
- package/dist/rules/form-semantics.js +105 -0
- package/dist/rules/form-semantics.js.map +1 -0
- package/dist/rules/heading-hierarchy.d.ts +3 -0
- package/dist/rules/heading-hierarchy.d.ts.map +1 -0
- package/dist/rules/heading-hierarchy.js +37 -0
- package/dist/rules/heading-hierarchy.js.map +1 -0
- package/dist/rules/index.d.ts +4 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +20 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/interactive-semantics.d.ts +3 -0
- package/dist/rules/interactive-semantics.d.ts.map +1 -0
- package/dist/rules/interactive-semantics.js +65 -0
- package/dist/rules/interactive-semantics.js.map +1 -0
- package/dist/rules/landmark-structure.d.ts +3 -0
- package/dist/rules/landmark-structure.d.ts.map +1 -0
- package/dist/rules/landmark-structure.js +60 -0
- package/dist/rules/landmark-structure.js.map +1 -0
- package/dist/types.d.ts +73 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +37 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGpD,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,OAAO,CAmB/E"}
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTSX = parseTSX;
|
|
4
|
+
const typescript_estree_1 = require("@typescript-eslint/typescript-estree");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
function parseTSX(sourceCode, filePath) {
|
|
7
|
+
try {
|
|
8
|
+
return (0, typescript_estree_1.parse)(sourceCode, {
|
|
9
|
+
jsx: true,
|
|
10
|
+
loc: true,
|
|
11
|
+
range: true,
|
|
12
|
+
tokens: false,
|
|
13
|
+
comment: false,
|
|
14
|
+
errorOnUnknownASTType: false,
|
|
15
|
+
filePath,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
throw new types_1.QualmParserError(`Failed to parse ${filePath}: ${err.message}`, err.lineNumber ?? 0, err.column ?? 0, filePath);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":";;AAIA,4BAmBC;AAvBD,4EAA6D;AAE7D,mCAA2C;AAE3C,SAAgB,QAAQ,CAAC,UAAkB,EAAE,QAAgB;IAC3D,IAAI,CAAC;QACH,OAAO,IAAA,yBAAK,EAAC,UAAU,EAAE;YACvB,GAAG,EAAE,IAAI;YACT,GAAG,EAAE,IAAI;YACT,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,KAAK;YACd,qBAAqB,EAAE,KAAK;YAC5B,QAAQ;SACT,CAAqB,CAAC;IACzB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,wBAAgB,CACxB,mBAAmB,QAAQ,KAAK,GAAG,CAAC,OAAO,EAAE,EAC7C,GAAG,CAAC,UAAU,IAAI,CAAC,EACnB,GAAG,CAAC,MAAM,IAAI,CAAC,EACf,QAAQ,CACT,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/reporters/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE1D,wBAAgB,UAAU,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAWhE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEvD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderJSON = renderJSON;
|
|
4
|
+
exports.renderDiffJSON = renderDiffJSON;
|
|
5
|
+
function renderJSON(results) {
|
|
6
|
+
return JSON.stringify({
|
|
7
|
+
summary: {
|
|
8
|
+
scannedFiles: results.length,
|
|
9
|
+
totalViolations: results.reduce((a, r) => a + r.violations.length, 0),
|
|
10
|
+
globalSemanticScore: results.length > 0
|
|
11
|
+
? results.reduce((a, r) => a + r.semanticScore, 0) / results.length
|
|
12
|
+
: 1.0
|
|
13
|
+
},
|
|
14
|
+
results
|
|
15
|
+
}, null, 2);
|
|
16
|
+
}
|
|
17
|
+
function renderDiffJSON(diff) {
|
|
18
|
+
return JSON.stringify(diff, null, 2);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/reporters/json.ts"],"names":[],"mappings":";;AAEA,gCAWC;AAED,wCAEC;AAfD,SAAgB,UAAU,CAAC,OAA6B;IACtD,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,OAAO,EAAE;YACP,YAAY,EAAE,OAAO,CAAC,MAAM;YAC5B,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YACrE,mBAAmB,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC;gBACrC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM;gBACnE,CAAC,CAAC,GAAG;SACR;QACD,OAAO;KACR,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACd,CAAC;AAED,SAAgB,cAAc,CAAC,IAAgB;IAC7C,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../../src/reporters/sarif.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAqCjE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderSARIF = renderSARIF;
|
|
4
|
+
const index_1 = require("../rules/index");
|
|
5
|
+
function renderSARIF(results) {
|
|
6
|
+
const sarif = {
|
|
7
|
+
$schema: 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json',
|
|
8
|
+
version: '2.1.0',
|
|
9
|
+
runs: [{
|
|
10
|
+
tool: {
|
|
11
|
+
driver: {
|
|
12
|
+
name: 'qualm',
|
|
13
|
+
version: '1.0.0',
|
|
14
|
+
informationUri: 'https://doi.org/10.5281/zenodo.20482307',
|
|
15
|
+
rules: index_1.activeRules.map(r => ({
|
|
16
|
+
id: r.id,
|
|
17
|
+
shortDescription: { text: r.meta.description },
|
|
18
|
+
helpUri: r.meta.docsUrl ?? 'https://doi.org/10.5281/zenodo.20482307'
|
|
19
|
+
}))
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
results: results.flatMap(result => result.violations.map(v => ({
|
|
23
|
+
ruleId: v.ruleId,
|
|
24
|
+
level: v.severity === 'error' ? 'error' : v.severity === 'warning' ? 'warning' : 'note',
|
|
25
|
+
message: { text: v.message },
|
|
26
|
+
locations: [{
|
|
27
|
+
physicalLocation: {
|
|
28
|
+
artifactLocation: { uri: result.filePath },
|
|
29
|
+
region: {
|
|
30
|
+
startLine: v.location.line,
|
|
31
|
+
startColumn: v.location.column + 1
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}]
|
|
35
|
+
})))
|
|
36
|
+
}]
|
|
37
|
+
};
|
|
38
|
+
return JSON.stringify(sarif, null, 2);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=sarif.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.js","sourceRoot":"","sources":["../../src/reporters/sarif.ts"],"names":[],"mappings":";;AAGA,kCAqCC;AAvCD,0CAA6C;AAE7C,SAAgB,WAAW,CAAC,OAA6B;IACvD,MAAM,KAAK,GAAG;QACZ,OAAO,EAAE,gGAAgG;QACzG,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,CAAC;gBACL,IAAI,EAAE;oBACJ,MAAM,EAAE;wBACN,IAAI,EAAE,OAAO;wBACb,OAAO,EAAE,OAAO;wBAChB,cAAc,EAAE,yCAAyC;wBACzD,KAAK,EAAE,mBAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;4BAC3B,EAAE,EAAE,CAAC,CAAC,EAAE;4BACR,gBAAgB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;4BAC9C,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,yCAAyC;yBACrE,CAAC,CAAC;qBACJ;iBACF;gBACD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAChC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,KAAK,EAAE,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;oBACvF,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;oBAC5B,SAAS,EAAE,CAAC;4BACV,gBAAgB,EAAE;gCAChB,gBAAgB,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE;gCAC1C,MAAM,EAAE;oCACN,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;oCAC1B,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;iCACnC;6BACF;yBACF,CAAC;iBACH,CAAC,CAAC,CACJ;aACF,CAAC;KACH,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { FileAnalysisResult, DiffResult } from '../types';
|
|
2
|
+
export declare function renderTerminal(results: FileAnalysisResult[]): void;
|
|
3
|
+
export declare function renderDiffTerminal(diff: DiffResult): void;
|
|
4
|
+
export declare function renderResearchMode(results: FileAnalysisResult[]): void;
|
|
5
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/reporters/terminal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAA8C,MAAM,UAAU,CAAC;AAEtG,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,IAAI,CA+BlE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAqBzD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAiCtE"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.renderTerminal = renderTerminal;
|
|
7
|
+
exports.renderDiffTerminal = renderDiffTerminal;
|
|
8
|
+
exports.renderResearchMode = renderResearchMode;
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const types_1 = require("../types");
|
|
11
|
+
function renderTerminal(results) {
|
|
12
|
+
const totalViolations = results.reduce((a, r) => a + r.violations.length, 0);
|
|
13
|
+
const avgScore = results.length > 0
|
|
14
|
+
? results.reduce((a, r) => a + r.semanticScore, 0) / results.length
|
|
15
|
+
: 1.0;
|
|
16
|
+
console.log(chalk_1.default.bold.cyan('\n qualm — Static Quality Analysis\n'));
|
|
17
|
+
console.log(`Scanned ${chalk_1.default.bold(String(results.length))} file(s) · ${chalk_1.default.bold(String(totalViolations))} violation(s) found\n`);
|
|
18
|
+
for (const result of results) {
|
|
19
|
+
if (result.violations.length === 0) {
|
|
20
|
+
console.log(chalk_1.default.green(`✓ ${result.filePath}`));
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
console.log(chalk_1.default.bold.white(`\n${result.filePath}`));
|
|
24
|
+
for (const v of result.violations) {
|
|
25
|
+
const icon = v.severity === 'error' ? chalk_1.default.red('✗') : chalk_1.default.yellow('⚠');
|
|
26
|
+
const loc = chalk_1.default.dim(`[${v.location.line}:${v.location.column}]`);
|
|
27
|
+
const cat = chalk_1.default.dim(`[${v.category}]`);
|
|
28
|
+
const sev = v.severity === 'error' ? chalk_1.default.red(v.severity) : chalk_1.default.yellow(v.severity);
|
|
29
|
+
console.log(` ${icon} ${loc} ${cat} ${sev}: ${v.message}`);
|
|
30
|
+
console.log(` ${chalk_1.default.cyan('→')} ${v.fixSuggestion}`);
|
|
31
|
+
if (v.snippet)
|
|
32
|
+
console.log(` ${chalk_1.default.dim(v.snippet.trim().slice(0, 120))}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
console.log(chalk_1.default.bold('\n📊 Summary — Sharma (2026) Taxonomy'));
|
|
36
|
+
console.log('─'.repeat(60));
|
|
37
|
+
console.log(`Mean Semantic Score : ${chalk_1.default.bold(avgScore.toFixed(4))} ${chalk_1.default.dim('(paper baseline: treated-pre=0.989, treated-post=0.983)')}`);
|
|
38
|
+
}
|
|
39
|
+
function renderDiffTerminal(diff) {
|
|
40
|
+
const icon = diff.regressionDetected
|
|
41
|
+
? chalk_1.default.red('REGRESSION DETECTED')
|
|
42
|
+
: chalk_1.default.green('✓ No regression');
|
|
43
|
+
console.log(`\n${icon} · ${diff.filePath}`);
|
|
44
|
+
console.log(` Semantic Score: ${diff.before?.semanticScore.toFixed(4) ?? 'N/A'} → ${diff.after.semanticScore.toFixed(4)} (Δ ${diff.deltaSemanticScore.toFixed(4)})`);
|
|
45
|
+
console.log(` Violations: ${diff.before?.violationsCount ?? 0} → ${diff.after.violationsCount}`);
|
|
46
|
+
if (diff.addedViolations.length > 0) {
|
|
47
|
+
console.log(chalk_1.default.red(`\n Added violations (${diff.addedViolations.length}):`));
|
|
48
|
+
for (const v of diff.addedViolations) {
|
|
49
|
+
console.log(` + [${v.category}] ${v.message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (diff.removedViolations.length > 0) {
|
|
53
|
+
console.log(chalk_1.default.green(`\n Removed violations (${diff.removedViolations.length}):`));
|
|
54
|
+
for (const v of diff.removedViolations) {
|
|
55
|
+
console.log(` - [${v.category}] ${v.message}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function renderResearchMode(results) {
|
|
60
|
+
console.log(chalk_1.default.bold.cyan('\nqualm Research Mode — Sharma (2026) Taxonomy\n'));
|
|
61
|
+
console.log('─'.repeat(80));
|
|
62
|
+
console.log(`${'Category'.padEnd(28)} | ${'Violations'.padEnd(12)} | ${'β (paper)'.padEnd(12)} | Weighted Score`);
|
|
63
|
+
console.log('─'.repeat(80));
|
|
64
|
+
const allViolations = results.flatMap(r => r.violations);
|
|
65
|
+
const totalBeta = Object.values(types_1.PAPER_BETA_COEFFICIENTS).reduce((a, b) => a + b, 0);
|
|
66
|
+
let compositeScore = 0;
|
|
67
|
+
for (const [category, beta] of Object.entries(types_1.PAPER_BETA_COEFFICIENTS)) {
|
|
68
|
+
const count = allViolations.filter(v => v.category === category).length;
|
|
69
|
+
const weight = beta / totalBeta;
|
|
70
|
+
const weighted = weight * count * 0.05;
|
|
71
|
+
compositeScore += weighted;
|
|
72
|
+
const betaStr = (beta >= 0 ? '+' : '') + beta.toFixed(3);
|
|
73
|
+
console.log(`${category.padEnd(28)} | ${String(count).padEnd(12)} | ${betaStr.padEnd(12)} | ${weighted.toFixed(4)}`);
|
|
74
|
+
}
|
|
75
|
+
console.log('─'.repeat(80));
|
|
76
|
+
const avgBaseline = results.length > 0
|
|
77
|
+
? results.reduce((a, r) => a + r.semanticScore, 0) / results.length
|
|
78
|
+
: 1.0;
|
|
79
|
+
console.log(`${'Composite Regression Score'.padEnd(28)} | ${compositeScore.toFixed(4).padEnd(12)} | ${'Baseline'.padEnd(12)} | ${avgBaseline.toFixed(4)}`);
|
|
80
|
+
console.log('─'.repeat(80));
|
|
81
|
+
console.log(chalk_1.default.dim('Paper baseline (Table A1): treated-pre AST score = 0.989, treated-post = 0.983'));
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/reporters/terminal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aria-correctness.d.ts","sourceRoot":"","sources":["../../src/rules/aria-correctness.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAWhC,eAAO,MAAM,mBAAmB,EAAE,IA4CjC,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ariaCorrectnessRule = void 0;
|
|
4
|
+
const BOOLEAN_ARIA_ATTRS = new Set([
|
|
5
|
+
'aria-expanded', 'aria-hidden', 'aria-checked', 'aria-selected',
|
|
6
|
+
'aria-pressed', 'aria-disabled', 'aria-invalid', 'aria-required',
|
|
7
|
+
'aria-multiselectable', 'aria-readonly', 'aria-busy', 'aria-modal',
|
|
8
|
+
'aria-atomic', 'aria-grabbed'
|
|
9
|
+
]);
|
|
10
|
+
const VALID_BOOLEAN_VALUES = new Set(['true', 'false']);
|
|
11
|
+
exports.ariaCorrectnessRule = {
|
|
12
|
+
id: 'aria-correctness',
|
|
13
|
+
category: 'aria_correctness',
|
|
14
|
+
severity: 'error',
|
|
15
|
+
meta: {
|
|
16
|
+
description: 'Enforce valid ARIA attribute values per WAI-ARIA specification'
|
|
17
|
+
},
|
|
18
|
+
create(context) {
|
|
19
|
+
return {
|
|
20
|
+
JSXAttribute(node) {
|
|
21
|
+
const attrName = node.name.type === 'JSXIdentifier' ? node.name.name : null;
|
|
22
|
+
if (!attrName || !attrName.startsWith('aria-'))
|
|
23
|
+
return;
|
|
24
|
+
if (!BOOLEAN_ARIA_ATTRS.has(attrName))
|
|
25
|
+
return;
|
|
26
|
+
// Bare boolean attribute (e.g. aria-disabled with no value) is invalid —
|
|
27
|
+
// WAI-ARIA requires an explicit "true" or "false" string.
|
|
28
|
+
if (!node.value) {
|
|
29
|
+
context.report({
|
|
30
|
+
message: `${attrName} used as a bare boolean attribute. WAI-ARIA requires an explicit string value: "true" or "false".`,
|
|
31
|
+
fixSuggestion: `Change to ${attrName}="true" to make the intent explicit and ensure assistive technology reads it correctly.`,
|
|
32
|
+
location: context.getLoc(node),
|
|
33
|
+
snippet: context.getSourceCode(node)
|
|
34
|
+
});
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (node.value.type === 'Literal' &&
|
|
38
|
+
typeof node.value.value === 'string') {
|
|
39
|
+
if (!VALID_BOOLEAN_VALUES.has(node.value.value)) {
|
|
40
|
+
context.report({
|
|
41
|
+
message: `Invalid value "${node.value.value}" for ${attrName}. Boolean ARIA attributes only accept "true" or "false".`,
|
|
42
|
+
fixSuggestion: `Change to ${attrName}="true" or ${attrName}="false", or use a dynamic expression like ${attrName}={isOpen ? "true" : "false"}.`,
|
|
43
|
+
location: context.getLoc(node),
|
|
44
|
+
snippet: context.getSourceCode(node)
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=aria-correctness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aria-correctness.js","sourceRoot":"","sources":["../../src/rules/aria-correctness.ts"],"names":[],"mappings":";;;AAGA,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;IACjC,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe;IAC/D,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe;IAChE,sBAAsB,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY;IAClE,aAAa,EAAE,cAAc;CAC9B,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3C,QAAA,mBAAmB,GAAS;IACvC,EAAE,EAAE,kBAAkB;IACtB,QAAQ,EAAE,kBAAkB;IAC5B,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE;QACJ,WAAW,EAAE,gEAAgE;KAC9E;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,YAAY,CAAC,IAA2B;gBACtC,MAAM,QAAQ,GACZ,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC7D,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;oBAAE,OAAO;gBAEvD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC;oBAAE,OAAO;gBAE9C,yEAAyE;gBACzE,0DAA0D;gBAC1D,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;oBAChB,OAAO,CAAC,MAAM,CAAC;wBACb,OAAO,EAAE,GAAG,QAAQ,mGAAmG;wBACvH,aAAa,EAAE,aAAa,QAAQ,yFAAyF;wBAC7H,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;wBAC9B,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC;qBACrC,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBAED,IACE,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;oBAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EACpC,CAAC;oBACD,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;wBAChD,OAAO,CAAC,MAAM,CAAC;4BACb,OAAO,EAAE,kBAAkB,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,QAAQ,0DAA0D;4BACtH,aAAa,EAAE,aAAa,QAAQ,cAAc,QAAQ,8CAA8C,QAAQ,+BAA+B;4BAC/I,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;4BAC9B,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC;yBACrC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complexity.d.ts","sourceRoot":"","sources":["../../src/rules/complexity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAmC7C,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,QAAQ,CAAC,OAAO,EACrB,UAAU,EAAE,MAAM,GACjB,iBAAiB,CAwDnB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateComplexityMetrics = calculateComplexityMetrics;
|
|
4
|
+
const typescript_estree_1 = require("@typescript-eslint/typescript-estree");
|
|
5
|
+
const CYCLOMATIC_NODES = new Set([
|
|
6
|
+
'IfStatement', 'ConditionalExpression', 'SwitchCase',
|
|
7
|
+
'ForStatement', 'ForInStatement', 'ForOfStatement',
|
|
8
|
+
'WhileStatement', 'DoWhileStatement', 'LogicalExpression',
|
|
9
|
+
'CatchClause'
|
|
10
|
+
]);
|
|
11
|
+
// Recursively compute max JSX nesting depth
|
|
12
|
+
function jsxDepth(node) {
|
|
13
|
+
if (node.type === 'JSXElement') {
|
|
14
|
+
const childDepths = node.children.map(c => jsxDepth(c));
|
|
15
|
+
return 1 + (childDepths.length > 0 ? Math.max(...childDepths) : 0);
|
|
16
|
+
}
|
|
17
|
+
let max = 0;
|
|
18
|
+
for (const key of Object.keys(node)) {
|
|
19
|
+
const child = node[key];
|
|
20
|
+
if (child && typeof child === 'object') {
|
|
21
|
+
if (Array.isArray(child)) {
|
|
22
|
+
for (const item of child) {
|
|
23
|
+
if (item && typeof item === 'object' && 'type' in item) {
|
|
24
|
+
const d = jsxDepth(item);
|
|
25
|
+
if (d > max)
|
|
26
|
+
max = d;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else if ('type' in child) {
|
|
31
|
+
const d = jsxDepth(child);
|
|
32
|
+
if (d > max)
|
|
33
|
+
max = d;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return max;
|
|
38
|
+
}
|
|
39
|
+
function calculateComplexityMetrics(ast, sourceCode) {
|
|
40
|
+
let cyclomaticComplexity = 1;
|
|
41
|
+
let cognitiveComplexity = 0;
|
|
42
|
+
let nestingDepth = 0;
|
|
43
|
+
let nodeCount = 0;
|
|
44
|
+
let propsCount = 0;
|
|
45
|
+
// Track nesting via parent stack — simpleTraverse is enter-only, so we
|
|
46
|
+
// increment nesting when entering control flow nodes and use node.range
|
|
47
|
+
// to determine when we've "exited" them.
|
|
48
|
+
// Simpler: count nesting depth by tracking enter-only and resetting on
|
|
49
|
+
// function/component boundaries.
|
|
50
|
+
const nestingStack = [];
|
|
51
|
+
(0, typescript_estree_1.simpleTraverse)(ast, {
|
|
52
|
+
enter(node) {
|
|
53
|
+
nodeCount++;
|
|
54
|
+
if (CYCLOMATIC_NODES.has(node.type)) {
|
|
55
|
+
cyclomaticComplexity++;
|
|
56
|
+
}
|
|
57
|
+
// Cognitive complexity: add (1 + current nesting level) for control flow
|
|
58
|
+
if (node.type === 'IfStatement' ||
|
|
59
|
+
node.type === 'ForStatement' ||
|
|
60
|
+
node.type === 'WhileStatement' ||
|
|
61
|
+
node.type === 'ForOfStatement' ||
|
|
62
|
+
node.type === 'ForInStatement' ||
|
|
63
|
+
node.type === 'DoWhileStatement') {
|
|
64
|
+
cognitiveComplexity += 1 + nestingStack.length;
|
|
65
|
+
nestingStack.push(node.type);
|
|
66
|
+
}
|
|
67
|
+
if (node.type === 'JSXAttribute') {
|
|
68
|
+
propsCount++;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
const linesOfCode = sourceCode.split('\n').length;
|
|
73
|
+
// Compute max JSX nesting depth via recursive walk
|
|
74
|
+
const maxJsxNestingDepth = jsxDepth(ast);
|
|
75
|
+
const propDrillingDepth = Math.max(0, maxJsxNestingDepth - 3);
|
|
76
|
+
return {
|
|
77
|
+
cyclomaticComplexity,
|
|
78
|
+
cognitiveComplexity,
|
|
79
|
+
maxJsxNestingDepth,
|
|
80
|
+
linesOfCode,
|
|
81
|
+
nodeCount,
|
|
82
|
+
propsCount,
|
|
83
|
+
propDrillingDepth
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=complexity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complexity.js","sourceRoot":"","sources":["../../src/rules/complexity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-structure.d.ts","sourceRoot":"","sources":["../../src/rules/document-structure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAOhC,eAAO,MAAM,qBAAqB,EAAE,IA4CnC,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.documentStructureRule = void 0;
|
|
4
|
+
const INTERACTIVE_EVENT_HANDLERS = new Set([
|
|
5
|
+
'onClick', 'onKeyDown', 'onKeyUp', 'onKeyPress',
|
|
6
|
+
'onFocus', 'onBlur', 'onMouseDown', 'onMouseUp'
|
|
7
|
+
]);
|
|
8
|
+
exports.documentStructureRule = {
|
|
9
|
+
id: 'document-structure',
|
|
10
|
+
category: 'document_structure',
|
|
11
|
+
severity: 'error',
|
|
12
|
+
meta: {
|
|
13
|
+
description: 'Enforce semantic HTML elements over generic containers with interactive handlers',
|
|
14
|
+
docsUrl: 'https://doi.org/10.5281/zenodo.20482307'
|
|
15
|
+
},
|
|
16
|
+
create(context) {
|
|
17
|
+
return {
|
|
18
|
+
JSXOpeningElement(node) {
|
|
19
|
+
const elementName = node.name.type === 'JSXIdentifier' ? node.name.name : null;
|
|
20
|
+
if (!elementName)
|
|
21
|
+
return;
|
|
22
|
+
if (elementName !== 'div' && elementName !== 'span')
|
|
23
|
+
return;
|
|
24
|
+
const attrs = node.attributes;
|
|
25
|
+
const hasInteractiveHandler = attrs.some(attr => {
|
|
26
|
+
if (attr.type !== 'JSXAttribute')
|
|
27
|
+
return false;
|
|
28
|
+
const name = attr.name.type === 'JSXIdentifier' ? attr.name.name : null;
|
|
29
|
+
return name !== null && INTERACTIVE_EVENT_HANDLERS.has(name);
|
|
30
|
+
});
|
|
31
|
+
if (!hasInteractiveHandler)
|
|
32
|
+
return;
|
|
33
|
+
const hasRoleAttr = attrs.some(attr => {
|
|
34
|
+
if (attr.type !== 'JSXAttribute')
|
|
35
|
+
return false;
|
|
36
|
+
const name = attr.name.type === 'JSXIdentifier' ? attr.name.name : null;
|
|
37
|
+
return name === 'role';
|
|
38
|
+
});
|
|
39
|
+
if (hasRoleAttr)
|
|
40
|
+
return;
|
|
41
|
+
context.report({
|
|
42
|
+
message: `Generic <${elementName}> element has interactive event handler without semantic element or explicit role. This is the dominant AI-generated code quality failure mode identified in Sharma (2026).`,
|
|
43
|
+
fixSuggestion: `Replace <${elementName}> with a semantic element like <button> for click handlers, or add role="button" with tabIndex={0} as a minimum. Prefer semantic HTML over role overrides.`,
|
|
44
|
+
location: context.getLoc(node),
|
|
45
|
+
snippet: context.getSourceCode(node)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=document-structure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-structure.js","sourceRoot":"","sources":["../../src/rules/document-structure.ts"],"names":[],"mappings":";;;AAGA,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC;IACzC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY;IAC/C,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW;CAChD,CAAC,CAAC;AAEU,QAAA,qBAAqB,GAAS;IACzC,EAAE,EAAE,oBAAoB;IACxB,QAAQ,EAAE,oBAAoB;IAC9B,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE;QACJ,WAAW,EAAE,kFAAkF;QAC/F,OAAO,EAAE,yCAAyC;KACnD;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,iBAAiB,CAAC,IAAgC;gBAChD,MAAM,WAAW,GACf,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAE7D,IAAI,CAAC,WAAW;oBAAE,OAAO;gBACzB,IAAI,WAAW,KAAK,KAAK,IAAI,WAAW,KAAK,MAAM;oBAAE,OAAO;gBAE5D,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;gBAE9B,MAAM,qBAAqB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;oBAC9C,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc;wBAAE,OAAO,KAAK,CAAC;oBAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;oBACxE,OAAO,IAAI,KAAK,IAAI,IAAI,0BAA0B,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC/D,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,qBAAqB;oBAAE,OAAO;gBAEnC,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;oBACpC,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc;wBAAE,OAAO,KAAK,CAAC;oBAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;oBACxE,OAAO,IAAI,KAAK,MAAM,CAAC;gBACzB,CAAC,CAAC,CAAC;gBAEH,IAAI,WAAW;oBAAE,OAAO;gBAExB,OAAO,CAAC,MAAM,CAAC;oBACb,OAAO,EAAE,YAAY,WAAW,6KAA6K;oBAC7M,aAAa,EAAE,YAAY,WAAW,4JAA4J;oBAClM,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;oBAC9B,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC;iBACrC,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-semantics.d.ts","sourceRoot":"","sources":["../../src/rules/form-semantics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAoBhC,eAAO,MAAM,iBAAiB,EAAE,IA8F/B,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formSemanticsRule = void 0;
|
|
4
|
+
const FORM_CONTROLS = new Set(['input', 'select', 'textarea']);
|
|
5
|
+
// Walk up the parent chain to detect implicit label wrapping.
|
|
6
|
+
// simpleTraverse doesn't set parent pointers, so we track the JSXElement
|
|
7
|
+
// ancestor stack ourselves via JSXElement enter/exit using a set of range starts.
|
|
8
|
+
function isInsideLabelElement(node, labelRanges) {
|
|
9
|
+
// We stored range[0] of every open <label> JSXElement that is currently open
|
|
10
|
+
// on the stack. If any open label's range contains this node's range, it's wrapped.
|
|
11
|
+
// Since simpleTraverse is single-pass enter-only in our analyser context, we
|
|
12
|
+
// instead record all label JSXElement ranges and check containment by range.
|
|
13
|
+
for (const labelStart of labelRanges) {
|
|
14
|
+
if (node.range && node.range[0] > labelStart) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
exports.formSemanticsRule = {
|
|
21
|
+
id: 'form-semantics',
|
|
22
|
+
category: 'form_semantics',
|
|
23
|
+
severity: 'error',
|
|
24
|
+
meta: {
|
|
25
|
+
description: 'Ensure form controls have associated label elements'
|
|
26
|
+
},
|
|
27
|
+
create(context) {
|
|
28
|
+
const labelHtmlFors = new Set();
|
|
29
|
+
const inputsWithIds = [];
|
|
30
|
+
// Track range[0] of every <label> JSXElement opening tag seen in the file.
|
|
31
|
+
// Used to detect implicit label wrapping (input inside <label>...</label>).
|
|
32
|
+
const labelElementRanges = [];
|
|
33
|
+
return {
|
|
34
|
+
JSXElement(node) {
|
|
35
|
+
const openingName = node.openingElement.name.type === 'JSXIdentifier'
|
|
36
|
+
? node.openingElement.name.name : null;
|
|
37
|
+
if (openingName === 'label' && node.range) {
|
|
38
|
+
labelElementRanges.push({ start: node.range[0], end: node.range[1] });
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
JSXAttribute(node) {
|
|
42
|
+
const attrName = node.name.type === 'JSXIdentifier' ? node.name.name : null;
|
|
43
|
+
if (attrName !== 'htmlFor')
|
|
44
|
+
return;
|
|
45
|
+
if (node.value?.type === 'Literal' &&
|
|
46
|
+
typeof node.value.value === 'string') {
|
|
47
|
+
labelHtmlFors.add(node.value.value);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
JSXOpeningElement(node) {
|
|
51
|
+
const name = node.name.type === 'JSXIdentifier' ? node.name.name : null;
|
|
52
|
+
if (!name || !FORM_CONTROLS.has(name))
|
|
53
|
+
return;
|
|
54
|
+
const hasAriaLabel = node.attributes.some(attr => {
|
|
55
|
+
if (attr.type !== 'JSXAttribute')
|
|
56
|
+
return false;
|
|
57
|
+
const n = attr.name.type === 'JSXIdentifier' ? attr.name.name : null;
|
|
58
|
+
return n === 'aria-label' || n === 'aria-labelledby';
|
|
59
|
+
});
|
|
60
|
+
if (hasAriaLabel)
|
|
61
|
+
return;
|
|
62
|
+
// Implicit label: input is wrapped inside a <label> element
|
|
63
|
+
const isImplicitlyLabelled = node.range
|
|
64
|
+
? labelElementRanges.some(l => node.range[0] > l.start && node.range[0] < l.end)
|
|
65
|
+
: false;
|
|
66
|
+
if (isImplicitlyLabelled)
|
|
67
|
+
return;
|
|
68
|
+
const idAttr = node.attributes.find(attr => {
|
|
69
|
+
if (attr.type !== 'JSXAttribute')
|
|
70
|
+
return false;
|
|
71
|
+
return attr.name.type === 'JSXIdentifier' && attr.name.name === 'id';
|
|
72
|
+
});
|
|
73
|
+
const idValue = idAttr?.value?.type === 'Literal' &&
|
|
74
|
+
typeof idAttr.value.value === 'string'
|
|
75
|
+
? idAttr.value.value
|
|
76
|
+
: null;
|
|
77
|
+
if (idValue) {
|
|
78
|
+
inputsWithIds.push({ id: idValue, node });
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
context.report({
|
|
82
|
+
message: `<${name}> has no associated label. Add a <label htmlFor="..."> or aria-label attribute.`,
|
|
83
|
+
fixSuggestion: `Add an id to the <${name}> and a matching <label htmlFor="id"> element, or use aria-label="Description".`,
|
|
84
|
+
location: context.getLoc(node),
|
|
85
|
+
snippet: context.getSourceCode(node)
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
'Program:exit'() {
|
|
90
|
+
for (const { id, node } of inputsWithIds) {
|
|
91
|
+
if (!labelHtmlFors.has(id)) {
|
|
92
|
+
const name = node.name.type === 'JSXIdentifier' ? node.name.name : 'input';
|
|
93
|
+
context.report({
|
|
94
|
+
message: `<${name} id="${id}"> has no associated <label htmlFor="${id}">. Form controls must be programmatically associated with labels.`,
|
|
95
|
+
fixSuggestion: `Add <label htmlFor="${id}">Label text</label> before or after the form control.`,
|
|
96
|
+
location: context.getLoc(node),
|
|
97
|
+
snippet: context.getSourceCode(node)
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=form-semantics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-semantics.js","sourceRoot":"","sources":["../../src/rules/form-semantics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heading-hierarchy.d.ts","sourceRoot":"","sources":["../../src/rules/heading-hierarchy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAIhC,eAAO,MAAM,oBAAoB,EAAE,IAkClC,CAAC"}
|