eslint 8.19.0 → 8.22.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 CHANGED
@@ -45,21 +45,15 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
45
45
 
46
46
  Prerequisites: [Node.js](https://nodejs.org/) (`^12.22.0`, `^14.17.0`, or `>=16.0.0`) built with SSL support. (If you are using an official Node.js distribution, SSL is always built in.)
47
47
 
48
- You can install ESLint using npm:
48
+ You can install and configure ESLint using this command:
49
49
 
50
- ```sh
51
- npm install eslint --save-dev
52
- ```
53
-
54
- You should then set up a configuration file:
55
-
56
- ```sh
50
+ ```shell
57
51
  npm init @eslint/config
58
52
  ```
59
53
 
60
54
  After that, you can run ESLint on any file or directory like this:
61
55
 
62
- ```sh
56
+ ```shell
63
57
  ./node_modules/.bin/eslint yourfile.js
64
58
  ```
65
59
 
@@ -15,7 +15,6 @@ const Rules = require("../rules");
15
15
  // Helpers
16
16
  //-----------------------------------------------------------------------------
17
17
 
18
-
19
18
  exports.defaultConfig = [
20
19
  {
21
20
  plugins: {
@@ -41,21 +40,31 @@ exports.defaultConfig = [
41
40
  })
42
41
  }
43
42
  },
44
- ignores: [
45
- "**/node_modules/**",
46
- ".git/**"
47
- ],
48
43
  languageOptions: {
49
- ecmaVersion: "latest",
50
44
  sourceType: "module",
45
+ ecmaVersion: "latest",
51
46
  parser: "@/espree",
52
47
  parserOptions: {}
53
48
  }
54
49
  },
50
+
51
+ // default ignores are listed here
52
+ {
53
+ ignores: [
54
+ "**/node_modules/**",
55
+ ".git/**"
56
+ ]
57
+ },
58
+
59
+ // intentionally empty config to ensure these files are globbed by default
60
+ {
61
+ files: ["**/*.js", "**/*.mjs"]
62
+ },
55
63
  {
56
64
  files: ["**/*.cjs"],
57
65
  languageOptions: {
58
- sourceType: "commonjs"
66
+ sourceType: "commonjs",
67
+ ecmaVersion: "latest"
59
68
  }
60
69
  }
61
70
  ];
@@ -36,6 +36,8 @@ function splitPluginIdentifier(identifier) {
36
36
  };
37
37
  }
38
38
 
39
+ const originalBaseConfig = Symbol("originalBaseConfig");
40
+
39
41
  //-----------------------------------------------------------------------------
40
42
  // Exports
41
43
  //-----------------------------------------------------------------------------
