aboutsummaryrefslogtreecommitdiff
path: root/node_modules/browserslist/node.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/browserslist/node.js')
-rw-r--r--node_modules/browserslist/node.js318
1 files changed, 318 insertions, 0 deletions
diff --git a/node_modules/browserslist/node.js b/node_modules/browserslist/node.js
new file mode 100644
index 0000000..d080075
--- /dev/null
+++ b/node_modules/browserslist/node.js
@@ -0,0 +1,318 @@
+var region = require('caniuse-lite/dist/unpacker/region').default
+var path = require('path')
+var fs = require('fs')
+
+var BrowserslistError = require('./error')
+
+var IS_SECTION = /^\s*\[(.+)\]\s*$/
+var CONFIG_PATTERN = /^browserslist-config-/
+var SCOPED_CONFIG__PATTERN = /@[^/]+\/browserslist-config(-|$|\/)/
+var TIME_TO_UPDATE_CANIUSE = 6 * 30 * 24 * 60 * 60 * 1000
+var FORMAT = 'Browserslist config should be a string or an array ' +
+ 'of strings with browser queries'
+
+var dataTimeChecked = false
+var filenessCache = { }
+var configCache = { }
+function checkExtend (name) {
+ var use = ' Use `dangerousExtend` option to disable.'
+ if (!CONFIG_PATTERN.test(name) && !SCOPED_CONFIG__PATTERN.test(name)) {
+ throw new BrowserslistError(
+ 'Browserslist config needs `browserslist-config-` prefix. ' + use)
+ }
+ if (name.replace(/^@[^/]+\//, '').indexOf('.') !== -1) {
+ throw new BrowserslistError(
+ '`.` not allowed in Browserslist config name. ' + use)
+ }
+ if (name.indexOf('node_modules') !== -1) {
+ throw new BrowserslistError(
+ '`node_modules` not allowed in Browserslist config.' + use)
+ }
+}
+
+function isFile (file) {
+ if (file in filenessCache) {
+ return filenessCache[file]
+ }
+ var result = fs.existsSync(file) && fs.statSync(file).isFile()
+ if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
+ filenessCache[file] = result
+ }
+ return result
+}
+
+function eachParent (file, callback) {
+ var loc = path.resolve(file)
+ do {
+ var result = callback(loc)
+ if (typeof result !== 'undefined') return result
+ } while (loc !== (loc = path.dirname(loc)))
+ return undefined
+}
+
+function check (section) {
+ if (Array.isArray(section)) {
+ for (var i = 0; i < section.length; i++) {
+ if (typeof section[i] !== 'string') {
+ throw new BrowserslistError(FORMAT)
+ }
+ }
+ } else if (typeof section !== 'string') {
+ throw new BrowserslistError(FORMAT)
+ }
+}
+
+function pickEnv (config, opts) {
+ if (typeof config !== 'object') return config
+
+ var name
+ if (typeof opts.env === 'string') {
+ name = opts.env
+ } else if (process.env.BROWSERSLIST_ENV) {
+ name = process.env.BROWSERSLIST_ENV
+ } else if (process.env.NODE_ENV) {
+ name = process.env.NODE_ENV
+ } else {
+ name = 'production'
+ }
+
+ return config[name] || config.defaults
+}
+
+function parsePackage (file) {
+ var config = JSON.parse(fs.readFileSync(file))
+ if (config.browserlist && !config.browserslist) {
+ throw new BrowserslistError(
+ '`browserlist` key instead of `browserslist` in ' + file)
+ }
+ var list = config.browserslist
+ if (Array.isArray(list) || typeof list === 'string') {
+ list = { defaults: list }
+ }
+ for (var i in list) {
+ check(list[i])
+ }
+
+ return list
+}
+
+function latestReleaseTime (agents) {
+ var latest = 0
+ for (var name in agents) {
+ var dates = agents[name].releaseDate || { }
+ for (var key in dates) {
+ if (latest < dates[key]) {
+ latest = dates[key]
+ }
+ }
+ }
+ return latest * 1000
+}
+
+module.exports = {
+ loadQueries: function loadQueries (context, name) {
+ if (!context.dangerousExtend) checkExtend(name)
+ // eslint-disable-next-line security/detect-non-literal-require
+ var queries = require(require.resolve(name, { paths: ['.'] }))
+ if (!Array.isArray(queries)) {
+ throw new BrowserslistError(
+ '`' + name + '` config exports not an array of queries')
+ }
+ return queries
+ },
+
+ getStat: function getStat (opts, data) {
+ var stats
+ if (opts.stats) {
+ stats = opts.stats
+ } else if (process.env.BROWSERSLIST_STATS) {
+ stats = process.env.BROWSERSLIST_STATS
+ } else if (opts.path && path.resolve && fs.existsSync) {
+ stats = eachParent(opts.path, function (dir) {
+ var file = path.join(dir, 'browserslist-stats.json')
+ return isFile(file) ? file : undefined
+ })
+ }
+
+ if (typeof stats === 'string') {
+ try {
+ stats = JSON.parse(fs.readFileSync(stats))
+ } catch (e) {
+ throw new BrowserslistError('Can\'t read ' + stats)
+ }
+ }
+
+ if (stats && 'dataByBrowser' in stats) {
+ stats = stats.dataByBrowser
+ }
+
+ if (typeof stats !== 'object') return undefined
+
+ var normalized = { }
+ for (var i in stats) {
+ var versions = Object.keys(stats[i])
+ if (versions.length === 1 && data[i] && data[i].versions.length === 1) {
+ var normal = Object.keys(data[i].versions)[0]
+ normalized[i] = { }
+ normalized[i][normal] = stats[i][versions[0]]
+ } else {
+ normalized[i] = stats[i]
+ }
+ }
+
+ return normalized
+ },
+
+ loadConfig: function loadConfig (opts) {
+ if (process.env.BROWSERSLIST) {
+ return process.env.BROWSERSLIST
+ } else if (opts.config || process.env.BROWSERSLIST_CONFIG) {
+ var file = opts.config || process.env.BROWSERSLIST_CONFIG
+ if (path.basename(file) === 'package.json') {
+ return pickEnv(parsePackage(file), opts)
+ } else {
+ return pickEnv(module.exports.readConfig(file), opts)
+ }
+ } else if (opts.path) {
+ return pickEnv(module.exports.findConfig(opts.path), opts)
+ } else {
+ return undefined
+ }
+ },
+
+ loadCountry: function loadCountry (usage, country) {
+ var code = country.replace(/[^\w-]/g, '')
+ if (!usage[code]) {
+ // eslint-disable-next-line security/detect-non-literal-require
+ var compressed = require('caniuse-lite/data/regions/' + code + '.js')
+ var data = region(compressed)
+ usage[country] = { }
+ for (var i in data) {
+ for (var j in data[i]) {
+ usage[country][i + ' ' + j] = data[i][j]
+ }
+ }
+ }
+ },
+
+ parseConfig: function parseConfig (string) {
+ var result = { defaults: [] }
+ var sections = ['defaults']
+
+ string.toString()
+ .replace(/#[^\n]*/g, '')
+ .split(/\n|,/)
+ .map(function (line) {
+ return line.trim()
+ })
+ .filter(function (line) {
+ return line !== ''
+ })
+ .forEach(function (line) {
+ if (IS_SECTION.test(line)) {
+ sections = line.match(IS_SECTION)[1].trim().split(' ')
+ sections.forEach(function (section) {
+ if (result[section]) {
+ throw new BrowserslistError(
+ 'Duplicate section ' + section + ' in Browserslist config')
+ }
+ result[section] = []
+ })
+ } else {
+ sections.forEach(function (section) {
+ result[section].push(line)
+ })
+ }
+ })
+
+ return result
+ },
+
+ readConfig: function readConfig (file) {
+ if (!isFile(file)) {
+ throw new BrowserslistError('Can\'t read ' + file + ' config')
+ }
+ return module.exports.parseConfig(fs.readFileSync(file))
+ },
+
+ findConfig: function findConfig (from) {
+ from = path.resolve(from)
+
+ var cacheKey = isFile(from) ? path.dirname(from) : from
+ if (cacheKey in configCache) {
+ return configCache[cacheKey]
+ }
+
+ var resolved = eachParent(from, function (dir) {
+ var config = path.join(dir, 'browserslist')
+ var pkg = path.join(dir, 'package.json')
+ var rc = path.join(dir, '.browserslistrc')
+
+ var pkgBrowserslist
+ if (isFile(pkg)) {
+ try {
+ pkgBrowserslist = parsePackage(pkg)
+ } catch (e) {
+ if (e.name === 'BrowserslistError') throw e
+ console.warn(
+ '[Browserslist] Could not parse ' + pkg + '. Ignoring it.')
+ }
+ }
+
+ if (isFile(config) && pkgBrowserslist) {
+ throw new BrowserslistError(
+ dir + ' contains both browserslist and package.json with browsers')
+ } else if (isFile(rc) && pkgBrowserslist) {
+ throw new BrowserslistError(
+ dir + ' contains both .browserslistrc and package.json with browsers')
+ } else if (isFile(config) && isFile(rc)) {
+ throw new BrowserslistError(
+ dir + ' contains both .browserslistrc and browserslist')
+ } else if (isFile(config)) {
+ return module.exports.readConfig(config)
+ } else if (isFile(rc)) {
+ return module.exports.readConfig(rc)
+ } else {
+ return pkgBrowserslist
+ }
+ })
+ if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
+ configCache[cacheKey] = resolved
+ }
+ return resolved
+ },
+
+ clearCaches: function clearCaches () {
+ dataTimeChecked = false
+ filenessCache = { }
+ configCache = { }
+ },
+
+ oldDataWarning: function oldDataWarning (agentsObj) {
+ if (dataTimeChecked) return
+ dataTimeChecked = true
+ if (process.env.BROWSERSLIST_IGNORE_OLD_DATA) return
+
+ var latest = latestReleaseTime(agentsObj)
+ var halfYearAgo = Date.now() - TIME_TO_UPDATE_CANIUSE
+
+ if (latest !== 0 && latest < halfYearAgo) {
+ var command = 'npm update'
+ eachParent(__filename, function (dir) {
+ var pckg = path.join(dir, 'package.json')
+ var yarnLock = path.join(dir, 'yarn.lock')
+ if (isFile(pckg) && isFile(yarnLock)) {
+ command = 'yarn upgrade'
+ }
+ })
+ console.warn(
+ 'Browserslist: caniuse-lite is outdated. ' +
+ 'Please run next command `' + command + '`'
+ )
+ }
+ },
+
+ currentNode: function currentNode () {
+ return 'node ' + process.versions.node
+ }
+}