@typia/utils 12.0.0-dev.20260225

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 (471) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/lib/converters/LlmSchemaConverter.d.ts +102 -0
  4. package/lib/converters/LlmSchemaConverter.js +652 -0
  5. package/lib/converters/LlmSchemaConverter.js.map +1 -0
  6. package/lib/converters/LlmSchemaConverter.mjs +771 -0
  7. package/lib/converters/LlmSchemaConverter.mjs.map +1 -0
  8. package/lib/converters/OpenApiConverter.d.ts +135 -0
  9. package/lib/converters/OpenApiConverter.js +130 -0
  10. package/lib/converters/OpenApiConverter.js.map +1 -0
  11. package/lib/converters/OpenApiConverter.mjs +128 -0
  12. package/lib/converters/OpenApiConverter.mjs.map +1 -0
  13. package/lib/converters/index.d.ts +2 -0
  14. package/lib/converters/index.js +21 -0
  15. package/lib/converters/index.js.map +1 -0
  16. package/lib/converters/index.mjs +4 -0
  17. package/lib/converters/index.mjs.map +1 -0
  18. package/lib/converters/internal/LlmDescriptionInverter.d.ts +6 -0
  19. package/lib/converters/internal/LlmDescriptionInverter.js +141 -0
  20. package/lib/converters/internal/LlmDescriptionInverter.js.map +1 -0
  21. package/lib/converters/internal/LlmDescriptionInverter.mjs +141 -0
  22. package/lib/converters/internal/LlmDescriptionInverter.mjs.map +1 -0
  23. package/lib/converters/internal/LlmParametersComposer.d.ts +1 -0
  24. package/lib/converters/internal/LlmParametersComposer.js +39 -0
  25. package/lib/converters/internal/LlmParametersComposer.js.map +1 -0
  26. package/lib/converters/internal/LlmParametersComposer.mjs +42 -0
  27. package/lib/converters/internal/LlmParametersComposer.mjs.map +1 -0
  28. package/lib/converters/internal/OpenApiConstraintShifter.d.ts +6 -0
  29. package/lib/converters/internal/OpenApiConstraintShifter.js +103 -0
  30. package/lib/converters/internal/OpenApiConstraintShifter.js.map +1 -0
  31. package/lib/converters/internal/OpenApiConstraintShifter.mjs +102 -0
  32. package/lib/converters/internal/OpenApiConstraintShifter.mjs.map +1 -0
  33. package/lib/converters/internal/OpenApiExclusiveEmender.d.ts +4 -0
  34. package/lib/converters/internal/OpenApiExclusiveEmender.js +32 -0
  35. package/lib/converters/internal/OpenApiExclusiveEmender.js.map +1 -0
  36. package/lib/converters/internal/OpenApiExclusiveEmender.mjs +35 -0
  37. package/lib/converters/internal/OpenApiExclusiveEmender.mjs.map +1 -0
  38. package/lib/converters/internal/OpenApiV3Downgrader.d.ts +10 -0
  39. package/lib/converters/internal/OpenApiV3Downgrader.js +214 -0
  40. package/lib/converters/internal/OpenApiV3Downgrader.js.map +1 -0
  41. package/lib/converters/internal/OpenApiV3Downgrader.mjs +279 -0
  42. package/lib/converters/internal/OpenApiV3Downgrader.mjs.map +1 -0
  43. package/lib/converters/internal/OpenApiV3Upgrader.d.ts +6 -0
  44. package/lib/converters/internal/OpenApiV3Upgrader.js +285 -0
  45. package/lib/converters/internal/OpenApiV3Upgrader.js.map +1 -0
  46. package/lib/converters/internal/OpenApiV3Upgrader.mjs +349 -0
  47. package/lib/converters/internal/OpenApiV3Upgrader.mjs.map +1 -0
  48. package/lib/converters/internal/OpenApiV3_1Upgrader.d.ts +6 -0
  49. package/lib/converters/internal/OpenApiV3_1Upgrader.js +405 -0
  50. package/lib/converters/internal/OpenApiV3_1Upgrader.js.map +1 -0
  51. package/lib/converters/internal/OpenApiV3_1Upgrader.mjs +545 -0
  52. package/lib/converters/internal/OpenApiV3_1Upgrader.mjs.map +1 -0
  53. package/lib/converters/internal/SwaggerV2Downgrader.d.ts +10 -0
  54. package/lib/converters/internal/SwaggerV2Downgrader.js +294 -0
  55. package/lib/converters/internal/SwaggerV2Downgrader.js.map +1 -0
  56. package/lib/converters/internal/SwaggerV2Downgrader.mjs +332 -0
  57. package/lib/converters/internal/SwaggerV2Downgrader.mjs.map +1 -0
  58. package/lib/converters/internal/SwaggerV2Upgrader.d.ts +6 -0
  59. package/lib/converters/internal/SwaggerV2Upgrader.js +357 -0
  60. package/lib/converters/internal/SwaggerV2Upgrader.js.map +1 -0
  61. package/lib/converters/internal/SwaggerV2Upgrader.mjs +403 -0
  62. package/lib/converters/internal/SwaggerV2Upgrader.mjs.map +1 -0
  63. package/lib/http/HttpError.d.ts +61 -0
  64. package/lib/http/HttpError.js +70 -0
  65. package/lib/http/HttpError.js.map +1 -0
  66. package/lib/http/HttpError.mjs +76 -0
  67. package/lib/http/HttpError.mjs.map +1 -0
  68. package/lib/http/HttpLlm.d.ts +130 -0
  69. package/lib/http/HttpLlm.js +124 -0
  70. package/lib/http/HttpLlm.js.map +1 -0
  71. package/lib/http/HttpLlm.mjs +123 -0
  72. package/lib/http/HttpLlm.mjs.map +1 -0
  73. package/lib/http/HttpMigration.d.ts +58 -0
  74. package/lib/http/HttpMigration.js +52 -0
  75. package/lib/http/HttpMigration.js.map +1 -0
  76. package/lib/http/HttpMigration.mjs +52 -0
  77. package/lib/http/HttpMigration.mjs.map +1 -0
  78. package/lib/http/index.d.ts +3 -0
  79. package/lib/http/index.js +20 -0
  80. package/lib/http/index.js.map +1 -0
  81. package/lib/http/index.mjs +4 -0
  82. package/lib/http/index.mjs.map +1 -0
  83. package/lib/http/internal/HttpLlmApplicationComposer.d.ts +8 -0
  84. package/lib/http/internal/HttpLlmApplicationComposer.js +254 -0
  85. package/lib/http/internal/HttpLlmApplicationComposer.js.map +1 -0
  86. package/lib/http/internal/HttpLlmApplicationComposer.mjs +256 -0
  87. package/lib/http/internal/HttpLlmApplicationComposer.mjs.map +1 -0
  88. package/lib/http/internal/HttpLlmFunctionFetcher.d.ts +6 -0
  89. package/lib/http/internal/HttpLlmFunctionFetcher.js +24 -0
  90. package/lib/http/internal/HttpLlmFunctionFetcher.js.map +1 -0
  91. package/lib/http/internal/HttpLlmFunctionFetcher.mjs +24 -0
  92. package/lib/http/internal/HttpLlmFunctionFetcher.mjs.map +1 -0
  93. package/lib/http/internal/HttpMigrateApplicationComposer.d.ts +4 -0
  94. package/lib/http/internal/HttpMigrateApplicationComposer.js +45 -0
  95. package/lib/http/internal/HttpMigrateApplicationComposer.js.map +1 -0
  96. package/lib/http/internal/HttpMigrateApplicationComposer.mjs +47 -0
  97. package/lib/http/internal/HttpMigrateApplicationComposer.mjs.map +1 -0
  98. package/lib/http/internal/HttpMigrateRouteAccessor.d.ts +4 -0
  99. package/lib/http/internal/HttpMigrateRouteAccessor.js +107 -0
  100. package/lib/http/internal/HttpMigrateRouteAccessor.js.map +1 -0
  101. package/lib/http/internal/HttpMigrateRouteAccessor.mjs +106 -0
  102. package/lib/http/internal/HttpMigrateRouteAccessor.mjs.map +1 -0
  103. package/lib/http/internal/HttpMigrateRouteComposer.d.ts +11 -0
  104. package/lib/http/internal/HttpMigrateRouteComposer.js +398 -0
  105. package/lib/http/internal/HttpMigrateRouteComposer.js.map +1 -0
  106. package/lib/http/internal/HttpMigrateRouteComposer.mjs +392 -0
  107. package/lib/http/internal/HttpMigrateRouteComposer.mjs.map +1 -0
  108. package/lib/http/internal/HttpMigrateRouteFetcher.d.ts +6 -0
  109. package/lib/http/internal/HttpMigrateRouteFetcher.js +179 -0
  110. package/lib/http/internal/HttpMigrateRouteFetcher.js.map +1 -0
  111. package/lib/http/internal/HttpMigrateRouteFetcher.mjs +174 -0
  112. package/lib/http/internal/HttpMigrateRouteFetcher.mjs.map +1 -0
  113. package/lib/http/internal/LlmDataMerger.d.ts +48 -0
  114. package/lib/http/internal/LlmDataMerger.js +60 -0
  115. package/lib/http/internal/LlmDataMerger.js.map +1 -0
  116. package/lib/http/internal/LlmDataMerger.mjs +59 -0
  117. package/lib/http/internal/LlmDataMerger.mjs.map +1 -0
  118. package/lib/index.d.ts +4 -0
  119. package/lib/index.js +21 -0
  120. package/lib/index.js.map +1 -0
  121. package/lib/index.mjs +20 -0
  122. package/lib/index.mjs.map +1 -0
  123. package/lib/utils/ArrayUtil.d.ts +1 -0
  124. package/lib/utils/ArrayUtil.js +29 -0
  125. package/lib/utils/ArrayUtil.js.map +1 -0
  126. package/lib/utils/ArrayUtil.mjs +28 -0
  127. package/lib/utils/ArrayUtil.mjs.map +1 -0
  128. package/lib/utils/MapUtil.d.ts +1 -0
  129. package/lib/utils/MapUtil.js +16 -0
  130. package/lib/utils/MapUtil.js.map +1 -0
  131. package/lib/utils/MapUtil.mjs +15 -0
  132. package/lib/utils/MapUtil.mjs.map +1 -0
  133. package/lib/utils/NamingConvention.d.ts +68 -0
  134. package/lib/utils/NamingConvention.js +199 -0
  135. package/lib/utils/NamingConvention.js.map +1 -0
  136. package/lib/utils/NamingConvention.mjs +198 -0
  137. package/lib/utils/NamingConvention.mjs.map +1 -0
  138. package/lib/utils/Singleton.d.ts +1 -0
  139. package/lib/utils/Singleton.js +18 -0
  140. package/lib/utils/Singleton.js.map +1 -0
  141. package/lib/utils/Singleton.mjs +18 -0
  142. package/lib/utils/Singleton.mjs.map +1 -0
  143. package/lib/utils/StringUtil.d.ts +1 -0
  144. package/lib/utils/StringUtil.js +17 -0
  145. package/lib/utils/StringUtil.js.map +1 -0
  146. package/lib/utils/StringUtil.mjs +13 -0
  147. package/lib/utils/StringUtil.mjs.map +1 -0
  148. package/lib/utils/dedent.d.ts +12 -0
  149. package/lib/utils/dedent.js +51 -0
  150. package/lib/utils/dedent.js.map +1 -0
  151. package/lib/utils/dedent.mjs +50 -0
  152. package/lib/utils/dedent.mjs.map +1 -0
  153. package/lib/utils/index.d.ts +7 -0
  154. package/lib/utils/index.js +24 -0
  155. package/lib/utils/index.js.map +1 -0
  156. package/lib/utils/index.mjs +8 -0
  157. package/lib/utils/index.mjs.map +1 -0
  158. package/lib/utils/internal/EndpointUtil.d.ts +8 -0
  159. package/lib/utils/internal/EndpointUtil.js +37 -0
  160. package/lib/utils/internal/EndpointUtil.js.map +1 -0
  161. package/lib/utils/internal/EndpointUtil.mjs +37 -0
  162. package/lib/utils/internal/EndpointUtil.mjs.map +1 -0
  163. package/lib/utils/internal/JsonDescriptor.d.ts +10 -0
  164. package/lib/utils/internal/JsonDescriptor.js +58 -0
  165. package/lib/utils/internal/JsonDescriptor.js.map +1 -0
  166. package/lib/utils/internal/JsonDescriptor.mjs +48 -0
  167. package/lib/utils/internal/JsonDescriptor.mjs.map +1 -0
  168. package/lib/utils/internal/OpenApiTypeCheckerBase.d.ts +1 -0
  169. package/lib/utils/internal/OpenApiTypeCheckerBase.js +520 -0
  170. package/lib/utils/internal/OpenApiTypeCheckerBase.js.map +1 -0
  171. package/lib/utils/internal/OpenApiTypeCheckerBase.mjs +584 -0
  172. package/lib/utils/internal/OpenApiTypeCheckerBase.mjs.map +1 -0
  173. package/lib/utils/stringifyValidationFailure.d.ts +25 -0
  174. package/lib/utils/stringifyValidationFailure.js +326 -0
  175. package/lib/utils/stringifyValidationFailure.js.map +1 -0
  176. package/lib/utils/stringifyValidationFailure.mjs +325 -0
  177. package/lib/utils/stringifyValidationFailure.mjs.map +1 -0
  178. package/lib/validators/LlmTypeChecker.d.ts +117 -0
  179. package/lib/validators/LlmTypeChecker.js +309 -0
  180. package/lib/validators/LlmTypeChecker.js.map +1 -0
  181. package/lib/validators/LlmTypeChecker.mjs +300 -0
  182. package/lib/validators/LlmTypeChecker.mjs.map +1 -0
  183. package/lib/validators/OpenApiTypeChecker.d.ts +211 -0
  184. package/lib/validators/OpenApiTypeChecker.js +207 -0
  185. package/lib/validators/OpenApiTypeChecker.js.map +1 -0
  186. package/lib/validators/OpenApiTypeChecker.mjs +218 -0
  187. package/lib/validators/OpenApiTypeChecker.mjs.map +1 -0
  188. package/lib/validators/OpenApiV3TypeChecker.d.ts +26 -0
  189. package/lib/validators/OpenApiV3TypeChecker.js +30 -0
  190. package/lib/validators/OpenApiV3TypeChecker.js.map +1 -0
  191. package/lib/validators/OpenApiV3TypeChecker.mjs +29 -0
  192. package/lib/validators/OpenApiV3TypeChecker.mjs.map +1 -0
  193. package/lib/validators/OpenApiV3_1TypeChecker.d.ts +29 -0
  194. package/lib/validators/OpenApiV3_1TypeChecker.js +34 -0
  195. package/lib/validators/OpenApiV3_1TypeChecker.js.map +1 -0
  196. package/lib/validators/OpenApiV3_1TypeChecker.mjs +33 -0
  197. package/lib/validators/OpenApiV3_1TypeChecker.mjs.map +1 -0
  198. package/lib/validators/OpenApiValidator.d.ts +36 -0
  199. package/lib/validators/OpenApiValidator.js +71 -0
  200. package/lib/validators/OpenApiValidator.js.map +1 -0
  201. package/lib/validators/OpenApiValidator.mjs +75 -0
  202. package/lib/validators/OpenApiValidator.mjs.map +1 -0
  203. package/lib/validators/SwaggerV2TypeChecker.d.ts +27 -0
  204. package/lib/validators/SwaggerV2TypeChecker.js +31 -0
  205. package/lib/validators/SwaggerV2TypeChecker.js.map +1 -0
  206. package/lib/validators/SwaggerV2TypeChecker.mjs +30 -0
  207. package/lib/validators/SwaggerV2TypeChecker.mjs.map +1 -0
  208. package/lib/validators/functional/_isBigintString.d.ts +1 -0
  209. package/lib/validators/functional/_isBigintString.js +14 -0
  210. package/lib/validators/functional/_isBigintString.js.map +1 -0
  211. package/lib/validators/functional/_isBigintString.mjs +12 -0
  212. package/lib/validators/functional/_isBigintString.mjs.map +1 -0
  213. package/lib/validators/functional/_isFormatByte.d.ts +1 -0
  214. package/lib/validators/functional/_isFormatByte.js +10 -0
  215. package/lib/validators/functional/_isFormatByte.js.map +1 -0
  216. package/lib/validators/functional/_isFormatByte.mjs +8 -0
  217. package/lib/validators/functional/_isFormatByte.mjs.map +1 -0
  218. package/lib/validators/functional/_isFormatDate.d.ts +1 -0
  219. package/lib/validators/functional/_isFormatDate.js +7 -0
  220. package/lib/validators/functional/_isFormatDate.js.map +1 -0
  221. package/lib/validators/functional/_isFormatDate.mjs +5 -0
  222. package/lib/validators/functional/_isFormatDate.mjs.map +1 -0
  223. package/lib/validators/functional/_isFormatDateTime.d.ts +1 -0
  224. package/lib/validators/functional/_isFormatDateTime.js +7 -0
  225. package/lib/validators/functional/_isFormatDateTime.js.map +1 -0
  226. package/lib/validators/functional/_isFormatDateTime.mjs +5 -0
  227. package/lib/validators/functional/_isFormatDateTime.mjs.map +1 -0
  228. package/lib/validators/functional/_isFormatDuration.d.ts +1 -0
  229. package/lib/validators/functional/_isFormatDuration.js +7 -0
  230. package/lib/validators/functional/_isFormatDuration.js.map +1 -0
  231. package/lib/validators/functional/_isFormatDuration.mjs +5 -0
  232. package/lib/validators/functional/_isFormatDuration.mjs.map +1 -0
  233. package/lib/validators/functional/_isFormatEmail.d.ts +1 -0
  234. package/lib/validators/functional/_isFormatEmail.js +7 -0
  235. package/lib/validators/functional/_isFormatEmail.js.map +1 -0
  236. package/lib/validators/functional/_isFormatEmail.mjs +5 -0
  237. package/lib/validators/functional/_isFormatEmail.mjs.map +1 -0
  238. package/lib/validators/functional/_isFormatHostname.d.ts +1 -0
  239. package/lib/validators/functional/_isFormatHostname.js +7 -0
  240. package/lib/validators/functional/_isFormatHostname.js.map +1 -0
  241. package/lib/validators/functional/_isFormatHostname.mjs +5 -0
  242. package/lib/validators/functional/_isFormatHostname.mjs.map +1 -0
  243. package/lib/validators/functional/_isFormatIdnEmail.d.ts +1 -0
  244. package/lib/validators/functional/_isFormatIdnEmail.js +7 -0
  245. package/lib/validators/functional/_isFormatIdnEmail.js.map +1 -0
  246. package/lib/validators/functional/_isFormatIdnEmail.mjs +5 -0
  247. package/lib/validators/functional/_isFormatIdnEmail.mjs.map +1 -0
  248. package/lib/validators/functional/_isFormatIdnHostname.d.ts +1 -0
  249. package/lib/validators/functional/_isFormatIdnHostname.js +7 -0
  250. package/lib/validators/functional/_isFormatIdnHostname.js.map +1 -0
  251. package/lib/validators/functional/_isFormatIdnHostname.mjs +5 -0
  252. package/lib/validators/functional/_isFormatIdnHostname.mjs.map +1 -0
  253. package/lib/validators/functional/_isFormatIpv4.d.ts +1 -0
  254. package/lib/validators/functional/_isFormatIpv4.js +7 -0
  255. package/lib/validators/functional/_isFormatIpv4.js.map +1 -0
  256. package/lib/validators/functional/_isFormatIpv4.mjs +5 -0
  257. package/lib/validators/functional/_isFormatIpv4.mjs.map +1 -0
  258. package/lib/validators/functional/_isFormatIpv6.d.ts +1 -0
  259. package/lib/validators/functional/_isFormatIpv6.js +7 -0
  260. package/lib/validators/functional/_isFormatIpv6.js.map +1 -0
  261. package/lib/validators/functional/_isFormatIpv6.mjs +5 -0
  262. package/lib/validators/functional/_isFormatIpv6.mjs.map +1 -0
  263. package/lib/validators/functional/_isFormatIri.d.ts +1 -0
  264. package/lib/validators/functional/_isFormatIri.js +7 -0
  265. package/lib/validators/functional/_isFormatIri.js.map +1 -0
  266. package/lib/validators/functional/_isFormatIri.mjs +5 -0
  267. package/lib/validators/functional/_isFormatIri.mjs.map +1 -0
  268. package/lib/validators/functional/_isFormatIriReference.d.ts +1 -0
  269. package/lib/validators/functional/_isFormatIriReference.js +7 -0
  270. package/lib/validators/functional/_isFormatIriReference.js.map +1 -0
  271. package/lib/validators/functional/_isFormatIriReference.mjs +5 -0
  272. package/lib/validators/functional/_isFormatIriReference.mjs.map +1 -0
  273. package/lib/validators/functional/_isFormatJsonPointer.d.ts +1 -0
  274. package/lib/validators/functional/_isFormatJsonPointer.js +7 -0
  275. package/lib/validators/functional/_isFormatJsonPointer.js.map +1 -0
  276. package/lib/validators/functional/_isFormatJsonPointer.mjs +5 -0
  277. package/lib/validators/functional/_isFormatJsonPointer.mjs.map +1 -0
  278. package/lib/validators/functional/_isFormatPassword.d.ts +1 -0
  279. package/lib/validators/functional/_isFormatPassword.js +6 -0
  280. package/lib/validators/functional/_isFormatPassword.js.map +1 -0
  281. package/lib/validators/functional/_isFormatPassword.mjs +4 -0
  282. package/lib/validators/functional/_isFormatPassword.mjs.map +1 -0
  283. package/lib/validators/functional/_isFormatRegex.d.ts +1 -0
  284. package/lib/validators/functional/_isFormatRegex.js +14 -0
  285. package/lib/validators/functional/_isFormatRegex.js.map +1 -0
  286. package/lib/validators/functional/_isFormatRegex.mjs +12 -0
  287. package/lib/validators/functional/_isFormatRegex.mjs.map +1 -0
  288. package/lib/validators/functional/_isFormatRelativeJsonPointer.d.ts +1 -0
  289. package/lib/validators/functional/_isFormatRelativeJsonPointer.js +7 -0
  290. package/lib/validators/functional/_isFormatRelativeJsonPointer.js.map +1 -0
  291. package/lib/validators/functional/_isFormatRelativeJsonPointer.mjs +5 -0
  292. package/lib/validators/functional/_isFormatRelativeJsonPointer.mjs.map +1 -0
  293. package/lib/validators/functional/_isFormatTime.d.ts +1 -0
  294. package/lib/validators/functional/_isFormatTime.js +7 -0
  295. package/lib/validators/functional/_isFormatTime.js.map +1 -0
  296. package/lib/validators/functional/_isFormatTime.mjs +5 -0
  297. package/lib/validators/functional/_isFormatTime.mjs.map +1 -0
  298. package/lib/validators/functional/_isFormatUri.d.ts +1 -0
  299. package/lib/validators/functional/_isFormatUri.js +8 -0
  300. package/lib/validators/functional/_isFormatUri.js.map +1 -0
  301. package/lib/validators/functional/_isFormatUri.mjs +6 -0
  302. package/lib/validators/functional/_isFormatUri.mjs.map +1 -0
  303. package/lib/validators/functional/_isFormatUriReference.d.ts +1 -0
  304. package/lib/validators/functional/_isFormatUriReference.js +7 -0
  305. package/lib/validators/functional/_isFormatUriReference.js.map +1 -0
  306. package/lib/validators/functional/_isFormatUriReference.mjs +5 -0
  307. package/lib/validators/functional/_isFormatUriReference.mjs.map +1 -0
  308. package/lib/validators/functional/_isFormatUriTemplate.d.ts +1 -0
  309. package/lib/validators/functional/_isFormatUriTemplate.js +7 -0
  310. package/lib/validators/functional/_isFormatUriTemplate.js.map +1 -0
  311. package/lib/validators/functional/_isFormatUriTemplate.mjs +5 -0
  312. package/lib/validators/functional/_isFormatUriTemplate.mjs.map +1 -0
  313. package/lib/validators/functional/_isFormatUrl.d.ts +1 -0
  314. package/lib/validators/functional/_isFormatUrl.js +7 -0
  315. package/lib/validators/functional/_isFormatUrl.js.map +1 -0
  316. package/lib/validators/functional/_isFormatUrl.mjs +5 -0
  317. package/lib/validators/functional/_isFormatUrl.mjs.map +1 -0
  318. package/lib/validators/functional/_isFormatUuid.d.ts +1 -0
  319. package/lib/validators/functional/_isFormatUuid.js +7 -0
  320. package/lib/validators/functional/_isFormatUuid.js.map +1 -0
  321. package/lib/validators/functional/_isFormatUuid.mjs +5 -0
  322. package/lib/validators/functional/_isFormatUuid.mjs.map +1 -0
  323. package/lib/validators/functional/_isUniqueItems.d.ts +1 -0
  324. package/lib/validators/functional/_isUniqueItems.js +140 -0
  325. package/lib/validators/functional/_isUniqueItems.js.map +1 -0
  326. package/lib/validators/functional/_isUniqueItems.mjs +138 -0
  327. package/lib/validators/functional/_isUniqueItems.mjs.map +1 -0
  328. package/lib/validators/index.d.ts +2 -0
  329. package/lib/validators/index.js +27 -0
  330. package/lib/validators/index.js.map +1 -0
  331. package/lib/validators/index.mjs +7 -0
  332. package/lib/validators/index.mjs.map +1 -0
  333. package/lib/validators/internal/IOpenApiValidatorContext.d.ts +14 -0
  334. package/lib/validators/internal/IOpenApiValidatorContext.js +3 -0
  335. package/lib/validators/internal/IOpenApiValidatorContext.js.map +1 -0
  336. package/lib/validators/internal/IOpenApiValidatorContext.mjs +2 -0
  337. package/lib/validators/internal/IOpenApiValidatorContext.mjs.map +1 -0
  338. package/lib/validators/internal/OpenApiArrayValidator.d.ts +5 -0
  339. package/lib/validators/internal/OpenApiArrayValidator.js +32 -0
  340. package/lib/validators/internal/OpenApiArrayValidator.js.map +1 -0
  341. package/lib/validators/internal/OpenApiArrayValidator.mjs +47 -0
  342. package/lib/validators/internal/OpenApiArrayValidator.mjs.map +1 -0
  343. package/lib/validators/internal/OpenApiBooleanValidator.d.ts +5 -0
  344. package/lib/validators/internal/OpenApiBooleanValidator.js +10 -0
  345. package/lib/validators/internal/OpenApiBooleanValidator.js.map +1 -0
  346. package/lib/validators/internal/OpenApiBooleanValidator.mjs +9 -0
  347. package/lib/validators/internal/OpenApiBooleanValidator.mjs.map +1 -0
  348. package/lib/validators/internal/OpenApiConstantValidator.d.ts +5 -0
  349. package/lib/validators/internal/OpenApiConstantValidator.js +10 -0
  350. package/lib/validators/internal/OpenApiConstantValidator.js.map +1 -0
  351. package/lib/validators/internal/OpenApiConstantValidator.mjs +9 -0
  352. package/lib/validators/internal/OpenApiConstantValidator.mjs.map +1 -0
  353. package/lib/validators/internal/OpenApiIntegerValidator.d.ts +5 -0
  354. package/lib/validators/internal/OpenApiIntegerValidator.js +33 -0
  355. package/lib/validators/internal/OpenApiIntegerValidator.js.map +1 -0
  356. package/lib/validators/internal/OpenApiIntegerValidator.mjs +47 -0
  357. package/lib/validators/internal/OpenApiIntegerValidator.mjs.map +1 -0
  358. package/lib/validators/internal/OpenApiNumberValidator.d.ts +5 -0
  359. package/lib/validators/internal/OpenApiNumberValidator.js +33 -0
  360. package/lib/validators/internal/OpenApiNumberValidator.js.map +1 -0
  361. package/lib/validators/internal/OpenApiNumberValidator.mjs +47 -0
  362. package/lib/validators/internal/OpenApiNumberValidator.mjs.map +1 -0
  363. package/lib/validators/internal/OpenApiObjectValidator.d.ts +5 -0
  364. package/lib/validators/internal/OpenApiObjectValidator.js +58 -0
  365. package/lib/validators/internal/OpenApiObjectValidator.js.map +1 -0
  366. package/lib/validators/internal/OpenApiObjectValidator.mjs +68 -0
  367. package/lib/validators/internal/OpenApiObjectValidator.mjs.map +1 -0
  368. package/lib/validators/internal/OpenApiOneOfValidator.d.ts +5 -0
  369. package/lib/validators/internal/OpenApiOneOfValidator.js +182 -0
  370. package/lib/validators/internal/OpenApiOneOfValidator.js.map +1 -0
  371. package/lib/validators/internal/OpenApiOneOfValidator.mjs +206 -0
  372. package/lib/validators/internal/OpenApiOneOfValidator.mjs.map +1 -0
  373. package/lib/validators/internal/OpenApiSchemaNamingRule.d.ts +4 -0
  374. package/lib/validators/internal/OpenApiSchemaNamingRule.js +122 -0
  375. package/lib/validators/internal/OpenApiSchemaNamingRule.js.map +1 -0
  376. package/lib/validators/internal/OpenApiSchemaNamingRule.mjs +121 -0
  377. package/lib/validators/internal/OpenApiSchemaNamingRule.mjs.map +1 -0
  378. package/lib/validators/internal/OpenApiStationValidator.d.ts +5 -0
  379. package/lib/validators/internal/OpenApiStationValidator.js +63 -0
  380. package/lib/validators/internal/OpenApiStationValidator.js.map +1 -0
  381. package/lib/validators/internal/OpenApiStationValidator.mjs +107 -0
  382. package/lib/validators/internal/OpenApiStationValidator.mjs.map +1 -0
  383. package/lib/validators/internal/OpenApiStringValidator.d.ts +5 -0
  384. package/lib/validators/internal/OpenApiStringValidator.js +73 -0
  385. package/lib/validators/internal/OpenApiStringValidator.js.map +1 -0
  386. package/lib/validators/internal/OpenApiStringValidator.mjs +85 -0
  387. package/lib/validators/internal/OpenApiStringValidator.mjs.map +1 -0
  388. package/lib/validators/internal/OpenApiTupleValidator.d.ts +5 -0
  389. package/lib/validators/internal/OpenApiTupleValidator.js +31 -0
  390. package/lib/validators/internal/OpenApiTupleValidator.js.map +1 -0
  391. package/lib/validators/internal/OpenApiTupleValidator.mjs +46 -0
  392. package/lib/validators/internal/OpenApiTupleValidator.mjs.map +1 -0
  393. package/package.json +91 -0
  394. package/src/converters/LlmSchemaConverter.ts +924 -0
  395. package/src/converters/OpenApiConverter.ts +285 -0
  396. package/src/converters/index.ts +5 -0
  397. package/src/converters/internal/LlmDescriptionInverter.ts +178 -0
  398. package/src/converters/internal/LlmParametersComposer.ts +52 -0
  399. package/src/converters/internal/OpenApiConstraintShifter.ts +154 -0
  400. package/src/converters/internal/OpenApiExclusiveEmender.ts +46 -0
  401. package/src/converters/internal/OpenApiV3Downgrader.ts +355 -0
  402. package/src/converters/internal/OpenApiV3Upgrader.ts +470 -0
  403. package/src/converters/internal/OpenApiV3_1Upgrader.ts +685 -0
  404. package/src/converters/internal/SwaggerV2Downgrader.ts +424 -0
  405. package/src/converters/internal/SwaggerV2Upgrader.ts +523 -0
  406. package/src/http/HttpError.ts +107 -0
  407. package/src/http/HttpLlm.ts +210 -0
  408. package/src/http/HttpMigration.ts +92 -0
  409. package/src/http/index.ts +3 -0
  410. package/src/http/internal/HttpLlmApplicationComposer.ts +308 -0
  411. package/src/http/internal/HttpLlmFunctionFetcher.ts +37 -0
  412. package/src/http/internal/HttpMigrateApplicationComposer.ts +56 -0
  413. package/src/http/internal/HttpMigrateRouteAccessor.ts +135 -0
  414. package/src/http/internal/HttpMigrateRouteComposer.ts +513 -0
  415. package/src/http/internal/HttpMigrateRouteFetcher.ts +203 -0
  416. package/src/http/internal/LlmDataMerger.ts +73 -0
  417. package/src/index.ts +4 -0
  418. package/src/utils/ArrayUtil.ts +42 -0
  419. package/src/utils/MapUtil.ts +15 -0
  420. package/src/utils/NamingConvention.ts +205 -0
  421. package/src/utils/Singleton.ts +17 -0
  422. package/src/utils/StringUtil.ts +14 -0
  423. package/src/utils/dedent.ts +57 -0
  424. package/src/utils/index.ts +8 -0
  425. package/src/utils/internal/EndpointUtil.ts +44 -0
  426. package/src/utils/internal/JsonDescriptor.ts +70 -0
  427. package/src/utils/internal/OpenApiTypeCheckerBase.ts +822 -0
  428. package/src/utils/stringifyValidationFailure.ts +415 -0
  429. package/src/validators/LlmTypeChecker.ts +402 -0
  430. package/src/validators/OpenApiTypeChecker.ts +297 -0
  431. package/src/validators/OpenApiV3TypeChecker.ts +70 -0
  432. package/src/validators/OpenApiV3_1TypeChecker.ts +86 -0
  433. package/src/validators/OpenApiValidator.ts +94 -0
  434. package/src/validators/SwaggerV2TypeChecker.ts +71 -0
  435. package/src/validators/functional/_isBigintString.ts +8 -0
  436. package/src/validators/functional/_isFormatByte.ts +7 -0
  437. package/src/validators/functional/_isFormatDate.ts +3 -0
  438. package/src/validators/functional/_isFormatDateTime.ts +4 -0
  439. package/src/validators/functional/_isFormatDuration.ts +4 -0
  440. package/src/validators/functional/_isFormatEmail.ts +4 -0
  441. package/src/validators/functional/_isFormatHostname.ts +4 -0
  442. package/src/validators/functional/_isFormatIdnEmail.ts +4 -0
  443. package/src/validators/functional/_isFormatIdnHostname.ts +4 -0
  444. package/src/validators/functional/_isFormatIpv4.ts +4 -0
  445. package/src/validators/functional/_isFormatIpv6.ts +4 -0
  446. package/src/validators/functional/_isFormatIri.ts +3 -0
  447. package/src/validators/functional/_isFormatIriReference.ts +4 -0
  448. package/src/validators/functional/_isFormatJsonPointer.ts +3 -0
  449. package/src/validators/functional/_isFormatPassword.ts +1 -0
  450. package/src/validators/functional/_isFormatRegex.ts +8 -0
  451. package/src/validators/functional/_isFormatRelativeJsonPointer.ts +4 -0
  452. package/src/validators/functional/_isFormatTime.ts +4 -0
  453. package/src/validators/functional/_isFormatUri.ts +6 -0
  454. package/src/validators/functional/_isFormatUriReference.ts +5 -0
  455. package/src/validators/functional/_isFormatUriTemplate.ts +4 -0
  456. package/src/validators/functional/_isFormatUrl.ts +4 -0
  457. package/src/validators/functional/_isFormatUuid.ts +3 -0
  458. package/src/validators/functional/_isUniqueItems.ts +159 -0
  459. package/src/validators/index.ts +14 -0
  460. package/src/validators/internal/IOpenApiValidatorContext.ts +17 -0
  461. package/src/validators/internal/OpenApiArrayValidator.ts +49 -0
  462. package/src/validators/internal/OpenApiBooleanValidator.ts +11 -0
  463. package/src/validators/internal/OpenApiConstantValidator.ts +11 -0
  464. package/src/validators/internal/OpenApiIntegerValidator.ts +49 -0
  465. package/src/validators/internal/OpenApiNumberValidator.ts +48 -0
  466. package/src/validators/internal/OpenApiObjectValidator.ts +83 -0
  467. package/src/validators/internal/OpenApiOneOfValidator.ts +309 -0
  468. package/src/validators/internal/OpenApiSchemaNamingRule.ts +124 -0
  469. package/src/validators/internal/OpenApiStationValidator.ts +115 -0
  470. package/src/validators/internal/OpenApiStringValidator.ts +88 -0
  471. package/src/validators/internal/OpenApiTupleValidator.ts +55 -0
