@nestia/sdk 3.1.0-dev.20240426 → 3.1.0-dev.20240430

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