UNPKG

@feathersjs/hooks

Version:

Async middleware for JavaScript and TypeScript

106 lines (105 loc) 4.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.legacyDecorator = exports.hookDecorator = exports.objectHooks = exports.functionHooks = exports.getOriginal = void 0; const compose_js_1 = require("./compose.js"); const base_js_1 = require("./base.js"); const utils_js_1 = require("./utils.js"); 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 = (0, base_js_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 (0, compose_js_1.compose)(hookChain).call(this, context); }; (0, utils_js_1.copyFnProperties)(wrapper, fn); (0, utils_js_1.copyProperties)(wrapper, fn); (0, base_js_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) { if (Array.isArray(hooks)) { return (0, base_js_1.setMiddleware)(obj, hooks); } for (const method of Object.keys(hooks)) { const target = typeof obj[method] === 'function' ? obj : obj.prototype; const fn = target && target[method]; if (typeof fn !== 'function') { throw new Error(`Can not apply hooks. '${method}' is not a function`); } const manager = (0, base_js_1.convertOptions)(hooks[method]); target[method] = functionHooks(fn, manager.props({ method })); } return obj; } exports.objectHooks = objectHooks; const hookDecorator = (managerOrMiddleware) => { return (target, context) => { const manager = (0, base_js_1.convertOptions)(managerOrMiddleware); if (context.kind === 'class') { (0, base_js_1.setManager)(target.prototype, manager); return target; } else if (context.kind === 'method') { const method = String(context.name); return functionHooks(target, manager.props({ method })); } throw new Error('Can not apply hooks.'); }; }; exports.hookDecorator = hookDecorator; const legacyDecorator = (managerOrMiddleware) => { const wrapper = (_target, method, descriptor) => { const manager = (0, base_js_1.convertOptions)(managerOrMiddleware); if (!descriptor) { (0, base_js_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.legacyDecorator = legacyDecorator;