@@ -28,6 +28,104 @@ const messageId = "preferNodeProtocol"
2828const supportedRangeForEsm = new Range ( "^12.20.0 || >= 14.13.1" )
2929const supportedRangeForCjs = new Range ( "^14.18.0 || >= 16.0.0" )
3030
31+ /**
32+ * @param {import('estree').Node } [node]
33+ * @returns {node is import('estree').Literal }
34+ */
35+ function isStringLiteral ( node ) {
36+ return node ?. type === "Literal" && typeof node . type === "string"
37+ }
38+
39+ /**
40+ * @param {import('eslint').Rule.RuleContext } context
41+ * @param {import('../util/import-target.js').ModuleStyle } moduleStyle
42+ * @returns {boolean }
43+ */
44+ function isEnablingThisRule ( context , moduleStyle ) {
45+ const version = getConfiguredNodeVersion ( context )
46+
47+ // Only check Node.js version because this rule is meaningless if configured Node.js version doesn't match semver range.
48+ if ( ! version . intersects ( supportedRangeForEsm ) ) {
49+ return false
50+ }
51+
52+ // Only check when using `require`
53+ if (
54+ moduleStyle === "require" &&
55+ ! version . intersects ( supportedRangeForCjs )
56+ ) {
57+ return false
58+ }
59+
60+ return true
61+ }
62+
63+ /**
64+ * @param {import('estree').Node } node
65+ * @returns {boolean }
66+ **/
67+ function isValidRequireArgument ( node ) {
68+ const rawName = getStringIfConstant ( node )
69+ if ( typeof rawName !== "string" ) {
70+ return false
71+ }
72+
73+ const name = stripImportPathParams ( rawName )
74+ if ( ! isBuiltin ( name ) ) {
75+ return false
76+ }
77+
78+ return true
79+ }
80+
81+ /**
82+ * @param {import('estree').Node | null | undefined } node
83+ * @param {import('eslint').Rule.RuleContext } context
84+ * @param {import('../util/import-target.js').ModuleStyle } moduleStyle
85+ */
86+ function validate ( node , context , moduleStyle ) {
87+ if ( node == null ) {
88+ return
89+ }
90+
91+ if ( ! isEnablingThisRule ( context , moduleStyle ) ) {
92+ return
93+ }
94+
95+ if ( ! isStringLiteral ( node ) ) {
96+ return
97+ }
98+
99+ if ( moduleStyle === "require" && ! isValidRequireArgument ( node ) ) {
100+ return
101+ }
102+
103+ if (
104+ ! ( "value" in node ) ||
105+ typeof node . value !== "string" ||
106+ node . value . startsWith ( "node:" ) ||
107+ ! isBuiltin ( node . value ) ||
108+ ! isBuiltin ( `node:${ node . value } ` )
109+ ) {
110+ return
111+ }
112+
113+ context . report ( {
114+ node,
115+ messageId,
116+ data : {
117+ moduleName : node . value ,
118+ } ,
119+ fix ( fixer ) {
120+ const firstCharacterIndex = ( node ?. range ?. [ 0 ] ?? 0 ) + 1
121+ return fixer . replaceTextRange (
122+ [ firstCharacterIndex , firstCharacterIndex ] ,
123+ "node:"
124+ )
125+ } ,
126+ } )
127+ }
128+
31129/** @type {import('eslint').Rule.RuleModule } */
32130module . exports = {
33131 meta : {
@@ -53,104 +151,6 @@ module.exports = {
53151 type : "suggestion" ,
54152 } ,
55153 create ( context ) {
56- /**
57- * @param {import('estree').Node } [node]
58- * @returns {node is import('estree').Literal }
59- */
60- function isStringLiteral ( node ) {
61- return node ?. type === "Literal" && typeof node . type === "string"
62- }
63-
64- /**
65- * @param {import('eslint').Rule.RuleContext } context
66- * @param {import('../util/import-target.js').ModuleStyle } moduleStyle
67- * @returns {boolean }
68- */
69- function isEnablingThisRule ( context , moduleStyle ) {
70- const version = getConfiguredNodeVersion ( context )
71-
72- // Only check Node.js version because this rule is meaningless if configured Node.js version doesn't match semver range.
73- if ( ! version . intersects ( supportedRangeForEsm ) ) {
74- return false
75- }
76-
77- // Only check when using `require`
78- if (
79- moduleStyle === "require" &&
80- ! version . intersects ( supportedRangeForCjs )
81- ) {
82- return false
83- }
84-
85- return true
86- }
87-
88- /**
89- * @param {import('estree').Node } node
90- * @returns {boolean }
91- **/
92- function isValidRequireArgument ( node ) {
93- const rawName = getStringIfConstant ( node )
94- if ( typeof rawName !== "string" ) {
95- return false
96- }
97-
98- const name = stripImportPathParams ( rawName )
99- if ( ! isBuiltin ( name ) ) {
100- return false
101- }
102-
103- return true
104- }
105-
106- /**
107- * @param {import('estree').Node | null | undefined } node
108- * @param {import('eslint').Rule.RuleContext } context
109- * @param {import('../util/import-target.js').ModuleStyle } moduleStyle
110- */
111- function validate ( node , context , moduleStyle ) {
112- if ( node == null ) {
113- return
114- }
115-
116- if ( ! isEnablingThisRule ( context , moduleStyle ) ) {
117- return
118- }
119-
120- if ( ! isStringLiteral ( node ) ) {
121- return
122- }
123-
124- if ( moduleStyle === "require" && ! isValidRequireArgument ( node ) ) {
125- return
126- }
127-
128- if (
129- ! ( "value" in node ) ||
130- typeof node . value !== "string" ||
131- node . value . startsWith ( "node:" ) ||
132- ! isBuiltin ( node . value ) ||
133- ! isBuiltin ( `node:${ node . value } ` )
134- ) {
135- return
136- }
137-
138- context . report ( {
139- node,
140- messageId,
141- data : {
142- moduleName : node . value ,
143- } ,
144- fix ( fixer ) {
145- const firstCharacterIndex = ( node ?. range ?. [ 0 ] ?? 0 ) + 1
146- return fixer . replaceTextRange (
147- [ firstCharacterIndex , firstCharacterIndex ] ,
148- "node:"
149- )
150- } ,
151- } )
152- }
153-
154154 return {
155155 CallExpression ( node ) {
156156 if ( node . type !== "CallExpression" ) {
0 commit comments