Skip to content

Commit 438447a

Browse files
committed
Merge pull request #51 from chrisinajar/0.1.x
Add "index" field to keys to account for extra wildcard groups
2 parents 66f8d3f + f63aafd commit 438447a

File tree

2 files changed

+105
-4
lines changed

2 files changed

+105
-4
lines changed

index.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ function pathtoRegexp(path, keys, options) {
2525
var strict = options.strict;
2626
var end = options.end !== false;
2727
var flags = options.sensitive ? '' : 'i';
28+
var index = 0;
29+
var extraOffset = 0;
2830
keys = keys || [];
2931

3032
if (path instanceof RegExp) {
@@ -45,23 +47,38 @@ function pathtoRegexp(path, keys, options) {
4547
path = ('^' + path + (strict ? '' : path[path.length - 1] === '/' ? '?' : '/?'))
4648
.replace(/\/\(/g, '/(?:')
4749
.replace(/([\/\.])/g, '\\$1')
48-
.replace(/(\\\/)?(\\\.)?:(\w+)(\(.*?\))?(\*)?(\?)?/g, function (match, slash, format, key, capture, star, optional) {
50+
.replace(/(\\\/)?(\\\.)?:(\w+)(\(.*?\))?(\*)?(\?)?/g, function (match, slash, format, key, capture, star, optional, offset) {
4951
slash = slash || '';
5052
format = format || '';
5153
capture = capture || '([^\\/' + format + ']+?)';
5254
optional = optional || '';
5355

54-
keys.push({ name: key, optional: !!optional });
56+
keys.push({
57+
name: key,
58+
optional: !!optional,
59+
index: index++,
60+
_offset: offset + extraOffset
61+
});
5562

56-
return ''
63+
var result = ''
5764
+ (optional ? '' : slash)
5865
+ '(?:'
5966
+ format + (optional ? slash : '') + capture
6067
+ (star ? '((?:[\\/' + format + '].+?)?)' : '')
6168
+ ')'
6269
+ optional;
70+
extraOffset += result.length - match.length;
71+
72+
return result;
6373
})
64-
.replace(/\*/g, '(.*)');
74+
.replace(/\*/g, function(star, index) {
75+
keys.forEach(function(key) {
76+
if (index < key._offset) {
77+
key.index++;
78+
}
79+
});
80+
return '(.*)';
81+
});
6582

6683
// If the path is non-ending, match until the end or a slash.
6784
path += (end ? '$' : (path[path.length - 1] === '/' ? '' : '(?=\\/|$)'));

test.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,90 @@ describe('path-to-regexp', function () {
4646
assert.ok(!m);
4747
});
4848

49+
it('should match wildcards', function () {
50+
var params = [];
51+
var m = pathToRegExp('/*', params).exec('/pathname');
52+
53+
assert.equal(params.length, 0);
54+
55+
assert.equal(m.length, 2);
56+
assert.equal(m[0], '/pathname');
57+
assert.equal(m[1], 'pathname');
58+
});
59+
60+
it('should match wildcards without leading /', function () {
61+
var params = [];
62+
var m = pathToRegExp('*', params).exec('/pathname');
63+
64+
assert.equal(params.length, 0);
65+
66+
assert.equal(m.length, 2);
67+
assert.equal(m[0], '/pathname');
68+
assert.equal(m[1], '/pathname');
69+
});
70+
71+
it('should match wildcards with express params', function () {
72+
var params = [];
73+
var m = pathToRegExp('/:test/*', params).exec('/pathone/pathtwo');
74+
75+
assert.equal(params.length, 1);
76+
assert.equal(params[0].name, 'test');
77+
assert.equal(params[0].optional, false);
78+
assert.equal(params[0].index, 0);
79+
80+
assert.equal(m.length, 3);
81+
assert.equal(m[0], '/pathone/pathtwo');
82+
assert.equal(m[1], 'pathone');
83+
assert.equal(m[2], 'pathtwo');
84+
});
85+
86+
it('should match wildcards with express params (reverse order)', function () {
87+
var params = [];
88+
var m = pathToRegExp('/*/:test', params).exec('/pathone/pathtwo');
89+
90+
assert.equal(params.length, 1);
91+
assert.equal(params[0].name, 'test');
92+
assert.equal(params[0].optional, false);
93+
assert.equal(params[0].index, 1);
94+
95+
assert.equal(m.length, 3);
96+
assert.equal(m[0], '/pathone/pathtwo');
97+
assert.equal(m[1], 'pathone');
98+
assert.equal(m[2], 'pathtwo');
99+
});
100+
101+
it('should match wildcards with express params (reverse order, no leading /)', function () {
102+
var params = [];
103+
var m = pathToRegExp('*/:test', params).exec('/pathone/pathtwo');
104+
105+
assert.equal(params.length, 1);
106+
assert.equal(params[0].name, 'test');
107+
assert.equal(params[0].optional, false);
108+
assert.equal(params[0].index, 1);
109+
110+
assert.equal(m.length, 3);
111+
assert.equal(m[0], '/pathone/pathtwo');
112+
assert.equal(m[1], '/pathone');
113+
assert.equal(m[2], 'pathtwo');
114+
});
115+
116+
it('should have proper indexes when using multiple wildcards', function () {
117+
var params = [];
118+
var m = pathToRegExp('*/:test/*/:foo/*/:bar/*', params).exec('/a/b/c/d/e/f/g');
119+
120+
assert.equal(params.length, 3);
121+
assert.equal(params[0].name, 'test');
122+
assert.equal(params[0].optional, false);
123+
assert.equal(params[0].index, 1);
124+
125+
assert.equal(params[1].name, 'foo');
126+
assert.equal(params[1].index, 3);
127+
128+
assert.equal(params[2].name, 'bar');
129+
assert.equal(params[2].index, 5);
130+
131+
});
132+
49133
it('should do strict matches with trailing slashes', function () {
50134
var params = [];
51135
var re = pathToRegExp('/:test/', params, { strict: true });

0 commit comments

Comments
 (0)