semver.js 43 KB

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