@nestia/migrate 0.21.4-dev.20241208-4 → 0.21.4

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 (50) hide show
  1. package/README.md +87 -87
  2. package/lib/bundles/NEST_TEMPLATE.js +66 -66
  3. package/lib/bundles/NEST_TEMPLATE.js.map +1 -1
  4. package/lib/bundles/SDK_TEMPLATE.js +30 -30
  5. package/lib/bundles/SDK_TEMPLATE.js.map +1 -1
  6. package/lib/executable/migrate.js +0 -0
  7. package/lib/index.mjs +92 -92
  8. package/lib/utils/openapi-down-convert/converter.js +2 -2
  9. package/package.json +2 -2
  10. package/src/MigrateApplication.ts +107 -107
  11. package/src/analyzers/MigrateAnalyzer.ts +18 -18
  12. package/src/analyzers/MigrateControllerAnalyzer.ts +40 -40
  13. package/src/archivers/MigrateFileArchiver.ts +38 -38
  14. package/src/bundles/NEST_TEMPLATE.ts +66 -66
  15. package/src/bundles/SDK_TEMPLATE.ts +30 -30
  16. package/src/executable/bundle.js +125 -125
  17. package/src/executable/migrate.ts +7 -7
  18. package/src/factories/TypeLiteralFactory.ts +57 -57
  19. package/src/index.ts +4 -4
  20. package/src/internal/MigrateCommander.ts +86 -86
  21. package/src/internal/MigrateInquirer.ts +89 -89
  22. package/src/module.ts +8 -8
  23. package/src/programmers/MigrateApiFileProgrammer.ts +49 -49
  24. package/src/programmers/MigrateApiFunctionProgrammer.ts +210 -210
  25. package/src/programmers/MigrateApiNamespaceProgrammer.ts +417 -417
  26. package/src/programmers/MigrateApiProgrammer.ts +103 -103
  27. package/src/programmers/MigrateApiSimulatationProgrammer.ts +324 -324
  28. package/src/programmers/MigrateApiStartProgrammer.ts +194 -194
  29. package/src/programmers/MigrateDtoProgrammer.ts +87 -87
  30. package/src/programmers/MigrateE2eFileProgrammer.ts +117 -117
  31. package/src/programmers/MigrateE2eProgrammer.ts +34 -34
  32. package/src/programmers/MigrateImportProgrammer.ts +118 -118
  33. package/src/programmers/MigrateNestControllerProgrammer.ts +50 -50
  34. package/src/programmers/MigrateNestMethodProgrammer.ts +371 -371
  35. package/src/programmers/MigrateNestModuleProgrammer.ts +65 -65
  36. package/src/programmers/MigrateNestProgrammer.ts +79 -79
  37. package/src/programmers/MigrateSchemaProgrammer.ts +373 -373
  38. package/src/structures/IHttpMigrateController.ts +8 -8
  39. package/src/structures/IHttpMigrateDto.ts +8 -8
  40. package/src/structures/IHttpMigrateFile.ts +5 -5
  41. package/src/structures/IHttpMigrateProgram.ts +27 -27
  42. package/src/structures/IHttpMigrateRoute.ts +1 -1
  43. package/src/structures/IHttpMigrateSchema.ts +4 -4
  44. package/src/utils/FilePrinter.ts +36 -36
  45. package/src/utils/MapUtil.ts +13 -13
  46. package/src/utils/OpenApiTypeChecker.ts +73 -73
  47. package/src/utils/SetupWizard.ts +12 -12
  48. package/src/utils/StringUtil.ts +113 -113
  49. package/src/utils/openapi-down-convert/RefVisitor.ts +139 -139
  50. package/src/utils/openapi-down-convert/converter.ts +527 -527
