@fuzdev/fuz_app 0.55.0 → 0.56.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 (331) hide show
  1. package/dist/actions/CLAUDE.md +211 -155
  2. package/dist/actions/action_bridge.d.ts +8 -5
  3. package/dist/actions/action_bridge.d.ts.map +1 -1
  4. package/dist/actions/action_bridge.js +1 -11
  5. package/dist/actions/action_codegen.d.ts +19 -0
  6. package/dist/actions/action_codegen.d.ts.map +1 -1
  7. package/dist/actions/action_codegen.js +20 -14
  8. package/dist/actions/action_registry.d.ts.map +1 -1
  9. package/dist/actions/action_registry.js +5 -2
  10. package/dist/actions/action_rpc.d.ts +110 -44
  11. package/dist/actions/action_rpc.d.ts.map +1 -1
  12. package/dist/actions/action_rpc.js +92 -287
  13. package/dist/actions/action_spec.d.ts +55 -16
  14. package/dist/actions/action_spec.d.ts.map +1 -1
  15. package/dist/actions/action_spec.js +16 -11
  16. package/dist/actions/action_types.d.ts +28 -60
  17. package/dist/actions/action_types.d.ts.map +1 -1
  18. package/dist/actions/action_types.js +13 -5
  19. package/dist/actions/broadcast_api.d.ts +2 -2
  20. package/dist/actions/broadcast_api.js +2 -2
  21. package/dist/actions/compile_action_registry.d.ts +50 -0
  22. package/dist/actions/compile_action_registry.d.ts.map +1 -0
  23. package/dist/actions/compile_action_registry.js +69 -0
  24. package/dist/actions/heartbeat.d.ts +8 -4
  25. package/dist/actions/heartbeat.d.ts.map +1 -1
  26. package/dist/actions/heartbeat.js +5 -4
  27. package/dist/actions/perform_action.d.ts +145 -0
  28. package/dist/actions/perform_action.d.ts.map +1 -0
  29. package/dist/actions/perform_action.js +258 -0
  30. package/dist/actions/register_action_ws.d.ts +44 -38
  31. package/dist/actions/register_action_ws.d.ts.map +1 -1
  32. package/dist/actions/register_action_ws.js +101 -159
  33. package/dist/actions/register_ws_endpoint.d.ts +2 -10
  34. package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
  35. package/dist/actions/register_ws_endpoint.js +32 -10
  36. package/dist/actions/transports_ws_auth_guard.d.ts +1 -1
  37. package/dist/actions/transports_ws_auth_guard.js +1 -1
  38. package/dist/actions/transports_ws_backend.d.ts +1 -1
  39. package/dist/actions/transports_ws_backend.js +1 -1
  40. package/dist/auth/CLAUDE.md +673 -442
  41. package/dist/auth/account_action_specs.d.ts +28 -7
  42. package/dist/auth/account_action_specs.d.ts.map +1 -1
  43. package/dist/auth/account_action_specs.js +7 -7
  44. package/dist/auth/account_actions.d.ts +8 -14
  45. package/dist/auth/account_actions.d.ts.map +1 -1
  46. package/dist/auth/account_actions.js +26 -32
  47. package/dist/auth/account_queries.d.ts +46 -13
  48. package/dist/auth/account_queries.d.ts.map +1 -1
  49. package/dist/auth/account_queries.js +73 -33
  50. package/dist/auth/account_routes.d.ts +4 -3
  51. package/dist/auth/account_routes.d.ts.map +1 -1
  52. package/dist/auth/account_routes.js +58 -33
  53. package/dist/auth/account_schema.d.ts +46 -54
  54. package/dist/auth/account_schema.d.ts.map +1 -1
  55. package/dist/auth/account_schema.js +21 -48
  56. package/dist/auth/admin_action_specs.d.ts +55 -21
  57. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  58. package/dist/auth/admin_action_specs.js +42 -26
  59. package/dist/auth/admin_actions.d.ts +14 -21
  60. package/dist/auth/admin_actions.d.ts.map +1 -1
  61. package/dist/auth/admin_actions.js +47 -44
  62. package/dist/auth/audit_emitter.d.ts +160 -0
  63. package/dist/auth/audit_emitter.d.ts.map +1 -0
  64. package/dist/auth/audit_emitter.js +83 -0
  65. package/dist/auth/audit_log_queries.d.ts +17 -87
  66. package/dist/auth/audit_log_queries.d.ts.map +1 -1
  67. package/dist/auth/audit_log_queries.js +17 -96
  68. package/dist/auth/audit_log_routes.d.ts +1 -1
  69. package/dist/auth/audit_log_routes.d.ts.map +1 -1
  70. package/dist/auth/audit_log_routes.js +7 -3
  71. package/dist/auth/audit_log_schema.d.ts +48 -42
  72. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  73. package/dist/auth/audit_log_schema.js +56 -43
  74. package/dist/auth/auth_guard_resolver.d.ts +44 -0
  75. package/dist/auth/auth_guard_resolver.d.ts.map +1 -0
  76. package/dist/auth/auth_guard_resolver.js +56 -0
  77. package/dist/auth/bootstrap_account.d.ts +7 -7
  78. package/dist/auth/bootstrap_account.d.ts.map +1 -1
  79. package/dist/auth/bootstrap_account.js +7 -7
  80. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  81. package/dist/auth/bootstrap_routes.js +11 -10
  82. package/dist/auth/cleanup.d.ts +20 -26
  83. package/dist/auth/cleanup.d.ts.map +1 -1
  84. package/dist/auth/cleanup.js +33 -47
  85. package/dist/auth/credential_type_schema.d.ts +115 -0
  86. package/dist/auth/credential_type_schema.d.ts.map +1 -0
  87. package/dist/auth/credential_type_schema.js +127 -0
  88. package/dist/auth/daemon_token_middleware.d.ts +1 -1
  89. package/dist/auth/daemon_token_middleware.js +3 -3
  90. package/dist/auth/ddl.d.ts +2 -2
  91. package/dist/auth/ddl.d.ts.map +1 -1
  92. package/dist/auth/ddl.js +6 -6
  93. package/dist/auth/deps.d.ts +7 -32
  94. package/dist/auth/deps.d.ts.map +1 -1
  95. package/dist/auth/grant_path_schema.d.ts +117 -0
  96. package/dist/auth/grant_path_schema.d.ts.map +1 -0
  97. package/dist/auth/grant_path_schema.js +137 -0
  98. package/dist/auth/invite_queries.d.ts +12 -1
  99. package/dist/auth/invite_queries.d.ts.map +1 -1
  100. package/dist/auth/invite_queries.js +12 -1
  101. package/dist/auth/invite_schema.d.ts +1 -1
  102. package/dist/auth/invite_schema.d.ts.map +1 -1
  103. package/dist/auth/invite_schema.js +1 -1
  104. package/dist/auth/middleware.d.ts.map +1 -1
  105. package/dist/auth/middleware.js +5 -2
  106. package/dist/auth/migrations.d.ts +22 -7
  107. package/dist/auth/migrations.d.ts.map +1 -1
  108. package/dist/auth/migrations.js +64 -25
  109. package/dist/auth/request_context.d.ts +157 -170
  110. package/dist/auth/request_context.d.ts.map +1 -1
  111. package/dist/auth/request_context.js +224 -268
  112. package/dist/auth/{permit_offer_action_specs.d.ts → role_grant_offer_action_specs.d.ts} +130 -100
  113. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -0
  114. package/dist/auth/role_grant_offer_action_specs.js +262 -0
  115. package/dist/auth/role_grant_offer_actions.d.ts +104 -0
  116. package/dist/auth/role_grant_offer_actions.d.ts.map +1 -0
  117. package/dist/auth/{permit_offer_actions.js → role_grant_offer_actions.js} +153 -140
  118. package/dist/auth/{permit_offer_notifications.d.ts → role_grant_offer_notifications.d.ts} +80 -70
  119. package/dist/auth/role_grant_offer_notifications.d.ts.map +1 -0
  120. package/dist/auth/role_grant_offer_notifications.js +182 -0
  121. package/dist/auth/{permit_offer_queries.d.ts → role_grant_offer_queries.d.ts} +64 -64
  122. package/dist/auth/role_grant_offer_queries.d.ts.map +1 -0
  123. package/dist/auth/{permit_offer_queries.js → role_grant_offer_queries.js} +136 -123
  124. package/dist/auth/role_grant_offer_schema.d.ts +150 -0
  125. package/dist/auth/role_grant_offer_schema.d.ts.map +1 -0
  126. package/dist/auth/{permit_offer_schema.js → role_grant_offer_schema.js} +55 -36
  127. package/dist/auth/role_grant_queries.d.ts +231 -0
  128. package/dist/auth/role_grant_queries.d.ts.map +1 -0
  129. package/dist/auth/role_grant_queries.js +320 -0
  130. package/dist/auth/role_schema.d.ts +150 -40
  131. package/dist/auth/role_schema.d.ts.map +1 -1
  132. package/dist/auth/role_schema.js +144 -45
  133. package/dist/auth/scope_kind_schema.d.ts +96 -0
  134. package/dist/auth/scope_kind_schema.d.ts.map +1 -0
  135. package/dist/auth/scope_kind_schema.js +94 -0
  136. package/dist/auth/self_service_role_action_specs.d.ts +4 -1
  137. package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
  138. package/dist/auth/self_service_role_action_specs.js +2 -2
  139. package/dist/auth/self_service_role_actions.d.ts +35 -29
  140. package/dist/auth/self_service_role_actions.d.ts.map +1 -1
  141. package/dist/auth/self_service_role_actions.js +58 -48
  142. package/dist/auth/session_cookie.d.ts +43 -6
  143. package/dist/auth/session_cookie.d.ts.map +1 -1
  144. package/dist/auth/session_cookie.js +31 -5
  145. package/dist/auth/session_middleware.d.ts +37 -3
  146. package/dist/auth/session_middleware.d.ts.map +1 -1
  147. package/dist/auth/session_middleware.js +33 -7
  148. package/dist/auth/signup_routes.d.ts.map +1 -1
  149. package/dist/auth/signup_routes.js +48 -19
  150. package/dist/auth/standard_action_specs.d.ts +2 -2
  151. package/dist/auth/standard_action_specs.js +4 -4
  152. package/dist/auth/standard_rpc_actions.d.ts +23 -19
  153. package/dist/auth/standard_rpc_actions.d.ts.map +1 -1
  154. package/dist/auth/standard_rpc_actions.js +12 -12
  155. package/dist/db/migrate.d.ts +1 -1
  156. package/dist/db/migrate.js +1 -1
  157. package/dist/dev/setup.d.ts +2 -2
  158. package/dist/dev/setup.d.ts.map +1 -1
  159. package/dist/dev/setup.js +4 -4
  160. package/dist/env/load.d.ts +1 -1
  161. package/dist/env/load.js +1 -1
  162. package/dist/hono_context.d.ts +27 -45
  163. package/dist/hono_context.d.ts.map +1 -1
  164. package/dist/hono_context.js +14 -28
  165. package/dist/http/CLAUDE.md +235 -121
  166. package/dist/http/auth_shape.d.ts +191 -0
  167. package/dist/http/auth_shape.d.ts.map +1 -0
  168. package/dist/http/auth_shape.js +237 -0
  169. package/dist/http/common_routes.js +3 -3
  170. package/dist/http/db_routes.d.ts +4 -0
  171. package/dist/http/db_routes.d.ts.map +1 -1
  172. package/dist/http/db_routes.js +44 -7
  173. package/dist/http/error_schemas.d.ts +56 -34
  174. package/dist/http/error_schemas.d.ts.map +1 -1
  175. package/dist/http/error_schemas.js +63 -28
  176. package/dist/http/pending_effects.d.ts +71 -18
  177. package/dist/http/pending_effects.d.ts.map +1 -1
  178. package/dist/http/pending_effects.js +87 -18
  179. package/dist/http/proxy.d.ts +52 -5
  180. package/dist/http/proxy.d.ts.map +1 -1
  181. package/dist/http/proxy.js +92 -14
  182. package/dist/http/route_spec.d.ts +89 -75
  183. package/dist/http/route_spec.d.ts.map +1 -1
  184. package/dist/http/route_spec.js +54 -72
  185. package/dist/http/schema_helpers.d.ts +3 -14
  186. package/dist/http/schema_helpers.d.ts.map +1 -1
  187. package/dist/http/schema_helpers.js +2 -14
  188. package/dist/http/surface.d.ts +2 -10
  189. package/dist/http/surface.d.ts.map +1 -1
  190. package/dist/http/surface.js +3 -4
  191. package/dist/http/surface_query.d.ts +39 -35
  192. package/dist/http/surface_query.d.ts.map +1 -1
  193. package/dist/http/surface_query.js +79 -36
  194. package/dist/primitive_schemas.d.ts +39 -0
  195. package/dist/primitive_schemas.d.ts.map +1 -0
  196. package/dist/primitive_schemas.js +40 -0
  197. package/dist/realtime/sse_auth_guard.d.ts +5 -5
  198. package/dist/realtime/sse_auth_guard.js +9 -9
  199. package/dist/runtime/mock.d.ts +1 -1
  200. package/dist/runtime/mock.js +1 -1
  201. package/dist/server/app_backend.d.ts +14 -11
  202. package/dist/server/app_backend.d.ts.map +1 -1
  203. package/dist/server/app_backend.js +12 -8
  204. package/dist/server/app_server.d.ts +7 -7
  205. package/dist/server/app_server.d.ts.map +1 -1
  206. package/dist/server/app_server.js +35 -40
  207. package/dist/server/validate_nginx.d.ts +1 -1
  208. package/dist/server/validate_nginx.js +1 -1
  209. package/dist/testing/CLAUDE.md +50 -38
  210. package/dist/testing/admin_integration.d.ts +5 -6
  211. package/dist/testing/admin_integration.d.ts.map +1 -1
  212. package/dist/testing/admin_integration.js +87 -85
  213. package/dist/testing/app_server.d.ts +11 -14
  214. package/dist/testing/app_server.d.ts.map +1 -1
  215. package/dist/testing/app_server.js +16 -15
  216. package/dist/testing/assertions.d.ts.map +1 -1
  217. package/dist/testing/assertions.js +2 -1
  218. package/dist/testing/attack_surface.d.ts.map +1 -1
  219. package/dist/testing/attack_surface.js +15 -9
  220. package/dist/testing/audit_completeness.d.ts +2 -2
  221. package/dist/testing/audit_completeness.d.ts.map +1 -1
  222. package/dist/testing/audit_completeness.js +36 -36
  223. package/dist/testing/auth_apps.d.ts +5 -4
  224. package/dist/testing/auth_apps.d.ts.map +1 -1
  225. package/dist/testing/auth_apps.js +22 -19
  226. package/dist/testing/data_exposure.d.ts.map +1 -1
  227. package/dist/testing/data_exposure.js +5 -5
  228. package/dist/testing/db.d.ts +1 -1
  229. package/dist/testing/db.d.ts.map +1 -1
  230. package/dist/testing/db.js +4 -4
  231. package/dist/testing/db_entities.d.ts +22 -0
  232. package/dist/testing/db_entities.d.ts.map +1 -0
  233. package/dist/testing/db_entities.js +28 -0
  234. package/dist/testing/entities.d.ts +8 -7
  235. package/dist/testing/entities.d.ts.map +1 -1
  236. package/dist/testing/entities.js +21 -18
  237. package/dist/testing/integration.d.ts.map +1 -1
  238. package/dist/testing/integration.js +13 -14
  239. package/dist/testing/integration_helpers.d.ts +4 -4
  240. package/dist/testing/integration_helpers.d.ts.map +1 -1
  241. package/dist/testing/integration_helpers.js +20 -18
  242. package/dist/testing/middleware.d.ts +4 -4
  243. package/dist/testing/middleware.d.ts.map +1 -1
  244. package/dist/testing/middleware.js +12 -11
  245. package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
  246. package/dist/testing/rpc_attack_surface.js +40 -24
  247. package/dist/testing/rpc_round_trip.d.ts +1 -1
  248. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  249. package/dist/testing/rpc_round_trip.js +14 -13
  250. package/dist/testing/sse_round_trip.d.ts +3 -4
  251. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  252. package/dist/testing/sse_round_trip.js +7 -11
  253. package/dist/testing/standard.d.ts +1 -1
  254. package/dist/testing/stubs.d.ts +25 -0
  255. package/dist/testing/stubs.d.ts.map +1 -1
  256. package/dist/testing/stubs.js +43 -2
  257. package/dist/testing/surface_invariants.d.ts +2 -2
  258. package/dist/testing/ws_round_trip.d.ts +12 -13
  259. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  260. package/dist/testing/ws_round_trip.js +19 -11
  261. package/dist/ui/AdminAccounts.svelte +23 -20
  262. package/dist/ui/AdminOverview.svelte +15 -13
  263. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  264. package/dist/ui/{AdminPermitHistory.svelte → AdminRoleGrantHistory.svelte} +12 -12
  265. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts +4 -0
  266. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts.map +1 -0
  267. package/dist/ui/BootstrapForm.svelte +1 -1
  268. package/dist/ui/CLAUDE.md +60 -60
  269. package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +27 -26
  270. package/dist/ui/{PermitOfferForm.svelte.d.ts → RoleGrantOfferForm.svelte.d.ts} +7 -7
  271. package/dist/ui/RoleGrantOfferForm.svelte.d.ts.map +1 -0
  272. package/dist/ui/{PermitOfferHistory.svelte → RoleGrantOfferHistory.svelte} +12 -12
  273. package/dist/ui/{PermitOfferHistory.svelte.d.ts → RoleGrantOfferHistory.svelte.d.ts} +4 -4
  274. package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -0
  275. package/dist/ui/{PermitOfferInbox.svelte → RoleGrantOfferInbox.svelte} +14 -14
  276. package/dist/ui/{PermitOfferInbox.svelte.d.ts → RoleGrantOfferInbox.svelte.d.ts} +4 -4
  277. package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -0
  278. package/dist/ui/SignupForm.svelte +1 -1
  279. package/dist/ui/SurfaceExplorer.svelte +35 -15
  280. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
  281. package/dist/ui/account_sessions_state.svelte.d.ts +2 -3
  282. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  283. package/dist/ui/account_sessions_state.svelte.js +2 -3
  284. package/dist/ui/admin_accounts_state.svelte.d.ts +18 -18
  285. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  286. package/dist/ui/admin_accounts_state.svelte.js +16 -16
  287. package/dist/ui/admin_rpc_adapters.d.ts +20 -20
  288. package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
  289. package/dist/ui/admin_rpc_adapters.js +17 -17
  290. package/dist/ui/admin_sessions_state.svelte.d.ts +2 -2
  291. package/dist/ui/admin_sessions_state.svelte.js +2 -2
  292. package/dist/ui/audit_log_state.svelte.d.ts +7 -7
  293. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  294. package/dist/ui/audit_log_state.svelte.js +6 -6
  295. package/dist/ui/auth_state.svelte.d.ts +3 -3
  296. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  297. package/dist/ui/auth_state.svelte.js +6 -6
  298. package/dist/ui/format_scope.d.ts +2 -2
  299. package/dist/ui/format_scope.js +2 -2
  300. package/dist/ui/{permit_offers_state.svelte.d.ts → role_grant_offers_state.svelte.d.ts} +30 -30
  301. package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -0
  302. package/dist/ui/{permit_offers_state.svelte.js → role_grant_offers_state.svelte.js} +18 -18
  303. package/dist/ui/ui_format.js +2 -2
  304. package/package.json +3 -3
  305. package/dist/auth/permit_offer_action_specs.d.ts.map +0 -1
  306. package/dist/auth/permit_offer_action_specs.js +0 -258
  307. package/dist/auth/permit_offer_actions.d.ts +0 -110
  308. package/dist/auth/permit_offer_actions.d.ts.map +0 -1
  309. package/dist/auth/permit_offer_notifications.d.ts.map +0 -1
  310. package/dist/auth/permit_offer_notifications.js +0 -182
  311. package/dist/auth/permit_offer_queries.d.ts.map +0 -1
  312. package/dist/auth/permit_offer_schema.d.ts +0 -125
  313. package/dist/auth/permit_offer_schema.d.ts.map +0 -1
  314. package/dist/auth/permit_queries.d.ts +0 -222
  315. package/dist/auth/permit_queries.d.ts.map +0 -1
  316. package/dist/auth/permit_queries.js +0 -305
  317. package/dist/auth/require_keeper.d.ts +0 -20
  318. package/dist/auth/require_keeper.d.ts.map +0 -1
  319. package/dist/auth/require_keeper.js +0 -35
  320. package/dist/auth/route_guards.d.ts +0 -27
  321. package/dist/auth/route_guards.d.ts.map +0 -1
  322. package/dist/auth/route_guards.js +0 -38
  323. package/dist/auth/session_lifecycle.d.ts +0 -37
  324. package/dist/auth/session_lifecycle.d.ts.map +0 -1
  325. package/dist/auth/session_lifecycle.js +0 -29
  326. package/dist/ui/AdminPermitHistory.svelte.d.ts +0 -4
  327. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +0 -1
  328. package/dist/ui/PermitOfferForm.svelte.d.ts.map +0 -1
  329. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +0 -1
  330. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +0 -1
  331. package/dist/ui/permit_offers_state.svelte.d.ts.map +0 -1
