Actualizacion maquina principal
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / semver / classes / range.js
1 // hoisted class for cyclic dependency
2 class Range {
3   constructor (range, options) {
4     if (!options || typeof options !== 'object') {
5       options = {
6         loose: !!options,
7         includePrerelease: false
8       }
9     }
10
11     if (range instanceof Range) {
12       if (
13         range.loose === !!options.loose &&
14         range.includePrerelease === !!options.includePrerelease
15       ) {
16         return range
17       } else {
18         return new Range(range.raw, options)
19       }
20     }
21
22     if (range instanceof Comparator) {
23       // just put it in the set and return
24       this.raw = range.value
25       this.set = [[range]]
26       this.format()
27       return this
28     }
29
30     this.options = options
31     this.loose = !!options.loose
32     this.includePrerelease = !!options.includePrerelease
33
34     // First, split based on boolean or ||
35     this.raw = range
36     this.set = range
37       .split(/\s*\|\|\s*/)
38       // map the range to a 2d array of comparators
39       .map(range => this.parseRange(range.trim()))
40       // throw out any comparator lists that are empty
41       // this generally means that it was not a valid range, which is allowed
42       // in loose mode, but will still throw if the WHOLE range is invalid.
43       .filter(c => c.length)
44
45     if (!this.set.length) {
46       throw new TypeError(`Invalid SemVer Range: ${range}`)
47     }
48
49     this.format()
50   }
51
52   format () {
53     this.range = this.set
54       .map((comps) => {
55         return comps.join(' ').trim()
56       })
57       .join('||')
58       .trim()
59     return this.range
60   }
61
62   toString () {
63     return this.range
64   }
65
66   parseRange (range) {
67     const loose = this.options.loose
68     range = range.trim()
69     // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
70     const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]
71     range = range.replace(hr, hyphenReplace(this.options.includePrerelease))
72     debug('hyphen replace', range)
73     // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
74     range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace)
75     debug('comparator trim', range, re[t.COMPARATORTRIM])
76
77     // `~ 1.2.3` => `~1.2.3`
78     range = range.replace(re[t.TILDETRIM], tildeTrimReplace)
79
80     // `^ 1.2.3` => `^1.2.3`
81     range = range.replace(re[t.CARETTRIM], caretTrimReplace)
82
83     // normalize spaces
84     range = range.split(/\s+/).join(' ')
85
86     // At this point, the range is completely trimmed and
87     // ready to be split into comparators.
88
89     const compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
90     return range
91       .split(' ')
92       .map(comp => parseComparator(comp, this.options))
93       .join(' ')
94       .split(/\s+/)
95       .map(comp => replaceGTE0(comp, this.options))
96       // in loose mode, throw out any that are not valid comparators
97       .filter(this.options.loose ? comp => !!comp.match(compRe) : () => true)
98       .map(comp => new Comparator(comp, this.options))
99   }
100
101   intersects (range, options) {
102     if (!(range instanceof Range)) {
103       throw new TypeError('a Range is required')
104     }
105
106     return this.set.some((thisComparators) => {
107       return (
108         isSatisfiable(thisComparators, options) &&
109         range.set.some((rangeComparators) => {
110           return (
111             isSatisfiable(rangeComparators, options) &&
112             thisComparators.every((thisComparator) => {
113               return rangeComparators.every((rangeComparator) => {
114                 return thisComparator.intersects(rangeComparator, options)
115               })
116             })
117           )
118         })
119       )
120     })
121   }
122
123   // if ANY of the sets match ALL of its comparators, then pass
124   test (version) {
125     if (!version) {
126       return false
127     }
128
129     if (typeof version === 'string') {
130       try {
131         version = new SemVer(version, this.options)
132       } catch (er) {
133         return false
134       }
135     }
136
137     for (let i = 0; i < this.set.length; i++) {
138       if (testSet(this.set[i], version, this.options)) {
139         return true
140       }
141     }
142     return false
143   }
144 }
145 module.exports = Range
146
147 const Comparator = require('./comparator')
148 const debug = require('../internal/debug')
149 const SemVer = require('./semver')
150 const {
151   re,
152   t,
153   comparatorTrimReplace,
154   tildeTrimReplace,
155   caretTrimReplace
156 } = require('../internal/re')
157
158 // take a set of comparators and determine whether there
159 // exists a version which can satisfy it
160 const isSatisfiable = (comparators, options) => {
161   let result = true
162   const remainingComparators = comparators.slice()
163   let testComparator = remainingComparators.pop()
164
165   while (result && remainingComparators.length) {
166     result = remainingComparators.every((otherComparator) => {
167       return testComparator.intersects(otherComparator, options)
168     })
169
170     testComparator = remainingComparators.pop()
171   }
172
173   return result
174 }
175
176 // comprised of xranges, tildes, stars, and gtlt's at this point.
177 // already replaced the hyphen ranges
178 // turn into a set of JUST comparators.
179 const parseComparator = (comp, options) => {
180   debug('comp', comp, options)
181   comp = replaceCarets(comp, options)
182   debug('caret', comp)
183   comp = replaceTildes(comp, options)
184   debug('tildes', comp)
185   comp = replaceXRanges(comp, options)
186   debug('xrange', comp)
187   comp = replaceStars(comp, options)
188   debug('stars', comp)
189   return comp
190 }
191
192 const isX = id => !id || id.toLowerCase() === 'x' || id === '*'
193
194 // ~, ~> --> * (any, kinda silly)
195 // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0
196 // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0
197 // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0
198 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0
199 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0
200 const replaceTildes = (comp, options) =>
201   comp.trim().split(/\s+/).map((comp) => {
202     return replaceTilde(comp, options)
203   }).join(' ')
204
205 const replaceTilde = (comp, options) => {
206   const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]
207   return comp.replace(r, (_, M, m, p, pr) => {
208     debug('tilde', comp, _, M, m, p, pr)
209     let ret
210
211     if (isX(M)) {
212       ret = ''
213     } else if (isX(m)) {
214       ret = `>=${M}.0.0 <${+M + 1}.0.0-0`
215     } else if (isX(p)) {
216       // ~1.2 == >=1.2.0 <1.3.0-0
217       ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`
218     } else if (pr) {
219       debug('replaceTilde pr', pr)
220       ret = `>=${M}.${m}.${p}-${pr
221       } <${M}.${+m + 1}.0-0`
222     } else {
223       // ~1.2.3 == >=1.2.3 <1.3.0-0
224       ret = `>=${M}.${m}.${p
225       } <${M}.${+m + 1}.0-0`
226     }
227
228     debug('tilde return', ret)
229     return ret
230   })
231 }
232
233 // ^ --> * (any, kinda silly)
234 // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0
235 // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0
236 // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0
237 // ^1.2.3 --> >=1.2.3 <2.0.0-0
238 // ^1.2.0 --> >=1.2.0 <2.0.0-0
239 const replaceCarets = (comp, options) =>
240   comp.trim().split(/\s+/).map((comp) => {
241     return replaceCaret(comp, options)
242   }).join(' ')
243
244 const replaceCaret = (comp, options) => {
245   debug('caret', comp, options)
246   const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET]
247   const z = options.includePrerelease ? '-0' : ''
248   return comp.replace(r, (_, M, m, p, pr) => {
249     debug('caret', comp, _, M, m, p, pr)
250     let ret
251
252     if (isX(M)) {
253       ret = ''
254     } else if (isX(m)) {
255       ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`
256     } else if (isX(p)) {
257       if (M === '0') {
258         ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`
259       } else {
260         ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`
261       }
262     } else if (pr) {
263       debug('replaceCaret pr', pr)
264       if (M === '0') {
265         if (m === '0') {
266           ret = `>=${M}.${m}.${p}-${pr
267           } <${M}.${m}.${+p + 1}-0`
268         } else {
269           ret = `>=${M}.${m}.${p}-${pr
270           } <${M}.${+m + 1}.0-0`
271         }
272       } else {
273         ret = `>=${M}.${m}.${p}-${pr
274         } <${+M + 1}.0.0-0`
275       }
276     } else {
277       debug('no pr')
278       if (M === '0') {
279         if (m === '0') {
280           ret = `>=${M}.${m}.${p
281           }${z} <${M}.${m}.${+p + 1}-0`
282         } else {
283           ret = `>=${M}.${m}.${p
284           }${z} <${M}.${+m + 1}.0-0`
285         }
286       } else {
287         ret = `>=${M}.${m}.${p
288         } <${+M + 1}.0.0-0`
289       }
290     }
291
292     debug('caret return', ret)
293     return ret
294   })
295 }
296
297 const replaceXRanges = (comp, options) => {
298   debug('replaceXRanges', comp, options)
299   return comp.split(/\s+/).map((comp) => {
300     return replaceXRange(comp, options)
301   }).join(' ')
302 }
303
304 const replaceXRange = (comp, options) => {
305   comp = comp.trim()
306   const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE]
307   return comp.replace(r, (ret, gtlt, M, m, p, pr) => {
308     debug('xRange', comp, ret, gtlt, M, m, p, pr)
309     const xM = isX(M)
310     const xm = xM || isX(m)
311     const xp = xm || isX(p)
312     const anyX = xp
313
314     if (gtlt === '=' && anyX) {
315       gtlt = ''
316     }
317
318     // if we're including prereleases in the match, then we need
319     // to fix this to -0, the lowest possible prerelease value
320     pr = options.includePrerelease ? '-0' : ''
321
322     if (xM) {
323       if (gtlt === '>' || gtlt === '<') {
324         // nothing is allowed
325         ret = '<0.0.0-0'
326       } else {
327         // nothing is forbidden
328         ret = '*'
329       }
330     } else if (gtlt && anyX) {
331       // we know patch is an x, because we have any x at all.
332       // replace X with 0
333       if (xm) {
334         m = 0
335       }
336       p = 0
337
338       if (gtlt === '>') {
339         // >1 => >=2.0.0
340         // >1.2 => >=1.3.0
341         gtlt = '>='
342         if (xm) {
343           M = +M + 1
344           m = 0
345           p = 0
346         } else {
347           m = +m + 1
348           p = 0
349         }
350       } else if (gtlt === '<=') {
351         // <=0.7.x is actually <0.8.0, since any 0.7.x should
352         // pass.  Similarly, <=7.x is actually <8.0.0, etc.
353         gtlt = '<'
354         if (xm) {
355           M = +M + 1
356         } else {
357           m = +m + 1
358         }
359       }
360
361       if (gtlt === '<')
362         pr = '-0'
363
364       ret = `${gtlt + M}.${m}.${p}${pr}`
365     } else if (xm) {
366       ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`
367     } else if (xp) {
368       ret = `>=${M}.${m}.0${pr
369       } <${M}.${+m + 1}.0-0`
370     }
371
372     debug('xRange return', ret)
373
374     return ret
375   })
376 }
377
378 // Because * is AND-ed with everything else in the comparator,
379 // and '' means "any version", just remove the *s entirely.
380 const replaceStars = (comp, options) => {
381   debug('replaceStars', comp, options)
382   // Looseness is ignored here.  star is always as loose as it gets!
383   return comp.trim().replace(re[t.STAR], '')
384 }
385
386 const replaceGTE0 = (comp, options) => {
387   debug('replaceGTE0', comp, options)
388   return comp.trim()
389     .replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '')
390 }
391
392 // This function is passed to string.replace(re[t.HYPHENRANGE])
393 // M, m, patch, prerelease, build
394 // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
395 // 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do
396 // 1.2 - 3.4 => >=1.2.0 <3.5.0-0
397 const hyphenReplace = incPr => ($0,
398   from, fM, fm, fp, fpr, fb,
399   to, tM, tm, tp, tpr, tb) => {
400   if (isX(fM)) {
401     from = ''
402   } else if (isX(fm)) {
403     from = `>=${fM}.0.0${incPr ? '-0' : ''}`
404   } else if (isX(fp)) {
405     from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}`
406   } else if (fpr) {
407     from = `>=${from}`
408   } else {
409     from = `>=${from}${incPr ? '-0' : ''}`
410   }
411
412   if (isX(tM)) {
413     to = ''
414   } else if (isX(tm)) {
415     to = `<${+tM + 1}.0.0-0`
416   } else if (isX(tp)) {
417     to = `<${tM}.${+tm + 1}.0-0`
418   } else if (tpr) {
419     to = `<=${tM}.${tm}.${tp}-${tpr}`
420   } else if (incPr) {
421     to = `<${tM}.${tm}.${+tp + 1}-0`
422   } else {
423     to = `<=${to}`
424   }
425
426   return (`${from} ${to}`).trim()
427 }
428
429 const testSet = (set, version, options) => {
430   for (let i = 0; i < set.length; i++) {
431     if (!set[i].test(version)) {
432       return false
433     }
434   }
435
436   if (version.prerelease.length && !options.includePrerelease) {
437     // Find the set of versions that are allowed to have prereleases
438     // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
439     // That should allow `1.2.3-pr.2` to pass.
440     // However, `1.2.4-alpha.notready` should NOT be allowed,
441     // even though it's within the range set by the comparators.
442     for (let i = 0; i < set.length; i++) {
443       debug(set[i].semver)
444       if (set[i].semver === Comparator.ANY) {
445         continue
446       }
447
448       if (set[i].semver.prerelease.length > 0) {
449         const allowed = set[i].semver
450         if (allowed.major === version.major &&
451             allowed.minor === version.minor &&
452             allowed.patch === version.patch) {
453           return true
454         }
455       }
456     }
457
458     // Version has a -pre, but it's not one of the ones we like.
459     return false
460   }
461
462   return true
463 }