🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

browserslist

Package Overview
Dependencies
Maintainers
1
Versions
215
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

browserslist - npm Package Compare versions

Comparing version
4.28.6
to
4.28.7
+16
-7
index.js

@@ -402,5 +402,14 @@ var bbm = require('baseline-browser-mapping')

var cache = {}
var parseCache = {}
var CACHE_MAX_ENTRIES = 500
function boundedCacheSet(map, key, value) {
if (map.size >= CACHE_MAX_ENTRIES) {
map.delete(map.keys().next().value)
}
map.set(key, value)
}
var cache = new Map()
var parseCache = new Map()
function browserslist(queries, opts) {

@@ -436,3 +445,3 @@ opts = prepareOpts(opts)

var cacheKey = JSON.stringify([queries, context])
if (cache[cacheKey]) return cache[cacheKey]
if (cache.has(cacheKey)) return cache.get(cacheKey)

@@ -454,3 +463,3 @@ var result = uniq(resolve(queries, context)).sort(function (name1, name2) {

if (!env.env.BROWSERSLIST_DISABLE_CACHE) {
cache[cacheKey] = result
boundedCacheSet(cache, cacheKey, result)
}

@@ -462,6 +471,6 @@ return result

var cacheKey = JSON.stringify(queries)
if (cacheKey in parseCache) return parseCache[cacheKey]
if (parseCache.has(cacheKey)) return parseCache.get(cacheKey)
var result = parseWithoutCache(QUERIES, queries)
if (!env.env.BROWSERSLIST_DISABLE_CACHE) {
parseCache[cacheKey] = result
boundedCacheSet(parseCache, cacheKey, result)
}

@@ -830,3 +839,3 @@ return result

regexp:
/^baseline\s+(?:(\d+)|(newly|widely)\s+available(?:\s+on\s+(\d{4}-\d{2}-\d{2}))?)?(\s+with\s+downstream)?(\s+including\s+kaios)?$/i,
/^baseline\s+(?!\s)(?:(\d+)|(newly|widely)\s+(?!\s)available(?:\s+(?!\s)on\s+(?!\s)(\d{4}-\d{2}-\d{2}))?)?(\s+(?!\s)with\s+(?!\s)downstream)?(\s+(?!\s)including\s+(?!\s)kaios)?$/i,
select: function (context, node) {

@@ -833,0 +842,0 @@ var baselineVersions

@@ -10,3 +10,4 @@ var feature = require('caniuse-lite/dist/unpacker/feature').default

var CONFIG_PATTERN = /^browserslist-config-/
var SCOPED_CONFIG__PATTERN = /@[^/]+(?:\/[^/]+)?\/browserslist-config(?:-|$|\/)/
var SCOPED_CONFIG__PATTERN =
/^@[^/]+(?:\/[^/]+)?\/browserslist-config(?:-|$|\/)/
var FORMAT =

@@ -225,8 +226,9 @@ 'Browserslist config should be a string or an array ' +

var normalized = {}
var normalized = Object.create(null)
for (var i in stats) {
var versions = Object.keys(stats[i])
if (versions.length === 1 && data[i] && data[i].versions.length === 1) {
var normal = data[i].versions[0]
normalized[i] = {}
var known = Object.prototype.hasOwnProperty.call(data, i) && data[i]
if (versions.length === 1 && known && known.versions.length === 1) {
var normal = known.versions[0]
normalized[i] = Object.create(null)
normalized[i][normal] = stats[i][versions[0]]

@@ -233,0 +235,0 @@ } else {

{
"name": "browserslist",
"version": "4.28.6",
"version": "4.28.7",
"description": "Share target browsers between different front-end tools, like Autoprefixer, Stylelint and babel-env-preset",

@@ -36,5 +36,5 @@ "keywords": [

"dependencies": {
"baseline-browser-mapping": "^2.10.42",
"caniuse-lite": "^1.0.30001803",
"electron-to-chromium": "^1.5.389",
"baseline-browser-mapping": "^2.10.44",
"caniuse-lite": "^1.0.30001806",
"electron-to-chromium": "^1.5.393",
"node-releases": "^2.0.51",

@@ -41,0 +41,0 @@ "update-browserslist-db": "^1.2.3"

+94
-36

@@ -1,19 +0,20 @@

var AND_REGEXP = /^\s+and\s+(.*)/i
var OR_REGEXP = /^(?:,\s*|\s+or\s+)(.*)/i
var SPACE = /\s/
function flatten(array) {
if (!Array.isArray(array)) return [array]
return array.reduce(function (a, b) {
return a.concat(flatten(b))
}, [])
}
function find(string, predicate) {
for (var max = string.length, n = 1; n <= max; n++) {
var parsed = string.substr(-n, n)
if (predicate(parsed, n, max)) {
return string.slice(0, -n)
// Iterative flatten: `reduce`+`concat` copies the accumulator on every step,
// which is O(n²) once a query resolves to many nodes.
var result = []
var stack = [array]
while (stack.length) {
var item = stack.pop()
if (Array.isArray(item)) {
for (var i = item.length - 1; i >= 0; i--) {
stack.push(item[i])
}
} else {
result.push(item)
}
}
return ''
return result
}

@@ -44,23 +45,82 @@

function matchBlock(all, string, qs) {
var node
return find(string, function (parsed, n, max) {
if (AND_REGEXP.test(parsed)) {
node = matchQuery(all, parsed.match(AND_REGEXP)[1])
node.compose = 'and'
qs.unshift(node)
return true
} else if (OR_REGEXP.test(parsed)) {
node = matchQuery(all, parsed.match(OR_REGEXP)[1])
node.compose = 'or'
qs.unshift(node)
return true
} else if (n === max) {
node = matchQuery(all, parsed.trim())
node.compose = 'or'
qs.unshift(node)
return true
function pushClause(all, qs, text, compose) {
var node = matchQuery(all, text.trim())
node.compose = compose
qs.push(node)
}
// Splits a query block into clauses on the `\s+and\s+`, `\s+or\s+` and `,\s*`
// delimiters in a single left-to-right pass. The previous implementation grew
// a suffix one character at a time and re-tested anchored `\s+…` regexps at
// every length, which backtracks across whitespace runs and is O(n²) — a
// small padded query could freeze the event loop for tens of seconds.
function parseBlock(all, block, qs) {
if (block.length === 0) return
var len = block.length
var clauseStart = 0
// Compose for the clause currently being read; the leftmost clause is `or`.
var compose = 'or'
var i = 0
while (i < len) {
var ch = block[i]
if (ch === ',') {
// `,\s*` delimiter. A delimiter at the very start (i === 0) has no left
// clause — the original never emits one there.
if (i !== 0) pushClause(all, qs, block.slice(clauseStart, i), compose)
i++
while (i < len && SPACE.test(block[i])) i++
compose = 'or'
clauseStart = i
continue
}
return false
})
if (SPACE.test(ch)) {
// Possible `\s+and\s+` or `\s+or\s+`. Scan the whitespace run once
// (linear, no backtracking), then check the following keyword.
var q = i
while (q < len && SPACE.test(block[q])) q++
if (
q + 3 < len &&
(block[q] === 'a' || block[q] === 'A') &&
(block[q + 1] === 'n' || block[q + 1] === 'N') &&
(block[q + 2] === 'd' || block[q + 2] === 'D') &&
SPACE.test(block[q + 3])
) {
// The leading `\s+` of `\s+and\s+` absorbs whitespace at the block
// start, so a delimiter at i === 0 has no left clause.
if (i !== 0) pushClause(all, qs, block.slice(clauseStart, i), compose)
var afterAnd = q + 3
while (afterAnd < len && SPACE.test(block[afterAnd])) afterAnd++
compose = 'and'
i = afterAnd
clauseStart = afterAnd
continue
} else if (
q + 2 < len &&
(block[q] === 'o' || block[q] === 'O') &&
(block[q + 1] === 'r' || block[q + 1] === 'R') &&
SPACE.test(block[q + 2])
) {
if (i !== 0) pushClause(all, qs, block.slice(clauseStart, i), compose)
var afterOr = q + 2
while (afterOr < len && SPACE.test(block[afterOr])) afterOr++
compose = 'or'
i = afterOr
clauseStart = afterOr
continue
} else {
// Whitespace inside a clause; skip the run and keep reading.
i = q
continue
}
}
i++
}
pushClause(all, qs, block.slice(clauseStart), compose)
}

@@ -73,5 +133,3 @@

var qs = []
do {
block = matchBlock(all, block, qs)
} while (block)
parseBlock(all, block, qs)
return qs

@@ -78,0 +136,0 @@ })