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.
- package/README.md +1 -1
- package/lib/cli-engine/formatters/stylish.js +3 -3
- package/lib/cli-engine/lint-result-cache.js +1 -1
- package/lib/config/config.js +40 -24
- package/lib/eslint/eslint-helpers.js +9 -13
- package/lib/languages/js/index.js +76 -0
- package/lib/languages/js/source-code/token-store/index.js +1 -1
- package/lib/linter/code-path-analysis/code-path-analyzer.js +1 -1
- package/lib/linter/code-path-analysis/fork-context.js +1 -1
- package/lib/linter/linter.js +36 -35
- package/lib/linter/report-translator.js +1 -1
- package/lib/rule-tester/rule-tester.js +1 -1
- package/lib/rules/accessor-pairs.js +14 -10
- package/lib/rules/array-callback-return.js +10 -8
- package/lib/rules/arrow-body-style.js +3 -1
- package/lib/rules/camelcase.js +18 -12
- package/lib/rules/class-methods-use-this.js +9 -5
- package/lib/rules/complexity.js +9 -5
- package/lib/rules/consistent-return.js +4 -4
- package/lib/rules/consistent-this.js +3 -7
- package/lib/rules/curly.js +3 -140
- package/lib/rules/default-case.js +3 -1
- package/lib/rules/dot-notation.js +9 -6
- package/lib/rules/func-names.js +3 -3
- package/lib/rules/func-style.js +10 -8
- package/lib/rules/getter-return.js +7 -5
- package/lib/rules/grouped-accessor-pairs.js +3 -1
- package/lib/rules/id-denylist.js +2 -1
- package/lib/rules/id-length.js +11 -6
- package/lib/rules/id-match.js +18 -16
- package/lib/rules/new-cap.js +16 -35
- package/lib/rules/no-bitwise.js +7 -5
- package/lib/rules/no-compare-neg-zero.js +1 -1
- package/lib/rules/no-cond-assign.js +3 -3
- package/lib/rules/no-console.js +3 -2
- package/lib/rules/no-constant-condition.js +5 -4
- package/lib/rules/no-duplicate-imports.js +7 -4
- package/lib/rules/no-else-return.js +4 -5
- package/lib/rules/no-empty-function.js +4 -4
- package/lib/rules/no-empty-pattern.js +6 -4
- package/lib/rules/no-empty.js +6 -5
- package/lib/rules/no-eval.js +6 -5
- package/lib/rules/no-extend-native.js +3 -3
- package/lib/rules/no-extra-boolean-cast.js +3 -3
- package/lib/rules/no-fallthrough.js +12 -15
- package/lib/rules/no-global-assign.js +3 -2
- package/lib/rules/no-implicit-coercion.js +13 -24
- package/lib/rules/no-implicit-globals.js +6 -4
- package/lib/rules/no-inline-comments.js +4 -6
- package/lib/rules/no-inner-declarations.js +5 -3
- package/lib/rules/no-invalid-regexp.js +5 -4
- package/lib/rules/no-invalid-this.js +4 -4
- package/lib/rules/no-irregular-whitespace.js +24 -22
- package/lib/rules/no-labels.js +8 -7
- package/lib/rules/no-lonely-if.js +8 -2
- package/lib/rules/no-multi-assign.js +7 -10
- package/lib/rules/no-plusplus.js +6 -9
- package/lib/rules/no-promise-executor-return.js +6 -6
- package/lib/rules/no-redeclare.js +5 -8
- package/lib/rules/no-return-assign.js +3 -1
- package/lib/rules/no-self-assign.js +4 -3
- package/lib/rules/no-sequences.js +7 -7
- package/lib/rules/no-shadow.js +21 -15
- package/lib/rules/no-undef.js +6 -4
- package/lib/rules/no-underscore-dangle.js +32 -28
- package/lib/rules/no-unneeded-ternary.js +4 -4
- package/lib/rules/no-unreachable-loop.js +4 -2
- package/lib/rules/no-unsafe-negation.js +6 -4
- package/lib/rules/no-unsafe-optional-chaining.js +6 -4
- package/lib/rules/no-unused-expressions.js +17 -13
- package/lib/rules/no-use-before-define.js +15 -13
- package/lib/rules/no-useless-computed-key.js +10 -4
- package/lib/rules/no-useless-rename.js +11 -8
- package/lib/rules/no-void.js +6 -4
- package/lib/rules/no-warning-comments.js +9 -7
- package/lib/rules/operator-assignment.js +4 -2
- package/lib/rules/prefer-arrow-callback.js +5 -8
- package/lib/rules/prefer-const.js +9 -5
- package/lib/rules/prefer-promise-reject-errors.js +7 -3
- package/lib/rules/prefer-regex-literals.js +6 -3
- package/lib/rules/radix.js +3 -1
- package/lib/rules/require-atomic-updates.js +6 -3
- package/lib/rules/sort-imports.js +20 -16
- package/lib/rules/sort-keys.js +22 -16
- package/lib/rules/sort-vars.js +7 -6
- package/lib/rules/strict.js +3 -2
- package/lib/rules/unicode-bom.js +4 -2
- package/lib/rules/use-isnan.js +8 -6
- package/lib/rules/utils/ast-utils.js +141 -0
- package/lib/rules/valid-typeof.js +6 -4
- package/lib/rules/yoda.js +9 -12
- package/lib/shared/assert.js +22 -0
- package/lib/shared/deep-merge-arrays.js +60 -0
- package/lib/shared/text-table.js +67 -0
- package/lib/shared/types.js +1 -0
- package/lib/types/index.d.ts +3 -0
- package/lib/types/rules/ecmascript-6.d.ts +36 -16
- package/lib/types/rules/stylistic-issues.d.ts +7 -0
- 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
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
/**
|
package/lib/rules/sort-keys.js
CHANGED
@@ -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
|
-
|
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
|
-
|
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);
|
package/lib/rules/sort-vars.js
CHANGED
@@ -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
|
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) {
|
package/lib/rules/strict.js
CHANGED
@@ -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
|
104
|
+
let [mode] = context.options;
|
104
105
|
|
105
106
|
if (ecmaFeatures.impliedStrict) {
|
106
107
|
mode = "implied";
|
package/lib/rules/unicode-bom.js
CHANGED
@@ -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
|
-
|
48
|
+
location = { column: 0, line: 1 };
|
49
|
+
const [requireBOM] = context.options;
|
48
50
|
|
49
51
|
if (!sourceCode.hasBOM && (requireBOM === "always")) {
|
50
52
|
context.report({
|
package/lib/rules/use-isnan.js
CHANGED
@@ -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
|
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
|
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
|
-
|
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
|
+
};
|
package/lib/shared/types.js
CHANGED
@@ -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.
|
package/lib/types/index.d.ts
CHANGED
@@ -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. */
|