Skip to content

Commit 9963485

Browse files
committed
feat!: path-to-regexp@^8.0.0
1 parent f5a99b0 commit 9963485

File tree

6 files changed

+167
-205
lines changed

6 files changed

+167
-205
lines changed

index.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,6 @@ function processParams (params, layer, called, req, res, done) {
576576
}
577577

578578
let i = 0
579-
let name
580579
let paramIndex = 0
581580
let key
582581
let paramVal
@@ -596,10 +595,9 @@ function processParams (params, layer, called, req, res, done) {
596595

597596
paramIndex = 0
598597
key = keys[i++]
599-
name = key.name
600-
paramVal = req.params[name]
601-
paramCallbacks = params[name]
602-
paramCalled = called[name]
598+
paramVal = req.params[key]
599+
paramCallbacks = params[key]
600+
paramCalled = called[key]
603601

604602
if (paramVal === undefined || !paramCallbacks) {
605603
return param()
@@ -609,13 +607,13 @@ function processParams (params, layer, called, req, res, done) {
609607
if (paramCalled && (paramCalled.match === paramVal ||
610608
(paramCalled.error && paramCalled.error !== 'route'))) {
611609
// restore value
612-
req.params[name] = paramCalled.value
610+
req.params[key] = paramCalled.value
613611

614612
// next param
615613
return param(paramCalled.error)
616614
}
617615

618-
called[name] = paramCalled = {
616+
called[key] = paramCalled = {
619617
error: null,
620618
match: paramVal,
621619
value: paramVal
@@ -629,7 +627,7 @@ function processParams (params, layer, called, req, res, done) {
629627
const fn = paramCallbacks[paramIndex++]
630628

631629
// store updated value
632-
paramCalled.value = req.params[key.name]
630+
paramCalled.value = req.params[key]
633631

634632
if (err) {
635633
// store error
@@ -641,7 +639,7 @@ function processParams (params, layer, called, req, res, done) {
641639
if (!fn) return param()
642640

643641
try {
644-
const ret = fn(req, res, paramCallback, paramVal, key.name)
642+
const ret = fn(req, res, paramCallback, paramVal, key)
645643
if (isPromise(ret)) {
646644
ret.then(null, function (error) {
647645
paramCallback(error || new Error('Rejected promise'))

lib/layer.js

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

23-
const hasOwnProperty = Object.prototype.hasOwnProperty
2423
const TRAILING_SLASH_REGEXP = /\/+$/
24+
const 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+
const keys = []
49+
let name = 0
50+
let m
51+
// eslint-disable-next-line no-cond-assign
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+
const match = _path.exec(p)
61+
if (!match) {
62+
return false
63+
}
64+
65+
const params = {}
66+
for (let i = 1; i < match.length; i++) {
67+
const key = keys[i - 1]
68+
const prop = key.name
69+
const val = decodeParam(match[i])
70+
71+
if (val !== undefined) {
72+
params[prop] = val
73+
}
74+
}
75+
76+
return {
77+
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
/**
@@ -126,14 +169,18 @@ Layer.prototype.match = function match (path) {
126169

127170
if (path != null) {
128171
// fast path non-ending match for / (any path matches)
129-
if (this.regexp._slash) {
172+
if (this.slash) {
130173
this.params = {}
131174
this.path = ''
132175
return true
133176
}
134177

135-
// match the path
136-
match = this.regexp.exec(path)
178+
let i = 0
179+
while (!match && i < this.matchers.length) {
180+
// match the path
181+
match = this.matchers[i](path)
182+
i++
183+
}
137184
}
138185

139186
if (!match) {
@@ -143,22 +190,9 @@ Layer.prototype.match = function match (path) {
143190
}
144191

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

163197
return true
164198
}
@@ -192,7 +226,7 @@ function decodeParam (val) {
192226
* Loosens the given path for path-to-regexp matching.
193227
*/
194228
function loosen (path) {
195-
if (path instanceof RegExp) {
229+
if (path instanceof RegExp || path === '/') {
196230
return path
197231
}
198232

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"is-promise": "4.0.0",
1414
"methods": "~1.1.2",
1515
"parseurl": "~1.3.3",
16-
"path-to-regexp": "3.2.0",
16+
"path-to-regexp": "^8.0.0",
1717
"setprototypeof": "1.2.0",
1818
"utils-merge": "1.0.1"
1919
},
@@ -41,6 +41,7 @@
4141
"scripts": {
4242
"lint": "standard",
4343
"test": "mocha --reporter spec --bail --check-leaks test/",
44+
"test:debug": "mocha --reporter spec --bail --check-leaks test/ --inspect --inspect-brk",
4445
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
4546
"test-cov": "nyc --reporter=text npm test",
4647
"version": "node scripts/version-history.js && git add HISTORY.md"

test/req.params.js

+29-29
Original file line numberDiff line numberDiff line change
@@ -124,45 +124,45 @@ describe('req.params', function () {
124124
.expect('x-params-1', '{"foo":"buzz"}')
125125
.expect(200, '{"foo":"bar"}', done)
126126
})
127+
})
127128

128-
describe('with numeric properties in req.params', function () {
129-
it('should merge numeric properties by offsetting', function (done) {
130-
const router = Router({ mergeParams: true })
131-
const server = createServer(function (req, res, next) {
132-
req.params = { 0: 'foo', 1: 'bar' }
129+
describe('with numeric properties in req.params', function () {
130+
it('should merge numeric properties by offsetting', function (done) {
131+
const router = Router({ mergeParams: true })
132+
const server = createServer(function (req, res, next) {
133+
req.params = { 0: 'foo', 1: 'bar' }
133134

134-
router(req, res, function (err) {
135-
if (err) return next(err)
136-
sawParams(req, res)
137-
})
135+
router(req, res, function (err) {
136+
if (err) return next(err)
137+
sawParams(req, res)
138138
})
139+
})
139140

140-
router.get('/(.*)', hitParams(1))
141+
router.get(/\/([^\/]*)/, hitParams(1))
141142

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-
})
143+
request(server)
144+
.get('/buzz')
145+
.expect('x-params-1', '{"0":"foo","1":"bar","2":"buzz"}')
146+
.expect(200, '{"0":"foo","1":"bar"}', done)
147+
})
147148

148-
it('should merge with same numeric properties', function (done) {
149-
const router = Router({ mergeParams: true })
150-
const server = createServer(function (req, res, next) {
151-
req.params = { 0: 'foo' }
149+
it('should merge with same numeric properties', function (done) {
150+
const router = Router({ mergeParams: true })
151+
const server = createServer(function (req, res, next) {
152+
req.params = { 0: 'foo' }
152153

153-
router(req, res, function (err) {
154-
if (err) return next(err)
155-
sawParams(req, res)
156-
})
154+
router(req, res, function (err) {
155+
if (err) return next(err)
156+
sawParams(req, res)
157157
})
158+
})
158159

159-
router.get('/(.*)', hitParams(1))
160+
router.get(/\/([^\/]*)/, hitParams(1))
160161

161-
request(server)
162-
.get('/bar')
163-
.expect('x-params-1', '{"0":"foo","1":"bar"}')
164-
.expect(200, '{"0":"foo"}', done)
165-
})
162+
request(server)
163+
.get('/bar')
164+
.expect('x-params-1', '{"0":"foo","1":"bar"}')
165+
.expect(200, '{"0":"foo"}', done)
166166
})
167167
})
168168
})

0 commit comments

Comments
 (0)