browserslist 2.10.2 → 2.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # Change Log
2
2
  This project adheres to [Semantic Versioning](http://semver.org/).
3
3
 
4
+ ## 2.11.3
5
+ * Fix for `path: undefined` option.
6
+
7
+ ## 2.11.2
8
+ * Remove Node.js specific code from webpack build.
9
+
10
+ ## 2.11.1
11
+ * Fix using Browserslist in browser with `path` but without `fs`.
12
+
13
+ ## 2.11
14
+ * Add `last 2 years` query support (by James Harris).
15
+
4
16
  ## 2.10.2
5
17
  * Fix Browserify support.
6
18
 
package/README.md CHANGED
@@ -8,7 +8,7 @@ It is used in:
8
8
 
9
9
  * [Autoprefixer]
10
10
  * [babel-preset-env]
11
- (external config in `package.json` or `browserslist` files supported in 2.0)
11
+ (external config in `package.json` or `browserslist` will be supported in 7.0)
12
12
  * [postcss-preset-env]
13
13
  * [eslint-plugin-compat]
14
14
  * [stylelint-no-unsupported-browser-features]
@@ -69,7 +69,7 @@ You can test Browserslist queries in [online demo].
69
69
  to match Browserslist target browsers query.
70
70
  * [`caniuse-api`] returns browsers which support some specific feature.
71
71
  * Run `npx browserslist` in your project directory to see project’s
72
- target browsers. This CLI tool is built-in and available in any project
72
+ target browsers. This CLI tool is built-in and available in any project
73
73
  with Autoprefixer.
74
74
 
75
75
  [`browserslist-useragent`]: https://github.com/pastelsky/browserslist-useragent
@@ -109,8 +109,8 @@ You can specify the versions by queries (case insensitive):
109
109
  alpha and beta versions.
110
110
  * `last 2 major versions` or `last 2 iOS major versions`:
111
111
  all minor/patch releases of last 2 major versions.
112
- * `since 2013`: all versions released since year 2013
113
- (also `since 2013-03` and `since 2013-03-10`).
112
+ * `since 2015` or `last 2 years`: all versions released since year 2015
113
+ (also `since 2015-03` and `since 2015-03-10`).
114
114
  * `not ie <= 8`: exclude browsers selected by previous queries.
115
115
 
116
116
  You can add `not ` to any query.
@@ -439,7 +439,7 @@ $ browserslist --coverage=US "> 1% in US"
439
439
  These browsers account for 83.1% of all users in the US
440
440
  ```
441
441
 
442
- ## Internal caches
442
+ ## Cache
443
443
 
444
444
  Browserslist caches the configuration it reads from `package.json` and
445
445
  `browserslist` files, as well as knowledge about the existence of files,
package/browser.js ADDED
@@ -0,0 +1,29 @@
1
+ var BrowserslistError = require('./error')
2
+
3
+ function noop () { }
4
+
5
+ module.exports = {
6
+ loadQueries: function loadQueries () {
7
+ throw new BrowserslistError(
8
+ 'Sharable configs are not supported in client-side build of Browserslist')
9
+ },
10
+
11
+ getStat: function getStat (opts) {
12
+ return opts.stats
13
+ },
14
+
15
+ loadConfig: function loadConfig (opts) {
16
+ if (opts.config) {
17
+ throw new BrowserslistError(
18
+ 'Browserslist config are not supported in client-side build')
19
+ }
20
+ },
21
+
22
+ parseConfig: noop,
23
+
24
+ readConfig: noop,
25
+
26
+ findConfig: noop,
27
+
28
+ clearCaches: noop
29
+ }
package/error.js ADDED
@@ -0,0 +1,12 @@
1
+ function BrowserslistError (message) {
2
+ this.name = 'BrowserslistError'
3
+ this.message = message || ''
4
+ this.browserslist = true
5
+ if (Error.captureStackTrace) {
6
+ Error.captureStackTrace(this, BrowserslistError)
7
+ }
8
+ }
9
+
10
+ BrowserslistError.prototype = Error.prototype
11
+
12
+ module.exports = BrowserslistError
package/index.js CHANGED
@@ -1,11 +1,14 @@
1
- var process = require('process')
2
1
  var path = require('path')
3
2
  var e2c = require('electron-to-chromium/versions')
4
- var fs = require('fs')
5
3
 
6
4
  var agents = require('caniuse-lite/dist/unpacker/agents').agents
7
5
  var region = require('caniuse-lite/dist/unpacker/region').default
8
6
 
7
+ var BrowserslistError = require('./error')
8
+ var env = require('./node') // Will load browser.js in webpack
9
+
10
+ var FLOAT_RANGE = /^\d+(\.\d+)?(-\d+(\.\d+)?)*$/
11
+
9
12
  function normalize (versions) {
10
13
  return versions.filter(function (version) {
11
14
  return typeof version === 'string'
@@ -33,11 +36,6 @@ function getMajorVersions (released, number) {
33
36
  return selected
34
37
  }
35
38
 
36
- var env = process && process.env ? process.env : { }
37
-
38
- var FLOAT_RANGE = /^\d+(\.\d+)?(-\d+(\.\d+)?)*$/
39
- var IS_SECTION = /^\s*\[(.+)\]\s*$/
40
-
41
39
  function uniq (array) {
42
40
  var filtered = []
43
41
  for (var i = 0; i < array.length; i++) {
@@ -46,16 +44,6 @@ function uniq (array) {
46
44
  return filtered
47
45
  }
48
46
 
49
- function BrowserslistError (message) {
50
- this.name = 'BrowserslistError'
51
- this.message = message || ''
52
- this.browserslist = true
53
- if (Error.captureStackTrace) {
54
- Error.captureStackTrace(this, BrowserslistError)
55
- }
56
- }
57
- BrowserslistError.prototype = Error.prototype
58
-
59
47
  // Helpers
60
48
 
61
49
  function fillUsage (result, name, data) {
@@ -64,74 +52,6 @@ function fillUsage (result, name, data) {
64
52
  }
65
53
  }
66
54
 
67
- var filenessCache = {}
68
- var configCache = {}
69
-
70
- function isFile (file) {
71
- if (file in filenessCache) {
72
- return filenessCache[file]
73
- }
74
- var result = fs.existsSync(file) && fs.statSync(file).isFile()
75
- if (!env.BROWSERSLIST_DISABLE_CACHE) {
76
- filenessCache[file] = result
77
- }
78
- return result
79
- }
80
-
81
- function eachParent (file, callback) {
82
- var loc = path.resolve(file)
83
- do {
84
- var result = callback(loc)
85
- if (typeof result !== 'undefined') return result
86
- } while (loc !== (loc = path.dirname(loc)))
87
- return undefined
88
- }
89
-
90
- function getStat (opts) {
91
- if (opts.stats) {
92
- return opts.stats
93
- } else if (env.BROWSERSLIST_STATS) {
94
- return env.BROWSERSLIST_STATS
95
- } else if (opts.path && path.resolve) {
96
- return eachParent(opts.path, function (dir) {
97
- var file = path.join(dir, 'browserslist-stats.json')
98
- return isFile(file) ? file : undefined
99
- })
100
- }
101
-
102
- return undefined
103
- }
104
-
105
- function parsePackage (file) {
106
- var config = JSON.parse(fs.readFileSync(file))
107
- if (config.browserlist && !config.browserslist) {
108
- throw new BrowserslistError(
109
- '`browserlist` key instead of `browserslist` in ' + file)
110
- }
111
- var list = config.browserslist
112
- if (typeof list === 'object' && list.length) {
113
- list = { defaults: list }
114
- }
115
- return list
116
- }
117
-
118
- function pickEnv (config, opts) {
119
- if (typeof config !== 'object') return config
120
-
121
- var name
122
- if (typeof opts.env === 'string') {
123
- name = opts.env
124
- } else if (env.BROWSERSLIST_ENV) {
125
- name = env.BROWSERSLIST_ENV
126
- } else if (env.NODE_ENV) {
127
- name = env.NODE_ENV
128
- } else {
129
- name = 'development'
130
- }
131
-
132
- return config[name] || config.defaults
133
- }
134
-
135
55
  function generateFilter (sign, version) {
136
56
  version = parseFloat(version)
137
57
  if (sign === '>') {
@@ -159,6 +79,55 @@ function compareStrings (a, b) {
159
79
  return 0
160
80
  }
161
81
 
82
+ function normalizeVersion (data, version) {
83
+ if (data.versions.indexOf(version) !== -1) {
84
+ return version
85
+ } else if (browserslist.versionAliases[data.name][version]) {
86
+ return browserslist.versionAliases[data.name][version]
87
+ } else if (data.versions.length === 1) {
88
+ return data.versions[0]
89
+ } else {
90
+ return false
91
+ }
92
+ }
93
+
94
+ function loadCountryStatistics (country) {
95
+ country = country.replace(/[^\w-]/g, '')
96
+ if (!browserslist.usage[country]) {
97
+ var usage = { }
98
+ // eslint-disable-next-line security/detect-non-literal-require
99
+ var compressed = require('caniuse-lite/data/regions/' + country + '.js')
100
+ var data = region(compressed)
101
+ for (var i in data) {
102
+ fillUsage(usage, i, data[i])
103
+ }
104
+ browserslist.usage[country] = usage
105
+ }
106
+ }
107
+
108
+ function filterByYear (since) {
109
+ return Object.keys(agents).reduce(function (selected, name) {
110
+ var data = byName(name)
111
+ if (!data) return selected
112
+ var versions = Object.keys(data.releaseDate).filter(function (v) {
113
+ return data.releaseDate[v] >= since
114
+ })
115
+ return selected.concat(versions.map(nameMapper(data.name)))
116
+ }, [])
117
+ }
118
+
119
+ function byName (name) {
120
+ name = name.toLowerCase()
121
+ name = browserslist.aliases[name] || name
122
+ return browserslist.data[name]
123
+ }
124
+
125
+ function checkName (name) {
126
+ var data = byName(name)
127
+ if (!data) throw new BrowserslistError('Unknown browser ' + name)
128
+ return data
129
+ }
130
+
162
131
  function resolve (queries, context) {
163
132
  return queries.reduce(function (result, selection, index) {
164
133
  selection = selection.trim()
@@ -222,24 +191,14 @@ function browserslist (queries, opts) {
222
191
  }
223
192
 
224
193
  if (typeof queries === 'undefined' || queries === null) {
225
- if (env.BROWSERSLIST) {
226
- queries = env.BROWSERSLIST
227
- } else if (opts.config || env.BROWSERSLIST_CONFIG) {
228
- var file = opts.config || env.BROWSERSLIST_CONFIG
229
- if (path.basename(file) === 'package.json') {
230
- queries = pickEnv(parsePackage(file), opts)
231
- } else {
232
- queries = pickEnv(browserslist.readConfig(file), opts)
233
- }
234
- } else if (opts.path) {
235
- queries = pickEnv(browserslist.findConfig(opts.path), opts)
194
+ var config = env.loadConfig(opts)
195
+ if (config) {
196
+ queries = config
197
+ } else {
198
+ queries = browserslist.defaults
236
199
  }
237
200
  }
238
201
 
239
- if (typeof queries === 'undefined' || queries === null) {
240
- queries = browserslist.defaults
241
- }
242
-
243
202
  if (typeof queries === 'string') {
244
203
  queries = queries.split(/,\s*/)
245
204
  }
@@ -251,19 +210,11 @@ function browserslist (queries, opts) {
251
210
 
252
211
  var context = { dangerousExtend: opts.dangerousExtend }
253
212
 
254
- var stats = getStat(opts)
213
+ var stats = env.getStat(opts)
255
214
  if (stats) {
256
- if (typeof stats === 'string') {
257
- try {
258
- stats = JSON.parse(fs.readFileSync(stats))
259
- } catch (e) {
260
- throw new BrowserslistError('Can\'t read ' + stats)
261
- }
262
- }
263
215
  if ('dataByBrowser' in stats) {
264
216
  stats = stats.dataByBrowser
265
217
  }
266
-
267
218
  context.customUsage = { }
268
219
  for (var browser in stats) {
269
220
  fillUsage(context.customUsage, browser, stats[browser])
@@ -296,32 +247,6 @@ function browserslist (queries, opts) {
296
247
  return uniq(result)
297
248
  }
298
249
 
299
- function normalizeVersion (data, version) {
300
- if (data.versions.indexOf(version) !== -1) {
301
- return version
302
- } else if (browserslist.versionAliases[data.name][version]) {
303
- return browserslist.versionAliases[data.name][version]
304
- } else if (data.versions.length === 1) {
305
- return data.versions[0]
306
- } else {
307
- return false
308
- }
309
- }
310
-
311
- function loadCountryStatistics (country) {
312
- country = country.replace(/[^\w-]/g, '')
313
- if (!browserslist.usage[country]) {
314
- var usage = { }
315
- // eslint-disable-next-line security/detect-non-literal-require
316
- var compressed = require('caniuse-lite/data/regions/' + country + '.js')
317
- var data = region(compressed)
318
- for (var i in data) {
319
- fillUsage(usage, i, data[i])
320
- }
321
- browserslist.usage[country] = usage
322
- }
323
- }
324
-
325
250
  // Will be filled by Can I Use data below
326
251
  browserslist.data = { }
327
252
  browserslist.usage = {
@@ -355,77 +280,10 @@ browserslist.aliases = {
355
280
  // Aliases to work with joined versions like `ios_saf 7.0-7.1`
356
281
  browserslist.versionAliases = { }
357
282
 
358
- // Get browser data by alias or case insensitive name
359
- function byName (name) {
360
- name = name.toLowerCase()
361
- name = browserslist.aliases[name] || name
362
- return browserslist.data[name]
363
- }
364
-
365
- // Get browser data by alias or case insensitive name and throw error
366
- // on unknown browser
367
- function checkName (name) {
368
- var data = byName(name)
369
- if (!data) throw new BrowserslistError('Unknown browser ' + name)
370
- return data
371
- }
372
-
373
- // Read and parse config
374
- browserslist.readConfig = function (file) {
375
- if (!isFile(file)) {
376
- throw new BrowserslistError('Can\'t read ' + file + ' config')
377
- }
378
- return browserslist.parseConfig(fs.readFileSync(file))
379
- }
380
-
381
- // Find config, read file and parse it
382
- browserslist.findConfig = function (from) {
383
- if (!path.resolve) return undefined
384
-
385
- from = path.resolve(from)
386
-
387
- var cacheKey = isFile(from) ? path.dirname(from) : from
388
- if (cacheKey in configCache) {
389
- return configCache[cacheKey]
390
- }
391
-
392
- var resolved = eachParent(from, function (dir) {
393
- var config = path.join(dir, 'browserslist')
394
- var pkg = path.join(dir, 'package.json')
395
- var rc = path.join(dir, '.browserslistrc')
396
-
397
- var pkgBrowserslist
398
- if (isFile(pkg)) {
399
- try {
400
- pkgBrowserslist = parsePackage(pkg)
401
- } catch (e) {
402
- if (e.name === 'BrowserslistError') throw e
403
- console.warn('[Browserslist] Could not parse ' + pkg + '. Ignoring it.')
404
- }
405
- }
406
-
407
- if (isFile(config) && pkgBrowserslist) {
408
- throw new BrowserslistError(
409
- dir + ' contains both browserslist and package.json with browsers')
410
- } else if (isFile(rc) && pkgBrowserslist) {
411
- throw new BrowserslistError(
412
- dir + ' contains both .browserslistrc and package.json with browsers')
413
- } else if (isFile(config) && isFile(rc)) {
414
- throw new BrowserslistError(
415
- dir + ' contains both .browserslistrc and browserslist')
416
- } else if (isFile(config)) {
417
- return browserslist.readConfig(config)
418
- } else if (isFile(rc)) {
419
- return browserslist.readConfig(rc)
420
- } else {
421
- return pkgBrowserslist
422
- }
423
- })
424
- if (!env.BROWSERSLIST_DISABLE_CACHE) {
425
- configCache[cacheKey] = resolved
426
- }
427
- return resolved
428
- }
283
+ browserslist.clearCaches = env.clearCaches
284
+ browserslist.parseConfig = env.parseConfig
285
+ browserslist.readConfig = env.readConfig
286
+ browserslist.findConfig = env.findConfig
429
287
 
430
288
  /**
431
289
  * Return browsers market coverage.
@@ -459,38 +317,6 @@ browserslist.coverage = function (browsers, country) {
459
317
  }, 0)
460
318
  }
461
319
 
462
- // Return array of queries from config content
463
- browserslist.parseConfig = function (string) {
464
- var result = { defaults: [] }
465
- var section = 'defaults'
466
-
467
- string.toString()
468
- .replace(/#[^\n]*/g, '')
469
- .split(/\n/)
470
- .map(function (line) {
471
- return line.trim()
472
- })
473
- .filter(function (line) {
474
- return line !== ''
475
- })
476
- .forEach(function (line) {
477
- if (IS_SECTION.test(line)) {
478
- section = line.match(IS_SECTION)[1].trim()
479
- result[section] = result[section] || []
480
- } else {
481
- result[section].push(line)
482
- }
483
- })
484
-
485
- return result
486
- }
487
-
488
- // Clear internal caches
489
- browserslist.clearCaches = function () {
490
- filenessCache = {}
491
- configCache = {}
492
- }
493
-
494
320
  var QUERIES = [
495
321
  {
496
322
  regexp: /^last\s+(\d+)\s+major versions?$/i,
@@ -580,6 +406,15 @@ var QUERIES = [
580
406
  }).map(nameMapper(data.name))
581
407
  }
582
408
  },
409
+ {
410
+ regexp: /^last\s+(\d+)\s+years?$/i,
411
+ select: function (context, years) {
412
+ var date = new Date()
413
+ var since = date.setFullYear(date.getFullYear() - years) / 1000
414
+
415
+ return filterByYear(since)
416
+ }
417
+ },
583
418
  {
584
419
  regexp: /^since (\d+)(?:-(\d+))?(?:-(\d+))?$/i,
585
420
  select: function (context, year, month, date) {
@@ -588,14 +423,7 @@ var QUERIES = [
588
423
  date = parseInt(date || '01')
589
424
  var since = Date.UTC(year, month, date, 0, 0, 0) / 1000
590
425
 
591
- return Object.keys(agents).reduce(function (selected, name) {
592
- var data = byName(name)
593
- if (!data) return selected
594
- var versions = Object.keys(data.releaseDate).filter(function (v) {
595
- return data.releaseDate[v] >= since
596
- })
597
- return selected.concat(versions.map(nameMapper(data.name)))
598
- }, [])
426
+ return filterByYear(since)
599
427
  }
600
428
  },
601
429
  {
@@ -801,14 +629,7 @@ var QUERIES = [
801
629
  {
802
630
  regexp: /^extends (.+)$/i,
803
631
  select: function (context, name) {
804
- if (!context.dangerousExtend) checkExtend(name)
805
- // eslint-disable-next-line security/detect-non-literal-require
806
- var queries = require(name)
807
- if (!Array.isArray(queries)) {
808
- throw new BrowserslistError(
809
- '`' + name + '` config exports not an array of queries')
810
- }
811
- return resolve(queries, context)
632
+ return resolve(env.loadQueries(context, name), context)
812
633
  }
813
634
  },
814
635
  {
@@ -817,26 +638,7 @@ var QUERIES = [
817
638
  return browserslist(browserslist.defaults)
818
639
  }
819
640
  }
820
- ]
821
-
822
- var CONFIG_PATTERN = /^browserslist-config-/
823
- var SCOPED_CONFIG__PATTERN = /@[^./]+\/browserslist-config(-|$)/
824
-
825
- function checkExtend (name) {
826
- var use = ' Use `dangerousExtend` option to disable.'
827
- if (!CONFIG_PATTERN.test(name) && !SCOPED_CONFIG__PATTERN.test(name)) {
828
- throw new BrowserslistError(
829
- 'Browserslist config needs `browserslist-config-` prefix. ' + use)
830
- }
831
- if (name.indexOf('.') !== -1) {
832
- throw new BrowserslistError(
833
- '`.` not allowed in Browserslist config name. ' + use)
834
- }
835
- if (name.indexOf('node_modules') !== -1) {
836
- throw new BrowserslistError(
837
- '`node_modules` not allowed in Browserslist config.' + use)
838
- }
839
- }
641
+ ];
840
642
 
841
643
  // Get and convert Can I Use data
842
644
 
package/node.js ADDED
@@ -0,0 +1,215 @@
1
+ var path = require('path')
2
+ var fs = require('fs')
3
+
4
+ var BrowserslistError = require('./error')
5
+
6
+ var IS_SECTION = /^\s*\[(.+)\]\s*$/
7
+ var CONFIG_PATTERN = /^browserslist-config-/
8
+ var SCOPED_CONFIG__PATTERN = /@[^./]+\/browserslist-config(-|$)/
9
+
10
+ var filenessCache = { }
11
+ var configCache = { }
12
+
13
+ function checkExtend (name) {
14
+ var use = ' Use `dangerousExtend` option to disable.'
15
+ if (!CONFIG_PATTERN.test(name) && !SCOPED_CONFIG__PATTERN.test(name)) {
16
+ throw new BrowserslistError(
17
+ 'Browserslist config needs `browserslist-config-` prefix. ' + use)
18
+ }
19
+ if (name.indexOf('.') !== -1) {
20
+ throw new BrowserslistError(
21
+ '`.` not allowed in Browserslist config name. ' + use)
22
+ }
23
+ if (name.indexOf('node_modules') !== -1) {
24
+ throw new BrowserslistError(
25
+ '`node_modules` not allowed in Browserslist config.' + use)
26
+ }
27
+ }
28
+
29
+ function isFile (file) {
30
+ if (file in filenessCache) {
31
+ return filenessCache[file]
32
+ }
33
+ var result = fs.existsSync(file) && fs.statSync(file).isFile()
34
+ if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
35
+ filenessCache[file] = result
36
+ }
37
+ return result
38
+ }
39
+
40
+ function eachParent (file, callback) {
41
+ var loc = path.resolve(file)
42
+ do {
43
+ var result = callback(loc)
44
+ if (typeof result !== 'undefined') return result
45
+ } while (loc !== (loc = path.dirname(loc)))
46
+ return undefined
47
+ }
48
+
49
+ function pickEnv (config, opts) {
50
+ if (typeof config !== 'object') return config
51
+
52
+ var name
53
+ if (typeof opts.env === 'string') {
54
+ name = opts.env
55
+ } else if (process.env.BROWSERSLIST_ENV) {
56
+ name = process.env.BROWSERSLIST_ENV
57
+ } else if (process.env.NODE_ENV) {
58
+ name = process.env.NODE_ENV
59
+ } else {
60
+ name = 'development'
61
+ }
62
+
63
+ return config[name] || config.defaults
64
+ }
65
+
66
+ function parsePackage (file) {
67
+ var config = JSON.parse(fs.readFileSync(file))
68
+ if (config.browserlist && !config.browserslist) {
69
+ throw new BrowserslistError(
70
+ '`browserlist` key instead of `browserslist` in ' + file)
71
+ }
72
+ var list = config.browserslist
73
+ if (typeof list === 'object' && list.length) {
74
+ list = { defaults: list }
75
+ }
76
+ return list
77
+ }
78
+
79
+ module.exports = {
80
+ loadQueries: function loadQueries (context, name) {
81
+ if (!context.dangerousExtend) checkExtend(name)
82
+ // eslint-disable-next-line security/detect-non-literal-require
83
+ var queries = require(name)
84
+ if (!Array.isArray(queries)) {
85
+ throw new BrowserslistError(
86
+ '`' + name + '` config exports not an array of queries')
87
+ }
88
+ return queries
89
+ },
90
+
91
+ getStat: function getStat (opts) {
92
+ var stats
93
+ if (opts.stats) {
94
+ stats = opts.stats
95
+ } else if (process.env.BROWSERSLIST_STATS) {
96
+ stats = process.env.BROWSERSLIST_STATS
97
+ } else if (opts.path && path.resolve && fs.existsSync) {
98
+ stats = eachParent(opts.path, function (dir) {
99
+ var file = path.join(dir, 'browserslist-stats.json')
100
+ return isFile(file) ? file : undefined
101
+ })
102
+ }
103
+
104
+ if (typeof stats === 'string') {
105
+ try {
106
+ stats = JSON.parse(fs.readFileSync(stats))
107
+ } catch (e) {
108
+ throw new BrowserslistError('Can\'t read ' + stats)
109
+ }
110
+ }
111
+
112
+ return stats
113
+ },
114
+
115
+ loadConfig: function loadConfig (opts) {
116
+ if (process.env.BROWSERSLIST) {
117
+ return process.env.BROWSERSLIST
118
+ } else if (opts.config || process.env.BROWSERSLIST_CONFIG) {
119
+ var file = opts.config || process.env.BROWSERSLIST_CONFIG
120
+ if (path.basename(file) === 'package.json') {
121
+ return pickEnv(parsePackage(file), opts)
122
+ } else {
123
+ return pickEnv(module.exports.readConfig(file), opts)
124
+ }
125
+ } else if (opts.path) {
126
+ return pickEnv(module.exports.findConfig(opts.path), opts)
127
+ } else {
128
+ return undefined
129
+ }
130
+ },
131
+
132
+ parseConfig: function parseConfig (string) {
133
+ var result = { defaults: [] }
134
+ var section = 'defaults'
135
+
136
+ string.toString()
137
+ .replace(/#[^\n]*/g, '')
138
+ .split(/\n/)
139
+ .map(function (line) {
140
+ return line.trim()
141
+ })
142
+ .filter(function (line) {
143
+ return line !== ''
144
+ })
145
+ .forEach(function (line) {
146
+ if (IS_SECTION.test(line)) {
147
+ section = line.match(IS_SECTION)[1].trim()
148
+ result[section] = result[section] || []
149
+ } else {
150
+ result[section].push(line)
151
+ }
152
+ })
153
+
154
+ return result
155
+ },
156
+
157
+ readConfig: function readConfig (file) {
158
+ if (!isFile(file)) {
159
+ throw new BrowserslistError('Can\'t read ' + file + ' config')
160
+ }
161
+ return module.exports.parseConfig(fs.readFileSync(file))
162
+ },
163
+
164
+ findConfig: function findConfig (from) {
165
+ from = path.resolve(from)
166
+
167
+ var cacheKey = isFile(from) ? path.dirname(from) : from
168
+ if (cacheKey in configCache) {
169
+ return configCache[cacheKey]
170
+ }
171
+
172
+ var resolved = eachParent(from, function (dir) {
173
+ var config = path.join(dir, 'browserslist')
174
+ var pkg = path.join(dir, 'package.json')
175
+ var rc = path.join(dir, '.browserslistrc')
176
+
177
+ var pkgBrowserslist
178
+ if (isFile(pkg)) {
179
+ try {
180
+ pkgBrowserslist = parsePackage(pkg)
181
+ } catch (e) {
182
+ if (e.name === 'BrowserslistError') throw e
183
+ console.warn(
184
+ '[Browserslist] Could not parse ' + pkg + '. Ignoring it.')
185
+ }
186
+ }
187
+
188
+ if (isFile(config) && pkgBrowserslist) {
189
+ throw new BrowserslistError(
190
+ dir + ' contains both browserslist and package.json with browsers')
191
+ } else if (isFile(rc) && pkgBrowserslist) {
192
+ throw new BrowserslistError(
193
+ dir + ' contains both .browserslistrc and package.json with browsers')
194
+ } else if (isFile(config) && isFile(rc)) {
195
+ throw new BrowserslistError(
196
+ dir + ' contains both .browserslistrc and browserslist')
197
+ } else if (isFile(config)) {
198
+ return module.exports.readConfig(config)
199
+ } else if (isFile(rc)) {
200
+ return module.exports.readConfig(rc)
201
+ } else {
202
+ return pkgBrowserslist
203
+ }
204
+ })
205
+ if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
206
+ configCache[cacheKey] = resolved
207
+ }
208
+ return resolved
209
+ },
210
+
211
+ clearCaches: function clearCaches () {
212
+ filenessCache = { }
213
+ configCache = { }
214
+ }
215
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browserslist",
3
- "version": "2.10.2",
3
+ "version": "2.11.3",
4
4
  "description": "Share target browsers between different front-end tools, like Autoprefixer, Stylelint and babel-env-preset",
5
5
  "keywords": [
6
6
  "caniuse",
@@ -11,27 +11,27 @@
11
11
  "license": "MIT",
12
12
  "repository": "ai/browserslist",
13
13
  "dependencies": {
14
- "caniuse-lite": "^1.0.30000784",
14
+ "caniuse-lite": "^1.0.30000792",
15
15
  "electron-to-chromium": "^1.3.30"
16
16
  },
17
17
  "bin": "./cli.js",
18
18
  "devDependencies": {
19
19
  "cross-spawn": "^5.1.0",
20
- "eslint": "^4.14.0",
20
+ "eslint": "^4.15.0",
21
21
  "eslint-ci": "^0.1.1",
22
22
  "eslint-config-logux": "^17.0.0",
23
23
  "eslint-config-standard": "^10.2.1",
24
- "eslint-plugin-es5": "^1.1.0",
24
+ "eslint-plugin-es5": "^1.2.0",
25
25
  "eslint-plugin-import": "^2.8.0",
26
- "eslint-plugin-jest": "^21.5.0",
26
+ "eslint-plugin-jest": "^21.6.2",
27
27
  "eslint-plugin-node": "^5.2.1",
28
28
  "eslint-plugin-promise": "^3.6.0",
29
29
  "eslint-plugin-security": "^1.4.0",
30
30
  "eslint-plugin-standard": "^3.0.1",
31
- "jest": "^22.0.4",
31
+ "jest": "^22.0.6",
32
32
  "lint-staged": "^6.0.0",
33
33
  "pre-commit": "^1.1.3",
34
- "size-limit": "^0.13.2",
34
+ "size-limit": "^0.14.0",
35
35
  "yaspeller-ci": "^1.0.0"
36
36
  },
37
37
  "eslintConfig": {
@@ -77,9 +77,8 @@
77
77
  "*.js": "eslint"
78
78
  },
79
79
  "browser": {
80
- "process": false,
81
- "path": false,
82
- "fs": false
80
+ "./node.js": "./browser.js",
81
+ "path": false
83
82
  },
84
83
  "pre-commit": [
85
84
  "lint-staged"