@nestia/sdk 6.0.6 → 7.0.0-dev.20250605

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 (137) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +92 -92
  3. package/assets/bundle/api/HttpError.ts +1 -1
  4. package/assets/bundle/api/IConnection.ts +1 -1
  5. package/assets/bundle/api/Primitive.ts +1 -1
  6. package/assets/bundle/api/Resolved.ts +1 -1
  7. package/assets/bundle/api/index.ts +4 -4
  8. package/assets/bundle/api/module.ts +6 -6
  9. package/assets/bundle/distribute/README.md +37 -37
  10. package/assets/bundle/distribute/package.json +28 -28
  11. package/assets/bundle/distribute/tsconfig.json +109 -109
  12. package/assets/bundle/e2e/index.ts +42 -42
  13. package/assets/config/nestia.config.ts +97 -97
  14. package/lib/INestiaConfig.d.ts +66 -69
  15. package/lib/executable/internal/NestiaConfigLoader.js +10 -5
  16. package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
  17. package/lib/executable/sdk.js +12 -12
  18. package/lib/generates/internal/E2eFileProgrammer.js +30 -14
  19. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  20. package/lib/generates/internal/ImportDictionary.js +13 -4
  21. package/lib/generates/internal/ImportDictionary.js.map +1 -1
  22. package/lib/generates/internal/SdkAliasCollection.d.ts +3 -2
  23. package/lib/generates/internal/SdkAliasCollection.js +8 -3
  24. package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
  25. package/lib/generates/internal/SdkHttpFunctionProgrammer.d.ts +1 -1
  26. package/lib/generates/internal/SdkHttpFunctionProgrammer.js +47 -35
  27. package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
  28. package/lib/generates/internal/SdkHttpNamespaceProgrammer.d.ts +1 -1
  29. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +50 -37
  30. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
  31. package/lib/generates/internal/SdkHttpRouteProgrammer.js +5 -4
  32. package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -1
  33. package/lib/generates/internal/SdkHttpSimulationProgrammer.d.ts +1 -1
  34. package/lib/generates/internal/SdkHttpSimulationProgrammer.js +28 -16
  35. package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
  36. package/lib/generates/internal/SdkTypeProgrammer.js +3 -3
  37. package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
  38. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +1 -1
  39. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
  40. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +1 -1
  41. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
  42. package/lib/utils/ArrayUtil.d.ts +2 -2
  43. package/lib/utils/ArrayUtil.js.map +1 -1
  44. package/package.json +6 -6
  45. package/src/INestiaConfig.ts +269 -271
  46. package/src/NestiaSdkApplication.ts +307 -307
  47. package/src/NestiaSwaggerComposer.ts +138 -138
  48. package/src/analyses/AccessorAnalyzer.ts +67 -67
  49. package/src/analyses/ConfigAnalyzer.ts +155 -155
  50. package/src/analyses/ExceptionAnalyzer.ts +154 -154
  51. package/src/analyses/GenericAnalyzer.ts +49 -49
  52. package/src/analyses/ImportAnalyzer.ts +171 -171
  53. package/src/analyses/PathAnalyzer.ts +69 -69
  54. package/src/analyses/ReflectControllerAnalyzer.ts +105 -105
  55. package/src/analyses/ReflectHttpOperationAnalyzer.ts +183 -183
  56. package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +71 -71
  57. package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +348 -348
  58. package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +127 -127
  59. package/src/analyses/ReflectMetadataAnalyzer.ts +44 -44
  60. package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +172 -172
  61. package/src/analyses/SecurityAnalyzer.ts +25 -25
  62. package/src/analyses/TypedHttpRouteAnalyzer.ts +186 -186
  63. package/src/analyses/TypedWebSocketRouteAnalyzer.ts +18 -18
  64. package/src/decorators/OperationMetadata.ts +15 -15
  65. package/src/executable/internal/CommandParser.ts +15 -15
  66. package/src/executable/internal/NestiaConfigLoader.ts +78 -78
  67. package/src/executable/internal/NestiaSdkCommand.ts +103 -103
  68. package/src/executable/sdk.ts +75 -75
  69. package/src/generates/CloneGenerator.ts +66 -66
  70. package/src/generates/E2eGenerator.ts +32 -32
  71. package/src/generates/SdkGenerator.ts +159 -159
  72. package/src/generates/SwaggerGenerator.ts +292 -292
  73. package/src/generates/internal/E2eFileProgrammer.ts +214 -183
  74. package/src/generates/internal/FilePrinter.ts +53 -53
  75. package/src/generates/internal/ImportDictionary.ts +159 -147
  76. package/src/generates/internal/SdkAliasCollection.ts +204 -185
  77. package/src/generates/internal/SdkDistributionComposer.ts +103 -103
  78. package/src/generates/internal/SdkFileProgrammer.ts +116 -116
  79. package/src/generates/internal/SdkHttpCloneProgrammer.ts +124 -124
  80. package/src/generates/internal/SdkHttpCloneReferencer.ts +71 -71
  81. package/src/generates/internal/SdkHttpFunctionProgrammer.ts +325 -301
  82. package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +563 -529
  83. package/src/generates/internal/SdkHttpRouteProgrammer.ts +119 -117
  84. package/src/generates/internal/SdkHttpSimulationProgrammer.ts +386 -362
  85. package/src/generates/internal/SdkImportWizard.ts +55 -55
  86. package/src/generates/internal/SdkRouteDirectory.ts +18 -18
  87. package/src/generates/internal/SdkTypeProgrammer.ts +377 -377
  88. package/src/generates/internal/SdkTypeTagProgrammer.ts +102 -102
  89. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +362 -362
  90. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +265 -265
  91. package/src/generates/internal/SwaggerDescriptionComposer.ts +64 -64
  92. package/src/generates/internal/SwaggerOperationComposer.ts +119 -119
  93. package/src/generates/internal/SwaggerOperationParameterComposer.ts +177 -177
  94. package/src/generates/internal/SwaggerOperationResponseComposer.ts +110 -110
  95. package/src/index.ts +4 -4
  96. package/src/module.ts +3 -3
  97. package/src/structures/INestiaProject.ts +13 -13
  98. package/src/structures/INestiaSdkInput.ts +20 -20
  99. package/src/structures/IReflectApplication.ts +8 -8
  100. package/src/structures/IReflectController.ts +15 -15
  101. package/src/structures/IReflectHttpOperation.ts +26 -26
  102. package/src/structures/IReflectHttpOperationException.ts +19 -19
  103. package/src/structures/IReflectHttpOperationParameter.ts +81 -81
  104. package/src/structures/IReflectHttpOperationSuccess.ts +22 -22
  105. package/src/structures/IReflectOperationError.ts +26 -26
  106. package/src/structures/IReflectType.ts +4 -4
  107. package/src/structures/IReflectTypeImport.ts +4 -4
  108. package/src/structures/IReflectWebSocketOperation.ts +17 -17
  109. package/src/structures/IReflectWebSocketOperationParameter.ts +38 -38
  110. package/src/structures/ITypedApplication.ts +11 -11
  111. package/src/structures/ITypedHttpRoute.ts +30 -30
  112. package/src/structures/ITypedHttpRouteException.ts +15 -15
  113. package/src/structures/ITypedHttpRouteParameter.ts +41 -41
  114. package/src/structures/ITypedHttpRouteSuccess.ts +22 -22
  115. package/src/structures/ITypedWebSocketRoute.ts +20 -20
  116. package/src/structures/ITypedWebSocketRouteParameter.ts +3 -3
  117. package/src/structures/MethodType.ts +5 -5
  118. package/src/structures/ParamCategory.ts +1 -1
  119. package/src/structures/TypeEntry.ts +22 -22
  120. package/src/transform.ts +9 -9
  121. package/src/transformers/IOperationMetadata.ts +44 -44
  122. package/src/transformers/ISdkOperationTransformerContext.ts +8 -8
  123. package/src/transformers/SdkOperationProgrammer.ts +209 -209
  124. package/src/transformers/SdkOperationTransformer.ts +253 -253
  125. package/src/transformers/TextPlainValidator.ts +17 -17
  126. package/src/typings/get-function-location.d.ts +7 -7
  127. package/src/utils/ArrayUtil.ts +26 -26
  128. package/src/utils/FileRetriever.ts +22 -22
  129. package/src/utils/MapUtil.ts +14 -14
  130. package/src/utils/MetadataUtil.ts +26 -26
  131. package/src/utils/PathUtil.ts +10 -10
  132. package/src/utils/SourceFinder.ts +66 -66
  133. package/src/utils/StringUtil.ts +17 -17
  134. package/src/utils/StripEnums.ts +5 -5
  135. package/src/utils/VersioningStrategy.ts +28 -28
  136. package/src/validators/HttpHeadersValidator.ts +34 -34
  137. package/src/validators/HttpQueryValidator.ts +34 -34
