(v1, v2)
| 228 | } |
| 229 | |
| 230 | function compareVersions(v1, v2) { |
| 231 | if (!v1 || !v2) return 0 |
| 232 | |
| 233 | if (!v1.match(/^\d+(\.\d+)*$/)) { |
| 234 | return -1 |
| 235 | } |
| 236 | |
| 237 | const parseVersion = (version) => { |
| 238 | const parts = version.split('-') |
| 239 | const mainParts = parts[0].split('.').map(Number) |
| 240 | const prereleaseParts = parts[1] ? parts[1].split('.') : [] |
| 241 | return { main: mainParts, prerelease: prereleaseParts } |
| 242 | } |
| 243 | |
| 244 | const p1 = parseVersion(v1) |
| 245 | const p2 = parseVersion(v2) |
| 246 | |
| 247 | for (let i = 0; i < Math.max(p1.main.length, p2.main.length); i++) { |
| 248 | const n1 = p1.main[i] || 0 |
| 249 | const n2 = p2.main[i] || 0 |
| 250 | |
| 251 | if (n1 < n2) return -1 |
| 252 | if (n1 > n2) return 1 |
| 253 | } |
| 254 | |
| 255 | if (p1.prerelease.length === 0 && p2.prerelease.length === 0) { |
| 256 | return 0 |
| 257 | } else if (p1.prerelease.length === 0) { |
| 258 | return 1 |
| 259 | } else if (p2.prerelease.length === 0) { |
| 260 | return -1 |
| 261 | } else { |
| 262 | for ( |
| 263 | let i = 0; |
| 264 | i < Math.max(p1.prerelease.length, p2.prerelease.length); |
| 265 | i++ |
| 266 | ) { |
| 267 | const pr1 = p1.prerelease[i] || '' |
| 268 | const pr2 = p2.prerelease[i] || '' |
| 269 | |
| 270 | const isNum1 = !isNaN(parseInt(pr1)) |
| 271 | const isNum2 = !isNaN(parseInt(pr2)) |
| 272 | |
| 273 | if (isNum1 && isNum2) { |
| 274 | const num1 = parseInt(pr1) |
| 275 | const num2 = parseInt(pr2) |
| 276 | if (num1 < num2) return -1 |
| 277 | if (num1 > num2) return 1 |
| 278 | } else if (isNum1 && !isNum2) { |
| 279 | return 1 |
| 280 | } else if (!isNum1 && isNum2) { |
| 281 | return -1 |
| 282 | } else if (pr1 < pr2) { |
| 283 | return -1 |
| 284 | } else if (pr1 > pr2) { |
| 285 | return 1 |
| 286 | } |
| 287 | } |
no test coverage detected