forked from Mirrors/doipjs
66 lines
2.1 KiB
JavaScript
66 lines
2.1 KiB
JavaScript
|
'use strict'
|
||
|
|
||
|
// hoisted due to circular dependency on command.
|
||
|
module.exports = {
|
||
|
applyMiddleware,
|
||
|
commandMiddlewareFactory,
|
||
|
globalMiddlewareFactory
|
||
|
}
|
||
|
const isPromise = require('./is-promise')
|
||
|
const argsert = require('./argsert')
|
||
|
|
||
|
function globalMiddlewareFactory (globalMiddleware, context) {
|
||
|
return function (callback, applyBeforeValidation = false) {
|
||
|
argsert('<array|function> [boolean]', [callback, applyBeforeValidation], arguments.length)
|
||
|
if (Array.isArray(callback)) {
|
||
|
for (let i = 0; i < callback.length; i++) {
|
||
|
if (typeof callback[i] !== 'function') {
|
||
|
throw Error('middleware must be a function')
|
||
|
}
|
||
|
callback[i].applyBeforeValidation = applyBeforeValidation
|
||
|
}
|
||
|
Array.prototype.push.apply(globalMiddleware, callback)
|
||
|
} else if (typeof callback === 'function') {
|
||
|
callback.applyBeforeValidation = applyBeforeValidation
|
||
|
globalMiddleware.push(callback)
|
||
|
}
|
||
|
return context
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function commandMiddlewareFactory (commandMiddleware) {
|
||
|
if (!commandMiddleware) return []
|
||
|
return commandMiddleware.map(middleware => {
|
||
|
middleware.applyBeforeValidation = false
|
||
|
return middleware
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function applyMiddleware (argv, yargs, middlewares, beforeValidation) {
|
||
|
const beforeValidationError = new Error('middleware cannot return a promise when applyBeforeValidation is true')
|
||
|
return middlewares
|
||
|
.reduce((accumulation, middleware) => {
|
||
|
if (middleware.applyBeforeValidation !== beforeValidation &&
|
||
|
!isPromise(accumulation)) {
|
||
|
return accumulation
|
||
|
}
|
||
|
|
||
|
if (isPromise(accumulation)) {
|
||
|
return accumulation
|
||
|
.then(initialObj =>
|
||
|
Promise.all([initialObj, middleware(initialObj, yargs)])
|
||
|
)
|
||
|
.then(([initialObj, middlewareObj]) =>
|
||
|
Object.assign(initialObj, middlewareObj)
|
||
|
)
|
||
|
} else {
|
||
|
const result = middleware(argv, yargs)
|
||
|
if (beforeValidation && isPromise(result)) throw beforeValidationError
|
||
|
|
||
|
return isPromise(result)
|
||
|
? result.then(middlewareObj => Object.assign(accumulation, middlewareObj))
|
||
|
: Object.assign(accumulation, result)
|
||
|
}
|
||
|
}, argv)
|
||
|
}
|