@fuzdev/fuz_app 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/actions/action_bridge.d.ts +3 -3
  2. package/dist/actions/action_bridge.d.ts.map +1 -1
  3. package/dist/actions/action_bridge.js +5 -4
  4. package/dist/actions/action_rpc.d.ts +89 -0
  5. package/dist/actions/action_rpc.d.ts.map +1 -0
  6. package/dist/actions/action_rpc.js +248 -0
  7. package/dist/actions/action_spec.d.ts +8 -8
  8. package/dist/actions/action_spec.d.ts.map +1 -1
  9. package/dist/actions/action_spec.js +2 -2
  10. package/dist/http/db_routes.d.ts.map +1 -1
  11. package/dist/http/db_routes.js +4 -2
  12. package/dist/http/jsonrpc.d.ts +62 -0
  13. package/dist/http/jsonrpc.d.ts.map +1 -0
  14. package/dist/http/jsonrpc.js +49 -0
  15. package/dist/http/jsonrpc_errors.d.ts +132 -0
  16. package/dist/http/jsonrpc_errors.d.ts.map +1 -0
  17. package/dist/http/jsonrpc_errors.js +197 -0
  18. package/dist/http/route_spec.d.ts +2 -1
  19. package/dist/http/route_spec.d.ts.map +1 -1
  20. package/dist/http/route_spec.js +43 -7
  21. package/dist/http/schema_helpers.d.ts +3 -3
  22. package/dist/http/schema_helpers.d.ts.map +1 -1
  23. package/dist/http/schema_helpers.js +5 -10
  24. package/dist/http/surface.d.ts +25 -0
  25. package/dist/http/surface.d.ts.map +1 -1
  26. package/dist/http/surface.js +16 -1
  27. package/dist/server/app_server.d.ts +3 -1
  28. package/dist/server/app_server.d.ts.map +1 -1
  29. package/dist/server/app_server.js +2 -1
  30. package/dist/testing/adversarial_input.d.ts.map +1 -1
  31. package/dist/testing/adversarial_input.js +22 -7
  32. package/dist/testing/stubs.d.ts +3 -1
  33. package/dist/testing/stubs.d.ts.map +1 -1
  34. package/dist/testing/stubs.js +2 -1
  35. package/dist/testing/surface_invariants.d.ts +4 -0
  36. package/dist/testing/surface_invariants.d.ts.map +1 -1
  37. package/dist/testing/surface_invariants.js +4 -0
  38. package/package.json +1 -1