@@ -1,301 +1,325 @@
1
- import ts from "typescript";
2
- import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
3
- import { TypeFactory } from "typia/lib/factories/TypeFactory";
4
-
5
- import { INestiaProject } from "../../structures/INestiaProject";
6
- import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
7
- import { ITypedHttpRouteParameter } from "../../structures/ITypedHttpRouteParameter";
8
- import { StringUtil } from "../../utils/StringUtil";
9
- import { ImportDictionary } from "./ImportDictionary";
10
- import { SdkAliasCollection } from "./SdkAliasCollection";
11
- import { SdkImportWizard } from "./SdkImportWizard";
12
-
13
- export namespace SdkHttpFunctionProgrammer {
14
- export const write =
15
- (project: INestiaProject) =>
16
- (importer: ImportDictionary) =>
17
- (
18
- route: ITypedHttpRoute,
19
- props: {
20
- headers: ITypedHttpRouteParameter.IHeaders | undefined;
21
- query: ITypedHttpRouteParameter.IQuery | undefined;
22
- input: ITypedHttpRouteParameter.IBody | undefined;
23
- },
24
- ): ts.FunctionDeclaration =>
25
- ts.factory.createFunctionDeclaration(
26
- [
27
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
28
- ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword),
29
- ],
30
- undefined,
31
- route.name,
32
- undefined,
33
- [
34
- IdentifierFactory.parameter(
35
- "connection",
36
- ts.factory.createTypeReferenceNode(
37
- SdkImportWizard.IConnection(importer),
38
- props.headers
39
- ? [ts.factory.createTypeReferenceNode(`${route.name}.Headers`)]
40
- : undefined,
41
- ),
42
- ),
43
- ...route.parameters
44
- .filter((p) => p.category !== "headers")
45
- .map((p) =>
46
- ts.factory.createParameterDeclaration(
47
- [],
48
- undefined,
49
- p.name,
50
- p.metadata.optional === true
51
- ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
52
- : undefined,
53
- project.config.primitive !== false &&
54
- (p === props.query || p === props.input)
55
- ? ts.factory.createTypeReferenceNode(
56
- `${route.name}.${p === props.query ? "Query" : "Input"}`,
57
- )
58
- : project.config.clone === true
59
- ? SdkAliasCollection.from(project)(importer)(p.metadata)
60
- : SdkAliasCollection.name(p),
61
- ),
62
- ),
63
- ],
64
- ts.factory.createTypeReferenceNode("Promise", [
65
- project.config.propagate === true ||
66
- route.success.metadata.size() !== 0
67
- ? ts.factory.createTypeReferenceNode(`${route.name}.Output`)
68
- : ts.factory.createTypeReferenceNode("void"),
69
- ]),
70
- ts.factory.createBlock(
71
- write_body(project)(importer)(route, props),
72
- true,
73
- ),
74
- );
75
-
76
- const write_body =
77
- (project: INestiaProject) =>
78
- (importer: ImportDictionary) =>
79
- (
80
- route: ITypedHttpRoute,
81
- props: {
82
- headers: ITypedHttpRouteParameter.IHeaders | undefined;
83
- query: ITypedHttpRouteParameter.IQuery | undefined;
84
- input: ITypedHttpRouteParameter.IBody | undefined;
85
- },
86
- ): ts.Statement[] => {
87
- const caller = () =>
88
- ts.factory.createCallExpression(
89
- IdentifierFactory.access(
90
- ts.factory.createIdentifier(
91
- SdkImportWizard.Fetcher(
92
- !!props.input?.encrypted || route.success.encrypted,
93
- )(importer),
94
- ),
95
- project.config.propagate ? "propagate" : "fetch",
96
- ),
97
- project.config.propagate
98
- ? route.method.toLowerCase() === "get" ||
99
- route.method.toLowerCase() === "head"
100
- ? [TypeFactory.keyword("any")]
101
- : [TypeFactory.keyword("any"), TypeFactory.keyword("any")]
102
- : undefined,
103
- [
104
- props.input && props.input.contentType !== "multipart/form-data"
105
- ? ts.factory.createObjectLiteralExpression(
106
- [
107
- ts.factory.createSpreadAssignment(
108
- ts.factory.createIdentifier("connection"),
109
- ),
110
- ts.factory.createPropertyAssignment(
111
- "headers",
112
- ts.factory.createObjectLiteralExpression(
113
- [
114
- ts.factory.createSpreadAssignment(
115
- IdentifierFactory.access(
116
- ts.factory.createIdentifier("connection"),
117
- "headers",
118
- ),
119
- ),
120
- ts.factory.createPropertyAssignment(
121
- ts.factory.createStringLiteral("Content-Type"),
122
- ts.factory.createStringLiteral(
123
- props.input?.contentType ?? "application/json",
124
- ),
125
- ),
126
- ],
127
- true,
128
- ),
129
- ),
130
- ],
131
- true,
132
- )
133
- : ts.factory.createIdentifier("connection"),
134
- ts.factory.createObjectLiteralExpression(
135
- [
136
- ts.factory.createSpreadAssignment(
137
- IdentifierFactory.access(
138
- ts.factory.createIdentifier(route.name),
139
- "METADATA",
140
- ),
141
- ),
142
- ts.factory.createPropertyAssignment(
143
- "template",
144
- IdentifierFactory.access(
145
- IdentifierFactory.access(
146
- ts.factory.createIdentifier(route.name),
147
- "METADATA",
148
- ),
149
- "path",
150
- ),
151
- ),
152
- ts.factory.createPropertyAssignment(
153
- "path",
154
- ts.factory.createCallExpression(
155
- IdentifierFactory.access(
156
- ts.factory.createIdentifier(route.name),
157
- "path",
158
- ),
159
- undefined,
160
- route.parameters
161
- .filter(
162
- (p) => p.category === "param" || p.category === "query",
163
- )
164
- .map((p) => ts.factory.createIdentifier(p.name)),
165
- ),
166
- ),
167
- ],
168
- true,
169
- ),
170
- ...(props.input
171
- ? [ts.factory.createIdentifier(props.input.name)]
172
- : []),
173
- ...(project.config.json &&
174
- props.input !== undefined &&
175
- (props.input.contentType === "application/json" ||
176
- props.input.encrypted === true)
177
- ? [ts.factory.createIdentifier(`${route.name}.stringify`)]
178
- : []),
179
- ],
180
- );
181
- const output = (awaiter: boolean) =>
182
- project.config.simulate
183
- ? ts.factory.createConditionalExpression(
184
- ts.factory.createIdentifier("!!connection.simulate"),
185
- undefined,
186
- ts.factory.createCallExpression(
187
- ts.factory.createIdentifier(`${route.name}.simulate`),
188
- [],
189
- [
190
- ts.factory.createIdentifier("connection"),
191
- ...route.parameters
192
- .filter((p) => p.category !== "headers")
193
- .map((p) => ts.factory.createIdentifier(p.name)),
194
- ],
195
- ),
196
- undefined,
197
- awaiter ? ts.factory.createAwaitExpression(caller()) : caller(),
198
- )
199
- : awaiter
200
- ? ts.factory.createAwaitExpression(caller())
201
- : caller();
202
- return [
203
- ...(project.config.assert
204
- ? route.parameters
205
- .filter((p) => p.category !== "headers")
206
- .map((p) =>
207
- ts.factory.createExpressionStatement(
208
- ts.factory.createCallExpression(
209
- IdentifierFactory.access(
210
- ts.factory.createIdentifier(
211
- SdkImportWizard.typia(importer),
212
- ),
213
- "assert",
214
- ),
215
- [
216
- ts.factory.createTypeQueryNode(
217
- ts.factory.createIdentifier(p.name),
218
- ),
219
- ],
220
- [ts.factory.createIdentifier(p.name)],
221
- ),
222
- ),
223
- )
224
- : []),
225
- ...(route.success.setHeaders.length === 0
226
- ? [ts.factory.createReturnStatement(output(false))]
227
- : write_set_headers(project)(importer)(route)(output(true))),
228
- ];
229
- };
230
-
231
- const write_set_headers =
232
- (project: INestiaProject) =>
233
- (importer: ImportDictionary) =>
234
- (route: ITypedHttpRoute) =>
235
- (condition: ts.Expression): ts.Statement[] => {
236
- const accessor = (x: string) => (y: string) =>
237
- x[0] === "[" ? `${x}${y}` : `${x}.${y}`;
238
- const output: string = StringUtil.escapeDuplicate([
239
- "connection",
240
- ...route.parameters.map((p) => p.name),
241
- ])("output");
242
- const headers: string = accessor("connection")("headers");
243
- const data: string = project.config.propagate
244
- ? accessor(output)("data")
245
- : output;
246
-
247
- const assigners: ts.ExpressionStatement[] = [
248
- ts.factory.createBinaryExpression(
249
- ts.factory.createIdentifier(headers),
250
- ts.factory.createToken(ts.SyntaxKind.QuestionQuestionEqualsToken),
251
- ts.factory.createObjectLiteralExpression([]),
252
- ),
253
- ...route.success.setHeaders.map((tuple) =>
254
- tuple.type === "assigner"
255
- ? ts.factory.createCallExpression(
256
- ts.factory.createIdentifier("Object.assign"),
257
- [],
258
- [
259
- ts.factory.createIdentifier(headers),
260
- ts.factory.createIdentifier(accessor(data)(tuple.source)),
261
- ],
262
- )
263
- : ts.factory.createBinaryExpression(
264
- ts.factory.createIdentifier(
265
- accessor(headers)(tuple.target ?? tuple.source),
266
- ),
267
- ts.factory.createToken(ts.SyntaxKind.EqualsToken),
268
- ts.factory.createIdentifier(accessor(data)(tuple.source)),
269
- ),
270
- ),
271
- ].map(ts.factory.createExpressionStatement);
272
- return [
273
- ts.factory.createVariableStatement(
274
- [],
275
- ts.factory.createVariableDeclarationList(
276
- [
277
- ts.factory.createVariableDeclaration(
278
- output,
279
- undefined,
280
- SdkAliasCollection.output(project)(importer)(route),
281
- condition,
282
- ),
283
- ],
284
- ts.NodeFlags.Const,
285
- ),
286
- ),
287
- ...(project.config.propagate
288
- ? [
289
- ts.factory.createIfStatement(
290
- ts.factory.createIdentifier(accessor(output)("success")),
291
- assigners.length === 1
292
- ? assigners[0]
293
- : ts.factory.createBlock(assigners, true),
294
- undefined,
295
- ),
296
- ]
297
- : assigners),
298
- ts.factory.createReturnStatement(ts.factory.createIdentifier(output)),
299
- ];
300
- };
301
- }
1
+ import ts from "typescript";
2
+ import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
3
+ import { TypeFactory } from "typia/lib/factories/TypeFactory";
4
+
5
+ import { INestiaProject } from "../../structures/INestiaProject";
6
+ import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
7
+ import { ITypedHttpRouteParameter } from "../../structures/ITypedHttpRouteParameter";
8
+ import { StringUtil } from "../../utils/StringUtil";
9
+ import { ImportDictionary } from "./ImportDictionary";
10
+ import { SdkAliasCollection } from "./SdkAliasCollection";
11
+ import { SdkImportWizard } from "./SdkImportWizard";
12
+
13
+ export namespace SdkHttpFunctionProgrammer {
14
+ export const write =
15
+ (project: INestiaProject) =>
16
+ (importer: ImportDictionary) =>
17
+ (
18
+ route: ITypedHttpRoute,
19
+ props: {
20
+ headers: ITypedHttpRouteParameter.IHeaders | undefined;
21
+ query: ITypedHttpRouteParameter.IQuery | undefined;
22
+ body: ITypedHttpRouteParameter.IBody | undefined;
23
+ },
24
+ ): ts.FunctionDeclaration =>
25
+ ts.factory.createFunctionDeclaration(
26
+ [
27
+ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
28
+ ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword),
29
+ ],
30
+ undefined,
31
+ route.name,
32
+ undefined,
33
+ [
34
+ IdentifierFactory.parameter(
35
+ "connection",
36
+ ts.factory.createTypeReferenceNode(
37
+ SdkImportWizard.IConnection(importer),
38
+ props.headers
39
+ ? [ts.factory.createTypeReferenceNode(`${route.name}.Headers`)]
40
+ : undefined,
41
+ ),
42
+ ),
43
+ ...(project.config.keyword === true &&
44
+ route.parameters.filter((p) => p.category !== "headers").length !== 0
45
+ ? [
46
+ ts.factory.createParameterDeclaration(
47
+ [],
48
+ undefined,
49
+ "props",
50
+ undefined,
51
+ ts.factory.createTypeReferenceNode(`${route.name}.IProps`),
52
+ ),
53
+ ]
54
+ : route.parameters
55
+ .filter((p) => p.category !== "headers")
56
+ .map((p) =>
57
+ ts.factory.createParameterDeclaration(
58
+ [],
59
+ undefined,
60
+ p.name,
61
+ p.metadata.optional === true
62
+ ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
63
+ : undefined,
64
+ project.config.primitive !== false &&
65
+ (p === props.query || p === props.body)
66
+ ? ts.factory.createTypeReferenceNode(
67
+ `${route.name}.${p === props.query ? "Query" : "RequestBody"}`,
68
+ )
69
+ : project.config.clone === true
70
+ ? SdkAliasCollection.from(project)(importer)(p.metadata)
71
+ : SdkAliasCollection.name(p),
72
+ ),
73
+ )),
74
+ ],
75
+ ts.factory.createTypeReferenceNode("Promise", [
76
+ project.config.propagate === true ||
77
+ route.success.metadata.size() !== 0
78
+ ? ts.factory.createTypeReferenceNode(`${route.name}.Response`)
79
+ : ts.factory.createTypeReferenceNode("void"),
80
+ ]),
81
+ ts.factory.createBlock(
82
+ writeBody(project)(importer)(route, props),
83
+ true,
84
+ ),
85
+ );
86
+
87
+ const writeBody =
88
+ (project: INestiaProject) =>
89
+ (importer: ImportDictionary) =>
90
+ (
91
+ route: ITypedHttpRoute,
92
+ props: {
93
+ headers: ITypedHttpRouteParameter.IHeaders | undefined;
94
+ query: ITypedHttpRouteParameter.IQuery | undefined;
95
+ body: ITypedHttpRouteParameter.IBody | undefined;
96
+ },
97
+ ): ts.Statement[] => {
98
+ const property = (name: string): ts.Expression =>
99
+ project.config.keyword === true
100
+ ? IdentifierFactory.access(ts.factory.createIdentifier("props"), name)
101
+ : ts.factory.createIdentifier(name);
102
+ const fetch = () =>
103
+ ts.factory.createCallExpression(
104
+ IdentifierFactory.access(
105
+ ts.factory.createIdentifier(
106
+ SdkImportWizard.Fetcher(
107
+ !!props.body?.encrypted || route.success.encrypted,
108
+ )(importer),
109
+ ),
110
+ project.config.propagate ? "propagate" : "fetch",
111
+ ),
112
+ project.config.propagate
113
+ ? route.method.toLowerCase() === "get" ||
114
+ route.method.toLowerCase() === "head"
115
+ ? [TypeFactory.keyword("any")]
116
+ : [TypeFactory.keyword("any"), TypeFactory.keyword("any")]
117
+ : undefined,
118
+ [
119
+ props.body && props.body.contentType !== "multipart/form-data"
120
+ ? ts.factory.createObjectLiteralExpression(
121
+ [
122
+ ts.factory.createSpreadAssignment(
123
+ ts.factory.createIdentifier("connection"),
124
+ ),
125
+ ts.factory.createPropertyAssignment(
126
+ "headers",
127
+ ts.factory.createObjectLiteralExpression(
128
+ [
129
+ ts.factory.createSpreadAssignment(
130
+ IdentifierFactory.access(
131
+ ts.factory.createIdentifier("connection"),
132
+ "headers",
133
+ ),
134
+ ),
135
+ ts.factory.createPropertyAssignment(
136
+ ts.factory.createStringLiteral("Content-Type"),
137
+ ts.factory.createStringLiteral(
138
+ props.body?.contentType ?? "application/json",
139
+ ),
140
+ ),
141
+ ],
142
+ true,
143
+ ),
144
+ ),
145
+ ],
146
+ true,
147
+ )
148
+ : ts.factory.createIdentifier("connection"),
149
+ ts.factory.createObjectLiteralExpression(
150
+ [
151
+ ts.factory.createSpreadAssignment(
152
+ IdentifierFactory.access(
153
+ ts.factory.createIdentifier(route.name),
154
+ "METADATA",
155
+ ),
156
+ ),
157
+ ts.factory.createPropertyAssignment(
158
+ "template",
159
+ IdentifierFactory.access(
160
+ IdentifierFactory.access(
161
+ ts.factory.createIdentifier(route.name),
162
+ "METADATA",
163
+ ),
164
+ "path",
165
+ ),
166
+ ),
167
+ ts.factory.createPropertyAssignment(
168
+ "path",
169
+ ts.factory.createCallExpression(
170
+ IdentifierFactory.access(
171
+ ts.factory.createIdentifier(route.name),
172
+ "path",
173
+ ),
174
+ undefined,
175
+ getArguments(project, route, false),
176
+ ),
177
+ ),
178
+ ],
179
+ true,
180
+ ),
181
+ ...(props.body ? [property(props.body.name)] : []),
182
+ ...(project.config.json &&
183
+ props.body !== undefined &&
184
+ (props.body.contentType === "application/json" ||
185
+ props.body.encrypted === true)
186
+ ? [ts.factory.createIdentifier(`${route.name}.stringify`)]
187
+ : []),
188
+ ],
189
+ );
190
+ const output = (awaiter: boolean) =>
191
+ project.config.simulate
192
+ ? ts.factory.createConditionalExpression(
193
+ ts.factory.createIdentifier("!!connection.simulate"),
194
+ undefined,
195
+ ts.factory.createCallExpression(
196
+ ts.factory.createIdentifier(`${route.name}.simulate`),
197
+ [],
198
+ [
199
+ ts.factory.createIdentifier("connection"),
200
+ ...getArguments(project, route, true),
201
+ ],
202
+ ),
203
+ undefined,
204
+ awaiter ? ts.factory.createAwaitExpression(fetch()) : fetch(),
205
+ )
206
+ : awaiter
207
+ ? ts.factory.createAwaitExpression(fetch())
208
+ : fetch();
209
+ return [
210
+ ...(project.config.assert
211
+ ? route.parameters
212
+ .filter((p) => p.category !== "headers")
213
+ .map((p) =>
214
+ ts.factory.createExpressionStatement(
215
+ ts.factory.createCallExpression(
216
+ IdentifierFactory.access(
217
+ ts.factory.createIdentifier(
218
+ SdkImportWizard.typia(importer),
219
+ ),
220
+ "assert",
221
+ ),
222
+ [
223
+ ts.factory.createTypeQueryNode(
224
+ ts.factory.createIdentifier(p.name),
225
+ ),
226
+ ],
227
+ [ts.factory.createIdentifier(p.name)],
228
+ ),
229
+ ),
230
+ )
231
+ : []),
232
+ ...(route.success.setHeaders.length === 0
233
+ ? [ts.factory.createReturnStatement(output(false))]
234
+ : writeSetHeaders(project)(importer)(route)(output(true))),
235
+ ];
236
+ };
237
+
238
+ const writeSetHeaders =
239
+ (project: INestiaProject) =>
240
+ (importer: ImportDictionary) =>
241
+ (route: ITypedHttpRoute) =>
242
+ (condition: ts.Expression): ts.Statement[] => {
243
+ const accessor = (x: string) => (y: string) =>
244
+ x[0] === "[" ? `${x}${y}` : `${x}.${y}`;
245
+ const output: string = StringUtil.escapeDuplicate([
246
+ "connection",
247
+ ...route.parameters.map((p) => p.name),
248
+ ])("output");
249
+ const headers: string = accessor("connection")("headers");
250
+ const data: string = project.config.propagate
251
+ ? accessor(output)("data")
252
+ : output;
253
+
254
+ const assigners: ts.ExpressionStatement[] = [
255
+ ts.factory.createBinaryExpression(
256
+ ts.factory.createIdentifier(headers),
257
+ ts.factory.createToken(ts.SyntaxKind.QuestionQuestionEqualsToken),
258
+ ts.factory.createObjectLiteralExpression([]),
259
+ ),
260
+ ...route.success.setHeaders.map((tuple) =>
261
+ tuple.type === "assigner"
262
+ ? ts.factory.createCallExpression(
263
+ ts.factory.createIdentifier("Object.assign"),
264
+ [],
265
+ [
266
+ ts.factory.createIdentifier(headers),
267
+ ts.factory.createIdentifier(accessor(data)(tuple.source)),
268
+ ],
269
+ )
270
+ : ts.factory.createBinaryExpression(
271
+ ts.factory.createIdentifier(
272
+ accessor(headers)(tuple.target ?? tuple.source),
273
+ ),
274
+ ts.factory.createToken(ts.SyntaxKind.EqualsToken),
275
+ ts.factory.createIdentifier(accessor(data)(tuple.source)),
276
+ ),
277
+ ),
278
+ ].map(ts.factory.createExpressionStatement);
279
+ return [
280
+ ts.factory.createVariableStatement(
281
+ [],
282
+ ts.factory.createVariableDeclarationList(
283
+ [
284
+ ts.factory.createVariableDeclaration(
285
+ output,
286
+ undefined,
287
+ SdkAliasCollection.response(project)(importer)(route),
288
+ condition,
289
+ ),
290
+ ],
291
+ ts.NodeFlags.Const,
292
+ ),
293
+ ),
294
+ ...(project.config.propagate
295
+ ? [
296
+ ts.factory.createIfStatement(
297
+ ts.factory.createIdentifier(accessor(output)("success")),
298
+ assigners.length === 1
299
+ ? assigners[0]
300
+ : ts.factory.createBlock(assigners, true),
301
+ undefined,
302
+ ),
303
+ ]
304
+ : assigners),
305
+ ts.factory.createReturnStatement(ts.factory.createIdentifier(output)),
306
+ ];
307
+ };
308
+
309
+ const getArguments = (
310
+ project: INestiaProject,
311
+ route: ITypedHttpRoute,
312
+ body: boolean,
313
+ ): ts.Expression[] => {
314
+ const parameters = route.parameters.filter(
315
+ (p) =>
316
+ p.category === "param" ||
317
+ p.category === "query" ||
318
+ (body === true && p.category === "body"),
319
+ );
320
+ if (parameters.length === 0) return [];
321
+ else if (project.config.keyword === true)
322
+ return [ts.factory.createIdentifier("props")];
323
+ return parameters.map((p) => ts.factory.createIdentifier(p.name));
324
+ };
325
+ }