Files
Clintchiz 2c960fc1dc
Quality / quality (ubuntu-latest) (push) Failing after 9m49s
Quality / quality (windows-latest) (push) Canceled after 0s
refactor: migrate legacy wire namespace to wrn
2026-08-12 18:51:15 +05:30

64 lines
1.9 KiB
TypeScript

export interface ServerCallOptions {
endpoint?: string;
signal?: AbortSignal;
headers?: HeadersInit;
csrfToken?: string;
}
export class WrnServerCallError extends Error {
constructor(
message: string,
readonly code: string,
readonly status: number,
readonly details?: unknown,
) {
super(message);
}
}
function csrfFromCookie(): string | undefined {
if (typeof document === "undefined") return undefined;
const raw = /(?:^|;\s*)wrn-csrf=([^;]+)/.exec(document.cookie)?.[1];
return raw ? decodeURIComponent(raw) : undefined;
}
export async function callServerFunction<TInput extends unknown[], TOutput>(
component: string,
functionName: string,
args: TInput,
options: ServerCallOptions = {},
): Promise<TOutput> {
const csrfToken = options.csrfToken ?? csrfFromCookie();
const response = await fetch(options.endpoint ?? "/__wrnexus/rpc", {
method: "POST",
credentials: "same-origin",
signal: options.signal,
headers: {
"content-type": "application/json",
...(csrfToken ? { "x-csrf-token": csrfToken } : {}),
...options.headers,
},
body: JSON.stringify({ component, function: functionName, args }),
});
const payload = (await response.json().catch(() => null)) as any;
if (!response.ok || !payload?.ok)
throw new WrnServerCallError(
payload?.error?.message ?? `Server call failed (${response.status})`,
payload?.error?.code ?? "WRN-RPC-FAILED",
response.status,
payload?.error?.details,
);
return payload.value as TOutput;
}
export function createServerProxy<T extends Record<string, (...args: any[]) => Promise<any>>>(
component: string,
options: ServerCallOptions = {},
): T {
return new Proxy({} as T, {
get:
(_target, property) =>
(...args: unknown[]) =>
callServerFunction(component, String(property), args, options),
});
}