eslint 9.13.0 → 9.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/cli-engine/formatters/stylish.js +3 -3
- package/lib/cli-engine/lint-result-cache.js +1 -1
- package/lib/config/config-loader.js +193 -177
- package/lib/config/config.js +40 -24
- package/lib/eslint/eslint-helpers.js +18 -22
- package/lib/eslint/eslint.js +2 -2
- 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 +10 -7
- package/lib/rules/array-callback-return.js +10 -8
- package/lib/rules/arrow-body-style.js +3 -1
- package/lib/rules/camelcase.js +27 -14
- 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 +5 -5
- package/lib/rules/grouped-accessor-pairs.js +3 -1
- package/lib/rules/id-denylist.js +14 -1
- package/lib/rules/id-length.js +12 -8
- package/lib/rules/id-match.js +20 -17
- package/lib/rules/new-cap.js +15 -34
- package/lib/rules/no-bitwise.js +4 -5
- 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 +5 -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 +4 -4
- package/lib/rules/no-empty.js +6 -5
- package/lib/rules/no-eval.js +4 -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 +4 -4
- package/lib/rules/no-inline-comments.js +4 -6
- package/lib/rules/no-inner-declarations.js +4 -2
- 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 +5 -10
- package/lib/rules/no-plusplus.js +4 -9
- package/lib/rules/no-promise-executor-return.js +4 -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 +18 -14
- package/lib/rules/no-undef.js +4 -4
- package/lib/rules/no-underscore-dangle.js +31 -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 +4 -4
- package/lib/rules/no-unsafe-optional-chaining.js +4 -4
- package/lib/rules/no-unused-expressions.js +17 -13
- package/lib/rules/no-use-before-define.js +14 -13
- package/lib/rules/no-useless-computed-key.js +9 -3
- package/lib/rules/no-useless-rename.js +7 -8
- package/lib/rules/no-void.js +4 -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 +5 -3
- package/lib/rules/prefer-promise-reject-errors.js +5 -3
- package/lib/rules/prefer-regex-literals.js +4 -3
- package/lib/rules/radix.js +3 -1
- package/lib/rules/require-atomic-updates.js +4 -3
- package/lib/rules/sort-imports.js +20 -16
- package/lib/rules/sort-keys.js +13 -16
- package/lib/rules/sort-vars.js +4 -4
- package/lib/rules/strict.js +3 -2
- package/lib/rules/unicode-bom.js +4 -2
- package/lib/rules/use-isnan.js +7 -4
- package/lib/rules/utils/ast-utils.js +186 -2
- package/lib/rules/valid-typeof.js +3 -2
- 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 +3 -0
- package/package.json +19 -20
package/lib/rules/sort-vars.js
CHANGED
@@ -14,6 +14,8 @@ module.exports = {
|
|
14
14
|
meta: {
|
15
15
|
type: "suggestion",
|
16
16
|
|
17
|
+
defaultOptions: [{}],
|
18
|
+
|
17
19
|
docs: {
|
18
20
|
description: "Require variables within the same declaration block to be sorted",
|
19
21
|
recommended: false,
|
@@ -41,10 +43,8 @@ module.exports = {
|
|
41
43
|
},
|
42
44
|
|
43
45
|
create(context) {
|
44
|
-
|
45
|
-
const
|
46
|
-
ignoreCase = configuration.ignoreCase || false,
|
47
|
-
sourceCode = context.sourceCode;
|
46
|
+
const [{ ignoreCase }] = context.options;
|
47
|
+
const sourceCode = context.sourceCode;
|
48
48
|
|
49
49
|
return {
|
50
50
|
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.",
|
@@ -1054,7 +1054,7 @@ let needsPrecedingSemicolon;
|
|
1054
1054
|
{
|
1055
1055
|
const BREAK_OR_CONTINUE = new Set(["BreakStatement", "ContinueStatement"]);
|
1056
1056
|
|
1057
|
-
// Declaration types that
|
1057
|
+
// Declaration types that cannot be continued by a punctuator when ending with a string Literal that is a direct child.
|
1058
1058
|
const DECLARATIONS = new Set(["ExportAllDeclaration", "ExportNamedDeclaration", "ImportDeclaration"]);
|
1059
1059
|
|
1060
1060
|
const IDENTIFIER_OR_KEYWORD = new Set(["Identifier", "Keyword"]);
|
@@ -1132,6 +1132,48 @@ let needsPrecedingSemicolon;
|
|
1132
1132
|
};
|
1133
1133
|
}
|
1134
1134
|
|
1135
|
+
/**
|
1136
|
+
* Checks if a node is used as an import attribute key, either in a static or dynamic import.
|
1137
|
+
* @param {ASTNode} node The node to check.
|
1138
|
+
* @returns {boolean} Whether the node is used as an import attribute key.
|
1139
|
+
*/
|
1140
|
+
function isImportAttributeKey(node) {
|
1141
|
+
const { parent } = node;
|
1142
|
+
|
1143
|
+
// static import/re-export
|
1144
|
+
if (parent.type === "ImportAttribute" && parent.key === node) {
|
1145
|
+
return true;
|
1146
|
+
}
|
1147
|
+
|
1148
|
+
// dynamic import
|
1149
|
+
if (
|
1150
|
+
parent.type === "Property" &&
|
1151
|
+
!parent.computed &&
|
1152
|
+
(parent.key === node || parent.value === node && parent.shorthand && !parent.method) &&
|
1153
|
+
parent.parent.type === "ObjectExpression"
|
1154
|
+
) {
|
1155
|
+
const objectExpression = parent.parent;
|
1156
|
+
const objectExpressionParent = objectExpression.parent;
|
1157
|
+
|
1158
|
+
if (
|
1159
|
+
objectExpressionParent.type === "ImportExpression" &&
|
1160
|
+
objectExpressionParent.options === objectExpression
|
1161
|
+
) {
|
1162
|
+
return true;
|
1163
|
+
}
|
1164
|
+
|
1165
|
+
// nested key
|
1166
|
+
if (
|
1167
|
+
objectExpressionParent.type === "Property" &&
|
1168
|
+
objectExpressionParent.value === objectExpression
|
1169
|
+
) {
|
1170
|
+
return isImportAttributeKey(objectExpressionParent.key);
|
1171
|
+
}
|
1172
|
+
}
|
1173
|
+
|
1174
|
+
return false;
|
1175
|
+
}
|
1176
|
+
|
1135
1177
|
//------------------------------------------------------------------------------
|
1136
1178
|
// Public Interface
|
1137
1179
|
//------------------------------------------------------------------------------
|
@@ -2269,6 +2311,147 @@ module.exports = {
|
|
2269
2311
|
return node.type === "TemplateLiteral" && node.expressions.length === 0;
|
2270
2312
|
},
|
2271
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
|
+
|
2272
2455
|
isReferenceToGlobalVariable,
|
2273
2456
|
isLogicalExpression,
|
2274
2457
|
isCoalesceExpression,
|
@@ -2288,5 +2471,6 @@ module.exports = {
|
|
2288
2471
|
isTopLevelExpressionStatement,
|
2289
2472
|
isDirective,
|
2290
2473
|
isStartOfExpressionStatement,
|
2291
|
-
needsPrecedingSemicolon
|
2474
|
+
needsPrecedingSemicolon,
|
2475
|
+
isImportAttributeKey
|
2292
2476
|
};
|
@@ -19,6 +19,8 @@ module.exports = {
|
|
19
19
|
meta: {
|
20
20
|
type: "problem",
|
21
21
|
|
22
|
+
defaultOptions: [{}],
|
23
|
+
|
22
24
|
docs: {
|
23
25
|
description: "Enforce comparing `typeof` expressions against valid strings",
|
24
26
|
recommended: true,
|
@@ -47,11 +49,10 @@ module.exports = {
|
|
47
49
|
},
|
48
50
|
|
49
51
|
create(context) {
|
50
|
-
|
51
52
|
const VALID_TYPES = new Set(["symbol", "undefined", "object", "boolean", "number", "string", "function", "bigint"]),
|
52
53
|
OPERATORS = new Set(["==", "===", "!=", "!=="]);
|
53
54
|
const sourceCode = context.sourceCode;
|
54
|
-
const requireStringLiterals
|
55
|
+
const [{ requireStringLiterals }] = context.options;
|
55
56
|
|
56
57
|
let globalScope;
|
57
58
|
|
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. */
|
@@ -27,6 +27,37 @@
|
|
27
27
|
|
28
28
|
import { Linter } from "../index";
|
29
29
|
|
30
|
+
export interface NoRestrictedImportPathCommonOptions {
|
31
|
+
name: string;
|
32
|
+
message?: string;
|
33
|
+
}
|
34
|
+
|
35
|
+
export type EitherImportNamesOrAllowImportName =
|
36
|
+
| { importNames?: string[]; allowImportNames?: never }
|
37
|
+
| { allowImportNames?: string[]; importNames?: never }
|
38
|
+
|
39
|
+
export type ValidNoRestrictedImportPathOptions = NoRestrictedImportPathCommonOptions & EitherImportNamesOrAllowImportName;
|
40
|
+
|
41
|
+
export interface NoRestrictedImportPatternCommonOptions {
|
42
|
+
message?: string;
|
43
|
+
caseSensitive?: boolean;
|
44
|
+
}
|
45
|
+
|
46
|
+
// Base type for group or regex constraint, ensuring mutual exclusivity
|
47
|
+
export type EitherGroupOrRegEx =
|
48
|
+
| { group: string[]; regex?: never }
|
49
|
+
| { regex: string; group?: never };
|
50
|
+
|
51
|
+
// Base type for import name specifiers, ensuring mutual exclusivity
|
52
|
+
export type EitherNameSpecifiers =
|
53
|
+
| { importNames: string[]; allowImportNames?: never; importNamePattern?: never; allowImportNamePattern?: never }
|
54
|
+
| { importNamePattern: string; allowImportNames?: never; importNames?: never; allowImportNamePattern?: never }
|
55
|
+
| { allowImportNames: string[]; importNames?: never; importNamePattern?: never; allowImportNamePattern?: never }
|
56
|
+
| { allowImportNamePattern: string; importNames?: never; allowImportNames?: never; importNamePattern?: never }
|
57
|
+
|
58
|
+
// Adds oneOf and not constraints, ensuring group or regex are present and mutually exclusive sets for importNames, allowImportNames, etc., as per the schema.
|
59
|
+
export type ValidNoRestrictedImportPatternOptions = NoRestrictedImportPatternCommonOptions & EitherGroupOrRegEx & EitherNameSpecifiers;
|
60
|
+
|
30
61
|
export interface ECMAScript6 extends Linter.RulesRecord {
|
31
62
|
/**
|
32
63
|
* Rule to require braces around arrow function bodies.
|
@@ -291,23 +322,12 @@ export interface ECMAScript6 extends Linter.RulesRecord {
|
|
291
322
|
[
|
292
323
|
...Array<
|
293
324
|
| string
|
294
|
-
|
|
295
|
-
name: string;
|
296
|
-
importNames?: string[] | undefined;
|
297
|
-
message?: string | undefined;
|
298
|
-
}
|
325
|
+
| ValidNoRestrictedImportPathOptions
|
299
326
|
| Partial<{
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
importNames?: string[] | undefined;
|
305
|
-
message?: string | undefined;
|
306
|
-
}
|
307
|
-
>;
|
308
|
-
patterns: string[];
|
309
|
-
}>
|
310
|
-
>,
|
327
|
+
paths: Array<string | ValidNoRestrictedImportPathOptions>;
|
328
|
+
patterns: Array<string | ValidNoRestrictedImportPatternOptions>;
|
329
|
+
}>
|
330
|
+
>
|
311
331
|
]
|
312
332
|
>;
|
313
333
|
|
@@ -493,6 +493,7 @@ export interface StylisticIssues extends Linter.RulesRecord {
|
|
493
493
|
* Rule to enforce consistent indentation.
|
494
494
|
*
|
495
495
|
* @since 0.14.0
|
496
|
+
* @deprecated since 8.53.0, please use the [corresponding rule](https://eslint.style/rules/js/indent) in `@stylistic/eslint-plugin-js`.
|
496
497
|
* @see https://eslint.org/docs/rules/indent
|
497
498
|
*/
|
498
499
|
indent: Linter.RuleEntry<
|
@@ -1746,6 +1747,7 @@ export interface StylisticIssues extends Linter.RulesRecord {
|
|
1746
1747
|
* Rule to enforce the consistent use of either backticks, double, or single quotes.
|
1747
1748
|
*
|
1748
1749
|
* @since 0.0.7
|
1750
|
+
* @deprecated since 8.53.0, please use the [corresponding rule](https://eslint.style/rules/js/quotes) in `@stylistic/eslint-plugin-js`.
|
1749
1751
|
* @see https://eslint.org/docs/rules/quotes
|
1750
1752
|
*/
|
1751
1753
|
quotes: Linter.RuleEntry<
|
@@ -1768,6 +1770,7 @@ export interface StylisticIssues extends Linter.RulesRecord {
|
|
1768
1770
|
* Rule to require or disallow semicolons instead of ASI.
|
1769
1771
|
*
|
1770
1772
|
* @since 0.0.6
|
1773
|
+
* @deprecated since 8.53.0, please use the [corresponding rule](https://eslint.style/rules/js/semi) in `@stylistic/eslint-plugin-js`.
|
1771
1774
|
* @see https://eslint.org/docs/rules/semi
|
1772
1775
|
*/
|
1773
1776
|
semi:
|