diff --git a/index.js b/index.js index 67692907..fe0cf058 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,9 @@ var path = require('path') var e2c = require('electron-to-chromium/versions') +var nodeReleases = require('node-releases/data/processed/envs.json') +var nodeReleaseSchedule = require( + 'node-releases/data/release-schedule/release-schedule.json' +) var agents = require('caniuse-lite/dist/unpacker/agents').agents @@ -668,6 +672,55 @@ var QUERIES = [ return ['chrome ' + chrome] } }, + { + regexp: /^node\s+((\d+\.?){0,2}\d+)$/i, + select: function (context, version) { + var targetNodeRelease = nodeReleases + .reduce(function (latestNodeRelease, nodeRelease) { + if (nodeRelease.name !== 'nodejs') { + return latestNodeRelease + } + if ((nodeRelease.version + '.').indexOf(version + '.') !== 0) { + return latestNodeRelease + } + if (!latestNodeRelease) { + return nodeRelease + } + var latestNodeReleaseSegments = latestNodeRelease.version.split('.') + var nodeReleaseSegments = nodeRelease.version.split('.') + for (var i = 0; i < latestNodeReleaseSegments.length; i++) { + if (latestNodeReleaseSegments[i] === nodeReleaseSegments[i]) { + continue + } + if (+nodeReleaseSegments[i] > +latestNodeReleaseSegments[i]) { + latestNodeRelease = nodeRelease + } + break + } + return latestNodeRelease + }, null) + if (targetNodeRelease) { + return 'node ' + targetNodeRelease.version + } + if (context.ignoreUnknownVersions) { + return [] + } + throw new BrowserslistError('Unknown version ' + version + ' of Node.js') + } + }, + { + regexp: /^maintained\s+node\s+versions$/i, + select: function () { + var maintainedNodeVersions = [] + var dateNow = Date.now() + for (var version in nodeReleaseSchedule) { + if (dateNow < Date.parse(nodeReleaseSchedule[version].end)) { + maintainedNodeVersions.push('node ' + version.slice(1)) + } + } + return maintainedNodeVersions + } + }, { regexp: /^(\w+)\s+(tp|[\d.]+)$/i, select: function (context, name, version) { diff --git a/package.json b/package.json index 9871c3f1..024079b2 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "repository": "browserslist/browserslist", "dependencies": { "caniuse-lite": "^1.0.30000853", - "electron-to-chromium": "^1.3.48" + "electron-to-chromium": "^1.3.48", + "node-releases": "^1.0.0-alpha.10" }, "bin": "./cli.js", "devDependencies": { diff --git a/test/node.test.js b/test/node.test.js new file mode 100644 index 00000000..a408daa0 --- /dev/null +++ b/test/node.test.js @@ -0,0 +1,67 @@ +var browserslist = require('../') + +describe('Node.js versions', () => { + it('selects Node.js version', () => { + expect(browserslist('node 7.5.0')).toEqual(['node 7.5.0']) + }) + + it('supports case insensitive Node.js name', () => { + expect(browserslist('Node 7.5.0')).toEqual(['node 7.5.0']) + }) + + it('throws on unknown Node.js version', () => { + expect(() => { + browserslist('node 7.5.7') + }).toThrowError(/Unknown version/) + }) + + it('return empty array on unknown Node.js version with special flag', () => { + expect(browserslist('node 7.5.7', { + ignoreUnknownVersions: true + })).toEqual([]) + }) + + it('supports selection of Node.js version by major.minor query', () => { + expect(browserslist('node 5.1')).toEqual(['node 5.1.0']) + }) + + it('supports selection of Node.js version by major version only', () => { + expect(browserslist('node 5')).toEqual(['node 5.12.0']) + }) + + it('returns latest version from unordered list', () => { + jest.resetModules() + jest.doMock('node-releases/data/processed/envs.json', () => { + return [ + { + 'name': 'nodejs', + 'version': '5.10.0', + 'date': '2016-04-01', + 'lts': false + }, + { + 'name': 'nodejs', + 'version': '5.12.0', + 'date': '2016-06-23', + 'lts': false + }, + { + 'name': 'nodejs', + 'version': '5.11.0', + 'date': '2016-04-21', + 'lts': false + } + ] + }) + var browserslistWithMocks = require('../') + expect(browserslistWithMocks('node 5')).toEqual(['node 5.12.0']) + }) + + it('selects maintained Node.js versions', () => { + expect(Array.isArray(browserslist('maintained node versions'))).toBe(true) + }) + + it('supports case insensitive query for maintained Node.js versions', () => { + expect(Array.isArray(browserslist('maintained Node versions'))).toBe(true) + }) +}) diff --git a/yarn.lock b/yarn.lock index 70a5a857..aede8558 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3927,6 +3927,12 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" +node-releases@^1.0.0-alpha.10: + version "1.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.10.tgz#61c8d5f9b5b2e05d84eba941d05b6f5202f68a2a" + dependencies: + semver "^5.3.0" + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"