zemdomu 1.0.1 โ 1.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/README.md +112 -112
- package/out/index.js +3 -1
- package/out/project-linter.js +87 -0
- package/package.json +34 -34
package/README.md
CHANGED
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
ZemDomu
|
|
2
|
-
|
|
3
|
-
Semantic HTML linting engine for clean, accessible, and SEO-friendly markup. This package provides the shared core logic used by the ZemDomu VS Code extension and upcoming GitHub Action.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
๐ง What is ZemDomu Core?
|
|
8
|
-
|
|
9
|
-
ZemDomu is a semantic-first linter that helps developers write better HTML and JSX by catching accessibility and structural issues. This package contains the framework-agnostic linting engine used by other tools in the ZemDomu ecosystem.
|
|
10
|
-
|
|
11
|
-
It parses .html, .jsx, and .tsx content and exposes a simple lint() function that returns semantic violations.
|
|
12
|
-
|
|
13
|
-
๐ Installation
|
|
14
|
-
|
|
15
|
-
npm install zemdomu
|
|
16
|
-
# or
|
|
17
|
-
yarn add zemdomu
|
|
18
|
-
|
|
19
|
-
โจ Features
|
|
20
|
-
|
|
21
|
-
โ
Lint semantic issues in HTML, JSX, and TSX
|
|
22
|
-
|
|
23
|
-
๐ฆ Works in Node.js, CI, or any JS runtime
|
|
24
|
-
|
|
25
|
-
โ๏ธ Extensible rule system
|
|
26
|
-
|
|
27
|
-
๐ Shared by extension and GitHub Action
|
|
28
|
-
|
|
29
|
-
๐งช Simple API: lint(content, options)
|
|
30
|
-
|
|
31
|
-
โ๏ธ Usage Example
|
|
32
|
-
|
|
33
|
-
import { lint } from 'zemdomu';
|
|
34
|
-
|
|
35
|
-
const html = '<img>';
|
|
36
|
-
const results = lint(html, { rules: { requireAltText: true } });
|
|
37
|
-
|
|
38
|
-
console.log(results);
|
|
39
|
-
// [
|
|
40
|
-
// {
|
|
41
|
-
// line: 0,
|
|
42
|
-
// column: 0,
|
|
43
|
-
// message: '<img> tag missing alt attribute',
|
|
44
|
-
// rule: 'requireAltText'
|
|
45
|
-
// }
|
|
46
|
-
// ]
|
|
47
|
-
|
|
48
|
-
// Custom rules can be supplied via the `customRules` option
|
|
49
|
-
// const myRule = { name: 'demo', checkHtml: () => [] };
|
|
50
|
-
// lint(html, { customRules: [myRule] });
|
|
51
|
-
|
|
52
|
-
๐ API
|
|
53
|
-
|
|
54
|
-
lint(content: string, options?: LinterOptions): LintResult[]
|
|
55
|
-
|
|
56
|
-
Parameters:
|
|
57
|
-
|
|
58
|
-
content โ HTML, JSX, or TSX string input
|
|
59
|
-
|
|
60
|
-
options.rules โ toggles for built-in rules
|
|
61
|
-
options.customRules โ array of additional rules
|
|
62
|
-
|
|
63
|
-
Example LinterOptions
|
|
64
|
-
|
|
65
|
-
interface LinterOptions {
|
|
66
|
-
rules: {
|
|
67
|
-
requireAltText: boolean;
|
|
68
|
-
// ...more rules to come
|
|
69
|
-
};
|
|
70
|
-
customRules?: Rule[];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
Example LintResult
|
|
74
|
-
|
|
75
|
-
interface LintResult {
|
|
76
|
-
line: number;
|
|
77
|
-
column: number;
|
|
78
|
-
message: string;
|
|
79
|
-
rule: string;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
๐ Related Tools
|
|
83
|
-
|
|
84
|
-
ZemDomu VS Code Extension
|
|
85
|
-
|
|
86
|
-
ZemDomu GitHub Action (coming soon)
|
|
87
|
-
|
|
88
|
-
๐ Development
|
|
89
|
-
|
|
90
|
-
git clone https://github.com/Zemdomu/ZemDomu-core.git
|
|
91
|
-
cd ZemDomu-core
|
|
92
|
-
npm install
|
|
93
|
-
npm run build
|
|
94
|
-
|
|
95
|
-
Tests and coverage support coming soon.
|
|
96
|
-
|
|
97
|
-
๐ค Contributing
|
|
98
|
-
|
|
99
|
-
We welcome contributions! If you'd like to add rules, improve parsing, or integrate new consumers:
|
|
100
|
-
|
|
101
|
-
Fork this repo
|
|
102
|
-
|
|
103
|
-
Add your logic inside src/rules or src/linter.ts
|
|
104
|
-
|
|
105
|
-
Write or update tests (if applicable)
|
|
106
|
-
|
|
107
|
-
Submit a pull request!
|
|
108
|
-
|
|
109
|
-
๐ License
|
|
110
|
-
|
|
111
|
-
MIT ยฉ 2025 Zacharias Eryd Berlin
|
|
112
|
-
|
|
1
|
+
ZemDomu
|
|
2
|
+
|
|
3
|
+
Semantic HTML linting engine for clean, accessible, and SEO-friendly markup. This package provides the shared core logic used by the ZemDomu VS Code extension and upcoming GitHub Action.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
๐ง What is ZemDomu Core?
|
|
8
|
+
|
|
9
|
+
ZemDomu is a semantic-first linter that helps developers write better HTML and JSX by catching accessibility and structural issues. This package contains the framework-agnostic linting engine used by other tools in the ZemDomu ecosystem.
|
|
10
|
+
|
|
11
|
+
It parses .html, .jsx, and .tsx content and exposes a simple lint() function that returns semantic violations.
|
|
12
|
+
|
|
13
|
+
๐ Installation
|
|
14
|
+
|
|
15
|
+
npm install zemdomu
|
|
16
|
+
# or
|
|
17
|
+
yarn add zemdomu
|
|
18
|
+
|
|
19
|
+
โจ Features
|
|
20
|
+
|
|
21
|
+
โ
Lint semantic issues in HTML, JSX, and TSX
|
|
22
|
+
|
|
23
|
+
๐ฆ Works in Node.js, CI, or any JS runtime
|
|
24
|
+
|
|
25
|
+
โ๏ธ Extensible rule system
|
|
26
|
+
|
|
27
|
+
๐ Shared by extension and GitHub Action
|
|
28
|
+
|
|
29
|
+
๐งช Simple API: lint(content, options)
|
|
30
|
+
|
|
31
|
+
โ๏ธ Usage Example
|
|
32
|
+
|
|
33
|
+
import { lint } from 'zemdomu';
|
|
34
|
+
|
|
35
|
+
const html = '<img>';
|
|
36
|
+
const results = lint(html, { rules: { requireAltText: true } });
|
|
37
|
+
|
|
38
|
+
console.log(results);
|
|
39
|
+
// [
|
|
40
|
+
// {
|
|
41
|
+
// line: 0,
|
|
42
|
+
// column: 0,
|
|
43
|
+
// message: '<img> tag missing alt attribute',
|
|
44
|
+
// rule: 'requireAltText'
|
|
45
|
+
// }
|
|
46
|
+
// ]
|
|
47
|
+
|
|
48
|
+
// Custom rules can be supplied via the `customRules` option
|
|
49
|
+
// const myRule = { name: 'demo', checkHtml: () => [] };
|
|
50
|
+
// lint(html, { customRules: [myRule] });
|
|
51
|
+
|
|
52
|
+
๐ API
|
|
53
|
+
|
|
54
|
+
lint(content: string, options?: LinterOptions): LintResult[]
|
|
55
|
+
|
|
56
|
+
Parameters:
|
|
57
|
+
|
|
58
|
+
content โ HTML, JSX, or TSX string input
|
|
59
|
+
|
|
60
|
+
options.rules โ toggles for built-in rules
|
|
61
|
+
options.customRules โ array of additional rules
|
|
62
|
+
|
|
63
|
+
Example LinterOptions
|
|
64
|
+
|
|
65
|
+
interface LinterOptions {
|
|
66
|
+
rules: {
|
|
67
|
+
requireAltText: boolean;
|
|
68
|
+
// ...more rules to come
|
|
69
|
+
};
|
|
70
|
+
customRules?: Rule[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
Example LintResult
|
|
74
|
+
|
|
75
|
+
interface LintResult {
|
|
76
|
+
line: number;
|
|
77
|
+
column: number;
|
|
78
|
+
message: string;
|
|
79
|
+
rule: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
๐ Related Tools
|
|
83
|
+
|
|
84
|
+
ZemDomu VS Code Extension
|
|
85
|
+
|
|
86
|
+
ZemDomu GitHub Action (coming soon)
|
|
87
|
+
|
|
88
|
+
๐ Development
|
|
89
|
+
|
|
90
|
+
git clone https://github.com/Zemdomu/ZemDomu-core.git
|
|
91
|
+
cd ZemDomu-core
|
|
92
|
+
npm install
|
|
93
|
+
npm run build
|
|
94
|
+
|
|
95
|
+
Tests and coverage support coming soon.
|
|
96
|
+
|
|
97
|
+
๐ค Contributing
|
|
98
|
+
|
|
99
|
+
We welcome contributions! If you'd like to add rules, improve parsing, or integrate new consumers:
|
|
100
|
+
|
|
101
|
+
Fork this repo
|
|
102
|
+
|
|
103
|
+
Add your logic inside src/rules or src/linter.ts
|
|
104
|
+
|
|
105
|
+
Write or update tests (if applicable)
|
|
106
|
+
|
|
107
|
+
Submit a pull request!
|
|
108
|
+
|
|
109
|
+
๐ License
|
|
110
|
+
|
|
111
|
+
MIT ยฉ 2025 Zacharias Eryd Berlin
|
|
112
|
+
|
package/out/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Exposes the core lint function and types
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.ComponentPathResolver = exports.ComponentAnalyzer = exports.lint = void 0;
|
|
4
|
+
exports.ProjectLinter = exports.ComponentPathResolver = exports.ComponentAnalyzer = exports.lint = void 0;
|
|
5
5
|
var linter_1 = require("./linter");
|
|
6
6
|
Object.defineProperty(exports, "lint", { enumerable: true, get: function () { return linter_1.lint; } });
|
|
7
7
|
var component_analyzer_1 = require("./component-analyzer");
|
|
8
8
|
Object.defineProperty(exports, "ComponentAnalyzer", { enumerable: true, get: function () { return component_analyzer_1.ComponentAnalyzer; } });
|
|
9
9
|
var component_path_resolver_1 = require("./component-path-resolver");
|
|
10
10
|
Object.defineProperty(exports, "ComponentPathResolver", { enumerable: true, get: function () { return component_path_resolver_1.ComponentPathResolver; } });
|
|
11
|
+
var project_linter_1 = require("./project-linter");
|
|
12
|
+
Object.defineProperty(exports, "ProjectLinter", { enumerable: true, get: function () { return project_linter_1.ProjectLinter; } });
|
|
@@ -0,0 +1,87 @@
|
|
|
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.ProjectLinter = void 0;
|
|
37
|
+
const fs = __importStar(require("fs/promises"));
|
|
38
|
+
const linter_1 = require("./linter");
|
|
39
|
+
const component_analyzer_1 = require("./component-analyzer");
|
|
40
|
+
class ProjectLinter {
|
|
41
|
+
constructor(options = {}) {
|
|
42
|
+
this.opts = options;
|
|
43
|
+
this.analyzer = new component_analyzer_1.ComponentAnalyzer(this.opts);
|
|
44
|
+
}
|
|
45
|
+
clear() {
|
|
46
|
+
this.analyzer = new component_analyzer_1.ComponentAnalyzer(this.opts);
|
|
47
|
+
}
|
|
48
|
+
async lintFile(filePath, content) {
|
|
49
|
+
if (!content) {
|
|
50
|
+
content = await fs.readFile(filePath, 'utf8');
|
|
51
|
+
}
|
|
52
|
+
const results = (0, linter_1.lint)(content, this.opts);
|
|
53
|
+
const byFile = new Map();
|
|
54
|
+
byFile.set(filePath, [...results]);
|
|
55
|
+
const xmlMode = /\.(jsx|tsx)$/.test(filePath);
|
|
56
|
+
if (xmlMode) {
|
|
57
|
+
const component = await this.analyzer.analyzeFile(filePath);
|
|
58
|
+
if (component) {
|
|
59
|
+
this.analyzer.registerComponent(component, results);
|
|
60
|
+
}
|
|
61
|
+
if (this.opts.crossComponentAnalysis) {
|
|
62
|
+
const cross = this.analyzer.analyzeComponentTree();
|
|
63
|
+
for (const r of cross) {
|
|
64
|
+
if (!r.filePath)
|
|
65
|
+
continue;
|
|
66
|
+
if (!byFile.has(r.filePath))
|
|
67
|
+
byFile.set(r.filePath, []);
|
|
68
|
+
byFile.get(r.filePath).push(r);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return byFile;
|
|
73
|
+
}
|
|
74
|
+
async lintFiles(filePaths) {
|
|
75
|
+
const aggregated = new Map();
|
|
76
|
+
for (const filePath of filePaths) {
|
|
77
|
+
const fileMap = await this.lintFile(filePath);
|
|
78
|
+
for (const [fp, res] of fileMap.entries()) {
|
|
79
|
+
if (!aggregated.has(fp))
|
|
80
|
+
aggregated.set(fp, []);
|
|
81
|
+
aggregated.get(fp).push(...res);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return aggregated;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.ProjectLinter = ProjectLinter;
|
package/package.json
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "zemdomu",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "Hello",
|
|
5
|
-
"main": "./out/index.js",
|
|
6
|
-
"files": [
|
|
7
|
-
"out"
|
|
8
|
-
],
|
|
9
|
-
"private": false,
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsc -p tsconfig.json",
|
|
12
|
-
"compile": "tsc -p tsconfig.json",
|
|
13
|
-
"test": "npm run compile && node tests/
|
|
14
|
-
},
|
|
15
|
-
"keywords": [],
|
|
16
|
-
"author": "",
|
|
17
|
-
"license": "ISC",
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
"@types/babel__traverse": "^7.20.7",
|
|
20
|
-
"@types/babel-traverse": "^6.25.10",
|
|
21
|
-
"@types/babel-types": "^7.0.16",
|
|
22
|
-
"typescript": "^5.8.2",
|
|
23
|
-
"@types/node": "^22.15.17",
|
|
24
|
-
"@types/jest": "^29.5.3",
|
|
25
|
-
"esbuild": "^0.25.5",
|
|
26
|
-
"jest": "^29.7.0"
|
|
27
|
-
},
|
|
28
|
-
"dependencies": {
|
|
29
|
-
"@babel/parser": "^7.27.0",
|
|
30
|
-
"@babel/traverse": "^7.27.0",
|
|
31
|
-
"@babel/types": "^7.27.0",
|
|
32
|
-
"glob": "^7.2.3"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "zemdomu",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Hello",
|
|
5
|
+
"main": "./out/index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"out"
|
|
8
|
+
],
|
|
9
|
+
"private": false,
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc -p tsconfig.json",
|
|
12
|
+
"compile": "tsc -p tsconfig.json",
|
|
13
|
+
"test": "npm run compile && node tests/unique-ids.test.js && node tests/label-form-control.test.js && node tests/cross-component.test.js && node tests/heading-order.test.js && node tests/prevent-empty-inline.test.js && node tests/section-heading.test.js && node tests/img-alt.test.js && node tests/button-accessibility.test.js && node tests/html-lang.test.js && node tests/table-caption.test.js && node tests/all-rules.test.js"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [],
|
|
16
|
+
"author": "",
|
|
17
|
+
"license": "ISC",
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/babel__traverse": "^7.20.7",
|
|
20
|
+
"@types/babel-traverse": "^6.25.10",
|
|
21
|
+
"@types/babel-types": "^7.0.16",
|
|
22
|
+
"typescript": "^5.8.2",
|
|
23
|
+
"@types/node": "^22.15.17",
|
|
24
|
+
"@types/jest": "^29.5.3",
|
|
25
|
+
"esbuild": "^0.25.5",
|
|
26
|
+
"jest": "^29.7.0"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@babel/parser": "^7.27.0",
|
|
30
|
+
"@babel/traverse": "^7.27.0",
|
|
31
|
+
"@babel/types": "^7.27.0",
|
|
32
|
+
"glob": "^7.2.3"
|
|
33
|
+
}
|
|
34
|
+
}
|