WIP - add extractor, generate snippet_data
This commit is contained in:
393
node_modules/fbjs/lib/VersionRange.js.flow
generated
vendored
Normal file
393
node_modules/fbjs/lib/VersionRange.js.flow
generated
vendored
Normal file
@ -0,0 +1,393 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule VersionRange
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const invariant = require("./invariant");
|
||||
|
||||
const componentRegex = /\./;
|
||||
const orRegex = /\|\|/;
|
||||
const rangeRegex = /\s+\-\s+/;
|
||||
const modifierRegex = /^(<=|<|=|>=|~>|~|>|)?\s*(.+)/;
|
||||
const numericRegex = /^(\d*)(.*)/;
|
||||
/**
|
||||
* Splits input `range` on "||" and returns true if any subrange matches
|
||||
* `version`.
|
||||
*
|
||||
* @param {string} range
|
||||
* @param {string} version
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
function checkOrExpression(range, version) {
|
||||
const expressions = range.split(orRegex);
|
||||
|
||||
if (expressions.length > 1) {
|
||||
return expressions.some(range => VersionRange.contains(range, version));
|
||||
} else {
|
||||
range = expressions[0].trim();
|
||||
return checkRangeExpression(range, version);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Splits input `range` on " - " (the surrounding whitespace is required) and
|
||||
* returns true if version falls between the two operands.
|
||||
*
|
||||
* @param {string} range
|
||||
* @param {string} version
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function checkRangeExpression(range, version) {
|
||||
const expressions = range.split(rangeRegex);
|
||||
invariant(expressions.length > 0 && expressions.length <= 2, 'the "-" operator expects exactly 2 operands');
|
||||
|
||||
if (expressions.length === 1) {
|
||||
return checkSimpleExpression(expressions[0], version);
|
||||
} else {
|
||||
const [startVersion, endVersion] = expressions;
|
||||
invariant(isSimpleVersion(startVersion) && isSimpleVersion(endVersion), 'operands to the "-" operator must be simple (no modifiers)');
|
||||
return checkSimpleExpression('>=' + startVersion, version) && checkSimpleExpression('<=' + endVersion, version);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks if `range` matches `version`. `range` should be a "simple" range (ie.
|
||||
* not a compound range using the " - " or "||" operators).
|
||||
*
|
||||
* @param {string} range
|
||||
* @param {string} version
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function checkSimpleExpression(range, version) {
|
||||
range = range.trim();
|
||||
|
||||
if (range === '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
const versionComponents = version.split(componentRegex);
|
||||
const {
|
||||
modifier,
|
||||
rangeComponents
|
||||
} = getModifierAndComponents(range);
|
||||
|
||||
switch (modifier) {
|
||||
case '<':
|
||||
return checkLessThan(versionComponents, rangeComponents);
|
||||
|
||||
case '<=':
|
||||
return checkLessThanOrEqual(versionComponents, rangeComponents);
|
||||
|
||||
case '>=':
|
||||
return checkGreaterThanOrEqual(versionComponents, rangeComponents);
|
||||
|
||||
case '>':
|
||||
return checkGreaterThan(versionComponents, rangeComponents);
|
||||
|
||||
case '~':
|
||||
case '~>':
|
||||
return checkApproximateVersion(versionComponents, rangeComponents);
|
||||
|
||||
default:
|
||||
return checkEqual(versionComponents, rangeComponents);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks whether `a` is less than `b`.
|
||||
*
|
||||
* @param {array<string>} a
|
||||
* @param {array<string>} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function checkLessThan(a, b) {
|
||||
return compareComponents(a, b) === -1;
|
||||
}
|
||||
/**
|
||||
* Checks whether `a` is less than or equal to `b`.
|
||||
*
|
||||
* @param {array<string>} a
|
||||
* @param {array<string>} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function checkLessThanOrEqual(a, b) {
|
||||
const result = compareComponents(a, b);
|
||||
return result === -1 || result === 0;
|
||||
}
|
||||
/**
|
||||
* Checks whether `a` is equal to `b`.
|
||||
*
|
||||
* @param {array<string>} a
|
||||
* @param {array<string>} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function checkEqual(a, b) {
|
||||
return compareComponents(a, b) === 0;
|
||||
}
|
||||
/**
|
||||
* Checks whether `a` is greater than or equal to `b`.
|
||||
*
|
||||
* @param {array<string>} a
|
||||
* @param {array<string>} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function checkGreaterThanOrEqual(a, b) {
|
||||
const result = compareComponents(a, b);
|
||||
return result === 1 || result === 0;
|
||||
}
|
||||
/**
|
||||
* Checks whether `a` is greater than `b`.
|
||||
*
|
||||
* @param {array<string>} a
|
||||
* @param {array<string>} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function checkGreaterThan(a, b) {
|
||||
return compareComponents(a, b) === 1;
|
||||
}
|
||||
/**
|
||||
* Checks whether `a` is "reasonably close" to `b` (as described in
|
||||
* https://www.npmjs.org/doc/misc/semver.html). For example, if `b` is "1.3.1"
|
||||
* then "reasonably close" is defined as ">= 1.3.1 and < 1.4".
|
||||
*
|
||||
* @param {array<string>} a
|
||||
* @param {array<string>} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function checkApproximateVersion(a, b) {
|
||||
const lowerBound = b.slice();
|
||||
const upperBound = b.slice();
|
||||
|
||||
if (upperBound.length > 1) {
|
||||
upperBound.pop();
|
||||
}
|
||||
|
||||
const lastIndex = upperBound.length - 1;
|
||||
const numeric = parseInt(upperBound[lastIndex], 10);
|
||||
|
||||
if (isNumber(numeric)) {
|
||||
upperBound[lastIndex] = numeric + 1 + '';
|
||||
}
|
||||
|
||||
return checkGreaterThanOrEqual(a, lowerBound) && checkLessThan(a, upperBound);
|
||||
}
|
||||
/**
|
||||
* Extracts the optional modifier (<, <=, =, >=, >, ~, ~>) and version
|
||||
* components from `range`.
|
||||
*
|
||||
* For example, given `range` ">= 1.2.3" returns an object with a `modifier` of
|
||||
* `">="` and `components` of `[1, 2, 3]`.
|
||||
*
|
||||
* @param {string} range
|
||||
* @returns {object}
|
||||
*/
|
||||
|
||||
|
||||
function getModifierAndComponents(range) {
|
||||
const rangeComponents = range.split(componentRegex);
|
||||
const matches = rangeComponents[0].match(modifierRegex);
|
||||
invariant(matches, 'expected regex to match but it did not');
|
||||
return {
|
||||
modifier: matches[1],
|
||||
rangeComponents: [matches[2]].concat(rangeComponents.slice(1))
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Determines if `number` is a number.
|
||||
*
|
||||
* @param {mixed} number
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function isNumber(number) {
|
||||
return !isNaN(number) && isFinite(number);
|
||||
}
|
||||
/**
|
||||
* Tests whether `range` is a "simple" version number without any modifiers
|
||||
* (">", "~" etc).
|
||||
*
|
||||
* @param {string} range
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
|
||||
function isSimpleVersion(range) {
|
||||
return !getModifierAndComponents(range).modifier;
|
||||
}
|
||||
/**
|
||||
* Zero-pads array `array` until it is at least `length` long.
|
||||
*
|
||||
* @param {array} array
|
||||
* @param {number} length
|
||||
*/
|
||||
|
||||
|
||||
function zeroPad(array, length) {
|
||||
for (let i = array.length; i < length; i++) {
|
||||
array[i] = '0';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Normalizes `a` and `b` in preparation for comparison by doing the following:
|
||||
*
|
||||
* - zero-pads `a` and `b`
|
||||
* - marks any "x", "X" or "*" component in `b` as equivalent by zero-ing it out
|
||||
* in both `a` and `b`
|
||||
* - marks any final "*" component in `b` as a greedy wildcard by zero-ing it
|
||||
* and all of its successors in `a`
|
||||
*
|
||||
* @param {array<string>} a
|
||||
* @param {array<string>} b
|
||||
* @returns {array<array<string>>}
|
||||
*/
|
||||
|
||||
|
||||
function normalizeVersions(a, b) {
|
||||
a = a.slice();
|
||||
b = b.slice();
|
||||
zeroPad(a, b.length); // mark "x" and "*" components as equal
|
||||
|
||||
for (let i = 0; i < b.length; i++) {
|
||||
const matches = b[i].match(/^[x*]$/i);
|
||||
|
||||
if (matches) {
|
||||
b[i] = a[i] = '0'; // final "*" greedily zeros all remaining components
|
||||
|
||||
if (matches[0] === '*' && i === b.length - 1) {
|
||||
for (let j = i; j < a.length; j++) {
|
||||
a[j] = '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zeroPad(b, a.length);
|
||||
return [a, b];
|
||||
}
|
||||
/**
|
||||
* Returns the numerical -- not the lexicographical -- ordering of `a` and `b`.
|
||||
*
|
||||
* For example, `10-alpha` is greater than `2-beta`.
|
||||
*
|
||||
* @param {string} a
|
||||
* @param {string} b
|
||||
* @returns {number} -1, 0 or 1 to indicate whether `a` is less than, equal to,
|
||||
* or greater than `b`, respectively
|
||||
*/
|
||||
|
||||
|
||||
function compareNumeric(a, b) {
|
||||
const aPrefix = a.match(numericRegex)[1];
|
||||
const bPrefix = b.match(numericRegex)[1];
|
||||
const aNumeric = parseInt(aPrefix, 10);
|
||||
const bNumeric = parseInt(bPrefix, 10);
|
||||
|
||||
if (isNumber(aNumeric) && isNumber(bNumeric) && aNumeric !== bNumeric) {
|
||||
return compare(aNumeric, bNumeric);
|
||||
} else {
|
||||
return compare(a, b);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the ordering of `a` and `b`.
|
||||
*
|
||||
* @param {string|number} a
|
||||
* @param {string|number} b
|
||||
* @returns {number} -1, 0 or 1 to indicate whether `a` is less than, equal to,
|
||||
* or greater than `b`, respectively
|
||||
*/
|
||||
|
||||
|
||||
function compare(a, b) {
|
||||
invariant(typeof a === typeof b, '"a" and "b" must be of the same type');
|
||||
|
||||
if (a > b) {
|
||||
return 1;
|
||||
} else if (a < b) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Compares arrays of version components.
|
||||
*
|
||||
* @param {array<string>} a
|
||||
* @param {array<string>} b
|
||||
* @returns {number} -1, 0 or 1 to indicate whether `a` is less than, equal to,
|
||||
* or greater than `b`, respectively
|
||||
*/
|
||||
|
||||
|
||||
function compareComponents(a, b) {
|
||||
const [aNormalized, bNormalized] = normalizeVersions(a, b);
|
||||
|
||||
for (let i = 0; i < bNormalized.length; i++) {
|
||||
const result = compareNumeric(aNormalized[i], bNormalized[i]);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
var VersionRange = {
|
||||
/**
|
||||
* Checks whether `version` satisfies the `range` specification.
|
||||
*
|
||||
* We support a subset of the expressions defined in
|
||||
* https://www.npmjs.org/doc/misc/semver.html:
|
||||
*
|
||||
* version Must match version exactly
|
||||
* =version Same as just version
|
||||
* >version Must be greater than version
|
||||
* >=version Must be greater than or equal to version
|
||||
* <version Must be less than version
|
||||
* <=version Must be less than or equal to version
|
||||
* ~version Must be at least version, but less than the next significant
|
||||
* revision above version:
|
||||
* "~1.2.3" is equivalent to ">= 1.2.3 and < 1.3"
|
||||
* ~>version Equivalent to ~version
|
||||
* 1.2.x Must match "1.2.x", where "x" is a wildcard that matches
|
||||
* anything
|
||||
* 1.2.* Similar to "1.2.x", but "*" in the trailing position is a
|
||||
* "greedy" wildcard, so will match any number of additional
|
||||
* components:
|
||||
* "1.2.*" will match "1.2.1", "1.2.1.1", "1.2.1.1.1" etc
|
||||
* * Any version
|
||||
* "" (Empty string) Same as *
|
||||
* v1 - v2 Equivalent to ">= v1 and <= v2"
|
||||
* r1 || r2 Passes if either r1 or r2 are satisfied
|
||||
*
|
||||
* @param {string} range
|
||||
* @param {string} version
|
||||
* @returns {boolean}
|
||||
*/
|
||||
contains(range, version) {
|
||||
return checkOrExpression(range.trim(), version.trim());
|
||||
}
|
||||
|
||||
};
|
||||
module.exports = VersionRange;
|
||||
Reference in New Issue
Block a user