@nestia/sdk 2.5.0-dev.20240130 → 2.5.0-dev.20240130-2

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