Flatlogic Bot c2aa0f3687 V5
2026-02-16 07:39:54 +00:00

209 lines
3.9 KiB
JavaScript

const errors = require('./errors')
class Version {
constructor(major, minor, patch, opts = {}) {
const { prerelease = [], build = [] } = opts
this.major = major
this.minor = minor
this.patch = patch
this.prerelease = prerelease
this.build = build
}
compare(version) {
return exports.compare(this, version)
}
toString() {
let result = `${this.major}.${this.minor}.${this.patch}`
if (this.prerelease.length) {
result += '-' + this.prerelease.join('.')
}
if (this.build.length) {
result += '+' + this.build.join('.')
}
return result
}
}
module.exports = exports = Version
exports.parse = function parse(
input,
state = { position: 0, partial: false, range: false }
) {
let i = state.position
let c
const unexpected = (expected) => {
let msg
if (i >= input.length) {
msg = `Unexpected end of input in '${input}'`
} else {
msg = `Unexpected token '${input[i]}' in '${input}' at position ${i}`
}
if (expected) msg += `, ${expected}`
throw errors.INVALID_VERSION(msg, unexpected)
}
const components = [0, 0, 0]
let k = 0
while (k < 3) {
c = input[i]
if (k > 0) {
if (c === '.') c = input[++i]
else if (state.range) break
else unexpected("expected '.'")
}
if (c === '0') {
i++
k++
} else if (c >= '1' && c <= '9') {
let j = 0
do c = input[i + ++j]
while (c >= '0' && c <= '9')
components[k++] = parseInt(input.substring(i, i + j))
i += j
} else unexpected('expected /[0-9]/')
}
const prerelease = []
if (k === 3 && input[i] === '-') {
i++
while (true) {
c = input[i]
let tag = ''
let j = 0
while (c >= '0' && c <= '9') c = input[i + ++j]
let isNumeric = false
if (j) {
tag += input.substring(i, i + j)
c = input[(i += j)]
isNumeric = tag[0] !== '0' || tag.length === 1
}
j = 0
while (
(c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
c === '-'
)
c = input[i + ++j]
if (j) {
tag += input.substring(i, i + j)
c = input[(i += j)]
} else if (!isNumeric) unexpected('expected /[a-zA-Z-]/')
prerelease.push(tag)
if (c === '.') c = input[++i]
else break
}
}
const build = []
if (k === 3 && input[i] === '+') {
i++
while (true) {
c = input[i]
let tag = ''
let j = 0
while (
(c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
c === '-'
)
c = input[i + ++j]
if (j) {
tag += input.substring(i, i + j)
c = input[(i += j)]
} else unexpected('expected /[0-9a-zA-Z-]/')
build.push(tag)
if (c === '.') c = input[++i]
else break
}
}
if (i < input.length && state.partial === false) {
unexpected('expected end of input')
}
state.position = i
return new Version(...components, { prerelease, build })
}
const integer = /^[0-9]+$/
exports.compare = function compare(a, b) {
if (a.major > b.major) return 1
if (a.major < b.major) return -1
if (a.minor > b.minor) return 1
if (a.minor < b.minor) return -1
if (a.patch > b.patch) return 1
if (a.patch < b.patch) return -1
if (a.prerelease.length === 0) return b.prerelease.length === 0 ? 0 : 1
if (b.prerelease.length === 0) return -1
let i = 0
do {
let x = a.prerelease[i]
let y = b.prerelease[i]
if (x === undefined) return y === undefined ? 0 : -1
if (y === undefined) return 1
if (x === y) continue
const xInt = integer.test(x)
const yInt = integer.test(y)
if (xInt && yInt) {
x = +x
y = +y
} else {
if (xInt) return -1
if (yInt) return 1
}
return x > y ? 1 : -1
} while (++i)
}