import { ConvectorController , getInvokables } from '@worldsibu/convector-core-controller' ; import { ControllerAdapter } from './controller-adapter' ; export interface IConvectorControllerClient < T extends ConvectorController > { config : any ; query : boolean ; user : string | true ; ctrl : new ( content ? ) => T ; adapter : ControllerAdapter ; raw : boolean ; } export const controllerClientMethods = { $withUser < T extends ConvectorController > ( this , user ) { const newClient = ClientFactory ( this . ctrl , this . adapter , this ) ; newClient . user = user ; return newClient ; } , $query < T extends ConvectorController > ( this ) { const newClient = ClientFactory ( this . ctrl , this . adapter , this ) ; newClient . query = true ; return newClient ; } , $config < T extends ConvectorController > ( this , config ) { const newClient = ClientFactory ( this . ctrl , this . adapter , this ) ; newClient . config = config ; return newClient ; } , $raw < T extends ConvectorController > ( this ) { const newClient = ClientFactory ( this . ctrl , this . adapter , this ) ; newClient . raw = true ; return newClient ; } } ; export type ConvectorControllerClient < T extends ConvectorController > = typeof controllerClientMethods & IConvectorControllerClient < T > & T ; export function ClientFactory < T extends ConvectorController > ( ctrl , adapter , extrasProperties ? ) { const client = new ctrl ( ) as any ; Object . assign ( client , { ctrl , adapter , query : false , raw : false } , controllerClientMethods , extrasProperties || { } ) ; const { namespace , invokables } = getInvokables ( ctrl ) ; for ( let fn in invokables ) { client [ fn ] = async function ControllerClientWrapper ( this , ... args ) { const config = { ... this . config , user : this . user } ; let res ; if ( this . query && adapter . query ) { res = await adapter . query ( namespace , fn , config , ... args ) ; } else { res = await adapter . invoke ( namespace , fn , config , ... args ) ; } return typeof res === 'object' && 'result' in res && ! this . raw ? res . result : res ; } ; } return client ; }