@@ -1,371 +1,371 @@
1
- import { 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 { IHttpMigrateRoute } from "../structures/IHttpMigrateRoute";
9
- import { FilePrinter } from "../utils/FilePrinter";
10
- import { StringUtil } from "../utils/StringUtil";
11
- import { MigrateImportProgrammer } from "./MigrateImportProgrammer";
12
- import { MigrateSchemaProgrammer } from "./MigrateSchemaProgrammer";
13
-
14
- export namespace MigrateNestMethodProgrammer {
15
- export const write =
16
- (components: OpenApi.IComponents) =>
17
- (importer: MigrateImportProgrammer) =>
18
- (route: IHttpMigrateRoute): ts.MethodDeclaration => {
19
- const output: ts.TypeNode = route.success
20
- ? MigrateSchemaProgrammer.write(components)(importer)(
21
- route.success.schema,
22
- )
23
- : TypeFactory.keyword("void");
24
-
25
- const method: ts.MethodDeclaration = ts.factory.createMethodDeclaration(
26
- [
27
- ...writeMethodDecorators(components)(importer)(route),
28
- ts.factory.createToken(ts.SyntaxKind.PublicKeyword),
29
- ts.factory.createToken(ts.SyntaxKind.AsyncKeyword),
30
- ],
31
- undefined,
32
- route.accessor.at(-1)!,
33
- undefined,
34
- undefined,
35
- writeParameters(components)(importer)(route),
36
- ts.factory.createTypeReferenceNode("Promise", [output]),
37
- ts.factory.createBlock(
38
- [
39
- ...[
40
- ...route.parameters.map((p) => p.key),
41
- ...(route.headers ? ["headers"] : []),
42
- ...(route.query ? ["query"] : []),
43
- ...(route.body ? ["body"] : []),
44
- ].map((str) =>
45
- ts.factory.createExpressionStatement(
46
- ts.factory.createIdentifier(str),
47
- ),
48
- ),
49
- ts.factory.createReturnStatement(
50
- ts.factory.createCallExpression(
51
- IdentifierFactory.access(
52
- ts.factory.createIdentifier(
53
- importer.external({
54
- type: "default",
55
- library: "typia",
56
- name: "typia",
57
- }),
58
- ),
59
- "random",
60
- ),
61
- [output],
62
- undefined,
63
- ),
64
- ),
65
- ],
66
- true,
67
- ),
68
- );
69
- return FilePrinter.description(method, writeDescription(route));
70
- };
71
-
72
- const writeDescription = (method: IHttpMigrateRoute): string =>
73
- [
74
- method.comment(),
75
- "@nestia Generated by Nestia - https://github.com/samchon/nestia",
76
- ].join("\n");
77
-
78
- const writeMethodDecorators =
79
- (components: OpenApi.IComponents) =>
80
- (importer: MigrateImportProgrammer) =>
81
- (route: IHttpMigrateRoute): ts.Decorator[] => {
82
- const external =
83
- (lib: string) =>
84
- (instance: string): ts.Identifier =>
85
- ts.factory.createIdentifier(
86
- importer.external({
87
- type: "instance",
88
- library: lib,
89
- name: instance,
90
- }),
91
- );
92
-
93
- // EXAMPLES
94
- const decorators: ts.Decorator[] = [];
95
- if (route.success)
96
- decorators.push(
97
- ...writeExampleDecorators("Response")(importer)(
98
- route.success.media(),
99
- ),
100
- );
101
-
102
- // ROUTER
103
- const router = (instance: string) =>
104
- ts.factory.createDecorator(
105
- ts.factory.createCallExpression(
106
- IdentifierFactory.access(
107
- external("@nestia/core")(instance),
108
- StringUtil.capitalize(route.method),
109
- ),
110
- [],
111
- [ts.factory.createStringLiteral(route.path)],
112
- ),
113
- );
114
- if (route.success?.["x-nestia-encrypted"])
115
- decorators.push(router("EncryptedRoute"));
116
- else if (route.success?.type === "text/plain")
117
- decorators.push(
118
- ts.factory.createDecorator(
119
- ts.factory.createCallExpression(
120
- external("@nestjs/common")(StringUtil.capitalize(route.method)),
121
- [],
122
- [ts.factory.createStringLiteral(route.path)],
123
- ),
124
- ),
125
- );
126
- else if (route.success?.type === "application/x-www-form-urlencoded")
127
- decorators.push(router("TypedQuery"));
128
- else if (route.method === "head")
129
- decorators.push(
130
- ts.factory.createDecorator(
131
- ts.factory.createCallExpression(
132
- external("@nestjs/common")("Head"),
133
- [],
134
- [ts.factory.createStringLiteral(route.path)],
135
- ),
136
- ),
137
- );
138
- else if (
139
- route.success === null ||
140
- route.success?.type === "application/json"
141
- )
142
- decorators.push(router("TypedRoute"));
143
- for (const [key, value] of Object.entries(route.exceptions ?? {}))
144
- decorators.push(
145
- ts.factory.createDecorator(
146
- ts.factory.createCallExpression(
147
- external("@nestia/core")("TypedException"),
148
- [
149
- MigrateSchemaProgrammer.write(components)(importer)(
150
- value.schema,
151
- ),
152
- ],
153
- [
154
- isNaN(Number(key))
155
- ? ts.factory.createStringLiteral(key)
156
- : ExpressionFactory.number(Number(key)),
157
- ...(value.response().description?.length
158
- ? [
159
- ts.factory.createStringLiteral(
160
- value.response().description!,
161
- ),
162
- ]
163
- : []),
164
- ],
165
- ),
166
- ),
167
- );
168
- return decorators;
169
- };
170
-
171
- const writeParameters =
172
- (components: OpenApi.IComponents) =>
173
- (importer: MigrateImportProgrammer) =>
174
- (route: IHttpMigrateRoute): ts.ParameterDeclaration[] => [
175
- ...route.parameters.map((p) =>
176
- ts.factory.createParameterDeclaration(
177
- [
178
- ...writeExampleDecorators("Parameter")(importer)(p.parameter()),
179
- ts.factory.createDecorator(
180
- ts.factory.createCallExpression(
181
- ts.factory.createIdentifier(
182
- importer.external({
183
- type: "instance",
184
- library: "@nestia/core",
185
- name: "TypedParam",
186
- }),
187
- ),
188
- undefined,
189
- [ts.factory.createStringLiteral(p.key)],
190
- ),
191
- ),
192
- ],
193
- undefined,
194
- p.key,
195
- undefined,
196
- MigrateSchemaProgrammer.write(components)(importer)(p.schema),
197
- ),
198
- ),
199
- ...(route.headers
200
- ? [
201
- writeDtoParameter({
202
- method: "TypedHeaders",
203
- variable: "headers",
204
- arguments: [],
205
- })(components)(importer)({
206
- required: true,
207
- schema: route.headers.schema,
208
- example: route.headers.example(),
209
- examples: route.headers.examples(),
210
- }),
211
- ]
212
- : []),
213
- ...(route.query
214
- ? [
215
- writeDtoParameter({
216
- method: "TypedQuery",
217
- variable: "query",
218
- arguments: [],
219
- })(components)(importer)({
220
- required: true,
221
- schema: route.query.schema,
222
- example: route.query.example(),
223
- examples: route.query.examples(),
224
- }),
225
- ]
226
- : []),
227
- ...(route.body
228
- ? [
229
- writeDtoParameter({
230
- method: route.body["x-nestia-encrypted"]
231
- ? "EncryptedBody"
232
- : route.body.type === "application/json"
233
- ? "TypedBody"
234
- : route.body.type === "application/x-www-form-urlencoded"
235
- ? ["TypedQuery", "Body"]
236
- : route.body.type === "text/plain"
237
- ? "PlainBody"
238
- : route.body.type === "multipart/form-data"
239
- ? ["TypedFormData", "Body"]
240
- : "TypedBody",
241
- variable: "body",
242
- arguments:
243
- route.body.type === "multipart/form-data"
244
- ? [
245
- ts.factory.createArrowFunction(
246
- undefined,
247
- undefined,
248
- [],
249
- undefined,
250
- undefined,
251
- ts.factory.createCallExpression(
252
- ts.factory.createIdentifier(
253
- importer.external({
254
- type: "default",
255
- library: "multer",
256
- name: "Multer",
257
- }),
258
- ),
259
- undefined,
260
- undefined,
261
- ),
262
- ),
263
- ]
264
- : [],
265
- })(components)(importer)({
266
- schema: route.body.schema,
267
- required: !(
268
- (route.body.type === "application/json" ||
269
- route.body.type === "text/plain") &&
270
- route.operation().requestBody?.required === false
271
- ),
272
- example: route.body.media().example,
273
- examples: route.body.media().examples,
274
- }),
275
- ]
276
- : []),
277
- ];
278
-
279
- const writeDtoParameter =
280
- (accessor: {
281
- method: string | [string, string];
282
- variable: string;
283
- arguments: ts.Expression[];
284
- }) =>
285
- (components: OpenApi.IComponents) =>
286
- (importer: MigrateImportProgrammer) =>
287
- (props: {
288
- schema: OpenApi.IJsonSchema;
289
- required: boolean;
290
- example?: any;
291
- examples?: Record<string, any>;
292
- }): ts.ParameterDeclaration => {
293
- const instance = ts.factory.createIdentifier(
294
- importer.external({
295
- type: "instance",
296
- library: "@nestia/core",
297
- name:
298
- typeof accessor.method === "string"
299
- ? accessor.method
300
- : accessor.method[0],
301
- }),
302
- );
303
- return ts.factory.createParameterDeclaration(
304
- [
305
- ...writeExampleDecorators("Parameter")(importer)(props),
306
- ts.factory.createDecorator(
307
- ts.factory.createCallExpression(
308
- typeof accessor.method === "string"
309
- ? instance
310
- : IdentifierFactory.access(instance, accessor.method[1]),
311
- undefined,
312
- accessor.arguments,
313
- ),
314
- ),
315
- ],
316
- undefined,
317
- accessor.variable,
318
- props.required === false
319
- ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
320
- : undefined,
321
- MigrateSchemaProgrammer.write(components)(importer)(props.schema),
322
- );
323
- };
324
-
325
- const writeExampleDecorators =
326
- (kind: "Response" | "Parameter") =>
327
- (importer: MigrateImportProgrammer) =>
328
- (media: {
329
- example?: any;
330
- examples?: Record<string, any>;
331
- }): ts.Decorator[] => [
332
- ...(media.example !== undefined
333
- ? [
334
- ts.factory.createDecorator(
335
- ts.factory.createCallExpression(
336
- IdentifierFactory.access(
337
- ts.factory.createIdentifier(
338
- importer.external({
339
- type: "instance",
340
- library: "@nestia/core",
341
- name: "SwaggerExample",
342
- }),
343
- ),
344
- kind,
345
- ),
346
- [],
347
- [LiteralFactory.write(media.example)],
348
- ),
349
- ),
350
- ]
351
- : []),
352
- ...Object.entries(media.examples ?? {}).map(([key, value]) =>
353
- ts.factory.createDecorator(
354
- ts.factory.createCallExpression(
355
- IdentifierFactory.access(
356
- ts.factory.createIdentifier(
357
- importer.external({
358
- type: "instance",
359
- library: "@nestia/core",
360
- name: "SwaggerExample",
361
- }),
362
- ),
363
- kind,
364
- ),
365
- [],
366
- [ts.factory.createStringLiteral(key), LiteralFactory.write(value)],
367
- ),
368
- ),
369
- ),
370
- ];
371
- }
1
+ import { 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 { IHttpMigrateRoute } from "../structures/IHttpMigrateRoute";
9
+ import { FilePrinter } from "../utils/FilePrinter";
10
+ import { StringUtil } from "../utils/StringUtil";
11
+ import { MigrateImportProgrammer } from "./MigrateImportProgrammer";
12
+ import { MigrateSchemaProgrammer } from "./MigrateSchemaProgrammer";
13
+
14
+ export namespace MigrateNestMethodProgrammer {
15
+ export const write =
16
+ (components: OpenApi.IComponents) =>
17
+ (importer: MigrateImportProgrammer) =>
18
+ (route: IHttpMigrateRoute): ts.MethodDeclaration => {
19
+ const output: ts.TypeNode = route.success
20
+ ? MigrateSchemaProgrammer.write(components)(importer)(
21
+ route.success.schema,
22
+ )
23
+ : TypeFactory.keyword("void");
24
+
25
+ const method: ts.MethodDeclaration = ts.factory.createMethodDeclaration(
26
+ [
27
+ ...writeMethodDecorators(components)(importer)(route),
28
+ ts.factory.createToken(ts.SyntaxKind.PublicKeyword),
29
+ ts.factory.createToken(ts.SyntaxKind.AsyncKeyword),
30
+ ],
31
+ undefined,
32
+ route.accessor.at(-1)!,
33
+ undefined,
34
+ undefined,
35
+ writeParameters(components)(importer)(route),
36
+ ts.factory.createTypeReferenceNode("Promise", [output]),
37
+ ts.factory.createBlock(
38
+ [
39
+ ...[
40
+ ...route.parameters.map((p) => p.key),
41
+ ...(route.headers ? ["headers"] : []),
42
+ ...(route.query ? ["query"] : []),
43
+ ...(route.body ? ["body"] : []),
44
+ ].map((str) =>
45
+ ts.factory.createExpressionStatement(
46
+ ts.factory.createIdentifier(str),
47
+ ),
48
+ ),
49
+ ts.factory.createReturnStatement(
50
+ ts.factory.createCallExpression(
51
+ IdentifierFactory.access(
52
+ ts.factory.createIdentifier(
53
+ importer.external({
54
+ type: "default",
55
+ library: "typia",
56
+ name: "typia",
57
+ }),
58
+ ),
59
+ "random",
60
+ ),
61
+ [output],
62
+ undefined,
63
+ ),
64
+ ),
65
+ ],
66
+ true,
67
+ ),
68
+ );
69
+ return FilePrinter.description(method, writeDescription(route));
70
+ };
71
+
72
+ const writeDescription = (method: IHttpMigrateRoute): string =>
73
+ [
74
+ method.comment(),
75
+ "@nestia Generated by Nestia - https://github.com/samchon/nestia",
76
+ ].join("\n");
77
+
78
+ const writeMethodDecorators =
79
+ (components: OpenApi.IComponents) =>
80
+ (importer: MigrateImportProgrammer) =>
81
+ (route: IHttpMigrateRoute): ts.Decorator[] => {
82
+ const external =
83
+ (lib: string) =>
84
+ (instance: string): ts.Identifier =>
85
+ ts.factory.createIdentifier(
86
+ importer.external({
87
+ type: "instance",
88
+ library: lib,
89
+ name: instance,
90
+ }),
91
+ );
92
+
93
+ // EXAMPLES
94
+ const decorators: ts.Decorator[] = [];
95
+ if (route.success)
96
+ decorators.push(
97
+ ...writeExampleDecorators("Response")(importer)(
98
+ route.success.media(),
99
+ ),
100
+ );
101
+
102
+ // ROUTER
103
+ const router = (instance: string) =>
104
+ ts.factory.createDecorator(
105
+ ts.factory.createCallExpression(
106
+ IdentifierFactory.access(
107
+ external("@nestia/core")(instance),
108
+ StringUtil.capitalize(route.method),
109
+ ),
110
+ [],
111
+ [ts.factory.createStringLiteral(route.path)],
112
+ ),
113
+ );
114
+ if (route.success?.["x-nestia-encrypted"])
115
+ decorators.push(router("EncryptedRoute"));
116
+ else if (route.success?.type === "text/plain")
117
+ decorators.push(
118
+ ts.factory.createDecorator(
119
+ ts.factory.createCallExpression(
120
+ external("@nestjs/common")(StringUtil.capitalize(route.method)),
121
+ [],
122
+ [ts.factory.createStringLiteral(route.path)],
123
+ ),
124
+ ),
125
+ );
126
+ else if (route.success?.type === "application/x-www-form-urlencoded")
127
+ decorators.push(router("TypedQuery"));
128
+ else if (route.method === "head")
129
+ decorators.push(
130
+ ts.factory.createDecorator(
131
+ ts.factory.createCallExpression(
132
+ external("@nestjs/common")("Head"),
133
+ [],
134
+ [ts.factory.createStringLiteral(route.path)],
135
+ ),
136
+ ),
137
+ );
138
+ else if (
139
+ route.success === null ||
140
+ route.success?.type === "application/json"
141
+ )
142
+ decorators.push(router("TypedRoute"));
143
+ for (const [key, value] of Object.entries(route.exceptions ?? {}))
144
+ decorators.push(
145
+ ts.factory.createDecorator(
146
+ ts.factory.createCallExpression(
147
+ external("@nestia/core")("TypedException"),
148
+ [
149
+ MigrateSchemaProgrammer.write(components)(importer)(
150
+ value.schema,
151
+ ),
152
+ ],
153
+ [
154
+ isNaN(Number(key))
155
+ ? ts.factory.createStringLiteral(key)
156
+ : ExpressionFactory.number(Number(key)),
157
+ ...(value.response().description?.length
158
+ ? [
159
+ ts.factory.createStringLiteral(
160
+ value.response().description!,
161
+ ),
162
+ ]
163
+ : []),
164
+ ],
165
+ ),
166
+ ),
167
+ );
168
+ return decorators;
169
+ };
170
+
171
+ const writeParameters =
172
+ (components: OpenApi.IComponents) =>
173
+ (importer: MigrateImportProgrammer) =>
174
+ (route: IHttpMigrateRoute): ts.ParameterDeclaration[] => [
175
+ ...route.parameters.map((p) =>
176
+ ts.factory.createParameterDeclaration(
177
+ [
178
+ ...writeExampleDecorators("Parameter")(importer)(p.parameter()),
179
+ ts.factory.createDecorator(
180
+ ts.factory.createCallExpression(
181
+ ts.factory.createIdentifier(
182
+ importer.external({
183
+ type: "instance",
184
+ library: "@nestia/core",
185
+ name: "TypedParam",
186
+ }),
187
+ ),
188
+ undefined,
189
+ [ts.factory.createStringLiteral(p.key)],
190
+ ),
191
+ ),
192
+ ],
193
+ undefined,
194
+ p.key,
195
+ undefined,
196
+ MigrateSchemaProgrammer.write(components)(importer)(p.schema),
197
+ ),
198
+ ),
199
+ ...(route.headers
200
+ ? [
201
+ writeDtoParameter({
202
+ method: "TypedHeaders",
203
+ variable: "headers",
204
+ arguments: [],
205
+ })(components)(importer)({
206
+ required: true,
207
+ schema: route.headers.schema,
208
+ example: route.headers.example(),
209
+ examples: route.headers.examples(),
210
+ }),
211
+ ]
212
+ : []),
213
+ ...(route.query
214
+ ? [
215
+ writeDtoParameter({
216
+ method: "TypedQuery",
217
+ variable: "query",
218
+ arguments: [],
219
+ })(components)(importer)({
220
+ required: true,
221
+ schema: route.query.schema,
222
+ example: route.query.example(),
223
+ examples: route.query.examples(),
224
+ }),
225
+ ]
226
+ : []),
227
+ ...(route.body
228
+ ? [
229
+ writeDtoParameter({
230
+ method: route.body["x-nestia-encrypted"]
231
+ ? "EncryptedBody"
232
+ : route.body.type === "application/json"
233
+ ? "TypedBody"
234
+ : route.body.type === "application/x-www-form-urlencoded"
235
+ ? ["TypedQuery", "Body"]
236
+ : route.body.type === "text/plain"
237
+ ? "PlainBody"
238
+ : route.body.type === "multipart/form-data"
239
+ ? ["TypedFormData", "Body"]
240
+ : "TypedBody",
241
+ variable: "body",
242
+ arguments:
243
+ route.body.type === "multipart/form-data"
244
+ ? [
245
+ ts.factory.createArrowFunction(
246
+ undefined,
247
+ undefined,
248
+ [],
249
+ undefined,
250
+ undefined,
251
+ ts.factory.createCallExpression(
252
+ ts.factory.createIdentifier(
253
+ importer.external({
254
+ type: "default",
255
+ library: "multer",
256
+ name: "Multer",
257
+ }),
258
+ ),
259
+ undefined,
260
+ undefined,
261
+ ),
262
+ ),
263
+ ]
264
+ : [],
265
+ })(components)(importer)({
266
+ schema: route.body.schema,
267
+ required: !(
268
+ (route.body.type === "application/json" ||
269
+ route.body.type === "text/plain") &&
270
+ route.operation().requestBody?.required === false
271
+ ),
272
+ example: route.body.media().example,
273
+ examples: route.body.media().examples,
274
+ }),
275
+ ]
276
+ : []),
277
+ ];
278
+
279
+ const writeDtoParameter =
280
+ (accessor: {
281
+ method: string | [string, string];
282
+ variable: string;
283
+ arguments: ts.Expression[];
284
+ }) =>
285
+ (components: OpenApi.IComponents) =>
286
+ (importer: MigrateImportProgrammer) =>
287
+ (props: {
288
+ schema: OpenApi.IJsonSchema;
289
+ required: boolean;
290
+ example?: any;
291
+ examples?: Record<string, any>;
292
+ }): ts.ParameterDeclaration => {
293
+ const instance = ts.factory.createIdentifier(
294
+ importer.external({
295
+ type: "instance",
296
+ library: "@nestia/core",
297
+ name:
298
+ typeof accessor.method === "string"
299
+ ? accessor.method
300
+ : accessor.method[0],
301
+ }),
302
+ );
303
+ return ts.factory.createParameterDeclaration(
304
+ [
305
+ ...writeExampleDecorators("Parameter")(importer)(props),
306
+ ts.factory.createDecorator(
307
+ ts.factory.createCallExpression(
308
+ typeof accessor.method === "string"
309
+ ? instance
310
+ : IdentifierFactory.access(instance, accessor.method[1]),
311
+ undefined,
312
+ accessor.arguments,
313
+ ),
314
+ ),
315
+ ],
316
+ undefined,
317
+ accessor.variable,
318
+ props.required === false
319
+ ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
320
+ : undefined,
321
+ MigrateSchemaProgrammer.write(components)(importer)(props.schema),
322
+ );
323
+ };
324
+
325
+ const writeExampleDecorators =
326
+ (kind: "Response" | "Parameter") =>
327
+ (importer: MigrateImportProgrammer) =>
328
+ (media: {
329
+ example?: any;
330
+ examples?: Record<string, any>;
331
+ }): ts.Decorator[] => [
332
+ ...(media.example !== undefined
333
+ ? [
334
+ ts.factory.createDecorator(
335
+ ts.factory.createCallExpression(
336
+ IdentifierFactory.access(
337
+ ts.factory.createIdentifier(
338
+ importer.external({
339
+ type: "instance",
340
+ library: "@nestia/core",
341
+ name: "SwaggerExample",
342
+ }),
343
+ ),
344
+ kind,
345
+ ),
346
+ [],
347
+ [LiteralFactory.write(media.example)],
348
+ ),
349
+ ),
350
+ ]
351
+ : []),
352
+ ...Object.entries(media.examples ?? {}).map(([key, value]) =>
353
+ ts.factory.createDecorator(
354
+ ts.factory.createCallExpression(
355
+ IdentifierFactory.access(
356
+ ts.factory.createIdentifier(
357
+ importer.external({
358
+ type: "instance",
359
+ library: "@nestia/core",
360
+ name: "SwaggerExample",
361
+ }),
362
+ ),
363
+ kind,
364
+ ),
365
+ [],
366
+ [ts.factory.createStringLiteral(key), LiteralFactory.write(value)],
367
+ ),
368
+ ),
369
+ ),
370
+ ];
371
+ }