typia 13.1.1 → 13.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (581) hide show
  1. package/README.md +3 -0
  2. package/lib/_virtual/_rolldown/runtime.mjs +1 -5
  3. package/lib/executable/FileSystemIdentity.d.ts +44 -0
  4. package/lib/executable/FileSystemIdentity.js +213 -0
  5. package/lib/executable/FileSystemIdentity.js.map +1 -0
  6. package/lib/executable/FileSystemIdentity.mjs +133 -0
  7. package/lib/executable/FileSystemIdentity.mjs.map +1 -0
  8. package/lib/executable/TypiaGenerateWizard.js +272 -106
  9. package/lib/executable/TypiaGenerateWizard.js.map +1 -1
  10. package/lib/executable/TypiaGenerateWizard.mjs +239 -95
  11. package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
  12. package/lib/functional.d.ts +15 -12
  13. package/lib/functional.js.map +1 -1
  14. package/lib/functional.mjs.map +1 -1
  15. package/lib/internal/_ProtobufReader.d.ts +32 -0
  16. package/lib/internal/_ProtobufReader.js +148 -48
  17. package/lib/internal/_ProtobufReader.js.map +1 -1
  18. package/lib/internal/_ProtobufReader.mjs +137 -41
  19. package/lib/internal/_ProtobufReader.mjs.map +1 -1
  20. package/lib/internal/_createStandardSchema.js +18 -1
  21. package/lib/internal/_createStandardSchema.js.map +1 -1
  22. package/lib/internal/_createStandardSchema.mjs +12 -1
  23. package/lib/internal/_createStandardSchema.mjs.map +1 -1
  24. package/lib/internal/_decimal.d.ts +14 -0
  25. package/lib/internal/_decimal.js +61 -0
  26. package/lib/internal/_decimal.js.map +1 -0
  27. package/lib/internal/_decimal.mjs +49 -0
  28. package/lib/internal/_decimal.mjs.map +1 -0
  29. package/lib/internal/_httpQueryParseURLSearchParams.js +23 -2
  30. package/lib/internal/_httpQueryParseURLSearchParams.js.map +1 -1
  31. package/lib/internal/_httpQueryParseURLSearchParams.mjs +20 -2
  32. package/lib/internal/_httpQueryParseURLSearchParams.mjs.map +1 -1
  33. package/lib/internal/_isFormatByte.js +2 -5
  34. package/lib/internal/_isFormatByte.js.map +1 -1
  35. package/lib/internal/_isFormatByte.mjs +2 -5
  36. package/lib/internal/_isFormatByte.mjs.map +1 -1
  37. package/lib/internal/_isFormatDate.js +15 -2
  38. package/lib/internal/_isFormatDate.js.map +1 -1
  39. package/lib/internal/_isFormatDate.mjs +22 -2
  40. package/lib/internal/_isFormatDate.mjs.map +1 -1
  41. package/lib/internal/_isFormatDateTime.js +21 -2
  42. package/lib/internal/_isFormatDateTime.js.map +1 -1
  43. package/lib/internal/_isFormatDateTime.mjs +13 -2
  44. package/lib/internal/_isFormatDateTime.mjs.map +1 -1
  45. package/lib/internal/_isFormatIri.js +3 -2
  46. package/lib/internal/_isFormatIri.js.map +1 -1
  47. package/lib/internal/_isFormatIri.mjs +3 -2
  48. package/lib/internal/_isFormatIri.mjs.map +1 -1
  49. package/lib/internal/_isFormatIriReference.js +10 -2
  50. package/lib/internal/_isFormatIriReference.js.map +1 -1
  51. package/lib/internal/_isFormatIriReference.mjs +9 -2
  52. package/lib/internal/_isFormatIriReference.mjs.map +1 -1
  53. package/lib/internal/_isFormatUriReference.js +1 -1
  54. package/lib/internal/_isFormatUriReference.js.map +1 -1
  55. package/lib/internal/_isFormatUriReference.mjs +1 -1
  56. package/lib/internal/_isFormatUriReference.mjs.map +1 -1
  57. package/lib/internal/_isMultipleOf.d.ts +1 -0
  58. package/lib/internal/_isMultipleOf.js +13 -0
  59. package/lib/internal/_isMultipleOf.js.map +1 -0
  60. package/lib/internal/_isMultipleOf.mjs +12 -0
  61. package/lib/internal/_isMultipleOf.mjs.map +1 -0
  62. package/lib/internal/_isTypeFloat.js +1 -1
  63. package/lib/internal/_isTypeFloat.js.map +1 -1
  64. package/lib/internal/_isTypeFloat.mjs +1 -1
  65. package/lib/internal/_isTypeFloat.mjs.map +1 -1
  66. package/lib/internal/_isTypeInt64.js +1 -0
  67. package/lib/internal/_isTypeInt64.js.map +1 -1
  68. package/lib/internal/_isTypeInt64.mjs.map +1 -1
  69. package/lib/internal/_isTypeInt64Bigint.d.ts +1 -0
  70. package/lib/internal/_isTypeInt64Bigint.js +15 -0
  71. package/lib/internal/_isTypeInt64Bigint.js.map +1 -0
  72. package/lib/internal/_isTypeInt64Bigint.mjs +8 -0
  73. package/lib/internal/_isTypeInt64Bigint.mjs.map +1 -0
  74. package/lib/internal/_isTypeUint64.js +1 -0
  75. package/lib/internal/_isTypeUint64.js.map +1 -1
  76. package/lib/internal/_isTypeUint64.mjs.map +1 -1
  77. package/lib/internal/_isTypeUint64Bigint.d.ts +1 -0
  78. package/lib/internal/_isTypeUint64Bigint.js +10 -0
  79. package/lib/internal/_isTypeUint64Bigint.js.map +1 -0
  80. package/lib/internal/_isTypeUint64Bigint.mjs +8 -0
  81. package/lib/internal/_isTypeUint64Bigint.mjs.map +1 -0
  82. package/lib/internal/_isUniqueItems.js +96 -109
  83. package/lib/internal/_isUniqueItems.js.map +1 -1
  84. package/lib/internal/_isUniqueItems.mjs +62 -50
  85. package/lib/internal/_isUniqueItems.mjs.map +1 -1
  86. package/lib/internal/_jsonStringifyArray.d.ts +1 -0
  87. package/lib/internal/_jsonStringifyArray.js +48 -0
  88. package/lib/internal/_jsonStringifyArray.js.map +1 -0
  89. package/lib/internal/_jsonStringifyArray.mjs +40 -0
  90. package/lib/internal/_jsonStringifyArray.mjs.map +1 -0
  91. package/lib/internal/_jsonStringifyElement.d.ts +1 -0
  92. package/lib/internal/_jsonStringifyElement.js +23 -0
  93. package/lib/internal/_jsonStringifyElement.js.map +1 -0
  94. package/lib/internal/_jsonStringifyElement.mjs +23 -0
  95. package/lib/internal/_jsonStringifyElement.mjs.map +1 -0
  96. package/lib/internal/_jsonStringifyProperty.d.ts +1 -0
  97. package/lib/internal/_jsonStringifyProperty.js +31 -0
  98. package/lib/internal/_jsonStringifyProperty.js.map +1 -0
  99. package/lib/internal/_jsonStringifyProperty.mjs +31 -0
  100. package/lib/internal/_jsonStringifyProperty.mjs.map +1 -0
  101. package/lib/internal/_llmApplicationFinalize.js +1 -1
  102. package/lib/internal/_llmApplicationFinalize.js.map +1 -1
  103. package/lib/internal/_llmApplicationFinalize.mjs +1 -1
  104. package/lib/internal/_llmApplicationFinalize.mjs.map +1 -1
  105. package/lib/internal/_notationAny.js +8 -1
  106. package/lib/internal/_notationAny.js.map +1 -1
  107. package/lib/internal/_notationAny.mjs +7 -1
  108. package/lib/internal/_notationAny.mjs.map +1 -1
  109. package/lib/internal/_notationAssign.d.ts +1 -0
  110. package/lib/internal/_notationAssign.js +18 -0
  111. package/lib/internal/_notationAssign.js.map +1 -0
  112. package/lib/internal/_notationAssign.mjs +17 -0
  113. package/lib/internal/_notationAssign.mjs.map +1 -0
  114. package/lib/internal/_notationCamel.js +30 -9
  115. package/lib/internal/_notationCamel.js.map +1 -1
  116. package/lib/internal/_notationCamel.mjs +13 -5
  117. package/lib/internal/_notationCamel.mjs.map +1 -1
  118. package/lib/internal/_notationKebab.d.ts +1 -0
  119. package/lib/internal/_notationKebab.js +15 -0
  120. package/lib/internal/_notationKebab.js.map +1 -0
  121. package/lib/internal/_notationKebab.mjs +15 -0
  122. package/lib/internal/_notationKebab.mjs.map +1 -0
  123. package/lib/internal/_notationKeyCollision.d.ts +1 -0
  124. package/lib/internal/_notationKeyCollision.js +8 -0
  125. package/lib/internal/_notationKeyCollision.js.map +1 -0
  126. package/lib/internal/_notationKeyCollision.mjs +8 -0
  127. package/lib/internal/_notationKeyCollision.mjs.map +1 -0
  128. package/lib/internal/_notationPascal.js +20 -5
  129. package/lib/internal/_notationPascal.js.map +1 -1
  130. package/lib/internal/_notationPascal.mjs +10 -5
  131. package/lib/internal/_notationPascal.mjs.map +1 -1
  132. package/lib/internal/_notationSnake.js +25 -22
  133. package/lib/internal/_notationSnake.js.map +1 -1
  134. package/lib/internal/_notationSnake.mjs +11 -11
  135. package/lib/internal/_notationSnake.mjs.map +1 -1
  136. package/lib/internal/_plainCloneAny.js +174 -38
  137. package/lib/internal/_plainCloneAny.js.map +1 -1
  138. package/lib/internal/_plainCloneAny.mjs +126 -22
  139. package/lib/internal/_plainCloneAny.mjs.map +1 -1
  140. package/lib/internal/_randomArray.d.ts +1 -1
  141. package/lib/internal/_randomArray.js +11 -4
  142. package/lib/internal/_randomArray.js.map +1 -1
  143. package/lib/internal/_randomArray.mjs +9 -3
  144. package/lib/internal/_randomArray.mjs.map +1 -1
  145. package/lib/internal/_randomFormatByte.d.ts +2 -1
  146. package/lib/internal/_randomFormatByte.js +25 -1
  147. package/lib/internal/_randomFormatByte.js.map +1 -1
  148. package/lib/internal/_randomFormatByte.mjs +20 -1
  149. package/lib/internal/_randomFormatByte.mjs.map +1 -1
  150. package/lib/internal/_randomFormatDate.d.ts +3 -4
  151. package/lib/internal/_randomFormatDate.js +3 -10
  152. package/lib/internal/_randomFormatDate.js.map +1 -1
  153. package/lib/internal/_randomFormatDate.mjs +3 -6
  154. package/lib/internal/_randomFormatDate.mjs.map +1 -1
  155. package/lib/internal/_randomFormatDatetime.d.ts +3 -4
  156. package/lib/internal/_randomFormatDatetime.js +26 -8
  157. package/lib/internal/_randomFormatDatetime.js.map +1 -1
  158. package/lib/internal/_randomFormatDatetime.mjs +17 -6
  159. package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
  160. package/lib/internal/_randomFormatDuration.d.ts +2 -1
  161. package/lib/internal/_randomFormatDuration.js +23 -14
  162. package/lib/internal/_randomFormatDuration.js.map +1 -1
  163. package/lib/internal/_randomFormatDuration.mjs +22 -13
  164. package/lib/internal/_randomFormatDuration.mjs.map +1 -1
  165. package/lib/internal/_randomFormatEmail.d.ts +2 -1
  166. package/lib/internal/_randomFormatEmail.js +8 -1
  167. package/lib/internal/_randomFormatEmail.js.map +1 -1
  168. package/lib/internal/_randomFormatEmail.mjs +5 -1
  169. package/lib/internal/_randomFormatEmail.mjs.map +1 -1
  170. package/lib/internal/_randomFormatHostname.d.ts +8 -1
  171. package/lib/internal/_randomFormatHostname.js +45 -2
  172. package/lib/internal/_randomFormatHostname.js.map +1 -1
  173. package/lib/internal/_randomFormatHostname.mjs +38 -2
  174. package/lib/internal/_randomFormatHostname.mjs.map +1 -1
  175. package/lib/internal/_randomFormatIdnEmail.d.ts +2 -1
  176. package/lib/internal/_randomFormatIdnEmail.js +16 -2
  177. package/lib/internal/_randomFormatIdnEmail.js.map +1 -1
  178. package/lib/internal/_randomFormatIdnEmail.mjs +11 -2
  179. package/lib/internal/_randomFormatIdnEmail.mjs.map +1 -1
  180. package/lib/internal/_randomFormatIdnHostname.d.ts +2 -1
  181. package/lib/internal/_randomFormatIdnHostname.js +26 -1
  182. package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
  183. package/lib/internal/_randomFormatIdnHostname.mjs +25 -2
  184. package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
  185. package/lib/internal/_randomFormatIpv4.d.ts +2 -1
  186. package/lib/internal/_randomFormatIpv4.js +32 -1
  187. package/lib/internal/_randomFormatIpv4.js.map +1 -1
  188. package/lib/internal/_randomFormatIpv4.mjs +23 -1
  189. package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
  190. package/lib/internal/_randomFormatIpv6.d.ts +2 -1
  191. package/lib/internal/_randomFormatIpv6.js +58 -1
  192. package/lib/internal/_randomFormatIpv6.js.map +1 -1
  193. package/lib/internal/_randomFormatIpv6.mjs +45 -1
  194. package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
  195. package/lib/internal/_randomFormatIri.d.ts +2 -1
  196. package/lib/internal/_randomFormatIri.js +1 -1
  197. package/lib/internal/_randomFormatIri.js.map +1 -1
  198. package/lib/internal/_randomFormatIri.mjs +1 -1
  199. package/lib/internal/_randomFormatIri.mjs.map +1 -1
  200. package/lib/internal/_randomFormatIriReference.d.ts +2 -1
  201. package/lib/internal/_randomFormatIriReference.js +1 -1
  202. package/lib/internal/_randomFormatIriReference.js.map +1 -1
  203. package/lib/internal/_randomFormatIriReference.mjs +1 -1
  204. package/lib/internal/_randomFormatIriReference.mjs.map +1 -1
  205. package/lib/internal/_randomFormatJsonPointer.d.ts +2 -1
  206. package/lib/internal/_randomFormatJsonPointer.js +20 -1
  207. package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
  208. package/lib/internal/_randomFormatJsonPointer.mjs +15 -1
  209. package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
  210. package/lib/internal/_randomFormatPassword.d.ts +2 -1
  211. package/lib/internal/_randomFormatPassword.js +7 -5
  212. package/lib/internal/_randomFormatPassword.js.map +1 -1
  213. package/lib/internal/_randomFormatPassword.mjs +5 -1
  214. package/lib/internal/_randomFormatPassword.mjs.map +1 -1
  215. package/lib/internal/_randomFormatRegex.d.ts +2 -1
  216. package/lib/internal/_randomFormatRegex.js +15 -1
  217. package/lib/internal/_randomFormatRegex.js.map +1 -1
  218. package/lib/internal/_randomFormatRegex.mjs +14 -1
  219. package/lib/internal/_randomFormatRegex.mjs.map +1 -1
  220. package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
  221. package/lib/internal/_randomFormatRelativeJsonPointer.js +20 -5
  222. package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
  223. package/lib/internal/_randomFormatRelativeJsonPointer.mjs +21 -5
  224. package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
  225. package/lib/internal/_randomFormatTime.d.ts +2 -1
  226. package/lib/internal/_randomFormatTime.js +34 -7
  227. package/lib/internal/_randomFormatTime.js.map +1 -1
  228. package/lib/internal/_randomFormatTime.mjs +37 -4
  229. package/lib/internal/_randomFormatTime.mjs.map +1 -1
  230. package/lib/internal/_randomFormatUri.d.ts +2 -1
  231. package/lib/internal/_randomFormatUri.js +1 -1
  232. package/lib/internal/_randomFormatUri.js.map +1 -1
  233. package/lib/internal/_randomFormatUri.mjs +1 -1
  234. package/lib/internal/_randomFormatUri.mjs.map +1 -1
  235. package/lib/internal/_randomFormatUriReference.d.ts +2 -1
  236. package/lib/internal/_randomFormatUriReference.js +1 -1
  237. package/lib/internal/_randomFormatUriReference.js.map +1 -1
  238. package/lib/internal/_randomFormatUriReference.mjs +1 -1
  239. package/lib/internal/_randomFormatUriReference.mjs.map +1 -1
  240. package/lib/internal/_randomFormatUriTemplate.d.ts +2 -1
  241. package/lib/internal/_randomFormatUriTemplate.js +1 -1
  242. package/lib/internal/_randomFormatUriTemplate.js.map +1 -1
  243. package/lib/internal/_randomFormatUriTemplate.mjs +1 -1
  244. package/lib/internal/_randomFormatUriTemplate.mjs.map +1 -1
  245. package/lib/internal/_randomFormatUrl.d.ts +2 -1
  246. package/lib/internal/_randomFormatUrl.js +21 -1
  247. package/lib/internal/_randomFormatUrl.js.map +1 -1
  248. package/lib/internal/_randomFormatUrl.mjs +18 -1
  249. package/lib/internal/_randomFormatUrl.mjs.map +1 -1
  250. package/lib/internal/_randomFormatUuid.d.ts +2 -1
  251. package/lib/internal/_randomFormatUuid.js +3 -2
  252. package/lib/internal/_randomFormatUuid.js.map +1 -1
  253. package/lib/internal/_randomFormatUuid.mjs +3 -2
  254. package/lib/internal/_randomFormatUuid.mjs.map +1 -1
  255. package/lib/internal/_randomInteger.js +59 -28
  256. package/lib/internal/_randomInteger.js.map +1 -1
  257. package/lib/internal/_randomInteger.mjs +56 -16
  258. package/lib/internal/_randomInteger.mjs.map +1 -1
  259. package/lib/internal/_randomMultiple.d.ts +8 -0
  260. package/lib/internal/_randomMultiple.js +168 -0
  261. package/lib/internal/_randomMultiple.js.map +1 -0
  262. package/lib/internal/_randomMultiple.mjs +158 -0
  263. package/lib/internal/_randomMultiple.mjs.map +1 -0
  264. package/lib/internal/_randomNumber.js +42 -42
  265. package/lib/internal/_randomNumber.js.map +1 -1
  266. package/lib/internal/_randomNumber.mjs +41 -27
  267. package/lib/internal/_randomNumber.mjs.map +1 -1
  268. package/lib/internal/_randomPattern.d.ts +2 -1
  269. package/lib/internal/_randomPattern.js +19 -4
  270. package/lib/internal/_randomPattern.js.map +1 -1
  271. package/lib/internal/_randomPattern.mjs +10 -4
  272. package/lib/internal/_randomPattern.mjs.map +1 -1
  273. package/lib/internal/_randomStringLength.d.ts +64 -0
  274. package/lib/internal/_randomStringLength.js +84 -0
  275. package/lib/internal/_randomStringLength.js.map +1 -0
  276. package/lib/internal/_randomStringLength.mjs +79 -0
  277. package/lib/internal/_randomStringLength.mjs.map +1 -0
  278. package/lib/internal/_stringLength.d.ts +1 -0
  279. package/lib/internal/_stringLength.js +11 -0
  280. package/lib/internal/_stringLength.js.map +1 -0
  281. package/lib/internal/_stringLength.mjs +10 -0
  282. package/lib/internal/_stringLength.mjs.map +1 -0
  283. package/lib/internal/_validateReport.js +4 -1
  284. package/lib/internal/_validateReport.js.map +1 -1
  285. package/lib/internal/_validateReport.mjs +2 -1
  286. package/lib/internal/_validateReport.mjs.map +1 -1
  287. package/lib/internal/private/__notationRename.d.ts +14 -0
  288. package/lib/internal/private/__notationRename.js +25 -0
  289. package/lib/internal/private/__notationRename.js.map +1 -0
  290. package/lib/internal/private/__notationRename.mjs +24 -0
  291. package/lib/internal/private/__notationRename.mjs.map +1 -0
  292. package/lib/internal/private/__randomComposition.d.ts +23 -0
  293. package/lib/internal/private/__randomComposition.js +48 -0
  294. package/lib/internal/private/__randomComposition.js.map +1 -0
  295. package/lib/internal/private/__randomComposition.mjs +54 -0
  296. package/lib/internal/private/__randomComposition.mjs.map +1 -0
  297. package/lib/internal/private/__randomEpoch.d.ts +19 -0
  298. package/lib/internal/private/__randomEpoch.js +31 -0
  299. package/lib/internal/private/__randomEpoch.js.map +1 -0
  300. package/lib/internal/private/__randomEpoch.mjs +28 -0
  301. package/lib/internal/private/__randomEpoch.mjs.map +1 -0
  302. package/lib/json.d.ts +2 -2
  303. package/lib/json.mjs.map +1 -1
  304. package/lib/module.d.ts +2 -2
  305. package/lib/module.js.map +1 -1
  306. package/lib/module.mjs.map +1 -1
  307. package/lib/notations.d.ts +20 -4
  308. package/lib/notations.js.map +1 -1
  309. package/lib/notations.mjs.map +1 -1
  310. package/native/adapter/plugin_options.go +117 -0
  311. package/native/adapter/plugin_options_payload_matrix_test.go +181 -0
  312. package/native/cmd/ttsc-typia/any_array_type_tags_transform_test.go +63 -9
  313. package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +152 -0
  314. package/native/cmd/ttsc-typia/build.go +84 -64
  315. package/native/cmd/ttsc-typia/build_no_emit_preserves_analysis_options_test.go +67 -0
  316. package/native/cmd/ttsc-typia/build_no_emit_transform_diagnostics_test.go +138 -0
  317. package/native/cmd/ttsc-typia/build_plugin_options_come_from_payload_test.go +48 -0
  318. package/native/cmd/ttsc-typia/build_transactional_emit_success_test.go +81 -0
  319. package/native/cmd/ttsc-typia/build_transform_failure_atomicity_test.go +138 -0
  320. package/native/cmd/ttsc-typia/callable_interface_function_semantics_transform_test.go +331 -0
  321. package/native/cmd/ttsc-typia/callable_type_literal_boundaries_transform_test.go +1184 -0
  322. package/native/cmd/ttsc-typia/command_routes_and_diagnostics_coverage_test.go +3 -1
  323. package/native/cmd/ttsc-typia/compare_functional_union_membership_transform_test.go +434 -0
  324. package/native/cmd/ttsc-typia/compare_less_nan_transform_test.go +98 -0
  325. package/native/cmd/ttsc-typia/compare_native_object_overmatch_transform_test.go +161 -0
  326. package/native/cmd/ttsc-typia/compare_nondiscriminable_union_transform_test.go +343 -0
  327. package/native/cmd/ttsc-typia/compare_template_literal_union_transform_test.go +241 -0
  328. package/native/cmd/ttsc-typia/compare_union_discrimination_transform_test.go +289 -0
  329. package/native/cmd/ttsc-typia/default_library_spoof_native_identity_transform_test.go +216 -0
  330. package/native/cmd/ttsc-typia/escaped_property_key_path_transform_test.go +193 -0
  331. package/native/cmd/ttsc-typia/finite_option_number_leaf_transform_test.go +240 -0
  332. package/native/cmd/ttsc-typia/functional_promised_type_transform_test.go +220 -0
  333. package/native/cmd/ttsc-typia/functional_receiver_transform_test.go +232 -0
  334. package/native/cmd/ttsc-typia/is_object_function_member_transform_test.go +205 -0
  335. package/native/cmd/ttsc-typia/json_application_alias_function_validation_transform_test.go +151 -0
  336. package/native/cmd/ttsc-typia/json_is_stringify_finite_number_transform_test.go +198 -0
  337. package/native/cmd/ttsc-typia/json_schema_dynamic_key_determinism_transform_test.go +246 -0
  338. package/native/cmd/ttsc-typia/json_stringify_contextual_undefined_transform_test.go +556 -0
  339. package/native/cmd/ttsc-typia/json_stringify_special_key_transform_test.go +238 -0
  340. package/native/cmd/ttsc-typia/lib_replacement_native_identity_transform_test.go +277 -0
  341. package/native/cmd/ttsc-typia/main_wasm.go +21 -2
  342. package/native/cmd/ttsc-typia/native_collection_identity_is_transform_test.go +234 -0
  343. package/native/cmd/ttsc-typia/native_generic_name_guard_is_transform_test.go +194 -0
  344. package/native/cmd/ttsc-typia/native_name_collision_is_transform_test.go +204 -0
  345. package/native/cmd/ttsc-typia/native_named_intersection_union_transform_test.go +390 -0
  346. package/native/cmd/ttsc-typia/node_buffer_native_exports_is_transform_test.go +526 -0
  347. package/native/cmd/ttsc-typia/non_trailing_rest_tuple_transform_test.go +23 -11
  348. package/native/cmd/ttsc-typia/notation_dynamic_keys_transform_test.go +286 -0
  349. package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +1 -1
  350. package/native/cmd/ttsc-typia/notation_literal_collision_transform_test.go +164 -0
  351. package/native/cmd/ttsc-typia/notation_pascal_case_transform_test.go +230 -0
  352. package/native/cmd/ttsc-typia/notation_unicode_key_transform_test.go +309 -0
  353. package/native/cmd/ttsc-typia/package_declaration_native_identity_is_transform_test.go +293 -0
  354. package/native/cmd/ttsc-typia/pattern_line_terminator_escape_transform_test.go +224 -0
  355. package/native/cmd/ttsc-typia/plain_prune_union_object_overmatch_transform_test.go +219 -0
  356. package/native/cmd/ttsc-typia/plugin_options_payload_helpers_test.go +181 -0
  357. package/native/cmd/ttsc-typia/private_field_filter_is_transform_test.go +278 -0
  358. package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +73 -27
  359. package/native/cmd/ttsc-typia/project_dependencies_barrel_reexport_transform_test.go +120 -0
  360. package/native/cmd/ttsc-typia/project_dependencies_collapsed_alias_transform_test.go +134 -0
  361. package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +135 -0
  362. package/native/cmd/ttsc-typia/project_dependencies_default_barrel_transform_test.go +114 -0
  363. package/native/cmd/ttsc-typia/project_dependencies_empty_heritage_transform_test.go +100 -0
  364. package/native/cmd/ttsc-typia/project_dependencies_envelope_transform_test.go +148 -0
  365. package/native/cmd/ttsc-typia/project_dependencies_index_signature_alias_transform_test.go +139 -0
  366. package/native/cmd/ttsc-typia/project_dependencies_local_reexport_transform_test.go +122 -0
  367. package/native/cmd/ttsc-typia/project_dependencies_signature_alias_transform_test.go +125 -0
  368. package/native/cmd/ttsc-typia/project_dependencies_star_barrel_transform_test.go +112 -0
  369. package/native/cmd/ttsc-typia/project_reference_graph_envelope_transform_test.go +190 -0
  370. package/native/cmd/ttsc-typia/protobuf_diagnostic_code_transform_test.go +167 -0
  371. package/native/cmd/ttsc-typia/protobuf_is_encode_finite_number_transform_test.go +98 -0
  372. package/native/cmd/ttsc-typia/protobuf_sequence_field_numbers_transform_test.go +52 -22
  373. package/native/cmd/ttsc-typia/symbol_index_domain_transform_test.go +316 -0
  374. package/native/cmd/ttsc-typia/symbol_key_member_filter_transform_test.go +279 -0
  375. package/native/cmd/ttsc-typia/template_interpolation_type_tags_transform_test.go +86 -23
  376. package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
  377. package/native/cmd/ttsc-typia/transform.go +251 -39
  378. package/native/cmd/ttsc-typia/{transform_declaration_source_produces_no_js_test.go → transform_declaration_source_produces_no_javascript_test.go} +10 -2
  379. package/native/cmd/ttsc-typia/transform_fixtures_emit_coverage_test.go +21 -4
  380. package/native/cmd/ttsc-typia/transform_helpers_test.go +236 -3
  381. package/native/cmd/ttsc-typia/transform_plugin_options_come_from_payload_test.go +43 -0
  382. package/native/cmd/ttsc-typia/transform_single_file_failure_atomicity_test.go +114 -0
  383. package/native/cmd/ttsc-typia/transform_single_file_failure_writes_no_stdout_test.go +43 -0
  384. package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go +81 -0
  385. package/native/cmd/ttsc-typia/transform_single_file_js_empty_emit_reports_no_output_test.go +100 -0
  386. package/native/cmd/ttsc-typia/transform_single_file_js_locates_output_across_layouts_test.go +160 -0
  387. package/native/cmd/ttsc-typia/transform_single_file_success_publishes_artifact_test.go +54 -0
  388. package/native/cmd/ttsc-typia/transform_wasm_host_argv_reports_diagnostics_test.go +39 -0
  389. package/native/cmd/ttsc-typia/tuple_optional_compare_clone_transform_test.go +227 -0
  390. package/native/cmd/ttsc-typia/user_global_native_identity_transform_test.go +484 -0
  391. package/native/core/factories/FormatCheatSheet.go +40 -7
  392. package/native/core/factories/IdentifierFactory.go +131 -4
  393. package/native/core/factories/MetadataCommentTagFactory.go +83 -40
  394. package/native/core/factories/MetadataTypeTagFactory.go +13 -1
  395. package/native/core/factories/NumericRangeFactory.go +60 -17
  396. package/native/core/factories/ProtobufFactory.go +13 -5
  397. package/native/core/factories/factory_utility_coverage_test.go +8 -2
  398. package/native/core/factories/format_alias_resolves_to_cheat_sheet_test.go +57 -0
  399. package/native/core/factories/format_alias_table_targets_the_cheat_sheet_test.go +44 -0
  400. package/native/core/factories/identifier_factory_postfix_escapes_every_key_test.go +147 -0
  401. package/native/core/factories/identifier_factory_postfix_survives_every_code_point_test.go +86 -0
  402. package/native/core/factories/internal/metadata/MetadataHelper.go +226 -17
  403. package/native/core/factories/internal/metadata/emplace_metadata_object.go +141 -8
  404. package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
  405. package/native/core/factories/internal/metadata/iterate_metadata_function.go +5 -12
  406. package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +111 -29
  407. package/native/core/factories/internal/metadata/iterate_metadata_map.go +5 -0
  408. package/native/core/factories/internal/metadata/iterate_metadata_native.go +45 -2
  409. package/native/core/factories/internal/metadata/iterate_metadata_set.go +5 -0
  410. package/native/core/factories/internal/metadata/type_arguments_precondition_test.go +70 -0
  411. package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +39 -0
  412. package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go +84 -0
  413. package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go +60 -0
  414. package/native/core/factories/metadata_type_tag_factory_declarations_test.go +86 -0
  415. package/native/core/factories/metadata_type_tag_factory_keeps_bool_form_exclusivity_test.go +38 -0
  416. package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go +65 -0
  417. package/native/core/factories/metadata_type_tag_factory_rejects_duplicated_array_form_tags_test.go +41 -0
  418. package/native/core/factories/numeric_range_factory_enforces_64bit_bounds_test.go +69 -0
  419. package/native/core/factories/protobuf_recovery_ownership_test.go +64 -0
  420. package/native/core/programmers/IsProgrammer.go +15 -1
  421. package/native/core/programmers/RandomProgrammer.go +51 -14
  422. package/native/core/programmers/compare/CompareEqualProgrammer.go +410 -8
  423. package/native/core/programmers/compare/CompareLessProgrammer.go +4 -2
  424. package/native/core/programmers/functional/FunctionalAssertFunctionProgrammer.go +4 -6
  425. package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +5 -13
  426. package/native/core/programmers/functional/FunctionalAssertReturnProgrammer.go +6 -14
  427. package/native/core/programmers/functional/FunctionalIsFunctionProgrammer.go +4 -6
  428. package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +49 -14
  429. package/native/core/programmers/functional/FunctionalIsReturnProgrammer.go +5 -13
  430. package/native/core/programmers/functional/FunctionalValidateFunctionProgrammer.go +4 -6
  431. package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +5 -13
  432. package/native/core/programmers/functional/FunctionalValidateReturnProgrammer.go +5 -13
  433. package/native/core/programmers/functional/internal/FunctionalGeneralProgrammer.go +4 -17
  434. package/native/core/programmers/helpers/CloneJoiner.go +32 -0
  435. package/native/core/programmers/helpers/FunctionProgrammer.go +6 -13
  436. package/native/core/programmers/helpers/NotationJoiner.go +86 -28
  437. package/native/core/programmers/helpers/StringifyJoinder.go +161 -51
  438. package/native/core/programmers/helpers/UnionExplorer.go +203 -61
  439. package/native/core/programmers/helpers/joiner_branch_coverage_test.go +116 -118
  440. package/native/core/programmers/helpers/union_explorer_coverage_test.go +1 -1
  441. package/native/core/programmers/internal/CheckerProgrammer.go +100 -48
  442. package/native/core/programmers/iterate/check_template.go +344 -32
  443. package/native/core/programmers/iterate/iterate_check_coverage_test.go +76 -158
  444. package/native/core/programmers/iterate/iterate_utility_coverage_test.go +231 -270
  445. package/native/core/programmers/iterate/json_schema_discriminator.go +36 -10
  446. package/native/core/programmers/iterate/json_schema_discriminator_declaration_syntax_test.go +205 -0
  447. package/native/core/programmers/iterate/json_schema_object.go +49 -7
  448. package/native/core/programmers/iterate/json_schema_pattern_property_order_test.go +44 -0
  449. package/native/core/programmers/iterate/openapi_v3_downgrader.go +674 -0
  450. package/native/core/programmers/iterate/openapi_v3_downgrader_boolean_default_test.go +95 -0
  451. package/native/core/programmers/iterate/openapi_v3_downgrader_test.go +123 -0
  452. package/native/core/programmers/iterate/template_interpolation_tags_test.go +40 -8
  453. package/native/core/programmers/iterate/template_runtime_pattern.go +63 -7
  454. package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
  455. package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
  456. package/native/core/programmers/json/JsonStringifyProgrammer.go +47 -6
  457. package/native/core/programmers/llm/LlmApplicationProgrammer.go +21 -11
  458. package/native/core/programmers/llm/LlmSchemaProgrammer.go +23 -6
  459. package/native/core/programmers/llm/llm_reference_codec_test.go +24 -0
  460. package/native/core/programmers/notations/NotationGeneralProgrammer.go +183 -67
  461. package/native/core/programmers/notations/notation_general_helpers_test.go +1 -3
  462. package/native/core/programmers/notations/notation_general_programmer_pascal_multiword_test.go +72 -0
  463. package/native/core/programmers/notations/notation_general_programmer_underscore_boundary_test.go +68 -0
  464. package/native/core/programmers/plain/PlainClassifyProgrammer.go +23 -15
  465. package/native/core/programmers/plain/PlainCloneProgrammer.go +20 -7
  466. package/native/core/programmers/plain/PlainPruneProgrammer.go +19 -5
  467. package/native/core/programmers/plain/plain_tuple_seed_recovery_ownership_test.go +25 -0
  468. package/native/core/programmers/protobuf/ProtobufDecodeProgrammer.go +37 -28
  469. package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +41 -22
  470. package/native/core/programmers/protobuf/protobuf_programmer_helper_coverage_test.go +26 -0
  471. package/native/core/programmers/random_programmer_length_argument_test.go +53 -0
  472. package/native/core/schemas/metadata/MetadataCollection.go +266 -25
  473. package/native/core/schemas/metadata/MetadataDefaultLibrary.go +81 -0
  474. package/native/core/schemas/metadata/MetadataDependency.go +388 -0
  475. package/native/core/schemas/metadata/MetadataObjectType.go +24 -22
  476. package/native/core/schemas/metadata/metadata_collection_generic_argument_dot_test.go +122 -0
  477. package/native/core/schemas/metadata/metadata_collection_name_allocation_test.go +147 -0
  478. package/native/core/schemas/metadata/metadata_collection_openapi_name_cascade_test.go +55 -0
  479. package/native/core/schemas/metadata/metadata_collection_openapi_name_test.go +68 -0
  480. package/native/core/utils/PatternUtil.go +13 -0
  481. package/native/core/utils/PromiseTypeFactory.go +59 -0
  482. package/native/core/utils/ProtobufNameEncoder.go +8 -0
  483. package/native/core/utils/promise_type_factory_semantics_test.go +118 -0
  484. package/native/go.mod +9 -1
  485. package/native/transform/CallExpressionTransformer.go +12 -0
  486. package/native/transform/features/json/JsonApplicationTransformer.go +1 -1
  487. package/native/transform/features/json/JsonSchemaTransformer.go +1 -1
  488. package/native/transform/features/json/JsonSchemasTransformer.go +5 -4
  489. package/native/transform/features/protobuf/ProtobufMessageTransformer.go +1 -1
  490. package/package.json +12 -4
  491. package/src/executable/FileSystemIdentity.ts +222 -0
  492. package/src/executable/TypiaGenerateWizard.ts +386 -113
  493. package/src/functional.ts +30 -60
  494. package/src/internal/_ProtobufReader.ts +161 -46
  495. package/src/internal/_createStandardSchema.ts +15 -1
  496. package/src/internal/_decimal.ts +69 -0
  497. package/src/internal/_httpQueryParseURLSearchParams.ts +24 -2
  498. package/src/internal/_isFormatByte.ts +2 -5
  499. package/src/internal/_isFormatDate.ts +15 -2
  500. package/src/internal/_isFormatDateTime.ts +28 -2
  501. package/src/internal/_isFormatIri.ts +5 -2
  502. package/src/internal/_isFormatIriReference.ts +11 -3
  503. package/src/internal/_isFormatUriReference.ts +1 -1
  504. package/src/internal/_isMultipleOf.ts +8 -0
  505. package/src/internal/_isTypeFloat.ts +1 -1
  506. package/src/internal/_isTypeInt64.ts +1 -0
  507. package/src/internal/_isTypeInt64Bigint.ts +12 -0
  508. package/src/internal/_isTypeUint64.ts +1 -0
  509. package/src/internal/_isTypeUint64Bigint.ts +7 -0
  510. package/src/internal/_isUniqueItems.ts +134 -132
  511. package/src/internal/_jsonStringifyArray.ts +50 -0
  512. package/src/internal/_jsonStringifyElement.ts +19 -0
  513. package/src/internal/_jsonStringifyProperty.ts +30 -0
  514. package/src/internal/_llmApplicationFinalize.ts +6 -1
  515. package/src/internal/_notationAny.ts +9 -4
  516. package/src/internal/_notationAssign.ts +20 -0
  517. package/src/internal/_notationCamel.ts +31 -10
  518. package/src/internal/_notationKebab.ts +11 -0
  519. package/src/internal/_notationKeyCollision.ts +9 -0
  520. package/src/internal/_notationPascal.ts +19 -6
  521. package/src/internal/_notationSnake.ts +24 -21
  522. package/src/internal/_plainCloneAny.ts +208 -33
  523. package/src/internal/_randomArray.ts +13 -4
  524. package/src/internal/_randomFormatByte.ts +31 -1
  525. package/src/internal/_randomFormatDate.ts +6 -17
  526. package/src/internal/_randomFormatDatetime.ts +34 -15
  527. package/src/internal/_randomFormatDuration.ts +30 -13
  528. package/src/internal/_randomFormatEmail.ts +8 -2
  529. package/src/internal/_randomFormatHostname.ts +48 -1
  530. package/src/internal/_randomFormatIdnEmail.ts +18 -2
  531. package/src/internal/_randomFormatIdnHostname.ts +34 -2
  532. package/src/internal/_randomFormatIpv4.ts +43 -2
  533. package/src/internal/_randomFormatIpv6.ts +67 -2
  534. package/src/internal/_randomFormatIri.ts +3 -1
  535. package/src/internal/_randomFormatIriReference.ts +3 -1
  536. package/src/internal/_randomFormatJsonPointer.ts +28 -2
  537. package/src/internal/_randomFormatPassword.ts +11 -6
  538. package/src/internal/_randomFormatRegex.ts +22 -1
  539. package/src/internal/_randomFormatRelativeJsonPointer.ts +26 -6
  540. package/src/internal/_randomFormatTime.ts +46 -10
  541. package/src/internal/_randomFormatUri.ts +3 -1
  542. package/src/internal/_randomFormatUriReference.ts +3 -1
  543. package/src/internal/_randomFormatUriTemplate.ts +3 -1
  544. package/src/internal/_randomFormatUrl.ts +25 -2
  545. package/src/internal/_randomFormatUuid.ts +10 -6
  546. package/src/internal/_randomInteger.ts +87 -40
  547. package/src/internal/_randomMultiple.ts +245 -0
  548. package/src/internal/_randomNumber.ts +72 -55
  549. package/src/internal/_randomPattern.ts +29 -4
  550. package/src/internal/_randomStringLength.ts +116 -0
  551. package/src/internal/_stringLength.ts +5 -0
  552. package/src/internal/_validateReport.ts +5 -1
  553. package/src/internal/private/__notationRename.ts +21 -0
  554. package/src/internal/private/__randomComposition.ts +50 -0
  555. package/src/internal/private/__randomEpoch.ts +34 -0
  556. package/src/json.ts +2 -2
  557. package/src/module.ts +4 -6
  558. package/src/notations.ts +20 -4
  559. package/lib/internal/private/__notationCapitalize.d.ts +0 -1
  560. package/lib/internal/private/__notationCapitalize.js +0 -6
  561. package/lib/internal/private/__notationCapitalize.js.map +0 -1
  562. package/lib/internal/private/__notationCapitalize.mjs +0 -6
  563. package/lib/internal/private/__notationCapitalize.mjs.map +0 -1
  564. package/lib/internal/private/__notationUnsnake.d.ts +0 -4
  565. package/lib/internal/private/__notationUnsnake.js +0 -26
  566. package/lib/internal/private/__notationUnsnake.js.map +0 -1
  567. package/lib/internal/private/__notationUnsnake.mjs +0 -15
  568. package/lib/internal/private/__notationUnsnake.mjs.map +0 -1
  569. package/native/adapter/visit.go +0 -173
  570. package/native/adapter/visit_property_chain_edges_test.go +0 -129
  571. package/native/cmd/ttsc-typia/plugin_options_missing_config_test.go +0 -26
  572. package/native/cmd/ttsc-typia/plugin_options_undefined_false_test.go +0 -36
  573. package/native/core/programmers/helpers/disable_function_programmer_declare.go +0 -10
  574. package/native/core/programmers/iterate/check_union_array_like.go +0 -422
  575. package/native/core/programmers/iterate/prune_object_properties.go +0 -105
  576. package/native/core/programmers/iterate/stringify_dynamic_properties.go +0 -219
  577. package/native/core/programmers/iterate/stringify_native.go +0 -14
  578. package/native/core/programmers/iterate/stringify_regular_properties.go +0 -112
  579. package/native/core/schemas/metadata/MetadataApplication.go +0 -41
  580. package/src/internal/private/__notationCapitalize.ts +0 -2
  581. package/src/internal/private/__notationUnsnake.ts +0 -24
