@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
@@ -4,85 +4,206 @@ import path from "path";
4
4
 
5
5
  import { INestiaConfig } from "../../INestiaConfig";
6
6
 
7
+ /**
8
+ * Composes the npm package of the SDK in the distribution directory.
9
+ *
10
+ * @evidence contracts/common.md#principled-implementation The namespace copies the bundle, fills its paths in, and installs the dependencies at the versions the project uses.
11
+ * @evidence contracts/common.md#clear-and-simple-design One public function and the private steps.
12
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Each filesystem step resolves against the distribution directory; no process-global directory or foreign method is changed.
13
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
14
+ * @evidence contracts/portability.md#os-neutral-implementation Native paths use path.relative/path.join and generated paths use slash separators. npm receives an argument vector and an explicit cwd. POSIX launches npm directly; Windows launches the npm-cli.js shipped beside the first npm.cmd on PATH through Node because a cmd shim itself requires shell interpretation. A nonstandard Windows npm shim lacking that adjacent npm installation is rejected explicitly.
15
+ */
7
16
  export namespace SdkDistributionComposer {
17
+ /**
18
+ * Prepares the distribution package once: files, paths, and dependencies, and
19
+ * does nothing when the package is already configured.
20
+ *
21
+ * @evidence contracts/common.md#principled-implementation The package counts as configured when it holds `@nestia/fetcher`, which is installed last with its peers, so an interrupted setup runs again. The caller directory is captured once, and every output path and package-manager cwd is explicit.
22
+ * @evidence contracts/common.md#clear-and-simple-design One function of sequential steps.
23
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts No process-global directory is changed, so independent compositions retain their own destinations.
24
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
25
+ * @evidence contracts/portability.md#os-neutral-implementation Existence of the two package files is the filesystem's own answer, and the bundle files are copied over any file of the same name in a distribution directory that is not yet configured, so an interrupted setup repeats the copy.
26
+ */
8
27
  export const compose = async (props: {
9
28
  config: INestiaConfig;
10
29
  mcp: boolean;
11
30
  websocket: boolean;
12
31
  }) => {
13
- if (!fs.existsSync(props.config.distribute!))
14
- await fs.promises.mkdir(props.config.distribute!, { recursive: true });
15
-
16
32
  const root: string = process.cwd();
33
+ const directory: string = path.resolve(props.config.distribute!);
17
34
  const output: string = path.resolve(props.config.output!);
18
- process.chdir(props.config.distribute!);
19
- try {
20
- if (await configured()) return;
21
-
22
- // COPY FILES
23
- console.log("Composing SDK distribution environments...");
24
- for (const file of await fs.promises.readdir(BUNDLE))
25
- await fs.promises.copyFile(`${BUNDLE}/${file}`, file);
35
+ await fs.promises.mkdir(directory, { recursive: true });
36
+ if (await configured(directory)) return;
26
37
 
27
- // CONFIGURE PATHS
28
- for (const file of ["package.json", "tsconfig.json"])
29
- await replace({ root, output })(file);
38
+ console.log("Composing SDK distribution environments...");
39
+ for (const file of await fs.promises.readdir(BUNDLE))
40
+ await fs.promises.copyFile(
41
+ path.join(BUNDLE, file),
42
+ path.join(directory, file),
43
+ );
44
+ for (const file of ["package.json", "tsconfig.json"])
45
+ await replace({ root, output, directory })(file);
30
46
 
31
- // INSTALL PACKAGES
32
- const v: IDependencies = await dependencies({
33
- websocket: props.websocket,
34
- });
35
- execute("npm install --save-dev rimraf");
36
- execute(`npm install --save @nestia/fetcher@${v.version}`);
37
- execute(`npm install --save typia@${v.typia}`);
38
- if (props.mcp && v.mcp !== undefined)
39
- execute(`npm install --save @modelcontextprotocol/sdk@${v.mcp}`);
40
- if (props.websocket && v.tgrid !== undefined)
41
- execute(`npm install --save tgrid@${v.tgrid}`);
42
- execute("npx typia setup --manager npm");
43
- } finally {
44
- process.chdir(root);
45
- }
47
+ // Compile with ttsc, which applies typia's transform; typia no longer has
48
+ // a setup command. Install each dependency kind together so an interrupted
49
+ // setup cannot mark @nestia/fetcher configured before its runtime peers.
50
+ const v: IDependencies = await dependencies({
51
+ root,
52
+ websocket: props.websocket,
53
+ });
54
+ execute(directory, [
55
+ "install",
56
+ "--save-dev",
57
+ "rimraf",
58
+ `ttsc@${v.ttsc}`,
59
+ `typescript@${v.typescript}`,
60
+ ]);
61
+ execute(directory, [
62
+ "install",
63
+ "--save",
64
+ `@nestia/fetcher@${v.version}`,
65
+ `typia@${v.typia}`,
66
+ ...(props.mcp && v.mcp !== undefined
67
+ ? [`@modelcontextprotocol/sdk@${v.mcp}`]
68
+ : []),
69
+ ...(props.websocket && v.tgrid !== undefined ? [`tgrid@${v.tgrid}`] : []),
70
+ ]);
46
71
  };
47
72
 
48
- const configured = async (): Promise<boolean> =>
49
- ["package.json", "tsconfig.json"].every(fs.existsSync) &&
73
+ const configured = async (directory: string): Promise<boolean> =>
74
+ ["package.json", "tsconfig.json"].every((file) =>
75
+ fs.existsSync(path.join(directory, file)),
76
+ ) &&
50
77
  (await (async () => {
51
78
  const content = JSON.parse(
52
- await fs.promises.readFile("package.json", "utf8"),
79
+ await fs.promises.readFile(
80
+ path.join(directory, "package.json"),
81
+ "utf8",
82
+ ),
53
83
  );
54
84
  return !!content.dependencies?.["@nestia/fetcher"];
55
85
  })());
56
86
 
57
- const execute = (command: string) => {
58
- console.log(` - ${command}`);
59
- cp.execSync(command, { stdio: "ignore" });
87
+ const execute = (cwd: string, args: string[]): void => {
88
+ console.log(` - npm ${args.join(" ")}`);
89
+ if (process.platform !== "win32")
90
+ cp.execFileSync("npm", args, { cwd, stdio: "ignore" });
91
+ else {
92
+ // Windows cannot execute npm.cmd without cmd.exe. Launch the JavaScript
93
+ // entry point installed beside that shim instead, so dependency ranges
94
+ // and paths never pass through a shell's metacharacter interpretation.
95
+ const directories = (process.env.PATH ?? "").split(path.delimiter);
96
+ const directory = directories.find((entry) =>
97
+ fs.existsSync(path.join(entry, "npm.cmd")),
98
+ );
99
+ const cli =
100
+ directory === undefined
101
+ ? undefined
102
+ : [
103
+ path.join(directory, "node_modules/npm/bin/npm-cli.js"),
104
+ path.resolve(directory, "../npm/bin/npm-cli.js"),
105
+ ].find((entry) => fs.existsSync(entry));
106
+ if (cli === undefined)
107
+ throw new Error(
108
+ "Unable to locate npm's JavaScript entry point beside npm.cmd on PATH.",
109
+ );
110
+ cp.execFileSync(process.execPath, [cli, ...args], {
111
+ cwd,
112
+ stdio: "ignore",
113
+ });
114
+ }
60
115
  };
61
116
 
62
117
  const replace =
63
- (props: { root: string; output: string }) =>
118
+ (props: { root: string; output: string; directory: string }) =>
64
119
  async (file: string): Promise<void> => {
65
120
  const relative = (from: string) => (to: string) =>
66
121
  path.relative(from, to).split("\\").join("/");
67
- const root: string = relative(process.cwd())(props.root);
68
- const output: string = relative(process.cwd())(props.output);
69
- const current: string = relative(props.root)(process.cwd());
70
-
71
- const content: string = await fs.promises.readFile(file, "utf8");
122
+ const root: string = relative(props.directory)(props.root);
123
+ const output: string = relative(props.directory)(props.output);
124
+ const current: string = relative(props.root)(props.directory);
125
+ const replacements: Record<string, string> = { root, output, current };
126
+ const location: string = path.join(props.directory, file);
127
+ const content: unknown = JSON.parse(
128
+ await fs.promises.readFile(location, "utf8"),
129
+ );
130
+ const substitute = (value: unknown): unknown => {
131
+ if (typeof value === "string")
132
+ return value.replace(
133
+ /\$\{(root|output|current)\}/g,
134
+ (_match, key: string) => replacements[key]!,
135
+ );
136
+ if (Array.isArray(value)) return value.map(substitute);
137
+ if (value !== null && typeof value === "object")
138
+ return Object.fromEntries(
139
+ Object.entries(value).map(([key, element]) => [
140
+ key,
141
+ substitute(element),
142
+ ]),
143
+ );
144
+ return value;
145
+ };
72
146
  await fs.promises.writeFile(
73
- file,
74
- content
75
- .split("${root}")
76
- .join(root)
77
- .split("${output}")
78
- .join(output)
79
- .split("${current}")
80
- .join(current),
147
+ location,
148
+ JSON.stringify(substitute(content), null, 2) + "\n",
81
149
  "utf8",
82
150
  );
83
151
  };
84
152
 
153
+ /**
154
+ * The version of a package the project installed, exactly: the staged package
155
+ * must run the typia, and compile with the ttsc and TypeScript, the project
156
+ * itself uses, with the tgrid and MCP SDK its WebSocket and MCP functions
157
+ * import. `@nestia/sdk`'s own specifier is only the fallback, and a
158
+ * workspace's `catalog:` one names no version npm could install.
159
+ */
160
+ const installed = (
161
+ root: string,
162
+ name: string,
163
+ fallback: string | undefined,
164
+ ): string | undefined =>
165
+ manifestVersion(root, name) ??
166
+ (fallback !== undefined && fallback.startsWith("catalog:") === false
167
+ ? fallback
168
+ : undefined);
169
+
170
+ /**
171
+ * The version in the manifest of the package as installed. Not every package
172
+ * exports its `package.json`, as tgrid does not, and a subpath export may map
173
+ * it to a nested manifest of no name, as `@modelcontextprotocol/sdk` maps it
174
+ * to `dist/cjs/package.json`; so the manifest is the nearest `package.json`
175
+ * naming the package, at or above what the request resolves to.
176
+ */
177
+ const manifestVersion = (root: string, name: string): string | undefined => {
178
+ for (const request of [`${name}/package.json`, name]) {
179
+ let file: string;
180
+ try {
181
+ file = require.resolve(request, { paths: [root, __dirname] });
182
+ } catch {
183
+ continue;
184
+ }
185
+ for (let directory: string = path.dirname(file); ; ) {
186
+ try {
187
+ const json: { name?: unknown; version?: unknown } = JSON.parse(
188
+ fs.readFileSync(path.join(directory, "package.json"), "utf8"),
189
+ );
190
+ if (
191
+ json.name === name &&
192
+ typeof json.version === "string" &&
193
+ json.version.length !== 0
194
+ )
195
+ return json.version;
196
+ } catch {}
197
+ const parent: string = path.dirname(directory);
198
+ if (parent === directory) break;
199
+ directory = parent;
200
+ }
201
+ }
202
+ return undefined;
203
+ };
204
+
85
205
  const dependencies = async (opts: {
206
+ root: string;
86
207
  websocket: boolean;
87
208
  }): Promise<IDependencies> => {
88
209
  const content: string = await fs.promises.readFile(
@@ -98,20 +219,22 @@ export namespace SdkDistributionComposer {
98
219
  ...json.devDependencies,
99
220
  ...json.dependencies,
100
221
  };
101
- const required = (key: "version" | "typia"): string => {
102
- const value: string | undefined =
103
- key === "version" ? json.version : dependencies[key];
222
+ const required = (key: string, value: string | undefined): string => {
104
223
  if (typeof value !== "string" || value.length === 0)
105
224
  throw new Error(
106
225
  `Unable to resolve ${key} version for SDK distribution.`,
107
226
  );
108
227
  return value;
109
228
  };
229
+ const version = (name: string): string | undefined =>
230
+ installed(opts.root, name, dependencies[name]);
110
231
  return {
111
- version: required("version"),
112
- typia: required("typia"),
113
- tgrid: opts.websocket ? dependencies.tgrid : undefined,
114
- mcp: dependencies["@modelcontextprotocol/sdk"],
232
+ version: required("@nestia/fetcher", json.version),
233
+ typia: required("typia", version("typia")),
234
+ ttsc: required("ttsc", version("ttsc")),
235
+ typescript: required("typescript", version("typescript")),
236
+ tgrid: opts.websocket ? version("tgrid") : undefined,
237
+ mcp: version("@modelcontextprotocol/sdk"),
115
238
  };
116
239
  };
117
240
  }
@@ -119,6 +242,8 @@ export namespace SdkDistributionComposer {
119
242
  interface IDependencies {
120
243
  version: string;
121
244
  typia: string;
245
+ ttsc: string;
246
+ typescript: string;
122
247
  tgrid: string | undefined;
123
248
  mcp: string | undefined;
124
249
  }
@@ -1,4 +1,4 @@
1
- import { type Node, factory } from "@ttsc/factory";
1
+ import { type Node, SyntaxKind, factory } from "@ttsc/factory";
2
2
  import fs from "fs";
3
3
 
4
4
  import { INestiaProject } from "../../structures/INestiaProject";
@@ -7,6 +7,7 @@ import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
7
7
  import { ITypedMcpRoute } from "../../structures/ITypedMcpRoute";
8
8
  import { ITypedWebSocketRoute } from "../../structures/ITypedWebSocketRoute";
9
9
  import { MapUtil } from "../../utils/MapUtil";
10
+ import { StringUtil } from "../../utils/StringUtil";
10
11
  import { FilePrinter } from "./FilePrinter";
11
12
  import { ImportDictionary } from "./ImportDictionary";
12
13
  import { SdkHttpRouteProgrammer } from "./SdkHttpRouteProgrammer";
@@ -14,10 +15,28 @@ import { SdkMcpRouteProgrammer } from "./SdkMcpRouteProgrammer";
14
15
  import { SdkRouteDirectory } from "./SdkRouteDirectory";
15
16
  import { SdkWebSocketRouteProgrammer } from "./SdkWebSocketRouteProgrammer";
16
17
 
18
+ /**
19
+ * Writes the functional part of the SDK.
20
+ *
21
+ * @evidence contracts/common.md#principled-implementation The namespace builds the directory tree of the routes by accessor and prints one `index.ts` per directory.
22
+ * @evidence contracts/common.md#clear-and-simple-design One public function and two private helpers.
23
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The tree follows the accessors of the routes.
24
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
25
+ * @evidence contracts/portability.md#os-neutral-implementation Node mkdir creates native directories from the configured output and analyzed identifier accessors; ImportDictionary separately renders relative module specifiers with forward slashes. No filesystem case equivalence is inferred from route names.
26
+ */
17
27
  export namespace SdkFileProgrammer {
18
28
  /* ---------------------------------------------------------
19
29
  CONSTRUCTOR
20
30
  --------------------------------------------------------- */
31
+ /**
32
+ * Writes the `functional` tree of the SDK from the routes' accessors.
33
+ *
34
+ * @evidence contracts/common.md#principled-implementation A route lands in the directory of its accessor without the last segment, and each directory exports its children as namespaces.
35
+ * @evidence contracts/common.md#clear-and-simple-design One tree build and one recursive writer.
36
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The order of routes is the analysis order.
37
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
38
+ * @evidence contracts/portability.md#os-neutral-implementation The recursive writer passes output paths to Node fs and FilePrinter, which accept the slash suffixes on Windows and POSIX. Accessor analysis supplies valid namespace names; module specifier spelling remains the importer’s separate responsibility.
39
+ */
21
40
  export const generate = async (app: ITypedApplication): Promise<void> => {
22
41
  // CONSTRUCT FOLDER TREE
23
42
  const root: SdkRouteDirectory = new SdkRouteDirectory(null, "functional");
@@ -70,22 +89,75 @@ export namespace SdkFileProgrammer {
70
89
  statements.push(FilePrinter.enter());
71
90
 
72
91
  // ITERATE ROUTES
73
- const importer: ImportDictionary = new ImportDictionary(
74
- `${outDir}/index.ts`,
75
- );
76
- directory.routes.forEach((route, i) => {
77
- if (!(project.config.clone === true && route.protocol === "http"))
78
- importer.declarations(route.imports);
79
- statements.push(
80
- ...(route.protocol === "http"
81
- ? SdkHttpRouteProgrammer.write(project)(importer)(route)
82
- : route.protocol === "websocket"
83
- ? SdkWebSocketRouteProgrammer.write(project)(importer)(route)
84
- : SdkMcpRouteProgrammer.write(project)(importer)(route)),
92
+ const write = (locals: Map<AnyRoute, string>) => {
93
+ const importer: ImportDictionary = new ImportDictionary(
94
+ `${outDir}/index.ts`,
85
95
  );
86
- if (i !== directory.routes.length - 1)
87
- statements.push(FilePrinter.enter());
88
- });
96
+ const output: Node[] = [];
97
+ directory.routes.forEach((route, i) => {
98
+ if (!(project.config.clone === true && route.protocol === "http"))
99
+ importer.declarations(route.imports);
100
+ const local: string | undefined = locals.get(route);
101
+ const target: AnyRoute =
102
+ local === undefined ? route : { ...route, name: local };
103
+ const written: Node[] =
104
+ target.protocol === "http"
105
+ ? SdkHttpRouteProgrammer.write(project)(importer)(target)
106
+ : target.protocol === "websocket"
107
+ ? SdkWebSocketRouteProgrammer.write(project)(importer)(target)
108
+ : SdkMcpRouteProgrammer.write(project)(importer)(target);
109
+ if (local !== undefined) {
110
+ written.forEach(unexport);
111
+ written.push(
112
+ factory.createExportDeclaration(
113
+ undefined,
114
+ false,
115
+ factory.createNamedExports([
116
+ factory.createExportSpecifier(false, local, route.name),
117
+ ]),
118
+ undefined,
119
+ ),
120
+ );
121
+ }
122
+ output.push(...written);
123
+ if (i !== directory.routes.length - 1)
124
+ output.push(FilePrinter.enter());
125
+ });
126
+ return { importer, statements: output };
127
+ };
128
+
129
+ // A route's function and namespace are declared in the module scope,
130
+ // where the file's imports and the globals its bodies reference live
131
+ // too. A route named like one of them shadows it for the whole file, or
132
+ // conflicts with the import, so the SDK would not compile (#1647); a
133
+ // method named `tags` whose path parameter is typed with `tags.Format`
134
+ // is enough. Its public name cannot change, so it is declared under a
135
+ // local one and exported as itself.
136
+ let file = write(new Map());
137
+ const scope: Set<string> = new Set([
138
+ ...file.importer.locals(),
139
+ ...MODULE_GLOBALS,
140
+ ]);
141
+ const shadowing: AnyRoute[] = directory.routes.filter((r) =>
142
+ scope.has(r.name),
143
+ );
144
+ if (shadowing.length !== 0) {
145
+ // each local name distinct from the scope, the routes, and the other
146
+ // locals
147
+ const taken: string[] = [
148
+ ...scope,
149
+ ...directory.routes.map((r) => r.name),
150
+ ];
151
+ const locals: Map<AnyRoute, string> = new Map();
152
+ for (const route of shadowing) {
153
+ const local: string = StringUtil.escapeDuplicate(taken)(route.name);
154
+ taken.push(local);
155
+ locals.set(route, local);
156
+ }
157
+ file = write(locals);
158
+ }
159
+ const importer: ImportDictionary = file.importer;
160
+ statements.push(...file.statements);
89
161
 
90
162
  // FINALIZE THE CONTENT
91
163
  if (directory.routes.length !== 0)
@@ -109,3 +181,41 @@ export namespace SdkFileProgrammer {
109
181
  });
110
182
  };
111
183
  }
184
+
185
+ type AnyRoute = ITypedHttpRoute | ITypedWebSocketRoute | ITypedMcpRoute;
186
+
187
+ /**
188
+ * Globals the generated route bodies reference, and names TypeScript reserves
189
+ * in a module's top-level scope: `Promise` in one with async functions, and
190
+ * `require` and `exports` in a CommonJS one.
191
+ */
192
+ const MODULE_GLOBALS: string[] = [
193
+ "Array",
194
+ "Error",
195
+ "JSON",
196
+ "Object",
197
+ "Promise",
198
+ "ReadableStream",
199
+ "String",
200
+ "URLSearchParams",
201
+ "encodeURIComponent",
202
+ "exports",
203
+ "require",
204
+ "undefined",
205
+ ];
206
+
207
+ /** Drops the `export` modifier of a route's function or namespace. */
208
+ const unexport = (node: Node): void => {
209
+ const declaration = node as {
210
+ kind: string;
211
+ modifiers?: Array<{ kind: string; token?: string }>;
212
+ };
213
+ if (
214
+ (declaration.kind === "FunctionDeclaration" ||
215
+ declaration.kind === "ModuleDeclaration") &&
216
+ declaration.modifiers !== undefined
217
+ )
218
+ declaration.modifiers = declaration.modifiers.filter(
219
+ (m) => m.token !== SyntaxKind.ExportKeyword,
220
+ );
221
+ };
@@ -15,13 +15,42 @@ import { FilePrinter } from "./FilePrinter";
15
15
  import { ImportDictionary } from "./ImportDictionary";
16
16
  import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
17
17
 
18
+ /**
19
+ * Composes the DTO declarations of the HTTP routes.
20
+ *
21
+ * @evidence contracts/common.md#principled-implementation The namespace turns each named object, alias and recursive collection into a declaration, placed in a tree of modules by its dotted name.
22
+ * @evidence contracts/common.md#clear-and-simple-design One declaration-tree operation dispatches object, alias and recursive collection bodies through their owning writers.
23
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Implicit object and alias names are not declared; native-marked recursive collections supply named declarations so recursive references have a definition.
24
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
25
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation SdkHttpCloneProgrammer composes SDK syntax, identifiers or import bindings; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
26
+ */
18
27
  export namespace SdkHttpCloneProgrammer {
28
+ /**
29
+ * A module of the declaration tree: its name, its children, and the writer of
30
+ * its own declaration.
31
+ *
32
+ * @evidence contracts/common.md#principled-implementation A module without a writer only holds children.
33
+ * @evidence contracts/common.md#clear-and-simple-design A three-member record.
34
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
35
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
36
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation SdkHttpCloneProgrammer.IModule composes SDK syntax, identifiers or import bindings; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
37
+ */
19
38
  export interface IModule {
20
39
  name: string;
21
40
  children: Map<string, IModule>;
22
41
  programmer: null | ((importer: ImportDictionary) => Node);
23
42
  }
24
43
 
44
+ /**
45
+ * Returns the declaration tree of the application's named types, keyed by
46
+ * their top-level name.
47
+ *
48
+ * @evidence contracts/common.md#principled-implementation Named objects and aliases are registered, and implicit names are skipped. Recursive arrays and tuples also need declarations: each writes one collection body whose nested uses are named references. Finite and object-mediated collections stay inline.
49
+ * @evidence contracts/common.md#clear-and-simple-design Four collection loops feed the same declaration tree, so all named forms share namespace and import decisions.
50
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The implicit test is the shared definition.
51
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
52
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation SdkHttpCloneProgrammer.write composes SDK syntax, identifiers or import bindings; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
53
+ */
25
54
  export const write = (app: ITypedApplication): Map<string, IModule> => {
26
55
  // COMPOSE THE DICTIONARY
27
56
  const dict: Map<string, IModule> = new Map();
@@ -39,6 +68,32 @@ export namespace SdkHttpCloneProgrammer {
39
68
  name: k,
40
69
  programmer: (importer) => writeAlias(app.project)(importer)(v),
41
70
  });
71
+ for (const [k, v] of app.collection.arrays.entries())
72
+ if (v.recursive)
73
+ prepare({
74
+ dict,
75
+ name: k,
76
+ programmer: (importer) =>
77
+ factory.createTypeAliasDeclaration(
78
+ [factory.createModifier(SyntaxKind.ExportKeyword)],
79
+ StringUtil.accessorsOf(k).at(-1)!,
80
+ [],
81
+ SdkTypeProgrammer.write_array_type(app.project)(importer)(v),
82
+ ),
83
+ });
84
+ for (const [k, v] of app.collection.tuples.entries())
85
+ if (v.recursive)
86
+ prepare({
87
+ dict,
88
+ name: k,
89
+ programmer: (importer) =>
90
+ factory.createTypeAliasDeclaration(
91
+ [factory.createModifier(SyntaxKind.ExportKeyword)],
92
+ StringUtil.accessorsOf(k).at(-1)!,
93
+ [],
94
+ SdkTypeProgrammer.write_tuple_type(app.project)(importer)(v),
95
+ ),
96
+ });
42
97
  return dict;
43
98
  };
44
99