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
@@ -273,7 +273,6 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
273
273
  radix: () => require("./radix"),
274
274
  "require-atomic-updates": () => require("./require-atomic-updates"),
275
275
  "require-await": () => require("./require-await"),
276
- "require-jsdoc": () => require("./require-jsdoc"),
277
276
  "require-unicode-regexp": () => require("./require-unicode-regexp"),
278
277
  "require-yield": () => require("./require-yield"),
279
278
  "rest-spread-spacing": () => require("./rest-spread-spacing"),
@@ -296,7 +295,6 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
296
295
  "template-tag-spacing": () => require("./template-tag-spacing"),
297
296
  "unicode-bom": () => require("./unicode-bom"),
298
297
  "use-isnan": () => require("./use-isnan"),
299
- "valid-jsdoc": () => require("./valid-jsdoc"),
300
298
  "valid-typeof": () => require("./valid-typeof"),
301
299
  "vars-on-top": () => require("./vars-on-top"),
302
300
  "wrap-iife": () => require("./wrap-iife"),
@@ -440,7 +440,7 @@ module.exports = {
440
440
  type: "problem",
441
441
  docs: {
442
442
  description: "Disallow expressions where the operation doesn't affect the value",
443
- recommended: false,
443
+ recommended: true,
444
444
  url: "https://eslint.org/docs/latest/rules/no-constant-binary-expression"
445
445
  },
446
446
  schema: [],
@@ -20,7 +20,7 @@ module.exports = {
20
20
  url: "https://eslint.org/docs/latest/rules/no-constructor-return"
21
21
  },
22
22
 
23
- schema: {},
23
+ schema: [],
24
24
 
25
25
  fixable: null,
26
26
 
@@ -15,7 +15,7 @@ module.exports = {
15
15
 
16
16
  docs: {
17
17
  description: "Disallow empty static blocks",
18
- recommended: false,
18
+ recommended: true,
19
19
  url: "https://eslint.org/docs/latest/rules/no-empty-static-block"
20
20
  },
21
21
 
@@ -26,7 +26,7 @@ module.exports = {
26
26
 
27
27
  docs: {
28
28
  description: "Disallow unnecessary semicolons",
29
- recommended: true,
29
+ recommended: false,
30
30
  url: "https://eslint.org/docs/latest/rules/no-extra-semi"
31
31
  },
32
32
 
@@ -12,7 +12,7 @@ const astUtils = require("./utils/ast-utils");
12
12
  //------------------------------------------------------------------------------
13
13
 
14
14
  const INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/u;
15
- const ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"];
15
+ const ALLOWABLE_OPERATORS = ["~", "!!", "+", "- -", "-", "*"];
16
16
 
17
17
  /**
18
18
  * Parses and normalizes an option object.
@@ -300,6 +300,14 @@ module.exports = {
300
300
 
301
301
  report(node, recommendation, true);
302
302
  }
303
+
304
+ // -(-foo)
305
+ operatorAllowed = options.allow.includes("- -");
306
+ if (!operatorAllowed && options.number && node.operator === "-" && node.argument.type === "UnaryExpression" && node.argument.operator === "-" && !isNumeric(node.argument.argument)) {
307
+ const recommendation = `Number(${sourceCode.getText(node.argument.argument)})`;
308
+
309
+ report(node, recommendation, false);
310
+ }
303
311
  },
304
312
 
305
313
  // Use `:exit` to prevent double reporting
@@ -317,6 +325,14 @@ module.exports = {
317
325
  report(node, recommendation, true);
318
326
  }
319
327
 
328
+ // foo - 0
329
+ operatorAllowed = options.allow.includes("-");
330
+ if (!operatorAllowed && options.number && node.operator === "-" && node.right.type === "Literal" && node.right.value === 0 && !isNumeric(node.left)) {
331
+ const recommendation = `Number(${sourceCode.getText(node.left)})`;
332
+
333
+ report(node, recommendation, true);
334
+ }
335
+
320
336
  // "" + foo
321
337
  operatorAllowed = options.allow.includes("+");
322
338
  if (!operatorAllowed && options.string && isConcatWithEmptyString(node)) {
@@ -49,7 +49,7 @@ module.exports = {
49
49
 
50
50
  docs: {
51
51
  description: "Disallow variable or `function` declarations in nested blocks",
52
- recommended: true,
52
+ recommended: false,
53
53
  url: "https://eslint.org/docs/latest/rules/no-inner-declarations"
54
54
  },
55
55
 
@@ -55,7 +55,7 @@ module.exports = {
55
55
  const temp = options.allowConstructorFlags.join("").replace(validFlags, "");
56
56
 
57
57
  if (temp) {
58
- allowedFlags = new RegExp(`[${temp}]`, "giu");
58
+ allowedFlags = new RegExp(`[${temp}]`, "gu");
59
59
  }
60
60
  }
61
61
 
@@ -96,7 +96,7 @@ module.exports = {
96
96
 
97
97
  if (codePath.origin === "program") {
98
98
  const scope = sourceCode.getScope(node);
99
- const features = context.parserOptions.ecmaFeatures || {};
99
+ const features = context.languageOptions.parserOptions.ecmaFeatures || {};
100
100
 
101
101
  // `this` at the top level of scripts always refers to the global object
102
102
  stack.push({
@@ -18,7 +18,7 @@ module.exports = {
18
18
 
19
19
  docs: {
20
20
  description: "Disallow mixed spaces and tabs for indentation",
21
- recommended: true,
21
+ recommended: false,
22
22
  url: "https://eslint.org/docs/latest/rules/no-mixed-spaces-and-tabs"
23
23
  },
24
24
 
@@ -22,7 +22,7 @@ module.exports = {
22
22
 
23
23
  docs: {
24
24
  description: "Disallow `new` operators with global non-constructor functions",
25
- recommended: false,
25
+ recommended: true,
26
26
  url: "https://eslint.org/docs/latest/rules/no-new-native-nonconstructor"
27
27
  },
28
28
 
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to disallow use of the new operator with the `Symbol` object
3
3
  * @author Alberto Rodríguez
4
+ * @deprecated in ESLint v9.0.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -16,10 +17,16 @@ module.exports = {
16
17
 
17
18
  docs: {
18
19
  description: "Disallow `new` operators with the `Symbol` object",
19
- recommended: true,
20
+ recommended: false,
20
21
  url: "https://eslint.org/docs/latest/rules/no-new-symbol"
21
22
  },
22
23
 
24
+ deprecated: true,
25
+
26
+ replacedBy: [
27
+ "no-new-native-nonconstructor"
28
+ ],
29
+
23
30
  schema: [],
24
31
 
25
32
  messages: {
@@ -209,12 +209,15 @@ module.exports = {
209
209
  });
210
210
  }
211
211
 
212
- suggest.push({
213
- messageId: "wrapBraces",
214
- fix(fixer) {
215
- return curlyWrapFixer(sourceCode, node, fixer);
216
- }
217
- });
212
+ // Do not suggest wrapping an unnamed FunctionExpression in braces as that would be invalid syntax.
213
+ if (!(node.body.type === "FunctionExpression" && !node.body.id)) {
214
+ suggest.push({
215
+ messageId: "wrapBraces",
216
+ fix(fixer) {
217
+ return curlyWrapFixer(sourceCode, node, fixer);
218
+ }
219
+ });
220
+ }
218
221
 
219
222
  context.report({
220
223
  node: node.body,
@@ -142,40 +142,27 @@ module.exports = {
142
142
  }
143
143
  }
144
144
 
145
- /**
146
- * Checks property accesses in a destructuring assignment expression, e.g. `var foo; ({foo} = bar);`
147
- * @param {ASTNode} node An AssignmentExpression or AssignmentPattern node
148
- * @returns {undefined}
149
- */
150
- function checkDestructuringAssignment(node) {
151
- if (node.right.type === "Identifier") {
152
- const objectName = node.right.name;
153
-
154
- if (node.left.type === "ObjectPattern") {
155
- node.left.properties.forEach(property => {
156
- checkPropertyAccess(node.left, objectName, astUtils.getStaticPropertyName(property));
157
- });
158
- }
159
- }
160
- }
161
-
162
145
  return {
163
146
  MemberExpression(node) {
164
147
  checkPropertyAccess(node, node.object && node.object.name, astUtils.getStaticPropertyName(node));
165
148
  },
166
- VariableDeclarator(node) {
167
- if (node.init && node.init.type === "Identifier") {
168
- const objectName = node.init.name;
169
-
170
- if (node.id.type === "ObjectPattern") {
171
- node.id.properties.forEach(property => {
172
- checkPropertyAccess(node.id, objectName, astUtils.getStaticPropertyName(property));
173
- });
149
+ ObjectPattern(node) {
150
+ let objectName = null;
151
+
152
+ if (node.parent.type === "VariableDeclarator") {
153
+ if (node.parent.init && node.parent.init.type === "Identifier") {
154
+ objectName = node.parent.init.name;
155
+ }
156
+ } else if (node.parent.type === "AssignmentExpression" || node.parent.type === "AssignmentPattern") {
157
+ if (node.parent.right.type === "Identifier") {
158
+ objectName = node.parent.right.name;
174
159
  }
175
160
  }
176
- },
177
- AssignmentExpression: checkDestructuringAssignment,
178
- AssignmentPattern: checkDestructuringAssignment
161
+
162
+ node.properties.forEach(property => {
163
+ checkPropertyAccess(node, objectName, astUtils.getStaticPropertyName(property));
164
+ });
165
+ }
179
166
  };
180
167
  }
181
168
  };
@@ -35,6 +35,7 @@ module.exports = {
35
35
  },
36
36
 
37
37
  schema: [{
38
+ type: "object",
38
39
  properties: {
39
40
  allowInParentheses: {
40
41
  type: "boolean",
@@ -16,7 +16,7 @@ module.exports = {
16
16
 
17
17
  docs: {
18
18
  description: "Disallow unused private class members",
19
- recommended: false,
19
+ recommended: true,
20
20
  url: "https://eslint.org/docs/latest/rules/no-unused-private-class-members"
21
21
  },
22
22
 
@@ -17,6 +17,23 @@
17
17
 
18
18
  "use strict";
19
19
 
20
+ //------------------------------------------------------------------------------
21
+ // Typedefs
22
+ //------------------------------------------------------------------------------
23
+
24
+ /** @typedef {import("../shared/types").Rule} Rule */
25
+
26
+ //------------------------------------------------------------------------------
27
+ // Private Members
28
+ //------------------------------------------------------------------------------
29
+
30
+ // JSON schema that disallows passing any options
31
+ const noOptionsSchema = Object.freeze({
32
+ type: "array",
33
+ minItems: 0,
34
+ maxItems: 0
35
+ });
36
+
20
37
  //------------------------------------------------------------------------------
21
38
  // Requirements
22
39
  //------------------------------------------------------------------------------
@@ -49,17 +66,36 @@ const severityMap = {
49
66
 
50
67
  /**
51
68
  * Gets a complete options schema for a rule.
52
- * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object
53
- * @returns {Object} JSON Schema for the rule's options.
69
+ * @param {Rule} rule A rule object
70
+ * @throws {TypeError} If `meta.schema` is specified but is not an array, object or `false`.
71
+ * @returns {Object|null} JSON Schema for the rule's options.
72
+ * `null` if rule wasn't passed or its `meta.schema` is `false`.
54
73
  */
55
74
  function getRuleOptionsSchema(rule) {
56
75
  if (!rule) {
57
76
  return null;
58
77
  }
59
78
 
60
- const schema = rule.schema || rule.meta && rule.meta.schema;
79
+ if (!rule.meta) {
80
+ return { ...noOptionsSchema }; // default if `meta.schema` is not specified
81
+ }
82
+
83
+ const schema = rule.meta.schema;
84
+
85
+ if (typeof schema === "undefined") {
86
+ return { ...noOptionsSchema }; // default if `meta.schema` is not specified
87
+ }
88
+
89
+ // `schema:false` is an allowed explicit opt-out of options validation for the rule
90
+ if (schema === false) {
91
+ return null;
92
+ }
93
+
94
+ if (typeof schema !== "object" || schema === null) {
95
+ throw new TypeError("Rule's `meta.schema` must be an array or object");
96
+ }
61
97
 
62
- // Given a tuple of schemas, insert warning level at the beginning
98
+ // ESLint-specific array form needs to be converted into a valid JSON Schema definition
63
99
  if (Array.isArray(schema)) {
64
100
  if (schema.length) {
65
101
  return {
@@ -69,16 +105,13 @@ function getRuleOptionsSchema(rule) {
69
105
  maxItems: schema.length
70
106
  };
71
107
  }
72
- return {
73
- type: "array",
74
- minItems: 0,
75
- maxItems: 0
76
- };
77
108
 
109
+ // `schema:[]` is an explicit way to specify that the rule does not accept any options
110
+ return { ...noOptionsSchema };
78
111
  }
79
112
 
80
- // Given a full schema, leave it alone
81
- return schema || null;
113
+ // `schema:<object>` is assumed to be a valid JSON Schema definition
114
+ return schema;
82
115
  }
83
116
 
84
117
  /**
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @fileoverview Helpers for severity values (e.g. normalizing different types).
3
+ * @author Bryan Mishkin
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /**
9
+ * Convert severity value of different types to a string.
10
+ * @param {string|number} severity severity value
11
+ * @throws error if severity is invalid
12
+ * @returns {string} severity string
13
+ */
14
+ function normalizeSeverityToString(severity) {
15
+ if ([2, "2", "error"].includes(severity)) {
16
+ return "error";
17
+ }
18
+ if ([1, "1", "warn"].includes(severity)) {
19
+ return "warn";
20
+ }
21
+ if ([0, "0", "off"].includes(severity)) {
22
+ return "off";
23
+ }
24
+ throw new Error(`Invalid severity value: ${severity}`);
25
+ }
26
+
27
+ /**
28
+ * Convert severity value of different types to a number.
29
+ * @param {string|number} severity severity value
30
+ * @throws error if severity is invalid
31
+ * @returns {number} severity number
32
+ */
33
+ function normalizeSeverityToNumber(severity) {
34
+ if ([2, "2", "error"].includes(severity)) {
35
+ return 2;
36
+ }
37
+ if ([1, "1", "warn"].includes(severity)) {
38
+ return 1;
39
+ }
40
+ if ([0, "0", "off"].includes(severity)) {
41
+ return 0;
42
+ }
43
+ throw new Error(`Invalid severity value: ${severity}`);
44
+ }
45
+
46
+ module.exports = {
47
+ normalizeSeverityToString,
48
+ normalizeSeverityToNumber
49
+ };
@@ -168,7 +168,7 @@ module.exports = {};
168
168
  * @property {Record<string, ConfigData>} [configs] The definition of plugin configs.
169
169
  * @property {Record<string, Environment>} [environments] The definition of plugin environments.
170
170
  * @property {Record<string, Processor>} [processors] The definition of plugin processors.
171
- * @property {Record<string, Function | Rule>} [rules] The definition of plugin rules.
171
+ * @property {Record<string, Rule>} [rules] The definition of plugin rules.
172
172
  */
173
173
 
174
174
  /**
@@ -212,24 +212,6 @@ function isSpaceBetween(sourceCode, first, second, checkInsideOfJSXText) {
212
212
  // Directive Comments
213
213
  //-----------------------------------------------------------------------------
214
214
 
215
- /**
216
- * Extract the directive and the justification from a given directive comment and trim them.
217
- * @param {string} value The comment text to extract.
218
- * @returns {{directivePart: string, justificationPart: string}} The extracted directive and justification.
219
- */
220
- function extractDirectiveComment(value) {
221
- const match = /\s-{2,}\s/u.exec(value);
222
-
223
- if (!match) {
224
- return { directivePart: value.trim(), justificationPart: "" };
225
- }
226
-
227
- const directive = value.slice(0, match.index).trim();
228
- const justification = value.slice(match.index + match[0].length).trim();
229
-
230
- return { directivePart: directive, justificationPart: justification };
231
- }
232
-
233
215
  /**
234
216
  * Ensures that variables representing built-in properties of the Global Object,
235
217
  * and any globals declared by special block comments, are present in the global
@@ -438,9 +420,6 @@ class SourceCode extends TokenStore {
438
420
  }
439
421
  this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1]));
440
422
 
441
- // Cache for comments found using getComments().
442
- this._commentCache = new WeakMap();
443
-
444
423
  // don't allow further modification of this object
445
424
  Object.freeze(this);
446
425
  Object.freeze(this.lines);
@@ -490,81 +469,6 @@ class SourceCode extends TokenStore {
490
469
  return this.ast.comments;
491
470
  }
492
471
 
493
- /**
494
- * Gets all comments for the given node.
495
- * @param {ASTNode} node The AST node to get the comments for.
496
- * @returns {Object} An object containing a leading and trailing array
497
- * of comments indexed by their position.
498
- * @public
499
- * @deprecated replaced by getCommentsBefore(), getCommentsAfter(), and getCommentsInside().
500
- */
501
- getComments(node) {
502
- if (this._commentCache.has(node)) {
503
- return this._commentCache.get(node);
504
- }
505
-
506
- const comments = {
507
- leading: [],
508
- trailing: []
509
- };
510
-
511
- /*
512
- * Return all comments as leading comments of the Program node when
513
- * there is no executable code.
514
- */
515
- if (node.type === "Program") {
516
- if (node.body.length === 0) {
517
- comments.leading = node.comments;
518
- }
519
- } else {
520
-
521
- /*
522
- * Return comments as trailing comments of nodes that only contain
523
- * comments (to mimic the comment attachment behavior present in Espree).
524
- */
525
- if ((node.type === "BlockStatement" || node.type === "ClassBody") && node.body.length === 0 ||
526
- node.type === "ObjectExpression" && node.properties.length === 0 ||
527
- node.type === "ArrayExpression" && node.elements.length === 0 ||
528
- node.type === "SwitchStatement" && node.cases.length === 0
529
- ) {
530
- comments.trailing = this.getTokens(node, {
531
- includeComments: true,
532
- filter: isCommentToken
533
- });
534
- }
535
-
536
- /*
537
- * Iterate over tokens before and after node and collect comment tokens.
538
- * Do not include comments that exist outside of the parent node
539
- * to avoid duplication.
540
- */
541
- let currentToken = this.getTokenBefore(node, { includeComments: true });
542
-
543
- while (currentToken && isCommentToken(currentToken)) {
544
- if (node.parent && node.parent.type !== "Program" && (currentToken.start < node.parent.start)) {
545
- break;
546
- }
547
- comments.leading.push(currentToken);
548
- currentToken = this.getTokenBefore(currentToken, { includeComments: true });
549
- }
550
-
551
- comments.leading.reverse();
552
-
553
- currentToken = this.getTokenAfter(node, { includeComments: true });
554
-
555
- while (currentToken && isCommentToken(currentToken)) {
556
- if (node.parent && node.parent.type !== "Program" && (currentToken.end > node.parent.end)) {
557
- break;
558
- }
559
- comments.trailing.push(currentToken);
560
- currentToken = this.getTokenAfter(currentToken, { includeComments: true });
561
- }
562
- }
563
-
564
- this._commentCache.set(node, comments);
565
- return comments;
566
- }
567
-
568
472
  /**
569
473
  * Retrieves the JSDoc comment for a given node.
570
474
  * @param {ASTNode} node The AST node to get the comment for.
@@ -921,7 +825,7 @@ class SourceCode extends TokenStore {
921
825
  return false;
922
826
  }
923
827
 
924
- const { directivePart } = extractDirectiveComment(comment.value);
828
+ const { directivePart } = commentParser.extractDirectiveComment(comment.value);
925
829
 
926
830
  const directiveMatch = directivesPattern.exec(directivePart);
927
831
 
@@ -977,14 +881,11 @@ class SourceCode extends TokenStore {
977
881
 
978
882
  this.getInlineConfigNodes().forEach(comment => {
979
883
 
980
- const { directivePart } = extractDirectiveComment(comment.value);
981
- const match = directivesPattern.exec(directivePart);
982
- const directiveText = match[1];
983
- const directiveValue = directivePart.slice(match.index + directiveText.length);
884
+ const { directiveText, directiveValue } = commentParser.parseDirective(comment);
984
885
 
985
886
  switch (directiveText) {
986
887
  case "exported":
987
- Object.assign(exportedVariables, commentParser.parseStringConfig(directiveValue, comment));
888
+ Object.assign(exportedVariables, commentParser.parseListConfig(directiveValue, comment));
988
889
  break;
989
890
 
990
891
  case "globals":
@@ -12,9 +12,8 @@
12
12
  //-----------------------------------------------------------------------------
13
13
 
14
14
  const { FileEnumerator } = require("./cli-engine/file-enumerator");
15
- const { FlatESLint, shouldUseFlatConfig } = require("./eslint/flat-eslint");
16
- const FlatRuleTester = require("./rule-tester/flat-rule-tester");
17
- const { ESLint } = require("./eslint/eslint");
15
+ const { ESLint: FlatESLint, shouldUseFlatConfig } = require("./eslint/eslint");
16
+ const { LegacyESLint } = require("./eslint/legacy-eslint");
18
17
 
19
18
  //-----------------------------------------------------------------------------
20
19
  // Exports
@@ -24,7 +23,6 @@ module.exports = {
24
23
  builtinRules: require("./rules"),
25
24
  FlatESLint,
26
25
  shouldUseFlatConfig,
27
- FlatRuleTester,
28
26
  FileEnumerator,
29
- LegacyESLint: ESLint
27
+ LegacyESLint
30
28
  };