@@ -0,0 +1,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
+ `
@@ -0,0 +1,219 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "os/exec"
6
+ "path/filepath"
7
+ "testing"
8
+ )
9
+
10
+ // TestPlainPruneUnionObjectOvermatchTransform pins prune over mixed unions.
11
+ //
12
+ // PlainPruneProgrammer emits one independent `if` per union member, and the
13
+ // object arm's guard is `IsObject` with `CheckArray:false`, which also matches
14
+ // arrays and native instances. With no `else` the array/native arm AND the
15
+ // object arm both run, so `Object.keys(input)` on a value another arm already
16
+ // owns gets its slots deleted: a typed array throws on `delete input[0]`, a
17
+ // plain array collapses to holes, and a native's own properties are stripped.
18
+ // clone/classify resolve the same unions with a mutually exclusive ladder, so
19
+ // the object arm is only reached when the value is a plain object. This test
20
+ // drives every native kind unioned with an object in both orders, plus an
21
+ // object∪tuple, and requires the native/array/tuple value to survive intact.
22
+ //
23
+ // 1. Transform prune factories over native|object, object|native, array|object
24
+ // and object|tuple unions.
25
+ // 2. Execute prune against a typed array, Date, Map, Set, RegExp, plain array,
26
+ // and tuple, requiring each to keep its identity and own state.
27
+ // 3. Require the object arm still prunes an ordinary object member.
28
+ func TestPlainPruneUnionObjectOvermatchTransform(t *testing.T) {
29
+ project := plainPruneUnionObjectOvermatchProject(t)
30
+ out, errText, code := ttscTypiaTestCapture(func() int {
31
+ return runTransform([]string{
32
+ "--cwd", project,
33
+ "--tsconfig", "tsconfig.json",
34
+ "--file", "src/main.ts",
35
+ "--output", "js",
36
+ })
37
+ })
38
+ if code != 0 {
39
+ t.Fatalf("prune union/object over-match transform failed: code=%d stderr=\n%s", code, errText)
40
+ }
41
+ plainPruneUnionObjectOvermatchRunRuntimeCases(t, project, out)
42
+ }
43
+
44
+ func plainPruneUnionObjectOvermatchProject(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, "plain-prune-union-object-")
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(plainPruneUnionObjectOvermatchTSConfig), 0o644); err != nil {
63
+ t.Fatalf("write tsconfig: %v", err)
64
+ }
65
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(plainPruneUnionObjectOvermatchSource), 0o644); err != nil {
66
+ t.Fatalf("write source: %v", err)
67
+ }
68
+ return dir
69
+ }
70
+
71
+ func plainPruneUnionObjectOvermatchRunRuntimeCases(t *testing.T, project string, js string) {
72
+ t.Helper()
73
+ node, err := exec.LookPath("node")
74
+ if err != nil {
75
+ t.Skip("node executable not found")
76
+ }
77
+ runtimeDir := filepath.Join(project, "runtime")
78
+ if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
79
+ t.Fatalf("mkdir runtime dir: %v", err)
80
+ }
81
+ ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
82
+ runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
83
+ if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
84
+ t.Fatalf("write runtime module: %v", err)
85
+ }
86
+ runner := filepath.Join(runtimeDir, "run.cjs")
87
+ if err := os.WriteFile(runner, []byte(plainPruneUnionObjectOvermatchRuntimeRunner), 0o644); err != nil {
88
+ t.Fatalf("write runtime runner: %v", err)
89
+ }
90
+ cmd := exec.Command(node, runner)
91
+ cmd.Dir = runtimeDir
92
+ output, err := cmd.CombinedOutput()
93
+ if err != nil {
94
+ t.Fatalf("prune union/object over-match runtime cases failed: %v\n%s", err, output)
95
+ }
96
+ }
97
+
98
+ const plainPruneUnionObjectOvermatchTSConfig = `{
99
+ "compilerOptions": {
100
+ "target": "ES2022",
101
+ "module": "commonjs",
102
+ "moduleResolution": "bundler",
103
+ "ignoreDeprecations": "6.0",
104
+ "types": ["*"],
105
+ "esModuleInterop": true,
106
+ "strict": true,
107
+ "skipLibCheck": true
108
+ },
109
+ "include": ["src"]
110
+ }
111
+ `
112
+
113
+ const plainPruneUnionObjectOvermatchSource = `import typia from "typia";
114
+
115
+ interface IBox {
116
+ x: number;
117
+ }
118
+ interface IElem {
119
+ y: number;
120
+ }
121
+
122
+ export const pruneBytesFirst = typia.plain.createPrune<Uint8Array | IBox>();
123
+ export const pruneBytesLast = typia.plain.createPrune<IBox | Uint8Array>();
124
+ export const pruneDateFirst = typia.plain.createPrune<Date | IBox>();
125
+ export const pruneDateLast = typia.plain.createPrune<IBox | Date>();
126
+ export const pruneMap = typia.plain.createPrune<Map<string, number> | IBox>();
127
+ export const pruneSet = typia.plain.createPrune<IBox | Set<number>>();
128
+ export const pruneRegExp = typia.plain.createPrune<RegExp | IBox>();
129
+ export const pruneArray = typia.plain.createPrune<IElem[] | IBox>();
130
+ export const pruneTuple = typia.plain.createPrune<IBox | [IElem, IElem]>();
131
+ `
132
+
133
+ const plainPruneUnionObjectOvermatchRuntimeRunner = `const mod = require("./main.cjs");
134
+
135
+ const fail = (label, detail) => {
136
+ throw new Error(label + ": " + detail);
137
+ };
138
+
139
+ // 1. A typed array must survive prune untouched (the buggy object arm throws
140
+ // "Cannot delete property '0'" while deleting its integer-indexed slots).
141
+ for (const [label, prune] of [
142
+ ["Uint8Array | IBox", mod.pruneBytesFirst],
143
+ ["IBox | Uint8Array", mod.pruneBytesLast],
144
+ ]) {
145
+ const bytes = new Uint8Array([1, 2, 3]);
146
+ prune(bytes);
147
+ if (!(bytes instanceof Uint8Array) || bytes.length !== 3 || bytes[0] !== 1 || bytes[1] !== 2 || bytes[2] !== 3)
148
+ fail(label, "typed array corrupted -> " + JSON.stringify(Array.from(bytes)));
149
+ }
150
+
151
+ // 2. A Date must keep its time and its own state; the object arm strips own keys.
152
+ for (const [label, prune] of [
153
+ ["Date | IBox", mod.pruneDateFirst],
154
+ ["IBox | Date", mod.pruneDateLast],
155
+ ]) {
156
+ const date = new Date(1000);
157
+ date.tag = "keep";
158
+ prune(date);
159
+ if (!(date instanceof Date) || date.getTime() !== 1000)
160
+ fail(label, "Date time corrupted -> " + date.getTime());
161
+ if (date.tag !== "keep")
162
+ fail(label, "Date own property stripped");
163
+ }
164
+
165
+ // 3. A Map / Set must keep their contents and own state.
166
+ {
167
+ const map = new Map([["a", 1]]);
168
+ map.tag = "keep";
169
+ mod.pruneMap(map);
170
+ if (!(map instanceof Map) || map.size !== 1 || map.get("a") !== 1 || map.tag !== "keep")
171
+ fail("Map<string,number> | IBox", "Map corrupted");
172
+ }
173
+ {
174
+ const set = new Set([7]);
175
+ set.tag = "keep";
176
+ mod.pruneSet(set);
177
+ if (!(set instanceof Set) || set.size !== 1 || set.has(7) === false || set.tag !== "keep")
178
+ fail("IBox | Set<number>", "Set corrupted");
179
+ }
180
+
181
+ // 4. A RegExp with equal source but its own state must survive.
182
+ {
183
+ const re = /abc/gi;
184
+ re.tag = "keep";
185
+ mod.pruneRegExp(re);
186
+ if (!(re instanceof RegExp) || re.source !== "abc" || re.flags !== "gi" || re.tag !== "keep")
187
+ fail("RegExp | IBox", "RegExp corrupted");
188
+ }
189
+
190
+ // 5. A plain array must be pruned element-by-element, not deleted to holes.
191
+ {
192
+ const arr = [{ y: 1, extra: 2 }, { y: 3, extra: 4 }];
193
+ mod.pruneArray(arr);
194
+ if (!Array.isArray(arr) || arr.length !== 2)
195
+ fail("IElem[] | IBox", "array shape corrupted -> " + JSON.stringify(arr));
196
+ if (arr[0] === undefined || arr[1] === undefined)
197
+ fail("IElem[] | IBox", "array slot deleted -> " + JSON.stringify(arr));
198
+ if (arr[0].y !== 1 || arr[1].y !== 3 || "extra" in arr[0] || "extra" in arr[1])
199
+ fail("IElem[] | IBox", "array elements not pruned as objects -> " + JSON.stringify(arr));
200
+ }
201
+
202
+ // 6. An object∪tuple must prune the tuple positionally, not delete its slots.
203
+ {
204
+ const tuple = [{ y: 1, extra: 2 }, { y: 3, extra: 4 }];
205
+ mod.pruneTuple(tuple);
206
+ if (!Array.isArray(tuple) || tuple.length !== 2 || tuple[0] === undefined || tuple[1] === undefined)
207
+ fail("IBox | [IElem, IElem]", "tuple slot deleted -> " + JSON.stringify(tuple));
208
+ if (tuple[0].y !== 1 || tuple[1].y !== 3 || "extra" in tuple[0] || "extra" in tuple[1])
209
+ fail("IBox | [IElem, IElem]", "tuple elements not pruned -> " + JSON.stringify(tuple));
210
+ }
211
+
212
+ // 7. The object arm must still prune an ordinary object member (nothing lost).
213
+ {
214
+ const box = { x: 1, junk: "drop" };
215
+ mod.pruneBytesFirst(box);
216
+ if (box.x !== 1 || "junk" in box)
217
+ fail("Uint8Array | IBox", "object member not pruned -> " + JSON.stringify(box));
218
+ }
219
+ `
@@ -0,0 +1,181 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "path/filepath"
6
+ "strings"
7
+ "testing"
8
+ )
9
+
10
+ // pluginOptionsPayloadCase is one row of the #1887 regression matrix: a project
11
+ // whose tsconfig the user wrote a particular way, the payload ttsc resolves that
12
+ // tsconfig into and hands the plugin, and whether typia's `functional` option is
13
+ // on as a result.
14
+ //
15
+ // `functional` is the probe because its effect is visible in the transform's own
16
+ // output: with the option on, a function-typed property becomes significant and
17
+ // the emitted validator checks it; with the option off, the property is skipped.
18
+ type pluginOptionsPayloadCase struct {
19
+ name string
20
+ // base is a base tsconfig the leaf `extends`, or "" for a single-file project.
21
+ base string
22
+ // leafPlugins is the `compilerOptions.plugins` text of the leaf tsconfig, or
23
+ // "" when the leaf declares no plugins at all.
24
+ leafPlugins string
25
+ // payload is the `--plugins-json` manifest ttsc sends for this project.
26
+ payload string
27
+ // functional is whether the emitted validator must check the function-typed
28
+ // property.
29
+ functional bool
30
+ }
31
+
32
+ // pluginOptionsPayloadCases returns the matrix every host must satisfy.
33
+ //
34
+ // Each row pairs the tsconfig the user wrote with the payload the host resolves
35
+ // it into, so the oracle is ttsc's plugin contract rather than typia's current
36
+ // output. The rows are the reproduction table of samchon/typia#1887: the
37
+ // comment and sibling-entry rows prove typia no longer matches option names
38
+ // against raw tsconfig text, and the `extends` row proves it no longer ignores
39
+ // the entry that loaded it.
40
+ func pluginOptionsPayloadCases() []pluginOptionsPayloadCase {
41
+ return []pluginOptionsPayloadCase{
42
+ {
43
+ // The documented shape, and the only one the old scrape read correctly.
44
+ // Pins behavior that must not change.
45
+ name: "option inline on typia's entry",
46
+ leafPlugins: `[{ "transform": "typia/lib/transform", "functional": true }]`,
47
+ payload: `[{"config":{"transform":"typia/lib/transform","functional":true},"name":"typia","stage":"transform"}]`,
48
+ functional: true,
49
+ },
50
+ {
51
+ // The user disabled the option. tsconfig is JSONC, so the host drops the
52
+ // comment and typia's entry carries nothing.
53
+ name: "option commented out with a line comment",
54
+ leafPlugins: `[{
55
+ "transform": "typia/lib/transform"
56
+ // "functional": true
57
+ }]`,
58
+ payload: `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`,
59
+ functional: false,
60
+ },
61
+ {
62
+ name: "option commented out with a block comment",
63
+ leafPlugins: `[{
64
+ "transform": "typia/lib/transform"
65
+ /* "functional": true */
66
+ }]`,
67
+ payload: `[{"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}]`,
68
+ functional: false,
69
+ },
70
+ {
71
+ // A transform host carries every transform-stage plugin's entry. The
72
+ // option belongs to the sibling, and reading it would be reading someone
73
+ // else's configuration.
74
+ name: "option owned by another plugin's entry",
75
+ leafPlugins: `[
76
+ { "transform": "other/lib/transform", "functional": true },
77
+ { "transform": "typia/lib/transform" }
78
+ ]`,
79
+ payload: `[
80
+ {"config":{"transform":"other/lib/transform","functional":true},"name":"other","stage":"transform"},
81
+ {"config":{"transform":"typia/lib/transform"},"name":"typia","stage":"transform"}
82
+ ]`,
83
+ functional: false,
84
+ },
85
+ {
86
+ // The standard monorepo layout: a shared base declares the plugin and its
87
+ // options, the leaf only extends it. The host resolved the chain and sent
88
+ // the merged entry -- which is why the plugin is running at all.
89
+ name: "option declared in a base tsconfig the leaf extends",
90
+ base: `{
91
+ "compilerOptions": {
92
+ "plugins": [{ "transform": "typia/lib/transform", "functional": true }]
93
+ }
94
+ }
95
+ `,
96
+ payload: `[{"config":{"transform":"typia/lib/transform","functional":true},"name":"typia","stage":"transform"}]`,
97
+ functional: true,
98
+ },
99
+ }
100
+ }
101
+
102
+ // pluginOptionsPayloadProject materializes one matrix row as a real project: the
103
+ // tsconfig exactly as the user wrote it (comments, sibling entries, `extends`
104
+ // chain and all), a typia stub to resolve the import against, and a source file
105
+ // with a function-typed property for the option to act on.
106
+ func pluginOptionsPayloadProject(t *testing.T, tc pluginOptionsPayloadCase) string {
107
+ t.Helper()
108
+ project := t.TempDir()
109
+ src := filepath.Join(project, "src")
110
+ if err := os.MkdirAll(src, 0o755); err != nil {
111
+ t.Fatalf("mkdir fixture src: %v", err)
112
+ }
113
+
114
+ extends := ""
115
+ if tc.base != "" {
116
+ if err := os.WriteFile(filepath.Join(project, "tsconfig.base.json"), []byte(tc.base), 0o644); err != nil {
117
+ t.Fatalf("write base tsconfig: %v", err)
118
+ }
119
+ extends = `"extends": "./tsconfig.base.json",
120
+ `
121
+ }
122
+ plugins := ""
123
+ if tc.leafPlugins != "" {
124
+ plugins = `,
125
+ "plugins": ` + tc.leafPlugins
126
+ }
127
+ config := `{
128
+ ` + extends + `"compilerOptions": {
129
+ "target": "ES2022",
130
+ "module": "commonjs",
131
+ "moduleResolution": "bundler",
132
+ "ignoreDeprecations": "6.0",
133
+ "types": ["*"],
134
+ "esModuleInterop": true,
135
+ "strict": true,
136
+ "skipLibCheck": true,
137
+ "rootDir": "src",
138
+ "outDir": "dist"` + plugins + `
139
+ },
140
+ "include": ["src"]
141
+ }
142
+ `
143
+ if err := os.WriteFile(filepath.Join(project, "tsconfig.json"), []byte(config), 0o644); err != nil {
144
+ t.Fatalf("write tsconfig: %v", err)
145
+ }
146
+ transformDiagnosticWriteTypiaStub(t, project)
147
+ if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(pluginOptionsPayloadSource), 0o644); err != nil {
148
+ t.Fatalf("write source: %v", err)
149
+ }
150
+ return project
151
+ }
152
+
153
+ // pluginOptionsPayloadAssert checks one host's output against the row's expected
154
+ // option state.
155
+ func pluginOptionsPayloadAssert(t *testing.T, tc pluginOptionsPayloadCase, output string) {
156
+ t.Helper()
157
+ checked := pluginOptionsPayloadFunctionalCheck(output)
158
+ if checked == tc.functional {
159
+ return
160
+ }
161
+ if tc.functional {
162
+ t.Fatalf("functional is configured on but the validator skipped the function property:\n%s", output)
163
+ }
164
+ t.Fatalf("functional is not configured but the validator checked the function property:\n%s", output)
165
+ }
166
+
167
+ func pluginOptionsPayloadFunctionalCheck(output string) bool {
168
+ return strings.Contains(output, pluginOptionsPayloadFunctionalNeedle)
169
+ }
170
+
171
+ // pluginOptionsPayloadFunctionalNeedle is the guard typia emits for the
172
+ // function-typed property only when `functional` is enabled.
173
+ const pluginOptionsPayloadFunctionalNeedle = `"function" === typeof input.cb`
174
+
175
+ const pluginOptionsPayloadSource = `import typia from "typia";
176
+ export interface IX {
177
+ value: number;
178
+ cb: () => void;
179
+ }
180
+ export const check = (input: unknown): boolean => typia.is<IX>(input);
181
+ `