const SemVer = require('../classes/semver'); const Comparator = require('../classes/comparator'); const { ANY } = Comparator; const Range = require('../classes/range'); const satisfies = require('../functions/satisfies'); const gt = require('../functions/gt'); const lt = require('../functions/lt'); const lte = require('../functions/lte'); const gte = require('../functions/gte'); const outside = (version, range, hilo, options) => { version = new SemVer(version, options); range = new Range(range, options); let gtfn, ltefn, ltfn, comp, ecomp; switch (hilo) { case '>': gtfn = gt; ltefn = lte; ltfn = lt; comp = '>'; ecomp = '>='; break; case '<': gtfn = lt; ltefn = gte; ltfn = gt; comp = '<'; ecomp = '<='; break; default: throw new TypeError('Must provide a hilo val of "<" or ">"'); } // If it satisfies the range it is not outside if (satisfies(version, range, options)) { return false; } // From now on, variable terms are as if we're in "gtr" mode. // but note that everything is flipped for the "ltr" function. for (let i = 0; i < range.set.length; ++i) { const comparators = range.set[i]; let high = null; let low = null; comparators.forEach((comparator) => { if (comparator.semver === ANY) { comparator = new Comparator('>=0.0.0'); } high = high || comparator; low = low || comparator; if (gtfn(comparator.semver, high.semver, options)) { high = comparator; } else if (ltfn(comparator.semver, low.semver, options)) { low = comparator; } }); // If the edge version comparator has a operator then our version // isn't outside it if (high.operator === comp || high.operator === ecomp) { return false; } // If the lowest version comparator has an operator and our version // is less than it then it isn't higher than the range if ( (!low.operator || low.operator === comp) && ltefn(version, low.semver) ) { return false; } else if (low.operator === ecomp && ltfn(version, low.semver)) { return false; } } return true; }; module.exports = outside;