Skip to content

Instantly share code, notes, and snippets.

@chihabhajji
Last active March 30, 2023 11:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chihabhajji/80b5bac0f071b915bdf7dac11df3acee to your computer and use it in GitHub Desktop.
Save chihabhajji/80b5bac0f071b915bdf7dac11df3acee to your computer and use it in GitHub Desktop.
Generic'ish nestjs mongoose repository
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import {
Document,
FilterQuery,
HydratedDocument,
LeanDocument,
Model,
model,
ProjectionType,
QueryOptions,
Require_id,
UpdateQuery,
} from 'mongoose';
import {
Circle,
CircleDocument,
CircleSchema,
} from '../schemas/circle/circle.schema';
export interface IRepository<T extends Document> {
create(data: T): Promise<T>;
find(
filter: FilterQuery<T>,
projection?: ProjectionType<T>,
options?: QueryOptions<T>,
): Promise<T[]>;
findOne(
filter: FilterQuery<T>,
projection?: ProjectionType<T>,
options?: QueryOptions<T>,
): Promise<T>;
findById(id: string): Promise<T>;
updateById(
id: string,
data: UpdateQuery<T>,
): Promise<NonNullable<HydratedDocument<T>>>;
deleteById(id: string): Promise<T>;
findLean(
filter: FilterQuery<T>,
projection?: ProjectionType<T>,
options?: QueryOptions<T>,
): Promise<
NonNullable<
T extends Document
? LeanDocument<HydratedDocument<T>>[]
: LeanDocument<Require_id<T>>[]
>
>;
}
export class MongoRepository<T extends Document> implements IRepository<T> {
readonly model: Model<T>;
constructor(model: Model<T>) {
this.model = model;
}
async create(data: T): Promise<T> {
return await this.model.create(data);
}
deleteById(id: string): Promise<T> {
return this.model.findByIdAndDelete(id).orFail().exec();
}
find(
filter: FilterQuery<T>,
projection?: ProjectionType<T>,
options?: QueryOptions<T>,
): Promise<T[]> {
return this.model.find(filter, projection, options).orFail().exec();
}
findLean(
filter: FilterQuery<T>,
projection?: ProjectionType<T>,
options?: QueryOptions<T>,
): Promise<
NonNullable<
T extends Document
? LeanDocument<HydratedDocument<T>>[]
: LeanDocument<Require_id<T>>[]
>
> {
return this.model.find(filter, projection, options).lean().orFail().exec();
}
findById(id: string): Promise<T> {
return this.model.findById(id).orFail().exec();
}
findOne(
filter: FilterQuery<T>,
projection?: ProjectionType<T>,
options?: QueryOptions<T>,
): Promise<T> {
return this.model.findOne(filter, projection, options).orFail().exec();
}
updateById(
id: string,
data: UpdateQuery<T>,
): Promise<NonNullable<HydratedDocument<T>>> {
return this.model
.findByIdAndUpdate(id, data, { new: true })
.orFail()
.exec();
}
}
const A = model<CircleDocument>('Circle', CircleSchema);
@Injectable()
export class CircleService extends MongoRepository<CircleDocument> {
constructor(@InjectModel(Circle.name) private entity: Model<CircleDocument>) {
super(entity);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment