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-12-04 07:06:25 +00:00
|
|
|
import { ProjectionType } from 'mongoose';
|
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,
|
2024-12-04 07:06:25 +00:00
|
|
|
projection?: ProjectionType<T>,
|
2024-09-10 09:50:11 +00:00
|
|
|
): Promise<T> {
|
2024-12-04 07:06:25 +00:00
|
|
|
return await this.repository.findOne(criteria, options, projection);
|
2024-09-10 09:50:11 +00:00
|
|
|
}
|
|
|
|
|
2024-12-04 07:06:25 +00:00
|
|
|
async findOneAndPopulate(
|
|
|
|
criteria: string | TFilterQuery<T>,
|
|
|
|
projection?: ProjectionType<T>,
|
|
|
|
) {
|
|
|
|
return await this.repository.findOneAndPopulate(criteria, projection);
|
2024-09-21 11:15:36 +00:00
|
|
|
}
|
|
|
|
|
2024-12-03 16:16:57 +00:00
|
|
|
async find(
|
|
|
|
filter: TFilterQuery<T>,
|
|
|
|
pageQuery?: PageQueryDto<T>,
|
2024-12-04 07:06:25 +00:00
|
|
|
projection?: ProjectionType<T>,
|
2024-12-03 16:16:57 +00:00
|
|
|
): Promise<T[]> {
|
2024-12-04 07:06:25 +00:00
|
|
|
return await this.repository.find(filter, pageQuery, projection);
|
2024-09-10 09:50:11 +00:00
|
|
|
}
|
|
|
|
|
2024-12-04 07:06:25 +00:00
|
|
|
async findAndPopulate(
|
|
|
|
filters: TFilterQuery<T>,
|
|
|
|
pageQuery?: PageQueryDto<T>,
|
|
|
|
projection?: ProjectionType<T>,
|
|
|
|
) {
|
|
|
|
return await this.repository.findAndPopulate(
|
|
|
|
filters,
|
|
|
|
pageQuery,
|
|
|
|
projection,
|
|
|
|
);
|
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 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);
|
|
|
|
}
|
|
|
|
}
|