@nestia/migrate 0.2.0 → 0.2.1-dev.20230802
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.
- package/lib/NestiaMigrateApplication.js +2 -2
- package/lib/NestiaMigrateApplication.js.map +1 -1
- package/lib/bundles/TEMPLATE.js +2 -2
- package/lib/programmers/ControllerProgrammer.d.ts +2 -1
- package/lib/programmers/ControllerProgrammer.js +12 -17
- package/lib/programmers/ControllerProgrammer.js.map +1 -1
- package/lib/programmers/DtoProgrammer.d.ts +2 -1
- package/lib/programmers/DtoProgrammer.js +5 -5
- package/lib/programmers/DtoProgrammer.js.map +1 -1
- package/lib/programmers/ImportProgrammer.d.ts +11 -0
- package/lib/programmers/ImportProgrammer.js +20 -0
- package/lib/programmers/ImportProgrammer.js.map +1 -0
- package/lib/programmers/MigrateProgrammer.d.ts +2 -1
- package/lib/programmers/MigrateProgrammer.js +3 -3
- package/lib/programmers/MigrateProgrammer.js.map +1 -1
- package/lib/programmers/RouteProgrammer.d.ts +2 -1
- package/lib/programmers/RouteProgrammer.js +45 -17
- package/lib/programmers/RouteProgrammer.js.map +1 -1
- package/lib/programmers/SchemaProgrammer.d.ts +2 -1
- package/lib/programmers/SchemaProgrammer.js +64 -42
- package/lib/programmers/SchemaProgrammer.js.map +1 -1
- package/package.json +4 -4
- package/src/NestiaMigrateApplication.ts +6 -2
- package/src/bundles/TEMPLATE.ts +2 -2
- package/src/programmers/ControllerProgrammer.ts +50 -54
- package/src/programmers/DtoProgrammer.ts +29 -25
- package/src/programmers/ImportProgrammer.ts +29 -0
- package/src/programmers/MigrateProgrammer.ts +17 -14
- package/src/programmers/RouteProgrammer.ts +99 -31
- package/src/programmers/SchemaProgrammer.ts +82 -40
@@ -3,6 +3,7 @@ import { Escaper } from "typia/lib/utils/Escaper";
|
|
3
3
|
import { IMigrateRoute } from "../structures/IMigrateRoute";
|
4
4
|
import { ISwaggerSchema } from "../structures/ISwaggeSchema";
|
5
5
|
import { ISwagger } from "../structures/ISwagger";
|
6
|
+
import { ISwaggerComponents } from "../structures/ISwaggerComponents";
|
6
7
|
import { ISwaggerRoute } from "../structures/ISwaggerRoute";
|
7
8
|
import { JsonTypeChecker } from "../utils/JsonTypeChecker";
|
8
9
|
import { StringUtil } from "../utils/StringUtil";
|
@@ -26,6 +27,15 @@ export namespace RouteProgrammer {
|
|
26
27
|
}: @nestia/migrate supports only application/json or text/plain format yet.`,
|
27
28
|
);
|
28
29
|
return null;
|
30
|
+
} else if (
|
31
|
+
SUPPORTED_METHODS.has(props.method.toUpperCase()) === false
|
32
|
+
) {
|
33
|
+
console.log(
|
34
|
+
`Failed to migrate ${props.method.toUpperCase()} ${
|
35
|
+
props.path
|
36
|
+
}: @nestia/migrate does not support ${props.method.toUpperCase()} method.`,
|
37
|
+
);
|
38
|
+
return null;
|
29
39
|
}
|
30
40
|
|
31
41
|
const [headers, query] = ["header", "query"].map((type) => {
|
@@ -292,17 +302,47 @@ export namespace RouteProgrammer {
|
|
292
302
|
};
|
293
303
|
|
294
304
|
export const write =
|
305
|
+
(importer: (module: string) => (instance: string) => string) =>
|
306
|
+
(components: ISwaggerComponents) =>
|
295
307
|
(references: ISwaggerSchema.IReference[]) =>
|
296
308
|
(route: IMigrateRoute): string => {
|
297
309
|
const output: string = route.response
|
298
|
-
? SchemaProgrammer.write(references)(
|
310
|
+
? SchemaProgrammer.write(components)(references)(
|
311
|
+
route.response.schema,
|
312
|
+
)
|
299
313
|
: "void";
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
314
|
+
|
315
|
+
const methoder = (composer: (name: string) => string) =>
|
316
|
+
`${composer(
|
317
|
+
StringUtil.capitalize(route.method),
|
318
|
+
)}(${JSON.stringify(route.path)})`;
|
319
|
+
const decorator: string[] =
|
320
|
+
route.response?.["x-nestia-encrypted"] === true
|
321
|
+
? [
|
322
|
+
`@${importer("@nestia/core")(
|
323
|
+
"EncryptedRoute",
|
324
|
+
)}.${methoder((str) => str)}`,
|
325
|
+
]
|
326
|
+
: route.response?.type === "text/plain"
|
327
|
+
? [
|
328
|
+
`@${importer("@nestjs/common")(
|
329
|
+
"Header",
|
330
|
+
)}("Content-Type", "text/plain")`,
|
331
|
+
`@${methoder((str) =>
|
332
|
+
importer("@nestjs/common")(str),
|
333
|
+
)}`,
|
334
|
+
]
|
335
|
+
: route.method === "head"
|
336
|
+
? [
|
337
|
+
`@${importer("@nestjs/common")("Head")}${methoder(
|
338
|
+
() => "",
|
339
|
+
)}`,
|
340
|
+
]
|
341
|
+
: [
|
342
|
+
`@${importer("@nestia/core")(
|
343
|
+
"TypedRoute",
|
344
|
+
)}.${methoder((str) => str)}`,
|
345
|
+
];
|
306
346
|
const content: string[] = [
|
307
347
|
...(route.description
|
308
348
|
? [
|
@@ -313,21 +353,26 @@ export namespace RouteProgrammer {
|
|
313
353
|
" */",
|
314
354
|
]
|
315
355
|
: []),
|
316
|
-
|
317
|
-
route.path.length ? `(${JSON.stringify(route.path)})` : "()"
|
318
|
-
}`,
|
356
|
+
...decorator,
|
319
357
|
`public async ${route.name}(`,
|
320
|
-
...route.parameters.map(
|
358
|
+
...route.parameters.map(
|
359
|
+
(param) =>
|
360
|
+
` ${writeParameter(components)(importer)(param)},`,
|
361
|
+
),
|
321
362
|
...(route.headers
|
322
363
|
? [
|
323
|
-
` @core
|
364
|
+
` @${importer("@nestia/core")(
|
365
|
+
"TypedHeaders",
|
366
|
+
)}() headers: ${SchemaProgrammer.write(components)(
|
324
367
|
references,
|
325
368
|
)(route.headers)},`,
|
326
369
|
]
|
327
370
|
: []),
|
328
371
|
...(route.query
|
329
372
|
? [
|
330
|
-
` @core
|
373
|
+
` @${importer("@nestia/core")(
|
374
|
+
"TypedQuery",
|
375
|
+
)}() query: ${SchemaProgrammer.write(components)(
|
331
376
|
references,
|
332
377
|
)(route.query)},`,
|
333
378
|
]
|
@@ -335,17 +380,25 @@ export namespace RouteProgrammer {
|
|
335
380
|
...(route.body
|
336
381
|
? route.body["x-nestia-encrypted"] === true
|
337
382
|
? [
|
338
|
-
` @core
|
383
|
+
` @${importer("@nestia/core")(
|
384
|
+
"EncryptedBody",
|
385
|
+
)}() body: ${SchemaProgrammer.write(components)(
|
339
386
|
references,
|
340
387
|
)(route.body.schema)},`,
|
341
388
|
]
|
342
389
|
: route.body.type === "application/json"
|
343
390
|
? [
|
344
|
-
` @core
|
391
|
+
` @${importer("@nestia/core")(
|
392
|
+
"TypedBody",
|
393
|
+
)}() body: ${SchemaProgrammer.write(components)(
|
345
394
|
references,
|
346
395
|
)(route.body.schema)},`,
|
347
396
|
]
|
348
|
-
: [
|
397
|
+
: [
|
398
|
+
` @${importer("@nestia/core")(
|
399
|
+
"PlainBody",
|
400
|
+
)}() body: string,`,
|
401
|
+
]
|
349
402
|
: []),
|
350
403
|
`): Promise<${output}> {`,
|
351
404
|
...route.parameters.map(
|
@@ -355,25 +408,40 @@ export namespace RouteProgrammer {
|
|
355
408
|
...(route.query ? [" query;"] : []),
|
356
409
|
...(route.body ? [" body;"] : []),
|
357
410
|
...(output !== "void"
|
358
|
-
? [
|
411
|
+
? [
|
412
|
+
` return ${importer("typia")(
|
413
|
+
"random",
|
414
|
+
)}<${output}>();`,
|
415
|
+
]
|
359
416
|
: []),
|
360
417
|
`}`,
|
361
418
|
];
|
362
419
|
return content.join("\n");
|
363
420
|
};
|
364
421
|
|
365
|
-
const writeParameter =
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
422
|
+
const writeParameter =
|
423
|
+
(components: ISwaggerComponents) =>
|
424
|
+
(importer: (library: string) => (instance: string) => string) =>
|
425
|
+
({ key, schema }: IMigrateRoute.IParameter): string => {
|
426
|
+
const variable = StringUtil.normalize(key);
|
427
|
+
const format =
|
428
|
+
JsonTypeChecker.isString(schema) &&
|
429
|
+
(schema.format === "uuid" || schema.format === "date")
|
430
|
+
? schema.format
|
431
|
+
: null;
|
432
|
+
return `@${importer("@nestia/core")("TypedParam")}(${JSON.stringify(
|
433
|
+
key,
|
434
|
+
)}${
|
435
|
+
format ? `, ${JSON.stringify(format)}` : ""
|
436
|
+
}) ${variable}: ${SchemaProgrammer.write(components)([])(schema)}`;
|
437
|
+
};
|
379
438
|
}
|
439
|
+
|
440
|
+
const SUPPORTED_METHODS: Set<string> = new Set([
|
441
|
+
"GET",
|
442
|
+
"POST",
|
443
|
+
"PUT",
|
444
|
+
"PATCH",
|
445
|
+
"DELETE",
|
446
|
+
"HEAD",
|
447
|
+
]);
|
@@ -1,49 +1,81 @@
|
|
1
1
|
import { Escaper } from "typia/lib/utils/Escaper";
|
2
2
|
|
3
3
|
import { ISwaggerSchema } from "../structures/ISwaggeSchema";
|
4
|
+
import { ISwaggerComponents } from "../structures/ISwaggerComponents";
|
4
5
|
import { JsonTypeChecker } from "../utils/JsonTypeChecker";
|
5
6
|
|
6
7
|
export namespace SchemaProgrammer {
|
7
8
|
export const write =
|
9
|
+
(components: ISwaggerComponents) =>
|
8
10
|
(references: ISwaggerSchema.IReference[]) =>
|
9
11
|
(schema: ISwaggerSchema): string =>
|
10
|
-
writeSchema(references)(() => () => {})(schema);
|
12
|
+
writeSchema(components)(references)(() => () => {})(true)(schema);
|
11
13
|
|
12
14
|
type Tagger = (tag: string) => (value?: string) => void;
|
13
15
|
const writeSchema =
|
16
|
+
(components: ISwaggerComponents) =>
|
14
17
|
(references: ISwaggerSchema.IReference[]) =>
|
15
18
|
(tagger: Tagger) =>
|
19
|
+
(final: boolean) =>
|
16
20
|
(schema: ISwaggerSchema): string => {
|
17
21
|
// SPECIAL TYPES
|
18
22
|
if (JsonTypeChecker.isUnknown(schema)) return "any";
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
|
24
|
+
const type: string = (() => {
|
25
|
+
if (JsonTypeChecker.isAnyOf(schema))
|
26
|
+
return (
|
27
|
+
"(" +
|
28
|
+
schema.anyOf
|
29
|
+
.map(
|
30
|
+
writeSchema(components)(references)(tagger)(
|
31
|
+
false,
|
32
|
+
),
|
33
|
+
)
|
34
|
+
.join(" | ") +
|
35
|
+
")"
|
36
|
+
);
|
37
|
+
else if (JsonTypeChecker.isOneOf(schema))
|
38
|
+
return schema.oneOf
|
39
|
+
.map(writeSchema(components)(references)(tagger)(false))
|
40
|
+
.join(" | ");
|
41
|
+
// ATOMIC TYPES
|
42
|
+
else if (JsonTypeChecker.isBoolean(schema))
|
43
|
+
return writeBoolean(tagger)(schema);
|
44
|
+
else if (JsonTypeChecker.isInteger(schema))
|
45
|
+
return writeInteger(tagger)(schema);
|
46
|
+
else if (JsonTypeChecker.isNumber(schema))
|
47
|
+
return writeNumber(tagger)(schema);
|
48
|
+
else if (JsonTypeChecker.isString(schema))
|
49
|
+
return writeString(tagger)(schema);
|
50
|
+
// INSTANCE TYPES
|
51
|
+
else if (JsonTypeChecker.isArray(schema))
|
52
|
+
return writeArray(components)(references)(tagger)(schema);
|
53
|
+
else if (JsonTypeChecker.isObject(schema))
|
54
|
+
return writeObject(components)(references)(schema);
|
55
|
+
else if (JsonTypeChecker.isReference(schema)) {
|
56
|
+
references.push(schema);
|
57
|
+
return schema.$ref.replace(`#/components/schemas/`, ``);
|
58
|
+
} else return "any";
|
59
|
+
})();
|
60
|
+
if (type === "any" || final === false) return type;
|
61
|
+
return isNullable(components)(schema) ? `${type} | null` : type;
|
62
|
+
};
|
63
|
+
|
64
|
+
const isNullable =
|
65
|
+
(components: ISwaggerComponents) =>
|
66
|
+
(schema: ISwaggerSchema): boolean => {
|
67
|
+
if (JsonTypeChecker.isAnyOf(schema))
|
68
|
+
return schema.anyOf.some(isNullable(components));
|
23
69
|
else if (JsonTypeChecker.isOneOf(schema))
|
24
|
-
return schema.oneOf
|
25
|
-
.map(writeSchema(references)(tagger))
|
26
|
-
.join(" | ");
|
27
|
-
// ATOMIC TYPES
|
28
|
-
else if (JsonTypeChecker.isBoolean(schema))
|
29
|
-
return writeBoolean(tagger)(schema);
|
30
|
-
else if (JsonTypeChecker.isInteger(schema))
|
31
|
-
return writeInteger(tagger)(schema);
|
32
|
-
else if (JsonTypeChecker.isNumber(schema))
|
33
|
-
return writeNumber(tagger)(schema);
|
34
|
-
else if (JsonTypeChecker.isString(schema))
|
35
|
-
return writeString(tagger)(schema);
|
36
|
-
// INSTANCE TYPES
|
37
|
-
else if (JsonTypeChecker.isArray(schema))
|
38
|
-
return writeArray(references)(tagger)(schema);
|
39
|
-
else if (JsonTypeChecker.isObject(schema))
|
40
|
-
return writeObject(references)(schema);
|
70
|
+
return schema.oneOf.some(isNullable(components));
|
41
71
|
else if (JsonTypeChecker.isReference(schema)) {
|
42
|
-
|
43
|
-
|
72
|
+
const $id = schema.$ref.replace("#/components/schemas/", "");
|
73
|
+
const target = (components.schemas ?? {})[$id];
|
74
|
+
return target === undefined
|
75
|
+
? false
|
76
|
+
: isNullable(components)(target);
|
44
77
|
}
|
45
|
-
|
46
|
-
return "any";
|
78
|
+
return (schema as ISwaggerSchema.IString).nullable === true;
|
47
79
|
};
|
48
80
|
|
49
81
|
const writeBoolean =
|
@@ -94,20 +126,24 @@ export namespace SchemaProgrammer {
|
|
94
126
|
};
|
95
127
|
|
96
128
|
const writeArray =
|
129
|
+
(components: ISwaggerComponents) =>
|
97
130
|
(references: ISwaggerSchema.IReference[]) =>
|
98
131
|
(tagger: Tagger) =>
|
99
132
|
(schema: ISwaggerSchema.IArray): string =>
|
100
133
|
schema["x-typia-tuple"]
|
101
134
|
? `[${schema["x-typia-tuple"].items
|
102
|
-
.map(writeTupleElement(references))
|
135
|
+
.map(writeTupleElement(components)(references))
|
103
136
|
.join(", ")}]`
|
104
|
-
: `Array<${writeSchema(references)(tagger)(
|
137
|
+
: `Array<${writeSchema(components)(references)(tagger)(true)(
|
138
|
+
schema.items,
|
139
|
+
)}>`;
|
105
140
|
const writeTupleElement =
|
141
|
+
(components: ISwaggerComponents) =>
|
106
142
|
(references: ISwaggerSchema.IReference[]) =>
|
107
143
|
(schema: ISwaggerSchema): string => {
|
108
|
-
const name: string = writeSchema(
|
109
|
-
|
110
|
-
);
|
144
|
+
const name: string = writeSchema(components)(references)(
|
145
|
+
() => () => {},
|
146
|
+
)(true)(schema);
|
111
147
|
return schema["x-typia-optional"]
|
112
148
|
? `${name}?`
|
113
149
|
: schema["x-typia-rest"]
|
@@ -116,29 +152,31 @@ export namespace SchemaProgrammer {
|
|
116
152
|
};
|
117
153
|
|
118
154
|
const writeObject =
|
155
|
+
(components: ISwaggerComponents) =>
|
119
156
|
(references: ISwaggerSchema.IReference[]) =>
|
120
157
|
(schema: ISwaggerSchema.IObject): string => {
|
121
158
|
const entries = Object.entries(schema.properties ?? {});
|
122
159
|
return typeof schema.additionalProperties === "object"
|
123
160
|
? entries.length
|
124
|
-
? `${writeStaticObject(references)(
|
161
|
+
? `${writeStaticObject(components)(references)(
|
125
162
|
schema,
|
126
|
-
)} & ${writeDynamicObject(references)(
|
163
|
+
)} & ${writeDynamicObject(components)(references)(
|
127
164
|
schema.additionalProperties,
|
128
165
|
)}`
|
129
|
-
: writeDynamicObject(references)(
|
166
|
+
: writeDynamicObject(components)(references)(
|
130
167
|
schema.additionalProperties,
|
131
168
|
)
|
132
|
-
: writeStaticObject(references)(schema);
|
169
|
+
: writeStaticObject(components)(references)(schema);
|
133
170
|
};
|
134
171
|
const writeStaticObject =
|
172
|
+
(components: ISwaggerComponents) =>
|
135
173
|
(references: ISwaggerSchema.IReference[]) =>
|
136
174
|
(schema: ISwaggerSchema.IObject): string =>
|
137
175
|
[
|
138
176
|
"{",
|
139
177
|
...Object.entries(schema.properties ?? {})
|
140
178
|
.map(([key, value]) =>
|
141
|
-
writeProperty(references)(key)(
|
179
|
+
writeProperty(components)(references)(key)(
|
142
180
|
(schema.required ?? []).some((r) => r === key),
|
143
181
|
)(value),
|
144
182
|
)
|
@@ -146,20 +184,23 @@ export namespace SchemaProgrammer {
|
|
146
184
|
"}",
|
147
185
|
].join("\n");
|
148
186
|
const writeDynamicObject =
|
187
|
+
(components: ISwaggerComponents) =>
|
149
188
|
(references: ISwaggerSchema.IReference[]) =>
|
150
189
|
(additional: ISwaggerSchema): string => {
|
151
190
|
return [
|
152
191
|
"{",
|
153
192
|
tab(4)(
|
154
|
-
writeProperty(
|
155
|
-
|
156
|
-
|
193
|
+
writeProperty(components)(references)(
|
194
|
+
"[key: string]",
|
195
|
+
true,
|
196
|
+
)(true)(additional),
|
157
197
|
),
|
158
198
|
"}",
|
159
199
|
].join("\n");
|
160
200
|
};
|
161
201
|
|
162
202
|
const writeProperty =
|
203
|
+
(components: ISwaggerComponents) =>
|
163
204
|
(references: ISwaggerSchema.IReference[]) =>
|
164
205
|
(key: string, ensureVariable: boolean = false) =>
|
165
206
|
(required: boolean) =>
|
@@ -184,7 +225,8 @@ export namespace SchemaProgrammer {
|
|
184
225
|
if (schema.title) tagger("@title")(schema.title);
|
185
226
|
|
186
227
|
// GET TYPE WITH SPECIAL TAGS
|
187
|
-
const type: string =
|
228
|
+
const type: string =
|
229
|
+
writeSchema(components)(references)(tagger)(true)(schema);
|
188
230
|
|
189
231
|
// ENDS WITH DEPRECATED TAG
|
190
232
|
if (schema.deprecated) tagger("@deprecated")();
|