typia 13.1.1 → 13.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/lib/_virtual/_rolldown/runtime.mjs +1 -5
- package/lib/executable/FileSystemIdentity.d.ts +44 -0
- package/lib/executable/FileSystemIdentity.js +213 -0
- package/lib/executable/FileSystemIdentity.js.map +1 -0
- package/lib/executable/FileSystemIdentity.mjs +133 -0
- package/lib/executable/FileSystemIdentity.mjs.map +1 -0
- package/lib/executable/TypiaGenerateWizard.js +272 -106
- package/lib/executable/TypiaGenerateWizard.js.map +1 -1
- package/lib/executable/TypiaGenerateWizard.mjs +239 -95
- package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
- package/lib/functional.d.ts +15 -12
- package/lib/functional.js.map +1 -1
- package/lib/functional.mjs.map +1 -1
- package/lib/internal/_ProtobufReader.d.ts +32 -0
- package/lib/internal/_ProtobufReader.js +148 -48
- package/lib/internal/_ProtobufReader.js.map +1 -1
- package/lib/internal/_ProtobufReader.mjs +137 -41
- package/lib/internal/_ProtobufReader.mjs.map +1 -1
- package/lib/internal/_createStandardSchema.js +18 -1
- package/lib/internal/_createStandardSchema.js.map +1 -1
- package/lib/internal/_createStandardSchema.mjs +12 -1
- package/lib/internal/_createStandardSchema.mjs.map +1 -1
- package/lib/internal/_decimal.d.ts +14 -0
- package/lib/internal/_decimal.js +61 -0
- package/lib/internal/_decimal.js.map +1 -0
- package/lib/internal/_decimal.mjs +49 -0
- package/lib/internal/_decimal.mjs.map +1 -0
- package/lib/internal/_httpQueryParseURLSearchParams.js +23 -2
- package/lib/internal/_httpQueryParseURLSearchParams.js.map +1 -1
- package/lib/internal/_httpQueryParseURLSearchParams.mjs +20 -2
- package/lib/internal/_httpQueryParseURLSearchParams.mjs.map +1 -1
- package/lib/internal/_isFormatByte.js +2 -5
- package/lib/internal/_isFormatByte.js.map +1 -1
- package/lib/internal/_isFormatByte.mjs +2 -5
- package/lib/internal/_isFormatByte.mjs.map +1 -1
- package/lib/internal/_isFormatDate.js +15 -2
- package/lib/internal/_isFormatDate.js.map +1 -1
- package/lib/internal/_isFormatDate.mjs +22 -2
- package/lib/internal/_isFormatDate.mjs.map +1 -1
- package/lib/internal/_isFormatDateTime.js +21 -2
- package/lib/internal/_isFormatDateTime.js.map +1 -1
- package/lib/internal/_isFormatDateTime.mjs +13 -2
- package/lib/internal/_isFormatDateTime.mjs.map +1 -1
- package/lib/internal/_isFormatIri.js +3 -2
- package/lib/internal/_isFormatIri.js.map +1 -1
- package/lib/internal/_isFormatIri.mjs +3 -2
- package/lib/internal/_isFormatIri.mjs.map +1 -1
- package/lib/internal/_isFormatIriReference.js +10 -2
- package/lib/internal/_isFormatIriReference.js.map +1 -1
- package/lib/internal/_isFormatIriReference.mjs +9 -2
- package/lib/internal/_isFormatIriReference.mjs.map +1 -1
- package/lib/internal/_isFormatUriReference.js +1 -1
- package/lib/internal/_isFormatUriReference.js.map +1 -1
- package/lib/internal/_isFormatUriReference.mjs +1 -1
- package/lib/internal/_isFormatUriReference.mjs.map +1 -1
- package/lib/internal/_isMultipleOf.d.ts +1 -0
- package/lib/internal/_isMultipleOf.js +13 -0
- package/lib/internal/_isMultipleOf.js.map +1 -0
- package/lib/internal/_isMultipleOf.mjs +12 -0
- package/lib/internal/_isMultipleOf.mjs.map +1 -0
- package/lib/internal/_isTypeFloat.js +1 -1
- package/lib/internal/_isTypeFloat.js.map +1 -1
- package/lib/internal/_isTypeFloat.mjs +1 -1
- package/lib/internal/_isTypeFloat.mjs.map +1 -1
- package/lib/internal/_isTypeInt64.js +1 -0
- package/lib/internal/_isTypeInt64.js.map +1 -1
- package/lib/internal/_isTypeInt64.mjs.map +1 -1
- package/lib/internal/_isTypeInt64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeInt64Bigint.js +15 -0
- package/lib/internal/_isTypeInt64Bigint.js.map +1 -0
- package/lib/internal/_isTypeInt64Bigint.mjs +8 -0
- package/lib/internal/_isTypeInt64Bigint.mjs.map +1 -0
- package/lib/internal/_isTypeUint64.js +1 -0
- package/lib/internal/_isTypeUint64.js.map +1 -1
- package/lib/internal/_isTypeUint64.mjs.map +1 -1
- package/lib/internal/_isTypeUint64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeUint64Bigint.js +10 -0
- package/lib/internal/_isTypeUint64Bigint.js.map +1 -0
- package/lib/internal/_isTypeUint64Bigint.mjs +8 -0
- package/lib/internal/_isTypeUint64Bigint.mjs.map +1 -0
- package/lib/internal/_isUniqueItems.js +96 -109
- package/lib/internal/_isUniqueItems.js.map +1 -1
- package/lib/internal/_isUniqueItems.mjs +62 -50
- package/lib/internal/_isUniqueItems.mjs.map +1 -1
- package/lib/internal/_jsonStringifyArray.d.ts +1 -0
- package/lib/internal/_jsonStringifyArray.js +48 -0
- package/lib/internal/_jsonStringifyArray.js.map +1 -0
- package/lib/internal/_jsonStringifyArray.mjs +40 -0
- package/lib/internal/_jsonStringifyArray.mjs.map +1 -0
- package/lib/internal/_jsonStringifyElement.d.ts +1 -0
- package/lib/internal/_jsonStringifyElement.js +23 -0
- package/lib/internal/_jsonStringifyElement.js.map +1 -0
- package/lib/internal/_jsonStringifyElement.mjs +23 -0
- package/lib/internal/_jsonStringifyElement.mjs.map +1 -0
- package/lib/internal/_jsonStringifyProperty.d.ts +1 -0
- package/lib/internal/_jsonStringifyProperty.js +31 -0
- package/lib/internal/_jsonStringifyProperty.js.map +1 -0
- package/lib/internal/_jsonStringifyProperty.mjs +31 -0
- package/lib/internal/_jsonStringifyProperty.mjs.map +1 -0
- package/lib/internal/_llmApplicationFinalize.js +1 -1
- package/lib/internal/_llmApplicationFinalize.js.map +1 -1
- package/lib/internal/_llmApplicationFinalize.mjs +1 -1
- package/lib/internal/_llmApplicationFinalize.mjs.map +1 -1
- package/lib/internal/_notationAny.js +8 -1
- package/lib/internal/_notationAny.js.map +1 -1
- package/lib/internal/_notationAny.mjs +7 -1
- package/lib/internal/_notationAny.mjs.map +1 -1
- package/lib/internal/_notationAssign.d.ts +1 -0
- package/lib/internal/_notationAssign.js +18 -0
- package/lib/internal/_notationAssign.js.map +1 -0
- package/lib/internal/_notationAssign.mjs +17 -0
- package/lib/internal/_notationAssign.mjs.map +1 -0
- package/lib/internal/_notationCamel.js +30 -9
- package/lib/internal/_notationCamel.js.map +1 -1
- package/lib/internal/_notationCamel.mjs +13 -5
- package/lib/internal/_notationCamel.mjs.map +1 -1
- package/lib/internal/_notationKebab.d.ts +1 -0
- package/lib/internal/_notationKebab.js +15 -0
- package/lib/internal/_notationKebab.js.map +1 -0
- package/lib/internal/_notationKebab.mjs +15 -0
- package/lib/internal/_notationKebab.mjs.map +1 -0
- package/lib/internal/_notationKeyCollision.d.ts +1 -0
- package/lib/internal/_notationKeyCollision.js +8 -0
- package/lib/internal/_notationKeyCollision.js.map +1 -0
- package/lib/internal/_notationKeyCollision.mjs +8 -0
- package/lib/internal/_notationKeyCollision.mjs.map +1 -0
- package/lib/internal/_notationPascal.js +20 -5
- package/lib/internal/_notationPascal.js.map +1 -1
- package/lib/internal/_notationPascal.mjs +10 -5
- package/lib/internal/_notationPascal.mjs.map +1 -1
- package/lib/internal/_notationSnake.js +25 -22
- package/lib/internal/_notationSnake.js.map +1 -1
- package/lib/internal/_notationSnake.mjs +11 -11
- package/lib/internal/_notationSnake.mjs.map +1 -1
- package/lib/internal/_plainCloneAny.js +174 -38
- package/lib/internal/_plainCloneAny.js.map +1 -1
- package/lib/internal/_plainCloneAny.mjs +126 -22
- package/lib/internal/_plainCloneAny.mjs.map +1 -1
- package/lib/internal/_randomArray.d.ts +1 -1
- package/lib/internal/_randomArray.js +11 -4
- package/lib/internal/_randomArray.js.map +1 -1
- package/lib/internal/_randomArray.mjs +9 -3
- package/lib/internal/_randomArray.mjs.map +1 -1
- package/lib/internal/_randomFormatByte.d.ts +2 -1
- package/lib/internal/_randomFormatByte.js +25 -1
- package/lib/internal/_randomFormatByte.js.map +1 -1
- package/lib/internal/_randomFormatByte.mjs +20 -1
- package/lib/internal/_randomFormatByte.mjs.map +1 -1
- package/lib/internal/_randomFormatDate.d.ts +3 -4
- package/lib/internal/_randomFormatDate.js +3 -10
- package/lib/internal/_randomFormatDate.js.map +1 -1
- package/lib/internal/_randomFormatDate.mjs +3 -6
- package/lib/internal/_randomFormatDate.mjs.map +1 -1
- package/lib/internal/_randomFormatDatetime.d.ts +3 -4
- package/lib/internal/_randomFormatDatetime.js +26 -8
- package/lib/internal/_randomFormatDatetime.js.map +1 -1
- package/lib/internal/_randomFormatDatetime.mjs +17 -6
- package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
- package/lib/internal/_randomFormatDuration.d.ts +2 -1
- package/lib/internal/_randomFormatDuration.js +23 -14
- package/lib/internal/_randomFormatDuration.js.map +1 -1
- package/lib/internal/_randomFormatDuration.mjs +22 -13
- package/lib/internal/_randomFormatDuration.mjs.map +1 -1
- package/lib/internal/_randomFormatEmail.d.ts +2 -1
- package/lib/internal/_randomFormatEmail.js +8 -1
- package/lib/internal/_randomFormatEmail.js.map +1 -1
- package/lib/internal/_randomFormatEmail.mjs +5 -1
- package/lib/internal/_randomFormatEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatHostname.d.ts +8 -1
- package/lib/internal/_randomFormatHostname.js +45 -2
- package/lib/internal/_randomFormatHostname.js.map +1 -1
- package/lib/internal/_randomFormatHostname.mjs +38 -2
- package/lib/internal/_randomFormatHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.d.ts +2 -1
- package/lib/internal/_randomFormatIdnEmail.js +16 -2
- package/lib/internal/_randomFormatIdnEmail.js.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.mjs +11 -2
- package/lib/internal/_randomFormatIdnEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.d.ts +2 -1
- package/lib/internal/_randomFormatIdnHostname.js +26 -1
- package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.mjs +25 -2
- package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv4.d.ts +2 -1
- package/lib/internal/_randomFormatIpv4.js +32 -1
- package/lib/internal/_randomFormatIpv4.js.map +1 -1
- package/lib/internal/_randomFormatIpv4.mjs +23 -1
- package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv6.d.ts +2 -1
- package/lib/internal/_randomFormatIpv6.js +58 -1
- package/lib/internal/_randomFormatIpv6.js.map +1 -1
- package/lib/internal/_randomFormatIpv6.mjs +45 -1
- package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
- package/lib/internal/_randomFormatIri.d.ts +2 -1
- package/lib/internal/_randomFormatIri.js +1 -1
- package/lib/internal/_randomFormatIri.js.map +1 -1
- package/lib/internal/_randomFormatIri.mjs +1 -1
- package/lib/internal/_randomFormatIri.mjs.map +1 -1
- package/lib/internal/_randomFormatIriReference.d.ts +2 -1
- package/lib/internal/_randomFormatIriReference.js +1 -1
- package/lib/internal/_randomFormatIriReference.js.map +1 -1
- package/lib/internal/_randomFormatIriReference.mjs +1 -1
- package/lib/internal/_randomFormatIriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatJsonPointer.js +20 -1
- package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.mjs +15 -1
- package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatPassword.d.ts +2 -1
- package/lib/internal/_randomFormatPassword.js +7 -5
- package/lib/internal/_randomFormatPassword.js.map +1 -1
- package/lib/internal/_randomFormatPassword.mjs +5 -1
- package/lib/internal/_randomFormatPassword.mjs.map +1 -1
- package/lib/internal/_randomFormatRegex.d.ts +2 -1
- package/lib/internal/_randomFormatRegex.js +15 -1
- package/lib/internal/_randomFormatRegex.js.map +1 -1
- package/lib/internal/_randomFormatRegex.mjs +14 -1
- package/lib/internal/_randomFormatRegex.mjs.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.js +20 -5
- package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs +21 -5
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatTime.d.ts +2 -1
- package/lib/internal/_randomFormatTime.js +34 -7
- package/lib/internal/_randomFormatTime.js.map +1 -1
- package/lib/internal/_randomFormatTime.mjs +37 -4
- package/lib/internal/_randomFormatTime.mjs.map +1 -1
- package/lib/internal/_randomFormatUri.d.ts +2 -1
- package/lib/internal/_randomFormatUri.js +1 -1
- package/lib/internal/_randomFormatUri.js.map +1 -1
- package/lib/internal/_randomFormatUri.mjs +1 -1
- package/lib/internal/_randomFormatUri.mjs.map +1 -1
- package/lib/internal/_randomFormatUriReference.d.ts +2 -1
- package/lib/internal/_randomFormatUriReference.js +1 -1
- package/lib/internal/_randomFormatUriReference.js.map +1 -1
- package/lib/internal/_randomFormatUriReference.mjs +1 -1
- package/lib/internal/_randomFormatUriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.d.ts +2 -1
- package/lib/internal/_randomFormatUriTemplate.js +1 -1
- package/lib/internal/_randomFormatUriTemplate.js.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs.map +1 -1
- package/lib/internal/_randomFormatUrl.d.ts +2 -1
- package/lib/internal/_randomFormatUrl.js +21 -1
- package/lib/internal/_randomFormatUrl.js.map +1 -1
- package/lib/internal/_randomFormatUrl.mjs +18 -1
- package/lib/internal/_randomFormatUrl.mjs.map +1 -1
- package/lib/internal/_randomFormatUuid.d.ts +2 -1
- package/lib/internal/_randomFormatUuid.js +3 -2
- package/lib/internal/_randomFormatUuid.js.map +1 -1
- package/lib/internal/_randomFormatUuid.mjs +3 -2
- package/lib/internal/_randomFormatUuid.mjs.map +1 -1
- package/lib/internal/_randomInteger.js +59 -28
- package/lib/internal/_randomInteger.js.map +1 -1
- package/lib/internal/_randomInteger.mjs +56 -16
- package/lib/internal/_randomInteger.mjs.map +1 -1
- package/lib/internal/_randomMultiple.d.ts +8 -0
- package/lib/internal/_randomMultiple.js +168 -0
- package/lib/internal/_randomMultiple.js.map +1 -0
- package/lib/internal/_randomMultiple.mjs +158 -0
- package/lib/internal/_randomMultiple.mjs.map +1 -0
- package/lib/internal/_randomNumber.js +42 -42
- package/lib/internal/_randomNumber.js.map +1 -1
- package/lib/internal/_randomNumber.mjs +41 -27
- package/lib/internal/_randomNumber.mjs.map +1 -1
- package/lib/internal/_randomPattern.d.ts +2 -1
- package/lib/internal/_randomPattern.js +19 -4
- package/lib/internal/_randomPattern.js.map +1 -1
- package/lib/internal/_randomPattern.mjs +10 -4
- package/lib/internal/_randomPattern.mjs.map +1 -1
- package/lib/internal/_randomStringLength.d.ts +64 -0
- package/lib/internal/_randomStringLength.js +84 -0
- package/lib/internal/_randomStringLength.js.map +1 -0
- package/lib/internal/_randomStringLength.mjs +79 -0
- package/lib/internal/_randomStringLength.mjs.map +1 -0
- package/lib/internal/_stringLength.d.ts +1 -0
- package/lib/internal/_stringLength.js +11 -0
- package/lib/internal/_stringLength.js.map +1 -0
- package/lib/internal/_stringLength.mjs +10 -0
- package/lib/internal/_stringLength.mjs.map +1 -0
- package/lib/internal/_validateReport.js +4 -1
- package/lib/internal/_validateReport.js.map +1 -1
- package/lib/internal/_validateReport.mjs +2 -1
- package/lib/internal/_validateReport.mjs.map +1 -1
- package/lib/internal/private/__notationRename.d.ts +14 -0
- package/lib/internal/private/__notationRename.js +25 -0
- package/lib/internal/private/__notationRename.js.map +1 -0
- package/lib/internal/private/__notationRename.mjs +24 -0
- package/lib/internal/private/__notationRename.mjs.map +1 -0
- package/lib/internal/private/__randomComposition.d.ts +23 -0
- package/lib/internal/private/__randomComposition.js +48 -0
- package/lib/internal/private/__randomComposition.js.map +1 -0
- package/lib/internal/private/__randomComposition.mjs +54 -0
- package/lib/internal/private/__randomComposition.mjs.map +1 -0
- package/lib/internal/private/__randomEpoch.d.ts +19 -0
- package/lib/internal/private/__randomEpoch.js +31 -0
- package/lib/internal/private/__randomEpoch.js.map +1 -0
- package/lib/internal/private/__randomEpoch.mjs +28 -0
- package/lib/internal/private/__randomEpoch.mjs.map +1 -0
- package/lib/json.d.ts +2 -2
- package/lib/json.mjs.map +1 -1
- package/lib/module.d.ts +2 -2
- package/lib/module.js.map +1 -1
- package/lib/module.mjs.map +1 -1
- package/lib/notations.d.ts +20 -4
- package/lib/notations.js.map +1 -1
- package/lib/notations.mjs.map +1 -1
- package/native/adapter/plugin_options.go +117 -0
- package/native/adapter/plugin_options_payload_matrix_test.go +181 -0
- package/native/cmd/ttsc-typia/any_array_type_tags_transform_test.go +63 -9
- package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +152 -0
- package/native/cmd/ttsc-typia/build.go +84 -64
- package/native/cmd/ttsc-typia/build_no_emit_preserves_analysis_options_test.go +67 -0
- package/native/cmd/ttsc-typia/build_no_emit_transform_diagnostics_test.go +138 -0
- package/native/cmd/ttsc-typia/build_plugin_options_come_from_payload_test.go +48 -0
- package/native/cmd/ttsc-typia/build_transactional_emit_success_test.go +81 -0
- package/native/cmd/ttsc-typia/build_transform_failure_atomicity_test.go +138 -0
- package/native/cmd/ttsc-typia/callable_interface_function_semantics_transform_test.go +331 -0
- package/native/cmd/ttsc-typia/callable_type_literal_boundaries_transform_test.go +1184 -0
- package/native/cmd/ttsc-typia/command_routes_and_diagnostics_coverage_test.go +3 -1
- package/native/cmd/ttsc-typia/compare_functional_union_membership_transform_test.go +434 -0
- package/native/cmd/ttsc-typia/compare_less_nan_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/compare_native_object_overmatch_transform_test.go +161 -0
- package/native/cmd/ttsc-typia/compare_nondiscriminable_union_transform_test.go +343 -0
- package/native/cmd/ttsc-typia/compare_template_literal_union_transform_test.go +241 -0
- package/native/cmd/ttsc-typia/compare_union_discrimination_transform_test.go +289 -0
- package/native/cmd/ttsc-typia/default_library_spoof_native_identity_transform_test.go +216 -0
- package/native/cmd/ttsc-typia/escaped_property_key_path_transform_test.go +193 -0
- package/native/cmd/ttsc-typia/finite_option_number_leaf_transform_test.go +240 -0
- package/native/cmd/ttsc-typia/functional_promised_type_transform_test.go +220 -0
- package/native/cmd/ttsc-typia/functional_receiver_transform_test.go +232 -0
- package/native/cmd/ttsc-typia/is_object_function_member_transform_test.go +205 -0
- package/native/cmd/ttsc-typia/json_application_alias_function_validation_transform_test.go +151 -0
- package/native/cmd/ttsc-typia/json_is_stringify_finite_number_transform_test.go +198 -0
- package/native/cmd/ttsc-typia/json_schema_dynamic_key_determinism_transform_test.go +246 -0
- package/native/cmd/ttsc-typia/json_stringify_contextual_undefined_transform_test.go +556 -0
- package/native/cmd/ttsc-typia/json_stringify_special_key_transform_test.go +238 -0
- package/native/cmd/ttsc-typia/lib_replacement_native_identity_transform_test.go +277 -0
- package/native/cmd/ttsc-typia/main_wasm.go +21 -2
- package/native/cmd/ttsc-typia/native_collection_identity_is_transform_test.go +234 -0
- package/native/cmd/ttsc-typia/native_generic_name_guard_is_transform_test.go +194 -0
- package/native/cmd/ttsc-typia/native_name_collision_is_transform_test.go +204 -0
- package/native/cmd/ttsc-typia/native_named_intersection_union_transform_test.go +390 -0
- package/native/cmd/ttsc-typia/node_buffer_native_exports_is_transform_test.go +526 -0
- package/native/cmd/ttsc-typia/non_trailing_rest_tuple_transform_test.go +23 -11
- package/native/cmd/ttsc-typia/notation_dynamic_keys_transform_test.go +286 -0
- package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +1 -1
- package/native/cmd/ttsc-typia/notation_literal_collision_transform_test.go +164 -0
- package/native/cmd/ttsc-typia/notation_pascal_case_transform_test.go +230 -0
- package/native/cmd/ttsc-typia/notation_unicode_key_transform_test.go +309 -0
- package/native/cmd/ttsc-typia/package_declaration_native_identity_is_transform_test.go +293 -0
- package/native/cmd/ttsc-typia/pattern_line_terminator_escape_transform_test.go +224 -0
- package/native/cmd/ttsc-typia/plain_prune_union_object_overmatch_transform_test.go +219 -0
- package/native/cmd/ttsc-typia/plugin_options_payload_helpers_test.go +181 -0
- package/native/cmd/ttsc-typia/private_field_filter_is_transform_test.go +278 -0
- package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +73 -27
- package/native/cmd/ttsc-typia/project_dependencies_barrel_reexport_transform_test.go +120 -0
- package/native/cmd/ttsc-typia/project_dependencies_collapsed_alias_transform_test.go +134 -0
- package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +135 -0
- package/native/cmd/ttsc-typia/project_dependencies_default_barrel_transform_test.go +114 -0
- package/native/cmd/ttsc-typia/project_dependencies_empty_heritage_transform_test.go +100 -0
- package/native/cmd/ttsc-typia/project_dependencies_envelope_transform_test.go +148 -0
- package/native/cmd/ttsc-typia/project_dependencies_index_signature_alias_transform_test.go +139 -0
- package/native/cmd/ttsc-typia/project_dependencies_local_reexport_transform_test.go +122 -0
- package/native/cmd/ttsc-typia/project_dependencies_signature_alias_transform_test.go +125 -0
- package/native/cmd/ttsc-typia/project_dependencies_star_barrel_transform_test.go +112 -0
- package/native/cmd/ttsc-typia/project_reference_graph_envelope_transform_test.go +190 -0
- package/native/cmd/ttsc-typia/protobuf_diagnostic_code_transform_test.go +167 -0
- package/native/cmd/ttsc-typia/protobuf_is_encode_finite_number_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/protobuf_sequence_field_numbers_transform_test.go +52 -22
- package/native/cmd/ttsc-typia/symbol_index_domain_transform_test.go +316 -0
- package/native/cmd/ttsc-typia/symbol_key_member_filter_transform_test.go +279 -0
- package/native/cmd/ttsc-typia/template_interpolation_type_tags_transform_test.go +86 -23
- package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
- package/native/cmd/ttsc-typia/transform.go +251 -39
- package/native/cmd/ttsc-typia/{transform_declaration_source_produces_no_js_test.go → transform_declaration_source_produces_no_javascript_test.go} +10 -2
- package/native/cmd/ttsc-typia/transform_fixtures_emit_coverage_test.go +21 -4
- package/native/cmd/ttsc-typia/transform_helpers_test.go +236 -3
- package/native/cmd/ttsc-typia/transform_plugin_options_come_from_payload_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_atomicity_test.go +114 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_writes_no_stdout_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go +81 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_empty_emit_reports_no_output_test.go +100 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_locates_output_across_layouts_test.go +160 -0
- package/native/cmd/ttsc-typia/transform_single_file_success_publishes_artifact_test.go +54 -0
- package/native/cmd/ttsc-typia/transform_wasm_host_argv_reports_diagnostics_test.go +39 -0
- package/native/cmd/ttsc-typia/tuple_optional_compare_clone_transform_test.go +227 -0
- package/native/cmd/ttsc-typia/user_global_native_identity_transform_test.go +484 -0
- package/native/core/factories/FormatCheatSheet.go +40 -7
- package/native/core/factories/IdentifierFactory.go +131 -4
- package/native/core/factories/MetadataCommentTagFactory.go +83 -40
- package/native/core/factories/MetadataTypeTagFactory.go +13 -1
- package/native/core/factories/NumericRangeFactory.go +60 -17
- package/native/core/factories/ProtobufFactory.go +13 -5
- package/native/core/factories/factory_utility_coverage_test.go +8 -2
- package/native/core/factories/format_alias_resolves_to_cheat_sheet_test.go +57 -0
- package/native/core/factories/format_alias_table_targets_the_cheat_sheet_test.go +44 -0
- package/native/core/factories/identifier_factory_postfix_escapes_every_key_test.go +147 -0
- package/native/core/factories/identifier_factory_postfix_survives_every_code_point_test.go +86 -0
- package/native/core/factories/internal/metadata/MetadataHelper.go +226 -17
- package/native/core/factories/internal/metadata/emplace_metadata_object.go +141 -8
- package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
- package/native/core/factories/internal/metadata/iterate_metadata_function.go +5 -12
- package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +111 -29
- package/native/core/factories/internal/metadata/iterate_metadata_map.go +5 -0
- package/native/core/factories/internal/metadata/iterate_metadata_native.go +45 -2
- package/native/core/factories/internal/metadata/iterate_metadata_set.go +5 -0
- package/native/core/factories/internal/metadata/type_arguments_precondition_test.go +70 -0
- package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +39 -0
- package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go +84 -0
- package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go +60 -0
- package/native/core/factories/metadata_type_tag_factory_declarations_test.go +86 -0
- package/native/core/factories/metadata_type_tag_factory_keeps_bool_form_exclusivity_test.go +38 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go +65 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_duplicated_array_form_tags_test.go +41 -0
- package/native/core/factories/numeric_range_factory_enforces_64bit_bounds_test.go +69 -0
- package/native/core/factories/protobuf_recovery_ownership_test.go +64 -0
- package/native/core/programmers/IsProgrammer.go +15 -1
- package/native/core/programmers/RandomProgrammer.go +51 -14
- package/native/core/programmers/compare/CompareEqualProgrammer.go +410 -8
- package/native/core/programmers/compare/CompareLessProgrammer.go +4 -2
- package/native/core/programmers/functional/FunctionalAssertFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalAssertReturnProgrammer.go +6 -14
- package/native/core/programmers/functional/FunctionalIsFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +49 -14
- package/native/core/programmers/functional/FunctionalIsReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/internal/FunctionalGeneralProgrammer.go +4 -17
- package/native/core/programmers/helpers/CloneJoiner.go +32 -0
- package/native/core/programmers/helpers/FunctionProgrammer.go +6 -13
- package/native/core/programmers/helpers/NotationJoiner.go +86 -28
- package/native/core/programmers/helpers/StringifyJoinder.go +161 -51
- package/native/core/programmers/helpers/UnionExplorer.go +203 -61
- package/native/core/programmers/helpers/joiner_branch_coverage_test.go +116 -118
- package/native/core/programmers/helpers/union_explorer_coverage_test.go +1 -1
- package/native/core/programmers/internal/CheckerProgrammer.go +100 -48
- package/native/core/programmers/iterate/check_template.go +344 -32
- package/native/core/programmers/iterate/iterate_check_coverage_test.go +76 -158
- package/native/core/programmers/iterate/iterate_utility_coverage_test.go +231 -270
- package/native/core/programmers/iterate/json_schema_discriminator.go +36 -10
- package/native/core/programmers/iterate/json_schema_discriminator_declaration_syntax_test.go +205 -0
- package/native/core/programmers/iterate/json_schema_object.go +49 -7
- package/native/core/programmers/iterate/json_schema_pattern_property_order_test.go +44 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader.go +674 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_boolean_default_test.go +95 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_test.go +123 -0
- package/native/core/programmers/iterate/template_interpolation_tags_test.go +40 -8
- package/native/core/programmers/iterate/template_runtime_pattern.go +63 -7
- package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
- package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
- package/native/core/programmers/json/JsonStringifyProgrammer.go +47 -6
- package/native/core/programmers/llm/LlmApplicationProgrammer.go +21 -11
- package/native/core/programmers/llm/LlmSchemaProgrammer.go +23 -6
- package/native/core/programmers/llm/llm_reference_codec_test.go +24 -0
- package/native/core/programmers/notations/NotationGeneralProgrammer.go +183 -67
- package/native/core/programmers/notations/notation_general_helpers_test.go +1 -3
- package/native/core/programmers/notations/notation_general_programmer_pascal_multiword_test.go +72 -0
- package/native/core/programmers/notations/notation_general_programmer_underscore_boundary_test.go +68 -0
- package/native/core/programmers/plain/PlainClassifyProgrammer.go +23 -15
- package/native/core/programmers/plain/PlainCloneProgrammer.go +20 -7
- package/native/core/programmers/plain/PlainPruneProgrammer.go +19 -5
- package/native/core/programmers/plain/plain_tuple_seed_recovery_ownership_test.go +25 -0
- package/native/core/programmers/protobuf/ProtobufDecodeProgrammer.go +37 -28
- package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +41 -22
- package/native/core/programmers/protobuf/protobuf_programmer_helper_coverage_test.go +26 -0
- package/native/core/programmers/random_programmer_length_argument_test.go +53 -0
- package/native/core/schemas/metadata/MetadataCollection.go +266 -25
- package/native/core/schemas/metadata/MetadataDefaultLibrary.go +81 -0
- package/native/core/schemas/metadata/MetadataDependency.go +388 -0
- package/native/core/schemas/metadata/MetadataObjectType.go +24 -22
- package/native/core/schemas/metadata/metadata_collection_generic_argument_dot_test.go +122 -0
- package/native/core/schemas/metadata/metadata_collection_name_allocation_test.go +147 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_cascade_test.go +55 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_test.go +68 -0
- package/native/core/utils/PatternUtil.go +13 -0
- package/native/core/utils/PromiseTypeFactory.go +59 -0
- package/native/core/utils/ProtobufNameEncoder.go +8 -0
- package/native/core/utils/promise_type_factory_semantics_test.go +118 -0
- package/native/go.mod +9 -1
- package/native/transform/CallExpressionTransformer.go +12 -0
- package/native/transform/features/json/JsonApplicationTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemaTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemasTransformer.go +5 -4
- package/native/transform/features/protobuf/ProtobufMessageTransformer.go +1 -1
- package/package.json +12 -4
- package/src/executable/FileSystemIdentity.ts +222 -0
- package/src/executable/TypiaGenerateWizard.ts +386 -113
- package/src/functional.ts +30 -60
- package/src/internal/_ProtobufReader.ts +161 -46
- package/src/internal/_createStandardSchema.ts +15 -1
- package/src/internal/_decimal.ts +69 -0
- package/src/internal/_httpQueryParseURLSearchParams.ts +24 -2
- package/src/internal/_isFormatByte.ts +2 -5
- package/src/internal/_isFormatDate.ts +15 -2
- package/src/internal/_isFormatDateTime.ts +28 -2
- package/src/internal/_isFormatIri.ts +5 -2
- package/src/internal/_isFormatIriReference.ts +11 -3
- package/src/internal/_isFormatUriReference.ts +1 -1
- package/src/internal/_isMultipleOf.ts +8 -0
- package/src/internal/_isTypeFloat.ts +1 -1
- package/src/internal/_isTypeInt64.ts +1 -0
- package/src/internal/_isTypeInt64Bigint.ts +12 -0
- package/src/internal/_isTypeUint64.ts +1 -0
- package/src/internal/_isTypeUint64Bigint.ts +7 -0
- package/src/internal/_isUniqueItems.ts +134 -132
- package/src/internal/_jsonStringifyArray.ts +50 -0
- package/src/internal/_jsonStringifyElement.ts +19 -0
- package/src/internal/_jsonStringifyProperty.ts +30 -0
- package/src/internal/_llmApplicationFinalize.ts +6 -1
- package/src/internal/_notationAny.ts +9 -4
- package/src/internal/_notationAssign.ts +20 -0
- package/src/internal/_notationCamel.ts +31 -10
- package/src/internal/_notationKebab.ts +11 -0
- package/src/internal/_notationKeyCollision.ts +9 -0
- package/src/internal/_notationPascal.ts +19 -6
- package/src/internal/_notationSnake.ts +24 -21
- package/src/internal/_plainCloneAny.ts +208 -33
- package/src/internal/_randomArray.ts +13 -4
- package/src/internal/_randomFormatByte.ts +31 -1
- package/src/internal/_randomFormatDate.ts +6 -17
- package/src/internal/_randomFormatDatetime.ts +34 -15
- package/src/internal/_randomFormatDuration.ts +30 -13
- package/src/internal/_randomFormatEmail.ts +8 -2
- package/src/internal/_randomFormatHostname.ts +48 -1
- package/src/internal/_randomFormatIdnEmail.ts +18 -2
- package/src/internal/_randomFormatIdnHostname.ts +34 -2
- package/src/internal/_randomFormatIpv4.ts +43 -2
- package/src/internal/_randomFormatIpv6.ts +67 -2
- package/src/internal/_randomFormatIri.ts +3 -1
- package/src/internal/_randomFormatIriReference.ts +3 -1
- package/src/internal/_randomFormatJsonPointer.ts +28 -2
- package/src/internal/_randomFormatPassword.ts +11 -6
- package/src/internal/_randomFormatRegex.ts +22 -1
- package/src/internal/_randomFormatRelativeJsonPointer.ts +26 -6
- package/src/internal/_randomFormatTime.ts +46 -10
- package/src/internal/_randomFormatUri.ts +3 -1
- package/src/internal/_randomFormatUriReference.ts +3 -1
- package/src/internal/_randomFormatUriTemplate.ts +3 -1
- package/src/internal/_randomFormatUrl.ts +25 -2
- package/src/internal/_randomFormatUuid.ts +10 -6
- package/src/internal/_randomInteger.ts +87 -40
- package/src/internal/_randomMultiple.ts +245 -0
- package/src/internal/_randomNumber.ts +72 -55
- package/src/internal/_randomPattern.ts +29 -4
- package/src/internal/_randomStringLength.ts +116 -0
- package/src/internal/_stringLength.ts +5 -0
- package/src/internal/_validateReport.ts +5 -1
- package/src/internal/private/__notationRename.ts +21 -0
- package/src/internal/private/__randomComposition.ts +50 -0
- package/src/internal/private/__randomEpoch.ts +34 -0
- package/src/json.ts +2 -2
- package/src/module.ts +4 -6
- package/src/notations.ts +20 -4
- package/lib/internal/private/__notationCapitalize.d.ts +0 -1
- package/lib/internal/private/__notationCapitalize.js +0 -6
- package/lib/internal/private/__notationCapitalize.js.map +0 -1
- package/lib/internal/private/__notationCapitalize.mjs +0 -6
- package/lib/internal/private/__notationCapitalize.mjs.map +0 -1
- package/lib/internal/private/__notationUnsnake.d.ts +0 -4
- package/lib/internal/private/__notationUnsnake.js +0 -26
- package/lib/internal/private/__notationUnsnake.js.map +0 -1
- package/lib/internal/private/__notationUnsnake.mjs +0 -15
- package/lib/internal/private/__notationUnsnake.mjs.map +0 -1
- package/native/adapter/visit.go +0 -173
- package/native/adapter/visit_property_chain_edges_test.go +0 -129
- package/native/cmd/ttsc-typia/plugin_options_missing_config_test.go +0 -26
- package/native/cmd/ttsc-typia/plugin_options_undefined_false_test.go +0 -36
- package/native/core/programmers/helpers/disable_function_programmer_declare.go +0 -10
- package/native/core/programmers/iterate/check_union_array_like.go +0 -422
- package/native/core/programmers/iterate/prune_object_properties.go +0 -105
- package/native/core/programmers/iterate/stringify_dynamic_properties.go +0 -219
- package/native/core/programmers/iterate/stringify_native.go +0 -14
- package/native/core/programmers/iterate/stringify_regular_properties.go +0 -112
- package/native/core/schemas/metadata/MetadataApplication.go +0 -41
- package/src/internal/private/__notationCapitalize.ts +0 -2
- package/src/internal/private/__notationUnsnake.ts +0 -24
|
@@ -3,12 +3,27 @@ package main
|
|
|
3
3
|
import (
|
|
4
4
|
"bytes"
|
|
5
5
|
"os"
|
|
6
|
+
"os/exec"
|
|
6
7
|
"path/filepath"
|
|
7
8
|
"runtime"
|
|
9
|
+
"sort"
|
|
8
10
|
"strings"
|
|
9
11
|
"testing"
|
|
10
12
|
)
|
|
11
13
|
|
|
14
|
+
func ttscTypiaTestTypecheck(t *testing.T, project string) {
|
|
15
|
+
t.Helper()
|
|
16
|
+
pnpm, err := exec.LookPath("pnpm")
|
|
17
|
+
if err != nil {
|
|
18
|
+
t.Skip("pnpm executable not found")
|
|
19
|
+
}
|
|
20
|
+
cmd := exec.Command(pnpm, "exec", "ttsc", "--noEmit", "-p", "tsconfig.json")
|
|
21
|
+
cmd.Dir = project
|
|
22
|
+
if output, err := cmd.CombinedOutput(); err != nil {
|
|
23
|
+
t.Fatalf("fixture typecheck failed: %v\n%s", err, output)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
12
27
|
func ttscTypiaTestRepoRoot(t *testing.T) string {
|
|
13
28
|
t.Helper()
|
|
14
29
|
_, file, _, ok := runtime.Caller(0)
|
|
@@ -50,7 +65,15 @@ func ttscTypiaTestWriteCommonRuntimeStubs(t *testing.T, runtimeDir string) {
|
|
|
50
65
|
"validate-report-stub.cjs": ttscTypiaTestValidateReportStub,
|
|
51
66
|
"standard-schema-stub.cjs": ttscTypiaTestStandardSchemaStub,
|
|
52
67
|
"assert-guard-stub.cjs": ttscTypiaTestAssertGuardStub,
|
|
68
|
+
"functional-error-stub.cjs": ttscTypiaTestFunctionalErrorStub,
|
|
53
69
|
"access-expression-stub.cjs": ttscTypiaTestAccessExpressionStub,
|
|
70
|
+
"string-length-stub.cjs": ttscTypiaTestStringLengthStub,
|
|
71
|
+
"notation-stub.cjs": ttscTypiaTestNotationStub,
|
|
72
|
+
"json-stringify-array-stub.cjs": ttscTypiaTestJsonStringifyArrayStub,
|
|
73
|
+
"json-stringify-property-stub.cjs": ttscTypiaTestJsonStringifyPropertyStub,
|
|
74
|
+
"json-stringify-element-stub.cjs": ttscTypiaTestJsonStringifyElementStub,
|
|
75
|
+
"json-stringify-tail-stub.cjs": ttscTypiaTestJsonStringifyTailStub,
|
|
76
|
+
"random-string-stub.cjs": ttscTypiaTestRandomStringStub,
|
|
54
77
|
}
|
|
55
78
|
for name, content := range files {
|
|
56
79
|
if err := os.WriteFile(filepath.Join(runtimeDir, name), []byte(content), 0o644); err != nil {
|
|
@@ -65,20 +88,58 @@ func ttscTypiaTestRewriteCommonJS(t *testing.T, js string) string {
|
|
|
65
88
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_validateReport")`, `require("./validate-report-stub.cjs")`)
|
|
66
89
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_createStandardSchema")`, `require("./standard-schema-stub.cjs")`)
|
|
67
90
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_assertGuard")`, `require("./assert-guard-stub.cjs")`)
|
|
91
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_functionalTypeGuardErrorFactory")`, `require("./functional-error-stub.cjs")`)
|
|
68
92
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_accessExpressionAsString")`, `require("./access-expression-stub.cjs")`)
|
|
93
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_stringLength")`, `require("./string-length-stub.cjs")`)
|
|
94
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyArray")`, `require("./json-stringify-array-stub.cjs")`)
|
|
95
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyProperty")`, `require("./json-stringify-property-stub.cjs")`)
|
|
96
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyElement")`, `require("./json-stringify-element-stub.cjs")`)
|
|
97
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyTail")`, `require("./json-stringify-tail-stub.cjs")`)
|
|
98
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_randomString")`, `require("./random-string-stub.cjs")`)
|
|
99
|
+
for _, helper := range []string{"_notationAssign", "_notationCamel", "_notationKebab", "_notationKeyCollision", "_notationPascal", "_notationSnake"} {
|
|
100
|
+
runtimeJS = strings.ReplaceAll(
|
|
101
|
+
runtimeJS,
|
|
102
|
+
`require("typia/lib/internal/`+helper+`")`,
|
|
103
|
+
`require("./notation-stub.cjs")`,
|
|
104
|
+
)
|
|
105
|
+
}
|
|
69
106
|
for _, needle := range []string{`require("typia")`, `require('typia')`, `from "typia"`, `from 'typia'`, `typia/lib/internal/`} {
|
|
70
|
-
if strings.Contains(runtimeJS, needle) {
|
|
71
|
-
|
|
107
|
+
if !strings.Contains(runtimeJS, needle) {
|
|
108
|
+
continue
|
|
72
109
|
}
|
|
110
|
+
// Name the modules that are actually unmapped. Reporting only the needle
|
|
111
|
+
// makes every new internal helper look like the same failure and sends the
|
|
112
|
+
// reader hunting through the emit for it.
|
|
113
|
+
if needle == `typia/lib/internal/` {
|
|
114
|
+
unresolved := map[string]bool{}
|
|
115
|
+
for _, part := range strings.Split(runtimeJS, needle)[1:] {
|
|
116
|
+
end := strings.IndexAny(part, "\"')")
|
|
117
|
+
if end < 0 {
|
|
118
|
+
end = len(part)
|
|
119
|
+
}
|
|
120
|
+
unresolved[part[:end]] = true
|
|
121
|
+
}
|
|
122
|
+
names := make([]string, 0, len(unresolved))
|
|
123
|
+
for name := range unresolved {
|
|
124
|
+
names = append(names, name)
|
|
125
|
+
}
|
|
126
|
+
sort.Strings(names)
|
|
127
|
+
t.Fatalf("runtime module has no stub for typia internal helpers: %s", strings.Join(names, ", "))
|
|
128
|
+
}
|
|
129
|
+
t.Fatalf("runtime module still contains unresolved typia import %q", needle)
|
|
73
130
|
}
|
|
74
131
|
return runtimeJS
|
|
75
132
|
}
|
|
76
133
|
|
|
77
134
|
const ttscTypiaTestValidateReportStub = `module.exports._validateReport = (array) => {
|
|
135
|
+
const isAncestor = (ancestor, descendant) =>
|
|
136
|
+
descendant === ancestor ||
|
|
137
|
+
descendant.startsWith(ancestor + ".") ||
|
|
138
|
+
descendant.startsWith(ancestor + "[");
|
|
78
139
|
const reportable = (path) => {
|
|
79
140
|
if (array.length === 0) return true;
|
|
80
141
|
const last = array[array.length - 1].path;
|
|
81
|
-
return path
|
|
142
|
+
return !isAncestor(path, last) && !isAncestor(last, path);
|
|
82
143
|
};
|
|
83
144
|
return (exceptable, error) => {
|
|
84
145
|
if (exceptable && reportable(error.path)) {
|
|
@@ -108,6 +169,61 @@ const ttscTypiaTestAssertGuardStub = `module.exports._assertGuard = (exceptionab
|
|
|
108
169
|
};
|
|
109
170
|
`
|
|
110
171
|
|
|
172
|
+
const ttscTypiaTestFunctionalErrorStub = `module.exports._functionalTypeGuardErrorFactory = (props) =>
|
|
173
|
+
Object.assign(new Error(props.expected), props);
|
|
174
|
+
`
|
|
175
|
+
|
|
176
|
+
// The two JSON stringify stubs mirror packages/typia/src/internal exactly. They
|
|
177
|
+
// are runtime doubles for the emit these tests execute; the shipped helpers
|
|
178
|
+
// themselves are exercised by the TypeScript suites against the real package.
|
|
179
|
+
const ttscTypiaTestJsonStringifyArrayStub = `module.exports._jsonStringifyArray = (elements, mapper) => {
|
|
180
|
+
const length = Math.min(
|
|
181
|
+
Math.max(Math.trunc(elements.length) || 0, 0),
|
|
182
|
+
Number.MAX_SAFE_INTEGER,
|
|
183
|
+
);
|
|
184
|
+
let output = "";
|
|
185
|
+
for (let i = 0; i < length; ++i) {
|
|
186
|
+
const elem = elements[i];
|
|
187
|
+
const text = elem === undefined ? undefined : mapper(elem, i);
|
|
188
|
+
output += (i === 0 ? "" : ",") + (text === undefined ? "null" : text);
|
|
189
|
+
}
|
|
190
|
+
return output;
|
|
191
|
+
};
|
|
192
|
+
`
|
|
193
|
+
|
|
194
|
+
const ttscTypiaTestJsonStringifyPropertyStub = `module.exports._jsonStringifyProperty = (head, text, tail) =>
|
|
195
|
+
text === undefined ? "" : head + text + tail;
|
|
196
|
+
`
|
|
197
|
+
|
|
198
|
+
const ttscTypiaTestJsonStringifyElementStub = `module.exports._jsonStringifyElement = (text) =>
|
|
199
|
+
text === undefined ? "null" : text;
|
|
200
|
+
`
|
|
201
|
+
|
|
202
|
+
// Deterministic rather than random: these runtimes assert observable behavior
|
|
203
|
+
// of the emitted validators, so a generated string only has to satisfy the
|
|
204
|
+
// declared bounds, and a stable one keeps a failure reproducible.
|
|
205
|
+
const ttscTypiaTestJsonStringifyTailStub = `module.exports._jsonStringifyTail = (str) =>
|
|
206
|
+
str[str.length - 1] === "," ? str.substring(0, str.length - 1) : str;
|
|
207
|
+
`
|
|
208
|
+
|
|
209
|
+
const ttscTypiaTestRandomStringStub = `module.exports._randomString = (props) => {
|
|
210
|
+
const minimum =
|
|
211
|
+
props.minLength !== undefined
|
|
212
|
+
? props.minLength
|
|
213
|
+
: Math.min(props.maxLength !== undefined ? props.maxLength : 5, 5);
|
|
214
|
+
const maximum = props.maxLength !== undefined ? props.maxLength : minimum + 5;
|
|
215
|
+
const length = Math.max(minimum, Math.min(minimum, maximum));
|
|
216
|
+
return "a".repeat(length);
|
|
217
|
+
};
|
|
218
|
+
`
|
|
219
|
+
|
|
220
|
+
const ttscTypiaTestStringLengthStub = `module.exports._stringLength = (value) => {
|
|
221
|
+
let count = 0;
|
|
222
|
+
for (const _ of value) ++count;
|
|
223
|
+
return count;
|
|
224
|
+
};
|
|
225
|
+
`
|
|
226
|
+
|
|
111
227
|
const ttscTypiaTestAccessExpressionStub = `const reserved = new Set([
|
|
112
228
|
"break",
|
|
113
229
|
"case",
|
|
@@ -153,3 +269,120 @@ module.exports._accessExpressionAsString = (key) => {
|
|
|
153
269
|
: "[" + JSON.stringify(key) + "]";
|
|
154
270
|
};
|
|
155
271
|
`
|
|
272
|
+
|
|
273
|
+
// ttscTypiaTestNotationStub stands in for typia/lib/internal/_notation*, which
|
|
274
|
+
// the emitted converter requires for dynamic (index-signature) keys.
|
|
275
|
+
//
|
|
276
|
+
// These tests assert that the statically emitted key and the runtime helper
|
|
277
|
+
// agree, so this stub is that assertion's oracle and has to stay a faithful
|
|
278
|
+
// transcription of packages/typia/src/internal/_notation{Camel,Pascal,Snake,
|
|
279
|
+
// Kebab}.ts and private/__notationRename.ts — an approximation turns "emit ==
|
|
280
|
+
// runtime" into "emit == whatever this file happens to say". Keep it a direct
|
|
281
|
+
// transcription: same routing on underscore presence (not on segment count),
|
|
282
|
+
// the same CamelizeSnakeString/PascalizeSnakeString recursions, and the same
|
|
283
|
+
// per-segment case-boundary walk in snake. It deliberately uses string
|
|
284
|
+
// concatenation rather than template literals because it is embedded in a Go
|
|
285
|
+
// raw string literal, which is backtick-delimited.
|
|
286
|
+
const ttscTypiaTestNotationStub = `const __notationRename = (props) => (str) => {
|
|
287
|
+
let prefix = "";
|
|
288
|
+
while (str.startsWith("_")) {
|
|
289
|
+
prefix += "_";
|
|
290
|
+
str = str.substring(1);
|
|
291
|
+
}
|
|
292
|
+
if (str.length === 0) return prefix;
|
|
293
|
+
return prefix + (str.includes("_") ? props.snake(str) : props.plain(str));
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const _notationCamelSnake = (str) => {
|
|
297
|
+
while (str.startsWith("_")) str = str.substring(1);
|
|
298
|
+
if (str.length === 0) return "";
|
|
299
|
+
const index = str.indexOf("_");
|
|
300
|
+
if (index < 0) return str.toLowerCase();
|
|
301
|
+
const middle = str[index + 1];
|
|
302
|
+
if (middle === undefined) return str.toLowerCase();
|
|
303
|
+
return middle === "_"
|
|
304
|
+
? _notationCamelSnake(str.substring(0, index) + "_" + str.substring(index + 2))
|
|
305
|
+
: str.substring(0, index).toLowerCase() +
|
|
306
|
+
middle.toUpperCase() +
|
|
307
|
+
_notationCamelSnake(str.substring(index + 2));
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
const _notationPascalSnake = (str) => {
|
|
311
|
+
while (str.startsWith("_")) str = str.substring(1);
|
|
312
|
+
if (str.length === 0) return "";
|
|
313
|
+
const index = str.indexOf("_");
|
|
314
|
+
return index < 0
|
|
315
|
+
? str[0].toUpperCase() + str.substring(1).toLowerCase()
|
|
316
|
+
: str[0].toUpperCase() +
|
|
317
|
+
str.substring(1, index).toLowerCase() +
|
|
318
|
+
_notationPascalSnake(str.substring(index + 1));
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const _notationSnakeWord = (str) => {
|
|
322
|
+
const indexes = [];
|
|
323
|
+
for (let i = 0; i < str.length; i++) {
|
|
324
|
+
const code = str.charCodeAt(i);
|
|
325
|
+
if (65 <= code && code <= 90) indexes.push(i);
|
|
326
|
+
}
|
|
327
|
+
for (let i = indexes.length - 1; i > 0; --i)
|
|
328
|
+
if (indexes[i] - indexes[i - 1] === 1) indexes.splice(i, 1);
|
|
329
|
+
if (indexes.length !== 0 && indexes[0] === 0) indexes.splice(0, 1);
|
|
330
|
+
if (indexes.length === 0) return str.toLowerCase();
|
|
331
|
+
let ret = "";
|
|
332
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
333
|
+
ret += str.substring(i === 0 ? 0 : indexes[i - 1], indexes[i]).toLowerCase();
|
|
334
|
+
ret += "_";
|
|
335
|
+
}
|
|
336
|
+
ret += str.substring(indexes[indexes.length - 1]).toLowerCase();
|
|
337
|
+
return ret;
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
module.exports._notationCamel = __notationRename({
|
|
341
|
+
plain: (str) =>
|
|
342
|
+
str === str.toUpperCase()
|
|
343
|
+
? str.toLowerCase()
|
|
344
|
+
: str[0].toLowerCase() + str.substring(1),
|
|
345
|
+
snake: _notationCamelSnake,
|
|
346
|
+
});
|
|
347
|
+
module.exports._notationPascal = __notationRename({
|
|
348
|
+
plain: (str) => str[0].toUpperCase() + str.substring(1),
|
|
349
|
+
snake: _notationPascalSnake,
|
|
350
|
+
});
|
|
351
|
+
module.exports._notationSnake = (str) => {
|
|
352
|
+
if (str.length === 0) return str;
|
|
353
|
+
let prefix = "";
|
|
354
|
+
for (let i = 0; i < str.length; i++) {
|
|
355
|
+
if (str[i] === "_") prefix += "_";
|
|
356
|
+
else break;
|
|
357
|
+
}
|
|
358
|
+
if (prefix.length !== 0) str = str.substring(prefix.length);
|
|
359
|
+
return prefix + str.split("_").map(_notationSnakeWord).join("_");
|
|
360
|
+
};
|
|
361
|
+
module.exports._notationKebab = (str) => {
|
|
362
|
+
let snaked = module.exports._notationSnake(str);
|
|
363
|
+
let prefix = "";
|
|
364
|
+
while (snaked.startsWith("_")) {
|
|
365
|
+
prefix += "_";
|
|
366
|
+
snaked = snaked.substring(1);
|
|
367
|
+
}
|
|
368
|
+
return prefix + snaked.replaceAll("_", "-");
|
|
369
|
+
};
|
|
370
|
+
module.exports._notationAssign = (output, sources, source, value, rename) => {
|
|
371
|
+
const destination = rename(source);
|
|
372
|
+
if (Object.hasOwn(output, destination))
|
|
373
|
+
module.exports._notationKeyCollision(sources[destination], source, destination);
|
|
374
|
+
Object.defineProperty(output, destination, {
|
|
375
|
+
configurable: true,
|
|
376
|
+
enumerable: true,
|
|
377
|
+
value,
|
|
378
|
+
writable: true,
|
|
379
|
+
});
|
|
380
|
+
sources[destination] = source;
|
|
381
|
+
};
|
|
382
|
+
module.exports._notationKeyCollision = (first, second, destination) => {
|
|
383
|
+
throw new Error(
|
|
384
|
+
"typia.notations cannot rename both " + JSON.stringify(first) +
|
|
385
|
+
" and " + JSON.stringify(second) + " to " + JSON.stringify(destination) + ".",
|
|
386
|
+
);
|
|
387
|
+
};
|
|
388
|
+
`
|
|
@@ -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
|
+
}
|