@nestia/migrate 10.0.2 → 11.0.0-dev.20260305

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