@nestia/migrate 0.11.4 → 0.11.5

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 (52) hide show
  1. package/lib/bundles/NEST_TEMPLATE.js +5 -5
  2. package/lib/bundles/NEST_TEMPLATE.js.map +1 -1
  3. package/lib/bundles/SDK_TEMPLATE.js +1 -1
  4. package/lib/utils/openapi-down-convert/converter.js +2 -2
  5. package/package.json +2 -2
  6. package/src/MigrateApplication.ts +81 -81
  7. package/src/analyzers/MigrateAnalyzer.ts +9 -9
  8. package/src/analyzers/MigrateControllerAnalyzer.ts +135 -135
  9. package/src/analyzers/MigrateMethodAnalyzer.ts +439 -439
  10. package/src/archivers/MigrateFileArchiver.ts +38 -38
  11. package/src/bundles/NEST_TEMPLATE.ts +5 -5
  12. package/src/bundles/SDK_TEMPLATE.ts +1 -1
  13. package/src/executable/bundle.ts +110 -110
  14. package/src/internal/MigrateCommander.ts +70 -70
  15. package/src/internal/MigrateInquirer.ts +86 -86
  16. package/src/module.ts +14 -14
  17. package/src/programmers/MigrateApiFileProgrammer.ts +53 -53
  18. package/src/programmers/MigrateApiFunctionProgrammer.ts +199 -199
  19. package/src/programmers/MigrateApiNamespaceProgrammer.ts +431 -431
  20. package/src/programmers/MigrateApiProgrammer.ts +170 -170
  21. package/src/programmers/MigrateApiSimulatationProgrammer.ts +327 -327
  22. package/src/programmers/MigrateApiStartProgrammer.ts +194 -194
  23. package/src/programmers/MigrateDtoProgrammer.ts +78 -78
  24. package/src/programmers/MigrateE2eFileProgrammer.ts +117 -117
  25. package/src/programmers/MigrateE2eProgrammer.ts +36 -36
  26. package/src/programmers/MigrateImportProgrammer.ts +121 -121
  27. package/src/programmers/MigrateNestControllerProgrammer.ts +50 -50
  28. package/src/programmers/MigrateNestMethodProgrammer.ts +250 -250
  29. package/src/programmers/MigrateNestModuleProgrammer.ts +63 -63
  30. package/src/programmers/MigrateNestProgrammer.ts +74 -74
  31. package/src/programmers/MigrateSchemaProgrammer.ts +267 -267
  32. package/src/structures/IMigrateDto.ts +8 -8
  33. package/src/structures/IMigrateProgram.ts +27 -27
  34. package/src/structures/IMigrateRoute.ts +51 -51
  35. package/src/structures/ISwagger.ts +23 -23
  36. package/src/structures/ISwaggerComponents.ts +14 -14
  37. package/src/structures/ISwaggerRoute.ts +20 -20
  38. package/src/structures/ISwaggerRouteBodyContent.ts +15 -15
  39. package/src/structures/ISwaggerRouteParameter.ts +14 -14
  40. package/src/structures/ISwaggerRouteRequestBody.ts +12 -12
  41. package/src/structures/ISwaggerRouteResponse.ts +11 -11
  42. package/src/structures/ISwaggerSchema.ts +90 -90
  43. package/src/structures/ISwaggerSecurityScheme.ts +47 -47
  44. package/src/structures/ISwaggerV20.ts +10 -10
  45. package/src/structures/ISwaggerV31.ts +10 -10
  46. package/src/utils/FilePrinter.ts +36 -36
  47. package/src/utils/OpenApiConverter.ts +19 -19
  48. package/src/utils/StringUtil.ts +60 -60
  49. package/src/utils/SwaggerComponentsExplorer.ts +43 -43
  50. package/src/utils/SwaggerTypeChecker.ts +67 -67
  51. package/src/utils/openapi-down-convert/RefVisitor.ts +139 -139
  52. package/src/utils/openapi-down-convert/converter.ts +527 -527
