Skip to content

Commit a868100

Browse files
committed
Fixes #41 Minor version ranges not respected
1 parent c6ff3c6 commit a868100

File tree

4 files changed

+87
-43
lines changed

4 files changed

+87
-43
lines changed

index.js

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,28 @@ const semverify = (version) => {
130130
return split.join('.')
131131
}
132132

133+
function flatten(arr) {
134+
return arr.reduce(function (flat, toFlatten) {
135+
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
136+
}, []);
137+
}
138+
139+
// 10.0-10.2 -> 10.0, 10.1, 10.2
140+
function generateSemversInRange(versionRange) {
141+
const [start, end] = versionRange.split('-')
142+
const startSemver = semverify(start)
143+
const endSemver = semverify(end)
144+
const versionsInRange = [];
145+
let curVersion = startSemver;
146+
147+
while (semver.gte(endSemver, curVersion)) {
148+
versionsInRange.push(curVersion)
149+
curVersion = semver.inc(curVersion, 'minor')
150+
}
151+
152+
return versionsInRange;
153+
}
154+
133155
function normalizeQuery(query) {
134156
let normalizedQuery = query
135157
const regex = `(${Object.keys(browserNameMap).join('|')})`
@@ -143,7 +165,7 @@ function normalizeQuery(query) {
143165
}
144166

145167
const parseBrowsersList = (browsersList) => {
146-
return browsersList.map(browser => {
168+
const browsers = browsersList.map(browser => {
147169
const [browserName, browserVersion] = browser.split(' ')
148170

149171
let normalizedName = browserName
@@ -153,17 +175,22 @@ const parseBrowsersList = (browsersList) => {
153175
normalizedName = browserNameMap[browserName]
154176
}
155177

156-
try {
157-
// Browser version can return as "10.0-10.2"
158-
normalizedVersion = browserVersion.split('-')[0]
159-
} catch (e) {
160-
}
161-
162-
return {
163-
family: normalizedName,
164-
version: normalizedVersion,
178+
// browserslist might return ranges (9.0-9.2), unwrap them
179+
// see https://github.com/browserslist/browserslist-useragent/issues/41
180+
if (browserVersion.indexOf('-') > 0) {
181+
return generateSemversInRange(browserVersion).map(version => ({
182+
family: normalizedName,
183+
version,
184+
}))
185+
} else {
186+
return {
187+
family: normalizedName,
188+
version: normalizedVersion,
189+
}
165190
}
166191
})
192+
193+
return flatten(browsers);
167194
}
168195

169196
const compareBrowserSemvers = (versionA, versionB, options) => {
@@ -196,6 +223,7 @@ const matchesUA = (uaString, opts = {}) => {
196223
path: process.cwd()
197224
})
198225
const parsedBrowsers = parseBrowsersList(browsers)
226+
199227
const resolvedUserAgent = resolveUserAgent(uaString)
200228

201229
const options = {

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
"build": "mkdir -p lib && babel index.js --out-file lib/index.js"
2020
},
2121
"dependencies": {
22-
"browserslist": "^4.3.6",
23-
"semver": "^5.6.0",
22+
"browserslist": "^4.6.6",
23+
"semver": "^6.3.0",
2424
"useragent": "^2.3.0"
2525
},
2626
"devDependencies": {

tests/index.test.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ const ua = require('useragent-generator')
33
const { resolveUserAgent, matchesUA, normalizeQuery } = require('../index')
44

55
const CustomUserAgentString = {
6-
YANDEX: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 YaBrowser/18.1.1.839 Yowser/2.5 Safari/537.36",
7-
SAMSUNG_BROWSER_7_2: "Mozilla/5.0 (Linux; Android 6.0.1; SAMSUNG SM-N930F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/7.2 Chrome/63.0.3239.111 Mobile Safari/537.36",
6+
YANDEX: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 YaBrowser/18.1.1.839 Yowser/2.5 Safari/537.36',
7+
SAMSUNG_BROWSER_7_2: 'Mozilla/5.0 (Linux; Android 6.0.1; SAMSUNG SM-N930F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/7.2 Chrome/63.0.3239.111 Mobile Safari/537.36',
88
}
99

1010
it('normalizes queries properly', () => {
@@ -174,12 +174,12 @@ it('detects if browserslist matches UA', () => {
174174
.toBeTruthy()
175175

176176
const modernList = [
177-
"Firefox >= 53",
178-
"Edge >= 15",
179-
"Chrome >= 58",
180-
"iOS >= 10",
181-
"Safari >= 11",
182-
"Samsung >= 7"
177+
'Firefox >= 53',
178+
'Edge >= 15',
179+
'Chrome >= 58',
180+
'iOS >= 10',
181+
'Safari >= 11',
182+
'Samsung >= 7'
183183
]
184184

185185
expect(matchesUA(ua.safari.iOS(9), { browsers: modernList }))
@@ -278,3 +278,19 @@ it('parses semvers liberally', () => {
278278
matchesUA('Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.0.0001', { browsers: ['opera >= 12'] }))
279279
.toBeTruthy()
280280
})
281+
282+
it('can deal with version ranges (if returned by browserslist)', () => {
283+
expect(
284+
matchesUA(ua.safari.iOS('9.1.0'), { browsers: ['ios_saf >= 9'] }))
285+
.toBeTruthy()
286+
287+
expect(
288+
matchesUA(ua.safari.iOS('9.0.0'), { browsers: ['ios_saf >= 9'] }))
289+
.toBeTruthy()
290+
291+
// This should fail
292+
// see https://github.com/browserslist/browserslist/issues/402
293+
expect(
294+
matchesUA(ua.safari.iOS('9.1.0'), { browsers: ['ios_saf >= 9.2'] }))
295+
.toBeTruthy() // <-- should actually be falsy
296+
})

yarn.lock

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -901,14 +901,14 @@ browser-resolve@^1.11.3:
901901
dependencies:
902902
resolve "1.1.7"
903903

904-
browserslist@^4.3.6:
905-
version "4.3.6"
906-
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.6.tgz#0f9d9081afc66b36f477c6bdf3813f784f42396a"
907-
integrity sha512-kMGKs4BTzRWviZ8yru18xBpx+CyHG9eqgRbj9XbE3IMgtczf4aiA0Y1YCpVdvUieKGZ03kolSPXqTcscBCb9qw==
904+
browserslist@^4.6.6:
905+
version "4.6.6"
906+
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453"
907+
integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==
908908
dependencies:
909-
caniuse-lite "^1.0.30000921"
910-
electron-to-chromium "^1.3.92"
911-
node-releases "^1.1.1"
909+
caniuse-lite "^1.0.30000984"
910+
electron-to-chromium "^1.3.191"
911+
node-releases "^1.1.25"
912912

913913
bser@^2.0.0:
914914
version "2.0.0"
@@ -950,10 +950,10 @@ camelcase@^4.1.0:
950950
version "4.1.0"
951951
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
952952

953-
caniuse-lite@^1.0.30000921:
954-
version "1.0.30000921"
955-
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000921.tgz#7a607c1623444b22351d834e093aedda3c42fbe8"
956-
integrity sha512-Bu09ciy0lMWLgpYC77I0YGuI8eFRBPPzaSOYJK1jTI64txCphYCqnWbxJYjHABYVt/TYX/p3jNjLBR87u1Bfpw==
953+
caniuse-lite@^1.0.30000984:
954+
version "1.0.30000987"
955+
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738"
956+
integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g==
957957

958958
caseless@~0.12.0:
959959
version "0.12.0"
@@ -1241,10 +1241,10 @@ ecc-jsbn@~0.1.1:
12411241
dependencies:
12421242
jsbn "~0.1.0"
12431243

1244-
electron-to-chromium@^1.3.92:
1245-
version "1.3.92"
1246-
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.92.tgz#9027b5abaea400045edd652c0e4838675c814399"
1247-
integrity sha512-En051LMzMl3/asMWGZEtU808HOoVWIpmmZx1Ep8N+TT9e7z/X8RcLeBU2kLSNLGQ+5SuKELzMx+MVuTBXk6Q9w==
1244+
electron-to-chromium@^1.3.191:
1245+
version "1.3.206"
1246+
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.206.tgz#f72a8694dce5c669170c78097177d7b601977c10"
1247+
integrity sha512-djq9Ehxs2rwPh7pyY1GMf8vkOWPoK8eoMp913E4t0UaEXvbnOsiSowBBHI8YoN4aKVQJjvxQp5I0LdZkT3Uzmw==
12481248

12491249
error-ex@^1.2.0:
12501250
version "1.3.1"
@@ -2728,10 +2728,10 @@ node-pre-gyp@^0.6.36:
27282728
tar "^2.2.1"
27292729
tar-pack "^3.4.0"
27302730

2731-
node-releases@^1.1.1:
2732-
version "1.1.1"
2733-
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.1.tgz#8fff8aea1cfcad1fb4205f805149054fbf73cafd"
2734-
integrity sha512-2UXrBr6gvaebo5TNF84C66qyJJ6r0kxBObgZIDX3D3/mt1ADKiHux3NJPWisq0wxvJJdkjECH+9IIKYViKj71Q==
2731+
node-releases@^1.1.25:
2732+
version "1.1.26"
2733+
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.26.tgz#f30563edc5c7dc20cf524cc8652ffa7be0762937"
2734+
integrity sha512-fZPsuhhUHMTlfkhDLGtfY80DSJTjOcx+qD1j5pqPkuhUHVS7xHZIg9EE4DHK8O3f0zTxXHX5VIkDG8pu98/wfQ==
27352735
dependencies:
27362736
semver "^5.3.0"
27372737

@@ -3334,10 +3334,10 @@ semver@^5.4.1, semver@^5.5.0:
33343334
version "5.5.0"
33353335
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
33363336

3337-
semver@^5.6.0:
3338-
version "5.6.0"
3339-
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
3340-
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
3337+
semver@^6.3.0:
3338+
version "6.3.0"
3339+
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
3340+
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
33413341

33423342
set-blocking@^2.0.0, set-blocking@~2.0.0:
33433343
version "2.0.0"

0 commit comments

Comments
 (0)