hexabot/api/src/utils/generics/base-service.ts

135 lines
3.9 KiB
TypeScript
Raw Normal View History

2024-09-10 09:50:11 +00:00
/*
* 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';
2024-10-29 13:36:46 +00:00
import { TFilterQuery } from '@/utils/types/filter.types';
2024-09-10 09:50:11 +00:00
2024-10-16 17:54:55 +00:00
import { PageQueryDto, QuerySortDto } from '../pagination/pagination-query.dto';
2024-09-10 09:50:11 +00:00
import { BaseRepository } from './base-repository';
import { BaseSchema } from './base-schema';
2024-09-21 11:15:36 +00:00
export abstract class BaseService<
T extends BaseSchema,
P extends string = never,
TFull extends Omit<T, P> = never,
> {
constructor(protected readonly repository: BaseRepository<T, P, TFull>) {}
getRepository() {
return this.repository;
}
2024-09-10 09:50:11 +00:00
async findOne(
criteria: string | TFilterQuery<T>,
options?: ClassTransformOptions,
): Promise<T> {
return await this.repository.findOne(criteria, options);
}
2024-10-12 11:44:32 +00:00
async findOneAndPopulate(criteria: string | TFilterQuery<T>) {
return await this.repository.findOneAndPopulate(criteria);
2024-09-21 11:15:36 +00:00
}
async find(
filter: TFilterQuery<T>,
pageQuery?: PageQueryDto<T>,
): Promise<T[]> {
return await this.repository.find(filter, pageQuery);
2024-09-10 09:50:11 +00:00
}
async findAndPopulate(filters: TFilterQuery<T>, pageQuery?: PageQueryDto<T>) {
return await this.repository.findAndPopulate(filters, pageQuery);
2024-09-21 11:15:36 +00:00
}
2024-09-10 09:50:11 +00:00
async findAll(sort?: QuerySortDto<T>): Promise<T[]> {
return await this.repository.findAll(sort);
}
2024-09-21 11:15:36 +00:00
async findAllAndPopulate(sort?: QuerySortDto<T>): Promise<TFull[]> {
return await this.repository.findAllAndPopulate(sort);
}
2024-09-10 09:50:11 +00:00
async findPage(
filters: TFilterQuery<T>,
pageQueryDto: PageQueryDto<T>,
): Promise<T[]> {
return await this.repository.findPage(filters, pageQueryDto);
}
2024-09-21 11:15:36 +00:00
async findPageAndPopulate(
filters: TFilterQuery<T>,
pageQueryDto: PageQueryDto<T>,
): Promise<TFull[]> {
return await this.repository.findPageAndPopulate(filters, pageQueryDto);
}
2024-09-10 09:50:11 +00:00
async countAll(): Promise<number> {
return await this.repository.countAll();
}
async count(criteria?: TFilterQuery<T>): Promise<number> {
return await this.repository.count(criteria);
}
async create<D extends Omit<T, keyof BaseSchema>>(dto: D): Promise<T> {
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<D extends Omit<T, keyof BaseSchema>>(
criteria: string | TFilterQuery<T>,
dto: D,
): Promise<T> {
const result = await this.findOne(criteria);
if (!result) {
return await this.create(dto);
}
return result;
}
async createMany<D extends Omit<T, keyof BaseSchema>>(
dtoArray: D[],
): Promise<T[]> {
return await this.repository.createMany(dtoArray);
}
async updateOne<D extends Partial<Omit<T, keyof BaseSchema>>>(
criteria: string | TFilterQuery<T>,
dto: D,
): Promise<T> {
return await this.repository.updateOne(criteria, dto);
}
async updateMany<D extends Partial<Omit<T, keyof BaseSchema>>>(
filter: TFilterQuery<T>,
dto: D,
) {
return await this.repository.updateMany(filter, dto);
}
async deleteOne(criteria: string | TFilterQuery<T>) {
return await this.repository.deleteOne(criteria);
}
async deleteMany(filter: TFilterQuery<T>) {
return await this.repository.deleteMany(filter);
}
}