testing/rpc_helpers.ts

JSON-RPC test helpers โ€” request construction, response assertion, and one-shot call ergonomics.

Shared by testing/rpc_attack_surface.ts, testing/rpc_round_trip.ts, and consumer-facing admin/audit suites that exercise RPC methods directly.

Declarations
#

19 declarations

view source

assert_jsonrpc_error_response
#

testing/rpc_helpers.ts view source

(body: unknown, expected_code?: -32700 | -32600 | -32601 | -32602 | -32603 | (number & $brand<"JsonrpcServerErrorCode">) | undefined): void

Assert that a response body is a valid JSON-RPC error response.

Validates the structure matches JsonrpcErrorResponse and optionally checks the error code.

body

type unknown

expected_code?

optional error code to assert

type -32700 | -32600 | -32601 | -32602 | -32603 | (number & $brand<"JsonrpcServerErrorCode">) | undefined
optional

returns

void

assert_jsonrpc_success_response
#

testing/rpc_helpers.ts view source

(body: unknown, output_schema?: ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>> | undefined): void

Assert that a response body is a valid JSON-RPC success response.

Validates the structure matches JsonrpcResponse. When output_schema is provided, also validates the result field against the declared output schema โ€” matching the REST round-trip's assert_response_matches_spec.

body

type unknown

output_schema?

optional Zod schema to validate the result field against

type ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>> | undefined
optional

returns

void

create_rpc_get_url
#

testing/rpc_helpers.ts view source

(endpoint_path: string, method: string, params?: unknown, id?: string | number): string

Build a GET URL with JSON-RPC query parameters.

endpoint_path

the RPC endpoint path (e.g., /api/rpc)

type string

method

type string

params?

params (omit for parameterless methods)

type unknown
optional

id

request id (default 'test')

type string | number
default 'test'

returns

string

create_rpc_post_init
#

testing/rpc_helpers.ts view source

(method: string, params?: unknown, id?: string | number): RequestInit

Create a RequestInit for a JSON-RPC POST request.

method

type string

params?

params (omit for parameterless methods; null is also stripped for ergonomic call sites โ€” JSON-RPC 2.0 ยง4.2 forbids "params": null on the wire, and create_rpc_endpoint rejects z.null() action input schemas at registration). Tests that need to construct a literal "params": null envelope (e.g. asserting envelope-level rejection) should build the body inline rather than route through this helper.

type unknown
optional

id

request id (default 'test')

type string | number
default 'test'

returns

RequestInit

find_rpc_action
#

testing/rpc_helpers.ts view source

(rpc_endpoints: readonly RpcEndpointSpec[], method: string): { path: string; action: RpcAction; } | undefined

Find the RpcAction for a method within a set of RPC endpoint specs. Returns both the endpoint path and the matched action. undefined when the method is not registered.

rpc_endpoints

type readonly RpcEndpointSpec[]

method

type string

returns

{ path: string; action: RpcAction; } | undefined

find_rpc_method
#

testing/rpc_helpers.ts view source

(rpc_endpoints: readonly AppSurfaceRpcEndpoint[], method: string): { path: string; method_spec: AppSurfaceRpcMethod; } | undefined

Find the generated surface entry for a method โ€” the shape returned by generate_app_surface (JSON-serializable, useful for schema assertions at the boundary of a consumer test).

rpc_endpoints

type readonly AppSurfaceRpcEndpoint[]

method

type string

returns

{ path: string; method_spec: AppSurfaceRpcMethod; } | undefined

http_transport
#

testing/rpc_helpers.ts view source

(app: { request: (input: string, init: RequestInit) => Response | Promise<Response>; }): RpcTestTransport

Adapt a Hono-style app into an RpcTestTransport.

app

type { request: (input: string, init: RequestInit) => Response | Promise<Response>; }

returns

RpcTestTransport

require_rpc_endpoint_path
#

testing/rpc_helpers.ts view source

(rpc_endpoints: readonly RpcEndpointSpec[]): string

Resolve a single RPC endpoint path โ€” the common case where a consumer mounts exactly one create_rpc_endpoint.

Used at suite setup time to hard-fail integration suites (admin / audit / SSE / rate-limiting) when the consumer omitted rpc_endpoints rather than letting tests fail mid-run with confusing errors.

Callers that need multi-endpoint support should iterate rpc_endpoints directly.

rpc_endpoints

type readonly RpcEndpointSpec[]

returns

string

