@nestia/sdk 11.0.0-dev.20260316 → 11.0.1

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 (65) 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/executable/internal/NestiaConfigLoader.js +5 -5
  15. package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
  16. package/package.json +8 -8
  17. package/src/INestiaConfig.ts +267 -267
  18. package/src/NestiaSdkApplication.ts +307 -307
  19. package/src/NestiaSwaggerComposer.ts +143 -143
  20. package/src/analyses/AccessorAnalyzer.ts +67 -67
  21. package/src/analyses/DtoAnalyzer.ts +260 -260
  22. package/src/analyses/ImportAnalyzer.ts +126 -126
  23. package/src/analyses/ReflectHttpOperationAnalyzer.ts +183 -183
  24. package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +72 -72
  25. package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +350 -350
  26. package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +126 -126
  27. package/src/analyses/TypedHttpRouteAnalyzer.ts +208 -208
  28. package/src/executable/internal/NestiaConfigLoader.ts +85 -85
  29. package/src/executable/internal/NestiaSdkCommand.ts +107 -107
  30. package/src/generates/SwaggerGenerator.ts +291 -291
  31. package/src/generates/internal/E2eFileProgrammer.ts +196 -196
  32. package/src/generates/internal/FilePrinter.ts +64 -64
  33. package/src/generates/internal/ImportDictionary.ts +192 -192
  34. package/src/generates/internal/SdkAliasCollection.ts +260 -260
  35. package/src/generates/internal/SdkFileProgrammer.ts +110 -110
  36. package/src/generates/internal/SdkHttpCloneProgrammer.ts +126 -126
  37. package/src/generates/internal/SdkHttpCloneReferencer.ts +77 -77
  38. package/src/generates/internal/SdkHttpFunctionProgrammer.ts +278 -278
  39. package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +502 -502
  40. package/src/generates/internal/SdkHttpRouteProgrammer.ts +109 -109
  41. package/src/generates/internal/SdkHttpSimulationProgrammer.ts +312 -312
  42. package/src/generates/internal/SdkImportWizard.ts +62 -62
  43. package/src/generates/internal/SdkTypeProgrammer.ts +388 -388
  44. package/src/generates/internal/SdkTypeTagProgrammer.ts +114 -114
  45. package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +379 -379
  46. package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +302 -302
  47. package/src/generates/internal/SwaggerOperationComposer.ts +119 -119
  48. package/src/generates/internal/SwaggerOperationParameterComposer.ts +161 -161
  49. package/src/generates/internal/SwaggerOperationResponseComposer.ts +110 -110
  50. package/src/module.ts +4 -4
  51. package/src/structures/IReflectHttpOperationException.ts +18 -18
  52. package/src/structures/IReflectHttpOperationParameter.ts +79 -79
  53. package/src/structures/IReflectHttpOperationSuccess.ts +21 -21
  54. package/src/structures/ITypedApplication.ts +11 -11
  55. package/src/structures/ITypedHttpRouteException.ts +15 -15
  56. package/src/structures/ITypedHttpRouteParameter.ts +41 -41
  57. package/src/structures/ITypedHttpRouteSuccess.ts +22 -22
  58. package/src/transformers/IOperationMetadata.ts +46 -46
  59. package/src/transformers/ISdkOperationTransformerContext.ts +8 -8
  60. package/src/transformers/SdkOperationProgrammer.ts +240 -240
  61. package/src/transformers/SdkOperationTransformer.ts +248 -248
  62. package/src/transformers/TextPlainValidator.ts +17 -17
  63. package/src/utils/MetadataUtil.ts +26 -26
  64. package/src/validators/HttpHeadersValidator.ts +40 -40
  65. package/src/validators/HttpQueryValidator.ts +40 -40
@@ -1,502 +1,502 @@
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
- );
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
+ );