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
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestFunctionalPromisedTypeTransform verifies semantic async wrappers.
|
|
12
|
+
//
|
|
13
|
+
// Every functional family shares the return-type classifier. A derived Promise
|
|
14
|
+
// must produce an async wrapper that validates the fulfilled value, while a
|
|
15
|
+
// non-thenable class merely named Promise must remain synchronous.
|
|
16
|
+
//
|
|
17
|
+
// 1. Transform all assert, is/equals, and validate function variants.
|
|
18
|
+
// 2. Exercise derived class/interface and branded Promise results.
|
|
19
|
+
// 3. Pin invalid parameters, invalid fulfilled values, rejection, and the
|
|
20
|
+
// shadowed-name negative control without regressing receiver forwarding.
|
|
21
|
+
func TestFunctionalPromisedTypeTransform(t *testing.T) {
|
|
22
|
+
project := compareEqualCoverProject(t, "functional-promised-type-", functionalPromisedTypeSource)
|
|
23
|
+
ttscTypiaTestTypecheck(t, project)
|
|
24
|
+
js := compareEqualCoverTransform(t, project)
|
|
25
|
+
if !strings.Contains(js, "async function") || !strings.Contains(js, "await Reflect.apply") {
|
|
26
|
+
t.Fatalf("promised wrappers do not emit async/await:\n%s", js)
|
|
27
|
+
}
|
|
28
|
+
if !strings.Contains(js, "Reflect.apply") {
|
|
29
|
+
t.Fatalf("promised wrappers do not preserve receiver forwarding:\n%s", js)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
node, err := exec.LookPath("node")
|
|
33
|
+
if err != nil {
|
|
34
|
+
t.Skip("node executable not found")
|
|
35
|
+
}
|
|
36
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
37
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
38
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
39
|
+
}
|
|
40
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
41
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(ttscTypiaTestRewriteCommonJS(t, js)), 0o644); err != nil {
|
|
42
|
+
t.Fatalf("write runtime module: %v", err)
|
|
43
|
+
}
|
|
44
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
45
|
+
if err := os.WriteFile(runner, []byte(functionalPromisedTypeRuntime), 0o644); err != nil {
|
|
46
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
47
|
+
}
|
|
48
|
+
cmd := exec.Command(node, runner)
|
|
49
|
+
cmd.Dir = runtimeDir
|
|
50
|
+
if output, err := cmd.CombinedOutput(); err != nil {
|
|
51
|
+
t.Fatalf("functional promised-type runtime cases failed: %v\n%s", err, output)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const functionalPromisedTypeSource = `import typia from "typia";
|
|
56
|
+
|
|
57
|
+
export interface Receiver { base: number; }
|
|
58
|
+
export interface Input { value: number; }
|
|
59
|
+
export interface Output { total: number; }
|
|
60
|
+
|
|
61
|
+
export class DerivedPromise<T> extends Promise<T> {}
|
|
62
|
+
export interface InterfacePromise<T> extends Promise<T> {}
|
|
63
|
+
export type BrandedPromise<T> = Promise<T> & { readonly __brand: unique symbol };
|
|
64
|
+
export namespace Shadow {
|
|
65
|
+
export class Promise<T> {
|
|
66
|
+
public constructor(public value: T) {}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function promisedTarget(this: Receiver, input: Input): DerivedPromise<Output> {
|
|
71
|
+
return new DerivedPromise((resolve) => resolve({ total: this.base + input.value }));
|
|
72
|
+
}
|
|
73
|
+
export function interfaceTarget(input: Input): InterfacePromise<Output> {
|
|
74
|
+
return Promise.resolve({ total: input.value }) as InterfacePromise<Output>;
|
|
75
|
+
}
|
|
76
|
+
export function brandedTarget(input: Input): BrandedPromise<Output> {
|
|
77
|
+
return Promise.resolve({ total: input.value }) as BrandedPromise<Output>;
|
|
78
|
+
}
|
|
79
|
+
export function shadowedTarget(input: Input): Shadow.Promise<Output> {
|
|
80
|
+
return new Shadow.Promise({ total: input.value });
|
|
81
|
+
}
|
|
82
|
+
export function rejectingTarget(): DerivedPromise<Output> {
|
|
83
|
+
return new DerivedPromise((_resolve, reject) => reject(new Error("promised rejection")));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const promised = {
|
|
87
|
+
assertFunction: typia.functional.assertFunction(promisedTarget),
|
|
88
|
+
assertParameters: typia.functional.assertParameters(promisedTarget),
|
|
89
|
+
assertReturn: typia.functional.assertReturn(promisedTarget),
|
|
90
|
+
assertEqualsFunction: typia.functional.assertEqualsFunction(promisedTarget),
|
|
91
|
+
assertEqualsParameters: typia.functional.assertEqualsParameters(promisedTarget),
|
|
92
|
+
assertEqualsReturn: typia.functional.assertEqualsReturn(promisedTarget),
|
|
93
|
+
isFunction: typia.functional.isFunction(promisedTarget),
|
|
94
|
+
isParameters: typia.functional.isParameters(promisedTarget),
|
|
95
|
+
isReturn: typia.functional.isReturn(promisedTarget),
|
|
96
|
+
equalsFunction: typia.functional.equalsFunction(promisedTarget),
|
|
97
|
+
equalsParameters: typia.functional.equalsParameters(promisedTarget),
|
|
98
|
+
equalsReturn: typia.functional.equalsReturn(promisedTarget),
|
|
99
|
+
validateFunction: typia.functional.validateFunction(promisedTarget),
|
|
100
|
+
validateParameters: typia.functional.validateParameters(promisedTarget),
|
|
101
|
+
validateReturn: typia.functional.validateReturn(promisedTarget),
|
|
102
|
+
validateEqualsFunction: typia.functional.validateEqualsFunction(promisedTarget),
|
|
103
|
+
validateEqualsParameters: typia.functional.validateEqualsParameters(promisedTarget),
|
|
104
|
+
validateEqualsReturn: typia.functional.validateEqualsReturn(promisedTarget),
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const shadowed = {
|
|
108
|
+
assertFunction: typia.functional.assertFunction(shadowedTarget),
|
|
109
|
+
assertParameters: typia.functional.assertParameters(shadowedTarget),
|
|
110
|
+
assertReturn: typia.functional.assertReturn(shadowedTarget),
|
|
111
|
+
assertEqualsFunction: typia.functional.assertEqualsFunction(shadowedTarget),
|
|
112
|
+
assertEqualsParameters: typia.functional.assertEqualsParameters(shadowedTarget),
|
|
113
|
+
assertEqualsReturn: typia.functional.assertEqualsReturn(shadowedTarget),
|
|
114
|
+
isFunction: typia.functional.isFunction(shadowedTarget),
|
|
115
|
+
isParameters: typia.functional.isParameters(shadowedTarget),
|
|
116
|
+
isReturn: typia.functional.isReturn(shadowedTarget),
|
|
117
|
+
equalsFunction: typia.functional.equalsFunction(shadowedTarget),
|
|
118
|
+
equalsParameters: typia.functional.equalsParameters(shadowedTarget),
|
|
119
|
+
equalsReturn: typia.functional.equalsReturn(shadowedTarget),
|
|
120
|
+
validateFunction: typia.functional.validateFunction(shadowedTarget),
|
|
121
|
+
validateParameters: typia.functional.validateParameters(shadowedTarget),
|
|
122
|
+
validateReturn: typia.functional.validateReturn(shadowedTarget),
|
|
123
|
+
validateEqualsFunction: typia.functional.validateEqualsFunction(shadowedTarget),
|
|
124
|
+
validateEqualsParameters: typia.functional.validateEqualsParameters(shadowedTarget),
|
|
125
|
+
validateEqualsReturn: typia.functional.validateEqualsReturn(shadowedTarget),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const semanticShapes = {
|
|
129
|
+
interfaceAssert: typia.functional.assertReturn<(input: Input) => InterfacePromise<Output>>(interfaceTarget),
|
|
130
|
+
interfaceIs: typia.functional.isReturn(interfaceTarget),
|
|
131
|
+
interfaceValidate: typia.functional.validateReturn(interfaceTarget),
|
|
132
|
+
brandedAssert: typia.functional.assertReturn(brandedTarget),
|
|
133
|
+
brandedIs: typia.functional.isReturn<(input: Input) => BrandedPromise<Output>>(brandedTarget),
|
|
134
|
+
brandedValidate: typia.functional.validateReturn(brandedTarget),
|
|
135
|
+
};
|
|
136
|
+
export const rejecting = typia.functional.assertReturn(rejectingTarget);
|
|
137
|
+
|
|
138
|
+
type Equal<X, Y> =
|
|
139
|
+
(<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
|
|
140
|
+
? true
|
|
141
|
+
: false;
|
|
142
|
+
type Assert<T extends true> = T;
|
|
143
|
+
export type PromisedWrapperCases = [
|
|
144
|
+
Assert<Equal<ReturnType<typeof promised.isFunction>, Promise<Output | null>>>,
|
|
145
|
+
Assert<Equal<ReturnType<typeof promised.validateReturn>, Promise<typia.IValidation<Output>>>>,
|
|
146
|
+
Assert<Equal<ReturnType<typeof shadowed.isFunction>, Shadow.Promise<Output> | null>>,
|
|
147
|
+
Assert<Equal<ReturnType<typeof shadowed.validateReturn>, typia.IValidation<Shadow.Promise<Output>>>>,
|
|
148
|
+
];
|
|
149
|
+
`
|
|
150
|
+
|
|
151
|
+
const functionalPromisedTypeRuntime = `const mod = require("./main.cjs");
|
|
152
|
+
|
|
153
|
+
const expect = (label, actual, expected) => {
|
|
154
|
+
if (actual !== expected) throw new Error(label + ": expected " + expected + ", got " + actual);
|
|
155
|
+
};
|
|
156
|
+
const assertNames = new Set([
|
|
157
|
+
"assertFunction", "assertParameters", "assertReturn",
|
|
158
|
+
"assertEqualsFunction", "assertEqualsParameters", "assertEqualsReturn",
|
|
159
|
+
]);
|
|
160
|
+
const validateNames = new Set([
|
|
161
|
+
"validateFunction", "validateParameters", "validateReturn",
|
|
162
|
+
"validateEqualsFunction", "validateEqualsParameters", "validateEqualsReturn",
|
|
163
|
+
]);
|
|
164
|
+
|
|
165
|
+
(async () => {
|
|
166
|
+
for (const [name, wrapped] of Object.entries(mod.promised)) {
|
|
167
|
+
const pending = wrapped.call({ base: 40 }, { value: 2 });
|
|
168
|
+
expect("promised " + name + " returns Promise", pending instanceof Promise, true);
|
|
169
|
+
const result = await pending;
|
|
170
|
+
if (validateNames.has(name)) {
|
|
171
|
+
expect("promised " + name + " succeeds", result.success, true);
|
|
172
|
+
expect("promised " + name + " fulfilled total", result.data.total, 42);
|
|
173
|
+
} else {
|
|
174
|
+
expect("promised " + name + " is non-null", result === null, false);
|
|
175
|
+
expect("promised " + name + " fulfilled total", result.total, 42);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const invalid = wrapped.call({ base: 40 }, { value: "bad" });
|
|
179
|
+
expect("invalid " + name + " keeps Promise shape", invalid instanceof Promise, true);
|
|
180
|
+
if (assertNames.has(name)) {
|
|
181
|
+
let error;
|
|
182
|
+
try { await invalid; } catch (exp) { error = exp; }
|
|
183
|
+
expect("invalid " + name + " rejects", Boolean(error), true);
|
|
184
|
+
} else {
|
|
185
|
+
const failure = await invalid;
|
|
186
|
+
if (validateNames.has(name)) expect("invalid " + name + " validation fails", failure.success, false);
|
|
187
|
+
else expect("invalid " + name + " returns null", failure, null);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
for (const [name, wrapped] of Object.entries(mod.semanticShapes)) {
|
|
192
|
+
const pending = wrapped({ value: 7 });
|
|
193
|
+
expect(name + " returns Promise", pending instanceof Promise, true);
|
|
194
|
+
const result = await pending;
|
|
195
|
+
if (name.endsWith("Validate")) {
|
|
196
|
+
expect(name + " succeeds", result.success, true);
|
|
197
|
+
expect(name + " total", result.data.total, 7);
|
|
198
|
+
} else expect(name + " total", result.total, 7);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
for (const [name, wrapped] of Object.entries(mod.shadowed)) {
|
|
202
|
+
const result = wrapped({ value: 9 });
|
|
203
|
+
expect("shadowed " + name + " stays synchronous", result instanceof Promise, false);
|
|
204
|
+
if (validateNames.has(name)) {
|
|
205
|
+
expect("shadowed " + name + " succeeds", result.success, true);
|
|
206
|
+
expect("shadowed " + name + " value", result.data.value.total, 9);
|
|
207
|
+
} else {
|
|
208
|
+
expect("shadowed " + name + " is non-null", result === null, false);
|
|
209
|
+
expect("shadowed " + name + " value", result.value.total, 9);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
let rejection;
|
|
214
|
+
try { await mod.rejecting(); } catch (error) { rejection = error; }
|
|
215
|
+
expect("rejection propagates", rejection && rejection.message, "promised rejection");
|
|
216
|
+
})().catch((error) => {
|
|
217
|
+
console.error(error);
|
|
218
|
+
process.exitCode = 1;
|
|
219
|
+
});
|
|
220
|
+
`
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestFunctionalReceiverTransform verifies dynamic receiver preservation.
|
|
12
|
+
//
|
|
13
|
+
// Functional wrappers advertise the target function's receiver contract, so
|
|
14
|
+
// the emitted wrapper must be an ordinary function and must invoke the captured
|
|
15
|
+
// target with the wrapper's call-site `this`. Arrow wrappers and bare calls
|
|
16
|
+
// silently discard that contract.
|
|
17
|
+
//
|
|
18
|
+
// 1. Transform all assert, is/equals, and validate parameter/return variants.
|
|
19
|
+
// 2. Exercise sync, async, bound, and receiver-free targets.
|
|
20
|
+
// 3. Preserve validation failures, thrown errors, and receiver-dependent data.
|
|
21
|
+
func TestFunctionalReceiverTransform(t *testing.T) {
|
|
22
|
+
project := compareEqualCoverProject(t, "functional-receiver-", functionalReceiverSource)
|
|
23
|
+
ttscTypiaTestTypecheck(t, project)
|
|
24
|
+
js := compareEqualCoverTransform(t, project)
|
|
25
|
+
if !strings.Contains(js, "Reflect.apply") {
|
|
26
|
+
t.Fatalf("functional output does not forward the dynamic receiver:\n%s", js)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
node, err := exec.LookPath("node")
|
|
30
|
+
if err != nil {
|
|
31
|
+
t.Skip("node executable not found")
|
|
32
|
+
}
|
|
33
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
34
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
35
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
36
|
+
}
|
|
37
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
38
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(ttscTypiaTestRewriteCommonJS(t, js)), 0o644); err != nil {
|
|
39
|
+
t.Fatalf("write runtime module: %v", err)
|
|
40
|
+
}
|
|
41
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
42
|
+
if err := os.WriteFile(runner, []byte(functionalReceiverRuntime), 0o644); err != nil {
|
|
43
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
44
|
+
}
|
|
45
|
+
cmd := exec.Command(node, runner)
|
|
46
|
+
cmd.Dir = runtimeDir
|
|
47
|
+
if output, err := cmd.CombinedOutput(); err != nil {
|
|
48
|
+
t.Fatalf("functional receiver runtime cases failed: %v\n%s", err, output)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const functionalReceiverSource = `import typia from "typia";
|
|
53
|
+
|
|
54
|
+
export interface Receiver {
|
|
55
|
+
base: number;
|
|
56
|
+
calls: number;
|
|
57
|
+
}
|
|
58
|
+
export interface Input {
|
|
59
|
+
value: number;
|
|
60
|
+
}
|
|
61
|
+
export interface Output {
|
|
62
|
+
total: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function syncTarget(this: Receiver, input: Input): Output {
|
|
66
|
+
this.calls += 1;
|
|
67
|
+
return { total: this.base + input.value };
|
|
68
|
+
}
|
|
69
|
+
export async function asyncTarget(this: Receiver, input: Input): Promise<Output> {
|
|
70
|
+
this.calls += 1;
|
|
71
|
+
return { total: this.base + input.value };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const sync = {
|
|
75
|
+
assertFunction: typia.functional.assertFunction(syncTarget),
|
|
76
|
+
assertParameters: typia.functional.assertParameters(syncTarget),
|
|
77
|
+
assertReturn: typia.functional.assertReturn(syncTarget),
|
|
78
|
+
assertEqualsFunction: typia.functional.assertEqualsFunction(syncTarget),
|
|
79
|
+
assertEqualsParameters: typia.functional.assertEqualsParameters(syncTarget),
|
|
80
|
+
assertEqualsReturn: typia.functional.assertEqualsReturn(syncTarget),
|
|
81
|
+
isFunction: typia.functional.isFunction(syncTarget),
|
|
82
|
+
isParameters: typia.functional.isParameters(syncTarget),
|
|
83
|
+
isReturn: typia.functional.isReturn(syncTarget),
|
|
84
|
+
equalsFunction: typia.functional.equalsFunction(syncTarget),
|
|
85
|
+
equalsParameters: typia.functional.equalsParameters(syncTarget),
|
|
86
|
+
equalsReturn: typia.functional.equalsReturn(syncTarget),
|
|
87
|
+
validateFunction: typia.functional.validateFunction(syncTarget),
|
|
88
|
+
validateParameters: typia.functional.validateParameters(syncTarget),
|
|
89
|
+
validateReturn: typia.functional.validateReturn(syncTarget),
|
|
90
|
+
validateEqualsFunction: typia.functional.validateEqualsFunction(syncTarget),
|
|
91
|
+
validateEqualsParameters: typia.functional.validateEqualsParameters(syncTarget),
|
|
92
|
+
validateEqualsReturn: typia.functional.validateEqualsReturn(syncTarget),
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const asynchronous = {
|
|
96
|
+
assertFunction: typia.functional.assertFunction(asyncTarget),
|
|
97
|
+
assertParameters: typia.functional.assertParameters(asyncTarget),
|
|
98
|
+
assertReturn: typia.functional.assertReturn(asyncTarget),
|
|
99
|
+
assertEqualsFunction: typia.functional.assertEqualsFunction(asyncTarget),
|
|
100
|
+
assertEqualsParameters: typia.functional.assertEqualsParameters(asyncTarget),
|
|
101
|
+
assertEqualsReturn: typia.functional.assertEqualsReturn(asyncTarget),
|
|
102
|
+
isFunction: typia.functional.isFunction(asyncTarget),
|
|
103
|
+
isParameters: typia.functional.isParameters(asyncTarget),
|
|
104
|
+
isReturn: typia.functional.isReturn(asyncTarget),
|
|
105
|
+
equalsFunction: typia.functional.equalsFunction(asyncTarget),
|
|
106
|
+
equalsParameters: typia.functional.equalsParameters(asyncTarget),
|
|
107
|
+
equalsReturn: typia.functional.equalsReturn(asyncTarget),
|
|
108
|
+
validateFunction: typia.functional.validateFunction(asyncTarget),
|
|
109
|
+
validateParameters: typia.functional.validateParameters(asyncTarget),
|
|
110
|
+
validateReturn: typia.functional.validateReturn(asyncTarget),
|
|
111
|
+
validateEqualsFunction: typia.functional.validateEqualsFunction(asyncTarget),
|
|
112
|
+
validateEqualsParameters: typia.functional.validateEqualsParameters(asyncTarget),
|
|
113
|
+
validateEqualsReturn: typia.functional.validateEqualsReturn(asyncTarget),
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const boundReceiver: Receiver = { base: 20, calls: 0 };
|
|
117
|
+
export const boundAssert = typia.functional.assertFunction(syncTarget).bind(boundReceiver);
|
|
118
|
+
export const customAssert = typia.functional.assertParameters(
|
|
119
|
+
syncTarget,
|
|
120
|
+
(props) => Object.assign(new Error("custom receiver"), props),
|
|
121
|
+
);
|
|
122
|
+
export const receiverFree = typia.functional.isFunction((input: Input): Output => ({ total: input.value }));
|
|
123
|
+
export const receiverFreeResult = receiverFree({ value: 2 });
|
|
124
|
+
export const throwing = typia.functional.assertParameters(function (this: Receiver, input: Input): Output {
|
|
125
|
+
throw new Error(String(this.base + input.value));
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
type Equal<X, Y> =
|
|
129
|
+
(<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
|
|
130
|
+
? true
|
|
131
|
+
: false;
|
|
132
|
+
type Assert<T extends true> = T;
|
|
133
|
+
export type ReceiverCases = [
|
|
134
|
+
Assert<Equal<ThisParameterType<typeof sync.assertFunction>, Receiver>>,
|
|
135
|
+
Assert<Equal<ThisParameterType<typeof sync.isFunction>, Receiver>>,
|
|
136
|
+
Assert<Equal<ThisParameterType<typeof sync.equalsParameters>, Receiver>>,
|
|
137
|
+
Assert<Equal<ThisParameterType<typeof sync.validateReturn>, Receiver>>,
|
|
138
|
+
Assert<Equal<ThisParameterType<typeof sync.validateEqualsFunction>, Receiver>>,
|
|
139
|
+
Assert<Equal<ThisParameterType<typeof asynchronous.assertReturn>, Receiver>>,
|
|
140
|
+
Assert<Equal<ThisParameterType<typeof asynchronous.isParameters>, Receiver>>,
|
|
141
|
+
Assert<Equal<ThisParameterType<typeof asynchronous.validateFunction>, Receiver>>,
|
|
142
|
+
];
|
|
143
|
+
`
|
|
144
|
+
|
|
145
|
+
const functionalReceiverRuntime = `const mod = require("./main.cjs");
|
|
146
|
+
|
|
147
|
+
const expect = (label, actual, expected) => {
|
|
148
|
+
if (actual !== expected) throw new Error(label + ": expected " + expected + ", got " + actual);
|
|
149
|
+
};
|
|
150
|
+
const assertNames = new Set([
|
|
151
|
+
"assertFunction", "assertParameters", "assertReturn",
|
|
152
|
+
"assertEqualsFunction", "assertEqualsParameters", "assertEqualsReturn",
|
|
153
|
+
]);
|
|
154
|
+
const validateNames = new Set([
|
|
155
|
+
"validateFunction", "validateParameters", "validateReturn",
|
|
156
|
+
"validateEqualsFunction", "validateEqualsParameters", "validateEqualsReturn",
|
|
157
|
+
]);
|
|
158
|
+
const checkResult = (label, name, result) => {
|
|
159
|
+
if (validateNames.has(name)) {
|
|
160
|
+
expect(label + " success", result.success, true);
|
|
161
|
+
expect(label + " total", result.data.total, 42);
|
|
162
|
+
} else {
|
|
163
|
+
expect(label + " non-null", result === null, false);
|
|
164
|
+
expect(label + " total", result.total, 42);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
(async () => {
|
|
169
|
+
for (const [name, wrapped] of Object.entries(mod.sync)) {
|
|
170
|
+
const receiver = { base: 40, calls: 0 };
|
|
171
|
+
const result = wrapped.call(receiver, { value: 2 });
|
|
172
|
+
checkResult("sync " + name, name, result);
|
|
173
|
+
expect("sync " + name + " receiver calls", receiver.calls, 1);
|
|
174
|
+
}
|
|
175
|
+
for (const [name, wrapped] of Object.entries(mod.asynchronous)) {
|
|
176
|
+
const receiver = { base: 40, calls: 0 };
|
|
177
|
+
const result = await wrapped.call(receiver, { value: 2 });
|
|
178
|
+
checkResult("async " + name, name, result);
|
|
179
|
+
expect("async " + name + " receiver calls", receiver.calls, 1);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const ignored = { base: 100, calls: 0 };
|
|
183
|
+
const bound = mod.boundAssert.call(ignored, { value: 2 });
|
|
184
|
+
expect("bound wrapper keeps bound receiver", bound.total, 22);
|
|
185
|
+
expect("bound wrapper ignores call receiver", ignored.calls, 0);
|
|
186
|
+
expect("receiver-free arrow remains directly callable", mod.receiverFreeResult.total, 2);
|
|
187
|
+
|
|
188
|
+
const receiver = { base: 40, calls: 0 };
|
|
189
|
+
let thrown;
|
|
190
|
+
try {
|
|
191
|
+
mod.throwing.call(receiver, { value: 2 });
|
|
192
|
+
} catch (error) {
|
|
193
|
+
thrown = error;
|
|
194
|
+
}
|
|
195
|
+
expect("thrown target error", thrown && thrown.message, "42");
|
|
196
|
+
|
|
197
|
+
for (const name of ["assertFunction", "isFunction", "validateFunction"]) {
|
|
198
|
+
const receiver = { base: 40, calls: 0 };
|
|
199
|
+
let result;
|
|
200
|
+
let error;
|
|
201
|
+
try {
|
|
202
|
+
result = mod.sync[name].call(receiver, { value: "bad" });
|
|
203
|
+
} catch (exp) {
|
|
204
|
+
error = exp;
|
|
205
|
+
}
|
|
206
|
+
if (assertNames.has(name)) {
|
|
207
|
+
expect("assert invalid throws", Boolean(error), true);
|
|
208
|
+
expect("assert invalid path", error.path, "$input.parameters[0].value");
|
|
209
|
+
} else if (validateNames.has(name)) {
|
|
210
|
+
expect("validate invalid fails", result.success, false);
|
|
211
|
+
expect("validate invalid path", result.errors[0].path, "$input.parameters[0].value");
|
|
212
|
+
} else {
|
|
213
|
+
expect("is invalid returns null", result, null);
|
|
214
|
+
}
|
|
215
|
+
expect(name + " invalid does not invoke target", receiver.calls, 0);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const customReceiver = { base: 40, calls: 0 };
|
|
219
|
+
let customError;
|
|
220
|
+
try {
|
|
221
|
+
mod.customAssert.call(customReceiver, { value: "bad" });
|
|
222
|
+
} catch (error) {
|
|
223
|
+
customError = error;
|
|
224
|
+
}
|
|
225
|
+
expect("custom error factory message", customError && customError.message, "custom receiver");
|
|
226
|
+
expect("custom error factory path", customError && customError.path, "$input.parameters[0].value");
|
|
227
|
+
expect("custom error does not invoke target", customReceiver.calls, 0);
|
|
228
|
+
})().catch((error) => {
|
|
229
|
+
console.error(error);
|
|
230
|
+
process.exitCode = 1;
|
|
231
|
+
});
|
|
232
|
+
`
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestIsObjectFunctionMemberTransform pins the runtime behavior of typia.is /
|
|
12
|
+
// assert / validate for the global `Object` interface and for `Function`-typed
|
|
13
|
+
// members (#2178).
|
|
14
|
+
//
|
|
15
|
+
// The global TS `Object` interface carries `constructor: Function`. The global
|
|
16
|
+
// `Function` interface is declared as an `InterfaceDeclaration`, so before the
|
|
17
|
+
// fix typia failed to recognize it as a function type and expanded it
|
|
18
|
+
// structurally to `{ prototype, length, arguments, caller, name }`. That made
|
|
19
|
+
// the `constructor` member emit `"object" === typeof input.constructor`, which
|
|
20
|
+
// is never satisfied by a real constructor (`typeof === "function"`), so
|
|
21
|
+
// `is<Object>(x)` was false for every input. The same defect struck any explicit
|
|
22
|
+
// `Function`-typed member and any interface that `extends Object`.
|
|
23
|
+
//
|
|
24
|
+
// After the fix the lib `Function` interface is classified as a function and
|
|
25
|
+
// routes through the same lenient member path typia already uses for
|
|
26
|
+
// `() => void` members, so `is<Object>` collapses to a non-null-object gate.
|
|
27
|
+
// The lowercase `object` keyword and the `{}` type must stay byte-identical
|
|
28
|
+
// (they keep their `Array.isArray` guard), and the null / undefined / primitive
|
|
29
|
+
// boundaries must stay false.
|
|
30
|
+
//
|
|
31
|
+
// 1. Transform one fixture that exports is / assert / validate for `Object`, an
|
|
32
|
+
// explicit `{ fn: Function }`, a `Moment extends Object` interface, plus the
|
|
33
|
+
// lowercase `object` and `{}` regression guards.
|
|
34
|
+
// 2. Execute the emitted validators in Node against the boundary matrix.
|
|
35
|
+
// 3. Require the runner to report the exact executed case count so a runner that
|
|
36
|
+
// silently skipped cases cannot pass as a false green.
|
|
37
|
+
func TestIsObjectFunctionMemberTransform(t *testing.T) {
|
|
38
|
+
project := isObjectFunctionMemberProject(t)
|
|
39
|
+
js := isObjectFunctionMemberTransform(t, project)
|
|
40
|
+
isObjectFunctionMemberRunRuntimeCases(t, project, js)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
func isObjectFunctionMemberProject(t *testing.T) string {
|
|
44
|
+
t.Helper()
|
|
45
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
46
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
47
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
48
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
49
|
+
}
|
|
50
|
+
dir, err := os.MkdirTemp(base, "is-object-function-member-")
|
|
51
|
+
if err != nil {
|
|
52
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
53
|
+
}
|
|
54
|
+
t.Cleanup(func() {
|
|
55
|
+
_ = os.RemoveAll(dir)
|
|
56
|
+
})
|
|
57
|
+
src := filepath.Join(dir, "src")
|
|
58
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
59
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
60
|
+
}
|
|
61
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(finiteOptionNumberLeafTSConfig), 0o644); err != nil {
|
|
62
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
63
|
+
}
|
|
64
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(isObjectFunctionMemberSource), 0o644); err != nil {
|
|
65
|
+
t.Fatalf("write source: %v", err)
|
|
66
|
+
}
|
|
67
|
+
return dir
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func isObjectFunctionMemberTransform(t *testing.T, project string) string {
|
|
71
|
+
t.Helper()
|
|
72
|
+
payload := `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`
|
|
73
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
74
|
+
return runTransform([]string{
|
|
75
|
+
"--cwd", project,
|
|
76
|
+
"--tsconfig", "tsconfig.json",
|
|
77
|
+
"--file", "src/main.ts",
|
|
78
|
+
"--output", "js",
|
|
79
|
+
"--plugins-json", payload,
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
if code != 0 {
|
|
83
|
+
t.Fatalf("is<Object> transform failed: code=%d stderr=\n%s", code, errText)
|
|
84
|
+
}
|
|
85
|
+
return out
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
func isObjectFunctionMemberRunRuntimeCases(t *testing.T, project string, js string) {
|
|
89
|
+
t.Helper()
|
|
90
|
+
node, err := exec.LookPath("node")
|
|
91
|
+
if err != nil {
|
|
92
|
+
t.Skip("node executable not found")
|
|
93
|
+
}
|
|
94
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
95
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
96
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
97
|
+
}
|
|
98
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
99
|
+
runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
|
|
100
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
101
|
+
t.Fatalf("write runtime module: %v", err)
|
|
102
|
+
}
|
|
103
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
104
|
+
if err := os.WriteFile(runner, []byte(isObjectFunctionMemberRuntimeRunner), 0o644); err != nil {
|
|
105
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
106
|
+
}
|
|
107
|
+
cmd := exec.Command(node, runner)
|
|
108
|
+
cmd.Dir = project
|
|
109
|
+
output, err := cmd.CombinedOutput()
|
|
110
|
+
if err != nil {
|
|
111
|
+
t.Fatalf("is<Object> runtime cases failed: %v\n%s", err, output)
|
|
112
|
+
}
|
|
113
|
+
const expected = "RAN 27 CASES"
|
|
114
|
+
if !strings.Contains(string(output), expected) {
|
|
115
|
+
t.Fatalf("is<Object> runner did not report %q; got:\n%s", expected, output)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const isObjectFunctionMemberSource = `import typia from "typia";
|
|
120
|
+
|
|
121
|
+
interface Moment extends Object {
|
|
122
|
+
valueOf(): number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export const isObject = typia.createIs<Object>();
|
|
126
|
+
export const assertObject = typia.createAssert<Object>();
|
|
127
|
+
export const validateObject = typia.createValidate<Object>();
|
|
128
|
+
|
|
129
|
+
export const isFuncMember = typia.createIs<{ fn: Function }>();
|
|
130
|
+
export const isMoment = typia.createIs<Moment>();
|
|
131
|
+
|
|
132
|
+
export const isLowerObject = typia.createIs<object>();
|
|
133
|
+
export const isEmptyObject = typia.createIs<{}>();
|
|
134
|
+
|
|
135
|
+
// random must produce a sample that its own is accepts (round trip). Object and
|
|
136
|
+
// a Function-only member need no numeric generator stub, so they stay hermetic.
|
|
137
|
+
export const randomObject = typia.createRandom<Object>();
|
|
138
|
+
export const randomFuncOnly = typia.createRandom<{ fn: Function }>();
|
|
139
|
+
|
|
140
|
+
export const captureThrow = (task: () => void): boolean => {
|
|
141
|
+
try {
|
|
142
|
+
task();
|
|
143
|
+
return false;
|
|
144
|
+
} catch {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
`
|
|
149
|
+
|
|
150
|
+
const isObjectFunctionMemberRuntimeRunner = `const mod = require("./main.cjs");
|
|
151
|
+
|
|
152
|
+
let ran = 0;
|
|
153
|
+
const eq = (name, actual, expected) => {
|
|
154
|
+
ran += 1;
|
|
155
|
+
if (actual !== expected) {
|
|
156
|
+
throw new Error(name + ": expected " + expected + " but got " + actual);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// is<Object>: every non-null object is accepted, including arrays and class
|
|
161
|
+
// instances; null / undefined / primitives stay rejected (#2178 core cases).
|
|
162
|
+
eq("is<Object>({})", mod.isObject({}), true);
|
|
163
|
+
eq("is<Object>({a:1})", mod.isObject({ a: 1 }), true);
|
|
164
|
+
eq("is<Object>(new Object())", mod.isObject(new Object()), true);
|
|
165
|
+
eq("is<Object>(new Date())", mod.isObject(new Date()), true);
|
|
166
|
+
eq("is<Object>([])", mod.isObject([]), true);
|
|
167
|
+
eq("is<Object>(null)", mod.isObject(null), false);
|
|
168
|
+
eq("is<Object>(undefined)", mod.isObject(undefined), false);
|
|
169
|
+
eq("is<Object>(5)", mod.isObject(5), false);
|
|
170
|
+
eq("is<Object>('x')", mod.isObject("x"), false);
|
|
171
|
+
|
|
172
|
+
// validate and assert share the checker object path, so they must agree with is.
|
|
173
|
+
eq("validate<Object>({})", mod.validateObject({}).success, true);
|
|
174
|
+
eq("validate<Object>({a:1})", mod.validateObject({ a: 1 }).success, true);
|
|
175
|
+
eq("validate<Object>(null)", mod.validateObject(null).success, false);
|
|
176
|
+
eq("assert<Object>({}) no throw", mod.captureThrow(() => mod.assertObject({})), false);
|
|
177
|
+
eq("assert<Object>(null) throws", mod.captureThrow(() => mod.assertObject(null)), true);
|
|
178
|
+
|
|
179
|
+
// Explicit Function-typed member: the same lenient function path as () => void.
|
|
180
|
+
eq("is<{fn:Function}>({fn(){}})", mod.isFuncMember({ fn() {} }), true);
|
|
181
|
+
eq("is<{fn:Function}>({fn:()=>{}})", mod.isFuncMember({ fn: () => {} }), true);
|
|
182
|
+
eq("is<{fn:Function}>(null)", mod.isFuncMember(null), false);
|
|
183
|
+
|
|
184
|
+
// interface Moment extends Object: the inherited constructor member no longer
|
|
185
|
+
// breaks a real instance.
|
|
186
|
+
eq("is<Moment>(real)", mod.isMoment({ valueOf: () => 1 }), true);
|
|
187
|
+
eq("is<Moment>(null)", mod.isMoment(null), false);
|
|
188
|
+
|
|
189
|
+
// lowercase object keeps its Array.isArray guard (byte-identical, unchanged).
|
|
190
|
+
eq("is<object>({})", mod.isLowerObject({}), true);
|
|
191
|
+
eq("is<object>([])", mod.isLowerObject([]), false);
|
|
192
|
+
eq("is<object>(null)", mod.isLowerObject(null), false);
|
|
193
|
+
|
|
194
|
+
// {} empty object type keeps its Array.isArray guard (byte-identical, unchanged).
|
|
195
|
+
eq("is<{}>({})", mod.isEmptyObject({}), true);
|
|
196
|
+
eq("is<{}>([])", mod.isEmptyObject([]), false);
|
|
197
|
+
eq("is<{}>(null)", mod.isEmptyObject(null), false);
|
|
198
|
+
|
|
199
|
+
// random <-> is round trip: the generated Object / Function-member sample must
|
|
200
|
+
// pass its own is checker.
|
|
201
|
+
eq("is<Object>(random<Object>())", mod.isObject(mod.randomObject()), true);
|
|
202
|
+
eq("is<{fn:Function}>(random)", mod.isFuncMember(mod.randomFuncOnly()), true);
|
|
203
|
+
|
|
204
|
+
console.log("RAN " + ran + " CASES");
|
|
205
|
+
`
|