typia 13.1.1 → 13.1.19
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 +21 -0
- package/lib/executable/FileSystemIdentity.js +183 -0
- package/lib/executable/FileSystemIdentity.js.map +1 -0
- package/lib/executable/FileSystemIdentity.mjs +129 -0
- package/lib/executable/FileSystemIdentity.mjs.map +1 -0
- package/lib/executable/TypiaGenerateWizard.js +264 -104
- package/lib/executable/TypiaGenerateWizard.js.map +1 -1
- package/lib/executable/TypiaGenerateWizard.mjs +233 -93
- 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 +17 -0
- package/lib/internal/_ProtobufReader.js +117 -45
- package/lib/internal/_ProtobufReader.js.map +1 -1
- package/lib/internal/_ProtobufReader.mjs +108 -39
- 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/_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 +2 -1
- package/lib/internal/_randomFormatByte.js.map +1 -1
- package/lib/internal/_randomFormatByte.mjs +2 -1
- package/lib/internal/_randomFormatByte.mjs.map +1 -1
- package/lib/internal/_randomFormatDate.d.ts +2 -0
- package/lib/internal/_randomFormatDate.js +3 -2
- package/lib/internal/_randomFormatDate.js.map +1 -1
- package/lib/internal/_randomFormatDate.mjs +3 -2
- package/lib/internal/_randomFormatDate.mjs.map +1 -1
- package/lib/internal/_randomFormatDatetime.d.ts +2 -0
- package/lib/internal/_randomFormatDatetime.js +3 -2
- package/lib/internal/_randomFormatDatetime.js.map +1 -1
- package/lib/internal/_randomFormatDatetime.mjs +3 -2
- package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
- package/lib/internal/_randomFormatDuration.d.ts +2 -1
- package/lib/internal/_randomFormatDuration.js +3 -2
- package/lib/internal/_randomFormatDuration.js.map +1 -1
- package/lib/internal/_randomFormatDuration.mjs +3 -2
- 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 +2 -1
- package/lib/internal/_randomFormatIpv4.js.map +1 -1
- package/lib/internal/_randomFormatIpv4.mjs +2 -1
- package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv6.d.ts +2 -1
- package/lib/internal/_randomFormatIpv6.js +2 -1
- package/lib/internal/_randomFormatIpv6.js.map +1 -1
- package/lib/internal/_randomFormatIpv6.mjs +2 -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 +8 -1
- package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.mjs +5 -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 +2 -1
- package/lib/internal/_randomFormatRegex.js.map +1 -1
- package/lib/internal/_randomFormatRegex.mjs +2 -1
- package/lib/internal/_randomFormatRegex.mjs.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.js +3 -2
- package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs +3 -2
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatTime.d.ts +2 -1
- package/lib/internal/_randomFormatTime.js +3 -2
- package/lib/internal/_randomFormatTime.js.map +1 -1
- package/lib/internal/_randomFormatTime.mjs +3 -2
- 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 +33 -0
- package/lib/internal/_randomStringLength.js +48 -0
- package/lib/internal/_randomStringLength.js.map +1 -0
- package/lib/internal/_randomStringLength.mjs +44 -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/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 +81 -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/command_routes_and_diagnostics_coverage_test.go +3 -1
- 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_union_discrimination_transform_test.go +289 -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_stringify_special_key_transform_test.go +238 -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/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/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_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_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 +228 -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 +159 -1
- 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/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 +7 -4
- 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 +60 -6
- package/native/core/factories/internal/metadata/emplace_metadata_object.go +116 -8
- package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
- package/native/core/factories/internal/metadata/iterate_metadata_function.go +4 -11
- package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +8 -6
- package/native/core/factories/internal/metadata/iterate_metadata_map.go +9 -0
- package/native/core/factories/internal/metadata/iterate_metadata_native.go +27 -2
- package/native/core/factories/internal/metadata/iterate_metadata_set.go +9 -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 +393 -5
- 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/NotationJoiner.go +86 -28
- package/native/core/programmers/helpers/StringifyJoinder.go +32 -1
- package/native/core/programmers/helpers/UnionExplorer.go +203 -61
- package/native/core/programmers/helpers/joiner_branch_coverage_test.go +5 -3
- 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/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/openapi_v3_downgrader.go +641 -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 +52 -7
- package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
- package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
- package/native/core/programmers/llm/LlmApplicationProgrammer.go +12 -10
- 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 +40 -21
- 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 +270 -20
- package/native/core/schemas/metadata/MetadataDependency.go +388 -0
- package/native/core/schemas/metadata/MetadataObjectType.go +17 -4
- 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/package.json +16 -4
- package/src/executable/FileSystemIdentity.ts +189 -0
- package/src/executable/TypiaGenerateWizard.ts +377 -110
- package/src/functional.ts +30 -60
- package/src/internal/_ProtobufReader.ts +129 -43
- 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/_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 +4 -1
- package/src/internal/_randomFormatDate.ts +17 -12
- package/src/internal/_randomFormatDatetime.ts +15 -10
- package/src/internal/_randomFormatDuration.ts +16 -14
- 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 +3 -2
- package/src/internal/_randomFormatIpv6.ts +3 -2
- package/src/internal/_randomFormatIri.ts +3 -1
- package/src/internal/_randomFormatIriReference.ts +3 -1
- package/src/internal/_randomFormatJsonPointer.ts +8 -2
- package/src/internal/_randomFormatPassword.ts +11 -6
- package/src/internal/_randomFormatRegex.ts +4 -1
- package/src/internal/_randomFormatRelativeJsonPointer.ts +13 -6
- package/src/internal/_randomFormatTime.ts +13 -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 +26 -4
- package/src/internal/_randomStringLength.ts +72 -0
- package/src/internal/_stringLength.ts +5 -0
- package/src/internal/_validateReport.ts +5 -1
- package/src/internal/private/__notationRename.ts +24 -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/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/src/internal/private/__notationCapitalize.ts +0 -2
- package/src/internal/private/__notationUnsnake.ts +0 -24
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestCompareUnionDiscriminationTransform pins compare.equals over a union of
|
|
11
|
+
// object types (issue #2214).
|
|
12
|
+
//
|
|
13
|
+
// CompareEqualProgrammer.schema assembled an object union as a flat OR of member
|
|
14
|
+
// comparators (`_eo0(x,y) || _eo1(x,y) || ...`) with no discrimination. A wrong
|
|
15
|
+
// member's comparator matched spuriously: its constant discriminant passed via
|
|
16
|
+
// the always-prepended `x.type === y.type` branch (both agree, even when neither
|
|
17
|
+
// is that member) and its absent payload keys compared `undefined === undefined`.
|
|
18
|
+
// So `equals({type:"a",x:1}, {type:"a",x:2})` was `true` for two distinct
|
|
19
|
+
// references. Every other object-union programmer (is/clone/classify/prune/json/
|
|
20
|
+
// notations/protobuf) discriminates so a member comparator only runs for the
|
|
21
|
+
// member both values actually are. `equals` must do the same: decide which member
|
|
22
|
+
// each operand is, return false if they differ, and compare within the one shared
|
|
23
|
+
// member — and must agree with `is` on membership.
|
|
24
|
+
//
|
|
25
|
+
// All fixtures compare DISTINCT references (fresh object literals) so the
|
|
26
|
+
// `x === y` identity fast path never hides the flaw.
|
|
27
|
+
//
|
|
28
|
+
// 1. Transform is + compare.createEquals over discriminated, non-discriminated
|
|
29
|
+
// disjoint, narrower-masks-wider, 3-member, array/union-member, and nested
|
|
30
|
+
// object unions, plus primitive/array-union and non-union controls.
|
|
31
|
+
// 2. Require distinct-but-different pairs to compare not-equal, distinct-but-
|
|
32
|
+
// identical pairs to compare equal, and equals to imply is on both operands.
|
|
33
|
+
// 3. Require primitive/array unions and non-union objects to be unchanged.
|
|
34
|
+
func TestCompareUnionDiscriminationTransform(t *testing.T) {
|
|
35
|
+
project := compareUnionDiscriminationProject(t)
|
|
36
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
37
|
+
return runTransform([]string{
|
|
38
|
+
"--cwd", project,
|
|
39
|
+
"--tsconfig", "tsconfig.json",
|
|
40
|
+
"--file", "src/main.ts",
|
|
41
|
+
"--output", "js",
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
if code != 0 {
|
|
45
|
+
t.Fatalf("compare union discrimination transform failed: code=%d stderr=\n%s", code, errText)
|
|
46
|
+
}
|
|
47
|
+
compareUnionDiscriminationRunRuntimeCases(t, project, out)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func compareUnionDiscriminationProject(t *testing.T) string {
|
|
51
|
+
t.Helper()
|
|
52
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
53
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
54
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
55
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
56
|
+
}
|
|
57
|
+
dir, err := os.MkdirTemp(base, "compare-union-disc-")
|
|
58
|
+
if err != nil {
|
|
59
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
60
|
+
}
|
|
61
|
+
t.Cleanup(func() {
|
|
62
|
+
_ = os.RemoveAll(dir)
|
|
63
|
+
})
|
|
64
|
+
src := filepath.Join(dir, "src")
|
|
65
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
66
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
67
|
+
}
|
|
68
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareUnionDiscriminationTSConfig), 0o644); err != nil {
|
|
69
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
70
|
+
}
|
|
71
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareUnionDiscriminationSource), 0o644); err != nil {
|
|
72
|
+
t.Fatalf("write source: %v", err)
|
|
73
|
+
}
|
|
74
|
+
return dir
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
func compareUnionDiscriminationRunRuntimeCases(t *testing.T, project string, js string) {
|
|
78
|
+
t.Helper()
|
|
79
|
+
node, err := exec.LookPath("node")
|
|
80
|
+
if err != nil {
|
|
81
|
+
t.Skip("node executable not found")
|
|
82
|
+
}
|
|
83
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
84
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
85
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
86
|
+
}
|
|
87
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
88
|
+
runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
|
|
89
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
90
|
+
t.Fatalf("write runtime module: %v", err)
|
|
91
|
+
}
|
|
92
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
93
|
+
if err := os.WriteFile(runner, []byte(compareUnionDiscriminationRuntimeRunner), 0o644); err != nil {
|
|
94
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
95
|
+
}
|
|
96
|
+
cmd := exec.Command(node, runner)
|
|
97
|
+
cmd.Dir = runtimeDir
|
|
98
|
+
output, err := cmd.CombinedOutput()
|
|
99
|
+
if err != nil {
|
|
100
|
+
t.Fatalf("compare union discrimination runtime cases failed: %v\n%s", err, output)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const compareUnionDiscriminationTSConfig = `{
|
|
105
|
+
"compilerOptions": {
|
|
106
|
+
"target": "ES2022",
|
|
107
|
+
"module": "commonjs",
|
|
108
|
+
"moduleResolution": "bundler",
|
|
109
|
+
"ignoreDeprecations": "6.0",
|
|
110
|
+
"types": ["*"],
|
|
111
|
+
"esModuleInterop": true,
|
|
112
|
+
"strict": true,
|
|
113
|
+
"skipLibCheck": true
|
|
114
|
+
},
|
|
115
|
+
"include": ["src"]
|
|
116
|
+
}
|
|
117
|
+
`
|
|
118
|
+
|
|
119
|
+
const compareUnionDiscriminationSource = `import typia from "typia";
|
|
120
|
+
|
|
121
|
+
// 1. discriminated union
|
|
122
|
+
type Disc = { type: "a"; x: number } | { type: "b"; y: string };
|
|
123
|
+
export const isDisc = typia.createIs<Disc>();
|
|
124
|
+
export const eqDisc = typia.compare.createEquals<Disc>();
|
|
125
|
+
|
|
126
|
+
// 2. non-discriminated union with disjoint keys
|
|
127
|
+
type Disjoint = { x: number } | { y: string };
|
|
128
|
+
export const isDisjoint = typia.createIs<Disjoint>();
|
|
129
|
+
export const eqDisjoint = typia.compare.createEquals<Disjoint>();
|
|
130
|
+
|
|
131
|
+
// 3. narrower-masks-wider
|
|
132
|
+
type Mask = { a: number } | { a: number; b: string };
|
|
133
|
+
export const isMask = typia.createIs<Mask>();
|
|
134
|
+
export const eqMask = typia.compare.createEquals<Mask>();
|
|
135
|
+
|
|
136
|
+
// 4. three-member discriminated union
|
|
137
|
+
type Three =
|
|
138
|
+
| { type: "a"; x: number }
|
|
139
|
+
| { type: "b"; y: string }
|
|
140
|
+
| { type: "c"; z: boolean };
|
|
141
|
+
export const isThree = typia.createIs<Three>();
|
|
142
|
+
export const eqThree = typia.compare.createEquals<Three>();
|
|
143
|
+
|
|
144
|
+
// 5. a member whose payload is itself an array / element union
|
|
145
|
+
type ArrMember =
|
|
146
|
+
| { kind: "multi"; values: (number | string)[] }
|
|
147
|
+
| { kind: "single"; value: number };
|
|
148
|
+
export const isArrMember = typia.createIs<ArrMember>();
|
|
149
|
+
export const eqArrMember = typia.compare.createEquals<ArrMember>();
|
|
150
|
+
|
|
151
|
+
// 6. nested object-union property
|
|
152
|
+
type Nested = { wrap: { type: "a"; x: number } | { type: "b"; y: string } };
|
|
153
|
+
export const isNested = typia.createIs<Nested>();
|
|
154
|
+
export const eqNested = typia.compare.createEquals<Nested>();
|
|
155
|
+
|
|
156
|
+
// 7. recursive discriminated union (exercises _vctx capture through the IIFE)
|
|
157
|
+
type Tree =
|
|
158
|
+
| { type: "leaf"; value: number }
|
|
159
|
+
| { type: "node"; left: Tree; right: Tree };
|
|
160
|
+
export const isTree = typia.createIs<Tree>();
|
|
161
|
+
export const eqTree = typia.compare.createEquals<Tree>();
|
|
162
|
+
|
|
163
|
+
// 8. native alongside a discriminated object union (notNatives guard + ladder)
|
|
164
|
+
type WithNative = Date | { kind: "a"; x: number } | { kind: "b"; y: string };
|
|
165
|
+
export const eqWithNative = typia.compare.createEquals<WithNative>();
|
|
166
|
+
|
|
167
|
+
// control: a native unioned with a SINGLE object keeps the flat guarded branch
|
|
168
|
+
type DateOrStamp = Date | { timestamp: number };
|
|
169
|
+
export const eqDateStamp = typia.compare.createEquals<DateOrStamp>();
|
|
170
|
+
|
|
171
|
+
// controls: primitive union, array union, non-union object
|
|
172
|
+
export const eqPrim = typia.compare.createEquals<string | number>();
|
|
173
|
+
export const eqArrUnion = typia.compare.createEquals<number[] | string[]>();
|
|
174
|
+
export const eqObj = typia.compare.createEquals<{ a: number; b: string }>();
|
|
175
|
+
`
|
|
176
|
+
|
|
177
|
+
const compareUnionDiscriminationRuntimeRunner = `const mod = require("./main.cjs");
|
|
178
|
+
|
|
179
|
+
let failures = 0;
|
|
180
|
+
const expect = (label, actual, expected) => {
|
|
181
|
+
if (actual !== expected) {
|
|
182
|
+
console.log("FAIL " + label + ": expected " + expected + ", got " + actual);
|
|
183
|
+
failures++;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// --- 1. discriminated union: {type:"a";x} | {type:"b";y} ---
|
|
188
|
+
expect("disc a distinct-different", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
|
|
189
|
+
expect("disc b distinct-different", mod.eqDisc({ type: "b", y: "p" }, { type: "b", y: "q" }), false);
|
|
190
|
+
expect("disc a distinct-identical", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 1 }), true);
|
|
191
|
+
expect("disc b distinct-identical", mod.eqDisc({ type: "b", y: "p" }, { type: "b", y: "p" }), true);
|
|
192
|
+
expect("disc cross-arm a vs b", mod.eqDisc({ type: "a", x: 1 }, { type: "b", y: "p" }), false);
|
|
193
|
+
|
|
194
|
+
// --- 2. non-discriminated disjoint keys: {x} | {y} ---
|
|
195
|
+
expect("disjoint x distinct-different", mod.eqDisjoint({ x: 1 }, { x: 2 }), false);
|
|
196
|
+
expect("disjoint y distinct-different", mod.eqDisjoint({ y: "p" }, { y: "q" }), false);
|
|
197
|
+
expect("disjoint x distinct-identical", mod.eqDisjoint({ x: 1 }, { x: 1 }), true);
|
|
198
|
+
expect("disjoint cross-arm x vs y", mod.eqDisjoint({ x: 1 }, { y: "p" }), false);
|
|
199
|
+
|
|
200
|
+
// --- 3. narrower-masks-wider: {a} | {a,b} ---
|
|
201
|
+
expect("mask wider distinct-different", mod.eqMask({ a: 1, b: "x" }, { a: 1, b: "y" }), false);
|
|
202
|
+
expect("mask narrower distinct-identical", mod.eqMask({ a: 1 }, { a: 1 }), true);
|
|
203
|
+
expect("mask wider distinct-identical", mod.eqMask({ a: 1, b: "x" }, { a: 1, b: "x" }), true);
|
|
204
|
+
expect("mask narrower vs wider", mod.eqMask({ a: 1 }, { a: 1, b: "x" }), false);
|
|
205
|
+
|
|
206
|
+
// --- 4. three-member ---
|
|
207
|
+
expect("three a-different", mod.eqThree({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
|
|
208
|
+
expect("three b-different", mod.eqThree({ type: "b", y: "p" }, { type: "b", y: "q" }), false);
|
|
209
|
+
expect("three c-different", mod.eqThree({ type: "c", z: true }, { type: "c", z: false }), false);
|
|
210
|
+
expect("three c-identical", mod.eqThree({ type: "c", z: true }, { type: "c", z: true }), true);
|
|
211
|
+
expect("three cross a vs c", mod.eqThree({ type: "a", x: 1 }, { type: "c", z: true }), false);
|
|
212
|
+
|
|
213
|
+
// --- 5. array/element-union member ---
|
|
214
|
+
expect("arrmember multi different length", mod.eqArrMember({ kind: "multi", values: [1, 2] }, { kind: "multi", values: [1] }), false);
|
|
215
|
+
expect("arrmember multi different elem", mod.eqArrMember({ kind: "multi", values: [1, "a"] }, { kind: "multi", values: [1, "b"] }), false);
|
|
216
|
+
expect("arrmember multi identical", mod.eqArrMember({ kind: "multi", values: [1, "a"] }, { kind: "multi", values: [1, "a"] }), true);
|
|
217
|
+
expect("arrmember single different", mod.eqArrMember({ kind: "single", value: 1 }, { kind: "single", value: 2 }), false);
|
|
218
|
+
expect("arrmember cross multi vs single", mod.eqArrMember({ kind: "multi", values: [1] }, { kind: "single", value: 1 }), false);
|
|
219
|
+
|
|
220
|
+
// --- 6. nested object-union property ---
|
|
221
|
+
expect("nested inner different", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "a", x: 2 } }), false);
|
|
222
|
+
expect("nested inner identical", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "a", x: 1 } }), true);
|
|
223
|
+
expect("nested cross arm", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "b", y: "p" } }), false);
|
|
224
|
+
|
|
225
|
+
// --- controls: primitive / array unions, non-union object ---
|
|
226
|
+
expect("prim number-different", mod.eqPrim(1, 2), false);
|
|
227
|
+
expect("prim string-identical", mod.eqPrim("x", "x"), true);
|
|
228
|
+
expect("prim cross string vs number", mod.eqPrim("1", 1), false);
|
|
229
|
+
expect("arrunion number-different", mod.eqArrUnion([1, 2], [1, 3]), false);
|
|
230
|
+
expect("arrunion number-identical", mod.eqArrUnion([1, 2], [1, 2]), true);
|
|
231
|
+
expect("arrunion string-identical", mod.eqArrUnion(["a"], ["a"]), true);
|
|
232
|
+
expect("obj different", mod.eqObj({ a: 1, b: "x" }, { a: 1, b: "y" }), false);
|
|
233
|
+
expect("obj identical", mod.eqObj({ a: 1, b: "x" }, { a: 1, b: "x" }), true);
|
|
234
|
+
|
|
235
|
+
// --- recursive discriminated union (distinct references throughout) ---
|
|
236
|
+
const mkTree = () => ({ type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 2 } });
|
|
237
|
+
expect("tree identical", mod.eqTree(mkTree(), mkTree()), true);
|
|
238
|
+
expect("tree leaf value differs", mod.eqTree({ type: "leaf", value: 1 }, { type: "leaf", value: 2 }), false);
|
|
239
|
+
expect("tree deep differs", mod.eqTree(mkTree(), { type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 9 } }), false);
|
|
240
|
+
expect("tree leaf vs node", mod.eqTree({ type: "leaf", value: 1 }, mkTree()), false);
|
|
241
|
+
expect("tree shape differs", mod.eqTree({ type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 2 } }, { type: "node", left: { type: "leaf", value: 1 }, right: { type: "node", left: { type: "leaf", value: 2 }, right: { type: "leaf", value: 3 } } }), false);
|
|
242
|
+
|
|
243
|
+
// --- native alongside a discriminated object union ---
|
|
244
|
+
expect("withnative same date", mod.eqWithNative(new Date(0), new Date(0)), true);
|
|
245
|
+
expect("withnative diff date", mod.eqWithNative(new Date(0), new Date(5000)), false);
|
|
246
|
+
expect("withnative obj a different", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "a", x: 2 }), false);
|
|
247
|
+
expect("withnative obj a identical", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "a", x: 1 }), true);
|
|
248
|
+
expect("withnative date vs obj", mod.eqWithNative(new Date(0), { kind: "a", x: 1 }), false);
|
|
249
|
+
expect("withnative cross arm", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "b", y: "p" }), false);
|
|
250
|
+
|
|
251
|
+
// --- native unioned with a single object (control) ---
|
|
252
|
+
expect("datestamp same date", mod.eqDateStamp(new Date(0), new Date(0)), true);
|
|
253
|
+
expect("datestamp diff date", mod.eqDateStamp(new Date(0), new Date(5000)), false);
|
|
254
|
+
expect("datestamp stamp identical", mod.eqDateStamp({ timestamp: 5 }, { timestamp: 5 }), true);
|
|
255
|
+
expect("datestamp stamp different", mod.eqDateStamp({ timestamp: 5 }, { timestamp: 9 }), false);
|
|
256
|
+
expect("datestamp date vs stamp", mod.eqDateStamp(new Date(0), { timestamp: 0 }), false);
|
|
257
|
+
|
|
258
|
+
// --- equals must imply is on both operands (agree with is) ---
|
|
259
|
+
const discSamples = [
|
|
260
|
+
{ type: "a", x: 1 }, { type: "a", x: 2 }, { type: "b", y: "p" }, { type: "b", y: "q" },
|
|
261
|
+
];
|
|
262
|
+
for (const a of discSamples)
|
|
263
|
+
for (const b of discSamples) {
|
|
264
|
+
// fresh distinct references
|
|
265
|
+
const x = JSON.parse(JSON.stringify(a));
|
|
266
|
+
const y = JSON.parse(JSON.stringify(b));
|
|
267
|
+
if (mod.eqDisc(x, y)) {
|
|
268
|
+
expect("agree-is disc lhs " + JSON.stringify(a), mod.isDisc(x), true);
|
|
269
|
+
expect("agree-is disc rhs " + JSON.stringify(b), mod.isDisc(y), true);
|
|
270
|
+
// equal implies structurally same JSON
|
|
271
|
+
expect("equal implies same json " + JSON.stringify(a) + "|" + JSON.stringify(b), JSON.stringify(x) === JSON.stringify(y), true);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const maskSamples = [{ a: 1 }, { a: 1, b: "x" }, { a: 1, b: "y" }, { a: 2 }];
|
|
276
|
+
for (const a of maskSamples)
|
|
277
|
+
for (const b of maskSamples) {
|
|
278
|
+
const x = JSON.parse(JSON.stringify(a));
|
|
279
|
+
const y = JSON.parse(JSON.stringify(b));
|
|
280
|
+
if (mod.eqMask(x, y)) {
|
|
281
|
+
expect("agree-is mask same json " + JSON.stringify(a) + "|" + JSON.stringify(b), JSON.stringify(x) === JSON.stringify(y), true);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (failures > 0) {
|
|
286
|
+
throw new Error(failures + " assertion(s) failed");
|
|
287
|
+
}
|
|
288
|
+
console.log("all compare-union-discrimination cases passed");
|
|
289
|
+
`
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestEscapedPropertyKeyPathTransform verifies emits with hostile keys parse.
|
|
11
|
+
//
|
|
12
|
+
// Sole-literal property keys are folded into the emit as accessor path text, and
|
|
13
|
+
// no build step reads the file back, so a wrongly escaped key shipped as a
|
|
14
|
+
// broken artifact while ttsc still exited 0. A `"` in a key terminated the path
|
|
15
|
+
// string early and the emitted module stopped being JavaScript; a control
|
|
16
|
+
// character stayed raw and the reported path could not be parsed. Only running
|
|
17
|
+
// node against a real emit can catch that, which is why this asserts on the
|
|
18
|
+
// transform output rather than on the factory in isolation.
|
|
19
|
+
//
|
|
20
|
+
// 1. Transform a fixture whose keys carry quotes, backslashes, and control
|
|
21
|
+
// characters.
|
|
22
|
+
// 2. Assert node --check accepts the emitted module as JavaScript.
|
|
23
|
+
// 3. Execute it and assert each reported path is the accessor JSON.stringify
|
|
24
|
+
// defines for that key, which is what the runtime helper produces for
|
|
25
|
+
// dynamic keys.
|
|
26
|
+
func TestEscapedPropertyKeyPathTransform(t *testing.T) {
|
|
27
|
+
project := escapedPropertyKeyPathProject(t)
|
|
28
|
+
js := escapedPropertyKeyPathTransform(t, project)
|
|
29
|
+
escapedPropertyKeyPathCheckSyntax(t, project, js)
|
|
30
|
+
escapedPropertyKeyPathRunRuntimeCases(t, project, js)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
func escapedPropertyKeyPathProject(t *testing.T) string {
|
|
34
|
+
t.Helper()
|
|
35
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
36
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
37
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
38
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
39
|
+
}
|
|
40
|
+
dir, err := os.MkdirTemp(base, "escaped-property-key-path-")
|
|
41
|
+
if err != nil {
|
|
42
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
43
|
+
}
|
|
44
|
+
t.Cleanup(func() {
|
|
45
|
+
_ = os.RemoveAll(dir)
|
|
46
|
+
})
|
|
47
|
+
src := filepath.Join(dir, "src")
|
|
48
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
49
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
50
|
+
}
|
|
51
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(escapedPropertyKeyPathTSConfig), 0o644); err != nil {
|
|
52
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
53
|
+
}
|
|
54
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(escapedPropertyKeyPathSource), 0o644); err != nil {
|
|
55
|
+
t.Fatalf("write source: %v", err)
|
|
56
|
+
}
|
|
57
|
+
return dir
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
func escapedPropertyKeyPathTransform(t *testing.T, project string) string {
|
|
61
|
+
t.Helper()
|
|
62
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
63
|
+
return runTransform([]string{
|
|
64
|
+
"--cwd", project,
|
|
65
|
+
"--tsconfig", "tsconfig.json",
|
|
66
|
+
"--file", "src/main.ts",
|
|
67
|
+
"--output", "js",
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
if code != 0 {
|
|
71
|
+
t.Fatalf("escaped property key transform failed: code=%d stderr=\n%s", code, errText)
|
|
72
|
+
}
|
|
73
|
+
return out
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// escapedPropertyKeyPathCheckSyntax runs node against the emit exactly as it
|
|
77
|
+
// would ship. node --check only parses, so the unresolved typia imports in the
|
|
78
|
+
// untouched output do not matter, and that keeps this a check of the real
|
|
79
|
+
// artifact rather than of a rewritten copy.
|
|
80
|
+
func escapedPropertyKeyPathCheckSyntax(t *testing.T, project string, js string) {
|
|
81
|
+
t.Helper()
|
|
82
|
+
node, err := exec.LookPath("node")
|
|
83
|
+
if err != nil {
|
|
84
|
+
t.Skip("node executable not found")
|
|
85
|
+
}
|
|
86
|
+
emitted := filepath.Join(project, "emitted.cjs")
|
|
87
|
+
if err := os.WriteFile(emitted, []byte(js), 0o644); err != nil {
|
|
88
|
+
t.Fatalf("write emitted module: %v", err)
|
|
89
|
+
}
|
|
90
|
+
if output, err := exec.Command(node, "--check", emitted).CombinedOutput(); err != nil {
|
|
91
|
+
t.Fatalf("emitted module is not valid JavaScript: %v\n%s\n--- emit ---\n%s", err, output, js)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
func escapedPropertyKeyPathRunRuntimeCases(t *testing.T, project string, js string) {
|
|
96
|
+
t.Helper()
|
|
97
|
+
node, err := exec.LookPath("node")
|
|
98
|
+
if err != nil {
|
|
99
|
+
t.Skip("node executable not found")
|
|
100
|
+
}
|
|
101
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
102
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
103
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
104
|
+
}
|
|
105
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
106
|
+
runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
|
|
107
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
108
|
+
t.Fatalf("write runtime module: %v", err)
|
|
109
|
+
}
|
|
110
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
111
|
+
if err := os.WriteFile(runner, []byte(escapedPropertyKeyPathRuntimeRunner), 0o644); err != nil {
|
|
112
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
113
|
+
}
|
|
114
|
+
cmd := exec.Command(node, runner)
|
|
115
|
+
cmd.Dir = project
|
|
116
|
+
if output, err := cmd.CombinedOutput(); err != nil {
|
|
117
|
+
t.Fatalf("escaped property key runtime cases failed: %v\n%s", err, output)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const escapedPropertyKeyPathTSConfig = `{
|
|
122
|
+
"compilerOptions": {
|
|
123
|
+
"target": "ES2022",
|
|
124
|
+
"module": "commonjs",
|
|
125
|
+
"moduleResolution": "bundler",
|
|
126
|
+
"ignoreDeprecations": "6.0",
|
|
127
|
+
"types": ["*"],
|
|
128
|
+
"esModuleInterop": true,
|
|
129
|
+
"strict": true,
|
|
130
|
+
"skipLibCheck": true
|
|
131
|
+
},
|
|
132
|
+
"include": ["src"]
|
|
133
|
+
}
|
|
134
|
+
`
|
|
135
|
+
|
|
136
|
+
const escapedPropertyKeyPathSource = `import typia from "typia";
|
|
137
|
+
|
|
138
|
+
interface IHostileKeys {
|
|
139
|
+
"quote\"key": number;
|
|
140
|
+
"back\\slash": number;
|
|
141
|
+
"line\nbreak": number;
|
|
142
|
+
"tab\tkey": number;
|
|
143
|
+
"bell\u0007key": number;
|
|
144
|
+
"nul\u0000key": number;
|
|
145
|
+
"sep\u2028key": number;
|
|
146
|
+
"plain-key": number;
|
|
147
|
+
plainIdentifier: number;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const KEYS: string[] = [
|
|
151
|
+
"quote\"key",
|
|
152
|
+
"back\\slash",
|
|
153
|
+
"line\nbreak",
|
|
154
|
+
"tab\tkey",
|
|
155
|
+
"bell\u0007key",
|
|
156
|
+
"nul\u0000key",
|
|
157
|
+
"sep\u2028key",
|
|
158
|
+
"plain-key",
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
const validateHostile = typia.createValidate<IHostileKeys>();
|
|
162
|
+
|
|
163
|
+
export const run = () => {
|
|
164
|
+
const input: Record<string, unknown> = { plainIdentifier: 1 };
|
|
165
|
+
for (const key of KEYS) input[key] = "not a number";
|
|
166
|
+
return validateHostile(input);
|
|
167
|
+
};
|
|
168
|
+
`
|
|
169
|
+
|
|
170
|
+
// The expected path is rebuilt with JSON.stringify rather than written out
|
|
171
|
+
// literally, because that is the contract _accessExpressionAsString implements
|
|
172
|
+
// for dynamic keys and the compile-time fold must agree with it.
|
|
173
|
+
const escapedPropertyKeyPathRuntimeRunner = `const mod = require("./main.cjs");
|
|
174
|
+
const result = mod.run();
|
|
175
|
+
|
|
176
|
+
if (result.success !== false) {
|
|
177
|
+
throw new Error("validate accepted non-number values");
|
|
178
|
+
}
|
|
179
|
+
for (const key of mod.KEYS) {
|
|
180
|
+
const expected = "$input[" + JSON.stringify(key) + "]";
|
|
181
|
+
const found = result.errors.find((error) => error.path === expected);
|
|
182
|
+
if (!found) {
|
|
183
|
+
throw new Error(
|
|
184
|
+
"missing path for key " + JSON.stringify(key) +
|
|
185
|
+
": expected " + JSON.stringify(expected) +
|
|
186
|
+
", got " + JSON.stringify(result.errors.map((error) => error.path)),
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (result.errors.some((error) => error.path === "$input.plainIdentifier")) {
|
|
191
|
+
throw new Error("identifier fast path reported an error for a valid value");
|
|
192
|
+
}
|
|
193
|
+
`
|