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.
Files changed (515) hide show
  1. package/README.md +3 -0
  2. package/lib/_virtual/_rolldown/runtime.mjs +1 -5
  3. package/lib/executable/FileSystemIdentity.d.ts +21 -0
  4. package/lib/executable/FileSystemIdentity.js +183 -0
  5. package/lib/executable/FileSystemIdentity.js.map +1 -0
  6. package/lib/executable/FileSystemIdentity.mjs +129 -0
  7. package/lib/executable/FileSystemIdentity.mjs.map +1 -0
  8. package/lib/executable/TypiaGenerateWizard.js +264 -104
  9. package/lib/executable/TypiaGenerateWizard.js.map +1 -1
  10. package/lib/executable/TypiaGenerateWizard.mjs +233 -93
  11. package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
  12. package/lib/functional.d.ts +15 -12
  13. package/lib/functional.js.map +1 -1
  14. package/lib/functional.mjs.map +1 -1
  15. package/lib/internal/_ProtobufReader.d.ts +17 -0
  16. package/lib/internal/_ProtobufReader.js +117 -45
  17. package/lib/internal/_ProtobufReader.js.map +1 -1
  18. package/lib/internal/_ProtobufReader.mjs +108 -39
  19. package/lib/internal/_ProtobufReader.mjs.map +1 -1
  20. package/lib/internal/_createStandardSchema.js +18 -1
  21. package/lib/internal/_createStandardSchema.js.map +1 -1
  22. package/lib/internal/_createStandardSchema.mjs +12 -1
  23. package/lib/internal/_createStandardSchema.mjs.map +1 -1
  24. package/lib/internal/_decimal.d.ts +14 -0
  25. package/lib/internal/_decimal.js +61 -0
  26. package/lib/internal/_decimal.js.map +1 -0
  27. package/lib/internal/_decimal.mjs +49 -0
  28. package/lib/internal/_decimal.mjs.map +1 -0
  29. package/lib/internal/_httpQueryParseURLSearchParams.js +23 -2
  30. package/lib/internal/_httpQueryParseURLSearchParams.js.map +1 -1
  31. package/lib/internal/_httpQueryParseURLSearchParams.mjs +20 -2
  32. package/lib/internal/_httpQueryParseURLSearchParams.mjs.map +1 -1
  33. package/lib/internal/_isFormatByte.js +2 -5
  34. package/lib/internal/_isFormatByte.js.map +1 -1
  35. package/lib/internal/_isFormatByte.mjs +2 -5
  36. package/lib/internal/_isFormatByte.mjs.map +1 -1
  37. package/lib/internal/_isFormatDate.js +15 -2
  38. package/lib/internal/_isFormatDate.js.map +1 -1
  39. package/lib/internal/_isFormatDate.mjs +22 -2
  40. package/lib/internal/_isFormatDate.mjs.map +1 -1
  41. package/lib/internal/_isFormatDateTime.js +21 -2
  42. package/lib/internal/_isFormatDateTime.js.map +1 -1
  43. package/lib/internal/_isFormatDateTime.mjs +13 -2
  44. package/lib/internal/_isFormatDateTime.mjs.map +1 -1
  45. package/lib/internal/_isFormatIri.js +3 -2
  46. package/lib/internal/_isFormatIri.js.map +1 -1
  47. package/lib/internal/_isFormatIri.mjs +3 -2
  48. package/lib/internal/_isFormatIri.mjs.map +1 -1
  49. package/lib/internal/_isFormatIriReference.js +10 -2
  50. package/lib/internal/_isFormatIriReference.js.map +1 -1
  51. package/lib/internal/_isFormatIriReference.mjs +9 -2
  52. package/lib/internal/_isFormatIriReference.mjs.map +1 -1
  53. package/lib/internal/_isFormatUriReference.js +1 -1
  54. package/lib/internal/_isFormatUriReference.js.map +1 -1
  55. package/lib/internal/_isFormatUriReference.mjs +1 -1
  56. package/lib/internal/_isFormatUriReference.mjs.map +1 -1
  57. package/lib/internal/_isMultipleOf.d.ts +1 -0
  58. package/lib/internal/_isMultipleOf.js +13 -0
  59. package/lib/internal/_isMultipleOf.js.map +1 -0
  60. package/lib/internal/_isMultipleOf.mjs +12 -0
  61. package/lib/internal/_isMultipleOf.mjs.map +1 -0
  62. package/lib/internal/_isTypeFloat.js +1 -1
  63. package/lib/internal/_isTypeFloat.js.map +1 -1
  64. package/lib/internal/_isTypeFloat.mjs +1 -1
  65. package/lib/internal/_isTypeFloat.mjs.map +1 -1
  66. package/lib/internal/_isTypeInt64.js +1 -0
  67. package/lib/internal/_isTypeInt64.js.map +1 -1
  68. package/lib/internal/_isTypeInt64.mjs.map +1 -1
  69. package/lib/internal/_isTypeInt64Bigint.d.ts +1 -0
  70. package/lib/internal/_isTypeInt64Bigint.js +15 -0
  71. package/lib/internal/_isTypeInt64Bigint.js.map +1 -0
  72. package/lib/internal/_isTypeInt64Bigint.mjs +8 -0
  73. package/lib/internal/_isTypeInt64Bigint.mjs.map +1 -0
  74. package/lib/internal/_isTypeUint64.js +1 -0
  75. package/lib/internal/_isTypeUint64.js.map +1 -1
  76. package/lib/internal/_isTypeUint64.mjs.map +1 -1
  77. package/lib/internal/_isTypeUint64Bigint.d.ts +1 -0
  78. package/lib/internal/_isTypeUint64Bigint.js +10 -0
  79. package/lib/internal/_isTypeUint64Bigint.js.map +1 -0
  80. package/lib/internal/_isTypeUint64Bigint.mjs +8 -0
  81. package/lib/internal/_isTypeUint64Bigint.mjs.map +1 -0
  82. package/lib/internal/_isUniqueItems.js +96 -109
  83. package/lib/internal/_isUniqueItems.js.map +1 -1
  84. package/lib/internal/_isUniqueItems.mjs +62 -50
  85. package/lib/internal/_isUniqueItems.mjs.map +1 -1
  86. package/lib/internal/_notationAny.js +8 -1
  87. package/lib/internal/_notationAny.js.map +1 -1
  88. package/lib/internal/_notationAny.mjs +7 -1
  89. package/lib/internal/_notationAny.mjs.map +1 -1
  90. package/lib/internal/_notationAssign.d.ts +1 -0
  91. package/lib/internal/_notationAssign.js +18 -0
  92. package/lib/internal/_notationAssign.js.map +1 -0
  93. package/lib/internal/_notationAssign.mjs +17 -0
  94. package/lib/internal/_notationAssign.mjs.map +1 -0
  95. package/lib/internal/_notationCamel.js +30 -9
  96. package/lib/internal/_notationCamel.js.map +1 -1
  97. package/lib/internal/_notationCamel.mjs +13 -5
  98. package/lib/internal/_notationCamel.mjs.map +1 -1
  99. package/lib/internal/_notationKebab.d.ts +1 -0
  100. package/lib/internal/_notationKebab.js +15 -0
  101. package/lib/internal/_notationKebab.js.map +1 -0
  102. package/lib/internal/_notationKebab.mjs +15 -0
  103. package/lib/internal/_notationKebab.mjs.map +1 -0
  104. package/lib/internal/_notationKeyCollision.d.ts +1 -0
  105. package/lib/internal/_notationKeyCollision.js +8 -0
  106. package/lib/internal/_notationKeyCollision.js.map +1 -0
  107. package/lib/internal/_notationKeyCollision.mjs +8 -0
  108. package/lib/internal/_notationKeyCollision.mjs.map +1 -0
  109. package/lib/internal/_notationPascal.js +20 -5
  110. package/lib/internal/_notationPascal.js.map +1 -1
  111. package/lib/internal/_notationPascal.mjs +10 -5
  112. package/lib/internal/_notationPascal.mjs.map +1 -1
  113. package/lib/internal/_notationSnake.js +25 -22
  114. package/lib/internal/_notationSnake.js.map +1 -1
  115. package/lib/internal/_notationSnake.mjs +11 -11
  116. package/lib/internal/_notationSnake.mjs.map +1 -1
  117. package/lib/internal/_plainCloneAny.js +174 -38
  118. package/lib/internal/_plainCloneAny.js.map +1 -1
  119. package/lib/internal/_plainCloneAny.mjs +126 -22
  120. package/lib/internal/_plainCloneAny.mjs.map +1 -1
  121. package/lib/internal/_randomArray.d.ts +1 -1
  122. package/lib/internal/_randomArray.js +11 -4
  123. package/lib/internal/_randomArray.js.map +1 -1
  124. package/lib/internal/_randomArray.mjs +9 -3
  125. package/lib/internal/_randomArray.mjs.map +1 -1
  126. package/lib/internal/_randomFormatByte.d.ts +2 -1
  127. package/lib/internal/_randomFormatByte.js +2 -1
  128. package/lib/internal/_randomFormatByte.js.map +1 -1
  129. package/lib/internal/_randomFormatByte.mjs +2 -1
  130. package/lib/internal/_randomFormatByte.mjs.map +1 -1
  131. package/lib/internal/_randomFormatDate.d.ts +2 -0
  132. package/lib/internal/_randomFormatDate.js +3 -2
  133. package/lib/internal/_randomFormatDate.js.map +1 -1
  134. package/lib/internal/_randomFormatDate.mjs +3 -2
  135. package/lib/internal/_randomFormatDate.mjs.map +1 -1
  136. package/lib/internal/_randomFormatDatetime.d.ts +2 -0
  137. package/lib/internal/_randomFormatDatetime.js +3 -2
  138. package/lib/internal/_randomFormatDatetime.js.map +1 -1
  139. package/lib/internal/_randomFormatDatetime.mjs +3 -2
  140. package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
  141. package/lib/internal/_randomFormatDuration.d.ts +2 -1
  142. package/lib/internal/_randomFormatDuration.js +3 -2
  143. package/lib/internal/_randomFormatDuration.js.map +1 -1
  144. package/lib/internal/_randomFormatDuration.mjs +3 -2
  145. package/lib/internal/_randomFormatDuration.mjs.map +1 -1
  146. package/lib/internal/_randomFormatEmail.d.ts +2 -1
  147. package/lib/internal/_randomFormatEmail.js +8 -1
  148. package/lib/internal/_randomFormatEmail.js.map +1 -1
  149. package/lib/internal/_randomFormatEmail.mjs +5 -1
  150. package/lib/internal/_randomFormatEmail.mjs.map +1 -1
  151. package/lib/internal/_randomFormatHostname.d.ts +8 -1
  152. package/lib/internal/_randomFormatHostname.js +45 -2
  153. package/lib/internal/_randomFormatHostname.js.map +1 -1
  154. package/lib/internal/_randomFormatHostname.mjs +38 -2
  155. package/lib/internal/_randomFormatHostname.mjs.map +1 -1
  156. package/lib/internal/_randomFormatIdnEmail.d.ts +2 -1
  157. package/lib/internal/_randomFormatIdnEmail.js +16 -2
  158. package/lib/internal/_randomFormatIdnEmail.js.map +1 -1
  159. package/lib/internal/_randomFormatIdnEmail.mjs +11 -2
  160. package/lib/internal/_randomFormatIdnEmail.mjs.map +1 -1
  161. package/lib/internal/_randomFormatIdnHostname.d.ts +2 -1
  162. package/lib/internal/_randomFormatIdnHostname.js +26 -1
  163. package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
  164. package/lib/internal/_randomFormatIdnHostname.mjs +25 -2
  165. package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
  166. package/lib/internal/_randomFormatIpv4.d.ts +2 -1
  167. package/lib/internal/_randomFormatIpv4.js +2 -1
  168. package/lib/internal/_randomFormatIpv4.js.map +1 -1
  169. package/lib/internal/_randomFormatIpv4.mjs +2 -1
  170. package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
  171. package/lib/internal/_randomFormatIpv6.d.ts +2 -1
  172. package/lib/internal/_randomFormatIpv6.js +2 -1
  173. package/lib/internal/_randomFormatIpv6.js.map +1 -1
  174. package/lib/internal/_randomFormatIpv6.mjs +2 -1
  175. package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
  176. package/lib/internal/_randomFormatIri.d.ts +2 -1
  177. package/lib/internal/_randomFormatIri.js +1 -1
  178. package/lib/internal/_randomFormatIri.js.map +1 -1
  179. package/lib/internal/_randomFormatIri.mjs +1 -1
  180. package/lib/internal/_randomFormatIri.mjs.map +1 -1
  181. package/lib/internal/_randomFormatIriReference.d.ts +2 -1
  182. package/lib/internal/_randomFormatIriReference.js +1 -1
  183. package/lib/internal/_randomFormatIriReference.js.map +1 -1
  184. package/lib/internal/_randomFormatIriReference.mjs +1 -1
  185. package/lib/internal/_randomFormatIriReference.mjs.map +1 -1
  186. package/lib/internal/_randomFormatJsonPointer.d.ts +2 -1
  187. package/lib/internal/_randomFormatJsonPointer.js +8 -1
  188. package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
  189. package/lib/internal/_randomFormatJsonPointer.mjs +5 -1
  190. package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
  191. package/lib/internal/_randomFormatPassword.d.ts +2 -1
  192. package/lib/internal/_randomFormatPassword.js +7 -5
  193. package/lib/internal/_randomFormatPassword.js.map +1 -1
  194. package/lib/internal/_randomFormatPassword.mjs +5 -1
  195. package/lib/internal/_randomFormatPassword.mjs.map +1 -1
  196. package/lib/internal/_randomFormatRegex.d.ts +2 -1
  197. package/lib/internal/_randomFormatRegex.js +2 -1
  198. package/lib/internal/_randomFormatRegex.js.map +1 -1
  199. package/lib/internal/_randomFormatRegex.mjs +2 -1
  200. package/lib/internal/_randomFormatRegex.mjs.map +1 -1
  201. package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
  202. package/lib/internal/_randomFormatRelativeJsonPointer.js +3 -2
  203. package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
  204. package/lib/internal/_randomFormatRelativeJsonPointer.mjs +3 -2
  205. package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
  206. package/lib/internal/_randomFormatTime.d.ts +2 -1
  207. package/lib/internal/_randomFormatTime.js +3 -2
  208. package/lib/internal/_randomFormatTime.js.map +1 -1
  209. package/lib/internal/_randomFormatTime.mjs +3 -2
  210. package/lib/internal/_randomFormatTime.mjs.map +1 -1
  211. package/lib/internal/_randomFormatUri.d.ts +2 -1
  212. package/lib/internal/_randomFormatUri.js +1 -1
  213. package/lib/internal/_randomFormatUri.js.map +1 -1
  214. package/lib/internal/_randomFormatUri.mjs +1 -1
  215. package/lib/internal/_randomFormatUri.mjs.map +1 -1
  216. package/lib/internal/_randomFormatUriReference.d.ts +2 -1
  217. package/lib/internal/_randomFormatUriReference.js +1 -1
  218. package/lib/internal/_randomFormatUriReference.js.map +1 -1
  219. package/lib/internal/_randomFormatUriReference.mjs +1 -1
  220. package/lib/internal/_randomFormatUriReference.mjs.map +1 -1
  221. package/lib/internal/_randomFormatUriTemplate.d.ts +2 -1
  222. package/lib/internal/_randomFormatUriTemplate.js +1 -1
  223. package/lib/internal/_randomFormatUriTemplate.js.map +1 -1
  224. package/lib/internal/_randomFormatUriTemplate.mjs +1 -1
  225. package/lib/internal/_randomFormatUriTemplate.mjs.map +1 -1
  226. package/lib/internal/_randomFormatUrl.d.ts +2 -1
  227. package/lib/internal/_randomFormatUrl.js +21 -1
  228. package/lib/internal/_randomFormatUrl.js.map +1 -1
  229. package/lib/internal/_randomFormatUrl.mjs +18 -1
  230. package/lib/internal/_randomFormatUrl.mjs.map +1 -1
  231. package/lib/internal/_randomFormatUuid.d.ts +2 -1
  232. package/lib/internal/_randomFormatUuid.js +3 -2
  233. package/lib/internal/_randomFormatUuid.js.map +1 -1
  234. package/lib/internal/_randomFormatUuid.mjs +3 -2
  235. package/lib/internal/_randomFormatUuid.mjs.map +1 -1
  236. package/lib/internal/_randomInteger.js +59 -28
  237. package/lib/internal/_randomInteger.js.map +1 -1
  238. package/lib/internal/_randomInteger.mjs +56 -16
  239. package/lib/internal/_randomInteger.mjs.map +1 -1
  240. package/lib/internal/_randomMultiple.d.ts +8 -0
  241. package/lib/internal/_randomMultiple.js +168 -0
  242. package/lib/internal/_randomMultiple.js.map +1 -0
  243. package/lib/internal/_randomMultiple.mjs +158 -0
  244. package/lib/internal/_randomMultiple.mjs.map +1 -0
  245. package/lib/internal/_randomNumber.js +42 -42
  246. package/lib/internal/_randomNumber.js.map +1 -1
  247. package/lib/internal/_randomNumber.mjs +41 -27
  248. package/lib/internal/_randomNumber.mjs.map +1 -1
  249. package/lib/internal/_randomPattern.d.ts +2 -1
  250. package/lib/internal/_randomPattern.js +19 -4
  251. package/lib/internal/_randomPattern.js.map +1 -1
  252. package/lib/internal/_randomPattern.mjs +10 -4
  253. package/lib/internal/_randomPattern.mjs.map +1 -1
  254. package/lib/internal/_randomStringLength.d.ts +33 -0
  255. package/lib/internal/_randomStringLength.js +48 -0
  256. package/lib/internal/_randomStringLength.js.map +1 -0
  257. package/lib/internal/_randomStringLength.mjs +44 -0
  258. package/lib/internal/_randomStringLength.mjs.map +1 -0
  259. package/lib/internal/_stringLength.d.ts +1 -0
  260. package/lib/internal/_stringLength.js +11 -0
  261. package/lib/internal/_stringLength.js.map +1 -0
  262. package/lib/internal/_stringLength.mjs +10 -0
  263. package/lib/internal/_stringLength.mjs.map +1 -0
  264. package/lib/internal/_validateReport.js +4 -1
  265. package/lib/internal/_validateReport.js.map +1 -1
  266. package/lib/internal/_validateReport.mjs +2 -1
  267. package/lib/internal/_validateReport.mjs.map +1 -1
  268. package/lib/internal/private/__notationRename.d.ts +14 -0
  269. package/lib/internal/private/__notationRename.js +25 -0
  270. package/lib/internal/private/__notationRename.js.map +1 -0
  271. package/lib/internal/private/__notationRename.mjs +24 -0
  272. package/lib/internal/private/__notationRename.mjs.map +1 -0
  273. package/lib/json.d.ts +2 -2
  274. package/lib/json.mjs.map +1 -1
  275. package/lib/module.d.ts +2 -2
  276. package/lib/module.js.map +1 -1
  277. package/lib/module.mjs.map +1 -1
  278. package/lib/notations.d.ts +20 -4
  279. package/lib/notations.js.map +1 -1
  280. package/lib/notations.mjs.map +1 -1
  281. package/native/adapter/plugin_options.go +117 -0
  282. package/native/adapter/plugin_options_payload_matrix_test.go +181 -0
  283. package/native/cmd/ttsc-typia/any_array_type_tags_transform_test.go +63 -9
  284. package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +152 -0
  285. package/native/cmd/ttsc-typia/build.go +81 -64
  286. package/native/cmd/ttsc-typia/build_no_emit_preserves_analysis_options_test.go +67 -0
  287. package/native/cmd/ttsc-typia/build_no_emit_transform_diagnostics_test.go +138 -0
  288. package/native/cmd/ttsc-typia/build_plugin_options_come_from_payload_test.go +48 -0
  289. package/native/cmd/ttsc-typia/build_transactional_emit_success_test.go +81 -0
  290. package/native/cmd/ttsc-typia/build_transform_failure_atomicity_test.go +138 -0
  291. package/native/cmd/ttsc-typia/command_routes_and_diagnostics_coverage_test.go +3 -1
  292. package/native/cmd/ttsc-typia/compare_less_nan_transform_test.go +98 -0
  293. package/native/cmd/ttsc-typia/compare_native_object_overmatch_transform_test.go +161 -0
  294. package/native/cmd/ttsc-typia/compare_nondiscriminable_union_transform_test.go +343 -0
  295. package/native/cmd/ttsc-typia/compare_union_discrimination_transform_test.go +289 -0
  296. package/native/cmd/ttsc-typia/escaped_property_key_path_transform_test.go +193 -0
  297. package/native/cmd/ttsc-typia/finite_option_number_leaf_transform_test.go +240 -0
  298. package/native/cmd/ttsc-typia/functional_promised_type_transform_test.go +220 -0
  299. package/native/cmd/ttsc-typia/functional_receiver_transform_test.go +232 -0
  300. package/native/cmd/ttsc-typia/is_object_function_member_transform_test.go +205 -0
  301. package/native/cmd/ttsc-typia/json_application_alias_function_validation_transform_test.go +151 -0
  302. package/native/cmd/ttsc-typia/json_is_stringify_finite_number_transform_test.go +198 -0
  303. package/native/cmd/ttsc-typia/json_stringify_special_key_transform_test.go +238 -0
  304. package/native/cmd/ttsc-typia/main_wasm.go +21 -2
  305. package/native/cmd/ttsc-typia/native_collection_identity_is_transform_test.go +234 -0
  306. package/native/cmd/ttsc-typia/native_generic_name_guard_is_transform_test.go +194 -0
  307. package/native/cmd/ttsc-typia/native_name_collision_is_transform_test.go +204 -0
  308. package/native/cmd/ttsc-typia/non_trailing_rest_tuple_transform_test.go +23 -11
  309. package/native/cmd/ttsc-typia/notation_dynamic_keys_transform_test.go +286 -0
  310. package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +1 -1
  311. package/native/cmd/ttsc-typia/notation_literal_collision_transform_test.go +164 -0
  312. package/native/cmd/ttsc-typia/notation_pascal_case_transform_test.go +230 -0
  313. package/native/cmd/ttsc-typia/notation_unicode_key_transform_test.go +309 -0
  314. package/native/cmd/ttsc-typia/pattern_line_terminator_escape_transform_test.go +224 -0
  315. package/native/cmd/ttsc-typia/plain_prune_union_object_overmatch_transform_test.go +219 -0
  316. package/native/cmd/ttsc-typia/plugin_options_payload_helpers_test.go +181 -0
  317. package/native/cmd/ttsc-typia/private_field_filter_is_transform_test.go +278 -0
  318. package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +73 -27
  319. package/native/cmd/ttsc-typia/project_dependencies_barrel_reexport_transform_test.go +120 -0
  320. package/native/cmd/ttsc-typia/project_dependencies_collapsed_alias_transform_test.go +134 -0
  321. package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +135 -0
  322. package/native/cmd/ttsc-typia/project_dependencies_default_barrel_transform_test.go +114 -0
  323. package/native/cmd/ttsc-typia/project_dependencies_empty_heritage_transform_test.go +100 -0
  324. package/native/cmd/ttsc-typia/project_dependencies_envelope_transform_test.go +148 -0
  325. package/native/cmd/ttsc-typia/project_dependencies_index_signature_alias_transform_test.go +139 -0
  326. package/native/cmd/ttsc-typia/project_dependencies_local_reexport_transform_test.go +122 -0
  327. package/native/cmd/ttsc-typia/project_dependencies_signature_alias_transform_test.go +125 -0
  328. package/native/cmd/ttsc-typia/project_dependencies_star_barrel_transform_test.go +112 -0
  329. package/native/cmd/ttsc-typia/project_reference_graph_envelope_transform_test.go +190 -0
  330. package/native/cmd/ttsc-typia/protobuf_is_encode_finite_number_transform_test.go +98 -0
  331. package/native/cmd/ttsc-typia/protobuf_sequence_field_numbers_transform_test.go +52 -22
  332. package/native/cmd/ttsc-typia/symbol_key_member_filter_transform_test.go +279 -0
  333. package/native/cmd/ttsc-typia/template_interpolation_type_tags_transform_test.go +86 -23
  334. package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
  335. package/native/cmd/ttsc-typia/transform.go +228 -39
  336. package/native/cmd/ttsc-typia/{transform_declaration_source_produces_no_js_test.go → transform_declaration_source_produces_no_javascript_test.go} +10 -2
  337. package/native/cmd/ttsc-typia/transform_fixtures_emit_coverage_test.go +21 -4
  338. package/native/cmd/ttsc-typia/transform_helpers_test.go +159 -1
  339. package/native/cmd/ttsc-typia/transform_plugin_options_come_from_payload_test.go +43 -0
  340. package/native/cmd/ttsc-typia/transform_single_file_failure_atomicity_test.go +114 -0
  341. package/native/cmd/ttsc-typia/transform_single_file_failure_writes_no_stdout_test.go +43 -0
  342. package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go +81 -0
  343. package/native/cmd/ttsc-typia/transform_single_file_js_empty_emit_reports_no_output_test.go +100 -0
  344. package/native/cmd/ttsc-typia/transform_single_file_js_locates_output_across_layouts_test.go +160 -0
  345. package/native/cmd/ttsc-typia/transform_single_file_success_publishes_artifact_test.go +54 -0
  346. package/native/cmd/ttsc-typia/transform_wasm_host_argv_reports_diagnostics_test.go +39 -0
  347. package/native/cmd/ttsc-typia/tuple_optional_compare_clone_transform_test.go +227 -0
  348. package/native/core/factories/FormatCheatSheet.go +40 -7
  349. package/native/core/factories/IdentifierFactory.go +131 -4
  350. package/native/core/factories/MetadataCommentTagFactory.go +83 -40
  351. package/native/core/factories/MetadataTypeTagFactory.go +13 -1
  352. package/native/core/factories/NumericRangeFactory.go +60 -17
  353. package/native/core/factories/ProtobufFactory.go +7 -4
  354. package/native/core/factories/factory_utility_coverage_test.go +8 -2
  355. package/native/core/factories/format_alias_resolves_to_cheat_sheet_test.go +57 -0
  356. package/native/core/factories/format_alias_table_targets_the_cheat_sheet_test.go +44 -0
  357. package/native/core/factories/identifier_factory_postfix_escapes_every_key_test.go +147 -0
  358. package/native/core/factories/identifier_factory_postfix_survives_every_code_point_test.go +86 -0
  359. package/native/core/factories/internal/metadata/MetadataHelper.go +60 -6
  360. package/native/core/factories/internal/metadata/emplace_metadata_object.go +116 -8
  361. package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
  362. package/native/core/factories/internal/metadata/iterate_metadata_function.go +4 -11
  363. package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +8 -6
  364. package/native/core/factories/internal/metadata/iterate_metadata_map.go +9 -0
  365. package/native/core/factories/internal/metadata/iterate_metadata_native.go +27 -2
  366. package/native/core/factories/internal/metadata/iterate_metadata_set.go +9 -0
  367. package/native/core/factories/internal/metadata/type_arguments_precondition_test.go +70 -0
  368. package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +39 -0
  369. package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go +84 -0
  370. package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go +60 -0
  371. package/native/core/factories/metadata_type_tag_factory_declarations_test.go +86 -0
  372. package/native/core/factories/metadata_type_tag_factory_keeps_bool_form_exclusivity_test.go +38 -0
  373. package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go +65 -0
  374. package/native/core/factories/metadata_type_tag_factory_rejects_duplicated_array_form_tags_test.go +41 -0
  375. package/native/core/factories/numeric_range_factory_enforces_64bit_bounds_test.go +69 -0
  376. package/native/core/factories/protobuf_recovery_ownership_test.go +64 -0
  377. package/native/core/programmers/IsProgrammer.go +15 -1
  378. package/native/core/programmers/RandomProgrammer.go +51 -14
  379. package/native/core/programmers/compare/CompareEqualProgrammer.go +393 -5
  380. package/native/core/programmers/compare/CompareLessProgrammer.go +4 -2
  381. package/native/core/programmers/functional/FunctionalAssertFunctionProgrammer.go +4 -6
  382. package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +5 -13
  383. package/native/core/programmers/functional/FunctionalAssertReturnProgrammer.go +6 -14
  384. package/native/core/programmers/functional/FunctionalIsFunctionProgrammer.go +4 -6
  385. package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +49 -14
  386. package/native/core/programmers/functional/FunctionalIsReturnProgrammer.go +5 -13
  387. package/native/core/programmers/functional/FunctionalValidateFunctionProgrammer.go +4 -6
  388. package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +5 -13
  389. package/native/core/programmers/functional/FunctionalValidateReturnProgrammer.go +5 -13
  390. package/native/core/programmers/functional/internal/FunctionalGeneralProgrammer.go +4 -17
  391. package/native/core/programmers/helpers/CloneJoiner.go +32 -0
  392. package/native/core/programmers/helpers/NotationJoiner.go +86 -28
  393. package/native/core/programmers/helpers/StringifyJoinder.go +32 -1
  394. package/native/core/programmers/helpers/UnionExplorer.go +203 -61
  395. package/native/core/programmers/helpers/joiner_branch_coverage_test.go +5 -3
  396. package/native/core/programmers/helpers/union_explorer_coverage_test.go +1 -1
  397. package/native/core/programmers/internal/CheckerProgrammer.go +100 -48
  398. package/native/core/programmers/iterate/check_template.go +344 -32
  399. package/native/core/programmers/iterate/json_schema_discriminator.go +36 -10
  400. package/native/core/programmers/iterate/json_schema_discriminator_declaration_syntax_test.go +205 -0
  401. package/native/core/programmers/iterate/openapi_v3_downgrader.go +641 -0
  402. package/native/core/programmers/iterate/openapi_v3_downgrader_boolean_default_test.go +95 -0
  403. package/native/core/programmers/iterate/openapi_v3_downgrader_test.go +123 -0
  404. package/native/core/programmers/iterate/template_interpolation_tags_test.go +40 -8
  405. package/native/core/programmers/iterate/template_runtime_pattern.go +52 -7
  406. package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
  407. package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
  408. package/native/core/programmers/llm/LlmApplicationProgrammer.go +12 -10
  409. package/native/core/programmers/llm/LlmSchemaProgrammer.go +23 -6
  410. package/native/core/programmers/llm/llm_reference_codec_test.go +24 -0
  411. package/native/core/programmers/notations/NotationGeneralProgrammer.go +183 -67
  412. package/native/core/programmers/notations/notation_general_helpers_test.go +1 -3
  413. package/native/core/programmers/notations/notation_general_programmer_pascal_multiword_test.go +72 -0
  414. package/native/core/programmers/notations/notation_general_programmer_underscore_boundary_test.go +68 -0
  415. package/native/core/programmers/plain/PlainClassifyProgrammer.go +23 -15
  416. package/native/core/programmers/plain/PlainCloneProgrammer.go +20 -7
  417. package/native/core/programmers/plain/PlainPruneProgrammer.go +19 -5
  418. package/native/core/programmers/plain/plain_tuple_seed_recovery_ownership_test.go +25 -0
  419. package/native/core/programmers/protobuf/ProtobufDecodeProgrammer.go +37 -28
  420. package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +40 -21
  421. package/native/core/programmers/protobuf/protobuf_programmer_helper_coverage_test.go +26 -0
  422. package/native/core/programmers/random_programmer_length_argument_test.go +53 -0
  423. package/native/core/schemas/metadata/MetadataCollection.go +270 -20
  424. package/native/core/schemas/metadata/MetadataDependency.go +388 -0
  425. package/native/core/schemas/metadata/MetadataObjectType.go +17 -4
  426. package/native/core/schemas/metadata/metadata_collection_generic_argument_dot_test.go +122 -0
  427. package/native/core/schemas/metadata/metadata_collection_name_allocation_test.go +147 -0
  428. package/native/core/schemas/metadata/metadata_collection_openapi_name_cascade_test.go +55 -0
  429. package/native/core/schemas/metadata/metadata_collection_openapi_name_test.go +68 -0
  430. package/native/core/utils/PatternUtil.go +13 -0
  431. package/native/core/utils/PromiseTypeFactory.go +59 -0
  432. package/native/core/utils/ProtobufNameEncoder.go +8 -0
  433. package/native/core/utils/promise_type_factory_semantics_test.go +118 -0
  434. package/native/go.mod +9 -1
  435. package/native/transform/CallExpressionTransformer.go +12 -0
  436. package/native/transform/features/json/JsonApplicationTransformer.go +1 -1
  437. package/native/transform/features/json/JsonSchemaTransformer.go +1 -1
  438. package/native/transform/features/json/JsonSchemasTransformer.go +5 -4
  439. package/package.json +16 -4
  440. package/src/executable/FileSystemIdentity.ts +189 -0
  441. package/src/executable/TypiaGenerateWizard.ts +377 -110
  442. package/src/functional.ts +30 -60
  443. package/src/internal/_ProtobufReader.ts +129 -43
  444. package/src/internal/_createStandardSchema.ts +15 -1
  445. package/src/internal/_decimal.ts +69 -0
  446. package/src/internal/_httpQueryParseURLSearchParams.ts +24 -2
  447. package/src/internal/_isFormatByte.ts +2 -5
  448. package/src/internal/_isFormatDate.ts +15 -2
  449. package/src/internal/_isFormatDateTime.ts +28 -2
  450. package/src/internal/_isFormatIri.ts +5 -2
  451. package/src/internal/_isFormatIriReference.ts +11 -3
  452. package/src/internal/_isFormatUriReference.ts +1 -1
  453. package/src/internal/_isMultipleOf.ts +8 -0
  454. package/src/internal/_isTypeFloat.ts +1 -1
  455. package/src/internal/_isTypeInt64.ts +1 -0
  456. package/src/internal/_isTypeInt64Bigint.ts +12 -0
  457. package/src/internal/_isTypeUint64.ts +1 -0
  458. package/src/internal/_isTypeUint64Bigint.ts +7 -0
  459. package/src/internal/_isUniqueItems.ts +134 -132
  460. package/src/internal/_notationAny.ts +9 -4
  461. package/src/internal/_notationAssign.ts +20 -0
  462. package/src/internal/_notationCamel.ts +31 -10
  463. package/src/internal/_notationKebab.ts +11 -0
  464. package/src/internal/_notationKeyCollision.ts +9 -0
  465. package/src/internal/_notationPascal.ts +19 -6
  466. package/src/internal/_notationSnake.ts +24 -21
  467. package/src/internal/_plainCloneAny.ts +208 -33
  468. package/src/internal/_randomArray.ts +13 -4
  469. package/src/internal/_randomFormatByte.ts +4 -1
  470. package/src/internal/_randomFormatDate.ts +17 -12
  471. package/src/internal/_randomFormatDatetime.ts +15 -10
  472. package/src/internal/_randomFormatDuration.ts +16 -14
  473. package/src/internal/_randomFormatEmail.ts +8 -2
  474. package/src/internal/_randomFormatHostname.ts +48 -1
  475. package/src/internal/_randomFormatIdnEmail.ts +18 -2
  476. package/src/internal/_randomFormatIdnHostname.ts +34 -2
  477. package/src/internal/_randomFormatIpv4.ts +3 -2
  478. package/src/internal/_randomFormatIpv6.ts +3 -2
  479. package/src/internal/_randomFormatIri.ts +3 -1
  480. package/src/internal/_randomFormatIriReference.ts +3 -1
  481. package/src/internal/_randomFormatJsonPointer.ts +8 -2
  482. package/src/internal/_randomFormatPassword.ts +11 -6
  483. package/src/internal/_randomFormatRegex.ts +4 -1
  484. package/src/internal/_randomFormatRelativeJsonPointer.ts +13 -6
  485. package/src/internal/_randomFormatTime.ts +13 -10
  486. package/src/internal/_randomFormatUri.ts +3 -1
  487. package/src/internal/_randomFormatUriReference.ts +3 -1
  488. package/src/internal/_randomFormatUriTemplate.ts +3 -1
  489. package/src/internal/_randomFormatUrl.ts +25 -2
  490. package/src/internal/_randomFormatUuid.ts +10 -6
  491. package/src/internal/_randomInteger.ts +87 -40
  492. package/src/internal/_randomMultiple.ts +245 -0
  493. package/src/internal/_randomNumber.ts +72 -55
  494. package/src/internal/_randomPattern.ts +26 -4
  495. package/src/internal/_randomStringLength.ts +72 -0
  496. package/src/internal/_stringLength.ts +5 -0
  497. package/src/internal/_validateReport.ts +5 -1
  498. package/src/internal/private/__notationRename.ts +24 -0
  499. package/src/json.ts +2 -2
  500. package/src/module.ts +4 -6
  501. package/src/notations.ts +20 -4
  502. package/lib/internal/private/__notationCapitalize.d.ts +0 -1
  503. package/lib/internal/private/__notationCapitalize.js +0 -6
  504. package/lib/internal/private/__notationCapitalize.js.map +0 -1
  505. package/lib/internal/private/__notationCapitalize.mjs +0 -6
  506. package/lib/internal/private/__notationCapitalize.mjs.map +0 -1
  507. package/lib/internal/private/__notationUnsnake.d.ts +0 -4
  508. package/lib/internal/private/__notationUnsnake.js +0 -26
  509. package/lib/internal/private/__notationUnsnake.js.map +0 -1
  510. package/lib/internal/private/__notationUnsnake.mjs +0 -15
  511. package/lib/internal/private/__notationUnsnake.mjs.map +0 -1
  512. package/native/cmd/ttsc-typia/plugin_options_missing_config_test.go +0 -26
  513. package/native/cmd/ttsc-typia/plugin_options_undefined_false_test.go +0 -36
  514. package/src/internal/private/__notationCapitalize.ts +0 -2
  515. package/src/internal/private/__notationUnsnake.ts +0 -24
