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
@@ -0,0 +1,161 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "testing"
8
+ )
9
+
10
+ // TestCompareNativeObjectOvermatchTransform pins equals/cover over native|object.
11
+ //
12
+ // CompareEqualProgrammer.schema ORs a branch per union member and the object
13
+ // branch (`_eo`) guards only with `typeof === "object" && !Array.isArray`,
14
+ // which a native instance also passes. For `Date | { timestamp: number }` the
15
+ // object branch compares two Dates by the absent `timestamp` key — both
16
+ // `undefined`, so it reports them equal, and the OR accepts even though the
17
+ // Date branch (comparing getTime) correctly said not-equal. The object branch
18
+ // must never claim a value a sibling native branch owns. This test drives Date,
19
+ // Uint8Array, and RegExp unioned with an object, in both orders, and requires
20
+ // two different natives to compare not-equal while every legitimate pair and
21
+ // the native-alone / object-alone controls are unchanged.
22
+ //
23
+ // 1. Transform equals/cover factories over native|object and object|native.
24
+ // 2. Require two different natives to compare not-equal (equals and cover).
25
+ // 3. Require same natives, plain-object pairs, and the native-alone control
26
+ // to keep their correct equal / not-equal results.
27
+ func TestCompareNativeObjectOvermatchTransform(t *testing.T) {
28
+ project := compareNativeObjectOvermatchProject(t)
29
+ out, errText, code := ttscTypiaTestCapture(func() int {
30
+ return runTransform([]string{
31
+ "--cwd", project,
32
+ "--tsconfig", "tsconfig.json",
33
+ "--file", "src/main.ts",
34
+ "--output", "js",
35
+ })
36
+ })
37
+ if code != 0 {
38
+ t.Fatalf("compare native/object over-match transform failed: code=%d stderr=\n%s", code, errText)
39
+ }
40
+ compareNativeObjectOvermatchRunRuntimeCases(t, project, out)
41
+ }
42
+
43
+ func compareNativeObjectOvermatchProject(t *testing.T) string {
44
+ t.Helper()
45
+ root := ttscTypiaTestRepoRoot(t)
46
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
47
+ if err := os.MkdirAll(base, 0o755); err != nil {
48
+ t.Fatalf("mkdir temp base: %v", err)
49
+ }
50
+ dir, err := os.MkdirTemp(base, "compare-native-object-")
51
+ if err != nil {
52
+ t.Fatalf("create temp fixture: %v", err)
53
+ }
54
+ t.Cleanup(func() {
55
+ _ = os.RemoveAll(dir)
56
+ })
57
+ src := filepath.Join(dir, "src")
58
+ if err := os.MkdirAll(src, 0o755); err != nil {
59
+ t.Fatalf("mkdir fixture src: %v", err)
60
+ }
61
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareNativeObjectOvermatchTSConfig), 0o644); err != nil {
62
+ t.Fatalf("write tsconfig: %v", err)
63
+ }
64
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareNativeObjectOvermatchSource), 0o644); err != nil {
65
+ t.Fatalf("write source: %v", err)
66
+ }
67
+ return dir
68
+ }
69
+
70
+ func compareNativeObjectOvermatchRunRuntimeCases(t *testing.T, project string, js string) {
71
+ t.Helper()
72
+ node, err := exec.LookPath("node")
73
+ if err != nil {
74
+ t.Skip("node executable not found")
75
+ }
76
+ runtimeDir := filepath.Join(project, "runtime")
77
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
78
+ t.Fatalf("mkdir runtime dir: %v", err)
79
+ }
80
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
81
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
82
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
83
+ t.Fatalf("write runtime module: %v", err)
84
+ }
85
+ runner := filepath.Join(runtimeDir, "run.cjs")
86
+ if err := os.WriteFile(runner, []byte(compareNativeObjectOvermatchRuntimeRunner), 0o644); err != nil {
87
+ t.Fatalf("write runtime runner: %v", err)
88
+ }
89
+ cmd := exec.Command(node, runner)
90
+ cmd.Dir = runtimeDir
91
+ output, err := cmd.CombinedOutput()
92
+ if err != nil {
93
+ t.Fatalf("compare native/object over-match runtime cases failed: %v\n%s", err, output)
94
+ }
95
+ }
96
+
97
+ const compareNativeObjectOvermatchTSConfig = `{
98
+ "compilerOptions": {
99
+ "target": "ES2022",
100
+ "module": "commonjs",
101
+ "moduleResolution": "bundler",
102
+ "ignoreDeprecations": "6.0",
103
+ "types": ["*"],
104
+ "esModuleInterop": true,
105
+ "strict": true,
106
+ "skipLibCheck": true
107
+ },
108
+ "include": ["src"]
109
+ }
110
+ `
111
+
112
+ const compareNativeObjectOvermatchSource = `import typia, { compare } from "typia";
113
+
114
+ interface IStamp {
115
+ timestamp: number;
116
+ }
117
+ interface ISource {
118
+ source: string;
119
+ }
120
+
121
+ export const equalDateObj = typia.compare.createEquals<Date | IStamp>();
122
+ export const coverDateObj = typia.compare.createCover<Date | IStamp>();
123
+ export const equalObjDate = typia.compare.createEquals<IStamp | Date>();
124
+ export const equalBytesObj = typia.compare.createEquals<Uint8Array | IStamp>();
125
+ export const equalRegExpObj = typia.compare.createEquals<RegExp | ISource>();
126
+
127
+ // controls: the native alone and the object alone must be unchanged.
128
+ export const equalDate = typia.compare.createEquals<Date>();
129
+ export const equalStamp = typia.compare.createEquals<IStamp>();
130
+ `
131
+
132
+ const compareNativeObjectOvermatchRuntimeRunner = `const mod = require("./main.cjs");
133
+
134
+ const expect = (label, actual, expected) => {
135
+ if (actual !== expected) {
136
+ throw new Error(label + ": expected " + expected + ", got " + actual);
137
+ }
138
+ };
139
+
140
+ // Two different natives must NOT be reported equal by the object branch.
141
+ expect("Date|obj: two different Dates equal", mod.equalDateObj(new Date(0), new Date(5000)), false);
142
+ expect("Date|obj: cover two different Dates", mod.coverDateObj(new Date(0), new Date(5000)), false);
143
+ expect("obj|Date: two different Dates equal", mod.equalObjDate(new Date(0), new Date(5000)), false);
144
+ expect("Bytes|obj: different bytes equal", mod.equalBytesObj(new Uint8Array([1, 2, 3]), new Uint8Array([9, 9, 9])), false);
145
+ expect("Bytes|obj: one-byte diff equal", mod.equalBytesObj(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 4])), false);
146
+ expect("RegExp|obj: same source diff flags equal", mod.equalRegExpObj(/a/g, /a/i), false);
147
+
148
+ // Legitimate equal cases must be preserved.
149
+ expect("Date|obj: same Date equal", mod.equalDateObj(new Date(0), new Date(0)), true);
150
+ expect("Date|obj: cover same Date", mod.coverDateObj(new Date(0), new Date(0)), true);
151
+ expect("Date|obj: stamp object equal", mod.equalDateObj({ timestamp: 5 }, { timestamp: 5 }), true);
152
+ expect("Date|obj: stamp object not equal", mod.equalDateObj({ timestamp: 5 }, { timestamp: 9 }), false);
153
+ expect("Bytes|obj: same bytes equal", mod.equalBytesObj(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3])), true);
154
+ expect("RegExp|obj: identical regexp equal", mod.equalRegExpObj(/a/g, /a/g), true);
155
+
156
+ // Controls: native alone and object alone are unchanged.
157
+ expect("control Date: equal", mod.equalDate(new Date(0), new Date(0)), true);
158
+ expect("control Date: not equal", mod.equalDate(new Date(0), new Date(5000)), false);
159
+ expect("control Stamp: equal", mod.equalStamp({ timestamp: 5 }, { timestamp: 5 }), true);
160
+ expect("control Stamp: not equal", mod.equalStamp({ timestamp: 5 }, { timestamp: 9 }), false);
161
+ `
@@ -0,0 +1,343 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ // TestCompareNonDiscriminableUnionTransform pins compare.equals over an object
12
+ // union no discriminant can split (issue #2225).
13
+ //
14
+ // #2214 discriminated the object unions UnionPredicator can specialize, but left
15
+ // every other object union on the pre-#2214 flat OR of member comparators.
16
+ // UnionPredicator.Object skips a key that is not required, so a union whose
17
+ // distinguishing keys are all optional (`{ a?: number } | { b?: string }`)
18
+ // produced no specialization and always took that fallback — which is the very
19
+ // defect #2214 removed: the wrong member's comparator matches because the keys
20
+ // it declares are absent from both operands and compare `undefined ===
21
+ // undefined`, while the keys that actually differ are not declared by that
22
+ // member at all. So `equals({ a: 1 }, { a: 2 })` and even `equals({ a: 1 }, {})`
23
+ // were `true` for distinct references.
24
+ //
25
+ // The fix routes such a union through the first-is-match ladder that
26
+ // clone/classify/prune reach via Decode_union_object: each operand resolves to
27
+ // the first member it structurally matches, distinct members compare false, and
28
+ // a shared member's comparator decides the rest. `equals` therefore agrees with
29
+ // what `clone` produces for the same value.
30
+ //
31
+ // All fixtures compare DISTINCT references (fresh object literals) so the
32
+ // `x === y` identity fast path never hides the flaw.
33
+ //
34
+ // 1. Transform is + compare.createEquals + plain.createClone over
35
+ // all-optional, shared-optional-key, three-member, empty-member,
36
+ // discriminable/non-discriminable mixed, nested, recursive, container-valued
37
+ // and native-bearing non-discriminable unions.
38
+ // 2. Require distinct-but-different values to compare not-equal (a populated
39
+ // object never equals `{}`), distinct-but-identical values to compare equal.
40
+ // 3. Require `equals` to agree with `clone` over every ordered sample pair of
41
+ // `is`-valid values, and to be false whenever either operand fails `is`.
42
+ func TestCompareNonDiscriminableUnionTransform(t *testing.T) {
43
+ project := compareNonDiscriminableUnionProject(t)
44
+ out, errText, code := ttscTypiaTestCapture(func() int {
45
+ return runTransform([]string{
46
+ "--cwd", project,
47
+ "--tsconfig", "tsconfig.json",
48
+ "--file", "src/main.ts",
49
+ "--output", "js",
50
+ })
51
+ })
52
+ if code != 0 {
53
+ t.Fatalf("compare non-discriminable union transform failed: code=%d stderr=\n%s", code, errText)
54
+ }
55
+ if strings.Contains(out, "_ui0") == false {
56
+ t.Fatalf("expected the is-match member matchers in the emit, got:\n%s", out)
57
+ }
58
+ compareNonDiscriminableUnionRunRuntimeCases(t, project, out)
59
+ }
60
+
61
+ func compareNonDiscriminableUnionProject(t *testing.T) string {
62
+ t.Helper()
63
+ root := ttscTypiaTestRepoRoot(t)
64
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
65
+ if err := os.MkdirAll(base, 0o755); err != nil {
66
+ t.Fatalf("mkdir temp base: %v", err)
67
+ }
68
+ dir, err := os.MkdirTemp(base, "compare-union-nondisc-")
69
+ if err != nil {
70
+ t.Fatalf("create temp fixture: %v", err)
71
+ }
72
+ t.Cleanup(func() {
73
+ _ = os.RemoveAll(dir)
74
+ })
75
+ src := filepath.Join(dir, "src")
76
+ if err := os.MkdirAll(src, 0o755); err != nil {
77
+ t.Fatalf("mkdir fixture src: %v", err)
78
+ }
79
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareNonDiscriminableUnionTSConfig), 0o644); err != nil {
80
+ t.Fatalf("write tsconfig: %v", err)
81
+ }
82
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareNonDiscriminableUnionSource), 0o644); err != nil {
83
+ t.Fatalf("write source: %v", err)
84
+ }
85
+ return dir
86
+ }
87
+
88
+ func compareNonDiscriminableUnionRunRuntimeCases(t *testing.T, project string, js string) {
89
+ t.Helper()
90
+ node, err := exec.LookPath("node")
91
+ if err != nil {
92
+ t.Skip("node executable not found")
93
+ }
94
+ runtimeDir := filepath.Join(project, "runtime")
95
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
96
+ t.Fatalf("mkdir runtime dir: %v", err)
97
+ }
98
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
99
+ if err := os.WriteFile(filepath.Join(runtimeDir, "throw-type-guard-error-stub.cjs"), []byte(compareNonDiscriminableUnionThrowStub), 0o644); err != nil {
100
+ t.Fatalf("write throw stub: %v", err)
101
+ }
102
+ js = strings.ReplaceAll(js, `require("typia/lib/internal/_throwTypeGuardError")`, `require("./throw-type-guard-error-stub.cjs")`)
103
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
104
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
105
+ t.Fatalf("write runtime module: %v", err)
106
+ }
107
+ runner := filepath.Join(runtimeDir, "run.cjs")
108
+ if err := os.WriteFile(runner, []byte(compareNonDiscriminableUnionRuntimeRunner), 0o644); err != nil {
109
+ t.Fatalf("write runtime runner: %v", err)
110
+ }
111
+ cmd := exec.Command(node, runner)
112
+ cmd.Dir = runtimeDir
113
+ output, err := cmd.CombinedOutput()
114
+ if err != nil {
115
+ t.Fatalf("compare non-discriminable union runtime cases failed: %v\n%s", err, output)
116
+ }
117
+ }
118
+
119
+ const compareNonDiscriminableUnionTSConfig = `{
120
+ "compilerOptions": {
121
+ "target": "ES2022",
122
+ "module": "commonjs",
123
+ "moduleResolution": "bundler",
124
+ "ignoreDeprecations": "6.0",
125
+ "types": ["*"],
126
+ "esModuleInterop": true,
127
+ "strict": true,
128
+ "skipLibCheck": true
129
+ },
130
+ "include": ["src"]
131
+ }
132
+ `
133
+
134
+ const compareNonDiscriminableUnionThrowStub = `module.exports._throwTypeGuardError = (props) => {
135
+ const error = new Error("guard: " + props.expected);
136
+ error.name = "TypeGuardError";
137
+ throw error;
138
+ };
139
+ `
140
+
141
+ const compareNonDiscriminableUnionSource = `import typia from "typia";
142
+
143
+ // 1. the canonical all-optional union: no member has a unique required key
144
+ type Opt = { a?: number } | { b?: string };
145
+ export const isOpt = typia.createIs<Opt>();
146
+ export const eqOpt = typia.compare.createEquals<Opt>();
147
+ export const cloneOpt = typia.plain.createClone<Opt>();
148
+
149
+ // 2. a key shared by both members, still no required discriminant
150
+ type Shared = { a?: number; c?: boolean } | { b?: string; c?: boolean };
151
+ export const isShared = typia.createIs<Shared>();
152
+ export const eqShared = typia.compare.createEquals<Shared>();
153
+ export const cloneShared = typia.plain.createClone<Shared>();
154
+
155
+ // 3. three all-optional members
156
+ type Three = { a?: number } | { b?: string } | { c?: boolean };
157
+ export const isThree = typia.createIs<Three>();
158
+ export const eqThree = typia.compare.createEquals<Three>();
159
+ export const cloneThree = typia.plain.createClone<Three>();
160
+
161
+ // 4. a member that declares nothing, so it matches every object
162
+ type WithEmpty = { a?: number } | { [key: string]: never };
163
+ export const isWithEmpty = typia.createIs<WithEmpty>();
164
+ export const eqWithEmpty = typia.compare.createEquals<WithEmpty>();
165
+
166
+ // 5. a discriminable member alongside a non-discriminable pair
167
+ type Mixed = { type: "a"; x: number } | { p?: number } | { q?: string };
168
+ export const isMixed = typia.createIs<Mixed>();
169
+ export const eqMixed = typia.compare.createEquals<Mixed>();
170
+ export const cloneMixed = typia.plain.createClone<Mixed>();
171
+
172
+ // 6. a nested non-discriminable union property
173
+ type Nested = { wrap: { a?: number } | { b?: string } };
174
+ export const isNested = typia.createIs<Nested>();
175
+ export const eqNested = typia.compare.createEquals<Nested>();
176
+ export const cloneNested = typia.plain.createClone<Nested>();
177
+
178
+ // 7. container-valued members: the array and tuple checks in the matcher are
179
+ // what routes a value, since the two members share their only key
180
+ type Container = { value?: number[] } | { value?: [number, string] };
181
+ export const isContainer = typia.createIs<Container>();
182
+ export const eqContainer = typia.compare.createEquals<Container>();
183
+ export const cloneContainer = typia.plain.createClone<Container>();
184
+
185
+ // 8. a recursive non-discriminable union (matcher must not recurse forever at
186
+ // generation time, and the comparator still receives its _vctx)
187
+ type Rec = { child?: Rec; a?: number } | { b?: string };
188
+ export const isRec = typia.createIs<Rec>();
189
+ export const eqRec = typia.compare.createEquals<Rec>();
190
+
191
+ // 9. a native alongside a non-discriminable object union (notNatives guard)
192
+ type WithNative = Date | { a?: number } | { b?: string };
193
+ export const eqWithNative = typia.compare.createEquals<WithNative>();
194
+
195
+ // controls that must keep the discriminated / flat forms
196
+ export const eqDisc = typia.compare.createEquals<
197
+ { type: "a"; x: number } | { type: "b"; y: string }
198
+ >();
199
+ export const eqPrim = typia.compare.createEquals<string | number>();
200
+ export const eqArrUnion = typia.compare.createEquals<number[] | string[]>();
201
+ export const eqObj = typia.compare.createEquals<{ a?: number; b?: string }>();
202
+ `
203
+
204
+ const compareNonDiscriminableUnionRuntimeRunner = `const mod = require("./main.cjs");
205
+
206
+ let failures = 0;
207
+ const expect = (label, actual, expected) => {
208
+ if (actual !== expected) {
209
+ console.log("FAIL " + label + ": expected " + expected + ", got " + actual);
210
+ failures++;
211
+ }
212
+ };
213
+ const copy = (v) => JSON.parse(JSON.stringify(v));
214
+ // Serialize a clone so that a key the resolved member declares but the value
215
+ // omits stays visible: JSON.stringify drops an undefined-valued key, which would
216
+ // make two members that declare different keys look alike.
217
+ const shape = (v) => JSON.stringify(v, (_key, value) => (value === undefined ? null : value));
218
+
219
+ // --- 1. the reported defect: {a?:number} | {b?:string} ---
220
+ expect("opt a different", mod.eqOpt({ a: 1 }, { a: 2 }), false);
221
+ expect("opt populated vs empty", mod.eqOpt({ a: 1 }, {}), false);
222
+ expect("opt empty vs populated", mod.eqOpt({}, { a: 1 }), false);
223
+ expect("opt cross member", mod.eqOpt({ a: 1 }, { b: "p" }), false);
224
+ expect("opt identical", mod.eqOpt({ a: 1 }, { a: 1 }), true);
225
+ expect("opt both empty", mod.eqOpt({}, {}), true);
226
+ // both values resolve to the first member, under which "b" is not declared:
227
+ // exactly what clone keeps, so equals must agree with clone rather than with
228
+ // the raw literals.
229
+ expect("opt second-member payload follows clone", mod.eqOpt({ b: "p" }, { b: "q" }), JSON.stringify(mod.cloneOpt({ b: "p" })) === JSON.stringify(mod.cloneOpt({ b: "q" })));
230
+ expect("opt member resolution follows clone", mod.eqOpt({}, { a: "x" }), false);
231
+ expect("opt invalid operand", mod.eqOpt({ a: "x", b: 1 }, { a: "x", b: 1 }), false);
232
+
233
+ // --- 2. shared optional key ---
234
+ expect("shared c different", mod.eqShared({ c: true }, { c: false }), false);
235
+ expect("shared c identical", mod.eqShared({ a: 1, c: true }, { a: 1, c: true }), true);
236
+ expect("shared a different", mod.eqShared({ a: 1, c: true }, { a: 2, c: true }), false);
237
+ expect("shared populated vs empty", mod.eqShared({ a: 1 }, {}), false);
238
+ expect("shared c only vs empty", mod.eqShared({ c: true }, {}), false);
239
+
240
+ // --- 3. three all-optional members ---
241
+ expect("three a different", mod.eqThree({ a: 1 }, { a: 2 }), false);
242
+ expect("three populated vs empty", mod.eqThree({ a: 1 }, {}), false);
243
+ expect("three identical", mod.eqThree({ a: 1 }, { a: 1 }), true);
244
+ expect("three cross member", mod.eqThree({ a: 1 }, { c: true }), false);
245
+
246
+ // --- 4. member matching everything ---
247
+ expect("withempty a different", mod.eqWithEmpty({ a: 1 }, { a: 2 }), false);
248
+ expect("withempty populated vs empty", mod.eqWithEmpty({ a: 1 }, {}), false);
249
+ expect("withempty identical", mod.eqWithEmpty({ a: 1 }, { a: 1 }), true);
250
+
251
+ // --- 5. discriminable member beside a non-discriminable pair ---
252
+ expect("mixed disc different", mod.eqMixed({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
253
+ expect("mixed disc identical", mod.eqMixed({ type: "a", x: 1 }, { type: "a", x: 1 }), true);
254
+ expect("mixed disc vs optional", mod.eqMixed({ type: "a", x: 1 }, { p: 1 }), false);
255
+ expect("mixed optional different", mod.eqMixed({ p: 1 }, { p: 2 }), false);
256
+ expect("mixed optional vs empty", mod.eqMixed({ p: 1 }, {}), false);
257
+ expect("mixed optional identical", mod.eqMixed({ p: 1 }, { p: 1 }), true);
258
+
259
+ // --- 6. nested non-discriminable union property ---
260
+ expect("nested inner different", mod.eqNested({ wrap: { a: 1 } }, { wrap: { a: 2 } }), false);
261
+ expect("nested inner populated vs empty", mod.eqNested({ wrap: { a: 1 } }, { wrap: {} }), false);
262
+ expect("nested inner identical", mod.eqNested({ wrap: { a: 1 } }, { wrap: { a: 1 } }), true);
263
+ expect("nested cross member", mod.eqNested({ wrap: { a: 1 } }, { wrap: { b: "p" } }), false);
264
+
265
+ // --- 7. container-valued members ---
266
+ expect("container array different", mod.eqContainer({ value: [1, 2] }, { value: [1, 3] }), false);
267
+ expect("container array identical", mod.eqContainer({ value: [1, 2] }, { value: [1, 2] }), true);
268
+ expect("container array vs empty", mod.eqContainer({ value: [1] }, {}), false);
269
+ expect("container tuple different", mod.eqContainer({ value: [1, "p"] }, { value: [1, "q"] }), false);
270
+ expect("container tuple identical", mod.eqContainer({ value: [1, "p"] }, { value: [1, "p"] }), true);
271
+ expect("container cross member", mod.eqContainer({ value: [1] }, { value: [1, "p"] }), false);
272
+
273
+ // --- 8. recursive non-discriminable union ---
274
+ const mkRec = () => ({ a: 1, child: { a: 2, child: { a: 3 } } });
275
+ expect("rec identical", mod.eqRec(mkRec(), mkRec()), true);
276
+ expect("rec deep different", mod.eqRec(mkRec(), { a: 1, child: { a: 2, child: { a: 9 } } }), false);
277
+ expect("rec depth different", mod.eqRec(mkRec(), { a: 1, child: { a: 2 } }), false);
278
+ expect("rec populated vs empty", mod.eqRec(mkRec(), {}), false);
279
+
280
+ // --- 9. native beside the non-discriminable union ---
281
+ expect("withnative same date", mod.eqWithNative(new Date(0), new Date(0)), true);
282
+ expect("withnative diff date", mod.eqWithNative(new Date(0), new Date(5000)), false);
283
+ expect("withnative date vs object", mod.eqWithNative(new Date(0), { a: 1 }), false);
284
+ expect("withnative object different", mod.eqWithNative({ a: 1 }, { a: 2 }), false);
285
+ expect("withnative object identical", mod.eqWithNative({ a: 1 }, { a: 1 }), true);
286
+ expect("withnative populated vs empty", mod.eqWithNative({ a: 1 }, {}), false);
287
+
288
+ // --- controls: the discriminated path and the non-union paths are untouched ---
289
+ expect("disc different", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
290
+ expect("disc identical", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 1 }), true);
291
+ expect("disc cross arm", mod.eqDisc({ type: "a", x: 1 }, { type: "b", y: "p" }), false);
292
+ expect("prim different", mod.eqPrim(1, 2), false);
293
+ expect("prim identical", mod.eqPrim("x", "x"), true);
294
+ expect("arrunion different", mod.eqArrUnion([1, 2], [1, 3]), false);
295
+ expect("arrunion identical", mod.eqArrUnion([1, 2], [1, 2]), true);
296
+ expect("obj optional different", mod.eqObj({ a: 1 }, { a: 2 }), false);
297
+ expect("obj optional vs empty", mod.eqObj({ a: 1 }, {}), false);
298
+ expect("obj optional identical", mod.eqObj({ a: 1 }, { a: 1 }), true);
299
+
300
+ // --- equals agrees with is and with the member clone resolves to ---
301
+ // For every ordered pair of samples (distinct references throughout):
302
+ // * an operand is rejects is never equal to anything, and
303
+ // * two is-valid operands are equal exactly when their clones are, which is
304
+ // the statement "both resolved to the same member and agree on everything
305
+ // that member declares".
306
+ const agree = (label, eq, is, clone, samples) => {
307
+ for (const a of samples)
308
+ for (const b of samples) {
309
+ const x = copy(a);
310
+ const y = copy(b);
311
+ const suffix = " " + JSON.stringify(a) + " | " + JSON.stringify(b);
312
+ if (is(x) === false || is(y) === false) {
313
+ expect(label + " invalid operand not equal" + suffix, eq(x, y), false);
314
+ continue;
315
+ }
316
+ expect(label + " equals agrees with clone" + suffix, eq(x, y), shape(clone(x)) === shape(clone(y)));
317
+ }
318
+ };
319
+
320
+ agree("opt", mod.eqOpt, mod.isOpt, mod.cloneOpt, [
321
+ {}, { a: 1 }, { a: 2 }, { b: "p" }, { b: "q" }, { a: 1, b: "p" }, { a: "x", b: 1 }, { a: "x" },
322
+ ]);
323
+ agree("shared", mod.eqShared, mod.isShared, mod.cloneShared, [
324
+ {}, { a: 1 }, { c: true }, { c: false }, { a: 1, c: true }, { b: "p" }, { b: "p", c: true }, { a: "x", b: 1 },
325
+ ]);
326
+ agree("three", mod.eqThree, mod.isThree, mod.cloneThree, [
327
+ {}, { a: 1 }, { b: "p" }, { c: true }, { c: false }, { a: 1, c: true }, { a: "x", b: 1, c: 2 },
328
+ ]);
329
+ agree("mixed", mod.eqMixed, mod.isMixed, mod.cloneMixed, [
330
+ {}, { type: "a", x: 1 }, { type: "a", x: 2 }, { p: 1 }, { p: 2 }, { q: "z" },
331
+ ]);
332
+ agree("nested", mod.eqNested, mod.isNested, mod.cloneNested, [
333
+ { wrap: {} }, { wrap: { a: 1 } }, { wrap: { a: 2 } }, { wrap: { b: "p" } },
334
+ ]);
335
+ agree("container", mod.eqContainer, mod.isContainer, mod.cloneContainer, [
336
+ {}, { value: [] }, { value: [1] }, { value: [1, 2] }, { value: [1, "p"] }, { value: [2, "p"] },
337
+ ]);
338
+
339
+ if (failures > 0) {
340
+ throw new Error(failures + " assertion(s) failed");
341
+ }
342
+ console.log("all compare-non-discriminable-union cases passed");
343
+ `