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