1 const ANY = Symbol('SemVer ANY')
2 // hoisted class for cyclic dependency
7 constructor (comp, options) {
8 options = parseOptions(options)
10 if (comp instanceof Comparator) {
11 if (comp.loose === !!options.loose) {
18 debug('comparator', comp, options)
19 this.options = options
20 this.loose = !!options.loose
23 if (this.semver === ANY) {
26 this.value = this.operator + this.semver.version
33 const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
34 const m = comp.match(r)
37 throw new TypeError(`Invalid comparator: ${comp}`)
40 this.operator = m[1] !== undefined ? m[1] : ''
41 if (this.operator === '=') {
45 // if it literally is just '>' or '' then allow anything.
49 this.semver = new SemVer(m[2], this.options.loose)
58 debug('Comparator.test', version, this.options.loose)
60 if (this.semver === ANY || version === ANY) {
64 if (typeof version === 'string') {
66 version = new SemVer(version, this.options)
72 return cmp(version, this.operator, this.semver, this.options)
75 intersects (comp, options) {
76 if (!(comp instanceof Comparator)) {
77 throw new TypeError('a Comparator is required')
80 if (!options || typeof options !== 'object') {
83 includePrerelease: false
87 if (this.operator === '') {
88 if (this.value === '') {
91 return new Range(comp.value, options).test(this.value)
92 } else if (comp.operator === '') {
93 if (comp.value === '') {
96 return new Range(this.value, options).test(comp.semver)
99 const sameDirectionIncreasing =
100 (this.operator === '>=' || this.operator === '>') &&
101 (comp.operator === '>=' || comp.operator === '>')
102 const sameDirectionDecreasing =
103 (this.operator === '<=' || this.operator === '<') &&
104 (comp.operator === '<=' || comp.operator === '<')
105 const sameSemVer = this.semver.version === comp.semver.version
106 const differentDirectionsInclusive =
107 (this.operator === '>=' || this.operator === '<=') &&
108 (comp.operator === '>=' || comp.operator === '<=')
109 const oppositeDirectionsLessThan =
110 cmp(this.semver, '<', comp.semver, options) &&
111 (this.operator === '>=' || this.operator === '>') &&
112 (comp.operator === '<=' || comp.operator === '<')
113 const oppositeDirectionsGreaterThan =
114 cmp(this.semver, '>', comp.semver, options) &&
115 (this.operator === '<=' || this.operator === '<') &&
116 (comp.operator === '>=' || comp.operator === '>')
119 sameDirectionIncreasing ||
120 sameDirectionDecreasing ||
121 (sameSemVer && differentDirectionsInclusive) ||
122 oppositeDirectionsLessThan ||
123 oppositeDirectionsGreaterThan
128 module.exports = Comparator
130 const parseOptions = require('../internal/parse-options')
131 const {re, t} = require('../internal/re')
132 const cmp = require('../functions/cmp')
133 const debug = require('../internal/debug')
134 const SemVer = require('./semver')
135 const Range = require('./range')