eslint 8.18.0 → 8.21.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 +3 -9
- package/lib/config/default-config.js +16 -7
- package/lib/config/flat-config-array.js +41 -2
- package/lib/config/flat-config-helpers.js +9 -1
- package/lib/eslint/eslint-helpers.js +621 -0
- package/lib/eslint/flat-eslint.js +1164 -0
- package/lib/eslint/index.js +3 -1
- package/lib/linter/linter.js +72 -4
- package/lib/rule-tester/flat-rule-tester.js +41 -38
- package/lib/rule-tester/rule-tester.js +42 -0
- package/lib/rules/accessor-pairs.js +1 -1
- package/lib/rules/array-bracket-newline.js +1 -1
- package/lib/rules/array-bracket-spacing.js +1 -1
- package/lib/rules/array-callback-return.js +1 -1
- package/lib/rules/array-element-newline.js +1 -1
- package/lib/rules/arrow-body-style.js +1 -1
- package/lib/rules/arrow-parens.js +1 -1
- package/lib/rules/arrow-spacing.js +1 -1
- package/lib/rules/block-scoped-var.js +1 -1
- package/lib/rules/block-spacing.js +1 -1
- package/lib/rules/brace-style.js +1 -1
- package/lib/rules/callback-return.js +1 -1
- package/lib/rules/camelcase.js +1 -1
- package/lib/rules/capitalized-comments.js +1 -1
- package/lib/rules/class-methods-use-this.js +1 -1
- package/lib/rules/comma-dangle.js +1 -1
- package/lib/rules/comma-spacing.js +36 -42
- package/lib/rules/comma-style.js +1 -1
- package/lib/rules/complexity.js +1 -1
- package/lib/rules/computed-property-spacing.js +1 -1
- package/lib/rules/consistent-return.js +1 -1
- package/lib/rules/consistent-this.js +1 -1
- package/lib/rules/constructor-super.js +1 -1
- package/lib/rules/curly.js +1 -1
- package/lib/rules/default-case-last.js +1 -1
- package/lib/rules/default-case.js +1 -1
- package/lib/rules/default-param-last.js +1 -1
- package/lib/rules/dot-location.js +1 -1
- package/lib/rules/dot-notation.js +1 -1
- package/lib/rules/eol-last.js +1 -1
- package/lib/rules/eqeqeq.js +1 -1
- package/lib/rules/for-direction.js +1 -1
- package/lib/rules/func-call-spacing.js +1 -1
- package/lib/rules/func-name-matching.js +1 -1
- package/lib/rules/func-names.js +1 -1
- package/lib/rules/func-style.js +1 -1
- package/lib/rules/function-call-argument-newline.js +1 -1
- package/lib/rules/function-paren-newline.js +1 -1
- package/lib/rules/generator-star-spacing.js +1 -1
- package/lib/rules/getter-return.js +1 -1
- package/lib/rules/global-require.js +1 -1
- package/lib/rules/grouped-accessor-pairs.js +1 -1
- package/lib/rules/guard-for-in.js +1 -1
- package/lib/rules/handle-callback-err.js +1 -1
- package/lib/rules/id-blacklist.js +1 -1
- package/lib/rules/id-denylist.js +1 -1
- package/lib/rules/id-length.js +1 -1
- package/lib/rules/id-match.js +1 -1
- package/lib/rules/implicit-arrow-linebreak.js +1 -1
- package/lib/rules/indent-legacy.js +1 -1
- package/lib/rules/indent.js +3 -3
- package/lib/rules/init-declarations.js +1 -1
- package/lib/rules/jsx-quotes.js +1 -1
- package/lib/rules/key-spacing.js +5 -2
- package/lib/rules/keyword-spacing.js +1 -1
- package/lib/rules/line-comment-position.js +1 -1
- package/lib/rules/linebreak-style.js +1 -1
- package/lib/rules/lines-around-comment.js +12 -5
- package/lib/rules/lines-around-directive.js +1 -1
- package/lib/rules/lines-between-class-members.js +1 -1
- package/lib/rules/max-classes-per-file.js +1 -1
- package/lib/rules/max-depth.js +1 -1
- package/lib/rules/max-len.js +1 -1
- package/lib/rules/max-lines-per-function.js +1 -1
- package/lib/rules/max-lines.js +1 -1
- package/lib/rules/max-nested-callbacks.js +1 -1
- package/lib/rules/max-params.js +1 -1
- package/lib/rules/max-statements-per-line.js +1 -1
- package/lib/rules/max-statements.js +1 -1
- package/lib/rules/multiline-comment-style.js +1 -1
- package/lib/rules/multiline-ternary.js +1 -1
- package/lib/rules/new-cap.js +1 -1
- package/lib/rules/new-parens.js +1 -1
- package/lib/rules/newline-after-var.js +1 -1
- package/lib/rules/newline-before-return.js +1 -1
- package/lib/rules/newline-per-chained-call.js +1 -1
- package/lib/rules/no-alert.js +1 -1
- package/lib/rules/no-array-constructor.js +1 -1
- package/lib/rules/no-async-promise-executor.js +1 -1
- package/lib/rules/no-await-in-loop.js +1 -1
- package/lib/rules/no-bitwise.js +1 -1
- package/lib/rules/no-buffer-constructor.js +1 -1
- package/lib/rules/no-caller.js +1 -1
- package/lib/rules/no-case-declarations.js +1 -1
- package/lib/rules/no-catch-shadow.js +1 -1
- package/lib/rules/no-class-assign.js +1 -1
- package/lib/rules/no-compare-neg-zero.js +1 -1
- package/lib/rules/no-cond-assign.js +1 -1
- package/lib/rules/no-confusing-arrow.js +1 -1
- package/lib/rules/no-console.js +1 -1
- package/lib/rules/no-const-assign.js +1 -1
- package/lib/rules/no-constant-binary-expression.js +1 -1
- package/lib/rules/no-constant-condition.js +1 -1
- package/lib/rules/no-constructor-return.js +1 -1
- package/lib/rules/no-continue.js +1 -1
- package/lib/rules/no-control-regex.js +1 -1
- package/lib/rules/no-debugger.js +1 -1
- package/lib/rules/no-delete-var.js +1 -1
- package/lib/rules/no-div-regex.js +1 -1
- package/lib/rules/no-dupe-args.js +1 -1
- package/lib/rules/no-dupe-class-members.js +1 -1
- package/lib/rules/no-dupe-else-if.js +1 -1
- package/lib/rules/no-dupe-keys.js +1 -1
- package/lib/rules/no-duplicate-case.js +1 -1
- package/lib/rules/no-duplicate-imports.js +1 -1
- package/lib/rules/no-else-return.js +1 -1
- package/lib/rules/no-empty-character-class.js +1 -1
- package/lib/rules/no-empty-function.js +1 -1
- package/lib/rules/no-empty-pattern.js +1 -1
- package/lib/rules/no-empty.js +1 -1
- package/lib/rules/no-eq-null.js +1 -1
- package/lib/rules/no-eval.js +1 -1
- package/lib/rules/no-ex-assign.js +1 -1
- package/lib/rules/no-extend-native.js +1 -1
- package/lib/rules/no-extra-bind.js +1 -1
- package/lib/rules/no-extra-boolean-cast.js +1 -1
- package/lib/rules/no-extra-label.js +1 -1
- package/lib/rules/no-extra-parens.js +1 -1
- package/lib/rules/no-extra-semi.js +1 -1
- package/lib/rules/no-fallthrough.js +1 -1
- package/lib/rules/no-floating-decimal.js +1 -1
- package/lib/rules/no-func-assign.js +1 -1
- package/lib/rules/no-global-assign.js +1 -1
- package/lib/rules/no-implicit-coercion.js +1 -1
- package/lib/rules/no-implicit-globals.js +1 -1
- package/lib/rules/no-implied-eval.js +1 -1
- package/lib/rules/no-import-assign.js +1 -1
- package/lib/rules/no-inline-comments.js +1 -1
- package/lib/rules/no-inner-declarations.js +1 -1
- package/lib/rules/no-invalid-regexp.js +1 -1
- package/lib/rules/no-invalid-this.js +1 -1
- package/lib/rules/no-irregular-whitespace.js +1 -1
- package/lib/rules/no-iterator.js +1 -1
- package/lib/rules/no-label-var.js +1 -1
- package/lib/rules/no-labels.js +1 -1
- package/lib/rules/no-lone-blocks.js +1 -1
- package/lib/rules/no-lonely-if.js +1 -1
- package/lib/rules/no-loop-func.js +1 -1
- package/lib/rules/no-loss-of-precision.js +1 -1
- package/lib/rules/no-magic-numbers.js +1 -1
- package/lib/rules/no-misleading-character-class.js +1 -1
- package/lib/rules/no-mixed-operators.js +1 -1
- package/lib/rules/no-mixed-requires.js +1 -1
- package/lib/rules/no-mixed-spaces-and-tabs.js +1 -1
- package/lib/rules/no-multi-assign.js +1 -1
- package/lib/rules/no-multi-spaces.js +1 -1
- package/lib/rules/no-multi-str.js +1 -1
- package/lib/rules/no-multiple-empty-lines.js +1 -1
- package/lib/rules/no-native-reassign.js +1 -1
- package/lib/rules/no-negated-condition.js +1 -1
- package/lib/rules/no-negated-in-lhs.js +1 -1
- package/lib/rules/no-nested-ternary.js +1 -1
- package/lib/rules/no-new-func.js +1 -1
- package/lib/rules/no-new-object.js +1 -1
- package/lib/rules/no-new-require.js +1 -1
- package/lib/rules/no-new-symbol.js +1 -1
- package/lib/rules/no-new-wrappers.js +1 -1
- package/lib/rules/no-new.js +1 -1
- package/lib/rules/no-nonoctal-decimal-escape.js +1 -1
- package/lib/rules/no-obj-calls.js +1 -1
- package/lib/rules/no-octal-escape.js +1 -1
- package/lib/rules/no-octal.js +1 -1
- package/lib/rules/no-param-reassign.js +1 -1
- package/lib/rules/no-path-concat.js +1 -1
- package/lib/rules/no-plusplus.js +1 -1
- package/lib/rules/no-process-env.js +1 -1
- package/lib/rules/no-process-exit.js +1 -1
- package/lib/rules/no-promise-executor-return.js +1 -1
- package/lib/rules/no-proto.js +1 -1
- package/lib/rules/no-prototype-builtins.js +1 -1
- package/lib/rules/no-redeclare.js +1 -1
- package/lib/rules/no-regex-spaces.js +1 -1
- package/lib/rules/no-restricted-exports.js +1 -1
- package/lib/rules/no-restricted-globals.js +1 -1
- package/lib/rules/no-restricted-imports.js +77 -12
- package/lib/rules/no-restricted-modules.js +1 -1
- package/lib/rules/no-restricted-properties.js +1 -1
- package/lib/rules/no-restricted-syntax.js +1 -1
- package/lib/rules/no-return-assign.js +1 -1
- package/lib/rules/no-return-await.js +1 -1
- package/lib/rules/no-script-url.js +1 -1
- package/lib/rules/no-self-assign.js +1 -1
- package/lib/rules/no-self-compare.js +1 -1
- package/lib/rules/no-sequences.js +1 -1
- package/lib/rules/no-setter-return.js +1 -1
- package/lib/rules/no-shadow-restricted-names.js +1 -1
- package/lib/rules/no-shadow.js +1 -1
- package/lib/rules/no-spaced-func.js +1 -1
- package/lib/rules/no-sparse-arrays.js +1 -1
- package/lib/rules/no-sync.js +1 -1
- package/lib/rules/no-tabs.js +1 -1
- package/lib/rules/no-template-curly-in-string.js +1 -1
- package/lib/rules/no-ternary.js +1 -1
- package/lib/rules/no-this-before-super.js +1 -1
- package/lib/rules/no-throw-literal.js +1 -1
- package/lib/rules/no-trailing-spaces.js +1 -1
- package/lib/rules/no-undef-init.js +1 -1
- package/lib/rules/no-undef.js +1 -1
- package/lib/rules/no-undefined.js +1 -1
- package/lib/rules/no-underscore-dangle.js +1 -1
- package/lib/rules/no-unexpected-multiline.js +1 -1
- package/lib/rules/no-unmodified-loop-condition.js +1 -1
- package/lib/rules/no-unneeded-ternary.js +1 -1
- package/lib/rules/no-unreachable-loop.js +1 -1
- package/lib/rules/no-unreachable.js +1 -1
- package/lib/rules/no-unsafe-finally.js +1 -1
- package/lib/rules/no-unsafe-negation.js +1 -1
- package/lib/rules/no-unsafe-optional-chaining.js +1 -1
- package/lib/rules/no-unused-expressions.js +1 -1
- package/lib/rules/no-unused-labels.js +1 -1
- package/lib/rules/no-unused-private-class-members.js +1 -1
- package/lib/rules/no-unused-vars.js +1 -1
- package/lib/rules/no-use-before-define.js +1 -1
- package/lib/rules/no-useless-backreference.js +1 -1
- package/lib/rules/no-useless-call.js +1 -1
- package/lib/rules/no-useless-catch.js +1 -1
- package/lib/rules/no-useless-computed-key.js +1 -1
- package/lib/rules/no-useless-concat.js +1 -1
- package/lib/rules/no-useless-constructor.js +1 -1
- package/lib/rules/no-useless-escape.js +1 -1
- package/lib/rules/no-useless-rename.js +1 -1
- package/lib/rules/no-useless-return.js +1 -1
- package/lib/rules/no-var.js +1 -1
- package/lib/rules/no-void.js +1 -1
- package/lib/rules/no-warning-comments.js +27 -41
- package/lib/rules/no-whitespace-before-property.js +1 -1
- package/lib/rules/no-with.js +1 -1
- package/lib/rules/nonblock-statement-body-position.js +1 -1
- package/lib/rules/object-curly-newline.js +1 -1
- package/lib/rules/object-curly-spacing.js +1 -1
- package/lib/rules/object-property-newline.js +1 -1
- package/lib/rules/object-shorthand.js +1 -1
- package/lib/rules/one-var-declaration-per-line.js +1 -1
- package/lib/rules/one-var.js +1 -1
- package/lib/rules/operator-assignment.js +1 -1
- package/lib/rules/operator-linebreak.js +1 -1
- package/lib/rules/padded-blocks.js +1 -1
- package/lib/rules/padding-line-between-statements.js +1 -1
- package/lib/rules/prefer-arrow-callback.js +1 -1
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/prefer-destructuring.js +1 -1
- package/lib/rules/prefer-exponentiation-operator.js +1 -1
- package/lib/rules/prefer-named-capture-group.js +1 -1
- package/lib/rules/prefer-numeric-literals.js +1 -1
- package/lib/rules/prefer-object-has-own.js +1 -1
- package/lib/rules/prefer-object-spread.js +1 -1
- package/lib/rules/prefer-promise-reject-errors.js +1 -1
- package/lib/rules/prefer-reflect.js +1 -1
- package/lib/rules/prefer-regex-literals.js +1 -1
- package/lib/rules/prefer-rest-params.js +1 -1
- package/lib/rules/prefer-spread.js +1 -1
- package/lib/rules/prefer-template.js +1 -1
- package/lib/rules/quote-props.js +1 -1
- package/lib/rules/quotes.js +1 -1
- package/lib/rules/radix.js +1 -1
- package/lib/rules/require-atomic-updates.js +1 -1
- package/lib/rules/require-await.js +1 -1
- package/lib/rules/require-jsdoc.js +1 -1
- package/lib/rules/require-unicode-regexp.js +1 -1
- package/lib/rules/require-yield.js +1 -1
- package/lib/rules/rest-spread-spacing.js +1 -1
- package/lib/rules/semi-spacing.js +1 -1
- package/lib/rules/semi-style.js +1 -1
- package/lib/rules/semi.js +1 -1
- package/lib/rules/sort-imports.js +1 -1
- package/lib/rules/sort-keys.js +44 -1
- package/lib/rules/sort-vars.js +1 -1
- package/lib/rules/space-before-blocks.js +1 -1
- package/lib/rules/space-before-function-paren.js +1 -1
- package/lib/rules/space-in-parens.js +1 -1
- package/lib/rules/space-infix-ops.js +1 -1
- package/lib/rules/space-unary-ops.js +1 -1
- package/lib/rules/spaced-comment.js +1 -1
- package/lib/rules/strict.js +1 -1
- package/lib/rules/switch-colon-spacing.js +1 -1
- package/lib/rules/symbol-description.js +1 -1
- package/lib/rules/template-curly-spacing.js +1 -1
- package/lib/rules/template-tag-spacing.js +1 -1
- package/lib/rules/unicode-bom.js +1 -1
- package/lib/rules/use-isnan.js +1 -1
- package/lib/rules/valid-jsdoc.js +1 -1
- package/lib/rules/valid-typeof.js +1 -1
- package/lib/rules/vars-on-top.js +1 -1
- package/lib/rules/wrap-iife.js +1 -1
- package/lib/rules/wrap-regex.js +1 -1
- package/lib/rules/yield-star-spacing.js +1 -1
- package/lib/rules/yoda.js +1 -1
- package/lib/unsupported-api.js +4 -0
- package/package.json +13 -10
@@ -0,0 +1,621 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Helper functions for ESLint class
|
3
|
+
* @author Nicholas C. Zakas
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//-----------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//-----------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const path = require("path");
|
13
|
+
const fs = require("fs");
|
14
|
+
const fsp = fs.promises;
|
15
|
+
const isGlob = require("is-glob");
|
16
|
+
const globby = require("globby");
|
17
|
+
const hash = require("../cli-engine/hash");
|
18
|
+
|
19
|
+
//-----------------------------------------------------------------------------
|
20
|
+
// Errors
|
21
|
+
//-----------------------------------------------------------------------------
|
22
|
+
|
23
|
+
/**
|
24
|
+
* The error type when no files match a glob.
|
25
|
+
*/
|
26
|
+
class NoFilesFoundError extends Error {
|
27
|
+
|
28
|
+
/**
|
29
|
+
* @param {string} pattern The glob pattern which was not found.
|
30
|
+
* @param {boolean} globEnabled If `false` then the pattern was a glob pattern, but glob was disabled.
|
31
|
+
*/
|
32
|
+
constructor(pattern, globEnabled) {
|
33
|
+
super(`No files matching '${pattern}' were found${!globEnabled ? " (glob was disabled)" : ""}.`);
|
34
|
+
this.messageTemplate = "file-not-found";
|
35
|
+
this.messageData = { pattern, globDisabled: !globEnabled };
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* The error type when there are files matched by a glob, but all of them have been ignored.
|
41
|
+
*/
|
42
|
+
class AllFilesIgnoredError extends Error {
|
43
|
+
|
44
|
+
/**
|
45
|
+
* @param {string} pattern The glob pattern which was not found.
|
46
|
+
*/
|
47
|
+
constructor(pattern) {
|
48
|
+
super(`All files matched by '${pattern}' are ignored.`);
|
49
|
+
this.messageTemplate = "all-files-ignored";
|
50
|
+
this.messageData = { pattern };
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
//-----------------------------------------------------------------------------
|
56
|
+
// General Helpers
|
57
|
+
//-----------------------------------------------------------------------------
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Check if a given value is a non-empty string or not.
|
61
|
+
* @param {any} x The value to check.
|
62
|
+
* @returns {boolean} `true` if `x` is a non-empty string.
|
63
|
+
*/
|
64
|
+
function isNonEmptyString(x) {
|
65
|
+
return typeof x === "string" && x.trim() !== "";
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Check if a given value is an array of non-empty stringss or not.
|
70
|
+
* @param {any} x The value to check.
|
71
|
+
* @returns {boolean} `true` if `x` is an array of non-empty stringss.
|
72
|
+
*/
|
73
|
+
function isArrayOfNonEmptyString(x) {
|
74
|
+
return Array.isArray(x) && x.every(isNonEmptyString);
|
75
|
+
}
|
76
|
+
|
77
|
+
//-----------------------------------------------------------------------------
|
78
|
+
// File-related Helpers
|
79
|
+
//-----------------------------------------------------------------------------
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Normalizes slashes in a file pattern to posix-style.
|
83
|
+
* @param {string} pattern The pattern to replace slashes in.
|
84
|
+
* @returns {string} The pattern with slashes normalized.
|
85
|
+
*/
|
86
|
+
function normalizeToPosix(pattern) {
|
87
|
+
return pattern.replace(/\\/gu, "/");
|
88
|
+
}
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Check if a string is a glob pattern or not.
|
92
|
+
* @param {string} pattern A glob pattern.
|
93
|
+
* @returns {boolean} `true` if the string is a glob pattern.
|
94
|
+
*/
|
95
|
+
function isGlobPattern(pattern) {
|
96
|
+
return isGlob(path.sep === "\\" ? normalizeToPosix(pattern) : pattern);
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Finds all files matching the options specified.
|
101
|
+
* @param {Object} args The arguments objects.
|
102
|
+
* @param {Array<string>} args.patterns An array of glob patterns.
|
103
|
+
* @param {boolean} args.globInputPaths true to interpret glob patterns,
|
104
|
+
* false to not interpret glob patterns.
|
105
|
+
* @param {string} args.cwd The current working directory to find from.
|
106
|
+
* @param {FlatConfigArray} args.configs The configs for the current run.
|
107
|
+
* @returns {Promise<Array<string>>} The fully resolved file paths.
|
108
|
+
* @throws {AllFilesIgnoredError} If there are no results due to an ignore pattern.
|
109
|
+
* @throws {NoFilesFoundError} If no files matched the given patterns.
|
110
|
+
*/
|
111
|
+
async function findFiles({
|
112
|
+
patterns,
|
113
|
+
globInputPaths,
|
114
|
+
cwd,
|
115
|
+
configs
|
116
|
+
}) {
|
117
|
+
|
118
|
+
const results = [];
|
119
|
+
const globbyPatterns = [];
|
120
|
+
const missingPatterns = [];
|
121
|
+
|
122
|
+
// check to see if we have explicit files and directories
|
123
|
+
const filePaths = patterns.map(filePath => path.resolve(cwd, filePath));
|
124
|
+
const stats = await Promise.all(
|
125
|
+
filePaths.map(
|
126
|
+
filePath => fsp.stat(filePath).catch(() => {})
|
127
|
+
)
|
128
|
+
);
|
129
|
+
|
130
|
+
stats.forEach((stat, index) => {
|
131
|
+
|
132
|
+
const filePath = filePaths[index];
|
133
|
+
const pattern = patterns[index];
|
134
|
+
|
135
|
+
if (stat) {
|
136
|
+
|
137
|
+
// files are added directly to the list
|
138
|
+
if (stat.isFile()) {
|
139
|
+
results.push({
|
140
|
+
filePath,
|
141
|
+
ignored: configs.isIgnored(filePath)
|
142
|
+
});
|
143
|
+
}
|
144
|
+
|
145
|
+
// directories need extensions attached
|
146
|
+
if (stat.isDirectory()) {
|
147
|
+
|
148
|
+
// filePatterns are all relative to cwd
|
149
|
+
const filePatterns = configs.files
|
150
|
+
.filter(filePattern => {
|
151
|
+
|
152
|
+
// can only do this for strings, not functions
|
153
|
+
if (typeof filePattern !== "string") {
|
154
|
+
return false;
|
155
|
+
}
|
156
|
+
|
157
|
+
// patterns ending with * are not used for file search
|
158
|
+
if (filePattern.endsWith("*")) {
|
159
|
+
return false;
|
160
|
+
}
|
161
|
+
|
162
|
+
// not sure how to handle negated patterns yet
|
163
|
+
if (filePattern.startsWith("!")) {
|
164
|
+
return false;
|
165
|
+
}
|
166
|
+
|
167
|
+
// check if the pattern would be inside the cwd or not
|
168
|
+
const fullFilePattern = path.join(cwd, filePattern);
|
169
|
+
const relativeFilePattern = path.relative(configs.basePath, fullFilePattern);
|
170
|
+
|
171
|
+
return !relativeFilePattern.startsWith("..");
|
172
|
+
})
|
173
|
+
.map(filePattern => {
|
174
|
+
if (filePattern.startsWith("**")) {
|
175
|
+
return path.join(pattern, filePattern);
|
176
|
+
}
|
177
|
+
|
178
|
+
// adjust the path to be relative to the cwd
|
179
|
+
return path.relative(
|
180
|
+
cwd,
|
181
|
+
path.join(configs.basePath, filePattern)
|
182
|
+
);
|
183
|
+
})
|
184
|
+
.map(normalizeToPosix);
|
185
|
+
|
186
|
+
if (filePatterns.length) {
|
187
|
+
globbyPatterns.push(...filePatterns);
|
188
|
+
}
|
189
|
+
|
190
|
+
}
|
191
|
+
|
192
|
+
return;
|
193
|
+
}
|
194
|
+
|
195
|
+
// save patterns for later use based on whether globs are enabled
|
196
|
+
if (globInputPaths && isGlobPattern(filePath)) {
|
197
|
+
globbyPatterns.push(pattern);
|
198
|
+
} else {
|
199
|
+
missingPatterns.push(pattern);
|
200
|
+
}
|
201
|
+
});
|
202
|
+
|
203
|
+
// note: globbyPatterns can be an empty array
|
204
|
+
const globbyResults = (await globby(globbyPatterns, {
|
205
|
+
cwd,
|
206
|
+
absolute: true,
|
207
|
+
ignore: configs.ignores.filter(matcher => typeof matcher === "string")
|
208
|
+
}));
|
209
|
+
|
210
|
+
// if there are no results, tell the user why
|
211
|
+
if (!results.length && !globbyResults.length) {
|
212
|
+
|
213
|
+
// try globby without ignoring anything
|
214
|
+
/* eslint-disable no-unreachable-loop -- We want to exit early. */
|
215
|
+
for (const globbyPattern of globbyPatterns) {
|
216
|
+
|
217
|
+
/* eslint-disable-next-line no-unused-vars -- Want to exit early. */
|
218
|
+
for await (const filePath of globby.stream(globbyPattern, { cwd, absolute: true })) {
|
219
|
+
|
220
|
+
// files were found but ignored
|
221
|
+
throw new AllFilesIgnoredError(globbyPattern);
|
222
|
+
}
|
223
|
+
|
224
|
+
// no files were found
|
225
|
+
throw new NoFilesFoundError(globbyPattern, globInputPaths);
|
226
|
+
}
|
227
|
+
/* eslint-enable no-unreachable-loop -- Go back to normal. */
|
228
|
+
|
229
|
+
}
|
230
|
+
|
231
|
+
// there were patterns that didn't match anything, tell the user
|
232
|
+
if (missingPatterns.length) {
|
233
|
+
throw new NoFilesFoundError(missingPatterns[0], globInputPaths);
|
234
|
+
}
|
235
|
+
|
236
|
+
|
237
|
+
return [
|
238
|
+
...results,
|
239
|
+
...globbyResults.map(filePath => ({
|
240
|
+
filePath: path.resolve(filePath),
|
241
|
+
ignored: false
|
242
|
+
}))
|
243
|
+
];
|
244
|
+
}
|
245
|
+
|
246
|
+
|
247
|
+
/**
|
248
|
+
* Checks whether a file exists at the given location
|
249
|
+
* @param {string} resolvedPath A path from the CWD
|
250
|
+
* @throws {Error} As thrown by `fs.statSync` or `fs.isFile`.
|
251
|
+
* @returns {boolean} `true` if a file exists
|
252
|
+
*/
|
253
|
+
function fileExists(resolvedPath) {
|
254
|
+
try {
|
255
|
+
return fs.statSync(resolvedPath).isFile();
|
256
|
+
} catch (error) {
|
257
|
+
if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
258
|
+
return false;
|
259
|
+
}
|
260
|
+
throw error;
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
/**
|
265
|
+
* Checks whether a directory exists at the given location
|
266
|
+
* @param {string} resolvedPath A path from the CWD
|
267
|
+
* @throws {Error} As thrown by `fs.statSync` or `fs.isDirectory`.
|
268
|
+
* @returns {boolean} `true` if a directory exists
|
269
|
+
*/
|
270
|
+
function directoryExists(resolvedPath) {
|
271
|
+
try {
|
272
|
+
return fs.statSync(resolvedPath).isDirectory();
|
273
|
+
} catch (error) {
|
274
|
+
if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
275
|
+
return false;
|
276
|
+
}
|
277
|
+
throw error;
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
//-----------------------------------------------------------------------------
|
282
|
+
// Results-related Helpers
|
283
|
+
//-----------------------------------------------------------------------------
|
284
|
+
|
285
|
+
/**
|
286
|
+
* Checks if the given message is an error message.
|
287
|
+
* @param {LintMessage} message The message to check.
|
288
|
+
* @returns {boolean} Whether or not the message is an error message.
|
289
|
+
* @private
|
290
|
+
*/
|
291
|
+
function isErrorMessage(message) {
|
292
|
+
return message.severity === 2;
|
293
|
+
}
|
294
|
+
|
295
|
+
/**
|
296
|
+
* Returns result with warning by ignore settings
|
297
|
+
* @param {string} filePath File path of checked code
|
298
|
+
* @param {string} baseDir Absolute path of base directory
|
299
|
+
* @returns {LintResult} Result with single warning
|
300
|
+
* @private
|
301
|
+
*/
|
302
|
+
function createIgnoreResult(filePath, baseDir) {
|
303
|
+
let message;
|
304
|
+
const isHidden = filePath.split(path.sep)
|
305
|
+
.find(segment => /^\./u.test(segment));
|
306
|
+
const isInNodeModules = baseDir && path.relative(baseDir, filePath).startsWith("node_modules");
|
307
|
+
|
308
|
+
if (isHidden) {
|
309
|
+
message = "File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern '!<relative/path/to/filename>'\") to override.";
|
310
|
+
} else if (isInNodeModules) {
|
311
|
+
message = "File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override.";
|
312
|
+
} else {
|
313
|
+
message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override.";
|
314
|
+
}
|
315
|
+
|
316
|
+
return {
|
317
|
+
filePath: path.resolve(filePath),
|
318
|
+
messages: [
|
319
|
+
{
|
320
|
+
fatal: false,
|
321
|
+
severity: 1,
|
322
|
+
message
|
323
|
+
}
|
324
|
+
],
|
325
|
+
errorCount: 0,
|
326
|
+
warningCount: 1,
|
327
|
+
fatalErrorCount: 0,
|
328
|
+
fixableErrorCount: 0,
|
329
|
+
fixableWarningCount: 0
|
330
|
+
};
|
331
|
+
}
|
332
|
+
|
333
|
+
//-----------------------------------------------------------------------------
|
334
|
+
// Options-related Helpers
|
335
|
+
//-----------------------------------------------------------------------------
|
336
|
+
|
337
|
+
|
338
|
+
/**
|
339
|
+
* Check if a given value is a valid fix type or not.
|
340
|
+
* @param {any} x The value to check.
|
341
|
+
* @returns {boolean} `true` if `x` is valid fix type.
|
342
|
+
*/
|
343
|
+
function isFixType(x) {
|
344
|
+
return x === "directive" || x === "problem" || x === "suggestion" || x === "layout";
|
345
|
+
}
|
346
|
+
|
347
|
+
/**
|
348
|
+
* Check if a given value is an array of fix types or not.
|
349
|
+
* @param {any} x The value to check.
|
350
|
+
* @returns {boolean} `true` if `x` is an array of fix types.
|
351
|
+
*/
|
352
|
+
function isFixTypeArray(x) {
|
353
|
+
return Array.isArray(x) && x.every(isFixType);
|
354
|
+
}
|
355
|
+
|
356
|
+
/**
|
357
|
+
* The error for invalid options.
|
358
|
+
*/
|
359
|
+
class ESLintInvalidOptionsError extends Error {
|
360
|
+
constructor(messages) {
|
361
|
+
super(`Invalid Options:\n- ${messages.join("\n- ")}`);
|
362
|
+
this.code = "ESLINT_INVALID_OPTIONS";
|
363
|
+
Error.captureStackTrace(this, ESLintInvalidOptionsError);
|
364
|
+
}
|
365
|
+
}
|
366
|
+
|
367
|
+
/**
|
368
|
+
* Validates and normalizes options for the wrapped CLIEngine instance.
|
369
|
+
* @param {FlatESLintOptions} options The options to process.
|
370
|
+
* @throws {ESLintInvalidOptionsError} If of any of a variety of type errors.
|
371
|
+
* @returns {FlatESLintOptions} The normalized options.
|
372
|
+
*/
|
373
|
+
function processOptions({
|
374
|
+
allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored.
|
375
|
+
baseConfig = null,
|
376
|
+
cache = false,
|
377
|
+
cacheLocation = ".eslintcache",
|
378
|
+
cacheStrategy = "metadata",
|
379
|
+
cwd = process.cwd(),
|
380
|
+
errorOnUnmatchedPattern = true,
|
381
|
+
extensions = null, // ← should be null by default because if it's an array then it suppresses RFC20 feature.
|
382
|
+
fix = false,
|
383
|
+
fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property.
|
384
|
+
globInputPaths = true,
|
385
|
+
ignore = true,
|
386
|
+
ignorePath = null, // ← should be null by default because if it's a string then it may throw ENOENT.
|
387
|
+
ignorePatterns = null,
|
388
|
+
overrideConfig = null,
|
389
|
+
overrideConfigFile = null,
|
390
|
+
plugins = {},
|
391
|
+
reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that.
|
392
|
+
...unknownOptions
|
393
|
+
}) {
|
394
|
+
const errors = [];
|
395
|
+
const unknownOptionKeys = Object.keys(unknownOptions);
|
396
|
+
|
397
|
+
if (unknownOptionKeys.length >= 1) {
|
398
|
+
errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`);
|
399
|
+
if (unknownOptionKeys.includes("cacheFile")) {
|
400
|
+
errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead.");
|
401
|
+
}
|
402
|
+
if (unknownOptionKeys.includes("configFile")) {
|
403
|
+
errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead.");
|
404
|
+
}
|
405
|
+
if (unknownOptionKeys.includes("envs")) {
|
406
|
+
errors.push("'envs' has been removed.");
|
407
|
+
}
|
408
|
+
if (unknownOptionKeys.includes("resolvePluginsRelativeTo")) {
|
409
|
+
errors.push("'resolvePluginsRelativeTo' has been removed.");
|
410
|
+
}
|
411
|
+
if (unknownOptionKeys.includes("globals")) {
|
412
|
+
errors.push("'globals' has been removed. Please use the 'overrideConfig.languageOptions.globals' option instead.");
|
413
|
+
}
|
414
|
+
if (unknownOptionKeys.includes("ignorePattern")) {
|
415
|
+
errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead.");
|
416
|
+
}
|
417
|
+
if (unknownOptionKeys.includes("parser")) {
|
418
|
+
errors.push("'parser' has been removed. Please use the 'overrideConfig.languageOptions.parser' option instead.");
|
419
|
+
}
|
420
|
+
if (unknownOptionKeys.includes("parserOptions")) {
|
421
|
+
errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.languageOptions.parserOptions' option instead.");
|
422
|
+
}
|
423
|
+
if (unknownOptionKeys.includes("rules")) {
|
424
|
+
errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead.");
|
425
|
+
}
|
426
|
+
if (unknownOptionKeys.includes("rulePaths")) {
|
427
|
+
errors.push("'rulePaths' has been removed. Please define your rules using plugins.");
|
428
|
+
}
|
429
|
+
}
|
430
|
+
if (typeof allowInlineConfig !== "boolean") {
|
431
|
+
errors.push("'allowInlineConfig' must be a boolean.");
|
432
|
+
}
|
433
|
+
if (typeof baseConfig !== "object") {
|
434
|
+
errors.push("'baseConfig' must be an object or null.");
|
435
|
+
}
|
436
|
+
if (typeof cache !== "boolean") {
|
437
|
+
errors.push("'cache' must be a boolean.");
|
438
|
+
}
|
439
|
+
if (cache) {
|
440
|
+
errors.push("'cache' option is not yet supported.");
|
441
|
+
}
|
442
|
+
if (!isNonEmptyString(cacheLocation)) {
|
443
|
+
errors.push("'cacheLocation' must be a non-empty string.");
|
444
|
+
}
|
445
|
+
if (
|
446
|
+
cacheStrategy !== "metadata" &&
|
447
|
+
cacheStrategy !== "content"
|
448
|
+
) {
|
449
|
+
errors.push("'cacheStrategy' must be any of \"metadata\", \"content\".");
|
450
|
+
}
|
451
|
+
if (!isNonEmptyString(cwd) || !path.isAbsolute(cwd)) {
|
452
|
+
errors.push("'cwd' must be an absolute path.");
|
453
|
+
}
|
454
|
+
if (typeof errorOnUnmatchedPattern !== "boolean") {
|
455
|
+
errors.push("'errorOnUnmatchedPattern' must be a boolean.");
|
456
|
+
}
|
457
|
+
if (!isArrayOfNonEmptyString(extensions) && extensions !== null) {
|
458
|
+
errors.push("'extensions' must be an array of non-empty strings or null.");
|
459
|
+
}
|
460
|
+
if (typeof fix !== "boolean" && typeof fix !== "function") {
|
461
|
+
errors.push("'fix' must be a boolean or a function.");
|
462
|
+
}
|
463
|
+
if (fixTypes !== null && !isFixTypeArray(fixTypes)) {
|
464
|
+
errors.push("'fixTypes' must be an array of any of \"directive\", \"problem\", \"suggestion\", and \"layout\".");
|
465
|
+
}
|
466
|
+
if (typeof globInputPaths !== "boolean") {
|
467
|
+
errors.push("'globInputPaths' must be a boolean.");
|
468
|
+
}
|
469
|
+
if (typeof ignore !== "boolean") {
|
470
|
+
errors.push("'ignore' must be a boolean.");
|
471
|
+
}
|
472
|
+
if (!isNonEmptyString(ignorePath) && ignorePath !== null) {
|
473
|
+
errors.push("'ignorePath' must be a non-empty string or null.");
|
474
|
+
}
|
475
|
+
if (typeof overrideConfig !== "object") {
|
476
|
+
errors.push("'overrideConfig' must be an object or null.");
|
477
|
+
}
|
478
|
+
if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null && overrideConfigFile !== true) {
|
479
|
+
errors.push("'overrideConfigFile' must be a non-empty string, null, or true.");
|
480
|
+
}
|
481
|
+
if (typeof plugins !== "object") {
|
482
|
+
errors.push("'plugins' must be an object or null.");
|
483
|
+
} else if (plugins !== null && Object.keys(plugins).includes("")) {
|
484
|
+
errors.push("'plugins' must not include an empty string.");
|
485
|
+
}
|
486
|
+
if (Array.isArray(plugins)) {
|
487
|
+
errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead.");
|
488
|
+
}
|
489
|
+
if (
|
490
|
+
reportUnusedDisableDirectives !== "error" &&
|
491
|
+
reportUnusedDisableDirectives !== "warn" &&
|
492
|
+
reportUnusedDisableDirectives !== "off" &&
|
493
|
+
reportUnusedDisableDirectives !== null
|
494
|
+
) {
|
495
|
+
errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null.");
|
496
|
+
}
|
497
|
+
if (errors.length > 0) {
|
498
|
+
throw new ESLintInvalidOptionsError(errors);
|
499
|
+
}
|
500
|
+
|
501
|
+
return {
|
502
|
+
allowInlineConfig,
|
503
|
+
baseConfig,
|
504
|
+
cache,
|
505
|
+
cacheLocation,
|
506
|
+
cacheStrategy,
|
507
|
+
|
508
|
+
// when overrideConfigFile is true that means don't do config file lookup
|
509
|
+
configFile: overrideConfigFile === true ? false : overrideConfigFile,
|
510
|
+
overrideConfig,
|
511
|
+
cwd,
|
512
|
+
errorOnUnmatchedPattern,
|
513
|
+
extensions,
|
514
|
+
fix,
|
515
|
+
fixTypes,
|
516
|
+
globInputPaths,
|
517
|
+
ignore,
|
518
|
+
ignorePath,
|
519
|
+
ignorePatterns,
|
520
|
+
reportUnusedDisableDirectives
|
521
|
+
};
|
522
|
+
}
|
523
|
+
|
524
|
+
|
525
|
+
//-----------------------------------------------------------------------------
|
526
|
+
// Cache-related helpers
|
527
|
+
//-----------------------------------------------------------------------------
|
528
|
+
|
529
|
+
/**
|
530
|
+
* return the cacheFile to be used by eslint, based on whether the provided parameter is
|
531
|
+
* a directory or looks like a directory (ends in `path.sep`), in which case the file
|
532
|
+
* name will be the `cacheFile/.cache_hashOfCWD`
|
533
|
+
*
|
534
|
+
* if cacheFile points to a file or looks like a file then in will just use that file
|
535
|
+
* @param {string} cacheFile The name of file to be used to store the cache
|
536
|
+
* @param {string} cwd Current working directory
|
537
|
+
* @returns {string} the resolved path to the cache file
|
538
|
+
*/
|
539
|
+
function getCacheFile(cacheFile, cwd) {
|
540
|
+
|
541
|
+
/*
|
542
|
+
* make sure the path separators are normalized for the environment/os
|
543
|
+
* keeping the trailing path separator if present
|
544
|
+
*/
|
545
|
+
const normalizedCacheFile = path.normalize(cacheFile);
|
546
|
+
|
547
|
+
const resolvedCacheFile = path.resolve(cwd, normalizedCacheFile);
|
548
|
+
const looksLikeADirectory = normalizedCacheFile.slice(-1) === path.sep;
|
549
|
+
|
550
|
+
/**
|
551
|
+
* return the name for the cache file in case the provided parameter is a directory
|
552
|
+
* @returns {string} the resolved path to the cacheFile
|
553
|
+
*/
|
554
|
+
function getCacheFileForDirectory() {
|
555
|
+
return path.join(resolvedCacheFile, `.cache_${hash(cwd)}`);
|
556
|
+
}
|
557
|
+
|
558
|
+
let fileStats;
|
559
|
+
|
560
|
+
try {
|
561
|
+
fileStats = fs.lstatSync(resolvedCacheFile);
|
562
|
+
} catch {
|
563
|
+
fileStats = null;
|
564
|
+
}
|
565
|
+
|
566
|
+
|
567
|
+
/*
|
568
|
+
* in case the file exists we need to verify if the provided path
|
569
|
+
* is a directory or a file. If it is a directory we want to create a file
|
570
|
+
* inside that directory
|
571
|
+
*/
|
572
|
+
if (fileStats) {
|
573
|
+
|
574
|
+
/*
|
575
|
+
* is a directory or is a file, but the original file the user provided
|
576
|
+
* looks like a directory but `path.resolve` removed the `last path.sep`
|
577
|
+
* so we need to still treat this like a directory
|
578
|
+
*/
|
579
|
+
if (fileStats.isDirectory() || looksLikeADirectory) {
|
580
|
+
return getCacheFileForDirectory();
|
581
|
+
}
|
582
|
+
|
583
|
+
// is file so just use that file
|
584
|
+
return resolvedCacheFile;
|
585
|
+
}
|
586
|
+
|
587
|
+
/*
|
588
|
+
* here we known the file or directory doesn't exist,
|
589
|
+
* so we will try to infer if its a directory if it looks like a directory
|
590
|
+
* for the current operating system.
|
591
|
+
*/
|
592
|
+
|
593
|
+
// if the last character passed is a path separator we assume is a directory
|
594
|
+
if (looksLikeADirectory) {
|
595
|
+
return getCacheFileForDirectory();
|
596
|
+
}
|
597
|
+
|
598
|
+
return resolvedCacheFile;
|
599
|
+
}
|
600
|
+
|
601
|
+
|
602
|
+
//-----------------------------------------------------------------------------
|
603
|
+
// Exports
|
604
|
+
//-----------------------------------------------------------------------------
|
605
|
+
|
606
|
+
module.exports = {
|
607
|
+
isGlobPattern,
|
608
|
+
directoryExists,
|
609
|
+
fileExists,
|
610
|
+
findFiles,
|
611
|
+
|
612
|
+
isNonEmptyString,
|
613
|
+
isArrayOfNonEmptyString,
|
614
|
+
|
615
|
+
createIgnoreResult,
|
616
|
+
isErrorMessage,
|
617
|
+
|
618
|
+
processOptions,
|
619
|
+
|
620
|
+
getCacheFile
|
621
|
+
};
|