import { Client as ElasticClient } from '@elastic/elasticsearch' ; import { ResponseError } from '@elastic/elasticsearch/lib/errors' ; import bodybuilder , { Bodybuilder } from 'bodybuilder' ; import httpStatus from 'http-status' ; import { AggregateRoot } from '../../../domain/AggregateRoot' ; import { Criteria } from '../../../domain/criteria/Criteria' ; import ElasticConfig from './ElasticConfig' ; import { ElasticCriteriaConverter , TypeQueryEnum } from './ElasticCriteriaConverter' ; type Hit = { _source : any ; } ; export abstract class ElasticRepository < T extends AggregateRoot > { private criteriaConverter : ElasticCriteriaConverter ; constructor ( private _client , private config ) { this . criteriaConverter = new ElasticCriteriaConverter ( ) ; } protected indexName ( ) { return this . config . indexName ; } protected client ( ) { return this . _client ; } protected async searchAllInElastic ( unserializer ) { const body = bodybuilder ( ) . query ( TypeQueryEnum . MATCH_ALL ) ; return this . searchInElasticWithBuilder ( unserializer , body ) ; } protected async searchByCriteria ( criteria , unserializer ) { const body = this . criteriaConverter . convert ( criteria ) ; return this . searchInElasticWithBuilder ( unserializer , body ) ; } private async searchInElasticWithBuilder ( unserializer , body ) { const client = await this . client ( ) ; try { const response = await client . search ( { index : this . indexName ( ) , body : body . build ( ) } ) ; return response . body . hits . hits . map ( ( hit ) => unserializer ( { ... hit . _source } ) ) ; } catch ( e ) { if ( this . isNotFoundError ( e ) ) { return [ ] ; } throw e ; } } private isNotFoundError ( e ) { return e instanceof ResponseError && ( e as ResponseError ) . meta . statusCode === httpStatus . NOT_FOUND ; } protected async persist ( id , aggregateRoot ) { const client = await this . client ( ) ; const document = { ... aggregateRoot . toPrimitives ( ) } ; await client . index ( { index : this . indexName ( ) , id , body : document , refresh : 'wait_for' } ) ; } }