mirror of
https://github.com/hexastack/hexabot
synced 2025-04-03 12:52:06 +00:00
fix: pre/post validate event typing
This commit is contained in:
parent
6b7a5bf0a2
commit
943b2dd3d2
@ -7,24 +7,19 @@
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import {
|
||||
EventEmitter2,
|
||||
IHookSettingsGroupLabelOperationMap,
|
||||
} from '@nestjs/event-emitter';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import {
|
||||
Document,
|
||||
FilterQuery,
|
||||
Model,
|
||||
Query,
|
||||
Types,
|
||||
UpdateQuery,
|
||||
UpdateWithAggregationPipeline,
|
||||
} from 'mongoose';
|
||||
|
||||
import { I18nService } from '@/i18n/services/i18n.service';
|
||||
import { BaseRepository, EHook } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
|
||||
import { Setting } from '../schemas/setting.schema';
|
||||
import { SettingType } from '../schemas/types';
|
||||
@ -42,64 +37,24 @@ export class SettingRepository extends BaseRepository<Setting> {
|
||||
async preCreateValidate(
|
||||
doc: Document<unknown, unknown, Setting> &
|
||||
Setting & { _id: Types.ObjectId },
|
||||
filterCriteria: FilterQuery<Setting>,
|
||||
updates: UpdateWithAggregationPipeline | UpdateQuery<Setting>,
|
||||
) {
|
||||
this.validateSettingValue(doc.type, doc.value);
|
||||
if (filterCriteria && updates) {
|
||||
this.eventEmitter.emit(
|
||||
`hook:setting:${EHook.preUpdateValidate}`,
|
||||
filterCriteria,
|
||||
updates,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async preUpdateValidate(
|
||||
criteria: string | TFilterQuery<Setting>,
|
||||
dto: UpdateQuery<Setting>,
|
||||
filterCriteria: FilterQuery<Setting>,
|
||||
criteria: FilterQuery<Setting>,
|
||||
updates: UpdateWithAggregationPipeline | UpdateQuery<Setting>,
|
||||
): Promise<void> {
|
||||
const payload = dto.$set ? dto.$set : dto;
|
||||
if (typeof payload.value !== 'undefined') {
|
||||
const { type } =
|
||||
'type' in payload ? payload : await this.findOne(criteria);
|
||||
this.validateSettingValue(type, payload.value);
|
||||
this.eventEmitter.emit(
|
||||
`hook:setting:${EHook.preUpdateValidate}`,
|
||||
filterCriteria,
|
||||
updates,
|
||||
);
|
||||
if (!Array.isArray(updates)) {
|
||||
const payload = updates.$set;
|
||||
if (typeof payload.value !== 'undefined') {
|
||||
const { type } =
|
||||
'type' in payload ? payload : await this.findOne(criteria);
|
||||
this.validateSettingValue(type, payload.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event after a `Setting` has been updated.
|
||||
*
|
||||
* This method is used to synchronize global settings by emitting an event
|
||||
* based on the `group` and `label` of the `Setting`.
|
||||
*
|
||||
* @param _query The Mongoose query object used to find and update the document.
|
||||
* @param setting The updated `Setting` object.
|
||||
*/
|
||||
async postUpdate(
|
||||
_query: Query<
|
||||
Document<Setting, any, any>,
|
||||
Document<Setting, any, any>,
|
||||
unknown,
|
||||
Setting,
|
||||
'findOneAndUpdate'
|
||||
>,
|
||||
setting: Setting,
|
||||
) {
|
||||
const group = setting.group as keyof IHookSettingsGroupLabelOperationMap;
|
||||
const label = setting.label as '*';
|
||||
|
||||
// Sync global settings var
|
||||
this.eventEmitter.emit(`hook:${group}:${label}`, setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the `Setting` document after it has been retrieved.
|
||||
*
|
||||
|
@ -209,14 +209,10 @@ describe('BaseRepository', () => {
|
||||
await dummyRepository.updateOne(created.id, mockUpdate);
|
||||
|
||||
expect(spyPreUpdateValidate).toHaveBeenCalledWith(
|
||||
created.id,
|
||||
mockUpdate,
|
||||
mockGetFilterValue,
|
||||
mockGetUpdateValue,
|
||||
);
|
||||
expect(spyPostUpdateValidate).toHaveBeenCalledWith(
|
||||
created.id,
|
||||
mockUpdate,
|
||||
mockGetFilterValue,
|
||||
mockGetUpdateValue,
|
||||
);
|
||||
@ -261,8 +257,6 @@ describe('BaseRepository', () => {
|
||||
).rejects.toThrow('Mocked error while validating dummy');
|
||||
|
||||
expect(spyPreUpdateValidate).toHaveBeenCalledWith(
|
||||
created.id,
|
||||
mockUpdate,
|
||||
mockGetFilterValue,
|
||||
mockGetUpdateValue,
|
||||
);
|
||||
|
@ -39,19 +39,20 @@ export type DeleteResult = {
|
||||
};
|
||||
|
||||
export enum EHook {
|
||||
preCreateValidate = 'preCreateValidate',
|
||||
preCreate = 'preCreate',
|
||||
preUpdateValidate = 'preUpdateValidate',
|
||||
preUpdate = 'preUpdate',
|
||||
preUpdateMany = 'preUpdateMany',
|
||||
preDelete = 'preDelete',
|
||||
preCreateValidate = 'preCreateValidate',
|
||||
postCreateValidate = 'postCreateValidate',
|
||||
postCreate = 'postCreate',
|
||||
postUpdateValidate = 'postUpdateValidate',
|
||||
postUpdate = 'postUpdate',
|
||||
postUpdateMany = 'postUpdateMany',
|
||||
postDelete = 'postDelete',
|
||||
postCreateValidate = 'postCreateValidate',
|
||||
preUpdateValidate = 'preUpdateValidate',
|
||||
postUpdateValidate = 'postUpdateValidate',
|
||||
}
|
||||
|
||||
// ! ------------------------------------ Note --------------------------------------------
|
||||
// Methods like `update()`, `updateOne()`, `updateMany()`, `findOneAndUpdate()`,
|
||||
// `findByIdAndUpdate()`, `findOneAndReplace()`, `findOneAndDelete()`, and `findByIdAndDelete()`
|
||||
@ -476,8 +477,21 @@ export abstract class BaseRepository<
|
||||
);
|
||||
const filterCriteria = query.getFilter();
|
||||
const queryUpdates = query.getUpdate();
|
||||
await this.preUpdateValidate(criteria, dto, filterCriteria, queryUpdates);
|
||||
await this.postUpdateValidate(criteria, dto, filterCriteria, queryUpdates);
|
||||
|
||||
await this.preUpdateValidate(filterCriteria, queryUpdates);
|
||||
this.emitter.emit(
|
||||
this.getEventName(EHook.preUpdateValidate),
|
||||
filterCriteria,
|
||||
queryUpdates,
|
||||
);
|
||||
|
||||
await this.postUpdateValidate(filterCriteria, queryUpdates);
|
||||
this.emitter.emit(
|
||||
this.getEventName(EHook.postUpdateValidate),
|
||||
filterCriteria,
|
||||
queryUpdates,
|
||||
);
|
||||
|
||||
return await this.executeOne(query, this.cls);
|
||||
}
|
||||
|
||||
@ -512,18 +526,14 @@ export abstract class BaseRepository<
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async preUpdateValidate<D extends Partial<U>>(
|
||||
_criteria: string | TFilterQuery<T>,
|
||||
_dto: UpdateQuery<D>,
|
||||
async preUpdateValidate(
|
||||
_filterCriteria: FilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<T>,
|
||||
): Promise<void> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async postUpdateValidate<D extends Partial<U>>(
|
||||
_criteria: string | TFilterQuery<T>,
|
||||
_dto: UpdateQuery<D>,
|
||||
async postUpdateValidate(
|
||||
_filterCriteria: FilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<T>,
|
||||
): Promise<void> {
|
||||
|
38
api/types/event-emitter.d.ts
vendored
38
api/types/event-emitter.d.ts
vendored
@ -6,7 +6,7 @@
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
*/
|
||||
|
||||
import type { Document, FilterQuery, Query } from 'mongoose';
|
||||
import type { Document, Query } from 'mongoose';
|
||||
import { type Socket } from 'socket.io';
|
||||
|
||||
import { type BotStats } from '@/analytics/schemas/bot-stats.schema';
|
||||
@ -179,11 +179,13 @@ declare module '@nestjs/event-emitter' {
|
||||
type EventNamespaces = keyof IHookEntityOperationMap;
|
||||
|
||||
/* pre hooks */
|
||||
type TPreValidate<T> = THydratedDocument<T>;
|
||||
type TPreCreateValidate<T> = THydratedDocument<T>;
|
||||
|
||||
type TPreCreate<T> = THydratedDocument<T>;
|
||||
|
||||
type TPreUpdate<T> = TFilterQuery<T> & object;
|
||||
type TPreUpdateValidate<T> = FilterQuery<T>;
|
||||
|
||||
type TPreUpdate<T> = TFilterQuery<T>;
|
||||
|
||||
type TPreDelete<T> = Query<
|
||||
DeleteResult,
|
||||
@ -195,27 +197,27 @@ declare module '@nestjs/event-emitter' {
|
||||
>;
|
||||
|
||||
type TPreUnion<T> =
|
||||
| TPreValidate<T>
|
||||
| TPreCreateValidate<T>
|
||||
| TPreCreate<T>
|
||||
| TPreUpdateValidate<T>
|
||||
| TPreUpdate<T>
|
||||
| TPreDelete<T>;
|
||||
|
||||
/* post hooks */
|
||||
type TPostValidate<T> = THydratedDocument<T>;
|
||||
type TPostCreateValidate<T> = THydratedDocument<T>;
|
||||
|
||||
type TPostCreate<T> = THydratedDocument<T>;
|
||||
|
||||
type TPostUpdateValidate<T> = FilterQuery<T>;
|
||||
|
||||
type TPostUpdate<T> = THydratedDocument<T>;
|
||||
|
||||
type TPreUpdateValidate<T> = FilterQuery<T>;
|
||||
|
||||
type TPostUpdateValidate<T> = THydratedDocument<T>;
|
||||
|
||||
type TPostDelete = DeleteResult;
|
||||
|
||||
type TPostUnion<T> =
|
||||
| TPostValidate<T>
|
||||
| TPostCreateValidate<T>
|
||||
| TPostCreate<T>
|
||||
| TPostUpdateValidate<T>
|
||||
| TPostUpdate<T>
|
||||
| TPostDelete;
|
||||
|
||||
@ -251,11 +253,14 @@ declare module '@nestjs/event-emitter' {
|
||||
T = IHookEntityOperationMap[E]['schema'],
|
||||
> =
|
||||
| {
|
||||
[EHook.preCreateValidate]: TPreValidate<T>;
|
||||
[EHook.preCreateValidate]: TPreCreateValidate<T>;
|
||||
}
|
||||
| {
|
||||
[EHook.preCreate]: TPreCreate<T>;
|
||||
}
|
||||
| {
|
||||
[EHook.preUpdateValidate]: TPreUpdateValidate<T>;
|
||||
}
|
||||
| {
|
||||
[EHook.preUpdate]: TPreUpdate<T>;
|
||||
}
|
||||
@ -263,22 +268,19 @@ declare module '@nestjs/event-emitter' {
|
||||
[EHook.preDelete]: TPreDelete<T>;
|
||||
}
|
||||
| {
|
||||
[EHook.postCreateValidate]: TPostValidate<T>;
|
||||
[EHook.postCreateValidate]: TPostCreateValidate<T>;
|
||||
}
|
||||
| {
|
||||
[EHook.postCreate]: TPostCreate<T>;
|
||||
}
|
||||
| {
|
||||
[EHook.postUpdateValidate]: TPostUpdateValidate<T>;
|
||||
}
|
||||
| {
|
||||
[EHook.postUpdate]: TPostUpdate<T>;
|
||||
}
|
||||
| {
|
||||
[EHook.postDelete]: TPostDelete;
|
||||
}
|
||||
| {
|
||||
[EHook.preUpdateValidate]: TPreUpdateValidate<T>;
|
||||
}
|
||||
| {
|
||||
[EHook.postUpdateValidate]: TPostUpdateValidate<T>;
|
||||
};
|
||||
|
||||
type TNormalizedHook<E extends keyof IHookEntityOperationMap, O> = Extract<
|
||||
|
Loading…
Reference in New Issue
Block a user