path-to-regexp 6.2.2 → 7.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 +141 -166
- package/dist/index.d.ts +86 -74
- package/dist/index.js +323 -302
- package/dist/index.js.map +1 -1
- package/package.json +11 -12
- package/dist.es2015/index.js +0 -400
- package/dist.es2015/index.js.map +0 -1
package/Readme.md
CHANGED
@@ -16,59 +16,55 @@ npm install path-to-regexp --save
|
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
|
19
|
-
```
|
19
|
+
```js
|
20
20
|
const { pathToRegexp, match, parse, compile } = require("path-to-regexp");
|
21
21
|
|
22
|
-
// pathToRegexp(path,
|
23
|
-
// match(path)
|
24
|
-
// parse(path)
|
25
|
-
// compile(path)
|
22
|
+
// pathToRegexp(path, options?)
|
23
|
+
// match(path, options?)
|
24
|
+
// parse(path, options?)
|
25
|
+
// compile(path, options?)
|
26
26
|
```
|
27
27
|
|
28
28
|
### Path to regexp
|
29
29
|
|
30
|
-
The `pathToRegexp` function
|
30
|
+
The `pathToRegexp` function returns a regular expression with `keys` as a property. It accepts the following arguments:
|
31
31
|
|
32
|
-
- **path** A string
|
33
|
-
- **keys** _(optional)_ An array to populate with keys found in the path.
|
32
|
+
- **path** A string.
|
34
33
|
- **options** _(optional)_
|
35
|
-
- **sensitive**
|
36
|
-
- **
|
37
|
-
- **
|
38
|
-
- **
|
39
|
-
- **
|
40
|
-
- **
|
41
|
-
- **
|
42
|
-
- **
|
43
|
-
|
44
|
-
```
|
45
|
-
const
|
46
|
-
|
47
|
-
//
|
48
|
-
// keys = [{ name: 'bar', prefix: '/', suffix: '', pattern: '[^\\/#\\?]+?', modifier: '' }]
|
34
|
+
- **sensitive** Regexp will be case sensitive. (default: `false`)
|
35
|
+
- **trailing** Allows optional trailing delimiter to match. (default: `true`)
|
36
|
+
- **strict** Verify patterns are valid and safe to use. (default: `false`, recommended: `true`)
|
37
|
+
- **end** Match to the end of the string. (default: `true`)
|
38
|
+
- **start** Match from the beginning of the string. (default: `true`)
|
39
|
+
- **loose** Allow the delimiter to be arbitrarily repeated, e.g. `/` or `///`. (default: `true`)
|
40
|
+
- **delimiter** The default delimiter for segments, e.g. `[^/]` for `:named` parameters. (default: `'/'`)
|
41
|
+
- **encodePath** A function for encoding input strings. (default: `x => x`, recommended: [`encodeurl`](https://github.com/pillarjs/encodeurl) for unicode encoding)
|
42
|
+
|
43
|
+
```js
|
44
|
+
const regexp = pathToRegexp("/foo/:bar");
|
45
|
+
// regexp = /^\/+foo(?:\/+([^\/]+?))(?:\/+)?$/i
|
46
|
+
// keys = [{ name: 'bar', prefix: '', suffix: '', pattern: '', modifier: '' }]
|
49
47
|
```
|
50
48
|
|
51
|
-
**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).
|
49
|
+
**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).
|
52
50
|
|
53
51
|
### Parameters
|
54
52
|
|
55
53
|
The path argument is used to define parameters and populate keys.
|
56
54
|
|
57
|
-
#### Named
|
55
|
+
#### Named parameters
|
58
56
|
|
59
|
-
Named parameters are defined by prefixing a colon to the parameter name (`:foo`).
|
57
|
+
Named parameters are defined by prefixing a colon to the parameter name (`:foo`). Parameter names can use any valid unicode identifier characters (similar to JavaScript).
|
60
58
|
|
61
59
|
```js
|
62
60
|
const regexp = pathToRegexp("/:foo/:bar");
|
63
|
-
// keys = [{ name: 'foo',
|
61
|
+
// keys = [{ name: 'foo', ... }, { name: 'bar', ... }]
|
64
62
|
|
65
63
|
regexp.exec("/test/route");
|
66
|
-
//=> [ '/test/route', 'test', 'route', index: 0
|
64
|
+
//=> [ '/test/route', 'test', 'route', index: 0 ]
|
67
65
|
```
|
68
66
|
|
69
|
-
|
70
|
-
|
71
|
-
##### Custom Matching Parameters
|
67
|
+
##### Custom matching parameters
|
72
68
|
|
73
69
|
Parameters can have a custom regexp, which overrides the default match (`[^/]+`). For example, you can match digits or names in a path:
|
74
70
|
|
@@ -94,64 +90,49 @@ regexpWord.exec("/users");
|
|
94
90
|
|
95
91
|
**Tip:** Backslashes need to be escaped with another backslash in JavaScript strings.
|
96
92
|
|
97
|
-
|
93
|
+
#### Unnamed parameters
|
98
94
|
|
99
|
-
|
95
|
+
It is possible to define a parameter without a name. The name will be numerically indexed:
|
100
96
|
|
101
97
|
```js
|
102
|
-
const regexp = pathToRegexp("/:
|
103
|
-
|
104
|
-
regexp.exec("/test");
|
105
|
-
// => ['/test', 'test', undefined, undefined]
|
98
|
+
const regexp = pathToRegexp("/:foo/(.*)");
|
99
|
+
// keys = [{ name: 'foo', ... }, { name: '0', ... }]
|
106
100
|
|
107
|
-
regexp.exec("/test
|
108
|
-
|
101
|
+
regexp.exec("/test/route");
|
102
|
+
//=> [ '/test/route', 'test', 'route', index: 0 ]
|
109
103
|
```
|
110
104
|
|
111
|
-
|
105
|
+
##### Custom prefix and suffix
|
112
106
|
|
113
|
-
|
107
|
+
Parameters can be wrapped in `{}` to create custom prefixes or suffixes for your segment:
|
114
108
|
|
115
109
|
```js
|
116
|
-
const regexp = pathToRegexp("/:
|
117
|
-
// keys = [{ name: 'foo', ... }, { name: 0, ... }]
|
110
|
+
const regexp = pathToRegexp("{/:attr1}?{-:attr2}?{-:attr3}?");
|
118
111
|
|
119
|
-
regexp.exec("/test
|
120
|
-
|
112
|
+
regexp.exec("/test");
|
113
|
+
// => ['/test', 'test', undefined, undefined]
|
114
|
+
|
115
|
+
regexp.exec("/test-test");
|
116
|
+
// => ['/test', 'test', 'test', undefined]
|
121
117
|
```
|
122
118
|
|
123
119
|
#### Modifiers
|
124
120
|
|
125
|
-
Modifiers
|
121
|
+
Modifiers are used after parameters with custom prefixes and suffixes (`{}`).
|
126
122
|
|
127
123
|
##### Optional
|
128
124
|
|
129
125
|
Parameters can be suffixed with a question mark (`?`) to make the parameter optional.
|
130
126
|
|
131
127
|
```js
|
132
|
-
const regexp = pathToRegexp("/:foo/:bar?");
|
128
|
+
const regexp = pathToRegexp("/:foo{/:bar}?");
|
133
129
|
// keys = [{ name: 'foo', ... }, { name: 'bar', prefix: '/', modifier: '?' }]
|
134
130
|
|
135
131
|
regexp.exec("/test");
|
136
|
-
//=> [ '/test', 'test', undefined, index: 0
|
132
|
+
//=> [ '/test', 'test', undefined, index: 0 ]
|
137
133
|
|
138
134
|
regexp.exec("/test/route");
|
139
|
-
//=> [ '/test/route', 'test', 'route', index: 0
|
140
|
-
```
|
141
|
-
|
142
|
-
**Tip:** The prefix is also optional, escape the prefix `\/` to make it required.
|
143
|
-
|
144
|
-
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.
|
145
|
-
|
146
|
-
```js
|
147
|
-
const regexp = pathToRegexp("/search/:tableName\\?useIndex=true&term=amazing");
|
148
|
-
|
149
|
-
regexp.exec("/search/people?useIndex=true&term=amazing");
|
150
|
-
//=> [ '/search/people?useIndex=true&term=amazing', 'people', index: 0, input: '/search/people?useIndex=true&term=amazing', groups: undefined ]
|
151
|
-
|
152
|
-
// This library does not handle query strings in different orders
|
153
|
-
regexp.exec("/search/people?term=amazing&useIndex=true");
|
154
|
-
//=> null
|
135
|
+
//=> [ '/test/route', 'test', 'route', index: 0 ]
|
155
136
|
```
|
156
137
|
|
157
138
|
##### Zero or more
|
@@ -159,14 +140,14 @@ regexp.exec("/search/people?term=amazing&useIndex=true");
|
|
159
140
|
Parameters can be suffixed with an asterisk (`*`) to denote a zero or more parameter matches.
|
160
141
|
|
161
142
|
```js
|
162
|
-
const regexp = pathToRegexp("/:foo*");
|
143
|
+
const regexp = pathToRegexp("{/:foo}*");
|
163
144
|
// keys = [{ name: 'foo', prefix: '/', modifier: '*' }]
|
164
145
|
|
165
|
-
regexp.exec("/");
|
166
|
-
//=> [ '/',
|
146
|
+
regexp.exec("/foo");
|
147
|
+
//=> [ '/foo', "foo", index: 0 ]
|
167
148
|
|
168
149
|
regexp.exec("/bar/baz");
|
169
|
-
//=> [ '/bar/baz', 'bar/baz', index: 0
|
150
|
+
//=> [ '/bar/baz', 'bar/baz', index: 0 ]
|
170
151
|
```
|
171
152
|
|
172
153
|
##### One or more
|
@@ -174,165 +155,159 @@ regexp.exec("/bar/baz");
|
|
174
155
|
Parameters can be suffixed with a plus sign (`+`) to denote a one or more parameter matches.
|
175
156
|
|
176
157
|
```js
|
177
|
-
const regexp = pathToRegexp("/:foo+");
|
158
|
+
const regexp = pathToRegexp("{/:foo}+");
|
178
159
|
// keys = [{ name: 'foo', prefix: '/', modifier: '+' }]
|
179
160
|
|
180
161
|
regexp.exec("/");
|
181
162
|
//=> null
|
182
163
|
|
183
164
|
regexp.exec("/bar/baz");
|
184
|
-
//=> [ '/bar/baz','bar/baz', index: 0
|
165
|
+
//=> [ '/bar/baz', 'bar/baz', index: 0 ]
|
185
166
|
```
|
186
167
|
|
187
|
-
|
168
|
+
##### Custom separator
|
188
169
|
|
189
|
-
|
170
|
+
By default, parameters set the separator as the `prefix + suffix` of the token. Using `;` you can modify this:
|
190
171
|
|
191
172
|
```js
|
192
|
-
|
193
|
-
const fn = match("/user/:id", { decode: decodeURIComponent });
|
173
|
+
const regexp = pathToRegexp("/name{/:parts;-}+");
|
194
174
|
|
195
|
-
|
196
|
-
|
197
|
-
|
175
|
+
regexp.exec("/name");
|
176
|
+
//=> null
|
177
|
+
|
178
|
+
regexp.exec("/bar/1-2-3");
|
179
|
+
//=> [ '/name/1-2-3', '1-2-3', index: 0 ]
|
198
180
|
```
|
199
181
|
|
200
|
-
|
182
|
+
#### Wildcard
|
201
183
|
|
202
|
-
|
203
|
-
const urlMatch = match("/users/:id/:tab(home|photos|bio)", {
|
204
|
-
decode: decodeURIComponent,
|
205
|
-
});
|
184
|
+
A wildcard can also be used. It is roughly equivalent to `(.*)`.
|
206
185
|
|
207
|
-
|
208
|
-
|
186
|
+
```js
|
187
|
+
const regexp = pathToRegexp("/*");
|
188
|
+
// keys = [{ name: '0', pattern: '[^\\/]*', separator: '/', modifier: '*' }]
|
209
189
|
|
210
|
-
|
211
|
-
//=>
|
190
|
+
regexp.exec("/");
|
191
|
+
//=> [ '/', '', index: 0 ]
|
212
192
|
|
213
|
-
|
214
|
-
//=>
|
193
|
+
regexp.exec("/bar/baz");
|
194
|
+
//=> [ '/bar/baz', 'bar/baz', index: 0 ]
|
215
195
|
```
|
216
196
|
|
217
|
-
|
197
|
+
### Match
|
198
|
+
|
199
|
+
The `match` function returns a function for transforming paths into parameters:
|
218
200
|
|
219
|
-
|
201
|
+
- **path** A string.
|
202
|
+
- **options** _(optional)_ The same options as `pathToRegexp`, plus:
|
203
|
+
- **decode** Function for decoding strings for params, or `false` to disable entirely. (default: `decodeURIComponent`)
|
220
204
|
|
221
205
|
```js
|
222
|
-
const fn = match("/
|
206
|
+
const fn = match("/user/:id");
|
223
207
|
|
224
|
-
fn("/
|
208
|
+
fn("/user/123"); //=> { path: '/user/123', index: 0, params: { id: '123' } }
|
209
|
+
fn("/invalid"); //=> false
|
210
|
+
fn("/user/caf%C3%A9"); //=> { path: '/user/caf%C3%A9', index: 0, params: { id: 'café' } }
|
225
211
|
```
|
226
212
|
|
227
|
-
**Note:**
|
213
|
+
**Note:** Setting `decode: false` disables the "splitting" behavior of repeated parameters, which is useful if you need the exactly matched parameter back.
|
214
|
+
|
215
|
+
### Compile ("Reverse" Path-To-RegExp)
|
228
216
|
|
229
|
-
|
217
|
+
The `compile` function will return a function for transforming parameters into a valid path:
|
230
218
|
|
231
|
-
|
219
|
+
- **path** A string.
|
220
|
+
- **options** _(optional)_ Similar to `pathToRegexp` (`delimiter`, `encodePath`, `sensitive`, and `loose`), plus:
|
221
|
+
- **validate** When `false` the function can produce an invalid (unmatched) path. (default: `true`)
|
222
|
+
- **encode** Function for encoding input strings for output into the path, or `false` to disable entirely. (default: `encodeURIComponent`)
|
232
223
|
|
233
224
|
```js
|
234
|
-
|
235
|
-
* Normalize a pathname for matching, replaces multiple slashes with a single
|
236
|
-
* slash and normalizes unicode characters to "NFC". When using this method,
|
237
|
-
* `decode` should be an identity function so you don't decode strings twice.
|
238
|
-
*/
|
239
|
-
function normalizePathname(pathname: string) {
|
240
|
-
return (
|
241
|
-
decodeURI(pathname)
|
242
|
-
// Replaces repeated slashes in the URL.
|
243
|
-
.replace(/\/+/g, "/")
|
244
|
-
// Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
|
245
|
-
// Note: Missing native IE support, may want to skip this step.
|
246
|
-
.normalize()
|
247
|
-
);
|
248
|
-
}
|
249
|
-
|
250
|
-
// Two possible ways of writing `/café`:
|
251
|
-
const re = pathToRegexp("/caf\u00E9");
|
252
|
-
const input = encodeURI("/cafe\u0301");
|
253
|
-
|
254
|
-
re.test(input); //=> false
|
255
|
-
re.test(normalizePathname(input)); //=> true
|
256
|
-
```
|
225
|
+
const toPath = compile("/user/:id");
|
257
226
|
|
258
|
-
|
227
|
+
toPath({ id: "name" }); //=> "/user/name"
|
228
|
+
toPath({ id: "café" }); //=> "/user/caf%C3%A9"
|
259
229
|
|
260
|
-
|
230
|
+
// When disabling `encode`, you need to make sure inputs are encoded correctly. No arrays are accepted.
|
231
|
+
const toPathRaw = compile("/user/:id", { encode: false });
|
261
232
|
|
262
|
-
|
263
|
-
|
233
|
+
toPathRaw({ id: "%3A%2F" }); //=> "/user/%3A%2F"
|
234
|
+
toPathRaw({ id: ":/" }); //=> Throws, "/user/:/" when `validate` is `false`.
|
264
235
|
|
265
|
-
|
266
|
-
//=> "/route"
|
236
|
+
const toPathRepeated = compile("{/:segment}+");
|
267
237
|
|
268
|
-
|
269
|
-
|
238
|
+
toPathRepeated({ segment: ["foo"] }); //=> "/foo"
|
239
|
+
toPathRepeated({ segment: ["a", "b", "c"] }); //=> "/a/b/c"
|
270
240
|
|
271
|
-
|
272
|
-
|
241
|
+
const toPathRegexp = compile("/user/:id(\\d+)");
|
242
|
+
|
243
|
+
toPathRegexp({ id: "123" }); //=> "/user/123"
|
273
244
|
```
|
274
245
|
|
275
|
-
|
246
|
+
## Developers
|
276
247
|
|
277
|
-
|
248
|
+
- If you are rewriting paths with match and compiler, consider using `encode: false` and `decode: false` to keep raw paths passed around.
|
249
|
+
- To ensure matches work on paths containing characters usually encoded, consider using [encodeurl](https://github.com/pillarjs/encodeurl) for `encodePath`.
|
250
|
+
- If matches are intended to be exact, you need to set `loose: false`, `trailing: false`, and `sensitive: true`.
|
251
|
+
- Enable `strict: true` to detect ReDOS issues.
|
278
252
|
|
279
|
-
|
253
|
+
### Parse
|
280
254
|
|
281
|
-
|
282
|
-
// Make sure you encode your path segments consistently.
|
283
|
-
const toPath = compile("/user/:id", { encode: encodeURIComponent });
|
255
|
+
A `parse` function is available and returns `TokenData`, the set of tokens and other metadata parsed from the input string. `TokenData` is can passed directly into `pathToRegexp`, `match`, and `compile`. It accepts only two options, `delimiter` and `encodePath`, which makes those options redundant in the above methods.
|
284
256
|
|
285
|
-
|
286
|
-
toPath({ id: "café" }); //=> "/user/caf%C3%A9"
|
287
|
-
toPath({ id: ":/" }); //=> "/user/%3A%2F"
|
257
|
+
### Tokens
|
288
258
|
|
289
|
-
|
290
|
-
// (Note: You can use `validate: false` to create an invalid paths.)
|
291
|
-
const toPathRaw = compile("/user/:id", { validate: false });
|
259
|
+
The `tokens` returned by `TokenData` is an array of strings or keys, represented as objects, with the following properties:
|
292
260
|
|
293
|
-
|
294
|
-
|
261
|
+
- `name` The name of the token
|
262
|
+
- `prefix` _(optional)_ The prefix string for the segment (e.g. `"/"`)
|
263
|
+
- `suffix` _(optional)_ The suffix string for the segment (e.g. `""`)
|
264
|
+
- `pattern` _(optional)_ The pattern defined to match this token
|
265
|
+
- `modifier` _(optional)_ The modifier character used for the segment (e.g. `?`)
|
266
|
+
- `separator` _(optional)_ The string used to separate repeated parameters
|
295
267
|
|
296
|
-
|
268
|
+
### Custom path
|
297
269
|
|
298
|
-
|
299
|
-
toPathRepeated({ segment: ["a", "b", "c"] }); //=> "/a/b/c"
|
270
|
+
In some applications, you may not be able to use the `path-to-regexp` syntax (e.g. file-based routing), but you can still use this library for `match`, `compile`, and `pathToRegexp` by building your own `TokenData` instance. For example:
|
300
271
|
|
301
|
-
|
272
|
+
```js
|
273
|
+
import { TokenData, match } from "path-to-regexp";
|
302
274
|
|
303
|
-
|
304
|
-
|
275
|
+
const tokens = ["/", { name: "foo" }];
|
276
|
+
const path = new TokenData(tokens, "/");
|
277
|
+
const fn = match(path);
|
278
|
+
|
279
|
+
fn("/test"); //=> { path: '/test', index: 0, params: { foo: 'test' } }
|
305
280
|
```
|
306
281
|
|
307
|
-
|
282
|
+
## Errors
|
283
|
+
|
284
|
+
An effort has been made to ensure ambiguous paths from previous releases throw an error. This means you might be seeing an error when things worked before.
|
308
285
|
|
309
|
-
###
|
286
|
+
### Unexpected `?`, `*`, or `+`
|
310
287
|
|
311
|
-
|
288
|
+
In previous major versions `/` and `.` were used as implicit prefixes of parameters. So `/:key?` was implicitly `{/:key}?`. For example:
|
312
289
|
|
313
|
-
-
|
314
|
-
-
|
290
|
+
- `/:key?` → `{/:key}?` or `/:key*` → `{/:key}*` or `/:key+` → `{/:key}+`
|
291
|
+
- `.:key?` → `{.:key}?` or `.:key*` → `{.:key}*` or `.:key+` → `{.:key}+`
|
292
|
+
- `:key?` → `{:key}?` or `:key*` → `{:key}*` or `:key+` → `{:key}+`
|
315
293
|
|
316
|
-
|
294
|
+
### Unexpected `;`
|
317
295
|
|
318
|
-
|
319
|
-
- `prefix` The prefix string for the segment (e.g. `"/"`)
|
320
|
-
- `suffix` The suffix string for the segment (e.g. `""`)
|
321
|
-
- `pattern` The RegExp used to match this token (`string`)
|
322
|
-
- `modifier` The modifier character used for the segment (e.g. `?`)
|
296
|
+
Used as a [custom separator](#custom-separator) for repeated parameters.
|
323
297
|
|
324
|
-
|
298
|
+
### Unexpected `!`, `@`, or `,`
|
325
299
|
|
326
|
-
|
300
|
+
These characters have been reserved for future use.
|
327
301
|
|
328
|
-
|
329
|
-
- Express.js 4.x supported `RegExp` special characters regardless of position - this is considered a bug
|
330
|
-
- Parameters have suffixes that augment meaning - `*`, `+` and `?`. E.g. `/:user*`
|
331
|
-
- No wildcard asterisk (`*`) - use parameters instead (`(.*)` or `:splat*`)
|
302
|
+
### Express <= 4.x
|
332
303
|
|
333
|
-
|
304
|
+
Path-To-RegExp breaks compatibility with Express <= `4.x` in the following ways:
|
334
305
|
|
335
|
-
|
306
|
+
- The only part of the string that is a regex is within `()`.
|
307
|
+
- In Express.js 4.x, everything was passed as-is after a simple replacement, so you could write `/[a-z]+` to match `/test`.
|
308
|
+
- The `?` optional character must be used after `{}`.
|
309
|
+
- Some characters have new meaning or have been reserved (`{}?*+@!;`).
|
310
|
+
- The parameter name now supports all unicode identifier characters, previously it was only `[a-z0-9]`.
|
336
311
|
|
337
312
|
## License
|
338
313
|
|