feat(web): route web build through same-origin /api proxy

client.current and createScopedClient resolve transport via dispatchFor:
web -> absolute origin + /api base with an X-Honcho-Upstream header; Tauri ->
absolute instance URL + reqwest. Absolute base (not bare "/api") so openapi-fetch
can construct a Request under node/undici and in the browser alike. Fleet fan-out
is unchanged; fleet.test.tsx now asserts the proxy contract.
This commit is contained in:
Offending Commit
2026-06-02 11:47:24 -05:00
parent 9945e4cf14
commit 0935099bc2
5 changed files with 30 additions and 28 deletions

View File

@@ -18,6 +18,17 @@ function normalizeUpstream(url: string): string {
return url.trim().replace(/\/+$/, "");
}
/**
* Absolute same-origin base for the web proxy. Absolute (origin + `/api`), not the
* bare relative `/api`, so openapi-fetch and node/undici can construct a Request
* without an ambient document base — and so it resolves identically in the browser,
* behind a tunnel, and under jsdom.
*/
function webApiBase(): string {
const origin = typeof location !== "undefined" ? location.origin : "";
return `${origin}${API_PREFIX}`;
}
/**
* Resolve how to issue a request for an instance.
* - Web: same-origin `/api` + `X-Honcho-Upstream` header (proxy forwards server-side, no CORS).
@@ -32,5 +43,5 @@ export function dispatchFor(instance: { baseUrl: string; token?: string }): Disp
}
headers[UPSTREAM_HEADER] = normalizeUpstream(instance.baseUrl);
return { baseUrl: API_PREFIX, headers, fetch: httpFetch };
return { baseUrl: webApiBase(), headers, fetch: httpFetch };
}