index.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. 'use strict'
  2. /**
  3. * Module dependencies.
  4. */
  5. const co = require('co')
  6. const compose = require('koa-compose')
  7. /**
  8. * Expose `convert()`.
  9. */
  10. module.exports = convert
  11. /**
  12. * Convert Koa legacy generator-based middleware
  13. * to modern promise-based middleware.
  14. *
  15. *
  16. * @api public
  17. * */
  18. function convert (mw) {
  19. if (typeof mw !== 'function') {
  20. throw new TypeError('middleware must be a function')
  21. }
  22. // assume it's Promise-based middleware
  23. if (
  24. mw.constructor.name !== 'GeneratorFunction' &&
  25. mw.constructor.name !== 'AsyncGeneratorFunction'
  26. ) {
  27. return mw
  28. }
  29. const converted = function (ctx, next) {
  30. return co.call(
  31. ctx,
  32. mw.call(
  33. ctx,
  34. (function * (next) { return yield next() })(next)
  35. ))
  36. }
  37. converted._name = mw._name || mw.name
  38. return converted
  39. }
  40. /**
  41. * Convert and compose multiple middleware
  42. * (could mix legacy and modern ones)
  43. * and return modern promise middleware.
  44. *
  45. *
  46. * @api public
  47. * */
  48. // convert.compose(mw, mw, mw)
  49. // convert.compose([mw, mw, mw])
  50. convert.compose = function (arr) {
  51. if (!Array.isArray(arr)) {
  52. arr = Array.from(arguments)
  53. }
  54. return compose(arr.map(convert))
  55. }
  56. /**
  57. * Convert Koa modern promise-based middleware
  58. * to legacy generator-based middleware.
  59. *
  60. *
  61. * @api public
  62. * */
  63. convert.back = function (mw) {
  64. if (typeof mw !== 'function') {
  65. throw new TypeError('middleware must be a function')
  66. }
  67. // assume it's generator middleware
  68. if (mw.constructor.name === 'GeneratorFunction' || mw.constructor.name === 'AsyncGeneratorFunction') {
  69. return mw
  70. }
  71. const converted = function * (next) {
  72. const ctx = this
  73. let called = false
  74. yield mw(ctx, function () {
  75. if (called) {
  76. // guard against multiple next() calls
  77. // https://github.com/koajs/compose/blob/4e3e96baf58b817d71bd44a8c0d78bb42623aa95/index.js#L36
  78. throw new Error('next() called multiple times')
  79. }
  80. called = true
  81. return co.call(ctx, next)
  82. })
  83. }
  84. converted._name = mw._name || mw.name
  85. return converted
  86. }