index.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. 'use strict'
  2. const co = require('co')
  3. const compose = require('koa-compose')
  4. module.exports = convert
  5. function convert (mw) {
  6. if (typeof mw !== 'function') {
  7. throw new TypeError('middleware must be a function')
  8. }
  9. if (mw.constructor.name !== 'GeneratorFunction') {
  10. // assume it's Promise-based middleware
  11. return mw
  12. }
  13. const converted = function (ctx, next) {
  14. return co.call(ctx, mw.call(ctx, createGenerator(next)))
  15. }
  16. converted._name = mw._name || mw.name
  17. return converted
  18. }
  19. function * createGenerator (next) {
  20. return yield next()
  21. }
  22. // convert.compose(mw, mw, mw)
  23. // convert.compose([mw, mw, mw])
  24. convert.compose = function (arr) {
  25. if (!Array.isArray(arr)) {
  26. arr = Array.from(arguments)
  27. }
  28. return compose(arr.map(convert))
  29. }
  30. convert.back = function (mw) {
  31. if (typeof mw !== 'function') {
  32. throw new TypeError('middleware must be a function')
  33. }
  34. if (mw.constructor.name === 'GeneratorFunction') {
  35. // assume it's generator middleware
  36. return mw
  37. }
  38. const converted = function * (next) {
  39. let ctx = this
  40. let called = false
  41. // no need try...catch here, it's ok even `mw()` throw exception
  42. yield Promise.resolve(mw(ctx, function () {
  43. if (called) {
  44. // guard against multiple next() calls
  45. // https://github.com/koajs/compose/blob/4e3e96baf58b817d71bd44a8c0d78bb42623aa95/index.js#L36
  46. return Promise.reject(new Error('next() called multiple times'))
  47. }
  48. called = true
  49. return co.call(ctx, next)
  50. }))
  51. }
  52. converted._name = mw._name || mw.name
  53. return converted
  54. }