/** * JSON-RPC 2.0 request parser — accepts a raw body (string or already- * parsed JSON) and returns a discriminated-union `ParseResult` that * describes what the transport should dispatch. * * The stable JSON-RPC operation-catalog contract enforces: * - `params` MUST be absent or a JSON object. Array-form positional * params are rejected with `InvalidRequest` (-32600). This matches * OpenRPC's `paramStructure: "by-name"` contract and eliminates a * whole class of drift between REST (which has no positional form) * and JSON-RPC. * - `jsonrpc` MUST be the literal string `"2.0"`. No auto-upgrade * from 1.0 or 1.1. * - `method` MUST be a non-empty string. The name regex * (`validateOperationName` in `operation-catalog.ts`) is NOT * enforced here — the dispatcher treats an unknown name as * `MethodNotFound`, which is the spec's intended semantics. * - Notifications are requests with no `id` key. Explicit `id: null` * is a real request (not a notification) per spec — the parser * surfaces this via `isNotification: false`. * * The result is transport-neutral: HTTP POST, WebSocket frames, and * stdio sessions all consume the same `ParseResult`. */ import { JSON_RPC_ERROR_CODES, type JsonRpcId, type JsonRpcRequest } from './json-rpc-protocol.ts'; /** * A request body that has been parsed successfully. Either a single * request, a batch of per-item parse results, or a body-level error. */ export type ParseResult = { readonly kind: 'parse-error'; readonly code: typeof JSON_RPC_ERROR_CODES.PARSE_ERROR; readonly message: string; } | { readonly kind: 'invalid-request'; readonly code: typeof JSON_RPC_ERROR_CODES.INVALID_REQUEST; readonly message: string; readonly id: JsonRpcId; } | { readonly kind: 'single'; readonly request: JsonRpcRequest; readonly isNotification: boolean; } | { readonly kind: 'batch'; readonly items: ReadonlyArray; }; export type ParsedBatchItem = { readonly kind: 'valid'; readonly request: JsonRpcRequest; readonly isNotification: boolean; } | { readonly kind: 'invalid'; readonly code: typeof JSON_RPC_ERROR_CODES.INVALID_REQUEST; readonly message: string; readonly id: JsonRpcId; }; /** * Parse a raw body into a transport-neutral `ParseResult`. Accepts * either a string (will be JSON.parse'd) or an already-parsed value. */ /** * Hard upper bound on batch size. A well-behaved client will stay well * below this; the limit exists to make a hostile client's first attempt * at memory/CPU exhaustion cheap to fail. Transport adapters (Phase 11 * HTTP, Phase 12 WebSocket, Phase 13 stdio) SHOULD enforce their own * body/frame byte limits in addition to this item cap. */ export declare const MAX_JSON_RPC_BATCH_ITEMS = 100; export declare function parseJsonRpcRequest(body: unknown): ParseResult;