@nestia/migrate 0.1.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/.prettierignore +3 -0
- package/.vscode/settings.json +10 -0
- package/lib/NestiaMigrateApplication.d.ts +18 -0
- package/lib/NestiaMigrateApplication.js +1330 -0
- package/lib/NestiaMigrateApplication.js.map +1 -0
- package/lib/archivers/FileArchiver.d.ts +8 -0
- package/lib/archivers/FileArchiver.js +35 -0
- package/lib/archivers/FileArchiver.js.map +1 -0
- package/lib/bundles/TEMPLATE.d.ts +5 -0
- package/lib/bundles/TEMPLATE.js +261 -0
- package/lib/bundles/TEMPLATE.js.map +1 -0
- package/lib/executable/bundle.d.ts +1 -0
- package/lib/executable/bundle.js +75 -0
- package/lib/executable/bundle.js.map +1 -0
- package/lib/executable/migrate.d.ts +2 -0
- package/lib/executable/migrate.js +65 -0
- package/lib/executable/migrate.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +32 -0
- package/lib/index.js.map +1 -0
- package/lib/module.d.ts +3 -0
- package/lib/module.js +20 -0
- package/lib/module.js.map +1 -0
- package/lib/programmers/ControllerProgrammer.d.ts +6 -0
- package/lib/programmers/ControllerProgrammer.js +119 -0
- package/lib/programmers/ControllerProgrammer.js.map +1 -0
- package/lib/programmers/DtoProgrammer.d.ts +6 -0
- package/lib/programmers/DtoProgrammer.js +95 -0
- package/lib/programmers/DtoProgrammer.js.map +1 -0
- package/lib/programmers/MigrateProgrammer.d.ts +7 -0
- package/lib/programmers/MigrateProgrammer.js +31 -0
- package/lib/programmers/MigrateProgrammer.js.map +1 -0
- package/lib/programmers/RouteProgrammer.d.ts +11 -0
- package/lib/programmers/RouteProgrammer.js +199 -0
- package/lib/programmers/RouteProgrammer.js.map +1 -0
- package/lib/programmers/SchemaProgrammer.d.ts +4 -0
- package/lib/programmers/SchemaProgrammer.js +163 -0
- package/lib/programmers/SchemaProgrammer.js.map +1 -0
- package/lib/structures/IMigrateController.d.ts +7 -0
- package/lib/structures/IMigrateController.js +3 -0
- package/lib/structures/IMigrateController.js.map +1 -0
- package/lib/structures/IMigrateDto.d.ts +7 -0
- package/lib/structures/IMigrateDto.js +3 -0
- package/lib/structures/IMigrateDto.js.map +1 -0
- package/lib/structures/IMigrateFile.d.ts +5 -0
- package/lib/structures/IMigrateFile.js +3 -0
- package/lib/structures/IMigrateFile.js.map +1 -0
- package/lib/structures/IMigrateProgram.d.ts +6 -0
- package/lib/structures/IMigrateProgram.js +3 -0
- package/lib/structures/IMigrateProgram.js.map +1 -0
- package/lib/structures/IMigrateRoute.d.ts +19 -0
- package/lib/structures/IMigrateRoute.js +3 -0
- package/lib/structures/IMigrateRoute.js.map +1 -0
- package/lib/structures/IMigrateSchema.d.ts +4 -0
- package/lib/structures/IMigrateSchema.js +3 -0
- package/lib/structures/IMigrateSchema.js.map +1 -0
- package/lib/structures/ISwaggeSchema.d.ts +72 -0
- package/lib/structures/ISwaggeSchema.js +3 -0
- package/lib/structures/ISwaggeSchema.js.map +1 -0
- package/lib/structures/ISwagger.d.ts +22 -0
- package/lib/structures/ISwagger.js +3 -0
- package/lib/structures/ISwagger.js.map +1 -0
- package/lib/structures/ISwaggerComponents.d.ts +6 -0
- package/lib/structures/ISwaggerComponents.js +3 -0
- package/lib/structures/ISwaggerComponents.js.map +1 -0
- package/lib/structures/ISwaggerRoute.d.ts +38 -0
- package/lib/structures/ISwaggerRoute.js +3 -0
- package/lib/structures/ISwaggerRoute.js.map +1 -0
- package/lib/structures/ISwaggerSecurity.d.ts +40 -0
- package/lib/structures/ISwaggerSecurity.js +3 -0
- package/lib/structures/ISwaggerSecurity.js.map +1 -0
- package/lib/test/index.d.ts +1 -0
- package/lib/test/index.js +45 -0
- package/lib/test/index.js.map +1 -0
- package/lib/utils/JsonTypeChecker.d.ts +13 -0
- package/lib/utils/JsonTypeChecker.js +20 -0
- package/lib/utils/JsonTypeChecker.js.map +1 -0
- package/lib/utils/MapUtil.d.ts +3 -0
- package/lib/utils/MapUtil.js +15 -0
- package/lib/utils/MapUtil.js.map +1 -0
- package/lib/utils/SetupWizard.d.ts +3 -0
- package/lib/utils/SetupWizard.js +21 -0
- package/lib/utils/SetupWizard.js.map +1 -0
- package/lib/utils/StringUtil.d.ts +9 -0
- package/lib/utils/StringUtil.js +41 -0
- package/lib/utils/StringUtil.js.map +1 -0
- package/package.json +43 -0
- package/prettier.config.js +15 -0
- package/src/NestiaMigrateApplication.ts +51 -0
- package/src/archivers/FileArchiver.ts +38 -0
- package/src/bundles/TEMPLATE.ts +257 -0
- package/src/executable/bundle.ts +74 -0
- package/src/executable/migrate.ts +58 -0
- package/src/index.ts +4 -0
- package/src/module.ts +4 -0
- package/src/programmers/ControllerProgrammer.ts +159 -0
- package/src/programmers/DtoProgrammer.ts +122 -0
- package/src/programmers/MigrateProgrammer.ts +31 -0
- package/src/programmers/RouteProgrammer.ts +264 -0
- package/src/programmers/SchemaProgrammer.ts +215 -0
- package/src/structures/IMigrateController.ts +8 -0
- package/src/structures/IMigrateDto.ts +8 -0
- package/src/structures/IMigrateFile.ts +5 -0
- package/src/structures/IMigrateProgram.ts +7 -0
- package/src/structures/IMigrateRoute.ts +20 -0
- package/src/structures/IMigrateSchema.ts +4 -0
- package/src/structures/ISwaggeSchema.ts +85 -0
- package/src/structures/ISwagger.ts +24 -0
- package/src/structures/ISwaggerComponents.ts +7 -0
- package/src/structures/ISwaggerRoute.ts +42 -0
- package/src/structures/ISwaggerSecurity.ts +47 -0
- package/src/test/index.ts +38 -0
- package/src/utils/JsonTypeChecker.ts +48 -0
- package/src/utils/MapUtil.ts +13 -0
- package/src/utils/SetupWizard.ts +15 -0
- package/src/utils/StringUtil.ts +49 -0
- package/tsconfig.json +81 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
import cp from "child_process";
|
2
|
+
import fs from "fs";
|
3
|
+
|
4
|
+
import { IMigrateFile } from "../structures/IMigrateFile";
|
5
|
+
|
6
|
+
const ROOT = __dirname + "/../..";
|
7
|
+
const ASSETS = ROOT + "/assets";
|
8
|
+
const TEMPLATE = ASSETS + "/template";
|
9
|
+
|
10
|
+
const clone = async (): Promise<void> => {
|
11
|
+
console.log("Preparing bundles...");
|
12
|
+
|
13
|
+
// CLONE REPOSITORY
|
14
|
+
if (fs.existsSync(TEMPLATE))
|
15
|
+
await fs.promises.rm(TEMPLATE, { recursive: true });
|
16
|
+
else
|
17
|
+
try {
|
18
|
+
await fs.promises.mkdir(ASSETS);
|
19
|
+
} catch {}
|
20
|
+
|
21
|
+
cp.execSync(
|
22
|
+
"git clone https://github.com/samchon/nestia-template template",
|
23
|
+
{
|
24
|
+
cwd: __dirname + "/../../assets",
|
25
|
+
},
|
26
|
+
);
|
27
|
+
|
28
|
+
// REMOVE VUNLERABLE FILES
|
29
|
+
for (const path of [
|
30
|
+
`${TEMPLATE}/src/api`,
|
31
|
+
`${TEMPLATE}/src/controllers`,
|
32
|
+
`${TEMPLATE}/src/providers`,
|
33
|
+
`${TEMPLATE}/test/features`,
|
34
|
+
`${TEMPLATE}/dist`,
|
35
|
+
])
|
36
|
+
await fs.promises.rm(path, { recursive: true });
|
37
|
+
};
|
38
|
+
|
39
|
+
const iterate = (collection: IMigrateFile[]) => async (location: string) => {
|
40
|
+
const directory: string[] = await fs.promises.readdir(location);
|
41
|
+
for (const file of directory) {
|
42
|
+
const absolute: string = location + "/" + file;
|
43
|
+
const stats: fs.Stats = await fs.promises.stat(absolute);
|
44
|
+
if (stats.isDirectory()) await iterate(collection)(absolute);
|
45
|
+
else {
|
46
|
+
const content: string = await fs.promises.readFile(
|
47
|
+
absolute,
|
48
|
+
"utf-8",
|
49
|
+
);
|
50
|
+
collection.push({
|
51
|
+
location: location.replace(TEMPLATE, ""),
|
52
|
+
file,
|
53
|
+
content,
|
54
|
+
});
|
55
|
+
}
|
56
|
+
}
|
57
|
+
};
|
58
|
+
|
59
|
+
const archive = async (collection: IMigrateFile[]): Promise<void> => {
|
60
|
+
const body: string = JSON.stringify(collection, null, 4);
|
61
|
+
const content: string = `export const TEMPLATE = ${body}`;
|
62
|
+
await fs.promises.writeFile(`${ROOT}/src/bundles/TEMPLATE.ts`, content);
|
63
|
+
};
|
64
|
+
|
65
|
+
const main = async (): Promise<void> => {
|
66
|
+
const collection: IMigrateFile[] = [];
|
67
|
+
await clone();
|
68
|
+
await iterate(collection)(TEMPLATE);
|
69
|
+
await archive(collection);
|
70
|
+
};
|
71
|
+
main().catch((exp) => {
|
72
|
+
console.error(exp);
|
73
|
+
process.exit(-1);
|
74
|
+
});
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
import fs from "fs";
|
3
|
+
|
4
|
+
import { NestiaMigrateApplication } from "../NestiaMigrateApplication";
|
5
|
+
import { ISwagger } from "../structures/ISwagger";
|
6
|
+
import { SetupWizard } from "../utils/SetupWizard";
|
7
|
+
|
8
|
+
const USAGE = `Wrong command has been detected. Use like below:
|
9
|
+
|
10
|
+
npx @nestia/migrate [input] [output]
|
11
|
+
|
12
|
+
ex) npx @nestia/migrate swagger.json my-new-project
|
13
|
+
`;
|
14
|
+
|
15
|
+
function halt(desc: string): never {
|
16
|
+
console.error(desc);
|
17
|
+
process.exit(-1);
|
18
|
+
}
|
19
|
+
|
20
|
+
const main = async (argv: string[]) => {
|
21
|
+
const input: string | undefined = argv[0];
|
22
|
+
const output: string | undefined = argv[1];
|
23
|
+
|
24
|
+
// VALIDATE ARGUMENTS
|
25
|
+
if (input === undefined || output === undefined) halt(USAGE);
|
26
|
+
else if (fs.existsSync(output)) halt("Output directory alreay exists.");
|
27
|
+
else if (fs.existsSync(output + "/..") === false)
|
28
|
+
halt("Output directory's parent directory does not exist.");
|
29
|
+
else if ((await fs.promises.stat(output + "/..")).isDirectory() === false)
|
30
|
+
halt("Output directory's parent is not a directory.");
|
31
|
+
|
32
|
+
// READ SWAGGER
|
33
|
+
const swagger: ISwagger = await (async () => {
|
34
|
+
if (fs.existsSync(input) === false)
|
35
|
+
halt("Unable to find the input swagger.json file.");
|
36
|
+
const stats: fs.Stats = await fs.promises.stat(input);
|
37
|
+
if (stats.isFile() === false)
|
38
|
+
halt("The input swagger.json is not a file.");
|
39
|
+
const content: string = await fs.readFileSync(input, "utf-8");
|
40
|
+
const swagger: ISwagger = JSON.parse(content);
|
41
|
+
return swagger;
|
42
|
+
})();
|
43
|
+
|
44
|
+
// DO GENERATE
|
45
|
+
const app = new NestiaMigrateApplication(swagger);
|
46
|
+
await app.generate({
|
47
|
+
mkdir: fs.promises.mkdir,
|
48
|
+
writeFile: (path, content) =>
|
49
|
+
fs.promises.writeFile(path, content, "utf8"),
|
50
|
+
})(output);
|
51
|
+
|
52
|
+
// RUN SCRIPTS
|
53
|
+
SetupWizard.setup(output);
|
54
|
+
};
|
55
|
+
main(process.argv.slice(2)).catch((exp) => {
|
56
|
+
console.log(exp);
|
57
|
+
process.exit(-1);
|
58
|
+
});
|
package/src/index.ts
ADDED
package/src/module.ts
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
import { IMigrateController } from "../structures/IMigrateController";
|
2
|
+
import { IMigrateRoute } from "../structures/IMigrateRoute";
|
3
|
+
import { ISwaggerSchema } from "../structures/ISwaggeSchema";
|
4
|
+
import { ISwagger } from "../structures/ISwagger";
|
5
|
+
import { MapUtil } from "../utils/MapUtil";
|
6
|
+
import { StringUtil } from "../utils/StringUtil";
|
7
|
+
import { RouteProgrammer } from "./RouteProgrammer";
|
8
|
+
|
9
|
+
export namespace ControllerProgrammer {
|
10
|
+
export const analyze = (swagger: ISwagger): IMigrateController[] => {
|
11
|
+
const dict: Map<string, IMigrateRoute[]> = new Map();
|
12
|
+
|
13
|
+
// GATHER ROUTES
|
14
|
+
for (const [path, collection] of Object.entries(swagger.paths)) {
|
15
|
+
// PREPARE DIRECTORIES
|
16
|
+
const location: string = StringUtil.split(path)
|
17
|
+
.filter((str) => str[0] !== "{")
|
18
|
+
.join("/");
|
19
|
+
for (const s of sequence(location)) MapUtil.take(dict)(s)(() => []);
|
20
|
+
|
21
|
+
// INSERT ROUTES TO THE LAST DIRECTORY
|
22
|
+
const routes: IMigrateRoute[] = MapUtil.take(dict)(location)(
|
23
|
+
() => [],
|
24
|
+
);
|
25
|
+
for (const [method, value] of Object.entries(collection)) {
|
26
|
+
const r: IMigrateRoute | null = RouteProgrammer.analyze(
|
27
|
+
swagger,
|
28
|
+
)({
|
29
|
+
path,
|
30
|
+
method,
|
31
|
+
})(value);
|
32
|
+
if (r !== null) routes.push(r);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
// ABSORB STANDALONE ROUTES
|
37
|
+
const emended: Map<string, IMigrateRoute[]> = new Map(
|
38
|
+
[...dict.entries()].sort((a, b) => a[0].localeCompare(b[0])),
|
39
|
+
);
|
40
|
+
for (const [location, routes] of emended) {
|
41
|
+
if (routes.length !== 1) continue;
|
42
|
+
for (const s of sequence(location).slice(0, 1)) {
|
43
|
+
const parent = emended.get(s);
|
44
|
+
if (parent) {
|
45
|
+
parent.push(...routes);
|
46
|
+
emended.delete(location);
|
47
|
+
break;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
// GENERATE CONTROLLERS
|
53
|
+
return [...emended.entries()]
|
54
|
+
.filter(([_l, routes]) => !!routes.length)
|
55
|
+
.map(([location, routes]) => {
|
56
|
+
const prefix: string = StringUtil.commonPrefix(
|
57
|
+
routes.map((r) => r.path),
|
58
|
+
);
|
59
|
+
for (const r of routes)
|
60
|
+
r.path = StringUtil.reJoinWithoutParameters(
|
61
|
+
r.path.replace(prefix, ""),
|
62
|
+
);
|
63
|
+
const controller: IMigrateController = {
|
64
|
+
name: StringUtil.pascal(location) + "Controller",
|
65
|
+
path: StringUtil.reJoinWithoutParameters(prefix),
|
66
|
+
location: "src/controllers/" + location,
|
67
|
+
routes,
|
68
|
+
};
|
69
|
+
naming(controller);
|
70
|
+
return controller;
|
71
|
+
});
|
72
|
+
};
|
73
|
+
|
74
|
+
const sequence = (location: string): string[] =>
|
75
|
+
StringUtil.split(location)
|
76
|
+
.map((_str, i, entire) => entire.slice(0, i + 1).join("/"))
|
77
|
+
.slice(0, -1)
|
78
|
+
.reverse();
|
79
|
+
|
80
|
+
const naming = (controller: IMigrateController): void => {
|
81
|
+
interface IRouteCapsule {
|
82
|
+
variables: string[];
|
83
|
+
route: IMigrateRoute;
|
84
|
+
}
|
85
|
+
const dict: Map<string, IRouteCapsule[]> = new Map();
|
86
|
+
for (const route of controller.routes) {
|
87
|
+
const additional: string[] = StringUtil.split(route.path);
|
88
|
+
const statics: string[] = additional.filter(
|
89
|
+
(str) => str[0] !== ":",
|
90
|
+
);
|
91
|
+
if (statics.length)
|
92
|
+
route.name = StringUtil.camel(statics.join("/"));
|
93
|
+
else
|
94
|
+
MapUtil.take(dict)(route.method)(() => []).push({
|
95
|
+
variables: additional
|
96
|
+
.filter((str) => str[0] === ":")
|
97
|
+
.map((str) => str.substring(1)),
|
98
|
+
route,
|
99
|
+
});
|
100
|
+
}
|
101
|
+
|
102
|
+
for (const [method, capsules] of dict) {
|
103
|
+
const emended: string = method === "delete" ? "erase" : method;
|
104
|
+
for (const c of capsules) {
|
105
|
+
const empty: boolean = c.variables.length === 0;
|
106
|
+
c.route.name = empty
|
107
|
+
? emended
|
108
|
+
: StringUtil.camel(
|
109
|
+
`${emended}By/${c.variables.join("/and/")}`,
|
110
|
+
);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
};
|
114
|
+
|
115
|
+
export const write = (controller: IMigrateController): string => {
|
116
|
+
const references: ISwaggerSchema.IReference[] = [];
|
117
|
+
const body: string = [
|
118
|
+
`@Controller(${JSON.stringify(controller.path)})`,
|
119
|
+
`export class ${controller.name} {`,
|
120
|
+
controller.routes
|
121
|
+
.map((r) =>
|
122
|
+
RouteProgrammer.write(references)(r)
|
123
|
+
.split("\n")
|
124
|
+
.map((l) => ` ${l}`)
|
125
|
+
.join("\n"),
|
126
|
+
)
|
127
|
+
.join("\n\n"),
|
128
|
+
`}`,
|
129
|
+
].join("\n");
|
130
|
+
|
131
|
+
const typia: boolean = controller.routes.some(
|
132
|
+
(m) => m.response !== null,
|
133
|
+
);
|
134
|
+
const imports: string[] = [
|
135
|
+
...new Set(
|
136
|
+
references.map(
|
137
|
+
(r) =>
|
138
|
+
r.$ref
|
139
|
+
.replace("#/components/schemas/", "")
|
140
|
+
.split(".")[0],
|
141
|
+
),
|
142
|
+
),
|
143
|
+
].map(
|
144
|
+
(ref) =>
|
145
|
+
`import { ${ref} } from "${"../".repeat(
|
146
|
+
StringUtil.split(controller.location).length - 1,
|
147
|
+
)}api/structures/${ref}"`,
|
148
|
+
);
|
149
|
+
|
150
|
+
return [
|
151
|
+
`import core from "@nestia/core";`,
|
152
|
+
`import { Controller } from "@nestjs/common";`,
|
153
|
+
"",
|
154
|
+
...(typia ? [`import typia from "typia";`, "\n"] : []),
|
155
|
+
...(imports.length ? [...imports, "\n"] : []),
|
156
|
+
body,
|
157
|
+
].join("\n");
|
158
|
+
};
|
159
|
+
}
|
@@ -0,0 +1,122 @@
|
|
1
|
+
import { IMigrateDto } from "../structures/IMigrateDto";
|
2
|
+
import { ISwaggerSchema } from "../structures/ISwaggeSchema";
|
3
|
+
import { ISwagger } from "../structures/ISwagger";
|
4
|
+
import { MapUtil } from "../utils/MapUtil";
|
5
|
+
import { SchemaProgrammer } from "./SchemaProgrammer";
|
6
|
+
|
7
|
+
export namespace DtoProgrammer {
|
8
|
+
export const analyze = (swagger: ISwagger): IMigrateDto[] => {
|
9
|
+
const root: Modulo = new Modulo("");
|
10
|
+
|
11
|
+
// COMPONENTS
|
12
|
+
for (const [id, schema] of Object.entries(
|
13
|
+
swagger.components.schemas ?? {},
|
14
|
+
)) {
|
15
|
+
const modulo = emplace(root)(id);
|
16
|
+
modulo.dto.schema = schema;
|
17
|
+
}
|
18
|
+
return root.toDto().children;
|
19
|
+
};
|
20
|
+
|
21
|
+
const emplace = (modulo: Modulo) => (name: string) => {
|
22
|
+
const identifiers: string[] = name.split(".");
|
23
|
+
for (const key of identifiers)
|
24
|
+
modulo = MapUtil.take(modulo.children)(key)(() => new Modulo(key));
|
25
|
+
return modulo;
|
26
|
+
};
|
27
|
+
|
28
|
+
export const write = (dto: IMigrateDto): string => {
|
29
|
+
const references: ISwaggerSchema.IReference[] = [];
|
30
|
+
const body: string = iterate(references)(dto);
|
31
|
+
const imports: string[] = [
|
32
|
+
...new Set(
|
33
|
+
references
|
34
|
+
.map(
|
35
|
+
(s) =>
|
36
|
+
s.$ref
|
37
|
+
.replace(`#/components/schemas/`, ``)
|
38
|
+
.split(".")[0],
|
39
|
+
)
|
40
|
+
.filter((str) => str !== dto.name),
|
41
|
+
),
|
42
|
+
];
|
43
|
+
const content: string[] = [
|
44
|
+
...imports.map((i) => `import { ${i} } from "./${i}";`),
|
45
|
+
...(imports.length ? [""] : []),
|
46
|
+
body,
|
47
|
+
];
|
48
|
+
return content.join("\n");
|
49
|
+
};
|
50
|
+
|
51
|
+
const iterate =
|
52
|
+
(references: ISwaggerSchema.IReference[]) =>
|
53
|
+
(dto: IMigrateDto): string => {
|
54
|
+
const content: string[] = [];
|
55
|
+
if (dto.schema) {
|
56
|
+
const description: string | undefined = describe(dto.schema);
|
57
|
+
content.push(
|
58
|
+
...(description
|
59
|
+
? [
|
60
|
+
"/**",
|
61
|
+
...description.split("\n").map((l) => ` * ${l}`),
|
62
|
+
" */",
|
63
|
+
]
|
64
|
+
: []),
|
65
|
+
`export type ${dto.name} = ${SchemaProgrammer.write(
|
66
|
+
references,
|
67
|
+
)(dto.schema)}`,
|
68
|
+
);
|
69
|
+
}
|
70
|
+
if (dto.children.length) {
|
71
|
+
content.push(
|
72
|
+
`export namespace ${dto.name} {`,
|
73
|
+
...dto.children.map((c) =>
|
74
|
+
iterate(references)(c)
|
75
|
+
.split("\n")
|
76
|
+
.map((l) => ` ${l}`)
|
77
|
+
.join("\n"),
|
78
|
+
),
|
79
|
+
`}`,
|
80
|
+
);
|
81
|
+
}
|
82
|
+
return content.join("\n");
|
83
|
+
};
|
84
|
+
|
85
|
+
const describe = (schema: ISwaggerSchema): string | undefined => {
|
86
|
+
const content: string[] = [];
|
87
|
+
const add = (text: string) => {
|
88
|
+
if (schema.description && !schema.description.includes(text))
|
89
|
+
content.push(text);
|
90
|
+
};
|
91
|
+
if (schema.description) {
|
92
|
+
content.push(...schema.description.split("\n"));
|
93
|
+
if (!schema.description.split("\n").at(-1)?.startsWith("@"))
|
94
|
+
content.push("");
|
95
|
+
}
|
96
|
+
if (schema.deprecated) add("@deprecated");
|
97
|
+
if (schema.title) add(`@title ${schema.title}`);
|
98
|
+
return content.length ? content.join("\n") : undefined;
|
99
|
+
};
|
100
|
+
}
|
101
|
+
|
102
|
+
class Modulo {
|
103
|
+
public readonly dto: IMigrateDto;
|
104
|
+
public readonly children: Map<string, Modulo>;
|
105
|
+
|
106
|
+
public constructor(name: string) {
|
107
|
+
this.dto = {
|
108
|
+
name,
|
109
|
+
location: "src/api/structures",
|
110
|
+
schema: null,
|
111
|
+
children: [],
|
112
|
+
};
|
113
|
+
this.children = new Map();
|
114
|
+
}
|
115
|
+
|
116
|
+
public toDto(): IMigrateDto {
|
117
|
+
this.dto.children = Array.from(this.children.values()).map((modulo) =>
|
118
|
+
modulo.toDto(),
|
119
|
+
);
|
120
|
+
return this.dto;
|
121
|
+
}
|
122
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { IMigrateFile } from "../structures/IMigrateFile";
|
2
|
+
import { IMigrateProgram } from "../structures/IMigrateProgram";
|
3
|
+
import { ISwagger } from "../structures/ISwagger";
|
4
|
+
import { ControllerProgrammer } from "./ControllerProgrammer";
|
5
|
+
import { DtoProgrammer } from "./DtoProgrammer";
|
6
|
+
|
7
|
+
export namespace MigrateProgrammer {
|
8
|
+
export const analyze = (swagger: ISwagger): IMigrateProgram => {
|
9
|
+
const controllers = ControllerProgrammer.analyze(swagger);
|
10
|
+
const structures = DtoProgrammer.analyze(swagger);
|
11
|
+
return {
|
12
|
+
controllers,
|
13
|
+
structures,
|
14
|
+
};
|
15
|
+
};
|
16
|
+
|
17
|
+
export const write = (program: IMigrateProgram): IMigrateFile[] => {
|
18
|
+
return [
|
19
|
+
...program.controllers.map((c) => ({
|
20
|
+
location: c.location,
|
21
|
+
file: `${c.name}.ts`,
|
22
|
+
content: ControllerProgrammer.write(c),
|
23
|
+
})),
|
24
|
+
...program.structures.map((s) => ({
|
25
|
+
location: s.location,
|
26
|
+
file: `${s.name}.ts`,
|
27
|
+
content: DtoProgrammer.write(s),
|
28
|
+
})),
|
29
|
+
];
|
30
|
+
};
|
31
|
+
}
|