eslint 8.55.0 → 9.0.0-alpha.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.
Files changed (54) hide show
  1. package/README.md +15 -15
  2. package/conf/rule-type-list.json +3 -1
  3. package/lib/api.js +1 -1
  4. package/lib/cli-engine/cli-engine.js +15 -4
  5. package/lib/cli-engine/formatters/formatters-meta.json +1 -29
  6. package/lib/cli.js +52 -10
  7. package/lib/config/default-config.js +3 -0
  8. package/lib/config/flat-config-array.js +0 -20
  9. package/lib/config/flat-config-helpers.js +41 -20
  10. package/lib/config/flat-config-schema.js +57 -26
  11. package/lib/config/rule-validator.js +27 -4
  12. package/lib/eslint/eslint-helpers.js +35 -22
  13. package/lib/eslint/eslint.js +856 -373
  14. package/lib/eslint/index.js +2 -2
  15. package/lib/eslint/legacy-eslint.js +722 -0
  16. package/lib/linter/apply-disable-directives.js +33 -5
  17. package/lib/linter/config-comment-parser.js +36 -2
  18. package/lib/linter/linter.js +100 -120
  19. package/lib/linter/rules.js +6 -15
  20. package/lib/options.js +17 -1
  21. package/lib/rule-tester/rule-tester.js +240 -272
  22. package/lib/rules/index.js +0 -2
  23. package/lib/rules/no-constant-binary-expression.js +1 -1
  24. package/lib/rules/no-constructor-return.js +1 -1
  25. package/lib/rules/no-empty-static-block.js +1 -1
  26. package/lib/rules/no-extra-semi.js +1 -1
  27. package/lib/rules/no-implicit-coercion.js +17 -1
  28. package/lib/rules/no-inner-declarations.js +1 -1
  29. package/lib/rules/no-invalid-regexp.js +1 -1
  30. package/lib/rules/no-invalid-this.js +1 -1
  31. package/lib/rules/no-mixed-spaces-and-tabs.js +1 -1
  32. package/lib/rules/no-new-native-nonconstructor.js +1 -1
  33. package/lib/rules/no-new-symbol.js +8 -1
  34. package/lib/rules/no-promise-executor-return.js +9 -6
  35. package/lib/rules/no-restricted-properties.js +15 -28
  36. package/lib/rules/no-sequences.js +1 -0
  37. package/lib/rules/no-unused-private-class-members.js +1 -1
  38. package/lib/shared/config-validator.js +44 -11
  39. package/lib/shared/severity.js +49 -0
  40. package/lib/shared/types.js +1 -1
  41. package/lib/source-code/source-code.js +3 -102
  42. package/lib/unsupported-api.js +3 -5
  43. package/package.json +12 -14
  44. package/lib/cli-engine/formatters/checkstyle.js +0 -60
  45. package/lib/cli-engine/formatters/compact.js +0 -60
  46. package/lib/cli-engine/formatters/jslint-xml.js +0 -41
  47. package/lib/cli-engine/formatters/junit.js +0 -82
  48. package/lib/cli-engine/formatters/tap.js +0 -95
  49. package/lib/cli-engine/formatters/unix.js +0 -58
  50. package/lib/cli-engine/formatters/visualstudio.js +0 -63
  51. package/lib/eslint/flat-eslint.js +0 -1149
  52. package/lib/rule-tester/flat-rule-tester.js +0 -1122
  53. package/lib/rules/require-jsdoc.js +0 -122
  54. package/lib/rules/valid-jsdoc.js +0 -516
package/README.md CHANGED
@@ -43,7 +43,7 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
43
43
 
44
44
  ## Installation and Usage
45
45
 
