markuplint 4.0.0-alpha.3 → 4.0.0-dev.28
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/lib/api/ml-engine.js +16 -6
- package/lib/cli/create-rule/index.js +2 -2
- package/lib/cli/index.js +55 -60
- package/lib/cli/init/index.js +2 -2
- package/lib/cli/init/install-module.js +3 -3
- package/lib/cli/search/index.js +3 -3
- package/lib/get-json-module.js +1 -1
- package/lib/reporter/github-reporter.js +4 -2
- package/lib/reporter/standard-reporter.js +2 -2
- package/lib/testing-tool/index.js +25 -23
- package/lib/util.js +6 -5
- package/package.json +17 -23
package/lib/api/ml-engine.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
1
12
|
var _MLEngine_configProvider, _MLEngine_core, _MLEngine_file, _MLEngine_options, _MLEngine_watcher;
|
|
2
|
-
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
|
|
3
13
|
import { ConfigProvider, resolveFiles, resolveParser, resolveRules, resolveSpecs } from '@markuplint/file-resolver';
|
|
4
14
|
import { MLCore, convertRuleset } from '@markuplint/ml-core';
|
|
5
15
|
import { FSWatcher } from 'chokidar';
|
|
@@ -64,11 +74,11 @@ class MLEngine extends Emitter {
|
|
|
64
74
|
log('exec: cancel (unsetuped yet)');
|
|
65
75
|
return null;
|
|
66
76
|
}
|
|
67
|
-
const violations = await core.verify(__classPrivateFieldGet(this, _MLEngine_options, "f")?.fix).catch(
|
|
68
|
-
if (
|
|
69
|
-
return
|
|
77
|
+
const violations = await core.verify(__classPrivateFieldGet(this, _MLEngine_options, "f")?.fix).catch(error => {
|
|
78
|
+
if (error instanceof Error) {
|
|
79
|
+
return error;
|
|
70
80
|
}
|
|
71
|
-
throw
|
|
81
|
+
throw error;
|
|
72
82
|
});
|
|
73
83
|
const sourceCode = await __classPrivateFieldGet(this, _MLEngine_file, "f").getCode();
|
|
74
84
|
const fixedCode = core.document.toString();
|
|
@@ -259,7 +269,7 @@ class MLEngine extends Emitter {
|
|
|
259
269
|
this.emit('config', __classPrivateFieldGet(this, _MLEngine_file, "f").path, configSet);
|
|
260
270
|
if (__classPrivateFieldGet(this, _MLEngine_options, "f")?.watch) {
|
|
261
271
|
// It doesn't watch the main HTML file because it may is watched and managed by a language server or text editor or more.
|
|
262
|
-
__classPrivateFieldGet(this, _MLEngine_watcher, "f").add(
|
|
272
|
+
__classPrivateFieldGet(this, _MLEngine_watcher, "f").add([...configSet.files]);
|
|
263
273
|
}
|
|
264
274
|
return configSet;
|
|
265
275
|
}
|
|
@@ -26,8 +26,8 @@ export async function createRule() {
|
|
|
26
26
|
choices: firstChoices,
|
|
27
27
|
});
|
|
28
28
|
const dirQuestion = purpose === 'ADD_TO_PROJECT' ? 'What is the directory name?' : 'What is the plugin name?';
|
|
29
|
-
const pluginName = purpose === 'CONTRIBUTE_TO_CORE' ? '' : await input(dirQuestion, /^[a-z][
|
|
30
|
-
const ruleName = await input('What is the rule name?', /^[a-z][
|
|
29
|
+
const pluginName = purpose === 'CONTRIBUTE_TO_CORE' ? '' : await input(dirQuestion, /^[a-z][\da-z]*(?:-[a-z][\da-z]*)*$/i);
|
|
30
|
+
const ruleName = await input('What is the rule name?', /^[a-z][\da-z]*(?:-[a-z][\da-z]*)*$/i);
|
|
31
31
|
const core = purpose === 'CONTRIBUTE_TO_CORE'
|
|
32
32
|
? {
|
|
33
33
|
description: await input('Description:'),
|
package/lib/cli/index.js
CHANGED
|
@@ -5,71 +5,66 @@ import { command } from './command.js';
|
|
|
5
5
|
import { createRule } from './create-rule/index.js';
|
|
6
6
|
import { initialize } from './init/index.js';
|
|
7
7
|
import search from './search/index.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
process.stderr.write(err + '\n');
|
|
38
|
-
process.exit(1);
|
|
39
|
-
});
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const hasError = await command(files, cli.flags).catch(err => {
|
|
43
|
-
throw err;
|
|
44
|
-
});
|
|
45
|
-
process.exit(hasError ? 1 : 0);
|
|
46
|
-
}
|
|
47
|
-
if (usePipe()) {
|
|
48
|
-
getStdin()
|
|
49
|
-
.then(async (stdin) => {
|
|
50
|
-
if (stdin) {
|
|
51
|
-
const hasError = await command([{ sourceCode: stdin }], {
|
|
52
|
-
...cli.flags,
|
|
53
|
-
ignoreExt: true,
|
|
54
|
-
}).catch(err => {
|
|
55
|
-
process.stderr.write(err + '\n');
|
|
56
|
-
process.exit(1);
|
|
57
|
-
});
|
|
58
|
-
process.exit(hasError ? 1 : 0);
|
|
59
|
-
}
|
|
60
|
-
// result is empty
|
|
61
|
-
cli.showHelp(1);
|
|
62
|
-
})
|
|
63
|
-
.catch(reason => {
|
|
64
|
-
// eslint-disable-next-line no-console
|
|
65
|
-
console.warn(reason);
|
|
8
|
+
/* eslint-disable unicorn/no-process-exit */
|
|
9
|
+
if (cli.flags.v) {
|
|
10
|
+
cli.showVersion(); // And exit successfully.
|
|
11
|
+
}
|
|
12
|
+
if (cli.flags.h) {
|
|
13
|
+
cli.showHelp(0); // And exit successfully.
|
|
14
|
+
}
|
|
15
|
+
if (cli.flags.verbose) {
|
|
16
|
+
verbosely();
|
|
17
|
+
}
|
|
18
|
+
if (cli.flags.init) {
|
|
19
|
+
await initialize().catch(error => {
|
|
20
|
+
process.stderr.write(error + '\n');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
});
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
if (cli.flags.createRule) {
|
|
26
|
+
await createRule().catch(error => {
|
|
27
|
+
process.stderr.write(error + '\n');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
});
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
const files = cli.input;
|
|
33
|
+
if (files.length > 0) {
|
|
34
|
+
if (cli.flags.search) {
|
|
35
|
+
await search(files, cli.flags, cli.flags.search).catch(error => {
|
|
36
|
+
process.stderr.write(error + '\n');
|
|
66
37
|
process.exit(1);
|
|
67
38
|
});
|
|
39
|
+
process.exit(0);
|
|
68
40
|
}
|
|
69
|
-
|
|
41
|
+
const hasError = await command(files, cli.flags).catch(error => {
|
|
42
|
+
throw error;
|
|
43
|
+
});
|
|
44
|
+
process.exit(hasError ? 1 : 0);
|
|
45
|
+
}
|
|
46
|
+
if (usePipe()) {
|
|
47
|
+
const stdin = await getStdin().catch(error => {
|
|
48
|
+
// eslint-disable-next-line no-console
|
|
49
|
+
console.warn(error);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
});
|
|
52
|
+
if (!stdin) {
|
|
53
|
+
// result is empty
|
|
70
54
|
cli.showHelp(1);
|
|
71
55
|
}
|
|
72
|
-
}
|
|
56
|
+
const hasError = await command([{ sourceCode: stdin }], {
|
|
57
|
+
...cli.flags,
|
|
58
|
+
ignoreExt: true,
|
|
59
|
+
}).catch(error => {
|
|
60
|
+
process.stderr.write(error + '\n');
|
|
61
|
+
process.exit(1);
|
|
62
|
+
});
|
|
63
|
+
process.exit(hasError ? 1 : 0);
|
|
64
|
+
}
|
|
65
|
+
// No arguments
|
|
66
|
+
cli.showHelp(1);
|
|
67
|
+
/* eslint-enable unicorn/no-process-exit */
|
|
73
68
|
function usePipe() {
|
|
74
69
|
return !process.stdin.isTTY && process.stdout.isTTY;
|
|
75
70
|
}
|
package/lib/cli/init/index.js
CHANGED
|
@@ -59,12 +59,12 @@ export async function initialize() {
|
|
|
59
59
|
}
|
|
60
60
|
const config = createConfig(selectedLangs, ruleSettingMode, defaultRules);
|
|
61
61
|
const filePath = path.resolve(process.cwd(), '.markuplintrc');
|
|
62
|
-
await writeFile(filePath, JSON.stringify(config, null, 2), { encoding: '
|
|
62
|
+
await writeFile(filePath, JSON.stringify(config, null, 2), { encoding: 'utf8' });
|
|
63
63
|
write(`✨Created: ${filePath}`);
|
|
64
64
|
if (autoInstall) {
|
|
65
65
|
write('Install automatically');
|
|
66
66
|
const modules = selectModules(selectedLangs);
|
|
67
|
-
const result = await installModule(modules, true).catch(
|
|
67
|
+
const result = await installModule(modules, true).catch(error_ => new Error(error_));
|
|
68
68
|
if (result instanceof Error) {
|
|
69
69
|
error.exit();
|
|
70
70
|
return;
|
|
@@ -24,7 +24,7 @@ export async function installModule(module, dev = false) {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
catch
|
|
27
|
+
catch {
|
|
28
28
|
// void
|
|
29
29
|
}
|
|
30
30
|
if (uninstallMods.length === 0) {
|
|
@@ -67,8 +67,8 @@ function isInstalled(module) {
|
|
|
67
67
|
resolve(exists);
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
|
-
catch (
|
|
71
|
-
reject(
|
|
70
|
+
catch (error) {
|
|
71
|
+
reject(error);
|
|
72
72
|
}
|
|
73
73
|
});
|
|
74
74
|
}
|
package/lib/cli/search/index.js
CHANGED
|
@@ -14,7 +14,7 @@ export default async function (files, options, selectors) {
|
|
|
14
14
|
...createRule({
|
|
15
15
|
verify({ document }) {
|
|
16
16
|
const nodes = document.querySelectorAll(selectors);
|
|
17
|
-
locations.push(...
|
|
17
|
+
locations.push(...[...nodes].map(node => {
|
|
18
18
|
return {
|
|
19
19
|
file: document.filename ?? '_NO_FILE_',
|
|
20
20
|
line: node.startLine,
|
|
@@ -31,7 +31,7 @@ export default async function (files, options, selectors) {
|
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
});
|
|
34
|
-
|
|
34
|
+
for (const loc of locations) {
|
|
35
35
|
process.stdout.write(`${loc.file}:${loc.line}:${loc.col}\n`);
|
|
36
|
-
}
|
|
36
|
+
}
|
|
37
37
|
}
|
package/lib/get-json-module.js
CHANGED
|
@@ -10,10 +10,12 @@ export function githubReporter(results) {
|
|
|
10
10
|
}
|
|
11
11
|
function severityToCommand(severity) {
|
|
12
12
|
switch (severity) {
|
|
13
|
-
case 'info':
|
|
13
|
+
case 'info': {
|
|
14
14
|
return 'notice';
|
|
15
|
+
}
|
|
15
16
|
case 'error':
|
|
16
|
-
case 'warning':
|
|
17
|
+
case 'warning': {
|
|
17
18
|
return severity;
|
|
19
|
+
}
|
|
18
20
|
}
|
|
19
21
|
}
|
|
@@ -21,8 +21,8 @@ export function standardReporter(results, options) {
|
|
|
21
21
|
const prev = lines[violation.line - 2] ?? '';
|
|
22
22
|
const line = lines[violation.line - 1] ?? '';
|
|
23
23
|
const next = lines[violation.line - 0] ?? '';
|
|
24
|
-
const before = line.
|
|
25
|
-
const after = line.
|
|
24
|
+
const before = line.slice(0, Math.max(0, violation.col - 1));
|
|
25
|
+
const after = line.slice(Math.max(0, violation.col - 1 + violation.raw.length));
|
|
26
26
|
const logger = violation.severity === 'error' ? loggerError : loggerWarning;
|
|
27
27
|
const meg = messageToString(violation.message, violation.reason);
|
|
28
28
|
out.push(`<${markuplint}> ${logger(`${violation.severity}: ${meg} (${violation.ruleId}) ${c.underline(`${results.filePath}:${violation.line}:${violation.col}`)}`)}`);
|
|
@@ -18,38 +18,40 @@ export async function mlTest(sourceCode, config, rules, locale = 'en', fix = fal
|
|
|
18
18
|
fixedCode: result?.fixedCode ?? sourceCode,
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
export async function mlRuleTest(rule, sourceCode,
|
|
21
|
+
export async function mlRuleTest(rule, sourceCode,
|
|
22
|
+
// eslint-disable-next-line unicorn/no-object-as-default-parameter
|
|
23
|
+
config = { rule: true }, fix = false, locale = 'en') {
|
|
22
24
|
const _config = {
|
|
23
25
|
...config,
|
|
24
|
-
rules: config.rule
|
|
25
|
-
?
|
|
26
|
-
'<current-rule>': config.rule,
|
|
27
|
-
}
|
|
28
|
-
: config.rule === undefined && config.nodeRule === undefined && config.childNodeRule === undefined
|
|
26
|
+
rules: config.rule === undefined
|
|
27
|
+
? config.rule === undefined && config.nodeRule === undefined && config.childNodeRule === undefined
|
|
29
28
|
? {
|
|
30
29
|
'<current-rule>': true,
|
|
31
30
|
}
|
|
32
|
-
: undefined
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
: undefined
|
|
32
|
+
: {
|
|
33
|
+
'<current-rule>': config.rule,
|
|
34
|
+
},
|
|
35
|
+
nodeRules: config.nodeRule === undefined
|
|
36
|
+
? undefined
|
|
37
|
+
: config.nodeRule.map(nodeConfig => ({
|
|
35
38
|
...nodeConfig,
|
|
36
|
-
rules: nodeConfig.rule
|
|
37
|
-
?
|
|
39
|
+
rules: nodeConfig.rule === undefined
|
|
40
|
+
? undefined
|
|
41
|
+
: {
|
|
38
42
|
'<current-rule>': nodeConfig.rule,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
? config.childNodeRule.map(childNodeConfig => ({
|
|
43
|
+
},
|
|
44
|
+
})),
|
|
45
|
+
childNodeRules: config.childNodeRule === undefined
|
|
46
|
+
? undefined
|
|
47
|
+
: config.childNodeRule.map(childNodeConfig => ({
|
|
45
48
|
...childNodeConfig,
|
|
46
|
-
rules: childNodeConfig.rule
|
|
47
|
-
?
|
|
49
|
+
rules: childNodeConfig.rule === undefined
|
|
50
|
+
? undefined
|
|
51
|
+
: {
|
|
48
52
|
'<current-rule>': childNodeConfig.rule,
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
}))
|
|
52
|
-
: undefined,
|
|
53
|
+
},
|
|
54
|
+
})),
|
|
53
55
|
};
|
|
54
56
|
const res = await mlTest(sourceCode, _config, [
|
|
55
57
|
new MLRule({
|
package/lib/util.js
CHANGED
|
@@ -43,6 +43,7 @@ write.break = () => process.stdout.write('\n');
|
|
|
43
43
|
export function error(message) {
|
|
44
44
|
process.stderr.write(message + '\n');
|
|
45
45
|
}
|
|
46
|
+
// eslint-disable-next-line unicorn/no-process-exit
|
|
46
47
|
error.exit = () => process.exit(1);
|
|
47
48
|
export const head = (method, noColor) => box([`${logo} ${markuplint}`, c.blackBright(`v${version}`), '', c.bold(method)], {
|
|
48
49
|
center: true,
|
|
@@ -55,18 +56,18 @@ export function p(s, pad, start = false) {
|
|
|
55
56
|
return start ? `${_}${s}` : `${s}${_}`;
|
|
56
57
|
}
|
|
57
58
|
export function w(s) {
|
|
58
|
-
return s.
|
|
59
|
+
return s.replaceAll(/./g, _ => '0'.repeat(eaw.characterLength(_))).length;
|
|
59
60
|
}
|
|
60
61
|
export function space(str) {
|
|
61
62
|
return str
|
|
62
|
-
.
|
|
63
|
+
.replaceAll(/\s+/g, $0 => {
|
|
63
64
|
return c.xterm(8)($0);
|
|
64
65
|
})
|
|
65
|
-
.
|
|
66
|
-
.
|
|
66
|
+
.replaceAll(' ', $0 => '•')
|
|
67
|
+
.replaceAll('\t', $0 => '→ ');
|
|
67
68
|
}
|
|
68
69
|
export function invisibleSpace(str) {
|
|
69
|
-
return str.
|
|
70
|
+
return str.replaceAll('\t', $0 => ' ').replaceAll(/./g, $0 => ' ');
|
|
70
71
|
}
|
|
71
72
|
export function messageToString(message, reason) {
|
|
72
73
|
if (!reason) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markuplint",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-dev.28+0131de5e",
|
|
4
4
|
"description": "An HTML linter for all markup developers",
|
|
5
5
|
"author": "Yusuke Hirao",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,26 +24,21 @@
|
|
|
24
24
|
"dev": "tsc --build --watch",
|
|
25
25
|
"clean": "tsc --build --clean"
|
|
26
26
|
},
|
|
27
|
-
"devDependencies": {
|
|
28
|
-
"execa": "^8.0.1"
|
|
29
|
-
},
|
|
30
27
|
"dependencies": {
|
|
31
|
-
"@markuplint/create-rule-helper": "4.0.0-
|
|
32
|
-
"@markuplint/file-resolver": "4.0.0-
|
|
33
|
-
"@markuplint/html-parser": "4.0.0-
|
|
34
|
-
"@markuplint/html-spec": "4.0.0-
|
|
35
|
-
"@markuplint/i18n": "4.0.0-
|
|
36
|
-
"@markuplint/ml-ast": "4.0.0-
|
|
37
|
-
"@markuplint/ml-config": "4.0.0-
|
|
38
|
-
"@markuplint/ml-core": "4.0.0-
|
|
39
|
-
"@markuplint/ml-spec": "4.0.0-
|
|
40
|
-
"@markuplint/rules": "4.0.0-
|
|
41
|
-
"@markuplint/shared": "4.0.0-
|
|
42
|
-
"@types/cli-color": "^2.0.
|
|
43
|
-
"@types/debug": "^4.1.
|
|
44
|
-
"@types/
|
|
45
|
-
"@types/meow": "^6.0.0",
|
|
46
|
-
"@types/uuid": "^9.0.4",
|
|
28
|
+
"@markuplint/create-rule-helper": "4.0.0-dev.28+0131de5e",
|
|
29
|
+
"@markuplint/file-resolver": "4.0.0-dev.28+0131de5e",
|
|
30
|
+
"@markuplint/html-parser": "4.0.0-dev.28+0131de5e",
|
|
31
|
+
"@markuplint/html-spec": "4.0.0-dev.28+0131de5e",
|
|
32
|
+
"@markuplint/i18n": "4.0.0-dev.28+0131de5e",
|
|
33
|
+
"@markuplint/ml-ast": "4.0.0-dev.28+0131de5e",
|
|
34
|
+
"@markuplint/ml-config": "4.0.0-dev.28+0131de5e",
|
|
35
|
+
"@markuplint/ml-core": "4.0.0-dev.28+0131de5e",
|
|
36
|
+
"@markuplint/ml-spec": "4.0.0-dev.28+0131de5e",
|
|
37
|
+
"@markuplint/rules": "4.0.0-dev.28+0131de5e",
|
|
38
|
+
"@markuplint/shared": "4.0.0-dev.28+0131de5e",
|
|
39
|
+
"@types/cli-color": "^2.0.4",
|
|
40
|
+
"@types/debug": "^4.1.10",
|
|
41
|
+
"@types/uuid": "^9.0.6",
|
|
47
42
|
"chokidar": "^3.5.3",
|
|
48
43
|
"cli-color": "^2.0.3",
|
|
49
44
|
"debug": "^4.3.4",
|
|
@@ -58,9 +53,8 @@
|
|
|
58
53
|
"os-locale": "^6.0.2",
|
|
59
54
|
"strict-event-emitter": "^0.5.1",
|
|
60
55
|
"strip-ansi": "^7.1.0",
|
|
61
|
-
"
|
|
62
|
-
"type-fest": "^4.3.1",
|
|
56
|
+
"type-fest": "^4.5.0",
|
|
63
57
|
"uuid": "^9.0.1"
|
|
64
58
|
},
|
|
65
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "0131de5ea9dd6d3fd5472d7b414b66644c758881"
|
|
66
60
|
}
|