throws

  • Error - if `rpc_endpoints` is empty (hard-fail; see the suite options

resolve_rpc_endpoints_for_setup
#

testing/rpc_helpers.ts view source

(rpc_endpoints: RpcEndpointsSuiteOption, session_options: SessionOptions<string>): RpcEndpointSpec[]

Resolve a suite's rpc_endpoints option to an array for setup-time inspection (path lookup, action presence checks).

For the factory form this invokes the factory twice with stub AppServerContexts and asserts that both invocations produce the same (path, method-list) shape โ€” catching factories that close over mutable state or otherwise diverge across calls. The first array is returned; the second is discarded after the comparison. create_app_server invokes the factory again per-test with its real ctx, and those are the handlers that actually serve requests.

Safe as long as the factory is pure with respect to the endpoint path and the action spec.method list โ€” the canonical helpers (create_standard_rpc_actions, create_admin_actions, create_account_actions, etc.) are. Factories that return a different path based on ctx will produce a setup/runtime mismatch; the path-purity assert below surfaces that as a clear gro check error rather than a silent test/runtime drift.

rpc_endpoints

session_options

type SessionOptions<string>

returns

RpcEndpointSpec[]

throws

  • Error - if the factory's two stub-ctx invocations produce different

rpc_call
#

testing/rpc_helpers.ts view source

(args: RpcCallArgs): Promise<RpcCallResult>

One-shot JSON-RPC call over a Hono app.

Merges sensible defaults (host, origin, Content-Type) under caller-provided headers, fires POST (default) or GET, parses the envelope, and returns a discriminated result.

args

returns

Promise<RpcCallResult>

throws

  • Error - if the response body is neither a valid `JsonrpcResponse`

rpc_call_for_spec
#

testing/rpc_helpers.ts view source

<TSpec extends RequestResponseActionSpec>(args: RpcCallForSpecArgs<TSpec>): Promise<RpcCallResultForSpec<TSpec>>

Typed wrapper over rpc_call โ€” binds params to z.infer<spec.input> and the success result to z.infer<spec.output> via the generic.

Success results are validated at runtime against spec.output (same contract as rpc_call_typed); a mismatch throws. Error responses come back on the discriminated {ok: false, error} branch โ€” use this for happy-path + denial-path assertions where the error data.reason shape is still asserted manually. For adversarial input tests that send malformed params, use the untyped rpc_call.

args

type RpcCallForSpecArgs<TSpec>

returns

Promise<RpcCallResultForSpec<TSpec>>

throws

  • Error - if the success `result` does not parse against `spec.output`,

rpc_call_non_browser
#

testing/rpc_helpers.ts view source

(args: Omit<RpcCallArgs, "suppress_default_origin">): Promise<RpcCallResult>

Same as rpc_call but without the default origin header. Use for bearer-auth probes: bearer_auth discards the token when Origin or Referer is present (browser context), so a bearer probe via rpc_call would short-circuit to 401 before the token is ever validated.

Equivalent to rpc_call({...args, suppress_default_origin: true}).

args

type Omit<RpcCallArgs, "suppress_default_origin">

returns

Promise<RpcCallResult>

rpc_call_typed
#

testing/rpc_helpers.ts view source

<T>(args: RpcCallArgs, output_schema: ZodType<T, unknown, $ZodTypeInternals<T, unknown>>): Promise<T>

Same as rpc_call but parses the success result through the given output schema and returns typed data. Envelope-level failures or error responses throw โ€” use the untyped rpc_call for tests that need to assert on specific error shapes.

args

output_schema

type ZodType<T, unknown, $ZodTypeInternals<T, unknown>>

returns

Promise<T>

throws

  • Error - if the response is a JSON-RPC error, if `rpc_call` throws

RpcCallArgs
#

testing/rpc_helpers.ts view source

RpcCallArgs

Arguments for rpc_call.

app

Hono-like app (anything with a request(url, init) method).

type {request: (input: string, init: RequestInit) => Promise<Response> | Response}

path

RPC endpoint path, e.g. '/api/rpc'.

type string

method

JSON-RPC method name.

type string

params

Params for the call. Omit (or pass undefined) for parameterless (z.void()) methods โ€” the helper drops params from the envelope either way. See create_rpc_post_init for the null-stripping affordance and JSON-RPC 2.0 ยง4.2's prohibition on params: null.

type unknown

headers

Extra request headers (session cookie, bearer, etc.). Overrides defaults.

type Record<string, string>

id

Request id. Defaults to 'test'.

type string | number

verb

HTTP verb โ€” 'POST' (default) or 'GET' for side_effects: false methods.

type 'POST' | 'GET'

suppress_default_origin

Suppress the default origin header. Required for bearer-auth paths: bearer_auth discards the token when Origin or Referer is present (browser context), so probing it via rpc_call needs this flag โ€” or use rpc_call_non_browser, which sets it for you.

type boolean

RpcCallForSpecArgs
#

RpcCallResult
#

RpcCallResultForSpec
#

RpcEndpointsSuiteOption
#

testing/rpc_helpers.ts view source

RpcEndpointsSuiteOption

Union accepted by the suite-level rpc_endpoints option โ€” eager array or a factory that takes an AppServerContext and returns endpoint specs. The factory form is required when action handlers must close over the per-test ctx.app_settings / ctx.deps (e.g. the canonical create_standard_rpc_actions(ctx.deps, {app_settings: ctx.app_settings}) pattern). create_app_server resolves either shape natively; test helpers forward the raw value to app_options.rpc_endpoints for live dispatch.

RpcTestTransport
#

testing/rpc_helpers.ts view source

RpcTestTransport

Minimal transport surface โ€” the duck type Hono.request already satisfies. Extracted so test setups that want an in-process / WS / mock path can plug a different dispatcher without changing call sites.

Depends on
#

Imported by
#