Skip to content
This repository has been archived by the owner on Aug 31, 2024. It is now read-only.

Commit

Permalink
add convert.back()
Browse files Browse the repository at this point in the history
  • Loading branch information
gyson committed Nov 6, 2015
1 parent e18b275 commit 1d58b7c
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 7 deletions.
37 changes: 30 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ function convert (mw) {
if (typeof mw !== 'function') {
throw new TypeError('middleware must be a function')
}
if (mw.constructor.name === 'GeneratorFunction') {
return function (ctx, next) {
return co.call(ctx, mw.call(ctx, createGenerator(next)))
}
} else {
if (mw.constructor.name !== 'GeneratorFunction') {
// assume it's Promise-based middleware
return mw
}
return function (ctx, next) {
return co.call(ctx, mw.call(ctx, createGenerator(next)))
}
}

function * createGenerator (next) {
return yield next()
}

// convert.compose(mw, mw, mw)
Expand All @@ -28,6 +31,26 @@ convert.compose = function (arr) {
return compose(arr.map(convert))
}

function * createGenerator (next) {
return yield next()
convert.back = function (mw) {
if (typeof mw !== 'function') {
throw new TypeError('middleware must be a function')
}
if (mw.constructor.name === 'GeneratorFunction') {
// assume it's generator middleware
return mw
}
return function * (next) {
let ctx = this
let called = false
// no need try...catch here, it's ok even `mw()` throw exception
yield Promise.resolve(mw(ctx, function () {
if (called) {
// guard against multiple next() calls
// https://github.com/koajs/compose/blob/4e3e96baf58b817d71bd44a8c0d78bb42623aa95/index.js#L36
return Promise.reject(new Error('next() called multiple times'))
}
called = true
return co.call(ctx, next)
}))
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
},
"devDependencies": {
"koa": "^2.0.0-alpha.2",
"koa-v1": "^1.0.0",
"mocha": "^2.3.3",
"standard": "^5.3.1",
"supertest": "^1.1.0"
Expand Down
55 changes: 55 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

const co = require('co')
const Koa = require('koa')
const KoaV1 = require('koa-v1')
const assert = require('assert')
const convert = require('./index')
const request = require('supertest')
Expand Down Expand Up @@ -143,6 +144,60 @@ describe('convert.compose()', () => {
})
})

describe('convert.back()', () => {
it('should work with koa 1', done => {
let app = new KoaV1()

app.use(function * (next) {
this.body = [1]
yield next
this.body.push(6)
})

app.use(convert.back((ctx, next) => {
ctx.body.push(2)
return next().then(() => {
ctx.body.push(5)
})
}))

app.use(convert.back(co.wrap(function * (ctx, next) {
ctx.body.push(3)
yield next()
ctx.body.push(4)
})))

request(app.callback())
.get('/')
.expect(200, [1, 2, 3, 4, 5, 6])
.end(done)
})

it('should guard multiple calls', done => {
let app = new KoaV1()

app.use(function * (next) {
try {
this.body = [1]
yield next
} catch (e) {
this.body.push(e.message)
}
})

app.use(convert.back(co.wrap(function * (ctx, next) {
ctx.body.push(2)
yield next()
yield next() // this should throw new Error('next() called multiple times')
})))

request(app.callback())
.get('/')
.expect(200, [1, 2, 'next() called multiple times'])
.end(done)
})
})

describe('migration snippet', () => {
let app = new Koa()

Expand Down

0 comments on commit 1d58b7c

Please sign in to comment.