@@ -15,38 +15,17 @@
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
17
  import { ThrownJsonrpcError, jsonrpc_error_code_to_http_status, jsonrpc_error_code_to_name, } from './jsonrpc_errors.js';
18
- import { CACHED_REQUEST_BODY_KEY } from '../hono_context.js';
19
18
  import { is_null_schema, merge_error_schemas } from './schema_helpers.js';
20
- /**
21
- * Get validated input from the Hono context.
22
- *
23
- * Call after the input validation middleware has run. The type parameter
24
- * should match the route's `input` schema.
25
- */
26
- export const get_route_input = (c) => {
19
+ import { assert_route_auth_acting_biconditional } from './auth_shape.js';
20
+ export function get_route_input(c, _schema) {
27
21
  return c.get('validated_input');
28
- };
29
- /**
30
- * Get validated URL path params from the Hono context.
31
- *
32
- * Call after the params validation middleware has run. The type parameter
33
- * should match the route's `params` schema.
34
- *
35
- * TODO derive `T` from the route spec so the type parameter isn't manually
36
- * specified — same applies to `get_route_input` / `get_route_query`.
37
- */
38
- export const get_route_params = (c) => {
22
+ }
23
+ export function get_route_params(c, _schema) {
39
24
  return c.get('validated_params');
40
- };
41
- /**
42
- * Get validated URL query params from the Hono context.
43
- *
44
- * Call after the query validation middleware has run. The type parameter
45
- * should match the route's `query` schema.
46
- */
47
- export const get_route_query = (c) => {
25
+ }
26
+ export function get_route_query(c, _schema) {
48
27
  return c.get('validated_query');
49
- };
28
+ }
50
29
  /**
51
30
  * Create input validation middleware for a route spec.
52
31
  *
@@ -54,7 +33,10 @@ export const get_route_query = (c) => {
54
33
  * validated elsewhere, e.g. from `?params=` query string in RPC handlers)
55
34
  * and for null-input routes (no body expected). For other routes with input
56
35
  * schemas, returns a middleware that parses and validates the JSON body,
57
- * storing the result on the context as `validated_input`.
36
+ * storing the result on the context as `validated_input`. Input validation
37
+ * runs before the authorization phase, so the authorization phase reads
38
+ * `c.var.validated_input.acting` directly — no separate body pre-parse /
39
+ * cache machinery is needed.
58
40
  *
59
41
  * @mutates `c.var.validated_input` - set to the parsed and validated body on success
60
42
  */
