import { ProviderNotRegisteredException } from '../exception' ; import { LoggableMixin } from '../logger' ; import { AbstractChainProvider , AbstractHttpProvider , ProvidableMixin } from '../model' ; import type { DistanceQueryInterface , GeocodeQueryInterface , GeocoderInterface , ReverseQueryInterface , SuggestQueryInterface } from '../interface' ; import type { AbstractProvider , Distance , Location , Suggestion } from '../model' ; import type { Type } from '../types' ; export abstract class AbstractGeocoder extends ProvidableMixin ( LoggableMixin ( Object ) ) implements GeocoderInterface { abstract geocode ( query ) ; abstract reverse ( query ) ; abstract suggest ( query ) ; protected async geocodeByProvider ( provider , query ) { return provider . geocode ( query ) ; } protected async reverseByProvider ( provider , query ) { return provider . reverse ( query ) ; } protected async suggestByProvider ( provider , query ) { return provider . suggest ( query ) ; } protected async distanceByProvider ( provider , query ) { return provider . distance ( query ) ; } using < HttpProviderClass extends AbstractHttpProvider > ( providerClass ) { let providerClassName ; if ( typeof providerClass === 'function' ) { if ( ! ( providerClass . prototype instanceof AbstractHttpProvider ) ) { throw ProviderNotRegisteredException . doesNotInheritAbstractProvider ( providerClass . name ) ; } providerClassName = providerClass . name ; } else { providerClassName = providerClass ; } for ( const provider of this . getProviders ( ) ) { const foundProvider = this . findHttpProviderRecursive ( providerClassName , provider ) ; if ( foundProvider ) { return foundProvider ; } } throw ProviderNotRegisteredException . create ( providerClassName , this . getProviders ( ) ) ; } private findHttpProviderRecursive ( providerClassName , provider ) { if ( provider instanceof AbstractHttpProvider && providerClassName === provider . constructor . name ) { return provider ; } if ( provider instanceof AbstractChainProvider ) { for ( const internalProvider of provider . getProviders ( ) ) { const foundProvider = this . findHttpProviderRecursive ( providerClassName , internalProvider ) ; if ( foundProvider ) { return foundProvider ; } } return ; } } }