Skip to content

Commit

Permalink
Add last N node versions (with major) support (browserslist#671)
Browse files Browse the repository at this point in the history
* Add `last N node versions` (with major) support

* Update tests

* Update docs
  • Loading branch information
g-plane authored and zhouyu9527 committed Jul 4, 2022
1 parent 4cf912d commit b70a56d
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 24 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -242,6 +242,8 @@ You can specify the browser and Node.js versions by queries (case insensitive):
* Node.js versions:
* `node 10` and `node 10.4`: selects latest Node.js `10.x.x`
or `10.4.x` release.
* `last 2 node versions`: select 2 latest Node.js releases.
* `last 2 node major versions`: select 2 latest major-version Node.js releases.
* `current node`: Node.js version used by Browserslist right now.
* `maintained node versions`: all Node.js versions, which are [still maintained]
by Node.js Foundation.
Expand Down
3 changes: 3 additions & 0 deletions grammar.w3c-ebnf
Expand Up @@ -46,6 +46,8 @@ LastBrowsers ::= 'last' Space+ Digit+ Space+ (BrowserName Space+)? ('major' Spac

LastElectron ::= 'last' Space+ Digit+ Space+ 'electron' Space+ ('major' Space+)? VersionKeyword

LastNode ::= 'last' Space+ Digit+ Space+ 'node' Space+ ('major' Space+)? VersionKeyword

Unreleased ::= 'unreleased' Space+ ((BrowserName | 'electron') Space+)? VersionKeyword

Years ::= 'last' Space+ Numeric Space+ 'year' 's'?
Expand Down Expand Up @@ -96,6 +98,7 @@ Dead ::= 'dead'

QueryAtom ::= LastBrowsers
| LastElectron
| LastNode
| Unreleased
| Years
| Since
Expand Down
2 changes: 2 additions & 0 deletions index.d.ts
Expand Up @@ -102,6 +102,8 @@ declare namespace browserslist {
| undefined
}

let nodeVersions: string[]

interface Usage {
[version: string]: number
}
Expand Down
53 changes: 29 additions & 24 deletions index.js
Expand Up @@ -19,8 +19,8 @@ function isVersionsMatch(versionA, versionB) {

function isEolReleased(name) {
var version = name.slice(1)
return jsReleases.some(function (i) {
return isVersionsMatch(i.version, version)
return browserslist.nodeVersions.some(function (i) {
return isVersionsMatch(i, version)
})
}

Expand Down Expand Up @@ -617,11 +617,8 @@ browserslist.coverage = function (browsers, stats) {
}

function nodeQuery(context, version) {
var nodeReleases = jsReleases.filter(function (i) {
return i.name === 'nodejs'
})
var matched = nodeReleases.filter(function (i) {
return isVersionsMatch(i.version, version)
var matched = browserslist.nodeVersions.filter(function (i) {
return isVersionsMatch(i, version)
})
if (matched.length === 0) {
if (context.ignoreUnknownVersions) {
Expand All @@ -630,7 +627,7 @@ function nodeQuery(context, version) {
throw new BrowserslistError('Unknown version ' + version + ' of Node.js')
}
}
return ['node ' + matched[matched.length - 1].version]
return ['node ' + matched[matched.length - 1]]
}

function sinceQuery(context, year, month, date) {
Expand Down Expand Up @@ -716,6 +713,16 @@ var QUERIES = [
})
}
},
{
regexp: /^last\s+(\d+)\s+node\s+major\s+versions?$/i,
select: function (context, versions) {
return getMajorVersions(browserslist.nodeVersions, versions).map(
function (version) {
return 'node ' + version
}
)
}
},
{
regexp: /^last\s+(\d+)\s+(\w+)\s+major\s+versions?$/i,
select: function (context, versions, name) {
Expand All @@ -738,6 +745,14 @@ var QUERIES = [
})
}
},
{
regexp: /^last\s+(\d+)\s+node\s+versions?$/i,
select: function (context, versions) {
return browserslist.nodeVersions.slice(-versions).map(function (version) {
return 'node ' + version
})
}
},
{
regexp: /^last\s+(\d+)\s+(\w+)\s+versions?$/i,
select: function (context, versions, name) {
Expand Down Expand Up @@ -980,14 +995,7 @@ var QUERIES = [
{
regexp: /^node\s+([\d.]+)\s*-\s*([\d.]+)$/i,
select: function (context, from, to) {
var nodeVersions = jsReleases
.filter(function (i) {
return i.name === 'nodejs'
})
.map(function (i) {
return i.version
})
return nodeVersions
return browserslist.nodeVersions
.filter(semverFilterLoose('>=', from))
.filter(semverFilterLoose('<=', to))
.map(function (v) {
Expand Down Expand Up @@ -1022,14 +1030,7 @@ var QUERIES = [
{
regexp: /^node\s*(>=?|<=?)\s*([\d.]+)$/i,
select: function (context, sign, version) {
var nodeVersions = jsReleases
.filter(function (i) {
return i.name === 'nodejs'
})
.map(function (i) {
return i.version
})
return nodeVersions
return browserslist.nodeVersions
.filter(generateSemverFilter(sign, version))
.map(function (v) {
return 'node ' + v
Expand Down Expand Up @@ -1225,6 +1226,10 @@ var QUERIES = [
}

browserslist.versionAliases.op_mob['59'] = '58'

browserslist.nodeVersions = jsReleases.map(function (release) {
return release.version
})
})()

module.exports = browserslist
34 changes: 34 additions & 0 deletions test/node.test.js
Expand Up @@ -343,4 +343,38 @@ test('supports range selection', () => {
)
})

test('supports last versions for Node.js', () => {
is(browserslist('last 2 node versions').length >= 1, true)

browserslist.nodeVersions = ['16.0.0', '16.1.0', '17.0.0', '17.1.0']
equal(browserslist('last 3 node versions'), [
'node 17.1.0',
'node 17.0.0',
'node 16.1.0'
])
})

test('supports last major versions for Node.js', () => {
is(browserslist('last 2 node major versions').length >= 1, true)

browserslist.nodeVersions = [
'14.0.0',
'14.1.0',
'15.0.0',
'15.1.0',
'16.0.0',
'16.1.0',
'17.0.0',
'17.1.0'
]
equal(browserslist('last 3 node major versions'), [
'node 17.1.0',
'node 17.0.0',
'node 16.1.0',
'node 16.0.0',
'node 15.1.0',
'node 15.0.0'
])
})

test.run()

0 comments on commit b70a56d

Please sign in to comment.