diff --git a/api/src/attachment/controllers/attachment.controller.ts b/api/src/attachment/controllers/attachment.controller.ts index fbc3717a..f6586742 100644 --- a/api/src/attachment/controllers/attachment.controller.ts +++ b/api/src/attachment/controllers/attachment.controller.ts @@ -94,7 +94,7 @@ export class AttachmentController extends BaseController { ) filters: TFilterQuery, ) { - return await this.attachmentService.findPage(filters, pageQuery); + return await this.attachmentService.find(filters, pageQuery); } /** diff --git a/api/src/chat/controllers/message.controller.ts b/api/src/chat/controllers/message.controller.ts index bddaf5a4..8bfc633c 100644 --- a/api/src/chat/controllers/message.controller.ts +++ b/api/src/chat/controllers/message.controller.ts @@ -55,7 +55,7 @@ import { SubscriberService } from '../services/subscriber.service'; @UseInterceptors(CsrfInterceptor) @Controller('message') export class MessageController extends BaseController< - Message, + AnyMessage, MessageStub, MessagePopulate, MessageFull diff --git a/api/src/chat/repositories/message.repository.ts b/api/src/chat/repositories/message.repository.ts index 64bd99f4..72fbe300 100644 --- a/api/src/chat/repositories/message.repository.ts +++ b/api/src/chat/repositories/message.repository.ts @@ -72,7 +72,7 @@ export class MessageRepository extends BaseRepository< until = new Date(), limit: number = 30, ) { - return await this.findPage( + return await this.find( { $or: [{ recipient: subscriber.id }, { sender: subscriber.id }], createdAt: { $lt: until }, @@ -96,7 +96,7 @@ export class MessageRepository extends BaseRepository< since = new Date(), limit: number = 30, ) { - return await this.findPage( + return await this.find( { $or: [{ recipient: subscriber.id }, { sender: subscriber.id }], createdAt: { $gt: since }, diff --git a/api/src/chat/repositories/subscriber.repository.ts b/api/src/chat/repositories/subscriber.repository.ts index 9c81cfdd..a3ee6cd1 100644 --- a/api/src/chat/repositories/subscriber.repository.ts +++ b/api/src/chat/repositories/subscriber.repository.ts @@ -106,7 +106,7 @@ export class SubscriberRepository extends BaseRepository< * @returns The constructed query object. */ findByForeignIdQuery(id: string) { - return this.findPageQuery( + return this.findQuery( { foreign_id: id }, { skip: 0, limit: 1, sort: ['lastvisit', 'desc'] }, ); diff --git a/api/src/chat/services/message.service.ts b/api/src/chat/services/message.service.ts index c66d0903..67474daa 100644 --- a/api/src/chat/services/message.service.ts +++ b/api/src/chat/services/message.service.ts @@ -126,7 +126,7 @@ export class MessageService extends BaseService< * @returns The message history since the specified date. */ async findLastMessages(subscriber: Subscriber, limit: number = 5) { - const lastMessages = await this.findPage( + const lastMessages = await this.find( { $or: [{ sender: subscriber.id }, { recipient: subscriber.id }], }, diff --git a/api/src/cms/controllers/content.controller.ts b/api/src/cms/controllers/content.controller.ts index b807b051..5f4bf0c5 100644 --- a/api/src/cms/controllers/content.controller.ts +++ b/api/src/cms/controllers/content.controller.ts @@ -283,10 +283,7 @@ export class ContentController extends BaseController< ); throw new NotFoundException(`ContentType of id ${contentType} not found`); } - return await this.contentService.findPage( - { entity: contentType }, - pageQuery, - ); + return await this.contentService.find({ entity: contentType }, pageQuery); } /** diff --git a/api/src/cms/services/content.service.ts b/api/src/cms/services/content.service.ts index bdcac780..03883828 100644 --- a/api/src/cms/services/content.service.ts +++ b/api/src/cms/services/content.service.ts @@ -170,7 +170,7 @@ export class ContentService extends BaseService< } try { - const contents = await this.findPage(query, { + const contents = await this.find(query, { skip, limit, sort: ['createdAt', 'desc'], diff --git a/api/src/utils/generics/base-repository.ts b/api/src/utils/generics/base-repository.ts index e2bc6f68..fdb55993 100644 --- a/api/src/utils/generics/base-repository.ts +++ b/api/src/utils/generics/base-repository.ts @@ -22,6 +22,7 @@ import { SortOrder, UpdateQuery, UpdateWithAggregationPipeline, + UpdateWriteOpResult, } from 'mongoose'; import { TFilterQuery } from '@/utils/types/filter.types'; @@ -70,7 +71,7 @@ export abstract class BaseRepository< this.registerLifeCycleHooks(); } - getPopulate() { + getPopulate(): P[] { return this.populate; } @@ -79,7 +80,7 @@ export abstract class BaseRepository< return `hook:${entity}:${suffix}` as `hook:${IHookEntities}:${TNormalizedEvents}`; } - private registerLifeCycleHooks() { + private registerLifeCycleHooks(): void { const repository = this; const hooks = LifecycleHookManager.getHooks(this.cls.name); @@ -202,7 +203,7 @@ export abstract class BaseRepository< protected async execute>( query: Query, cls: new () => R, - ) { + ): Promise { const resultSet = await query.lean(this.leanOpts).exec(); return resultSet.map((doc) => plainToClass(cls, doc, this.transformOpts)); } @@ -211,7 +212,7 @@ export abstract class BaseRepository< query: Query, cls: new () => R, options?: ClassTransformOptions, - ) { + ): Promise { const doc = await query.lean(this.leanOpts).exec(); return plainToClass(cls, doc, options ?? this.transformOpts); } @@ -219,7 +220,7 @@ export abstract class BaseRepository< protected findOneQuery( criteria: string | TFilterQuery, projection?: ProjectionType, - ) { + ): Query { if (!criteria) { // An empty criteria would return the first document that it finds throw new Error('findOneQuery() should not have an empty criteria'); @@ -247,7 +248,7 @@ export abstract class BaseRepository< async findOneAndPopulate( criteria: string | TFilterQuery, projection?: ProjectionType, - ) { + ): Promise { this.ensureCanPopulate(); const query = this.findOneQuery(criteria, projection).populate( this.populate, @@ -259,8 +260,32 @@ export abstract class BaseRepository< filter: TFilterQuery, pageQuery?: PageQueryDto, projection?: ProjectionType, - ) { - const { skip = 0, limit, sort = ['createdAt', 'asc'] } = pageQuery || {}; + ): Query; + + /** + * @deprecated + */ + protected findQuery( + filter: TFilterQuery, + pageQuery?: QuerySortDto, + projection?: ProjectionType, + ): Query; + + protected findQuery( + filter: TFilterQuery, + pageQuery?: QuerySortDto | PageQueryDto, + projection?: ProjectionType, + ): Query { + if (Array.isArray(pageQuery)) { + const query = this.model.find(filter, projection); + return query.sort([pageQuery] as [string, SortOrder][]); + } + + const { + skip = 0, + limit = 0, + sort = ['createdAt', 'asc'], + } = pageQuery || {}; const query = this.model.find(filter, projection); return query .skip(skip) @@ -272,12 +297,32 @@ export abstract class BaseRepository< filter: TFilterQuery, pageQuery?: PageQueryDto, projection?: ProjectionType, - ) { + ): Promise; + + /** + * @deprecated + */ + async find( + filter: TFilterQuery, + pageQuery?: QuerySortDto, + projection?: ProjectionType, + ): Promise; + + async find( + filter: TFilterQuery, + pageQuery?: QuerySortDto | PageQueryDto, + projection?: ProjectionType, + ): Promise { + if (Array.isArray(pageQuery)) { + const query = this.findQuery(filter, pageQuery, projection); + return await this.execute(query, this.cls); + } + const query = this.findQuery(filter, pageQuery, projection); return await this.execute(query, this.cls); } - private ensureCanPopulate() { + private ensureCanPopulate(): void { if (!this.populate || !this.clsPopulate) { throw new Error('Cannot populate query'); } @@ -287,23 +332,47 @@ export abstract class BaseRepository< filters: TFilterQuery, pageQuery?: PageQueryDto, projection?: ProjectionType, - ) { + ): Promise; + + /** + * @deprecated + */ + async findAndPopulate( + filters: TFilterQuery, + pageQuery?: QuerySortDto, + projection?: ProjectionType, + ): Promise; + + async findAndPopulate( + filters: TFilterQuery, + pageQuery?: QuerySortDto | PageQueryDto, + projection?: ProjectionType, + ): Promise { this.ensureCanPopulate(); + if (Array.isArray(pageQuery)) { + const query = this.findQuery(filters, pageQuery, projection).populate( + this.populate, + ); + return await this.execute(query, this.clsPopulate); + } + const query = this.findQuery(filters, pageQuery, projection).populate( this.populate, ); return await this.execute(query, this.clsPopulate); } - protected findAllQuery(sort?: QuerySortDto) { - return this.findQuery({}, { limit: undefined, skip: undefined, sort }); + protected findAllQuery( + sort?: QuerySortDto, + ): Query { + return this.findQuery({}, { limit: 0, skip: 0, sort }); } - async findAll(sort?: QuerySortDto) { - return await this.find({}, { limit: undefined, skip: undefined, sort }); + async findAll(sort?: QuerySortDto): Promise { + return await this.find({}, { limit: 0, skip: 0, sort }); } - async findAllAndPopulate(sort?: QuerySortDto) { + async findAllAndPopulate(sort?: QuerySortDto): Promise { this.ensureCanPopulate(); const query = this.findAllQuery(sort).populate(this.populate); return await this.execute(query, this.clsPopulate); @@ -315,7 +384,7 @@ export abstract class BaseRepository< protected findPageQuery( filters: TFilterQuery, { skip, limit, sort }: PageQueryDto, - ) { + ): Query { return this.findQuery(filters) .skip(skip) .limit(limit) @@ -339,7 +408,7 @@ export abstract class BaseRepository< async findPageAndPopulate( filters: TFilterQuery, pageQuery: PageQueryDto, - ) { + ): Promise { this.ensureCanPopulate(); const query = this.findPageQuery(filters, pageQuery).populate( this.populate, @@ -365,7 +434,7 @@ export abstract class BaseRepository< ); } - async createMany(dtoArray: U[]) { + async createMany(dtoArray: U[]): Promise { const docs = await this.model.create(dtoArray); return docs.map((doc) => @@ -394,7 +463,7 @@ export abstract class BaseRepository< async updateMany>( filter: TFilterQuery, dto: UpdateQuery, - ) { + ): Promise { return await this.model.updateMany(filter, { $set: dto, }); @@ -410,19 +479,19 @@ export abstract class BaseRepository< return await this.model.deleteMany(criteria); } - async preValidate(_doc: HydratedDocument) { + async preValidate(_doc: HydratedDocument): Promise { // Nothing ... } - async postValidate(_validated: HydratedDocument) { + async postValidate(_validated: HydratedDocument): Promise { // Nothing ... } - async preCreate(_doc: HydratedDocument) { + async preCreate(_doc: HydratedDocument): Promise { // Nothing ... } - async postCreate(_created: HydratedDocument) { + async postCreate(_created: HydratedDocument): Promise { // Nothing ... } @@ -430,7 +499,7 @@ export abstract class BaseRepository< _query: Query, _criteria: TFilterQuery, _updates: UpdateWithAggregationPipeline | UpdateQuery, - ) { + ): Promise { // Nothing ... } @@ -438,35 +507,35 @@ export abstract class BaseRepository< _query: Query, _criteria: TFilterQuery, _updates: UpdateWithAggregationPipeline | UpdateQuery, - ) { + ): Promise { // Nothing ... } async postUpdateMany( _query: Query, _updated: any, - ) { + ): Promise { // Nothing ... } async postUpdate( _query: Query, _updated: T, - ) { + ): Promise { // Nothing ... } async preDelete( _query: Query, _criteria: TFilterQuery, - ) { + ): Promise { // Nothing ... } async postDelete( _query: Query, _result: DeleteResult, - ) { + ): Promise { // Nothing ... } } diff --git a/api/src/utils/generics/base-service.ts b/api/src/utils/generics/base-service.ts index fede7015..5faeaf4c 100644 --- a/api/src/utils/generics/base-service.ts +++ b/api/src/utils/generics/base-service.ts @@ -48,7 +48,25 @@ export abstract class BaseService< filter: TFilterQuery, pageQuery?: PageQueryDto, projection?: ProjectionType, + ): Promise; + + /** + * @deprecated + */ + async find( + filter: TFilterQuery, + pageQuery?: QuerySortDto, + projection?: ProjectionType, + ): Promise; + + async find( + filter: TFilterQuery, + pageQuery?: QuerySortDto | PageQueryDto, + projection?: ProjectionType, ): Promise { + if (Array.isArray(pageQuery)) + return await this.repository.find(filter, pageQuery, projection); + return await this.repository.find(filter, pageQuery, projection); } @@ -56,7 +74,29 @@ export abstract class BaseService< filters: TFilterQuery, pageQuery?: PageQueryDto, projection?: ProjectionType, - ) { + ): Promise; + + /** + * @deprecated + */ + async findAndPopulate( + filters: TFilterQuery, + pageQuery?: QuerySortDto, + projection?: ProjectionType, + ): Promise; + + async findAndPopulate( + filters: TFilterQuery, + pageQuery?: QuerySortDto | PageQueryDto, + projection?: ProjectionType, + ): Promise { + if (Array.isArray(pageQuery)) + return await this.repository.findAndPopulate( + filters, + pageQuery, + projection, + ); + return await this.repository.findAndPopulate( filters, pageQuery,