browserslist 4.24.3 → 4.24.5

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 (3) hide show
  1. package/index.js +23 -4
  2. package/node.js +117 -96
  3. package/package.json +4 -4
package/index.js CHANGED
@@ -6,7 +6,7 @@ var path = require('path')
6
6
 
7
7
  var BrowserslistError = require('./error')
8
8
  var env = require('./node')
9
- var parse = require('./parse') // Will load browser.js in webpack
9
+ var parseWithoutCache = require('./parse') // Will load browser.js in webpack
10
10
 
11
11
  var YEAR = 365.259641 * 24 * 60 * 60 * 1000
12
12
  var ANDROID_EVERGREEN_FIRST = '37'
@@ -319,7 +319,7 @@ function isSupported(flags, withPartial) {
319
319
  }
320
320
 
321
321
  function resolve(queries, context) {
322
- return parse(QUERIES, queries).reduce(function (result, node, index) {
322
+ return parseQueries(queries).reduce(function (result, node, index) {
323
323
  if (node.not && index === 0) {
324
324
  throw new BrowserslistError(
325
325
  'Write any browsers query (for instance, `defaults`) ' +
@@ -395,19 +395,26 @@ function checkQueries(queries) {
395
395
  }
396
396
 
397
397
  var cache = {}
398
+ var parseCache = {}
398
399
 
399
400
  function browserslist(queries, opts) {
400
401
  opts = prepareOpts(opts)
401
402
  queries = prepareQueries(queries, opts)
402
403
  checkQueries(queries)
403
404
 
405
+ var needsPath = parseQueries(queries).some(function (node) {
406
+ return QUERIES[node.type].needsPath
407
+ })
404
408
  var context = {
405
409
  ignoreUnknownVersions: opts.ignoreUnknownVersions,
406
410
  dangerousExtend: opts.dangerousExtend,
407
411
  mobileToDesktop: opts.mobileToDesktop,
408
- path: opts.path,
409
412
  env: opts.env
410
413
  }
414
+ // Removing to avoid using context.path without marking query as needsPath
415
+ if (needsPath) {
416
+ context.path = opts.path
417
+ }
411
418
 
412
419
  env.oldDataWarning(browserslist.data)
413
420
  var stats = env.getStat(opts, browserslist.data)
@@ -441,11 +448,21 @@ function browserslist(queries, opts) {
441
448
  return result
442
449
  }
443
450
 
451
+ function parseQueries(queries) {
452
+ var cacheKey = JSON.stringify(queries)
453
+ if (cacheKey in parseCache) return parseCache[cacheKey]
454
+ var result = parseWithoutCache(QUERIES, queries)
455
+ if (!env.env.BROWSERSLIST_DISABLE_CACHE) {
456
+ parseCache[cacheKey] = result
457
+ }
458
+ return result
459
+ }
460
+
444
461
  browserslist.parse = function (queries, opts) {
445
462
  opts = prepareOpts(opts)
446
463
  queries = prepareQueries(queries, opts)
447
464
  checkQueries(queries)
448
- return parse(QUERIES, queries)
465
+ return parseQueries(queries)
449
466
  }
450
467
 
451
468
  // Will be filled by Can I Use data below
@@ -1133,6 +1150,7 @@ var QUERIES = {
1133
1150
  browserslist_config: {
1134
1151
  matches: [],
1135
1152
  regexp: /^browserslist config$/i,
1153
+ needsPath: true,
1136
1154
  select: function (context) {
1137
1155
  return browserslist(undefined, context)
1138
1156
  }
@@ -1140,6 +1158,7 @@ var QUERIES = {
1140
1158
  extends: {
1141
1159
  matches: ['config'],
1142
1160
  regexp: /^extends (.+)$/i,
1161
+ needsPath: true,
1143
1162
  select: function (context, node) {
1144
1163
  return resolve(env.loadQueries(context, node.config), context)
1145
1164
  }
package/node.js CHANGED
@@ -13,8 +13,10 @@ var FORMAT =
13
13
  'of strings with browser queries'
14
14
 
15
15
  var dataTimeChecked = false
16
- var filenessCache = {}
17
- var configCache = {}
16
+ var statCache = {}
17
+ var configPathCache = {}
18
+ var parseConfigCache = {}
19
+
18
20
  function checkExtend(name) {
19
21
  var use = ' Use `dangerousExtend` option to disable.'
20
22
  if (!CONFIG_PATTERN.test(name) && !SCOPED_CONFIG__PATTERN.test(name)) {
@@ -35,25 +37,43 @@ function checkExtend(name) {
35
37
  }
36
38
 
37
39
  function isFile(file) {
38
- if (file in filenessCache) {
39
- return filenessCache[file]
40
- }
41
- var result = fs.existsSync(file) && fs.statSync(file).isFile()
42
- if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
43
- filenessCache[file] = result
44
- }
45
- return result
40
+ return fs.existsSync(file) && fs.statSync(file).isFile()
41
+ }
42
+ function isDirectory(dir) {
43
+ return fs.existsSync(dir) && fs.statSync(dir).isDirectory()
46
44
  }
47
45
 
48
- function eachParent(file, callback) {
49
- var dir = isFile(file) ? path.dirname(file) : file
50
- var loc = path.resolve(dir)
46
+ function eachParent(file, callback, cache) {
47
+ var loc = path.resolve(file)
48
+ var pathsForCacheResult = []
49
+ var result
51
50
  do {
52
- if (!pathInRoot(loc)) break
53
- var result = callback(loc)
54
- if (typeof result !== 'undefined') return result
51
+ if (!pathInRoot(loc)) {
52
+ break
53
+ }
54
+ if (cache && loc in cache) {
55
+ result = cache[loc]
56
+ break
57
+ }
58
+ pathsForCacheResult.push(loc)
59
+
60
+ if (!isDirectory(loc)) {
61
+ continue
62
+ }
63
+
64
+ var locResult = callback(loc)
65
+ if (typeof locResult !== 'undefined') {
66
+ result = locResult
67
+ break
68
+ }
55
69
  } while (loc !== (loc = path.dirname(loc)))
56
- return undefined
70
+
71
+ if (cache && !process.env.BROWSERSLIST_DISABLE_CACHE) {
72
+ pathsForCacheResult.forEach(function (cachePath) {
73
+ cache[cachePath] = result
74
+ })
75
+ }
76
+ return result
57
77
  }
58
78
 
59
79
  function pathInRoot(p) {
@@ -103,18 +123,21 @@ function pickEnv(config, opts) {
103
123
  }
104
124
 
105
125
  function parsePackage(file) {
106
- var config = JSON.parse(
107
- fs
108
- .readFileSync(file)
109
- .toString()
110
- .replace(/^\uFEFF/m, '')
111
- )
112
- if (config.browserlist && !config.browserslist) {
113
- throw new BrowserslistError(
114
- '`browserlist` key instead of `browserslist` in ' + file
115
- )
126
+ var text = fs
127
+ .readFileSync(file)
128
+ .toString()
129
+ .replace(/^\uFEFF/m, '')
130
+ var list
131
+ if (text.indexOf('"browserslist"') >= 0) {
132
+ list = JSON.parse(text).browserslist
133
+ } else if (text.indexOf('"browserlist"') >= 0) {
134
+ var config = JSON.parse(text)
135
+ if (config.browserlist && !config.browserslist) {
136
+ throw new BrowserslistError(
137
+ '`browserlist` key instead of `browserslist` in ' + file
138
+ )
139
+ }
116
140
  }
117
- var list = config.browserslist
118
141
  if (Array.isArray(list) || typeof list === 'string') {
119
142
  list = { defaults: list }
120
143
  }
@@ -126,11 +149,17 @@ function parsePackage(file) {
126
149
  }
127
150
 
128
151
  function parsePackageOrReadConfig(file) {
129
- if (path.basename(file) === 'package.json') {
130
- return parsePackage(file)
131
- } else {
132
- return module.exports.readConfig(file)
152
+ if (file in parseConfigCache) {
153
+ return parseConfigCache[file]
133
154
  }
155
+
156
+ var isPackage = path.basename(file) === 'package.json'
157
+ var result = isPackage ? parsePackage(file) : module.exports.readConfig(file)
158
+
159
+ if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
160
+ parseConfigCache[file] = result
161
+ }
162
+ return result
134
163
  }
135
164
 
136
165
  function latestReleaseTime(agents) {
@@ -200,6 +229,9 @@ module.exports = {
200
229
  checkExtend(name)
201
230
  }
202
231
  var queries = require(require.resolve(name, { paths: ['.', ctx.path] }))
232
+ if (typeof queries === 'object' && queries !== null && queries.__esModule) {
233
+ queries = queries.default
234
+ }
203
235
  if (queries) {
204
236
  if (Array.isArray(queries)) {
205
237
  return queries
@@ -234,10 +266,14 @@ module.exports = {
234
266
  } else if (process.env.BROWSERSLIST_STATS) {
235
267
  stats = process.env.BROWSERSLIST_STATS
236
268
  } else if (opts.path && path.resolve && fs.existsSync) {
237
- stats = eachParent(opts.path, function (dir) {
238
- var file = path.join(dir, 'browserslist-stats.json')
239
- return isFile(file) ? file : undefined
240
- })
269
+ stats = eachParent(
270
+ opts.path,
271
+ function (dir) {
272
+ var file = path.join(dir, 'browserslist-stats.json')
273
+ return isFile(file) ? file : undefined
274
+ },
275
+ statCache
276
+ )
241
277
  }
242
278
  if (typeof stats === 'string') {
243
279
  try {
@@ -340,81 +376,66 @@ module.exports = {
340
376
  if (!isFile(file)) {
341
377
  throw new BrowserslistError("Can't read " + file + ' config')
342
378
  }
379
+
343
380
  return module.exports.parseConfig(fs.readFileSync(file))
344
381
  },
345
382
 
346
383
  findConfigFile: function findConfigFile(from) {
347
- var resolved = eachParent(from, function (dir) {
348
- var config = path.join(dir, 'browserslist')
349
- var pkg = path.join(dir, 'package.json')
350
- var rc = path.join(dir, '.browserslistrc')
351
-
352
- var pkgBrowserslist
353
- if (isFile(pkg)) {
354
- try {
355
- pkgBrowserslist = parsePackage(pkg)
356
- } catch (e) {
357
- if (e.name === 'BrowserslistError') throw e
358
- console.warn(
359
- '[Browserslist] Could not parse ' + pkg + '. Ignoring it.'
360
- )
384
+ return eachParent(
385
+ from,
386
+ function (dir) {
387
+ var config = path.join(dir, 'browserslist')
388
+ var pkg = path.join(dir, 'package.json')
389
+ var rc = path.join(dir, '.browserslistrc')
390
+
391
+ var pkgBrowserslist
392
+ if (isFile(pkg)) {
393
+ try {
394
+ pkgBrowserslist = parsePackage(pkg)
395
+ } catch (e) {
396
+ if (e.name === 'BrowserslistError') throw e
397
+ console.warn(
398
+ '[Browserslist] Could not parse ' + pkg + '. Ignoring it.'
399
+ )
400
+ }
361
401
  }
362
- }
363
-
364
- if (isFile(config) && pkgBrowserslist) {
365
- throw new BrowserslistError(
366
- dir + ' contains both browserslist and package.json with browsers'
367
- )
368
- } else if (isFile(rc) && pkgBrowserslist) {
369
- throw new BrowserslistError(
370
- dir + ' contains both .browserslistrc and package.json with browsers'
371
- )
372
- } else if (isFile(config) && isFile(rc)) {
373
- throw new BrowserslistError(
374
- dir + ' contains both .browserslistrc and browserslist'
375
- )
376
- } else if (isFile(config)) {
377
- return config
378
- } else if (isFile(rc)) {
379
- return rc
380
- } else if (pkgBrowserslist) {
381
- return pkg
382
- }
383
- })
384
402
 
385
- return resolved
403
+ if (isFile(config) && pkgBrowserslist) {
404
+ throw new BrowserslistError(
405
+ dir + ' contains both browserslist and package.json with browsers'
406
+ )
407
+ } else if (isFile(rc) && pkgBrowserslist) {
408
+ throw new BrowserslistError(
409
+ dir +
410
+ ' contains both .browserslistrc and package.json with browsers'
411
+ )
412
+ } else if (isFile(config) && isFile(rc)) {
413
+ throw new BrowserslistError(
414
+ dir + ' contains both .browserslistrc and browserslist'
415
+ )
416
+ } else if (isFile(config)) {
417
+ return config
418
+ } else if (isFile(rc)) {
419
+ return rc
420
+ } else if (pkgBrowserslist) {
421
+ return pkg
422
+ }
423
+ },
424
+ configPathCache
425
+ )
386
426
  },
387
427
 
388
428
  findConfig: function findConfig(from) {
389
- from = path.resolve(from)
390
-
391
- var fromDir = isFile(from) ? path.dirname(from) : from
392
- if (fromDir in configCache) {
393
- return configCache[fromDir]
394
- }
395
-
396
- var resolved
397
429
  var configFile = this.findConfigFile(from)
398
- if (configFile) {
399
- resolved = parsePackageOrReadConfig(configFile)
400
- }
401
430
 
402
- if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
403
- var configDir = configFile && path.dirname(configFile)
404
- eachParent(from, function (dir) {
405
- configCache[dir] = resolved
406
- if (dir === configDir) {
407
- return null
408
- }
409
- })
410
- }
411
- return resolved
431
+ return configFile ? parsePackageOrReadConfig(configFile) : undefined
412
432
  },
413
433
 
414
434
  clearCaches: function clearCaches() {
415
435
  dataTimeChecked = false
416
- filenessCache = {}
417
- configCache = {}
436
+ statCache = {}
437
+ configPathCache = {}
438
+ parseConfigCache = {}
418
439
 
419
440
  this.cache = {}
420
441
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browserslist",
3
- "version": "4.24.3",
3
+ "version": "4.24.5",
4
4
  "description": "Share target browsers between different front-end tools, like Autoprefixer, Stylelint and babel-env-preset",
5
5
  "keywords": [
6
6
  "caniuse",
@@ -25,10 +25,10 @@
25
25
  "license": "MIT",
26
26
  "repository": "browserslist/browserslist",
27
27
  "dependencies": {
28
- "caniuse-lite": "^1.0.30001688",
29
- "electron-to-chromium": "^1.5.73",
28
+ "caniuse-lite": "^1.0.30001716",
29
+ "electron-to-chromium": "^1.5.149",
30
30
  "node-releases": "^2.0.19",
31
- "update-browserslist-db": "^1.1.1"
31
+ "update-browserslist-db": "^1.1.3"
32
32
  },
33
33
  "engines": {
34
34
  "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"