import { AllowedNames } from "../types"; import { getInheritedHiddenProp } from "../object"; type ObjectKey = (string | symbol | number); export interface RegisterDecorator { (target: O, property: AllowedNames, descriptor?: PropertyDescriptor): any; get_registry(target: any): Record; get_keys(target: any): ObjectKey[] registry_symbol: Symbol; } export interface ArgRegisterDecorator { (...args: R): ((target: O, property: AllowedNames, descriptor?: PropertyDescriptor) => any) get_registry(target: any): Record get_keys(target: any): ObjectKey[] registry_symbol: Symbol; } // TODO Stage 3 Compat? export function create_arg_registering_decorator(): ArgRegisterDecorator export function create_arg_registering_decorator(transformer: (key: symbol | string, ...args: R) => P): ArgRegisterDecorator export function create_arg_registering_decorator( transformer: (key, ...args: R) => P = ((key, ...params) => ({ key, params })) as any ) { const symbol = Symbol(); const metaDecorator = (...args: R) => { const decorator = ((target: O, property: AllowedNames, descriptor?: PropertyDescriptor): any => { const registry = metaDecorator.get_registry(target); registry[property] = transformer(property, ...args); return descriptor; }) as any as ArgRegisterDecorator; return decorator; } metaDecorator.get_registry = (target: any) => getInheritedHiddenProp(target, symbol, 'object') metaDecorator.get_keys = (target: any) => { const registry = metaDecorator.get_registry(target); return Object.keys(registry); } metaDecorator.registry_symbol = symbol; return metaDecorator as any; } // TODO Stage 3 Compat? export function create_registering_decorator(): RegisterDecorator { const symbol = Symbol(); const decorator = (target: O, property: AllowedNames, descriptor?: PropertyDescriptor): any => { const registry = decorator.get_registry(target); registry[property] = { key: property, } return descriptor; } decorator.get_registry = (target: any) => getInheritedHiddenProp(target, symbol, 'object') decorator.get_keys = (target: any) => { const registry = decorator.get_registry(target); return Object.keys(registry); } decorator.registry_symbol = symbol; return decorator as any; }