@fuzdev/fuz_app 0.146.1 → 0.148.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 +6 -4
- package/dist/actions/action_codegen.d.ts +15 -1
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +23 -2
- package/dist/actions/perform_action.js +1 -1
- package/dist/auth/CLAUDE.md +1 -1
- package/dist/auth/bootstrap_account.d.ts +2 -1
- package/dist/auth/bootstrap_account.d.ts.map +1 -1
- package/dist/auth/bootstrap_account.js +17 -6
- package/dist/auth/cell_action_specs.d.ts +3 -1
- package/dist/auth/cell_action_specs.d.ts.map +1 -1
- package/dist/auth/cell_action_specs.js +5 -5
- package/dist/auth/cell_actions.d.ts.map +1 -1
- package/dist/auth/cell_actions.js +2 -3
- package/dist/auth/cell_data_schema.d.ts +1 -1
- package/dist/auth/cell_data_schema.js +1 -1
- package/dist/auth/cell_field_action_specs.d.ts +4 -3
- package/dist/auth/cell_field_action_specs.d.ts.map +1 -1
- package/dist/auth/cell_field_action_specs.js +5 -6
- package/dist/auth/cell_field_actions.d.ts.map +1 -1
- package/dist/auth/cell_field_actions.js +8 -1
- package/dist/auth/cell_item_action_specs.d.ts +4 -2
- package/dist/auth/cell_item_action_specs.d.ts.map +1 -1
- package/dist/auth/cell_item_action_specs.js +5 -5
- package/dist/auth/cell_item_actions.d.ts.map +1 -1
- package/dist/auth/cell_item_actions.js +8 -1
- package/dist/auth/keyring.d.ts +35 -38
- package/dist/auth/keyring.d.ts.map +1 -1
- package/dist/auth/keyring.js +43 -50
- package/dist/auth/password_argon2.d.ts.map +1 -1
- package/dist/auth/password_argon2.js +11 -8
- package/dist/auth/role_grant_offer_action_specs.d.ts +2 -0
- package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -1
- package/dist/auth/role_grant_offer_action_specs.js +3 -1
- package/dist/auth/session_cookie.d.ts.map +1 -1
- package/dist/auth/session_cookie.js +5 -2
- package/dist/db/CLAUDE.md +18 -16
- package/dist/db/cell_queries.d.ts +3 -2
- package/dist/db/cell_queries.d.ts.map +1 -1
- package/dist/db/cell_queries.js +3 -2
- package/dist/db/fact_disk_storage.d.ts +15 -15
- package/dist/db/fact_disk_storage.d.ts.map +1 -1
- package/dist/db/fact_disk_storage.js +22 -28
- package/dist/db/fact_queries.d.ts +2 -3
- package/dist/db/fact_queries.d.ts.map +1 -1
- package/dist/db/fact_queries.js +2 -3
- package/dist/db/fact_store.d.ts +20 -18
- package/dist/db/fact_store.d.ts.map +1 -1
- package/dist/db/fact_store.js +30 -44
- package/dist/db/file_fact_url.d.ts +19 -4
- package/dist/db/file_fact_url.d.ts.map +1 -1
- package/dist/db/file_fact_url.js +19 -4
- package/dist/primitive_schemas.d.ts +1 -1
- package/dist/primitive_schemas.d.ts.map +1 -1
- package/dist/primitive_schemas.js +2 -1
- package/dist/schema_meta.d.ts +20 -0
- package/dist/schema_meta.d.ts.map +1 -1
- package/dist/schema_meta.js +7 -1
- package/dist/server/env.d.ts.map +1 -1
- package/dist/server/env.js +2 -2
- package/dist/server/serve_fact_route.d.ts +9 -5
- package/dist/server/serve_fact_route.d.ts.map +1 -1
- package/dist/server/serve_fact_route.js +15 -7
- package/dist/testing/CLAUDE.md +737 -114
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +73 -5
- package/dist/testing/adversarial_input.d.ts +0 -47
- package/dist/testing/adversarial_input.d.ts.map +1 -1
- package/dist/testing/adversarial_input.js +4 -340
- package/dist/testing/adversarial_input_cases.d.ts +64 -0
- package/dist/testing/adversarial_input_cases.d.ts.map +1 -0
- package/dist/testing/adversarial_input_cases.js +348 -0
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +2 -2
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +24 -20
- package/dist/testing/audit_drift_guard.d.ts +27 -1
- package/dist/testing/audit_drift_guard.d.ts.map +1 -1
- package/dist/testing/audit_drift_guard.js +50 -0
- package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
- package/dist/testing/cross_backend/account_lifecycle.js +29 -12
- package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -1
- package/dist/testing/cross_backend/actor_lookup.js +7 -25
- package/dist/testing/cross_backend/app_settings.d.ts.map +1 -1
- package/dist/testing/cross_backend/app_settings.js +4 -6
- package/dist/testing/cross_backend/audit_cross_helpers.d.ts +51 -0
- package/dist/testing/cross_backend/audit_cross_helpers.d.ts.map +1 -0
- package/dist/testing/cross_backend/audit_cross_helpers.js +78 -0
- package/dist/testing/cross_backend/backend_config.d.ts +2 -1
- package/dist/testing/cross_backend/backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/body_size.d.ts +6 -0
- package/dist/testing/cross_backend/body_size.d.ts.map +1 -1
- package/dist/testing/cross_backend/body_size.js +26 -44
- package/dist/testing/cross_backend/body_size_smuggling.d.ts +5 -0
- package/dist/testing/cross_backend/body_size_smuggling.d.ts.map +1 -1
- package/dist/testing/cross_backend/body_size_smuggling.js +7 -14
- package/dist/testing/cross_backend/bootstrap_backend.d.ts +11 -1
- package/dist/testing/cross_backend/bootstrap_backend.d.ts.map +1 -1
- package/dist/testing/cross_backend/bootstrap_backend.js +2 -1
- package/dist/testing/cross_backend/build_test_backend_paths.d.ts +3 -1
- package/dist/testing/cross_backend/build_test_backend_paths.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.d.ts +55 -59
- package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.js +20 -23
- package/dist/testing/cross_backend/cargo_binary.d.ts +70 -0
- package/dist/testing/cross_backend/cargo_binary.d.ts.map +1 -0
- package/dist/testing/cross_backend/cargo_binary.js +148 -0
- package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_crud.js +57 -1
- package/dist/testing/cross_backend/cell_gated_create.d.ts +0 -60
- package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_gated_create.js +9 -487
- package/dist/testing/cross_backend/cell_grant_role.d.ts +14 -2
- package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_grant_role.js +22 -12
- package/dist/testing/cross_backend/cell_moderate.d.ts +66 -0
- package/dist/testing/cross_backend/cell_moderate.d.ts.map +1 -0
- package/dist/testing/cross_backend/cell_moderate.js +511 -0
- package/dist/testing/cross_backend/cell_ref_admission.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_ref_admission.js +1 -1
- package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_relations.js +40 -19
- package/dist/testing/cross_backend/conformance_case.d.ts +43 -4
- package/dist/testing/cross_backend/conformance_case.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_case.js +29 -1
- package/dist/testing/cross_backend/conformance_rpc_auth.d.ts +93 -0
- package/dist/testing/cross_backend/conformance_rpc_auth.d.ts.map +1 -0
- package/dist/testing/cross_backend/conformance_rpc_auth.js +125 -0
- package/dist/testing/cross_backend/conformance_table.d.ts +144 -4
- package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_table.js +297 -65
- package/dist/testing/cross_backend/cookie_attributes.d.ts.map +1 -1
- package/dist/testing/cross_backend/cookie_attributes.js +3 -2
- package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts +38 -5
- package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/create_cross_backend_global_setup.js +24 -3
- package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts +5 -5
- package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/credential_deadline.d.ts +10 -6
- package/dist/testing/cross_backend/credential_deadline.d.ts.map +1 -1
- package/dist/testing/cross_backend/credential_deadline.js +32 -31
- package/dist/testing/cross_backend/credential_header_robustness.d.ts.map +1 -1
- package/dist/testing/cross_backend/credential_header_robustness.js +4 -6
- package/dist/testing/cross_backend/{cell_cross_helpers.d.ts → cross_rpc.d.ts} +12 -2
- package/dist/testing/cross_backend/cross_rpc.d.ts.map +1 -0
- package/dist/testing/cross_backend/{cell_cross_helpers.js → cross_rpc.js} +31 -7
- package/dist/testing/cross_backend/default_backend_configs.d.ts +56 -61
- package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.js +97 -91
- package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_spine_surface.js +2 -2
- package/dist/testing/cross_backend/differential.d.ts +126 -0
- package/dist/testing/cross_backend/differential.d.ts.map +1 -0
- package/dist/testing/cross_backend/differential.js +201 -0
- package/dist/testing/cross_backend/differential_normalize.d.ts +150 -0
- package/dist/testing/cross_backend/differential_normalize.d.ts.map +1 -0
- package/dist/testing/cross_backend/differential_normalize.js +153 -0
- package/dist/testing/cross_backend/fact_serving.d.ts +5 -0
- package/dist/testing/cross_backend/fact_serving.d.ts.map +1 -1
- package/dist/testing/cross_backend/fact_serving.js +41 -7
- package/dist/testing/cross_backend/full_spine_mount.d.ts +15 -0
- package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -1
- package/dist/testing/cross_backend/full_spine_mount.js +55 -1
- package/dist/testing/cross_backend/identity_parity.d.ts.map +1 -1
- package/dist/testing/cross_backend/identity_parity.js +6 -5
- package/dist/testing/cross_backend/in_process_setup.d.ts +12 -2
- package/dist/testing/cross_backend/in_process_setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/in_process_setup.js +10 -7
- package/dist/testing/cross_backend/login_security.d.ts.map +1 -1
- package/dist/testing/cross_backend/login_security.js +13 -18
- package/dist/testing/cross_backend/origin.js +1 -1
- package/dist/testing/cross_backend/origin_conformance.js +1 -1
- package/dist/testing/cross_backend/origin_scope.d.ts +6 -0
- package/dist/testing/cross_backend/origin_scope.d.ts.map +1 -1
- package/dist/testing/cross_backend/origin_scope.js +13 -12
- package/dist/testing/cross_backend/peer_ping_ws.d.ts +2 -5
- package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/peer_ping_ws.js +14 -24
- package/dist/testing/cross_backend/postgres_database.d.ts +85 -0
- package/dist/testing/cross_backend/postgres_database.d.ts.map +1 -0
- package/dist/testing/cross_backend/postgres_database.js +140 -0
- package/dist/testing/cross_backend/provided_context.d.ts +28 -0
- package/dist/testing/cross_backend/provided_context.d.ts.map +1 -0
- package/dist/testing/cross_backend/provided_context.js +35 -0
- package/dist/testing/cross_backend/query_shape.d.ts.map +1 -1
- package/dist/testing/cross_backend/query_shape.js +10 -12
- package/dist/testing/cross_backend/ready.js +2 -2
- package/dist/testing/cross_backend/revocation_drivers.d.ts +4 -3
- package/dist/testing/cross_backend/revocation_drivers.d.ts.map +1 -1
- package/dist/testing/cross_backend/revocation_drivers.js +1 -1
- package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts +3 -2
- package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts +13 -0
- package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts.map +1 -0
- package/dist/testing/cross_backend/role_grant_offer_lifecycle.js +203 -0
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts +2 -5
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.js +203 -111
- package/dist/testing/cross_backend/role_grant_participation.d.ts +13 -0
- package/dist/testing/cross_backend/role_grant_participation.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_participation.js +32 -21
- package/dist/testing/cross_backend/role_grant_role_grammar.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_role_grammar.js +6 -9
- package/dist/testing/cross_backend/rpc_adversarial.d.ts +38 -0
- package/dist/testing/cross_backend/rpc_adversarial.d.ts.map +1 -0
- package/dist/testing/cross_backend/rpc_adversarial.js +292 -0
- package/dist/testing/cross_backend/rpc_success_fixtures.d.ts +24 -0
- package/dist/testing/cross_backend/rpc_success_fixtures.d.ts.map +1 -0
- package/dist/testing/cross_backend/rpc_success_fixtures.js +124 -0
- package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts +101 -0
- package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts.map +1 -0
- package/dist/testing/cross_backend/rust_spine_consumer_surface.js +113 -0
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts +10 -0
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +27 -18
- package/dist/testing/cross_backend/session_cap.d.ts +9 -8
- package/dist/testing/cross_backend/session_cap.d.ts.map +1 -1
- package/dist/testing/cross_backend/session_cap.js +9 -4
- package/dist/testing/cross_backend/session_cookie_codec.d.ts +19 -0
- package/dist/testing/cross_backend/session_cookie_codec.d.ts.map +1 -0
- package/dist/testing/cross_backend/session_cookie_codec.js +128 -0
- package/dist/testing/cross_backend/setup.d.ts +56 -54
- package/dist/testing/cross_backend/setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/setup.js +29 -29
- package/dist/testing/cross_backend/simple_request.d.ts.map +1 -1
- package/dist/testing/cross_backend/simple_request.js +4 -4
- package/dist/testing/cross_backend/spawn_backend.d.ts +59 -10
- package/dist/testing/cross_backend/spawn_backend.d.ts.map +1 -1
- package/dist/testing/cross_backend/spawn_backend.js +219 -60
- package/dist/testing/cross_backend/spine_suites.d.ts +231 -0
- package/dist/testing/cross_backend/spine_suites.d.ts.map +1 -0
- package/dist/testing/cross_backend/spine_suites.js +626 -0
- package/dist/testing/cross_backend/spine_surface_constants.d.ts +29 -0
- package/dist/testing/cross_backend/spine_surface_constants.d.ts.map +1 -1
- package/dist/testing/cross_backend/spine_surface_constants.js +29 -0
- package/dist/testing/cross_backend/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/sse_round_trip.js +3 -4
- package/dist/testing/cross_backend/standard.d.ts +18 -1
- package/dist/testing/cross_backend/standard.d.ts.map +1 -1
- package/dist/testing/cross_backend/standard.js +2 -0
- package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts +24 -0
- package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts.map +1 -1
- package/dist/testing/cross_backend/test_cell_gated_create_authorize.js +15 -0
- package/dist/testing/cross_backend/testing_backdoor.d.ts +2 -8
- package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_backdoor.js +7 -10
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +10 -5
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +21 -12
- package/dist/testing/cross_backend/testing_server_bun.js +1 -1
- package/dist/testing/cross_backend/token_lifetime.js +1 -1
- package/dist/testing/cross_backend/token_scope_surface.d.ts.map +1 -1
- package/dist/testing/cross_backend/token_scope_surface.js +9 -13
- package/dist/testing/cross_backend/transport_composition.d.ts +26 -2
- package/dist/testing/cross_backend/transport_composition.d.ts.map +1 -1
- package/dist/testing/cross_backend/transport_composition.js +81 -51
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts +8 -0
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/ts_spine_backend_config.js +17 -10
- package/dist/testing/cross_backend/ws_action_rate_limit.d.ts +2 -5
- package/dist/testing/cross_backend/ws_action_rate_limit.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_action_rate_limit.js +8 -14
- package/dist/testing/cross_backend/ws_connection_cap.d.ts +4 -9
- package/dist/testing/cross_backend/ws_connection_cap.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_connection_cap.js +11 -12
- package/dist/testing/cross_backend/ws_endpoint.d.ts +52 -0
- package/dist/testing/cross_backend/ws_endpoint.d.ts.map +1 -0
- package/dist/testing/cross_backend/ws_endpoint.js +54 -0
- package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts +2 -5
- package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_inbound_dispatch.js +9 -15
- package/dist/testing/cross_backend/ws_outbound_overflow.d.ts +2 -7
- package/dist/testing/cross_backend/ws_outbound_overflow.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_outbound_overflow.js +5 -9
- package/dist/testing/cross_backend/ws_role_gated.d.ts +4 -5
- package/dist/testing/cross_backend/ws_role_gated.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_role_gated.js +12 -21
- package/dist/testing/cross_backend/ws_round_trip.d.ts +12 -9
- package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_round_trip.js +29 -34
- package/dist/testing/db_entities.d.ts +16 -3
- package/dist/testing/db_entities.d.ts.map +1 -1
- package/dist/testing/db_entities.js +28 -5
- package/dist/testing/integration_helpers.d.ts +61 -2
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/integration_helpers.js +75 -18
- package/dist/testing/round_trip.d.ts +17 -0
- package/dist/testing/round_trip.d.ts.map +1 -1
- package/dist/testing/round_trip.js +67 -24
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.js +13 -138
- package/dist/testing/rpc_envelope_cases.d.ts +111 -0
- package/dist/testing/rpc_envelope_cases.d.ts.map +1 -0
- package/dist/testing/rpc_envelope_cases.js +240 -0
- package/dist/testing/rpc_helpers.d.ts +31 -0
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.js +35 -14
- package/dist/testing/rpc_round_trip.d.ts +62 -6
- package/dist/testing/rpc_round_trip.d.ts.map +1 -1
- package/dist/testing/rpc_round_trip.js +151 -39
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +22 -2
- package/dist/testing/standard.d.ts +26 -0
- package/dist/testing/standard.d.ts.map +1 -1
- package/dist/testing/standard.js +4 -1
- package/dist/testing/transports/raw_http.d.ts +21 -0
- package/dist/testing/transports/raw_http.d.ts.map +1 -1
- package/dist/testing/transports/raw_http.js +30 -0
- package/package.json +10 -8
- package/dist/testing/cross_backend/actor_search.d.ts +0 -6
- package/dist/testing/cross_backend/actor_search.d.ts.map +0 -1
- package/dist/testing/cross_backend/actor_search.js +0 -90
- package/dist/testing/cross_backend/cell_cross_helpers.d.ts.map +0 -1
package/dist/actions/CLAUDE.md
CHANGED
|
@@ -127,7 +127,7 @@ and options on each function's TSDoc.
|
|
|
127
127
|
- `get_executor_phases(spec, executor)` — phases an executor participates in for the spec.
|
|
128
128
|
- `get_handler_return_type` — TS type a phase handler must return; side-effect imports `ActionOutputs`.
|
|
129
129
|
- `generate_phase_handlers` — per-action typed handler-map fragment.
|
|
130
|
-
- `generate_actions_api_method_signature` — single source of truth for the typed `FrontendActionsApi` method shape.
|
|
130
|
+
- `generate_actions_api_method_signature` — single source of truth for the typed `FrontendActionsApi` method shape. Its `input?:` follows `action_input_is_optional` — the schema accepts `undefined`, or accepts `{}` and is not marked `.meta({empty_input_handler_guarded: true})` (`SchemaFieldMeta`, read by `is_empty_input_handler_guarded` in `schema_meta.ts` — set on `cell_get`, `cell_field_list` and `cell_item_list`, whose `{}` reaches a handler guard that refuses it with a declared reason, so their input stays required; a consumer marks its own the same way); an input-shape invariant test reads the same rule.
|
|
131
131
|
- `generate_action_method_enums` — up to nine `z.enum` + `z.infer` pairs.
|
|
132
132
|
- `generate_action_method_enum_block` — lower-level escape hatch for cross-product enums.
|
|
133
133
|
- `generate_typed_action_event_alias` — fixed-shape `TypedActionEvent<TMethod, TPhase, TStep>` alias.
|
|
@@ -219,9 +219,11 @@ auth/validation/dispatch pipeline is shared with the WebSocket dispatcher.
|
|
|
219
219
|
throttle, validate after — a caller the authority gates refuse never learns
|
|
220
220
|
the action's input shape, the coarse authority facts settle before the fine
|
|
221
221
|
ones, and a malformed flood burns the budget it should. The Rust spine's
|
|
222
|
-
dispatcher enforces the same order:
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
dispatcher enforces the same order: after the rate limit it refuses a
|
|
223
|
+
non-object `params` (which only `GET`'s `?params=` can carry past the
|
|
224
|
+
envelope) and validates the `acting` selector, and leaves every other field
|
|
225
|
+
to the handlers. So an anonymous `GET` with `?params=42` is a 401 on both
|
|
226
|
+
spines, and an authorized one is `invalid_params`.
|
|
225
227
|
|
|
226
228
|
Shim responsibilities (per-request):
|
|
227
229
|
|
|
@@ -144,6 +144,17 @@ export declare const to_action_spec_output_identifier: (method: string) => strin
|
|
|
144
144
|
* value/type lookups, which already accepts the raw method string.
|
|
145
145
|
*/
|
|
146
146
|
export declare const to_action_property_key: (method: string) => string;
|
|
147
|
+
/**
|
|
148
|
+
* Whether a caller may omit an action's input: its schema accepts `undefined`,
|
|
149
|
+
* or accepts `{}` (what an omitted input is validated as) and is not marked
|
|
150
|
+
* `empty_input_handler_guarded` (`SchemaFieldMeta`, read by
|
|
151
|
+
* `is_empty_input_handler_guarded`). The rule codegen emits `input?:` by and
|
|
152
|
+
* the input-shape invariant tests read.
|
|
153
|
+
*
|
|
154
|
+
* @param spec - the action spec
|
|
155
|
+
* @returns whether the typed surface makes the input optional
|
|
156
|
+
*/
|
|
157
|
+
export declare const action_input_is_optional: (spec: Pick<ActionSpecUnion, "input">) => boolean;
|
|
147
158
|
/**
|
|
148
159
|
* Generates one method line of the typed `FrontendActionsApi` interface for a
|
|
149
160
|
* single spec. Encapsulates the input/options/return-type signature shape so
|
|
@@ -181,7 +192,10 @@ ActingActor})` and other all-optional-fields strict objects. The second
|
|
|
181
192
|
* schema is asked to validate. A schema with required fields fails both
|
|
182
193
|
* probes and stays `input:` (required at the typed surface). Refinements
|
|
183
194
|
* and transforms run as part of `safeParse`, so their accept/reject
|
|
184
|
-
* decisions feed into the optional/required choice naturally.
|
|
195
|
+
* decisions feed into the optional/required choice naturally. An input
|
|
196
|
+
* marked `empty_input_handler_guarded` is the exception: its schema accepts
|
|
197
|
+
* `{}` but the handler refuses it, so it stays `input:`
|
|
198
|
+
* (`action_input_is_optional` is the one rule).
|
|
185
199
|
*
|
|
186
200
|
* @param options.sync_returns_value - When true (default), sync `local_call`
|
|
187
201
|
* methods return the output value directly; when false they're wrapped in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action_codegen.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_codegen.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"action_codegen.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_codegen.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { UnreachableError } from '@fuzdev/fuz_util/error.ts';
|
|
2
2
|
import { zod_get_base_type } from '../zod.js';
|
|
3
|
+
import { is_empty_input_handler_guarded } from '../schema_meta.js';
|
|
3
4
|
import { ActionRegistry } from './action_registry.js';
|
|
4
5
|
/**
|
|
5
6
|
* Method names of fuz_app's protocol actions — `heartbeat` (auth-aware client
|
|
@@ -320,6 +321,23 @@ export const to_action_spec_output_identifier = (method) => `${to_action_spec_id
|
|
|
320
321
|
* value/type lookups, which already accepts the raw method string.
|
|
321
322
|
*/
|
|
322
323
|
export const to_action_property_key = (method) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(method) ? method : `'${method}'`;
|
|
324
|
+
/**
|
|
325
|
+
* Whether a caller may omit an action's input: its schema accepts `undefined`,
|
|
326
|
+
* or accepts `{}` (what an omitted input is validated as) and is not marked
|
|
327
|
+
* `empty_input_handler_guarded` (`SchemaFieldMeta`, read by
|
|
328
|
+
* `is_empty_input_handler_guarded`). The rule codegen emits `input?:` by and
|
|
329
|
+
* the input-shape invariant tests read.
|
|
330
|
+
*
|
|
331
|
+
* @param spec - the action spec
|
|
332
|
+
* @returns whether the typed surface makes the input optional
|
|
333
|
+
*/
|
|
334
|
+
export const action_input_is_optional = (spec) => {
|
|
335
|
+
if (spec.input.safeParse(undefined).success)
|
|
336
|
+
return true;
|
|
337
|
+
if (is_empty_input_handler_guarded(spec.input))
|
|
338
|
+
return false;
|
|
339
|
+
return spec.input.safeParse({}).success;
|
|
340
|
+
};
|
|
323
341
|
/**
|
|
324
342
|
* Generates one method line of the typed `FrontendActionsApi` interface for a
|
|
325
343
|
* single spec. Encapsulates the input/options/return-type signature shape so
|
|
@@ -357,7 +375,10 @@ ActingActor})` and other all-optional-fields strict objects. The second
|
|
|
357
375
|
* schema is asked to validate. A schema with required fields fails both
|
|
358
376
|
* probes and stays `input:` (required at the typed surface). Refinements
|
|
359
377
|
* and transforms run as part of `safeParse`, so their accept/reject
|
|
360
|
-
* decisions feed into the optional/required choice naturally.
|
|
378
|
+
* decisions feed into the optional/required choice naturally. An input
|
|
379
|
+
* marked `empty_input_handler_guarded` is the exception: its schema accepts
|
|
380
|
+
* `{}` but the handler refuses it, so it stays `input:`
|
|
381
|
+
* (`action_input_is_optional` is the one rule).
|
|
361
382
|
*
|
|
362
383
|
* @param options.sync_returns_value - When true (default), sync `local_call`
|
|
363
384
|
* methods return the output value directly; when false they're wrapped in
|
|
@@ -372,7 +393,7 @@ export const generate_actions_api_method_signature = (spec, imports, options) =>
|
|
|
372
393
|
const collections_path = options?.collections_path ?? DEFAULT_COLLECTIONS_PATH;
|
|
373
394
|
const innermost_type_name = zod_get_base_type(spec.input);
|
|
374
395
|
const has_input = innermost_type_name !== 'null' && innermost_type_name !== 'void';
|
|
375
|
-
const input_optional = has_input && (spec
|
|
396
|
+
const input_optional = has_input && action_input_is_optional(spec);
|
|
376
397
|
const input_param = has_input
|
|
377
398
|
? `input${input_optional ? '?' : ''}: ActionInputs['${spec.method}']`
|
|
378
399
|
: 'input?: void';
|
|
@@ -319,7 +319,7 @@ const check_action_auth_post_authorization = (auth, request_context, credential_
|
|
|
319
319
|
}
|
|
320
320
|
if (auth.roles?.length) {
|
|
321
321
|
if (!has_any_scoped_role(request_context, auth.roles, null)) {
|
|
322
|
-
return jsonrpc_error_messages.forbidden(
|
|
322
|
+
return jsonrpc_error_messages.forbidden('forbidden', {
|
|
323
323
|
reason: ERROR_INSUFFICIENT_PERMISSIONS,
|
|
324
324
|
required_roles: auth.roles
|
|
325
325
|
});
|
package/dist/auth/CLAUDE.md
CHANGED
|
@@ -31,7 +31,7 @@ over the pool so rows persist when request transactions roll back. See root
|
|
|
31
31
|
|
|
32
32
|
### Crypto primitives (pure, I/O-free)
|
|
33
33
|
|
|
34
|
-
- `auth/keyring.ts` — `Keyring`, `create_keyring
|
|
34
|
+
- `auth/keyring.ts` — `Keyring`, `create_keyring` (validates — the one way to build a `Keyring`), `validate_keyring`.
|
|
35
35
|
- `auth/session_cookie.ts` — `SessionOptions<T>`, `parse_session`, `process_session_cookie` (`'none' | 'clear'` — no refresh action; the 30-day lifetime is an absolute cap signed once at mint), `create_session_config`, `fuz_session_config`, `SESSION_AGE_MAX`.
|
|
36
36
|
- `auth/password.ts` — `Password`, `PasswordProvided`, `PasswordHashDeps`, `PASSWORD_LENGTH_MIN` (12, OWASP), `PASSWORD_LENGTH_MAX` (300).
|
|
37
37
|
- `auth/password_argon2.ts` — `hash_password`, `verify_password`, `verify_dummy`, `argon2_password_deps`.
|
|
@@ -72,7 +72,8 @@ export interface BootstrapAccountDeps {
|
|
|
72
72
|
* Uses an atomic `bootstrap_lock` UPDATE to prevent concurrent bootstrap
|
|
73
73
|
* attempts (TOCTOU). The full flow runs in a single transaction:
|
|
74
74
|
*
|
|
75
|
-
* 1. Read and verify the bootstrap token (before transaction)
|
|
75
|
+
* 1. Read and verify the bootstrap token (before transaction) — the file's
|
|
76
|
+
* raw bytes less one optional trailing LF, compared in constant time
|
|
76
77
|
* 2. Hash the password (CPU-intensive, before transaction)
|
|
77
78
|
* 3. Acquire the bootstrap lock atomically (inside transaction)
|
|
78
79
|
* 4. Create account + actor
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap_account.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_account.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACN,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGrE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEtC,gDAAgD;AAChD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,6DAA6D;AAC7D,MAAM,WAAW,uBAAuB;IACvC,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;IACrD,wFAAwF;IACxF,kBAAkB,EAAE,OAAO,CAAC;CAC5B;AAED,gCAAgC;AAChC,MAAM,MAAM,uBAAuB,GAChC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,0BAA0B,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GACpE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,wBAAwB,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GAClE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,mBAAmB,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,CAAC;AAEjE,qFAAqF;AACrF,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG,uBAAuB,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,EAAE,CAAC;IACP,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACxD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,6EAA6E;IAC7E,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IAClD,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;CACZ;
|
|
1
|
+
{"version":3,"file":"bootstrap_account.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_account.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACN,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGrE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEtC,gDAAgD;AAChD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,6DAA6D;AAC7D,MAAM,WAAW,uBAAuB;IACvC,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;IACrD,wFAAwF;IACxF,kBAAkB,EAAE,OAAO,CAAC;CAC5B;AAED,gCAAgC;AAChC,MAAM,MAAM,uBAAuB,GAChC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,0BAA0B,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GACpE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,wBAAwB,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GAClE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,mBAAmB,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,CAAC;AAEjE,qFAAqF;AACrF,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG,uBAAuB,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,EAAE,CAAC;IACP,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACxD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,6EAA6E;IAC7E,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IAClD,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;CACZ;AAcD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,iBAAiB,GAC7B,MAAM,oBAAoB,EAC1B,gBAAgB,MAAM,EACtB,OAAO,qBAAqB,KAC1B,OAAO,CAAC,sBAAsB,CA6EhC,CAAC"}
|
|
@@ -12,13 +12,24 @@ import { ERROR_INVALID_TOKEN, ERROR_ALREADY_BOOTSTRAPPED, ERROR_TOKEN_FILE_MISSI
|
|
|
12
12
|
import { ROLE_ADMIN, ROLE_KEEPER } from './role_schema.js';
|
|
13
13
|
import { query_create_account_with_actor } from './account_queries.js';
|
|
14
14
|
import { query_create_role_grant } from './role_grant_queries.js';
|
|
15
|
+
/**
|
|
16
|
+
* Strip exactly one trailing `\n` from the operator-written token bytes.
|
|
17
|
+
*
|
|
18
|
+
* Not `trim()`: trimming widens the set of accepted tokens — `tok\r\n`,
|
|
19
|
+
* `tok \n`, or a leading newline would all pass. One trailing LF is the
|
|
20
|
+
* newline a POSIX editor appends; anything else stays in the bytes and fails
|
|
21
|
+
* the compare, so operators write the token exactly. Twin of the Rust
|
|
22
|
+
* `strip_one_trailing_newline` (`fuz_auth`).
|
|
23
|
+
*/
|
|
24
|
+
const strip_one_trailing_newline = (bytes) => bytes.at(-1) === 0x0a ? bytes.subarray(0, -1) : bytes;
|
|
15
25
|
/**
|
|
16
26
|
* Bootstrap the first account with keeper and admin privileges.
|
|
17
27
|
*
|
|
18
28
|
* Uses an atomic `bootstrap_lock` UPDATE to prevent concurrent bootstrap
|
|
19
29
|
* attempts (TOCTOU). The full flow runs in a single transaction:
|
|
20
30
|
*
|
|
21
|
-
* 1. Read and verify the bootstrap token (before transaction)
|
|
31
|
+
* 1. Read and verify the bootstrap token (before transaction) — the file's
|
|
32
|
+
* raw bytes less one optional trailing LF, compared in constant time
|
|
22
33
|
* 2. Hash the password (CPU-intensive, before transaction)
|
|
23
34
|
* 3. Acquire the bootstrap lock atomically (inside transaction)
|
|
24
35
|
* 4. Create account + actor
|
|
@@ -41,17 +52,17 @@ export const bootstrap_account = async (deps, provided_token, input) => {
|
|
|
41
52
|
// wire always carried, with the specific reason logged for the operator.
|
|
42
53
|
let expected_token;
|
|
43
54
|
try {
|
|
44
|
-
expected_token =
|
|
55
|
+
expected_token = strip_one_trailing_newline(await read_secure_file(token_path));
|
|
45
56
|
}
|
|
46
57
|
catch (err) {
|
|
47
58
|
log.warn(`bootstrap token file rejected: ${to_error_message(err)}`);
|
|
48
59
|
return { ok: false, error: ERROR_TOKEN_FILE_MISSING, status: 404 };
|
|
49
60
|
}
|
|
50
|
-
//
|
|
51
|
-
//
|
|
61
|
+
// raw bytes on both sides, nothing trimmed — the provided token must be the
|
|
62
|
+
// file's bytes exactly, less the one newline an editor appends
|
|
52
63
|
const provided_buf = Buffer.from(provided_token);
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
if (provided_buf.length !== expected_token.length ||
|
|
65
|
+
!timingSafeEqual(provided_buf, expected_token)) {
|
|
55
66
|
return { ok: false, error: ERROR_INVALID_TOKEN, status: 401 };
|
|
56
67
|
}
|
|
57
68
|
// 2. Hash password (CPU-intensive, before transaction)
|
|
@@ -251,7 +251,9 @@ export declare const CellCreateOutput: z.ZodObject<{
|
|
|
251
251
|
export type CellCreateOutput = z.infer<typeof CellCreateOutput>;
|
|
252
252
|
/**
|
|
253
253
|
* Input for `cell_get`. Pass `id` OR `path` (exactly one expected; both
|
|
254
|
-
* accepted, `id` takes precedence).
|
|
254
|
+
* accepted, `id` takes precedence). Neither is `invalid_params` with
|
|
255
|
+
* `ERROR_CELL_GET_REQUIRES_ID_OR_PATH`, from the handler (the schema leaves
|
|
256
|
+
* both optional). The handler responds with 404 when no
|
|
255
257
|
* row matches OR when `can_view_cell` rejects the caller — same code so
|
|
256
258
|
* private-cell existence doesn't leak.
|
|
257
259
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_action_specs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"cell_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_action_specs.ts"],"names":[],"mappings":"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"}
|
|
@@ -243,7 +243,9 @@ export const CellCreateOutput = z.strictObject({ cell: CellJson });
|
|
|
243
243
|
// -- cell_get ---------------------------------------------------------------
|
|
244
244
|
/**
|
|
245
245
|
* Input for `cell_get`. Pass `id` OR `path` (exactly one expected; both
|
|
246
|
-
* accepted, `id` takes precedence).
|
|
246
|
+
* accepted, `id` takes precedence). Neither is `invalid_params` with
|
|
247
|
+
* `ERROR_CELL_GET_REQUIRES_ID_OR_PATH`, from the handler (the schema leaves
|
|
248
|
+
* both optional). The handler responds with 404 when no
|
|
247
249
|
* row matches OR when `can_view_cell` rejects the caller — same code so
|
|
248
250
|
* private-cell existence doesn't leak.
|
|
249
251
|
*/
|
|
@@ -253,9 +255,7 @@ export const CellGetInput = z
|
|
|
253
255
|
path: CellPath.optional(),
|
|
254
256
|
acting: ActingActor
|
|
255
257
|
})
|
|
256
|
-
.
|
|
257
|
-
message: ERROR_CELL_GET_REQUIRES_ID_OR_PATH
|
|
258
|
-
});
|
|
258
|
+
.meta({ empty_input_handler_guarded: true });
|
|
259
259
|
/**
|
|
260
260
|
* Output for `cell_get`. Bundles relation arrays (`fields` + `items`)
|
|
261
261
|
* server-side via JOINs so the common "show this cell with its
|
|
@@ -377,7 +377,7 @@ export const CellCloneInput = z.strictObject({
|
|
|
377
377
|
description: 'Recurse into `items[]` (depth=1 — clones direct children only). Default false.'
|
|
378
378
|
}),
|
|
379
379
|
// TODO: cap `with_data_patch` size/depth once a consumer measures the
|
|
380
|
-
// upper bound. `
|
|
380
|
+
// upper bound. `CellData` is a loose object, unbounded — a multi-MB patch is in scope
|
|
381
381
|
// today, gated only by the JSON-RPC body limit. Realistic patches are
|
|
382
382
|
// O(few KB); a `.refine` on serialized size would tighten the surface
|
|
383
383
|
// without disturbing the patch-wins-last semantics.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAIH,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAEN,KAAK,mBAAmB,EAExB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAoCN,KAAK,QAAQ,EAEb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EASN,KAAK,OAAO,EACZ,MAAM,uBAAuB,CAAC;AAmC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACxC,uFAAuF;IACvF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6HAA6H;IAC7H,IAAI,EAAE,QAAQ,CAAC;IACf,wHAAwH;IACxH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,wJAAwJ;IACxJ,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,qbAAqb;IACrb,SAAS,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,8GAA8G;IAC9G,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,mBAAmB,EAAE,OAAO,CAAA;CAAE,CAAC;AAEjG;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAAG,CACjC,IAAI,EAAE,mBAAmB,EACzB,KAAK,EAAE,wBAAwB,KAC3B,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEpD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG;IAChD,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,QAAQ,CAAC;IAC7C,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;CACvC,CAAC;AA6BF,eAAO,MAAM,YAAY,GAAI,KAAK,OAAO,KAAG,QAgB1C,CAAC;AAkDH,+CAA+C;AAC/C,eAAO,MAAM,mBAAmB,GAAI,MAAM,cAAc,KAAG,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"cell_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAIH,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAEN,KAAK,mBAAmB,EAExB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAoCN,KAAK,QAAQ,EAEb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EASN,KAAK,OAAO,EACZ,MAAM,uBAAuB,CAAC;AAmC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACxC,uFAAuF;IACvF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6HAA6H;IAC7H,IAAI,EAAE,QAAQ,CAAC;IACf,wHAAwH;IACxH,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,wJAAwJ;IACxJ,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,qbAAqb;IACrb,SAAS,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,8GAA8G;IAC9G,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,mBAAmB,EAAE,OAAO,CAAA;CAAE,CAAC;AAEjG;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAAG,CACjC,IAAI,EAAE,mBAAmB,EACzB,KAAK,EAAE,wBAAwB,KAC3B,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEpD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG;IAChD,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,QAAQ,CAAC;IAC7C,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;CACvC,CAAC;AA6BF,eAAO,MAAM,YAAY,GAAI,KAAK,OAAO,KAAG,QAgB1C,CAAC;AAkDH,+CAA+C;AAC/C,eAAO,MAAM,mBAAmB,GAAI,MAAM,cAAc,KAAG,KAAK,CAAC,SAAS,CAmrBzE,CAAC"}
|
|
@@ -294,9 +294,8 @@ export const create_cell_actions = (deps) => {
|
|
|
294
294
|
return { cell: to_cell_json(row) };
|
|
295
295
|
};
|
|
296
296
|
const get_handler = async (input, ctx) => {
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
// bypass the wire schema get the same error shape.
|
|
297
|
+
// both optional on the wire, so the handler holds "id or path" and
|
|
298
|
+
// names it in the reason (`id` wins when both are given)
|
|
300
299
|
if (input.id === undefined && input.path === undefined) {
|
|
301
300
|
throw jsonrpc_errors.invalid_params('cell_get requires id or path', {
|
|
302
301
|
reason: ERROR_CELL_GET_REQUIRES_ID_OR_PATH
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Generic cell-data base schema.
|
|
3
3
|
*
|
|
4
4
|
* The wire-side shape every cell consumer can read without per-kind
|
|
5
|
-
* knowledge: a permissive bag with
|
|
5
|
+
* knowledge: a permissive bag with two universally-relevant typed
|
|
6
6
|
* fields. Per-kind schemas extend this and narrow `kind` to a literal.
|
|
7
7
|
*
|
|
8
8
|
* Loose object: arbitrary additional fields pass through unvalidated,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Generic cell-data base schema.
|
|
3
3
|
*
|
|
4
4
|
* The wire-side shape every cell consumer can read without per-kind
|
|
5
|
-
* knowledge: a permissive bag with
|
|
5
|
+
* knowledge: a permissive bag with two universally-relevant typed
|
|
6
6
|
* fields. Per-kind schemas extend this and narrow `kind` to a literal.
|
|
7
7
|
*
|
|
8
8
|
* Loose object: arbitrary additional fields pass through unvalidated,
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @module
|
|
12
12
|
*/
|
|
13
13
|
import { z } from 'zod';
|
|
14
|
-
/** Error reason — `cell_field_list` got neither `source_id`
|
|
14
|
+
/** Error reason — `cell_field_list` got neither or both of `source_id` and `target_id`. */
|
|
15
15
|
export declare const ERROR_CELL_FIELD_LIST_REQUIRES_SOURCE_OR_TARGET: "cell_field_list_requires_source_or_target";
|
|
16
16
|
/**
|
|
17
17
|
* Field name grammar — fuz snake_case identifier convention. Anchored
|
|
@@ -66,8 +66,9 @@ export declare const CellFieldDeleteOutput: z.ZodObject<{
|
|
|
66
66
|
export type CellFieldDeleteOutput = z.infer<typeof CellFieldDeleteOutput>;
|
|
67
67
|
/**
|
|
68
68
|
* Input for `cell_field_list`. Pass `source_id` for forward fields or
|
|
69
|
-
* `target_id` for reverse upfields — exactly one
|
|
70
|
-
*
|
|
69
|
+
* `target_id` for reverse upfields — exactly one; both or neither is
|
|
70
|
+
* `invalid_params` with `ERROR_CELL_FIELD_LIST_REQUIRES_SOURCE_OR_TARGET`,
|
|
71
|
+
* from the handler (the schema leaves both optional). Reverse listing has 2-layer authz (target view-check
|
|
71
72
|
* gates the call; per-source view-check filters the rows).
|
|
72
73
|
*
|
|
73
74
|
* Either direction returns a page of up to `limit` fields (default
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell_field_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_field_action_specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"cell_field_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_field_action_specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,2FAA2F;AAC3F,eAAO,MAAM,+CAA+C,EAC3D,2CAAoD,CAAC;AAItD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAA2B,CAAC;AAC9D,eAAO,MAAM,aAAa,yDAAiE,CAAC;AAC5F,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,2EAA2E;AAC3E,eAAO,MAAM,SAAS;;;;;kBAKpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAIlD;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;kBAO5B,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,eAAO,MAAM,kBAAkB;;;;;;;kBAAuC,CAAC;AACvE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAIpE;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;kBAI/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,eAAO,MAAM,qBAAqB;;;kBAGhC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAI1E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB;;;;;;kBAewC,CAAC;AACxE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,eAAO,MAAM,mBAAmB;;;;;;;kBAE9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAItE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;CAWF,CAAC;AAEtC,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;CAWL,CAAC;AAEtC,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYH,CAAC;AAEtC,2EAA2E;AAC3E,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAI9B,CAAC"}
|
|
@@ -15,7 +15,7 @@ import { Uuid } from '../primitive_schemas.js';
|
|
|
15
15
|
import { ActingActor } from '../http/auth_shape.js';
|
|
16
16
|
import { CellRelationListLimit } from './cell_relation_list_limit.js';
|
|
17
17
|
// -- Error reasons ----------------------------------------------------------
|
|
18
|
-
/** Error reason — `cell_field_list` got neither `source_id`
|
|
18
|
+
/** Error reason — `cell_field_list` got neither or both of `source_id` and `target_id`. */
|
|
19
19
|
export const ERROR_CELL_FIELD_LIST_REQUIRES_SOURCE_OR_TARGET = 'cell_field_list_requires_source_or_target';
|
|
20
20
|
// -- Shared schemas ---------------------------------------------------------
|
|
21
21
|
/**
|
|
@@ -63,8 +63,9 @@ export const CellFieldDeleteOutput = z.strictObject({
|
|
|
63
63
|
// -- cell_field_list --------------------------------------------------------
|
|
64
64
|
/**
|
|
65
65
|
* Input for `cell_field_list`. Pass `source_id` for forward fields or
|
|
66
|
-
* `target_id` for reverse upfields — exactly one
|
|
67
|
-
*
|
|
66
|
+
* `target_id` for reverse upfields — exactly one; both or neither is
|
|
67
|
+
* `invalid_params` with `ERROR_CELL_FIELD_LIST_REQUIRES_SOURCE_OR_TARGET`,
|
|
68
|
+
* from the handler (the schema leaves both optional). Reverse listing has 2-layer authz (target view-check
|
|
68
69
|
* gates the call; per-source view-check filters the rows).
|
|
69
70
|
*
|
|
70
71
|
* Either direction returns a page of up to `limit` fields (default
|
|
@@ -87,9 +88,7 @@ export const CellFieldListInput = z
|
|
|
87
88
|
limit: CellRelationListLimit,
|
|
88
89
|
acting: ActingActor
|
|
89
90
|
})
|
|
90
|
-
.
|
|
91
|
-
message: ERROR_CELL_FIELD_LIST_REQUIRES_SOURCE_OR_TARGET
|
|
92
|
-
});
|
|
91
|
+
.meta({ empty_input_handler_guarded: true });
|
|
93
92
|
export const CellFieldListOutput = z.strictObject({
|
|
94
93
|
fields: z.array(FieldJson)
|
|
95
94
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell_field_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_field_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAUN,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"cell_field_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_field_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAUN,KAAK,SAAS,EAEd,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,6BAA6B,CAAC;AAMrC,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAEpD,eAAO,MAAM,aAAa,GAAI,KAAK,YAAY,KAAG,SAKhD,CAAC;AAEH,mDAAmD;AACnD,eAAO,MAAM,yBAAyB,GAAI,MAAM,mBAAmB,KAAG,KAAK,CAAC,SAAS,CA4IpF,CAAC"}
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
import { rpc_action } from '../actions/action_rpc.js';
|
|
29
29
|
import { jsonrpc_errors } from '../http/jsonrpc_errors.js';
|
|
30
|
-
import { cell_field_set_action_spec, cell_field_delete_action_spec, cell_field_list_action_spec } from './cell_field_action_specs.js';
|
|
30
|
+
import { cell_field_set_action_spec, cell_field_delete_action_spec, cell_field_list_action_spec, ERROR_CELL_FIELD_LIST_REQUIRES_SOURCE_OR_TARGET } from './cell_field_action_specs.js';
|
|
31
31
|
import { ERROR_CELL_NOT_FOUND } from './cell_action_specs.js';
|
|
32
32
|
import { can_view_cell, can_edit_cell, cell_viewer_from_auth } from './cell_authorize.js';
|
|
33
33
|
import { CELL_RELATION_LIST_LIMIT_DEFAULT } from './cell_relation_list_limit.js';
|
|
@@ -110,6 +110,13 @@ export const create_cell_field_actions = (deps) => {
|
|
|
110
110
|
};
|
|
111
111
|
const list_handler = async (input, ctx) => {
|
|
112
112
|
const auth = ctx.auth;
|
|
113
|
+
// exactly one endpoint — both optional on the wire, so the handler
|
|
114
|
+
// holds the rule and names it in the reason
|
|
115
|
+
if ((input.source_id === undefined) === (input.target_id === undefined)) {
|
|
116
|
+
throw jsonrpc_errors.invalid_params('invalid params', {
|
|
117
|
+
reason: ERROR_CELL_FIELD_LIST_REQUIRES_SOURCE_OR_TARGET
|
|
118
|
+
});
|
|
119
|
+
}
|
|
113
120
|
// an omitted limit is the default page, either direction
|
|
114
121
|
const limit = input.limit ?? CELL_RELATION_LIST_LIMIT_DEFAULT;
|
|
115
122
|
// Forward listing: gate on can_view_cell(source), then page the fields
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @module
|
|
11
11
|
*/
|
|
12
12
|
import { z } from 'zod';
|
|
13
|
-
/** Error reason — `cell_item_list` got neither `parent_id`
|
|
13
|
+
/** Error reason — `cell_item_list` got neither or both of `parent_id` and `child_id`. */
|
|
14
14
|
export declare const ERROR_CELL_ITEM_LIST_REQUIRES_PARENT_OR_CHILD: "cell_item_list_requires_parent_or_child";
|
|
15
15
|
/**
|
|
16
16
|
* Error reason — `(parent_id, position)` collision on `cell_item_insert`
|
|
@@ -106,7 +106,9 @@ export declare const CellItemDeleteOutput: z.ZodObject<{
|
|
|
106
106
|
export type CellItemDeleteOutput = z.infer<typeof CellItemDeleteOutput>;
|
|
107
107
|
/**
|
|
108
108
|
* Input for `cell_item_list`. Pass `parent_id` for forward items or
|
|
109
|
-
* `child_id` for reverse lists — exactly one
|
|
109
|
+
* `child_id` for reverse lists — exactly one; both or neither is
|
|
110
|
+
* `invalid_params` with `ERROR_CELL_ITEM_LIST_REQUIRES_PARENT_OR_CHILD`, from
|
|
111
|
+
* the handler (the schema leaves both optional). Reverse listing has 2-layer
|
|
110
112
|
* authz (child view-check gates the call; per-parent view-check filters
|
|
111
113
|
* the rows).
|
|
112
114
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell_item_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_item_action_specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"cell_item_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_item_action_specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,yFAAyF;AACzF,eAAO,MAAM,6CAA6C,EACzD,yCAAkD,CAAC;AAEpD;;;;;;;;;GASG;AACH,eAAO,MAAM,8BAA8B,EAAG,0BAAmC,CAAC;AAIlF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,4DAEF,CAAC;AAC5B,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ;;;;;kBAKnB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAIhD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;kBAO9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,oBAAoB;;;;;;;kBAAqC,CAAC;AACvE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIxE;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;kBAK5B,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,eAAO,MAAM,kBAAkB;;;;;;;kBAAqC,CAAC;AACrE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAIpE,gEAAgE;AAChE,eAAO,MAAM,mBAAmB;;;;kBAI9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,oBAAoB;;;kBAG/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIxE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB;;;;;;kBAcyC,CAAC;AACxE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,eAAO,MAAM,kBAAkB;;;;;;;kBAE7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAIpE,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;CAWJ,CAAC;AAEtC,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;CAWF,CAAC;AAEtC,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;CAWJ,CAAC;AAEtC,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYF,CAAC;AAEtC,0EAA0E;AAC1E,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK7B,CAAC"}
|
|
@@ -15,7 +15,7 @@ import { FRACTIONAL_INDEX_LENGTH_MAX, FRACTIONAL_INDEX_REGEX } from '@fuzdev/fuz
|
|
|
15
15
|
import { ActingActor } from '../http/auth_shape.js';
|
|
16
16
|
import { CellRelationListLimit } from './cell_relation_list_limit.js';
|
|
17
17
|
// -- Error reasons ----------------------------------------------------------
|
|
18
|
-
/** Error reason — `cell_item_list` got neither `parent_id`
|
|
18
|
+
/** Error reason — `cell_item_list` got neither or both of `parent_id` and `child_id`. */
|
|
19
19
|
export const ERROR_CELL_ITEM_LIST_REQUIRES_PARENT_OR_CHILD = 'cell_item_list_requires_parent_or_child';
|
|
20
20
|
/**
|
|
21
21
|
* Error reason — `(parent_id, position)` collision on `cell_item_insert`
|
|
@@ -98,7 +98,9 @@ export const CellItemDeleteOutput = z.strictObject({
|
|
|
98
98
|
// -- cell_item_list ---------------------------------------------------------
|
|
99
99
|
/**
|
|
100
100
|
* Input for `cell_item_list`. Pass `parent_id` for forward items or
|
|
101
|
-
* `child_id` for reverse lists — exactly one
|
|
101
|
+
* `child_id` for reverse lists — exactly one; both or neither is
|
|
102
|
+
* `invalid_params` with `ERROR_CELL_ITEM_LIST_REQUIRES_PARENT_OR_CHILD`, from
|
|
103
|
+
* the handler (the schema leaves both optional). Reverse listing has 2-layer
|
|
102
104
|
* authz (child view-check gates the call; per-parent view-check filters
|
|
103
105
|
* the rows).
|
|
104
106
|
*
|
|
@@ -122,9 +124,7 @@ export const CellItemListInput = z
|
|
|
122
124
|
limit: CellRelationListLimit,
|
|
123
125
|
acting: ActingActor
|
|
124
126
|
})
|
|
125
|
-
.
|
|
126
|
-
message: ERROR_CELL_ITEM_LIST_REQUIRES_PARENT_OR_CHILD
|
|
127
|
-
});
|
|
127
|
+
.meta({ empty_input_handler_guarded: true });
|
|
128
128
|
export const CellItemListOutput = z.strictObject({
|
|
129
129
|
items: z.array(ItemJson)
|
|
130
130
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell_item_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_item_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,
|
|
1
|
+
{"version":3,"file":"cell_item_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_item_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAgBN,KAAK,QAAQ,EACb,MAAM,6BAA6B,CAAC;AAMrC,OAAO,EAMN,KAAK,WAAW,EAChB,MAAM,4BAA4B,CAAC;AAOpC,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAEnD,eAAO,MAAM,YAAY,GAAI,KAAK,WAAW,KAAG,QAS9C,CAAC;AAOH,iDAAiD;AACjD,eAAO,MAAM,wBAAwB,GAAI,MAAM,kBAAkB,KAAG,KAAK,CAAC,SAAS,CA+KlF,CAAC"}
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
import { rpc_action } from '../actions/action_rpc.js';
|
|
31
31
|
import { jsonrpc_errors } from '../http/jsonrpc_errors.js';
|
|
32
32
|
import { is_pg_unique_violation } from '../db/pg_error.js';
|
|
33
|
-
import { cell_item_insert_action_spec, cell_item_move_action_spec, cell_item_delete_action_spec, cell_item_list_action_spec, ERROR_CELL_ITEM_POSITION_TAKEN } from './cell_item_action_specs.js';
|
|
33
|
+
import { cell_item_insert_action_spec, cell_item_move_action_spec, cell_item_delete_action_spec, cell_item_list_action_spec, ERROR_CELL_ITEM_POSITION_TAKEN, ERROR_CELL_ITEM_LIST_REQUIRES_PARENT_OR_CHILD } from './cell_item_action_specs.js';
|
|
34
34
|
import { ERROR_CELL_NOT_FOUND } from './cell_action_specs.js';
|
|
35
35
|
import { can_view_cell, can_edit_cell, cell_viewer_from_auth } from './cell_authorize.js';
|
|
36
36
|
import { CELL_RELATION_LIST_LIMIT_DEFAULT } from './cell_relation_list_limit.js';
|
|
@@ -161,6 +161,13 @@ export const create_cell_item_actions = (deps) => {
|
|
|
161
161
|
};
|
|
162
162
|
const list_handler = async (input, ctx) => {
|
|
163
163
|
const auth = ctx.auth;
|
|
164
|
+
// exactly one endpoint — both optional on the wire, so the handler
|
|
165
|
+
// holds the rule and names it in the reason
|
|
166
|
+
if ((input.parent_id === undefined) === (input.child_id === undefined)) {
|
|
167
|
+
throw jsonrpc_errors.invalid_params('invalid params', {
|
|
168
|
+
reason: ERROR_CELL_ITEM_LIST_REQUIRES_PARENT_OR_CHILD
|
|
169
|
+
});
|
|
170
|
+
}
|
|
164
171
|
// an omitted limit is the default page, either direction
|
|
165
172
|
const limit = input.limit ?? CELL_RELATION_LIST_LIMIT_DEFAULT;
|
|
166
173
|
// Forward listing: gate on can_view_cell(parent), then page the items
|