@nestia/sdk 2.6.2 → 2.6.3

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