import type { FetchContext } from '../types' export interface EapiRequestConfig { url: string method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' params?: Record body?: unknown data?: unknown headers?: Record } export interface EapiClient { request: (config: EapiRequestConfig) => Promise } export interface EapiAdapterOptions { /** Called before each request to inject dynamic headers (e.g. auth tokens) */ getHeaders?: () => Record /** Called after each response with the response headers */ onResponse?: (headers: Record) => void } export function createEapiAdapter( client: EapiClient, options?: EapiAdapterOptions, ) { async function fetchConfig(config: EapiRequestConfig): Promise { const headers = { ...config.headers, ...(options?.getHeaders?.() ?? {}), } const requestConfig: EapiRequestConfig = { ...config, // Map 'body' to 'data' for axios compatibility data: config.body ?? config.data, headers, } const response = await client.request(requestConfig) // Call onResponse callback with response headers if provided if (options?.onResponse && (response as Record)?.headers) { options.onResponse( (response as Record).headers as Record, ) } // Extract data from axios response wrapper return (response as Record)?.data ?? response } return { /** Directly call the EAPI client with a static config */ fetch: fetchConfig, /** * Returns a SourceDescriptor-compatible fetch function that merges the * base config with dynamic params passed via engine.trigger(key, { params }). */ createFetch: (baseConfig: EapiRequestConfig) => (ctx: FetchContext): Promise => { const merged: EapiRequestConfig = { ...baseConfig, params: { ...baseConfig.params, ...ctx.options.params }, } return fetchConfig(merged) }, } }