@nestia/sdk 3.10.0 → 3.11.0-dev.20240813

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 (279) hide show
  1. package/lib/NestiaSdkApplication.d.ts +1 -3
  2. package/lib/NestiaSdkApplication.js +138 -136
  3. package/lib/NestiaSdkApplication.js.map +1 -1
  4. package/lib/analyses/ConfigAnalyzer.d.ts +2 -2
  5. package/lib/analyses/ConfigAnalyzer.js +39 -80
  6. package/lib/analyses/ConfigAnalyzer.js.map +1 -1
  7. package/lib/analyses/ExceptionAnalyzer.d.ts +0 -16
  8. package/lib/analyses/ExceptionAnalyzer.js +142 -105
  9. package/lib/analyses/ExceptionAnalyzer.js.map +1 -1
  10. package/lib/analyses/GenericAnalyzer.d.ts +1 -2
  11. package/lib/analyses/GenericAnalyzer.js.map +1 -1
  12. package/lib/analyses/ImportAnalyzer.d.ts +6 -11
  13. package/lib/analyses/ImportAnalyzer.js +70 -42
  14. package/lib/analyses/ImportAnalyzer.js.map +1 -1
  15. package/lib/analyses/ReflectControllerAnalyzer.d.ts +7 -1
  16. package/lib/analyses/ReflectControllerAnalyzer.js +28 -99
  17. package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
  18. package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +6 -2
  19. package/lib/analyses/ReflectHttpOperationAnalyzer.js +72 -152
  20. package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
  21. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.d.ts +15 -0
  22. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js +215 -0
  23. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js.map +1 -0
  24. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.d.ts +15 -0
  25. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +81 -0
  26. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -0
  27. package/lib/analyses/ReflectMetadataAnalyzer.d.ts +1 -3
  28. package/lib/analyses/ReflectMetadataAnalyzer.js +0 -4
  29. package/lib/analyses/ReflectMetadataAnalyzer.js.map +1 -1
  30. package/lib/analyses/ReflectWebSocketOperationAnalyzer.d.ts +6 -2
  31. package/lib/analyses/ReflectWebSocketOperationAnalyzer.js +72 -48
  32. package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -1
  33. package/lib/analyses/TypedHttpRouteAnalyzer.d.ts +15 -0
  34. package/lib/analyses/TypedHttpRouteAnalyzer.js +111 -0
  35. package/lib/analyses/TypedHttpRouteAnalyzer.js.map +1 -0
  36. package/lib/analyses/TypedWebSocketRouteAnalyzer.d.ts +10 -0
  37. package/lib/analyses/TypedWebSocketRouteAnalyzer.js +9 -0
  38. package/lib/analyses/TypedWebSocketRouteAnalyzer.js.map +1 -0
  39. package/lib/decorators/OperationMetadata.d.ts +2 -0
  40. package/lib/decorators/OperationMetadata.js +10 -0
  41. package/lib/decorators/OperationMetadata.js.map +1 -0
  42. package/lib/executable/internal/NestiaConfigLoader.d.ts +1 -1
  43. package/lib/executable/internal/NestiaConfigLoader.js +34 -3
  44. package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
  45. package/lib/executable/internal/NestiaSdkCommand.js +1 -1
  46. package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
  47. package/lib/generates/CloneGenerator.d.ts +0 -5
  48. package/lib/generates/CloneGenerator.js +60 -60
  49. package/lib/generates/CloneGenerator.js.map +1 -1
  50. package/lib/generates/E2eGenerator.d.ts +2 -3
  51. package/lib/generates/E2eGenerator.js +9 -8
  52. package/lib/generates/E2eGenerator.js.map +1 -1
  53. package/lib/generates/OpenAiGenerator.d.ts +2 -4
  54. package/lib/generates/OpenAiGenerator.js +13 -3
  55. package/lib/generates/OpenAiGenerator.js.map +1 -1
  56. package/lib/generates/SdkGenerator.d.ts +4 -4
  57. package/lib/generates/SdkGenerator.js +63 -73
  58. package/lib/generates/SdkGenerator.js.map +1 -1
  59. package/lib/generates/SwaggerGenerator.d.ts +6 -18
  60. package/lib/generates/SwaggerGenerator.js +60 -235
  61. package/lib/generates/SwaggerGenerator.js.map +1 -1
  62. package/lib/generates/internal/E2eFileProgrammer.js +5 -9
  63. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  64. package/lib/generates/internal/SdkAliasCollection.d.ts +6 -4
  65. package/lib/generates/internal/SdkAliasCollection.js +33 -31
  66. package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
  67. package/lib/generates/internal/SdkDistributionComposer.d.ts +4 -1
  68. package/lib/generates/internal/SdkDistributionComposer.js +6 -6
  69. package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
  70. package/lib/generates/internal/SdkFileProgrammer.d.ts +2 -4
  71. package/lib/generates/internal/SdkFileProgrammer.js +6 -6
  72. package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
  73. package/lib/generates/internal/SdkHttpCloneProgrammer.d.ts +0 -12
  74. package/lib/generates/internal/SdkHttpCloneProgrammer.js +142 -97
  75. package/lib/generates/internal/SdkHttpCloneProgrammer.js.map +1 -1
  76. package/lib/generates/internal/SdkHttpFunctionProgrammer.d.ts +4 -3
  77. package/lib/generates/internal/SdkHttpFunctionProgrammer.js +37 -59
  78. package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
  79. package/lib/generates/internal/SdkHttpNamespaceProgrammer.d.ts +4 -3
  80. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +31 -48
  81. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
  82. package/lib/generates/internal/SdkHttpRouteProgrammer.js +7 -3
  83. package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -1
  84. package/lib/generates/internal/SdkHttpSimulationProgrammer.d.ts +4 -3
  85. package/lib/generates/internal/SdkHttpSimulationProgrammer.js +7 -13
  86. package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
  87. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.d.ts +1 -2
  88. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +11 -16
  89. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
  90. package/lib/generates/internal/SdkWebSocketRouteProgrammer.d.ts +1 -2
  91. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +7 -10
  92. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
  93. package/lib/generates/internal/SwaggerDescriptionComposer.d.ts +23 -0
  94. package/lib/generates/internal/SwaggerDescriptionComposer.js +44 -0
  95. package/lib/generates/internal/SwaggerDescriptionComposer.js.map +1 -0
  96. package/lib/generates/internal/SwaggerOperationComposer.d.ts +12 -0
  97. package/lib/generates/internal/SwaggerOperationComposer.js +68 -0
  98. package/lib/generates/internal/SwaggerOperationComposer.js.map +1 -0
  99. package/lib/generates/internal/SwaggerOperationParameterComposer.d.ts +18 -0
  100. package/lib/generates/internal/SwaggerOperationParameterComposer.js +99 -0
  101. package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -0
  102. package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +9 -0
  103. package/lib/generates/internal/SwaggerOperationResponseComposer.js +91 -0
  104. package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -0
  105. package/lib/structures/INestiaProject.d.ts +5 -5
  106. package/lib/structures/INestiaSdkInput.d.ts +20 -0
  107. package/lib/structures/{ISwaggerError.js → INestiaSdkInput.js} +1 -1
  108. package/lib/structures/INestiaSdkInput.js.map +1 -0
  109. package/lib/structures/IReflectApplication.d.ts +6 -0
  110. package/lib/structures/IReflectApplication.js +3 -0
  111. package/lib/structures/IReflectApplication.js.map +1 -0
  112. package/lib/structures/IReflectController.d.ts +3 -5
  113. package/lib/structures/IReflectHttpOperation.d.ts +13 -65
  114. package/lib/structures/IReflectHttpOperationException.d.ts +14 -0
  115. package/lib/structures/IReflectHttpOperationException.js +3 -0
  116. package/lib/structures/IReflectHttpOperationException.js.map +1 -0
  117. package/lib/structures/IReflectHttpOperationParameter.d.ts +35 -0
  118. package/lib/structures/IReflectHttpOperationParameter.js +3 -0
  119. package/lib/structures/IReflectHttpOperationParameter.js.map +1 -0
  120. package/lib/structures/IReflectHttpOperationSuccess.d.ts +15 -0
  121. package/lib/structures/IReflectHttpOperationSuccess.js +3 -0
  122. package/lib/structures/IReflectHttpOperationSuccess.js.map +1 -0
  123. package/lib/structures/IReflectOperationError.d.ts +16 -0
  124. package/lib/structures/IReflectOperationError.js +23 -0
  125. package/lib/structures/IReflectOperationError.js.map +1 -0
  126. package/lib/structures/IReflectType.d.ts +4 -0
  127. package/lib/structures/{IErrorReport.js → IReflectType.js} +1 -1
  128. package/lib/structures/IReflectType.js.map +1 -0
  129. package/lib/structures/IReflectTypeImport.d.ts +4 -0
  130. package/lib/structures/{ISwaggerLazySchema.js → IReflectTypeImport.js} +1 -1
  131. package/lib/structures/IReflectTypeImport.js.map +1 -0
  132. package/lib/structures/IReflectWebSocketOperation.d.ts +8 -9
  133. package/lib/structures/IReflectWebSocketOperationParameter.d.ts +23 -0
  134. package/lib/structures/IReflectWebSocketOperationParameter.js +3 -0
  135. package/lib/structures/IReflectWebSocketOperationParameter.js.map +1 -0
  136. package/lib/structures/ITypedApplication.d.ts +7 -0
  137. package/lib/structures/{INormalizedInput.js → ITypedApplication.js} +1 -1
  138. package/lib/structures/ITypedApplication.js.map +1 -0
  139. package/lib/structures/ITypedHttpRoute.d.ts +14 -42
  140. package/lib/structures/ITypedHttpRouteException.d.ts +10 -0
  141. package/lib/structures/ITypedHttpRouteException.js +3 -0
  142. package/lib/structures/ITypedHttpRouteException.js.map +1 -0
  143. package/lib/structures/ITypedHttpRouteParameter.d.ts +31 -0
  144. package/lib/structures/ITypedHttpRouteParameter.js +3 -0
  145. package/lib/structures/ITypedHttpRouteParameter.js.map +1 -0
  146. package/lib/structures/ITypedHttpRouteSuccess.d.ts +19 -0
  147. package/lib/structures/{ISwaggerLazyProperty.js → ITypedHttpRouteSuccess.js} +1 -1
  148. package/lib/structures/ITypedHttpRouteSuccess.js.map +1 -0
  149. package/lib/structures/ITypedWebSocketRoute.d.ts +8 -44
  150. package/lib/structures/ITypedWebSocketRouteParameter.d.ts +2 -0
  151. package/lib/structures/ITypedWebSocketRouteParameter.js +3 -0
  152. package/lib/structures/ITypedWebSocketRouteParameter.js.map +1 -0
  153. package/lib/transform.d.ts +3 -0
  154. package/lib/transform.js +8 -0
  155. package/lib/transform.js.map +1 -0
  156. package/lib/transformers/IOperationMetadata.d.ts +36 -0
  157. package/lib/transformers/IOperationMetadata.js +3 -0
  158. package/lib/transformers/IOperationMetadata.js.map +1 -0
  159. package/lib/transformers/ISdkTransformerContext.d.ts +7 -0
  160. package/lib/transformers/ISdkTransformerContext.js +3 -0
  161. package/lib/transformers/ISdkTransformerContext.js.map +1 -0
  162. package/lib/transformers/SdkMetadataProgrammer.d.ts +11 -0
  163. package/lib/transformers/SdkMetadataProgrammer.js +159 -0
  164. package/lib/transformers/SdkMetadataProgrammer.js.map +1 -0
  165. package/lib/transformers/SdkTransformer.d.ts +4 -0
  166. package/lib/transformers/SdkTransformer.js +88 -0
  167. package/lib/transformers/SdkTransformer.js.map +1 -0
  168. package/lib/transformers/TextPlainValidator.d.ts +4 -0
  169. package/lib/transformers/TextPlainValidator.js +19 -0
  170. package/lib/transformers/TextPlainValidator.js.map +1 -0
  171. package/lib/utils/StringUtil.d.ts +1 -0
  172. package/lib/utils/StringUtil.js +1 -0
  173. package/lib/utils/StringUtil.js.map +1 -1
  174. package/package.json +8 -8
  175. package/src/NestiaSdkApplication.ts +173 -160
  176. package/src/analyses/ConfigAnalyzer.ts +50 -98
  177. package/src/analyses/ExceptionAnalyzer.ts +142 -142
  178. package/src/analyses/GenericAnalyzer.ts +3 -5
  179. package/src/analyses/ImportAnalyzer.ts +130 -115
  180. package/src/analyses/ReflectControllerAnalyzer.ts +63 -115
  181. package/src/analyses/ReflectHttpOperationAnalyzer.ts +142 -278
  182. package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +319 -0
  183. package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +117 -0
  184. package/src/analyses/ReflectMetadataAnalyzer.ts +1 -18
  185. package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +143 -78
  186. package/src/analyses/TypedHttpRouteAnalyzer.ts +178 -0
  187. package/src/analyses/TypedWebSocketRouteAnalyzer.ts +18 -0
  188. package/src/decorators/OperationMetadata.ts +15 -0
  189. package/src/executable/internal/NestiaConfigLoader.ts +18 -3
  190. package/src/executable/internal/NestiaSdkCommand.ts +1 -4
  191. package/src/generates/CloneGenerator.ts +60 -59
  192. package/src/generates/E2eGenerator.ts +20 -21
  193. package/src/generates/OpenAiGenerator.ts +44 -45
  194. package/src/generates/SdkGenerator.ts +97 -125
  195. package/src/generates/SwaggerGenerator.ts +114 -416
  196. package/src/generates/internal/E2eFileProgrammer.ts +5 -14
  197. package/src/generates/internal/SdkAliasCollection.ts +33 -41
  198. package/src/generates/internal/SdkDistributionComposer.ts +9 -6
  199. package/src/generates/internal/SdkFileProgrammer.ts +11 -14
  200. package/src/generates/internal/SdkHttpCloneProgrammer.ts +142 -142
  201. package/src/generates/internal/SdkHttpFunctionProgrammer.ts +20 -47
  202. package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +245 -275
  203. package/src/generates/internal/SdkHttpRouteProgrammer.ts +7 -7
  204. package/src/generates/internal/SdkHttpSimulationProgrammer.ts +11 -23
  205. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +197 -233
  206. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +5 -15
  207. package/src/generates/internal/{SwaggerDescriptionGenerator.ts → SwaggerDescriptionComposer.ts} +25 -5
  208. package/src/generates/internal/SwaggerOperationComposer.ts +90 -0
  209. package/src/generates/internal/SwaggerOperationParameterComposer.ts +173 -0
  210. package/src/generates/internal/SwaggerOperationResponseComposer.ts +110 -0
  211. package/src/structures/INestiaProject.ts +5 -5
  212. package/src/structures/INestiaSdkInput.ts +25 -0
  213. package/src/structures/IReflectApplication.ts +8 -0
  214. package/src/structures/IReflectController.ts +3 -5
  215. package/src/structures/IReflectHttpOperation.ts +14 -76
  216. package/src/structures/IReflectHttpOperationException.ts +19 -0
  217. package/src/structures/IReflectHttpOperationParameter.ts +81 -0
  218. package/src/structures/IReflectHttpOperationSuccess.ts +22 -0
  219. package/src/structures/IReflectOperationError.ts +26 -0
  220. package/src/structures/IReflectType.ts +4 -0
  221. package/src/structures/IReflectTypeImport.ts +4 -0
  222. package/src/structures/IReflectWebSocketOperation.ts +9 -9
  223. package/src/structures/IReflectWebSocketOperationParameter.ts +38 -0
  224. package/src/structures/ITypedApplication.ts +8 -0
  225. package/src/structures/ITypedHttpRoute.ts +15 -45
  226. package/src/structures/ITypedHttpRouteException.ts +15 -0
  227. package/src/structures/ITypedHttpRouteParameter.ts +41 -0
  228. package/src/structures/ITypedHttpRouteSuccess.ts +22 -0
  229. package/src/structures/ITypedWebSocketRoute.ts +8 -56
  230. package/src/structures/ITypedWebSocketRouteParameter.ts +3 -0
  231. package/src/transform.ts +9 -0
  232. package/src/transformers/IOperationMetadata.ts +38 -0
  233. package/src/transformers/ISdkTransformerContext.ts +8 -0
  234. package/src/transformers/SdkMetadataProgrammer.ts +227 -0
  235. package/src/transformers/SdkTransformer.ts +168 -0
  236. package/src/transformers/TextPlainValidator.ts +17 -0
  237. package/src/utils/StringUtil.ts +3 -0
  238. package/lib/analyses/TypedControllerAnalyzer.d.ts +0 -8
  239. package/lib/analyses/TypedControllerAnalyzer.js +0 -77
  240. package/lib/analyses/TypedControllerAnalyzer.js.map +0 -1
  241. package/lib/analyses/TypedHttpOperationAnalyzer.d.ts +0 -15
  242. package/lib/analyses/TypedHttpOperationAnalyzer.js +0 -263
  243. package/lib/analyses/TypedHttpOperationAnalyzer.js.map +0 -1
  244. package/lib/analyses/TypedWebSocketOperationAnalyzer.d.ts +0 -15
  245. package/lib/analyses/TypedWebSocketOperationAnalyzer.js +0 -226
  246. package/lib/analyses/TypedWebSocketOperationAnalyzer.js.map +0 -1
  247. package/lib/generates/internal/SwaggerDescriptionGenerator.d.ts +0 -14
  248. package/lib/generates/internal/SwaggerDescriptionGenerator.js +0 -33
  249. package/lib/generates/internal/SwaggerDescriptionGenerator.js.map +0 -1
  250. package/lib/generates/internal/SwaggerSchemaGenerator.d.ts +0 -21
  251. package/lib/generates/internal/SwaggerSchemaGenerator.js +0 -289
  252. package/lib/generates/internal/SwaggerSchemaGenerator.js.map +0 -1
  253. package/lib/generates/internal/SwaggerSchemaValidator.d.ts +0 -7
  254. package/lib/generates/internal/SwaggerSchemaValidator.js +0 -191
  255. package/lib/generates/internal/SwaggerSchemaValidator.js.map +0 -1
  256. package/lib/structures/IErrorReport.d.ts +0 -6
  257. package/lib/structures/IErrorReport.js.map +0 -1
  258. package/lib/structures/INormalizedInput.d.ts +0 -19
  259. package/lib/structures/INormalizedInput.js.map +0 -1
  260. package/lib/structures/ISwaggerError.d.ts +0 -6
  261. package/lib/structures/ISwaggerError.js.map +0 -1
  262. package/lib/structures/ISwaggerLazyProperty.d.ts +0 -6
  263. package/lib/structures/ISwaggerLazyProperty.js.map +0 -1
  264. package/lib/structures/ISwaggerLazySchema.d.ts +0 -6
  265. package/lib/structures/ISwaggerLazySchema.js.map +0 -1
  266. package/lib/structures/ITypeTuple.d.ts +0 -5
  267. package/lib/structures/ITypeTuple.js +0 -3
  268. package/lib/structures/ITypeTuple.js.map +0 -1
  269. package/src/analyses/TypedControllerAnalyzer.ts +0 -92
  270. package/src/analyses/TypedHttpOperationAnalyzer.ts +0 -365
  271. package/src/analyses/TypedWebSocketOperationAnalyzer.ts +0 -375
  272. package/src/generates/internal/SwaggerSchemaGenerator.ts +0 -473
  273. package/src/generates/internal/SwaggerSchemaValidator.ts +0 -206
  274. package/src/structures/IErrorReport.ts +0 -6
  275. package/src/structures/INormalizedInput.ts +0 -20
  276. package/src/structures/ISwaggerError.ts +0 -8
  277. package/src/structures/ISwaggerLazyProperty.ts +0 -7
  278. package/src/structures/ISwaggerLazySchema.ts +0 -7
  279. package/src/structures/ITypeTuple.ts +0 -6
