123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- 'use strict';
- var invariant = require('./invariant');
- var componentRegex = /\./;
- var orRegex = /\|\|/;
- var rangeRegex = /\s+\-\s+/;
- var modifierRegex = /^(<=|<|=|>=|~>|~|>|)?\s*(.+)/;
- var numericRegex = /^(\d*)(.*)/;
- function checkOrExpression(range, version) {
- var expressions = range.split(orRegex);
- if (expressions.length > 1) {
- return expressions.some(function (range) {
- return VersionRange.contains(range, version);
- });
- } else {
- range = expressions[0].trim();
- return checkRangeExpression(range, version);
- }
- }
- function checkRangeExpression(range, version) {
- var expressions = range.split(rangeRegex);
- !(expressions.length > 0 && expressions.length <= 2) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'the "-" operator expects exactly 2 operands') : invariant(false) : void 0;
- if (expressions.length === 1) {
- return checkSimpleExpression(expressions[0], version);
- } else {
- var startVersion = expressions[0],
- endVersion = expressions[1];
- !(isSimpleVersion(startVersion) && isSimpleVersion(endVersion)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'operands to the "-" operator must be simple (no modifiers)') : invariant(false) : void 0;
- return checkSimpleExpression('>=' + startVersion, version) && checkSimpleExpression('<=' + endVersion, version);
- }
- }
- function checkSimpleExpression(range, version) {
- range = range.trim();
- if (range === '') {
- return true;
- }
- var versionComponents = version.split(componentRegex);
- var _getModifierAndCompon = getModifierAndComponents(range),
- modifier = _getModifierAndCompon.modifier,
- rangeComponents = _getModifierAndCompon.rangeComponents;
- switch (modifier) {
- case '<':
- return checkLessThan(versionComponents, rangeComponents);
- case '<=':
- return checkLessThanOrEqual(versionComponents, rangeComponents);
- case '>=':
- return checkGreaterThanOrEqual(versionComponents, rangeComponents);
- case '>':
- return checkGreaterThan(versionComponents, rangeComponents);
- case '~':
- case '~>':
- return checkApproximateVersion(versionComponents, rangeComponents);
- default:
- return checkEqual(versionComponents, rangeComponents);
- }
- }
- function checkLessThan(a, b) {
- return compareComponents(a, b) === -1;
- }
- function checkLessThanOrEqual(a, b) {
- var result = compareComponents(a, b);
- return result === -1 || result === 0;
- }
- function checkEqual(a, b) {
- return compareComponents(a, b) === 0;
- }
- function checkGreaterThanOrEqual(a, b) {
- var result = compareComponents(a, b);
- return result === 1 || result === 0;
- }
- function checkGreaterThan(a, b) {
- return compareComponents(a, b) === 1;
- }
- function checkApproximateVersion(a, b) {
- var lowerBound = b.slice();
- var upperBound = b.slice();
- if (upperBound.length > 1) {
- upperBound.pop();
- }
- var lastIndex = upperBound.length - 1;
- var numeric = parseInt(upperBound[lastIndex], 10);
- if (isNumber(numeric)) {
- upperBound[lastIndex] = numeric + 1 + '';
- }
- return checkGreaterThanOrEqual(a, lowerBound) && checkLessThan(a, upperBound);
- }
- function getModifierAndComponents(range) {
- var rangeComponents = range.split(componentRegex);
- var matches = rangeComponents[0].match(modifierRegex);
- !matches ? process.env.NODE_ENV !== 'production' ? invariant(false, 'expected regex to match but it did not') : invariant(false) : void 0;
- return {
- modifier: matches[1],
- rangeComponents: [matches[2]].concat(rangeComponents.slice(1))
- };
- }
- function isNumber(number) {
- return !isNaN(number) && isFinite(number);
- }
- function isSimpleVersion(range) {
- return !getModifierAndComponents(range).modifier;
- }
- function zeroPad(array, length) {
- for (var i = array.length; i < length; i++) {
- array[i] = '0';
- }
- }
- function normalizeVersions(a, b) {
- a = a.slice();
- b = b.slice();
- zeroPad(a, b.length);
-
- for (var i = 0; i < b.length; i++) {
- var matches = b[i].match(/^[x*]$/i);
- if (matches) {
- b[i] = a[i] = '0';
-
- if (matches[0] === '*' && i === b.length - 1) {
- for (var j = i; j < a.length; j++) {
- a[j] = '0';
- }
- }
- }
- }
- zeroPad(b, a.length);
- return [a, b];
- }
- function compareNumeric(a, b) {
- var aPrefix = a.match(numericRegex)[1];
- var bPrefix = b.match(numericRegex)[1];
- var aNumeric = parseInt(aPrefix, 10);
- var bNumeric = parseInt(bPrefix, 10);
- if (isNumber(aNumeric) && isNumber(bNumeric) && aNumeric !== bNumeric) {
- return compare(aNumeric, bNumeric);
- } else {
- return compare(a, b);
- }
- }
- function compare(a, b) {
- !(typeof a === typeof b) ? process.env.NODE_ENV !== 'production' ? invariant(false, '"a" and "b" must be of the same type') : invariant(false) : void 0;
- if (a > b) {
- return 1;
- } else if (a < b) {
- return -1;
- } else {
- return 0;
- }
- }
- function compareComponents(a, b) {
- var _normalizeVersions = normalizeVersions(a, b),
- aNormalized = _normalizeVersions[0],
- bNormalized = _normalizeVersions[1];
- for (var i = 0; i < bNormalized.length; i++) {
- var result = compareNumeric(aNormalized[i], bNormalized[i]);
- if (result) {
- return result;
- }
- }
- return 0;
- }
- var VersionRange = {
-
- contains: function contains(range, version) {
- return checkOrExpression(range.trim(), version.trim());
- }
- };
- module.exports = VersionRange;
|