You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.5 KiB
136 lines
3.5 KiB
const ANY = Symbol('SemVer ANY') |
|
// hoisted class for cyclic dependency |
|
class Comparator { |
|
static get ANY () { |
|
return ANY |
|
} |
|
|
|
constructor (comp, options) { |
|
options = parseOptions(options) |
|
|
|
if (comp instanceof Comparator) { |
|
if (comp.loose === !!options.loose) { |
|
return comp |
|
} else { |
|
comp = comp.value |
|
} |
|
} |
|
|
|
debug('comparator', comp, options) |
|
this.options = options |
|
this.loose = !!options.loose |
|
this.parse(comp) |
|
|
|
if (this.semver === ANY) { |
|
this.value = '' |
|
} else { |
|
this.value = this.operator + this.semver.version |
|
} |
|
|
|
debug('comp', this) |
|
} |
|
|
|
parse (comp) { |
|
const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] |
|
const m = comp.match(r) |
|
|
|
if (!m) { |
|
throw new TypeError(`Invalid comparator: ${comp}`) |
|
} |
|
|
|
this.operator = m[1] !== undefined ? m[1] : '' |
|
if (this.operator === '=') { |
|
this.operator = '' |
|
} |
|
|
|
// if it literally is just '>' or '' then allow anything. |
|
if (!m[2]) { |
|
this.semver = ANY |
|
} else { |
|
this.semver = new SemVer(m[2], this.options.loose) |
|
} |
|
} |
|
|
|
toString () { |
|
return this.value |
|
} |
|
|
|
test (version) { |
|
debug('Comparator.test', version, this.options.loose) |
|
|
|
if (this.semver === ANY || version === ANY) { |
|
return true |
|
} |
|
|
|
if (typeof version === 'string') { |
|
try { |
|
version = new SemVer(version, this.options) |
|
} catch (er) { |
|
return false |
|
} |
|
} |
|
|
|
return cmp(version, this.operator, this.semver, this.options) |
|
} |
|
|
|
intersects (comp, options) { |
|
if (!(comp instanceof Comparator)) { |
|
throw new TypeError('a Comparator is required') |
|
} |
|
|
|
if (!options || typeof options !== 'object') { |
|
options = { |
|
loose: !!options, |
|
includePrerelease: false, |
|
} |
|
} |
|
|
|
if (this.operator === '') { |
|
if (this.value === '') { |
|
return true |
|
} |
|
return new Range(comp.value, options).test(this.value) |
|
} else if (comp.operator === '') { |
|
if (comp.value === '') { |
|
return true |
|
} |
|
return new Range(this.value, options).test(comp.semver) |
|
} |
|
|
|
const sameDirectionIncreasing = |
|
(this.operator === '>=' || this.operator === '>') && |
|
(comp.operator === '>=' || comp.operator === '>') |
|
const sameDirectionDecreasing = |
|
(this.operator === '<=' || this.operator === '<') && |
|
(comp.operator === '<=' || comp.operator === '<') |
|
const sameSemVer = this.semver.version === comp.semver.version |
|
const differentDirectionsInclusive = |
|
(this.operator === '>=' || this.operator === '<=') && |
|
(comp.operator === '>=' || comp.operator === '<=') |
|
const oppositeDirectionsLessThan = |
|
cmp(this.semver, '<', comp.semver, options) && |
|
(this.operator === '>=' || this.operator === '>') && |
|
(comp.operator === '<=' || comp.operator === '<') |
|
const oppositeDirectionsGreaterThan = |
|
cmp(this.semver, '>', comp.semver, options) && |
|
(this.operator === '<=' || this.operator === '<') && |
|
(comp.operator === '>=' || comp.operator === '>') |
|
|
|
return ( |
|
sameDirectionIncreasing || |
|
sameDirectionDecreasing || |
|
(sameSemVer && differentDirectionsInclusive) || |
|
oppositeDirectionsLessThan || |
|
oppositeDirectionsGreaterThan |
|
) |
|
} |
|
} |
|
|
|
module.exports = Comparator |
|
|
|
const parseOptions = require('../internal/parse-options') |
|
const { re, t } = require('../internal/re') |
|
const cmp = require('../functions/cmp') |
|
const debug = require('../internal/debug') |
|
const SemVer = require('./semver') |
|
const Range = require('./range')
|
|
|