"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/semver/semver.js" (8 Mar 2017, 32966 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 exports = module.exports = SemVer;
    2 
    3 // The debug function is excluded entirely from the minified version.
    4 /* nomin */ var debug;
    5 /* nomin */ if (typeof process === 'object' &&
    6     /* nomin */ process.env &&
    7     /* nomin */ process.env.NODE_DEBUG &&
    8     /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG))
    9   /* nomin */ debug = function() {
   10     /* nomin */ var args = Array.prototype.slice.call(arguments, 0);
   11     /* nomin */ args.unshift('SEMVER');
   12     /* nomin */ console.log.apply(console, args);
   13     /* nomin */ };
   14 /* nomin */ else
   15   /* nomin */ debug = function() {};
   16 
   17 // Note: this is the semver.org version of the spec that it implements
   18 // Not necessarily the package version of this code.
   19 exports.SEMVER_SPEC_VERSION = '2.0.0';
   20 
   21 var MAX_LENGTH = 256;
   22 var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
   23 
   24 // The actual regexps go on exports.re
   25 var re = exports.re = [];
   26 var src = exports.src = [];
   27 var R = 0;
   28 
   29 // The following Regular Expressions can be used for tokenizing,
   30 // validating, and parsing SemVer version strings.
   31 
   32 // ## Numeric Identifier
   33 // A single `0`, or a non-zero digit followed by zero or more digits.
   34 
   35 var NUMERICIDENTIFIER = R++;
   36 src[NUMERICIDENTIFIER] = '0|[1-9]\\d*';
   37 var NUMERICIDENTIFIERLOOSE = R++;
   38 src[NUMERICIDENTIFIERLOOSE] = '[0-9]+';
   39 
   40 
   41 // ## Non-numeric Identifier
   42 // Zero or more digits, followed by a letter or hyphen, and then zero or
   43 // more letters, digits, or hyphens.
   44 
   45 var NONNUMERICIDENTIFIER = R++;
   46 src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';
   47 
   48 
   49 // ## Main Version
   50 // Three dot-separated numeric identifiers.
   51 
   52 var MAINVERSION = R++;
   53 src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' +
   54                    '(' + src[NUMERICIDENTIFIER] + ')\\.' +
   55                    '(' + src[NUMERICIDENTIFIER] + ')';
   56 
   57 var MAINVERSIONLOOSE = R++;
   58 src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
   59                         '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
   60                         '(' + src[NUMERICIDENTIFIERLOOSE] + ')';
   61 
   62 // ## Pre-release Version Identifier
   63 // A numeric identifier, or a non-numeric identifier.
   64 
   65 var PRERELEASEIDENTIFIER = R++;
   66 src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] +
   67                             '|' + src[NONNUMERICIDENTIFIER] + ')';
   68 
   69 var PRERELEASEIDENTIFIERLOOSE = R++;
   70 src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] +
   71                                  '|' + src[NONNUMERICIDENTIFIER] + ')';
   72 
   73 
   74 // ## Pre-release Version
   75 // Hyphen, followed by one or more dot-separated pre-release version
   76 // identifiers.
   77 
   78 var PRERELEASE = R++;
   79 src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] +
   80                   '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))';
   81 
   82 var PRERELEASELOOSE = R++;
   83 src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] +
   84                        '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))';
   85 
   86 // ## Build Metadata Identifier
   87 // Any combination of digits, letters, or hyphens.
   88 
   89 var BUILDIDENTIFIER = R++;
   90 src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+';
   91 
   92 // ## Build Metadata
   93 // Plus sign, followed by one or more period-separated build metadata
   94 // identifiers.
   95 
   96 var BUILD = R++;
   97 src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
   98              '(?:\\.' + src[BUILDIDENTIFIER] + ')*))';
   99 
  100 
  101 // ## Full Version String
  102 // A main version, followed optionally by a pre-release version and
  103 // build metadata.
  104 
  105 // Note that the only major, minor, patch, and pre-release sections of
  106 // the version string are capturing groups.  The build metadata is not a
  107 // capturing group, because it should not ever be used in version
  108 // comparison.
  109 
  110 var FULL = R++;
  111 var FULLPLAIN = 'v?' + src[MAINVERSION] +
  112                 src[PRERELEASE] + '?' +
  113                 src[BUILD] + '?';
  114 
  115 src[FULL] = '^' + FULLPLAIN + '$';
  116 
  117 // like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
  118 // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
  119 // common in the npm registry.
  120 var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] +
  121                  src[PRERELEASELOOSE] + '?' +
  122                  src[BUILD] + '?';
  123 
  124 var LOOSE = R++;
  125 src[LOOSE] = '^' + LOOSEPLAIN + '$';
  126 
  127 var GTLT = R++;
  128 src[GTLT] = '((?:<|>)?=?)';
  129 
  130 // Something like "2.*" or "1.2.x".
  131 // Note that "x.x" is a valid xRange identifer, meaning "any version"
  132 // Only the first item is strictly required.
  133 var XRANGEIDENTIFIERLOOSE = R++;
  134 src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*';
  135 var XRANGEIDENTIFIER = R++;
  136 src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*';
  137 
  138 var XRANGEPLAIN = R++;
  139 src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' +
  140                    '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
  141                    '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
  142                    '(?:' + src[PRERELEASE] + ')?' +
  143                    src[BUILD] + '?' +
  144                    ')?)?';
  145 
  146 var XRANGEPLAINLOOSE = R++;
  147 src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
  148                         '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
  149                         '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
  150                         '(?:' + src[PRERELEASELOOSE] + ')?' +
  151                         src[BUILD] + '?' +
  152                         ')?)?';
  153 
  154 var XRANGE = R++;
  155 src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$';
  156 var XRANGELOOSE = R++;
  157 src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$';
  158 
  159 // Tilde ranges.
  160 // Meaning is "reasonably at or greater than"
  161 var LONETILDE = R++;
  162 src[LONETILDE] = '(?:~>?)';
  163 
  164 var TILDETRIM = R++;
  165 src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+';
  166 re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g');
  167 var tildeTrimReplace = '$1~';
  168 
  169 var TILDE = R++;
  170 src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$';
  171 var TILDELOOSE = R++;
  172 src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$';
  173 
  174 // Caret ranges.
  175 // Meaning is "at least and backwards compatible with"
  176 var LONECARET = R++;
  177 src[LONECARET] = '(?:\\^)';
  178 
  179 var CARETTRIM = R++;
  180 src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+';
  181 re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g');
  182 var caretTrimReplace = '$1^';
  183 
  184 var CARET = R++;
  185 src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$';
  186 var CARETLOOSE = R++;
  187 src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$';
  188 
  189 // A simple gt/lt/eq thing, or just "" to indicate "any version"
  190 var COMPARATORLOOSE = R++;
  191 src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$';
  192 var COMPARATOR = R++;
  193 src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$';
  194 
  195 
  196 // An expression to strip any whitespace between the gtlt and the thing
  197 // it modifies, so that `> 1.2.3` ==> `>1.2.3`
  198 var COMPARATORTRIM = R++;
  199 src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] +
  200                       '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')';
  201 
  202 // this one has to use the /g flag
  203 re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g');
  204 var comparatorTrimReplace = '$1$2$3';
  205 
  206 
  207 // Something like `1.2.3 - 1.2.4`
  208 // Note that these all use the loose form, because they'll be
  209 // checked against either the strict or loose comparator form
  210 // later.
  211 var HYPHENRANGE = R++;
  212 src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' +
  213                    '\\s+-\\s+' +
  214                    '(' + src[XRANGEPLAIN] + ')' +
  215                    '\\s*$';
  216 
  217 var HYPHENRANGELOOSE = R++;
  218 src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' +
  219                         '\\s+-\\s+' +
  220                         '(' + src[XRANGEPLAINLOOSE] + ')' +
  221                         '\\s*$';
  222 
  223 // Star ranges basically just allow anything at all.
  224 var STAR = R++;
  225 src[STAR] = '(<|>)?=?\\s*\\*';
  226 
  227 // Compile to actual regexp objects.
  228 // All are flag-free, unless they were created above with a flag.
  229 for (var i = 0; i < R; i++) {
  230   debug(i, src[i]);
  231   if (!re[i])
  232     re[i] = new RegExp(src[i]);
  233 }
  234 
  235 exports.parse = parse;
  236 function parse(version, loose) {
  237   if (version instanceof SemVer)
  238     return version;
  239 
  240   if (typeof version !== 'string')
  241     return null;
  242 
  243   if (version.length > MAX_LENGTH)
  244     return null;
  245 
  246   var r = loose ? re[LOOSE] : re[FULL];
  247   if (!r.test(version))
  248     return null;
  249 
  250   try {
  251     return new SemVer(version, loose);
  252   } catch (er) {
  253     return null;
  254   }
  255 }
  256 
  257 exports.valid = valid;
  258 function valid(version, loose) {
  259   var v = parse(version, loose);
  260   return v ? v.version : null;
  261 }
  262 
  263 
  264 exports.clean = clean;
  265 function clean(version, loose) {
  266   var s = parse(version.trim().replace(/^[=v]+/, ''), loose);
  267   return s ? s.version : null;
  268 }
  269 
  270 exports.SemVer = SemVer;
  271 
  272 function SemVer(version, loose) {
  273   if (version instanceof SemVer) {
  274     if (version.loose === loose)
  275       return version;
  276     else
  277       version = version.version;
  278   } else if (typeof version !== 'string') {
  279     throw new TypeError('Invalid Version: ' + version);
  280   }
  281 
  282   if (version.length > MAX_LENGTH)
  283     throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters')
  284 
  285   if (!(this instanceof SemVer))
  286     return new SemVer(version, loose);
  287 
  288   debug('SemVer', version, loose);
  289   this.loose = loose;
  290   var m = version.trim().match(loose ? re[LOOSE] : re[FULL]);
  291 
  292   if (!m)
  293     throw new TypeError('Invalid Version: ' + version);
  294 
  295   this.raw = version;
  296 
  297   // these are actually numbers
  298   this.major = +m[1];
  299   this.minor = +m[2];
  300   this.patch = +m[3];
  301 
  302   if (this.major > MAX_SAFE_INTEGER || this.major < 0)
  303     throw new TypeError('Invalid major version')
  304 
  305   if (this.minor > MAX_SAFE_INTEGER || this.minor < 0)
  306     throw new TypeError('Invalid minor version')
  307 
  308   if (this.patch > MAX_SAFE_INTEGER || this.patch < 0)
  309     throw new TypeError('Invalid patch version')
  310 
  311   // numberify any prerelease numeric ids
  312   if (!m[4])
  313     this.prerelease = [];
  314   else
  315     this.prerelease = m[4].split('.').map(function(id) {
  316       if (/^[0-9]+$/.test(id)) {
  317         var num = +id;
  318         if (num >= 0 && num < MAX_SAFE_INTEGER)
  319           return num;
  320       }
  321       return id;
  322     });
  323 
  324   this.build = m[5] ? m[5].split('.') : [];
  325   this.format();
  326 }
  327 
  328 SemVer.prototype.format = function() {
  329   this.version = this.major + '.' + this.minor + '.' + this.patch;
  330   if (this.prerelease.length)
  331     this.version += '-' + this.prerelease.join('.');
  332   return this.version;
  333 };
  334 
  335 SemVer.prototype.toString = function() {
  336   return this.version;
  337 };
  338 
  339 SemVer.prototype.compare = function(other) {
  340   debug('SemVer.compare', this.version, this.loose, other);
  341   if (!(other instanceof SemVer))
  342     other = new SemVer(other, this.loose);
  343 
  344   return this.compareMain(other) || this.comparePre(other);
  345 };
  346 
  347 SemVer.prototype.compareMain = function(other) {
  348   if (!(other instanceof SemVer))
  349     other = new SemVer(other, this.loose);
  350 
  351   return compareIdentifiers(this.major, other.major) ||
  352          compareIdentifiers(this.minor, other.minor) ||
  353          compareIdentifiers(this.patch, other.patch);
  354 };
  355 
  356 SemVer.prototype.comparePre = function(other) {
  357   if (!(other instanceof SemVer))
  358     other = new SemVer(other, this.loose);
  359 
  360   // NOT having a prerelease is > having one
  361   if (this.prerelease.length && !other.prerelease.length)
  362     return -1;
  363   else if (!this.prerelease.length && other.prerelease.length)
  364     return 1;
  365   else if (!this.prerelease.length && !other.prerelease.length)
  366     return 0;
  367 
  368   var i = 0;
  369   do {
  370     var a = this.prerelease[i];
  371     var b = other.prerelease[i];
  372     debug('prerelease compare', i, a, b);
  373     if (a === undefined && b === undefined)
  374       return 0;
  375     else if (b === undefined)
  376       return 1;
  377     else if (a === undefined)
  378       return -1;
  379     else if (a === b)
  380       continue;
  381     else
  382       return compareIdentifiers(a, b);
  383   } while (++i);
  384 };
  385 
  386 // preminor will bump the version up to the next minor release, and immediately
  387 // down to pre-release. premajor and prepatch work the same way.
  388 SemVer.prototype.inc = function(release, identifier) {
  389   switch (release) {
  390     case 'premajor':
  391       this.prerelease.length = 0;
  392       this.patch = 0;
  393       this.minor = 0;
  394       this.major++;
  395       this.inc('pre', identifier);
  396       break;
  397     case 'preminor':
  398       this.prerelease.length = 0;
  399       this.patch = 0;
  400       this.minor++;
  401       this.inc('pre', identifier);
  402       break;
  403     case 'prepatch':
  404       // If this is already a prerelease, it will bump to the next version
  405       // drop any prereleases that might already exist, since they are not
  406       // relevant at this point.
  407       this.prerelease.length = 0;
  408       this.inc('patch', identifier);
  409       this.inc('pre', identifier);
  410       break;
  411     // If the input is a non-prerelease version, this acts the same as
  412     // prepatch.
  413     case 'prerelease':
  414       if (this.prerelease.length === 0)
  415         this.inc('patch', identifier);
  416       this.inc('pre', identifier);
  417       break;
  418 
  419     case 'major':
  420       // If this is a pre-major version, bump up to the same major version.
  421       // Otherwise increment major.
  422       // 1.0.0-5 bumps to 1.0.0
  423       // 1.1.0 bumps to 2.0.0
  424       if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0)
  425         this.major++;
  426       this.minor = 0;
  427       this.patch = 0;
  428       this.prerelease = [];
  429       break;
  430     case 'minor':
  431       // If this is a pre-minor version, bump up to the same minor version.
  432       // Otherwise increment minor.
  433       // 1.2.0-5 bumps to 1.2.0
  434       // 1.2.1 bumps to 1.3.0
  435       if (this.patch !== 0 || this.prerelease.length === 0)
  436         this.minor++;
  437       this.patch = 0;
  438       this.prerelease = [];
  439       break;
  440     case 'patch':
  441       // If this is not a pre-release version, it will increment the patch.
  442       // If it is a pre-release it will bump up to the same patch version.
  443       // 1.2.0-5 patches to 1.2.0
  444       // 1.2.0 patches to 1.2.1
  445       if (this.prerelease.length === 0)
  446         this.patch++;
  447       this.prerelease = [];
  448       break;
  449     // This probably shouldn't be used publicly.
  450     // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
  451     case 'pre':
  452       if (this.prerelease.length === 0)
  453         this.prerelease = [0];
  454       else {
  455         var i = this.prerelease.length;
  456         while (--i >= 0) {
  457           if (typeof this.prerelease[i] === 'number') {
  458             this.prerelease[i]++;
  459             i = -2;
  460           }
  461         }
  462         if (i === -1) // didn't increment anything
  463           this.prerelease.push(0);
  464       }
  465       if (identifier) {
  466         // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
  467         // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
  468         if (this.prerelease[0] === identifier) {
  469           if (isNaN(this.prerelease[1]))
  470             this.prerelease = [identifier, 0];
  471         } else
  472           this.prerelease = [identifier, 0];
  473       }
  474       break;
  475 
  476     default:
  477       throw new Error('invalid increment argument: ' + release);
  478   }
  479   this.format();
  480   this.raw = this.version;
  481   return this;
  482 };
  483 
  484 exports.inc = inc;
  485 function inc(version, release, loose, identifier) {
  486   if (typeof(loose) === 'string') {
  487     identifier = loose;
  488     loose = undefined;
  489   }
  490 
  491   try {
  492     return new SemVer(version, loose).inc(release, identifier).version;
  493   } catch (er) {
  494     return null;
  495   }
  496 }
  497 
  498 exports.diff = diff;
  499 function diff(version1, version2) {
  500   if (eq(version1, version2)) {
  501     return null;
  502   } else {
  503     var v1 = parse(version1);
  504     var v2 = parse(version2);
  505     if (v1.prerelease.length || v2.prerelease.length) {
  506       for (var key in v1) {
  507         if (key === 'major' || key === 'minor' || key === 'patch') {
  508           if (v1[key] !== v2[key]) {
  509             return 'pre'+key;
  510           }
  511         }
  512       }
  513       return 'prerelease';
  514     }
  515     for (var key in v1) {
  516       if (key === 'major' || key === 'minor' || key === 'patch') {
  517         if (v1[key] !== v2[key]) {
  518           return key;
  519         }
  520       }
  521     }
  522   }
  523 }
  524 
  525 exports.compareIdentifiers = compareIdentifiers;
  526 
  527 var numeric = /^[0-9]+$/;
  528 function compareIdentifiers(a, b) {
  529   var anum = numeric.test(a);
  530   var bnum = numeric.test(b);
  531 
  532   if (anum && bnum) {
  533     a = +a;
  534     b = +b;
  535   }
  536 
  537   return (anum && !bnum) ? -1 :
  538          (bnum && !anum) ? 1 :
  539          a < b ? -1 :
  540          a > b ? 1 :
  541          0;
  542 }
  543 
  544 exports.rcompareIdentifiers = rcompareIdentifiers;
  545 function rcompareIdentifiers(a, b) {
  546   return compareIdentifiers(b, a);
  547 }
  548 
  549 exports.major = major;
  550 function major(a, loose) {
  551   return new SemVer(a, loose).major;
  552 }
  553 
  554 exports.minor = minor;
  555 function minor(a, loose) {
  556   return new SemVer(a, loose).minor;
  557 }
  558 
  559 exports.patch = patch;
  560 function patch(a, loose) {
  561   return new SemVer(a, loose).patch;
  562 }
  563 
  564 exports.compare = compare;
  565 function compare(a, b, loose) {
  566   return new SemVer(a, loose).compare(b);
  567 }
  568 
  569 exports.compareLoose = compareLoose;
  570 function compareLoose(a, b) {
  571   return compare(a, b, true);
  572 }
  573 
  574 exports.rcompare = rcompare;
  575 function rcompare(a, b, loose) {
  576   return compare(b, a, loose);
  577 }
  578 
  579 exports.sort = sort;
  580 function sort(list, loose) {
  581   return list.sort(function(a, b) {
  582     return exports.compare(a, b, loose);
  583   });
  584 }
  585 
  586 exports.rsort = rsort;
  587 function rsort(list, loose) {
  588   return list.sort(function(a, b) {
  589     return exports.rcompare(a, b, loose);
  590   });
  591 }
  592 
  593 exports.gt = gt;
  594 function gt(a, b, loose) {
  595   return compare(a, b, loose) > 0;
  596 }
  597 
  598 exports.lt = lt;
  599 function lt(a, b, loose) {
  600   return compare(a, b, loose) < 0;
  601 }
  602 
  603 exports.eq = eq;
  604 function eq(a, b, loose) {
  605   return compare(a, b, loose) === 0;
  606 }
  607 
  608 exports.neq = neq;
  609 function neq(a, b, loose) {
  610   return compare(a, b, loose) !== 0;
  611 }
  612 
  613 exports.gte = gte;
  614 function gte(a, b, loose) {
  615   return compare(a, b, loose) >= 0;
  616 }
  617 
  618 exports.lte = lte;
  619 function lte(a, b, loose) {
  620   return compare(a, b, loose) <= 0;
  621 }
  622 
  623 exports.cmp = cmp;
  624 function cmp(a, op, b, loose) {
  625   var ret;
  626   switch (op) {
  627     case '===':
  628       if (typeof a === 'object') a = a.version;
  629       if (typeof b === 'object') b = b.version;
  630       ret = a === b;
  631       break;
  632     case '!==':
  633       if (typeof a === 'object') a = a.version;
  634       if (typeof b === 'object') b = b.version;
  635       ret = a !== b;
  636       break;
  637     case '': case '=': case '==': ret = eq(a, b, loose); break;
  638     case '!=': ret = neq(a, b, loose); break;
  639     case '>': ret = gt(a, b, loose); break;
  640     case '>=': ret = gte(a, b, loose); break;
  641     case '<': ret = lt(a, b, loose); break;
  642     case '<=': ret = lte(a, b, loose); break;
  643     default: throw new TypeError('Invalid operator: ' + op);
  644   }
  645   return ret;
  646 }
  647 
  648 exports.Comparator = Comparator;
  649 function Comparator(comp, loose) {
  650   if (comp instanceof Comparator) {
  651     if (comp.loose === loose)
  652       return comp;
  653     else
  654       comp = comp.value;
  655   }
  656 
  657   if (!(this instanceof Comparator))
  658     return new Comparator(comp, loose);
  659 
  660   debug('comparator', comp, loose);
  661   this.loose = loose;
  662   this.parse(comp);
  663 
  664   if (this.semver === ANY)
  665     this.value = '';
  666   else
  667     this.value = this.operator + this.semver.version;
  668 
  669   debug('comp', this);
  670 }
  671 
  672 var ANY = {};
  673 Comparator.prototype.parse = function(comp) {
  674   var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
  675   var m = comp.match(r);
  676 
  677   if (!m)
  678     throw new TypeError('Invalid comparator: ' + comp);
  679 
  680   this.operator = m[1];
  681   if (this.operator === '=')
  682     this.operator = '';
  683 
  684   // if it literally is just '>' or '' then allow anything.
  685   if (!m[2])
  686     this.semver = ANY;
  687   else
  688     this.semver = new SemVer(m[2], this.loose);
  689 };
  690 
  691 Comparator.prototype.toString = function() {
  692   return this.value;
  693 };
  694 
  695 Comparator.prototype.test = function(version) {
  696   debug('Comparator.test', version, this.loose);
  697 
  698   if (this.semver === ANY)
  699     return true;
  700 
  701   if (typeof version === 'string')
  702     version = new SemVer(version, this.loose);
  703 
  704   return cmp(version, this.operator, this.semver, this.loose);
  705 };
  706 
  707 
  708 exports.Range = Range;
  709 function Range(range, loose) {
  710   if ((range instanceof Range) && range.loose === loose)
  711     return range;
  712 
  713   if (!(this instanceof Range))
  714     return new Range(range, loose);
  715 
  716   this.loose = loose;
  717 
  718   // First, split based on boolean or ||
  719   this.raw = range;
  720   this.set = range.split(/\s*\|\|\s*/).map(function(range) {
  721     return this.parseRange(range.trim());
  722   }, this).filter(function(c) {
  723     // throw out any that are not relevant for whatever reason
  724     return c.length;
  725   });
  726 
  727   if (!this.set.length) {
  728     throw new TypeError('Invalid SemVer Range: ' + range);
  729   }
  730 
  731   this.format();
  732 }
  733 
  734 Range.prototype.format = function() {
  735   this.range = this.set.map(function(comps) {
  736     return comps.join(' ').trim();
  737   }).join('||').trim();
  738   return this.range;
  739 };
  740 
  741 Range.prototype.toString = function() {
  742   return this.range;
  743 };
  744 
  745 Range.prototype.parseRange = function(range) {
  746   var loose = this.loose;
  747   range = range.trim();
  748   debug('range', range, loose);
  749   // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
  750   var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
  751   range = range.replace(hr, hyphenReplace);
  752   debug('hyphen replace', range);
  753   // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
  754   range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace);
  755   debug('comparator trim', range, re[COMPARATORTRIM]);
  756 
  757   // `~ 1.2.3` => `~1.2.3`
  758   range = range.replace(re[TILDETRIM], tildeTrimReplace);
  759 
  760   // `^ 1.2.3` => `^1.2.3`
  761   range = range.replace(re[CARETTRIM], caretTrimReplace);
  762 
  763   // normalize spaces
  764   range = range.split(/\s+/).join(' ');
  765 
  766   // At this point, the range is completely trimmed and
  767   // ready to be split into comparators.
  768 
  769   var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
  770   var set = range.split(' ').map(function(comp) {
  771     return parseComparator(comp, loose);
  772   }).join(' ').split(/\s+/);
  773   if (this.loose) {
  774     // in loose mode, throw out any that are not valid comparators
  775     set = set.filter(function(comp) {
  776       return !!comp.match(compRe);
  777     });
  778   }
  779   set = set.map(function(comp) {
  780     return new Comparator(comp, loose);
  781   });
  782 
  783   return set;
  784 };
  785 
  786 // Mostly just for testing and legacy API reasons
  787 exports.toComparators = toComparators;
  788 function toComparators(range, loose) {
  789   return new Range(range, loose).set.map(function(comp) {
  790     return comp.map(function(c) {
  791       return c.value;
  792     }).join(' ').trim().split(' ');
  793   });
  794 }
  795 
  796 // comprised of xranges, tildes, stars, and gtlt's at this point.
  797 // already replaced the hyphen ranges
  798 // turn into a set of JUST comparators.
  799 function parseComparator(comp, loose) {
  800   debug('comp', comp);
  801   comp = replaceCarets(comp, loose);
  802   debug('caret', comp);
  803   comp = replaceTildes(comp, loose);
  804   debug('tildes', comp);
  805   comp = replaceXRanges(comp, loose);
  806   debug('xrange', comp);
  807   comp = replaceStars(comp, loose);
  808   debug('stars', comp);
  809   return comp;
  810 }
  811 
  812 function isX(id) {
  813   return !id || id.toLowerCase() === 'x' || id === '*';
  814 }
  815 
  816 // ~, ~> --> * (any, kinda silly)
  817 // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
  818 // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
  819 // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
  820 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
  821 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
  822 function replaceTildes(comp, loose) {
  823   return comp.trim().split(/\s+/).map(function(comp) {
  824     return replaceTilde(comp, loose);
  825   }).join(' ');
  826 }
  827 
  828 function replaceTilde(comp, loose) {
  829   var r = loose ? re[TILDELOOSE] : re[TILDE];
  830   return comp.replace(r, function(_, M, m, p, pr) {
  831     debug('tilde', comp, _, M, m, p, pr);
  832     var ret;
  833 
  834     if (isX(M))
  835       ret = '';
  836     else if (isX(m))
  837       ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
  838     else if (isX(p))
  839       // ~1.2 == >=1.2.0 <1.3.0
  840       ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
  841     else if (pr) {
  842       debug('replaceTilde pr', pr);
  843       if (pr.charAt(0) !== '-')
  844         pr = '-' + pr;
  845       ret = '>=' + M + '.' + m + '.' + p + pr +
  846             ' <' + M + '.' + (+m + 1) + '.0';
  847     } else
  848       // ~1.2.3 == >=1.2.3 <1.3.0
  849       ret = '>=' + M + '.' + m + '.' + p +
  850             ' <' + M + '.' + (+m + 1) + '.0';
  851 
  852     debug('tilde return', ret);
  853     return ret;
  854   });
  855 }
  856 
  857 // ^ --> * (any, kinda silly)
  858 // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
  859 // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
  860 // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
  861 // ^1.2.3 --> >=1.2.3 <2.0.0
  862 // ^1.2.0 --> >=1.2.0 <2.0.0
  863 function replaceCarets(comp, loose) {
  864   return comp.trim().split(/\s+/).map(function(comp) {
  865     return replaceCaret(comp, loose);
  866   }).join(' ');
  867 }
  868 
  869 function replaceCaret(comp, loose) {
  870   debug('caret', comp, loose);
  871   var r = loose ? re[CARETLOOSE] : re[CARET];
  872   return comp.replace(r, function(_, M, m, p, pr) {
  873     debug('caret', comp, _, M, m, p, pr);
  874     var ret;
  875 
  876     if (isX(M))
  877       ret = '';
  878     else if (isX(m))
  879       ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
  880     else if (isX(p)) {
  881       if (M === '0')
  882         ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
  883       else
  884         ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0';
  885     } else if (pr) {
  886       debug('replaceCaret pr', pr);
  887       if (pr.charAt(0) !== '-')
  888         pr = '-' + pr;
  889       if (M === '0') {
  890         if (m === '0')
  891           ret = '>=' + M + '.' + m + '.' + p + pr +
  892                 ' <' + M + '.' + m + '.' + (+p + 1);
  893         else
  894           ret = '>=' + M + '.' + m + '.' + p + pr +
  895                 ' <' + M + '.' + (+m + 1) + '.0';
  896       } else
  897         ret = '>=' + M + '.' + m + '.' + p + pr +
  898               ' <' + (+M + 1) + '.0.0';
  899     } else {
  900       debug('no pr');
  901       if (M === '0') {
  902         if (m === '0')
  903           ret = '>=' + M + '.' + m + '.' + p +
  904                 ' <' + M + '.' + m + '.' + (+p + 1);
  905         else
  906           ret = '>=' + M + '.' + m + '.' + p +
  907                 ' <' + M + '.' + (+m + 1) + '.0';
  908       } else
  909         ret = '>=' + M + '.' + m + '.' + p +
  910               ' <' + (+M + 1) + '.0.0';
  911     }
  912 
  913     debug('caret return', ret);
  914     return ret;
  915   });
  916 }
  917 
  918 function replaceXRanges(comp, loose) {
  919   debug('replaceXRanges', comp, loose);
  920   return comp.split(/\s+/).map(function(comp) {
  921     return replaceXRange(comp, loose);
  922   }).join(' ');
  923 }
  924 
  925 function replaceXRange(comp, loose) {
  926   comp = comp.trim();
  927   var r = loose ? re[XRANGELOOSE] : re[XRANGE];
  928   return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
  929     debug('xRange', comp, ret, gtlt, M, m, p, pr);
  930     var xM = isX(M);
  931     var xm = xM || isX(m);
  932     var xp = xm || isX(p);
  933     var anyX = xp;
  934 
  935     if (gtlt === '=' && anyX)
  936       gtlt = '';
  937 
  938     if (xM) {
  939       if (gtlt === '>' || gtlt === '<') {
  940         // nothing is allowed
  941         ret = '<0.0.0';
  942       } else {
  943         // nothing is forbidden
  944         ret = '*';
  945       }
  946     } else if (gtlt && anyX) {
  947       // replace X with 0
  948       if (xm)
  949         m = 0;
  950       if (xp)
  951         p = 0;
  952 
  953       if (gtlt === '>') {
  954         // >1 => >=2.0.0
  955         // >1.2 => >=1.3.0
  956         // >1.2.3 => >= 1.2.4
  957         gtlt = '>=';
  958         if (xm) {
  959           M = +M + 1;
  960           m = 0;
  961           p = 0;
  962         } else if (xp) {
  963           m = +m + 1;
  964           p = 0;
  965         }
  966       } else if (gtlt === '<=') {
  967         // <=0.7.x is actually <0.8.0, since any 0.7.x should
  968         // pass.  Similarly, <=7.x is actually <8.0.0, etc.
  969         gtlt = '<';
  970         if (xm)
  971           M = +M + 1;
  972         else
  973           m = +m + 1;
  974       }
  975 
  976       ret = gtlt + M + '.' + m + '.' + p;
  977     } else if (xm) {
  978       ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
  979     } else if (xp) {
  980       ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
  981     }
  982 
  983     debug('xRange return', ret);
  984 
  985     return ret;
  986   });
  987 }
  988 
  989 // Because * is AND-ed with everything else in the comparator,
  990 // and '' means "any version", just remove the *s entirely.
  991 function replaceStars(comp, loose) {
  992   debug('replaceStars', comp, loose);
  993   // Looseness is ignored here.  star is always as loose as it gets!
  994   return comp.trim().replace(re[STAR], '');
  995 }
  996 
  997 // This function is passed to string.replace(re[HYPHENRANGE])
  998 // M, m, patch, prerelease, build
  999 // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
 1000 // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
 1001 // 1.2 - 3.4 => >=1.2.0 <3.5.0
 1002 function hyphenReplace($0,
 1003                        from, fM, fm, fp, fpr, fb,
 1004                        to, tM, tm, tp, tpr, tb) {
 1005 
 1006   if (isX(fM))
 1007     from = '';
 1008   else if (isX(fm))
 1009     from = '>=' + fM + '.0.0';
 1010   else if (isX(fp))
 1011     from = '>=' + fM + '.' + fm + '.0';
 1012   else
 1013     from = '>=' + from;
 1014 
 1015   if (isX(tM))
 1016     to = '';
 1017   else if (isX(tm))
 1018     to = '<' + (+tM + 1) + '.0.0';
 1019   else if (isX(tp))
 1020     to = '<' + tM + '.' + (+tm + 1) + '.0';
 1021   else if (tpr)
 1022     to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr;
 1023   else
 1024     to = '<=' + to;
 1025 
 1026   return (from + ' ' + to).trim();
 1027 }
 1028 
 1029 
 1030 // if ANY of the sets match ALL of its comparators, then pass
 1031 Range.prototype.test = function(version) {
 1032   if (!version)
 1033     return false;
 1034 
 1035   if (typeof version === 'string')
 1036     version = new SemVer(version, this.loose);
 1037 
 1038   for (var i = 0; i < this.set.length; i++) {
 1039     if (testSet(this.set[i], version))
 1040       return true;
 1041   }
 1042   return false;
 1043 };
 1044 
 1045 function testSet(set, version) {
 1046   for (var i = 0; i < set.length; i++) {
 1047     if (!set[i].test(version))
 1048       return false;
 1049   }
 1050 
 1051   if (version.prerelease.length) {
 1052     // Find the set of versions that are allowed to have prereleases
 1053     // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
 1054     // That should allow `1.2.3-pr.2` to pass.
 1055     // However, `1.2.4-alpha.notready` should NOT be allowed,
 1056     // even though it's within the range set by the comparators.
 1057     for (var i = 0; i < set.length; i++) {
 1058       debug(set[i].semver);
 1059       if (set[i].semver === ANY)
 1060         continue;
 1061 
 1062       if (set[i].semver.prerelease.length > 0) {
 1063         var allowed = set[i].semver;
 1064         if (allowed.major === version.major &&
 1065             allowed.minor === version.minor &&
 1066             allowed.patch === version.patch)
 1067           return true;
 1068       }
 1069     }
 1070 
 1071     // Version has a -pre, but it's not one of the ones we like.
 1072     return false;
 1073   }
 1074 
 1075   return true;
 1076 }
 1077 
 1078 exports.satisfies = satisfies;
 1079 function satisfies(version, range, loose) {
 1080   try {
 1081     range = new Range(range, loose);
 1082   } catch (er) {
 1083     return false;
 1084   }
 1085   return range.test(version);
 1086 }
 1087 
 1088 exports.maxSatisfying = maxSatisfying;
 1089 function maxSatisfying(versions, range, loose) {
 1090   return versions.filter(function(version) {
 1091     return satisfies(version, range, loose);
 1092   }).sort(function(a, b) {
 1093     return rcompare(a, b, loose);
 1094   })[0] || null;
 1095 }
 1096 
 1097 exports.minSatisfying = minSatisfying;
 1098 function minSatisfying(versions, range, loose) {
 1099   return versions.filter(function(version) {
 1100     return satisfies(version, range, loose);
 1101   }).sort(function(a, b) {
 1102     return compare(a, b, loose);
 1103   })[0] || null;
 1104 }
 1105 
 1106 exports.validRange = validRange;
 1107 function validRange(range, loose) {
 1108   try {
 1109     // Return '*' instead of '' so that truthiness works.
 1110     // This will throw if it's invalid anyway
 1111     return new Range(range, loose).range || '*';
 1112   } catch (er) {
 1113     return null;
 1114   }
 1115 }
 1116 
 1117 // Determine if version is less than all the versions possible in the range
 1118 exports.ltr = ltr;
 1119 function ltr(version, range, loose) {
 1120   return outside(version, range, '<', loose);
 1121 }
 1122 
 1123 // Determine if version is greater than all the versions possible in the range.
 1124 exports.gtr = gtr;
 1125 function gtr(version, range, loose) {
 1126   return outside(version, range, '>', loose);
 1127 }
 1128 
 1129 exports.outside = outside;
 1130 function outside(version, range, hilo, loose) {
 1131   version = new SemVer(version, loose);
 1132   range = new Range(range, loose);
 1133 
 1134   var gtfn, ltefn, ltfn, comp, ecomp;
 1135   switch (hilo) {
 1136     case '>':
 1137       gtfn = gt;
 1138       ltefn = lte;
 1139       ltfn = lt;
 1140       comp = '>';
 1141       ecomp = '>=';
 1142       break;
 1143     case '<':
 1144       gtfn = lt;
 1145       ltefn = gte;
 1146       ltfn = gt;
 1147       comp = '<';
 1148       ecomp = '<=';
 1149       break;
 1150     default:
 1151       throw new TypeError('Must provide a hilo val of "<" or ">"');
 1152   }
 1153 
 1154   // If it satisifes the range it is not outside
 1155   if (satisfies(version, range, loose)) {
 1156     return false;
 1157   }
 1158 
 1159   // From now on, variable terms are as if we're in "gtr" mode.
 1160   // but note that everything is flipped for the "ltr" function.
 1161 
 1162   for (var i = 0; i < range.set.length; ++i) {
 1163     var comparators = range.set[i];
 1164 
 1165     var high = null;
 1166     var low = null;
 1167 
 1168     comparators.forEach(function(comparator) {
 1169       if (comparator.semver === ANY) {
 1170         comparator = new Comparator('>=0.0.0')
 1171       }
 1172       high = high || comparator;
 1173       low = low || comparator;
 1174       if (gtfn(comparator.semver, high.semver, loose)) {
 1175         high = comparator;
 1176       } else if (ltfn(comparator.semver, low.semver, loose)) {
 1177         low = comparator;
 1178       }
 1179     });
 1180 
 1181     // If the edge version comparator has a operator then our version
 1182     // isn't outside it
 1183     if (high.operator === comp || high.operator === ecomp) {
 1184       return false;
 1185     }
 1186 
 1187     // If the lowest version comparator has an operator and our version
 1188     // is less than it then it isn't higher than the range
 1189     if ((!low.operator || low.operator === comp) &&
 1190         ltefn(version, low.semver)) {
 1191       return false;
 1192     } else if (low.operator === ecomp && ltfn(version, low.semver)) {
 1193       return false;
 1194     }
 1195   }
 1196   return true;
 1197 }
 1198 
 1199 exports.prerelease = prerelease;
 1200 function prerelease(version, loose) {
 1201   var parsed = parse(version, loose);
 1202   return (parsed && parsed.prerelease.length) ? parsed.prerelease : null;
 1203 }