/* * Copyright © 2024 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 { ConflictException } from '@nestjs/common'; import { ClassTransformOptions } from 'class-transformer'; import { MongoError } from 'mongodb'; import { TFilterQuery } from '@/utils/types/filter.types'; import { PageQueryDto, QuerySortDto } from '../pagination/pagination-query.dto'; import { BaseRepository } from './base-repository'; import { BaseSchema } from './base-schema'; export abstract class BaseService< T extends BaseSchema, P extends string = never, TFull extends Omit = never, > { constructor(protected readonly repository: BaseRepository) {} getRepository() { return this.repository; } async findOne( criteria: string | TFilterQuery, options?: ClassTransformOptions, ): Promise { return await this.repository.findOne(criteria, options); } async findOneAndPopulate(criteria: string | TFilterQuery) { return await this.repository.findOneAndPopulate(criteria); } async find( filter: TFilterQuery, pageQuery?: PageQueryDto, ): Promise { return await this.repository.find(filter, pageQuery); } async findAndPopulate(filters: TFilterQuery, pageQuery?: PageQueryDto) { return await this.repository.findAndPopulate(filters, pageQuery); } async findAll(sort?: QuerySortDto): Promise { return await this.repository.findAll(sort); } async findAllAndPopulate(sort?: QuerySortDto): Promise { return await this.repository.findAllAndPopulate(sort); } async findPage( filters: TFilterQuery, pageQueryDto: PageQueryDto, ): Promise { return await this.repository.findPage(filters, pageQueryDto); } async findPageAndPopulate( filters: TFilterQuery, pageQueryDto: PageQueryDto, ): Promise { return await this.repository.findPageAndPopulate(filters, pageQueryDto); } async countAll(): Promise { return await this.repository.countAll(); } async count(criteria?: TFilterQuery): Promise { return await this.repository.count(criteria); } async create>(dto: D): Promise { try { return await this.repository.create(dto); } catch (error) { if (error instanceof MongoError && error.code === 11000) { throw new ConflictException( 'Duplicate key error: element already exists', ); } throw error; } } async findOneOrCreate>( criteria: string | TFilterQuery, dto: D, ): Promise { const result = await this.findOne(criteria); if (!result) { return await this.create(dto); } return result; } async createMany>( dtoArray: D[], ): Promise { return await this.repository.createMany(dtoArray); } async updateOne>>( criteria: string | TFilterQuery, dto: D, ): Promise { return await this.repository.updateOne(criteria, dto); } async updateMany>>( filter: TFilterQuery, dto: D, ) { return await this.repository.updateMany(filter, dto); } async deleteOne(criteria: string | TFilterQuery) { return await this.repository.deleteOne(criteria); } async deleteMany(filter: TFilterQuery) { return await this.repository.deleteMany(filter); } }