import { ipcMain } from 'electron' import { ApiHandler, DefaultRouteShape, EmptyApiHandler, Mutator, } from '@seleniumhq/side-api' import noop from 'lodash/fp/noop' import { Session, SessionControllerKeys } from '../../types' export type AsyncHandler = ( ...args: Parameters ) => Promise> export type HandlerFactory = ( path: string, session: Session ) => AsyncHandler const defaultHandler = ( path: string, session: Session ): AsyncHandler => { const [namespace, method] = path.split('.') const controller = session[namespace as SessionControllerKeys] if (controller && method in controller) { // @ts-expect-error return controller[method].bind(controller) as AsyncHandler } console.warn(`Missing method for path ${path}, using passthrough`) return noop as unknown as AsyncHandler } const passThroughHandler = ( _path: string, _session: Session ): AsyncHandler => { const handler = async (..._args: Parameters) => {} return handler as unknown as AsyncHandler } export const passthrough = passThroughHandler const Handler = ( factory: HandlerFactory = defaultHandler ) => (path: string, session: Session, mutator?: Mutator) => { const handler = factory(path, session) const doAPI = async (...params: Parameters) => { const result = await handler(...params) await session.state.mutate(mutator, params, result, path) return result } ipcMain.handle(path, async (_event, ...args) => { session.system.loggers.api('Received API Request', path, args) const result = await doAPI(...(args as Parameters)) session.system.loggers.api('Resolved API Request', path, result) return result }) return doAPI } export default Handler