zemdomu 1.3.15 → 1.3.17
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 +20 -4
- package/out/cli.js +22 -1
- package/out/component-analyzer.d.ts +22 -0
- package/out/component-analyzer.js +429 -74
- package/out/index.d.ts +2 -1
- package/out/index.js +5 -1
- package/out/linter.d.ts +4 -0
- package/out/linter.js +23 -0
- package/out/project-linter.d.ts +2 -0
- package/out/project-linter.js +41 -2
- package/out/rule-codes.d.ts +1 -0
- package/out/rule-codes.js +1 -0
- package/out/rules/preventZemdomuPlaceholders.d.ts +2 -0
- package/out/rules/preventZemdomuPlaceholders.js +236 -0
- package/out/rules/requireButtonText.js +282 -23
- package/out/rules/requireLabelForFormControls.js +216 -26
- package/out/rules/requireNavLinks.js +8 -2
- package/out/rules/requireSectionHeading.js +238 -18
- package/out/rules/requireTableCaption.js +91 -9
- package/out/rules/singleH1.js +85 -6
- package/out/rules/utils.d.ts +3 -0
- package/out/rules/utils.js +67 -0
- package/out/src/cli.js +22 -1
- package/out/src/component-analyzer.js +429 -74
- package/out/src/index.js +5 -1
- package/out/src/project-linter.js +38 -0
- package/out/src/rules/enforceListNesting.js +6 -44
- package/out/src/rules/preventZemdomuPlaceholders.js +236 -0
- package/out/src/rules/requireAltText.js +20 -16
- package/out/src/rules/requireHrefOnAnchors.js +16 -5
- package/out/src/rules/requireLinkText.js +41 -16
- package/out/src/rules/requireNavLinks.js +8 -2
- package/out/src/rules/singleH1.js +85 -6
- package/out/src/rules/utils.js +181 -0
- package/out/tests/button-accessibility-jsx.test.js +53 -0
- package/out/tests/cli-custom-rule.test.js +19 -0
- package/out/tests/cli-performance.test.js +35 -0
- package/out/tests/cross-list-nesting.test.js +34 -0
- package/out/tests/cross-section-heading.test.js +32 -0
- package/out/tests/crossComponent/cross-button-text.test.js +31 -0
- package/out/tests/exports-helpers.test.js +45 -0
- package/out/tests/label-form-control-jsx.test.js +29 -0
- package/out/tests/nav-links-components.test.js +27 -0
- package/out/tests/parse-error-multifile.test.js +29 -0
- package/out/tests/prevent-placeholders-jsx.test.js +34 -0
- package/out/tests/section-heading-jsx.test.js +32 -0
- package/out/tests/single-h1-returns.test.js +74 -0
- package/out/tests/vue-support.test.js +59 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,8 +109,13 @@ npx zemdomu "src/**/*.html,src/**/*.jsx"
|
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
Use `--custom` (or `-c`) to provide a path to a JavaScript or TypeScript module
|
|
112
|
-
exporting a custom rule or array of rules.
|
|
113
|
-
|
|
112
|
+
exporting a custom rule or array of rules. For safety, the CLI only accepts
|
|
113
|
+
files inside a `./custom-rules` directory (relative to your current working
|
|
114
|
+
directory). You can repeat `--custom` to load multiple rule files. Use `--cross`
|
|
115
|
+
to enable cross component analysis.
|
|
116
|
+
|
|
117
|
+
Use `--perf` to emit a JSON timing report to stdout, and `--perf-slowest` to
|
|
118
|
+
also print the slowest file and phase.
|
|
114
119
|
|
|
115
120
|
### Cross-component analysis
|
|
116
121
|
|
|
@@ -186,7 +191,11 @@ import {
|
|
|
186
191
|
visitHtml,
|
|
187
192
|
getAttr,
|
|
188
193
|
getJsxAttr,
|
|
194
|
+
getJsxAttribute,
|
|
195
|
+
getJsxAttributeState,
|
|
196
|
+
getJsxExpressionState,
|
|
189
197
|
getTag,
|
|
198
|
+
isJsxExpressionPossiblyEmpty,
|
|
190
199
|
ElementNode,
|
|
191
200
|
HtmlVisitor,
|
|
192
201
|
} from "zemdomu";
|
|
@@ -195,14 +204,21 @@ import {
|
|
|
195
204
|
`parseHtml` returns the root `ElementNode`. The `visitHtml` function performs a
|
|
196
205
|
simple depth-first traversal using an `HtmlVisitor` with optional `enter` and
|
|
197
206
|
`exit` callbacks. Utility functions like `getAttr` and `getJsxAttr` help reading
|
|
198
|
-
attributes
|
|
207
|
+
attributes. JSX helpers like `getJsxAttribute`, `getJsxAttributeState`, and
|
|
208
|
+
`getJsxExpressionState` help interpret JSX attributes and expressions, while
|
|
209
|
+
`getTag` resolves JSX element names.
|
|
199
210
|
|
|
200
211
|
Or via the CLI:
|
|
201
212
|
|
|
202
213
|
```bash
|
|
203
|
-
|
|
214
|
+
mkdir -p custom-rules
|
|
215
|
+
cp my-rule.js custom-rules/my-rule.js
|
|
216
|
+
npx zemdomu file.html --custom custom-rules/my-rule.js
|
|
217
|
+
npx zemdomu "src/**/*.{html,jsx,tsx,vue}" --perf --perf-slowest
|
|
204
218
|
```
|
|
205
219
|
|
|
220
|
+
There is a sample rule in `custom-rules/example-rule.js` you can copy and edit.
|
|
221
|
+
|
|
206
222
|
## Local development (monorepo)
|
|
207
223
|
|
|
208
224
|
From the core package:
|
package/out/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
const glob_1 = require("glob");
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const project_linter_1 = require("./project-linter");
|
|
10
|
+
const performance_diagnostics_1 = require("./performance-diagnostics");
|
|
10
11
|
const rule_codes_1 = require("./rule-codes");
|
|
11
12
|
function parsePatterns(inputs) {
|
|
12
13
|
const result = [];
|
|
@@ -26,6 +27,8 @@ async function run() {
|
|
|
26
27
|
const customRules = [];
|
|
27
28
|
let cross = false;
|
|
28
29
|
let depth;
|
|
30
|
+
let perfEnabled = false;
|
|
31
|
+
let perfSlowest = false;
|
|
29
32
|
for (let i = 0; i < args.length; i++) {
|
|
30
33
|
const arg = args[i];
|
|
31
34
|
if (arg === '--custom' || arg === '-c') {
|
|
@@ -48,6 +51,13 @@ async function run() {
|
|
|
48
51
|
else if (arg === '--cross') {
|
|
49
52
|
cross = true;
|
|
50
53
|
}
|
|
54
|
+
else if (arg === '--perf') {
|
|
55
|
+
perfEnabled = true;
|
|
56
|
+
}
|
|
57
|
+
else if (arg === '--perf-slowest') {
|
|
58
|
+
perfEnabled = true;
|
|
59
|
+
perfSlowest = true;
|
|
60
|
+
}
|
|
51
61
|
else if (arg === '--cross-depth') {
|
|
52
62
|
const val = args[++i];
|
|
53
63
|
if (!val)
|
|
@@ -71,7 +81,13 @@ async function run() {
|
|
|
71
81
|
for (const m of matches)
|
|
72
82
|
files.add(m);
|
|
73
83
|
}
|
|
74
|
-
const
|
|
84
|
+
const perf = perfEnabled ? new performance_diagnostics_1.PerformanceDiagnostics() : undefined;
|
|
85
|
+
const linter = new project_linter_1.ProjectLinter({
|
|
86
|
+
customRules,
|
|
87
|
+
crossComponentAnalysis: cross,
|
|
88
|
+
crossComponentDepth: depth,
|
|
89
|
+
perf,
|
|
90
|
+
});
|
|
75
91
|
const results = await linter.lintFiles(Array.from(files));
|
|
76
92
|
let hasIssues = false;
|
|
77
93
|
for (const [file, issues] of results.entries()) {
|
|
@@ -81,6 +97,11 @@ async function run() {
|
|
|
81
97
|
hasIssues = true;
|
|
82
98
|
}
|
|
83
99
|
}
|
|
100
|
+
if (perfEnabled && perf) {
|
|
101
|
+
process.stdout.write(perf.getAsJSON() + '\n');
|
|
102
|
+
if (perfSlowest)
|
|
103
|
+
perf.logSlowest();
|
|
104
|
+
}
|
|
84
105
|
if (hasIssues)
|
|
85
106
|
process.exit(1);
|
|
86
107
|
}
|
|
@@ -13,6 +13,9 @@ interface ComponentReference {
|
|
|
13
13
|
usageLocations: Array<{
|
|
14
14
|
line: number;
|
|
15
15
|
column: number;
|
|
16
|
+
inListDirect?: boolean;
|
|
17
|
+
inSection?: boolean;
|
|
18
|
+
renderGroup?: string;
|
|
16
19
|
}>;
|
|
17
20
|
}
|
|
18
21
|
interface HeadingInfo {
|
|
@@ -34,6 +37,19 @@ interface NavInfo {
|
|
|
34
37
|
hasLocalLink: boolean;
|
|
35
38
|
childComponents: ComponentReference[];
|
|
36
39
|
}
|
|
40
|
+
interface SectionInfo {
|
|
41
|
+
filePath: string;
|
|
42
|
+
line: number;
|
|
43
|
+
column: number;
|
|
44
|
+
hasLocalHeading: boolean;
|
|
45
|
+
childComponents: ComponentReference[];
|
|
46
|
+
}
|
|
47
|
+
interface ListItemInfo {
|
|
48
|
+
filePath: string;
|
|
49
|
+
line: number;
|
|
50
|
+
column: number;
|
|
51
|
+
nesting: 'root' | 'inList' | 'inOther';
|
|
52
|
+
}
|
|
37
53
|
interface ComponentDefinition {
|
|
38
54
|
name: string;
|
|
39
55
|
filePath: string;
|
|
@@ -43,6 +59,9 @@ interface ComponentDefinition {
|
|
|
43
59
|
ids: IdInfo[];
|
|
44
60
|
navs: NavInfo[];
|
|
45
61
|
hasLocalAnchor: boolean;
|
|
62
|
+
sections: SectionInfo[];
|
|
63
|
+
hasHeadingOutsideSection: boolean;
|
|
64
|
+
listItems: ListItemInfo[];
|
|
46
65
|
}
|
|
47
66
|
export declare class ComponentAnalyzer {
|
|
48
67
|
private componentRegistry;
|
|
@@ -80,9 +99,12 @@ export declare class ComponentAnalyzer {
|
|
|
80
99
|
private findCrossComponentDuplicateIds;
|
|
81
100
|
private collectIds;
|
|
82
101
|
private findCrossComponentNavLinks;
|
|
102
|
+
private findCrossComponentListNestingIssues;
|
|
83
103
|
private checkNavs;
|
|
84
104
|
private navHasLink;
|
|
85
105
|
private componentHasAnchor;
|
|
106
|
+
getListNestingSuppressions(): Map<string, Set<string>>;
|
|
107
|
+
getSectionHeadingSuppressions(): Map<string, Set<string>>;
|
|
86
108
|
private findEntryPoints;
|
|
87
109
|
private findComponentsWithRule;
|
|
88
110
|
}
|