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,241 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ // TestCompareTemplateLiteralUnionTransform verifies template-literal object
12
+ // union members retain their runtime domains during equality dispatch.
13
+ //
14
+ // The #2225 first-match fallback must use the same structural template
15
+ // membership decision as is and clone. Weakening both template domains to
16
+ // `typeof string` routes valid `b_*` values through the `a_*` comparator and
17
+ // drops `b`.
18
+ //
19
+ // 1. Transform direct and factory is, clone, and equals calls for a tag-free
20
+ // template-literal object union and the same union nested in an object.
21
+ // 2. Prove is accepts both witnesses and clone selects the `b_*` member while
22
+ // preserving their different `b` values.
23
+ // 3. Exercise equal, cross-member, invalid-discriminator, nested, literal-
24
+ // discriminated, non-discriminable, and non-union controls at runtime.
25
+ func TestCompareTemplateLiteralUnionTransform(t *testing.T) {
26
+ project := compareTemplateLiteralUnionProject(t)
27
+ out, errText, code := ttscTypiaTestCapture(func() int {
28
+ return runTransform([]string{
29
+ "--cwd", project,
30
+ "--tsconfig", "tsconfig.json",
31
+ "--file", "src/main.ts",
32
+ "--output", "js",
33
+ })
34
+ })
35
+ if code != 0 {
36
+ t.Fatalf("compare template-literal union transform failed: code=%d stderr=\n%s", code, errText)
37
+ }
38
+ compareTemplateLiteralUnionRunRuntimeCases(t, project, out)
39
+ }
40
+
41
+ func compareTemplateLiteralUnionProject(t *testing.T) string {
42
+ t.Helper()
43
+ root := ttscTypiaTestRepoRoot(t)
44
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
45
+ if err := os.MkdirAll(base, 0o755); err != nil {
46
+ t.Fatalf("mkdir temp base: %v", err)
47
+ }
48
+ dir, err := os.MkdirTemp(base, "compare-template-literal-union-")
49
+ if err != nil {
50
+ t.Fatalf("create temp fixture: %v", err)
51
+ }
52
+ t.Cleanup(func() {
53
+ _ = os.RemoveAll(dir)
54
+ })
55
+ src := filepath.Join(dir, "src")
56
+ if err := os.MkdirAll(src, 0o755); err != nil {
57
+ t.Fatalf("mkdir fixture src: %v", err)
58
+ }
59
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareTemplateLiteralUnionTSConfig), 0o644); err != nil {
60
+ t.Fatalf("write tsconfig: %v", err)
61
+ }
62
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareTemplateLiteralUnionSource), 0o644); err != nil {
63
+ t.Fatalf("write source: %v", err)
64
+ }
65
+ return dir
66
+ }
67
+
68
+ func compareTemplateLiteralUnionRunRuntimeCases(t *testing.T, project string, js string) {
69
+ t.Helper()
70
+ node, err := exec.LookPath("node")
71
+ if err != nil {
72
+ t.Skip("node executable not found")
73
+ }
74
+ runtimeDir := filepath.Join(project, "runtime")
75
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
76
+ t.Fatalf("mkdir runtime dir: %v", err)
77
+ }
78
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
79
+ if err := os.WriteFile(filepath.Join(runtimeDir, "throw-type-guard-error-stub.cjs"), []byte(compareTemplateLiteralUnionThrowStub), 0o644); err != nil {
80
+ t.Fatalf("write throw stub: %v", err)
81
+ }
82
+ js = strings.ReplaceAll(js, `require("typia/lib/internal/_throwTypeGuardError")`, `require("./throw-type-guard-error-stub.cjs")`)
83
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
84
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
85
+ t.Fatalf("write runtime module: %v", err)
86
+ }
87
+ runner := filepath.Join(runtimeDir, "run.cjs")
88
+ if err := os.WriteFile(runner, []byte(compareTemplateLiteralUnionRuntimeRunner), 0o644); err != nil {
89
+ t.Fatalf("write runtime runner: %v", err)
90
+ }
91
+ cmd := exec.Command(node, runner)
92
+ cmd.Dir = runtimeDir
93
+ output, err := cmd.CombinedOutput()
94
+ if err != nil {
95
+ t.Fatalf("compare template-literal union runtime cases failed: %v\n%s", err, output)
96
+ }
97
+ }
98
+
99
+ const compareTemplateLiteralUnionTSConfig = `{
100
+ "compilerOptions": {
101
+ "target": "ES2022",
102
+ "module": "commonjs",
103
+ "moduleResolution": "bundler",
104
+ "ignoreDeprecations": "6.0",
105
+ "types": ["*"],
106
+ "esModuleInterop": true,
107
+ "strict": true,
108
+ "skipLibCheck": true
109
+ },
110
+ "include": ["src"]
111
+ }
112
+ `
113
+
114
+ const compareTemplateLiteralUnionThrowStub = `module.exports._throwTypeGuardError = (props) => {
115
+ const error = new Error("guard: " + props.expected);
116
+ error.name = "TypeGuardError";
117
+ throw error;
118
+ };
119
+ `
120
+
121
+ const compareTemplateLiteralUnionSource = `import typia from "typia";
122
+
123
+ type TemplateUnion =
124
+ | { kind: ` + "`a_${string}`" + `; common: string }
125
+ | { kind: ` + "`b_${string}`" + `; common: string; b?: string };
126
+ type Nested = { value: TemplateUnion };
127
+
128
+ export const isTemplate = typia.createIs<TemplateUnion>();
129
+ export const cloneTemplate = typia.plain.createClone<TemplateUnion>();
130
+ export const eqTemplateFactory = typia.compare.createEquals<TemplateUnion>();
131
+ export const eqTemplateDirect = (x: TemplateUnion, y: TemplateUnion) =>
132
+ typia.compare.equals<TemplateUnion>(x, y);
133
+
134
+ export const isNested = typia.createIs<Nested>();
135
+ export const cloneNested = typia.plain.createClone<Nested>();
136
+ export const eqNestedFactory = typia.compare.createEquals<Nested>();
137
+ export const eqNestedDirect = (x: Nested, y: Nested) =>
138
+ typia.compare.equals<Nested>(x, y);
139
+
140
+ export const eqLiteral = typia.compare.createEquals<
141
+ { kind: "a"; value: number } | { kind: "b"; value: string }
142
+ >();
143
+ export const eqOptional = typia.compare.createEquals<
144
+ { a?: number } | { b?: string }
145
+ >();
146
+ export const eqPlain = typia.compare.createEquals<{
147
+ kind: string;
148
+ common: string;
149
+ b?: string;
150
+ }>();
151
+ `
152
+
153
+ const compareTemplateLiteralUnionRuntimeRunner = `const mod = require("./main.cjs");
154
+
155
+ let failures = 0;
156
+ const expect = (label, actual, expected) => {
157
+ if (actual !== expected) {
158
+ console.log("FAIL " + label + ": expected " + expected + ", got " + actual);
159
+ failures++;
160
+ }
161
+ };
162
+ const expectJson = (label, actual, expected) =>
163
+ expect(label, JSON.stringify(actual), JSON.stringify(expected));
164
+
165
+ const left = { kind: "b_x", common: "same", b: "left" };
166
+ const right = { kind: "b_x", common: "same", b: "right" };
167
+ expect("is left b member", mod.isTemplate(left), true);
168
+ expect("is right b member", mod.isTemplate(right), true);
169
+ expectJson("clone left preserves b", mod.cloneTemplate(left), left);
170
+ expectJson("clone right preserves b", mod.cloneTemplate(right), right);
171
+ expect("factory different b", mod.eqTemplateFactory(left, right), false);
172
+ expect("direct different b", mod.eqTemplateDirect(left, right), false);
173
+
174
+ expect("factory equal b", mod.eqTemplateFactory(
175
+ { kind: "b_x", common: "same", b: "same" },
176
+ { kind: "b_x", common: "same", b: "same" },
177
+ ), true);
178
+ expect("direct equal b", mod.eqTemplateDirect(
179
+ { kind: "b_x", common: "same", b: "same" },
180
+ { kind: "b_x", common: "same", b: "same" },
181
+ ), true);
182
+ expect("a member different common", mod.eqTemplateFactory(
183
+ { kind: "a_x", common: "left" },
184
+ { kind: "a_x", common: "right" },
185
+ ), false);
186
+ expect("a member equal", mod.eqTemplateFactory(
187
+ { kind: "a_x", common: "same" },
188
+ { kind: "a_x", common: "same" },
189
+ ), true);
190
+ expect("a versus b", mod.eqTemplateFactory(
191
+ { kind: "a_x", common: "same" },
192
+ { kind: "b_x", common: "same" },
193
+ ), false);
194
+
195
+ const invalidLeft = { kind: "c_x", common: "same" };
196
+ const invalidRight = { kind: "c_x", common: "same" };
197
+ expect("is rejects invalid discriminator", mod.isTemplate(invalidLeft), false);
198
+ expect("factory rejects invalid discriminator", mod.eqTemplateFactory(invalidLeft, invalidRight), false);
199
+ expect("direct rejects invalid discriminator", mod.eqTemplateDirect(invalidLeft, invalidRight), false);
200
+
201
+ const nestedLeft = { value: left };
202
+ const nestedRight = { value: right };
203
+ expect("nested is left", mod.isNested(nestedLeft), true);
204
+ expect("nested is right", mod.isNested(nestedRight), true);
205
+ expectJson("nested clone left preserves b", mod.cloneNested(nestedLeft), nestedLeft);
206
+ expectJson("nested clone right preserves b", mod.cloneNested(nestedRight), nestedRight);
207
+ expect("nested factory different b", mod.eqNestedFactory(nestedLeft, nestedRight), false);
208
+ expect("nested direct different b", mod.eqNestedDirect(nestedLeft, nestedRight), false);
209
+ expect("nested factory equal b", mod.eqNestedFactory(
210
+ { value: { kind: "b_x", common: "same", b: "same" } },
211
+ { value: { kind: "b_x", common: "same", b: "same" } },
212
+ ), true);
213
+ expect("nested invalid discriminator", mod.eqNestedFactory(
214
+ { value: invalidLeft },
215
+ { value: invalidRight },
216
+ ), false);
217
+
218
+ expect("literal member different", mod.eqLiteral(
219
+ { kind: "a", value: 1 },
220
+ { kind: "a", value: 2 },
221
+ ), false);
222
+ expect("literal cross member", mod.eqLiteral(
223
+ { kind: "a", value: 1 },
224
+ { kind: "b", value: "1" },
225
+ ), false);
226
+ expect("optional member different", mod.eqOptional({ a: 1 }, { a: 2 }), false);
227
+ expect("optional second payload follows first match", mod.eqOptional({ b: "left" }, { b: "right" }), true);
228
+ expect("plain different", mod.eqPlain(
229
+ { kind: "b_x", common: "same", b: "left" },
230
+ { kind: "b_x", common: "same", b: "right" },
231
+ ), false);
232
+ expect("plain equal", mod.eqPlain(
233
+ { kind: "b_x", common: "same", b: "same" },
234
+ { kind: "b_x", common: "same", b: "same" },
235
+ ), true);
236
+
237
+ if (failures > 0) {
238
+ throw new Error(failures + " assertion(s) failed");
239
+ }
240
+ console.log("all compare template-literal union cases passed");
241
+ `
@@ -0,0 +1,289 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "testing"
8
+ )
9
+
10
+ // TestCompareUnionDiscriminationTransform pins compare.equals over a union of
11
+ // object types (issue #2214).
12
+ //
13
+ // CompareEqualProgrammer.schema assembled an object union as a flat OR of member
14
+ // comparators (`_eo0(x,y) || _eo1(x,y) || ...`) with no discrimination. A wrong
15
+ // member's comparator matched spuriously: its constant discriminant passed via
16
+ // the always-prepended `x.type === y.type` branch (both agree, even when neither
17
+ // is that member) and its absent payload keys compared `undefined === undefined`.
18
+ // So `equals({type:"a",x:1}, {type:"a",x:2})` was `true` for two distinct
19
+ // references. Every other object-union programmer (is/clone/classify/prune/json/
20
+ // notations/protobuf) discriminates so a member comparator only runs for the
21
+ // member both values actually are. `equals` must do the same: decide which member
22
+ // each operand is, return false if they differ, and compare within the one shared
23
+ // member — and must agree with `is` on membership.
24
+ //
25
+ // All fixtures compare DISTINCT references (fresh object literals) so the
26
+ // `x === y` identity fast path never hides the flaw.
27
+ //
28
+ // 1. Transform is + compare.createEquals over discriminated, non-discriminated
29
+ // disjoint, narrower-masks-wider, 3-member, array/union-member, and nested
30
+ // object unions, plus primitive/array-union and non-union controls.
31
+ // 2. Require distinct-but-different pairs to compare not-equal, distinct-but-
32
+ // identical pairs to compare equal, and equals to imply is on both operands.
33
+ // 3. Require primitive/array unions and non-union objects to be unchanged.
34
+ func TestCompareUnionDiscriminationTransform(t *testing.T) {
35
+ project := compareUnionDiscriminationProject(t)
36
+ out, errText, code := ttscTypiaTestCapture(func() int {
37
+ return runTransform([]string{
38
+ "--cwd", project,
39
+ "--tsconfig", "tsconfig.json",
40
+ "--file", "src/main.ts",
41
+ "--output", "js",
42
+ })
43
+ })
44
+ if code != 0 {
45
+ t.Fatalf("compare union discrimination transform failed: code=%d stderr=\n%s", code, errText)
46
+ }
47
+ compareUnionDiscriminationRunRuntimeCases(t, project, out)
48
+ }
49
+
50
+ func compareUnionDiscriminationProject(t *testing.T) string {
51
+ t.Helper()
52
+ root := ttscTypiaTestRepoRoot(t)
53
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
54
+ if err := os.MkdirAll(base, 0o755); err != nil {
55
+ t.Fatalf("mkdir temp base: %v", err)
56
+ }
57
+ dir, err := os.MkdirTemp(base, "compare-union-disc-")
58
+ if err != nil {
59
+ t.Fatalf("create temp fixture: %v", err)
60
+ }
61
+ t.Cleanup(func() {
62
+ _ = os.RemoveAll(dir)
63
+ })
64
+ src := filepath.Join(dir, "src")
65
+ if err := os.MkdirAll(src, 0o755); err != nil {
66
+ t.Fatalf("mkdir fixture src: %v", err)
67
+ }
68
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareUnionDiscriminationTSConfig), 0o644); err != nil {
69
+ t.Fatalf("write tsconfig: %v", err)
70
+ }
71
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareUnionDiscriminationSource), 0o644); err != nil {
72
+ t.Fatalf("write source: %v", err)
73
+ }
74
+ return dir
75
+ }
76
+
77
+ func compareUnionDiscriminationRunRuntimeCases(t *testing.T, project string, js string) {
78
+ t.Helper()
79
+ node, err := exec.LookPath("node")
80
+ if err != nil {
81
+ t.Skip("node executable not found")
82
+ }
83
+ runtimeDir := filepath.Join(project, "runtime")
84
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
85
+ t.Fatalf("mkdir runtime dir: %v", err)
86
+ }
87
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
88
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
89
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
90
+ t.Fatalf("write runtime module: %v", err)
91
+ }
92
+ runner := filepath.Join(runtimeDir, "run.cjs")
93
+ if err := os.WriteFile(runner, []byte(compareUnionDiscriminationRuntimeRunner), 0o644); err != nil {
94
+ t.Fatalf("write runtime runner: %v", err)
95
+ }
96
+ cmd := exec.Command(node, runner)
97
+ cmd.Dir = runtimeDir
98
+ output, err := cmd.CombinedOutput()
99
+ if err != nil {
100
+ t.Fatalf("compare union discrimination runtime cases failed: %v\n%s", err, output)
101
+ }
102
+ }
103
+
104
+ const compareUnionDiscriminationTSConfig = `{
105
+ "compilerOptions": {
106
+ "target": "ES2022",
107
+ "module": "commonjs",
108
+ "moduleResolution": "bundler",
109
+ "ignoreDeprecations": "6.0",
110
+ "types": ["*"],
111
+ "esModuleInterop": true,
112
+ "strict": true,
113
+ "skipLibCheck": true
114
+ },
115
+ "include": ["src"]
116
+ }
117
+ `
118
+
119
+ const compareUnionDiscriminationSource = `import typia from "typia";
120
+
121
+ // 1. discriminated union
122
+ type Disc = { type: "a"; x: number } | { type: "b"; y: string };
123
+ export const isDisc = typia.createIs<Disc>();
124
+ export const eqDisc = typia.compare.createEquals<Disc>();
125
+
126
+ // 2. non-discriminated union with disjoint keys
127
+ type Disjoint = { x: number } | { y: string };
128
+ export const isDisjoint = typia.createIs<Disjoint>();
129
+ export const eqDisjoint = typia.compare.createEquals<Disjoint>();
130
+
131
+ // 3. narrower-masks-wider
132
+ type Mask = { a: number } | { a: number; b: string };
133
+ export const isMask = typia.createIs<Mask>();
134
+ export const eqMask = typia.compare.createEquals<Mask>();
135
+
136
+ // 4. three-member discriminated union
137
+ type Three =
138
+ | { type: "a"; x: number }
139
+ | { type: "b"; y: string }
140
+ | { type: "c"; z: boolean };
141
+ export const isThree = typia.createIs<Three>();
142
+ export const eqThree = typia.compare.createEquals<Three>();
143
+
144
+ // 5. a member whose payload is itself an array / element union
145
+ type ArrMember =
146
+ | { kind: "multi"; values: (number | string)[] }
147
+ | { kind: "single"; value: number };
148
+ export const isArrMember = typia.createIs<ArrMember>();
149
+ export const eqArrMember = typia.compare.createEquals<ArrMember>();
150
+
151
+ // 6. nested object-union property
152
+ type Nested = { wrap: { type: "a"; x: number } | { type: "b"; y: string } };
153
+ export const isNested = typia.createIs<Nested>();
154
+ export const eqNested = typia.compare.createEquals<Nested>();
155
+
156
+ // 7. recursive discriminated union (exercises _vctx capture through the IIFE)
157
+ type Tree =
158
+ | { type: "leaf"; value: number }
159
+ | { type: "node"; left: Tree; right: Tree };
160
+ export const isTree = typia.createIs<Tree>();
161
+ export const eqTree = typia.compare.createEquals<Tree>();
162
+
163
+ // 8. native alongside a discriminated object union (notNatives guard + ladder)
164
+ type WithNative = Date | { kind: "a"; x: number } | { kind: "b"; y: string };
165
+ export const eqWithNative = typia.compare.createEquals<WithNative>();
166
+
167
+ // control: a native unioned with a SINGLE object keeps the flat guarded branch
168
+ type DateOrStamp = Date | { timestamp: number };
169
+ export const eqDateStamp = typia.compare.createEquals<DateOrStamp>();
170
+
171
+ // controls: primitive union, array union, non-union object
172
+ export const eqPrim = typia.compare.createEquals<string | number>();
173
+ export const eqArrUnion = typia.compare.createEquals<number[] | string[]>();
174
+ export const eqObj = typia.compare.createEquals<{ a: number; b: string }>();
175
+ `
176
+
177
+ const compareUnionDiscriminationRuntimeRunner = `const mod = require("./main.cjs");
178
+
179
+ let failures = 0;
180
+ const expect = (label, actual, expected) => {
181
+ if (actual !== expected) {
182
+ console.log("FAIL " + label + ": expected " + expected + ", got " + actual);
183
+ failures++;
184
+ }
185
+ };
186
+
187
+ // --- 1. discriminated union: {type:"a";x} | {type:"b";y} ---
188
+ expect("disc a distinct-different", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
189
+ expect("disc b distinct-different", mod.eqDisc({ type: "b", y: "p" }, { type: "b", y: "q" }), false);
190
+ expect("disc a distinct-identical", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 1 }), true);
191
+ expect("disc b distinct-identical", mod.eqDisc({ type: "b", y: "p" }, { type: "b", y: "p" }), true);
192
+ expect("disc cross-arm a vs b", mod.eqDisc({ type: "a", x: 1 }, { type: "b", y: "p" }), false);
193
+
194
+ // --- 2. non-discriminated disjoint keys: {x} | {y} ---
195
+ expect("disjoint x distinct-different", mod.eqDisjoint({ x: 1 }, { x: 2 }), false);
196
+ expect("disjoint y distinct-different", mod.eqDisjoint({ y: "p" }, { y: "q" }), false);
197
+ expect("disjoint x distinct-identical", mod.eqDisjoint({ x: 1 }, { x: 1 }), true);
198
+ expect("disjoint cross-arm x vs y", mod.eqDisjoint({ x: 1 }, { y: "p" }), false);
199
+
200
+ // --- 3. narrower-masks-wider: {a} | {a,b} ---
201
+ expect("mask wider distinct-different", mod.eqMask({ a: 1, b: "x" }, { a: 1, b: "y" }), false);
202
+ expect("mask narrower distinct-identical", mod.eqMask({ a: 1 }, { a: 1 }), true);
203
+ expect("mask wider distinct-identical", mod.eqMask({ a: 1, b: "x" }, { a: 1, b: "x" }), true);
204
+ expect("mask narrower vs wider", mod.eqMask({ a: 1 }, { a: 1, b: "x" }), false);
205
+
206
+ // --- 4. three-member ---
207
+ expect("three a-different", mod.eqThree({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
208
+ expect("three b-different", mod.eqThree({ type: "b", y: "p" }, { type: "b", y: "q" }), false);
209
+ expect("three c-different", mod.eqThree({ type: "c", z: true }, { type: "c", z: false }), false);
210
+ expect("three c-identical", mod.eqThree({ type: "c", z: true }, { type: "c", z: true }), true);
211
+ expect("three cross a vs c", mod.eqThree({ type: "a", x: 1 }, { type: "c", z: true }), false);
212
+
213
+ // --- 5. array/element-union member ---
214
+ expect("arrmember multi different length", mod.eqArrMember({ kind: "multi", values: [1, 2] }, { kind: "multi", values: [1] }), false);
215
+ expect("arrmember multi different elem", mod.eqArrMember({ kind: "multi", values: [1, "a"] }, { kind: "multi", values: [1, "b"] }), false);
216
+ expect("arrmember multi identical", mod.eqArrMember({ kind: "multi", values: [1, "a"] }, { kind: "multi", values: [1, "a"] }), true);
217
+ expect("arrmember single different", mod.eqArrMember({ kind: "single", value: 1 }, { kind: "single", value: 2 }), false);
218
+ expect("arrmember cross multi vs single", mod.eqArrMember({ kind: "multi", values: [1] }, { kind: "single", value: 1 }), false);
219
+
220
+ // --- 6. nested object-union property ---
221
+ expect("nested inner different", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "a", x: 2 } }), false);
222
+ expect("nested inner identical", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "a", x: 1 } }), true);
223
+ expect("nested cross arm", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "b", y: "p" } }), false);
224
+
225
+ // --- controls: primitive / array unions, non-union object ---
226
+ expect("prim number-different", mod.eqPrim(1, 2), false);
227
+ expect("prim string-identical", mod.eqPrim("x", "x"), true);
228
+ expect("prim cross string vs number", mod.eqPrim("1", 1), false);
229
+ expect("arrunion number-different", mod.eqArrUnion([1, 2], [1, 3]), false);
230
+ expect("arrunion number-identical", mod.eqArrUnion([1, 2], [1, 2]), true);
231
+ expect("arrunion string-identical", mod.eqArrUnion(["a"], ["a"]), true);
232
+ expect("obj different", mod.eqObj({ a: 1, b: "x" }, { a: 1, b: "y" }), false);
233
+ expect("obj identical", mod.eqObj({ a: 1, b: "x" }, { a: 1, b: "x" }), true);
234
+
235
+ // --- recursive discriminated union (distinct references throughout) ---
236
+ const mkTree = () => ({ type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 2 } });
237
+ expect("tree identical", mod.eqTree(mkTree(), mkTree()), true);
238
+ expect("tree leaf value differs", mod.eqTree({ type: "leaf", value: 1 }, { type: "leaf", value: 2 }), false);
239
+ expect("tree deep differs", mod.eqTree(mkTree(), { type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 9 } }), false);
240
+ expect("tree leaf vs node", mod.eqTree({ type: "leaf", value: 1 }, mkTree()), false);
241
+ expect("tree shape differs", mod.eqTree({ type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 2 } }, { type: "node", left: { type: "leaf", value: 1 }, right: { type: "node", left: { type: "leaf", value: 2 }, right: { type: "leaf", value: 3 } } }), false);
242
+
243
+ // --- native alongside a discriminated object union ---
244
+ expect("withnative same date", mod.eqWithNative(new Date(0), new Date(0)), true);
245
+ expect("withnative diff date", mod.eqWithNative(new Date(0), new Date(5000)), false);
246
+ expect("withnative obj a different", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "a", x: 2 }), false);
247
+ expect("withnative obj a identical", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "a", x: 1 }), true);
248
+ expect("withnative date vs obj", mod.eqWithNative(new Date(0), { kind: "a", x: 1 }), false);
249
+ expect("withnative cross arm", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "b", y: "p" }), false);
250
+
251
+ // --- native unioned with a single object (control) ---
252
+ expect("datestamp same date", mod.eqDateStamp(new Date(0), new Date(0)), true);
253
+ expect("datestamp diff date", mod.eqDateStamp(new Date(0), new Date(5000)), false);
254
+ expect("datestamp stamp identical", mod.eqDateStamp({ timestamp: 5 }, { timestamp: 5 }), true);
255
+ expect("datestamp stamp different", mod.eqDateStamp({ timestamp: 5 }, { timestamp: 9 }), false);
256
+ expect("datestamp date vs stamp", mod.eqDateStamp(new Date(0), { timestamp: 0 }), false);
257
+
258
+ // --- equals must imply is on both operands (agree with is) ---
259
+ const discSamples = [
260
+ { type: "a", x: 1 }, { type: "a", x: 2 }, { type: "b", y: "p" }, { type: "b", y: "q" },
261
+ ];
262
+ for (const a of discSamples)
263
+ for (const b of discSamples) {
264
+ // fresh distinct references
265
+ const x = JSON.parse(JSON.stringify(a));
266
+ const y = JSON.parse(JSON.stringify(b));
267
+ if (mod.eqDisc(x, y)) {
268
+ expect("agree-is disc lhs " + JSON.stringify(a), mod.isDisc(x), true);
269
+ expect("agree-is disc rhs " + JSON.stringify(b), mod.isDisc(y), true);
270
+ // equal implies structurally same JSON
271
+ expect("equal implies same json " + JSON.stringify(a) + "|" + JSON.stringify(b), JSON.stringify(x) === JSON.stringify(y), true);
272
+ }
273
+ }
274
+
275
+ const maskSamples = [{ a: 1 }, { a: 1, b: "x" }, { a: 1, b: "y" }, { a: 2 }];
276
+ for (const a of maskSamples)
277
+ for (const b of maskSamples) {
278
+ const x = JSON.parse(JSON.stringify(a));
279
+ const y = JSON.parse(JSON.stringify(b));
280
+ if (mod.eqMask(x, y)) {
281
+ expect("agree-is mask same json " + JSON.stringify(a) + "|" + JSON.stringify(b), JSON.stringify(x) === JSON.stringify(y), true);
282
+ }
283
+ }
284
+
285
+ if (failures > 0) {
286
+ throw new Error(failures + " assertion(s) failed");
287
+ }
288
+ console.log("all compare-union-discrimination cases passed");
289
+ `