eslint 8.20.0 → 8.23.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/bin/eslint.js +2 -4
- package/conf/globals.js +6 -1
- package/lib/cli.js +123 -29
- package/lib/config/default-config.js +16 -7
- package/lib/config/flat-config-array.js +94 -14
- package/lib/config/flat-config-helpers.js +9 -1
- package/lib/eslint/eslint-helpers.js +622 -0
- package/lib/eslint/flat-eslint.js +1176 -0
- package/lib/eslint/index.js +3 -1
- package/lib/linter/config-comment-parser.js +1 -2
- package/lib/linter/linter.js +18 -1
- package/lib/options.js +290 -242
- package/lib/rule-tester/flat-rule-tester.js +40 -37
- package/lib/rule-tester/rule-tester.js +43 -1
- package/lib/rules/key-spacing.js +4 -1
- package/lib/rules/lines-around-comment.js +11 -4
- package/lib/rules/no-fallthrough.js +8 -3
- package/lib/rules/no-lone-blocks.js +1 -1
- package/lib/rules/no-warning-comments.js +24 -5
- package/lib/rules/object-shorthand.js +15 -0
- package/lib/rules/sort-keys.js +43 -0
- package/lib/rules/utils/ast-utils.js +9 -3
- package/lib/shared/types.js +1 -1
- package/lib/unsupported-api.js +4 -0
- package/package.json +14 -9
@@ -4,7 +4,7 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
-
/*
|
7
|
+
/* globals describe, it -- Mocha globals */
|
8
8
|
|
9
9
|
//------------------------------------------------------------------------------
|
10
10
|
// Requirements
|
@@ -480,51 +480,54 @@ class FlatRuleTester {
|
|
480
480
|
].concat(scenarioErrors).join("\n"));
|
481
481
|
}
|
482
482
|
|
483
|
-
const baseConfig =
|
484
|
-
|
483
|
+
const baseConfig = [
|
484
|
+
{
|
485
|
+
plugins: {
|
485
486
|
|
486
|
-
|
487
|
-
|
487
|
+
// copy root plugin over
|
488
|
+
"@": {
|
488
489
|
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
490
|
+
/*
|
491
|
+
* Parsers are wrapped to detect more errors, so this needs
|
492
|
+
* to be a new object for each call to run(), otherwise the
|
493
|
+
* parsers will be wrapped multiple times.
|
494
|
+
*/
|
495
|
+
parsers: {
|
496
|
+
...defaultConfig[0].plugins["@"].parsers
|
497
|
+
},
|
497
498
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
499
|
+
/*
|
500
|
+
* The rules key on the default plugin is a proxy to lazy-load
|
501
|
+
* just the rules that are needed. So, don't create a new object
|
502
|
+
* here, just use the default one to keep that performance
|
503
|
+
* enhancement.
|
504
|
+
*/
|
505
|
+
rules: defaultConfig[0].plugins["@"].rules
|
506
|
+
},
|
507
|
+
"rule-to-test": {
|
508
|
+
rules: {
|
509
|
+
[ruleName]: Object.assign({}, rule, {
|
509
510
|
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
511
|
+
// Create a wrapper rule that freezes the `context` properties.
|
512
|
+
create(context) {
|
513
|
+
freezeDeeply(context.options);
|
514
|
+
freezeDeeply(context.settings);
|
515
|
+
freezeDeeply(context.parserOptions);
|
515
516
|
|
516
|
-
|
517
|
+
// freezeDeeply(context.languageOptions);
|
517
518
|
|
518
|
-
|
519
|
-
|
520
|
-
|
519
|
+
return (typeof rule === "function" ? rule : rule.create)(context);
|
520
|
+
}
|
521
|
+
})
|
522
|
+
}
|
521
523
|
}
|
524
|
+
},
|
525
|
+
languageOptions: {
|
526
|
+
...defaultConfig[0].languageOptions
|
522
527
|
}
|
523
528
|
},
|
524
|
-
|
525
|
-
|
526
|
-
}
|
527
|
-
};
|
529
|
+
...defaultConfig.slice(1)
|
530
|
+
];
|
528
531
|
|
529
532
|
/**
|
530
533
|
* Run the rule for the given item
|
@@ -4,7 +4,7 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
-
/*
|
7
|
+
/* globals describe, it -- Mocha globals */
|
8
8
|
|
9
9
|
/*
|
10
10
|
* This is a wrapper around mocha to allow for DRY unittests for eslint
|
@@ -305,6 +305,36 @@ function getCommentsDeprecation() {
|
|
305
305
|
);
|
306
306
|
}
|
307
307
|
|
308
|
+
/**
|
309
|
+
* Emit a deprecation warning if function-style format is being used.
|
310
|
+
* @param {string} ruleName Name of the rule.
|
311
|
+
* @returns {void}
|
312
|
+
*/
|
313
|
+
function emitLegacyRuleAPIWarning(ruleName) {
|
314
|
+
if (!emitLegacyRuleAPIWarning[`warned-${ruleName}`]) {
|
315
|
+
emitLegacyRuleAPIWarning[`warned-${ruleName}`] = true;
|
316
|
+
process.emitWarning(
|
317
|
+
`"${ruleName}" rule is using the deprecated function-style format and will stop working in ESLint v9. Please use object-style format: https://eslint.org/docs/developer-guide/working-with-rules`,
|
318
|
+
"DeprecationWarning"
|
319
|
+
);
|
320
|
+
}
|
321
|
+
}
|
322
|
+
|
323
|
+
/**
|
324
|
+
* Emit a deprecation warning if rule has options but is missing the "meta.schema" property
|
325
|
+
* @param {string} ruleName Name of the rule.
|
326
|
+
* @returns {void}
|
327
|
+
*/
|
328
|
+
function emitMissingSchemaWarning(ruleName) {
|
329
|
+
if (!emitMissingSchemaWarning[`warned-${ruleName}`]) {
|
330
|
+
emitMissingSchemaWarning[`warned-${ruleName}`] = true;
|
331
|
+
process.emitWarning(
|
332
|
+
`"${ruleName}" rule has options but is missing the "meta.schema" property and will stop working in ESLint v9. Please add a schema: https://eslint.org/docs/developer-guide/working-with-rules#options-schemas`,
|
333
|
+
"DeprecationWarning"
|
334
|
+
);
|
335
|
+
}
|
336
|
+
}
|
337
|
+
|
308
338
|
//------------------------------------------------------------------------------
|
309
339
|
// Public Interface
|
310
340
|
//------------------------------------------------------------------------------
|
@@ -521,6 +551,9 @@ class RuleTester {
|
|
521
551
|
].concat(scenarioErrors).join("\n"));
|
522
552
|
}
|
523
553
|
|
554
|
+
if (typeof rule === "function") {
|
555
|
+
emitLegacyRuleAPIWarning(ruleName);
|
556
|
+
}
|
524
557
|
|
525
558
|
linter.defineRule(ruleName, Object.assign({}, rule, {
|
526
559
|
|
@@ -578,6 +611,15 @@ class RuleTester {
|
|
578
611
|
|
579
612
|
if (hasOwnProperty(item, "options")) {
|
580
613
|
assert(Array.isArray(item.options), "options must be an array");
|
614
|
+
if (
|
615
|
+
item.options.length > 0 &&
|
616
|
+
typeof rule === "object" &&
|
617
|
+
(
|
618
|
+
!rule.meta || (rule.meta && (typeof rule.meta.schema === "undefined" || rule.meta.schema === null))
|
619
|
+
)
|
620
|
+
) {
|
621
|
+
emitMissingSchemaWarning(ruleName);
|
622
|
+
}
|
581
623
|
config.rules[ruleName] = [1].concat(item.options);
|
582
624
|
} else {
|
583
625
|
config.rules[ruleName] = 1;
|
package/lib/rules/key-spacing.js
CHANGED
@@ -9,6 +9,9 @@
|
|
9
9
|
//------------------------------------------------------------------------------
|
10
10
|
|
11
11
|
const astUtils = require("./utils/ast-utils");
|
12
|
+
const GraphemeSplitter = require("grapheme-splitter");
|
13
|
+
|
14
|
+
const splitter = new GraphemeSplitter();
|
12
15
|
|
13
16
|
//------------------------------------------------------------------------------
|
14
17
|
// Helpers
|
@@ -508,7 +511,7 @@ module.exports = {
|
|
508
511
|
const startToken = sourceCode.getFirstToken(property);
|
509
512
|
const endToken = getLastTokenBeforeColon(property.key);
|
510
513
|
|
511
|
-
return
|
514
|
+
return splitter.countGraphemes(sourceCode.getText().slice(startToken.range[0], endToken.range[1]));
|
512
515
|
}
|
513
516
|
|
514
517
|
/**
|
@@ -231,9 +231,15 @@ module.exports = {
|
|
231
231
|
const parent = getParentNodeOfToken(token);
|
232
232
|
|
233
233
|
if (parent && isParentNodeType(parent, nodeType)) {
|
234
|
-
|
235
|
-
|
236
|
-
|
234
|
+
let parentStartNodeOrToken = parent;
|
235
|
+
|
236
|
+
if (parent.type === "StaticBlock") {
|
237
|
+
parentStartNodeOrToken = sourceCode.getFirstToken(parent, { skip: 1 }); // opening brace of the static block
|
238
|
+
} else if (parent.type === "SwitchStatement") {
|
239
|
+
parentStartNodeOrToken = sourceCode.getTokenAfter(parent.discriminant, {
|
240
|
+
filter: astUtils.isOpeningBraceToken
|
241
|
+
}); // opening brace of the switch statement
|
242
|
+
}
|
237
243
|
|
238
244
|
return token.loc.start.line - parentStartNodeOrToken.loc.start.line === 1;
|
239
245
|
}
|
@@ -264,7 +270,8 @@ module.exports = {
|
|
264
270
|
isCommentAtParentStart(token, "ClassBody") ||
|
265
271
|
isCommentAtParentStart(token, "BlockStatement") ||
|
266
272
|
isCommentAtParentStart(token, "StaticBlock") ||
|
267
|
-
isCommentAtParentStart(token, "SwitchCase")
|
273
|
+
isCommentAtParentStart(token, "SwitchCase") ||
|
274
|
+
isCommentAtParentStart(token, "SwitchStatement")
|
268
275
|
);
|
269
276
|
}
|
270
277
|
|
@@ -76,6 +76,10 @@ module.exports = {
|
|
76
76
|
commentPattern: {
|
77
77
|
type: "string",
|
78
78
|
default: ""
|
79
|
+
},
|
80
|
+
allowEmptyCase: {
|
81
|
+
type: "boolean",
|
82
|
+
default: false
|
79
83
|
}
|
80
84
|
},
|
81
85
|
additionalProperties: false
|
@@ -91,6 +95,7 @@ module.exports = {
|
|
91
95
|
const options = context.options[0] || {};
|
92
96
|
let currentCodePath = null;
|
93
97
|
const sourceCode = context.getSourceCode();
|
98
|
+
const allowEmptyCase = options.allowEmptyCase || false;
|
94
99
|
|
95
100
|
/*
|
96
101
|
* We need to use leading comments of the next SwitchCase node because
|
@@ -104,7 +109,6 @@ module.exports = {
|
|
104
109
|
} else {
|
105
110
|
fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT;
|
106
111
|
}
|
107
|
-
|
108
112
|
return {
|
109
113
|
onCodePathStart(codePath) {
|
110
114
|
currentCodePath = codePath;
|
@@ -119,7 +123,8 @@ module.exports = {
|
|
119
123
|
* Checks whether or not there is a fallthrough comment.
|
120
124
|
* And reports the previous fallthrough node if that does not exist.
|
121
125
|
*/
|
122
|
-
|
126
|
+
|
127
|
+
if (fallthroughCase && (!hasFallthroughComment(fallthroughCase, node, context, fallthroughCommentPattern))) {
|
123
128
|
context.report({
|
124
129
|
messageId: node.test ? "case" : "default",
|
125
130
|
node
|
@@ -137,7 +142,7 @@ module.exports = {
|
|
137
142
|
* And allows empty cases and the last case.
|
138
143
|
*/
|
139
144
|
if (currentCodePath.currentSegments.some(isReachable) &&
|
140
|
-
(node.consequent.length > 0 || hasBlankLinesBetween(node, nextToken)) &&
|
145
|
+
(node.consequent.length > 0 || (!allowEmptyCase && hasBlankLinesBetween(node, nextToken))) &&
|
141
146
|
node.parent.cases[node.parent.cases.length - 1] !== node) {
|
142
147
|
fallthroughCase = node;
|
143
148
|
}
|
@@ -91,7 +91,7 @@ module.exports = {
|
|
91
91
|
};
|
92
92
|
|
93
93
|
// ES6: report blocks without block-level bindings, or that's only child of another block
|
94
|
-
if (context.
|
94
|
+
if (context.languageOptions.ecmaVersion >= 2015) {
|
95
95
|
ruleDef = {
|
96
96
|
BlockStatement(node) {
|
97
97
|
if (isLoneBlock(node)) {
|
@@ -37,6 +37,15 @@ module.exports = {
|
|
37
37
|
},
|
38
38
|
location: {
|
39
39
|
enum: ["start", "anywhere"]
|
40
|
+
},
|
41
|
+
decoration: {
|
42
|
+
type: "array",
|
43
|
+
items: {
|
44
|
+
type: "string",
|
45
|
+
pattern: "^\\S$"
|
46
|
+
},
|
47
|
+
minItems: 1,
|
48
|
+
uniqueItems: true
|
40
49
|
}
|
41
50
|
},
|
42
51
|
additionalProperties: false
|
@@ -53,6 +62,7 @@ module.exports = {
|
|
53
62
|
configuration = context.options[0] || {},
|
54
63
|
warningTerms = configuration.terms || ["todo", "fixme", "xxx"],
|
55
64
|
location = configuration.location || "start",
|
65
|
+
decoration = [...configuration.decoration || []].join(""),
|
56
66
|
selfConfigRegEx = /\bno-warning-comments\b/u;
|
57
67
|
|
58
68
|
/**
|
@@ -64,6 +74,7 @@ module.exports = {
|
|
64
74
|
*/
|
65
75
|
function convertToRegExp(term) {
|
66
76
|
const escaped = escapeRegExp(term);
|
77
|
+
const escapedDecoration = escapeRegExp(decoration);
|
67
78
|
|
68
79
|
/*
|
69
80
|
* When matching at the start, ignore leading whitespace, and
|
@@ -74,18 +85,23 @@ module.exports = {
|
|
74
85
|
* e.g. terms ["TODO"] matches `//TODO something`
|
75
86
|
* $ handles any terms at the end of a comment
|
76
87
|
* e.g. terms ["TODO"] matches `// something TODO`
|
77
|
-
* \s* handles optional leading spaces (for "start" location only)
|
78
|
-
* e.g. terms ["TODO"] matches `// TODO something`
|
79
88
|
* \b handles terms preceded/followed by word boundary
|
80
89
|
* e.g. terms: ["!FIX", "FIX!"] matches `// FIX!something` or `// something!FIX`
|
81
90
|
* terms: ["FIX"] matches `// FIX!` or `// !FIX`, but not `// fixed or affix`
|
91
|
+
*
|
92
|
+
* For location start:
|
93
|
+
* [\s]* handles optional leading spaces
|
94
|
+
* e.g. terms ["TODO"] matches `// TODO something`
|
95
|
+
* [\s\*]* (where "\*" is the escaped string of decoration)
|
96
|
+
* handles optional leading spaces or decoration characters (for "start" location only)
|
97
|
+
* e.g. terms ["TODO"] matches `/**** TODO something ... `
|
82
98
|
*/
|
83
99
|
const wordBoundary = "\\b";
|
84
100
|
|
85
101
|
let prefix = "";
|
86
102
|
|
87
103
|
if (location === "start") {
|
88
|
-
prefix =
|
104
|
+
prefix = `^[\\s${escapedDecoration}]*`;
|
89
105
|
} else if (/^\w/u.test(term)) {
|
90
106
|
prefix = wordBoundary;
|
91
107
|
}
|
@@ -95,12 +111,15 @@ module.exports = {
|
|
95
111
|
|
96
112
|
/*
|
97
113
|
* For location "start", the typical regex is:
|
98
|
-
*
|
114
|
+
* /^[\s]*ESCAPED_TERM\b/iu.
|
115
|
+
* Or if decoration characters are specified (e.g. "*"), then any of
|
116
|
+
* those characters may appear in any order at the start:
|
117
|
+
* /^[\s\*]*ESCAPED_TERM\b/iu.
|
99
118
|
*
|
100
119
|
* For location "anywhere" the typical regex is
|
101
120
|
* /\bESCAPED_TERM\b/iu
|
102
121
|
*
|
103
|
-
* If it starts or ends with non-word character, the prefix and suffix empty, respectively.
|
122
|
+
* If it starts or ends with non-word character, the prefix and suffix are empty, respectively.
|
104
123
|
*/
|
105
124
|
return new RegExp(`${prefix}${escaped}${suffix}`, flags);
|
106
125
|
}
|
@@ -78,6 +78,9 @@ module.exports = {
|
|
78
78
|
ignoreConstructors: {
|
79
79
|
type: "boolean"
|
80
80
|
},
|
81
|
+
methodsIgnorePattern: {
|
82
|
+
type: "string"
|
83
|
+
},
|
81
84
|
avoidQuotes: {
|
82
85
|
type: "boolean"
|
83
86
|
},
|
@@ -115,6 +118,9 @@ module.exports = {
|
|
115
118
|
|
116
119
|
const PARAMS = context.options[1] || {};
|
117
120
|
const IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors;
|
121
|
+
const METHODS_IGNORE_PATTERN = PARAMS.methodsIgnorePattern
|
122
|
+
? new RegExp(PARAMS.methodsIgnorePattern, "u")
|
123
|
+
: null;
|
118
124
|
const AVOID_QUOTES = PARAMS.avoidQuotes;
|
119
125
|
const AVOID_EXPLICIT_RETURN_ARROWS = !!PARAMS.avoidExplicitReturnArrows;
|
120
126
|
const sourceCode = context.getSourceCode();
|
@@ -457,6 +463,15 @@ module.exports = {
|
|
457
463
|
if (IGNORE_CONSTRUCTORS && node.key.type === "Identifier" && isConstructor(node.key.name)) {
|
458
464
|
return;
|
459
465
|
}
|
466
|
+
|
467
|
+
if (METHODS_IGNORE_PATTERN) {
|
468
|
+
const propertyName = astUtils.getStaticPropertyName(node);
|
469
|
+
|
470
|
+
if (propertyName !== null && METHODS_IGNORE_PATTERN.test(propertyName)) {
|
471
|
+
return;
|
472
|
+
}
|
473
|
+
}
|
474
|
+
|
460
475
|
if (AVOID_QUOTES && isStringLiteral(node.key)) {
|
461
476
|
return;
|
462
477
|
}
|
package/lib/rules/sort-keys.js
CHANGED
@@ -105,6 +105,10 @@ module.exports = {
|
|
105
105
|
type: "integer",
|
106
106
|
minimum: 2,
|
107
107
|
default: 2
|
108
|
+
},
|
109
|
+
allowLineSeparatedGroups: {
|
110
|
+
type: "boolean",
|
111
|
+
default: false
|
108
112
|
}
|
109
113
|
},
|
110
114
|
additionalProperties: false
|
@@ -124,17 +128,21 @@ module.exports = {
|
|
124
128
|
const insensitive = options && options.caseSensitive === false;
|
125
129
|
const natural = options && options.natural;
|
126
130
|
const minKeys = options && options.minKeys;
|
131
|
+
const allowLineSeparatedGroups = options && options.allowLineSeparatedGroups || false;
|
127
132
|
const isValidOrder = isValidOrders[
|
128
133
|
order + (insensitive ? "I" : "") + (natural ? "N" : "")
|
129
134
|
];
|
130
135
|
|
131
136
|
// The stack to save the previous property's name for each object literals.
|
132
137
|
let stack = null;
|
138
|
+
const sourceCode = context.getSourceCode();
|
133
139
|
|
134
140
|
return {
|
135
141
|
ObjectExpression(node) {
|
136
142
|
stack = {
|
137
143
|
upper: stack,
|
144
|
+
prevNode: null,
|
145
|
+
prevBlankLine: false,
|
138
146
|
prevName: null,
|
139
147
|
numKeys: node.properties.length
|
140
148
|
};
|
@@ -159,10 +167,45 @@ module.exports = {
|
|
159
167
|
const numKeys = stack.numKeys;
|
160
168
|
const thisName = getPropertyName(node);
|
161
169
|
|
170
|
+
// Get tokens between current node and previous node
|
171
|
+
const tokens = stack.prevNode && sourceCode
|
172
|
+
.getTokensBetween(stack.prevNode, node, { includeComments: true });
|
173
|
+
|
174
|
+
let isBlankLineBetweenNodes = stack.prevBlankLine;
|
175
|
+
|
176
|
+
if (tokens) {
|
177
|
+
|
178
|
+
// check blank line between tokens
|
179
|
+
tokens.forEach((token, index) => {
|
180
|
+
const previousToken = tokens[index - 1];
|
181
|
+
|
182
|
+
if (previousToken && (token.loc.start.line - previousToken.loc.end.line > 1)) {
|
183
|
+
isBlankLineBetweenNodes = true;
|
184
|
+
}
|
185
|
+
});
|
186
|
+
|
187
|
+
// check blank line between the current node and the last token
|
188
|
+
if (!isBlankLineBetweenNodes && (node.loc.start.line - tokens[tokens.length - 1].loc.end.line > 1)) {
|
189
|
+
isBlankLineBetweenNodes = true;
|
190
|
+
}
|
191
|
+
|
192
|
+
// check blank line between the first token and the previous node
|
193
|
+
if (!isBlankLineBetweenNodes && (tokens[0].loc.start.line - stack.prevNode.loc.end.line > 1)) {
|
194
|
+
isBlankLineBetweenNodes = true;
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
stack.prevNode = node;
|
199
|
+
|
162
200
|
if (thisName !== null) {
|
163
201
|
stack.prevName = thisName;
|
164
202
|
}
|
165
203
|
|
204
|
+
if (allowLineSeparatedGroups && isBlankLineBetweenNodes) {
|
205
|
+
stack.prevBlankLine = thisName === null;
|
206
|
+
return;
|
207
|
+
}
|
208
|
+
|
166
209
|
if (prevName === null || thisName === null || numKeys < minKeys) {
|
167
210
|
return;
|
168
211
|
}
|
@@ -1978,7 +1978,7 @@ module.exports = {
|
|
1978
1978
|
if (comments.length) {
|
1979
1979
|
const lastComment = comments[comments.length - 1];
|
1980
1980
|
|
1981
|
-
if (lastComment.range[0] > leftToken.range[0]) {
|
1981
|
+
if (!leftToken || lastComment.range[0] > leftToken.range[0]) {
|
1982
1982
|
leftToken = lastComment;
|
1983
1983
|
}
|
1984
1984
|
}
|
@@ -1986,7 +1986,13 @@ module.exports = {
|
|
1986
1986
|
leftToken = leftValue;
|
1987
1987
|
}
|
1988
1988
|
|
1989
|
-
|
1989
|
+
/*
|
1990
|
+
* If a hashbang comment was passed as a token object from SourceCode,
|
1991
|
+
* its type will be "Shebang" because of the way ESLint itself handles hashbangs.
|
1992
|
+
* If a hashbang comment was passed in a string and then tokenized in this function,
|
1993
|
+
* its type will be "Hashbang" because of the way Espree tokenizes hashbangs.
|
1994
|
+
*/
|
1995
|
+
if (leftToken.type === "Shebang" || leftToken.type === "Hashbang") {
|
1990
1996
|
return false;
|
1991
1997
|
}
|
1992
1998
|
|
@@ -2007,7 +2013,7 @@ module.exports = {
|
|
2007
2013
|
if (comments.length) {
|
2008
2014
|
const firstComment = comments[0];
|
2009
2015
|
|
2010
|
-
if (firstComment.range[0] < rightToken.range[0]) {
|
2016
|
+
if (!rightToken || firstComment.range[0] < rightToken.range[0]) {
|
2011
2017
|
rightToken = firstComment;
|
2012
2018
|
}
|
2013
2019
|
}
|
package/lib/shared/types.js
CHANGED
@@ -21,7 +21,7 @@ module.exports = {};
|
|
21
21
|
/**
|
22
22
|
* @typedef {Object} ParserOptions
|
23
23
|
* @property {EcmaFeatures} [ecmaFeatures] The optional features.
|
24
|
-
* @property {3|5|6|7|8|9|10|11|12|13|2015|2016|2017|2018|2019|2020|2021|2022} [ecmaVersion] The ECMAScript version (or revision number).
|
24
|
+
* @property {3|5|6|7|8|9|10|11|12|13|14|2015|2016|2017|2018|2019|2020|2021|2022|2023} [ecmaVersion] The ECMAScript version (or revision number).
|
25
25
|
* @property {"script"|"module"} [sourceType] The source code type.
|
26
26
|
* @property {boolean} [allowReserved] Allowing the use of reserved words as identifiers in ES3.
|
27
27
|
*/
|
package/lib/unsupported-api.js
CHANGED
@@ -12,6 +12,8 @@
|
|
12
12
|
//-----------------------------------------------------------------------------
|
13
13
|
|
14
14
|
const { FileEnumerator } = require("./cli-engine/file-enumerator");
|
15
|
+
const { FlatESLint } = require("./eslint/flat-eslint");
|
16
|
+
const FlatRuleTester = require("./rule-tester/flat-rule-tester");
|
15
17
|
|
16
18
|
//-----------------------------------------------------------------------------
|
17
19
|
// Exports
|
@@ -19,5 +21,7 @@ const { FileEnumerator } = require("./cli-engine/file-enumerator");
|
|
19
21
|
|
20
22
|
module.exports = {
|
21
23
|
builtinRules: require("./rules"),
|
24
|
+
FlatESLint,
|
25
|
+
FlatRuleTester,
|
22
26
|
FileEnumerator
|
23
27
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.23.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -39,7 +39,8 @@
|
|
39
39
|
"docs/src/rules/*.md": [
|
40
40
|
"node tools/fetch-docs-links.js",
|
41
41
|
"git add docs/src/_data/further_reading_links.json"
|
42
|
-
]
|
42
|
+
],
|
43
|
+
"docs/**/*.svg": "npx svgo -r --multipass"
|
43
44
|
},
|
44
45
|
"files": [
|
45
46
|
"LICENSE",
|
@@ -54,8 +55,10 @@
|
|
54
55
|
"homepage": "https://eslint.org",
|
55
56
|
"bugs": "https://github.com/eslint/eslint/issues/",
|
56
57
|
"dependencies": {
|
57
|
-
"@eslint/eslintrc": "^1.3.
|
58
|
-
"@humanwhocodes/config-array": "^0.
|
58
|
+
"@eslint/eslintrc": "^1.3.1",
|
59
|
+
"@humanwhocodes/config-array": "^0.10.4",
|
60
|
+
"@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
|
61
|
+
"@humanwhocodes/module-importer": "^1.0.1",
|
59
62
|
"ajv": "^6.10.0",
|
60
63
|
"chalk": "^4.0.0",
|
61
64
|
"cross-spawn": "^7.0.2",
|
@@ -65,14 +68,17 @@
|
|
65
68
|
"eslint-scope": "^7.1.1",
|
66
69
|
"eslint-utils": "^3.0.0",
|
67
70
|
"eslint-visitor-keys": "^3.3.0",
|
68
|
-
"espree": "^9.
|
71
|
+
"espree": "^9.4.0",
|
69
72
|
"esquery": "^1.4.0",
|
70
73
|
"esutils": "^2.0.2",
|
71
74
|
"fast-deep-equal": "^3.1.3",
|
72
75
|
"file-entry-cache": "^6.0.1",
|
76
|
+
"find-up": "^5.0.0",
|
73
77
|
"functional-red-black-tree": "^1.0.1",
|
74
78
|
"glob-parent": "^6.0.1",
|
75
79
|
"globals": "^13.15.0",
|
80
|
+
"globby": "^11.1.0",
|
81
|
+
"grapheme-splitter": "^1.0.4",
|
76
82
|
"ignore": "^5.2.0",
|
77
83
|
"import-fresh": "^3.0.0",
|
78
84
|
"imurmurhash": "^0.1.4",
|
@@ -87,8 +93,7 @@
|
|
87
93
|
"regexpp": "^3.2.0",
|
88
94
|
"strip-ansi": "^6.0.1",
|
89
95
|
"strip-json-comments": "^3.1.0",
|
90
|
-
"text-table": "^0.2.0"
|
91
|
-
"v8-compile-cache": "^2.0.3"
|
96
|
+
"text-table": "^0.2.0"
|
92
97
|
},
|
93
98
|
"devDependencies": {
|
94
99
|
"@babel/core": "^7.4.3",
|
@@ -105,7 +110,7 @@
|
|
105
110
|
"eslint-plugin-eslint-plugin": "^4.4.0",
|
106
111
|
"eslint-plugin-internal-rules": "file:tools/internal-rules",
|
107
112
|
"eslint-plugin-jsdoc": "^38.1.6",
|
108
|
-
"eslint-plugin-
|
113
|
+
"eslint-plugin-n": "^15.2.4",
|
109
114
|
"eslint-plugin-unicorn": "^42.0.0",
|
110
115
|
"eslint-release": "^3.2.0",
|
111
116
|
"eslump": "^3.0.0",
|
@@ -141,7 +146,7 @@
|
|
141
146
|
"pirates": "^4.0.5",
|
142
147
|
"progress": "^2.0.3",
|
143
148
|
"proxyquire": "^2.0.1",
|
144
|
-
"puppeteer": "^
|
149
|
+
"puppeteer": "^13.7.0",
|
145
150
|
"recast": "^0.20.4",
|
146
151
|
"regenerator-runtime": "^0.13.2",
|
147
152
|
"semver": "^7.3.5",
|