@nestia/sdk 3.0.5 → 3.1.0-dev.20240429

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 (174) hide show
  1. package/lib/NestiaSdkApplication.d.ts +1 -0
  2. package/lib/NestiaSdkApplication.js +17 -17
  3. package/lib/NestiaSdkApplication.js.map +1 -1
  4. package/lib/analyses/AccessorAnalyzer.d.ts +3 -2
  5. package/lib/analyses/AccessorAnalyzer.js.map +1 -1
  6. package/lib/analyses/ExceptionAnalyzer.d.ts +11 -3
  7. package/lib/analyses/ExceptionAnalyzer.js +23 -18
  8. package/lib/analyses/ExceptionAnalyzer.js.map +1 -1
  9. package/lib/analyses/GenericAnalyzer.d.ts +1 -0
  10. package/lib/analyses/ImportAnalyzer.d.ts +6 -1
  11. package/lib/analyses/ImportAnalyzer.js +27 -29
  12. package/lib/analyses/ImportAnalyzer.js.map +1 -1
  13. package/lib/analyses/PathAnalyzer.d.ts +0 -5
  14. package/lib/analyses/PathAnalyzer.js +0 -32
  15. package/lib/analyses/PathAnalyzer.js.map +1 -1
  16. package/lib/analyses/{ReflectAnalyzer.d.ts → ReflectControllerAnalyzer.d.ts} +3 -4
  17. package/lib/analyses/ReflectControllerAnalyzer.js +145 -0
  18. package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -0
  19. package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +10 -0
  20. package/lib/analyses/ReflectHttpOperationAnalyzer.js +224 -0
  21. package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -0
  22. package/lib/analyses/ReflectMetadataAnalyzer.d.ts +8 -0
  23. package/lib/analyses/ReflectMetadataAnalyzer.js +34 -0
  24. package/lib/analyses/ReflectMetadataAnalyzer.js.map +1 -0
  25. package/lib/analyses/ReflectWebSocketOperationAnalyzer.d.ts +10 -0
  26. package/lib/analyses/ReflectWebSocketOperationAnalyzer.js +78 -0
  27. package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -0
  28. package/lib/analyses/SecurityAnalyzer.js +1 -1
  29. package/lib/analyses/SecurityAnalyzer.js.map +1 -1
  30. package/lib/analyses/TypedControllerAnalyzer.d.ts +9 -0
  31. package/lib/analyses/TypedControllerAnalyzer.js +77 -0
  32. package/lib/analyses/TypedControllerAnalyzer.js.map +1 -0
  33. package/lib/analyses/TypedHttpOperationAnalyzer.d.ts +16 -0
  34. package/lib/analyses/TypedHttpOperationAnalyzer.js +251 -0
  35. package/lib/analyses/TypedHttpOperationAnalyzer.js.map +1 -0
  36. package/lib/analyses/TypedWebSocketOperationAnalyzer.d.ts +16 -0
  37. package/lib/analyses/TypedWebSocketOperationAnalyzer.js +218 -0
  38. package/lib/analyses/TypedWebSocketOperationAnalyzer.js.map +1 -0
  39. package/lib/executable/internal/NestiaConfigLoader.d.ts +1 -0
  40. package/lib/generates/CloneGenerator.d.ts +3 -4
  41. package/lib/generates/CloneGenerator.js +8 -8
  42. package/lib/generates/CloneGenerator.js.map +1 -1
  43. package/lib/generates/E2eGenerator.d.ts +3 -4
  44. package/lib/generates/E2eGenerator.js +7 -7
  45. package/lib/generates/E2eGenerator.js.map +1 -1
  46. package/lib/generates/SdkGenerator.d.ts +4 -4
  47. package/lib/generates/SdkGenerator.js +8 -8
  48. package/lib/generates/SdkGenerator.js.map +1 -1
  49. package/lib/generates/SwaggerGenerator.d.ts +5 -2
  50. package/lib/generates/SwaggerGenerator.js +15 -13
  51. package/lib/generates/SwaggerGenerator.js.map +1 -1
  52. package/lib/generates/internal/E2eFileProgrammer.d.ts +4 -5
  53. package/lib/generates/internal/E2eFileProgrammer.js +13 -12
  54. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  55. package/lib/generates/internal/FilePrinter.d.ts +1 -0
  56. package/lib/generates/internal/ImportDictionary.d.ts +1 -0
  57. package/lib/generates/internal/SdkAliasCollection.d.ts +9 -8
  58. package/lib/generates/internal/SdkAliasCollection.js +20 -20
  59. package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
  60. package/lib/generates/internal/SdkDistributionComposer.d.ts +1 -1
  61. package/lib/generates/internal/SdkDistributionComposer.js +36 -2
  62. package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
  63. package/lib/generates/internal/SdkFileProgrammer.d.ts +4 -4
  64. package/lib/generates/internal/SdkFileProgrammer.js +10 -7
  65. package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
  66. package/lib/generates/internal/SdkHttpCloneProgrammer.d.ts +13 -0
  67. package/lib/generates/internal/{SdkCloneProgrammer.js → SdkHttpCloneProgrammer.js} +14 -14
  68. package/lib/generates/internal/SdkHttpCloneProgrammer.js.map +1 -0
  69. package/lib/generates/internal/SdkHttpFunctionProgrammer.d.ts +12 -0
  70. package/lib/generates/internal/{SdkFunctionProgrammer.js → SdkHttpFunctionProgrammer.js} +12 -12
  71. package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -0
  72. package/lib/generates/internal/SdkHttpNamespaceProgrammer.d.ts +12 -0
  73. package/lib/generates/internal/{SdkNamespaceProgrammer.js → SdkHttpNamespaceProgrammer.js} +26 -26
  74. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -0
  75. package/lib/generates/internal/SdkHttpRouteProgrammer.d.ts +8 -0
  76. package/lib/generates/internal/{SdkRouteProgrammer.js → SdkHttpRouteProgrammer.js} +11 -11
  77. package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -0
  78. package/lib/generates/internal/SdkHttpSimulationProgrammer.d.ts +13 -0
  79. package/lib/generates/internal/{SdkSimulationProgrammer.js → SdkHttpSimulationProgrammer.js} +18 -18
  80. package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -0
  81. package/lib/generates/internal/SdkRouteDirectory.d.ts +3 -2
  82. package/lib/generates/internal/SdkRouteDirectory.js.map +1 -1
  83. package/lib/generates/internal/SdkTypeProgrammer.d.ts +4 -3
  84. package/lib/generates/internal/SdkTypeProgrammer.js +33 -33
  85. package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
  86. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.d.ts +8 -0
  87. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +115 -0
  88. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -0
  89. package/lib/generates/internal/SdkWebSocketRouteProgrammer.d.ts +8 -0
  90. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +79 -0
  91. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -0
  92. package/lib/generates/internal/SwaggerSchemaGenerator.d.ts +6 -5
  93. package/lib/generates/internal/SwaggerSchemaGenerator.js +3 -1
  94. package/lib/generates/internal/SwaggerSchemaGenerator.js.map +1 -1
  95. package/lib/structures/INestiaProject.d.ts +1 -0
  96. package/lib/structures/IReflectController.d.ts +15 -0
  97. package/lib/structures/{IRoute.js → IReflectController.js} +1 -1
  98. package/lib/structures/IReflectController.js.map +1 -0
  99. package/lib/structures/{IController.d.ts → IReflectHttpOperation.d.ts} +15 -25
  100. package/lib/structures/IReflectHttpOperation.js +3 -0
  101. package/lib/structures/IReflectHttpOperation.js.map +1 -0
  102. package/lib/structures/IReflectWebSocketOperation.d.ts +16 -0
  103. package/lib/structures/IReflectWebSocketOperation.js +3 -0
  104. package/lib/structures/IReflectWebSocketOperation.js.map +1 -0
  105. package/lib/structures/ISwaggerError.d.ts +2 -2
  106. package/lib/structures/ITypeTuple.d.ts +1 -0
  107. package/lib/structures/{IRoute.d.ts → ITypedHttpRoute.d.ts} +12 -12
  108. package/lib/structures/{IController.js → ITypedHttpRoute.js} +1 -1
  109. package/lib/structures/ITypedHttpRoute.js.map +1 -0
  110. package/lib/structures/ITypedWebSocketRoute.d.ts +54 -0
  111. package/lib/structures/ITypedWebSocketRoute.js +3 -0
  112. package/lib/structures/ITypedWebSocketRoute.js.map +1 -0
  113. package/lib/structures/TypeEntry.d.ts +1 -0
  114. package/lib/utils/VersioningStrategy.d.ts +6 -0
  115. package/lib/utils/VersioningStrategy.js +22 -0
  116. package/lib/utils/VersioningStrategy.js.map +1 -0
  117. package/package.json +9 -7
  118. package/src/NestiaSdkApplication.ts +36 -34
  119. package/src/analyses/AccessorAnalyzer.ts +12 -5
  120. package/src/analyses/ExceptionAnalyzer.ts +49 -39
  121. package/src/analyses/ImportAnalyzer.ts +123 -104
  122. package/src/analyses/PathAnalyzer.ts +0 -41
  123. package/src/analyses/ReflectControllerAnalyzer.ts +155 -0
  124. package/src/analyses/ReflectHttpOperationAnalyzer.ts +290 -0
  125. package/src/analyses/ReflectMetadataAnalyzer.ts +53 -0
  126. package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +96 -0
  127. package/src/analyses/SecurityAnalyzer.ts +2 -1
  128. package/src/analyses/TypedControllerAnalyzer.ts +92 -0
  129. package/src/analyses/TypedHttpOperationAnalyzer.ts +352 -0
  130. package/src/analyses/TypedWebSocketOperationAnalyzer.ts +368 -0
  131. package/src/generates/CloneGenerator.ts +17 -15
  132. package/src/generates/E2eGenerator.ts +10 -12
  133. package/src/generates/SdkGenerator.ts +19 -12
  134. package/src/generates/SwaggerGenerator.ts +32 -22
  135. package/src/generates/internal/E2eFileProgrammer.ts +20 -24
  136. package/src/generates/internal/SdkAliasCollection.ts +38 -33
  137. package/src/generates/internal/SdkDistributionComposer.ts +13 -4
  138. package/src/generates/internal/SdkFileProgrammer.ts +17 -13
  139. package/src/generates/internal/{SdkCloneProgrammer.ts → SdkHttpCloneProgrammer.ts} +14 -15
  140. package/src/generates/internal/{SdkFunctionProgrammer.ts → SdkHttpFunctionProgrammer.ts} +24 -23
  141. package/src/generates/internal/{SdkNamespaceProgrammer.ts → SdkHttpNamespaceProgrammer.ts} +44 -49
  142. package/src/generates/internal/{SdkRouteProgrammer.ts → SdkHttpRouteProgrammer.ts} +12 -13
  143. package/src/generates/internal/{SdkSimulationProgrammer.ts → SdkHttpSimulationProgrammer.ts} +23 -25
  144. package/src/generates/internal/SdkRouteDirectory.ts +3 -2
  145. package/src/generates/internal/SdkTypeProgrammer.ts +43 -37
  146. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +378 -0
  147. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +248 -0
  148. package/src/generates/internal/SwaggerSchemaGenerator.ts +26 -21
  149. package/src/structures/IReflectController.ts +17 -0
  150. package/src/structures/{IController.ts → IReflectHttpOperation.ts} +78 -94
  151. package/src/structures/IReflectWebSocketOperation.ts +17 -0
  152. package/src/structures/ISwaggerError.ts +2 -2
  153. package/src/structures/{IRoute.ts → ITypedHttpRoute.ts} +14 -12
  154. package/src/structures/ITypedWebSocketRoute.ts +67 -0
  155. package/src/utils/VersioningStrategy.ts +28 -0
  156. package/lib/analyses/ControllerAnalyzer.d.ts +0 -7
  157. package/lib/analyses/ControllerAnalyzer.js +0 -269
  158. package/lib/analyses/ControllerAnalyzer.js.map +0 -1
  159. package/lib/analyses/ReflectAnalyzer.js +0 -377
  160. package/lib/analyses/ReflectAnalyzer.js.map +0 -1
  161. package/lib/generates/internal/SdkCloneProgrammer.d.ts +0 -12
  162. package/lib/generates/internal/SdkCloneProgrammer.js.map +0 -1
  163. package/lib/generates/internal/SdkFunctionProgrammer.d.ts +0 -11
  164. package/lib/generates/internal/SdkFunctionProgrammer.js.map +0 -1
  165. package/lib/generates/internal/SdkNamespaceProgrammer.d.ts +0 -11
  166. package/lib/generates/internal/SdkNamespaceProgrammer.js.map +0 -1
  167. package/lib/generates/internal/SdkRouteProgrammer.d.ts +0 -7
  168. package/lib/generates/internal/SdkRouteProgrammer.js.map +0 -1
  169. package/lib/generates/internal/SdkSimulationProgrammer.d.ts +0 -12
  170. package/lib/generates/internal/SdkSimulationProgrammer.js.map +0 -1
  171. package/lib/structures/IController.js.map +0 -1
  172. package/lib/structures/IRoute.js.map +0 -1
  173. package/src/analyses/ControllerAnalyzer.ts +0 -402
  174. package/src/analyses/ReflectAnalyzer.ts +0 -471