@@ -2,311 +2,101 @@ import { OpenApi, OpenApiV3, SwaggerV2 } from "@samchon/openapi";
2
2
  import fs from "fs";
3
3
  import path from "path";
4
4
  import { Singleton } from "tstl";
5
- import ts from "typescript";
6
5
  import typia, { IJsonApplication } from "typia";
7
- import { MetadataCollection } from "typia/lib/factories/MetadataCollection";
8
6
  import { JsonApplicationProgrammer } from "typia/lib/programmers/json/JsonApplicationProgrammer";
7
+ import { Metadata } from "typia/lib/schemas/metadata/Metadata";
9
8
 
10
9
  import { INestiaConfig } from "../INestiaConfig";
11
- import { INestiaProject } from "../structures/INestiaProject";
12
- import { ISwaggerError } from "../structures/ISwaggerError";
13
- import { ISwaggerLazyProperty } from "../structures/ISwaggerLazyProperty";
14
- import { ISwaggerLazySchema } from "../structures/ISwaggerLazySchema";
10
+ import { ITypedApplication } from "../structures/ITypedApplication";
15
11
  import { ITypedHttpRoute } from "../structures/ITypedHttpRoute";
16
- import { ITypedWebSocketRoute } from "../structures/ITypedWebSocketRoute";
12
+ import { ITypedHttpRouteParameter } from "../structures/ITypedHttpRouteParameter";
17
13
  import { FileRetriever } from "../utils/FileRetriever";
