convert-range.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. var nodeSemver = require('semver');
  2. var sver = require('./sver');
  3. var Semver = sver.Semver;
  4. var SemverRange = sver.SemverRange;
  5. var forOf = require('es6-iterator/for-of');
  6. module.exports = function nodeRangeToSemverRange (range) {
  7. var parsed = nodeSemver.validRange(range);
  8. // tag version
  9. if (!parsed)
  10. return new SemverRange(range);
  11. if (parsed === '*')
  12. return new SemverRange(parsed);
  13. try {
  14. var semverRange = new SemverRange(range);
  15. if (!semverRange.version.tag)
  16. return semverRange;
  17. }
  18. catch (e) {
  19. if (e.code !== 'ENOTSEMVER')
  20. throw e;
  21. }
  22. var outRange;
  23. forOf(parsed.split('||'), function(union) {
  24. // compute the intersection into a lowest upper bound and a highest lower bound
  25. var upperBound, lowerBound, upperEq, lowerEq;
  26. forOf(union.split(' '), function(intersection, doBreak) {
  27. var lt = intersection[0] === '<';
  28. var gt = intersection[0] === '>';
  29. if (!lt && !gt) {
  30. upperBound = intersection;
  31. upperEq = true;
  32. return doBreak();
  33. }
  34. var eq = intersection[1] === '=';
  35. if (!gt) {
  36. var version = new Semver(intersection.substr(1 + eq));
  37. if (!upperBound || upperBound.gt(version)) {
  38. upperBound = version;
  39. upperEq = eq;
  40. }
  41. }
  42. else if (!lt) {
  43. var eq = intersection[1] === '=';
  44. var version = new Semver(intersection.substr(1 + eq));
  45. if (!lowerBound || lowerBound.lt(version)) {
  46. lowerBound = version;
  47. lowerEq = eq;
  48. }
  49. }
  50. });
  51. // if the lower bound is greater than the upper bound then just return the lower bound exactly
  52. if (lowerBound && upperBound && lowerBound.gt(upperBound)) {
  53. var curRange = new SemverRange(lowerBound.toString());
  54. // the largest or highest union range wins
  55. if (!outRange || !outRange.contains(curRange) && (curRange.gt(outRange) || curRange.contains(outRange)))
  56. outRange = curRange;
  57. return;
  58. }
  59. // determine the largest semver range satisfying the upper bound
  60. var upperRange;
  61. if (upperBound) {
  62. // if the upper bound has an equality then we return it directly
  63. if (upperEq) {
  64. var curRange = new SemverRange(upperBound.toString());
  65. // the largest or highest union range wins
  66. if (!outRange || !outRange.contains(curRange) && (curRange.gt(outRange) || curRange.contains(outRange)))
  67. outRange = curRange;
  68. return;
  69. }
  70. // prerelease ignored in upper bound
  71. var major = 0, minor = 0, patch = 0, rangeType = '';
  72. // <2.0.0 -> ^1.0.0
  73. if (upperBound.patch === 0) {
  74. if (upperBound.minor === 0) {
  75. if (upperBound.major > 0) {
  76. major = upperBound.major - 1;
  77. rangeType = '^';
  78. }
  79. }
  80. // <1.2.0 -> ~1.1.0
  81. else {
  82. major = upperBound.major;
  83. minor = upperBound.minor - 1;
  84. rangeType = '~';
  85. }
  86. }
  87. // <1.2.3 -> ~1.2.0
  88. else {
  89. major = upperBound.major;
  90. minor = upperBound.minor;
  91. patch = 0;
  92. rangeType = '~';
  93. }
  94. if (major === 0 && rangeType === '^')
  95. upperRange = new SemverRange('0');
  96. else
  97. upperRange = new SemverRange(rangeType + major + '.' + minor + '.' + patch);
  98. }
  99. // determine the lower range semver range
  100. var lowerRange;
  101. if (!lowerEq) {
  102. if (lowerBound.pre)
  103. lowerRange = new SemverRange('^' + lowerBound.major + '.' + lowerBound.minor + '.' + lowerBound.patch + '-' + lowerBound.pre.join('.') + '.1');
  104. else
  105. lowerRange = new SemverRange('^' + lowerBound.major + '.' + lowerBound.minor + '.' + (lowerBound.patch + 1));
  106. }
  107. else {
  108. lowerRange = new SemverRange('^' + lowerBound.toString());
  109. }
  110. // we then intersect the upper semver range with the lower semver range
  111. // if the intersection is empty, we return the upper range only
  112. var curRange = upperRange ? lowerRange.intersect(upperRange) || upperRange : lowerRange;
  113. // the largest or highest union range wins
  114. if (!outRange || !outRange.contains(curRange) && (curRange.gt(outRange) || curRange.contains(outRange)))
  115. outRange = curRange;
  116. });
  117. return outRange;
  118. }