| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 | 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 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.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 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 = 'development'  }  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 (typeof list === 'object' && list.length) {    list = { defaults: list }  }  return list}module.exports = {  loadQueries: function loadQueries (context, name) {    if (!context.dangerousExtend) checkExtend(name)    // eslint-disable-next-line security/detect-non-literal-require    var queries = require(name)    if (!Array.isArray(queries)) {      throw new BrowserslistError(        '`' + name + '` config exports not an array of queries')    }    return queries  },  getStat: function getStat (opts) {    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)      }    }    return stats  },  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    }  },  parseConfig: function parseConfig (string) {    var result = { defaults: [] }    var section = '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)) {          section = line.match(IS_SECTION)[1].trim()          result[section] = result[section] || []        } else {          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 () {    filenessCache = { }    configCache = { }  }}
 |