@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
|
@@ -18,46 +18,82 @@ import type { Logger } from '@fuzdev/fuz_util/log.js';
|
|
|
18
18
|
import type { Db } from '../db/db.js';
|
|
19
19
|
import { type RouteErrorSchemas, type RateLimitKey } from './error_schemas.js';
|
|
20
20
|
import type { MiddlewareSpec } from './middleware_spec.js';
|
|
21
|
+
import { type RouteAuth } from './auth_shape.js';
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
+
* Two-phase auth guard set returned by `AuthGuardResolver`.
|
|
23
24
|
*
|
|
24
|
-
* `
|
|
25
|
-
*
|
|
25
|
+
* `pre_validation` runs before input validation — 401 checks live here
|
|
26
|
+
* so unauthenticated callers never see route-shape information from
|
|
27
|
+
* input parsing failures. `post_authorization` runs after the
|
|
28
|
+
* authorization phase has populated `RequestContext` — role / keeper
|
|
29
|
+
* checks live here because they read `c.var.request_context.role_grants`.
|
|
26
30
|
*/
|
|
27
|
-
export
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} | {
|
|
32
|
-
type: 'role';
|
|
33
|
-
role: string;
|
|
34
|
-
} | {
|
|
35
|
-
type: 'keeper';
|
|
36
|
-
};
|
|
31
|
+
export interface AuthGuards {
|
|
32
|
+
pre_validation: Array<MiddlewareHandler>;
|
|
33
|
+
post_authorization: Array<MiddlewareHandler>;
|
|
34
|
+
}
|
|
37
35
|
/**
|
|
38
36
|
* Resolves a `RouteAuth` to middleware guard handlers.
|
|
39
37
|
*
|
|
40
38
|
* Injected into `apply_route_specs` to decouple route registration
|
|
41
39
|
* from auth-specific middleware. See `fuz_auth_guard_resolver` in
|
|
42
|
-
* `auth/
|
|
40
|
+
* `auth/auth_guard_resolver.ts` for the standard implementation.
|
|
41
|
+
*/
|
|
42
|
+
export type AuthGuardResolver = (auth: RouteAuth) => AuthGuards;
|
|
43
|
+
/**
|
|
44
|
+
* Per-route authorization phase. Runs after pre-validation auth guards
|
|
45
|
+
* AND input validation; resolves the acting actor (when `auth.actor !== 'none'`)
|
|
46
|
+
* by reading `c.var.validated_input.acting` and sets the request context on
|
|
47
|
+
* the Hono context. Per-route order in `apply_route_specs`: params → query
|
|
48
|
+
* → pre-validation auth (401) → input validation (400) → authorization
|
|
49
|
+
* phase → post-authorization auth (403) → handler.
|
|
50
|
+
*
|
|
51
|
+
* Returns a `Response` to short-circuit (resolution failure → 400 / 500),
|
|
52
|
+
* or `void` to continue. The http framework stays auth-agnostic — fuz_app
|
|
53
|
+
* provides the implementation via `create_fuz_authorization_handler` in
|
|
54
|
+
* `auth/request_context.ts`.
|
|
43
55
|
*/
|
|
44
|
-
export type
|
|
56
|
+
export type AuthorizationHandler = (c: Context, spec: RouteSpec) => Promise<Response | void>;
|
|
45
57
|
/** HTTP methods supported by route specs. */
|
|
46
58
|
export type RouteMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
47
59
|
/**
|
|
48
60
|
* Per-request deps provided by the framework to route handlers.
|
|
61
|
+
*
|
|
62
|
+
* Audit writes and other rollback-resilient fire-and-forget calls run
|
|
63
|
+
* through `AppDeps.audit.emit(ctx, input)` (see `auth/audit_emitter.ts`),
|
|
64
|
+
* which captures the pool inside its closure — handlers can never
|
|
65
|
+
* accidentally write audits against the request transaction.
|
|
66
|
+
*
|
|
67
|
+
* Routes whose body manages its own transaction (signup, bootstrap)
|
|
68
|
+
* declare `transaction: false` on the spec, which makes `route.db` the
|
|
69
|
+
* pool — they reach for it directly.
|
|
49
70
|
*/
|
|
50
71
|
export interface RouteContext {
|
|
51
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* Transaction-scoped when `RouteSpec.transaction` is true (the default
|
|
74
|
+
* for non-GET); pool-level otherwise.
|
|
75
|
+
*/
|
|
52
76
|
db: Db;
|
|
53
|
-
/**
|
|
54
|
-
|
|
55
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Eager fire-and-forget queue — push the in-flight `Promise<void>` for
|
|
79
|
+
* pool writes already running (audit emits, session touch, api-token
|
|
80
|
+
* usage tracking). The flush middleware drains via
|
|
81
|
+
* `flush_pending_effects` after the handler returns.
|
|
82
|
+
*/
|
|
56
83
|
pending_effects: Array<Promise<void>>;
|
|
84
|
+
/**
|
|
85
|
+
* Deferred post-commit thunks — do not push directly; reach for
|
|
86
|
+
* `emit_after_commit(ctx, fn)` from `pending_effects.ts`. The flush
|
|
87
|
+
* middleware invokes each thunk after the handler (and any wrapping
|
|
88
|
+
* `db.transaction`) returns, closing the microtask-ordering window
|
|
89
|
+
* that an eager `Promise.resolve().then(fn)` leaves open inside the
|
|
90
|
+
* transaction.
|
|
91
|
+
*/
|
|
92
|
+
post_commit_effects: Array<() => void | Promise<void>>;
|
|
57
93
|
}
|
|
58
94
|
/**
|
|
59
95
|
* Route handler function — receives the Hono context and a `RouteContext`
|
|
60
|
-
* with per-request deps (db,
|
|
96
|
+
* with per-request deps (db, pending_effects).
|
|
61
97
|
*
|
|
62
98
|
* TypeScript allows fewer params, so handlers that don't need `route`
|
|
63
99
|
* can use `(c) => ...` without changes.
|
|
@@ -121,27 +157,39 @@ export interface RouteSpec {
|
|
|
121
157
|
/**
|
|
122
158
|
* Get validated input from the Hono context.
|
|
123
159
|
*
|
|
124
|
-
* Call after the input validation middleware has run.
|
|
125
|
-
*
|
|
160
|
+
* Call after the input validation middleware has run. Pass the route's
|
|
161
|
+
* `input` Zod schema to infer the typed shape directly:
|
|
162
|
+
*
|
|
163
|
+
* ```ts
|
|
164
|
+
* const input = get_route_input(c, my_route_spec.input);
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* Or pass an explicit type argument when the schema isn't in scope:
|
|
168
|
+
*
|
|
169
|
+
* ```ts
|
|
170
|
+
* const input = get_route_input<MyInput>(c);
|
|
171
|
+
* ```
|
|
126
172
|
*/
|
|
127
|
-
export declare
|
|
173
|
+
export declare function get_route_input<S extends z.ZodType>(c: Context, schema: S): z.infer<S>;
|
|
174
|
+
export declare function get_route_input<T = unknown>(c: Context): T;
|
|
128
175
|
/**
|
|
129
176
|
* Get validated URL path params from the Hono context.
|
|
130
177
|
*
|
|
131
|
-
* Call after the params validation middleware has run.
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* TODO derive `T` from the route spec so the type parameter isn't manually
|
|
135
|
-
* specified — same applies to `get_route_input` / `get_route_query`.
|
|
178
|
+
* Call after the params validation middleware has run. Pass the route's
|
|
179
|
+
* `params` schema to infer the typed shape, or supply an explicit type
|
|
180
|
+
* argument. See `get_route_input` for the two call shapes.
|
|
136
181
|
*/
|
|
137
|
-
export declare
|
|
182
|
+
export declare function get_route_params<S extends z.ZodType>(c: Context, schema: S): z.infer<S>;
|
|
183
|
+
export declare function get_route_params<T = unknown>(c: Context): T;
|
|
138
184
|
/**
|
|
139
185
|
* Get validated URL query params from the Hono context.
|
|
140
186
|
*
|
|
141
|
-
* Call after the query validation middleware has run.
|
|
142
|
-
*
|
|
187
|
+
* Call after the query validation middleware has run. Pass the route's
|
|
188
|
+
* `query` schema to infer the typed shape, or supply an explicit type
|
|
189
|
+
* argument. See `get_route_input` for the two call shapes.
|
|
143
190
|
*/
|
|
144
|
-
export declare
|
|
191
|
+
export declare function get_route_query<S extends z.ZodType>(c: Context, schema: S): z.infer<S>;
|
|
192
|
+
export declare function get_route_query<T = unknown>(c: Context): T;
|
|
145
193
|
/**
|
|
146
194
|
* Apply named middleware specs to a Hono app.
|
|
147
195
|
*
|
|
@@ -153,20 +201,44 @@ export declare const apply_middleware_specs: (app: Hono, specs: Array<Middleware
|
|
|
153
201
|
*
|
|
154
202
|
* For each spec: resolves auth to guards via the provided resolver,
|
|
155
203
|
* adds input validation middleware (for routes with non-null input schemas),
|
|
156
|
-
*
|
|
157
|
-
*
|
|
204
|
+
* runs the optional authorization phase to resolve the acting actor + build
|
|
205
|
+
* the request context, wraps handler with DEV-only output and error
|
|
206
|
+
* validation, wraps with error catch layer (catches `ThrownJsonrpcError`
|
|
207
|
+
* and generic errors), and registers the route.
|
|
208
|
+
*
|
|
209
|
+
* Per-route middleware order: params → query → pre-validation auth
|
|
210
|
+
* guards (401) → input validation (400) → authorization phase →
|
|
211
|
+
* post-authorization auth guards (403) → handler. The 401 check runs
|
|
212
|
+
* before any body parsing so unauthenticated callers never see
|
|
213
|
+
* route-shape information from parse failures. Input validation runs
|
|
214
|
+
* before the authorization phase (validate first, authorize after) so
|
|
215
|
+
* the authorization phase reads `c.var.validated_input.acting` as a
|
|
216
|
+
* typed Zod field instead of pre-parsing the raw body. Role /
|
|
217
|
+
* credential-type denials still surface 403 last; trade-off is that
|
|
218
|
+
* authenticated-but-unauthorized callers can distinguish 400
|
|
219
|
+
* (validation) from 403 (authorization), a defense-in-depth concession
|
|
220
|
+
* deemed acceptable because the route surface is public via
|
|
221
|
+
* spec/codegen JSON.
|
|
158
222
|
*
|
|
159
223
|
* Each handler receives a `RouteContext` with:
|
|
160
|
-
* - `db`: transaction-scoped
|
|
161
|
-
* - `
|
|
162
|
-
* - `
|
|
163
|
-
*
|
|
164
|
-
*
|
|
224
|
+
* - `db`: transaction-scoped when `RouteSpec.transaction` is true; pool-level otherwise
|
|
225
|
+
* - `pending_effects`: eager fire-and-forget pool-write queue
|
|
226
|
+
* - `post_commit_effects`: deferred-thunk queue (push via `emit_after_commit`)
|
|
227
|
+
*
|
|
228
|
+
* Also enforces registry-time invariant 2 from the auth-shape design:
|
|
229
|
+
* `auth.actor !== 'none' ⟺ input or query declares acting?: ActingActor`.
|
|
230
|
+
* REST is bi-located (GETs declare `acting` on `query`, mutations on
|
|
231
|
+
* `input`), so the check passes both slots; the action-dispatcher
|
|
232
|
+
* registries (`compile_action_registry`) share the same helper with
|
|
233
|
+
* `input` only — `ActionSpec` has no `query` shape.
|
|
234
|
+
*
|
|
235
|
+
* @param resolve_auth_guards - maps `RouteAuth` to middleware — use `fuz_auth_guard_resolver` from `auth/auth_guard_resolver.ts`
|
|
236
|
+
* @param authorize - optional authorization phase; runs after input validation
|
|
165
237
|
* @param db - used for transaction wrapping and `RouteContext`
|
|
166
238
|
* @mutates `app`
|
|
167
|
-
* @throws Error if two specs share the same `method` + `path` (each combination must be unique)
|
|
239
|
+
* @throws Error if two specs share the same `method` + `path` (each combination must be unique), or if any spec violates the actor-acting biconditional
|
|
168
240
|
*/
|
|
169
|
-
export declare const apply_route_specs: (app: Hono, specs: Array<RouteSpec>, resolve_auth_guards: AuthGuardResolver, log: Logger, db: Db) => void;
|
|
241
|
+
export declare const apply_route_specs: (app: Hono, specs: Array<RouteSpec>, resolve_auth_guards: AuthGuardResolver, log: Logger, db: Db, authorize?: AuthorizationHandler) => void;
|
|
170
242
|
/**
|
|
171
243
|
* Prepend a prefix to all route spec paths.
|
|
172
244
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route_spec.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/route_spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAC,OAAO,EAAW,IAAI,EAAE,iBAAiB,EAAC,MAAM,MAAM,CAAC;AACpE,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAKjB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"route_spec.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/route_spec.ts"],"names":[],"mappings":"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"}
|
package/dist/http/route_spec.js
CHANGED
|
@@ -14,38 +14,18 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { DEV } from 'esm-env';
|
|
16
16
|
import { ERROR_INVALID_JSON_BODY, ERROR_INVALID_REQUEST_BODY, ERROR_INVALID_ROUTE_PARAMS, ERROR_INVALID_QUERY_PARAMS, } from './error_schemas.js';
|
|
17
|
-
import { ThrownJsonrpcError,
|
|
17
|
+
import { ThrownJsonrpcError, jsonrpc_error_code_to_http_status, jsonrpc_error_code_to_name, } from './jsonrpc_errors.js';
|
|
18
18
|
import { is_null_schema, merge_error_schemas } from './schema_helpers.js';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
*
|
|
22
|
-
* Call after the input validation middleware has run. The type parameter
|
|
23
|
-
* should match the route's `input` schema.
|
|
24
|
-
*/
|
|
25
|
-
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) {
|
|
26
21
|
return c.get('validated_input');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
* Get validated URL path params from the Hono context.
|
|
30
|
-
*
|
|
31
|
-
* Call after the params validation middleware has run. The type parameter
|
|
32
|
-
* should match the route's `params` schema.
|
|
33
|
-
*
|
|
34
|
-
* TODO derive `T` from the route spec so the type parameter isn't manually
|
|
35
|
-
* specified — same applies to `get_route_input` / `get_route_query`.
|
|
36
|
-
*/
|
|
37
|
-
export const get_route_params = (c) => {
|
|
22
|
+
}
|
|
23
|
+
export function get_route_params(c, _schema) {
|
|
38
24
|
return c.get('validated_params');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
* Get validated URL query params from the Hono context.
|
|
42
|
-
*
|
|
43
|
-
* Call after the query validation middleware has run. The type parameter
|
|
44
|
-
* should match the route's `query` schema.
|
|
45
|
-
*/
|
|
46
|
-
export const get_route_query = (c) => {
|
|
25
|
+
}
|
|
26
|
+
export function get_route_query(c, _schema) {
|
|
47
27
|
return c.get('validated_query');
|
|
48
|
-
}
|
|
28
|
+
}
|
|
49
29
|
/**
|
|
50
30
|
* Create input validation middleware for a route spec.
|
|
51
31
|
*
|
|
@@ -53,7 +33,10 @@ export const get_route_query = (c) => {
|
|
|
53
33
|
* validated elsewhere, e.g. from `?params=` query string in RPC handlers)
|
|
54
34
|
* and for null-input routes (no body expected). For other routes with input
|
|
55
35
|
* schemas, returns a middleware that parses and validates the JSON body,
|
|
56
|
-
* 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.
|
|
57
40
|
*
|
|
58
41
|
* @mutates `c.var.validated_input` - set to the parsed and validated body on success
|
|
59
42
|
*/
|
|
@@ -192,10 +175,29 @@ export const apply_middleware_specs = (app, specs) => {
|
|
|
192
175
|
/**
|
|
193
176
|
* Wrap a handler with error catch logic.
|
|
194
177
|
*
|
|
195
|
-
* Catches `ThrownJsonrpcError` and maps to
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
178
|
+
* Catches `ThrownJsonrpcError` and maps it to a flat REST `ApiError` body
|
|
179
|
+
* (`{error: <reason>, message?, ...rest_data}`) at the matching HTTP status.
|
|
180
|
+
* Catches generic `Error` and maps to `{error: 'internal_error', message?}`
|
|
181
|
+
* at 500 (`message` populated only in DEV). Existing handlers that return
|
|
182
|
+
* `c.json()` directly are unaffected — the catch layer only activates when
|
|
183
|
+
* something is thrown.
|
|
184
|
+
*
|
|
185
|
+
* The flat shape matches what middleware and direct handler emissions
|
|
186
|
+
* produce (e.g. `c.json({error: ERROR_FOO}, status)`,
|
|
187
|
+
* `c.json(failure.body, status)` from the dispatcher's authorization phase),
|
|
188
|
+
* so REST callers see one error envelope across every emit site. The
|
|
189
|
+
* `<reason>` string comes from `err.data.reason` when set (consumer-supplied
|
|
190
|
+
* canonical reason code) or from `jsonrpc_error_code_to_name(err.code)`
|
|
191
|
+
* (the JSON-RPC error name — `'not_found'`, `'forbidden'`, etc.). Other
|
|
192
|
+
* `data` fields flatten alongside `error` so diagnostic data is visible
|
|
193
|
+
* to clients without descending an envelope.
|
|
194
|
+
*
|
|
195
|
+
* The JSON-RPC code is intentionally **not** carried on the REST body —
|
|
196
|
+
* REST callers key on HTTP status + `error` reason, and the JSON-RPC code
|
|
197
|
+
* is recoverable via `http_status_to_jsonrpc_error_code(status)` on the
|
|
198
|
+
* rare consumer that wants it. Keeping the shape transport-shaped (REST
|
|
199
|
+
* emits ApiError; JSON-RPC dispatcher emits the JSON-RPC envelope) avoids
|
|
200
|
+
* a hybrid envelope that has to be normalized on the way out.
|
|
199
201
|
*/
|
|
200
202
|
const wrap_error_catch = (handler, log) => {
|
|
201
203
|
return async (c, next) => {
|
|
@@ -205,37 +207,94 @@ const wrap_error_catch = (handler, log) => {
|
|
|
205
207
|
catch (err) {
|
|
206
208
|
if (err instanceof ThrownJsonrpcError) {
|
|
207
209
|
const status = jsonrpc_error_code_to_http_status(err.code);
|
|
208
|
-
|
|
209
|
-
if (err.data !== undefined)
|
|
210
|
-
error.data = err.data;
|
|
211
|
-
return c.json({ error }, status);
|
|
210
|
+
return c.json(build_rest_error_body(err), status);
|
|
212
211
|
}
|
|
213
212
|
// generic error — internal_error
|
|
214
213
|
log.error('Unhandled handler error', err);
|
|
215
|
-
const
|
|
216
|
-
|
|
214
|
+
const body = { error: 'internal_error' };
|
|
215
|
+
if (DEV && err instanceof Error)
|
|
216
|
+
body.message = err.message;
|
|
217
|
+
return c.json(body, 500);
|
|
217
218
|
}
|
|
218
219
|
};
|
|
219
220
|
};
|
|
221
|
+
/**
|
|
222
|
+
* Build the REST body for a thrown `ThrownJsonrpcError`. Splits out
|
|
223
|
+
* for unit-test directness and keeps the catch handler readable.
|
|
224
|
+
*
|
|
225
|
+
* Reason resolution order:
|
|
226
|
+
* 1. `err.data.reason` (consumer-supplied canonical reason — overrides code-derived name)
|
|
227
|
+
* 2. `jsonrpc_error_code_to_name(err.code)` (e.g. -32003 → `'not_found'`)
|
|
228
|
+
*
|
|
229
|
+
* Remaining `err.data` fields (everything except `reason`) flatten under
|
|
230
|
+
* the body. Non-object `data` is dropped — we don't want a primitive
|
|
231
|
+
* `data` to overwrite the structured shape.
|
|
232
|
+
*/
|
|
233
|
+
const build_rest_error_body = (err) => {
|
|
234
|
+
let reason;
|
|
235
|
+
const rest = {};
|
|
236
|
+
if (err.data !== null &&
|
|
237
|
+
typeof err.data === 'object' &&
|
|
238
|
+
!Array.isArray(err.data) &&
|
|
239
|
+
typeof err.data.reason === 'string') {
|
|
240
|
+
const { reason: data_reason, ...other } = err.data;
|
|
241
|
+
reason = data_reason;
|
|
242
|
+
Object.assign(rest, other);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
reason = jsonrpc_error_code_to_name(err.code);
|
|
246
|
+
if (err.data !== null && typeof err.data === 'object' && !Array.isArray(err.data)) {
|
|
247
|
+
Object.assign(rest, err.data);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const body = { error: reason, ...rest };
|
|
251
|
+
if (err.message && err.message !== reason)
|
|
252
|
+
body.message = err.message;
|
|
253
|
+
return body;
|
|
254
|
+
};
|
|
220
255
|
/**
|
|
221
256
|
* Apply route specs to a Hono app.
|
|
222
257
|
*
|
|
223
258
|
* For each spec: resolves auth to guards via the provided resolver,
|
|
224
259
|
* adds input validation middleware (for routes with non-null input schemas),
|
|
225
|
-
*
|
|
226
|
-
*
|
|
260
|
+
* runs the optional authorization phase to resolve the acting actor + build
|
|
261
|
+
* the request context, wraps handler with DEV-only output and error
|
|
262
|
+
* validation, wraps with error catch layer (catches `ThrownJsonrpcError`
|
|
263
|
+
* and generic errors), and registers the route.
|
|
264
|
+
*
|
|
265
|
+
* Per-route middleware order: params → query → pre-validation auth
|
|
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.
|
|
227
278
|
*
|
|
228
279
|
* Each handler receives a `RouteContext` with:
|
|
229
|
-
* - `db`: transaction-scoped
|
|
230
|
-
* - `
|
|
231
|
-
* - `
|
|
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.
|
|
232
290
|
*
|
|
233
|
-
* @param resolve_auth_guards - maps `RouteAuth` to middleware — use `fuz_auth_guard_resolver` from `auth/
|
|
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
|
|
234
293
|
* @param db - used for transaction wrapping and `RouteContext`
|
|
235
294
|
* @mutates `app`
|
|
236
|
-
* @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
|
|
237
296
|
*/
|
|
238
|
-
export const apply_route_specs = (app, specs, resolve_auth_guards, log, db) => {
|
|
297
|
+
export const apply_route_specs = (app, specs, resolve_auth_guards, log, db, authorize) => {
|
|
239
298
|
const registered = new Set();
|
|
240
299
|
for (const spec of specs) {
|
|
241
300
|
const route_key = `${spec.method} ${spec.path}`;
|
|
@@ -243,22 +302,41 @@ export const apply_route_specs = (app, specs, resolve_auth_guards, log, db) => {
|
|
|
243
302
|
throw new Error(`Duplicate route: ${route_key} — each method+path combination must be unique`);
|
|
244
303
|
}
|
|
245
304
|
registered.add(route_key);
|
|
246
|
-
|
|
305
|
+
assert_route_auth_acting_biconditional(spec.auth, { input: spec.input, query: spec.query }, `Route "${route_key}"`);
|
|
306
|
+
const { pre_validation: pre_validation_guards, post_authorization: post_authorization_guards } = resolve_auth_guards(spec.auth);
|
|
247
307
|
const params_validation = create_params_validation(spec.params);
|
|
248
308
|
const query_validation = create_query_validation(spec.query);
|
|
249
309
|
const input_validation = create_input_validation(spec.input, spec.method);
|
|
250
|
-
const merged_errors = merge_error_schemas(spec);
|
|
310
|
+
const merged_errors = merge_error_schemas(spec, null);
|
|
311
|
+
const authorization = authorize
|
|
312
|
+
? [
|
|
313
|
+
async (c, next) => {
|
|
314
|
+
const response = await authorize(c, spec);
|
|
315
|
+
if (response)
|
|
316
|
+
return response;
|
|
317
|
+
await next();
|
|
318
|
+
},
|
|
319
|
+
]
|
|
320
|
+
: [];
|
|
251
321
|
// Step 1: adapt RouteHandler → Handler (construct RouteContext, call spec.handler)
|
|
252
322
|
const use_transaction = spec.transaction ?? spec.method !== 'GET';
|
|
253
323
|
const inner = spec.handler;
|
|
254
324
|
let handler = use_transaction
|
|
255
|
-
? (c) => db.transaction(async (tx) => inner(c, {
|
|
256
|
-
|
|
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
|
+
});
|
|
257
335
|
// Step 2: output validation
|
|
258
336
|
handler = wrap_output_validation(handler, spec.output, merged_errors, log);
|
|
259
337
|
// Step 3: error catch layer
|
|
260
338
|
handler = wrap_error_catch(handler, log);
|
|
261
|
-
app.on(spec.method, [spec.path], ...
|
|
339
|
+
app.on(spec.method, [spec.path], ...params_validation, ...query_validation, ...pre_validation_guards, ...input_validation, ...authorization, ...post_authorization_guards, handler);
|
|
262
340
|
}
|
|
263
341
|
};
|
|
264
342
|
/**
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
|
-
import type { RouteAuth } from './
|
|
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/
|
|
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;
|
|
@@ -56,6 +56,7 @@ export declare const middleware_applies: (mw_path: string, route_path: string) =
|
|
|
56
56
|
* Later layers override earlier ones for the same status code.
|
|
57
57
|
*
|
|
58
58
|
* @param spec - the route spec (needs `auth`, `input`, `params`, `rate_limit`, `errors`)
|
|
59
|
+
* @param middleware_errors - errors contributed by middleware whose path matches the route
|
|
59
60
|
* @returns merged error schemas, or `null` if empty
|
|
60
61
|
*/
|
|
61
62
|
export declare const merge_error_schemas: (spec: {
|
|
@@ -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
|
|
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/
|
|
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) => {
|
|
@@ -95,10 +95,17 @@ export const middleware_applies = (mw_path, route_path) => {
|
|
|
95
95
|
* Later layers override earlier ones for the same status code.
|
|
96
96
|
*
|
|
97
97
|
* @param spec - the route spec (needs `auth`, `input`, `params`, `rate_limit`, `errors`)
|
|
98
|
+
* @param middleware_errors - errors contributed by middleware whose path matches the route
|
|
98
99
|
* @returns merged error schemas, or `null` if empty
|
|
99
100
|
*/
|
|
100
101
|
export const merge_error_schemas = (spec, middleware_errors) => {
|
|
101
|
-
const derived = derive_error_schemas(
|
|
102
|
+
const derived = derive_error_schemas({
|
|
103
|
+
auth: spec.auth,
|
|
104
|
+
has_input: !is_null_schema(spec.input),
|
|
105
|
+
has_params: !!spec.params,
|
|
106
|
+
has_query: !!spec.query,
|
|
107
|
+
rate_limit: spec.rate_limit,
|
|
108
|
+
});
|
|
102
109
|
const merged = { ...derived, ...middleware_errors, ...spec.errors };
|
|
103
110
|
return Object.keys(merged).length > 0 ? merged : null;
|
|
104
111
|
};
|
package/dist/http/surface.d.ts
CHANGED
|
@@ -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 {
|
|
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';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/surface.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/surface.ts"],"names":[],"mappings":"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"}
|
package/dist/http/surface.js
CHANGED
|
@@ -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
|
/**
|
|
@@ -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:
|
|
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,
|