@@ -64,30 +46,12 @@ const create_input_validation = (input_schema, method) => {
64
46
  if (is_null_schema(input_schema))
65
47
  return [];
66
48
  const validate = async (c, next) => {
67
- // Prefer the cached parse result written by `read_raw_acting`
68
- // (the dispatcher's `acting` extractor). The cache decouples
69
- // us from Hono's internal `bodyCache` — Hono keeps the body
70
- // text alive across multiple `c.req.json()` calls but still
71
- // re-runs `JSON.parse` each time, so caching the parsed value
72
- // saves work and pins behavior to fuz_app code rather than to
73
- // undocumented Hono internals.
74
- // Hono's `c.get()` types this as the variable-map entry, but at
75
- // runtime it returns `undefined` when no setter has run for this
76
- // request. Narrow defensively.
77
- const cached = c.get(CACHED_REQUEST_BODY_KEY);
78
49
  let body;
79
- if (cached !== undefined) {
80
- if (!cached.ok)
81
- return c.json({ error: ERROR_INVALID_JSON_BODY }, 400);
82
- body = cached.body;
50
+ try {
51
+ body = await c.req.json();
83
52
  }
84
- else {
85
- try {
86
- body = await c.req.json();
87
- }
88
- catch {
89
- return c.json({ error: ERROR_INVALID_JSON_BODY }, 400);
90
- }
53
+ catch {
54
+ return c.json({ error: ERROR_INVALID_JSON_BODY }, 400);
91
55
  }
92
56
  if (typeof body !== 'object' || body === null || Array.isArray(body)) {
93
57
  return c.json({ error: ERROR_INVALID_JSON_BODY }, 400);
@@ -299,29 +263,38 @@ const build_rest_error_body = (err) => {
299
263
  * and generic errors), and registers the route.
300
264
  *
301
265
  * Per-route middleware order: params → query → pre-validation auth
302
- * guards (401) → authorization phasepost-authorization auth guards
303
- * (403) → input validation → handler. The 401 check runs before any
304
- * body parsing so unauthenticated callers never see route-shape
305
- * information from parse failures. The authorization phase runs before
306
- * input validation (matches the RPC dispatcher's order) so role /
307
- * keeper denials surface 403 before 400 invalid_params; it extracts
308
- * `acting` from raw query (GET) or pre-parsed JSON body (POST/PUT/...)
309
- * Hono caches the parsed body internally so the subsequent input-
310
- * validation step does not re-parse. The role / keeper guards consume
311
- * the `RequestContext` populated by the authorization phase.
266
+ * guards (401) → input validation (400) → authorization phase
267
+ * post-authorization auth guards (403) → handler. The 401 check runs
268
+ * before any body parsing so unauthenticated callers never see
269
+ * route-shape information from parse failures. Input validation runs
270
+ * before the authorization phase (validate first, authorize after) so
271
+ * the authorization phase reads `c.var.validated_input.acting` as a
272
+ * typed Zod field instead of pre-parsing the raw body. Role /
273
+ * credential-type denials still surface 403 last; trade-off is that
274
+ * authenticated-but-unauthorized callers can distinguish 400
275
+ * (validation) from 403 (authorization), a defense-in-depth concession
276
+ * deemed acceptable because the route surface is public via
277
+ * spec/codegen JSON.
312
278
  *
313
279
  * Each handler receives a `RouteContext` with:
314
- * - `db`: transaction-scoped (for non-GET) or pool-level (for GET)
315
- * - `background_db`: always pool-level
316
- * - `pending_effects`: fire-and-forget effect queue
280
+ * - `db`: transaction-scoped when `RouteSpec.transaction` is true; pool-level otherwise
281
+ * - `pending_effects`: eager fire-and-forget pool-write queue
282
+ * - `post_commit_effects`: deferred-thunk queue (push via `emit_after_commit`)
283
+ *
284
+ * Also enforces registry-time invariant 2 from the auth-shape design:
285
+ * `auth.actor !== 'none' ⟺ input or query declares acting?: ActingActor`.
286
+ * REST is bi-located (GETs declare `acting` on `query`, mutations on
287
+ * `input`), so the check passes both slots; the action-dispatcher
288
+ * registries (`compile_action_registry`) share the same helper with
289
+ * `input` only — `ActionSpec` has no `query` shape.
317
290
  *
318
- * @param resolve_auth_guards - maps `RouteAuth` to middleware — use `fuz_auth_guard_resolver` from `auth/route_guards.ts`
319
- * @param authorize - optional authorization phase; runs between guards and input validation
291
+ * @param resolve_auth_guards - maps `RouteAuth` to middleware — use `fuz_auth_guard_resolver` from `auth/auth_guard_resolver.ts`
292
+ * @param authorize - optional authorization phase; runs after input validation
320
293
  * @param db - used for transaction wrapping and `RouteContext`
321
294
  * @mutates `app`
322
- * @throws Error if two specs share the same `method` + `path` (each combination must be unique)
295
+ * @throws Error if two specs share the same `method` + `path` (each combination must be unique), or if any spec violates the actor-acting biconditional
323
296
  */
324
- export const apply_route_specs = (app, specs, resolve_auth_guards, log, db, authorize, is_acting_aware) => {
297
+ export const apply_route_specs = (app, specs, resolve_auth_guards, log, db, authorize) => {
325
298
  const registered = new Set();
326
299
  for (const spec of specs) {
327
300
  const route_key = `${spec.method} ${spec.path}`;
@@ -329,11 +302,12 @@ export const apply_route_specs = (app, specs, resolve_auth_guards, log, db, auth
329
302
  throw new Error(`Duplicate route: ${route_key} — each method+path combination must be unique`);
330
303
  }
331
304
  registered.add(route_key);
305
+ assert_route_auth_acting_biconditional(spec.auth, { input: spec.input, query: spec.query }, `Route "${route_key}"`);
332
306
  const { pre_validation: pre_validation_guards, post_authorization: post_authorization_guards } = resolve_auth_guards(spec.auth);
333
307
  const params_validation = create_params_validation(spec.params);
334
308
  const query_validation = create_query_validation(spec.query);
335
309
  const input_validation = create_input_validation(spec.input, spec.method);
336
- const merged_errors = merge_error_schemas(spec, null, is_acting_aware?.(spec) ?? false);
310
+ const merged_errors = merge_error_schemas(spec, null);
337
311
  const authorization = authorize
338
312
  ? [
339
313
  async (c, next) => {
@@ -348,13 +322,21 @@ export const apply_route_specs = (app, specs, resolve_auth_guards, log, db, auth
348
322
  const use_transaction = spec.transaction ?? spec.method !== 'GET';
349
323
  const inner = spec.handler;
350
324
  let handler = use_transaction
351
- ? (c) => db.transaction(async (tx) => inner(c, { db: tx, background_db: db, pending_effects: c.var.pending_effects }))
352
- : (c) => inner(c, { db, background_db: db, pending_effects: c.var.pending_effects });
325
+ ? (c) => db.transaction(async (tx) => inner(c, {
326
+ db: tx,
327
+ pending_effects: c.var.pending_effects,
328
+ post_commit_effects: c.var.post_commit_effects,
329
+ }))
330
+ : (c) => inner(c, {
331
+ db,
332
+ pending_effects: c.var.pending_effects,
333
+ post_commit_effects: c.var.post_commit_effects,
334
+ });
353
335
  // Step 2: output validation
354
336
  handler = wrap_output_validation(handler, spec.output, merged_errors, log);
355
337
  // Step 3: error catch layer
356
338
  handler = wrap_error_catch(handler, log);
357
- app.on(spec.method, [spec.path], ...params_validation, ...query_validation, ...pre_validation_guards, ...authorization, ...post_authorization_guards, ...input_validation, handler);
339
+ app.on(spec.method, [spec.path], ...params_validation, ...query_validation, ...pre_validation_guards, ...input_validation, ...authorization, ...post_authorization_guards, handler);
358
340
  }
359
341
  };
360
342
  /**
@@ -8,7 +8,7 @@
8
8
  * @module
9
9
  */
10
10
  import { z } from 'zod';
11
- import type { RouteAuth } from './route_spec.js';
11
+ import type { RouteAuth } from './auth_shape.js';
12
12
  import { type RateLimitKey, type RouteErrorSchemas } from './error_schemas.js';
13
13
  /**
14
14
  * Check if a schema is exactly `z.null()`.
@@ -45,7 +45,7 @@ export declare const schema_to_surface: (schema: z.ZodType) => unknown;
45
45
  *
46
46
  * Supports Hono-style patterns:
47
47
  * - `/api/*` matches `/api/anything`
48
- * - `/api/tx/*` matches `/api/tx/runs` but not `/api/account/login`
48
+ * - `/api/zap/*` matches `/api/zap/runs` but not `/api/account/login`
49
49
  * - Exact match: `/health` matches `/health`
50
50
  */
51
51
  export declare const middleware_applies: (mw_path: string, route_path: string) => boolean;
@@ -55,19 +55,8 @@ export declare const middleware_applies: (mw_path: string, route_path: string) =
55
55
  * Merge order: derived -> middleware -> explicit route errors.
56
56
  * Later layers override earlier ones for the same status code.
57
57
  *
58
- * `acting_aware` flows through to `derive_error_schemas` so routes whose
59
- * input declares `acting?: ActingActor` (or whose auth requires permits)
60
- * pick up the actor-failure error shapes the dispatcher's authorization
61
- * phase may emit. The flag is computed at the call site rather than here
62
- * because the `acting`-detection helper lives in `auth/` (it depends on
63
- * the canonical `ActingActor` schema for reference equality, and `http/`
64
- * stays auth-agnostic). See `http/CLAUDE.md` § Three-layer error-schema
65
- * merge.
66
- *
67
58
  * @param spec - the route spec (needs `auth`, `input`, `params`, `rate_limit`, `errors`)
68
59
  * @param middleware_errors - errors contributed by middleware whose path matches the route
69
- * @param acting_aware - whether the dispatcher's authorization phase may emit
70
- * actor-failure errors on this route
71
60
  * @returns merged error schemas, or `null` if empty
72
61
  */
73
62
  export declare const merge_error_schemas: (spec: {
@@ -77,5 +66,5 @@ export declare const merge_error_schemas: (spec: {
77
66
  query?: z.ZodObject;
78
67
  rate_limit?: RateLimitKey;
79
68
  errors?: RouteErrorSchemas;
80
- }, middleware_errors?: RouteErrorSchemas | null, acting_aware?: boolean) => RouteErrorSchemas | null;
69
+ }, middleware_errors?: RouteErrorSchemas | null) => RouteErrorSchemas | null;
81
70
  //# sourceMappingURL=schema_helpers.d.ts.map
@@ -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,OAAsC,CAAC;AAE1F;;;;;;;GAOG;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,OAQrD,CAAC;AAoBF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;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,EAC5C,sBAAoB,KAClB,iBAAiB,GAAG,IAWtB,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;;;;;;;GAOG;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,OAQrD,CAAC;AAoBF;;;;;;;GAOG;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"}
@@ -74,7 +74,7 @@ const strip_json_schema_noise = (value) => {
74
74
  *
75
75
  * Supports Hono-style patterns:
76
76
  * - `/api/*` matches `/api/anything`
77
- * - `/api/tx/*` matches `/api/tx/runs` but not `/api/account/login`
77
+ * - `/api/zap/*` matches `/api/zap/runs` but not `/api/account/login`
78
78
  * - Exact match: `/health` matches `/health`
79
79
  */
80
80
  export const middleware_applies = (mw_path, route_path) => {
@@ -94,29 +94,17 @@ export const middleware_applies = (mw_path, route_path) => {
94
94
  * Merge order: derived -> middleware -> explicit route errors.
95
95
  * Later layers override earlier ones for the same status code.
96
96
  *
97
- * `acting_aware` flows through to `derive_error_schemas` so routes whose
98
- * input declares `acting?: ActingActor` (or whose auth requires permits)
99
- * pick up the actor-failure error shapes the dispatcher's authorization
100
- * phase may emit. The flag is computed at the call site rather than here
101
- * because the `acting`-detection helper lives in `auth/` (it depends on
102
- * the canonical `ActingActor` schema for reference equality, and `http/`
103
- * stays auth-agnostic). See `http/CLAUDE.md` § Three-layer error-schema
104
- * merge.
105
- *
106
97
  * @param spec - the route spec (needs `auth`, `input`, `params`, `rate_limit`, `errors`)
107
98
  * @param middleware_errors - errors contributed by middleware whose path matches the route
108
- * @param acting_aware - whether the dispatcher's authorization phase may emit
109
- * actor-failure errors on this route
110
99
  * @returns merged error schemas, or `null` if empty
111
100
  */
112
- export const merge_error_schemas = (spec, middleware_errors, acting_aware = false) => {
101
+ export const merge_error_schemas = (spec, middleware_errors) => {
113
102
  const derived = derive_error_schemas({
114
103
  auth: spec.auth,
115
104
  has_input: !is_null_schema(spec.input),
116
105
  has_params: !!spec.params,
117
106
  has_query: !!spec.query,
118
107
  rate_limit: spec.rate_limit,
119
- acting_aware,
120
108
  });
121
109
  const merged = { ...derived, ...middleware_errors, ...spec.errors };
122
110
  return Object.keys(merged).length > 0 ? merged : null;
@@ -9,7 +9,8 @@
9
9
  import { z } from 'zod';
10
10
  import type { EventSpec } from '../realtime/sse.js';
11
11
  import type { MiddlewareSpec } from './middleware_spec.js';
12
- import type { IsActingAware, RouteAuth, RouteSpec } from './route_spec.js';
12
+ import type { RouteSpec } from './route_spec.js';
13
+ import type { RouteAuth } from './auth_shape.js';
13
14
  import type { RateLimitKey, RouteErrorSchemas } from './error_schemas.js';
14
15
  import type { RpcAction } from '../actions/action_rpc.js';
15
16
  import type { Sensitivity } from '../sensitivity.js';
@@ -118,15 +119,6 @@ export interface GenerateAppSurfaceOptions {
118
119
  env_schema?: z.ZodObject;
119
120
  event_specs?: Array<EventSpec>;
120
121
  rpc_endpoints?: Array<RpcEndpointSpec>;
121
- /**
122
- * Per-route predicate that decides whether the dispatcher's authorization
123
- * phase may emit `actor_required` / `actor_not_on_account` (400) or
124
- * `no_actors_on_account` / `account_vanished` (500) on this spec. Mirrors
125
- * the parameter on `apply_route_specs` so the surface exposes the same
126
- * error shapes the live framework would emit. See `http/CLAUDE.md` §
127
- * Three-layer error-schema merge.
128
- */
129
- is_acting_aware?: IsActingAware;
130
122
  }
131
123
  /**
132
124
  * 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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"}
@@ -7,7 +7,6 @@
7
7
  * @module
8
8
  */
9
9
  import { z } from 'zod';
10
- import { map_action_auth } from '../actions/action_bridge.js';
11
10
  import { schema_to_surface, middleware_applies, merge_error_schemas, is_null_schema, is_strict_object_schema, } from './schema_helpers.js';
12
11
  // --- Surface generation ---
13
12
  /**
@@ -61,7 +60,7 @@ export const events_to_surface = (event_specs) => {
61
60
  * and optional env/event metadata.
62
61
  */
63
62
  export const generate_app_surface = (options) => {
64
- const { route_specs, middleware_specs, env_schema, event_specs, rpc_endpoints, is_acting_aware } = options;
63
+ const { route_specs, middleware_specs, env_schema, event_specs, rpc_endpoints } = options;
65
64
  const diagnostics = [];
66
65
  // Spec-level diagnostics: check for non-strict input schemas
67
66
  for (const r of route_specs) {
@@ -98,7 +97,7 @@ export const generate_app_surface = (options) => {
98
97
  .map((m) => m.name);
99
98
  // Merge auto-derived + middleware + explicit error schemas
100
99
  const mw_errors = collect_middleware_errors(middleware_specs, r.path);
101
- const merged_errors = merge_error_schemas(r, mw_errors, is_acting_aware?.(r) ?? false);
100
+ const merged_errors = merge_error_schemas(r, mw_errors);
102
101
  let error_schemas = null;
103
102
  if (merged_errors) {
104
103
  const schemas = {};
@@ -133,7 +132,7 @@ export const generate_app_surface = (options) => {
133
132
  path: ep.path,
134
133
  methods: ep.actions.map((a) => ({
135
134
  name: a.spec.method,
136
- auth: map_action_auth(a.spec.auth),
135
+ auth: a.spec.auth,
137
136
  input_schema: schema_to_surface(a.spec.input),
138
137
  output_schema: schema_to_surface(a.spec.output),
139
138
  side_effects: a.spec.side_effects,
@@ -4,49 +4,48 @@
4
4
  * Usable in tests, the adversarial auth runner, and future surface explorer UI.
5
5
  * Replaces duplicated inline `.filter()` patterns.
6
6
  *
7
- * TODO @surface-explorer Used by test utilities (test_auth_surface, adversarial_input,
8
- * surface_invariants) and SurfaceExplorer.svelte (surface_auth_summary, format_route_key).
9
- * Several query functions (filter_authenticated_routes, filter_keeper_routes,
10
- * routes_by_auth_type, filter_routes_by_prefix) are pre-built for richer surface
11
- * explorer features and consumer test suites leverage more as the surface UI matures.
7
+ * Categorical filters (`filter_authenticated_routes`, `filter_role_routes`,
8
+ * `filter_keeper_routes`) group the new flat-record `RouteAuth` shape into
9
+ * the legacy categorical buckets (`'authenticated'`, `'role'`, `'keeper'`)
10
+ * for adversarial test runners and the surface explorer. The buckets are
11
+ * derived views over the four axes (`account`, `actor`, `roles`,
12
+ * `credential_types`) — see `http/auth_shape.ts` for the canonical shape.
12
13
  *
13
14
  * @module
14
15
  */
15
16
  import type { AppSurface, AppSurfaceRoute } from './surface.js';
16
17
  /** Filter routes that require any form of authentication. */
17
18
  export declare const filter_protected_routes: (surface: AppSurface) => Array<AppSurfaceRoute>;
18
- /** Filter routes that are publicly accessible (no auth). */
19
+ /** Filter routes that are publicly accessible (no auth surface at all). */
19
20
  export declare const filter_public_routes: (surface: AppSurface) => Array<AppSurfaceRoute>;
20
- /** Filter all role-guarded routes (any role). */
21
- export declare const filter_role_routes: (surface: AppSurface) => Array<AppSurfaceRoute & {
22
- auth: {
23
- type: "role";
24
- role: string;
25
- };
26
- }>;
27
- /** Filter routes that require basic authentication (no specific role). */
28
- export declare const filter_authenticated_routes: (surface: AppSurface) => Array<AppSurfaceRoute & {
29
- auth: {
30
- type: "authenticated";
31
- };
32
- }>;
33
- /** Filter routes that require keeper credentials. */
34
- export declare const filter_keeper_routes: (surface: AppSurface) => Array<AppSurfaceRoute & {
35
- auth: {
36
- type: "keeper";
37
- };
38
- }>;
39
- /** Filter routes that require a specific named role. */
40
- export declare const filter_routes_for_role: (surface: AppSurface, role: string) => Array<AppSurfaceRoute & {
41
- auth: {
42
- type: "role";
43
- role: string;
44
- };
45
- }>;
21
+ /** Filter all role-guarded routes (any role declared on `auth.roles`). */
22
+ export declare const filter_role_routes: (surface: AppSurface) => Array<AppSurfaceRoute>;
46
23
  /**
47
- * Group routes by auth type.
24
+ * Filter routes that require basic authentication only — `account === 'required'`
25
+ * with no role / credential gate.
26
+ */
27
+ export declare const filter_authenticated_routes: (surface: AppSurface) => Array<AppSurfaceRoute>;
28
+ /** Filter routes that require keeper credentials (`daemon_token`). */
29
+ export declare const filter_keeper_routes: (surface: AppSurface) => Array<AppSurfaceRoute>;
30
+ /** Filter routes whose `auth.roles` includes the named role. */
31
+ export declare const filter_routes_for_role: (surface: AppSurface, role: string) => Array<AppSurfaceRoute>;
32
+ /**
33
+ * Categorize a `RouteAuth` into one of the legacy auth buckets.
48
34
  *
49
- * @returns a map from auth type string to route arrays, with role routes keyed as `'role:name'`
35
+ * Returns:
36
+ * - `'none'` for fully public routes (account === 'none' && actor === 'none')
37
+ * - `'keeper'` when `credential_types` includes `'daemon_token'`
38
+ * - `'role:<name>'` for each role declared on `auth.roles` (multi-role specs
39
+ * are emitted multiple times; callers that need single-bucket grouping
40
+ * should pre-collapse)
41
+ * - `'authenticated'` for `account === 'required'` without role / credential gate
42
+ * - `'optional'` when either axis is `'optional'` and no other bucket fits
43
+ * - `'other'` as a last-resort bucket for shapes that don't match above
44
+ */
45
+ export type RouteAuthCategory = 'none' | 'authenticated' | 'optional' | 'keeper' | `role:${string}` | 'other';
46
+ /**
47
+ * Group routes by auth category (see `RouteAuthCategory`). Multi-role specs
48
+ * appear under each of their role buckets.
50
49
  */
51
50
  export declare const routes_by_auth_type: (surface: AppSurface) => Map<string, Array<AppSurfaceRoute>>;
52
51
  /** Filter routes whose path starts with `prefix`. */
@@ -66,12 +65,17 @@ export declare const format_route_key: (route: AppSurfaceRoute) => string;
66
65
  /**
67
66
  * Summarize route auth distribution across the surface.
68
67
  *
69
- * @returns counts by auth type, with role counts broken out by role name
68
+ * Categorical view over the four-axis flat record. Multi-role specs
69
+ * contribute one count per role they admit.
70
+ *
71
+ * @returns counts by auth category, with role counts broken out by role name
70
72
  */
71
73
  export declare const surface_auth_summary: (surface: AppSurface) => {
72
74
  none: number;
73
75
  authenticated: number;
76
+ optional: number;
74
77
  role: Map<string, number>;
75
78
  keeper: number;
79
+ other: number;
76
80
  };
77
81
  //# sourceMappingURL=surface_query.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"surface_query.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/surface_query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,cAAc,CAAC;AAE9D,6DAA6D;AAC7D,eAAO,MAAM,uBAAuB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC9B,CAAC;AAEtD,4DAA4D;AAC5D,eAAO,MAAM,oBAAoB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC3B,CAAC;AAEtD,iDAAiD;AACjD,eAAO,MAAM,kBAAkB,GAC9B,SAAS,UAAU,KACjB,KAAK,CAAC,eAAe,GAAG;IAAC,IAAI,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAA;CAAC,CAG7D,CAAC;AAEH,0EAA0E;AAC1E,eAAO,MAAM,2BAA2B,GACvC,SAAS,UAAU,KACjB,KAAK,CAAC,eAAe,GAAG;IAAC,IAAI,EAAE;QAAC,IAAI,EAAE,eAAe,CAAA;KAAC,CAAA;CAAC,CAGxD,CAAC;AAEH,qDAAqD;AACrD,eAAO,MAAM,oBAAoB,GAChC,SAAS,UAAU,KACjB,KAAK,CAAC,eAAe,GAAG;IAAC,IAAI,EAAE;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAC,CAAA;CAAC,CAGjD,CAAC;AAEH,wDAAwD;AACxD,eAAO,MAAM,sBAAsB,GAClC,SAAS,UAAU,EACnB,MAAM,MAAM,KACV,KAAK,CAAC,eAAe,GAAG;IAAC,IAAI,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAA;CAAC,CAI7D,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,UAAU,KAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,eAAe,CAAC,CAY3F,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,uBAAuB,GACnC,SAAS,UAAU,EACnB,QAAQ,MAAM,KACZ,KAAK,CAAC,eAAe,CAA4D,CAAC;AAErF,uDAAuD;AACvD,eAAO,MAAM,wBAAwB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC9B,CAAC;AAEvD,wDAAwD;AACxD,eAAO,MAAM,yBAAyB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC9B,CAAC;AAExD,uDAAuD;AACvD,eAAO,MAAM,wBAAwB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC9B,CAAC;AAEvD,mEAAmE;AACnE,eAAO,MAAM,sBAAsB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CACtC,CAAC;AAE7C,gDAAgD;AAChD,eAAO,MAAM,0BAA0B,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC9B,CAAC;AAEzD,iEAAiE;AACjE,eAAO,MAAM,gBAAgB,GAAI,OAAO,eAAe,KAAG,MAAyC,CAAC;AAEpG;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAChC,SAAS,UAAU,KACjB;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAwBjF,CAAC"}
1
+ {"version":3,"file":"surface_query.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/surface_query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,cAAc,CAAC;AAQ9D,6DAA6D;AAC7D,eAAO,MAAM,uBAAuB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC7B,CAAC;AAEvD,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC3B,CAAC;AAEtD,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC3B,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CACrB,CAAC;AAEnE,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC3B,CAAC;AAEtD,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,GAAI,SAAS,UAAU,EAAE,MAAM,MAAM,KAAG,KAAK,CAAC,eAAe,CAC5B,CAAC;AAErE;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,iBAAiB,GAC1B,MAAM,GACN,eAAe,GACf,UAAU,GACV,QAAQ,GACR,QAAQ,MAAM,EAAE,GAChB,OAAO,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,UAAU,KAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,eAAe,CAAC,CAmC3F,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,uBAAuB,GACnC,SAAS,UAAU,EACnB,QAAQ,MAAM,KACZ,KAAK,CAAC,eAAe,CAA4D,CAAC;AAErF,uDAAuD;AACvD,eAAO,MAAM,wBAAwB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC9B,CAAC;AAEvD,wDAAwD;AACxD,eAAO,MAAM,yBAAyB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC9B,CAAC;AAExD,uDAAuD;AACvD,eAAO,MAAM,wBAAwB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC9B,CAAC;AAEvD,mEAAmE;AACnE,eAAO,MAAM,sBAAsB,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CACtC,CAAC;AAE7C,gDAAgD;AAChD,eAAO,MAAM,0BAA0B,GAAI,SAAS,UAAU,KAAG,KAAK,CAAC,eAAe,CAC9B,CAAC;AAEzD,iEAAiE;AACjE,eAAO,MAAM,gBAAgB,GAAI,OAAO,eAAe,KAAG,MAAyC,CAAC;AAEpG;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAChC,SAAS,UAAU,KACjB;IACF,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CAqCd,CAAC"}
@@ -4,41 +4,69 @@
4
4
  * Usable in tests, the adversarial auth runner, and future surface explorer UI.
5
5
  * Replaces duplicated inline `.filter()` patterns.
6
6
  *
7
- * TODO @surface-explorer Used by test utilities (test_auth_surface, adversarial_input,
8
- * surface_invariants) and SurfaceExplorer.svelte (surface_auth_summary, format_route_key).
9
- * Several query functions (filter_authenticated_routes, filter_keeper_routes,
10
- * routes_by_auth_type, filter_routes_by_prefix) are pre-built for richer surface
11
- * explorer features and consumer test suites leverage more as the surface UI matures.
7
+ * Categorical filters (`filter_authenticated_routes`, `filter_role_routes`,
8
+ * `filter_keeper_routes`) group the new flat-record `RouteAuth` shape into
9
+ * the legacy categorical buckets (`'authenticated'`, `'role'`, `'keeper'`)
10
+ * for adversarial test runners and the surface explorer. The buckets are
11
+ * derived views over the four axes (`account`, `actor`, `roles`,
12
+ * `credential_types`) — see `http/auth_shape.ts` for the canonical shape.
12
13
  *
13
14
  * @module
14
15
  */
16
+ import { is_keeper_auth, is_plain_authenticated_auth, is_public_auth, is_role_auth, } from './auth_shape.js';
15
17
  /** Filter routes that require any form of authentication. */
16
- export const filter_protected_routes = (surface) => surface.routes.filter((r) => r.auth.type !== 'none');
17
- /** Filter routes that are publicly accessible (no auth). */
18
- export const filter_public_routes = (surface) => surface.routes.filter((r) => r.auth.type === 'none');
19
- /** Filter all role-guarded routes (any role). */
20
- export const filter_role_routes = (surface) => surface.routes.filter((r) => r.auth.type === 'role');
21
- /** Filter routes that require basic authentication (no specific role). */
22
- export const filter_authenticated_routes = (surface) => surface.routes.filter((r) => r.auth.type === 'authenticated');
23
- /** Filter routes that require keeper credentials. */
24
- export const filter_keeper_routes = (surface) => surface.routes.filter((r) => r.auth.type === 'keeper');
25
- /** Filter routes that require a specific named role. */
26
- export const filter_routes_for_role = (surface, role) => surface.routes.filter((r) => r.auth.type === 'role' && r.auth.role === role);
18
+ export const filter_protected_routes = (surface) => surface.routes.filter((r) => !is_public_auth(r.auth));
19
+ /** Filter routes that are publicly accessible (no auth surface at all). */
20
+ export const filter_public_routes = (surface) => surface.routes.filter((r) => is_public_auth(r.auth));
21
+ /** Filter all role-guarded routes (any role declared on `auth.roles`). */
22
+ export const filter_role_routes = (surface) => surface.routes.filter((r) => is_role_auth(r.auth));
27
23
  /**
28
- * Group routes by auth type.
29
- *
30
- * @returns a map from auth type string to route arrays, with role routes keyed as `'role:name'`
24
+ * Filter routes that require basic authentication only — `account === 'required'`
25
+ * with no role / credential gate.
26
+ */
27
+ export const filter_authenticated_routes = (surface) => surface.routes.filter((r) => is_plain_authenticated_auth(r.auth));
28
+ /** Filter routes that require keeper credentials (`daemon_token`). */
29
+ export const filter_keeper_routes = (surface) => surface.routes.filter((r) => is_keeper_auth(r.auth));
30
+ /** Filter routes whose `auth.roles` includes the named role. */
31
+ export const filter_routes_for_role = (surface, role) => surface.routes.filter((r) => r.auth.roles?.includes(role) ?? false);
32
+ /**
33
+ * Group routes by auth category (see `RouteAuthCategory`). Multi-role specs
34
+ * appear under each of their role buckets.
31
35
  */
32
36
  export const routes_by_auth_type = (surface) => {
33
37
  const groups = new Map();
34
- for (const r of surface.routes) {
35
- const key = r.auth.type === 'role' ? `role:${r.auth.role}` : r.auth.type;
38
+ const push = (key, r) => {
36
39
  let group = groups.get(key);
37
40
  if (!group) {
38
41
  group = [];
39
42
  groups.set(key, group);
40
43
  }
41
44
  group.push(r);
45
+ };
46
+ for (const r of surface.routes) {
47
+ const auth = r.auth;
48
+ if (is_public_auth(auth)) {
49
+ push('none', r);
50
+ continue;
51
+ }
52
+ if (is_keeper_auth(auth)) {
53
+ push('keeper', r);
54
+ continue;
55
+ }
56
+ if (is_role_auth(auth)) {
57
+ for (const role of auth.roles)
58
+ push(`role:${role}`, r);
59
+ continue;
60
+ }
61
+ if (is_plain_authenticated_auth(auth)) {
62
+ push('authenticated', r);
63
+ continue;
64
+ }
65
+ if (auth.account === 'optional' || auth.actor === 'optional') {
66
+ push('optional', r);
67
+ continue;
68
+ }
69
+ push('other', r);
42
70
  }
43
71
  return groups;
44
72
  };
@@ -59,28 +87,43 @@ export const format_route_key = (route) => `${route.method} ${route.path}`;
59
87
  /**
60
88
  * Summarize route auth distribution across the surface.
61
89
  *
62
- * @returns counts by auth type, with role counts broken out by role name
90
+ * Categorical view over the four-axis flat record. Multi-role specs
91
+ * contribute one count per role they admit.
92
+ *
93
+ * @returns counts by auth category, with role counts broken out by role name
63
94
  */
64
95
  export const surface_auth_summary = (surface) => {
65
96
  let none = 0;
66
97
  let authenticated = 0;
98
+ let optional = 0;
67
99
  const role = new Map();
68
100
  let keeper = 0;
101
+ let other = 0;
69
102
  for (const r of surface.routes) {
70
- switch (r.auth.type) {
71
- case 'none':
72
- none++;
73
- break;
74
- case 'authenticated':
75
- authenticated++;
76
- break;
77
- case 'role':
78
- role.set(r.auth.role, (role.get(r.auth.role) ?? 0) + 1);
79
- break;
80
- case 'keeper':
81
- keeper++;
82
- break;
103
+ const auth = r.auth;
104
+ if (is_public_auth(auth)) {
105
+ none++;
106
+ continue;
107
+ }
108
+ if (is_keeper_auth(auth)) {
109
+ keeper++;
110
+ continue;
111
+ }
112
+ if (is_role_auth(auth)) {
113
+ for (const r_name of auth.roles) {
114
+ role.set(r_name, (role.get(r_name) ?? 0) + 1);
115
+ }
116
+ continue;
117
+ }
118
+ if (is_plain_authenticated_auth(auth)) {
119
+ authenticated++;
120
+ continue;
121
+ }
122
+ if (auth.account === 'optional' || auth.actor === 'optional') {
123
+ optional++;
124
+ continue;
83
125
  }
126
+ other++;
84
127
  }
85
- return { none, authenticated, role, keeper };
128
+ return { none, authenticated, optional, role, keeper, other };
86
129
  };