@@ -15,51 +15,56 @@ const semverRangeSubset = require("semver/ranges/subset")
1515 * Parses the options.
1616 * @param {import('eslint').Rule.RuleContext } context The rule context.
1717 * @returns {Readonly<{
18- * version: import('semver').Range,
19- * ignores: Set<string>
18+ * version: import('semver').Range;
19+ * ignores: Set<string>;
20+ * allowExperimental: boolean;
2021 * }>} Parsed value.
2122 */
2223function parseOptions ( context ) {
2324 const raw = context . options [ 0 ] || { }
2425 const version = getConfiguredNodeVersion ( context )
2526 const ignores = new Set ( raw . ignores || [ ] )
27+ const allowExperimental = raw . allowExperimental ?? false
2628
27- return Object . freeze ( { version, ignores } )
29+ return Object . freeze ( { version, ignores, allowExperimental } )
2830}
2931
3032/**
3133 * 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 }
3437 */
35- function isSupported ( { supported } , configured ) {
36- if ( supported == null || supported . length === 0 ) {
38+ function isInRange ( featureRange , requestedRange ) {
39+ if ( featureRange == null || featureRange . length === 0 ) {
3740 return false
3841 }
3942
40- const [ latest ] = rsort ( supported )
43+ const [ latest ] = rsort ( featureRange )
4144 const range = getSemverRange (
42- [ ...supported . map ( version => `^${ version } ` ) , `>= ${ latest } ` ] . join ( "||" )
45+ [ ...featureRange . map ( version => `^${ version } ` ) , `>= ${ latest } ` ] . join (
46+ "||"
47+ )
4348 )
4449
4550 if ( range == null ) {
4651 return false
4752 }
4853
49- return semverRangeSubset ( configured , range )
54+ return semverRangeSubset ( requestedRange , range )
5055}
5156
5257/**
5358 * 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.
5560 * @returns {string | undefined }
5661 */
57- function supportedVersionToString ( { supported } ) {
58- if ( supported == null || supported . length === 0 ) {
62+ function versionsToString ( versions ) {
63+ if ( versions == null ) {
5964 return
6065 }
6166
62- const [ latest , ...backported ] = rsort ( supported )
67+ const [ latest , ...backported ] = rsort ( versions )
6368
6469 if ( backported . length === 0 ) {
6570 return latest
@@ -92,27 +97,66 @@ module.exports.checkUnsupportedBuiltins = function checkUnsupportedBuiltins(
9297
9398 for ( const { node, path, info } of references ) {
9499 const name = unprefixNodeColon ( path . join ( "." ) )
95- const supported = isSupported ( info , options . version )
96100
97- if ( supported === true || options . ignores . has ( name ) ) {
101+ if ( options . ignores . has ( name ) ) {
98102 continue
99103 }
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+
101143 context . report ( {
102144 node,
103- messageId : supportedVersion
104- ? "not-supported-till"
105- : "not-supported-yet" ,
145+ messageId : "not-supported-yet" ,
106146 data : {
107147 name : path . join ( "." ) ,
108- supported : /** @type string */ ( supportedVersion ) ,
109148 version : options . version . raw ,
110149 } ,
111150 } )
112151 }
113152}
114153
115154exports . 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 ( " " ) ,
116160 "not-supported-till" : [
117161 "The '{{name}}' is still an experimental feature" ,
118162 "and is not supported until Node.js {{supported}}." ,
0 commit comments