eslint 9.33.0 → 9.35.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.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/lib/cli-engine/file-enumerator.js +1 -1
  3. package/lib/cli.js +62 -266
  4. package/lib/config/flat-config-schema.js +1 -1
  5. package/lib/eslint/eslint-helpers.js +426 -6
  6. package/lib/eslint/eslint.js +381 -313
  7. package/lib/eslint/worker.js +164 -0
  8. package/lib/languages/js/source-code/source-code.js +3 -4
  9. package/lib/linter/esquery.js +3 -0
  10. package/lib/linter/interpolate.js +1 -1
  11. package/lib/linter/linter.js +3 -4
  12. package/lib/options.js +23 -9
  13. package/lib/rule-tester/rule-tester.js +3 -0
  14. package/lib/rules/array-callback-return.js +0 -1
  15. package/lib/rules/dot-notation.js +1 -1
  16. package/lib/rules/grouped-accessor-pairs.js +8 -7
  17. package/lib/rules/indent-legacy.js +1 -1
  18. package/lib/rules/index.js +1 -0
  19. package/lib/rules/no-alert.js +1 -1
  20. package/lib/rules/no-empty-function.js +20 -1
  21. package/lib/rules/no-empty-static-block.js +25 -1
  22. package/lib/rules/no-empty.js +37 -0
  23. package/lib/rules/no-eval.js +3 -1
  24. package/lib/rules/no-irregular-whitespace.js +2 -2
  25. package/lib/rules/no-loss-of-precision.js +26 -3
  26. package/lib/rules/no-mixed-spaces-and-tabs.js +1 -0
  27. package/lib/rules/no-octal.js +1 -4
  28. package/lib/rules/no-trailing-spaces.js +2 -1
  29. package/lib/rules/no-useless-escape.js +1 -1
  30. package/lib/rules/prefer-regex-literals.js +1 -1
  31. package/lib/rules/preserve-caught-error.js +509 -0
  32. package/lib/rules/strict.js +2 -1
  33. package/lib/rules/utils/ast-utils.js +1 -1
  34. package/lib/rules/utils/char-source.js +1 -1
  35. package/lib/rules/yoda.js +2 -2
  36. package/lib/services/suppressions-service.js +3 -0
  37. package/lib/services/warning-service.js +13 -0
  38. package/lib/shared/naming.js +1 -1
  39. package/lib/shared/translate-cli-options.js +281 -0
  40. package/lib/types/index.d.ts +7 -0
  41. package/lib/types/rules.d.ts +22 -14
  42. package/package.json +3 -3
@@ -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
 
@@ -2254,6 +2259,8 @@ export namespace RuleTester {
2254
2259
  only?: boolean;
2255
2260
  languageOptions?: Linter.LanguageOptions | undefined;
2256
2261
  settings?: { [name: string]: any } | undefined;
2262
+ before?: () => void;
2263
+ after?: () => void;
2257
2264
  }
2258
2265
 
2259
2266
  interface SuggestionOutput {
@@ -60,25 +60,19 @@ type EitherGroupOrRegEx =
60
60
  // Base type for import name specifiers, ensuring mutual exclusivity
61
61
  type EitherNameSpecifiers =
62
62
  | {
63
- importNames: string[];
63
+ importNames?: string[];
64
+ importNamePattern?: string;
64
65
  allowImportNames?: never;
65
- importNamePattern?: never;
66
66
  allowImportNamePattern?: never;
67
67
  }
68
68
  | {
69
- importNamePattern: string;
70
- allowImportNames?: never;
71
- importNames?: never;
72
- allowImportNamePattern?: never;
73
- }
74
- | {
75
- allowImportNames: string[];
69
+ allowImportNames?: string[];
76
70
  importNames?: never;
77
71
  importNamePattern?: never;
78
72
  allowImportNamePattern?: never;
79
73
  }
80
74
  | {
81
- allowImportNamePattern: string;
75
+ allowImportNamePattern?: string;
82
76
  importNames?: never;
83
77
  allowImportNames?: never;
84
78
  importNamePattern?: never;
@@ -117,7 +111,7 @@ export interface ESLintRules extends Linter.RulesRecord {
117
111
  */
118
112
  enforceForClassMembers: boolean;
119
113
  /**
120
- * @default true
114
+ * @default false
121
115
  */
122
116
  enforceForTSTypes: boolean;
123
117
  }>,
@@ -3441,9 +3435,9 @@ export interface ESLintRules extends Linter.RulesRecord {
3441
3435
  paths: Array<
3442
3436
  string | ValidNoRestrictedImportPathOptions
3443
3437
  >;
3444
- patterns: Array<
3445
- string | ValidNoRestrictedImportPatternOptions
3446
- >;
3438
+ patterns:
3439
+ | Array<string>
3440
+ | Array<ValidNoRestrictedImportPatternOptions>;
3447
3441
  }>
3448
3442
  >,
3449
3443
  ]
@@ -4809,6 +4803,20 @@ export interface ESLintRules extends Linter.RulesRecord {
4809
4803
  */
4810
4804
  "prefer-template": Linter.RuleEntry<[]>;
4811
4805
 
4806
+ /**
4807
+ * Rule to disallow losing originally caught error when re-throwing custom errors.
4808
+ *
4809
+ * @since 9.35.0
4810
+ * @see https://eslint.org/docs/latest/rules/preserve-caught-error
4811
+ */
4812
+ "preserve-caught-error": Linter.RuleEntry<
4813
+ [
4814
+ Partial<{
4815
+ requireCatchParameter: boolean;
4816
+ }>,
4817
+ ]
4818
+ >;
4819
+
4812
4820
  /**
4813
4821
  * Rule to require quotes around object literal property names.
4814
4822
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "9.33.0",
3
+ "version": "9.35.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",
@@ -104,13 +104,13 @@
104
104
  "homepage": "https://eslint.org",
105
105
  "bugs": "https://github.com/eslint/eslint/issues/",
106
106
  "dependencies": {
107
- "@eslint-community/eslint-utils": "^4.2.0",
107
+ "@eslint-community/eslint-utils": "^4.8.0",
108
108
  "@eslint-community/regexpp": "^4.12.1",
109
109
  "@eslint/config-array": "^0.21.0",
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.35.0",
114
114
  "@eslint/plugin-kit": "^0.3.5",
115
115
  "@humanfs/node": "^0.16.6",
116
116
  "@humanwhocodes/module-importer": "^1.0.1",