diff --git a/.jshintrc b/.jshintrc index 9776863..08f61c0 100644 --- a/.jshintrc +++ b/.jshintrc @@ -49,7 +49,7 @@ "lastsemic": false, "iterator": false, "funcscope": false, - "esnext": false, + "esnext": true, "newcap": false, "noempty": false, diff --git a/.travis.yml b/.travis.yml index 73d47bf..1c802ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,5 @@ language: node_js node_js: - - "0.12" - - "4" - - "6" - "8" branches: only: diff --git a/README.md b/README.md index 2a679a9..ace19fb 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,16 @@ module.exports = { } ``` +### Async Handlders +async/await requires at least node 7.6. Errors that occurred in async function will be automatically passed to next() callback +```javascript +module.exports = { + get: async (req, res) => { ... }, + put: async (req, res) => { ... }, + ... +} +``` + ### Handler Middleware Handlers can also specify middleware chains by providing an array of handler functions under the verb: diff --git a/lib/expressroutes.js b/lib/expressroutes.js index a24ee68..0f804ac 100644 --- a/lib/expressroutes.js +++ b/lib/expressroutes.js @@ -6,6 +6,18 @@ var async = require('async'), utils = require('swaggerize-routes/lib/utils'), pathRegexp = require('path-to-regexp'); +/** + * Wraps try catch block around async function + * Errors are sent to next handler automatically + * + * @param fn + * @return {Function} + */ +function asyncMiddleware(fn) { + return function (req, res, next) { + return Promise.resolve(fn(req, res, next)).catch(next); + }; +} /** * Makes default accessor functions for a specific data location, e.g. query, params etc @@ -125,26 +137,32 @@ function buildRoutePath(mountpath, path) { * @param routeSpec */ function makeExpressRoute(router, mountpath, route, securityDefinitions) { - var path, args, before, validators; + var path, args, before, validators, handlers, i; path = buildRoutePath(mountpath, route.path); args = [path]; before = []; + handlers = []; if (route.security) { before.push(authorizeFor(route.security, securityDefinitions)); } - if (thing.isArray(route.handler)) { - if (route.handler.length > 1) { - Array.prototype.push.apply(before, route.handler.slice(0, route.handler.length - 1)); + if (!thing.isArray(route.handler)) { + route.handler = [route.handler]; + } + + for (i = 0; i < route.handler.length; ++i) { + if (route.handler[i].constructor.name === "AsyncFunction") { + handlers.push(asyncMiddleware(route.handler[i])); + } else { + handlers.push(route.handler[i]); } - route.handler = route.handler[route.handler.length - 1]; } validators = []; - for (var i = 0; i < route.validators.length; ++i) { + for (i = 0; i < route.validators.length; ++i) { validators.push(makeValidator(route.validators[i], route.consumes)); } @@ -152,7 +170,7 @@ function makeExpressRoute(router, mountpath, route, securityDefinitions) { Array.prototype.push.apply(args, before); - args.push(route.handler); + Array.prototype.push.apply(args, handlers); router[route.method].apply(router, args); } diff --git a/package.json b/package.json index 293e5b0..240b7d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "swaggerize-express", - "version": "4.0.6", + "version": "4.0.7", "author": "Trevor Livingston ", "contributors": [ "Trevor Livingston ", @@ -28,7 +28,7 @@ }, "bugs": "http://github.com/krakenjs/swaggerize-express/issues", "engines": { - "node": "<=4.x" + "node": ">=4.8.7" }, "dependencies": { "async": "^1.5.0", diff --git a/test/fixtures/handlers/pets/{id}.js b/test/fixtures/handlers/pets/{id}.js index a54c30f..7ffb216 100644 --- a/test/fixtures/handlers/pets/{id}.js +++ b/test/fixtures/handlers/pets/{id}.js @@ -4,7 +4,10 @@ var store = require('../../lib/store'); module.exports = { - get: function (req, res) { + get: async (req, res) => { + // pretend waiting for database + await new Promise(res => setTimeout(res, 10)); + res.json(store.get(req.params['id'])); }, delete: function (req, res) {