@fuzdev/fuz_app 0.147.0 → 0.148.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 (273) hide show
  1. package/dist/actions/CLAUDE.md +6 -4
  2. package/dist/actions/action_codegen.d.ts +15 -1
  3. package/dist/actions/action_codegen.d.ts.map +1 -1
  4. package/dist/actions/action_codegen.js +23 -2
  5. package/dist/actions/perform_action.js +1 -1
  6. package/dist/auth/cell_action_specs.d.ts +3 -1
  7. package/dist/auth/cell_action_specs.d.ts.map +1 -1
  8. package/dist/auth/cell_action_specs.js +5 -5
  9. package/dist/auth/cell_actions.d.ts.map +1 -1
  10. package/dist/auth/cell_actions.js +2 -3
  11. package/dist/auth/cell_data_schema.d.ts +1 -1
  12. package/dist/auth/cell_data_schema.js +1 -1
  13. package/dist/auth/cell_field_action_specs.d.ts +4 -3
  14. package/dist/auth/cell_field_action_specs.d.ts.map +1 -1
  15. package/dist/auth/cell_field_action_specs.js +5 -6
  16. package/dist/auth/cell_field_actions.d.ts.map +1 -1
  17. package/dist/auth/cell_field_actions.js +8 -1
  18. package/dist/auth/cell_item_action_specs.d.ts +4 -2
  19. package/dist/auth/cell_item_action_specs.d.ts.map +1 -1
  20. package/dist/auth/cell_item_action_specs.js +5 -5
  21. package/dist/auth/cell_item_actions.d.ts.map +1 -1
  22. package/dist/auth/cell_item_actions.js +8 -1
  23. package/dist/auth/role_grant_offer_action_specs.d.ts +2 -0
  24. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -1
  25. package/dist/auth/role_grant_offer_action_specs.js +3 -1
  26. package/dist/primitive_schemas.d.ts +1 -1
  27. package/dist/primitive_schemas.d.ts.map +1 -1
  28. package/dist/primitive_schemas.js +2 -1
  29. package/dist/schema_meta.d.ts +20 -0
  30. package/dist/schema_meta.d.ts.map +1 -1
  31. package/dist/schema_meta.js +7 -1
  32. package/dist/testing/CLAUDE.md +720 -114
  33. package/dist/testing/admin_integration.d.ts.map +1 -1
  34. package/dist/testing/admin_integration.js +73 -5
  35. package/dist/testing/adversarial_input.d.ts +0 -47
  36. package/dist/testing/adversarial_input.d.ts.map +1 -1
  37. package/dist/testing/adversarial_input.js +4 -340
  38. package/dist/testing/adversarial_input_cases.d.ts +64 -0
  39. package/dist/testing/adversarial_input_cases.d.ts.map +1 -0
  40. package/dist/testing/adversarial_input_cases.js +348 -0
  41. package/dist/testing/audit_completeness.d.ts.map +1 -1
  42. package/dist/testing/audit_completeness.js +24 -20
  43. package/dist/testing/audit_drift_guard.d.ts +27 -1
  44. package/dist/testing/audit_drift_guard.d.ts.map +1 -1
  45. package/dist/testing/audit_drift_guard.js +50 -0
  46. package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
  47. package/dist/testing/cross_backend/account_lifecycle.js +29 -12
  48. package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -1
  49. package/dist/testing/cross_backend/actor_lookup.js +7 -25
  50. package/dist/testing/cross_backend/app_settings.d.ts.map +1 -1
  51. package/dist/testing/cross_backend/app_settings.js +4 -6
  52. package/dist/testing/cross_backend/audit_cross_helpers.d.ts +51 -0
  53. package/dist/testing/cross_backend/audit_cross_helpers.d.ts.map +1 -0
  54. package/dist/testing/cross_backend/audit_cross_helpers.js +78 -0
  55. package/dist/testing/cross_backend/backend_config.d.ts +2 -1
  56. package/dist/testing/cross_backend/backend_config.d.ts.map +1 -1
  57. package/dist/testing/cross_backend/body_size.d.ts +6 -0
  58. package/dist/testing/cross_backend/body_size.d.ts.map +1 -1
  59. package/dist/testing/cross_backend/body_size.js +26 -44
  60. package/dist/testing/cross_backend/body_size_smuggling.d.ts +5 -0
  61. package/dist/testing/cross_backend/body_size_smuggling.d.ts.map +1 -1
  62. package/dist/testing/cross_backend/body_size_smuggling.js +7 -14
  63. package/dist/testing/cross_backend/build_test_backend_paths.d.ts +3 -1
  64. package/dist/testing/cross_backend/build_test_backend_paths.d.ts.map +1 -1
  65. package/dist/testing/cross_backend/capabilities.d.ts +55 -59
  66. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
  67. package/dist/testing/cross_backend/capabilities.js +20 -23
  68. package/dist/testing/cross_backend/cargo_binary.d.ts +70 -0
  69. package/dist/testing/cross_backend/cargo_binary.d.ts.map +1 -0
  70. package/dist/testing/cross_backend/cargo_binary.js +148 -0
  71. package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
  72. package/dist/testing/cross_backend/cell_crud.js +57 -1
  73. package/dist/testing/cross_backend/cell_gated_create.d.ts +0 -60
  74. package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
  75. package/dist/testing/cross_backend/cell_gated_create.js +9 -487
  76. package/dist/testing/cross_backend/cell_grant_role.d.ts +14 -2
  77. package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -1
  78. package/dist/testing/cross_backend/cell_grant_role.js +22 -12
  79. package/dist/testing/cross_backend/cell_moderate.d.ts +66 -0
  80. package/dist/testing/cross_backend/cell_moderate.d.ts.map +1 -0
  81. package/dist/testing/cross_backend/cell_moderate.js +511 -0
  82. package/dist/testing/cross_backend/cell_ref_admission.d.ts.map +1 -1
  83. package/dist/testing/cross_backend/cell_ref_admission.js +1 -1
  84. package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
  85. package/dist/testing/cross_backend/cell_relations.js +40 -19
  86. package/dist/testing/cross_backend/conformance_case.d.ts +43 -4
  87. package/dist/testing/cross_backend/conformance_case.d.ts.map +1 -1
  88. package/dist/testing/cross_backend/conformance_case.js +29 -1
  89. package/dist/testing/cross_backend/conformance_rpc_auth.d.ts +93 -0
  90. package/dist/testing/cross_backend/conformance_rpc_auth.d.ts.map +1 -0
  91. package/dist/testing/cross_backend/conformance_rpc_auth.js +125 -0
  92. package/dist/testing/cross_backend/conformance_table.d.ts +144 -4
  93. package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
  94. package/dist/testing/cross_backend/conformance_table.js +297 -65
  95. package/dist/testing/cross_backend/cookie_attributes.d.ts.map +1 -1
  96. package/dist/testing/cross_backend/cookie_attributes.js +3 -2
  97. package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts +38 -5
  98. package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts.map +1 -1
  99. package/dist/testing/cross_backend/create_cross_backend_global_setup.js +24 -3
  100. package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts +5 -5
  101. package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts.map +1 -1
  102. package/dist/testing/cross_backend/credential_deadline.d.ts +10 -6
  103. package/dist/testing/cross_backend/credential_deadline.d.ts.map +1 -1
  104. package/dist/testing/cross_backend/credential_deadline.js +32 -31
  105. package/dist/testing/cross_backend/credential_header_robustness.d.ts.map +1 -1
  106. package/dist/testing/cross_backend/credential_header_robustness.js +4 -6
  107. package/dist/testing/cross_backend/{cell_cross_helpers.d.ts → cross_rpc.d.ts} +12 -2
  108. package/dist/testing/cross_backend/cross_rpc.d.ts.map +1 -0
  109. package/dist/testing/cross_backend/{cell_cross_helpers.js → cross_rpc.js} +31 -7
  110. package/dist/testing/cross_backend/default_backend_configs.d.ts +56 -61
  111. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
  112. package/dist/testing/cross_backend/default_backend_configs.js +97 -91
  113. package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
  114. package/dist/testing/cross_backend/default_spine_surface.js +2 -2
  115. package/dist/testing/cross_backend/differential.d.ts +126 -0
  116. package/dist/testing/cross_backend/differential.d.ts.map +1 -0
  117. package/dist/testing/cross_backend/differential.js +201 -0
  118. package/dist/testing/cross_backend/differential_normalize.d.ts +150 -0
  119. package/dist/testing/cross_backend/differential_normalize.d.ts.map +1 -0
  120. package/dist/testing/cross_backend/differential_normalize.js +153 -0
  121. package/dist/testing/cross_backend/fact_serving.d.ts.map +1 -1
  122. package/dist/testing/cross_backend/fact_serving.js +27 -17
  123. package/dist/testing/cross_backend/full_spine_mount.d.ts +15 -0
  124. package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -1
  125. package/dist/testing/cross_backend/full_spine_mount.js +55 -1
  126. package/dist/testing/cross_backend/identity_parity.d.ts.map +1 -1
  127. package/dist/testing/cross_backend/identity_parity.js +6 -5
  128. package/dist/testing/cross_backend/in_process_setup.d.ts +12 -2
  129. package/dist/testing/cross_backend/in_process_setup.d.ts.map +1 -1
  130. package/dist/testing/cross_backend/in_process_setup.js +10 -7
  131. package/dist/testing/cross_backend/login_security.d.ts.map +1 -1
  132. package/dist/testing/cross_backend/login_security.js +13 -18
  133. package/dist/testing/cross_backend/origin.js +1 -1
  134. package/dist/testing/cross_backend/origin_conformance.js +1 -1
  135. package/dist/testing/cross_backend/origin_scope.d.ts +6 -0
  136. package/dist/testing/cross_backend/origin_scope.d.ts.map +1 -1
  137. package/dist/testing/cross_backend/origin_scope.js +13 -12
  138. package/dist/testing/cross_backend/peer_ping_ws.d.ts +2 -5
  139. package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
  140. package/dist/testing/cross_backend/peer_ping_ws.js +14 -24
  141. package/dist/testing/cross_backend/postgres_database.d.ts +85 -0
  142. package/dist/testing/cross_backend/postgres_database.d.ts.map +1 -0
  143. package/dist/testing/cross_backend/postgres_database.js +140 -0
  144. package/dist/testing/cross_backend/provided_context.d.ts +28 -0
  145. package/dist/testing/cross_backend/provided_context.d.ts.map +1 -0
  146. package/dist/testing/cross_backend/provided_context.js +35 -0
  147. package/dist/testing/cross_backend/query_shape.d.ts.map +1 -1
  148. package/dist/testing/cross_backend/query_shape.js +10 -12
  149. package/dist/testing/cross_backend/ready.js +2 -2
  150. package/dist/testing/cross_backend/revocation_drivers.d.ts +4 -3
  151. package/dist/testing/cross_backend/revocation_drivers.d.ts.map +1 -1
  152. package/dist/testing/cross_backend/revocation_drivers.js +1 -1
  153. package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts +3 -2
  154. package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts.map +1 -1
  155. package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts +13 -0
  156. package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts.map +1 -0
  157. package/dist/testing/cross_backend/role_grant_offer_lifecycle.js +203 -0
  158. package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts +2 -5
  159. package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts.map +1 -1
  160. package/dist/testing/cross_backend/role_grant_offer_notification_ws.js +203 -111
  161. package/dist/testing/cross_backend/role_grant_participation.d.ts +13 -0
  162. package/dist/testing/cross_backend/role_grant_participation.d.ts.map +1 -1
  163. package/dist/testing/cross_backend/role_grant_participation.js +32 -21
  164. package/dist/testing/cross_backend/role_grant_role_grammar.d.ts.map +1 -1
  165. package/dist/testing/cross_backend/role_grant_role_grammar.js +6 -9
  166. package/dist/testing/cross_backend/rpc_adversarial.d.ts +38 -0
  167. package/dist/testing/cross_backend/rpc_adversarial.d.ts.map +1 -0
  168. package/dist/testing/cross_backend/rpc_adversarial.js +292 -0
  169. package/dist/testing/cross_backend/rpc_success_fixtures.d.ts +24 -0
  170. package/dist/testing/cross_backend/rpc_success_fixtures.d.ts.map +1 -0
  171. package/dist/testing/cross_backend/rpc_success_fixtures.js +124 -0
  172. package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts +101 -0
  173. package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts.map +1 -0
  174. package/dist/testing/cross_backend/rust_spine_consumer_surface.js +113 -0
  175. package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts +10 -0
  176. package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
  177. package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +27 -18
  178. package/dist/testing/cross_backend/session_cap.d.ts +9 -8
  179. package/dist/testing/cross_backend/session_cap.d.ts.map +1 -1
  180. package/dist/testing/cross_backend/session_cap.js +9 -4
  181. package/dist/testing/cross_backend/session_cookie_codec.js +1 -1
  182. package/dist/testing/cross_backend/setup.d.ts +56 -54
  183. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  184. package/dist/testing/cross_backend/setup.js +29 -29
  185. package/dist/testing/cross_backend/simple_request.d.ts.map +1 -1
  186. package/dist/testing/cross_backend/simple_request.js +4 -4
  187. package/dist/testing/cross_backend/spawn_backend.d.ts +59 -10
  188. package/dist/testing/cross_backend/spawn_backend.d.ts.map +1 -1
  189. package/dist/testing/cross_backend/spawn_backend.js +219 -60
  190. package/dist/testing/cross_backend/spine_suites.d.ts +231 -0
  191. package/dist/testing/cross_backend/spine_suites.d.ts.map +1 -0
  192. package/dist/testing/cross_backend/spine_suites.js +626 -0
  193. package/dist/testing/cross_backend/spine_surface_constants.d.ts +29 -0
  194. package/dist/testing/cross_backend/spine_surface_constants.d.ts.map +1 -1
  195. package/dist/testing/cross_backend/spine_surface_constants.js +29 -0
  196. package/dist/testing/cross_backend/sse_round_trip.d.ts.map +1 -1
  197. package/dist/testing/cross_backend/sse_round_trip.js +3 -4
  198. package/dist/testing/cross_backend/standard.d.ts +18 -1
  199. package/dist/testing/cross_backend/standard.d.ts.map +1 -1
  200. package/dist/testing/cross_backend/standard.js +2 -0
  201. package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts +24 -0
  202. package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts.map +1 -1
  203. package/dist/testing/cross_backend/test_cell_gated_create_authorize.js +15 -0
  204. package/dist/testing/cross_backend/testing_backdoor.d.ts +2 -8
  205. package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
  206. package/dist/testing/cross_backend/testing_backdoor.js +7 -10
  207. package/dist/testing/cross_backend/testing_reset_actions.d.ts +3 -2
  208. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
  209. package/dist/testing/cross_backend/testing_reset_actions.js +8 -4
  210. package/dist/testing/cross_backend/testing_server_bun.js +1 -1
  211. package/dist/testing/cross_backend/token_lifetime.js +1 -1
  212. package/dist/testing/cross_backend/token_scope_surface.d.ts.map +1 -1
  213. package/dist/testing/cross_backend/token_scope_surface.js +9 -13
  214. package/dist/testing/cross_backend/transport_composition.d.ts +26 -2
  215. package/dist/testing/cross_backend/transport_composition.d.ts.map +1 -1
  216. package/dist/testing/cross_backend/transport_composition.js +81 -51
  217. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts +8 -0
  218. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
  219. package/dist/testing/cross_backend/ts_spine_backend_config.js +17 -10
  220. package/dist/testing/cross_backend/ws_action_rate_limit.d.ts +2 -5
  221. package/dist/testing/cross_backend/ws_action_rate_limit.d.ts.map +1 -1
  222. package/dist/testing/cross_backend/ws_action_rate_limit.js +8 -14
  223. package/dist/testing/cross_backend/ws_connection_cap.d.ts +4 -9
  224. package/dist/testing/cross_backend/ws_connection_cap.d.ts.map +1 -1
  225. package/dist/testing/cross_backend/ws_connection_cap.js +11 -12
  226. package/dist/testing/cross_backend/ws_endpoint.d.ts +52 -0
  227. package/dist/testing/cross_backend/ws_endpoint.d.ts.map +1 -0
  228. package/dist/testing/cross_backend/ws_endpoint.js +54 -0
  229. package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts +2 -5
  230. package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts.map +1 -1
  231. package/dist/testing/cross_backend/ws_inbound_dispatch.js +9 -15
  232. package/dist/testing/cross_backend/ws_outbound_overflow.d.ts +2 -7
  233. package/dist/testing/cross_backend/ws_outbound_overflow.d.ts.map +1 -1
  234. package/dist/testing/cross_backend/ws_outbound_overflow.js +5 -9
  235. package/dist/testing/cross_backend/ws_role_gated.d.ts +4 -5
  236. package/dist/testing/cross_backend/ws_role_gated.d.ts.map +1 -1
  237. package/dist/testing/cross_backend/ws_role_gated.js +12 -21
  238. package/dist/testing/cross_backend/ws_round_trip.d.ts +12 -9
  239. package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
  240. package/dist/testing/cross_backend/ws_round_trip.js +29 -34
  241. package/dist/testing/db_entities.d.ts +16 -3
  242. package/dist/testing/db_entities.d.ts.map +1 -1
  243. package/dist/testing/db_entities.js +28 -5
  244. package/dist/testing/integration_helpers.d.ts +61 -2
  245. package/dist/testing/integration_helpers.d.ts.map +1 -1
  246. package/dist/testing/integration_helpers.js +75 -18
  247. package/dist/testing/round_trip.d.ts +17 -0
  248. package/dist/testing/round_trip.d.ts.map +1 -1
  249. package/dist/testing/round_trip.js +67 -24
  250. package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
  251. package/dist/testing/rpc_attack_surface.js +13 -138
  252. package/dist/testing/rpc_envelope_cases.d.ts +111 -0
  253. package/dist/testing/rpc_envelope_cases.d.ts.map +1 -0
  254. package/dist/testing/rpc_envelope_cases.js +240 -0
  255. package/dist/testing/rpc_helpers.d.ts +31 -0
  256. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  257. package/dist/testing/rpc_helpers.js +35 -14
  258. package/dist/testing/rpc_round_trip.d.ts +62 -6
  259. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  260. package/dist/testing/rpc_round_trip.js +151 -39
  261. package/dist/testing/schema_generators.d.ts.map +1 -1
  262. package/dist/testing/schema_generators.js +22 -2
  263. package/dist/testing/standard.d.ts +26 -0
  264. package/dist/testing/standard.d.ts.map +1 -1
  265. package/dist/testing/standard.js +4 -1
  266. package/dist/testing/transports/raw_http.d.ts +21 -0
  267. package/dist/testing/transports/raw_http.d.ts.map +1 -1
  268. package/dist/testing/transports/raw_http.js +30 -0
  269. package/package.json +6 -4
  270. package/dist/testing/cross_backend/actor_search.d.ts +0 -6
  271. package/dist/testing/cross_backend/actor_search.d.ts.map +0 -1
  272. package/dist/testing/cross_backend/actor_search.js +0 -90
  273. package/dist/testing/cross_backend/cell_cross_helpers.d.ts.map +0 -1