@@ -8,10 +8,12 @@ import { MetadataCollection } from "typia/lib/factories/MetadataCollection";
8
8
  import { JsonApplicationProgrammer } from "typia/lib/programmers/json/JsonApplicationProgrammer";
9
9
 
10
10
  import { INestiaConfig } from "../INestiaConfig";
11
- import { IRoute } from "../structures/IRoute";
11
+ import { INestiaProject } from "../structures/INestiaProject";
12
12
  import { ISwaggerError } from "../structures/ISwaggerError";
13
13
  import { ISwaggerLazyProperty } from "../structures/ISwaggerLazyProperty";
14
14
  import { ISwaggerLazySchema } from "../structures/ISwaggerLazySchema";
15
+ import { ITypedHttpRoute } from "../structures/ITypedHttpRoute";
16
+ import { ITypedWebSocketRoute } from "../structures/ITypedWebSocketRoute";
15
17
  import { FileRetriever } from "../utils/FileRetriever";
16
18
  import { MapUtil } from "../utils/MapUtil";
17
19
  import { SwaggerSchemaGenerator } from "./internal/SwaggerSchemaGenerator";
@@ -28,13 +30,18 @@ export namespace SwaggerGenerator {
28
30
  }
29
31
 
30
32
  export const generate =
31
- (checker: ts.TypeChecker) =>
32
- (config: INestiaConfig.ISwaggerConfig) =>
33
- async (routeList: IRoute[]): Promise<void> => {
33
+ (project: INestiaProject) =>
34
+ async (
35
+ routeList: Array<ITypedHttpRoute | ITypedWebSocketRoute>,
36
+ ): Promise<void> => {
34
37
  console.log("Generating Swagger Documents");
35
38
 
36
39
  // VALIDATE SECURITY
37
- validate_security(config)(routeList);
40
+ const config = project.config.swagger!;
41
+ const httpRoutes: ITypedHttpRoute[] = routeList.filter(
42
+ (route): route is ITypedHttpRoute => route.protocol === "http",
43
+ ) as ITypedHttpRoute[];
44
+ validate_security(config)(httpRoutes);
38
45
 
39
46
  // PREPARE ASSETS
40
47
  const parsed: path.ParsedPath = path.parse(config.output);
@@ -66,7 +73,7 @@ export namespace SwaggerGenerator {
66
73
  Record<string, OpenApi.IOperation>
67
74
  > = new Map();
68
75
 
69
- for (const route of routeList) {
76
+ for (const route of httpRoutes) {
70
77
  if (route.jsDocTags.find((tag) => tag.name === "internal")) continue;
71
78
 
72
79
  const path: Record<string, OpenApi.IOperation> = MapUtil.take(
@@ -76,7 +83,7 @@ export namespace SwaggerGenerator {
76
83
  );
77
84
  path[route.method.toLowerCase()] = generate_route({
78
85
  config,
79
- checker,
86
+ checker: project.checker,
80
87
  collection,
81
88
  lazySchemas,
82
89
  lazyProperties,
@@ -116,9 +123,9 @@ export namespace SwaggerGenerator {
116
123
  if (errors.length) {
117
124
  for (const e of errors)
118
125
  console.error(
119
- `${path.relative(e.route.location, process.cwd())}:${
120
- e.route.target.class.name
121
- }.${e.route.target.function.name}:${
126
+ `${path.relative(process.cwd(), e.route.location)}:${
127
+ e.route.controller.name
128
+ }.${e.route.name}:${
122
129
  e.from
123
130
  } - error TS(@nestia/sdk): invalid type detected.\n\n` +
124
131
  e.messages.map((m) => ` - ${m}`).join("\n"),
@@ -131,11 +138,11 @@ export namespace SwaggerGenerator {
131
138
  const customizer = {
132
139
  at: new Singleton(() => {
133
140
  const functor: Map<Function, Endpoint> = new Map();
134
- for (const route of routeList) {
141
+ for (const route of httpRoutes) {
135
142
  const method: OpenApi.Method =
136
143
  route.method.toLowerCase() as OpenApi.Method;
137
144
  const path: string = get_path(route.path, route.parameters);
138
- functor.set(route.target.function, {
145
+ functor.set(route.function, {
139
146
  method,
140
147
  path,
141
148
  route: swagger.paths![path][method]!,
@@ -161,13 +168,13 @@ export namespace SwaggerGenerator {
161
168
  },
162
169
  ),
163
170
  };
164
- for (const route of routeList) {
171
+ for (const route of httpRoutes) {
165
172
  if (
166
173
  false ===
167
174
  Reflect.hasMetadata(
168
175
  "nestia/SwaggerCustomizer",
169
176
  route.controller.prototype,
170
- route.target.function.name,
177
+ route.name,
171
178
  )
172
179
  )
173
180
  continue;
@@ -179,7 +186,7 @@ export namespace SwaggerGenerator {
179
186
  const closure: Function | Function[] = Reflect.getMetadata(
180
187
  "nestia/SwaggerCustomizer",
181
188
  route.controller.prototype,
182
- route.target.function.name,
189
+ route.name,
183
190
  );
184
191
  const array: Function[] = Array.isArray(closure) ? closure : [closure];
185
192
  for (const fn of array)
@@ -209,7 +216,7 @@ export namespace SwaggerGenerator {
209
216
 
210
217
  const validate_security =
211
218
  (config: INestiaConfig.ISwaggerConfig) =>
212
- (routeList: IRoute[]): void | never => {
219
+ (routeList: ITypedHttpRoute[]): void | never => {
213
220
  const securityMap: Map<
214
221
  string,
215
222
  { scheme: OpenApi.ISecurityScheme; scopes: Set<string> }
@@ -252,7 +259,7 @@ export namespace SwaggerGenerator {
252
259
  for (const [key, scopes] of Object.entries(record))
253
260
  validate((str) =>
254
261
  violations.push(
255
- ` - ${str} (${route.target.class.name}.${route.target.function.name}() at "${route.location}")`,
262
+ ` - ${str} (${route.controller.name}.${route.name}() at "${route.location}")`,
256
263
  ),
257
264
  )(key, scopes);
258
265
 
@@ -345,8 +352,11 @@ export namespace SwaggerGenerator {
345
352
  };
346
353
  };
347
354
 
348
- function get_path(path: string, parameters: IRoute.IParameter[]): string {
349
- const filtered: IRoute.IParameter[] = parameters.filter(
355
+ function get_path(
356
+ path: string,
357
+ parameters: ITypedHttpRoute.IParameter[],
358
+ ): string {
359
+ const filtered: ITypedHttpRoute.IParameter[] = parameters.filter(
350
360
  (param) => param.category === "param" && !!param.field,
351
361
  );
352
362
  for (const param of filtered)
@@ -356,7 +366,7 @@ export namespace SwaggerGenerator {
356
366
 
357
367
  const generate_route =
358
368
  (props: IProps) =>
359
- (route: IRoute): OpenApi.IOperation => {
369
+ (route: ITypedHttpRoute): OpenApi.IOperation => {
360
370
  // FIND REQUEST BODY
361
371
  const body = route.parameters.find((param) => param.category === "body");
362
372
 
@@ -414,8 +424,8 @@ export namespace SwaggerGenerator {
414
424
  operationId:
415
425
  route.operationId ??
416
426
  props.config.operationId?.({
417
- class: route.target.class.name,
418
- function: route.target.function.name,
427
+ class: route.controller.name,
428
+ function: route.name,
419
429
  method: route.method as "GET",
420
430
  path: route.path,
421
431
  }),
@@ -1,8 +1,8 @@
1
1
  import ts from "typescript";
2
2
  import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
3
3
 
4
- import { INestiaConfig } from "../../INestiaConfig";
5
- import { IRoute } from "../../structures/IRoute";
4
+ import { INestiaProject } from "../../structures/INestiaProject";
5
+ import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
6
6
  import { FilePrinter } from "./FilePrinter";
7
7
  import { ImportDictionary } from "./ImportDictionary";
8
8
  import { SdkAliasCollection } from "./SdkAliasCollection";
@@ -11,14 +11,13 @@ import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
11
11
 
12
12
  export namespace E2eFileProgrammer {
13
13
  export const generate =
14
- (checker: ts.TypeChecker) =>
15
- (config: INestiaConfig) =>
14
+ (project: INestiaProject) =>
16
15
  (props: { api: string; current: string }) =>
17
- async (route: IRoute): Promise<void> => {
16
+ async (route: ITypedHttpRoute): Promise<void> => {
18
17
  const importer: ImportDictionary = new ImportDictionary(
19
18
  `${props.current}/${getFunctionName(route)}.ts`,
20
19
  );
21
- if (config.clone !== true)
20
+ if (project.config.clone !== true)
22
21
  for (const tuple of route.imports)
23
22
  for (const instance of tuple[1])
24
23
  importer.internal({
@@ -33,7 +32,7 @@ export namespace E2eFileProgrammer {
33
32
  name: "api",
34
33
  });
35
34
 
36
- const functor = generate_function(checker)(config)(importer)(route);
35
+ const functor = generate_function(project)(importer)(route);
37
36
  await FilePrinter.write({
38
37
  location: importer.file,
39
38
  statements: [
@@ -45,10 +44,9 @@ export namespace E2eFileProgrammer {
45
44
  };
46
45
 
47
46
  const generate_function =
48
- (checker: ts.TypeChecker) =>
49
- (config: INestiaConfig) =>
47
+ (project: INestiaProject) =>
50
48
  (importer: ImportDictionary) =>
51
- (route: IRoute): ts.Statement =>
49
+ (route: ITypedHttpRoute): ts.Statement =>
52
50
  ts.factory.createVariableStatement(
53
51
  [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
54
52
  ts.factory.createVariableDeclarationList(
@@ -57,7 +55,7 @@ export namespace E2eFileProgrammer {
57
55
  ts.factory.createIdentifier(getFunctionName(route)),
58
56
  undefined,
59
57
  undefined,
60
- generate_arrow(checker)(config)(importer)(route),
58
+ generate_arrow(project)(importer)(route),
61
59
  ),
62
60
  ],
63
61
  ts.NodeFlags.Const,
@@ -65,10 +63,9 @@ export namespace E2eFileProgrammer {
65
63
  );
66
64
 
67
65
  const generate_arrow =
68
- (checker: ts.TypeChecker) =>
69
- (config: INestiaConfig) =>
66
+ (project: INestiaProject) =>
70
67
  (importer: ImportDictionary) =>
71
- (route: IRoute) => {
68
+ (route: ITypedHttpRoute) => {
72
69
  const headers = route.parameters.find(
73
70
  (p) => p.category === "headers" && p.field === undefined,
74
71
  );
@@ -94,7 +91,7 @@ export namespace E2eFileProgrammer {
94
91
  SdkImportWizard.typia(importer),
95
92
  ),
96
93
  )("random"),
97
- [getTypeName(config)(importer)(headers)],
94
+ [getTypeName(project)(importer)(headers)],
98
95
  undefined,
99
96
  ),
100
97
  ),
@@ -120,7 +117,7 @@ export namespace E2eFileProgrammer {
120
117
  IdentifierFactory.access(
121
118
  ts.factory.createIdentifier(SdkImportWizard.typia(importer)),
122
119
  )("random"),
123
- [getTypeName(config)(importer)(p)],
120
+ [getTypeName(project)(importer)(p)],
124
121
  undefined,
125
122
  ),
126
123
  ),
@@ -153,11 +150,10 @@ export namespace E2eFileProgrammer {
153
150
  ts.factory.createVariableDeclaration(
154
151
  "output",
155
152
  undefined,
156
- config.propagate !== true && route.output.typeName === "void"
153
+ project.config.propagate !== true &&
154
+ route.output.typeName === "void"
157
155
  ? undefined
158
- : SdkAliasCollection.output(checker)(config)(importer)(
159
- route,
160
- ),
156
+ : SdkAliasCollection.output(project)(importer)(route),
161
157
  ts.factory.createAwaitExpression(caller),
162
158
  ),
163
159
  ],
@@ -170,13 +166,13 @@ export namespace E2eFileProgrammer {
170
166
  };
171
167
  }
172
168
 
173
- const getFunctionName = (route: IRoute): string =>
169
+ const getFunctionName = (route: ITypedHttpRoute): string =>
174
170
  ["test", "api", ...route.accessors].join("_");
175
171
 
176
172
  const getTypeName =
177
- (config: INestiaConfig) =>
173
+ (project: INestiaProject) =>
178
174
  (importer: ImportDictionary) =>
179
- (p: IRoute.IParameter | IRoute.IOutput) =>
175
+ (p: ITypedHttpRoute.IParameter | ITypedHttpRoute.IOutput) =>
180
176
  p.metadata
181
- ? SdkTypeProgrammer.write(config)(importer)(p.metadata)
177
+ ? SdkTypeProgrammer.write(project)(importer)(p.metadata)
182
178
  : ts.factory.createTypeReferenceNode(p.typeName);
@@ -1,27 +1,27 @@
1
1
  import ts from "typescript";
2
2
  import typia from "typia";
3
3
 
4
- import { INestiaConfig } from "../../INestiaConfig";
5
- import { IController } from "../../structures/IController";
6
- import { IRoute } from "../../structures/IRoute";
4
+ import { INestiaProject } from "../../structures/INestiaProject";
5
+ import { IReflectHttpOperation } from "../../structures/IReflectHttpOperation";
6
+ import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
7
7
  import { ImportDictionary } from "./ImportDictionary";
8
8
  import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
9
9
 
10
10
  export namespace SdkAliasCollection {
11
11
  export const name =
12
- (config: INestiaConfig) =>
12
+ (project: INestiaProject) =>
13
13
  (importer: ImportDictionary) =>
14
- (p: IRoute.IParameter | IRoute.IOutput): ts.TypeNode =>
14
+ (p: ITypedHttpRoute.IParameter | ITypedHttpRoute.IOutput): ts.TypeNode =>
15
15
  p.metadata
16
- ? SdkTypeProgrammer.write(config)(importer)(p.metadata)
16
+ ? SdkTypeProgrammer.write(project)(importer)(p.metadata)
17
17
  : ts.factory.createTypeReferenceNode(p.typeName);
18
18
 
19
19
  export const headers =
20
- (config: INestiaConfig) =>
20
+ (project: INestiaProject) =>
21
21
  (importer: ImportDictionary) =>
22
- (param: IRoute.IParameter): ts.TypeNode => {
23
- const type: ts.TypeNode = name(config)(importer)(param);
24
- if (config.primitive === false) return type;
22
+ (param: ITypedHttpRoute.IParameter): ts.TypeNode => {
23
+ const type: ts.TypeNode = name(project)(importer)(param);
24
+ if (project.config.primitive === false) return type;
25
25
  return ts.factory.createTypeReferenceNode(
26
26
  importer.external({
27
27
  type: true,
@@ -33,11 +33,11 @@ export namespace SdkAliasCollection {
33
33
  };
34
34
 
35
35
  export const query =
36
- (config: INestiaConfig) =>
36
+ (project: INestiaProject) =>
37
37
  (importer: ImportDictionary) =>
38
- (param: IRoute.IParameter): ts.TypeNode => {
39
- const type: ts.TypeNode = name(config)(importer)(param);
40
- if (config.primitive === false) return type;
38
+ (param: ITypedHttpRoute.IParameter): ts.TypeNode => {
39
+ const type: ts.TypeNode = name(project)(importer)(param);
40
+ if (project.config.primitive === false) return type;
41
41
  return ts.factory.createTypeReferenceNode(
42
42
  importer.external({
43
43
  type: true,
@@ -49,17 +49,18 @@ export namespace SdkAliasCollection {
49
49
  };
50
50
 
51
51
  export const input =
52
- (config: INestiaConfig) =>
52
+ (project: INestiaProject) =>
53
53
  (importer: ImportDictionary) =>
54
- (param: IRoute.IParameter): ts.TypeNode => {
55
- const type: ts.TypeNode = name(config)(importer)(param);
56
- if (config.clone === true || config.primitive === false) return type;
54
+ (param: ITypedHttpRoute.IParameter): ts.TypeNode => {
55
+ const type: ts.TypeNode = name(project)(importer)(param);
56
+ if (project.config.clone === true || project.config.primitive === false)
57
+ return type;
57
58
  return ts.factory.createTypeReferenceNode(
58
59
  importer.external({
59
60
  type: true,
60
61
  library: "@nestia/fetcher",
61
62
  instance:
62
- typia.is<IController.IBodyParameter>(param) &&
63
+ typia.is<IReflectHttpOperation.IBodyParameter>(param) &&
63
64
  param.contentType === "multipart/form-data"
64
65
  ? "Resolved"
65
66
  : "Primitive",
@@ -69,18 +70,17 @@ export namespace SdkAliasCollection {
69
70
  };
70
71
 
71
72
  export const output =
72
- (checker: ts.TypeChecker) =>
73
- (config: INestiaConfig) =>
73
+ (project: INestiaProject) =>
74
74
  (importer: ImportDictionary) =>
75
- (route: IRoute): ts.TypeNode => {
76
- if (config.propagate !== true) {
77
- const node: ts.TypeNode = name(config)(importer)(route.output);
78
- const type = checker.getTypeAtLocation(node);
75
+ (route: ITypedHttpRoute): ts.TypeNode => {
76
+ if (project.config.propagate !== true) {
77
+ const node: ts.TypeNode = name(project)(importer)(route.output);
78
+ const type = project.checker.getTypeAtLocation(node);
79
79
  const filter = (flag: ts.TypeFlags) => (type.getFlags() & flag) !== 0;
80
80
 
81
81
  if (
82
- config.clone === true ||
83
- config.primitive === false ||
82
+ project.config.clone === true ||
83
+ project.config.primitive === false ||
84
84
  filter(ts.TypeFlags.Undefined) ||
85
85
  filter(ts.TypeFlags.Never) ||
86
86
  filter(ts.TypeFlags.Void) ||
@@ -103,11 +103,11 @@ export namespace SdkAliasCollection {
103
103
  const branches: IBranch[] = [
104
104
  {
105
105
  status: String(route.status ?? (route.method === "POST" ? 201 : 200)),
106
- type: name(config)(importer)(route.output),
106
+ type: name(project)(importer)(route.output),
107
107
  },
108
108
  ...Object.entries(route.exceptions).map(([status, value]) => ({
109
109
  status,
110
- type: name(config)(importer)(value),
110
+ type: name(project)(importer)(value),
111
111
  })),
112
112
  ];
113
113
  return ts.factory.createTypeReferenceNode(
@@ -139,11 +139,16 @@ export namespace SdkAliasCollection {
139
139
  };
140
140
 
141
141
  export const responseBody =
142
- (checker: ts.TypeChecker) =>
143
- (config: INestiaConfig) =>
142
+ (project: INestiaProject) =>
144
143
  (importer: ImportDictionary) =>
145
- (route: IRoute): ts.TypeNode =>
146
- output(checker)({ ...config, propagate: false })(importer)(route);
144
+ (route: ITypedHttpRoute): ts.TypeNode =>
145
+ output({
146
+ ...project,
147
+ config: {
148
+ ...project.config,
149
+ propagate: false,
150
+ },
151
+ })(importer)(route);
147
152
  }
148
153
 
149
154
  interface IBranch {
@@ -1,11 +1,12 @@
1
1
  import cp from "child_process";
2
2
  import fs from "fs";
3
3
  import path from "path";
4
+ import typia from "typia";
4
5
 
5
6
  import { INestiaConfig } from "../../INestiaConfig";
6
7
 
7
8
  export namespace SdkDistributionComposer {
8
- export const compose = async (config: INestiaConfig) => {
9
+ export const compose = async (config: INestiaConfig, websocket: boolean) => {
9
10
  if (!fs.existsSync(config.distribute!))
10
11
  await fs.promises.mkdir(config.distribute!);
11
12
 
@@ -32,6 +33,7 @@ export namespace SdkDistributionComposer {
32
33
  `npm install --save @nestia/fetcher@${versions["@nestia/fetcher"]}`,
33
34
  );
34
35
  execute(`npm install --save typia@${versions["typia"]}`);
36
+ if (websocket) execute(`npm install --save tgrid@${versions["tgrid"]}`);
35
37
  execute("npx typia setup --manager npm");
36
38
 
37
39
  exit();
@@ -74,18 +76,25 @@ export namespace SdkDistributionComposer {
74
76
  );
75
77
  };
76
78
 
77
- const dependencies = async () => {
79
+ const dependencies = async (): Promise<IDependencies> => {
78
80
  const content: string = await fs.promises.readFile(
79
81
  __dirname + "/../../../package.json",
80
82
  "utf8",
81
83
  );
82
- const json: { dependencies: IDependencies } = JSON.parse(content);
83
- return json.dependencies;
84
+ const json: {
85
+ dependencies: Record<string, string>;
86
+ devDependencies: Record<string, string>;
87
+ } = JSON.parse(content);
88
+ return typia.assert<IDependencies>({
89
+ ...json.devDependencies,
90
+ ...json.dependencies,
91
+ });
84
92
  };
85
93
  }
86
94
 
87
95
  interface IDependencies {
88
96
  "@nestia/fetcher": string;
89
97
  typia: string;
98
+ tgrid: string;
90
99
  }
91
100
  const BUNDLE = __dirname + "/../../../assets/bundle/distribute";
@@ -1,33 +1,36 @@
1
1
  import fs from "fs";
2
2
  import ts from "typescript";
3
3
 
4
- import { INestiaConfig } from "../../INestiaConfig";
5
- import { IRoute } from "../../structures/IRoute";
4
+ import { INestiaProject } from "../../structures/INestiaProject";
5
+ import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
6
+ import { ITypedWebSocketRoute } from "../../structures/ITypedWebSocketRoute";
6
7
  import { MapUtil } from "../../utils/MapUtil";
7
8
  import { FilePrinter } from "./FilePrinter";
8
9
  import { ImportDictionary } from "./ImportDictionary";
10
+ import { SdkHttpRouteProgrammer } from "./SdkHttpRouteProgrammer";
9
11
  import { SdkRouteDirectory } from "./SdkRouteDirectory";
10
- import { SdkRouteProgrammer } from "./SdkRouteProgrammer";
12
+ import { SdkWebSocketRouteProgrammer } from "./SdkWebSocketRouteProgrammer";
11
13
 
12
14
  export namespace SdkFileProgrammer {
13
15
  /* ---------------------------------------------------------
14
16
  CONSTRUCTOR
15
17
  --------------------------------------------------------- */
16
18
  export const generate =
17
- (checker: ts.TypeChecker) =>
18
- (config: INestiaConfig) =>
19
- async (routeList: IRoute[]): Promise<void> => {
19
+ (project: INestiaProject) =>
20
+ async (
21
+ routeList: Array<ITypedHttpRoute | ITypedWebSocketRoute>,
22
+ ): Promise<void> => {
20
23
  // CONSTRUCT FOLDER TREE
21
24
  const root: SdkRouteDirectory = new SdkRouteDirectory(null, "functional");
22
25
  for (const route of routeList) emplace(root)(route);
23
26
 
24
27
  // ITERATE FILES
25
- await iterate(checker)(config)(root)(config.output + "/functional");
28
+ await iterate(project)(root)(project.config.output + "/functional");
26
29
  };
27
30
 
28
31
  const emplace =
29
32
  (directory: SdkRouteDirectory) =>
30
- (route: IRoute): void => {
33
+ (route: ITypedHttpRoute | ITypedWebSocketRoute): void => {
31
34
  // OPEN DIRECTORIES
32
35
  for (const key of route.accessors.slice(0, -1)) {
33
36
  directory = MapUtil.take(
@@ -45,8 +48,7 @@ export namespace SdkFileProgrammer {
45
48
  FILE ITERATOR
46
49
  --------------------------------------------------------- */
47
50
  const iterate =
48
- (checker: ts.TypeChecker) =>
49
- (config: INestiaConfig) =>
51
+ (project: INestiaProject) =>
50
52
  (directory: SdkRouteDirectory) =>
51
53
  async (outDir: string): Promise<void> => {
52
54
  // CREATE A NEW DIRECTORY
@@ -57,7 +59,7 @@ export namespace SdkFileProgrammer {
57
59
  // ITERATE CHILDREN
58
60
  const statements: ts.Statement[] = [];
59
61
  for (const [key, value] of directory.children) {
60
- await iterate(checker)(config)(value)(`${outDir}/${key}`);
62
+ await iterate(project)(value)(`${outDir}/${key}`);
61
63
  statements.push(
62
64
  ts.factory.createExportDeclaration(
63
65
  undefined,
@@ -76,7 +78,7 @@ export namespace SdkFileProgrammer {
76
78
  `${outDir}/index.ts`,
77
79
  );
78
80
  directory.routes.forEach((route, i) => {
79
- if (config.clone !== true)
81
+ if (project.config.clone !== true)
80
82
  for (const tuple of route.imports)
81
83
  for (const instance of tuple[1])
82
84
  importer.internal({
@@ -85,7 +87,9 @@ export namespace SdkFileProgrammer {
85
87
  type: true,
86
88
  });
87
89
  statements.push(
88
- ...SdkRouteProgrammer.generate(checker)(config)(importer)(route),
90
+ ...(route.protocol === "http"
91
+ ? SdkHttpRouteProgrammer.write(project)(importer)(route)
92
+ : SdkWebSocketRouteProgrammer.write(project)(importer)(route)),
89
93
  );
90
94
  if (i !== directory.routes.length - 1)
91
95
  statements.push(FilePrinter.enter());
@@ -7,14 +7,14 @@ import { MetadataAlias } from "typia/lib/schemas/metadata/MetadataAlias";
7
7
  import { MetadataAtomic } from "typia/lib/schemas/metadata/MetadataAtomic";
8
8
  import { MetadataObject } from "typia/lib/schemas/metadata/MetadataObject";
9
9
 
10
- import { INestiaConfig } from "../../INestiaConfig";
11
- import { IRoute } from "../../structures/IRoute";
10
+ import { INestiaProject } from "../../structures/INestiaProject";
11
+ import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
12
12
  import { MapUtil } from "../../utils/MapUtil";
13
13
  import { FilePrinter } from "./FilePrinter";
14
14
  import { ImportDictionary } from "./ImportDictionary";
15
15
  import { SdkTypeProgrammer } from "./SdkTypeProgrammer";
16
16
 
17
- export namespace SdkCloneProgrammer {
17
+ export namespace SdkHttpCloneProgrammer {
18
18
  export interface IModule {
19
19
  name: string;
20
20
  children: Map<string, IModule>;
@@ -24,15 +24,14 @@ export namespace SdkCloneProgrammer {
24
24
  }
25
25
 
26
26
  export const write =
27
- (checker: ts.TypeChecker) =>
28
- (config: INestiaConfig) =>
29
- (routes: IRoute[]): Map<string, IModule> => {
27
+ (project: INestiaProject) =>
28
+ (routes: ITypedHttpRoute[]): Map<string, IModule> => {
30
29
  const collection = new MetadataCollection({
31
30
  replace: MetadataCollection.replace,
32
31
  });
33
32
  for (const r of routes) {
34
33
  for (const p of r.parameters) {
35
- const res = MetadataFactory.analyze(checker)({
34
+ const res = MetadataFactory.analyze(project.checker)({
36
35
  escape: false,
37
36
  constant: true,
38
37
  absorb: false,
@@ -40,14 +39,14 @@ export namespace SdkCloneProgrammer {
40
39
  if (res.success) p.metadata = res.data;
41
40
  }
42
41
  for (const e of Object.values(r.exceptions)) {
43
- const res = MetadataFactory.analyze(checker)({
42
+ const res = MetadataFactory.analyze(project.checker)({
44
43
  escape: true,
45
44
  constant: true,
46
45
  absorb: false,
47
46
  })(collection)(e.type);
48
47
  if (res.success) e.metadata = res.data;
49
48
  }
50
- const res = MetadataFactory.analyze(checker)({
49
+ const res = MetadataFactory.analyze(project.checker)({
51
50
  escape: true,
52
51
  constant: true,
53
52
  absorb: false,
@@ -59,12 +58,12 @@ export namespace SdkCloneProgrammer {
59
58
  for (const alias of collection.aliases())
60
59
  if (isNamedDeclaration(alias.name))
61
60
  prepare(dict)(alias.name)((importer) =>
62
- write_alias(config)(importer)(alias),
61
+ write_alias(project)(importer)(alias),
63
62
  );
64
63
  for (const object of collection.objects())
65
64
  if (isNamedDeclaration(object.name))
66
65
  prepare(dict)(object.name)((importer) =>
67
- write_object(config)(importer)(object),
66
+ write_object(project)(importer)(object),
68
67
  );
69
68
  return dict;
70
69
  };
@@ -89,7 +88,7 @@ export namespace SdkCloneProgrammer {
89
88
  };
90
89
 
91
90
  const write_alias =
92
- (config: INestiaConfig) =>
91
+ (project: INestiaProject) =>
93
92
  (importer: ImportDictionary) =>
94
93
  (alias: MetadataAlias): ts.TypeAliasDeclaration =>
95
94
  FilePrinter.description(
@@ -97,13 +96,13 @@ export namespace SdkCloneProgrammer {
97
96
  [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
98
97
  alias.name.split(".").at(-1)!,
99
98
  [],
100
- SdkTypeProgrammer.write(config)(importer)(alias.value),
99
+ SdkTypeProgrammer.write(project)(importer)(alias.value),
101
100
  ),
102
101
  writeComment([])(alias.description, alias.jsDocTags),
103
102
  );
104
103
 
105
104
  const write_object =
106
- (config: INestiaConfig) =>
105
+ (project: INestiaProject) =>
107
106
  (importer: ImportDictionary) =>
108
107
  (object: MetadataObject): ts.TypeAliasDeclaration => {
109
108
  return FilePrinter.description(
@@ -111,7 +110,7 @@ export namespace SdkCloneProgrammer {
111
110
  [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
112
111
  object.name.split(".").at(-1)!,
113
112
  [],
114
- SdkTypeProgrammer.write_object(config)(importer)(object),
113
+ SdkTypeProgrammer.write_object(project)(importer)(object),
115
114
  ),
116
115
  writeComment([])(object.description ?? null, object.jsDocTags),
117
116
  );