release: WRNexusJS 0.6.0
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
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*)wrnexus_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-wrnexus-csrf": 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),
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user