eslint 9.0.0-beta.2 → 9.0.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 +8 -12
- package/bin/eslint.js +14 -1
- package/lib/cli.js +30 -11
- package/lib/config/flat-config-schema.js +1 -2
- package/lib/eslint/eslint-helpers.js +5 -1
- package/lib/eslint/eslint.js +16 -1
- package/lib/linter/code-path-analysis/code-path-analyzer.js +0 -1
- package/lib/linter/index.js +1 -3
- package/lib/linter/linter.js +184 -40
- package/lib/linter/timing.js +16 -8
- package/lib/options.js +25 -1
- package/lib/rule-tester/index.js +3 -1
- package/lib/rule-tester/rule-tester.js +18 -2
- package/lib/rules/camelcase.js +3 -5
- package/lib/rules/constructor-super.js +98 -99
- package/lib/rules/no-fallthrough.js +41 -16
- package/lib/rules/no-lone-blocks.js +1 -1
- package/lib/rules/no-this-before-super.js +28 -9
- package/lib/rules/no-unused-vars.js +179 -29
- package/lib/rules/no-useless-return.js +7 -2
- package/lib/rules/use-isnan.js +2 -2
- package/lib/rules/utils/lazy-loading-rule-map.js +1 -1
- package/lib/rules/utils/unicode/index.js +9 -4
- package/lib/shared/runtime-info.js +1 -0
- package/lib/shared/stats.js +30 -0
- package/lib/shared/types.js +34 -0
- package/lib/source-code/index.js +3 -1
- package/lib/source-code/source-code.js +165 -1
- package/lib/source-code/token-store/backward-token-cursor.js +3 -3
- package/lib/source-code/token-store/cursors.js +4 -2
- package/lib/source-code/token-store/forward-token-comment-cursor.js +3 -3
- package/lib/source-code/token-store/forward-token-cursor.js +3 -3
- package/messages/plugin-conflict.js +1 -1
- package/messages/plugin-invalid.js +1 -1
- package/messages/plugin-missing.js +1 -1
- package/package.json +12 -8
- package/lib/cli-engine/xml-escape.js +0 -34
- package/lib/shared/deprecation-warnings.js +0 -58
package/README.md
CHANGED
@@ -59,15 +59,11 @@ After that, you can run ESLint on any file or directory like this:
|
|
59
59
|
|
60
60
|
## Configuration
|
61
61
|
|
62
|
-
After running `npm init @eslint/config`, you'll have an
|
63
|
-
|
64
|
-
```
|
65
|
-
|
66
|
-
|
67
|
-
"semi": ["error", "always"],
|
68
|
-
"quotes": ["error", "double"]
|
69
|
-
}
|
70
|
-
}
|
62
|
+
After running `npm init @eslint/config`, you'll have an `eslint.config.js` or `eslint.config.mjs` file in your directory. In it, you'll see some rules configured like this:
|
63
|
+
|
64
|
+
```js
|
65
|
+
import pluginJs from "@eslint/js";
|
66
|
+
export default [ pluginJs.configs.recommended, ];
|
71
67
|
```
|
72
68
|
|
73
69
|
The names `"semi"` and `"quotes"` are the names of [rules](https://eslint.org/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values:
|
@@ -303,10 +299,10 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
303
299
|
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
|
304
300
|
<!--sponsorsstart-->
|
305
301
|
<h3>Platinum Sponsors</h3>
|
306
|
-
<p><a href="
|
307
|
-
<p><a href="https://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a></p><h3>Silver Sponsors</h3>
|
302
|
+
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
|
303
|
+
<p><a href="https://bitwarden.com"><img src="https://avatars.githubusercontent.com/u/15990069?v=4" alt="Bitwarden" height="96"></a> <a href="https://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a></p><h3>Silver Sponsors</h3>
|
308
304
|
<p><a href="https://www.jetbrains.com/"><img src="https://images.opencollective.com/jetbrains/eb04ddc/logo.png" alt="JetBrains" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a> <a href="https://www.workleap.com"><img src="https://avatars.githubusercontent.com/u/53535748?u=d1e55d7661d724bf2281c1bfd33cb8f99fe2465f&v=4" alt="Workleap" height="64"></a></p><h3>Bronze Sponsors</h3>
|
309
|
-
<p><a href="https://www.notion.so"><img src="https://images.opencollective.com/notion/bf3b117/logo.png" alt="notion" height="32"></a> <a href="https://
|
305
|
+
<p><a href="https://www.notion.so"><img src="https://images.opencollective.com/notion/bf3b117/logo.png" alt="notion" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104?v=4" alt="Nx" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://usenextbase.com"><img src="https://avatars.githubusercontent.com/u/145838380?v=4" alt="Nextbase Starter Kit" height="32"></a></p>
|
310
306
|
<!--sponsorsend-->
|
311
307
|
|
312
308
|
## Technology Sponsors
|
package/bin/eslint.js
CHANGED
@@ -148,8 +148,21 @@ ${getErrorMessage(error)}`;
|
|
148
148
|
return;
|
149
149
|
}
|
150
150
|
|
151
|
+
// Call the config inspector if `--inspect-config` is present.
|
152
|
+
if (process.argv.includes("--inspect-config")) {
|
153
|
+
|
154
|
+
console.warn("You can also run this command directly using 'npx @eslint/config-inspector' in the same directory as your configuration file.");
|
155
|
+
|
156
|
+
const spawn = require("cross-spawn");
|
157
|
+
|
158
|
+
spawn.sync("npx", ["@eslint/config-inspector"], { encoding: "utf8", stdio: "inherit" });
|
159
|
+
|
160
|
+
return;
|
161
|
+
}
|
162
|
+
|
151
163
|
// Otherwise, call the CLI.
|
152
|
-
const
|
164
|
+
const cli = require("../lib/cli");
|
165
|
+
const exitCode = await cli.execute(
|
153
166
|
process.argv,
|
154
167
|
process.argv.includes("--stdin") ? await readStdin() : null,
|
155
168
|
true
|
package/lib/cli.js
CHANGED
@@ -37,6 +37,7 @@ const debug = require("debug")("eslint:cli");
|
|
37
37
|
/** @typedef {import("./eslint/eslint").LintMessage} LintMessage */
|
38
38
|
/** @typedef {import("./eslint/eslint").LintResult} LintResult */
|
39
39
|
/** @typedef {import("./options").ParsedCLIOptions} ParsedCLIOptions */
|
40
|
+
/** @typedef {import("./shared/types").Plugin} Plugin */
|
40
41
|
/** @typedef {import("./shared/types").ResultsMeta} ResultsMeta */
|
41
42
|
|
42
43
|
//------------------------------------------------------------------------------
|
@@ -47,6 +48,32 @@ const mkdir = promisify(fs.mkdir);
|
|
47
48
|
const stat = promisify(fs.stat);
|
48
49
|
const writeFile = promisify(fs.writeFile);
|
49
50
|
|
51
|
+
/**
|
52
|
+
* Loads plugins with the specified names.
|
53
|
+
* @param {{ "import": (name: string) => Promise<any> }} importer An object with an `import` method called once for each plugin.
|
54
|
+
* @param {string[]} pluginNames The names of the plugins to be loaded, with or without the "eslint-plugin-" prefix.
|
55
|
+
* @returns {Promise<Record<string, Plugin>>} A mapping of plugin short names to implementations.
|
56
|
+
*/
|
57
|
+
async function loadPlugins(importer, pluginNames) {
|
58
|
+
const plugins = {};
|
59
|
+
|
60
|
+
await Promise.all(pluginNames.map(async pluginName => {
|
61
|
+
|
62
|
+
const longName = naming.normalizePackageName(pluginName, "eslint-plugin");
|
63
|
+
const module = await importer.import(longName);
|
64
|
+
|
65
|
+
if (!("default" in module)) {
|
66
|
+
throw new Error(`"${longName}" cannot be used with the \`--plugin\` option because its default module does not provide a \`default\` export`);
|
67
|
+
}
|
68
|
+
|
69
|
+
const shortName = naming.getShorthandName(pluginName, "eslint-plugin");
|
70
|
+
|
71
|
+
plugins[shortName] = module.default;
|
72
|
+
}));
|
73
|
+
|
74
|
+
return plugins;
|
75
|
+
}
|
76
|
+
|
50
77
|
/**
|
51
78
|
* Predicate function for whether or not to apply fixes in quiet mode.
|
52
79
|
* If a message is a warning, do not apply a fix.
|
@@ -104,6 +131,7 @@ async function translateOptions({
|
|
104
131
|
resolvePluginsRelativeTo,
|
105
132
|
rule,
|
106
133
|
rulesdir,
|
134
|
+
stats,
|
107
135
|
warnIgnored,
|
108
136
|
passOnNoPatterns,
|
109
137
|
maxWarnings
|
@@ -152,17 +180,7 @@ async function translateOptions({
|
|
152
180
|
}
|
153
181
|
|
154
182
|
if (plugin) {
|
155
|
-
|
156
|
-
|
157
|
-
for (const pluginName of plugin) {
|
158
|
-
|
159
|
-
const shortName = naming.getShorthandName(pluginName, "eslint-plugin");
|
160
|
-
const longName = naming.normalizePackageName(pluginName, "eslint-plugin");
|
161
|
-
|
162
|
-
plugins[shortName] = await importer.import(longName);
|
163
|
-
}
|
164
|
-
|
165
|
-
overrideConfig[0].plugins = plugins;
|
183
|
+
overrideConfig[0].plugins = await loadPlugins(importer, plugin);
|
166
184
|
}
|
167
185
|
|
168
186
|
} else {
|
@@ -205,6 +223,7 @@ async function translateOptions({
|
|
205
223
|
|
206
224
|
if (configType === "flat") {
|
207
225
|
options.ignorePatterns = ignorePattern;
|
226
|
+
options.stats = stats;
|
208
227
|
options.warnIgnored = warnIgnored;
|
209
228
|
|
210
229
|
/*
|
@@ -685,6 +685,7 @@ function processOptions({
|
|
685
685
|
overrideConfig = null,
|
686
686
|
overrideConfigFile = null,
|
687
687
|
plugins = {},
|
688
|
+
stats = false,
|
688
689
|
warnIgnored = true,
|
689
690
|
passOnNoPatterns = false,
|
690
691
|
ruleFilter = () => true,
|
@@ -791,6 +792,9 @@ function processOptions({
|
|
791
792
|
if (Array.isArray(plugins)) {
|
792
793
|
errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead.");
|
793
794
|
}
|
795
|
+
if (typeof stats !== "boolean") {
|
796
|
+
errors.push("'stats' must be a boolean.");
|
797
|
+
}
|
794
798
|
if (typeof warnIgnored !== "boolean") {
|
795
799
|
errors.push("'warnIgnored' must be a boolean.");
|
796
800
|
}
|
@@ -818,6 +822,7 @@ function processOptions({
|
|
818
822
|
globInputPaths,
|
819
823
|
ignore,
|
820
824
|
ignorePatterns,
|
825
|
+
stats,
|
821
826
|
passOnNoPatterns,
|
822
827
|
warnIgnored,
|
823
828
|
ruleFilter
|
@@ -907,7 +912,6 @@ function getCacheFile(cacheFile, cwd) {
|
|
907
912
|
//-----------------------------------------------------------------------------
|
908
913
|
|
909
914
|
module.exports = {
|
910
|
-
isGlobPattern,
|
911
915
|
findFiles,
|
912
916
|
|
913
917
|
isNonEmptyString,
|
package/lib/eslint/eslint.js
CHANGED
@@ -84,6 +84,7 @@ const LintResultCache = require("../cli-engine/lint-result-cache");
|
|
84
84
|
* doesn't do any config file lookup when `true`; considered to be a config filename
|
85
85
|
* when a string.
|
86
86
|
* @property {Record<string,Plugin>} [plugins] An array of plugin implementations.
|
87
|
+
* @property {boolean} [stats] True enables added statistics on lint results.
|
87
88
|
* @property {boolean} warnIgnored Show warnings when the file list includes ignored files
|
88
89
|
* @property {boolean} [passOnNoPatterns=false] When set to true, missing patterns cause
|
89
90
|
* the linting operation to short circuit and not report any failures.
|
@@ -465,6 +466,7 @@ async function calculateConfigArray(eslint, {
|
|
465
466
|
* @param {boolean} config.fix If `true` then it does fix.
|
466
467
|
* @param {boolean} config.allowInlineConfig If `true` then it uses directive comments.
|
467
468
|
* @param {Function} config.ruleFilter A predicate function to filter which rules should be run.
|
469
|
+
* @param {boolean} config.stats If `true`, then if reports extra statistics with the lint results.
|
468
470
|
* @param {Linter} config.linter The linter instance to verify.
|
469
471
|
* @returns {LintResult} The result of linting.
|
470
472
|
* @private
|
@@ -477,6 +479,7 @@ function verifyText({
|
|
477
479
|
fix,
|
478
480
|
allowInlineConfig,
|
479
481
|
ruleFilter,
|
482
|
+
stats,
|
480
483
|
linter
|
481
484
|
}) {
|
482
485
|
const filePath = providedFilePath || "<text>";
|
@@ -497,6 +500,7 @@ function verifyText({
|
|
497
500
|
filename: filePathToVerify,
|
498
501
|
fix,
|
499
502
|
ruleFilter,
|
503
|
+
stats,
|
500
504
|
|
501
505
|
/**
|
502
506
|
* Check if the linter should adopt a given code block or not.
|
@@ -528,6 +532,13 @@ function verifyText({
|
|
528
532
|
result.source = text;
|
529
533
|
}
|
530
534
|
|
535
|
+
if (stats) {
|
536
|
+
result.stats = {
|
537
|
+
times: linter.getTimes(),
|
538
|
+
fixPasses: linter.getFixPassCount()
|
539
|
+
};
|
540
|
+
}
|
541
|
+
|
531
542
|
return result;
|
532
543
|
}
|
533
544
|
|
@@ -808,6 +819,7 @@ class ESLint {
|
|
808
819
|
fix,
|
809
820
|
fixTypes,
|
810
821
|
ruleFilter,
|
822
|
+
stats,
|
811
823
|
globInputPaths,
|
812
824
|
errorOnUnmatchedPattern,
|
813
825
|
warnIgnored
|
@@ -922,6 +934,7 @@ class ESLint {
|
|
922
934
|
fix: fixer,
|
923
935
|
allowInlineConfig,
|
924
936
|
ruleFilter,
|
937
|
+
stats,
|
925
938
|
linter
|
926
939
|
});
|
927
940
|
|
@@ -1010,7 +1023,8 @@ class ESLint {
|
|
1010
1023
|
cwd,
|
1011
1024
|
fix,
|
1012
1025
|
warnIgnored: constructorWarnIgnored,
|
1013
|
-
ruleFilter
|
1026
|
+
ruleFilter,
|
1027
|
+
stats
|
1014
1028
|
} = eslintOptions;
|
1015
1029
|
const results = [];
|
1016
1030
|
const startTime = Date.now();
|
@@ -1034,6 +1048,7 @@ class ESLint {
|
|
1034
1048
|
fix,
|
1035
1049
|
allowInlineConfig,
|
1036
1050
|
ruleFilter,
|
1051
|
+
stats,
|
1037
1052
|
linter
|
1038
1053
|
}));
|
1039
1054
|
}
|
package/lib/linter/index.js
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
3
|
const { Linter } = require("./linter");
|
4
|
-
const { interpolate } = require("./interpolate");
|
5
4
|
const SourceCodeFixer = require("./source-code-fixer");
|
6
5
|
|
7
6
|
module.exports = {
|
8
7
|
Linter,
|
9
8
|
|
10
9
|
// For testers.
|
11
|
-
SourceCodeFixer
|
12
|
-
interpolate
|
10
|
+
SourceCodeFixer
|
13
11
|
};
|