@nestia/migrate 0.5.0 → 0.6.0
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 +15 -15
- package/lib/NestiaMigrateApplication.js.map +1 -1
- package/lib/archivers/FileArchiver.js.map +1 -1
- package/lib/bundles/TEMPLATE.js +11 -11
- package/lib/bundles/TEMPLATE.js.map +1 -1
- package/lib/executable/bundle.js.map +1 -1
- package/lib/executable/migrate.js +5 -5
- package/lib/executable/migrate.js.map +1 -1
- package/lib/programmers/ControllerProgrammer.d.ts +2 -1
- package/lib/programmers/ControllerProgrammer.js +21 -18
- package/lib/programmers/ControllerProgrammer.js.map +1 -1
- package/lib/programmers/DtoProgrammer.d.ts +8 -4
- package/lib/programmers/DtoProgrammer.js +36 -77
- package/lib/programmers/DtoProgrammer.js.map +1 -1
- package/lib/programmers/ImportProgrammer.d.ts +5 -5
- package/lib/programmers/ImportProgrammer.js +27 -19
- package/lib/programmers/ImportProgrammer.js.map +1 -1
- package/lib/programmers/MigrateProgrammer.d.ts +1 -2
- package/lib/programmers/MigrateProgrammer.js +52 -36
- package/lib/programmers/MigrateProgrammer.js.map +1 -1
- package/lib/programmers/ModuleProgrammer.d.ts +5 -0
- package/lib/programmers/ModuleProgrammer.js +29 -0
- package/lib/programmers/ModuleProgrammer.js.map +1 -0
- package/lib/programmers/RouteProgrammer.d.ts +2 -2
- package/lib/programmers/RouteProgrammer.js +108 -111
- package/lib/programmers/RouteProgrammer.js.map +1 -1
- package/lib/programmers/SchemaProgrammer.d.ts +2 -1
- package/lib/programmers/SchemaProgrammer.js +122 -189
- package/lib/programmers/SchemaProgrammer.js.map +1 -1
- package/lib/structures/IMigrateProgram.d.ts +2 -2
- package/lib/structures/ISwaggerInfo.d.ts +3 -3
- package/lib/utils/FilePrinter.d.ts +9 -0
- package/lib/utils/FilePrinter.js +25 -0
- package/lib/utils/FilePrinter.js.map +1 -0
- package/lib/utils/JsonTypeChecker.d.ts +3 -1
- package/lib/utils/JsonTypeChecker.js +31 -18
- package/lib/utils/JsonTypeChecker.js.map +1 -1
- package/lib/utils/MapUtil.js.map +1 -1
- package/lib/utils/SetupWizard.js.map +1 -1
- package/lib/utils/StringUtil.js.map +1 -1
- package/package.json +11 -9
- package/src/NestiaMigrateApplication.ts +68 -73
- package/src/archivers/FileArchiver.ts +35 -38
- package/src/bundles/TEMPLATE.ts +11 -11
- package/src/executable/bundle.ts +72 -78
- package/src/executable/migrate.ts +59 -60
- package/src/index.ts +4 -4
- package/src/module.ts +4 -4
- package/src/programmers/ControllerProgrammer.ts +155 -157
- package/src/programmers/DtoProgrammer.ts +74 -118
- package/src/programmers/ImportProgrammer.ts +98 -60
- package/src/programmers/MigrateProgrammer.ts +75 -62
- package/src/programmers/ModuleProgrammer.ts +62 -0
- package/src/programmers/RouteProgrammer.ts +486 -466
- package/src/programmers/SchemaProgrammer.ts +247 -339
- package/src/structures/IMigrateController.ts +8 -8
- package/src/structures/IMigrateDto.ts +8 -8
- package/src/structures/IMigrateFile.ts +5 -5
- package/src/structures/IMigrateProgram.ts +7 -7
- package/src/structures/IMigrateRoute.ts +36 -36
- package/src/structures/IMigrateSchema.ts +4 -4
- package/src/structures/ISwaggeSchema.ts +82 -82
- package/src/structures/ISwagger.ts +20 -20
- package/src/structures/ISwaggerComponents.ts +7 -7
- package/src/structures/ISwaggerInfo.ts +57 -57
- package/src/structures/ISwaggerRoute.ts +52 -52
- package/src/structures/ISwaggerSecurity.ts +47 -47
- package/src/utils/FilePrinter.ts +36 -0
- package/src/utils/JsonTypeChecker.ts +67 -52
- package/src/utils/MapUtil.ts +13 -13
- package/src/utils/SetupWizard.ts +15 -15
- package/src/utils/StringUtil.ts +51 -51
@@ -1,60 +1,59 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
import fs from "fs";
|
3
|
-
import path from "path";
|
4
|
-
|
5
|
-
import { NestiaMigrateApplication } from "../NestiaMigrateApplication";
|
6
|
-
import { ISwagger } from "../structures/ISwagger";
|
7
|
-
import { SetupWizard } from "../utils/SetupWizard";
|
8
|
-
|
9
|
-
const USAGE = `Wrong command has been detected. Use like below:
|
10
|
-
|
11
|
-
npx @nestia/migrate [input] [output]
|
12
|
-
|
13
|
-
ex) npx @nestia/migrate swagger.json my-new-project
|
14
|
-
`;
|
15
|
-
|
16
|
-
function halt(desc: string): never {
|
17
|
-
|
18
|
-
|
19
|
-
}
|
20
|
-
|
21
|
-
const main = (argv: string[]) => {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
main(process.argv.slice(2));
|
1
|
+
#!/usr/bin/env node
|
2
|
+
import fs from "fs";
|
3
|
+
import path from "path";
|
4
|
+
|
5
|
+
import { NestiaMigrateApplication } from "../NestiaMigrateApplication";
|
6
|
+
import { ISwagger } from "../structures/ISwagger";
|
7
|
+
import { SetupWizard } from "../utils/SetupWizard";
|
8
|
+
|
9
|
+
const USAGE = `Wrong command has been detected. Use like below:
|
10
|
+
|
11
|
+
npx @nestia/migrate [input] [output]
|
12
|
+
|
13
|
+
ex) npx @nestia/migrate swagger.json my-new-project
|
14
|
+
`;
|
15
|
+
|
16
|
+
function halt(desc: string): never {
|
17
|
+
console.error(desc);
|
18
|
+
process.exit(-1);
|
19
|
+
}
|
20
|
+
|
21
|
+
const main = (argv: string[]) => {
|
22
|
+
const resolve = (str: string | undefined) =>
|
23
|
+
str ? path.resolve(str).split("\\").join("/") : undefined;
|
24
|
+
const input: string | undefined = resolve(argv[0]);
|
25
|
+
const output: string | undefined = resolve(argv[1]);
|
26
|
+
|
27
|
+
// VALIDATE ARGUMENTS
|
28
|
+
if (input === undefined || output === undefined) halt(USAGE);
|
29
|
+
|
30
|
+
// VALIDATE OUTPUT DIRECTORY
|
31
|
+
const parent: string = resolve(output + "/..")!;
|
32
|
+
if (fs.existsSync(output)) halt("Output directory alreay exists.");
|
33
|
+
else if (fs.existsSync(parent) === false)
|
34
|
+
halt("Output directory's parent directory does not exist.");
|
35
|
+
else if (fs.statSync(parent).isDirectory() === false)
|
36
|
+
halt("Output directory's parent is not a directory.");
|
37
|
+
|
38
|
+
// READ SWAGGER
|
39
|
+
const swagger: ISwagger = (() => {
|
40
|
+
if (fs.existsSync(input) === false)
|
41
|
+
halt("Unable to find the input swagger.json file.");
|
42
|
+
const stats: fs.Stats = fs.statSync(input);
|
43
|
+
if (stats.isFile() === false) halt("The input swagger.json is not a file.");
|
44
|
+
const content: string = fs.readFileSync(input, "utf-8");
|
45
|
+
const swagger: ISwagger = JSON.parse(content);
|
46
|
+
return swagger;
|
47
|
+
})();
|
48
|
+
|
49
|
+
// DO GENERATE
|
50
|
+
const app = new NestiaMigrateApplication(swagger);
|
51
|
+
app.generate({
|
52
|
+
mkdir: fs.mkdirSync,
|
53
|
+
writeFile: (path, content) => fs.writeFileSync(path, content, "utf8"),
|
54
|
+
})(output);
|
55
|
+
|
56
|
+
// RUN SCRIPTS
|
57
|
+
SetupWizard.setup(output);
|
58
|
+
};
|
59
|
+
main(process.argv.slice(2));
|
package/src/index.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import * as migrate from "./module";
|
2
|
-
|
3
|
-
export default migrate;
|
4
|
-
export * from "./module";
|
1
|
+
import * as migrate from "./module";
|
2
|
+
|
3
|
+
export default migrate;
|
4
|
+
export * from "./module";
|
package/src/module.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
export * from "./NestiaMigrateApplication";
|
2
|
-
|
3
|
-
export * from "./structures/ISwagger";
|
4
|
-
export * from "./structures/IMigrateProgram";
|
1
|
+
export * from "./NestiaMigrateApplication";
|
2
|
+
|
3
|
+
export * from "./structures/ISwagger";
|
4
|
+
export * from "./structures/IMigrateProgram";
|
@@ -1,157 +1,155 @@
|
|
1
|
-
import
|
2
|
-
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import {
|
8
|
-
import {
|
9
|
-
import {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
};
|
157
|
-
}
|
1
|
+
import ts from "typescript";
|
2
|
+
|
3
|
+
import { IMigrateController } from "../structures/IMigrateController";
|
4
|
+
import { IMigrateRoute } from "../structures/IMigrateRoute";
|
5
|
+
import { ISwagger } from "../structures/ISwagger";
|
6
|
+
import { ISwaggerComponents } from "../structures/ISwaggerComponents";
|
7
|
+
import { FilePrinter } from "../utils/FilePrinter";
|
8
|
+
import { MapUtil } from "../utils/MapUtil";
|
9
|
+
import { StringUtil } from "../utils/StringUtil";
|
10
|
+
import { ImportProgrammer } from "./ImportProgrammer";
|
11
|
+
import { RouteProgrammer } from "./RouteProgrammer";
|
12
|
+
|
13
|
+
export namespace ControllerProgrammer {
|
14
|
+
/* -----------------------------------------------------------
|
15
|
+
ANALYZERS
|
16
|
+
----------------------------------------------------------- */
|
17
|
+
export const analyze = (swagger: ISwagger): IMigrateController[] => {
|
18
|
+
const dict: Map<string, IMigrateRoute[]> = new Map();
|
19
|
+
|
20
|
+
// GATHER ROUTES
|
21
|
+
for (const [path, collection] of Object.entries(swagger.paths)) {
|
22
|
+
// PREPARE DIRECTORIES
|
23
|
+
const location: string = StringUtil.splitWithNormalization(path)
|
24
|
+
.filter((str) => str[0] !== "{" && str[0] !== ":")
|
25
|
+
.join("/");
|
26
|
+
for (const s of sequence(location)) MapUtil.take(dict)(s)(() => []);
|
27
|
+
|
28
|
+
// INSERT ROUTES TO THE LAST DIRECTORY
|
29
|
+
const routes: IMigrateRoute[] = MapUtil.take(dict)(location)(() => []);
|
30
|
+
for (const [method, value] of Object.entries(collection)) {
|
31
|
+
const r: IMigrateRoute | null = RouteProgrammer.analyze(swagger)({
|
32
|
+
path,
|
33
|
+
method,
|
34
|
+
})(value);
|
35
|
+
if (r !== null) routes.push(r);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
// ABSORB STANDALONE ROUTES
|
40
|
+
const emended: Map<string, IMigrateRoute[]> = new Map(
|
41
|
+
[...dict.entries()].sort((a, b) => a[0].localeCompare(b[0])),
|
42
|
+
);
|
43
|
+
for (const [location, routes] of emended) {
|
44
|
+
if (routes.length !== 1) continue;
|
45
|
+
for (const s of sequence(location).slice(0, 1)) {
|
46
|
+
const parent = emended.get(s);
|
47
|
+
if (parent) {
|
48
|
+
parent.push(...routes);
|
49
|
+
emended.delete(location);
|
50
|
+
break;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
// GENERATE CONTROLLERS
|
56
|
+
return [...emended.entries()]
|
57
|
+
.filter(([_l, routes]) => !!routes.length)
|
58
|
+
.map(([location, routes]) => {
|
59
|
+
const prefix: string = StringUtil.commonPrefix(
|
60
|
+
routes.map((r) => r.path),
|
61
|
+
);
|
62
|
+
for (const r of routes)
|
63
|
+
r.path = StringUtil.reJoinWithDecimalParameters(
|
64
|
+
r.path.replace(prefix, ""),
|
65
|
+
);
|
66
|
+
const controller: IMigrateController = {
|
67
|
+
name: StringUtil.pascal(location) + "Controller",
|
68
|
+
path: StringUtil.reJoinWithDecimalParameters(prefix),
|
69
|
+
location: "src/controllers/" + location,
|
70
|
+
routes,
|
71
|
+
};
|
72
|
+
if (controller.name === "Controller") controller.name = "__Controller";
|
73
|
+
naming(controller);
|
74
|
+
return controller;
|
75
|
+
});
|
76
|
+
};
|
77
|
+
|
78
|
+
const sequence = (location: string): string[] =>
|
79
|
+
StringUtil.splitWithNormalization(location)
|
80
|
+
.map((_str, i, entire) => entire.slice(0, i + 1).join("/"))
|
81
|
+
.slice(0, -1)
|
82
|
+
.reverse();
|
83
|
+
|
84
|
+
const naming = (controller: IMigrateController): void => {
|
85
|
+
interface IRouteCapsule {
|
86
|
+
variables: string[];
|
87
|
+
route: IMigrateRoute;
|
88
|
+
}
|
89
|
+
const dict: Map<string, IRouteCapsule[]> = new Map();
|
90
|
+
for (const route of controller.routes) {
|
91
|
+
const additional: string[] = StringUtil.splitWithNormalization(
|
92
|
+
route.path,
|
93
|
+
);
|
94
|
+
const statics: string[] = additional.filter((str) => str[0] !== ":");
|
95
|
+
if (statics.length) route.name = StringUtil.camel(statics.join("/"));
|
96
|
+
else
|
97
|
+
MapUtil.take(dict)(route.method)(() => []).push({
|
98
|
+
variables: additional
|
99
|
+
.filter((str) => str[0] === ":")
|
100
|
+
.map((str) => str.substring(1)),
|
101
|
+
route,
|
102
|
+
});
|
103
|
+
}
|
104
|
+
|
105
|
+
for (const [method, capsules] of dict) {
|
106
|
+
const emended: string = method === "delete" ? "erase" : method;
|
107
|
+
for (const c of capsules) {
|
108
|
+
const empty: boolean = c.variables.length === 0;
|
109
|
+
c.route.name = empty
|
110
|
+
? emended
|
111
|
+
: StringUtil.camel(`${emended}By/${c.variables.join("/and/")}`);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
};
|
115
|
+
|
116
|
+
/* -----------------------------------------------------------
|
117
|
+
WRITERS
|
118
|
+
----------------------------------------------------------- */
|
119
|
+
export const write =
|
120
|
+
(components: ISwaggerComponents) =>
|
121
|
+
(controller: IMigrateController): ts.Statement[] => {
|
122
|
+
const importer: ImportProgrammer = new ImportProgrammer();
|
123
|
+
const $class = ts.factory.createClassDeclaration(
|
124
|
+
[
|
125
|
+
ts.factory.createDecorator(
|
126
|
+
ts.factory.createCallExpression(
|
127
|
+
ts.factory.createIdentifier(
|
128
|
+
importer.external({
|
129
|
+
library: "@nestjs/common",
|
130
|
+
instance: "Controller",
|
131
|
+
}),
|
132
|
+
),
|
133
|
+
[],
|
134
|
+
[ts.factory.createStringLiteral(controller.path)],
|
135
|
+
),
|
136
|
+
),
|
137
|
+
ts.factory.createToken(ts.SyntaxKind.ExportKeyword),
|
138
|
+
],
|
139
|
+
controller.name,
|
140
|
+
[],
|
141
|
+
[],
|
142
|
+
controller.routes.map(RouteProgrammer.write(components)(importer)),
|
143
|
+
);
|
144
|
+
return [
|
145
|
+
...importer.toStatements(
|
146
|
+
(ref) =>
|
147
|
+
`${"../".repeat(
|
148
|
+
StringUtil.splitWithNormalization(controller.location).length - 1,
|
149
|
+
)}api/structures/${ref}`,
|
150
|
+
),
|
151
|
+
...(importer.empty() ? [] : [FilePrinter.enter()]),
|
152
|
+
$class,
|
153
|
+
];
|
154
|
+
};
|
155
|
+
}
|