@@ -0,0 +1,49 @@
1
+ /**
2
+ * JSON-RPC 2.0 envelope schemas for the single RPC endpoint dispatcher.
3
+ *
4
+ * Minimal subset extracted from zzz's `jsonrpc.ts` — only what the
5
+ * `create_rpc_endpoint` dispatcher needs to parse incoming requests
6
+ * and format outgoing responses. Full JSON-RPC schemas (batching,
7
+ * MCP extensions, notification types) remain in zzz.
8
+ *
9
+ * Following MCP, params and result are object-only (no positional arrays).
10
+ *
11
+ * @source https://github.com/modelcontextprotocol/typescript-sdk
12
+ * @see https://www.jsonrpc.org/specification
13
+ * @module
14
+ */
15
+ import { z } from 'zod';
16
+ export const JSONRPC_VERSION = '2.0';
17
+ /** A uniquely identifying id for a request in JSON-RPC. Like MCP, excludes null. */
18
+ export const JsonrpcRequestId = z.union([z.string(), z.number()]);
19
+ /** A JSON-RPC method name. */
20
+ export const JsonrpcMethod = z.string();
21
+ /** Request params — loose object to allow additional properties. */
22
+ export const JsonrpcRequestParams = z.looseObject({});
23
+ /** Result — loose object to allow additional properties. */
24
+ export const JsonrpcResult = z.looseObject({});
25
+ /** A request that expects a response. */
26
+ export const JsonrpcRequest = z.looseObject({
27
+ jsonrpc: z.literal(JSONRPC_VERSION),
28
+ id: JsonrpcRequestId,
29
+ method: JsonrpcMethod,
30
+ params: JsonrpcRequestParams.optional(),
31
+ });
32
+ /** A successful (non-error) response to a request. */
33
+ export const JsonrpcResponse = z.looseObject({
34
+ jsonrpc: z.literal(JSONRPC_VERSION),
35
+ id: JsonrpcRequestId,
36
+ result: JsonrpcResult,
37
+ });
38
+ /** Error object within a JSON-RPC error response. */
39
+ export const JsonrpcErrorObject = z.looseObject({
40
+ code: z.number(),
41
+ message: z.string(),
42
+ data: z.unknown().optional(),
43
+ });
44
+ /** A response that indicates an error occurred. */
45
+ export const JsonrpcErrorResponse = z.looseObject({
46
+ jsonrpc: z.literal(JSONRPC_VERSION),
47
+ id: JsonrpcRequestId.nullable(),
48
+ error: JsonrpcErrorObject,
49
+ });
@@ -0,0 +1,132 @@
1
+ /**
2
+ * JSON-RPC error infrastructure for fuz_app routes.
3
+ *
4
+ * Provides error types, named constructors, and HTTP status mapping
5
+ * for the throw/catch error pattern used by `apply_route_specs`.
6
+ * Extracted from zzz's `jsonrpc_errors.ts` — only core error codes
7
+ * (5 standard + 8 general application). Domain-specific codes stay
8
+ * in consumers. `JSONRPC_ERROR_CODES` is extensible — consumers
9
+ * add their own codes by casting `as JsonrpcErrorCode`.
10
+ *
11
+ * Complementary to `error_schemas.ts`: that module is declarative
12
+ * (Zod schemas for surface introspection), this one is runtime
13
+ * (throw + catch + map).
14
+ *
15
+ * @module
16
+ */
17
+ /** Branded number type for JSON-RPC error codes. */
18
+ export type JsonrpcErrorCode = number & {
19
+ readonly __brand: 'JsonrpcErrorCode';
20
+ };
21
+ /** JSON-RPC error response object — code, message, and optional data. */
22
+ export interface JsonrpcErrorJson {
23
+ code: JsonrpcErrorCode;
24
+ message: string;
25
+ data?: unknown;
26
+ }
27
+ /** Names of standard and general application JSON-RPC error codes. */
28
+ export type JsonrpcErrorName = 'parse_error' | 'invalid_request' | 'method_not_found' | 'invalid_params' | 'internal_error' | 'unauthenticated' | 'forbidden' | 'not_found' | 'conflict' | 'validation_error' | 'rate_limited' | 'service_unavailable' | 'timeout';
29
+ /**
30
+ * Standard JSON-RPC error codes (5) plus general application codes (8).
31
+ *
32
+ * Extensible — consumers add domain-specific codes to their own objects
33
+ * by casting `as JsonrpcErrorCode`. Application codes use the -32000 to
34
+ * -32099 range reserved by the JSON-RPC spec.
35
+ */
36
+ export declare const JSONRPC_ERROR_CODES: {
37
+ /** -32700 */
38
+ readonly parse_error: JsonrpcErrorCode;
39
+ /** -32600 */
40
+ readonly invalid_request: JsonrpcErrorCode;
41
+ /** -32601 */
42
+ readonly method_not_found: JsonrpcErrorCode;
43
+ /** -32602 */
44
+ readonly invalid_params: JsonrpcErrorCode;
45
+ /** -32603 */
46
+ readonly internal_error: JsonrpcErrorCode;
47
+ /**
48
+ * Same as HTTP 401 "unauthorized", but correctly named.
49
+ *
50
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status#client_error_responses
51
+ */
52
+ readonly unauthenticated: JsonrpcErrorCode;
53
+ /**
54
+ * Named to match HTTP 403 — avoids confusion with 401 which
55
+ * is incorrectly named "unauthorized" in HTTP.
56
+ */
57
+ readonly forbidden: JsonrpcErrorCode;
58
+ readonly not_found: JsonrpcErrorCode;
59
+ readonly conflict: JsonrpcErrorCode;
60
+ /**
61
+ * Application-level validation failures (business logic).
62
+ * Use `invalid_params` (-32602) for schema/parsing failures.
63
+ */
64
+ readonly validation_error: JsonrpcErrorCode;
65
+ readonly rate_limited: JsonrpcErrorCode;
66
+ readonly service_unavailable: JsonrpcErrorCode;
67
+ readonly timeout: JsonrpcErrorCode;
68
+ };
69
+ /**
70
+ * Named constructors for `JsonrpcErrorJson` objects.
71
+ *
72
+ * Each function creates a JSON-RPC error response object with the correct
73
+ * code and a sensible default message. Used by the catch layer in
74
+ * `apply_route_specs` to build response bodies.
75
+ */
76
+ export declare const jsonrpc_error_messages: {
77
+ readonly parse_error: (data?: unknown) => JsonrpcErrorJson;
78
+ readonly invalid_request: (data?: unknown) => JsonrpcErrorJson;
79
+ readonly method_not_found: (method?: string, data?: unknown) => JsonrpcErrorJson;
80
+ readonly invalid_params: (message?: string, data?: unknown) => JsonrpcErrorJson;
81
+ readonly internal_error: (message?: string, data?: unknown) => JsonrpcErrorJson;
82
+ readonly unauthenticated: (message?: string, data?: unknown) => JsonrpcErrorJson;
83
+ readonly forbidden: (message?: string, data?: unknown) => JsonrpcErrorJson;
84
+ readonly not_found: (resource?: string, data?: unknown) => JsonrpcErrorJson;
85
+ readonly conflict: (message?: string, data?: unknown) => JsonrpcErrorJson;
86
+ readonly validation_error: (message?: string, data?: unknown) => JsonrpcErrorJson;
87
+ readonly rate_limited: (message?: string, data?: unknown) => JsonrpcErrorJson;
88
+ readonly service_unavailable: (message?: string, data?: unknown) => JsonrpcErrorJson;
89
+ readonly timeout: (message?: string, data?: unknown) => JsonrpcErrorJson;
90
+ };
91
+ /**
92
+ * Error class carrying a JSON-RPC error code — thrown by handlers,
93
+ * caught by `apply_route_specs` and mapped to HTTP status + JSON-RPC error response.
94
+ *
95
+ * Named for what it is: an error with a JSON-RPC error code that gets thrown.
96
+ */
97
+ export declare class ThrownJsonrpcError extends Error {
98
+ code: JsonrpcErrorCode;
99
+ data?: unknown;
100
+ constructor(code: JsonrpcErrorCode, message: string, data?: unknown, options?: ErrorOptions);
101
+ }
102
+ /**
103
+ * Named constructors for `ThrownJsonrpcError`.
104
+ *
105
+ * Usage: `throw jsonrpc_errors.not_found('user')` or `throw jsonrpc_errors.forbidden()`.
106
+ */
107
+ export declare const jsonrpc_errors: {
108
+ readonly parse_error: (data?: unknown) => ThrownJsonrpcError;
109
+ readonly invalid_request: (data?: unknown) => ThrownJsonrpcError;
110
+ readonly method_not_found: (method?: string | undefined, data?: unknown) => ThrownJsonrpcError;
111
+ readonly invalid_params: (message?: string | undefined, data?: unknown) => ThrownJsonrpcError;
112
+ readonly internal_error: (message?: string | undefined, data?: unknown) => ThrownJsonrpcError;
113
+ readonly unauthenticated: (message?: string | undefined, data?: unknown) => ThrownJsonrpcError;
114
+ readonly forbidden: (message?: string | undefined, data?: unknown) => ThrownJsonrpcError;
115
+ readonly not_found: (resource?: string | undefined, data?: unknown) => ThrownJsonrpcError;
116
+ readonly conflict: (message?: string | undefined, data?: unknown) => ThrownJsonrpcError;
117
+ readonly validation_error: (message?: string | undefined, data?: unknown) => ThrownJsonrpcError;
118
+ readonly rate_limited: (message?: string | undefined, data?: unknown) => ThrownJsonrpcError;
119
+ readonly service_unavailable: (message?: string | undefined, data?: unknown) => ThrownJsonrpcError;
120
+ readonly timeout: (message?: string | undefined, data?: unknown) => ThrownJsonrpcError;
121
+ };
122
+ /**
123
+ * Map a JSON-RPC error code to an HTTP status code.
124
+ *
125
+ * Returns 500 for unrecognized codes (consumer-defined codes
126
+ * without a mapping default to internal server error).
127
+ *
128
+ * @param code - the JSON-RPC error code
129
+ * @returns the corresponding HTTP status code
130
+ */
131
+ export declare const jsonrpc_error_code_to_http_status: (code: JsonrpcErrorCode) => number;
132
+ //# sourceMappingURL=jsonrpc_errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonrpc_errors.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/jsonrpc_errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,oDAAoD;AACpD,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG;IAAC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAA;CAAC,CAAC;AAE/E,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAED,sEAAsE;AACtE,MAAM,MAAM,gBAAgB,GACzB,aAAa,GACb,iBAAiB,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,iBAAiB,GACjB,WAAW,GACX,WAAW,GACX,UAAU,GACV,kBAAkB,GAClB,cAAc,GACd,qBAAqB,GACrB,SAAS,CAAC;AAEb;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB;IAE/B,aAAa;0BACU,gBAAgB;IACvC,aAAa;8BACc,gBAAgB;IAC3C,aAAa;+BACe,gBAAgB;IAC5C,aAAa;6BACa,gBAAgB;IAC1C,aAAa;6BACa,gBAAgB;IAG1C;;;;OAIG;8BACwB,gBAAgB;IAC3C;;;OAGG;wBACkB,gBAAgB;wBAChB,gBAAgB;uBACjB,gBAAgB;IACpC;;;OAGG;+BACyB,gBAAgB;2BACpB,gBAAgB;kCACT,gBAAgB;sBAC5B,gBAAgB;CAC2B,CAAC;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB;kCACb,OAAO,KAAG,gBAAgB;sCAMtB,OAAO,KAAG,gBAAgB;yCAMvB,MAAM,SAAS,OAAO,KAAG,gBAAgB;wCAM1C,MAAM,SAAS,OAAO,KAAG,gBAAgB;wCAO1D,MAAM,SACR,OAAO,KACZ,gBAAgB;yCAMQ,MAAM,SAA6B,OAAO,KAAG,gBAAgB;mCAMnE,MAAM,SAAuB,OAAO,KAAG,gBAAgB;oCAMrD,MAAM,SAAS,OAAO,KAAG,gBAAgB;kCAM5C,MAAM,SAAsB,OAAO,KAAG,gBAAgB;0CAM9C,MAAM,SAA8B,OAAO,KAAG,gBAAgB;sCAMlE,MAAM,SAA0B,OAAO,KAAG,gBAAgB;6CAOxE,MAAM,SACR,OAAO,KACZ,gBAAgB;iCAMA,MAAM,SAAqB,OAAO,KAAG,gBAAgB;CAKe,CAAC;AAEzF;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;gBAEH,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY;CAK3F;AAWD;;;;GAIG;AACH,eAAO,MAAM,cAAc;8CAXQ,kBAAkB;kDAAlB,kBAAkB;gFAAlB,kBAAkB;+EAAlB,kBAAkB;+EAAlB,kBAAkB;gFAAlB,kBAAkB;0EAAlB,kBAAkB;2EAAlB,kBAAkB;yEAAlB,kBAAkB;iFAAlB,kBAAkB;6EAAlB,kBAAkB;oFAAlB,kBAAkB;wEAAlB,kBAAkB;CAyBqC,CAAC;AAoB3F;;;;;;;;GAQG;AACH,eAAO,MAAM,iCAAiC,GAAI,MAAM,gBAAgB,KAAG,MACjB,CAAC"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * JSON-RPC error infrastructure for fuz_app routes.
3
+ *
4
+ * Provides error types, named constructors, and HTTP status mapping
5
+ * for the throw/catch error pattern used by `apply_route_specs`.
6
+ * Extracted from zzz's `jsonrpc_errors.ts` — only core error codes
7
+ * (5 standard + 8 general application). Domain-specific codes stay
8
+ * in consumers. `JSONRPC_ERROR_CODES` is extensible — consumers
9
+ * add their own codes by casting `as JsonrpcErrorCode`.
10
+ *
11
+ * Complementary to `error_schemas.ts`: that module is declarative
12
+ * (Zod schemas for surface introspection), this one is runtime
13
+ * (throw + catch + map).
14
+ *
15
+ * @module
16
+ */
17
+ /**
18
+ * Standard JSON-RPC error codes (5) plus general application codes (8).
19
+ *
20
+ * Extensible — consumers add domain-specific codes to their own objects
21
+ * by casting `as JsonrpcErrorCode`. Application codes use the -32000 to
22
+ * -32099 range reserved by the JSON-RPC spec.
23
+ */
24
+ export const JSONRPC_ERROR_CODES = {
25
+ // Standard JSON-RPC errors — https://www.jsonrpc.org/specification
26
+ /** -32700 */
27
+ parse_error: -32700,
28
+ /** -32600 */
29
+ invalid_request: -32600,
30
+ /** -32601 */
31
+ method_not_found: -32601,
32
+ /** -32602 */
33
+ invalid_params: -32602,
34
+ /** -32603 */
35
+ internal_error: -32603,
36
+ // General application errors (-32000 to -32099)
37
+ /**
38
+ * Same as HTTP 401 "unauthorized", but correctly named.
39
+ *
40
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status#client_error_responses
41
+ */
42
+ unauthenticated: -32001,
43
+ /**
44
+ * Named to match HTTP 403 — avoids confusion with 401 which
45
+ * is incorrectly named "unauthorized" in HTTP.
46
+ */
47
+ forbidden: -32002,
48
+ not_found: -32003,
49
+ conflict: -32004,
50
+ /**
51
+ * Application-level validation failures (business logic).
52
+ * Use `invalid_params` (-32602) for schema/parsing failures.
53
+ */
54
+ validation_error: -32005,
55
+ rate_limited: -32006,
56
+ service_unavailable: -32007,
57
+ timeout: -32008,
58
+ };
59
+ /**
60
+ * Named constructors for `JsonrpcErrorJson` objects.
61
+ *
62
+ * Each function creates a JSON-RPC error response object with the correct
63
+ * code and a sensible default message. Used by the catch layer in
64
+ * `apply_route_specs` to build response bodies.
65
+ */
66
+ export const jsonrpc_error_messages = {
67
+ parse_error: (data) => ({
68
+ code: JSONRPC_ERROR_CODES.parse_error,
69
+ message: 'parse error',
70
+ data,
71
+ }),
72
+ invalid_request: (data) => ({
73
+ code: JSONRPC_ERROR_CODES.invalid_request,
74
+ message: 'invalid request',
75
+ data,
76
+ }),
77
+ method_not_found: (method, data) => ({
78
+ code: JSONRPC_ERROR_CODES.method_not_found,
79
+ message: method ? `method not found: ${method}` : 'method not found',
80
+ data,
81
+ }),
82
+ invalid_params: (message, data) => ({
83
+ code: JSONRPC_ERROR_CODES.invalid_params,
84
+ message: message ?? 'invalid params',
85
+ data,
86
+ }),
87
+ internal_error: (message = 'internal server error', data) => ({
88
+ code: JSONRPC_ERROR_CODES.internal_error,
89
+ message,
90
+ data,
91
+ }),
92
+ unauthenticated: (message = 'unauthenticated', data) => ({
93
+ code: JSONRPC_ERROR_CODES.unauthenticated,
94
+ message,
95
+ data,
96
+ }),
97
+ forbidden: (message = 'forbidden', data) => ({
98
+ code: JSONRPC_ERROR_CODES.forbidden,
99
+ message,
100
+ data,
101
+ }),
102
+ not_found: (resource, data) => ({
103
+ code: JSONRPC_ERROR_CODES.not_found,
104
+ message: resource ? `${resource} not found` : 'not found',
105
+ data,
106
+ }),
107
+ conflict: (message = 'conflict', data) => ({
108
+ code: JSONRPC_ERROR_CODES.conflict,
109
+ message,
110
+ data,
111
+ }),
112
+ validation_error: (message = 'validation error', data) => ({
113
+ code: JSONRPC_ERROR_CODES.validation_error,
114
+ message,
115
+ data,
116
+ }),
117
+ rate_limited: (message = 'rate limited', data) => ({
118
+ code: JSONRPC_ERROR_CODES.rate_limited,
119
+ message,
120
+ data,
121
+ }),
122
+ service_unavailable: (message = 'service unavailable', data) => ({
123
+ code: JSONRPC_ERROR_CODES.service_unavailable,
124
+ message,
125
+ data,
126
+ }),
127
+ timeout: (message = 'timeout', data) => ({
128
+ code: JSONRPC_ERROR_CODES.timeout,
129
+ message,
130
+ data,
131
+ }),
132
+ };
133
+ /**
134
+ * Error class carrying a JSON-RPC error code — thrown by handlers,
135
+ * caught by `apply_route_specs` and mapped to HTTP status + JSON-RPC error response.
136
+ *
137
+ * Named for what it is: an error with a JSON-RPC error code that gets thrown.
138
+ */
139
+ export class ThrownJsonrpcError extends Error {
140
+ code;
141
+ data;
142
+ constructor(code, message, data, options) {
143
+ super(message, options);
144
+ this.code = code;
145
+ this.data = data;
146
+ }
147
+ }
148
+ const create_error_thrower = (error_fn) => (...args) => {
149
+ const m = error_fn(...args);
150
+ return new ThrownJsonrpcError(m.code, m.message, m.data);
151
+ };
152
+ /**
153
+ * Named constructors for `ThrownJsonrpcError`.
154
+ *
155
+ * Usage: `throw jsonrpc_errors.not_found('user')` or `throw jsonrpc_errors.forbidden()`.
156
+ */
157
+ export const jsonrpc_errors = {
158
+ parse_error: create_error_thrower(jsonrpc_error_messages.parse_error),
159
+ invalid_request: create_error_thrower(jsonrpc_error_messages.invalid_request),
160
+ method_not_found: create_error_thrower(jsonrpc_error_messages.method_not_found),
161
+ invalid_params: create_error_thrower(jsonrpc_error_messages.invalid_params),
162
+ internal_error: create_error_thrower(jsonrpc_error_messages.internal_error),
163
+ unauthenticated: create_error_thrower(jsonrpc_error_messages.unauthenticated),
164
+ forbidden: create_error_thrower(jsonrpc_error_messages.forbidden),
165
+ not_found: create_error_thrower(jsonrpc_error_messages.not_found),
166
+ conflict: create_error_thrower(jsonrpc_error_messages.conflict),
167
+ validation_error: create_error_thrower(jsonrpc_error_messages.validation_error),
168
+ rate_limited: create_error_thrower(jsonrpc_error_messages.rate_limited),
169
+ service_unavailable: create_error_thrower(jsonrpc_error_messages.service_unavailable),
170
+ timeout: create_error_thrower(jsonrpc_error_messages.timeout),
171
+ };
172
+ // --- HTTP status mapping ---
173
+ const JSONRPC_ERROR_CODE_HTTP_STATUS = new Map([
174
+ [-32700, 400], // parse_error
175
+ [-32600, 400], // invalid_request
176
+ [-32601, 404], // method_not_found
177
+ [-32602, 400], // invalid_params
178
+ [-32603, 500], // internal_error
179
+ [-32001, 401], // unauthenticated
180
+ [-32002, 403], // forbidden
181
+ [-32003, 404], // not_found
182
+ [-32004, 409], // conflict
183
+ [-32005, 422], // validation_error
184
+ [-32006, 429], // rate_limited
185
+ [-32007, 503], // service_unavailable
186
+ [-32008, 504], // timeout
187
+ ]);
188
+ /**
189
+ * Map a JSON-RPC error code to an HTTP status code.
190
+ *
191
+ * Returns 500 for unrecognized codes (consumer-defined codes
192
+ * without a mapping default to internal server error).
193
+ *
194
+ * @param code - the JSON-RPC error code
195
+ * @returns the corresponding HTTP status code
196
+ */
197
+ export const jsonrpc_error_code_to_http_status = (code) => JSONRPC_ERROR_CODE_HTTP_STATUS.get(code) ?? 500;
@@ -171,7 +171,8 @@ export declare const apply_middleware_specs: (app: Hono, specs: Array<Middleware
171
171
  *
172
172
  * For each spec: resolves auth to guards via the provided resolver,
173
173
  * adds input validation middleware (for routes with non-null input schemas),
174
- * wraps handler with DEV-only output and error validation, and registers the route.
174
+ * wraps handler with DEV-only output and error validation, wraps with error
175
+ * catch layer (catches `ThrownJsonrpcError` and generic errors), and registers the route.
175
176
  *
176
177
  * Each handler receives a `RouteContext` with:
177
178
  * - `db`: transaction-scoped (for non-GET) or pool-level (for GET)
@@ -1 +1 @@
1
- {"version":3,"file":"route_spec.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/route_spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route_spec.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/route_spec.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import { DEV } from 'esm-env';
16
16
  import { ERROR_INVALID_JSON_BODY, ERROR_INVALID_REQUEST_BODY, ERROR_INVALID_ROUTE_PARAMS, ERROR_INVALID_QUERY_PARAMS, } from './error_schemas.js';
17
+ import { ThrownJsonrpcError, JSONRPC_ERROR_CODES, jsonrpc_error_code_to_http_status, } from './jsonrpc_errors.js';
17
18
  import { is_null_schema, merge_error_schemas } from './schema_helpers.js';
18
19
  /**
19
20
  * Get validated input from the Hono context.
@@ -54,11 +55,15 @@ export const get_route_query = (c) => {
54
55
  /**
55
56
  * Create input validation middleware for a route spec.
56
57
  *
57
- * Returns an empty array for null-input routes (no body expected).
58
- * For routes with input schemas, returns a middleware that parses and validates
59
- * the JSON body, storing the result on the context as `validated_input`.
58
+ * Returns an empty array for GET routes (no body to parse — GET input is
59
+ * validated elsewhere, e.g. from `?params=` query string in RPC handlers)
60
+ * and for null-input routes (no body expected). For other routes with input
61
+ * schemas, returns a middleware that parses and validates the JSON body,
62
+ * storing the result on the context as `validated_input`.
60
63
  */
61
- const create_input_validation = (input_schema) => {
64
+ const create_input_validation = (input_schema, method) => {
65
+ if (method === 'GET')
66
+ return [];
62
67
  if (is_null_schema(input_schema))
63
68
  return [];
64
69
  const validate = async (c, next) => {
@@ -185,12 +190,41 @@ export const apply_middleware_specs = (app, specs) => {
185
190
  app.use(spec.path, spec.handler);
186
191
  }
187
192
  };
193
+ /**
194
+ * Wrap a handler with error catch logic.
195
+ *
196
+ * Catches `ThrownJsonrpcError` and maps to HTTP status + JSON-RPC error response.
197
+ * Catches generic `Error` and maps to `internal_error` (-32603 → 500), including
198
+ * the error message in DEV only. Existing handlers that return `c.json()` directly
199
+ * are unaffected — the catch layer only activates when something is thrown.
200
+ */
201
+ const wrap_error_catch = (handler, log) => {
202
+ return async (c, next) => {
203
+ try {
204
+ return await handler(c, next);
205
+ }
206
+ catch (err) {
207
+ if (err instanceof ThrownJsonrpcError) {
208
+ const status = jsonrpc_error_code_to_http_status(err.code);
209
+ const error = { code: err.code, message: err.message };
210
+ if (err.data !== undefined)
211
+ error.data = err.data;
212
+ return c.json({ error }, status);
213
+ }
214
+ // generic error — internal_error
215
+ log.error('Unhandled handler error', err);
216
+ const message = DEV && err instanceof Error ? err.message : 'internal server error';
217
+ return c.json({ error: { code: JSONRPC_ERROR_CODES.internal_error, message } }, 500);
218
+ }
219
+ };
220
+ };
188
221
  /**
189
222
  * Apply route specs to a Hono app.
190
223
  *
191
224
  * For each spec: resolves auth to guards via the provided resolver,
192
225
  * adds input validation middleware (for routes with non-null input schemas),
193
- * wraps handler with DEV-only output and error validation, and registers the route.
226
+ * wraps handler with DEV-only output and error validation, wraps with error
227
+ * catch layer (catches `ThrownJsonrpcError` and generic errors), and registers the route.
194
228
  *
195
229
  * Each handler receives a `RouteContext` with:
196
230
  * - `db`: transaction-scoped (for non-GET) or pool-level (for GET)
@@ -215,7 +249,7 @@ export const apply_route_specs = (app, specs, resolve_auth_guards, log, db) => {
215
249
  const guards = resolve_auth_guards(spec.auth);
216
250
  const params_validation = create_params_validation(spec.params);
217
251
  const query_validation = create_query_validation(spec.query);
218
- const validation = create_input_validation(spec.input);
252
+ const input_validation = create_input_validation(spec.input, spec.method);
219
253
  const merged_errors = merge_error_schemas(spec);
220
254
  // Step 1: adapt RouteHandler → Handler (construct RouteContext, call spec.handler)
221
255
  const use_transaction = spec.transaction ?? spec.method !== 'GET';
@@ -225,7 +259,9 @@ export const apply_route_specs = (app, specs, resolve_auth_guards, log, db) => {
225
259
  : (c) => inner(c, { db, background_db: db, pending_effects: c.var.pending_effects });
226
260
  // Step 2: output validation
227
261
  handler = wrap_output_validation(handler, spec.output, merged_errors, log);
228
- app.on(spec.method, [spec.path], ...guards, ...params_validation, ...query_validation, ...validation, handler);
262
+ // Step 3: error catch layer
263
+ handler = wrap_error_catch(handler, log);
264
+ app.on(spec.method, [spec.path], ...guards, ...params_validation, ...query_validation, ...input_validation, handler);
229
265
  }
230
266
  };
231
267
  /**
@@ -13,9 +13,9 @@ import { type RateLimitKey, type RouteErrorSchemas } from './error_schemas.js';
13
13
  /**
14
14
  * Check if a schema is exactly `z.null()`.
15
15
  *
16
- * Uses Zod 4 type introspection (`_zod.def.type`) rather than runtime parsing
17
- * to avoid false positives from `z.nullable(z.string())` or similar schemas
18
- * that accept null but also accept other values.
16
+ * Uses `instanceof` rather than runtime parsing to avoid false positives
17
+ * from `z.nullable(z.string())` or similar schemas that accept null
18
+ * but also accept other values.
19
19
  */
20
20
  export declare const is_null_schema: (schema: z.ZodType) => boolean;
21
21
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAuB,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AAEnG;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAA0C,CAAC;AAE9F;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAI3D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAcrD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM;IACL,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,EACD,oBAAoB,iBAAiB,GAAG,IAAI,KAC1C,iBAAiB,GAAG,IAUtB,CAAC"}
1
+ {"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAuB,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AAEnG;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OACe,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAcrD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM;IACL,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,EACD,oBAAoB,iBAAiB,GAAG,IAAI,KAC1C,iBAAiB,GAAG,IAUtB,CAAC"}
@@ -12,23 +12,18 @@ import { derive_error_schemas } from './error_schemas.js';
12
12
  /**
13
13
  * Check if a schema is exactly `z.null()`.
14
14
  *
15
- * Uses Zod 4 type introspection (`_zod.def.type`) rather than runtime parsing
16
- * to avoid false positives from `z.nullable(z.string())` or similar schemas
17
- * that accept null but also accept other values.
15
+ * Uses `instanceof` rather than runtime parsing to avoid false positives
16
+ * from `z.nullable(z.string())` or similar schemas that accept null
17
+ * but also accept other values.
18
18
  */
19
- export const is_null_schema = (schema) => schema._zod.def.type === 'null';
19
+ export const is_null_schema = (schema) => schema instanceof z.ZodNull;
20
20
  /**
21
21
  * Check if a schema is a strict object (`z.strictObject()`).
22
22
  *
23
23
  * Strict objects set `catchall` to `ZodNever` to reject unknown keys.
24
24
  * Regular `z.object()` has `catchall: undefined` (strips unknown keys in Zod 4).
25
25
  */
26
- export const is_strict_object_schema = (schema) => {
27
- if (schema._zod.def.type !== 'object')
28
- return false;
29
- const catchall = schema._zod.def.catchall;
30
- return catchall?._zod.def.type === 'never';
31
- };
26
+ export const is_strict_object_schema = (schema) => schema instanceof z.ZodObject && schema.def.catchall instanceof z.ZodNever;
32
27
  /**
33
28
  * Convert a Zod schema to a JSON-serializable representation for the surface.
34
29
  *
@@ -11,6 +11,7 @@ import type { SseEventSpec } from '../realtime/sse.js';
11
11
  import type { MiddlewareSpec } from './middleware_spec.js';
12
12
  import type { RouteAuth, RouteSpec } from './route_spec.js';
13
13
  import type { RateLimitKey, RouteErrorSchemas } from './error_schemas.js';
14
+ import type { RpcAction } from '../actions/action_rpc.js';
14
15
  import type { Sensitivity } from '../sensitivity.js';
15
16
  /** A route in the generated attack surface (JSON-serializable). */
16
17
  export interface AppSurfaceRoute {
@@ -59,6 +60,22 @@ export interface AppSurfaceEvent {
59
60
  channel: string | null;
60
61
  params_schema: unknown;
61
62
  }
63
+ /** A method within an RPC endpoint in the generated attack surface (JSON-serializable). */
64
+ export interface AppSurfaceRpcMethod {
65
+ name: string;
66
+ auth: RouteAuth;
67
+ /** JSON Schema representation of the input schema. `null` for null-input methods. */
68
+ input_schema: unknown;
69
+ /** JSON Schema representation of the output schema. */
70
+ output_schema: unknown;
71
+ side_effects: boolean;
72
+ description: string;
73
+ }
74
+ /** An RPC endpoint in the generated attack surface (JSON-serializable). */
75
+ export interface AppSurfaceRpcEndpoint {
76
+ path: string;
77
+ methods: Array<AppSurfaceRpcMethod>;
78
+ }
62
79
  /** Assembly-time diagnostic collected during surface generation or server assembly. */
63
80
  export interface AppSurfaceDiagnostic {
64
81
  level: 'warning' | 'info';
@@ -70,6 +87,7 @@ export interface AppSurfaceDiagnostic {
70
87
  export interface AppSurface {
71
88
  middleware: Array<AppSurfaceMiddleware>;
72
89
  routes: Array<AppSurfaceRoute>;
90
+ rpc_endpoints: Array<AppSurfaceRpcEndpoint>;
73
91
  env: Array<AppSurfaceEnv>;
74
92
  events: Array<AppSurfaceEvent>;
75
93
  diagnostics: Array<AppSurfaceDiagnostic>;
@@ -84,6 +102,12 @@ export interface AppSurfaceSpec {
84
102
  surface: AppSurface;
85
103
  route_specs: Array<RouteSpec>;
86
104
  middleware_specs: Array<MiddlewareSpec>;
105
+ rpc_endpoints: Array<RpcEndpointSpec>;
106
+ }
107
+ /** An RPC endpoint definition for surface generation. */
108
+ export interface RpcEndpointSpec {
109
+ path: string;
110
+ actions: Array<RpcAction>;
87
111
  }
88
112
  /** Options for `generate_app_surface`. */
89
113
  export interface GenerateAppSurfaceOptions {
@@ -91,6 +115,7 @@ export interface GenerateAppSurfaceOptions {
91
115
  middleware_specs: Array<MiddlewareSpec>;
92
116
  env_schema?: z.ZodObject;
93
117
  event_specs?: Array<SseEventSpec>;
118
+ rpc_endpoints?: Array<RpcEndpointSpec>;
94
119
  }
95
120
  /**
96
121
  * Collect error schemas from all middleware that applies to a route path.
@@ -1 +1 @@
1
- {"version":3,"file":"surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/surface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/surface.ts"],"names":[],"mappings":"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"}