18
- import { MapUtil } from "../utils/MapUtil";
19
- import { SwaggerDescriptionGenerator } from "./internal/SwaggerDescriptionGenerator";
20
- import { SwaggerSchemaGenerator } from "./internal/SwaggerSchemaGenerator";
14
+ import { SwaggerOperationComposer } from "./internal/SwaggerOperationComposer";
21
15
 
22
16
  export namespace SwaggerGenerator {
23
- export interface IProps {
24
- config: INestiaConfig.ISwaggerConfig;
25
- checker: ts.TypeChecker;
26
- collection: MetadataCollection;
27
- lazySchemas: Array<ISwaggerLazySchema>;
28
- lazyProperties: Array<ISwaggerLazyProperty>;
29
- errors: ISwaggerError[];
30
- swagger: OpenApi.IDocument;
31
- }
32
-
33
- export const generate =
34
- (project: INestiaProject) =>
35
- async (
36
- routeList: Array<ITypedHttpRoute | ITypedWebSocketRoute>,
37
- ): Promise<void> => {
38
- console.log("Generating Swagger Document");
39
-
40
- // VALIDATE SECURITY
41
- const config = project.config.swagger!;
42
- const httpRoutes: ITypedHttpRoute[] = routeList.filter(
43
- (route): route is ITypedHttpRoute => route.protocol === "http",
44
- ) as ITypedHttpRoute[];
45
- validate_security(config)(httpRoutes);
46
-
47
- // PREPARE ASSETS
48
- const parsed: path.ParsedPath = path.parse(config.output);
49
- const directory: string = path.dirname(parsed.dir);
50
- if (fs.existsSync(directory) === false)
51
- try {
52
- await fs.promises.mkdir(directory);
53
- } catch {}
54
- if (fs.existsSync(directory) === false)
55
- throw new Error(
56
- `Error on NestiaApplication.swagger(): failed to create output directory: ${directory}`,
57
- );
58
-
59
- // COMPOSE SWAGGER DOCUMENT
60
- const location: string = !!parsed.ext
61
- ? path.resolve(config.output)
62
- : path.join(path.resolve(config.output), "swagger.json");
63
- const swagger: OpenApi.IDocument = await compose(project)(routeList);
64
-
65
- // DO GENERATE
66
- const document:
67
- | OpenApi.IDocument
68
- | SwaggerV2.IDocument
69
- | OpenApiV3.IDocument =
70
- config.openapi === "2.0"
71
- ? OpenApi.downgrade(swagger, config.openapi as "2.0")
72
- : config.openapi === "3.0"
73
- ? OpenApi.downgrade(swagger, config.openapi as "3.0")
74
- : swagger;
75
- await fs.promises.writeFile(
76
- location,
77
- !config.beautify
78
- ? JSON.stringify(document)
79
- : JSON.stringify(
80
- document,
81
- null,
82
- typeof config.beautify === "number" ? config.beautify : 2,
83
- ),
84
- "utf8",
17
+ export const generate = async (app: ITypedApplication): Promise<void> => {
18
+ // GET CONFIGURATION
19
+ if (app.project.config.swagger === undefined)
20
+ throw new Error("Swagger configuration is not defined.");
21
+ const config: INestiaConfig.ISwaggerConfig = app.project.config.swagger;
22
+
23
+ // TARGET LOCATION
24
+ const parsed: path.ParsedPath = path.parse(config.output);
25
+ const directory: string = path.dirname(parsed.dir);
26
+ if (fs.existsSync(directory) === false)
27
+ try {
28
+ await fs.promises.mkdir(directory);
29
+ } catch {}
30
+ if (fs.existsSync(directory) === false)
31
+ throw new Error(
32
+ `Error on NestiaApplication.swagger(): failed to create output directory: ${directory}`,
85
33
  );
86
- };
87
-
88
- export const compose =
89
- (project: INestiaProject) =>
90
- async (
91
- routeList: Array<ITypedHttpRoute | ITypedWebSocketRoute>,
92
- ): Promise<OpenApi.IDocument> => {
93
- // VALIDATE SECURITY
94
- const config = project.config.swagger!;
95
- const httpRoutes: ITypedHttpRoute[] = routeList.filter(
96
- (route): route is ITypedHttpRoute => route.protocol === "http",
97
- ) as ITypedHttpRoute[];
98
- validate_security(config)(httpRoutes);
99
-
100
- const collection: MetadataCollection = new MetadataCollection({
101
- replace: MetadataCollection.replace,
102
- });
103
-
104
- // CONSTRUCT SWAGGER DOCUMENTS
105
- const errors: ISwaggerError[] = [];
106
- const lazySchemas: Array<ISwaggerLazySchema> = [];
107
- const lazyProperties: Array<ISwaggerLazyProperty> = [];
108
- const swagger: OpenApi.IDocument = await initialize(config);
109
- const pathDict: Map<
110
- string,
111
- Record<string, OpenApi.IOperation>
112
- > = new Map();
113
-
114
- for (const route of httpRoutes) {
115
- if (route.jsDocTags.find((tag) => tag.name === "internal")) continue;
116
-
117
- const path: Record<string, OpenApi.IOperation> = MapUtil.take(
118
- pathDict,
119
- get_path(route.path, route.parameters),
120
- () => ({}),
121
- );
122
- path[route.method.toLowerCase()] = generate_route({
123
- config,
124
- checker: project.checker,
125
- collection,
126
- lazySchemas,
127
- lazyProperties,
128
- errors,
129
- swagger,
130
- })(route);
131
- }
132
- swagger.paths = {};
133
- for (const [path, routes] of pathDict) swagger.paths[path] = routes;
134
-
135
- // FILL JSON-SCHEMAS
136
- const application: IJsonApplication<"3.1"> =
137
- JsonApplicationProgrammer.write("3.1")(
138
- lazySchemas.map(({ metadata }) => metadata),
139
- ) as IJsonApplication<"3.1">;
140
- swagger.components = {
141
- ...(swagger.components ?? {}),
142
- ...(application.components ?? {}),
143
- };
144
- lazySchemas.forEach(({ schema }, index) => {
145
- Object.assign(schema, application.schemas[index]!);
146
- });
147
- for (const p of lazyProperties)
148
- Object.assign(
149
- p.schema,
150
- (
151
- application.components.schemas?.[
152
- p.object
153
- ] as OpenApi.IJsonSchema.IObject
154
- )?.properties?.[p.property] ?? {},
155
- );
156
-
157
- // CONFIGURE SECURITY
158
- if (config.security) fill_security(config.security, swagger);
159
-
160
- // REPORT ERRORS
161
- if (errors.length) {
162
- for (const e of errors)
163
- console.error(
164
- `${path.relative(process.cwd(), e.route.location)}:${
165
- e.route.controller.name
166
- }.${e.route.name}:${
167
- e.from
168
- } - error TS(@nestia/sdk): invalid type detected.\n\n` +
169
- e.messages.map((m) => ` - ${m}`).join("\n"),
170
- "\n\n",
171
- );
172
- throw new TypeError("Invalid type detected");
173
- }
174
-
175
- // SWAGGER CUSTOMIZER
176
- const customizer = {
177
- at: new Singleton(() => {
178
- const functor: Map<Function, Endpoint> = new Map();
179
- for (const route of httpRoutes) {
180
- const method: OpenApi.Method =
181
- route.method.toLowerCase() as OpenApi.Method;
182
- const path: string = get_path(route.path, route.parameters);
183
- const operation: OpenApi.IOperation | undefined =
184
- swagger.paths?.[path]?.[method];
185
- if (operation === undefined) continue;
186
- functor.set(route.function, {
187
- method,
188
- path,
189
- route: operation,
190
- });
191
- }
192
- return functor;
193
- }),
194
- get: new Singleton(
195
- () =>
196
- (key: Accessor): OpenApi.IOperation | undefined => {
197
- const method: OpenApi.Method =
198
- key.method.toLowerCase() as OpenApi.Method;
199
- const path: string =
200
- "/" +
201
- key.path
202
- .split("/")
203
- .filter((str) => !!str.length)
204
- .map((str) =>
205
- str.startsWith(":") ? `{${str.substring(1)}}` : str,
206
- )
207
- .join("/");
208
- return swagger.paths?.[path]?.[method];
209
- },
210
- ),
211
- };
212
- for (const route of httpRoutes) {
213
- if (
214
- false ===
215
- Reflect.hasMetadata(
216
- "nestia/SwaggerCustomizer",
217
- route.controller.prototype,
218
- route.name,
219
- )
220
- )
221
- continue;
222
-
223
- const path: string = get_path(route.path, route.parameters);
224
- const method: OpenApi.Method =
225
- route.method.toLowerCase() as OpenApi.Method;
226
- const target: OpenApi.IOperation | undefined =
227
- swagger.paths?.[path]?.[method];
228
- if (target === undefined) continue;
229
-
230
- const closure: Function | Function[] = Reflect.getMetadata(
231
- "nestia/SwaggerCustomizer",
232
- route.controller.prototype,
233
- route.name,
234
- );
235
- const array: Function[] = Array.isArray(closure) ? closure : [closure];
236
- for (const fn of array)
237
- fn({
238
- route: target,
239
- method,
240
- path,
241
- swagger,
242
- at: (func: Function) => customizer.at.get().get(func),
243
- get: (accessor: Accessor) => customizer.get.get()(accessor),
244
- });
245
- }
246
- return swagger;
247
- };
248
-
249
- const validate_security =
250
- (config: INestiaConfig.ISwaggerConfig) =>
251
- (routeList: ITypedHttpRoute[]): void | never => {
252
- const securityMap: Map<
253
- string,
254
- { scheme: OpenApi.ISecurityScheme; scopes: Set<string> }
255
- > = new Map();
256
- for (const [key, value] of Object.entries(config.security ?? {}))
257
- securityMap.set(key, {
258
- scheme: emend_security(value),
259
- scopes:
260
- value.type === "oauth2"
261
- ? new Set([
262
- ...Object.keys(value.flows.authorizationCode?.scopes ?? {}),
263
- ...Object.keys(value.flows.implicit?.scopes ?? {}),
264
- ...Object.keys(value.flows.password?.scopes ?? {}),
265
- ...Object.keys(value.flows.clientCredentials?.scopes ?? {}),
266
- ])
267
- : new Set(),
268
- });
269
-
270
- const validate =
271
- (reporter: (str: string) => void) =>
272
- (key: string, scopes: string[]) => {
273
- const security = securityMap.get(key);
274
- if (security === undefined)
275
- return reporter(`target security scheme "${key}" does not exists.`);
276
- else if (scopes.length === 0) return;
277
- else if (security.scheme.type !== "oauth2")
278
- return reporter(
279
- `target security scheme "${key}" is not "oauth2" type, but you've configured the scopes.`,
280
- );
281
- for (const s of scopes)
282
- if (security.scopes.has(s) === false)
283
- reporter(
284
- `target security scheme "${key}" does not have a specific scope "${s}".`,
285
- );
286
- };
287
-
288
- const violations: string[] = [];
289
- for (const route of routeList)
290
- for (const record of route.security)
291
- for (const [key, scopes] of Object.entries(record))
292
- validate((str) =>
293
- violations.push(
294
- ` - ${str} (${route.controller.name}.${route.name}() at "${route.location}")`,
295
- ),
296
- )(key, scopes);
34
+ const location: string = !!parsed.ext
35
+ ? path.resolve(config.output)
36
+ : path.join(path.resolve(config.output), "swagger.json");
37
+
38
+ // COMPOSE SWAGGER DOCUMENT
39
+ const document: OpenApi.IDocument = compose({
40
+ config,
41
+ routes: app.routes.filter((route) => route.protocol === "http"),
42
+ document: await initialize(config),
43
+ });
44
+ const specified:
45
+ | OpenApi.IDocument
46
+ | SwaggerV2.IDocument
47
+ | OpenApiV3.IDocument =
48
+ config.openapi === "2.0"
49
+ ? OpenApi.downgrade(document, config.openapi as "2.0")
50
+ : config.openapi === "3.0"
51
+ ? OpenApi.downgrade(document, config.openapi as "3.0")
52
+ : document;
53
+ await fs.promises.writeFile(
54
+ location,
55
+ !config.beautify
56
+ ? JSON.stringify(specified)
57
+ : JSON.stringify(
58
+ specified,
59
+ null,
60
+ typeof config.beautify === "number" ? config.beautify : 2,
61
+ ),
62
+ "utf8",
63
+ );
64
+ };
297
65
 
298
- if (violations.length)
299
- throw new Error(
300
- `Error on NestiaApplication.swagger(): invalid security specification. Check your "nestia.config.ts" file's "swagger.security" property, or each controller methods.\n` +
301
- `\n` +
302
- `List of violations:\n` +
303
- violations.join("\n"),
304
- );
305
- };
66
+ export const compose = (props: {
67
+ config: INestiaConfig.ISwaggerConfig;
68
+ routes: ITypedHttpRoute[];
69
+ document: OpenApi.IDocument;
70
+ }): OpenApi.IDocument => {
71
+ // GATHER METADATA
72
+ const metadatas: Metadata[] = props.routes
73
+ .filter((r) => r.protocol === "http")
74
+ .map((r) => [
75
+ r.success.metadata,
76
+ ...r.parameters.map((p) => p.metadata),
77
+ ...Object.values(r.exceptions).map((e) => e.metadata),
78
+ ])
79
+ .flat()
80
+ .filter((m) => m.size() !== 0);
81
+
82
+ // COMPOSE JSON SCHEMAS
83
+ const json: IJsonApplication = JsonApplicationProgrammer.write("3.1")(
84
+ metadatas,
85
+ ) as IJsonApplication;
86
+ const dict: WeakMap<Metadata, OpenApi.IJsonSchema> = new WeakMap();
87
+ json.schemas.forEach((schema, i) => dict.set(metadatas[i], schema));
88
+ const schema = (metadata: Metadata): OpenApi.IJsonSchema | undefined =>
89
+ dict.get(metadata);
90
+
91
+ // COMPOSE DOCUMENT
92
+ const document: OpenApi.IDocument = props.document;
93
+ document.components.schemas ??= {};
94
+ Object.assign(document.components.schemas, json.components.schemas);
95
+ document.paths = writePaths({ ...props, schema });
96
+
97
+ return document;
98
+ };
306
99
 
307
- /* ---------------------------------------------------------
308
- INITIALIZERS
309
- --------------------------------------------------------- */
310
100
  export const initialize = async (
311
101
  config: INestiaConfig.ISwaggerConfig,
312
102
  ): Promise<OpenApi.IDocument> => {
@@ -378,134 +168,42 @@ export namespace SwaggerGenerator {
378
168
  paths: {},
379
169
  components: {
380
170
  schemas: {},
171
+ securitySchemes: config.security,
381
172
  },
382
173
  tags: config.tags ?? [],
383
174
  "x-samchon-emended": true,
384
175
  };
385
176
  };
386
177
 
387
- function get_path(
388
- path: string,
389
- parameters: ITypedHttpRoute.IParameter[],
390
- ): string {
391
- const filtered: ITypedHttpRoute.IParameter[] = parameters.filter(
392
- (param) => param.category === "param" && !!param.field,
178
+ const writePaths = (props: {
179
+ config: INestiaConfig.ISwaggerConfig;
180
+ document: OpenApi.IDocument;
181
+ schema: (metadata: Metadata) => OpenApi.IJsonSchema | undefined;
182
+ routes: ITypedHttpRoute[];
183
+ }): Record<string, OpenApi.IPath> => {
184
+ const output: Record<string, OpenApi.IPath> = {};
185
+ for (const r of props.routes) {
186
+ const path: string = getPath(r);
187
+ output[path] ??= {};
188
+ output[path][r.method.toLowerCase() as "get"] =
189
+ SwaggerOperationComposer.compose({
190
+ ...props,
191
+ route: r,
192
+ });
193
+ }
194
+ return output;
195
+ };
196
+
197
+ const getPath = (route: {
198
+ path: string;
199
+ parameters: ITypedHttpRouteParameter[];
200
+ }): string => {
201
+ let str: string = route.path;
202
+ const filtered: ITypedHttpRouteParameter.IParam[] = route.parameters.filter(
203
+ (param) => param.category === "param",
393
204
  );
394
205
  for (const param of filtered)
395
- path = path.replace(`:${param.field}`, `{${param.field}}`);
396
- return path;
397
- }
398
-
399
- export const generate_route =
400
- (props: IProps) =>
401
- (route: ITypedHttpRoute): OpenApi.IOperation => {
402
- // FIND REQUEST BODY
403
- const body = route.parameters.find((param) => param.category === "body");
404
-
405
- // CONSTRUCT SUMMARY & DESCRIPTION
406
- const getJsDocTexts = (name: string): string[] =>
407
- route.jsDocTags
408
- .filter(
409
- (tag) =>
410
- tag.name === name &&
411
- tag.text &&
412
- tag.text.find(
413
- (elem) => elem.kind === "text" && elem.text.length,
414
- ) !== undefined,
415
- )
416
- .map((tag) => tag.text!.find((elem) => elem.kind === "text")!.text);
417
- const { summary, description } = SwaggerDescriptionGenerator.generate({
418
- description: route.description,
419
- jsDocTags: route.jsDocTags,
420
- kind: "summary",
421
- });
422
- const deprecated = route.jsDocTags.find(
423
- (tag) => tag.name === "deprecated",
424
- );
425
-
426
- // CONSTRUCT TAGS
427
- const tagSet: Set<string> = new Set([
428
- ...route.swaggerTags,
429
- ...getJsDocTexts("tag").map((tag) => tag.split(" ")[0]),
430
- ]);
431
- props.swagger.tags ??= [];
432
- for (const tag of tagSet)
433
- if (props.swagger.tags!.find((elem) => elem.name === tag) === undefined)
434
- props.swagger.tags!.push({ name: tag });
435
- for (const texts of getJsDocTexts("tag")) {
436
- const [name, ...description] = texts.split(" ");
437
- if (description.length)
438
- props.swagger.tags!.find(
439
- (elem) => elem.name === name,
440
- )!.description ??= description.join(" ");
441
- }
442
-
443
- // FINALIZE
444
- return {
445
- deprecated: deprecated ? true : undefined,
446
- tags: [...tagSet],
447
- operationId:
448
- route.operationId ??
449
- props.config.operationId?.({
450
- class: route.controller.name,
451
- function: route.name,
452
- method: route.method as "GET",
453
- path: route.path,
454
- }),
455
- parameters: route.parameters
456
- .filter((param) => param.category !== "body")
457
- .map((param) => SwaggerSchemaGenerator.parameter(props)(route)(param))
458
- .flat(),
459
- requestBody: body
460
- ? SwaggerSchemaGenerator.body(props)(route)(body)
461
- : undefined,
462
- responses: SwaggerSchemaGenerator.response(props)(route),
463
- summary,
464
- description,
465
- security: route.security.length ? route.security : undefined,
466
- ...(props.config.additional === true
467
- ? {
468
- "x-nestia-namespace": [
469
- ...route.path
470
- .split("/")
471
- .filter((str) => str.length && str[0] !== ":"),
472
- route.name,
473
- ].join("."),
474
- "x-nestia-jsDocTags": route.jsDocTags,
475
- "x-nestia-method": route.method,
476
- }
477
- : {}),
478
- };
479
- };
480
-
481
- function fill_security(
482
- security: Required<INestiaConfig.ISwaggerConfig>["security"],
483
- swagger: OpenApi.IDocument,
484
- ): void {
485
- swagger.components.securitySchemes = {};
486
- for (const [key, value] of Object.entries(security))
487
- swagger.components.securitySchemes[key] = emend_security(value);
488
- }
489
-
490
- function emend_security(
491
- input: OpenApi.ISecurityScheme,
492
- ): OpenApi.ISecurityScheme {
493
- if (input.type === "apiKey")
494
- return {
495
- ...input,
496
- in: input.in ?? "header",
497
- name: input.name ?? "Authorization",
498
- };
499
- return input;
500
- }
501
- }
502
-
503
- interface Accessor {
504
- method: string;
505
- path: string;
506
- }
507
- interface Endpoint {
508
- method: string;
509
- path: string;
510
- route: OpenApi.IOperation;
206
+ str = str.replace(`:${param.field}`, `{${param.field}}`);
207
+ return str;
208
+ };
511
209
  }
@@ -7,7 +7,6 @@ import { FilePrinter } from "./FilePrinter";
7
7
  import { ImportDictionary } from "./ImportDictionary";
8
8
  import { SdkAliasCollection } from "./SdkAliasCollection";
9
9
  import { SdkImportWizard } from "./SdkImportWizard";
10
- import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
11
10
 
12
11
  export namespace E2eFileProgrammer {
13
12
  export const generate =
@@ -19,9 +18,9 @@ export namespace E2eFileProgrammer {
19
18
  );
20
19
  if (project.config.clone !== true)
21
20
  for (const tuple of route.imports)
22
- for (const instance of tuple[1])
21
+ for (const instance of tuple.instances)
23
22
  importer.internal({
24
- file: tuple[0],
23
+ file: tuple.file,
25
24
  type: true,
26
25
  instance,
27
26
  });
@@ -91,7 +90,7 @@ export namespace E2eFileProgrammer {
91
90
  SdkImportWizard.typia(importer),
92
91
  ),
93
92
  )("random"),
94
- [getTypeName(project)(importer)(headers)],
93
+ [SdkAliasCollection.name(headers.type)],
95
94
  undefined,
96
95
  ),
97
96
  ),
