import { injectable } from 'inversify' ; import { MongoClient } from 'mongodb' ; import * as asyncRetry from 'async-retry' ; import { IdeaModels } from '@centsideas/models' ; import { UserId , IdeaId } from '@centsideas/types' ; import * as Errors from './idea-read.errors' ; import { IdeaReadConfig } from './idea-read.config' ; @ injectable ( ) export class IdeaRepository { client = new MongoClient ( this . config . get ( 'idea-read.database.url' ) , { useNewUrlParser : true , useUnifiedTopology : true , } ) ; private readonly collectionName = this . config . get ( 'idea-read.database.collection' ) ; private readonly databaseName = this . config . get ( 'idea-read.database.name' ) ; constructor ( private config ) { } async getById ( id , user ? ) { const collection = await this . collection ( ) ; const idea = await collection . findOne ( { id : id . toString ( ) } ) ; if ( ! idea ) throw new Errors . IdeaNotFound ( id ) ; if ( ! idea . publishedAt && user ?. equals ( UserId . fromString ( idea . userId ) ) ) throw new Errors . IdeaNotFound ( id ) ; if ( idea . deletedAt && user ?. equals ( UserId . fromString ( idea . userId ) ) ) throw new Errors . IdeaNotFound ( id ) ; return idea ; } async getAll ( ) { const collection = await this . collection ( ) ; const result = await collection . find ( { publishedAt : { $ne : undefined } , deletedAt : undefined , } ) ; return result . toArray ( ) ; } async getAllByUserId ( user , privates ) { const collection = await this . collection ( ) ; const result = privates ? await collection . find ( { userId : user . toString ( ) } ) : await collection . find ( { userId : user . toString ( ) , publishedAt : { $ne : undefined } , deletedAt : undefined , } ) ; return result . toArray ( ) ; } async getUnpublished ( user ) { const collection = await this . collection ( ) ; const found = await collection . findOne ( { userId : user . toString ( ) , publishedAt : undefined , deletedAt : undefined , } ) ; if ( ! found ) throw new Errors . IdeaNotFound ( ) ; return found ; } private async collection ( ) { const db = await this . db ( ) ; return db . collection < IdeaModels . IdeaModel > ( this . collectionName ) ; } private async db ( ) { if ( ! this . client . isConnected ( ) ) await asyncRetry ( ( ) => this . client ?. connect ( ) ) ; return this . client . db ( this . databaseName ) ; } }