eslint 9.33.0 → 9.34.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.
@@ -0,0 +1,281 @@
1
+ /**
2
+ * @fileoverview Translates CLI options into ESLint constructor options.
3
+ * @author Nicholas C. Zakas
4
+ * @author Francesco Trotta
5
+ */
6
+
7
+ "use strict";
8
+
9
+ //------------------------------------------------------------------------------
10
+ // Requirements
11
+ //------------------------------------------------------------------------------
12
+
13
+ const { normalizeSeverityToString } = require("./severity");
14
+ const { getShorthandName, normalizePackageName } = require("./naming");
15
+ const { ModuleImporter } = require("@humanwhocodes/module-importer");
16
+
17
+ //------------------------------------------------------------------------------
18
+ // Types
19
+ //------------------------------------------------------------------------------
20
+
21
+ /** @typedef {import("../types").ESLint.Options} ESLintOptions */
22
+ /** @typedef {import("../types").ESLint.LegacyOptions} LegacyESLintOptions */
23
+ /** @typedef {import("../types").Linter.LintMessage} LintMessage */
24
+ /** @typedef {import("../options").ParsedCLIOptions} ParsedCLIOptions */
25
+ /** @typedef {import("../types").ESLint.Plugin} Plugin */
26
+
27
+ //------------------------------------------------------------------------------
28
+ // Helpers
29
+ //------------------------------------------------------------------------------
30
+
31
+ /**
32
+ * Loads plugins with the specified names.
33
+ * @param {{ "import": (name: string) => Promise<any> }} importer An object with an `import` method called once for each plugin.
34
+ * @param {string[]} pluginNames The names of the plugins to be loaded, with or without the "eslint-plugin-" prefix.
35
+ * @returns {Promise<Record<string, Plugin>>} A mapping of plugin short names to implementations.
36
+ */
37
+ async function loadPlugins(importer, pluginNames) {
38
+ const plugins = {};
39
+
40
+ await Promise.all(
41
+ pluginNames.map(async pluginName => {
42
+ const longName = normalizePackageName(pluginName, "eslint-plugin");
43
+ const module = await importer.import(longName);
44
+
45
+ if (!("default" in module)) {
46
+ throw new Error(
47
+ `"${longName}" cannot be used with the \`--plugin\` option because its default module does not provide a \`default\` export`,
48
+ );
49
+ }
50
+
51
+ const shortName = getShorthandName(pluginName, "eslint-plugin");
52
+
53
+ plugins[shortName] = module.default;
54
+ }),
55
+ );
56
+
57
+ return plugins;
58
+ }
59
+
60
+ /**
61
+ * Predicate function for whether or not to apply fixes in quiet mode.
62
+ * If a message is a warning, do not apply a fix.
63
+ * @param {LintMessage} message The lint result.
64
+ * @returns {boolean} True if the lint message is an error (and thus should be
65
+ * autofixed), false otherwise.
66
+ */
67
+ function quietFixPredicate(message) {
68
+ return message.severity === 2;
69
+ }
70
+
71
+ /**
72
+ * Predicate function for whether or not to run a rule in quiet mode.
73
+ * If a rule is set to warning, do not run it.
74
+ * @param {{ ruleId: string; severity: number; }} rule The rule id and severity.
75
+ * @returns {boolean} True if the lint rule should run, false otherwise.
76
+ */
77
+ function quietRuleFilter(rule) {
78
+ return rule.severity === 2;
79
+ }
80
+
81
+ //------------------------------------------------------------------------------
82
+ // Public Interface
83
+ //------------------------------------------------------------------------------
84
+
85
+ /**
86
+ * Translates the CLI options into the options expected by the ESLint constructor.
87
+ * @param {ParsedCLIOptions} cliOptions The CLI options to translate.
88
+ * @param {"flat"|"eslintrc"} [configType="eslintrc"] The format of the config to generate.
89
+ * @returns {Promise<ESLintOptions | LegacyESLintOptions>} The options object for the ESLint constructor.
90
+ */
91
+ async function translateOptions(
92
+ {
93
+ cache,
94
+ cacheFile,
95
+ cacheLocation,
96
+ cacheStrategy,
97
+ concurrency,
98
+ config,
99
+ configLookup,
100
+ env,
101
+ errorOnUnmatchedPattern,
102
+ eslintrc,
103
+ ext,
104
+ fix,
105
+ fixDryRun,
106
+ fixType,
107
+ flag,
108
+ global,
109
+ ignore,
110
+ ignorePath,
111
+ ignorePattern,
112
+ inlineConfig,
113
+ parser,
114
+ parserOptions,
115
+ plugin,
116
+ quiet,
117
+ reportUnusedDisableDirectives,
118
+ reportUnusedDisableDirectivesSeverity,
119
+ reportUnusedInlineConfigs,
120
+ resolvePluginsRelativeTo,
121
+ rule,
122
+ rulesdir,
123
+ stats,
124
+ warnIgnored,
125
+ passOnNoPatterns,
126
+ maxWarnings,
127
+ },
128
+ configType,
129
+ ) {
130
+ let overrideConfig, overrideConfigFile;
131
+ const importer = new ModuleImporter();
132
+
133
+ if (configType === "flat") {
134
+ overrideConfigFile =
135
+ typeof config === "string" ? config : !configLookup;
136
+ if (overrideConfigFile === false) {
137
+ overrideConfigFile = void 0;
138
+ }
139
+
140
+ const languageOptions = {};
141
+
142
+ if (global) {
143
+ languageOptions.globals = global.reduce((obj, name) => {
144
+ if (name.endsWith(":true")) {
145
+ obj[name.slice(0, -5)] = "writable";
146
+ } else {
147
+ obj[name] = "readonly";
148
+ }
149
+ return obj;
150
+ }, {});
151
+ }
152
+
153
+ if (parserOptions) {
154
+ languageOptions.parserOptions = parserOptions;
155
+ }
156
+
157
+ if (parser) {
158
+ languageOptions.parser = await importer.import(parser);
159
+ }
160
+
161
+ overrideConfig = [
162
+ {
163
+ ...(Object.keys(languageOptions).length > 0
164
+ ? { languageOptions }
165
+ : {}),
166
+ rules: rule ? rule : {},
167
+ },
168
+ ];
169
+
170
+ if (
171
+ reportUnusedDisableDirectives ||
172
+ reportUnusedDisableDirectivesSeverity !== void 0
173
+ ) {
174
+ overrideConfig[0].linterOptions = {
175
+ reportUnusedDisableDirectives: reportUnusedDisableDirectives
176
+ ? "error"
177
+ : normalizeSeverityToString(
178
+ reportUnusedDisableDirectivesSeverity,
179
+ ),
180
+ };
181
+ }
182
+
183
+ if (reportUnusedInlineConfigs !== void 0) {
184
+ overrideConfig[0].linterOptions = {
185
+ ...overrideConfig[0].linterOptions,
186
+ reportUnusedInlineConfigs: normalizeSeverityToString(
187
+ reportUnusedInlineConfigs,
188
+ ),
189
+ };
190
+ }
191
+
192
+ if (plugin) {
193
+ overrideConfig[0].plugins = await loadPlugins(importer, plugin);
194
+ }
195
+
196
+ if (ext) {
197
+ overrideConfig.push({
198
+ files: ext.map(
199
+ extension =>
200
+ `**/*${extension.startsWith(".") ? "" : "."}${extension}`,
201
+ ),
202
+ });
203
+ }
204
+ } else {
205
+ overrideConfigFile = config;
206
+
207
+ overrideConfig = {
208
+ env:
209
+ env &&
210
+ env.reduce((obj, name) => {
211
+ obj[name] = true;
212
+ return obj;
213
+ }, {}),
214
+ globals:
215
+ global &&
216
+ global.reduce((obj, name) => {
217
+ if (name.endsWith(":true")) {
218
+ obj[name.slice(0, -5)] = "writable";
219
+ } else {
220
+ obj[name] = "readonly";
221
+ }
222
+ return obj;
223
+ }, {}),
224
+ ignorePatterns: ignorePattern,
225
+ parser,
226
+ parserOptions,
227
+ plugins: plugin,
228
+ rules: rule,
229
+ };
230
+ }
231
+
232
+ const options = {
233
+ allowInlineConfig: inlineConfig,
234
+ cache,
235
+ cacheLocation: cacheLocation || cacheFile,
236
+ cacheStrategy,
237
+ errorOnUnmatchedPattern,
238
+ fix: (fix || fixDryRun) && (quiet ? quietFixPredicate : true),
239
+ fixTypes: fixType,
240
+ ignore,
241
+ overrideConfig,
242
+ overrideConfigFile,
243
+ passOnNoPatterns,
244
+ };
245
+
246
+ if (configType === "flat") {
247
+ options.concurrency = concurrency;
248
+ options.flags = flag;
249
+ options.ignorePatterns = ignorePattern;
250
+ options.stats = stats;
251
+ options.warnIgnored = warnIgnored;
252
+
253
+ /*
254
+ * For performance reasons rules not marked as 'error' are filtered out in quiet mode. As maxWarnings
255
+ * requires rules set to 'warn' to be run, we only filter out 'warn' rules if maxWarnings is not specified.
256
+ */
257
+ options.ruleFilter =
258
+ quiet && maxWarnings === -1 ? quietRuleFilter : () => true;
259
+ } else {
260
+ options.resolvePluginsRelativeTo = resolvePluginsRelativeTo;
261
+ options.rulePaths = rulesdir;
262
+ options.useEslintrc = eslintrc;
263
+ options.extensions = ext;
264
+ options.ignorePath = ignorePath;
265
+ if (
266
+ reportUnusedDisableDirectives ||
267
+ reportUnusedDisableDirectivesSeverity !== void 0
268
+ ) {
269
+ options.reportUnusedDisableDirectives =
270
+ reportUnusedDisableDirectives
271
+ ? "error"
272
+ : normalizeSeverityToString(
273
+ reportUnusedDisableDirectivesSeverity,
274
+ );
275
+ }
276
+ }
277
+
278
+ return options;
279
+ }
280
+
281
+ module.exports = translateOptions;
@@ -1966,6 +1966,10 @@ export class ESLint {
1966
1966
  isPathIgnored(filePath: string): Promise<boolean>;
1967
1967
 
1968
1968
  loadFormatter(nameOrPath?: string): Promise<ESLint.LoadedFormatter>;
1969
+
1970
+ static fromOptionsModule(optionsURL: {
1971
+ readonly href: string;
1972
+ }): Promise<ESLint>;
1969
1973
  }