@@ -48,10 +50,14 @@ class FlatConfigArray extends ConfigArray {
48
50
  /**
49
51
  * Creates a new instance.
50
52
  * @param {*[]} configs An array of configuration information.
51
- * @param {{basePath: string, baseConfig: FlatConfig}} options The options
53
+ * @param {{basePath: string, shouldIgnore: boolean, baseConfig: FlatConfig}} options The options
52
54
  * to use for the config array instance.
53
55
  */
54
- constructor(configs, { basePath, baseConfig = defaultConfig } = {}) {
56
+ constructor(configs, {
57
+ basePath,
58
+ shouldIgnore = true,
59
+ baseConfig = defaultConfig
60
+ } = {}) {
55
61
  super(configs, {
56
62
  basePath,
57
63
  schema: flatConfigSchema
@@ -62,6 +68,22 @@ class FlatConfigArray extends ConfigArray {
62
68
  } else {
63
69
  this.unshift(baseConfig);
64
70
  }
71
+
72
+ /**
73
+ * The baes config used to build the config array.
74
+ * @type {Array<FlatConfig>}
75
+ */
76
+ this[originalBaseConfig] = baseConfig;
77
+ Object.defineProperty(this, originalBaseConfig, { writable: false });
78
+
79
+ /**
80
+ * Determines if `ignores` fields should be honored.
81
+ * If true, then all `ignores` fields are honored.
82
+ * if false, then only `ignores` fields in the baseConfig are honored.
83
+ * @type {boolean}
84
+ */
85
+ this.shouldIgnore = shouldIgnore;
86
+ Object.defineProperty(this, "shouldIgnore", { writable: false });
65
87
  }
66
88
 
67
89
  /* eslint-disable class-methods-use-this -- Desired as instance method */
@@ -87,6 +109,23 @@ class FlatConfigArray extends ConfigArray {
87
109
  return require("../../conf/eslint-all");
88
110
  }
89
111
 
112
+ /*
113
+ * If `shouldIgnore` is false, we remove any ignore patterns specified
114
+ * in the config so long as it's not a default config and it doesn't
115
+ * have a `files` entry.
116
+ */
117
+ if (
118
+ !this.shouldIgnore &&
119
+ !this[originalBaseConfig].includes(config) &&
120
+ config.ignores &&
121
+ !config.files
122
+ ) {
123
+ /* eslint-disable-next-line no-unused-vars -- need to strip off other keys */
124
+ const { ignores, ...otherKeys } = config;
125
+
126
+ return otherKeys;
127
+ }
128
+
90
129
  return config;
91
130
  }
92
131
 
@@ -100,31 +139,72 @@ class FlatConfigArray extends ConfigArray {
100
139
  [ConfigArraySymbol.finalizeConfig](config) {
101
140
 
102
141
  const { plugins, languageOptions, processor } = config;
142
+ let parserName, processorName;
143
+ let invalidParser = false,
144
+ invalidProcessor = false;
103
145
 
104
146
  // Check parser value
105
- if (languageOptions && languageOptions.parser && typeof languageOptions.parser === "string") {
106
- const { pluginName, objectName: parserName } = splitPluginIdentifier(languageOptions.parser);
147
+ if (languageOptions && languageOptions.parser) {
148
+ if (typeof languageOptions.parser === "string") {
149
+ const { pluginName, objectName: localParserName } = splitPluginIdentifier(languageOptions.parser);
107
150
 
108
- if (!plugins || !plugins[pluginName] || !plugins[pluginName].parsers || !plugins[pluginName].parsers[parserName]) {
109
- throw new TypeError(`Key "parser": Could not find "${parserName}" in plugin "${pluginName}".`);
110
- }
151
+ parserName = languageOptions.parser;
152
+
153
+ if (!plugins || !plugins[pluginName] || !plugins[pluginName].parsers || !plugins[pluginName].parsers[localParserName]) {
154
+ throw new TypeError(`Key "parser": Could not find "${localParserName}" in plugin "${pluginName}".`);
155
+ }
111
156
 
112
- languageOptions.parser = plugins[pluginName].parsers[parserName];
157
+ languageOptions.parser = plugins[pluginName].parsers[localParserName];
158
+ } else {
159
+ invalidParser = true;
160
+ }
113
161
  }
114
162
 
115
163
  // Check processor value
116
- if (processor && typeof processor === "string") {
117
- const { pluginName, objectName: processorName } = splitPluginIdentifier(processor);
164
+ if (processor) {
165
+ if (typeof processor === "string") {
166
+ const { pluginName, objectName: localProcessorName } = splitPluginIdentifier(processor);
118
167
 
119
- if (!plugins || !plugins[pluginName] || !plugins[pluginName].processors || !plugins[pluginName].processors[processorName]) {
120
- throw new TypeError(`Key "processor": Could not find "${processorName}" in plugin "${pluginName}".`);
121
- }
168
+ processorName = processor;
169
+
170
+ if (!plugins || !plugins[pluginName] || !plugins[pluginName].processors || !plugins[pluginName].processors[localProcessorName]) {
171
+ throw new TypeError(`Key "processor": Could not find "${localProcessorName}" in plugin "${pluginName}".`);
172
+ }
122
173
 
123
- config.processor = plugins[pluginName].processors[processorName];
174
+ config.processor = plugins[pluginName].processors[localProcessorName];
175
+ } else {
176
+ invalidProcessor = true;
177
+ }
124
178
  }
125
179
 
126
180
  ruleValidator.validate(config);
127
181
 
182
+ // apply special logic for serialization into JSON
183
+ /* eslint-disable object-shorthand -- shorthand would change "this" value */
184
+ Object.defineProperty(config, "toJSON", {
185
+ value: function() {
186
+
187
+ if (invalidParser) {
188
+ throw new Error("Caching is not supported when parser is an object.");
189
+ }
190
+
191
+ if (invalidProcessor) {
192
+ throw new Error("Caching is not supported when processor is an object.");
193
+ }
194
+
195
+ return {
196
+ ...this,
197
+ plugins: Object.keys(plugins),
198
+ languageOptions: {
199
+ ...languageOptions,
200
+ parser: parserName
201
+ },
202
+ processor: processorName
203
+ };
204
+ }
205
+ });
206
+ /* eslint-enable object-shorthand -- ok to enable now */
207
+
128
208
  return config;
129
209
  }
130
210
  /* eslint-enable class-methods-use-this -- Desired as instance method */
@@ -20,7 +20,14 @@ function parseRuleId(ruleId) {
20
20
 
21
21
  // distinguish between core rules and plugin rules
22
22
  if (ruleId.includes("/")) {
23
- pluginName = ruleId.slice(0, ruleId.lastIndexOf("/"));
23
+
24
+ // mimic scoped npm packages
25
+ if (ruleId.startsWith("@")) {
26
+ pluginName = ruleId.slice(0, ruleId.lastIndexOf("/"));
27
+ } else {
28
+ pluginName = ruleId.slice(0, ruleId.indexOf("/"));
29
+ }
30
+
24
31
  ruleName = ruleId.slice(pluginName.length + 1);
25
32
  } else {
26
33
  pluginName = "@";
@@ -47,6 +54,7 @@ function getRuleFromConfig(ruleId, config) {
47
54
  const plugin = config.plugins && config.plugins[pluginName];
48
55
  let rule = plugin && plugin.rules && plugin.rules[ruleName];
49
56
 
57
+
50
58
  // normalize function rules into objects
51
59
  if (rule && typeof rule === "function") {
52
60
  rule = {