import { Booster } from '../booster' ; import { Class , EntityInterface , ReducerMetadata , EventInterface , RoleAccess , AnyClass , } from '@boostercloud/framework-types' ; import 'reflect-metadata' ; interface EntityAttributes { authorizeReadEvents : RoleAccess [ 'authorize' ] ; } type EntityDecoratorParam = AnyClass | EntityAttributes ; type EntityDecoratorResult < TEntity , TParam > = TParam extends EntityAttributes ? ( entityClass : Class < TEntity > ) => void : void ; constructor export function Entity < TEntity extends EntityInterface , TParam extends EntityDecoratorParam > ( classOrAttributes ) { let authorizeReadEvents = [ ] ; const mainLogicFunction = ( entityClass ) => { Booster . configureCurrentEnv ( ( config ) : void => { if ( config . entities [ entityClass . name ] ) { throw new Error ( `An entity called ${ entityClass . name } is already registered
        If you think that this is an error, try performing a clean build..` ) ; } config . entities [ entityClass . name ] = { class : entityClass , authorizeReadEvents , } ; } ) ; } ; if ( isEntityAttributes ( classOrAttributes ) ) { authorizeReadEvents = classOrAttributes . authorizeReadEvents ; return mainLogicFunction as EntityDecoratorResult < TEntity , TParam > ; } return mainLogicFunction ( classOrAttributes as Class < TEntity > ) as EntityDecoratorResult < TEntity , TParam > ; } function isEntityAttributes ( param ) { return 'authorizeReadEvents' in param ; } param eventClass export function Reduces < TEvent extends EventInterface > ( eventClass ) { return ( entityClass , methodName ) => { registerReducer ( eventClass . name , { class : entityClass , methodName : methodName , } ) ; } ; } function registerReducer ( eventName , reducerMetadata ) { Booster . configureCurrentEnv ( ( config ) : void => { const reducerPath = config . reducers [ eventName ] ; if ( reducerPath ) { throw new Error ( `Error registering reducer: The event ${ eventName } was already registered to be reduced by method ${ reducerPath . methodName } in the entity ${ reducerPath . class . name }.
        If you think that this is an error, try performing a clean build.` ) ; } config . reducers [ eventName ] = reducerMetadata ; } ) ; } type ReducerMethod < TEvent , TEntity > = TypedPropertyDescriptor < ( event : TEvent , entity : TEntity ) => TEntity > | TypedPropertyDescriptor < ( event : TEvent , entity ? : TEntity ) => TEntity > ;