eslint 8.56.0 → 8.57.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/lib/api.js CHANGED
@@ -9,17 +9,45 @@
9
9
  // Requirements
10
10
  //-----------------------------------------------------------------------------
11
11
 
12
- const { ESLint } = require("./eslint");
12
+ const { ESLint, FlatESLint } = require("./eslint");
13
+ const { shouldUseFlatConfig } = require("./eslint/flat-eslint");
13
14
  const { Linter } = require("./linter");
14
15
  const { RuleTester } = require("./rule-tester");
15
16
  const { SourceCode } = require("./source-code");
16
17
 
18
+ //-----------------------------------------------------------------------------
19
+ // Functions
20
+ //-----------------------------------------------------------------------------
21
+
22
+ /**
23
+ * Loads the correct ESLint constructor given the options.
24
+ * @param {Object} [options] The options object
25
+ * @param {boolean} [options.useFlatConfig] Whether or not to use a flat config
26
+ * @param {string} [options.cwd] The current working directory
27
+ * @returns {Promise<ESLint|LegacyESLint>} The ESLint constructor
28
+ */
29
+ async function loadESLint({ useFlatConfig, cwd = process.cwd() } = {}) {
30
+
31
+ /*
32
+ * Note: The v9.x version of this function doesn't have a cwd option
33
+ * because it's not used. It's only used in the v8.x version of this
34
+ * function.
35
+ */
36
+
37
+ const shouldESLintUseFlatConfig = typeof useFlatConfig === "boolean"
38
+ ? useFlatConfig
39
+ : await shouldUseFlatConfig({ cwd });
40
+
41
+ return shouldESLintUseFlatConfig ? FlatESLint : ESLint;
42
+ }
43
+
17
44
  //-----------------------------------------------------------------------------
18
45
  // Exports
19
46
  //-----------------------------------------------------------------------------
20
47
 
21
48
  module.exports = {
22
49
  Linter,
50
+ loadESLint,
23
51
  ESLint,
24
52
  RuleTester,
25
53
  SourceCode
@@ -53,6 +53,15 @@ function isNonNullObject(value) {
53
53
  return typeof value === "object" && value !== null;
54
54
  }
55
55
 
56
+ /**
57
+ * Check if a value is a non-null non-array object.
58
+ * @param {any} value The value to check.
59
+ * @returns {boolean} `true` if the value is a non-null non-array object.
60
+ */
61
+ function isNonArrayObject(value) {
62
+ return isNonNullObject(value) && !Array.isArray(value);
63
+ }
64
+
56
65
  /**
57
66
  * Check if a value is undefined.
58
67
  * @param {any} value The value to check.
@@ -63,19 +72,27 @@ function isUndefined(value) {
63
72
  }
64
73
 
65
74
  /**
66
- * Deeply merges two objects.
75
+ * Deeply merges two non-array objects.
67
76
  * @param {Object} first The base object.
68
77
  * @param {Object} second The overrides object.
78
+ * @param {Map<string, Map<string, Object>>} [mergeMap] Maps the combination of first and second arguments to a merged result.
69
79
  * @returns {Object} An object with properties from both first and second.
70
80
  */
71
- function deepMerge(first = {}, second = {}) {
81
+ function deepMerge(first, second, mergeMap = new Map()) {
72
82
 
73
- /*
74
- * If the second value is an array, just return it. We don't merge
75
- * arrays because order matters and we can't know the correct order.
76
- */
77
- if (Array.isArray(second)) {
78
- return second;
83
+ let secondMergeMap = mergeMap.get(first);
84
+
85
+ if (secondMergeMap) {
86
+ const result = secondMergeMap.get(second);
87
+
88
+ if (result) {
89
+
90
+ // If this combination of first and second arguments has been already visited, return the previously created result.
91
+ return result;
92
+ }
93
+ } else {
94
+ secondMergeMap = new Map();
95
+ mergeMap.set(first, secondMergeMap);
79
96
  }
80
97
 
81
98
  /*
@@ -89,27 +106,25 @@ function deepMerge(first = {}, second = {}) {
89
106
  ...second
90
107
  };
91
108
 
109
+ delete result.__proto__; // eslint-disable-line no-proto -- don't merge own property "__proto__"
110
+
111
+ // Store the pending result for this combination of first and second arguments.
112
+ secondMergeMap.set(second, result);
113
+
92
114
  for (const key of Object.keys(second)) {
93
115
 
94
116
  // avoid hairy edge case
95
- if (key === "__proto__") {
117
+ if (key === "__proto__" || !Object.prototype.propertyIsEnumerable.call(first, key)) {
96
118
  continue;
97
119
  }
98
120
 
99
121
  const firstValue = first[key];
100
122
  const secondValue = second[key];
101
123
 
102
- if (isNonNullObject(firstValue)) {
103
- result[key] = deepMerge(firstValue, secondValue);
104
- } else if (isUndefined(firstValue)) {
105
- if (isNonNullObject(secondValue)) {
106
- result[key] = deepMerge(
107
- Array.isArray(secondValue) ? [] : {},
108
- secondValue
109
- );
110
- } else if (!isUndefined(secondValue)) {
111
- result[key] = secondValue;
112
- }
124
+ if (isNonArrayObject(firstValue) && isNonArrayObject(secondValue)) {
125
+ result[key] = deepMerge(firstValue, secondValue, mergeMap);
126
+ } else if (isUndefined(secondValue)) {
127
+ result[key] = firstValue;
113
128
  }
114
129
  }
115
130
 
@@ -682,6 +682,13 @@ class ESLint {
682
682
  }
683
683
  }
684
684
 
685
+ /**
686
+ * The type of configuration used by this class.
687
+ * @type {string}
688
+ * @static
689
+ */
690
+ ESLint.configType = "eslintrc";
691
+
685
692
  //------------------------------------------------------------------------------
686
693
  // Public Interface
687
694
  //------------------------------------------------------------------------------
@@ -91,7 +91,11 @@ const LintResultCache = require("../cli-engine/lint-result-cache");
91
91
  // Helpers
92
92
  //------------------------------------------------------------------------------
93
93
 
94
- const FLAT_CONFIG_FILENAME = "eslint.config.js";
94
+ const FLAT_CONFIG_FILENAMES = [
95
+ "eslint.config.js",
96
+ "eslint.config.mjs",
97
+ "eslint.config.cjs"
98
+ ];
95
99
  const debug = require("debug")("eslint:flat-eslint");
96
100
  const removedFormatters = new Set(["table", "codeframe"]);
97
101
  const privateMembers = new WeakMap();
@@ -248,7 +252,7 @@ function compareResultsByFilePath(a, b) {
248
252
  */
249
253
  function findFlatConfigFile(cwd) {
250
254
  return findUp(
251
- FLAT_CONFIG_FILENAME,
255
+ FLAT_CONFIG_FILENAMES,
252
256
  { cwd }
253
257
  );
254
258
  }
@@ -1112,11 +1116,20 @@ class FlatESLint {
1112
1116
  }
1113
1117
  }
1114
1118
 
1119
+ /**
1120
+ * The type of configuration used by this class.
1121
+ * @type {string}
1122
+ * @static
1123
+ */
1124
+ FlatESLint.configType = "flat";
1125
+
1115
1126
  /**
1116
1127
  * Returns whether flat config should be used.
1128
+ * @param {Object} [options] The options for this function.
1129
+ * @param {string} [options.cwd] The current working directory.
1117
1130
  * @returns {Promise<boolean>} Whether flat config should be used.
1118
1131
  */
1119
- async function shouldUseFlatConfig() {
1132
+ async function shouldUseFlatConfig({ cwd = process.cwd() } = {}) {
1120
1133
  switch (process.env.ESLINT_USE_FLAT_CONFIG) {
1121
1134
  case "true":
1122
1135
  return true;
@@ -1128,7 +1141,7 @@ async function shouldUseFlatConfig() {
1128
1141
  * If neither explicitly enabled nor disabled, then use the presence
1129
1142
  * of a flat config file to determine enablement.
1130
1143
  */
1131
- return !!(await findFlatConfigFile(process.cwd()));
1144
+ return !!(await findFlatConfigFile(cwd));
1132
1145
  }
1133
1146
  }
1134
1147
 
package/lib/options.js CHANGED
@@ -168,7 +168,7 @@ module.exports = function(usingFlatConfig) {
168
168
  alias: "c",
169
169
  type: "path::String",
170
170
  description: usingFlatConfig
171
- ? "Use this configuration instead of eslint.config.js"
171
+ ? "Use this configuration instead of eslint.config.js, eslint.config.mjs, or eslint.config.cjs"
172
172
  : "Use this configuration, overriding .eslintrc.* config options if present"
173
173
  },
174
174
  envFlag,
@@ -13,6 +13,7 @@
13
13
  const
14
14
  assert = require("assert"),
15
15
  util = require("util"),
16
+ path = require("path"),
16
17
  equal = require("fast-deep-equal"),
17
18
  Traverser = require("../shared/traverser"),
18
19
  { getRuleOptionsSchema } = require("../config/flat-config-helpers"),
@@ -592,7 +593,15 @@ class FlatRuleTester {
592
593
  * @private
593
594
  */
594
595
  function runRuleForItem(item) {
595
- const configs = new FlatConfigArray(testerConfig, { baseConfig });
596
+ const flatConfigArrayOptions = {
597
+ baseConfig
598
+ };
599
+
600
+ if (item.filename) {
601
+ flatConfigArrayOptions.basePath = path.parse(item.filename).root;
602
+ }
603
+
604
+ const configs = new FlatConfigArray(testerConfig, flatConfigArrayOptions);
596
605
 
597
606
  /*
598
607
  * Modify the returned config so that the parser is wrapped to catch
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "8.56.0",
3
+ "version": "8.57.0",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -65,8 +65,8 @@
65
65
  "@eslint-community/eslint-utils": "^4.2.0",
66
66
  "@eslint-community/regexpp": "^4.6.1",
67
67
  "@eslint/eslintrc": "^2.1.4",
68
- "@eslint/js": "8.56.0",
69
- "@humanwhocodes/config-array": "^0.11.13",
68
+ "@eslint/js": "8.57.0",
69
+ "@humanwhocodes/config-array": "^0.11.14",
70
70
  "@humanwhocodes/module-importer": "^1.0.1",
71
71
  "@nodelib/fs.walk": "^1.2.8",
72
72
  "@ungap/structured-clone": "^1.2.0",
@@ -122,7 +122,7 @@
122
122
  "eslint-plugin-eslint-plugin": "^5.2.1",
123
123
  "eslint-plugin-internal-rules": "file:tools/internal-rules",
124
124
  "eslint-plugin-jsdoc": "^46.2.5",
125
- "eslint-plugin-n": "^16.4.0",
125
+ "eslint-plugin-n": "^16.6.0",
126
126
  "eslint-plugin-unicorn": "^49.0.0",
127
127
  "eslint-release": "^3.2.0",
128
128
  "eslump": "^3.0.0",