first commit
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# `bridge-marshal`
|
||||
|
||||
## Purpose
|
||||
|
||||
Shared `RequestContext` → `SerializedRequest` and `SerializedResponse`
|
||||
→ `Response` helpers used by BOTH bridge variants. Splitting them out
|
||||
keeps `bridge-direct.ts` and `bridge-wasi-stdio.ts` focused on the
|
||||
guest-call orchestration that differs between variants — the wire
|
||||
marshalling is identical because both variants exchange the same
|
||||
`SerializedRequest` / `SerializedResponse` shapes (the difference is
|
||||
the transport: linear-memory copy vs. WASI-stdio frame).
|
||||
|
||||
The error-code mapping for sandbox-originated `errorCode` values is
|
||||
also shared: `SAND_PERM.DENIED` surfaces as `SandboxPermissionError`,
|
||||
everything else as `SAND_WASM_BRIDGE.CAPABILITY_DENIED` carrying the
|
||||
plugin's own code.
|
||||
|
||||
## Features
|
||||
|
||||
- `marshalContextRequest(ctx)` — convert a structural `RequestContext`
|
||||
into the wire `SerializedRequest`. Body bytes are base64-url-no-pad
|
||||
encoded; headers are lowercased.
|
||||
- `buildHostResponse(wire, pluginName)` — convert the wire
|
||||
`SerializedResponse` into a host `Response`. When `wire.errorCode`
|
||||
is set, raise the matching sandbox error instead of returning a
|
||||
response.
|
||||
- `RequestContextLike` — minimal structural interface for the five
|
||||
fields the bridge reads. Defined here so neither variant has to
|
||||
import the host's generic `RequestContext<T>`.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
buildHostResponse,
|
||||
marshalContextRequest,
|
||||
type RequestContextLike,
|
||||
} from "../bridge/bridge-marshal.js";
|
||||
|
||||
async function handle(ctx: RequestContextLike): Promise<Response> {
|
||||
const wire = await marshalContextRequest(ctx);
|
||||
void wire;
|
||||
return buildHostResponse(
|
||||
{ status: 200, headers: [], bodyBase64: "" },
|
||||
"plugin",
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { buildHostResponse } from "../bridge/bridge-marshal.js";
|
||||
import {
|
||||
SAND_WASM_BRIDGE_CODES,
|
||||
SandboxWasmBridgeError,
|
||||
} from "../error-codes/error-codes.js";
|
||||
|
||||
try {
|
||||
const res = buildHostResponse(
|
||||
{
|
||||
status: 500,
|
||||
headers: [],
|
||||
bodyBase64: "",
|
||||
errorCode: "PLUGIN.RATE_LIMITED",
|
||||
errorMessage: "too many",
|
||||
},
|
||||
"billing",
|
||||
);
|
||||
void res;
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof SandboxWasmBridgeError &&
|
||||
err.code === SAND_WASM_BRIDGE_CODES.CAPABILITY_DENIED
|
||||
) {
|
||||
// The plugin's own code is on `err.context.sandboxErrorCode`.
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `marshalContextRequest(ctx: RequestContextLike): Promise<SerializedRequest>`
|
||||
|
||||
Reads the request body via `arrayBuffer()` once and encodes the bytes
|
||||
as base64-url-no-pad. Headers are lowercased.
|
||||
|
||||
### `buildHostResponse(wire: SerializedResponse, pluginName: string): Response`
|
||||
|
||||
Throws `SandboxPermissionError` when `wire.errorCode === "SAND_PERM.DENIED"`;
|
||||
otherwise throws `SandboxWasmBridgeError` with code
|
||||
`CAPABILITY_DENIED` for any other `errorCode`. Returns a `Response`
|
||||
when no error.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- Base64-url-no-pad matches the encoding used by `api-types/sandbox-bridge`'s
|
||||
documented body field; both bridges and Javy guests use the same
|
||||
encoding so the wire shape stays consistent.
|
||||
- The request's `body` is materialised eagerly via `arrayBuffer()`
|
||||
because the wasi-stdio guest cannot read from a `ReadableStream` —
|
||||
the entire payload must be in the envelope before it crosses the
|
||||
fd 0 boundary.
|
||||
- Capability denials route through `SAND_PERM.DENIED` regardless of
|
||||
variant; the bridge-local `CAPABILITY_DENIED` is reserved for
|
||||
plugin-originated codes outside the `SAND_PERM` namespace.
|
||||
Reference in New Issue
Block a user