167 lines
5.3 KiB
Plaintext
167 lines
5.3 KiB
Plaintext
'use strict';
|
|
|
|
/**
|
|
* Escapes a character if it has a special meaning in regular expressions
|
|
* and returns the character as is if it doesn't
|
|
*/
|
|
function escapeRegExpChar(char) {
|
|
if (char === '-' ||
|
|
char === '^' ||
|
|
char === '$' ||
|
|
char === '+' ||
|
|
char === '.' ||
|
|
char === '(' ||
|
|
char === ')' ||
|
|
char === '|' ||
|
|
char === '[' ||
|
|
char === ']' ||
|
|
char === '{' ||
|
|
char === '}' ||
|
|
char === '*' ||
|
|
char === '?' ||
|
|
char === '\\') {
|
|
return "\\" + char;
|
|
}
|
|
else {
|
|
return char;
|
|
}
|
|
}
|
|
/**
|
|
* Escapes all characters in a given string that have a special meaning in regular expressions
|
|
*/
|
|
function escapeRegExpString(str) {
|
|
var result = '';
|
|
for (var i = 0; i < str.length; i++) {
|
|
result += escapeRegExpChar(str[i]);
|
|
}
|
|
return result;
|
|
}
|
|
/**
|
|
* Transforms one or more glob patterns into a RegExp pattern
|
|
*/
|
|
function transform(pattern, separator) {
|
|
if (separator === void 0) { separator = true; }
|
|
if (Array.isArray(pattern)) {
|
|
var regExpPatterns = pattern.map(function (p) { return "^" + transform(p, separator) + "$"; });
|
|
return "(?:" + regExpPatterns.join('|') + ")";
|
|
}
|
|
var separatorSplitter = '';
|
|
var separatorMatcher = '';
|
|
var wildcard = '.';
|
|
if (separator === true) {
|
|
separatorSplitter = '/';
|
|
separatorMatcher = '[/\\\\]';
|
|
wildcard = '[^/\\\\]';
|
|
}
|
|
else if (separator) {
|
|
separatorSplitter = separator;
|
|
separatorMatcher = escapeRegExpString(separatorSplitter);
|
|
if (separatorMatcher.length > 1) {
|
|
separatorMatcher = "(?:" + separatorMatcher + ")";
|
|
wildcard = "((?!" + separatorMatcher + ").)";
|
|
}
|
|
else {
|
|
wildcard = "[^" + separatorMatcher + "]";
|
|
}
|
|
}
|
|
var requiredSeparator = separator ? separatorMatcher + "+?" : '';
|
|
var optionalSeparator = separator ? separatorMatcher + "*?" : '';
|
|
var segments = separator ? pattern.split(separatorSplitter) : [pattern];
|
|
var result = '';
|
|
for (var s = 0; s < segments.length; s++) {
|
|
var segment = segments[s];
|
|
var nextSegment = segments[s + 1];
|
|
var currentSeparator = '';
|
|
if (!segment && s > 0) {
|
|
continue;
|
|
}
|
|
if (separator) {
|
|
if (s === segments.length - 1) {
|
|
currentSeparator = optionalSeparator;
|
|
}
|
|
else if (nextSegment !== '**') {
|
|
currentSeparator = requiredSeparator;
|
|
}
|
|
else {
|
|
currentSeparator = '';
|
|
}
|
|
}
|
|
if (separator && segment === '**') {
|
|
if (currentSeparator) {
|
|
result += s === 0 ? '' : currentSeparator;
|
|
result += "(?:" + wildcard + "*?" + currentSeparator + ")*?";
|
|
}
|
|
continue;
|
|
}
|
|
for (var c = 0; c < segment.length; c++) {
|
|
var char = segment[c];
|
|
if (char === '\\') {
|
|
if (c < segment.length - 1) {
|
|
result += escapeRegExpChar(segment[c + 1]);
|
|
c++;
|
|
}
|
|
}
|
|
else if (char === '?') {
|
|
result += wildcard;
|
|
}
|
|
else if (char === '*') {
|
|
result += wildcard + "*?";
|
|
}
|
|
else {
|
|
result += escapeRegExpChar(char);
|
|
}
|
|
}
|
|
result += currentSeparator;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function isMatch(regexp, sample) {
|
|
if (typeof sample !== 'string') {
|
|
throw new TypeError("Sample must be a string, but " + typeof sample + " given");
|
|
}
|
|
return regexp.test(sample);
|
|
}
|
|
/**
|
|
* Compiles one or more glob patterns into a RegExp and returns an isMatch function.
|
|
* The isMatch function takes a sample string as its only argument and returns `true`
|
|
* if the string matches the pattern(s).
|
|
*
|
|
* ```js
|
|
* wildcardMatch('src/*.js')('src/index.js') //=> true
|
|
* ```
|
|
*
|
|
* ```js
|
|
* const isMatch = wildcardMatch('*.example.com', '.')
|
|
* isMatch('foo.example.com') //=> true
|
|
* isMatch('foo.bar.com') //=> false
|
|
* ```
|
|
*/
|
|
function wildcardMatch(pattern, options) {
|
|
if (typeof pattern !== 'string' && !Array.isArray(pattern)) {
|
|
throw new TypeError("The first argument must be a single pattern string or an array of patterns, but " + typeof pattern + " given");
|
|
}
|
|
if (typeof options === 'string' || typeof options === 'boolean') {
|
|
options = { separator: options };
|
|
}
|
|
if (arguments.length === 2 &&
|
|
!(typeof options === 'undefined' ||
|
|
(typeof options === 'object' && options !== null && !Array.isArray(options)))) {
|
|
throw new TypeError("The second argument must be an options object or a string/boolean separator, but " + typeof options + " given");
|
|
}
|
|
options = options || {};
|
|
if (options.separator === '\\') {
|
|
throw new Error('\\ is not a valid separator because it is used for escaping. Try setting the separator to `true` instead');
|
|
}
|
|
var regexpPattern = transform(pattern, options.separator);
|
|
var regexp = new RegExp("^" + regexpPattern + "$", options.flags);
|
|
var fn = isMatch.bind(null, regexp);
|
|
fn.options = options;
|
|
fn.pattern = pattern;
|
|
fn.regexp = regexp;
|
|
return fn;
|
|
}
|
|
|
|
module.exports = wildcardMatch;
|
|
//# sourceMappingURL=index.js.map
|