From 8b84aca71093dfefd01622c5be2f96ac18326b79 Mon Sep 17 00:00:00 2001 From: calebboyd Date: Wed, 23 Sep 2015 13:28:56 -0500 Subject: [PATCH 1/2] expose next on context --- index.js | 62 ++++++++++++++++++++++++++++++++++++---------------- test/test.js | 13 +++++++++-- 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/index.js b/index.js index 0c5669b..befd013 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,45 @@ module.exports = compose; +function noop () { + return Promise.resolve() +} + +/** + * Try catch middlware invocation + * @api private + * @param fn + * @param ctx + * @param next + * @returns {Promise} + */ + +function tryCatch(fn, ctx, next) { + try { + return Promise.resolve(fn(ctx, next)) + } catch (err) { + return Promise.reject(err) + } +} + + +/** + * Reducer for creating storing next reference + * @api private + * @param next + * @param mw + * @returns {Function} + */ + +function middlewareReducer(next, mw) { + return function(ctx, nextFn) { + ctx.next = next && function () { return next(ctx) } + || nextFn + || noop + return tryCatch(mw, ctx, ctx.next) + } +} + /** * Compose `middleware` returning * a fully valid middleware comprised @@ -21,25 +60,10 @@ function compose(middleware){ for (const fn of middleware) { if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!') } - - /** - * @param {Object} context - * @return {Promise} - * @api public - */ - - return function (context, next) { - return dispatch(0) - function dispatch(i) { - const fn = middleware[i] || next - if (!fn) return Promise.resolve() - try { - return Promise.resolve(fn(context, function next() { - return dispatch(i + 1) - })) - } catch(err) { - return Promise.reject(err); - } + if (!middleware.length) { + return function(ctx, next) { + return tryCatch(next || noop, ctx, noop) } } + return middleware.reduceRight(middlewareReducer, undefined) } diff --git a/test/test.js b/test/test.js index 814bcb1..959e1d5 100644 --- a/test/test.js +++ b/test/test.js @@ -174,9 +174,18 @@ describe('Koa Compose', function(){ return compose(stack.map(co.wrap))({}).then(function () { throw 'promise was not rejected' - }) - .catch(function (e) { + }).catch(function (e) { e.should.be.instanceof(Error) }) }) + + it('should expose next on the context', function () { + var stack = []; + + stack.push(function (context, next) { + context.next.should.equal(next) + }) + + return compose(stack.map(co.wrap))({}) + }) }) From 1c9c3d1a6de9410b496f04f354fb69915d0cd657 Mon Sep 17 00:00:00 2001 From: calebboyd Date: Thu, 24 Sep 2015 22:21:53 -0500 Subject: [PATCH 2/2] pass initial next function through --- index.js | 2 +- test/test.js | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index befd013..38acae3 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,7 @@ function tryCatch(fn, ctx, next) { function middlewareReducer(next, mw) { return function(ctx, nextFn) { - ctx.next = next && function () { return next(ctx) } + ctx.next = next && function () { return next(ctx, nextFn) } || nextFn || noop return tryCatch(mw, ctx, ctx.next) diff --git a/test/test.js b/test/test.js index 959e1d5..b20ed9d 100644 --- a/test/test.js +++ b/test/test.js @@ -179,6 +179,28 @@ describe('Koa Compose', function(){ }) }) + it('should return a valid middleware', function () { + var val = 0 + compose([ + compose([ + (ctx, next) => { + val++ + return next() + }, + (ctx, next) => { + val++ + return next() + } + ]), + (ctx, next) => { + val++ + return next() + } + ])({}).then(function () { + val.should.equal(3) + }) + }) + it('should expose next on the context', function () { var stack = [];