typia 13.1.0 → 13.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. package/README.md +3 -0
  2. package/lib/_virtual/_rolldown/runtime.mjs +1 -5
  3. package/lib/executable/FileSystemIdentity.d.ts +21 -0
  4. package/lib/executable/FileSystemIdentity.js +183 -0
  5. package/lib/executable/FileSystemIdentity.js.map +1 -0
  6. package/lib/executable/FileSystemIdentity.mjs +129 -0
  7. package/lib/executable/FileSystemIdentity.mjs.map +1 -0
  8. package/lib/executable/TypiaGenerateWizard.js +264 -104
  9. package/lib/executable/TypiaGenerateWizard.js.map +1 -1
  10. package/lib/executable/TypiaGenerateWizard.mjs +233 -93
  11. package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
  12. package/lib/functional.d.ts +15 -12
  13. package/lib/functional.js.map +1 -1
  14. package/lib/functional.mjs.map +1 -1
  15. package/lib/internal/_ProtobufReader.d.ts +17 -0
  16. package/lib/internal/_ProtobufReader.js +117 -45
  17. package/lib/internal/_ProtobufReader.js.map +1 -1
  18. package/lib/internal/_ProtobufReader.mjs +108 -39
  19. package/lib/internal/_ProtobufReader.mjs.map +1 -1
  20. package/lib/internal/_createStandardSchema.js +18 -1
  21. package/lib/internal/_createStandardSchema.js.map +1 -1
  22. package/lib/internal/_createStandardSchema.mjs +12 -1
  23. package/lib/internal/_createStandardSchema.mjs.map +1 -1
  24. package/lib/internal/_decimal.d.ts +14 -0
  25. package/lib/internal/_decimal.js +61 -0
  26. package/lib/internal/_decimal.js.map +1 -0
  27. package/lib/internal/_decimal.mjs +49 -0
  28. package/lib/internal/_decimal.mjs.map +1 -0
  29. package/lib/internal/_httpQueryParseURLSearchParams.js +23 -2
  30. package/lib/internal/_httpQueryParseURLSearchParams.js.map +1 -1
  31. package/lib/internal/_httpQueryParseURLSearchParams.mjs +20 -2
  32. package/lib/internal/_httpQueryParseURLSearchParams.mjs.map +1 -1
  33. package/lib/internal/_isFormatByte.js +2 -5
  34. package/lib/internal/_isFormatByte.js.map +1 -1
  35. package/lib/internal/_isFormatByte.mjs +2 -5
  36. package/lib/internal/_isFormatByte.mjs.map +1 -1
  37. package/lib/internal/_isFormatDate.js +15 -2
  38. package/lib/internal/_isFormatDate.js.map +1 -1
  39. package/lib/internal/_isFormatDate.mjs +22 -2
  40. package/lib/internal/_isFormatDate.mjs.map +1 -1
  41. package/lib/internal/_isFormatDateTime.js +21 -2
  42. package/lib/internal/_isFormatDateTime.js.map +1 -1
  43. package/lib/internal/_isFormatDateTime.mjs +13 -2
  44. package/lib/internal/_isFormatDateTime.mjs.map +1 -1
  45. package/lib/internal/_isFormatIri.js +3 -2
  46. package/lib/internal/_isFormatIri.js.map +1 -1
  47. package/lib/internal/_isFormatIri.mjs +3 -2
  48. package/lib/internal/_isFormatIri.mjs.map +1 -1
  49. package/lib/internal/_isFormatIriReference.js +10 -2
  50. package/lib/internal/_isFormatIriReference.js.map +1 -1
  51. package/lib/internal/_isFormatIriReference.mjs +9 -2
  52. package/lib/internal/_isFormatIriReference.mjs.map +1 -1
  53. package/lib/internal/_isFormatUriReference.js +1 -1
  54. package/lib/internal/_isFormatUriReference.js.map +1 -1
  55. package/lib/internal/_isFormatUriReference.mjs +1 -1
  56. package/lib/internal/_isFormatUriReference.mjs.map +1 -1
  57. package/lib/internal/_isMultipleOf.d.ts +1 -0
  58. package/lib/internal/_isMultipleOf.js +13 -0
  59. package/lib/internal/_isMultipleOf.js.map +1 -0
  60. package/lib/internal/_isMultipleOf.mjs +12 -0
  61. package/lib/internal/_isMultipleOf.mjs.map +1 -0
  62. package/lib/internal/_isTypeFloat.js +1 -1
  63. package/lib/internal/_isTypeFloat.js.map +1 -1
  64. package/lib/internal/_isTypeFloat.mjs +1 -1
  65. package/lib/internal/_isTypeFloat.mjs.map +1 -1
  66. package/lib/internal/_isTypeInt64.js +1 -0
  67. package/lib/internal/_isTypeInt64.js.map +1 -1
  68. package/lib/internal/_isTypeInt64.mjs.map +1 -1
  69. package/lib/internal/_isTypeInt64Bigint.d.ts +1 -0
  70. package/lib/internal/_isTypeInt64Bigint.js +15 -0
  71. package/lib/internal/_isTypeInt64Bigint.js.map +1 -0
  72. package/lib/internal/_isTypeInt64Bigint.mjs +8 -0
  73. package/lib/internal/_isTypeInt64Bigint.mjs.map +1 -0
  74. package/lib/internal/_isTypeUint64.js +1 -0
  75. package/lib/internal/_isTypeUint64.js.map +1 -1
  76. package/lib/internal/_isTypeUint64.mjs.map +1 -1
  77. package/lib/internal/_isTypeUint64Bigint.d.ts +1 -0
  78. package/lib/internal/_isTypeUint64Bigint.js +10 -0
  79. package/lib/internal/_isTypeUint64Bigint.js.map +1 -0
  80. package/lib/internal/_isTypeUint64Bigint.mjs +8 -0
  81. package/lib/internal/_isTypeUint64Bigint.mjs.map +1 -0
  82. package/lib/internal/_isUniqueItems.js +96 -109
  83. package/lib/internal/_isUniqueItems.js.map +1 -1
  84. package/lib/internal/_isUniqueItems.mjs +62 -50
  85. package/lib/internal/_isUniqueItems.mjs.map +1 -1
  86. package/lib/internal/_notationAny.js +8 -1
  87. package/lib/internal/_notationAny.js.map +1 -1
  88. package/lib/internal/_notationAny.mjs +7 -1
  89. package/lib/internal/_notationAny.mjs.map +1 -1
  90. package/lib/internal/_notationAssign.d.ts +1 -0
  91. package/lib/internal/_notationAssign.js +18 -0
  92. package/lib/internal/_notationAssign.js.map +1 -0
  93. package/lib/internal/_notationAssign.mjs +17 -0
  94. package/lib/internal/_notationAssign.mjs.map +1 -0
  95. package/lib/internal/_notationCamel.js +30 -9
  96. package/lib/internal/_notationCamel.js.map +1 -1
  97. package/lib/internal/_notationCamel.mjs +13 -5
  98. package/lib/internal/_notationCamel.mjs.map +1 -1
  99. package/lib/internal/_notationKebab.d.ts +1 -0
  100. package/lib/internal/_notationKebab.js +15 -0
  101. package/lib/internal/_notationKebab.js.map +1 -0
  102. package/lib/internal/_notationKebab.mjs +15 -0
  103. package/lib/internal/_notationKebab.mjs.map +1 -0
  104. package/lib/internal/_notationKeyCollision.d.ts +1 -0
  105. package/lib/internal/_notationKeyCollision.js +8 -0
  106. package/lib/internal/_notationKeyCollision.js.map +1 -0
  107. package/lib/internal/_notationKeyCollision.mjs +8 -0
  108. package/lib/internal/_notationKeyCollision.mjs.map +1 -0
  109. package/lib/internal/_notationPascal.js +20 -5
  110. package/lib/internal/_notationPascal.js.map +1 -1
  111. package/lib/internal/_notationPascal.mjs +10 -5
  112. package/lib/internal/_notationPascal.mjs.map +1 -1
  113. package/lib/internal/_notationSnake.js +25 -22
  114. package/lib/internal/_notationSnake.js.map +1 -1
  115. package/lib/internal/_notationSnake.mjs +11 -11
  116. package/lib/internal/_notationSnake.mjs.map +1 -1
  117. package/lib/internal/_plainCloneAny.js +174 -38
  118. package/lib/internal/_plainCloneAny.js.map +1 -1
  119. package/lib/internal/_plainCloneAny.mjs +126 -22
  120. package/lib/internal/_plainCloneAny.mjs.map +1 -1
  121. package/lib/internal/_randomArray.d.ts +1 -1
  122. package/lib/internal/_randomArray.js +11 -4
  123. package/lib/internal/_randomArray.js.map +1 -1
  124. package/lib/internal/_randomArray.mjs +9 -3
  125. package/lib/internal/_randomArray.mjs.map +1 -1
  126. package/lib/internal/_randomFormatByte.d.ts +2 -1
  127. package/lib/internal/_randomFormatByte.js +2 -1
  128. package/lib/internal/_randomFormatByte.js.map +1 -1
  129. package/lib/internal/_randomFormatByte.mjs +2 -1
  130. package/lib/internal/_randomFormatByte.mjs.map +1 -1
  131. package/lib/internal/_randomFormatDate.d.ts +2 -0
  132. package/lib/internal/_randomFormatDate.js +3 -2
  133. package/lib/internal/_randomFormatDate.js.map +1 -1
  134. package/lib/internal/_randomFormatDate.mjs +3 -2
  135. package/lib/internal/_randomFormatDate.mjs.map +1 -1
  136. package/lib/internal/_randomFormatDatetime.d.ts +2 -0
  137. package/lib/internal/_randomFormatDatetime.js +3 -2
  138. package/lib/internal/_randomFormatDatetime.js.map +1 -1
  139. package/lib/internal/_randomFormatDatetime.mjs +3 -2
  140. package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
  141. package/lib/internal/_randomFormatDuration.d.ts +2 -1
  142. package/lib/internal/_randomFormatDuration.js +3 -2
  143. package/lib/internal/_randomFormatDuration.js.map +1 -1
  144. package/lib/internal/_randomFormatDuration.mjs +3 -2
  145. package/lib/internal/_randomFormatDuration.mjs.map +1 -1
  146. package/lib/internal/_randomFormatEmail.d.ts +2 -1
  147. package/lib/internal/_randomFormatEmail.js +8 -1
  148. package/lib/internal/_randomFormatEmail.js.map +1 -1
  149. package/lib/internal/_randomFormatEmail.mjs +5 -1
  150. package/lib/internal/_randomFormatEmail.mjs.map +1 -1
  151. package/lib/internal/_randomFormatHostname.d.ts +8 -1
  152. package/lib/internal/_randomFormatHostname.js +45 -2
  153. package/lib/internal/_randomFormatHostname.js.map +1 -1
  154. package/lib/internal/_randomFormatHostname.mjs +38 -2
  155. package/lib/internal/_randomFormatHostname.mjs.map +1 -1
  156. package/lib/internal/_randomFormatIdnEmail.d.ts +2 -1
  157. package/lib/internal/_randomFormatIdnEmail.js +16 -2
  158. package/lib/internal/_randomFormatIdnEmail.js.map +1 -1
  159. package/lib/internal/_randomFormatIdnEmail.mjs +11 -2
  160. package/lib/internal/_randomFormatIdnEmail.mjs.map +1 -1
  161. package/lib/internal/_randomFormatIdnHostname.d.ts +2 -1
  162. package/lib/internal/_randomFormatIdnHostname.js +26 -1
  163. package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
  164. package/lib/internal/_randomFormatIdnHostname.mjs +25 -2
  165. package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
  166. package/lib/internal/_randomFormatIpv4.d.ts +2 -1
  167. package/lib/internal/_randomFormatIpv4.js +2 -1
  168. package/lib/internal/_randomFormatIpv4.js.map +1 -1
  169. package/lib/internal/_randomFormatIpv4.mjs +2 -1
  170. package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
  171. package/lib/internal/_randomFormatIpv6.d.ts +2 -1
  172. package/lib/internal/_randomFormatIpv6.js +2 -1
  173. package/lib/internal/_randomFormatIpv6.js.map +1 -1
  174. package/lib/internal/_randomFormatIpv6.mjs +2 -1
  175. package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
  176. package/lib/internal/_randomFormatIri.d.ts +2 -1
  177. package/lib/internal/_randomFormatIri.js +1 -1
  178. package/lib/internal/_randomFormatIri.js.map +1 -1
  179. package/lib/internal/_randomFormatIri.mjs +1 -1
  180. package/lib/internal/_randomFormatIri.mjs.map +1 -1
  181. package/lib/internal/_randomFormatIriReference.d.ts +2 -1
  182. package/lib/internal/_randomFormatIriReference.js +1 -1
  183. package/lib/internal/_randomFormatIriReference.js.map +1 -1
  184. package/lib/internal/_randomFormatIriReference.mjs +1 -1
  185. package/lib/internal/_randomFormatIriReference.mjs.map +1 -1
  186. package/lib/internal/_randomFormatJsonPointer.d.ts +2 -1
  187. package/lib/internal/_randomFormatJsonPointer.js +8 -1
  188. package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
  189. package/lib/internal/_randomFormatJsonPointer.mjs +5 -1
  190. package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
  191. package/lib/internal/_randomFormatPassword.d.ts +2 -1
  192. package/lib/internal/_randomFormatPassword.js +7 -5
  193. package/lib/internal/_randomFormatPassword.js.map +1 -1
  194. package/lib/internal/_randomFormatPassword.mjs +5 -1
  195. package/lib/internal/_randomFormatPassword.mjs.map +1 -1
  196. package/lib/internal/_randomFormatRegex.d.ts +2 -1
  197. package/lib/internal/_randomFormatRegex.js +2 -1
  198. package/lib/internal/_randomFormatRegex.js.map +1 -1
  199. package/lib/internal/_randomFormatRegex.mjs +2 -1
  200. package/lib/internal/_randomFormatRegex.mjs.map +1 -1
  201. package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
  202. package/lib/internal/_randomFormatRelativeJsonPointer.js +3 -2
  203. package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
  204. package/lib/internal/_randomFormatRelativeJsonPointer.mjs +3 -2
  205. package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
  206. package/lib/internal/_randomFormatTime.d.ts +2 -1
  207. package/lib/internal/_randomFormatTime.js +3 -2
  208. package/lib/internal/_randomFormatTime.js.map +1 -1
  209. package/lib/internal/_randomFormatTime.mjs +3 -2
  210. package/lib/internal/_randomFormatTime.mjs.map +1 -1
  211. package/lib/internal/_randomFormatUri.d.ts +2 -1
  212. package/lib/internal/_randomFormatUri.js +1 -1
  213. package/lib/internal/_randomFormatUri.js.map +1 -1
  214. package/lib/internal/_randomFormatUri.mjs +1 -1
  215. package/lib/internal/_randomFormatUri.mjs.map +1 -1
  216. package/lib/internal/_randomFormatUriReference.d.ts +2 -1
  217. package/lib/internal/_randomFormatUriReference.js +1 -1
  218. package/lib/internal/_randomFormatUriReference.js.map +1 -1
  219. package/lib/internal/_randomFormatUriReference.mjs +1 -1
  220. package/lib/internal/_randomFormatUriReference.mjs.map +1 -1
  221. package/lib/internal/_randomFormatUriTemplate.d.ts +2 -1
  222. package/lib/internal/_randomFormatUriTemplate.js +1 -1
  223. package/lib/internal/_randomFormatUriTemplate.js.map +1 -1
  224. package/lib/internal/_randomFormatUriTemplate.mjs +1 -1
  225. package/lib/internal/_randomFormatUriTemplate.mjs.map +1 -1
  226. package/lib/internal/_randomFormatUrl.d.ts +2 -1
  227. package/lib/internal/_randomFormatUrl.js +21 -1
  228. package/lib/internal/_randomFormatUrl.js.map +1 -1
  229. package/lib/internal/_randomFormatUrl.mjs +18 -1
  230. package/lib/internal/_randomFormatUrl.mjs.map +1 -1
  231. package/lib/internal/_randomFormatUuid.d.ts +2 -1
  232. package/lib/internal/_randomFormatUuid.js +3 -2
  233. package/lib/internal/_randomFormatUuid.js.map +1 -1
  234. package/lib/internal/_randomFormatUuid.mjs +3 -2
  235. package/lib/internal/_randomFormatUuid.mjs.map +1 -1
  236. package/lib/internal/_randomInteger.js +59 -28
  237. package/lib/internal/_randomInteger.js.map +1 -1
  238. package/lib/internal/_randomInteger.mjs +56 -16
  239. package/lib/internal/_randomInteger.mjs.map +1 -1
  240. package/lib/internal/_randomMultiple.d.ts +8 -0
  241. package/lib/internal/_randomMultiple.js +168 -0
  242. package/lib/internal/_randomMultiple.js.map +1 -0
  243. package/lib/internal/_randomMultiple.mjs +158 -0
  244. package/lib/internal/_randomMultiple.mjs.map +1 -0
  245. package/lib/internal/_randomNumber.js +42 -42
  246. package/lib/internal/_randomNumber.js.map +1 -1
  247. package/lib/internal/_randomNumber.mjs +41 -27
  248. package/lib/internal/_randomNumber.mjs.map +1 -1
  249. package/lib/internal/_randomPattern.d.ts +2 -1
  250. package/lib/internal/_randomPattern.js +19 -4
  251. package/lib/internal/_randomPattern.js.map +1 -1
  252. package/lib/internal/_randomPattern.mjs +10 -4
  253. package/lib/internal/_randomPattern.mjs.map +1 -1
  254. package/lib/internal/_randomStringLength.d.ts +33 -0
  255. package/lib/internal/_randomStringLength.js +48 -0
  256. package/lib/internal/_randomStringLength.js.map +1 -0
  257. package/lib/internal/_randomStringLength.mjs +44 -0
  258. package/lib/internal/_randomStringLength.mjs.map +1 -0
  259. package/lib/internal/_stringLength.d.ts +1 -0
  260. package/lib/internal/_stringLength.js +11 -0
  261. package/lib/internal/_stringLength.js.map +1 -0
  262. package/lib/internal/_stringLength.mjs +10 -0
  263. package/lib/internal/_stringLength.mjs.map +1 -0
  264. package/lib/internal/_validateReport.js +4 -1
  265. package/lib/internal/_validateReport.js.map +1 -1
  266. package/lib/internal/_validateReport.mjs +2 -1
  267. package/lib/internal/_validateReport.mjs.map +1 -1
  268. package/lib/internal/private/__notationRename.d.ts +14 -0
  269. package/lib/internal/private/__notationRename.js +25 -0
  270. package/lib/internal/private/__notationRename.js.map +1 -0
  271. package/lib/internal/private/__notationRename.mjs +24 -0
  272. package/lib/internal/private/__notationRename.mjs.map +1 -0
  273. package/lib/json.d.ts +2 -2
  274. package/lib/json.mjs.map +1 -1
  275. package/lib/module.d.ts +2 -2
  276. package/lib/module.js.map +1 -1
  277. package/lib/module.mjs.map +1 -1
  278. package/lib/notations.d.ts +20 -4
  279. package/lib/notations.js.map +1 -1
  280. package/lib/notations.mjs.map +1 -1
  281. package/native/adapter/plugin_options.go +117 -0
  282. package/native/adapter/plugin_options_payload_matrix_test.go +181 -0
  283. package/native/cmd/ttsc-typia/any_array_type_tags_transform_test.go +63 -9
  284. package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +152 -0
  285. package/native/cmd/ttsc-typia/build.go +81 -64
  286. package/native/cmd/ttsc-typia/build_no_emit_preserves_analysis_options_test.go +67 -0
  287. package/native/cmd/ttsc-typia/build_no_emit_transform_diagnostics_test.go +138 -0
  288. package/native/cmd/ttsc-typia/build_plugin_options_come_from_payload_test.go +48 -0
  289. package/native/cmd/ttsc-typia/build_transactional_emit_success_test.go +81 -0
  290. package/native/cmd/ttsc-typia/build_transform_failure_atomicity_test.go +138 -0
  291. package/native/cmd/ttsc-typia/command_routes_and_diagnostics_coverage_test.go +3 -1
  292. package/native/cmd/ttsc-typia/compare_less_nan_transform_test.go +98 -0
  293. package/native/cmd/ttsc-typia/compare_native_object_overmatch_transform_test.go +161 -0
  294. package/native/cmd/ttsc-typia/compare_nondiscriminable_union_transform_test.go +343 -0
  295. package/native/cmd/ttsc-typia/compare_union_discrimination_transform_test.go +289 -0
  296. package/native/cmd/ttsc-typia/escaped_property_key_path_transform_test.go +193 -0
  297. package/native/cmd/ttsc-typia/finite_option_number_leaf_transform_test.go +240 -0
  298. package/native/cmd/ttsc-typia/functional_promised_type_transform_test.go +220 -0
  299. package/native/cmd/ttsc-typia/functional_receiver_transform_test.go +232 -0
  300. package/native/cmd/ttsc-typia/is_object_function_member_transform_test.go +205 -0
  301. package/native/cmd/ttsc-typia/json_application_alias_function_validation_transform_test.go +151 -0
  302. package/native/cmd/ttsc-typia/json_is_stringify_finite_number_transform_test.go +198 -0
  303. package/native/cmd/ttsc-typia/json_stringify_special_key_transform_test.go +238 -0
  304. package/native/cmd/ttsc-typia/main_wasm.go +21 -2
  305. package/native/cmd/ttsc-typia/native_collection_identity_is_transform_test.go +234 -0
  306. package/native/cmd/ttsc-typia/native_generic_name_guard_is_transform_test.go +194 -0
  307. package/native/cmd/ttsc-typia/native_name_collision_is_transform_test.go +204 -0
  308. package/native/cmd/ttsc-typia/non_trailing_rest_tuple_transform_test.go +23 -11
  309. package/native/cmd/ttsc-typia/notation_dynamic_keys_transform_test.go +286 -0
  310. package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +1 -1
  311. package/native/cmd/ttsc-typia/notation_literal_collision_transform_test.go +164 -0
  312. package/native/cmd/ttsc-typia/notation_pascal_case_transform_test.go +230 -0
  313. package/native/cmd/ttsc-typia/notation_unicode_key_transform_test.go +309 -0
  314. package/native/cmd/ttsc-typia/pattern_line_terminator_escape_transform_test.go +224 -0
  315. package/native/cmd/ttsc-typia/plain_prune_union_object_overmatch_transform_test.go +219 -0
  316. package/native/cmd/ttsc-typia/plugin_options_payload_helpers_test.go +181 -0
  317. package/native/cmd/ttsc-typia/private_field_filter_is_transform_test.go +278 -0
  318. package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +73 -27
  319. package/native/cmd/ttsc-typia/project_dependencies_barrel_reexport_transform_test.go +120 -0
  320. package/native/cmd/ttsc-typia/project_dependencies_collapsed_alias_transform_test.go +134 -0
  321. package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +135 -0
  322. package/native/cmd/ttsc-typia/project_dependencies_default_barrel_transform_test.go +114 -0
  323. package/native/cmd/ttsc-typia/project_dependencies_empty_heritage_transform_test.go +100 -0
  324. package/native/cmd/ttsc-typia/project_dependencies_envelope_transform_test.go +148 -0
  325. package/native/cmd/ttsc-typia/project_dependencies_index_signature_alias_transform_test.go +139 -0
  326. package/native/cmd/ttsc-typia/project_dependencies_local_reexport_transform_test.go +122 -0
  327. package/native/cmd/ttsc-typia/project_dependencies_signature_alias_transform_test.go +125 -0
  328. package/native/cmd/ttsc-typia/project_dependencies_star_barrel_transform_test.go +112 -0
  329. package/native/cmd/ttsc-typia/project_reference_graph_envelope_transform_test.go +190 -0
  330. package/native/cmd/ttsc-typia/protobuf_is_encode_finite_number_transform_test.go +98 -0
  331. package/native/cmd/ttsc-typia/protobuf_sequence_field_numbers_transform_test.go +52 -22
  332. package/native/cmd/ttsc-typia/symbol_key_member_filter_transform_test.go +279 -0
  333. package/native/cmd/ttsc-typia/template_interpolation_type_tags_transform_test.go +86 -23
  334. package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
  335. package/native/cmd/ttsc-typia/transform.go +228 -39
  336. package/native/cmd/ttsc-typia/{transform_declaration_source_produces_no_js_test.go → transform_declaration_source_produces_no_javascript_test.go} +10 -2
  337. package/native/cmd/ttsc-typia/transform_fixtures_emit_coverage_test.go +21 -4
  338. package/native/cmd/ttsc-typia/transform_helpers_test.go +159 -1
  339. package/native/cmd/ttsc-typia/transform_plugin_options_come_from_payload_test.go +43 -0
  340. package/native/cmd/ttsc-typia/transform_single_file_failure_atomicity_test.go +114 -0
  341. package/native/cmd/ttsc-typia/transform_single_file_failure_writes_no_stdout_test.go +43 -0
  342. package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go +81 -0
  343. package/native/cmd/ttsc-typia/transform_single_file_js_empty_emit_reports_no_output_test.go +100 -0
  344. package/native/cmd/ttsc-typia/transform_single_file_js_locates_output_across_layouts_test.go +160 -0
  345. package/native/cmd/ttsc-typia/transform_single_file_success_publishes_artifact_test.go +54 -0
  346. package/native/cmd/ttsc-typia/transform_wasm_host_argv_reports_diagnostics_test.go +39 -0
  347. package/native/cmd/ttsc-typia/tuple_optional_compare_clone_transform_test.go +227 -0
  348. package/native/core/factories/FormatCheatSheet.go +40 -7
  349. package/native/core/factories/IdentifierFactory.go +131 -4
  350. package/native/core/factories/MetadataCommentTagFactory.go +83 -40
  351. package/native/core/factories/MetadataTypeTagFactory.go +13 -1
  352. package/native/core/factories/NumericRangeFactory.go +60 -17
  353. package/native/core/factories/ProtobufFactory.go +7 -4
  354. package/native/core/factories/factory_utility_coverage_test.go +8 -2
  355. package/native/core/factories/format_alias_resolves_to_cheat_sheet_test.go +57 -0
  356. package/native/core/factories/format_alias_table_targets_the_cheat_sheet_test.go +44 -0
  357. package/native/core/factories/identifier_factory_postfix_escapes_every_key_test.go +147 -0
  358. package/native/core/factories/identifier_factory_postfix_survives_every_code_point_test.go +86 -0
  359. package/native/core/factories/internal/metadata/MetadataHelper.go +134 -7
  360. package/native/core/factories/internal/metadata/emplace_metadata_object.go +116 -8
  361. package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
  362. package/native/core/factories/internal/metadata/iterate_metadata_function.go +4 -11
  363. package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +8 -6
  364. package/native/core/factories/internal/metadata/iterate_metadata_map.go +9 -0
  365. package/native/core/factories/internal/metadata/iterate_metadata_native.go +27 -2
  366. package/native/core/factories/internal/metadata/iterate_metadata_set.go +9 -0
  367. package/native/core/factories/internal/metadata/js_doc_link_text_test.go +69 -0
  368. package/native/core/factories/internal/metadata/type_arguments_precondition_test.go +70 -0
  369. package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +39 -0
  370. package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go +84 -0
  371. package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go +60 -0
  372. package/native/core/factories/metadata_type_tag_factory_declarations_test.go +86 -0
  373. package/native/core/factories/metadata_type_tag_factory_keeps_bool_form_exclusivity_test.go +38 -0
  374. package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go +65 -0
  375. package/native/core/factories/metadata_type_tag_factory_rejects_duplicated_array_form_tags_test.go +41 -0
  376. package/native/core/factories/numeric_range_factory_enforces_64bit_bounds_test.go +69 -0
  377. package/native/core/factories/protobuf_recovery_ownership_test.go +64 -0
  378. package/native/core/programmers/IsProgrammer.go +15 -1
  379. package/native/core/programmers/RandomProgrammer.go +51 -14
  380. package/native/core/programmers/compare/CompareEqualProgrammer.go +393 -5
  381. package/native/core/programmers/compare/CompareLessProgrammer.go +4 -2
  382. package/native/core/programmers/functional/FunctionalAssertFunctionProgrammer.go +4 -6
  383. package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +5 -13
  384. package/native/core/programmers/functional/FunctionalAssertReturnProgrammer.go +6 -14
  385. package/native/core/programmers/functional/FunctionalIsFunctionProgrammer.go +4 -6
  386. package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +49 -14
  387. package/native/core/programmers/functional/FunctionalIsReturnProgrammer.go +5 -13
  388. package/native/core/programmers/functional/FunctionalValidateFunctionProgrammer.go +4 -6
  389. package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +5 -13
  390. package/native/core/programmers/functional/FunctionalValidateReturnProgrammer.go +5 -13
  391. package/native/core/programmers/functional/internal/FunctionalGeneralProgrammer.go +4 -17
  392. package/native/core/programmers/helpers/CloneJoiner.go +32 -0
  393. package/native/core/programmers/helpers/NotationJoiner.go +86 -28
  394. package/native/core/programmers/helpers/StringifyJoinder.go +32 -1
  395. package/native/core/programmers/helpers/UnionExplorer.go +203 -61
  396. package/native/core/programmers/helpers/joiner_branch_coverage_test.go +5 -3
  397. package/native/core/programmers/helpers/union_explorer_coverage_test.go +1 -1
  398. package/native/core/programmers/internal/CheckerProgrammer.go +100 -48
  399. package/native/core/programmers/iterate/check_template.go +344 -32
  400. package/native/core/programmers/iterate/json_schema_discriminator.go +36 -10
  401. package/native/core/programmers/iterate/json_schema_discriminator_declaration_syntax_test.go +205 -0
  402. package/native/core/programmers/iterate/openapi_v3_downgrader.go +641 -0
  403. package/native/core/programmers/iterate/openapi_v3_downgrader_boolean_default_test.go +95 -0
  404. package/native/core/programmers/iterate/openapi_v3_downgrader_test.go +123 -0
  405. package/native/core/programmers/iterate/template_interpolation_tags_test.go +40 -8
  406. package/native/core/programmers/iterate/template_runtime_pattern.go +52 -7
  407. package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
  408. package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
  409. package/native/core/programmers/llm/LlmApplicationProgrammer.go +12 -10
  410. package/native/core/programmers/llm/LlmSchemaProgrammer.go +23 -6
  411. package/native/core/programmers/llm/llm_reference_codec_test.go +24 -0
  412. package/native/core/programmers/notations/NotationGeneralProgrammer.go +183 -67
  413. package/native/core/programmers/notations/notation_general_helpers_test.go +1 -3
  414. package/native/core/programmers/notations/notation_general_programmer_pascal_multiword_test.go +72 -0
  415. package/native/core/programmers/notations/notation_general_programmer_underscore_boundary_test.go +68 -0
  416. package/native/core/programmers/plain/PlainClassifyProgrammer.go +23 -15
  417. package/native/core/programmers/plain/PlainCloneProgrammer.go +20 -7
  418. package/native/core/programmers/plain/PlainPruneProgrammer.go +19 -5
  419. package/native/core/programmers/plain/plain_tuple_seed_recovery_ownership_test.go +25 -0
  420. package/native/core/programmers/protobuf/ProtobufDecodeProgrammer.go +37 -28
  421. package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +40 -21
  422. package/native/core/programmers/protobuf/protobuf_programmer_helper_coverage_test.go +26 -0
  423. package/native/core/programmers/random_programmer_length_argument_test.go +53 -0
  424. package/native/core/schemas/metadata/MetadataCollection.go +270 -20
  425. package/native/core/schemas/metadata/MetadataDependency.go +388 -0
  426. package/native/core/schemas/metadata/MetadataObjectType.go +17 -4
  427. package/native/core/schemas/metadata/metadata_collection_generic_argument_dot_test.go +122 -0
  428. package/native/core/schemas/metadata/metadata_collection_name_allocation_test.go +147 -0
  429. package/native/core/schemas/metadata/metadata_collection_openapi_name_cascade_test.go +55 -0
  430. package/native/core/schemas/metadata/metadata_collection_openapi_name_test.go +68 -0
  431. package/native/core/utils/PatternUtil.go +13 -0
  432. package/native/core/utils/PromiseTypeFactory.go +59 -0
  433. package/native/core/utils/ProtobufNameEncoder.go +8 -0
  434. package/native/core/utils/promise_type_factory_semantics_test.go +118 -0
  435. package/native/go.mod +9 -1
  436. package/native/transform/CallExpressionTransformer.go +12 -0
  437. package/native/transform/features/json/JsonApplicationTransformer.go +1 -1
  438. package/native/transform/features/json/JsonSchemaTransformer.go +1 -1
  439. package/native/transform/features/json/JsonSchemasTransformer.go +5 -4
  440. package/package.json +16 -4
  441. package/src/executable/FileSystemIdentity.ts +189 -0
  442. package/src/executable/TypiaGenerateWizard.ts +377 -110
  443. package/src/functional.ts +30 -60
  444. package/src/internal/_ProtobufReader.ts +129 -43
  445. package/src/internal/_createStandardSchema.ts +15 -1
  446. package/src/internal/_decimal.ts +69 -0
  447. package/src/internal/_httpQueryParseURLSearchParams.ts +24 -2
  448. package/src/internal/_isFormatByte.ts +2 -5
  449. package/src/internal/_isFormatDate.ts +15 -2
  450. package/src/internal/_isFormatDateTime.ts +28 -2
  451. package/src/internal/_isFormatIri.ts +5 -2
  452. package/src/internal/_isFormatIriReference.ts +11 -3
  453. package/src/internal/_isFormatUriReference.ts +1 -1
  454. package/src/internal/_isMultipleOf.ts +8 -0
  455. package/src/internal/_isTypeFloat.ts +1 -1
  456. package/src/internal/_isTypeInt64.ts +1 -0
  457. package/src/internal/_isTypeInt64Bigint.ts +12 -0
  458. package/src/internal/_isTypeUint64.ts +1 -0
  459. package/src/internal/_isTypeUint64Bigint.ts +7 -0
  460. package/src/internal/_isUniqueItems.ts +134 -132
  461. package/src/internal/_notationAny.ts +9 -4
  462. package/src/internal/_notationAssign.ts +20 -0
  463. package/src/internal/_notationCamel.ts +31 -10
  464. package/src/internal/_notationKebab.ts +11 -0
  465. package/src/internal/_notationKeyCollision.ts +9 -0
  466. package/src/internal/_notationPascal.ts +19 -6
  467. package/src/internal/_notationSnake.ts +24 -21
  468. package/src/internal/_plainCloneAny.ts +208 -33
  469. package/src/internal/_randomArray.ts +13 -4
  470. package/src/internal/_randomFormatByte.ts +4 -1
  471. package/src/internal/_randomFormatDate.ts +17 -12
  472. package/src/internal/_randomFormatDatetime.ts +15 -10
  473. package/src/internal/_randomFormatDuration.ts +16 -14
  474. package/src/internal/_randomFormatEmail.ts +8 -2
  475. package/src/internal/_randomFormatHostname.ts +48 -1
  476. package/src/internal/_randomFormatIdnEmail.ts +18 -2
  477. package/src/internal/_randomFormatIdnHostname.ts +34 -2
  478. package/src/internal/_randomFormatIpv4.ts +3 -2
  479. package/src/internal/_randomFormatIpv6.ts +3 -2
  480. package/src/internal/_randomFormatIri.ts +3 -1
  481. package/src/internal/_randomFormatIriReference.ts +3 -1
  482. package/src/internal/_randomFormatJsonPointer.ts +8 -2
  483. package/src/internal/_randomFormatPassword.ts +11 -6
  484. package/src/internal/_randomFormatRegex.ts +4 -1
  485. package/src/internal/_randomFormatRelativeJsonPointer.ts +13 -6
  486. package/src/internal/_randomFormatTime.ts +13 -10
  487. package/src/internal/_randomFormatUri.ts +3 -1
  488. package/src/internal/_randomFormatUriReference.ts +3 -1
  489. package/src/internal/_randomFormatUriTemplate.ts +3 -1
  490. package/src/internal/_randomFormatUrl.ts +25 -2
  491. package/src/internal/_randomFormatUuid.ts +10 -6
  492. package/src/internal/_randomInteger.ts +87 -40
  493. package/src/internal/_randomMultiple.ts +245 -0
  494. package/src/internal/_randomNumber.ts +72 -55
  495. package/src/internal/_randomPattern.ts +26 -4
  496. package/src/internal/_randomStringLength.ts +72 -0
  497. package/src/internal/_stringLength.ts +5 -0
  498. package/src/internal/_validateReport.ts +5 -1
  499. package/src/internal/private/__notationRename.ts +24 -0
  500. package/src/json.ts +2 -2
  501. package/src/module.ts +4 -6
  502. package/src/notations.ts +20 -4
  503. package/lib/internal/private/__notationCapitalize.d.ts +0 -1
  504. package/lib/internal/private/__notationCapitalize.js +0 -6
  505. package/lib/internal/private/__notationCapitalize.js.map +0 -1
  506. package/lib/internal/private/__notationCapitalize.mjs +0 -6
  507. package/lib/internal/private/__notationCapitalize.mjs.map +0 -1
  508. package/lib/internal/private/__notationUnsnake.d.ts +0 -4
  509. package/lib/internal/private/__notationUnsnake.js +0 -26
  510. package/lib/internal/private/__notationUnsnake.js.map +0 -1
  511. package/lib/internal/private/__notationUnsnake.mjs +0 -15
  512. package/lib/internal/private/__notationUnsnake.mjs.map +0 -1
  513. package/native/cmd/ttsc-typia/plugin_options_missing_config_test.go +0 -26
  514. package/native/cmd/ttsc-typia/plugin_options_undefined_false_test.go +0 -36
  515. package/src/internal/private/__notationCapitalize.ts +0 -2
  516. package/src/internal/private/__notationUnsnake.ts +0 -24
