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,95 @@
1
+ package iterate
2
+
3
+ import (
4
+ "testing"
5
+ )
6
+
7
+ // TestOpenApiV3DowngraderCarriesBooleanKeywords verifies the 3.0 downgrade keeps
8
+ // a boolean's declared keywords instead of rebuilding a bare `{"type":
9
+ // "boolean"}`.
10
+ //
11
+ // The boolean branch used to append `{"type": "boolean"}` from scratch, dropping
12
+ // `default` and every other keyword, while the number/string/reference branch
13
+ // carried theirs through `omit_examples`. So a `boolean & Default<true>` kept
14
+ // `default` under 3.1 but lost it under 3.0, contradicting
15
+ // `OpenApiV3.IJsonSchema.IBoolean`, which declares `default` (and the shared
16
+ // `title`/`description`/`deprecated` attributes). The expectations below come
17
+ // from that declared type: only keys it allows may survive, and `examples` — the
18
+ // one 3.0 does not define — must not.
19
+ //
20
+ // 1. Downgrade a boolean carrying `default`, and one also carrying attributes.
21
+ // 2. Assert each keeps every declared keyword and drops only `examples`.
22
+ // 3. Assert a keyword-less boolean still degrades to a bare `{"type": "boolean"}`
23
+ // and that a boolean inside a union keeps its `default`.
24
+ func TestOpenApiV3DowngraderCarriesBooleanKeywords(t *testing.T) {
25
+ collection := OpenApiV3Downgrader_downgrade_components(&OpenApi_IComponents{})
26
+
27
+ cases := []struct {
28
+ label string
29
+ input JsonSchema
30
+ expected JsonSchema
31
+ }{
32
+ {
33
+ label: "boolean carries its default",
34
+ input: JsonSchema{"type": "boolean", "default": true},
35
+ expected: JsonSchema{"type": "boolean", "default": true},
36
+ },
37
+ {
38
+ label: "boolean carries default:false and shared attributes",
39
+ input: JsonSchema{
40
+ "type": "boolean",
41
+ "default": false,
42
+ "title": "Enabled",
43
+ "description": "Whether the feature is enabled.",
44
+ "deprecated": true,
45
+ },
46
+ expected: JsonSchema{
47
+ "type": "boolean",
48
+ "default": false,
49
+ "title": "Enabled",
50
+ "description": "Whether the feature is enabled.",
51
+ "deprecated": true,
52
+ },
53
+ },
54
+ {
55
+ // `examples` is the one attribute 3.0 does not define; the downgrade must
56
+ // drop it while keeping `default`.
57
+ label: "boolean drops examples but keeps default",
58
+ input: JsonSchema{
59
+ "type": "boolean",
60
+ "default": true,
61
+ "examples": map[string]any{"on": true},
62
+ },
63
+ expected: JsonSchema{"type": "boolean", "default": true},
64
+ },
65
+ {
66
+ label: "keyword-less boolean stays bare",
67
+ input: JsonSchema{"type": "boolean"},
68
+ expected: JsonSchema{"type": "boolean"},
69
+ },
70
+ {
71
+ label: "boolean default survives inside a union",
72
+ input: JsonSchema{
73
+ "oneOf": []JsonSchema{
74
+ {"type": "boolean", "default": true},
75
+ {"type": "number"},
76
+ },
77
+ },
78
+ expected: JsonSchema{
79
+ "oneOf": []JsonSchema{
80
+ {"type": "boolean", "default": true},
81
+ {"type": "number"},
82
+ },
83
+ },
84
+ },
85
+ }
86
+
87
+ for _, tc := range cases {
88
+ actual := OpenApiV3Downgrader_downgrade_schema(collection, tc.input)
89
+ if openApiV3DowngraderTestJSON(t, actual) != openApiV3DowngraderTestJSON(t, tc.expected) {
90
+ t.Fatalf("%s: got %s, want %s", tc.label,
91
+ openApiV3DowngraderTestJSON(t, actual),
92
+ openApiV3DowngraderTestJSON(t, tc.expected))
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,123 @@
1
+ package iterate
2
+
3
+ import (
4
+ "encoding/json"
5
+ "strings"
6
+ "testing"
7
+ )
8
+
9
+ // TestOpenApiV3DowngraderRewritesDialect verifies the 3.0 downgrade rewrites the
10
+ // three constructs the emended 3.1 writer emits that OpenAPI 3.0 does not define.
11
+ //
12
+ // json_schema_station speaks 3.1 only: a nullable type is a `{"type": "null"}`
13
+ // union member, a literal is `const`, and a tuple is `prefixItems`. The "3.0"
14
+ // entry points used to relabel that document without rewriting it, so a document
15
+ // declaring 3.0 carried keywords no conformant 3.0 consumer can read. The
16
+ // expected shapes below come from the OpenAPI 3.0 specification, not from what
17
+ // the downgrader happens to produce.
18
+ //
19
+ // 1. Downgrade a nullable atomic, a literal union, and a tuple.
20
+ // 2. Assert each uses the 3.0 spelling: nullable flag, enum, bounded array.
21
+ // 3. Assert no 3.1-only keyword (`const`, `prefixItems`, a null union member)
22
+ // survives.
23
+ func TestOpenApiV3DowngraderRewritesDialect(t *testing.T) {
24
+ collection := OpenApiV3Downgrader_downgrade_components(&OpenApi_IComponents{})
25
+
26
+ cases := []struct {
27
+ label string
28
+ input JsonSchema
29
+ expected JsonSchema
30
+ }{
31
+ {
32
+ label: "nullable atomic uses the nullable flag",
33
+ input: JsonSchema{
34
+ "oneOf": []JsonSchema{
35
+ {"type": "null"},
36
+ {"type": "string"},
37
+ },
38
+ },
39
+ expected: JsonSchema{"type": "string", "nullable": true},
40
+ },
41
+ {
42
+ label: "literal union collapses to enum",
43
+ input: JsonSchema{
44
+ "oneOf": []JsonSchema{
45
+ {"const": "alpha"},
46
+ {"const": "beta"},
47
+ },
48
+ },
49
+ expected: JsonSchema{"type": "string", "enum": []any{"alpha", "beta"}},
50
+ },
51
+ {
52
+ // A numeric literal reaches the downgrader as the compiler's named
53
+ // `jsnum.Number` (underlying float64), so classifying constants by
54
+ // concrete type mislabels the numeric branch `object`. The named type
55
+ // below stands in for it.
56
+ label: "mixed literal union labels the numeric branch number",
57
+ input: JsonSchema{
58
+ "oneOf": []JsonSchema{
59
+ {"const": "three"},
60
+ {"const": openApiV3DowngraderTestNumber(1)},
61
+ {"const": openApiV3DowngraderTestNumber(2)},
62
+ },
63
+ },
64
+ expected: JsonSchema{
65
+ "oneOf": []JsonSchema{
66
+ {"type": "string", "enum": []any{"three"}},
67
+ {"type": "number", "enum": []any{openApiV3DowngraderTestNumber(1), openApiV3DowngraderTestNumber(2)}},
68
+ },
69
+ },
70
+ },
71
+ {
72
+ label: "tuple degrades to a bounded array",
73
+ input: JsonSchema{
74
+ "type": "array",
75
+ "prefixItems": []JsonSchema{
76
+ {"type": "string"},
77
+ {"type": "number"},
78
+ },
79
+ "additionalItems": false,
80
+ },
81
+ expected: JsonSchema{
82
+ "type": "array",
83
+ "items": JsonSchema{
84
+ "oneOf": []JsonSchema{
85
+ {"type": "string"},
86
+ {"type": "number"},
87
+ },
88
+ },
89
+ "minItems": 2,
90
+ "maxItems": 2,
91
+ },
92
+ },
93
+ }
94
+
95
+ for _, tc := range cases {
96
+ actual := OpenApiV3Downgrader_downgrade_schema(collection, tc.input)
97
+ if openApiV3DowngraderTestJSON(t, actual) != openApiV3DowngraderTestJSON(t, tc.expected) {
98
+ t.Fatalf("%s: got %s, want %s", tc.label,
99
+ openApiV3DowngraderTestJSON(t, actual),
100
+ openApiV3DowngraderTestJSON(t, tc.expected))
101
+ }
102
+ serialized := openApiV3DowngraderTestJSON(t, actual)
103
+ for _, keyword := range []string{`"const"`, `"prefixItems"`, `"type":"null"`} {
104
+ if strings.Contains(serialized, keyword) {
105
+ t.Fatalf("%s: 3.1-only keyword %s leaked into 3.0 output: %s", tc.label, keyword, serialized)
106
+ }
107
+ }
108
+ }
109
+ }
110
+
111
+ // openApiV3DowngraderTestNumber is a named float64 type standing in for the
112
+ // compiler's `jsnum.Number`, so the test exercises the reflected-kind path
113
+ // rather than the plain `float64` a literal never actually carries.
114
+ type openApiV3DowngraderTestNumber float64
115
+
116
+ func openApiV3DowngraderTestJSON(t *testing.T, schema JsonSchema) string {
117
+ t.Helper()
118
+ bytes, err := json.Marshal(schema)
119
+ if err != nil {
120
+ t.Fatalf("marshal failed: %v", err)
121
+ }
122
+ return string(bytes)
123
+ }
@@ -141,10 +141,10 @@ func TestTemplateConstrainedCapture(t *testing.T) {
141
141
  //
142
142
  // 1. A leading literal plus a constrained number captures at index 1.
143
143
  // 2. `${n}-${n}` keeps both numbers ("-" is not number-extendable) at 1 and 2;
144
- // a string with a sibling absorbs the separator and falls back entirely.
144
+ // a string with a sibling absorbs the separator and has no direct capture.
145
145
  // 3. A sole constrained string lowers to `([\s\S]*)`, anchored.
146
146
  // 4. A constrained bigint lowers to the integer-only `([+-]?\d+)`, anchored.
147
- // 5. A constrained placeholder adjacent to a variable-width neighbor falls back.
147
+ // 5. An ambiguous placeholder has no direct capture; backtracking owns it.
148
148
  // 6. A template with no constrained placeholder yields no captures and the
149
149
  // historical pattern.
150
150
  func TestTemplateRuntimePattern(t *testing.T) {
@@ -169,10 +169,10 @@ func TestTemplateRuntimePattern(t *testing.T) {
169
169
  }
170
170
 
171
171
  // A string with a sibling absorbs the "-" (greedy `[\s\S]*`), unpinning both
172
- // itself and the number, so the whole template falls back to no captures.
172
+ // itself and the number, so the direct-capture path stays empty.
173
173
  _, captures = template_runtime_pattern([]*nativemetadata.MetadataSchema{str, iterateLiteral("-"), numberB})
174
174
  if len(captures) != 0 {
175
- t.Fatalf("string-with-sibling template must fall back, got %#v", captures)
175
+ t.Fatalf("string-with-sibling template must not capture directly, got %#v", captures)
176
176
  }
177
177
 
178
178
  // A constrained string captures every character (newlines included) via
@@ -197,15 +197,15 @@ func TestTemplateRuntimePattern(t *testing.T) {
197
197
 
198
198
  // A constrained placeholder adjacent to a variable-width neighbor (here an
199
199
  // unconstrained string before the number, with no literal between) is
200
- // ambiguous under greedy matching, so it falls back to structural-only
201
- // matching with no capture rather than risking a false negative.
200
+ // ambiguous under greedy matching, so it has no direct capture; the checker
201
+ // routes the template to existential backtracking instead.
202
202
  _, captures = template_runtime_pattern([]*nativemetadata.MetadataSchema{iterateAtomic("string"), number})
203
203
  if len(captures) != 0 {
204
204
  t.Fatalf("number adjacent to a variable-width neighbor must not be captured, got %#v", captures)
205
205
  }
206
206
  _, captures = template_runtime_pattern([]*nativemetadata.MetadataSchema{str, numberB})
207
207
  if len(captures) != 0 {
208
- t.Fatalf("two adjacent constrained placeholders must both fall back, got %#v", captures)
208
+ t.Fatalf("two adjacent constrained placeholders must not capture directly, got %#v", captures)
209
209
  }
210
210
 
211
211
  pattern, captures = template_runtime_pattern([]*nativemetadata.MetadataSchema{iterateLiteral("plain"), iterateAtomic("string")})
@@ -217,11 +217,43 @@ func TestTemplateRuntimePattern(t *testing.T) {
217
217
  }
218
218
  }
219
219
 
220
+ // TestTemplateRequiresBacktracking separates unique captures from ambiguous
221
+ // boundary searches and keeps each searched placeholder's standalone pattern
222
+ // faithful to its runtime base type.
223
+ func TestTemplateRequiresBacktracking(t *testing.T) {
224
+ number := iterateTemplateAtomic("number", [][]nativemetadata.IMetadataTypeTag{{{Name: "Minimum<10>", Validate: "10 <= $input"}}})
225
+ str := iterateTemplateAtomic("string", [][]nativemetadata.IMetadataTypeTag{{{Name: "MinLength<3>", Validate: "$input.length >= 3"}}})
226
+
227
+ cases := []struct {
228
+ name string
229
+ row []*nativemetadata.MetadataSchema
230
+ want bool
231
+ }{
232
+ {"unique suffix", []*nativemetadata.MetadataSchema{iterateLiteral("v"), number}, false},
233
+ {"adjacent placeholders", []*nativemetadata.MetadataSchema{iterateAtomic("string"), number}, true},
234
+ {"safe numeric fence", []*nativemetadata.MetadataSchema{number, iterateLiteral("-"), number}, false},
235
+ {"decimal fence", []*nativemetadata.MetadataSchema{number, iterateLiteral("."), iterateAtomic("number")}, true},
236
+ {"repeated string fence", []*nativemetadata.MetadataSchema{iterateAtomic("string"), iterateLiteral("X"), str}, true},
237
+ }
238
+ for _, tc := range cases {
239
+ if got := template_requires_backtracking(tc.row); got != tc.want {
240
+ t.Fatalf("template_requires_backtracking(%s) = %v, want %v", tc.name, got, tc.want)
241
+ }
242
+ }
243
+
244
+ if got := template_backtracking_pattern(str); got != "^[\\s\\S]*$" {
245
+ t.Fatalf("constrained string backtracking pattern = %q", got)
246
+ }
247
+ if got := template_backtracking_pattern(iterateAtomic("bigint")); got != "^[+-]?\\d+$" {
248
+ t.Fatalf("bigint backtracking pattern = %q", got)
249
+ }
250
+ }
251
+
220
252
  // TestTemplateClearBoundary gates capture on boundaries the greedy regex pins.
221
253
  //
222
254
  // A placeholder is captured only when, on each side, the template edge or a
223
255
  // literal whose first character its relevant variable neighbor cannot absorb
224
- // pins it; otherwise the split can slide and it falls back.
256
+ // pins it; otherwise the split can slide and requires backtracking.
225
257
  //
226
258
  // 1. A single literal segment is a boundary; an atomic, a multi-value constant,
227
259
  // and nil are not.
@@ -25,6 +25,17 @@ type templateCapture struct {
25
25
  Atomic *nativemetadata.MetadataAtomic
26
26
  }
27
27
 
28
+ // TemplateRuntimePattern returns the structural regular-expression pattern the
29
+ // runtime template checker uses for one template-literal row.
30
+ //
31
+ // Consumers that only need template membership can share the checker's exact
32
+ // pattern without duplicating its lowering. Runtime tag conditions remain owned
33
+ // by Check_template because they require the checker context and capture map.
34
+ func TemplateRuntimePattern(row []*nativemetadata.MetadataSchema) string {
35
+ pattern, _ := template_runtime_pattern(row)
36
+ return pattern
37
+ }
38
+
28
39
  // template_runtime_pattern builds the structural regex of a template literal for
29
40
  // the runtime checker and, alongside it, the capture map of every constrained
30
41
  // interpolation placeholder.
@@ -84,10 +95,47 @@ func template_runtime_pattern(row []*nativemetadata.MetadataSchema) (string, []t
84
95
  return nativeutils.PatternUtil.Fix(strings.Join(parts, "")), captures
85
96
  }
86
97
 
98
+ // template_requires_backtracking reports whether a constrained placeholder has
99
+ // an ambiguous boundary. Such a template cannot validate tags from the single
100
+ // greedy capture selected by RegExp.exec; the checker must instead search the
101
+ // possible placeholder boundaries and accept when any complete split satisfies
102
+ // every structural and tag predicate.
103
+ func template_requires_backtracking(row []*nativemetadata.MetadataSchema) bool {
104
+ for i, meta := range row {
105
+ if _, _, ok := template_constrained_capture(meta); ok && template_clear_boundary(row, i) == false {
106
+ return true
107
+ }
108
+ }
109
+ return false
110
+ }
111
+
112
+ // template_backtracking_pattern is the whole-substring structural predicate
113
+ // used for one placeholder during existential boundary search. Constrained
114
+ // string and bigint placeholders retain the runtime capture semantics from
115
+ // template_runtime_pattern: strings include newlines and bigints are integers.
116
+ func template_backtracking_pattern(meta *nativemetadata.MetadataSchema) string {
117
+ sub := metadata_to_pattern(struct {
118
+ top bool
119
+ metadata *nativemetadata.MetadataSchema
120
+ }{
121
+ top: false,
122
+ metadata: meta,
123
+ })
124
+ if meta != nil && meta.Bucket() == 1 && len(meta.Atomics) == 1 && meta.Atomics[0].Type == "bigint" {
125
+ sub = "[+-]?\\d+"
126
+ } else if _, kind, ok := template_constrained_capture(meta); ok {
127
+ switch kind {
128
+ case "string":
129
+ sub = "[\\s\\S]*"
130
+ }
131
+ }
132
+ return nativeutils.PatternUtil.Fix(sub)
133
+ }
134
+
87
135
  // template_clear_boundary reports whether the placeholder at row[i] is delimited
88
136
  // strongly enough that the greedy structural regex assigns it a unique — hence
89
- // correct — substring. An ambiguous placeholder falls back to structural-only
90
- // matching (tag unenforced, as before) rather than risking a false negative.
137
+ // correct — substring. Ambiguous placeholders skip direct capture and are
138
+ // validated by the existential matcher in check_template_backtracking.
91
139
  //
92
140
  // Two adjacent variable-width placeholders slide their shared boundary iff the
93
141
  // left one can extend over the first character of the literal between them: a
@@ -100,9 +148,9 @@ func template_runtime_pattern(row []*nativemetadata.MetadataSchema) (string, []t
100
148
  // - `${n}-${n}` (#1965): "-" is not in a number's right-extension set, so both
101
149
  // numbers are pinned and enforced.
102
150
  // - `${number}.${number}` / IP grids: "." extends a number (decimal), so the
103
- // split slides ("5.9.1.1.1" splits as 5.9|… or 5|9.1|…) — fall back.
151
+ // split slides ("5.9.1.1.1" splits as 5.9|… or 5|9.1|…) — backtrack.
104
152
  // - `${string}-${number}` / `${string}X${string}`: a string absorbs any
105
- // character, so a string with any sibling falls back.
153
+ // character, so a string with any sibling needs backtracking.
106
154
  // - `a${string}b` / `prefix${string}suffix` / `${number}%` / `CODE-${string}`:
107
155
  // sole placeholder, the `^`/`$` anchors pin both ends — enforced.
108
156
  func template_clear_boundary(row []*nativemetadata.MetadataSchema, i int) bool {
@@ -141,7 +189,7 @@ func template_boundary_safe(row []*nativemetadata.MetadataSchema, i int, dir int
141
189
 
142
190
  // template_variable_kind returns the base type a variable placeholder matches:
143
191
  // "number", "bigint", or "string". Anything else (boolean, unions, constants)
144
- // is treated as "string" — conservatively absorbing, so its neighbor falls back.
192
+ // is treated as "string" — conservatively absorbing, so its neighbor backtracks.
145
193
  func template_variable_kind(meta *nativemetadata.MetadataSchema) string {
146
194
  if meta != nil && meta.Bucket() == 1 && len(meta.Atomics) == 1 {
147
195
  switch meta.Atomics[0].Type {
@@ -171,16 +219,24 @@ func template_right_extends(kind string, ch rune) bool {
171
219
 
172
220
  // template_literal_first returns the first character of a literal segment's text.
173
221
  func template_literal_first(meta *nativemetadata.MetadataSchema) (rune, bool) {
174
- if meta == nil || len(meta.Constants) == 0 || len(meta.Constants[0].Values) == 0 {
222
+ value, ok := template_literal_value(meta)
223
+ if ok == false {
175
224
  return 0, false
176
225
  }
177
- runes := []rune(fmt.Sprint(meta.Constants[0].Values[0].Value))
226
+ runes := []rune(value)
178
227
  if len(runes) == 0 {
179
228
  return 0, false
180
229
  }
181
230
  return runes[0], true
182
231
  }
183
232
 
233
+ func template_literal_value(meta *nativemetadata.MetadataSchema) (string, bool) {
234
+ if template_is_literal(meta) == false || len(meta.Constants) == 0 || len(meta.Constants[0].Values) == 0 {
235
+ return "", false
236
+ }
237
+ return fmt.Sprint(meta.Constants[0].Values[0].Value), true
238
+ }
239
+
184
240
  // template_is_literal reports whether a row element is a single fixed literal
185
241
  // segment (exactly one constant value), i.e. a fixed-width boundary between
186
242
  // placeholders.
@@ -51,19 +51,31 @@ func (jsonApplicationProgrammerNamespace) Validate(props struct {
51
51
  }
52
52
  least := false
53
53
  for _, p := range object.Properties {
54
- value := p.Value
54
+ // Resolve the function through any `type` alias exactly as
55
+ // WriteApplication does, so an aliased function is recognized as a
56
+ // function property here too. Otherwise `p.Value.Functions` is empty for
57
+ // an aliased member and every check below is skipped, letting
58
+ // WriteApplication silently drop the malformed function (issue #2216,
59
+ // reopening #2195 for aliased members).
60
+ value := jsonApplicationProgrammer_unaliasFunctions(p.Value)
55
61
  if len(value.Functions) != 0 {
56
62
  least = true
57
- if valid == false {
58
- if len(value.Functions) != 1 || value.Size() != 1 {
59
- output = append(output, "JSON application's function type does not allow union type.")
60
- }
61
- if value.IsRequired() == false {
62
- output = append(output, "JSON application's function type must be required.")
63
- }
64
- if value.Nullable == true {
65
- output = append(output, "JSON application's function type must not be nullable.")
66
- }
63
+ // These per-function shape checks must run for every function
64
+ // property, independent of the top-level `valid`: otherwise a
65
+ // malformed function (union/optional/nullable) is silently dropped by
66
+ // WriteApplication with no diagnostic at all (issue #2195). The union
67
+ // shape comes from the unaliased value, while the reference-site
68
+ // optional/nullable modifiers stay on the raw property value: an
69
+ // optional or nullable alias is not unwrapped by MetadataSchema_unalias,
70
+ // so those two checks must read `p.Value`, not the unaliased schema.
71
+ if len(value.Functions) != 1 || value.Size() != 1 {
72
+ output = append(output, "JSON application's function type does not allow union type.")
73
+ }
74
+ if p.Value.IsRequired() == false {
75
+ output = append(output, "JSON application's function type must be required.")
76
+ }
77
+ if p.Value.Nullable == true {
78
+ output = append(output, "JSON application's function type must not be nullable.")
67
79
  }
68
80
  }
69
81
  }
@@ -370,6 +382,28 @@ func jsonApplicationProgrammer_descriptionFromParam(tags []nativemetadata.IJsDoc
370
382
  return &text
371
383
  }
372
384
 
385
+ // jsonApplicationProgrammer_unaliasFunctions resolves the metadata schema whose
386
+ // `Functions` decide whether a property is a function slot and how that function
387
+ // is shaped. WriteApplication reads `len(MetadataSchema_unalias(value).Functions)`
388
+ // for the same decision, but MetadataSchema_unalias preserves a reference-site
389
+ // optional or nullable modifier and so stops before an optional/nullable alias.
390
+ // This peels a pure single-alias chain past those modifiers too (guarded by
391
+ // Size == 1 so a union stays visible), so an aliased function that is optional,
392
+ // nullable, or a union of functions is still recognized and reported instead of
393
+ // being silently dropped (issue #2216). A non-function alias resolves to a
394
+ // schema with no functions and is therefore ignored, exactly as before.
395
+ func jsonApplicationProgrammer_unaliasFunctions(value *nativemetadata.MetadataSchema) *nativemetadata.MetadataSchema {
396
+ visited := map[*nativemetadata.MetadataSchema]struct{}{}
397
+ for len(value.Functions) == 0 && len(value.Aliases) == 1 && value.Size() == 1 {
398
+ if _, ok := visited[value]; ok {
399
+ break
400
+ }
401
+ visited[value] = struct{}{}
402
+ value = value.Aliases[0].Type.Value
403
+ }
404
+ return value
405
+ }
406
+
373
407
  func jsonApplicationProgrammer_hidden(tags []nativemetadata.IJsDocTagInfo) bool {
374
408
  for _, tag := range tags {
375
409
  if tag.Name == "hidden" || tag.Name == "ignore" || tag.Name == "internal" {
@@ -102,12 +102,22 @@ func (jsonSchemasProgrammerNamespace) WriteSchemas(props struct {
102
102
  return jsonSchemasProgrammer_writeV3_1(props.Metadatas)
103
103
  }
104
104
 
105
+ // jsonSchemasProgrammer_writeV3_0 builds the emended 3.1 document and rewrites
106
+ // it into the OpenAPI 3.0 dialect. The version string is a claim about the
107
+ // content, so relabeling the 3.1 document alone would emit `const`,
108
+ // `prefixItems`, and 3.1 nullable type unions under a "3.0" banner that no
109
+ // conformant 3.0 consumer can read.
105
110
  func jsonSchemasProgrammer_writeV3_0(metadataList []*nativemetadata.MetadataSchema) JsonSchemasProgrammer_IJsonSchemaCollection {
106
111
  collection := jsonSchemasProgrammer_writeV3_1(metadataList)
112
+ downgrader := nativeiterate.OpenApiV3Downgrader_downgrade_components(collection.Components)
113
+ schemas := make([]nativeiterate.JsonSchema, 0, len(collection.Schemas))
114
+ for _, schema := range collection.Schemas {
115
+ schemas = append(schemas, nativeiterate.OpenApiV3Downgrader_downgrade_schema(downgrader, schema))
116
+ }
107
117
  return JsonSchemasProgrammer_IJsonSchemaCollection{
108
118
  Version: "3.0",
109
- Components: collection.Components,
110
- Schemas: collection.Schemas,
119
+ Components: downgrader.Downgraded,
120
+ Schemas: schemas,
111
121
  }
112
122
  }
113
123
 
@@ -278,7 +278,34 @@ func jsonStringifyProgrammer_decode(props struct {
278
278
  Value: func() *shimast.Node {
279
279
  next := props
280
280
  next.Metadata = metadata
281
- return jsonStringifyProgrammer_decode_to_json(next)
281
+ resolved := jsonStringifyProgrammer_decode_to_json(next)
282
+ if isDate {
283
+ return resolved
284
+ }
285
+ // The arm's own test is `typeof input.toJSON === "function"`, but an arm
286
+ // test is not always emitted — a sole arm needs no choice, and a final
287
+ // arm is the else — while this value *calls* `toJSON`. Leaving the call
288
+ // to be guarded by the arm meant a value whose `toJSON` is not callable
289
+ // threw `input.toJSON is not a function` from inside the serializer,
290
+ // including under `isStringify` and `validateStringify`, whose contract
291
+ // is to answer rather than throw (samchon/typia#2271).
292
+ //
293
+ // The guard therefore belongs to the call. `JSON.stringify` ignores a
294
+ // non-callable `toJSON` and serializes the object itself, and the
295
+ // metadata already carries that shape, so the fallback describes the
296
+ // original rather than inventing an answer. `Date` keeps the plain form:
297
+ // its arm is `instanceof Date`, and a real Date's `toJSON` is callable.
298
+ original := props
299
+ original.Metadata = props.Metadata.Escaped.Original
300
+ return nativefactories.ExpressionFactory.Conditional(
301
+ nativeprogrammers.IsProgrammer.Decode_to_json(struct {
302
+ Input *shimast.Expression
303
+ CheckNull bool
304
+ }{Input: props.Input, CheckNull: false}),
305
+ resolved,
306
+ jsonStringifyProgrammer_decode(original),
307
+ props.Context.Emit,
308
+ )
282
309
  },
283
310
  })
284
311
  } else if len(props.Metadata.Functions) != 0 {
@@ -697,9 +724,10 @@ func jsonStringifyProgrammer_decode_array_inline(props jsonStringifyProgrammer_d
697
724
  Arrow *shimast.Node
698
725
  }) *shimast.Node {
699
726
  return nativehelpers.StringifyJoiner.Array(nativehelpers.StringifyJoiner_ArrayProps{
700
- Input: next.Input,
701
- Arrow: next.Arrow,
702
- Emit: props.Context.Emit,
727
+ Context: props.Context,
728
+ Input: next.Input,
729
+ Arrow: next.Arrow,
730
+ Emit: props.Context.Emit,
703
731
  })
704
732
  },
705
733
  Array: props.Array,
@@ -772,7 +800,7 @@ func jsonStringifyProgrammer_decode_tuple_inline(props jsonStringifyProgrammer_d
772
800
  } else {
773
801
  explore.Postfix = fmt.Sprintf("\"[%d]\"", index)
774
802
  }
775
- elements = append(elements, jsonStringifyProgrammer_decode(struct {
803
+ code := jsonStringifyProgrammer_decode(struct {
776
804
  Context nativecontext.ITypiaContext
777
805
  Config nativeinternal.FeatureProgrammer_IConfig
778
806
  Functor *nativehelpers.FunctionProgrammer
@@ -788,7 +816,20 @@ func jsonStringifyProgrammer_decode_tuple_inline(props jsonStringifyProgrammer_d
788
816
  Metadata: elem,
789
817
  Explore: explore,
790
818
  Validated: props.Validated,
791
- }))
819
+ })
820
+ if nativehelpers.StringifyJoiner_ResultUndefinable(elem) {
821
+ // A tuple slot holds its position, so an element that serializes to
822
+ // nothing is `null` rather than omitted; without this its text was the
823
+ // literal `undefined` (#2253).
824
+ code = f.NewCallExpression(
825
+ jsonStringifyProgrammer_internal(props.Context, "jsonStringifyElement"),
826
+ nil,
827
+ nil,
828
+ f.NewNodeList([]*shimast.Node{code}),
829
+ shimast.NodeFlagsNone,
830
+ )
831
+ }
832
+ elements = append(elements, code)
792
833
  }
793
834
  var rest *shimast.Node
794
835
  if len(props.Tuple.Elements) != 0 {
@@ -139,16 +139,18 @@ func (llmApplicationProgrammerNamespace) Validate(props struct {
139
139
  }
140
140
  least = true
141
141
  name := fmt.Sprintf("%q", *rawName)
142
- if isValidType == false {
143
- if len(value.Functions) != 1 || value.Size() != 1 {
144
- output = append(output, "LLM application's function ("+name+") type does not allow union type.")
145
- }
146
- if value.IsRequired() == false {
147
- output = append(output, "LLM application's function ("+name+") type must be required.")
148
- }
149
- if value.Nullable {
150
- output = append(output, "LLM application's function ("+name+") type must not be nullable.")
151
- }
142
+ // These per-function shape checks must run for every function property,
143
+ // independent of the top-level `isValidType`: otherwise a malformed
144
+ // function (union/optional/nullable) is silently dropped by
145
+ // WriteApplication with no diagnostic at all (issue #2195).
146
+ if len(value.Functions) != 1 || value.Size() != 1 {
147
+ output = append(output, "LLM application's function ("+name+") type does not allow union type.")
148
+ }
149
+ if value.IsRequired() == false {
150
+ output = append(output, "LLM application's function ("+name+") type must be required.")
151
+ }
152
+ if value.Nullable {
153
+ output = append(output, "LLM application's function ("+name+") type must not be nullable.")
152
154
  }
153
155
  prefix := "LLM application's function (" + name + ")"
154
156
  output = append(output, llmApplicationProgrammer_validateName(prefix, *rawName)...)
@@ -238,7 +240,15 @@ func (llmApplicationProgrammerNamespace) WriteApplication(props struct {
238
240
  functions = append(functions, written)
239
241
  }
240
242
  }
241
- result := map[string]any{"functions": functions}
243
+ // The call site's schema configuration is resolved here and nowhere else, so
244
+ // it travels with the emitted application; the runtime finalizer only adds
245
+ // the validate hook to it. Rebuilding it at runtime reported `strict: false`
246
+ // for a strict build (issue #2293).
247
+ strict, _ := props.Config["strict"].(bool)
248
+ result := map[string]any{
249
+ "config": map[string]any{"strict": strict},
250
+ "functions": functions,
251
+ }
242
252
  if len(metadata.Objects) != 0 {
243
253
  if object := metadata.Objects[0].Type; object != nil {
244
254
  if description := llmApplicationProgrammer_describe(object.Description, object.JsDocTags); description != nil && len(*description) != 0 {