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