typia 13.1.1 → 13.2.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/README.md +3 -0
- package/lib/_virtual/_rolldown/runtime.mjs +1 -5
- package/lib/executable/FileSystemIdentity.d.ts +44 -0
- package/lib/executable/FileSystemIdentity.js +213 -0
- package/lib/executable/FileSystemIdentity.js.map +1 -0
- package/lib/executable/FileSystemIdentity.mjs +133 -0
- package/lib/executable/FileSystemIdentity.mjs.map +1 -0
- package/lib/executable/TypiaGenerateWizard.js +272 -106
- package/lib/executable/TypiaGenerateWizard.js.map +1 -1
- package/lib/executable/TypiaGenerateWizard.mjs +239 -95
- package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
- package/lib/functional.d.ts +15 -12
- package/lib/functional.js.map +1 -1
- package/lib/functional.mjs.map +1 -1
- package/lib/internal/_ProtobufReader.d.ts +32 -0
- package/lib/internal/_ProtobufReader.js +148 -48
- package/lib/internal/_ProtobufReader.js.map +1 -1
- package/lib/internal/_ProtobufReader.mjs +137 -41
- package/lib/internal/_ProtobufReader.mjs.map +1 -1
- package/lib/internal/_createStandardSchema.js +18 -1
- package/lib/internal/_createStandardSchema.js.map +1 -1
- package/lib/internal/_createStandardSchema.mjs +12 -1
- package/lib/internal/_createStandardSchema.mjs.map +1 -1
- package/lib/internal/_decimal.d.ts +14 -0
- package/lib/internal/_decimal.js +61 -0
- package/lib/internal/_decimal.js.map +1 -0
- package/lib/internal/_decimal.mjs +49 -0
- package/lib/internal/_decimal.mjs.map +1 -0
- package/lib/internal/_httpQueryParseURLSearchParams.js +23 -2
- package/lib/internal/_httpQueryParseURLSearchParams.js.map +1 -1
- package/lib/internal/_httpQueryParseURLSearchParams.mjs +20 -2
- package/lib/internal/_httpQueryParseURLSearchParams.mjs.map +1 -1
- package/lib/internal/_isFormatByte.js +2 -5
- package/lib/internal/_isFormatByte.js.map +1 -1
- package/lib/internal/_isFormatByte.mjs +2 -5
- package/lib/internal/_isFormatByte.mjs.map +1 -1
- package/lib/internal/_isFormatDate.js +15 -2
- package/lib/internal/_isFormatDate.js.map +1 -1
- package/lib/internal/_isFormatDate.mjs +22 -2
- package/lib/internal/_isFormatDate.mjs.map +1 -1
- package/lib/internal/_isFormatDateTime.js +21 -2
- package/lib/internal/_isFormatDateTime.js.map +1 -1
- package/lib/internal/_isFormatDateTime.mjs +13 -2
- package/lib/internal/_isFormatDateTime.mjs.map +1 -1
- package/lib/internal/_isFormatIri.js +3 -2
- package/lib/internal/_isFormatIri.js.map +1 -1
- package/lib/internal/_isFormatIri.mjs +3 -2
- package/lib/internal/_isFormatIri.mjs.map +1 -1
- package/lib/internal/_isFormatIriReference.js +10 -2
- package/lib/internal/_isFormatIriReference.js.map +1 -1
- package/lib/internal/_isFormatIriReference.mjs +9 -2
- package/lib/internal/_isFormatIriReference.mjs.map +1 -1
- package/lib/internal/_isFormatUriReference.js +1 -1
- package/lib/internal/_isFormatUriReference.js.map +1 -1
- package/lib/internal/_isFormatUriReference.mjs +1 -1
- package/lib/internal/_isFormatUriReference.mjs.map +1 -1
- package/lib/internal/_isMultipleOf.d.ts +1 -0
- package/lib/internal/_isMultipleOf.js +13 -0
- package/lib/internal/_isMultipleOf.js.map +1 -0
- package/lib/internal/_isMultipleOf.mjs +12 -0
- package/lib/internal/_isMultipleOf.mjs.map +1 -0
- package/lib/internal/_isTypeFloat.js +1 -1
- package/lib/internal/_isTypeFloat.js.map +1 -1
- package/lib/internal/_isTypeFloat.mjs +1 -1
- package/lib/internal/_isTypeFloat.mjs.map +1 -1
- package/lib/internal/_isTypeInt64.js +1 -0
- package/lib/internal/_isTypeInt64.js.map +1 -1
- package/lib/internal/_isTypeInt64.mjs.map +1 -1
- package/lib/internal/_isTypeInt64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeInt64Bigint.js +15 -0
- package/lib/internal/_isTypeInt64Bigint.js.map +1 -0
- package/lib/internal/_isTypeInt64Bigint.mjs +8 -0
- package/lib/internal/_isTypeInt64Bigint.mjs.map +1 -0
- package/lib/internal/_isTypeUint64.js +1 -0
- package/lib/internal/_isTypeUint64.js.map +1 -1
- package/lib/internal/_isTypeUint64.mjs.map +1 -1
- package/lib/internal/_isTypeUint64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeUint64Bigint.js +10 -0
- package/lib/internal/_isTypeUint64Bigint.js.map +1 -0
- package/lib/internal/_isTypeUint64Bigint.mjs +8 -0
- package/lib/internal/_isTypeUint64Bigint.mjs.map +1 -0
- package/lib/internal/_isUniqueItems.js +96 -109
- package/lib/internal/_isUniqueItems.js.map +1 -1
- package/lib/internal/_isUniqueItems.mjs +62 -50
- package/lib/internal/_isUniqueItems.mjs.map +1 -1
- package/lib/internal/_jsonStringifyArray.d.ts +1 -0
- package/lib/internal/_jsonStringifyArray.js +48 -0
- package/lib/internal/_jsonStringifyArray.js.map +1 -0
- package/lib/internal/_jsonStringifyArray.mjs +40 -0
- package/lib/internal/_jsonStringifyArray.mjs.map +1 -0
- package/lib/internal/_jsonStringifyElement.d.ts +1 -0
- package/lib/internal/_jsonStringifyElement.js +23 -0
- package/lib/internal/_jsonStringifyElement.js.map +1 -0
- package/lib/internal/_jsonStringifyElement.mjs +23 -0
- package/lib/internal/_jsonStringifyElement.mjs.map +1 -0
- package/lib/internal/_jsonStringifyProperty.d.ts +1 -0
- package/lib/internal/_jsonStringifyProperty.js +31 -0
- package/lib/internal/_jsonStringifyProperty.js.map +1 -0
- package/lib/internal/_jsonStringifyProperty.mjs +31 -0
- package/lib/internal/_jsonStringifyProperty.mjs.map +1 -0
- package/lib/internal/_llmApplicationFinalize.js +1 -1
- package/lib/internal/_llmApplicationFinalize.js.map +1 -1
- package/lib/internal/_llmApplicationFinalize.mjs +1 -1
- package/lib/internal/_llmApplicationFinalize.mjs.map +1 -1
- package/lib/internal/_notationAny.js +8 -1
- package/lib/internal/_notationAny.js.map +1 -1
- package/lib/internal/_notationAny.mjs +7 -1
- package/lib/internal/_notationAny.mjs.map +1 -1
- package/lib/internal/_notationAssign.d.ts +1 -0
- package/lib/internal/_notationAssign.js +18 -0
- package/lib/internal/_notationAssign.js.map +1 -0
- package/lib/internal/_notationAssign.mjs +17 -0
- package/lib/internal/_notationAssign.mjs.map +1 -0
- package/lib/internal/_notationCamel.js +30 -9
- package/lib/internal/_notationCamel.js.map +1 -1
- package/lib/internal/_notationCamel.mjs +13 -5
- package/lib/internal/_notationCamel.mjs.map +1 -1
- package/lib/internal/_notationKebab.d.ts +1 -0
- package/lib/internal/_notationKebab.js +15 -0
- package/lib/internal/_notationKebab.js.map +1 -0
- package/lib/internal/_notationKebab.mjs +15 -0
- package/lib/internal/_notationKebab.mjs.map +1 -0
- package/lib/internal/_notationKeyCollision.d.ts +1 -0
- package/lib/internal/_notationKeyCollision.js +8 -0
- package/lib/internal/_notationKeyCollision.js.map +1 -0
- package/lib/internal/_notationKeyCollision.mjs +8 -0
- package/lib/internal/_notationKeyCollision.mjs.map +1 -0
- package/lib/internal/_notationPascal.js +20 -5
- package/lib/internal/_notationPascal.js.map +1 -1
- package/lib/internal/_notationPascal.mjs +10 -5
- package/lib/internal/_notationPascal.mjs.map +1 -1
- package/lib/internal/_notationSnake.js +25 -22
- package/lib/internal/_notationSnake.js.map +1 -1
- package/lib/internal/_notationSnake.mjs +11 -11
- package/lib/internal/_notationSnake.mjs.map +1 -1
- package/lib/internal/_plainCloneAny.js +174 -38
- package/lib/internal/_plainCloneAny.js.map +1 -1
- package/lib/internal/_plainCloneAny.mjs +126 -22
- package/lib/internal/_plainCloneAny.mjs.map +1 -1
- package/lib/internal/_randomArray.d.ts +1 -1
- package/lib/internal/_randomArray.js +11 -4
- package/lib/internal/_randomArray.js.map +1 -1
- package/lib/internal/_randomArray.mjs +9 -3
- package/lib/internal/_randomArray.mjs.map +1 -1
- package/lib/internal/_randomFormatByte.d.ts +2 -1
- package/lib/internal/_randomFormatByte.js +25 -1
- package/lib/internal/_randomFormatByte.js.map +1 -1
- package/lib/internal/_randomFormatByte.mjs +20 -1
- package/lib/internal/_randomFormatByte.mjs.map +1 -1
- package/lib/internal/_randomFormatDate.d.ts +3 -4
- package/lib/internal/_randomFormatDate.js +3 -10
- package/lib/internal/_randomFormatDate.js.map +1 -1
- package/lib/internal/_randomFormatDate.mjs +3 -6
- package/lib/internal/_randomFormatDate.mjs.map +1 -1
- package/lib/internal/_randomFormatDatetime.d.ts +3 -4
- package/lib/internal/_randomFormatDatetime.js +26 -8
- package/lib/internal/_randomFormatDatetime.js.map +1 -1
- package/lib/internal/_randomFormatDatetime.mjs +17 -6
- package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
- package/lib/internal/_randomFormatDuration.d.ts +2 -1
- package/lib/internal/_randomFormatDuration.js +23 -14
- package/lib/internal/_randomFormatDuration.js.map +1 -1
- package/lib/internal/_randomFormatDuration.mjs +22 -13
- package/lib/internal/_randomFormatDuration.mjs.map +1 -1
- package/lib/internal/_randomFormatEmail.d.ts +2 -1
- package/lib/internal/_randomFormatEmail.js +8 -1
- package/lib/internal/_randomFormatEmail.js.map +1 -1
- package/lib/internal/_randomFormatEmail.mjs +5 -1
- package/lib/internal/_randomFormatEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatHostname.d.ts +8 -1
- package/lib/internal/_randomFormatHostname.js +45 -2
- package/lib/internal/_randomFormatHostname.js.map +1 -1
- package/lib/internal/_randomFormatHostname.mjs +38 -2
- package/lib/internal/_randomFormatHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.d.ts +2 -1
- package/lib/internal/_randomFormatIdnEmail.js +16 -2
- package/lib/internal/_randomFormatIdnEmail.js.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.mjs +11 -2
- package/lib/internal/_randomFormatIdnEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.d.ts +2 -1
- package/lib/internal/_randomFormatIdnHostname.js +26 -1
- package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.mjs +25 -2
- package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv4.d.ts +2 -1
- package/lib/internal/_randomFormatIpv4.js +32 -1
- package/lib/internal/_randomFormatIpv4.js.map +1 -1
- package/lib/internal/_randomFormatIpv4.mjs +23 -1
- package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv6.d.ts +2 -1
- package/lib/internal/_randomFormatIpv6.js +58 -1
- package/lib/internal/_randomFormatIpv6.js.map +1 -1
- package/lib/internal/_randomFormatIpv6.mjs +45 -1
- package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
- package/lib/internal/_randomFormatIri.d.ts +2 -1
- package/lib/internal/_randomFormatIri.js +1 -1
- package/lib/internal/_randomFormatIri.js.map +1 -1
- package/lib/internal/_randomFormatIri.mjs +1 -1
- package/lib/internal/_randomFormatIri.mjs.map +1 -1
- package/lib/internal/_randomFormatIriReference.d.ts +2 -1
- package/lib/internal/_randomFormatIriReference.js +1 -1
- package/lib/internal/_randomFormatIriReference.js.map +1 -1
- package/lib/internal/_randomFormatIriReference.mjs +1 -1
- package/lib/internal/_randomFormatIriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatJsonPointer.js +20 -1
- package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.mjs +15 -1
- package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatPassword.d.ts +2 -1
- package/lib/internal/_randomFormatPassword.js +7 -5
- package/lib/internal/_randomFormatPassword.js.map +1 -1
- package/lib/internal/_randomFormatPassword.mjs +5 -1
- package/lib/internal/_randomFormatPassword.mjs.map +1 -1
- package/lib/internal/_randomFormatRegex.d.ts +2 -1
- package/lib/internal/_randomFormatRegex.js +15 -1
- package/lib/internal/_randomFormatRegex.js.map +1 -1
- package/lib/internal/_randomFormatRegex.mjs +14 -1
- package/lib/internal/_randomFormatRegex.mjs.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.js +20 -5
- package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs +21 -5
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatTime.d.ts +2 -1
- package/lib/internal/_randomFormatTime.js +34 -7
- package/lib/internal/_randomFormatTime.js.map +1 -1
- package/lib/internal/_randomFormatTime.mjs +37 -4
- package/lib/internal/_randomFormatTime.mjs.map +1 -1
- package/lib/internal/_randomFormatUri.d.ts +2 -1
- package/lib/internal/_randomFormatUri.js +1 -1
- package/lib/internal/_randomFormatUri.js.map +1 -1
- package/lib/internal/_randomFormatUri.mjs +1 -1
- package/lib/internal/_randomFormatUri.mjs.map +1 -1
- package/lib/internal/_randomFormatUriReference.d.ts +2 -1
- package/lib/internal/_randomFormatUriReference.js +1 -1
- package/lib/internal/_randomFormatUriReference.js.map +1 -1
- package/lib/internal/_randomFormatUriReference.mjs +1 -1
- package/lib/internal/_randomFormatUriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.d.ts +2 -1
- package/lib/internal/_randomFormatUriTemplate.js +1 -1
- package/lib/internal/_randomFormatUriTemplate.js.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs.map +1 -1
- package/lib/internal/_randomFormatUrl.d.ts +2 -1
- package/lib/internal/_randomFormatUrl.js +21 -1
- package/lib/internal/_randomFormatUrl.js.map +1 -1
- package/lib/internal/_randomFormatUrl.mjs +18 -1
- package/lib/internal/_randomFormatUrl.mjs.map +1 -1
- package/lib/internal/_randomFormatUuid.d.ts +2 -1
- package/lib/internal/_randomFormatUuid.js +3 -2
- package/lib/internal/_randomFormatUuid.js.map +1 -1
- package/lib/internal/_randomFormatUuid.mjs +3 -2
- package/lib/internal/_randomFormatUuid.mjs.map +1 -1
- package/lib/internal/_randomInteger.js +59 -28
- package/lib/internal/_randomInteger.js.map +1 -1
- package/lib/internal/_randomInteger.mjs +56 -16
- package/lib/internal/_randomInteger.mjs.map +1 -1
- package/lib/internal/_randomMultiple.d.ts +8 -0
- package/lib/internal/_randomMultiple.js +168 -0
- package/lib/internal/_randomMultiple.js.map +1 -0
- package/lib/internal/_randomMultiple.mjs +158 -0
- package/lib/internal/_randomMultiple.mjs.map +1 -0
- package/lib/internal/_randomNumber.js +42 -42
- package/lib/internal/_randomNumber.js.map +1 -1
- package/lib/internal/_randomNumber.mjs +41 -27
- package/lib/internal/_randomNumber.mjs.map +1 -1
- package/lib/internal/_randomPattern.d.ts +2 -1
- package/lib/internal/_randomPattern.js +19 -4
- package/lib/internal/_randomPattern.js.map +1 -1
- package/lib/internal/_randomPattern.mjs +10 -4
- package/lib/internal/_randomPattern.mjs.map +1 -1
- package/lib/internal/_randomStringLength.d.ts +64 -0
- package/lib/internal/_randomStringLength.js +84 -0
- package/lib/internal/_randomStringLength.js.map +1 -0
- package/lib/internal/_randomStringLength.mjs +79 -0
- package/lib/internal/_randomStringLength.mjs.map +1 -0
- package/lib/internal/_stringLength.d.ts +1 -0
- package/lib/internal/_stringLength.js +11 -0
- package/lib/internal/_stringLength.js.map +1 -0
- package/lib/internal/_stringLength.mjs +10 -0
- package/lib/internal/_stringLength.mjs.map +1 -0
- package/lib/internal/_validateReport.js +4 -1
- package/lib/internal/_validateReport.js.map +1 -1
- package/lib/internal/_validateReport.mjs +2 -1
- package/lib/internal/_validateReport.mjs.map +1 -1
- package/lib/internal/private/__notationRename.d.ts +14 -0
- package/lib/internal/private/__notationRename.js +25 -0
- package/lib/internal/private/__notationRename.js.map +1 -0
- package/lib/internal/private/__notationRename.mjs +24 -0
- package/lib/internal/private/__notationRename.mjs.map +1 -0
- package/lib/internal/private/__randomComposition.d.ts +23 -0
- package/lib/internal/private/__randomComposition.js +48 -0
- package/lib/internal/private/__randomComposition.js.map +1 -0
- package/lib/internal/private/__randomComposition.mjs +54 -0
- package/lib/internal/private/__randomComposition.mjs.map +1 -0
- package/lib/internal/private/__randomEpoch.d.ts +19 -0
- package/lib/internal/private/__randomEpoch.js +31 -0
- package/lib/internal/private/__randomEpoch.js.map +1 -0
- package/lib/internal/private/__randomEpoch.mjs +28 -0
- package/lib/internal/private/__randomEpoch.mjs.map +1 -0
- package/lib/json.d.ts +2 -2
- package/lib/json.mjs.map +1 -1
- package/lib/module.d.ts +2 -2
- package/lib/module.js.map +1 -1
- package/lib/module.mjs.map +1 -1
- package/lib/notations.d.ts +20 -4
- package/lib/notations.js.map +1 -1
- package/lib/notations.mjs.map +1 -1
- package/native/adapter/plugin_options.go +117 -0
- package/native/adapter/plugin_options_payload_matrix_test.go +181 -0
- package/native/cmd/ttsc-typia/any_array_type_tags_transform_test.go +63 -9
- package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +152 -0
- package/native/cmd/ttsc-typia/build.go +84 -64
- package/native/cmd/ttsc-typia/build_no_emit_preserves_analysis_options_test.go +67 -0
- package/native/cmd/ttsc-typia/build_no_emit_transform_diagnostics_test.go +138 -0
- package/native/cmd/ttsc-typia/build_plugin_options_come_from_payload_test.go +48 -0
- package/native/cmd/ttsc-typia/build_transactional_emit_success_test.go +81 -0
- package/native/cmd/ttsc-typia/build_transform_failure_atomicity_test.go +138 -0
- package/native/cmd/ttsc-typia/callable_interface_function_semantics_transform_test.go +331 -0
- package/native/cmd/ttsc-typia/callable_type_literal_boundaries_transform_test.go +1184 -0
- package/native/cmd/ttsc-typia/command_routes_and_diagnostics_coverage_test.go +3 -1
- package/native/cmd/ttsc-typia/compare_functional_union_membership_transform_test.go +434 -0
- package/native/cmd/ttsc-typia/compare_less_nan_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/compare_native_object_overmatch_transform_test.go +161 -0
- package/native/cmd/ttsc-typia/compare_nondiscriminable_union_transform_test.go +343 -0
- package/native/cmd/ttsc-typia/compare_template_literal_union_transform_test.go +241 -0
- package/native/cmd/ttsc-typia/compare_union_discrimination_transform_test.go +289 -0
- package/native/cmd/ttsc-typia/default_library_spoof_native_identity_transform_test.go +216 -0
- package/native/cmd/ttsc-typia/escaped_property_key_path_transform_test.go +193 -0
- package/native/cmd/ttsc-typia/finite_option_number_leaf_transform_test.go +240 -0
- package/native/cmd/ttsc-typia/functional_promised_type_transform_test.go +220 -0
- package/native/cmd/ttsc-typia/functional_receiver_transform_test.go +232 -0
- package/native/cmd/ttsc-typia/is_object_function_member_transform_test.go +205 -0
- package/native/cmd/ttsc-typia/json_application_alias_function_validation_transform_test.go +151 -0
- package/native/cmd/ttsc-typia/json_is_stringify_finite_number_transform_test.go +198 -0
- package/native/cmd/ttsc-typia/json_schema_dynamic_key_determinism_transform_test.go +246 -0
- package/native/cmd/ttsc-typia/json_stringify_contextual_undefined_transform_test.go +556 -0
- package/native/cmd/ttsc-typia/json_stringify_special_key_transform_test.go +238 -0
- package/native/cmd/ttsc-typia/lib_replacement_native_identity_transform_test.go +277 -0
- package/native/cmd/ttsc-typia/main_wasm.go +21 -2
- package/native/cmd/ttsc-typia/native_collection_identity_is_transform_test.go +234 -0
- package/native/cmd/ttsc-typia/native_generic_name_guard_is_transform_test.go +194 -0
- package/native/cmd/ttsc-typia/native_name_collision_is_transform_test.go +204 -0
- package/native/cmd/ttsc-typia/native_named_intersection_union_transform_test.go +390 -0
- package/native/cmd/ttsc-typia/node_buffer_native_exports_is_transform_test.go +526 -0
- package/native/cmd/ttsc-typia/non_trailing_rest_tuple_transform_test.go +23 -11
- package/native/cmd/ttsc-typia/notation_dynamic_keys_transform_test.go +286 -0
- package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +1 -1
- package/native/cmd/ttsc-typia/notation_literal_collision_transform_test.go +164 -0
- package/native/cmd/ttsc-typia/notation_pascal_case_transform_test.go +230 -0
- package/native/cmd/ttsc-typia/notation_unicode_key_transform_test.go +309 -0
- package/native/cmd/ttsc-typia/package_declaration_native_identity_is_transform_test.go +293 -0
- package/native/cmd/ttsc-typia/pattern_line_terminator_escape_transform_test.go +224 -0
- package/native/cmd/ttsc-typia/plain_prune_union_object_overmatch_transform_test.go +219 -0
- package/native/cmd/ttsc-typia/plugin_options_payload_helpers_test.go +181 -0
- package/native/cmd/ttsc-typia/private_field_filter_is_transform_test.go +278 -0
- package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +73 -27
- package/native/cmd/ttsc-typia/project_dependencies_barrel_reexport_transform_test.go +120 -0
- package/native/cmd/ttsc-typia/project_dependencies_collapsed_alias_transform_test.go +134 -0
- package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +135 -0
- package/native/cmd/ttsc-typia/project_dependencies_default_barrel_transform_test.go +114 -0
- package/native/cmd/ttsc-typia/project_dependencies_empty_heritage_transform_test.go +100 -0
- package/native/cmd/ttsc-typia/project_dependencies_envelope_transform_test.go +148 -0
- package/native/cmd/ttsc-typia/project_dependencies_index_signature_alias_transform_test.go +139 -0
- package/native/cmd/ttsc-typia/project_dependencies_local_reexport_transform_test.go +122 -0
- package/native/cmd/ttsc-typia/project_dependencies_signature_alias_transform_test.go +125 -0
- package/native/cmd/ttsc-typia/project_dependencies_star_barrel_transform_test.go +112 -0
- package/native/cmd/ttsc-typia/project_reference_graph_envelope_transform_test.go +190 -0
- package/native/cmd/ttsc-typia/protobuf_diagnostic_code_transform_test.go +167 -0
- package/native/cmd/ttsc-typia/protobuf_is_encode_finite_number_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/protobuf_sequence_field_numbers_transform_test.go +52 -22
- package/native/cmd/ttsc-typia/symbol_index_domain_transform_test.go +316 -0
- package/native/cmd/ttsc-typia/symbol_key_member_filter_transform_test.go +279 -0
- package/native/cmd/ttsc-typia/template_interpolation_type_tags_transform_test.go +86 -23
- package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
- package/native/cmd/ttsc-typia/transform.go +251 -39
- package/native/cmd/ttsc-typia/{transform_declaration_source_produces_no_js_test.go → transform_declaration_source_produces_no_javascript_test.go} +10 -2
- package/native/cmd/ttsc-typia/transform_fixtures_emit_coverage_test.go +21 -4
- package/native/cmd/ttsc-typia/transform_helpers_test.go +236 -3
- package/native/cmd/ttsc-typia/transform_plugin_options_come_from_payload_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_atomicity_test.go +114 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_writes_no_stdout_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go +81 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_empty_emit_reports_no_output_test.go +100 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_locates_output_across_layouts_test.go +160 -0
- package/native/cmd/ttsc-typia/transform_single_file_success_publishes_artifact_test.go +54 -0
- package/native/cmd/ttsc-typia/transform_wasm_host_argv_reports_diagnostics_test.go +39 -0
- package/native/cmd/ttsc-typia/tuple_optional_compare_clone_transform_test.go +227 -0
- package/native/cmd/ttsc-typia/user_global_native_identity_transform_test.go +484 -0
- package/native/core/factories/FormatCheatSheet.go +40 -7
- package/native/core/factories/IdentifierFactory.go +131 -4
- package/native/core/factories/MetadataCommentTagFactory.go +83 -40
- package/native/core/factories/MetadataTypeTagFactory.go +13 -1
- package/native/core/factories/NumericRangeFactory.go +60 -17
- package/native/core/factories/ProtobufFactory.go +13 -5
- package/native/core/factories/factory_utility_coverage_test.go +8 -2
- package/native/core/factories/format_alias_resolves_to_cheat_sheet_test.go +57 -0
- package/native/core/factories/format_alias_table_targets_the_cheat_sheet_test.go +44 -0
- package/native/core/factories/identifier_factory_postfix_escapes_every_key_test.go +147 -0
- package/native/core/factories/identifier_factory_postfix_survives_every_code_point_test.go +86 -0
- package/native/core/factories/internal/metadata/MetadataHelper.go +226 -17
- package/native/core/factories/internal/metadata/emplace_metadata_object.go +141 -8
- package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
- package/native/core/factories/internal/metadata/iterate_metadata_function.go +5 -12
- package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +111 -29
- package/native/core/factories/internal/metadata/iterate_metadata_map.go +5 -0
- package/native/core/factories/internal/metadata/iterate_metadata_native.go +45 -2
- package/native/core/factories/internal/metadata/iterate_metadata_set.go +5 -0
- package/native/core/factories/internal/metadata/type_arguments_precondition_test.go +70 -0
- package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +39 -0
- package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go +84 -0
- package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go +60 -0
- package/native/core/factories/metadata_type_tag_factory_declarations_test.go +86 -0
- package/native/core/factories/metadata_type_tag_factory_keeps_bool_form_exclusivity_test.go +38 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go +65 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_duplicated_array_form_tags_test.go +41 -0
- package/native/core/factories/numeric_range_factory_enforces_64bit_bounds_test.go +69 -0
- package/native/core/factories/protobuf_recovery_ownership_test.go +64 -0
- package/native/core/programmers/IsProgrammer.go +15 -1
- package/native/core/programmers/RandomProgrammer.go +51 -14
- package/native/core/programmers/compare/CompareEqualProgrammer.go +410 -8
- package/native/core/programmers/compare/CompareLessProgrammer.go +4 -2
- package/native/core/programmers/functional/FunctionalAssertFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalAssertReturnProgrammer.go +6 -14
- package/native/core/programmers/functional/FunctionalIsFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +49 -14
- package/native/core/programmers/functional/FunctionalIsReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/internal/FunctionalGeneralProgrammer.go +4 -17
- package/native/core/programmers/helpers/CloneJoiner.go +32 -0
- package/native/core/programmers/helpers/FunctionProgrammer.go +6 -13
- package/native/core/programmers/helpers/NotationJoiner.go +86 -28
- package/native/core/programmers/helpers/StringifyJoinder.go +161 -51
- package/native/core/programmers/helpers/UnionExplorer.go +203 -61
- package/native/core/programmers/helpers/joiner_branch_coverage_test.go +116 -118
- package/native/core/programmers/helpers/union_explorer_coverage_test.go +1 -1
- package/native/core/programmers/internal/CheckerProgrammer.go +100 -48
- package/native/core/programmers/iterate/check_template.go +344 -32
- package/native/core/programmers/iterate/iterate_check_coverage_test.go +76 -158
- package/native/core/programmers/iterate/iterate_utility_coverage_test.go +231 -270
- package/native/core/programmers/iterate/json_schema_discriminator.go +36 -10
- package/native/core/programmers/iterate/json_schema_discriminator_declaration_syntax_test.go +205 -0
- package/native/core/programmers/iterate/json_schema_object.go +49 -7
- package/native/core/programmers/iterate/json_schema_pattern_property_order_test.go +44 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader.go +674 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_boolean_default_test.go +95 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_test.go +123 -0
- package/native/core/programmers/iterate/template_interpolation_tags_test.go +40 -8
- package/native/core/programmers/iterate/template_runtime_pattern.go +63 -7
- package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
- package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
- package/native/core/programmers/json/JsonStringifyProgrammer.go +47 -6
- package/native/core/programmers/llm/LlmApplicationProgrammer.go +21 -11
- package/native/core/programmers/llm/LlmSchemaProgrammer.go +23 -6
- package/native/core/programmers/llm/llm_reference_codec_test.go +24 -0
- package/native/core/programmers/notations/NotationGeneralProgrammer.go +183 -67
- package/native/core/programmers/notations/notation_general_helpers_test.go +1 -3
- package/native/core/programmers/notations/notation_general_programmer_pascal_multiword_test.go +72 -0
- package/native/core/programmers/notations/notation_general_programmer_underscore_boundary_test.go +68 -0
- package/native/core/programmers/plain/PlainClassifyProgrammer.go +23 -15
- package/native/core/programmers/plain/PlainCloneProgrammer.go +20 -7
- package/native/core/programmers/plain/PlainPruneProgrammer.go +19 -5
- package/native/core/programmers/plain/plain_tuple_seed_recovery_ownership_test.go +25 -0
- package/native/core/programmers/protobuf/ProtobufDecodeProgrammer.go +37 -28
- package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +41 -22
- package/native/core/programmers/protobuf/protobuf_programmer_helper_coverage_test.go +26 -0
- package/native/core/programmers/random_programmer_length_argument_test.go +53 -0
- package/native/core/schemas/metadata/MetadataCollection.go +266 -25
- package/native/core/schemas/metadata/MetadataDefaultLibrary.go +81 -0
- package/native/core/schemas/metadata/MetadataDependency.go +388 -0
- package/native/core/schemas/metadata/MetadataObjectType.go +24 -22
- package/native/core/schemas/metadata/metadata_collection_generic_argument_dot_test.go +122 -0
- package/native/core/schemas/metadata/metadata_collection_name_allocation_test.go +147 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_cascade_test.go +55 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_test.go +68 -0
- package/native/core/utils/PatternUtil.go +13 -0
- package/native/core/utils/PromiseTypeFactory.go +59 -0
- package/native/core/utils/ProtobufNameEncoder.go +8 -0
- package/native/core/utils/promise_type_factory_semantics_test.go +118 -0
- package/native/go.mod +9 -1
- package/native/transform/CallExpressionTransformer.go +12 -0
- package/native/transform/features/json/JsonApplicationTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemaTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemasTransformer.go +5 -4
- package/native/transform/features/protobuf/ProtobufMessageTransformer.go +1 -1
- package/package.json +12 -4
- package/src/executable/FileSystemIdentity.ts +222 -0
- package/src/executable/TypiaGenerateWizard.ts +386 -113
- package/src/functional.ts +30 -60
- package/src/internal/_ProtobufReader.ts +161 -46
- package/src/internal/_createStandardSchema.ts +15 -1
- package/src/internal/_decimal.ts +69 -0
- package/src/internal/_httpQueryParseURLSearchParams.ts +24 -2
- package/src/internal/_isFormatByte.ts +2 -5
- package/src/internal/_isFormatDate.ts +15 -2
- package/src/internal/_isFormatDateTime.ts +28 -2
- package/src/internal/_isFormatIri.ts +5 -2
- package/src/internal/_isFormatIriReference.ts +11 -3
- package/src/internal/_isFormatUriReference.ts +1 -1
- package/src/internal/_isMultipleOf.ts +8 -0
- package/src/internal/_isTypeFloat.ts +1 -1
- package/src/internal/_isTypeInt64.ts +1 -0
- package/src/internal/_isTypeInt64Bigint.ts +12 -0
- package/src/internal/_isTypeUint64.ts +1 -0
- package/src/internal/_isTypeUint64Bigint.ts +7 -0
- package/src/internal/_isUniqueItems.ts +134 -132
- package/src/internal/_jsonStringifyArray.ts +50 -0
- package/src/internal/_jsonStringifyElement.ts +19 -0
- package/src/internal/_jsonStringifyProperty.ts +30 -0
- package/src/internal/_llmApplicationFinalize.ts +6 -1
- package/src/internal/_notationAny.ts +9 -4
- package/src/internal/_notationAssign.ts +20 -0
- package/src/internal/_notationCamel.ts +31 -10
- package/src/internal/_notationKebab.ts +11 -0
- package/src/internal/_notationKeyCollision.ts +9 -0
- package/src/internal/_notationPascal.ts +19 -6
- package/src/internal/_notationSnake.ts +24 -21
- package/src/internal/_plainCloneAny.ts +208 -33
- package/src/internal/_randomArray.ts +13 -4
- package/src/internal/_randomFormatByte.ts +31 -1
- package/src/internal/_randomFormatDate.ts +6 -17
- package/src/internal/_randomFormatDatetime.ts +34 -15
- package/src/internal/_randomFormatDuration.ts +30 -13
- package/src/internal/_randomFormatEmail.ts +8 -2
- package/src/internal/_randomFormatHostname.ts +48 -1
- package/src/internal/_randomFormatIdnEmail.ts +18 -2
- package/src/internal/_randomFormatIdnHostname.ts +34 -2
- package/src/internal/_randomFormatIpv4.ts +43 -2
- package/src/internal/_randomFormatIpv6.ts +67 -2
- package/src/internal/_randomFormatIri.ts +3 -1
- package/src/internal/_randomFormatIriReference.ts +3 -1
- package/src/internal/_randomFormatJsonPointer.ts +28 -2
- package/src/internal/_randomFormatPassword.ts +11 -6
- package/src/internal/_randomFormatRegex.ts +22 -1
- package/src/internal/_randomFormatRelativeJsonPointer.ts +26 -6
- package/src/internal/_randomFormatTime.ts +46 -10
- package/src/internal/_randomFormatUri.ts +3 -1
- package/src/internal/_randomFormatUriReference.ts +3 -1
- package/src/internal/_randomFormatUriTemplate.ts +3 -1
- package/src/internal/_randomFormatUrl.ts +25 -2
- package/src/internal/_randomFormatUuid.ts +10 -6
- package/src/internal/_randomInteger.ts +87 -40
- package/src/internal/_randomMultiple.ts +245 -0
- package/src/internal/_randomNumber.ts +72 -55
- package/src/internal/_randomPattern.ts +29 -4
- package/src/internal/_randomStringLength.ts +116 -0
- package/src/internal/_stringLength.ts +5 -0
- package/src/internal/_validateReport.ts +5 -1
- package/src/internal/private/__notationRename.ts +21 -0
- package/src/internal/private/__randomComposition.ts +50 -0
- package/src/internal/private/__randomEpoch.ts +34 -0
- package/src/json.ts +2 -2
- package/src/module.ts +4 -6
- package/src/notations.ts +20 -4
- package/lib/internal/private/__notationCapitalize.d.ts +0 -1
- package/lib/internal/private/__notationCapitalize.js +0 -6
- package/lib/internal/private/__notationCapitalize.js.map +0 -1
- package/lib/internal/private/__notationCapitalize.mjs +0 -6
- package/lib/internal/private/__notationCapitalize.mjs.map +0 -1
- package/lib/internal/private/__notationUnsnake.d.ts +0 -4
- package/lib/internal/private/__notationUnsnake.js +0 -26
- package/lib/internal/private/__notationUnsnake.js.map +0 -1
- package/lib/internal/private/__notationUnsnake.mjs +0 -15
- package/lib/internal/private/__notationUnsnake.mjs.map +0 -1
- package/native/adapter/visit.go +0 -173
- package/native/adapter/visit_property_chain_edges_test.go +0 -129
- package/native/cmd/ttsc-typia/plugin_options_missing_config_test.go +0 -26
- package/native/cmd/ttsc-typia/plugin_options_undefined_false_test.go +0 -36
- package/native/core/programmers/helpers/disable_function_programmer_declare.go +0 -10
- package/native/core/programmers/iterate/check_union_array_like.go +0 -422
- package/native/core/programmers/iterate/prune_object_properties.go +0 -105
- package/native/core/programmers/iterate/stringify_dynamic_properties.go +0 -219
- package/native/core/programmers/iterate/stringify_native.go +0 -14
- package/native/core/programmers/iterate/stringify_regular_properties.go +0 -112
- package/native/core/schemas/metadata/MetadataApplication.go +0 -41
- package/src/internal/private/__notationCapitalize.ts +0 -2
- package/src/internal/private/__notationUnsnake.ts +0 -24
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
package adapter
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"fmt"
|
|
6
|
+
"strings"
|
|
7
|
+
|
|
8
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// PluginName is typia's identity in the ttsc plugin protocol.
|
|
12
|
+
//
|
|
13
|
+
// typia's descriptor declares it (`packages/typia/src/transform.ts` ->
|
|
14
|
+
// `name: "typia"`) and the playground wasm plugin registers the same string
|
|
15
|
+
// with the ttsc wasm host. ttsc echoes it back on every payload entry, so it is
|
|
16
|
+
// how typia recognizes its own entry among the sibling plugins that ride in the
|
|
17
|
+
// same payload: a transform host carries the entries of every transform-stage
|
|
18
|
+
// plugin, not just its own.
|
|
19
|
+
const PluginName = "typia"
|
|
20
|
+
|
|
21
|
+
// ReadPluginOptions resolves typia's transform options from the ordered plugin
|
|
22
|
+
// payload the host passes on `--plugins-json`.
|
|
23
|
+
//
|
|
24
|
+
// The host owns tsconfig resolution. It parses the file as JSONC, follows the
|
|
25
|
+
// `extends` chain, discards comments, orders the plugin entries, and hands each
|
|
26
|
+
// native plugin back the resolved entry that caused that plugin to load. That
|
|
27
|
+
// entry is the only authority on typia's options, so this reads it and nothing
|
|
28
|
+
// else -- there is deliberately no fallback that re-reads tsconfig.json.
|
|
29
|
+
//
|
|
30
|
+
// Re-reading the file is what made samchon/typia#1887: the previous reader took
|
|
31
|
+
// the leaf file's raw bytes and regex-matched the option names over the whole
|
|
32
|
+
// text. It therefore dropped an option inherited through `extends` (the host
|
|
33
|
+
// resolved it, typia never saw it), and adopted an option the user had commented
|
|
34
|
+
// out or one that belonged to a sibling plugin's entry (the text matched, the
|
|
35
|
+
// entry did not). Reading the file back cannot be made correct without
|
|
36
|
+
// re-implementing the host's JSONC parse and `extends` walk, so a fallback that
|
|
37
|
+
// tried would either duplicate that work or keep the defect on whichever path
|
|
38
|
+
// took it.
|
|
39
|
+
//
|
|
40
|
+
// An absent or empty payload yields the zero options, which are typia's
|
|
41
|
+
// documented defaults. That is not a guess: a host that hands typia no entry
|
|
42
|
+
// has stated that typia was configured with nothing.
|
|
43
|
+
func ReadPluginOptions(pluginsJSON string) (PluginOptions, error) {
|
|
44
|
+
entries, err := parsePluginEntries(pluginsJSON)
|
|
45
|
+
if err != nil {
|
|
46
|
+
return PluginOptions{}, err
|
|
47
|
+
}
|
|
48
|
+
entry := findPluginEntry(entries, PluginName)
|
|
49
|
+
if entry == nil {
|
|
50
|
+
return PluginOptions{}, nil
|
|
51
|
+
}
|
|
52
|
+
return PluginOptions{
|
|
53
|
+
Functional: pluginOptionEnabled(entry.Config, "functional"),
|
|
54
|
+
Numeric: pluginOptionEnabled(entry.Config, "numeric"),
|
|
55
|
+
Finite: pluginOptionEnabled(entry.Config, "finite"),
|
|
56
|
+
Undefined: pluginOptionBoolean(entry.Config, "undefined"),
|
|
57
|
+
}, nil
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// parsePluginEntries decodes the payload. An empty payload is not an error --
|
|
61
|
+
// a host may legitimately run typia's binary with no plugin manifest -- but a
|
|
62
|
+
// payload that is present and undecodable is: the host meant to state typia's
|
|
63
|
+
// configuration and we cannot read it, so silently substituting defaults would
|
|
64
|
+
// reintroduce exactly the silent wrong-options failure this reader exists to
|
|
65
|
+
// prevent.
|
|
66
|
+
func parsePluginEntries(pluginsJSON string) ([]driver.PluginEntry, error) {
|
|
67
|
+
text := strings.TrimSpace(pluginsJSON)
|
|
68
|
+
if text == "" {
|
|
69
|
+
return nil, nil
|
|
70
|
+
}
|
|
71
|
+
var entries []driver.PluginEntry
|
|
72
|
+
if err := json.Unmarshal([]byte(text), &entries); err != nil {
|
|
73
|
+
return nil, fmt.Errorf("invalid --plugins-json payload: %w", err)
|
|
74
|
+
}
|
|
75
|
+
return entries, nil
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// findPluginEntry returns the payload entry the named plugin owns, or nil when
|
|
79
|
+
// the payload carries none. It matches on the host-assigned name rather than on
|
|
80
|
+
// the entry's `transform` specifier: the specifier is a module request the user
|
|
81
|
+
// may legally spell several ways (bare specifier, absolute path), while the
|
|
82
|
+
// name is the identity the host and the plugin already agree on.
|
|
83
|
+
func findPluginEntry(entries []driver.PluginEntry, name string) *driver.PluginEntry {
|
|
84
|
+
for index := range entries {
|
|
85
|
+
if entries[index].Name == name {
|
|
86
|
+
return &entries[index]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return nil
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// pluginOptionEnabled reports whether a tri-state option is explicitly on.
|
|
93
|
+
// Omitted, explicitly false, and non-boolean all mean off, matching how typia
|
|
94
|
+
// has always treated its three on/off options.
|
|
95
|
+
func pluginOptionEnabled(config map[string]any, name string) bool {
|
|
96
|
+
value := pluginOptionBoolean(config, name)
|
|
97
|
+
return value != nil && *value
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// pluginOptionBoolean reads one boolean option out of a resolved plugin entry's
|
|
101
|
+
// config, distinguishing "omitted" (nil) from "explicitly false".
|
|
102
|
+
//
|
|
103
|
+
// The distinction is load-bearing for `undefined`: `undefined: false` drives the
|
|
104
|
+
// exactOptionalPropertyTypes workflow and must not collapse into the omitted
|
|
105
|
+
// default. A present-but-non-boolean value is treated as omitted rather than
|
|
106
|
+
// coerced, so a typo cannot silently turn an option on.
|
|
107
|
+
func pluginOptionBoolean(config map[string]any, name string) *bool {
|
|
108
|
+
raw, ok := config[name]
|
|
109
|
+
if !ok {
|
|
110
|
+
return nil
|
|
111
|
+
}
|
|
112
|
+
value, ok := raw.(bool)
|
|
113
|
+
if !ok {
|
|
114
|
+
return nil
|
|
115
|
+
}
|
|
116
|
+
return &value
|
|
117
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
package adapter
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
// TestReadPluginOptionsPayloadMatrix verifies typia reads its options from its
|
|
8
|
+
// own entry in the host payload and from nothing else.
|
|
9
|
+
//
|
|
10
|
+
// The host resolves tsconfig -- JSONC parse, `extends` walk, plugin ordering --
|
|
11
|
+
// and hands each plugin back the entry that loaded it. Reading anything else
|
|
12
|
+
// produced samchon/typia#1887 in both directions: an option inherited through
|
|
13
|
+
// `extends` was dropped because only the leaf file was read, and an option that
|
|
14
|
+
// was commented out or that belonged to a sibling plugin was adopted because the
|
|
15
|
+
// match was against raw file text rather than against typia's entry. Every case
|
|
16
|
+
// below is expressed as the payload the host would actually send for that
|
|
17
|
+
// tsconfig, so the oracle is the host contract rather than typia's own output.
|
|
18
|
+
//
|
|
19
|
+
// 1. Feed the reader each payload shape the host can produce.
|
|
20
|
+
// 2. Assert the three on/off options and the tri-state `undefined` option.
|
|
21
|
+
// 3. Cover the sibling-entry, missing-entry, and empty-payload boundaries.
|
|
22
|
+
func TestReadPluginOptionsPayloadMatrix(t *testing.T) {
|
|
23
|
+
truth := true
|
|
24
|
+
lie := false
|
|
25
|
+
cases := []struct {
|
|
26
|
+
name string
|
|
27
|
+
payload string
|
|
28
|
+
expected PluginOptions
|
|
29
|
+
}{
|
|
30
|
+
{
|
|
31
|
+
// The documented shape: options inline on typia's own entry. This is the
|
|
32
|
+
// one case the old regex scrape got right, so it pins behavior that must
|
|
33
|
+
// not change.
|
|
34
|
+
name: "options on typia's own entry",
|
|
35
|
+
payload: `[{"config":{"transform":"typia/lib/transform","functional":true,"numeric":true,"finite":true},"name":"typia","stage":"transform"}]`,
|
|
36
|
+
expected: PluginOptions{Functional: true, Numeric: true, Finite: true},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
// A base tsconfig declares the option and the leaf `extends` it. The host
|
|
40
|
+
// resolved the chain and sends the merged entry; there is no leaf file to
|
|
41
|
+
// miss it in.
|
|
42
|
+
name: "option inherited through extends arrives resolved",
|
|
43
|
+
payload: `[{"config":{"transform":"typia/lib/transform","functional":true},"name":"typia","stage":"transform"}]`,
|
|
44
|
+
expected: PluginOptions{Functional: true},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
// The user commented the option out. The host's JSONC parse dropped it, so
|
|
48
|
+
// typia's entry simply does not carry it -- there is no comment left for a
|
|
49
|
+
// text match to find.
|
|
50
|
+
name: "option the user commented out never reaches the entry",
|
|
51
|
+
payload: `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`,
|
|
52
|
+
expected: PluginOptions{},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
// A transform host carries every transform-stage plugin's entry, so a
|
|
56
|
+
// sibling's identically-named option sits in the same payload. It belongs
|
|
57
|
+
// to the sibling.
|
|
58
|
+
name: "sibling plugin's identically-named option does not leak",
|
|
59
|
+
payload: `[
|
|
60
|
+
{"config":{"transform":"other/lib/transform","functional":true,"numeric":true,"finite":true,"undefined":true},"name":"other","stage":"transform"},
|
|
61
|
+
{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}
|
|
62
|
+
]`,
|
|
63
|
+
expected: PluginOptions{},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
// Entry order is the host's, not typia's: typia must find itself by name
|
|
67
|
+
// rather than assume it is first.
|
|
68
|
+
name: "typia's entry is found when it is not first",
|
|
69
|
+
payload: `[
|
|
70
|
+
{"config":{"transform":"other/lib/transform"},"name":"other","stage":"transform"},
|
|
71
|
+
{"config":{"transform":"typia/lib/transform","finite":true},"name":"typia","stage":"transform"}
|
|
72
|
+
]`,
|
|
73
|
+
expected: PluginOptions{Finite: true},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
// `undefined: false` drives the exactOptionalPropertyTypes workflow and
|
|
77
|
+
// must stay distinguishable from an omitted option.
|
|
78
|
+
name: "explicit undefined=false is preserved",
|
|
79
|
+
payload: `[{"config":{"transform":"typia/lib/transform","undefined":false},"name":"typia","stage":"transform"}]`,
|
|
80
|
+
expected: PluginOptions{Undefined: &lie},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "explicit undefined=true is preserved",
|
|
84
|
+
payload: `[{"config":{"transform":"typia/lib/transform","undefined":true},"name":"typia","stage":"transform"}]`,
|
|
85
|
+
expected: PluginOptions{Undefined: &truth},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "omitted undefined stays nil rather than collapsing to false",
|
|
89
|
+
payload: `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`,
|
|
90
|
+
expected: PluginOptions{},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
// Explicit false is off for the three on/off options, matching how typia
|
|
94
|
+
// has always read them.
|
|
95
|
+
name: "explicit false is off",
|
|
96
|
+
payload: `[{"config":{"transform":"typia/lib/transform","functional":false,"numeric":false,"finite":false},"name":"typia","stage":"transform"}]`,
|
|
97
|
+
expected: PluginOptions{},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
// A typo must not turn an option on by truthiness.
|
|
101
|
+
name: "non-boolean values are not coerced",
|
|
102
|
+
payload: `[{"config":{"transform":"typia/lib/transform","functional":"true","numeric":1,"finite":null,"undefined":"false"},"name":"typia","stage":"transform"}]`,
|
|
103
|
+
expected: PluginOptions{},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "entry with no options yields the defaults",
|
|
107
|
+
payload: `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`,
|
|
108
|
+
expected: PluginOptions{},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: "payload carrying no typia entry yields the defaults",
|
|
112
|
+
payload: `[{"config":{"transform":"other/lib/transform","functional":true},"name":"other","stage":"transform"}]`,
|
|
113
|
+
expected: PluginOptions{},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "empty payload array yields the defaults",
|
|
117
|
+
payload: `[]`,
|
|
118
|
+
expected: PluginOptions{},
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "absent payload yields the defaults",
|
|
122
|
+
payload: ``,
|
|
123
|
+
expected: PluginOptions{},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "blank payload yields the defaults",
|
|
127
|
+
payload: ` `,
|
|
128
|
+
expected: PluginOptions{},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
// An entry with a null config must not panic the map reads.
|
|
132
|
+
name: "null config yields the defaults",
|
|
133
|
+
payload: `[{"config":null,"name":"typia","stage":"transform"}]`,
|
|
134
|
+
expected: PluginOptions{},
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
for _, tc := range cases {
|
|
138
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
139
|
+
options, err := ReadPluginOptions(tc.payload)
|
|
140
|
+
if err != nil {
|
|
141
|
+
t.Fatalf("payload should be readable: %v", err)
|
|
142
|
+
}
|
|
143
|
+
if options.Functional != tc.expected.Functional ||
|
|
144
|
+
options.Numeric != tc.expected.Numeric ||
|
|
145
|
+
options.Finite != tc.expected.Finite {
|
|
146
|
+
t.Fatalf("on/off options mismatch: got %+v want %+v", options, tc.expected)
|
|
147
|
+
}
|
|
148
|
+
if !equalBooleanOption(options.Undefined, tc.expected.Undefined) {
|
|
149
|
+
t.Fatalf("undefined option mismatch: got %s want %s",
|
|
150
|
+
formatBooleanOption(options.Undefined), formatBooleanOption(tc.expected.Undefined))
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
t.Run("undecodable payload is reported rather than defaulted", func(t *testing.T) {
|
|
156
|
+
// The host meant to state typia's configuration. If that statement cannot be
|
|
157
|
+
// read, substituting defaults would silently compile the project under the
|
|
158
|
+
// wrong options -- the very failure this reader exists to prevent -- so the
|
|
159
|
+
// host must hear about it instead.
|
|
160
|
+
if _, err := ReadPluginOptions(`{"not":"an array"}`); err == nil {
|
|
161
|
+
t.Fatal("an undecodable payload must be an error, not silent defaults")
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
func equalBooleanOption(actual, expected *bool) bool {
|
|
167
|
+
if actual == nil || expected == nil {
|
|
168
|
+
return actual == nil && expected == nil
|
|
169
|
+
}
|
|
170
|
+
return *actual == *expected
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
func formatBooleanOption(value *bool) string {
|
|
174
|
+
if value == nil {
|
|
175
|
+
return "<nil>"
|
|
176
|
+
}
|
|
177
|
+
if *value {
|
|
178
|
+
return "true"
|
|
179
|
+
}
|
|
180
|
+
return "false"
|
|
181
|
+
}
|
|
@@ -141,13 +141,35 @@ export const validateConcrete = typia.createValidate<
|
|
|
141
141
|
string[] & tags.MinItems<2> & ContainsStatus
|
|
142
142
|
>();
|
|
143
143
|
|
|
144
|
-
// Union branch: a tagged any-element array beside another array variant.
|
|
145
|
-
//
|
|
146
|
-
// satisfies trivially, so these tags are knowingly NOT enforced yet (the
|
|
147
|
-
// residual gap documented on issue #1933).
|
|
144
|
+
// Union branch: a tagged any-element array beside another array variant. The
|
|
145
|
+
// wrapper predicate participates in complete-branch selection (#2040).
|
|
148
146
|
export const validateUnion = typia.createValidate<
|
|
149
147
|
{ list: (unknown[] & tags.MinItems<2>) | string[] }
|
|
150
148
|
>();
|
|
149
|
+
export const validateUnionReversed = typia.createValidate<
|
|
150
|
+
{ list: string[] | (unknown[] & tags.MinItems<2>) }
|
|
151
|
+
>();
|
|
152
|
+
export const isUnion = typia.createIs<
|
|
153
|
+
{ list: (unknown[] & tags.MinItems<2>) | string[] }
|
|
154
|
+
>();
|
|
155
|
+
export const assertUnion = typia.createAssert<
|
|
156
|
+
{ list: (unknown[] & tags.MinItems<2>) | string[] }
|
|
157
|
+
>();
|
|
158
|
+
export const equalsUnion = typia.createEquals<
|
|
159
|
+
{ list: (unknown[] & tags.MinItems<2>) | string[] }
|
|
160
|
+
>();
|
|
161
|
+
export const validateTupleUnion = typia.createValidate<
|
|
162
|
+
{ list: (unknown[] & tags.MinItems<2>) | [number] }
|
|
163
|
+
>();
|
|
164
|
+
export const validateTaggedAlternatives = typia.createValidate<
|
|
165
|
+
{ list: (unknown[] & tags.MinItems<2>) | (string[] & tags.MaxItems<1>) }
|
|
166
|
+
>();
|
|
167
|
+
export const stringifyUnion = typia.json.createValidateStringify<
|
|
168
|
+
{ list: (unknown[] & tags.MinItems<2>) | string[] }
|
|
169
|
+
>();
|
|
170
|
+
export const schemaUnion = typia.json.schemas<[
|
|
171
|
+
(unknown[] & tags.MinItems<2>) | string[],
|
|
172
|
+
]>();
|
|
151
173
|
`
|
|
152
174
|
|
|
153
175
|
const anyArrayTypeTagsRuntimeRunner = `const mod = require("./main.cjs");
|
|
@@ -194,11 +216,43 @@ expectFailure("concrete too short", mod.validateConcrete(["SUCCESS"]), "MinItems
|
|
|
194
216
|
expectFailure("concrete no status", mod.validateConcrete(["a", "b"]), "ContainsStatus");
|
|
195
217
|
expectSuccess("concrete valid", mod.validateConcrete(["a", "SUCCESS"]));
|
|
196
218
|
|
|
197
|
-
// 4.
|
|
198
|
-
// gap — the whole bucket keeps the historical wholesale acceptance, so
|
|
199
|
-
// even [1] (matching neither branch on paper) passes. When union branch
|
|
200
|
-
// backtracking lands, flip the last expectation to a failure.
|
|
219
|
+
// 4. Complete branches backtrack across wrapper predicates and element types.
|
|
201
220
|
expectSuccess("union via tagged any", mod.validateUnion({ list: [1, 2] }));
|
|
202
221
|
expectSuccess("union via string branch", mod.validateUnion({ list: ["solo"] }));
|
|
203
|
-
|
|
222
|
+
expectFailure("union no valid branch", mod.validateUnion({ list: [1] }), "MinItems<2>");
|
|
223
|
+
expectSuccess("reversed union via tagged any", mod.validateUnionReversed({ list: [1, 2] }));
|
|
224
|
+
expectSuccess("reversed union via string branch", mod.validateUnionReversed({ list: ["solo"] }));
|
|
225
|
+
expectFailure("reversed union no valid branch", mod.validateUnionReversed({ list: [1] }), "MinItems<2>");
|
|
226
|
+
if (mod.isUnion({ list: [1] }) !== false || mod.isUnion({ list: [1, 2] }) !== true) {
|
|
227
|
+
throw new Error("is did not honor the complete tagged union branches");
|
|
228
|
+
}
|
|
229
|
+
if (mod.equalsUnion({ list: [1] }) !== false || mod.equalsUnion({ list: ["solo"] }) !== true) {
|
|
230
|
+
throw new Error("equals did not honor the complete tagged union branches");
|
|
231
|
+
}
|
|
232
|
+
let asserted = false;
|
|
233
|
+
try {
|
|
234
|
+
mod.assertUnion({ list: [1] });
|
|
235
|
+
} catch (error) {
|
|
236
|
+
asserted = String(error && error.message).includes("MinItems<2>");
|
|
237
|
+
}
|
|
238
|
+
if (asserted !== true) {
|
|
239
|
+
throw new Error("assert did not attribute the failed wrapper tag");
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
expectSuccess("tuple branch", mod.validateTupleUnion({ list: [1] }));
|
|
243
|
+
expectSuccess("tuple union tagged any", mod.validateTupleUnion({ list: [1, 2] }));
|
|
244
|
+
expectSuccess("tagged alternative string", mod.validateTaggedAlternatives({ list: ["solo"] }));
|
|
245
|
+
expectSuccess("tagged alternative any", mod.validateTaggedAlternatives({ list: [1, 2] }));
|
|
246
|
+
expectSuccess("tagged alternative empty", mod.validateTaggedAlternatives({ list: [] }));
|
|
247
|
+
expectFailure("tagged alternatives reject", mod.validateTaggedAlternatives({ list: [1] }), "MinItems<2>");
|
|
248
|
+
|
|
249
|
+
const stringified = mod.stringifyUnion({ list: ["solo"] });
|
|
250
|
+
if (stringified.success !== true || JSON.parse(stringified.data).list[0] !== "solo") {
|
|
251
|
+
throw new Error("validated stringify rejected a later valid branch: " + JSON.stringify(stringified));
|
|
252
|
+
}
|
|
253
|
+
expectFailure("validated stringify no valid branch", mod.stringifyUnion({ list: [1] }), "MinItems<2>");
|
|
254
|
+
const unionSchema = JSON.stringify(mod.schemaUnion);
|
|
255
|
+
if (unionSchema.includes('"minItems":2') === false) {
|
|
256
|
+
throw new Error("array union schema lost MinItems: " + unionSchema);
|
|
257
|
+
}
|
|
204
258
|
`
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
|
|
10
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
11
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
// TestAssertGuardFactoryContract verifies factory typing and runtime shape.
|
|
15
|
+
//
|
|
16
|
+
// An assertion-guard factory returns the guard itself. Its successful invocation
|
|
17
|
+
// returns void while narrowing the input; it never returns another callable
|
|
18
|
+
// assertion guard.
|
|
19
|
+
//
|
|
20
|
+
// 1. Compile normal and equals factories with explicit and inferred types.
|
|
21
|
+
// 2. Prove successful invocations narrow and have a void return type.
|
|
22
|
+
// 3. Exercise custom errors and the equals-only surplus-property boundary.
|
|
23
|
+
func TestAssertGuardFactoryContract(t *testing.T) {
|
|
24
|
+
project := compareEqualCoverProject(t, "assert-guard-factory-", assertGuardFactorySource)
|
|
25
|
+
ttscTypiaTestAssertGuardFactoryType(t, project)
|
|
26
|
+
ttscTypiaTestTypecheck(t, project)
|
|
27
|
+
js := compareEqualCoverTransform(t, project)
|
|
28
|
+
if strings.Contains(js, "createAssertGuard<") {
|
|
29
|
+
t.Fatalf("assert guard factory call was not transformed:\n%s", js)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
node, err := exec.LookPath("node")
|
|
33
|
+
if err != nil {
|
|
34
|
+
t.Skip("node executable not found")
|
|
35
|
+
}
|
|
36
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
37
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
38
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
39
|
+
}
|
|
40
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
41
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(ttscTypiaTestRewriteCommonJS(t, js)), 0o644); err != nil {
|
|
42
|
+
t.Fatalf("write runtime module: %v", err)
|
|
43
|
+
}
|
|
44
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
45
|
+
if err := os.WriteFile(runner, []byte(assertGuardFactoryRuntime), 0o644); err != nil {
|
|
46
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
47
|
+
}
|
|
48
|
+
cmd := exec.Command(node, runner)
|
|
49
|
+
cmd.Dir = runtimeDir
|
|
50
|
+
if output, err := cmd.CombinedOutput(); err != nil {
|
|
51
|
+
t.Fatalf("assert guard factory runtime cases failed: %v\n%s", err, output)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
func ttscTypiaTestAssertGuardFactoryType(t *testing.T, project string) {
|
|
56
|
+
t.Helper()
|
|
57
|
+
program, diagnostics, err := driver.LoadProgram(project, "tsconfig.json", driver.LoadProgramOptions{})
|
|
58
|
+
if err != nil {
|
|
59
|
+
t.Fatalf("load assertion guard fixture: %v", err)
|
|
60
|
+
}
|
|
61
|
+
if len(diagnostics) != 0 {
|
|
62
|
+
t.Fatalf("assertion guard fixture diagnostics: %+v", diagnostics)
|
|
63
|
+
}
|
|
64
|
+
defer program.Close()
|
|
65
|
+
|
|
66
|
+
source := program.SourceFile(filepath.Join(project, "src", "main.ts"))
|
|
67
|
+
if source == nil {
|
|
68
|
+
t.Fatal("assertion guard fixture source was not loaded")
|
|
69
|
+
}
|
|
70
|
+
found := 0
|
|
71
|
+
for _, statement := range source.Statements.Nodes {
|
|
72
|
+
if statement.Kind != shimast.KindVariableStatement {
|
|
73
|
+
continue
|
|
74
|
+
}
|
|
75
|
+
for _, declaration := range statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes {
|
|
76
|
+
name := declaration.Name().Text()
|
|
77
|
+
if name != "inferred" && name != "inferredEquals" {
|
|
78
|
+
continue
|
|
79
|
+
}
|
|
80
|
+
found++
|
|
81
|
+
typeName := program.Checker.TypeToString(program.Checker.GetTypeAtLocation(declaration))
|
|
82
|
+
if strings.Contains(typeName, "=> AssertionGuard") {
|
|
83
|
+
t.Fatalf("%s returns a nested assertion guard: %s", name, typeName)
|
|
84
|
+
}
|
|
85
|
+
if typeName != "AssertionGuard<User>" && !strings.Contains(typeName, "asserts input is User") {
|
|
86
|
+
t.Fatalf("%s is not an assertion guard: %s", name, typeName)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if found != 2 {
|
|
91
|
+
t.Fatalf("expected two inferred assertion guards, found %d", found)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const assertGuardFactorySource = `import typia, { AssertionGuard, TypeGuardError } from "typia";
|
|
96
|
+
|
|
97
|
+
interface User {
|
|
98
|
+
id: number;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const custom = (props: TypeGuardError.IProps): Error =>
|
|
102
|
+
Object.assign(new Error("custom guard"), props);
|
|
103
|
+
|
|
104
|
+
export const guard: AssertionGuard<User> = typia.createAssertGuard<User>(custom);
|
|
105
|
+
export const equalsGuard: AssertionGuard<User> = typia.createAssertGuardEquals<User>(custom);
|
|
106
|
+
export const inferred = typia.createAssertGuard<User>();
|
|
107
|
+
export const inferredEquals = typia.createAssertGuardEquals<User>();
|
|
108
|
+
|
|
109
|
+
let input: unknown = { id: 1 };
|
|
110
|
+
const returned = guard(input);
|
|
111
|
+
input.id satisfies number;
|
|
112
|
+
|
|
113
|
+
type Equal<X, Y> =
|
|
114
|
+
(<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
|
|
115
|
+
? true
|
|
116
|
+
: false;
|
|
117
|
+
type Assert<T extends true> = T;
|
|
118
|
+
export type FactoryCases = [
|
|
119
|
+
Assert<Equal<typeof inferred, AssertionGuard<User>>>,
|
|
120
|
+
Assert<Equal<typeof inferredEquals, AssertionGuard<User>>>,
|
|
121
|
+
Assert<Equal<typeof returned, void>>,
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
// @ts-expect-error invoking an assertion guard returns void, not another guard.
|
|
125
|
+
const nested: AssertionGuard<User> = guard(input);
|
|
126
|
+
void nested;
|
|
127
|
+
`
|
|
128
|
+
|
|
129
|
+
const assertGuardFactoryRuntime = `const mod = require("./main.cjs");
|
|
130
|
+
|
|
131
|
+
const expect = (label, actual, expected) => {
|
|
132
|
+
if (actual !== expected) throw new Error(label + ": expected " + expected + ", got " + actual);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
expect("normal success returns void", mod.guard({ id: 1 }), undefined);
|
|
136
|
+
expect("equals success returns void", mod.equalsGuard({ id: 1 }), undefined);
|
|
137
|
+
expect("normal permits surplus", mod.guard({ id: 1, extra: true }), undefined);
|
|
138
|
+
|
|
139
|
+
for (const [label, guard, value] of [
|
|
140
|
+
["normal invalid", mod.guard, { id: "bad" }],
|
|
141
|
+
["equals invalid", mod.equalsGuard, { id: "bad" }],
|
|
142
|
+
["equals surplus", mod.equalsGuard, { id: 1, extra: true }],
|
|
143
|
+
]) {
|
|
144
|
+
let error;
|
|
145
|
+
try {
|
|
146
|
+
guard(value);
|
|
147
|
+
} catch (exp) {
|
|
148
|
+
error = exp;
|
|
149
|
+
}
|
|
150
|
+
expect(label + " uses custom error", error && error.message, "custom guard");
|
|
151
|
+
}
|
|
152
|
+
`
|