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.
- package/lib/configs/_commons.js +5 -2
- package/lib/eslint-utils.d.ts +1 -4
- package/lib/index.js +34 -34
- package/lib/rules/callback-return.js +4 -8
- package/lib/rules/exports-style.js +49 -42
- package/lib/rules/file-extension-in-import.js +23 -19
- package/lib/rules/global-require.js +2 -2
- package/lib/rules/no-callback-literal.js +4 -6
- package/lib/rules/no-deprecated-api.js +10 -18
- package/lib/rules/no-hide-core-modules.js +0 -3
- package/lib/rules/no-mixed-requires.js +12 -16
- package/lib/rules/no-path-concat.js +37 -29
- package/lib/rules/no-unsupported-features/es-syntax.js +16 -7
- package/lib/rules/prefer-node-protocol.js +11 -14
- package/lib/rules/prefer-promises/dns.js +32 -22
- package/lib/rules/prefer-promises/fs.js +5 -1
- package/lib/unsupported-features/node-builtins-modules/assert.js +7 -2
- package/lib/unsupported-features/node-builtins-modules/async_hooks.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/buffer.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/child_process.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/cluster.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/console.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/crypto.js +9 -3
- package/lib/unsupported-features/node-builtins-modules/dgram.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/diagnostics_channel.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/dns.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/domain.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/events.js +9 -3
- package/lib/unsupported-features/node-builtins-modules/fs.js +15 -5
- package/lib/unsupported-features/node-builtins-modules/http.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/http2.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/https.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/inspector.js +12 -4
- package/lib/unsupported-features/node-builtins-modules/module.js +8 -2
- package/lib/unsupported-features/node-builtins-modules/net.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/os.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/path.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/perf_hooks.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/process.js +19 -2
- package/lib/unsupported-features/node-builtins-modules/punycode.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/querystring.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/readline.js +9 -3
- package/lib/unsupported-features/node-builtins-modules/repl.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/sea.js +10 -5
- package/lib/unsupported-features/node-builtins-modules/sqlite.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/stream.js +21 -9
- package/lib/unsupported-features/node-builtins-modules/string_decoder.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/test.js +8 -3
- package/lib/unsupported-features/node-builtins-modules/timers.js +9 -3
- package/lib/unsupported-features/node-builtins-modules/tls.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/trace_events.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/tty.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/url.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/util.js +14 -5
- package/lib/unsupported-features/node-builtins-modules/v8.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/vm.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/wasi.js +6 -2
- package/lib/unsupported-features/node-builtins-modules/worker_threads.js +7 -2
- package/lib/unsupported-features/node-builtins-modules/zlib.js +6 -2
- package/lib/unsupported-features/node-builtins.js +3 -2
- package/lib/unsupported-features/node-globals.js +14 -6
- package/lib/util/check-existence.js +0 -3
- package/lib/util/check-extraneous.js +5 -7
- package/lib/util/check-publish.js +0 -3
- package/lib/util/extend-trackmap-with-node-prefix.js +1 -1
- package/lib/util/get-configured-node-version.js +12 -5
- package/lib/util/has-parent-node.js +18 -0
- package/lib/util/import-target.js +20 -19
- package/lib/util/map-typescript-extension.js +12 -2
- package/lib/util/merge-visitors-in-place.js +1 -2
- package/lib/util/visit-import.js +2 -1
- package/lib/util/visit-require.js +4 -0
- package/package.json +28 -28
- package/types/index.d.ts +14 -37
package/lib/configs/_commons.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict"
|
|
2
2
|
|
|
3
|
-
|
|
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
|
+
}
|
package/lib/eslint-utils.d.ts
CHANGED
|
@@ -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 {
|
|
21
|
-
const
|
|
10
|
+
/** @type {ESLint.Plugin} */
|
|
11
|
+
const base = {
|
|
22
12
|
meta: {
|
|
23
13
|
name: pkg.name,
|
|
24
14
|
version: pkg.version,
|
|
25
15
|
},
|
|
26
|
-
rules:
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
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
|
|
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]
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
|
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:
|
|
317
|
-
|
|
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
|
-
|
|
99
|
-
|
|
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
|
-
|
|
118
|
+
/** @type {import('eslint').Rule.ReportDescriptor} */
|
|
119
|
+
const descriptor = {
|
|
117
120
|
node,
|
|
118
121
|
messageId: "forbidExt",
|
|
119
122
|
data: { ext: currentExt },
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
71
|
-
|
|
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
|
-
|
|
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
|
|
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('
|
|
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
|
-
({
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
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
|
})
|
|
@@ -172,19 +172,18 @@ module.exports = {
|
|
|
172
172
|
return inferModuleType(initExpression.object)
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
if (
|
|
176
|
-
|
|
177
|
-
|
|
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 =
|
|
184
|
-
initExpression
|
|
185
|
-
).arguments[0]
|
|
184
|
+
const arg = initExpression.arguments[0]
|
|
186
185
|
|
|
187
|
-
if (arg
|
|
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 (
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
|