typia 13.1.1 → 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 +60 -6
- 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/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,279 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestSymbolKeyMemberFilterTransform verifies a `symbol`-keyed data member is
|
|
12
|
+
// excluded from a type's validated shape and from its emitted JSON schema, so a
|
|
13
|
+
// real object carrying that member passes its own `is`/`assert`/`validate` guard
|
|
14
|
+
// (#2226).
|
|
15
|
+
//
|
|
16
|
+
// A symbol-keyed member is unreachable through the string index access typia
|
|
17
|
+
// emits, is ignored by `JSON.stringify`, and has no JSON-Schema representation.
|
|
18
|
+
// Before the fix the member filter excluded only keyword `private`/`protected`
|
|
19
|
+
// and ES `#private` members, so a symbol key leaked into the validated shape
|
|
20
|
+
// under the checker's internal escaped name (`input["\xFE@sym@5"]`) — a string
|
|
21
|
+
// key no runtime object carries, making the guard unconditionally false — and
|
|
22
|
+
// into the schema as an uninhabitable required property.
|
|
23
|
+
//
|
|
24
|
+
// 1. Emit `is`/`assert`/`validate` plus `json.schemas` for a `unique symbol`
|
|
25
|
+
// key, a well-known symbol key, a symbol key inside an intersection, a type
|
|
26
|
+
// whose only member is symbol-keyed, a symbol-keyed method, and
|
|
27
|
+
// string/number/computed-string keys as positive controls.
|
|
28
|
+
// 2. Assert neither the validators nor the schemas reference a mangled key.
|
|
29
|
+
// 3. Execute the emitted JavaScript against real objects carrying the symbol
|
|
30
|
+
// members, proving each passes on its string-keyed shape.
|
|
31
|
+
func TestSymbolKeyMemberFilterTransform(t *testing.T) {
|
|
32
|
+
project := symbolKeyMemberFilterProject(t)
|
|
33
|
+
|
|
34
|
+
ts := symbolKeyMemberFilterTransform(t, project, "ts")
|
|
35
|
+
// The checker escapes a symbol-keyed member name with a leading 0xFE byte
|
|
36
|
+
// (`InternalSymbolNamePrefix`), an invalid UTF-8 lead unit that never begins a
|
|
37
|
+
// real string property name, followed by `@<name>@<id>`; the printer renders
|
|
38
|
+
// that byte as `�` (or the replacement character itself). None of those,
|
|
39
|
+
// nor the `@<name>@` infix, can appear in the fixture source echoed alongside
|
|
40
|
+
// the validators, so each is an exact byte signature of the leak.
|
|
41
|
+
for _, marker := range []string{
|
|
42
|
+
string([]byte{0xFE}),
|
|
43
|
+
"\uFFFD",
|
|
44
|
+
`\uFFFD`,
|
|
45
|
+
`\ufffd`,
|
|
46
|
+
"@sym@",
|
|
47
|
+
"@toStringTag@",
|
|
48
|
+
"@joined@",
|
|
49
|
+
"@solo@",
|
|
50
|
+
"@invoke@",
|
|
51
|
+
} {
|
|
52
|
+
if strings.Contains(ts, marker) {
|
|
53
|
+
t.Fatalf("emit references a mangled symbol key (marker %q leaked into the validated shape):\n%s", marker, ts)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// The string-keyed shape must still be validated.
|
|
57
|
+
for _, needle := range []string{"input.name", "input.id", "input.plain"} {
|
|
58
|
+
if !strings.Contains(ts, needle) {
|
|
59
|
+
t.Fatalf("emit dropped a string-keyed property %q:\n%s", needle, ts)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
symbolKeyMemberFilterRunRuntimeCases(
|
|
64
|
+
t,
|
|
65
|
+
project,
|
|
66
|
+
symbolKeyMemberFilterTransform(t, project, "js"),
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func symbolKeyMemberFilterProject(t *testing.T) string {
|
|
71
|
+
t.Helper()
|
|
72
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
73
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
74
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
75
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
76
|
+
}
|
|
77
|
+
dir, err := os.MkdirTemp(base, "symbol-key-member-filter-")
|
|
78
|
+
if err != nil {
|
|
79
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
80
|
+
}
|
|
81
|
+
t.Cleanup(func() {
|
|
82
|
+
_ = os.RemoveAll(dir)
|
|
83
|
+
})
|
|
84
|
+
src := filepath.Join(dir, "src")
|
|
85
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
86
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
87
|
+
}
|
|
88
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(symbolKeyMemberFilterTSConfig), 0o644); err != nil {
|
|
89
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
90
|
+
}
|
|
91
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(symbolKeyMemberFilterSource), 0o644); err != nil {
|
|
92
|
+
t.Fatalf("write source: %v", err)
|
|
93
|
+
}
|
|
94
|
+
return dir
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
func symbolKeyMemberFilterTransform(t *testing.T, project string, output string) string {
|
|
98
|
+
t.Helper()
|
|
99
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
100
|
+
return runTransform([]string{
|
|
101
|
+
"--cwd", project,
|
|
102
|
+
"--tsconfig", "tsconfig.json",
|
|
103
|
+
"--file", "src/main.ts",
|
|
104
|
+
"--output", output,
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
if code != 0 {
|
|
108
|
+
t.Fatalf("symbol key member filter transform failed: output=%s code=%d stderr=\n%s", output, code, errText)
|
|
109
|
+
}
|
|
110
|
+
return out
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
func symbolKeyMemberFilterRunRuntimeCases(t *testing.T, project string, js string) {
|
|
114
|
+
t.Helper()
|
|
115
|
+
node, err := exec.LookPath("node")
|
|
116
|
+
if err != nil {
|
|
117
|
+
t.Skip("node executable not found")
|
|
118
|
+
}
|
|
119
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
120
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
121
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
122
|
+
}
|
|
123
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
124
|
+
runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
|
|
125
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
126
|
+
t.Fatalf("write runtime module: %v", err)
|
|
127
|
+
}
|
|
128
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
129
|
+
if err := os.WriteFile(runner, []byte(symbolKeyMemberFilterRuntimeRunner), 0o644); err != nil {
|
|
130
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
131
|
+
}
|
|
132
|
+
cmd := exec.Command(node, runner)
|
|
133
|
+
cmd.Dir = runtimeDir
|
|
134
|
+
if output, err := cmd.CombinedOutput(); err != nil {
|
|
135
|
+
t.Fatalf("symbol key member filter runtime cases failed: %v\n%s", err, output)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const symbolKeyMemberFilterTSConfig = `{
|
|
140
|
+
"compilerOptions": {
|
|
141
|
+
"target": "ES2022",
|
|
142
|
+
"module": "commonjs",
|
|
143
|
+
"moduleResolution": "bundler",
|
|
144
|
+
"ignoreDeprecations": "6.0",
|
|
145
|
+
"types": ["*"],
|
|
146
|
+
"esModuleInterop": true,
|
|
147
|
+
"strict": true,
|
|
148
|
+
"skipLibCheck": true
|
|
149
|
+
},
|
|
150
|
+
"include": ["src"]
|
|
151
|
+
}
|
|
152
|
+
`
|
|
153
|
+
|
|
154
|
+
const symbolKeyMemberFilterSource = `import typia from "typia";
|
|
155
|
+
|
|
156
|
+
declare const sym: unique symbol;
|
|
157
|
+
declare const joined: unique symbol;
|
|
158
|
+
declare const solo: unique symbol;
|
|
159
|
+
declare const invoke: unique symbol;
|
|
160
|
+
declare const COMPUTED: "computed";
|
|
161
|
+
|
|
162
|
+
export interface Symbolic {
|
|
163
|
+
name: string;
|
|
164
|
+
[sym]: number;
|
|
165
|
+
[Symbol.toStringTag]: string;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface Controlled {
|
|
169
|
+
plain: string;
|
|
170
|
+
"quoted-key": number;
|
|
171
|
+
42: boolean;
|
|
172
|
+
[COMPUTED]: string;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export type Joined = { id: string } & { [joined]: number };
|
|
176
|
+
|
|
177
|
+
export interface SoloSymbol {
|
|
178
|
+
[solo]: number;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export interface Methodic {
|
|
182
|
+
id: string;
|
|
183
|
+
[invoke](): number;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export const isSymbolic = typia.createIs<Symbolic>();
|
|
187
|
+
export const assertSymbolic = typia.createAssert<Symbolic>();
|
|
188
|
+
export const validateSymbolic = typia.createValidate<Symbolic>();
|
|
189
|
+
export const isControlled = typia.createIs<Controlled>();
|
|
190
|
+
export const isJoined = typia.createIs<Joined>();
|
|
191
|
+
export const isSolo = typia.createIs<SoloSymbol>();
|
|
192
|
+
export const isMethodic = typia.createIs<Methodic>();
|
|
193
|
+
export const schemas = typia.json.schemas<[Symbolic, Joined, SoloSymbol, Methodic]>();
|
|
194
|
+
`
|
|
195
|
+
|
|
196
|
+
const symbolKeyMemberFilterRuntimeRunner = `const mod = require("./main.cjs");
|
|
197
|
+
|
|
198
|
+
const sym = Symbol("sym");
|
|
199
|
+
const joined = Symbol("joined");
|
|
200
|
+
const solo = Symbol("solo");
|
|
201
|
+
const invoke = Symbol("invoke");
|
|
202
|
+
|
|
203
|
+
const expect = (label, actual, expected) => {
|
|
204
|
+
if (actual !== expected) {
|
|
205
|
+
throw new Error(label + ": expected " + expected + " but got " + actual);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// A real object carrying every declared member — including the symbol-keyed
|
|
210
|
+
// ones — passes its own guard.
|
|
211
|
+
expect(
|
|
212
|
+
"is real Symbolic value",
|
|
213
|
+
mod.isSymbolic({ name: "x", [sym]: 1, [Symbol.toStringTag]: "Symbolic" }),
|
|
214
|
+
true,
|
|
215
|
+
);
|
|
216
|
+
expect("is real Joined value", mod.isJoined({ id: "x", [joined]: 1 }), true);
|
|
217
|
+
expect("is real SoloSymbol value", mod.isSolo({ [solo]: 1 }), true);
|
|
218
|
+
expect("is real Methodic value", mod.isMethodic({ id: "x", [invoke]: () => 1 }), true);
|
|
219
|
+
|
|
220
|
+
// A symbol-keyed member is not part of the structural JSON shape, so a plain
|
|
221
|
+
// object carrying only the string keys is accepted too.
|
|
222
|
+
expect("is plain Symbolic shape", mod.isSymbolic({ name: "x" }), true);
|
|
223
|
+
expect("is plain Joined shape", mod.isJoined({ id: "x" }), true);
|
|
224
|
+
expect("is empty SoloSymbol shape", mod.isSolo({}), true);
|
|
225
|
+
expect("is plain Methodic shape", mod.isMethodic({ id: "x" }), true);
|
|
226
|
+
|
|
227
|
+
// The string-keyed shape is still validated structurally.
|
|
228
|
+
expect("reject wrong Symbolic name type", mod.isSymbolic({ name: 1 }), false);
|
|
229
|
+
expect("reject missing Symbolic name", mod.isSymbolic({}), false);
|
|
230
|
+
expect("reject missing Joined id", mod.isJoined({ [joined]: 1 }), false);
|
|
231
|
+
expect("reject non-object SoloSymbol", mod.isSolo(null), false);
|
|
232
|
+
|
|
233
|
+
// Positive controls: string / number / computed-string keys still resolve.
|
|
234
|
+
expect(
|
|
235
|
+
"is Controlled value",
|
|
236
|
+
mod.isControlled({ plain: "a", "quoted-key": 1, 42: true, computed: "c" }),
|
|
237
|
+
true,
|
|
238
|
+
);
|
|
239
|
+
expect(
|
|
240
|
+
"reject missing computed-string key",
|
|
241
|
+
mod.isControlled({ plain: "a", "quoted-key": 1, 42: true }),
|
|
242
|
+
false,
|
|
243
|
+
);
|
|
244
|
+
expect(
|
|
245
|
+
"reject missing numeric key",
|
|
246
|
+
mod.isControlled({ plain: "a", "quoted-key": 1, computed: "c" }),
|
|
247
|
+
false,
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// assert / validate accept a real value without touching a mangled key.
|
|
251
|
+
expect(
|
|
252
|
+
"assert real Symbolic returns input",
|
|
253
|
+
typeof mod.assertSymbolic({ name: "x", [sym]: 1, [Symbol.toStringTag]: "Symbolic" }),
|
|
254
|
+
"object",
|
|
255
|
+
);
|
|
256
|
+
expect(
|
|
257
|
+
"validate real Symbolic succeeds",
|
|
258
|
+
mod.validateSymbolic({ name: "x", [sym]: 1, [Symbol.toStringTag]: "Symbolic" }).success,
|
|
259
|
+
true,
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
let threw = false;
|
|
263
|
+
try {
|
|
264
|
+
mod.assertSymbolic({ name: 1 });
|
|
265
|
+
} catch (_exp) {
|
|
266
|
+
threw = true;
|
|
267
|
+
}
|
|
268
|
+
expect("assert rejects wrong name type", threw, true);
|
|
269
|
+
|
|
270
|
+
// The emitted schemas carry no mangled symbol key.
|
|
271
|
+
const serialized = JSON.stringify(mod.schemas);
|
|
272
|
+
for (const marker of ["@sym@", "@toStringTag@", "@joined@", "@solo@", "@invoke@", "�"]) {
|
|
273
|
+
if (serialized.includes(marker)) {
|
|
274
|
+
throw new Error("schema references a mangled symbol key (" + marker + "): " + serialized);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
const required = JSON.stringify(mod.schemas.components.schemas.Symbolic.required);
|
|
278
|
+
expect("Symbolic schema requires only its string key", required, JSON.stringify(["name"]));
|
|
279
|
+
`
|
|
@@ -100,8 +100,10 @@ func templateInterpolationTypeTagsRunRuntimeCases(t *testing.T, project string,
|
|
|
100
100
|
// common stub set covers; stub them before the shared rewrite asserts that no
|
|
101
101
|
// `typia/lib/internal/*` import survives.
|
|
102
102
|
extraStubs := map[string]string{
|
|
103
|
-
"is-type-int32-stub.cjs":
|
|
104
|
-
"random-number-stub.cjs":
|
|
103
|
+
"is-type-int32-stub.cjs": "module.exports._isTypeInt32 = (value) => Number.isInteger(value) && -2147483648 <= value && value <= 2147483647;\n",
|
|
104
|
+
"random-number-stub.cjs": templateInterpolationTypeTagsRandomNumberStub,
|
|
105
|
+
"random-string-stub.cjs": "module.exports._randomString = () => 'prefix';\n",
|
|
106
|
+
"json-stringify-string-stub.cjs": "module.exports._jsonStringifyString = (value) => JSON.stringify(value);\n",
|
|
105
107
|
}
|
|
106
108
|
for name, content := range extraStubs {
|
|
107
109
|
if err := os.WriteFile(filepath.Join(runtimeDir, name), []byte(content), 0o644); err != nil {
|
|
@@ -110,6 +112,8 @@ func templateInterpolationTypeTagsRunRuntimeCases(t *testing.T, project string,
|
|
|
110
112
|
}
|
|
111
113
|
runtimeJS := strings.ReplaceAll(js, `require("typia/lib/internal/_isTypeInt32")`, `require("./is-type-int32-stub.cjs")`)
|
|
112
114
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_randomNumber")`, `require("./random-number-stub.cjs")`)
|
|
115
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_randomString")`, `require("./random-string-stub.cjs")`)
|
|
116
|
+
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyString")`, `require("./json-stringify-string-stub.cjs")`)
|
|
113
117
|
runtimeJS = ttscTypiaTestRewriteCommonJS(t, runtimeJS)
|
|
114
118
|
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
115
119
|
t.Fatalf("write runtime module: %v", err)
|
|
@@ -153,9 +157,14 @@ type StrNum = ` + "`${string & tags.MaxLength<2>}-${number}`" + `;
|
|
|
153
157
|
type NumStr = ` + "`${number & tags.Maximum<9>}-${string & tags.MinLength<2>}`" + `;
|
|
154
158
|
type Dec = ` + "`${number & tags.Maximum<1.2>}.${number}`" + `;
|
|
155
159
|
type BigDot = ` + "`${bigint}.${number & tags.Minimum<5>}`" + `;
|
|
160
|
+
type Triple = ` + "`${string & tags.MaxLength<2>}${string & tags.MinLength<2>}${number & tags.Minimum<10>}`" + `;
|
|
161
|
+
type AmbiguousUnion = Adjacent | NonAdj;
|
|
156
162
|
interface DynKey {
|
|
157
163
|
[key: ` + "`slot${number & tags.Minimum<0> & tags.Maximum<9>}`" + `]: string;
|
|
158
164
|
}
|
|
165
|
+
interface AmbiguousDynKey {
|
|
166
|
+
[key: ` + "`${string}${number & tags.Minimum<10>}`" + `]: string;
|
|
167
|
+
}
|
|
159
168
|
|
|
160
169
|
export const isPercent = typia.createIs<Percent>();
|
|
161
170
|
export const validatePercent = typia.createValidate<Percent>();
|
|
@@ -168,14 +177,22 @@ export const isMultiline = typia.createIs<Multiline>();
|
|
|
168
177
|
export const isBigRange = typia.createIs<BigRange>();
|
|
169
178
|
export const isBigExcl = typia.createIs<BigExcl>();
|
|
170
179
|
export const isAdjacent = typia.createIs<Adjacent>();
|
|
180
|
+
export const validateAdjacent = typia.createValidate<Adjacent>();
|
|
181
|
+
export const assertAdjacent = typia.createAssert<Adjacent>();
|
|
171
182
|
export const isInfix = typia.createIs<Infix>();
|
|
172
183
|
export const isNonAdj = typia.createIs<NonAdj>();
|
|
173
184
|
export const isStrNum = typia.createIs<StrNum>();
|
|
174
185
|
export const isNumStr = typia.createIs<NumStr>();
|
|
175
186
|
export const isDec = typia.createIs<Dec>();
|
|
176
187
|
export const isBigDot = typia.createIs<BigDot>();
|
|
188
|
+
export const isTriple = typia.createIs<Triple>();
|
|
189
|
+
export const isAmbiguousUnion = typia.createIs<AmbiguousUnion>();
|
|
177
190
|
export const equalsDynKey = typia.createEquals<DynKey>();
|
|
191
|
+
export const equalsAmbiguousDynKey = typia.createEquals<AmbiguousDynKey>();
|
|
178
192
|
export const randomPercent = typia.createRandom<Percent>();
|
|
193
|
+
export const randomAdjacent = typia.createRandom<Adjacent>();
|
|
194
|
+
export const stringifyAdjacent = typia.json.createValidateStringify<{ value: Adjacent }>();
|
|
195
|
+
export const schemaAdjacent = typia.json.schemas<[Adjacent]>();
|
|
179
196
|
`
|
|
180
197
|
|
|
181
198
|
const templateInterpolationTypeTagsRuntimeRunner = `const mod = require("./main.cjs");
|
|
@@ -248,11 +265,13 @@ expect("bigint excluded value", mod.isBigExcl("#5"), false);
|
|
|
248
265
|
expect("bigint allowed value", mod.isBigExcl("#3"), true);
|
|
249
266
|
expect("bigint exclude negative", mod.isBigExcl("#-1"), false);
|
|
250
267
|
|
|
251
|
-
// Adjacent variable-width placeholders
|
|
252
|
-
//
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
expect("adjacent placeholders
|
|
268
|
+
// Adjacent variable-width placeholders accept a non-greedy split when it is the
|
|
269
|
+
// split that satisfies the number tag.
|
|
270
|
+
expect("adjacent placeholders backtrack", mod.isAdjacent("abc123"), true);
|
|
271
|
+
expect("adjacent placeholders edge split", mod.isAdjacent("123"), true);
|
|
272
|
+
expect("adjacent placeholders no valid split", mod.isAdjacent("abc9"), false);
|
|
273
|
+
expect("adjacent placeholders structural failure", mod.isAdjacent("abc"), false);
|
|
274
|
+
expect("adjacent placeholders long invalid input", mod.isAdjacent("x".repeat(2048) + "9"), false);
|
|
256
275
|
|
|
257
276
|
// A sole string fenced by literals is enforced: the ^/$ anchors pin "a" and the
|
|
258
277
|
// final "b", so the split string="XbY" (length 3) is unique and exceeds
|
|
@@ -260,15 +279,13 @@ expect("adjacent placeholders fall back", mod.isAdjacent("abc123"), true);
|
|
|
260
279
|
expect("sole string fenced by literals, too long", mod.isInfix("aXbYb"), false);
|
|
261
280
|
expect("sole string fenced by literals, in range", mod.isInfix("aXb"), true);
|
|
262
281
|
|
|
263
|
-
// A
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
expect("string with sibling falls back", mod.isNonAdj("aXbXcd"), true);
|
|
282
|
+
// A repeated literal fence tries each split until the tagged suffix is valid.
|
|
283
|
+
expect("string sibling backtracks", mod.isNonAdj("aXbXcd"), true);
|
|
284
|
+
expect("string sibling no valid split", mod.isNonAdj("aXbc"), false);
|
|
267
285
|
|
|
268
|
-
//
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
expect("strnum string-first falls back", mod.isStrNum("xy-1e-9"), true);
|
|
286
|
+
// A separator that can also occur in an exponent is tried at each position.
|
|
287
|
+
expect("strnum string-first backtracks", mod.isStrNum("xy-1e-9"), true);
|
|
288
|
+
expect("strnum no valid bounded prefix", mod.isStrNum("toolong-1"), false);
|
|
272
289
|
|
|
273
290
|
// number-first: "-" is not number-extendable, so both placeholders are pinned
|
|
274
291
|
// and enforced — number=50 > 9 fails, string="a" length 1 < 2 fails.
|
|
@@ -276,15 +293,35 @@ expect("numstr ok", mod.isNumStr("5-ab"), true);
|
|
|
276
293
|
expect("numstr number violated", mod.isNumStr("50-ab"), false);
|
|
277
294
|
expect("numstr string violated", mod.isNumStr("5-a"), false);
|
|
278
295
|
|
|
279
|
-
//
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
296
|
+
// A decimal point can be part of either number; any fully valid split passes.
|
|
297
|
+
expect("dec decimal-separator backtracks", mod.isDec("1.9.0"), true);
|
|
298
|
+
expect("dec no valid bounded first number", mod.isDec("2.0.3"), false);
|
|
299
|
+
|
|
300
|
+
// A bigint/number mix keeps the bigint side integral while trying dot fences.
|
|
301
|
+
expect("bigint-dot-number backtracks", mod.isBigDot("1.9.4"), true);
|
|
302
|
+
expect("bigint-dot-number no valid suffix", mod.isBigDot("1.4.0"), false);
|
|
303
|
+
expect("three adjacent placeholders backtrack", mod.isTriple("abcd12"), true);
|
|
304
|
+
expect("three adjacent placeholders no valid split", mod.isTriple("abcd9"), false);
|
|
305
|
+
expect("ambiguous union adjacent branch", mod.isAmbiguousUnion("prefix123"), true);
|
|
306
|
+
expect("ambiguous union fenced branch", mod.isAmbiguousUnion("aXbXcd"), true);
|
|
307
|
+
expect("ambiguous union no valid branch", mod.isAmbiguousUnion("prefix9"), false);
|
|
283
308
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
309
|
+
const adjacentFailure = mod.validateAdjacent("abc9");
|
|
310
|
+
if (
|
|
311
|
+
adjacentFailure.success !== false ||
|
|
312
|
+
adjacentFailure.errors.every((error) => error.expected.includes("Minimum<10>") === false)
|
|
313
|
+
) {
|
|
314
|
+
throw new Error("ambiguous validate error should name Minimum<10>: " + JSON.stringify(adjacentFailure));
|
|
315
|
+
}
|
|
316
|
+
let adjacentAsserted = false;
|
|
317
|
+
try {
|
|
318
|
+
mod.assertAdjacent("abc9");
|
|
319
|
+
} catch (error) {
|
|
320
|
+
adjacentAsserted = String(error && error.message).includes("Minimum<10>");
|
|
321
|
+
}
|
|
322
|
+
if (adjacentAsserted !== true) {
|
|
323
|
+
throw new Error("ambiguous assert error should name Minimum<10>");
|
|
324
|
+
}
|
|
288
325
|
|
|
289
326
|
// A dynamic index key typed as a tagged-interpolation template (the
|
|
290
327
|
// check_dynamic_key path): a key whose number violates the tag no longer
|
|
@@ -293,6 +330,8 @@ expect("dynkey in range", mod.equalsDynKey({ slot5: "x" }), true);
|
|
|
293
330
|
expect("dynkey both ends", mod.equalsDynKey({ slot0: "x", slot9: "y" }), true);
|
|
294
331
|
expect("dynkey out of range", mod.equalsDynKey({ slot50: "x" }), false);
|
|
295
332
|
expect("dynkey non-number", mod.equalsDynKey({ slotABC: "x" }), false);
|
|
333
|
+
expect("ambiguous dynkey valid split", mod.equalsAmbiguousDynKey({ slot123: "x" }), true);
|
|
334
|
+
expect("ambiguous dynkey invalid split", mod.equalsAmbiguousDynKey({ slot9: "x" }), false);
|
|
296
335
|
|
|
297
336
|
// validate must name the violated placeholder tag, not just the template.
|
|
298
337
|
const tooBig = mod.validatePercent("150%");
|
|
@@ -319,4 +358,28 @@ for (let i = 0; i < 100; ++i) {
|
|
|
319
358
|
throw new Error("random percent did not round-trip: " + JSON.stringify(value));
|
|
320
359
|
}
|
|
321
360
|
}
|
|
361
|
+
for (let i = 0; i < 25; ++i) {
|
|
362
|
+
const value = mod.randomAdjacent(generator);
|
|
363
|
+
if (mod.isAdjacent(value) !== true) {
|
|
364
|
+
throw new Error("random adjacent template did not round-trip: " + JSON.stringify(value));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const stringifiedAdjacent = mod.stringifyAdjacent({ value: "prefix123" });
|
|
368
|
+
if (
|
|
369
|
+
stringifiedAdjacent.success !== true ||
|
|
370
|
+
JSON.parse(stringifiedAdjacent.data).value !== "prefix123"
|
|
371
|
+
) {
|
|
372
|
+
throw new Error("validated stringify rejected an existentially valid split");
|
|
373
|
+
}
|
|
374
|
+
const invalidStringifiedAdjacent = mod.stringifyAdjacent({ value: "prefix9" });
|
|
375
|
+
if (
|
|
376
|
+
invalidStringifiedAdjacent.success !== false ||
|
|
377
|
+
invalidStringifiedAdjacent.errors.every((error) => error.expected.includes("Minimum<10>") === false)
|
|
378
|
+
) {
|
|
379
|
+
throw new Error("validated stringify did not preserve the ambiguous placeholder tag diagnostic");
|
|
380
|
+
}
|
|
381
|
+
const adjacentSchema = JSON.stringify(mod.schemaAdjacent);
|
|
382
|
+
if (adjacentSchema.includes("Minimum<10>")) {
|
|
383
|
+
throw new Error("template interpolation tags must remain intentionally absent from JSON Schema");
|
|
384
|
+
}
|
|
322
385
|
`
|
|
@@ -34,7 +34,9 @@ func TestTemplateLiteralTypeTagsTransform(t *testing.T) {
|
|
|
34
34
|
if code != 0 {
|
|
35
35
|
t.Fatalf("template literal tags transform failed: code=%d stderr=\n%s", code, errText)
|
|
36
36
|
}
|
|
37
|
-
if !strings.Contains(out, "
|
|
37
|
+
if !strings.Contains(out, `require("typia/lib/internal/_stringLength")`) ||
|
|
38
|
+
!strings.Contains(out, "._stringLength(input) <= 30") ||
|
|
39
|
+
!strings.Contains(out, "RegExp(/^prefix(.*)postfix$/)") {
|
|
38
40
|
t.Fatalf("emitted checker should combine the template pattern with its tags:\n%s", out)
|
|
39
41
|
}
|
|
40
42
|
templateLiteralTypeTagsRunRuntimeCases(t, project, out)
|