Skip to content

Commit 44c69d5

Browse files
authored
Enable a default delimiter for parsing behaviour (#94)
1 parent 9932d18 commit 44c69d5

File tree

4 files changed

+132
-29
lines changed

4 files changed

+132
-29
lines changed

Readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var pathToRegexp = require('path-to-regexp')
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: `'/'`)
3435

3536
```javascript
3637
var keys = []

index.d.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,43 @@
1-
declare function pathToRegexp (path: pathToRegexp.Path, options?: pathToRegexp.Options): pathToRegexp.PathRegExp;
2-
declare function pathToRegexp (path: pathToRegexp.Path, keys?: pathToRegexp.Key[], options?: pathToRegexp.Options): pathToRegexp.PathRegExp;
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;
33

44
declare namespace pathToRegexp {
55
export interface PathRegExp extends RegExp {
66
// An array to be populated with the keys found in the path.
77
keys: Key[];
88
}
99

10-
export interface Options {
11-
// When `true` the route will be case sensitive. (default: `false`)
10+
export interface RegExpOptions {
11+
/**
12+
* When `true` the route will be case sensitive. (default: `false`)
13+
*/
1214
sensitive?: boolean;
13-
// When `false` the trailing slash is optional. (default: `false`)
15+
/**
16+
* When `false` the trailing slash is optional. (default: `false`)
17+
*/
1418
strict?: boolean;
15-
// When `false` the path will match at the beginning. (default: `true`)
19+
/**
20+
* When `false` the path will match at the beginning. (default: `true`)
21+
*/
1622
end?: boolean;
1723
}
1824

25+
export interface ParseOptions {
26+
/**
27+
* Set the default delimiter for repeat parameters. (default: `'/'`)
28+
*/
29+
delimiter?: string;
30+
}
31+
1932
/**
2033
* Parse an Express-style path into an array of tokens.
2134
*/
22-
export function parse (path: string): Token[];
35+
export function parse (path: string, options?: ParseOptions): Token[];
2336

2437
/**
2538
* Transforming an Express-style path into a valid path.
2639
*/
27-
export function compile (path: string): PathFunction;
40+
export function compile (path: string, options?: ParseOptions): PathFunction;
2841

2942
/**
3043
* Transform an array of tokens into a path generator function.
@@ -34,8 +47,8 @@ declare namespace pathToRegexp {
3447
/**
3548
* Transform an array of tokens into a matching regular expression.
3649
*/
37-
export function tokensToRegExp (tokens: Token[], options?: Options): PathRegExp;
38-
export function tokensToRegExp (tokens: Token[], keys?: Key[], options?: Options): PathRegExp;
50+
export function tokensToRegExp (tokens: Token[], options?: RegExpOptions): PathRegExp;
51+
export function tokensToRegExp (tokens: Token[], keys?: Key[], options?: RegExpOptions): PathRegExp;
3952

4053
export interface Key {
4154
name: string | number;

index.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@ var PATH_REGEXP = new RegExp([
3030
/**
3131
* Parse a string for the raw tokens.
3232
*
33-
* @param {string} str
33+
* @param {string} str
34+
* @param {Object=} options
3435
* @return {!Array}
3536
*/
36-
function parse (str) {
37+
function parse (str, options) {
3738
var tokens = []
3839
var key = 0
3940
var index = 0
4041
var path = ''
42+
var defaultDelimiter = options && options.delimiter || '/'
4143
var res
4244

4345
while ((res = PATH_REGEXP.exec(str)) != null) {
@@ -70,8 +72,8 @@ function parse (str) {
7072
var partial = prefix != null && next != null && next !== prefix
7173
var repeat = modifier === '+' || modifier === '*'
7274
var optional = modifier === '?' || modifier === '*'
73-
var delimiter = res[2] || '/'
74-
var pattern = capture || group || (asterisk ? '.*' : '[^' + delimiter + ']+?')
75+
var delimiter = res[2] || defaultDelimiter
76+
var pattern = capture || group
7577

7678
tokens.push({
7779
name: name || key++,
@@ -81,7 +83,7 @@ function parse (str) {
8183
repeat: repeat,
8284
partial: partial,
8385
asterisk: !!asterisk,
84-
pattern: escapeGroup(pattern)
86+
pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')
8587
})
8688
}
8789

@@ -102,10 +104,11 @@ function parse (str) {
102104
* Compile a string to a template function for the path.
103105
*
104106
* @param {string} str
107+
* @param {Object=} options
105108
* @return {!function(Object=, Object=)}
106109
*/
107-
function compile (str) {
108-
return tokensToFunction(parse(str))
110+
function compile (str, options) {
111+
return tokensToFunction(parse(str, options))
109112
}
110113

111114
/**
@@ -316,7 +319,7 @@ function arrayToRegexp (path, keys, options) {
316319
* @return {!RegExp}
317320
*/
318321
function stringToRegexp (path, keys, options) {
319-
return tokensToRegExp(parse(path), keys, options)
322+
return tokensToRegExp(parse(path, options), keys, options)
320323
}
321324

322325
/**

test.ts

Lines changed: 97 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const expect = chai.expect
1010

1111
type Test = [
1212
pathToRegexp.Path,
13-
pathToRegexp.Options,
13+
pathToRegexp.RegExpOptions & pathToRegexp.ParseOptions,
1414
pathToRegexp.Token[],
1515
Array<[string, string[]]>,
1616
Array<[any, string]>
@@ -1122,7 +1122,7 @@ var TESTS: Test[] = [
11221122
repeat: false,
11231123
partial: false,
11241124
asterisk: false,
1125-
pattern: '[^.]+?'
1125+
pattern: '[^\\.]+?'
11261126
}
11271127
],
11281128
[
@@ -1148,7 +1148,7 @@ var TESTS: Test[] = [
11481148
repeat: false,
11491149
partial: false,
11501150
asterisk: false,
1151-
pattern: '[^.]+?'
1151+
pattern: '[^\\.]+?'
11521152
},
11531153
{
11541154
name: 'format',
@@ -1158,7 +1158,7 @@ var TESTS: Test[] = [
11581158
repeat: false,
11591159
partial: false,
11601160
asterisk: false,
1161-
pattern: '[^.]+?'
1161+
pattern: '[^\\.]+?'
11621162
}
11631163
],
11641164
[
@@ -1183,7 +1183,7 @@ var TESTS: Test[] = [
11831183
repeat: true,
11841184
partial: false,
11851185
asterisk: false,
1186-
pattern: '[^.]+?'
1186+
pattern: '[^\\.]+?'
11871187
}
11881188
],
11891189
[
@@ -1211,7 +1211,7 @@ var TESTS: Test[] = [
12111211
repeat: false,
12121212
partial: false,
12131213
asterisk: false,
1214-
pattern: '[^.]+?'
1214+
pattern: '[^\\.]+?'
12151215
}
12161216
],
12171217
[
@@ -1235,7 +1235,7 @@ var TESTS: Test[] = [
12351235
repeat: false,
12361236
partial: false,
12371237
asterisk: false,
1238-
pattern: '[^.]+?'
1238+
pattern: '[^\\.]+?'
12391239
},
12401240
'.'
12411241
],
@@ -1274,7 +1274,7 @@ var TESTS: Test[] = [
12741274
repeat: false,
12751275
partial: false,
12761276
asterisk: false,
1277-
pattern: '[^.]+?'
1277+
pattern: '[^\\.]+?'
12781278
}
12791279
],
12801280
[
@@ -1309,7 +1309,7 @@ var TESTS: Test[] = [
13091309
repeat: false,
13101310
partial: false,
13111311
asterisk: false,
1312-
pattern: '[^.]+?'
1312+
pattern: '[^\\.]+?'
13131313
}
13141314
],
13151315
[
@@ -1347,7 +1347,7 @@ var TESTS: Test[] = [
13471347
repeat: false,
13481348
partial: false,
13491349
asterisk: false,
1350-
pattern: '[^.]+?'
1350+
pattern: '[^\\.]+?'
13511351
}
13521352
],
13531353
[
@@ -2135,6 +2135,92 @@ var TESTS: Test[] = [
21352135
[
21362136
[{ foo: 'café' }, '/caf%C3%A9']
21372137
]
2138+
],
2139+
2140+
/**
2141+
* Hostnames.
2142+
*/
2143+
[
2144+
':domain.com',
2145+
{
2146+
delimiter: '.'
2147+
},
2148+
[
2149+
{
2150+
name: 'domain',
2151+
prefix: '',
2152+
delimiter: '.',
2153+
optional: false,
2154+
repeat: false,
2155+
partial: false,
2156+
asterisk: false,
2157+
pattern: '[^\\.]+?'
2158+
},
2159+
'.com'
2160+
],
2161+
[
2162+
['example.com', ['example.com', 'example']],
2163+
['github.com', ['github.com', 'github']],
2164+
],
2165+
[
2166+
[{ domain: 'example' }, 'example.com'],
2167+
[{ domain: 'github' }, 'github.com']
2168+
]
2169+
],
2170+
[
2171+
'mail.:domain.com',
2172+
{
2173+
delimiter: '.'
2174+
},
2175+
[
2176+
'mail',
2177+
{
2178+
name: 'domain',
2179+
prefix: '.',
2180+
delimiter: '.',
2181+
optional: false,
2182+
repeat: false,
2183+
partial: false,
2184+
asterisk: false,
2185+
pattern: '[^\\.]+?'
2186+
},
2187+
'.com'
2188+
],
2189+
[
2190+
['mail.example.com', ['mail.example.com', 'example']],
2191+
['mail.github.com', ['mail.github.com', 'github']]
2192+
],
2193+
[
2194+
[{ domain: 'example' }, 'mail.example.com'],
2195+
[{ domain: 'github' }, 'mail.github.com']
2196+
]
2197+
],
2198+
[
2199+
'example.:ext',
2200+
{
2201+
delimiter: '.'
2202+
},
2203+
[
2204+
'example',
2205+
{
2206+
name: 'ext',
2207+
prefix: '.',
2208+
delimiter: '.',
2209+
optional: false,
2210+
repeat: false,
2211+
partial: false,
2212+
asterisk: false,
2213+
pattern: '[^\\.]+?'
2214+
}
2215+
],
2216+
[
2217+
['example.com', ['example.com', 'com']],
2218+
['example.org', ['example.org', 'org']],
2219+
],
2220+
[
2221+
[{ ext: 'com' }, 'example.com'],
2222+
[{ ext: 'org' }, 'example.org']
2223+
]
21382224
]
21392225
]
21402226

@@ -2224,7 +2310,7 @@ describe('path-to-regexp', function () {
22242310
// Parsing and compiling is only supported with string input.
22252311
if (typeof path === 'string') {
22262312
it('should parse', function () {
2227-
expect(pathToRegexp.parse(path)).to.deep.equal(tokens)
2313+
expect(pathToRegexp.parse(path, opts)).to.deep.equal(tokens)
22282314
})
22292315

22302316
describe('compile', function () {

0 commit comments

Comments
 (0)