eslint 8.56.0 → 8.57.1
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/lib/api.js +29 -1
- package/lib/config/flat-config-array.js +110 -4
- package/lib/config/flat-config-schema.js +35 -20
- package/lib/eslint/eslint-helpers.js +85 -55
- package/lib/eslint/eslint.js +7 -0
- package/lib/eslint/flat-eslint.js +48 -31
- package/lib/linter/linter.js +1 -1
- package/lib/options.js +1 -1
- package/lib/rule-tester/flat-rule-tester.js +10 -1
- package/lib/source-code/source-code.js +1 -1
- package/package.json +9 -7
package/lib/api.js
CHANGED
@@ -9,17 +9,45 @@
|
|
9
9
|
// Requirements
|
10
10
|
//-----------------------------------------------------------------------------
|
11
11
|
|
12
|
-
const { ESLint } = require("./eslint");
|
12
|
+
const { ESLint, FlatESLint } = require("./eslint");
|
13
|
+
const { shouldUseFlatConfig } = require("./eslint/flat-eslint");
|
13
14
|
const { Linter } = require("./linter");
|
14
15
|
const { RuleTester } = require("./rule-tester");
|
15
16
|
const { SourceCode } = require("./source-code");
|
16
17
|
|
18
|
+
//-----------------------------------------------------------------------------
|
19
|
+
// Functions
|
20
|
+
//-----------------------------------------------------------------------------
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Loads the correct ESLint constructor given the options.
|
24
|
+
* @param {Object} [options] The options object
|
25
|
+
* @param {boolean} [options.useFlatConfig] Whether or not to use a flat config
|
26
|
+
* @param {string} [options.cwd] The current working directory
|
27
|
+
* @returns {Promise<ESLint|LegacyESLint>} The ESLint constructor
|
28
|
+
*/
|
29
|
+
async function loadESLint({ useFlatConfig, cwd = process.cwd() } = {}) {
|
30
|
+
|
31
|
+
/*
|
32
|
+
* Note: The v9.x version of this function doesn't have a cwd option
|
33
|
+
* because it's not used. It's only used in the v8.x version of this
|
34
|
+
* function.
|
35
|
+
*/
|
36
|
+
|
37
|
+
const shouldESLintUseFlatConfig = typeof useFlatConfig === "boolean"
|
38
|
+
? useFlatConfig
|
39
|
+
: await shouldUseFlatConfig({ cwd });
|
40
|
+
|
41
|
+
return shouldESLintUseFlatConfig ? FlatESLint : ESLint;
|
42
|
+
}
|
43
|
+
|
17
44
|
//-----------------------------------------------------------------------------
|
18
45
|
// Exports
|
19
46
|
//-----------------------------------------------------------------------------
|
20
47
|
|
21
48
|
module.exports = {
|
22
49
|
Linter,
|
50
|
+
loadESLint,
|
23
51
|
ESLint,
|
24
52
|
RuleTester,
|
25
53
|
SourceCode
|
@@ -19,6 +19,11 @@ const jsPlugin = require("@eslint/js");
|
|
19
19
|
// Helpers
|
20
20
|
//-----------------------------------------------------------------------------
|
21
21
|
|
22
|
+
/**
|
23
|
+
* Fields that are considered metadata and not part of the config object.
|
24
|
+
*/
|
25
|
+
const META_FIELDS = new Set(["name"]);
|
26
|
+
|
22
27
|
const ruleValidator = new RuleValidator();
|
23
28
|
|
24
29
|
/**
|
@@ -75,7 +80,53 @@ function getObjectId(object) {
|
|
75
80
|
return name;
|
76
81
|
}
|
77
82
|
|
83
|
+
/**
|
84
|
+
* Wraps a config error with details about where the error occurred.
|
85
|
+
* @param {Error} error The original error.
|
86
|
+
* @param {number} originalLength The original length of the config array.
|
87
|
+
* @param {number} baseLength The length of the base config.
|
88
|
+
* @returns {TypeError} The new error with details.
|
89
|
+
*/
|
90
|
+
function wrapConfigErrorWithDetails(error, originalLength, baseLength) {
|
91
|
+
|
92
|
+
let location = "user-defined";
|
93
|
+
let configIndex = error.index;
|
94
|
+
|
95
|
+
/*
|
96
|
+
* A config array is set up in this order:
|
97
|
+
* 1. Base config
|
98
|
+
* 2. Original configs
|
99
|
+
* 3. User-defined configs
|
100
|
+
* 4. CLI-defined configs
|
101
|
+
*
|
102
|
+
* So we need to adjust the index to account for the base config.
|
103
|
+
*
|
104
|
+
* - If the index is less than the base length, it's in the base config
|
105
|
+
* (as specified by `baseConfig` argument to `FlatConfigArray` constructor).
|
106
|
+
* - If the index is greater than the base length but less than the original
|
107
|
+
* length + base length, it's in the original config. The original config
|
108
|
+
* is passed to the `FlatConfigArray` constructor as the first argument.
|
109
|
+
* - Otherwise, it's in the user-defined config, which is loaded from the
|
110
|
+
* config file and merged with any command-line options.
|
111
|
+
*/
|
112
|
+
if (error.index < baseLength) {
|
113
|
+
location = "base";
|
114
|
+
} else if (error.index < originalLength + baseLength) {
|
115
|
+
location = "original";
|
116
|
+
configIndex = error.index - baseLength;
|
117
|
+
} else {
|
118
|
+
configIndex = error.index - originalLength - baseLength;
|
119
|
+
}
|
120
|
+
|
121
|
+
return new TypeError(
|
122
|
+
`${error.message.slice(0, -1)} at ${location} index ${configIndex}.`,
|
123
|
+
{ cause: error }
|
124
|
+
);
|
125
|
+
}
|
126
|
+
|
78
127
|
const originalBaseConfig = Symbol("originalBaseConfig");
|
128
|
+
const originalLength = Symbol("originalLength");
|
129
|
+
const baseLength = Symbol("baseLength");
|
79
130
|
|
80
131
|
//-----------------------------------------------------------------------------
|
81
132
|
// Exports
|
@@ -102,12 +153,24 @@ class FlatConfigArray extends ConfigArray {
|
|
102
153
|
schema: flatConfigSchema
|
103
154
|
});
|
104
155
|
|
156
|
+
/**
|
157
|
+
* The original length of the array before any modifications.
|
158
|
+
* @type {number}
|
159
|
+
*/
|
160
|
+
this[originalLength] = this.length;
|
161
|
+
|
105
162
|
if (baseConfig[Symbol.iterator]) {
|
106
163
|
this.unshift(...baseConfig);
|
107
164
|
} else {
|
108
165
|
this.unshift(baseConfig);
|
109
166
|
}
|
110
167
|
|
168
|
+
/**
|
169
|
+
* The length of the array after applying the base config.
|
170
|
+
* @type {number}
|
171
|
+
*/
|
172
|
+
this[baseLength] = this.length - this[originalLength];
|
173
|
+
|
111
174
|
/**
|
112
175
|
* The base config used to build the config array.
|
113
176
|
* @type {Array<FlatConfig>}
|
@@ -125,6 +188,49 @@ class FlatConfigArray extends ConfigArray {
|
|
125
188
|
Object.defineProperty(this, "shouldIgnore", { writable: false });
|
126
189
|
}
|
127
190
|
|
191
|
+
/**
|
192
|
+
* Normalizes the array by calling the superclass method and catching/rethrowing
|
193
|
+
* any ConfigError exceptions with additional details.
|
194
|
+
* @param {any} [context] The context to use to normalize the array.
|
195
|
+
* @returns {Promise<FlatConfigArray>} A promise that resolves when the array is normalized.
|
196
|
+
*/
|
197
|
+
normalize(context) {
|
198
|
+
return super.normalize(context)
|
199
|
+
.catch(error => {
|
200
|
+
if (error.name === "ConfigError") {
|
201
|
+
throw wrapConfigErrorWithDetails(error, this[originalLength], this[baseLength]);
|
202
|
+
}
|
203
|
+
|
204
|
+
throw error;
|
205
|
+
|
206
|
+
});
|
207
|
+
}
|
208
|
+
|
209
|
+
/**
|
210
|
+
* Normalizes the array by calling the superclass method and catching/rethrowing
|
211
|
+
* any ConfigError exceptions with additional details.
|
212
|
+
* @param {any} [context] The context to use to normalize the array.
|
213
|
+
* @returns {FlatConfigArray} The current instance.
|
214
|
+
* @throws {TypeError} If the config is invalid.
|
215
|
+
*/
|
216
|
+
normalizeSync(context) {
|
217
|
+
|
218
|
+
try {
|
219
|
+
|
220
|
+
return super.normalizeSync(context);
|
221
|
+
|
222
|
+
} catch (error) {
|
223
|
+
|
224
|
+
if (error.name === "ConfigError") {
|
225
|
+
throw wrapConfigErrorWithDetails(error, this[originalLength], this[baseLength]);
|
226
|
+
}
|
227
|
+
|
228
|
+
throw error;
|
229
|
+
|
230
|
+
}
|
231
|
+
|
232
|
+
}
|
233
|
+
|
128
234
|
/* eslint-disable class-methods-use-this -- Desired as instance method */
|
129
235
|
/**
|
130
236
|
* Replaces a config with another config to allow us to put strings
|
@@ -155,15 +261,15 @@ class FlatConfigArray extends ConfigArray {
|
|
155
261
|
}
|
156
262
|
|
157
263
|
/*
|
158
|
-
* If `
|
159
|
-
*
|
160
|
-
*
|
264
|
+
* If a config object has `ignores` and no other non-meta fields, then it's an object
|
265
|
+
* for global ignores. If `shouldIgnore` is false, that object shouldn't apply,
|
266
|
+
* so we'll remove its `ignores`.
|
161
267
|
*/
|
162
268
|
if (
|
163
269
|
!this.shouldIgnore &&
|
164
270
|
!this[originalBaseConfig].includes(config) &&
|
165
271
|
config.ignores &&
|
166
|
-
|
272
|
+
Object.keys(config).filter(key => !META_FIELDS.has(key)).length === 1
|
167
273
|
) {
|
168
274
|
/* eslint-disable-next-line no-unused-vars -- need to strip off other keys */
|
169
275
|
const { ignores, ...otherKeys } = config;
|
@@ -53,6 +53,15 @@ function isNonNullObject(value) {
|
|
53
53
|
return typeof value === "object" && value !== null;
|
54
54
|
}
|
55
55
|
|
56
|
+
/**
|
57
|
+
* Check if a value is a non-null non-array object.
|
58
|
+
* @param {any} value The value to check.
|
59
|
+
* @returns {boolean} `true` if the value is a non-null non-array object.
|
60
|
+
*/
|
61
|
+
function isNonArrayObject(value) {
|
62
|
+
return isNonNullObject(value) && !Array.isArray(value);
|
63
|
+
}
|
64
|
+
|
56
65
|
/**
|
57
66
|
* Check if a value is undefined.
|
58
67
|
* @param {any} value The value to check.
|
@@ -63,19 +72,27 @@ function isUndefined(value) {
|
|
63
72
|
}
|
64
73
|
|
65
74
|
/**
|
66
|
-
* Deeply merges two objects.
|
75
|
+
* Deeply merges two non-array objects.
|
67
76
|
* @param {Object} first The base object.
|
68
77
|
* @param {Object} second The overrides object.
|
78
|
+
* @param {Map<string, Map<string, Object>>} [mergeMap] Maps the combination of first and second arguments to a merged result.
|
69
79
|
* @returns {Object} An object with properties from both first and second.
|
70
80
|
*/
|
71
|
-
function deepMerge(first
|
81
|
+
function deepMerge(first, second, mergeMap = new Map()) {
|
72
82
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
83
|
+
let secondMergeMap = mergeMap.get(first);
|
84
|
+
|
85
|
+
if (secondMergeMap) {
|
86
|
+
const result = secondMergeMap.get(second);
|
87
|
+
|
88
|
+
if (result) {
|
89
|
+
|
90
|
+
// If this combination of first and second arguments has been already visited, return the previously created result.
|
91
|
+
return result;
|
92
|
+
}
|
93
|
+
} else {
|
94
|
+
secondMergeMap = new Map();
|
95
|
+
mergeMap.set(first, secondMergeMap);
|
79
96
|
}
|
80
97
|
|
81
98
|
/*
|
@@ -89,27 +106,25 @@ function deepMerge(first = {}, second = {}) {
|
|
89
106
|
...second
|
90
107
|
};
|
91
108
|
|
109
|
+
delete result.__proto__; // eslint-disable-line no-proto -- don't merge own property "__proto__"
|
110
|
+
|
111
|
+
// Store the pending result for this combination of first and second arguments.
|
112
|
+
secondMergeMap.set(second, result);
|
113
|
+
|
92
114
|
for (const key of Object.keys(second)) {
|
93
115
|
|
94
116
|
// avoid hairy edge case
|
95
|
-
if (key === "__proto__") {
|
117
|
+
if (key === "__proto__" || !Object.prototype.propertyIsEnumerable.call(first, key)) {
|
96
118
|
continue;
|
97
119
|
}
|
98
120
|
|
99
121
|
const firstValue = first[key];
|
100
122
|
const secondValue = second[key];
|
101
123
|
|
102
|
-
if (
|
103
|
-
result[key] = deepMerge(firstValue, secondValue);
|
104
|
-
} else if (isUndefined(
|
105
|
-
|
106
|
-
result[key] = deepMerge(
|
107
|
-
Array.isArray(secondValue) ? [] : {},
|
108
|
-
secondValue
|
109
|
-
);
|
110
|
-
} else if (!isUndefined(secondValue)) {
|
111
|
-
result[key] = secondValue;
|
112
|
-
}
|
124
|
+
if (isNonArrayObject(firstValue) && isNonArrayObject(secondValue)) {
|
125
|
+
result[key] = deepMerge(firstValue, secondValue, mergeMap);
|
126
|
+
} else if (isUndefined(secondValue)) {
|
127
|
+
result[key] = firstValue;
|
113
128
|
}
|
114
129
|
}
|
115
130
|
|
@@ -15,7 +15,6 @@ const fsp = fs.promises;
|
|
15
15
|
const isGlob = require("is-glob");
|
16
16
|
const hash = require("../cli-engine/hash");
|
17
17
|
const minimatch = require("minimatch");
|
18
|
-
const util = require("util");
|
19
18
|
const fswalk = require("@nodelib/fs.walk");
|
20
19
|
const globParent = require("glob-parent");
|
21
20
|
const isPathInside = require("is-path-inside");
|
@@ -24,7 +23,6 @@ const isPathInside = require("is-path-inside");
|
|
24
23
|
// Fixup references
|
25
24
|
//-----------------------------------------------------------------------------
|
26
25
|
|
27
|
-
const doFsWalk = util.promisify(fswalk.walk);
|
28
26
|
const Minimatch = minimatch.Minimatch;
|
29
27
|
const MINIMATCH_OPTIONS = { dot: true };
|
30
28
|
|
@@ -270,56 +268,92 @@ async function globSearch({
|
|
270
268
|
*/
|
271
269
|
const unmatchedPatterns = new Set([...relativeToPatterns.keys()]);
|
272
270
|
|
273
|
-
const filePaths = (await
|
271
|
+
const filePaths = (await new Promise((resolve, reject) => {
|
274
272
|
|
275
|
-
|
276
|
-
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
277
|
-
const matchesPattern = matchers.some(matcher => matcher.match(relativePath, true));
|
278
|
-
|
279
|
-
return matchesPattern && !configs.isDirectoryIgnored(entry.path);
|
280
|
-
},
|
281
|
-
entryFilter(entry) {
|
282
|
-
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
273
|
+
let promiseRejected = false;
|
283
274
|
|
284
|
-
|
285
|
-
|
275
|
+
/**
|
276
|
+
* Wraps a boolean-returning filter function. The wrapped function will reject the promise if an error occurs.
|
277
|
+
* @param {Function} filter A filter function to wrap.
|
278
|
+
* @returns {Function} A function similar to the wrapped filter that rejects the promise if an error occurs.
|
279
|
+
*/
|
280
|
+
function wrapFilter(filter) {
|
281
|
+
return (...args) => {
|
282
|
+
|
283
|
+
// No need to run the filter if an error has been thrown.
|
284
|
+
if (!promiseRejected) {
|
285
|
+
try {
|
286
|
+
return filter(...args);
|
287
|
+
} catch (error) {
|
288
|
+
promiseRejected = true;
|
289
|
+
reject(error);
|
290
|
+
}
|
291
|
+
}
|
286
292
|
return false;
|
287
|
-
}
|
293
|
+
};
|
294
|
+
}
|
288
295
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
296
|
+
fswalk.walk(
|
297
|
+
basePath,
|
298
|
+
{
|
299
|
+
deepFilter: wrapFilter(entry => {
|
300
|
+
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
301
|
+
const matchesPattern = matchers.some(matcher => matcher.match(relativePath, true));
|
302
|
+
|
303
|
+
return matchesPattern && !configs.isDirectoryIgnored(entry.path);
|
304
|
+
}),
|
305
|
+
entryFilter: wrapFilter(entry => {
|
306
|
+
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
307
|
+
|
308
|
+
// entries may be directories or files so filter out directories
|
309
|
+
if (entry.dirent.isDirectory()) {
|
310
|
+
return false;
|
311
|
+
}
|
301
312
|
|
302
313
|
/*
|
303
|
-
* We
|
304
|
-
*
|
305
|
-
*
|
306
|
-
* pattern
|
307
|
-
*
|
308
|
-
*
|
309
|
-
*
|
310
|
-
* it twice with the same argument.
|
314
|
+
* Optimization: We need to track when patterns are left unmatched
|
315
|
+
* and so we use `unmatchedPatterns` to do that. There is a bit of
|
316
|
+
* complexity here because the same file can be matched by more than
|
317
|
+
* one pattern. So, when we start, we actually need to test every
|
318
|
+
* pattern against every file. Once we know there are no remaining
|
319
|
+
* unmatched patterns, then we can switch to just looking for the
|
320
|
+
* first matching pattern for improved speed.
|
311
321
|
*/
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
322
|
+
const matchesPattern = unmatchedPatterns.size > 0
|
323
|
+
? matchers.reduce((previousValue, matcher) => {
|
324
|
+
const pathMatches = matcher.match(relativePath);
|
325
|
+
|
326
|
+
/*
|
327
|
+
* We updated the unmatched patterns set only if the path
|
328
|
+
* matches and the file isn't ignored. If the file is
|
329
|
+
* ignored, that means there wasn't a match for the
|
330
|
+
* pattern so it should not be removed.
|
331
|
+
*
|
332
|
+
* Performance note: isFileIgnored() aggressively caches
|
333
|
+
* results so there is no performance penalty for calling
|
334
|
+
* it twice with the same argument.
|
335
|
+
*/
|
336
|
+
if (pathMatches && !configs.isFileIgnored(entry.path)) {
|
337
|
+
unmatchedPatterns.delete(matcher.pattern);
|
338
|
+
}
|
339
|
+
|
340
|
+
return pathMatches || previousValue;
|
341
|
+
}, false)
|
342
|
+
: matchers.some(matcher => matcher.match(relativePath));
|
343
|
+
|
344
|
+
return matchesPattern && !configs.isFileIgnored(entry.path);
|
345
|
+
})
|
346
|
+
},
|
347
|
+
(error, entries) => {
|
348
|
+
|
349
|
+
// If the promise is already rejected, calling `resolve` or `reject` will do nothing.
|
350
|
+
if (error) {
|
351
|
+
reject(error);
|
352
|
+
} else {
|
353
|
+
resolve(entries);
|
354
|
+
}
|
355
|
+
}
|
356
|
+
);
|
323
357
|
})).map(entry => entry.path);
|
324
358
|
|
325
359
|
// now check to see if we have any unmatched patterns
|
@@ -450,7 +484,7 @@ async function globMultiSearch({ searches, configs, errorOnUnmatchedPattern }) {
|
|
450
484
|
|
451
485
|
}
|
452
486
|
|
453
|
-
return
|
487
|
+
return filePaths;
|
454
488
|
|
455
489
|
}
|
456
490
|
|
@@ -499,10 +533,7 @@ async function findFiles({
|
|
499
533
|
|
500
534
|
// files are added directly to the list
|
501
535
|
if (stat.isFile()) {
|
502
|
-
results.push(
|
503
|
-
filePath,
|
504
|
-
ignored: configs.isFileIgnored(filePath)
|
505
|
-
});
|
536
|
+
results.push(filePath);
|
506
537
|
}
|
507
538
|
|
508
539
|
// directories need extensions attached
|
@@ -560,11 +591,10 @@ async function findFiles({
|
|
560
591
|
});
|
561
592
|
|
562
593
|
return [
|
563
|
-
...
|
564
|
-
|
565
|
-
filePath
|
566
|
-
|
567
|
-
}))
|
594
|
+
...new Set([
|
595
|
+
...results,
|
596
|
+
...globbyResults.map(filePath => path.resolve(filePath))
|
597
|
+
])
|
568
598
|
];
|
569
599
|
}
|
570
600
|
|
package/lib/eslint/eslint.js
CHANGED
@@ -682,6 +682,13 @@ class ESLint {
|
|
682
682
|
}
|
683
683
|
}
|
684
684
|
|
685
|
+
/**
|
686
|
+
* The type of configuration used by this class.
|
687
|
+
* @type {string}
|
688
|
+
* @static
|
689
|
+
*/
|
690
|
+
ESLint.configType = "eslintrc";
|
691
|
+
|
685
692
|
//------------------------------------------------------------------------------
|
686
693
|
// Public Interface
|
687
694
|
//------------------------------------------------------------------------------
|
@@ -91,7 +91,11 @@ const LintResultCache = require("../cli-engine/lint-result-cache");
|
|
91
91
|
// Helpers
|
92
92
|
//------------------------------------------------------------------------------
|
93
93
|
|
94
|
-
const
|
94
|
+
const FLAT_CONFIG_FILENAMES = [
|
95
|
+
"eslint.config.js",
|
96
|
+
"eslint.config.mjs",
|
97
|
+
"eslint.config.cjs"
|
98
|
+
];
|
95
99
|
const debug = require("debug")("eslint:flat-eslint");
|
96
100
|
const removedFormatters = new Set(["table", "codeframe"]);
|
97
101
|
const privateMembers = new WeakMap();
|
@@ -248,7 +252,7 @@ function compareResultsByFilePath(a, b) {
|
|
248
252
|
*/
|
249
253
|
function findFlatConfigFile(cwd) {
|
250
254
|
return findUp(
|
251
|
-
|
255
|
+
FLAT_CONFIG_FILENAMES,
|
252
256
|
{ cwd }
|
253
257
|
);
|
254
258
|
}
|
@@ -485,7 +489,7 @@ function verifyText({
|
|
485
489
|
* @returns {boolean} `true` if the linter should adopt the code block.
|
486
490
|
*/
|
487
491
|
filterCodeBlock(blockFilename) {
|
488
|
-
return configs.
|
492
|
+
return configs.getConfig(blockFilename) !== void 0;
|
489
493
|
}
|
490
494
|
}
|
491
495
|
);
|
@@ -537,6 +541,23 @@ function createExtraneousResultsError() {
|
|
537
541
|
return new TypeError("Results object was not created from this ESLint instance.");
|
538
542
|
}
|
539
543
|
|
544
|
+
/**
|
545
|
+
* Creates a fixer function based on the provided fix, fixTypesSet, and config.
|
546
|
+
* @param {Function|boolean} fix The original fix option.
|
547
|
+
* @param {Set<string>} fixTypesSet A set of fix types to filter messages for fixing.
|
548
|
+
* @param {FlatConfig} config The config for the file that generated the message.
|
549
|
+
* @returns {Function|boolean} The fixer function or the original fix value.
|
550
|
+
*/
|
551
|
+
function getFixerForFixTypes(fix, fixTypesSet, config) {
|
552
|
+
if (!fix || !fixTypesSet) {
|
553
|
+
return fix;
|
554
|
+
}
|
555
|
+
|
556
|
+
const originalFix = (typeof fix === "function") ? fix : () => true;
|
557
|
+
|
558
|
+
return message => shouldMessageBeFixed(message, config, fixTypesSet) && originalFix(message);
|
559
|
+
}
|
560
|
+
|
540
561
|
//-----------------------------------------------------------------------------
|
541
562
|
// Main API
|
542
563
|
//-----------------------------------------------------------------------------
|
@@ -786,13 +807,15 @@ class FlatESLint {
|
|
786
807
|
*/
|
787
808
|
const results = await Promise.all(
|
788
809
|
|
789
|
-
filePaths.map(
|
810
|
+
filePaths.map(filePath => {
|
811
|
+
|
812
|
+
const config = configs.getConfig(filePath);
|
790
813
|
|
791
814
|
/*
|
792
|
-
* If a filename was entered that
|
793
|
-
*
|
815
|
+
* If a filename was entered that cannot be matched
|
816
|
+
* to a config, then notify the user.
|
794
817
|
*/
|
795
|
-
if (
|
818
|
+
if (!config) {
|
796
819
|
if (warnIgnored) {
|
797
820
|
return createIgnoreResult(filePath, cwd);
|
798
821
|
}
|
@@ -800,17 +823,6 @@ class FlatESLint {
|
|
800
823
|
return void 0;
|
801
824
|
}
|
802
825
|
|
803
|
-
const config = configs.getConfig(filePath);
|
804
|
-
|
805
|
-
/*
|
806
|
-
* Sometimes a file found through a glob pattern will
|
807
|
-
* be ignored. In this case, `config` will be undefined
|
808
|
-
* and we just silently ignore the file.
|
809
|
-
*/
|
810
|
-
if (!config) {
|
811
|
-
return void 0;
|
812
|
-
}
|
813
|
-
|
814
826
|
// Skip if there is cached result.
|
815
827
|
if (lintResultCache) {
|
816
828
|
const cachedResult =
|
@@ -832,16 +844,7 @@ class FlatESLint {
|
|
832
844
|
|
833
845
|
|
834
846
|
// set up fixer for fixTypes if necessary
|
835
|
-
|
836
|
-
|
837
|
-
if (fix && fixTypesSet) {
|
838
|
-
|
839
|
-
// save original value of options.fix in case it's a function
|
840
|
-
const originalFix = (typeof fix === "function")
|
841
|
-
? fix : () => true;
|
842
|
-
|
843
|
-
fixer = message => shouldMessageBeFixed(message, config, fixTypesSet) && originalFix(message);
|
844
|
-
}
|
847
|
+
const fixer = getFixerForFixTypes(fix, fixTypesSet, config);
|
845
848
|
|
846
849
|
return fs.readFile(filePath, "utf8")
|
847
850
|
.then(text => {
|
@@ -938,11 +941,16 @@ class FlatESLint {
|
|
938
941
|
allowInlineConfig,
|
939
942
|
cwd,
|
940
943
|
fix,
|
944
|
+
fixTypes,
|
941
945
|
warnIgnored: constructorWarnIgnored
|
942
946
|
} = eslintOptions;
|
943
947
|
const results = [];
|
944
948
|
const startTime = Date.now();
|
949
|
+
const fixTypesSet = fixTypes ? new Set(fixTypes) : null;
|
945
950
|
const resolvedFilename = path.resolve(cwd, filePath || "__placeholder__.js");
|
951
|
+
const config = configs.getConfig(resolvedFilename);
|
952
|
+
|
953
|
+
const fixer = getFixerForFixTypes(fix, fixTypesSet, config);
|
946
954
|
|
947
955
|
// Clear the last used config arrays.
|
948
956
|
if (resolvedFilename && await this.isPathIgnored(resolvedFilename)) {
|
@@ -959,7 +967,7 @@ class FlatESLint {
|
|
959
967
|
filePath: resolvedFilename.endsWith("__placeholder__.js") ? "<text>" : resolvedFilename,
|
960
968
|
configs,
|
961
969
|
cwd,
|
962
|
-
fix,
|
970
|
+
fix: fixer,
|
963
971
|
allowInlineConfig,
|
964
972
|
linter
|
965
973
|
}));
|
@@ -1112,11 +1120,20 @@ class FlatESLint {
|
|
1112
1120
|
}
|
1113
1121
|
}
|
1114
1122
|
|
1123
|
+
/**
|
1124
|
+
* The type of configuration used by this class.
|
1125
|
+
* @type {string}
|
1126
|
+
* @static
|
1127
|
+
*/
|
1128
|
+
FlatESLint.configType = "flat";
|
1129
|
+
|
1115
1130
|
/**
|
1116
1131
|
* Returns whether flat config should be used.
|
1132
|
+
* @param {Object} [options] The options for this function.
|
1133
|
+
* @param {string} [options.cwd] The current working directory.
|
1117
1134
|
* @returns {Promise<boolean>} Whether flat config should be used.
|
1118
1135
|
*/
|
1119
|
-
async function shouldUseFlatConfig() {
|
1136
|
+
async function shouldUseFlatConfig({ cwd = process.cwd() } = {}) {
|
1120
1137
|
switch (process.env.ESLINT_USE_FLAT_CONFIG) {
|
1121
1138
|
case "true":
|
1122
1139
|
return true;
|
@@ -1128,7 +1145,7 @@ async function shouldUseFlatConfig() {
|
|
1128
1145
|
* If neither explicitly enabled nor disabled, then use the presence
|
1129
1146
|
* of a flat config file to determine enablement.
|
1130
1147
|
*/
|
1131
|
-
return !!(await findFlatConfigFile(
|
1148
|
+
return !!(await findFlatConfigFile(cwd));
|
1132
1149
|
}
|
1133
1150
|
}
|
1134
1151
|
|
package/lib/linter/linter.js
CHANGED
@@ -733,7 +733,7 @@ function createLanguageOptions({ globals: configuredGlobals, parser, parserOptio
|
|
733
733
|
*/
|
734
734
|
function resolveGlobals(providedGlobals, enabledEnvironments) {
|
735
735
|
return Object.assign(
|
736
|
-
|
736
|
+
Object.create(null),
|
737
737
|
...enabledEnvironments.filter(env => env.globals).map(env => env.globals),
|
738
738
|
providedGlobals
|
739
739
|
);
|
package/lib/options.js
CHANGED
@@ -168,7 +168,7 @@ module.exports = function(usingFlatConfig) {
|
|
168
168
|
alias: "c",
|
169
169
|
type: "path::String",
|
170
170
|
description: usingFlatConfig
|
171
|
-
? "Use this configuration instead of eslint.config.js"
|
171
|
+
? "Use this configuration instead of eslint.config.js, eslint.config.mjs, or eslint.config.cjs"
|
172
172
|
: "Use this configuration, overriding .eslintrc.* config options if present"
|
173
173
|
},
|
174
174
|
envFlag,
|
@@ -13,6 +13,7 @@
|
|
13
13
|
const
|
14
14
|
assert = require("assert"),
|
15
15
|
util = require("util"),
|
16
|
+
path = require("path"),
|
16
17
|
equal = require("fast-deep-equal"),
|
17
18
|
Traverser = require("../shared/traverser"),
|
18
19
|
{ getRuleOptionsSchema } = require("../config/flat-config-helpers"),
|
@@ -592,7 +593,15 @@ class FlatRuleTester {
|
|
592
593
|
* @private
|
593
594
|
*/
|
594
595
|
function runRuleForItem(item) {
|
595
|
-
const
|
596
|
+
const flatConfigArrayOptions = {
|
597
|
+
baseConfig
|
598
|
+
};
|
599
|
+
|
600
|
+
if (item.filename) {
|
601
|
+
flatConfigArrayOptions.basePath = path.parse(item.filename).root;
|
602
|
+
}
|
603
|
+
|
604
|
+
const configs = new FlatConfigArray(testerConfig, flatConfigArrayOptions);
|
596
605
|
|
597
606
|
/*
|
598
607
|
* Modify the returned config so that the parser is wrapped to catch
|
@@ -934,7 +934,7 @@ class SourceCode extends TokenStore {
|
|
934
934
|
* https://github.com/eslint/eslint/issues/16302
|
935
935
|
*/
|
936
936
|
const configGlobals = Object.assign(
|
937
|
-
|
937
|
+
Object.create(null), // https://github.com/eslint/eslint/issues/18363
|
938
938
|
getGlobalsForEcmaVersion(languageOptions.ecmaVersion),
|
939
939
|
languageOptions.sourceType === "commonjs" ? globals.commonjs : void 0,
|
940
940
|
languageOptions.globals
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.57.1",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -24,7 +24,8 @@
|
|
24
24
|
"lint:fix:docs:js": "node Makefile.js lintDocsJS -- fix",
|
25
25
|
"release:generate:alpha": "node Makefile.js generatePrerelease -- alpha",
|
26
26
|
"release:generate:beta": "node Makefile.js generatePrerelease -- beta",
|
27
|
-
"release:generate:latest": "node Makefile.js generateRelease",
|
27
|
+
"release:generate:latest": "node Makefile.js generateRelease -- latest",
|
28
|
+
"release:generate:maintenance": "node Makefile.js generateRelease -- maintenance",
|
28
29
|
"release:generate:rc": "node Makefile.js generatePrerelease -- rc",
|
29
30
|
"release:publish": "node Makefile.js publishRelease",
|
30
31
|
"test": "node Makefile.js test",
|
@@ -65,8 +66,8 @@
|
|
65
66
|
"@eslint-community/eslint-utils": "^4.2.0",
|
66
67
|
"@eslint-community/regexpp": "^4.6.1",
|
67
68
|
"@eslint/eslintrc": "^2.1.4",
|
68
|
-
"@eslint/js": "8.
|
69
|
-
"@humanwhocodes/config-array": "^0.
|
69
|
+
"@eslint/js": "8.57.1",
|
70
|
+
"@humanwhocodes/config-array": "^0.13.0",
|
70
71
|
"@humanwhocodes/module-importer": "^1.0.1",
|
71
72
|
"@nodelib/fs.walk": "^1.2.8",
|
72
73
|
"@ungap/structured-clone": "^1.2.0",
|
@@ -104,6 +105,7 @@
|
|
104
105
|
"devDependencies": {
|
105
106
|
"@babel/core": "^7.4.3",
|
106
107
|
"@babel/preset-env": "^7.4.3",
|
108
|
+
"@sinonjs/fake-timers": "11.2.2",
|
107
109
|
"@wdio/browser-runner": "^8.14.6",
|
108
110
|
"@wdio/cli": "^8.14.6",
|
109
111
|
"@wdio/concise-reporter": "^8.14.0",
|
@@ -122,9 +124,9 @@
|
|
122
124
|
"eslint-plugin-eslint-plugin": "^5.2.1",
|
123
125
|
"eslint-plugin-internal-rules": "file:tools/internal-rules",
|
124
126
|
"eslint-plugin-jsdoc": "^46.2.5",
|
125
|
-
"eslint-plugin-n": "^16.
|
127
|
+
"eslint-plugin-n": "^16.6.0",
|
126
128
|
"eslint-plugin-unicorn": "^49.0.0",
|
127
|
-
"eslint-release": "^3.
|
129
|
+
"eslint-release": "^3.3.0",
|
128
130
|
"eslump": "^3.0.0",
|
129
131
|
"esprima": "^4.0.1",
|
130
132
|
"fast-glob": "^3.2.11",
|
@@ -159,7 +161,7 @@
|
|
159
161
|
"semver": "^7.5.3",
|
160
162
|
"shelljs": "^0.8.2",
|
161
163
|
"sinon": "^11.0.0",
|
162
|
-
"vite-plugin-commonjs": "
|
164
|
+
"vite-plugin-commonjs": "0.10.1",
|
163
165
|
"webdriverio": "^8.14.6",
|
164
166
|
"webpack": "^5.23.0",
|
165
167
|
"webpack-cli": "^4.5.0",
|