UNPKG

ts-ioc-container

Version:

Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.

43 lines (42 loc) 1.74 kB
import { Is } from '../utils/basic.js'; import { getProxyTarget, isProxy } from '../utils/proxy.js'; const isHookClassConstructor = (execute) => { return Is.constructor(execute) && execute.prototype.execute; }; export const toHookFn = (execute) => isHookClassConstructor(execute) ? (context) => context.scope.resolve(execute).execute(context) : execute; const getReflectionTarget = (target) => { return isProxy(target) ? getProxyTarget(target) : target; }; const getConstructorChain = (ctor) => { const chain = []; let current = ctor; while (typeof current === 'function' && current !== Function.prototype) { chain.push(current); current = Object.getPrototypeOf(current); } return chain; }; export function getHooks(target, key) { const reflectionTarget = getReflectionTarget(target); const merged = new Map(); for (const ctor of getConstructorChain(reflectionTarget.constructor).reverse()) { const ownHooks = Reflect.getOwnMetadata(key, ctor); if (ownHooks) { for (const [methodName, fns] of ownHooks) { merged.set(methodName, fns); } } } return merged; } export function hasHooks(target, key) { const reflectionTarget = getReflectionTarget(target); return getConstructorChain(reflectionTarget.constructor).some((ctor) => Reflect.hasOwnMetadata(key, ctor)); } export const hook = (key, ...fns) => (target, propertyKey) => { const hooks = Reflect.hasOwnMetadata(key, target.constructor) ? Reflect.getOwnMetadata(key, target.constructor) : new Map(); hooks.set(propertyKey, (hooks.get(propertyKey) ?? []).concat(fns)); Reflect.defineMetadata(key, hooks, target.constructor); };