browserslist 4.12.0 → 4.14.0

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,12 +1,26 @@
1
1
  # Change Log
2
2
  This project adheres to [Semantic Versioning](http://semver.org/).
3
3
 
4
+ ## 4.14
5
+ * Add `BROWSERSLIST_DANGEROUS_EXTEND` support (by Timo Mayer).
6
+
7
+ ## 4.13
8
+ * Added `supports` query to select browsers (by Jesús Leganés-Combarro).
9
+
10
+ ## 4.12.2
11
+ * Update Firefox ESR.
12
+
13
+ ## 4.12.1
14
+ * Update `package.json` scanning tool for `--update-db` (by Luke Edwards).
15
+ * Improve docs (by Mukundan Senthil).
16
+ * Drop Node.js 13.0-13.6 support because of ES modules bug in that versions.
17
+
4
18
  ## 4.12
5
19
  * Add environments to shared configs (by Yevgeny Petukhov).
6
20
  * Fix docs (by Dmitry Statsenko and Thomas Pozzo di Borgo).
7
21
 
8
22
  ## 4.11.1
9
- * FIx Node.js 6 support.
23
+ * Fix Node.js 6 support.
10
24
 
11
25
  ## 4.11
12
26
  * Add `npx browserslist --mobile-to-desktop` (by James Ross).
package/README.md CHANGED
@@ -17,12 +17,12 @@ front-end tools. It is used in:
17
17
  All tools will find target browsers automatically,
18
18
  when you add the following to `package.json`:
19
19
 
20
- ```js
20
+ ```json
21
21
  "browserslist": [
22
22
  "defaults",
23
23
  "not IE 11",
24
24
  "not IE_Mob 11",
25
- "maintained node versions",
25
+ "maintained node versions"
26
26
  ]
27
27
  ```
28
28
 
@@ -164,7 +164,9 @@ An `or` combiner can use the keyword `or` as well as `,`.
164
164
  `last 1 version or > 1%` is equal to `last 1 version, > 1%`.
165
165
 
166
166
  `and` query combinations are also supported to perform an
167
- intersection of the previous query: `last 1 version and > 1%`.
167
+ intersection of all the previous queries:
168
+ `last 1 version or chrome > 75 and > 1%` will select
169
+ (`browser last version` or `Chrome since 76`) and `more than 1% marketshare`.
168
170
 
169
171
  There is 3 different ways to combine queries as depicted below. First you start
170
172
  with a single query and then we combine the queries to get our final list.
@@ -173,8 +175,6 @@ Obviously you can *not* start with a `not` combiner, since there is no left-hand
173
175
  side query to combine it with. The left-hand is always resolved as `and`
174
176
  combiner even if `or` is used (this is an API implementation specificity).
175
177
 
176
- `and` combiner has precedence over `or` combiner.
177
-
178
178
  | Query combiner type | Illustration | Example |
179
179
  | ------------------- | :----------: | ------- |
180
180
  |`or`/`,` combiner <br> (union) | ![Union of queries](img/union.svg) | `> .5% or last 2 versions` <br> `> .5%, last 2 versions` |
@@ -184,7 +184,6 @@ combiner even if `or` is used (this is an API implementation specificity).
184
184
  _A quick way to test your query is to do `npx browserslist '> 0.5%, not IE 11'`
185
185
  in your terminal._
186
186
 
187
-
188
187
  ### Full List
189
188
 
190
189
  You can specify the browser and Node.js versions by queries (case insensitive):
@@ -193,45 +192,51 @@ You can specify the browser and Node.js versions by queries (case insensitive):
193
192
  (`> 0.5%, last 2 versions, Firefox ESR, not dead`).
194
193
  * `> 5%`: browsers versions selected by global usage statistics.
195
194
  `>=`, `<` and `<=` work too.
196
- * `> 5% in US`: uses USA usage statistics. It accepts [two-letter country code].
197
- * `> 5% in alt-AS`: uses Asia region usage statistics. List of all region codes
198
- can be found at [`caniuse-lite/data/regions`].
199
- * `> 5% in my stats`: uses [custom usage data].
200
- * `> 5% in browserslist-config-mycompany stats`: uses [custom usage data]
201
- from `browserslist-config-mycompany/browserslist-stats.json`.
202
- * `cover 99.5%`: most popular browsers that provide coverage.
203
- * `cover 99.5% in US`: same as above, with [two-letter country code].
204
- * `cover 99.5% in my stats`: uses [custom usage data].
205
- * `maintained node versions`: all Node.js versions, which are [still maintained]
206
- by Node.js Foundation.
195
+ * `> 5% in US`: uses USA usage statistics.
196
+ It accepts [two-letter country code].
197
+ * `> 5% in alt-AS`: uses Asia region usage statistics.
198
+ List of all region codes can be found at [`caniuse-lite/data/regions`].
199
+ * `> 5% in my stats`: uses [custom usage data].
200
+ * `> 5% in browserslist-config-mycompany stats`: uses [custom usage data]
201
+ from `browserslist-config-mycompany/browserslist-stats.json`.
202
+ * `cover 99.5%`: most popular browsers that provide coverage.
203
+ * `cover 99.5% in US`: same as above, with [two-letter country code].
204
+ * `cover 99.5% in my stats`: uses [custom usage data].
205
+ * `dead`: browsers without official support or updates for 24 months.
206
+ Right now it is `IE 10`, `IE_Mob 11`, `BlackBerry 10`, `BlackBerry 7`,
207
+ `Samsung 4` and `OperaMobile 12.1`.
208
+ * `last 2 versions`: the last 2 versions for *each* browser.
209
+ * `last 2 Chrome versions`: the last 2 versions of Chrome browser.
210
+ * `last 2 major versions` or `last 2 iOS major versions`:
211
+ all minor/patch releases of last 2 major versions.
207
212
  * `node 10` and `node 10.4`: selects latest Node.js `10.x.x`
208
213
  or `10.4.x` release.
209
- * `current node`: Node.js version used by Browserslist right now.
214
+ * `current node`: Node.js version used by Browserslist right now.
215
+ * `maintained node versions`: all Node.js versions, which are [still maintained]
216
+ by Node.js Foundation.
217
+ * `iOS 7`: the iOS browser version 7 directly.
218
+ * `Firefox > 20`: versions of Firefox newer than 20.
219
+ `>=`, `<` and `<=` work too. It also works with Node.js.
220
+ * `ie 6-8`: selects an inclusive range of versions.
221
+ * `Firefox ESR`: the latest [Firefox ESR] version.
222
+ * `PhantomJS 2.1` and `PhantomJS 1.9`: selects Safari versions similar
223
+ to PhantomJS runtime.
210
224
  * `extends browserslist-config-mycompany`: take queries from
211
225
  `browserslist-config-mycompany` npm package.
212
- * `ie 6-8`: selects an inclusive range of versions.
213
- * `Firefox > 20`: versions of Firefox newer than 20.
214
- `>=`, `<` and `<=` work too. It also works with Node.js.
215
- * `iOS 7`: the iOS browser version 7 directly.
216
- * `Firefox ESR`: the latest [Firefox ESR] version.
217
- * `PhantomJS 2.1` and `PhantomJS 1.9`: selects Safari versions similar
218
- to PhantomJS runtime.
219
- * `unreleased versions` or `unreleased Chrome versions`:
220
- alpha and beta versions.
221
- * `last 2 major versions` or `last 2 iOS major versions`:
222
- all minor/patch releases of last 2 major versions.
226
+ * `supports es6-module`: browsers with support for specific features.
227
+ `es6-module` here is the `feat` parameter at the URL of the [Can I Use]
228
+ page. A list of all available features can be found at
229
+ [`caniuse-lite/data/features`].
223
230
  * `since 2015` or `last 2 years`: all versions released since year 2015
224
231
  (also `since 2015-03` and `since 2015-03-10`).
225
- * `dead`: browsers without official support or updates for 24 months.
226
- Right now it is `IE 10`, `IE_Mob 11`, `BlackBerry 10`, `BlackBerry 7`,
227
- `Samsung 4` and `OperaMobile 12.1`.
228
- * `last 2 versions`: the last 2 versions for *each* browser.
229
- * `last 2 Chrome versions`: the last 2 versions of Chrome browser.
232
+ * `unreleased versions` or `unreleased Chrome versions`:
233
+ alpha and beta versions.
230
234
  * `not ie <= 8`: exclude browsers selected by previous queries.
231
235
 
232
236
  You can add `not ` to any query.
233
237
 
234
238
  [`caniuse-lite/data/regions`]: https://github.com/ben-eb/caniuse-lite/tree/master/data/regions
239
+ [`caniuse-lite/data/features`]: https://github.com/ben-eb/caniuse-lite/tree/master/data/features
235
240
  [two-letter country code]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
236
241
  [custom usage data]: #custom-usage-data
237
242
  [still maintained]: https://github.com/nodejs/Release
@@ -574,32 +579,39 @@ with [environment variables]:
574
579
  * `BROWSERSLIST` with browsers queries.
575
580
 
576
581
  ```sh
577
- BROWSERSLIST="> 5%" gulp css
582
+ BROWSERSLIST="> 5%" npx webpack
578
583
  ```
579
584
 
580
585
  * `BROWSERSLIST_CONFIG` with path to config file.
581
586
 
582
587
  ```sh
583
- BROWSERSLIST_CONFIG=./config/browserslist gulp css
588
+ BROWSERSLIST_CONFIG=./config/browserslist npx webpack
584
589
  ```
585
590
 
586
591
  * `BROWSERSLIST_ENV` with environments string.
587
592
 
588
593
  ```sh
589
- BROWSERSLIST_ENV="development" gulp css
594
+ BROWSERSLIST_ENV="development" npx webpack
590
595
  ```
591
596
 
592
597
  * `BROWSERSLIST_STATS` with path to the custom usage data
593
598
  for `> 1% in my stats` query.
594
599
 
595
600
  ```sh
596
- BROWSERSLIST_STATS=./config/usage_data.json gulp css
601
+ BROWSERSLIST_STATS=./config/usage_data.json npx webpack
597
602
  ```
598
603
 
599
604
  * `BROWSERSLIST_DISABLE_CACHE` if you want to disable config reading cache.
600
605
 
601
606
  ```sh
602
- BROWSERSLIST_DISABLE_CACHE=1 gulp css
607
+ BROWSERSLIST_DISABLE_CACHE=1 npx webpack
608
+ ```
609
+
610
+ * `BROWSERSLIST_DANGEROUS_EXTEND` to disable security shareable config
611
+ name check.
612
+
613
+ ```sh
614
+ BROWSERSLIST_DANGEROUS_EXTEND=1 npx webpack
603
615
  ```
604
616
 
605
617
  [environment variables]: https://en.wikipedia.org/wiki/Environment_variable
package/browser.js CHANGED
@@ -21,10 +21,15 @@ module.exports = {
21
21
 
22
22
  loadCountry: function loadCountry () {
23
23
  throw new BrowserslistError(
24
- 'Country statistics is not supported ' +
24
+ 'Country statistics are not supported ' +
25
25
  'in client-side build of Browserslist')
26
26
  },
27
27
 
28
+ loadFeature: function loadFeature () {
29
+ throw new BrowserslistError(
30
+ 'Supports queries are not available in client-side build of Browserslist')
31
+ },
32
+
28
33
  currentNode: function currentNode (resolve, context) {
29
34
  return resolve(['maintained node versions'], context)[0]
30
35
  },
package/index.js CHANGED
@@ -505,6 +505,7 @@ function flatten (array) {
505
505
  }
506
506
 
507
507
  // Will be filled by Can I Use data below
508
+ browserslist.cache = { }
508
509
  browserslist.data = { }
509
510
  browserslist.usage = {
510
511
  global: { },
@@ -646,7 +647,7 @@ var QUERIES = [
646
647
  {
647
648
  regexp: /^last\s+(\d+)\s+electron\s+major\s+versions?$/i,
648
649
  select: function (context, versions) {
649
- var validVersions = getMajorVersions(Object.keys(e2c).reverse(), versions)
650
+ var validVersions = getMajorVersions(Object.keys(e2c), versions)
650
651
  return validVersions.map(function (i) {
651
652
  return 'chrome ' + e2c[i]
652
653
  })
@@ -887,6 +888,20 @@ var QUERIES = [
887
888
  return result
888
889
  }
889
890
  },
891
+ {
892
+ regexp: /^supports\s+([\w-]+)$/,
893
+ select: function (context, feature) {
894
+ env.loadFeature(browserslist.cache, feature)
895
+ var features = browserslist.cache[feature]
896
+ return Object.keys(features).reduce(function (result, version) {
897
+ var flags = features[version]
898
+ if (flags.indexOf('y') >= 0 || flags.indexOf('a') >= 0) {
899
+ result.push(version)
900
+ }
901
+ return result
902
+ }, [])
903
+ }
904
+ },
890
905
  {
891
906
  regexp: /^electron\s+([\d.]+)\s*-\s*([\d.]+)$/i,
892
907
  select: function (context, from, to) {
@@ -990,7 +1005,7 @@ var QUERIES = [
990
1005
  {
991
1006
  regexp: /^(firefox|ff|fx)\s+esr$/i,
992
1007
  select: function () {
993
- return ['firefox 68']
1008
+ return ['firefox 68', 'firefox 78']
994
1009
  }
995
1010
  },
996
1011
  {
package/node.js CHANGED
@@ -1,3 +1,4 @@
1
+ var feature = require('caniuse-lite/dist/unpacker/feature').default
1
2
  var region = require('caniuse-lite/dist/unpacker/region').default
2
3
  var path = require('path')
3
4
  var fs = require('fs')
@@ -152,8 +153,10 @@ function normalizeUsageData (usageData, data) {
152
153
  }
153
154
 
154
155
  module.exports = {
155
- loadQueries: function loadQueries (context, name) {
156
- if (!context.dangerousExtend) checkExtend(name)
156
+ loadQueries: function loadQueries (ctx, name) {
157
+ if (!ctx.dangerousExtend && !process.env.BROWSERSLIST_DANGEROUS_EXTEND) {
158
+ checkExtend(name)
159
+ }
157
160
  // eslint-disable-next-line security/detect-non-literal-require
158
161
  var queries = require(require.resolve(name, { paths: ['.'] }))
159
162
  if (queries) {
@@ -161,7 +164,7 @@ module.exports = {
161
164
  return queries
162
165
  } else if (typeof queries === 'object') {
163
166
  if (!queries.defaults) queries.defaults = []
164
- return pickEnv(queries, context, name)
167
+ return pickEnv(queries, ctx, name)
165
168
  }
166
169
  }
167
170
  throw new BrowserslistError(
@@ -170,8 +173,10 @@ module.exports = {
170
173
  )
171
174
  },
172
175
 
173
- loadStat: function loadStat (context, name, data) {
174
- if (!context.dangerousExtend) checkExtend(name)
176
+ loadStat: function loadStat (ctx, name, data) {
177
+ if (!ctx.dangerousExtend && !process.env.BROWSERSLIST_DANGEROUS_EXTEND) {
178
+ checkExtend(name)
179
+ }
175
180
  // eslint-disable-next-line security/detect-non-literal-require
176
181
  var stats = require(
177
182
  require.resolve(
@@ -237,6 +242,21 @@ module.exports = {
237
242
  }
238
243
  },
239
244
 
245
+ loadFeature: function loadFeature (features, name) {
246
+ name = name.replace(/[^\w-]/g, '')
247
+ if (features[name]) return
248
+
249
+ // eslint-disable-next-line security/detect-non-literal-require
250
+ var compressed = require('caniuse-lite/data/features/' + name + '.js')
251
+ var stats = feature(compressed).stats
252
+ features[name] = { }
253
+ for (var i in stats) {
254
+ for (var j in stats[i]) {
255
+ features[name][i + ' ' + j] = stats[i][j]
256
+ }
257
+ }
258
+ },
259
+
240
260
  parseConfig: function parseConfig (string) {
241
261
  var result = { defaults: [] }
242
262
  var sections = ['defaults']
@@ -337,6 +357,8 @@ module.exports = {
337
357
  dataTimeChecked = false
338
358
  filenessCache = { }
339
359
  configCache = { }
360
+
361
+ this.cache = { }
340
362
  },
341
363
 
342
364
  oldDataWarning: function oldDataWarning (agentsObj) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browserslist",
3
- "version": "4.12.0",
3
+ "version": "4.14.0",
4
4
  "description": "Share target browsers between different front-end tools, like Autoprefixer, Stylelint and babel-env-preset",
5
5
  "keywords": [
6
6
  "caniuse",
@@ -15,10 +15,13 @@
15
15
  "license": "MIT",
16
16
  "repository": "browserslist/browserslist",
17
17
  "dependencies": {
18
- "caniuse-lite": "^1.0.30001043",
19
- "electron-to-chromium": "^1.3.413",
20
- "node-releases": "^1.1.53",
21
- "pkg-up": "^2.0.0"
18
+ "caniuse-lite": "^1.0.30001111",
19
+ "electron-to-chromium": "^1.3.523",
20
+ "escalade": "^3.0.2",
21
+ "node-releases": "^1.1.60"
22
+ },
23
+ "engines": {
24
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
22
25
  },
23
26
  "bin": "./cli.js",
24
27
  "browser": {
package/update-db.js CHANGED
@@ -1,23 +1,25 @@
1
1
  var childProcess = require('child_process')
2
- var pkgUp = require('pkg-up')
2
+ var escalade = require('escalade/sync')
3
3
  var path = require('path')
4
4
  var fs = require('fs')
5
5
 
6
6
  var BrowserslistError = require('./error')
7
7
 
8
8
  function detectLockfile () {
9
- var packagePath = pkgUp.sync()
10
- if (!packagePath) {
9
+ var packageDir = escalade('.', function (dir, names) {
10
+ return names.indexOf('package.json') !== -1 ? dir : ''
11
+ })
12
+
13
+ if (!packageDir) {
11
14
  throw new BrowserslistError(
12
15
  'Cannot find package.json. ' +
13
16
  'Is it a right project to run npx browserslist --update-db?'
14
17
  )
15
18
  }
16
19
 
17
- var rootDir = path.dirname(packagePath)
18
- var lockfileNpm = path.join(rootDir, 'package-lock.json')
19
- var lockfileYarn = path.join(rootDir, 'yarn.lock')
20
- var lockfilePnpm = path.join(rootDir, 'pnpm-lock.yaml')
20
+ var lockfileNpm = path.join(packageDir, 'package-lock.json')
21
+ var lockfileYarn = path.join(packageDir, 'yarn.lock')
22
+ var lockfilePnpm = path.join(packageDir, 'pnpm-lock.yaml')
21
23
 
22
24
  /* istanbul ignore next */
23
25
  if (fs.existsSync(lockfilePnpm)) {