import { ClassConstructor , plainToClass } from 'class-transformer' ; import { Document , FilterQuery , Model } from 'mongoose' ; export class BaseRepository < T > { public _model : Model < any & Document > ; constructor ( protected MongooseModel , protected entity ) { this . _model = MongooseModel ; } async count ( query ) { return await this . MongooseModel . countDocuments ( query ) ; } async aggregate ( query ) { return await this . MongooseModel . aggregate ( query ) ; } async findById ( id , select ? ) { const data = await this . MongooseModel . findById ( id , select ) ; if ( ! data ) return null ; return this . mapEntity ( data . toObject ( ) ) ; } async findOne ( query , select ? ) { const data = await this . MongooseModel . findOne ( query , select ) ; if ( ! data ) return null ; return this . mapEntity ( data . toObject ( ) ) ; } async delete ( query ) { const data = await this . MongooseModel . remove ( query ) ; return data ; } async find ( query , select = '' , options = { } ) { const data = await this . MongooseModel . find ( query , select , { sort : options . sort || null , } ) . skip ( options . skip ) . limit ( options . limit ) . lean ( ) . exec ( ) ; return this . mapEntities ( data ) ; } async create ( data ) { const newEntity = new this . MongooseModel ( data ) ; const saved = await newEntity . save ( ) ; return this . mapEntity ( saved ) ; } async createMany ( data ) { await new Promise ( ( resolve ) => { this . MongooseModel . collection . insertMany ( data , ( err , response ) => { resolve ( response ) ; } ) ; } ) ; } async update ( query , updateBody ) { const saved = await this . MongooseModel . updateMany ( query , updateBody , { multi : true , } ) ; return { matched : saved . n , modified : saved . nModified , } ; } protected mapEntity ( data ) { return plainToClass < T , T > ( this . entity , JSON . parse ( JSON . stringify ( data ) ) ) as any ; } protected mapEntities ( data ) { return plainToClass < T , T [ ] > ( this . entity , JSON . parse ( JSON . stringify ( data ) ) ) ; } }