eslint-plugin-n 17.11.0 → 17.12.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 (74) hide show
  1. package/lib/configs/_commons.js +5 -2
  2. package/lib/eslint-utils.d.ts +1 -4
  3. package/lib/index.js +34 -34
  4. package/lib/rules/callback-return.js +4 -8
  5. package/lib/rules/exports-style.js +49 -42
  6. package/lib/rules/file-extension-in-import.js +23 -19
  7. package/lib/rules/global-require.js +2 -2
  8. package/lib/rules/no-callback-literal.js +4 -6
  9. package/lib/rules/no-deprecated-api.js +10 -18
  10. package/lib/rules/no-hide-core-modules.js +0 -3
  11. package/lib/rules/no-mixed-requires.js +12 -16
  12. package/lib/rules/no-path-concat.js +37 -29
  13. package/lib/rules/no-unsupported-features/es-syntax.js +16 -7
  14. package/lib/rules/prefer-node-protocol.js +11 -14
  15. package/lib/rules/prefer-promises/dns.js +32 -22
  16. package/lib/rules/prefer-promises/fs.js +5 -1
  17. package/lib/unsupported-features/node-builtins-modules/assert.js +7 -2
  18. package/lib/unsupported-features/node-builtins-modules/async_hooks.js +6 -2
  19. package/lib/unsupported-features/node-builtins-modules/buffer.js +6 -2
  20. package/lib/unsupported-features/node-builtins-modules/child_process.js +6 -2
  21. package/lib/unsupported-features/node-builtins-modules/cluster.js +6 -2
  22. package/lib/unsupported-features/node-builtins-modules/console.js +6 -2
  23. package/lib/unsupported-features/node-builtins-modules/crypto.js +9 -3
  24. package/lib/unsupported-features/node-builtins-modules/dgram.js +6 -2
  25. package/lib/unsupported-features/node-builtins-modules/diagnostics_channel.js +6 -2
  26. package/lib/unsupported-features/node-builtins-modules/dns.js +6 -2
  27. package/lib/unsupported-features/node-builtins-modules/domain.js +6 -2
  28. package/lib/unsupported-features/node-builtins-modules/events.js +9 -3
  29. package/lib/unsupported-features/node-builtins-modules/fs.js +15 -5
  30. package/lib/unsupported-features/node-builtins-modules/http.js +6 -2
  31. package/lib/unsupported-features/node-builtins-modules/http2.js +6 -2
  32. package/lib/unsupported-features/node-builtins-modules/https.js +6 -2
  33. package/lib/unsupported-features/node-builtins-modules/inspector.js +12 -4
  34. package/lib/unsupported-features/node-builtins-modules/module.js +8 -2
  35. package/lib/unsupported-features/node-builtins-modules/net.js +6 -2
  36. package/lib/unsupported-features/node-builtins-modules/os.js +6 -2
  37. package/lib/unsupported-features/node-builtins-modules/path.js +6 -2
  38. package/lib/unsupported-features/node-builtins-modules/perf_hooks.js +6 -2
  39. package/lib/unsupported-features/node-builtins-modules/process.js +19 -2
  40. package/lib/unsupported-features/node-builtins-modules/punycode.js +6 -2
  41. package/lib/unsupported-features/node-builtins-modules/querystring.js +6 -2
  42. package/lib/unsupported-features/node-builtins-modules/readline.js +9 -3
  43. package/lib/unsupported-features/node-builtins-modules/repl.js +6 -2
  44. package/lib/unsupported-features/node-builtins-modules/sea.js +10 -5
  45. package/lib/unsupported-features/node-builtins-modules/sqlite.js +6 -2
  46. package/lib/unsupported-features/node-builtins-modules/stream.js +21 -9
  47. package/lib/unsupported-features/node-builtins-modules/string_decoder.js +6 -2
  48. package/lib/unsupported-features/node-builtins-modules/test.js +8 -3
  49. package/lib/unsupported-features/node-builtins-modules/timers.js +9 -3
  50. package/lib/unsupported-features/node-builtins-modules/tls.js +6 -2
  51. package/lib/unsupported-features/node-builtins-modules/trace_events.js +6 -2
  52. package/lib/unsupported-features/node-builtins-modules/tty.js +6 -2
  53. package/lib/unsupported-features/node-builtins-modules/url.js +6 -2
  54. package/lib/unsupported-features/node-builtins-modules/util.js +14 -5
  55. package/lib/unsupported-features/node-builtins-modules/v8.js +6 -2
  56. package/lib/unsupported-features/node-builtins-modules/vm.js +6 -2
  57. package/lib/unsupported-features/node-builtins-modules/wasi.js +6 -2
  58. package/lib/unsupported-features/node-builtins-modules/worker_threads.js +7 -2
  59. package/lib/unsupported-features/node-builtins-modules/zlib.js +6 -2
  60. package/lib/unsupported-features/node-builtins.js +3 -2
  61. package/lib/unsupported-features/node-globals.js +14 -6
  62. package/lib/util/check-existence.js +0 -3
  63. package/lib/util/check-extraneous.js +5 -7
  64. package/lib/util/check-publish.js +0 -3
  65. package/lib/util/extend-trackmap-with-node-prefix.js +1 -1
  66. package/lib/util/get-configured-node-version.js +12 -5
  67. package/lib/util/has-parent-node.js +18 -0
  68. package/lib/util/import-target.js +20 -19
  69. package/lib/util/map-typescript-extension.js +12 -2
  70. package/lib/util/merge-visitors-in-place.js +1 -2
  71. package/lib/util/visit-import.js +2 -1
  72. package/lib/util/visit-require.js +4 -0
  73. package/package.json +28 -28
  74. package/types/index.d.ts +14 -37
