browserslist 4.5.6 → 4.6.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.
Files changed (4) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +34 -38
  3. package/index.js +96 -43
  4. package/package.json +4 -4
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
+ ## 4.6.3
5
+ * Dirty fix for `android all` error.
6
+
7
+ ## 4.6.2
8
+ * Fix `last x version` and similar queries for Android (by Tony Ross).
9
+
10
+ ## 4.6.1
11
+ * Fix patch version support for Electron (by Kilian Valkhof).
12
+
13
+ ## 4.6
14
+ * Add `mobileToDesktop` option (by Nicolò Ribaudo).
15
+
4
16
  ## 4.5.6
5
17
  * Make `Node > 5` and `node > 5` queries case insensitive.
6
18
 
package/README.md CHANGED
@@ -18,15 +18,13 @@ front-end tools. It is used in:
18
18
  All tools will find target browsers automatically,
19
19
  when you add the following to `package.json`:
20
20
 
21
- ```json
22
- {
21
+ ```js
23
22
  "browserslist": [
24
23
  "last 1 version",
25
24
  "> 1%",
26
25
  "maintained node versions",
27
26
  "not dead"
28
27
  ]
29
- }
30
28
  ```
31
29
 
32
30
  Or in `.browserslistrc` config:
@@ -117,7 +115,7 @@ You can test Browserslist queries in [online demo].
117
115
  * Don’t remove browsers just because you don’t know them. Opera Mini has
118
116
  100 million users in Africa and it is more popular in the global market
119
117
  than Microsoft Edge. Chinese QQ Browsers has more market share than Firefox
120
- and desktop Safari altogether.
118
+ and desktop Safari combined.
121
119
 
122
120
 
123
121
  ## Queries
@@ -127,11 +125,10 @@ from one of this sources:
127
125
 
128
126
  1. `browserslist` key in `package.json` file in current or parent directories.
129
127
  **We recommend this way.**
130
- 2. Tool options. For example `browsers` option in Autoprefixer.
131
- 3. `BROWSERSLIST` environment variable.
132
- 4. `browserslist` config file in current or parent directories.
133
- 5. `.browserslistrc` config file in current or parent directories.
134
- 6. If the above methods did not produce a valid result
128
+ 2. `.browserslistrc` config file in current or parent directories.
129
+ 3. `browserslist` config file in current or parent directories.
130
+ 4. `BROWSERSLIST` environment variable.
131
+ 5. If the above methods did not produce a valid result
135
132
  Browserslist will use defaults:
136
133
  `> 0.5%, last 2 versions, Firefox ESR, not dead`.
137
134
 
@@ -203,6 +200,12 @@ You can specify the browser and Node.js versions by queries (case insensitive):
203
200
 
204
201
  You can add `not ` to any query.
205
202
 
203
+ [`caniuse-lite/data/regions`]: https://github.com/ben-eb/caniuse-lite/tree/master/data/regions
204
+ [two-letter country code]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
205
+ [custom usage data]: #custom-usage-data
206
+ [still maintained]: https://github.com/nodejs/Release
207
+ [Can I Use]: https://caniuse.com/
208
+
206
209
 
207
210
  ### Debug
208
211
 
@@ -228,23 +231,6 @@ samsung 5
228
231
  ```
229
232
 
230
233
 
231
- ### Notes
232
-
233
- Browserslist works with separated versions of browsers.
234
- You should avoid queries like `Firefox > 0`.
235
- The list of the specified browsers acts as a white list which means other browsers are ignored.
236
-
237
- All queries are based on the [Can I Use] support table,
238
- e.g. `last 3 iOS versions` might select `8.4, 9.2, 9.3` (mixed major and minor),
239
- whereas `last 3 Chrome versions` might select `50, 49, 48` (major only).
240
-
241
- [`caniuse-lite/data/regions`]: https://github.com/ben-eb/caniuse-lite/tree/master/data/regions
242
- [two-letter country code]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
243
- [custom usage data]: #custom-usage-data
244
- [still maintained]: https://github.com/nodejs/Release
245
- [Can I Use]: https://caniuse.com/
246
-
247
-
248
234
  ### Browsers
249
235
 
250
236
  Names are case insensitive:
@@ -411,9 +397,12 @@ In `package.json`:
411
397
  "> 1%",
412
398
  "ie 10"
413
399
  ],
414
- "development": [
400
+ "modern": [
415
401
  "last 1 chrome version",
416
402
  "last 1 firefox version"
403
+ ],
404
+ "ssr": [
405
+ "node 12"
417
406
  ]
418
407
  }
