semver.js 41 KB

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