@nestia/sdk 10.0.2 → 11.0.0-dev.20260312

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 (151) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +93 -93
  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 +3 -3
  15. package/lib/NestiaSdkApplication.js.map +1 -1
  16. package/lib/NestiaSwaggerComposer.d.ts +3 -2
  17. package/lib/NestiaSwaggerComposer.js +5 -6
  18. package/lib/NestiaSwaggerComposer.js.map +1 -1
  19. package/lib/analyses/AccessorAnalyzer.js +2 -2
  20. package/lib/analyses/AccessorAnalyzer.js.map +1 -1
  21. package/lib/analyses/DtoAnalyzer.js.map +1 -1
  22. package/lib/analyses/ImportAnalyzer.js.map +1 -1
  23. package/lib/analyses/ReflectHttpOperationAnalyzer.js +3 -3
  24. package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
  25. package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.js +4 -2
  26. package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.js.map +1 -1
  27. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js +7 -11
  28. package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js.map +1 -1
  29. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +6 -6
  30. package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -1
  31. package/lib/analyses/TypedHttpRouteAnalyzer.d.ts +1 -1
  32. package/lib/analyses/TypedHttpRouteAnalyzer.js +6 -8
  33. package/lib/analyses/TypedHttpRouteAnalyzer.js.map +1 -1
  34. package/lib/executable/internal/NestiaConfigLoader.js +111 -52
  35. package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
  36. package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
  37. package/lib/executable/sdk.js +0 -0
  38. package/lib/generates/SwaggerGenerator.d.ts +1 -1
  39. package/lib/generates/SwaggerGenerator.js +11 -12
  40. package/lib/generates/SwaggerGenerator.js.map +1 -1
  41. package/lib/generates/internal/E2eFileProgrammer.js +8 -9
  42. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  43. package/lib/generates/internal/SdkAliasCollection.d.ts +2 -2
  44. package/lib/generates/internal/SdkAliasCollection.js +2 -2
  45. package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
  46. package/lib/generates/internal/SdkDistributionComposer.js +1 -1
  47. package/lib/generates/internal/SdkHttpCloneProgrammer.js.map +1 -1
  48. package/lib/generates/internal/SdkHttpCloneReferencer.js.map +1 -1
  49. package/lib/generates/internal/SdkHttpFunctionProgrammer.js +11 -12
  50. package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
  51. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +13 -16
  52. package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
  53. package/lib/generates/internal/SdkHttpRouteProgrammer.js +4 -4
  54. package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -1
  55. package/lib/generates/internal/SdkHttpSimulationProgrammer.js +12 -16
  56. package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
  57. package/lib/generates/internal/SdkImportWizard.js +2 -2
  58. package/lib/generates/internal/SdkImportWizard.js.map +1 -1
  59. package/lib/generates/internal/SdkTypeProgrammer.d.ts +2 -3
  60. package/lib/generates/internal/SdkTypeProgrammer.js +6 -7
  61. package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
  62. package/lib/generates/internal/SdkTypeTagProgrammer.d.ts +1 -1
  63. package/lib/generates/internal/SdkTypeTagProgrammer.js +11 -11
  64. package/lib/generates/internal/SdkTypeTagProgrammer.js.map +1 -1
  65. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +6 -8
  66. package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
  67. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +2 -2
  68. package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
  69. package/lib/generates/internal/SwaggerOperationComposer.d.ts +3 -3
  70. package/lib/generates/internal/SwaggerOperationComposer.js.map +1 -1
  71. package/lib/generates/internal/SwaggerOperationParameterComposer.d.ts +1 -1
  72. package/lib/generates/internal/SwaggerOperationParameterComposer.js +10 -8
  73. package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -1
  74. package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +3 -3
  75. package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -1
  76. package/lib/module.d.ts +1 -0
  77. package/lib/module.js +1 -0
  78. package/lib/module.js.map +1 -1
  79. package/lib/structures/IReflectHttpOperationException.d.ts +3 -4
  80. package/lib/structures/IReflectHttpOperationParameter.d.ts +3 -5
  81. package/lib/structures/IReflectHttpOperationSuccess.d.ts +3 -4
  82. package/lib/structures/ITypedApplication.d.ts +1 -1
  83. package/lib/structures/ITypedHttpRouteException.d.ts +2 -2
  84. package/lib/structures/ITypedHttpRouteParameter.d.ts +2 -2
  85. package/lib/structures/ITypedHttpRouteSuccess.d.ts +2 -2
  86. package/lib/transformers/IOperationMetadata.d.ts +2 -4
  87. package/lib/transformers/ISdkOperationTransformerContext.d.ts +1 -1
  88. package/lib/transformers/SdkOperationProgrammer.js +8 -10
  89. package/lib/transformers/SdkOperationProgrammer.js.map +1 -1
  90. package/lib/transformers/SdkOperationTransformer.js +6 -8
  91. package/lib/transformers/SdkOperationTransformer.js.map +1 -1
  92. package/lib/transformers/TextPlainValidator.d.ts +2 -2
  93. package/lib/transformers/TextPlainValidator.js.map +1 -1
  94. package/lib/utils/MetadataUtil.d.ts +2 -2
  95. package/lib/utils/MetadataUtil.js.map +1 -1
  96. package/lib/validators/HttpHeadersValidator.d.ts +2 -3
  97. package/lib/validators/HttpHeadersValidator.js +2 -2
  98. package/lib/validators/HttpHeadersValidator.js.map +1 -1
  99. package/lib/validators/HttpQueryValidator.d.ts +2 -3
  100. package/lib/validators/HttpQueryValidator.js +2 -2
  101. package/lib/validators/HttpQueryValidator.js.map +1 -1
  102. package/package.json +44 -30
  103. package/src/INestiaConfig.ts +267 -267
  104. package/src/NestiaSdkApplication.ts +307 -307
  105. package/src/NestiaSwaggerComposer.ts +143 -138
  106. package/src/analyses/AccessorAnalyzer.ts +67 -67
  107. package/src/analyses/DtoAnalyzer.ts +260 -260
  108. package/src/analyses/ImportAnalyzer.ts +126 -126
  109. package/src/analyses/ReflectHttpOperationAnalyzer.ts +183 -183
  110. package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +72 -71
  111. package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +350 -348
  112. package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +126 -127
  113. package/src/analyses/TypedHttpRouteAnalyzer.ts +208 -204
  114. package/src/executable/internal/NestiaConfigLoader.ts +85 -78
  115. package/src/executable/internal/NestiaSdkCommand.ts +107 -103
  116. package/src/generates/SwaggerGenerator.ts +291 -284
  117. package/src/generates/internal/E2eFileProgrammer.ts +196 -197
  118. package/src/generates/internal/FilePrinter.ts +64 -64
  119. package/src/generates/internal/ImportDictionary.ts +192 -192
  120. package/src/generates/internal/SdkAliasCollection.ts +260 -261
  121. package/src/generates/internal/SdkFileProgrammer.ts +110 -110
  122. package/src/generates/internal/SdkHttpCloneProgrammer.ts +126 -124
  123. package/src/generates/internal/SdkHttpCloneReferencer.ts +77 -77
  124. package/src/generates/internal/SdkHttpFunctionProgrammer.ts +278 -279
  125. package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +502 -500
  126. package/src/generates/internal/SdkHttpRouteProgrammer.ts +109 -108
  127. package/src/generates/internal/SdkHttpSimulationProgrammer.ts +312 -310
  128. package/src/generates/internal/SdkImportWizard.ts +62 -62
  129. package/src/generates/internal/SdkTypeProgrammer.ts +388 -385
  130. package/src/generates/internal/SdkTypeTagProgrammer.ts +114 -104
  131. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +379 -381
  132. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +302 -302
  133. package/src/generates/internal/SwaggerOperationComposer.ts +119 -119
  134. package/src/generates/internal/SwaggerOperationParameterComposer.ts +161 -162
  135. package/src/generates/internal/SwaggerOperationResponseComposer.ts +110 -110
  136. package/src/module.ts +4 -3
  137. package/src/structures/IReflectHttpOperationException.ts +18 -19
  138. package/src/structures/IReflectHttpOperationParameter.ts +79 -77
  139. package/src/structures/IReflectHttpOperationSuccess.ts +21 -22
  140. package/src/structures/ITypedApplication.ts +11 -11
  141. package/src/structures/ITypedHttpRouteException.ts +15 -15
  142. package/src/structures/ITypedHttpRouteParameter.ts +41 -41
  143. package/src/structures/ITypedHttpRouteSuccess.ts +22 -22
  144. package/src/transformers/IOperationMetadata.ts +46 -44
  145. package/src/transformers/ISdkOperationTransformerContext.ts +8 -8
  146. package/src/transformers/SdkOperationProgrammer.ts +240 -238
  147. package/src/transformers/SdkOperationTransformer.ts +248 -252
  148. package/src/transformers/TextPlainValidator.ts +17 -17
  149. package/src/utils/MetadataUtil.ts +26 -26
  150. package/src/validators/HttpHeadersValidator.ts +36 -34
  151. package/src/validators/HttpQueryValidator.ts +36 -34
