@@ -15,51 +15,56 @@ const semverRangeSubset = require("semver/ranges/subset")
15
15
* Parses the options.
16
16
* @param {import('eslint').Rule.RuleContext } context The rule context.
17
17
* @returns {Readonly<{
18
- * version: import('semver').Range,
19
- * ignores: Set<string>
18
+ * version: import('semver').Range;
19
+ * ignores: Set<string>;
20
+ * allowExperimental: boolean;
20
21
* }>} Parsed value.
21
22
*/
22
23
function parseOptions ( context ) {
23
24
const raw = context . options [ 0 ] || { }
24
25
const version = getConfiguredNodeVersion ( context )
25
26
const ignores = new Set ( raw . ignores || [ ] )
27
+ const allowExperimental = raw . allowExperimental ?? false
26
28
27
- return Object . freeze ( { version, ignores } )
29
+ return Object . freeze ( { version, ignores, allowExperimental } )
28
30
}
29
31
30
32
/**
31
33
* Check if it has been supported.
32
- * @param {import('../unsupported-features/types.js').SupportInfo } info The support info.
33
- * @param {import('semver').Range } configured The configured version range.
34
+ * @param {string[] | undefined } featureRange The target features supported range
35
+ * @param {import('semver').Range } requestedRange The configured version range.
36
+ * @returns {boolean }
34
37
*/
35
- function isSupported ( { supported } , configured ) {
36
- if ( supported == null || supported . length === 0 ) {
38
+ function isInRange ( featureRange , requestedRange ) {
39
+ if ( featureRange == null || featureRange . length === 0 ) {
37
40
return false
38
41
}
39
42
40
- const [ latest ] = rsort ( supported )
43
+ const [ latest ] = rsort ( featureRange )
41
44
const range = getSemverRange (
42
- [ ...supported . map ( version => `^${ version } ` ) , `>= ${ latest } ` ] . join ( "||" )
45
+ [ ...featureRange . map ( version => `^${ version } ` ) , `>= ${ latest } ` ] . join (
46
+ "||"
47
+ )
43
48
)
44
49
45
50
if ( range == null ) {
46
51
return false
47
52
}
48
53
49
- return semverRangeSubset ( configured , range )
54
+ return semverRangeSubset ( requestedRange , range )
50
55
}
51
56
52
57
/**
53
58
* Get the formatted text of a given supported version.
54
- * @param {import('../unsupported-features/types.js').SupportInfo } info The support info.
59
+ * @param {string[] | undefined } versions The support info.
55
60
* @returns {string | undefined }
56
61
*/
57
- function supportedVersionToString ( { supported } ) {
58
- if ( supported == null || supported . length === 0 ) {
62
+ function versionsToString ( versions ) {
63
+ if ( versions == null ) {
59
64
return
60
65
}
61
66
62
- const [ latest , ...backported ] = rsort ( supported )
67
+ const [ latest , ...backported ] = rsort ( versions )
63
68
64
69
if ( backported . length === 0 ) {
65
70
return latest
@@ -92,27 +97,66 @@ module.exports.checkUnsupportedBuiltins = function checkUnsupportedBuiltins(
92
97
93
98
for ( const { node, path, info } of references ) {
94
99
const name = unprefixNodeColon ( path . join ( "." ) )
95
- const supported = isSupported ( info , options . version )
96
100
97
- if ( supported === true || options . ignores . has ( name ) ) {
101
+ if ( options . ignores . has ( name ) ) {
98
102
continue
99
103
}
100
- const supportedVersion = supportedVersionToString ( info )
104
+
105
+ if ( options . allowExperimental ) {
106
+ if ( isInRange ( info . experimental , options . version ) ) {
107
+ continue
108
+ }
109
+
110
+ const experimentalVersion = versionsToString ( info . experimental )
111
+ if ( experimentalVersion ) {
112
+ context . report ( {
113
+ node,
114
+ messageId : "not-experimental-till" ,
115
+ data : {
116
+ name : path . join ( "." ) ,
117
+ experimental : experimentalVersion ,
118
+ version : options . version . raw ,
119
+ } ,
120
+ } )
121
+ continue
122
+ }
123
+ }
124
+
125
+ if ( isInRange ( info . supported , options . version ) ) {
126
+ continue
127
+ }
128
+
129
+ const supportedVersion = versionsToString ( info . supported )
130
+ if ( supportedVersion ) {
131
+ context . report ( {
132
+ node,
133
+ messageId : "not-supported-till" ,
134
+ data : {
135
+ name : path . join ( "." ) ,
136
+ supported : supportedVersion ,
137
+ version : options . version . raw ,
138
+ } ,
139
+ } )
140
+ continue
141
+ }
142
+
101
143
context . report ( {
102
144
node,
103
- messageId : supportedVersion
104
- ? "not-supported-till"
105
- : "not-supported-yet" ,
145
+ messageId : "not-supported-yet" ,
106
146
data : {
107
147
name : path . join ( "." ) ,
108
- supported : /** @type string */ ( supportedVersion ) ,
109
148
version : options . version . raw ,
110
149
} ,
111
150
} )
112
151
}
113
152
}
114
153
115
154
exports . messages = {
155
+ "not-experimental-till" : [
156
+ "The '{{name}}' is not an experimental feature" ,
157
+ "until Node.js {{experimental}}." ,
158
+ "The configured version range is '{{version}}'." ,
159
+ ] . join ( " " ) ,
116
160
"not-supported-till" : [
117
161
"The '{{name}}' is still an experimental feature" ,
118
162
"and is not supported until Node.js {{supported}}." ,
0 commit comments