diff --git a/lib/router.js b/lib/router.js index 3c920d7..7b4ad89 100644 --- a/lib/router.js +++ b/lib/router.js @@ -565,6 +565,40 @@ Router.prototype.all = function (name, path, middleware) { return this; }; +/** + * Register route with concrete verbs. + * + * @param {Array} verbs + * @param {String} name Optional. + * @param {String} path + * @param {Function=} middleware You may also pass multiple middleware. + * @param {Function} callback + * @returns {Router} + */ + +Router.prototype.verbs = function (verbs, path, middleware) { + + if (!Array.isArray(verbs) || verbs.length === 0) { + throw new Error('You have to provide a list of verbs when adding an verbs handler'); + } + + if (typeof path === 'string') { + middleware = Array.prototype.slice.call(arguments, 2); + } + + // Sanity check to ensure we have a viable path candidate (eg: string|regex|non-empty array) + if ( + typeof path !== 'string' && + !(path instanceof RegExp) && + (!Array.isArray(path) || path.length === 0) + ) + throw new Error('You have to provide a path when adding an all handler'); + + this.register(path, verbs.map(verb => verb.toLowerCase()), middleware); + + return this; +}; + /** * Redirect `source` to `destination` URL with optional 30x status `code`. * diff --git a/test/lib/router.js b/test/lib/router.js index 065fe91..5f4dcdd 100644 --- a/test/lib/router.js +++ b/test/lib/router.js @@ -1131,6 +1131,53 @@ describe('Router', function () { }); }); + describe('Router#verbs()', function () { + it('correctly returns an error when not passed a verbs for "verbs"', function () { + const router = new Router(); + try { + router.verbs(function () {}); + } catch (err) { + expect(err.message).to.be( + 'You have to provide a list of verbs when adding an verbs handler' + ); + } + }); + + it('registers multiple verbs for one route', function (done) { + const app = new Koa(); + const router = new Router(); + + const verbs = ['get', 'post'] + + router.verbs( + verbs, + '/route', + function (ctx) { + ctx.body = { message: ctx.method }; + } + ); + + app.use(router.routes()); + + Promise.all( + verbs.map((verb) => { + return request(http.createServer(app.callback())) + [verb](`/route`) + .expect(200); + }) + ).then( + (resList) => { + for (const res of resList) { + assert.strictEqual(verbs.includes(res.body.message.toLowerCase()), true); + } + + done(); + }, + (err) => done(err) + ); + }); + }) + describe('Router#use()', function () { it('uses router middleware without path', function (done) { const app = new Koa();