@@ -0,0 +1,309 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ // TestNotationUnicodeKeyTransform verifies the notation emit keeps a non-ASCII
12
+ // key intact and agrees with the runtime helper.
13
+ //
14
+ // Issue #2227: the emit computed each renamed key by slicing one *byte*
15
+ // (`value[:1]`) before case-converting it, so a multi-byte rune's lead byte was
16
+ // handed to the case operation on its own, could not be decoded, and came back
17
+ // as U+FFFD — `typia.notations.createPascal<{ "École": number }>()` emitted the
18
+ // key `"��cole"`. The static path corrupted the key while the dynamic
19
+ // (index-signature) path, which calls the runtime `_notationPascal`, did not, so
20
+ // one object could carry two different renamings of the same character and the
21
+ // emitted key did not match its declared `CamelCase<T>` / `PascalCase<T>` type.
22
+ //
23
+ // The same fix covers the second half of the divergence: JavaScript performs
24
+ // Unicode *full* case conversion while Go's `strings.ToUpper`/`ToLower` perform
25
+ // the *simple* per-rune mapping, so the emit also disagreed with the runtime on
26
+ // `ß` -> `SS`, `İ` -> `i` + U+0307, and the word-final sigma `ΑΣ` -> `ας`. That
27
+ // half reached `snake`/`kebab` too, which never sliced a byte.
28
+ //
29
+ // Every key and every expectation below is written with `\uXXXX` escapes so the
30
+ // fixture cannot be silently renormalized (NFC/NFD) by an editor, and so the
31
+ // combining-mark and surrogate-pair cases stay exactly what they claim to be.
32
+ //
33
+ // 1. Transform a fixture whose keys cover a multi-byte first character, a
34
+ // multi-byte character right after an underscore, a key that is a single
35
+ // multi-byte character, a combining mark (NFD), a surrogate pair, and the
36
+ // case-folding-sensitive `İ`, `ß`, and word-final sigma — plus two ASCII
37
+ // keys as a regression anchor.
38
+ // 2. Require the emitted JavaScript to carry no U+FFFD at all.
39
+ // 3. Execute each statically emitted converter and assert its key-to-value map
40
+ // equals the expectation derived from JavaScript's own case semantics.
41
+ // 4. Execute the dynamic `Record` converter, which routes through the runtime
42
+ // `_notation*` helper, over the same keys and require an identical map, so
43
+ // the compile-time emit and the runtime helper are proven equal per key.
44
+ func TestNotationUnicodeKeyTransform(t *testing.T) {
45
+ project := notationUnicodeKeyProject(t)
46
+ out, errText, code := ttscTypiaTestCapture(func() int {
47
+ return runTransform([]string{
48
+ "--cwd", project,
49
+ "--tsconfig", "tsconfig.json",
50
+ "--file", "src/main.ts",
51
+ "--output", "js",
52
+ })
53
+ })
54
+ if code != 0 {
55
+ t.Fatalf("unicode notation transform failed: code=%d stderr=\n%s", code, errText)
56
+ }
57
+ // The printer escapes every non-ASCII code unit, so a corrupted key reaches
58
+ // the output as the escape text rather than as the replacement rune itself.
59
+ // Both forms are rejected; checking only the rune would never fire.
60
+ if strings.Contains(out, `\uFFFD`) || strings.ContainsRune(out, '�') {
61
+ t.Fatalf("emitted converter must not contain U+FFFD; a key was corrupted by byte slicing:\n%s", out)
62
+ }
63
+ // Pin the exact emitted assignments for the witnesses of each half of the
64
+ // defect: the multi-byte first character and the post-underscore segment that
65
+ // byte slicing destroyed, plus the two characters that the simple per-rune
66
+ // case mapping got wrong. The printer escapes every non-ASCII code unit, so
67
+ // these are the literal bytes of the emitted JavaScript.
68
+ for _, assignment := range []string{
69
+ `["\u00E9cole"]: input["\u00C9cole"]`,
70
+ `["Key\u00D6lig"]: input["key_\u00D6lig"]`,
71
+ `["SS"]: input["\u00DF"]`,
72
+ `["i\u0307stanbul"]: input["\u0130stanbul"]`,
73
+ } {
74
+ if !strings.Contains(out, assignment) {
75
+ t.Fatalf("emitted converter should contain the assignment %s:\n%s", assignment, out)
76
+ }
77
+ }
78
+ notationUnicodeKeyRunRuntimeCases(t, project, out)
79
+ }
80
+
81
+ func notationUnicodeKeyProject(t *testing.T) string {
82
+ t.Helper()
83
+ root := ttscTypiaTestRepoRoot(t)
84
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
85
+ if err := os.MkdirAll(base, 0o755); err != nil {
86
+ t.Fatalf("mkdir temp base: %v", err)
87
+ }
88
+ dir, err := os.MkdirTemp(base, "notation-unicode-")
89
+ if err != nil {
90
+ t.Fatalf("create temp fixture: %v", err)
91
+ }
92
+ t.Cleanup(func() {
93
+ _ = os.RemoveAll(dir)
94
+ })
95
+ src := filepath.Join(dir, "src")
96
+ if err := os.MkdirAll(src, 0o755); err != nil {
97
+ t.Fatalf("mkdir fixture src: %v", err)
98
+ }
99
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(notationUnicodeKeyTSConfig), 0o644); err != nil {
100
+ t.Fatalf("write tsconfig: %v", err)
101
+ }
102
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(notationUnicodeKeySource), 0o644); err != nil {
103
+ t.Fatalf("write source: %v", err)
104
+ }
105
+ return dir
106
+ }
107
+
108
+ func notationUnicodeKeyRunRuntimeCases(t *testing.T, project string, js string) {
109
+ t.Helper()
110
+ node, err := exec.LookPath("node")
111
+ if err != nil {
112
+ t.Skip("node executable not found")
113
+ }
114
+ runtimeDir := filepath.Join(project, "runtime")
115
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
116
+ t.Fatalf("mkdir runtime dir: %v", err)
117
+ }
118
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
119
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
120
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
121
+ t.Fatalf("write runtime module: %v", err)
122
+ }
123
+ runner := filepath.Join(runtimeDir, "run.cjs")
124
+ if err := os.WriteFile(runner, []byte(notationUnicodeKeyRuntimeRunner), 0o644); err != nil {
125
+ t.Fatalf("write runtime runner: %v", err)
126
+ }
127
+ cmd := exec.Command(node, runner)
128
+ cmd.Dir = runtimeDir
129
+ output, err := cmd.CombinedOutput()
130
+ if err != nil {
131
+ t.Fatalf("unicode notation runtime cases failed: %v\n%s", err, output)
132
+ }
133
+ }
134
+
135
+ const notationUnicodeKeyTSConfig = `{
136
+ "compilerOptions": {
137
+ "target": "ES2022",
138
+ "module": "commonjs",
139
+ "moduleResolution": "bundler",
140
+ "ignoreDeprecations": "6.0",
141
+ "types": ["*"],
142
+ "esModuleInterop": true,
143
+ "strict": true,
144
+ "skipLibCheck": true
145
+ },
146
+ "include": ["src"]
147
+ }
148
+ `
149
+
150
+ const notationUnicodeKeySource = `import typia from "typia";
151
+
152
+ interface SourceRecord {
153
+ "\u00C9cole": number;
154
+ "\u00F6lwert": number;
155
+ "\u65E5\u672C\u8A9E": number;
156
+ "key_\u00D6lig": number;
157
+ "\u00D6": number;
158
+ "\u0130stanbul": number;
159
+ "\u00DF": number;
160
+ "\uD801\uDC28test": number;
161
+ "\u0391\u03A3_\u0391\u03A3": number;
162
+ "e\u0301cole": number;
163
+ "\u00FCber_Stra\u00DFe": number;
164
+ MAX_COUNT: number;
165
+ fooBar: number;
166
+ }
167
+
168
+ type DynamicRecord = Record<string, number>;
169
+
170
+ export const toCamel = typia.notations.createCamel<SourceRecord>();
171
+ export const toPascal = typia.notations.createPascal<SourceRecord>();
172
+ export const toSnake = typia.notations.createSnake<SourceRecord>();
173
+ export const toKebab = typia.notations.createKebab<SourceRecord>();
174
+
175
+ export const toCamelDynamic = typia.notations.createCamel<DynamicRecord>();
176
+ export const toPascalDynamic = typia.notations.createPascal<DynamicRecord>();
177
+ export const toSnakeDynamic = typia.notations.createSnake<DynamicRecord>();
178
+ export const toKebabDynamic = typia.notations.createKebab<DynamicRecord>();
179
+ `
180
+
181
+ const notationUnicodeKeyRuntimeRunner = `const mod = require("./main.cjs");
182
+
183
+ // Every source key carries a distinct value, so comparing the whole
184
+ // key-to-value map proves the per-key renaming rather than just the key set.
185
+ const input = {
186
+ ["\u00C9cole"]: 1,
187
+ ["\u00F6lwert"]: 2,
188
+ ["\u65E5\u672C\u8A9E"]: 3,
189
+ ["key_\u00D6lig"]: 4,
190
+ ["\u00D6"]: 5,
191
+ ["\u0130stanbul"]: 6,
192
+ ["\u00DF"]: 7,
193
+ ["\uD801\uDC28test"]: 8,
194
+ ["\u0391\u03A3_\u0391\u03A3"]: 9,
195
+ ["e\u0301cole"]: 10,
196
+ ["\u00FCber_Stra\u00DFe"]: 11,
197
+ ["MAX_COUNT"]: 12,
198
+ ["fooBar"]: 13,
199
+ };
200
+
201
+ // Expectations are JavaScript's own case semantics, not a snapshot of the Go
202
+ // emit: full case conversion (ß -> SS, İ -> i + U+0307, word-final
203
+ // sigma ΑΣ -> ας) and UTF-16 code-unit indexing, under which
204
+ // str[0] of an astral character is an uncased lone surrogate and stays put.
205
+ const expected = {
206
+ camel: {
207
+ ["\u00E9cole"]: 1,
208
+ ["\u00F6lwert"]: 2,
209
+ ["\u65E5\u672C\u8A9E"]: 3,
210
+ ["key\u00D6lig"]: 4,
211
+ ["\u00F6"]: 5,
212
+ ["i\u0307stanbul"]: 6,
213
+ ["\u00DF"]: 7,
214
+ ["\uD801\uDC28test"]: 8,
215
+ ["\u03B1\u03C2\u0391\u03C3"]: 9,
216
+ ["e\u0301cole"]: 10,
217
+ ["\u00FCberStra\u00DFe"]: 11,
218
+ ["maxCount"]: 12,
219
+ ["fooBar"]: 13,
220
+ },
221
+ pascal: {
222
+ ["\u00C9cole"]: 1,
223
+ ["\u00D6lwert"]: 2,
224
+ ["\u65E5\u672C\u8A9E"]: 3,
225
+ ["Key\u00D6lig"]: 4,
226
+ ["\u00D6"]: 5,
227
+ ["\u0130stanbul"]: 6,
228
+ ["SS"]: 7,
229
+ ["\uD801\uDC28test"]: 8,
230
+ ["\u0391\u03C3\u0391\u03C3"]: 9,
231
+ ["E\u0301cole"]: 10,
232
+ ["\u00DCberStra\u00DFe"]: 11,
233
+ ["MaxCount"]: 12,
234
+ ["FooBar"]: 13,
235
+ },
236
+ snake: {
237
+ ["\u00E9cole"]: 1,
238
+ ["\u00F6lwert"]: 2,
239
+ ["\u65E5\u672C\u8A9E"]: 3,
240
+ ["key_\u00F6lig"]: 4,
241
+ ["\u00F6"]: 5,
242
+ ["i\u0307stanbul"]: 6,
243
+ ["\u00DF"]: 7,
244
+ ["\uD801\uDC28test"]: 8,
245
+ ["\u03B1\u03C2_\u03B1\u03C2"]: 9,
246
+ ["e\u0301cole"]: 10,
247
+ ["\u00FCber_stra\u00DFe"]: 11,
248
+ ["max_count"]: 12,
249
+ ["foo_bar"]: 13,
250
+ },
251
+ kebab: {
252
+ ["\u00E9cole"]: 1,
253
+ ["\u00F6lwert"]: 2,
254
+ ["\u65E5\u672C\u8A9E"]: 3,
255
+ ["key-\u00F6lig"]: 4,
256
+ ["\u00F6"]: 5,
257
+ ["i\u0307stanbul"]: 6,
258
+ ["\u00DF"]: 7,
259
+ ["\uD801\uDC28test"]: 8,
260
+ ["\u03B1\u03C2-\u03B1\u03C2"]: 9,
261
+ ["e\u0301cole"]: 10,
262
+ ["\u00FCber-stra\u00DFe"]: 11,
263
+ ["max-count"]: 12,
264
+ ["foo-bar"]: 13,
265
+ },
266
+ };
267
+
268
+ const normalize = (object) =>
269
+ JSON.stringify(
270
+ Object.entries(object)
271
+ .map(([key, value]) => [Array.from(key, (c) => c.charCodeAt(0)), value])
272
+ .sort((a, b) => (String(a) < String(b) ? -1 : 1)),
273
+ );
274
+
275
+ const notations = ["camel", "pascal", "snake", "kebab"];
276
+ const capitalize = (name) => name[0].toUpperCase() + name.substring(1);
277
+
278
+ for (const notation of notations) {
279
+ const want = normalize(expected[notation]);
280
+
281
+ // The statically emitted converter: one property assignment per known key.
282
+ const staticResult = mod["to" + capitalize(notation)](input);
283
+ if (normalize(staticResult) !== want) {
284
+ throw new Error(
285
+ "static " + notation + " emit disagreed with JavaScript case semantics:\n" +
286
+ " expected " + want + "\n" +
287
+ " actual " + normalize(staticResult),
288
+ );
289
+ }
290
+
291
+ // The dynamic converter: one runtime _notation* call per index-signature key.
292
+ const dynamicResult = mod["to" + capitalize(notation) + "Dynamic"](input);
293
+ if (normalize(dynamicResult) !== normalize(staticResult)) {
294
+ throw new Error(
295
+ "static " + notation + " emit disagreed with the runtime helper:\n" +
296
+ " runtime " + normalize(dynamicResult) + "\n" +
297
+ " emit " + normalize(staticResult),
298
+ );
299
+ }
300
+
301
+ for (const key of Object.keys(staticResult)) {
302
+ if (key.includes("�")) {
303
+ throw new Error(
304
+ "renamed " + notation + " key contains U+FFFD: " + JSON.stringify(key),
305
+ );
306
+ }
307
+ }
308
+ }
309
+ `
@@ -0,0 +1,224 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ // TestPatternLineTerminatorEscapeTransform verifies that a line terminator in a
12
+ // structural (template-literal-type or dynamic-key) pattern is escaped before it
13
+ // is spliced into an emitted `RegExp(/.../)` literal.
14
+ //
15
+ // A JavaScript regex literal cannot contain a raw line terminator, so a template
16
+ // literal type or dynamic key whose literal part holds one of the four
17
+ // ECMAScript LineTerminators (LF, CR, U+2028, U+2029) produced an unparsable
18
+ // module while the transform still exited 0 (a false-green). `PatternUtil.Escape`
19
+ // escaped the regex metacharacters but not the line terminators, and it is the
20
+ // single source feeding every regex-literal sink (`check_template`,
21
+ // `stringify_dynamic_properties`, `prune_object_properties`, and the
22
+ // clone/prune/classify/notation joiners), so one fixture that drives `is`,
23
+ // `json.stringify`, `clone`, `prune`, and `notations` over line-terminator
24
+ // patterns exercises them all (#2211).
25
+ //
26
+ // 1. Transform a fixture whose template literal types and Record dynamic keys
27
+ // carry each of the four line terminators, across every affected operation.
28
+ // 2. Assert the transform exits 0 and `node --check` accepts the whole emit as
29
+ // JavaScript -- RED before the fix (raw LF/CR/LS/PS in a regex literal).
30
+ // 3. Execute the emit and assert each `is` predicate matches a
31
+ // line-terminator-containing value and rejects a value that lacks it.
32
+ func TestPatternLineTerminatorEscapeTransform(t *testing.T) {
33
+ project := patternLineTerminatorProject(t)
34
+ js := patternLineTerminatorTransform(t, project)
35
+ // A line-terminator-free template still lowers to its historical pattern, so
36
+ // nothing but the escaped line terminators changes.
37
+ if !strings.Contains(js, "RegExp(/^prefix(.*)postfix$/)") {
38
+ t.Fatalf("line-terminator-free pattern must keep its historical form:\n%s", js)
39
+ }
40
+ patternLineTerminatorCheckSyntax(t, project, js)
41
+ patternLineTerminatorRunRuntimeCases(t, project, js)
42
+ }
43
+
44
+ func patternLineTerminatorProject(t *testing.T) string {
45
+ t.Helper()
46
+ root := ttscTypiaTestRepoRoot(t)
47
+ base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
48
+ if err := os.MkdirAll(base, 0o755); err != nil {
49
+ t.Fatalf("mkdir temp base: %v", err)
50
+ }
51
+ dir, err := os.MkdirTemp(base, "pattern-line-terminator-")
52
+ if err != nil {
53
+ t.Fatalf("create temp fixture: %v", err)
54
+ }
55
+ t.Cleanup(func() {
56
+ _ = os.RemoveAll(dir)
57
+ })
58
+ src := filepath.Join(dir, "src")
59
+ if err := os.MkdirAll(src, 0o755); err != nil {
60
+ t.Fatalf("mkdir fixture src: %v", err)
61
+ }
62
+ if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(patternLineTerminatorTSConfig), 0o644); err != nil {
63
+ t.Fatalf("write tsconfig: %v", err)
64
+ }
65
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(patternLineTerminatorSource), 0o644); err != nil {
66
+ t.Fatalf("write source: %v", err)
67
+ }
68
+ return dir
69
+ }
70
+
71
+ func patternLineTerminatorTransform(t *testing.T, project string) string {
72
+ t.Helper()
73
+ out, errText, code := ttscTypiaTestCapture(func() int {
74
+ return runTransform([]string{
75
+ "--cwd", project,
76
+ "--tsconfig", "tsconfig.json",
77
+ "--file", "src/main.ts",
78
+ "--output", "js",
79
+ })
80
+ })
81
+ if code != 0 {
82
+ t.Fatalf("line terminator pattern transform failed: code=%d stderr=\n%s", code, errText)
83
+ }
84
+ return out
85
+ }
86
+
87
+ // patternLineTerminatorCheckSyntax runs node against the emit exactly as it would
88
+ // ship. node --check only parses, so the unresolved typia imports in the
89
+ // untouched output do not matter, which keeps this a check of the real artifact.
90
+ func patternLineTerminatorCheckSyntax(t *testing.T, project string, js string) {
91
+ t.Helper()
92
+ node, err := exec.LookPath("node")
93
+ if err != nil {
94
+ t.Skip("node executable not found")
95
+ }
96
+ emitted := filepath.Join(project, "emitted.cjs")
97
+ if err := os.WriteFile(emitted, []byte(js), 0o644); err != nil {
98
+ t.Fatalf("write emitted module: %v", err)
99
+ }
100
+ if output, err := exec.Command(node, "--check", emitted).CombinedOutput(); err != nil {
101
+ t.Fatalf("emitted module is not valid JavaScript: %v\n%s\n--- emit ---\n%s", err, output, js)
102
+ }
103
+ }
104
+
105
+ func patternLineTerminatorRunRuntimeCases(t *testing.T, project string, js string) {
106
+ t.Helper()
107
+ node, err := exec.LookPath("node")
108
+ if err != nil {
109
+ t.Skip("node executable not found")
110
+ }
111
+ runtimeDir := filepath.Join(project, "runtime")
112
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
113
+ t.Fatalf("mkdir runtime dir: %v", err)
114
+ }
115
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
116
+ // json.stringify pulls in _jsonStringifyNumber, which the shared rewrite does
117
+ // not map; stub it locally so the whole module loads. The runner only exercises
118
+ // the `is` predicates, so the stub body is immaterial.
119
+ if err := os.WriteFile(filepath.Join(runtimeDir, "json-stringify-number-stub.cjs"), []byte(patternLineTerminatorNumberStub), 0o644); err != nil {
120
+ t.Fatalf("write json stringify number stub: %v", err)
121
+ }
122
+ runtimeJS := strings.ReplaceAll(js, `require("typia/lib/internal/_jsonStringifyNumber")`, `require("./json-stringify-number-stub.cjs")`)
123
+ runtimeJS = ttscTypiaTestRewriteCommonJS(t, runtimeJS)
124
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
125
+ t.Fatalf("write runtime module: %v", err)
126
+ }
127
+ runner := filepath.Join(runtimeDir, "run.cjs")
128
+ if err := os.WriteFile(runner, []byte(patternLineTerminatorRuntimeRunner), 0o644); err != nil {
129
+ t.Fatalf("write runtime runner: %v", err)
130
+ }
131
+ cmd := exec.Command(node, runner)
132
+ cmd.Dir = runtimeDir
133
+ if output, err := cmd.CombinedOutput(); err != nil {
134
+ t.Fatalf("line terminator pattern runtime cases failed: %v\n%s", err, output)
135
+ }
136
+ }
137
+
138
+ const patternLineTerminatorNumberStub = `module.exports._jsonStringifyNumber = (value) => String(value);
139
+ `
140
+
141
+ const patternLineTerminatorTSConfig = `{
142
+ "compilerOptions": {
143
+ "target": "ES2022",
144
+ "module": "commonjs",
145
+ "moduleResolution": "bundler",
146
+ "ignoreDeprecations": "6.0",
147
+ "types": ["*"],
148
+ "esModuleInterop": true,
149
+ "strict": true,
150
+ "skipLibCheck": true
151
+ },
152
+ "include": ["src"]
153
+ }
154
+ `
155
+
156
+ // The template literal types embed the line terminators as TypeScript escapes
157
+ // (backslash n, backslash r, backslash u2028, backslash u2029), which the
158
+ // compiler folds into real line terminator characters in the literal type --
159
+ // the exact trigger.
160
+ const patternLineTerminatorSource = `import typia from "typia";
161
+
162
+ export const isLF = typia.createIs<` + "`a\\n${string}b`" + `>();
163
+ export const isCR = typia.createIs<` + "`a\\r${string}b`" + `>();
164
+ export const isLS = typia.createIs<` + "`a\\u2028${string}b`" + `>();
165
+ export const isPS = typia.createIs<` + "`a\\u2029${string}b`" + `>();
166
+ export const isControl = typia.createIs<` + "`prefix${string}postfix`" + `>();
167
+
168
+ type LFRecord = Record<` + "`a\\n${string}`" + `, number>;
169
+ export const isRecord = typia.createIs<LFRecord>();
170
+ export const stringifyRecord = typia.json.createStringify<LFRecord>();
171
+ export const cloneRecord = typia.plain.createClone<LFRecord>();
172
+ export const pruneRecord = typia.plain.createPrune<LFRecord>();
173
+ export const camelRecord = typia.notations.createCamel<LFRecord>();
174
+ `
175
+
176
+ // Every value's only line terminator is the one the template's literal part
177
+ // pins, so the trailing `(.*)` (dot excludes newlines) still matches the tail.
178
+ // LF/CR go in as JS escapes and U+2028/U+2029 via String.fromCharCode so this
179
+ // source carries no raw line terminator of its own.
180
+ const patternLineTerminatorRuntimeRunner = `const mod = require("./main.cjs");
181
+
182
+ const LS = String.fromCharCode(0x2028);
183
+ const PS = String.fromCharCode(0x2029);
184
+ const cases = [
185
+ ["isLF", "a\nZZb", "aZZb"],
186
+ ["isCR", "a\rZZb", "aZZb"],
187
+ ["isLS", "a" + LS + "ZZb", "aZZb"],
188
+ ["isPS", "a" + PS + "ZZb", "aZZb"],
189
+ ];
190
+ for (const [name, good, bad] of cases) {
191
+ if (mod[name](good) !== true) {
192
+ throw new Error(name + " must accept a value carrying its line terminator: " + JSON.stringify(good));
193
+ }
194
+ if (mod[name](bad) !== false) {
195
+ throw new Error(name + " must reject a value lacking its line terminator: " + JSON.stringify(bad));
196
+ }
197
+ }
198
+
199
+ if (mod.isControl("prefix_mid_postfix") !== true) {
200
+ throw new Error("line-terminator-free template must still accept a conforming value");
201
+ }
202
+ if (mod.isControl("nope") !== false) {
203
+ throw new Error("line-terminator-free template must still reject a non-conforming value");
204
+ }
205
+
206
+ // A Record index signature only constrains keys its key pattern matches, so the
207
+ // newline in the key regex is what decides which keys get the number check. A
208
+ // matching key with a bad value must fail, while a near-miss key that lacks the
209
+ // newline is not matched (and so is left unchecked) -- together they prove the
210
+ // escaped line terminator is load-bearing in the emitted regex.
211
+ const goodRecord = {};
212
+ goodRecord["a\nkey"] = 1;
213
+ if (mod.isRecord(goodRecord) !== true) {
214
+ throw new Error("Record: a matching key with a number value must pass");
215
+ }
216
+ const matchedBadValue = {};
217
+ matchedBadValue["a\nkey"] = "not a number";
218
+ if (mod.isRecord(matchedBadValue) !== false) {
219
+ throw new Error("Record: a newline-matching key with a non-number value must fail");
220
+ }
221
+ if (mod.isRecord({ "axkey": "not a number" }) !== true) {
222
+ throw new Error("Record: a key lacking the newline must not match the pattern, so it stays unchecked");
223
+ }
224
+ `