middleware.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. 'use strict'
  2. // hoisted due to circular dependency on command.
  3. module.exports = {
  4. applyMiddleware,
  5. commandMiddlewareFactory,
  6. globalMiddlewareFactory
  7. }
  8. const isPromise = require('./is-promise')
  9. const argsert = require('./argsert')
  10. function globalMiddlewareFactory (globalMiddleware, context) {
  11. return function (callback, applyBeforeValidation = false) {
  12. argsert('<array|function> [boolean]', [callback, applyBeforeValidation], arguments.length)
  13. if (Array.isArray(callback)) {
  14. for (let i = 0; i < callback.length; i++) {
  15. if (typeof callback[i] !== 'function') {
  16. throw Error('middleware must be a function')
  17. }
  18. callback[i].applyBeforeValidation = applyBeforeValidation
  19. }
  20. Array.prototype.push.apply(globalMiddleware, callback)
  21. } else if (typeof callback === 'function') {
  22. callback.applyBeforeValidation = applyBeforeValidation
  23. globalMiddleware.push(callback)
  24. }
  25. return context
  26. }
  27. }
  28. function commandMiddlewareFactory (commandMiddleware) {
  29. if (!commandMiddleware) return []
  30. return commandMiddleware.map(middleware => {
  31. middleware.applyBeforeValidation = false
  32. return middleware
  33. })
  34. }
  35. function applyMiddleware (argv, yargs, middlewares, beforeValidation) {
  36. const beforeValidationError = new Error('middleware cannot return a promise when applyBeforeValidation is true')
  37. return middlewares
  38. .reduce((accumulation, middleware) => {
  39. if (middleware.applyBeforeValidation !== beforeValidation &&
  40. !isPromise(accumulation)) {
  41. return accumulation
  42. }
  43. if (isPromise(accumulation)) {
  44. return accumulation
  45. .then(initialObj =>
  46. Promise.all([initialObj, middleware(initialObj, yargs)])
  47. )
  48. .then(([initialObj, middlewareObj]) =>
  49. Object.assign(initialObj, middlewareObj)
  50. )
  51. } else {
  52. const result = middleware(argv, yargs)
  53. if (beforeValidation && isPromise(result)) throw beforeValidationError
  54. return isPromise(result)
  55. ? result.then(middlewareObj => Object.assign(accumulation, middlewareObj))
  56. : Object.assign(accumulation, result)
  57. }
  58. }, argv)
  59. }