diff --git a/README.md b/README.md index 6c5bddf..90f662a 100644 --- a/README.md +++ b/README.md @@ -382,6 +382,64 @@ router.route('/pet/:id') server.listen(8080) ``` +## Migrating to 2.x from 1.x + +The main change is the update to `path-to-regexp@2.0.0`, which has a few breaking changes: + +#### No longer a direct conversion to a RegExp with sugar on top. + +It's a path matcher with named and unnamed matching groups. It's unlikely you previously abused this feature, +it's rare and you could always use a RegExp instead. An example of this would be: + +```javascript +// Used to work +router.get('/\\d+') + +// Now requires matching group +router.get('/(\\d+)') +``` + +#### All matching RegExp special characters can be used in a matching group. + +Other RegExp features are not supported - no nested matching groups, non-capturing groups or look aheads +There is really only one common change is needing replacing any routes with `*` to `(.*)`. Some examples: + +- `/:user(*)` becomes `/:user(.*)` +- `/:user/*` becomes `/:user/(.*)` +- `/foo/*/bar` becomes `/foo/(.*)/bar` + +#### Parameters have suffixes that augment meaning - `*`, `+` and `?`. E.g. `/:user*` + +Needs more info. + +#### Named params with regex no longer define positionally. + +One other small change (hopefully low impact), is that named parameters with regular expressions no longer result in positional +values in the `params` object. An example is: + +```javascript +router.get('/:foo(.*)') + +// old GET /bar +console.log(req.params) // {0: 'bar', 'foo': 'bar'} + +// new GET /bar +console.log(req.params) // {'foo': 'bar'} +``` + +#### Partial matching, prefer escaping delimiter + +The update to `path-to-regexp@3` includes a change to how partial matches are handled, +now you should escape the delimiter before a partial match segment. For example: + +```javascript +// old +router.get('/user(s)?/:user/:op') + +// new +router.get('\\/user(s)?/:user/:op') +``` + ## License [MIT](LICENSE) diff --git a/lib/layer.js b/lib/layer.js index c012165..e6d8576 100644 --- a/lib/layer.js +++ b/lib/layer.js @@ -28,14 +28,28 @@ var hasOwnProperty = Object.prototype.hasOwnProperty module.exports = Layer -function Layer(path, options, fn) { +function Layer(p, options, fn) { if (!(this instanceof Layer)) { - return new Layer(path, options, fn) + return new Layer(p, options, fn) } debug('new %o', path) var opts = options || {} + // If not in strict allow both with or without trailing slash + var path = p + if (!opts.strict) { + if (!Array.isArray(path) && path !== '/' && path[path.length - 1] === '/') { + path = path.substr(0, path.length - 1) + } else { + for (var i = 0; i < path.length; i++) { + if (path[i] !== '/' && path[i][path[i].length - 1] === '/') { + path[i] = path[i].substr(0, path[i].length - 1) + } + } + } + } + this.handle = fn this.name = fn.name || '' this.params = undefined diff --git a/package.json b/package.json index 41328ab..2719372 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "debug": "3.1.0", "methods": "~1.1.2", "parseurl": "~1.3.2", - "path-to-regexp": "0.1.7", + "path-to-regexp": "^3.0.0", "setprototypeof": "1.1.0", "utils-merge": "1.0.1" }, diff --git a/test/req.params.js b/test/req.params.js index c7dbba2..57c82bf 100644 --- a/test/req.params.js +++ b/test/req.params.js @@ -137,7 +137,7 @@ describe('req.params', function () { }) }) - router.get('/*', hitParams(1)) + router.get('/(.*)', hitParams(1)) request(server) .get('/buzz') @@ -156,7 +156,7 @@ describe('req.params', function () { }) }) - router.get('/*', hitParams(1)) + router.get('/(.*)', hitParams(1)) request(server) .get('/bar') diff --git a/test/route.js b/test/route.js index d680272..3c7a98d 100644 --- a/test/route.js +++ b/test/route.js @@ -645,7 +645,7 @@ describe('Router', function () { it('should work following a partial capture group', function (done) { var cb = after(2, done) var router = new Router() - var route = router.route('/user(s)?/:user/:op') + var route = router.route('\\/user(s)?/:user/:op') var server = createServer(router) route.all(sendParams) @@ -716,7 +716,7 @@ describe('Router', function () { it('should capture everything with pre- and post-fixes', function (done) { var router = new Router() - var route = router.route('/foo/*/bar') + var route = router.route('/foo/(.*)/bar') var server = createServer(router) route.all(sendParams) @@ -728,7 +728,7 @@ describe('Router', function () { it('should capture greedly', function (done) { var router = new Router() - var route = router.route('/foo/*/bar') + var route = router.route('/foo/(.*)/bar') var server = createServer(router) route.all(sendParams) @@ -740,7 +740,7 @@ describe('Router', function () { it('should be an optional capture', function (done) { var router = new Router() - var route = router.route('/foo*') + var route = router.route('/foo(.*)') var server = createServer(router) route.all(sendParams) @@ -753,7 +753,7 @@ describe('Router', function () { it('should require preceeding /', function (done) { var cb = after(2, done) var router = new Router() - var route = router.route('/foo/*') + var route = router.route('/foo/(.*)') var server = createServer(router) route.all(sendParams) @@ -770,23 +770,23 @@ describe('Router', function () { it('should work in a named parameter', function (done) { var cb = after(2, done) var router = new Router() - var route = router.route('/:foo(*)') + var route = router.route('/:foo(.*)') var server = createServer(router) route.all(sendParams) request(server) .get('/bar') - .expect(200, {'0': 'bar', 'foo': 'bar'}, cb) + .expect(200, {'foo': 'bar'}, cb) request(server) .get('/fizz/buzz') - .expect(200, {'0': 'fizz/buzz', 'foo': 'fizz/buzz'}, cb) + .expect(200, {'foo': 'fizz/buzz'}, cb) }) it('should work before a named parameter', function (done) { var router = new Router() - var route = router.route('/*/user/:id') + var route = router.route('/(.*)/user/:id') var server = createServer(router) route.all(sendParams) @@ -799,7 +799,7 @@ describe('Router', function () { it('should work within arrays', function (done) { var cb = after(3, done) var router = new Router() - var route = router.route(['/user/:id', '/foo/*', '/:action']) + var route = router.route(['/user/:id', '/foo/(.*)', '/:action']) var server = createServer(router) route.all(sendParams)