Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

semver.js 38KB

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