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
@@ -615,27 +615,36 @@ type randomProgrammer_composedAtomic struct {
615
615
  func randomProgrammer_compose_atomic(atomicType string, schema nativeiterate.JsonSchema, emit *shimprinter.EmitContext) randomProgrammer_composedAtomic {
616
616
  f := nativecontext.EmitFactoryOf(randomProgrammer_factory, emit)
617
617
  if atomicType == "string" {
618
+ // A string leaf that also carries a length tag needs the bounds forwarded
619
+ // to the format and pattern generators; only the plain-string fall-through
620
+ // used to receive the full schema, so a format or pattern combined with
621
+ // minLength/maxLength was generated at the wrong length and failed its own
622
+ // validator (issue #2189).
623
+ lengthArgs := randomProgrammer_length_argument(schema, emit)
618
624
  if raw, ok := schema["format"].(string); ok && raw != "" {
619
625
  if raw == "date-time" {
620
- return randomProgrammer_composedAtomic{Method: "datetime", Internal: "randomFormatDatetime"}
626
+ return randomProgrammer_composedAtomic{Method: "datetime", Internal: "randomFormatDatetime", Arguments: lengthArgs}
621
627
  }
622
628
  method := randomProgrammer_format_method(raw)
623
629
  return randomProgrammer_composedAtomic{
624
- Method: method,
625
- Internal: "randomFormat" + randomProgrammer_format_pascal(raw),
630
+ Method: method,
631
+ Internal: "randomFormat" + randomProgrammer_format_pascal(raw),
632
+ Arguments: lengthArgs,
626
633
  }
627
634
  }
628
635
  if pattern, ok := schema["pattern"].(string); ok && pattern != "" {
636
+ arguments := []*shimast.Node{
637
+ f.NewNewExpression(
638
+ f.NewIdentifier("RegExp"),
639
+ nil,
640
+ f.NewNodeList([]*shimast.Node{f.NewStringLiteral(pattern, shimast.TokenFlagsNone)}),
641
+ ),
642
+ }
643
+ arguments = append(arguments, lengthArgs...)
629
644
  return randomProgrammer_composedAtomic{
630
- Method: "pattern",
631
- Internal: "randomPattern",
632
- Arguments: []*shimast.Node{
633
- f.NewNewExpression(
634
- f.NewIdentifier("RegExp"),
635
- nil,
636
- f.NewNodeList([]*shimast.Node{f.NewStringLiteral(pattern, shimast.TokenFlagsNone)}),
637
- ),
638
- },
645
+ Method: "pattern",
646
+ Internal: "randomPattern",
647
+ Arguments: arguments,
639
648
  }
640
649
  }
641
650
  } else if atomicType == "number" {
@@ -659,6 +668,24 @@ func randomProgrammer_compose_atomic(atomicType string, schema nativeiterate.Jso
659
668
  }
660
669
  }
661
670
 
671
+ // randomProgrammer_length_argument forwards the minLength/maxLength bounds of a
672
+ // string leaf to the format and pattern generators as a
673
+ // `{ minLength?, maxLength? }` object literal, or nil when the leaf carries no
674
+ // length tag so the format-only and pattern-only emission stays byte-identical.
675
+ func randomProgrammer_length_argument(schema nativeiterate.JsonSchema, emit *shimprinter.EmitContext) []*shimast.Node {
676
+ length := map[string]any{}
677
+ if value, ok := schema["minLength"]; ok {
678
+ length["minLength"] = value
679
+ }
680
+ if value, ok := schema["maxLength"]; ok {
681
+ length["maxLength"] = value
682
+ }
683
+ if len(length) == 0 {
684
+ return nil
685
+ }
686
+ return []*shimast.Node{nativefactories.LiteralFactory.Write(length, emit)}
687
+ }
688
+
662
689
  func randomProgrammer_decode_template(props struct {
663
690
  Context nativecontext.ITypiaContext
664
691
  Functor *nativehelpers.FunctionProgrammer
@@ -1407,6 +1434,16 @@ func randomProgrammer_is_typed_array(name string) bool {
1407
1434
  }
1408
1435
  }
1409
1436
 
1437
+ // randomProgrammer_typed_array_range reports the type tag and range a TypedArray's
1438
+ // elements are generated from.
1439
+ //
1440
+ // These bounds are a generation hint, not a validation gate, and they are the one
1441
+ // copy of the 64-bit bound that is deliberately inexact. They become `minimum` and
1442
+ // `maximum` comment tags on a number-typed JSON schema, and `number` cannot
1443
+ // represent 2**63 - 1 or 2**64 - 1 -- both arrive rounded up to the next power of
1444
+ // two. That costs nothing here: the generator only picks a value from the range,
1445
+ // and the TypedArray constructor wraps whatever it is handed. Validation owns
1446
+ // exactness instead, in _isTypeInt64Bigint and its siblings.
1410
1447
  func randomProgrammer_typed_array_range(name string) (string, string, string) {
1411
1448
  switch name {
1412
1449
  case "Uint8Array", "Uint8ClampedArray":
@@ -1424,9 +1461,9 @@ func randomProgrammer_typed_array_range(name string) (string, string, string) {
1424
1461
  case "Int32Array":
1425
1462
  return "int32", "-2147483648", "2147483647"
1426
1463
  case "BigInt64Array":
1427
- return "uint64", "-9223372036854775808", "9223372036854775807"
1464
+ return "int64", "-9223372036854775808", "9223372036854775807"
1428
1465
  case "Float32Array":
1429
- return "float", "-1.175494351e38", "3.4028235e38"
1466
+ return "float", "-3.4028235e38", "3.4028235e38"
1430
1467
  default:
1431
1468
  return "double", fmt.Sprint(math.SmallestNonzeroFloat64), fmt.Sprint(math.MaxFloat64)
1432
1469
  }
@@ -12,6 +12,7 @@ import (
12
12
  nativefactories "github.com/samchon/typia/packages/typia/native/core/factories"
13
13
  nativehelpers "github.com/samchon/typia/packages/typia/native/core/programmers/helpers"
14
14
  nativeinternal "github.com/samchon/typia/packages/typia/native/core/programmers/internal"
15
+ nativeiterate "github.com/samchon/typia/packages/typia/native/core/programmers/iterate"
15
16
  schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
16
17
  )
17
18
 
@@ -31,9 +32,14 @@ type CompareEqualProgrammer_IProps struct {
31
32
  }
32
33
 
33
34
  type compareEqualProgrammerGenerator struct {
34
- Config CompareEqualProgrammer_IConfig
35
- Recursive bool
36
- Counter int
35
+ Config CompareEqualProgrammer_IConfig
36
+ Functional bool
37
+ Recursive bool
38
+ Counter int
39
+ // Member-resolution checkers (`_ui<index>`) emitted on demand for the object
40
+ // unions that need the is-match ladder, keyed by the object's collection index.
41
+ Matchers []string
42
+ MatcherIndex map[int]bool
37
43
  }
38
44
 
39
45
  var compareEqualProgrammer_factory = shimast.NewNodeFactory(shimast.NodeFactoryHooks{})
@@ -71,8 +77,10 @@ func (compareEqualProgrammerNamespace) Write(props CompareEqualProgrammer_IProps
71
77
  }
72
78
 
73
79
  generator := &compareEqualProgrammerGenerator{
74
- Config: props.Config,
75
- Recursive: nativeinternal.FeatureProgrammer.CollectionRecursive(collection),
80
+ Config: props.Config,
81
+ Functional: nativehelpers.OptionPredicator.Functional(props.Context.Options),
82
+ Recursive: nativeinternal.FeatureProgrammer.CollectionRecursive(collection),
83
+ MatcherIndex: map[int]bool{},
76
84
  }
77
85
  body := generator.schema(result.Data, "x", "y")
78
86
  statements := []string{}
@@ -89,6 +97,12 @@ func (compareEqualProgrammerNamespace) Write(props CompareEqualProgrammer_IProps
89
97
  statements = append(statements, generator.tupleFunction(tuple))
90
98
  }
91
99
  }
100
+ // The member matchers are collected last because every generation step above
101
+ // may request one. They are `const` arrow functions in the same scope as the
102
+ // `_eo`/`_ea`/`_et` helpers and are only ever called after this IIFE returns,
103
+ // so declaring them at the end is free of temporal-dead-zone hazards — the
104
+ // same placement `is` uses for the `_io` checkers it appends after `_cu`.
105
+ statements = append(statements, generator.Matchers...)
92
106
  if generator.Recursive {
93
107
  statements = append(statements, "return (x, y) => { const _vctx = {}; return "+body+"; };")
94
108
  } else {
@@ -155,8 +169,28 @@ func (g *compareEqualProgrammerGenerator) schema(metadata *schemametadata.Metada
155
169
  for _, array := range metadata.Arrays {
156
170
  branches = append(branches, g.array(array, x, y))
157
171
  }
158
- for _, object := range metadata.Objects {
159
- branches = append(branches, g.objectCall(object.Type, x, y))
172
+ // A union of two or more object types must discriminate: route each operand
173
+ // to exactly one member and compare within that single member. A flat OR of
174
+ // member comparators lets a wrong member's comparator match spuriously — its
175
+ // literal discriminant is satisfied by the always-present `x[k] === y[k]`
176
+ // branch and its absent payload keys compare `undefined === undefined`. The
177
+ // discrimination reuses the shared UnionPredicator specialization the sibling
178
+ // programmers (is/clone/classify/...) route through, so `equals` agrees with
179
+ // `is` on which member a value is. A union no discriminant can split (every
180
+ // distinguishing key optional, e.g. `{ a?: number } | { b?: string }`) routes
181
+ // through the first-is-match ladder instead — never a flat OR, which admits
182
+ // the same spurious match through absent keys comparing
183
+ // `undefined === undefined` (issue #2225).
184
+ if len(metadata.Objects) >= 2 {
185
+ expr := g.objectUnion(metadata.Objects, x, y)
186
+ if guard := g.notNatives(metadata.Natives, x, y); guard != "" {
187
+ expr = g.and(guard, expr)
188
+ }
189
+ branches = append(branches, expr)
190
+ } else {
191
+ for _, object := range metadata.Objects {
192
+ branches = append(branches, g.objectFlatBranch(object.Type, metadata.Natives, x, y))
193
+ }
160
194
  }
161
195
  for _, alias := range metadata.Aliases {
162
196
  branches = append(branches, g.schema(alias.Type.Value, x, y))
@@ -233,7 +267,27 @@ func (g *compareEqualProgrammerGenerator) tupleInline(tuple *schemametadata.Meta
233
267
  g.same(g.access(x, "length"), g.access(y, "length")),
234
268
  }
235
269
  if rest == nil {
236
- checks = append(checks, g.same(g.access(x, "length"), strconv.Itoa(fixed)))
270
+ // An omitted optional trailing element makes the tuple's length a range
271
+ // [required, fixed] — exactly the gate `is` emits. A hard `=== fixed`
272
+ // rejects a value `is` accepts and breaks reflexivity of `equals`; the
273
+ // per-element `x[i] === y[i]` prefix already treats both-absent as equal,
274
+ // so only the length gate needs the range. A fully-required tuple keeps
275
+ // its byte-identical `x.length === fixed`.
276
+ required := 0
277
+ allRequired := true
278
+ for i := 0; i < fixed; i++ {
279
+ if tuple.Elements[i].Optional {
280
+ allRequired = false
281
+ } else {
282
+ required++
283
+ }
284
+ }
285
+ if allRequired {
286
+ checks = append(checks, g.same(g.access(x, "length"), strconv.Itoa(fixed)))
287
+ } else {
288
+ length := g.access(x, "length")
289
+ checks = append(checks, fmt.Sprintf("%d <= %s && %d >= %s", required, length, fixed, length))
290
+ }
237
291
  } else {
238
292
  checks = append(checks, fmt.Sprintf("%s.length >= %d", g.wrap(x), fixed))
239
293
  }
@@ -256,6 +310,326 @@ func (g *compareEqualProgrammerGenerator) objectCall(object *schemametadata.Meta
256
310
  return fmt.Sprintf("_eo%d(%s, %s)", object.Index, g.wrap(x), g.wrap(y))
257
311
  }
258
312
 
313
+ // objectFlatBranch renders a single object member as a guarded comparator. A
314
+ // multi-object union always uses objectUnion's member dispatch instead.
315
+ func (g *compareEqualProgrammerGenerator) objectFlatBranch(object *schemametadata.MetadataObjectType, natives []*schemametadata.MetadataNative, x string, y string) string {
316
+ // Guard the object branch against the sibling native instances. `_eo` admits
317
+ // any `typeof === "object" && !Array.isArray` value, so a native (a Date is
318
+ // an object) would be compared by the object's declared keys, which the
319
+ // native lacks — two different Dates then look equal on their absent keys and
320
+ // the OR wrongly accepts. Excluding what a native branch owns makes the arms
321
+ // mutually exclusive, matching the clone/classify ladder whose object arm is
322
+ // unreachable once a native arm matches.
323
+ call := g.objectCall(object, x, y)
324
+ if guard := g.notNatives(natives, x, y); guard != "" {
325
+ call = g.and(guard, call)
326
+ }
327
+ return call
328
+ }
329
+
330
+ // objectUnion renders a discriminated comparison for a union of two or more
331
+ // object types. It mirrors the is/clone/classify discrimination: each operand is
332
+ // routed to exactly one member, and only when both land on the same member does
333
+ // that member's comparator run. This replaces the flat OR whose wrong-member
334
+ // comparator could match spuriously.
335
+ //
336
+ // Routing prefers the shared UnionPredicator discriminants (issue #2214). When
337
+ // no discriminant splits the members — every distinguishing key is optional, so
338
+ // UnionPredicator yields no specialization, or more than one member is left
339
+ // unspecialized — routing falls back to the first-is-match ladder that
340
+ // clone/classify/prune reach through Decode_union_object (issue #2225). There is
341
+ // no flat-OR fallback: the flat OR is the defect both issues describe.
342
+ func (g *compareEqualProgrammerGenerator) objectUnion(objects []*schemametadata.MetadataObject, x string, y string) string {
343
+ types := make([]*schemametadata.MetadataObjectType, 0, len(objects))
344
+ for _, object := range objects {
345
+ types = append(types, object.Type)
346
+ }
347
+ ladder, ok := g.discriminantLadder(types)
348
+ if ok == false {
349
+ ladder = g.matchLadder(types)
350
+ }
351
+
352
+ tag := g.local("utag")
353
+ tx := g.local("utx")
354
+ // Dispatch: with the shared member index, run only that member's comparator.
355
+ dispatch := "false"
356
+ for i := len(types) - 1; i >= 0; i-- {
357
+ dispatch = fmt.Sprintf("%s === %d ? %s : %s", tx, types[i].Index, g.objectCall(types[i], "x", "y"), dispatch)
358
+ }
359
+ body := fmt.Sprintf(
360
+ "((x, y) => { const %s = (v) => (%s) ? (%s) : -1; const %s = %s(x); return %s !== -1 && %s === %s(y) && (%s); })(%s, %s)",
361
+ tag, g.isObject("v"), ladder, tx, tag, tx, tx, tag, dispatch, g.wrap(x), g.wrap(y),
362
+ )
363
+ return body
364
+ }
365
+
366
+ // discriminantLadder renders the routing ternary from the shared UnionPredicator
367
+ // specialization: `<discriminant of member i> ? <index of member i> : ...`,
368
+ // ending in the lone unspecialized member (the unconditional else the
369
+ // discriminant ladder leaves) or -1 for "no member". It reports ok=false when
370
+ // the members carry no usable discriminant, when more than one member is left
371
+ // unspecialized, or when a discriminant value cannot be rendered as a check —
372
+ // the caller then routes by is-match instead.
373
+ func (g *compareEqualProgrammerGenerator) discriminantLadder(types []*schemametadata.MetadataObjectType) (string, bool) {
374
+ specs := nativehelpers.UnionPredicator.Object(types)
375
+ if len(specs) == 0 {
376
+ return "", false
377
+ }
378
+ specialized := map[*schemametadata.MetadataObjectType]bool{}
379
+ for _, spec := range specs {
380
+ specialized[spec.Object] = true
381
+ }
382
+ remained := []*schemametadata.MetadataObjectType{}
383
+ for _, object := range types {
384
+ if specialized[object] == false {
385
+ remained = append(remained, object)
386
+ }
387
+ }
388
+ if len(remained) > 1 {
389
+ return "", false
390
+ }
391
+ fallback := "-1"
392
+ if len(remained) == 1 {
393
+ fallback = strconv.Itoa(remained[0].Index)
394
+ }
395
+ ladder := fallback
396
+ for i := len(specs) - 1; i >= 0; i-- {
397
+ check, ok := g.discriminant(specs[i], "v")
398
+ if ok == false {
399
+ return "", false
400
+ }
401
+ ladder = fmt.Sprintf("%s ? %d : %s", check, specs[i].Object.Index, ladder)
402
+ }
403
+ return ladder, true
404
+ }
405
+
406
+ // matchLadder renders the routing ternary for a union no discriminant splits:
407
+ // the first member the value is-matches wins, exactly as `clone`/`classify`/
408
+ // `prune` resolve membership through Decode_union_object's `if (_io0(input))
409
+ // return ...; if (_io1(input)) ...` ladder. A value matching no member yields
410
+ // -1, which makes `equals` false rather than letting a wrong member's comparator
411
+ // decide.
412
+ func (g *compareEqualProgrammerGenerator) matchLadder(types []*schemametadata.MetadataObjectType) string {
413
+ calls := make([]string, 0, len(types))
414
+ for _, object := range types {
415
+ // Declared in member order so the emitted matchers read in the same order
416
+ // as the ladder that calls them; the ladder itself is folded back to front.
417
+ calls = append(calls, g.matchCall(object, "v"))
418
+ }
419
+ ladder := "-1"
420
+ for i := len(types) - 1; i >= 0; i-- {
421
+ ladder = fmt.Sprintf("%s ? %d : %s", calls[i], types[i].Index, ladder)
422
+ }
423
+ return ladder
424
+ }
425
+
426
+ // matchCall returns a call to the member's `_ui<index>` matcher, declaring the
427
+ // matcher on first request. The index is registered before the body is rendered
428
+ // so a recursive member refers to its own matcher instead of recursing forever
429
+ // at generation time.
430
+ func (g *compareEqualProgrammerGenerator) matchCall(object *schemametadata.MetadataObjectType, v string) string {
431
+ name := fmt.Sprintf("_ui%d", object.Index)
432
+ if g.MatcherIndex[object.Index] == false {
433
+ g.MatcherIndex[object.Index] = true
434
+ g.Matchers = append(g.Matchers, fmt.Sprintf("const %s = (v) => %s;", name, g.matchObject(object, "v")))
435
+ }
436
+ return fmt.Sprintf("%s(%s)", name, g.wrap(v))
437
+ }
438
+
439
+ // matchObject renders the structural is-check of one object member: every
440
+ // declared regular key must hold a value of its declared type (an optional key
441
+ // may be absent), and every extra key a dynamic index signature declares must
442
+ // hold a value of the signature's type. It mirrors the `_io` checkers `is`
443
+ // emits, at the abstraction level the rest of this programmer works at — shape
444
+ // and typeof, plus structural template patterns. Function-valued properties
445
+ // participate in this routing check whenever `is` makes them meaningful; they
446
+ // remain excluded from object value comparison after a member is selected. It
447
+ // deliberately ignores `typia.tags.*` constraints.
448
+ func (g *compareEqualProgrammerGenerator) matchObject(object *schemametadata.MetadataObjectType, v string) string {
449
+ checks := []string{}
450
+ regularKeys := []string{}
451
+ dynamic := []*schemametadata.MetadataProperty{}
452
+ for _, property := range object.Properties {
453
+ if sole := property.Key.GetSoleLiteral(); sole != nil {
454
+ regularKeys = append(regularKeys, *sole)
455
+ checks = append(checks, g.matchSlot(property.Value, g.property(v, *sole)))
456
+ } else {
457
+ dynamic = append(dynamic, property)
458
+ }
459
+ }
460
+ if len(dynamic) != 0 {
461
+ key := g.local("key")
462
+ regularCheck := compareEqualProgrammer_regularKeyCheck(regularKeys)
463
+ conditions := []string{}
464
+ for _, property := range dynamic {
465
+ conditions = append(conditions, g.and(g.dynamicKey(property.Key, key), g.matchSlot(property.Value, g.index(v, key))))
466
+ }
467
+ checks = append(checks, fmt.Sprintf("Object.keys(%s).every((%s) => %s)", g.wrap(v), key, g.or(regularCheck(key), g.or(conditions...))))
468
+ }
469
+ return g.and(checks...)
470
+ }
471
+
472
+ // matchSlot renders the is-check of a value slot — an object property or a tuple
473
+ // element — allowing the slot to be absent when it is optional.
474
+ func (g *compareEqualProgrammerGenerator) matchSlot(metadata *schemametadata.MetadataSchema, v string) string {
475
+ check := g.match(metadata, v)
476
+ if metadata != nil && metadata.IsRequired() == false {
477
+ return g.or(g.same(v, "undefined"), check)
478
+ }
479
+ return check
480
+ }
481
+
482
+ // match renders the structural is-check of one metadata schema as the OR of its
483
+ // buckets, the same bucket walk `schema` compares over. An unconstrained bucket
484
+ // (anything the compare feature already rejects, or a bucket carrying no shape
485
+ // to test) renders as "true", which keeps the ladder's first-match order the
486
+ // deciding factor exactly as it is in `is`.
487
+ func (g *compareEqualProgrammerGenerator) match(metadata *schemametadata.MetadataSchema, v string) string {
488
+ if metadata == nil {
489
+ return "true"
490
+ }
491
+ metadata = schemametadata.MetadataSchema_unalias(metadata)
492
+ if metadata.Any {
493
+ return "true"
494
+ }
495
+ branches := []string{}
496
+ if metadata.Nullable {
497
+ branches = append(branches, g.same(v, "null"))
498
+ }
499
+ for _, constant := range metadata.Constants {
500
+ for _, value := range constant.Values {
501
+ branches = append(branches, g.same(v, compareEqualProgrammer_literal(value.Value, constant.Type)))
502
+ }
503
+ }
504
+ for _, atomic := range metadata.Atomics {
505
+ branches = append(branches, g.typeof(v, atomic.Type))
506
+ }
507
+ if len(metadata.Templates) != 0 {
508
+ branches = append(branches, g.and(g.typeof(v, "string"), g.template(metadata.Templates, v)))
509
+ }
510
+ if len(metadata.Functions) != 0 && (g.Functional || metadata.Size() != 1) {
511
+ branches = append(branches, g.typeof(v, "function"))
512
+ }
513
+ for _, native := range metadata.Natives {
514
+ branches = append(branches, g.instanceof(v, native.Name))
515
+ }
516
+ for _, tuple := range metadata.Tuples {
517
+ branches = append(branches, g.matchTuple(tuple.Type, v))
518
+ }
519
+ for _, array := range metadata.Arrays {
520
+ elem := g.local("elem")
521
+ branches = append(branches, g.and(g.isArray(v), fmt.Sprintf("%s.every((%s) => %s)", g.wrap(v), elem, g.match(array.Type.Value, elem))))
522
+ }
523
+ if len(metadata.Objects) != 0 {
524
+ calls := []string{}
525
+ for _, object := range metadata.Objects {
526
+ calls = append(calls, g.matchCall(object.Type, v))
527
+ }
528
+ branches = append(branches, g.and(g.isObject(v), g.or(calls...)))
529
+ }
530
+ for _, alias := range metadata.Aliases {
531
+ branches = append(branches, g.match(alias.Type.Value, v))
532
+ }
533
+ if metadata.Escaped != nil {
534
+ branches = append(branches, g.match(metadata.Escaped.Original, v))
535
+ }
536
+ if metadata.Rest != nil {
537
+ branches = append(branches, g.match(metadata.Rest, v))
538
+ }
539
+ if len(branches) == 0 {
540
+ return "true"
541
+ }
542
+ return g.or(branches...)
543
+ }
544
+
545
+ // matchTuple renders the is-check of a tuple: the array gate, the length range
546
+ // an omitted optional trailing element makes legal (the same range `tupleInline`
547
+ // compares over), and each element's own check.
548
+ func (g *compareEqualProgrammerGenerator) matchTuple(tuple *schemametadata.MetadataTupleType, v string) string {
549
+ fixed := len(tuple.Elements)
550
+ var rest *schemametadata.MetadataSchema
551
+ if fixed != 0 && tuple.Elements[fixed-1].Rest != nil {
552
+ rest = tuple.Elements[fixed-1].Rest
553
+ fixed--
554
+ }
555
+ checks := []string{g.isArray(v)}
556
+ length := g.access(v, "length")
557
+ if rest == nil {
558
+ required := 0
559
+ allRequired := true
560
+ for i := 0; i < fixed; i++ {
561
+ if tuple.Elements[i].Optional {
562
+ allRequired = false
563
+ } else {
564
+ required++
565
+ }
566
+ }
567
+ if allRequired {
568
+ checks = append(checks, g.same(length, strconv.Itoa(fixed)))
569
+ } else {
570
+ checks = append(checks, fmt.Sprintf("%d <= %s && %d >= %s", required, length, fixed, length))
571
+ }
572
+ } else {
573
+ checks = append(checks, fmt.Sprintf("%s >= %d", length, fixed))
574
+ }
575
+ for i := 0; i < fixed; i++ {
576
+ checks = append(checks, g.matchSlot(tuple.Elements[i], g.index(v, strconv.Itoa(i))))
577
+ }
578
+ if rest != nil {
579
+ elem := g.local("elem")
580
+ checks = append(checks, fmt.Sprintf("%s.slice(%d).every((%s) => %s)", g.wrap(v), fixed, elem, g.match(rest, elem)))
581
+ }
582
+ return g.and(checks...)
583
+ }
584
+
585
+ // discriminant renders the routing predicate for one specialized union member,
586
+ // matching how `is` decides membership: presence (`v[key] !== undefined`) for a
587
+ // key unique to this member, or a value check (literal equality for constants,
588
+ // typeof for atomics/templates) for a shared key whose value distinguishes it.
589
+ // It returns ok=false for any discriminant value it cannot render as such a
590
+ // check, so the caller falls back rather than emit a weaker predicate.
591
+ func (g *compareEqualProgrammerGenerator) discriminant(spec nativehelpers.UnionPredicator_ISpecialized, v string) (string, bool) {
592
+ sole := spec.Property.Key.GetSoleLiteral()
593
+ if sole == nil {
594
+ return "", false
595
+ }
596
+ access := g.property(v, *sole)
597
+ if spec.Neighbor == false {
598
+ return fmt.Sprintf("%s !== undefined", g.wrap(access)), true
599
+ }
600
+ meta := schemametadata.MetadataSchema_unalias(spec.Property.Value)
601
+ if meta == nil || meta.Any {
602
+ return "", false
603
+ }
604
+ if len(meta.Objects) != 0 || len(meta.Arrays) != 0 || len(meta.Tuples) != 0 ||
605
+ len(meta.Natives) != 0 || len(meta.Sets) != 0 || len(meta.Maps) != 0 ||
606
+ len(meta.Aliases) != 0 || len(meta.Functions) != 0 || meta.Escaped != nil || meta.Rest != nil {
607
+ return "", false
608
+ }
609
+ checks := []string{}
610
+ if meta.Nullable {
611
+ // A nullable discriminant (e.g. `type: "a" | null`) routes a null value to
612
+ // this member exactly as `is` does, so `equals(null-arm, null-arm)` stays
613
+ // reflexive rather than falling through to no member.
614
+ checks = append(checks, g.same(access, "null"))
615
+ }
616
+ for _, constant := range meta.Constants {
617
+ for _, value := range constant.Values {
618
+ checks = append(checks, g.same(access, compareEqualProgrammer_literal(value.Value, constant.Type)))
619
+ }
620
+ }
621
+ for _, atomic := range meta.Atomics {
622
+ checks = append(checks, g.typeof(access, atomic.Type))
623
+ }
624
+ if len(meta.Templates) != 0 {
625
+ checks = append(checks, g.typeof(access, "string"))
626
+ }
627
+ if len(checks) == 0 {
628
+ return "", false
629
+ }
630
+ return g.or(checks...), true
631
+ }
632
+
259
633
  func (g *compareEqualProgrammerGenerator) arrayCall(array *schemametadata.MetadataArrayType, x string, y string) string {
260
634
  index := 0
261
635
  if array.Index != nil {
@@ -394,6 +768,19 @@ func (g *compareEqualProgrammerGenerator) dynamicKey(metadata *schemametadata.Me
394
768
  return g.or(checks...)
395
769
  }
396
770
 
771
+ // template renders the structural membership test shared with the authoritative
772
+ // runtime template checker. Compare still ignores typia tag predicates when it
773
+ // compares values, but it must retain the template-literal domain while routing
774
+ // an object union to a declared member.
775
+ func (g *compareEqualProgrammerGenerator) template(templates []*schemametadata.MetadataTemplate, input string) string {
776
+ checks := make([]string, 0, len(templates))
777
+ for _, template := range templates {
778
+ pattern := nativeiterate.TemplateRuntimePattern(template.Row)
779
+ checks = append(checks, fmt.Sprintf("RegExp(%s).test(%s)", strconv.Quote(pattern), g.wrap(input)))
780
+ }
781
+ return g.or(checks...)
782
+ }
783
+
397
784
  func (g *compareEqualProgrammerGenerator) visit(kind string, index int) string {
398
785
  slot := fmt.Sprintf("_vctx.%s%d", kind, index)
399
786
  return fmt.Sprintf("const _map = %s || (%s = new WeakMap()); let _set = _map.get(x); if (_set && _set.has(y)) return true; if (!_set) _map.set(x, (_set = new WeakSet())); _set.add(y);", slot, slot)
@@ -409,6 +796,21 @@ func (g *compareEqualProgrammerGenerator) objectGuard(x string, y string) string
409
796
  return g.and(g.isObject(x), g.isObject(y))
410
797
  }
411
798
 
799
+ // notNatives builds "neither x nor y is one of the union's native instances",
800
+ // so the object branch never claims a value a native branch owns. Empty when
801
+ // the union declares no native, keeping the object-only output unchanged.
802
+ func (g *compareEqualProgrammerGenerator) notNatives(natives []*schemametadata.MetadataNative, x string, y string) string {
803
+ if len(natives) == 0 {
804
+ return ""
805
+ }
806
+ checks := []string{}
807
+ for _, native := range natives {
808
+ checks = append(checks, "!"+g.wrap(g.instanceof(x, native.Name)))
809
+ checks = append(checks, "!"+g.wrap(g.instanceof(y, native.Name)))
810
+ }
811
+ return g.and(checks...)
812
+ }
813
+
412
814
  func (g *compareEqualProgrammerGenerator) isObject(input string) string {
413
815
  return fmt.Sprintf("typeof %s === \"object\" && %s !== null && !Array.isArray(%s)", g.wrap(input), g.wrap(input), g.wrap(input))
414
816
  }
@@ -219,9 +219,11 @@ func (g *compareLessProgrammerGenerator) core(metadata *schemametadata.MetadataS
219
219
  }
220
220
 
221
221
  // primitive renders the scalar three-way comparator (works for number, string,
222
- // boolean and bigint via the relational operators).
222
+ // boolean and bigint via the relational operators). Self-inequality detects NaN
223
+ // without coercing other scalar types and places it after every ordinary number.
223
224
  func (g *compareLessProgrammerGenerator) primitive(x string, y string) string {
224
- return fmt.Sprintf("(%s < %s ? -1 : %s > %s ? 1 : 0)", g.wrap(x), g.wrap(y), g.wrap(x), g.wrap(y))
225
+ return fmt.Sprintf("(%s !== %s ? (%s !== %s ? 0 : 1) : %s !== %s ? -1 : %s < %s ? -1 : %s > %s ? 1 : 0)",
226
+ g.wrap(x), g.wrap(x), g.wrap(y), g.wrap(y), g.wrap(y), g.wrap(y), g.wrap(x), g.wrap(y), g.wrap(x), g.wrap(y))
225
227
  }
226
228
 
227
229
  func (g *compareLessProgrammerGenerator) native(name string, x string, y string) string {
@@ -66,13 +66,11 @@ func (functionalAssertFunctionProgrammerNamespace) Write(props FunctionalAssertF
66
66
  }
67
67
  body = append(body, f.NewReturnStatement(r.Value))
68
68
  statements = append(statements, f.NewReturnStatement(
69
- f.NewArrowFunction(
70
- functionalIsProgrammer_asyncModifiers(r.Async, props.Context.Emit),
71
- nil,
72
- functionalIsProgrammer_parameters(props.Declaration, props.Context.Emit),
69
+ functionalIsProgrammer_function(
70
+ props.Context,
71
+ props.Declaration,
72
+ r.Async,
73
73
  functionalAssertProgrammer_returnType(props.Declaration),
74
- nil,
75
- f.NewToken(shimast.KindEqualsGreaterThanToken),
76
74
  f.NewBlock(f.NewNodeList(body), true),
77
75
  ),
78
76
  ))
@@ -66,21 +66,13 @@ func (functionalAssertParametersProgrammerNamespace) Write(props FunctionalAsser
66
66
  for _, exp := range result.Expressions {
67
67
  body = append(body, f.NewExpressionStatement(exp))
68
68
  }
69
- body = append(body, f.NewReturnStatement(f.NewCallExpression(
70
- props.Expression,
71
- nil,
72
- nil,
73
- f.NewNodeList(functionalIsProgrammer_parameterIdentifiers(props.Declaration, props.Context.Emit)),
74
- shimast.NodeFlagsNone,
75
- )))
69
+ body = append(body, f.NewReturnStatement(functionalIsProgrammer_call(props.Context, props.Expression, props.Declaration)))
76
70
  statements = append(statements, f.NewReturnStatement(
77
- f.NewArrowFunction(
78
- functionalIsProgrammer_asyncModifiers(output.Async, props.Context.Emit),
79
- nil,
80
- functionalIsProgrammer_parameters(props.Declaration, props.Context.Emit),
71
+ functionalIsProgrammer_function(
72
+ props.Context,
73
+ props.Declaration,
74
+ output.Async,
81
75
  functionalAssertProgrammer_returnType(props.Declaration),
82
- nil,
83
- f.NewToken(shimast.KindEqualsGreaterThanToken),
84
76
  f.NewBlock(f.NewNodeList(body), true),
85
77
  ),
86
78
  ))
@@ -62,14 +62,12 @@ func (functionAssertReturnProgrammerNamespace) Write(props FunctionAssertReturnP
62
62
  statements := []*shimast.Node{wrapper.Variable}
63
63
  statements = append(statements, result.Functions...)
64
64
  statements = append(statements, f.NewReturnStatement(
65
- f.NewArrowFunction(
66
- functionalIsProgrammer_asyncModifiers(result.Async, props.Context.Emit),
67
- nil,
68
- functionalIsProgrammer_parameters(props.Declaration, props.Context.Emit),
65
+ functionalIsProgrammer_function(
66
+ props.Context,
67
+ props.Declaration,
68
+ result.Async,
69
69
  functionalAssertProgrammer_returnType(props.Declaration),
70
- nil,
71
- f.NewToken(shimast.KindEqualsGreaterThanToken),
72
- result.Value,
70
+ f.NewBlock(f.NewNodeList([]*shimast.Node{f.NewReturnStatement(result.Value)}), true),
73
71
  ),
74
72
  ))
75
73
  return nativefactories.ExpressionFactory.SelfCall(
@@ -84,13 +82,7 @@ func (functionAssertReturnProgrammerNamespace) Decompose(props FunctionAssertRet
84
82
  Checker: props.Context.Checker,
85
83
  Declaration: props.Declaration,
86
84
  })
87
- caller := f.NewCallExpression(
88
- props.Expression,
89
- nil,
90
- nil,
91
- f.NewNodeList(functionalIsProgrammer_parameterIdentifiers(props.Declaration, props.Context.Emit)),
92
- shimast.NodeFlagsNone,
93
- )
85
+ caller := functionalIsProgrammer_call(props.Context, props.Expression, props.Declaration)
94
86
  value := caller
95
87
  if output.Async {
96
88
  value = f.NewAwaitExpression(caller)