var bbm = require('baseline-browser-mapping') var jsReleases = require('node-releases/data/processed/envs.json') var agents = require('caniuse-lite/dist/unpacker/agents').agents var e2c = require('electron-to-chromium/versions') var jsEOL = require('node-releases/data/release-schedule/release-schedule.json') var path = require('path') var BrowserslistError = require('./error') var env = require('./node') var parseWithoutCache = require('./parse') // Will load browser.js in webpack var YEAR = 365.259641 * 24 * 60 * 60 * 1000 var ANDROID_EVERGREEN_FIRST = '37' var OP_MOB_BLINK_FIRST = 14 var FIREFOX_ESR_VERSION = '140' // Helpers function isVersionsMatch(versionA, versionB) { return (versionA + '.').indexOf(versionB + '.') === 0 } function isEolReleased(name) { var version = name.slice(1) return browserslist.nodeVersions.some(function (i) { return isVersionsMatch(i, version) }) } function normalize(versions) { return versions.filter(function (version) { return typeof version === 'string' }) } function normalizeElectron(version) { var versionToUse = version if (version.split('.').length === 3) { versionToUse = version.split('.').slice(0, -1).join('.') } return versionToUse } function nameMapper(name) { return function mapName(version) { return name + ' ' + version } } function getMajor(version) { return parseInt(version.split('.')[0]) } function getMajorVersions(released, number) { if (released.length === 0) return [] var majorVersions = uniq(released.map(getMajor)) var minimum = majorVersions[majorVersions.length - number] if (!minimum) { return released } var selected = [] for (var i = released.length - 1; i >= 0; i--) { if (minimum > getMajor(released[i])) break selected.unshift(released[i]) } return selected } function uniq(array) { var filtered = [] for (var i = 0; i < array.length; i++) { if (filtered.indexOf(array[i]) === -1) filtered.push(array[i]) } return filtered } function fillUsage(result, name, data) { for (var i in data) { result[name + ' ' + i] = data[i] } } function generateFilter(sign, version) { version = parseFloat(version) if (sign === '>') { return function (v) { return parseLatestFloat(v) > version } } else if (sign === '>=') { return function (v) { return parseLatestFloat(v) >= version } } else if (sign === '<') { return function (v) { return parseFloat(v) < version } } else { return function (v) { return parseFloat(v) <= version } } function parseLatestFloat(v) { return parseFloat(v.split('-')[1] || v) } } function generateSemverFilter(sign, version) { version = version.split('.').map(parseSimpleInt) version[1] = version[1] || 0 version[2] = version[2] || 0 if (sign === '>') { return function (v) { v = v.split('.').map(parseSimpleInt) return compareSemver(v, version) > 0 } } else if (sign === '>=') { return function (v) { v = v.split('.').map(parseSimpleInt) return compareSemver(v, version) >= 0 } } else if (sign === '<') { return function (v) { v = v.split('.').map(parseSimpleInt) return compareSemver(version, v) > 0 } } else { return function (v) { v = v.split('.').map(parseSimpleInt) return compareSemver(version, v) >= 0 } } } function parseSimpleInt(x) { return parseInt(x) } function compare(a, b) { if (a < b) return -1 if (a > b) return +1 return 0 } function compareSemver(a, b) { return ( compare(parseInt(a[0]), parseInt(b[0])) || compare(parseInt(a[1] || '0'), parseInt(b[1] || '0')) || compare(parseInt(a[2] || '0'), parseInt(b[2] || '0')) ) } // this follows the npm-like semver behavior function semverFilterLoose(operator, range) { range = range.split('.').map(parseSimpleInt) if (typeof range[1] === 'undefined') { range[1] = 'x' } // ignore any patch version because we only return minor versions // range[2] = 'x' switch (operator) { case '<=': return function (version) { version = version.split('.').map(parseSimpleInt) return compareSemverLoose(version, range) <= 0 } case '>=': default: return function (version) { version = version.split('.').map(parseSimpleInt) return compareSemverLoose(version, range) >= 0 } } } // this follows the npm-like semver behavior function compareSemverLoose(version, range) { if (version[0] !== range[0]) { return version[0] < range[0] ? -1 : +1 } if (range[1] === 'x') { return 0 } if (version[1] !== range[1]) { return version[1] < range[1] ? -1 : +1 } return 0 } function resolveVersion(data, version) { if (data.versions.indexOf(version) !== -1) { return version } else if (browserslist.versionAliases[data.name][version]) { return browserslist.versionAliases[data.name][version] } else { return false } } function normalizeVersion(data, version) { var resolved = resolveVersion(data, version) if (resolved) { return resolved } else if (data.versions.length === 1) { return data.versions[0] } else { return false } } function filterByYear(since, context) { since = since / 1000 return Object.keys(agents).reduce(function (selected, name) { var data = byName(name, context) if (!data) return selected var versions = Object.keys(data.releaseDate).filter(function (v) { var date = data.releaseDate[v] return date !== null && date >= since }) return selected.concat(versions.map(nameMapper(data.name