import { actionTypeWithEntity, EntityMetadata, hasEntityMetadata, } from '../Redux/EntityMetadata'; import { SerializableQuery } from './SerializableQuery'; import { Query, QueryConstructor } from 'ts-eventsourcing/QueryHandling/Query'; import { InvalidQueryTypeError } from './Error/InvalidQueryTypeError'; import { EntityName } from '../ValueObject/EntityName'; import { ClassUtil } from 'ts-eventsourcing/ClassUtil'; import { ClassConstructor } from '../Serializer/ClassConstructor'; export interface QueryAction { type: string; metadata: EntityMetadata & Metadata; query: T; } export interface QueryResponseAction extends QueryAction { response: Response; } export function isQueryAction(action: any): action is QueryAction { return action && hasEntityMetadata(action) && SerializableQuery.isSerializableQuery(action.query); } export function isQueryActionOfType(action: any, type: (entity: string, query: QueryConstructor | Query) => string): action is QueryAction { return isQueryAction(action) && type(action.metadata.entity, action.query) === action.type; } export function queryActionTypeFactory(type: string) { return (entity: EntityName, query: QueryConstructor | Query) => { return actionTypeWithEntity(`[${ClassUtil.nameOff(query)}] ${type}`, entity); }; } export function asQueryAction( action: any, query: QueryConstructor, ): QueryAction { if (!isQueryAction(action)) { throw InvalidQueryTypeError.actionIsNotAnQueryAction(); } if (!(action.query instanceof query)) { throw InvalidQueryTypeError.doesNotMatchQuery(action.query, query); } return action as any; } export function asQueryActionWithResponse( action: any, query: QueryConstructor, responseClass?: ClassConstructor, ): QueryResponseAction { if (!isQueryAction(action)) { throw InvalidQueryTypeError.actionIsNotAnQueryAction(); } if (!(action.query instanceof query)) { throw InvalidQueryTypeError.doesNotMatchQuery(action.query, query); } const response = (action as any).response; if (typeof response === 'undefined') { throw InvalidQueryTypeError.doesNotHaveResponse(action.query); } if (responseClass && !(response instanceof responseClass)) { throw InvalidQueryTypeError.doesNotHaveCorrectResponse(action.query, responseClass); } return action as any; }