@@ -0,0 +1,111 @@
1
+ import './assert_dev_env.js';
2
+ import type { z } from 'zod';
3
+ import type { AppSurfaceRpcEndpoint, AppSurfaceRpcMethod } from '../http/surface.js';
4
+ import type { JsonrpcErrorCode, JsonrpcRequestId } from '../http/jsonrpc.js';
5
+ import { type InputTestCase } from './adversarial_input_cases.js';
6
+ /** The request id every envelope case sends where it sends one. */
7
+ export declare const RPC_ENVELOPE_PROBE_ID = "envelope_probe";
8
+ /**
9
+ * One malformed-envelope request and the refusal it owes.
10
+ *
11
+ * Data, so the in-process group here and the cross-process
12
+ * `describe_rpc_adversarial_cross_tests` run the same set.
13
+ */
14
+ export interface RpcEnvelopeCase {
15
+ readonly name: string;
16
+ /**
17
+ * Who sends it: the principal `method`'s auth admits, so the envelope check
18
+ * is what refuses, or no credential at all — the ordering cases, where an
19
+ * answer of 401 would mean auth ran before the envelope check.
20
+ */
21
+ readonly as: 'authorized' | 'anonymous';
22
+ /** The declared method whose auth picks the principal (`'authorized'`). */
23
+ readonly method: AppSurfaceRpcMethod;
24
+ /** A raw POST body, or a GET query string starting with `?`. */
25
+ readonly request: {
26
+ readonly verb: 'POST';
27
+ readonly body: string;
28
+ } | {
29
+ readonly verb: 'GET';
30
+ readonly query: string;
31
+ };
32
+ readonly expect: {
33
+ readonly status: number;
34
+ readonly code: JsonrpcErrorCode;
35
+ /** The echoed `id` — `null` where the request carries none the server can read. */
36
+ readonly id: JsonrpcRequestId | null;
37
+ /** `error.data.reason` exactly, or `null` to require it absent. */
38
+ readonly reason: string | null;
39
+ };
40
+ }
41
+ /** Options for `create_rpc_envelope_cases`. */
42
+ export interface RpcEnvelopeCaseOptions {
43
+ /** Method names never chosen as a case's method. */
44
+ readonly skip_methods?: ReadonlyArray<string>;
45
+ }
46
+ /**
47
+ * The JSON values that are neither an object nor `null`, one per JSON type —
48
+ * what a `GET` `?params=` can carry that no input schema admits.
49
+ */
50
+ export declare const RPC_NON_OBJECT_PARAMS: ReadonlyArray<string>;
51
+ /** The `data.reason` the dispatchers answer a `GET` of a `side_effects` method with. */
52
+ export declare const rpc_get_side_effects_reason: (method: string) => string;
53
+ /**
54
+ * Build the malformed-envelope cases for one RPC endpoint — the dispatcher's
55
+ * envelope parse, method lookup, and GET read restriction.
56
+ *
57
+ * The POST cases and the GET read cases ride the endpoint's first read method
58
+ * (`side_effects: false`), the GET mutation cases its first mutation that
59
+ * needs an account. `_testing_*` and protocol methods are never chosen. A case
60
+ * whose method the endpoint lacks is left out.
61
+ *
62
+ * Every read (`side_effects: false`) gets a `GET` with each of
63
+ * `RPC_NON_OBJECT_PARAMS` → `invalid_params`: the query string is no envelope,
64
+ * so the dispatcher's params validation is what refuses it.
65
+ *
66
+ * Three cases pin an order against auth, sent with no credential: a `GET` of
67
+ * a mutating method is refused `invalid_request` (the read restriction runs
68
+ * after the method lookup and before authorization), a batch array is
69
+ * refused `invalid_request` with `id: null` (the envelope parse runs first,
70
+ * and batches are unsupported), and a `GET` with non-object params on a
71
+ * read requiring an identity is the 401 (params validation runs after authorization).
72
+ *
73
+ * @param endpoint - the endpoint from the generated surface
74
+ * @param options - methods never chosen
75
+ * @returns the cases, in a fixed order
76
+ */
77
+ export declare const create_rpc_envelope_cases: (endpoint: AppSurfaceRpcEndpoint, options?: RpcEnvelopeCaseOptions) => Array<RpcEnvelopeCase>;
78
+ /**
79
+ * Build the `RequestInit` + path suffix for an envelope case.
80
+ *
81
+ * @param endpoint_path - the RPC endpoint path
82
+ * @param c - the case
83
+ * @param headers - auth headers to merge in
84
+ * @returns the URL (path + query for GET) and the init
85
+ */
86
+ export declare const to_rpc_envelope_request: (endpoint_path: string, c: RpcEnvelopeCase, headers?: Record<string, string>) => {
87
+ url: string;
88
+ init: RequestInit;
89
+ };
90
+ /**
91
+ * Assert a response body is the refusal an envelope case owes: a well-formed
92
+ * JSON-RPC error envelope with the case's code, echoed id, and `data.reason`.
93
+ *
94
+ * @param status - the response's HTTP status
95
+ * @param body - the parsed response body
96
+ * @param c - the case
97
+ */
98
+ export declare const assert_rpc_envelope_refusal: (status: number, body: unknown, c: RpcEnvelopeCase) => void;
99
+ /**
100
+ * Generate the schema-invalid params cases for one RPC method's input.
101
+ *
102
+ * `generate_input_test_cases` minus its structural cases: a non-object body
103
+ * is a non-object `params`, which the JSON-RPC envelope refuses
104
+ * (`invalid_request`) before params validation runs, and the envelope cases
105
+ * cover it. Every case returned owes 400 `invalid_params`.
106
+ *
107
+ * @param input - the method's input schema
108
+ * @returns the cases, each a `params` object
109
+ */
110
+ export declare const generate_rpc_params_test_cases: (input: z.ZodType) => Array<InputTestCase>;
111
+ //# sourceMappingURL=rpc_envelope_cases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc_envelope_cases.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_envelope_cases.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAe7B,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGrF,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAK7E,OAAO,EAA6B,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAI7F,mEAAmE;AACnE,eAAO,MAAM,qBAAqB,mBAAmB,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,YAAY,GAAG,WAAW,CAAC;IACxC,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,gEAAgE;IAChE,QAAQ,CAAC,OAAO,EACb;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAChD;QAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;QAChC,mFAAmF;QACnF,QAAQ,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI,CAAC;QACrC,mEAAmE;QACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B,CAAC;CACF;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACtC,oDAAoD;IACpD,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,MAAM,CAAgC,CAAC;AAEzF,wFAAwF;AACxF,eAAO,MAAM,2BAA2B,GAAI,QAAQ,MAAM,KAAG,MACL,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,yBAAyB,GACrC,UAAU,qBAAqB,EAC/B,UAAS,sBAA2B,KAClC,KAAK,CAAC,eAAe,CAmKvB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GACnC,eAAe,MAAM,EACrB,GAAG,eAAe,EAClB,UAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,KAClC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAUgD,CAAC;AAEpF;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GACvC,QAAQ,MAAM,EACd,MAAM,OAAO,EACb,GAAG,eAAe,KAChB,IAUF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,GAAI,OAAO,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,aAAa,CACU,CAAC"}
@@ -0,0 +1,240 @@
1
+ import './assert_dev_env.js';
2
+ /**
3
+ * The malformed-envelope and invalid-params cases for a JSON-RPC endpoint, as
4
+ * data.
5
+ *
6
+ * Hono-free, so the in-process `describe_rpc_attack_surface_tests` and the
7
+ * cross-process `describe_rpc_adversarial_cross_tests` run one set: the
8
+ * envelope cases (`create_rpc_envelope_cases`) and the per-method params
9
+ * cases (`generate_rpc_params_test_cases`).
10
+ *
11
+ * @module
12
+ */
13
+ import { assert } from 'vitest';
14
+ import { is_public_auth } from '../http/auth_shape.js';
15
+ import { JSONRPC_ERROR_CODES } from '../http/jsonrpc_errors.js';
16
+ import { ERROR_AUTHENTICATION_REQUIRED, ERROR_INVALID_JSON_BODY } from '../http/error_schemas.js';
17
+ import { PROTOCOL_ACTION_METHODS } from '../actions/action_codegen.js';
18
+ import { TESTING_METHOD_PREFIX } from './surface_invariants.js';
19
+ import { assert_jsonrpc_error_response } from './rpc_helpers.js';
20
+ import { generate_input_test_cases } from './adversarial_input_cases.js';
21
+ const PROTOCOL_METHODS = new Set(PROTOCOL_ACTION_METHODS);
22
+ /** The request id every envelope case sends where it sends one. */
23
+ export const RPC_ENVELOPE_PROBE_ID = 'envelope_probe';
24
+ /**
25
+ * The JSON values that are neither an object nor `null`, one per JSON type —
26
+ * what a `GET` `?params=` can carry that no input schema admits.
27
+ */
28
+ export const RPC_NON_OBJECT_PARAMS = ['42', '[1]', '"x"', 'true'];
29
+ /** The `data.reason` the dispatchers answer a `GET` of a `side_effects` method with. */
30
+ export const rpc_get_side_effects_reason = (method) => `method '${method}' has side effects and must use POST`;
31
+ /**
32
+ * Build the malformed-envelope cases for one RPC endpoint — the dispatcher's
33
+ * envelope parse, method lookup, and GET read restriction.
34
+ *
35
+ * The POST cases and the GET read cases ride the endpoint's first read method
36
+ * (`side_effects: false`), the GET mutation cases its first mutation that
37
+ * needs an account. `_testing_*` and protocol methods are never chosen. A case
38
+ * whose method the endpoint lacks is left out.
39
+ *
40
+ * Every read (`side_effects: false`) gets a `GET` with each of
41
+ * `RPC_NON_OBJECT_PARAMS` → `invalid_params`: the query string is no envelope,
42
+ * so the dispatcher's params validation is what refuses it.
43
+ *
44
+ * Three cases pin an order against auth, sent with no credential: a `GET` of
45
+ * a mutating method is refused `invalid_request` (the read restriction runs
46
+ * after the method lookup and before authorization), a batch array is
47
+ * refused `invalid_request` with `id: null` (the envelope parse runs first,
48
+ * and batches are unsupported), and a `GET` with non-object params on a
49
+ * read requiring an identity is the 401 (params validation runs after authorization).
50
+ *
51
+ * @param endpoint - the endpoint from the generated surface
52
+ * @param options - methods never chosen
53
+ * @returns the cases, in a fixed order
54
+ */
55
+ export const create_rpc_envelope_cases = (endpoint, options = {}) => {
56
+ const skip = new Set(options.skip_methods);
57
+ const eligible = endpoint.methods.filter((m) => !m.name.startsWith(TESTING_METHOD_PREFIX) &&
58
+ !PROTOCOL_METHODS.has(m.name) &&
59
+ !skip.has(m.name));
60
+ const read = eligible.find((m) => !m.side_effects);
61
+ const mutation = eligible.find((m) => m.side_effects && !is_public_auth(m.auth));
62
+ const id = RPC_ENVELOPE_PROBE_ID;
63
+ const cases = [];
64
+ if (read) {
65
+ const post = (name, body, expect) => {
66
+ cases.push({ name, as: 'authorized', method: read, request: { verb: 'POST', body }, expect });
67
+ };
68
+ const get = (name, query, expect) => {
69
+ cases.push({ name, as: 'authorized', method: read, request: { verb: 'GET', query }, expect });
70
+ };
71
+ const invalid_request = { status: 400, code: JSONRPC_ERROR_CODES.invalid_request };
72
+ const m = read.name;
73
+ const q = encodeURIComponent;
74
+ post('non-JSON body → parse_error', 'not-json', {
75
+ status: 400,
76
+ code: JSONRPC_ERROR_CODES.parse_error,
77
+ id: null,
78
+ reason: null
79
+ });
80
+ post('wrong jsonrpc version → invalid_request', JSON.stringify({ jsonrpc: '1.0', id, method: m }), { ...invalid_request, id, reason: null });
81
+ post('missing jsonrpc field → invalid_request', JSON.stringify({ id, method: m }), {
82
+ ...invalid_request,
83
+ id,
84
+ reason: null
85
+ });
86
+ post('missing method field → invalid_request', JSON.stringify({ jsonrpc: '2.0', id }), {
87
+ ...invalid_request,
88
+ id,
89
+ reason: null
90
+ });
91
+ post('missing id field → invalid_request', JSON.stringify({ jsonrpc: '2.0', method: m }), {
92
+ ...invalid_request,
93
+ id: null,
94
+ reason: null
95
+ });
96
+ post('batch (array) body → invalid_request', JSON.stringify([{ jsonrpc: '2.0', id, method: m }]), { ...invalid_request, id: null, reason: null });
97
+ post('unknown method name → method_not_found', JSON.stringify({ jsonrpc: '2.0', id, method: '__nonexistent_method__' }), { status: 404, code: JSONRPC_ERROR_CODES.method_not_found, id, reason: null });
98
+ get('GET missing method → invalid_request', `?id=${id}`, {
99
+ ...invalid_request,
100
+ id: null,
101
+ reason: 'missing method query parameter'
102
+ });
103
+ get('GET missing id → invalid_request', `?method=${q(m)}`, {
104
+ ...invalid_request,
105
+ id: null,
106
+ reason: 'missing id query parameter'
107
+ });
108
+ get('GET invalid JSON params → invalid_params', `?method=${q(m)}&id=${id}&params=not-json`, {
109
+ status: 400,
110
+ code: JSONRPC_ERROR_CODES.invalid_params,
111
+ id,
112
+ reason: null
113
+ });
114
+ // a present non-object `params` fails the envelope schema on POST
115
+ post('POST non-object params → invalid_request', JSON.stringify({ jsonrpc: '2.0', id, method: m, params: 42 }), { ...invalid_request, id, reason: null });
116
+ }
117
+ // The GET query string is no envelope, so a non-object `params` reaches the
118
+ // dispatcher's params validation — on every read, since a spine that decodes
119
+ // params per handler can drift on any of them.
120
+ for (const r of eligible) {
121
+ if (r.side_effects)
122
+ continue;
123
+ for (const value of RPC_NON_OBJECT_PARAMS) {
124
+ cases.push({
125
+ name: `GET non-object params (${value}) → invalid_params: ${r.name}`,
126
+ as: 'authorized',
127
+ method: r,
128
+ request: {
129
+ verb: 'GET',
130
+ query: `?method=${encodeURIComponent(r.name)}&id=${id}&params=${encodeURIComponent(value)}`
131
+ },
132
+ expect: { status: 400, code: JSONRPC_ERROR_CODES.invalid_params, id, reason: null }
133
+ });
134
+ }
135
+ }
136
+ // params validation runs after authorization: an anonymous non-object
137
+ // `params` hears the 401 of any anonymous call, not a 400 about its input.
138
+ // The read must require an identity — an identity-optional one admits the
139
+ // anonymous caller, whose params validation then refuses
140
+ const protected_read = eligible.find((r) => !r.side_effects && (r.auth.account === 'required' || r.auth.actor === 'required'));
141
+ if (protected_read) {
142
+ cases.push({
143
+ name: 'ordering: anonymous GET non-object params → 401, not invalid_params',
144
+ as: 'anonymous',
145
+ method: protected_read,
146
+ request: {
147
+ verb: 'GET',
148
+ query: `?method=${encodeURIComponent(protected_read.name)}&id=${id}&params=42`
149
+ },
150
+ expect: {
151
+ status: 401,
152
+ code: JSONRPC_ERROR_CODES.unauthenticated,
153
+ id,
154
+ reason: ERROR_AUTHENTICATION_REQUIRED
155
+ }
156
+ });
157
+ }
158
+ if (mutation) {
159
+ const query = `?method=${encodeURIComponent(mutation.name)}&id=${id}`;
160
+ const expect = {
161
+ status: 400,
162
+ code: JSONRPC_ERROR_CODES.invalid_request,
163
+ id,
164
+ reason: rpc_get_side_effects_reason(mutation.name)
165
+ };
166
+ cases.push({
167
+ name: 'GET mutation method → invalid_request (side effects)',
168
+ as: 'authorized',
169
+ method: mutation,
170
+ request: { verb: 'GET', query },
171
+ expect
172
+ });
173
+ cases.push({
174
+ name: 'ordering: anonymous GET mutation method → invalid_request, not 401',
175
+ as: 'anonymous',
176
+ method: mutation,
177
+ request: { verb: 'GET', query },
178
+ expect
179
+ });
180
+ cases.push({
181
+ name: 'ordering: anonymous batch (array) body → invalid_request, not 401',
182
+ as: 'anonymous',
183
+ method: mutation,
184
+ request: {
185
+ verb: 'POST',
186
+ body: JSON.stringify([{ jsonrpc: '2.0', id, method: mutation.name }])
187
+ },
188
+ expect: { status: 400, code: JSONRPC_ERROR_CODES.invalid_request, id: null, reason: null }
189
+ });
190
+ }
191
+ return cases;
192
+ };
193
+ /**
194
+ * Build the `RequestInit` + path suffix for an envelope case.
195
+ *
196
+ * @param endpoint_path - the RPC endpoint path
197
+ * @param c - the case
198
+ * @param headers - auth headers to merge in
199
+ * @returns the URL (path + query for GET) and the init
200
+ */
201
+ export const to_rpc_envelope_request = (endpoint_path, c, headers = {}) => c.request.verb === 'POST'
202
+ ? {
203
+ url: endpoint_path,
204
+ init: {
205
+ method: 'POST',
206
+ headers: { 'Content-Type': 'application/json', ...headers },
207
+ body: c.request.body
208
+ }
209
+ }
210
+ : { url: `${endpoint_path}${c.request.query}`, init: { method: 'GET', headers } };
211
+ /**
212
+ * Assert a response body is the refusal an envelope case owes: a well-formed
213
+ * JSON-RPC error envelope with the case's code, echoed id, and `data.reason`.
214
+ *
215
+ * @param status - the response's HTTP status
216
+ * @param body - the parsed response body
217
+ * @param c - the case
218
+ */
219
+ export const assert_rpc_envelope_refusal = (status, body, c) => {
220
+ const detail = `${c.name}: got ${status} ${JSON.stringify(body)}`;
221
+ assert.strictEqual(status, c.expect.status, detail);
222
+ assert_jsonrpc_error_response(body, c.expect.code);
223
+ const envelope = body;
224
+ assert.strictEqual(envelope.id, c.expect.id, `${detail} — echoed id`);
225
+ const data = envelope.error.data;
226
+ const reason = typeof data === 'object' && data !== null ? data.reason : undefined;
227
+ assert.strictEqual(reason ?? null, c.expect.reason, `${detail} — data.reason`);
228
+ };
229
+ /**
230
+ * Generate the schema-invalid params cases for one RPC method's input.
231
+ *
232
+ * `generate_input_test_cases` minus its structural cases: a non-object body
233
+ * is a non-object `params`, which the JSON-RPC envelope refuses
234
+ * (`invalid_request`) before params validation runs, and the envelope cases
235
+ * cover it. Every case returned owes 400 `invalid_params`.
236
+ *
237
+ * @param input - the method's input schema
238
+ * @returns the cases, each a `params` object
239
+ */
240
+ export const generate_rpc_params_test_cases = (input) => generate_input_test_cases(input).filter((tc) => tc.expected_error !== ERROR_INVALID_JSON_BODY);
@@ -156,6 +156,37 @@ export interface RpcCallArgs {
156
156
  */
157
157
  suppress_default_origin?: boolean;
158
158
  }
