import { api } from '../api'; type FunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]; type Prom = { [K in FunctionPropertyNames]: ReturnType extends Promise ? T[K] : (...params: Parameters) => Promise>; }; type PromOrError = { [K in FunctionPropertyNames]: ReturnType extends Promise ? (...params: Parameters) => ReturnType | Promise : (...params: Parameters) => Promise | Error>; }; function handler(namespace: string, waitService: boolean): ProxyHandler { return { get: (_target: T, prop: string): any => (...params: any): Promise => api[waitService ? 'waitAndCall' : 'call'](`${namespace}.${prop}`, params), }; } // TODO remove the need to wait for a service, if that is really needed it should have a dependency on startup export function proxifyWithWait(namespace: string): Prom { return new Proxy({}, handler(namespace, true)) as unknown as Prom; } export function proxify(namespace: string): PromOrError { return new Proxy({}, handler(namespace, false)) as unknown as Prom; }