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,43 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"path/filepath"
|
|
5
|
+
"testing"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
// TestTransformPluginOptionsComeFromPayload verifies the transform host takes
|
|
9
|
+
// typia's options from ttsc's resolved plugin entry, not from tsconfig text.
|
|
10
|
+
//
|
|
11
|
+
// This host owns its own `--plugins-json` flag and its own option read, so it
|
|
12
|
+
// needs its own proof: the build host passing does not show that this one is
|
|
13
|
+
// wired. Every row writes a tsconfig whose raw text disagrees with the resolved
|
|
14
|
+
// entry, which is exactly what samchon/typia#1887 could not tell apart -- the
|
|
15
|
+
// old reader regex-matched option names over the leaf file's bytes, so it
|
|
16
|
+
// enabled options the user had commented out, adopted a sibling plugin's
|
|
17
|
+
// options, and ignored options inherited through `extends`.
|
|
18
|
+
//
|
|
19
|
+
// 1. Materialize each matrix row as a project plus the payload ttsc resolves it into.
|
|
20
|
+
// 2. Run the transform host over it.
|
|
21
|
+
// 3. Assert the emitted validator honors the entry, not the file text.
|
|
22
|
+
func TestTransformPluginOptionsComeFromPayload(t *testing.T) {
|
|
23
|
+
for _, tc := range pluginOptionsPayloadCases() {
|
|
24
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
25
|
+
project := pluginOptionsPayloadProject(t, tc)
|
|
26
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
27
|
+
return runTransform([]string{
|
|
28
|
+
"--cwd", project,
|
|
29
|
+
"--tsconfig", "tsconfig.json",
|
|
30
|
+
"--file", filepath.Join("src", "main.ts"),
|
|
31
|
+
"--output", "ts",
|
|
32
|
+
// `=`-joined, the exact shape ttsc's createNativeBuildArgs and the
|
|
33
|
+
// wasm hosts put on the wire.
|
|
34
|
+
"--plugins-json=" + tc.payload,
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
if code != 0 {
|
|
38
|
+
t.Fatalf("transform failed with code %d\nstdout=%s\nstderr=%s", code, out, errText)
|
|
39
|
+
}
|
|
40
|
+
pluginOptionsPayloadAssert(t, tc, out)
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"reflect"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestTransformSingleFileFailurePreservesArtifacts verifies single-file atomicity.
|
|
12
|
+
//
|
|
13
|
+
// The project host returns 3 when typia's analysis produced diagnostics, but both
|
|
14
|
+
// single-file hosts used to publish `--out` and exit 0 regardless, shipping the
|
|
15
|
+
// untransformed `typia.is<T>(input)` call behind a success code. Publication must
|
|
16
|
+
// follow the same decision as the exit code in both output modes, and a failed
|
|
17
|
+
// transform must not destroy an artifact a previous run left behind.
|
|
18
|
+
//
|
|
19
|
+
// 1. Seed `--out` with a byte-sensitive prior artifact beside an unrelated file.
|
|
20
|
+
// 2. Run the single-file transform over a typia-invalid source in `ts` and `js`.
|
|
21
|
+
// 3. Require exit 3, the diagnostic on stderr, and a byte-identical output tree.
|
|
22
|
+
// 4. Require a fresh `--out` parent to stay uncreated, since publishing nothing
|
|
23
|
+
// must also mean creating no directory for it.
|
|
24
|
+
func TestTransformSingleFileFailurePreservesArtifacts(t *testing.T) {
|
|
25
|
+
for _, output := range []string{"ts", "js"} {
|
|
26
|
+
t.Run(output, func(t *testing.T) {
|
|
27
|
+
project := transformSingleFileProject(t, transformDiagnosticSource)
|
|
28
|
+
dist := filepath.Join(project, "dist")
|
|
29
|
+
outPath := filepath.Join(dist, "main."+output)
|
|
30
|
+
seeds := map[string]string{
|
|
31
|
+
outPath: "previous artifact\n",
|
|
32
|
+
filepath.Join(dist, "keep.txt"): "unrelated output\n",
|
|
33
|
+
}
|
|
34
|
+
for path, body := range seeds {
|
|
35
|
+
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
36
|
+
t.Fatalf("mkdir seed parent: %v", err)
|
|
37
|
+
}
|
|
38
|
+
if err := os.WriteFile(path, []byte(body), 0o644); err != nil {
|
|
39
|
+
t.Fatalf("write seed %s: %v", path, err)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
before := buildReadTree(t, dist)
|
|
43
|
+
|
|
44
|
+
_, errText, code := ttscTypiaTestCapture(func() int {
|
|
45
|
+
return runTransform([]string{
|
|
46
|
+
"--cwd", project,
|
|
47
|
+
"--tsconfig", "tsconfig.json",
|
|
48
|
+
"--file", filepath.Join("src", "main.ts"),
|
|
49
|
+
"--output", output,
|
|
50
|
+
"--out", outPath,
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
if code != 3 {
|
|
54
|
+
t.Fatalf("invalid single-file transform should fail with code 3, got %d\nstderr=%s", code, errText)
|
|
55
|
+
}
|
|
56
|
+
normalized := filepath.ToSlash(errText)
|
|
57
|
+
if !strings.Contains(normalized, "src/main.ts:3:9 - error TS(typia.is):") ||
|
|
58
|
+
!strings.Contains(normalized, "non-specified generic argument") {
|
|
59
|
+
t.Fatalf("single-file diagnostic did not preserve location/code/message:\n%s", errText)
|
|
60
|
+
}
|
|
61
|
+
if after := buildReadTree(t, dist); !reflect.DeepEqual(after, before) {
|
|
62
|
+
t.Fatalf("failed single-file transform mutated output tree:\nbefore=%q\nafter=%q", before, after)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// writeSingleOutput mkdirs its parent, so a guard placed after publication
|
|
66
|
+
// would leave the directory behind even with no artifact in it.
|
|
67
|
+
fresh := filepath.Join(project, "fresh", "nested")
|
|
68
|
+
_, _, code = ttscTypiaTestCapture(func() int {
|
|
69
|
+
return runTransform([]string{
|
|
70
|
+
"--cwd", project,
|
|
71
|
+
"--tsconfig", "tsconfig.json",
|
|
72
|
+
"--file", filepath.Join("src", "main.ts"),
|
|
73
|
+
"--output", output,
|
|
74
|
+
"--out", filepath.Join(fresh, "main."+output),
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
if code != 3 {
|
|
78
|
+
t.Fatalf("invalid single-file transform should fail with code 3, got %d", code)
|
|
79
|
+
}
|
|
80
|
+
if _, err := os.Stat(filepath.Join(project, "fresh")); !os.IsNotExist(err) {
|
|
81
|
+
t.Fatalf("failed single-file transform created the --out directory: %v", err)
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// transformSingleFileProject writes a one-source project whose `src/main.ts`
|
|
88
|
+
// carries the given body, sharing the typia stub the other transform diagnostic
|
|
89
|
+
// fixtures use.
|
|
90
|
+
func transformSingleFileProject(t *testing.T, source string) string {
|
|
91
|
+
t.Helper()
|
|
92
|
+
project := t.TempDir()
|
|
93
|
+
src := filepath.Join(project, "src")
|
|
94
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
95
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
96
|
+
}
|
|
97
|
+
if err := os.WriteFile(filepath.Join(project, "tsconfig.json"), []byte(transformDiagnosticTSConfig), 0o644); err != nil {
|
|
98
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
99
|
+
}
|
|
100
|
+
transformDiagnosticWriteTypiaStub(t, project)
|
|
101
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(source), 0o644); err != nil {
|
|
102
|
+
t.Fatalf("write source: %v", err)
|
|
103
|
+
}
|
|
104
|
+
return project
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// transformSingleFileValidSource is the negative twin of
|
|
108
|
+
// transformDiagnosticSource: the same call shape with a resolved generic
|
|
109
|
+
// argument, which typia can lower without a diagnostic.
|
|
110
|
+
const transformSingleFileValidSource = `import typia from "typia";
|
|
111
|
+
export function check(input: unknown): boolean {
|
|
112
|
+
return typia.is<{ value: number }>(input);
|
|
113
|
+
}
|
|
114
|
+
`
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"path/filepath"
|
|
5
|
+
"strings"
|
|
6
|
+
"testing"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// TestTransformSingleFileFailureWritesNoStdout verifies the stdout publication path.
|
|
10
|
+
//
|
|
11
|
+
// Without `--out` the artifact is stdout, so withholding a file is not enough:
|
|
12
|
+
// the untransformed source must not reach the stream a caller pipes into a file.
|
|
13
|
+
// This is also the shape the wasm host reaches through `jsTransform`, whose
|
|
14
|
+
// `{ code, stdout, stderr }` response is exactly these three values.
|
|
15
|
+
//
|
|
16
|
+
// 1. Transform a typia-invalid source in `ts` and `js` with no `--out`.
|
|
17
|
+
// 2. Require exit 3 and the diagnostic on stderr.
|
|
18
|
+
// 3. Require stdout to be empty rather than carrying the untransformed call.
|
|
19
|
+
func TestTransformSingleFileFailureWritesNoStdout(t *testing.T) {
|
|
20
|
+
for _, output := range []string{"ts", "js"} {
|
|
21
|
+
t.Run(output, func(t *testing.T) {
|
|
22
|
+
project := transformSingleFileProject(t, transformDiagnosticSource)
|
|
23
|
+
outText, errText, code := ttscTypiaTestCapture(func() int {
|
|
24
|
+
return runTransform([]string{
|
|
25
|
+
"--cwd", project,
|
|
26
|
+
"--tsconfig", "tsconfig.json",
|
|
27
|
+
"--file", filepath.Join("src", "main.ts"),
|
|
28
|
+
"--output", output,
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
if code != 3 {
|
|
32
|
+
t.Fatalf("invalid single-file transform should fail with code 3, got %d\nstdout=%s\nstderr=%s", code, outText, errText)
|
|
33
|
+
}
|
|
34
|
+
if !strings.Contains(errText, "error TS(typia.is):") {
|
|
35
|
+
t.Fatalf("single-file diagnostic missing from stderr:\n%s", errText)
|
|
36
|
+
}
|
|
37
|
+
// Before the fix this carried the untransformed `typia.is<T>(input)` call.
|
|
38
|
+
if outText != "" {
|
|
39
|
+
t.Fatalf("failed single-file transform published an artifact on stdout:\n%s", outText)
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
}
|
package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestTransformSingleFileJSDistinguishesSameBasenameSources verifies the
|
|
11
|
+
// collision boundary of the `--output js` artifact match.
|
|
12
|
+
//
|
|
13
|
+
// The comment on the old whole-path-stem match named the intended repair --
|
|
14
|
+
// "match on basename stem" -- and a basename match would indeed have unblocked
|
|
15
|
+
// `outDir`. It would also have made `src/alpha/main.ts` and `src/beta/main.ts`
|
|
16
|
+
// indistinguishable, so whichever emitted `main.js` arrived last would win and
|
|
17
|
+
// the command would publish another file's validator under an exit 0. Resolving
|
|
18
|
+
// the expected output path through the compiler keeps the two apart by
|
|
19
|
+
// construction, since they resolve to different artifacts.
|
|
20
|
+
//
|
|
21
|
+
// 1. Give one project two sources that share a basename in different
|
|
22
|
+
// directories, each lowering a differently shaped validator.
|
|
23
|
+
// 2. Transform each with `--output js --out` under a `rootDir`/`outDir` layout.
|
|
24
|
+
// 3. Require each published artifact to carry its own validator and not its
|
|
25
|
+
// namesake's.
|
|
26
|
+
func TestTransformSingleFileJSDistinguishesSameBasenameSources(t *testing.T) {
|
|
27
|
+
const alphaSource = `import typia from "typia";
|
|
28
|
+
export function check(input: unknown): boolean {
|
|
29
|
+
return typia.is<{ alpha: number }>(input);
|
|
30
|
+
}
|
|
31
|
+
`
|
|
32
|
+
const betaSource = `import typia from "typia";
|
|
33
|
+
export function check(input: unknown): boolean {
|
|
34
|
+
return typia.is<{ beta: string }>(input);
|
|
35
|
+
}
|
|
36
|
+
`
|
|
37
|
+
project := transformSingleFileLayoutProject(
|
|
38
|
+
t,
|
|
39
|
+
[]string{`"rootDir": "src"`, `"outDir": "dist"`},
|
|
40
|
+
map[string]string{
|
|
41
|
+
"src/alpha/main.ts": alphaSource,
|
|
42
|
+
"src/beta/main.ts": betaSource,
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
for _, probe := range []struct {
|
|
46
|
+
name string
|
|
47
|
+
file string
|
|
48
|
+
carries string
|
|
49
|
+
rejects string
|
|
50
|
+
}{
|
|
51
|
+
{name: "alpha", file: "src/alpha/main.ts", carries: "alpha", rejects: "beta"},
|
|
52
|
+
{name: "beta", file: "src/beta/main.ts", carries: "beta", rejects: "alpha"},
|
|
53
|
+
} {
|
|
54
|
+
t.Run(probe.name, func(t *testing.T) {
|
|
55
|
+
outPath := filepath.Join(project, "artifact", probe.name+".js")
|
|
56
|
+
_, errText, code := ttscTypiaTestCapture(func() int {
|
|
57
|
+
return runTransform([]string{
|
|
58
|
+
"--cwd", project,
|
|
59
|
+
"--tsconfig", "tsconfig.json",
|
|
60
|
+
"--file", filepath.FromSlash(probe.file),
|
|
61
|
+
"--output", "js",
|
|
62
|
+
"--out", outPath,
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
if code != 0 {
|
|
66
|
+
t.Fatalf("`--output js` should publish %s, got %d\nstderr=%s", probe.file, code, errText)
|
|
67
|
+
}
|
|
68
|
+
data, err := os.ReadFile(outPath)
|
|
69
|
+
if err != nil {
|
|
70
|
+
t.Fatalf("`--output js` published no artifact for %s: %v", probe.file, err)
|
|
71
|
+
}
|
|
72
|
+
text := string(data)
|
|
73
|
+
if !strings.Contains(text, probe.carries) {
|
|
74
|
+
t.Fatalf("published artifact does not carry %s's validator:\n%s", probe.file, text)
|
|
75
|
+
}
|
|
76
|
+
if strings.Contains(text, probe.rejects) {
|
|
77
|
+
t.Fatalf("published artifact carries the same-basename sibling's validator:\n%s", text)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestTransformSingleFileJSEmptyEmitReportsNoOutput verifies the negative twin
|
|
11
|
+
// of the `--output js` artifact match.
|
|
12
|
+
//
|
|
13
|
+
// Teaching the match where an `outDir` puts an artifact must not turn it into a
|
|
14
|
+
// match that always succeeds. "No output produced" is a real outcome: a source
|
|
15
|
+
// can belong to the program and still have no JavaScript of its own, and the
|
|
16
|
+
// caller needs exit 3 rather than an empty file behind exit 0. Every probe puts
|
|
17
|
+
// a real artifact for a sibling source through the same write callback, so a
|
|
18
|
+
// check that stopped discriminating would capture that neighbor and report
|
|
19
|
+
// success. The three probes reach the outcome by different routes -- an emit
|
|
20
|
+
// that skips the file, an emit that withholds it, and a file the resolution
|
|
21
|
+
// gives no output path at all -- so no one of them stands in for the others.
|
|
22
|
+
//
|
|
23
|
+
// 1. Ask for the JavaScript of a declaration source, which the emit skips.
|
|
24
|
+
// 2. Ask for the JavaScript of a source outside `rootDir`, whose output would
|
|
25
|
+
// land outside `outDir` and is therefore withheld by the emit.
|
|
26
|
+
// 3. Ask for the JavaScript of a JSON module that would be emitted over
|
|
27
|
+
// itself, which resolves to no JavaScript output path.
|
|
28
|
+
// 4. Require exit 3, the "no output produced" report, and an unwritten `--out`
|
|
29
|
+
// in all three.
|
|
30
|
+
func TestTransformSingleFileJSEmptyEmitReportsNoOutput(t *testing.T) {
|
|
31
|
+
for _, probe := range []struct {
|
|
32
|
+
name string
|
|
33
|
+
extra []string
|
|
34
|
+
sources map[string]string
|
|
35
|
+
file string
|
|
36
|
+
}{
|
|
37
|
+
// A declaration source is in the program but never emitted, so no write
|
|
38
|
+
// ever arrives for the path it resolves to.
|
|
39
|
+
{
|
|
40
|
+
name: "declaration_source",
|
|
41
|
+
extra: []string{`"rootDir": "src"`, `"outDir": "dist"`},
|
|
42
|
+
sources: map[string]string{
|
|
43
|
+
"src/types.d.ts": "export declare const value: string;\n",
|
|
44
|
+
"src/main.ts": transformSingleFileValidSource,
|
|
45
|
+
},
|
|
46
|
+
file: "src/types.d.ts",
|
|
47
|
+
},
|
|
48
|
+
// A source outside `rootDir` resolves to an output outside `outDir`, which
|
|
49
|
+
// the emit refuses to write rather than escaping the output tree. The
|
|
50
|
+
// source is ordinary TypeScript that transforms fine, so only the absent
|
|
51
|
+
// write distinguishes it -- exactly the state the check exists to report.
|
|
52
|
+
{
|
|
53
|
+
name: "output_escapes_out_dir",
|
|
54
|
+
extra: []string{`"rootDir": "src/deep"`, `"outDir": "dist"`},
|
|
55
|
+
sources: map[string]string{
|
|
56
|
+
"src/deep/main.ts": transformSingleFileValidSource,
|
|
57
|
+
"src/stray.ts": transformSingleFileValidSource,
|
|
58
|
+
},
|
|
59
|
+
file: "src/stray.ts",
|
|
60
|
+
},
|
|
61
|
+
// A JSON module with no `outDir` would be emitted over its own source, so
|
|
62
|
+
// the compiler resolves it to no JavaScript output path at all. This is the
|
|
63
|
+
// one route that reaches the empty-path guard rather than an absent write.
|
|
64
|
+
{
|
|
65
|
+
name: "json_module_emitted_over_itself",
|
|
66
|
+
extra: []string{`"resolveJsonModule": true`},
|
|
67
|
+
sources: map[string]string{
|
|
68
|
+
"src/data.json": "{ \"value\": 1 }\n",
|
|
69
|
+
"src/main.ts": "import data from \"./data.json\";\nexport const value = data.value;\n",
|
|
70
|
+
},
|
|
71
|
+
file: "src/data.json",
|
|
72
|
+
},
|
|
73
|
+
} {
|
|
74
|
+
t.Run(probe.name, func(t *testing.T) {
|
|
75
|
+
project := transformSingleFileLayoutProject(t, probe.extra, probe.sources)
|
|
76
|
+
outPath := filepath.Join(project, "artifact", "main.js")
|
|
77
|
+
_, errText, code := ttscTypiaTestCapture(func() int {
|
|
78
|
+
return runTransform([]string{
|
|
79
|
+
"--cwd", project,
|
|
80
|
+
"--tsconfig", "tsconfig.json",
|
|
81
|
+
"--file", filepath.FromSlash(probe.file),
|
|
82
|
+
"--output", "js",
|
|
83
|
+
"--out", outPath,
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
if code != 3 {
|
|
87
|
+
t.Fatalf("an empty emit must still fail with code 3, got %d\nstderr=%s", code, errText)
|
|
88
|
+
}
|
|
89
|
+
if !strings.Contains(errText, "no output produced") {
|
|
90
|
+
t.Fatalf("an empty emit must still report the cause:\n%s", errText)
|
|
91
|
+
}
|
|
92
|
+
// An empty emit leaves runTransformSingle through `if code != 0`, a
|
|
93
|
+
// different branch than the diagnostic route the atomicity case pins, so
|
|
94
|
+
// withholding the artifact needs its own check here.
|
|
95
|
+
if _, err := os.Stat(outPath); !os.IsNotExist(err) {
|
|
96
|
+
t.Fatalf("an empty emit must publish nothing, but --out exists: %v", err)
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestTransformSingleFileJSLocatesOutputAcrossLayouts verifies `--output js`
|
|
11
|
+
// finds its artifact wherever the compiler places the emit.
|
|
12
|
+
//
|
|
13
|
+
// `transformSingleToJavaScript` captures the emit by matching the write callback
|
|
14
|
+
// against the requested source. Comparing whole path stems made that match ask
|
|
15
|
+
// whether `dist/main` equals `src/main`, so every project with an `outDir` --
|
|
16
|
+
// which is every realistic layout -- reported "no output produced" and exited 3
|
|
17
|
+
// over a transform that had in fact succeeded (samchon/typia#2134). `outDir` is
|
|
18
|
+
// only one of the settings that reposition an emit, so this pins the whole class
|
|
19
|
+
// rather than the reported witness: the match must come from the compiler's own
|
|
20
|
+
// output-path resolution, the same one the emitter uses to choose where to
|
|
21
|
+
// write, so no combination of `outDir`, `rootDir`, `rootDirs`, or source nesting
|
|
22
|
+
// can desynchronize the two.
|
|
23
|
+
//
|
|
24
|
+
// 1. Build the same typia-valid source under each output-path layout.
|
|
25
|
+
// 2. Transform it with `--output js --out`.
|
|
26
|
+
// 3. Require exit 0, a silent stderr, and a published artifact carrying the
|
|
27
|
+
// lowered validator rather than the untransformed call.
|
|
28
|
+
func TestTransformSingleFileJSLocatesOutputAcrossLayouts(t *testing.T) {
|
|
29
|
+
for _, layout := range []struct {
|
|
30
|
+
name string
|
|
31
|
+
extra []string
|
|
32
|
+
file string
|
|
33
|
+
}{
|
|
34
|
+
// The reported regression. With no `rootDir` the common source directory is
|
|
35
|
+
// the tsconfig's own directory, so the emit lands at `dist/src/main.js`.
|
|
36
|
+
{
|
|
37
|
+
name: "out_dir",
|
|
38
|
+
extra: []string{`"outDir": "dist"`},
|
|
39
|
+
file: "src/main.ts",
|
|
40
|
+
},
|
|
41
|
+
// `rootDir` re-bases the emit again, to `dist/main.js`, so a fix keyed on
|
|
42
|
+
// `outDir` alone would still put the artifact somewhere else than expected.
|
|
43
|
+
{
|
|
44
|
+
name: "root_dir_and_out_dir",
|
|
45
|
+
extra: []string{`"rootDir": "src"`, `"outDir": "dist"`},
|
|
46
|
+
file: "src/main.ts",
|
|
47
|
+
},
|
|
48
|
+
// Nesting below the root dir carries into the output as `dist/deep/nested/
|
|
49
|
+
// main.js`: the emitted path differs from the source path in more than its
|
|
50
|
+
// leading directory.
|
|
51
|
+
{
|
|
52
|
+
name: "nested_source_directory",
|
|
53
|
+
extra: []string{`"rootDir": "src"`, `"outDir": "dist"`},
|
|
54
|
+
file: "src/deep/nested/main.ts",
|
|
55
|
+
},
|
|
56
|
+
// `rootDirs` is a module-resolution feature and must not reposition the
|
|
57
|
+
// emit. Pin that the resolution agrees instead of assuming it.
|
|
58
|
+
{
|
|
59
|
+
name: "root_dirs_and_out_dir",
|
|
60
|
+
extra: []string{`"rootDirs": ["src", "generated"]`, `"outDir": "dist"`},
|
|
61
|
+
file: "src/main.ts",
|
|
62
|
+
},
|
|
63
|
+
// One source, three writes through the one callback: `dist/main.js`,
|
|
64
|
+
// `dist/main.js.map`, and `dist/main.d.ts`. Finding the artifact is not
|
|
65
|
+
// enough here -- the check has to tell it apart from its own siblings. The
|
|
66
|
+
// map is the trap, since its `sourcesContent` embeds the original
|
|
67
|
+
// TypeScript, so capturing it would publish text still carrying
|
|
68
|
+
// `typia.is<` behind exit 0.
|
|
69
|
+
{
|
|
70
|
+
name: "declaration_and_source_map",
|
|
71
|
+
extra: []string{
|
|
72
|
+
`"rootDir": "src"`,
|
|
73
|
+
`"outDir": "dist"`,
|
|
74
|
+
`"declaration": true`,
|
|
75
|
+
`"sourceMap": true`,
|
|
76
|
+
},
|
|
77
|
+
file: "src/main.ts",
|
|
78
|
+
},
|
|
79
|
+
// The one layout that already worked, because the emit lands beside its
|
|
80
|
+
// source. It must keep working.
|
|
81
|
+
{
|
|
82
|
+
name: "no_out_dir",
|
|
83
|
+
extra: nil,
|
|
84
|
+
file: "src/main.ts",
|
|
85
|
+
},
|
|
86
|
+
} {
|
|
87
|
+
t.Run(layout.name, func(t *testing.T) {
|
|
88
|
+
project := transformSingleFileLayoutProject(t, layout.extra, map[string]string{
|
|
89
|
+
layout.file: transformSingleFileValidSource,
|
|
90
|
+
})
|
|
91
|
+
outPath := filepath.Join(project, "artifact", "main.js")
|
|
92
|
+
_, errText, code := ttscTypiaTestCapture(func() int {
|
|
93
|
+
return runTransform([]string{
|
|
94
|
+
"--cwd", project,
|
|
95
|
+
"--tsconfig", "tsconfig.json",
|
|
96
|
+
"--file", filepath.FromSlash(layout.file),
|
|
97
|
+
"--output", "js",
|
|
98
|
+
"--out", outPath,
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
if code != 0 {
|
|
102
|
+
t.Fatalf("`--output js` should publish under this layout, got %d\nstderr=%s", code, errText)
|
|
103
|
+
}
|
|
104
|
+
if errText != "" {
|
|
105
|
+
t.Fatalf("`--output js` reported diagnostics under this layout:\n%s", errText)
|
|
106
|
+
}
|
|
107
|
+
data, err := os.ReadFile(outPath)
|
|
108
|
+
if err != nil {
|
|
109
|
+
t.Fatalf("`--output js` published no artifact: %v", err)
|
|
110
|
+
}
|
|
111
|
+
text := string(data)
|
|
112
|
+
if strings.Contains(text, "typia.is<") {
|
|
113
|
+
t.Fatalf("published artifact still carries the untransformed call:\n%s", text)
|
|
114
|
+
}
|
|
115
|
+
if !strings.Contains(text, `"number"`) {
|
|
116
|
+
t.Fatalf("published artifact does not carry the lowered validator:\n%s", text)
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// transformSingleFileLayoutProject writes a project whose tsconfig carries the
|
|
123
|
+
// given extra `compilerOptions` entries and whose sources are the given
|
|
124
|
+
// project-relative slash paths, sharing the typia stub the other transform
|
|
125
|
+
// fixtures use. It exists so one fixture can vary only the output-path settings.
|
|
126
|
+
func transformSingleFileLayoutProject(
|
|
127
|
+
t *testing.T,
|
|
128
|
+
extra []string,
|
|
129
|
+
sources map[string]string,
|
|
130
|
+
) string {
|
|
131
|
+
t.Helper()
|
|
132
|
+
project := t.TempDir()
|
|
133
|
+
options := append([]string{
|
|
134
|
+
`"target": "ES2022"`,
|
|
135
|
+
`"module": "commonjs"`,
|
|
136
|
+
`"moduleResolution": "bundler"`,
|
|
137
|
+
`"ignoreDeprecations": "6.0"`,
|
|
138
|
+
`"types": ["*"]`,
|
|
139
|
+
`"esModuleInterop": true`,
|
|
140
|
+
`"strict": true`,
|
|
141
|
+
`"skipLibCheck": true`,
|
|
142
|
+
}, extra...)
|
|
143
|
+
tsconfig := "{\n \"compilerOptions\": {\n " +
|
|
144
|
+
strings.Join(options, ",\n ") +
|
|
145
|
+
"\n },\n \"include\": [\"src\"]\n}\n"
|
|
146
|
+
if err := os.WriteFile(filepath.Join(project, "tsconfig.json"), []byte(tsconfig), 0o644); err != nil {
|
|
147
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
148
|
+
}
|
|
149
|
+
transformDiagnosticWriteTypiaStub(t, project)
|
|
150
|
+
for rel, body := range sources {
|
|
151
|
+
path := filepath.Join(project, filepath.FromSlash(rel))
|
|
152
|
+
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
153
|
+
t.Fatalf("mkdir %s: %v", rel, err)
|
|
154
|
+
}
|
|
155
|
+
if err := os.WriteFile(path, []byte(body), 0o644); err != nil {
|
|
156
|
+
t.Fatalf("write %s: %v", rel, err)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return project
|
|
160
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestTransformSingleFileSuccessPublishesArtifact verifies the positive twin.
|
|
11
|
+
//
|
|
12
|
+
// Consulting the diagnostics before publishing must not make a clean transform
|
|
13
|
+
// withhold its artifact: the guard has to key on a reported diagnostic, not on
|
|
14
|
+
// merely having run. This pins the success side of the same decision in both
|
|
15
|
+
// output modes, including that the call was actually rewritten rather than
|
|
16
|
+
// copied through as an untransformed stub.
|
|
17
|
+
//
|
|
18
|
+
// 1. Transform a typia-valid source with `--out` in `ts` and `js`.
|
|
19
|
+
// 2. Require exit 0 and a silent stderr.
|
|
20
|
+
// 3. Require the published artifact to exist and carry the lowered validator.
|
|
21
|
+
func TestTransformSingleFileSuccessPublishesArtifact(t *testing.T) {
|
|
22
|
+
for _, output := range []string{"ts", "js"} {
|
|
23
|
+
t.Run(output, func(t *testing.T) {
|
|
24
|
+
project := transformSingleFileProject(t, transformSingleFileValidSource)
|
|
25
|
+
outPath := filepath.Join(project, "dist", "main."+output)
|
|
26
|
+
_, errText, code := ttscTypiaTestCapture(func() int {
|
|
27
|
+
return runTransform([]string{
|
|
28
|
+
"--cwd", project,
|
|
29
|
+
"--tsconfig", "tsconfig.json",
|
|
30
|
+
"--file", filepath.Join("src", "main.ts"),
|
|
31
|
+
"--output", output,
|
|
32
|
+
"--out", outPath,
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
if code != 0 {
|
|
36
|
+
t.Fatalf("valid single-file transform should succeed, got %d\nstderr=%s", code, errText)
|
|
37
|
+
}
|
|
38
|
+
if errText != "" {
|
|
39
|
+
t.Fatalf("valid single-file transform reported diagnostics:\n%s", errText)
|
|
40
|
+
}
|
|
41
|
+
data, err := os.ReadFile(outPath)
|
|
42
|
+
if err != nil {
|
|
43
|
+
t.Fatalf("valid single-file transform published no artifact: %v", err)
|
|
44
|
+
}
|
|
45
|
+
text := string(data)
|
|
46
|
+
if strings.Contains(text, "typia.is<") {
|
|
47
|
+
t.Fatalf("published artifact still carries the untransformed call:\n%s", text)
|
|
48
|
+
}
|
|
49
|
+
if !strings.Contains(text, `"number"`) {
|
|
50
|
+
t.Fatalf("published artifact does not carry the lowered validator:\n%s", text)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"path/filepath"
|
|
5
|
+
"strings"
|
|
6
|
+
"testing"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// TestTransformWasmHostArgvReportsDiagnostics verifies the wasm host contract.
|
|
10
|
+
//
|
|
11
|
+
// `main_wasm.go` is `js && wasm` only, so its `jsTransform` cannot be called
|
|
12
|
+
// here. It carries no decision of its own: it renders the JS options object into
|
|
13
|
+
// argv via `transformArgs`, hands that to this same `runTransform`, and returns
|
|
14
|
+
// the resulting `{ code, stdout, stderr }`. Driving the exact argv it builds --
|
|
15
|
+
// `--cwd=`/`--tsconfig=`/`--file=` with its `--output=ts` default -- therefore
|
|
16
|
+
// pins what a playground caller observes: the typia error, not a stub.
|
|
17
|
+
//
|
|
18
|
+
// 1. Build the argv `transformArgs` produces for a single-file request.
|
|
19
|
+
// 2. Run it against a typia-invalid source.
|
|
20
|
+
// 3. Require code 3, the diagnostic in stderr, and no stub in stdout.
|
|
21
|
+
func TestTransformWasmHostArgvReportsDiagnostics(t *testing.T) {
|
|
22
|
+
project := transformSingleFileProject(t, transformDiagnosticSource)
|
|
23
|
+
argv := []string{
|
|
24
|
+
"--cwd=" + project,
|
|
25
|
+
"--tsconfig=tsconfig.json",
|
|
26
|
+
"--file=" + filepath.Join(project, "src", "main.ts"),
|
|
27
|
+
"--output=ts",
|
|
28
|
+
}
|
|
29
|
+
outText, errText, code := ttscTypiaTestCapture(func() int { return runTransform(argv) })
|
|
30
|
+
if code != 3 {
|
|
31
|
+
t.Fatalf("wasm host argv should surface code 3, got %d\nstdout=%s\nstderr=%s", code, outText, errText)
|
|
32
|
+
}
|
|
33
|
+
if !strings.Contains(errText, "non-specified generic argument") {
|
|
34
|
+
t.Fatalf("wasm host argv did not surface the typia diagnostic:\n%s", errText)
|
|
35
|
+
}
|
|
36
|
+
if outText != "" {
|
|
37
|
+
t.Fatalf("wasm host argv returned an untransformed stub as stdout:\n%s", outText)
|
|
38
|
+
}
|
|
39
|
+
}
|