@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
|
@@ -12,34 +12,78 @@ import { z } from 'zod';
|
|
|
12
12
|
import { zod_unwrap_def, zod_get_base_type, zod_unwrap_to_object, zod_extract_fields } from '../zod.js';
|
|
13
13
|
import { is_null_schema } from '../http/schema_helpers.js';
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* The JSON Schema of a field's input side — where its format, pattern and
|
|
16
|
+
* bounds live — or `null` when JSON Schema can't render the field or any part
|
|
17
|
+
* of it (`z.date()`, `z.custom()`, a union with a `z.date()` branch).
|
|
18
|
+
*
|
|
19
|
+
* Rendered with `io: 'input'`, so a field carrying a `.transform()` or a pipe
|
|
20
|
+
* (`Username`) still yields the constraints its input is checked against;
|
|
21
|
+
* the default output side throws on a transform. A pipe yields its input
|
|
22
|
+
* side only, so constraints of the stage after it are not here. A
|
|
23
|
+
* `.nullable()` / `.nullish()` field renders as
|
|
24
|
+
* `anyOf: [{…}, {type: 'null'}]`; its one non-null branch is returned, so
|
|
25
|
+
* the bounds and pattern read the same as on the bare field. A union of two
|
|
26
|
+
* or more non-null branches returns the whole schema — its branches' bounds
|
|
27
|
+
* are no single field's bounds.
|
|
28
|
+
*
|
|
29
|
+
* A `.refine()` is never here: JSON Schema can't express one, so a bound a
|
|
30
|
+
* refinement enforces (a code-point length, a cross-field rule) generates no
|
|
31
|
+
* boundary case.
|
|
32
|
+
*
|
|
33
|
+
* @param field_schema - the field to read
|
|
34
|
+
* @returns the field's input-side JSON Schema, or `null` when it can't be rendered
|
|
17
35
|
*/
|
|
18
|
-
export const
|
|
36
|
+
export const to_field_json_schema = (field_schema) => {
|
|
37
|
+
let json;
|
|
19
38
|
try {
|
|
20
|
-
|
|
21
|
-
if (typeof json.format === 'string')
|
|
22
|
-
return json.format;
|
|
23
|
-
if (typeof json.pattern === 'string')
|
|
24
|
-
return 'pattern';
|
|
25
|
-
// `.nullish()` / `.nullable()` produce `anyOf: [{format, …}, {type: 'null'}]`
|
|
26
|
-
// — descend into the first non-null branch so format/pattern surface.
|
|
27
|
-
if (Array.isArray(json.anyOf)) {
|
|
28
|
-
for (const branch of json.anyOf) {
|
|
29
|
-
if (branch.type === 'null')
|
|
30
|
-
continue;
|
|
31
|
-
if (typeof branch.format === 'string')
|
|
32
|
-
return branch.format;
|
|
33
|
-
if (typeof branch.pattern === 'string')
|
|
34
|
-
return 'pattern';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
39
|
+
json = z.toJSONSchema(field_schema, { io: 'input' });
|
|
37
40
|
}
|
|
38
41
|
catch {
|
|
39
|
-
//
|
|
42
|
+
return null; // a type JSON Schema can't represent
|
|
43
|
+
}
|
|
44
|
+
if (Array.isArray(json.anyOf)) {
|
|
45
|
+
const branches = json.anyOf.filter((branch) => branch.type !== 'null');
|
|
46
|
+
if (branches.length === 1)
|
|
47
|
+
return branches[0];
|
|
48
|
+
}
|
|
49
|
+
return json;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* The format constraint a field's input-side JSON Schema carries: its
|
|
53
|
+
* `format` (e.g. `'uuid'`, `'email'`), `'pattern'` for a regex, or `null`.
|
|
54
|
+
* A union (`anyOf` of several non-null branches) answers its first branch
|
|
55
|
+
* carrying one — a value violating every branch is what the caller needs,
|
|
56
|
+
* and the generators check the field refuses the candidate.
|
|
57
|
+
*
|
|
58
|
+
* @param json - a field's JSON Schema, as `to_field_json_schema` returns it
|
|
59
|
+
* @returns the format, `'pattern'`, or `null`
|
|
60
|
+
*/
|
|
61
|
+
export const detect_json_schema_format = (json) => {
|
|
62
|
+
if (typeof json.format === 'string')
|
|
63
|
+
return json.format;
|
|
64
|
+
if (typeof json.pattern === 'string')
|
|
65
|
+
return 'pattern';
|
|
66
|
+
if (Array.isArray(json.anyOf)) {
|
|
67
|
+
for (const branch of json.anyOf) {
|
|
68
|
+
if (branch.type === 'null')
|
|
69
|
+
continue;
|
|
70
|
+
if (typeof branch.format === 'string')
|
|
71
|
+
return branch.format;
|
|
72
|
+
if (typeof branch.pattern === 'string')
|
|
73
|
+
return 'pattern';
|
|
74
|
+
}
|
|
40
75
|
}
|
|
41
76
|
return null;
|
|
42
77
|
};
|
|
78
|
+
/**
|
|
79
|
+
* Detect format constraints on a field from its input-side JSON Schema
|
|
80
|
+
* (`to_field_json_schema`). Returns the format string (e.g. `'uuid'`,
|
|
81
|
+
* `'email'`), `'pattern'` for a regex, or `null`.
|
|
82
|
+
*/
|
|
83
|
+
export const detect_format = (field_schema) => {
|
|
84
|
+
const json = to_field_json_schema(field_schema);
|
|
85
|
+
return json && detect_json_schema_format(json);
|
|
86
|
+
};
|
|
43
87
|
/**
|
|
44
88
|
* Extract a candidate value from a JSON Schema `pattern` when the shape is a
|
|
45
89
|
* fixed-length hex character class, optionally behind a literal prefix —
|
|
@@ -110,8 +154,8 @@ const generate_valid_string = (field_schema) => {
|
|
|
110
154
|
let min_length = 0;
|
|
111
155
|
let max_length = Infinity;
|
|
112
156
|
let pattern = null;
|
|
113
|
-
|
|
114
|
-
|
|
157
|
+
const json = to_field_json_schema(field_schema);
|
|
158
|
+
if (json) {
|
|
115
159
|
if (typeof json.minLength === 'number')
|
|
116
160
|
min_length = json.minLength;
|
|
117
161
|
if (typeof json.maxLength === 'number')
|
|
@@ -119,9 +163,6 @@ const generate_valid_string = (field_schema) => {
|
|
|
119
163
|
if (typeof json.pattern === 'string')
|
|
120
164
|
pattern = json.pattern;
|
|
121
165
|
}
|
|
122
|
-
catch {
|
|
123
|
-
// no constraints
|
|
124
|
-
}
|
|
125
166
|
const target = Math.max(min_length, Math.min(10, max_length));
|
|
126
167
|
const base = 'x'.repeat(target) || 'test_value';
|
|
127
168
|
// Validate against the full schema (including refinements/brands).
|
|
@@ -155,6 +196,10 @@ const generate_valid_string = (field_schema) => {
|
|
|
155
196
|
const as_url = 'https://example.com/' + base;
|
|
156
197
|
if (field_schema.safeParse(as_url).success)
|
|
157
198
|
return as_url;
|
|
199
|
+
// Two-segment path refinement (an `owner/name` repo slug)
|
|
200
|
+
const segments = `${base}/${base}`;
|
|
201
|
+
if (field_schema.safeParse(segments).success)
|
|
202
|
+
return segments;
|
|
158
203
|
return base; // fall through — generate_valid_body will report the failure
|
|
159
204
|
};
|
|
160
205
|
/** Generate a valid-ish value for a field based on its base type. */
|
|
@@ -174,20 +219,30 @@ export const generate_valid_value = (field, field_schema) => {
|
|
|
174
219
|
return '2020-01-01T00:00:00.000Z';
|
|
175
220
|
return generate_valid_string(field_schema);
|
|
176
221
|
case 'number':
|
|
177
|
-
case 'int':
|
|
178
|
-
|
|
222
|
+
case 'int': {
|
|
223
|
+
// 1, unless the schema's bounds rule it out (`.negative()`, `.min(10)`)
|
|
224
|
+
for (const candidate of [1, -1, 0]) {
|
|
225
|
+
if (field_schema.safeParse(candidate).success)
|
|
226
|
+
return candidate;
|
|
227
|
+
}
|
|
228
|
+
const json = to_field_json_schema(field_schema);
|
|
229
|
+
if (json) {
|
|
230
|
+
if (typeof json.minimum === 'number')
|
|
231
|
+
return Math.ceil(json.minimum);
|
|
232
|
+
if (typeof json.exclusiveMinimum === 'number')
|
|
233
|
+
return Math.floor(json.exclusiveMinimum) + 1;
|
|
234
|
+
if (typeof json.maximum === 'number')
|
|
235
|
+
return Math.floor(json.maximum);
|
|
236
|
+
if (typeof json.exclusiveMaximum === 'number')
|
|
237
|
+
return Math.ceil(json.exclusiveMaximum) - 1;
|
|
238
|
+
}
|
|
239
|
+
return 1; // fall through — generate_valid_body will report the failure
|
|
240
|
+
}
|
|
179
241
|
case 'boolean':
|
|
180
242
|
return true;
|
|
181
243
|
case 'array': {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const json = z.toJSONSchema(field_schema);
|
|
185
|
-
if (typeof json.minItems === 'number')
|
|
186
|
-
min_items = json.minItems;
|
|
187
|
-
}
|
|
188
|
-
catch {
|
|
189
|
-
// no constraint
|
|
190
|
-
}
|
|
244
|
+
const json = to_field_json_schema(field_schema);
|
|
245
|
+
const min_items = typeof json?.minItems === 'number' ? json.minItems : 0;
|
|
191
246
|
if (min_items === 0)
|
|
192
247
|
return [];
|
|
193
248
|
const def = zod_unwrap_def(field_schema);
|
|
@@ -202,18 +257,13 @@ export const generate_valid_value = (field, field_schema) => {
|
|
|
202
257
|
return Array.from({ length: min_items }, () => item);
|
|
203
258
|
}
|
|
204
259
|
case 'object': {
|
|
205
|
-
//
|
|
260
|
+
// recurse with the same optional-field fallback as the top level, so a
|
|
261
|
+
// nested `.refine()` over optional fields (exactly-one-of) is satisfied;
|
|
262
|
+
// a nested object that still fails is returned as built, and the
|
|
263
|
+
// top-level parse reports it
|
|
206
264
|
const nested_schema = zod_unwrap_to_object(field_schema);
|
|
207
|
-
if (nested_schema)
|
|
208
|
-
|
|
209
|
-
const nested = {};
|
|
210
|
-
for (const nf of nested_fields) {
|
|
211
|
-
if (!nf.required && !nf.has_default)
|
|
212
|
-
continue;
|
|
213
|
-
nested[nf.name] = generate_valid_value(nf, nested_schema.shape[nf.name]);
|
|
214
|
-
}
|
|
215
|
-
return nested;
|
|
216
|
-
}
|
|
265
|
+
if (nested_schema)
|
|
266
|
+
return generate_valid_object(nested_schema, field_schema).value;
|
|
217
267
|
return {};
|
|
218
268
|
}
|
|
219
269
|
case 'null':
|
|
@@ -264,6 +314,166 @@ export const generate_valid_value = (field, field_schema) => {
|
|
|
264
314
|
return 'test_value';
|
|
265
315
|
}
|
|
266
316
|
};
|
|
317
|
+
/**
|
|
318
|
+
* Generate a valid object for an object schema: its required and defaulted
|
|
319
|
+
* fields first; when `schema` still refuses it, each optional field alone on
|
|
320
|
+
* top of those, in declaration order, taking the first that parses; and
|
|
321
|
+
* failing that, the optional fields added one at a time, in declaration
|
|
322
|
+
* order, until it parses. The fill covers a `.refine()` over optional fields
|
|
323
|
+
* (at least one of, exactly one of, both of), which the required-only object
|
|
324
|
+
* can't satisfy, and the single-field pass keeps an unrelated optional field
|
|
325
|
+
* declared ahead of the refined ones (an `acting`, a note) out of the object.
|
|
326
|
+
*
|
|
327
|
+
* Shared by the top-level body generators and `generate_valid_value`'s
|
|
328
|
+
* nested-object case, so a refined object validates the same way at any depth.
|
|
329
|
+
*
|
|
330
|
+
* @param object_schema - the unwrapped object whose fields are generated
|
|
331
|
+
* @param schema - the schema the object must satisfy, refinements included
|
|
332
|
+
* (`object_schema` or a schema wrapping it)
|
|
333
|
+
* @returns the generated object and its last `safeParse` result — the caller
|
|
334
|
+
* decides whether a failure throws
|
|
335
|
+
*/
|
|
336
|
+
export const generate_valid_object = (object_schema, schema) => {
|
|
337
|
+
const base = {};
|
|
338
|
+
const optional = [];
|
|
339
|
+
for (const field of zod_extract_fields(object_schema)) {
|
|
340
|
+
const value = generate_valid_value(field, object_schema.shape[field.name]);
|
|
341
|
+
if (is_optional_field(field))
|
|
342
|
+
optional.push([field.name, value]);
|
|
343
|
+
else
|
|
344
|
+
base[field.name] = value;
|
|
345
|
+
}
|
|
346
|
+
return fill_optional_fields(schema, base, optional);
|
|
347
|
+
};
|
|
348
|
+
/** A field the object may omit — optional and without a default Zod fills. */
|
|
349
|
+
const is_optional_field = (field) => !field.required && !field.has_default;
|
|
350
|
+
/**
|
|
351
|
+
* `start` as is when `schema` accepts it; else `start` plus each candidate
|
|
352
|
+
* alone, in order, taking the first that parses; else the candidates added
|
|
353
|
+
* one at a time, in order, until it parses.
|
|
354
|
+
*
|
|
355
|
+
* @param schema - the schema the object must satisfy
|
|
356
|
+
* @param start - the fields every result keeps
|
|
357
|
+
* @param candidates - optional fields and their values, in declaration order
|
|
358
|
+
* @returns the object and its last `safeParse` result
|
|
359
|
+
*/
|
|
360
|
+
const fill_optional_fields = (schema, start, candidates) => {
|
|
361
|
+
let result = schema.safeParse(start);
|
|
362
|
+
if (result.success)
|
|
363
|
+
return { value: start, result };
|
|
364
|
+
// each optional field alone, so one the refinement doesn't need stays out
|
|
365
|
+
for (const [name, field_value] of candidates) {
|
|
366
|
+
const value = { ...start, [name]: field_value };
|
|
367
|
+
const single_result = schema.safeParse(value);
|
|
368
|
+
if (single_result.success)
|
|
369
|
+
return { value, result: single_result };
|
|
370
|
+
}
|
|
371
|
+
// then cumulatively, for a refinement needing several
|
|
372
|
+
const value = { ...start };
|
|
373
|
+
for (const [name, field_value] of candidates) {
|
|
374
|
+
value[name] = field_value;
|
|
375
|
+
result = schema.safeParse(value);
|
|
376
|
+
if (result.success)
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
return { value, result };
|
|
380
|
+
};
|
|
381
|
+
/**
|
|
382
|
+
* A valid object that carries `field`, built from `base`, a valid object of
|
|
383
|
+
* `object_schema` — the body a case breaking `field` changes, so the case
|
|
384
|
+
* breaks that field and nothing else. `base` itself when it carries the
|
|
385
|
+
* field. Otherwise the field takes a generated value and joins `base`, with
|
|
386
|
+
* the optional fields `base` omits filled as `generate_valid_object` fills
|
|
387
|
+
* them (a pair rule: adding `scope_kind` needs `scope_id`); failing that, it
|
|
388
|
+
* replaces `base`'s optional fields, refilled the same way around it (an
|
|
389
|
+
* exactly-one-of rule: adding `slug` means dropping `id`).
|
|
390
|
+
*
|
|
391
|
+
* @param object_schema - the unwrapped object `base` is an instance of
|
|
392
|
+
* @param schema - the schema the object must satisfy, refinements included
|
|
393
|
+
* @param base - a valid object, the generated or seeded base
|
|
394
|
+
* @param field - the field the object must carry
|
|
395
|
+
* @returns the object, or `null` when no object the generator can build
|
|
396
|
+
* carries the field and passes `schema`
|
|
397
|
+
*/
|
|
398
|
+
export const generate_valid_object_with_field = (object_schema, schema, base, field) => {
|
|
399
|
+
if (Object.hasOwn(base, field.name))
|
|
400
|
+
return base;
|
|
401
|
+
const fields = zod_extract_fields(object_schema);
|
|
402
|
+
const value_of = (f) => Object.hasOwn(base, f.name)
|
|
403
|
+
? base[f.name]
|
|
404
|
+
: generate_valid_value(f, object_schema.shape[f.name]);
|
|
405
|
+
const field_value = value_of(field);
|
|
406
|
+
// the field joins the base, which keeps its optional fields
|
|
407
|
+
const absent = fields
|
|
408
|
+
.filter((f) => f.name !== field.name && is_optional_field(f) && !Object.hasOwn(base, f.name))
|
|
409
|
+
.map((f) => [f.name, value_of(f)]);
|
|
410
|
+
const joined = fill_optional_fields(schema, { ...base, [field.name]: field_value }, absent);
|
|
411
|
+
if (joined.result.success)
|
|
412
|
+
return joined.value;
|
|
413
|
+
// the field in place of the base's optional fields, which are refilled around it
|
|
414
|
+
const optional_names = new Set(fields.filter(is_optional_field).map((f) => f.name));
|
|
415
|
+
const core = {};
|
|
416
|
+
for (const [k, v] of Object.entries(base)) {
|
|
417
|
+
if (!optional_names.has(k))
|
|
418
|
+
core[k] = v;
|
|
419
|
+
}
|
|
420
|
+
core[field.name] = field_value;
|
|
421
|
+
const others = fields
|
|
422
|
+
.filter((f) => f.name !== field.name && is_optional_field(f))
|
|
423
|
+
.map((f) => [f.name, value_of(f)]);
|
|
424
|
+
const replaced = fill_optional_fields(schema, core, others);
|
|
425
|
+
return replaced.result.success ? replaced.value : null;
|
|
426
|
+
};
|
|
427
|
+
const NIL_UUID = '00000000-0000-0000-0000-000000000000';
|
|
428
|
+
/**
|
|
429
|
+
* A string a URL-sourced field accepts — a route param or a query value, which
|
|
430
|
+
* arrive as strings whatever the schema parses them into. The nil UUID for a
|
|
431
|
+
* UUID field; else the first the field accepts of `test_value`, the generated
|
|
432
|
+
* valid value written as a string, `1`, `0`, `true` and `false`, the field's
|
|
433
|
+
* JSON Schema `default` or lower bound written as a string (a preprocessed
|
|
434
|
+
* integer whose minimum is above one), and a string synthesized from the
|
|
435
|
+
* field's constraints.
|
|
436
|
+
*
|
|
437
|
+
* @param field - the field's info, from `zod_extract_fields`
|
|
438
|
+
* @param field_schema - the field's schema
|
|
439
|
+
* @returns the string, or `null` when no candidate passes
|
|
440
|
+
*/
|
|
441
|
+
export const generate_valid_string_param = (field, field_schema) => {
|
|
442
|
+
const candidates = [];
|
|
443
|
+
if (field.base_type === 'uuid' || detect_format(field_schema) === 'uuid') {
|
|
444
|
+
candidates.push(NIL_UUID);
|
|
445
|
+
}
|
|
446
|
+
candidates.push('test_value');
|
|
447
|
+
const generated = generate_valid_value(field, field_schema);
|
|
448
|
+
if (typeof generated === 'string' ||
|
|
449
|
+
typeof generated === 'number' ||
|
|
450
|
+
typeof generated === 'boolean') {
|
|
451
|
+
candidates.push(String(generated));
|
|
452
|
+
}
|
|
453
|
+
candidates.push('1', '0', 'true', 'false');
|
|
454
|
+
// a number the URL string is preprocessed into: its default or its lower bound
|
|
455
|
+
const json = to_field_json_schema(field_schema);
|
|
456
|
+
if (json) {
|
|
457
|
+
const fallback = json.default;
|
|
458
|
+
if (typeof fallback === 'number' || typeof fallback === 'string') {
|
|
459
|
+
candidates.push(String(fallback));
|
|
460
|
+
}
|
|
461
|
+
if (typeof json.minimum === 'number')
|
|
462
|
+
candidates.push(String(Math.ceil(json.minimum)));
|
|
463
|
+
if (typeof json.exclusiveMinimum === 'number') {
|
|
464
|
+
candidates.push(String(Math.floor(json.exclusiveMinimum) + 1));
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
candidates.push(generate_valid_string(field_schema));
|
|
468
|
+
return candidates.find((c) => field_schema.safeParse(c).success) ?? null;
|
|
469
|
+
};
|
|
470
|
+
/**
|
|
471
|
+
* Format Zod issues as `path: message` pairs for a generator's error message.
|
|
472
|
+
*
|
|
473
|
+
* @param error - the failed parse's error
|
|
474
|
+
* @returns the issues, comma-separated
|
|
475
|
+
*/
|
|
476
|
+
export const format_zod_issues = (error) => error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join(', ');
|
|
267
477
|
/**
|
|
268
478
|
* The `Content-Type` a well-formed request to a route sends: `application/json`,
|
|
269
479
|
* or `application/octet-stream` for a `raw_body` route. Every `POST` route
|
|
@@ -331,32 +541,10 @@ export const generate_valid_body = (input_schema) => {
|
|
|
331
541
|
const object_schema = zod_unwrap_to_object(input_schema);
|
|
332
542
|
if (!object_schema)
|
|
333
543
|
return undefined;
|
|
334
|
-
const
|
|
335
|
-
const body = {};
|
|
336
|
-
for (const field of fields) {
|
|
337
|
-
if (!field.required && !field.has_default)
|
|
338
|
-
continue;
|
|
339
|
-
body[field.name] = generate_valid_value(field, object_schema.shape[field.name]);
|
|
340
|
-
}
|
|
341
|
-
let result = input_schema.safeParse(body);
|
|
342
|
-
if (!result.success) {
|
|
343
|
-
// Fallback for schemas with a top-level `.refine()` that requires at
|
|
344
|
-
// least one of N optional fields. Fill optional fields until the body
|
|
345
|
-
// satisfies validation.
|
|
346
|
-
for (const field of fields) {
|
|
347
|
-
if (field.required || field.has_default || field.name in body)
|
|
348
|
-
continue;
|
|
349
|
-
body[field.name] = generate_valid_value(field, object_schema.shape[field.name]);
|
|
350
|
-
result = input_schema.safeParse(body);
|
|
351
|
-
if (result.success)
|
|
352
|
-
break;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
544
|
+
const { value, result } = generate_valid_object(object_schema, input_schema);
|
|
355
545
|
if (!result.success) {
|
|
356
546
|
throw new Error(`generate_valid_body: generated body fails validation — ` +
|
|
357
|
-
`fix generate_valid_value for: ${result.error
|
|
358
|
-
.map((i) => `${i.path.join('.')}: ${i.message}`)
|
|
359
|
-
.join(', ')}`);
|
|
547
|
+
`fix generate_valid_value for: ${format_zod_issues(result.error)}`);
|
|
360
548
|
}
|
|
361
|
-
return
|
|
549
|
+
return value;
|
|
362
550
|
};
|
|
@@ -21,6 +21,7 @@ import type { RoleSchemaResult } from '../auth/role_schema.js';
|
|
|
21
21
|
import type { BootstrapServerOptions } from '../server/app_server.js';
|
|
22
22
|
import type { AppServerContext } from '../server/app_server_context.js';
|
|
23
23
|
import type { RouteSpec } from '../http/route_spec.js';
|
|
24
|
+
import { type RpcSuccessFixtures } from './rpc_round_trip.js';
|
|
24
25
|
import type { RpcEndpointsSuiteOption } from './rpc_helpers.js';
|
|
25
26
|
import type { BackendCapabilities } from './cross_backend/capabilities.js';
|
|
26
27
|
import type { SetupTest } from './cross_backend/setup.js';
|
|
@@ -85,6 +86,31 @@ export interface StandardTestOptions {
|
|
|
85
86
|
error_coverage_min?: number;
|
|
86
87
|
/** Override the bootstrap-success suite's synthetic token. */
|
|
87
88
|
bootstrap_token?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Forwarded to `describe_rpc_round_trip_tests` as `success_fixtures`
|
|
91
|
+
* (method name → async params factory) — drives a populated **success**
|
|
92
|
+
* body for methods that act on an existing row, validated against the
|
|
93
|
+
* method's `output` schema. `create_spine_rpc_success_fixtures`
|
|
94
|
+
* (`cross_backend/rpc_success_fixtures.ts`) builds the map for the
|
|
95
|
+
* standard spine methods. See `RpcRoundTripTestOptions.success_fixtures`.
|
|
96
|
+
*/
|
|
97
|
+
rpc_success_fixtures?: RpcSuccessFixtures;
|
|
98
|
+
/**
|
|
99
|
+
* Forwarded to `describe_rpc_round_trip_tests` as `skip_methods` — the
|
|
100
|
+
* consumer escape hatch for a method the generic round-trip can't drive at
|
|
101
|
+
* all (a handler whose test wiring stubs out the deps it reaches, or reads
|
|
102
|
+
* tables the suite's database doesn't migrate). Each entry hides the
|
|
103
|
+
* method from both the crash check and the envelope check, so name the
|
|
104
|
+
* reason beside it.
|
|
105
|
+
*/
|
|
106
|
+
rpc_skip_methods?: Array<string>;
|
|
107
|
+
/**
|
|
108
|
+
* Forwarded to `describe_rpc_round_trip_tests` as `input_overrides`
|
|
109
|
+
* (method name → params) — for a method whose generated params can't
|
|
110
|
+
* reach its handler cleanly. The response is held to the same rules as a
|
|
111
|
+
* generated one.
|
|
112
|
+
*/
|
|
113
|
+
rpc_input_overrides?: Map<string, Record<string, unknown>>;
|
|
88
114
|
}
|
|
89
115
|
/**
|
|
90
116
|
* Run the full standard test bundle — integration, admin (when `roles`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/standard.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"standard.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/standard.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKvD,OAAO,EAAiC,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAI7F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,2CAA2C;IAC3C,UAAU,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;OAIG;IACH,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;OAKG;IACH,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE;;;;;OAKG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,sEAAsE;IACtE,yBAAyB,CAAC,EAAE,eAAe,CAAC;IAC5C;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC3D;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,SAAS,mBAAmB,KAAG,IAyDtE,CAAC"}
|
package/dist/testing/standard.js
CHANGED
|
@@ -30,7 +30,10 @@ export const describe_standard_tests = (options) => {
|
|
|
30
30
|
setup_test: options.setup_test,
|
|
31
31
|
surface_source: options.surface_source,
|
|
32
32
|
session_options: options.session_options,
|
|
33
|
-
rpc_endpoints: options.rpc_endpoints
|
|
33
|
+
rpc_endpoints: options.rpc_endpoints,
|
|
34
|
+
skip_methods: options.rpc_skip_methods,
|
|
35
|
+
input_overrides: options.rpc_input_overrides,
|
|
36
|
+
success_fixtures: options.rpc_success_fixtures
|
|
34
37
|
});
|
|
35
38
|
describe_data_exposure_tests({
|
|
36
39
|
setup_test: options.setup_test,
|
package/dist/testing/stubs.d.ts
CHANGED
|
@@ -64,9 +64,10 @@ export declare const stub_mw: (_c: any, next: any) => Promise<void>;
|
|
|
64
64
|
* wires a listener fails loudly instead of silently never firing
|
|
65
65
|
* (`create_recording_audit_emitter` accepts listeners); `listener_count`
|
|
66
66
|
* returns 0; `drain_inflight` resolves immediately, since nothing is ever
|
|
67
|
-
* written
|
|
68
|
-
* fan-out) build a real emitter
|
|
69
|
-
*
|
|
67
|
+
* written, and `is_tracking_inflight` answers `false`. Tests asserting on
|
|
68
|
+
* real audit-row persistence (or on listener fan-out) build a real emitter
|
|
69
|
+
* via `create_audit_emitter` against a stub or real DB — `create_test_app`
|
|
70
|
+
* already does this on the test backend.
|
|
70
71
|
*/
|
|
71
72
|
export declare const create_test_audit_emitter: () => AuditEmitter;
|
|
72
73
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stubs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/stubs.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAa7B,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAErF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAI3E,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAA+B,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAc9F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,GAAG,GAAG,EAAE,OAAO,MAAM,KAAG,CAqBtD,CAAC;AAET;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,GAAG,GAAG,EAAE,QAAQ,MAAM,EAAE,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,CAOxF,CAAC;AAET,iEAAiE;AACjE,eAAO,MAAM,IAAI,EAAE,GAAkC,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,QAAO,EAI/B,CAAC;AAEJ,gDAAgD;AAChD,eAAO,MAAM,YAAY,QAAO,QAAgC,CAAC;AAEjE,2CAA2C;AAC3C,eAAO,MAAM,OAAO,GAAU,IAAI,GAAG,EAAE,MAAM,GAAG,KAAG,OAAO,CAAC,IAAI,CAAW,CAAC;AAI3E
|
|
1
|
+
{"version":3,"file":"stubs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/stubs.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAa7B,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAErF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAI3E,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAA+B,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAc9F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,GAAG,GAAG,EAAE,OAAO,MAAM,KAAG,CAqBtD,CAAC;AAET;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,GAAG,GAAG,EAAE,QAAQ,MAAM,EAAE,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,CAOxF,CAAC;AAET,iEAAiE;AACjE,eAAO,MAAM,IAAI,EAAE,GAAkC,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,QAAO,EAI/B,CAAC;AAEJ,gDAAgD;AAChD,eAAO,MAAM,YAAY,QAAO,QAAgC,CAAC;AAEjE,2CAA2C;AAC3C,eAAO,MAAM,OAAO,GAAU,IAAI,GAAG,EAAE,MAAM,GAAG,KAAG,OAAO,CAAC,IAAI,CAAW,CAAC;AAI3E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,QAAO,YAa3C,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,QAAO,WAUxC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAO,OAWtC,CAAC;AAEH,6CAA6C;AAC7C,MAAM,WAAW,2BAA2B;IAC3C,oEAAoE;IACpE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAAI,UAAU,2BAA2B,KAAG,UAM9E,CAAC;AAKH;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,GAAI,UAAU;IACpD,iDAAiD;IACjD,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACtD,KAAG,KAAK,CAAC,cAAc,CA6BvB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,GAC1C,iBAAiB,cAAc,CAAC,MAAM,CAAC,KACrC,gBAgBF,CAAC;AAEF,kDAAkD;AAClD,MAAM,WAAW,+BAA+B;IAC/C,6DAA6D;IAC7D,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,qFAAqF;IACrF,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,oEAAoE;IACpE,UAAU,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACzB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAC7F;;;;;;;;OAQG;IACH,YAAY,CAAC,EACZ,aAAa,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,gBAAgB,KAAK,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC;IAC5F;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,KAAK,CAAC,cAAc,CAAC,CAAC;IAC/E;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAC9C;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAoBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,4BAA4B,GACxC,SAAS,+BAA+B,KACtC,cAoGF,CAAC"}
|
package/dist/testing/stubs.js
CHANGED
|
@@ -102,9 +102,10 @@ const stub_db = create_noop_stub('stub_db');
|
|
|
102
102
|
* wires a listener fails loudly instead of silently never firing
|
|
103
103
|
* (`create_recording_audit_emitter` accepts listeners); `listener_count`
|
|
104
104
|
* returns 0; `drain_inflight` resolves immediately, since nothing is ever
|
|
105
|
-
* written
|
|
106
|
-
* fan-out) build a real emitter
|
|
107
|
-
*
|
|
105
|
+
* written, and `is_tracking_inflight` answers `false`. Tests asserting on
|
|
106
|
+
* real audit-row persistence (or on listener fan-out) build a real emitter
|
|
107
|
+
* via `create_audit_emitter` against a stub or real DB — `create_test_app`
|
|
108
|
+
* already does this on the test backend.
|
|
108
109
|
*/
|
|
109
110
|
export const create_test_audit_emitter = () => ({
|
|
110
111
|
emit: () => { },
|
|
@@ -115,7 +116,8 @@ export const create_test_audit_emitter = () => ({
|
|
|
115
116
|
throw new Error('create_test_audit_emitter accepts no listeners — use create_recording_audit_emitter');
|
|
116
117
|
},
|
|
117
118
|
listener_count: () => 0,
|
|
118
|
-
drain_inflight: async () => { }
|
|
119
|
+
drain_inflight: async () => { },
|
|
120
|
+
is_tracking_inflight: () => false
|
|
119
121
|
});
|
|
120
122
|
/**
|
|
121
123
|
* Build a no-op `AuditLogSse` for tests that wire `audit_sse` into the
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import '../assert_dev_env.js';
|
|
2
|
+
/**
|
|
3
|
+
* The read window a raw exchange gets by default in the cross suites. The
|
|
4
|
+
* server holds every byte it will get when the wait starts, so a backend that
|
|
5
|
+
* answers on what it has answers at once, and one that waits for more runs the
|
|
6
|
+
* whole window.
|
|
7
|
+
*/
|
|
8
|
+
export declare const RAW_HTTP_READ_TIMEOUT_MS = 2000;
|
|
2
9
|
/** What a raw exchange read back, and how it ended. */
|
|
3
10
|
export interface RawHttpExchange {
|
|
4
11
|
/** Every byte the server sent, `latin1`-decoded. */
|
|
@@ -53,6 +60,20 @@ export interface RawHttpResponse {
|
|
|
53
60
|
* @param request_bytes - the bytes to send, `latin1`-encoded
|
|
54
61
|
*/
|
|
55
62
|
export declare const raw_http_exchange: (base_url: string, request_bytes: string, options: RawHttpExchangeOptions) => Promise<RawHttpExchange>;
|
|
63
|
+
/**
|
|
64
|
+
* Render request headers as raw HTTP/1.1 header lines, each ending in CRLF.
|
|
65
|
+
*
|
|
66
|
+
* @param headers - header names to values, sent in iteration order
|
|
67
|
+
* @returns the lines, concatenated
|
|
68
|
+
*/
|
|
69
|
+
export declare const raw_http_header_lines: (headers: Record<string, string>) => string;
|
|
70
|
+
/**
|
|
71
|
+
* Parse a response body as JSON.
|
|
72
|
+
*
|
|
73
|
+
* @param body - the body text
|
|
74
|
+
* @returns the parsed value, or `undefined` when the body is not JSON
|
|
75
|
+
*/
|
|
76
|
+
export declare const raw_http_parse_json: (body: string) => unknown;
|
|
56
77
|
/**
|
|
57
78
|
* Count HTTP response status lines in a raw byte stream. Deliberately
|
|
58
79
|
* **unanchored** (no `^`/`m`): a second pipelined response is concatenated
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw_http.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/transports/raw_http.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAuB9B,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC/B,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACnC;AAED,uCAAuC;AACvC,MAAM,WAAW,sBAAsB;IACtC,uDAAuD;IACvD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CACtC;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,GAC7B,UAAU,MAAM,EAChB,eAAe,MAAM,EACrB,SAAS,sBAAsB,KAC7B,OAAO,CAAC,eAAe,CAwBvB,CAAC;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GAAI,KAAK,MAAM,KAAG,MACN,CAAC;AAElD,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAG5D,CAAC;AAyBF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GAAI,KAAK,MAAM,KAAG,eAAe,GAAG,IAyBvE,CAAC"}
|
|
1
|
+
{"version":3,"file":"raw_http.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/transports/raw_http.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAuB9B;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC/B,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACnC;AAED,uCAAuC;AACvC,MAAM,WAAW,sBAAsB;IACtC,uDAAuD;IACvD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CACtC;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,GAC7B,UAAU,MAAM,EAChB,eAAe,MAAM,EACrB,SAAS,sBAAsB,KAC7B,OAAO,CAAC,eAAe,CAwBvB,CAAC;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,MAG7D,CAAC;AAEZ;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,KAAG,OAMlD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GAAI,KAAK,MAAM,KAAG,MACN,CAAC;AAElD,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAG5D,CAAC;AAyBF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GAAI,KAAK,MAAM,KAAG,eAAe,GAAG,IAyBvE,CAAC"}
|
|
@@ -18,6 +18,13 @@ import '../assert_dev_env.js';
|
|
|
18
18
|
* @module
|
|
19
19
|
*/
|
|
20
20
|
import { connect } from 'node:net';
|
|
21
|
+
/**
|
|
22
|
+
* The read window a raw exchange gets by default in the cross suites. The
|
|
23
|
+
* server holds every byte it will get when the wait starts, so a backend that
|
|
24
|
+
* answers on what it has answers at once, and one that waits for more runs the
|
|
25
|
+
* whole window.
|
|
26
|
+
*/
|
|
27
|
+
export const RAW_HTTP_READ_TIMEOUT_MS = 2000;
|
|
21
28
|
/**
|
|
22
29
|
* Open a raw TCP socket to `base_url`, write `request_bytes` once, and collect
|
|
23
30
|
* what the server sends back until it closes the connection, a whole response
|
|
@@ -59,6 +66,29 @@ export const raw_http_exchange = (base_url, request_bytes, options) => new Promi
|
|
|
59
66
|
socket.on('error', () => { }); // EPIPE/ECONNRESET on a mid-write close is expected
|
|
60
67
|
socket.on('close', () => finish(true));
|
|
61
68
|
});
|
|
69
|
+
/**
|
|
70
|
+
* Render request headers as raw HTTP/1.1 header lines, each ending in CRLF.
|
|
71
|
+
*
|
|
72
|
+
* @param headers - header names to values, sent in iteration order
|
|
73
|
+
* @returns the lines, concatenated
|
|
74
|
+
*/
|
|
75
|
+
export const raw_http_header_lines = (headers) => Object.entries(headers)
|
|
76
|
+
.map(([name, value]) => `${name}: ${value}\r\n`)
|
|
77
|
+
.join('');
|
|
78
|
+
/**
|
|
79
|
+
* Parse a response body as JSON.
|
|
80
|
+
*
|
|
81
|
+
* @param body - the body text
|
|
82
|
+
* @returns the parsed value, or `undefined` when the body is not JSON
|
|
83
|
+
*/
|
|
84
|
+
export const raw_http_parse_json = (body) => {
|
|
85
|
+
try {
|
|
86
|
+
return JSON.parse(body);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
62
92
|
/**
|
|
63
93
|
* Count HTTP response status lines in a raw byte stream. Deliberately
|
|
64
94
|
* **unanchored** (no `^`/`m`): a second pipelined response is concatenated
|
package/dist/zod.d.ts
CHANGED
|
@@ -30,6 +30,15 @@ export declare const zod_get_base_type: (schema: z.ZodType) => string;
|
|
|
30
30
|
* @returns the innermost non-wrapper schema
|
|
31
31
|
*/
|
|
32
32
|
export declare const zod_get_innermost_type: (schema: z.ZodType) => z.ZodType;
|
|
33
|
+
/**
|
|
34
|
+
* Every layer of a schema, from the schema itself through each wrapper
|
|
35
|
+
* (optional, nullable, default, transform, pipe, prefault) to the innermost
|
|
36
|
+
* non-wrapper — for reading `.meta()` a wrapper does not carry over from the
|
|
37
|
+
* schema it wraps.
|
|
38
|
+
*
|
|
39
|
+
* @returns the layers, outermost first, ending at `zod_get_innermost_type(schema)`
|
|
40
|
+
*/
|
|
41
|
+
export declare const zod_get_schema_layers: (schema: z.ZodType) => Array<z.ZodType>;
|
|
33
42
|
/**
|
|
34
43
|
* Get all property keys from an object schema, unwrapping wrappers.
|
|
35
44
|
* Returns an empty array if the innermost type is not an object.
|
package/dist/zod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/zod.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgC7B;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,CAAC,CAAC,IAAI,CAAC,WAOzD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,MAAqC,CAAC;AAgC5F;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,CAAC,CAAC,OAM5D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EACtD,QAAQ,CAAC,KACP,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAGjC,CAAC;AAaF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,CAAC,CAAC,OAAO,EAAE,KAAK,MAAM,KAAG,CAAC,CAAC,OAIvE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,CAAC,CAAC,SAAS,GAAG,IAUtE,CAAC;AAIF,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,CAAC,CAAC,SAAS,KAAG,KAAK,CAAC,YAAY,CAa1E,CAAC"}
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/zod.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgC7B;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,CAAC,CAAC,IAAI,CAAC,WAOzD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,MAAqC,CAAC;AAgC5F;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,CAAC,CAAC,OAM5D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAUxE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EACtD,QAAQ,CAAC,KACP,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAGjC,CAAC;AAaF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,CAAC,CAAC,OAAO,EAAE,KAAK,MAAM,KAAG,CAAC,CAAC,OAIvE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,CAAC,CAAC,SAAS,GAAG,IAUtE,CAAC;AAIF,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,CAAC,CAAC,SAAS,KAAG,KAAK,CAAC,YAAY,CAa1E,CAAC"}
|
package/dist/zod.js
CHANGED
|
@@ -104,6 +104,26 @@ export const zod_get_innermost_type = (schema) => {
|
|
|
104
104
|
}
|
|
105
105
|
return schema;
|
|
106
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* Every layer of a schema, from the schema itself through each wrapper
|
|
109
|
+
* (optional, nullable, default, transform, pipe, prefault) to the innermost
|
|
110
|
+
* non-wrapper — for reading `.meta()` a wrapper does not carry over from the
|
|
111
|
+
* schema it wraps.
|
|
112
|
+
*
|
|
113
|
+
* @returns the layers, outermost first, ending at `zod_get_innermost_type(schema)`
|
|
114
|
+
*/
|
|
115
|
+
export const zod_get_schema_layers = (schema) => {
|
|
116
|
+
const layers = [schema];
|
|
117
|
+
let s = schema;
|
|
118
|
+
while (ZOD_WRAPPER_TYPES.has(s.def.type)) {
|
|
119
|
+
const sub = zod_to_subschema(s.def);
|
|
120
|
+
if (!sub)
|
|
121
|
+
break;
|
|
122
|
+
layers.push(sub);
|
|
123
|
+
s = sub;
|
|
124
|
+
}
|
|
125
|
+
return layers;
|
|
126
|
+
};
|
|
107
127
|
/**
|
|
108
128
|
* Get all property keys from an object schema, unwrapping wrappers.
|
|
109
129
|
* Returns an empty array if the innermost type is not an object.
|