2021-04-22 10:07:10 +02:00
|
|
|
import { IUnleashConfig } from '../types/option';
|
2023-09-27 15:23:05 +02:00
|
|
|
import { IFeatureTagStore, IUnleashStores } from '../types/stores';
|
2021-04-22 10:07:10 +02:00
|
|
|
import { Logger } from '../logger';
|
2021-08-12 15:04:37 +02:00
|
|
|
import { IEventStore } from '../types/stores/event-store';
|
2024-01-17 16:55:59 +01:00
|
|
|
import { IBaseEvent, IEventList, IUserEvent } from '../types/events';
|
2022-08-09 16:14:50 +02:00
|
|
|
import { SearchEventsSchema } from '../openapi/spec/search-events-schema';
|
2023-09-27 15:23:05 +02:00
|
|
|
import EventEmitter from 'events';
|
2024-01-17 16:55:59 +01:00
|
|
|
import { ADMIN_TOKEN_USER, IApiUser, ITag, IUser, SYSTEM_USER } from '../types';
|
|
|
|
import { ApiTokenType } from '../../lib/types/models/api-token';
|
2021-04-22 10:07:10 +02:00
|
|
|
|
|
|
|
export default class EventService {
|
|
|
|
private logger: Logger;
|
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
private eventStore: IEventStore;
|
2021-04-22 10:07:10 +02:00
|
|
|
|
2023-09-27 15:23:05 +02:00
|
|
|
private featureTagStore: IFeatureTagStore;
|
|
|
|
|
2021-04-22 10:07:10 +02:00
|
|
|
constructor(
|
2023-09-27 15:23:05 +02:00
|
|
|
{
|
|
|
|
eventStore,
|
|
|
|
featureTagStore,
|
|
|
|
}: Pick<IUnleashStores, 'eventStore' | 'featureTagStore'>,
|
2021-04-22 10:07:10 +02:00
|
|
|
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>,
|
|
|
|
) {
|
|
|
|
this.logger = getLogger('services/event-service.ts');
|
|
|
|
this.eventStore = eventStore;
|
2023-09-27 15:23:05 +02:00
|
|
|
this.featureTagStore = featureTagStore;
|
2021-04-22 10:07:10 +02:00
|
|
|
}
|
|
|
|
|
2022-09-02 08:35:31 +02:00
|
|
|
async getEvents(): Promise<IEventList> {
|
2023-09-29 14:18:21 +02:00
|
|
|
const totalEvents = await this.eventStore.count();
|
|
|
|
const events = await this.eventStore.getEvents();
|
2022-09-02 08:35:31 +02:00
|
|
|
return {
|
|
|
|
events,
|
|
|
|
totalEvents,
|
|
|
|
};
|
2021-04-22 10:07:10 +02:00
|
|
|
}
|
|
|
|
|
2022-09-02 08:35:31 +02:00
|
|
|
async searchEvents(search: SearchEventsSchema): Promise<IEventList> {
|
2023-09-29 14:18:21 +02:00
|
|
|
const totalEvents = await this.eventStore.filteredCount(search);
|
|
|
|
const events = await this.eventStore.searchEvents(search);
|
2022-09-02 08:35:31 +02:00
|
|
|
return {
|
|
|
|
events,
|
|
|
|
totalEvents,
|
|
|
|
};
|
2021-09-20 12:13:38 +02:00
|
|
|
}
|
2023-09-27 15:23:05 +02:00
|
|
|
|
|
|
|
async onEvent(
|
|
|
|
eventName: string | symbol,
|
|
|
|
listener: (...args: any[]) => void,
|
|
|
|
): Promise<EventEmitter> {
|
|
|
|
return this.eventStore.on(eventName, listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
private async enhanceEventsWithTags(
|
|
|
|
events: IBaseEvent[],
|
|
|
|
): Promise<IBaseEvent[]> {
|
|
|
|
const featureNamesSet = new Set<string>();
|
|
|
|
for (const event of events) {
|
|
|
|
if (event.featureName && !event.tags) {
|
|
|
|
featureNamesSet.add(event.featureName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const featureTagsMap: Map<string, ITag[]> = new Map();
|
|
|
|
const allTagsInFeatures = await this.featureTagStore.getAllByFeatures(
|
|
|
|
Array.from(featureNamesSet),
|
|
|
|
);
|
|
|
|
|
|
|
|
for (const tag of allTagsInFeatures) {
|
|
|
|
const featureTags = featureTagsMap.get(tag.featureName) || [];
|
|
|
|
featureTags.push({ value: tag.tagValue, type: tag.tagType });
|
|
|
|
featureTagsMap.set(tag.featureName, featureTags);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const event of events) {
|
|
|
|
if (event.featureName && !event.tags) {
|
|
|
|
event.tags = featureTagsMap.get(event.featureName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return events;
|
|
|
|
}
|
|
|
|
|
2024-01-17 16:55:59 +01:00
|
|
|
isAdminToken(user: IUser | IApiUser): boolean {
|
|
|
|
return (user as IApiUser)?.type === ApiTokenType.ADMIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
getUserDetails(user: IUser | IApiUser): {
|
|
|
|
createdBy: string;
|
|
|
|
createdByUserId: number;
|
|
|
|
} {
|
|
|
|
return {
|
|
|
|
createdBy:
|
|
|
|
(user as IUser)?.email ||
|
|
|
|
user?.username ||
|
|
|
|
(this.isAdminToken(user)
|
|
|
|
? ADMIN_TOKEN_USER.username
|
|
|
|
: SYSTEM_USER.username),
|
|
|
|
createdByUserId:
|
|
|
|
(user as IUser)?.id ||
|
|
|
|
(user as IApiUser)?.internalAdminTokenUserId ||
|
|
|
|
SYSTEM_USER.id,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated use storeUserEvent instead
|
|
|
|
*/
|
2023-09-27 15:23:05 +02:00
|
|
|
async storeEvent(event: IBaseEvent): Promise<void> {
|
|
|
|
return this.storeEvents([event]);
|
|
|
|
}
|
|
|
|
|
2024-01-17 16:55:59 +01:00
|
|
|
/**
|
|
|
|
* @deprecated use storeUserEvents instead
|
|
|
|
*/
|
2023-09-27 15:23:05 +02:00
|
|
|
async storeEvents(events: IBaseEvent[]): Promise<void> {
|
|
|
|
let enhancedEvents = events;
|
|
|
|
for (const enhancer of [this.enhanceEventsWithTags.bind(this)]) {
|
|
|
|
enhancedEvents = await enhancer(enhancedEvents);
|
|
|
|
}
|
|
|
|
return this.eventStore.batchStore(enhancedEvents);
|
|
|
|
}
|
2024-01-17 16:55:59 +01:00
|
|
|
|
|
|
|
async storeUserEvent(event: IUserEvent): Promise<void> {
|
|
|
|
return this.storeUserEvents([event]);
|
|
|
|
}
|
|
|
|
|
|
|
|
async storeUserEvents(events: IUserEvent[]): Promise<void> {
|
|
|
|
let enhancedEvents = events.map(({ byUser, ...event }) => {
|
|
|
|
return {
|
|
|
|
...event,
|
|
|
|
...this.getUserDetails(byUser),
|
|
|
|
};
|
|
|
|
});
|
|
|
|
for (const enhancer of [this.enhanceEventsWithTags.bind(this)]) {
|
|
|
|
enhancedEvents = await enhancer(enhancedEvents);
|
|
|
|
}
|
|
|
|
return this.eventStore.batchStore(enhancedEvents);
|
|
|
|
}
|
2021-04-22 10:07:10 +02:00
|
|
|
}
|