rintenki 0.14.5 → 0.15.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 +31 -18
- package/bin/rintenki.js +80 -14
- package/bin/worker.js +46 -28
- package/index.d.ts +142 -6
- package/index.js +3 -6
- package/package.json +8 -8
- package/rintenki.darwin-arm64.node +0 -0
- package/rintenki.linux-x64-gnu.node +0 -0
- package/rintenki.win32-x64-msvc.node +0 -0
- package/rintenkirc.schema.json +0 -561
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ The name "rintenki" comes from the Japanese word "輪転機" (rintenki), meaning
|
|
|
15
15
|
- LSP server for editor integration
|
|
16
16
|
- Vue / JSX / eRuby / Astro support via parser plugins
|
|
17
17
|
- Per-rule severity customization and inline disable comments
|
|
18
|
-
-
|
|
18
|
+
- Type-safe configuration via `rintenki.config.ts` with `defineRintenkiConfig`
|
|
19
19
|
|
|
20
20
|
## Install
|
|
21
21
|
|
|
@@ -37,7 +37,7 @@ npx rintenki --watch "src/**/*.html"
|
|
|
37
37
|
```
|
|
38
38
|
rintenki [options] <files...>
|
|
39
39
|
|
|
40
|
-
-c, --config <path> Path to config file (default: .
|
|
40
|
+
-c, --config <path> Path to config file (default: rintenki.config.ts)
|
|
41
41
|
-f, --format <format> Output format: stylish (default), json, sarif
|
|
42
42
|
--fix Auto-fix fixable rules
|
|
43
43
|
-w, --watch Watch files for changes and re-lint
|
|
@@ -53,25 +53,30 @@ const { lint, fix } = require("rintenki");
|
|
|
53
53
|
const result = lint("<html><body><img></body></html>");
|
|
54
54
|
console.log(result.diagnostics);
|
|
55
55
|
|
|
56
|
-
const fixed = fix('
|
|
57
|
-
console.log(fixed.output); //
|
|
56
|
+
const fixed = fix('<!DOCTYPE html><DIV Class="foo">text</DIV>');
|
|
57
|
+
console.log(fixed.output); // <!DOCTYPE html><div class="foo">text</div>
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
## Configuration
|
|
61
61
|
|
|
62
|
-
Place
|
|
62
|
+
Place `rintenki.config.ts` in your project root:
|
|
63
63
|
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
```ts
|
|
65
|
+
// rintenki.config.ts
|
|
66
|
+
import { defineRintenkiConfig } from "rintenki";
|
|
67
|
+
|
|
68
|
+
export default defineRintenkiConfig({
|
|
69
|
+
rules: {
|
|
67
70
|
"doctype": "error",
|
|
68
71
|
"no-consecutive-br": "warning",
|
|
69
|
-
"no-hard-code-id": "off"
|
|
72
|
+
"no-hard-code-id": "off",
|
|
70
73
|
},
|
|
71
|
-
|
|
72
|
-
}
|
|
74
|
+
ignore: ["dist/**", "vendor/**"],
|
|
75
|
+
});
|
|
73
76
|
```
|
|
74
77
|
|
|
78
|
+
`rintenki.config.js` is also supported. `defineRintenkiConfig` provides autocomplete and type checking for rule names and severity values.
|
|
79
|
+
|
|
75
80
|
| Value | Description |
|
|
76
81
|
|-------|-------------|
|
|
77
82
|
| `"error"` | Report as error (exit code 1) |
|
|
@@ -81,7 +86,12 @@ Place `.rintenkirc.json` in your project root:
|
|
|
81
86
|
|
|
82
87
|
### Ignore Patterns
|
|
83
88
|
|
|
84
|
-
|
|
89
|
+
Two equivalent ways to exclude files (both can be used together):
|
|
90
|
+
|
|
91
|
+
1. **`ignore` field in `rintenki.config.ts`** — glob patterns inside the config
|
|
92
|
+
2. **`.rintenkiignore` file** at the project root — one glob per line, `#` for comments, blank lines ignored (same format as `.gitignore`)
|
|
93
|
+
|
|
94
|
+
`**/node_modules/**` is always excluded automatically. See the [Configuration guide](https://rintenki.dev/guide/configuration.html#ignore-patterns) for details.
|
|
85
95
|
|
|
86
96
|
### Inline Disable Comments
|
|
87
97
|
|
|
@@ -103,12 +113,15 @@ Use a `.rintenkiignore` file or the `ignore` field in config. `node_modules` is
|
|
|
103
113
|
|
|
104
114
|
Parsers are auto-detected from installed packages, or configured explicitly:
|
|
105
115
|
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
```ts
|
|
117
|
+
// rintenki.config.ts
|
|
118
|
+
import { defineRintenkiConfig } from "rintenki";
|
|
119
|
+
|
|
120
|
+
export default defineRintenkiConfig({
|
|
121
|
+
parser: {
|
|
122
|
+
".vue": "@rintenki/vue-parser",
|
|
123
|
+
},
|
|
124
|
+
});
|
|
112
125
|
```
|
|
113
126
|
|
|
114
127
|
## Rules
|
package/bin/rintenki.js
CHANGED
|
@@ -4,6 +4,7 @@ const { existsSync, readFileSync, writeFileSync, watch } = require("fs");
|
|
|
4
4
|
const { resolve, relative, dirname, join } = require("path");
|
|
5
5
|
const { createHash } = require("crypto");
|
|
6
6
|
const { glob } = require("tinyglobby");
|
|
7
|
+
const { createJiti } = require("jiti");
|
|
7
8
|
const { lint, fix } = require("../index");
|
|
8
9
|
|
|
9
10
|
let loadParser;
|
|
@@ -21,14 +22,28 @@ const COLORS = {
|
|
|
21
22
|
reset: "\x1b[0m",
|
|
22
23
|
};
|
|
23
24
|
|
|
24
|
-
const CONFIG_FILES = [".
|
|
25
|
+
const CONFIG_FILES = ["rintenki.config.ts", "rintenki.config.js"];
|
|
25
26
|
const IGNORE_FILE = ".rintenkiignore";
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
let jitiInstance;
|
|
29
|
+
function getJiti() {
|
|
30
|
+
if (!jitiInstance) {
|
|
31
|
+
jitiInstance = createJiti(__filename);
|
|
32
|
+
}
|
|
33
|
+
return jitiInstance;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Load a rintenki config file. Supports both TypeScript (`rintenki.config.ts`)
|
|
38
|
+
* and JavaScript (`rintenki.config.js`) configs. Both ES module (`export default`)
|
|
39
|
+
* and CommonJS (`module.exports`) styles work via the jiti runtime.
|
|
40
|
+
*/
|
|
41
|
+
function loadConfigFile(filePath) {
|
|
28
42
|
try {
|
|
29
|
-
|
|
43
|
+
const mod = getJiti()(filePath);
|
|
44
|
+
return mod.default ?? mod;
|
|
30
45
|
} catch (err) {
|
|
31
|
-
console.error(`Failed to
|
|
46
|
+
console.error(`Failed to load config file: ${filePath}`);
|
|
32
47
|
console.error(err.message);
|
|
33
48
|
process.exit(1);
|
|
34
49
|
}
|
|
@@ -41,13 +56,13 @@ function loadConfig(configPath) {
|
|
|
41
56
|
console.error(`Config file not found: ${configPath}`);
|
|
42
57
|
process.exit(1);
|
|
43
58
|
}
|
|
44
|
-
return
|
|
59
|
+
return loadConfigFile(abs);
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
for (const name of CONFIG_FILES) {
|
|
48
63
|
const abs = resolve(name);
|
|
49
64
|
if (existsSync(abs)) {
|
|
50
|
-
return
|
|
65
|
+
return loadConfigFile(abs);
|
|
51
66
|
}
|
|
52
67
|
}
|
|
53
68
|
|
|
@@ -184,11 +199,10 @@ function buildSarif(jsonOutput) {
|
|
|
184
199
|
async function main() {
|
|
185
200
|
const args = parseArgs(process.argv.slice(2));
|
|
186
201
|
|
|
187
|
-
|
|
188
|
-
console.log(`Usage: rintenki [options] <files...>
|
|
202
|
+
const helpText = `Usage: rintenki [options] <files...>
|
|
189
203
|
|
|
190
204
|
Options:
|
|
191
|
-
-c, --config <path> Path to config file (default: .
|
|
205
|
+
-c, --config <path> Path to config file (default: rintenki.config.ts)
|
|
192
206
|
-f, --format <format> Output format: stylish (default), json, sarif
|
|
193
207
|
--fix Auto-fix fixable issues
|
|
194
208
|
-w, --watch Watch files for changes and re-lint
|
|
@@ -196,16 +210,34 @@ Options:
|
|
|
196
210
|
-h, --help Show help
|
|
197
211
|
|
|
198
212
|
Ignore patterns:
|
|
199
|
-
|
|
200
|
-
|
|
213
|
+
Two equivalent options (both can be combined):
|
|
214
|
+
1. ".rintenkiignore" file at the project root — one glob per line,
|
|
215
|
+
# for comments, blank lines ignored.
|
|
216
|
+
2. "ignore" field in rintenki.config.ts — array of glob patterns.
|
|
217
|
+
node_modules is always excluded.
|
|
201
218
|
|
|
202
219
|
Examples:
|
|
203
220
|
rintenki index.html
|
|
204
221
|
rintenki "src/**/*.html"
|
|
205
|
-
rintenki --format json "src/**/*.html"
|
|
222
|
+
rintenki --format json "src/**/*.html"`;
|
|
223
|
+
|
|
224
|
+
if (args.help) {
|
|
225
|
+
console.log(helpText);
|
|
206
226
|
process.exit(0);
|
|
207
227
|
}
|
|
208
228
|
|
|
229
|
+
if (args.files.length === 0) {
|
|
230
|
+
console.error("Error: No files specified.\n");
|
|
231
|
+
console.error(helpText);
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const validFormats = ["stylish", "json", "sarif"];
|
|
236
|
+
if (args.format && !validFormats.includes(args.format)) {
|
|
237
|
+
console.error(`Error: Invalid format "${args.format}". Valid formats: ${validFormats.join(", ")}`);
|
|
238
|
+
process.exit(1);
|
|
239
|
+
}
|
|
240
|
+
|
|
209
241
|
const config = loadConfig(args.config);
|
|
210
242
|
const ignorePatterns = loadIgnorePatterns(config);
|
|
211
243
|
const files = await glob(args.files, { absolute: true, ignore: ignorePatterns });
|
|
@@ -255,8 +287,31 @@ Examples:
|
|
|
255
287
|
|
|
256
288
|
const PARALLEL_THRESHOLD = 20;
|
|
257
289
|
|
|
290
|
+
function internalErrorDiagnostic(message) {
|
|
291
|
+
return {
|
|
292
|
+
rule: "internal-error",
|
|
293
|
+
message,
|
|
294
|
+
severity: "error",
|
|
295
|
+
line: 1,
|
|
296
|
+
col: null,
|
|
297
|
+
endLine: null,
|
|
298
|
+
endCol: null,
|
|
299
|
+
fixable: false,
|
|
300
|
+
hint: null,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
258
304
|
function lintOneFile(file, config, args) {
|
|
259
|
-
let source
|
|
305
|
+
let source;
|
|
306
|
+
try {
|
|
307
|
+
source = readFileSync(file, "utf-8");
|
|
308
|
+
} catch (err) {
|
|
309
|
+
return {
|
|
310
|
+
diagnostics: [internalErrorDiagnostic(`Failed to read file: ${err.message}`)],
|
|
311
|
+
fixedCount: 0,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
260
315
|
let lineOffset = 0;
|
|
261
316
|
let isFragment = false;
|
|
262
317
|
|
|
@@ -344,7 +399,18 @@ async function lintFiles(files, config, args, cache) {
|
|
|
344
399
|
// Sequential mode (with optional cache for watch)
|
|
345
400
|
fileResults = [];
|
|
346
401
|
for (const file of files) {
|
|
347
|
-
|
|
402
|
+
let source;
|
|
403
|
+
try {
|
|
404
|
+
source = readFileSync(file, "utf-8");
|
|
405
|
+
} catch (err) {
|
|
406
|
+
fileResults.push({
|
|
407
|
+
file,
|
|
408
|
+
rel: relative(process.cwd(), file),
|
|
409
|
+
diagnostics: [internalErrorDiagnostic(`Failed to read file: ${err.message}`)],
|
|
410
|
+
fixedCount: 0,
|
|
411
|
+
});
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
348
414
|
const hash = fileHash(source);
|
|
349
415
|
|
|
350
416
|
if (cache) {
|
package/bin/worker.js
CHANGED
|
@@ -13,41 +13,59 @@ const { files, config, fix: shouldFix } = workerData;
|
|
|
13
13
|
const results = [];
|
|
14
14
|
|
|
15
15
|
for (const file of files) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
try {
|
|
17
|
+
let source = readFileSync(file, "utf-8");
|
|
18
|
+
let lineOffset = 0;
|
|
19
|
+
let isFragment = false;
|
|
20
|
+
|
|
21
|
+
const parser = loadParser(file, config?.parser);
|
|
22
|
+
if (parser) {
|
|
23
|
+
const preprocessed = parser.preprocess(source);
|
|
24
|
+
source = preprocessed.html;
|
|
25
|
+
lineOffset = preprocessed.lineOffset;
|
|
26
|
+
isFragment = preprocessed.isFragment ?? false;
|
|
27
|
+
if (!source) continue;
|
|
28
|
+
}
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
let html = source;
|
|
31
|
+
let fixedCount = 0;
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
if (shouldFix) {
|
|
34
|
+
const fixResult = fix(html, config);
|
|
35
|
+
if (fixResult.fixedCount > 0) {
|
|
36
|
+
writeFileSync(file, fixResult.output, "utf-8");
|
|
37
|
+
html = fixResult.output;
|
|
38
|
+
fixedCount = fixResult.fixedCount;
|
|
39
|
+
}
|
|
38
40
|
}
|
|
39
|
-
}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
const result = lint(html, config, isFragment);
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
if (lineOffset > 0) {
|
|
45
|
+
for (const d of result.diagnostics) {
|
|
46
|
+
if (d.line != null) d.line += lineOffset;
|
|
47
|
+
if (d.endLine != null) d.endLine += lineOffset;
|
|
48
|
+
}
|
|
47
49
|
}
|
|
48
|
-
}
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
results.push({ file, diagnostics: result.diagnostics, fixedCount });
|
|
52
|
+
} catch (err) {
|
|
53
|
+
results.push({
|
|
54
|
+
file,
|
|
55
|
+
diagnostics: [{
|
|
56
|
+
rule: "internal-error",
|
|
57
|
+
message: `Failed to process file: ${err.message}`,
|
|
58
|
+
severity: "error",
|
|
59
|
+
line: 1,
|
|
60
|
+
col: null,
|
|
61
|
+
endLine: null,
|
|
62
|
+
endCol: null,
|
|
63
|
+
fixable: false,
|
|
64
|
+
hint: null,
|
|
65
|
+
}],
|
|
66
|
+
fixedCount: 0,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
51
69
|
}
|
|
52
70
|
|
|
53
71
|
parentPort.postMessage(results);
|
package/index.d.ts
CHANGED
|
@@ -19,18 +19,154 @@ export interface FixResult {
|
|
|
19
19
|
fixedCount: number;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export type
|
|
22
|
+
export type RuleName =
|
|
23
|
+
| "address-content-model"
|
|
24
|
+
| "aria-attr-conflicts"
|
|
25
|
+
| "aria-attr-valid-values"
|
|
26
|
+
| "aria-hidden-focusable"
|
|
27
|
+
| "aria-naming-prohibited"
|
|
28
|
+
| "aria-role-conflicts"
|
|
29
|
+
| "attr-duplication"
|
|
30
|
+
| "attr-value-quotes"
|
|
31
|
+
| "base-before-urls"
|
|
32
|
+
| "base-has-href-or-target"
|
|
33
|
+
| "case-sensitive-attr-name"
|
|
34
|
+
| "case-sensitive-tag-name"
|
|
35
|
+
| "character-reference"
|
|
36
|
+
| "class-naming"
|
|
37
|
+
| "colspan-rowspan-range"
|
|
38
|
+
| "deprecated-attr"
|
|
39
|
+
| "deprecated-element"
|
|
40
|
+
| "dfn-no-dfn-descendants"
|
|
41
|
+
| "disallowed-element"
|
|
42
|
+
| "doctype"
|
|
43
|
+
| "empty-heading"
|
|
44
|
+
| "empty-title"
|
|
45
|
+
| "end-tag"
|
|
46
|
+
| "fieldset-has-legend"
|
|
47
|
+
| "figcaption-position"
|
|
48
|
+
| "form-dup-name"
|
|
49
|
+
| "header-footer-nesting"
|
|
50
|
+
| "heading-levels"
|
|
51
|
+
| "id-duplication"
|
|
52
|
+
| "ineffective-attr"
|
|
53
|
+
| "input-attr-applicability"
|
|
54
|
+
| "internal-error"
|
|
55
|
+
| "invalid-attr"
|
|
56
|
+
| "label-has-control"
|
|
57
|
+
| "landmark-roles"
|
|
58
|
+
| "link-constraints"
|
|
59
|
+
| "link-rel-or-itemprop"
|
|
60
|
+
| "media-has-captions"
|
|
61
|
+
| "meta-constraints"
|
|
62
|
+
| "neighbor-popovers"
|
|
63
|
+
| "no-abstract-role"
|
|
64
|
+
| "no-ambiguous-navigable-target-names"
|
|
65
|
+
| "no-aria-checked-mismatch"
|
|
66
|
+
| "no-aria-disabled-link"
|
|
67
|
+
| "no-aria-hidden-body"
|
|
68
|
+
| "no-autoplay-media"
|
|
69
|
+
| "no-boolean-attr-value"
|
|
70
|
+
| "no-consecutive-br"
|
|
71
|
+
| "no-default-value"
|
|
72
|
+
| "no-dup-class"
|
|
73
|
+
| "no-duplicate-accesskey"
|
|
74
|
+
| "no-duplicate-base"
|
|
75
|
+
| "no-duplicate-dt"
|
|
76
|
+
| "no-duplicate-in-head"
|
|
77
|
+
| "no-duplicate-landmark"
|
|
78
|
+
| "no-duplicate-track"
|
|
79
|
+
| "no-empty-palpable-content"
|
|
80
|
+
| "no-empty-track-label"
|
|
81
|
+
| "no-form-without-action"
|
|
82
|
+
| "no-generic-role"
|
|
83
|
+
| "no-hard-code-id"
|
|
84
|
+
| "no-implicit-button-type"
|
|
85
|
+
| "no-inline-style"
|
|
86
|
+
| "no-javascript-url"
|
|
87
|
+
| "no-multiple-default-track"
|
|
88
|
+
| "no-nested-forms"
|
|
89
|
+
| "no-nested-interactive"
|
|
90
|
+
| "no-non-scalable-viewport"
|
|
91
|
+
| "no-obsolete-doctype"
|
|
92
|
+
| "no-orphaned-end-tag"
|
|
93
|
+
| "no-positive-tabindex"
|
|
94
|
+
| "no-redundant-role"
|
|
95
|
+
| "no-refer-to-non-existent-id"
|
|
96
|
+
| "no-role-on-meta-elements"
|
|
97
|
+
| "no-tabindex-on-dialog"
|
|
98
|
+
| "no-target-blank-without-rel"
|
|
99
|
+
| "no-use-event-handler-attr"
|
|
100
|
+
| "obsolete-but-conforming"
|
|
101
|
+
| "parse-error"
|
|
102
|
+
| "permitted-contents"
|
|
103
|
+
| "picture-structure"
|
|
104
|
+
| "placeholder-label-option"
|
|
105
|
+
| "prefer-native-over-aria"
|
|
106
|
+
| "require-accessible-name"
|
|
107
|
+
| "require-datetime"
|
|
108
|
+
| "require-meta-charset"
|
|
109
|
+
| "required-attr"
|
|
110
|
+
| "required-element"
|
|
111
|
+
| "required-h1"
|
|
112
|
+
| "script-type"
|
|
113
|
+
| "src-not-empty"
|
|
114
|
+
| "summary-first-child"
|
|
115
|
+
| "table-has-caption"
|
|
116
|
+
| "table-row-column-alignment"
|
|
117
|
+
| "th-content-restrictions"
|
|
118
|
+
| "th-has-scope"
|
|
119
|
+
| "track-has-srclang"
|
|
120
|
+
| "unique-main"
|
|
121
|
+
| "use-list"
|
|
122
|
+
| "valid-attr-value"
|
|
123
|
+
| "valid-autocomplete"
|
|
124
|
+
| "valid-id"
|
|
125
|
+
| "valid-rel"
|
|
126
|
+
| "void-content"
|
|
127
|
+
| "wai-aria";
|
|
23
128
|
|
|
24
|
-
export
|
|
129
|
+
export type RuleSeverity = "error" | "warning" | "warn" | "off" | boolean;
|
|
130
|
+
|
|
131
|
+
export type ParserSyntax = ".vue" | ".jsx" | ".tsx" | ".erb" | ".astro";
|
|
132
|
+
|
|
133
|
+
export interface RintenkiConfig {
|
|
25
134
|
/**
|
|
26
135
|
* Rule name -> severity.
|
|
27
|
-
* - "error": report as error
|
|
136
|
+
* - "error": report as error (exit code 1)
|
|
28
137
|
* - "warning" | "warn": report as warning
|
|
29
138
|
* - "off" | false: disable the rule
|
|
30
139
|
* - true: use default severity
|
|
31
140
|
*/
|
|
32
|
-
rules?: Record<
|
|
141
|
+
rules?: Partial<Record<RuleName, RuleSeverity>>;
|
|
142
|
+
/** Glob patterns to ignore. */
|
|
143
|
+
ignore?: string[];
|
|
144
|
+
/** File extension -> parser package mapping. */
|
|
145
|
+
parser?: Partial<Record<ParserSyntax, string>>;
|
|
33
146
|
}
|
|
34
147
|
|
|
35
|
-
|
|
36
|
-
export
|
|
148
|
+
/** @deprecated Use `RintenkiConfig` instead. */
|
|
149
|
+
export type LintConfig = RintenkiConfig;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Define a type-safe rintenki configuration.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```ts
|
|
156
|
+
* // rintenki.config.ts
|
|
157
|
+
* import { defineRintenkiConfig } from "rintenki";
|
|
158
|
+
*
|
|
159
|
+
* export default defineRintenkiConfig({
|
|
160
|
+
* rules: {
|
|
161
|
+
* "doctype": "error",
|
|
162
|
+
* "no-consecutive-br": "warning",
|
|
163
|
+
* "no-hard-code-id": "off",
|
|
164
|
+
* },
|
|
165
|
+
* ignore: ["dist/**", "vendor/**"],
|
|
166
|
+
* });
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export function defineRintenkiConfig(config: RintenkiConfig): RintenkiConfig;
|
|
170
|
+
|
|
171
|
+
export function lint(html: string, config?: RintenkiConfig, isFragment?: boolean): LintResult;
|
|
172
|
+
export function fix(html: string, config?: RintenkiConfig): FixResult;
|
package/index.js
CHANGED
|
@@ -6,20 +6,14 @@ const { platform, arch } = process;
|
|
|
6
6
|
function loadBinding() {
|
|
7
7
|
const triples = {
|
|
8
8
|
"darwin-arm64": "rintenki.darwin-arm64.node",
|
|
9
|
-
"darwin-x64": "rintenki.darwin-x64.node",
|
|
10
9
|
"linux-x64": "rintenki.linux-x64-gnu.node",
|
|
11
|
-
"linux-arm64": "rintenki.linux-arm64-gnu.node",
|
|
12
10
|
"win32-x64": "rintenki.win32-x64-msvc.node",
|
|
13
|
-
"win32-arm64": "rintenki.win32-arm64-msvc.node",
|
|
14
11
|
};
|
|
15
12
|
|
|
16
13
|
const packages = {
|
|
17
14
|
"darwin-arm64": "rintenki-darwin-arm64",
|
|
18
|
-
"darwin-x64": "rintenki-darwin-x64",
|
|
19
15
|
"linux-x64": "rintenki-linux-x64-gnu",
|
|
20
|
-
"linux-arm64": "rintenki-linux-arm64-gnu",
|
|
21
16
|
"win32-x64": "rintenki-win32-x64-msvc",
|
|
22
|
-
"win32-arm64": "rintenki-win32-arm64-msvc",
|
|
23
17
|
};
|
|
24
18
|
|
|
25
19
|
const key = `${platform}-${arch}`;
|
|
@@ -47,3 +41,6 @@ function loadBinding() {
|
|
|
47
41
|
const binding = loadBinding();
|
|
48
42
|
module.exports.lint = binding.lint;
|
|
49
43
|
module.exports.fix = binding.fix;
|
|
44
|
+
module.exports.defineRintenkiConfig = function defineRintenkiConfig(config) {
|
|
45
|
+
return config;
|
|
46
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rintenki",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "A fast HTML linter powered by html5ever + napi-rs",
|
|
5
5
|
"author": "Kazuhiro Kobayashi <https://github.com/kzhrk>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,8 +34,7 @@
|
|
|
34
34
|
"bin/rintenki.js",
|
|
35
35
|
"bin/worker.js",
|
|
36
36
|
"rintenki.*.node",
|
|
37
|
-
"README.md"
|
|
38
|
-
"rintenkirc.schema.json"
|
|
37
|
+
"README.md"
|
|
39
38
|
],
|
|
40
39
|
"napi": {
|
|
41
40
|
"binaryName": "rintenki",
|
|
@@ -46,13 +45,14 @@
|
|
|
46
45
|
]
|
|
47
46
|
},
|
|
48
47
|
"dependencies": {
|
|
49
|
-
"
|
|
48
|
+
"jiti": "^2.7.0",
|
|
49
|
+
"tinyglobby": "0.2.16"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@napi-rs/cli": "3.6.
|
|
53
|
-
"@types/node": "25.
|
|
54
|
-
"typescript": "6.0.
|
|
55
|
-
"vitest": "4.1.
|
|
52
|
+
"@napi-rs/cli": "3.6.2",
|
|
53
|
+
"@types/node": "25.6.2",
|
|
54
|
+
"typescript": "6.0.3",
|
|
55
|
+
"vitest": "4.1.5"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "napi build --release --platform --no-js --dts .napi-output.d.ts && rm -f .napi-output.d.ts",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/rintenkirc.schema.json
DELETED
|
@@ -1,561 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"title": "Rintenki Configuration",
|
|
4
|
-
"description": "Configuration file for the rintenki HTML linter",
|
|
5
|
-
"type": "object",
|
|
6
|
-
"properties": {
|
|
7
|
-
"rules": {
|
|
8
|
-
"type": "object",
|
|
9
|
-
"description": "Rule severity overrides",
|
|
10
|
-
"properties": {
|
|
11
|
-
"aria-attr-conflicts": {
|
|
12
|
-
"$ref": "#/definitions/severity",
|
|
13
|
-
"description": "Detect conflicting ARIA and native HTML attributes",
|
|
14
|
-
"default": "error"
|
|
15
|
-
},
|
|
16
|
-
"aria-attr-valid-values": {
|
|
17
|
-
"$ref": "#/definitions/severity",
|
|
18
|
-
"description": "Validate ARIA attribute values",
|
|
19
|
-
"default": "warning"
|
|
20
|
-
},
|
|
21
|
-
"aria-hidden-focusable": {
|
|
22
|
-
"$ref": "#/definitions/severity",
|
|
23
|
-
"description": "Disallow aria-hidden on focusable elements",
|
|
24
|
-
"default": "error"
|
|
25
|
-
},
|
|
26
|
-
"aria-naming-prohibited": {
|
|
27
|
-
"$ref": "#/definitions/severity",
|
|
28
|
-
"description": "Disallow aria-label/aria-labelledby on elements where naming is prohibited",
|
|
29
|
-
"default": "error"
|
|
30
|
-
},
|
|
31
|
-
"aria-role-conflicts": {
|
|
32
|
-
"$ref": "#/definitions/severity",
|
|
33
|
-
"description": "Detect conflicts between explicit role and element's implicit role",
|
|
34
|
-
"default": "warning"
|
|
35
|
-
},
|
|
36
|
-
"attr-duplication": {
|
|
37
|
-
"$ref": "#/definitions/severity",
|
|
38
|
-
"description": "Disallow duplicate attributes on the same element",
|
|
39
|
-
"default": "error"
|
|
40
|
-
},
|
|
41
|
-
"attr-value-quotes": {
|
|
42
|
-
"$ref": "#/definitions/severity",
|
|
43
|
-
"description": "Require attribute values to be quoted",
|
|
44
|
-
"default": "warning"
|
|
45
|
-
},
|
|
46
|
-
"case-sensitive-attr-name": {
|
|
47
|
-
"$ref": "#/definitions/severity",
|
|
48
|
-
"description": "Enforce lowercase attribute names (auto-fixable)",
|
|
49
|
-
"default": "warning"
|
|
50
|
-
},
|
|
51
|
-
"colspan-rowspan-range": {
|
|
52
|
-
"$ref": "#/definitions/severity",
|
|
53
|
-
"description": "Require colspan and rowspan values to be within valid ranges",
|
|
54
|
-
"default": "error"
|
|
55
|
-
},
|
|
56
|
-
"case-sensitive-tag-name": {
|
|
57
|
-
"$ref": "#/definitions/severity",
|
|
58
|
-
"description": "Enforce lowercase tag names (auto-fixable)",
|
|
59
|
-
"default": "warning"
|
|
60
|
-
},
|
|
61
|
-
"character-reference": {
|
|
62
|
-
"$ref": "#/definitions/severity",
|
|
63
|
-
"description": "Require unescaped & to be written as &",
|
|
64
|
-
"default": "warning"
|
|
65
|
-
},
|
|
66
|
-
"class-naming": {
|
|
67
|
-
"$ref": "#/definitions/severity",
|
|
68
|
-
"description": "Enforce class name conventions (opt-in)",
|
|
69
|
-
"default": "off"
|
|
70
|
-
},
|
|
71
|
-
"dfn-no-dfn-descendants": {
|
|
72
|
-
"$ref": "#/definitions/severity",
|
|
73
|
-
"description": "Disallow dfn nested inside another dfn",
|
|
74
|
-
"default": "error"
|
|
75
|
-
},
|
|
76
|
-
"deprecated-attr": {
|
|
77
|
-
"$ref": "#/definitions/severity",
|
|
78
|
-
"description": "Disallow deprecated HTML attributes",
|
|
79
|
-
"default": "error"
|
|
80
|
-
},
|
|
81
|
-
"deprecated-element": {
|
|
82
|
-
"$ref": "#/definitions/severity",
|
|
83
|
-
"description": "Disallow deprecated HTML elements",
|
|
84
|
-
"default": "error"
|
|
85
|
-
},
|
|
86
|
-
"disallowed-element": {
|
|
87
|
-
"$ref": "#/definitions/severity",
|
|
88
|
-
"description": "Disallow specified elements (opt-in)",
|
|
89
|
-
"default": "off"
|
|
90
|
-
},
|
|
91
|
-
"doctype": {
|
|
92
|
-
"$ref": "#/definitions/severity",
|
|
93
|
-
"description": "Require DOCTYPE declaration",
|
|
94
|
-
"default": "error"
|
|
95
|
-
},
|
|
96
|
-
"empty-heading": {
|
|
97
|
-
"$ref": "#/definitions/severity",
|
|
98
|
-
"description": "Detect empty heading elements",
|
|
99
|
-
"default": "warning"
|
|
100
|
-
},
|
|
101
|
-
"empty-title": {
|
|
102
|
-
"$ref": "#/definitions/severity",
|
|
103
|
-
"description": "Detect empty title element",
|
|
104
|
-
"default": "error"
|
|
105
|
-
},
|
|
106
|
-
"end-tag": {
|
|
107
|
-
"$ref": "#/definitions/severity",
|
|
108
|
-
"description": "Require closing tags for non-void elements",
|
|
109
|
-
"default": "warning"
|
|
110
|
-
},
|
|
111
|
-
"figcaption-position": {
|
|
112
|
-
"$ref": "#/definitions/severity",
|
|
113
|
-
"description": "Require figcaption to be the first or last child of figure",
|
|
114
|
-
"default": "warning"
|
|
115
|
-
},
|
|
116
|
-
"fieldset-has-legend": {
|
|
117
|
-
"$ref": "#/definitions/severity",
|
|
118
|
-
"description": "Require legend element in fieldset",
|
|
119
|
-
"default": "warning"
|
|
120
|
-
},
|
|
121
|
-
"form-dup-name": {
|
|
122
|
-
"$ref": "#/definitions/severity",
|
|
123
|
-
"description": "Detect duplicate form control names within a form",
|
|
124
|
-
"default": "warning"
|
|
125
|
-
},
|
|
126
|
-
"header-footer-nesting": {
|
|
127
|
-
"$ref": "#/definitions/severity",
|
|
128
|
-
"description": "Disallow header/footer/main nesting inside header or footer",
|
|
129
|
-
"default": "error"
|
|
130
|
-
},
|
|
131
|
-
"heading-levels": {
|
|
132
|
-
"$ref": "#/definitions/severity",
|
|
133
|
-
"description": "Disallow skipping heading levels (e.g. h1 to h3)",
|
|
134
|
-
"default": "error"
|
|
135
|
-
},
|
|
136
|
-
"id-duplication": {
|
|
137
|
-
"$ref": "#/definitions/severity",
|
|
138
|
-
"description": "Disallow duplicate id attribute values",
|
|
139
|
-
"default": "error"
|
|
140
|
-
},
|
|
141
|
-
"input-attr-applicability": {
|
|
142
|
-
"$ref": "#/definitions/severity",
|
|
143
|
-
"description": "Detect attributes that do not apply to the input type",
|
|
144
|
-
"default": "warning"
|
|
145
|
-
},
|
|
146
|
-
"ineffective-attr": {
|
|
147
|
-
"$ref": "#/definitions/severity",
|
|
148
|
-
"description": "Disallow attributes that have no effect on the element",
|
|
149
|
-
"default": "warning"
|
|
150
|
-
},
|
|
151
|
-
"invalid-attr": {
|
|
152
|
-
"$ref": "#/definitions/severity",
|
|
153
|
-
"description": "Disallow non-standard attributes",
|
|
154
|
-
"default": "error"
|
|
155
|
-
},
|
|
156
|
-
"media-has-captions": {
|
|
157
|
-
"$ref": "#/definitions/severity",
|
|
158
|
-
"description": "Require captions or subtitles track on video elements",
|
|
159
|
-
"default": "warning"
|
|
160
|
-
},
|
|
161
|
-
"meta-constraints": {
|
|
162
|
-
"$ref": "#/definitions/severity",
|
|
163
|
-
"description": "Validate meta element attribute constraints",
|
|
164
|
-
"default": "error"
|
|
165
|
-
},
|
|
166
|
-
"link-constraints": {
|
|
167
|
-
"$ref": "#/definitions/severity",
|
|
168
|
-
"description": "Validate link element attribute constraints (preload requires as, etc.)",
|
|
169
|
-
"default": "error"
|
|
170
|
-
},
|
|
171
|
-
"label-has-control": {
|
|
172
|
-
"$ref": "#/definitions/severity",
|
|
173
|
-
"description": "Require label elements to have an associated control",
|
|
174
|
-
"default": "error"
|
|
175
|
-
},
|
|
176
|
-
"landmark-roles": {
|
|
177
|
-
"$ref": "#/definitions/severity",
|
|
178
|
-
"description": "Disallow nested landmark roles",
|
|
179
|
-
"default": "warning"
|
|
180
|
-
},
|
|
181
|
-
"neighbor-popovers": {
|
|
182
|
-
"$ref": "#/definitions/severity",
|
|
183
|
-
"description": "Require popover triggers to be adjacent to their targets (opt-in)",
|
|
184
|
-
"default": "off"
|
|
185
|
-
},
|
|
186
|
-
"no-abstract-role": {
|
|
187
|
-
"$ref": "#/definitions/severity",
|
|
188
|
-
"description": "Disallow abstract ARIA roles",
|
|
189
|
-
"default": "error"
|
|
190
|
-
},
|
|
191
|
-
"no-autoplay-media": {
|
|
192
|
-
"$ref": "#/definitions/severity",
|
|
193
|
-
"description": "Detect autoplay without muted on video/audio elements",
|
|
194
|
-
"default": "warning"
|
|
195
|
-
},
|
|
196
|
-
"no-aria-hidden-body": {
|
|
197
|
-
"$ref": "#/definitions/severity",
|
|
198
|
-
"description": "Disallow aria-hidden on body element",
|
|
199
|
-
"default": "error"
|
|
200
|
-
},
|
|
201
|
-
"no-ambiguous-navigable-target-names": {
|
|
202
|
-
"$ref": "#/definitions/severity",
|
|
203
|
-
"description": "Disallow ambiguous target attribute values",
|
|
204
|
-
"default": "warning"
|
|
205
|
-
},
|
|
206
|
-
"no-boolean-attr-value": {
|
|
207
|
-
"$ref": "#/definitions/severity",
|
|
208
|
-
"description": "Disallow redundant boolean attribute values (auto-fixable)",
|
|
209
|
-
"default": "warning"
|
|
210
|
-
},
|
|
211
|
-
"no-consecutive-br": {
|
|
212
|
-
"$ref": "#/definitions/severity",
|
|
213
|
-
"description": "Disallow consecutive br elements",
|
|
214
|
-
"default": "warning"
|
|
215
|
-
},
|
|
216
|
-
"no-dup-class": {
|
|
217
|
-
"$ref": "#/definitions/severity",
|
|
218
|
-
"description": "Detect duplicate class names in class attribute",
|
|
219
|
-
"default": "warning"
|
|
220
|
-
},
|
|
221
|
-
"no-default-value": {
|
|
222
|
-
"$ref": "#/definitions/severity",
|
|
223
|
-
"description": "Disallow default attribute values (auto-fixable)",
|
|
224
|
-
"default": "warning"
|
|
225
|
-
},
|
|
226
|
-
"no-duplicate-landmark": {
|
|
227
|
-
"$ref": "#/definitions/severity",
|
|
228
|
-
"description": "Require aria-label on duplicate landmarks",
|
|
229
|
-
"default": "warning"
|
|
230
|
-
},
|
|
231
|
-
"no-duplicate-in-head": {
|
|
232
|
-
"$ref": "#/definitions/severity",
|
|
233
|
-
"description": "Disallow duplicate charset, viewport, or description meta elements",
|
|
234
|
-
"default": "error"
|
|
235
|
-
},
|
|
236
|
-
"no-duplicate-base": {
|
|
237
|
-
"$ref": "#/definitions/severity",
|
|
238
|
-
"description": "Disallow multiple base or title elements in the document",
|
|
239
|
-
"default": "error"
|
|
240
|
-
},
|
|
241
|
-
"no-duplicate-dt": {
|
|
242
|
-
"$ref": "#/definitions/severity",
|
|
243
|
-
"description": "Disallow duplicate dt elements in a dl",
|
|
244
|
-
"default": "error"
|
|
245
|
-
},
|
|
246
|
-
"no-empty-track-label": {
|
|
247
|
-
"$ref": "#/definitions/severity",
|
|
248
|
-
"description": "Disallow empty label attribute on track elements",
|
|
249
|
-
"default": "warning"
|
|
250
|
-
},
|
|
251
|
-
"no-empty-palpable-content": {
|
|
252
|
-
"$ref": "#/definitions/severity",
|
|
253
|
-
"description": "Disallow empty interactive or palpable content elements",
|
|
254
|
-
"default": "warning"
|
|
255
|
-
},
|
|
256
|
-
"no-javascript-url": {
|
|
257
|
-
"$ref": "#/definitions/severity",
|
|
258
|
-
"description": "Detect javascript: URLs in href attributes",
|
|
259
|
-
"default": "error"
|
|
260
|
-
},
|
|
261
|
-
"no-hard-code-id": {
|
|
262
|
-
"$ref": "#/definitions/severity",
|
|
263
|
-
"description": "Disallow hardcoded id attributes (opt-in)",
|
|
264
|
-
"default": "off"
|
|
265
|
-
},
|
|
266
|
-
"no-obsolete-doctype": {
|
|
267
|
-
"$ref": "#/definitions/severity",
|
|
268
|
-
"description": "Detect legacy XHTML/HTML4 doctypes",
|
|
269
|
-
"default": "warning"
|
|
270
|
-
},
|
|
271
|
-
"no-nested-forms": {
|
|
272
|
-
"$ref": "#/definitions/severity",
|
|
273
|
-
"description": "Disallow nested form elements",
|
|
274
|
-
"default": "error"
|
|
275
|
-
},
|
|
276
|
-
"no-nested-interactive": {
|
|
277
|
-
"$ref": "#/definitions/severity",
|
|
278
|
-
"description": "Disallow interactive content inside a or button elements",
|
|
279
|
-
"default": "error"
|
|
280
|
-
},
|
|
281
|
-
"no-implicit-button-type": {
|
|
282
|
-
"$ref": "#/definitions/severity",
|
|
283
|
-
"description": "Require explicit type attribute on button elements",
|
|
284
|
-
"default": "warning"
|
|
285
|
-
},
|
|
286
|
-
"no-inline-style": {
|
|
287
|
-
"$ref": "#/definitions/severity",
|
|
288
|
-
"description": "Disallow inline style attributes",
|
|
289
|
-
"default": "warning"
|
|
290
|
-
},
|
|
291
|
-
"no-non-scalable-viewport": {
|
|
292
|
-
"$ref": "#/definitions/severity",
|
|
293
|
-
"description": "Disallow user-scalable=no or maximum-scale=1 in viewport meta",
|
|
294
|
-
"default": "error"
|
|
295
|
-
},
|
|
296
|
-
"no-target-blank-without-rel": {
|
|
297
|
-
"$ref": "#/definitions/severity",
|
|
298
|
-
"description": "Require rel=\"noopener\" on target=\"_blank\" anchors",
|
|
299
|
-
"default": "warning"
|
|
300
|
-
},
|
|
301
|
-
"no-orphaned-end-tag": {
|
|
302
|
-
"$ref": "#/definitions/severity",
|
|
303
|
-
"description": "Disallow unmatched closing tags",
|
|
304
|
-
"default": "error"
|
|
305
|
-
},
|
|
306
|
-
"no-tabindex-on-dialog": {
|
|
307
|
-
"$ref": "#/definitions/severity",
|
|
308
|
-
"description": "Disallow tabindex attribute on dialog elements",
|
|
309
|
-
"default": "error"
|
|
310
|
-
},
|
|
311
|
-
"no-refer-to-non-existent-id": {
|
|
312
|
-
"$ref": "#/definitions/severity",
|
|
313
|
-
"description": "Disallow references to non-existent id values",
|
|
314
|
-
"default": "error"
|
|
315
|
-
},
|
|
316
|
-
"no-redundant-role": {
|
|
317
|
-
"$ref": "#/definitions/severity",
|
|
318
|
-
"description": "Detect redundant explicit ARIA roles matching implicit role",
|
|
319
|
-
"default": "warning"
|
|
320
|
-
},
|
|
321
|
-
"no-role-on-meta-elements": {
|
|
322
|
-
"$ref": "#/definitions/severity",
|
|
323
|
-
"description": "Disallow role and aria-* attributes on meta elements",
|
|
324
|
-
"default": "error"
|
|
325
|
-
},
|
|
326
|
-
"no-positive-tabindex": {
|
|
327
|
-
"$ref": "#/definitions/severity",
|
|
328
|
-
"description": "Disallow positive tabindex values",
|
|
329
|
-
"default": "warning"
|
|
330
|
-
},
|
|
331
|
-
"no-use-event-handler-attr": {
|
|
332
|
-
"$ref": "#/definitions/severity",
|
|
333
|
-
"description": "Disallow inline event handler attributes",
|
|
334
|
-
"default": "warning"
|
|
335
|
-
},
|
|
336
|
-
"obsolete-but-conforming": {
|
|
337
|
-
"$ref": "#/definitions/severity",
|
|
338
|
-
"description": "Warn about obsolete but conforming features",
|
|
339
|
-
"default": "warning"
|
|
340
|
-
},
|
|
341
|
-
"script-type": {
|
|
342
|
-
"$ref": "#/definitions/severity",
|
|
343
|
-
"description": "Validate script type attribute values",
|
|
344
|
-
"default": "error"
|
|
345
|
-
},
|
|
346
|
-
"src-not-empty": {
|
|
347
|
-
"$ref": "#/definitions/severity",
|
|
348
|
-
"description": "Disallow empty src or href attributes",
|
|
349
|
-
"default": "error"
|
|
350
|
-
},
|
|
351
|
-
"picture-structure": {
|
|
352
|
-
"$ref": "#/definitions/severity",
|
|
353
|
-
"description": "Validate picture element structure",
|
|
354
|
-
"default": "error"
|
|
355
|
-
},
|
|
356
|
-
"permitted-contents": {
|
|
357
|
-
"$ref": "#/definitions/severity",
|
|
358
|
-
"description": "Enforce HTML content model restrictions",
|
|
359
|
-
"default": "error"
|
|
360
|
-
},
|
|
361
|
-
"placeholder-label-option": {
|
|
362
|
-
"$ref": "#/definitions/severity",
|
|
363
|
-
"description": "Require placeholder option in select elements with required attribute",
|
|
364
|
-
"default": "warning"
|
|
365
|
-
},
|
|
366
|
-
"require-accessible-name": {
|
|
367
|
-
"$ref": "#/definitions/severity",
|
|
368
|
-
"description": "Require accessible names for interactive elements",
|
|
369
|
-
"default": "error"
|
|
370
|
-
},
|
|
371
|
-
"require-datetime": {
|
|
372
|
-
"$ref": "#/definitions/severity",
|
|
373
|
-
"description": "Require datetime attribute on time elements",
|
|
374
|
-
"default": "error"
|
|
375
|
-
},
|
|
376
|
-
"required-attr": {
|
|
377
|
-
"$ref": "#/definitions/severity",
|
|
378
|
-
"description": "Require specification-mandated attributes",
|
|
379
|
-
"default": "error"
|
|
380
|
-
},
|
|
381
|
-
"required-element": {
|
|
382
|
-
"$ref": "#/definitions/severity",
|
|
383
|
-
"description": "Require specification-mandated child elements",
|
|
384
|
-
"default": "error"
|
|
385
|
-
},
|
|
386
|
-
"require-meta-charset": {
|
|
387
|
-
"$ref": "#/definitions/severity",
|
|
388
|
-
"description": "Require meta charset declaration in the document",
|
|
389
|
-
"default": "off"
|
|
390
|
-
},
|
|
391
|
-
"required-h1": {
|
|
392
|
-
"$ref": "#/definitions/severity",
|
|
393
|
-
"description": "Require exactly one h1 element per document",
|
|
394
|
-
"default": "error"
|
|
395
|
-
},
|
|
396
|
-
"summary-first-child": {
|
|
397
|
-
"$ref": "#/definitions/severity",
|
|
398
|
-
"description": "Require summary to be the first child of details",
|
|
399
|
-
"default": "error"
|
|
400
|
-
},
|
|
401
|
-
"table-has-caption": {
|
|
402
|
-
"$ref": "#/definitions/severity",
|
|
403
|
-
"description": "Require caption element on data tables",
|
|
404
|
-
"default": "warning"
|
|
405
|
-
},
|
|
406
|
-
"table-row-column-alignment": {
|
|
407
|
-
"$ref": "#/definitions/severity",
|
|
408
|
-
"description": "Require consistent column counts in table rows",
|
|
409
|
-
"default": "warning"
|
|
410
|
-
},
|
|
411
|
-
"th-content-restrictions": {
|
|
412
|
-
"$ref": "#/definitions/severity",
|
|
413
|
-
"description": "Disallow header, footer, sectioning, and heading elements inside th",
|
|
414
|
-
"default": "error"
|
|
415
|
-
},
|
|
416
|
-
"track-has-srclang": {
|
|
417
|
-
"$ref": "#/definitions/severity",
|
|
418
|
-
"description": "Require srclang on subtitles track elements",
|
|
419
|
-
"default": "error"
|
|
420
|
-
},
|
|
421
|
-
"unique-main": {
|
|
422
|
-
"$ref": "#/definitions/severity",
|
|
423
|
-
"description": "Require at most one visible main element per document",
|
|
424
|
-
"default": "error"
|
|
425
|
-
},
|
|
426
|
-
"use-list": {
|
|
427
|
-
"$ref": "#/definitions/severity",
|
|
428
|
-
"description": "Suggest using list elements for bullet-like text patterns",
|
|
429
|
-
"default": "warning"
|
|
430
|
-
},
|
|
431
|
-
"valid-id": {
|
|
432
|
-
"$ref": "#/definitions/severity",
|
|
433
|
-
"description": "Require valid id attribute values (non-empty, no whitespace)",
|
|
434
|
-
"default": "error"
|
|
435
|
-
},
|
|
436
|
-
"void-content": {
|
|
437
|
-
"$ref": "#/definitions/severity",
|
|
438
|
-
"description": "Disallow content inside void elements",
|
|
439
|
-
"default": "error"
|
|
440
|
-
},
|
|
441
|
-
"valid-attr-value": {
|
|
442
|
-
"$ref": "#/definitions/severity",
|
|
443
|
-
"description": "Validate enumerated attribute values",
|
|
444
|
-
"default": "error"
|
|
445
|
-
},
|
|
446
|
-
"valid-autocomplete": {
|
|
447
|
-
"$ref": "#/definitions/severity",
|
|
448
|
-
"description": "Validate autocomplete attribute values on form elements",
|
|
449
|
-
"default": "warning"
|
|
450
|
-
},
|
|
451
|
-
"valid-rel": {
|
|
452
|
-
"$ref": "#/definitions/severity",
|
|
453
|
-
"description": "Validate rel attribute values for a, area, link, and form elements",
|
|
454
|
-
"default": "error"
|
|
455
|
-
},
|
|
456
|
-
"wai-aria": {
|
|
457
|
-
"$ref": "#/definitions/severity",
|
|
458
|
-
"description": "Validate WAI-ARIA roles and attributes",
|
|
459
|
-
"default": "error"
|
|
460
|
-
},
|
|
461
|
-
"no-duplicate-track": {
|
|
462
|
-
"$ref": "#/definitions/severity",
|
|
463
|
-
"description": "Disallow duplicate track elements with same kind, srclang, and label",
|
|
464
|
-
"default": "error"
|
|
465
|
-
},
|
|
466
|
-
"no-multiple-default-track": {
|
|
467
|
-
"$ref": "#/definitions/severity",
|
|
468
|
-
"description": "Disallow multiple default track elements in the same category",
|
|
469
|
-
"default": "error"
|
|
470
|
-
},
|
|
471
|
-
"base-before-urls": {
|
|
472
|
-
"$ref": "#/definitions/severity",
|
|
473
|
-
"description": "Require base href to appear before elements with URL attributes",
|
|
474
|
-
"default": "warning"
|
|
475
|
-
},
|
|
476
|
-
"address-content-model": {
|
|
477
|
-
"$ref": "#/definitions/severity",
|
|
478
|
-
"description": "Disallow heading, sectioning, header, footer, address inside address",
|
|
479
|
-
"default": "error"
|
|
480
|
-
},
|
|
481
|
-
"link-rel-or-itemprop": {
|
|
482
|
-
"$ref": "#/definitions/severity",
|
|
483
|
-
"description": "Require link to have rel or itemprop attribute",
|
|
484
|
-
"default": "error"
|
|
485
|
-
},
|
|
486
|
-
"base-has-href-or-target": {
|
|
487
|
-
"$ref": "#/definitions/severity",
|
|
488
|
-
"description": "Require base to have at least href or target attribute",
|
|
489
|
-
"default": "error"
|
|
490
|
-
},
|
|
491
|
-
"no-aria-disabled-link": {
|
|
492
|
-
"$ref": "#/definitions/severity",
|
|
493
|
-
"description": "Disallow aria-disabled on anchor elements with href",
|
|
494
|
-
"default": "warning"
|
|
495
|
-
},
|
|
496
|
-
"no-generic-role": {
|
|
497
|
-
"$ref": "#/definitions/severity",
|
|
498
|
-
"description": "Disallow explicit role=\"generic\"",
|
|
499
|
-
"default": "warning"
|
|
500
|
-
},
|
|
501
|
-
"no-aria-checked-mismatch": {
|
|
502
|
-
"$ref": "#/definitions/severity",
|
|
503
|
-
"description": "Disallow aria-checked on checkbox/radio with checked attribute",
|
|
504
|
-
"default": "warning"
|
|
505
|
-
},
|
|
506
|
-
"th-has-scope": {
|
|
507
|
-
"$ref": "#/definitions/severity",
|
|
508
|
-
"description": "Require scope attribute on th elements",
|
|
509
|
-
"default": "warning"
|
|
510
|
-
},
|
|
511
|
-
"prefer-native-over-aria": {
|
|
512
|
-
"$ref": "#/definitions/severity",
|
|
513
|
-
"description": "Prefer native HTML elements over ARIA roles",
|
|
514
|
-
"default": "warning"
|
|
515
|
-
},
|
|
516
|
-
"no-duplicate-accesskey": {
|
|
517
|
-
"$ref": "#/definitions/severity",
|
|
518
|
-
"description": "Disallow duplicate accesskey values in the document",
|
|
519
|
-
"default": "warning"
|
|
520
|
-
},
|
|
521
|
-
"no-form-without-action": {
|
|
522
|
-
"$ref": "#/definitions/severity",
|
|
523
|
-
"description": "Warn when form element has no action attribute",
|
|
524
|
-
"default": "warning"
|
|
525
|
-
}
|
|
526
|
-
},
|
|
527
|
-
"additionalProperties": {
|
|
528
|
-
"$ref": "#/definitions/severity"
|
|
529
|
-
}
|
|
530
|
-
},
|
|
531
|
-
"ignore": {
|
|
532
|
-
"type": "array",
|
|
533
|
-
"description": "Glob patterns for files to exclude from linting",
|
|
534
|
-
"items": {
|
|
535
|
-
"type": "string"
|
|
536
|
-
}
|
|
537
|
-
},
|
|
538
|
-
"parser": {
|
|
539
|
-
"type": "object",
|
|
540
|
-
"description": "File extension to parser package mapping (e.g. { \".vue\": \"@rintenki/vue-parser\" })",
|
|
541
|
-
"additionalProperties": {
|
|
542
|
-
"type": "string"
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
},
|
|
546
|
-
"additionalProperties": false,
|
|
547
|
-
"definitions": {
|
|
548
|
-
"severity": {
|
|
549
|
-
"oneOf": [
|
|
550
|
-
{
|
|
551
|
-
"type": "string",
|
|
552
|
-
"enum": ["error", "warning", "warn", "off"]
|
|
553
|
-
},
|
|
554
|
-
{
|
|
555
|
-
"type": "boolean"
|
|
556
|
-
}
|
|
557
|
-
],
|
|
558
|
-
"description": "Rule severity: \"error\", \"warning\"/\"warn\", \"off\", true (default severity), or false (off)"
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
}
|