@fuzdev/fuz_app 0.54.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.
- package/dist/actions/CLAUDE.md +214 -103
- package/dist/actions/action_bridge.d.ts +8 -5
- package/dist/actions/action_bridge.d.ts.map +1 -1
- package/dist/actions/action_bridge.js +1 -11
- package/dist/actions/action_codegen.d.ts +32 -0
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +35 -15
- package/dist/actions/action_registry.d.ts.map +1 -1
- package/dist/actions/action_registry.js +5 -2
- package/dist/actions/action_rpc.d.ts +141 -22
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +106 -187
- package/dist/actions/action_spec.d.ts +55 -16
- package/dist/actions/action_spec.d.ts.map +1 -1
- package/dist/actions/action_spec.js +16 -11
- package/dist/actions/action_types.d.ts +28 -60
- package/dist/actions/action_types.d.ts.map +1 -1
- package/dist/actions/action_types.js +13 -5
- package/dist/actions/broadcast_api.d.ts +2 -2
- package/dist/actions/broadcast_api.js +2 -2
- package/dist/actions/compile_action_registry.d.ts +50 -0
- package/dist/actions/compile_action_registry.d.ts.map +1 -0
- package/dist/actions/compile_action_registry.js +69 -0
- package/dist/actions/heartbeat.d.ts +8 -4
- package/dist/actions/heartbeat.d.ts.map +1 -1
- package/dist/actions/heartbeat.js +5 -4
- package/dist/actions/perform_action.d.ts +145 -0
- package/dist/actions/perform_action.d.ts.map +1 -0
- package/dist/actions/perform_action.js +258 -0
- package/dist/actions/register_action_ws.d.ts +46 -40
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +101 -159
- package/dist/actions/register_ws_endpoint.d.ts +15 -10
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +54 -7
- package/dist/actions/transports.d.ts.map +1 -1
- package/dist/actions/transports.js +0 -4
- package/dist/actions/transports_ws_auth_guard.d.ts +1 -1
- package/dist/actions/transports_ws_auth_guard.js +1 -1
- package/dist/actions/transports_ws_backend.d.ts +1 -1
- package/dist/actions/transports_ws_backend.js +1 -1
- package/dist/auth/CLAUDE.md +794 -410
- package/dist/auth/account_action_specs.d.ts +28 -7
- package/dist/auth/account_action_specs.d.ts.map +1 -1
- package/dist/auth/account_action_specs.js +7 -7
- package/dist/auth/account_actions.d.ts +7 -13
- package/dist/auth/account_actions.d.ts.map +1 -1
- package/dist/auth/account_actions.js +26 -35
- package/dist/auth/account_queries.d.ts +52 -16
- package/dist/auth/account_queries.d.ts.map +1 -1
- package/dist/auth/account_queries.js +87 -38
- package/dist/auth/account_routes.d.ts +9 -11
- package/dist/auth/account_routes.d.ts.map +1 -1
- package/dist/auth/account_routes.js +118 -46
- package/dist/auth/account_schema.d.ts +46 -35
- package/dist/auth/account_schema.d.ts.map +1 -1
- package/dist/auth/account_schema.js +21 -28
- package/dist/auth/admin_action_specs.d.ts +100 -32
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_action_specs.js +64 -33
- package/dist/auth/admin_actions.d.ts +13 -19
- package/dist/auth/admin_actions.d.ts.map +1 -1
- package/dist/auth/admin_actions.js +37 -41
- package/dist/auth/audit_emitter.d.ts +160 -0
- package/dist/auth/audit_emitter.d.ts.map +1 -0
- package/dist/auth/audit_emitter.js +83 -0
- package/dist/auth/audit_log_queries.d.ts +17 -48
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.js +20 -56
- package/dist/auth/audit_log_routes.d.ts +1 -1
- package/dist/auth/audit_log_routes.d.ts.map +1 -1
- package/dist/auth/audit_log_routes.js +7 -3
- package/dist/auth/audit_log_schema.d.ts +92 -32
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +75 -46
- package/dist/auth/auth_guard_resolver.d.ts +44 -0
- package/dist/auth/auth_guard_resolver.d.ts.map +1 -0
- package/dist/auth/auth_guard_resolver.js +56 -0
- package/dist/auth/bearer_auth.d.ts +9 -7
- package/dist/auth/bearer_auth.d.ts.map +1 -1
- package/dist/auth/bearer_auth.js +13 -21
- package/dist/auth/bootstrap_account.d.ts +7 -7
- package/dist/auth/bootstrap_account.d.ts.map +1 -1
- package/dist/auth/bootstrap_account.js +7 -7
- package/dist/auth/bootstrap_routes.d.ts.map +1 -1
- package/dist/auth/bootstrap_routes.js +11 -10
- package/dist/auth/cleanup.d.ts +20 -26
- package/dist/auth/cleanup.d.ts.map +1 -1
- package/dist/auth/cleanup.js +33 -42
- package/dist/auth/credential_type_schema.d.ts +115 -0
- package/dist/auth/credential_type_schema.d.ts.map +1 -0
- package/dist/auth/credential_type_schema.js +127 -0
- package/dist/auth/daemon_token_middleware.d.ts +23 -11
- package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
- package/dist/auth/daemon_token_middleware.js +28 -22
- package/dist/auth/ddl.d.ts +2 -2
- package/dist/auth/ddl.d.ts.map +1 -1
- package/dist/auth/ddl.js +6 -6
- package/dist/auth/deps.d.ts +7 -18
- package/dist/auth/deps.d.ts.map +1 -1
- package/dist/auth/grant_path_schema.d.ts +117 -0
- package/dist/auth/grant_path_schema.d.ts.map +1 -0
- package/dist/auth/grant_path_schema.js +137 -0
- package/dist/auth/invite_queries.d.ts +12 -1
- package/dist/auth/invite_queries.d.ts.map +1 -1
- package/dist/auth/invite_queries.js +12 -1
- package/dist/auth/invite_schema.d.ts +1 -1
- package/dist/auth/invite_schema.d.ts.map +1 -1
- package/dist/auth/invite_schema.js +1 -1
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +9 -4
- package/dist/auth/migrations.d.ts +37 -14
- package/dist/auth/migrations.d.ts.map +1 -1
- package/dist/auth/migrations.js +79 -32
- package/dist/auth/request_context.d.ts +331 -61
- package/dist/auth/request_context.d.ts.map +1 -1
- package/dist/auth/request_context.js +378 -95
- package/dist/auth/{permit_offer_action_specs.d.ts → role_grant_offer_action_specs.d.ts} +163 -94
- package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -0
- package/dist/auth/role_grant_offer_action_specs.js +262 -0
- package/dist/auth/role_grant_offer_actions.d.ts +104 -0
- package/dist/auth/role_grant_offer_actions.d.ts.map +1 -0
- package/dist/auth/role_grant_offer_actions.js +473 -0
- package/dist/auth/{permit_offer_notifications.d.ts → role_grant_offer_notifications.d.ts} +90 -70
- package/dist/auth/role_grant_offer_notifications.d.ts.map +1 -0
- package/dist/auth/role_grant_offer_notifications.js +182 -0
- package/dist/auth/role_grant_offer_queries.d.ts +242 -0
- package/dist/auth/role_grant_offer_queries.d.ts.map +1 -0
- package/dist/auth/role_grant_offer_queries.js +533 -0
- package/dist/auth/role_grant_offer_schema.d.ts +150 -0
- package/dist/auth/role_grant_offer_schema.d.ts.map +1 -0
- package/dist/auth/{permit_offer_schema.js → role_grant_offer_schema.js} +60 -36
- package/dist/auth/role_grant_queries.d.ts +231 -0
- package/dist/auth/role_grant_queries.d.ts.map +1 -0
- package/dist/auth/role_grant_queries.js +320 -0
- package/dist/auth/role_schema.d.ts +150 -40
- package/dist/auth/role_schema.d.ts.map +1 -1
- package/dist/auth/role_schema.js +144 -45
- package/dist/auth/scope_kind_schema.d.ts +96 -0
- package/dist/auth/scope_kind_schema.d.ts.map +1 -0
- package/dist/auth/scope_kind_schema.js +94 -0
- package/dist/auth/self_service_role_action_specs.d.ts +6 -1
- package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
- package/dist/auth/self_service_role_action_specs.js +3 -1
- package/dist/auth/self_service_role_actions.d.ts +34 -27
- package/dist/auth/self_service_role_actions.d.ts.map +1 -1
- package/dist/auth/self_service_role_actions.js +68 -48
- package/dist/auth/session_cookie.d.ts +43 -6
- package/dist/auth/session_cookie.d.ts.map +1 -1
- package/dist/auth/session_cookie.js +31 -5
- package/dist/auth/session_middleware.d.ts +37 -3
- package/dist/auth/session_middleware.d.ts.map +1 -1
- package/dist/auth/session_middleware.js +33 -7
- package/dist/auth/signup_routes.d.ts.map +1 -1
- package/dist/auth/signup_routes.js +48 -19
- package/dist/auth/standard_action_specs.d.ts +2 -2
- package/dist/auth/standard_action_specs.js +4 -4
- package/dist/auth/standard_rpc_actions.d.ts +23 -19
- package/dist/auth/standard_rpc_actions.d.ts.map +1 -1
- package/dist/auth/standard_rpc_actions.js +12 -12
- package/dist/db/migrate.d.ts +12 -8
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +10 -7
- package/dist/dev/setup.d.ts +2 -2
- package/dist/dev/setup.d.ts.map +1 -1
- package/dist/dev/setup.js +9 -7
- package/dist/env/load.d.ts +1 -1
- package/dist/env/load.js +1 -1
- package/dist/hono_context.d.ts +64 -5
- package/dist/hono_context.d.ts.map +1 -1
- package/dist/hono_context.js +38 -2
- package/dist/http/CLAUDE.md +264 -87
- package/dist/http/auth_shape.d.ts +191 -0
- package/dist/http/auth_shape.d.ts.map +1 -0
- package/dist/http/auth_shape.js +237 -0
- package/dist/http/common_routes.js +3 -3
- package/dist/http/db_routes.d.ts +4 -0
- package/dist/http/db_routes.d.ts.map +1 -1
- package/dist/http/db_routes.js +44 -7
- package/dist/http/error_schemas.d.ts +132 -19
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +132 -40
- package/dist/http/jsonrpc_errors.d.ts +27 -2
- package/dist/http/jsonrpc_errors.d.ts.map +1 -1
- package/dist/http/jsonrpc_errors.js +26 -2
- package/dist/http/pending_effects.d.ts +71 -18
- package/dist/http/pending_effects.d.ts.map +1 -1
- package/dist/http/pending_effects.js +87 -18
- package/dist/http/proxy.d.ts +52 -5
- package/dist/http/proxy.d.ts.map +1 -1
- package/dist/http/proxy.js +92 -14
- package/dist/http/route_spec.d.ts +113 -41
- package/dist/http/route_spec.d.ts.map +1 -1
- package/dist/http/route_spec.js +130 -52
- package/dist/http/schema_helpers.d.ts +3 -2
- package/dist/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +9 -2
- package/dist/http/surface.d.ts +2 -1
- package/dist/http/surface.d.ts.map +1 -1
- package/dist/http/surface.js +1 -2
- package/dist/http/surface_query.d.ts +39 -35
- package/dist/http/surface_query.d.ts.map +1 -1
- package/dist/http/surface_query.js +79 -36
- package/dist/primitive_schemas.d.ts +39 -0
- package/dist/primitive_schemas.d.ts.map +1 -0
- package/dist/primitive_schemas.js +40 -0
- package/dist/realtime/sse_auth_guard.d.ts +5 -5
- package/dist/realtime/sse_auth_guard.js +9 -9
- package/dist/runtime/mock.d.ts +1 -1
- package/dist/runtime/mock.js +1 -1
- package/dist/server/app_backend.d.ts +14 -11
- package/dist/server/app_backend.d.ts.map +1 -1
- package/dist/server/app_backend.js +12 -8
- package/dist/server/app_server.d.ts +7 -7
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +36 -31
- package/dist/server/validate_nginx.d.ts +1 -1
- package/dist/server/validate_nginx.js +1 -1
- package/dist/testing/CLAUDE.md +73 -55
- package/dist/testing/admin_integration.d.ts +5 -6
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +100 -96
- package/dist/testing/adversarial_headers.js +1 -1
- package/dist/testing/app_server.d.ts +11 -14
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +18 -17
- package/dist/testing/assertions.d.ts.map +1 -1
- package/dist/testing/assertions.js +2 -1
- package/dist/testing/attack_surface.d.ts.map +1 -1
- package/dist/testing/attack_surface.js +15 -9
- package/dist/testing/audit_completeness.d.ts +2 -2
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +53 -39
- package/dist/testing/auth_apps.d.ts +5 -4
- package/dist/testing/auth_apps.d.ts.map +1 -1
- package/dist/testing/auth_apps.js +28 -22
- package/dist/testing/data_exposure.d.ts.map +1 -1
- package/dist/testing/data_exposure.js +5 -5
- package/dist/testing/db.d.ts +1 -1
- package/dist/testing/db.d.ts.map +1 -1
- package/dist/testing/db.js +4 -4
- package/dist/testing/db_entities.d.ts +22 -0
- package/dist/testing/db_entities.d.ts.map +1 -0
- package/dist/testing/db_entities.js +28 -0
- package/dist/testing/entities.d.ts +10 -8
- package/dist/testing/entities.d.ts.map +1 -1
- package/dist/testing/entities.js +22 -18
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +13 -14
- package/dist/testing/integration_helpers.d.ts +8 -6
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/integration_helpers.js +29 -23
- package/dist/testing/middleware.d.ts +15 -11
- package/dist/testing/middleware.d.ts.map +1 -1
- package/dist/testing/middleware.js +75 -32
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.js +40 -24
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.js +3 -1
- package/dist/testing/rpc_round_trip.d.ts +1 -1
- package/dist/testing/rpc_round_trip.d.ts.map +1 -1
- package/dist/testing/rpc_round_trip.js +14 -13
- package/dist/testing/sse_round_trip.d.ts +3 -4
- package/dist/testing/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/sse_round_trip.js +7 -11
- package/dist/testing/standard.d.ts +1 -1
- package/dist/testing/stubs.d.ts +25 -0
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +43 -2
- package/dist/testing/surface_invariants.d.ts +2 -2
- package/dist/testing/ws_round_trip.d.ts +12 -13
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/ws_round_trip.js +24 -12
- package/dist/ui/AdminAccounts.svelte +23 -20
- package/dist/ui/AdminOverview.svelte +15 -13
- package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
- package/dist/ui/{AdminPermitHistory.svelte → AdminRoleGrantHistory.svelte} +12 -12
- package/dist/ui/AdminRoleGrantHistory.svelte.d.ts +4 -0
- package/dist/ui/AdminRoleGrantHistory.svelte.d.ts.map +1 -0
- package/dist/ui/BootstrapForm.svelte +1 -1
- package/dist/ui/CLAUDE.md +65 -59
- package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +37 -22
- package/dist/ui/RoleGrantOfferForm.svelte.d.ts +20 -0
- package/dist/ui/RoleGrantOfferForm.svelte.d.ts.map +1 -0
- package/dist/ui/{PermitOfferHistory.svelte → RoleGrantOfferHistory.svelte} +12 -12
- package/dist/ui/{PermitOfferHistory.svelte.d.ts → RoleGrantOfferHistory.svelte.d.ts} +4 -4
- package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -0
- package/dist/ui/{PermitOfferInbox.svelte → RoleGrantOfferInbox.svelte} +14 -14
- package/dist/ui/{PermitOfferInbox.svelte.d.ts → RoleGrantOfferInbox.svelte.d.ts} +4 -4
- package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -0
- package/dist/ui/SignupForm.svelte +1 -1
- package/dist/ui/SurfaceExplorer.svelte +35 -15
- package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
- package/dist/ui/account_sessions_state.svelte.d.ts +2 -3
- package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
- package/dist/ui/account_sessions_state.svelte.js +2 -3
- package/dist/ui/admin_accounts_state.svelte.d.ts +25 -18
- package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
- package/dist/ui/admin_accounts_state.svelte.js +28 -17
- package/dist/ui/admin_rpc_adapters.d.ts +20 -20
- package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
- package/dist/ui/admin_rpc_adapters.js +17 -17
- package/dist/ui/admin_sessions_state.svelte.d.ts +2 -2
- package/dist/ui/admin_sessions_state.svelte.js +2 -2
- package/dist/ui/audit_log_state.svelte.d.ts +7 -7
- package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
- package/dist/ui/audit_log_state.svelte.js +6 -6
- package/dist/ui/auth_state.svelte.d.ts +3 -3
- package/dist/ui/auth_state.svelte.d.ts.map +1 -1
- package/dist/ui/auth_state.svelte.js +6 -6
- package/dist/ui/format_scope.d.ts +2 -2
- package/dist/ui/format_scope.js +2 -2
- package/dist/ui/{permit_offers_state.svelte.d.ts → role_grant_offers_state.svelte.d.ts} +39 -31
- package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -0
- package/dist/ui/{permit_offers_state.svelte.js → role_grant_offers_state.svelte.js} +25 -19
- package/dist/ui/ui_format.js +2 -2
- package/package.json +3 -3
- package/dist/auth/permit_offer_action_specs.d.ts.map +0 -1
- package/dist/auth/permit_offer_action_specs.js +0 -227
- package/dist/auth/permit_offer_actions.d.ts +0 -110
- package/dist/auth/permit_offer_actions.d.ts.map +0 -1
- package/dist/auth/permit_offer_actions.js +0 -452
- package/dist/auth/permit_offer_notifications.d.ts.map +0 -1
- package/dist/auth/permit_offer_notifications.js +0 -182
- package/dist/auth/permit_offer_queries.d.ts +0 -183
- package/dist/auth/permit_offer_queries.d.ts.map +0 -1
- package/dist/auth/permit_offer_queries.js +0 -408
- package/dist/auth/permit_offer_schema.d.ts +0 -103
- package/dist/auth/permit_offer_schema.d.ts.map +0 -1
- package/dist/auth/permit_queries.d.ts +0 -210
- package/dist/auth/permit_queries.d.ts.map +0 -1
- package/dist/auth/permit_queries.js +0 -294
- package/dist/auth/require_keeper.d.ts +0 -20
- package/dist/auth/require_keeper.d.ts.map +0 -1
- package/dist/auth/require_keeper.js +0 -35
- package/dist/auth/route_guards.d.ts +0 -21
- package/dist/auth/route_guards.d.ts.map +0 -1
- package/dist/auth/route_guards.js +0 -32
- package/dist/auth/session_lifecycle.d.ts +0 -37
- package/dist/auth/session_lifecycle.d.ts.map +0 -1
- package/dist/auth/session_lifecycle.js +0 -29
- package/dist/ui/AdminPermitHistory.svelte.d.ts +0 -4
- package/dist/ui/AdminPermitHistory.svelte.d.ts.map +0 -1
- package/dist/ui/PermitOfferForm.svelte.d.ts +0 -14
- package/dist/ui/PermitOfferForm.svelte.d.ts.map +0 -1
- package/dist/ui/PermitOfferHistory.svelte.d.ts.map +0 -1
- package/dist/ui/PermitOfferInbox.svelte.d.ts.map +0 -1
- package/dist/ui/permit_offers_state.svelte.d.ts.map +0 -1
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport-agnostic dispatch core shared by HTTP RPC and WebSocket
|
|
3
|
+
* action dispatchers.
|
|
4
|
+
*
|
|
5
|
+
* `perform_action` runs the post-parse pipeline that every action-spec
|
|
6
|
+
* handler must traverse:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Pre-validation auth (401)** — short-circuits unauthenticated callers
|
|
9
|
+
* on `'required'` axes before input validation runs, so callers never
|
|
10
|
+
* see `invalid_params` for methods with required input.
|
|
11
|
+
* 2. **Validate params (400)** — `spec.input.safeParse(raw_params)` with
|
|
12
|
+
* `z.void()` / `?? {}` rules. The validated input lands inside the
|
|
13
|
+
* function so the authorization phase reads `acting` as a typed Zod
|
|
14
|
+
* field.
|
|
15
|
+
* 3. **Authorization phase** — when `auth.actor !== 'none'` (or
|
|
16
|
+
* `auth.account !== 'none' && actor === 'none'`), resolves the actor
|
|
17
|
+
* via `apply_authorization_phase` against the supplied `account_id`
|
|
18
|
+
* plus `validated_input.acting`. Failures fold into a JSON-RPC error
|
|
19
|
+
* envelope. The test-harness escape hatch lives in the caller — pass
|
|
20
|
+
* `preset.request_context` to skip the live phase and use a pre-baked
|
|
21
|
+
* context instead.
|
|
22
|
+
* 4. **Post-authorization auth (403)** — gates `auth.credential_types` and
|
|
23
|
+
* `auth.roles` against the resolved context.
|
|
24
|
+
* 5. **Rate limit (429)** — per-action IP / account throttling, throttle-
|
|
25
|
+
* requests semantics (every invocation records, regardless of outcome).
|
|
26
|
+
* 6. **Dispatch + DEV-only output validation + error normalization** —
|
|
27
|
+
* `spec.side_effects` picks transaction (`deps.db.transaction`) vs
|
|
28
|
+
* pool. Handler throws roll back the transaction; the catch sits
|
|
29
|
+
* outside the transaction boundary. Handler outputs are validated
|
|
30
|
+
* against `spec.output` under DEV (logs an error on mismatch, never
|
|
31
|
+
* throws, never mutates the result).
|
|
32
|
+
*
|
|
33
|
+
* The function is pure data — it never touches a Hono context, so HTTP
|
|
34
|
+
* RPC, REST bridge (when on the action surface), and WS dispatch all
|
|
35
|
+
* call into it the same way and bind the discriminated
|
|
36
|
+
* `PerformActionResult` to their wire shape.
|
|
37
|
+
*
|
|
38
|
+
* @module
|
|
39
|
+
*/
|
|
40
|
+
import { DEV } from 'esm-env';
|
|
41
|
+
import { apply_authorization_phase, has_any_scoped_role, } from '../auth/request_context.js';
|
|
42
|
+
import {} from '../hono_context.js';
|
|
43
|
+
import { is_void_schema } from '../http/schema_helpers.js';
|
|
44
|
+
import { JSONRPC_VERSION, } from '../http/jsonrpc.js';
|
|
45
|
+
import { jsonrpc_error_messages, jsonrpc_error_code_to_http_status, http_status_to_jsonrpc_error_code, JSONRPC_ERROR_CODES, } from '../http/jsonrpc_errors.js';
|
|
46
|
+
import { ERROR_INSUFFICIENT_PERMISSIONS, ERROR_CREDENTIAL_TYPE_REQUIRED, } from '../http/error_schemas.js';
|
|
47
|
+
import { is_public_auth } from '../http/auth_shape.js';
|
|
48
|
+
/**
|
|
49
|
+
* The shared dispatch core. Pure data — no Hono context, no socket. Each
|
|
50
|
+
* transport calls into this with pre-parsed inputs and binds the result
|
|
51
|
+
* to its wire shape.
|
|
52
|
+
*
|
|
53
|
+
* Phase order: 401 → 400 → 403 → handler. On the test-preset path the
|
|
54
|
+
* dispatcher skips the live authorization phase and uses the supplied
|
|
55
|
+
* pre-baked context for post-authorization checks; pre-validation 401
|
|
56
|
+
* still fires when the harness omits `account_id`.
|
|
57
|
+
*/
|
|
58
|
+
export const perform_action = async (input, deps) => {
|
|
59
|
+
const { action, raw_params, request_id: id, account_id, credential_type, client_ip, signal, notify, connection_id, preset, } = input;
|
|
60
|
+
const { db, pending_effects, post_commit_effects, log, action_ip_rate_limiter, action_account_rate_limiter, } = deps;
|
|
61
|
+
const { spec, handler } = action;
|
|
62
|
+
const action_auth = spec.auth;
|
|
63
|
+
// step 1: pre-validation auth — 401 short-circuit before input validation.
|
|
64
|
+
const pre = check_action_auth_pre_validation(action_auth, account_id);
|
|
65
|
+
if (pre)
|
|
66
|
+
return error_result(pre);
|
|
67
|
+
// step 2: validate params. JSON-RPC 2.0 §4.2 forbids `params: null`;
|
|
68
|
+
// registration sites reject `z.null()` inputs. Empty-body convention
|
|
69
|
+
// (`raw_params ?? {}`) lets all-optional-object methods omit `params`.
|
|
70
|
+
const params = is_void_schema(spec.input) ? raw_params : (raw_params ?? {});
|
|
71
|
+
const parse_result = spec.input.safeParse(params);
|
|
72
|
+
if (!parse_result.success) {
|
|
73
|
+
return error_result(jsonrpc_error_messages.invalid_params('invalid params', {
|
|
74
|
+
issues: parse_result.error.issues,
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
const validated_input = parse_result.data;
|
|
78
|
+
// step 3: authorization phase. `acting` reads off the typed Zod field
|
|
79
|
+
// validated in step 2. Per registry-time invariant 2,
|
|
80
|
+
// `auth.actor !== 'none' ⟺ input declares acting?: ActingActor` — so
|
|
81
|
+
// the typed read is safe whenever the dispatcher needs it.
|
|
82
|
+
let request_context = null;
|
|
83
|
+
if (preset !== undefined) {
|
|
84
|
+
request_context = preset.request_context;
|
|
85
|
+
}
|
|
86
|
+
else if (!is_public_auth(action_auth)) {
|
|
87
|
+
const validated_with_acting = validated_input;
|
|
88
|
+
const acting_value = validated_with_acting && typeof validated_with_acting.acting === 'string'
|
|
89
|
+
? validated_with_acting.acting
|
|
90
|
+
: undefined;
|
|
91
|
+
const result = await apply_authorization_phase({ db }, account_id, action_auth, acting_value);
|
|
92
|
+
if (!result.ok) {
|
|
93
|
+
const { error: reason, ...rest } = result.body;
|
|
94
|
+
const code = http_status_to_jsonrpc_error_code(result.status);
|
|
95
|
+
return {
|
|
96
|
+
kind: 'error',
|
|
97
|
+
status: result.status,
|
|
98
|
+
error: { code, message: reason, data: { reason, ...rest } },
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// `request_context: null` covers public actions and the
|
|
102
|
+
// unauthenticated-optional axis; the handler sees null in either case.
|
|
103
|
+
request_context = result.request_context;
|
|
104
|
+
}
|
|
105
|
+
// step 4: post-authorization auth — credential gate first, role gate second.
|
|
106
|
+
const post = check_action_auth_post_authorization(action_auth, request_context, credential_type);
|
|
107
|
+
if (post)
|
|
108
|
+
return error_result(post);
|
|
109
|
+
// step 5: rate limit — throttle-requests semantics (record on every
|
|
110
|
+
// invocation, no success-reset). Same limiters shared with the WS
|
|
111
|
+
// dispatcher so an attacker can't switch transports to bypass the budget.
|
|
112
|
+
const rate_limit = spec.rate_limit;
|
|
113
|
+
if (rate_limit) {
|
|
114
|
+
const ip_check = action_ip_rate_limiter && (rate_limit === 'ip' || rate_limit === 'both');
|
|
115
|
+
const account_keyed_context = action_account_rate_limiter &&
|
|
116
|
+
request_context !== null &&
|
|
117
|
+
(rate_limit === 'account' || rate_limit === 'both')
|
|
118
|
+
? request_context
|
|
119
|
+
: null;
|
|
120
|
+
if (ip_check) {
|
|
121
|
+
const result = action_ip_rate_limiter.check(client_ip);
|
|
122
|
+
if (!result.allowed)
|
|
123
|
+
return rate_limited_result(result.retry_after);
|
|
124
|
+
}
|
|
125
|
+
if (account_keyed_context) {
|
|
126
|
+
const result = action_account_rate_limiter.check(account_keyed_context.account.id);
|
|
127
|
+
if (!result.allowed)
|
|
128
|
+
return rate_limited_result(result.retry_after);
|
|
129
|
+
}
|
|
130
|
+
if (ip_check)
|
|
131
|
+
action_ip_rate_limiter.record(client_ip);
|
|
132
|
+
if (account_keyed_context) {
|
|
133
|
+
action_account_rate_limiter.record(account_keyed_context.account.id);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// step 6: dispatch — transaction for mutations, pool for reads.
|
|
137
|
+
const use_transaction = spec.side_effects;
|
|
138
|
+
const execute = async (effective_db) => {
|
|
139
|
+
const action_context = {
|
|
140
|
+
auth: request_context,
|
|
141
|
+
request_id: id,
|
|
142
|
+
connection_id,
|
|
143
|
+
db: effective_db,
|
|
144
|
+
pending_effects,
|
|
145
|
+
post_commit_effects,
|
|
146
|
+
client_ip,
|
|
147
|
+
log,
|
|
148
|
+
notify,
|
|
149
|
+
signal,
|
|
150
|
+
};
|
|
151
|
+
const output = await handler(validated_input, action_context);
|
|
152
|
+
// DEV-only output validation — logs on mismatch, never throws.
|
|
153
|
+
if (DEV) {
|
|
154
|
+
const output_result = spec.output.safeParse(output);
|
|
155
|
+
if (!output_result.success) {
|
|
156
|
+
log.error(`action output schema mismatch: ${spec.method}`, output_result.error.issues);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return { kind: 'ok', result: output };
|
|
160
|
+
};
|
|
161
|
+
try {
|
|
162
|
+
if (use_transaction) {
|
|
163
|
+
return await db.transaction((tx) => execute(tx));
|
|
164
|
+
}
|
|
165
|
+
return await execute(db);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
// Duck-type check: Error with numeric `code` signals a JSON-RPC error.
|
|
169
|
+
// Avoids cross-realm `instanceof` misses when consumers throw their own
|
|
170
|
+
// `ThrownJsonrpcError` (structurally identical, different class identity).
|
|
171
|
+
const error_like = err;
|
|
172
|
+
if (err instanceof Error && typeof error_like.code === 'number') {
|
|
173
|
+
const code = error_like.code;
|
|
174
|
+
const status = jsonrpc_error_code_to_http_status(code);
|
|
175
|
+
const error = { code, message: err.message };
|
|
176
|
+
if (error_like.data !== undefined)
|
|
177
|
+
error.data = error_like.data;
|
|
178
|
+
return { kind: 'error', status, error };
|
|
179
|
+
}
|
|
180
|
+
log.error(`unhandled action handler error: ${spec.method}`, err);
|
|
181
|
+
const message = DEV && err instanceof Error ? err.message : 'internal server error';
|
|
182
|
+
return error_result(jsonrpc_error_messages.internal_error(message));
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
const error_result = (error) => ({
|
|
186
|
+
kind: 'error',
|
|
187
|
+
error,
|
|
188
|
+
status: jsonrpc_error_code_to_http_status(error.code),
|
|
189
|
+
});
|
|
190
|
+
const rate_limited_result = (retry_after) => {
|
|
191
|
+
const error = jsonrpc_error_messages.rate_limited('rate limited', { retry_after });
|
|
192
|
+
return {
|
|
193
|
+
kind: 'error',
|
|
194
|
+
error,
|
|
195
|
+
status: jsonrpc_error_code_to_http_status(JSONRPC_ERROR_CODES.rate_limited),
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* Pre-validation auth gate — fires before input validation so missing
|
|
200
|
+
* credentials short-circuit with `unauthenticated` instead of leaking
|
|
201
|
+
* a `invalid_params` error for methods with required input.
|
|
202
|
+
*
|
|
203
|
+
* 401 fires when `auth.account === 'required'` (or `auth.actor === 'required'`,
|
|
204
|
+
* since registry-time invariant 3 forbids accountless actors in v1) and
|
|
205
|
+
* no account is on the request. `'optional'` axes pass through — the
|
|
206
|
+
* authorization phase decides based on whatever the credential supports.
|
|
207
|
+
*/
|
|
208
|
+
const check_action_auth_pre_validation = (auth, account_id) => {
|
|
209
|
+
if (auth.account === 'required' || auth.actor === 'required') {
|
|
210
|
+
if (account_id == null)
|
|
211
|
+
return jsonrpc_error_messages.unauthenticated();
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Post-authorization auth gate — fires after the authorization phase
|
|
217
|
+
* resolved the actor + role_grants. Enforces `auth.credential_types` and
|
|
218
|
+
* `auth.roles`.
|
|
219
|
+
*
|
|
220
|
+
* Credential gate fires first: if the spec restricts credential types
|
|
221
|
+
* and the request didn't arrive on one of them, emit
|
|
222
|
+
* `ERROR_CREDENTIAL_TYPE_REQUIRED` 403 with `required_credential_types`
|
|
223
|
+
* echoing the spec's allowlist (symmetric with the role gate's
|
|
224
|
+
* `required_roles`).
|
|
225
|
+
*
|
|
226
|
+
* Role gate fires second: if the spec declares any roles and the actor
|
|
227
|
+
* doesn't hold one globally, emit `ERROR_INSUFFICIENT_PERMISSIONS` 403
|
|
228
|
+
* with `required_roles` (the multi-role disjunction).
|
|
229
|
+
*/
|
|
230
|
+
const check_action_auth_post_authorization = (auth, request_context, credential_type) => {
|
|
231
|
+
if (auth.credential_types?.length) {
|
|
232
|
+
if (!credential_type || !auth.credential_types.includes(credential_type)) {
|
|
233
|
+
return jsonrpc_error_messages.forbidden('forbidden', {
|
|
234
|
+
reason: ERROR_CREDENTIAL_TYPE_REQUIRED,
|
|
235
|
+
required_credential_types: auth.credential_types,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (auth.roles?.length) {
|
|
240
|
+
if (!has_any_scoped_role(request_context, auth.roles, null)) {
|
|
241
|
+
return jsonrpc_error_messages.forbidden(`requires role: ${auth.roles.join(' or ')}`, {
|
|
242
|
+
reason: ERROR_INSUFFICIENT_PERMISSIONS,
|
|
243
|
+
required_roles: auth.roles,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* Build a JSON-RPC response envelope from a `PerformActionResult` for
|
|
251
|
+
* transports that wire over the JSON-RPC 2.0 message shape (HTTP RPC + WS).
|
|
252
|
+
*/
|
|
253
|
+
export const perform_action_result_to_envelope = (id, result) => {
|
|
254
|
+
if (result.kind === 'ok') {
|
|
255
|
+
return { jsonrpc: JSONRPC_VERSION, id, result: result.result };
|
|
256
|
+
}
|
|
257
|
+
return { jsonrpc: JSONRPC_VERSION, id, error: result.error };
|
|
258
|
+
};
|
|
@@ -2,40 +2,39 @@
|
|
|
2
2
|
* WebSocket JSON-RPC dispatch — the low-level WS transport binding.
|
|
3
3
|
*
|
|
4
4
|
* Most consumers should mount WS endpoints via `register_ws_endpoint`
|
|
5
|
-
* (`actions/register_ws_endpoint.ts`), which wraps this function with the
|
|
6
|
-
* upgrade stack (origin check + auth + optional role). This
|
|
7
|
-
* exported as the lower-level entry point for tests that
|
|
8
|
-
* dispatcher directly via `create_ws_test_harness`.
|
|
5
|
+
* (`actions/register_ws_endpoint.ts`), which wraps this function with the
|
|
6
|
+
* standard upgrade stack (origin check + auth + optional role). This
|
|
7
|
+
* module stays exported as the lower-level entry point for tests that
|
|
8
|
+
* drive the dispatcher directly via `create_ws_test_harness`.
|
|
9
9
|
*
|
|
10
10
|
* Symmetric to `create_rpc_endpoint` (from `actions/action_rpc.ts`):
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* socket-scoped `ctx.notify` + per-socket `ctx.signal`. See
|
|
19
|
-
* `BackendWebsocketTransport.send` for broadcast.
|
|
11
|
+
* both transports parse their wire envelope, then call the shared
|
|
12
|
+
* `perform_action` core (`actions/perform_action.ts`) for the post-parse
|
|
13
|
+
* pipeline. WS-specific concerns — connection lifecycle, heartbeat,
|
|
14
|
+
* cancel-notification interception, socket-scoped notify — stay in this
|
|
15
|
+
* module; everything else (auth gates, input validation, authorization
|
|
16
|
+
* phase, rate limiting, transactional dispatch, DEV output validation,
|
|
17
|
+
* thrown-error normalization) is shared.
|
|
20
18
|
*
|
|
21
19
|
* ## Auth expectations
|
|
22
20
|
*
|
|
23
|
-
* The consumer is responsible for rejecting unauthenticated upgrades
|
|
24
|
-
* routing to this handler (fuz_app's `require_auth` middleware,
|
|
25
|
-
* `register_ws_endpoint` which wires it for you).
|
|
26
|
-
* `
|
|
27
|
-
*
|
|
21
|
+
* The consumer is responsible for rejecting unauthenticated upgrades
|
|
22
|
+
* *before* routing to this handler (fuz_app's `require_auth` middleware,
|
|
23
|
+
* or `register_ws_endpoint` which wires it for you). Per-action auth
|
|
24
|
+
* runs inside `perform_action` on every message via the same gates HTTP
|
|
25
|
+
* RPC uses.
|
|
28
26
|
*
|
|
29
27
|
* @module
|
|
30
28
|
*/
|
|
31
|
-
import type {
|
|
29
|
+
import type { Hono } from 'hono';
|
|
32
30
|
import type { UpgradeWebSocket, WSContext } from 'hono/ws';
|
|
33
31
|
import { type Logger as LoggerType } from '@fuzdev/fuz_util/log.js';
|
|
34
32
|
import type { Uuid } from '@fuzdev/fuz_util/id.js';
|
|
35
33
|
import type { RateLimiter } from '../rate_limiter.js';
|
|
36
|
-
import
|
|
34
|
+
import type { Db } from '../db/db.js';
|
|
35
|
+
import { type Action } from './action_types.js';
|
|
37
36
|
import { BackendWebsocketTransport, type ConnectionIdentity } from './transports_ws_backend.js';
|
|
38
|
-
export type { Action
|
|
37
|
+
export type { Action };
|
|
39
38
|
/** Default inactivity window before the server closes a silent socket. */
|
|
40
39
|
export declare const DEFAULT_SERVER_HEARTBEAT_TIMEOUT = 60000;
|
|
41
40
|
/**
|
|
@@ -87,7 +86,7 @@ export interface ServerHeartbeatOptions {
|
|
|
87
86
|
timeout?: number;
|
|
88
87
|
}
|
|
89
88
|
/** Options for `register_action_ws`. */
|
|
90
|
-
export interface RegisterActionWsOptions
|
|
89
|
+
export interface RegisterActionWsOptions {
|
|
91
90
|
/** Mount path (e.g., `/api/ws`). */
|
|
92
91
|
path: string;
|
|
93
92
|
/** The Hono app to mount on. */
|
|
@@ -102,14 +101,18 @@ export interface RegisterActionWsOptions<TCtx extends BaseHandlerContext> {
|
|
|
102
101
|
* here to complete the disconnect-detection + per-request cancel
|
|
103
102
|
* pairing with the frontend client.
|
|
104
103
|
*/
|
|
105
|
-
actions: ReadonlyArray<Action
|
|
104
|
+
actions: ReadonlyArray<Action>;
|
|
106
105
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
106
|
+
* Pool-level DB. The dispatcher wraps in `db.transaction` for
|
|
107
|
+
* `side_effects: true` actions, the same way HTTP RPC does. Per-message
|
|
108
|
+
* authorization phase reads through this pool.
|
|
109
|
+
*
|
|
110
|
+
* Audit writes and other rollback-resilient fire-and-forget calls run
|
|
111
|
+
* through `AppDeps.audit.emit` from the action factory's closure —
|
|
112
|
+
* the dispatcher never holds an audit-side pool reference; the bound
|
|
113
|
+
* emitter owns the pool.
|
|
111
114
|
*/
|
|
112
|
-
|
|
115
|
+
db: Db;
|
|
113
116
|
/**
|
|
114
117
|
* Existing transport to register connections with. When omitted, a fresh
|
|
115
118
|
* one is created and returned in the result. Pass your own to keep a
|
|
@@ -150,9 +153,9 @@ export interface RegisterActionWsOptions<TCtx extends BaseHandlerContext> {
|
|
|
150
153
|
*/
|
|
151
154
|
action_ip_rate_limiter?: RateLimiter | null;
|
|
152
155
|
/**
|
|
153
|
-
* Per-
|
|
156
|
+
* Per-account rate limiter consulted for actions whose spec declares
|
|
154
157
|
* `rate_limit: 'account'` or `'both'`. Keyed on
|
|
155
|
-
* `request_context.
|
|
158
|
+
* `request_context.account.id`. `null` (or omitted) disables the
|
|
156
159
|
* account check. Same limiter is shared with the HTTP RPC dispatcher.
|
|
157
160
|
*/
|
|
158
161
|
action_account_rate_limiter?: RateLimiter | null;
|
|
@@ -163,19 +166,22 @@ export interface RegisterActionWsResult {
|
|
|
163
166
|
transport: BackendWebsocketTransport;
|
|
164
167
|
}
|
|
165
168
|
/**
|
|
166
|
-
* Mount a JSON-RPC WebSocket endpoint that dispatches
|
|
167
|
-
*
|
|
168
|
-
* `RegisterActionWsOptions.extend_context`.
|
|
169
|
+
* Mount a JSON-RPC WebSocket endpoint that dispatches via the shared
|
|
170
|
+
* `perform_action` core.
|
|
169
171
|
*
|
|
170
172
|
* Wire behavior:
|
|
171
173
|
* - Batch JSON-RPC is rejected (single-message only).
|
|
172
174
|
* - Notifications (method + no id) are silently dropped per JSON-RPC spec.
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
175
|
+
* Exception: `cancel` notifications abort the matching pending request's
|
|
176
|
+
* `ctx.signal` before bubbling out.
|
|
177
|
+
* - Per-message dispatch goes through `perform_action`: pre-validation
|
|
178
|
+
* auth (401) → input validation (400) → authorization phase →
|
|
179
|
+
* post-authorization auth (403) → rate limit (429) → handler (with
|
|
180
|
+
* transaction wrap iff `spec.side_effects: true`) → DEV output validation.
|
|
181
|
+
* - Authorization phase runs **per message** — role_grant changes during a
|
|
182
|
+
* connection lifetime are picked up on the next message without any
|
|
183
|
+
* in-place refresh. Authentication invalidation closes the socket via
|
|
184
|
+
* `create_ws_auth_guard`.
|
|
179
185
|
*
|
|
180
186
|
* @returns the transport (supplied or freshly created) — retain it to wire
|
|
181
187
|
* `create_ws_auth_guard` or broadcast on audit events.
|
|
@@ -183,5 +189,5 @@ export interface RegisterActionWsResult {
|
|
|
183
189
|
* @mutates options.transport - on every message, adds/removes connections
|
|
184
190
|
* in the transport's internal maps via `add_connection` / `remove_connection`
|
|
185
191
|
*/
|
|
186
|
-
export declare const register_action_ws:
|
|
192
|
+
export declare const register_action_ws: (options: RegisterActionWsOptions) => RegisterActionWsResult;
|
|
187
193
|
//# sourceMappingURL=register_action_ws.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register_action_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_action_ws.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"register_action_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_action_ws.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,MAAM,CAAC;AAC/B,OAAO,KAAK,EAAC,gBAAgB,EAAE,SAAS,EAAC,MAAM,SAAS,CAAC;AAEzD,OAAO,EAAS,KAAK,MAAM,IAAI,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAUjD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAgBpD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAI9C,OAAO,EAAC,yBAAyB,EAAE,KAAK,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAG9F,YAAY,EAAC,MAAM,EAAC,CAAC;AAErB,0EAA0E;AAC1E,eAAO,MAAM,gCAAgC,QAAS,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IACjC,qFAAqF;IACrF,EAAE,EAAE,SAAS,CAAC;IACd,4EAA4E;IAC5E,aAAa,EAAE,IAAI,CAAC;IACpB,oDAAoD;IACpD,QAAQ,EAAE,kBAAkB,CAAC;IAC7B;;;OAGG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,wFAAwF;IACxF,MAAM,EAAE,WAAW,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IAClC,+CAA+C;IAC/C,EAAE,EAAE,SAAS,CAAC;IACd,2CAA2C;IAC3C,aAAa,EAAE,IAAI,CAAC;IACpB,kGAAkG;IAClG,QAAQ,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACtC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wCAAwC;AACxC,MAAM,WAAW,uBAAuB;IACvC,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,GAAG,EAAE,IAAI,CAAC;IACV,iEAAiE;IACjE,gBAAgB,EAAE,gBAAgB,CAAC;IACnC;;;;;;;OAOG;IACH,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;;;;;;OASG;IACH,EAAE,EAAE,EAAE,CAAC;IACP;;;;OAIG;IACH,SAAS,CAAC,EAAE,yBAAyB,CAAC;IACtC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,sBAAsB,CAAC;IAC7C,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qDAAqD;IACrD,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACjD;AAED,sCAAsC;AACtC,MAAM,WAAW,sBAAsB;IACtC,yEAAyE;IACzE,SAAS,EAAE,yBAAyB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,uBAAuB,KAAG,sBAuUrE,CAAC"}
|