path-to-regexp
Advanced tools
Comparing version 1.0.2 to 1.0.3
@@ -0,1 +1,15 @@ | ||
1.0.3 / 2015-01-17 | ||
================== | ||
* Optimised function runtime | ||
* Added `files` to `package.json` | ||
1.0.2 / 2014-12-17 | ||
================== | ||
* Use `Array.isArray` shim | ||
* Remove ES5 incompatible code | ||
* Fixed repository path | ||
* Added new readme badges | ||
1.0.1 / 2014-08-27 | ||
@@ -2,0 +16,0 @@ ================== |
190
index.js
var isArray = require('isarray'); | ||
/** | ||
* Expose `pathtoRegexp`. | ||
* Expose `pathToRegexp`. | ||
*/ | ||
module.exports = pathtoRegexp; | ||
module.exports = pathToRegexp; | ||
@@ -14,5 +14,4 @@ /** | ||
var PATH_REGEXP = new RegExp([ | ||
// Match already escaped characters that would otherwise incorrectly appear | ||
// in future matches. This allows the user to escape special characters that | ||
// shouldn't be transformed. | ||
// Match escaped characters that would otherwise appear in future matches. | ||
// This allows the user to escape special characters that won't transform. | ||
'(\\\\.)', | ||
@@ -25,3 +24,3 @@ // Match Express-style parameters and un-named parameters with a prefix | ||
'([\\/.])?(?:\\:(\\w+)(?:\\(((?:\\\\.|[^)])*)\\))?|\\(((?:\\\\.|[^)])*)\\))([+*?])?', | ||
// Match regexp special characters that should always be escaped. | ||
// Match regexp special characters that are always escaped. | ||
'([.+*?=^!:${}()[\\]|\\/])' | ||
@@ -49,67 +48,70 @@ ].join('|'), 'g'); | ||
re.keys = keys; | ||
return re; | ||
}; | ||
} | ||
/** | ||
* Normalize the given path string, returning a regular expression. | ||
* Get the flags for a regexp from the options. | ||
* | ||
* An empty array should be passed in, which will contain the placeholder key | ||
* names. For example `/user/:id` will then contain `["id"]`. | ||
* @param {Object} options | ||
* @return {String} | ||
*/ | ||
function flags (options) { | ||
return options.sensitive ? '' : 'i'; | ||
} | ||
/** | ||
* Pull out keys from a regexp. | ||
* | ||
* @param {(String|RegExp|Array)} path | ||
* @param {Array} keys | ||
* @param {Object} options | ||
* @param {RegExp} path | ||
* @param {Array} keys | ||
* @return {RegExp} | ||
*/ | ||
function pathtoRegexp (path, keys, options) { | ||
if (!isArray(keys)) { | ||
options = keys; | ||
keys = null; | ||
function regexpToRegexp (path, keys) { | ||
// Use a negative lookahead to match only capturing groups. | ||
var groups = path.source.match(/\((?!\?)/g); | ||
if (groups) { | ||
for (var i = 0; i < groups.length; i++) { | ||
keys.push({ | ||
name: i, | ||
delimiter: null, | ||
optional: false, | ||
repeat: false | ||
}); | ||
} | ||
} | ||
keys = keys || []; | ||
options = options || {}; | ||
return attachKeys(path, keys); | ||
} | ||
var strict = options.strict; | ||
var end = options.end !== false; | ||
var flags = options.sensitive ? '' : 'i'; | ||
var index = 0; | ||
/** | ||
* Transform an array into a regexp. | ||
* | ||
* @param {Array} path | ||
* @param {Array} keys | ||
* @param {Object} options | ||
* @return {RegExp} | ||
*/ | ||
function arrayToRegexp (path, keys, options) { | ||
var parts = []; | ||
if (path instanceof RegExp) { | ||
// Match all capturing groups of a regexp. | ||
var groups = path.source.match(/\((?!\?)/g); | ||
// Map all the matches to their numeric indexes and push into the keys. | ||
if (groups) { | ||
for (var i = 0; i < groups.length; i++) { | ||
keys.push({ | ||
name: i, | ||
delimiter: null, | ||
optional: false, | ||
repeat: false | ||
}); | ||
} | ||
} | ||
// Return the source back to the user. | ||
return attachKeys(path, keys); | ||
for (var i = 0; i < path.length; i++) { | ||
parts.push(pathToRegexp(path[i], keys, options).source); | ||
} | ||
// Map array parts into regexps and return their source. We also pass | ||
// the same keys and options instance into every generation to get | ||
// consistent matching groups before we join the sources together. | ||
if (isArray(path)) { | ||
var parts = []; | ||
var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options)); | ||
return attachKeys(regexp, keys); | ||
} | ||
for (var i = 0; i < path.length; i++) { | ||
parts.push(pathtoRegexp(path[i], keys, options).source); | ||
} | ||
// Generate a new regexp instance by joining all the parts together. | ||
return attachKeys(new RegExp('(?:' + parts.join('|') + ')', flags), keys); | ||
} | ||
/** | ||
* Replace the specific tags with regexp strings. | ||
* | ||
* @param {String} path | ||
* @param {Array} keys | ||
* @return {String} | ||
*/ | ||
function replacePath (path, keys) { | ||
var index = 0; | ||
// Alter the path string into a usable regexp. | ||
path = path.replace(PATH_REGEXP, function (match, escaped, prefix, key, capture, group, suffix, escape) { | ||
// Avoiding re-escaping escaped characters. | ||
function replace (_, escaped, prefix, key, capture, group, suffix, escape) { | ||
if (escaped) { | ||
@@ -119,3 +121,2 @@ return escaped; | ||
// Escape regexp special characters. | ||
if (escape) { | ||
@@ -135,11 +136,5 @@ return '\\' + escape; | ||
// Escape the prefix character. | ||
prefix = prefix ? '\\' + prefix : ''; | ||
// Match using the custom capturing group, or fallback to capturing | ||
// everything up to the next slash (or next period if the param was | ||
// prefixed with a period). | ||
prefix = prefix ? ('\\' + prefix) : ''; | ||
capture = escapeGroup(capture || group || '[^' + (prefix || '\\/') + ']+?'); | ||
// Allow parameters to be repeated more than once. | ||
if (repeat) { | ||
@@ -149,3 +144,2 @@ capture = capture + '(?:' + prefix + capture + ')*'; | ||
// Allow a parameter to be optional. | ||
if (optional) { | ||
@@ -157,23 +151,59 @@ return '(?:' + prefix + '(' + capture + '))?'; | ||
return prefix + '(' + capture + ')'; | ||
}); | ||
} | ||
// Check whether the path ends in a slash as it alters some match behaviour. | ||
var endsWithSlash = path[path.length - 1] === '/'; | ||
return path.replace(PATH_REGEXP, replace); | ||
} | ||
// In non-strict mode we allow an optional trailing slash in the match. If | ||
// the path to match already ended with a slash, we need to remove it for | ||
// consistency. The slash is only valid at the very end of a path match, not | ||
// anywhere in the middle. This is important for non-ending mode, otherwise | ||
// "/test/" will match "/test//route". | ||
/** | ||
* Normalize the given path string, returning a regular expression. | ||
* | ||
* An empty array can be passed in for the keys, which will hold the | ||
* placeholder key descriptions. For example, using `/user/:id`, `keys` will | ||
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`. | ||
* | ||
* @param {(String|RegExp|Array)} path | ||
* @param {Array} [keys] | ||
* @param {Object} [options] | ||
* @return {RegExp} | ||
*/ | ||
function pathToRegexp (path, keys, options) { | ||
keys = keys || []; | ||
if (!isArray(keys)) { | ||
options = keys; | ||
keys = []; | ||
} else if (!options) { | ||
options = {}; | ||
} | ||
if (path instanceof RegExp) { | ||
return regexpToRegexp(path, keys, options); | ||
} | ||
if (isArray(path)) { | ||
return arrayToRegexp(path, keys, options); | ||
} | ||
var strict = options.strict; | ||
var end = options.end !== false; | ||
var route = replacePath(path, keys); | ||
var endsWithSlash = path.charAt(path.length - 1) === '/'; | ||
// In non-strict mode we allow a slash at the end of match. If the path to | ||
// match already ends with a slash, we remove it for consistency. The slash | ||
// is valid at the end of a path match, not in the middle. This is important | ||
// in non-ending mode, where "/test/" shouldn't match "/test//route". | ||
if (!strict) { | ||
path = (endsWithSlash ? path.slice(0, -2) : path) + '(?:\\/(?=$))?'; | ||
route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?'; | ||
} | ||
// In non-ending mode, we need prompt the capturing groups to match as much | ||
// as possible by using a positive lookahead for the end or next path segment. | ||
if (!end) { | ||
path += strict && endsWithSlash ? '' : '(?=\\/|$)'; | ||
if (end) { | ||
route += '$'; | ||
} else { | ||
// In non-ending mode, we need the capturing groups to match as much as | ||
// possible by using a positive lookahead to the end or next path segment. | ||
route += strict && endsWithSlash ? '' : '(?=\\/|$)'; | ||
} | ||
return attachKeys(new RegExp('^' + path + (end ? '$' : ''), flags), keys); | ||
}; | ||
return attachKeys(new RegExp('^' + route, flags(options)), keys); | ||
} |
{ | ||
"name": "path-to-regexp", | ||
"description": "Express style path to RegExp utility", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"files": [ | ||
"index.js", | ||
"LICENSE" | ||
], | ||
"scripts": { | ||
@@ -6,0 +10,0 @@ "test": "istanbul cover node_modules/mocha/bin/_mocha -- -R spec" |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13739
5
173
1