Resource primitives
Contract
v0.1.23 adds Go/WASM-first resource primitives to the reusable runtime
packages inside bus-ui. A resource client resolves safe host paths, attaches
approved request helpers, executes requests, decodes responses, and maps
provider failures into public UI result values.
import (
"context"
uiresource "github.com/busdk/bus-ui/pkg/uikit/uiresource"
uisession "github.com/busdk/bus-ui/pkg/uikit/uisession"
)
ctx := context.Background()
session := uisession.FromHost(hostSession)
draft := Draft{Title: "Release notes"}
client := uiresource.Client{
Base: uiresource.ModuleAPI,
Path: "/v1/drafts",
Session: session,
}
result := uiresource.UseResource(client).PostJSON(ctx, draft)
Resource requests support GET, POST, PUT, PATCH, DELETE, multipart
upload, redirect requests, abort signals, and provider-error mapping. Fetch
streaming is represented as a reader interface with cancellation; it does not
make the minimal runtime a terminal protocol or general networking library.
Valid resource paths are same-origin absolute paths such as /v1/drafts, or
host-resolved paths such as {Base: uiresource.PortalAPI, Path: "/v1/session"}.
Rejected paths include javascript:alert(1), data:text/html,...,
https://example.test/v1/drafts without an explicit host allowlist, empty
paths, and paths containing ...
Authentication comes from uisession.RequestAuthorizer. Client.Session
implements that interface. Before dispatch, the resource client calls
Authorize(req uiresource.Request) (uiresource.Request, error), which attaches
bearer behavior for approved API requests and CSRF behavior for same-origin
unsafe methods.
Provider failures return uiresource.Result{State: uiresource.ProviderError}.
The public error fields are Title, Summary, Status, RequestID, and
Fields []uiresource.FieldError. Field errors use Path, Code, and
optional Message. Raw response bodies, tokens, stack traces, SQL, and
credentials are never copied into the result.
Requirements
- Paths are same-origin or host-resolved and reject unsafe schemes, external
origins without allowlist, empty paths, and
... - Bearer and CSRF handling comes from
uisession.RequestAuthorizer. - Multipart upload uses file handles from v0.1.16 and product-owned validation.
- Abort signals cancel requests and close stream readers.
- Provider errors redact secrets and expose public title, summary, status, request id, and field errors where available.
- Tests can use fake clients, fake streams, and deterministic provider errors.
Boundary
Resources do not own product endpoints, authorization policy, provider DTOs, or terminal protocols. They give actions and effects a safe transport primitive that can run in Go/WASM, server-side tests, and pure unit tests.