typia 13.1.1 → 13.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (581) hide show
  1. package/README.md +3 -0
  2. package/lib/_virtual/_rolldown/runtime.mjs +1 -5
  3. package/lib/executable/FileSystemIdentity.d.ts +44 -0
  4. package/lib/executable/FileSystemIdentity.js +213 -0
  5. package/lib/executable/FileSystemIdentity.js.map +1 -0
  6. package/lib/executable/FileSystemIdentity.mjs +133 -0
  7. package/lib/executable/FileSystemIdentity.mjs.map +1 -0
  8. package/lib/executable/TypiaGenerateWizard.js +272 -106
  9. package/lib/executable/TypiaGenerateWizard.js.map +1 -1
  10. package/lib/executable/TypiaGenerateWizard.mjs +239 -95
  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 +32 -0
  16. package/lib/internal/_ProtobufReader.js +148 -48
  17. package/lib/internal/_ProtobufReader.js.map +1 -1
  18. package/lib/internal/_ProtobufReader.mjs +137 -41
  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/_jsonStringifyArray.d.ts +1 -0
  87. package/lib/internal/_jsonStringifyArray.js +48 -0
  88. package/lib/internal/_jsonStringifyArray.js.map +1 -0
  89. package/lib/internal/_jsonStringifyArray.mjs +40 -0
  90. package/lib/internal/_jsonStringifyArray.mjs.map +1 -0
  91. package/lib/internal/_jsonStringifyElement.d.ts +1 -0
  92. package/lib/internal/_jsonStringifyElement.js +23 -0
  93. package/lib/internal/_jsonStringifyElement.js.map +1 -0
  94. package/lib/internal/_jsonStringifyElement.mjs +23 -0
  95. package/lib/internal/_jsonStringifyElement.mjs.map +1 -0
  96. package/lib/internal/_jsonStringifyProperty.d.ts +1 -0
  97. package/lib/internal/_jsonStringifyProperty.js +31 -0
  98. package/lib/internal/_jsonStringifyProperty.js.map +1 -0
  99. package/lib/internal/_jsonStringifyProperty.mjs +31 -0
  100. package/lib/internal/_jsonStringifyProperty.mjs.map +1 -0
  101. package/lib/internal/_llmApplicationFinalize.js +1 -1
  102. package/lib/internal/_llmApplicationFinalize.js.map +1 -1
  103. package/lib/internal/_llmApplicationFinalize.mjs +1 -1
  104. package/lib/internal/_llmApplicationFinalize.mjs.map +1 -1
  105. package/lib/internal/_notationAny.js +8 -1
  106. package/lib/internal/_notationAny.js.map +1 -1
  107. package/lib/internal/_notationAny.mjs +7 -1
  108. package/lib/internal/_notationAny.mjs.map +1 -1
  109. package/lib/internal/_notationAssign.d.ts +1 -0
  110. package/lib/internal/_notationAssign.js +18 -0
  111. package/lib/internal/_notationAssign.js.map +1 -0
  112. package/lib/internal/_notationAssign.mjs +17 -0
  113. package/lib/internal/_notationAssign.mjs.map +1 -0
  114. package/lib/internal/_notationCamel.js +30 -9
  115. package/lib/internal/_notationCamel.js.map +1 -1
  116. package/lib/internal/_notationCamel.mjs +13 -5
  117. package/lib/internal/_notationCamel.mjs.map +1 -1
  118. package/lib/internal/_notationKebab.d.ts +1 -0
  119. package/lib/internal/_notationKebab.js +15 -0
  120. package/lib/internal/_notationKebab.js.map +1 -0
  121. package/lib/internal/_notationKebab.mjs +15 -0
  122. package/lib/internal/_notationKebab.mjs.map +1 -0
  123. package/lib/internal/_notationKeyCollision.d.ts +1 -0
  124. package/lib/internal/_notationKeyCollision.js +8 -0
  125. package/lib/internal/_notationKeyCollision.js.map +1 -0
  126. package/lib/internal/_notationKeyCollision.mjs +8 -0
  127. package/lib/internal/_notationKeyCollision.mjs.map +1 -0
  128. package/lib/internal/_notationPascal.js +20 -5
  129. package/lib/internal/_notationPascal.js.map +1 -1
  130. package/lib/internal/_notationPascal.mjs +10 -5
  131. package/lib/internal/_notationPascal.mjs.map +1 -1
  132. package/lib/internal/_notationSnake.js +25 -22
  133. package/lib/internal/_notationSnake.js.map +1 -1
  134. package/lib/internal/_notationSnake.mjs +11 -11
  135. package/lib/internal/_notationSnake.mjs.map +1 -1
  136. package/lib/internal/_plainCloneAny.js +174 -38
  137. package/lib/internal/_plainCloneAny.js.map +1 -1
  138. package/lib/internal/_plainCloneAny.mjs +126 -22
  139. package/lib/internal/_plainCloneAny.mjs.map +1 -1
  140. package/lib/internal/_randomArray.d.ts +1 -1
  141. package/lib/internal/_randomArray.js +11 -4
  142. package/lib/internal/_randomArray.js.map +1 -1
  143. package/lib/internal/_randomArray.mjs +9 -3
  144. package/lib/internal/_randomArray.mjs.map +1 -1
  145. package/lib/internal/_randomFormatByte.d.ts +2 -1
  146. package/lib/internal/_randomFormatByte.js +25 -1
  147. package/lib/internal/_randomFormatByte.js.map +1 -1
  148. package/lib/internal/_randomFormatByte.mjs +20 -1
  149. package/lib/internal/_randomFormatByte.mjs.map +1 -1
  150. package/lib/internal/_randomFormatDate.d.ts +3 -4
  151. package/lib/internal/_randomFormatDate.js +3 -10
  152. package/lib/internal/_randomFormatDate.js.map +1 -1
  153. package/lib/internal/_randomFormatDate.mjs +3 -6
  154. package/lib/internal/_randomFormatDate.mjs.map +1 -1
  155. package/lib/internal/_randomFormatDatetime.d.ts +3 -4
  156. package/lib/internal/_randomFormatDatetime.js +26 -8
  157. package/lib/internal/_randomFormatDatetime.js.map +1 -1
  158. package/lib/internal/_randomFormatDatetime.mjs +17 -6
  159. package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
  160. package/lib/internal/_randomFormatDuration.d.ts +2 -1
  161. package/lib/internal/_randomFormatDuration.js +23 -14
  162. package/lib/internal/_randomFormatDuration.js.map +1 -1
  163. package/lib/internal/_randomFormatDuration.mjs +22 -13
  164. package/lib/internal/_randomFormatDuration.mjs.map +1 -1
  165. package/lib/internal/_randomFormatEmail.d.ts +2 -1
  166. package/lib/internal/_randomFormatEmail.js +8 -1
  167. package/lib/internal/_randomFormatEmail.js.map +1 -1
  168. package/lib/internal/_randomFormatEmail.mjs +5 -1
  169. package/lib/internal/_randomFormatEmail.mjs.map +1 -1
  170. package/lib/internal/_randomFormatHostname.d.ts +8 -1
  171. package/lib/internal/_randomFormatHostname.js +45 -2
  172. package/lib/internal/_randomFormatHostname.js.map +1 -1
  173. package/lib/internal/_randomFormatHostname.mjs +38 -2
  174. package/lib/internal/_randomFormatHostname.mjs.map +1 -1
  175. package/lib/internal/_randomFormatIdnEmail.d.ts +2 -1
  176. package/lib/internal/_randomFormatIdnEmail.js +16 -2
  177. package/lib/internal/_randomFormatIdnEmail.js.map +1 -1
  178. package/lib/internal/_randomFormatIdnEmail.mjs +11 -2
  179. package/lib/internal/_randomFormatIdnEmail.mjs.map +1 -1
  180. package/lib/internal/_randomFormatIdnHostname.d.ts +2 -1
  181. package/lib/internal/_randomFormatIdnHostname.js +26 -1
  182. package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
  183. package/lib/internal/_randomFormatIdnHostname.mjs +25 -2
  184. package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
  185. package/lib/internal/_randomFormatIpv4.d.ts +2 -1
  186. package/lib/internal/_randomFormatIpv4.js +32 -1
  187. package/lib/internal/_randomFormatIpv4.js.map +1 -1
  188. package/lib/internal/_randomFormatIpv4.mjs +23 -1
  189. package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
  190. package/lib/internal/_randomFormatIpv6.d.ts +2 -1
  191. package/lib/internal/_randomFormatIpv6.js +58 -1
  192. package/lib/internal/_randomFormatIpv6.js.map +1 -1
  193. package/lib/internal/_randomFormatIpv6.mjs +45 -1
  194. package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
  195. package/lib/internal/_randomFormatIri.d.ts +2 -1
  196. package/lib/internal/_randomFormatIri.js +1 -1
  197. package/lib/internal/_randomFormatIri.js.map +1 -1
  198. package/lib/internal/_randomFormatIri.mjs +1 -1
  199. package/lib/internal/_randomFormatIri.mjs.map +1 -1
  200. package/lib/internal/_randomFormatIriReference.d.ts +2 -1
  201. package/lib/internal/_randomFormatIriReference.js +1 -1
  202. package/lib/internal/_randomFormatIriReference.js.map +1 -1
  203. package/lib/internal/_randomFormatIriReference.mjs +1 -1
  204. package/lib/internal/_randomFormatIriReference.mjs.map +1 -1
  205. package/lib/internal/_randomFormatJsonPointer.d.ts +2 -1
  206. package/lib/internal/_randomFormatJsonPointer.js +20 -1
  207. package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
  208. package/lib/internal/_randomFormatJsonPointer.mjs +15 -1
  209. package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
  210. package/lib/internal/_randomFormatPassword.d.ts +2 -1
  211. package/lib/internal/_randomFormatPassword.js +7 -5
  212. package/lib/internal/_randomFormatPassword.js.map +1 -1
  213. package/lib/internal/_randomFormatPassword.mjs +5 -1
  214. package/lib/internal/_randomFormatPassword.mjs.map +1 -1
  215. package/lib/internal/_randomFormatRegex.d.ts +2 -1
  216. package/lib/internal/_randomFormatRegex.js +15 -1
  217. package/lib/internal/_randomFormatRegex.js.map +1 -1
  218. package/lib/internal/_randomFormatRegex.mjs +14 -1
  219. package/lib/internal/_randomFormatRegex.mjs.map +1 -1
  220. package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
  221. package/lib/internal/_randomFormatRelativeJsonPointer.js +20 -5
  222. package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
  223. package/lib/internal/_randomFormatRelativeJsonPointer.mjs +21 -5
  224. package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
  225. package/lib/internal/_randomFormatTime.d.ts +2 -1
  226. package/lib/internal/_randomFormatTime.js +34 -7
  227. package/lib/internal/_randomFormatTime.js.map +1 -1
  228. package/lib/internal/_randomFormatTime.mjs +37 -4
  229. package/lib/internal/_randomFormatTime.mjs.map +1 -1
  230. package/lib/internal/_randomFormatUri.d.ts +2 -1
  231. package/lib/internal/_randomFormatUri.js +1 -1
  232. package/lib/internal/_randomFormatUri.js.map +1 -1
  233. package/lib/internal/_randomFormatUri.mjs +1 -1
  234. package/lib/internal/_randomFormatUri.mjs.map +1 -1
  235. package/lib/internal/_randomFormatUriReference.d.ts +2 -1
  236. package/lib/internal/_randomFormatUriReference.js +1 -1
  237. package/lib/internal/_randomFormatUriReference.js.map +1 -1
  238. package/lib/internal/_randomFormatUriReference.mjs +1 -1
  239. package/lib/internal/_randomFormatUriReference.mjs.map +1 -1
  240. package/lib/internal/_randomFormatUriTemplate.d.ts +2 -1
  241. package/lib/internal/_randomFormatUriTemplate.js +1 -1
  242. package/lib/internal/_randomFormatUriTemplate.js.map +1 -1
  243. package/lib/internal/_randomFormatUriTemplate.mjs +1 -1
  244. package/lib/internal/_randomFormatUriTemplate.mjs.map +1 -1
  245. package/lib/internal/_randomFormatUrl.d.ts +2 -1
  246. package/lib/internal/_randomFormatUrl.js +21 -1
  247. package/lib/internal/_randomFormatUrl.js.map +1 -1
  248. package/lib/internal/_randomFormatUrl.mjs +18 -1
  249. package/lib/internal/_randomFormatUrl.mjs.map +1 -1
  250. package/lib/internal/_randomFormatUuid.d.ts +2 -1
  251. package/lib/internal/_randomFormatUuid.js +3 -2
  252. package/lib/internal/_randomFormatUuid.js.map +1 -1
  253. package/lib/internal/_randomFormatUuid.mjs +3 -2
  254. package/lib/internal/_randomFormatUuid.mjs.map +1 -1
  255. package/lib/internal/_randomInteger.js +59 -28
  256. package/lib/internal/_randomInteger.js.map +1 -1
  257. package/lib/internal/_randomInteger.mjs +56 -16
  258. package/lib/internal/_randomInteger.mjs.map +1 -1
  259. package/lib/internal/_randomMultiple.d.ts +8 -0
  260. package/lib/internal/_randomMultiple.js +168 -0
  261. package/lib/internal/_randomMultiple.js.map +1 -0
  262. package/lib/internal/_randomMultiple.mjs +158 -0
  263. package/lib/internal/_randomMultiple.mjs.map +1 -0
  264. package/lib/internal/_randomNumber.js +42 -42
  265. package/lib/internal/_randomNumber.js.map +1 -1
  266. package/lib/internal/_randomNumber.mjs +41 -27
  267. package/lib/internal/_randomNumber.mjs.map +1 -1
  268. package/lib/internal/_randomPattern.d.ts +2 -1
  269. package/lib/internal/_randomPattern.js +19 -4
  270. package/lib/internal/_randomPattern.js.map +1 -1
  271. package/lib/internal/_randomPattern.mjs +10 -4
  272. package/lib/internal/_randomPattern.mjs.map +1 -1
  273. package/lib/internal/_randomStringLength.d.ts +64 -0
  274. package/lib/internal/_randomStringLength.js +84 -0
  275. package/lib/internal/_randomStringLength.js.map +1 -0
  276. package/lib/internal/_randomStringLength.mjs +79 -0
  277. package/lib/internal/_randomStringLength.mjs.map +1 -0
  278. package/lib/internal/_stringLength.d.ts +1 -0
  279. package/lib/internal/_stringLength.js +11 -0
  280. package/lib/internal/_stringLength.js.map +1 -0
  281. package/lib/internal/_stringLength.mjs +10 -0
  282. package/lib/internal/_stringLength.mjs.map +1 -0
  283. package/lib/internal/_validateReport.js +4 -1
  284. package/lib/internal/_validateReport.js.map +1 -1
  285. package/lib/internal/_validateReport.mjs +2 -1
  286. package/lib/internal/_validateReport.mjs.map +1 -1
  287. package/lib/internal/private/__notationRename.d.ts +14 -0
  288. package/lib/internal/private/__notationRename.js +25 -0
  289. package/lib/internal/private/__notationRename.js.map +1 -0
  290. package/lib/internal/private/__notationRename.mjs +24 -0
  291. package/lib/internal/private/__notationRename.mjs.map +1 -0
  292. package/lib/internal/private/__randomComposition.d.ts +23 -0
  293. package/lib/internal/private/__randomComposition.js +48 -0
  294. package/lib/internal/private/__randomComposition.js.map +1 -0
  295. package/lib/internal/private/__randomComposition.mjs +54 -0
  296. package/lib/internal/private/__randomComposition.mjs.map +1 -0
  297. package/lib/internal/private/__randomEpoch.d.ts +19 -0
  298. package/lib/internal/private/__randomEpoch.js +31 -0
  299. package/lib/internal/private/__randomEpoch.js.map +1 -0
  300. package/lib/internal/private/__randomEpoch.mjs +28 -0
  301. package/lib/internal/private/__randomEpoch.mjs.map +1 -0
  302. package/lib/json.d.ts +2 -2
  303. package/lib/json.mjs.map +1 -1
  304. package/lib/module.d.ts +2 -2
  305. package/lib/module.js.map +1 -1
  306. package/lib/module.mjs.map +1 -1
  307. package/lib/notations.d.ts +20 -4
  308. package/lib/notations.js.map +1 -1
  309. package/lib/notations.mjs.map +1 -1
  310. package/native/adapter/plugin_options.go +117 -0
  311. package/native/adapter/plugin_options_payload_matrix_test.go +181 -0
  312. package/native/cmd/ttsc-typia/any_array_type_tags_transform_test.go +63 -9
  313. package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +152 -0
  314. package/native/cmd/ttsc-typia/build.go +84 -64
  315. package/native/cmd/ttsc-typia/build_no_emit_preserves_analysis_options_test.go +67 -0
  316. package/native/cmd/ttsc-typia/build_no_emit_transform_diagnostics_test.go +138 -0
  317. package/native/cmd/ttsc-typia/build_plugin_options_come_from_payload_test.go +48 -0
  318. package/native/cmd/ttsc-typia/build_transactional_emit_success_test.go +81 -0
  319. package/native/cmd/ttsc-typia/build_transform_failure_atomicity_test.go +138 -0
  320. package/native/cmd/ttsc-typia/callable_interface_function_semantics_transform_test.go +331 -0
  321. package/native/cmd/ttsc-typia/callable_type_literal_boundaries_transform_test.go +1184 -0
  322. package/native/cmd/ttsc-typia/command_routes_and_diagnostics_coverage_test.go +3 -1
  323. package/native/cmd/ttsc-typia/compare_functional_union_membership_transform_test.go +434 -0
  324. package/native/cmd/ttsc-typia/compare_less_nan_transform_test.go +98 -0
  325. package/native/cmd/ttsc-typia/compare_native_object_overmatch_transform_test.go +161 -0
  326. package/native/cmd/ttsc-typia/compare_nondiscriminable_union_transform_test.go +343 -0
  327. package/native/cmd/ttsc-typia/compare_template_literal_union_transform_test.go +241 -0
  328. package/native/cmd/ttsc-typia/compare_union_discrimination_transform_test.go +289 -0
  329. package/native/cmd/ttsc-typia/default_library_spoof_native_identity_transform_test.go +216 -0
  330. package/native/cmd/ttsc-typia/escaped_property_key_path_transform_test.go +193 -0
  331. package/native/cmd/ttsc-typia/finite_option_number_leaf_transform_test.go +240 -0
  332. package/native/cmd/ttsc-typia/functional_promised_type_transform_test.go +220 -0
  333. package/native/cmd/ttsc-typia/functional_receiver_transform_test.go +232 -0
  334. package/native/cmd/ttsc-typia/is_object_function_member_transform_test.go +205 -0
  335. package/native/cmd/ttsc-typia/json_application_alias_function_validation_transform_test.go +151 -0
  336. package/native/cmd/ttsc-typia/json_is_stringify_finite_number_transform_test.go +198 -0
  337. package/native/cmd/ttsc-typia/json_schema_dynamic_key_determinism_transform_test.go +246 -0
  338. package/native/cmd/ttsc-typia/json_stringify_contextual_undefined_transform_test.go +556 -0
  339. package/native/cmd/ttsc-typia/json_stringify_special_key_transform_test.go +238 -0
  340. package/native/cmd/ttsc-typia/lib_replacement_native_identity_transform_test.go +277 -0
  341. package/native/cmd/ttsc-typia/main_wasm.go +21 -2
  342. package/native/cmd/ttsc-typia/native_collection_identity_is_transform_test.go +234 -0
  343. package/native/cmd/ttsc-typia/native_generic_name_guard_is_transform_test.go +194 -0
  344. package/native/cmd/ttsc-typia/native_name_collision_is_transform_test.go +204 -0
  345. package/native/cmd/ttsc-typia/native_named_intersection_union_transform_test.go +390 -0
  346. package/native/cmd/ttsc-typia/node_buffer_native_exports_is_transform_test.go +526 -0
  347. package/native/cmd/ttsc-typia/non_trailing_rest_tuple_transform_test.go +23 -11
  348. package/native/cmd/ttsc-typia/notation_dynamic_keys_transform_test.go +286 -0
  349. package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +1 -1
  350. package/native/cmd/ttsc-typia/notation_literal_collision_transform_test.go +164 -0
  351. package/native/cmd/ttsc-typia/notation_pascal_case_transform_test.go +230 -0
  352. package/native/cmd/ttsc-typia/notation_unicode_key_transform_test.go +309 -0
  353. package/native/cmd/ttsc-typia/package_declaration_native_identity_is_transform_test.go +293 -0
  354. package/native/cmd/ttsc-typia/pattern_line_terminator_escape_transform_test.go +224 -0
  355. package/native/cmd/ttsc-typia/plain_prune_union_object_overmatch_transform_test.go +219 -0
  356. package/native/cmd/ttsc-typia/plugin_options_payload_helpers_test.go +181 -0
  357. package/native/cmd/ttsc-typia/private_field_filter_is_transform_test.go +278 -0
  358. package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +73 -27
  359. package/native/cmd/ttsc-typia/project_dependencies_barrel_reexport_transform_test.go +120 -0
  360. package/native/cmd/ttsc-typia/project_dependencies_collapsed_alias_transform_test.go +134 -0
  361. package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +135 -0
  362. package/native/cmd/ttsc-typia/project_dependencies_default_barrel_transform_test.go +114 -0
  363. package/native/cmd/ttsc-typia/project_dependencies_empty_heritage_transform_test.go +100 -0
  364. package/native/cmd/ttsc-typia/project_dependencies_envelope_transform_test.go +148 -0
  365. package/native/cmd/ttsc-typia/project_dependencies_index_signature_alias_transform_test.go +139 -0
  366. package/native/cmd/ttsc-typia/project_dependencies_local_reexport_transform_test.go +122 -0
  367. package/native/cmd/ttsc-typia/project_dependencies_signature_alias_transform_test.go +125 -0
  368. package/native/cmd/ttsc-typia/project_dependencies_star_barrel_transform_test.go +112 -0
  369. package/native/cmd/ttsc-typia/project_reference_graph_envelope_transform_test.go +190 -0
  370. package/native/cmd/ttsc-typia/protobuf_diagnostic_code_transform_test.go +167 -0
  371. package/native/cmd/ttsc-typia/protobuf_is_encode_finite_number_transform_test.go +98 -0
  372. package/native/cmd/ttsc-typia/protobuf_sequence_field_numbers_transform_test.go +52 -22
  373. package/native/cmd/ttsc-typia/symbol_index_domain_transform_test.go +316 -0
  374. package/native/cmd/ttsc-typia/symbol_key_member_filter_transform_test.go +279 -0
  375. package/native/cmd/ttsc-typia/template_interpolation_type_tags_transform_test.go +86 -23
  376. package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
  377. package/native/cmd/ttsc-typia/transform.go +251 -39
  378. package/native/cmd/ttsc-typia/{transform_declaration_source_produces_no_js_test.go → transform_declaration_source_produces_no_javascript_test.go} +10 -2
  379. package/native/cmd/ttsc-typia/transform_fixtures_emit_coverage_test.go +21 -4
  380. package/native/cmd/ttsc-typia/transform_helpers_test.go +236 -3
  381. package/native/cmd/ttsc-typia/transform_plugin_options_come_from_payload_test.go +43 -0
  382. package/native/cmd/ttsc-typia/transform_single_file_failure_atomicity_test.go +114 -0
  383. package/native/cmd/ttsc-typia/transform_single_file_failure_writes_no_stdout_test.go +43 -0
  384. package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go +81 -0
  385. package/native/cmd/ttsc-typia/transform_single_file_js_empty_emit_reports_no_output_test.go +100 -0
  386. package/native/cmd/ttsc-typia/transform_single_file_js_locates_output_across_layouts_test.go +160 -0
  387. package/native/cmd/ttsc-typia/transform_single_file_success_publishes_artifact_test.go +54 -0
  388. package/native/cmd/ttsc-typia/transform_wasm_host_argv_reports_diagnostics_test.go +39 -0
  389. package/native/cmd/ttsc-typia/tuple_optional_compare_clone_transform_test.go +227 -0
  390. package/native/cmd/ttsc-typia/user_global_native_identity_transform_test.go +484 -0
  391. package/native/core/factories/FormatCheatSheet.go +40 -7
  392. package/native/core/factories/IdentifierFactory.go +131 -4
  393. package/native/core/factories/MetadataCommentTagFactory.go +83 -40
  394. package/native/core/factories/MetadataTypeTagFactory.go +13 -1
  395. package/native/core/factories/NumericRangeFactory.go +60 -17
  396. package/native/core/factories/ProtobufFactory.go +13 -5
  397. package/native/core/factories/factory_utility_coverage_test.go +8 -2
  398. package/native/core/factories/format_alias_resolves_to_cheat_sheet_test.go +57 -0
  399. package/native/core/factories/format_alias_table_targets_the_cheat_sheet_test.go +44 -0
  400. package/native/core/factories/identifier_factory_postfix_escapes_every_key_test.go +147 -0
  401. package/native/core/factories/identifier_factory_postfix_survives_every_code_point_test.go +86 -0
  402. package/native/core/factories/internal/metadata/MetadataHelper.go +226 -17
  403. package/native/core/factories/internal/metadata/emplace_metadata_object.go +141 -8
  404. package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
  405. package/native/core/factories/internal/metadata/iterate_metadata_function.go +5 -12
  406. package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +111 -29
  407. package/native/core/factories/internal/metadata/iterate_metadata_map.go +5 -0
  408. package/native/core/factories/internal/metadata/iterate_metadata_native.go +45 -2
  409. package/native/core/factories/internal/metadata/iterate_metadata_set.go +5 -0
  410. package/native/core/factories/internal/metadata/type_arguments_precondition_test.go +70 -0
  411. package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +39 -0
  412. package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go +84 -0
  413. package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go +60 -0
  414. package/native/core/factories/metadata_type_tag_factory_declarations_test.go +86 -0
  415. package/native/core/factories/metadata_type_tag_factory_keeps_bool_form_exclusivity_test.go +38 -0
  416. package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go +65 -0
  417. package/native/core/factories/metadata_type_tag_factory_rejects_duplicated_array_form_tags_test.go +41 -0
  418. package/native/core/factories/numeric_range_factory_enforces_64bit_bounds_test.go +69 -0
  419. package/native/core/factories/protobuf_recovery_ownership_test.go +64 -0
  420. package/native/core/programmers/IsProgrammer.go +15 -1
  421. package/native/core/programmers/RandomProgrammer.go +51 -14
  422. package/native/core/programmers/compare/CompareEqualProgrammer.go +410 -8
  423. package/native/core/programmers/compare/CompareLessProgrammer.go +4 -2
  424. package/native/core/programmers/functional/FunctionalAssertFunctionProgrammer.go +4 -6
  425. package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +5 -13
  426. package/native/core/programmers/functional/FunctionalAssertReturnProgrammer.go +6 -14
  427. package/native/core/programmers/functional/FunctionalIsFunctionProgrammer.go +4 -6
  428. package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +49 -14
  429. package/native/core/programmers/functional/FunctionalIsReturnProgrammer.go +5 -13
  430. package/native/core/programmers/functional/FunctionalValidateFunctionProgrammer.go +4 -6
  431. package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +5 -13
  432. package/native/core/programmers/functional/FunctionalValidateReturnProgrammer.go +5 -13
  433. package/native/core/programmers/functional/internal/FunctionalGeneralProgrammer.go +4 -17
  434. package/native/core/programmers/helpers/CloneJoiner.go +32 -0
  435. package/native/core/programmers/helpers/FunctionProgrammer.go +6 -13
  436. package/native/core/programmers/helpers/NotationJoiner.go +86 -28
  437. package/native/core/programmers/helpers/StringifyJoinder.go +161 -51
  438. package/native/core/programmers/helpers/UnionExplorer.go +203 -61
  439. package/native/core/programmers/helpers/joiner_branch_coverage_test.go +116 -118
  440. package/native/core/programmers/helpers/union_explorer_coverage_test.go +1 -1
  441. package/native/core/programmers/internal/CheckerProgrammer.go +100 -48
  442. package/native/core/programmers/iterate/check_template.go +344 -32
  443. package/native/core/programmers/iterate/iterate_check_coverage_test.go +76 -158
  444. package/native/core/programmers/iterate/iterate_utility_coverage_test.go +231 -270
  445. package/native/core/programmers/iterate/json_schema_discriminator.go +36 -10
  446. package/native/core/programmers/iterate/json_schema_discriminator_declaration_syntax_test.go +205 -0
  447. package/native/core/programmers/iterate/json_schema_object.go +49 -7
  448. package/native/core/programmers/iterate/json_schema_pattern_property_order_test.go +44 -0
  449. package/native/core/programmers/iterate/openapi_v3_downgrader.go +674 -0
  450. package/native/core/programmers/iterate/openapi_v3_downgrader_boolean_default_test.go +95 -0
  451. package/native/core/programmers/iterate/openapi_v3_downgrader_test.go +123 -0
  452. package/native/core/programmers/iterate/template_interpolation_tags_test.go +40 -8
  453. package/native/core/programmers/iterate/template_runtime_pattern.go +63 -7
  454. package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
  455. package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
  456. package/native/core/programmers/json/JsonStringifyProgrammer.go +47 -6
  457. package/native/core/programmers/llm/LlmApplicationProgrammer.go +21 -11
  458. package/native/core/programmers/llm/LlmSchemaProgrammer.go +23 -6
  459. package/native/core/programmers/llm/llm_reference_codec_test.go +24 -0
  460. package/native/core/programmers/notations/NotationGeneralProgrammer.go +183 -67
  461. package/native/core/programmers/notations/notation_general_helpers_test.go +1 -3
  462. package/native/core/programmers/notations/notation_general_programmer_pascal_multiword_test.go +72 -0
  463. package/native/core/programmers/notations/notation_general_programmer_underscore_boundary_test.go +68 -0
  464. package/native/core/programmers/plain/PlainClassifyProgrammer.go +23 -15
  465. package/native/core/programmers/plain/PlainCloneProgrammer.go +20 -7
  466. package/native/core/programmers/plain/PlainPruneProgrammer.go +19 -5
  467. package/native/core/programmers/plain/plain_tuple_seed_recovery_ownership_test.go +25 -0
  468. package/native/core/programmers/protobuf/ProtobufDecodeProgrammer.go +37 -28
  469. package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +41 -22
  470. package/native/core/programmers/protobuf/protobuf_programmer_helper_coverage_test.go +26 -0
  471. package/native/core/programmers/random_programmer_length_argument_test.go +53 -0
  472. package/native/core/schemas/metadata/MetadataCollection.go +266 -25
  473. package/native/core/schemas/metadata/MetadataDefaultLibrary.go +81 -0
  474. package/native/core/schemas/metadata/MetadataDependency.go +388 -0
  475. package/native/core/schemas/metadata/MetadataObjectType.go +24 -22
  476. package/native/core/schemas/metadata/metadata_collection_generic_argument_dot_test.go +122 -0
  477. package/native/core/schemas/metadata/metadata_collection_name_allocation_test.go +147 -0
  478. package/native/core/schemas/metadata/metadata_collection_openapi_name_cascade_test.go +55 -0
  479. package/native/core/schemas/metadata/metadata_collection_openapi_name_test.go +68 -0
  480. package/native/core/utils/PatternUtil.go +13 -0
  481. package/native/core/utils/PromiseTypeFactory.go +59 -0
  482. package/native/core/utils/ProtobufNameEncoder.go +8 -0
  483. package/native/core/utils/promise_type_factory_semantics_test.go +118 -0
  484. package/native/go.mod +9 -1
  485. package/native/transform/CallExpressionTransformer.go +12 -0
  486. package/native/transform/features/json/JsonApplicationTransformer.go +1 -1
  487. package/native/transform/features/json/JsonSchemaTransformer.go +1 -1
  488. package/native/transform/features/json/JsonSchemasTransformer.go +5 -4
  489. package/native/transform/features/protobuf/ProtobufMessageTransformer.go +1 -1
  490. package/package.json +12 -4
  491. package/src/executable/FileSystemIdentity.ts +222 -0
  492. package/src/executable/TypiaGenerateWizard.ts +386 -113
  493. package/src/functional.ts +30 -60
  494. package/src/internal/_ProtobufReader.ts +161 -46
  495. package/src/internal/_createStandardSchema.ts +15 -1
  496. package/src/internal/_decimal.ts +69 -0
  497. package/src/internal/_httpQueryParseURLSearchParams.ts +24 -2
  498. package/src/internal/_isFormatByte.ts +2 -5
  499. package/src/internal/_isFormatDate.ts +15 -2
  500. package/src/internal/_isFormatDateTime.ts +28 -2
  501. package/src/internal/_isFormatIri.ts +5 -2
  502. package/src/internal/_isFormatIriReference.ts +11 -3
  503. package/src/internal/_isFormatUriReference.ts +1 -1
  504. package/src/internal/_isMultipleOf.ts +8 -0
  505. package/src/internal/_isTypeFloat.ts +1 -1
  506. package/src/internal/_isTypeInt64.ts +1 -0
  507. package/src/internal/_isTypeInt64Bigint.ts +12 -0
  508. package/src/internal/_isTypeUint64.ts +1 -0
  509. package/src/internal/_isTypeUint64Bigint.ts +7 -0
  510. package/src/internal/_isUniqueItems.ts +134 -132
  511. package/src/internal/_jsonStringifyArray.ts +50 -0
  512. package/src/internal/_jsonStringifyElement.ts +19 -0
  513. package/src/internal/_jsonStringifyProperty.ts +30 -0
  514. package/src/internal/_llmApplicationFinalize.ts +6 -1
  515. package/src/internal/_notationAny.ts +9 -4
  516. package/src/internal/_notationAssign.ts +20 -0
  517. package/src/internal/_notationCamel.ts +31 -10
  518. package/src/internal/_notationKebab.ts +11 -0
  519. package/src/internal/_notationKeyCollision.ts +9 -0
  520. package/src/internal/_notationPascal.ts +19 -6
  521. package/src/internal/_notationSnake.ts +24 -21
  522. package/src/internal/_plainCloneAny.ts +208 -33
  523. package/src/internal/_randomArray.ts +13 -4
  524. package/src/internal/_randomFormatByte.ts +31 -1
  525. package/src/internal/_randomFormatDate.ts +6 -17
  526. package/src/internal/_randomFormatDatetime.ts +34 -15
  527. package/src/internal/_randomFormatDuration.ts +30 -13
  528. package/src/internal/_randomFormatEmail.ts +8 -2
  529. package/src/internal/_randomFormatHostname.ts +48 -1
  530. package/src/internal/_randomFormatIdnEmail.ts +18 -2
  531. package/src/internal/_randomFormatIdnHostname.ts +34 -2
  532. package/src/internal/_randomFormatIpv4.ts +43 -2
  533. package/src/internal/_randomFormatIpv6.ts +67 -2
  534. package/src/internal/_randomFormatIri.ts +3 -1
  535. package/src/internal/_randomFormatIriReference.ts +3 -1
  536. package/src/internal/_randomFormatJsonPointer.ts +28 -2
  537. package/src/internal/_randomFormatPassword.ts +11 -6
  538. package/src/internal/_randomFormatRegex.ts +22 -1
  539. package/src/internal/_randomFormatRelativeJsonPointer.ts +26 -6
  540. package/src/internal/_randomFormatTime.ts +46 -10
  541. package/src/internal/_randomFormatUri.ts +3 -1
  542. package/src/internal/_randomFormatUriReference.ts +3 -1
  543. package/src/internal/_randomFormatUriTemplate.ts +3 -1
  544. package/src/internal/_randomFormatUrl.ts +25 -2
  545. package/src/internal/_randomFormatUuid.ts +10 -6
  546. package/src/internal/_randomInteger.ts +87 -40
  547. package/src/internal/_randomMultiple.ts +245 -0
  548. package/src/internal/_randomNumber.ts +72 -55
  549. package/src/internal/_randomPattern.ts +29 -4
  550. package/src/internal/_randomStringLength.ts +116 -0
  551. package/src/internal/_stringLength.ts +5 -0
  552. package/src/internal/_validateReport.ts +5 -1
  553. package/src/internal/private/__notationRename.ts +21 -0
  554. package/src/internal/private/__randomComposition.ts +50 -0
  555. package/src/internal/private/__randomEpoch.ts +34 -0
  556. package/src/json.ts +2 -2
  557. package/src/module.ts +4 -6
  558. package/src/notations.ts +20 -4
  559. package/lib/internal/private/__notationCapitalize.d.ts +0 -1
  560. package/lib/internal/private/__notationCapitalize.js +0 -6
  561. package/lib/internal/private/__notationCapitalize.js.map +0 -1
  562. package/lib/internal/private/__notationCapitalize.mjs +0 -6
  563. package/lib/internal/private/__notationCapitalize.mjs.map +0 -1
  564. package/lib/internal/private/__notationUnsnake.d.ts +0 -4
  565. package/lib/internal/private/__notationUnsnake.js +0 -26
  566. package/lib/internal/private/__notationUnsnake.js.map +0 -1
  567. package/lib/internal/private/__notationUnsnake.mjs +0 -15
  568. package/lib/internal/private/__notationUnsnake.mjs.map +0 -1
  569. package/native/adapter/visit.go +0 -173
  570. package/native/adapter/visit_property_chain_edges_test.go +0 -129
  571. package/native/cmd/ttsc-typia/plugin_options_missing_config_test.go +0 -26
  572. package/native/cmd/ttsc-typia/plugin_options_undefined_false_test.go +0 -36
  573. package/native/core/programmers/helpers/disable_function_programmer_declare.go +0 -10
  574. package/native/core/programmers/iterate/check_union_array_like.go +0 -422
  575. package/native/core/programmers/iterate/prune_object_properties.go +0 -105
  576. package/native/core/programmers/iterate/stringify_dynamic_properties.go +0 -219
  577. package/native/core/programmers/iterate/stringify_native.go +0 -14
  578. package/native/core/programmers/iterate/stringify_regular_properties.go +0 -112
  579. package/native/core/schemas/metadata/MetadataApplication.go +0 -41
  580. package/src/internal/private/__notationCapitalize.ts +0 -2
  581. package/src/internal/private/__notationUnsnake.ts +0 -24
