73247ad2b7eabc1361784d0b16340e34d298aea0
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / semver / classes / semver.js
1 const debug = require('../internal/debug')
2 const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants')
3 const { re, t } = require('../internal/re')
4
5 const { compareIdentifiers } = require('../internal/identifiers')
6 class SemVer {
7   constructor (version, options) {
8     if (!options || typeof options !== 'object') {
9       options = {
10         loose: !!options,
11         includePrerelease: false
12       }
13     }
14     if (version instanceof SemVer) {
15       if (version.loose === !!options.loose &&
16           version.includePrerelease === !!options.includePrerelease) {
17         return version
18       } else {
19         version = version.version
20       }
21     } else if (typeof version !== 'string') {
22       throw new TypeError(`Invalid Version: ${version}`)
23     }
24
25     if (version.length > MAX_LENGTH) {
26       throw new TypeError(
27         `version is longer than ${MAX_LENGTH} characters`
28       )
29     }
30
31     debug('SemVer', version, options)
32     this.options = options
33     this.loose = !!options.loose
34     // this isn't actually relevant for versions, but keep it so that we
35     // don't run into trouble passing this.options around.
36     this.includePrerelease = !!options.includePrerelease
37
38     const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL])
39
40     if (!m) {
41       throw new TypeError(`Invalid Version: ${version}`)
42     }
43
44     this.raw = version
45
46     // these are actually numbers
47     this.major = +m[1]
48     this.minor = +m[2]
49     this.patch = +m[3]
50
51     if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
52       throw new TypeError('Invalid major version')
53     }
54
55     if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
56       throw new TypeError('Invalid minor version')
57     }
58
59     if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
60       throw new TypeError('Invalid patch version')
61     }
62
63     // numberify any prerelease numeric ids
64     if (!m[4]) {
65       this.prerelease = []
66     } else {
67       this.prerelease = m[4].split('.').map((id) => {
68         if (/^[0-9]+$/.test(id)) {
69           const num = +id
70           if (num >= 0 && num < MAX_SAFE_INTEGER) {
71             return num
72           }
73         }
74         return id
75       })
76     }
77
78     this.build = m[5] ? m[5].split('.') : []
79     this.format()
80   }
81
82   format () {
83     this.version = `${this.major}.${this.minor}.${this.patch}`
84     if (this.prerelease.length) {
85       this.version += `-${this.prerelease.join('.')}`
86     }
87     return this.version
88   }
89
90   toString () {
91     return this.version
92   }
93
94   compare (other) {
95     debug('SemVer.compare', this.version, this.options, other)
96     if (!(other instanceof SemVer)) {
97       if (typeof other === 'string' && other === this.version) {
98         return 0
99       }
100       other = new SemVer(other, this.options)
101     }
102
103     if (other.version === this.version) {
104       return 0
105     }
106
107     return this.compareMain(other) || this.comparePre(other)
108   }
109
110   compareMain (other) {
111     if (!(other instanceof SemVer)) {
112       other = new SemVer(other, this.options)
113     }
114
115     return (
116       compareIdentifiers(this.major, other.major) ||
117       compareIdentifiers(this.minor, other.minor) ||
118       compareIdentifiers(this.patch, other.patch)
119     )
120   }
121
122   comparePre (other) {
123     if (!(other instanceof SemVer)) {
124       other = new SemVer(other, this.options)
125     }
126
127     // NOT having a prerelease is > having one
128     if (this.prerelease.length && !other.prerelease.length) {
129       return -1
130     } else if (!this.prerelease.length && other.prerelease.length) {
131       return 1
132     } else if (!this.prerelease.length && !other.prerelease.length) {
133       return 0
134     }
135
136     let i = 0
137     do {
138       const a = this.prerelease[i]
139       const b = other.prerelease[i]
140       debug('prerelease compare', i, a, b)
141       if (a === undefined && b === undefined) {
142         return 0
143       } else if (b === undefined) {
144         return 1
145       } else if (a === undefined) {
146         return -1
147       } else if (a === b) {
148         continue
149       } else {
150         return compareIdentifiers(a, b)
151       }
152     } while (++i)
153   }
154
155   compareBuild (other) {
156     if (!(other instanceof SemVer)) {
157       other = new SemVer(other, this.options)
158     }
159
160     let i = 0
161     do {
162       const a = this.build[i]
163       const b = other.build[i]
164       debug('prerelease compare', i, a, b)
165       if (a === undefined && b === undefined) {
166         return 0
167       } else if (b === undefined) {
168         return 1
169       } else if (a === undefined) {
170         return -1
171       } else if (a === b) {
172         continue
173       } else {
174         return compareIdentifiers(a, b)
175       }
176     } while (++i)
177   }
178
179   // preminor will bump the version up to the next minor release, and immediately
180   // down to pre-release. premajor and prepatch work the same way.
181   inc (release, identifier) {
182     switch (release) {
183       case 'premajor':
184         this.prerelease.length = 0
185         this.patch = 0
186         this.minor = 0
187         this.major++
188         this.inc('pre', identifier)
189         break
190       case 'preminor':
191         this.prerelease.length = 0
192         this.patch = 0
193         this.minor++
194         this.inc('pre', identifier)
195         break
196       case 'prepatch':
197         // If this is already a prerelease, it will bump to the next version
198         // drop any prereleases that might already exist, since they are not
199         // relevant at this point.
200         this.prerelease.length = 0
201         this.inc('patch', identifier)
202         this.inc('pre', identifier)
203         break
204       // If the input is a non-prerelease version, this acts the same as
205       // prepatch.
206       case 'prerelease':
207         if (this.prerelease.length === 0) {
208           this.inc('patch', identifier)
209         }
210         this.inc('pre', identifier)
211         break
212
213       case 'major':
214         // If this is a pre-major version, bump up to the same major version.
215         // Otherwise increment major.
216         // 1.0.0-5 bumps to 1.0.0
217         // 1.1.0 bumps to 2.0.0
218         if (
219           this.minor !== 0 ||
220           this.patch !== 0 ||
221           this.prerelease.length === 0
222         ) {
223           this.major++
224         }
225         this.minor = 0
226         this.patch = 0
227         this.prerelease = []
228         break
229       case 'minor':
230         // If this is a pre-minor version, bump up to the same minor version.
231         // Otherwise increment minor.
232         // 1.2.0-5 bumps to 1.2.0
233         // 1.2.1 bumps to 1.3.0
234         if (this.patch !== 0 || this.prerelease.length === 0) {
235           this.minor++
236         }
237         this.patch = 0
238         this.prerelease = []
239         break
240       case 'patch':
241         // If this is not a pre-release version, it will increment the patch.
242         // If it is a pre-release it will bump up to the same patch version.
243         // 1.2.0-5 patches to 1.2.0
244         // 1.2.0 patches to 1.2.1
245         if (this.prerelease.length === 0) {
246           this.patch++
247         }
248         this.prerelease = []
249         break
250       // This probably shouldn't be used publicly.
251       // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
252       case 'pre':
253         if (this.prerelease.length === 0) {
254           this.prerelease = [0]
255         } else {
256           let i = this.prerelease.length
257           while (--i >= 0) {
258             if (typeof this.prerelease[i] === 'number') {
259               this.prerelease[i]++
260               i = -2
261             }
262           }
263           if (i === -1) {
264             // didn't increment anything
265             this.prerelease.push(0)
266           }
267         }
268         if (identifier) {
269           // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
270           // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
271           if (this.prerelease[0] === identifier) {
272             if (isNaN(this.prerelease[1])) {
273               this.prerelease = [identifier, 0]
274             }
275           } else {
276             this.prerelease = [identifier, 0]
277           }
278         }
279         break
280
281       default:
282         throw new Error(`invalid increment argument: ${release}`)
283     }
284     this.format()
285     this.raw = this.version
286     return this
287   }
288 }
289
290 module.exports = SemVer