Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

path-to-regexp

Package Overview
Dependencies
Maintainers
5
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

path-to-regexp - npm Package Compare versions

Comparing version 1.7.0 to 2.0.0

5

History.md

@@ -0,1 +1,6 @@

1.7.0 / 2016-11-08
==================
* Allow a `delimiter` option to be passed in with `tokensToRegExp` which will be used for "non-ending" token match situations
1.6.0 / 2016-10-03

@@ -2,0 +7,0 @@ ==================

25

index.d.ts

@@ -1,10 +0,4 @@

declare function pathToRegexp (path: pathToRegexp.Path, options?: pathToRegexp.RegExpOptions & pathToRegexp.ParseOptions): pathToRegexp.PathRegExp;
declare function pathToRegexp (path: pathToRegexp.Path, keys?: pathToRegexp.Key[], options?: pathToRegexp.RegExpOptions & pathToRegexp.ParseOptions): pathToRegexp.PathRegExp;
declare function pathToRegexp (path: pathToRegexp.Path, keys?: pathToRegexp.Key[], options?: pathToRegexp.RegExpOptions & pathToRegexp.ParseOptions): RegExp;
declare namespace pathToRegexp {
export interface PathRegExp extends RegExp {
// An array to be populated with the keys found in the path.
keys: Key[];
}
export interface RegExpOptions {

@@ -27,2 +21,6 @@ /**

delimiter?: string;
/**
* List of characters that can also be "end" characters.
*/
endsWith?: string | string[];
}

@@ -35,2 +33,6 @@

delimiter?: string;
/**
* List of valid delimiter characters. (default: `'./'`)
*/
delimiters?: string | string[];
}

@@ -56,4 +58,3 @@

*/
export function tokensToRegExp (tokens: Token[], options?: RegExpOptions): PathRegExp;
export function tokensToRegExp (tokens: Token[], keys?: Key[], options?: RegExpOptions): PathRegExp;
export function tokensToRegExp (tokens: Token[], keys?: Key[], options?: RegExpOptions): RegExp;

@@ -68,7 +69,9 @@ export interface Key {

partial: boolean;
asterisk: boolean;
}
interface PathFunctionOptions {
pretty?: boolean;
/**
* Function for encoding input strings for output.
*/
encode?: (value: string) => string;
}

@@ -75,0 +78,0 @@

@@ -1,3 +0,1 @@

var isarray = require('isarray')
/**

@@ -24,6 +22,5 @@ * Expose `pathToRegexp`.

//
// "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
// "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined]
// "/*" => ["/", undefined, undefined, undefined, undefined, "*"]
'([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))'
// "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?"]
// "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined]
'(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?'
].join('|'), 'g')

@@ -43,6 +40,8 @@

var path = ''
var defaultDelimiter = options && options.delimiter || '/'
var defaultDelimiter = (options && options.delimiter) || '/'
var delimiters = (options && options.delimiters) || './'
var pathEscaped = false
var res
while ((res = PATH_REGEXP.exec(str)) != null) {
while ((res = PATH_REGEXP.exec(str)) !== null) {
var m = res[0]

@@ -57,13 +56,22 @@ var escaped = res[1]

path += escaped[1]
pathEscaped = true
continue
}
var prev = ''
var next = str[index]
var prefix = res[2]
var name = res[3]
var capture = res[4]
var group = res[5]
var modifier = res[6]
var asterisk = res[7]
var name = res[2]
var capture = res[3]
var group = res[4]
var modifier = res[5]
if (!pathEscaped && path.length) {
var k = path.length - 1
if (delimiters.indexOf(path[k]) > -1) {
prev = path[k]
path = path.slice(0, k)
}
}
// Push the current path onto the tokens.

@@ -73,8 +81,9 @@ if (path) {

path = ''
pathEscaped = false
}
var partial = prefix != null && next != null && next !== prefix
var partial = prev !== '' && next !== undefined && next !== prev
var repeat = modifier === '+' || modifier === '*'
var optional = modifier === '?' || modifier === '*'
var delimiter = res[2] || defaultDelimiter
var delimiter = prev || defaultDelimiter
var pattern = capture || group

@@ -84,3 +93,3 @@

name: name || key++,
prefix: prefix || '',
prefix: prev,
delimiter: delimiter,

@@ -90,17 +99,11 @@ optional: optional,

partial: partial,
asterisk: !!asterisk,
pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')
pattern: pattern ? escapeGroup(pattern) : '[^' + escapeString(delimiter) + ']+?'
})
}
// Match any characters still remaining.
if (index < str.length) {
path += str.substr(index)
// Push any remaining characters.
if (path || index < str.length) {
tokens.push(path + str.substr(index))
}
// If the path exists, push it onto the end.
if (path) {
tokens.push(path)
}
return tokens

@@ -121,26 +124,2 @@ }

/**
* Prettier encoding of URI path segments.
*
* @param {string}
* @return {string}
*/
function encodeURIComponentPretty (str) {
return encodeURI(str).replace(/[\/?#]/g, function (c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
})
}
/**
* Encode the asterisk parameter. Similar to `pretty`, but allows slashes.
*
* @param {string}
* @return {string}
*/
function encodeAsterisk (str) {
return encodeURI(str).replace(/[?#]/g, function (c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
})
}
/**
* Expose a method for transforming tokens into the path function.

@@ -159,7 +138,5 @@ */

