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
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestIsObjectFunctionMemberTransform pins the runtime behavior of typia.is /
|
|
12
|
+
// assert / validate for the global `Object` interface and for `Function`-typed
|
|
13
|
+
// members (#2178).
|
|
14
|
+
//
|
|
15
|
+
// The global TS `Object` interface carries `constructor: Function`. The global
|
|
16
|
+
// `Function` interface is declared as an `InterfaceDeclaration`, so before the
|
|
17
|
+
// fix typia failed to recognize it as a function type and expanded it
|
|
18
|
+
// structurally to `{ prototype, length, arguments, caller, name }`. That made
|
|
19
|
+
// the `constructor` member emit `"object" === typeof input.constructor`, which
|
|
20
|
+
// is never satisfied by a real constructor (`typeof === "function"`), so
|
|
21
|
+
// `is<Object>(x)` was false for every input. The same defect struck any explicit
|
|
22
|
+
// `Function`-typed member and any interface that `extends Object`.
|
|
23
|
+
//
|
|
24
|
+
// After the fix the lib `Function` interface is classified as a function and
|
|
25
|
+
// routes through the same lenient member path typia already uses for
|
|
26
|
+
// `() => void` members, so `is<Object>` collapses to a non-null-object gate.
|
|
27
|
+
// The lowercase `object` keyword and the `{}` type must stay byte-identical
|
|
28
|
+
// (they keep their `Array.isArray` guard), and the null / undefined / primitive
|
|
29
|
+
// boundaries must stay false.
|
|
30
|
+
//
|
|
31
|
+
// 1. Transform one fixture that exports is / assert / validate for `Object`, an
|
|
32
|
+
// explicit `{ fn: Function }`, a `Moment extends Object` interface, plus the
|
|
33
|
+
// lowercase `object` and `{}` regression guards.
|
|
34
|
+
// 2. Execute the emitted validators in Node against the boundary matrix.
|
|
35
|
+
// 3. Require the runner to report the exact executed case count so a runner that
|
|
36
|
+
// silently skipped cases cannot pass as a false green.
|
|
37
|
+
func TestIsObjectFunctionMemberTransform(t *testing.T) {
|
|
38
|
+
project := isObjectFunctionMemberProject(t)
|
|
39
|
+
js := isObjectFunctionMemberTransform(t, project)
|
|
40
|
+
isObjectFunctionMemberRunRuntimeCases(t, project, js)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
func isObjectFunctionMemberProject(t *testing.T) string {
|
|
44
|
+
t.Helper()
|
|
45
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
46
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
47
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
48
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
49
|
+
}
|
|
50
|
+
dir, err := os.MkdirTemp(base, "is-object-function-member-")
|
|
51
|
+
if err != nil {
|
|
52
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
53
|
+
}
|
|
54
|
+
t.Cleanup(func() {
|
|
55
|
+
_ = os.RemoveAll(dir)
|
|
56
|
+
})
|
|
57
|
+
src := filepath.Join(dir, "src")
|
|
58
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
59
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
60
|
+
}
|
|
61
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(finiteOptionNumberLeafTSConfig), 0o644); err != nil {
|
|
62
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
63
|
+
}
|
|
64
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(isObjectFunctionMemberSource), 0o644); err != nil {
|
|
65
|
+
t.Fatalf("write source: %v", err)
|
|
66
|
+
}
|
|
67
|
+
return dir
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func isObjectFunctionMemberTransform(t *testing.T, project string) string {
|
|
71
|
+
t.Helper()
|
|
72
|
+
payload := `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`
|
|
73
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
74
|
+
return runTransform([]string{
|
|
75
|
+
"--cwd", project,
|
|
76
|
+
"--tsconfig", "tsconfig.json",
|
|
77
|
+
"--file", "src/main.ts",
|
|
78
|
+
"--output", "js",
|
|
79
|
+
"--plugins-json", payload,
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
if code != 0 {
|
|
83
|
+
t.Fatalf("is<Object> transform failed: code=%d stderr=\n%s", code, errText)
|
|
84
|
+
}
|
|
85
|
+
return out
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
func isObjectFunctionMemberRunRuntimeCases(t *testing.T, project string, js string) {
|
|
89
|
+
t.Helper()
|
|
90
|
+
node, err := exec.LookPath("node")
|
|
91
|
+
if err != nil {
|
|
92
|
+
t.Skip("node executable not found")
|
|
93
|
+
}
|
|
94
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
95
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
96
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
97
|
+
}
|
|
98
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
99
|
+
runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
|
|
100
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
101
|
+
t.Fatalf("write runtime module: %v", err)
|
|
102
|
+
}
|
|
103
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
104
|
+
if err := os.WriteFile(runner, []byte(isObjectFunctionMemberRuntimeRunner), 0o644); err != nil {
|
|
105
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
106
|
+
}
|
|
107
|
+
cmd := exec.Command(node, runner)
|
|
108
|
+
cmd.Dir = project
|
|
109
|
+
output, err := cmd.CombinedOutput()
|
|
110
|
+
if err != nil {
|
|
111
|
+
t.Fatalf("is<Object> runtime cases failed: %v\n%s", err, output)
|
|
112
|
+
}
|
|
113
|
+
const expected = "RAN 27 CASES"
|
|
114
|
+
if !strings.Contains(string(output), expected) {
|
|
115
|
+
t.Fatalf("is<Object> runner did not report %q; got:\n%s", expected, output)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const isObjectFunctionMemberSource = `import typia from "typia";
|
|
120
|
+
|
|
121
|
+
interface Moment extends Object {
|
|
122
|
+
valueOf(): number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export const isObject = typia.createIs<Object>();
|
|
126
|
+
export const assertObject = typia.createAssert<Object>();
|
|
127
|
+
export const validateObject = typia.createValidate<Object>();
|
|
128
|
+
|
|
129
|
+
export const isFuncMember = typia.createIs<{ fn: Function }>();
|
|
130
|
+
export const isMoment = typia.createIs<Moment>();
|
|
131
|
+
|
|
132
|
+
export const isLowerObject = typia.createIs<object>();
|
|
133
|
+
export const isEmptyObject = typia.createIs<{}>();
|
|
134
|
+
|
|
135
|
+
// random must produce a sample that its own is accepts (round trip). Object and
|
|
136
|
+
// a Function-only member need no numeric generator stub, so they stay hermetic.
|
|
137
|
+
export const randomObject = typia.createRandom<Object>();
|
|
138
|
+
export const randomFuncOnly = typia.createRandom<{ fn: Function }>();
|
|
139
|
+
|
|
140
|
+
export const captureThrow = (task: () => void): boolean => {
|
|
141
|
+
try {
|
|
142
|
+
task();
|
|
143
|
+
return false;
|
|
144
|
+
} catch {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
`
|
|
149
|
+
|
|
150
|
+
const isObjectFunctionMemberRuntimeRunner = `const mod = require("./main.cjs");
|
|
151
|
+
|
|
152
|
+
let ran = 0;
|
|
153
|
+
const eq = (name, actual, expected) => {
|
|
154
|
+
ran += 1;
|
|
155
|
+
if (actual !== expected) {
|
|
156
|
+
throw new Error(name + ": expected " + expected + " but got " + actual);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// is<Object>: every non-null object is accepted, including arrays and class
|
|
161
|
+
// instances; null / undefined / primitives stay rejected (#2178 core cases).
|
|
162
|
+
eq("is<Object>({})", mod.isObject({}), true);
|
|
163
|
+
eq("is<Object>({a:1})", mod.isObject({ a: 1 }), true);
|
|
164
|
+
eq("is<Object>(new Object())", mod.isObject(new Object()), true);
|
|
165
|
+
eq("is<Object>(new Date())", mod.isObject(new Date()), true);
|
|
166
|
+
eq("is<Object>([])", mod.isObject([]), true);
|
|
167
|
+
eq("is<Object>(null)", mod.isObject(null), false);
|
|
168
|
+
eq("is<Object>(undefined)", mod.isObject(undefined), false);
|
|
169
|
+
eq("is<Object>(5)", mod.isObject(5), false);
|
|
170
|
+
eq("is<Object>('x')", mod.isObject("x"), false);
|
|
171
|
+
|
|
172
|
+
// validate and assert share the checker object path, so they must agree with is.
|
|
173
|
+
eq("validate<Object>({})", mod.validateObject({}).success, true);
|
|
174
|
+
eq("validate<Object>({a:1})", mod.validateObject({ a: 1 }).success, true);
|
|
175
|
+
eq("validate<Object>(null)", mod.validateObject(null).success, false);
|
|
176
|
+
eq("assert<Object>({}) no throw", mod.captureThrow(() => mod.assertObject({})), false);
|
|
177
|
+
eq("assert<Object>(null) throws", mod.captureThrow(() => mod.assertObject(null)), true);
|
|
178
|
+
|
|
179
|
+
// Explicit Function-typed member: the same lenient function path as () => void.
|
|
180
|
+
eq("is<{fn:Function}>({fn(){}})", mod.isFuncMember({ fn() {} }), true);
|
|
181
|
+
eq("is<{fn:Function}>({fn:()=>{}})", mod.isFuncMember({ fn: () => {} }), true);
|
|
182
|
+
eq("is<{fn:Function}>(null)", mod.isFuncMember(null), false);
|
|
183
|
+
|
|
184
|
+
// interface Moment extends Object: the inherited constructor member no longer
|
|
185
|
+
// breaks a real instance.
|
|
186
|
+
eq("is<Moment>(real)", mod.isMoment({ valueOf: () => 1 }), true);
|
|
187
|
+
eq("is<Moment>(null)", mod.isMoment(null), false);
|
|
188
|
+
|
|
189
|
+
// lowercase object keeps its Array.isArray guard (byte-identical, unchanged).
|
|
190
|
+
eq("is<object>({})", mod.isLowerObject({}), true);
|
|
191
|
+
eq("is<object>([])", mod.isLowerObject([]), false);
|
|
192
|
+
eq("is<object>(null)", mod.isLowerObject(null), false);
|
|
193
|
+
|
|
194
|
+
// {} empty object type keeps its Array.isArray guard (byte-identical, unchanged).
|
|
195
|
+
eq("is<{}>({})", mod.isEmptyObject({}), true);
|
|
196
|
+
eq("is<{}>([])", mod.isEmptyObject([]), false);
|
|
197
|
+
eq("is<{}>(null)", mod.isEmptyObject(null), false);
|
|
198
|
+
|
|
199
|
+
// random <-> is round trip: the generated Object / Function-member sample must
|
|
200
|
+
// pass its own is checker.
|
|
201
|
+
eq("is<Object>(random<Object>())", mod.isObject(mod.randomObject()), true);
|
|
202
|
+
eq("is<{fn:Function}>(random)", mod.isFuncMember(mod.randomFuncOnly()), true);
|
|
203
|
+
|
|
204
|
+
console.log("RAN " + ran + " CASES");
|
|
205
|
+
`
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestJsonApplicationAliasFunctionValidation verifies that a function property
|
|
11
|
+
// written through a `type` alias reaches the same #2195 guards as an inline one.
|
|
12
|
+
//
|
|
13
|
+
// `json.application` keeps the alias on the property value it validates but
|
|
14
|
+
// unaliases the one it emits, so before #2216 the two disagreed: `Validate` read
|
|
15
|
+
// `p.Value.Functions` (empty for an aliased member) and skipped every per-function
|
|
16
|
+
// check, while `WriteApplication` unaliased and silently dropped the malformed
|
|
17
|
+
// function. The mirror case rejected a valid aliased application with a spurious
|
|
18
|
+
// "must have at least a function type." This pins both directions.
|
|
19
|
+
//
|
|
20
|
+
// 1. Reject an aliased union / optional / nullable function with its exact
|
|
21
|
+
// #2195 diagnostic, matching the inline sibling fixtures.
|
|
22
|
+
// 2. Accept an aliased required single function (direct and through a deep
|
|
23
|
+
// alias chain), emitting it and reporting no "at least a function" error.
|
|
24
|
+
func TestJsonApplicationAliasFunctionValidation(t *testing.T) {
|
|
25
|
+
for _, tt := range []struct {
|
|
26
|
+
name string
|
|
27
|
+
source string
|
|
28
|
+
fragment string
|
|
29
|
+
}{
|
|
30
|
+
{
|
|
31
|
+
name: "alias-union",
|
|
32
|
+
source: `import typia from "typia";
|
|
33
|
+
type BadUnion = (() => number) | ((value: number) => string);
|
|
34
|
+
typia.json.application<{ good(): number; bad: BadUnion; }>();
|
|
35
|
+
`,
|
|
36
|
+
fragment: "JSON application's function type does not allow union type.",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "alias-optional",
|
|
40
|
+
source: `import typia from "typia";
|
|
41
|
+
type BadFn = () => number;
|
|
42
|
+
typia.json.application<{ good(): number; bad?: BadFn; }>();
|
|
43
|
+
`,
|
|
44
|
+
fragment: "JSON application's function type must be required.",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "alias-nullable",
|
|
48
|
+
source: `import typia from "typia";
|
|
49
|
+
type BadFn = () => number;
|
|
50
|
+
typia.json.application<{ good(): number; bad: BadFn | null; }>();
|
|
51
|
+
`,
|
|
52
|
+
fragment: "JSON application's function type must not be nullable.",
|
|
53
|
+
},
|
|
54
|
+
} {
|
|
55
|
+
jsonApplicationAliasExpectDiagnostic(t, tt.name, tt.source, tt.fragment)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for _, tt := range []struct {
|
|
59
|
+
name string
|
|
60
|
+
source string
|
|
61
|
+
function string
|
|
62
|
+
}{
|
|
63
|
+
{
|
|
64
|
+
name: "alias-required-single",
|
|
65
|
+
source: `import typia from "typia";
|
|
66
|
+
type GoodFn = () => number;
|
|
67
|
+
typia.json.application<{ only: GoodFn; }>();
|
|
68
|
+
`,
|
|
69
|
+
function: "only",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "alias-deep-chain",
|
|
73
|
+
source: `import typia from "typia";
|
|
74
|
+
type A = B;
|
|
75
|
+
type B = () => number;
|
|
76
|
+
typia.json.application<{ deep: A; }>();
|
|
77
|
+
`,
|
|
78
|
+
function: "deep",
|
|
79
|
+
},
|
|
80
|
+
} {
|
|
81
|
+
jsonApplicationAliasExpectInclusion(t, tt.name, tt.source, tt.function)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func jsonApplicationAliasExpectDiagnostic(t *testing.T, name string, source string, fragment string) {
|
|
86
|
+
t.Helper()
|
|
87
|
+
project := jsonApplicationAliasProject(t, name, source)
|
|
88
|
+
_, errText, code := ttscTypiaTestCapture(func() int {
|
|
89
|
+
return runBuild([]string{
|
|
90
|
+
"--cwd", project,
|
|
91
|
+
"--tsconfig", "tsconfig.json",
|
|
92
|
+
"--emit",
|
|
93
|
+
"--outDir", filepath.Join(project, "dist"),
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
if code != 3 {
|
|
97
|
+
t.Fatalf("%s aliased application build should fail with code 3, got %d\nstderr=%s", name, code, errText)
|
|
98
|
+
}
|
|
99
|
+
for _, want := range []string{"error TS(typia.json.application):", fragment} {
|
|
100
|
+
if !strings.Contains(errText, want) {
|
|
101
|
+
t.Fatalf("%s aliased application diagnostic missing %q:\n%s", name, want, errText)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func jsonApplicationAliasExpectInclusion(t *testing.T, name string, source string, function string) {
|
|
107
|
+
t.Helper()
|
|
108
|
+
project := jsonApplicationAliasProject(t, name, source)
|
|
109
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
110
|
+
return runTransform([]string{
|
|
111
|
+
"--cwd", project,
|
|
112
|
+
"--tsconfig", "tsconfig.json",
|
|
113
|
+
"--file", "src/main.ts",
|
|
114
|
+
"--output", "js",
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
if code != 0 {
|
|
118
|
+
t.Fatalf("%s valid aliased application should transform, got code %d\nstderr=%s", name, code, errText)
|
|
119
|
+
}
|
|
120
|
+
if !strings.Contains(out, `name: "`+function+`"`) {
|
|
121
|
+
t.Fatalf("%s valid aliased application dropped its function %q:\n%s", name, function, out)
|
|
122
|
+
}
|
|
123
|
+
if strings.Contains(out, "at least a function") {
|
|
124
|
+
t.Fatalf("%s valid aliased application reported a spurious empty-application error:\n%s", name, out)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
func jsonApplicationAliasProject(t *testing.T, name string, source string) string {
|
|
129
|
+
t.Helper()
|
|
130
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
131
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
132
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
133
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
134
|
+
}
|
|
135
|
+
dir, err := os.MkdirTemp(base, "json-application-alias-"+name+"-")
|
|
136
|
+
if err != nil {
|
|
137
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
138
|
+
}
|
|
139
|
+
t.Cleanup(func() { _ = os.RemoveAll(dir) })
|
|
140
|
+
src := filepath.Join(dir, "src")
|
|
141
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
142
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
143
|
+
}
|
|
144
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(randomRecursiveMinItemsTSConfig), 0o644); err != nil {
|
|
145
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
146
|
+
}
|
|
147
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(source), 0o644); err != nil {
|
|
148
|
+
t.Fatalf("write source: %v", err)
|
|
149
|
+
}
|
|
150
|
+
return dir
|
|
151
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestJsonIsStringifyFiniteNumberTransform pins json.isStringify against a bare
|
|
12
|
+
// number leaf so a non-finite value cannot leak into the serialized text (#2196).
|
|
13
|
+
//
|
|
14
|
+
// json.isStringify forces Options.Finite on its inner `__is` guard precisely to
|
|
15
|
+
// keep NaN and Infinity out of JSON. Because `is` dropped `finite`, that guard
|
|
16
|
+
// accepted NaN, so `__is(input) ? __stringify(input) : null` serialized the input
|
|
17
|
+
// instead of returning the top-level null it owes an invalid value. Both option
|
|
18
|
+
// rows reproduce a distinct failure the fix must close:
|
|
19
|
+
//
|
|
20
|
+
// - default options: the validated stringify folds the number through
|
|
21
|
+
// _jsonStringifyNumber, so NaN silently became `{"value":null}` -- an accepted
|
|
22
|
+
// invalid input rather than a rejected one.
|
|
23
|
+
// - finite:true: the validated stringify emits raw `String(input)` for the
|
|
24
|
+
// number, so NaN became the literal `{"value":NaN}` token -- invalid JSON that
|
|
25
|
+
// JSON.parse throws on. This is the corruption hole the guard closes.
|
|
26
|
+
//
|
|
27
|
+
// 1. Transform a `json.isStringify<{ value: number }>` fixture per option row.
|
|
28
|
+
// 2. Execute the emitted serializer in Node.
|
|
29
|
+
// 3. Require a finite value to serialize and NaN/Infinity/-Infinity to yield null.
|
|
30
|
+
func TestJsonIsStringifyFiniteNumberTransform(t *testing.T) {
|
|
31
|
+
for _, tc := range jsonIsStringifyFiniteNumberCases() {
|
|
32
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
33
|
+
project := jsonIsStringifyFiniteNumberProject(t)
|
|
34
|
+
js := jsonIsStringifyFiniteNumberTransform(t, project, tc.payload)
|
|
35
|
+
jsonIsStringifyFiniteNumberRunRuntime(t, project, js)
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
type jsonIsStringifyFiniteNumberCase struct {
|
|
41
|
+
name string
|
|
42
|
+
payload string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
func jsonIsStringifyFiniteNumberCases() []jsonIsStringifyFiniteNumberCase {
|
|
46
|
+
return []jsonIsStringifyFiniteNumberCase{
|
|
47
|
+
{
|
|
48
|
+
name: "default options",
|
|
49
|
+
payload: `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "finite option on",
|
|
53
|
+
payload: `[{"config":{"transform":"typia/lib/transform","finite":true},"name":"typia","stage":"transform"}]`,
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
func jsonIsStringifyFiniteNumberProject(t *testing.T) string {
|
|
59
|
+
t.Helper()
|
|
60
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
61
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
62
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
63
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
64
|
+
}
|
|
65
|
+
dir, err := os.MkdirTemp(base, "json-is-stringify-finite-number-")
|
|
66
|
+
if err != nil {
|
|
67
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
68
|
+
}
|
|
69
|
+
t.Cleanup(func() {
|
|
70
|
+
_ = os.RemoveAll(dir)
|
|
71
|
+
})
|
|
72
|
+
src := filepath.Join(dir, "src")
|
|
73
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
74
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
75
|
+
}
|
|
76
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(jsonIsStringifyFiniteNumberTSConfig), 0o644); err != nil {
|
|
77
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
78
|
+
}
|
|
79
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(jsonIsStringifyFiniteNumberSource), 0o644); err != nil {
|
|
80
|
+
t.Fatalf("write source: %v", err)
|
|
81
|
+
}
|
|
82
|
+
return dir
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func jsonIsStringifyFiniteNumberTransform(t *testing.T, project string, payload string) string {
|
|
86
|
+
t.Helper()
|
|
87
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
88
|
+
return runTransform([]string{
|
|
89
|
+
"--cwd", project,
|
|
90
|
+
"--tsconfig", "tsconfig.json",
|
|
91
|
+
"--file", "src/main.ts",
|
|
92
|
+
"--output", "js",
|
|
93
|
+
"--plugins-json", payload,
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
if code != 0 {
|
|
97
|
+
t.Fatalf("json isStringify finite transform failed: code=%d stderr=\n%s", code, errText)
|
|
98
|
+
}
|
|
99
|
+
return out
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
func jsonIsStringifyFiniteNumberRunRuntime(t *testing.T, project string, js string) {
|
|
103
|
+
t.Helper()
|
|
104
|
+
node, err := exec.LookPath("node")
|
|
105
|
+
if err != nil {
|
|
106
|
+
t.Skip("node executable not found")
|
|
107
|
+
}
|
|
108
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
109
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
110
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
111
|
+
}
|
|
112
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
113
|
+
stubs := map[string]string{
|
|
114
|
+
"json-stringify-number-stub.cjs": jsonIsStringifyScopedCheckerNumberStub,
|
|
115
|
+
"json-stringify-string-stub.cjs": jsonIsStringifyScopedCheckerStringStub,
|
|
116
|
+
"throw-type-guard-error-stub.cjs": jsonIsStringifyScopedCheckerThrowStub,
|
|
117
|
+
}
|
|
118
|
+
for name, content := range stubs {
|
|
119
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, name), []byte(content), 0o644); err != nil {
|
|
120
|
+
t.Fatalf("write %s: %v", name, err)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
runtimeJS := strings.ReplaceAll(js, `require("typia/lib/internal/_jsonStringifyNumber")`, `require("./json-stringify-number-stub.cjs")`)
|
|
124
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyString")`, `require("./json-stringify-string-stub.cjs")`)
|
|
125
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_throwTypeGuardError")`, `require("./throw-type-guard-error-stub.cjs")`)
|
|
126
|
+
runtimeJS = ttscTypiaTestRewriteCommonJS(t, runtimeJS)
|
|
127
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
128
|
+
t.Fatalf("write runtime module: %v", err)
|
|
129
|
+
}
|
|
130
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
131
|
+
if err := os.WriteFile(runner, []byte(jsonIsStringifyFiniteNumberRunner), 0o644); err != nil {
|
|
132
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
133
|
+
}
|
|
134
|
+
cmd := exec.Command(node, runner)
|
|
135
|
+
cmd.Dir = runtimeDir
|
|
136
|
+
output, err := cmd.CombinedOutput()
|
|
137
|
+
if err != nil {
|
|
138
|
+
t.Fatalf("json isStringify finite runtime failed: %v\n%s", err, output)
|
|
139
|
+
}
|
|
140
|
+
const expected = "RAN 4 CASES"
|
|
141
|
+
if !strings.Contains(string(output), expected) {
|
|
142
|
+
t.Fatalf("json isStringify finite runner did not report %q; got:\n%s", expected, output)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const jsonIsStringifyFiniteNumberTSConfig = `{
|
|
147
|
+
"compilerOptions": {
|
|
148
|
+
"target": "ES2022",
|
|
149
|
+
"module": "commonjs",
|
|
150
|
+
"moduleResolution": "bundler",
|
|
151
|
+
"ignoreDeprecations": "6.0",
|
|
152
|
+
"types": ["*"],
|
|
153
|
+
"esModuleInterop": true,
|
|
154
|
+
"strict": true,
|
|
155
|
+
"skipLibCheck": true
|
|
156
|
+
},
|
|
157
|
+
"include": ["src"]
|
|
158
|
+
}
|
|
159
|
+
`
|
|
160
|
+
|
|
161
|
+
const jsonIsStringifyFiniteNumberSource = `import typia from "typia";
|
|
162
|
+
|
|
163
|
+
interface Box {
|
|
164
|
+
value: number;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export const stringify = (input: unknown): string | null =>
|
|
168
|
+
typia.json.isStringify<Box>(input);
|
|
169
|
+
`
|
|
170
|
+
|
|
171
|
+
const jsonIsStringifyFiniteNumberRunner = `const mod = require("./main.cjs");
|
|
172
|
+
|
|
173
|
+
const finite = mod.stringify({ value: 1 });
|
|
174
|
+
if (finite === null) {
|
|
175
|
+
throw new Error("json.isStringify rejected a finite number");
|
|
176
|
+
}
|
|
177
|
+
const parsed = JSON.parse(finite);
|
|
178
|
+
if (parsed.value !== 1) {
|
|
179
|
+
throw new Error("json.isStringify serialized the wrong value: " + finite);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
let ran = 1;
|
|
183
|
+
for (const [name, value] of [
|
|
184
|
+
["NaN", Number.NaN],
|
|
185
|
+
["Infinity", Number.POSITIVE_INFINITY],
|
|
186
|
+
["-Infinity", Number.NEGATIVE_INFINITY],
|
|
187
|
+
]) {
|
|
188
|
+
const out = mod.stringify({ value });
|
|
189
|
+
ran += 1;
|
|
190
|
+
if (out !== null) {
|
|
191
|
+
throw new Error(
|
|
192
|
+
name + " leaked into json.isStringify output instead of null: " + JSON.stringify(out),
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
console.log("RAN " + ran + " CASES");
|
|
198
|
+
`
|