typia 13.1.0 → 13.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/lib/_virtual/_rolldown/runtime.mjs +1 -5
- package/lib/executable/FileSystemIdentity.d.ts +21 -0
- package/lib/executable/FileSystemIdentity.js +183 -0
- package/lib/executable/FileSystemIdentity.js.map +1 -0
- package/lib/executable/FileSystemIdentity.mjs +129 -0
- package/lib/executable/FileSystemIdentity.mjs.map +1 -0
- package/lib/executable/TypiaGenerateWizard.js +264 -104
- package/lib/executable/TypiaGenerateWizard.js.map +1 -1
- package/lib/executable/TypiaGenerateWizard.mjs +233 -93
- package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
- package/lib/functional.d.ts +15 -12
- package/lib/functional.js.map +1 -1
- package/lib/functional.mjs.map +1 -1
- package/lib/internal/_ProtobufReader.d.ts +17 -0
- package/lib/internal/_ProtobufReader.js +117 -45
- package/lib/internal/_ProtobufReader.js.map +1 -1
- package/lib/internal/_ProtobufReader.mjs +108 -39
- package/lib/internal/_ProtobufReader.mjs.map +1 -1
- package/lib/internal/_createStandardSchema.js +18 -1
- package/lib/internal/_createStandardSchema.js.map +1 -1
- package/lib/internal/_createStandardSchema.mjs +12 -1
- package/lib/internal/_createStandardSchema.mjs.map +1 -1
- package/lib/internal/_decimal.d.ts +14 -0
- package/lib/internal/_decimal.js +61 -0
- package/lib/internal/_decimal.js.map +1 -0
- package/lib/internal/_decimal.mjs +49 -0
- package/lib/internal/_decimal.mjs.map +1 -0
- package/lib/internal/_httpQueryParseURLSearchParams.js +23 -2
- package/lib/internal/_httpQueryParseURLSearchParams.js.map +1 -1
- package/lib/internal/_httpQueryParseURLSearchParams.mjs +20 -2
- package/lib/internal/_httpQueryParseURLSearchParams.mjs.map +1 -1
- package/lib/internal/_isFormatByte.js +2 -5
- package/lib/internal/_isFormatByte.js.map +1 -1
- package/lib/internal/_isFormatByte.mjs +2 -5
- package/lib/internal/_isFormatByte.mjs.map +1 -1
- package/lib/internal/_isFormatDate.js +15 -2
- package/lib/internal/_isFormatDate.js.map +1 -1
- package/lib/internal/_isFormatDate.mjs +22 -2
- package/lib/internal/_isFormatDate.mjs.map +1 -1
- package/lib/internal/_isFormatDateTime.js +21 -2
- package/lib/internal/_isFormatDateTime.js.map +1 -1
- package/lib/internal/_isFormatDateTime.mjs +13 -2
- package/lib/internal/_isFormatDateTime.mjs.map +1 -1
- package/lib/internal/_isFormatIri.js +3 -2
- package/lib/internal/_isFormatIri.js.map +1 -1
- package/lib/internal/_isFormatIri.mjs +3 -2
- package/lib/internal/_isFormatIri.mjs.map +1 -1
- package/lib/internal/_isFormatIriReference.js +10 -2
- package/lib/internal/_isFormatIriReference.js.map +1 -1
- package/lib/internal/_isFormatIriReference.mjs +9 -2
- package/lib/internal/_isFormatIriReference.mjs.map +1 -1
- package/lib/internal/_isFormatUriReference.js +1 -1
- package/lib/internal/_isFormatUriReference.js.map +1 -1
- package/lib/internal/_isFormatUriReference.mjs +1 -1
- package/lib/internal/_isFormatUriReference.mjs.map +1 -1
- package/lib/internal/_isMultipleOf.d.ts +1 -0
- package/lib/internal/_isMultipleOf.js +13 -0
- package/lib/internal/_isMultipleOf.js.map +1 -0
- package/lib/internal/_isMultipleOf.mjs +12 -0
- package/lib/internal/_isMultipleOf.mjs.map +1 -0
- package/lib/internal/_isTypeFloat.js +1 -1
- package/lib/internal/_isTypeFloat.js.map +1 -1
- package/lib/internal/_isTypeFloat.mjs +1 -1
- package/lib/internal/_isTypeFloat.mjs.map +1 -1
- package/lib/internal/_isTypeInt64.js +1 -0
- package/lib/internal/_isTypeInt64.js.map +1 -1
- package/lib/internal/_isTypeInt64.mjs.map +1 -1
- package/lib/internal/_isTypeInt64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeInt64Bigint.js +15 -0
- package/lib/internal/_isTypeInt64Bigint.js.map +1 -0
- package/lib/internal/_isTypeInt64Bigint.mjs +8 -0
- package/lib/internal/_isTypeInt64Bigint.mjs.map +1 -0
- package/lib/internal/_isTypeUint64.js +1 -0
- package/lib/internal/_isTypeUint64.js.map +1 -1
- package/lib/internal/_isTypeUint64.mjs.map +1 -1
- package/lib/internal/_isTypeUint64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeUint64Bigint.js +10 -0
- package/lib/internal/_isTypeUint64Bigint.js.map +1 -0
- package/lib/internal/_isTypeUint64Bigint.mjs +8 -0
- package/lib/internal/_isTypeUint64Bigint.mjs.map +1 -0
- package/lib/internal/_isUniqueItems.js +96 -109
- package/lib/internal/_isUniqueItems.js.map +1 -1
- package/lib/internal/_isUniqueItems.mjs +62 -50
- package/lib/internal/_isUniqueItems.mjs.map +1 -1
- package/lib/internal/_notationAny.js +8 -1
- package/lib/internal/_notationAny.js.map +1 -1
- package/lib/internal/_notationAny.mjs +7 -1
- package/lib/internal/_notationAny.mjs.map +1 -1
- package/lib/internal/_notationAssign.d.ts +1 -0
- package/lib/internal/_notationAssign.js +18 -0
- package/lib/internal/_notationAssign.js.map +1 -0
- package/lib/internal/_notationAssign.mjs +17 -0
- package/lib/internal/_notationAssign.mjs.map +1 -0
- package/lib/internal/_notationCamel.js +30 -9
- package/lib/internal/_notationCamel.js.map +1 -1
- package/lib/internal/_notationCamel.mjs +13 -5
- package/lib/internal/_notationCamel.mjs.map +1 -1
- package/lib/internal/_notationKebab.d.ts +1 -0
- package/lib/internal/_notationKebab.js +15 -0
- package/lib/internal/_notationKebab.js.map +1 -0
- package/lib/internal/_notationKebab.mjs +15 -0
- package/lib/internal/_notationKebab.mjs.map +1 -0
- package/lib/internal/_notationKeyCollision.d.ts +1 -0
- package/lib/internal/_notationKeyCollision.js +8 -0
- package/lib/internal/_notationKeyCollision.js.map +1 -0
- package/lib/internal/_notationKeyCollision.mjs +8 -0
- package/lib/internal/_notationKeyCollision.mjs.map +1 -0
- package/lib/internal/_notationPascal.js +20 -5
- package/lib/internal/_notationPascal.js.map +1 -1
- package/lib/internal/_notationPascal.mjs +10 -5
- package/lib/internal/_notationPascal.mjs.map +1 -1
- package/lib/internal/_notationSnake.js +25 -22
- package/lib/internal/_notationSnake.js.map +1 -1
- package/lib/internal/_notationSnake.mjs +11 -11
- package/lib/internal/_notationSnake.mjs.map +1 -1
- package/lib/internal/_plainCloneAny.js +174 -38
- package/lib/internal/_plainCloneAny.js.map +1 -1
- package/lib/internal/_plainCloneAny.mjs +126 -22
- package/lib/internal/_plainCloneAny.mjs.map +1 -1
- package/lib/internal/_randomArray.d.ts +1 -1
- package/lib/internal/_randomArray.js +11 -4
- package/lib/internal/_randomArray.js.map +1 -1
- package/lib/internal/_randomArray.mjs +9 -3
- package/lib/internal/_randomArray.mjs.map +1 -1
- package/lib/internal/_randomFormatByte.d.ts +2 -1
- package/lib/internal/_randomFormatByte.js +2 -1
- package/lib/internal/_randomFormatByte.js.map +1 -1
- package/lib/internal/_randomFormatByte.mjs +2 -1
- package/lib/internal/_randomFormatByte.mjs.map +1 -1
- package/lib/internal/_randomFormatDate.d.ts +2 -0
- package/lib/internal/_randomFormatDate.js +3 -2
- package/lib/internal/_randomFormatDate.js.map +1 -1
- package/lib/internal/_randomFormatDate.mjs +3 -2
- package/lib/internal/_randomFormatDate.mjs.map +1 -1
- package/lib/internal/_randomFormatDatetime.d.ts +2 -0
- package/lib/internal/_randomFormatDatetime.js +3 -2
- package/lib/internal/_randomFormatDatetime.js.map +1 -1
- package/lib/internal/_randomFormatDatetime.mjs +3 -2
- package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
- package/lib/internal/_randomFormatDuration.d.ts +2 -1
- package/lib/internal/_randomFormatDuration.js +3 -2
- package/lib/internal/_randomFormatDuration.js.map +1 -1
- package/lib/internal/_randomFormatDuration.mjs +3 -2
- package/lib/internal/_randomFormatDuration.mjs.map +1 -1
- package/lib/internal/_randomFormatEmail.d.ts +2 -1
- package/lib/internal/_randomFormatEmail.js +8 -1
- package/lib/internal/_randomFormatEmail.js.map +1 -1
- package/lib/internal/_randomFormatEmail.mjs +5 -1
- package/lib/internal/_randomFormatEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatHostname.d.ts +8 -1
- package/lib/internal/_randomFormatHostname.js +45 -2
- package/lib/internal/_randomFormatHostname.js.map +1 -1
- package/lib/internal/_randomFormatHostname.mjs +38 -2
- package/lib/internal/_randomFormatHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.d.ts +2 -1
- package/lib/internal/_randomFormatIdnEmail.js +16 -2
- package/lib/internal/_randomFormatIdnEmail.js.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.mjs +11 -2
- package/lib/internal/_randomFormatIdnEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.d.ts +2 -1
- package/lib/internal/_randomFormatIdnHostname.js +26 -1
- package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.mjs +25 -2
- package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv4.d.ts +2 -1
- package/lib/internal/_randomFormatIpv4.js +2 -1
- package/lib/internal/_randomFormatIpv4.js.map +1 -1
- package/lib/internal/_randomFormatIpv4.mjs +2 -1
- package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv6.d.ts +2 -1
- package/lib/internal/_randomFormatIpv6.js +2 -1
- package/lib/internal/_randomFormatIpv6.js.map +1 -1
- package/lib/internal/_randomFormatIpv6.mjs +2 -1
- package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
- package/lib/internal/_randomFormatIri.d.ts +2 -1
- package/lib/internal/_randomFormatIri.js +1 -1
- package/lib/internal/_randomFormatIri.js.map +1 -1
- package/lib/internal/_randomFormatIri.mjs +1 -1
- package/lib/internal/_randomFormatIri.mjs.map +1 -1
- package/lib/internal/_randomFormatIriReference.d.ts +2 -1
- package/lib/internal/_randomFormatIriReference.js +1 -1
- package/lib/internal/_randomFormatIriReference.js.map +1 -1
- package/lib/internal/_randomFormatIriReference.mjs +1 -1
- package/lib/internal/_randomFormatIriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatJsonPointer.js +8 -1
- package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.mjs +5 -1
- package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatPassword.d.ts +2 -1
- package/lib/internal/_randomFormatPassword.js +7 -5
- package/lib/internal/_randomFormatPassword.js.map +1 -1
- package/lib/internal/_randomFormatPassword.mjs +5 -1
- package/lib/internal/_randomFormatPassword.mjs.map +1 -1
- package/lib/internal/_randomFormatRegex.d.ts +2 -1
- package/lib/internal/_randomFormatRegex.js +2 -1
- package/lib/internal/_randomFormatRegex.js.map +1 -1
- package/lib/internal/_randomFormatRegex.mjs +2 -1
- package/lib/internal/_randomFormatRegex.mjs.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.js +3 -2
- package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs +3 -2
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatTime.d.ts +2 -1
- package/lib/internal/_randomFormatTime.js +3 -2
- package/lib/internal/_randomFormatTime.js.map +1 -1
- package/lib/internal/_randomFormatTime.mjs +3 -2
- package/lib/internal/_randomFormatTime.mjs.map +1 -1
- package/lib/internal/_randomFormatUri.d.ts +2 -1
- package/lib/internal/_randomFormatUri.js +1 -1
- package/lib/internal/_randomFormatUri.js.map +1 -1
- package/lib/internal/_randomFormatUri.mjs +1 -1
- package/lib/internal/_randomFormatUri.mjs.map +1 -1
- package/lib/internal/_randomFormatUriReference.d.ts +2 -1
- package/lib/internal/_randomFormatUriReference.js +1 -1
- package/lib/internal/_randomFormatUriReference.js.map +1 -1
- package/lib/internal/_randomFormatUriReference.mjs +1 -1
- package/lib/internal/_randomFormatUriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.d.ts +2 -1
- package/lib/internal/_randomFormatUriTemplate.js +1 -1
- package/lib/internal/_randomFormatUriTemplate.js.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs.map +1 -1
- package/lib/internal/_randomFormatUrl.d.ts +2 -1
- package/lib/internal/_randomFormatUrl.js +21 -1
- package/lib/internal/_randomFormatUrl.js.map +1 -1
- package/lib/internal/_randomFormatUrl.mjs +18 -1
- package/lib/internal/_randomFormatUrl.mjs.map +1 -1
- package/lib/internal/_randomFormatUuid.d.ts +2 -1
- package/lib/internal/_randomFormatUuid.js +3 -2
- package/lib/internal/_randomFormatUuid.js.map +1 -1
- package/lib/internal/_randomFormatUuid.mjs +3 -2
- package/lib/internal/_randomFormatUuid.mjs.map +1 -1
- package/lib/internal/_randomInteger.js +59 -28
- package/lib/internal/_randomInteger.js.map +1 -1
- package/lib/internal/_randomInteger.mjs +56 -16
- package/lib/internal/_randomInteger.mjs.map +1 -1
- package/lib/internal/_randomMultiple.d.ts +8 -0
- package/lib/internal/_randomMultiple.js +168 -0
- package/lib/internal/_randomMultiple.js.map +1 -0
- package/lib/internal/_randomMultiple.mjs +158 -0
- package/lib/internal/_randomMultiple.mjs.map +1 -0
- package/lib/internal/_randomNumber.js +42 -42
- package/lib/internal/_randomNumber.js.map +1 -1
- package/lib/internal/_randomNumber.mjs +41 -27
- package/lib/internal/_randomNumber.mjs.map +1 -1
- package/lib/internal/_randomPattern.d.ts +2 -1
- package/lib/internal/_randomPattern.js +19 -4
- package/lib/internal/_randomPattern.js.map +1 -1
- package/lib/internal/_randomPattern.mjs +10 -4
- package/lib/internal/_randomPattern.mjs.map +1 -1
- package/lib/internal/_randomStringLength.d.ts +33 -0
- package/lib/internal/_randomStringLength.js +48 -0
- package/lib/internal/_randomStringLength.js.map +1 -0
- package/lib/internal/_randomStringLength.mjs +44 -0
- package/lib/internal/_randomStringLength.mjs.map +1 -0
- package/lib/internal/_stringLength.d.ts +1 -0
- package/lib/internal/_stringLength.js +11 -0
- package/lib/internal/_stringLength.js.map +1 -0
- package/lib/internal/_stringLength.mjs +10 -0
- package/lib/internal/_stringLength.mjs.map +1 -0
- package/lib/internal/_validateReport.js +4 -1
- package/lib/internal/_validateReport.js.map +1 -1
- package/lib/internal/_validateReport.mjs +2 -1
- package/lib/internal/_validateReport.mjs.map +1 -1
- package/lib/internal/private/__notationRename.d.ts +14 -0
- package/lib/internal/private/__notationRename.js +25 -0
- package/lib/internal/private/__notationRename.js.map +1 -0
- package/lib/internal/private/__notationRename.mjs +24 -0
- package/lib/internal/private/__notationRename.mjs.map +1 -0
- package/lib/json.d.ts +2 -2
- package/lib/json.mjs.map +1 -1
- package/lib/module.d.ts +2 -2
- package/lib/module.js.map +1 -1
- package/lib/module.mjs.map +1 -1
- package/lib/notations.d.ts +20 -4
- package/lib/notations.js.map +1 -1
- package/lib/notations.mjs.map +1 -1
- package/native/adapter/plugin_options.go +117 -0
- package/native/adapter/plugin_options_payload_matrix_test.go +181 -0
- package/native/cmd/ttsc-typia/any_array_type_tags_transform_test.go +63 -9
- package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +152 -0
- package/native/cmd/ttsc-typia/build.go +81 -64
- package/native/cmd/ttsc-typia/build_no_emit_preserves_analysis_options_test.go +67 -0
- package/native/cmd/ttsc-typia/build_no_emit_transform_diagnostics_test.go +138 -0
- package/native/cmd/ttsc-typia/build_plugin_options_come_from_payload_test.go +48 -0
- package/native/cmd/ttsc-typia/build_transactional_emit_success_test.go +81 -0
- package/native/cmd/ttsc-typia/build_transform_failure_atomicity_test.go +138 -0
- package/native/cmd/ttsc-typia/command_routes_and_diagnostics_coverage_test.go +3 -1
- package/native/cmd/ttsc-typia/compare_less_nan_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/compare_native_object_overmatch_transform_test.go +161 -0
- package/native/cmd/ttsc-typia/compare_nondiscriminable_union_transform_test.go +343 -0
- package/native/cmd/ttsc-typia/compare_union_discrimination_transform_test.go +289 -0
- package/native/cmd/ttsc-typia/escaped_property_key_path_transform_test.go +193 -0
- package/native/cmd/ttsc-typia/finite_option_number_leaf_transform_test.go +240 -0
- package/native/cmd/ttsc-typia/functional_promised_type_transform_test.go +220 -0
- package/native/cmd/ttsc-typia/functional_receiver_transform_test.go +232 -0
- package/native/cmd/ttsc-typia/is_object_function_member_transform_test.go +205 -0
- package/native/cmd/ttsc-typia/json_application_alias_function_validation_transform_test.go +151 -0
- package/native/cmd/ttsc-typia/json_is_stringify_finite_number_transform_test.go +198 -0
- package/native/cmd/ttsc-typia/json_stringify_special_key_transform_test.go +238 -0
- package/native/cmd/ttsc-typia/main_wasm.go +21 -2
- package/native/cmd/ttsc-typia/native_collection_identity_is_transform_test.go +234 -0
- package/native/cmd/ttsc-typia/native_generic_name_guard_is_transform_test.go +194 -0
- package/native/cmd/ttsc-typia/native_name_collision_is_transform_test.go +204 -0
- package/native/cmd/ttsc-typia/non_trailing_rest_tuple_transform_test.go +23 -11
- package/native/cmd/ttsc-typia/notation_dynamic_keys_transform_test.go +286 -0
- package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +1 -1
- package/native/cmd/ttsc-typia/notation_literal_collision_transform_test.go +164 -0
- package/native/cmd/ttsc-typia/notation_pascal_case_transform_test.go +230 -0
- package/native/cmd/ttsc-typia/notation_unicode_key_transform_test.go +309 -0
- package/native/cmd/ttsc-typia/pattern_line_terminator_escape_transform_test.go +224 -0
- package/native/cmd/ttsc-typia/plain_prune_union_object_overmatch_transform_test.go +219 -0
- package/native/cmd/ttsc-typia/plugin_options_payload_helpers_test.go +181 -0
- package/native/cmd/ttsc-typia/private_field_filter_is_transform_test.go +278 -0
- package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +73 -27
- package/native/cmd/ttsc-typia/project_dependencies_barrel_reexport_transform_test.go +120 -0
- package/native/cmd/ttsc-typia/project_dependencies_collapsed_alias_transform_test.go +134 -0
- package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +135 -0
- package/native/cmd/ttsc-typia/project_dependencies_default_barrel_transform_test.go +114 -0
- package/native/cmd/ttsc-typia/project_dependencies_empty_heritage_transform_test.go +100 -0
- package/native/cmd/ttsc-typia/project_dependencies_envelope_transform_test.go +148 -0
- package/native/cmd/ttsc-typia/project_dependencies_index_signature_alias_transform_test.go +139 -0
- package/native/cmd/ttsc-typia/project_dependencies_local_reexport_transform_test.go +122 -0
- package/native/cmd/ttsc-typia/project_dependencies_signature_alias_transform_test.go +125 -0
- package/native/cmd/ttsc-typia/project_dependencies_star_barrel_transform_test.go +112 -0
- package/native/cmd/ttsc-typia/project_reference_graph_envelope_transform_test.go +190 -0
- package/native/cmd/ttsc-typia/protobuf_is_encode_finite_number_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/protobuf_sequence_field_numbers_transform_test.go +52 -22
- package/native/cmd/ttsc-typia/symbol_key_member_filter_transform_test.go +279 -0
- package/native/cmd/ttsc-typia/template_interpolation_type_tags_transform_test.go +86 -23
- package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
- package/native/cmd/ttsc-typia/transform.go +228 -39
- package/native/cmd/ttsc-typia/{transform_declaration_source_produces_no_js_test.go → transform_declaration_source_produces_no_javascript_test.go} +10 -2
- package/native/cmd/ttsc-typia/transform_fixtures_emit_coverage_test.go +21 -4
- package/native/cmd/ttsc-typia/transform_helpers_test.go +159 -1
- package/native/cmd/ttsc-typia/transform_plugin_options_come_from_payload_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_atomicity_test.go +114 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_writes_no_stdout_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go +81 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_empty_emit_reports_no_output_test.go +100 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_locates_output_across_layouts_test.go +160 -0
- package/native/cmd/ttsc-typia/transform_single_file_success_publishes_artifact_test.go +54 -0
- package/native/cmd/ttsc-typia/transform_wasm_host_argv_reports_diagnostics_test.go +39 -0
- package/native/cmd/ttsc-typia/tuple_optional_compare_clone_transform_test.go +227 -0
- package/native/core/factories/FormatCheatSheet.go +40 -7
- package/native/core/factories/IdentifierFactory.go +131 -4
- package/native/core/factories/MetadataCommentTagFactory.go +83 -40
- package/native/core/factories/MetadataTypeTagFactory.go +13 -1
- package/native/core/factories/NumericRangeFactory.go +60 -17
- package/native/core/factories/ProtobufFactory.go +7 -4
- package/native/core/factories/factory_utility_coverage_test.go +8 -2
- package/native/core/factories/format_alias_resolves_to_cheat_sheet_test.go +57 -0
- package/native/core/factories/format_alias_table_targets_the_cheat_sheet_test.go +44 -0
- package/native/core/factories/identifier_factory_postfix_escapes_every_key_test.go +147 -0
- package/native/core/factories/identifier_factory_postfix_survives_every_code_point_test.go +86 -0
- package/native/core/factories/internal/metadata/MetadataHelper.go +134 -7
- package/native/core/factories/internal/metadata/emplace_metadata_object.go +116 -8
- package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
- package/native/core/factories/internal/metadata/iterate_metadata_function.go +4 -11
- package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +8 -6
- package/native/core/factories/internal/metadata/iterate_metadata_map.go +9 -0
- package/native/core/factories/internal/metadata/iterate_metadata_native.go +27 -2
- package/native/core/factories/internal/metadata/iterate_metadata_set.go +9 -0
- package/native/core/factories/internal/metadata/js_doc_link_text_test.go +69 -0
- package/native/core/factories/internal/metadata/type_arguments_precondition_test.go +70 -0
- package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +39 -0
- package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go +84 -0
- package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go +60 -0
- package/native/core/factories/metadata_type_tag_factory_declarations_test.go +86 -0
- package/native/core/factories/metadata_type_tag_factory_keeps_bool_form_exclusivity_test.go +38 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go +65 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_duplicated_array_form_tags_test.go +41 -0
- package/native/core/factories/numeric_range_factory_enforces_64bit_bounds_test.go +69 -0
- package/native/core/factories/protobuf_recovery_ownership_test.go +64 -0
- package/native/core/programmers/IsProgrammer.go +15 -1
- package/native/core/programmers/RandomProgrammer.go +51 -14
- package/native/core/programmers/compare/CompareEqualProgrammer.go +393 -5
- package/native/core/programmers/compare/CompareLessProgrammer.go +4 -2
- package/native/core/programmers/functional/FunctionalAssertFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalAssertReturnProgrammer.go +6 -14
- package/native/core/programmers/functional/FunctionalIsFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +49 -14
- package/native/core/programmers/functional/FunctionalIsReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/internal/FunctionalGeneralProgrammer.go +4 -17
- package/native/core/programmers/helpers/CloneJoiner.go +32 -0
- package/native/core/programmers/helpers/NotationJoiner.go +86 -28
- package/native/core/programmers/helpers/StringifyJoinder.go +32 -1
- package/native/core/programmers/helpers/UnionExplorer.go +203 -61
- package/native/core/programmers/helpers/joiner_branch_coverage_test.go +5 -3
- package/native/core/programmers/helpers/union_explorer_coverage_test.go +1 -1
- package/native/core/programmers/internal/CheckerProgrammer.go +100 -48
- package/native/core/programmers/iterate/check_template.go +344 -32
- package/native/core/programmers/iterate/json_schema_discriminator.go +36 -10
- package/native/core/programmers/iterate/json_schema_discriminator_declaration_syntax_test.go +205 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader.go +641 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_boolean_default_test.go +95 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_test.go +123 -0
- package/native/core/programmers/iterate/template_interpolation_tags_test.go +40 -8
- package/native/core/programmers/iterate/template_runtime_pattern.go +52 -7
- package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
- package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
- package/native/core/programmers/llm/LlmApplicationProgrammer.go +12 -10
- package/native/core/programmers/llm/LlmSchemaProgrammer.go +23 -6
- package/native/core/programmers/llm/llm_reference_codec_test.go +24 -0
- package/native/core/programmers/notations/NotationGeneralProgrammer.go +183 -67
- package/native/core/programmers/notations/notation_general_helpers_test.go +1 -3
- package/native/core/programmers/notations/notation_general_programmer_pascal_multiword_test.go +72 -0
- package/native/core/programmers/notations/notation_general_programmer_underscore_boundary_test.go +68 -0
- package/native/core/programmers/plain/PlainClassifyProgrammer.go +23 -15
- package/native/core/programmers/plain/PlainCloneProgrammer.go +20 -7
- package/native/core/programmers/plain/PlainPruneProgrammer.go +19 -5
- package/native/core/programmers/plain/plain_tuple_seed_recovery_ownership_test.go +25 -0
- package/native/core/programmers/protobuf/ProtobufDecodeProgrammer.go +37 -28
- package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +40 -21
- package/native/core/programmers/protobuf/protobuf_programmer_helper_coverage_test.go +26 -0
- package/native/core/programmers/random_programmer_length_argument_test.go +53 -0
- package/native/core/schemas/metadata/MetadataCollection.go +270 -20
- package/native/core/schemas/metadata/MetadataDependency.go +388 -0
- package/native/core/schemas/metadata/MetadataObjectType.go +17 -4
- package/native/core/schemas/metadata/metadata_collection_generic_argument_dot_test.go +122 -0
- package/native/core/schemas/metadata/metadata_collection_name_allocation_test.go +147 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_cascade_test.go +55 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_test.go +68 -0
- package/native/core/utils/PatternUtil.go +13 -0
- package/native/core/utils/PromiseTypeFactory.go +59 -0
- package/native/core/utils/ProtobufNameEncoder.go +8 -0
- package/native/core/utils/promise_type_factory_semantics_test.go +118 -0
- package/native/go.mod +9 -1
- package/native/transform/CallExpressionTransformer.go +12 -0
- package/native/transform/features/json/JsonApplicationTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemaTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemasTransformer.go +5 -4
- package/package.json +16 -4
- package/src/executable/FileSystemIdentity.ts +189 -0
- package/src/executable/TypiaGenerateWizard.ts +377 -110
- package/src/functional.ts +30 -60
- package/src/internal/_ProtobufReader.ts +129 -43
- package/src/internal/_createStandardSchema.ts +15 -1
- package/src/internal/_decimal.ts +69 -0
- package/src/internal/_httpQueryParseURLSearchParams.ts +24 -2
- package/src/internal/_isFormatByte.ts +2 -5
- package/src/internal/_isFormatDate.ts +15 -2
- package/src/internal/_isFormatDateTime.ts +28 -2
- package/src/internal/_isFormatIri.ts +5 -2
- package/src/internal/_isFormatIriReference.ts +11 -3
- package/src/internal/_isFormatUriReference.ts +1 -1
- package/src/internal/_isMultipleOf.ts +8 -0
- package/src/internal/_isTypeFloat.ts +1 -1
- package/src/internal/_isTypeInt64.ts +1 -0
- package/src/internal/_isTypeInt64Bigint.ts +12 -0
- package/src/internal/_isTypeUint64.ts +1 -0
- package/src/internal/_isTypeUint64Bigint.ts +7 -0
- package/src/internal/_isUniqueItems.ts +134 -132
- package/src/internal/_notationAny.ts +9 -4
- package/src/internal/_notationAssign.ts +20 -0
- package/src/internal/_notationCamel.ts +31 -10
- package/src/internal/_notationKebab.ts +11 -0
- package/src/internal/_notationKeyCollision.ts +9 -0
- package/src/internal/_notationPascal.ts +19 -6
- package/src/internal/_notationSnake.ts +24 -21
- package/src/internal/_plainCloneAny.ts +208 -33
- package/src/internal/_randomArray.ts +13 -4
- package/src/internal/_randomFormatByte.ts +4 -1
- package/src/internal/_randomFormatDate.ts +17 -12
- package/src/internal/_randomFormatDatetime.ts +15 -10
- package/src/internal/_randomFormatDuration.ts +16 -14
- package/src/internal/_randomFormatEmail.ts +8 -2
- package/src/internal/_randomFormatHostname.ts +48 -1
- package/src/internal/_randomFormatIdnEmail.ts +18 -2
- package/src/internal/_randomFormatIdnHostname.ts +34 -2
- package/src/internal/_randomFormatIpv4.ts +3 -2
- package/src/internal/_randomFormatIpv6.ts +3 -2
- package/src/internal/_randomFormatIri.ts +3 -1
- package/src/internal/_randomFormatIriReference.ts +3 -1
- package/src/internal/_randomFormatJsonPointer.ts +8 -2
- package/src/internal/_randomFormatPassword.ts +11 -6
- package/src/internal/_randomFormatRegex.ts +4 -1
- package/src/internal/_randomFormatRelativeJsonPointer.ts +13 -6
- package/src/internal/_randomFormatTime.ts +13 -10
- package/src/internal/_randomFormatUri.ts +3 -1
- package/src/internal/_randomFormatUriReference.ts +3 -1
- package/src/internal/_randomFormatUriTemplate.ts +3 -1
- package/src/internal/_randomFormatUrl.ts +25 -2
- package/src/internal/_randomFormatUuid.ts +10 -6
- package/src/internal/_randomInteger.ts +87 -40
- package/src/internal/_randomMultiple.ts +245 -0
- package/src/internal/_randomNumber.ts +72 -55
- package/src/internal/_randomPattern.ts +26 -4
- package/src/internal/_randomStringLength.ts +72 -0
- package/src/internal/_stringLength.ts +5 -0
- package/src/internal/_validateReport.ts +5 -1
- package/src/internal/private/__notationRename.ts +24 -0
- package/src/json.ts +2 -2
- package/src/module.ts +4 -6
- package/src/notations.ts +20 -4
- package/lib/internal/private/__notationCapitalize.d.ts +0 -1
- package/lib/internal/private/__notationCapitalize.js +0 -6
- package/lib/internal/private/__notationCapitalize.js.map +0 -1
- package/lib/internal/private/__notationCapitalize.mjs +0 -6
- package/lib/internal/private/__notationCapitalize.mjs.map +0 -1
- package/lib/internal/private/__notationUnsnake.d.ts +0 -4
- package/lib/internal/private/__notationUnsnake.js +0 -26
- package/lib/internal/private/__notationUnsnake.js.map +0 -1
- package/lib/internal/private/__notationUnsnake.mjs +0 -15
- package/lib/internal/private/__notationUnsnake.mjs.map +0 -1
- package/native/cmd/ttsc-typia/plugin_options_missing_config_test.go +0 -26
- package/native/cmd/ttsc-typia/plugin_options_undefined_false_test.go +0 -36
- package/src/internal/private/__notationCapitalize.ts +0 -2
- package/src/internal/private/__notationUnsnake.ts +0 -24
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestJsonStringifySpecialKeyTransform pins json.createStringify (and the
|
|
12
|
+
// guarded isStringify / assertStringify / validateStringify variants) against a
|
|
13
|
+
// static object key that contains a double quote, a backslash, a control
|
|
14
|
+
// character, a `${` interpolation sequence, an empty string, or a backtick
|
|
15
|
+
// (#2201).
|
|
16
|
+
//
|
|
17
|
+
// StringifyJoinder emits each static key by JSON-escaping it with
|
|
18
|
+
// json.Marshal, then splicing the JSON bytes into a *template literal* through
|
|
19
|
+
// TemplateFactory.Generate. JSON escaping and template-literal escaping
|
|
20
|
+
// disagree, so at runtime `\"`->`"`, `\\`->`\`, a control char stays raw, a raw
|
|
21
|
+
// backtick closes the template (a SyntaxError in the emitted module), and `${`
|
|
22
|
+
// starts a live interpolation (a serialize-time ReferenceError / injection).
|
|
23
|
+
// The result is invalid JSON, or a crash, for exactly these keys, while
|
|
24
|
+
// ordinary keys, dynamic Record keys, and all string values stay correct.
|
|
25
|
+
//
|
|
26
|
+
// 1. Transform a fixture that exports json.createStringify (plus the guarded
|
|
27
|
+
// variants) for an object whose keys are `q"k`, `back\slash`, a TAB,
|
|
28
|
+
// `interp${bad}here`, the empty string, and a backtick.
|
|
29
|
+
// 2. Execute the emitted serializer in Node with a faithful
|
|
30
|
+
// _jsonStringifyNumber stub.
|
|
31
|
+
// 3. Require the serialized document to JSON.parse back to the original object
|
|
32
|
+
// for every key, and report the exact executed case count so a runner that
|
|
33
|
+
// silently skipped a key cannot pass as a false green.
|
|
34
|
+
func TestJsonStringifySpecialKeyTransform(t *testing.T) {
|
|
35
|
+
project := jsonStringifySpecialKeyProject(t)
|
|
36
|
+
js := jsonStringifySpecialKeyTransform(t, project)
|
|
37
|
+
jsonStringifySpecialKeyRunRuntime(t, project, js)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func jsonStringifySpecialKeyProject(t *testing.T) string {
|
|
41
|
+
t.Helper()
|
|
42
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
43
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
44
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
45
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
46
|
+
}
|
|
47
|
+
dir, err := os.MkdirTemp(base, "json-stringify-special-key-")
|
|
48
|
+
if err != nil {
|
|
49
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
50
|
+
}
|
|
51
|
+
t.Cleanup(func() {
|
|
52
|
+
_ = os.RemoveAll(dir)
|
|
53
|
+
})
|
|
54
|
+
src := filepath.Join(dir, "src")
|
|
55
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
56
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
57
|
+
}
|
|
58
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(jsonStringifySpecialKeyTSConfig), 0o644); err != nil {
|
|
59
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
60
|
+
}
|
|
61
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(jsonStringifySpecialKeySource), 0o644); err != nil {
|
|
62
|
+
t.Fatalf("write source: %v", err)
|
|
63
|
+
}
|
|
64
|
+
return dir
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
func jsonStringifySpecialKeyTransform(t *testing.T, project string) string {
|
|
68
|
+
t.Helper()
|
|
69
|
+
payload := `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`
|
|
70
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
71
|
+
return runTransform([]string{
|
|
72
|
+
"--cwd", project,
|
|
73
|
+
"--tsconfig", "tsconfig.json",
|
|
74
|
+
"--file", "src/main.ts",
|
|
75
|
+
"--output", "js",
|
|
76
|
+
"--plugins-json", payload,
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
if code != 0 {
|
|
80
|
+
t.Fatalf("json stringify special-key transform failed: code=%d stderr=\n%s", code, errText)
|
|
81
|
+
}
|
|
82
|
+
return out
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func jsonStringifySpecialKeyRunRuntime(t *testing.T, project string, js string) {
|
|
86
|
+
t.Helper()
|
|
87
|
+
node, err := exec.LookPath("node")
|
|
88
|
+
if err != nil {
|
|
89
|
+
t.Skip("node executable not found")
|
|
90
|
+
}
|
|
91
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
92
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
93
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
94
|
+
}
|
|
95
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
96
|
+
stubs := map[string]string{
|
|
97
|
+
"json-stringify-number-stub.cjs": jsonStringifySpecialKeyNumberStub,
|
|
98
|
+
"json-stringify-string-stub.cjs": jsonStringifySpecialKeyStringStub,
|
|
99
|
+
"throw-type-guard-error-stub.cjs": jsonStringifySpecialKeyThrowStub,
|
|
100
|
+
}
|
|
101
|
+
for name, content := range stubs {
|
|
102
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, name), []byte(content), 0o644); err != nil {
|
|
103
|
+
t.Fatalf("write %s: %v", name, err)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
runtimeJS := strings.ReplaceAll(js, `require("typia/lib/internal/_jsonStringifyNumber")`, `require("./json-stringify-number-stub.cjs")`)
|
|
107
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyString")`, `require("./json-stringify-string-stub.cjs")`)
|
|
108
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_throwTypeGuardError")`, `require("./throw-type-guard-error-stub.cjs")`)
|
|
109
|
+
runtimeJS = ttscTypiaTestRewriteCommonJS(t, runtimeJS)
|
|
110
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
111
|
+
t.Fatalf("write runtime module: %v", err)
|
|
112
|
+
}
|
|
113
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
114
|
+
if err := os.WriteFile(runner, []byte(jsonStringifySpecialKeyRunner), 0o644); err != nil {
|
|
115
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
116
|
+
}
|
|
117
|
+
cmd := exec.Command(node, runner)
|
|
118
|
+
cmd.Dir = runtimeDir
|
|
119
|
+
output, err := cmd.CombinedOutput()
|
|
120
|
+
if err != nil {
|
|
121
|
+
t.Fatalf("json stringify special-key runtime failed: %v\n%s", err, output)
|
|
122
|
+
}
|
|
123
|
+
const expected = "RAN 24 CASES"
|
|
124
|
+
if !strings.Contains(string(output), expected) {
|
|
125
|
+
t.Fatalf("json stringify special-key runner did not report %q; got:\n%s", expected, output)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const jsonStringifySpecialKeyTSConfig = `{
|
|
130
|
+
"compilerOptions": {
|
|
131
|
+
"target": "ES2022",
|
|
132
|
+
"module": "commonjs",
|
|
133
|
+
"moduleResolution": "bundler",
|
|
134
|
+
"ignoreDeprecations": "6.0",
|
|
135
|
+
"types": ["*"],
|
|
136
|
+
"esModuleInterop": true,
|
|
137
|
+
"strict": true,
|
|
138
|
+
"skipLibCheck": true
|
|
139
|
+
},
|
|
140
|
+
"include": ["src"]
|
|
141
|
+
}
|
|
142
|
+
`
|
|
143
|
+
|
|
144
|
+
const jsonStringifySpecialKeySource = `import typia from "typia";
|
|
145
|
+
|
|
146
|
+
interface Special {
|
|
147
|
+
"q\"k": number;
|
|
148
|
+
"back\\slash": number;
|
|
149
|
+
"\t": number;
|
|
150
|
+
"interp${bad}here": number;
|
|
151
|
+
"": number;
|
|
152
|
+
"` + "`" + `": number;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export const stringifySpecial = typia.json.createStringify<Special>();
|
|
156
|
+
export const isStringifySpecial = typia.json.createIsStringify<Special>();
|
|
157
|
+
export const assertStringifySpecial = typia.json.createAssertStringify<Special>();
|
|
158
|
+
export const validateStringifySpecial = typia.json.createValidateStringify<Special>();
|
|
159
|
+
`
|
|
160
|
+
|
|
161
|
+
const jsonStringifySpecialKeyNumberStub = `module.exports._jsonStringifyNumber = (value) => (Number.isFinite(value) ? String(value) : "null");
|
|
162
|
+
`
|
|
163
|
+
|
|
164
|
+
const jsonStringifySpecialKeyStringStub = `module.exports._jsonStringifyString = (value) => JSON.stringify(value);
|
|
165
|
+
`
|
|
166
|
+
|
|
167
|
+
const jsonStringifySpecialKeyThrowStub = `module.exports._throwTypeGuardError = (props) => {
|
|
168
|
+
const error = new Error(props.expected);
|
|
169
|
+
Object.assign(error, props);
|
|
170
|
+
throw error;
|
|
171
|
+
};
|
|
172
|
+
`
|
|
173
|
+
|
|
174
|
+
const jsonStringifySpecialKeyRunner = `const mod = require("./main.cjs");
|
|
175
|
+
|
|
176
|
+
const TAB = String.fromCharCode(9);
|
|
177
|
+
const BQ = String.fromCharCode(96);
|
|
178
|
+
|
|
179
|
+
const makeInput = () => {
|
|
180
|
+
const input = {};
|
|
181
|
+
input['q"k'] = 1;
|
|
182
|
+
input['back\\slash'] = 2;
|
|
183
|
+
input[TAB] = 3;
|
|
184
|
+
input['interp${bad}here'] = 4;
|
|
185
|
+
input[''] = 5;
|
|
186
|
+
input[BQ] = 6;
|
|
187
|
+
return input;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const entries = [
|
|
191
|
+
['q"k', 1],
|
|
192
|
+
['back\\slash', 2],
|
|
193
|
+
[TAB, 3],
|
|
194
|
+
['interp${bad}here', 4],
|
|
195
|
+
['', 5],
|
|
196
|
+
[BQ, 6],
|
|
197
|
+
];
|
|
198
|
+
|
|
199
|
+
let ran = 0;
|
|
200
|
+
|
|
201
|
+
const roundTrip = (label, text) => {
|
|
202
|
+
const parsed = JSON.parse(text);
|
|
203
|
+
for (const [key, expected] of entries) {
|
|
204
|
+
ran += 1;
|
|
205
|
+
if (parsed[key] !== expected) {
|
|
206
|
+
throw new Error(
|
|
207
|
+
label + ": key " + JSON.stringify(key) + " round-trip failed; got " +
|
|
208
|
+
JSON.stringify(parsed[key]) + " in " + text,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (Object.keys(parsed).length !== entries.length) {
|
|
213
|
+
throw new Error(label + ": unexpected key count in " + text);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// json.createStringify: the raw serializer must emit valid JSON for every key.
|
|
218
|
+
roundTrip("createStringify", mod.stringifySpecial(makeInput()));
|
|
219
|
+
|
|
220
|
+
// json.createIsStringify: valid input serializes; the document must round-trip.
|
|
221
|
+
const isText = mod.isStringifySpecial(makeInput());
|
|
222
|
+
if (isText === null) {
|
|
223
|
+
throw new Error("isStringify rejected a valid special-key object");
|
|
224
|
+
}
|
|
225
|
+
roundTrip("isStringify", isText);
|
|
226
|
+
|
|
227
|
+
// json.createAssertStringify: valid input passes the guard, then serializes.
|
|
228
|
+
roundTrip("assertStringify", mod.assertStringifySpecial(makeInput()));
|
|
229
|
+
|
|
230
|
+
// json.createValidateStringify: success carries the serialized document.
|
|
231
|
+
const validated = mod.validateStringifySpecial(makeInput());
|
|
232
|
+
if (validated.success !== true) {
|
|
233
|
+
throw new Error("validateStringify rejected a valid special-key object: " + JSON.stringify(validated));
|
|
234
|
+
}
|
|
235
|
+
roundTrip("validateStringify", validated.data);
|
|
236
|
+
|
|
237
|
+
console.log("RAN " + ran + " CASES");
|
|
238
|
+
`
|
|
@@ -74,6 +74,7 @@ func jsVersion(this js.Value, args []js.Value) any {
|
|
|
74
74
|
// file?: string, // absolute path of the .ts file to rewrite. Omit
|
|
75
75
|
// // for project-wide JSON output.
|
|
76
76
|
// output?: "ts"|"js",
|
|
77
|
+
// "plugins-json"?: string, // ttsc's resolved plugin manifest; see buildArgs
|
|
77
78
|
// }
|
|
78
79
|
//
|
|
79
80
|
// JS output: Promise<{ code: number, stdout: string, stderr: string }>.
|
|
@@ -154,9 +155,11 @@ func transformArgs(opts js.Value) []string {
|
|
|
154
155
|
} else {
|
|
155
156
|
out = append(out, "--output=ts")
|
|
156
157
|
}
|
|
157
|
-
return out
|
|
158
|
+
return append(out, pluginsJSONArgs(opts)...)
|
|
158
159
|
}
|
|
159
160
|
|
|
161
|
+
// buildArgs renders the JS options object into `runBuild`'s argv. Input mirrors
|
|
162
|
+
// jsTransform but carries `outDir`/`emit`/`noEmit` instead of `file`/`output`.
|
|
160
163
|
func buildArgs(opts js.Value) []string {
|
|
161
164
|
out := []string{}
|
|
162
165
|
if v := stringProp(opts, "cwd"); v != "" {
|
|
@@ -176,7 +179,23 @@ func buildArgs(opts js.Value) []string {
|
|
|
176
179
|
if boolProp(opts, "noEmit") {
|
|
177
180
|
out = append(out, "--noEmit")
|
|
178
181
|
}
|
|
179
|
-
return out
|
|
182
|
+
return append(out, pluginsJSONArgs(opts)...)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// pluginsJSONArgs forwards ttsc's resolved plugin manifest, when the caller
|
|
186
|
+
// supplied one.
|
|
187
|
+
//
|
|
188
|
+
// typia's options come from the entry its host resolved and handed it, never
|
|
189
|
+
// from re-reading tsconfig.json (samchon/typia#1887). A JS host driving this
|
|
190
|
+
// wasm is that host: it owns the virtual filesystem the tsconfig lives in, so it
|
|
191
|
+
// is the one that knows the resolved entry. Without this pass-through the wasm
|
|
192
|
+
// could only ever run typia at its defaults, because there would be no channel
|
|
193
|
+
// left to state anything else.
|
|
194
|
+
func pluginsJSONArgs(opts js.Value) []string {
|
|
195
|
+
if v := stringProp(opts, "plugins-json"); v != "" {
|
|
196
|
+
return []string{"--plugins-json=" + v}
|
|
197
|
+
}
|
|
198
|
+
return nil
|
|
180
199
|
}
|
|
181
200
|
|
|
182
201
|
func runWithCapturedIO(task func() int) any {
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestNativeCollectionIdentityIsTransform pins the runtime and emit behavior of
|
|
12
|
+
// typia.is for a user type whose name collides with a built-in collection native
|
|
13
|
+
// (#2212, the collection half of #2200).
|
|
14
|
+
//
|
|
15
|
+
// Collection-native classification matched Map/Set (iterate_metadata_map.go /
|
|
16
|
+
// iterate_metadata_set.go) and WeakMap/WeakSet (the generics loop in
|
|
17
|
+
// iterate_metadata_native.go) by base name alone, so a module-scoped user
|
|
18
|
+
// `interface Map<K, V> { brandMap; keyMap; valMap }` yielded the base name "Map"
|
|
19
|
+
// and was emitted as `input instanceof Map && [...]` — its own members dropped,
|
|
20
|
+
// byte-identical to the real-lib Map. Every valid structural value was rejected
|
|
21
|
+
// and the emit could throw where no such global exists.
|
|
22
|
+
//
|
|
23
|
+
// After the fix, collection-native classification (like the simples path #2200
|
|
24
|
+
// already gated) requires the matched symbol to be declared in a `.d.ts`
|
|
25
|
+
// declaration file, which a real built-in always is and a user type in a `.ts`
|
|
26
|
+
// module never is. A colliding user type then falls through to the structural
|
|
27
|
+
// object path and validates against its declared members, while the genuine
|
|
28
|
+
// natives keep their `instanceof` check.
|
|
29
|
+
//
|
|
30
|
+
// 1. Transform is for user interfaces named Map/Set/WeakMap/WeakSet (main.ts,
|
|
31
|
+
// module-scoped, shadowing the globals) and for the genuine globals of the
|
|
32
|
+
// same names (real.ts, unshadowed).
|
|
33
|
+
// 2. Assert the user emit is structural (its own brand members survive, no
|
|
34
|
+
// `instanceof`) while the genuine natives keep their `instanceof` path.
|
|
35
|
+
// 3. Execute both emitted modules in Node against the boundary matrix, requiring
|
|
36
|
+
// the runner to report the exact executed case count so a runner that
|
|
37
|
+
// silently skipped cases cannot pass as a false green.
|
|
38
|
+
func TestNativeCollectionIdentityIsTransform(t *testing.T) {
|
|
39
|
+
project := nativeCollectionIdentityProject(t)
|
|
40
|
+
transform := func(file string) string {
|
|
41
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
42
|
+
return runTransform([]string{
|
|
43
|
+
"--cwd", project,
|
|
44
|
+
"--tsconfig", "tsconfig.json",
|
|
45
|
+
"--file", file,
|
|
46
|
+
"--output", "js",
|
|
47
|
+
})
|
|
48
|
+
})
|
|
49
|
+
if code != 0 {
|
|
50
|
+
t.Fatalf("collection identity transform %s failed: code=%d stderr=\n%s", file, code, errText)
|
|
51
|
+
}
|
|
52
|
+
return out
|
|
53
|
+
}
|
|
54
|
+
userJS := transform("src/main.ts")
|
|
55
|
+
realJS := transform("src/real.ts")
|
|
56
|
+
|
|
57
|
+
// The colliding user types must validate structurally: their own members
|
|
58
|
+
// survive and no native instanceof is emitted for them.
|
|
59
|
+
for _, member := range []string{"brandMap", "brandSet", "brandWeakMap", "brandWeakSet"} {
|
|
60
|
+
if !strings.Contains(userJS, member) {
|
|
61
|
+
t.Fatalf("expected user collection type member %q to survive structurally, but it was dropped in:\n%s", member, userJS)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for _, gone := range []string{"instanceof Map", "instanceof Set", "instanceof WeakMap", "instanceof WeakSet"} {
|
|
65
|
+
if strings.Contains(userJS, gone) {
|
|
66
|
+
t.Fatalf("expected user collection collision %q to be reclassified structurally, but it survived in:\n%s", gone, userJS)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// The genuine globals of the same names must stay native.
|
|
70
|
+
for _, kept := range []string{"instanceof Map", "instanceof Set", "instanceof WeakMap", "instanceof WeakSet"} {
|
|
71
|
+
if !strings.Contains(realJS, kept) {
|
|
72
|
+
t.Fatalf("expected genuine native path %q to remain in transform output:\n%s", kept, realJS)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
nativeCollectionIdentityRunRuntimeCases(t, project, userJS, realJS)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
func nativeCollectionIdentityProject(t *testing.T) string {
|
|
79
|
+
t.Helper()
|
|
80
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
81
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
82
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
83
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
84
|
+
}
|
|
85
|
+
dir, err := os.MkdirTemp(base, "native-collection-identity-")
|
|
86
|
+
if err != nil {
|
|
87
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
88
|
+
}
|
|
89
|
+
t.Cleanup(func() {
|
|
90
|
+
_ = os.RemoveAll(dir)
|
|
91
|
+
})
|
|
92
|
+
src := filepath.Join(dir, "src")
|
|
93
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
94
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
95
|
+
}
|
|
96
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(finiteOptionNumberLeafTSConfig), 0o644); err != nil {
|
|
97
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
98
|
+
}
|
|
99
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(nativeCollectionIdentityUserSource), 0o644); err != nil {
|
|
100
|
+
t.Fatalf("write user source: %v", err)
|
|
101
|
+
}
|
|
102
|
+
if err := os.WriteFile(filepath.Join(src, "real.ts"), []byte(nativeCollectionIdentityRealSource), 0o644); err != nil {
|
|
103
|
+
t.Fatalf("write real source: %v", err)
|
|
104
|
+
}
|
|
105
|
+
return dir
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
func nativeCollectionIdentityRunRuntimeCases(t *testing.T, project string, userJS string, realJS string) {
|
|
109
|
+
t.Helper()
|
|
110
|
+
node, err := exec.LookPath("node")
|
|
111
|
+
if err != nil {
|
|
112
|
+
t.Skip("node executable not found")
|
|
113
|
+
}
|
|
114
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
115
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
116
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
117
|
+
}
|
|
118
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
119
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(ttscTypiaTestRewriteCommonJS(t, userJS)), 0o644); err != nil {
|
|
120
|
+
t.Fatalf("write user runtime module: %v", err)
|
|
121
|
+
}
|
|
122
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "real.cjs"), []byte(ttscTypiaTestRewriteCommonJS(t, realJS)), 0o644); err != nil {
|
|
123
|
+
t.Fatalf("write real runtime module: %v", err)
|
|
124
|
+
}
|
|
125
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
126
|
+
if err := os.WriteFile(runner, []byte(nativeCollectionIdentityRuntimeRunner), 0o644); err != nil {
|
|
127
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
128
|
+
}
|
|
129
|
+
cmd := exec.Command(node, runner)
|
|
130
|
+
cmd.Dir = runtimeDir
|
|
131
|
+
output, err := cmd.CombinedOutput()
|
|
132
|
+
if err != nil {
|
|
133
|
+
t.Fatalf("collection identity runtime cases failed: %v\n%s", err, output)
|
|
134
|
+
}
|
|
135
|
+
const expected = "RAN 27 CASES"
|
|
136
|
+
if !strings.Contains(string(output), expected) {
|
|
137
|
+
t.Fatalf("collection identity runner did not report %q; got:\n%s", expected, output)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// main.ts declares module-scoped interfaces named exactly Map/Set/WeakMap/WeakSet
|
|
142
|
+
// that shadow the globals within this module, so their base name is exactly the
|
|
143
|
+
// native name (the #2212 collision). Their type parameters are their own.
|
|
144
|
+
const nativeCollectionIdentityUserSource = `import typia from "typia";
|
|
145
|
+
|
|
146
|
+
interface Map<K, V> {
|
|
147
|
+
brandMap: string;
|
|
148
|
+
keyMap: K;
|
|
149
|
+
valMap: V;
|
|
150
|
+
}
|
|
151
|
+
interface Set<T> {
|
|
152
|
+
brandSet: string;
|
|
153
|
+
elemSet: T;
|
|
154
|
+
}
|
|
155
|
+
interface WeakMap<K extends object, V> {
|
|
156
|
+
brandWeakMap: string;
|
|
157
|
+
}
|
|
158
|
+
interface WeakSet<T extends object> {
|
|
159
|
+
brandWeakSet: string;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export const isUserMap = typia.createIs<Map<string, number>>();
|
|
163
|
+
export const isUserSet = typia.createIs<Set<number>>();
|
|
164
|
+
export const isUserWeakMap = typia.createIs<WeakMap<object, number>>();
|
|
165
|
+
export const isUserWeakSet = typia.createIs<WeakSet<object>>();
|
|
166
|
+
`
|
|
167
|
+
|
|
168
|
+
// real.ts declares no local shadow, so its Map/Set/WeakMap/WeakSet resolve to the
|
|
169
|
+
// genuine globals declared in a lib `.d.ts` and must stay native.
|
|
170
|
+
const nativeCollectionIdentityRealSource = `import typia from "typia";
|
|
171
|
+
|
|
172
|
+
export const isRealMap = typia.createIs<Map<string, number>>();
|
|
173
|
+
export const isRealSet = typia.createIs<Set<number>>();
|
|
174
|
+
export const isRealWeakMap = typia.createIs<WeakMap<object, number>>();
|
|
175
|
+
export const isRealWeakSet = typia.createIs<WeakSet<object>>();
|
|
176
|
+
`
|
|
177
|
+
|
|
178
|
+
const nativeCollectionIdentityRuntimeRunner = `const user = require("./main.cjs");
|
|
179
|
+
const real = require("./real.cjs");
|
|
180
|
+
|
|
181
|
+
let ran = 0;
|
|
182
|
+
const eq = (name, actual, expected) => {
|
|
183
|
+
ran += 1;
|
|
184
|
+
if (actual !== expected) {
|
|
185
|
+
throw new Error(name + ": expected " + expected + " but got " + actual);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// A user interface named Map must validate against its own members, not the
|
|
190
|
+
// native Map instanceof path (#2212).
|
|
191
|
+
eq("isUserMap valid", user.isUserMap({ brandMap: "x", keyMap: "k", valMap: 1 }), true);
|
|
192
|
+
eq("isUserMap missing brand", user.isUserMap({ keyMap: "k", valMap: 1 }), false);
|
|
193
|
+
eq("isUserMap wrong valMap type", user.isUserMap({ brandMap: "x", keyMap: "k", valMap: "1" }), false);
|
|
194
|
+
eq("isUserMap rejects a real Map", user.isUserMap(new Map([["k", 1]])), false);
|
|
195
|
+
eq("isUserMap null", user.isUserMap(null), false);
|
|
196
|
+
eq("isUserMap empty object", user.isUserMap({}), false);
|
|
197
|
+
|
|
198
|
+
// A user interface named Set is structural too.
|
|
199
|
+
eq("isUserSet valid", user.isUserSet({ brandSet: "s", elemSet: 2 }), true);
|
|
200
|
+
eq("isUserSet missing brand", user.isUserSet({ elemSet: 2 }), false);
|
|
201
|
+
eq("isUserSet rejects a real Set", user.isUserSet(new Set([1])), false);
|
|
202
|
+
|
|
203
|
+
// A user interface named WeakMap is structural, not instanceof WeakMap.
|
|
204
|
+
eq("isUserWeakMap valid", user.isUserWeakMap({ brandWeakMap: "w" }), true);
|
|
205
|
+
eq("isUserWeakMap missing brand", user.isUserWeakMap({}), false);
|
|
206
|
+
eq("isUserWeakMap rejects a real WeakMap", user.isUserWeakMap(new WeakMap()), false);
|
|
207
|
+
|
|
208
|
+
// A user interface named WeakSet is structural, not instanceof WeakSet.
|
|
209
|
+
eq("isUserWeakSet valid", user.isUserWeakSet({ brandWeakSet: "z" }), true);
|
|
210
|
+
eq("isUserWeakSet missing brand", user.isUserWeakSet({}), false);
|
|
211
|
+
eq("isUserWeakSet rejects a real WeakSet", user.isUserWeakSet(new WeakSet()), false);
|
|
212
|
+
|
|
213
|
+
// The genuine globals keep their instanceof check and accept a real instance
|
|
214
|
+
// while rejecting a plain object of the same shape.
|
|
215
|
+
eq("isRealMap real", real.isRealMap(new Map([["a", 1]])), true);
|
|
216
|
+
eq("isRealMap empty real", real.isRealMap(new Map()), true);
|
|
217
|
+
eq("isRealMap plain object", real.isRealMap({}), false);
|
|
218
|
+
eq("isRealMap user Map shape", real.isRealMap({ brandMap: "x", keyMap: "k", valMap: 1 }), false);
|
|
219
|
+
|
|
220
|
+
eq("isRealSet real", real.isRealSet(new Set([1, 2])), true);
|
|
221
|
+
eq("isRealSet plain object", real.isRealSet({}), false);
|
|
222
|
+
|
|
223
|
+
eq("isRealWeakMap real", real.isRealWeakMap(new WeakMap()), true);
|
|
224
|
+
eq("isRealWeakMap plain object", real.isRealWeakMap({}), false);
|
|
225
|
+
|
|
226
|
+
eq("isRealWeakSet real", real.isRealWeakSet(new WeakSet()), true);
|
|
227
|
+
eq("isRealWeakSet plain object", real.isRealWeakSet({}), false);
|
|
228
|
+
|
|
229
|
+
// Real collections stay disjoint from one another.
|
|
230
|
+
eq("isRealMap rejects a real Set", real.isRealMap(new Set()), false);
|
|
231
|
+
eq("isRealWeakMap rejects a real WeakSet", real.isRealWeakMap(new WeakSet()), false);
|
|
232
|
+
|
|
233
|
+
console.log("RAN " + ran + " CASES");
|
|
234
|
+
`
|