eslint 8.34.0 → 8.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.
package/README.md CHANGED
@@ -16,8 +16,7 @@
16
16
  [Report Bugs](https://eslint.org/docs/latest/contribute/report-bugs) |
17
17
  [Code of Conduct](https://eslint.org/conduct) |
18
18
  [Twitter](https://twitter.com/geteslint) |
19
- [Mailing List](https://groups.google.com/group/eslint) |
20
- [Chat Room](https://eslint.org/chat)
19
+ [Discord](https://eslint.org/chat)
21
20
 
22
21
  ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:
23
22
 
@@ -129,7 +128,7 @@ Once a language feature has been adopted into the ECMAScript standard (stage 4 a
129
128
 
130
129
  ### Where to ask for help?
131
130
 
132
- Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](https://eslint.org/chat).
131
+ Open a [discussion](https://github.com/eslint/eslint/discussions) or stop by our [Discord server](https://eslint.org/chat).
133
132
 
134
133
  ### Why doesn't ESLint lock dependency versions?
135
134
 
@@ -255,6 +254,11 @@ Bryan Mishkin
255
254
  Sara Soueidan
256
255
  </a>
257
256
  </td><td align="center" valign="top" width="11%">
257
+ <a href="https://github.com/fasttime">
258
+ <img src="https://github.com/fasttime.png?s=75" width="75" height="75"><br />
259
+ Francesco Trotta
260
+ </a>
261
+ </td><td align="center" valign="top" width="11%">
258
262
  <a href="https://github.com/yeonjuan">
259
263
  <img src="https://github.com/yeonjuan.png?s=75" width="75" height="75"><br />
260
264
  YeonJuan
@@ -615,8 +615,8 @@ class CLIEngine {
615
615
  useEslintrc: options.useEslintrc,
616
616
  builtInRules,
617
617
  loadRules,
618
- getEslintRecommendedConfig: () => require("../../conf/eslint-recommended.js"),
619
- getEslintAllConfig: () => require("../../conf/eslint-all.js")
618
+ getEslintRecommendedConfig: () => require("@eslint/js").configs.recommended,
619
+ getEslintAllConfig: () => require("@eslint/js").configs.all
620
620
  });
621
621
  const fileEnumerator = new FileEnumerator({
622
622
  configArrayFactory,
@@ -217,8 +217,8 @@ class FileEnumerator {
217
217
  cwd = process.cwd(),
218
218
  configArrayFactory = new CascadingConfigArrayFactory({
219
219
  cwd,
220
- getEslintRecommendedConfig: () => require("../../conf/eslint-recommended.js"),
221
- getEslintAllConfig: () => require("../../conf/eslint-all.js")
220
+ getEslintRecommendedConfig: () => require("@eslint/js").configs.recommended,
221
+ getEslintAllConfig: () => require("@eslint/js").configs.all
222
222
  }),
223
223
  extensions = null,
224
224
  globInputPaths = true,
@@ -13,7 +13,7 @@ const { ConfigArray, ConfigArraySymbol } = require("@humanwhocodes/config-array"
13
13
  const { flatConfigSchema } = require("./flat-config-schema");
14
14
  const { RuleValidator } = require("./rule-validator");
15
15
  const { defaultConfig } = require("./default-config");
16
- const recommendedConfig = require("../../conf/eslint-recommended");
16
+ const jsPlugin = require("@eslint/js");
17
17
 
18
18
  //-----------------------------------------------------------------------------
19
19
  // Helpers
@@ -96,17 +96,23 @@ class FlatConfigArray extends ConfigArray {
96
96
  */
97
97
  [ConfigArraySymbol.preprocessConfig](config) {
98
98
  if (config === "eslint:recommended") {
99
- return recommendedConfig;
99
+
100
+ // if we are in a Node.js environment warn the user
101
+ if (typeof process !== "undefined" && process.emitWarning) {
102
+ process.emitWarning("The 'eslint:recommended' string configuration is deprecated and will be replaced by the @eslint/js package's 'recommended' config.");
103
+ }
104
+
105
+ return jsPlugin.configs.recommended;
100
106
  }
101
107
 
102
108
  if (config === "eslint:all") {
103
109
 
104
- /*
105
- * Load `eslint-all.js` here instead of at the top level to avoid loading all rule modules
106
- * when it isn't necessary. `eslint-all.js` reads `meta` of rule objects to filter out deprecated ones,
107
- * so requiring `eslint-all.js` module loads all rule modules as a consequence.
108
- */
109
- return require("../../conf/eslint-all");
110
+ // if we are in a Node.js environment warn the user
111
+ if (typeof process !== "undefined" && process.emitWarning) {
112
+ process.emitWarning("The 'eslint:all' string configuration is deprecated and will be replaced by the @eslint/js package's 'all' config.");
113
+ }
114
+
115
+ return jsPlugin.configs.all;
110
116
  }
111
117
 
112
118
  /*
@@ -223,7 +223,7 @@ function globMatch({ basePath, pattern }) {
223
223
  * should be thrown when a pattern is unmatched.
224
224
  * @returns {Promise<Array<string>>} An array of matching file paths
225
225
  * or an empty array if there are no matches.
226
- * @throws {UnmatchedSearchPatternsErrror} If there is a pattern that doesn't
226
+ * @throws {UnmatchedSearchPatternsError} If there is a pattern that doesn't
227
227
  * match any files.
228
228
  */
229
229
  async function globSearch({
@@ -113,6 +113,10 @@ module.exports = {
113
113
  },
114
114
  applyDefaultIgnorePatterns: {
115
115
  type: "boolean"
116
+ },
117
+ afterHashbangComment: {
118
+ type: "boolean",
119
+ default: false
116
120
  }
117
121
  },
118
122
  additionalProperties: false
@@ -449,6 +453,13 @@ module.exports = {
449
453
  before: options.beforeBlockComment
450
454
  });
451
455
  }
456
+ } else if (token.type === "Shebang") {
457
+ if (options.afterHashbangComment) {
458
+ checkForEmptyLine(token, {
459
+ after: options.afterHashbangComment,
460
+ before: false
461
+ });
462
+ }
452
463
  }
453
464
  });
454
465
  }
@@ -112,7 +112,7 @@ function isBooleanCast(expression, scope) {
112
112
  /**
113
113
  * Returns true for:
114
114
  * truthiness checks: value, Boolean(value), !!value
115
- * falsyness checks: !value, !Boolean(value)
115
+ * falsiness checks: !value, !Boolean(value)
116
116
  * nullish checks: value == null, value === undefined || value === null
117
117
  * @param {ASTNode} expression Test condition
118
118
  * @param {import('eslint-scope').Scope} scope Scope of the expression
@@ -14,6 +14,23 @@ const NUMERIC_OR_STRING_BINARY_OPERATORS = new Set(["+", "-", "*", "/", "%", "|"
14
14
  // Helpers
15
15
  //------------------------------------------------------------------------------
16
16
 
17
+ /**
18
+ * Checks whether or not a node is `null` or `undefined`. Similar to the one
19
+ * found in ast-utils.js, but this one correctly handles the edge case that
20
+ * `undefined` has been redefined.
21
+ * @param {Scope} scope Scope in which the expression was found.
22
+ * @param {ASTNode} node A node to check.
23
+ * @returns {boolean} Whether or not the node is a `null` or `undefined`.
24
+ * @public
25
+ */
26
+ function isNullOrUndefined(scope, node) {
27
+ return (
28
+ isNullLiteral(node) ||
29
+ (node.type === "Identifier" && node.name === "undefined" && isReferenceToGlobalVariable(scope, node)) ||
30
+ (node.type === "UnaryExpression" && node.operator === "void")
31
+ );
32
+ }
33
+
17
34
  /**
18
35
  * Test if an AST node has a statically knowable constant nullishness. Meaning,
19
36
  * it will always resolve to a constant value of either: `null`, `undefined`
@@ -21,9 +38,14 @@ const NUMERIC_OR_STRING_BINARY_OPERATORS = new Set(["+", "-", "*", "/", "%", "|"
21
38
  * three states at runtime would return `false`.
22
39
  * @param {Scope} scope The scope in which the node was found.
23
40
  * @param {ASTNode} node The AST node being tested.
41
+ * @param {boolean} nonNullish if `true` then nullish values are not considered constant.
24
42
  * @returns {boolean} Does `node` have constant nullishness?
25
43
  */
26
- function hasConstantNullishness(scope, node) {
44
+ function hasConstantNullishness(scope, node, nonNullish) {
45
+ if (nonNullish && isNullOrUndefined(scope, node)) {
46
+ return false;
47
+ }
48
+
27
49
  switch (node.type) {
28
50
  case "ObjectExpression": // Objects are never nullish
29
51
  case "ArrayExpression": // Arrays are never nullish
@@ -45,9 +67,12 @@ function hasConstantNullishness(scope, node) {
45
67
  return (functionName === "Boolean" || functionName === "String" || functionName === "Number") &&
46
68
  isReferenceToGlobalVariable(scope, node.callee);
47
69
  }
70
+ case "LogicalExpression": {
71
+ return node.operator === "??" && hasConstantNullishness(scope, node.right, true);
72
+ }
48
73
  case "AssignmentExpression":
49
74
  if (node.operator === "=") {
50
- return hasConstantNullishness(scope, node.right);
75
+ return hasConstantNullishness(scope, node.right, nonNullish);
51
76
  }
52
77
 
53
78
  /*
@@ -80,7 +105,7 @@ function hasConstantNullishness(scope, node) {
80
105
  case "SequenceExpression": {
81
106
  const last = node.expressions[node.expressions.length - 1];
82
107
 
83
- return hasConstantNullishness(scope, last);
108
+ return hasConstantNullishness(scope, last, nonNullish);
84
109
  }
85
110
  case "Identifier":
86
111
  return node.name === "undefined" && isReferenceToGlobalVariable(scope, node);
@@ -348,7 +373,7 @@ function isAlwaysNew(scope, node) {
348
373
  * user-defined constructors could return a sentinel
349
374
  * object.
350
375
  *
351
- * Catching these is especially useful for primitive constructures
376
+ * Catching these is especially useful for primitive constructors
352
377
  * which return boxed values, a surprising gotcha' in JavaScript.
353
378
  */
354
379
  return Object.hasOwnProperty.call(globals.builtin, node.callee.name) &&
@@ -378,24 +403,6 @@ function isAlwaysNew(scope, node) {
378
403
  }
379
404
  }
380
405
 
381
- /**
382
- * Checks whether or not a node is `null` or `undefined`. Similar to the one
383
- * found in ast-utils.js, but this one correctly handles the edge case that
384
- * `undefined` has been redefined.
385
- * @param {Scope} scope Scope in which the expression was found.
386
- * @param {ASTNode} node A node to check.
387
- * @returns {boolean} Whether or not the node is a `null` or `undefined`.
388
- * @public
389
- */
390
- function isNullOrUndefined(scope, node) {
391
- return (
392
- isNullLiteral(node) ||
393
- (node.type === "Identifier" && node.name === "undefined" && isReferenceToGlobalVariable(scope, node)) ||
394
- (node.type === "UnaryExpression" && node.operator === "void")
395
- );
396
- }
397
-
398
-
399
406
  /**
400
407
  * Checks if one operand will cause the result to be constant.
401
408
  * @param {Scope} scope Scope in which the expression was found.
@@ -407,14 +414,14 @@ function isNullOrUndefined(scope, node) {
407
414
  function findBinaryExpressionConstantOperand(scope, a, b, operator) {
408
415
  if (operator === "==" || operator === "!=") {
409
416
  if (
410
- (isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b)) ||
417
+ (isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b, false)) ||
411
418
  (isStaticBoolean(scope, a) && hasConstantLooseBooleanComparison(scope, b))
412
419
  ) {
413
420
  return b;
414
421
  }
415
422
  } else if (operator === "===" || operator === "!==") {
416
423
  if (
417
- (isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b)) ||
424
+ (isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b, false)) ||
418
425
  (isStaticBoolean(scope, a) && hasConstantStrictBooleanComparison(scope, b))
419
426
  ) {
420
427
  return b;
@@ -453,7 +460,7 @@ module.exports = {
453
460
 
454
461
  if ((operator === "&&" || operator === "||") && isConstant(scope, left, true)) {
455
462
  context.report({ node: left, messageId: "constantShortCircuit", data: { property: "truthiness", operator } });
456
- } else if (operator === "??" && hasConstantNullishness(scope, left)) {
463
+ } else if (operator === "??" && hasConstantNullishness(scope, left, false)) {
457
464
  context.report({ node: left, messageId: "constantShortCircuit", data: { property: "nullishness", operator } });
458
465
  }
459
466
  },
@@ -72,7 +72,7 @@ module.exports = {
72
72
  let funcInfo = null;
73
73
 
74
74
  /**
75
- * Pushs a `this` scope (non-arrow function, class static block, or class field initializer) information to the stack.
75
+ * Pushes a `this` scope (non-arrow function, class static block, or class field initializer) information to the stack.
76
76
  * Top-level scopes are handled separately.
77
77
  *
78
78
  * This is used in order to check whether or not `this` binding is a
@@ -197,7 +197,7 @@ module.exports = {
197
197
 
198
198
  return {
199
199
 
200
- // Makes and pushs a new scope information.
200
+ // Makes and pushes a new scope information.
201
201
  onCodePathStart(codePath) {
202
202
  scopeInfo = {
203
203
  upper: scopeInfo,
@@ -10,6 +10,6 @@ ESLint couldn't find a configuration file. To set up a configuration file for th
10
10
 
11
11
  ESLint looked for configuration files in ${directoryPath} and its ancestors. If it found none, it then looked in your home directory.
12
12
 
13
- If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://eslint.org/chat/help
13
+ If you think you already have a configuration file or if you need more help, please stop by the ESLint Discord server: https://eslint.org/chat
14
14
  `.trimStart();
15
15
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "8.34.0",
3
+ "version": "8.35.0",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -37,6 +37,10 @@
37
37
  "lint-staged": {
38
38
  "*.js": "eslint --fix",
39
39
  "*.md": "markdownlint --fix",
40
+ "lib/rules/*.js": [
41
+ "node tools/update-eslint-all.js",
42
+ "git add packages/js/src/configs/eslint-all.js"
43
+ ],
40
44
  "docs/src/rules/*.md": [
41
45
  "node tools/fetch-docs-links.js",
42
46
  "git add docs/src/_data/further_reading_links.json"
@@ -56,7 +60,8 @@
56
60
  "homepage": "https://eslint.org",
57
61
  "bugs": "https://github.com/eslint/eslint/issues/",
58
62
  "dependencies": {
59
- "@eslint/eslintrc": "^1.4.1",
63
+ "@eslint/eslintrc": "^2.0.0",
64
+ "@eslint/js": "8.35.0",
60
65
  "@humanwhocodes/config-array": "^0.11.8",
61
66
  "@humanwhocodes/module-importer": "^1.0.1",
62
67
  "@nodelib/fs.walk": "^1.2.8",
@@ -70,7 +75,7 @@
70
75
  "eslint-utils": "^3.0.0",
71
76
  "eslint-visitor-keys": "^3.3.0",
72
77
  "espree": "^9.4.0",
73
- "esquery": "^1.4.0",
78
+ "esquery": "^1.4.2",
74
79
  "esutils": "^2.0.2",
75
80
  "fast-deep-equal": "^3.1.3",
76
81
  "file-entry-cache": "^6.0.1",
@@ -1,31 +0,0 @@
1
- /**
2
- * @fileoverview Config to enable all rules.
3
- * @author Robert Fletcher
4
- */
5
-
6
- "use strict";
7
-
8
- //------------------------------------------------------------------------------
9
- // Requirements
10
- //------------------------------------------------------------------------------
11
-
12
- const builtInRules = require("../lib/rules");
13
-
14
- //------------------------------------------------------------------------------
15
- // Helpers
16
- //------------------------------------------------------------------------------
17
-
18
- const allRules = {};
19
-
20
- for (const [ruleId, rule] of builtInRules) {
21
- if (!rule.meta.deprecated) {
22
- allRules[ruleId] = "error";
23
- }
24
- }
25
-
26
- //------------------------------------------------------------------------------
27
- // Public Interface
28
- //------------------------------------------------------------------------------
29
-
30
- /** @type {import("../lib/shared/types").ConfigData} */
31
- module.exports = { rules: allRules };
@@ -1,76 +0,0 @@
1
- /**
2
- * @fileoverview Configuration applied when a user configuration extends from
3
- * eslint:recommended.
4
- * @author Nicholas C. Zakas
5
- */
6
-
7
- "use strict";
8
-
9
- /* eslint sort-keys: ["error", "asc"] -- Long, so make more readable */
10
-
11
- /** @type {import("../lib/shared/types").ConfigData} */
12
- module.exports = {
13
- rules: {
14
- "constructor-super": "error",
15
- "for-direction": "error",
16
- "getter-return": "error",
17
- "no-async-promise-executor": "error",
18
- "no-case-declarations": "error",
19
- "no-class-assign": "error",
20
- "no-compare-neg-zero": "error",
21
- "no-cond-assign": "error",
22
- "no-const-assign": "error",
23
- "no-constant-condition": "error",
24
- "no-control-regex": "error",
25
- "no-debugger": "error",
26
- "no-delete-var": "error",
27
- "no-dupe-args": "error",
28
- "no-dupe-class-members": "error",
29
- "no-dupe-else-if": "error",
30
- "no-dupe-keys": "error",
31
- "no-duplicate-case": "error",
32
- "no-empty": "error",
33
- "no-empty-character-class": "error",
34
- "no-empty-pattern": "error",
35
- "no-ex-assign": "error",
36
- "no-extra-boolean-cast": "error",
37
- "no-extra-semi": "error",
38
- "no-fallthrough": "error",
39
- "no-func-assign": "error",
40
- "no-global-assign": "error",
41
- "no-import-assign": "error",
42
- "no-inner-declarations": "error",
43
- "no-invalid-regexp": "error",
44
- "no-irregular-whitespace": "error",
45
- "no-loss-of-precision": "error",
46
- "no-misleading-character-class": "error",
47
- "no-mixed-spaces-and-tabs": "error",
48
- "no-new-symbol": "error",
49
- "no-nonoctal-decimal-escape": "error",
50
- "no-obj-calls": "error",
51
- "no-octal": "error",
52
- "no-prototype-builtins": "error",
53
- "no-redeclare": "error",
54
- "no-regex-spaces": "error",
55
- "no-self-assign": "error",
56
- "no-setter-return": "error",
57
- "no-shadow-restricted-names": "error",
58
- "no-sparse-arrays": "error",
59
- "no-this-before-super": "error",
60
- "no-undef": "error",
61
- "no-unexpected-multiline": "error",
62
- "no-unreachable": "error",
63
- "no-unsafe-finally": "error",
64
- "no-unsafe-negation": "error",
65
- "no-unsafe-optional-chaining": "error",
66
- "no-unused-labels": "error",
67
- "no-unused-vars": "error",
68
- "no-useless-backreference": "error",
69
- "no-useless-catch": "error",
70
- "no-useless-escape": "error",
71
- "no-with": "error",
72
- "require-yield": "error",
73
- "use-isnan": "error",
74
- "valid-typeof": "error"
75
- }
76
- };