@@ -1,500 +1,502 @@
1
- import ts from "typescript";
2
- import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
3
- import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
4
- import { LiteralFactory } from "typia/lib/factories/LiteralFactory";
5
- import { TypeFactory } from "typia/lib/factories/TypeFactory";
6
- import { Escaper } from "typia/lib/utils/Escaper";
7
-
8
- import { INestiaProject } from "../../structures/INestiaProject";
9
- import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
10
- import { FilePrinter } from "./FilePrinter";
11
- import { ImportDictionary } from "./ImportDictionary";
12
- import { SdkAliasCollection } from "./SdkAliasCollection";
13
- import { SdkHttpParameterProgrammer } from "./SdkHttpParameterProgrammer";
14
- import { SdkHttpSimulationProgrammer } from "./SdkHttpSimulationProgrammer";
15
- import { SdkImportWizard } from "./SdkImportWizard";
16
-
17
- export namespace SdkHttpNamespaceProgrammer {
18
- export const write =
19
- (project: INestiaProject) =>
20
- (importer: ImportDictionary) =>
21
- (route: ITypedHttpRoute): ts.ModuleDeclaration => {
22
- const types: ts.TypeAliasDeclaration[] =
23
- writeTypes(project)(importer)(route);
24
- return ts.factory.createModuleDeclaration(
25
- [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
26
- ts.factory.createIdentifier(route.name),
27
- ts.factory.createModuleBlock([
28
- ...types,
29
- ...(types.length ? [FilePrinter.enter()] : []),
30
- writeMetadata(project)(importer)(route),
31
- FilePrinter.enter(),
32
- writePath(project)(importer)(route),
33
- ...(project.config.simulate
34
- ? [
35
- SdkHttpSimulationProgrammer.random(project)(importer)(route),
36
- SdkHttpSimulationProgrammer.simulate(project)(importer)(route),
37
- ]
38
- : []),
39
- ...(project.config.json &&
40
- route.body &&
41
- (route.body.contentType === "application/json" ||
42
- route.body.encrypted === true)
43
- ? [writeStringify(project)(importer)]
44
- : []),
45
- ]),
46
- ts.NodeFlags.Namespace,
47
- );
48
- };
49
-
50
- const writeTypes =
51
- (project: INestiaProject) =>
52
- (importer: ImportDictionary) =>
53
- (route: ITypedHttpRoute): ts.TypeAliasDeclaration[] => {
54
- const array: ts.TypeAliasDeclaration[] = [];
55
- const declare = (name: string, type: ts.TypeNode) =>
56
- array.push(
57
- ts.factory.createTypeAliasDeclaration(
58
- [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
59
- name,
60
- undefined,
61
- type,
62
- ),
63
- );
64
- if (
65
- project.config.keyword === true &&
66
- SdkHttpParameterProgrammer.getSignificant(route, true).length !== 0
67
- )
68
- declare(
69
- "Props",
70
- SdkAliasCollection.httpProps(project)(importer)(route),
71
- );
72
- if (route.headerObject)
73
- declare(
74
- "Headers",
75
- SdkAliasCollection.headers(project)(importer)(route.headerObject),
76
- );
77
- if (route.queryObject)
78
- declare(
79
- "Query",
80
- SdkAliasCollection.query(project)(importer)(route.queryObject),
81
- );
82
- if (route.body)
83
- declare("Body", SdkAliasCollection.body(project)(importer)(route.body));
84
- if (
85
- project.config.propagate === true ||
86
- route.success.metadata.size() !== 0
87
- )
88
- declare(
89
- "Output",
90
- SdkAliasCollection.response(project)(importer)(route),
91
- );
92
- return array;
93
- };
94
-
95
- const writeMetadata =
96
- (project: INestiaProject) =>
97
- (importer: ImportDictionary) =>
98
- (route: ITypedHttpRoute): ts.VariableStatement =>
99
- constant("METADATA")(
100
- ts.factory.createAsExpression(
101
- ts.factory.createObjectLiteralExpression(
102
- [
103
- ts.factory.createPropertyAssignment(
104
- "method",
105
- ts.factory.createStringLiteral(route.method),
106
- ),
107
- ts.factory.createPropertyAssignment(
108
- "path",
109
- ts.factory.createStringLiteral(route.path),
110
- ),
111
- ts.factory.createPropertyAssignment(
112
- "request",
113
- route.body
114
- ? LiteralFactory.write(
115
- route.body !== undefined
116
- ? {
117
- type: route.body.contentType,
118
- encrypted: !!route.body.encrypted,
119
- }
120
- : {
121
- type: "application/json",
122
- encrypted: false,
123
- },
124
- )
125
- : ts.factory.createNull(),
126
- ),
127
- ts.factory.createPropertyAssignment(
128
- "response",
129
- route.method !== "HEAD"
130
- ? LiteralFactory.write({
131
- type: route.success.contentType,
132
- encrypted: !!route.success.encrypted,
133
- })
134
- : ts.factory.createNull(),
135
- ),
136
- ts.factory.createPropertyAssignment(
137
- "status",
138
- route.success.status !== null
139
- ? ExpressionFactory.number(route.success.status)
140
- : ts.factory.createNull(),
141
- ),
142
- ...(route.success.contentType ===
143
- "application/x-www-form-urlencoded"
144
- ? [
145
- ts.factory.createPropertyAssignment(
146
- "parseQuery",
147
- ts.factory.createCallExpression(
148
- ts.factory.createIdentifier(
149
- `${SdkImportWizard.typia(importer)}.http.createAssertQuery`,
150
- ),
151
- [
152
- project.config.clone === true
153
- ? SdkAliasCollection.from(project)(importer)(
154
- route.success.metadata,
155
- )
156
- : SdkAliasCollection.name(route.success),
157
- ],
158
- undefined,
159
- ),
160
- ),
161
- ]
162
- : []),
163
- ],
164
- true,
165
- ),
166
- ts.factory.createTypeReferenceNode(
167
- ts.factory.createIdentifier("const"),
168
- ),
169
- ),
170
- );
171
-
172
- const writePath =
173
- (project: INestiaProject) =>
174
- (importer: ImportDictionary) =>
175
- (route: ITypedHttpRoute): ts.VariableStatement => {
176
- const out = (body: ts.ConciseBody) =>
177
- constant("path")(
178
- ts.factory.createArrowFunction(
179
- [],
180
- [],
181
- SdkHttpParameterProgrammer.getParameterDeclarations({
182
- project,
183
- importer,
184
- route,
185
- body: false,
186
- prefix: false,
187
- }),
188
- undefined,
189
- undefined,
190
- body,
191
- ),
192
- );
193
- const parameters = SdkHttpParameterProgrammer.getSignificant(
194
- route,
195
- false,
196
- );
197
- if (parameters.length === 0)
198
- return out(ts.factory.createStringLiteral(route.path));
199
-
200
- const access = (name: string) =>
201
- project.config.keyword === true ? `props.${name}` : name;
202
- const template = () => {
203
- const split: string[] = route.path.split(":");
204
- if (split.length === 1)
205
- return ts.factory.createStringLiteral(route.path);
206
- return ts.factory.createTemplateExpression(
207
- ts.factory.createTemplateHead(split[0]),
208
- split.slice(1).map((s, i, arr) => {
209
- const name: string = s.split("/")[0];
210
- return ts.factory.createTemplateSpan(
211
- ts.factory.createCallExpression(
212
- ts.factory.createIdentifier("encodeURIComponent"),
213
- undefined,
214
- [
215
- ts.factory.createBinaryExpression(
216
- ts.factory.createCallChain(
217
- ts.factory.createPropertyAccessChain(
218
- ts.factory.createIdentifier(
219
- access(
220
- route.pathParameters.find((p) => p.field === name)!
221
- .name,
222
- ),
223
- ),
224
- ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
225
- "toString",
226
- ),
227
- undefined,
228
- undefined,
229
- [],
230
- ),
231
- ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
232
- ts.factory.createStringLiteral("null"),
233
- ),
234
- ],
235
- ),
236
- (i !== arr.length - 1
237
- ? ts.factory.createTemplateMiddle
238
- : ts.factory.createTemplateTail)(s.substring(name.length)),
239
- );
240
- }),
241
- );
242
- };
243
- if (route.queryObject === null && route.queryParameters.length === 0)
244
- return out(template());
245
-
246
- const block = (expr: ts.Expression) => {
247
- const computeName = (str: string): string =>
248
- parameters.find((p) => p.name === str) !== undefined
249
- ? computeName("_" + str)
250
- : str;
251
- const variables: string = computeName("variables");
252
- return ts.factory.createBlock(
253
- [
254
- local(variables)("URLSearchParams")(
255
- ts.factory.createNewExpression(
256
- ts.factory.createIdentifier("URLSearchParams"),
257
- [],
258
- [],
259
- ),
260
- ),
261
- ts.factory.createForOfStatement(
262
- undefined,
263
- ts.factory.createVariableDeclarationList(
264
- [
265
- ts.factory.createVariableDeclaration(
266
- ts.factory.createArrayBindingPattern([
267
- ts.factory.createBindingElement(
268
- undefined,
269
- undefined,
270
- ts.factory.createIdentifier("key"),
271
- undefined,
272
- ),
273
- ts.factory.createBindingElement(
274
- undefined,
275
- undefined,
276
- ts.factory.createIdentifier("value"),
277
- undefined,
278
- ),
279
- ]),
280
- undefined,
281
- undefined,
282
- undefined,
283
- ),
284
- ],
285
- ts.NodeFlags.Const,
286
- ),
287
- ts.factory.createCallExpression(
288
- ts.factory.createIdentifier("Object.entries"),
289
- undefined,
290
- [
291
- ts.factory.createAsExpression(
292
- expr,
293
- TypeFactory.keyword("any"),
294
- ),
295
- ],
296
- ),
297
- ts.factory.createIfStatement(
298
- ts.factory.createStrictEquality(
299
- ts.factory.createIdentifier("undefined"),
300
- ts.factory.createIdentifier("value"),
301
- ),
302
- ts.factory.createContinueStatement(),
303
- ts.factory.createIfStatement(
304
- ts.factory.createCallExpression(
305
- ts.factory.createIdentifier("Array.isArray"),
306
- undefined,
307
- [ts.factory.createIdentifier("value")],
308
- ),
309
- ts.factory.createExpressionStatement(
310
- ts.factory.createCallExpression(
311
- ts.factory.createPropertyAccessExpression(
312
- ts.factory.createIdentifier("value"),
313
- ts.factory.createIdentifier("forEach"),
314
- ),
315
- undefined,
316
- [
317
- ts.factory.createArrowFunction(
318
- undefined,
319
- undefined,
320
- [IdentifierFactory.parameter("elem")],
321
- undefined,
322
- undefined,
323
- ts.factory.createCallExpression(
324
- IdentifierFactory.access(
325
- ts.factory.createIdentifier(variables),
326
- "append",
327
- ),
328
- undefined,
329
- [
330
- ts.factory.createIdentifier("key"),
331
- ts.factory.createCallExpression(
332
- ts.factory.createIdentifier("String"),
333
- undefined,
334
- [ts.factory.createIdentifier("elem")],
335
- ),
336
- ],
337
- ),
338
- ),
339
- ],
340
- ),
341
- ),
342
- ts.factory.createExpressionStatement(
343
- ts.factory.createCallExpression(
344
- IdentifierFactory.access(
345
- ts.factory.createIdentifier(variables),
346
- "set",
347
- ),
348
- undefined,
349
- [
350
- ts.factory.createIdentifier("key"),
351
- ts.factory.createCallExpression(
352
- ts.factory.createIdentifier("String"),
353
- undefined,
354
- [ts.factory.createIdentifier("value")],
355
- ),
356
- ],
357
- ),
358
- ),
359
- ),
360
- ),
361
- ),
362
- local("location")("string")(template()),
363
- ts.factory.createReturnStatement(
364
- ts.factory.createConditionalExpression(
365
- ts.factory.createStrictEquality(
366
- ExpressionFactory.number(0),
367
- IdentifierFactory.access(
368
- ts.factory.createIdentifier(variables),
369
- "size",
370
- ),
371
- ),
372
- undefined,
373
- ts.factory.createIdentifier("location"),
374
- undefined,
375
- ts.factory.createTemplateExpression(
376
- ts.factory.createTemplateHead(""),
377
- [
378
- ts.factory.createTemplateSpan(
379
- ts.factory.createIdentifier("location"),
380
- ts.factory.createTemplateMiddle("?"),
381
- ),
382
- ts.factory.createTemplateSpan(
383
- ts.factory.createCallExpression(
384
- IdentifierFactory.access(
385
- ts.factory.createIdentifier(variables),
386
- "toString",
387
- ),
388
- undefined,
389
- undefined,
390
- ),
391
- ts.factory.createTemplateTail(""),
392
- ),
393
- ],
394
- ),
395
- ),
396
- ),
397
- ],
398
- true,
399
- );
400
- };
401
- if (route.queryObject !== null && route.queryParameters.length === 0)
402
- return out(
403
- block(
404
- route.queryObject.metadata.isRequired() === false
405
- ? ts.factory.createBinaryExpression(
406
- ts.factory.createIdentifier(route.queryObject.name),
407
- ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
408
- ts.factory.createObjectLiteralExpression([], false),
409
- )
410
- : ts.factory.createIdentifier(access(route.queryObject.name)),
411
- ),
412
- );
413
- return out(
414
- block(
415
- ts.factory.createObjectLiteralExpression(
416
- [
417
- ...(route.queryObject
418
- ? [
419
- ts.factory.createSpreadAssignment(
420
- ts.factory.createIdentifier(
421
- access(route.queryObject.name),
422
- ),
423
- ),
424
- ]
425
- : []),
426
- ...route.queryParameters.map((q) =>
427
- ts.factory.createPropertyAssignment(
428
- Escaper.variable(q.field!)
429
- ? q.field!
430
- : ts.factory.createStringLiteral(q.field!),
431
- ts.factory.createIdentifier(access(q.name)),
432
- ),
433
- ),
434
- ],
435
- true,
436
- ),
437
- ),
438
- );
439
- };
440
-
441
- const writeStringify =
442
- (project: INestiaProject) =>
443
- (importer: ImportDictionary): ts.VariableStatement =>
444
- constant("stringify")(
445
- ts.factory.createArrowFunction(
446
- [],
447
- undefined,
448
- [
449
- IdentifierFactory.parameter(
450
- "input",
451
- ts.factory.createTypeReferenceNode("Body"),
452
- ),
453
- ],
454
- undefined,
455
- undefined,
456
- ts.factory.createCallExpression(
457
- IdentifierFactory.access(
458
- IdentifierFactory.access(
459
- ts.factory.createIdentifier(SdkImportWizard.typia(importer)),
460
- "json",
461
- ),
462
- project.config.assert ? "stringify" : "assertStringify",
463
- ),
464
- undefined,
465
- [ts.factory.createIdentifier("input")],
466
- ),
467
- ),
468
- );
469
- }
470
-
471
- const local = (name: string) => (type: string) => (expression: ts.Expression) =>
472
- ts.factory.createVariableStatement(
473
- [],
474
- ts.factory.createVariableDeclarationList(
475
- [
476
- ts.factory.createVariableDeclaration(
477
- name,
478
- undefined,
479
- ts.factory.createTypeReferenceNode(type),
480
- expression,
481
- ),
482
- ],
483
- ts.NodeFlags.Const,
484
- ),
485
- );
486
- const constant = (name: string) => (expression: ts.Expression) =>
487
- ts.factory.createVariableStatement(
488
- [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
489
- ts.factory.createVariableDeclarationList(
490
- [
491
- ts.factory.createVariableDeclaration(
492
- name,
493
- undefined,
494
- undefined,
495
- expression,
496
- ),
497
- ],
498
- ts.NodeFlags.Const,
499
- ),
500
- );
1
+ import {
2
+ ExpressionFactory,
3
+ IdentifierFactory,
4
+ LiteralFactory,
5
+ TypeFactory,
6
+ } from "@typia/core";
7
+ import { NamingConvention } from "@typia/utils";
8
+ import ts from "typescript";
9
+
10
+ import { INestiaProject } from "../../structures/INestiaProject";
11
+ import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
12
+ import { FilePrinter } from "./FilePrinter";
13
+ import { ImportDictionary } from "./ImportDictionary";
14
+ import { SdkAliasCollection } from "./SdkAliasCollection";
15
+ import { SdkHttpParameterProgrammer } from "./SdkHttpParameterProgrammer";
16
+ import { SdkHttpSimulationProgrammer } from "./SdkHttpSimulationProgrammer";
17
+ import { SdkImportWizard } from "./SdkImportWizard";
18
+
19
+ export namespace SdkHttpNamespaceProgrammer {
20
+ export const write =
21
+ (project: INestiaProject) =>
22
+ (importer: ImportDictionary) =>
23
+ (route: ITypedHttpRoute): ts.ModuleDeclaration => {
24
+ const types: ts.TypeAliasDeclaration[] =
25
+ writeTypes(project)(importer)(route);
26
+ return ts.factory.createModuleDeclaration(
27
+ [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
28
+ ts.factory.createIdentifier(route.name),
29
+ ts.factory.createModuleBlock([
30
+ ...types,
31
+ ...(types.length ? [FilePrinter.enter()] : []),
32
+ writeMetadata(project)(importer)(route),
33
+ FilePrinter.enter(),
34
+ writePath(project)(importer)(route),
35
+ ...(project.config.simulate
36
+ ? [
37
+ SdkHttpSimulationProgrammer.random(project)(importer)(route),
38
+ SdkHttpSimulationProgrammer.simulate(project)(importer)(route),
39
+ ]
40
+ : []),
41
+ ...(project.config.json &&
42
+ route.body &&
43
+ (route.body.contentType === "application/json" ||
44
+ route.body.encrypted === true)
45
+ ? [writeStringify(project)(importer)]
46
+ : []),
47
+ ]),
48
+ ts.NodeFlags.Namespace,
49
+ );
50
+ };
51
+
52
+ const writeTypes =
53
+ (project: INestiaProject) =>
54
+ (importer: ImportDictionary) =>
55
+ (route: ITypedHttpRoute): ts.TypeAliasDeclaration[] => {
56
+ const array: ts.TypeAliasDeclaration[] = [];
57
+ const declare = (name: string, type: ts.TypeNode) =>
58
+ array.push(
59
+ ts.factory.createTypeAliasDeclaration(
60
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
61
+ name,
62
+ undefined,
63
+ type,
64
+ ),
65
+ );
66
+ if (
67
+ project.config.keyword === true &&
68
+ SdkHttpParameterProgrammer.getSignificant(route, true).length !== 0
69
+ )
70
+ declare(
71
+ "Props",
72
+ SdkAliasCollection.httpProps(project)(importer)(route),
73
+ );
74
+ if (route.headerObject)
75
+ declare(
76
+ "Headers",
77
+ SdkAliasCollection.headers(project)(importer)(route.headerObject),
78
+ );
79
+ if (route.queryObject)
80
+ declare(
81
+ "Query",
82
+ SdkAliasCollection.query(project)(importer)(route.queryObject),
83
+ );
84
+ if (route.body)
85
+ declare("Body", SdkAliasCollection.body(project)(importer)(route.body));
86
+ if (
87
+ project.config.propagate === true ||
88
+ route.success.metadata.size() !== 0
89
+ )
90
+ declare(
91
+ "Output",
92
+ SdkAliasCollection.response(project)(importer)(route),
93
+ );
94
+ return array;
95
+ };
96
+
97
+ const writeMetadata =
98
+ (project: INestiaProject) =>
99
+ (importer: ImportDictionary) =>
100
+ (route: ITypedHttpRoute): ts.VariableStatement =>
101
+ constant("METADATA")(
102
+ ts.factory.createAsExpression(
103
+ ts.factory.createObjectLiteralExpression(
104
+ [
105
+ ts.factory.createPropertyAssignment(
106
+ "method",
107
+ ts.factory.createStringLiteral(route.method),
108
+ ),
109
+ ts.factory.createPropertyAssignment(
110
+ "path",
111
+ ts.factory.createStringLiteral(route.path),
112
+ ),
113
+ ts.factory.createPropertyAssignment(
114
+ "request",
115
+ route.body
116
+ ? LiteralFactory.write(
117
+ route.body !== undefined
118
+ ? {
119
+ type: route.body.contentType,
120
+ encrypted: !!route.body.encrypted,
121
+ }
122
+ : {
123
+ type: "application/json",
124
+ encrypted: false,
125
+ },
126
+ )
127
+ : ts.factory.createNull(),
128
+ ),
129
+ ts.factory.createPropertyAssignment(
130
+ "response",
131
+ route.method !== "HEAD"
132
+ ? LiteralFactory.write({
133
+ type: route.success.contentType,
134
+ encrypted: !!route.success.encrypted,
135
+ })
136
+ : ts.factory.createNull(),
137
+ ),
138
+ ts.factory.createPropertyAssignment(
139
+ "status",
140
+ route.success.status !== null
141
+ ? ExpressionFactory.number(route.success.status)
142
+ : ts.factory.createNull(),
143
+ ),
144
+ ...(route.success.contentType ===
145
+ "application/x-www-form-urlencoded"
146
+ ? [
147
+ ts.factory.createPropertyAssignment(
148
+ "parseQuery",
149
+ ts.factory.createCallExpression(
150
+ ts.factory.createIdentifier(
151
+ `${SdkImportWizard.typia(importer)}.http.createAssertQuery`,
152
+ ),
153
+ [
154
+ project.config.clone === true
155
+ ? SdkAliasCollection.from(project)(importer)(
156
+ route.success.metadata,
157
+ )
158
+ : SdkAliasCollection.name(route.success),
159
+ ],
160
+ undefined,
161
+ ),
162
+ ),
163
+ ]
164
+ : []),
165
+ ],
166
+ true,
167
+ ),
168
+ ts.factory.createTypeReferenceNode(
169
+ ts.factory.createIdentifier("const"),
170
+ ),
171
+ ),
172
+ );
173
+
174
+ const writePath =
175
+ (project: INestiaProject) =>
176
+ (importer: ImportDictionary) =>
177
+ (route: ITypedHttpRoute): ts.VariableStatement => {
178
+ const out = (body: ts.ConciseBody) =>
179
+ constant("path")(
180
+ ts.factory.createArrowFunction(
181
+ [],
182
+ [],
183
+ SdkHttpParameterProgrammer.getParameterDeclarations({
184
+ project,
185
+ importer,
186
+ route,
187
+ body: false,
188
+ prefix: false,
189
+ }),
190
+ undefined,
191
+ undefined,
192
+ body,
193
+ ),
194
+ );
195
+ const parameters = SdkHttpParameterProgrammer.getSignificant(
196
+ route,
197
+ false,
198
+ );
199
+ if (parameters.length === 0)
200
+ return out(ts.factory.createStringLiteral(route.path));
201
+
202
+ const access = (name: string) =>
203
+ project.config.keyword === true ? `props.${name}` : name;
204
+ const template = () => {
205
+ const split: string[] = route.path.split(":");
206
+ if (split.length === 1)
207
+ return ts.factory.createStringLiteral(route.path);
208
+ return ts.factory.createTemplateExpression(
209
+ ts.factory.createTemplateHead(split[0]!),
210
+ split.slice(1).map((s, i, arr) => {
211
+ const name: string = s.split("/")[0]!;
212
+ return ts.factory.createTemplateSpan(
213
+ ts.factory.createCallExpression(
214
+ ts.factory.createIdentifier("encodeURIComponent"),
215
+ undefined,
216
+ [
217
+ ts.factory.createBinaryExpression(
218
+ ts.factory.createCallChain(
219
+ ts.factory.createPropertyAccessChain(
220
+ ts.factory.createIdentifier(
221
+ access(
222
+ route.pathParameters.find((p) => p.field === name)!
223
+ .name,
224
+ ),
225
+ ),
226
+ ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
227
+ "toString",
228
+ ),
229
+ undefined,
230
+ undefined,
231
+ [],
232
+ ),
233
+ ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
234
+ ts.factory.createStringLiteral("null"),
235
+ ),
236
+ ],
237
+ ),
238
+ (i !== arr.length - 1
239
+ ? ts.factory.createTemplateMiddle
240
+ : ts.factory.createTemplateTail)(s.substring(name.length)),
241
+ );
242
+ }),
243
+ );
244
+ };
245
+ if (route.queryObject === null && route.queryParameters.length === 0)
246
+ return out(template());
247
+
248
+ const block = (expr: ts.Expression) => {
249
+ const computeName = (str: string): string =>
250
+ parameters.find((p) => p.name === str) !== undefined
251
+ ? computeName("_" + str)
252
+ : str;
253
+ const variables: string = computeName("variables");
254
+ return ts.factory.createBlock(
255
+ [
256
+ local(variables)("URLSearchParams")(
257
+ ts.factory.createNewExpression(
258
+ ts.factory.createIdentifier("URLSearchParams"),
259
+ [],
260
+ [],
261
+ ),
262
+ ),
263
+ ts.factory.createForOfStatement(
264
+ undefined,
265
+ ts.factory.createVariableDeclarationList(
266
+ [
267
+ ts.factory.createVariableDeclaration(
268
+ ts.factory.createArrayBindingPattern([
269
+ ts.factory.createBindingElement(
270
+ undefined,
271
+ undefined,
272
+ ts.factory.createIdentifier("key"),
273
+ undefined,
274
+ ),
275
+ ts.factory.createBindingElement(
276
+ undefined,
277
+ undefined,
278
+ ts.factory.createIdentifier("value"),
279
+ undefined,
280
+ ),
281
+ ]),
282
+ undefined,
283
+ undefined,
284
+ undefined,
285
+ ),
286
+ ],
287
+ ts.NodeFlags.Const,
288
+ ),
289
+ ts.factory.createCallExpression(
290
+ ts.factory.createIdentifier("Object.entries"),
291
+ undefined,
292
+ [
293
+ ts.factory.createAsExpression(
294
+ expr,
295
+ TypeFactory.keyword("any"),
296
+ ),
297
+ ],
298
+ ),
299
+ ts.factory.createIfStatement(
300
+ ts.factory.createStrictEquality(
301
+ ts.factory.createIdentifier("undefined"),
302
+ ts.factory.createIdentifier("value"),
303
+ ),
304
+ ts.factory.createContinueStatement(),
305
+ ts.factory.createIfStatement(
306
+ ts.factory.createCallExpression(
307
+ ts.factory.createIdentifier("Array.isArray"),
308
+ undefined,
309
+ [ts.factory.createIdentifier("value")],
310
+ ),
311
+ ts.factory.createExpressionStatement(
312
+ ts.factory.createCallExpression(
313
+ ts.factory.createPropertyAccessExpression(
314
+ ts.factory.createIdentifier("value"),
315
+ ts.factory.createIdentifier("forEach"),
316
+ ),
317
+ undefined,
318
+ [
319
+ ts.factory.createArrowFunction(
320
+ undefined,
321
+ undefined,
322
+ [IdentifierFactory.parameter("elem")],
323
+ undefined,
324
+ undefined,
325
+ ts.factory.createCallExpression(
326
+ IdentifierFactory.access(
327
+ ts.factory.createIdentifier(variables),
328
+ "append",
329
+ ),
330
+ undefined,
331
+ [
332
+ ts.factory.createIdentifier("key"),
333
+ ts.factory.createCallExpression(
334
+ ts.factory.createIdentifier("String"),
335
+ undefined,
336
+ [ts.factory.createIdentifier("elem")],
337
+ ),
338
+ ],
339
+ ),
340
+ ),
341
+ ],
342
+ ),
343
+ ),
344
+ ts.factory.createExpressionStatement(
345
+ ts.factory.createCallExpression(
346
+ IdentifierFactory.access(
347
+ ts.factory.createIdentifier(variables),
348
+ "set",
349
+ ),
350
+ undefined,
351
+ [
352
+ ts.factory.createIdentifier("key"),
353
+ ts.factory.createCallExpression(
354
+ ts.factory.createIdentifier("String"),
355
+ undefined,
356
+ [ts.factory.createIdentifier("value")],
357
+ ),
358
+ ],
359
+ ),
360
+ ),
361
+ ),
362
+ ),
363
+ ),
364
+ local("location")("string")(template()),
365
+ ts.factory.createReturnStatement(
366
+ ts.factory.createConditionalExpression(
367
+ ts.factory.createStrictEquality(
368
+ ExpressionFactory.number(0),
369
+ IdentifierFactory.access(
370
+ ts.factory.createIdentifier(variables),
371
+ "size",
372
+ ),
373
+ ),
374
+ undefined,
375
+ ts.factory.createIdentifier("location"),
376
+ undefined,
377
+ ts.factory.createTemplateExpression(
378
+ ts.factory.createTemplateHead(""),
379
+ [
380
+ ts.factory.createTemplateSpan(
381
+ ts.factory.createIdentifier("location"),
382
+ ts.factory.createTemplateMiddle("?"),
383
+ ),
384
+ ts.factory.createTemplateSpan(
385
+ ts.factory.createCallExpression(
386
+ IdentifierFactory.access(
387
+ ts.factory.createIdentifier(variables),
388
+ "toString",
389
+ ),
390
+ undefined,
391
+ undefined,
392
+ ),
393
+ ts.factory.createTemplateTail(""),
394
+ ),
395
+ ],
396
+ ),
397
+ ),
398
+ ),
399
+ ],
400
+ true,
401
+ );
402
+ };
403
+ if (route.queryObject !== null && route.queryParameters.length === 0)
404
+ return out(
405
+ block(
406
+ route.queryObject.metadata.isRequired() === false
407
+ ? ts.factory.createBinaryExpression(
408
+ ts.factory.createIdentifier(route.queryObject.name),
409
+ ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
410
+ ts.factory.createObjectLiteralExpression([], false),
411
+ )
412
+ : ts.factory.createIdentifier(access(route.queryObject.name)),
413
+ ),
414
+ );
415
+ return out(
416
+ block(
417
+ ts.factory.createObjectLiteralExpression(
418
+ [
419
+ ...(route.queryObject
420
+ ? [
421
+ ts.factory.createSpreadAssignment(
422
+ ts.factory.createIdentifier(
423
+ access(route.queryObject.name),
424
+ ),
425
+ ),
426
+ ]
427
+ : []),
428
+ ...route.queryParameters.map((q) =>
429
+ ts.factory.createPropertyAssignment(
430
+ NamingConvention.variable(q.field!)
431
+ ? q.field!
432
+ : ts.factory.createStringLiteral(q.field!),
433
+ ts.factory.createIdentifier(access(q.name)),
434
+ ),
435
+ ),
436
+ ],
437
+ true,
438
+ ),
439
+ ),
440
+ );
441
+ };
442
+
443
+ const writeStringify =
444
+ (project: INestiaProject) =>
445
+ (importer: ImportDictionary): ts.VariableStatement =>
446
+ constant("stringify")(
447
+ ts.factory.createArrowFunction(
448
+ [],
449
+ undefined,
450
+ [
451
+ IdentifierFactory.parameter(
452
+ "input",
453
+ ts.factory.createTypeReferenceNode("Body"),
454
+ ),
455
+ ],
456
+ undefined,
457
+ undefined,
458
+ ts.factory.createCallExpression(
459
+ IdentifierFactory.access(
460
+ IdentifierFactory.access(
461
+ ts.factory.createIdentifier(SdkImportWizard.typia(importer)),
462
+ "json",
463
+ ),
464
+ project.config.assert ? "stringify" : "assertStringify",
465
+ ),
466
+ undefined,
467
+ [ts.factory.createIdentifier("input")],
468
+ ),
469
+ ),
470
+ );
471
+ }
472
+
473
+ const local = (name: string) => (type: string) => (expression: ts.Expression) =>
474
+ ts.factory.createVariableStatement(
475
+ [],
476
+ ts.factory.createVariableDeclarationList(
477
+ [
478
+ ts.factory.createVariableDeclaration(
479
+ name,
480
+ undefined,
481
+ ts.factory.createTypeReferenceNode(type),
482
+ expression,
483
+ ),
484
+ ],
485
+ ts.NodeFlags.Const,
486
+ ),
487
+ );
488
+ const constant = (name: string) => (expression: ts.Expression) =>
489
+ ts.factory.createVariableStatement(
490
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
491
+ ts.factory.createVariableDeclarationList(
492
+ [
493
+ ts.factory.createVariableDeclaration(
494
+ name,
495
+ undefined,
496
+ undefined,
497
+ expression,
498
+ ),
499
+ ],
500
+ ts.NodeFlags.Const,
501
+ ),
502
+ );