Skip to content

Commit 4357077

Browse files
committed
WIP: v8
1 parent e14430a commit 4357077

File tree

7 files changed

+470
-490
lines changed

7 files changed

+470
-490
lines changed

index.js

+7-8
Original file line numberDiff line numberDiff line change
@@ -596,10 +596,9 @@ function processParams (params, layer, called, req, res, done) {
596596

597597
paramIndex = 0
598598
key = keys[i++]
599-
name = key.name
600-
paramVal = req.params[name]
601-
paramCallbacks = params[name]
602-
paramCalled = called[name]
599+
paramVal = req.params[key]
600+
paramCallbacks = params[key]
601+
paramCalled = called[key]
603602

604603
if (paramVal === undefined || !paramCallbacks) {
605604
return param()
@@ -609,13 +608,13 @@ function processParams (params, layer, called, req, res, done) {
609608
if (paramCalled && (paramCalled.match === paramVal ||
610609
(paramCalled.error && paramCalled.error !== 'route'))) {
611610
// restore value
612-
req.params[name] = paramCalled.value
611+
req.params[key] = paramCalled.value
613612

614613
// next param
615614
return param(paramCalled.error)
616615
}
617616

618-
called[name] = paramCalled = {
617+
called[key] = paramCalled = {
619618
error: null,
620619
match: paramVal,
621620
value: paramVal
@@ -629,7 +628,7 @@ function processParams (params, layer, called, req, res, done) {
629628
var fn = paramCallbacks[paramIndex++]
630629

631630
// store updated value
632-
paramCalled.value = req.params[key.name]
631+
paramCalled.value = req.params[key]
633632

634633
if (err) {
635634
// store error
@@ -641,7 +640,7 @@ function processParams (params, layer, called, req, res, done) {
641640
if (!fn) return param()
642641

643642
try {
644-
var ret = fn(req, res, paramCallback, paramVal, key.name)
643+
var ret = fn(req, res, paramCallback, paramVal, key)
645644
if (isPromise(ret)) {
646645
ret.then(null, function (error) {
647646
paramCallback(error || new Error('Rejected promise'))

lib/layer.js

+58-25
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ var pathRegexp = require('path-to-regexp')
2020
* @private
2121
*/
2222

23-
var hasOwnProperty = Object.prototype.hasOwnProperty
2423
var TRAILING_SLASH_REGEXP = /\/+$/
24+
var MATCHING_GROUP_REGEXP = /\((?:\?<(.*?)>)?(?!\?)/g
2525

2626
/**
2727
* Expose `Layer`.
@@ -41,10 +41,53 @@ function Layer (path, options, fn) {
4141
this.name = fn.name || '<anonymous>'
4242
this.params = undefined
4343
this.path = undefined
44-
this.regexp = pathRegexp((opts.strict ? path : loosen(path)), this.keys, opts)
44+
this.slash = path === '/' && opts.end === false
45+
46+
function matcher (_path) {
47+
if (_path instanceof RegExp) {
48+
debugger
49+
var keys = []
50+
var name = 0
51+
var m
52+
while (m = MATCHING_GROUP_REGEXP.exec(_path.source)) {
53+
keys.push({
54+
name: m[1] || name++,
55+
offset: m.index
56+
})
57+
}
58+
59+
return function regexpMatcher (p) {
60+
var match = _path.exec(p)
61+
if (!match) {
62+
return false
63+
}
64+
65+
var params = {}
66+
for (var i = 1; i < match.length; i++) {
67+
var key = keys[i - 1]
68+
var prop = key.name
69+
var val = decodeParam(match[i])
70+
71+
if (val !== undefined || !(hasOwnProperty.call(params, prop))) {
72+
params[prop] = val
73+
}
74+
}
75+
76+
return {
77+
params: params,
78+
path: p
79+
}
80+
}
81+
}
4582

46-
// set fast path flags
47-
this.regexp._slash = path === '/' && opts.end === false
83+
return pathRegexp.match((opts.strict ? _path : loosen(_path)), {
84+
sensitive: opts.sensitive,
85+
end: opts.end,
86+
trailing: !opts.strict,
87+
decode: decodeParam
88+
})
89+
}
90+
this.matchers = Array.isArray(path) ? path.map(matcher) : [matcher(path)]
4891
}
4992

5093
/**
@@ -123,17 +166,20 @@ Layer.prototype.handleRequest = function handleRequest (req, res, next) {
123166

124167
Layer.prototype.match = function match (path) {
125168
var match
126-
127169
if (path != null) {
128170
// fast path non-ending match for / (any path matches)
129-
if (this.regexp._slash) {
171+
if (this.slash) {
130172
this.params = {}
131173
this.path = ''
132174
return true
133175
}
134176

135-
// match the path
136-
match = this.regexp.exec(path)
177+
var i = 0;
178+
while (!match && i < this.matchers.length) {
179+
// match the path
180+
match = this.matchers[i](path)
181+
i++;
182+
}
137183
}
138184

139185
if (!match) {
@@ -143,22 +189,9 @@ Layer.prototype.match = function match (path) {
143189
}
144190

145191
// store values
146-
this.params = {}
147-
this.path = match[0]
148-
149-
// iterate matches
150-
var keys = this.keys
151-
var params = this.params
152-
153-
for (var i = 1; i < match.length; i++) {
154-
var key = keys[i - 1]
155-
var prop = key.name
156-
var val = decodeParam(match[i])
157-
158-
if (val !== undefined || !(hasOwnProperty.call(params, prop))) {
159-
params[prop] = val
160-
}
161-
}
192+
this.params = match.params
193+
this.path = match.path
194+
this.keys = Object.keys(match.params)
162195

163196
return true
164197
}
@@ -192,7 +225,7 @@ function decodeParam (val) {
192225
* Loosens the given path for path-to-regexp matching.
193226
*/
194227
function loosen (path) {
195-
if (path instanceof RegExp) {
228+
if (path instanceof RegExp || path === '/') {
196229
return path
197230
}
198231

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"finalhandler": "1.2.0",
3030
"mocha": "10.2.0",
3131
"nyc": "15.1.0",
32+
"run-series": "^1.1.9",
3233
"safe-buffer": "5.2.1",
3334
"supertest": "6.3.3"
3435
},
@@ -46,6 +47,7 @@
4647
"scripts": {
4748
"lint": "eslint .",
4849
"test": "mocha --reporter spec --bail --check-leaks test/",
50+
"test:debug": "mocha --reporter spec --bail --check-leaks test/ --inspect --inspect-brk",
4951
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
5052
"test-cov": "nyc --reporter=text npm test",
5153
"version": "node scripts/version-history.js && git add HISTORY.md"

test/param.js

+18-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
var after = require('after')
3+
var series = require('run-series')
34
var Router = require('..')
45
var utils = require('./support/utils')
56

@@ -300,7 +301,6 @@ describe('Router', function () {
300301

301302
describe('next("route")', function () {
302303
it('should cause route with param to be skipped', function (done) {
303-
var cb = after(3, done)
304304
var router = new Router()
305305
var server = createServer(router)
306306

@@ -326,17 +326,23 @@ describe('Router', function () {
326326
res.end('cannot get a new user')
327327
})
328328

329-
request(server)
330-
.get('/user/2')
331-
.expect(200, 'get user 2', cb)
332-
333-
request(server)
334-
.get('/user/bob')
335-
.expect(404, cb)
336-
337-
request(server)
338-
.get('/user/new')
339-
.expect(400, 'cannot get a new user', cb)
329+
series([
330+
function (cb) {
331+
request(server)
332+
.get('/user/2')
333+
.expect(200, 'get user 2', cb)
334+
},
335+
function (cb) {
336+
request(server)
337+
.get('/user/bob')
338+
.expect(404, cb)
339+
},
340+
function (cb) {
341+
request(server)
342+
.get('/user/new')
343+
.expect(400, 'cannot get a new user', cb)
344+
}
345+
], done)
340346
})
341347

342348
it('should invoke fn if path value differs', function (done) {

test/req.params.js

-40
Original file line numberDiff line numberDiff line change
@@ -124,46 +124,6 @@ describe('req.params', function () {
124124
.expect('x-params-1', '{"foo":"buzz"}')
125125
.expect(200, '{"foo":"bar"}', done)
126126
})
127-
128-
describe('with numeric properties in req.params', function () {
129-
it('should merge numeric properties by offsetting', function (done) {
130-
var router = Router({ mergeParams: true })
131-
var server = createServer(function (req, res, next) {
132-
req.params = { 0: 'foo', 1: 'bar' }
133-
134-
router(req, res, function (err) {
135-
if (err) return next(err)
136-
sawParams(req, res)
137-
})
138-
})
139-
140-
router.get('/(.*)', hitParams(1))
141-
142-
request(server)
143-
.get('/buzz')
144-
.expect('x-params-1', '{"0":"foo","1":"bar","2":"buzz"}')
145-
.expect(200, '{"0":"foo","1":"bar"}', done)
146-
})
147-
148-
it('should merge with same numeric properties', function (done) {
149-
var router = Router({ mergeParams: true })
150-
var server = createServer(function (req, res, next) {
151-
req.params = { 0: 'foo' }
152-
153-
router(req, res, function (err) {
154-
if (err) return next(err)
155-
sawParams(req, res)
156-
})
157-
})
158-
159-
router.get('/(.*)', hitParams(1))
160-
161-
request(server)
162-
.get('/bar')
163-
.expect('x-params-1', '{"0":"foo","1":"bar"}')
164-
.expect(200, '{"0":"foo"}', done)
165-
})
166-
})
167127
})
168128
})
169129

0 commit comments

Comments
 (0)