Skip to content

Commit 9d4cbd9

Browse files
authored
Major changes (pillarjs#114)
* New option! Ability to set `endsWith` to match paths like `/test?query=string` up to the query string * New option! Set `delimiters` for specific characters to be treated as parameter prefixes (e.g. `/:test`) * Remove `isarray` dependency * Explicitly handle trailing delimiters instead of trimming them (e.g. `/test/` is now treated as `/test/` instead of `/test` when matching) * Remove overloaded `keys` argument that accepted `options` * Remove `keys` list attached to the `RegExp` output * Remove asterisk functionality (it's a real pain to properly encode) * Change `tokensToFunction` (e.g. `compile`) to accept an `encode` function for pretty encoding (e.g. pass your own implementation)
1 parent e97122d commit 9d4cbd9

File tree

7 files changed

+294
-411
lines changed

7 files changed

+294
-411
lines changed

.travis.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1+
sudo: false
12
language: node_js
23

34
node_js:
4-
- "0.10"
5-
- "0.12"
65
- "4.0"
7-
- "4.1"
6+
- "stable"
87

98
after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls"

Readme.md

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Path-to-RegExp
22

3-
> Turn an Express-style path string such as `/user/:name` into a regular expression.
3+
> Turn a path string such as `/user/:name` into a regular expression.
44
55
[![NPM version][npm-image]][npm-url]
66
[![Build status][travis-image]][travis-url]
@@ -20,18 +20,21 @@ npm install path-to-regexp --save
2020
```javascript
2121
var pathToRegexp = require('path-to-regexp')
2222

23-
// pathToRegexp(path, keys, options)
23+
// pathToRegexp(path, keys?, options?)
2424
// pathToRegexp.parse(path)
2525
// pathToRegexp.compile(path)
2626
```
2727

28-
- **path** An Express-style string, an array of strings, or a regular expression.
28+
- **path** A string, array of strings, or a regular expression.
2929
- **keys** An array to be populated with the keys found in the path.
3030
- **options**
3131
- **sensitive** When `true` the route will be case sensitive. (default: `false`)
3232
- **strict** When `false` the trailing slash is optional. (default: `false`)
3333
- **end** When `false` the path will match at the beginning. (default: `true`)
34-
- **delimiter** Set the default delimiter for repeat parameters. (default: `'/'`)
34+
- Advanced options (use for non-pathname strings, e.g. host names):
35+
- **delimiter** The default delimiter for segments. (default: `'/'`)
36+
- **endsWith** Optional character, or list of characters, to treat as "end" characters.
37+
- **delimiters** List of characters to consider delimiters when parsing. (default: `'./'`)
3538

3639
```javascript
3740
var keys = []
@@ -40,18 +43,18 @@ var re = pathToRegexp('/foo/:bar', keys)
4043
// keys = [{ name: 'bar', prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '[^\\/]+?' }]
4144
```
4245

43-
**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.
46+
**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).
4447

4548
### Parameters
4649

47-
The path string can be used to define parameters and populate the keys.
50+
The path argument is used to define parameters and populate the list of keys.
4851

4952
#### Named Parameters
5053

5154
Named parameters are defined by prefixing a colon to the parameter name (`:foo`). By default, the parameter will match until the following path segment.
5255

5356
```js
54-
var re = pathToRegexp('/:foo/:bar', keys)
57+
var re = pathToRegexp('/:foo/:bar')
5558
// keys = [{ name: 'foo', prefix: '/', ... }, { name: 'bar', prefix: '/', ... }]
5659

5760
re.exec('/test/route')
@@ -61,21 +64,21 @@ re.exec('/test/route')
6164
**Please note:** Named parameters must be made up of "word characters" (`[A-Za-z0-9_]`).
6265

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

6770
re.exec('/icon-76.png')
6871
//=> ['/icon-76.png', undefined, '76']
6972
```
7073

71-
#### Modified Parameters
74+
#### Parameter Modifiers
7275

7376
##### Optional
7477

75-
Parameters can be suffixed with a question mark (`?`) to make the parameter optional. This will also make the prefix optional.
78+
Parameters can be suffixed with a question mark (`?`) to make the parameter optional.
7679

7780
```js
78-
var re = pathToRegexp('/:foo/:bar?', keys)
81+
var re = pathToRegexp('/:foo/:bar?')
7982
// keys = [{ name: 'foo', ... }, { name: 'bar', delimiter: '/', optional: true, repeat: false }]
8083

8184
re.exec('/test')
@@ -85,12 +88,14 @@ re.exec('/test/route')
8588
//=> ['/test', 'test', 'route']
8689
```
8790

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

9095
Parameters can be suffixed with an asterisk (`*`) to denote a zero or more parameter matches. The prefix is taken into account for each match.
9196

9297
```js
93-
var re = pathToRegexp('/:foo*', keys)
98+
var re = pathToRegexp('/:foo*')
9499
// keys = [{ name: 'foo', delimiter: '/', optional: true, repeat: true }]
95100

96101
re.exec('/')
@@ -105,7 +110,7 @@ re.exec('/bar/baz')
105110
Parameters can be suffixed with a plus sign (`+`) to denote a one or more parameter matches. The prefix is taken into account for each match.
106111

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

111116
re.exec('/')
@@ -120,7 +125,7 @@ re.exec('/bar/baz')
120125
All parameters can be provided a custom regexp, which overrides the default (`[^\/]+`).
121126

122127
```js
123-
var re = pathToRegexp('/:foo(\\d+)', keys)
128+
var re = pathToRegexp('/:foo(\\d+)')
124129
// keys = [{ name: 'foo', ... }]
125130

126131
re.exec('/123')
@@ -137,25 +142,13 @@ re.exec('/abc')
137142
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.
138143

139144
```js
140-
var re = pathToRegexp('/:foo/(.*)', keys)
145+
var re = pathToRegexp('/:foo/(.*)')
141146
// keys = [{ name: 'foo', ... }, { name: 0, ... }]
142147

143148
re.exec('/test/route')
144149
//=> ['/test/route', 'test', 'route']
145150
```
146151

147-
#### Asterisk
148-
149-
An asterisk can be used for matching everything. It is equivalent to an unnamed matching group of `(.*)`.
150-
151-
```js
152-
var re = pathToRegexp('/foo/*', keys)
153-
// keys = [{ name: '0', ... }]
154-
155-
re.exec('/foo/bar/baz')
156-
//=> ['/foo/bar/baz', 'bar/baz']
157-
```
158-
159152
### Parse
160153

161154
The parse function is exposed via `pathToRegexp.parse`. This will return an array of strings and keys.
@@ -173,11 +166,11 @@ console.log(tokens[2])
173166
//=> { name: 0, prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '.*' }
174167
```
175168

176-
**Note:** This method only works with Express-style strings.
169+
**Note:** This method only works with strings.
177170

178171
### Compile ("Reverse" Path-To-RegExp)
179172

180-
Path-To-RegExp exposes a compile function for transforming an Express-style path into a valid path.
173+
Path-To-RegExp exposes a compile function for transforming a string into a valid path.
181174

182175
```js
183176
var toPath = pathToRegexp.compile('/user/:id')
@@ -186,8 +179,8 @@ toPath({ id: 123 }) //=> "/user/123"
186179
toPath({ id: 'café' }) //=> "/user/caf%C3%A9"
187180
toPath({ id: '/' }) //=> "/user/%2F"
188181

189-
toPath({ id: ':' }) //=> "/user/%3A"
190-
toPath({ id: ':' }, { pretty: true }) //=> "/user/:"
182+
toPath({ id: ':/' }) //=> "/user/%3A%2F"
183+
toPath({ id: ':/' }, { encode: (x) => x }) //=> "/user/:/"
191184

192185
var toPathRepeated = pathToRegexp.compile('/:segment+')
193186

@@ -219,17 +212,15 @@ Path-To-RegExp exposes the two functions used internally that accept an array of
219212
* `repeat` Indicates the token is repeated (`boolean`)
220213
* `partial` Indicates this token is a partial path segment (`boolean`)
221214
* `pattern` The RegExp used to match this token (`string`)
222-
* `asterisk` Indicates the token is an `*` match (`boolean`)
223215

224216
## Compatibility with Express <= 4.x
225217

226218
Path-To-RegExp breaks compatibility with Express <= `4.x`:
227219

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

234225
## TypeScript
235226

index.d.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
declare function pathToRegexp (path: pathToRegexp.Path, options?: pathToRegexp.RegExpOptions & pathToRegexp.ParseOptions): pathToRegexp.PathRegExp;
2-
declare function pathToRegexp (path: pathToRegexp.Path, keys?: pathToRegexp.Key[], options?: pathToRegexp.RegExpOptions & pathToRegexp.ParseOptions): pathToRegexp.PathRegExp;
1+
declare function pathToRegexp (path: pathToRegexp.Path, keys?: pathToRegexp.Key[], options?: pathToRegexp.RegExpOptions & pathToRegexp.ParseOptions): RegExp;
32

43
declare namespace pathToRegexp {
5-
export interface PathRegExp extends RegExp {
6-
// An array to be populated with the keys found in the path.
7-
keys: Key[];
8-
}
9-
104
export interface RegExpOptions {
115
/**
126
* When `true` the route will be case sensitive. (default: `false`)
@@ -24,13 +18,21 @@ declare namespace pathToRegexp {
2418
* Sets the final character for non-ending optimistic matches. (default: `/`)
2519
*/
2620
delimiter?: string;
21+
/**
22+
* List of characters that can also be "end" characters.
23+
*/
24+
endsWith?: string | string[];
2725
}
2826

2927
export interface ParseOptions {
3028
/**
3129
* Set the default delimiter for repeat parameters. (default: `'/'`)
3230
*/
3331
delimiter?: string;
32+
/**
33+
* List of valid delimiter characters. (default: `'./'`)
34+
*/
35+
delimiters?: string | string[];
3436
}
3537

3638
/**
@@ -51,8 +53,7 @@ declare namespace pathToRegexp {
5153
/**
5254
* Transform an array of tokens into a matching regular expression.
5355
*/
54-
export function tokensToRegExp (tokens: Token[], options?: RegExpOptions): PathRegExp;
55-
export function tokensToRegExp (tokens: Token[], keys?: Key[], options?: RegExpOptions): PathRegExp;
56+
export function tokensToRegExp (tokens: Token[], keys?: Key[], options?: RegExpOptions): RegExp;
5657

5758
export interface Key {
5859
name: string | number;
@@ -62,11 +63,13 @@ declare namespace pathToRegexp {
6263
repeat: boolean;
6364
pattern: string;
6465
partial: boolean;
65-
asterisk: boolean;
6666
}
6767

6868
interface PathFunctionOptions {
69-
pretty?: boolean;
69+
/**
70+
* Function for encoding input strings for output.
71+
*/
72+
encode?: (value: string) => string;
7073
}
7174

7275
export type Token = string | Key;

0 commit comments

Comments
 (0)