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
|
@@ -207,8 +207,8 @@ var metadataCommentTagFactory_PARSER = map[string]metadataCommentTagFactory_pars
|
|
|
207
207
|
Value string
|
|
208
208
|
}{Report: props.Report, Value: props.Value, Unsigned: true})
|
|
209
209
|
return metadataCommentTagFactory_TagRecord{"array": {
|
|
210
|
-
{Name: "MinItems<" + props.Value + ">", Target: "array", Kind: "minItems", Value: value, Validate: props.Value + " <= $input.length", Exclusive:
|
|
211
|
-
{Name: "MaxItems<" + props.Value + ">", Target: "array", Kind: "maxItems", Value: value, Validate: "$input.length <= " + props.Value, Exclusive:
|
|
210
|
+
{Name: "MinItems<" + props.Value + ">", Target: "array", Kind: "minItems", Value: value, Validate: props.Value + " <= $input.length", Exclusive: metadataCommentTagFactory_exclusive("minItems"), Schema: map[string]any{"minItems": value}},
|
|
211
|
+
{Name: "MaxItems<" + props.Value + ">", Target: "array", Kind: "maxItems", Value: value, Validate: "$input.length <= " + props.Value, Exclusive: metadataCommentTagFactory_exclusive("maxItems"), Schema: map[string]any{"maxItems": value}},
|
|
212
212
|
}}
|
|
213
213
|
},
|
|
214
214
|
"minItems": func(props struct {
|
|
@@ -220,7 +220,7 @@ var metadataCommentTagFactory_PARSER = map[string]metadataCommentTagFactory_pars
|
|
|
220
220
|
Unsigned bool
|
|
221
221
|
Value string
|
|
222
222
|
}{Report: props.Report, Value: props.Value, Unsigned: true})
|
|
223
|
-
return metadataCommentTagFactory_TagRecord{"array": {{Name: "MinItems<" + props.Value + ">", Target: "array", Kind: "minItems", Value: value, Validate: props.Value + " <= $input.length", Exclusive:
|
|
223
|
+
return metadataCommentTagFactory_TagRecord{"array": {{Name: "MinItems<" + props.Value + ">", Target: "array", Kind: "minItems", Value: value, Validate: props.Value + " <= $input.length", Exclusive: metadataCommentTagFactory_exclusive("minItems"), Schema: map[string]any{"minItems": value}}}}
|
|
224
224
|
},
|
|
225
225
|
"maxItems": func(props struct {
|
|
226
226
|
Report func(msg string) any
|
|
@@ -231,60 +231,60 @@ var metadataCommentTagFactory_PARSER = map[string]metadataCommentTagFactory_pars
|
|
|
231
231
|
Unsigned bool
|
|
232
232
|
Value string
|
|
233
233
|
}{Report: props.Report, Value: props.Value, Unsigned: true})
|
|
234
|
-
return metadataCommentTagFactory_TagRecord{"array": {{Name: "MaxItems<" + props.Value + ">", Target: "array", Kind: "maxItems", Value: value, Validate: "$input.length <= " + props.Value, Exclusive:
|
|
234
|
+
return metadataCommentTagFactory_TagRecord{"array": {{Name: "MaxItems<" + props.Value + ">", Target: "array", Kind: "maxItems", Value: value, Validate: "$input.length <= " + props.Value, Exclusive: metadataCommentTagFactory_exclusive("maxItems"), Schema: map[string]any{"maxItems": value}}}}
|
|
235
235
|
},
|
|
236
236
|
"uniqueItems": func(props struct {
|
|
237
237
|
Report func(msg string) any
|
|
238
238
|
Value string
|
|
239
239
|
}) metadataCommentTagFactory_TagRecord {
|
|
240
|
-
return metadataCommentTagFactory_TagRecord{"array": {{Name: "UniqueItems", Target: "array", Kind: "uniqueItems", Value: true, Validate: "$
|
|
240
|
+
return metadataCommentTagFactory_TagRecord{"array": {{Name: "UniqueItems", Target: "array", Kind: "uniqueItems", Value: true, Validate: "$importInternal(\"isUniqueItems\")($input)", Exclusive: metadataCommentTagFactory_exclusive("uniqueItems"), Schema: map[string]any{"uniqueItems": true}}}}
|
|
241
241
|
},
|
|
242
242
|
"type": metadataCommentTagFactory_parse_type,
|
|
243
243
|
"minimum": func(props struct {
|
|
244
244
|
Report func(msg string) any
|
|
245
245
|
Value string
|
|
246
246
|
}) metadataCommentTagFactory_TagRecord {
|
|
247
|
-
return metadataCommentTagFactory_numeric(props, "Minimum", "minimum", props.Value+" <= $input", props.Value+" <= $input"
|
|
247
|
+
return metadataCommentTagFactory_numeric(props, "Minimum", "minimum", props.Value+" <= $input", props.Value+" <= $input")
|
|
248
248
|
},
|
|
249
249
|
"maximum": func(props struct {
|
|
250
250
|
Report func(msg string) any
|
|
251
251
|
Value string
|
|
252
252
|
}) metadataCommentTagFactory_TagRecord {
|
|
253
|
-
return metadataCommentTagFactory_numeric(props, "Maximum", "maximum", "$input <= "+props.Value, "$input <= "+props.Value
|
|
253
|
+
return metadataCommentTagFactory_numeric(props, "Maximum", "maximum", "$input <= "+props.Value, "$input <= "+props.Value)
|
|
254
254
|
},
|
|
255
255
|
"exclusiveMinimum": func(props struct {
|
|
256
256
|
Report func(msg string) any
|
|
257
257
|
Value string
|
|
258
258
|
}) metadataCommentTagFactory_TagRecord {
|
|
259
|
-
return metadataCommentTagFactory_numeric(props, "ExclusiveMinimum", "exclusiveMinimum", props.Value+" < $input", props.Value+" < $input"
|
|
259
|
+
return metadataCommentTagFactory_numeric(props, "ExclusiveMinimum", "exclusiveMinimum", props.Value+" < $input", props.Value+" < $input")
|
|
260
260
|
},
|
|
261
261
|
"exclusiveMaximum": func(props struct {
|
|
262
262
|
Report func(msg string) any
|
|
263
263
|
Value string
|
|
264
264
|
}) metadataCommentTagFactory_TagRecord {
|
|
265
|
-
return metadataCommentTagFactory_numeric(props, "ExclusiveMaximum", "exclusiveMaximum", "$input < "+props.Value, "$input < "+props.Value
|
|
265
|
+
return metadataCommentTagFactory_numeric(props, "ExclusiveMaximum", "exclusiveMaximum", "$input < "+props.Value, "$input < "+props.Value)
|
|
266
266
|
},
|
|
267
267
|
"multipleOf": func(props struct {
|
|
268
268
|
Report func(msg string) any
|
|
269
269
|
Value string
|
|
270
270
|
}) metadataCommentTagFactory_TagRecord {
|
|
271
|
-
return metadataCommentTagFactory_numeric(props, "MultipleOf", "multipleOf", "$input
|
|
271
|
+
return metadataCommentTagFactory_numeric(props, "MultipleOf", "multipleOf", "$importInternal(\"_isMultipleOf\")($input, "+props.Value+")", "$input % "+props.Value+"n === 0n")
|
|
272
272
|
},
|
|
273
273
|
"format": func(props struct {
|
|
274
274
|
Report func(msg string) any
|
|
275
275
|
Value string
|
|
276
276
|
}) metadataCommentTagFactory_TagRecord {
|
|
277
|
-
|
|
277
|
+
name, validate, ok := formatCheatSheet_resolve(props.Value)
|
|
278
278
|
if ok == false {
|
|
279
279
|
return metadataCommentTagFactory_TagRecord{}
|
|
280
280
|
}
|
|
281
|
-
return metadataCommentTagFactory_TagRecord{"string": {{Name: "Format<" + strconv.Quote(
|
|
281
|
+
return metadataCommentTagFactory_TagRecord{"string": {{Name: "Format<" + strconv.Quote(name) + ">", Target: "string", Kind: "format", Value: name, Validate: validate, Exclusive: metadataCommentTagFactory_exclusive("format"), Schema: map[string]any{"format": name}}}}
|
|
282
282
|
},
|
|
283
283
|
"pattern": func(props struct {
|
|
284
284
|
Report func(msg string) any
|
|
285
285
|
Value string
|
|
286
286
|
}) metadataCommentTagFactory_TagRecord {
|
|
287
|
-
return metadataCommentTagFactory_TagRecord{"string": {{Name: "Pattern<" + strconv.Quote(props.Value) + ">", Target: "string", Kind: "pattern", Value: props.Value, Validate: "RegExp(" + strconv.Quote(props.Value) + ").test($input)", Exclusive:
|
|
287
|
+
return metadataCommentTagFactory_TagRecord{"string": {{Name: "Pattern<" + strconv.Quote(props.Value) + ">", Target: "string", Kind: "pattern", Value: props.Value, Validate: "RegExp(" + strconv.Quote(props.Value) + ").test($input)", Exclusive: metadataCommentTagFactory_exclusive("pattern"), Schema: map[string]any{"pattern": props.Value}}}}
|
|
288
288
|
},
|
|
289
289
|
"length": func(props struct {
|
|
290
290
|
Report func(msg string) any
|
|
@@ -292,8 +292,8 @@ var metadataCommentTagFactory_PARSER = map[string]metadataCommentTagFactory_pars
|
|
|
292
292
|
}) metadataCommentTagFactory_TagRecord {
|
|
293
293
|
value := metadataCommentTagFactory_parse_number(props)
|
|
294
294
|
return metadataCommentTagFactory_TagRecord{"string": {
|
|
295
|
-
{Name: "MinLength<" + props.Value + ">", Target: "string", Kind: "minLength", Value: value, Validate: props.Value + " <= $input
|
|
296
|
-
{Name: "MaxLength<" + props.Value + ">", Target: "string", Kind: "maxLength", Value: value, Validate: "$input
|
|
295
|
+
{Name: "MinLength<" + props.Value + ">", Target: "string", Kind: "minLength", Value: value, Validate: props.Value + " <= $importInternal(\"_stringLength\")($input)", Exclusive: metadataCommentTagFactory_exclusive("minLength"), Schema: map[string]any{"minLength": value}},
|
|
296
|
+
{Name: "MaxLength<" + props.Value + ">", Target: "string", Kind: "maxLength", Value: value, Validate: "$importInternal(\"_stringLength\")($input) <= " + props.Value, Exclusive: metadataCommentTagFactory_exclusive("maxLength"), Schema: map[string]any{"maxLength": value}},
|
|
297
297
|
}}
|
|
298
298
|
},
|
|
299
299
|
"minLength": func(props struct {
|
|
@@ -301,17 +301,58 @@ var metadataCommentTagFactory_PARSER = map[string]metadataCommentTagFactory_pars
|
|
|
301
301
|
Value string
|
|
302
302
|
}) metadataCommentTagFactory_TagRecord {
|
|
303
303
|
value := metadataCommentTagFactory_parse_number(props)
|
|
304
|
-
return metadataCommentTagFactory_TagRecord{"string": {{Name: "MinLength<" + props.Value + ">", Target: "string", Kind: "minLength", Value: value, Validate: props.Value + " <= $input
|
|
304
|
+
return metadataCommentTagFactory_TagRecord{"string": {{Name: "MinLength<" + props.Value + ">", Target: "string", Kind: "minLength", Value: value, Validate: props.Value + " <= $importInternal(\"_stringLength\")($input)", Exclusive: metadataCommentTagFactory_exclusive("minLength"), Schema: map[string]any{"minLength": value}}}}
|
|
305
305
|
},
|
|
306
306
|
"maxLength": func(props struct {
|
|
307
307
|
Report func(msg string) any
|
|
308
308
|
Value string
|
|
309
309
|
}) metadataCommentTagFactory_TagRecord {
|
|
310
310
|
value := metadataCommentTagFactory_parse_number(props)
|
|
311
|
-
return metadataCommentTagFactory_TagRecord{"string": {{Name: "MaxLength<" + props.Value + ">", Target: "string", Kind: "maxLength", Value: value, Validate: "$input
|
|
311
|
+
return metadataCommentTagFactory_TagRecord{"string": {{Name: "MaxLength<" + props.Value + ">", Target: "string", Kind: "maxLength", Value: value, Validate: "$importInternal(\"_stringLength\")($input) <= " + props.Value, Exclusive: metadataCommentTagFactory_exclusive("maxLength"), Schema: map[string]any{"maxLength": value}}}}
|
|
312
312
|
},
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
+
// metadataCommentTagFactory_EXCLUSIVE is the single authority for every JSDoc
|
|
316
|
+
// comment tag's mutual-exclusivity rule, keyed by tag kind and transcribing the
|
|
317
|
+
// `exclusive` field the matching @typia/interface tag declares
|
|
318
|
+
// (packages/interface/src/tags/*.ts). The JSDoc path and the type-tag path must
|
|
319
|
+
// enforce the same exclusivity, because MetadataTypeTagFactory.Validate reads
|
|
320
|
+
// this list for both; the type-tag path takes it straight from the declaration,
|
|
321
|
+
// so the comment path must publish the identical value. Hand-copying a separate
|
|
322
|
+
// list per parser is exactly what let `@format` (a bare `true`) and `@pattern`
|
|
323
|
+
// (`["format"]`, missing its own kind) drift from the declared
|
|
324
|
+
// `["format", "pattern"]`. Every parser now reads its list from here, so no one
|
|
325
|
+
// list can diverge on its own again. Each `[]string` names its own kind plus
|
|
326
|
+
// every cross-kind partner it may not share a property with, in the declaration
|
|
327
|
+
// order; `true` forbids only same-kind duplication.
|
|
328
|
+
var metadataCommentTagFactory_EXCLUSIVE = map[string]any{
|
|
329
|
+
"minItems": true,
|
|
330
|
+
"maxItems": true,
|
|
331
|
+
"uniqueItems": true,
|
|
332
|
+
"type": true,
|
|
333
|
+
"minimum": []string{"minimum", "exclusiveMinimum"},
|
|
334
|
+
"maximum": []string{"maximum", "exclusiveMaximum"},
|
|
335
|
+
"exclusiveMinimum": []string{"exclusiveMinimum", "minimum"},
|
|
336
|
+
"exclusiveMaximum": []string{"exclusiveMaximum", "maximum"},
|
|
337
|
+
"multipleOf": true,
|
|
338
|
+
"format": []string{"format", "pattern"},
|
|
339
|
+
"pattern": []string{"format", "pattern"},
|
|
340
|
+
"minLength": true,
|
|
341
|
+
"maxLength": true,
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// metadataCommentTagFactory_exclusive returns the declared exclusivity rule for
|
|
345
|
+
// a tag kind. It panics on an unknown kind so a newly added comment tag that
|
|
346
|
+
// forgets its rule fails loudly here rather than silently emitting a tag with a
|
|
347
|
+
// nil `Exclusive` that the validator would never check.
|
|
348
|
+
func metadataCommentTagFactory_exclusive(kind string) any {
|
|
349
|
+
value, ok := metadataCommentTagFactory_EXCLUSIVE[kind]
|
|
350
|
+
if ok == false {
|
|
351
|
+
panic("no exclusive rule for comment tag kind: " + kind)
|
|
352
|
+
}
|
|
353
|
+
return value
|
|
354
|
+
}
|
|
355
|
+
|
|
315
356
|
func metadataCommentTagFactory_parse_type(props struct {
|
|
316
357
|
Report func(msg string) any
|
|
317
358
|
Value string
|
|
@@ -342,11 +383,15 @@ func metadataCommentTagFactory_parse_type(props struct {
|
|
|
342
383
|
} else if value == "uint32" {
|
|
343
384
|
validate = "Math.floor($input) === $input && 0 <= $input && $input <= 4294967295"
|
|
344
385
|
} else if value == "int64" {
|
|
345
|
-
|
|
386
|
+
// Delegate to the runtime helper instead of restating the bound. The 64-bit
|
|
387
|
+
// maxima are not representable as JavaScript numbers, so an inline literal
|
|
388
|
+
// here silently rounds up and admits an out-of-range value; the helper owns
|
|
389
|
+
// the one correct spelling and documents why it is exclusive.
|
|
390
|
+
validate = "$importInternal(\"isTypeInt64\")($input)"
|
|
346
391
|
} else if value == "uint64" {
|
|
347
|
-
validate = "
|
|
392
|
+
validate = "$importInternal(\"isTypeUint64\")($input)"
|
|
348
393
|
} else if value == "float" {
|
|
349
|
-
validate = "-
|
|
394
|
+
validate = "-3.4028235e38 <= $input && $input <= 3.4028235e38"
|
|
350
395
|
}
|
|
351
396
|
var numberSchema any
|
|
352
397
|
if value == "int8" || value == "int16" || value == "int32" || value == "int64" {
|
|
@@ -359,11 +404,19 @@ func metadataCommentTagFactory_parse_type(props struct {
|
|
|
359
404
|
bigintSchema = map[string]any{"minimum": 0}
|
|
360
405
|
}
|
|
361
406
|
record := metadataCommentTagFactory_TagRecord{
|
|
362
|
-
"number": {{Name: "Type<" + strconv.Quote(value) + ">", Target: "number", Kind: "type", Value: value, Validate: validate, Exclusive:
|
|
407
|
+
"number": {{Name: "Type<" + strconv.Quote(value) + ">", Target: "number", Kind: "type", Value: value, Validate: validate, Exclusive: metadataCommentTagFactory_exclusive("type"), Schema: numberSchema}},
|
|
363
408
|
}
|
|
364
409
|
if value == "int64" || value == "uint64" {
|
|
410
|
+
// The bigint form used to emit `true` for int64 and a lower bound only for
|
|
411
|
+
// uint64, so `bigint & Type<"int64">` -- the spelling the documentation
|
|
412
|
+
// recommends -- certified any magnitude at all. Both now delegate to the
|
|
413
|
+
// helper that holds the exact inclusive bound a bigint can represent.
|
|
414
|
+
bigintValidate := "$importInternal(\"isTypeUint64Bigint\")($input)"
|
|
415
|
+
if value == "int64" {
|
|
416
|
+
bigintValidate = "$importInternal(\"isTypeInt64Bigint\")($input)"
|
|
417
|
+
}
|
|
365
418
|
record["bigint"] = []schemametadata.IMetadataTypeTag{
|
|
366
|
-
{Name: "Type<" + strconv.Quote(value) + ">", Target: "bigint", Kind: "type", Value: value, Validate:
|
|
419
|
+
{Name: "Type<" + strconv.Quote(value) + ">", Target: "bigint", Kind: "type", Value: value, Validate: bigintValidate, Exclusive: metadataCommentTagFactory_exclusive("type"), Schema: bigintSchema},
|
|
367
420
|
}
|
|
368
421
|
}
|
|
369
422
|
return record
|
|
@@ -372,21 +425,21 @@ func metadataCommentTagFactory_parse_type(props struct {
|
|
|
372
425
|
func metadataCommentTagFactory_numeric(props struct {
|
|
373
426
|
Report func(msg string) any
|
|
374
427
|
Value string
|
|
375
|
-
}, name string, kind string, numberValidate string, bigintValidate string
|
|
428
|
+
}, name string, kind string, numberValidate string, bigintValidate string) metadataCommentTagFactory_TagRecord {
|
|
376
429
|
number := metadataCommentTagFactory_parse_number(props)
|
|
377
430
|
integer := metadataCommentTagFactory_parse_integer(struct {
|
|
378
431
|
Report func(msg string) any
|
|
379
432
|
Unsigned bool
|
|
380
433
|
Value string
|
|
381
|
-
}{Report:
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
bigint = int64(*integer)
|
|
385
|
-
}
|
|
386
|
-
return metadataCommentTagFactory_TagRecord{
|
|
434
|
+
}{Report: func(string) any { return nil }, Value: props.Value, Unsigned: false})
|
|
435
|
+
exclusive := metadataCommentTagFactory_exclusive(kind)
|
|
436
|
+
record := metadataCommentTagFactory_TagRecord{
|
|
387
437
|
"number": {{Name: name + "<" + props.Value + ">", Target: "number", Kind: kind, Value: number, Validate: numberValidate, Exclusive: exclusive, Schema: map[string]any{kind: number}}},
|
|
388
|
-
"bigint": {{Name: name + "<" + props.Value + "n>", Target: "bigint", Kind: kind, Value: bigint, Validate: bigintValidate, Exclusive: exclusive, Schema: map[string]any{kind: number}}},
|
|
389
438
|
}
|
|
439
|
+
if integer != nil {
|
|
440
|
+
record["bigint"] = []schemametadata.IMetadataTypeTag{{Name: name + "<" + props.Value + "n>", Target: "bigint", Kind: kind, Value: int64(*integer), Validate: bigintValidate, Exclusive: exclusive, Schema: map[string]any{kind: number}}}
|
|
441
|
+
}
|
|
442
|
+
return record
|
|
390
443
|
}
|
|
391
444
|
|
|
392
445
|
func metadataCommentTagFactory_parse_number(props struct {
|
|
@@ -426,16 +479,6 @@ func metadataCommentTagFactory_parse_integer(props struct {
|
|
|
426
479
|
return &value
|
|
427
480
|
}
|
|
428
481
|
|
|
429
|
-
var metadataCommentTagFactory_FORMATS = func() map[string][2]string {
|
|
430
|
-
output := map[string][2]string{}
|
|
431
|
-
for key, value := range FormatCheatSheet {
|
|
432
|
-
output[key] = [2]string{key, value}
|
|
433
|
-
}
|
|
434
|
-
output["datetime"] = [2]string{"date-time", "!isNaN(new Date($input).getTime())"}
|
|
435
|
-
output["dateTime"] = [2]string{"date-time", "!isNaN(new Date($input).getTime())"}
|
|
436
|
-
return output
|
|
437
|
-
}()
|
|
438
|
-
|
|
439
482
|
func metadataCommentTagFactory_includes(values []string, target string) bool {
|
|
440
483
|
for _, value := range values {
|
|
441
484
|
if value == target {
|
|
@@ -246,9 +246,21 @@ func (metadataTypeTagFactoryNamespace) Validate(props struct {
|
|
|
246
246
|
}{Property: nil, Message: "kind '" + tag.Kind + "' can't be duplicated"})
|
|
247
247
|
}
|
|
248
248
|
case []string:
|
|
249
|
+
// The `exclusive` list names every kind this tag may not share a property
|
|
250
|
+
// with, itself included, and it is the authoritative spec. Reject when any
|
|
251
|
+
// other tag's kind appears in the list, matching kinds against kinds.
|
|
252
|
+
//
|
|
253
|
+
// Two bugs made this inert: it compared the list of kinds against
|
|
254
|
+
// `opposite.Name` ("minimum" against "Minimum<0>"), which never matched,
|
|
255
|
+
// and it also required `opposite.Kind == tag.Kind`, which excluded the
|
|
256
|
+
// cross-kind partners the list exists to catch. Both must go, or a
|
|
257
|
+
// forbidden combination keeps compiling: `Minimum<5> & Minimum<0>` emits
|
|
258
|
+
// `{"minimum":0}` yet its validator requires 5, and `Minimum<0> &
|
|
259
|
+
// ExclusiveMinimum<5>` or `Format<"uuid"> & Pattern<...>` coexist though
|
|
260
|
+
// the declarations forbid it.
|
|
249
261
|
var some *schemametadata.IMetadataTypeTag
|
|
250
262
|
for j, opposite := range props.Tags {
|
|
251
|
-
if i != j &&
|
|
263
|
+
if i != j && metadataTypeTagFactory_includes(exclusive, opposite.Kind) {
|
|
252
264
|
copied := opposite
|
|
253
265
|
some = &copied
|
|
254
266
|
break
|
|
@@ -23,30 +23,27 @@ func (numericRangeFactoryNamespace) Number(t string, input *shimast.Expression,
|
|
|
23
23
|
case "uint64":
|
|
24
24
|
return numericRangeFactory_number_uint64(input, emit...)
|
|
25
25
|
case "float":
|
|
26
|
-
return numericRangeFactory_between("-
|
|
26
|
+
return numericRangeFactory_between("-3.4028235e38", "3.4028235e38", emit...)(input)
|
|
27
27
|
default:
|
|
28
28
|
return nativecontext.EmitFactoryOf(numericRangeFactory_factory, emit...).NewKeywordExpression(shimast.KindTrueKeyword)
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// Bigint narrows a protobuf union candidate whose atomic type is `bigint`.
|
|
33
|
+
//
|
|
34
|
+
// ProtobufFactory only ever routes "int64" and "uint64" here, so the fall-through
|
|
35
|
+
// used to be the int64 case: it returned a bare `true`, and a `bigint &
|
|
36
|
+
// Type<"int64">` candidate matched any magnitude at all. Both types are now
|
|
37
|
+
// explicit, and the default is reached only by an unknown type.
|
|
32
38
|
func (numericRangeFactoryNamespace) Bigint(t string, input *shimast.Expression, emit ...*shimprinter.EmitContext) *shimast.Node {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
nil,
|
|
41
|
-
f.NewNodeList([]*shimast.Node{ExpressionFactory.Number(0, emit...)}),
|
|
42
|
-
shimast.NodeFlagsNone,
|
|
43
|
-
),
|
|
44
|
-
nil,
|
|
45
|
-
f.NewToken(shimast.KindLessThanEqualsToken),
|
|
46
|
-
input,
|
|
47
|
-
)
|
|
39
|
+
switch t {
|
|
40
|
+
case "int64":
|
|
41
|
+
return numericRangeFactory_bigint_between("-9223372036854775808", "9223372036854775807", input, emit...)
|
|
42
|
+
case "uint64":
|
|
43
|
+
return numericRangeFactory_bigint_between("0", "18446744073709551615", input, emit...)
|
|
44
|
+
default:
|
|
45
|
+
return nativecontext.EmitFactoryOf(numericRangeFactory_factory, emit...).NewKeywordExpression(shimast.KindTrueKeyword)
|
|
48
46
|
}
|
|
49
|
-
return f.NewKeywordExpression(shimast.KindTrueKeyword)
|
|
50
47
|
}
|
|
51
48
|
|
|
52
49
|
func numericRangeFactory_number_int32(input *shimast.Expression, emit ...*shimprinter.EmitContext) *shimast.Node {
|
|
@@ -65,6 +62,8 @@ func numericRangeFactory_number_uint32(input *shimast.Expression, emit ...*shimp
|
|
|
65
62
|
)
|
|
66
63
|
}
|
|
67
64
|
|
|
65
|
+
// numericRangeFactory_number_int64 bounds a `number` candidate to the int64 range.
|
|
66
|
+
// The maximum is 2**63 - 1, the int64 upper bound.
|
|
68
67
|
func numericRangeFactory_number_int64(input *shimast.Expression, emit ...*shimprinter.EmitContext) *shimast.Node {
|
|
69
68
|
return numericRangeFactory_logical_and(
|
|
70
69
|
numericRangeFactory_integer(input, emit...),
|
|
@@ -73,6 +72,8 @@ func numericRangeFactory_number_int64(input *shimast.Expression, emit ...*shimpr
|
|
|
73
72
|
)
|
|
74
73
|
}
|
|
75
74
|
|
|
75
|
+
// numericRangeFactory_number_uint64 bounds a `number` candidate to the uint64 range.
|
|
76
|
+
// The maximum is 2**64 - 1, the uint64 upper bound.
|
|
76
77
|
func numericRangeFactory_number_uint64(input *shimast.Expression, emit ...*shimprinter.EmitContext) *shimast.Node {
|
|
77
78
|
return numericRangeFactory_logical_and(
|
|
78
79
|
numericRangeFactory_integer(input, emit...),
|
|
@@ -121,6 +122,48 @@ func numericRangeFactory_between(x string, y string, emit ...*shimprinter.EmitCo
|
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
|
|
125
|
+
// numericRangeFactory_bigint_literal emits `BigInt("<value>")`.
|
|
126
|
+
//
|
|
127
|
+
// The argument has to stay a string literal. `BigInt(9223372036854775807)` would
|
|
128
|
+
// round its number literal to 2**63 before BigInt ever parsed it -- the same
|
|
129
|
+
// rounding that broke the number path -- while the string form parses the digits
|
|
130
|
+
// exactly.
|
|
131
|
+
func numericRangeFactory_bigint_literal(value string, emit ...*shimprinter.EmitContext) *shimast.Node {
|
|
132
|
+
f := nativecontext.EmitFactoryOf(numericRangeFactory_factory, emit...)
|
|
133
|
+
return f.NewCallExpression(
|
|
134
|
+
f.NewIdentifier("BigInt"),
|
|
135
|
+
nil,
|
|
136
|
+
nil,
|
|
137
|
+
f.NewNodeList([]*shimast.Node{f.NewStringLiteral(value, shimast.TokenFlagsNone)}),
|
|
138
|
+
shimast.NodeFlagsNone,
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// numericRangeFactory_bigint_between emits `BigInt(x) <= input && input <= BigInt(y)`.
|
|
143
|
+
//
|
|
144
|
+
// Both comparisons are inclusive because a bigint represents the true 64-bit
|
|
145
|
+
// bounds exactly, unlike the number path's exclusive approximation.
|
|
146
|
+
func numericRangeFactory_bigint_between(x string, y string, input *shimast.Expression, emit ...*shimprinter.EmitContext) *shimast.Node {
|
|
147
|
+
f := nativecontext.EmitFactoryOf(numericRangeFactory_factory, emit...)
|
|
148
|
+
return numericRangeFactory_logical_and(
|
|
149
|
+
f.NewBinaryExpression(
|
|
150
|
+
nil,
|
|
151
|
+
numericRangeFactory_bigint_literal(x, emit...),
|
|
152
|
+
nil,
|
|
153
|
+
f.NewToken(shimast.KindLessThanEqualsToken),
|
|
154
|
+
input,
|
|
155
|
+
),
|
|
156
|
+
f.NewBinaryExpression(
|
|
157
|
+
nil,
|
|
158
|
+
input,
|
|
159
|
+
nil,
|
|
160
|
+
f.NewToken(shimast.KindLessThanEqualsToken),
|
|
161
|
+
numericRangeFactory_bigint_literal(y, emit...),
|
|
162
|
+
),
|
|
163
|
+
emit...,
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
124
167
|
func numericRangeFactory_logical_and(x *shimast.Expression, y *shimast.Expression, emit ...*shimprinter.EmitContext) *shimast.Node {
|
|
125
168
|
return nativecontext.EmitFactoryOf(numericRangeFactory_factory, emit...).NewBinaryExpression(
|
|
126
169
|
nil,
|
|
@@ -44,9 +44,16 @@ func (protobufFactoryNamespace) Metadata(props ProtobufFactory_IProps) *schemame
|
|
|
44
44
|
Errors: protobufFactory_errors(result.Errors),
|
|
45
45
|
}))
|
|
46
46
|
}
|
|
47
|
+
protobufFactory_emplaceObjects(props.Components.Objects())
|
|
47
48
|
return result.Data
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
func protobufFactory_emplaceObjects(objects []*schemametadata.MetadataObjectType) {
|
|
52
|
+
for _, object := range objects {
|
|
53
|
+
ProtobufFactory.EmplaceObject(object)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
50
57
|
func (protobufFactoryNamespace) EmplaceObject(object *schemametadata.MetadataObjectType) {
|
|
51
58
|
for _, property := range object.Properties {
|
|
52
59
|
protobufFactory_emplaceProperty(property)
|
|
@@ -335,10 +342,6 @@ func protobufFactory_validate() MetadataFactory_Validator {
|
|
|
335
342
|
}
|
|
336
343
|
visited[obj.Type] = true
|
|
337
344
|
protobufFactory_validateObject(obj.Type, &errors)
|
|
338
|
-
func() {
|
|
339
|
-
defer func() { _ = recover() }()
|
|
340
|
-
ProtobufFactory.EmplaceObject(obj.Type)
|
|
341
|
-
}()
|
|
342
345
|
}
|
|
343
346
|
noSupport := func(msg string) { insert("does not support " + msg) }
|
|
344
347
|
if props.Metadata.Any {
|
|
@@ -499,8 +499,14 @@ export let inner!: Outer.Inner;
|
|
|
499
499
|
Report: typeTagReport,
|
|
500
500
|
Type: "string",
|
|
501
501
|
Tags: []schemametadata.IMetadataTypeTag{
|
|
502
|
-
|
|
503
|
-
|
|
502
|
+
// Format and Pattern as they are actually declared: both list the
|
|
503
|
+
// kinds `["format", "pattern"]`, so intersecting them on one property
|
|
504
|
+
// is forbidden. The cross-kind conflict fires on the opposite's kind,
|
|
505
|
+
// not its name, and without a same-kind guard. The previous fixture
|
|
506
|
+
// named the opposite in `exclusive` by tag name, the only shape the
|
|
507
|
+
// doubly-broken check could fire on and no real declaration produces.
|
|
508
|
+
{Target: "string", Kind: "format", Name: "Format<\"uuid\">", Exclusive: []string{"format", "pattern"}},
|
|
509
|
+
{Target: "string", Kind: "pattern", Name: "Pattern<\"^x$\">", Exclusive: []string{"format", "pattern"}},
|
|
504
510
|
},
|
|
505
511
|
})
|
|
506
512
|
invalidExclusiveReports := []string{}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
package factories
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
|
|
6
|
+
schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// TestFormatAliasResolvesToCheatSheet verifies every `@format` alias generates the cheat sheet validator it emits.
|
|
10
|
+
//
|
|
11
|
+
// An alias that carries its own validator string is not an alias; it is a
|
|
12
|
+
// second implementation sharing a name, free to drift from the format it
|
|
13
|
+
// claims. `@format datetime` did exactly that: it emitted `format: "date-time"`
|
|
14
|
+
// while validating with `!isNaN(new Date($input).getTime())`, so it accepted
|
|
15
|
+
// February 30th and rejected the RFC 3339 leap second the cheat sheet handles.
|
|
16
|
+
// This pins the alias to the cheat sheet as the single owner of the validator.
|
|
17
|
+
//
|
|
18
|
+
// 1. Parse each alias spelling of the `date-time` format as a JSDoc comment tag.
|
|
19
|
+
// 2. Require the emitted format name, schema, and tag name to be the canonical one.
|
|
20
|
+
// 3. Require the generated validator to be the cheat sheet entry verbatim.
|
|
21
|
+
func TestFormatAliasResolvesToCheatSheet(t *testing.T) {
|
|
22
|
+
canonical := "date-time"
|
|
23
|
+
expected, ok := FormatCheatSheet[canonical]
|
|
24
|
+
if ok == false {
|
|
25
|
+
t.Fatalf("the cheat sheet must own the %s format", canonical)
|
|
26
|
+
}
|
|
27
|
+
for _, alias := range []string{"datetime", "dateTime", "date-time"} {
|
|
28
|
+
record := metadataCommentTagFactory_parse(struct {
|
|
29
|
+
Report func(msg string) any
|
|
30
|
+
Tag schemametadata.IJsDocTagInfo
|
|
31
|
+
}{
|
|
32
|
+
Report: func(msg string) any { return nil },
|
|
33
|
+
Tag: schemametadata.IJsDocTagInfo{
|
|
34
|
+
Name: "format",
|
|
35
|
+
Text: []schemametadata.IJsDocTagInfo_IText{{Text: alias}},
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
tags := record["string"]
|
|
39
|
+
if len(tags) != 1 {
|
|
40
|
+
t.Fatalf("@format %s should generate exactly one string tag, generated %d", alias, len(tags))
|
|
41
|
+
}
|
|
42
|
+
tag := tags[0]
|
|
43
|
+
if tag.Value != canonical {
|
|
44
|
+
t.Fatalf("@format %s should carry the canonical %s value, carried %v", alias, canonical, tag.Value)
|
|
45
|
+
}
|
|
46
|
+
if tag.Name != "Format<\""+canonical+"\">" {
|
|
47
|
+
t.Fatalf("@format %s should name the canonical format tag, named %s", alias, tag.Name)
|
|
48
|
+
}
|
|
49
|
+
schema, ok := tag.Schema.(map[string]any)
|
|
50
|
+
if ok == false || schema["format"] != canonical {
|
|
51
|
+
t.Fatalf("@format %s should emit format %s, emitted %v", alias, canonical, tag.Schema)
|
|
52
|
+
}
|
|
53
|
+
if tag.Validate != expected {
|
|
54
|
+
t.Fatalf("@format %s must validate as the cheat sheet %s entry does, validated with %s", alias, canonical, tag.Validate)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
package factories
|
|
2
|
+
|
|
3
|
+
import "testing"
|
|
4
|
+
|
|
5
|
+
// TestFormatAliasTableTargetsTheCheatSheet verifies every declared `@format` alias names a real cheat sheet format.
|
|
6
|
+
//
|
|
7
|
+
// The original defect was structural, not arithmetic: the aliases were appended
|
|
8
|
+
// after a loop that copied the cheat sheet, so they were invisible to any sweep
|
|
9
|
+
// that enumerated the cheat sheet's entries and could drift from the format they
|
|
10
|
+
// emit without contradicting anything. The alias table now holds only cheat
|
|
11
|
+
// sheet keys, and this pins that shape — an alias pointing nowhere, or shadowing
|
|
12
|
+
// a real format with a different meaning, fails here rather than at a user's
|
|
13
|
+
// call site.
|
|
14
|
+
//
|
|
15
|
+
// 1. Require every alias to resolve to an existing cheat sheet entry.
|
|
16
|
+
// 2. Require no alias to shadow a cheat sheet key of its own name.
|
|
17
|
+
// 3. Require resolution to reject a format the cheat sheet does not own.
|
|
18
|
+
func TestFormatAliasTableTargetsTheCheatSheet(t *testing.T) {
|
|
19
|
+
if len(formatCheatSheet_ALIASES) == 0 {
|
|
20
|
+
t.Fatal("the alias table should stay the enumerable owner of every alternative spelling")
|
|
21
|
+
}
|
|
22
|
+
for alias, canonical := range formatCheatSheet_ALIASES {
|
|
23
|
+
expected, ok := FormatCheatSheet[canonical]
|
|
24
|
+
if ok == false {
|
|
25
|
+
t.Fatalf("the alias %s targets %s, which the cheat sheet does not own", alias, canonical)
|
|
26
|
+
}
|
|
27
|
+
if _, ok := FormatCheatSheet[alias]; ok {
|
|
28
|
+
t.Fatalf("the alias %s shadows a cheat sheet format of the same name", alias)
|
|
29
|
+
}
|
|
30
|
+
name, validate, ok := formatCheatSheet_resolve(alias)
|
|
31
|
+
if ok == false || name != canonical || validate != expected {
|
|
32
|
+
t.Fatalf("the alias %s must resolve to the cheat sheet %s entry, resolved to %s", alias, canonical, name)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
for name, validate := range FormatCheatSheet {
|
|
36
|
+
resolvedName, resolvedValidate, ok := formatCheatSheet_resolve(name)
|
|
37
|
+
if ok == false || resolvedName != name || resolvedValidate != validate {
|
|
38
|
+
t.Fatalf("the canonical format %s must resolve to itself", name)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if _, _, ok := formatCheatSheet_resolve("not-a-format"); ok {
|
|
42
|
+
t.Fatal("an unsupported format must not resolve")
|
|
43
|
+
}
|
|
44
|
+
}
|