@nestia/sdk 14.0.0 → 14.0.2

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 (391) hide show
  1. package/README.md +1 -1
  2. package/assets/bundle/distribute/build-sdk.cjs +28 -0
  3. package/assets/bundle/distribute/package.json +7 -3
  4. package/assets/bundle/distribute/tsconfig.json +15 -105
  5. package/lib/INestiaConfig.d.ts +74 -34
  6. package/lib/NestiaSdkApplication.d.ts +60 -0
  7. package/lib/NestiaSdkApplication.js +121 -32
  8. package/lib/NestiaSdkApplication.js.map +1 -1
  9. package/lib/NestiaSwaggerComposer.d.ts +21 -0
  10. package/lib/NestiaSwaggerComposer.js +32 -13
  11. package/lib/NestiaSwaggerComposer.js.map +1 -1
  12. package/lib/analyses/AccessorAnalyzer.d.ts +26 -0
  13. package/lib/analyses/AccessorAnalyzer.js +26 -0
  14. package/lib/analyses/AccessorAnalyzer.js.map +1 -1
  15. package/lib/analyses/ConfigAnalyzer.d.ts +41 -0
  16. package/lib/analyses/ConfigAnalyzer.js +52 -77
  17. package/lib/analyses/ConfigAnalyzer.js.map +1 -1
  18. package/lib/analyses/ImportAnalyzer.d.ts +25 -0
  19. package/lib/analyses/ImportAnalyzer.js +25 -0
  20. package/lib/analyses/ImportAnalyzer.js.map +1 -1
  21. package/lib/analyses/ParameterNameAnalyzer.d.ts +44 -0
  22. package/lib/analyses/ParameterNameAnalyzer.js +63 -0
  23. package/lib/analyses/ParameterNameAnalyzer.js.map +1 -0
  24. package/lib/analyses/PathAnalyzer.d.ts +93 -1
  25. package/lib/analyses/PathAnalyzer.js +160 -23
  26. package/lib/analyses/PathAnalyzer.js.map +1 -1
  27. package/lib/analyses/ReflectControllerAnalyzer.d.ts +32 -0
  28. package/lib/analyses/ReflectControllerAnalyzer.js +24 -1
  29. package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
  30. package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +29 -0
  31. package/lib/analyses/ReflectHttpOperationAnalyzer.js +35 -24
  32. package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
  33. package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.d.ts +31 -0
  34. package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.js +21 -0
  35. package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.js.map +1 -1
  36. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.d.ts +31 -0
  37. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js +143 -23
  38. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js.map +1 -1
  39. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.d.ts +32 -0
  40. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +27 -2
  41. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -1
  42. package/lib/analyses/ReflectMcpOperationAnalyzer.d.ts +29 -0
  43. package/lib/analyses/ReflectMcpOperationAnalyzer.js +35 -11
  44. package/lib/analyses/ReflectMcpOperationAnalyzer.js.map +1 -1
  45. package/lib/analyses/ReflectMetadataAnalyzer.d.ts +47 -0
  46. package/lib/analyses/ReflectMetadataAnalyzer.js +47 -0
  47. package/lib/analyses/ReflectMetadataAnalyzer.js.map +1 -1
  48. package/lib/analyses/ReflectWebSocketOperationAnalyzer.d.ts +29 -0
  49. package/lib/analyses/ReflectWebSocketOperationAnalyzer.js +27 -5
  50. package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -1
  51. package/lib/analyses/SecurityAnalyzer.d.ts +25 -0
  52. package/lib/analyses/SecurityAnalyzer.js +39 -19
  53. package/lib/analyses/SecurityAnalyzer.js.map +1 -1
  54. package/lib/analyses/SwaggerExampleAnalyzer.d.ts +31 -0
  55. package/lib/analyses/SwaggerExampleAnalyzer.js +36 -0
  56. package/lib/analyses/SwaggerExampleAnalyzer.js.map +1 -0
  57. package/lib/analyses/TypedHttpRouteAnalyzer.d.ts +41 -3
  58. package/lib/analyses/TypedHttpRouteAnalyzer.js +196 -172
  59. package/lib/analyses/TypedHttpRouteAnalyzer.js.map +1 -1
  60. package/lib/analyses/TypedMcpRouteAnalyzer.d.ts +29 -0
  61. package/lib/analyses/TypedMcpRouteAnalyzer.js +152 -20
  62. package/lib/analyses/TypedMcpRouteAnalyzer.js.map +1 -1
  63. package/lib/analyses/TypedWebSocketRouteAnalyzer.d.ts +19 -0
  64. package/lib/analyses/TypedWebSocketRouteAnalyzer.js +20 -1
  65. package/lib/analyses/TypedWebSocketRouteAnalyzer.js.map +1 -1
  66. package/lib/decorators/OperationMetadata.d.ts +6 -0
  67. package/lib/decorators/OperationMetadata.js +6 -0
  68. package/lib/decorators/OperationMetadata.js.map +1 -1
  69. package/lib/executable/internal/CommandParser.d.ts +19 -0
  70. package/lib/executable/internal/CommandParser.js +19 -0
  71. package/lib/executable/internal/CommandParser.js.map +1 -1
  72. package/lib/executable/internal/NestiaConfigLoader.d.ts +56 -0
  73. package/lib/executable/internal/NestiaConfigLoader.js +48 -42
  74. package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
  75. package/lib/executable/internal/NestiaSdkCommand.d.ts +60 -0
  76. package/lib/executable/internal/NestiaSdkCommand.js +95 -3
  77. package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
  78. package/lib/executable/internal/NestiaSdkWatcher.d.ts +81 -0
  79. package/lib/executable/internal/NestiaSdkWatcher.js +125 -41
  80. package/lib/executable/internal/NestiaSdkWatcher.js.map +1 -1
  81. package/lib/executable/internal/NestiaSwaggerWatch.d.ts +80 -0
  82. package/lib/executable/internal/NestiaSwaggerWatch.js +308 -0
  83. package/lib/executable/internal/NestiaSwaggerWatch.js.map +1 -0
  84. package/lib/executable/sdk.js +16 -1
  85. package/lib/executable/sdk.js.map +1 -1
  86. package/lib/factories/ExpressionFactory.d.ts +18 -0
  87. package/lib/factories/ExpressionFactory.js +21 -2
  88. package/lib/factories/ExpressionFactory.js.map +1 -1
  89. package/lib/factories/IdentifierFactory.d.ts +24 -0
  90. package/lib/factories/IdentifierFactory.js +24 -0
  91. package/lib/factories/IdentifierFactory.js.map +1 -1
  92. package/lib/factories/LiteralFactory.d.ts +22 -4
  93. package/lib/factories/LiteralFactory.js +33 -11
  94. package/lib/factories/LiteralFactory.js.map +1 -1
  95. package/lib/factories/StatementFactory.d.ts +28 -1
  96. package/lib/factories/StatementFactory.js +28 -1
  97. package/lib/factories/StatementFactory.js.map +1 -1
  98. package/lib/factories/TypeFactory.d.ts +24 -0
  99. package/lib/factories/TypeFactory.js +15 -0
  100. package/lib/factories/TypeFactory.js.map +1 -1
  101. package/lib/generates/CloneGenerator.d.ts +22 -0
  102. package/lib/generates/CloneGenerator.js +26 -5
  103. package/lib/generates/CloneGenerator.js.map +1 -1
  104. package/lib/generates/E2eGenerator.d.ts +19 -0
  105. package/lib/generates/E2eGenerator.js +19 -0
  106. package/lib/generates/E2eGenerator.js.map +1 -1
  107. package/lib/generates/SdkGenerator.d.ts +38 -0
  108. package/lib/generates/SdkGenerator.js +43 -5
  109. package/lib/generates/SdkGenerator.js.map +1 -1
  110. package/lib/generates/SwaggerGenerator.d.ts +36 -6
  111. package/lib/generates/SwaggerGenerator.js +190 -40
  112. package/lib/generates/SwaggerGenerator.js.map +1 -1
  113. package/lib/generates/internal/E2eFileProgrammer.d.ts +19 -0
  114. package/lib/generates/internal/E2eFileProgrammer.js +20 -1
  115. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  116. package/lib/generates/internal/FilePrinter.d.ts +57 -0
  117. package/lib/generates/internal/FilePrinter.js +74 -0
  118. package/lib/generates/internal/FilePrinter.js.map +1 -1
  119. package/lib/generates/internal/ImportDictionary.d.ts +93 -1
  120. package/lib/generates/internal/ImportDictionary.js +103 -2
  121. package/lib/generates/internal/ImportDictionary.js.map +1 -1
  122. package/lib/generates/internal/SdkAliasCollection.d.ts +121 -1
  123. package/lib/generates/internal/SdkAliasCollection.js +132 -11
  124. package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
  125. package/lib/generates/internal/SdkDistributionComposer.d.ts +19 -0
  126. package/lib/generates/internal/SdkDistributionComposer.js +149 -52
  127. package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
  128. package/lib/generates/internal/SdkFileProgrammer.d.ts +18 -0
  129. package/lib/generates/internal/SdkFileProgrammer.js +101 -12
  130. package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
  131. package/lib/generates/internal/SdkHttpCloneProgrammer.d.ts +29 -0
  132. package/lib/generates/internal/SdkHttpCloneProgrammer.js +33 -0
  133. package/lib/generates/internal/SdkHttpCloneProgrammer.js.map +1 -1
  134. package/lib/generates/internal/SdkHttpCloneReferencer.d.ts +19 -0
  135. package/lib/generates/internal/SdkHttpCloneReferencer.js +78 -25
  136. package/lib/generates/internal/SdkHttpCloneReferencer.js.map +1 -1
  137. package/lib/generates/internal/SdkHttpFunctionProgrammer.d.ts +19 -0
  138. package/lib/generates/internal/SdkHttpFunctionProgrammer.js +40 -23
  139. package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
  140. package/lib/generates/internal/SdkHttpNamespaceProgrammer.d.ts +19 -0
  141. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +46 -34
  142. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
  143. package/lib/generates/internal/SdkHttpParameterProgrammer.d.ts +142 -1
  144. package/lib/generates/internal/SdkHttpParameterProgrammer.js +175 -6
  145. package/lib/generates/internal/SdkHttpParameterProgrammer.js.map +1 -1
  146. package/lib/generates/internal/SdkHttpRouteProgrammer.d.ts +20 -0
  147. package/lib/generates/internal/SdkHttpRouteProgrammer.js +36 -32
  148. package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -1
  149. package/lib/generates/internal/SdkHttpSimulationProgrammer.d.ts +38 -0
  150. package/lib/generates/internal/SdkHttpSimulationProgrammer.js +66 -18
  151. package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
  152. package/lib/generates/internal/SdkImportWizard.d.ts +63 -0
  153. package/lib/generates/internal/SdkImportWizard.js +63 -0
  154. package/lib/generates/internal/SdkImportWizard.js.map +1 -1
  155. package/lib/generates/internal/SdkMcpRouteProgrammer.d.ts +17 -2
  156. package/lib/generates/internal/SdkMcpRouteProgrammer.js +72 -24
  157. package/lib/generates/internal/SdkMcpRouteProgrammer.js.map +1 -1
  158. package/lib/generates/internal/SdkPathTemplate.d.ts +36 -0
  159. package/lib/generates/internal/SdkPathTemplate.js +65 -0
  160. package/lib/generates/internal/SdkPathTemplate.js.map +1 -0
  161. package/lib/generates/internal/SdkRouteDirectory.d.ts +10 -0
  162. package/lib/generates/internal/SdkRouteDirectory.js +10 -0
  163. package/lib/generates/internal/SdkRouteDirectory.js.map +1 -1
  164. package/lib/generates/internal/SdkTypeProgrammer.d.ts +54 -1
  165. package/lib/generates/internal/SdkTypeProgrammer.js +111 -27
  166. package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
  167. package/lib/generates/internal/SdkTypeTagProgrammer.d.ts +53 -1
  168. package/lib/generates/internal/SdkTypeTagProgrammer.js +407 -67
  169. package/lib/generates/internal/SdkTypeTagProgrammer.js.map +1 -1
  170. package/lib/generates/internal/SdkWebSocketCloneProgrammer.d.ts +40 -0
  171. package/lib/generates/internal/SdkWebSocketCloneProgrammer.js +149 -142
  172. package/lib/generates/internal/SdkWebSocketCloneProgrammer.js.map +1 -1
  173. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.d.ts +19 -0
  174. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +46 -36
  175. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
  176. package/lib/generates/internal/SdkWebSocketParameterProgrammer.d.ts +114 -1
  177. package/lib/generates/internal/SdkWebSocketParameterProgrammer.js +120 -5
  178. package/lib/generates/internal/SdkWebSocketParameterProgrammer.js.map +1 -1
  179. package/lib/generates/internal/SdkWebSocketRouteProgrammer.d.ts +18 -0
  180. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +75 -33
  181. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
  182. package/lib/generates/internal/SwaggerDescriptionComposer.d.ts +42 -0
  183. package/lib/generates/internal/SwaggerDescriptionComposer.js +44 -1
  184. package/lib/generates/internal/SwaggerDescriptionComposer.js.map +1 -1
  185. package/lib/generates/internal/SwaggerOperationComposer.d.ts +18 -0
  186. package/lib/generates/internal/SwaggerOperationComposer.js +37 -8
  187. package/lib/generates/internal/SwaggerOperationComposer.js.map +1 -1
  188. package/lib/generates/internal/SwaggerOperationParameterComposer.d.ts +40 -1
  189. package/lib/generates/internal/SwaggerOperationParameterComposer.js +230 -25
  190. package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -1
  191. package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +21 -0
  192. package/lib/generates/internal/SwaggerOperationResponseComposer.js +58 -7
  193. package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -1
  194. package/lib/internal/legacy.d.ts +342 -31
  195. package/lib/internal/legacy.js +207 -31
  196. package/lib/internal/legacy.js.map +1 -1
  197. package/lib/structures/INestiaProject.d.ts +10 -0
  198. package/lib/structures/INestiaSdkInput.d.ts +30 -0
  199. package/lib/structures/IOperationMetadata.d.ts +77 -0
  200. package/lib/structures/IReflectController.d.ts +10 -0
  201. package/lib/structures/IReflectHttpOperation.d.ts +10 -0
  202. package/lib/structures/IReflectHttpOperationException.d.ts +13 -2
  203. package/lib/structures/IReflectHttpOperationParameter.d.ts +55 -3
  204. package/lib/structures/IReflectHttpOperationSuccess.d.ts +15 -3
  205. package/lib/structures/IReflectImport.d.ts +10 -0
  206. package/lib/structures/IReflectMcpOperation.d.ts +19 -0
  207. package/lib/structures/IReflectMcpOperationParameter.d.ts +9 -0
  208. package/lib/structures/IReflectOperationError.d.ts +28 -0
  209. package/lib/structures/IReflectOperationError.js +22 -2
  210. package/lib/structures/IReflectOperationError.js.map +1 -1
  211. package/lib/structures/IReflectType.d.ts +9 -0
  212. package/lib/structures/IReflectWebSocketOperation.d.ts +10 -0
  213. package/lib/structures/IReflectWebSocketOperationParameter.d.ts +55 -0
  214. package/lib/structures/ITypedApplication.d.ts +10 -0
  215. package/lib/structures/ITypedHttpRoute.d.ts +18 -0
  216. package/lib/structures/ITypedHttpRouteException.d.ts +13 -1
  217. package/lib/structures/ITypedHttpRouteParameter.d.ts +48 -1
  218. package/lib/structures/ITypedHttpRouteSuccess.d.ts +13 -1
  219. package/lib/structures/ITypedMcpRoute.d.ts +11 -0
  220. package/lib/structures/ITypedWebSocketRoute.d.ts +18 -0
  221. package/lib/transform.d.ts +6 -0
  222. package/lib/transform.js +6 -0
  223. package/lib/transform.js.map +1 -1
  224. package/lib/utils/ArrayUtil.d.ts +31 -1
  225. package/lib/utils/ArrayUtil.js +32 -11
  226. package/lib/utils/ArrayUtil.js.map +1 -1
  227. package/lib/utils/EmittedJavaScriptPatcher.d.ts +20 -0
  228. package/lib/utils/EmittedJavaScriptPatcher.js +65 -46
  229. package/lib/utils/EmittedJavaScriptPatcher.js.map +1 -1
  230. package/lib/utils/FileRetriever.d.ts +29 -0
  231. package/lib/utils/FileRetriever.js +29 -0
  232. package/lib/utils/FileRetriever.js.map +1 -1
  233. package/lib/utils/HttpResponseContentTypeUtil.d.ts +41 -0
  234. package/lib/utils/HttpResponseContentTypeUtil.js +31 -0
  235. package/lib/utils/HttpResponseContentTypeUtil.js.map +1 -1
  236. package/lib/utils/MapUtil.d.ts +64 -1
  237. package/lib/utils/MapUtil.js +24 -3
  238. package/lib/utils/MapUtil.js.map +1 -1
  239. package/lib/utils/PathUtil.d.ts +31 -0
  240. package/lib/utils/PathUtil.js +38 -0
  241. package/lib/utils/PathUtil.js.map +1 -1
  242. package/lib/utils/SdkBundlePath.d.ts +2 -0
  243. package/lib/utils/SdkBundlePath.js +10 -0
  244. package/lib/utils/SdkBundlePath.js.map +1 -0
  245. package/lib/utils/SdkInputFilter.d.ts +31 -0
  246. package/lib/utils/SdkInputFilter.js +115 -0
  247. package/lib/utils/SdkInputFilter.js.map +1 -0
  248. package/lib/utils/SourceFinder.d.ts +45 -0
  249. package/lib/utils/SourceFinder.js +74 -16
  250. package/lib/utils/SourceFinder.js.map +1 -1
  251. package/lib/utils/StringUtil.d.ts +77 -2
  252. package/lib/utils/StringUtil.js +166 -4
  253. package/lib/utils/StringUtil.js.map +1 -1
  254. package/lib/utils/TemporaryDirectory.d.ts +60 -0
  255. package/lib/utils/TemporaryDirectory.js +112 -0
  256. package/lib/utils/TemporaryDirectory.js.map +1 -0
  257. package/lib/utils/TsConfigReader.d.ts +42 -0
  258. package/lib/utils/TsConfigReader.js +98 -14
  259. package/lib/utils/TsConfigReader.js.map +1 -1
  260. package/lib/utils/TtscExecutor.d.ts +23 -1
  261. package/lib/utils/TtscExecutor.js +22 -0
  262. package/lib/utils/TtscExecutor.js.map +1 -1
  263. package/lib/utils/VersioningStrategy.d.ts +39 -2
  264. package/lib/utils/VersioningStrategy.js +46 -13
  265. package/lib/utils/VersioningStrategy.js.map +1 -1
  266. package/lib/validators/TextPlainValidator.d.ts +19 -0
  267. package/lib/validators/TextPlainValidator.js +19 -0
  268. package/lib/validators/TextPlainValidator.js.map +1 -1
  269. package/native/go.mod +1 -1
  270. package/native/go.sum +2 -2
  271. package/native/sdk/register.go +12 -2
  272. package/native/sdk/sdk_http_rules.go +210 -0
  273. package/native/sdk/sdk_metadata_json.go +79 -4
  274. package/native/sdk/sdk_transform.go +1157 -414
  275. package/package.json +8 -6
  276. package/src/INestiaConfig.ts +74 -34
  277. package/src/NestiaSdkApplication.ts +129 -41
  278. package/src/NestiaSwaggerComposer.ts +32 -14
  279. package/src/analyses/AccessorAnalyzer.ts +26 -0
  280. package/src/analyses/ConfigAnalyzer.ts +52 -90
  281. package/src/analyses/ImportAnalyzer.ts +25 -0
  282. package/src/analyses/ParameterNameAnalyzer.ts +75 -0
  283. package/src/analyses/PathAnalyzer.ts +167 -23
  284. package/src/analyses/ReflectControllerAnalyzer.ts +34 -1
  285. package/src/analyses/ReflectHttpOperationAnalyzer.ts +36 -14
  286. package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +31 -0
  287. package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +153 -39
  288. package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +38 -7
  289. package/src/analyses/ReflectMcpOperationAnalyzer.ts +38 -3
  290. package/src/analyses/ReflectMetadataAnalyzer.ts +47 -0
  291. package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +40 -7
  292. package/src/analyses/SecurityAnalyzer.ts +45 -20
  293. package/src/analyses/SwaggerExampleAnalyzer.ts +39 -0
  294. package/src/analyses/TypedHttpRouteAnalyzer.ts +263 -198
  295. package/src/analyses/TypedMcpRouteAnalyzer.ts +180 -20
  296. package/src/analyses/TypedWebSocketRouteAnalyzer.ts +20 -0
  297. package/src/decorators/OperationMetadata.ts +6 -0
  298. package/src/executable/internal/CommandParser.ts +19 -0
  299. package/src/executable/internal/NestiaConfigLoader.ts +66 -50
  300. package/src/executable/internal/NestiaSdkCommand.ts +96 -3
  301. package/src/executable/internal/NestiaSdkWatcher.ts +172 -44
  302. package/src/executable/internal/NestiaSwaggerWatch.ts +359 -0
  303. package/src/executable/sdk.ts +24 -1
  304. package/src/factories/ExpressionFactory.ts +23 -2
  305. package/src/factories/IdentifierFactory.ts +24 -0
  306. package/src/factories/LiteralFactory.ts +51 -13
  307. package/src/factories/StatementFactory.ts +28 -1
  308. package/src/factories/TypeFactory.ts +24 -0
  309. package/src/generates/CloneGenerator.ts +26 -5
  310. package/src/generates/E2eGenerator.ts +19 -0
  311. package/src/generates/SdkGenerator.ts +43 -12
  312. package/src/generates/SwaggerGenerator.ts +229 -46
  313. package/src/generates/internal/E2eFileProgrammer.ts +20 -0
  314. package/src/generates/internal/FilePrinter.ts +71 -0
  315. package/src/generates/internal/ImportDictionary.ts +120 -2
  316. package/src/generates/internal/SdkAliasCollection.ts +144 -15
  317. package/src/generates/internal/SdkDistributionComposer.ts +181 -56
  318. package/src/generates/internal/SdkFileProgrammer.ts +126 -16
  319. package/src/generates/internal/SdkHttpCloneProgrammer.ts +55 -0
  320. package/src/generates/internal/SdkHttpCloneReferencer.ts +97 -23
  321. package/src/generates/internal/SdkHttpFunctionProgrammer.ts +47 -30
  322. package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +53 -64
  323. package/src/generates/internal/SdkHttpParameterProgrammer.ts +295 -13
  324. package/src/generates/internal/SdkHttpRouteProgrammer.ts +37 -31
  325. package/src/generates/internal/SdkHttpSimulationProgrammer.ts +122 -18
  326. package/src/generates/internal/SdkImportWizard.ts +63 -0
  327. package/src/generates/internal/SdkMcpRouteProgrammer.ts +150 -33
  328. package/src/generates/internal/SdkPathTemplate.ts +88 -0
  329. package/src/generates/internal/SdkRouteDirectory.ts +10 -0
  330. package/src/generates/internal/SdkTypeProgrammer.ts +137 -36
  331. package/src/generates/internal/SdkTypeTagProgrammer.ts +536 -78
  332. package/src/generates/internal/SdkWebSocketCloneProgrammer.ts +185 -142
  333. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +62 -68
  334. package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +205 -5
  335. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +89 -48
  336. package/src/generates/internal/SwaggerDescriptionComposer.ts +47 -1
  337. package/src/generates/internal/SwaggerOperationComposer.ts +38 -6
  338. package/src/generates/internal/SwaggerOperationParameterComposer.ts +318 -36
  339. package/src/generates/internal/SwaggerOperationResponseComposer.ts +74 -11
  340. package/src/internal/legacy-augmentation.d.ts +16 -0
  341. package/src/internal/legacy.ts +407 -49
  342. package/src/structures/INestiaProject.ts +10 -0
  343. package/src/structures/INestiaSdkInput.ts +30 -0
  344. package/src/structures/IOperationMetadata.ts +83 -0
  345. package/src/structures/IReflectController.ts +10 -0
  346. package/src/structures/IReflectHttpOperation.ts +10 -0
  347. package/src/structures/IReflectHttpOperationException.ts +17 -2
  348. package/src/structures/IReflectHttpOperationParameter.ts +56 -2
  349. package/src/structures/IReflectHttpOperationSuccess.ts +19 -3
  350. package/src/structures/IReflectImport.ts +10 -0
  351. package/src/structures/IReflectMcpOperation.ts +19 -0
  352. package/src/structures/IReflectMcpOperationParameter.ts +9 -0
  353. package/src/structures/IReflectOperationError.ts +31 -2
  354. package/src/structures/IReflectType.ts +9 -0
  355. package/src/structures/IReflectWebSocketOperation.ts +10 -0
  356. package/src/structures/IReflectWebSocketOperationParameter.ts +55 -0
  357. package/src/structures/ITypedApplication.ts +10 -0
  358. package/src/structures/ITypedHttpRoute.ts +18 -0
  359. package/src/structures/ITypedHttpRouteException.ts +14 -1
  360. package/src/structures/ITypedHttpRouteParameter.ts +48 -1
  361. package/src/structures/ITypedHttpRouteSuccess.ts +14 -1
  362. package/src/structures/ITypedMcpRoute.ts +12 -0
  363. package/src/structures/ITypedWebSocketRoute.ts +18 -0
  364. package/src/transform.ts +6 -0
  365. package/src/utils/ArrayUtil.ts +32 -13
  366. package/src/utils/EmittedJavaScriptPatcher.ts +70 -47
  367. package/src/utils/FileRetriever.ts +29 -0
  368. package/src/utils/HttpResponseContentTypeUtil.ts +41 -0
  369. package/src/utils/MapUtil.ts +68 -3
  370. package/src/utils/PathUtil.ts +38 -0
  371. package/src/utils/SdkBundlePath.ts +11 -0
  372. package/src/utils/SdkInputFilter.ts +108 -0
  373. package/src/utils/SourceFinder.ts +76 -18
  374. package/src/utils/StringUtil.ts +182 -5
  375. package/src/utils/TemporaryDirectory.ts +108 -0
  376. package/src/utils/TsConfigReader.ts +124 -26
  377. package/src/utils/TtscExecutor.ts +23 -1
  378. package/src/utils/VersioningStrategy.ts +51 -16
  379. package/src/validators/TextPlainValidator.ts +19 -0
  380. package/lib/generates/internal/SwaggerReadonlyArrayEmender.d.ts +0 -9
  381. package/lib/generates/internal/SwaggerReadonlyArrayEmender.js +0 -178
  382. package/lib/generates/internal/SwaggerReadonlyArrayEmender.js.map +0 -1
  383. package/lib/validators/HttpHeadersValidator.d.ts +0 -11
  384. package/lib/validators/HttpHeadersValidator.js +0 -15
  385. package/lib/validators/HttpHeadersValidator.js.map +0 -1
  386. package/lib/validators/HttpQueryValidator.d.ts +0 -10
  387. package/lib/validators/HttpQueryValidator.js +0 -14
  388. package/lib/validators/HttpQueryValidator.js.map +0 -1
  389. package/src/generates/internal/SwaggerReadonlyArrayEmender.ts +0 -264
  390. package/src/validators/HttpHeadersValidator.ts +0 -12
  391. package/src/validators/HttpQueryValidator.ts +0 -11
