@fuzdev/fuz_app 0.51.0 → 0.53.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 +43 -10
- package/dist/actions/action_bridge.d.ts +3 -1
- package/dist/actions/action_bridge.d.ts.map +1 -1
- package/dist/actions/action_bridge.js +3 -1
- package/dist/actions/action_codegen.d.ts +28 -43
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +31 -50
- package/dist/actions/action_event.d.ts +44 -1
- package/dist/actions/action_event.d.ts.map +1 -1
- package/dist/actions/action_event.js +44 -1
- package/dist/actions/action_event_helpers.d.ts +26 -0
- package/dist/actions/action_event_helpers.d.ts.map +1 -1
- package/dist/actions/action_event_helpers.js +26 -1
- package/dist/actions/action_peer.d.ts +17 -0
- package/dist/actions/action_peer.d.ts.map +1 -1
- package/dist/actions/action_peer.js +8 -9
- package/dist/actions/action_registry.d.ts +1 -5
- package/dist/actions/action_registry.d.ts.map +1 -1
- package/dist/actions/action_registry.js +5 -11
- package/dist/actions/action_rpc.d.ts +20 -0
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +45 -20
- package/dist/actions/action_spec.d.ts +75 -6
- package/dist/actions/action_spec.d.ts.map +1 -1
- package/dist/actions/action_spec.js +36 -6
- package/dist/actions/frontend_rpc_client.d.ts +1 -9
- package/dist/actions/frontend_rpc_client.d.ts.map +1 -1
- package/dist/actions/frontend_rpc_client.js +1 -9
- package/dist/actions/register_action_ws.d.ts +19 -0
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +44 -1
- package/dist/actions/register_ws_endpoint.d.ts +3 -0
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +3 -0
- package/dist/actions/request_tracker.svelte.d.ts +24 -16
- package/dist/actions/request_tracker.svelte.d.ts.map +1 -1
- package/dist/actions/request_tracker.svelte.js +24 -16
- package/dist/actions/rpc_client.d.ts +0 -1
- package/dist/actions/rpc_client.d.ts.map +1 -1
- package/dist/actions/rpc_client.js +3 -17
- package/dist/actions/socket.svelte.d.ts +35 -16
- package/dist/actions/socket.svelte.d.ts.map +1 -1
- package/dist/actions/socket.svelte.js +33 -14
- package/dist/actions/transports.d.ts +15 -5
- package/dist/actions/transports.d.ts.map +1 -1
- package/dist/actions/transports.js +15 -15
- package/dist/actions/transports_http.d.ts +7 -0
- package/dist/actions/transports_http.d.ts.map +1 -1
- package/dist/actions/transports_http.js +7 -0
- package/dist/actions/transports_ws.d.ts +13 -0
- package/dist/actions/transports_ws.d.ts.map +1 -1
- package/dist/actions/transports_ws.js +13 -0
- package/dist/actions/transports_ws_auth_guard.d.ts +6 -4
- package/dist/actions/transports_ws_auth_guard.d.ts.map +1 -1
- package/dist/actions/transports_ws_auth_guard.js +6 -4
- package/dist/actions/transports_ws_backend.d.ts +14 -1
- package/dist/actions/transports_ws_backend.d.ts.map +1 -1
- package/dist/actions/transports_ws_backend.js +14 -10
- package/dist/auth/CLAUDE.md +64 -18
- package/dist/auth/account_queries.d.ts +7 -0
- package/dist/auth/account_queries.d.ts.map +1 -1
- package/dist/auth/account_queries.js +7 -0
- package/dist/auth/admin_action_specs.d.ts +5 -0
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_action_specs.js +5 -0
- package/dist/auth/admin_actions.d.ts +1 -0
- package/dist/auth/admin_actions.d.ts.map +1 -1
- package/dist/auth/admin_actions.js +1 -0
- package/dist/auth/api_token_queries.d.ts +6 -0
- package/dist/auth/api_token_queries.d.ts.map +1 -1
- package/dist/auth/api_token_queries.js +6 -0
- package/dist/auth/app_settings_queries.d.ts +4 -0
- package/dist/auth/app_settings_queries.d.ts.map +1 -1
- package/dist/auth/app_settings_queries.js +4 -0
- package/dist/auth/audit_log_queries.d.ts +5 -0
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.js +5 -0
- package/dist/auth/audit_log_routes.d.ts +2 -2
- package/dist/auth/audit_log_routes.js +2 -2
- package/dist/auth/audit_log_schema.d.ts +2 -0
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +134 -55
- package/dist/auth/bearer_auth.d.ts +2 -0
- package/dist/auth/bearer_auth.d.ts.map +1 -1
- package/dist/auth/bearer_auth.js +2 -0
- package/dist/auth/bootstrap_account.d.ts +3 -0
- package/dist/auth/bootstrap_account.d.ts.map +1 -1
- package/dist/auth/bootstrap_account.js +3 -0
- package/dist/auth/cleanup.d.ts +6 -0
- package/dist/auth/cleanup.d.ts.map +1 -1
- package/dist/auth/cleanup.js +6 -0
- package/dist/auth/daemon_token_middleware.d.ts +4 -0
- package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
- package/dist/auth/daemon_token_middleware.js +4 -0
- package/dist/auth/invite_queries.d.ts +3 -0
- package/dist/auth/invite_queries.d.ts.map +1 -1
- package/dist/auth/invite_queries.js +3 -0
- package/dist/auth/permit_offer_action_specs.d.ts +6 -0
- package/dist/auth/permit_offer_action_specs.d.ts.map +1 -1
- package/dist/auth/permit_offer_action_specs.js +11 -0
- package/dist/auth/permit_offer_queries.d.ts +18 -0
- package/dist/auth/permit_offer_queries.d.ts.map +1 -1
- package/dist/auth/permit_offer_queries.js +18 -0
- package/dist/auth/permit_queries.d.ts +7 -0
- package/dist/auth/permit_queries.d.ts.map +1 -1
- package/dist/auth/permit_queries.js +7 -0
- package/dist/auth/request_context.d.ts +1 -0
- package/dist/auth/request_context.d.ts.map +1 -1
- package/dist/auth/request_context.js +1 -0
- package/dist/auth/role_schema.d.ts +2 -0
- package/dist/auth/role_schema.d.ts.map +1 -1
- package/dist/auth/role_schema.js +2 -0
- package/dist/auth/self_service_role_actions.d.ts +1 -0
- package/dist/auth/self_service_role_actions.d.ts.map +1 -1
- package/dist/auth/self_service_role_actions.js +1 -0
- package/dist/auth/session_lifecycle.d.ts +2 -0
- package/dist/auth/session_lifecycle.d.ts.map +1 -1
- package/dist/auth/session_lifecycle.js +2 -0
- package/dist/auth/session_middleware.d.ts +1 -0
- package/dist/auth/session_middleware.d.ts.map +1 -1
- package/dist/auth/session_middleware.js +1 -0
- package/dist/auth/session_queries.d.ts +9 -0
- package/dist/auth/session_queries.d.ts.map +1 -1
- package/dist/auth/session_queries.js +9 -0
- package/dist/cli/config.d.ts +1 -2
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +1 -2
- package/dist/cli/daemon.d.ts +6 -1
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +6 -1
- package/dist/db/assert_row.d.ts +2 -1
- package/dist/db/assert_row.d.ts.map +1 -1
- package/dist/db/assert_row.js +2 -1
- package/dist/db/create_db.d.ts +3 -1
- package/dist/db/create_db.d.ts.map +1 -1
- package/dist/db/create_db.js +3 -1
- package/dist/db/db.d.ts +15 -4
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +14 -3
- package/dist/db/db_pg.d.ts +4 -3
- package/dist/db/db_pg.d.ts.map +1 -1
- package/dist/db/db_pg.js +7 -5
- package/dist/db/db_pglite.d.ts +4 -4
- package/dist/db/db_pglite.js +4 -4
- package/dist/db/migrate.d.ts +7 -4
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +5 -2
- package/dist/db/sql_identifier.d.ts +2 -1
- package/dist/db/sql_identifier.d.ts.map +1 -1
- package/dist/db/sql_identifier.js +2 -1
- package/dist/db/status.d.ts +4 -1
- package/dist/db/status.d.ts.map +1 -1
- package/dist/db/status.js +5 -2
- package/dist/dev/setup.d.ts +15 -2
- package/dist/dev/setup.d.ts.map +1 -1
- package/dist/dev/setup.js +15 -2
- package/dist/env/dotenv.d.ts +2 -1
- package/dist/env/dotenv.d.ts.map +1 -1
- package/dist/env/dotenv.js +2 -1
- package/dist/env/load.d.ts +1 -3
- package/dist/env/load.d.ts.map +1 -1
- package/dist/env/load.js +1 -3
- package/dist/env/resolve.d.ts +1 -1
- package/dist/env/resolve.js +1 -1
- package/dist/env/update_env_variable.d.ts +2 -0
- package/dist/env/update_env_variable.d.ts.map +1 -1
- package/dist/env/update_env_variable.js +2 -0
- package/dist/hono_context.d.ts +2 -5
- package/dist/hono_context.d.ts.map +1 -1
- package/dist/hono_context.js +2 -5
- package/dist/http/common_routes.d.ts +0 -8
- package/dist/http/common_routes.d.ts.map +1 -1
- package/dist/http/common_routes.js +0 -8
- package/dist/http/db_routes.d.ts +0 -3
- package/dist/http/db_routes.d.ts.map +1 -1
- package/dist/http/db_routes.js +0 -3
- package/dist/http/error_schemas.d.ts +12 -11
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +11 -7
- package/dist/http/jsonrpc_errors.d.ts +0 -6
- package/dist/http/jsonrpc_errors.d.ts.map +1 -1
- package/dist/http/jsonrpc_errors.js +0 -6
- package/dist/http/origin.d.ts +6 -13
- package/dist/http/origin.d.ts.map +1 -1
- package/dist/http/origin.js +7 -14
- package/dist/http/pending_effects.d.ts +4 -0
- package/dist/http/pending_effects.d.ts.map +1 -1
- package/dist/http/pending_effects.js +4 -0
- package/dist/http/proxy.d.ts +3 -6
- package/dist/http/proxy.d.ts.map +1 -1
- package/dist/http/proxy.js +3 -6
- package/dist/http/route_spec.d.ts +14 -35
- package/dist/http/route_spec.d.ts.map +1 -1
- package/dist/http/route_spec.js +17 -22
- package/dist/http/schema_helpers.d.ts +0 -4
- package/dist/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +0 -4
- package/dist/http/surface.d.ts +2 -12
- package/dist/http/surface.d.ts.map +1 -1
- package/dist/http/surface.js +1 -12
- package/dist/rate_limiter.d.ts +30 -1
- package/dist/rate_limiter.d.ts.map +1 -1
- package/dist/rate_limiter.js +40 -1
- package/dist/realtime/sse.d.ts +7 -2
- package/dist/realtime/sse.d.ts.map +1 -1
- package/dist/realtime/sse.js +3 -2
- package/dist/realtime/sse_auth_guard.d.ts +21 -21
- package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
- package/dist/realtime/sse_auth_guard.js +24 -24
- package/dist/realtime/subscriber_registry.d.ts +4 -5
- package/dist/realtime/subscriber_registry.d.ts.map +1 -1
- package/dist/realtime/subscriber_registry.js +4 -5
- package/dist/runtime/fs.d.ts +5 -3
- package/dist/runtime/fs.d.ts.map +1 -1
- package/dist/runtime/fs.js +5 -3
- package/dist/runtime/mock.d.ts +6 -3
- package/dist/runtime/mock.d.ts.map +1 -1
- package/dist/runtime/mock.js +6 -3
- package/dist/server/app_backend.d.ts +1 -0
- package/dist/server/app_backend.d.ts.map +1 -1
- package/dist/server/app_backend.js +1 -0
- package/dist/server/app_server.d.ts +31 -5
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +23 -7
- package/dist/server/startup.d.ts +0 -2
- package/dist/server/startup.d.ts.map +1 -1
- package/dist/server/startup.js +0 -2
- package/dist/server/static.d.ts +0 -1
- package/dist/server/static.d.ts.map +1 -1
- package/dist/server/static.js +0 -1
- package/dist/server/validate_nginx.d.ts +3 -3
- package/dist/server/validate_nginx.d.ts.map +1 -1
- package/dist/server/validate_nginx.js +0 -3
- package/dist/testing/CLAUDE.md +1 -1
- package/dist/testing/admin_integration.d.ts +5 -1
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +8 -6
- package/dist/testing/adversarial_404.d.ts +0 -2
- package/dist/testing/adversarial_404.d.ts.map +1 -1
- package/dist/testing/adversarial_404.js +0 -2
- package/dist/testing/adversarial_headers.d.ts +5 -4
- package/dist/testing/adversarial_headers.d.ts.map +1 -1
- package/dist/testing/adversarial_headers.js +5 -4
- package/dist/testing/adversarial_input.d.ts +4 -2
- package/dist/testing/adversarial_input.d.ts.map +1 -1
- package/dist/testing/adversarial_input.js +4 -2
- package/dist/testing/app_server.d.ts +25 -0
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +11 -2
- package/dist/testing/assertions.d.ts +23 -11
- package/dist/testing/assertions.d.ts.map +1 -1
- package/dist/testing/assertions.js +23 -11
- package/dist/testing/attack_surface.d.ts +0 -4
- package/dist/testing/attack_surface.d.ts.map +1 -1
- package/dist/testing/attack_surface.js +0 -4
- package/dist/testing/audit_completeness.d.ts +4 -1
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +4 -1
- package/dist/testing/auth_apps.d.ts +5 -10
- package/dist/testing/auth_apps.d.ts.map +1 -1
- package/dist/testing/auth_apps.js +5 -10
- package/dist/testing/data_exposure.d.ts +0 -11
- package/dist/testing/data_exposure.d.ts.map +1 -1
- package/dist/testing/data_exposure.js +0 -11
- package/dist/testing/db.d.ts +9 -7
- package/dist/testing/db.d.ts.map +1 -1
- package/dist/testing/db.js +9 -7
- package/dist/testing/error_coverage.d.ts +9 -14
- package/dist/testing/error_coverage.d.ts.map +1 -1
- package/dist/testing/error_coverage.js +9 -14
- package/dist/testing/integration.d.ts +4 -1
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +4 -1
- package/dist/testing/integration_helpers.d.ts +5 -34
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/integration_helpers.js +5 -41
- package/dist/testing/middleware.d.ts +5 -10
- package/dist/testing/middleware.d.ts.map +1 -1
- package/dist/testing/middleware.js +5 -10
- package/dist/testing/mock_fs.d.ts +0 -2
- package/dist/testing/mock_fs.d.ts.map +1 -1
- package/dist/testing/mock_fs.js +0 -2
- package/dist/testing/rate_limiting.d.ts +3 -1
- package/dist/testing/rate_limiting.d.ts.map +1 -1
- package/dist/testing/rate_limiting.js +3 -1
- package/dist/testing/round_trip.d.ts +0 -2
- package/dist/testing/round_trip.d.ts.map +1 -1
- package/dist/testing/round_trip.js +0 -2
- package/dist/testing/rpc_attack_surface.d.ts +0 -2
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.js +0 -2
- package/dist/testing/rpc_helpers.d.ts +21 -14
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.js +21 -14
- package/dist/testing/rpc_round_trip.d.ts +0 -2
- package/dist/testing/rpc_round_trip.d.ts.map +1 -1
- package/dist/testing/rpc_round_trip.js +0 -2
- package/dist/testing/schema_generators.d.ts +5 -3
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +22 -3
- package/dist/testing/sse_round_trip.d.ts +3 -1
- package/dist/testing/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/sse_round_trip.js +3 -1
- package/dist/testing/standard.d.ts +0 -2
- package/dist/testing/standard.d.ts.map +1 -1
- package/dist/testing/standard.js +0 -2
- package/dist/testing/stubs.d.ts +8 -3
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +10 -3
- package/dist/testing/surface_invariants.d.ts +14 -3
- package/dist/testing/surface_invariants.d.ts.map +1 -1
- package/dist/testing/surface_invariants.js +14 -3
- package/dist/testing/ws_round_trip.d.ts +13 -1
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/ui/AccountSessions.svelte +9 -0
- package/dist/ui/AccountSessions.svelte.d.ts.map +1 -1
- package/dist/ui/AdminAccounts.svelte +10 -0
- package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
- package/dist/ui/AdminAuditLog.svelte +10 -0
- package/dist/ui/AdminAuditLog.svelte.d.ts.map +1 -1
- package/dist/ui/AdminInvites.svelte +9 -0
- package/dist/ui/AdminInvites.svelte.d.ts.map +1 -1
- package/dist/ui/AdminOverview.svelte +10 -0
- package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
- package/dist/ui/AdminPermitHistory.svelte +9 -0
- package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -1
- package/dist/ui/AdminSessions.svelte +10 -0
- package/dist/ui/AdminSessions.svelte.d.ts.map +1 -1
- package/dist/ui/AdminSettings.svelte +9 -0
- package/dist/ui/AdminSettings.svelte.d.ts.map +1 -1
- package/dist/ui/AdminSurface.svelte +9 -0
- package/dist/ui/AdminSurface.svelte.d.ts.map +1 -1
- package/dist/ui/AppShell.svelte +24 -0
- package/dist/ui/AppShell.svelte.d.ts +23 -0
- package/dist/ui/AppShell.svelte.d.ts.map +1 -1
- package/dist/ui/BootstrapForm.svelte +17 -0
- package/dist/ui/BootstrapForm.svelte.d.ts +4 -0
- package/dist/ui/BootstrapForm.svelte.d.ts.map +1 -1
- package/dist/ui/CLAUDE.md +1 -1
- package/dist/ui/ColumnLayout.svelte +11 -0
- package/dist/ui/ColumnLayout.svelte.d.ts +10 -0
- package/dist/ui/ColumnLayout.svelte.d.ts.map +1 -1
- package/dist/ui/Datatable.svelte +18 -0
- package/dist/ui/Datatable.svelte.d.ts +17 -0
- package/dist/ui/Datatable.svelte.d.ts.map +1 -1
- package/dist/ui/LoginForm.svelte +18 -0
- package/dist/ui/LoginForm.svelte.d.ts +9 -0
- package/dist/ui/LoginForm.svelte.d.ts.map +1 -1
- package/dist/ui/LogoutButton.svelte +9 -0
- package/dist/ui/LogoutButton.svelte.d.ts +8 -0
- package/dist/ui/LogoutButton.svelte.d.ts.map +1 -1
- package/dist/ui/MenuLink.svelte +10 -0
- package/dist/ui/MenuLink.svelte.d.ts +9 -0
- package/dist/ui/MenuLink.svelte.d.ts.map +1 -1
- package/dist/ui/OpenSignupToggle.svelte +9 -0
- package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -1
- package/dist/ui/SignupForm.svelte +16 -0
- package/dist/ui/SignupForm.svelte.d.ts +4 -0
- package/dist/ui/SignupForm.svelte.d.ts.map +1 -1
- package/dist/ui/SurfaceExplorer.svelte +9 -0
- package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
- package/dist/ui/audit_log_state.svelte.d.ts +6 -1
- package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
- package/dist/ui/audit_log_state.svelte.js +7 -2
- package/dist/ui/auth_state.svelte.d.ts +16 -4
- package/dist/ui/auth_state.svelte.d.ts.map +1 -1
- package/dist/ui/auth_state.svelte.js +16 -4
- package/dist/ui/form_state.svelte.d.ts +9 -0
- package/dist/ui/form_state.svelte.d.ts.map +1 -1
- package/dist/ui/form_state.svelte.js +9 -0
- package/dist/ui/loadable.svelte.d.ts +6 -1
- package/dist/ui/loadable.svelte.d.ts.map +1 -1
- package/dist/ui/loadable.svelte.js +6 -1
- package/dist/ui/permit_offers_state.svelte.d.ts +2 -0
- package/dist/ui/permit_offers_state.svelte.d.ts.map +1 -1
- package/dist/ui/permit_offers_state.svelte.js +2 -0
- package/dist/ui/popover.svelte.d.ts +17 -4
- package/dist/ui/popover.svelte.d.ts.map +1 -1
- package/dist/ui/popover.svelte.js +17 -4
- package/dist/ui/position_helpers.d.ts +1 -3
- package/dist/ui/position_helpers.d.ts.map +1 -1
- package/dist/ui/position_helpers.js +1 -3
- package/dist/ui/sidebar_state.svelte.d.ts +21 -9
- package/dist/ui/sidebar_state.svelte.d.ts.map +1 -1
- package/dist/ui/sidebar_state.svelte.js +16 -2
- package/dist/ui/table_state.svelte.d.ts +14 -0
- package/dist/ui/table_state.svelte.d.ts.map +1 -1
- package/dist/ui/table_state.svelte.js +14 -0
- package/dist/ui/ui_fetch.d.ts +1 -7
- package/dist/ui/ui_fetch.d.ts.map +1 -1
- package/dist/ui/ui_fetch.js +1 -7
- package/dist/ui/ui_format.d.ts +2 -14
- package/dist/ui/ui_format.d.ts.map +1 -1
- package/dist/ui/ui_format.js +2 -14
- package/package.json +2 -2
|
@@ -9,23 +9,14 @@ import { type DbFactory } from './db.js';
|
|
|
9
9
|
*
|
|
10
10
|
* Walks `properties`, `items`, `allOf`/`anyOf`/`oneOf`, and
|
|
11
11
|
* `additionalProperties` to find every declared field name at any depth.
|
|
12
|
-
*
|
|
13
|
-
* @param schema - JSON Schema object
|
|
14
|
-
* @returns set of all property names found
|
|
15
12
|
*/
|
|
16
13
|
export declare const collect_json_schema_property_names: (schema: unknown) => Set<string>;
|
|
17
14
|
/**
|
|
18
15
|
* Assert that no output schema in the surface contains sensitive field names.
|
|
19
|
-
*
|
|
20
|
-
* @param surface - the app surface to check
|
|
21
|
-
* @param sensitive_fields - field names to flag
|
|
22
16
|
*/
|
|
23
17
|
export declare const assert_output_schemas_no_sensitive_fields: (surface: AppSurface, sensitive_fields?: ReadonlyArray<string>) => void;
|
|
24
18
|
/**
|
|
25
19
|
* Assert that non-admin route output schemas don't contain admin-only fields.
|
|
26
|
-
*
|
|
27
|
-
* @param surface - the app surface to check
|
|
28
|
-
* @param admin_only_fields - field names that are admin-only
|
|
29
20
|
*/
|
|
30
21
|
export declare const assert_non_admin_schemas_no_admin_fields: (surface: AppSurface, admin_only_fields?: ReadonlyArray<string>) => void;
|
|
31
22
|
/** Options for `describe_data_exposure_tests`. */
|
|
@@ -55,8 +46,6 @@ export interface DataExposureTestOptions {
|
|
|
55
46
|
* 2. Runtime — fire real requests and check response bodies against blocklists
|
|
56
47
|
* 3. Cross-privilege — admin routes return 403 for non-admin, error responses
|
|
57
48
|
* contain no sensitive fields
|
|
58
|
-
*
|
|
59
|
-
* @param options - test configuration
|
|
60
49
|
*/
|
|
61
50
|
export declare const describe_data_exposure_tests: (options: DataExposureTestOptions) => void;
|
|
62
51
|
//# sourceMappingURL=data_exposure.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data_exposure.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/data_exposure.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgB7B,OAAO,KAAK,EAAC,UAAU,EAAE,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAe9D
|
|
1
|
+
{"version":3,"file":"data_exposure.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/data_exposure.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgB7B,OAAO,KAAK,EAAC,UAAU,EAAE,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAe9D;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,GAAI,QAAQ,OAAO,KAAG,GAAG,CAAC,MAAM,CAuB9E,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,UAAU,EACnB,mBAAkB,aAAa,CAAC,MAAM,CAA6B,KACjE,IAWF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wCAAwC,GACpD,SAAS,UAAU,EACnB,oBAAmB,aAAa,CAAC,MAAM,CAA8B,KACnE,IAcF,CAAC;AAIF,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACvC,4DAA4D;IAC5D,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,wCAAwC;IACxC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4CAA4C;IAC5C,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,2FAA2F;IAC3F,gBAAgB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CACpB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC,CAC5E,CAAC;IACF,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,kDAAkD;IAClD,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,GAAI,SAAS,uBAAuB,KAAG,IAmC/E,CAAC"}
|
|
@@ -25,9 +25,6 @@ import { SENSITIVE_FIELD_BLOCKLIST, ADMIN_ONLY_FIELD_BLOCKLIST, assert_no_sensit
|
|
|
25
25
|
*
|
|
26
26
|
* Walks `properties`, `items`, `allOf`/`anyOf`/`oneOf`, and
|
|
27
27
|
* `additionalProperties` to find every declared field name at any depth.
|
|
28
|
-
*
|
|
29
|
-
* @param schema - JSON Schema object
|
|
30
|
-
* @returns set of all property names found
|
|
31
28
|
*/
|
|
32
29
|
export const collect_json_schema_property_names = (schema) => {
|
|
33
30
|
const names = new Set();
|
|
@@ -59,9 +56,6 @@ export const collect_json_schema_property_names = (schema) => {
|
|
|
59
56
|
// --- Schema-level assertions ---
|
|
60
57
|
/**
|
|
61
58
|
* Assert that no output schema in the surface contains sensitive field names.
|
|
62
|
-
*
|
|
63
|
-
* @param surface - the app surface to check
|
|
64
|
-
* @param sensitive_fields - field names to flag
|
|
65
59
|
*/
|
|
66
60
|
export const assert_output_schemas_no_sensitive_fields = (surface, sensitive_fields = SENSITIVE_FIELD_BLOCKLIST) => {
|
|
67
61
|
for (const route of surface.routes) {
|
|
@@ -75,9 +69,6 @@ export const assert_output_schemas_no_sensitive_fields = (surface, sensitive_fie
|
|
|
75
69
|
};
|
|
76
70
|
/**
|
|
77
71
|
* Assert that non-admin route output schemas don't contain admin-only fields.
|
|
78
|
-
*
|
|
79
|
-
* @param surface - the app surface to check
|
|
80
|
-
* @param admin_only_fields - field names that are admin-only
|
|
81
72
|
*/
|
|
82
73
|
export const assert_non_admin_schemas_no_admin_fields = (surface, admin_only_fields = ADMIN_ONLY_FIELD_BLOCKLIST) => {
|
|
83
74
|
const non_admin = surface.routes.filter((r) => r.auth.type !== 'keeper' && !(r.auth.type === 'role' && r.auth.role === 'admin'));
|
|
@@ -98,8 +89,6 @@ export const assert_non_admin_schemas_no_admin_fields = (surface, admin_only_fie
|
|
|
98
89
|
* 2. Runtime — fire real requests and check response bodies against blocklists
|
|
99
90
|
* 3. Cross-privilege — admin routes return 403 for non-admin, error responses
|
|
100
91
|
* contain no sensitive fields
|
|
101
|
-
*
|
|
102
|
-
* @param options - test configuration
|
|
103
92
|
*/
|
|
104
93
|
export const describe_data_exposure_tests = (options) => {
|
|
105
94
|
const { build, sensitive_fields = SENSITIVE_FIELD_BLOCKLIST, admin_only_fields = ADMIN_ONLY_FIELD_BLOCKLIST, } = options;
|
package/dist/testing/db.d.ts
CHANGED
|
@@ -20,7 +20,8 @@ export interface DbFactory {
|
|
|
20
20
|
* Removes all tables, sequences, indexes, types, and functions.
|
|
21
21
|
* The database instance remains usable after reset.
|
|
22
22
|
*
|
|
23
|
-
* @
|
|
23
|
+
* @mutates db - drops the `public` schema and recreates it; all rows in all
|
|
24
|
+
* tables are gone after this returns.
|
|
24
25
|
*/
|
|
25
26
|
export declare const reset_pglite: (db: Db) => Promise<void>;
|
|
26
27
|
/**
|
|
@@ -33,7 +34,6 @@ export declare const reset_pglite: (db: Db) => Promise<void>;
|
|
|
33
34
|
* cold-start cost again.
|
|
34
35
|
*
|
|
35
36
|
* @param init_schema - callback to initialize the database schema
|
|
36
|
-
* @returns a factory that creates in-memory pglite databases
|
|
37
37
|
*/
|
|
38
38
|
export declare const create_pglite_factory: (init_schema: (db: Db) => Promise<void>) => DbFactory;
|
|
39
39
|
/**
|
|
@@ -50,7 +50,10 @@ export declare const create_pglite_factory: (init_schema: (db: Db) => Promise<vo
|
|
|
50
50
|
*
|
|
51
51
|
* @param init_schema - callback to initialize the database schema
|
|
52
52
|
* @param test_url - PostgreSQL connection URL (e.g. from `TEST_DATABASE_URL`)
|
|
53
|
-
* @returns a factory that creates pg databases
|
|
53
|
+
* @returns a factory that creates pg databases. The returned `create()`
|
|
54
|
+
* throws when `test_url` is unset (despite the `skip: true` flag — defense
|
|
55
|
+
* against direct invocation), and rewrites Postgres "database does not
|
|
56
|
+
* exist" errors into a `createdb` hint message.
|
|
54
57
|
*/
|
|
55
58
|
export declare const create_pg_factory: (init_schema: (db: Db) => Promise<void>, test_url?: string) => DbFactory;
|
|
56
59
|
/**
|
|
@@ -86,7 +89,7 @@ export declare const AUTH_DROP_TABLES: readonly ["app_settings", "invite", "audi
|
|
|
86
89
|
* Safe on fresh databases (`IF EXISTS` on all statements). No-op effect for
|
|
87
90
|
* PGlite (already fresh), but harmless to call unconditionally.
|
|
88
91
|
*
|
|
89
|
-
* @
|
|
92
|
+
* @mutates db - drops every table in `AUTH_DROP_TABLES` plus `schema_version`.
|
|
90
93
|
*/
|
|
91
94
|
export declare const drop_auth_schema: (db: Db) => Promise<void>;
|
|
92
95
|
/**
|
|
@@ -99,13 +102,12 @@ export declare const drop_auth_schema: (db: Db) => Promise<void>;
|
|
|
99
102
|
*
|
|
100
103
|
* @param factories - one or more database factories to run suites against
|
|
101
104
|
* @param truncate_tables - tables to truncate between tests (children first for FK safety)
|
|
102
|
-
* @
|
|
105
|
+
* @mutates the underlying database between tests — `beforeEach` issues
|
|
106
|
+
* `TRUNCATE <truncate_tables> CASCADE` against the shared instance.
|
|
103
107
|
*/
|
|
104
108
|
export declare const create_describe_db: (factories: DbFactory | Array<DbFactory>, truncate_tables: Array<string>) => ((name: string, fn: (get_db: () => Db) => void) => void);
|
|
105
109
|
/**
|
|
106
110
|
* Log factory status to console.
|
|
107
|
-
*
|
|
108
|
-
* @param factories - the database factories to report on
|
|
109
111
|
*/
|
|
110
112
|
export declare const log_db_factory_status: (factories: Array<DbFactory>) => void;
|
|
111
113
|
//# sourceMappingURL=db.d.ts.map
|
package/dist/testing/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/db.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA6B7B,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAKpC;;GAEG;AACH,eAAO,MAAM,KAAK,SAA4B,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/db.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA6B7B,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAKpC;;GAEG;AACH,eAAO,MAAM,KAAK,SAA4B,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAU,IAAI,EAAE,KAAG,OAAO,CAAC,IAAI,CAGvD,CAAC;AAMF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,GAAI,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,KAAG,SAkB7E,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB,GAC7B,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EACtC,WAAW,MAAM,KACf,SA2DF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,UAQhC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,UAAyC,CAAC;AAEvF;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,+IAWnB,CAAC;AAEX;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,GAAU,IAAI,EAAE,KAAG,OAAO,CAAC,IAAI,CAK3D,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,GAC9B,WAAW,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,EACvC,iBAAiB,KAAK,CAAC,MAAM,CAAC,KAC5B,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,KAAK,IAAI,CAwBzD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,KAAK,CAAC,SAAS,CAAC,KAAG,IAMnE,CAAC"}
|
package/dist/testing/db.js
CHANGED
|
@@ -36,7 +36,8 @@ export const IS_CI = process.env.CI === 'true';
|
|
|
36
36
|
* Removes all tables, sequences, indexes, types, and functions.
|
|
37
37
|
* The database instance remains usable after reset.
|
|
38
38
|
*
|
|
39
|
-
* @
|
|
39
|
+
* @mutates db - drops the `public` schema and recreates it; all rows in all
|
|
40
|
+
* tables are gone after this returns.
|
|
40
41
|
*/
|
|
41
42
|
export const reset_pglite = async (db) => {
|
|
42
43
|
await db.query('DROP SCHEMA public CASCADE');
|
|
@@ -55,7 +56,6 @@ let module_db = null;
|
|
|
55
56
|
* cold-start cost again.
|
|
56
57
|
*
|
|
57
58
|
* @param init_schema - callback to initialize the database schema
|
|
58
|
-
* @returns a factory that creates in-memory pglite databases
|
|
59
59
|
*/
|
|
60
60
|
export const create_pglite_factory = (init_schema) => ({
|
|
61
61
|
name: 'pglite',
|
|
@@ -91,7 +91,10 @@ export const create_pglite_factory = (init_schema) => ({
|
|
|
91
91
|
*
|
|
92
92
|
* @param init_schema - callback to initialize the database schema
|
|
93
93
|
* @param test_url - PostgreSQL connection URL (e.g. from `TEST_DATABASE_URL`)
|
|
94
|
-
* @returns a factory that creates pg databases
|
|
94
|
+
* @returns a factory that creates pg databases. The returned `create()`
|
|
95
|
+
* throws when `test_url` is unset (despite the `skip: true` flag — defense
|
|
96
|
+
* against direct invocation), and rewrites Postgres "database does not
|
|
97
|
+
* exist" errors into a `createdb` hint message.
|
|
95
98
|
*/
|
|
96
99
|
export const create_pg_factory = (init_schema, test_url) => {
|
|
97
100
|
const should_skip = !test_url;
|
|
@@ -204,7 +207,7 @@ export const AUTH_DROP_TABLES = [
|
|
|
204
207
|
* Safe on fresh databases (`IF EXISTS` on all statements). No-op effect for
|
|
205
208
|
* PGlite (already fresh), but harmless to call unconditionally.
|
|
206
209
|
*
|
|
207
|
-
* @
|
|
210
|
+
* @mutates db - drops every table in `AUTH_DROP_TABLES` plus `schema_version`.
|
|
208
211
|
*/
|
|
209
212
|
export const drop_auth_schema = async (db) => {
|
|
210
213
|
for (const table of AUTH_DROP_TABLES) {
|
|
@@ -222,7 +225,8 @@ export const drop_auth_schema = async (db) => {
|
|
|
222
225
|
*
|
|
223
226
|
* @param factories - one or more database factories to run suites against
|
|
224
227
|
* @param truncate_tables - tables to truncate between tests (children first for FK safety)
|
|
225
|
-
* @
|
|
228
|
+
* @mutates the underlying database between tests — `beforeEach` issues
|
|
229
|
+
* `TRUNCATE <truncate_tables> CASCADE` against the shared instance.
|
|
226
230
|
*/
|
|
227
231
|
export const create_describe_db = (factories, truncate_tables) => {
|
|
228
232
|
const factory_list = Array.isArray(factories) ? factories : [factories];
|
|
@@ -250,8 +254,6 @@ export const create_describe_db = (factories, truncate_tables) => {
|
|
|
250
254
|
};
|
|
251
255
|
/**
|
|
252
256
|
* Log factory status to console.
|
|
253
|
-
*
|
|
254
|
-
* @param factories - the database factories to report on
|
|
255
257
|
*/
|
|
256
258
|
export const log_db_factory_status = (factories) => {
|
|
257
259
|
const enabled = factories.filter((f) => !f.skip).map((f) => f.name);
|
|
@@ -71,12 +71,11 @@ export declare class ErrorCoverageCollector {
|
|
|
71
71
|
* (e.g., `/api/accounts/abc` → `/api/accounts/:id`). When `code` is provided,
|
|
72
72
|
* it is stored alongside the status for per-code coverage tracking.
|
|
73
73
|
*
|
|
74
|
-
* @param route_specs - route specs for path resolution
|
|
75
|
-
* @param method - HTTP method
|
|
76
74
|
* @param path - request path (may be concrete)
|
|
77
|
-
* @param status - observed HTTP status code
|
|
78
75
|
* @param code - observed body `error` code (pass when the route's error
|
|
79
76
|
* schema declares specific codes via `z.literal` or `z.enum`)
|
|
77
|
+
* @mutates `this.observed` - adds the resolved `"METHOD /spec-path:STATUS"`
|
|
78
|
+
* key (and the `:CODE` variant when `code` is provided).
|
|
80
79
|
*/
|
|
81
80
|
record(route_specs: Array<RouteSpec>, method: string, path: string, status: number, code?: string): void;
|
|
82
81
|
/**
|
|
@@ -88,13 +87,13 @@ export declare class ErrorCoverageCollector {
|
|
|
88
87
|
* for per-code coverage. Pass an explicit `code` to override the
|
|
89
88
|
* auto-extracted value or when the body was already consumed.
|
|
90
89
|
*
|
|
91
|
-
* @param route_specs - route specs for schema lookup and path resolution
|
|
92
|
-
* @param method - HTTP method
|
|
93
|
-
* @param path - request path
|
|
94
|
-
* @param response - the Response to validate and record
|
|
95
90
|
* @param code - observed body `error` code (override; if omitted and the
|
|
96
91
|
* response body is a JSON object with a string `error` field, that value
|
|
97
92
|
* is auto-extracted)
|
|
93
|
+
* @mutates `this.observed` - via `record` after `assert_response_matches_spec`
|
|
94
|
+
* succeeds.
|
|
95
|
+
* @throws Error if the response body fails the route spec's declared
|
|
96
|
+
* schemas (propagated from `assert_response_matches_spec`).
|
|
98
97
|
*/
|
|
99
98
|
assert_and_record(route_specs: Array<RouteSpec>, method: string, path: string, response: Response, code?: string): Promise<void>;
|
|
100
99
|
/**
|
|
@@ -105,10 +104,6 @@ export declare class ErrorCoverageCollector {
|
|
|
105
104
|
* `z.enum`), reports per-code rows; otherwise reports one row per status.
|
|
106
105
|
* A status-only observation (no code) satisfies all declared codes for that
|
|
107
106
|
* status — the "any-code" rule.
|
|
108
|
-
*
|
|
109
|
-
* @param route_specs - route specs to check coverage against
|
|
110
|
-
* @param options - exclusion configuration (skip routes or statuses)
|
|
111
|
-
* @returns uncovered entries with method, path, status, and optional code
|
|
112
107
|
*/
|
|
113
108
|
uncovered(route_specs: Array<RouteSpec>, options?: CoverageFilterOptions): Array<UncoveredEntry>;
|
|
114
109
|
}
|
|
@@ -136,9 +131,9 @@ export interface ErrorCoverageOptions extends CoverageFilterOptions {
|
|
|
136
131
|
* When `min_coverage` is 0 (default), logs coverage info without failing.
|
|
137
132
|
* When > 0, fails if coverage is below the threshold.
|
|
138
133
|
*
|
|
139
|
-
* @
|
|
140
|
-
*
|
|
141
|
-
*
|
|
134
|
+
* @throws AssertionError if `min_coverage > 0` and the covered/total ratio
|
|
135
|
+
* falls below the threshold — the failure message lists every uncovered
|
|
136
|
+
* route + status (+ code).
|
|
142
137
|
*/
|
|
143
138
|
export declare const assert_error_coverage: (collector: ErrorCoverageCollector, route_specs: Array<RouteSpec>, options?: ErrorCoverageOptions) => void;
|
|
144
139
|
//# sourceMappingURL=error_coverage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error_coverage.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/error_coverage.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;;;;GAWG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAIrD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,MAAM,CAAC,GAAG,IAWhF,CAAC;AAEF,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,6EAA6E;AAC7E,MAAM,WAAW,qBAAqB;IACrC,kDAAkD;IAClD,aAAa,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B,iCAAiC;IACjC,eAAe,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAChC;AAqDD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,sBAAsB;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAE3C
|
|
1
|
+
{"version":3,"file":"error_coverage.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/error_coverage.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;;;;GAWG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAIrD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,MAAM,CAAC,GAAG,IAWhF,CAAC;AAEF,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,6EAA6E;AAC7E,MAAM,WAAW,qBAAqB;IACrC,kDAAkD;IAClD,aAAa,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B,iCAAiC;IACjC,eAAe,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAChC;AAqDD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,sBAAsB;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAE3C;;;;;;;;;;;;OAYG;IACH,MAAM,CACL,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,EAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,GACX,IAAI;IAUP;;;;;;;;;;;;;;;;OAgBG;IACG,iBAAiB,CACtB,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,EAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAgBhB;;;;;;;;OAQG;IACH,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAC,cAAc,CAAC;CAKhG;AAED;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,MAAM,CAAC;AAEtD,2CAA2C;AAC3C,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;IAClE,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAaD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,qBAAqB,GACjC,WAAW,sBAAsB,EACjC,aAAa,KAAK,CAAC,SAAS,CAAC,EAC7B,UAAU,oBAAoB,KAC5B,IAqBF,CAAC"}
|
|
@@ -113,12 +113,11 @@ export class ErrorCoverageCollector {
|
|
|
113
113
|
* (e.g., `/api/accounts/abc` → `/api/accounts/:id`). When `code` is provided,
|
|
114
114
|
* it is stored alongside the status for per-code coverage tracking.
|
|
115
115
|
*
|
|
116
|
-
* @param route_specs - route specs for path resolution
|
|
117
|
-
* @param method - HTTP method
|
|
118
116
|
* @param path - request path (may be concrete)
|
|
119
|
-
* @param status - observed HTTP status code
|
|
120
117
|
* @param code - observed body `error` code (pass when the route's error
|
|
121
118
|
* schema declares specific codes via `z.literal` or `z.enum`)
|
|
119
|
+
* @mutates `this.observed` - adds the resolved `"METHOD /spec-path:STATUS"`
|
|
120
|
+
* key (and the `:CODE` variant when `code` is provided).
|
|
122
121
|
*/
|
|
123
122
|
record(route_specs, method, path, status, code) {
|
|
124
123
|
const spec = find_route_spec(route_specs, method, path);
|
|
@@ -138,13 +137,13 @@ export class ErrorCoverageCollector {
|
|
|
138
137
|
* for per-code coverage. Pass an explicit `code` to override the
|
|
139
138
|
* auto-extracted value or when the body was already consumed.
|
|
140
139
|
*
|
|
141
|
-
* @param route_specs - route specs for schema lookup and path resolution
|
|
142
|
-
* @param method - HTTP method
|
|
143
|
-
* @param path - request path
|
|
144
|
-
* @param response - the Response to validate and record
|
|
145
140
|
* @param code - observed body `error` code (override; if omitted and the
|
|
146
141
|
* response body is a JSON object with a string `error` field, that value
|
|
147
142
|
* is auto-extracted)
|
|
143
|
+
* @mutates `this.observed` - via `record` after `assert_response_matches_spec`
|
|
144
|
+
* succeeds.
|
|
145
|
+
* @throws Error if the response body fails the route spec's declared
|
|
146
|
+
* schemas (propagated from `assert_response_matches_spec`).
|
|
148
147
|
*/
|
|
149
148
|
async assert_and_record(route_specs, method, path, response, code) {
|
|
150
149
|
await assert_response_matches_spec(route_specs, method, path, response);
|
|
@@ -170,10 +169,6 @@ export class ErrorCoverageCollector {
|
|
|
170
169
|
* `z.enum`), reports per-code rows; otherwise reports one row per status.
|
|
171
170
|
* A status-only observation (no code) satisfies all declared codes for that
|
|
172
171
|
* status — the "any-code" rule.
|
|
173
|
-
*
|
|
174
|
-
* @param route_specs - route specs to check coverage against
|
|
175
|
-
* @param options - exclusion configuration (skip routes or statuses)
|
|
176
|
-
* @returns uncovered entries with method, path, status, and optional code
|
|
177
172
|
*/
|
|
178
173
|
uncovered(route_specs, options) {
|
|
179
174
|
return walk_coverage(this, route_specs, options)
|
|
@@ -207,9 +202,9 @@ const format_uncovered = (entry) => `${entry.method} ${entry.path} → ${entry.s
|
|
|
207
202
|
* When `min_coverage` is 0 (default), logs coverage info without failing.
|
|
208
203
|
* When > 0, fails if coverage is below the threshold.
|
|
209
204
|
*
|
|
210
|
-
* @
|
|
211
|
-
*
|
|
212
|
-
*
|
|
205
|
+
* @throws AssertionError if `min_coverage > 0` and the covered/total ratio
|
|
206
|
+
* falls below the threshold — the failure message lists every uncovered
|
|
207
|
+
* route + status (+ code).
|
|
213
208
|
*/
|
|
214
209
|
export const assert_error_coverage = (collector, route_specs, options) => {
|
|
215
210
|
const min_coverage = options?.min_coverage ?? 0;
|
|
@@ -51,7 +51,10 @@ export interface StandardIntegrationTestOptions {
|
|
|
51
51
|
* Each test group asserts that required routes exist, failing with a descriptive
|
|
52
52
|
* message if the consumer's route specs are misconfigured.
|
|
53
53
|
*
|
|
54
|
-
* @
|
|
54
|
+
* @throws Error at setup time when `options.rpc_endpoints` is empty — the
|
|
55
|
+
* suite hard-fails via `require_rpc_endpoint_path` rather than running
|
|
56
|
+
* tests that would crash mid-suite trying to dispatch
|
|
57
|
+
* `account_verify` / `account_session_*` / `account_token_*`.
|
|
55
58
|
*/
|
|
56
59
|
export declare const describe_standard_integration_tests: (options: StandardIntegrationTestOptions) => void;
|
|
57
60
|
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAsB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAA6C,KAAK,eAAe,EAAC,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAOjB,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAqB1B;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC9C,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,EAAE,uBAAuB,CAAC;CACvC;AAsBD
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAsB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAA6C,KAAK,eAAe,EAAC,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAOjB,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAqB1B;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC9C,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,EAAE,uBAAuB,CAAC;CACvC;AAsBD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mCAAmC,GAC/C,SAAS,8BAA8B,KACrC,IAg8CF,CAAC"}
|
|
@@ -56,7 +56,10 @@ const build_test_app_options = (options, db) => ({
|
|
|
56
56
|
* Each test group asserts that required routes exist, failing with a descriptive
|
|
57
57
|
* message if the consumer's route specs are misconfigured.
|
|
58
58
|
*
|
|
59
|
-
* @
|
|
59
|
+
* @throws Error at setup time when `options.rpc_endpoints` is empty — the
|
|
60
|
+
* suite hard-fails via `require_rpc_endpoint_path` rather than running
|
|
61
|
+
* tests that would crash mid-suite trying to dispatch
|
|
62
|
+
* `account_verify` / `account_session_*` / `account_token_*`.
|
|
60
63
|
*/
|
|
61
64
|
export const describe_standard_integration_tests = (options) => {
|
|
62
65
|
// Hard-fail early so consumers see a clear setup error instead of a
|
|
@@ -8,10 +8,7 @@ import type { TestApp, TestAccount } from './app_server.js';
|
|
|
8
8
|
*
|
|
9
9
|
* Supports both exact matches and parameterized paths (`:param` segments).
|
|
10
10
|
*
|
|
11
|
-
* @param specs - route specs to search
|
|
12
|
-
* @param method - HTTP method
|
|
13
11
|
* @param path - request path (exact or with concrete param values)
|
|
14
|
-
* @returns matching route spec, or `undefined`
|
|
15
12
|
*/
|
|
16
13
|
export declare const find_route_spec: (specs: Array<RouteSpec>, method: string, path: string) => RouteSpec | undefined;
|
|
17
14
|
/**
|
|
@@ -31,10 +28,7 @@ export type RestAuthRouteSuffix = (typeof REST_AUTH_ROUTE_SUFFIXES)[number];
|
|
|
31
28
|
* method name (e.g. `/sessions/revoke-all`) fails loudly at the call site
|
|
32
29
|
* instead of silently returning `undefined`.
|
|
33
30
|
*
|
|
34
|
-
* @
|
|
35
|
-
* @param suffix - REST auth path suffix
|
|
36
|
-
* @param method - HTTP method
|
|
37
|
-
* @returns matching route spec, or `undefined`
|
|
31
|
+
* @throws Error if `suffix` is not in `REST_AUTH_ROUTE_SUFFIXES`.
|
|
38
32
|
*/
|
|
39
33
|
export declare const find_auth_route: (specs: Array<RouteSpec>, suffix: RestAuthRouteSuffix, method: RouteMethod) => RouteSpec | undefined;
|
|
40
34
|
/**
|
|
@@ -42,31 +36,22 @@ export declare const find_auth_route: (specs: Array<RouteSpec>, suffix: RestAuth
|
|
|
42
36
|
*
|
|
43
37
|
* For 2xx responses, validates against `spec.output`.
|
|
44
38
|
* For error responses, validates against the merged error schema for that status code.
|
|
45
|
-
* Throws with details on mismatch.
|
|
46
39
|
*
|
|
47
|
-
* @
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* @param response - the Response to validate
|
|
40
|
+
* @throws Error if no route spec matches `method` + `path`, if the response
|
|
41
|
+
* body fails to parse against the declared output / error schema, or if the
|
|
42
|
+
* response is non-JSON despite a declared schema for that status.
|
|
51
43
|
*/
|
|
52
44
|
export declare const assert_response_matches_spec: (route_specs: Array<RouteSpec>, method: string, path: string, response: Response) => Promise<void>;
|
|
53
45
|
/**
|
|
54
46
|
* Create an expired test cookie — validly signed but with an expiry timestamp in 1970.
|
|
55
|
-
*
|
|
56
|
-
* @param keyring - keyring for signing
|
|
57
|
-
* @param session_options - session config
|
|
58
|
-
* @returns signed cookie value with long-past expiry
|
|
59
47
|
*/
|
|
60
48
|
export declare const create_expired_test_cookie: (keyring: Keyring, session_options: SessionOptions<string>) => Promise<string>;
|
|
61
49
|
/**
|
|
62
|
-
*
|
|
50
|
+
* List the fields in an error response body that are not in the known-safe set.
|
|
63
51
|
*
|
|
64
52
|
* Error schemas use `z.looseObject` (intentional — multiple producers), but
|
|
65
53
|
* test responses should be checked for fields that could leak information.
|
|
66
|
-
* Flags any field not in the known-safe set.
|
|
67
54
|
*
|
|
68
|
-
* @param body - parsed error response JSON
|
|
69
|
-
* @param context - description for error messages (e.g., `'POST /api/login 401'`)
|
|
70
55
|
* @returns array of unexpected field names (empty = clean)
|
|
71
56
|
*/
|
|
72
57
|
export declare const check_error_response_fields: (body: Record<string, unknown>) => Array<string>;
|
|
@@ -76,16 +61,12 @@ export declare const check_error_response_fields: (body: Record<string, unknown>
|
|
|
76
61
|
* Checks both field names and string values for patterns indicating
|
|
77
62
|
* stack traces, SQL, or internal paths.
|
|
78
63
|
*
|
|
79
|
-
* @param body - parsed error response JSON
|
|
80
64
|
* @param context - description for error messages
|
|
81
65
|
*/
|
|
82
66
|
export declare const assert_no_error_info_leakage: (body: Record<string, unknown>, context: string) => void;
|
|
83
67
|
/**
|
|
84
68
|
* Assert that a 429 response includes a valid `Retry-After` header
|
|
85
69
|
* matching the JSON body's `retry_after` field.
|
|
86
|
-
*
|
|
87
|
-
* @param response - the 429 response
|
|
88
|
-
* @param body - parsed JSON body with `retry_after` field
|
|
89
70
|
*/
|
|
90
71
|
export declare const assert_rate_limit_retry_after_header: (response: Response, body: {
|
|
91
72
|
retry_after: number;
|
|
@@ -98,16 +79,11 @@ export declare const ADMIN_ONLY_FIELD_BLOCKLIST: ReadonlyArray<string>;
|
|
|
98
79
|
* Recursively collect all key names from a parsed JSON value.
|
|
99
80
|
*
|
|
100
81
|
* Walks objects and arrays to find every property name at any nesting depth.
|
|
101
|
-
*
|
|
102
|
-
* @param value - parsed JSON value
|
|
103
|
-
* @returns set of all key names found
|
|
104
82
|
*/
|
|
105
83
|
export declare const collect_json_keys_recursive: (value: unknown) => Set<string>;
|
|
106
84
|
/**
|
|
107
85
|
* Assert that a parsed JSON body contains no fields from the given blocklist.
|
|
108
86
|
*
|
|
109
|
-
* @param body - parsed response JSON
|
|
110
|
-
* @param blocklist - field names to check for
|
|
111
87
|
* @param context - description for error messages
|
|
112
88
|
*/
|
|
113
89
|
export declare const assert_no_sensitive_fields_in_json: (body: unknown, blocklist: ReadonlyArray<string>, context: string) => void;
|
|
@@ -120,11 +96,6 @@ export declare const assert_no_sensitive_fields_in_json: (body: unknown, blockli
|
|
|
120
96
|
* - `role: admin` — the admin account's session cookie
|
|
121
97
|
* - `role: <other>` — the test app's bootstrapped keeper session
|
|
122
98
|
* - `keeper` — the test app's daemon token
|
|
123
|
-
*
|
|
124
|
-
* @param spec - route spec to inspect
|
|
125
|
-
* @param test_app - the assembled test app (for bootstrapped credentials)
|
|
126
|
-
* @param authed_account - an account with no roles (for `authenticated` auth)
|
|
127
|
-
* @param admin_account - an account with `admin` role (for role-gated routes)
|
|
128
99
|
*/
|
|
129
100
|
export declare const pick_auth_headers: (spec: RouteSpec, test_app: TestApp, authed_account: TestAccount, admin_account: TestAccount) => Record<string, string>;
|
|
130
101
|
//# sourceMappingURL=integration_helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAU7B,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAC,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAA8B,KAAK,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAE3F,OAAO,KAAK,EAAC,OAAO,EAAE,WAAW,EAAC,MAAM,iBAAiB,CAAC;AAE1D
|
|
1
|
+
{"version":3,"file":"integration_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAU7B,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAC,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAA8B,KAAK,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAE3F,OAAO,KAAK,EAAC,OAAO,EAAE,WAAW,EAAC,MAAM,iBAAiB,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC3B,OAAO,KAAK,CAAC,SAAS,CAAC,EACvB,QAAQ,MAAM,EACd,MAAM,MAAM,KACV,SAAS,GAAG,SAad,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,iFAO3B,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAC3B,OAAO,KAAK,CAAC,SAAS,CAAC,EACvB,QAAQ,mBAAmB,EAC3B,QAAQ,WAAW,KACjB,SAAS,GAAG,SAOd,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,GACxC,aAAa,KAAK,CAAC,SAAS,CAAC,EAC7B,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,UAAU,QAAQ,KAChB,OAAO,CAAC,IAAI,CAmDd,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B,GACtC,SAAS,OAAO,EAChB,iBAAiB,cAAc,CAAC,MAAM,CAAC,KACrC,OAAO,CAAC,MAAM,CAGhB,CAAC;AAgCF;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GAAI,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,KAAK,CAAC,MAAM,CAQvF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,GACxC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,MAAM,KACb,IAkBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oCAAoC,GAChD,UAAU,QAAQ,EAClB,MAAM;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,KACzB,IAUF,CAAC;AAIF,oEAAoE;AACpE,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,MAAM,CAAmC,CAAC;AAEhG,0EAA0E;AAC1E,eAAO,MAAM,0BAA0B,EAAE,aAAa,CAAC,MAAM,CAAgC,CAAC;AAE9F;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GAAI,OAAO,OAAO,KAAG,GAAG,CAAC,MAAM,CAetE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,GAC9C,MAAM,OAAO,EACb,WAAW,aAAa,CAAC,MAAM,CAAC,EAChC,SAAS,MAAM,KACb,IAKF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAC7B,MAAM,SAAS,EACf,UAAU,OAAO,EACjB,gBAAgB,WAAW,EAC3B,eAAe,WAAW,KACxB,MAAM,CAAC,MAAM,EAAE,MAAM,CAcvB,CAAC"}
|
|
@@ -13,10 +13,7 @@ import { ROLE_ADMIN } from '../auth/role_schema.js';
|
|
|
13
13
|
*
|
|
14
14
|
* Supports both exact matches and parameterized paths (`:param` segments).
|
|
15
15
|
*
|
|
16
|
-
* @param specs - route specs to search
|
|
17
|
-
* @param method - HTTP method
|
|
18
16
|
* @param path - request path (exact or with concrete param values)
|
|
19
|
-
* @returns matching route spec, or `undefined`
|
|
20
17
|
*/
|
|
21
18
|
export const find_route_spec = (specs, method, path) => {
|
|
22
19
|
// exact match first
|
|
@@ -57,10 +54,7 @@ export const REST_AUTH_ROUTE_SUFFIXES = [
|
|
|
57
54
|
* method name (e.g. `/sessions/revoke-all`) fails loudly at the call site
|
|
58
55
|
* instead of silently returning `undefined`.
|
|
59
56
|
*
|
|
60
|
-
* @
|
|
61
|
-
* @param suffix - REST auth path suffix
|
|
62
|
-
* @param method - HTTP method
|
|
63
|
-
* @returns matching route spec, or `undefined`
|
|
57
|
+
* @throws Error if `suffix` is not in `REST_AUTH_ROUTE_SUFFIXES`.
|
|
64
58
|
*/
|
|
65
59
|
export const find_auth_route = (specs, suffix, method) => {
|
|
66
60
|
if (!REST_AUTH_ROUTE_SUFFIXES.includes(suffix)) {
|
|
@@ -73,12 +67,10 @@ export const find_auth_route = (specs, suffix, method) => {
|
|
|
73
67
|
*
|
|
74
68
|
* For 2xx responses, validates against `spec.output`.
|
|
75
69
|
* For error responses, validates against the merged error schema for that status code.
|
|
76
|
-
* Throws with details on mismatch.
|
|
77
70
|
*
|
|
78
|
-
* @
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* @param response - the Response to validate
|
|
71
|
+
* @throws Error if no route spec matches `method` + `path`, if the response
|
|
72
|
+
* body fails to parse against the declared output / error schema, or if the
|
|
73
|
+
* response is non-JSON despite a declared schema for that status.
|
|
82
74
|
*/
|
|
83
75
|
export const assert_response_matches_spec = async (route_specs, method, path, response) => {
|
|
84
76
|
const spec = find_route_spec(route_specs, method, path);
|
|
@@ -126,22 +118,11 @@ export const assert_response_matches_spec = async (route_specs, method, path, re
|
|
|
126
118
|
};
|
|
127
119
|
/**
|
|
128
120
|
* Create an expired test cookie — validly signed but with an expiry timestamp in 1970.
|
|
129
|
-
*
|
|
130
|
-
* @param keyring - keyring for signing
|
|
131
|
-
* @param session_options - session config
|
|
132
|
-
* @returns signed cookie value with long-past expiry
|
|
133
121
|
*/
|
|
134
122
|
export const create_expired_test_cookie = async (keyring, session_options) => {
|
|
135
123
|
// now_seconds=1 puts the expiry at 1 + max_age seconds past epoch — still in 1970
|
|
136
124
|
return create_session_cookie_value(keyring, 'expired_test_token', session_options, 1);
|
|
137
125
|
};
|
|
138
|
-
/**
|
|
139
|
-
* Assert that a 429 response includes a valid `Retry-After` header
|
|
140
|
-
* matching the JSON body's `retry_after` field.
|
|
141
|
-
*
|
|
142
|
-
* @param response - the 429 response
|
|
143
|
-
* @param body - parsed JSON body with `retry_after` field
|
|
144
|
-
*/
|
|
145
126
|
/**
|
|
146
127
|
* Known safe fields that may appear in any error response.
|
|
147
128
|
*
|
|
@@ -171,14 +152,11 @@ const LEAKY_FIELD_PATTERNS = [
|
|
|
171
152
|
'token',
|
|
172
153
|
];
|
|
173
154
|
/**
|
|
174
|
-
*
|
|
155
|
+
* List the fields in an error response body that are not in the known-safe set.
|
|
175
156
|
*
|
|
176
157
|
* Error schemas use `z.looseObject` (intentional — multiple producers), but
|
|
177
158
|
* test responses should be checked for fields that could leak information.
|
|
178
|
-
* Flags any field not in the known-safe set.
|
|
179
159
|
*
|
|
180
|
-
* @param body - parsed error response JSON
|
|
181
|
-
* @param context - description for error messages (e.g., `'POST /api/login 401'`)
|
|
182
160
|
* @returns array of unexpected field names (empty = clean)
|
|
183
161
|
*/
|
|
184
162
|
export const check_error_response_fields = (body) => {
|
|
@@ -196,7 +174,6 @@ export const check_error_response_fields = (body) => {
|
|
|
196
174
|
* Checks both field names and string values for patterns indicating
|
|
197
175
|
* stack traces, SQL, or internal paths.
|
|
198
176
|
*
|
|
199
|
-
* @param body - parsed error response JSON
|
|
200
177
|
* @param context - description for error messages
|
|
201
178
|
*/
|
|
202
179
|
export const assert_no_error_info_leakage = (body, context) => {
|
|
@@ -215,9 +192,6 @@ export const assert_no_error_info_leakage = (body, context) => {
|
|
|
215
192
|
/**
|
|
216
193
|
* Assert that a 429 response includes a valid `Retry-After` header
|
|
217
194
|
* matching the JSON body's `retry_after` field.
|
|
218
|
-
*
|
|
219
|
-
* @param response - the 429 response
|
|
220
|
-
* @param body - parsed JSON body with `retry_after` field
|
|
221
195
|
*/
|
|
222
196
|
export const assert_rate_limit_retry_after_header = (response, body) => {
|
|
223
197
|
const header = response.headers.get('Retry-After');
|
|
@@ -235,9 +209,6 @@ export const ADMIN_ONLY_FIELD_BLOCKLIST = ['updated_by', 'created_by'];
|
|
|
235
209
|
* Recursively collect all key names from a parsed JSON value.
|
|
236
210
|
*
|
|
237
211
|
* Walks objects and arrays to find every property name at any nesting depth.
|
|
238
|
-
*
|
|
239
|
-
* @param value - parsed JSON value
|
|
240
|
-
* @returns set of all key names found
|
|
241
212
|
*/
|
|
242
213
|
export const collect_json_keys_recursive = (value) => {
|
|
243
214
|
const keys = new Set();
|
|
@@ -260,8 +231,6 @@ export const collect_json_keys_recursive = (value) => {
|
|
|
260
231
|
/**
|
|
261
232
|
* Assert that a parsed JSON body contains no fields from the given blocklist.
|
|
262
233
|
*
|
|
263
|
-
* @param body - parsed response JSON
|
|
264
|
-
* @param blocklist - field names to check for
|
|
265
234
|
* @param context - description for error messages
|
|
266
235
|
*/
|
|
267
236
|
export const assert_no_sensitive_fields_in_json = (body, blocklist, context) => {
|
|
@@ -279,11 +248,6 @@ export const assert_no_sensitive_fields_in_json = (body, blocklist, context) =>
|
|
|
279
248
|
* - `role: admin` — the admin account's session cookie
|
|
280
249
|
* - `role: <other>` — the test app's bootstrapped keeper session
|
|
281
250
|
* - `keeper` — the test app's daemon token
|
|
282
|
-
*
|
|
283
|
-
* @param spec - route spec to inspect
|
|
284
|
-
* @param test_app - the assembled test app (for bootstrapped credentials)
|
|
285
|
-
* @param authed_account - an account with no roles (for `authenticated` auth)
|
|
286
|
-
* @param admin_account - an account with `admin` role (for role-gated routes)
|
|
287
251
|
*/
|
|
288
252
|
export const pick_auth_headers = (spec, test_app, authed_account, admin_account) => {
|
|
289
253
|
switch (spec.auth.type) {
|