@@ -0,0 +1,924 @@
1
+ import {
2
+ IJsonSchemaAttribute,
3
+ IJsonSchemaTransformError,
4
+ ILlmFunction,
5
+ ILlmSchema,
6
+ IResult,
7
+ OpenApi,
8
+ } from "@typia/interface";
9
+
10
+ import { NamingConvention } from "../utils/NamingConvention";
11
+ import { JsonDescriptor } from "../utils/internal/JsonDescriptor";
12
+ import { LlmTypeChecker } from "../validators/LlmTypeChecker";
13
+ import { OpenApiTypeChecker } from "../validators/OpenApiTypeChecker";
14
+ import { OpenApiValidator } from "../validators/OpenApiValidator";
15
+ import { LlmDescriptionInverter } from "./internal/LlmDescriptionInverter";
16
+ import { LlmParametersFinder } from "./internal/LlmParametersComposer";
17
+ import { OpenApiConstraintShifter } from "./internal/OpenApiConstraintShifter";
18
+
19
+ /**
20
+ * OpenAPI to LLM schema converter.
21
+ *
22
+ * `LlmSchemaConverter` converts OpenAPI JSON schemas to LLM-compatible
23
+ * {@link ILlmSchema} format. LLMs don't fully support JSON Schema, so this
24
+ * simplifies schemas by removing unsupported features (tuples, `const`, mixed
25
+ * unions).
26
+ *
27
+ * Main functions:
28
+ *
29
+ * - {@link parameters}: Convert object schema to {@link ILlmSchema.IParameters}
30
+ * - {@link schema}: Convert any schema to {@link ILlmSchema}
31
+ * - {@link separate}: Split parameters into LLM-fillable vs human-required
32
+ * - {@link invert}: Extract constraints from description back to schema
33
+ *
34
+ * Configuration options ({@link ILlmSchema.IConfig}):
35
+ *
36
+ * - `reference`: Allow `$ref` references (reduces tokens but may confuse LLM)
37
+ * - `strict`: OpenAI structured output mode (all properties required)
38
+ *
39
+ * @author Jeongho Nam - https://github.com/samchon
40
+ */
41
+ export namespace LlmSchemaConverter {
42
+ /**
43
+ * Get configuration with defaults applied.
44
+ *
45
+ * @param config Partial configuration
46
+ * @returns Full configuration with defaults
47
+ */
48
+ export const getConfig = (
49
+ config?: Partial<ILlmSchema.IConfig> | undefined,
50
+ ): ILlmSchema.IConfig => ({
51
+ reference: config?.reference ?? true,
52
+ strict: config?.strict ?? false,
53
+ });
54
+
55
+ /* -----------------------------------------------------------
56
+ CONVERTERS
57
+ ----------------------------------------------------------- */
58
+ /**
59
+ * Convert OpenAPI object schema to LLM parameters schema.
60
+ *
61
+ * @param props.config Conversion configuration
62
+ * @param props.components OpenAPI components for reference resolution
63
+ * @param props.schema Object or reference schema to convert
64
+ * @param props.accessor Error path accessor
65
+ * @param props.refAccessor Reference path accessor
66
+ * @returns Converted parameters or error
67
+ */
68
+ export const parameters = (props: {
69
+ config?: Partial<ILlmSchema.IConfig>;
70
+ components: OpenApi.IComponents;
71
+ schema: OpenApi.IJsonSchema.IObject | OpenApi.IJsonSchema.IReference;
72
+ accessor?: string;
73
+ refAccessor?: string;
74
+ }): IResult<ILlmSchema.IParameters, IJsonSchemaTransformError> => {
75
+ const config: ILlmSchema.IConfig = getConfig(props.config);
76
+ const entity: IResult<
77
+ OpenApi.IJsonSchema.IObject,
78
+ IJsonSchemaTransformError
79
+ > = LlmParametersFinder.parameters({
80
+ ...props,
81
+ method: "LlmSchemaConverter.parameters",
82
+ });
83
+ if (entity.success === false) return entity;
84
+
85
+ const $defs: Record<string, ILlmSchema> = {};
86
+ const result: IResult<ILlmSchema, IJsonSchemaTransformError> = transform({
87
+ ...props,
88
+ config,
89
+ $defs,
90
+ schema: entity.value,
91
+ });
92
+ if (result.success === false) return result;
93
+ return {
94
+ success: true,
95
+ value: {
96
+ ...(result.value as ILlmSchema.IObject),
97
+ additionalProperties: false,
98
+ $defs,
99
+ description: OpenApiTypeChecker.isReference(props.schema)
100
+ ? JsonDescriptor.cascade({
101
+ prefix: "#/components/schemas/",
102
+ components: props.components,
103
+ schema: {
104
+ ...props.schema,
105
+ description: result.value.description,
106
+ },
107
+ escape: true,
108
+ })
109
+ : result.value.description,
110
+ } satisfies ILlmSchema.IParameters,
111
+ };
112
+ };
113
+
114
+ /**
115
+ * Convert OpenAPI schema to LLM schema.
116
+ *
117
+ * @param props.config Conversion configuration
118
+ * @param props.components OpenAPI components for reference resolution
119
+ * @param props.$defs Definition store (mutated with referenced types)
120
+ * @param props.schema Schema to convert
121
+ * @param props.accessor Error path accessor
122
+ * @param props.refAccessor Reference path accessor
123
+ * @returns Converted schema or error
124
+ */
125
+ export const schema = (props: {
126
+ config?: Partial<ILlmSchema.IConfig>;
127
+ components: OpenApi.IComponents;
128
+ $defs: Record<string, ILlmSchema>;
129
+ schema: OpenApi.IJsonSchema;
130
+ accessor?: string;
131
+ refAccessor?: string;
132
+ }): IResult<ILlmSchema, IJsonSchemaTransformError> =>
133
+ transform({
134
+ config: getConfig(props.config),
135
+ components: props.components,
136
+ $defs: props.$defs,
137
+ schema: props.schema,
138
+ accessor: props.accessor,
139
+ refAccessor: props.refAccessor,
140
+ });
141
+
142
+ const transform = (props: {
143
+ config: ILlmSchema.IConfig;
144
+ components: OpenApi.IComponents;
145
+ $defs: Record<string, ILlmSchema>;
146
+ schema: OpenApi.IJsonSchema;
147
+ accessor?: string;
148
+ refAccessor?: string;
149
+ }): IResult<ILlmSchema, IJsonSchemaTransformError> => {
150
+ // PREPARE ASSETS
151
+ const union: Array<ILlmSchema> = [];
152
+ const attribute: IJsonSchemaAttribute = {
153
+ title: props.schema.title,
154
+ description: props.schema.description,
155
+ deprecated: props.schema.deprecated,
156
+ readOnly: props.schema.readOnly,
157
+ writeOnly: props.schema.writeOnly,
158
+ example: props.schema.example,
159
+ examples: props.schema.examples,
160
+ ...Object.fromEntries(
161
+ Object.entries(props.schema).filter(
162
+ ([key, value]) => key.startsWith("x-") && value !== undefined,
163
+ ),
164
+ ),
165
+ };
166
+
167
+ // VALIDADTE SCHEMA
168
+ const reasons: IJsonSchemaTransformError.IReason[] = [];
169
+ OpenApiTypeChecker.visit({
170
+ closure: (next, accessor) => {
171
+ if (props.config.strict === true) {
172
+ // STRICT MODE VALIDATION
173
+ reasons.push(...validateStrict(next, accessor));
174
+ }
175
+ if (OpenApiTypeChecker.isTuple(next))
176
+ reasons.push({
177
+ accessor,
178
+ schema: next,
179
+ message: `LLM does not allow tuple type.`,
180
+ });
181
+ else if (OpenApiTypeChecker.isReference(next)) {
182
+ // UNABLE TO FIND MATCHED REFERENCE
183
+ const key: string =
184
+ next.$ref.split("#/components/schemas/")[1] ??
185
+ next.$ref.split("/").at(-1)!;
186
+ if (props.components.schemas?.[key] === undefined)
187
+ reasons.push({
188
+ schema: next,
189
+ accessor: accessor,
190
+ message: `unable to find reference type ${JSON.stringify(key)}.`,
191
+ });
192
+ }
193
+ },
194
+ components: props.components,
195
+ schema: props.schema,
196
+ accessor: props.accessor,
197
+ refAccessor: props.refAccessor,
198
+ });
199
+ if (reasons.length > 0)
200
+ return {
201
+ success: false,
202
+ error: {
203
+ method: "LlmSchemaConverter.schema",
204
+ message: "Failed to compose LLM schema",
205
+ reasons,
206
+ },
207
+ };
208
+
209
+ const visitConstant = (input: OpenApi.IJsonSchema): void => {
210
+ const insert = (value: any): void => {
211
+ const matched:
212
+ | ILlmSchema.IString
213
+ | ILlmSchema.INumber
214
+ | ILlmSchema.IBoolean
215
+ | undefined = union.find(
216
+ (u) =>
217
+ (u as (IJsonSchemaAttribute & { type: string }) | undefined)
218
+ ?.type === typeof value,
219
+ ) as ILlmSchema.IString | undefined;
220
+ if (matched !== undefined) {
221
+ matched.enum ??= [];
222
+ matched.enum.push(value);
223
+ } else
224
+ union.push({
225
+ type: typeof value as "number",
226
+ enum: [value],
227
+ });
228
+ };
229
+ if (OpenApiTypeChecker.isConstant(input)) insert(input.const);
230
+ else if (OpenApiTypeChecker.isOneOf(input))
231
+ input.oneOf.forEach(visitConstant);
232
+ };
233
+ const visit = (input: OpenApi.IJsonSchema, accessor: string): void => {
234
+ if (OpenApiTypeChecker.isOneOf(input)) {
235
+ // UNION TYPE
236
+ input.oneOf.forEach((s, i) => visit(s, `${accessor}.oneOf[${i}]`));
237
+ } else if (OpenApiTypeChecker.isReference(input)) {
238
+ // REFERENCE TYPE
239
+ const key: string =
240
+ input.$ref.split("#/components/schemas/")[1] ??
241
+ input.$ref.split("/").at(-1)!;
242
+ const target: OpenApi.IJsonSchema | undefined =
243
+ props.components.schemas?.[key];
244
+ if (target === undefined) return;
245
+ else if (
246
+ // KEEP THE REFERENCE TYPE
247
+ props.config.reference === true ||
248
+ OpenApiTypeChecker.isRecursiveReference({
249
+ components: props.components,
250
+ schema: input,
251
+ })
252
+ ) {
253
+ const out = () => {
254
+ union.push({
255
+ ...input,
256
+ $ref: `#/$defs/${key}`,
257
+ });
258
+ };
259
+ if (props.$defs[key] !== undefined) return out();
260
+
261
+ props.$defs[key] = {};
262
+ const converted: IResult<ILlmSchema, IJsonSchemaTransformError> =
263
+ transform({
264
+ config: props.config,
265
+ components: props.components,
266
+ $defs: props.$defs,
267
+ schema: target,
268
+ refAccessor: props.refAccessor,
269
+ accessor: `${props.refAccessor ?? "$def"}[${JSON.stringify(key)}]`,
270
+ });
271
+ if (converted.success === false) return; // UNREACHABLE
272
+ props.$defs[key] = converted.value;
273
+ return out();
274
+ } else {
275
+ // DISCARD THE REFERENCE TYPE
276
+ const length: number = union.length;
277
+ visit(target, accessor);
278
+ visitConstant(target);
279
+ if (length === union.length - 1)
280
+ union[union.length - 1] = {
281
+ ...union[union.length - 1]!,
282
+ description: JsonDescriptor.cascade({
283
+ prefix: "#/components/schemas/",
284
+ components: props.components,
285
+ schema: input,
286
+ escape: true,
287
+ }),
288
+ };
289
+ else
290
+ attribute.description = JsonDescriptor.cascade({
291
+ prefix: "#/components/schemas/",
292
+ components: props.components,
293
+ schema: input,
294
+ escape: true,
295
+ });
296
+ }
297
+ } else if (OpenApiTypeChecker.isObject(input)) {
298
+ // OBJECT TYPE
299
+ const properties: Record<string, ILlmSchema> = Object.fromEntries(
300
+ Object.entries(input.properties ?? {})
301
+ .map(([key, value]) => {
302
+ const converted: IResult<ILlmSchema, IJsonSchemaTransformError> =
303
+ transform({
304
+ config: props.config,
305
+ components: props.components,
306
+ $defs: props.$defs,
307
+ schema: value,
308
+ refAccessor: props.refAccessor,
309
+ accessor: `${props.accessor ?? "$input.schema"}.properties[${JSON.stringify(key)}]`,
310
+ });
311
+ if (converted.success === false) {
312
+ reasons.push(...converted.error.reasons);
313
+ return [key, null];
314
+ }
315
+ return [key, converted.value];
316
+ })
317
+ .filter(([, value]) => value !== null),
318
+ );
319
+ if (Object.values(properties).some((v) => v === null)) return;
320
+
321
+ const additionalProperties: ILlmSchema | boolean | undefined | null =
322
+ (() => {
323
+ if (
324
+ typeof input.additionalProperties === "object" &&
325
+ input.additionalProperties !== null
326
+ ) {
327
+ const converted: IResult<ILlmSchema, IJsonSchemaTransformError> =
328
+ transform({
329
+ config: props.config,
330
+ components: props.components,
331
+ $defs: props.$defs,
332
+ schema: input.additionalProperties,
333
+ refAccessor: props.refAccessor,
334
+ accessor: `${accessor}.additionalProperties`,
335
+ });
336
+ if (converted.success === false) {
337
+ reasons.push(...converted.error.reasons);
338
+ return null;
339
+ }
340
+ return converted.value;
341
+ }
342
+ return props.config.strict === true
343
+ ? false
344
+ : input.additionalProperties;
345
+ })();
346
+ if (additionalProperties === null) return;
347
+ union.push({
348
+ ...input,
349
+ properties,
350
+ additionalProperties,
351
+ required: input.required ?? [],
352
+ description:
353
+ props.config.strict === true
354
+ ? JsonDescriptor.take(input)
355
+ : input.description,
356
+ });
357
+ } else if (OpenApiTypeChecker.isArray(input)) {
358
+ // ARRAY TYPE
359
+ const items: IResult<ILlmSchema, IJsonSchemaTransformError> = transform(
360
+ {
361
+ config: props.config,
362
+ components: props.components,
363
+ $defs: props.$defs,
364
+ schema: input.items,
365
+ refAccessor: props.refAccessor,
366
+ accessor: `${accessor}.items`,
367
+ },
368
+ );
369
+ if (items.success === false) {
370
+ reasons.push(...items.error.reasons);
371
+ return;
372
+ }
373
+ union.push(
374
+ props.config.strict === true
375
+ ? OpenApiConstraintShifter.shiftArray({
376
+ ...input,
377
+ items: items.value,
378
+ })
379
+ : {
380
+ ...input,
381
+ items: items.value,
382
+ },
383
+ );
384
+ } else if (OpenApiTypeChecker.isString(input))
385
+ union.push(
386
+ props.config.strict === true
387
+ ? OpenApiConstraintShifter.shiftString({ ...input })
388
+ : input,
389
+ );
390
+ else if (
391
+ OpenApiTypeChecker.isNumber(input) ||
392
+ OpenApiTypeChecker.isInteger(input)
393
+ )
394
+ union.push(
395
+ props.config.strict === true
396
+ ? OpenApiConstraintShifter.shiftNumeric({ ...input })
397
+ : input,
398
+ );
399
+ else if (OpenApiTypeChecker.isTuple(input))
400
+ return; // UNREACHABLE
401
+ else if (OpenApiTypeChecker.isConstant(input) === false)
402
+ union.push({ ...input });
403
+ };
404
+
405
+ visitConstant(props.schema);
406
+ visit(props.schema, props.accessor ?? "$input.schema");
407
+
408
+ if (reasons.length > 0)
409
+ return {
410
+ success: false,
411
+ error: {
412
+ method: "LlmSchemaConverter.schema",
413
+ message: "Failed to compose LLM schema",
414
+ reasons,
415
+ },
416
+ };
417
+ else if (union.length === 0)
418
+ return {
419
+ // unknown type
420
+ success: true,
421
+ value: {
422
+ ...attribute,
423
+ type: undefined,
424
+ },
425
+ };
426
+ else if (union.length === 1)
427
+ return {
428
+ // single type
429
+ success: true,
430
+ value: {
431
+ ...attribute,
432
+ ...union[0],
433
+ description:
434
+ props.config.strict === true &&
435
+ LlmTypeChecker.isReference(union[0]!)
436
+ ? undefined
437
+ : (union[0]!.description ?? attribute.description),
438
+ },
439
+ };
440
+ return {
441
+ success: true,
442
+ value: {
443
+ ...attribute,
444
+ anyOf: union.map((u) => ({
445
+ ...u,
446
+ description:
447
+ props.config.strict === true && LlmTypeChecker.isReference(u)
448
+ ? undefined
449
+ : u.description,
450
+ })),
451
+ "x-discriminator":
452
+ OpenApiTypeChecker.isOneOf(props.schema) &&
453
+ props.schema.discriminator !== undefined &&
454
+ props.schema.oneOf.length === union.length &&
455
+ union.every(
456
+ (e) => LlmTypeChecker.isReference(e) || LlmTypeChecker.isNull(e),
457
+ )
458
+ ? {
459
+ propertyName: props.schema.discriminator.propertyName,
460
+ mapping:
461
+ props.schema.discriminator.mapping !== undefined
462
+ ? Object.fromEntries(
463
+ Object.entries(props.schema.discriminator.mapping).map(
464
+ ([key, value]) => [
465
+ key,
466
+ `#/$defs/${value.split("/").at(-1)}`,
467
+ ],
468
+ ),
469
+ )
470
+ : undefined,
471
+ }
472
+ : undefined,
473
+ },
474
+ };
475
+ };
476
+
477
+ /* -----------------------------------------------------------
478
+ INVERTERS
479
+ ----------------------------------------------------------- */
480
+ /**
481
+ * Convert LLM schema back to OpenAPI schema.
482
+ *
483
+ * Restores constraint information from description tags and converts `$defs`
484
+ * references to `#/components/schemas`.
485
+ *
486
+ * @param props.components Target components (mutated with definitions)
487
+ * @param props.schema LLM schema to invert
488
+ * @param props.$defs LLM schema definitions
489
+ * @returns OpenAPI JSON schema
490
+ */
491
+ export const invert = (props: {
492
+ components: OpenApi.IComponents;
493
+ schema: ILlmSchema;
494
+ $defs: Record<string, ILlmSchema>;
495
+ }): OpenApi.IJsonSchema => {
496
+ const union: OpenApi.IJsonSchema[] = [];
497
+ const attribute: IJsonSchemaAttribute = {
498
+ title: props.schema.title,
499
+ description: props.schema.description,
500
+ deprecated: props.schema.deprecated,
501
+ readOnly: props.schema.readOnly,
502
+ writeOnly: props.schema.writeOnly,
503
+ example: props.schema.example,
504
+ examples: props.schema.examples,
505
+ ...Object.fromEntries(
506
+ Object.entries(props.schema).filter(
507
+ ([key, value]) => key.startsWith("x-") && value !== undefined,
508
+ ),
509
+ ),
510
+ };
511
+
512
+ const next = (schema: ILlmSchema): OpenApi.IJsonSchema =>
513
+ invert({
514
+ components: props.components,
515
+ $defs: props.$defs,
516
+ schema,
517
+ });
518
+ const visit = (schema: ILlmSchema): void => {
519
+ if (LlmTypeChecker.isArray(schema))
520
+ union.push({
521
+ ...schema,
522
+ ...LlmDescriptionInverter.array(schema.description),
523
+ items: next(schema.items),
524
+ });
525
+ else if (LlmTypeChecker.isObject(schema))
526
+ union.push({
527
+ ...schema,
528
+ properties: Object.fromEntries(
529
+ Object.entries(schema.properties).map(([key, value]) => [
530
+ key,
531
+ next(value),
532
+ ]),
533
+ ),
534
+ additionalProperties:
535
+ typeof schema.additionalProperties === "object" &&
536
+ schema.additionalProperties !== null
537
+ ? next(schema.additionalProperties)
538
+ : schema.additionalProperties,
539
+ });
540
+ else if (LlmTypeChecker.isAnyOf(schema)) schema.anyOf.forEach(visit);
541
+ else if (LlmTypeChecker.isReference(schema)) {
542
+ const key: string =
543
+ schema.$ref.split("#/$defs/")[1] ?? schema.$ref.split("/").at(-1)!;
544
+ if (props.components.schemas?.[key] === undefined) {
545
+ props.components.schemas ??= {};
546
+ props.components.schemas[key] = {};
547
+ props.components.schemas[key] = next(props.$defs[key] ?? {});
548
+ }
549
+ union.push({
550
+ ...schema,
551
+ $ref: `#/components/schemas/${key}`,
552
+ });
553
+ } else if (LlmTypeChecker.isBoolean(schema))
554
+ if (!!schema.enum?.length)
555
+ schema.enum.forEach((v) =>
556
+ union.push({
557
+ const: v,
558
+ }),
559
+ );
560
+ else union.push(schema);
561
+ else if (
562
+ LlmTypeChecker.isInteger(schema) ||
563
+ LlmTypeChecker.isNumber(schema)
564
+ )
565
+ if (!!schema.enum?.length)
566
+ schema.enum.forEach((v) =>
567
+ union.push({
568
+ const: v,
569
+ }),
570
+ );
571
+ else
572
+ union.push({
573
+ ...schema,
574
+ ...LlmDescriptionInverter.numeric(schema.description),
575
+ ...{ enum: undefined },
576
+ });
577
+ else if (LlmTypeChecker.isString(schema))
578
+ if (!!schema.enum?.length)
579
+ schema.enum.forEach((v) =>
580
+ union.push({
581
+ const: v,
582
+ }),
583
+ );
584
+ else
585
+ union.push({
586
+ ...schema,
587
+ ...LlmDescriptionInverter.string(schema.description),
588
+ ...{ enum: undefined },
589
+ });
590
+ else
591
+ union.push({
592
+ ...schema,
593
+ });
594
+ };
595
+ visit(props.schema);
596
+
597
+ return {
598
+ ...attribute,
599
+ ...(union.length === 0
600
+ ? { type: undefined }
601
+ : union.length === 1
602
+ ? { ...union[0] }
603
+ : {
604
+ oneOf: union.map((u) => ({ ...u, nullable: undefined })),
605
+ discriminator:
606
+ LlmTypeChecker.isAnyOf(props.schema) &&
607
+ props.schema["x-discriminator"] !== undefined
608
+ ? {
609
+ propertyName:
610
+ props.schema["x-discriminator"].propertyName,
611
+ mapping:
612
+ props.schema["x-discriminator"].mapping !== undefined
613
+ ? Object.fromEntries(
614
+ Object.entries(
615
+ props.schema["x-discriminator"].mapping,
616
+ ).map(([key, value]) => [
617
+ key,
618
+ `#/components/schemas/${value.split("/").at(-1)}`,
619
+ ]),
620
+ )
621
+ : undefined,
622
+ }
623
+ : undefined,
624
+ }),
625
+ } satisfies OpenApi.IJsonSchema;
626
+ };
627
+
628
+ /* -----------------------------------------------------------
629
+ SEPARATORS
630
+ ----------------------------------------------------------- */
631
+ /**
632
+ * Separate parameters into LLM and human parts.
633
+ *
634
+ * Splits parameters based on predicate (human-side if true). Creates separate
635
+ * schemas for LLM-fillable and human-required fields.
636
+ *
637
+ * @param props.parameters Parameters schema to separate
638
+ * @param props.predicate Returns true for human-side properties
639
+ * @param props.convention Key naming convention for separated types
640
+ * @param props.equals Whether to use strict equality validation
641
+ * @returns Separated LLM and human parameter schemas
642
+ */
643
+ export const separate = (props: {
644
+ parameters: ILlmSchema.IParameters;
645
+ predicate: (schema: ILlmSchema) => boolean;
646
+ convention?: (key: string, type: "llm" | "human") => string;
647
+ equals?: boolean;
648
+ }): ILlmFunction.ISeparated => {
649
+ const convention =
650
+ props.convention ??
651
+ ((key, type) => `${key}.${NamingConvention.capitalize(type)}`);
652
+ const [llm, human] = separateObject({
653
+ predicate: props.predicate,
654
+ convention,
655
+ $defs: props.parameters.$defs,
656
+ schema: props.parameters,
657
+ });
658
+ if (llm === null || human === null)
659
+ return {
660
+ llm: (llm as ILlmSchema.IParameters | null) ?? {
661
+ type: "object",
662
+ properties: {} as Record<string, ILlmSchema>,
663
+ required: [],
664
+ additionalProperties: false,
665
+ $defs: {},
666
+ },
667
+ human: human as ILlmSchema.IParameters | null,
668
+ };
669
+ const output: ILlmFunction.ISeparated = {
670
+ llm: {
671
+ ...llm,
672
+ $defs: Object.fromEntries(
673
+ Object.entries(props.parameters.$defs).filter(([key]) =>
674
+ key.endsWith(".Llm"),
675
+ ),
676
+ ),
677
+ additionalProperties: false,
678
+ },
679
+ human: {
680
+ ...human,
681
+ $defs: Object.fromEntries(
682
+ Object.entries(props.parameters.$defs).filter(([key]) =>
683
+ key.endsWith(".Human"),
684
+ ),
685
+ ),
686
+ additionalProperties: false,
687
+ },
688
+ };
689
+ for (const key of Object.keys(props.parameters.$defs))
690
+ if (key.endsWith(".Llm") === false && key.endsWith(".Human") === false)
691
+ delete props.parameters.$defs[key];
692
+ if (Object.keys(output.llm.properties).length !== 0) {
693
+ const components: OpenApi.IComponents = {};
694
+ output.validate = OpenApiValidator.create({
695
+ components,
696
+ schema: invert({
697
+ components,
698
+ schema: output.llm,
699
+ $defs: output.llm.$defs,
700
+ }),
701
+ required: true,
702
+ equals: props.equals,
703
+ });
704
+ }
705
+ return output;
706
+ };
707
+
708
+ const separateStation = (props: {
709
+ predicate: (schema: ILlmSchema) => boolean;
710
+ convention: (key: string, type: "llm" | "human") => string;
711
+ $defs: Record<string, ILlmSchema>;
712
+ schema: ILlmSchema;
713
+ }): [ILlmSchema | null, ILlmSchema | null] => {
714
+ if (props.predicate(props.schema) === true) return [null, props.schema];
715
+ else if (
716
+ LlmTypeChecker.isUnknown(props.schema) ||
717
+ LlmTypeChecker.isAnyOf(props.schema)
718
+ )
719
+ return [props.schema, null];
720
+ else if (LlmTypeChecker.isObject(props.schema))
721
+ return separateObject({
722
+ predicate: props.predicate,
723
+ convention: props.convention,
724
+ $defs: props.$defs,
725
+ schema: props.schema,
726
+ });
727
+ else if (LlmTypeChecker.isArray(props.schema))
728
+ return separateArray({
729
+ predicate: props.predicate,
730
+ convention: props.convention,
731
+ $defs: props.$defs,
732
+ schema: props.schema,
733
+ });
734
+ else if (LlmTypeChecker.isReference(props.schema))
735
+ return separateReference({
736
+ predicate: props.predicate,
737
+ convention: props.convention,
738
+ $defs: props.$defs,
739
+ schema: props.schema,
740
+ });
741
+ return [props.schema, null];
742
+ };
743
+
744
+ const separateArray = (props: {
745
+ predicate: (schema: ILlmSchema) => boolean;
746
+ convention: (key: string, type: "llm" | "human") => string;
747
+ $defs: Record<string, ILlmSchema>;
748
+ schema: ILlmSchema.IArray;
749
+ }): [ILlmSchema.IArray | null, ILlmSchema.IArray | null] => {
750
+ const [x, y] = separateStation({
751
+ predicate: props.predicate,
752
+ convention: props.convention,
753
+ $defs: props.$defs,
754
+ schema: props.schema.items,
755
+ });
756
+ return [
757
+ x !== null
758
+ ? {
759
+ ...props.schema,
760
+ items: x,
761
+ }
762
+ : null,
763
+ y !== null
764
+ ? {
765
+ ...props.schema,
766
+ items: y,
767
+ }
768
+ : null,
769
+ ];
770
+ };
771
+
772
+ const separateObject = (props: {
773
+ $defs: Record<string, ILlmSchema>;
774
+ predicate: (schema: ILlmSchema) => boolean;
775
+ convention: (key: string, type: "llm" | "human") => string;
776
+ schema: ILlmSchema.IObject;
777
+ }): [ILlmSchema.IObject | null, ILlmSchema.IObject | null] => {
778
+ // EMPTY OBJECT
779
+ if (
780
+ Object.keys(props.schema.properties ?? {}).length === 0 &&
781
+ !!props.schema.additionalProperties === false
782
+ )
783
+ return [props.schema, null];
784
+
785
+ const llm = {
786
+ ...props.schema,
787
+ properties: {} as Record<string, ILlmSchema>,
788
+ additionalProperties: props.schema.additionalProperties,
789
+ } satisfies ILlmSchema.IObject;
790
+ const human = {
791
+ ...props.schema,
792
+ properties: {} as Record<string, ILlmSchema>,
793
+ } satisfies ILlmSchema.IObject;
794
+
795
+ for (const [key, value] of Object.entries(props.schema.properties ?? {})) {
796
+ const [x, y] = separateStation({
797
+ predicate: props.predicate,
798
+ convention: props.convention,
799
+ $defs: props.$defs,
800
+ schema: value,
801
+ });
802
+ if (x !== null) llm.properties[key] = x;
803
+ if (y !== null) human.properties[key] = y;
804
+ }
805
+ if (
806
+ typeof props.schema.additionalProperties === "object" &&
807
+ props.schema.additionalProperties !== null
808
+ ) {
809
+ const [dx, dy] = separateStation({
810
+ predicate: props.predicate,
811
+ convention: props.convention,
812
+ $defs: props.$defs,
813
+ schema: props.schema.additionalProperties,
814
+ });
815
+ llm.additionalProperties = dx ?? false;
816
+ human.additionalProperties = dy ?? false;
817
+ }
818
+ return [
819
+ !!Object.keys(llm.properties).length || !!llm.additionalProperties
820
+ ? shrinkRequired(llm)
821
+ : null,
822
+ !!Object.keys(human.properties).length || human.additionalProperties
823
+ ? shrinkRequired(human)
824
+ : null,
825
+ ];
826
+ };
827
+
828
+ const separateReference = (props: {
829
+ predicate: (schema: ILlmSchema) => boolean;
830
+ convention: (key: string, type: "llm" | "human") => string;
831
+ $defs: Record<string, ILlmSchema>;
832
+ schema: ILlmSchema.IReference;
833
+ }): [ILlmSchema.IReference | null, ILlmSchema.IReference | null] => {
834
+ const key: string =
835
+ props.schema.$ref.split("#/$defs/")[1] ??
836
+ props.schema.$ref.split("/").at(-1)!;
837
+ const humanKey: string = props.convention(key, "human");
838
+ const llmKey: string = props.convention(key, "llm");
839
+
840
+ // FIND EXISTING
841
+ if (props.$defs?.[humanKey] || props.$defs?.[llmKey])
842
+ return [
843
+ props.$defs?.[llmKey]
844
+ ? {
845
+ ...props.schema,
846
+ $ref: `#/$defs/${llmKey}`,
847
+ }
848
+ : null,
849
+ props.$defs?.[humanKey]
850
+ ? {
851
+ ...props.schema,
852
+ $ref: `#/$defs/${humanKey}`,
853
+ }
854
+ : null,
855
+ ];
856
+
857
+ // PRE-ASSIGNMENT
858
+ props.$defs![llmKey] = {};
859
+ props.$defs![humanKey] = {};
860
+
861
+ // DO COMPOSE
862
+ const schema: ILlmSchema = props.$defs?.[key]!;
863
+ const [llm, human] = separateStation({
864
+ predicate: props.predicate,
865
+ convention: props.convention,
866
+ $defs: props.$defs,
867
+ schema,
868
+ });
869
+ if (llm !== null) Object.assign(props.$defs[llmKey], llm);
870
+ if (human !== null) Object.assign(props.$defs[humanKey], human);
871
+
872
+ // ONLY ONE
873
+ if (llm === null || human === null) {
874
+ delete props.$defs[llmKey];
875
+ delete props.$defs[humanKey];
876
+ return llm === null ? [null, props.schema] : [props.schema, null];
877
+ }
878
+
879
+ // BOTH OF THEM
880
+ return [
881
+ llm !== null
882
+ ? {
883
+ ...props.schema,
884
+ $ref: `#/$defs/${llmKey}`,
885
+ }
886
+ : null,
887
+ human !== null
888
+ ? {
889
+ ...props.schema,
890
+ $ref: `#/$defs/${humanKey}`,
891
+ }
892
+ : null,
893
+ ];
894
+ };
895
+
896
+ const shrinkRequired = (s: ILlmSchema.IObject): ILlmSchema.IObject => {
897
+ s.required = s.required.filter((key) => s.properties?.[key] !== undefined);
898
+ return s;
899
+ };
900
+ }
901
+
902
+ const validateStrict = (
903
+ schema: OpenApi.IJsonSchema,
904
+ accessor: string,
905
+ ): IJsonSchemaTransformError.IReason[] => {
906
+ const reasons: IJsonSchemaTransformError.IReason[] = [];
907
+ if (OpenApiTypeChecker.isObject(schema)) {
908
+ if (!!schema.additionalProperties)
909
+ reasons.push({
910
+ schema: schema,
911
+ accessor: `${accessor}.additionalProperties`,
912
+ message:
913
+ "LLM does not allow additionalProperties in strict mode, the dynamic key typed object.",
914
+ });
915
+ for (const key of Object.keys(schema.properties ?? {}))
916
+ if (schema.required?.includes(key) === false)
917
+ reasons.push({
918
+ schema: schema,
919
+ accessor: `${accessor}.properties.${key}`,
920
+ message: "LLM does not allow optional properties in strict mode.",
921
+ });
922
+ }
923
+ return reasons;
924
+ };