@@ -1,431 +1,431 @@
1
- import ts from "typescript";
2
- import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
3
- import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
4
- import { LiteralFactory } from "typia/lib/factories/LiteralFactory";
5
- import { TypeFactory } from "typia/lib/factories/TypeFactory";
6
-
7
- import { IMigrateController } from "../structures/IMigrateController";
8
- import { IMigrateProgram } from "../structures/IMigrateProgram";
9
- import { IMigrateRoute } from "../structures/IMigrateRoute";
10
- import { ISwaggerComponents } from "../structures/ISwaggerComponents";
11
- import { FilePrinter } from "../utils/FilePrinter";
12
- import { MigrateApiSimulatationProgrammer } from "./MigrateApiSimulatationProgrammer";
13
- import { MigrateImportProgrammer } from "./MigrateImportProgrammer";
14
- import { MigrateSchemaProgrammer } from "./MigrateSchemaProgrammer";
15
-
16
- export namespace MigrateApiNamespaceProgrammer {
17
- export interface IProps {
18
- controller: IMigrateController;
19
- route: IMigrateRoute;
20
- alias: string;
21
- }
22
-
23
- export const write =
24
- (config: IMigrateProgram.IConfig) =>
25
- (components: ISwaggerComponents) =>
26
- (importer: MigrateImportProgrammer) =>
27
- (props: IProps): ts.ModuleDeclaration => {
28
- const types = writeTypes(components)(importer)(props.route);
29
- return ts.factory.createModuleDeclaration(
30
- [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
31
- ts.factory.createIdentifier(props.alias),
32
- ts.factory.createModuleBlock([
33
- ...types,
34
- ...(types.length ? [FilePrinter.newLine()] : []),
35
- writeMetadata(components)(importer)(props),
36
- FilePrinter.newLine(),
37
- writePath(components)(importer)(props),
38
- ...(config.simulate
39
- ? [
40
- MigrateApiSimulatationProgrammer.random(components)(importer)(
41
- props,
42
- ),
43
- MigrateApiSimulatationProgrammer.simulate(components)(importer)(
44
- props,
45
- ),
46
- ]
47
- : []),
48
- ]),
49
- ts.NodeFlags.Namespace,
50
- );
51
- };
52
-
53
- export const writePathCallExpression = (props: IProps) =>
54
- ts.factory.createCallExpression(
55
- ts.factory.createIdentifier(`${props.alias}.path`),
56
- undefined,
57
- [
58
- ...props.route.parameters.map((p) =>
59
- ts.factory.createIdentifier(p.key),
60
- ),
61
- ...(props.route.query
62
- ? [ts.factory.createIdentifier(props.route.query.key)]
63
- : []),
64
- ],
65
- );
66
-
67
- const writeTypes =
68
- (components: ISwaggerComponents) =>
69
- (importer: MigrateImportProgrammer) =>
70
- (route: IMigrateRoute): ts.TypeAliasDeclaration[] => {
71
- const array: ts.TypeAliasDeclaration[] = [];
72
- const declare = (name: string, type: ts.TypeNode) =>
73
- array.push(
74
- ts.factory.createTypeAliasDeclaration(
75
- [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
76
- name,
77
- undefined,
78
- type,
79
- ),
80
- );
81
- if (route.headers)
82
- declare(
83
- "Headers",
84
- MigrateSchemaProgrammer.write(components)(importer)(
85
- route.headers.schema,
86
- ),
87
- );
88
- if (route.query)
89
- declare(
90
- "Query",
91
- MigrateSchemaProgrammer.write(components)(importer)(
92
- route.query.schema,
93
- ),
94
- );
95
- if (route.body)
96
- declare(
97
- "Input",
98
- MigrateSchemaProgrammer.write(components)(importer)(
99
- route.body.schema,
100
- ),
101
- );
102
- if (route.success)
103
- declare(
104
- "Output",
105
- MigrateSchemaProgrammer.write(components)(importer)(
106
- route.success.schema,
107
- ),
108
- );
109
- return array;
110
- };
111
-
112
- const writeMetadata =
113
- (components: ISwaggerComponents) =>
114
- (importer: MigrateImportProgrammer) =>
115
- (props: IProps): ts.VariableStatement =>
116
- constant("METADATA")(
117
- ts.factory.createAsExpression(
118
- ts.factory.createObjectLiteralExpression(
119
- [
120
- ts.factory.createPropertyAssignment(
121
- "method",
122
- ts.factory.createStringLiteral(
123
- props.route.method.toUpperCase(),
124
- ),
125
- ),
126
- ts.factory.createPropertyAssignment(
127
- "path",
128
- ts.factory.createStringLiteral(getPath(props)),
129
- ),
130
- ts.factory.createPropertyAssignment(
131
- "request",
132
- props.route.body
133
- ? LiteralFactory.generate({
134
- type: props.route.body.type,
135
- encrypted: !!props.route.body["x-nestia-encrypted"],
136
- })
137
- : ts.factory.createNull(),
138
- ),
139
- ts.factory.createPropertyAssignment(
140
- "response",
141
- props.route.method.toUpperCase() !== "HEAD"
142
- ? LiteralFactory.generate({
143
- type: props.route.success?.type ?? "application/json",
144
- encrypted: !!props.route.success?.["x-nestia-encrypted"],
145
- })
146
- : ts.factory.createNull(),
147
- ),
148
- ...(props.route.success?.type ===
149
- "application/x-www-form-urlencoded"
150
- ? [
151
- ts.factory.createPropertyAssignment(
152
- "parseQuery",
153
- ts.factory.createCallExpression(
154
- ts.factory.createIdentifier(
155
- `${importer.external({
156
- type: "default",
157
- library: "typia",
158
- name: "typia",
159
- })}.http.createAssertQuery`,
160
- ),
161
- [
162
- MigrateSchemaProgrammer.write(components)(importer)(
163
- props.route.success.schema,
164
- ),
165
- ],
166
- undefined,
167
- ),
168
- ),
169
- ]
170
- : []),
171
- ],
172
- true,
173
- ),
174
- ts.factory.createTypeReferenceNode(
175
- ts.factory.createIdentifier("const"),
176
- ),
177
- ),
178
- );
179
-
180
- const writePath =
181
- (components: ISwaggerComponents) =>
182
- (importer: MigrateImportProgrammer) =>
183
- (props: IProps): ts.VariableStatement => {
184
- const out = (body: ts.ConciseBody) =>
185
- constant("path")(
186
- ts.factory.createArrowFunction(
187
- [],
188
- [],
189
- [
190
- ...props.route.parameters.map((p) =>
191
- IdentifierFactory.parameter(
192
- p.key,
193
- MigrateSchemaProgrammer.write(components)(importer)(p.schema),
194
- ),
195
- ),
196
- ...(props.route.query
197
- ? [
198
- IdentifierFactory.parameter(
199
- props.route.query.key,
200
- ts.factory.createTypeReferenceNode(
201
- `${props.alias}.Query`,
202
- ),
203
- ),
204
- ]
205
- : []),
206
- ],
207
- undefined,
208
- undefined,
209
- body,
210
- ),
211
- );
212
- const template = () => {
213
- const path: string = getPath(props);
214
- const splitted: string[] = path.split(":");
215
- if (splitted.length === 1) return ts.factory.createStringLiteral(path);
216
- return ts.factory.createTemplateExpression(
217
- ts.factory.createTemplateHead(splitted[0]),
218
- splitted.slice(1).map((s, i, arr) => {
219
- const name: string = s.split("/")[0];
220
- return ts.factory.createTemplateSpan(
221
- ts.factory.createCallExpression(
222
- ts.factory.createIdentifier("encodeURIComponent"),
223
- undefined,
224
- [
225
- ts.factory.createBinaryExpression(
226
- ts.factory.createIdentifier(
227
- props.route.parameters.find((p) => p.name === name)!.key,
228
- ),
229
- ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
230
- ts.factory.createStringLiteral("null"),
231
- ),
232
- ],
233
- ),
234
- (i !== arr.length - 1
235
- ? ts.factory.createTemplateMiddle
236
- : ts.factory.createTemplateTail)(s.substring(name.length)),
237
- );
238
- }),
239
- );
240
- };
241
- if (!props.route.query) return out(template());
242
-
243
- const computeName = (str: string): string =>
244
- props.route.parameters.find((p) => p.key === str) !== undefined
245
- ? computeName("_" + str)
246
- : str;
247
- const variables: string = computeName("variables");
248
- return out(
249
- ts.factory.createBlock(
250
- [
251
- local(variables)("URLSearchParams")(
252
- ts.factory.createNewExpression(
253
- ts.factory.createIdentifier("URLSearchParams"),
254
- [],
255
- [],
256
- ),
257
- ),
258
- ts.factory.createForOfStatement(
259
- undefined,
260
- ts.factory.createVariableDeclarationList(
261
- [
262
- ts.factory.createVariableDeclaration(
263
- ts.factory.createArrayBindingPattern([
264
- ts.factory.createBindingElement(
265
- undefined,
266
- undefined,
267
- ts.factory.createIdentifier("key"),
268
- undefined,
269
- ),
270
- ts.factory.createBindingElement(
271
- undefined,
272
- undefined,
273
- ts.factory.createIdentifier("value"),
274
- undefined,
275
- ),
276
- ]),
277
- undefined,
278
- undefined,
279
- undefined,
280
- ),
281
- ],
282
- ts.NodeFlags.Const,
283
- ),
284
- ts.factory.createCallExpression(
285
- ts.factory.createIdentifier("Object.entries"),
286
- undefined,
287
- [
288
- ts.factory.createAsExpression(
289
- ts.factory.createIdentifier(props.route.query.key),
290
- TypeFactory.keyword("any"),
291
- ),
292
- ],
293
- ),
294
- ts.factory.createIfStatement(
295
- ts.factory.createStrictEquality(
296
- ts.factory.createIdentifier("undefined"),
297
- ts.factory.createIdentifier("value"),
298
- ),
299
- ts.factory.createContinueStatement(),
300
- ts.factory.createIfStatement(
301
- ts.factory.createCallExpression(
302
- ts.factory.createIdentifier("Array.isArray"),
303
- undefined,
304
- [ts.factory.createIdentifier("value")],
305
- ),
306
- ts.factory.createExpressionStatement(
307
- ts.factory.createCallExpression(
308
- ts.factory.createPropertyAccessExpression(
309
- ts.factory.createIdentifier("value"),
310
- ts.factory.createIdentifier("forEach"),
311
- ),
312
- undefined,
313
- [
314
- ts.factory.createArrowFunction(
315
- undefined,
316
- undefined,
317
- [IdentifierFactory.parameter("elem")],
318
- undefined,
319
- undefined,
320
- ts.factory.createCallExpression(
321
- IdentifierFactory.access(
322
- ts.factory.createIdentifier(variables),
323
- )("append"),
324
- undefined,
325
- [
326
- ts.factory.createIdentifier("key"),
327
- ts.factory.createCallExpression(
328
- ts.factory.createIdentifier("String"),
329
- undefined,
330
- [ts.factory.createIdentifier("elem")],
331
- ),
332
- ],
333
- ),
334
- ),
335
- ],
336
- ),
337
- ),
338
- ts.factory.createExpressionStatement(
339
- ts.factory.createCallExpression(
340
- IdentifierFactory.access(
341
- ts.factory.createIdentifier(variables),
342
- )("set"),
343
- undefined,
344
- [
345
- ts.factory.createIdentifier("key"),
346
- ts.factory.createCallExpression(
347
- ts.factory.createIdentifier("String"),
348
- undefined,
349
- [ts.factory.createIdentifier("value")],
350
- ),
351
- ],
352
- ),
353
- ),
354
- ),
355
- ),
356
- ),
357
- local("location")("string")(template()),
358
- ts.factory.createReturnStatement(
359
- ts.factory.createConditionalExpression(
360
- ts.factory.createStrictEquality(
361
- ExpressionFactory.number(0),
362
- IdentifierFactory.access(
363
- ts.factory.createIdentifier(variables),
364
- )("size"),
365
- ),
366
- undefined,
367
- ts.factory.createIdentifier("location"),
368
- undefined,
369
- ts.factory.createTemplateExpression(
370
- ts.factory.createTemplateHead(""),
371
- [
372
- ts.factory.createTemplateSpan(
373
- ts.factory.createIdentifier("location"),
374
- ts.factory.createTemplateMiddle("?"),
375
- ),
376
- ts.factory.createTemplateSpan(
377
- ts.factory.createCallExpression(
378
- IdentifierFactory.access(
379
- ts.factory.createIdentifier(variables),
380
- )("toString"),
381
- undefined,
382
- undefined,
383
- ),
384
- ts.factory.createTemplateTail(""),
385
- ),
386
- ],
387
- ),
388
- ),
389
- ),
390
- ],
391
- true,
392
- ),
393
- );
394
- };
395
- }
396
-
397
- const constant = (name: string) => (expression: ts.Expression) =>
398
- ts.factory.createVariableStatement(
399
- [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
400
- ts.factory.createVariableDeclarationList(
401
- [
402
- ts.factory.createVariableDeclaration(
403
- name,
404
- undefined,
405
- undefined,
406
- expression,
407
- ),
408
- ],
409
- ts.NodeFlags.Const,
410
- ),
411
- );
412
- const getPath = (props: MigrateApiNamespaceProgrammer.IProps) =>
413
- "/" +
414
- [...props.controller.path.split("/"), ...props.route.path.split("/")]
415
- .filter((str) => !!str.length)
416
- .join("/");
417
- const local = (name: string) => (type: string) => (expression: ts.Expression) =>
418
- ts.factory.createVariableStatement(
419
- [],
420
- ts.factory.createVariableDeclarationList(
421
- [
422
- ts.factory.createVariableDeclaration(
423
- name,
424
- undefined,
425
- ts.factory.createTypeReferenceNode(type),
426
- expression,
427
- ),
428
- ],
429
- ts.NodeFlags.Const,
430
- ),
431
- );
1
+ import ts from "typescript";
2
+ import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
3
+ import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
4
+ import { LiteralFactory } from "typia/lib/factories/LiteralFactory";
5
+ import { TypeFactory } from "typia/lib/factories/TypeFactory";
6
+
7
+ import { IMigrateController } from "../structures/IMigrateController";
8
+ import { IMigrateProgram } from "../structures/IMigrateProgram";
9
+ import { IMigrateRoute } from "../structures/IMigrateRoute";
10
+ import { ISwaggerComponents } from "../structures/ISwaggerComponents";
11
+ import { FilePrinter } from "../utils/FilePrinter";
12
+ import { MigrateApiSimulatationProgrammer } from "./MigrateApiSimulatationProgrammer";
13
+ import { MigrateImportProgrammer } from "./MigrateImportProgrammer";
14
+ import { MigrateSchemaProgrammer } from "./MigrateSchemaProgrammer";
15
+
16
+ export namespace MigrateApiNamespaceProgrammer {
17
+ export interface IProps {
18
+ controller: IMigrateController;
19
+ route: IMigrateRoute;
20
+ alias: string;
21
+ }
22
+
23
+ export const write =
24
+ (config: IMigrateProgram.IConfig) =>
25
+ (components: ISwaggerComponents) =>
26
+ (importer: MigrateImportProgrammer) =>
27
+ (props: IProps): ts.ModuleDeclaration => {
28
+ const types = writeTypes(components)(importer)(props.route);
29
+ return ts.factory.createModuleDeclaration(
30
+ [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
31
+ ts.factory.createIdentifier(props.alias),
32
+ ts.factory.createModuleBlock([
33
+ ...types,
34
+ ...(types.length ? [FilePrinter.newLine()] : []),
35
+ writeMetadata(components)(importer)(props),
36
+ FilePrinter.newLine(),
37
+ writePath(components)(importer)(props),
38
+ ...(config.simulate
39
+ ? [
40
+ MigrateApiSimulatationProgrammer.random(components)(importer)(
41
+ props,
42
+ ),
43
+ MigrateApiSimulatationProgrammer.simulate(components)(importer)(
44
+ props,
45
+ ),
46
+ ]
47
+ : []),
48
+ ]),
49
+ ts.NodeFlags.Namespace,
50
+ );
51
+ };
52
+
53
+ export const writePathCallExpression = (props: IProps) =>
54
+ ts.factory.createCallExpression(
55
+ ts.factory.createIdentifier(`${props.alias}.path`),
56
+ undefined,
57
+ [
58
+ ...props.route.parameters.map((p) =>
59
+ ts.factory.createIdentifier(p.key),
60
+ ),
61
+ ...(props.route.query
62
+ ? [ts.factory.createIdentifier(props.route.query.key)]
63
+ : []),
64
+ ],
65
+ );
66
+
67
+ const writeTypes =
68
+ (components: ISwaggerComponents) =>
69
+ (importer: MigrateImportProgrammer) =>
70
+ (route: IMigrateRoute): ts.TypeAliasDeclaration[] => {
71
+ const array: ts.TypeAliasDeclaration[] = [];
72
+ const declare = (name: string, type: ts.TypeNode) =>
73
+ array.push(
74
+ ts.factory.createTypeAliasDeclaration(
75
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
76
+ name,
77
+ undefined,
78
+ type,
79
+ ),
80
+ );
81
+ if (route.headers)
82
+ declare(
83
+ "Headers",
84
+ MigrateSchemaProgrammer.write(components)(importer)(
85
+ route.headers.schema,
86
+ ),
87
+ );
88
+ if (route.query)
89
+ declare(
90
+ "Query",
91
+ MigrateSchemaProgrammer.write(components)(importer)(
92
+ route.query.schema,
93
+ ),
94
+ );
95
+ if (route.body)
96
+ declare(
97
+ "Input",
98
+ MigrateSchemaProgrammer.write(components)(importer)(
99
+ route.body.schema,
100
+ ),
101
+ );
102
+ if (route.success)
103
+ declare(
104
+ "Output",
105
+ MigrateSchemaProgrammer.write(components)(importer)(
106
+ route.success.schema,
107
+ ),
108
+ );
109
+ return array;
110
+ };
111
+
112
+ const writeMetadata =
113
+ (components: ISwaggerComponents) =>
114
+ (importer: MigrateImportProgrammer) =>
115
+ (props: IProps): ts.VariableStatement =>
116
+ constant("METADATA")(
117
+ ts.factory.createAsExpression(
118
+ ts.factory.createObjectLiteralExpression(
119
+ [
120
+ ts.factory.createPropertyAssignment(
121
+ "method",
122
+ ts.factory.createStringLiteral(
123
+ props.route.method.toUpperCase(),
124
+ ),
125
+ ),
126
+ ts.factory.createPropertyAssignment(
127
+ "path",
128
+ ts.factory.createStringLiteral(getPath(props)),
129
+ ),
130
+ ts.factory.createPropertyAssignment(
131
+ "request",
132
+ props.route.body
133
+ ? LiteralFactory.generate({
134
+ type: props.route.body.type,
135
+ encrypted: !!props.route.body["x-nestia-encrypted"],
136
+ })
137
+ : ts.factory.createNull(),
138
+ ),
139
+ ts.factory.createPropertyAssignment(
140
+ "response",
141
+ props.route.method.toUpperCase() !== "HEAD"
142
+ ? LiteralFactory.generate({
143
+ type: props.route.success?.type ?? "application/json",
144
+ encrypted: !!props.route.success?.["x-nestia-encrypted"],
145
+ })
146
+ : ts.factory.createNull(),
147
+ ),
148
+ ...(props.route.success?.type ===
149
+ "application/x-www-form-urlencoded"
150
+ ? [
151
+ ts.factory.createPropertyAssignment(
152
+ "parseQuery",
153
+ ts.factory.createCallExpression(
154
+ ts.factory.createIdentifier(
155
+ `${importer.external({
156
+ type: "default",
157
+ library: "typia",
158
+ name: "typia",
159
+ })}.http.createAssertQuery`,
160
+ ),
161
+ [
162
+ MigrateSchemaProgrammer.write(components)(importer)(
163
+ props.route.success.schema,
164
+ ),
165
+ ],
166
+ undefined,
167
+ ),
168
+ ),
169
+ ]
170
+ : []),
171
+ ],
172
+ true,
173
+ ),
174
+ ts.factory.createTypeReferenceNode(
175
+ ts.factory.createIdentifier("const"),
176
+ ),
177
+ ),
178
+ );
179
+
180
+ const writePath =
181
+ (components: ISwaggerComponents) =>
182
+ (importer: MigrateImportProgrammer) =>
183
+ (props: IProps): ts.VariableStatement => {
184
+ const out = (body: ts.ConciseBody) =>
185
+ constant("path")(
186
+ ts.factory.createArrowFunction(
187
+ [],
188
+ [],
189
+ [
190
+ ...props.route.parameters.map((p) =>
191
+ IdentifierFactory.parameter(
192
+ p.key,
193
+ MigrateSchemaProgrammer.write(components)(importer)(p.schema),
194
+ ),
195
+ ),
196
+ ...(props.route.query
197
+ ? [
198
+ IdentifierFactory.parameter(
199
+ props.route.query.key,
200
+ ts.factory.createTypeReferenceNode(
201
+ `${props.alias}.Query`,
202
+ ),
203
+ ),
204
+ ]
205
+ : []),
206
+ ],
207
+ undefined,
208
+ undefined,
209
+ body,
210
+ ),
211
+ );
212
+ const template = () => {
213
+ const path: string = getPath(props);
214
+ const splitted: string[] = path.split(":");
215
+ if (splitted.length === 1) return ts.factory.createStringLiteral(path);
216
+ return ts.factory.createTemplateExpression(
217
+ ts.factory.createTemplateHead(splitted[0]),
218
+ splitted.slice(1).map((s, i, arr) => {
219
+ const name: string = s.split("/")[0];
220
+ return ts.factory.createTemplateSpan(
221
+ ts.factory.createCallExpression(
222
+ ts.factory.createIdentifier("encodeURIComponent"),
223
+ undefined,
224
+ [
225
+ ts.factory.createBinaryExpression(
226
+ ts.factory.createIdentifier(
227
+ props.route.parameters.find((p) => p.name === name)!.key,
228
+ ),
229
+ ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
230
+ ts.factory.createStringLiteral("null"),
231
+ ),
232
+ ],
233
+ ),
234
+ (i !== arr.length - 1
235
+ ? ts.factory.createTemplateMiddle
236
+ : ts.factory.createTemplateTail)(s.substring(name.length)),
237
+ );
238
+ }),
239
+ );
240
+ };
241
+ if (!props.route.query) return out(template());
242
+
243
+ const computeName = (str: string): string =>
244
+ props.route.parameters.find((p) => p.key === str) !== undefined
245
+ ? computeName("_" + str)
246
+ : str;
247
+ const variables: string = computeName("variables");
248
+ return out(
249
+ ts.factory.createBlock(
250
+ [
251
+ local(variables)("URLSearchParams")(
252
+ ts.factory.createNewExpression(
253
+ ts.factory.createIdentifier("URLSearchParams"),
254
+ [],
255
+ [],
256
+ ),
257
+ ),
258
+ ts.factory.createForOfStatement(
259
+ undefined,
260
+ ts.factory.createVariableDeclarationList(
261
+ [
262
+ ts.factory.createVariableDeclaration(
263
+ ts.factory.createArrayBindingPattern([
264
+ ts.factory.createBindingElement(
265
+ undefined,
266
+ undefined,
267
+ ts.factory.createIdentifier("key"),
268
+ undefined,
269
+ ),
270
+ ts.factory.createBindingElement(
271
+ undefined,
272
+ undefined,
273
+ ts.factory.createIdentifier("value"),
274
+ undefined,
275
+ ),
276
+ ]),
277
+ undefined,
278
+ undefined,
279
+ undefined,
280
+ ),
281
+ ],
282
+ ts.NodeFlags.Const,
283
+ ),
284
+ ts.factory.createCallExpression(
285
+ ts.factory.createIdentifier("Object.entries"),
286
+ undefined,
287
+ [
288
+ ts.factory.createAsExpression(
289
+ ts.factory.createIdentifier(props.route.query.key),
290
+ TypeFactory.keyword("any"),
291
+ ),
292
+ ],
293
+ ),
294
+ ts.factory.createIfStatement(
295
+ ts.factory.createStrictEquality(
296
+ ts.factory.createIdentifier("undefined"),
297
+ ts.factory.createIdentifier("value"),
298
+ ),
299
+ ts.factory.createContinueStatement(),
300
+ ts.factory.createIfStatement(
301
+ ts.factory.createCallExpression(
302
+ ts.factory.createIdentifier("Array.isArray"),
303
+ undefined,
304
+ [ts.factory.createIdentifier("value")],
305
+ ),
306
+ ts.factory.createExpressionStatement(
307
+ ts.factory.createCallExpression(
308
+ ts.factory.createPropertyAccessExpression(
309
+ ts.factory.createIdentifier("value"),
310
+ ts.factory.createIdentifier("forEach"),
311
+ ),
312
+ undefined,
313
+ [
314
+ ts.factory.createArrowFunction(
315
+ undefined,
316
+ undefined,
317
+ [IdentifierFactory.parameter("elem")],
318
+ undefined,
319
+ undefined,
320
+ ts.factory.createCallExpression(
321
+ IdentifierFactory.access(
322
+ ts.factory.createIdentifier(variables),
323
+ )("append"),
324
+ undefined,
325
+ [
326
+ ts.factory.createIdentifier("key"),
327
+ ts.factory.createCallExpression(
328
+ ts.factory.createIdentifier("String"),
329
+ undefined,
330
+ [ts.factory.createIdentifier("elem")],
331
+ ),
332
+ ],
333
+ ),
334
+ ),
335
+ ],
336
+ ),
337
+ ),
338
+ ts.factory.createExpressionStatement(
339
+ ts.factory.createCallExpression(
340
+ IdentifierFactory.access(
341
+ ts.factory.createIdentifier(variables),
342
+ )("set"),
343
+ undefined,
344
+ [
345
+ ts.factory.createIdentifier("key"),
346
+ ts.factory.createCallExpression(
347
+ ts.factory.createIdentifier("String"),
348
+ undefined,
349
+ [ts.factory.createIdentifier("value")],
350
+ ),
351
+ ],
352
+ ),
353
+ ),
354
+ ),
355
+ ),
356
+ ),
357
+ local("location")("string")(template()),
358
+ ts.factory.createReturnStatement(
359
+ ts.factory.createConditionalExpression(
360
+ ts.factory.createStrictEquality(
361
+ ExpressionFactory.number(0),
362
+ IdentifierFactory.access(
363
+ ts.factory.createIdentifier(variables),
364
+ )("size"),
365
+ ),
366
+ undefined,
367
+ ts.factory.createIdentifier("location"),
368
+ undefined,
369
+ ts.factory.createTemplateExpression(
370
+ ts.factory.createTemplateHead(""),
371
+ [
372
+ ts.factory.createTemplateSpan(
373
+ ts.factory.createIdentifier("location"),
374
+ ts.factory.createTemplateMiddle("?"),
375
+ ),
376
+ ts.factory.createTemplateSpan(
377
+ ts.factory.createCallExpression(
378
+ IdentifierFactory.access(
379
+ ts.factory.createIdentifier(variables),
380
+ )("toString"),
381
+ undefined,
382
+ undefined,
383
+ ),
384
+ ts.factory.createTemplateTail(""),
385
+ ),
386
+ ],
387
+ ),
388
+ ),
389
+ ),
390
+ ],
391
+ true,
392
+ ),
393
+ );
394
+ };
395
+ }
396
+
397
+ const constant = (name: string) => (expression: ts.Expression) =>
398
+ ts.factory.createVariableStatement(
399
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
400
+ ts.factory.createVariableDeclarationList(
401
+ [
402
+ ts.factory.createVariableDeclaration(
403
+ name,
404
+ undefined,
405
+ undefined,
406
+ expression,
407
+ ),
408
+ ],
409
+ ts.NodeFlags.Const,
410
+ ),
411
+ );
412
+ const getPath = (props: MigrateApiNamespaceProgrammer.IProps) =>
413
+ "/" +
414
+ [...props.controller.path.split("/"), ...props.route.path.split("/")]
415
+ .filter((str) => !!str.length)
416
+ .join("/");
417
+ const local = (name: string) => (type: string) => (expression: ts.Expression) =>
418
+ ts.factory.createVariableStatement(
419
+ [],
420
+ ts.factory.createVariableDeclarationList(
421
+ [
422
+ ts.factory.createVariableDeclaration(
423
+ name,
424
+ undefined,
425
+ ts.factory.createTypeReferenceNode(type),
426
+ expression,
427
+ ),
428
+ ],
429
+ ts.NodeFlags.Const,
430
+ ),
431
+ );