typia 13.1.0 → 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 +134 -7
- 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/js_doc_link_text_test.go +69 -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
|
@@ -357,8 +357,10 @@ func iterate_metadata_intersection_is_symbol_key(key *schemametadata.MetadataSch
|
|
|
357
357
|
// name is a computed `symbol` member. The TypeScript checker prefixes such names
|
|
358
358
|
// with a 0xFE byte (`InternalSymbolNamePrefix`), an invalid UTF-8 lead unit that
|
|
359
359
|
// never begins a real string property name. This runs on the raw checker symbol
|
|
360
|
-
// name (`is_removable_object_constraint
|
|
361
|
-
//
|
|
360
|
+
// name (`is_removable_object_constraint`, and the member filter in
|
|
361
|
+
// `Emplace_metadata_object` that keeps such a member out of the validated shape)
|
|
362
|
+
// as well as the metadata key literal (`is_symbol_key`), so the type-level,
|
|
363
|
+
// member-level, and schema-level checks all agree on what a symbol key is.
|
|
362
364
|
func iterate_metadata_intersection_is_symbol_name(name string) bool {
|
|
363
365
|
return len(name) != 0 && name[0] == 0xFE
|
|
364
366
|
}
|
|
@@ -490,7 +492,7 @@ func iterate_metadata_intersection_is_removable_object_constraint(
|
|
|
490
492
|
return false
|
|
491
493
|
}
|
|
492
494
|
for _, generic := range iterate_metadata_native_generics {
|
|
493
|
-
if strings.HasPrefix(name, generic.Name) {
|
|
495
|
+
if name == generic.Name || strings.HasPrefix(name, generic.Name+"<") {
|
|
494
496
|
return false
|
|
495
497
|
}
|
|
496
498
|
}
|
|
@@ -563,7 +565,7 @@ func iterate_metadata_intersection_identify(
|
|
|
563
565
|
return iterate_metadata_intersection_identity{Kind: "native", Name: name}
|
|
564
566
|
}
|
|
565
567
|
for _, generic := range iterate_metadata_native_generics {
|
|
566
|
-
if strings.HasPrefix(name, generic.Name) {
|
|
568
|
+
if name == generic.Name || strings.HasPrefix(name, generic.Name+"<") {
|
|
567
569
|
return iterate_metadata_intersection_identity{Kind: "native", Name: generic.Name}
|
|
568
570
|
}
|
|
569
571
|
}
|
|
@@ -678,7 +680,7 @@ func iterate_metadata_intersection_is_plain_object_only(
|
|
|
678
680
|
return false
|
|
679
681
|
}
|
|
680
682
|
for _, generic := range iterate_metadata_native_generics {
|
|
681
|
-
if strings.HasPrefix(name, generic.Name) {
|
|
683
|
+
if name == generic.Name || strings.HasPrefix(name, generic.Name+"<") {
|
|
682
684
|
return false
|
|
683
685
|
}
|
|
684
686
|
}
|
|
@@ -987,7 +989,7 @@ func iterate_metadata_intersection_category(
|
|
|
987
989
|
return "native:" + name
|
|
988
990
|
}
|
|
989
991
|
for _, generic := range iterate_metadata_native_generics {
|
|
990
|
-
if strings.HasPrefix(name, generic.Name) {
|
|
992
|
+
if name == generic.Name || strings.HasPrefix(name, generic.Name+"<") {
|
|
991
993
|
return "object"
|
|
992
994
|
}
|
|
993
995
|
}
|
|
@@ -10,6 +10,15 @@ func Iterate_metadata_map(props IMetadataIteratorProps) bool {
|
|
|
10
10
|
if metadata_type_symbol_base_name(typ) != "Map" {
|
|
11
11
|
return false
|
|
12
12
|
}
|
|
13
|
+
// Classify the native Map only when the type actually is the built-in, not
|
|
14
|
+
// merely a user type of the same name. A real Map is declared in a `.d.ts`
|
|
15
|
+
// library, so a module-scoped user `interface Map<K, V> { brandMap; ... }` in a
|
|
16
|
+
// `.ts` module falls through to the structural object path and is validated
|
|
17
|
+
// against its own members instead of `input instanceof Map` — the collection
|
|
18
|
+
// half of the #2200 identity gate (#2212).
|
|
19
|
+
if !metadata_symbol_from_declaration_file(typ.Symbol()) {
|
|
20
|
+
return false
|
|
21
|
+
}
|
|
13
22
|
generic := metadata_get_type_arguments(props.Checker, typ)
|
|
14
23
|
if len(generic) != 2 {
|
|
15
24
|
return false
|
|
@@ -3,24 +3,49 @@ package metadata
|
|
|
3
3
|
import (
|
|
4
4
|
"strings"
|
|
5
5
|
|
|
6
|
+
nativeast "github.com/microsoft/typescript-go/shim/ast"
|
|
6
7
|
schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
7
8
|
)
|
|
8
9
|
|
|
9
10
|
func Iterate_metadata_native(props IMetadataIteratorProps) bool {
|
|
11
|
+
var symbol *nativeast.Symbol
|
|
10
12
|
name := ""
|
|
11
13
|
if props.Type != nil {
|
|
14
|
+
symbol = props.Type.Symbol()
|
|
12
15
|
name = metadata_type_symbol_base_name(props.Type)
|
|
13
16
|
}
|
|
14
17
|
if name == "" && props.Checker != nil && props.Type != nil {
|
|
15
|
-
|
|
18
|
+
apparent := props.Checker.GetApparentType(props.Type)
|
|
19
|
+
if apparent != nil {
|
|
20
|
+
symbol = apparent.Symbol()
|
|
21
|
+
}
|
|
22
|
+
name = metadata_type_symbol_base_name(apparent)
|
|
16
23
|
}
|
|
17
24
|
name = iterate_metadata_native_getNativeName(name)
|
|
18
25
|
if _, ok := iterate_metadata_native_simples[name]; ok {
|
|
26
|
+
// Match the built-in only when the type actually is the built-in, not merely
|
|
27
|
+
// a user type of the same name. A real native is declared in a `.d.ts`
|
|
28
|
+
// library, so a user `interface File { name; size }` in a `.ts` module falls
|
|
29
|
+
// through to the structural object path and is validated against its own
|
|
30
|
+
// members instead of `input instanceof File` (#2200).
|
|
31
|
+
if !metadata_symbol_from_declaration_file(symbol) {
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
19
34
|
iterate_metadata_native_take(props.Metadata, name)
|
|
20
35
|
return true
|
|
21
36
|
}
|
|
22
37
|
for _, generic := range iterate_metadata_native_generics {
|
|
23
|
-
if strings.HasPrefix(name, generic.Name) {
|
|
38
|
+
if name == generic.Name || strings.HasPrefix(name, generic.Name+"<") {
|
|
39
|
+
// Classify the native generic (WeakMap/WeakSet) only when the type
|
|
40
|
+
// actually is the built-in, not merely a user type of the same name. A
|
|
41
|
+
// real WeakMap/WeakSet is declared in a `.d.ts` library, so a module-scoped
|
|
42
|
+
// user `interface WeakMap<K, V> { brandWeak }` in a `.ts` module falls
|
|
43
|
+
// through to the structural object path — the same identity gate the
|
|
44
|
+
// simples path above uses (#2200), applied to the collection generics the
|
|
45
|
+
// `+"<"` arity guard (#2181) alone left ungated (#2212).
|
|
46
|
+
if !metadata_symbol_from_declaration_file(symbol) {
|
|
47
|
+
return false
|
|
48
|
+
}
|
|
24
49
|
iterate_metadata_native_take(props.Metadata, generic.Name)
|
|
25
50
|
return true
|
|
26
51
|
}
|
|
@@ -10,6 +10,15 @@ func Iterate_metadata_set(props IMetadataIteratorProps) bool {
|
|
|
10
10
|
if metadata_type_symbol_base_name(typ) != "Set" {
|
|
11
11
|
return false
|
|
12
12
|
}
|
|
13
|
+
// Classify the native Set only when the type actually is the built-in, not
|
|
14
|
+
// merely a user type of the same name. A real Set is declared in a `.d.ts`
|
|
15
|
+
// library, so a module-scoped user `interface Set<T> { brandSet; ... }` in a
|
|
16
|
+
// `.ts` module falls through to the structural object path and is validated
|
|
17
|
+
// against its own members instead of `input instanceof Set` — the collection
|
|
18
|
+
// half of the #2200 identity gate (#2212).
|
|
19
|
+
if !metadata_symbol_from_declaration_file(typ.Symbol()) {
|
|
20
|
+
return false
|
|
21
|
+
}
|
|
13
22
|
generic := metadata_get_type_arguments(props.Checker, typ)
|
|
14
23
|
if len(generic) != 1 {
|
|
15
24
|
return false
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
//go:build typia_native_internal
|
|
2
|
+
// +build typia_native_internal
|
|
3
|
+
|
|
4
|
+
package metadata
|
|
5
|
+
|
|
6
|
+
import (
|
|
7
|
+
"path/filepath"
|
|
8
|
+
"testing"
|
|
9
|
+
|
|
10
|
+
nativeast "github.com/microsoft/typescript-go/shim/ast"
|
|
11
|
+
nativecore "github.com/microsoft/typescript-go/shim/core"
|
|
12
|
+
nativeparser "github.com/microsoft/typescript-go/shim/parser"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
// TestJsDocLinkText verifies the metadata helper renders visible inline links.
|
|
16
|
+
//
|
|
17
|
+
// JSDoc link nodes split their entity target into Name() and their optional
|
|
18
|
+
// display label into Text(). This test pins the shared renderer directly so all
|
|
19
|
+
// metadata consumers keep qualified targets, normalized labels, call suffixes,
|
|
20
|
+
// URLs, and tag comments without depending only on an application-programmer
|
|
21
|
+
// integration.
|
|
22
|
+
//
|
|
23
|
+
// 1. Parse a property comment containing plain, qualified, labeled, URL, and
|
|
24
|
+
// unresolved and malformed links, empty labels, call suffixes, plus a link
|
|
25
|
+
// inside a JSDoc tag.
|
|
26
|
+
// 2. Reflect the property's description and tags through the metadata helpers.
|
|
27
|
+
// 3. Assert the visible text and punctuation are preserved deterministically.
|
|
28
|
+
func TestJsDocLinkText(t *testing.T) {
|
|
29
|
+
file := nativeparser.ParseSourceFile(
|
|
30
|
+
nativeast.SourceFileParseOptions{FileName: filepath.ToSlash(filepath.Join(t.TempDir(), "links.ts"))},
|
|
31
|
+
`interface ITarget {
|
|
32
|
+
value: string;
|
|
33
|
+
}
|
|
34
|
+
interface IBox {
|
|
35
|
+
/**
|
|
36
|
+
* Plain; {@link ITarget}; {@link ITarget.value};
|
|
37
|
+
* {@link ITarget | label}; {@linkcode ITarget};
|
|
38
|
+
* {@linkplain ITarget.value}; {@link MissingTarget};
|
|
39
|
+
* {@link https://example.com/docs}; {@link https://example.com/docs | docs}.
|
|
40
|
+
* {@link ITarget | }; {@link makeTarget()}; {@link makeTarget() | maker}.
|
|
41
|
+
* {@link Missing.};
|
|
42
|
+
* @title {@link ITarget titled target}
|
|
43
|
+
*/
|
|
44
|
+
field: string;
|
|
45
|
+
}
|
|
46
|
+
`,
|
|
47
|
+
nativecore.ScriptKindTS,
|
|
48
|
+
)
|
|
49
|
+
member := file.Statements.Nodes[1].AsInterfaceDeclaration().Members.Nodes[0]
|
|
50
|
+
symbol := &nativeast.Symbol{
|
|
51
|
+
Name: "field",
|
|
52
|
+
ValueDeclaration: member,
|
|
53
|
+
Declarations: []*nativeast.Node{member},
|
|
54
|
+
}
|
|
55
|
+
description := metadata_node_description(symbol)
|
|
56
|
+
if description == nil {
|
|
57
|
+
t.Fatal("description was not reflected")
|
|
58
|
+
}
|
|
59
|
+
if *description != "Plain; ITarget; ITarget.value;\nlabel; ITarget;\nITarget.value; MissingTarget;\nhttps://example.com/docs; docs.\nITarget; makeTarget(); maker.\nMissing.;" {
|
|
60
|
+
t.Fatalf("unexpected description: %q", *description)
|
|
61
|
+
}
|
|
62
|
+
tags := metadata_node_js_doc_tags(symbol)
|
|
63
|
+
if len(tags) != 1 || tags[0].Name != "title" || len(tags[0].Text) != 1 || tags[0].Text[0].Text != "titled target" {
|
|
64
|
+
t.Fatalf("unexpected tags: %#v", tags)
|
|
65
|
+
}
|
|
66
|
+
if metadata_js_doc_link_text(nil) != "" {
|
|
67
|
+
t.Fatal("nil JSDoc link should render empty text")
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
package metadata
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"testing"
|
|
7
|
+
|
|
8
|
+
shimchecker "github.com/microsoft/typescript-go/shim/checker"
|
|
9
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
// TestMetadataTypeArgumentsPrecondition verifies reference-only extraction.
|
|
13
|
+
//
|
|
14
|
+
// The checker accepts GetTypeArguments only for object-reference types. The
|
|
15
|
+
// helper should identify that capability explicitly, return no arguments for a
|
|
16
|
+
// primitive, and preserve generic arguments for a real reference.
|
|
17
|
+
//
|
|
18
|
+
// 1. Load primitive and generic reference declarations through the checker.
|
|
19
|
+
// 2. Verify the primitive follows the unsupported-input fallback.
|
|
20
|
+
// 3. Verify the reference returns its sole string argument.
|
|
21
|
+
func TestMetadataTypeArgumentsPrecondition(t *testing.T) {
|
|
22
|
+
dir := t.TempDir()
|
|
23
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(`{
|
|
24
|
+
"compilerOptions": {
|
|
25
|
+
"target": "ES2022",
|
|
26
|
+
"module": "commonjs",
|
|
27
|
+
"moduleResolution": "bundler",
|
|
28
|
+
"ignoreDeprecations": "6.0",
|
|
29
|
+
"strict": true,
|
|
30
|
+
"skipLibCheck": true
|
|
31
|
+
},
|
|
32
|
+
"include": ["src"]
|
|
33
|
+
}`), 0o644); err != nil {
|
|
34
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
35
|
+
}
|
|
36
|
+
if err := os.MkdirAll(filepath.Join(dir, "src"), 0o755); err != nil {
|
|
37
|
+
t.Fatalf("mkdir src: %v", err)
|
|
38
|
+
}
|
|
39
|
+
if err := os.WriteFile(filepath.Join(dir, "src", "main.ts"), []byte(`
|
|
40
|
+
interface Box<T> { value: T; }
|
|
41
|
+
let primitive!: number;
|
|
42
|
+
let reference!: Box<string>;
|
|
43
|
+
`), 0o644); err != nil {
|
|
44
|
+
t.Fatalf("write source: %v", err)
|
|
45
|
+
}
|
|
46
|
+
program, diagnostics, err := driver.LoadProgram(dir, "tsconfig.json", driver.LoadProgramOptions{})
|
|
47
|
+
if err != nil {
|
|
48
|
+
t.Fatalf("load program: %v", err)
|
|
49
|
+
}
|
|
50
|
+
if len(diagnostics) != 0 {
|
|
51
|
+
t.Fatalf("fixture diagnostics: %+v", diagnostics)
|
|
52
|
+
}
|
|
53
|
+
defer program.Close()
|
|
54
|
+
|
|
55
|
+
source := program.SourceFile(filepath.Join(dir, "src", "main.ts"))
|
|
56
|
+
if source == nil || source.Statements == nil || len(source.Statements.Nodes) != 3 {
|
|
57
|
+
t.Fatal("fixture declarations were not loaded")
|
|
58
|
+
}
|
|
59
|
+
variableType := func(index int) *shimchecker.Type {
|
|
60
|
+
declaration := source.Statements.Nodes[index].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0]
|
|
61
|
+
return program.Checker.GetTypeAtLocation(declaration)
|
|
62
|
+
}
|
|
63
|
+
if args := metadata_get_type_arguments(program.Checker, variableType(1)); len(args) != 0 {
|
|
64
|
+
t.Fatalf("primitive type returned %d type arguments", len(args))
|
|
65
|
+
}
|
|
66
|
+
args := metadata_get_type_arguments(program.Checker, variableType(2))
|
|
67
|
+
if len(args) != 1 || program.Checker.TypeToString(args[0]) != "string" {
|
|
68
|
+
t.Fatalf("generic reference arguments mismatch: %#v", args)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -110,6 +110,23 @@ func TestMetadataCommentTagFactoryCoverage(t *testing.T) {
|
|
|
110
110
|
Tag schemametadata.IJsDocTagInfo
|
|
111
111
|
}{Report: report, Tag: tag})
|
|
112
112
|
}
|
|
113
|
+
decimalReportCount := len(reports)
|
|
114
|
+
decimal := metadataCommentTagFactory_parse(struct {
|
|
115
|
+
Report func(msg string) any
|
|
116
|
+
Tag schemametadata.IJsDocTagInfo
|
|
117
|
+
}{
|
|
118
|
+
Report: report,
|
|
119
|
+
Tag: schemametadata.IJsDocTagInfo{
|
|
120
|
+
Name: "multipleOf",
|
|
121
|
+
Text: []schemametadata.IJsDocTagInfo_IText{{Text: "0.01"}},
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
if len(reports) != decimalReportCount || len(decimal["number"]) != 1 || len(decimal["bigint"]) != 0 {
|
|
125
|
+
t.Fatalf("decimal multipleOf must remain a number-only JSDoc tag: %#v, reports=%#v", decimal, reports[decimalReportCount:])
|
|
126
|
+
}
|
|
127
|
+
if decimal["number"][0].Validate != "$importInternal(\"_isMultipleOf\")($input, 0.01)" {
|
|
128
|
+
t.Fatalf("decimal multipleOf must use the shared exact helper: %s", decimal["number"][0].Validate)
|
|
129
|
+
}
|
|
113
130
|
invalidBefore := len(reports)
|
|
114
131
|
_ = metadataCommentTagFactory_parse_number(struct {
|
|
115
132
|
Report func(msg string) any
|
|
@@ -193,6 +210,28 @@ func TestMetadataCommentTagFactoryCoverage(t *testing.T) {
|
|
|
193
210
|
if len(oppositeOnly.Atomics[0].Tags) == 0 {
|
|
194
211
|
t.Fatal("numeric comment tag should apply when only one numeric side exists")
|
|
195
212
|
}
|
|
213
|
+
decimalOnly := schemametadata.MetadataSchema_create(schemametadata.MetadataSchema{
|
|
214
|
+
Atomics: []*schemametadata.MetadataAtomic{
|
|
215
|
+
schemametadata.MetadataAtomic_create(schemametadata.MetadataAtomic{Type: "number"}),
|
|
216
|
+
},
|
|
217
|
+
})
|
|
218
|
+
decimalErrors := []MetadataFactory_IError{}
|
|
219
|
+
MetadataCommentTagFactory.Analyze(struct {
|
|
220
|
+
Errors *[]MetadataFactory_IError
|
|
221
|
+
Metadata *schemametadata.MetadataSchema
|
|
222
|
+
Tags []schemametadata.IJsDocTagInfo
|
|
223
|
+
Explore MetadataFactory_IExplore
|
|
224
|
+
}{
|
|
225
|
+
Errors: &decimalErrors,
|
|
226
|
+
Metadata: decimalOnly,
|
|
227
|
+
Tags: []schemametadata.IJsDocTagInfo{{
|
|
228
|
+
Name: "multipleOf",
|
|
229
|
+
Text: []schemametadata.IJsDocTagInfo_IText{{Text: "0.01"}},
|
|
230
|
+
}},
|
|
231
|
+
})
|
|
232
|
+
if len(decimalErrors) != 0 || len(decimalOnly.Atomics[0].Tags) != 1 {
|
|
233
|
+
t.Fatalf("decimal number JSDoc must analyze without bigint diagnostics: errors=%#v tags=%#v", decimalErrors, decimalOnly.Atomics[0].Tags)
|
|
234
|
+
}
|
|
196
235
|
|
|
197
236
|
empty := schemametadata.MetadataSchema_create(schemametadata.MetadataSchema{})
|
|
198
237
|
unsupportedErrors := []MetadataFactory_IError{}
|
package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
package factories
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"reflect"
|
|
5
|
+
"testing"
|
|
6
|
+
|
|
7
|
+
schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestMetadataCommentTagFactoryExclusivityMatchesInterface pins every JSDoc
|
|
11
|
+
// comment tag's `Exclusive` value to the @typia/interface declaration.
|
|
12
|
+
//
|
|
13
|
+
// The JSDoc path and the type-tag path both feed
|
|
14
|
+
// MetadataTypeTagFactory.Validate, which reads a tag's `Exclusive` list to
|
|
15
|
+
// reject forbidden combinations. The type-tag path takes that list straight
|
|
16
|
+
// from the interface declaration, but the comment factory used to hand-copy it
|
|
17
|
+
// per parser, and two copies drifted: `@format` published a bare `true` and
|
|
18
|
+
// `@pattern` published `["format"]` (missing its own kind), so `@pattern ^a`
|
|
19
|
+
// `@pattern ^b` compiled while `Pattern<...> & Pattern<...>` is a compile error.
|
|
20
|
+
// This test transcribes the authority once via
|
|
21
|
+
// metadataTypeTagFactoryTestDeclarations -- the same mirror the type-tag tests
|
|
22
|
+
// use -- and asserts the comment factory now produces the identical list.
|
|
23
|
+
//
|
|
24
|
+
// 1. Build the array-form authority (kind -> exclusive kinds) from the shared
|
|
25
|
+
// declaration mirror, and note the kinds that declare a bare `true`.
|
|
26
|
+
// 2. Parse one representative JSDoc comment per tag kind through the factory.
|
|
27
|
+
// 3. Assert the produced tag's kind and `Exclusive` match the authority exactly,
|
|
28
|
+
// so `@format`/`@pattern` carry `["format", "pattern"]` and no list drifts.
|
|
29
|
+
func TestMetadataCommentTagFactoryExclusivityMatchesInterface(t *testing.T) {
|
|
30
|
+
arrayForm := map[string][]string{}
|
|
31
|
+
for _, declaration := range metadataTypeTagFactoryTestDeclarations() {
|
|
32
|
+
arrayForm[declaration.kind] = declaration.exclusive
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
report := func(string) any { return nil }
|
|
36
|
+
cases := []struct {
|
|
37
|
+
tag string
|
|
38
|
+
text string
|
|
39
|
+
kind string
|
|
40
|
+
key string
|
|
41
|
+
}{
|
|
42
|
+
{tag: "minimum", text: "0", kind: "minimum", key: "number"},
|
|
43
|
+
{tag: "maximum", text: "10", kind: "maximum", key: "number"},
|
|
44
|
+
{tag: "exclusiveMinimum", text: "0", kind: "exclusiveMinimum", key: "number"},
|
|
45
|
+
{tag: "exclusiveMaximum", text: "10", kind: "exclusiveMaximum", key: "number"},
|
|
46
|
+
{tag: "format", text: "uuid", kind: "format", key: "string"},
|
|
47
|
+
{tag: "pattern", text: "^x$", kind: "pattern", key: "string"},
|
|
48
|
+
{tag: "multipleOf", text: "2", kind: "multipleOf", key: "number"},
|
|
49
|
+
{tag: "minItems", text: "1", kind: "minItems", key: "array"},
|
|
50
|
+
{tag: "maxItems", text: "2", kind: "maxItems", key: "array"},
|
|
51
|
+
{tag: "uniqueItems", text: "", kind: "uniqueItems", key: "array"},
|
|
52
|
+
{tag: "minLength", text: "1", kind: "minLength", key: "string"},
|
|
53
|
+
{tag: "maxLength", text: "2", kind: "maxLength", key: "string"},
|
|
54
|
+
{tag: "type", text: "int32", kind: "type", key: "number"},
|
|
55
|
+
}
|
|
56
|
+
for _, tuple := range cases {
|
|
57
|
+
info := schemametadata.IJsDocTagInfo{Name: tuple.tag}
|
|
58
|
+
if tuple.text != "" {
|
|
59
|
+
info.Text = []schemametadata.IJsDocTagInfo_IText{{Text: tuple.text}}
|
|
60
|
+
}
|
|
61
|
+
record := metadataCommentTagFactory_parse(struct {
|
|
62
|
+
Report func(msg string) any
|
|
63
|
+
Tag schemametadata.IJsDocTagInfo
|
|
64
|
+
}{Report: report, Tag: info})
|
|
65
|
+
tags := record[tuple.key]
|
|
66
|
+
if len(tags) == 0 {
|
|
67
|
+
t.Fatalf("@%s should produce a %q tag", tuple.tag, tuple.key)
|
|
68
|
+
}
|
|
69
|
+
produced := tags[0]
|
|
70
|
+
if produced.Kind != tuple.kind {
|
|
71
|
+
t.Fatalf("@%s should produce kind %q, got %q", tuple.tag, tuple.kind, produced.Kind)
|
|
72
|
+
}
|
|
73
|
+
var expected any = true
|
|
74
|
+
if list, ok := arrayForm[tuple.kind]; ok {
|
|
75
|
+
expected = list
|
|
76
|
+
}
|
|
77
|
+
if reflect.DeepEqual(produced.Exclusive, expected) == false {
|
|
78
|
+
t.Fatalf(
|
|
79
|
+
"@%s exclusive drifted from the interface authority: got %#v, want %#v",
|
|
80
|
+
tuple.tag, produced.Exclusive, expected,
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
package factories
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
|
|
6
|
+
schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// TestMetadataTypeTagFactoryAcceptsLegalTagCombinations verifies enforcing exclusivity rejects nothing a declaration permits.
|
|
10
|
+
//
|
|
11
|
+
// This is the negative twin of the rejection tests. Making an inert check fire
|
|
12
|
+
// is only correct if it fires on exactly the declared `exclusive` pairs: a check
|
|
13
|
+
// that over-matches would reject `Minimum<0> & Maximum<10>`, which neither tag's
|
|
14
|
+
// `exclusive` list names and which every bounded-range type depends on.
|
|
15
|
+
//
|
|
16
|
+
// 1. Combine each array-form tag with a kind absent from its exclusive list.
|
|
17
|
+
// 2. Combine bool-form tags of differing kinds, which the untouched branch owns.
|
|
18
|
+
// 3. Require every combination, and each tag alone, to validate.
|
|
19
|
+
func TestMetadataTypeTagFactoryAcceptsLegalTagCombinations(t *testing.T) {
|
|
20
|
+
declarations := metadataTypeTagFactoryTestDeclarations()
|
|
21
|
+
byKind := map[string]metadataTypeTagFactoryTestDeclaration{}
|
|
22
|
+
for _, declaration := range declarations {
|
|
23
|
+
byKind[declaration.kind] = declaration
|
|
24
|
+
success, messages := metadataTypeTagFactoryTestValidate(
|
|
25
|
+
declaration.target,
|
|
26
|
+
[]schemametadata.IMetadataTypeTag{declaration.tag("A")},
|
|
27
|
+
)
|
|
28
|
+
if success == false {
|
|
29
|
+
t.Fatalf("a lone %s tag must validate, reported %#v", declaration.kind, messages)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for _, pair := range [][2]string{
|
|
34
|
+
{"minimum", "maximum"},
|
|
35
|
+
{"minimum", "exclusiveMaximum"},
|
|
36
|
+
{"exclusiveMinimum", "maximum"},
|
|
37
|
+
{"exclusiveMinimum", "exclusiveMaximum"},
|
|
38
|
+
} {
|
|
39
|
+
left := byKind[pair[0]]
|
|
40
|
+
right := byKind[pair[1]]
|
|
41
|
+
success, messages := metadataTypeTagFactoryTestValidate(
|
|
42
|
+
left.target,
|
|
43
|
+
[]schemametadata.IMetadataTypeTag{left.tag("0"), right.tag("10")},
|
|
44
|
+
)
|
|
45
|
+
if success == false {
|
|
46
|
+
t.Fatalf("%s and %s bound opposite ends and must combine, reported %#v", pair[0], pair[1], messages)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
boolFormTarget := "string"
|
|
51
|
+
boolForm := []schemametadata.IMetadataTypeTag{
|
|
52
|
+
{Target: boolFormTarget, Name: "MinLength<3>", Kind: "minLength", Exclusive: true},
|
|
53
|
+
{Target: boolFormTarget, Name: "MaxLength<7>", Kind: "maxLength", Exclusive: true},
|
|
54
|
+
{Target: boolFormTarget, Name: "Format<\"uuid\">", Kind: "format", Exclusive: true},
|
|
55
|
+
}
|
|
56
|
+
success, messages := metadataTypeTagFactoryTestValidate(boolFormTarget, boolForm)
|
|
57
|
+
if success == false {
|
|
58
|
+
t.Fatalf("bool-form tags of differing kinds must combine, reported %#v", messages)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
package factories
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
|
|
6
|
+
schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// metadataTypeTagFactoryTestDeclaration mirrors one type tag declaration from
|
|
10
|
+
// `packages/interface/src/tags`, which is the specification the native check
|
|
11
|
+
// must enforce. `exclusive` names kinds, never tag names.
|
|
12
|
+
type metadataTypeTagFactoryTestDeclaration struct {
|
|
13
|
+
target string
|
|
14
|
+
kind string
|
|
15
|
+
exclusive []string
|
|
16
|
+
name string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// tag materializes the declaration as the metadata tag the factory receives.
|
|
20
|
+
func (d metadataTypeTagFactoryTestDeclaration) tag(value string) schemametadata.IMetadataTypeTag {
|
|
21
|
+
return schemametadata.IMetadataTypeTag{
|
|
22
|
+
Target: d.target,
|
|
23
|
+
Name: fmt.Sprintf(d.name, value),
|
|
24
|
+
Kind: d.kind,
|
|
25
|
+
Exclusive: d.exclusive,
|
|
26
|
+
Value: value,
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// metadataTypeTagFactoryTestDeclarations transcribes every array-form tag
|
|
31
|
+
// declaration, in the exact `kind` and `exclusive` shape each publishes:
|
|
32
|
+
//
|
|
33
|
+
// - Minimum kind "minimum" exclusive ["minimum", "exclusiveMinimum"]
|
|
34
|
+
// - Maximum kind "maximum" exclusive ["maximum", "exclusiveMaximum"]
|
|
35
|
+
// - ExclusiveMinimum kind "exclusiveMinimum" exclusive ["exclusiveMinimum", "minimum"]
|
|
36
|
+
// - ExclusiveMaximum kind "exclusiveMaximum" exclusive ["exclusiveMaximum", "maximum"]
|
|
37
|
+
// - Format kind "format" exclusive ["format", "pattern"]
|
|
38
|
+
// - Pattern kind "pattern" exclusive ["format", "pattern"]
|
|
39
|
+
//
|
|
40
|
+
// Each list names its own kind, so no tag may be duplicated, plus exactly one
|
|
41
|
+
// cross-kind partner.
|
|
42
|
+
func metadataTypeTagFactoryTestDeclarations() []metadataTypeTagFactoryTestDeclaration {
|
|
43
|
+
return []metadataTypeTagFactoryTestDeclaration{
|
|
44
|
+
{target: "number", kind: "minimum", exclusive: []string{"minimum", "exclusiveMinimum"}, name: "Minimum<%s>"},
|
|
45
|
+
{target: "number", kind: "maximum", exclusive: []string{"maximum", "exclusiveMaximum"}, name: "Maximum<%s>"},
|
|
46
|
+
{target: "number", kind: "exclusiveMinimum", exclusive: []string{"exclusiveMinimum", "minimum"}, name: "ExclusiveMinimum<%s>"},
|
|
47
|
+
{target: "number", kind: "exclusiveMaximum", exclusive: []string{"exclusiveMaximum", "maximum"}, name: "ExclusiveMaximum<%s>"},
|
|
48
|
+
{target: "string", kind: "format", exclusive: []string{"format", "pattern"}, name: "Format<%s>"},
|
|
49
|
+
{target: "string", kind: "pattern", exclusive: []string{"format", "pattern"}, name: "Pattern<%s>"},
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// metadataTypeTagFactoryTestReport collects the factory's validation messages.
|
|
54
|
+
func metadataTypeTagFactoryTestReport(messages *[]string) func(struct {
|
|
55
|
+
Property *string
|
|
56
|
+
Message string
|
|
57
|
+
}) bool {
|
|
58
|
+
return func(next struct {
|
|
59
|
+
Property *string
|
|
60
|
+
Message string
|
|
61
|
+
}) bool {
|
|
62
|
+
*messages = append(*messages, next.Message)
|
|
63
|
+
return false
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// metadataTypeTagFactoryTestValidate runs the factory check over one tag list.
|
|
68
|
+
func metadataTypeTagFactoryTestValidate(
|
|
69
|
+
target string,
|
|
70
|
+
tags []schemametadata.IMetadataTypeTag,
|
|
71
|
+
) (bool, []string) {
|
|
72
|
+
messages := []string{}
|
|
73
|
+
success := MetadataTypeTagFactory.Validate(struct {
|
|
74
|
+
Report func(struct {
|
|
75
|
+
Property *string
|
|
76
|
+
Message string
|
|
77
|
+
}) bool
|
|
78
|
+
Type string
|
|
79
|
+
Tags []schemametadata.IMetadataTypeTag
|
|
80
|
+
}{
|
|
81
|
+
Report: metadataTypeTagFactoryTestReport(&messages),
|
|
82
|
+
Type: target,
|
|
83
|
+
Tags: tags,
|
|
84
|
+
})
|
|
85
|
+
return success, messages
|
|
86
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package factories
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"strings"
|
|
5
|
+
"testing"
|
|
6
|
+
|
|
7
|
+
schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestMetadataTypeTagFactoryKeepsBoolFormExclusivity verifies the bool-form exclusivity branch still rejects a duplicated kind.
|
|
11
|
+
//
|
|
12
|
+
// The bool branch was never broken; it is the working neighbor of the inert
|
|
13
|
+
// array-form branch and shares the same loop and reporting path. Repairing the
|
|
14
|
+
// array-form branch must not disturb it, so this pins its behavior in both
|
|
15
|
+
// directions independently of the array-form tests.
|
|
16
|
+
//
|
|
17
|
+
// 1. Duplicate a bool-form kind and require rejection naming the kind.
|
|
18
|
+
// 2. Require an opted-out `exclusive: false` tag to permit its own duplicate.
|
|
19
|
+
func TestMetadataTypeTagFactoryKeepsBoolFormExclusivity(t *testing.T) {
|
|
20
|
+
success, messages := metadataTypeTagFactoryTestValidate("string", []schemametadata.IMetadataTypeTag{
|
|
21
|
+
{Target: "string", Name: "Format<\"uuid\">", Kind: "format", Exclusive: true},
|
|
22
|
+
{Target: "string", Name: "Format<\"email\">", Kind: "format", Exclusive: true},
|
|
23
|
+
})
|
|
24
|
+
if success {
|
|
25
|
+
t.Fatal("a duplicated bool-form kind must be rejected")
|
|
26
|
+
}
|
|
27
|
+
if len(messages) != 1 || strings.Contains(messages[0], "format") == false {
|
|
28
|
+
t.Fatalf("the bool-form duplication report must name the kind, reported %#v", messages)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
success, messages = metadataTypeTagFactoryTestValidate("string", []schemametadata.IMetadataTypeTag{
|
|
32
|
+
{Target: "string", Name: "Example<\"first\">", Kind: "example", Exclusive: false},
|
|
33
|
+
{Target: "string", Name: "Example<\"second\">", Kind: "example", Exclusive: false},
|
|
34
|
+
})
|
|
35
|
+
if success == false {
|
|
36
|
+
t.Fatalf("a tag opting out of exclusivity must permit its own duplicate, reported %#v", messages)
|
|
37
|
+
}
|
|
38
|
+
}
|
package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
package factories
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"strings"
|
|
5
|
+
"testing"
|
|
6
|
+
|
|
7
|
+
schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestMetadataTypeTagFactoryRejectsCrossKindExclusiveTags verifies each array-form tag rejects the cross-kind partner it declares.
|
|
11
|
+
//
|
|
12
|
+
// The cross-kind partner is the whole reason an `exclusive` list holds more
|
|
13
|
+
// than the tag's own kind: `Minimum` lists `exclusiveMinimum`, `Format` lists
|
|
14
|
+
// `pattern`. The declaration is the spec and it forbids the coexistence, so
|
|
15
|
+
// `number & Minimum<0> & ExclusiveMinimum<5>` and
|
|
16
|
+
// `string & Format<"uuid"> & Pattern<...>` must not compile. The original check
|
|
17
|
+
// scanned only same-kind tags, so the two never met; dropping that same-kind
|
|
18
|
+
// guard is what lets this fire, so restoring the guard turns this red while
|
|
19
|
+
// leaving the same-kind duplication test green.
|
|
20
|
+
//
|
|
21
|
+
// 1. Derive every declared cross-kind pair from the declarations themselves.
|
|
22
|
+
// 2. Validate each pair, both orders, and require rejection naming the conflict.
|
|
23
|
+
// 3. Require all six declarations to contribute exactly one cross-kind partner.
|
|
24
|
+
func TestMetadataTypeTagFactoryRejectsCrossKindExclusiveTags(t *testing.T) {
|
|
25
|
+
declarations := metadataTypeTagFactoryTestDeclarations()
|
|
26
|
+
byKind := map[string]metadataTypeTagFactoryTestDeclaration{}
|
|
27
|
+
for _, declaration := range declarations {
|
|
28
|
+
byKind[declaration.kind] = declaration
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
covered := 0
|
|
32
|
+
for _, declaration := range declarations {
|
|
33
|
+
for _, kind := range declaration.exclusive {
|
|
34
|
+
if kind == declaration.kind {
|
|
35
|
+
continue
|
|
36
|
+
}
|
|
37
|
+
opposite, ok := byKind[kind]
|
|
38
|
+
if ok == false {
|
|
39
|
+
t.Fatalf("%s declares the unknown partner kind %s", declaration.kind, kind)
|
|
40
|
+
}
|
|
41
|
+
if opposite.target != declaration.target {
|
|
42
|
+
t.Fatalf("%s and %s must share a target to ever conflict", declaration.kind, kind)
|
|
43
|
+
}
|
|
44
|
+
covered++
|
|
45
|
+
|
|
46
|
+
subject := declaration.tag("A")
|
|
47
|
+
partner := opposite.tag("B")
|
|
48
|
+
success, messages := metadataTypeTagFactoryTestValidate(
|
|
49
|
+
declaration.target,
|
|
50
|
+
[]schemametadata.IMetadataTypeTag{subject, partner},
|
|
51
|
+
)
|
|
52
|
+
if success {
|
|
53
|
+
t.Fatalf("kind %s must not be used with kind %s", declaration.kind, kind)
|
|
54
|
+
}
|
|
55
|
+
if len(messages) != 1 ||
|
|
56
|
+
strings.Contains(messages[0], declaration.kind) == false ||
|
|
57
|
+
strings.Contains(messages[0], partner.Name) == false {
|
|
58
|
+
t.Fatalf("the %s and %s conflict report must name the conflict, reported %#v", declaration.kind, kind, messages)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if covered != len(declarations) {
|
|
63
|
+
t.Fatalf("every array-form declaration should name exactly one cross-kind partner, covered %d of %d", covered, len(declarations))
|
|
64
|
+
}
|
|
65
|
+
}
|