@@ -117,7 +116,7 @@ export namespace E2eFileProgrammer {
117
116
  IdentifierFactory.access(
118
117
  ts.factory.createIdentifier(SdkImportWizard.typia(importer)),
119
118
  )("random"),
120
- [getTypeName(project)(importer)(p)],
119
+ [SdkAliasCollection.name(p.type)],
121
120
  undefined,
122
121
  ),
123
122
  ),
@@ -151,7 +150,7 @@ export namespace E2eFileProgrammer {
151
150
  "output",
152
151
  undefined,
153
152
  project.config.propagate !== true &&
154
- route.output.typeName === "void"
153
+ route.success.type.name === "void"
155
154
  ? undefined
156
155
  : SdkAliasCollection.output(project)(importer)(route),
157
156
  ts.factory.createAwaitExpression(caller),
@@ -168,11 +167,3 @@ export namespace E2eFileProgrammer {
168
167
 
169
168
  const getFunctionName = (route: ITypedHttpRoute): string =>
170
169
  ["test", "api", ...route.accessors].join("_");
171
-
172
- const getTypeName =
173
- (project: INestiaProject) =>
174
- (importer: ImportDictionary) =>
175
- (p: ITypedHttpRoute.IParameter | ITypedHttpRoute.IOutput) =>
176
- p.metadata
177
- ? SdkTypeProgrammer.write(project)(importer)(p.metadata)
178
- : ts.factory.createTypeReferenceNode(p.typeName);