93 lines
3.6 KiB
JavaScript
93 lines
3.6 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.hookDecorator = exports.objectHooks = exports.functionHooks = exports.getOriginal = void 0;
|
|
const compose_1 = require("./compose");
|
|
const base_1 = require("./base");
|
|
const utils_1 = require("./utils");
|
|
function getOriginal(fn) {
|
|
return typeof fn.original === 'function' ? getOriginal(fn.original) : fn;
|
|
}
|
|
exports.getOriginal = getOriginal;
|
|
function functionHooks(fn, managerOrMiddleware) {
|
|
if (typeof fn !== 'function') {
|
|
throw new Error('Can not apply hooks to non-function');
|
|
}
|
|
const manager = base_1.convertOptions(managerOrMiddleware);
|
|
const wrapper = function (...args) {
|
|
const { Context, original } = wrapper;
|
|
// If we got passed an existing HookContext instance, we want to return it as well
|
|
const returnContext = args[args.length - 1] instanceof Context;
|
|
// Use existing context or default
|
|
const base = returnContext ? args.pop() : new Context();
|
|
// Initialize the context
|
|
const context = manager.initializeContext(this, args, base);
|
|
// Assemble the hook chain
|
|
const hookChain = [
|
|
// Return `ctx.result` or the context
|
|
(ctx, next) => next().then(() => returnContext ? ctx : ctx.result)
|
|
];
|
|
// Create the hook chain by calling the `collectMiddleware function
|
|
const mw = manager.collectMiddleware(this, args);
|
|
if (mw) {
|
|
Array.prototype.push.apply(hookChain, mw);
|
|
}
|
|
// Runs the actual original method if `ctx.result` is not already set
|
|
hookChain.push((ctx, next) => {
|
|
if (!Object.prototype.hasOwnProperty.call(context, 'result')) {
|
|
return Promise.resolve(original.apply(this, ctx.arguments)).then(result => {
|
|
ctx.result = result;
|
|
return next();
|
|
});
|
|
}
|
|
return next();
|
|
});
|
|
return compose_1.compose(hookChain).call(this, context);
|
|
};
|
|
utils_1.copyFnProperties(wrapper, fn);
|
|
utils_1.copyProperties(wrapper, fn);
|
|
base_1.setManager(wrapper, manager);
|
|
return Object.assign(wrapper, {
|
|
original: getOriginal(fn),
|
|
Context: manager.getContextClass(),
|
|
createContext: (data = {}) => {
|
|
return new wrapper.Context(data);
|
|
}
|
|
});
|
|
}
|
|
exports.functionHooks = functionHooks;
|
|
;
|
|
function objectHooks(_obj, hooks) {
|
|
const obj = typeof _obj === 'function' ? _obj.prototype : _obj;
|
|
if (Array.isArray(hooks)) {
|
|
return base_1.setMiddleware(obj, hooks);
|
|
}
|
|
return Object.keys(hooks).reduce((result, method) => {
|
|
const fn = obj[method];
|
|
if (typeof fn !== 'function') {
|
|
throw new Error(`Can not apply hooks. '${method}' is not a function`);
|
|
}
|
|
const manager = base_1.convertOptions(hooks[method]);
|
|
result[method] = functionHooks(fn, manager.props({ method }));
|
|
return result;
|
|
}, obj);
|
|
}
|
|
exports.objectHooks = objectHooks;
|
|
;
|
|
const hookDecorator = (managerOrMiddleware) => {
|
|
const wrapper = (_target, method, descriptor) => {
|
|
const manager = base_1.convertOptions(managerOrMiddleware);
|
|
if (!descriptor) {
|
|
base_1.setManager(_target.prototype, manager);
|
|
return _target;
|
|
}
|
|
const fn = descriptor.value;
|
|
if (typeof fn !== 'function') {
|
|
throw new Error(`Can not apply hooks. '${method}' is not a function`);
|
|
}
|
|
descriptor.value = functionHooks(fn, manager.props({ method }));
|
|
return descriptor;
|
|
};
|
|
return wrapper;
|
|
};
|
|
exports.hookDecorator = hookDecorator;
|
|
//# sourceMappingURL=hooks.js.map
|