eslint 8.49.0 → 8.51.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 +2 -2
- package/bin/eslint.js +15 -4
- package/lib/cli.js +6 -2
- package/lib/config/flat-config-schema.js +12 -4
- package/lib/eslint/eslint-helpers.js +8 -3
- package/lib/eslint/flat-eslint.js +15 -6
- package/lib/linter/apply-disable-directives.js +1 -1
- package/lib/linter/code-path-analysis/code-path-state.js +1108 -243
- package/lib/linter/code-path-analysis/code-path.js +127 -33
- package/lib/linter/code-path-analysis/fork-context.js +173 -72
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/linter/linter.js +172 -57
- package/lib/options.js +13 -0
- package/lib/rule-tester/flat-rule-tester.js +50 -5
- package/lib/rule-tester/rule-tester.js +78 -20
- package/lib/rules/array-callback-return.js +139 -14
- package/lib/rules/index.js +1 -0
- package/lib/rules/logical-assignment-operators.js +31 -3
- package/lib/rules/no-misleading-character-class.js +65 -15
- package/lib/rules/no-new-object.js +7 -0
- package/lib/rules/no-object-constructor.js +118 -0
- package/lib/source-code/source-code.js +350 -3
- package/package.json +2 -2
package/README.md
CHANGED
@@ -288,8 +288,8 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
288
288
|
<h3>Platinum Sponsors</h3>
|
289
289
|
<p><a href="#"><img src="https://images.opencollective.com/2021-frameworks-fund/logo.png" alt="Chrome Frameworks Fund" height="undefined"></a> <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>
|
290
290
|
<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>
|
291
|
-
<p><a href="https://
|
292
|
-
<p><a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://
|
291
|
+
<p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://opensource.siemens.com"><img src="https://avatars.githubusercontent.com/u/624020?v=4" alt="Siemens" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a></p><h3>Bronze Sponsors</h3>
|
292
|
+
<p><a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" 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://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
|
293
293
|
<!--sponsorsend-->
|
294
294
|
|
295
295
|
## Technology Sponsors
|
package/bin/eslint.js
CHANGED
@@ -92,6 +92,14 @@ function getErrorMessage(error) {
|
|
92
92
|
return util.format("%o", error);
|
93
93
|
}
|
94
94
|
|
95
|
+
/**
|
96
|
+
* Tracks error messages that are shown to the user so we only ever show the
|
97
|
+
* same message once.
|
98
|
+
* @type {Set<string>}
|
99
|
+
*/
|
100
|
+
|
101
|
+
const displayedErrors = new Set();
|
102
|
+
|
95
103
|
/**
|
96
104
|
* Catch and report unexpected error.
|
97
105
|
* @param {any} error The thrown error object.
|
@@ -101,14 +109,17 @@ function onFatalError(error) {
|
|
101
109
|
process.exitCode = 2;
|
102
110
|
|
103
111
|
const { version } = require("../package.json");
|
104
|
-
const message =
|
105
|
-
|
106
|
-
console.error(`
|
112
|
+
const message = `
|
107
113
|
Oops! Something went wrong! :(
|
108
114
|
|
109
115
|
ESLint: ${version}
|
110
116
|
|
111
|
-
${
|
117
|
+
${getErrorMessage(error)}`;
|
118
|
+
|
119
|
+
if (!displayedErrors.has(message)) {
|
120
|
+
console.error(message);
|
121
|
+
displayedErrors.add(message);
|
122
|
+
}
|
112
123
|
}
|
113
124
|
|
114
125
|
//------------------------------------------------------------------------------
|
package/lib/cli.js
CHANGED
@@ -91,7 +91,8 @@ async function translateOptions({
|
|
91
91
|
reportUnusedDisableDirectives,
|
92
92
|
resolvePluginsRelativeTo,
|
93
93
|
rule,
|
94
|
-
rulesdir
|
94
|
+
rulesdir,
|
95
|
+
warnIgnored
|
95
96
|
}, configType) {
|
96
97
|
|
97
98
|
let overrideConfig, overrideConfigFile;
|
@@ -182,6 +183,7 @@ async function translateOptions({
|
|
182
183
|
|
183
184
|
if (configType === "flat") {
|
184
185
|
options.ignorePatterns = ignorePattern;
|
186
|
+
options.warnIgnored = warnIgnored;
|
185
187
|
} else {
|
186
188
|
options.resolvePluginsRelativeTo = resolvePluginsRelativeTo;
|
187
189
|
options.rulePaths = rulesdir;
|
@@ -385,7 +387,9 @@ const cli = {
|
|
385
387
|
if (useStdin) {
|
386
388
|
results = await engine.lintText(text, {
|
387
389
|
filePath: options.stdinFilename,
|
388
|
-
|
390
|
+
|
391
|
+
// flatConfig respects CLI flag and constructor warnIgnored, eslintrc forces true for backwards compatibility
|
392
|
+
warnIgnored: usingFlatConfig ? void 0 : true
|
389
393
|
});
|
390
394
|
} else {
|
391
395
|
results = await engine.lintFiles(files);
|
@@ -179,9 +179,7 @@ class InvalidRuleSeverityError extends Error {
|
|
179
179
|
* @throws {InvalidRuleSeverityError} If the value isn't a valid rule severity.
|
180
180
|
*/
|
181
181
|
function assertIsRuleSeverity(ruleId, value) {
|
182
|
-
const severity =
|
183
|
-
? ruleSeverities.get(value.toLowerCase())
|
184
|
-
: ruleSeverities.get(value);
|
182
|
+
const severity = ruleSeverities.get(value);
|
185
183
|
|
186
184
|
if (typeof severity === "undefined") {
|
187
185
|
throw new InvalidRuleSeverityError(ruleId, value);
|
@@ -507,7 +505,7 @@ const eslintrcKeys = [
|
|
507
505
|
// Full schema
|
508
506
|
//-----------------------------------------------------------------------------
|
509
507
|
|
510
|
-
|
508
|
+
const flatConfigSchema = {
|
511
509
|
|
512
510
|
// eslintrc-style keys that should always error
|
513
511
|
...Object.fromEntries(eslintrcKeys.map(key => [key, createEslintrcErrorSchema(key)])),
|
@@ -533,3 +531,13 @@ exports.flatConfigSchema = {
|
|
533
531
|
plugins: pluginsSchema,
|
534
532
|
rules: rulesSchema
|
535
533
|
};
|
534
|
+
|
535
|
+
//-----------------------------------------------------------------------------
|
536
|
+
// Exports
|
537
|
+
//-----------------------------------------------------------------------------
|
538
|
+
|
539
|
+
module.exports = {
|
540
|
+
flatConfigSchema,
|
541
|
+
assertIsRuleSeverity,
|
542
|
+
assertIsRuleOptions
|
543
|
+
};
|
@@ -594,9 +594,9 @@ function createIgnoreResult(filePath, baseDir) {
|
|
594
594
|
const isInNodeModules = baseDir && path.dirname(path.relative(baseDir, filePath)).split(path.sep).includes("node_modules");
|
595
595
|
|
596
596
|
if (isInNodeModules) {
|
597
|
-
message = "File ignored by default because it is located under the node_modules directory. Use ignore pattern \"!**/node_modules/\" to
|
597
|
+
message = "File ignored by default because it is located under the node_modules directory. Use ignore pattern \"!**/node_modules/\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
|
598
598
|
} else {
|
599
|
-
message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to
|
599
|
+
message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
|
600
600
|
}
|
601
601
|
|
602
602
|
return {
|
@@ -676,6 +676,7 @@ function processOptions({
|
|
676
676
|
overrideConfigFile = null,
|
677
677
|
plugins = {},
|
678
678
|
reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that.
|
679
|
+
warnIgnored = true,
|
679
680
|
...unknownOptions
|
680
681
|
}) {
|
681
682
|
const errors = [];
|
@@ -781,6 +782,9 @@ function processOptions({
|
|
781
782
|
) {
|
782
783
|
errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null.");
|
783
784
|
}
|
785
|
+
if (typeof warnIgnored !== "boolean") {
|
786
|
+
errors.push("'warnIgnored' must be a boolean.");
|
787
|
+
}
|
784
788
|
if (errors.length > 0) {
|
785
789
|
throw new ESLintInvalidOptionsError(errors);
|
786
790
|
}
|
@@ -802,7 +806,8 @@ function processOptions({
|
|
802
806
|
globInputPaths,
|
803
807
|
ignore,
|
804
808
|
ignorePatterns,
|
805
|
-
reportUnusedDisableDirectives
|
809
|
+
reportUnusedDisableDirectives,
|
810
|
+
warnIgnored
|
806
811
|
};
|
807
812
|
}
|
808
813
|
|
@@ -84,6 +84,7 @@ const LintResultCache = require("../cli-engine/lint-result-cache");
|
|
84
84
|
* when a string.
|
85
85
|
* @property {Record<string,Plugin>} [plugins] An array of plugin implementations.
|
86
86
|
* @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives.
|
87
|
+
* @property {boolean} warnIgnored Show warnings when the file list includes ignored files
|
87
88
|
*/
|
88
89
|
|
89
90
|
//------------------------------------------------------------------------------
|
@@ -749,7 +750,8 @@ class FlatESLint {
|
|
749
750
|
fixTypes,
|
750
751
|
reportUnusedDisableDirectives,
|
751
752
|
globInputPaths,
|
752
|
-
errorOnUnmatchedPattern
|
753
|
+
errorOnUnmatchedPattern,
|
754
|
+
warnIgnored
|
753
755
|
} = eslintOptions;
|
754
756
|
const startTime = Date.now();
|
755
757
|
const fixTypesSet = fixTypes ? new Set(fixTypes) : null;
|
@@ -795,7 +797,11 @@ class FlatESLint {
|
|
795
797
|
* pattern, then notify the user.
|
796
798
|
*/
|
797
799
|
if (ignored) {
|
798
|
-
|
800
|
+
if (warnIgnored) {
|
801
|
+
return createIgnoreResult(filePath, cwd);
|
802
|
+
}
|
803
|
+
|
804
|
+
return void 0;
|
799
805
|
}
|
800
806
|
|
801
807
|
const config = configs.getConfig(filePath);
|
@@ -908,7 +914,7 @@ class FlatESLint {
|
|
908
914
|
|
909
915
|
const {
|
910
916
|
filePath,
|
911
|
-
warnIgnored
|
917
|
+
warnIgnored,
|
912
918
|
...unknownOptions
|
913
919
|
} = options || {};
|
914
920
|
|
@@ -922,7 +928,7 @@ class FlatESLint {
|
|
922
928
|
throw new Error("'options.filePath' must be a non-empty string or undefined");
|
923
929
|
}
|
924
930
|
|
925
|
-
if (typeof warnIgnored !== "boolean") {
|
931
|
+
if (typeof warnIgnored !== "boolean" && typeof warnIgnored !== "undefined") {
|
926
932
|
throw new Error("'options.warnIgnored' must be a boolean or undefined");
|
927
933
|
}
|
928
934
|
|
@@ -937,7 +943,8 @@ class FlatESLint {
|
|
937
943
|
allowInlineConfig,
|
938
944
|
cwd,
|
939
945
|
fix,
|
940
|
-
reportUnusedDisableDirectives
|
946
|
+
reportUnusedDisableDirectives,
|
947
|
+
warnIgnored: constructorWarnIgnored
|
941
948
|
} = eslintOptions;
|
942
949
|
const results = [];
|
943
950
|
const startTime = Date.now();
|
@@ -945,7 +952,9 @@ class FlatESLint {
|
|
945
952
|
|
946
953
|
// Clear the last used config arrays.
|
947
954
|
if (resolvedFilename && await this.isPathIgnored(resolvedFilename)) {
|
948
|
-
|
955
|
+
const shouldWarnIgnored = typeof warnIgnored === "boolean" ? warnIgnored : constructorWarnIgnored;
|
956
|
+
|
957
|
+
if (shouldWarnIgnored) {
|
949
958
|
results.push(createIgnoreResult(resolvedFilename, cwd));
|
950
959
|
}
|
951
960
|
} else {
|
@@ -87,7 +87,7 @@ function createIndividualDirectivesRemoval(directives, commentToken) {
|
|
87
87
|
return directives.map(directive => {
|
88
88
|
const { ruleId } = directive;
|
89
89
|
|
90
|
-
const regex = new RegExp(String.raw`(?:^|\s*,\s*)${escapeRegExp(ruleId)}(?:\s*,\s*|$)`, "u");
|
90
|
+
const regex = new RegExp(String.raw`(?:^|\s*,\s*)(?<quote>['"]?)${escapeRegExp(ruleId)}\k<quote>(?:\s*,\s*|$)`, "u");
|
91
91
|
const match = regex.exec(listText);
|
92
92
|
const matchedText = match[0];
|
93
93
|
const matchStartOffset = listStartOffset + match.index;
|