eslint 9.19.0 → 9.20.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 -11
- package/lib/config/config-loader.js +34 -4
- package/lib/config/config.js +6 -1
- package/lib/eslint/eslint.js +1 -1
- package/lib/linter/linter.js +24 -3
- package/lib/rules/arrow-body-style.js +1 -1
- package/lib/rules/consistent-this.js +9 -0
- package/lib/shared/flags.js +43 -5
- package/lib/types/index.d.ts +64 -60
- package/messages/config-serialize-function.js +28 -0
- package/messages/eslintrc-plugins.js +6 -2
- package/package.json +4 -4
package/README.md
CHANGED
@@ -35,7 +35,6 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
|
|
35
35
|
1. [Releases](#releases)
|
36
36
|
1. [Security Policy](#security-policy)
|
37
37
|
1. [Semantic Versioning Policy](#semantic-versioning-policy)
|
38
|
-
1. [Stylistic Rule Updates](#stylistic-rule-updates)
|
39
38
|
1. [License](#license)
|
40
39
|
1. [Team](#team)
|
41
40
|
1. [Sponsors](#sponsors)
|
@@ -191,15 +190,6 @@ ESLint follows [semantic versioning](https://semver.org). However, due to the na
|
|
191
190
|
|
192
191
|
According to our policy, any minor update may report more linting errors than the previous release (ex: from a bug fix). As such, we recommend using the tilde (`~`) in `package.json` e.g. `"eslint": "~3.1.0"` to guarantee the results of your builds.
|
193
192
|
|
194
|
-
## Stylistic Rule Updates
|
195
|
-
|
196
|
-
Stylistic rules are frozen according to [our policy](https://eslint.org/blog/2020/05/changes-to-rules-policies) on how we evaluate new rules and rule changes.
|
197
|
-
This means:
|
198
|
-
|
199
|
-
* **Bug fixes**: We will still fix bugs in stylistic rules.
|
200
|
-
* **New ECMAScript features**: We will also make sure stylistic rules are compatible with new ECMAScript features.
|
201
|
-
* **New options**: We will **not** add any new options to stylistic rules unless an option is the only way to fix a bug or support a newly-added ECMAScript feature.
|
202
|
-
|
203
193
|
## License
|
204
194
|
|
205
195
|
MIT License
|
@@ -318,7 +308,7 @@ to get your logo on our READMEs and [website](https://eslint.org/sponsors).
|
|
318
308
|
<h3>Platinum Sponsors</h3>
|
319
309
|
<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>
|
320
310
|
<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></p><h3>Silver Sponsors</h3>
|
321
|
-
<p><a href="https://www.serptriumph.com/"><img src="https://images.opencollective.com/serp-triumph5/fea3074/logo.png" alt="SERP Triumph" height="64"></a> <a href="https://www.jetbrains.com/"><img src="https://images.opencollective.com/jetbrains/fe76f99/logo.png" alt="JetBrains" 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></p><h3>Bronze Sponsors</h3>
|
311
|
+
<p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/e6d15e1/logo.png" alt="Vite" height="64"></a> <a href="https://www.serptriumph.com/"><img src="https://images.opencollective.com/serp-triumph5/fea3074/logo.png" alt="SERP Triumph" height="64"></a> <a href="https://www.jetbrains.com/"><img src="https://images.opencollective.com/jetbrains/fe76f99/logo.png" alt="JetBrains" 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></p><h3>Bronze Sponsors</h3>
|
322
312
|
<p><a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" 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://nolebase.ayaka.io"><img src="https://avatars.githubusercontent.com/u/11081491" alt="Neko" 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></p>
|
323
313
|
<h3>Technology Sponsors</h3>
|
324
314
|
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.
|
@@ -499,11 +499,41 @@ class ConfigLoader {
|
|
499
499
|
debug(`Loading config file ${configFilePath}`);
|
500
500
|
const fileConfig = await loadConfigFile(configFilePath);
|
501
501
|
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
502
|
+
/*
|
503
|
+
* It's possible that a config file could be empty or else
|
504
|
+
* have an empty object or array. In this case, we want to
|
505
|
+
* warn the user that they have an empty config.
|
506
|
+
*
|
507
|
+
* An empty CommonJS file exports an empty object while
|
508
|
+
* an empty ESM file exports undefined.
|
509
|
+
*/
|
510
|
+
|
511
|
+
let emptyConfig = typeof fileConfig === "undefined";
|
512
|
+
|
513
|
+
debug(`Config file ${configFilePath} is ${emptyConfig ? "empty" : "not empty"}`);
|
514
|
+
|
515
|
+
if (!emptyConfig) {
|
516
|
+
if (Array.isArray(fileConfig)) {
|
517
|
+
if (fileConfig.length === 0) {
|
518
|
+
debug(`Config file ${configFilePath} is an empty array`);
|
519
|
+
emptyConfig = true;
|
520
|
+
} else {
|
521
|
+
configs.push(...fileConfig);
|
522
|
+
}
|
523
|
+
} else {
|
524
|
+
if (typeof fileConfig === "object" && fileConfig !== null && Object.keys(fileConfig).length === 0) {
|
525
|
+
debug(`Config file ${configFilePath} is an empty object`);
|
526
|
+
emptyConfig = true;
|
527
|
+
} else {
|
528
|
+
configs.push(fileConfig);
|
529
|
+
}
|
530
|
+
}
|
506
531
|
}
|
532
|
+
|
533
|
+
if (emptyConfig) {
|
534
|
+
globalThis.process?.emitWarning?.(`Running ESLint with an empty config (from ${configFilePath}). Please double-check that this is what you want. If you want to run ESLint with an empty config, export [{}] to remove this warning.`, "ESLintEmptyConfigWarning");
|
535
|
+
}
|
536
|
+
|
507
537
|
}
|
508
538
|
|
509
539
|
// add in any configured defaults
|
package/lib/config/config.js
CHANGED
@@ -110,7 +110,12 @@ function languageOptionsToJSON(languageOptions, objectKey = "languageOptions") {
|
|
110
110
|
}
|
111
111
|
|
112
112
|
if (typeof value === "function") {
|
113
|
-
|
113
|
+
const error = new TypeError(`Cannot serialize key "${key}" in ${objectKey}: Function values are not supported.`);
|
114
|
+
|
115
|
+
error.messageTemplate = "config-serialize-function";
|
116
|
+
error.messageData = { key, objectKey };
|
117
|
+
|
118
|
+
throw error;
|
114
119
|
}
|
115
120
|
|
116
121
|
}
|
package/lib/eslint/eslint.js
CHANGED
@@ -470,7 +470,7 @@ class ESLint {
|
|
470
470
|
defaultConfigs
|
471
471
|
};
|
472
472
|
|
473
|
-
this.#configLoader =
|
473
|
+
this.#configLoader = linter.hasFlag("unstable_config_lookup_from_file")
|
474
474
|
? new ConfigLoader(configLoaderOptions)
|
475
475
|
: new LegacyConfigLoader(configLoaderOptions);
|
476
476
|
|
package/lib/linter/linter.js
CHANGED
@@ -43,7 +43,7 @@ const { assertIsRuleSeverity } = require("../config/flat-config-schema");
|
|
43
43
|
const { normalizeSeverityToString, normalizeSeverityToNumber } = require("../shared/severity");
|
44
44
|
const { deepMergeArrays } = require("../shared/deep-merge-arrays");
|
45
45
|
const jslang = require("../languages/js");
|
46
|
-
const { activeFlags, inactiveFlags } = require("../shared/flags");
|
46
|
+
const { activeFlags, inactiveFlags, getInactivityReasonMessage } = require("../shared/flags");
|
47
47
|
const debug = require("debug")("eslint:linter");
|
48
48
|
const MAX_AUTOFIX_PASSES = 10;
|
49
49
|
const DEFAULT_PARSER_NAME = "espree";
|
@@ -1326,19 +1326,40 @@ class Linter {
|
|
1326
1326
|
*/
|
1327
1327
|
constructor({ cwd, configType = "flat", flags = [] } = {}) {
|
1328
1328
|
|
1329
|
+
const processedFlags = [];
|
1330
|
+
|
1329
1331
|
flags.forEach(flag => {
|
1330
1332
|
if (inactiveFlags.has(flag)) {
|
1331
|
-
|
1333
|
+
const inactiveFlagData = inactiveFlags.get(flag);
|
1334
|
+
const inactivityReason = getInactivityReasonMessage(inactiveFlagData);
|
1335
|
+
|
1336
|
+
if (typeof inactiveFlagData.replacedBy === "undefined") {
|
1337
|
+
throw new Error(`The flag '${flag}' is inactive: ${inactivityReason}`);
|
1338
|
+
}
|
1339
|
+
|
1340
|
+
// if there's a replacement, enable it instead of original
|
1341
|
+
if (typeof inactiveFlagData.replacedBy === "string") {
|
1342
|
+
processedFlags.push(inactiveFlagData.replacedBy);
|
1343
|
+
}
|
1344
|
+
|
1345
|
+
globalThis.process?.emitWarning?.(
|
1346
|
+
`The flag '${flag}' is inactive: ${inactivityReason}`,
|
1347
|
+
`ESLintInactiveFlag_${flag}`
|
1348
|
+
);
|
1349
|
+
|
1350
|
+
return;
|
1332
1351
|
}
|
1333
1352
|
|
1334
1353
|
if (!activeFlags.has(flag)) {
|
1335
1354
|
throw new Error(`Unknown flag '${flag}'.`);
|
1336
1355
|
}
|
1356
|
+
|
1357
|
+
processedFlags.push(flag);
|
1337
1358
|
});
|
1338
1359
|
|
1339
1360
|
internalSlotsMap.set(this, {
|
1340
1361
|
cwd: normalizeCwd(cwd),
|
1341
|
-
flags,
|
1362
|
+
flags: processedFlags,
|
1342
1363
|
lastConfigArray: null,
|
1343
1364
|
lastSourceCode: null,
|
1344
1365
|
lastSuppressedMessages: [],
|
@@ -143,7 +143,7 @@ module.exports = {
|
|
143
143
|
|
144
144
|
if (blockBody.length === 0) {
|
145
145
|
messageId = "unexpectedEmptyBlock";
|
146
|
-
} else if (blockBody.length > 1) {
|
146
|
+
} else if (blockBody.length > 1 || blockBody[0].type !== "ReturnStatement") {
|
147
147
|
messageId = "unexpectedOtherBlock";
|
148
148
|
} else if (blockBody[0].argument === null) {
|
149
149
|
messageId = "unexpectedSingleBlock";
|
@@ -119,8 +119,17 @@ module.exports = {
|
|
119
119
|
function ensureWasAssigned(node) {
|
120
120
|
const scope = sourceCode.getScope(node);
|
121
121
|
|
122
|
+
// if this is program scope we also need to check module scope
|
123
|
+
const extraScope = node.type === "Program" && node.sourceType === "module"
|
124
|
+
? scope.childScopes[0]
|
125
|
+
: null;
|
126
|
+
|
122
127
|
aliases.forEach(alias => {
|
123
128
|
checkWasAssigned(alias, scope);
|
129
|
+
|
130
|
+
if (extraScope) {
|
131
|
+
checkWasAssigned(alias, extraScope);
|
132
|
+
}
|
124
133
|
});
|
125
134
|
}
|
126
135
|
|
package/lib/shared/flags.js
CHANGED
@@ -4,6 +4,23 @@
|
|
4
4
|
|
5
5
|
"use strict";
|
6
6
|
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Typedefs
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
/**
|
12
|
+
* @typedef {Object} InactiveFlagData
|
13
|
+
* @property {string} description Flag description
|
14
|
+
* @property {string | null} [replacedBy] Can be either:
|
15
|
+
* - An active flag (string) that enables the same feature.
|
16
|
+
* - `null` if the feature is now enabled by default.
|
17
|
+
* - Omitted if the feature has been abandoned.
|
18
|
+
*/
|
19
|
+
|
20
|
+
//-----------------------------------------------------------------------------
|
21
|
+
// Exports
|
22
|
+
//-----------------------------------------------------------------------------
|
23
|
+
|
7
24
|
/**
|
8
25
|
* The set of flags that change ESLint behavior with a description.
|
9
26
|
* @type {Map<string, string>}
|
@@ -14,15 +31,36 @@ const activeFlags = new Map([
|
|
14
31
|
]);
|
15
32
|
|
16
33
|
/**
|
17
|
-
* The set of flags that used to be active
|
18
|
-
* @type {Map<string,
|
34
|
+
* The set of flags that used to be active.
|
35
|
+
* @type {Map<string, InactiveFlagData>}
|
19
36
|
*/
|
20
37
|
const inactiveFlags = new Map([
|
21
|
-
["
|
22
|
-
["
|
38
|
+
["test_only_replaced", { description: "Used only for testing flags that have been replaced by other flags.", replacedBy: "test_only" }],
|
39
|
+
["test_only_enabled_by_default", { description: "Used only for testing flags whose features have been enabled by default.", replacedBy: null }],
|
40
|
+
["test_only_abandoned", { description: "Used only for testing flags whose features have been abandoned." }],
|
41
|
+
["unstable_ts_config", { description: "Enable TypeScript configuration files.", replacedBy: null }]
|
23
42
|
]);
|
24
43
|
|
44
|
+
/**
|
45
|
+
* Creates a message that describes the reason the flag is inactive.
|
46
|
+
* @param {InactiveFlagData} inactiveFlagData Data for the inactive flag.
|
47
|
+
* @returns {string} Message describing the reason the flag is inactive.
|
48
|
+
*/
|
49
|
+
function getInactivityReasonMessage({ replacedBy }) {
|
50
|
+
if (typeof replacedBy === "undefined") {
|
51
|
+
return "This feature has been abandoned.";
|
52
|
+
}
|
53
|
+
|
54
|
+
if (typeof replacedBy === "string") {
|
55
|
+
return `This flag has been renamed '${replacedBy}' to reflect its stabilization. Please use '${replacedBy}' instead.`;
|
56
|
+
}
|
57
|
+
|
58
|
+
// null
|
59
|
+
return "This feature is now enabled by default.";
|
60
|
+
}
|
61
|
+
|
25
62
|
module.exports = {
|
26
63
|
activeFlags,
|
27
|
-
inactiveFlags
|
64
|
+
inactiveFlags,
|
65
|
+
getInactivityReasonMessage
|
28
66
|
};
|
package/lib/types/index.d.ts
CHANGED
@@ -26,10 +26,41 @@
|
|
26
26
|
*/
|
27
27
|
|
28
28
|
import * as ESTree from "estree";
|
29
|
-
import {
|
29
|
+
import type {
|
30
|
+
RuleVisitor,
|
31
|
+
TextSourceCode,
|
32
|
+
Language,
|
33
|
+
SourceRange,
|
34
|
+
TraversalStep,
|
35
|
+
LanguageOptions as GenericLanguageOptions,
|
36
|
+
RuleDefinition,
|
37
|
+
RuleContext as CoreRuleContext
|
38
|
+
} from "@eslint/core";
|
30
39
|
import { JSONSchema4 } from "json-schema";
|
31
40
|
import { LegacyESLint } from "./use-at-your-own-risk.js";
|
32
41
|
|
42
|
+
/*
|
43
|
+
* Need to extend the `RuleContext` interface to include the
|
44
|
+
* deprecated methods that have not yet been removed.
|
45
|
+
* TODO: Remove in v10.0.0.
|
46
|
+
*/
|
47
|
+
declare module "@eslint/core" {
|
48
|
+
interface RuleContext {
|
49
|
+
|
50
|
+
/** @deprecated Use `sourceCode.getAncestors()` instead */
|
51
|
+
getAncestors(): ESTree.Node[];
|
52
|
+
|
53
|
+
/** @deprecated Use `sourceCode.getDeclaredVariables()` instead */
|
54
|
+
getDeclaredVariables(node: ESTree.Node): Scope.Variable[];
|
55
|
+
|
56
|
+
/** @deprecated Use `sourceCode.getScope()` instead */
|
57
|
+
getScope(): Scope.Scope;
|
58
|
+
|
59
|
+
/** @deprecated Use `sourceCode.markVariableAsUsed()` instead */
|
60
|
+
markVariableAsUsed(name: string): boolean;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
33
64
|
export namespace AST {
|
34
65
|
type TokenType =
|
35
66
|
| "Boolean"
|
@@ -149,7 +180,12 @@ export namespace Scope {
|
|
149
180
|
|
150
181
|
// #region SourceCode
|
151
182
|
|
152
|
-
export class SourceCode {
|
183
|
+
export class SourceCode implements TextSourceCode<{
|
184
|
+
LangOptions: Linter.LanguageOptions;
|
185
|
+
RootNode: AST.Program;
|
186
|
+
SyntaxElementWithLoc: AST.Token | ESTree.Node;
|
187
|
+
ConfigNode: ESTree.Comment;
|
188
|
+
}> {
|
153
189
|
text: string;
|
154
190
|
ast: AST.Program;
|
155
191
|
lines: string[];
|
@@ -163,6 +199,9 @@ export class SourceCode {
|
|
163
199
|
|
164
200
|
static splitLines(text: string): string[];
|
165
201
|
|
202
|
+
getLoc(syntaxElement: AST.Token | ESTree.Node): ESTree.SourceLocation;
|
203
|
+
getRange(syntaxElement: AST.Token | ESTree.Node): SourceRange;
|
204
|
+
|
166
205
|
getText(node?: ESTree.Node, beforeCount?: number, afterCount?: number): string;
|
167
206
|
|
168
207
|
getLines(): string[];
|
@@ -238,6 +277,8 @@ export class SourceCode {
|
|
238
277
|
): boolean;
|
239
278
|
|
240
279
|
markVariableAsUsed(name: string, refNode?: ESTree.Node): boolean;
|
280
|
+
|
281
|
+
traverse(): Iterable<TraversalStep>;
|
241
282
|
}
|
242
283
|
|
243
284
|
export namespace SourceCode {
|
@@ -507,21 +548,25 @@ export namespace SourceCode {
|
|
507
548
|
// #endregion
|
508
549
|
|
509
550
|
export namespace Rule {
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
551
|
+
|
552
|
+
type RuleModule = RuleDefinition<{
|
553
|
+
LangOptions: Linter.LanguageOptions,
|
554
|
+
Code: SourceCode,
|
555
|
+
RuleOptions: any[],
|
556
|
+
Visitor: NodeListener,
|
557
|
+
Node: ESTree.Node,
|
558
|
+
MessageIds: string,
|
559
|
+
ExtRuleDocs: {}
|
560
|
+
}>;
|
514
561
|
|
515
562
|
type NodeTypes = ESTree.Node["type"];
|
516
|
-
interface NodeListener {
|
563
|
+
interface NodeListener extends RuleVisitor {
|
517
564
|
ArrayExpression?: ((node: ESTree.ArrayExpression & NodeParentExtension) => void) | undefined;
|
518
565
|
"ArrayExpression:exit"?: ((node: ESTree.ArrayExpression & NodeParentExtension) => void) | undefined;
|
519
566
|
ArrayPattern?: ((node: ESTree.ArrayPattern & NodeParentExtension) => void) | undefined;
|
520
567
|
"ArrayPattern:exit"?: ((node: ESTree.ArrayPattern & NodeParentExtension) => void) | undefined;
|
521
568
|
ArrowFunctionExpression?: ((node: ESTree.ArrowFunctionExpression & NodeParentExtension) => void) | undefined;
|
522
|
-
"ArrowFunctionExpression:exit"?:
|
523
|
-
| ((node: ESTree.ArrowFunctionExpression & NodeParentExtension) => void)
|
524
|
-
| undefined;
|
569
|
+
"ArrowFunctionExpression:exit"?: ((node: ESTree.ArrowFunctionExpression & NodeParentExtension) => void) | undefined;
|
525
570
|
AssignmentExpression?: ((node: ESTree.AssignmentExpression & NodeParentExtension) => void) | undefined;
|
526
571
|
"AssignmentExpression:exit"?: ((node: ESTree.AssignmentExpression & NodeParentExtension) => void) | undefined;
|
527
572
|
AssignmentPattern?: ((node: ESTree.AssignmentPattern & NodeParentExtension) => void) | undefined;
|
@@ -559,13 +604,9 @@ export namespace Rule {
|
|
559
604
|
ExportAllDeclaration?: ((node: ESTree.ExportAllDeclaration & NodeParentExtension) => void) | undefined;
|
560
605
|
"ExportAllDeclaration:exit"?: ((node: ESTree.ExportAllDeclaration & NodeParentExtension) => void) | undefined;
|
561
606
|
ExportDefaultDeclaration?: ((node: ESTree.ExportDefaultDeclaration & NodeParentExtension) => void) | undefined;
|
562
|
-
"ExportDefaultDeclaration:exit"?:
|
563
|
-
| ((node: ESTree.ExportDefaultDeclaration & NodeParentExtension) => void)
|
564
|
-
| undefined;
|
607
|
+
"ExportDefaultDeclaration:exit"?: ((node: ESTree.ExportDefaultDeclaration & NodeParentExtension) => void) | undefined;
|
565
608
|
ExportNamedDeclaration?: ((node: ESTree.ExportNamedDeclaration & NodeParentExtension) => void) | undefined;
|
566
|
-
"ExportNamedDeclaration:exit"?:
|
567
|
-
| ((node: ESTree.ExportNamedDeclaration & NodeParentExtension) => void)
|
568
|
-
| undefined;
|
609
|
+
"ExportNamedDeclaration:exit"?: ((node: ESTree.ExportNamedDeclaration & NodeParentExtension) => void) | undefined;
|
569
610
|
ExportSpecifier?: ((node: ESTree.ExportSpecifier & NodeParentExtension) => void) | undefined;
|
570
611
|
"ExportSpecifier:exit"?: ((node: ESTree.ExportSpecifier & NodeParentExtension) => void) | undefined;
|
571
612
|
ExpressionStatement?: ((node: ESTree.ExpressionStatement & NodeParentExtension) => void) | undefined;
|
@@ -587,15 +628,11 @@ export namespace Rule {
|
|
587
628
|
ImportDeclaration?: ((node: ESTree.ImportDeclaration & NodeParentExtension) => void) | undefined;
|
588
629
|
"ImportDeclaration:exit"?: ((node: ESTree.ImportDeclaration & NodeParentExtension) => void) | undefined;
|
589
630
|
ImportDefaultSpecifier?: ((node: ESTree.ImportDefaultSpecifier & NodeParentExtension) => void) | undefined;
|
590
|
-
"ImportDefaultSpecifier:exit"?:
|
591
|
-
| ((node: ESTree.ImportDefaultSpecifier & NodeParentExtension) => void)
|
592
|
-
| undefined;
|
631
|
+
"ImportDefaultSpecifier:exit"?: ((node: ESTree.ImportDefaultSpecifier & NodeParentExtension) => void) | undefined;
|
593
632
|
ImportExpression?: ((node: ESTree.ImportExpression & NodeParentExtension) => void) | undefined;
|
594
633
|
"ImportExpression:exit"?: ((node: ESTree.ImportExpression & NodeParentExtension) => void) | undefined;
|
595
634
|
ImportNamespaceSpecifier?: ((node: ESTree.ImportNamespaceSpecifier & NodeParentExtension) => void) | undefined;
|
596
|
-
"ImportNamespaceSpecifier:exit"?:
|
597
|
-
| ((node: ESTree.ImportNamespaceSpecifier & NodeParentExtension) => void)
|
598
|
-
| undefined;
|
635
|
+
"ImportNamespaceSpecifier:exit"?: ((node: ESTree.ImportNamespaceSpecifier & NodeParentExtension) => void) | undefined;
|
599
636
|
ImportSpecifier?: ((node: ESTree.ImportSpecifier & NodeParentExtension) => void) | undefined;
|
600
637
|
"ImportSpecifier:exit"?: ((node: ESTree.ImportSpecifier & NodeParentExtension) => void) | undefined;
|
601
638
|
LabeledStatement?: ((node: ESTree.LabeledStatement & NodeParentExtension) => void) | undefined;
|
@@ -641,9 +678,7 @@ export namespace Rule {
|
|
641
678
|
SwitchStatement?: ((node: ESTree.SwitchStatement & NodeParentExtension) => void) | undefined;
|
642
679
|
"SwitchStatement:exit"?: ((node: ESTree.SwitchStatement & NodeParentExtension) => void) | undefined;
|
643
680
|
TaggedTemplateExpression?: ((node: ESTree.TaggedTemplateExpression & NodeParentExtension) => void) | undefined;
|
644
|
-
"TaggedTemplateExpression:exit"?:
|
645
|
-
| ((node: ESTree.TaggedTemplateExpression & NodeParentExtension) => void)
|
646
|
-
| undefined;
|
681
|
+
"TaggedTemplateExpression:exit"?: ((node: ESTree.TaggedTemplateExpression & NodeParentExtension) => void) | undefined;
|
647
682
|
TemplateElement?: ((node: ESTree.TemplateElement & NodeParentExtension) => void) | undefined;
|
648
683
|
"TemplateElement:exit"?: ((node: ESTree.TemplateElement & NodeParentExtension) => void) | undefined;
|
649
684
|
TemplateLiteral?: ((node: ESTree.TemplateLiteral & NodeParentExtension) => void) | undefined;
|
@@ -765,39 +800,8 @@ export namespace Rule {
|
|
765
800
|
hasSuggestions?: boolean | undefined;
|
766
801
|
}
|
767
802
|
|
768
|
-
interface RuleContext {
|
769
|
-
|
770
|
-
options: any[];
|
771
|
-
settings: { [name: string]: any };
|
772
|
-
parserPath: string | undefined;
|
773
|
-
languageOptions: Linter.LanguageOptions;
|
774
|
-
parserOptions: Linter.ParserOptions;
|
775
|
-
cwd: string;
|
776
|
-
filename: string;
|
777
|
-
physicalFilename: string;
|
778
|
-
sourceCode: SourceCode;
|
779
|
-
|
780
|
-
getAncestors(): ESTree.Node[];
|
781
|
-
|
782
|
-
getDeclaredVariables(node: ESTree.Node): Scope.Variable[];
|
783
|
-
|
784
|
-
/** @deprecated Use property `filename` directly instead */
|
785
|
-
getFilename(): string;
|
786
|
-
|
787
|
-
/** @deprecated Use property `physicalFilename` directly instead */
|
788
|
-
getPhysicalFilename(): string;
|
789
|
-
|
790
|
-
/** @deprecated Use property `cwd` directly instead */
|
791
|
-
getCwd(): string;
|
792
|
-
|
793
|
-
getScope(): Scope.Scope;
|
794
|
-
|
795
|
-
/** @deprecated Use property `sourceCode` directly instead */
|
796
|
-
getSourceCode(): SourceCode;
|
797
|
-
|
798
|
-
markVariableAsUsed(name: string): boolean;
|
799
|
-
|
800
|
-
report(descriptor: ReportDescriptor): void;
|
803
|
+
interface RuleContext extends CoreRuleContext {
|
804
|
+
// report(descriptor: ReportDescriptor): void;
|
801
805
|
}
|
802
806
|
|
803
807
|
type ReportFixer = (fixer: RuleFixer) => null | Fix | IterableIterator<Fix> | Fix[];
|
@@ -1325,7 +1329,7 @@ export namespace Linter {
|
|
1325
1329
|
[name: string]: GlobalConf;
|
1326
1330
|
}
|
1327
1331
|
|
1328
|
-
interface LanguageOptions {
|
1332
|
+
interface LanguageOptions extends GenericLanguageOptions {
|
1329
1333
|
/**
|
1330
1334
|
* The version of ECMAScript to support. May be any year (i.e., 2022) or
|
1331
1335
|
* version (i.e., 5). Set to "latest" for the most recent supported version.
|
@@ -1469,7 +1473,7 @@ export namespace ESLint {
|
|
1469
1473
|
environments?: Record<string, Environment> | undefined;
|
1470
1474
|
languages?: Record<string, Language> | undefined;
|
1471
1475
|
processors?: Record<string, Linter.Processor> | undefined;
|
1472
|
-
rules?: Record<string,
|
1476
|
+
rules?: Record<string, RuleDefinition> | undefined;
|
1473
1477
|
}
|
1474
1478
|
|
1475
1479
|
type FixType = "directive" | "problem" | "suggestion" | "layout";
|
@@ -0,0 +1,28 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
module.exports = function({ key, objectKey }) {
|
4
|
+
|
5
|
+
// special case for parsers
|
6
|
+
const isParser = objectKey === "parser" && (key === "parse" || key === "parseForESLint");
|
7
|
+
const parserMessage = `
|
8
|
+
This typically happens when you're using a custom parser that does not
|
9
|
+
provide a "meta" property, which is how ESLint determines the serialized
|
10
|
+
representation. Please open an issue with the maintainer of the custom parser
|
11
|
+
and share this link:
|
12
|
+
|
13
|
+
https://eslint.org/docs/latest/extend/custom-parsers#meta-data-in-custom-parsers
|
14
|
+
`.trim();
|
15
|
+
|
16
|
+
return `
|
17
|
+
The requested operation requires ESLint to serialize configuration data,
|
18
|
+
but the configuration key "${objectKey}.${key}" contains a function value,
|
19
|
+
which cannot be serialized.
|
20
|
+
|
21
|
+
${
|
22
|
+
isParser ? parserMessage : "Please double-check your configuration for errors."
|
23
|
+
}
|
24
|
+
|
25
|
+
If you still have problems, please stop by https://eslint.org/chat/help to chat
|
26
|
+
with the team.
|
27
|
+
`.trimStart();
|
28
|
+
};
|
@@ -5,9 +5,13 @@ module.exports = function({ plugins }) {
|
|
5
5
|
const isArrayOfStrings = typeof plugins[0] === "string";
|
6
6
|
|
7
7
|
return `
|
8
|
-
A config object has a "plugins" key defined as an array${isArrayOfStrings ? " of strings" : ""}.
|
8
|
+
A config object has a "plugins" key defined as an array${isArrayOfStrings ? " of strings" : ""}. It looks something like this:
|
9
9
|
|
10
|
-
|
10
|
+
{
|
11
|
+
"plugins": ${JSON.stringify(plugins)}
|
12
|
+
}
|
13
|
+
|
14
|
+
Flat config requires "plugins" to be an object, like this:
|
11
15
|
|
12
16
|
{
|
13
17
|
plugins: {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "9.
|
3
|
+
"version": "9.20.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"type": "commonjs",
|
@@ -102,9 +102,9 @@
|
|
102
102
|
"@eslint-community/eslint-utils": "^4.2.0",
|
103
103
|
"@eslint-community/regexpp": "^4.12.1",
|
104
104
|
"@eslint/config-array": "^0.19.0",
|
105
|
-
"@eslint/core": "^0.
|
105
|
+
"@eslint/core": "^0.11.0",
|
106
106
|
"@eslint/eslintrc": "^3.2.0",
|
107
|
-
"@eslint/js": "9.
|
107
|
+
"@eslint/js": "9.20.0",
|
108
108
|
"@eslint/plugin-kit": "^0.2.5",
|
109
109
|
"@humanfs/node": "^0.16.6",
|
110
110
|
"@humanwhocodes/module-importer": "^1.0.1",
|
@@ -138,7 +138,7 @@
|
|
138
138
|
"@arethetypeswrong/cli": "^0.17.0",
|
139
139
|
"@babel/core": "^7.4.3",
|
140
140
|
"@babel/preset-env": "^7.4.3",
|
141
|
-
"@eslint/json": "^0.
|
141
|
+
"@eslint/json": "^0.10.0",
|
142
142
|
"@trunkio/launcher": "^1.3.0",
|
143
143
|
"@types/node": "^20.11.5",
|
144
144
|
"@typescript-eslint/parser": "^8.4.0",
|