1const SemVer = require('../classes/semver')
2const Range = require('../classes/range')
3const gt = require('../functions/gt')
4
5const minVersion = (range, loose) => {
6  range = new Range(range, loose)
7
8  let minver = new SemVer('0.0.0')
9  if (range.test(minver)) {
10    return minver
11  }
12
13  minver = new SemVer('0.0.0-0')
14  if (range.test(minver)) {
15    return minver
16  }
17
18  minver = null
19  for (let i = 0; i < range.set.length; ++i) {
20    const comparators = range.set[i]
21
22    let setMin = null
23    comparators.forEach((comparator) => {
24      // Clone to avoid manipulating the comparator's semver object.
25      const compver = new SemVer(comparator.semver.version)
26      switch (comparator.operator) {
27        case '>':
28          if (compver.prerelease.length === 0) {
29            compver.patch++
30          } else {
31            compver.prerelease.push(0)
32          }
33          compver.raw = compver.format()
34          /* fallthrough */
35        case '':
36        case '>=':
37          if (!setMin || gt(compver, setMin)) {
38            setMin = compver
39          }
40          break
41        case '<':
42        case '<=':
43          /* Ignore maximum versions */
44          break
45        /* istanbul ignore next */
46        default:
47          throw new Error(`Unexpected operation: ${comparator.operator}`)
48      }
49    })
50    if (setMin && (!minver || gt(minver, setMin))) {
51      minver = setMin
52    }
53  }
54
55  if (minver && range.test(minver)) {
56    return minver
57  }
58
59  return null
60}
61module.exports = minVersion
62