return function (obj, opts) {
return function (data, options) {
var path = ''
var data = obj || {}
var options = opts || {}
var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent
var encode = (options && options.encode) || encodeURIComponent

@@ -171,33 +148,17 @@ for (var i = 0; i < tokens.length; i++) {

path += token
continue
}
var value = data[token.name]
var value = data ? data[token.name] : undefined
var segment
if (value == null) {
if (token.optional) {
// Prepend partial segment prefixes.
if (token.partial) {
path += token.prefix
}
continue
} else {
throw new TypeError('Expected "' + token.name + '" to be defined')
}
}
if (isarray(value)) {
if (Array.isArray(value)) {
if (!token.repeat) {
throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`')
throw new TypeError('Expected "' + token.name + '" to not repeat, but got array')
}
if (value.length === 0) {
if (token.optional) {
continue
} else {
throw new TypeError('Expected "' + token.name + '" to not be empty')
}
if (token.optional) continue
throw new TypeError('Expected "' + token.name + '" to not be empty')
}

@@ -209,3 +170,3 @@

if (!matches[i].test(segment)) {
throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`')
throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '"')
}

@@ -219,9 +180,21 @@

segment = token.asterisk ? encodeAsterisk(value) : encode(value)
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
segment = encode(String(value))
if (!matches[i].test(segment)) {
throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
if (!matches[i].test(segment)) {
throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but got "' + segment + '"')
}
path += token.prefix + segment
continue
}
path += token.prefix + segment
if (token.optional) {
// Prepend partial segment prefixes.
if (token.partial) path += token.prefix
continue
}
throw new TypeError('Expected "' + token.name + '" to be ' + (token.repeat ? 'an array' : 'a string'))
}

@@ -240,3 +213,3 @@

function escapeString (str) {
return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1')
return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, '\\$1')
}

@@ -251,18 +224,6 @@

function escapeGroup (group) {
return group.replace(/([=!:$\/()])/g, '\\$1')
return group.replace(/([=!:$/()])/g, '\\$1')
}
/**
* Attach the keys as a property of the regexp.
*
* @param {!RegExp} re
* @param {Array} keys
* @return {!RegExp}
*/
function attachKeys (re, keys) {
re.keys = keys
return re
}
/**
* Get the flags for a regexp from the options.

@@ -274,3 +235,3 @@ *

function flags (options) {
return options.sensitive ? '' : 'i'
return options && options.sensitive ? '' : 'i'
}

@@ -282,6 +243,8 @@

* @param {!RegExp} path
* @param {!Array} keys
* @param {Array=} keys
* @return {!RegExp}
*/
function regexpToRegexp (path, keys) {
if (!keys) return path
// Use a negative lookahead to match only capturing groups.

@@ -299,3 +262,2 @@ var groups = path.source.match(/\((?!\?)/g)

partial: false,
asterisk: false,
pattern: null

@@ -306,3 +268,3 @@ })

return attachKeys(path, keys)
return path
}

@@ -314,4 +276,4 @@

* @param {!Array} path
* @param {Array} keys
* @param {!Object} options
* @param {Array=} keys
* @param {Object=} options
* @return {!RegExp}

@@ -326,5 +288,3 @@ */

var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
return attachKeys(regexp, keys)
return new RegExp('(?:' + parts.join('|') + ')', flags(options))
}

@@ -336,4 +296,4 @@

* @param {string} path
* @param {!Array} keys
* @param {!Object} options
* @param {Array=} keys
* @param {Object=} options
* @return {!RegExp}

@@ -348,13 +308,8 @@ */

