eslint 9.9.0 → 9.10.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 +43 -38
- package/lib/config/config.js +278 -0
- package/lib/config/flat-config-array.js +3 -204
- package/lib/eslint/eslint.js +24 -11
- package/lib/languages/js/source-code/source-code.js +29 -94
- package/lib/linter/apply-disable-directives.js +17 -28
- package/lib/linter/file-context.js +134 -0
- package/lib/linter/linter.js +49 -87
- package/lib/rules/id-length.js +1 -0
- package/lib/rules/no-invalid-regexp.js +34 -18
- package/lib/rules/require-unicode-regexp.js +95 -14
- package/lib/rules/utils/regular-expressions.js +11 -3
- package/lib/services/parser-service.js +65 -0
- package/lib/types/index.d.ts +1635 -0
- package/lib/types/rules/best-practices.d.ts +1075 -0
- package/lib/types/rules/deprecated.d.ts +294 -0
- package/lib/types/rules/ecmascript-6.d.ts +561 -0
- package/lib/types/rules/index.d.ts +50 -0
- package/lib/types/rules/node-commonjs.d.ts +160 -0
- package/lib/types/rules/possible-errors.d.ts +598 -0
- package/lib/types/rules/strict-mode.d.ts +38 -0
- package/lib/types/rules/stylistic-issues.d.ts +1932 -0
- package/lib/types/rules/variables.d.ts +221 -0
- package/lib/types/use-at-your-own-risk.d.ts +85 -0
- package/package.json +34 -23
- package/lib/linter/config-comment-parser.js +0 -169
@@ -0,0 +1,221 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview This file contains the rule types for ESLint. It was initially extracted
|
3
|
+
* from the `@types/eslint` package.
|
4
|
+
*/
|
5
|
+
|
6
|
+
/*
|
7
|
+
* MIT License
|
8
|
+
* Copyright (c) Microsoft Corporation.
|
9
|
+
*
|
10
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11
|
+
* of this software and associated documentation files (the "Software"), to deal
|
12
|
+
* in the Software without restriction, including without limitation the rights
|
13
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14
|
+
* copies of the Software, and to permit persons to whom the Software is
|
15
|
+
* furnished to do so, subject to the following conditions:
|
16
|
+
* The above copyright notice and this permission notice shall be included in all
|
17
|
+
* copies or substantial portions of the Software.
|
18
|
+
*
|
19
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
20
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
21
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
22
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
23
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
24
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
25
|
+
* SOFTWARE
|
26
|
+
*/
|
27
|
+
|
28
|
+
import { Linter } from "../index";
|
29
|
+
|
30
|
+
export interface Variables extends Linter.RulesRecord {
|
31
|
+
/**
|
32
|
+
* Rule to require or disallow initialization in variable declarations.
|
33
|
+
*
|
34
|
+
* @since 1.0.0-rc-1
|
35
|
+
* @see https://eslint.org/docs/rules/init-declarations
|
36
|
+
*/
|
37
|
+
"init-declarations":
|
38
|
+
| Linter.RuleEntry<["always"]>
|
39
|
+
| Linter.RuleEntry<
|
40
|
+
[
|
41
|
+
"never",
|
42
|
+
Partial<{
|
43
|
+
ignoreForLoopInit: boolean;
|
44
|
+
}>,
|
45
|
+
]
|
46
|
+
>;
|
47
|
+
|
48
|
+
/**
|
49
|
+
* Rule to disallow deleting variables.
|
50
|
+
*
|
51
|
+
* @remarks
|
52
|
+
* Recommended by ESLint, the rule was enabled in `eslint:recommended`.
|
53
|
+
*
|
54
|
+
* @since 0.0.9
|
55
|
+
* @see https://eslint.org/docs/rules/no-delete-var
|
56
|
+
*/
|
57
|
+
"no-delete-var": Linter.RuleEntry<[]>;
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Rule to disallow labels that share a name with a variable.
|
61
|
+
*
|
62
|
+
* @since 0.0.9
|
63
|
+
* @see https://eslint.org/docs/rules/no-label-var
|
64
|
+
*/
|
65
|
+
"no-label-var": Linter.RuleEntry<[]>;
|
66
|
+
|
67
|
+
/**
|
68
|
+
* Rule to disallow specified global variables.
|
69
|
+
*
|
70
|
+
* @since 2.3.0
|
71
|
+
* @see https://eslint.org/docs/rules/no-restricted-globals
|
72
|
+
*/
|
73
|
+
"no-restricted-globals": Linter.RuleEntry<
|
74
|
+
[
|
75
|
+
...Array<
|
76
|
+
| string
|
77
|
+
| {
|
78
|
+
name: string;
|
79
|
+
message?: string | undefined;
|
80
|
+
}
|
81
|
+
>,
|
82
|
+
]
|
83
|
+
>;
|
84
|
+
|
85
|
+
/**
|
86
|
+
* Rule to disallow variable declarations from shadowing variables declared in the outer scope.
|
87
|
+
*
|
88
|
+
* @since 0.0.9
|
89
|
+
* @see https://eslint.org/docs/rules/no-shadow
|
90
|
+
*/
|
91
|
+
"no-shadow": Linter.RuleEntry<
|
92
|
+
[
|
93
|
+
Partial<{
|
94
|
+
/**
|
95
|
+
* @default false
|
96
|
+
*/
|
97
|
+
builtinGlobals: boolean;
|
98
|
+
/**
|
99
|
+
* @default 'functions'
|
100
|
+
*/
|
101
|
+
hoist: "functions" | "all" | "never";
|
102
|
+
allow: string[];
|
103
|
+
}>,
|
104
|
+
]
|
105
|
+
>;
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Rule to disallow identifiers from shadowing restricted names.
|
109
|
+
*
|
110
|
+
* @remarks
|
111
|
+
* Recommended by ESLint, the rule was enabled in `eslint:recommended`.
|
112
|
+
*
|
113
|
+
* @since 0.1.4
|
114
|
+
* @see https://eslint.org/docs/rules/no-shadow-restricted-names
|
115
|
+
*/
|
116
|
+
"no-shadow-restricted-names": Linter.RuleEntry<[]>;
|
117
|
+
|
118
|
+
/**
|
119
|
+
* Rule to disallow the use of undeclared variables unless mentioned in `global` comments.
|
120
|
+
*
|
121
|
+
* @remarks
|
122
|
+
* Recommended by ESLint, the rule was enabled in `eslint:recommended`.
|
123
|
+
*
|
124
|
+
* @since 0.0.9
|
125
|
+
* @see https://eslint.org/docs/rules/no-undef
|
126
|
+
*/
|
127
|
+
"no-undef": Linter.RuleEntry<
|
128
|
+
[
|
129
|
+
Partial<{
|
130
|
+
/**
|
131
|
+
* @default false
|
132
|
+
*/
|
133
|
+
typeof: boolean;
|
134
|
+
}>,
|
135
|
+
]
|
136
|
+
>;
|
137
|
+
|
138
|
+
/**
|
139
|
+
* Rule to disallow initializing variables to `undefined`.
|
140
|
+
*
|
141
|
+
* @since 0.0.6
|
142
|
+
* @see https://eslint.org/docs/rules/no-undef-init
|
143
|
+
*/
|
144
|
+
"no-undef-init": Linter.RuleEntry<[]>;
|
145
|
+
|
146
|
+
/**
|
147
|
+
* Rule to disallow the use of `undefined` as an identifier.
|
148
|
+
*
|
149
|
+
* @since 0.7.1
|
150
|
+
* @see https://eslint.org/docs/rules/no-undefined
|
151
|
+
*/
|
152
|
+
"no-undefined": Linter.RuleEntry<[]>;
|
153
|
+
|
154
|
+
/**
|
155
|
+
* Rule to disallow unused variables.
|
156
|
+
*
|
157
|
+
* @remarks
|
158
|
+
* Recommended by ESLint, the rule was enabled in `eslint:recommended`.
|
159
|
+
*
|
160
|
+
* @since 0.0.9
|
161
|
+
* @see https://eslint.org/docs/rules/no-unused-vars
|
162
|
+
*/
|
163
|
+
"no-unused-vars": Linter.RuleEntry<
|
164
|
+
[
|
165
|
+
| "all"
|
166
|
+
| "local"
|
167
|
+
| Partial<{
|
168
|
+
/**
|
169
|
+
* @default 'all'
|
170
|
+
*/
|
171
|
+
vars: "all" | "local";
|
172
|
+
varsIgnorePattern: string;
|
173
|
+
/**
|
174
|
+
* @default 'after-used'
|
175
|
+
*/
|
176
|
+
args: "after-used" | "all" | "none";
|
177
|
+
/**
|
178
|
+
* @default false
|
179
|
+
*/
|
180
|
+
ignoreRestSiblings: boolean;
|
181
|
+
argsIgnorePattern: string;
|
182
|
+
/**
|
183
|
+
* @default 'none'
|
184
|
+
*/
|
185
|
+
caughtErrors: "none" | "all";
|
186
|
+
caughtErrorsIgnorePattern: string;
|
187
|
+
destructuredArrayIgnorePattern: string;
|
188
|
+
}>,
|
189
|
+
]
|
190
|
+
>;
|
191
|
+
|
192
|
+
/**
|
193
|
+
* Rule to disallow the use of variables before they are defined.
|
194
|
+
*
|
195
|
+
* @since 0.0.9
|
196
|
+
* @see https://eslint.org/docs/rules/no-use-before-define
|
197
|
+
*/
|
198
|
+
"no-use-before-define": Linter.RuleEntry<
|
199
|
+
[
|
200
|
+
| Partial<{
|
201
|
+
/**
|
202
|
+
* @default true
|
203
|
+
*/
|
204
|
+
functions: boolean;
|
205
|
+
/**
|
206
|
+
* @default true
|
207
|
+
*/
|
208
|
+
classes: boolean;
|
209
|
+
/**
|
210
|
+
* @default true
|
211
|
+
*/
|
212
|
+
variables: boolean;
|
213
|
+
/**
|
214
|
+
* @default false
|
215
|
+
*/
|
216
|
+
allowNamedExports: boolean;
|
217
|
+
}>
|
218
|
+
| "nofunc",
|
219
|
+
]
|
220
|
+
>;
|
221
|
+
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview This file contains the types for the use-at-your-own-risk
|
3
|
+
* entrypoint. It was initially extracted from the `@types/eslint` package.
|
4
|
+
*/
|
5
|
+
|
6
|
+
/*
|
7
|
+
* MIT License
|
8
|
+
* Copyright (c) Microsoft Corporation.
|
9
|
+
*
|
10
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11
|
+
* of this software and associated documentation files (the "Software"), to deal
|
12
|
+
* in the Software without restriction, including without limitation the rights
|
13
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14
|
+
* copies of the Software, and to permit persons to whom the Software is
|
15
|
+
* furnished to do so, subject to the following conditions:
|
16
|
+
* The above copyright notice and this permission notice shall be included in all
|
17
|
+
* copies or substantial portions of the Software.
|
18
|
+
*
|
19
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
20
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
21
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
22
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
23
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
24
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
25
|
+
* SOFTWARE
|
26
|
+
*/
|
27
|
+
|
28
|
+
|
29
|
+
import { ESLint, Rule } from "./index.js";
|
30
|
+
|
31
|
+
/** @deprecated */
|
32
|
+
export const builtinRules: Map<string, Rule.RuleModule>;
|
33
|
+
|
34
|
+
/** @deprecated */
|
35
|
+
export class FileEnumerator {
|
36
|
+
constructor(
|
37
|
+
params?: {
|
38
|
+
cwd?: string;
|
39
|
+
configArrayFactory?: any;
|
40
|
+
extensions?: any;
|
41
|
+
globInputPaths?: boolean;
|
42
|
+
errorOnUnmatchedPattern?: boolean;
|
43
|
+
ignore?: boolean;
|
44
|
+
},
|
45
|
+
);
|
46
|
+
isTargetPath(filePath: string, providedConfig?: any): boolean;
|
47
|
+
iterateFiles(
|
48
|
+
patternOrPatterns: string | string[],
|
49
|
+
): IterableIterator<{ config: any; filePath: string; ignored: boolean }>;
|
50
|
+
}
|
51
|
+
|
52
|
+
export { /** @deprecated */ ESLint as FlatESLint };
|
53
|
+
|
54
|
+
/** @deprecated */
|
55
|
+
export class LegacyESLint {
|
56
|
+
static configType: "eslintrc";
|
57
|
+
|
58
|
+
static readonly version: string;
|
59
|
+
|
60
|
+
static outputFixes(results: ESLint.LintResult[]): Promise<void>;
|
61
|
+
|
62
|
+
static getErrorResults(results: ESLint.LintResult[]): ESLint.LintResult[];
|
63
|
+
|
64
|
+
constructor(options?: ESLint.LegacyOptions);
|
65
|
+
|
66
|
+
lintFiles(patterns: string | string[]): Promise<ESLint.LintResult[]>;
|
67
|
+
|
68
|
+
lintText(
|
69
|
+
code: string,
|
70
|
+
options?: { filePath?: string | undefined; warnIgnored?: boolean | undefined },
|
71
|
+
): Promise<ESLint.LintResult[]>;
|
72
|
+
|
73
|
+
getRulesMetaForResults(results: ESLint.LintResult[]): ESLint.LintResultData["rulesMeta"];
|
74
|
+
|
75
|
+
hasFlag(flag: string): false;
|
76
|
+
|
77
|
+
calculateConfigForFile(filePath: string): Promise<any>;
|
78
|
+
|
79
|
+
isPathIgnored(filePath: string): Promise<boolean>;
|
80
|
+
|
81
|
+
loadFormatter(nameOrPath?: string): Promise<ESLint.Formatter>;
|
82
|
+
}
|
83
|
+
|
84
|
+
/** @deprecated */
|
85
|
+
export function shouldUseFlatConfig(): Promise<boolean>;
|
package/package.json
CHANGED
@@ -1,16 +1,26 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "9.
|
3
|
+
"version": "9.10.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
7
7
|
"eslint": "./bin/eslint.js"
|
8
8
|
},
|
9
9
|
"main": "./lib/api.js",
|
10
|
+
"types": "./lib/types/index.d.ts",
|
10
11
|
"exports": {
|
12
|
+
".": {
|
13
|
+
"types": "./lib/types/index.d.ts",
|
14
|
+
"default": "./lib/api.js"
|
15
|
+
},
|
11
16
|
"./package.json": "./package.json",
|
12
|
-
"
|
13
|
-
|
17
|
+
"./use-at-your-own-risk": {
|
18
|
+
"types": "./lib/types/use-at-your-own-risk.d.ts",
|
19
|
+
"default": "./lib/unsupported-api.js"
|
20
|
+
},
|
21
|
+
"./rules": {
|
22
|
+
"types": "./lib/types/rules/index.d.ts"
|
23
|
+
}
|
14
24
|
},
|
15
25
|
"scripts": {
|
16
26
|
"build:docs:update-links": "node tools/fetch-docs-links.js",
|
@@ -18,12 +28,12 @@
|
|
18
28
|
"build:webpack": "node Makefile.js webpack",
|
19
29
|
"build:readme": "node tools/update-readme.js",
|
20
30
|
"build:rules-index": "node Makefile.js generateRuleIndexPage",
|
21
|
-
"lint": "
|
22
|
-
"lint:docs:js": "
|
31
|
+
"lint": "trunk check --no-fix --ignore=docs/**/*.js -a --filter=eslint && trunk check --no-fix --ignore=docs/**/*.js",
|
32
|
+
"lint:docs:js": "trunk check --no-fix --ignore=** --ignore=!docs/**/*.js -a --filter=eslint && trunk check --no-fix --ignore=** --ignore=!docs/**/*.js",
|
23
33
|
"lint:docs:rule-examples": "node Makefile.js checkRuleExamples",
|
24
|
-
"lint:fix": "node Makefile.js lint -- fix",
|
25
|
-
"lint:fix:docs:js": "node Makefile.js lintDocsJS -- fix",
|
26
34
|
"lint:unused": "knip",
|
35
|
+
"lint:fix": "trunk check -y --ignore=docs/**/*.js -a --filter=eslint && trunk check -y --ignore=docs/**/*.js",
|
36
|
+
"lint:fix:docs:js": "trunk check -y --ignore=** --ignore=!docs/**/*.js -a --flter=eslint && trunk check -y --ignore=** --ignore=!docs/**/*.js",
|
27
37
|
"release:generate:alpha": "node Makefile.js generatePrerelease -- alpha",
|
28
38
|
"release:generate:beta": "node Makefile.js generatePrerelease -- beta",
|
29
39
|
"release:generate:latest": "node Makefile.js generateRelease",
|
@@ -34,14 +44,15 @@
|
|
34
44
|
"test:cli": "mocha",
|
35
45
|
"test:fuzz": "node Makefile.js fuzz",
|
36
46
|
"test:performance": "node Makefile.js perf",
|
37
|
-
"test:emfile": "node tools/check-emfile-handling.js"
|
47
|
+
"test:emfile": "node tools/check-emfile-handling.js",
|
48
|
+
"test:types": "tsc -p tests/lib/types/tsconfig.json"
|
38
49
|
},
|
39
50
|
"gitHooks": {
|
40
51
|
"pre-commit": "lint-staged"
|
41
52
|
},
|
42
53
|
"lint-staged": {
|
43
|
-
"*.js": "
|
44
|
-
"*.md": "
|
54
|
+
"*.js": "trunk check --fix --filter=eslint",
|
55
|
+
"*.md": "trunk check --fix --filter=markdownlint",
|
45
56
|
"lib/rules/*.js": [
|
46
57
|
"node tools/update-eslint-all.js",
|
47
58
|
"git add packages/js/src/configs/eslint-all.js"
|
@@ -51,7 +62,7 @@
|
|
51
62
|
"node tools/fetch-docs-links.js",
|
52
63
|
"git add docs/src/_data/further_reading_links.json"
|
53
64
|
],
|
54
|
-
"docs/**/*.svg": "
|
65
|
+
"docs/**/*.svg": "trunk check --fix --filter=svgo"
|
55
66
|
},
|
56
67
|
"files": [
|
57
68
|
"LICENSE",
|
@@ -68,9 +79,10 @@
|
|
68
79
|
"dependencies": {
|
69
80
|
"@eslint-community/eslint-utils": "^4.2.0",
|
70
81
|
"@eslint-community/regexpp": "^4.11.0",
|
71
|
-
"@eslint/config-array": "^0.
|
82
|
+
"@eslint/config-array": "^0.18.0",
|
72
83
|
"@eslint/eslintrc": "^3.1.0",
|
73
|
-
"@eslint/js": "9.
|
84
|
+
"@eslint/js": "9.10.0",
|
85
|
+
"@eslint/plugin-kit": "^0.1.0",
|
74
86
|
"@humanwhocodes/module-importer": "^1.0.1",
|
75
87
|
"@humanwhocodes/retry": "^0.3.0",
|
76
88
|
"@nodelib/fs.walk": "^1.2.8",
|
@@ -93,7 +105,6 @@
|
|
93
105
|
"is-glob": "^4.0.0",
|
94
106
|
"is-path-inside": "^3.0.3",
|
95
107
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
96
|
-
"levn": "^0.4.1",
|
97
108
|
"lodash.merge": "^4.6.2",
|
98
109
|
"minimatch": "^3.1.2",
|
99
110
|
"natural-compare": "^1.4.0",
|
@@ -104,14 +115,16 @@
|
|
104
115
|
"devDependencies": {
|
105
116
|
"@babel/core": "^7.4.3",
|
106
117
|
"@babel/preset-env": "^7.4.3",
|
107
|
-
"@eslint/core": "^0.
|
108
|
-
"@eslint/json": "^0.
|
118
|
+
"@eslint/core": "^0.5.0",
|
119
|
+
"@eslint/json": "^0.4.0",
|
120
|
+
"@trunkio/launcher": "^1.3.0",
|
109
121
|
"@types/estree": "^1.0.5",
|
122
|
+
"@types/json-schema": "^7.0.15",
|
110
123
|
"@types/node": "^20.11.5",
|
111
|
-
"@wdio/browser-runner": "^
|
112
|
-
"@wdio/cli": "^
|
113
|
-
"@wdio/concise-reporter": "^
|
114
|
-
"@wdio/mocha-framework": "^
|
124
|
+
"@wdio/browser-runner": "^9.0.5",
|
125
|
+
"@wdio/cli": "^9.0.5",
|
126
|
+
"@wdio/concise-reporter": "^9.0.4",
|
127
|
+
"@wdio/mocha-framework": "^9.0.5",
|
115
128
|
"babel-loader": "^8.0.5",
|
116
129
|
"c8": "^7.12.0",
|
117
130
|
"chai": "^4.0.1",
|
@@ -122,6 +135,7 @@
|
|
122
135
|
"eslint": "file:.",
|
123
136
|
"eslint-config-eslint": "file:packages/eslint-config-eslint",
|
124
137
|
"eslint-plugin-eslint-plugin": "^6.0.0",
|
138
|
+
"eslint-plugin-yml": "^1.14.0",
|
125
139
|
"eslint-release": "^3.2.2",
|
126
140
|
"eslint-rule-composer": "^0.3.0",
|
127
141
|
"eslump": "^3.0.0",
|
@@ -133,14 +147,11 @@
|
|
133
147
|
"got": "^11.8.3",
|
134
148
|
"gray-matter": "^4.0.3",
|
135
149
|
"jiti": "^1.21.6",
|
136
|
-
"js-yaml": "^4.1.0",
|
137
150
|
"knip": "^5.21.0",
|
138
151
|
"lint-staged": "^11.0.0",
|
139
152
|
"load-perf": "^0.2.0",
|
140
153
|
"markdown-it": "^12.2.0",
|
141
154
|
"markdown-it-container": "^3.0.0",
|
142
|
-
"markdownlint": "^0.34.0",
|
143
|
-
"markdownlint-cli": "^0.41.0",
|
144
155
|
"marked": "^4.0.8",
|
145
156
|
"metascraper": "^5.25.7",
|
146
157
|
"metascraper-description": "^5.25.7",
|
@@ -1,169 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview Config Comment Parser
|
3
|
-
* @author Nicholas C. Zakas
|
4
|
-
*/
|
5
|
-
|
6
|
-
/* eslint class-methods-use-this: off -- Methods desired on instance */
|
7
|
-
"use strict";
|
8
|
-
|
9
|
-
//------------------------------------------------------------------------------
|
10
|
-
// Requirements
|
11
|
-
//------------------------------------------------------------------------------
|
12
|
-
|
13
|
-
const levn = require("levn"),
|
14
|
-
{
|
15
|
-
Legacy: {
|
16
|
-
ConfigOps
|
17
|
-
}
|
18
|
-
} = require("@eslint/eslintrc/universal"),
|
19
|
-
{
|
20
|
-
directivesPattern
|
21
|
-
} = require("../shared/directives");
|
22
|
-
|
23
|
-
const debug = require("debug")("eslint:config-comment-parser");
|
24
|
-
|
25
|
-
//------------------------------------------------------------------------------
|
26
|
-
// Public Interface
|
27
|
-
//------------------------------------------------------------------------------
|
28
|
-
|
29
|
-
/**
|
30
|
-
* Object to parse ESLint configuration comments inside JavaScript files.
|
31
|
-
* @name ConfigCommentParser
|
32
|
-
*/
|
33
|
-
module.exports = class ConfigCommentParser {
|
34
|
-
|
35
|
-
/**
|
36
|
-
* Parses a list of "name:string_value" or/and "name" options divided by comma or
|
37
|
-
* whitespace. Used for "global" comments.
|
38
|
-
* @param {string} string The string to parse.
|
39
|
-
* @param {Comment} comment The comment node which has the string.
|
40
|
-
* @returns {Object} Result map object of names and string values, or null values if no value was provided
|
41
|
-
*/
|
42
|
-
parseStringConfig(string, comment) {
|
43
|
-
debug("Parsing String config");
|
44
|
-
|
45
|
-
const items = {};
|
46
|
-
|
47
|
-
// Collapse whitespace around `:` and `,` to make parsing easier
|
48
|
-
const trimmedString = string.replace(/\s*([:,])\s*/gu, "$1");
|
49
|
-
|
50
|
-
trimmedString.split(/\s|,+/u).forEach(name => {
|
51
|
-
if (!name) {
|
52
|
-
return;
|
53
|
-
}
|
54
|
-
|
55
|
-
// value defaults to null (if not provided), e.g: "foo" => ["foo", null]
|
56
|
-
const [key, value = null] = name.split(":");
|
57
|
-
|
58
|
-
items[key] = { value, comment };
|
59
|
-
});
|
60
|
-
return items;
|
61
|
-
}
|
62
|
-
|
63
|
-
/**
|
64
|
-
* Parses a JSON-like config.
|
65
|
-
* @param {string} string The string to parse.
|
66
|
-
* @returns {({success: true, config: Object}|{success: false, error: {message: string}})} Result map object
|
67
|
-
*/
|
68
|
-
parseJsonConfig(string) {
|
69
|
-
debug("Parsing JSON config");
|
70
|
-
|
71
|
-
// Parses a JSON-like comment by the same way as parsing CLI option.
|
72
|
-
try {
|
73
|
-
const items = levn.parse("Object", string) || {};
|
74
|
-
|
75
|
-
// Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`.
|
76
|
-
// Also, commaless notations have invalid severity:
|
77
|
-
// "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"}
|
78
|
-
// Should ignore that case as well.
|
79
|
-
if (ConfigOps.isEverySeverityValid(items)) {
|
80
|
-
return {
|
81
|
-
success: true,
|
82
|
-
config: items
|
83
|
-
};
|
84
|
-
}
|
85
|
-
} catch {
|
86
|
-
|
87
|
-
debug("Levn parsing failed; falling back to manual parsing.");
|
88
|
-
|
89
|
-
// ignore to parse the string by a fallback.
|
90
|
-
}
|
91
|
-
|
92
|
-
/*
|
93
|
-
* Optionator cannot parse commaless notations.
|
94
|
-
* But we are supporting that. So this is a fallback for that.
|
95
|
-
*/
|
96
|
-
const normalizedString = string.replace(/([-a-zA-Z0-9/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,");
|
97
|
-
|
98
|
-
try {
|
99
|
-
const items = JSON.parse(`{${normalizedString}}`);
|
100
|
-
|
101
|
-
return {
|
102
|
-
success: true,
|
103
|
-
config: items
|
104
|
-
};
|
105
|
-
} catch (ex) {
|
106
|
-
debug("Manual parsing failed.");
|
107
|
-
|
108
|
-
return {
|
109
|
-
success: false,
|
110
|
-
error: {
|
111
|
-
message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`
|
112
|
-
}
|
113
|
-
};
|
114
|
-
|
115
|
-
}
|
116
|
-
}
|
117
|
-
|
118
|
-
/**
|
119
|
-
* Parses a config of values separated by comma.
|
120
|
-
* @param {string} string The string to parse.
|
121
|
-
* @returns {Object} Result map of values and true values
|
122
|
-
*/
|
123
|
-
parseListConfig(string) {
|
124
|
-
debug("Parsing list config");
|
125
|
-
|
126
|
-
const items = {};
|
127
|
-
|
128
|
-
string.split(",").forEach(name => {
|
129
|
-
const trimmedName = name.trim().replace(/^(?<quote>['"]?)(?<ruleId>.*)\k<quote>$/us, "$<ruleId>");
|
130
|
-
|
131
|
-
if (trimmedName) {
|
132
|
-
items[trimmedName] = true;
|
133
|
-
}
|
134
|
-
});
|
135
|
-
return items;
|
136
|
-
}
|
137
|
-
|
138
|
-
/**
|
139
|
-
* Extract the directive and the justification from a given directive comment and trim them.
|
140
|
-
* @param {string} value The comment text to extract.
|
141
|
-
* @returns {{directivePart: string, justificationPart: string}} The extracted directive and justification.
|
142
|
-
*/
|
143
|
-
extractDirectiveComment(value) {
|
144
|
-
const match = /\s-{2,}\s/u.exec(value);
|
145
|
-
|
146
|
-
if (!match) {
|
147
|
-
return { directivePart: value.trim(), justificationPart: "" };
|
148
|
-
}
|
149
|
-
|
150
|
-
const directive = value.slice(0, match.index).trim();
|
151
|
-
const justification = value.slice(match.index + match[0].length).trim();
|
152
|
-
|
153
|
-
return { directivePart: directive, justificationPart: justification };
|
154
|
-
}
|
155
|
-
|
156
|
-
/**
|
157
|
-
* Parses a directive comment into directive text and value.
|
158
|
-
* @param {Comment} comment The comment node with the directive to be parsed.
|
159
|
-
* @returns {{directiveText: string, directiveValue: string}} The directive text and value.
|
160
|
-
*/
|
161
|
-
parseDirective(comment) {
|
162
|
-
const { directivePart } = this.extractDirectiveComment(comment.value);
|
163
|
-
const match = directivesPattern.exec(directivePart);
|
164
|
-
const directiveText = match[1];
|
165
|
-
const directiveValue = directivePart.slice(match.index + directiveText.length);
|
166
|
-
|
167
|
-
return { directiveText, directiveValue };
|
168
|
-
}
|
169
|
-
};
|