@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
@@ -8,7 +8,25 @@ import { SwaggerDescriptionComposer } from "./SwaggerDescriptionComposer";
8
8
  import { SwaggerOperationParameterComposer } from "./SwaggerOperationParameterComposer";
9
9
  import { SwaggerOperationResponseComposer } from "./SwaggerOperationResponseComposer";
10
10
 
11
+ /**
12
+ * Composes the operation object of a route.
13
+ *
14
+ * @evidence contracts/common.md#principled-implementation The namespace collects tags, security, parameters, and responses.
15
+ * @evidence contracts/common.md#clear-and-simple-design One function.
16
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The document's own tag list is edited only by adding.
17
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
18
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation SwaggerOperationComposer composes OpenAPI data; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
19
+ */
11
20
  export namespace SwaggerOperationComposer {
21
+ /**
22
+ * Returns the operation of a route, registering its tags in the document.
23
+ *
24
+ * @evidence contracts/common.md#principled-implementation The tags are the controller's, the route's, and the `@tag` comments, each registered once with the first description, and the security is merged from the controller, the route, and the `@security` comments.
25
+ * @evidence contracts/common.md#clear-and-simple-design One function.
26
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts A tag's description is never overwritten.
27
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
28
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation SwaggerOperationComposer.compose composes OpenAPI data; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
29
+ */
12
30
  export const compose = (props: {
13
31
  config: Omit<INestiaConfig.ISwaggerConfig, "output">;
14
32
  document: OpenApi.IDocument;
@@ -22,7 +40,7 @@ export namespace SwaggerOperationComposer {
22
40
  ...SwaggerDescriptionComposer.getJsDocTexts({
23
41
  jsDocTags: props.route.jsDocTags,
24
42
  name: "tag",
25
- }).map((t) => t.split(" ")[0]!),
43
+ }).map((t) => t.trim().split(/\s+/)[0]!),
26
44
  ]);
27
45
  if (tags.size) {
28
46
  props.document.tags ??= [];
@@ -33,11 +51,13 @@ export namespace SwaggerOperationComposer {
33
51
  jsDocTags: props.route.jsDocTags,
34
52
  name: "tag",
35
53
  })) {
36
- const [name, ...description] = texts.split(" ");
54
+ // the name is the first word; a tag's text may run over lines
55
+ const name: string = texts.trim().split(/\s+/)[0]!;
56
+ const description: string = texts.trim().substring(name.length).trim();
37
57
  if (description.length)
38
58
  props.document.tags.find(
39
59
  (elem) => elem.name === name,
40
- )!.description ??= description.join(" ");
60
+ )!.description ??= description;
41
61
  }
42
62
  }
43
63
 
