@fuzdev/fuz_app 0.55.0 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/CLAUDE.md +211 -155
- 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 +19 -0
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +20 -14
- 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 +110 -44
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +92 -287
- 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 +44 -38
- 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 +2 -10
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +32 -10
- 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 +673 -442
- 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 +8 -14
- package/dist/auth/account_actions.d.ts.map +1 -1
- package/dist/auth/account_actions.js +26 -32
- package/dist/auth/account_queries.d.ts +46 -13
- package/dist/auth/account_queries.d.ts.map +1 -1
- package/dist/auth/account_queries.js +73 -33
- package/dist/auth/account_routes.d.ts +4 -3
- package/dist/auth/account_routes.d.ts.map +1 -1
- package/dist/auth/account_routes.js +58 -33
- package/dist/auth/account_schema.d.ts +46 -54
- package/dist/auth/account_schema.d.ts.map +1 -1
- package/dist/auth/account_schema.js +21 -48
- package/dist/auth/admin_action_specs.d.ts +55 -21
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_action_specs.js +42 -26
- package/dist/auth/admin_actions.d.ts +14 -21
- package/dist/auth/admin_actions.d.ts.map +1 -1
- package/dist/auth/admin_actions.js +47 -44
- 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 -87
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.js +17 -96
- 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 +48 -42
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +56 -43
- 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/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 -47
- 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 +1 -1
- package/dist/auth/daemon_token_middleware.js +3 -3
- 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 -32
- 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 +5 -2
- package/dist/auth/migrations.d.ts +22 -7
- package/dist/auth/migrations.d.ts.map +1 -1
- package/dist/auth/migrations.js +64 -25
- package/dist/auth/request_context.d.ts +157 -170
- package/dist/auth/request_context.d.ts.map +1 -1
- package/dist/auth/request_context.js +224 -268
- package/dist/auth/{permit_offer_action_specs.d.ts → role_grant_offer_action_specs.d.ts} +130 -100
- 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/{permit_offer_actions.js → role_grant_offer_actions.js} +153 -140
- package/dist/auth/{permit_offer_notifications.d.ts → role_grant_offer_notifications.d.ts} +80 -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/{permit_offer_queries.d.ts → role_grant_offer_queries.d.ts} +64 -64
- package/dist/auth/role_grant_offer_queries.d.ts.map +1 -0
- package/dist/auth/{permit_offer_queries.js → role_grant_offer_queries.js} +136 -123
- 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} +55 -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 +4 -1
- package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
- package/dist/auth/self_service_role_action_specs.js +2 -2
- package/dist/auth/self_service_role_actions.d.ts +35 -29
- package/dist/auth/self_service_role_actions.d.ts.map +1 -1
- package/dist/auth/self_service_role_actions.js +58 -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 +1 -1
- package/dist/db/migrate.js +1 -1
- package/dist/dev/setup.d.ts +2 -2
- package/dist/dev/setup.d.ts.map +1 -1
- package/dist/dev/setup.js +4 -4
- package/dist/env/load.d.ts +1 -1
- package/dist/env/load.js +1 -1
- package/dist/hono_context.d.ts +27 -45
- package/dist/hono_context.d.ts.map +1 -1
- package/dist/hono_context.js +14 -28
- package/dist/http/CLAUDE.md +235 -121
- 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 +56 -34
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +63 -28
- 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 +89 -75
- package/dist/http/route_spec.d.ts.map +1 -1
- package/dist/http/route_spec.js +54 -72
- package/dist/http/schema_helpers.d.ts +3 -14
- package/dist/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +2 -14
- package/dist/http/surface.d.ts +2 -10
- package/dist/http/surface.d.ts.map +1 -1
- package/dist/http/surface.js +3 -4
- 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 +35 -40
- package/dist/server/validate_nginx.d.ts +1 -1
- package/dist/server/validate_nginx.js +1 -1
- package/dist/testing/CLAUDE.md +50 -38
- 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 +87 -85
- 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 +16 -15
- 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 +36 -36
- 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 +22 -19
- 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 +8 -7
- package/dist/testing/entities.d.ts.map +1 -1
- package/dist/testing/entities.js +21 -18
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +13 -14
- package/dist/testing/integration_helpers.d.ts +4 -4
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/integration_helpers.js +20 -18
- package/dist/testing/middleware.d.ts +4 -4
- package/dist/testing/middleware.d.ts.map +1 -1
- package/dist/testing/middleware.js +12 -11
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.js +40 -24
- 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 +19 -11
- 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 +60 -60
- package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +27 -26
- package/dist/ui/{PermitOfferForm.svelte.d.ts → RoleGrantOfferForm.svelte.d.ts} +7 -7
- 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 +18 -18
- package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
- package/dist/ui/admin_accounts_state.svelte.js +16 -16
- 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} +30 -30
- 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} +18 -18
- 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 -258
- 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_notifications.d.ts.map +0 -1
- package/dist/auth/permit_offer_notifications.js +0 -182
- package/dist/auth/permit_offer_queries.d.ts.map +0 -1
- package/dist/auth/permit_offer_schema.d.ts +0 -125
- package/dist/auth/permit_offer_schema.d.ts.map +0 -1
- package/dist/auth/permit_queries.d.ts +0 -222
- package/dist/auth/permit_queries.d.ts.map +0 -1
- package/dist/auth/permit_queries.js +0 -305
- 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 -27
- package/dist/auth/route_guards.d.ts.map +0 -1
- package/dist/auth/route_guards.js +0 -38
- 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.map +0 -1
- package/dist/ui/PermitOfferHistory.svelte.d.ts.map +0 -1
- package/dist/ui/PermitOfferInbox.svelte.d.ts.map +0 -1
- package/dist/ui/permit_offers_state.svelte.d.ts.map +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reusable validator-schema primitives — `Username`, `UsernameProvided`,
|
|
3
|
+
* `Email`. Lives at the top level (not inside `auth/` or `http/`) because
|
|
4
|
+
* these shapes don't depend on or imply any domain — accounts hold a
|
|
5
|
+
* username and email, but invites, password resets, future cell-sharing,
|
|
6
|
+
* and other surfaces all reach for the same primitives without going
|
|
7
|
+
* through auth.
|
|
8
|
+
*
|
|
9
|
+
* Split out from `auth/account_schema.ts` so the auth module shrinks to
|
|
10
|
+
* entity types + client-safe JSON shapes (its real responsibility) and
|
|
11
|
+
* non-auth consumers can import these primitives without dragging the
|
|
12
|
+
* auth domain along. Future cross-domain primitives (phone, url, slug)
|
|
13
|
+
* land here too.
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
/** Minimum username length (must have start + middle + end characters). */
|
|
19
|
+
export declare const USERNAME_LENGTH_MIN = 3;
|
|
20
|
+
/** Maximum username length (matches GitHub's limit). */
|
|
21
|
+
export declare const USERNAME_LENGTH_MAX = 39;
|
|
22
|
+
/** Maximum length for username input on login/lookup — more permissive than `USERNAME_LENGTH_MAX` for forward-compatibility if the creation limit is raised. */
|
|
23
|
+
export declare const USERNAME_PROVIDED_LENGTH_MAX = 255;
|
|
24
|
+
/** Username for account creation — starts with letter, alphanumeric/dash/underscore middle, ends with alphanumeric. No @ or . allowed. */
|
|
25
|
+
export declare const Username: z.ZodString;
|
|
26
|
+
export type Username = z.infer<typeof Username>;
|
|
27
|
+
/** Username submitted for login or lookup — minimal validation for forward-compatibility if format rules change. */
|
|
28
|
+
export declare const UsernameProvided: z.ZodString;
|
|
29
|
+
export type UsernameProvided = z.infer<typeof UsernameProvided>;
|
|
30
|
+
/**
|
|
31
|
+
* Email validation. Lives here rather than `@fuzdev/fuz_util` because every
|
|
32
|
+
* current consumer pairs it with `Username` (signup, invites, audit log) —
|
|
33
|
+
* keeping the two together avoids a cross-package import for the
|
|
34
|
+
* identity-primitive bundle. Promote to fuz_util if a non-identity consumer
|
|
35
|
+
* surfaces.
|
|
36
|
+
*/
|
|
37
|
+
export declare const Email: z.ZodEmail;
|
|
38
|
+
export type Email = z.infer<typeof Email>;
|
|
39
|
+
//# sourceMappingURL=primitive_schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitive_schemas.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/primitive_schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAItB,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,wDAAwD;AACxD,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,gKAAgK;AAChK,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD,0IAA0I;AAC1I,eAAO,MAAM,QAAQ,aAIyB,CAAC;AAC/C,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEhD,oHAAoH;AACpH,eAAO,MAAM,gBAAgB,aAAsD,CAAC;AACpF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,YAAY,CAAC;AAC/B,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reusable validator-schema primitives — `Username`, `UsernameProvided`,
|
|
3
|
+
* `Email`. Lives at the top level (not inside `auth/` or `http/`) because
|
|
4
|
+
* these shapes don't depend on or imply any domain — accounts hold a
|
|
5
|
+
* username and email, but invites, password resets, future cell-sharing,
|
|
6
|
+
* and other surfaces all reach for the same primitives without going
|
|
7
|
+
* through auth.
|
|
8
|
+
*
|
|
9
|
+
* Split out from `auth/account_schema.ts` so the auth module shrinks to
|
|
10
|
+
* entity types + client-safe JSON shapes (its real responsibility) and
|
|
11
|
+
* non-auth consumers can import these primitives without dragging the
|
|
12
|
+
* auth domain along. Future cross-domain primitives (phone, url, slug)
|
|
13
|
+
* land here too.
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
// TODO consider `.brand()` on Username and Email for compile-time safety
|
|
19
|
+
/** Minimum username length (must have start + middle + end characters). */
|
|
20
|
+
export const USERNAME_LENGTH_MIN = 3;
|
|
21
|
+
/** Maximum username length (matches GitHub's limit). */
|
|
22
|
+
export const USERNAME_LENGTH_MAX = 39;
|
|
23
|
+
/** Maximum length for username input on login/lookup — more permissive than `USERNAME_LENGTH_MAX` for forward-compatibility if the creation limit is raised. */
|
|
24
|
+
export const USERNAME_PROVIDED_LENGTH_MAX = 255;
|
|
25
|
+
/** Username for account creation — starts with letter, alphanumeric/dash/underscore middle, ends with alphanumeric. No @ or . allowed. */
|
|
26
|
+
export const Username = z
|
|
27
|
+
.string()
|
|
28
|
+
.min(USERNAME_LENGTH_MIN)
|
|
29
|
+
.max(USERNAME_LENGTH_MAX)
|
|
30
|
+
.regex(/^[a-zA-Z][0-9a-zA-Z_-]*[0-9a-zA-Z]$/);
|
|
31
|
+
/** Username submitted for login or lookup — minimal validation for forward-compatibility if format rules change. */
|
|
32
|
+
export const UsernameProvided = z.string().min(1).max(USERNAME_PROVIDED_LENGTH_MAX);
|
|
33
|
+
/**
|
|
34
|
+
* Email validation. Lives here rather than `@fuzdev/fuz_util` because every
|
|
35
|
+
* current consumer pairs it with `Username` (signup, invites, audit log) —
|
|
36
|
+
* keeping the two together avoids a cross-package import for the
|
|
37
|
+
* identity-primitive bundle. Promote to fuz_util if a non-identity consumer
|
|
38
|
+
* surfaces.
|
|
39
|
+
*/
|
|
40
|
+
export const Email = z.email();
|
|
@@ -19,9 +19,9 @@ export declare const AUDIT_LOG_CHANNEL = "audit_log";
|
|
|
19
19
|
/**
|
|
20
20
|
* Audit event types that trigger SSE stream disconnection.
|
|
21
21
|
*
|
|
22
|
-
* `
|
|
22
|
+
* `role_grant_revoke` requires the revoked role to match the guard's `required_role`
|
|
23
23
|
* (or is skipped entirely when `required_role` is `null` — useful for streams
|
|
24
|
-
* not gated by any specific
|
|
24
|
+
* not gated by any specific role_grant).
|
|
25
25
|
* `session_revoke_all` and `password_change` close every stream for the target account.
|
|
26
26
|
* `session_revoke` closes only the stream tied to the specific revoked session
|
|
27
27
|
* (matched by the blake3 session hash in `event.metadata.session_id`) — closing
|
|
@@ -32,7 +32,7 @@ export declare const DISCONNECT_EVENT_TYPES: ReadonlySet<string>;
|
|
|
32
32
|
* Create an audit event handler that closes SSE streams on auth changes.
|
|
33
33
|
*
|
|
34
34
|
* Closes streams when:
|
|
35
|
-
* - `
|
|
35
|
+
* - `role_grant_revoke` fires for the `required_role` targeting a connected subscriber
|
|
36
36
|
* - `session_revoke_all` targets a connected subscriber (consistent invalidation)
|
|
37
37
|
* - `password_change` targets a connected subscriber (sessions revoked implicitly)
|
|
38
38
|
*
|
|
@@ -41,8 +41,8 @@ export declare const DISCONNECT_EVENT_TYPES: ReadonlySet<string>;
|
|
|
41
41
|
*
|
|
42
42
|
* @param registry - the subscriber registry to guard
|
|
43
43
|
* @param required_role - the role that grants access to the SSE endpoint,
|
|
44
|
-
* or `null` to skip `
|
|
45
|
-
* by a specific
|
|
44
|
+
* or `null` to skip `role_grant_revoke` handling entirely (for streams not gated
|
|
45
|
+
* by a specific role_grant)
|
|
46
46
|
* @param log - logger for disconnect events
|
|
47
47
|
* @returns an `on_audit_event` callback
|
|
48
48
|
*/
|
|
@@ -17,16 +17,16 @@ export const AUDIT_LOG_CHANNEL = 'audit_log';
|
|
|
17
17
|
/**
|
|
18
18
|
* Audit event types that trigger SSE stream disconnection.
|
|
19
19
|
*
|
|
20
|
-
* `
|
|
20
|
+
* `role_grant_revoke` requires the revoked role to match the guard's `required_role`
|
|
21
21
|
* (or is skipped entirely when `required_role` is `null` — useful for streams
|
|
22
|
-
* not gated by any specific
|
|
22
|
+
* not gated by any specific role_grant).
|
|
23
23
|
* `session_revoke_all` and `password_change` close every stream for the target account.
|
|
24
24
|
* `session_revoke` closes only the stream tied to the specific revoked session
|
|
25
25
|
* (matched by the blake3 session hash in `event.metadata.session_id`) — closing
|
|
26
26
|
* all of a user's streams for a single-session revoke would be over-aggressive.
|
|
27
27
|
*/
|
|
28
28
|
export const DISCONNECT_EVENT_TYPES = new Set([
|
|
29
|
-
'
|
|
29
|
+
'role_grant_revoke', // role revoked — user lost access
|
|
30
30
|
'session_revoke', // single session revoked — close only that stream
|
|
31
31
|
'session_revoke_all', // all sessions invalidated — user should be kicked
|
|
32
32
|
'password_change', // password changed — all sessions revoked implicitly
|
|
@@ -35,7 +35,7 @@ export const DISCONNECT_EVENT_TYPES = new Set([
|
|
|
35
35
|
* Create an audit event handler that closes SSE streams on auth changes.
|
|
36
36
|
*
|
|
37
37
|
* Closes streams when:
|
|
38
|
-
* - `
|
|
38
|
+
* - `role_grant_revoke` fires for the `required_role` targeting a connected subscriber
|
|
39
39
|
* - `session_revoke_all` targets a connected subscriber (consistent invalidation)
|
|
40
40
|
* - `password_change` targets a connected subscriber (sessions revoked implicitly)
|
|
41
41
|
*
|
|
@@ -44,8 +44,8 @@ export const DISCONNECT_EVENT_TYPES = new Set([
|
|
|
44
44
|
*
|
|
45
45
|
* @param registry - the subscriber registry to guard
|
|
46
46
|
* @param required_role - the role that grants access to the SSE endpoint,
|
|
47
|
-
* or `null` to skip `
|
|
48
|
-
* by a specific
|
|
47
|
+
* or `null` to skip `role_grant_revoke` handling entirely (for streams not gated
|
|
48
|
+
* by a specific role_grant)
|
|
49
49
|
* @param log - logger for disconnect events
|
|
50
50
|
* @returns an `on_audit_event` callback
|
|
51
51
|
*/
|
|
@@ -73,9 +73,9 @@ export const create_sse_auth_guard = (registry, required_role, log) => {
|
|
|
73
73
|
}
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
//
|
|
77
|
-
// stream isn't gated by a specific
|
|
78
|
-
if (event.event_type === '
|
|
76
|
+
// role_grant_revoke requires matching the specific role. `null` means the
|
|
77
|
+
// stream isn't gated by a specific role_grant, so role_grant_revoke is a no-op.
|
|
78
|
+
if (event.event_type === 'role_grant_revoke') {
|
|
79
79
|
if (required_role === null)
|
|
80
80
|
return;
|
|
81
81
|
if (event.metadata?.role !== required_role)
|
package/dist/runtime/mock.d.ts
CHANGED
|
@@ -58,7 +58,7 @@ export interface MockRuntime extends RuntimeDeps {
|
|
|
58
58
|
*
|
|
59
59
|
* @example
|
|
60
60
|
* ```ts
|
|
61
|
-
* const runtime = create_mock_runtime(['apply', '
|
|
61
|
+
* const runtime = create_mock_runtime(['apply', 'zap.ts']);
|
|
62
62
|
* runtime.mock_env.set('HOME', '/home/test');
|
|
63
63
|
* runtime.mock_fs.set('/home/test/.app/config.json', '{}');
|
|
64
64
|
*
|
package/dist/runtime/mock.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*
|
|
19
19
|
* @example
|
|
20
20
|
* ```ts
|
|
21
|
-
* const runtime = create_mock_runtime(['apply', '
|
|
21
|
+
* const runtime = create_mock_runtime(['apply', 'zap.ts']);
|
|
22
22
|
* runtime.mock_env.set('HOME', '/home/test');
|
|
23
23
|
* runtime.mock_fs.set('/home/test/.app/config.json', '{}');
|
|
24
24
|
*
|
|
@@ -55,17 +55,19 @@ export interface CreateAppBackendOptions {
|
|
|
55
55
|
/** Structured logger instance. Omit for default (`new Logger('server')`). */
|
|
56
56
|
log?: Logger;
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
59
|
-
* Use to broadcast audit events via SSE.
|
|
60
|
-
*
|
|
58
|
+
* Initial subscriber appended to `AppDeps.audit.on_event_chain`.
|
|
59
|
+
* Use to broadcast audit events via SSE / WS. Additional subscribers
|
|
60
|
+
* (e.g. the factory-managed audit-log SSE) are appended at server
|
|
61
|
+
* assembly via `audit.on_event_chain.push(listener)` — no shallow-copy
|
|
62
|
+
* of `AppDeps` required.
|
|
61
63
|
*/
|
|
62
64
|
on_audit_event?: (event: AuditLogEvent) => void;
|
|
63
65
|
/**
|
|
64
66
|
* Audit-log config for consumer event-type extensions. Built once at
|
|
65
|
-
* startup via `create_audit_log_config({extra_events})` and
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
67
|
+
* startup via `create_audit_log_config({extra_events})` and captured
|
|
68
|
+
* inside `AppDeps.audit` so consumer handlers cannot silently fall
|
|
69
|
+
* back to the builtin config. Omit to use `BUILTIN_AUDIT_LOG_CONFIG`
|
|
70
|
+
* (no extra events).
|
|
69
71
|
*/
|
|
70
72
|
audit_log_config?: AuditLogConfig;
|
|
71
73
|
/**
|
|
@@ -74,9 +76,10 @@ export interface CreateAppBackendOptions {
|
|
|
74
76
|
* (`namespace`, `name`, `sequence`); order is append-only so forward-only
|
|
75
77
|
* guarantees hold per-namespace.
|
|
76
78
|
*
|
|
77
|
-
*
|
|
78
|
-
* extra namespaces. This is the only
|
|
79
|
-
* — DB init belongs to the backend
|
|
79
|
+
* Names in `RESERVED_MIGRATION_NAMESPACES` (currently `['fuz_auth']`) are
|
|
80
|
+
* rejected at startup. Omit for no extra namespaces. This is the only
|
|
81
|
+
* place to splice consumer migrations — DB init belongs to the backend
|
|
82
|
+
* lifecycle, not server assembly.
|
|
80
83
|
*/
|
|
81
84
|
migration_namespaces?: ReadonlyArray<MigrationNamespace>;
|
|
82
85
|
}
|
|
@@ -89,7 +92,7 @@ export interface CreateAppBackendOptions {
|
|
|
89
92
|
*
|
|
90
93
|
* @param options - keyring, password deps, optional database URL, and optional `migration_namespaces`
|
|
91
94
|
* @returns app backend with deps, database metadata, and combined migration results
|
|
92
|
-
* @throws Error if `migration_namespaces` contains
|
|
95
|
+
* @throws Error if `migration_namespaces` contains a namespace in `RESERVED_MIGRATION_NAMESPACES`
|
|
93
96
|
*/
|
|
94
97
|
export declare const create_app_backend: (options: CreateAppBackendOptions) => Promise<AppBackend>;
|
|
95
98
|
//# sourceMappingURL=app_backend.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app_backend.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAE/C,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"app_backend.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAE/C,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAE/E,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAiB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAI/F;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,oIAAoI;IACpI,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC3D,iEAAiE;IACjE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACvC,+DAA+D;IAC/D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,2BAA2B;IAC3B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAC;IAClC;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACzD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAU,SAAS,uBAAuB,KAAG,OAAO,CAAC,UAAU,CAuC7F,CAAC"}
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
* @module
|
|
12
12
|
*/
|
|
13
13
|
import { Logger } from '@fuzdev/fuz_util/log.js';
|
|
14
|
+
import { create_audit_emitter } from '../auth/audit_emitter.js';
|
|
14
15
|
import { run_migrations } from '../db/migrate.js';
|
|
15
|
-
import { AUTH_MIGRATION_NS,
|
|
16
|
+
import { AUTH_MIGRATION_NS, RESERVED_MIGRATION_NAMESPACES } from '../auth/migrations.js';
|
|
16
17
|
import { create_db } from '../db/create_db.js';
|
|
17
18
|
/**
|
|
18
19
|
* Initialize the backend: database + auth migrations + deps.
|
|
@@ -23,18 +24,16 @@ import { create_db } from '../db/create_db.js';
|
|
|
23
24
|
*
|
|
24
25
|
* @param options - keyring, password deps, optional database URL, and optional `migration_namespaces`
|
|
25
26
|
* @returns app backend with deps, database metadata, and combined migration results
|
|
26
|
-
* @throws Error if `migration_namespaces` contains
|
|
27
|
+
* @throws Error if `migration_namespaces` contains a namespace in `RESERVED_MIGRATION_NAMESPACES`
|
|
27
28
|
*/
|
|
28
29
|
export const create_app_backend = async (options) => {
|
|
29
30
|
const { database_url, keyring, password, stat, read_text_file, delete_file } = options;
|
|
30
31
|
const log = options.log ?? new Logger('server');
|
|
31
|
-
const on_audit_event = options.on_audit_event ?? (() => { }); // eslint-disable-line @typescript-eslint/no-empty-function
|
|
32
|
-
const { audit_log_config } = options;
|
|
33
32
|
const { db, close, db_type, db_name } = await create_db(database_url);
|
|
34
33
|
if (options.migration_namespaces?.length) {
|
|
35
34
|
for (const ns of options.migration_namespaces) {
|
|
36
|
-
if (ns.namespace
|
|
37
|
-
throw new Error(`Migration namespace "${
|
|
35
|
+
if (RESERVED_MIGRATION_NAMESPACES.includes(ns.namespace)) {
|
|
36
|
+
throw new Error(`Migration namespace "${ns.namespace}" is reserved by fuz_app — choose a different namespace`);
|
|
38
37
|
}
|
|
39
38
|
}
|
|
40
39
|
}
|
|
@@ -42,6 +41,12 @@ export const create_app_backend = async (options) => {
|
|
|
42
41
|
AUTH_MIGRATION_NS,
|
|
43
42
|
...(options.migration_namespaces ?? []),
|
|
44
43
|
]);
|
|
44
|
+
const audit = create_audit_emitter({
|
|
45
|
+
db,
|
|
46
|
+
log,
|
|
47
|
+
on_audit_event: options.on_audit_event,
|
|
48
|
+
audit_log_config: options.audit_log_config,
|
|
49
|
+
});
|
|
45
50
|
return {
|
|
46
51
|
db_type,
|
|
47
52
|
db_name,
|
|
@@ -55,8 +60,7 @@ export const create_app_backend = async (options) => {
|
|
|
55
60
|
read_text_file,
|
|
56
61
|
delete_file,
|
|
57
62
|
log,
|
|
58
|
-
|
|
59
|
-
audit_log_config,
|
|
63
|
+
audit,
|
|
60
64
|
},
|
|
61
65
|
};
|
|
62
66
|
};
|
|
@@ -133,10 +133,11 @@ export interface AppServerOptions {
|
|
|
133
133
|
/**
|
|
134
134
|
* Enable factory-managed audit log SSE.
|
|
135
135
|
*
|
|
136
|
-
* When truthy, creates an `AuditLogSse` instance internally,
|
|
137
|
-
*
|
|
138
|
-
* `
|
|
139
|
-
*
|
|
136
|
+
* When truthy, creates an `AuditLogSse` instance internally, appends the SSE
|
|
137
|
+
* listener to `backend.deps.audit.on_event_chain` (composing with the
|
|
138
|
+
* consumer's `on_audit_event` callback rather than rebuilding `AppDeps`), and
|
|
139
|
+
* auto-includes `AUDIT_LOG_EVENT_SPECS` in the surface. The result is exposed
|
|
140
|
+
* on `AppServerContext` (for route factories) and `AppServer` (for the caller).
|
|
140
141
|
*
|
|
141
142
|
* Pass `true` for defaults (admin role), or `{role: 'custom'}` for a custom role.
|
|
142
143
|
* Omit to wire audit SSE manually.
|
|
@@ -229,9 +230,8 @@ export declare const DEFAULT_MAX_BODY_SIZE: number;
|
|
|
229
230
|
* static serving. Database migrations belong to the backend lifecycle —
|
|
230
231
|
* pass `migration_namespaces` to `create_app_backend`.
|
|
231
232
|
*
|
|
232
|
-
* When `audit_log_sse` is set,
|
|
233
|
-
* `
|
|
234
|
-
* callback — `backend.deps` itself is not mutated.
|
|
233
|
+
* When `audit_log_sse` is set, the SSE registry's listener is appended to
|
|
234
|
+
* `backend.deps.audit.on_event_chain` — no shallow-copy of `AppDeps`.
|
|
235
235
|
*
|
|
236
236
|
* @returns assembled Hono app, backend, surface build, and bootstrap status
|
|
237
237
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,IAAI,EAAE,KAAK,OAAO,EAAC,MAAM,MAAM,CAAC;AAGxC,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAEN,KAAK,cAAc,EAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAGN,KAAK,WAAW,EAChB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAEhE,OAAO,EAKN,KAAK,WAAW,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAGjD,OAAO,oBAAoB,CAAC;AAE5B,OAAO,EAA2B,KAAK,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAE9E,OAAO,EAEN,KAAK,cAAc,EAEnB,KAAK,eAAe,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,9 +25,10 @@ import { create_app_surface_spec, } from '../http/surface.js';
|
|
|
25
25
|
import { apply_middleware_specs, apply_route_specs, prefix_route_specs, } from '../http/route_spec.js';
|
|
26
26
|
import { check_bootstrap_status, create_bootstrap_route_specs, } from '../auth/bootstrap_routes.js';
|
|
27
27
|
import { create_surface_route_spec } from '../http/common_routes.js';
|
|
28
|
+
import { flush_pending_effects, flush_post_commit_effects } from '../http/pending_effects.js';
|
|
28
29
|
import { create_auth_middleware_specs } from '../auth/middleware.js';
|
|
29
|
-
import { fuz_auth_guard_resolver } from '../auth/
|
|
30
|
-
import { create_fuz_authorization_handler
|
|
30
|
+
import { fuz_auth_guard_resolver } from '../auth/auth_guard_resolver.js';
|
|
31
|
+
import { create_fuz_authorization_handler } from '../auth/request_context.js';
|
|
31
32
|
import { ERROR_PAYLOAD_TOO_LARGE } from '../http/error_schemas.js';
|
|
32
33
|
import { create_rpc_endpoint } from '../actions/action_rpc.js';
|
|
33
34
|
/** Default maximum request body size: 1 MiB. */
|
|
@@ -40,15 +41,15 @@ export const DEFAULT_MAX_BODY_SIZE = 1024 * 1024;
|
|
|
40
41
|
* static serving. Database migrations belong to the backend lifecycle —
|
|
41
42
|
* pass `migration_namespaces` to `create_app_backend`.
|
|
42
43
|
*
|
|
43
|
-
* When `audit_log_sse` is set,
|
|
44
|
-
* `
|
|
45
|
-
* callback — `backend.deps` itself is not mutated.
|
|
44
|
+
* When `audit_log_sse` is set, the SSE registry's listener is appended to
|
|
45
|
+
* `backend.deps.audit.on_event_chain` — no shallow-copy of `AppDeps`.
|
|
46
46
|
*
|
|
47
47
|
* @returns assembled Hono app, backend, surface build, and bootstrap status
|
|
48
48
|
*/
|
|
49
49
|
export const create_app_server = async (options) => {
|
|
50
50
|
const { backend } = options;
|
|
51
|
-
const {
|
|
51
|
+
const { deps } = backend;
|
|
52
|
+
const { log } = deps;
|
|
52
53
|
// Rate limiter defaults (undefined = default, null = disable)
|
|
53
54
|
const ip_rate_limiter = options.ip_rate_limiter === undefined ? create_rate_limiter() : options.ip_rate_limiter;
|
|
54
55
|
const login_account_rate_limiter = options.login_account_rate_limiter === undefined
|
|
@@ -66,22 +67,18 @@ export const create_app_server = async (options) => {
|
|
|
66
67
|
const action_account_rate_limiter = options.action_account_rate_limiter === undefined
|
|
67
68
|
? create_rate_limiter(DEFAULT_ACTION_ACCOUNT_RATE_LIMIT)
|
|
68
69
|
: options.action_account_rate_limiter;
|
|
69
|
-
// Factory-managed audit SSE
|
|
70
|
+
// Factory-managed audit SSE — appends a listener to the bound emitter's
|
|
71
|
+
// chain so SSE fan-out runs alongside the consumer's `on_audit_event`
|
|
72
|
+
// without rebuilding `AppDeps`.
|
|
70
73
|
const audit_sse = options.audit_log_sse
|
|
71
74
|
? create_audit_log_sse({
|
|
72
75
|
log,
|
|
73
76
|
role: typeof options.audit_log_sse === 'object' ? options.audit_log_sse.role : undefined,
|
|
74
77
|
})
|
|
75
78
|
: null;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
on_audit_event: (event) => {
|
|
80
|
-
audit_sse.on_audit_event(event);
|
|
81
|
-
backend.deps.on_audit_event(event);
|
|
82
|
-
},
|
|
83
|
-
}
|
|
84
|
-
: backend.deps;
|
|
79
|
+
if (audit_sse) {
|
|
80
|
+
deps.audit.on_event_chain.push(audit_sse.on_audit_event);
|
|
81
|
+
}
|
|
85
82
|
// Proxy middleware
|
|
86
83
|
const proxy_spec = create_proxy_middleware_spec({ ...options.proxy, log });
|
|
87
84
|
// Auth middleware
|
|
@@ -161,20 +158,12 @@ export const create_app_server = async (options) => {
|
|
|
161
158
|
...(options.event_specs ?? []),
|
|
162
159
|
...(audit_sse ? AUDIT_LOG_EVENT_SPECS : []),
|
|
163
160
|
];
|
|
164
|
-
// Per-route flag for the dispatcher's authorization-phase error shapes.
|
|
165
|
-
// Mirrors the runtime check in `apply_authorization_phase`: a route emits
|
|
166
|
-
// actor-failure errors when its input declares `acting?: ActingActor` or
|
|
167
|
-
// its auth requires permits. Routes that fail this check stay on the
|
|
168
|
-
// narrow derived schema (validation + auth shapes) so non-fuz_app HTTP
|
|
169
|
-
// frameworks aren't forced to surface fuz_app-specific error codes.
|
|
170
|
-
const fuz_is_acting_aware = (spec) => is_actor_implying_auth(spec.auth) || input_schema_declares_acting(spec.input);
|
|
171
161
|
const surface_spec = create_app_surface_spec({
|
|
172
162
|
middleware_specs: surface_middleware,
|
|
173
163
|
route_specs,
|
|
174
164
|
env_schema: options.env_schema,
|
|
175
165
|
event_specs: all_event_specs,
|
|
176
166
|
rpc_endpoints: resolved_rpc_endpoints,
|
|
177
|
-
is_acting_aware: fuz_is_acting_aware,
|
|
178
167
|
});
|
|
179
168
|
// Config-level diagnostics (concatenated after spec-level from generate_app_surface)
|
|
180
169
|
const config_diagnostics = [];
|
|
@@ -224,31 +213,37 @@ export const create_app_server = async (options) => {
|
|
|
224
213
|
log_startup_summary(surface_spec.surface, log, options.env_values);
|
|
225
214
|
// Hono app assembly
|
|
226
215
|
const app = new Hono();
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
//
|
|
216
|
+
// Two-queue side-effect flush. `pending_effects` collects eager
|
|
217
|
+
// fire-and-forget promises (audit emits, session touch, api-token
|
|
218
|
+
// usage). `post_commit_effects` collects deferred thunks pushed via
|
|
219
|
+
// `emit_after_commit` (WS notifications, anything that must observe a
|
|
220
|
+
// committed transaction). Both queues drain here, after the handler
|
|
221
|
+
// (and any wrapping `db.transaction`) returns. In test mode both are
|
|
222
|
+
// awaited before the response returns; in production, eager-queue
|
|
223
|
+
// rejections are reported via `on_effect_error`.
|
|
230
224
|
app.use('*', async (c, next) => {
|
|
231
225
|
c.set('pending_effects', []);
|
|
226
|
+
c.set('post_commit_effects', []);
|
|
232
227
|
try {
|
|
233
228
|
await next();
|
|
234
229
|
}
|
|
235
230
|
finally {
|
|
236
|
-
const
|
|
237
|
-
|
|
231
|
+
const eager = c.var.pending_effects;
|
|
232
|
+
const deferred = c.var.post_commit_effects;
|
|
233
|
+
if (eager.length || deferred.length) {
|
|
238
234
|
if (options.await_pending_effects) {
|
|
239
|
-
await
|
|
235
|
+
await flush_pending_effects(eager, log);
|
|
236
|
+
await flush_post_commit_effects(deferred, log);
|
|
240
237
|
}
|
|
241
238
|
else {
|
|
242
|
-
const
|
|
239
|
+
const error_ctx = { method: c.req.method, path: c.req.path };
|
|
243
240
|
const callback = options.on_effect_error;
|
|
244
|
-
void
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
});
|
|
241
|
+
void flush_pending_effects(eager, log, callback ? (reason) => callback(reason, error_ctx) : undefined);
|
|
242
|
+
// `flush_post_commit_effects` is non-throwing: per-thunk
|
|
243
|
+
// errors are routed through `log.error` inside the helper,
|
|
244
|
+
// so production fire-and-forget skips the `on_effect_error`
|
|
245
|
+
// fan-out (deferred thunks are wrapped end-to-end already).
|
|
246
|
+
void flush_post_commit_effects(deferred, log);
|
|
252
247
|
}
|
|
253
248
|
}
|
|
254
249
|
}
|
|
@@ -267,7 +262,7 @@ export const create_app_server = async (options) => {
|
|
|
267
262
|
}
|
|
268
263
|
apply_middleware_specs(app, middleware_specs);
|
|
269
264
|
const authorize = create_fuz_authorization_handler({ db: deps.db });
|
|
270
|
-
apply_route_specs(app, route_specs, fuz_auth_guard_resolver, log, deps.db, authorize
|
|
265
|
+
apply_route_specs(app, route_specs, fuz_auth_guard_resolver, log, deps.db, authorize);
|
|
271
266
|
// Post-route middleware (before static serving)
|
|
272
267
|
if (options.post_route_middleware) {
|
|
273
268
|
apply_middleware_specs(app, options.post_route_middleware);
|
|
@@ -24,7 +24,7 @@ export interface NginxValidationResult {
|
|
|
24
24
|
*
|
|
25
25
|
* Checks for required security headers, Authorization stripping in `/api`
|
|
26
26
|
* blocks, and the nginx `add_header` inheritance gotcha. Designed for
|
|
27
|
-
* fuz_app consumer deploy configs (
|
|
27
|
+
* fuz_app consumer deploy configs (zap.ts `NGINX_CONFIG` constants).
|
|
28
28
|
*
|
|
29
29
|
* Limitations: string pattern matching, not a real nginx parser. Catches
|
|
30
30
|
* common omissions in fuz_app deploy configs but won't catch all possible
|
|
@@ -92,7 +92,7 @@ const location_matches_api = (block) => {
|
|
|
92
92
|
*
|
|
93
93
|
* Checks for required security headers, Authorization stripping in `/api`
|
|
94
94
|
* blocks, and the nginx `add_header` inheritance gotcha. Designed for
|
|
95
|
-
* fuz_app consumer deploy configs (
|
|
95
|
+
* fuz_app consumer deploy configs (zap.ts `NGINX_CONFIG` constants).
|
|
96
96
|
*
|
|
97
97
|
* Limitations: string pattern matching, not a real nginx parser. Catches
|
|
98
98
|
* common omissions in fuz_app deploy configs but won't catch all possible
|