path-to-regexp 2.3.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/History.md +16 -0
- package/Readme.md +75 -54
- package/index.d.ts +47 -7
- package/index.js +72 -32
- package/package.json +9 -8
package/History.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
3.0.0 / 2019-01-13
|
2
|
+
==================
|
3
|
+
|
4
|
+
* Always use prefix character as delimiter token, allowing any character to be a delimiter (e.g. `/:att1-:att2-:att3-:att4-:att5`)
|
5
|
+
* Remove `partial` support, prefer escaping the prefix delimiter explicitly (e.g. `\\/(apple-)?icon-:res(\\d+).png`)
|
6
|
+
|
7
|
+
2.4.0 / 2018-08-26
|
8
|
+
==================
|
9
|
+
|
10
|
+
* Support `start` option to disable anchoring from beginning of the string
|
11
|
+
|
12
|
+
2.3.0 / 2018-08-20
|
13
|
+
==================
|
14
|
+
|
15
|
+
* Use `delimiter` when processing repeated matching groups (e.g. `foo/bar` has no prefix, but has a delimiter)
|
16
|
+
|
1
17
|
2.2.1 / 2018-04-24
|
2
18
|
==================
|
3
19
|
|
package/Readme.md
CHANGED
@@ -18,32 +18,33 @@ npm install path-to-regexp --save
|
|
18
18
|
## Usage
|
19
19
|
|
20
20
|
```javascript
|
21
|
-
|
21
|
+
const pathToRegexp = require('path-to-regexp')
|
22
22
|
|
23
23
|
// pathToRegexp(path, keys?, options?)
|
24
|
+
// pathToRegexp.match(path)
|
24
25
|
// pathToRegexp.parse(path)
|
25
26
|
// pathToRegexp.compile(path)
|
26
27
|
```
|
27
28
|
|
28
29
|
- **path** A string, array of strings, or a regular expression.
|
29
|
-
- **keys** An array to
|
30
|
+
- **keys** An array to populate with keys found in the path.
|
30
31
|
- **options**
|
31
32
|
- **sensitive** When `true` the regexp will be case sensitive. (default: `false`)
|
32
33
|
- **strict** When `true` the regexp allows an optional trailing delimiter to match. (default: `false`)
|
33
|
-
- **end** When `
|
34
|
-
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
- **end** When `true` the regexp will match to the end of the string. (default: `true`)
|
35
|
+
- **start** When `true` the regexp will match from the beginning of the string. (default: `true`)
|
36
|
+
- **delimiter** The default delimiter for segments. (default: `'/'`)
|
37
|
+
- **endsWith** Optional character, or list of characters, to treat as "end" characters.
|
38
|
+
- **whitelist** List of characters to consider delimiters when parsing. (default: `undefined`, any character)
|
38
39
|
|
39
40
|
```javascript
|
40
|
-
|
41
|
-
|
42
|
-
//
|
41
|
+
const keys = []
|
42
|
+
const regexp = pathToRegexp('/foo/:bar', keys)
|
43
|
+
// regexp = /^\/foo\/([^\/]+?)\/?$/i
|
43
44
|
// keys = [{ name: 'bar', prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '[^\\/]+?' }]
|
44
45
|
```
|
45
46
|
|
46
|
-
**Please note:** The `RegExp` returned by `path-to-regexp` is intended for ordered data (e.g. pathnames, hostnames). It
|
47
|
+
**Please note:** The `RegExp` returned by `path-to-regexp` is intended for ordered data (e.g. pathnames, hostnames). It can not handle arbitrarily ordered data (e.g. query strings, URL fragments, JSON, etc).
|
47
48
|
|
48
49
|
### Parameters
|
49
50
|
|
@@ -51,17 +52,17 @@ The path argument is used to define parameters and populate the list of keys.
|
|
51
52
|
|
52
53
|
#### Named Parameters
|
53
54
|
|
54
|
-
Named parameters are defined by prefixing a colon to the parameter name (`:foo`). By default, the parameter will match until the
|
55
|
+
Named parameters are defined by prefixing a colon to the parameter name (`:foo`). By default, the parameter will match until the next prefix (e.g. `[^/]+`).
|
55
56
|
|
56
57
|
```js
|
57
|
-
|
58
|
+
const regexp = pathToRegexp('/:foo/:bar')
|
58
59
|
// keys = [{ name: 'foo', prefix: '/', ... }, { name: 'bar', prefix: '/', ... }]
|
59
60
|
|
60
|
-
|
61
|
-
//=> ['/test/route', 'test', 'route']
|
61
|
+
regexp.exec('/test/route')
|
62
|
+
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]
|
62
63
|
```
|
63
64
|
|
64
|
-
**Please note:** Parameter names must
|
65
|
+
**Please note:** Parameter names must use "word characters" (`[A-Za-z0-9_]`).
|
65
66
|
|
66
67
|
#### Parameter Modifiers
|
67
68
|
|
@@ -70,83 +71,103 @@ re.exec('/test/route')
|
|
70
71
|
Parameters can be suffixed with a question mark (`?`) to make the parameter optional.
|
71
72
|
|
72
73
|
```js
|
73
|
-
|
74
|
+
const regexp = pathToRegexp('/:foo/:bar?')
|
74
75
|
// keys = [{ name: 'foo', ... }, { name: 'bar', delimiter: '/', optional: true, repeat: false }]
|
75
76
|
|
76
|
-
|
77
|
-
//=> ['/test', 'test', undefined]
|
77
|
+
regexp.exec('/test')
|
78
|
+
//=> [ '/test', 'test', undefined, index: 0, input: '/test', groups: undefined ]
|
78
79
|
|
79
|
-
|
80
|
-
//=> ['/test', 'test', 'route']
|
80
|
+
regexp.exec('/test/route')
|
81
|
+
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]
|
81
82
|
```
|
82
83
|
|
83
|
-
**Tip:**
|
84
|
+
**Tip:** The prefix is also optional, escape the prefix `\/` to make it required.
|
84
85
|
|
85
86
|
##### Zero or more
|
86
87
|
|
87
|
-
Parameters can be suffixed with an asterisk (`*`) to denote a zero or more parameter matches. The prefix is
|
88
|
+
Parameters can be suffixed with an asterisk (`*`) to denote a zero or more parameter matches. The prefix is used for each match.
|
88
89
|
|
89
90
|
```js
|
90
|
-
|
91
|
+
const regexp = pathToRegexp('/:foo*')
|
91
92
|
// keys = [{ name: 'foo', delimiter: '/', optional: true, repeat: true }]
|
92
93
|
|
93
|
-
|
94
|
-
//=> ['/', undefined]
|
94
|
+
regexp.exec('/')
|
95
|
+
//=> [ '/', undefined, index: 0, input: '/', groups: undefined ]
|
95
96
|
|
96
|
-
|
97
|
-
//=> ['/bar/baz', 'bar/baz']
|
97
|
+
regexp.exec('/bar/baz')
|
98
|
+
//=> [ '/bar/baz', 'bar/baz', index: 0, input: '/bar/baz', groups: undefined ]
|
98
99
|
```
|
99
100
|
|
100
101
|
##### One or more
|
101
102
|
|
102
|
-
Parameters can be suffixed with a plus sign (`+`) to denote a one or more parameter matches. The prefix is
|
103
|
+
Parameters can be suffixed with a plus sign (`+`) to denote a one or more parameter matches. The prefix is used for each match.
|
103
104
|
|
104
105
|
```js
|
105
|
-
|
106
|
+
const regexp = pathToRegexp('/:foo+')
|
106
107
|
// keys = [{ name: 'foo', delimiter: '/', optional: false, repeat: true }]
|
107
108
|
|
108
|
-
|
109
|
+
regexp.exec('/')
|
109
110
|
//=> null
|
110
111
|
|
111
|
-
|
112
|
-
//=> ['/bar/baz', 'bar/baz']
|
112
|
+
regexp.exec('/bar/baz')
|
113
|
+
//=> [ '/bar/baz','bar/baz', index: 0, input: '/bar/baz', groups: undefined ]
|
114
|
+
```
|
115
|
+
|
116
|
+
#### Unnamed Parameters
|
117
|
+
|
118
|
+
It is possible to write an unnamed parameter that only consists of a matching group. It works the same as a named parameter, except it will be numerically indexed.
|
119
|
+
|
120
|
+
```js
|
121
|
+
const regexp = pathToRegexp('/:foo/(.*)')
|
122
|
+
// keys = [{ name: 'foo', ... }, { name: 0, ... }]
|
123
|
+
|
124
|
+
regexp.exec('/test/route')
|
125
|
+
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]
|
113
126
|
```
|
114
127
|
|
115
128
|
#### Custom Matching Parameters
|
116
129
|
|
117
|
-
All parameters can
|
130
|
+
All parameters can have a custom regexp, which overrides the default match (`[^/]+`). For example, you can match digits or names in a path:
|
118
131
|
|
119
132
|
```js
|
120
|
-
|
133
|
+
const regexpNumbers = pathToRegexp('/icon-:foo(\\d+).png')
|
121
134
|
// keys = [{ name: 'foo', ... }]
|
122
135
|
|
123
|
-
|
136
|
+
regexpNumbers.exec('/icon-123.png')
|
124
137
|
//=> ['/icon-123.png', '123']
|
125
138
|
|
126
|
-
|
139
|
+
regexpNumbers.exec('/icon-abc.png')
|
140
|
+
//=> null
|
141
|
+
|
142
|
+
const regexpWord = pathToRegexp('/(user|u)')
|
143
|
+
// keys = [{ name: 0, ... }]
|
144
|
+
|
145
|
+
regexpWord.exec('/u')
|
146
|
+
//=> ['/u', 'u']
|
147
|
+
|
148
|
+
regexpWord.exec('/users')
|
127
149
|
//=> null
|
128
150
|
```
|
129
151
|
|
130
|
-
**
|
152
|
+
**Tip:** Backslashes need to be escaped with another backslash in JavaScript strings.
|
131
153
|
|
132
|
-
|
154
|
+
### Match
|
133
155
|
|
134
|
-
|
156
|
+
The `match` function will return a function for transforming paths into parameters:
|
135
157
|
|
136
158
|
```js
|
137
|
-
|
138
|
-
// keys = [{ name: 'foo', ... }, { name: 0, ... }]
|
159
|
+
const match = pathToRegexp.match('/user/:id')
|
139
160
|
|
140
|
-
|
141
|
-
|
161
|
+
match('/user/123') //=> { path: '/user/123', index: 0, params: { id: '123' } }
|
162
|
+
match('/invalid') //=> false
|
142
163
|
```
|
143
164
|
|
144
165
|
### Parse
|
145
166
|
|
146
|
-
The parse function
|
167
|
+
The `parse` function will return a list of strings and keys from a path string:
|
147
168
|
|
148
169
|
```js
|
149
|
-
|
170
|
+
const tokens = pathToRegexp.parse('/route/:foo/(.*)')
|
150
171
|
|
151
172
|
console.log(tokens[0])
|
152
173
|
//=> "/route"
|
@@ -162,28 +183,29 @@ console.log(tokens[2])
|
|
162
183
|
|
163
184
|
### Compile ("Reverse" Path-To-RegExp)
|
164
185
|
|
165
|
-
|
186
|
+
The `compile` function will return a function for transforming parameters into a valid path:
|
166
187
|
|
167
188
|
```js
|
168
|
-
|
189
|
+
const toPath = pathToRegexp.compile('/user/:id')
|
169
190
|
|
170
191
|
toPath({ id: 123 }) //=> "/user/123"
|
171
192
|
toPath({ id: 'café' }) //=> "/user/caf%C3%A9"
|
172
193
|
toPath({ id: '/' }) //=> "/user/%2F"
|
173
194
|
|
174
195
|
toPath({ id: ':/' }) //=> "/user/%3A%2F"
|
175
|
-
toPath({ id: ':/' }, { encode: (value, token) => value }) //=> "/user/:/"
|
196
|
+
toPath({ id: ':/' }, { encode: (value, token) => value, validate: false }) //=> "/user/:/"
|
176
197
|
|
177
|
-
|
198
|
+
const toPathRepeated = pathToRegexp.compile('/:segment+')
|
178
199
|
|
179
200
|
toPathRepeated({ segment: 'foo' }) //=> "/foo"
|
180
201
|
toPathRepeated({ segment: ['a', 'b', 'c'] }) //=> "/a/b/c"
|
181
202
|
|
182
|
-
|
203
|
+
const toPathRegexp = pathToRegexp.compile('/user/:id(\\d+)')
|
183
204
|
|
184
205
|
toPathRegexp({ id: 123 }) //=> "/user/123"
|
185
206
|
toPathRegexp({ id: '123' }) //=> "/user/123"
|
186
207
|
toPathRegexp({ id: 'abc' }) //=> Throws `TypeError`.
|
208
|
+
toPathRegexp({ id: 'abc' }, { validate: false }) //=> "/user/abc"
|
187
209
|
```
|
188
210
|
|
189
211
|
**Note:** The generated function will throw on invalid input. It will do all necessary checks to ensure the generated path is valid. This method only works with strings.
|
@@ -198,11 +220,10 @@ Path-To-RegExp exposes the two functions used internally that accept an array of
|
|
198
220
|
#### Token Information
|
199
221
|
|
200
222
|
* `name` The name of the token (`string` for named or `number` for index)
|
201
|
-
* `prefix` The prefix character for the segment (`/`
|
202
|
-
* `delimiter` The delimiter for the segment (same as prefix or
|
223
|
+
* `prefix` The prefix character for the segment (e.g. `/`)
|
224
|
+
* `delimiter` The delimiter for the segment (same as prefix or default delimiter)
|
203
225
|
* `optional` Indicates the token is optional (`boolean`)
|
204
226
|
* `repeat` Indicates the token is repeated (`boolean`)
|
205
|
-
* `partial` Indicates this token is a partial path segment (`boolean`)
|
206
227
|
* `pattern` The RegExp used to match this token (`string`)
|
207
228
|
|
208
229
|
## Compatibility with Express <= 4.x
|
package/index.d.ts
CHANGED
@@ -11,9 +11,13 @@ declare namespace pathToRegexp {
|
|
11
11
|
*/
|
12
12
|
strict?: boolean;
|
13
13
|
/**
|
14
|
-
* When `
|
14
|
+
* When `true` the regexp will match to the end of the string. (default: `true`)
|
15
15
|
*/
|
16
16
|
end?: boolean;
|
17
|
+
/**
|
18
|
+
* When `true` the regexp will match from the beginning of the string. (default: `true`)
|
19
|
+
*/
|
20
|
+
start?: boolean;
|
17
21
|
/**
|
18
22
|
* Sets the final character for non-ending optimistic matches. (default: `/`)
|
19
23
|
*/
|
@@ -22,6 +26,10 @@ declare namespace pathToRegexp {
|
|
22
26
|
* List of characters that can also be "end" characters.
|
23
27
|
*/
|
24
28
|
endsWith?: string | string[];
|
29
|
+
/**
|
30
|
+
* List of characters to consider delimiters when parsing. (default: `undefined`, any character)
|
31
|
+
*/
|
32
|
+
whitelist?: string | string[];
|
25
33
|
}
|
26
34
|
|
27
35
|
export interface ParseOptions {
|
@@ -29,10 +37,13 @@ declare namespace pathToRegexp {
|
|
29
37
|
* Set the default delimiter for repeat parameters. (default: `'/'`)
|
30
38
|
*/
|
31
39
|
delimiter?: string;
|
40
|
+
}
|
41
|
+
|
42
|
+
export interface TokensToFunctionOptions {
|
32
43
|
/**
|
33
|
-
*
|
44
|
+
* When `true` the regexp will be case sensitive. (default: `false`)
|
34
45
|
*/
|
35
|
-
|
46
|
+
sensitive?: boolean;
|
36
47
|
}
|
37
48
|
|
38
49
|
/**
|
@@ -40,15 +51,25 @@ declare namespace pathToRegexp {
|
|
40
51
|
*/
|
41
52
|
export function parse (path: string, options?: ParseOptions): Token[];
|
42
53
|
|
54
|
+
/**
|
55
|
+
* Create path match function from `path-to-regexp` spec.
|
56
|
+
*/
|
57
|
+
export function match <P extends object = object> (path: string, options?: ParseOptions): MatchFunction<P>;
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Create a path match function from `path-to-regexp` output.
|
61
|
+
*/
|
62
|
+
export function regexpToFunction <P extends object = object> (re: RegExp, keys: Key[]): MatchFunction<P>;
|
63
|
+
|
43
64
|
/**
|
44
65
|
* Transforming an Express-style path into a valid path.
|
45
66
|
*/
|
46
|
-
export function compile (path: string, options?: ParseOptions): PathFunction
|
67
|
+
export function compile <P extends object = object> (path: string, options?: ParseOptions & TokensToFunctionOptions): PathFunction<P>;
|
47
68
|
|
48
69
|
/**
|
49
70
|
* Transform an array of tokens into a path generator function.
|
50
71
|
*/
|
51
|
-
export function tokensToFunction (tokens: Token[]): PathFunction
|
72
|
+
export function tokensToFunction <P extends object = object> (tokens: Token[], options?: TokensToFunctionOptions): PathFunction<P>;
|
52
73
|
|
53
74
|
/**
|
54
75
|
* Transform an array of tokens into a matching regular expression.
|
@@ -62,7 +83,6 @@ declare namespace pathToRegexp {
|
|
62
83
|
optional: boolean;
|
63
84
|
repeat: boolean;
|
64
85
|
pattern: string;
|
65
|
-
partial: boolean;
|
66
86
|
}
|
67
87
|
|
68
88
|
interface PathFunctionOptions {
|
@@ -70,11 +90,31 @@ declare namespace pathToRegexp {
|
|
70
90
|
* Function for encoding input strings for output.
|
71
91
|
*/
|
72
92
|
encode?: (value: string, token: Key) => string;
|
93
|
+
/**
|
94
|
+
* When `false` the function can produce an invalid (unmatched) path. (default: `true`)
|
95
|
+
*/
|
96
|
+
validate?: boolean;
|
73
97
|
}
|
74
98
|
|
99
|
+
interface MatchFunctionOptions {
|
100
|
+
/**
|
101
|
+
* Function for decoding strings for params.
|
102
|
+
*/
|
103
|
+
decode?: (value: string, token: Key) => string;
|
104
|
+
}
|
105
|
+
|
106
|
+
interface MatchResult <P extends object = object> {
|
107
|
+
path: string;
|
108
|
+
index: number;
|
109
|
+
params: P;
|
110
|
+
}
|
111
|
+
|
112
|
+
type Match <P extends object = object> = false | MatchResult<P>;
|
113
|
+
|
75
114
|
export type Token = string | Key;
|
76
115
|
export type Path = string | RegExp | Array<string | RegExp>;
|
77
|
-
export type PathFunction = (data?:
|
116
|
+
export type PathFunction <P extends object = object> = (data?: P, options?: PathFunctionOptions) => string;
|
117
|
+
export type MatchFunction <P extends object = object> = (path: string, options?: MatchFunctionOptions) => Match<P>;
|
78
118
|
}
|
79
119
|
|
80
120
|
export = pathToRegexp;
|
package/index.js
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
* Expose `pathToRegexp`.
|
3
3
|
*/
|
4
4
|
module.exports = pathToRegexp
|
5
|
+
module.exports.match = match
|
6
|
+
module.exports.regexpToFunction = regexpToFunction
|
5
7
|
module.exports.parse = parse
|
6
8
|
module.exports.compile = compile
|
7
9
|
module.exports.tokensToFunction = tokensToFunction
|
@@ -11,7 +13,6 @@ module.exports.tokensToRegExp = tokensToRegExp
|
|
11
13
|
* Default configs.
|
12
14
|
*/
|
13
15
|
var DEFAULT_DELIMITER = '/'
|
14
|
-
var DEFAULT_DELIMITERS = './'
|
15
16
|
|
16
17
|
/**
|
17
18
|
* The main path matching regexp utility.
|
@@ -43,7 +44,7 @@ function parse (str, options) {
|
|
43
44
|
var index = 0
|
44
45
|
var path = ''
|
45
46
|
var defaultDelimiter = (options && options.delimiter) || DEFAULT_DELIMITER
|
46
|
-
var
|
47
|
+
var whitelist = (options && options.whitelist) || undefined
|
47
48
|
var pathEscaped = false
|
48
49
|
var res
|
49
50
|
|
@@ -62,7 +63,6 @@ function parse (str, options) {
|
|
62
63
|
}
|
63
64
|
|
64
65
|
var prev = ''
|
65
|
-
var next = str[index]
|
66
66
|
var name = res[2]
|
67
67
|
var capture = res[3]
|
68
68
|
var group = res[4]
|
@@ -70,9 +70,11 @@ function parse (str, options) {
|
|
70
70
|
|
71
71
|
if (!pathEscaped && path.length) {
|
72
72
|
var k = path.length - 1
|
73
|
+
var c = path[k]
|
74
|
+
var matches = whitelist ? whitelist.indexOf(c) > -1 : true
|
73
75
|
|
74
|
-
if (
|
75
|
-
prev =
|
76
|
+
if (matches) {
|
77
|
+
prev = c
|
76
78
|
path = path.slice(0, k)
|
77
79
|
}
|
78
80
|
}
|
@@ -84,11 +86,10 @@ function parse (str, options) {
|
|
84
86
|
pathEscaped = false
|
85
87
|
}
|
86
88
|
|
87
|
-
var partial = prev !== '' && next !== undefined && next !== prev
|
88
89
|
var repeat = modifier === '+' || modifier === '*'
|
89
90
|
var optional = modifier === '?' || modifier === '*'
|
90
|
-
var delimiter = prev || defaultDelimiter
|
91
91
|
var pattern = capture || group
|
92
|
+
var delimiter = prev || defaultDelimiter
|
92
93
|
|
93
94
|
tokens.push({
|
94
95
|
name: name || key++,
|
@@ -96,8 +97,9 @@ function parse (str, options) {
|
|
96
97
|
delimiter: delimiter,
|
97
98
|
optional: optional,
|
98
99
|
repeat: repeat,
|
99
|
-
|
100
|
-
|
100
|
+
pattern: pattern
|
101
|
+
? escapeGroup(pattern)
|
102
|
+
: '[^' + escapeString(delimiter === defaultDelimiter ? delimiter : (delimiter + defaultDelimiter)) + ']+?'
|
101
103
|
})
|
102
104
|
}
|
103
105
|
|
@@ -117,26 +119,67 @@ function parse (str, options) {
|
|
117
119
|
* @return {!function(Object=, Object=)}
|
118
120
|
*/
|
119
121
|
function compile (str, options) {
|
120
|
-
return tokensToFunction(parse(str, options))
|
122
|
+
return tokensToFunction(parse(str, options), options)
|
123
|
+
}
|
124
|
+
|
125
|
+
/**
|
126
|
+
* Create path match function from `path-to-regexp` spec.
|
127
|
+
*/
|
128
|
+
function match (str, options) {
|
129
|
+
var keys = []
|
130
|
+
var re = pathToRegexp(str, keys, options)
|
131
|
+
return regexpToFunction(re, keys)
|
132
|
+
}
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Create a path match function from `path-to-regexp` output.
|
136
|
+
*/
|
137
|
+
function regexpToFunction (re, keys) {
|
138
|
+
return function (pathname, options) {
|
139
|
+
var m = re.exec(pathname)
|
140
|
+
if (!m) return false
|
141
|
+
|
142
|
+
var path = m[0]
|
143
|
+
var index = m.index
|
144
|
+
var params = {}
|
145
|
+
var decode = (options && options.decode) || decodeURIComponent
|
146
|
+
|
147
|
+
for (var i = 1; i < m.length; i++) {
|
148
|
+
if (m[i] === undefined) continue
|
149
|
+
|
150
|
+
var key = keys[i - 1]
|
151
|
+
|
152
|
+
if (key.repeat) {
|
153
|
+
params[key.name] = m[i].split(key.delimiter).map(function (value) {
|
154
|
+
return decode(value, key)
|
155
|
+
})
|
156
|
+
} else {
|
157
|
+
params[key.name] = decode(m[i], key)
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
return { path: path, index: index, params: params }
|
162
|
+
}
|
121
163
|
}
|
122
164
|
|
123
165
|
/**
|
124
166
|
* Expose a method for transforming tokens into the path function.
|
125
167
|
*/
|
126
|
-
function tokensToFunction (tokens) {
|
168
|
+
function tokensToFunction (tokens, options) {
|
127
169
|
// Compile all the tokens into regexps.
|
128
170
|
var matches = new Array(tokens.length)
|
129
171
|
|
130
172
|
// Compile all the patterns before compilation.
|
131
173
|
for (var i = 0; i < tokens.length; i++) {
|
132
174
|
if (typeof tokens[i] === 'object') {
|
133
|
-
matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$')
|
175
|
+
matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$', flags(options))
|
134
176
|
}
|
135
177
|
}
|
136
178
|
|
137
179
|
return function (data, options) {
|
138
180
|
var path = ''
|
139
181
|
var encode = (options && options.encode) || encodeURIComponent
|
182
|
+
var validate = options ? options.validate !== false : true
|
140
183
|
|
141
184
|
for (var i = 0; i < tokens.length; i++) {
|
142
185
|
var token = tokens[i]
|
@@ -163,7 +206,7 @@ function tokensToFunction (tokens) {
|
|
163
206
|
for (var j = 0; j < value.length; j++) {
|
164
207
|
segment = encode(value[j], token)
|
165
208
|
|
166
|
-
if (!matches[i].test(segment)) {
|
209
|
+
if (validate && !matches[i].test(segment)) {
|
167
210
|
throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '"')
|
168
211
|
}
|
169
212
|
|
@@ -176,7 +219,7 @@ function tokensToFunction (tokens) {
|
|
176
219
|
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
177
220
|
segment = encode(String(value), token)
|
178
221
|
|
179
|
-
if (!matches[i].test(segment)) {
|
222
|
+
if (validate && !matches[i].test(segment)) {
|
180
223
|
throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but got "' + segment + '"')
|
181
224
|
}
|
182
225
|
|
@@ -184,12 +227,7 @@ function tokensToFunction (tokens) {
|
|
184
227
|
continue
|
185
228
|
}
|
186
229
|
|
187
|
-
if (token.optional)
|
188
|
-
// Prepend partial segment prefixes.
|
189
|
-
if (token.partial) path += token.prefix
|
190
|
-
|
191
|
-
continue
|
192
|
-
}
|
230
|
+
if (token.optional) continue
|
193
231
|
|
194
232
|
throw new TypeError('Expected "' + token.name + '" to be ' + (token.repeat ? 'an array' : 'a string'))
|
195
233
|
}
|
@@ -249,7 +287,6 @@ function regexpToRegexp (path, keys) {
|
|
249
287
|
delimiter: null,
|
250
288
|
optional: false,
|
251
289
|
repeat: false,
|
252
|
-
partial: false,
|
253
290
|
pattern: null
|
254
291
|
})
|
255
292
|
}
|
@@ -300,12 +337,11 @@ function tokensToRegExp (tokens, keys, options) {
|
|
300
337
|
options = options || {}
|
301
338
|
|
302
339
|
var strict = options.strict
|
340
|
+
var start = options.start !== false
|
303
341
|
var end = options.end !== false
|
304
|
-
var delimiter =
|
305
|
-
var delimiters = options.delimiters || DEFAULT_DELIMITERS
|
342
|
+
var delimiter = options.delimiter || DEFAULT_DELIMITER
|
306
343
|
var endsWith = [].concat(options.endsWith || []).map(escapeString).concat('$').join('|')
|
307
|
-
var route = ''
|
308
|
-
var isEndDelimited = tokens.length === 0
|
344
|
+
var route = start ? '^' : ''
|
309
345
|
|
310
346
|
// Iterate over the tokens and create our regexp string.
|
311
347
|
for (var i = 0; i < tokens.length; i++) {
|
@@ -313,7 +349,6 @@ function tokensToRegExp (tokens, keys, options) {
|
|
313
349
|
|
314
350
|
if (typeof token === 'string') {
|
315
351
|
route += escapeString(token)
|
316
|
-
isEndDelimited = i === tokens.length - 1 && delimiters.indexOf(token[token.length - 1]) > -1
|
317
352
|
} else {
|
318
353
|
var capture = token.repeat
|
319
354
|
? '(?:' + token.pattern + ')(?:' + escapeString(token.delimiter) + '(?:' + token.pattern + '))*'
|
@@ -322,8 +357,8 @@ function tokensToRegExp (tokens, keys, options) {
|
|
322
357
|
if (keys) keys.push(token)
|
323
358
|
|
324
359
|
if (token.optional) {
|
325
|
-
if (token.
|
326
|
-
route +=
|
360
|
+
if (!token.prefix) {
|
361
|
+
route += '(' + capture + ')?'
|
327
362
|
} else {
|
328
363
|
route += '(?:' + escapeString(token.prefix) + '(' + capture + '))?'
|
329
364
|
}
|
@@ -334,15 +369,20 @@ function tokensToRegExp (tokens, keys, options) {
|
|
334
369
|
}
|
335
370
|
|
336
371
|
if (end) {
|
337
|
-
if (!strict) route += '(?:' + delimiter + ')?'
|
372
|
+
if (!strict) route += '(?:' + escapeString(delimiter) + ')?'
|
338
373
|
|
339
374
|
route += endsWith === '$' ? '$' : '(?=' + endsWith + ')'
|
340
375
|
} else {
|
341
|
-
|
342
|
-
|
376
|
+
var endToken = tokens[tokens.length - 1]
|
377
|
+
var isEndDelimited = typeof endToken === 'string'
|
378
|
+
? endToken[endToken.length - 1] === delimiter
|
379
|
+
: endToken === undefined
|
380
|
+
|
381
|
+
if (!strict) route += '(?:' + escapeString(delimiter) + '(?=' + endsWith + '))?'
|
382
|
+
if (!isEndDelimited) route += '(?=' + escapeString(delimiter) + '|' + endsWith + ')'
|
343
383
|
}
|
344
384
|
|
345
|
-
return new RegExp(
|
385
|
+
return new RegExp(route, flags(options))
|
346
386
|
}
|
347
387
|
|
348
388
|
/**
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "path-to-regexp",
|
3
3
|
"description": "Express style path to RegExp utility",
|
4
|
-
"version": "2.
|
4
|
+
"version": "3.2.0",
|
5
5
|
"main": "index.js",
|
6
6
|
"typings": "index.d.ts",
|
7
7
|
"files": [
|
@@ -12,7 +12,8 @@
|
|
12
12
|
"scripts": {
|
13
13
|
"lint": "standard",
|
14
14
|
"test-spec": "mocha --require ts-node/register -R spec --bail test.ts",
|
15
|
-
"test-cov": "
|
15
|
+
"test-cov": "nyc --reporter=lcov mocha -- --require ts-node/register -R spec test.ts",
|
16
|
+
"coverage": "nyc report --reporter=text-lcov",
|
16
17
|
"test": "npm run lint && npm run test-cov"
|
17
18
|
},
|
18
19
|
"keywords": [
|
@@ -34,12 +35,12 @@
|
|
34
35
|
"devDependencies": {
|
35
36
|
"@types/chai": "^4.0.4",
|
36
37
|
"@types/mocha": "^5.2.5",
|
37
|
-
"@types/node": "^
|
38
|
+
"@types/node": "^12.7.3",
|
38
39
|
"chai": "^4.1.1",
|
39
|
-
"
|
40
|
-
"
|
41
|
-
"standard": "^
|
42
|
-
"ts-node": "^
|
43
|
-
"typescript": "^3.
|
40
|
+
"mocha": "^6.2.0",
|
41
|
+
"nyc": "^14.1.1",
|
42
|
+
"standard": "^14.1.0",
|
43
|
+
"ts-node": "^8.3.0",
|
44
|
+
"typescript": "^3.7.2"
|
44
45
|
}
|
45
46
|
}
|