@@ -52,8 +72,7 @@ export namespace SwaggerOperationComposer {
52
72
  ? [{}]
53
73
  : tag.text.map((text) => {
54
74
  const line: string[] = text.text
55
- .split(" ")
56
- .filter((s) => s.trim())
75
+ .split(/\s+/)
57
76
  .filter((s) => !!s.length);
58
77
  if (line.length === 0) return {};
59
78
  return {
@@ -79,7 +98,7 @@ export namespace SwaggerOperationComposer {
79
98
  props.route.operationId ??
80
99
  props.config.operationId?.({
81
100
  class: props.route.controller.class.name,
82
- function: props.route.name,
101
+ function: props.route.key,
83
102
  method: props.route.method as "GET",
84
103
  path: props.route.path,
85
104
  }),
@@ -87,6 +106,7 @@ export namespace SwaggerOperationComposer {
87
106
  ...props.route.pathParameters,
88
107
  ...props.route.queryParameters,
89
108
  ...(props.route.queryObject ? [props.route.queryObject] : []),
109
+ ...props.route.headerParameters,
90
110
  ...(props.route.headerObject ? [props.route.headerObject] : []),
91
111
  ]
92
112
  .map((p) =>
@@ -101,6 +121,7 @@ export namespace SwaggerOperationComposer {
101
121
  .flat(),
102
122
  requestBody: writeRequestBody(props),
103
123
  responses: SwaggerOperationResponseComposer.compose({
124
+ config: props.config,
104
125
  schema: props.schema,
105
126
  route: props.route,
106
127
  }),
@@ -108,6 +129,13 @@ export namespace SwaggerOperationComposer {
108
129
  ...(props.route.extensions ?? {}),
109
130
  "x-samchon-accessor": props.route.accessor,
110
131
  "x-samchon-controller": props.route.controller.class.name,
132
+ ...(props.config.additional === true
133
+ ? {
134
+ "x-nestia-method": props.route.method,
135
+ "x-nestia-namespace": props.route.accessor.join("."),
136
+ "x-nestia-jsDocTags": props.route.jsDocTags,
137
+ }
138
+ : {}),
111
139
  };
112
140
  };
113
141
  }
@@ -135,6 +163,8 @@ export namespace SwaggerOperationComposer {
135
163
  * helper across two rules that disagree would trade one defect for another.
136
164
  */
137
165
  const writeRequestBody = (props: {
166
+ config: Omit<INestiaConfig.ISwaggerConfig, "output">;
167
+ document: OpenApi.IDocument;
138
168
  schema: (metadata: MetadataSchema) => OpenApi.IJsonSchema | undefined;
139
169
  route: ITypedHttpRoute;
140
170
  }): OpenApi.IOperation.IRequestBody | undefined => {
@@ -144,6 +174,8 @@ const writeRequestBody = (props: {
144
174
  );
145
175
  if (schema === undefined) return undefined;
146
176
  return SwaggerOperationParameterComposer.body({
177
+ config: props.config,
178
+ document: props.document,
147
179
  schema,
148
180
  jsDocTags: props.route.jsDocTags,
149
181
  parameter: props.route.body,
@@ -1,4 +1,5 @@
1
1
  import { OpenApi } from "@typia/interface";
2
+ import { OpenApiTypeChecker } from "@typia/utils";
2
3
  import { VariadicSingleton } from "tstl";
3
4
  import { IJsDocTagInfo, IJsonSchemaCollection } from "typia";
4
5
 
@@ -6,13 +7,33 @@ import { INestiaConfig } from "../../INestiaConfig";
6
7
  import {
7
8
  JsonSchemasProgrammer,
8
9
  MetadataObjectType,
10
+ MetadataProperty,
9
11
  isRequiredOf,
12
+ isSoleLiteralOf,
10
13
  } from "../../internal/legacy";
11
14
  import { ITypedHttpRouteParameter } from "../../structures/ITypedHttpRouteParameter";
12
15
  import { SwaggerDescriptionComposer } from "./SwaggerDescriptionComposer";
13
- import { SwaggerReadonlyArrayEmender } from "./SwaggerReadonlyArrayEmender";
14
16
 
17
+ /**
18
+ * Composes the parameters and the request body of an operation.
19
+ *
20
+ * @evidence contracts/common.md#principled-implementation The namespace writes each parameter where the router reads it, decomposes a query or headers object into its keys where the format needs it, and fits a body into what Swagger 2.0 can hold.
21
+ * @evidence contracts/common.md#clear-and-simple-design Two public functions over private helpers.
22
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The 2.0 restrictions are applied by dedicated helpers.
23
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
24
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation SwaggerOperationParameterComposer composes OpenAPI data; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
25
+ */
15
26
  export namespace SwaggerOperationParameterComposer {
27
+ /**
28
+ * The inputs of a parameter's composition: the configuration, the document,
29
+ * the route's comment tags, the parameter, and its schema.
30
+ *
31
+ * @evidence contracts/common.md#principled-implementation The record is the argument of every composer.
32
+ * @evidence contracts/common.md#clear-and-simple-design A flat record.
33
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
34
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
35
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation SwaggerOperationParameterComposer.IProps composes OpenAPI data; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
36
+ */
16
37
  export interface IProps<Parameter extends ITypedHttpRouteParameter> {
17
38
  config: Omit<INestiaConfig.ISwaggerConfig, "output">;
18
39
  document: OpenApi.IDocument;
@@ -21,6 +42,15 @@ export namespace SwaggerOperationParameterComposer {
21
42
  parameter: Parameter;
22
43
  }
23
44
 
45
+ /**
46
+ * Returns the parameter objects of a path, query, or header parameter.
47
+ *
48
+ * @evidence contracts/common.md#principled-implementation A query object or a headers object is decomposed into one parameter per property where the format needs it.
49
+ * @evidence contracts/common.md#clear-and-simple-design One dispatch by category.
50
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The category decides the location.
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 SwaggerOperationParameterComposer.compose composes OpenAPI data; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
53
+ */
24
54
  export const compose = (
25
55
  props: IProps<ITypedHttpRouteParameter>,
26
56
  ): OpenApi.IOperation.IParameter[] =>
@@ -32,9 +62,20 @@ export namespace SwaggerOperationParameterComposer {
32
62
  ? query({ ...props, parameter: props.parameter })
33
63
  : header({ ...props, parameter: props.parameter });
34
64
 
65
+ /**
66
+ * Returns the request body of a route, or `undefined`.
67
+ *
68
+ * Swagger 2.0 receives the form a body parameter can hold.
69
+ *
70
+ * @evidence contracts/common.md#principled-implementation The description carries the encryption warning, and the flag is written for the versions that can hold it.
71
+ * @evidence contracts/common.md#clear-and-simple-design One function.
72
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The 2.0 conversion is separate.
73
+ * @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
74
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation SwaggerOperationParameterComposer.body composes OpenAPI data; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
75
+ */
35
76
  export const body = (
36
- props: Omit<IProps<ITypedHttpRouteParameter.IBody>, "config" | "document">,
37
- ): OpenApi.IOperation.IRequestBody => {
77
+ props: IProps<ITypedHttpRouteParameter.IBody>,
78
+ ): OpenApi.IOperation.IRequestBody | undefined => {
38
79
  const description: string | undefined =
39
80
  props.parameter.description ??
40
81
  SwaggerDescriptionComposer.descriptionFromJsDocTag({
@@ -42,7 +83,7 @@ export namespace SwaggerOperationParameterComposer {
42
83
  tag: "param",
43
84
  parameter: props.parameter.name,
44
85
  });
45
- return {
86
+ const output: OpenApi.IOperation.IRequestBody = {
46
87
  description: props.parameter.encrypted
47
88
  ? `${warning.get(!!description)}${description ?? ""}`
48
89
  : description,
@@ -56,6 +97,68 @@ export namespace SwaggerOperationParameterComposer {
56
97
  required: props.parameter.metadata.required,
57
98
  ...(props.parameter.encrypted ? { "x-nestia-encrypted": true } : {}),
58
99
  };
100
+ return props.config.openapi === "2.0"
101
+ ? swaggerV2Body(props, output)
102
+ : output;
103
+ };
104
+
105
+ /**
106
+ * The request body a Swagger 2.0 document can hold.
107
+ *
108
+ * Typia's downgrader refuses what 2.0 has no place for rather than lose it,
109
+ * so one route used to fail the whole document (#1649). A 2.0 body parameter
110
+ * holds only a schema: no example, and no `x-nestia-encrypted` flag, whose
111
+ * warning the description keeps. A form becomes one `formData` parameter per
112
+ * field, which carry neither the body's description nor the form object's own
113
+ * attributes, and are each required or not; so a form keeps only its fields,
114
+ * is required when one of them is, and without fields has no body to list. A
115
+ * `formData` file is one file, never an array, a union, or null, so a field
116
+ * taking several files, or none, is listed as one file, optional unless it
117
+ * requires one ({@link swaggerV2FormField}).
118
+ */
119
+ const swaggerV2Body = (
120
+ props: IProps<ITypedHttpRouteParameter.IBody>,
121
+ body: OpenApi.IOperation.IRequestBody,
122
+ ): OpenApi.IOperation.IRequestBody | undefined => {
123
+ const contentType: string = props.parameter.contentType;
124
+ if (
125
+ contentType !== "multipart/form-data" &&
126
+ contentType !== "application/x-www-form-urlencoded"
127
+ )
128
+ return {
129
+ description: body.description,
130
+ content: { [contentType]: { schema: props.schema } },
131
+ required: body.required,
132
+ };
133
+ const object: OpenApi.IJsonSchema.IObject | undefined = resolveObject(
134
+ props.document,
135
+ props.schema,
136
+ );
137
+ if (
138
+ object === undefined ||
139
+ Object.keys(object.properties ?? {}).length === 0
140
+ )
141
+ return undefined;
142
+ const fields: [string, ISwaggerV2FormField][] = Object.entries(
143
+ object.properties ?? {},
144
+ ).map(([key, value]) => [key, swaggerV2FormField(value)]);
145
+ const required: string[] = (object.required ?? []).filter(
146
+ (key) => fields.find(([name]) => name === key)?.[1].optional !== true,
147
+ );
148
+ return {
149
+ content: {
150
+ [contentType]: {
151
+ schema: {
152
+ type: "object",
153
+ properties: Object.fromEntries(
154
+ fields.map(([key, field]) => [key, field.schema]),
155
+ ),
156
+ required,
157
+ },
158
+ },
159
+ },
160
+ required: required.length !== 0,
161
+ };
59
162
  };
60
163
 
61
164
  const path = (
@@ -103,48 +206,71 @@ export namespace SwaggerOperationParameterComposer {
103
206
  ITypedHttpRouteParameter.IHeaders | ITypedHttpRouteParameter.IQuery
104
207
  >,
105
208
  ): OpenApi.IOperation.IParameter[] => {
209
+ const object: MetadataObjectType | undefined = props.parameter.metadata
210
+ .objects[0]?.type as MetadataObjectType | undefined;
106
211
  const param: OpenApi.IOperation.IParameter = {
107
212
  name: props.parameter.field ?? props.parameter.name,
108
213
  in: props.parameter.category === "query" ? "query" : "header",
109
214
  schema: props.schema,
110
215
  description: parameterDescription(props),
111
- required: props.parameter.metadata.required,
216
+ // An unnamed object's keys are the request's own query keys or headers,
217
+ // so it is mandatory only when one of the keys the document describes
218
+ // is; an object whose described properties are all optional is satisfied
219
+ // when the request sends none of them. A field-named parameter is one
220
+ // key, required as declared.
221
+ required:
222
+ props.parameter.metadata.required &&
223
+ (props.parameter.field !== null ||
224
+ (object?.properties.some(
225
+ (p) => isDescribed(p) && isRequiredOf(p.value),
226
+ ) ??
227
+ true)),
112
228
  example: props.parameter.example,
113
229
  examples: props.parameter.examples,
114
230
  };
231
+ // A field-named parameter is one key, which typia's HTTP rules (#1648)
232
+ // keep atomic, and a query or headers object passed them: one object of
233
+ // statically named atomic or array-of-atomic properties, so each has a
234
+ // name to give its parameter.
235
+ if (props.parameter.field !== null || object === undefined) return [param];
236
+ // `decompose: false` keeps a query object one parameter where the format
237
+ // can say so: OpenAPI 3.x spreads it into its keys with `style: form` and
238
+ // `explode: true`. Swagger 2.0 has no object query parameter, and no
239
+ // format spreads an object into headers, so one parameter would be a key
240
+ // or header no request carries (#1653); those are always decomposed.
115
241
  if (
116
- props.config.decompose === false ||
117
- props.parameter.metadata.objects.length === 0
242
+ props.config.decompose === false &&
243
+ props.parameter.category === "query" &&
244
+ props.config.openapi !== "2.0"
118
245
  )
119
- return [param];
120
- return (
121
- props.parameter.metadata.objects[0]!.type as MetadataObjectType
122
- ).properties
123
- .filter((p) =>
124
- p.jsDocTags.every(
125
- (tag) => tag.name !== "hidden" && tag.name !== "ignore",
126
- ),
127
- )
128
- .map((p) => {
129
- const json: IJsonSchemaCollection = JsonSchemasProgrammer.writeSchemas({
130
- version: "3.1",
131
- metadatas: [p.value],
132
- }) as IJsonSchemaCollection;
133
- SwaggerReadonlyArrayEmender.emend({
134
- components: json.components,
135
- schema: json.schemas[0],
136
- metadata: p.value,
137
- });
138
- if (Object.keys(json.components.schemas ?? {}).length !== 0) {
139
- props.document.components ??= {};
140
- props.document.components.schemas ??= {};
141
- Object.assign(
142
- props.document.components.schemas,
143
- json.components.schemas,
144
- );
145
- }
246
+ return [{ ...param, style: "form", explode: true }];
247
+ // One parameter per property typia's object schema describes, so the
248
+ // decomposed form says what `decompose: false` would say about the object:
249
+ // the property's schema, and in the parameter's own fields its
250
+ // description, deprecation, and share of the object's examples.
251
+ return object.properties
252
+ .filter(isDescribed)
253
+ .map((p): IDecomposedParameter | null => {
254
+ const key: string = String(p.key.constants[0]!.values[0]!.value);
255
+ const json: IJsonSchemaCollection | null =
256
+ JsonSchemasProgrammer.writeProperty({
257
+ version: "3.1",
258
+ metadata: props.parameter.metadata,
259
+ key,
260
+ value: p.value,
261
+ });
262
+ if (json === null) return null;
263
+ // Only what the document lacks: the parameter's own schema already
264
+ // brought every component its properties reach from the native bake.
265
+ // Existing document components take precedence over this copy.
266
+ props.document.components ??= {};
267
+ props.document.components.schemas ??= {};
268
+ for (const [name, schema] of Object.entries(
269
+ json.components.schemas ?? {},
270
+ ))
271
+ props.document.components.schemas[name] ??= schema;
146
272
  return {
147
- name: p.key.constants[0]!.values[0]!.value as string,
273
+ name: key,
148
274
  in: props.parameter.category === "query" ? "query" : "header",
149
275
  schema: json.schemas[0]!,
150
276
  required: isRequiredOf(p.value),
@@ -153,11 +279,167 @@ export namespace SwaggerOperationParameterComposer {
153
279
  jsDocTags: p.jsDocTags,
154
280
  kind: "title",
155
281
  }).description,
282
+ // Swagger 2.0 defines no `deprecated` on a parameter, and the
283
+ // downgrader copies the field through rather than refusing it.
284
+ deprecated:
285
+ props.config.openapi !== "2.0" &&
286
+ p.jsDocTags.some((tag) => tag.name === "deprecated")
287
+ ? true
288
+ : undefined,
289
+ example: memberOf(props.parameter.example, key),
290
+ examples: membersOf(props.parameter.examples, key),
156
291
  };
157
- });
292
+ })
293
+ .filter((p): p is IDecomposedParameter => p !== null);
294
+ };
295
+ }
296
+
297
+ /**
298
+ * A decomposed parameter. OpenAPI 3.0 through 3.2 define `deprecated` on the
299
+ * Parameter Object, which typia's `OpenApi.IOperation.IParameter` does not
300
+ * model; its 3.x downgraders carry the field through unchanged.
301
+ */
302
+ type IDecomposedParameter = OpenApi.IOperation.IParameter & {
303
+ deprecated?: boolean;
304
+ };
305
+
306
+ /**
307
+ * Whether the document can describe a property on its own: it has a literal key
308
+ * to name it, and none of the `@hidden`, `@ignore`, and `@internal` tags
309
+ * typia's object schema drops it for.
310
+ */
311
+ const isDescribed = (p: MetadataProperty): boolean =>
312
+ isSoleLiteralOf(p.key) &&
313
+ p.jsDocTags.every(
314
+ (tag) =>
315
+ tag.name !== "hidden" && tag.name !== "ignore" && tag.name !== "internal",
316
+ );
317
+
318
+ /** A form field as a Swagger 2.0 `formData` parameter holds it. */
319
+ interface ISwaggerV2FormField {
320
+ schema: OpenApi.IJsonSchema;
321
+
322
+ /** Whether a request may leave the field out though its type requires it. */
323
+ optional: boolean;
324
+ }
325
+
326
+ /**
327
+ * A form field as a Swagger 2.0 `formData` parameter can hold it.
328
+ *
329
+ * A 2.0 file is one file: never an array, a union, or null. A field whose value
330
+ * is made of files, a union of files or one of them or null, or an array of
331
+ * those, becomes the one file a request may carry, keeping the field's title,
332
+ * description, and deprecation. A request may then carry none, since the server
333
+ * reads a missing field as null or an empty array, so such a field is not
334
+ * required unless its array requires an item; a plain file is kept as it is.
335
+ */
336
+ const swaggerV2FormField = (
337
+ schema: OpenApi.IJsonSchema,
338
+ ): ISwaggerV2FormField => {
339
+ const file: IFileOf | undefined = fileOf(schema, true);
340
+ if (file === undefined || file.binary === schema)
341
+ return { schema, optional: false };
342
+ const attributes = schema as OpenApi.IJsonSchema.IString;
343
+ return {
344
+ schema: {
345
+ ...file.binary,
346
+ ...(attributes.title !== undefined ? { title: attributes.title } : {}),
347
+ ...(attributes.description !== undefined
348
+ ? { description: attributes.description }
349
+ : {}),
350
+ ...(attributes.deprecated !== undefined
351
+ ? { deprecated: attributes.deprecated }
352
+ : {}),
353
+ },
354
+ optional: file.optional,
158
355
  };
356
+ };
357
+
358
+ interface IFileOf {
359
+ binary: OpenApi.IJsonSchema;
360
+ optional: boolean;
159
361
  }
160
362
 
363
+ /** The file a field's value is made of, if it is made of files only. */
364
+ const fileOf = (
365
+ schema: OpenApi.IJsonSchema,
366
+ top: boolean,
367
+ ): IFileOf | undefined => {
368
+ if (isBinary(schema)) return { binary: schema, optional: false };
369
+ if (OpenApiTypeChecker.isOneOf(schema)) {
370
+ const members: OpenApi.IJsonSchema[] = schema.oneOf.filter(
371
+ (s) => OpenApiTypeChecker.isNull(s) === false,
372
+ );
373
+ const files: Array<IFileOf | undefined> = members.map((s) =>
374
+ fileOf(s, top),
375
+ );
376
+ if (files.length === 0 || files.some((f) => f === undefined))
377
+ return undefined;
378
+ return {
379
+ binary: files[0]!.binary,
380
+ optional:
381
+ members.length !== schema.oneOf.length ||
382
+ files.some((f) => f!.optional),
383
+ };
384
+ }
385
+ if (top && OpenApiTypeChecker.isArray(schema)) {
386
+ const item: IFileOf | undefined = fileOf(schema.items, false);
387
+ // an empty array is a request without the field, unless one file is due
388
+ return item === undefined
389
+ ? undefined
390
+ : { binary: item.binary, optional: (schema.minItems ?? 0) === 0 };
391
+ }
392
+ return undefined;
393
+ };
394
+
395
+ const isBinary = (schema: OpenApi.IJsonSchema): boolean =>
396
+ OpenApiTypeChecker.isString(schema) && schema.format === "binary";
397
+
398
+ /** The object schema `schema` is or refers to, if it is one. */
399
+ const resolveObject = (
400
+ document: OpenApi.IDocument,
401
+ schema: OpenApi.IJsonSchema,
402
+ ): OpenApi.IJsonSchema.IObject | undefined => {
403
+ const visited: Set<string> = new Set();
404
+ while (OpenApiTypeChecker.isReference(schema)) {
405
+ if (visited.has(schema.$ref)) return undefined;
406
+ visited.add(schema.$ref);
407
+ const next: OpenApi.IJsonSchema | undefined =
408
+ document.components?.schemas?.[
409
+ schema.$ref.substring("#/components/schemas/".length)
410
+ ];
411
+ if (next === undefined) return undefined;
412
+ schema = next;
413
+ }
414
+ return OpenApiTypeChecker.isObject(schema) ? schema : undefined;
415
+ };
416
+
417
+ /** The `key` member of an object example, if the example has one. */
418
+ const memberOf = (example: unknown, key: string): unknown =>
419
+ typeof example === "object" &&
420
+ example !== null &&
421
+ Object.prototype.hasOwnProperty.call(example, key)
422
+ ? (example as Record<string, unknown>)[key]
423
+ : undefined;
424
+
425
+ /**
426
+ * Named object examples narrowed to the ones whose value has a `key` member,
427
+ * each an Example Object of that member.
428
+ */
429
+ const membersOf = (
430
+ examples: Record<string, OpenApi.IExample> | undefined,
431
+ key: string,
432
+ ): Record<string, OpenApi.IExample> | undefined => {
433
+ if (examples === undefined) return undefined;
434
+ const entries: [string, OpenApi.IExample][] = Object.entries(examples)
435
+ .map(([name, example]): [string, OpenApi.IExample] => [
436
+ name,
437
+ { ...example, value: memberOf(example.value, key) },
438
+ ])
439
+ .filter(([, example]) => example.value !== undefined);
440
+ return entries.length !== 0 ? Object.fromEntries(entries) : undefined;
441
+ };
442
+
161
443
  const warning = new VariadicSingleton((described: boolean): string => {
162
444
  const summary = "Request body must be encrypted.";
163
445
  const component =