In the context of SemVer the individual components, major, minor and patch are integers however the composite value, major.minor.patch is not a valid number itself. This is why they are stored as strings, the period is merely a delimiter and not a decimal point.
To correctly compare versions you need to break the strings into their component parts and compare each pair of numbers individually. The following example does this by sorting in descending order then taking the first value.
Note: As it is unclear from the question what exactly the requirements are, abbreviated versions e.g. 1.1
, will be treated as 1.1.0
here for the sake of simplicity - where typically it is more idiomatic to say that 1.1
represents the highest version of 1.1.x
available for a given set.
const cmpVersionDesc = (a, b) => {
const as = a.split('.').map(Number)
const bs = b.split('.').map(Number)
return (bs[0]||0) - (as[0]||0)
|| (bs[1]||0) - (as[1]||0)
|| (bs[2]||0) - (as[2]||0)
}
const latestVersion = versions =>
[...versions].sort(cmpVersionDesc)[0]
const versions = [
'16.9',
'16.12',
'16.12.1',
'16.1'
]
console.log('latest', latestVersion(versions)) // '16.12.1'