import { DTODecoratorName, DTODecoratorFactories, DTODecoratorOptions, PropertyDecoratorFactory, Target, } from './types'; /* Multiple property decorators can be composed into a new property decorator. */ export function composePropertyDecorators( decorators: Array, ): PropertyDecorator { return (target: Target, propertyKey: string | symbol): void => { for (const decorator of decorators) { if (decorator !== undefined) { decorator(target, propertyKey); } } }; } /* Multiple property decorator factories of the same type can be composed into a new factory. */ export function composePropertyDecoratorFactories( factories: PropertyDecoratorFactory>[], ): PropertyDecoratorFactory> { return (options: DTODecoratorOptions): PropertyDecorator => composePropertyDecorators( factories.map( (factory) => factory(options), ), ); } /* A specific property decorator factory can be selected from a factory by name. */ export function selectPropertyDecoratorFactory( name: Name, factory: DTODecoratorFactories, ): PropertyDecoratorFactory> { return factory[name] as unknown as PropertyDecoratorFactory>; } /* A specific property decorator factory can be selected from a set of factories by name. */ export function selectPropertyDecoratorFactories( name: Name, factories: DTODecoratorFactories[], ): PropertyDecoratorFactory>[] { return factories.map( (factory) => selectPropertyDecoratorFactory(name, factory), ); }