@storybook/semver
Version:
The semantic version parser used by npm for browser.
600 lines (478 loc) • 20.6 kB
JavaScript
"use strict";
require("core-js/modules/es.symbol");
require("core-js/modules/es.symbol.description");
require("core-js/modules/es.symbol.iterator");
require("core-js/modules/es.array.concat");
require("core-js/modules/es.array.every");
require("core-js/modules/es.array.filter");
require("core-js/modules/es.array.from");
require("core-js/modules/es.array.is-array");
require("core-js/modules/es.array.iterator");
require("core-js/modules/es.array.join");
require("core-js/modules/es.array.map");
require("core-js/modules/es.array.slice");
require("core-js/modules/es.array.some");
require("core-js/modules/es.date.to-string");
require("core-js/modules/es.function.name");
require("core-js/modules/es.map");
require("core-js/modules/es.object.define-property");
require("core-js/modules/es.object.to-string");
require("core-js/modules/es.regexp.exec");
require("core-js/modules/es.regexp.to-string");
require("core-js/modules/es.string.iterator");
require("core-js/modules/es.string.match");
require("core-js/modules/es.string.replace");
require("core-js/modules/es.string.split");
require("core-js/modules/es.string.trim");
require("core-js/modules/web.dom-collections.iterator");
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
// hoisted class for cyclic dependency
var Range = /*#__PURE__*/function () {
function Range(range, options) {
var _this = this;
_classCallCheck(this, Range);
if (!options || _typeof(options) !== 'object') {
options = {
loose: !!options,
includePrerelease: false
};
}
if (range instanceof Range) {
if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) {
return range;
} else {
return new Range(range.raw, options);
}
}
if (range instanceof Comparator) {
// just put it in the set and return
this.raw = range.value;
this.set = [[range]];
this.format();
return this;
}
this.options = options;
this.loose = !!options.loose;
this.includePrerelease = !!options.includePrerelease; // First, split based on boolean or ||
this.raw = range;
this.set = range.split(/\s*\|\|\s*/) // map the range to a 2d array of comparators
.map(function (range) {
return _this.parseRange(range.trim());
}) // throw out any comparator lists that are empty
// this generally means that it was not a valid range, which is allowed
// in loose mode, but will still throw if the WHOLE range is invalid.
.filter(function (c) {
return c.length;
});
if (!this.set.length) {
throw new TypeError("Invalid SemVer Range: ".concat(range));
} // if we have any that are not the null set, throw out null sets.
if (this.set.length > 1) {
// keep the first one, in case they're all null sets
var first = this.set[0];
this.set = this.set.filter(function (c) {
return !isNullSet(c[0]);
});
if (this.set.length === 0) this.set = [first];else if (this.set.length > 1) {
// if we have any that are *, then the range is just *
var _iterator = _createForOfIteratorHelper(this.set),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var c = _step.value;
if (c.length === 1 && isAny(c[0])) {
this.set = [c];
break;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
}
this.format();
}
_createClass(Range, [{
key: "format",
value: function format() {
this.range = this.set.map(function (comps) {
return comps.join(' ').trim();
}).join('||').trim();
return this.range;
}
}, {
key: "toString",
value: function toString() {
return this.range;
}
}, {
key: "parseRange",
value: function parseRange(range) {
var _this2 = this;
var loose = this.options.loose;
range = range.trim(); // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
var hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE];
range = range.replace(hr, hyphenReplace(this.options.includePrerelease));
debug('hyphen replace', range); // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace);
debug('comparator trim', range, re[t.COMPARATORTRIM]); // `~ 1.2.3` => `~1.2.3`
range = range.replace(re[t.TILDETRIM], tildeTrimReplace); // `^ 1.2.3` => `^1.2.3`
range = range.replace(re[t.CARETTRIM], caretTrimReplace); // normalize spaces
range = range.split(/\s+/).join(' '); // At this point, the range is completely trimmed and
// ready to be split into comparators.
var compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR];
var rangeList = range.split(' ').map(function (comp) {
return parseComparator(comp, _this2.options);
}).join(' ').split(/\s+/) // >=0.0.0 is equivalent to *
.map(function (comp) {
return replaceGTE0(comp, _this2.options);
}) // in loose mode, throw out any that are not valid comparators
.filter(this.options.loose ? function (comp) {
return !!comp.match(compRe);
} : function () {
return true;
}).map(function (comp) {
return new Comparator(comp, _this2.options);
}); // if any comparators are the null set, then replace with JUST null set
// if more than one comparator, remove any * comparators
// also, don't include the same comparator more than once
var l = rangeList.length;
var rangeMap = new Map();
var _iterator2 = _createForOfIteratorHelper(rangeList),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var comp = _step2.value;
if (isNullSet(comp)) return [comp];
rangeMap.set(comp.value, comp);
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
if (rangeMap.size > 1 && rangeMap.has('')) rangeMap["delete"]('');
return _toConsumableArray(rangeMap.values());
}
}, {
key: "intersects",
value: function intersects(range, options) {
if (!(range instanceof Range)) {
throw new TypeError('a Range is required');
}
return this.set.some(function (thisComparators) {
return isSatisfiable(thisComparators, options) && range.set.some(function (rangeComparators) {
return isSatisfiable(rangeComparators, options) && thisComparators.every(function (thisComparator) {
return rangeComparators.every(function (rangeComparator) {
return thisComparator.intersects(rangeComparator, options);
});
});
});
});
} // if ANY of the sets match ALL of its comparators, then pass
}, {
key: "test",
value: function test(version) {
if (!version) {
return false;
}
if (typeof version === 'string') {
try {
version = new SemVer(version, this.options);
} catch (er) {
return false;
}
}
for (var i = 0; i < this.set.length; i++) {
if (testSet(this.set[i], version, this.options)) {
return true;
}
}
return false;
}
}]);
return Range;
}();
module.exports = Range;
var Comparator = require('./comparator');
var debug = require('../internal/debug');
var SemVer = require('./semver');
var _require = require('../internal/re'),
re = _require.re,
t = _require.t,
comparatorTrimReplace = _require.comparatorTrimReplace,
tildeTrimReplace = _require.tildeTrimReplace,
caretTrimReplace = _require.caretTrimReplace;
var isNullSet = function isNullSet(c) {
return c.value === '<0.0.0-0';
};
var isAny = function isAny(c) {
return c.value === '';
}; // take a set of comparators and determine whether there
// exists a version which can satisfy it
var isSatisfiable = function isSatisfiable(comparators, options) {
var result = true;
var remainingComparators = comparators.slice();
var testComparator = remainingComparators.pop();
while (result && remainingComparators.length) {
result = remainingComparators.every(function (otherComparator) {
return testComparator.intersects(otherComparator, options);
});
testComparator = remainingComparators.pop();
}
return result;
}; // comprised of xranges, tildes, stars, and gtlt's at this point.
// already replaced the hyphen ranges
// turn into a set of JUST comparators.
var parseComparator = function parseComparator(comp, options) {
debug('comp', comp, options);
comp = replaceCarets(comp, options);
debug('caret', comp);
comp = replaceTildes(comp, options);
debug('tildes', comp);
comp = replaceXRanges(comp, options);
debug('xrange', comp);
comp = replaceStars(comp, options);
debug('stars', comp);
return comp;
};
var isX = function isX(id) {
return !id || id.toLowerCase() === 'x' || id === '*';
}; // ~, ~> --> * (any, kinda silly)
// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0
// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0
// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0
// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0
var replaceTildes = function replaceTildes(comp, options) {
return comp.trim().split(/\s+/).map(function (comp) {
return replaceTilde(comp, options);
}).join(' ');
};
var replaceTilde = function replaceTilde(comp, options) {
var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE];
return comp.replace(r, function (_, M, m, p, pr) {
debug('tilde', comp, _, M, m, p, pr);
var ret;
if (isX(M)) {
ret = '';
} else if (isX(m)) {
ret = ">=".concat(M, ".0.0 <").concat(+M + 1, ".0.0-0");
} else if (isX(p)) {
// ~1.2 == >=1.2.0 <1.3.0-0
ret = ">=".concat(M, ".").concat(m, ".0 <").concat(M, ".").concat(+m + 1, ".0-0");
} else if (pr) {
debug('replaceTilde pr', pr);
ret = ">=".concat(M, ".").concat(m, ".").concat(p, "-").concat(pr, " <").concat(M, ".").concat(+m + 1, ".0-0");
} else {
// ~1.2.3 == >=1.2.3 <1.3.0-0
ret = ">=".concat(M, ".").concat(m, ".").concat(p, " <").concat(M, ".").concat(+m + 1, ".0-0");
}
debug('tilde return', ret);
return ret;
});
}; // ^ --> * (any, kinda silly)
// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0
// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0
// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0
// ^1.2.3 --> >=1.2.3 <2.0.0-0
// ^1.2.0 --> >=1.2.0 <2.0.0-0
var replaceCarets = function replaceCarets(comp, options) {
return comp.trim().split(/\s+/).map(function (comp) {
return replaceCaret(comp, options);
}).join(' ');
};
var replaceCaret = function replaceCaret(comp, options) {
debug('caret', comp, options);
var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET];
var z = options.includePrerelease ? '-0' : '';
return comp.replace(r, function (_, M, m, p, pr) {
debug('caret', comp, _, M, m, p, pr);
var ret;
if (isX(M)) {
ret = '';
} else if (isX(m)) {
ret = ">=".concat(M, ".0.0").concat(z, " <").concat(+M + 1, ".0.0-0");
} else if (isX(p)) {
if (M === '0') {
ret = ">=".concat(M, ".").concat(m, ".0").concat(z, " <").concat(M, ".").concat(+m + 1, ".0-0");
} else {
ret = ">=".concat(M, ".").concat(m, ".0").concat(z, " <").concat(+M + 1, ".0.0-0");
}
} else if (pr) {
debug('replaceCaret pr', pr);
if (M === '0') {
if (m === '0') {
ret = ">=".concat(M, ".").concat(m, ".").concat(p, "-").concat(pr, " <").concat(M, ".").concat(m, ".").concat(+p + 1, "-0");
} else {
ret = ">=".concat(M, ".").concat(m, ".").concat(p, "-").concat(pr, " <").concat(M, ".").concat(+m + 1, ".0-0");
}
} else {
ret = ">=".concat(M, ".").concat(m, ".").concat(p, "-").concat(pr, " <").concat(+M + 1, ".0.0-0");
}
} else {
debug('no pr');
if (M === '0') {
if (m === '0') {
ret = ">=".concat(M, ".").concat(m, ".").concat(p).concat(z, " <").concat(M, ".").concat(m, ".").concat(+p + 1, "-0");
} else {
ret = ">=".concat(M, ".").concat(m, ".").concat(p).concat(z, " <").concat(M, ".").concat(+m + 1, ".0-0");
}
} else {
ret = ">=".concat(M, ".").concat(m, ".").concat(p, " <").concat(+M + 1, ".0.0-0");
}
}
debug('caret return', ret);
return ret;
});
};
var replaceXRanges = function replaceXRanges(comp, options) {
debug('replaceXRanges', comp, options);
return comp.split(/\s+/).map(function (comp) {
return replaceXRange(comp, options);
}).join(' ');
};
var replaceXRange = function replaceXRange(comp, options) {
comp = comp.trim();
var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE];
return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
debug('xRange', comp, ret, gtlt, M, m, p, pr);
var xM = isX(M);
var xm = xM || isX(m);
var xp = xm || isX(p);
var anyX = xp;
if (gtlt === '=' && anyX) {
gtlt = '';
} // if we're including prereleases in the match, then we need
// to fix this to -0, the lowest possible prerelease value
pr = options.includePrerelease ? '-0' : '';
if (xM) {
if (gtlt === '>' || gtlt === '<') {
// nothing is allowed
ret = '<0.0.0-0';
} else {
// nothing is forbidden
ret = '*';
}
} else if (gtlt && anyX) {
// we know patch is an x, because we have any x at all.
// replace X with 0
if (xm) {
m = 0;
}
p = 0;
if (gtlt === '>') {
// >1 => >=2.0.0
// >1.2 => >=1.3.0
gtlt = '>=';
if (xm) {
M = +M + 1;
m = 0;
p = 0;
} else {
m = +m + 1;
p = 0;
}
} else if (gtlt === '<=') {
// <=0.7.x is actually <0.8.0, since any 0.7.x should
// pass. Similarly, <=7.x is actually <8.0.0, etc.
gtlt = '<';
if (xm) {
M = +M + 1;
} else {
m = +m + 1;
}
}
if (gtlt === '<') pr = '-0';
ret = "".concat(gtlt + M, ".").concat(m, ".").concat(p).concat(pr);
} else if (xm) {
ret = ">=".concat(M, ".0.0").concat(pr, " <").concat(+M + 1, ".0.0-0");
} else if (xp) {
ret = ">=".concat(M, ".").concat(m, ".0").concat(pr, " <").concat(M, ".").concat(+m + 1, ".0-0");
}
debug('xRange return', ret);
return ret;
});
}; // Because * is AND-ed with everything else in the comparator,
// and '' means "any version", just remove the *s entirely.
var replaceStars = function replaceStars(comp, options) {
debug('replaceStars', comp, options); // Looseness is ignored here. star is always as loose as it gets!
return comp.trim().replace(re[t.STAR], '');
};
var replaceGTE0 = function replaceGTE0(comp, options) {
debug('replaceGTE0', comp, options);
return comp.trim().replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '');
}; // This function is passed to string.replace(re[t.HYPHENRANGE])
// M, m, patch, prerelease, build
// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
// 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do
// 1.2 - 3.4 => >=1.2.0 <3.5.0-0
var hyphenReplace = function hyphenReplace(incPr) {
return function ($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) {
if (isX(fM)) {
from = '';
} else if (isX(fm)) {
from = ">=".concat(fM, ".0.0").concat(incPr ? '-0' : '');
} else if (isX(fp)) {
from = ">=".concat(fM, ".").concat(fm, ".0").concat(incPr ? '-0' : '');
} else if (fpr) {
from = ">=".concat(from);
} else {
from = ">=".concat(from).concat(incPr ? '-0' : '');
}
if (isX(tM)) {
to = '';
} else if (isX(tm)) {
to = "<".concat(+tM + 1, ".0.0-0");
} else if (isX(tp)) {
to = "<".concat(tM, ".").concat(+tm + 1, ".0-0");
} else if (tpr) {
to = "<=".concat(tM, ".").concat(tm, ".").concat(tp, "-").concat(tpr);
} else if (incPr) {
to = "<".concat(tM, ".").concat(tm, ".").concat(+tp + 1, "-0");
} else {
to = "<=".concat(to);
}
return "".concat(from, " ").concat(to).trim();
};
};
var testSet = function testSet(set, version, options) {
for (var i = 0; i < set.length; i++) {
if (!set[i].test(version)) {
return false;
}
}
if (version.prerelease.length && !options.includePrerelease) {
// Find the set of versions that are allowed to have prereleases
// For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
// That should allow `1.2.3-pr.2` to pass.
// However, `1.2.4-alpha.notready` should NOT be allowed,
// even though it's within the range set by the comparators.
for (var _i = 0; _i < set.length; _i++) {
debug(set[_i].semver);
if (set[_i].semver === Comparator.ANY) {
continue;
}
if (set[_i].semver.prerelease.length > 0) {
var allowed = set[_i].semver;
if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) {
return true;
}
}
} // Version has a -pre, but it's not one of the ones we like.
return false;
}
return true;
};