import { ApiClientConfiguration , ApiVersion } from './client.model' ; import { errorHandler , fetchTransport , Transport , TransportResponse , } from '../transport' ; import { HEADERS } from '../constants' ; export abstract class ApiClient < Response , Params = undefined > { protected abstract url : string ; protected abstract method : 'get' | 'post' ; private static DEFAULT_CONFIG = { host : 'https://api.what3words.com' , apiVersion : ApiVersion . Version3 , } ; private _config : ApiClientConfiguration ; private transport : Transport ; constructor ( private _apiKey = '' , config = { } , transport = fetchTransport ( ) ) { this . _config = Object . assign ( { } , ApiClient . DEFAULT_CONFIG , config ) ; this . transport = transport ; } public apiKey ( apiKey ? ) { if ( apiKey !== undefined ) { this . _apiKey = apiKey ; return this ; } return this . _apiKey ; } public config ( config ? ) { if ( config !== undefined ) { this . _config = Object . assign ( { } , this . _config , config ) ; return this ; } return this . _config ; } public async run ( options ? ) { const validation = await this . validate ( options ) ; if ( ! validation . valid ) { throw new Error ( validation . message || 'There was a problem validating your request options' ) ; } const params = { headers : { ... this . headers ( ) , ... ( this . _config . headers || { } ) } , body : this . body ( options ) , query : this . query ( options ) , } ; const response = await this . makeClientRequest < Response > ( this . method , this . url , params ) ; if ( ! response . body ) throw new Error ( 'No response body set' ) ; return response . body ; } protected async makeClientRequest < T > ( method , url , params ? ) { const clientRequest = this . getClientRequest ( method , url , params ) ; const response = await this . transport < T > ( clientRequest ) ; const result = await errorHandler ( response ) ; return result ; } protected getClientRequest ( method , url , params ? ) { return { method , host : `${ this . _config . host ?. replace ( /\/$/ , '' ) }/${ this . _config . apiVersion }` , url , query : { ... ( params ?. query || { } ) , key : this . _apiKey , } , headers : { ... ( params ?. headers || { } ) , 'X-Api-Key' : this . _apiKey , ... HEADERS , } , body : params ?. body || null , } ; } protected async validate ( options ? ) { return { valid : true , message : undefined } ; } protected headers ( options ? ) { return { } ; } protected body ( options ? ) { return null ; } protected query ( options ? ) { return { } ; } }