Ejdjdososs/fable-ai
0
1exports = module.exports = SemVer2 3var debug4/* istanbul ignore next */5if (typeof process === 'object' &&6 process.env &&7 process.env.NODE_DEBUG &&8 /\bsemver\b/i.test(process.env.NODE_DEBUG)) {9 debug = function () {10 var args = Array.prototype.slice.call(arguments, 0)11 args.unshift('SEMVER')12 console.log.apply(console, args)13 }14} else {15 debug = function () {}16}17 18// Note: this is the semver.org version of the spec that it implements19// Not necessarily the package version of this code.20exports.SEMVER_SPEC_VERSION = '2.0.0'21 22var MAX_LENGTH = 25623var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||24 /* istanbul ignore next */ 900719925474099125 26// Max safe segment length for coercion.27var MAX_SAFE_COMPONENT_LENGTH = 1628 29var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 630 31// The actual regexps go on exports.re32var re = exports.re = []33var safeRe = exports.safeRe = []34var src = exports.src = []35var t = exports.tokens = {}36var R = 037 38function tok (n) {39 t[n] = R++40}41 42var LETTERDASHNUMBER = '[a-zA-Z0-9-]'43 44// Replace some greedy regex tokens to prevent regex dos issues. These regex are45// used internally via the safeRe object since all inputs in this library get46// normalized first to trim and collapse all extra whitespace. The original47// regexes are exported for userland consumption and lower level usage. A48// future breaking change could export the safer regex only with a note that49// all input should have extra whitespace removed.50var safeRegexReplacements = [51 ['\\s', 1],52 ['\\d', MAX_LENGTH],53 [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],54]55 56function makeSafeRe (value) {57 for (var i = 0; i < safeRegexReplacements.length; i++) {58 var token = safeRegexReplacements[i][0]59 var max = safeRegexReplacements[i][1]60 value = value61 .split(token + '*').join(token + '{0,' + max + '}')62 .split(token + '+').join(token + '{1,' + max + '}')63 }64 return value65}66 67// The following Regular Expressions can be used for tokenizing,68// validating, and parsing SemVer version strings.69 70// ## Numeric Identifier71// A single `0`, or a non-zero digit followed by zero or more digits.72 73tok('NUMERICIDENTIFIER')74src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*'75tok('NUMERICIDENTIFIERLOOSE')76src[t.NUMERICIDENTIFIERLOOSE] = '\\d+'77 78// ## Non-numeric Identifier79// Zero or more digits, followed by a letter or hyphen, and then zero or80// more letters, digits, or hyphens.81 82tok('NONNUMERICIDENTIFIER')83src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-]' + LETTERDASHNUMBER + '*'84 85// ## Main Version86// Three dot-separated numeric identifiers.87 88tok('MAINVERSION')89src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' +90 '(' + src[t.NUMERICIDENTIFIER] + ')\\.' +91 '(' + src[t.NUMERICIDENTIFIER] + ')'92 93tok('MAINVERSIONLOOSE')94src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' +95 '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' +96 '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')'97 98// ## Pre-release Version Identifier99// A numeric identifier, or a non-numeric identifier.100 101tok('PRERELEASEIDENTIFIER')102src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] +103 '|' + src[t.NONNUMERICIDENTIFIER] + ')'104 105tok('PRERELEASEIDENTIFIERLOOSE')106src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] +107 '|' + src[t.NONNUMERICIDENTIFIER] + ')'108 109// ## Pre-release Version110// Hyphen, followed by one or more dot-separated pre-release version111// identifiers.112 113tok('PRERELEASE')114src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] +115 '(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))'116 117tok('PRERELEASELOOSE')118src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] +119 '(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))'120 121// ## Build Metadata Identifier122// Any combination of digits, letters, or hyphens.123 124tok('BUILDIDENTIFIER')125src[t.BUILDIDENTIFIER] = LETTERDASHNUMBER + '+'126 127// ## Build Metadata128// Plus sign, followed by one or more period-separated build metadata129// identifiers.130 131tok('BUILD')132src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] +133 '(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))'134 135// ## Full Version String136// A main version, followed optionally by a pre-release version and137// build metadata.138 139// Note that the only major, minor, patch, and pre-release sections of140// the version string are capturing groups. The build metadata is not a141// capturing group, because it should not ever be used in version142// comparison.143 144tok('FULL')145tok('FULLPLAIN')146src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] +147 src[t.PRERELEASE] + '?' +148 src[t.BUILD] + '?'149 150src[t.FULL] = '^' + src[t.FULLPLAIN] + '$'151 152// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.153// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty154// common in the npm registry.155tok('LOOSEPLAIN')156src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] +157 src[t.PRERELEASELOOSE] + '?' +158 src[t.BUILD] + '?'159 160tok('LOOSE')161src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$'162 163tok('GTLT')164src[t.GTLT] = '((?:<|>)?=?)'165 166// Something like "2.*" or "1.2.x".167// Note that "x.x" is a valid xRange identifer, meaning "any version"168// Only the first item is strictly required.169tok('XRANGEIDENTIFIERLOOSE')170src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'171tok('XRANGEIDENTIFIER')172src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*'173 174tok('XRANGEPLAIN')175src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' +176 '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' +177 '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' +178 '(?:' + src[t.PRERELEASE] + ')?' +179 src[t.BUILD] + '?' +180 ')?)?'181 182tok('XRANGEPLAINLOOSE')183src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' +184 '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' +185 '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' +186 '(?:' + src[t.PRERELEASELOOSE] + ')?' +187 src[t.BUILD] + '?' +188 ')?)?'189 190tok('XRANGE')191src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$'192tok('XRANGELOOSE')193src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$'194 195// Coercion.196// Extract anything that could conceivably be a part of a valid semver197tok('COERCE')198src[t.COERCE] = '(^|[^\\d])' +199 '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' +200 '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +201 '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +202 '(?:$|[^\\d])'203tok('COERCERTL')204re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g')205safeRe[t.COERCERTL] = new RegExp(makeSafeRe(src[t.COERCE]), 'g')206 207// Tilde ranges.208// Meaning is "reasonably at or greater than"209tok('LONETILDE')210src[t.LONETILDE] = '(?:~>?)'211 212tok('TILDETRIM')213src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+'214re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g')215safeRe[t.TILDETRIM] = new RegExp(makeSafeRe(src[t.TILDETRIM]), 'g')216var tildeTrimReplace = '$1~'217 218tok('TILDE')219src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$'220tok('TILDELOOSE')221src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$'222 223// Caret ranges.224// Meaning is "at least and backwards compatible with"225tok('LONECARET')226src[t.LONECARET] = '(?:\\^)'227 228tok('CARETTRIM')229src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+'230re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g')231safeRe[t.CARETTRIM] = new RegExp(makeSafeRe(src[t.CARETTRIM]), 'g')232var caretTrimReplace = '$1^'233 234tok('CARET')235src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$'236tok('CARETLOOSE')237src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$'238 239// A simple gt/lt/eq thing, or just "" to indicate "any version"240tok('COMPARATORLOOSE')241src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$'242tok('COMPARATOR')243src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$'244 245// An expression to strip any whitespace between the gtlt and the thing246// it modifies, so that `> 1.2.3` ==> `>1.2.3`247tok('COMPARATORTRIM')248src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] +249 '\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')'250 251// this one has to use the /g flag252re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g')253safeRe[t.COMPARATORTRIM] = new RegExp(makeSafeRe(src[t.COMPARATORTRIM]), 'g')254var comparatorTrimReplace = '$1$2$3'255 256// Something like `1.2.3 - 1.2.4`257// Note that these all use the loose form, because they'll be258// checked against either the strict or loose comparator form259// later.260tok('HYPHENRANGE')261src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' +262 '\\s+-\\s+' +263 '(' + src[t.XRANGEPLAIN] + ')' +264 '\\s*$'265 266tok('HYPHENRANGELOOSE')267src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' +268 '\\s+-\\s+' +269 '(' + src[t.XRANGEPLAINLOOSE] + ')' +270 '\\s*$'271 272// Star ranges basically just allow anything at all.273tok('STAR')274src[t.STAR] = '(<|>)?=?\\s*\\*'275 276// Compile to actual regexp objects.277// All are flag-free, unless they were created above with a flag.278for (var i = 0; i < R; i++) {279 debug(i, src[i])280 if (!re[i]) {281 re[i] = new RegExp(src[i])282 283 // Replace all greedy whitespace to prevent regex dos issues. These regex are284 // used internally via the safeRe object since all inputs in this library get285 // normalized first to trim and collapse all extra whitespace. The original286 // regexes are exported for userland consumption and lower level usage. A287 // future breaking change could export the safer regex only with a note that288 // all input should have extra whitespace removed.289 safeRe[i] = new RegExp(makeSafeRe(src[i]))290 }291}292 293exports.parse = parse294function parse (version, options) {295 if (!options || typeof options !== 'object') {296 options = {297 loose: !!options,298 includePrerelease: false299 }300 }301 302 if (version instanceof SemVer) {303 return version304 }305 306 if (typeof version !== 'string') {307 return null308 }309 310 if (version.length > MAX_LENGTH) {311 return null312 }313 314 var r = options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]315 if (!r.test(version)) {316 return null317 }318 319 try {320 return new SemVer(version, options)321 } catch (er) {322 return null323 }324}325 326exports.valid = valid327function valid (version, options) {328 var v = parse(version, options)329 return v ? v.version : null330}331 332exports.clean = clean333function clean (version, options) {334 var s = parse(version.trim().replace(/^[=v]+/, ''), options)335 return s ? s.version : null336}337 338exports.SemVer = SemVer339 340function SemVer (version, options) {341 if (!options || typeof options !== 'object') {342 options = {343 loose: !!options,344 includePrerelease: false345 }346 }347 if (version instanceof SemVer) {348 if (version.loose === options.loose) {349 return version350 } else {351 version = version.version352 }353 } else if (typeof version !== 'string') {354 throw new TypeError('Invalid Version: ' + version)355 }356 357 if (version.length > MAX_LENGTH) {358 throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters')359 }360 361 if (!(this instanceof SemVer)) {362 return new SemVer(version, options)363 }364 365 debug('SemVer', version, options)366 this.options = options367 this.loose = !!options.loose368 369 var m = version.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL])370 371 if (!m) {372 throw new TypeError('Invalid Version: ' + version)373 }374 375 this.raw = version376 377 // these are actually numbers378 this.major = +m[1]379 this.minor = +m[2]380 this.patch = +m[3]381 382 if (this.major > MAX_SAFE_INTEGER || this.major < 0) {383 throw new TypeError('Invalid major version')384 }385 386 if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {387 throw new TypeError('Invalid minor version')388 }389 390 if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {391 throw new TypeError('Invalid patch version')392 }393 394 // numberify any prerelease numeric ids395 if (!m[4]) {396 this.prerelease = []397 } else {398 this.prerelease = m[4].split('.').map(function (id) {399 if (/^[0-9]+$/.test(id)) {400 var num = +id401 if (num >= 0 && num < MAX_SAFE_INTEGER) {402 return num403 }404 }405 return id406 })407 }408 409 this.build = m[5] ? m[5].split('.') : []410 this.format()411}412 413SemVer.prototype.format = function () {414 this.version = this.major + '.' + this.minor + '.' + this.patch415 if (this.prerelease.length) {416 this.version += '-' + this.prerelease.join('.')417 }418 return this.version419}420 421SemVer.prototype.toString = function () {422 return this.version423}424 425SemVer.prototype.compare = function (other) {426 debug('SemVer.compare', this.version, this.options, other)427 if (!(other instanceof SemVer)) {428 other = new SemVer(other, this.options)429 }430 431 return this.compareMain(other) || this.comparePre(other)432}433 434SemVer.prototype.compareMain = function (other) {435 if (!(other instanceof SemVer)) {436 other = new SemVer(other, this.options)437 }438 439 return compareIdentifiers(this.major, other.major) ||440 compareIdentifiers(this.minor, other.minor) ||441 compareIdentifiers(this.patch, other.patch)442}443 444SemVer.prototype.comparePre = function (other) {445 if (!(other instanceof SemVer)) {446 other = new SemVer(other, this.options)447 }448 449 // NOT having a prerelease is > having one450 if (this.prerelease.length && !other.prerelease.length) {451 return -1452 } else if (!this.prerelease.length && other.prerelease.length) {453 return 1454 } else if (!this.prerelease.length && !other.prerelease.length) {455 return 0456 }457 458 var i = 0459 do {460 var a = this.prerelease[i]461 var b = other.prerelease[i]462 debug('prerelease compare', i, a, b)463 if (a === undefined && b === undefined) {464 return 0465 } else if (b === undefined) {466 return 1467 } else if (a === undefined) {468 return -1469 } else if (a === b) {470 continue471 } else {472 return compareIdentifiers(a, b)473 }474 } while (++i)475}476 477SemVer.prototype.compareBuild = function (other) {478 if (!(other instanceof SemVer)) {479 other = new SemVer(other, this.options)480 }481 482 var i = 0483 do {484 var a = this.build[i]485 var b = other.build[i]486 debug('prerelease compare', i, a, b)487 if (a === undefined && b === undefined) {488 return 0489 } else if (b === undefined) {490 return 1491 } else if (a === undefined) {492 return -1493 } else if (a === b) {494 continue495 } else {496 return compareIdentifiers(a, b)497 }498 } while (++i)499}500 501// preminor will bump the version up to the next minor release, and immediately502// down to pre-release. premajor and prepatch work the same way.503SemVer.prototype.inc = function (release, identifier) {504 switch (release) {505 case 'premajor':506 this.prerelease.length = 0507 this.patch = 0508 this.minor = 0509 this.major++510 this.inc('pre', identifier)511 break512 case 'preminor':513 this.prerelease.length = 0514 this.patch = 0515 this.minor++516 this.inc('pre', identifier)517 break518 case 'prepatch':519 // If this is already a prerelease, it will bump to the next version520 // drop any prereleases that might already exist, since they are not521 // relevant at this point.522 this.prerelease.length = 0523 this.inc('patch', identifier)524 this.inc('pre', identifier)525 break526 // If the input is a non-prerelease version, this acts the same as527 // prepatch.528 case 'prerelease':529 if (this.prerelease.length === 0) {530 this.inc('patch', identifier)531 }532 this.inc('pre', identifier)533 break534 535 case 'major':536 // If this is a pre-major version, bump up to the same major version.537 // Otherwise increment major.538 // 1.0.0-5 bumps to 1.0.0539 // 1.1.0 bumps to 2.0.0540 if (this.minor !== 0 ||541 this.patch !== 0 ||542 this.prerelease.length === 0) {543 this.major++544 }545 this.minor = 0546 this.patch = 0547 this.prerelease = []548 break549 case 'minor':550 // If this is a pre-minor version, bump up to the same minor version.551 // Otherwise increment minor.552 // 1.2.0-5 bumps to 1.2.0553 // 1.2.1 bumps to 1.3.0554 if (this.patch !== 0 || this.prerelease.length === 0) {555 this.minor++556 }557 this.patch = 0558 this.prerelease = []559 break560 case 'patch':561 // If this is not a pre-release version, it will increment the patch.562 // If it is a pre-release it will bump up to the same patch version.563 // 1.2.0-5 patches to 1.2.0564 // 1.2.0 patches to 1.2.1565 if (this.prerelease.length === 0) {566 this.patch++567 }568 this.prerelease = []569 break570 // This probably shouldn't be used publicly.571 // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.572 case 'pre':573 if (this.prerelease.length === 0) {574 this.prerelease = [0]575 } else {576 var i = this.prerelease.length577 while (--i >= 0) {578 if (typeof this.prerelease[i] === 'number') {579 this.prerelease[i]++580 i = -2581 }582 }583 if (i === -1) {584 // didn't increment anything585 this.prerelease.push(0)586 }587 }588 if (identifier) {589 // 1.2.0-beta.1 bumps to 1.2.0-beta.2,590 // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0591 if (this.prerelease[0] === identifier) {592 if (isNaN(this.prerelease[1])) {593 this.prerelease = [identifier, 0]594 }595 } else {596 this.prerelease = [identifier, 0]597 }598 }599 break600 601 default:602 throw new Error('invalid increment argument: ' + release)603 }604 this.format()605 this.raw = this.version606 return this607}608 609exports.inc = inc610function inc (version, release, loose, identifier) {611 if (typeof (loose) === 'string') {612 identifier = loose613 loose = undefined614 }615 616 try {617 return new SemVer(version, loose).inc(release, identifier).version618 } catch (er) {619 return null620 }621}622 623exports.diff = diff624function diff (version1, version2) {625 if (eq(version1, version2)) {626 return null627 } else {628 var v1 = parse(version1)629 var v2 = parse(version2)630 var prefix = ''631 if (v1.prerelease.length || v2.prerelease.length) {632 prefix = 'pre'633 var defaultResult = 'prerelease'634 }635 for (var key in v1) {636 if (key === 'major' || key === 'minor' || key === 'patch') {637 if (v1[key] !== v2[key]) {638 return prefix + key639 }640 }641 }642 return defaultResult // may be undefined643 }644}645 646exports.compareIdentifiers = compareIdentifiers647 648var numeric = /^[0-9]+$/649function compareIdentifiers (a, b) {650 var anum = numeric.test(a)651 var bnum = numeric.test(b)652 653 if (anum && bnum) {654 a = +a655 b = +b656 }657 658 return a === b ? 0659 : (anum && !bnum) ? -1660 : (bnum && !anum) ? 1661 : a < b ? -1662 : 1663}664 665exports.rcompareIdentifiers = rcompareIdentifiers666function rcompareIdentifiers (a, b) {667 return compareIdentifiers(b, a)668}669 670exports.major = major671function major (a, loose) {672 return new SemVer(a, loose).major673}674 675exports.minor = minor676function minor (a, loose) {677 return new SemVer(a, loose).minor678}679 680exports.patch = patch681function patch (a, loose) {682 return new SemVer(a, loose).patch683}684 685exports.compare = compare686function compare (a, b, loose) {687 return new SemVer(a, loose).compare(new SemVer(b, loose))688}689 690exports.compareLoose = compareLoose691function compareLoose (a, b) {692 return compare(a, b, true)693}694 695exports.compareBuild = compareBuild696function compareBuild (a, b, loose) {697 var versionA = new SemVer(a, loose)698 var versionB = new SemVer(b, loose)699 return versionA.compare(versionB) || versionA.compareBuild(versionB)700}701 702exports.rcompare = rcompare703function rcompare (a, b, loose) {704 return compare(b, a, loose)705}706 707exports.sort = sort708function sort (list, loose) {709 return list.sort(function (a, b) {710 return exports.compareBuild(a, b, loose)711 })712}713 714exports.rsort = rsort715function rsort (list, loose) {716 return list.sort(function (a, b) {717 return exports.compareBuild(b, a, loose)718 })719}720 721exports.gt = gt722function gt (a, b, loose) {723 return compare(a, b, loose) > 0724}725 726exports.lt = lt727function lt (a, b, loose) {728 return compare(a, b, loose) < 0729}730 731exports.eq = eq732function eq (a, b, loose) {733 return compare(a, b, loose) === 0734}735 736exports.neq = neq737function neq (a, b, loose) {738 return compare(a, b, loose) !== 0739}740 741exports.gte = gte742function gte (a, b, loose) {743 return compare(a, b, loose) >= 0744}745 746exports.lte = lte747function lte (a, b, loose) {748 return compare(a, b, loose) <= 0749}750 751exports.cmp = cmp752function cmp (a, op, b, loose) {753 switch (op) {754 case '===':755 if (typeof a === 'object')756 a = a.version757 if (typeof b === 'object')758 b = b.version759 return a === b760 761 case '!==':762 if (typeof a === 'object')763 a = a.version764 if (typeof b === 'object')765 b = b.version766 return a !== b767 768 case '':769 case '=':770 case '==':771 return eq(a, b, loose)772 773 case '!=':774 return neq(a, b, loose)775 776 case '>':777 return gt(a, b, loose)778 779 case '>=':780 return gte(a, b, loose)781 782 case '<':783 return lt(a, b, loose)784 785 case '<=':786 return lte(a, b, loose)787 788 default:789 throw new TypeError('Invalid operator: ' + op)790 }791}792 793exports.Comparator = Comparator794function Comparator (comp, options) {795 if (!options || typeof options !== 'object') {796 options = {797 loose: !!options,798 includePrerelease: false799 }800 }801 802 if (comp instanceof Comparator) {803 if (comp.loose === !!options.loose) {804 return comp805 } else {806 comp = comp.value807 }808 }809 810 if (!(this instanceof Comparator)) {811 return new Comparator(comp, options)812 }813 814 comp = comp.trim().split(/\s+/).join(' ')815 debug('comparator', comp, options)816 this.options = options817 this.loose = !!options.loose818 this.parse(comp)819 820 if (this.semver === ANY) {821 this.value = ''822 } else {823 this.value = this.operator + this.semver.version824 }825 826 debug('comp', this)827}828 829var ANY = {}830Comparator.prototype.parse = function (comp) {831 var r = this.options.loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR]832 var m = comp.match(r)833 834 if (!m) {835 throw new TypeError('Invalid comparator: ' + comp)836 }837 838 this.operator = m[1] !== undefined ? m[1] : ''839 if (this.operator === '=') {840 this.operator = ''841 }842 843 // if it literally is just '>' or '' then allow anything.844 if (!m[2]) {845 this.semver = ANY846 } else {847 this.semver = new SemVer(m[2], this.options.loose)848 }849}850 851Comparator.prototype.toString = function () {852 return this.value853}854 855Comparator.prototype.test = function (version) {856 debug('Comparator.test', version, this.options.loose)857 858 if (this.semver === ANY || version === ANY) {859 return true860 }861 862 if (typeof version === 'string') {863 try {864 version = new SemVer(version, this.options)865 } catch (er) {866 return false867 }868 }869 870 return cmp(version, this.operator, this.semver, this.options)871}872 873Comparator.prototype.intersects = function (comp, options) {874 if (!(comp instanceof Comparator)) {875 throw new TypeError('a Comparator is required')876 }877 878 if (!options || typeof options !== 'object') {879 options = {880 loose: !!options,881 includePrerelease: false882 }883 }884 885 var rangeTmp886 887 if (this.operator === '') {888 if (this.value === '') {889 return true890 }891 rangeTmp = new Range(comp.value, options)892 return satisfies(this.value, rangeTmp, options)893 } else if (comp.operator === '') {894 if (comp.value === '') {895 return true896 }897 rangeTmp = new Range(this.value, options)898 return satisfies(comp.semver, rangeTmp, options)899 }900 901 var sameDirectionIncreasing =902 (this.operator === '>=' || this.operator === '>') &&903 (comp.operator === '>=' || comp.operator === '>')904 var sameDirectionDecreasing =905 (this.operator === '<=' || this.operator === '<') &&906 (comp.operator === '<=' || comp.operator === '<')907 var sameSemVer = this.semver.version === comp.semver.version908 var differentDirectionsInclusive =909 (this.operator === '>=' || this.operator === '<=') &&910 (comp.operator === '>=' || comp.operator === '<=')911 var oppositeDirectionsLessThan =912 cmp(this.semver, '<', comp.semver, options) &&913 ((this.operator === '>=' || this.operator === '>') &&914 (comp.operator === '<=' || comp.operator === '<'))915 var oppositeDirectionsGreaterThan =916 cmp(this.semver, '>', comp.semver, options) &&917 ((this.operator === '<=' || this.operator === '<') &&918 (comp.operator === '>=' || comp.operator === '>'))919 920 return sameDirectionIncreasing || sameDirectionDecreasing ||921 (sameSemVer && differentDirectionsInclusive) ||922 oppositeDirectionsLessThan || oppositeDirectionsGreaterThan923}924 925exports.Range = Range926function Range (range, options) {927 if (!options || typeof options !== 'object') {928 options = {929 loose: !!options,930 includePrerelease: false931 }932 }933 934 if (range instanceof Range) {935 if (range.loose === !!options.loose &&936 range.includePrerelease === !!options.includePrerelease) {937 return range938 } else {939 return new Range(range.raw, options)940 }941 }942 943 if (range instanceof Comparator) {944 return new Range(range.value, options)945 }946 947 if (!(this instanceof Range)) {948 return new Range(range, options)949 }950 951 this.options = options952 this.loose = !!options.loose953 this.includePrerelease = !!options.includePrerelease954 955 // First reduce all whitespace as much as possible so we do not have to rely956 // on potentially slow regexes like \s*. This is then stored and used for957 // future error messages as well.958 this.raw = range959 .trim()960 .split(/\s+/)961 .join(' ')962 963 // First, split based on boolean or ||964 this.set = this.raw.split('||').map(function (range) {965 return this.parseRange(range.trim())966 }, this).filter(function (c) {967 // throw out any that are not relevant for whatever reason968 return c.length969 })970 971 if (!this.set.length) {972 throw new TypeError('Invalid SemVer Range: ' + this.raw)973 }974 975 this.format()976}977 978Range.prototype.format = function () {979 this.range = this.set.map(function (comps) {980 return comps.join(' ').trim()981 }).join('||').trim()982 return this.range983}984 985Range.prototype.toString = function () {986 return this.range987}988 989Range.prototype.parseRange = function (range) {990 var loose = this.options.loose991 // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`992 var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE]993 range = range.replace(hr, hyphenReplace)994 debug('hyphen replace', range)995 // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`996 range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace)997 debug('comparator trim', range, safeRe[t.COMPARATORTRIM])998 999 // `~ 1.2.3` => `~1.2.3`1000 range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace)1001 1002 // `^ 1.2.3` => `^1.2.3`1003 range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace)1004 1005 // normalize spaces1006 range = range.split(/\s+/).join(' ')1007 1008 // At this point, the range is completely trimmed and1009 // ready to be split into comparators.1010 1011 var compRe = loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR]1012 var set = range.split(' ').map(function (comp) {1013 return parseComparator(comp, this.options)1014 }, this).join(' ').split(/\s+/)1015 if (this.options.loose) {1016 // in loose mode, throw out any that are not valid comparators1017 set = set.filter(function (comp) {1018 return !!comp.match(compRe)1019 })1020 }1021 set = set.map(function (comp) {1022 return new Comparator(comp, this.options)1023 }, this)1024 1025 return set1026}1027 1028Range.prototype.intersects = function (range, options) {1029 if (!(range instanceof Range)) {1030 throw new TypeError('a Range is required')1031 }1032 1033 return this.set.some(function (thisComparators) {1034 return (1035 isSatisfiable(thisComparators, options) &&1036 range.set.some(function (rangeComparators) {1037 return (1038 isSatisfiable(rangeComparators, options) &&1039 thisComparators.every(function (thisComparator) {1040 return rangeComparators.every(function (rangeComparator) {1041 return thisComparator.intersects(rangeComparator, options)1042 })1043 })1044 )1045 })1046 )1047 })1048}1049 1050// take a set of comparators and determine whether there1051// exists a version which can satisfy it1052function isSatisfiable (comparators, options) {1053 var result = true1054 var remainingComparators = comparators.slice()1055 var testComparator = remainingComparators.pop()1056 1057 while (result && remainingComparators.length) {1058 result = remainingComparators.every(function (otherComparator) {1059 return testComparator.intersects(otherComparator, options)1060 })1061 1062 testComparator = remainingComparators.pop()1063 }1064 1065 return result1066}1067 1068// Mostly just for testing and legacy API reasons1069exports.toComparators = toComparators1070function toComparators (range, options) {1071 return new Range(range, options).set.map(function (comp) {1072 return comp.map(function (c) {1073 return c.value1074 }).join(' ').trim().split(' ')1075 })1076}1077 1078// comprised of xranges, tildes, stars, and gtlt's at this point.1079// already replaced the hyphen ranges1080// turn into a set of JUST comparators.1081function parseComparator (comp, options) {1082 debug('comp', comp, options)1083 comp = replaceCarets(comp, options)1084 debug('caret', comp)1085 comp = replaceTildes(comp, options)1086 debug('tildes', comp)1087 comp = replaceXRanges(comp, options)1088 debug('xrange', comp)1089 comp = replaceStars(comp, options)1090 debug('stars', comp)1091 return comp1092}1093 1094function isX (id) {1095 return !id || id.toLowerCase() === 'x' || id === '*'1096}1097 1098// ~, ~> --> * (any, kinda silly)1099// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.01100// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.01101// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.01102// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.01103// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.01104function replaceTildes (comp, options) {1105 return comp.trim().split(/\s+/).map(function (comp) {1106 return replaceTilde(comp, options)1107 }).join(' ')1108}1109 1110function replaceTilde (comp, options) {1111 var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE]1112 return comp.replace(r, function (_, M, m, p, pr) {1113 debug('tilde', comp, _, M, m, p, pr)1114 var ret1115 1116 if (isX(M)) {1117 ret = ''1118 } else if (isX(m)) {1119 ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'1120 } else if (isX(p)) {1121 // ~1.2 == >=1.2.0 <1.3.01122 ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'1123 } else if (pr) {1124 debug('replaceTilde pr', pr)1125 ret = '>=' + M + '.' + m + '.' + p + '-' + pr +1126 ' <' + M + '.' + (+m + 1) + '.0'1127 } else {1128 // ~1.2.3 == >=1.2.3 <1.3.01129 ret = '>=' + M + '.' + m + '.' + p +1130 ' <' + M + '.' + (+m + 1) + '.0'1131 }1132 1133 debug('tilde return', ret)1134 return ret1135 })1136}1137 1138// ^ --> * (any, kinda silly)1139// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.01140// ^2.0, ^2.0.x --> >=2.0.0 <3.0.01141// ^1.2, ^1.2.x --> >=1.2.0 <2.0.01142// ^1.2.3 --> >=1.2.3 <2.0.01143// ^1.2.0 --> >=1.2.0 <2.0.01144function replaceCarets (comp, options) {1145 return comp.trim().split(/\s+/).map(function (comp) {1146 return replaceCaret(comp, options)1147 }).join(' ')1148}1149 1150function replaceCaret (comp, options) {1151 debug('caret', comp, options)1152 var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET]1153 return comp.replace(r, function (_, M, m, p, pr) {1154 debug('caret', comp, _, M, m, p, pr)1155 var ret1156 1157 if (isX(M)) {1158 ret = ''1159 } else if (isX(m)) {1160 ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'1161 } else if (isX(p)) {1162 if (M === '0') {1163 ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'1164 } else {1165 ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'1166 }1167 } else if (pr) {1168 debug('replaceCaret pr', pr)1169 if (M === '0') {1170 if (m === '0') {1171 ret = '>=' + M + '.' + m + '.' + p + '-' + pr +1172 ' <' + M + '.' + m + '.' + (+p + 1)1173 } else {1174 ret = '>=' + M + '.' + m + '.' + p + '-' + pr +1175 ' <' + M + '.' + (+m + 1) + '.0'1176 }1177 } else {1178 ret = '>=' + M + '.' + m + '.' + p + '-' + pr +1179 ' <' + (+M + 1) + '.0.0'1180 }1181 } else {1182 debug('no pr')1183 if (M === '0') {1184 if (m === '0') {1185 ret = '>=' + M + '.' + m + '.' + p +1186 ' <' + M + '.' + m + '.' + (+p + 1)1187 } else {1188 ret = '>=' + M + '.' + m + '.' + p +1189 ' <' + M + '.' + (+m + 1) + '.0'1190 }1191 } else {1192 ret = '>=' + M + '.' + m + '.' + p +1193 ' <' + (+M + 1) + '.0.0'1194 }1195 }1196 1197 debug('caret return', ret)1198 return ret1199 })1200}