mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
refactor(api): centrelize lifecycle-hook-manager types
This commit is contained in:
parent
911d1fb3df
commit
3e22921401
@ -8,17 +8,17 @@
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import {
|
||||
Document,
|
||||
Model,
|
||||
Query,
|
||||
Types,
|
||||
UpdateQuery,
|
||||
UpdateWithAggregationPipeline,
|
||||
} from 'mongoose';
|
||||
import { Model, Types } from 'mongoose';
|
||||
|
||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import {
|
||||
Args,
|
||||
postDelete,
|
||||
preCreate,
|
||||
preDelete,
|
||||
preUpdate,
|
||||
preUpdateMany,
|
||||
} from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { BlockCreateDto, BlockDto, BlockUpdateDto } from '../dto/block.dto';
|
||||
import {
|
||||
@ -63,10 +63,8 @@ export class BlockRepository extends BaseRepository<
|
||||
*
|
||||
* @param doc - The document that is being created.
|
||||
*/
|
||||
async preCreate(
|
||||
_doc: Document<unknown, object, Block> & Block & { _id: Types.ObjectId },
|
||||
): Promise<void> {
|
||||
if (_doc) this.checkDeprecatedAttachmentUrl(_doc);
|
||||
async preCreate(...[doc]: Args<preCreate<Block>>): Promise<void> {
|
||||
if (doc) this.checkDeprecatedAttachmentUrl(doc);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,19 +75,9 @@ export class BlockRepository extends BaseRepository<
|
||||
* @param updates - The update data.
|
||||
*/
|
||||
async preUpdate(
|
||||
_query: Query<
|
||||
Document<Block, any, any>,
|
||||
Document<Block, any, any>,
|
||||
unknown,
|
||||
Block,
|
||||
'findOneAndUpdate'
|
||||
>,
|
||||
criteria: TFilterQuery<Block>,
|
||||
updates:
|
||||
| UpdateWithAggregationPipeline
|
||||
| UpdateQuery<Document<Block, any, any>>,
|
||||
...[, criteria, updates]: Args<preUpdate<Block>>
|
||||
): Promise<void> {
|
||||
const update: BlockUpdateDto = updates?.['$set'];
|
||||
const update = '$set' in updates ? updates.$set : {};
|
||||
|
||||
if (update?.category) {
|
||||
const movedBlock = await this.findOne(criteria);
|
||||
@ -109,7 +97,10 @@ export class BlockRepository extends BaseRepository<
|
||||
{ $set: { attachedBlock: null } },
|
||||
);
|
||||
}
|
||||
this.checkDeprecatedAttachmentUrl(update);
|
||||
|
||||
if (update) {
|
||||
this.checkDeprecatedAttachmentUrl(update);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,18 +111,10 @@ export class BlockRepository extends BaseRepository<
|
||||
* @param updates - The update data.
|
||||
*/
|
||||
async preUpdateMany(
|
||||
_query: Query<
|
||||
Document<Block, any, any>,
|
||||
Document<Block, any, any>,
|
||||
unknown,
|
||||
Block,
|
||||
'updateMany',
|
||||
Record<string, never>
|
||||
>,
|
||||
criteria: TFilterQuery<Block>,
|
||||
updates: UpdateQuery<Document<Block, any, any>>,
|
||||
...[, criteria, updates]: Args<preUpdateMany<Block>>
|
||||
): Promise<void> {
|
||||
const categoryId: string = updates.$set.category;
|
||||
const categoryId = '$set' in updates && updates.$set?.category;
|
||||
|
||||
if (categoryId) {
|
||||
const movedBlocks = await this.find(criteria);
|
||||
|
||||
@ -226,16 +209,7 @@ export class BlockRepository extends BaseRepository<
|
||||
* @param query - The delete query.
|
||||
* @param result - The result of the delete operation.
|
||||
*/
|
||||
async postDelete(
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<Block, any, any>,
|
||||
unknown,
|
||||
Block,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
result: DeleteResult,
|
||||
) {
|
||||
async postDelete(...[, result]: Args<postDelete<Block>>) {
|
||||
if (result.deletedCount > 0) {
|
||||
}
|
||||
}
|
||||
@ -247,16 +221,7 @@ export class BlockRepository extends BaseRepository<
|
||||
* @param query - The delete query.
|
||||
* @param criteria - The filter criteria for finding blocks to delete.
|
||||
*/
|
||||
async preDelete(
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<Block, any, any>,
|
||||
unknown,
|
||||
Block,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
criteria: TFilterQuery<Block>,
|
||||
) {
|
||||
async preDelete(...[, criteria]: Args<preDelete<Block>>) {
|
||||
const docsToDelete = await this.model.find(criteria);
|
||||
const idsToDelete = docsToDelete.map(({ id }) => id);
|
||||
if (idsToDelete.length > 0) {
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
import { ForbiddenException, Injectable, Optional } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import { Document, Model, Query } from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import { Args, preDelete } from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { CategoryDto } from '../dto/category.dto';
|
||||
import { Category } from '../schemas/category.schema';
|
||||
@ -41,16 +41,7 @@ export class CategoryRepository extends BaseRepository<
|
||||
* @param query - The delete query.
|
||||
* @param criteria - The filter criteria for finding blocks to delete.
|
||||
*/
|
||||
async preDelete(
|
||||
query: Query<
|
||||
DeleteResult,
|
||||
Document<Category, any, any>,
|
||||
unknown,
|
||||
Category,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
criteria: TFilterQuery<Category>,
|
||||
) {
|
||||
async preDelete(...[query, criteria]: Args<preDelete<Category>>) {
|
||||
criteria = query.getQuery();
|
||||
const ids = Array.isArray(criteria._id?.$in)
|
||||
? criteria._id.$in
|
||||
|
@ -13,10 +13,10 @@ import {
|
||||
Optional,
|
||||
} from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import { Document, Model, Query } from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import { Args, preDelete } from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { ContextVarDto } from '../dto/context-var.dto';
|
||||
import { ContextVar } from '../schemas/context-var.schema';
|
||||
@ -47,16 +47,7 @@ export class ContextVarRepository extends BaseRepository<
|
||||
* @param query - The delete query.
|
||||
* @param criteria - The filter criteria for finding context vars to delete.
|
||||
*/
|
||||
async preDelete(
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<ContextVar, any, any>,
|
||||
unknown,
|
||||
ContextVar,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
criteria: TFilterQuery<ContextVar>,
|
||||
) {
|
||||
async preDelete(...[, criteria]: Args<preDelete<ContextVar>>) {
|
||||
const ids = Array.isArray(criteria._id) ? criteria._id : [criteria._id];
|
||||
|
||||
for (const id of ids) {
|
||||
|
@ -8,16 +8,19 @@
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import { Document, Model, Query } from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import {
|
||||
Args,
|
||||
postCreate,
|
||||
preDelete,
|
||||
} from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { LabelDto } from '../dto/label.dto';
|
||||
import {
|
||||
Label,
|
||||
LABEL_POPULATE,
|
||||
LabelDocument,
|
||||
LabelFull,
|
||||
LabelPopulate,
|
||||
} from '../schemas/label.schema';
|
||||
@ -40,7 +43,7 @@ export class LabelRepository extends BaseRepository<
|
||||
*
|
||||
* @returns A promise that resolves when the update operation is complete.
|
||||
*/
|
||||
async postCreate(created: LabelDocument): Promise<void> {
|
||||
async postCreate(...[created]: Args<postCreate<Label>>): Promise<void> {
|
||||
this.eventEmitter.emit(
|
||||
'hook:label:create',
|
||||
created,
|
||||
@ -68,16 +71,7 @@ export class LabelRepository extends BaseRepository<
|
||||
*
|
||||
* @returns {Promise<void>} A promise that resolves once the event is emitted.
|
||||
*/
|
||||
async preDelete(
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<Label, any, any>,
|
||||
unknown,
|
||||
Label,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
_criteria: TFilterQuery<Label>,
|
||||
): Promise<void> {
|
||||
async preDelete(...[, _criteria]: Args<preDelete<Label>>): Promise<void> {
|
||||
const ids = Array.isArray(_criteria._id?.$in)
|
||||
? _criteria._id.$in
|
||||
: Array.isArray(_criteria._id)
|
||||
|
@ -8,23 +8,20 @@
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import {
|
||||
Document,
|
||||
Model,
|
||||
Query,
|
||||
UpdateQuery,
|
||||
UpdateWithAggregationPipeline,
|
||||
} from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BotStatsType } from '@/analytics/schemas/bot-stats.schema';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import {
|
||||
Args,
|
||||
postCreate,
|
||||
preUpdate,
|
||||
} from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { SubscriberDto, SubscriberUpdateDto } from '../dto/subscriber.dto';
|
||||
import {
|
||||
Subscriber,
|
||||
SUBSCRIBER_POPULATE,
|
||||
SubscriberDocument,
|
||||
SubscriberFull,
|
||||
SubscriberPopulate,
|
||||
} from '../schemas/subscriber.schema';
|
||||
@ -45,7 +42,7 @@ export class SubscriberRepository extends BaseRepository<
|
||||
*
|
||||
* @param created - The newly created subscriber document.
|
||||
*/
|
||||
async postCreate(created: SubscriberDocument): Promise<void> {
|
||||
async postCreate(...[created]: Args<postCreate<Subscriber>>): Promise<void> {
|
||||
this.eventEmitter.emit(
|
||||
'hook:stats:entry',
|
||||
BotStatsType.new_users,
|
||||
@ -63,17 +60,7 @@ export class SubscriberRepository extends BaseRepository<
|
||||
* @param updates - The update data, which may include fields like `assignedTo`.
|
||||
*/
|
||||
async preUpdate(
|
||||
_query: Query<
|
||||
Document<Subscriber, any, any>,
|
||||
Document<Subscriber, any, any>,
|
||||
unknown,
|
||||
Subscriber,
|
||||
'findOneAndUpdate'
|
||||
>,
|
||||
criteria: TFilterQuery<Subscriber>,
|
||||
updates:
|
||||
| UpdateWithAggregationPipeline
|
||||
| UpdateQuery<Document<Subscriber, any, any>>,
|
||||
...[, criteria, updates]: Args<preUpdate<Subscriber>>
|
||||
): Promise<void> {
|
||||
const subscriberUpdates: SubscriberUpdateDto = updates?.['$set'];
|
||||
|
||||
|
@ -8,11 +8,11 @@
|
||||
|
||||
import { ForbiddenException, Injectable, Optional } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import { Document, Model, Query } from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BlockService } from '@/chat/services/block.service';
|
||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import { Args, preDelete } from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { ContentTypeDto } from '../dto/contentType.dto';
|
||||
import { ContentType } from '../schemas/content-type.schema';
|
||||
@ -42,25 +42,16 @@ export class ContentTypeRepository extends BaseRepository<
|
||||
* @param query - The query object used for deletion.
|
||||
* @param criteria - The filter query to identify the content type entity to delete.
|
||||
*/
|
||||
async preDelete(
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<ContentType, any, any>,
|
||||
unknown,
|
||||
ContentType,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
criteria: TFilterQuery<ContentType>,
|
||||
) {
|
||||
const entityId: string = criteria._id as string;
|
||||
async preDelete(...[, criteria]: Args<preDelete<ContentType>>) {
|
||||
const entityId = criteria._id;
|
||||
const associatedBlocks = await this.blockService?.findOne({
|
||||
'options.content.entity': entityId,
|
||||
});
|
||||
if (associatedBlocks) {
|
||||
throw new ForbiddenException(`Content type have blocks associated to it`);
|
||||
}
|
||||
if (criteria._id) {
|
||||
await this.contentModel.deleteMany({ entity: criteria._id });
|
||||
if (entityId) {
|
||||
await this.contentModel.deleteMany({ entity: entityId });
|
||||
} else {
|
||||
throw new Error(
|
||||
'Attempted to delete content type using unknown criteria',
|
||||
|
@ -8,17 +8,14 @@
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import {
|
||||
Document,
|
||||
HydratedDocument,
|
||||
Model,
|
||||
Query,
|
||||
UpdateQuery,
|
||||
UpdateWithAggregationPipeline,
|
||||
} from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import {
|
||||
Args,
|
||||
preCreate,
|
||||
preUpdate,
|
||||
} from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { ContentDto } from '../dto/content.dto';
|
||||
import {
|
||||
@ -45,7 +42,7 @@ export class ContentRepository extends BaseRepository<
|
||||
*
|
||||
* @param doc - The document that is about to be created.
|
||||
*/
|
||||
async preCreate(_doc: HydratedDocument<Content>) {
|
||||
async preCreate(...[_doc]: Args<preCreate<Content>>) {
|
||||
_doc.set('rag', this.stringify(_doc.dynamicFields));
|
||||
}
|
||||
|
||||
@ -58,17 +55,7 @@ export class ContentRepository extends BaseRepository<
|
||||
* @param updates - The update operations to be applied to the document.
|
||||
*/
|
||||
async preUpdate(
|
||||
_query: Query<
|
||||
Document<Content, any, any>,
|
||||
Document<Content, any, any>,
|
||||
unknown,
|
||||
Content,
|
||||
'findOneAndUpdate'
|
||||
>,
|
||||
_criteria: TFilterQuery<Content>,
|
||||
_updates:
|
||||
| UpdateWithAggregationPipeline
|
||||
| UpdateQuery<Document<Content, any, any>>,
|
||||
...[_query, , _updates]: Args<preUpdate<Content>>
|
||||
): Promise<void> {
|
||||
if ('dynamicFields' in _updates['$set']) {
|
||||
_query.set('rag', this.stringify(_updates['$set']['dynamicFields']));
|
||||
|
@ -8,16 +8,20 @@
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import { Document, Model, Query } from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import {
|
||||
Args,
|
||||
postCreate,
|
||||
postUpdate,
|
||||
preDelete,
|
||||
} from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { NlpEntityDto } from '../dto/nlp-entity.dto';
|
||||
import {
|
||||
NLP_ENTITY_POPULATE,
|
||||
NlpEntity,
|
||||
NlpEntityDocument,
|
||||
NlpEntityFull,
|
||||
NlpEntityPopulate,
|
||||
} from '../schemas/nlp-entity.schema';
|
||||
@ -47,7 +51,7 @@ export class NlpEntityRepository extends BaseRepository<
|
||||
*
|
||||
* @param created - The newly created NLP entity document.
|
||||
*/
|
||||
async postCreate(_created: NlpEntityDocument): Promise<void> {
|
||||
async postCreate(...[_created]: Args<postCreate<NlpEntity>>): Promise<void> {
|
||||
if (!_created.builtin) {
|
||||
// Bypass builtin entities (probably fixtures)
|
||||
this.eventEmitter.emit('hook:nlpEntity:create', _created);
|
||||
@ -62,16 +66,7 @@ export class NlpEntityRepository extends BaseRepository<
|
||||
* @param query - The query used to find and update the entity.
|
||||
* @param updated - The updated NLP entity document.
|
||||
*/
|
||||
async postUpdate(
|
||||
_query: Query<
|
||||
Document<NlpEntity, any, any>,
|
||||
Document<NlpEntity, any, any>,
|
||||
unknown,
|
||||
NlpEntity,
|
||||
'findOneAndUpdate'
|
||||
>,
|
||||
updated: NlpEntity,
|
||||
): Promise<void> {
|
||||
async postUpdate(...[, updated]: Args<postUpdate<NlpEntity>>): Promise<void> {
|
||||
if (!updated?.builtin) {
|
||||
// Bypass builtin entities (probably fixtures)
|
||||
this.eventEmitter.emit('hook:nlpEntity:update', updated);
|
||||
@ -87,16 +82,7 @@ export class NlpEntityRepository extends BaseRepository<
|
||||
* @param query The query used to delete the entity.
|
||||
* @param criteria The filter criteria used to find the entity for deletion.
|
||||
*/
|
||||
async preDelete(
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<NlpEntity, any, any>,
|
||||
unknown,
|
||||
NlpEntity,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
criteria: TFilterQuery<NlpEntity>,
|
||||
): Promise<void> {
|
||||
async preDelete(...[, criteria]: Args<preDelete<NlpEntity>>): Promise<void> {
|
||||
if (criteria._id) {
|
||||
await this.nlpValueRepository.deleteMany({ entity: criteria._id });
|
||||
await this.nlpSampleEntityRepository.deleteMany({ entity: criteria._id });
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import { Document, Model, Query } from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import { Args, preDelete } from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { TNlpSampleDto } from '../dto/nlp-sample.dto';
|
||||
import {
|
||||
@ -43,16 +43,7 @@ export class NlpSampleRepository extends BaseRepository<
|
||||
* @param query - The query object used for deletion.
|
||||
* @param criteria - Criteria to identify the sample(s) to delete.
|
||||
*/
|
||||
async preDelete(
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<NlpSample, any, any>,
|
||||
unknown,
|
||||
NlpSample,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
criteria: TFilterQuery<NlpSample>,
|
||||
) {
|
||||
async preDelete(...[, criteria]: Args<preDelete<NlpSample>>) {
|
||||
if (criteria._id) {
|
||||
await this.nlpSampleEntityRepository.deleteMany({
|
||||
sample: criteria._id,
|
||||
|
@ -9,25 +9,23 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import {
|
||||
Document,
|
||||
Model,
|
||||
PipelineStage,
|
||||
Query,
|
||||
SortOrder,
|
||||
Types,
|
||||
} from 'mongoose';
|
||||
import { Model, PipelineStage, SortOrder, Types } from 'mongoose';
|
||||
|
||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import { PageQueryDto } from '@/utils/pagination/pagination-query.dto';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import { Format } from '@/utils/types/format.types';
|
||||
import {
|
||||
Args,
|
||||
postCreate,
|
||||
postUpdate,
|
||||
preDelete,
|
||||
} from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { NlpValueDto } from '../dto/nlp-value.dto';
|
||||
import {
|
||||
NLP_VALUE_POPULATE,
|
||||
NlpValue,
|
||||
NlpValueDocument,
|
||||
NlpValueFull,
|
||||
NlpValueFullWithCount,
|
||||
NlpValuePopulate,
|
||||
@ -56,7 +54,7 @@ export class NlpValueRepository extends BaseRepository<
|
||||
*
|
||||
* @param created - The newly created NLP value document.
|
||||
*/
|
||||
async postCreate(created: NlpValueDocument): Promise<void> {
|
||||
async postCreate(...[created]: Args<postCreate<NlpValue>>): Promise<void> {
|
||||
if (!created.builtin) {
|
||||
// Bypass builtin entities (probably fixtures)
|
||||
this.eventEmitter.emit('hook:nlpValue:create', created);
|
||||
@ -69,16 +67,7 @@ export class NlpValueRepository extends BaseRepository<
|
||||
* @param query - The query that was used to update the NLP value.
|
||||
* @param updated - The updated NLP value document.
|
||||
*/
|
||||
async postUpdate(
|
||||
_query: Query<
|
||||
Document<NlpValue, any, any>,
|
||||
Document<NlpValue, any, any>,
|
||||
unknown,
|
||||
NlpValue,
|
||||
'findOneAndUpdate'
|
||||
>,
|
||||
updated: NlpValue,
|
||||
): Promise<void> {
|
||||
async postUpdate(...[, updated]: Args<postUpdate<NlpValue>>): Promise<void> {
|
||||
if (!updated?.builtin) {
|
||||
// Bypass builtin entities (probably fixtures)
|
||||
this.eventEmitter.emit('hook:nlpValue:update', updated);
|
||||
@ -92,16 +81,7 @@ export class NlpValueRepository extends BaseRepository<
|
||||
* @param _query - The query used to delete the NLP value(s).
|
||||
* @param criteria - The filter criteria used to identify the NLP value(s) to delete.
|
||||
*/
|
||||
async preDelete(
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<NlpValue, any, any>,
|
||||
unknown,
|
||||
NlpValue,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
criteria: TFilterQuery<NlpValue>,
|
||||
): Promise<void> {
|
||||
async preDelete(...[, criteria]: Args<preDelete<NlpValue>>): Promise<void> {
|
||||
if (criteria._id) {
|
||||
await this.nlpSampleEntityRepository.deleteMany({ value: criteria._id });
|
||||
|
||||
|
@ -9,17 +9,15 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { IHookSettingsGroupLabelOperationMap } from '@nestjs/event-emitter';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import {
|
||||
Document,
|
||||
FilterQuery,
|
||||
Model,
|
||||
Query,
|
||||
Types,
|
||||
UpdateQuery,
|
||||
UpdateWithAggregationPipeline,
|
||||
} from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import {
|
||||
Args,
|
||||
postUpdate,
|
||||
preCreateValidate,
|
||||
preUpdateValidate,
|
||||
} from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { Setting } from '../schemas/setting.schema';
|
||||
import { SettingType } from '../schemas/types';
|
||||
@ -30,16 +28,12 @@ export class SettingRepository extends BaseRepository<Setting> {
|
||||
super(model, Setting);
|
||||
}
|
||||
|
||||
async preCreateValidate(
|
||||
doc: Document<unknown, unknown, Setting> &
|
||||
Setting & { _id: Types.ObjectId },
|
||||
) {
|
||||
async preCreateValidate(...[doc]: Args<preCreateValidate<Setting>>) {
|
||||
this.validateSettingValue(doc.type, doc.value);
|
||||
}
|
||||
|
||||
async preUpdateValidate(
|
||||
criteria: FilterQuery<Setting>,
|
||||
updates: UpdateWithAggregationPipeline | UpdateQuery<Setting>,
|
||||
...[criteria, updates]: Args<preUpdateValidate<Setting>>
|
||||
): Promise<void> {
|
||||
if (!Array.isArray(updates)) {
|
||||
const payload = updates.$set;
|
||||
@ -70,21 +64,12 @@ export class SettingRepository extends BaseRepository<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 '*';
|
||||
async postUpdate(...[, updated]: Args<postUpdate<Setting>>) {
|
||||
const group = updated.group as keyof IHookSettingsGroupLabelOperationMap;
|
||||
const label = updated.label as '*';
|
||||
|
||||
// Sync global settings var
|
||||
this.eventEmitter.emit(`hook:${group}:${label}`, setting);
|
||||
this.eventEmitter.emit(`hook:${group}:${label}`, updated);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,22 +8,19 @@
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import {
|
||||
Document,
|
||||
Model,
|
||||
Query,
|
||||
UpdateQuery,
|
||||
UpdateWithAggregationPipeline,
|
||||
} from 'mongoose';
|
||||
import { Model } from 'mongoose';
|
||||
|
||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import {
|
||||
Args,
|
||||
preCreate,
|
||||
preUpdate,
|
||||
} from '@/utils/types/lifecycle-hook-manager.types';
|
||||
|
||||
import { UserDto, UserEditProfileDto } from '../dto/user.dto';
|
||||
import {
|
||||
User,
|
||||
USER_POPULATE,
|
||||
UserDocument,
|
||||
UserFull,
|
||||
UserPopulate,
|
||||
} from '../schemas/user.schema';
|
||||
@ -46,7 +43,7 @@ export class UserRepository extends BaseRepository<
|
||||
*
|
||||
* @param _doc The user document being created.
|
||||
*/
|
||||
async preCreate(_doc: UserDocument) {
|
||||
async preCreate(...[_doc]: Args<preCreate<User>>) {
|
||||
if (_doc?.password) {
|
||||
_doc.password = hash(_doc.password);
|
||||
} else {
|
||||
@ -62,19 +59,7 @@ export class UserRepository extends BaseRepository<
|
||||
* @param _criteria The criteria used to filter the user documents to update.
|
||||
* @param _updates The update object that may contain password or resetToken to be hashed.
|
||||
*/
|
||||
async preUpdate(
|
||||
_query: Query<
|
||||
Document<User, any, any>,
|
||||
Document<User, any, any>,
|
||||
unknown,
|
||||
User,
|
||||
'findOneAndUpdate'
|
||||
>,
|
||||
_criteria: TFilterQuery<User>,
|
||||
_updates:
|
||||
| UpdateWithAggregationPipeline
|
||||
| UpdateQuery<Document<User, any, any>>,
|
||||
) {
|
||||
async preUpdate(...[_query, , _updates]: Args<preUpdate<User>>) {
|
||||
const updates: UserEditProfileDto & {
|
||||
resetToken?: string;
|
||||
} = _updates?.['$set'];
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
import { ClassTransformOptions, plainToClass } from 'class-transformer';
|
||||
import {
|
||||
Document,
|
||||
FilterQuery,
|
||||
FlattenMaps,
|
||||
HydratedDocument,
|
||||
Model,
|
||||
@ -23,7 +22,6 @@ import {
|
||||
Query,
|
||||
SortOrder,
|
||||
UpdateQuery,
|
||||
UpdateWithAggregationPipeline,
|
||||
UpdateWriteOpResult,
|
||||
} from 'mongoose';
|
||||
|
||||
@ -37,6 +35,22 @@ import {
|
||||
import { flatten } from '../helpers/flatten';
|
||||
import { PageQueryDto, QuerySortDto } from '../pagination/pagination-query.dto';
|
||||
import { DtoAction, DtoConfig, DtoInfer } from '../types/dto.types';
|
||||
import {
|
||||
Args,
|
||||
postCreate,
|
||||
postCreateValidate,
|
||||
postDelete,
|
||||
postUpdate,
|
||||
postUpdateMany,
|
||||
postUpdateValidate,
|
||||
preCreate,
|
||||
preCreateValidate,
|
||||
preDelete,
|
||||
preUpdate,
|
||||
preUpdateMany,
|
||||
preUpdateValidate,
|
||||
R,
|
||||
} from '../types/lifecycle-hook-manager.types';
|
||||
|
||||
import { BaseSchema } from './base-schema';
|
||||
import { LifecycleHookManager } from './lifecycle-hook-manager';
|
||||
@ -79,7 +93,7 @@ export abstract class BaseRepository<
|
||||
TFull extends Omit<T, P> = never,
|
||||
Dto extends DtoConfig = object,
|
||||
U extends Omit<T, keyof BaseSchema> = Omit<T, keyof BaseSchema>,
|
||||
D = Document<T>,
|
||||
D extends Document<T> = Document<T>,
|
||||
> {
|
||||
private readonly transformOpts = { excludePrefixes: ['_', 'password'] };
|
||||
|
||||
@ -567,80 +581,58 @@ export abstract class BaseRepository<
|
||||
}
|
||||
|
||||
async preCreateValidate(
|
||||
_doc: HydratedDocument<T>,
|
||||
_filterCriteria?: FilterQuery<T>,
|
||||
_updates?: UpdateWithAggregationPipeline | UpdateQuery<T>,
|
||||
): Promise<void> {
|
||||
..._: Args<preCreateValidate<T>>
|
||||
): R<preCreateValidate<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async postCreateValidate(_validated: HydratedDocument<T>): Promise<void> {
|
||||
async postCreateValidate(
|
||||
..._: Args<postCreateValidate<T>>
|
||||
): R<postCreateValidate<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async preUpdateValidate(
|
||||
_filterCriteria: FilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<T>,
|
||||
): Promise<void> {
|
||||
..._: Args<preUpdateValidate<T>>
|
||||
): R<preUpdateValidate<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async postUpdateValidate(
|
||||
_filterCriteria: FilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<T>,
|
||||
): Promise<void> {
|
||||
..._: Args<postUpdateValidate<T>>
|
||||
): R<postUpdateValidate<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async preCreate(_doc: HydratedDocument<T>): Promise<void> {
|
||||
async preCreate(..._: Args<preCreate<T>>): R<postCreate<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async postCreate(_created: HydratedDocument<T>): Promise<void> {
|
||||
async postCreate(..._: Args<postCreate<T>>): R<postCreate<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async preUpdate(
|
||||
_query: Query<D, D, unknown, T, 'findOneAndUpdate'>,
|
||||
_criteria: TFilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<D>,
|
||||
): Promise<void> {
|
||||
async preUpdate(..._: Args<preUpdate<T>>): R<preUpdate<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async preUpdateMany(
|
||||
_query: Query<D, D, unknown, T, 'updateMany'>,
|
||||
_criteria: TFilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<D>,
|
||||
): Promise<void> {
|
||||
async preUpdateMany(..._: Args<preUpdateMany<T>>): R<preUpdateMany<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async postUpdateMany(
|
||||
_query: Query<D, D, unknown, T, 'updateMany'>,
|
||||
_updated: any,
|
||||
): Promise<void> {
|
||||
async postUpdateMany(..._: Args<postUpdateMany<T>>): R<postUpdateMany<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async postUpdate(
|
||||
_query: Query<D, D, unknown, T, 'findOneAndUpdate'>,
|
||||
_updated: T,
|
||||
): Promise<void> {
|
||||
async postUpdate(..._: Args<postUpdate<T>>): R<preDelete<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async preDelete(
|
||||
_query: Query<DeleteResult, D, unknown, T, 'deleteOne' | 'deleteMany'>,
|
||||
_criteria: TFilterQuery<T>,
|
||||
): Promise<void> {
|
||||
async preDelete(..._: Args<preDelete<T>>): R<preDelete<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
|
||||
async postDelete(
|
||||
_query: Query<DeleteResult, D, unknown, T, 'deleteOne' | 'deleteMany'>,
|
||||
_result: DeleteResult,
|
||||
): Promise<void> {
|
||||
async postDelete(..._: Args<postDelete<T>>): R<postDelete<T>> {
|
||||
// Nothing ...
|
||||
}
|
||||
}
|
||||
|
91
api/src/utils/types/lifecycle-hook-manager.types.ts
Normal file
91
api/src/utils/types/lifecycle-hook-manager.types.ts
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
* 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 {
|
||||
Document,
|
||||
HydratedDocument,
|
||||
Query,
|
||||
UpdateQuery,
|
||||
UpdateWithAggregationPipeline,
|
||||
} from 'mongoose';
|
||||
|
||||
import { DeleteResult } from '../generics/base-repository';
|
||||
|
||||
import { TFilterQuery } from './filter.types';
|
||||
|
||||
export type Args<T extends (...args: any) => unknown> = Parameters<T>;
|
||||
|
||||
export type R<T extends (...args: any) => unknown> = ReturnType<T>;
|
||||
|
||||
export type preCreateValidate<T> = (
|
||||
_doc: HydratedDocument<T>,
|
||||
_filterCriteria?: TFilterQuery<T>,
|
||||
_updates?: UpdateWithAggregationPipeline | UpdateQuery<T>,
|
||||
) => Promise<void>;
|
||||
|
||||
export type postCreateValidate<T> = (
|
||||
_validated: HydratedDocument<T>,
|
||||
) => Promise<void>;
|
||||
|
||||
export type preUpdateValidate<T> = (
|
||||
_filterCriteria: TFilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<T>,
|
||||
) => Promise<void>;
|
||||
|
||||
export type postUpdateValidate<T> = (
|
||||
_filterCriteria: TFilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<T>,
|
||||
) => Promise<void>;
|
||||
|
||||
export type preCreate<T> = (_doc: HydratedDocument<T>) => Promise<void>;
|
||||
|
||||
export type postCreate<T> = (_created: HydratedDocument<T>) => Promise<void>;
|
||||
|
||||
export type preUpdate<T> = (
|
||||
_query: Query<Document<T>, Document<T>, unknown, T, 'findOneAndUpdate'>,
|
||||
_criteria: TFilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<Document<T>>,
|
||||
) => Promise<void>;
|
||||
|
||||
export type preUpdateMany<T> = (
|
||||
_query: Query<Document<T>, Document<T>, unknown, T, 'updateMany'>,
|
||||
_criteria: TFilterQuery<T>,
|
||||
_updates: UpdateWithAggregationPipeline | UpdateQuery<Document<T>>,
|
||||
) => Promise<void>;
|
||||
|
||||
export type postUpdateMany<T> = (
|
||||
_query: Query<Document<T>, Document<T>, unknown, T, 'updateMany'>,
|
||||
_updated: any,
|
||||
) => Promise<void>;
|
||||
|
||||
export type postUpdate<T> = (
|
||||
_query: Query<Document<T>, Document<T>, unknown, T, 'findOneAndUpdate'>,
|
||||
_updated: T,
|
||||
) => Promise<void>;
|
||||
|
||||
export type preDelete<T> = (
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<T>,
|
||||
unknown,
|
||||
T,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
_criteria: TFilterQuery<T>,
|
||||
) => Promise<void>;
|
||||
|
||||
export type postDelete<T> = (
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<T>,
|
||||
unknown,
|
||||
T,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
_result: DeleteResult,
|
||||
) => Promise<void>;
|
Loading…
Reference in New Issue
Block a user