path-to-regexp 4.0.4 → 6.1.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/Readme.md +127 -68
- package/dist/index.d.ts +14 -23
- package/dist/index.js +177 -151
- package/dist/index.js.map +1 -1
- package/dist/index.spec.js +469 -496
- package/dist/index.spec.js.map +1 -1
- package/dist.es2015/index.js +177 -150
- package/dist.es2015/index.js.map +1 -1
- package/dist.es2015/index.spec.js +469 -496
- package/dist.es2015/index.spec.js.map +1 -1
- package/package.json +2 -2
package/Readme.md
CHANGED
@@ -18,19 +18,12 @@ npm install path-to-regexp --save
|
|
18
18
|
## Usage
|
19
19
|
|
20
20
|
```javascript
|
21
|
-
const {
|
22
|
-
pathToRegexp,
|
23
|
-
match,
|
24
|
-
parse,
|
25
|
-
compile,
|
26
|
-
normalizePathname
|
27
|
-
} = require("path-to-regexp");
|
21
|
+
const { pathToRegexp, match, parse, compile } = require("path-to-regexp");
|
28
22
|
|
29
23
|
// pathToRegexp(path, keys?, options?)
|
30
24
|
// match(path)
|
31
25
|
// parse(path)
|
32
26
|
// compile(path)
|
33
|
-
// normalizePathname(path)
|
34
27
|
```
|
35
28
|
|
36
29
|
- **path** A string, array of strings, or a regular expression.
|
@@ -40,26 +33,27 @@ const {
|
|
40
33
|
- **strict** When `true` the regexp allows an optional trailing delimiter to match. (default: `false`)
|
41
34
|
- **end** When `true` the regexp will match to the end of the string. (default: `true`)
|
42
35
|
- **start** When `true` the regexp will match from the beginning of the string. (default: `true`)
|
43
|
-
- **delimiter** The default delimiter for segments. (default: `'
|
36
|
+
- **delimiter** The default delimiter for segments, e.g. `[^/#?]` for `:named` patterns. (default: `'/#?'`)
|
44
37
|
- **endsWith** Optional character, or list of characters, to treat as "end" characters.
|
45
|
-
- **
|
38
|
+
- **encode** A function to encode strings before inserting into `RegExp`. (default: `x => x`)
|
39
|
+
- **prefixes** List of characters to automatically consider prefixes when parsing. (default: `./`)
|
46
40
|
|
47
41
|
```javascript
|
48
42
|
const keys = [];
|
49
43
|
const regexp = pathToRegexp("/foo/:bar", keys);
|
50
44
|
// regexp = /^\/foo\/([^\/]+?)\/?$/i
|
51
|
-
// keys = [{ name: 'bar', prefix: '/',
|
45
|
+
// keys = [{ name: 'bar', prefix: '/', suffix: '', pattern: '[^\\/#\\?]+?', modifier: '' }]
|
52
46
|
```
|
53
47
|
|
54
|
-
**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).
|
48
|
+
**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). When using paths that contain query strings, you need to escape the question mark (`?`) to ensure it does not flag the parameter as [optional](#optional).
|
55
49
|
|
56
50
|
### Parameters
|
57
51
|
|
58
|
-
The path argument is used to define parameters and populate
|
52
|
+
The path argument is used to define parameters and populate keys.
|
59
53
|
|
60
54
|
#### Named Parameters
|
61
55
|
|
62
|
-
Named parameters are defined by prefixing a colon to the parameter name (`:foo`).
|
56
|
+
Named parameters are defined by prefixing a colon to the parameter name (`:foo`).
|
63
57
|
|
64
58
|
```js
|
65
59
|
const regexp = pathToRegexp("/:foo/:bar");
|
@@ -71,7 +65,61 @@ regexp.exec("/test/route");
|
|
71
65
|
|
72
66
|
**Please note:** Parameter names must use "word characters" (`[A-Za-z0-9_]`).
|
73
67
|
|
74
|
-
|
68
|
+
##### Custom Matching Parameters
|
69
|
+
|
70
|
+
Parameters can have a custom regexp, which overrides the default match (`[^/]+`). For example, you can match digits or names in a path:
|
71
|
+
|
72
|
+
```js
|
73
|
+
const regexpNumbers = pathToRegexp("/icon-:foo(\\d+).png");
|
74
|
+
// keys = [{ name: 'foo', ... }]
|
75
|
+
|
76
|
+
regexpNumbers.exec("/icon-123.png");
|
77
|
+
//=> ['/icon-123.png', '123']
|
78
|
+
|
79
|
+
regexpNumbers.exec("/icon-abc.png");
|
80
|
+
//=> null
|
81
|
+
|
82
|
+
const regexpWord = pathToRegexp("/(user|u)");
|
83
|
+
// keys = [{ name: 0, ... }]
|
84
|
+
|
85
|
+
regexpWord.exec("/u");
|
86
|
+
//=> ['/u', 'u']
|
87
|
+
|
88
|
+
regexpWord.exec("/users");
|
89
|
+
//=> null
|
90
|
+
```
|
91
|
+
|
92
|
+
**Tip:** Backslashes need to be escaped with another backslash in JavaScript strings.
|
93
|
+
|
94
|
+
##### Custom Prefix and Suffix
|
95
|
+
|
96
|
+
Parameters can be wrapped in `{}` to create custom prefixes or suffixes for your segment:
|
97
|
+
|
98
|
+
```js
|
99
|
+
const regexp = pathToRegexp("/:attr1?{-:attr2}?{-:attr3}?");
|
100
|
+
|
101
|
+
regexp.exec("/test");
|
102
|
+
// => ['/test', 'test', undefined, undefined]
|
103
|
+
|
104
|
+
regexp.exec("/test-test");
|
105
|
+
// => ['/test', 'test', 'test', undefined]
|
106
|
+
```
|
107
|
+
|
108
|
+
#### Unnamed Parameters
|
109
|
+
|
110
|
+
It is possible to write an unnamed parameter that only consists of a regexp. It works the same the named parameter, except it will be numerically indexed:
|
111
|
+
|
112
|
+
```js
|
113
|
+
const regexp = pathToRegexp("/:foo/(.*)");
|
114
|
+
// keys = [{ name: 'foo', ... }, { name: 0, ... }]
|
115
|
+
|
116
|
+
regexp.exec("/test/route");
|
117
|
+
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]
|
118
|
+
```
|
119
|
+
|
120
|
+
#### Modifiers
|
121
|
+
|
122
|
+
Modifiers must be placed after the parameter (e.g. `/:foo?`, `/(test)?`, or `/:foo(test)?`).
|
75
123
|
|
76
124
|
##### Optional
|
77
125
|
|
@@ -79,7 +127,7 @@ Parameters can be suffixed with a question mark (`?`) to make the parameter opti
|
|
79
127
|
|
80
128
|
```js
|
81
129
|
const regexp = pathToRegexp("/:foo/:bar?");
|
82
|
-
// keys = [{ name: 'foo', ... }, { name: 'bar',
|
130
|
+
// keys = [{ name: 'foo', ... }, { name: 'bar', prefix: '/', modifier: '?' }]
|
83
131
|
|
84
132
|
regexp.exec("/test");
|
85
133
|
//=> [ '/test', 'test', undefined, index: 0, input: '/test', groups: undefined ]
|
@@ -90,13 +138,26 @@ regexp.exec("/test/route");
|
|
90
138
|
|
91
139
|
**Tip:** The prefix is also optional, escape the prefix `\/` to make it required.
|
92
140
|
|
141
|
+
When dealing with query strings, escape the question mark (`?`) so it doesn't mark the parameter as optional. Handling unordered data is outside the scope of this library.
|
142
|
+
|
143
|
+
```js
|
144
|
+
const regexp = pathToRegexp("/search/:tableName\\?useIndex=true&term=amazing");
|
145
|
+
|
146
|
+
regexp.exec("/search/people?useIndex=true&term=amazing");
|
147
|
+
//=> [ '/search/people?useIndex=true&term=amazing', 'people', index: 0, input: '/search/people?useIndex=true&term=amazing', groups: undefined ]
|
148
|
+
|
149
|
+
// This library does not handle query strings in different orders
|
150
|
+
regexp.exec("/search/people?term=amazing&useIndex=true");
|
151
|
+
//=> null
|
152
|
+
```
|
153
|
+
|
93
154
|
##### Zero or more
|
94
155
|
|
95
|
-
Parameters can be suffixed with an asterisk (`*`) to denote a zero or more parameter matches.
|
156
|
+
Parameters can be suffixed with an asterisk (`*`) to denote a zero or more parameter matches.
|
96
157
|
|
97
158
|
```js
|
98
159
|
const regexp = pathToRegexp("/:foo*");
|
99
|
-
// keys = [{ name: 'foo',
|
160
|
+
// keys = [{ name: 'foo', prefix: '/', modifier: '*' }]
|
100
161
|
|
101
162
|
regexp.exec("/");
|
102
163
|
//=> [ '/', undefined, index: 0, input: '/', groups: undefined ]
|
@@ -107,11 +168,11 @@ regexp.exec("/bar/baz");
|
|
107
168
|
|
108
169
|
##### One or more
|
109
170
|
|
110
|
-
Parameters can be suffixed with a plus sign (`+`) to denote a one or more parameter matches.
|
171
|
+
Parameters can be suffixed with a plus sign (`+`) to denote a one or more parameter matches.
|
111
172
|
|
112
173
|
```js
|
113
174
|
const regexp = pathToRegexp("/:foo+");
|
114
|
-
// keys = [{ name: 'foo',
|
175
|
+
// keys = [{ name: 'foo', prefix: '/', modifier: '+' }]
|
115
176
|
|
116
177
|
regexp.exec("/");
|
117
178
|
//=> null
|
@@ -120,60 +181,53 @@ regexp.exec("/bar/baz");
|
|
120
181
|
//=> [ '/bar/baz','bar/baz', index: 0, input: '/bar/baz', groups: undefined ]
|
121
182
|
```
|
122
183
|
|
123
|
-
|
184
|
+
### Match
|
124
185
|
|
125
|
-
|
186
|
+
The `match` function will return a function for transforming paths into parameters:
|
126
187
|
|
127
188
|
```js
|
128
|
-
|
129
|
-
|
189
|
+
// Make sure you consistently `decode` segments.
|
190
|
+
const match = match("/user/:id", { decode: decodeURIComponent });
|
130
191
|
|
131
|
-
|
132
|
-
|
192
|
+
match("/user/123"); //=> { path: '/user/123', index: 0, params: { id: '123' } }
|
193
|
+
match("/invalid"); //=> false
|
194
|
+
match("/user/caf%C3%A9"); //=> { path: '/user/caf%C3%A9', index: 0, params: { id: 'café' } }
|
133
195
|
```
|
134
196
|
|
135
|
-
####
|
197
|
+
#### Process Pathname
|
136
198
|
|
137
|
-
|
199
|
+
You should make sure variations of the same path match the expected `path`. Here's one possible solution using `encode`:
|
138
200
|
|
139
201
|
```js
|
140
|
-
const
|
141
|
-
// keys = [{ name: 'foo', ... }]
|
142
|
-
|
143
|
-
regexpNumbers.exec("/icon-123.png");
|
144
|
-
//=> ['/icon-123.png', '123']
|
145
|
-
|
146
|
-
regexpNumbers.exec("/icon-abc.png");
|
147
|
-
//=> null
|
148
|
-
|
149
|
-
const regexpWord = pathToRegexp("/(user|u)");
|
150
|
-
// keys = [{ name: 0, ... }]
|
202
|
+
const match = match("/café", { encode: encodeURI, decode: decodeURIComponent });
|
151
203
|
|
152
|
-
|
153
|
-
//=> ['/u', 'u']
|
154
|
-
|
155
|
-
regexpWord.exec("/users");
|
156
|
-
//=> null
|
204
|
+
match("/user/caf%C3%A9"); //=> { path: '/user/caf%C3%A9', index: 0, params: { id: 'café' } }
|
157
205
|
```
|
158
206
|
|
159
|
-
**
|
160
|
-
|
161
|
-
### Match
|
207
|
+
**Note:** [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) automatically encodes pathnames for you.
|
162
208
|
|
163
|
-
|
209
|
+
##### Alternative Using Normalize
|
164
210
|
|
165
|
-
|
166
|
-
const match = match("/user/:id");
|
167
|
-
|
168
|
-
match("/user/123"); //=> { path: '/user/123', index: 0, params: { id: '123' } }
|
169
|
-
match("/invalid"); //=> false
|
170
|
-
```
|
171
|
-
|
172
|
-
### Normalize Pathname
|
173
|
-
|
174
|
-
The `normalizePathname` function will return a normalized string for matching with `pathToRegexp`.
|
211
|
+
Sometimes you won't have an already normalized pathname. You can normalize it yourself before processing:
|
175
212
|
|
176
213
|
```js
|
214
|
+
/**
|
215
|
+
* Normalize a pathname for matching, replaces multiple slashes with a single
|
216
|
+
* slash and normalizes unicode characters to "NFC". When using this method,
|
217
|
+
* `decode` should be an identity function so you don't decode strings twice.
|
218
|
+
*/
|
219
|
+
function normalizePathname(pathname: string) {
|
220
|
+
return (
|
221
|
+
decodeURI(pathname)
|
222
|
+
// Replaces repeated slashes in the URL.
|
223
|
+
.replace(/\/+/g, "/")
|
224
|
+
// Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
|
225
|
+
// Note: Missing native IE support, may want to skip this step.
|
226
|
+
.normalize()
|
227
|
+
);
|
228
|
+
}
|
229
|
+
|
230
|
+
// Two possible ways of writing `/café`:
|
177
231
|
const re = pathToRegexp("/caf\u00E9");
|
178
232
|
const input = encodeURI("/cafe\u0301");
|
179
233
|
|
@@ -192,10 +246,10 @@ console.log(tokens[0]);
|
|
192
246
|
//=> "/route"
|
193
247
|
|
194
248
|
console.log(tokens[1]);
|
195
|
-
//=> { name: 'foo', prefix: '/',
|
249
|
+
//=> { name: 'foo', prefix: '/', suffix: '', pattern: '[^\\/#\\?]+?', modifier: '' }
|
196
250
|
|
197
251
|
console.log(tokens[2]);
|
198
|
-
//=> { name: 0, prefix: '/',
|
252
|
+
//=> { name: 0, prefix: '/', suffix: '', pattern: '.*', modifier: '' }
|
199
253
|
```
|
200
254
|
|
201
255
|
**Note:** This method only works with strings.
|
@@ -205,14 +259,20 @@ console.log(tokens[2]);
|
|
205
259
|
The `compile` function will return a function for transforming parameters into a valid path:
|
206
260
|
|
207
261
|
```js
|
208
|
-
|
262
|
+
// Make sure you encode your path segments consistently.
|
263
|
+
const toPath = compile("/user/:id", { encode: encodeURIComponent });
|
209
264
|
|
210
265
|
toPath({ id: 123 }); //=> "/user/123"
|
211
266
|
toPath({ id: "café" }); //=> "/user/caf%C3%A9"
|
212
267
|
toPath({ id: "/" }); //=> "/user/%2F"
|
213
268
|
|
214
269
|
toPath({ id: ":/" }); //=> "/user/%3A%2F"
|
215
|
-
|
270
|
+
|
271
|
+
// Without `encode`, you need to make sure inputs are encoded correctly.
|
272
|
+
const toPathRaw = compile("/user/:id");
|
273
|
+
|
274
|
+
toPathRaw({ id: "%3A%2F" }); //=> "/user/%3A%2F"
|
275
|
+
toPathRaw({ id: ":/" }, { validate: false }); //=> "/user/:/"
|
216
276
|
|
217
277
|
const toPathRepeated = compile("/:segment+");
|
218
278
|
|
@@ -227,11 +287,11 @@ toPathRegexp({ id: "abc" }); //=> Throws `TypeError`.
|
|
227
287
|
toPathRegexp({ id: "abc" }, { validate: false }); //=> "/user/abc"
|
228
288
|
```
|
229
289
|
|
230
|
-
**Note:** The generated function will throw on invalid input.
|
290
|
+
**Note:** The generated function will throw on invalid input.
|
231
291
|
|
232
292
|
### Working with Tokens
|
233
293
|
|
234
|
-
Path-To-RegExp exposes the two functions used internally that accept an array of tokens
|
294
|
+
Path-To-RegExp exposes the two functions used internally that accept an array of tokens:
|
235
295
|
|
236
296
|
- `tokensToRegexp(tokens, keys?, options?)` Transform an array of tokens into a matching regular expression.
|
237
297
|
- `tokensToFunction(tokens)` Transform an array of tokens into a path generator function.
|
@@ -239,11 +299,10 @@ Path-To-RegExp exposes the two functions used internally that accept an array of
|
|
239
299
|
#### Token Information
|
240
300
|
|
241
301
|
- `name` The name of the token (`string` for named or `number` for unnamed index)
|
242
|
-
- `prefix` The prefix
|
243
|
-
- `
|
244
|
-
- `optional` Indicates the token is optional (`boolean`)
|
245
|
-
- `repeat` Indicates the token is repeated (`boolean`)
|
302
|
+
- `prefix` The prefix string for the segment (e.g. `"/"`)
|
303
|
+
- `suffix` The suffix string for the segment (e.g. `""`)
|
246
304
|
- `pattern` The RegExp used to match this token (`string`)
|
305
|
+
- `modifier` The modifier character used for the segment (e.g. `?`)
|
247
306
|
|
248
307
|
## Compatibility with Express <= 4.x
|
249
308
|
|
package/dist/index.d.ts
CHANGED
@@ -4,16 +4,10 @@ export interface ParseOptions {
|
|
4
4
|
*/
|
5
5
|
delimiter?: string;
|
6
6
|
/**
|
7
|
-
* List of characters to consider
|
7
|
+
* List of characters to automatically consider prefixes when parsing.
|
8
8
|
*/
|
9
|
-
|
9
|
+
prefixes?: string;
|
10
10
|
}
|
11
|
-
/**
|
12
|
-
* Normalize a pathname for matching, replaces multiple slashes with a single
|
13
|
-
* slash and normalizes unicode characters to "NFC". When using this method,
|
14
|
-
* `decode` should be an identity function so you don't decode strings twice.
|
15
|
-
*/
|
16
|
-
export declare function normalizePathname(pathname: string, whitelist?: string | string[]): string;
|
17
11
|
/**
|
18
12
|
* Parse a string for the raw tokens.
|
19
13
|
*/
|
@@ -66,7 +60,7 @@ export declare type MatchFunction<P extends object = object> = (path: string) =>
|
|
66
60
|
/**
|
67
61
|
* Create path match function from `path-to-regexp` spec.
|
68
62
|
*/
|
69
|
-
export declare function match<P extends object = object>(str: Path, options?: ParseOptions &
|
63
|
+
export declare function match<P extends object = object>(str: Path, options?: ParseOptions & TokensToRegexpOptions & RegexpToFunctionOptions): MatchFunction<P>;
|
70
64
|
/**
|
71
65
|
* Create a path match function from `path-to-regexp` output.
|
72
66
|
*/
|
@@ -77,20 +71,15 @@ export declare function regexpToFunction<P extends object = object>(re: RegExp,
|
|
77
71
|
export interface Key {
|
78
72
|
name: string | number;
|
79
73
|
prefix: string;
|
80
|
-
|
81
|
-
optional: boolean;
|
82
|
-
repeat: boolean;
|
74
|
+
suffix: string;
|
83
75
|
pattern: string;
|
76
|
+
modifier: string;
|
84
77
|
}
|
85
78
|
/**
|
86
79
|
* A token is a string (nothing special) or key metadata (capture group).
|
87
80
|
*/
|
88
81
|
export declare type Token = string | Key;
|
89
|
-
|
90
|
-
* Expose a function for taking tokens and returning a RegExp.
|
91
|
-
*/
|
92
|
-
export declare function tokensToRegexp(tokens: Token[], keys?: Key[], options?: RegexpOptions): RegExp;
|
93
|
-
export interface RegexpOptions {
|
82
|
+
export interface TokensToRegexpOptions {
|
94
83
|
/**
|
95
84
|
* When `true` the regexp will be case sensitive. (default: `false`)
|
96
85
|
*/
|
@@ -114,14 +103,16 @@ export interface RegexpOptions {
|
|
114
103
|
/**
|
115
104
|
* List of characters that can also be "end" characters.
|
116
105
|
*/
|
117
|
-
endsWith?: string
|
118
|
-
}
|
119
|
-
export interface ParseOptions {
|
106
|
+
endsWith?: string;
|
120
107
|
/**
|
121
|
-
*
|
108
|
+
* Encode path tokens for use in the `RegExp`.
|
122
109
|
*/
|
123
|
-
|
110
|
+
encode?: (value: string) => string;
|
124
111
|
}
|
112
|
+
/**
|
113
|
+
* Expose a function for taking tokens and returning a RegExp.
|
114
|
+
*/
|
115
|
+
export declare function tokensToRegexp(tokens: Token[], keys?: Key[], options?: TokensToRegexpOptions): RegExp;
|
125
116
|
/**
|
126
117
|
* Supported `path-to-regexp` input types.
|
127
118
|
*/
|
@@ -133,4 +124,4 @@ export declare type Path = string | RegExp | Array<string | RegExp>;
|
|
133
124
|
* placeholder key descriptions. For example, using `/user/:id`, `keys` will
|
134
125
|
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
|
135
126
|
*/
|
136
|
-
export declare function pathToRegexp(path: Path, keys?: Key[], options?:
|
127
|
+
export declare function pathToRegexp(path: Path, keys?: Key[], options?: TokensToRegexpOptions & ParseOptions): RegExp;
|