@fuzdev/fuz_app 0.147.0 → 0.149.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 +8 -6
- 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/action_event.d.ts.map +1 -1
- package/dist/actions/action_event.js +14 -1
- package/dist/actions/perform_action.d.ts +17 -1
- package/dist/actions/perform_action.d.ts.map +1 -1
- package/dist/actions/perform_action.js +23 -3
- package/dist/auth/CLAUDE.md +3 -2
- package/dist/auth/account_action_specs.d.ts +12 -0
- package/dist/auth/account_action_specs.d.ts.map +1 -1
- package/dist/auth/account_action_specs.js +16 -2
- package/dist/auth/account_actions.d.ts.map +1 -1
- package/dist/auth/account_actions.js +7 -4
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_action_specs.js +29 -8
- package/dist/auth/audit_emitter.d.ts +14 -0
- package/dist/auth/audit_emitter.d.ts.map +1 -1
- package/dist/auth/audit_emitter.js +5 -1
- 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/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 +8 -4
- package/dist/http/CLAUDE.md +14 -2
- package/dist/http/error_schemas.d.ts +8 -0
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +12 -0
- package/dist/http/jsonrpc_errors.d.ts +40 -15
- package/dist/http/jsonrpc_errors.d.ts.map +1 -1
- package/dist/http/jsonrpc_errors.js +90 -35
- 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 +80 -0
- package/dist/schema_meta.d.ts.map +1 -1
- package/dist/schema_meta.js +71 -1
- package/dist/testing/CLAUDE.md +853 -146
- 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 +124 -0
- package/dist/testing/adversarial_input_cases.d.ts.map +1 -0
- package/dist/testing/adversarial_input_cases.js +393 -0
- 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 +30 -3
- package/dist/testing/audit_drift_guard.d.ts.map +1 -1
- package/dist/testing/audit_drift_guard.js +55 -3
- 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 +57 -0
- package/dist/testing/cross_backend/audit_cross_helpers.d.ts.map +1 -0
- package/dist/testing/cross_backend/audit_cross_helpers.js +89 -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/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 +78 -59
- package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.js +25 -24
- 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 +174 -3
- 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} +14 -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 +58 -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.map +1 -1
- package/dist/testing/cross_backend/fact_serving.js +27 -17
- 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 +47 -0
- package/dist/testing/cross_backend/rpc_adversarial.d.ts.map +1 -0
- package/dist/testing/cross_backend/rpc_adversarial.js +302 -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 +33 -21
- 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.js +1 -1
- package/dist/testing/cross_backend/setup.d.ts +58 -56
- 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 +311 -0
- package/dist/testing/cross_backend/spine_suites.d.ts.map +1 -0
- package/dist/testing/cross_backend/spine_suites.js +897 -0
- package/dist/testing/cross_backend/spine_surface_constants.d.ts +44 -0
- package/dist/testing/cross_backend/spine_surface_constants.d.ts.map +1 -1
- package/dist/testing/cross_backend/spine_surface_constants.js +53 -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 +29 -12
- package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_backdoor.js +143 -51
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +30 -14
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +58 -37
- 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 +23 -13
- 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 +10 -0
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.js +27 -140
- package/dist/testing/rpc_envelope_cases.d.ts +114 -0
- package/dist/testing/rpc_envelope_cases.d.ts.map +1 -0
- package/dist/testing/rpc_envelope_cases.js +243 -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 +99 -2
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +261 -73
- 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/stubs.d.ts +4 -3
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +6 -4
- 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/dist/zod.d.ts +9 -0
- package/dist/zod.d.ts.map +1 -1
- package/dist/zod.js +20 -0
- package/package.json +6 -4
- 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
|
@@ -9,38 +9,72 @@ import './assert_dev_env.js';
|
|
|
9
9
|
* fixture-producing callback.
|
|
10
10
|
*
|
|
11
11
|
* Cadence: per-describe `setup_test()` call (see `testing/round_trip.ts` module
|
|
12
|
-
* docstring).
|
|
13
|
-
* method-direction
|
|
14
|
-
*
|
|
12
|
+
* docstring). The generic POST and GET cases fire one JSON-RPC envelope per
|
|
13
|
+
* method-direction against shared principals (an authed account, an admin
|
|
14
|
+
* account, the keeper). A side-effecting method called as the authed account
|
|
15
|
+
* runs on a fresh account of its own (`round_trip_uses_fresh_account`):
|
|
16
|
+
* the generated params of a self-targeting method act on the caller — an
|
|
17
|
+
* `account_delete` with no `account_id` deletes it, an
|
|
18
|
+
* `account_session_revoke_all` ends its session — and on the shared account
|
|
19
|
+
* that would leave every later call refused as unauthenticated. A 401 to any
|
|
20
|
+
* non-public call fails (`assert_rpc_authenticated`), so a credential lost
|
|
21
|
+
* some other way goes red rather than vacuous. The `success_fixtures` case
|
|
22
|
+
* also mutates — each fixture builds a row and the call revokes, deletes, or
|
|
23
|
+
* decides it — so it runs last on the describe's fixture, and each factory
|
|
24
|
+
* seeds its own rows.
|
|
15
25
|
*
|
|
16
26
|
* @module
|
|
17
27
|
*/
|
|
18
28
|
import { describe, test, beforeAll, assert } from 'vitest';
|
|
19
29
|
import { ROLE_ADMIN } from '../auth/role_schema.js';
|
|
20
|
-
import { JSONRPC_METHOD_NOT_FOUND, JsonrpcErrorResponse } from '../http/jsonrpc.js';
|
|
30
|
+
import { JSONRPC_INTERNAL_ERROR, JSONRPC_METHOD_NOT_FOUND, JsonrpcErrorResponse } from '../http/jsonrpc.js';
|
|
31
|
+
import { jsonrpc_error_code_to_http_status } from '../http/jsonrpc_errors.js';
|
|
21
32
|
import { generate_valid_body } from './schema_generators.js';
|
|
22
|
-
import { is_public_auth } from '../http/auth_shape.js';
|
|
23
33
|
import { create_rpc_post_init, create_rpc_get_url, assert_jsonrpc_error_response, assert_jsonrpc_success_response, resolve_rpc_endpoints_for_setup, find_rpc_action, find_rpc_method } from './rpc_helpers.js';
|
|
34
|
+
import { is_unauthenticated_refusal, pick_auth_principal, round_trip_uses_fresh_account, to_principal_headers } from './integration_helpers.js';
|
|
24
35
|
/**
|
|
25
|
-
* Pick
|
|
26
|
-
*
|
|
27
|
-
* `
|
|
36
|
+
* Pick the principal matching an RPC method's auth requirement
|
|
37
|
+
* (`pick_auth_principal`, shared with the REST round-trip), and the headers
|
|
38
|
+
* carrying its credential. Accepts any `KeeperHeaderProvider` — both `TestApp`
|
|
39
|
+
* (in-process) and `TestFixture` (cross-backend) satisfy the shape
|
|
40
|
+
* structurally.
|
|
28
41
|
*/
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
export const pick_rpc_auth = (method, keeper, authed_account, admin_account) => {
|
|
43
|
+
const principal = pick_auth_principal(method.auth);
|
|
44
|
+
return {
|
|
45
|
+
principal,
|
|
46
|
+
headers: to_principal_headers(principal, keeper, authed_account, admin_account)
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Guard against a refusal that says the call carried no valid credential
|
|
51
|
+
* when it carried one (`is_unauthenticated_refusal`). The round-trip sends
|
|
52
|
+
* every non-public method a live credential its auth admits, so such a 401
|
|
53
|
+
* means the backend failed to authenticate it — most often because an earlier
|
|
54
|
+
* call destroyed it (a self-delete, a revoke-all), which would turn every
|
|
55
|
+
* later method's coverage into a vacuous refusal. A public method may still
|
|
56
|
+
* answer 401 (a login with a wrong password), and so may a handler refusing
|
|
57
|
+
* an authenticated call with a reason of its own (`invalid_credentials`).
|
|
58
|
+
*
|
|
59
|
+
* @param method - the RPC method name
|
|
60
|
+
* @param status - the HTTP status
|
|
61
|
+
* @param body - the parsed response body (or raw text when not JSON)
|
|
62
|
+
* @param principal - the principal the call was sent as
|
|
63
|
+
*/
|
|
64
|
+
export const assert_rpc_authenticated = (method, status, body, principal) => {
|
|
65
|
+
if (principal === 'public')
|
|
66
|
+
return;
|
|
67
|
+
const parsed = JsonrpcErrorResponse.safeParse(body);
|
|
68
|
+
const data = parsed.success ? parsed.data.error.data : undefined;
|
|
69
|
+
const reason = data !== null && typeof data === 'object' ? data.reason : undefined;
|
|
70
|
+
if (!is_unauthenticated_refusal(status, reason))
|
|
71
|
+
return;
|
|
72
|
+
const detail = parsed.success
|
|
73
|
+
? `code ${parsed.data.error.code}, message ${JSON.stringify(parsed.data.error.message)}${data === undefined ? '' : `, data ${JSON.stringify(data)}`}`
|
|
74
|
+
: `body ${typeof body === 'string' ? body.slice(0, 500) : JSON.stringify(body).slice(0, 500)}`;
|
|
75
|
+
assert.fail(`method '${method}' answered 401 to the ${principal} principal's credential (${detail})` +
|
|
76
|
+
' — the call carried a credential its auth admits, so the backend owed an' +
|
|
77
|
+
' authenticated answer; a 401 here means that credential stopped working');
|
|
44
78
|
};
|
|
45
79
|
/**
|
|
46
80
|
* Guard against silent parity gaps: a method enumerated from the local action
|
|
@@ -62,6 +96,76 @@ const assert_method_implemented = (method, body) => {
|
|
|
62
96
|
` returned method-not-found — backend is missing this method (parity gap)`);
|
|
63
97
|
}
|
|
64
98
|
};
|
|
99
|
+
/**
|
|
100
|
+
* Read a response body as JSON, falling back to the raw text — a crashed
|
|
101
|
+
* backend may answer with a non-JSON body (an HTML or plain-text 500), and
|
|
102
|
+
* the round-trip must report that response, not a JSON parse error with no
|
|
103
|
+
* method attached.
|
|
104
|
+
*/
|
|
105
|
+
const read_rpc_body = async (res) => {
|
|
106
|
+
const text = await res.text();
|
|
107
|
+
try {
|
|
108
|
+
return JSON.parse(text);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return text;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
/** The HTTP status an `internal_error` maps to, read off the shared status table. */
|
|
115
|
+
const INTERNAL_ERROR_HTTP_STATUS = jsonrpc_error_code_to_http_status(JSONRPC_INTERNAL_ERROR);
|
|
116
|
+
/**
|
|
117
|
+
* Guard against a backend that crashes on schema-valid input. A response is
|
|
118
|
+
* a crash when any of these holds:
|
|
119
|
+
*
|
|
120
|
+
* - its HTTP status is the one `internal_error` maps to (500) — what an
|
|
121
|
+
* uncaught throw and an unmapped error code both answer
|
|
122
|
+
* - its JSON-RPC code is `internal_error` (-32603)
|
|
123
|
+
* - its status is ≥500 and its body is not a well-formed JSON-RPC error
|
|
124
|
+
* envelope (an HTML or plain-text crash page)
|
|
125
|
+
*
|
|
126
|
+
* Any other ≥500 that carries a well-formed envelope with a declared code
|
|
127
|
+
* passes like a 4xx: `service_unavailable` (503), `timeout` (504), or a
|
|
128
|
+
* consumer's own code declared with `register_jsonrpc_error_code` (a 502).
|
|
129
|
+
* Those are server conditions a handler declares on purpose — a dependency
|
|
130
|
+
* the test environment doesn't provide — while an undeclared 500 or -32603
|
|
131
|
+
* is a handler that failed where it owed an answer.
|
|
132
|
+
*
|
|
133
|
+
* @param method - the RPC method name
|
|
134
|
+
* @param status - the HTTP status
|
|
135
|
+
* @param body - the parsed response body (or raw text when not JSON)
|
|
136
|
+
* @param expected - what the call owed: a refusal (the generic nil-id loop)
|
|
137
|
+
* or a success (a declared success fixture), for the failure message
|
|
138
|
+
*/
|
|
139
|
+
const assert_not_crash = (method, status, body, expected) => {
|
|
140
|
+
const parsed = JsonrpcErrorResponse.safeParse(body);
|
|
141
|
+
const code = parsed.success ? parsed.data.error.code : null;
|
|
142
|
+
const crashed = parsed.success
|
|
143
|
+
? status === INTERNAL_ERROR_HTTP_STATUS || code === JSONRPC_INTERNAL_ERROR
|
|
144
|
+
: status >= 500;
|
|
145
|
+
if (!crashed)
|
|
146
|
+
return;
|
|
147
|
+
const message = parsed.success
|
|
148
|
+
? parsed.data.error.message
|
|
149
|
+
: typeof body === 'string'
|
|
150
|
+
? body.slice(0, 500)
|
|
151
|
+
: JSON.stringify(body).slice(0, 500);
|
|
152
|
+
assert.fail(`method '${method}' crashed on ${expected === 'success' ? 'its success fixture' : 'schema-valid params'} (status ${status}, code ${code ?? 'none'}, message ${JSON.stringify(message)})` +
|
|
153
|
+
(expected === 'success'
|
|
154
|
+
? ' — the fixture built a real row, so the backend owed a success here'
|
|
155
|
+
: ' — the backend owes a declared refusal here (a 4xx, or a declared 5xx code)'));
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Assert a non-ok response is an acceptable refusal: the method exists, the
|
|
159
|
+
* failure is not a crash (`assert_not_crash`), an authenticated call was not
|
|
160
|
+
* refused as unauthenticated (`assert_rpc_authenticated`), and the body is a
|
|
161
|
+
* well-formed JSON-RPC error envelope.
|
|
162
|
+
*/
|
|
163
|
+
const assert_rpc_refusal = (method, status, body, principal) => {
|
|
164
|
+
assert_method_implemented(method, body);
|
|
165
|
+
assert_not_crash(method, status, body, 'refusal');
|
|
166
|
+
assert_rpc_authenticated(method, status, body, principal);
|
|
167
|
+
assert_jsonrpc_error_response(body);
|
|
168
|
+
};
|
|
65
169
|
/**
|
|
66
170
|
* Run schema-driven round-trip validation for RPC endpoints.
|
|
67
171
|
*
|
|
@@ -74,10 +178,15 @@ const assert_method_implemented = (method, body) => {
|
|
|
74
178
|
*
|
|
75
179
|
* Error responses (from missing DB state, etc.) are expected and validated
|
|
76
180
|
* as well-formed JSON-RPC errors. Successful responses are validated against
|
|
77
|
-
* `action.spec.output`.
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
181
|
+
* `action.spec.output`. Two error classes fail loud instead of passing as a
|
|
182
|
+
* valid envelope: `method not found` (-32601) means the backend is missing a
|
|
183
|
+
* method the local surface advertises (`assert_method_implemented`), and a
|
|
184
|
+
* crash — HTTP 500, `internal_error` (-32603), or a ≥500 with no JSON-RPC
|
|
185
|
+
* envelope — means the backend failed on schema-valid input
|
|
186
|
+
* (`assert_not_crash`). A declared ≥500 code (`service_unavailable`,
|
|
187
|
+
* `timeout`) passes as a refusal. A method the suite can't drive generically
|
|
188
|
+
* goes in `skip_methods`; one whose generated params can't reach its handler
|
|
189
|
+
* gets an `input_overrides` entry.
|
|
81
190
|
*/
|
|
82
191
|
export const describe_rpc_round_trip_tests = (options) => {
|
|
83
192
|
const skip_set = new Set(options.skip_methods);
|
|
@@ -116,18 +225,20 @@ export const describe_rpc_round_trip_tests = (options) => {
|
|
|
116
225
|
continue;
|
|
117
226
|
const override = options.input_overrides?.get(action.spec.method);
|
|
118
227
|
const params = override ?? generate_valid_body(action.spec.input) ?? null;
|
|
119
|
-
const
|
|
228
|
+
const picked = pick_rpc_auth(surface_method, fixture, authed_account, admin_account);
|
|
229
|
+
const { principal, headers } = round_trip_uses_fresh_account(picked.principal, action.spec.side_effects)
|
|
230
|
+
? pick_rpc_auth(surface_method, fixture, await fixture.create_account({ roles: [] }), admin_account)
|
|
231
|
+
: picked;
|
|
120
232
|
const init = create_rpc_post_init(action.spec.method, params);
|
|
121
233
|
Object.assign(init.headers, headers);
|
|
122
234
|
const res = await fixture.transport(ep_spec.path, init);
|
|
123
|
-
const body = await res
|
|
235
|
+
const body = await read_rpc_body(res);
|
|
124
236
|
try {
|
|
125
237
|
if (res.ok) {
|
|
126
238
|
assert_jsonrpc_success_response(body, action.spec.output);
|
|
127
239
|
}
|
|
128
240
|
else {
|
|
129
|
-
|
|
130
|
-
assert_jsonrpc_error_response(body);
|
|
241
|
+
assert_rpc_refusal(action.spec.method, res.status, body, principal);
|
|
131
242
|
}
|
|
132
243
|
}
|
|
133
244
|
catch (e) {
|
|
@@ -150,17 +261,16 @@ export const describe_rpc_round_trip_tests = (options) => {
|
|
|
150
261
|
continue;
|
|
151
262
|
const override = options.input_overrides?.get(action.spec.method);
|
|
152
263
|
const params = override ?? generate_valid_body(action.spec.input) ?? undefined;
|
|
153
|
-
const headers =
|
|
264
|
+
const { principal, headers } = pick_rpc_auth(surface_method, fixture, authed_account, admin_account);
|
|
154
265
|
const url = create_rpc_get_url(ep_spec.path, action.spec.method, params);
|
|
155
266
|
const res = await fixture.transport(url, { headers });
|
|
156
|
-
const body = await res
|
|
267
|
+
const body = await read_rpc_body(res);
|
|
157
268
|
try {
|
|
158
269
|
if (res.ok) {
|
|
159
270
|
assert_jsonrpc_success_response(body, action.spec.output);
|
|
160
271
|
}
|
|
161
272
|
else {
|
|
162
|
-
|
|
163
|
-
assert_jsonrpc_error_response(body);
|
|
273
|
+
assert_rpc_refusal(action.spec.method, res.status, body, principal);
|
|
164
274
|
}
|
|
165
275
|
}
|
|
166
276
|
catch (e) {
|
|
@@ -178,14 +288,16 @@ export const describe_rpc_round_trip_tests = (options) => {
|
|
|
178
288
|
assert.ok(located, `success_fixtures references unknown RPC method '${method}'`);
|
|
179
289
|
const surface = find_rpc_method(surface_rpc_endpoints, method);
|
|
180
290
|
assert.ok(surface, `success_fixtures method '${method}' missing from generated surface`);
|
|
181
|
-
const
|
|
182
|
-
const headers =
|
|
183
|
-
|
|
291
|
+
const fixture_case = await build(fixture);
|
|
292
|
+
const headers = fixture_case.headers ??
|
|
293
|
+
pick_rpc_auth(surface.method_spec, fixture, authed_account, admin_account).headers;
|
|
294
|
+
const init = create_rpc_post_init(method, fixture_case.params);
|
|
184
295
|
Object.assign(init.headers, headers);
|
|
185
296
|
const res = await fixture.transport(located.path, init);
|
|
186
|
-
const body = await res
|
|
297
|
+
const body = await read_rpc_body(res);
|
|
187
298
|
try {
|
|
188
299
|
assert_method_implemented(method, body);
|
|
300
|
+
assert_not_crash(method, res.status, body, 'success');
|
|
189
301
|
assert.ok(res.ok, `success fixture expected a success response, got status ${res.status}: ${JSON.stringify(body)}`);
|
|
190
302
|
assert_jsonrpc_success_response(body, located.action.spec.output);
|
|
191
303
|
}
|
|
@@ -11,12 +11,109 @@ import './assert_dev_env.js';
|
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import { type ZodFieldInfo } from '../zod.js';
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* The JSON Schema of a field's input side — where its format, pattern and
|
|
15
|
+
* bounds live — or `null` when JSON Schema can't render the field or any part
|
|
16
|
+
* of it (`z.date()`, `z.custom()`, a union with a `z.date()` branch).
|
|
17
|
+
*
|
|
18
|
+
* Rendered with `io: 'input'`, so a field carrying a `.transform()` or a pipe
|
|
19
|
+
* (`Username`) still yields the constraints its input is checked against;
|
|
20
|
+
* the default output side throws on a transform. A pipe yields its input
|
|
21
|
+
* side only, so constraints of the stage after it are not here. A
|
|
22
|
+
* `.nullable()` / `.nullish()` field renders as
|
|
23
|
+
* `anyOf: [{…}, {type: 'null'}]`; its one non-null branch is returned, so
|
|
24
|
+
* the bounds and pattern read the same as on the bare field. A union of two
|
|
25
|
+
* or more non-null branches returns the whole schema — its branches' bounds
|
|
26
|
+
* are no single field's bounds.
|
|
27
|
+
*
|
|
28
|
+
* A `.refine()` is never here: JSON Schema can't express one, so a bound a
|
|
29
|
+
* refinement enforces (a code-point length, a cross-field rule) generates no
|
|
30
|
+
* boundary case.
|
|
31
|
+
*
|
|
32
|
+
* @param field_schema - the field to read
|
|
33
|
+
* @returns the field's input-side JSON Schema, or `null` when it can't be rendered
|
|
34
|
+
*/
|
|
35
|
+
export declare const to_field_json_schema: (field_schema: z.ZodType) => Record<string, unknown> | null;
|
|
36
|
+
/**
|
|
37
|
+
* The format constraint a field's input-side JSON Schema carries: its
|
|
38
|
+
* `format` (e.g. `'uuid'`, `'email'`), `'pattern'` for a regex, or `null`.
|
|
39
|
+
* A union (`anyOf` of several non-null branches) answers its first branch
|
|
40
|
+
* carrying one — a value violating every branch is what the caller needs,
|
|
41
|
+
* and the generators check the field refuses the candidate.
|
|
42
|
+
*
|
|
43
|
+
* @param json - a field's JSON Schema, as `to_field_json_schema` returns it
|
|
44
|
+
* @returns the format, `'pattern'`, or `null`
|
|
45
|
+
*/
|
|
46
|
+
export declare const detect_json_schema_format: (json: Record<string, unknown>) => string | null;
|
|
47
|
+
/**
|
|
48
|
+
* Detect format constraints on a field from its input-side JSON Schema
|
|
49
|
+
* (`to_field_json_schema`). Returns the format string (e.g. `'uuid'`,
|
|
50
|
+
* `'email'`), `'pattern'` for a regex, or `null`.
|
|
16
51
|
*/
|
|
17
52
|
export declare const detect_format: (field_schema: z.ZodType) => string | null;
|
|
18
53
|
/** Generate a valid-ish value for a field based on its base type. */
|
|
19
54
|
export declare const generate_valid_value: (field: ZodFieldInfo, field_schema: z.ZodType) => unknown;
|
|
55
|
+
/**
|
|
56
|
+
* Generate a valid object for an object schema: its required and defaulted
|
|
57
|
+
* fields first; when `schema` still refuses it, each optional field alone on
|
|
58
|
+
* top of those, in declaration order, taking the first that parses; and
|
|
59
|
+
* failing that, the optional fields added one at a time, in declaration
|
|
60
|
+
* order, until it parses. The fill covers a `.refine()` over optional fields
|
|
61
|
+
* (at least one of, exactly one of, both of), which the required-only object
|
|
62
|
+
* can't satisfy, and the single-field pass keeps an unrelated optional field
|
|
63
|
+
* declared ahead of the refined ones (an `acting`, a note) out of the object.
|
|
64
|
+
*
|
|
65
|
+
* Shared by the top-level body generators and `generate_valid_value`'s
|
|
66
|
+
* nested-object case, so a refined object validates the same way at any depth.
|
|
67
|
+
*
|
|
68
|
+
* @param object_schema - the unwrapped object whose fields are generated
|
|
69
|
+
* @param schema - the schema the object must satisfy, refinements included
|
|
70
|
+
* (`object_schema` or a schema wrapping it)
|
|
71
|
+
* @returns the generated object and its last `safeParse` result — the caller
|
|
72
|
+
* decides whether a failure throws
|
|
73
|
+
*/
|
|
74
|
+
export declare const generate_valid_object: (object_schema: z.ZodObject, schema: z.ZodType) => {
|
|
75
|
+
value: Record<string, unknown>;
|
|
76
|
+
result: z.ZodSafeParseResult<unknown>;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* A valid object that carries `field`, built from `base`, a valid object of
|
|
80
|
+
* `object_schema` — the body a case breaking `field` changes, so the case
|
|
81
|
+
* breaks that field and nothing else. `base` itself when it carries the
|
|
82
|
+
* field. Otherwise the field takes a generated value and joins `base`, with
|
|
83
|
+
* the optional fields `base` omits filled as `generate_valid_object` fills
|
|
84
|
+
* them (a pair rule: adding `scope_kind` needs `scope_id`); failing that, it
|
|
85
|
+
* replaces `base`'s optional fields, refilled the same way around it (an
|
|
86
|
+
* exactly-one-of rule: adding `slug` means dropping `id`).
|
|
87
|
+
*
|
|
88
|
+
* @param object_schema - the unwrapped object `base` is an instance of
|
|
89
|
+
* @param schema - the schema the object must satisfy, refinements included
|
|
90
|
+
* @param base - a valid object, the generated or seeded base
|
|
91
|
+
* @param field - the field the object must carry
|
|
92
|
+
* @returns the object, or `null` when no object the generator can build
|
|
93
|
+
* carries the field and passes `schema`
|
|
94
|
+
*/
|
|
95
|
+
export declare const generate_valid_object_with_field: (object_schema: z.ZodObject, schema: z.ZodType, base: Record<string, unknown>, field: ZodFieldInfo) => Record<string, unknown> | null;
|
|
96
|
+
/**
|
|
97
|
+
* A string a URL-sourced field accepts — a route param or a query value, which
|
|
98
|
+
* arrive as strings whatever the schema parses them into. The nil UUID for a
|
|
99
|
+
* UUID field; else the first the field accepts of `test_value`, the generated
|
|
100
|
+
* valid value written as a string, `1`, `0`, `true` and `false`, the field's
|
|
101
|
+
* JSON Schema `default` or lower bound written as a string (a preprocessed
|
|
102
|
+
* integer whose minimum is above one), and a string synthesized from the
|
|
103
|
+
* field's constraints.
|
|
104
|
+
*
|
|
105
|
+
* @param field - the field's info, from `zod_extract_fields`
|
|
106
|
+
* @param field_schema - the field's schema
|
|
107
|
+
* @returns the string, or `null` when no candidate passes
|
|
108
|
+
*/
|
|
109
|
+
export declare const generate_valid_string_param: (field: ZodFieldInfo, field_schema: z.ZodType) => string | null;
|
|
110
|
+
/**
|
|
111
|
+
* Format Zod issues as `path: message` pairs for a generator's error message.
|
|
112
|
+
*
|
|
113
|
+
* @param error - the failed parse's error
|
|
114
|
+
* @returns the issues, comma-separated
|
|
115
|
+
*/
|
|
116
|
+
export declare const format_zod_issues: (error: z.ZodError) => string;
|
|
20
117
|
/**
|
|
21
118
|
* The `Content-Type` a well-formed request to a route sends: `application/json`,
|
|
22
119
|
* or `application/octet-stream` for a `raw_body` route. Every `POST` route
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema_generators.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/schema_generators.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,WAAW,CAAC;AAInB
|
|
1
|
+
{"version":3,"file":"schema_generators.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/schema_generators.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,WAAW,CAAC;AAInB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,oBAAoB,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAcxF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,GAAI,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,GAAG,IAWlF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAGhE,CAAC;AAqHF,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,OAAO,KAAG,OAkGnF,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,GACjC,eAAe,CAAC,CAAC,SAAS,EAC1B,QAAQ,CAAC,CAAC,OAAO,KACf;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAA;CASzE,CAAC;AAsCF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gCAAgC,GAC5C,eAAe,CAAC,CAAC,SAAS,EAC1B,QAAQ,CAAC,CAAC,OAAO,EACjB,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,YAAY,KACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IA0B5B,CAAC;AAIF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,2BAA2B,GACvC,OAAO,YAAY,EACnB,cAAc,CAAC,CAAC,OAAO,KACrB,MAAM,GAAG,IA6BX,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,CAAC,CAAC,QAAQ,KAAG,MACkB,CAAC;AAEzE;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,KAAG,MACL,CAAC;AAElE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,gBAAgB,CAAC,CAAC,SAAS,KAAG,MAiB9E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAC/B,cAAc,CAAC,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAY5B,CAAC"}
|