122 lines
2.4 KiB
JavaScript
122 lines
2.4 KiB
JavaScript
const constants = require('./constants')
|
|
const errors = require('./errors')
|
|
const Version = require('./version')
|
|
const Comparator = require('./comparator')
|
|
|
|
class Range {
|
|
constructor(comparators = []) {
|
|
this.comparators = comparators
|
|
}
|
|
|
|
test(version) {
|
|
for (const set of this.comparators) {
|
|
let matches = true
|
|
|
|
for (const comparator of set) {
|
|
if (comparator.test(version)) continue
|
|
matches = false
|
|
break
|
|
}
|
|
|
|
if (matches) return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
toString() {
|
|
let result = ''
|
|
let first = true
|
|
|
|
for (const set of this.comparators) {
|
|
if (first) first = false
|
|
else result += ' || '
|
|
|
|
result += set.join(' ')
|
|
}
|
|
|
|
return result
|
|
}
|
|
}
|
|
|
|
module.exports = exports = Range
|
|
|
|
exports.parse = function parse(input, state = { position: 0, partial: 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 comparators = []
|
|
|
|
while (i < input.length) {
|
|
const set = []
|
|
|
|
while (i < input.length) {
|
|
c = input[i]
|
|
|
|
let operator = constants.EQ
|
|
|
|
if (c === '<') {
|
|
operator = constants.LT
|
|
c = input[++i]
|
|
|
|
if (c === '=') {
|
|
operator = constants.LTE
|
|
c = input[++i]
|
|
}
|
|
} else if (c === '>') {
|
|
operator = constants.GT
|
|
c = input[++i]
|
|
|
|
if (c === '=') {
|
|
operator = constants.GTE
|
|
c = input[++i]
|
|
}
|
|
} else if (c === '=') {
|
|
c = input[++i]
|
|
}
|
|
|
|
const state = { position: i, partial: true, range: true }
|
|
|
|
set.push(new Comparator(operator, Version.parse(input, state)))
|
|
|
|
c = input[(i = state.position)]
|
|
|
|
while (c === ' ') c = input[++i]
|
|
|
|
if (c === '|' && input[i + 1] === '|') {
|
|
c = input[(i += 2)]
|
|
|
|
while (c === ' ') c = input[++i]
|
|
|
|
break
|
|
}
|
|
|
|
if (c && c !== '<' && c !== '>') unexpected("expected '||', '<', or '>'")
|
|
}
|
|
|
|
if (set.length) comparators.push(set)
|
|
}
|
|
|
|
if (i < input.length && state.partial === false) {
|
|
unexpected('expected end of input')
|
|
}
|
|
|
|
state.position = i
|
|
|
|
return new Range(comparators)
|
|
}
|