*
* @param {!Array} tokens
* @param {(Array|Object)=} keys
* @param {Object=} options
* @param {!Array} tokens
* @param {Array=} keys
* @param {Object=} options
* @return {!RegExp}
*/
function tokensToRegExp (tokens, keys, options) {
if (!isarray(keys)) {
options = /** @type {!Object} */ (keys || options)
keys = []
}
options = options || {}

@@ -364,2 +319,4 @@

var end = options.end !== false
var delimiter = escapeString(options.delimiter || '/')
var endsWith = [].concat(options.endsWith || []).map(escapeString).concat('$').join('|')
var route = ''

@@ -377,3 +334,3 @@

keys.push(token)
if (keys) keys.push(token)

@@ -398,22 +355,16 @@ if (token.repeat) {

var delimiter = escapeString(options.delimiter || '/')
var endsWithDelimiter = route.slice(-delimiter.length) === delimiter
// 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".
// In non-strict mode we allow a delimiter at the end of a match.
if (!strict) {
route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?'
route += '(?:' + delimiter + '(?=' + endsWith + '))?'
}
if (end) {
route += '$'
route += endsWith === '$' ? endsWith : '(?=' + endsWith + ')'
} 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 && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)'
route += '(?=' + delimiter + '|' + endsWith + ')'
}
return attachKeys(new RegExp('^' + route, flags(options)), keys)
return new RegExp('^' + route, flags(options))
}

@@ -429,3 +380,3 @@

* @param {(string|RegExp|Array)} path
* @param {(Array|Object)=} keys
* @param {Array=} keys
* @param {Object=} options

@@ -435,18 +386,11 @@ * @return {!RegExp}

function pathToRegexp (path, keys, options) {
if (!isarray(keys)) {
options = /** @type {!Object} */ (keys || options)
keys = []
}
options = options || {}
if (path instanceof RegExp) {
return regexpToRegexp(path, /** @type {!Array} */ (keys))
return regexpToRegexp(path, keys)
}
if (isarray(path)) {
return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
if (Array.isArray(path)) {
return arrayToRegexp(/** @type {!Array} */ (path), keys, options)
}
return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
return stringToRegexp(/** @type {string} */ (path), keys, options)
}
{
"name": "path-to-regexp",
"description": "Express style path to RegExp utility",
"version": "1.7.0",
"version": "2.0.0",
"main": "index.js",

@@ -16,3 +16,2 @@ "typings": "index.d.ts",

"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require ts-node/register -R spec test.ts",
"prepublish": "typings install",
"test": "npm run lint && npm run test-cov"

@@ -37,13 +36,12 @@ },

"devDependencies": {
"chai": "^2.3.0",
"istanbul": "~0.3.0",
"mocha": "~2.2.4",
"standard": "~3.7.3",
"ts-node": "^0.5.5",
"typescript": "^1.8.7",
"typings": "^1.0.4"
},
"dependencies": {
"isarray": "0.0.1"
"@types/chai": "^4.0.4",
"@types/mocha": "^2.2.42",
"@types/node": "^8.0.24",
"chai": "^4.1.1",
"istanbul": "^0.4.5",
"mocha": "^3.5.0",
"standard": "^10.0.3",
"ts-node": "^3.3.0",
"typescript": "^2.4.2"
}
}
# Path-to-RegExp
> Turn an Express-style path string such as `/user/:name` into a regular expression.
> Turn a path string such as `/user/:name` into a regular expression.

@@ -23,3 +23,3 @@ [![NPM version][npm-image]][npm-url]

// pathToRegexp(path, keys, options)
// pathToRegexp(path, keys?, options?)
// pathToRegexp.parse(path)

@@ -29,3 +29,3 @@ // pathToRegexp.compile(path)

- **path** An Express-style string, an array of strings, or a regular expression.
- **path** A string, array of strings, or a regular expression.
- **keys** An array to be populated with the keys found in the path.

@@ -36,3 +36,6 @@ - **options**

- **end** When `false` the path will match at the beginning. (default: `true`)
- **delimiter** Set the default delimiter for repeat parameters. (default: `'/'`)
- Advanced options (use for non-pathname strings, e.g. host names):
- **delimiter** The default delimiter for segments. (default: `'/'`)
- **endsWith** Optional character, or list of characters, to treat as "end" characters.
- **delimiters** List of characters to consider delimiters when parsing. (default: `'./'`)