@@ -175,6 +175,8 @@ func TestCommandRoutesAndDiagnosticsCoverage(t *testing.T) {
175
175
  "--rewrite-mode", "none",
176
176
  })
177
177
  }, 0},
178
+ // Publishes, rather than the 3 this expected while samchon/typia#2134
179
+ // made `--output js` miss its own artifact under the fixture's `outDir`.
178
180
  {"transform_js_out", func(t *testing.T) int {
179
181
  return runTransform([]string{
180
182
  "--cwd", primitives,
@@ -184,7 +186,7 @@ func TestCommandRoutesAndDiagnosticsCoverage(t *testing.T) {
184
186
  "--out", filepath.Join(t.TempDir(), "main.js"),
185
187
  "--rewrite-mode", "none",
186
188
  })
187
- }, 3},
189
+ }, 0},
188
190
  {"transform_ts_stdout_write_error", func(t *testing.T) int {
189
191
  return commandRoutesWithFailingStdout(func() int {
190
192
  return runTransform([]string{
@@ -0,0 +1,434 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ // TestCompareFunctionalUnionMembershipTransform verifies that compare.equals
12
+ // selects an object-union member with the same functional-property semantics as
13
+ // typia.is and the plain member routers (samchon/typia#2252).
14
+ //
15
+ // Object comparison deliberately ignores function-valued properties after it
16
+ // has selected a member. That must not make those properties invisible while
17
+ // selecting a member when the active `functional: true` option makes them part
18
+ // of membership. Otherwise a string-valued later member enters an earlier
19
+ // function-bearing member, and equality or cover can ignore the later member's
20
+ // distinguishing data. The default mode remains intentionally lenient for a
21
+ // sole function-valued property.
22
+ //
23
+ // 1. Transform functional and default-option variants of direct/factory is,
24
+ // equals, cover, clone, prune, and nested equality calls over both union
25
+ // orders.
26
+ // 2. Execute distinct valid, invalid, same-reference, reversed-order, nested,
27
+ // and actual-function-member controls against the emitted JavaScript. The
28
+ // order-symmetric pair makes the function member the later declaration and
29
+ // changes only its later-member label, so member routing rather than
30
+ // function identity decides the result.
31
+ // 3. Require compare.less to retain its existing multi-object-union diagnostic.
32
+ func TestCompareFunctionalUnionMembershipTransform(t *testing.T) {
33
+ project := compareFunctionalUnionMembershipProject(t)
34
+ functional := compareFunctionalUnionMembershipTransform(t, project, true)
35
+ defaultMode := compareFunctionalUnionMembershipTransform(t, project, false)
36
+ compareFunctionalUnionMembershipRunRuntimeCases(t, project, functional, defaultMode)
37
+ if strings.Contains(functional, `typeof v.handler === "function"`) == false {
38
+ t.Fatalf("functional equality emit did not retain the function membership guard:\n%s", functional)
39
+ }
40
+ compareFunctionalUnionMembershipRejectsLess(t, project)
41
+ }
42
+
43
+ func compareFunctionalUnionMembershipProject(t *testing.T) string {
44
+ t.Helper()
45
+ base := os.Getenv("TYPIA_TEST_TMPDIR")
46
+ if base == "" {
47
+ root := ttscTypiaTestRepoRoot(t)
48
+ base = filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
49
+ }
50
+ if err := os.MkdirAll(base, 0o755); err != nil {
51
+ t.Fatalf("mkdir temp base: %v", err)
52
+ }
53
+ dir, err := os.MkdirTemp(base, "compare-functional-union-")
54
+ if err != nil {
55
+ t.Fatalf("create temp fixture: %v", err)
56
+ }
57
+ t.Cleanup(func() {
58
+ _ = os.RemoveAll(dir)
59
+ })
60
+ src := filepath.Join(dir, "src")
61
+ if err := os.MkdirAll(src, 0o755); err != nil {
62
+ t.Fatalf("mkdir fixture src: %v", err)
63
+ }
64
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.main.json"), []byte(compareFunctionalUnionMembershipTSConfig("src/main.ts")), 0o644); err != nil {
65
+ t.Fatalf("write main tsconfig: %v", err)
66
+ }
67
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.less.json"), []byte(compareFunctionalUnionMembershipTSConfig("src/less.ts")), 0o644); err != nil {
68
+ t.Fatalf("write less tsconfig: %v", err)
69
+ }
70
+ compareFunctionalUnionMembershipWriteTypiaFixture(t, dir)
71
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareFunctionalUnionMembershipSource), 0o644); err != nil {
72
+ t.Fatalf("write source: %v", err)
73
+ }
74
+ if err := os.WriteFile(filepath.Join(src, "less.ts"), []byte(compareFunctionalUnionMembershipLessSource), 0o644); err != nil {
75
+ t.Fatalf("write less source: %v", err)
76
+ }
77
+ return dir
78
+ }
79
+
80
+ func compareFunctionalUnionMembershipWriteTypiaFixture(t *testing.T, project string) {
81
+ t.Helper()
82
+ root := filepath.Join(project, "node_modules", "typia")
83
+ if err := os.MkdirAll(filepath.Join(root, "src"), 0o755); err != nil {
84
+ t.Fatalf("mkdir typia fixture: %v", err)
85
+ }
86
+ if err := os.MkdirAll(filepath.Join(root, "lib"), 0o755); err != nil {
87
+ t.Fatalf("mkdir typia fixture lib: %v", err)
88
+ }
89
+ files := map[string]string{
90
+ "package.json": `{
91
+ "name": "typia",
92
+ "version": "0.0.0-test",
93
+ "main": "./src/index.ts",
94
+ "types": "./src/index.ts",
95
+ "exports": {
96
+ ".": "./src/index.ts",
97
+ "./lib/transform": "./lib/transform.js"
98
+ },
99
+ "ttsc": {
100
+ "plugin": { "transform": "typia/lib/transform" }
101
+ }
102
+ }
103
+ `,
104
+ "src/index.ts": compareFunctionalUnionMembershipTypiaIndex,
105
+ "src/module.ts": compareFunctionalUnionMembershipTypiaModule,
106
+ "src/compare.ts": compareFunctionalUnionMembershipTypiaCompare,
107
+ "src/plain.ts": compareFunctionalUnionMembershipTypiaPlain,
108
+ "lib/transform.js": "module.exports = {};\n",
109
+ }
110
+ for name, body := range files {
111
+ if err := os.WriteFile(filepath.Join(root, name), []byte(body), 0o644); err != nil {
112
+ t.Fatalf("write typia fixture %s: %v", name, err)
113
+ }
114
+ }
115
+ }
116
+
117
+ func compareFunctionalUnionMembershipTransform(t *testing.T, project string, functional bool) string {
118
+ t.Helper()
119
+ payload := `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`
120
+ if functional {
121
+ payload = `[{"config":{"transform":"typia/lib/transform","functional":true},"name":"typia","stage":"transform"}]`
122
+ }
123
+ out, errText, code := ttscTypiaTestCapture(func() int {
124
+ return runTransform([]string{
125
+ "--cwd", project,
126
+ "--tsconfig", "tsconfig.main.json",
127
+ "--file", "src/main.ts",
128
+ "--output", "js",
129
+ "--plugins-json=" + payload,
130
+ })
131
+ })
132
+ if code != 0 {
133
+ t.Fatalf("functional=%t transform failed: code=%d stderr=\n%s", functional, code, errText)
134
+ }
135
+ return out
136
+ }
137
+
138
+ func compareFunctionalUnionMembershipRunRuntimeCases(t *testing.T, project string, functional string, defaultMode string) {
139
+ t.Helper()
140
+ node, err := exec.LookPath("node")
141
+ if err != nil {
142
+ t.Skip("node executable not found")
143
+ }
144
+ runtimeDir := filepath.Join(project, "runtime")
145
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
146
+ t.Fatalf("mkdir runtime dir: %v", err)
147
+ }
148
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
149
+ if err := os.WriteFile(filepath.Join(runtimeDir, "throw-type-guard-error-stub.cjs"), []byte(compareFunctionalUnionMembershipThrowStub), 0o644); err != nil {
150
+ t.Fatalf("write throw type guard error stub: %v", err)
151
+ }
152
+ for _, output := range []struct {
153
+ name string
154
+ js string
155
+ }{
156
+ {name: "functional.cjs", js: functional},
157
+ {name: "default.cjs", js: defaultMode},
158
+ } {
159
+ js := strings.ReplaceAll(output.js, `require("typia/lib/internal/_throwTypeGuardError")`, `require("./throw-type-guard-error-stub.cjs")`)
160
+ js = ttscTypiaTestRewriteCommonJS(t, js)
161
+ if err := os.WriteFile(filepath.Join(runtimeDir, output.name), []byte(js), 0o644); err != nil {
162
+ t.Fatalf("write %s: %v", output.name, err)
163
+ }
164
+ }
165
+ runner := filepath.Join(runtimeDir, "run.cjs")
166
+ if err := os.WriteFile(runner, []byte(compareFunctionalUnionMembershipRuntimeRunner), 0o644); err != nil {
167
+ t.Fatalf("write runtime runner: %v", err)
168
+ }
169
+ cmd := exec.Command(node, runner)
170
+ cmd.Dir = runtimeDir
171
+ output, err := cmd.CombinedOutput()
172
+ if err != nil {
173
+ t.Fatalf("functional union membership runtime cases failed: %v\n%s", err, output)
174
+ }
175
+ if strings.Contains(string(output), "RAN 52 CASES") == false {
176
+ t.Fatalf("functional union membership runner skipped cases:\n%s", output)
177
+ }
178
+ }
179
+
180
+ func compareFunctionalUnionMembershipRejectsLess(t *testing.T, project string) {
181
+ t.Helper()
182
+ payload := `[{"config":{"transform":"typia/lib/transform","functional":true},"name":"typia","stage":"transform"}]`
183
+ _, errText, code := ttscTypiaTestCapture(func() int {
184
+ return runTransform([]string{
185
+ "--cwd", project,
186
+ "--tsconfig", "tsconfig.less.json",
187
+ "--file", "src/less.ts",
188
+ "--output", "js",
189
+ "--plugins-json=" + payload,
190
+ })
191
+ })
192
+ if code == 0 || strings.Contains(errText, "unable to order a union of multiple object types") == false {
193
+ t.Fatalf("compare.less did not retain its object-union diagnostic: code=%d stderr=\n%s", code, errText)
194
+ }
195
+ }
196
+
197
+ func compareFunctionalUnionMembershipTSConfig(entry string) string {
198
+ return `{
199
+ "compilerOptions": {
200
+ "target": "ES2022",
201
+ "module": "commonjs",
202
+ "moduleResolution": "bundler",
203
+ "ignoreDeprecations": "6.0",
204
+ "types": ["*"],
205
+ "esModuleInterop": true,
206
+ "strict": true,
207
+ "skipLibCheck": true
208
+ },
209
+ "include": ["` + entry + `"]
210
+ }
211
+ `
212
+ }
213
+
214
+ const compareFunctionalUnionMembershipTypiaIndex = `import * as typia from "./module";
215
+
216
+ export default typia;
217
+ export * from "./module";
218
+ `
219
+
220
+ const compareFunctionalUnionMembershipTypiaModule = `export * as compare from "./compare";
221
+ export * as plain from "./plain";
222
+
223
+ export declare function is<T>(input: unknown): input is T;
224
+ export declare function createIs<T>(): (input: unknown) => input is T;
225
+ `
226
+
227
+ const compareFunctionalUnionMembershipTypiaCompare = `export type Cover<T> = T extends object
228
+ ? { [K in keyof T]?: Cover<T[K]> }
229
+ : T;
230
+
231
+ export declare function equals<T>(x: T, y: T): boolean;
232
+ export declare function cover<T>(x: T, y: Cover<T>): boolean;
233
+ export declare function less<T>(x: T, y: T): boolean;
234
+ export declare function createEquals<T>(): (x: T, y: T) => boolean;
235
+ export declare function createCover<T>(): (x: T, y: Cover<T>) => boolean;
236
+ `
237
+
238
+ const compareFunctionalUnionMembershipTypiaPlain = `export declare function clone<T>(input: T): T;
239
+ export declare function createClone<T>(): (input: T) => T;
240
+ export declare function createPrune<T extends object>(): (input: T) => void;
241
+ `
242
+
243
+ const compareFunctionalUnionMembershipThrowStub = `module.exports._throwTypeGuardError = (props) => {
244
+ const error = new Error("guard: " + props.expected);
245
+ error.name = "TypeGuardError";
246
+ throw error;
247
+ };
248
+ `
249
+
250
+ const compareFunctionalUnionMembershipSource = `import typia from "typia";
251
+
252
+ type FunctionUnion =
253
+ | { handler: (value: number) => string; common: string }
254
+ | { handler: string; common: string; label: string };
255
+ type StringFirstUnion =
256
+ | { handler: string; common: string; label: string }
257
+ | { handler: (value: number) => string; common: string };
258
+ type FunctionSecondUnion =
259
+ | { handler: string; common: string }
260
+ | { handler: (value: number) => string; common: string; label: string };
261
+ type CoverPartial = { common: string; label: string };
262
+ type Nested = { value: FunctionUnion };
263
+ type FunctionSecondNested = { value: FunctionSecondUnion };
264
+ interface Delegated {
265
+ value: string;
266
+ equals(input: Delegated): boolean;
267
+ }
268
+
269
+ export const directIs = (input: unknown): input is FunctionUnion =>
270
+ typia.is<FunctionUnion>(input);
271
+ export const factoryIs = typia.createIs<FunctionUnion>();
272
+ export const directEquals = (x: unknown, y: unknown): boolean =>
273
+ typia.compare.equals<FunctionUnion>(x as FunctionUnion, y as FunctionUnion);
274
+ export const factoryEquals = typia.compare.createEquals<FunctionUnion>();
275
+ export const directCover = (x: FunctionUnion, y: unknown): boolean =>
276
+ typia.compare.cover<FunctionUnion>(x, y as typia.compare.Cover<FunctionUnion>);
277
+ export const factoryCover = typia.compare.createCover<FunctionUnion>();
278
+ export const directClone = (input: FunctionUnion) =>
279
+ typia.plain.clone<FunctionUnion>(input);
280
+ export const factoryClone = typia.plain.createClone<FunctionUnion>();
281
+ export const prune = typia.plain.createPrune<FunctionUnion>();
282
+
283
+ export const reversedEquals = typia.compare.createEquals<StringFirstUnion>();
284
+ export const functionSecondDirectIs = (input: unknown): input is FunctionSecondUnion =>
285
+ typia.is<FunctionSecondUnion>(input);
286
+ export const functionSecondFactoryIs = typia.createIs<FunctionSecondUnion>();
287
+ export const functionSecondDirectEquals = (x: FunctionSecondUnion, y: FunctionSecondUnion): boolean =>
288
+ typia.compare.equals<FunctionSecondUnion>(x, y);
289
+ export const functionSecondFactoryEquals = typia.compare.createEquals<FunctionSecondUnion>();
290
+ export const functionSecondDirectCover = (x: FunctionSecondUnion, y: unknown): boolean =>
291
+ typia.compare.cover<FunctionSecondUnion>(x, y as typia.compare.Cover<FunctionSecondUnion>);
292
+ export const functionSecondFactoryCover = typia.compare.createCover<FunctionSecondUnion>();
293
+ export const coverPartialDirect = (x: CoverPartial, y: unknown): boolean =>
294
+ typia.compare.cover<CoverPartial>(x, y as typia.compare.Cover<CoverPartial>);
295
+ export const coverPartialFactory = typia.compare.createCover<CoverPartial>();
296
+ export const functionSecondNestedDirectEquals = (x: FunctionSecondNested, y: FunctionSecondNested): boolean =>
297
+ typia.compare.equals<FunctionSecondNested>(x, y);
298
+ export const functionSecondNestedFactoryEquals = typia.compare.createEquals<FunctionSecondNested>();
299
+ export const delegatedDirectEquals = (x: Delegated, y: Delegated): boolean =>
300
+ typia.compare.equals<Delegated>(x, y);
301
+ export const delegatedFactoryEquals = typia.compare.createEquals<Delegated>();
302
+ export const nestedEquals = typia.compare.createEquals<Nested>();
303
+ export const nestedDirectEquals = (x: Nested, y: Nested): boolean =>
304
+ typia.compare.equals<Nested>(x, y);
305
+ `
306
+
307
+ const compareFunctionalUnionMembershipLessSource = `import typia from "typia";
308
+
309
+ type FunctionUnion =
310
+ | { handler: (value: number) => string; common: string }
311
+ | { handler: string; common: string; label: string };
312
+
313
+ typia.compare.less<FunctionUnion>({} as FunctionUnion, {} as FunctionUnion);
314
+ `
315
+
316
+ const compareFunctionalUnionMembershipRuntimeRunner = `const functional = require("./functional.cjs");
317
+ const defaults = require("./default.cjs");
318
+
319
+ let ran = 0;
320
+ const failures = [];
321
+ const expect = (name, actual, expected) => {
322
+ ran += 1;
323
+ if (actual !== expected)
324
+ failures.push(name + ": expected " + expected + ", got " + actual);
325
+ };
326
+ const expectJson = (name, actual, expected) =>
327
+ expect(name, JSON.stringify(actual), JSON.stringify(expected));
328
+
329
+ const left = { handler: "text", common: "same", label: "left" };
330
+ const right = { handler: "text", common: "same", label: "right" };
331
+ const equal = { handler: "text", common: "same", label: "left" };
332
+ const invalidLeft = { handler: 1, common: "same", label: "left" };
333
+ const invalidRight = { handler: 1, common: "same", label: "right" };
334
+
335
+ // Functional mode must use handler while routing, then preserve equality's
336
+ // established post-selection treatment of actual function-valued properties.
337
+ expect("functional direct is accepts later member", functional.directIs(left), true);
338
+ expect("functional factory is accepts later member", functional.factoryIs(right), true);
339
+ expect("functional direct equals distinguishes later label", functional.directEquals(left, right), false);
340
+ expect("functional factory equals distinguishes later label", functional.factoryEquals(left, right), false);
341
+ expect("functional direct equals keeps equal later member", functional.directEquals(left, equal), true);
342
+ expect("functional factory equals keeps equal later member", functional.factoryEquals(left, equal), true);
343
+ expect("functional direct cover distinguishes later label", functional.directCover(left, right), false);
344
+ expect("functional factory cover distinguishes later label", functional.factoryCover(left, right), false);
345
+ expectJson("functional direct clone preserves later member", functional.directClone(left), left);
346
+ expectJson("functional factory clone preserves later member", functional.factoryClone(right), right);
347
+
348
+ const pruned = { ...left, extra: true };
349
+ functional.prune(pruned);
350
+ expectJson("functional prune retains selected later label", pruned, left);
351
+ expect("functional reversed union distinguishes later label", functional.reversedEquals(left, right), false);
352
+ expect("functional nested factory distinguishes later label", functional.nestedEquals({ value: left }, { value: right }), false);
353
+ expect("functional nested direct distinguishes later label", functional.nestedDirectEquals({ value: left }, { value: right }), false);
354
+
355
+ expect("functional direct is rejects invalid handler", functional.directIs(invalidLeft), false);
356
+ expect("functional factory is rejects invalid handler", functional.factoryIs(invalidRight), false);
357
+ expect("functional direct equals rejects distinct invalid operands", functional.directEquals(invalidLeft, invalidRight), false);
358
+ expect("functional factory equals rejects distinct invalid operands", functional.factoryEquals(invalidLeft, invalidRight), false);
359
+ expect("functional same invalid reference keeps identity fast path", functional.factoryEquals(invalidLeft, invalidLeft), true);
360
+
361
+ const functionLeft = { handler: (value) => String(value), common: "same" };
362
+ const functionRight = { handler: (value) => "#" + value, common: "same" };
363
+ const functionDifferentCommon = { handler: (value) => String(value), common: "different" };
364
+ expect("functional actual functions keep method identity ignored", functional.factoryEquals(functionLeft, functionRight), true);
365
+ expect("functional actual function member still compares data", functional.factoryEquals(functionLeft, functionDifferentCommon), false);
366
+
367
+ // This is the order-symmetric public-behavior control. The function arm follows
368
+ // the strict string arm and alone owns label. The string matcher must reject an
369
+ // actual function before the later arm is selected, then equality compares label.
370
+ const functionSecondHandler = (value) => String(value);
371
+ const functionSecondLeft = {
372
+ common: "same",
373
+ handler: functionSecondHandler,
374
+ label: "left",
375
+ };
376
+ const functionSecondRight = {
377
+ common: "same",
378
+ handler: functionSecondHandler,
379
+ label: "right",
380
+ };
381
+ const functionSecondEqual = {
382
+ common: "same",
383
+ handler: (value) => "!" + value,
384
+ label: "left",
385
+ };
386
+ const functionSecondString = { handler: "text", common: "same" };
387
+ const functionSecondExtra = { ...functionSecondLeft, extra: "ignored" };
388
+ const functionSecondInvalidLeft = { common: "same", handler: 1, label: "same" };
389
+ const functionSecondInvalidRight = { common: "same", handler: 1, label: "same" };
390
+ const coverPartialFull = { common: "same", label: "left" };
391
+ const coverPartialOmitted = { common: "same" };
392
+ const coverPartialUndefined = { common: "same", label: undefined };
393
+ expect("functional second function arm direct is accepts", functional.functionSecondDirectIs(functionSecondLeft), true);
394
+ expect("functional second function arm factory is accepts", functional.functionSecondFactoryIs(functionSecondRight), true);
395
+ expect("functional second function arm direct is rejects invalid handler", functional.functionSecondDirectIs(functionSecondInvalidLeft), false);
396
+ expect("functional second function arm factory is rejects invalid handler", functional.functionSecondFactoryIs(functionSecondInvalidRight), false);
397
+ expect("functional second function arm direct equals compares label", functional.functionSecondDirectEquals(functionSecondLeft, functionSecondRight), false);
398
+ expect("functional second function arm factory equals compares label", functional.functionSecondFactoryEquals(functionSecondLeft, functionSecondRight), false);
399
+ expect("functional second function arm direct equals rejects invalid equal-label handlers", functional.functionSecondDirectEquals(functionSecondInvalidLeft, functionSecondInvalidRight), false);
400
+ expect("functional second function arm factory equals rejects invalid equal-label handlers", functional.functionSecondFactoryEquals(functionSecondInvalidLeft, functionSecondInvalidRight), false);
401
+ expect("functional second function arm direct cover compares label", functional.functionSecondDirectCover(functionSecondLeft, functionSecondRight), false);
402
+ expect("functional second function arm factory cover compares label", functional.functionSecondFactoryCover(functionSecondLeft, functionSecondRight), false);
403
+ expect("functional second function arm nested direct equals compares label", functional.functionSecondNestedDirectEquals({ value: functionSecondLeft }, { value: functionSecondRight }), false);
404
+ expect("functional second function arm nested factory equals compares label", functional.functionSecondNestedFactoryEquals({ value: functionSecondLeft }, { value: functionSecondRight }), false);
405
+ expect("functional second function arm direct equals keeps equal label", functional.functionSecondDirectEquals(functionSecondLeft, functionSecondEqual), true);
406
+ expect("functional second function arm factory equals keeps equal label", functional.functionSecondFactoryEquals(functionSecondLeft, functionSecondEqual), true);
407
+ expect("functional function-first direct cross-member equals rejects", functional.directEquals(functionLeft, left), false);
408
+ expect("functional function-first factory cross-member equals rejects", functional.factoryEquals(functionLeft, left), false);
409
+ expect("functional function-second direct cross-member equals rejects", functional.functionSecondDirectEquals(functionSecondLeft, functionSecondString), false);
410
+ expect("functional function-second factory cross-member equals rejects", functional.functionSecondFactoryEquals(functionSecondLeft, functionSecondString), false);
411
+ expect("functional direct cover accepts omitted right property", functional.coverPartialDirect(coverPartialFull, coverPartialOmitted), true);
412
+ expect("functional factory cover accepts omitted right property", functional.coverPartialFactory(coverPartialFull, coverPartialOmitted), true);
413
+ expect("functional direct cover accepts undefined right property", functional.coverPartialDirect(coverPartialFull, coverPartialUndefined), true);
414
+ expect("functional factory cover accepts undefined right property", functional.coverPartialFactory(coverPartialFull, coverPartialUndefined), true);
415
+ expect("functional second function arm direct equals ignores extra key", functional.functionSecondDirectEquals(functionSecondLeft, functionSecondExtra), true);
416
+ expect("functional second function arm factory equals ignores extra key", functional.functionSecondFactoryEquals(functionSecondLeft, functionSecondExtra), true);
417
+
418
+ const delegatedLeft = { value: "left", equals: () => true };
419
+ const delegatedRight = { value: "right", equals: () => true };
420
+ expect("functional direct equals delegates declared method", functional.delegatedDirectEquals(delegatedLeft, delegatedRight), true);
421
+ expect("functional factory equals delegates declared method", functional.delegatedFactoryEquals(delegatedLeft, delegatedRight), true);
422
+
423
+ // Default mode deliberately treats a sole function-valued member as lenient.
424
+ // The option boundary must stay visible rather than changing compare globally.
425
+ expect("default direct is keeps function member lenient", defaults.directIs(invalidLeft), true);
426
+ expect("default factory is keeps function member lenient", defaults.factoryIs(invalidRight), true);
427
+ expect("default equals keeps function member ignored", defaults.factoryEquals(invalidLeft, invalidRight), true);
428
+ expect("default second function arm direct equals retains later label", defaults.functionSecondDirectEquals(functionSecondLeft, functionSecondRight), false);
429
+ expect("default second function arm factory equals retains later label", defaults.functionSecondFactoryEquals(functionSecondLeft, functionSecondRight), false);
430
+
431
+ if (failures.length !== 0)
432
+ throw new Error(failures.join("\n"));
433
+ console.log("RAN " + ran + " CASES");
434
+ `
@@ -0,0 +1,98 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ // TestCompareLessNaNTransform verifies NaN-last total ordering.
12
+ //
13
+ // Relational comparison treats NaN as equal to every value because both `<`
14
+ // and `>` return false. The compare contract instead needs a total scalar order
15
+ // so its documented two-direction sort comparator never collapses distinct
16
+ // numeric or Date values.
17
+ //
18
+ // 1. Transform direct and factory comparators over scalars and containers.
19
+ // 2. Exercise NaN, infinities, signed zero, and invalid Date boundaries.
20
+ // 3. Verify antisymmetry and sort composition across nested sibling paths.
21
+ func TestCompareLessNaNTransform(t *testing.T) {
22
+ project := compareEqualCoverProject(t, "compare-less-nan-", compareLessNaNSource)
23
+ js := compareEqualCoverTransform(t, project)
24
+ if !strings.Contains(js, "Number") && !strings.Contains(js, "!==") {
25
+ t.Fatalf("NaN-aware output is missing a numeric discriminator:\n%s", js)
26
+ }
27
+
28
+ node, err := exec.LookPath("node")
29
+ if err != nil {
30
+ t.Skip("node executable not found")
31
+ }
32
+ runtimeDir := filepath.Join(project, "runtime")
33
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
34
+ t.Fatalf("mkdir runtime dir: %v", err)
35
+ }
36
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
37
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(ttscTypiaTestRewriteCommonJS(t, js)), 0o644); err != nil {
38
+ t.Fatalf("write runtime module: %v", err)
39
+ }
40
+ runner := filepath.Join(runtimeDir, "run.cjs")
41
+ if err := os.WriteFile(runner, []byte(compareLessNaNRuntime), 0o644); err != nil {
42
+ t.Fatalf("write runtime runner: %v", err)
43
+ }
44
+ cmd := exec.Command(node, runner)
45
+ cmd.Dir = runtimeDir
46
+ if output, err := cmd.CombinedOutput(); err != nil {
47
+ t.Fatalf("NaN ordering runtime cases failed: %v\n%s", err, output)
48
+ }
49
+ }
50
+
51
+ const compareLessNaNSource = `import typia from "typia";
52
+
53
+ export const lessNumber = typia.compare.createLess<number>();
54
+ export const lessNumberDirect = (x: number, y: number) => typia.compare.less<number>(x, y);
55
+ export const lessDate = typia.compare.createLess<Date>();
56
+ export const lessArray = typia.compare.createLess<number[]>();
57
+ export const lessTuple = typia.compare.createLess<[number, Date]>();
58
+ export const lessNested = typia.compare.createLess<{ value: number }>();
59
+ export const lessMixed = typia.compare.createLess<number | string>();
60
+ `
61
+
62
+ const compareLessNaNRuntime = `const mod = require("./main.cjs");
63
+
64
+ const expect = (label, actual, expected) => {
65
+ if (actual !== expected) throw new Error(label + ": expected " + expected + ", got " + actual);
66
+ };
67
+ const assertPair = (label, less, ordinary, nan) => {
68
+ expect(label + " ordinary < NaN", less(ordinary, nan), true);
69
+ expect(label + " NaN !< ordinary", less(nan, ordinary), false);
70
+ expect(label + " NaN !< NaN", less(nan, nan), false);
71
+ };
72
+
73
+ for (const less of [mod.lessNumber, mod.lessNumberDirect]) {
74
+ assertPair("number", less, 1, Number.NaN);
75
+ expect("-Infinity < finite", less(-Infinity, 0), true);
76
+ expect("finite < Infinity", less(0, Infinity), true);
77
+ expect("signed zero equivalent left", less(-0, 0), false);
78
+ expect("signed zero equivalent right", less(0, -0), false);
79
+ }
80
+
81
+ assertPair("date", mod.lessDate, new Date(0), new Date(Number.NaN));
82
+ assertPair("array", mod.lessArray, [1], [Number.NaN]);
83
+ assertPair("tuple head", mod.lessTuple, [1, new Date(0)], [Number.NaN, new Date(0)]);
84
+ assertPair("tuple date", mod.lessTuple, [1, new Date(0)], [1, new Date(Number.NaN)]);
85
+ assertPair("nested", mod.lessNested, { value: 1 }, { value: Number.NaN });
86
+ assertPair("mixed numeric arm", mod.lessMixed, 1, Number.NaN);
87
+ expect("mixed type rank before numeric rule", mod.lessMixed(Number.NaN, "a"), true);
88
+
89
+ const values = [Number.NaN, Infinity, -1, -Infinity, 0, Number.NaN];
90
+ const comparator = (x, y) => mod.lessNumber(x, y) ? -1 : mod.lessNumber(y, x) ? 1 : 0;
91
+ const sorted = values.slice().sort(comparator);
92
+ expect("sort first", sorted[0], -Infinity);
93
+ expect("sort second", sorted[1], -1);
94
+ expect("sort third", sorted[2], 0);
95
+ expect("sort fourth", sorted[3], Infinity);
96
+ expect("sort NaN tail 1", Number.isNaN(sorted[4]), true);
97
+ expect("sort NaN tail 2", Number.isNaN(sorted[5]), true);
98
+ `