import { w } from "../../../utils/types/general"; import { fetchViaProxy } from "../proxy"; import { loadApiProxyDef } from "./api-proxy-def"; export type ApiProxy = {}> = any; const apiProxyLoaded: Record> = {}; export const apiProxy = (api_url: string) => { if (!w.prasiApi) { w.prasiApi = {}; } try { const base = new URL(api_url); let base_url = `${base.protocol}//${base.host}`; if (!w.prasiApi[base_url]) { if (!apiProxyLoaded[base_url]) { apiProxyLoaded[base_url] = loadApiProxyDef(base_url, true); } } return new Proxy( {}, { get: (_, actionName: string) => { const createFn = (actionName: string) => { return function ( this: { api_url: string } | undefined, ...rest: any ) { return new Promise(async (resolve, reject) => { try { let api_ref = w.prasiApi[base_url]; if ( !api_ref && apiProxyLoaded && typeof apiProxyLoaded[base_url] === "object" ) { await apiProxyLoaded[base_url]; api_ref = w.prasiApi[base_url]; } if (api_ref) { if (!api_ref.apiEntry) api_ref.apiEntry = {}; if (api_ref.apiEntry && !api_ref.apiEntry[actionName]) { reject( `API ${actionName.toString()} not found, existing API: \n - ${Object.keys( api_ref || {} ).join("\n - ")}` ); return; } let actionUrl = api_ref.apiEntry[actionName].url; const actionParams = api_ref.apiEntry[actionName].args; if (actionUrl && actionParams) { if (rest.length > 0 && actionParams.length > 0) { for (const [idx, p] of Object.entries(rest)) { const paramName = actionParams[parseInt(idx)]; if ( actionParams && actionParams.includes(paramName) ) { if ( !!p && typeof p !== "string" && typeof p !== "number" ) { continue; } } actionUrl = actionUrl.replace( `:${paramName}?`, p + "" ); actionUrl = actionUrl.replace( `:${paramName}`, p + "" ); } } const url = `${base_url}${actionUrl}`; const result = await fetchSendApi(url, rest); resolve(result); } else { console.error(`API Not Found: ${actionName.toString()}`); } } else { reject("Failed to load API: " + base_url); } } catch (e) { reject(e); } }); }; }; if (actionName === "then") { return new Proxy( {}, { get: (_, actionName: string) => { return createFn(actionName); }, } ); } return createFn(actionName); }, } ); } catch (e) { console.warn("Init API failed for URL: ", JSON.stringify(api_url)); return null; } }; const fetchSendApi = async (url: string, params: any) => { return await fetchViaProxy(url, params, { "content-type": "application/json", }); };