feat: close application architecture gaps
Quality / quality (ubuntu-latest) (push) Failing after 9m56s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-23 11:45:57 +05:30
parent d87b197224
commit 2e12656060
20 changed files with 548 additions and 23 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/csr",
"version": "0.8.29",
"version": "0.8.31",
"type": "module",
"main": "src/index.ts",
"exports": {
+24
View File
@@ -1173,6 +1173,7 @@ export const REACTIVE_RUNTIME = String.raw`
* lacks one of these does not break the rest.
*/
if (name === "toast") return toastApi;
if (name === "useFetch") return useFetch;
if (boundWindowGlobals[name] && typeof window[name] === "function") {
return window[name].bind(window);
}
@@ -4350,6 +4351,29 @@ export const REACTIVE_RUNTIME = String.raw`
});
}
/**
* Public client transport for dynamic API paths.
*
* The apis block remains the typed, declarative choice for fixed routes. This
* helper covers paths assembled at runtime without exposing a private
* framework global to application code.
*/
function useFetch(path, methodOrOptions, input) {
var method = "GET";
var values = input;
if (typeof methodOrOptions === "string") {
method = methodOrOptions;
} else if (methodOrOptions && typeof methodOrOptions === "object") {
method = methodOrOptions.method || "GET";
values = method === "GET" || method === "HEAD"
? (methodOrOptions.query || methodOrOptions.params)
: (methodOrOptions.body === undefined ? methodOrOptions.data : methodOrOptions.body);
}
return wrnexusCallApi(path, method, values);
}
window.useFetch = useFetch;
// Compatibility for applications compiled before the public helper landed.
window.__wrnexusCallApi = wrnexusCallApi;
function dispatchComponentEvent(root, name, detail) {
+15
View File
@@ -64,6 +64,21 @@ test("POST sends a JSON body", async () => {
);
});
test("useFetch is the public dynamic-path transport", async () => {
const { calls, win } = harness({ status: 200, payload: { ok: true } });
const useFetch = (
win as unknown as {
useFetch: (path: string, options: { method: string; body: unknown }) => Promise<unknown>;
}
).useFetch;
await expect(
useFetch("/api/users/42/test", { method: "POST", body: { dryRun: true } }),
).resolves.toEqual({ ok: true });
expect(calls[0]!.url).toBe("/api/users/42/test");
expect(calls[0]!.init.body).toBe(JSON.stringify({ dryRun: true }));
});
test("a non-GET request carries the CSRF token from the cookie", async () => {
const { callApi, calls, win } = harness({ status: 200, payload: {} });
win.document.cookie = "wrn-csrf=token-123";