@@ -1,6 +1,9 @@
1
1
  "use strict"
2
2
 
3
- module.exports.commonRules = /** @type {const} */ ({
3
+ /**
4
+ * @type {import('eslint').Linter.RulesRecord}
5
+ */
6
+ module.exports.commonRules = {
4
7
  "n/no-deprecated-api": "error",
5
8
  "n/no-extraneous-import": "error",
6
9
  "n/no-extraneous-require": "error",
@@ -16,4 +19,4 @@ module.exports.commonRules = /** @type {const} */ ({
16
19
  "n/no-unsupported-features/node-builtins": "error",
17
20
  "n/process-exit-as-throw": "error",
18
21
  "n/hashbang": "error",
19
- })
22
+ }
@@ -1,12 +1,9 @@
1
1
  declare module "eslint-plugin-es-x" {
2
- // @ts-ignore
3
2
  export const rules: NonNullable<import('eslint').ESLint.Plugin["rules"]>;
4
3
  }
5
4
 
6
5
  declare module "@eslint-community/eslint-utils" {
7
- // @ts-ignore
8
6
  import * as estree from 'estree';
9
- // @ts-ignore
10
7
  import * as eslint from 'eslint';
11
8
 
12
9
  type Node = estree.Node | estree.Expression;
@@ -39,7 +36,7 @@ declare module "@eslint-community/eslint-utils" {
39
36
  [READ]?: Info;
40
37
  [CALL]?: Info;
41
38
  [CONSTRUCT]?: Info;
42
- [key: string]: TraceMap<Info>;
39
+ [key: string]: TraceMap<Info> | undefined;
43
40
  }
44
41
  type RichNode = eslint.Rule.Node | Node;
45
42
  type Reference<Info extends unknown> = {
package/lib/index.js CHANGED
@@ -5,25 +5,15 @@ const esmConfig = require("./configs/recommended-module")
5
5
  const cjsConfig = require("./configs/recommended-script")
6
6
  const recommendedConfig = require("./configs/recommended")
7
7
 
8
- /**
9
- * @typedef {{
10
- 'recommended-module': import('eslint').ESLint.ConfigData;
11
- 'recommended-script': import('eslint').ESLint.ConfigData;
12
- 'recommended': import('eslint').ESLint.ConfigData;
13
- 'flat/recommended-module': import('eslint').Linter.FlatConfig;
14
- 'flat/recommended-script': import('eslint').Linter.FlatConfig;
15
- 'flat/recommended': import('eslint').Linter.FlatConfig;
16
- 'flat/mixed-esm-and-cjs': import('eslint').Linter.FlatConfig[];
17
- }} Configs
18
- */
8
+ /** @import { ESLint, Linter } from 'eslint' */
19
9
 
20
- /** @type {import('eslint').ESLint.Plugin & { configs: Configs }} */
21
- const plugin = {
10
+ /** @type {ESLint.Plugin} */
11
+ const base = {
22
12
  meta: {
23
13
  name: pkg.name,
24
14
  version: pkg.version,
25
15
  },
26
- rules: /** @type {Record<string, import('eslint').Rule.RuleModule>} */ ({
16
+ rules: {
27
17
  "callback-return": require("./rules/callback-return"),
28
18
  "exports-style": require("./rules/exports-style"),
29
19
  "file-extension-in-import": require("./rules/file-extension-in-import"),
@@ -66,28 +56,38 @@ const plugin = {
66
56
  // Deprecated rules.
67
57
  "no-hide-core-modules": require("./rules/no-hide-core-modules"),
68
58
  shebang: require("./rules/shebang"),
69
- }),
70
- configs: {
71
- "recommended-module": { plugins: ["n"], ...esmConfig.eslintrc },
72
- "recommended-script": { plugins: ["n"], ...cjsConfig.eslintrc },
73
- recommended: { plugins: ["n"], ...recommendedConfig.eslintrc },
74
- "flat/recommended-module": { ...esmConfig.flat },
75
- "flat/recommended-script": { ...cjsConfig.flat },
76
- "flat/recommended": { ...recommendedConfig.flat },
77
- "flat/mixed-esm-and-cjs": [
78
- { files: ["**/*.js"], ...recommendedConfig.flat },
79
- { files: ["**/*.mjs"], ...esmConfig.flat },
80
- { files: ["**/*.cjs"], ...cjsConfig.flat },
81
- ],
82
59
  },
83
60
  }
61
+ /**
62
+ * @typedef {{
63
+ * 'recommended-module': ESLint.ConfigData;
64
+ * 'recommended-script': ESLint.ConfigData;
65
+ * 'recommended': ESLint.ConfigData;
66
+ * 'flat/recommended-module': Linter.Config;
67
+ * 'flat/recommended-script': Linter.Config;
68
+ * 'flat/recommended': Linter.Config;
69
+ * 'flat/mixed-esm-and-cjs': Linter.Config[];
70
+ * }} Configs
71
+ */
84
72
 
85
- plugin.configs["flat/recommended-module"].plugins = { n: plugin }
86
- plugin.configs["flat/recommended-script"].plugins = { n: plugin }
87
- plugin.configs["flat/recommended"].plugins = { n: plugin }
88
-
89
- for (const config of plugin.configs["flat/mixed-esm-and-cjs"]) {
90
- config.plugins = { n: plugin }
73
+ /** @type {Configs} */
74
+ const configs = {
75
+ "recommended-module": { plugins: ["n"], ...esmConfig.eslintrc },
76
+ "recommended-script": { plugins: ["n"], ...cjsConfig.eslintrc },
77
+ recommended: { plugins: ["n"], ...recommendedConfig.eslintrc },
78
+ "flat/recommended-module": { plugins: { n: base }, ...esmConfig.flat },
79
+ "flat/recommended-script": { plugins: { n: base }, ...cjsConfig.flat },
80
+ "flat/recommended": { plugins: { n: base }, ...recommendedConfig.flat },
81
+ "flat/mixed-esm-and-cjs": [
82
+ { files: ["**/*.js"], plugins: { n: base }, ...recommendedConfig.flat },
83
+ { files: ["**/*.mjs"], plugins: { n: base }, ...esmConfig.flat },
84
+ { files: ["**/*.cjs"], plugins: { n: base }, ...cjsConfig.flat },
85
+ ],
91
86
  }
92
87
 
93
- module.exports = plugin
88
+ /** @type {ESLint.Plugin & { configs: Configs }} */
89
+ module.exports = {
90
+ meta: base.meta,
91
+ rules: base.rules,
92
+ configs: configs,
93
+ }
@@ -82,7 +82,7 @@ module.exports = {
82
82
  /**
83
83
  * Determines whether or not the callback is part of a callback expression.
84
84
  * @param {import('eslint').Rule.Node} node The callback node
85
- * @param {import('estree').Statement} parentNode The expression node
85
+ * @param {import('estree').Statement} [parentNode] The expression node
86
86
  * @returns {boolean} Whether or not this is part of a callback expression
87
87
  */
88
88
  function isCallbackExpression(node, parentNode) {
@@ -136,8 +136,7 @@ module.exports = {
136
136
  // block statements are part of functions and most if statements
137
137
  if (closestBlock?.type === "BlockStatement") {
138
138
  // find the last item in the block
139
- const lastItem =
140
- closestBlock.body[closestBlock.body.length - 1]
139
+ const lastItem = closestBlock.body.at(-1)
141
140
 
142
141
  // if the callback is the last thing in a block that might be ok
143
142
  if (isCallbackExpression(node, lastItem)) {
@@ -154,13 +153,10 @@ module.exports = {
154
153
  }
155
154
 
156
155
  // ending a block with a return is also ok
157
- if (lastItem.type === "ReturnStatement") {
156
+ if (lastItem?.type === "ReturnStatement") {
158
157
  // but only if the callback is immediately before
159
158
  if (
160
- isCallbackExpression(
161
- node,
162
- closestBlock.body[closestBlock.body.length - 2]
163
- )
159
+ isCallbackExpression(node, closestBlock.body.at(-2))
164
160
  ) {
165
161
  return
166
162
  }
@@ -4,15 +4,13 @@
4
4
  */
5
5
  "use strict"
6
6
 
7
- /**
8
- * @typedef {import('estree').Node & { parent?: Node }} Node
9
- */
7
+ const { hasParentNode } = require("../util/has-parent-node.js")
10
8
 
11
9
  /*istanbul ignore next */
12
10
  /**
13
11
  * This function is copied from https://github.com/eslint/eslint/blob/2355f8d0de1d6732605420d15ddd4f1eee3c37b6/lib/ast-utils.js#L648-L684
14
12
  *
15
- * @param {Node} node - The node to get.
13
+ * @param {import('estree').Node} node - The node to get.
16
14
  * @returns {string | null | undefined} The property name if static. Otherwise, null.
17
15
  * @private
18
16
  */
@@ -39,17 +37,12 @@ function getStaticPropertyName(node) {
39
37
 
40
38
  case "TemplateLiteral":
41
39
  if (prop.expressions.length === 0 && prop.quasis.length === 1) {
42
- return prop.quasis[0].value.cooked
40
+ return prop.quasis[0]?.value.cooked
43
41
  }
44
42
  break
45
43
 
46
44
  case "Identifier":
47
- if (
48
- !(
49
- /** @type {import('estree').MemberExpression} */ (node)
50
- .computed
51
- )
52
- ) {
45
+ if (node.type === "MemberExpression" && node.computed === false) {
53
46
  return prop.name
54
47
  }
55
48
  break
@@ -63,11 +56,12 @@ function getStaticPropertyName(node) {
63
56
  /**
64
57
  * Checks whether the given node is assignee or not.
65
58
  *
66
- * @param {Node} node - The node to check.
59
+ * @param {import('estree').Node} node - The node to check.
67
60
  * @returns {boolean} `true` if the node is assignee.
68
61
  */
69
62
  function isAssignee(node) {
70
63
  return (
64
+ hasParentNode(node) &&
71
65
  node.parent?.type === "AssignmentExpression" &&
72
66
  node.parent.left === node
73
67
  )
@@ -79,15 +73,16 @@ function isAssignee(node) {
79
73
  * This is used to distinguish 2 assignees belong to the same assignment.
80
74
  * If the node is not an assignee, this returns null.
81
75
  *
82
- * @param {Node} leafNode - The node to get.
83
- * @returns {Node|null} The top assignment expression node, or null.
76
+ * @param {import('estree').Node} leafNode - The node to get.
77
+ * @returns {import('estree').Node | null} The top assignment expression node, or null.
84
78
  */
85
79
  function getTopAssignment(leafNode) {
86
80
  let node = leafNode
87
81
 
88
82
  // Skip MemberExpressions.
89
83
  while (
90
- node.parent?.type === "MemberExpression" &&
84
+ hasParentNode(node) &&
85
+ node.parent.type === "MemberExpression" &&
91
86
  node.parent.object === node
92
87
  ) {
93
88
  node = node.parent
@@ -99,7 +94,7 @@ function getTopAssignment(leafNode) {
99
94
  }
100
95
 
101
96
  // Find the top.
102
- while (node.parent?.type === "AssignmentExpression") {
97
+ while (hasParentNode(node) && node.parent.type === "AssignmentExpression") {
103
98
  node = node.parent
104
99
  }
105
100
 
@@ -109,35 +104,41 @@ function getTopAssignment(leafNode) {
109
104
  /**
110
105
  * Gets top assignment nodes of the given node list.
111
106
  *
112
- * @param {Node[]} nodes - The node list to get.
113
- * @returns {Node[]} Gotten top assignment nodes.
107
+ * @param {import('estree').Node[]} nodes - The node list to get.
108
+ * @returns {import('estree').Node[]} Gotten top assignment nodes.
114
109
  */
115
110
  function createAssignmentList(nodes) {
116
- return /** @type {Node[]} */ (nodes.map(getTopAssignment).filter(Boolean))
111
+ return nodes.map(getTopAssignment).filter(input => input != null)
117
112
  }
118
113
 
119
114
  /**
120
115
  * Gets the reference of `module.exports` from the given scope.
121
116
  *
122
117
  * @param {import('eslint').Scope.Scope} scope - The scope to get.
123
- * @returns {Node[]} Gotten MemberExpression node list.
118
+ * @returns {import('estree').Node[]} Gotten MemberExpression node list.
124
119
  */
125
120
  function getModuleExportsNodes(scope) {
126
121
  const variable = scope.set.get("module")
127
122
  if (variable == null) {
128
123
  return []
129
124
  }
130
- return variable.references
131
- .map(
132
- reference =>
133
- /** @type {Node & { parent: Node }} */ (reference.identifier)
134
- .parent
135
- )
136
- .filter(
137
- node =>
138
- node?.type === "MemberExpression" &&
139
- getStaticPropertyName(node) === "exports"
140
- )
125
+
126
+ /** @type {import('estree').Node[]} */
127
+ const nodes = []
128
+
129
+ for (const reference of variable.references) {
130
+ if (hasParentNode(reference.identifier) === false) {
131
+ continue
132
+ }
133
+ const node = reference.identifier.parent
134
+ if (
135
+ node.type === "MemberExpression" &&
136
+ getStaticPropertyName(node) === "exports"
137
+ ) {
138
+ nodes.push(node)
139
+ }
140
+ }
141
+ return nodes
141
142
  }
142
143
 
143
144
  /**
@@ -156,7 +157,7 @@ function getExportsNodes(scope) {
156
157
  }
157
158
 
158
159
  /**
159
- * @param {Node} property
160
+ * @param {import('estree').Node} property
160
161
  * @param {import('eslint').SourceCode} sourceCode
161
162
  * @returns {string | null}
162
163
  */
@@ -210,13 +211,16 @@ function getReplacementForProperty(property, sourceCode) {
210
211
 
211
212
  /**
212
213
  * Check for a top level module.exports = { ... }
213
- * @param {Node} node
214
+ * @param {import('estree').Node} node
214
215
  * @returns {node is {parent: import('estree').AssignmentExpression & {parent: import('estree').ExpressionStatement, right: import('estree').ObjectExpression}}}
215
216
  */
216
217
  function isModuleExportsObjectAssignment(node) {
217
218
  return (
219
+ hasParentNode(node) &&
218
220
  node.parent?.type === "AssignmentExpression" &&
221
+ hasParentNode(node.parent) &&
219
222
  node.parent?.parent?.type === "ExpressionStatement" &&
223
+ hasParentNode(node.parent.parent) &&
220
224
  node.parent.parent.parent?.type === "Program" &&
221
225
  node.parent.right.type === "ObjectExpression"
222
226
  )
@@ -224,17 +228,19 @@ function isModuleExportsObjectAssignment(node) {
224
228
 
225
229
  /**
226
230
  * Check for module.exports.foo or module.exports.bar reference or assignment
227
- * @param {Node} node
231
+ * @param {import('estree').Node} node
228
232
  * @returns {node is import('estree').MemberExpression}
229
233
  */
230
234
  function isModuleExportsReference(node) {
231
235
  return (
232
- node.parent?.type === "MemberExpression" && node.parent.object === node
236
+ hasParentNode(node) &&
237
+ node.parent?.type === "MemberExpression" &&
238
+ node.parent.object === node
233
239
  )
234
240
  }
235
241
 
236
242
  /**
237
- * @param {Node} node
243
+ * @param {import('estree').Node} node
238
244
  * @param {import('eslint').SourceCode} sourceCode
239
245
  * @param {import('eslint').Rule.RuleFixer} fixer
240
246
  * @returns {import('eslint').Rule.Fix | null}
@@ -307,16 +313,17 @@ module.exports = {
307
313
  * module.exports = foo
308
314
  * ^^^^^^^^^^^^^^^^
309
315
  *
310
- * @param {Node} node - The node of `exports`/`module.exports`.
311
- * @returns {import('estree').SourceLocation} The location info of reports.
316
+ * @param {import('estree').Node} node - The node of `exports`/`module.exports`.
317
+ * @returns {import('estree').SourceLocation | undefined} The location info of reports.
312
318
  */
313
319
  function getLocation(node) {
314
320
  const token = sourceCode.getTokenAfter(node)
321
+ if (node.loc?.start == null || token?.loc?.end == null) {
322
+ return
323
+ }
315
324
  return {
316
- start: /** @type {import('estree').SourceLocation} */ (node.loc)
317
- .start,
318
- end: /** @type {import('estree').SourceLocation} */ (token?.loc)
319
- ?.end,
325
+ start: node.loc?.start,
326
+ end: token?.loc?.end,
320
327
  }
321
328
  }
322
329
 
@@ -95,8 +95,11 @@ module.exports = {
95
95
  messageId: "requireExt",
96
96
  data: { ext: expectedExt },
97
97
  fix(fixer) {
98
- const index =
99
- /** @type {[number, number]} */ (node.range)[1] - 1
98
+ if (node.range == null) {
99
+ return null
100
+ }
101
+
102
+ const index = node.range[1] - 1
100
103
  return fixer.insertTextBeforeRange(
101
104
  [index, index],
102
105
  expectedExt
@@ -112,26 +115,27 @@ module.exports = {
112
115
  currentExt === expectedExt
113
116
  ) {
114
117
  const otherExtensions = getExistingExtensions(filePath)
115
-
116
- context.report({
118
+ /** @type {import('eslint').Rule.ReportDescriptor} */
119
+ const descriptor = {
117
120
  node,
118
121
  messageId: "forbidExt",
119
122
  data: { ext: currentExt },
120
- fix:
121
- otherExtensions.length > 1
122
- ? undefined
123
- : fixer => {
124
- const index = name.lastIndexOf(currentExt)
125
- const start =
126
- /** @type {[number, number]} */ (
127
- node.range
128
- )[0] +
129
- 1 +
130
- index
131
- const end = start + currentExt.length
132
- return fixer.removeRange([start, end])
133
- },
134
- })
123
+ }
124
+
125
+ if (otherExtensions.length === 1) {
126
+ descriptor.fix = fixer => {
127
+ if (node.range == null) {
128
+ return null
129
+ }
130
+
131
+ const index = name.lastIndexOf(currentExt)
132
+ const start = node.range[0] + 1 + index
133
+ const end = start + currentExt.length
134
+ return fixer.removeRange([start, end])
135
+ }
136
+ }
137
+
138
+ context.report(descriptor)
135
139
  }
136
140
  }
137
141
 
@@ -67,8 +67,8 @@ module.exports = {
67
67
  sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
68
68
 
69
69
  if (
70
- /** @type {import('estree').Identifier} */ (node.callee)
71
- .name === "require" &&
70
+ node.callee.type === "Identifier" &&
71
+ node.callee.name === "require" &&
72
72
  !isShadowed(currentScope, node.callee)
73
73
  ) {
74
74
  const isGoodRequire = (
@@ -28,14 +28,12 @@ module.exports = {
28
28
  return {
29
29
  CallExpression(node) {
30
30
  const errorArg = node.arguments[0]
31
- const calleeName = /** @type {import('estree').Identifier} */ (
32
- node.callee
33
- ).name
34
31
 
35
32
  if (
36
33
  errorArg &&
37
34
  !couldBeError(errorArg) &&
38
- callbackNames.includes(calleeName)
35
+ node.callee.type === "Identifier" &&
36
+ callbackNames.includes(node.callee.name)
39
37
  ) {
40
38
  context.report({
41
39
  node,
@@ -49,11 +47,11 @@ module.exports = {
49
47
 
50
48
  /**
51
49
  * Determine if a node has a possiblity to be an Error object
52
- * @param {import('estree').Node} node ASTNode to check
50
+ * @param {import('estree').Node} [node] ASTNode to check
53
51
  * @returns {boolean} True if there is a chance it contains an Error obj
54
52
  */
55
53
  function couldBeError(node) {
56
- switch (node.type) {
54
+ switch (node?.type) {
57
55
  case "Identifier":
58
56
  case "CallExpression":
59
57
  case "NewExpression":
@@ -23,7 +23,7 @@ const unprefixNodeColon = require("../util/unprefix-node-colon")
23
23
  * @property {Set<string>} ignoredGlobalItems
24
24
  * @property {Set<string>} ignoredModuleItems
25
25
  */
26
- /** @type {import('@eslint-community/eslint-utils').TraceMap<DeprecatedInfo>} */
26
+ /** @type {import('../unsupported-features/types.js').DeprecatedInfoTraceMap} */
27
27
  const rawModules = {
28
28
  _linklist: {
29
29
  [READ]: { since: "5.0.0", replacedBy: null },
@@ -330,12 +330,6 @@ const rawModules = {
330
330
  },
331
331
  },
332
332
  },
333
- nextTick: {
334
- [READ]: {
335
- since: "22.7.0",
336
- replacedBy: "'queueMicrotask()'",
337
- },
338
- },
339
333
  },
340
334
  punycode: {
341
335
  [READ]: {
@@ -631,6 +625,7 @@ const rawModules = {
631
625
  }
632
626
  const modules = extendTrackmapWithNodePrefix(rawModules)
633
627
 
628
+ /** @type {import('../unsupported-features/types.js').DeprecatedInfoTraceMap} */
634
629
  const globals = {
635
630
  Buffer: {
636
631
  [CONSTRUCT]: {
@@ -706,14 +701,14 @@ function toReplaceMessage(replacedBy, version) {
706
701
 
707
702
  if (Array.isArray(replacedBy)) {
708
703
  message = replacedBy
709
- .filter(
710
- ({ supported }) =>
711
- !version.intersects(
712
- /** @type {import('semver').Range} */ (
713
- getSemverRange(`<${supported}`)
714
- )
715
- )
716
- )
704
+ .filter(({ supported }) => {
705
+ const range = getSemverRange(`<${supported}`)
706
+ if (range == null) {
707
+ return false
708
+ }
709
+
710
+ return !version.intersects(range)
711
+ })
717
712
  .map(({ name }) => name)
718
713
  .join(" or ")
719
714
  }
@@ -820,9 +815,6 @@ module.exports = {
820
815
 
821
816
  context.report({
822
817
  node,
823
- loc: /** @type {NonNullable<import('estree').Node["loc"]>} */ (
824
- node.loc
825
- ),
826
818
  messageId,
827
819
  data,
828
820
  })
@@ -137,9 +137,6 @@ module.exports = {
137
137
 
138
138
  context.report({
139
139
  node: target.node,
140
- loc: /** @type {NonNullable<import('estree').Node["loc"]>} */ (
141
- target.node.loc
142
- ),
143
140
  messageId: "unexpectedImport",
144
141
  data: {
145
142
  name: path
@@ -172,19 +172,18 @@ module.exports = {
172
172
  return inferModuleType(initExpression.object)
173
173
  }
174
174
 
175
- if (
176
- /** @type {import('estree').CallExpression} */ (initExpression)
177
- .arguments.length === 0
178
- ) {
175
+ if (initExpression.type !== "CallExpression") {
176
+ return REQ_MODULE
177
+ }
178
+
179
+ if (initExpression.arguments.length === 0) {
179
180
  // "var x = require();"
180
181
  return REQ_COMPUTED
181
182
  }
182
183
 
183
- const arg = /** @type {import('estree').CallExpression} */ (
184
- initExpression
185
- ).arguments[0]
184
+ const arg = initExpression.arguments[0]
186
185
 
187
- if (arg.type !== "Literal" || typeof arg.value !== "string") {
186
+ if (arg?.type !== "Literal" || typeof arg.value !== "string") {
188
187
  // "var x = require(42);"
189
188
  return REQ_COMPUTED
190
189
  }
@@ -235,14 +234,11 @@ module.exports = {
235
234
  const found = {}
236
235
 
237
236
  for (const declaration of declarations) {
238
- if (getDeclarationType(declaration.init) === DECL_REQUIRE) {
239
- found[
240
- inferModuleType(
241
- /** @type {import('estree').Expression} */ (
242
- declaration.init
243
- )
244
- )
245
- ] = true
237
+ if (
238
+ declaration.init != null &&
239
+ getDeclarationType(declaration.init) === DECL_REQUIRE
240
+ ) {
241
+ found[inferModuleType(declaration.init)] = true
246
242
  }
247
243
  }
248
244