419
408
  ```
@@ -421,13 +410,16 @@ In `package.json`:
421
410
  In `.browserslistrc` config:
422
411
 
423
412
  ```ini
424
- [production staging]
413
+ [production]
425
414
  > 1%
426
415
  ie 10
427
416
 
428
- [development]
417
+ [modern]
429
418
  last 1 chrome version
430
419
  last 1 firefox version
420
+
421
+ [ssr]
422
+ node 12
431
423
  ```
432
424
 
433
425
 
@@ -469,16 +461,16 @@ For example, the query `> 1% in my stats, > 5% in US, 10%` is permitted.
469
461
  ## JS API
470
462
 
471
463
  ```js
472
- var browserslist = require('browserslist');
464
+ const browserslist = require('browserslist')
473
465
 
474
466
  // Your CSS/JS build tool code
475
- var process = function (source, opts) {
476
- var browsers = browserslist(opts.browsers, {
477
- stats: opts.stats,
478
- path: opts.file,
479
- env: opts.env
480
- });
481
- // Your code to add features for selected browsers
467
+ function process (source, opts) {
468
+ const browsers = browserslist(opts.overrideBrowserslist, {
469
+ stats: opts.stats,
470
+ path: opts.file,
471
+ env: opts.env
472
+ })
473
+ // Your code to add features for selected browsers
482
474
  }
483
475
  ```
484
476
 
@@ -499,6 +491,10 @@ Options:
499
491
  Default is `false.`
500
492
  * `dangerousExtend`: Disable security checks for `extend` query.
501
493
  Default is `false.`
494
+ * `mobileToDesktop`: Use desktop browsers if Can I Use doesn’t have data
495
+ about this mobile version. For instance, Browserslist will return
496
+ `chrome 20` on `and_chr 20` query (Can I Use has only data only about
497
+ latest versions of mobile browsers). Default is `false`.
502
498
 
503
499
  For non-JS environment and debug purpose you can use CLI tool:
504
500
 
@@ -563,7 +559,7 @@ for the duration of the hosting process.
563
559
  To clear these caches, use:
564
560
 
565
561
  ```js
566
- browserslist.clearCaches();
562
+ browserslist.clearCaches()
567
563
  ```
568
564
 
569
565
  To disable the caching altogether, set the `BROWSERSLIST_DISABLE_CACHE`
package/index.js CHANGED
@@ -33,6 +33,17 @@ function normalize (versions) {
33
33
  })
34
34
  }
35
35
 
36
+ function normalizeElectron (version) {
37
+ var versionToUse = version
38
+ if (version.split('.').length === 3) {
39
+ versionToUse = version
40
+ .split('.')
41
+ .slice(0, -1)
42
+ .join('.')
43
+ }
44
+ return versionToUse
45
+ }
46
+
36
47
  function nameMapper (name) {
37
48
  return function mapName (version) {
38
49
  return name + ' ' + version
@@ -136,11 +147,28 @@ function compareSemver (a, b) {
136
147
  )
137
148
  }
138
149
 
139
- function normalizeVersion (data, version) {
150
+ function resolveVersion (data, version) {
140
151
  if (data.versions.indexOf(version) !== -1) {
141
152
  return version
142
153
  } else if (browserslist.versionAliases[data.name][version]) {
143
154
  return browserslist.versionAliases[data.name][version]
155
+ } else {
156
+ return false
157
+ }
158
+ }
159
+
160
+ function normalizeVersion (data, version, context) {
161
+ var resolved = resolveVersion(data, version)
162
+ if (
163
+ !resolved &&
164
+ context.mobileToDesktop &&
165
+ browserslist.desktopNames[data.name]
166
+ ) {
167
+ var alias = checkName(browserslist.desktopNames[data.name])
168
+ resolved = resolveVersion(alias, version)
169
+ }
170
+ if (resolved) {
171
+ return resolved
144
172
  } else if (data.versions.length === 1) {
145
173
  return data.versions[0]
146
174
  } else {
@@ -179,6 +207,18 @@ function unknownQuery (query) {
179
207
  )
180
208
  }
181
209
 
210
+ function filterAndroid (list, versions) {
211
+ var released = browserslist.data.android.released
212
+ var firstEvergreen = 37
213
+ var last = released[released.length - 1]
214
+ var diff = last - firstEvergreen - versions // First Android Evergreen
215
+ if (diff > 0) {
216
+ return list.slice(-1)
217
+ } else {
218
+ return list.slice(diff - 1)
219
+ }
220
+ }
221
+
182
222
  /**
183
223
  * Resolves queries into a browser list.
184
224
  * @param {string|string[]} queries Queries to combine.
@@ -274,6 +314,9 @@ function resolve (queries, context) {
274
314
  * version in direct query.
275
315
  * @param {boolean} [opts.dangerousExtend] Disable security checks
276
316
  * for extend query.
317
+ * @param {boolean} [opts.mobileToDesktop] Alias mobile browsers to the desktop
318
+ * version when Can I Use doesn't have
319
+ * data about the specified version.
277
320
  * @returns {string[]} Array with browser names in Can I Use.
278
321
  *
279
322
  * @example
@@ -302,7 +345,8 @@ function browserslist (queries, opts) {
302
345
 
303
346
  var context = {
304
347
  ignoreUnknownVersions: opts.ignoreUnknownVersions,
305
- dangerousExtend: opts.dangerousExtend
348
+ dangerousExtend: opts.dangerousExtend,
349
+ mobileToDesktop: opts.mobileToDesktop
306
350
  }
307
351
 
308
352
  env.oldDataWarning(browserslist.data)
@@ -427,6 +471,15 @@ browserslist.aliases = {
427
471
  qqandroid: 'and_qq'
428
472
  }
429
473
 
474
+ // Can I Use only provides a few versions for some browsers (e.g. and_chr).
475
+ // Fallback to a similar browser for unknown versions
476
+ browserslist.desktopNames = {
477
+ and_chr: 'chrome',
478
+ and_ff: 'firefox',
479
+ ie_mob: 'ie',
480
+ op_mob: 'opera'
481
+ }
482
+
430
483
  // Aliases to work with joined versions like `ios_saf 7.0-7.1`
431
484
  browserslist.versionAliases = { }
432
485
 
@@ -496,15 +549,15 @@ browserslist.coverage = function (browsers, stats) {
496
549
 
497
550
  var QUERIES = [
498
551
  {
499
- regexp: /^last\s+(\d+)\s+major versions?$/i,
552
+ regexp: /^last\s+(\d+)\s+major\s+versions?$/i,
500
553
  select: function (context, versions) {
501
554
  return Object.keys(agents).reduce(function (selected, name) {
502
555
  var data = byName(name)
503
556
  if (!data) return selected
504
- var array = getMajorVersions(data.released, versions)
505
-
506
- array = array.map(nameMapper(data.name))
507
- return selected.concat(array)
557
+ var list = getMajorVersions(data.released, versions)
558
+ list = list.map(nameMapper(data.name))
559
+ if (data.name === 'android') list = filterAndroid(list, versions)
560
+ return selected.concat(list)
508
561
  }, [])
509
562
  }
510
563
  },
@@ -514,15 +567,15 @@ var QUERIES = [
514
567
  return Object.keys(agents).reduce(function (selected, name) {
515
568
  var data = byName(name)
516
569
  if (!data) return selected
517
- var array = data.released.slice(-versions)
518
-
519
- array = array.map(nameMapper(data.name))
520
- return selected.concat(array)
570
+ var list = data.released.slice(-versions)
571
+ list = list.map(nameMapper(data.name))
572
+ if (data.name === 'android') list = filterAndroid(list, versions)
573
+ return selected.concat(list)
521
574
  }, [])
522
575
  }
523
576
  },
524
577
  {
525
- regexp: /^last\s+(\d+)\s+electron\s+major versions?$/i,
578
+ regexp: /^last\s+(\d+)\s+electron\s+major\s+versions?$/i,
526
579
  select: function (context, versions) {
527
580
  var validVersions = getMajorVersions(Object.keys(e2c).reverse(), versions)
528
581
  return validVersions.map(function (i) {
@@ -531,11 +584,13 @@ var QUERIES = [
531
584
  }
532
585
  },
533
586
  {
534
- regexp: /^last\s+(\d+)\s+(\w+)\s+major versions?$/i,
587
+ regexp: /^last\s+(\d+)\s+(\w+)\s+major\s+versions?$/i,
535
588
  select: function (context, versions, name) {
536
589
  var data = checkName(name)
537
590
  var validVersions = getMajorVersions(data.released, versions)
538
- return validVersions.map(nameMapper(data.name))
591
+ var list = validVersions.map(nameMapper(data.name))
592
+ if (data.name === 'android') list = filterAndroid(list, versions)
593
+ return list
539
594
  }
540
595
  },
541
596
  {
@@ -550,7 +605,9 @@ var QUERIES = [
550
605
  regexp: /^last\s+(\d+)\s+(\w+)\s+versions?$/i,
551
606
  select: function (context, versions, name) {
552
607
  var data = checkName(name)
553
- return data.released.slice(-versions).map(nameMapper(data.name))
608
+ var list = data.released.slice(-versions).map(nameMapper(data.name))
609
+ if (data.name === 'android') list = filterAndroid(list, versions)
610
+ return list
554
611
  }
555
612
  },
556
613
  {
@@ -559,12 +616,11 @@ var QUERIES = [
559
616
  return Object.keys(agents).reduce(function (selected, name) {
560
617
  var data = byName(name)
561
618
  if (!data) return selected
562
- var array = data.versions.filter(function (v) {
619
+ var list = data.versions.filter(function (v) {
563
620
  return data.released.indexOf(v) === -1
564
621
  })
565
-
566
- array = array.map(nameMapper(data.name))
567
- return selected.concat(array)
622
+ list = list.map(nameMapper(data.name))
623
+ return selected.concat(list)
568
624
  }, [])
569
625
  }
570
626
  },
@@ -603,7 +659,6 @@ var QUERIES = [
603
659
  select: function (context, sign, popularity) {
604
660
  popularity = parseFloat(popularity)
605
661
  var usage = browserslist.usage.global
606
-
607
662
  return Object.keys(usage).reduce(function (result, version) {
608
663
  if (sign === '>') {
609
664
  if (usage[version] > popularity) {
@@ -628,13 +683,10 @@ var QUERIES = [
628
683
  regexp: /^(>=?|<=?)\s*(\d*\.?\d+)%\s+in\s+my\s+stats$/,
629
684
  select: function (context, sign, popularity) {
630
685
  popularity = parseFloat(popularity)
631
-
632
686
  if (!context.customUsage) {
633
687
  throw new BrowserslistError('Custom usage statistics was not provided')
634
688
  }
635
-
636
689
  var usage = context.customUsage
637
-
638
690
  return Object.keys(usage).reduce(function (result, version) {
639
691
  if (sign === '>') {
640
692
  if (usage[version] > popularity) {
@@ -659,16 +711,13 @@ var QUERIES = [
659
711
  regexp: /^(>=?|<=?)\s*(\d*\.?\d+)%\s+in\s+((alt-)?\w\w)$/,
660
712
  select: function (context, sign, popularity, place) {
661
713
  popularity = parseFloat(popularity)
662
-
663
714
  if (place.length === 2) {
664
715
  place = place.toUpperCase()
665
716
  } else {
666
717
  place = place.toLowerCase()
667
718
  }
668
-
669
719
  env.loadCountry(browserslist.usage, place)
670
720
  var usage = browserslist.usage[place]
671
-
672
721
  return Object.keys(usage).reduce(function (result, version) {
673
722
  if (sign === '>') {
674
723
  if (usage[version] > popularity) {
@@ -693,7 +742,6 @@ var QUERIES = [
693
742
  regexp: /^cover\s+(\d*\.?\d+)%(\s+in\s+(my\s+stats|(alt-)?\w\w))?$/,
694
743
  select: function (context, coverage, statMode) {
695
744
  coverage = parseFloat(coverage)
696
-
697
745
  var usage = browserslist.usage.global
698
746
  if (statMode) {
699
747
  if (statMode.match(/^\s+in\s+my\s+stats$/)) {
@@ -715,39 +763,35 @@ var QUERIES = [
715
763
  usage = browserslist.usage[place]
716
764
  }
717
765
  }
718
-
719
766
  var versions = Object.keys(usage).sort(function (a, b) {
720
767
  return usage[b] - usage[a]
721
768
  })
722
-
723
769
  var coveraged = 0
724
770
  var result = []
725
771
  var version
726
772
  for (var i = 0; i <= versions.length; i++) {
727
773
  version = versions[i]
728
774
  if (usage[version] === 0) break
729
-
730
775
  coveraged += usage[version]
731
776
  result.push(version)
732
777
  if (coveraged >= coverage) break
733
778
  }
734
-
735
779
  return result
736
780
  }
737
781
  },
738
782
  {
739
783
  regexp: /^electron\s+([\d.]+)\s*-\s*([\d.]+)$/i,
740
784
  select: function (context, from, to) {
741
- if (!e2c[from]) {
785
+ var fromToUse = normalizeElectron(from)
786
+ var toToUse = normalizeElectron(to)
787
+ if (!e2c[fromToUse]) {
742
788
  throw new BrowserslistError('Unknown version ' + from + ' of electron')
743
789
  }
744
- if (!e2c[to]) {
790
+ if (!e2c[toToUse]) {
745
791
  throw new BrowserslistError('Unknown version ' + to + ' of electron')
746
792
  }
747
-
748
793
  from = parseFloat(from)
749
794
  to = parseFloat(to)
750
-
751
795
  return Object.keys(e2c).filter(function (i) {
752
796
  var parsed = parseFloat(i)
753
797
  return parsed >= from && parsed <= to
@@ -760,22 +804,21 @@ var QUERIES = [
760
804
  regexp: /^(\w+)\s+([\d.]+)\s*-\s*([\d.]+)$/i,
761
805
  select: function (context, name, from, to) {
762
806
  var data = checkName(name)
763
- from = parseFloat(normalizeVersion(data, from) || from)
764
- to = parseFloat(normalizeVersion(data, to) || to)
765
-
807
+ from = parseFloat(normalizeVersion(data, from, context) || from)
808
+ to = parseFloat(normalizeVersion(data, to, context) || to)
766
809
  function filter (v) {
767
810
  var parsed = parseFloat(v)
768
811
  return parsed >= from && parsed <= to
769
812
  }
770
-
771
813
  return data.released.filter(filter).map(nameMapper(data.name))
772
814
  }
773
815
  },
774
816
  {
775
817
  regexp: /^electron\s*(>=?|<=?)\s*([\d.]+)$/i,
776
818
  select: function (context, sign, version) {
819
+ var versionToUse = normalizeElectron(version)
777
820
  return Object.keys(e2c)
778
- .filter(generateFilter(sign, version))
821
+ .filter(generateFilter(sign, versionToUse))
779
822
  .map(function (i) {
780
823
  return 'chrome ' + e2c[i]
781
824
  })
@@ -826,7 +869,8 @@ var QUERIES = [
826
869
  {
827
870
  regexp: /^electron\s+([\d.]+)$/i,
828
871
  select: function (context, version) {
829
- var chrome = e2c[version]
872
+ var versionToUse = normalizeElectron(version)
873
+ var chrome = e2c[versionToUse]
830
874
  if (!chrome) {
831
875
  throw new BrowserslistError(
832
876
  'Unknown version ' + version + ' of electron')
@@ -879,7 +923,7 @@ var QUERIES = [
879
923
  select: function (context, name, version) {
880
924
  if (/^tp$/i.test(version)) version = 'TP'
881
925
  var data = checkName(name)
882
- var alias = normalizeVersion(data, version)
926
+ var alias = normalizeVersion(data, version, context)
883
927
  if (alias) {
884
928
  version = alias
885
929
  } else {
@@ -888,7 +932,7 @@ var QUERIES = [
888
932
  } else {
889
933
  alias = version.replace(/\.0$/, '')
890
934
  }
891
- alias = normalizeVersion(data, alias)
935
+ alias = normalizeVersion(data, alias, context)
892
936
  if (alias) {
893
937
  version = alias
894
938
  } else if (context.ignoreUnknownVersions) {
@@ -913,6 +957,15 @@ var QUERIES = [
913
957
  return browserslist(browserslist.defaults)
914
958
  }
915
959
  },
960
+ {
961
+ regexp: /^android all$/i,
962
+ select: function () {
963
+ /* istanbul ignore next */
964
+ console.warn('BrowserslistError: Unknown browser query `android all`')
965
+ /* istanbul ignore next */
966
+ return []
967
+ }
968
+ },
916
969
  {
917
970
  regexp: /^dead$/i,
918
971
  select: function (context) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browserslist",
3
- "version": "4.5.6",
3
+ "version": "4.6.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,9 +11,9 @@
11
11
  "license": "MIT",
12
12
  "repository": "browserslist/browserslist",
13
13
  "dependencies": {
14
- "caniuse-lite": "^1.0.30000963",
15
- "electron-to-chromium": "^1.3.127",
16
- "node-releases": "^1.1.17"
14
+ "caniuse-lite": "^1.0.30000975",
15
+ "electron-to-chromium": "^1.3.164",
16
+ "node-releases": "^1.1.23"
17
17
  },
18
18
  "bin": "./cli.js",
19
19
  "browser": {