159
+ /**
160
+ * The unparsed response `rpc_call_raw` returns: the HTTP status, the
161
+ * response-headers snapshot (lowercased keys), and the JSON body exactly as
162
+ * the server sent it — the whole envelope, `jsonrpc` and `id` included.
163
+ */
164
+ export interface RpcCallRawResult {
165
+ status: number;
166
+ headers: Record<string, string>;
167
+ body: unknown;
168
+ }
169
+ /**
170
+ * Send one JSON-RPC request the way `rpc_call` does — same defaults, verbs
171
+ * and header merging — and return the response unparsed.
172
+ *
173
+ * For callers that compare whole bodies (the cross-backend differential),
174
+ * where `rpc_call`'s envelope parse would hide anything outside `result` /
175
+ * `error`.
176
+ *
177
+ * @throws Error if the response body is not JSON
178
+ */
179
+ export declare const rpc_call_raw: (args: RpcCallArgs) => Promise<RpcCallRawResult>;
180
+ /**
181
+ * Parse a raw JSON-RPC response into `rpc_call`'s discriminated result.
182
+ *
183
+ * @param raw - the response `rpc_call_raw` returned
184
+ * @param method - the method called, for the error message
185
+ * @returns the success or error branch
186
+ * @throws Error if the body is neither a valid `JsonrpcResponse` nor
187
+ * `JsonrpcErrorResponse` envelope
188
+ */
189
+ export declare const parse_rpc_call_result: (raw: RpcCallRawResult, method: string) => RpcCallResult;
159
190
  /**
160
191
  * One-shot JSON-RPC call over a Hono app.
161
192
  *
@@ -1 +1 @@
1
- {"version":3,"file":"rpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_helpers.ts"],"names":[],"mappings":"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"}
@@ -169,18 +169,16 @@ const RPC_CALL_DEFAULT_HEADERS = {
169
169
  origin: 'http://localhost:5173'
170
170
  };
171
171
  /**
172
- * One-shot JSON-RPC call over a Hono app.
172
+ * Send one JSON-RPC request the way `rpc_call` does — same defaults, verbs
173
+ * and header merging — and return the response unparsed.
173
174
  *
174
- * Merges sensible defaults (`host`, `origin`, `Content-Type`) under
175
- * caller-provided headers, fires POST (default) or GET, parses the envelope,
176
- * and returns a discriminated result.
175
+ * For callers that compare whole bodies (the cross-backend differential),
176
+ * where `rpc_call`'s envelope parse would hide anything outside `result` /
177
+ * `error`.
177
178
  *
178
- * @throws Error if the response body is neither a valid `JsonrpcResponse`
179
- * nor `JsonrpcErrorResponse` envelope — protocol-level failures the caller
180
- * should never tolerate. All JSON-RPC errors come back via `{ok: false, error}`
181
- * so assertions can focus on `error.code` / `error.data.reason`.
179
+ * @throws Error if the response body is not JSON
182
180
  */
