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
@@ -7,13 +7,16 @@ import (
7
7
  "fmt"
8
8
  "os"
9
9
  "path/filepath"
10
+ "sort"
10
11
  "strings"
11
12
 
12
13
  shimast "github.com/microsoft/typescript-go/shim/ast"
13
14
  shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
14
15
  shimprinter "github.com/microsoft/typescript-go/shim/printer"
15
16
  "github.com/samchon/ttsc/packages/ttsc/driver"
17
+ typiaadapter "github.com/samchon/typia/packages/typia/native/adapter"
16
18
  nativecontext "github.com/samchon/typia/packages/typia/native/core/context"
19
+ schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
17
20
  nativetransform "github.com/samchon/typia/packages/typia/native/transform"
18
21
  )
19
22
 
@@ -24,6 +27,10 @@ import (
24
27
  // transformers), so injected namespace imports stay as ES imports the caller
25
28
  // can type-strip per file. With no --file it emits a JSON envelope of every
26
29
  // project source keyed by its cwd-relative path; with --file it prints one file.
30
+ //
31
+ // Every host here consults the same transformDiags before choosing its exit code
32
+ // and before publishing anything: runTransformProject encodes them and returns 3,
33
+ // runTransformSingle reports them and withholds the artifact.
27
34
  func runTransform(args []string) int {
28
35
  fs := flag.NewFlagSet("transform", flag.ContinueOnError)
29
36
  fs.SetOutput(stderr)
@@ -33,7 +40,7 @@ func runTransform(args []string) int {
33
40
  out := fs.String("out", "", "write single-file output to PATH instead of stdout")
34
41
  rewriteMode := fs.String("rewrite-mode", "typia", "native rewrite backend id")
35
42
  output := fs.String("output", defaultTransformOutput(), "single-file output kind: js or ts")
36
- _ = fs.String("plugins-json", "", "ordered ttsc plugin payload")
43
+ pluginsJSON := fs.String("plugins-json", "", "ordered ttsc plugin payload")
37
44
  if err := fs.Parse(args); err != nil {
38
45
  return 2
39
46
  }
@@ -45,11 +52,17 @@ func runTransform(args []string) int {
45
52
  fmt.Fprintf(stderr, "ttsc-typia transform: unknown --output value %q\n", *output)
46
53
  return 2
47
54
  }
55
+ // Resolve the options before loading the program: they come from the payload
56
+ // alone, so an unreadable manifest is a usage error to report now rather than
57
+ // after a full transform has already run under the wrong configuration.
58
+ pluginOptions, err := typiaadapter.ReadPluginOptions(*pluginsJSON)
59
+ if err != nil {
60
+ fmt.Fprintf(stderr, "ttsc-typia transform: %v\n", err)
61
+ return 2
62
+ }
48
63
  cwd := *cwdOverride
49
64
  if cwd == "" {
50
- var err error
51
- cwd, err = os.Getwd()
52
- if err != nil {
65
+ if cwd, err = os.Getwd(); err != nil {
53
66
  fmt.Fprintf(stderr, "ttsc-typia transform: cwd: %v\n", err)
54
67
  return 2
55
68
  }
@@ -69,7 +82,6 @@ func runTransform(args []string) int {
69
82
  defer prog.Close()
70
83
 
71
84
  transformDiags := []typiaTransformDiagnostic{}
72
- pluginOptions := readTypiaPluginOptions(cwd, *tsconfigPath)
73
85
  transformOptions := pluginOptions.TransformOptions()
74
86
  extras := nativecontext.ITypiaContext_Extras{
75
87
  AddDiagnostic: func(diag *nativecontext.ITypiaDiagnostic) int {
@@ -102,15 +114,59 @@ func runTransform(args []string) int {
102
114
  fmt.Fprintf(stderr, "ttsc-typia transform: source file is not in program: %s\n", absFile)
103
115
  return 2
104
116
  }
105
- if *output == "js" {
106
- return runTransformSingleJS(prog, typiaTransform, target, absFile, *out)
117
+ return runTransformSingle(cwd, *out, &transformDiags, func() (string, int) {
118
+ if *output == "js" {
119
+ return transformSingleToJavaScript(prog, typiaTransform, target)
120
+ }
121
+ return transformFileToTypeScript(prog, typiaTransform, target), 0
122
+ })
123
+ }
124
+
125
+ // runTransformSingle is the single-file counterpart of runTransformProject's
126
+ // diagnostic decision: produce the artifact into memory, then publish it only
127
+ // when typia's analysis reported nothing. Every single-file output mode routes
128
+ // through this one commit point, so a mode cannot exit 0 over a diagnostic and
129
+ // publish an untransformed `typia.is<T>(input)` call by forgetting its own check
130
+ // (samchon/typia#2117).
131
+ //
132
+ // Diagnostics outrank the producer's own failure code: when typia could not
133
+ // lower a call, that diagnostic is the cause a caller needs, not the "no output
134
+ // produced" symptom it leaves behind.
135
+ func runTransformSingle(
136
+ cwd string,
137
+ outPath string,
138
+ transformDiags *[]typiaTransformDiagnostic,
139
+ produce func() (string, int),
140
+ ) int {
141
+ text, code := produce()
142
+ if len(*transformDiags) > 0 {
143
+ writeTypiaTransformDiagnostics(stderr, *transformDiags, cwd)
144
+ return 3
145
+ }
146
+ if code != 0 {
147
+ return code
107
148
  }
108
- text := transformFileToTypeScript(prog, typiaTransform, target)
109
- return writeSingleOutput(text, *out)
149
+ return writeSingleOutput(text, outPath)
110
150
  }
111
151
 
112
152
  // runTransformProject prints every non-declaration project source as transformed
113
- // TypeScript and encodes the JSON envelope the ttsc host expects.
153
+ // TypeScript and encodes the JSON envelope the ttsc host expects. Alongside the
154
+ // transformed sources it reports two invalidation channels the ttsc consumer
155
+ // registers with the bundler so persistent caches and watch mode invalidate
156
+ // generated validators soundly:
157
+ //
158
+ // - `graph`, the host-owned reference graph of the loaded program (direct
159
+ // resolved edges, ambient globals, tsconfig extends chain) computed by the
160
+ // ttsc driver SDK. It is the plugin-agnostic sound baseline under `tsc
161
+ // --incremental` semantics; the consumer registers, per file F,
162
+ // reach(edges, F) ∪ globals ∪ configs.
163
+ // - `dependencies`, typia's precise per-file list of the source files owning
164
+ // the declarations the typia analysis consulted for each transformed file.
165
+ //
166
+ // The consumer unions the two (reach(edges, F) ∪ globals ∪ configs ∪
167
+ // dependencies[F]), so graph is added alongside dependencies, not a replacement.
168
+ // Every section keys through driver.TransformOutputKey, so the consumer joins
169
+ // them by key.
114
170
  func runTransformProject(
115
171
  prog *driver.Program,
116
172
  cwd string,
@@ -121,16 +177,29 @@ func runTransformProject(
121
177
  Diagnostics: []transformCompilerDiagnostic{},
122
178
  TypeScript: map[string]string{},
123
179
  }
180
+ // Compute the reference graph from the loaded program before the transform
181
+ // loop runs typia's per-file node transformer: the graph must describe the
182
+ // original source's resolved references (the transform's inputs), matching
183
+ // ttsc's own `api-transform` host.
184
+ out.Graph = driver.NewTransformGraph(prog, cwd)
185
+ collector := newTransformDependencyCollector(cwd, func(fileName string) bool {
186
+ sf := prog.SourceFile(fileName)
187
+ return sf != nil && prog.TSProgram.IsLibFile(sf)
188
+ })
189
+ schemametadata.MetadataDependency_listen(prog.Checker, collector.Touch)
190
+ defer schemametadata.MetadataDependency_release(prog.Checker)
124
191
  for _, sf := range prog.SourceFiles() {
125
192
  if sf.IsDeclarationFile {
126
193
  continue
127
194
  }
128
- key := sourceFileKey(cwd, filepath.ToSlash(sf.FileName()))
195
+ key := driver.TransformOutputKey(cwd, sf.FileName())
129
196
  if filepath.IsAbs(key) || key == ".." || strings.HasPrefix(key, "../") {
130
197
  continue
131
198
  }
199
+ collector.Begin(key)
132
200
  out.TypeScript[key] = transformFileToTypeScript(prog, typiaTransform, sf)
133
201
  }
202
+ out.Dependencies = collector.ToJSON()
134
203
  for _, diag := range *transformDiags {
135
204
  out.Diagnostics = append(out.Diagnostics, transformDiagnosticToCompilerDiagnostic(diag))
136
205
  }
@@ -165,21 +234,45 @@ func transformFileToTypeScript(
165
234
  return writer.String()
166
235
  }
167
236
 
168
- // runTransformSingleJS emits a single file's JS through the full node-path emit
169
- // pipeline and writes it to stdout or --out.
170
- func runTransformSingleJS(
237
+ // transformSingleToJavaScript emits a single file's JS through the full node-path
238
+ // emit pipeline and returns the captured text. It only produces; publishing is
239
+ // runTransformSingle's decision, so a diagnostic can withhold the artifact.
240
+ //
241
+ // The emit pass covers every file in the program, so unlike the `ts` mode -- which
242
+ // transforms only the target -- a diagnostic raised by any project source reaches
243
+ // runTransformSingle and withholds this file's artifact. That is deliberate and
244
+ // matches the build host, which fails the whole build on any transform diagnostic:
245
+ // the emit that produced this text is the same one that could not lower the other
246
+ // call, so its success is not independently trustworthy.
247
+ //
248
+ // The emit writes every project output through one callback, so the target's own
249
+ // artifact has to be identified among them. That identity comes from the
250
+ // compiler's output-path resolution rather than from a resemblance between the
251
+ // source and emitted paths, because the emit chooses its write path with that
252
+ // same resolution: `outDir`, `rootDir`, and nested source directories may move
253
+ // the artifact anywhere without the two disagreeing, and two sources sharing a
254
+ // basename in different directories resolve to different artifacts instead of
255
+ // collapsing onto one. Deriving the path instead of matching stems is what fixed
256
+ // samchon/typia#2134, where a whole-path-stem match asked whether `dist/main`
257
+ // equaled `src/main` and so reported "no output produced" for every project
258
+ // with an `outDir`.
259
+ func transformSingleToJavaScript(
171
260
  prog *driver.Program,
172
261
  typiaTransform driver.PluginTransform,
173
262
  target *shimast.SourceFile,
174
- absFile string,
175
- outPath string,
176
- ) int {
263
+ ) (string, int) {
264
+ // The resolution answers with an empty path for a source that has no
265
+ // JavaScript lane of its own -- a JSON module that would be emitted over
266
+ // itself. Nothing the emit writes is then this file's artifact, so guard the
267
+ // comparison rather than let an empty expectation match anything.
268
+ expected := ""
269
+ if paths := shimcompiler.GetOutputPathsFor(target, prog.TSProgram.Options(), prog.TSProgram, false); paths != nil {
270
+ expected = filepath.ToSlash(paths.JsFilePath())
271
+ }
177
272
  var captured string
178
273
  found := false
179
- targetKey := filepath.ToSlash(absFile)
180
274
  writeFile := shimcompiler.WriteFile(func(fileName, text string, _ *shimcompiler.WriteFileData) error {
181
- // The emitted .js maps back to its .ts; match on basename stem.
182
- if sameSourceStem(targetKey, fileName) {
275
+ if expected != "" && filepath.ToSlash(fileName) == expected {
183
276
  captured = text
184
277
  found = true
185
278
  }
@@ -187,20 +280,13 @@ func runTransformSingleJS(
187
280
  })
188
281
  if _, err := prog.EmitWithPluginTransformers([]driver.PluginTransform{typiaTransform}, writeFile); err != nil {
189
282
  fmt.Fprintf(stderr, "ttsc-typia transform: emit: %v\n", err)
190
- return 3
283
+ return "", 3
191
284
  }
192
285
  if !found {
193
- fmt.Fprintf(stderr, "ttsc-typia transform: no output produced for %s\n", absFile)
194
- return 3
286
+ fmt.Fprintf(stderr, "ttsc-typia transform: no output produced for %s\n", target.FileName())
287
+ return "", 3
195
288
  }
196
- return writeSingleOutput(captured, outPath)
197
- }
198
-
199
- // sameSourceStem reports whether an emitted .js path corresponds to a .ts source
200
- // path by comparing their extension-stripped values.
201
- func sameSourceStem(tsPath, jsPath string) bool {
202
- return strings.TrimSuffix(filepath.ToSlash(jsPath), filepath.Ext(jsPath)) ==
203
- strings.TrimSuffix(tsPath, filepath.Ext(tsPath))
289
+ return captured, 0
204
290
  }
205
291
 
206
292
  func writeSingleOutput(text, outPath string) int {
@@ -234,6 +320,117 @@ func defaultTransformOutput() string {
234
320
  type transformProjectOutput struct {
235
321
  Diagnostics []transformCompilerDiagnostic `json:"diagnostics,omitempty"`
236
322
  TypeScript map[string]string `json:"typescript"`
323
+ // Graph is the host-owned reference graph of the loaded program produced by
324
+ // the ttsc driver SDK (driver.NewTransformGraph): direct resolved reference
325
+ // edges, ambient global-scope files, and the tsconfig extends chain, keyed
326
+ // like TypeScript through driver.TransformOutputKey. It is the plugin-agnostic
327
+ // sound invalidation baseline; the consumer unions it with Dependencies.
328
+ // Omitted only when the program is nil (never here — a nil program returns
329
+ // earlier).
330
+ Graph *driver.TransformGraph `json:"graph,omitempty"`
331
+ // Dependencies maps each transformed file (same project-relative keys as
332
+ // TypeScript) to the source files owning the declarations typia's analysis
333
+ // consulted for it. Values are project-relative when the file lives under the
334
+ // project and absolute otherwise; the consumer absolutizes against the
335
+ // project root and drops the file itself. Compiler-owned default library
336
+ // files are excluded (toolchain-versioned, not project inputs);
337
+ // `node_modules` declaration files are included.
338
+ Dependencies map[string][]string `json:"dependencies,omitempty"`
339
+ }
340
+
341
+ // transformDependencyCollector accumulates the consulted-declaration files the
342
+ // metadata dependency listener reports while one project file is transformed,
343
+ // attributing them to that file's envelope key.
344
+ type transformDependencyCollector struct {
345
+ cwd string
346
+ current string
347
+ files map[string]map[string]bool
348
+ // isLibraryFile reports the compiler's own classification of a file as a
349
+ // default library. Classification must come from the program, never from a
350
+ // filename pattern: a project's own ambient declaration file may legitimately
351
+ // be named `lib.custom.d.ts`, and dropping it by basename silently loses
352
+ // cache invalidation for the types it declares (samchon/typia#2108).
353
+ isLibraryFile func(fileName string) bool
354
+ // values memoizes fileName -> envelope value ("" for a dropped file): the
355
+ // listener reports the same declaration files repeatedly across call sites.
356
+ values map[string]string
357
+ }
358
+
359
+ func newTransformDependencyCollector(
360
+ cwd string,
361
+ isLibraryFile func(fileName string) bool,
362
+ ) *transformDependencyCollector {
363
+ return &transformDependencyCollector{
364
+ cwd: cwd,
365
+ isLibraryFile: isLibraryFile,
366
+ files: map[string]map[string]bool{},
367
+ values: map[string]string{},
368
+ }
369
+ }
370
+
371
+ // Begin attributes subsequent touches to the given envelope key.
372
+ func (collector *transformDependencyCollector) Begin(key string) {
373
+ collector.current = key
374
+ }
375
+
376
+ // Touch records one consulted declaration file for the current key. Default
377
+ // library files, virtual URI sources (e.g. tsgo's `bundled:///` libraries),
378
+ // and the transformed file itself are dropped so the envelope carries only
379
+ // actionable project inputs.
380
+ func (collector *transformDependencyCollector) Touch(fileName string) {
381
+ if collector.current == "" {
382
+ return
383
+ }
384
+ value, memoized := collector.values[fileName]
385
+ if memoized == false {
386
+ value = collector.value(fileName)
387
+ collector.values[fileName] = value
388
+ }
389
+ if value == "" || value == collector.current {
390
+ return
391
+ }
392
+ set := collector.files[collector.current]
393
+ if set == nil {
394
+ set = map[string]bool{}
395
+ collector.files[collector.current] = set
396
+ }
397
+ set[value] = true
398
+ }
399
+
400
+ // value renders one reported file as its envelope value, or "" when the file
401
+ // must be dropped: virtual URI sources (e.g. tsgo's `bundled:///` embedded
402
+ // libraries) cannot be watched, and files the compiler classifies as default
403
+ // libraries (on-disk in `noembed` or `libReplacement` configurations) are
404
+ // toolchain inputs, not project inputs.
405
+ func (collector *transformDependencyCollector) value(fileName string) string {
406
+ if strings.Contains(fileName, "://") || collector.isLibraryFile(fileName) {
407
+ return ""
408
+ }
409
+ return driver.TransformOutputKey(collector.cwd, fileName)
410
+ }
411
+
412
+ // ToJSON renders the collected sets as the envelope's `dependencies` map with
413
+ // deterministically sorted values, or nil when nothing was collected.
414
+ func (collector *transformDependencyCollector) ToJSON() map[string][]string {
415
+ if len(collector.files) == 0 {
416
+ return nil
417
+ }
418
+ output := map[string][]string{}
419
+ for key, set := range collector.files {
420
+ if len(set) == 0 {
421
+ continue
422
+ }
423
+ values := make([]string, 0, len(set))
424
+ for value := range set {
425
+ values = append(values, value)
426
+ }
427
+ sort.Strings(values)
428
+ output[key] = values
429
+ }
430
+ if len(output) == 0 {
431
+ return nil
432
+ }
433
+ return output
237
434
  }
238
435
 
239
436
  type transformCompilerDiagnostic struct {
@@ -245,14 +442,6 @@ type transformCompilerDiagnostic struct {
245
442
  MessageText string `json:"messageText"`
246
443
  }
247
444
 
248
- func sourceFileKey(cwd string, file string) string {
249
- rel, err := filepath.Rel(cwd, filepath.FromSlash(file))
250
- if err != nil {
251
- return filepath.ToSlash(file)
252
- }
253
- return filepath.ToSlash(rel)
254
- }
255
-
256
445
  func transformDiagnosticToCompilerDiagnostic(diag typiaTransformDiagnostic) transformCompilerDiagnostic {
257
446
  var ptr *string
258
447
  if diag.File != "" {
@@ -10,17 +10,25 @@ import (
10
10
  "testing"
11
11
  )
12
12
 
13
- // TestTransformDeclarationSourceProducesNoJS verifies JS transform reports empty emission.
13
+ // TestTransformDeclarationSourceProducesNoJavaScript verifies JS transform reports empty emission.
14
14
  //
15
15
  // Declaration files can belong to the program while producing no JavaScript
16
16
  // output. The single-file transform path must detect that empty capture instead
17
17
  // of returning a successful but blank result.
18
18
  //
19
+ // The file name deliberately spells out "javascript". Go reads a trailing `_js`
20
+ // on a source file name as a `GOOS=js` build constraint, so under the earlier
21
+ // name `..._produces_no_js_test.go` this case built only for `GOOS=js` -- where
22
+ // `main.go` (`//go:build !js`) drops out and the test package does not compile
23
+ // at all. It therefore ran on no platform whatsoever, and the tag it carries was
24
+ // never the reason. Keep a `_js`, `_windows`, `_linux`, or `_darwin` ending off
25
+ // a Go file name unless that constraint is meant.
26
+ //
19
27
  // 1. Create a project that includes only a declaration source file.
20
28
  // 2. Run single-file transform with JavaScript output.
21
29
  // 3. Capture the command diagnostics.
22
30
  // 4. Assert the command reports that no output was produced.
23
- func TestTransformDeclarationSourceProducesNoJS(t *testing.T) {
31
+ func TestTransformDeclarationSourceProducesNoJavaScript(t *testing.T) {
24
32
  root := transformCoverageRepoRoot(t)
25
33
  base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
26
34
  if err := os.MkdirAll(base, 0o755); err != nil {
@@ -20,9 +20,19 @@ import (
20
20
  // directly, which makes transformer, adapter, and programmer code visible to
21
21
  // `-coverpkg`.
22
22
  //
23
+ // The `_js` lane asserted the opposite of this until samchon/typia#2134 was
24
+ // fixed: it required every fixture to report "no output produced". These
25
+ // projects all set `rootDir`/`outDir`, and the old identity check compared whole
26
+ // path stems, so it asked whether `dist/main` equaled `src/main` and never
27
+ // found the artifact the emit had just written. Reading those exit 3s as the
28
+ // specification turned this suite into the defect's own guard rail -- it would
29
+ // have failed the repair -- and left the JS emit path it exists to cover
30
+ // unreached, since the run stopped at the identity check.
31
+ //
23
32
  // 1. Create isolated temporary TypeScript projects under the native package.
24
33
  // 2. Transform each project's `src/main.ts` to TypeScript output in memory.
25
- // 3. Exercise JavaScript single-file output error handling for synthetic projects.
34
+ // 3. Transform each project's `src/main.ts` to JavaScript and require emitted
35
+ // CommonJS, which is what reaches the printer and the emit path.
26
36
  // 4. Cover reflect metadata, protobuf maps, and object-union emit paths.
27
37
  // 5. Run build/check/project-transform command paths against the same project.
28
38
  func TestTransformSyntheticEmitCoverage(t *testing.T) {
@@ -63,7 +73,7 @@ func TestTransformSyntheticEmitCoverage(t *testing.T) {
63
73
  for _, tc := range cases {
64
74
  tc := tc
65
75
  t.Run(tc.name+"_js", func(t *testing.T) {
66
- _, errText, code := transformCoverageCapture(func() int {
76
+ out, errText, code := transformCoverageCapture(func() int {
67
77
  return runTransform([]string{
68
78
  "--cwd", projects[tc.name],
69
79
  "--tsconfig", "tsconfig.json",
@@ -71,8 +81,15 @@ func TestTransformSyntheticEmitCoverage(t *testing.T) {
71
81
  "--output", "js",
72
82
  })
73
83
  })
74
- if code != 3 || !strings.Contains(errText, "no output produced") {
75
- t.Fatalf("transform js should report no output for %s: code=%d stderr=\n%s", tc.name, code, errText)
84
+ if code != 0 {
85
+ t.Fatalf("transform js failed for %s: code=%d stderr=\n%s", tc.name, code, errText)
86
+ }
87
+ // These fixtures compile as `commonjs`, so a real emit is module-wrapped
88
+ // JavaScript. The lowering itself is pinned by the dedicated single-file
89
+ // `js` cases; what this lane adds is that every fixture's shape reaches
90
+ // the printer at all.
91
+ if !strings.Contains(out, `"use strict"`) || !strings.Contains(out, "exports.") {
92
+ t.Fatalf("transform js output for %s is not emitted CommonJS:\n%s", tc.name, out)
76
93
  }
77
94
  })
78
95
  }
@@ -3,12 +3,26 @@ package main
3
3
  import (
4
4
  "bytes"
5
5
  "os"
6
+ "os/exec"
6
7
  "path/filepath"
7
8
  "runtime"
8
9
  "strings"
9
10
  "testing"
10
11
  )
11
12
 
13
+ func ttscTypiaTestTypecheck(t *testing.T, project string) {
14
+ t.Helper()
15
+ pnpm, err := exec.LookPath("pnpm")
16
+ if err != nil {
17
+ t.Skip("pnpm executable not found")
18
+ }
19
+ cmd := exec.Command(pnpm, "exec", "ttsc", "--noEmit", "-p", "tsconfig.json")
20
+ cmd.Dir = project
21
+ if output, err := cmd.CombinedOutput(); err != nil {
22
+ t.Fatalf("fixture typecheck failed: %v\n%s", err, output)
23
+ }
24
+ }
25
+
12
26
  func ttscTypiaTestRepoRoot(t *testing.T) string {
13
27
  t.Helper()
14
28
  _, file, _, ok := runtime.Caller(0)
@@ -50,7 +64,10 @@ func ttscTypiaTestWriteCommonRuntimeStubs(t *testing.T, runtimeDir string) {
50
64
  "validate-report-stub.cjs": ttscTypiaTestValidateReportStub,
51
65
  "standard-schema-stub.cjs": ttscTypiaTestStandardSchemaStub,
52
66
  "assert-guard-stub.cjs": ttscTypiaTestAssertGuardStub,
67
+ "functional-error-stub.cjs": ttscTypiaTestFunctionalErrorStub,
53
68
  "access-expression-stub.cjs": ttscTypiaTestAccessExpressionStub,
69
+ "string-length-stub.cjs": ttscTypiaTestStringLengthStub,
70
+ "notation-stub.cjs": ttscTypiaTestNotationStub,
54
71
  }
55
72
  for name, content := range files {
56
73
  if err := os.WriteFile(filepath.Join(runtimeDir, name), []byte(content), 0o644); err != nil {
@@ -65,7 +82,16 @@ func ttscTypiaTestRewriteCommonJS(t *testing.T, js string) string {
65
82
  runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_validateReport")`, `require("./validate-report-stub.cjs")`)
66
83
  runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_createStandardSchema")`, `require("./standard-schema-stub.cjs")`)
67
84
  runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_assertGuard")`, `require("./assert-guard-stub.cjs")`)
85
+ runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_functionalTypeGuardErrorFactory")`, `require("./functional-error-stub.cjs")`)
68
86
  runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_accessExpressionAsString")`, `require("./access-expression-stub.cjs")`)
87
+ runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_stringLength")`, `require("./string-length-stub.cjs")`)
88
+ for _, helper := range []string{"_notationAssign", "_notationCamel", "_notationKebab", "_notationKeyCollision", "_notationPascal", "_notationSnake"} {
89
+ runtimeJS = strings.ReplaceAll(
90
+ runtimeJS,
91
+ `require("typia/lib/internal/`+helper+`")`,
92
+ `require("./notation-stub.cjs")`,
93
+ )
94
+ }
69
95
  for _, needle := range []string{`require("typia")`, `require('typia')`, `from "typia"`, `from 'typia'`, `typia/lib/internal/`} {
70
96
  if strings.Contains(runtimeJS, needle) {
71
97
  t.Fatalf("runtime module still contains unresolved typia import %q", needle)
@@ -75,10 +101,14 @@ func ttscTypiaTestRewriteCommonJS(t *testing.T, js string) string {
75
101
  }
76
102
 
77
103
  const ttscTypiaTestValidateReportStub = `module.exports._validateReport = (array) => {
104
+ const isAncestor = (ancestor, descendant) =>
105
+ descendant === ancestor ||
106
+ descendant.startsWith(ancestor + ".") ||
107
+ descendant.startsWith(ancestor + "[");
78
108
  const reportable = (path) => {
79
109
  if (array.length === 0) return true;
80
110
  const last = array[array.length - 1].path;
81
- return path.length > last.length || last.substring(0, path.length) !== path;
111
+ return !isAncestor(path, last) && !isAncestor(last, path);
82
112
  };
83
113
  return (exceptable, error) => {
84
114
  if (exceptable && reportable(error.path)) {
@@ -108,6 +138,17 @@ const ttscTypiaTestAssertGuardStub = `module.exports._assertGuard = (exceptionab
108
138
  };
109
139
  `
110
140
 
141
+ const ttscTypiaTestFunctionalErrorStub = `module.exports._functionalTypeGuardErrorFactory = (props) =>
142
+ Object.assign(new Error(props.expected), props);
143
+ `
144
+
145
+ const ttscTypiaTestStringLengthStub = `module.exports._stringLength = (value) => {
146
+ let count = 0;
147
+ for (const _ of value) ++count;
148
+ return count;
149
+ };
150
+ `
151
+
111
152
  const ttscTypiaTestAccessExpressionStub = `const reserved = new Set([
112
153
  "break",
113
154
  "case",
@@ -153,3 +194,120 @@ module.exports._accessExpressionAsString = (key) => {
153
194
  : "[" + JSON.stringify(key) + "]";
154
195
  };
155
196
  `
197
+
198
+ // ttscTypiaTestNotationStub stands in for typia/lib/internal/_notation*, which
199
+ // the emitted converter requires for dynamic (index-signature) keys.
200
+ //
201
+ // These tests assert that the statically emitted key and the runtime helper
202
+ // agree, so this stub is that assertion's oracle and has to stay a faithful
203
+ // transcription of packages/typia/src/internal/_notation{Camel,Pascal,Snake,
204
+ // Kebab}.ts and private/__notationRename.ts — an approximation turns "emit ==
205
+ // runtime" into "emit == whatever this file happens to say". Keep it a direct
206
+ // transcription: same routing on underscore presence (not on segment count),
207
+ // the same CamelizeSnakeString/PascalizeSnakeString recursions, and the same
208
+ // per-segment case-boundary walk in snake. It deliberately uses string
209
+ // concatenation rather than template literals because it is embedded in a Go
210
+ // raw string literal, which is backtick-delimited.
211
+ const ttscTypiaTestNotationStub = `const __notationRename = (props) => (str) => {
212
+ let prefix = "";
213
+ while (str.startsWith("_")) {
214
+ prefix += "_";
215
+ str = str.substring(1);
216
+ }
217
+ if (str.length === 0) return prefix;
218
+ return prefix + (str.includes("_") ? props.snake(str) : props.plain(str));
219
+ };
220
+
221
+ const _notationCamelSnake = (str) => {
222
+ while (str.startsWith("_")) str = str.substring(1);
223
+ if (str.length === 0) return "";
224
+ const index = str.indexOf("_");
225
+ if (index < 0) return str.toLowerCase();
226
+ const middle = str[index + 1];
227
+ if (middle === undefined) return str.toLowerCase();
228
+ return middle === "_"
229
+ ? _notationCamelSnake(str.substring(0, index) + "_" + str.substring(index + 2))
230
+ : str.substring(0, index).toLowerCase() +
231
+ middle.toUpperCase() +
232
+ _notationCamelSnake(str.substring(index + 2));
233
+ };
234
+
235
+ const _notationPascalSnake = (str) => {
236
+ while (str.startsWith("_")) str = str.substring(1);
237
+ if (str.length === 0) return "";
238
+ const index = str.indexOf("_");
239
+ return index < 0
240
+ ? str[0].toUpperCase() + str.substring(1).toLowerCase()
241
+ : str[0].toUpperCase() +
242
+ str.substring(1, index).toLowerCase() +
243
+ _notationPascalSnake(str.substring(index + 1));
244
+ };
245
+
246
+ const _notationSnakeWord = (str) => {
247
+ const indexes = [];
248
+ for (let i = 0; i < str.length; i++) {
249
+ const code = str.charCodeAt(i);
250
+ if (65 <= code && code <= 90) indexes.push(i);
251
+ }
252
+ for (let i = indexes.length - 1; i > 0; --i)
253
+ if (indexes[i] - indexes[i - 1] === 1) indexes.splice(i, 1);
254
+ if (indexes.length !== 0 && indexes[0] === 0) indexes.splice(0, 1);
255
+ if (indexes.length === 0) return str.toLowerCase();
256
+ let ret = "";
257
+ for (let i = 0; i < indexes.length; i++) {
258
+ ret += str.substring(i === 0 ? 0 : indexes[i - 1], indexes[i]).toLowerCase();
259
+ ret += "_";
260
+ }
261
+ ret += str.substring(indexes[indexes.length - 1]).toLowerCase();
262
+ return ret;
263
+ };
264
+
265
+ module.exports._notationCamel = __notationRename({
266
+ plain: (str) =>
267
+ str === str.toUpperCase()
268
+ ? str.toLowerCase()
269
+ : str[0].toLowerCase() + str.substring(1),
270
+ snake: _notationCamelSnake,
271
+ });
272
+ module.exports._notationPascal = __notationRename({
273
+ plain: (str) => str[0].toUpperCase() + str.substring(1),
274
+ snake: _notationPascalSnake,
275
+ });
276
+ module.exports._notationSnake = (str) => {
277
+ if (str.length === 0) return str;
278
+ let prefix = "";
279
+ for (let i = 0; i < str.length; i++) {
280
+ if (str[i] === "_") prefix += "_";
281
+ else break;
282
+ }
283
+ if (prefix.length !== 0) str = str.substring(prefix.length);
284
+ return prefix + str.split("_").map(_notationSnakeWord).join("_");
285
+ };
286
+ module.exports._notationKebab = (str) => {
287
+ let snaked = module.exports._notationSnake(str);
288
+ let prefix = "";
289
+ while (snaked.startsWith("_")) {
290
+ prefix += "_";
291
+ snaked = snaked.substring(1);
292
+ }
293
+ return prefix + snaked.replaceAll("_", "-");
294
+ };
295
+ module.exports._notationAssign = (output, sources, source, value, rename) => {
296
+ const destination = rename(source);
297
+ if (Object.hasOwn(output, destination))
298
+ module.exports._notationKeyCollision(sources[destination], source, destination);
299
+ Object.defineProperty(output, destination, {
300
+ configurable: true,
301
+ enumerable: true,
302
+ value,
303
+ writable: true,
304
+ });
305
+ sources[destination] = source;
306
+ };
307
+ module.exports._notationKeyCollision = (first, second, destination) => {
308
+ throw new Error(
309
+ "typia.notations cannot rename both " + JSON.stringify(first) +
310
+ " and " + JSON.stringify(second) + " to " + JSON.stringify(destination) + ".",
311
+ );
312
+ };
313
+ `