@@ -46,7 +49,7 @@ ```javascript

**Please note:** The `RegExp` returned by `path-to-regexp` is intended for use with pathnames or hostnames. It can not handle the query strings or fragments of a URL.
**Please note:** The `RegExp` returned by `path-to-regexp` is intended for ordered data (e.g. pathnames, hostnames). It does not handle arbitrary data (e.g. query strings, URL fragments, JSON, etc).
### Parameters
The path string can be used to define parameters and populate the keys.
The path argument is used to define parameters and populate the list of keys.

@@ -58,3 +61,3 @@ #### Named Parameters

```js
var re = pathToRegexp('/:foo/:bar', keys)
var re = pathToRegexp('/:foo/:bar')
// keys = [{ name: 'foo', prefix: '/', ... }, { name: 'bar', prefix: '/', ... }]

@@ -69,3 +72,3 @@

```js
var re = pathToRegexp('/(apple-)?icon-:res(\\d+).png', keys)
var re = pathToRegexp('/(apple-)?icon-:res(\\d+).png')
// keys = [{ name: 0, prefix: '/', ... }, { name: 'res', prefix: '', ... }]

@@ -77,10 +80,10 @@

#### Modified Parameters
#### Parameter Modifiers
##### Optional
Parameters can be suffixed with a question mark (`?`) to make the parameter optional. This will also make the prefix optional.
Parameters can be suffixed with a question mark (`?`) to make the parameter optional.
```js
var re = pathToRegexp('/:foo/:bar?', keys)
var re = pathToRegexp('/:foo/:bar?')
// keys = [{ name: 'foo', ... }, { name: 'bar', delimiter: '/', optional: true, repeat: false }]

@@ -95,2 +98,4 @@

**Tip:** If the parameter is the _only_ value in the segment, the prefix is also optional.
##### Zero or more

@@ -101,3 +106,3 @@

```js
var re = pathToRegexp('/:foo*', keys)
var re = pathToRegexp('/:foo*')
// keys = [{ name: 'foo', delimiter: '/', optional: true, repeat: true }]

@@ -117,3 +122,3 @@

```js
var re = pathToRegexp('/:foo+', keys)
var re = pathToRegexp('/:foo+')
// keys = [{ name: 'foo', delimiter: '/', optional: false, repeat: true }]

@@ -133,3 +138,3 @@

```js
var re = pathToRegexp('/:foo(\\d+)', keys)
var re = pathToRegexp('/:foo(\\d+)')
// keys = [{ name: 'foo', ... }]

@@ -151,3 +156,3 @@

```js
var re = pathToRegexp('/:foo/(.*)', keys)
var re = pathToRegexp('/:foo/(.*)')
// keys = [{ name: 'foo', ... }, { name: 0, ... }]

@@ -159,14 +164,2 @@

#### Asterisk
An asterisk can be used for matching everything. It is equivalent to an unnamed matching group of `(.*)`.
```js
var re = pathToRegexp('/foo/*', keys)
// keys = [{ name: '0', ... }]
re.exec('/foo/bar/baz')
//=> ['/foo/bar/baz', 'bar/baz']
```
### Parse

@@ -189,7 +182,7 @@

**Note:** This method only works with Express-style strings.
**Note:** This method only works with strings.
### Compile ("Reverse" Path-To-RegExp)
Path-To-RegExp exposes a compile function for transforming an Express-style path into a valid path.
Path-To-RegExp exposes a compile function for transforming a string into a valid path.

@@ -203,4 +196,4 @@ ```js

toPath({ id: ':' }) //=> "/user/%3A"
toPath({ id: ':' }, { pretty: true }) //=> "/user/:"
toPath({ id: ':/' }) //=> "/user/%3A%2F"
toPath({ id: ':/' }, { encode: (x) => x }) //=> "/user/:/"

@@ -237,3 +230,2 @@ var toPathRepeated = pathToRegexp.compile('/:segment+')

* `pattern` The RegExp used to match this token (`string`)
* `asterisk` Indicates the token is an `*` match (`boolean`)

@@ -244,7 +236,6 @@ ## Compatibility with Express <= 4.x

* No longer a direct conversion to a RegExp with sugar on top - it's a path matcher with named and unnamed matching groups
* It's unlikely you previously abused this feature, it's rare and you could always use a RegExp instead
* All matching RegExp special characters can be used in a matching group. E.g. `/:user(.*)`
* Other RegExp features are not support - no nested matching groups, non-capturing groups or look aheads
* RegExp special characters can only be used in a parameter
* Express.js 4.x used all `RegExp` special characters regardless of position - this considered a bug
* Parameters have suffixes that augment meaning - `*`, `+` and `?`. E.g. `/:user*`
* No wildcard asterisk (`*`) - use parameters instead (`(.*)`)

@@ -251,0 +242,0 @@ ## TypeScript

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc