eslint 9.14.0 → 9.16.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 (99) hide show
  1. package/README.md +1 -1
  2. package/lib/cli-engine/formatters/stylish.js +3 -3
  3. package/lib/cli-engine/lint-result-cache.js +1 -1
  4. package/lib/config/config.js +40 -24
  5. package/lib/eslint/eslint-helpers.js +9 -13
  6. package/lib/languages/js/index.js +76 -0
  7. package/lib/languages/js/source-code/token-store/index.js +1 -1
  8. package/lib/linter/code-path-analysis/code-path-analyzer.js +1 -1
  9. package/lib/linter/code-path-analysis/fork-context.js +1 -1
  10. package/lib/linter/linter.js +36 -35
  11. package/lib/linter/report-translator.js +1 -1
  12. package/lib/rule-tester/rule-tester.js +1 -1
  13. package/lib/rules/accessor-pairs.js +14 -10
  14. package/lib/rules/array-callback-return.js +10 -8
  15. package/lib/rules/arrow-body-style.js +3 -1
  16. package/lib/rules/camelcase.js +18 -12
  17. package/lib/rules/class-methods-use-this.js +9 -5
  18. package/lib/rules/complexity.js +9 -5
  19. package/lib/rules/consistent-return.js +4 -4
  20. package/lib/rules/consistent-this.js +3 -7
  21. package/lib/rules/curly.js +3 -140
  22. package/lib/rules/default-case.js +3 -1
  23. package/lib/rules/dot-notation.js +9 -6
  24. package/lib/rules/func-names.js +3 -3
  25. package/lib/rules/func-style.js +10 -8
  26. package/lib/rules/getter-return.js +7 -5
  27. package/lib/rules/grouped-accessor-pairs.js +3 -1
  28. package/lib/rules/id-denylist.js +2 -1
  29. package/lib/rules/id-length.js +11 -6
  30. package/lib/rules/id-match.js +18 -16
  31. package/lib/rules/new-cap.js +16 -35
  32. package/lib/rules/no-bitwise.js +7 -5
  33. package/lib/rules/no-compare-neg-zero.js +1 -1
  34. package/lib/rules/no-cond-assign.js +3 -3
  35. package/lib/rules/no-console.js +3 -2
  36. package/lib/rules/no-constant-condition.js +5 -4
  37. package/lib/rules/no-duplicate-imports.js +7 -4
  38. package/lib/rules/no-else-return.js +4 -5
  39. package/lib/rules/no-empty-function.js +4 -4
  40. package/lib/rules/no-empty-pattern.js +6 -4
  41. package/lib/rules/no-empty.js +6 -5
  42. package/lib/rules/no-eval.js +6 -5
  43. package/lib/rules/no-extend-native.js +3 -3
  44. package/lib/rules/no-extra-boolean-cast.js +3 -3
  45. package/lib/rules/no-fallthrough.js +12 -15
  46. package/lib/rules/no-global-assign.js +3 -2
  47. package/lib/rules/no-implicit-coercion.js +13 -24
  48. package/lib/rules/no-implicit-globals.js +6 -4
  49. package/lib/rules/no-inline-comments.js +4 -6
  50. package/lib/rules/no-inner-declarations.js +5 -3
  51. package/lib/rules/no-invalid-regexp.js +5 -4
  52. package/lib/rules/no-invalid-this.js +4 -4
  53. package/lib/rules/no-irregular-whitespace.js +24 -22
  54. package/lib/rules/no-labels.js +8 -7
  55. package/lib/rules/no-lonely-if.js +8 -2
  56. package/lib/rules/no-multi-assign.js +7 -10
  57. package/lib/rules/no-plusplus.js +6 -9
  58. package/lib/rules/no-promise-executor-return.js +6 -6
  59. package/lib/rules/no-redeclare.js +5 -8
  60. package/lib/rules/no-return-assign.js +3 -1
  61. package/lib/rules/no-self-assign.js +4 -3
  62. package/lib/rules/no-sequences.js +7 -7
  63. package/lib/rules/no-shadow.js +21 -15
  64. package/lib/rules/no-undef.js +6 -4
  65. package/lib/rules/no-underscore-dangle.js +32 -28
  66. package/lib/rules/no-unneeded-ternary.js +4 -4
  67. package/lib/rules/no-unreachable-loop.js +4 -2
  68. package/lib/rules/no-unsafe-negation.js +6 -4
  69. package/lib/rules/no-unsafe-optional-chaining.js +6 -4
  70. package/lib/rules/no-unused-expressions.js +17 -13
  71. package/lib/rules/no-use-before-define.js +15 -13
  72. package/lib/rules/no-useless-computed-key.js +10 -4
  73. package/lib/rules/no-useless-rename.js +11 -8
  74. package/lib/rules/no-void.js +6 -4
  75. package/lib/rules/no-warning-comments.js +9 -7
  76. package/lib/rules/operator-assignment.js +4 -2
  77. package/lib/rules/prefer-arrow-callback.js +5 -8
  78. package/lib/rules/prefer-const.js +9 -5
  79. package/lib/rules/prefer-promise-reject-errors.js +7 -3
  80. package/lib/rules/prefer-regex-literals.js +6 -3
  81. package/lib/rules/radix.js +3 -1
  82. package/lib/rules/require-atomic-updates.js +6 -3
  83. package/lib/rules/sort-imports.js +20 -16
  84. package/lib/rules/sort-keys.js +22 -16
  85. package/lib/rules/sort-vars.js +7 -6
  86. package/lib/rules/strict.js +3 -2
  87. package/lib/rules/unicode-bom.js +4 -2
  88. package/lib/rules/use-isnan.js +8 -6
  89. package/lib/rules/utils/ast-utils.js +141 -0
  90. package/lib/rules/valid-typeof.js +6 -4
  91. package/lib/rules/yoda.js +9 -12
  92. package/lib/shared/assert.js +22 -0
  93. package/lib/shared/deep-merge-arrays.js +60 -0
  94. package/lib/shared/text-table.js +67 -0
  95. package/lib/shared/types.js +1 -0
  96. package/lib/types/index.d.ts +3 -0
  97. package/lib/types/rules/ecmascript-6.d.ts +36 -16
  98. package/lib/types/rules/stylistic-issues.d.ts +7 -0
  99. package/package.json +11 -12
