semver.browser.js 31 KB

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