Phase 69o — Client Remoting proxy convention adoption (migration)
Phase 69o — Client Remoting proxy convention adoption (migration)
What changes
This is a consumer-side adoption sweep, not a substrate change. The transport-level per-call header read was already implemented earlier (the send-time CsrfClient request-guard installed at the XHR + fetch seam) and codified as a convention in docs/platform/client-remoting-proxies.md. What remained was the consumer-side cleanup: convert the older defensive let private api () = ... per-call shape to module-level values.
See docs/platform/client-remoting-proxies.md for the canonical convention statement. This phase doesn't change the convention; it sweeps the remaining sites that hadn't adopted yet.
Diff to apply (per consumer)
For each *.Client module that still declares let private api () = …:
- // Built per call (not module-level): `Api.makeProxy` captures
- // `withRequestHeaders` once and the transport historically froze the
- // header list, so a module-level value would snapshot an empty
- // `X-CSRF-Token` before the SDK's async CSRF prefetch resolved — 403
- // on every mutating call under `DefaultSecurityHardening`.
- let private api () =
- Api.makeProxy<FooApi> (customOptions = UserSession.withRequestHeaders)
+ // Module-level per the SDK convention — see
+ // `toolup-forge/docs/platform/client-remoting-proxies.md`. The
+ // `UserSession.withRequestHeaders` customiser is a passthrough; CSRF /
+ // auth headers attach at send time via `CsrfClient`'s request-guard,
+ // not at proxy-build time.
+ let private api: FooApi =
+ Api.makeProxy<FooApi> (customOptions = UserSession.withRequestHeaders)
Then sweep call sites: (api ()).Method args → api.Method args. If your editor has find/replace, the simplest pair is (api ()) → api (and (configApi ()) → configApi where present). Run Fantomas after.
Verification
dotnet build <your-app>.sln— clean.dotnet fable -o output --noCachefor the consuming client project — clean. Browser smoke-test that mutating calls still carry theX-CSRF-Tokenheader (DevTools → Network → any POST to/api/*).- A diff vs the previous build's Fable JS shows the per-call proxy-construction code removed; the proxy is constructed once during module init.
Rollback
Revert the diff above. If a future change re-introduces a header-snapshot customiser on UserSession.withRequestHeaders — see the convention doc's "When per-call would be needed" section — the per-call shape becomes correct again, but the right place to relitigate that trade-off is the customiser PR review, not a consumer-module defensive scattering.
See also
docs/platform/client-remoting-proxies.md— canonical statement of the client-Remoting proxy convention this sweep adopts.