@@ -0,0 +1,289 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "testing"
8
+ )
9
+
10
+ // TestCompareUnionDiscriminationTransform pins compare.equals over a union of
11
+ // object types (issue #2214).
12
+ //
13
+ // CompareEqualProgrammer.schema assembled an object union as a flat OR of member
14
+ // comparators (`_eo0(x,y) || _eo1(x,y) || ...`) with no discrimination. A wrong
15
+ // member's comparator matched spuriously: its constant discriminant passed via
16
+ // the always-prepended `x.type === y.type` branch (both agree, even when neither
17
+ // is that member) and its absent payload keys compared `undefined === undefined`.
18
+ // So `equals({type:"a",x:1}, {type:"a",x:2})` was `true` for two distinct
19
+ // references. Every other object-union programmer (is/clone/classify/prune/json/
20
+ // notations/protobuf) discriminates so a member comparator only runs for the
21
+ // member both values actually are. `equals` must do the same: decide which member
22
+ // each operand is, return false if they differ, and compare within the one shared
23
+ // member — and must agree with `is` on membership.
24
+ //
25
+ // All fixtures compare DISTINCT references (fresh object literals) so the
26
+ // `x === y` identity fast path never hides the flaw.
27
+ //
28
+ // 1. Transform is + compare.createEquals over discriminated, non-discriminated
29
+ // disjoint, narrower-masks-wider, 3-member, array/union-member, and nested
30
+ // object unions, plus primitive/array-union and non-union controls.
31
+ // 2. Require distinct-but-different pairs to compare not-equal, distinct-but-
32
+ // identical pairs to compare equal, and equals to imply is on both operands.
33
+ // 3. Require primitive/array unions and non-union objects to be unchanged.
34
+ func TestCompareUnionDiscriminationTransform(t *testing.T) {
35
+ project := compareUnionDiscriminationProject(t)
36
+ out, errText, code := ttscTypiaTestCapture(func() int {
37
+ return runTransform([]string{
38
+ "--cwd", project,
39
+ "--tsconfig", "tsconfig.json",
40
+ "--file", "src/main.ts",
41
+ "--output", "js",
42
+ })
43
+ })
44
+ if code != 0 {
45
+ t.Fatalf("compare union discrimination transform failed: code=%d stderr=\n%s", code, errText)
46
+ }
47
+ compareUnionDiscriminationRunRuntimeCases(t, project, out)
48
+ }
49
+
50
+ func compareUnionDiscriminationProject(t *testing.T) string {
51
+ t.Helper()
52
+ root := ttscTypiaTestRepoRoot(t)
53
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
54
+ if err := os.MkdirAll(base, 0o755); err != nil {
55
+ t.Fatalf("mkdir temp base: %v", err)
56
+ }
57
+ dir, err := os.MkdirTemp(base, "compare-union-disc-")
58
+ if err != nil {
59
+ t.Fatalf("create temp fixture: %v", err)
60
+ }
61
+ t.Cleanup(func() {
62
+ _ = os.RemoveAll(dir)
63
+ })
64
+ src := filepath.Join(dir, "src")
65
+ if err := os.MkdirAll(src, 0o755); err != nil {
66
+ t.Fatalf("mkdir fixture src: %v", err)
67
+ }
68
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareUnionDiscriminationTSConfig), 0o644); err != nil {
69
+ t.Fatalf("write tsconfig: %v", err)
70
+ }
71
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareUnionDiscriminationSource), 0o644); err != nil {
72
+ t.Fatalf("write source: %v", err)
73
+ }
74
+ return dir
75
+ }
76
+
77
+ func compareUnionDiscriminationRunRuntimeCases(t *testing.T, project string, js string) {
78
+ t.Helper()
79
+ node, err := exec.LookPath("node")
80
+ if err != nil {
81
+ t.Skip("node executable not found")
82
+ }
83
+ runtimeDir := filepath.Join(project, "runtime")
84
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
85
+ t.Fatalf("mkdir runtime dir: %v", err)
86
+ }
87
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
88
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
89
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
90
+ t.Fatalf("write runtime module: %v", err)
91
+ }
92
+ runner := filepath.Join(runtimeDir, "run.cjs")
93
+ if err := os.WriteFile(runner, []byte(compareUnionDiscriminationRuntimeRunner), 0o644); err != nil {
94
+ t.Fatalf("write runtime runner: %v", err)
95
+ }
96
+ cmd := exec.Command(node, runner)
97
+ cmd.Dir = runtimeDir
98
+ output, err := cmd.CombinedOutput()
99
+ if err != nil {
100
+ t.Fatalf("compare union discrimination runtime cases failed: %v\n%s", err, output)
101
+ }
102
+ }
103
+
104
+ const compareUnionDiscriminationTSConfig = `{
105
+ "compilerOptions": {
106
+ "target": "ES2022",
107
+ "module": "commonjs",
108
+ "moduleResolution": "bundler",
109
+ "ignoreDeprecations": "6.0",
110
+ "types": ["*"],
111
+ "esModuleInterop": true,
112
+ "strict": true,
113
+ "skipLibCheck": true
114
+ },
115
+ "include": ["src"]
116
+ }
117
+ `
118
+
119
+ const compareUnionDiscriminationSource = `import typia from "typia";
120
+
121
+ // 1. discriminated union
122
+ type Disc = { type: "a"; x: number } | { type: "b"; y: string };
123
+ export const isDisc = typia.createIs<Disc>();
124
+ export const eqDisc = typia.compare.createEquals<Disc>();
125
+
126
+ // 2. non-discriminated union with disjoint keys
127
+ type Disjoint = { x: number } | { y: string };
128
+ export const isDisjoint = typia.createIs<Disjoint>();
129
+ export const eqDisjoint = typia.compare.createEquals<Disjoint>();
130
+
131
+ // 3. narrower-masks-wider
132
+ type Mask = { a: number } | { a: number; b: string };
133
+ export const isMask = typia.createIs<Mask>();
134
+ export const eqMask = typia.compare.createEquals<Mask>();
135
+
136
+ // 4. three-member discriminated union
137
+ type Three =
138
+ | { type: "a"; x: number }
139
+ | { type: "b"; y: string }
140
+ | { type: "c"; z: boolean };
141
+ export const isThree = typia.createIs<Three>();
142
+ export const eqThree = typia.compare.createEquals<Three>();
143
+
144
+ // 5. a member whose payload is itself an array / element union
145
+ type ArrMember =
146
+ | { kind: "multi"; values: (number | string)[] }
147
+ | { kind: "single"; value: number };
148
+ export const isArrMember = typia.createIs<ArrMember>();
149
+ export const eqArrMember = typia.compare.createEquals<ArrMember>();
150
+
151
+ // 6. nested object-union property
152
+ type Nested = { wrap: { type: "a"; x: number } | { type: "b"; y: string } };
153
+ export const isNested = typia.createIs<Nested>();
154
+ export const eqNested = typia.compare.createEquals<Nested>();
155
+
156
+ // 7. recursive discriminated union (exercises _vctx capture through the IIFE)
157
+ type Tree =
158
+ | { type: "leaf"; value: number }
159
+ | { type: "node"; left: Tree; right: Tree };
160
+ export const isTree = typia.createIs<Tree>();
161
+ export const eqTree = typia.compare.createEquals<Tree>();
162
+
163
+ // 8. native alongside a discriminated object union (notNatives guard + ladder)
164
+ type WithNative = Date | { kind: "a"; x: number } | { kind: "b"; y: string };
165
+ export const eqWithNative = typia.compare.createEquals<WithNative>();
166
+
167
+ // control: a native unioned with a SINGLE object keeps the flat guarded branch
168
+ type DateOrStamp = Date | { timestamp: number };
169
+ export const eqDateStamp = typia.compare.createEquals<DateOrStamp>();
170
+
171
+ // controls: primitive union, array union, non-union object
172
+ export const eqPrim = typia.compare.createEquals<string | number>();
173
+ export const eqArrUnion = typia.compare.createEquals<number[] | string[]>();
174
+ export const eqObj = typia.compare.createEquals<{ a: number; b: string }>();
175
+ `
176
+
177
+ const compareUnionDiscriminationRuntimeRunner = `const mod = require("./main.cjs");
178
+
179
+ let failures = 0;
180
+ const expect = (label, actual, expected) => {
181
+ if (actual !== expected) {
182
+ console.log("FAIL " + label + ": expected " + expected + ", got " + actual);
183
+ failures++;
184
+ }
185
+ };
186
+
187
+ // --- 1. discriminated union: {type:"a";x} | {type:"b";y} ---
188
+ expect("disc a distinct-different", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
189
+ expect("disc b distinct-different", mod.eqDisc({ type: "b", y: "p" }, { type: "b", y: "q" }), false);
190
+ expect("disc a distinct-identical", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 1 }), true);
191
+ expect("disc b distinct-identical", mod.eqDisc({ type: "b", y: "p" }, { type: "b", y: "p" }), true);
192
+ expect("disc cross-arm a vs b", mod.eqDisc({ type: "a", x: 1 }, { type: "b", y: "p" }), false);
193
+
194
+ // --- 2. non-discriminated disjoint keys: {x} | {y} ---
195
+ expect("disjoint x distinct-different", mod.eqDisjoint({ x: 1 }, { x: 2 }), false);
196
+ expect("disjoint y distinct-different", mod.eqDisjoint({ y: "p" }, { y: "q" }), false);
197
+ expect("disjoint x distinct-identical", mod.eqDisjoint({ x: 1 }, { x: 1 }), true);
198
+ expect("disjoint cross-arm x vs y", mod.eqDisjoint({ x: 1 }, { y: "p" }), false);
199
+
200
+ // --- 3. narrower-masks-wider: {a} | {a,b} ---
201
+ expect("mask wider distinct-different", mod.eqMask({ a: 1, b: "x" }, { a: 1, b: "y" }), false);
202
+ expect("mask narrower distinct-identical", mod.eqMask({ a: 1 }, { a: 1 }), true);
203
+ expect("mask wider distinct-identical", mod.eqMask({ a: 1, b: "x" }, { a: 1, b: "x" }), true);
204
+ expect("mask narrower vs wider", mod.eqMask({ a: 1 }, { a: 1, b: "x" }), false);
205
+
206
+ // --- 4. three-member ---
207
+ expect("three a-different", mod.eqThree({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
208
+ expect("three b-different", mod.eqThree({ type: "b", y: "p" }, { type: "b", y: "q" }), false);
209
+ expect("three c-different", mod.eqThree({ type: "c", z: true }, { type: "c", z: false }), false);
210
+ expect("three c-identical", mod.eqThree({ type: "c", z: true }, { type: "c", z: true }), true);
211
+ expect("three cross a vs c", mod.eqThree({ type: "a", x: 1 }, { type: "c", z: true }), false);
212
+
213
+ // --- 5. array/element-union member ---
214
+ expect("arrmember multi different length", mod.eqArrMember({ kind: "multi", values: [1, 2] }, { kind: "multi", values: [1] }), false);
215
+ expect("arrmember multi different elem", mod.eqArrMember({ kind: "multi", values: [1, "a"] }, { kind: "multi", values: [1, "b"] }), false);
216
+ expect("arrmember multi identical", mod.eqArrMember({ kind: "multi", values: [1, "a"] }, { kind: "multi", values: [1, "a"] }), true);
217
+ expect("arrmember single different", mod.eqArrMember({ kind: "single", value: 1 }, { kind: "single", value: 2 }), false);
218
+ expect("arrmember cross multi vs single", mod.eqArrMember({ kind: "multi", values: [1] }, { kind: "single", value: 1 }), false);
219
+
220
+ // --- 6. nested object-union property ---
221
+ expect("nested inner different", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "a", x: 2 } }), false);
222
+ expect("nested inner identical", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "a", x: 1 } }), true);
223
+ expect("nested cross arm", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "b", y: "p" } }), false);
224
+
225
+ // --- controls: primitive / array unions, non-union object ---
226
+ expect("prim number-different", mod.eqPrim(1, 2), false);
227
+ expect("prim string-identical", mod.eqPrim("x", "x"), true);
228
+ expect("prim cross string vs number", mod.eqPrim("1", 1), false);
229
+ expect("arrunion number-different", mod.eqArrUnion([1, 2], [1, 3]), false);
230
+ expect("arrunion number-identical", mod.eqArrUnion([1, 2], [1, 2]), true);
231
+ expect("arrunion string-identical", mod.eqArrUnion(["a"], ["a"]), true);
232
+ expect("obj different", mod.eqObj({ a: 1, b: "x" }, { a: 1, b: "y" }), false);
233
+ expect("obj identical", mod.eqObj({ a: 1, b: "x" }, { a: 1, b: "x" }), true);
234
+
235
+ // --- recursive discriminated union (distinct references throughout) ---
236
+ const mkTree = () => ({ type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 2 } });
237
+ expect("tree identical", mod.eqTree(mkTree(), mkTree()), true);
238
+ expect("tree leaf value differs", mod.eqTree({ type: "leaf", value: 1 }, { type: "leaf", value: 2 }), false);
239
+ expect("tree deep differs", mod.eqTree(mkTree(), { type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 9 } }), false);
240
+ expect("tree leaf vs node", mod.eqTree({ type: "leaf", value: 1 }, mkTree()), false);
241
+ expect("tree shape differs", mod.eqTree({ type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 2 } }, { type: "node", left: { type: "leaf", value: 1 }, right: { type: "node", left: { type: "leaf", value: 2 }, right: { type: "leaf", value: 3 } } }), false);
242
+
243
+ // --- native alongside a discriminated object union ---
244
+ expect("withnative same date", mod.eqWithNative(new Date(0), new Date(0)), true);
245
+ expect("withnative diff date", mod.eqWithNative(new Date(0), new Date(5000)), false);
246
+ expect("withnative obj a different", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "a", x: 2 }), false);
247
+ expect("withnative obj a identical", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "a", x: 1 }), true);
248
+ expect("withnative date vs obj", mod.eqWithNative(new Date(0), { kind: "a", x: 1 }), false);
249
+ expect("withnative cross arm", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "b", y: "p" }), false);
250
+
251
+ // --- native unioned with a single object (control) ---
252
+ expect("datestamp same date", mod.eqDateStamp(new Date(0), new Date(0)), true);
253
+ expect("datestamp diff date", mod.eqDateStamp(new Date(0), new Date(5000)), false);
254
+ expect("datestamp stamp identical", mod.eqDateStamp({ timestamp: 5 }, { timestamp: 5 }), true);
255
+ expect("datestamp stamp different", mod.eqDateStamp({ timestamp: 5 }, { timestamp: 9 }), false);
256
+ expect("datestamp date vs stamp", mod.eqDateStamp(new Date(0), { timestamp: 0 }), false);
257
+
258
+ // --- equals must imply is on both operands (agree with is) ---
259
+ const discSamples = [
260
+ { type: "a", x: 1 }, { type: "a", x: 2 }, { type: "b", y: "p" }, { type: "b", y: "q" },
261
+ ];
262
+ for (const a of discSamples)
263
+ for (const b of discSamples) {
264
+ // fresh distinct references
265
+ const x = JSON.parse(JSON.stringify(a));
266
+ const y = JSON.parse(JSON.stringify(b));
267
+ if (mod.eqDisc(x, y)) {
268
+ expect("agree-is disc lhs " + JSON.stringify(a), mod.isDisc(x), true);
269
+ expect("agree-is disc rhs " + JSON.stringify(b), mod.isDisc(y), true);
270
+ // equal implies structurally same JSON
271
+ expect("equal implies same json " + JSON.stringify(a) + "|" + JSON.stringify(b), JSON.stringify(x) === JSON.stringify(y), true);
272
+ }
273
+ }
274
+
275
+ const maskSamples = [{ a: 1 }, { a: 1, b: "x" }, { a: 1, b: "y" }, { a: 2 }];
276
+ for (const a of maskSamples)
277
+ for (const b of maskSamples) {
278
+ const x = JSON.parse(JSON.stringify(a));
279
+ const y = JSON.parse(JSON.stringify(b));
280
+ if (mod.eqMask(x, y)) {
281
+ expect("agree-is mask same json " + JSON.stringify(a) + "|" + JSON.stringify(b), JSON.stringify(x) === JSON.stringify(y), true);
282
+ }
283
+ }
284
+
285
+ if (failures > 0) {
286
+ throw new Error(failures + " assertion(s) failed");
287
+ }
288
+ console.log("all compare-union-discrimination cases passed");
289
+ `
@@ -0,0 +1,193 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "testing"
8
+ )
9
+
10
+ // TestEscapedPropertyKeyPathTransform verifies emits with hostile keys parse.
11
+ //
12
+ // Sole-literal property keys are folded into the emit as accessor path text, and
13
+ // no build step reads the file back, so a wrongly escaped key shipped as a
14
+ // broken artifact while ttsc still exited 0. A `"` in a key terminated the path
15
+ // string early and the emitted module stopped being JavaScript; a control
16
+ // character stayed raw and the reported path could not be parsed. Only running
17
+ // node against a real emit can catch that, which is why this asserts on the
18
+ // transform output rather than on the factory in isolation.
19
+ //
20
+ // 1. Transform a fixture whose keys carry quotes, backslashes, and control
21
+ // characters.
22
+ // 2. Assert node --check accepts the emitted module as JavaScript.
23
+ // 3. Execute it and assert each reported path is the accessor JSON.stringify
24
+ // defines for that key, which is what the runtime helper produces for
25
+ // dynamic keys.
26
+ func TestEscapedPropertyKeyPathTransform(t *testing.T) {
27
+ project := escapedPropertyKeyPathProject(t)
28
+ js := escapedPropertyKeyPathTransform(t, project)
29
+ escapedPropertyKeyPathCheckSyntax(t, project, js)
30
+ escapedPropertyKeyPathRunRuntimeCases(t, project, js)
31
+ }
32
+
33
+ func escapedPropertyKeyPathProject(t *testing.T) string {
34
+ t.Helper()
35
+ root := ttscTypiaTestRepoRoot(t)
36
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
37
+ if err := os.MkdirAll(base, 0o755); err != nil {
38
+ t.Fatalf("mkdir temp base: %v", err)
39
+ }
40
+ dir, err := os.MkdirTemp(base, "escaped-property-key-path-")
41
+ if err != nil {
42
+ t.Fatalf("create temp fixture: %v", err)
43
+ }
44
+ t.Cleanup(func() {
45
+ _ = os.RemoveAll(dir)
46
+ })
47
+ src := filepath.Join(dir, "src")
48
+ if err := os.MkdirAll(src, 0o755); err != nil {
49
+ t.Fatalf("mkdir fixture src: %v", err)
50
+ }
51
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(escapedPropertyKeyPathTSConfig), 0o644); err != nil {
52
+ t.Fatalf("write tsconfig: %v", err)
53
+ }
54
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(escapedPropertyKeyPathSource), 0o644); err != nil {
55
+ t.Fatalf("write source: %v", err)
56
+ }
57
+ return dir
58
+ }
59
+
60
+ func escapedPropertyKeyPathTransform(t *testing.T, project string) string {
61
+ t.Helper()
62
+ out, errText, code := ttscTypiaTestCapture(func() int {
63
+ return runTransform([]string{
64
+ "--cwd", project,
65
+ "--tsconfig", "tsconfig.json",
66
+ "--file", "src/main.ts",
67
+ "--output", "js",
68
+ })
69
+ })
70
+ if code != 0 {
71
+ t.Fatalf("escaped property key transform failed: code=%d stderr=\n%s", code, errText)
72
+ }
73
+ return out
74
+ }
75
+
76
+ // escapedPropertyKeyPathCheckSyntax runs node against the emit exactly as it
77
+ // would ship. node --check only parses, so the unresolved typia imports in the
78
+ // untouched output do not matter, and that keeps this a check of the real
79
+ // artifact rather than of a rewritten copy.
80
+ func escapedPropertyKeyPathCheckSyntax(t *testing.T, project string, js string) {
81
+ t.Helper()
82
+ node, err := exec.LookPath("node")
83
+ if err != nil {
84
+ t.Skip("node executable not found")
85
+ }
86
+ emitted := filepath.Join(project, "emitted.cjs")
87
+ if err := os.WriteFile(emitted, []byte(js), 0o644); err != nil {
88
+ t.Fatalf("write emitted module: %v", err)
89
+ }
90
+ if output, err := exec.Command(node, "--check", emitted).CombinedOutput(); err != nil {
91
+ t.Fatalf("emitted module is not valid JavaScript: %v\n%s\n--- emit ---\n%s", err, output, js)
92
+ }
93
+ }
94
+
95
+ func escapedPropertyKeyPathRunRuntimeCases(t *testing.T, project string, js string) {
96
+ t.Helper()
97
+ node, err := exec.LookPath("node")
98
+ if err != nil {
99
+ t.Skip("node executable not found")
100
+ }
101
+ runtimeDir := filepath.Join(project, "runtime")
102
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
103
+ t.Fatalf("mkdir runtime dir: %v", err)
104
+ }
105
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
106
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
107
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
108
+ t.Fatalf("write runtime module: %v", err)
109
+ }
110
+ runner := filepath.Join(runtimeDir, "run.cjs")
111
+ if err := os.WriteFile(runner, []byte(escapedPropertyKeyPathRuntimeRunner), 0o644); err != nil {
112
+ t.Fatalf("write runtime runner: %v", err)
113
+ }
114
+ cmd := exec.Command(node, runner)
115
+ cmd.Dir = project
116
+ if output, err := cmd.CombinedOutput(); err != nil {
117
+ t.Fatalf("escaped property key runtime cases failed: %v\n%s", err, output)
118
+ }
119
+ }
120
+
121
+ const escapedPropertyKeyPathTSConfig = `{
122
+ "compilerOptions": {
123
+ "target": "ES2022",
124
+ "module": "commonjs",
125
+ "moduleResolution": "bundler",
126
+ "ignoreDeprecations": "6.0",
127
+ "types": ["*"],
128
+ "esModuleInterop": true,
129
+ "strict": true,
130
+ "skipLibCheck": true
131
+ },
132
+ "include": ["src"]
133
+ }
134
+ `
135
+
136
+ const escapedPropertyKeyPathSource = `import typia from "typia";
137
+
138
+ interface IHostileKeys {
139
+ "quote\"key": number;
140
+ "back\\slash": number;
141
+ "line\nbreak": number;
142
+ "tab\tkey": number;
143
+ "bell\u0007key": number;
144
+ "nul\u0000key": number;
145
+ "sep\u2028key": number;
146
+ "plain-key": number;
147
+ plainIdentifier: number;
148
+ }
149
+
150
+ export const KEYS: string[] = [
151
+ "quote\"key",
152
+ "back\\slash",
153
+ "line\nbreak",
154
+ "tab\tkey",
155
+ "bell\u0007key",
156
+ "nul\u0000key",
157
+ "sep\u2028key",
158
+ "plain-key",
159
+ ];
160
+
161
+ const validateHostile = typia.createValidate<IHostileKeys>();
162
+
163
+ export const run = () => {
164
+ const input: Record<string, unknown> = { plainIdentifier: 1 };
165
+ for (const key of KEYS) input[key] = "not a number";
166
+ return validateHostile(input);
167
+ };
168
+ `
169
+
170
+ // The expected path is rebuilt with JSON.stringify rather than written out
171
+ // literally, because that is the contract _accessExpressionAsString implements
172
+ // for dynamic keys and the compile-time fold must agree with it.
173
+ const escapedPropertyKeyPathRuntimeRunner = `const mod = require("./main.cjs");
174
+ const result = mod.run();
175
+
176
+ if (result.success !== false) {
177
+ throw new Error("validate accepted non-number values");
178
+ }
179
+ for (const key of mod.KEYS) {
180
+ const expected = "$input[" + JSON.stringify(key) + "]";
181
+ const found = result.errors.find((error) => error.path === expected);
182
+ if (!found) {
183
+ throw new Error(
184
+ "missing path for key " + JSON.stringify(key) +
185
+ ": expected " + JSON.stringify(expected) +
186
+ ", got " + JSON.stringify(result.errors.map((error) => error.path)),
187
+ );
188
+ }
189
+ }
190
+ if (result.errors.some((error) => error.path === "$input.plainIdentifier")) {
191
+ throw new Error("identifier fast path reported an error for a valid value");
192
+ }
193
+ `