1970
1974
 
1971
1975
  export namespace ESLint {
@@ -2047,6 +2051,7 @@ export namespace ESLint {
2047
2051
  cacheStrategy?: CacheStrategy | undefined;
2048
2052
 
2049
2053
  // Other Options
2054
+ concurrency?: number | "auto" | "off" | undefined;
2050
2055
  flags?: string[] | undefined;
2051
2056
  }
2052
2057
 
@@ -117,7 +117,7 @@ export interface ESLintRules extends Linter.RulesRecord {
117
117
  */
118
118
  enforceForClassMembers: boolean;
119
119
  /**
120
- * @default true
120
+ * @default false
121
121
  */
122
122
  enforceForTSTypes: boolean;
123
123
  }>,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "9.33.0",
3
+ "version": "9.34.0",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "type": "commonjs",
@@ -110,7 +110,7 @@
110
110
  "@eslint/config-helpers": "^0.3.1",
111
111
  "@eslint/core": "^0.15.2",
112
112
  "@eslint/eslintrc": "^3.3.1",
113
- "@eslint/js": "9.33.0",
113
+ "@eslint/js": "9.34.0",
114
114
  "@eslint/plugin-kit": "^0.3.5",
115
115
  "@humanfs/node": "^0.16.6",
116
116
  "@humanwhocodes/module-importer": "^1.0.1",