@@ -18,34 +18,40 @@ import { ITypedHttpRoute } from "../structures/ITypedHttpRoute";
18
18
  import { ITypedHttpRouteException } from "../structures/ITypedHttpRouteException";
19
19
  import { ITypedHttpRouteParameter } from "../structures/ITypedHttpRouteParameter";
20
20
  import { ITypedHttpRouteSuccess } from "../structures/ITypedHttpRouteSuccess";
21
+ import { ITypedMcpRoute } from "../structures/ITypedMcpRoute";
21
22
  import { PathUtil } from "../utils/PathUtil";
23
+ import { StringUtil } from "../utils/StringUtil";
22
24
 
25
+ /**
26
+ * Turns reflected HTTP operations into typed routes, one per path, and builds
27
+ * the shared dictionary of the JSON components HTTP and MCP routes use.
28
+ *
29
+ * @evidence contracts/common.md#principled-implementation Each operation's metadata is resolved against its own components and validated by the policy of its position, the routes carry the typed parameters, the success response, and the exceptions, and the dictionary of the routes is built after component names that collide with different definitions are renamed per controller.
30
+ * @evidence contracts/common.md#clear-and-simple-design Two public functions and private collectors for the component rename.
31
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The rename mutates only component definitions owned by analysis; consumers emit resolved structural types rather than modifying foreign cache fields or replacing names in strings.
32
+ * @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
33
+ * efficient algorithms: This namespace groups operations; analyze and routeDictionary own the algorithms.
34
+ * reuse equivalent work: The namespace itself coordinates no completed or in-flight work.
35
+ * bound retention and release resources: The namespace owns no cache, handle or running task.
36
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation TypedHttpRouteAnalyzer analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
37
+ */
23
38
  export namespace TypedHttpRouteAnalyzer {
24
- export const dictionary = (
25
- controllers: IReflectController[],
26
- ): IMetadataDictionary => {
27
- const individual: IMetadataComponents[] = [];
28
- for (const c of controllers)
29
- for (const o of c.operations) {
30
- if (o.protocol !== "http") continue;
31
- if (o.success) individual.push(o.success.components);
32
- for (const p of o.parameters) individual.push(p.components);
33
- for (const e of Object.values(o.exceptions))
34
- individual.push(e.components);
35
- }
36
- const components: MetadataComponents = MetadataComponents.from({
37
- objects: uniqueComponents(individual.flatMap((c) => c.objects)),
38
- arrays: uniqueComponents(individual.flatMap((c) => c.arrays)),
39
- tuples: uniqueComponents(individual.flatMap((c) => c.tuples)),
40
- aliases: uniqueComponents(individual.flatMap((c) => c.aliases)),
41
- });
42
- return components.dictionary;
43
- };
44
-
39
+ /**
40
+ * Returns the typed routes of one operation, one per path, or none when the
41
+ * metadata violates a policy; the violations are pushed to the errors.
42
+ *
43
+ * @evidence contracts/common.md#principled-implementation Each metadata is resolved against its own components and validated with the policy of its position (JSON, query, header, or text), the `@setHeader` and `@assignHeaders` tags become header directives, and the route splits the parameters by category.
44
+ * @evidence contracts/common.md#clear-and-simple-design One function.
45
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The policies come from the validators of the package.
46
+ * @evidence contracts/common.md#meaningful-documentation The comment states the result and the errors.
47
+ * efficient algorithms: Each supplied parameter and exception is cast once, policy validation belongs to MetadataFactory, and route splitting maps only the supplied paths.
48
+ * reuse equivalent work: Independently supplied operation metadata and position-specific validation have no shared completed or in-flight request.
49
+ * bound retention and release resources: Metadata dictionaries and local diagnostics belong to this synchronous operation and its returned routes; no process, handle or persistent history is retained.
50
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation TypedHttpRouteAnalyzer.analyze analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
51
+ */
45
52
  export const analyze = (props: {
46
53
  controller: IReflectController;
47
54
  errors: IReflectOperationError[];
48
- dictionary: IMetadataDictionary;
49
55
  operation: IReflectHttpOperation;
50
56
  paths: string[];
51
57
  }): ITypedHttpRoute[] => {
@@ -54,10 +60,9 @@ export namespace TypedHttpRouteAnalyzer {
54
60
  next: {
55
61
  metadata: IMetadataSchema;
56
62
  components: IMetadataComponents;
57
- validate: MetadataFactory.Validator;
63
+ validate?: MetadataFactory.Validator;
58
64
  },
59
65
  from: string,
60
- escape: boolean,
61
66
  ): MetadataSchema => {
62
67
  const components: MetadataComponents = MetadataComponents.from(
63
68
  next.components,
@@ -66,16 +71,13 @@ export namespace TypedHttpRouteAnalyzer {
66
71
  next.metadata,
67
72
  components.dictionary,
68
73
  );
69
- const metaErrors: MetadataFactory.IError[] = MetadataFactory.validate({
70
- options: {
71
- escape,
72
- constant: true,
73
- absorb: true,
74
- validate: next.validate, // @todo -> CHECK IN TYPIA
75
- },
76
- functor: next.validate, // @todo -> CHECK IN TYPIA
77
- metadata,
78
- });
74
+ const metaErrors: MetadataFactory.IError[] =
75
+ next.validate === undefined
76
+ ? []
77
+ : MetadataFactory.validate({
78
+ functor: next.validate,
79
+ metadata,
80
+ });
79
81
  if (metaErrors.length)
80
82
  errors.push({
81
83
  file: props.controller.file,
@@ -108,28 +110,18 @@ export namespace TypedHttpRouteAnalyzer {
108
110
  example: value.example,
109
111
  examples: value.examples,
110
112
  type: value.type,
111
- metadata: cast(value, `exception (status: ${key})`, true),
113
+ metadata: cast(value, `exception (status: ${key})`),
112
114
  },
113
115
  ]),
114
116
  );
115
117
  const parameters: ITypedHttpRouteParameter[] =
116
118
  props.operation.parameters.map((p) => ({
117
119
  ...p,
118
- metadata: cast(
119
- p,
120
- `parameter (name: ${JSON.stringify(p.name)})`,
121
- p.category === "body" &&
122
- (p.contentType === "application/json" || p.encrypted === true),
123
- ),
120
+ metadata: cast(p, `parameter (name: ${JSON.stringify(p.name)})`),
124
121
  }));
125
122
  const success: ITypedHttpRouteSuccess = {
126
123
  ...props.operation.success,
127
- metadata: cast(
128
- props.operation.success,
129
- "success",
130
- props.operation.success.encrypted ||
131
- props.operation.success.contentType === "application/json",
132
- ),
124
+ metadata: cast(props.operation.success, "success"),
133
125
  setHeaders: props.operation.jsDocTags
134
126
  .filter(
135
127
  (t) =>
@@ -137,18 +129,23 @@ export namespace TypedHttpRouteAnalyzer {
137
129
  t.text[0]!.text &&
138
130
  (t.name === "setHeader" || t.name === "assignHeaders"),
139
131
  )
140
- .map((t) =>
141
- t.name === "setHeader"
132
+ .map((t) => {
133
+ // the words of the first line; the next lines only describe
134
+ const words: string[] = t
135
+ .text![0]!.text.split("\n")[0]!
136
+ .trim()
137
+ .split(/\s+/);
138
+ return t.name === "setHeader"
142
139
  ? {
143
- type: "setter",
144
- source: t.text![0]!.text.split(" ")[0]!.trim(),
145
- target: t.text![0]!.text.split(" ")[1]?.trim(),
140
+ type: "setter" as const,
141
+ source: words[0]!,
142
+ target: words[1],
146
143
  }
147
144
  : {
148
- type: "assigner",
149
- source: t.text![0]!.text,
150
- },
151
- ),
145
+ type: "assigner" as const,
146
+ source: words[0]!,
147
+ };
148
+ }),
152
149
  };
153
150
  if (errors.length) {
154
151
  props.errors.push(...errors);
@@ -159,6 +156,7 @@ export namespace TypedHttpRouteAnalyzer {
159
156
  ({
160
157
  ...props.operation,
161
158
  controller: props.controller,
159
+ key: props.operation.name,
162
160
  path,
163
161
  accessor: [...PathUtil.accessors(path), props.operation.name],
164
162
  exceptions,
@@ -184,8 +182,21 @@ export namespace TypedHttpRouteAnalyzer {
184
182
  );
185
183
  };
186
184
 
185
+ /**
186
+ * Returns the dictionary of the components the routes actually use, after
187
+ * renaming components whose names collide with different definitions.
188
+ *
189
+ * @evidence contracts/common.md#principled-implementation Objects, aliases and recursive arrays/tuples share their emitted accessor-path slots, while finite and object-mediated collections remain kind-specific inline groups. Different semantic classes in one slot receive unique controller-qualified names, and the emitted dictionary follows escaped returns rather than original-only toJSON declarations.
190
+ * @evidence contracts/common.md#clear-and-simple-design One function over private collectors.
191
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Finite partition refinement preserves semantic discriminators and user payloads while component edges reference equivalence classes. Only actual component ordinals are omitted; no foreign name cache or generated text is rewritten.
192
+ * @evidence contracts/common.md#meaningful-documentation The comment states the result and the rename.
193
+ * efficient algorithms: Each refinement round encodes each distinct component body with constant-sized component edges. The partition only splits and stabilizes within the distinct component count, avoiding exponential expansion of shared DAGs.
194
+ * reuse equivalent work: One local partition compares all routes together, reuses graph node colors for shared children and supplies all collision groups; equivalent same-slot definitions reuse one emitted representative.
195
+ * bound retention and release resources: Collected nodes, partitions and visited sets are local to this synchronous call and are released with it; the returned dictionary retains only its reachable emitted representatives.
196
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation TypedHttpRouteAnalyzer.routeDictionary analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
197
+ */
187
198
  export const routeDictionary = (
188
- routes: Array<ITypedHttpRoute>,
199
+ routes: Array<ITypedHttpRoute | ITypedMcpRoute>,
189
200
  ): IMetadataDictionary => {
190
201
  renameDuplicateComponents(routes);
191
202
  const dictionary: IMetadataDictionary = {
@@ -194,20 +205,9 @@ export namespace TypedHttpRouteAnalyzer {
194
205
  arrays: new Map(),
195
206
  tuples: new Map(),
196
207
  };
197
- for (const route of routes) {
198
- for (const p of [
199
- ...route.pathParameters,
200
- ...route.queryParameters,
201
- ...route.headerParameters,
202
- ...(route.queryObject ? [route.queryObject] : []),
203
- ...(route.body ? [route.body] : []),
204
- ...(route.headerObject ? [route.headerObject] : []),
205
- ])
206
- enrollMetadata(dictionary, p.metadata);
207
- for (const e of Object.values(route.exceptions))
208
- enrollMetadata(dictionary, e.metadata);
209
- enrollMetadata(dictionary, route.success.metadata);
210
- }
208
+ for (const route of routes)
209
+ for (const metadata of routeMetadatas(route))
210
+ enrollMetadata(dictionary, metadata);
211
211
  return dictionary;
212
212
  };
213
213
  }
@@ -221,21 +221,51 @@ type ComponentType =
221
221
 
222
222
  interface IComponentEntry {
223
223
  kind: ComponentKind;
224
- route: ITypedHttpRoute;
224
+ route: ITypedHttpRoute | ITypedMcpRoute;
225
225
  signature: string;
226
226
  type: ComponentType;
227
227
  }
228
228
 
229
- const renameDuplicateComponents = (routes: ITypedHttpRoute[]): void => {
229
+ const renameDuplicateComponents = (
230
+ routes: Array<ITypedHttpRoute | ITypedMcpRoute>,
231
+ ): void => {
230
232
  const entries: IComponentEntry[] = [];
231
233
  for (const route of routes)
232
234
  for (const metadata of routeMetadatas(route))
233
235
  collectComponentEntries(entries, route, metadata);
236
+ // Original toJSON definitions participate in semantic comparison but do not
237
+ // become emitted declarations unless another route uses them directly.
238
+ const comparisonEntries: IComponentEntry[] = [];
239
+ for (const route of routes)
240
+ for (const metadata of routeMetadatas(route))
241
+ collectComponentEntries(
242
+ comparisonEntries,
243
+ route,
244
+ metadata,
245
+ createCollectVisited(),
246
+ true,
247
+ );
248
+ const signatures = componentSignatures(comparisonEntries);
249
+ for (const entry of entries) entry.signature = signatures.get(entry.type)!;
234
250
 
235
- const used: Set<string> = new Set(entries.map((e) => e.type!.name));
251
+ const used: Set<string> = new Set(
252
+ entries.map((e) => StringUtil.accessorsOf(e.type.name).join(".")),
253
+ );
236
254
  const groups: Map<string, IComponentEntry[]> = new Map();
237
255
  for (const entry of entries) {
238
- const key: string = `${entry.kind}:${entry.type!.name}`;
256
+ // Named recursive collections also need a declaration to break cycles.
257
+ // Ordinary arrays and tuples remain inline forms without their own slot.
258
+ const slot =
259
+ entry.kind === "objects" ||
260
+ entry.kind === "aliases" ||
261
+ entry.type.recursive
262
+ ? "declarations"
263
+ : entry.kind;
264
+ const name =
265
+ slot === "declarations"
266
+ ? StringUtil.accessorsOf(entry.type.name).join(".")
267
+ : entry.type.name;
268
+ const key: string = `${slot}:${name}`;
239
269
  const group: IComponentEntry[] | undefined = groups.get(key);
240
270
  if (group === undefined) groups.set(key, [entry]);
241
271
  else group.push(entry);
@@ -258,55 +288,100 @@ const renameDuplicateComponents = (routes: ITypedHttpRoute[]): void => {
258
288
  `${prefix}.${oldName}`,
259
289
  );
260
290
  renamed.set(entry.signature, name);
261
- used.add(name);
291
+ used.add(StringUtil.accessorsOf(name).join("."));
262
292
  return name;
263
293
  })();
264
294
  (entry.type as { name: string }).name = next;
265
295
  }
266
296
  }
267
- for (const route of routes)
268
- for (const metadata of routeMetadatas(route))
269
- clearMetadataNameCache(metadata);
270
297
  };
271
298
 
272
- const routeMetadatas = (route: ITypedHttpRoute): MetadataSchema[] => [
273
- ...[
274
- ...route.pathParameters,
275
- ...route.queryParameters,
276
- ...route.headerParameters,
277
- ...(route.queryObject ? [route.queryObject] : []),
278
- ...(route.body ? [route.body] : []),
279
- ...(route.headerObject ? [route.headerObject] : []),
280
- ].map((p) => p.metadata),
281
- ...Object.values(route.exceptions).map((e) => e.metadata),
282
- route.success.metadata,
283
- ];
299
+ const routeMetadatas = (
300
+ route: ITypedHttpRoute | ITypedMcpRoute,
301
+ ): MetadataSchema[] =>
302
+ route.protocol === "mcp"
303
+ ? [route.inputMetadata, route.outputMetadata].filter(
304
+ (m): m is MetadataSchema => m !== undefined,
305
+ )
306
+ : [
307
+ ...[
308
+ ...route.pathParameters,
309
+ ...route.queryParameters,
310
+ ...route.headerParameters,
311
+ ...(route.queryObject ? [route.queryObject] : []),
312
+ ...(route.body ? [route.body] : []),
313
+ ...(route.headerObject ? [route.headerObject] : []),
314
+ ].map((p) => p.metadata),
315
+ ...Object.values(route.exceptions).map((e) => e.metadata),
316
+ route.success.metadata,
317
+ ];
284
318
 
285
319
  const collectComponentEntries = (
286
320
  entries: IComponentEntry[],
287
- route: ITypedHttpRoute,
321
+ route: ITypedHttpRoute | ITypedMcpRoute,
288
322
  metadata: MetadataSchema,
289
323
  visited: ICollectVisited = createCollectVisited(),
324
+ includeOriginal: boolean = false,
290
325
  ): void => {
291
326
  if (visited.schemas.has(metadata)) return;
292
327
  visited.schemas.add(metadata);
293
328
 
294
329
  if (metadata.rest !== null)
295
- collectComponentEntries(entries, route, metadata.rest, visited);
330
+ collectComponentEntries(
331
+ entries,
332
+ route,
333
+ metadata.rest,
334
+ visited,
335
+ includeOriginal,
336
+ );
296
337
  if (metadata.escaped !== null) {
297
- collectComponentEntries(entries, route, metadata.escaped.original, visited);
298
- collectComponentEntries(entries, route, metadata.escaped.returns, visited);
338
+ if (includeOriginal)
339
+ collectComponentEntries(
340
+ entries,
341
+ route,
342
+ metadata.escaped.original,
343
+ visited,
344
+ includeOriginal,
345
+ );
346
+ collectComponentEntries(
347
+ entries,
348
+ route,
349
+ metadata.escaped.returns,
350
+ visited,
351
+ includeOriginal,
352
+ );
299
353
  }
354
+ for (const template of metadata.templates)
355
+ for (const elem of template.row ?? template)
356
+ collectComponentEntries(entries, route, elem, visited, includeOriginal);
300
357
  for (const func of metadata.functions) {
301
358
  for (const p of func.parameters)
302
- collectComponentEntries(entries, route, p.type, visited);
303
- collectComponentEntries(entries, route, func.output, visited);
359
+ collectComponentEntries(entries, route, p.type, visited, includeOriginal);
360
+ collectComponentEntries(
361
+ entries,
362
+ route,
363
+ func.output,
364
+ visited,
365
+ includeOriginal,
366
+ );
304
367
  }
305
368
  for (const set of metadata.sets)
306
- collectComponentEntries(entries, route, set.value, visited);
369
+ collectComponentEntries(
370
+ entries,
371
+ route,
372
+ set.value,
373
+ visited,
374
+ includeOriginal,
375
+ );
307
376
  for (const map of metadata.maps) {
308
- collectComponentEntries(entries, route, map.key, visited);
309
- collectComponentEntries(entries, route, map.value, visited);
377
+ collectComponentEntries(entries, route, map.key, visited, includeOriginal);
378
+ collectComponentEntries(
379
+ entries,
380
+ route,
381
+ map.value,
382
+ visited,
383
+ includeOriginal,
384
+ );
310
385
  }
311
386
  for (const array of metadata.arrays)
312
387
  if (visited.arrays.has(array.type as MetadataArrayType) === false) {
@@ -319,6 +394,7 @@ const collectComponentEntries = (
319
394
  route,
320
395
  (array.type as MetadataArrayType as MetadataArrayType).value,
321
396
  visited,
397
+ includeOriginal,
322
398
  );
323
399
  }
324
400
  for (const tuple of metadata.tuples)
@@ -329,7 +405,7 @@ const collectComponentEntries = (
329
405
  );
330
406
  for (const elem of (tuple.type as MetadataTupleType as MetadataTupleType)
331
407
  .elements)
332
- collectComponentEntries(entries, route, elem, visited);
408
+ collectComponentEntries(entries, route, elem, visited, includeOriginal);
333
409
  }
334
410
  for (const alias of metadata.aliases)
335
411
  if (visited.aliases.has(alias.type as MetadataAliasType) === false) {
@@ -342,6 +418,7 @@ const collectComponentEntries = (
342
418
  route,
343
419
  (alias.type as MetadataAliasType as MetadataAliasType).value,
344
420
  visited,
421
+ includeOriginal,
345
422
  );
346
423
  }
347
424
  for (const obj of metadata.objects)
@@ -352,31 +429,96 @@ const collectComponentEntries = (
352
429
  );
353
430
  for (const p of (obj.type as MetadataObjectType as MetadataObjectType)
354
431
  .properties) {
355
- collectComponentEntries(entries, route, p.key, visited);
356
- collectComponentEntries(entries, route, p.value, visited);
432
+ collectComponentEntries(
433
+ entries,
434
+ route,
435
+ p.key,
436
+ visited,
437
+ includeOriginal,
438
+ );
439
+ collectComponentEntries(
440
+ entries,
441
+ route,
442
+ p.value,
443
+ visited,
444
+ includeOriginal,
445
+ );
357
446
  }
358
447
  }
359
448
  };
360
449
 
361
450
  const componentEntry = <T extends ComponentType>(
362
- route: ITypedHttpRoute,
451
+ route: ITypedHttpRoute | ITypedMcpRoute,
363
452
  kind: ComponentKind,
364
453
  type: T,
365
454
  ): IComponentEntry => ({
366
455
  kind,
367
456
  route,
368
- signature: componentSignature(type),
457
+ signature: "",
369
458
  type,
370
459
  });
371
460
 
372
- const componentSignature = (type: ComponentType): string =>
373
- JSON.stringify(type, (key, value) =>
374
- // `type` is the resolved back-reference attached by
375
- // `MetadataSchema.from`; it closes a cycle on recursive schemas.
376
- // `index` carries the per-route ordinal and is not part of the
377
- // component's identity.
378
- key === "index" || key === "type" ? undefined : value,
379
- );
461
+ /**
462
+ * Refines a finite component graph until no semantic equivalence class splits.
463
+ * Component edges carry class numbers, so shared children are never expanded as
464
+ * trees. Ordinary payloads retain separate object/array representations. Each
465
+ * round preserves the previous partition and can only split its classes; at
466
+ * most the number of distinct components rounds are necessary.
467
+ */
468
+ const componentSignatures = (
469
+ entries: IComponentEntry[],
470
+ ): Map<ComponentType, string> => {
471
+ const kinds = new Map<ComponentType, ComponentKind>();
472
+ for (const entry of entries) kinds.set(entry.type, entry.kind);
473
+ const nodes = [...kinds.keys()];
474
+ let colors = new Map(nodes.map((node) => [node, 0]));
475
+ let classes = nodes.length ? 1 : 0;
476
+ while (nodes.length) {
477
+ const intern = new Map<string, number>();
478
+ const next = new Map<ComponentType, number>();
479
+ for (const node of nodes) {
480
+ const ancestors = new WeakMap<object, number>();
481
+ let depth = 0;
482
+ const encode = (value: unknown, root = false): unknown => {
483
+ if (value === null || typeof value !== "object") return value;
484
+ if (!root && kinds.has(value as ComponentType))
485
+ return ["component", colors.get(value as ComponentType)];
486
+ const position = ancestors.get(value);
487
+ if (position !== undefined) return ["payload-cycle", position];
488
+ ancestors.set(value, depth++);
489
+ const result = Array.isArray(value)
490
+ ? ["array", value.map((child) => encode(child))]
491
+ : [
492
+ "object",
493
+ Object.entries(value)
494
+ .filter(
495
+ ([key, child]) =>
496
+ child !== undefined && !(root && key === "index"),
497
+ )
498
+ .map(([key, child]) => [key, encode(child)]),
499
+ ];
500
+ ancestors.delete(value);
501
+ --depth;
502
+ return result;
503
+ };
504
+ const signature = JSON.stringify([
505
+ colors.get(node),
506
+ kinds.get(node),
507
+ encode(node, true),
508
+ ]);
509
+ let color = intern.get(signature);
510
+ if (color === undefined) {
511
+ color = intern.size;
512
+ intern.set(signature, color);
513
+ }
514
+ next.set(node, color);
515
+ }
516
+ colors = next;
517
+ if (intern.size === classes) break;
518
+ classes = intern.size;
519
+ }
520
+ return new Map(nodes.map((node) => [node, String(colors.get(node))]));
521
+ };
380
522
 
381
523
  const normalizeComponentNamespace = (name: string): string => {
382
524
  const next: string = name.replace(/[^A-Za-z0-9_$]/g, "_");
@@ -384,63 +526,9 @@ const normalizeComponentNamespace = (name: string): string => {
384
526
  };
385
527
 
386
528
  const escapeComponentName = (used: Set<string>, name: string): string =>
387
- used.has(name) ? escapeComponentName(used, `_${name}`) : name;
388
-
389
- const clearMetadataNameCache = (
390
- metadata: MetadataSchema,
391
- visited: WeakSet<MetadataSchema> = new WeakSet(),
392
- ): void => {
393
- if (visited.has(metadata)) return;
394
- visited.add(metadata);
395
- (metadata as unknown as { name_?: string }).name_ = undefined;
396
-
397
- if (metadata.rest !== null) clearMetadataNameCache(metadata.rest, visited);
398
- if (metadata.escaped !== null) {
399
- clearMetadataNameCache(metadata.escaped.original, visited);
400
- clearMetadataNameCache(metadata.escaped.returns, visited);
401
- }
402
- for (const func of metadata.functions) {
403
- for (const p of func.parameters) clearMetadataNameCache(p.type, visited);
404
- clearMetadataNameCache(func.output, visited);
405
- }
406
- for (const set of metadata.sets) {
407
- (set as unknown as { name_?: string }).name_ = undefined;
408
- clearMetadataNameCache(set.value, visited);
409
- }
410
- for (const map of metadata.maps) {
411
- (map as unknown as { name_?: string }).name_ = undefined;
412
- clearMetadataNameCache(map.key, visited);
413
- clearMetadataNameCache(map.value, visited);
414
- }
415
- for (const array of metadata.arrays) {
416
- (array as unknown as { name_?: string }).name_ = undefined;
417
- clearMetadataNameCache(
418
- (array.type as MetadataArrayType as MetadataArrayType).value,
419
- visited,
420
- );
421
- }
422
- for (const tuple of metadata.tuples) {
423
- (tuple as unknown as { name_?: string }).name_ = undefined;
424
- for (const elem of (tuple.type as MetadataTupleType as MetadataTupleType)
425
- .elements)
426
- clearMetadataNameCache(elem, visited);
427
- }
428
- for (const alias of metadata.aliases) {
429
- (alias as unknown as { name_?: string }).name_ = undefined;
430
- clearMetadataNameCache(
431
- (alias.type as MetadataAliasType as MetadataAliasType).value,
432
- visited,
433
- );
434
- }
435
- for (const obj of metadata.objects) {
436
- (obj as unknown as { name_?: string }).name_ = undefined;
437
- for (const p of (obj.type as MetadataObjectType as MetadataObjectType)
438
- .properties) {
439
- clearMetadataNameCache(p.key, visited);
440
- clearMetadataNameCache(p.value, visited);
441
- }
442
- }
443
- };
529
+ used.has(StringUtil.accessorsOf(name).join("."))
530
+ ? escapeComponentName(used, `_${name}`)
531
+ : name;
444
532
 
445
533
  interface ICollectVisited {
446
534
  aliases: WeakSet<MetadataAliasType>;
@@ -458,27 +546,6 @@ const createCollectVisited = (): ICollectVisited => ({
458
546
  tuples: new WeakSet<MetadataTupleType>(),
459
547
  });
460
548
 
461
- const uniqueComponents = <T extends { name: string }>(input: T[]): T[] => {
462
- const dict: Record<string, T> = {};
463
- for (const elem of input) {
464
- const oldbie: T | undefined = dict[elem.name];
465
- if (oldbie === undefined) dict[elem.name] = elem;
466
- else if (
467
- elem.name.includes(".") ||
468
- componentScore(oldbie) < componentScore(elem)
469
- )
470
- dict[elem.name] = elem;
471
- }
472
- return Object.values(dict);
473
- };
474
-
475
- const componentScore = (input: unknown): number =>
476
- JSON.stringify(input, (key, value) =>
477
- // Resolved-reference back-edges close cycles on recursive schemas;
478
- // skip them when scoring component "richness".
479
- key === "type" ? undefined : value,
480
- ).length;
481
-
482
549
  const enrollMetadata = (
483
550
  dictionary: IMetadataDictionary,
484
551
  metadata: MetadataSchema,
@@ -490,9 +557,11 @@ const enrollMetadata = (
490
557
  if (metadata.rest !== null)
491
558
  enrollMetadata(dictionary, metadata.rest, visited);
492
559
  if (metadata.escaped !== null) {
493
- enrollMetadata(dictionary, metadata.escaped.original, visited);
494
560
  enrollMetadata(dictionary, metadata.escaped.returns, visited);
495
561
  }
562
+ for (const template of metadata.templates)
563
+ for (const elem of template.row ?? template)
564
+ enrollMetadata(dictionary, elem, visited);
496
565
  for (const func of metadata.functions) {
497
566
  for (const p of func.parameters)
498
567
  enrollMetadata(dictionary, p.type, visited);
@@ -542,17 +611,13 @@ const enroll = <
542
611
  dict: Map<string, T>,
543
612
  elem: T,
544
613
  ): boolean => {
614
+ // Collision refinement established equivalence for every remaining same-name
615
+ // entry in this kind; selecting another representative cannot add meaning.
545
616
  const oldbie: T | undefined = dict.get(elem.name);
546
617
  if (oldbie === elem) return false;
547
618
  if (oldbie === undefined) {
548
619
  dict.set(elem.name, elem);
549
620
  return true;
550
- } else if (
551
- elem.name.includes(".") ||
552
- componentScore(oldbie) < componentScore(elem)
553
- ) {
554
- dict.set(elem.name, elem);
555
- return true;
556
621
  }
557
622
  return false;
558
623
  };