markuplint 3.0.0-alpha.66 → 3.0.0-dev.24
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 +24 -20
- package/lib/api/ml-engine.d.ts +10 -8
- package/lib/api/ml-engine.js +81 -69
- package/lib/api/types.d.ts +6 -5
- package/lib/cli/bootstrap.d.ts +2 -2
- package/lib/cli/bootstrap.js +1 -1
- package/lib/cli/command.js +15 -1
- package/lib/cli/create-rule/index.js +16 -7
- package/lib/cli/index.js +4 -1
- package/lib/cli/init/index.js +9 -1
- package/lib/cli/init/install-module.d.ts +1 -1
- package/lib/cli/init/install-module.js +3 -0
- package/lib/cli/output.js +0 -1
- package/lib/cli/prompt.d.ts +1 -1
- package/lib/global-settings.d.ts +1 -1
- package/lib/i18n.d.ts +2 -6
- package/lib/i18n.js +2 -1
- package/lib/types.d.ts +1 -1
- package/lib/util.d.ts +1 -1
- package/lib/util.js +11 -5
- package/package.json +19 -19
- package/tsconfig.tsbuildinfo +1 -1
- package/.markuplintrc +0 -19
package/README.md
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
# 
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/markuplint)
|
|
4
|
+
[](https://www.npmjs.com/package/markuplint)
|
|
4
5
|
[](https://github.com/markuplint/markuplint/actions?query=workflow%3ATest)
|
|
5
6
|
[](https://coveralls.io/github/markuplint/markuplint?branch=main)
|
|
7
|
+
[](https://github.com/markuplint/markuplint)
|
|
8
|
+
[](https://twitter.com/intent/user?screen_name=markuplint)
|
|
6
9
|
|
|
7
|
-
Peace of mind in your markup - A
|
|
10
|
+
**Peace of mind in your markup** - A linter for all markup developers.
|
|
8
11
|
|
|
9
12
|
## Features
|
|
10
13
|
|
|
11
|
-
- Conformance checking
|
|
12
|
-
- Supports
|
|
13
|
-
- Supports
|
|
14
|
-
- Possible to specify the rule
|
|
15
|
-
-
|
|
14
|
+
- Conformance checking according to _HTML Standard_, _WAI-ARIA_, _ARIA in HTML_, etc.
|
|
15
|
+
- Supports _CSS_ and _SVG_ values.
|
|
16
|
+
- Supports _React_, _Vue_, _Svelte_, _Pug_, _PHP_, and more.
|
|
17
|
+
- Possible to specify the rule for each element if you use _CSS Selector_.
|
|
18
|
+
- Potential to create a custom rule.
|
|
16
19
|
|
|
17
20
|

|
|
18
21
|
|
|
@@ -22,7 +25,7 @@ Peace of mind in your markup - A Linter for All Markup Languages.
|
|
|
22
25
|
$ npx markuplint target.html
|
|
23
26
|
```
|
|
24
27
|
|
|
25
|
-
Supported for _Node.js_ `
|
|
28
|
+
Supported for _Node.js_ `v14.6.0` or later.
|
|
26
29
|
|
|
27
30
|
## Usage
|
|
28
31
|
|
|
@@ -37,7 +40,7 @@ $ yarn run markuplint --init
|
|
|
37
40
|
```
|
|
38
41
|
|
|
39
42
|
Answer questions interactively.
|
|
40
|
-
By doing this, needed modules are installed
|
|
43
|
+
By doing this, needed modules are installed, including `markuplint`.
|
|
41
44
|
|
|
42
45
|
Add a command to the `scripts` option on `package.json`:
|
|
43
46
|
|
|
@@ -65,7 +68,7 @@ $ yarn html:lint
|
|
|
65
68
|
$ npx markuplint --help
|
|
66
69
|
|
|
67
70
|
Usage
|
|
68
|
-
$ markuplint <HTML file
|
|
71
|
+
$ markuplint <HTML file paths (glob format)>
|
|
69
72
|
$ <stdout> | markuplint
|
|
70
73
|
|
|
71
74
|
Options
|
|
@@ -91,32 +94,33 @@ Examples
|
|
|
91
94
|
$ cat verifyee.html | markuplint
|
|
92
95
|
```
|
|
93
96
|
|
|
94
|
-
##
|
|
97
|
+
## Documentation
|
|
95
98
|
|
|
96
99
|
- [Getting Started](https://markuplint.dev/getting-started)
|
|
97
100
|
- [Rules](https://markuplint.dev/rules)
|
|
98
101
|
- [Configuration](https://markuplint.dev/configuration)
|
|
99
102
|
- [API](https://markuplint.dev/api-docs)
|
|
103
|
+
|
|
104
|
+
## Playground
|
|
105
|
+
|
|
100
106
|
- [Playground](https://playground.markuplint.dev/)
|
|
101
107
|
|
|
102
108
|
## Editor Extensions
|
|
103
109
|
|
|
104
|
-
|
|
105
|
-
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
|
|
106
|
-
| <a href="https://marketplace.visualstudio.com/items?itemName=yusukehirao.vscode-markuplint"><img src="https://raw.githubusercontent.com/markuplint/markuplint/main/media/vscode.png" width="75" height="82" alt="Visual Studio Code: markuplint extension"></a> | [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=yusukehirao.vscode-markuplint) | [@YusukeHirao](https://github.com/YusukeHirao) |
|
|
110
|
+
- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=yusukehirao.vscode-markuplint)
|
|
107
111
|
|
|
108
112
|
## License
|
|
109
113
|
|
|
110
|
-
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fmarkuplint%2Fmarkuplint?ref=badge_large)
|
|
111
115
|
|
|
112
116
|
## Sponsors
|
|
113
117
|
|
|
114
|
-
[
|
|
118
|
+
Need [Sponsors❤️🔥](https://github.com/sponsors/markuplint)
|
|
115
119
|
|
|
116
120
|
### Personal Supporters
|
|
117
121
|
|
|
118
|
-
[<img width="36" src="https://avatars.githubusercontent.com/u/
|
|
119
|
-
[<img width="36" src="https://avatars.githubusercontent.com/u/
|
|
122
|
+
[<img width="36" src="https://avatars.githubusercontent.com/u/91733847" alt="Tokitake" />](https://github.com/Tokitake)
|
|
123
|
+
[<img width="36" src="https://avatars.githubusercontent.com/u/1996642" alt="yamanoku" />](https://github.com/yamanoku)
|
|
120
124
|
|
|
121
125
|
## Thanks
|
|
122
126
|
|
|
@@ -124,5 +128,5 @@ This linter is inspired by:
|
|
|
124
128
|
|
|
125
129
|
- [HTMLHint](http://htmlhint.com/)
|
|
126
130
|
- [ESLint](https://eslint.org/)
|
|
127
|
-
- [
|
|
131
|
+
- [Stylelint](https://stylelint.io/)
|
|
128
132
|
- [textlint](https://textlint.github.io/)
|
package/lib/api/ml-engine.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { MLResultInfo } from '../types';
|
|
2
2
|
import type { APIOptions, MLEngineEventMap } from './types';
|
|
3
3
|
import type { MLFile, Target } from '@markuplint/file-resolver';
|
|
4
|
+
import type { Document, RuleConfigValue } from '@markuplint/ml-core';
|
|
4
5
|
import { StrictEventEmitter } from 'strict-event-emitter';
|
|
5
|
-
|
|
6
|
+
type MLEngineOptions = {
|
|
6
7
|
debug?: boolean;
|
|
7
8
|
watch?: boolean;
|
|
8
9
|
};
|
|
@@ -10,19 +11,20 @@ export default class MLEngine extends StrictEventEmitter<MLEngineEventMap> {
|
|
|
10
11
|
#private;
|
|
11
12
|
static toMLFile(target: Target): Promise<MLFile>;
|
|
12
13
|
constructor(file: MLFile, options?: APIOptions & MLEngineOptions);
|
|
13
|
-
|
|
14
|
+
get document(): Document<RuleConfigValue, unknown> | null;
|
|
15
|
+
close(): Promise<void>;
|
|
14
16
|
exec(): Promise<MLResultInfo | null>;
|
|
15
17
|
setCode(code: string): Promise<void>;
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
+
watchMode(enable: boolean): void;
|
|
19
|
+
private createCore;
|
|
20
|
+
private i18n;
|
|
21
|
+
private onChange;
|
|
18
22
|
private provide;
|
|
19
|
-
private cretateCore;
|
|
20
23
|
private resolveConfig;
|
|
21
24
|
private resolveParser;
|
|
25
|
+
private resolveRules;
|
|
22
26
|
private resolveRuleset;
|
|
23
27
|
private resolveSchemas;
|
|
24
|
-
private
|
|
25
|
-
private i18n;
|
|
26
|
-
private onChange;
|
|
28
|
+
private setup;
|
|
27
29
|
}
|
|
28
30
|
export {};
|
package/lib/api/ml-engine.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
2
|
+
var _MLEngine_configProvider, _MLEngine_core, _MLEngine_file, _MLEngine_options, _MLEngine_watcher;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const file_resolver_1 = require("@markuplint/file-resolver");
|
|
@@ -11,14 +11,18 @@ const i18n_1 = require("../i18n");
|
|
|
11
11
|
const log = debug_1.log.extend('ml-engine');
|
|
12
12
|
const fileLog = log.extend('file');
|
|
13
13
|
class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
14
|
+
static async toMLFile(target) {
|
|
15
|
+
const files = await (0, file_resolver_1.resolveFiles)([target]);
|
|
16
|
+
return files[0];
|
|
17
|
+
}
|
|
14
18
|
constructor(file, options) {
|
|
15
19
|
var _a, _b;
|
|
16
20
|
super();
|
|
21
|
+
_MLEngine_configProvider.set(this, void 0);
|
|
22
|
+
_MLEngine_core.set(this, null);
|
|
17
23
|
_MLEngine_file.set(this, void 0);
|
|
18
24
|
_MLEngine_options.set(this, void 0);
|
|
19
|
-
_MLEngine_core.set(this, null);
|
|
20
25
|
_MLEngine_watcher.set(this, new chokidar_1.FSWatcher());
|
|
21
|
-
_MLEngine_configProvider.set(this, void 0);
|
|
22
26
|
tslib_1.__classPrivateFieldSet(this, _MLEngine_file, file, "f");
|
|
23
27
|
tslib_1.__classPrivateFieldSet(this, _MLEngine_options, options, "f");
|
|
24
28
|
tslib_1.__classPrivateFieldSet(this, _MLEngine_configProvider, new file_resolver_1.ConfigProvider(), "f");
|
|
@@ -27,21 +31,16 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
|
27
31
|
(0, debug_1.verbosely)();
|
|
28
32
|
}
|
|
29
33
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
watchMode(enable) {
|
|
35
|
-
tslib_1.__classPrivateFieldSet(this, _MLEngine_options, {
|
|
36
|
-
...tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f"),
|
|
37
|
-
watch: enable,
|
|
38
|
-
}, "f");
|
|
39
|
-
if (enable) {
|
|
40
|
-
tslib_1.__classPrivateFieldGet(this, _MLEngine_watcher, "f").on('change', this.onChange.bind(this));
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
tslib_1.__classPrivateFieldGet(this, _MLEngine_watcher, "f").removeAllListeners();
|
|
34
|
+
get document() {
|
|
35
|
+
var _a, _b, _c;
|
|
36
|
+
if (((_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_core, "f")) === null || _a === void 0 ? void 0 : _a.document) instanceof Error) {
|
|
37
|
+
return null;
|
|
44
38
|
}
|
|
39
|
+
return (_c = (_b = tslib_1.__classPrivateFieldGet(this, _MLEngine_core, "f")) === null || _b === void 0 ? void 0 : _b.document) !== null && _c !== void 0 ? _c : null;
|
|
40
|
+
}
|
|
41
|
+
async close() {
|
|
42
|
+
this.removeAllListeners();
|
|
43
|
+
await tslib_1.__classPrivateFieldGet(this, _MLEngine_watcher, "f").close();
|
|
45
44
|
}
|
|
46
45
|
async exec() {
|
|
47
46
|
var _a, _b;
|
|
@@ -97,25 +96,60 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
|
97
96
|
tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").setCode(code);
|
|
98
97
|
core.setCode(code);
|
|
99
98
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
watchMode(enable) {
|
|
100
|
+
tslib_1.__classPrivateFieldSet(this, _MLEngine_options, {
|
|
101
|
+
...tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f"),
|
|
102
|
+
watch: enable,
|
|
103
|
+
}, "f");
|
|
104
|
+
if (enable) {
|
|
105
|
+
tslib_1.__classPrivateFieldGet(this, _MLEngine_watcher, "f").on('change', this.onChange.bind(this));
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
tslib_1.__classPrivateFieldGet(this, _MLEngine_watcher, "f").removeAllListeners();
|
|
109
|
+
}
|
|
103
110
|
}
|
|
104
|
-
async
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
async createCore(fabric) {
|
|
112
|
+
var _a;
|
|
113
|
+
fileLog('Get source code');
|
|
114
|
+
const sourceCode = await tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").getCode();
|
|
115
|
+
fileLog('Source code path: %s', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path);
|
|
116
|
+
// cspell: disable-next-line
|
|
117
|
+
fileLog('Source code size: %dbyte', sourceCode.length);
|
|
118
|
+
this.emit('code', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, sourceCode);
|
|
119
|
+
const core = new ml_core_1.MLCore({
|
|
120
|
+
sourceCode,
|
|
121
|
+
filename: tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path,
|
|
122
|
+
debug: (_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _a === void 0 ? void 0 : _a.debug,
|
|
123
|
+
...fabric,
|
|
124
|
+
});
|
|
125
|
+
tslib_1.__classPrivateFieldSet(this, _MLEngine_core, core, "f");
|
|
126
|
+
return core;
|
|
127
|
+
}
|
|
128
|
+
async i18n() {
|
|
129
|
+
var _a;
|
|
130
|
+
const i18nSettings = await (0, i18n_1.i18n)((_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _a === void 0 ? void 0 : _a.locale);
|
|
131
|
+
this.emit('i18n', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, i18nSettings);
|
|
132
|
+
return i18nSettings;
|
|
133
|
+
}
|
|
134
|
+
async onChange(filePath) {
|
|
135
|
+
var _a, _b;
|
|
136
|
+
if (!((_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _a === void 0 ? void 0 : _a.watch)) {
|
|
137
|
+
return;
|
|
107
138
|
}
|
|
108
|
-
|
|
139
|
+
this.emit('log', 'watch:onChange', filePath);
|
|
140
|
+
const fabric = await this.provide(false);
|
|
109
141
|
if (!fabric) {
|
|
110
|
-
return
|
|
142
|
+
return;
|
|
111
143
|
}
|
|
112
144
|
if (fabric.configErrors) {
|
|
113
145
|
this.emit('config-errors', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, fabric.configErrors);
|
|
114
146
|
}
|
|
115
|
-
|
|
147
|
+
this.emit('log', 'update:core', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path);
|
|
148
|
+
(_b = tslib_1.__classPrivateFieldGet(this, _MLEngine_core, "f")) === null || _b === void 0 ? void 0 : _b.update(fabric);
|
|
149
|
+
await this.exec();
|
|
116
150
|
}
|
|
117
151
|
async provide(cache = true) {
|
|
118
|
-
var _a, _b;
|
|
152
|
+
var _a, _b, _c;
|
|
119
153
|
const configSet = await this.resolveConfig(cache);
|
|
120
154
|
fileLog('Fetched Config files: %O', configSet.files);
|
|
121
155
|
fileLog('Resolved Config: %O', configSet.config);
|
|
@@ -123,6 +157,7 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
|
123
157
|
fileLog('Resolve Errors: %O', configSet.errs);
|
|
124
158
|
if (!(await tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").isFile())) {
|
|
125
159
|
this.emit('log', 'file-no-exists', `The file doesn't exist or it is not a file: ${tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path}`);
|
|
160
|
+
fileLog("The file doesn't exist or it is not a file: %s", tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path);
|
|
126
161
|
return null;
|
|
127
162
|
}
|
|
128
163
|
// Exclude
|
|
@@ -130,6 +165,7 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
|
130
165
|
for (const excludeFile of excludeFiles) {
|
|
131
166
|
if (tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").matches(excludeFile)) {
|
|
132
167
|
this.emit('exclude', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, excludeFile);
|
|
168
|
+
fileLog('Excludes the file: %s', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path);
|
|
133
169
|
return null;
|
|
134
170
|
}
|
|
135
171
|
}
|
|
@@ -137,6 +173,7 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
|
137
173
|
const checkingExt = !((_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _a === void 0 ? void 0 : _a.ignoreExt);
|
|
138
174
|
if (checkingExt && !matched) {
|
|
139
175
|
this.emit('log', 'ext-unmatched', `Avoided linting because a file is unmatched by the extension: ${tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path}`);
|
|
176
|
+
fileLog('Avoided linting because a file is unmatched by the extension: %s', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path);
|
|
140
177
|
return null;
|
|
141
178
|
}
|
|
142
179
|
const ruleset = this.resolveRuleset(configSet);
|
|
@@ -163,6 +200,7 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
|
163
200
|
return {
|
|
164
201
|
parser,
|
|
165
202
|
parserOptions,
|
|
203
|
+
pretenders: (_c = configSet.config.pretenders) !== null && _c !== void 0 ? _c : [],
|
|
166
204
|
ruleset,
|
|
167
205
|
schemas,
|
|
168
206
|
rules,
|
|
@@ -170,22 +208,6 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
|
170
208
|
configErrors: configSet.errs,
|
|
171
209
|
};
|
|
172
210
|
}
|
|
173
|
-
async cretateCore(fabric) {
|
|
174
|
-
var _a;
|
|
175
|
-
fileLog('Get source code');
|
|
176
|
-
const sourceCode = await tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").getCode();
|
|
177
|
-
fileLog('Source code path: %s', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path);
|
|
178
|
-
fileLog('Source code size: %dbyte', sourceCode.length);
|
|
179
|
-
this.emit('code', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, sourceCode);
|
|
180
|
-
const core = new ml_core_1.MLCore({
|
|
181
|
-
sourceCode,
|
|
182
|
-
filename: tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path,
|
|
183
|
-
debug: (_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _a === void 0 ? void 0 : _a.debug,
|
|
184
|
-
...fabric,
|
|
185
|
-
});
|
|
186
|
-
tslib_1.__classPrivateFieldSet(this, _MLEngine_core, core, "f");
|
|
187
|
-
return core;
|
|
188
|
-
}
|
|
189
211
|
async resolveConfig(cache) {
|
|
190
212
|
var _a, _b, _c, _d, _e, _f;
|
|
191
213
|
const defaultConfigKey = ((_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _a === void 0 ? void 0 : _a.defaultConfig) && tslib_1.__classPrivateFieldGet(this, _MLEngine_configProvider, "f").set((_b = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _b === void 0 ? void 0 : _b.defaultConfig);
|
|
@@ -209,16 +231,6 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
|
209
231
|
fileLog('Fetched Parser module: %s', parser.parserModName);
|
|
210
232
|
return parser;
|
|
211
233
|
}
|
|
212
|
-
resolveRuleset(configSet) {
|
|
213
|
-
const ruleset = (0, ml_core_1.convertRuleset)(configSet.config);
|
|
214
|
-
this.emit('ruleset', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, ruleset);
|
|
215
|
-
return ruleset;
|
|
216
|
-
}
|
|
217
|
-
async resolveSchemas(configSet) {
|
|
218
|
-
const { schemas } = await (0, file_resolver_1.resolveSpecs)(tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, configSet.config.specs);
|
|
219
|
-
this.emit('schemas', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, schemas);
|
|
220
|
-
return schemas;
|
|
221
|
-
}
|
|
222
234
|
async resolveRules(plugins, ruleset) {
|
|
223
235
|
var _a, _b, _c, _d, _e;
|
|
224
236
|
const rules = await (0, file_resolver_1.resolveRules)(plugins, ruleset, (_b = (_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _a === void 0 ? void 0 : _a.importPresetRules) !== null && _b !== void 0 ? _b : true, (_d = (_c = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _c === void 0 ? void 0 : _c.autoLoad) !== null && _d !== void 0 ? _d : true);
|
|
@@ -228,29 +240,29 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
|
|
|
228
240
|
this.emit('rules', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, rules);
|
|
229
241
|
return rules;
|
|
230
242
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return i18nSettings;
|
|
243
|
+
resolveRuleset(configSet) {
|
|
244
|
+
const ruleset = (0, ml_core_1.convertRuleset)(configSet.config);
|
|
245
|
+
this.emit('ruleset', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, ruleset);
|
|
246
|
+
return ruleset;
|
|
236
247
|
}
|
|
237
|
-
async
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
248
|
+
async resolveSchemas(configSet) {
|
|
249
|
+
const { schemas } = await (0, file_resolver_1.resolveSpecs)(tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, configSet.config.specs);
|
|
250
|
+
this.emit('schemas', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, schemas);
|
|
251
|
+
return schemas;
|
|
252
|
+
}
|
|
253
|
+
async setup() {
|
|
254
|
+
if (tslib_1.__classPrivateFieldGet(this, _MLEngine_core, "f")) {
|
|
255
|
+
return tslib_1.__classPrivateFieldGet(this, _MLEngine_core, "f");
|
|
241
256
|
}
|
|
242
|
-
this.
|
|
243
|
-
const fabric = await this.provide(false);
|
|
257
|
+
const fabric = await this.provide();
|
|
244
258
|
if (!fabric) {
|
|
245
|
-
return;
|
|
259
|
+
return null;
|
|
246
260
|
}
|
|
247
261
|
if (fabric.configErrors) {
|
|
248
262
|
this.emit('config-errors', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, fabric.configErrors);
|
|
249
263
|
}
|
|
250
|
-
this.
|
|
251
|
-
(_b = tslib_1.__classPrivateFieldGet(this, _MLEngine_core, "f")) === null || _b === void 0 ? void 0 : _b.update(fabric);
|
|
252
|
-
await this.exec();
|
|
264
|
+
return this.createCore(fabric);
|
|
253
265
|
}
|
|
254
266
|
}
|
|
255
267
|
exports.default = MLEngine;
|
|
256
|
-
|
|
268
|
+
_MLEngine_configProvider = new WeakMap(), _MLEngine_core = new WeakMap(), _MLEngine_file = new WeakMap(), _MLEngine_options = new WeakMap(), _MLEngine_watcher = new WeakMap();
|
package/lib/api/types.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ConfigSet } from '@markuplint/file-resolver';
|
|
2
2
|
import type { LocaleSet } from '@markuplint/i18n';
|
|
3
|
-
import type { MLMarkupLanguageParser } from '@markuplint/ml-ast';
|
|
4
|
-
import type { Config,
|
|
3
|
+
import type { MLMarkupLanguageParser, ParserOptions } from '@markuplint/ml-ast';
|
|
4
|
+
import type { Config, Pretender, Violation } from '@markuplint/ml-config';
|
|
5
5
|
import type { AnyMLRule, MLSchema, Ruleset } from '@markuplint/ml-core';
|
|
6
|
-
export
|
|
6
|
+
export type APIOptions = {
|
|
7
7
|
configFile?: string;
|
|
8
8
|
config?: Config;
|
|
9
9
|
defaultConfig?: Config;
|
|
@@ -18,16 +18,17 @@ export declare type APIOptions = {
|
|
|
18
18
|
*/
|
|
19
19
|
autoLoad?: boolean;
|
|
20
20
|
};
|
|
21
|
-
export
|
|
21
|
+
export type MLFabric = {
|
|
22
22
|
ruleset: Ruleset;
|
|
23
23
|
rules: AnyMLRule[];
|
|
24
24
|
schemas: MLSchema;
|
|
25
25
|
parser: MLMarkupLanguageParser;
|
|
26
26
|
parserOptions: ParserOptions;
|
|
27
|
+
pretenders: Pretender[];
|
|
27
28
|
locale: LocaleSet;
|
|
28
29
|
configErrors?: Error[];
|
|
29
30
|
};
|
|
30
|
-
export
|
|
31
|
+
export type MLEngineEventMap = {
|
|
31
32
|
log: (phase: string, message: string) => void;
|
|
32
33
|
config: (filePath: string, config: ConfigSet, message?: string) => void;
|
|
33
34
|
exclude: (filePath: string, setting: string, message?: string) => void;
|
package/lib/cli/bootstrap.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import meow from 'meow';
|
|
2
|
-
export declare const help = "\nUsage\n\t$ markuplint <HTML file
|
|
2
|
+
export declare const help = "\nUsage\n\t$ markuplint <HTML file paths (glob format)>\n\t$ <stdout> | markuplint\n\nOptions\n\t--config, -c FILE_PATH A configuration file path.\n\t--fix, Fix HTML.\n\t--format, -f FORMAT Output format. Support \"JSON\", \"Simple\" and \"Standard\". Default: \"Standard\".\n\t--no-search-config No search a configure file automatically.\n\t--ignore-ext Evaluate files that are received even though the type of extension.\n\t--no-import-preset-rules No import preset rules.\n\t--locale Locale of the message of violation. Default is an OS setting.\n\t--no-color, Output no color.\n\t--problem-only, -p Output only problems, without passeds.\n\t--verbose Output with detailed information.\n\n\t--init Initialize settings interactively.\n\t--create-rule Add the scaffold of a custom rule.\n\t--search Search lines of codes that include the target element by selectors.\n\n\t--help, -h Show help.\n\t--version, -v Show version.\n\nExamples\n\t$ markuplint verifyee.html --config path/to/.markuplintrc\n\t$ cat verifyee.html | markuplint\n";
|
|
3
3
|
export declare const cli: meow.Result<{
|
|
4
4
|
config: {
|
|
5
5
|
type: "string";
|
|
@@ -53,4 +53,4 @@ export declare const cli: meow.Result<{
|
|
|
53
53
|
type: "string";
|
|
54
54
|
};
|
|
55
55
|
}>;
|
|
56
|
-
export
|
|
56
|
+
export type CLIOptions = typeof cli.flags;
|
package/lib/cli/bootstrap.js
CHANGED
package/lib/cli/command.js
CHANGED
|
@@ -9,6 +9,7 @@ const api_1 = require("../api");
|
|
|
9
9
|
const debug_1 = require("../debug");
|
|
10
10
|
const output_1 = require("./output");
|
|
11
11
|
async function command(files, options, apiOptions) {
|
|
12
|
+
var _a;
|
|
12
13
|
const fix = options.fix;
|
|
13
14
|
const configFile = options.config && path_1.default.join(process.cwd(), options.config);
|
|
14
15
|
const locale = options.locale;
|
|
@@ -22,7 +23,9 @@ async function command(files, options, apiOptions) {
|
|
|
22
23
|
(0, debug_1.log)('Config: %s', configFile || 'N/A');
|
|
23
24
|
(0, debug_1.log)('Fix option: %s', fix);
|
|
24
25
|
}
|
|
26
|
+
const format = (_a = options.format) === null || _a === void 0 ? void 0 : _a.toLowerCase().trim();
|
|
25
27
|
let hasError = false;
|
|
28
|
+
const jsonOutput = [];
|
|
26
29
|
for (const file of fileList) {
|
|
27
30
|
const engine = new api_1.MLEngine(file, {
|
|
28
31
|
configFile,
|
|
@@ -47,10 +50,21 @@ async function command(files, options, apiOptions) {
|
|
|
47
50
|
process.stdout.write(`markuplint: Fix "${result.filePath}"\n`);
|
|
48
51
|
}
|
|
49
52
|
else {
|
|
53
|
+
if (format === 'json') {
|
|
54
|
+
jsonOutput.push(...result.violations.map(v => ({
|
|
55
|
+
...v,
|
|
56
|
+
filePath: result.filePath,
|
|
57
|
+
})));
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
50
60
|
(0, debug_1.log)('Output reports');
|
|
51
|
-
|
|
61
|
+
(0, output_1.output)(result, options);
|
|
52
62
|
}
|
|
53
63
|
}
|
|
64
|
+
if (format === 'json') {
|
|
65
|
+
process.stdout.write(JSON.stringify(jsonOutput, null, 2) + '\n');
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
54
68
|
return hasError;
|
|
55
69
|
}
|
|
56
70
|
exports.command = command;
|
|
@@ -10,13 +10,16 @@ const prompt_1 = require("../prompt");
|
|
|
10
10
|
async function createRule() {
|
|
11
11
|
(0, util_1.write)((0, util_1.head)('Create a rule'));
|
|
12
12
|
util_1.write.break();
|
|
13
|
+
const firstChoices = [
|
|
14
|
+
{ name: 'Add the rule to this project', value: 'ADD_TO_PROJECT' },
|
|
15
|
+
{ name: 'Create the rule and publish it as a package', value: 'PUBLISH_AS_PACKAGE' },
|
|
16
|
+
];
|
|
17
|
+
if (await (0, create_rule_helper_1.isMarkuplintRepo)()) {
|
|
18
|
+
firstChoices.push({ name: 'Contribute the new rule to markuplint core rules', value: 'CONTRIBUTE_TO_CORE' });
|
|
19
|
+
}
|
|
13
20
|
const purpose = await (0, prompt_1.select)({
|
|
14
21
|
message: 'What purpose do you create the rule for?',
|
|
15
|
-
choices:
|
|
16
|
-
{ name: 'Add the rule to this project', value: 'ADD_TO_PROJECT' },
|
|
17
|
-
{ name: 'Create the rule and publish it as a package', value: 'PUBLISH_AS_PACKAGE' },
|
|
18
|
-
{ name: 'Contribute the new rule to markuplint core rules', value: 'CONTRIBUTE_TO_CORE' },
|
|
19
|
-
],
|
|
22
|
+
choices: firstChoices,
|
|
20
23
|
});
|
|
21
24
|
const name = await (0, prompt_1.input)('What is the name?', /^[a-z][a-z0-9]*(?:-[a-z][a-z0-9]*)*$/i);
|
|
22
25
|
const lang = purpose === 'CONTRIBUTE_TO_CORE'
|
|
@@ -35,13 +38,19 @@ async function createRule() {
|
|
|
35
38
|
if (result.test) {
|
|
36
39
|
output(name, '🖍 ', 'index.spec', result.test);
|
|
37
40
|
}
|
|
41
|
+
if (result.rules) {
|
|
42
|
+
output(name, '🛡 ', 'rules', result.rules);
|
|
43
|
+
}
|
|
44
|
+
if (result.rulesTest) {
|
|
45
|
+
output(name, '🖍 ', 'rules.spec', result.rulesTest);
|
|
46
|
+
}
|
|
38
47
|
if (result.schemaJson) {
|
|
39
48
|
output(name, '⚙️ ', 'schema.json', result.schemaJson);
|
|
40
49
|
}
|
|
41
50
|
if (result.packageJson) {
|
|
42
|
-
output(name, '🎁
|
|
51
|
+
output(name, '🎁', 'package.json', result.packageJson);
|
|
43
52
|
if (result.tsConfig) {
|
|
44
|
-
output(name, '💎
|
|
53
|
+
output(name, '💎', 'tsconfig.json', result.tsConfig);
|
|
45
54
|
}
|
|
46
55
|
await (0, install_module_1.installModule)(result.dependencies);
|
|
47
56
|
await (0, install_module_1.installModule)(result.devDependencies, true);
|
package/lib/cli/index.js
CHANGED
|
@@ -52,7 +52,10 @@ const search_1 = tslib_1.__importDefault(require("./search"));
|
|
|
52
52
|
(0, get_stdin_1.default)()
|
|
53
53
|
.then(async (stdin) => {
|
|
54
54
|
if (stdin) {
|
|
55
|
-
const hasError = await (0, command_1.command)([{ sourceCode: stdin }],
|
|
55
|
+
const hasError = await (0, command_1.command)([{ sourceCode: stdin }], {
|
|
56
|
+
...bootstrap_1.cli.flags,
|
|
57
|
+
ignoreExt: true,
|
|
58
|
+
}).catch(err => {
|
|
56
59
|
process.stderr.write(err + '\n');
|
|
57
60
|
process.exit(1);
|
|
58
61
|
});
|
package/lib/cli/init/index.js
CHANGED
|
@@ -46,7 +46,7 @@ const defaultRules = {
|
|
|
46
46
|
default: true,
|
|
47
47
|
},
|
|
48
48
|
'character-reference': {
|
|
49
|
-
category: '
|
|
49
|
+
category: 'style',
|
|
50
50
|
default: true,
|
|
51
51
|
},
|
|
52
52
|
'class-naming': {
|
|
@@ -86,6 +86,10 @@ const defaultRules = {
|
|
|
86
86
|
category: 'validation',
|
|
87
87
|
default: true,
|
|
88
88
|
},
|
|
89
|
+
'label-has-control': {
|
|
90
|
+
category: 'a11y',
|
|
91
|
+
default: false,
|
|
92
|
+
},
|
|
89
93
|
'landmark-roles': {
|
|
90
94
|
category: 'a11y',
|
|
91
95
|
default: true,
|
|
@@ -98,6 +102,10 @@ const defaultRules = {
|
|
|
98
102
|
category: 'style',
|
|
99
103
|
default: true,
|
|
100
104
|
},
|
|
105
|
+
'no-empty-palpable-content': {
|
|
106
|
+
category: 'validation',
|
|
107
|
+
default: false,
|
|
108
|
+
},
|
|
101
109
|
'no-hard-code-id': {
|
|
102
110
|
category: 'style',
|
|
103
111
|
default: true,
|
|
@@ -33,6 +33,9 @@ async function installModule(module, dev = false) {
|
|
|
33
33
|
if (dev) {
|
|
34
34
|
opt.push('-D');
|
|
35
35
|
}
|
|
36
|
+
if (!(0, has_yarn_1.default)()) {
|
|
37
|
+
opt.push('--legacy-peer-deps');
|
|
38
|
+
}
|
|
36
39
|
opt.push(...uninstallMods);
|
|
37
40
|
return new Promise((resolve, reject) => {
|
|
38
41
|
process.stdout.write(cli_color_1.default.blackBright(`${mod} ${opt.join(' ')}\n`));
|
package/lib/cli/output.js
CHANGED
package/lib/cli/prompt.d.ts
CHANGED
package/lib/global-settings.d.ts
CHANGED
package/lib/i18n.d.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
listFormat?: import("packages/@markuplint/i18n/src/types").ListFormat | undefined;
|
|
4
|
-
keywords?: import("packages/@markuplint/i18n/src/types").LocalesKeywords | undefined;
|
|
5
|
-
sentences?: import("packages/@markuplint/i18n/src/types").LocalesKeywords | undefined;
|
|
6
|
-
}>;
|
|
1
|
+
import type { LocaleSet } from '@markuplint/i18n';
|
|
2
|
+
export declare function i18n(locale?: string): Promise<LocaleSet>;
|