-
Notifications
You must be signed in to change notification settings - Fork 4
/
SemVer.js
37 lines (30 loc) · 1.2 KB
/
SemVer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import { compareStringWithNumber } from 'source/common/compare'
const REGEXP_SEMVER = /^(\d+)\.(\d+)\.(\d+)(.*)$/ // simple match
const parseSemVer = (versionString) => {
let [ , major, minor, patch, label = '' ] = REGEXP_SEMVER.exec(versionString) || []
major = parseInt(major)
minor = parseInt(minor)
patch = parseInt(patch)
if (isNaN(major) || isNaN(minor) || isNaN(patch)) throw new Error(`invalid version: ${versionString}`) // TODO: remove func name in error (should use stack mostly)
return { major, minor, patch, label }
}
const compareSemVer = (stringA, stringB) => { // basically (a - b)
const a = parseSemVer(stringA)
const b = parseSemVer(stringB)
return (
(a.major - b.major) ||
(a.minor - b.minor) ||
(a.patch - b.patch) ||
compareSemVerLabel(a.label, b.label)
)
}
const compareSemVerLabel = (a, b) => (a === b) ? 0
: isShorterWithoutNumber(a, b) ? 1
: isShorterWithoutNumber(b, a) ? -1
: compareStringWithNumber(a, b)
const REGEXP_DOUBLE_NUMBER = /\d\d/
const isShorterWithoutNumber = (shorter, longer) => (
longer.startsWith(shorter) &&
!REGEXP_DOUBLE_NUMBER.test(longer.slice(shorter.length - 1, shorter.length + 1))
)
export { parseSemVer, compareSemVer }