diff options
Diffstat (limited to 'node_modules/to-regex/index.js')
-rw-r--r-- | node_modules/to-regex/index.js | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/node_modules/to-regex/index.js b/node_modules/to-regex/index.js new file mode 100644 index 0000000..a87d015 --- /dev/null +++ b/node_modules/to-regex/index.js @@ -0,0 +1,155 @@ +'use strict'; + +var safe = require('safe-regex'); +var define = require('define-property'); +var extend = require('extend-shallow'); +var not = require('regex-not'); +var MAX_LENGTH = 1024 * 64; + +/** + * Session cache + */ + +var cache = {}; + +/** + * Create a regular expression from the given `pattern` string. + * + * @param {String|RegExp} `pattern` Pattern can be a string or regular expression. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ + +module.exports = function(patterns, options) { + if (!Array.isArray(patterns)) { + return makeRe(patterns, options); + } + return makeRe(patterns.join('|'), options); +}; + +/** + * Create a regular expression from the given `pattern` string. + * + * @param {String|RegExp} `pattern` Pattern can be a string or regular expression. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ + +function makeRe(pattern, options) { + if (pattern instanceof RegExp) { + return pattern; + } + + if (typeof pattern !== 'string') { + throw new TypeError('expected a string'); + } + + if (pattern.length > MAX_LENGTH) { + throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); + } + + var key = pattern; + // do this before shallow cloning options, it's a lot faster + if (!options || (options && options.cache !== false)) { + key = createKey(pattern, options); + + if (cache.hasOwnProperty(key)) { + return cache[key]; + } + } + + var opts = extend({}, options); + if (opts.contains === true) { + if (opts.negate === true) { + opts.strictNegate = false; + } else { + opts.strict = false; + } + } + + if (opts.strict === false) { + opts.strictOpen = false; + opts.strictClose = false; + } + + var open = opts.strictOpen !== false ? '^' : ''; + var close = opts.strictClose !== false ? '$' : ''; + var flags = opts.flags || ''; + var regex; + + if (opts.nocase === true && !/i/.test(flags)) { + flags += 'i'; + } + + try { + if (opts.negate || typeof opts.strictNegate === 'boolean') { + pattern = not.create(pattern, opts); + } + + var str = open + '(?:' + pattern + ')' + close; + regex = new RegExp(str, flags); + + if (opts.safe === true && safe(regex) === false) { + throw new Error('potentially unsafe regular expression: ' + regex.source); + } + + } catch (err) { + if (opts.strictErrors === true || opts.safe === true) { + err.key = key; + err.pattern = pattern; + err.originalOptions = options; + err.createdOptions = opts; + throw err; + } + + try { + regex = new RegExp('^' + pattern.replace(/(\W)/g, '\\$1') + '$'); + } catch (err) { + regex = /.^/; //<= match nothing + } + } + + if (opts.cache !== false) { + memoize(regex, key, pattern, opts); + } + return regex; +} + +/** + * Memoize generated regex. This can result in dramatic speed improvements + * and simplify debugging by adding options and pattern to the regex. It can be + * disabled by passing setting `options.cache` to false. + */ + +function memoize(regex, key, pattern, options) { + define(regex, 'cached', true); + define(regex, 'pattern', pattern); + define(regex, 'options', options); + define(regex, 'key', key); + cache[key] = regex; +} + +/** + * Create the key to use for memoization. The key is generated + * by iterating over the options and concatenating key-value pairs + * to the pattern string. + */ + +function createKey(pattern, options) { + if (!options) return pattern; + var key = pattern; + for (var prop in options) { + if (options.hasOwnProperty(prop)) { + key += ';' + prop + '=' + String(options[prop]); + } + } + return key; +} + +/** + * Expose `makeRe` + */ + +module.exports.makeRe = makeRe; |