/* eslint-disable @typescript-eslint/no-explicit-any */ import 'reflect-metadata'; import type { AbleRegistry } from './able'; import type { EntityDataRegistry, EntityRegistry } from './'; export const ABLES_DECO_KEY = Symbol('AblesDecorator'); export const ENTITIES_DECO_KEY = Symbol('EntitiesDecorator'); export const PAYLOAD_DECO_KEY = Symbol('PayloadDecorator'); export const HANDLE_DECO_KEY = Symbol('HandleDecorator'); export interface RegistryValueGetter { (target: any, method: string | Symbol): T } export interface RegistryInit { (target: any, method: string | Symbol): void } const cache: any[] = []; export function getRegistryMetadata(target: any, key: Symbol): any[] { return Reflect.getMetadata(key, target.prototype) || []; } export function createRegistryDecorator(key: Symbol, data: any, getValue?: RegistryValueGetter, init?: RegistryInit): MethodDecorator { return (target, method, descriptor) => { cache.push(target); let registries = Reflect.getMetadata(key, target); if (!registries) { registries = []; Reflect.defineMetadata(key, registries, target); } if (!Array.isArray(data)) { data = [data]; } data.forEach((registry: any) => { if (!registries.includes(registry)) { registries.push(registry); } }); if (init) init(target, method); if (getValue) { return { get(): any { return getValue(this, method); } }; } }; } export function getAbleMetadata(layer: any): AbleRegistry[] { return getRegistryMetadata(layer, ABLES_DECO_KEY); } export function getEntityMetadata(layer: any): EntityRegistry[] { return getRegistryMetadata(layer, ENTITIES_DECO_KEY); } export function getPayloadMetadata(able: AbleRegistry): string | Symbol { return getRegistryMetadata(able, PAYLOAD_DECO_KEY)[0]; } export function getHandleParams(able: AbleRegistry): EntityDataRegistry[] { return getRegistryMetadata(able, HANDLE_DECO_KEY); }