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