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 +12 -0
- package/README.md +5 -5
- package/browser.js +29 -0
- package/error.js +12 -0
- package/index.js +76 -274
- package/node.js +215 -0
- package/package.json +9 -10
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`
|
|
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
|
|
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
|
|
113
|
-
(also `since
|
|
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
|
-
##
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
24
|
+
"eslint-plugin-es5": "^1.2.0",
|
|
25
25
|
"eslint-plugin-import": "^2.8.0",
|
|
26
|
-
"eslint-plugin-jest": "^21.
|
|
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.
|
|
31
|
+
"jest": "^22.0.6",
|
|
32
32
|
"lint-staged": "^6.0.0",
|
|
33
33
|
"pre-commit": "^1.1.3",
|
|
34
|
-
"size-limit": "^0.
|
|
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
|
-
"
|
|
81
|
-
"path": false
|
|
82
|
-
"fs": false
|
|
80
|
+
"./node.js": "./browser.js",
|
|
81
|
+
"path": false
|
|
83
82
|
},
|
|
84
83
|
"pre-commit": [
|
|
85
84
|
"lint-staged"
|