183
- export const rpc_call = async (args) => {
181
+ export const rpc_call_raw = async (args) => {
184
182
  const { app, path, method, params, headers, id = 'test', verb = 'POST', suppress_default_origin } = args;
185
183
  const defaults = suppress_default_origin
186
184
  ? RPC_CALL_DEFAULT_HEADERS_BASE
@@ -201,19 +199,29 @@ export const rpc_call = async (args) => {
201
199
  };
202
200
  }
203
201
  const res = await (typeof app === 'function' ? app(url, init) : app.request(url, init));
204
- const status = res.status;
205
- const response_headers = headers_to_record(res.headers);
206
- const body = await res.json();
202
+ return { status: res.status, headers: headers_to_record(res.headers), body: await res.json() };
203
+ };
204
+ /**
205
+ * Parse a raw JSON-RPC response into `rpc_call`'s discriminated result.
206
+ *
207
+ * @param raw - the response `rpc_call_raw` returned
208
+ * @param method - the method called, for the error message
209
+ * @returns the success or error branch
210
+ * @throws Error if the body is neither a valid `JsonrpcResponse` nor
211
+ * `JsonrpcErrorResponse` envelope
212
+ */
213
+ export const parse_rpc_call_result = (raw, method) => {
214
+ const { status, headers, body } = raw;
207
215
  const success = JsonrpcResponse.safeParse(body);
208
216
  if (success.success) {
209
- return { ok: true, status, headers: response_headers, result: success.data.result };
217
+ return { ok: true, status, headers, result: success.data.result };
210
218
  }
211
219
  const error = JsonrpcErrorResponse.safeParse(body);
212
220
  if (error.success) {
213
221
  return {
214
222
  ok: false,
215
223
  status,
216
- headers: response_headers,
224
+ headers,
217
225
  error: {
218
226
  code: error.data.error.code,
219
227
  message: error.data.error.message,
@@ -223,6 +231,19 @@ export const rpc_call = async (args) => {
223
231
  }
224
232
  throw new Error(`rpc_call: response is not a valid JSON-RPC envelope (method=${method}, status=${status}): ${JSON.stringify(body)}`);
225
233
  };
234
+ /**
235
+ * One-shot JSON-RPC call over a Hono app.
236
+ *
237
+ * Merges sensible defaults (`host`, `origin`, `Content-Type`) under
238
+ * caller-provided headers, fires POST (default) or GET, parses the envelope,
239
+ * and returns a discriminated result.
240
+ *
241
+ * @throws Error if the response body is neither a valid `JsonrpcResponse`
242
+ * nor `JsonrpcErrorResponse` envelope — protocol-level failures the caller
243
+ * should never tolerate. All JSON-RPC errors come back via `{ok: false, error}`
244
+ * so assertions can focus on `error.code` / `error.data.reason`.
245
+ */
246
+ export const rpc_call = async (args) => parse_rpc_call_result(await rpc_call_raw(args), args.method);
226
247
  /**
227
248
  * Same as `rpc_call` but without the default `origin` header. Use for
228
249
  * bearer-auth probes: `bearer_auth` discards the token when Origin or
@@ -1,6 +1,8 @@
1
1
  import './assert_dev_env.js';
2
- import type { AppSurfaceSpec } from '../http/surface.js';
2
+ import type { TestAccount } from './app_server.js';
3
+ import type { AppSurfaceSpec, AppSurfaceRpcMethod } from '../http/surface.js';
3
4
  import { type RpcEndpointsSuiteOption } from './rpc_helpers.js';
5
+ import { type AuthPrincipal, type KeeperHeaderProvider } from './integration_helpers.js';
4
6
  import type { SetupTest, TestFixture } from './cross_backend/setup.js';
5
7
  import type { SessionOptions } from '../auth/session_cookie.js';
6
8
  /** Options for `describe_rpc_round_trip_tests`. */
@@ -51,9 +53,58 @@ export interface RpcRoundTripTestOptions {
51
53
  *
52
54
  * Fired as POST. The factory runs against the shared per-describe fixture,
53
55
  * so it must not assume a clean slate between entries (seed unique state).
56
+ * By default the request carries the identity the generic loop picks for
57
+ * the method's auth (`authed` / `admin` / keeper); a case that returns
58
+ * `headers` sends those instead — for methods whose row must belong to the
59
+ * caller (revoking one's own token or session, retracting one's own offer).
60
+ * `create_spine_rpc_success_fixtures` (`cross_backend/rpc_success_fixtures.ts`)
61
+ * builds the map for the standard spine methods.
54
62
  */
55
- success_fixtures?: Map<string, (fixture: TestFixture) => Promise<Record<string, unknown>>>;
63
+ success_fixtures?: RpcSuccessFixtures;
56
64
  }
65
+ /** One success-fixture request: the params, and optionally the caller's headers. */
66
+ export interface RpcSuccessFixtureCase {
67
+ /** Params that drive a success response. */
68
+ params: Record<string, unknown>;
69
+ /**
70
+ * Auth headers to send in place of the identity the suite picks from the
71
+ * method's auth — for a row that only its owner may act on.
72
+ */
73
+ headers?: Record<string, string>;
74
+ }
75
+ /** One success-fixture factory: builds the row against the per-test fixture, then returns the request. */
76
+ export type RpcSuccessFixture = (fixture: TestFixture) => Promise<RpcSuccessFixtureCase>;
77
+ /** Success-case fixtures, method name → async factory. See `RpcRoundTripTestOptions.success_fixtures`. */
78
+ export type RpcSuccessFixtures = Map<string, RpcSuccessFixture>;
79
+ /** A picked principal and the headers that carry its credential. */
80
+ export interface RpcRoundTripAuth {
81
+ principal: AuthPrincipal;
82
+ headers: Record<string, string>;
83
+ }
84
+ /**
85
+ * Pick the principal matching an RPC method's auth requirement
86
+ * (`pick_auth_principal`, shared with the REST round-trip), and the headers
87
+ * carrying its credential. Accepts any `KeeperHeaderProvider` — both `TestApp`
88
+ * (in-process) and `TestFixture` (cross-backend) satisfy the shape
89
+ * structurally.
90
+ */
91
+ export declare const pick_rpc_auth: (method: AppSurfaceRpcMethod, keeper: KeeperHeaderProvider, authed_account: TestAccount, admin_account: TestAccount) => RpcRoundTripAuth;
92
+ /**
93
+ * Guard against a refusal that says the call carried no valid credential
94
+ * when it carried one (`is_unauthenticated_refusal`). The round-trip sends
95
+ * every non-public method a live credential its auth admits, so such a 401
96
+ * means the backend failed to authenticate it — most often because an earlier
97
+ * call destroyed it (a self-delete, a revoke-all), which would turn every
98
+ * later method's coverage into a vacuous refusal. A public method may still
99
+ * answer 401 (a login with a wrong password), and so may a handler refusing
100
+ * an authenticated call with a reason of its own (`invalid_credentials`).
101
+ *
102
+ * @param method - the RPC method name
103
+ * @param status - the HTTP status
104
+ * @param body - the parsed response body (or raw text when not JSON)
105
+ * @param principal - the principal the call was sent as
106
+ */
107
+ export declare const assert_rpc_authenticated: (method: string, status: number, body: unknown, principal: AuthPrincipal) => void;
57
108
  /**
58
109
  * Run schema-driven round-trip validation for RPC endpoints.
59
110
  *
@@ -66,10 +117,15 @@ export interface RpcRoundTripTestOptions {
66
117
  *
67
118
  * Error responses (from missing DB state, etc.) are expected and validated
68
119
  * as well-formed JSON-RPC errors. Successful responses are validated against
69
- * `action.spec.output`. A `method not found` (-32601) error is the one
70
- * exception — it means the backend is missing a method the local surface
71
- * advertises, so the round-trip fails loud (`assert_method_implemented`)
72
- * rather than accepting it as a valid error envelope.
120
+ * `action.spec.output`. Two error classes fail loud instead of passing as a
121
+ * valid envelope: `method not found` (-32601) means the backend is missing a
122
+ * method the local surface advertises (`assert_method_implemented`), and a
123
+ * crash — HTTP 500, `internal_error` (-32603), or a ≥500 with no JSON-RPC
124
+ * envelope — means the backend failed on schema-valid input
125
+ * (`assert_not_crash`). A declared ≥500 code (`service_unavailable`,
126
+ * `timeout`) passes as a refusal. A method the suite can't drive generically
127
+ * goes in `skip_methods`; one whose generated params can't reach its handler
128
+ * gets an `input_overrides` entry.
73
129
  */
74
130
  export declare const describe_rpc_round_trip_tests: (options: RpcRoundTripTestOptions) => void;
75
131
  //# sourceMappingURL=rpc_round_trip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rpc_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAyB7B,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAQN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACvC,kEAAkE;IAClE,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;;OAKG;IACH,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;OAKG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,qDAAqD;IACrD,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC3F;AAoDD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,uBAAuB,KAAG,IA+JhF,CAAC"}
1
+ {"version":3,"file":"rpc_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAsC7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAQN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAKN,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACvC,kEAAkE;IAClE,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;;OAKG;IACH,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;OAKG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,qDAAqD;IACrD,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,oFAAoF;AACpF,MAAM,WAAW,qBAAqB;IACrC,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,0GAA0G;AAC1G,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEzF,0GAA0G;AAC1G,MAAM,MAAM,kBAAkB,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAEhE,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GACzB,QAAQ,mBAAmB,EAC3B,QAAQ,oBAAoB,EAC5B,gBAAgB,WAAW,EAC3B,eAAe,WAAW,KACxB,gBAMF,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,wBAAwB,GACpC,QAAQ,MAAM,EACd,QAAQ,MAAM,EACd,MAAM,OAAO,EACb,WAAW,aAAa,KACtB,IAiBF,CAAC;AA+GF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,uBAAuB,KAAG,IAiKhF,CAAC"}