eslint 9.34.0 → 9.36.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 +6 -1
- package/lib/eslint/eslint.js +8 -4
- package/lib/linter/esquery.js +3 -0
- package/lib/rule-tester/rule-tester.js +3 -0
- package/lib/rules/array-callback-return.js +0 -1
- package/lib/rules/index.js +1 -0
- package/lib/rules/no-empty-function.js +19 -0
- package/lib/rules/no-empty-static-block.js +25 -1
- package/lib/rules/no-empty.js +37 -0
- package/lib/rules/no-eval.js +3 -1
- package/lib/rules/no-loss-of-precision.js +1 -1
- package/lib/rules/no-misleading-character-class.js +7 -2
- package/lib/rules/preserve-caught-error.js +539 -0
- package/lib/rules/require-unicode-regexp.js +3 -1
- package/lib/rules/strict.js +2 -1
- package/lib/services/suppressions-service.js +3 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/rules.d.ts +226 -79
- package/package.json +3 -3
package/README.md
CHANGED
@@ -277,6 +277,11 @@ Nitin Kumar
|
|
277
277
|
The people who review and fix bugs and help triage issues.
|
278
278
|
|
279
279
|
<table><tbody><tr><td align="center" valign="top" width="11%">
|
280
|
+
<a href="https://github.com/DMartens">
|
281
|
+
<img src="https://github.com/DMartens.png?s=75" width="75" height="75" alt="fnx's Avatar"><br />
|
282
|
+
fnx
|
283
|
+
</a>
|
284
|
+
</td><td align="center" valign="top" width="11%">
|
280
285
|
<a href="https://github.com/JoshuaKGoldberg">
|
281
286
|
<img src="https://github.com/JoshuaKGoldberg.png?s=75" width="75" height="75" alt="Josh Goldberg ✨'s Avatar"><br />
|
282
287
|
Josh Goldberg ✨
|
@@ -328,7 +333,7 @@ to get your logo on our READMEs and [website](https://eslint.org/sponsors).
|
|
328
333
|
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="128"></a></p><h3>Gold Sponsors</h3>
|
329
334
|
<p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a> <a href="https://trunk.io/"><img src="https://images.opencollective.com/trunkio/fb92d60/avatar.png" alt="trunk.io" height="96"></a> <a href="https://shopify.engineering/"><img src="https://avatars.githubusercontent.com/u/8085" alt="Shopify" height="96"></a></p><h3>Silver Sponsors</h3>
|
330
335
|
<p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/e6d15e1/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301" alt="American Express" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3>
|
331
|
-
<p><a href="https://
|
336
|
+
<p><a href="https://syntax.fm"><img src="https://github.com/syntaxfm.png" alt="Syntax" height="32"></a> <a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://sentry.io"><img src="https://github.com/getsentry.png" alt="Sentry" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104" alt="Nx" height="32"></a> <a href="https://opensource.mercedes-benz.com/"><img src="https://avatars.githubusercontent.com/u/34240465" alt="Mercedes-Benz Group" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="LambdaTest" height="32"></a></p>
|
332
337
|
<h3>Technology Sponsors</h3>
|
333
338
|
Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.
|
334
339
|
<p><a href="https://netlify.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/netlify-icon.svg" alt="Netlify" height="32"></a> <a href="https://algolia.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/algolia-icon.svg" alt="Algolia" height="32"></a> <a href="https://1password.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/1password-icon.svg" alt="1Password" height="32"></a></p>
|
package/lib/eslint/eslint.js
CHANGED
@@ -263,11 +263,15 @@ async function locateConfigFileToUse({ configFile, cwd }) {
|
|
263
263
|
|
264
264
|
/**
|
265
265
|
* Creates an error to be thrown when an array of results passed to `getRulesMetaForResults` was not created by the current engine.
|
266
|
+
* @param {Error|undefined} cause The original error that led to this symptom error being thrown. Might not always be available.
|
266
267
|
* @returns {TypeError} An error object.
|
267
268
|
*/
|
268
|
-
function createExtraneousResultsError() {
|
269
|
+
function createExtraneousResultsError(cause) {
|
269
270
|
return new TypeError(
|
270
271
|
"Results object was not created from this ESLint instance.",
|
272
|
+
{
|
273
|
+
cause,
|
274
|
+
},
|
271
275
|
);
|
272
276
|
}
|
273
277
|
|
@@ -543,7 +547,7 @@ function validateOptionCloneability(options) {
|
|
543
547
|
})
|
544
548
|
.sort();
|
545
549
|
const error = new TypeError(
|
546
|
-
`The ${uncloneableOptionKeys.length === 1 ? "option" : "options"} ${new Intl.ListFormat("en-US").format(uncloneableOptionKeys.map(key => `"${key}"`))} cannot be cloned. When concurrency is enabled, all options must be cloneable. Remove uncloneable options or use an options module.`,
|
550
|
+
`The ${uncloneableOptionKeys.length === 1 ? "option" : "options"} ${new Intl.ListFormat("en-US").format(uncloneableOptionKeys.map(key => `"${key}"`))} cannot be cloned. When concurrency is enabled, all options must be cloneable values (JSON values). Remove uncloneable options or use an options module.`,
|
547
551
|
);
|
548
552
|
error.code = "ESLINT_UNCLONEABLE_OPTIONS";
|
549
553
|
throw error;
|
@@ -773,8 +777,8 @@ class ESLint {
|
|
773
777
|
try {
|
774
778
|
configs =
|
775
779
|
configLoader.getCachedConfigArrayForFile(filePath);
|
776
|
-
} catch {
|
777
|
-
throw createExtraneousResultsError();
|
780
|
+
} catch (err) {
|
781
|
+
throw createExtraneousResultsError(err);
|
778
782
|
}
|
779
783
|
|
780
784
|
const config = configs.getConfig(filePath);
|
package/lib/linter/esquery.js
CHANGED
package/lib/rules/index.js
CHANGED
@@ -293,6 +293,7 @@ module.exports = new LazyLoadingRuleMap(
|
|
293
293
|
"prefer-rest-params": () => require("./prefer-rest-params"),
|
294
294
|
"prefer-spread": () => require("./prefer-spread"),
|
295
295
|
"prefer-template": () => require("./prefer-template"),
|
296
|
+
"preserve-caught-error": () => require("./preserve-caught-error"),
|
296
297
|
"quote-props": () => require("./quote-props"),
|
297
298
|
quotes: () => require("./quotes"),
|
298
299
|
radix: () => require("./radix"),
|
@@ -105,6 +105,7 @@ module.exports = {
|
|
105
105
|
meta: {
|
106
106
|
dialects: ["javascript", "typescript"],
|
107
107
|
language: "javascript",
|
108
|
+
hasSuggestions: true,
|
108
109
|
type: "suggestion",
|
109
110
|
|
110
111
|
defaultOptions: [{ allow: [] }],
|
@@ -131,6 +132,7 @@ module.exports = {
|
|
131
132
|
|
132
133
|
messages: {
|
133
134
|
unexpected: "Unexpected empty {{name}}.",
|
135
|
+
suggestComment: "Add comment inside empty {{name}}.",
|
134
136
|
},
|
135
137
|
},
|
136
138
|
|
@@ -204,6 +206,23 @@ module.exports = {
|
|
204
206
|
loc: node.body.loc,
|
205
207
|
messageId: "unexpected",
|
206
208
|
data: { name },
|
209
|
+
suggest: [
|
210
|
+
{
|
211
|
+
messageId: "suggestComment",
|
212
|
+
data: { name },
|
213
|
+
fix(fixer) {
|
214
|
+
const range = [
|
215
|
+
node.body.range[0] + 1,
|
216
|
+
node.body.range[1] - 1,
|
217
|
+
];
|
218
|
+
|
219
|
+
return fixer.replaceTextRange(
|
220
|
+
range,
|
221
|
+
" /* empty */ ",
|
222
|
+
);
|
223
|
+
},
|
224
|
+
},
|
225
|
+
],
|
207
226
|
});
|
208
227
|
}
|
209
228
|
}
|
@@ -11,6 +11,7 @@
|
|
11
11
|
/** @type {import('../types').Rule.RuleModule} */
|
12
12
|
module.exports = {
|
13
13
|
meta: {
|
14
|
+
hasSuggestions: true,
|
14
15
|
type: "suggestion",
|
15
16
|
|
16
17
|
docs: {
|
@@ -23,6 +24,7 @@ module.exports = {
|
|
23
24
|
|
24
25
|
messages: {
|
25
26
|
unexpected: "Unexpected empty static block.",
|
27
|
+
suggestComment: "Add comment inside empty static block.",
|
26
28
|
},
|
27
29
|
},
|
28
30
|
|
@@ -32,14 +34,36 @@ module.exports = {
|
|
32
34
|
return {
|
33
35
|
StaticBlock(node) {
|
34
36
|
if (node.body.length === 0) {
|
37
|
+
const openingBrace = sourceCode.getFirstToken(node, {
|
38
|
+
skip: 1,
|
39
|
+
});
|
35
40
|
const closingBrace = sourceCode.getLastToken(node);
|
36
41
|
|
37
42
|
if (
|
38
43
|
sourceCode.getCommentsBefore(closingBrace).length === 0
|
39
44
|
) {
|
40
45
|
context.report({
|
41
|
-
|
46
|
+
loc: {
|
47
|
+
start: openingBrace.loc.start,
|
48
|
+
end: closingBrace.loc.end,
|
49
|
+
},
|
42
50
|
messageId: "unexpected",
|
51
|
+
suggest: [
|
52
|
+
{
|
53
|
+
messageId: "suggestComment",
|
54
|
+
fix(fixer) {
|
55
|
+
const range = [
|
56
|
+
openingBrace.range[1],
|
57
|
+
closingBrace.range[0],
|
58
|
+
];
|
59
|
+
|
60
|
+
return fixer.replaceTextRange(
|
61
|
+
range,
|
62
|
+
" /* empty */ ",
|
63
|
+
);
|
64
|
+
},
|
65
|
+
},
|
66
|
+
],
|
43
67
|
});
|
44
68
|
}
|
45
69
|
}
|
package/lib/rules/no-empty.js
CHANGED
@@ -104,10 +104,47 @@ module.exports = {
|
|
104
104
|
typeof node.cases === "undefined" ||
|
105
105
|
node.cases.length === 0
|
106
106
|
) {
|
107
|
+
const openingBrace = sourceCode.getTokenAfter(
|
108
|
+
node.discriminant,
|
109
|
+
astUtils.isOpeningBraceToken,
|
110
|
+
);
|
111
|
+
|
112
|
+
const closingBrace = sourceCode.getLastToken(node);
|
113
|
+
|
114
|
+
if (
|
115
|
+
sourceCode.commentsExistBetween(
|
116
|
+
openingBrace,
|
117
|
+
closingBrace,
|
118
|
+
)
|
119
|
+
) {
|
120
|
+
return;
|
121
|
+
}
|
122
|
+
|
107
123
|
context.report({
|
108
124
|
node,
|
125
|
+
loc: {
|
126
|
+
start: openingBrace.loc.start,
|
127
|
+
end: closingBrace.loc.end,
|
128
|
+
},
|
109
129
|
messageId: "unexpected",
|
110
130
|
data: { type: "switch" },
|
131
|
+
suggest: [
|
132
|
+
{
|
133
|
+
messageId: "suggestComment",
|
134
|
+
data: { type: "switch" },
|
135
|
+
fix(fixer) {
|
136
|
+
const range = [
|
137
|
+
openingBrace.range[1],
|
138
|
+
closingBrace.range[0],
|
139
|
+
];
|
140
|
+
|
141
|
+
return fixer.replaceTextRange(
|
142
|
+
range,
|
143
|
+
" /* empty */ ",
|
144
|
+
);
|
145
|
+
},
|
146
|
+
},
|
147
|
+
],
|
111
148
|
});
|
112
149
|
}
|
113
150
|
},
|
package/lib/rules/no-eval.js
CHANGED
@@ -226,7 +226,9 @@ module.exports = {
|
|
226
226
|
|
227
227
|
Program(node) {
|
228
228
|
const scope = sourceCode.getScope(node),
|
229
|
-
features =
|
229
|
+
features =
|
230
|
+
context.languageOptions.parserOptions.ecmaFeatures ||
|
231
|
+
{},
|
230
232
|
strict =
|
231
233
|
scope.isStrict ||
|
232
234
|
node.sourceType === "module" ||
|
@@ -189,7 +189,7 @@ module.exports = {
|
|
189
189
|
* @returns {boolean} true if they do not match
|
190
190
|
*/
|
191
191
|
function baseTenLosesPrecision(node) {
|
192
|
-
const rawNumber = getRaw(node);
|
192
|
+
const rawNumber = getRaw(node).toLowerCase();
|
193
193
|
|
194
194
|
/*
|
195
195
|
* If trailing zeros equal the exponent, this is a valid representation
|
@@ -278,6 +278,12 @@ module.exports = {
|
|
278
278
|
meta: {
|
279
279
|
type: "problem",
|
280
280
|
|
281
|
+
defaultOptions: [
|
282
|
+
{
|
283
|
+
allowEscape: false,
|
284
|
+
},
|
285
|
+
],
|
286
|
+
|
281
287
|
docs: {
|
282
288
|
description:
|
283
289
|
"Disallow characters which are made with multiple code points in character class syntax",
|
@@ -293,7 +299,6 @@ module.exports = {
|
|
293
299
|
properties: {
|
294
300
|
allowEscape: {
|
295
301
|
type: "boolean",
|
296
|
-
default: false,
|
297
302
|
},
|
298
303
|
},
|
299
304
|
additionalProperties: false,
|
@@ -313,7 +318,7 @@ module.exports = {
|
|
313
318
|
},
|
314
319
|
},
|
315
320
|
create(context) {
|
316
|
-
const allowEscape = context.options
|
321
|
+
const [{ allowEscape }] = context.options;
|
317
322
|
const sourceCode = context.sourceCode;
|
318
323
|
const parser = new RegExpParser();
|
319
324
|
const checkedPatternNodes = new Set();
|