@@ -170,6 +170,10 @@ module.exports = {
170
170
  meta: {
171
171
  type: "problem",
172
172
 
173
+ defaultOptions: [{
174
+ allowProperties: false
175
+ }],
176
+
173
177
  docs: {
174
178
  description: "Disallow assignments that can lead to race conditions due to usage of `await` or `yield`",
175
179
  recommended: false,
@@ -182,8 +186,7 @@ module.exports = {
182
186
  type: "object",
183
187
  properties: {
184
188
  allowProperties: {
185
- type: "boolean",
186
- default: false
189
+ type: "boolean"
187
190
  }
188
191
  },
189
192
  additionalProperties: false
@@ -196,7 +199,7 @@ module.exports = {
196
199
  },
197
200
 
198
201
  create(context) {
199
- const allowProperties = !!context.options[0] && context.options[0].allowProperties;
202
+ const [{ allowProperties }] = context.options;
200
203
 
201
204
  const sourceCode = context.sourceCode;
202
205
  const assignmentReferences = new Map();
@@ -14,6 +14,14 @@ module.exports = {
14
14
  meta: {
15
15
  type: "suggestion",
16
16
 
17
+ defaultOptions: [{
18
+ allowSeparatedGroups: false,
19
+ ignoreCase: false,
20
+ ignoreDeclarationSort: false,
21
+ ignoreMemberSort: false,
22
+ memberSyntaxSortOrder: ["none", "all", "multiple", "single"]
23
+ }],
24
+
17
25
  docs: {
18
26
  description: "Enforce sorted import declarations within modules",
19
27
  recommended: false,
@@ -25,8 +33,7 @@ module.exports = {
25
33
  type: "object",
26
34
  properties: {
27
35
  ignoreCase: {
28
- type: "boolean",
29
- default: false
36
+ type: "boolean"
30
37
  },
31
38
  memberSyntaxSortOrder: {
32
39
  type: "array",
@@ -38,16 +45,13 @@ module.exports = {
38
45
  maxItems: 4
39
46
  },
40
47
  ignoreDeclarationSort: {
41
- type: "boolean",
42
- default: false
48
+ type: "boolean"
43
49
  },
44
50
  ignoreMemberSort: {
45
- type: "boolean",
46
- default: false
51
+ type: "boolean"
47
52
  },
48
53
  allowSeparatedGroups: {
49
- type: "boolean",
50
- default: false
54
+ type: "boolean"
51
55
  }
52
56
  },
53
57
  additionalProperties: false
@@ -64,14 +68,14 @@ module.exports = {
64
68
  },
65
69
 
66
70
  create(context) {
67
-
68
- const configuration = context.options[0] || {},
69
- ignoreCase = configuration.ignoreCase || false,
70
- ignoreDeclarationSort = configuration.ignoreDeclarationSort || false,
71
- ignoreMemberSort = configuration.ignoreMemberSort || false,
72
- memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"],
73
- allowSeparatedGroups = configuration.allowSeparatedGroups || false,
74
- sourceCode = context.sourceCode;
71
+ const [{
72
+ ignoreCase,
73
+ ignoreDeclarationSort,
74
+ ignoreMemberSort,
75
+ memberSyntaxSortOrder,
76
+ allowSeparatedGroups
77
+ }] = context.options;
78
+ const sourceCode = context.sourceCode;
75
79
  let previousDeclaration = null;
76
80
 
77
81
  /**
@@ -80,6 +80,14 @@ module.exports = {
80
80
  meta: {
81
81
  type: "suggestion",
82
82
 
83
+ defaultOptions: ["asc", {
84
+ allowLineSeparatedGroups: false,
85
+ caseSensitive: true,
86
+ ignoreComputedKeys: false,
87
+ minKeys: 2,
88
+ natural: false
89
+ }],
90
+
83
91
  docs: {
84
92
  description: "Require object keys to be sorted",
85
93
  recommended: false,
@@ -94,21 +102,20 @@ module.exports = {
94
102
  type: "object",
95
103
  properties: {
96
104
  caseSensitive: {
97
- type: "boolean",
98
- default: true
105
+ type: "boolean"
99
106
  },
100
107
  natural: {
101
- type: "boolean",
102
- default: false
108
+ type: "boolean"
103
109
  },
104
110
  minKeys: {
105
111
  type: "integer",
106
- minimum: 2,
107
- default: 2
112
+ minimum: 2
108
113
  },
109
114
  allowLineSeparatedGroups: {
110
- type: "boolean",
111
- default: false
115
+ type: "boolean"
116
+ },
117
+ ignoreComputedKeys: {
118
+ type: "boolean"
112
119
  }
113
120
  },
114
121
  additionalProperties: false
@@ -121,14 +128,8 @@ module.exports = {
121
128
  },
122
129
 
123
130
  create(context) {
124
-
125
- // Parse options.
126
- const order = context.options[0] || "asc";
127
- const options = context.options[1];
128
- const insensitive = options && options.caseSensitive === false;
129
- const natural = options && options.natural;
130
- const minKeys = options && options.minKeys;
131
- const allowLineSeparatedGroups = options && options.allowLineSeparatedGroups || false;
131
+ const [order, { caseSensitive, natural, minKeys, allowLineSeparatedGroups, ignoreComputedKeys }] = context.options;
132
+ const insensitive = !caseSensitive;
132
133
  const isValidOrder = isValidOrders[
133
134
  order + (insensitive ? "I" : "") + (natural ? "N" : "")
134
135
  ];
@@ -163,6 +164,11 @@ module.exports = {
163
164
  return;
164
165
  }
165
166
 
167
+ if (ignoreComputedKeys && node.computed) {
168
+ stack.prevName = null; // reset sort
169
+ return;
170
+ }
171
+
166
172
  const prevName = stack.prevName;
167
173
  const numKeys = stack.numKeys;
168
174
  const thisName = getPropertyName(node);
@@ -14,6 +14,10 @@ module.exports = {
14
14
  meta: {
15
15
  type: "suggestion",
16
16
 
17
+ defaultOptions: [{
18
+ ignoreCase: false
19
+ }],
20
+
17
21
  docs: {
18
22
  description: "Require variables within the same declaration block to be sorted",
19
23
  recommended: false,
@@ -25,8 +29,7 @@ module.exports = {
25
29
  type: "object",
26
30
  properties: {
27
31
  ignoreCase: {
28
- type: "boolean",
29
- default: false
32
+ type: "boolean"
30
33
  }
31
34
  },
32
35
  additionalProperties: false
@@ -41,10 +44,8 @@ module.exports = {
41
44
  },
42
45
 
43
46
  create(context) {
44
-
45
- const configuration = context.options[0] || {},
46
- ignoreCase = configuration.ignoreCase || false,
47
- sourceCode = context.sourceCode;
47
+ const [{ ignoreCase }] = context.options;
48
+ const sourceCode = context.sourceCode;
48
49
 
49
50
  return {
50
51
  VariableDeclaration(node) {
@@ -68,6 +68,8 @@ module.exports = {
68
68
  meta: {
69
69
  type: "suggestion",
70
70
 
71
+ defaultOptions: ["safe"],
72
+
71
73
  docs: {
72
74
  description: "Require or disallow strict mode directives",
73
75
  recommended: false,
@@ -96,11 +98,10 @@ module.exports = {
96
98
  },
97
99
 
98
100
  create(context) {
99
-
100
101
  const ecmaFeatures = context.parserOptions.ecmaFeatures || {},
101
102
  scopes = [],
102
103
  classScopes = [];
103
- let mode = context.options[0] || "safe";
104
+ let [mode] = context.options;
104
105
 
105
106
  if (ecmaFeatures.impliedStrict) {
106
107
  mode = "implied";
@@ -13,6 +13,8 @@ module.exports = {
13
13
  meta: {
14
14
  type: "layout",
15
15
 
16
+ defaultOptions: ["never"],
17
+
16
18
  docs: {
17
19
  description: "Require or disallow Unicode byte order mark (BOM)",
18
20
  recommended: false,
@@ -43,8 +45,8 @@ module.exports = {
43
45
  Program: function checkUnicodeBOM(node) {
44
46
 
45
47
  const sourceCode = context.sourceCode,
46
- location = { column: 0, line: 1 },
47
- requireBOM = context.options[0] || "never";
48
+ location = { column: 0, line: 1 };
49
+ const [requireBOM] = context.options;
48
50
 
49
51
  if (!sourceCode.hasBOM && (requireBOM === "always")) {
50
52
  context.report({
@@ -56,18 +56,21 @@ module.exports = {
56
56
  type: "object",
57
57
  properties: {
58
58
  enforceForSwitchCase: {
59
- type: "boolean",
60
- default: true
59
+ type: "boolean"
61
60
  },
62
61
  enforceForIndexOf: {
63
- type: "boolean",
64
- default: false
62
+ type: "boolean"
65
63
  }
66
64
  },
67
65
  additionalProperties: false
68
66
  }
69
67
  ],
70
68
 
69
+ defaultOptions: [{
70
+ enforceForIndexOf: false,
71
+ enforceForSwitchCase: true
72
+ }],
73
+
71
74
  messages: {
72
75
  comparisonWithNaN: "Use the isNaN function to compare with NaN.",
73
76
  switchNaN: "'switch(NaN)' can never match a case clause. Use Number.isNaN instead of the switch.",
@@ -81,8 +84,7 @@ module.exports = {
81
84
 
82
85
  create(context) {
83
86
 
84
- const enforceForSwitchCase = !context.options[0] || context.options[0].enforceForSwitchCase;
85
- const enforceForIndexOf = context.options[0] && context.options[0].enforceForIndexOf;
87
+ const [{ enforceForIndexOf, enforceForSwitchCase }] = context.options;
86
88
  const sourceCode = context.sourceCode;
87
89
 
88
90
  const fixableOperators = new Set(["==", "===", "!=", "!=="]);
@@ -2311,6 +2311,147 @@ module.exports = {
2311
2311
  return node.type === "TemplateLiteral" && node.expressions.length === 0;
2312
2312
  },
2313
2313
 
2314
+ /**
2315
+ * Determines whether the existing curly braces around the single statement are necessary to preserve the semantics of the code.
2316
+ * The braces, which make the given block body, are necessary in either of the following situations:
2317
+ *
2318
+ * 1. The statement is a lexical declaration.
2319
+ * 2. Without the braces, an `if` within the statement would become associated with an `else` after the closing brace:
2320
+ *
2321
+ * if (a) {
2322
+ * if (b)
2323
+ * foo();
2324
+ * }
2325
+ * else
2326
+ * bar();
2327
+ *
2328
+ * if (a)
2329
+ * while (b)
2330
+ * while (c) {
2331
+ * while (d)
2332
+ * if (e)
2333
+ * while(f)
2334
+ * foo();
2335
+ * }
2336
+ * else
2337
+ * bar();
2338
+ * @param {ASTNode} node `BlockStatement` body with exactly one statement directly inside. The statement can have its own nested statements.
2339
+ * @param {SourceCode} sourceCode The source code
2340
+ * @returns {boolean} `true` if the braces are necessary - removing them (replacing the given `BlockStatement` body with its single statement content)
2341
+ * would change the semantics of the code or produce a syntax error.
2342
+ */
2343
+ areBracesNecessary(node, sourceCode) {
2344
+
2345
+ /**
2346
+ * Determines if the given node is a lexical declaration (let, const, function, or class)
2347
+ * @param {ASTNode} nodeToCheck The node to check
2348
+ * @returns {boolean} True if the node is a lexical declaration
2349
+ * @private
2350
+ */
2351
+ function isLexicalDeclaration(nodeToCheck) {
2352
+ if (nodeToCheck.type === "VariableDeclaration") {
2353
+ return nodeToCheck.kind === "const" || nodeToCheck.kind === "let";
2354
+ }
2355
+
2356
+ return nodeToCheck.type === "FunctionDeclaration" || nodeToCheck.type === "ClassDeclaration";
2357
+ }
2358
+
2359
+
2360
+ /**
2361
+ * Checks if the given token is an `else` token or not.
2362
+ * @param {Token} token The token to check.
2363
+ * @returns {boolean} `true` if the token is an `else` token.
2364
+ */
2365
+ function isElseKeywordToken(token) {
2366
+ return token.value === "else" && token.type === "Keyword";
2367
+ }
2368
+
2369
+ /**
2370
+ * Determines whether the given node has an `else` keyword token as the first token after.
2371
+ * @param {ASTNode} nodeToCheck The node to check.
2372
+ * @returns {boolean} `true` if the node is followed by an `else` keyword token.
2373
+ */
2374
+ function isFollowedByElseKeyword(nodeToCheck) {
2375
+ const nextToken = sourceCode.getTokenAfter(nodeToCheck);
2376
+
2377
+ return Boolean(nextToken) && isElseKeywordToken(nextToken);
2378
+ }
2379
+
2380
+ /**
2381
+ * Determines whether the code represented by the given node contains an `if` statement
2382
+ * that would become associated with an `else` keyword directly appended to that code.
2383
+ *
2384
+ * Examples where it returns `true`:
2385
+ *
2386
+ * if (a)
2387
+ * foo();
2388
+ *
2389
+ * if (a) {
2390
+ * foo();
2391
+ * }
2392
+ *
2393
+ * if (a)
2394
+ * foo();
2395
+ * else if (b)
2396
+ * bar();
2397
+ *
2398
+ * while (a)
2399
+ * if (b)
2400
+ * if(c)
2401
+ * foo();
2402
+ * else
2403
+ * bar();
2404
+ *
2405
+ * Examples where it returns `false`:
2406
+ *
2407
+ * if (a)
2408
+ * foo();
2409
+ * else
2410
+ * bar();
2411
+ *
2412
+ * while (a) {
2413
+ * if (b)
2414
+ * if(c)
2415
+ * foo();
2416
+ * else
2417
+ * bar();
2418
+ * }
2419
+ *
2420
+ * while (a)
2421
+ * if (b) {
2422
+ * if(c)
2423
+ * foo();
2424
+ * }
2425
+ * else
2426
+ * bar();
2427
+ * @param {ASTNode} nodeToCheck Node representing the code to check.
2428
+ * @returns {boolean} `true` if an `if` statement within the code would become associated with an `else` appended to that code.
2429
+ */
2430
+ function hasUnsafeIf(nodeToCheck) {
2431
+ switch (nodeToCheck.type) {
2432
+ case "IfStatement":
2433
+ if (!nodeToCheck.alternate) {
2434
+ return true;
2435
+ }
2436
+ return hasUnsafeIf(nodeToCheck.alternate);
2437
+ case "ForStatement":
2438
+ case "ForInStatement":
2439
+ case "ForOfStatement":
2440
+ case "LabeledStatement":
2441
+ case "WithStatement":
2442
+ case "WhileStatement":
2443
+ return hasUnsafeIf(nodeToCheck.body);
2444
+ default:
2445
+ return false;
2446
+ }
2447
+ }
2448
+
2449
+ const statement = node.body[0];
2450
+
2451
+ return isLexicalDeclaration(statement) ||
2452
+ hasUnsafeIf(statement) && isFollowedByElseKeyword(node);
2453
+ },
2454
+
2314
2455
  isReferenceToGlobalVariable,
2315
2456
  isLogicalExpression,
2316
2457
  isCoalesceExpression,
@@ -19,6 +19,10 @@ module.exports = {
19
19
  meta: {
20
20
  type: "problem",
21
21
 
22
+ defaultOptions: [{
23
+ requireStringLiterals: false
24
+ }],
25
+
22
26
  docs: {
23
27
  description: "Enforce comparing `typeof` expressions against valid strings",
24
28
  recommended: true,
@@ -32,8 +36,7 @@ module.exports = {
32
36
  type: "object",
33
37
  properties: {
34
38
  requireStringLiterals: {
35
- type: "boolean",
36
- default: false
39
+ type: "boolean"
37
40
  }
38
41
  },
39
42
  additionalProperties: false
@@ -47,11 +50,10 @@ module.exports = {
47
50
  },
48
51
 
49
52
  create(context) {
50
-
51
53
  const VALID_TYPES = new Set(["symbol", "undefined", "object", "boolean", "number", "string", "function", "bigint"]),
52
54
  OPERATORS = new Set(["==", "===", "!=", "!=="]);
53
55
  const sourceCode = context.sourceCode;
54
- const requireStringLiterals = context.options[0] && context.options[0].requireStringLiterals;
56
+ const [{ requireStringLiterals }] = context.options;
55
57
 
56
58
  let globalScope;
57
59
 
package/lib/rules/yoda.js CHANGED
@@ -111,6 +111,11 @@ module.exports = {
111
111
  meta: {
112
112
  type: "suggestion",
113
113
 
114
+ defaultOptions: ["never", {
115
+ exceptRange: false,
116
+ onlyEquality: false
117
+ }],
118
+
114
119
  docs: {
115
120
  description: 'Require or disallow "Yoda" conditions',
116
121
  recommended: false,
@@ -125,12 +130,10 @@ module.exports = {
125
130
  type: "object",
126
131
  properties: {
127
132
  exceptRange: {
128
- type: "boolean",
129
- default: false
133
+ type: "boolean"
130
134
  },
131
135
  onlyEquality: {
132
- type: "boolean",
133
- default: false
136
+ type: "boolean"
134
137
  }
135
138
  },
136
139
  additionalProperties: false
@@ -145,14 +148,8 @@ module.exports = {
145
148
  },
146
149
 
147
150
  create(context) {
148
-
149
- // Default to "never" (!always) if no option
150
- const always = context.options[0] === "always";
151
- const exceptRange =
152
- context.options[1] && context.options[1].exceptRange;
153
- const onlyEquality =
154
- context.options[1] && context.options[1].onlyEquality;
155
-
151
+ const [when, { exceptRange, onlyEquality }] = context.options;
152
+ const always = when === "always";
156
153
  const sourceCode = context.sourceCode;
157
154
 
158
155
  /**
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fileoverview Assertion utilities equivalent to the Node.js node:asserts module.
3
+ * @author Josh Goldberg
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /**
9
+ * Throws an error if the input is not truthy.
10
+ * @param {unknown} value The input that is checked for being truthy.
11
+ * @param {string} message Message to throw if the input is not truthy.
12
+ * @returns {void}
13
+ * @throws {Error} When the condition is not truthy.
14
+ */
15
+ function ok(value, message = "Assertion failed.") {
16
+ if (!value) {
17
+ throw new Error(message);
18
+ }
19
+ }
20
+
21
+
22
+ module.exports = ok;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @fileoverview Applies default rule options
3
+ * @author JoshuaKGoldberg
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /**
9
+ * Check if the variable contains an object strictly rejecting arrays
10
+ * @param {unknown} value an object
11
+ * @returns {boolean} Whether value is an object
12
+ */
13
+ function isObjectNotArray(value) {
14
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15
+ }
16
+
17
+ /**
18
+ * Deeply merges second on top of first, creating a new {} object if needed.
19
+ * @param {T} first Base, default value.
20
+ * @param {U} second User-specified value.
21
+ * @returns {T | U | (T & U)} Merged equivalent of second on top of first.
22
+ */
23
+ function deepMergeObjects(first, second) {
24
+ if (second === void 0) {
25
+ return first;
26
+ }
27
+
28
+ if (!isObjectNotArray(first) || !isObjectNotArray(second)) {
29
+ return second;
30
+ }
31
+
32
+ const result = { ...first, ...second };
33
+
34
+ for (const key of Object.keys(second)) {
35
+ if (Object.prototype.propertyIsEnumerable.call(first, key)) {
36
+ result[key] = deepMergeObjects(first[key], second[key]);
37
+ }
38
+ }
39
+
40
+ return result;
41
+ }
42
+
43
+ /**
44
+ * Deeply merges second on top of first, creating a new [] array if needed.
45
+ * @param {T[]} first Base, default values.
46
+ * @param {U[]} second User-specified values.
47
+ * @returns {(T | U | (T & U))[]} Merged equivalent of second on top of first.
48
+ */
49
+ function deepMergeArrays(first, second) {
50
+ if (!first || !second) {
51
+ return second || first || [];
52
+ }
53
+
54
+ return [
55
+ ...first.map((value, i) => deepMergeObjects(value, i < second.length ? second[i] : void 0)),
56
+ ...second.slice(first.length)
57
+ ];
58
+ }
59
+
60
+ module.exports = { deepMergeArrays };
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @fileoverview Optimized version of the `text-table` npm module to improve performance by replacing inefficient regex-based
3
+ * whitespace trimming with a modern built-in method.
4
+ *
5
+ * This modification addresses a performance issue reported in https://github.com/eslint/eslint/issues/18709
6
+ *
7
+ * The `text-table` module is published under the MIT License. For the original source, refer to:
8
+ * https://www.npmjs.com/package/text-table.
9
+ */
10
+
11
+ /*
12
+ *
13
+ * This software is released under the MIT license:
14
+ *
15
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
16
+ * this software and associated documentation files (the "Software"), to deal in
17
+ * the Software without restriction, including without limitation the rights to
18
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
19
+ * the Software, and to permit persons to whom the Software is furnished to do so,
20
+ * subject to the following conditions:
21
+ *
22
+ * The above copyright notice and this permission notice shall be included in all
23
+ * copies or substantial portions of the Software.
24
+ *
25
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
27
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
28
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
29
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ */
32
+
33
+ "use strict";
34
+
35
+ module.exports = function(rows_, opts) {
36
+ const hsep = " ";
37
+ const align = opts.align;
38
+ const stringLength = opts.stringLength;
39
+
40
+ const sizes = rows_.reduce((acc, row) => {
41
+ row.forEach((c, ix) => {
42
+ const n = stringLength(c);
43
+
44
+ if (!acc[ix] || n > acc[ix]) {
45
+ acc[ix] = n;
46
+ }
47
+ });
48
+ return acc;
49
+ }, []);
50
+
51
+ return rows_
52
+ .map(row =>
53
+ row
54
+ .map((c, ix) => {
55
+ const n = sizes[ix] - stringLength(c) || 0;
56
+ const s = Array(Math.max(n + 1, 1)).join(" ");
57
+
58
+ if (align[ix] === "r") {
59
+ return s + c;
60
+ }
61
+
62
+ return c + s;
63
+ })
64
+ .join(hsep)
65
+ .trimEnd())
66
+ .join("\n");
67
+ };
@@ -148,6 +148,7 @@ module.exports = {};
148
148
  /**
149
149
  * @typedef {Object} RuleMeta
150
150
  * @property {boolean} [deprecated] If `true` then the rule has been deprecated.
151
+ * @property {Array} [defaultOptions] Default options for the rule.
151
152
  * @property {RuleMetaDocs} docs The document information of the rule.
152
153
  * @property {"code"|"whitespace"} [fixable] The autofix type.
153
154
  * @property {boolean} [hasSuggestions] If `true` then the rule provides suggestions.
@@ -741,6 +741,9 @@ export namespace Rule {
741
741
  */
742
742
  schema?: JSONSchema4 | JSONSchema4[] | false | undefined;
743
743
 
744
+ /** Any default options to be recursively merged on top of any user-provided options. */
745
+ defaultOptions?: unknown[];
746
+
744
747
  /** Indicates whether the rule has been deprecated. Omit if not deprecated. */
745
748
  deprecated?: boolean | undefined;
746
749
  /** The name of the rule(s) this rule was replaced by, if it was deprecated. */