46
- Prerequisites: [Node.js](https://nodejs.org/) (`^12.22.0`, `^14.17.0`, or `>=16.0.0`) built with SSL support. (If you are using an official Node.js distribution, SSL is always built in.)
46
+ Prerequisites: [Node.js](https://nodejs.org/) (`^18.18.0`, `^20.9.0`, or `>=21.1.0`) built with SSL support. (If you are using an official Node.js distribution, SSL is always built in.)
47
47
 
48
48
  You can install and configure ESLint using this command:
49
49
 
@@ -103,7 +103,7 @@ We are now at or near 100% compatibility with JSCS. If you try ESLint and believ
103
103
 
104
104
  ### Does Prettier replace ESLint?
105
105
 
106
- No, ESLint does both traditional linting (looking for problematic patterns) and style checking (enforcement of conventions). You can use ESLint for everything, or you can combine both using Prettier to format your code and ESLint to catch possible errors.
106
+ No, ESLint and Prettier have diffent jobs: ESLint is a linter (looking for problematic patterns) and Prettier is a code formatter. Using both tools is common, refer to [Prettier's documentation](https://prettier.io/docs/en/install#eslint-and-other-linters) to learn how to configure them to work well with each other.
107
107
 
108
108
  ### Why can't ESLint find my plugins?
109
109
 
@@ -209,12 +209,12 @@ The people who manage releases, review feature requests, and meet regularly to e
209
209
 
210
210
  <table><tbody><tr><td align="center" valign="top" width="11%">
211
211
  <a href="https://github.com/nzakas">
212
- <img src="https://github.com/nzakas.png?s=75" width="75" height="75"><br />
212
+ <img src="https://github.com/nzakas.png?s=75" width="75" height="75" alt="Nicholas C. Zakas's Avatar"><br />
213
213
  Nicholas C. Zakas
214
214
  </a>
215
215
  </td><td align="center" valign="top" width="11%">
216
216
  <a href="https://github.com/mdjermanovic">
217
- <img src="https://github.com/mdjermanovic.png?s=75" width="75" height="75"><br />
217
+ <img src="https://github.com/mdjermanovic.png?s=75" width="75" height="75" alt="Milos Djermanovic's Avatar"><br />
218
218
  Milos Djermanovic
219
219
  </a>
220
220
  </td></tr></tbody></table>
@@ -225,12 +225,12 @@ The people who review and implement new features.
225
225
 
226
226
  <table><tbody><tr><td align="center" valign="top" width="11%">
227
227
  <a href="https://github.com/aladdin-add">
228
- <img src="https://github.com/aladdin-add.png?s=75" width="75" height="75"><br />
228
+ <img src="https://github.com/aladdin-add.png?s=75" width="75" height="75" alt="唯然's Avatar"><br />
229
229
  唯然
230
230
  </a>
231
231
  </td><td align="center" valign="top" width="11%">
232
232
  <a href="https://github.com/snitin315">
233
- <img src="https://github.com/snitin315.png?s=75" width="75" height="75"><br />
233
+ <img src="https://github.com/snitin315.png?s=75" width="75" height="75" alt="Nitin Kumar's Avatar"><br />
234
234
  Nitin Kumar
235
235
  </a>
236
236
  </td></tr></tbody></table>
@@ -241,22 +241,22 @@ The people who review and fix bugs and help triage issues.
241
241
 
242
242
  <table><tbody><tr><td align="center" valign="top" width="11%">
243
243
  <a href="https://github.com/bmish">
244
- <img src="https://github.com/bmish.png?s=75" width="75" height="75"><br />
244
+ <img src="https://github.com/bmish.png?s=75" width="75" height="75" alt="Bryan Mishkin's Avatar"><br />
245
245
  Bryan Mishkin
246
246
  </a>
247
247
  </td><td align="center" valign="top" width="11%">
248
248
  <a href="https://github.com/fasttime">
249
- <img src="https://github.com/fasttime.png?s=75" width="75" height="75"><br />
249
+ <img src="https://github.com/fasttime.png?s=75" width="75" height="75" alt="Francesco Trotta's Avatar"><br />
250
250
  Francesco Trotta
251
251
  </a>
252
252
  </td><td align="center" valign="top" width="11%">
253
253
  <a href="https://github.com/ota-meshi">
254
- <img src="https://github.com/ota-meshi.png?s=75" width="75" height="75"><br />
254
+ <img src="https://github.com/ota-meshi.png?s=75" width="75" height="75" alt="Yosuke Ota's Avatar"><br />
255
255
  Yosuke Ota
256
256
  </a>
257
257
  </td><td align="center" valign="top" width="11%">
258
258
  <a href="https://github.com/Tanujkanti4441">
259
- <img src="https://github.com/Tanujkanti4441.png?s=75" width="75" height="75"><br />
259
+ <img src="https://github.com/Tanujkanti4441.png?s=75" width="75" height="75" alt="Tanuj Kanti's Avatar"><br />
260
260
  Tanuj Kanti
261
261
  </a>
262
262
  </td></tr></tbody></table>
@@ -267,17 +267,17 @@ Team members who focus specifically on eslint.org
267
267
 
268
268
  <table><tbody><tr><td align="center" valign="top" width="11%">
269
269
  <a href="https://github.com/amareshsm">
270
- <img src="https://github.com/amareshsm.png?s=75" width="75" height="75"><br />
270
+ <img src="https://github.com/amareshsm.png?s=75" width="75" height="75" alt="Amaresh S M's Avatar"><br />
271
271
  Amaresh S M
272
272
  </a>
273
273
  </td><td align="center" valign="top" width="11%">
274
274
  <a href="https://github.com/harish-sethuraman">
275
- <img src="https://github.com/harish-sethuraman.png?s=75" width="75" height="75"><br />
275
+ <img src="https://github.com/harish-sethuraman.png?s=75" width="75" height="75" alt="Strek's Avatar"><br />
276
276
  Strek
277
277
  </a>
278
278
  </td><td align="center" valign="top" width="11%">
279
279
  <a href="https://github.com/kecrily">
280
- <img src="https://github.com/kecrily.png?s=75" width="75" height="75"><br />
280
+ <img src="https://github.com/kecrily.png?s=75" width="75" height="75" alt="Percy Ma's Avatar"><br />
281
281
  Percy Ma
282
282
  </a>
283
283
  </td></tr></tbody></table>
@@ -293,8 +293,8 @@ The following companies, organizations, and individuals support ESLint's ongoing
293
293
  <h3>Platinum Sponsors</h3>
294
294
  <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>
295
295
  <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>
296
- <p><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></p><h3>Bronze Sponsors</h3>
297
- <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></p>
296
+ <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>
297
+ <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://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></p>
298
298
  <!--sponsorsend-->
299
299
 
300
300
  ## Technology Sponsors
@@ -23,6 +23,8 @@
23
23
  { "removed": "space-in-brackets", "replacedBy": ["object-curly-spacing", "array-bracket-spacing"] },
24
24
  { "removed": "space-return-throw-case", "replacedBy": ["keyword-spacing"] },
25
25
  { "removed": "space-unary-word-ops", "replacedBy": ["space-unary-ops"] },
26
- { "removed": "spaced-line-comment", "replacedBy": ["spaced-comment"] }
26
+ { "removed": "spaced-line-comment", "replacedBy": ["spaced-comment"] },
27
+ { "removed": "valid-jsdoc", "replacedBy": [] },
28
+ { "removed": "require-jsdoc", "replacedBy": [] }
27
29
  ]
28
30
  }
package/lib/api.js CHANGED
@@ -9,7 +9,7 @@
9
9
  // Requirements
10
10
  //-----------------------------------------------------------------------------
11
11
 
12
- const { ESLint } = require("./eslint");
12
+ const { ESLint } = require("./eslint/eslint");
13
13
  const { Linter } = require("./linter");
14
14
  const { RuleTester } = require("./rule-tester");
15
15
  const { SourceCode } = require("./source-code");
@@ -41,6 +41,17 @@ const hash = require("./hash");
41
41
  const LintResultCache = require("./lint-result-cache");
42
42
 
43
43
  const debug = require("debug")("eslint:cli-engine");
44
+ const removedFormatters = new Set([
45
+ "checkstyle",
46
+ "codeframe",
47
+ "compact",
48
+ "jslint-xml",
49
+ "junit",
50
+ "table",
51
+ "tap",
52
+ "unix",
53
+ "visualstudio"
54
+ ]);
44
55
  const validFixTypes = new Set(["directive", "problem", "suggestion", "layout"]);
45
56
 
46
57
  //------------------------------------------------------------------------------
@@ -83,7 +94,7 @@ const validFixTypes = new Set(["directive", "problem", "suggestion", "layout"]);
83
94
  * @property {string[]} [plugins] An array of plugins to load.
84
95
  * @property {Record<string,RuleConf>} [rules] An object of rules to use.
85
96
  * @property {string[]} [rulePaths] An array of directories to load custom rules from.
86
- * @property {boolean} [reportUnusedDisableDirectives] `true` adds reports for unused eslint-disable directives
97
+ * @property {boolean|string} [reportUnusedDisableDirectives] `true`, `"error"` or '"warn"' adds reports for unused eslint-disable directives
87
98
  * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
88
99
  * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD
89
100
  */
@@ -224,7 +235,7 @@ function calculateStatsPerRun(results) {
224
235
  * @param {ConfigArray} config.config The config.
225
236
  * @param {boolean} config.fix If `true` then it does fix.
226
237
  * @param {boolean} config.allowInlineConfig If `true` then it uses directive comments.
227
- * @param {boolean} config.reportUnusedDisableDirectives If `true` then it reports unused `eslint-disable` comments.
238
+ * @param {boolean|string} config.reportUnusedDisableDirectives If `true`, `"error"` or '"warn"', then it reports unused `eslint-disable` comments.
228
239
  * @param {FileEnumerator} config.fileEnumerator The file enumerator to check if a path is a target or not.
229
240
  * @param {Linter} config.linter The linter instance to verify.
230
241
  * @returns {LintResult} The result of linting.
@@ -639,7 +650,7 @@ class CLIEngine {
639
650
  });
640
651
  const lintResultCache =
641
652
  options.cache ? new LintResultCache(cacheFilePath, options.cacheStrategy) : null;
642
- const linter = new Linter({ cwd: options.cwd });
653
+ const linter = new Linter({ cwd: options.cwd, configType: "eslintrc" });
643
654
 
644
655
  /** @type {ConfigArray[]} */
645
656
  const lastConfigArrays = [configArrayFactory.getConfigArrayForFile()];
@@ -1047,7 +1058,7 @@ class CLIEngine {
1047
1058
  try {
1048
1059
  return require(formatterPath);
1049
1060
  } catch (ex) {
1050
- if (format === "table" || format === "codeframe") {
1061
+ if (removedFormatters.has(format)) {
1051
1062
  ex.message = `The ${format} formatter is no longer part of core ESLint. Install it manually with \`npm install -D eslint-formatter-${format}\``;
1052
1063
  } else {
1053
1064
  ex.message = `There was a problem loading formatter: ${formatterPath}\nError: ${ex.message}`;
@@ -1,20 +1,8 @@
1
1
  [
2
- {
3
- "name": "checkstyle",
4
- "description": "Outputs results to the [Checkstyle](https://checkstyle.sourceforge.io/) format."
5
- },
6
- {
7
- "name": "compact",
8
- "description": "Human-readable output format. Mimics the default output of JSHint."
9
- },
10
2
  {
11
3
  "name": "html",
12
4
  "description": "Outputs results to HTML. The `html` formatter is useful for visual presentation in the browser."
13
5
  },
14
- {
15
- "name": "jslint-xml",
16
- "description": "Outputs results to format compatible with the [JSLint Jenkins plugin](https://plugins.jenkins.io/jslint/)."
17
- },
18
6
  {
19
7
  "name": "json-with-metadata",
20
8
  "description": "Outputs JSON-serialized results. The `json-with-metadata` provides the same linting results as the [`json`](#json) formatter with additional metadata about the rules applied. The linting results are included in the `results` property and the rules metadata is included in the `metadata` property.\n\nAlternatively, you can use the [ESLint Node.js API](../../integrate/nodejs-api) to programmatically use ESLint."
@@ -23,24 +11,8 @@
23
11
  "name": "json",
24
12
  "description": "Outputs JSON-serialized results. The `json` formatter is useful when you want to programmatically work with the CLI's linting results.\n\nAlternatively, you can use the [ESLint Node.js API](../../integrate/nodejs-api) to programmatically use ESLint."
25
13
  },
26
- {
27
- "name": "junit",
28
- "description": "Outputs results to format compatible with the [JUnit Jenkins plugin](https://plugins.jenkins.io/junit/)."
29
- },
30
14
  {
31
15
  "name": "stylish",
32
16
  "description": "Human-readable output format. This is the default formatter."
33
- },
34
- {
35
- "name": "tap",
36
- "description": "Outputs results to the [Test Anything Protocol (TAP)](https://testanything.org/) specification format."
37
- },
38
- {
39
- "name": "unix",
40
- "description": "Outputs results to a format similar to many commands in UNIX-like systems. Parsable with tools such as [grep](https://www.gnu.org/software/grep/manual/grep.html), [sed](https://www.gnu.org/software/sed/manual/sed.html), and [awk](https://www.gnu.org/software/gawk/manual/gawk.html)."
41
- },
42
- {
43
- "name": "visualstudio",
44
- "description": "Outputs results to format compatible with the integrated terminal of the [Visual Studio](https://visualstudio.microsoft.com/) IDE. When using Visual Studio, you can click on the linting results in the integrated terminal to go to the issue in the source code."
45
17
  }
46
- ]
18
+ ]
package/lib/cli.js CHANGED
@@ -18,11 +18,12 @@
18
18
  const fs = require("fs"),
19
19
  path = require("path"),
20
20
  { promisify } = require("util"),
21
- { ESLint } = require("./eslint"),
22
- { FlatESLint, shouldUseFlatConfig } = require("./eslint/flat-eslint"),
21
+ { LegacyESLint } = require("./eslint"),
22
+ { ESLint, shouldUseFlatConfig } = require("./eslint/eslint"),
23
23
  createCLIOptions = require("./options"),
24
24
  log = require("./shared/logging"),
25
- RuntimeInfo = require("./shared/runtime-info");
25
+ RuntimeInfo = require("./shared/runtime-info"),
26
+ { normalizeSeverityToString } = require("./shared/severity");
26
27
  const { Legacy: { naming } } = require("@eslint/eslintrc");
27
28
  const { ModuleImporter } = require("@humanwhocodes/module-importer");
28
29
 
@@ -57,6 +58,16 @@ function quietFixPredicate(message) {
57
58
  return message.severity === 2;
58
59
  }
59
60
 
61
+ /**
62
+ * Predicate function for whether or not to run a rule in quiet mode.
63
+ * If a rule is set to warning, do not run it.
64
+ * @param {{ ruleId: string; severity: number; }} rule The rule id and severity.
65
+ * @returns {boolean} True if the lint rule should run, false otherwise.
66
+ */
67
+ function quietRuleFilter(rule) {
68
+ return rule.severity === 2;
69
+ }
70
+
60
71
  /**
61
72
  * Translates the CLI options into the options expected by the ESLint constructor.
62
73
  * @param {ParsedCLIOptions} cliOptions The CLI options to translate.
@@ -89,10 +100,13 @@ async function translateOptions({
89
100
  plugin,
90
101
  quiet,
91
102
  reportUnusedDisableDirectives,
103
+ reportUnusedDisableDirectivesSeverity,
92
104
  resolvePluginsRelativeTo,
93
105
  rule,
94
106
  rulesdir,
95
- warnIgnored
107
+ warnIgnored,
108
+ passOnNoPatterns,
109
+ maxWarnings
96
110
  }, configType) {
97
111
 
98
112
  let overrideConfig, overrideConfigFile;
@@ -125,6 +139,14 @@ async function translateOptions({
125
139
  rules: rule ? rule : {}
126
140
  }];
127
141
 
142
+ if (reportUnusedDisableDirectives || reportUnusedDisableDirectivesSeverity !== void 0) {
143
+ overrideConfig[0].linterOptions = {
144
+ reportUnusedDisableDirectives: reportUnusedDisableDirectives
145
+ ? "error"
146
+ : normalizeSeverityToString(reportUnusedDisableDirectivesSeverity)
147
+ };
148
+ }
149
+
128
150
  if (parser) {
129
151
  overrideConfig[0].languageOptions.parser = await importer.import(parser);
130
152
  }
@@ -178,18 +200,29 @@ async function translateOptions({
178
200
  ignore,
179
201
  overrideConfig,
180
202
  overrideConfigFile,
181
- reportUnusedDisableDirectives: reportUnusedDisableDirectives ? "error" : void 0
203
+ passOnNoPatterns
182
204
  };
183
205
 
184
206
  if (configType === "flat") {
185
207
  options.ignorePatterns = ignorePattern;
186
208
  options.warnIgnored = warnIgnored;
209
+
210
+ /*
211
+ * For performance reasons rules not marked as 'error' are filtered out in quiet mode. As maxWarnings
212
+ * requires rules set to 'warn' to be run, we only filter out 'warn' rules if maxWarnings is not specified.
213
+ */
214
+ options.ruleFilter = quiet && maxWarnings === -1 ? quietRuleFilter : () => true;
187
215
  } else {
188
216
  options.resolvePluginsRelativeTo = resolvePluginsRelativeTo;
189
217
  options.rulePaths = rulesdir;
190
218
  options.useEslintrc = eslintrc;
191
219
  options.extensions = ext;
192
220
  options.ignorePath = ignorePath;
221
+ if (reportUnusedDisableDirectives || reportUnusedDisableDirectivesSeverity !== void 0) {
222
+ options.reportUnusedDisableDirectives = reportUnusedDisableDirectives
223
+ ? "error"
224
+ : normalizeSeverityToString(reportUnusedDisableDirectivesSeverity);
225
+ }
193
226
  }
194
227
 
195
228
  return options;
@@ -290,10 +323,10 @@ const cli = {
290
323
  * Executes the CLI based on an array of arguments that is passed in.
291
324
  * @param {string|Array|Object} args The arguments to process.
292
325
  * @param {string} [text] The text to lint (used for TTY).
293
- * @param {boolean} [allowFlatConfig] Whether or not to allow flat config.
326
+ * @param {boolean} [allowFlatConfig=true] Whether or not to allow flat config.
294
327
  * @returns {Promise<number>} The exit code for the operation.
295
328
  */
296
- async execute(args, text, allowFlatConfig) {
329
+ async execute(args, text, allowFlatConfig = true) {
297
330
  if (Array.isArray(args)) {
298
331
  debug("CLI args: %o", args.slice(2));
299
332
  }
@@ -309,6 +342,10 @@ const cli = {
309
342
 
310
343
  debug("Using flat config?", usingFlatConfig);
311
344
 
345
+ if (allowFlatConfig && !usingFlatConfig) {
346
+ process.emitWarning("You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details.", "ESLintRCWarning");
347
+ }
348
+
312
349
  const CLIOptions = createCLIOptions(usingFlatConfig);
313
350
 
314
351
  /** @type {ParsedCLIOptions} */
@@ -362,8 +399,8 @@ const cli = {
362
399
  }
363
400
 
364
401
  const engine = usingFlatConfig
365
- ? new FlatESLint(await translateOptions(options, "flat"))
366
- : new ESLint(await translateOptions(options));
402
+ ? new ESLint(await translateOptions(options, "flat"))
403
+ : new LegacyESLint(await translateOptions(options));
367
404
  const fileConfig =
368
405
  await engine.calculateConfigForFile(options.printConfig);
369
406
 
@@ -386,7 +423,12 @@ const cli = {
386
423
  return 2;
387
424
  }
388
425
 
389
- const ActiveESLint = usingFlatConfig ? FlatESLint : ESLint;
426
+ if (options.reportUnusedDisableDirectives && options.reportUnusedDisableDirectivesSeverity !== void 0) {
427
+ log.error("The --report-unused-disable-directives option and the --report-unused-disable-directives-severity option cannot be used together.");
428
+ return 2;
429
+ }
430
+
431
+ const ActiveESLint = usingFlatConfig ? ESLint : LegacyESLint;
390
432
 
391
433
  const engine = new ActiveESLint(await translateOptions(options, usingFlatConfig ? "flat" : "eslintrc"));
392
434
  let results;
@@ -42,6 +42,9 @@ exports.defaultConfig = [
42
42
  ecmaVersion: "latest",
43
43
  parser: require("espree"),
44
44
  parserOptions: {}
45
+ },
46
+ linterOptions: {
47
+ reportUnusedDisableDirectives: 1
45
48
  }
46
49
  },
47
50
 
@@ -13,7 +13,6 @@ const { ConfigArray, ConfigArraySymbol } = require("@humanwhocodes/config-array"
13
13
  const { flatConfigSchema } = require("./flat-config-schema");
14
14
  const { RuleValidator } = require("./rule-validator");
15
15
  const { defaultConfig } = require("./default-config");
16
- const jsPlugin = require("@eslint/js");
17
16
 
18
17
  //-----------------------------------------------------------------------------
19
18
  // Helpers
@@ -134,25 +133,6 @@ class FlatConfigArray extends ConfigArray {
134
133
  * @returns {Object} The preprocessed config.
135
134
  */
136
135
  [ConfigArraySymbol.preprocessConfig](config) {
137
- if (config === "eslint:recommended") {
138
-
139
- // if we are in a Node.js environment warn the user
140
- if (typeof process !== "undefined" && process.emitWarning) {
141
- process.emitWarning("The 'eslint:recommended' string configuration is deprecated and will be replaced by the @eslint/js package's 'recommended' config.");
142
- }
143
-
144
- return jsPlugin.configs.recommended;
145
- }
146
-
147
- if (config === "eslint:all") {
148
-
149
- // if we are in a Node.js environment warn the user
150
- if (typeof process !== "undefined" && process.emitWarning) {
151
- process.emitWarning("The 'eslint:all' string configuration is deprecated and will be replaced by the @eslint/js package's 'all' config.");
152
- }
153
-
154
- return jsPlugin.configs.all;
155
- }
156
136
 
157
137
  /*
158
138
  * If `shouldIgnore` is false, we remove any ignore patterns specified
@@ -5,6 +5,23 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Typedefs
10
+ //------------------------------------------------------------------------------
11
+
12
+ /** @typedef {import("../shared/types").Rule} Rule */
13
+
14
+ //------------------------------------------------------------------------------
15
+ // Private Members
16
+ //------------------------------------------------------------------------------
17
+
18
+ // JSON schema that disallows passing any options
19
+ const noOptionsSchema = Object.freeze({
20
+ type: "array",
21
+ minItems: 0,
22
+ maxItems: 0
23
+ });
24
+
8
25
  //-----------------------------------------------------------------------------
9
26
  // Functions
10
27
  //-----------------------------------------------------------------------------
@@ -52,32 +69,39 @@ function getRuleFromConfig(ruleId, config) {
52
69
  const { pluginName, ruleName } = parseRuleId(ruleId);
53
70
 
54
71
  const plugin = config.plugins && config.plugins[pluginName];
55
- let rule = plugin && plugin.rules && plugin.rules[ruleName];
56
-
57
-
58
- // normalize function rules into objects
59
- if (rule && typeof rule === "function") {
60
- rule = {
61
- create: rule
62
- };
63
- }
72
+ const rule = plugin && plugin.rules && plugin.rules[ruleName];
64
73
 
65
74
  return rule;
66
75
  }
67
76
 
68
77
  /**
69
78
  * Gets a complete options schema for a rule.
70
- * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object
71
- * @returns {Object} JSON Schema for the rule's options.
79
+ * @param {Rule} rule A rule object
80
+ * @throws {TypeError} If `meta.schema` is specified but is not an array, object or `false`.
81
+ * @returns {Object|null} JSON Schema for the rule's options. `null` if `meta.schema` is `false`.
72
82
  */
73
83
  function getRuleOptionsSchema(rule) {
74
84
 
75
- if (!rule) {
85
+ if (!rule.meta) {
86
+ return { ...noOptionsSchema }; // default if `meta.schema` is not specified
87
+ }
88
+
89
+ const schema = rule.meta.schema;
90
+
91
+ if (typeof schema === "undefined") {
92
+ return { ...noOptionsSchema }; // default if `meta.schema` is not specified
93
+ }
94
+
95
+ // `schema:false` is an allowed explicit opt-out of options validation for the rule
96
+ if (schema === false) {
76
97
  return null;
77
98
  }
78
99
 
79
- const schema = rule.schema || rule.meta && rule.meta.schema;
100
+ if (typeof schema !== "object" || schema === null) {
101
+ throw new TypeError("Rule's `meta.schema` must be an array or object");
102
+ }
80
103
 
104
+ // ESLint-specific array form needs to be converted into a valid JSON Schema definition
81
105
  if (Array.isArray(schema)) {
82
106
  if (schema.length) {
83
107
  return {
@@ -87,16 +111,13 @@ function getRuleOptionsSchema(rule) {
87
111
  maxItems: schema.length
88
112
  };
89
113
  }
90
- return {
91
- type: "array",
92
- minItems: 0,
93
- maxItems: 0
94
- };
95
114
 
115
+ // `schema:[]` is an explicit way to specify that the rule does not accept any options
116
+ return { ...noOptionsSchema };
96
117
  }
97
118
 
98
- // Given a full schema, leave it alone
99
- return schema || null;
119
+ // `schema:<object>` is assumed to be a valid JSON Schema definition
120
+ return schema;
100
121
  }
101
122
 
102
123