Files
Superalgos/node_modules/before-after-hook/lib/register.js
T

105 lines
2.4 KiB
JavaScript

module.exports = register
function register (state, name, options, method) {
if (arguments.length === 3) {
method = options
options = {}
}
if (typeof method !== 'function') {
throw new Error('method for before hook must be a function')
}
if (typeof options !== 'object') {
throw new Error('options for before hook must be an object')
}
if (Array.isArray(name)) {
return name.reverse().reduce(function (callback, name) {
return register.bind(null, state, name, options, callback)
}, method)()
}
var hooks = state.registry[name]
if (!hooks) {
return invokeMethod(options, method)
}
var beforeHooks = hooks.before
var errorHooks = hooks.error
var afterHooks = hooks.after
// 1. run "before hooks" which may mutate options
return Promise.all(beforeHooks.map(invokeBeforeHook.bind(null, options)))
// 2. Once all finish without error, call the method with the (mutated) options
.then(function () {
return method(options)
})
// 3. If an error occurs in 1. or 2. run the "error hooks" which may mutate
// the error object. If one of them does not return an error then set the
// result to that. Otherwise throw (mutated) error.
.catch(function (error) {
return Promise.all(errorHooks.map(invokeErrorHook.bind(null, error, options)))
.then(function (results) {
var nonErrorResults = results.filter(isntError)
if (nonErrorResults.length) {
return nonErrorResults[0]
}
throw error
})
})
// 4. Run the "after hooks". They may mutate the result
.then(function (result) {
return Promise.all(afterHooks.map(invokeAfterHook.bind(null, result, options)))
.then(function () {
return result
})
})
}
function invokeMethod (options, method) {
try {
return Promise.resolve(method(options))
} catch (error) {
return Promise.reject(error)
}
}
function invokeBeforeHook (options, method) {
try {
return method(options)
} catch (error) {
return Promise.reject(error)
}
}
function invokeErrorHook (result, options, errorHook) {
try {
return Promise.resolve(errorHook(result, options))
.catch(function (error) { return error })
} catch (error) {
return Promise.resolve(error)
}
}
function invokeAfterHook (result, options, method) {
try {
return method(result, options)
} catch (error) {
return Promise.reject(error)
}
}
function isntError (result) {
return !(result instanceof Error)
}