@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.
Files changed (72) hide show
  1. package/lib/NestiaMigrateApplication.js +15 -15
  2. package/lib/NestiaMigrateApplication.js.map +1 -1
  3. package/lib/archivers/FileArchiver.js.map +1 -1
  4. package/lib/bundles/TEMPLATE.js +11 -11
  5. package/lib/bundles/TEMPLATE.js.map +1 -1
  6. package/lib/executable/bundle.js.map +1 -1
  7. package/lib/executable/migrate.js +5 -5
  8. package/lib/executable/migrate.js.map +1 -1
  9. package/lib/programmers/ControllerProgrammer.d.ts +2 -1
  10. package/lib/programmers/ControllerProgrammer.js +21 -18
  11. package/lib/programmers/ControllerProgrammer.js.map +1 -1
  12. package/lib/programmers/DtoProgrammer.d.ts +8 -4
  13. package/lib/programmers/DtoProgrammer.js +36 -77
  14. package/lib/programmers/DtoProgrammer.js.map +1 -1
  15. package/lib/programmers/ImportProgrammer.d.ts +5 -5
  16. package/lib/programmers/ImportProgrammer.js +27 -19
  17. package/lib/programmers/ImportProgrammer.js.map +1 -1
  18. package/lib/programmers/MigrateProgrammer.d.ts +1 -2
  19. package/lib/programmers/MigrateProgrammer.js +52 -36
  20. package/lib/programmers/MigrateProgrammer.js.map +1 -1
  21. package/lib/programmers/ModuleProgrammer.d.ts +5 -0
  22. package/lib/programmers/ModuleProgrammer.js +29 -0
  23. package/lib/programmers/ModuleProgrammer.js.map +1 -0
  24. package/lib/programmers/RouteProgrammer.d.ts +2 -2
  25. package/lib/programmers/RouteProgrammer.js +108 -111
  26. package/lib/programmers/RouteProgrammer.js.map +1 -1
  27. package/lib/programmers/SchemaProgrammer.d.ts +2 -1
  28. package/lib/programmers/SchemaProgrammer.js +122 -189
  29. package/lib/programmers/SchemaProgrammer.js.map +1 -1
  30. package/lib/structures/IMigrateProgram.d.ts +2 -2
  31. package/lib/structures/ISwaggerInfo.d.ts +3 -3
  32. package/lib/utils/FilePrinter.d.ts +9 -0
  33. package/lib/utils/FilePrinter.js +25 -0
  34. package/lib/utils/FilePrinter.js.map +1 -0
  35. package/lib/utils/JsonTypeChecker.d.ts +3 -1
  36. package/lib/utils/JsonTypeChecker.js +31 -18
  37. package/lib/utils/JsonTypeChecker.js.map +1 -1
  38. package/lib/utils/MapUtil.js.map +1 -1
  39. package/lib/utils/SetupWizard.js.map +1 -1
  40. package/lib/utils/StringUtil.js.map +1 -1
  41. package/package.json +11 -9
  42. package/src/NestiaMigrateApplication.ts +68 -73
  43. package/src/archivers/FileArchiver.ts +35 -38
  44. package/src/bundles/TEMPLATE.ts +11 -11
  45. package/src/executable/bundle.ts +72 -78
  46. package/src/executable/migrate.ts +59 -60
  47. package/src/index.ts +4 -4
  48. package/src/module.ts +4 -4
  49. package/src/programmers/ControllerProgrammer.ts +155 -157
  50. package/src/programmers/DtoProgrammer.ts +74 -118
  51. package/src/programmers/ImportProgrammer.ts +98 -60
  52. package/src/programmers/MigrateProgrammer.ts +75 -62
  53. package/src/programmers/ModuleProgrammer.ts +62 -0
  54. package/src/programmers/RouteProgrammer.ts +486 -466
  55. package/src/programmers/SchemaProgrammer.ts +247 -339
  56. package/src/structures/IMigrateController.ts +8 -8
  57. package/src/structures/IMigrateDto.ts +8 -8
  58. package/src/structures/IMigrateFile.ts +5 -5
  59. package/src/structures/IMigrateProgram.ts +7 -7
  60. package/src/structures/IMigrateRoute.ts +36 -36
  61. package/src/structures/IMigrateSchema.ts +4 -4
  62. package/src/structures/ISwaggeSchema.ts +82 -82
  63. package/src/structures/ISwagger.ts +20 -20
  64. package/src/structures/ISwaggerComponents.ts +7 -7
  65. package/src/structures/ISwaggerInfo.ts +57 -57
  66. package/src/structures/ISwaggerRoute.ts +52 -52
  67. package/src/structures/ISwaggerSecurity.ts +47 -47
  68. package/src/utils/FilePrinter.ts +36 -0
  69. package/src/utils/JsonTypeChecker.ts +67 -52
  70. package/src/utils/MapUtil.ts +13 -13
  71. package/src/utils/SetupWizard.ts +15 -15
  72. 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
- 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)
44
- halt("The input swagger.json is not a file.");
45
- const content: string = fs.readFileSync(input, "utf-8");
46
- const swagger: ISwagger = JSON.parse(content);
47
- return swagger;
48
- })();
49
-
50
- // DO GENERATE
51
- const app = new NestiaMigrateApplication(swagger);
52
- app.generate({
53
- mkdir: fs.mkdirSync,
54
- writeFile: (path, content) => fs.writeFileSync(path, content, "utf8"),
55
- })(output);
56
-
57
- // RUN SCRIPTS
58
- SetupWizard.setup(output);
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 { IMigrateController } from "../structures/IMigrateController";
2
- import { IMigrateRoute } from "../structures/IMigrateRoute";
3
- import { ISwaggerSchema } from "../structures/ISwaggeSchema";
4
- import { ISwagger } from "../structures/ISwagger";
5
- import { ISwaggerComponents } from "../structures/ISwaggerComponents";
6
- import { MapUtil } from "../utils/MapUtil";
7
- import { StringUtil } from "../utils/StringUtil";
8
- import { ImportProgrammer } from "./ImportProgrammer";
9
- import { RouteProgrammer } from "./RouteProgrammer";
10
-
11
- export namespace ControllerProgrammer {
12
- export const analyze = (swagger: ISwagger): IMigrateController[] => {
13
- const dict: Map<string, IMigrateRoute[]> = new Map();
14
-
15
- // GATHER ROUTES
16
- for (const [path, collection] of Object.entries(swagger.paths)) {
17
- // PREPARE DIRECTORIES
18
- const location: string = StringUtil.splitWithNormalization(path)
19
- .filter((str) => str[0] !== "{" && str[0] !== ":")
20
- .join("/");
21
- for (const s of sequence(location)) MapUtil.take(dict)(s)(() => []);
22
-
23
- // INSERT ROUTES TO THE LAST DIRECTORY
24
- const routes: IMigrateRoute[] = MapUtil.take(dict)(location)(
25
- () => [],
26
- );
27
- for (const [method, value] of Object.entries(collection)) {
28
- const r: IMigrateRoute | null = RouteProgrammer.analyze(
29
- swagger,
30
- )({
31
- path,
32
- method,
33
- })(value);
34
- if (r !== null) routes.push(r);
35
- }
36
- }
37
-
38
- // ABSORB STANDALONE ROUTES
39
- const emended: Map<string, IMigrateRoute[]> = new Map(
40
- [...dict.entries()].sort((a, b) => a[0].localeCompare(b[0])),
41
- );
42
- for (const [location, routes] of emended) {
43
- if (routes.length !== 1) continue;
44
- for (const s of sequence(location).slice(0, 1)) {
45
- const parent = emended.get(s);
46
- if (parent) {
47
- parent.push(...routes);
48
- emended.delete(location);
49
- break;
50
- }
51
- }
52
- }
53
-
54
- // GENERATE CONTROLLERS
55
- return [...emended.entries()]
56
- .filter(([_l, routes]) => !!routes.length)
57
- .map(([location, routes]) => {
58
- const prefix: string = StringUtil.commonPrefix(
59
- routes.map((r) => r.path),
60
- );
61
- for (const r of routes)
62
- r.path = StringUtil.reJoinWithDecimalParameters(
63
- r.path.replace(prefix, ""),
64
- );
65
- const controller: IMigrateController = {
66
- name: StringUtil.pascal(location) + "Controller",
67
- path: StringUtil.reJoinWithDecimalParameters(prefix),
68
- location: "src/controllers/" + location,
69
- routes,
70
- };
71
- if (controller.name === "Controller")
72
- 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(
95
- (str) => str[0] !== ":",
96
- );
97
- if (statics.length)
98
- route.name = StringUtil.camel(statics.join("/"));
99
- else
100
- MapUtil.take(dict)(route.method)(() => []).push({
101
- variables: additional
102
- .filter((str) => str[0] === ":")
103
- .map((str) => str.substring(1)),
104
- route,
105
- });
106
- }
107
-
108
- for (const [method, capsules] of dict) {
109
- const emended: string = method === "delete" ? "erase" : method;
110
- for (const c of capsules) {
111
- const empty: boolean = c.variables.length === 0;
112
- c.route.name = empty
113
- ? emended
114
- : StringUtil.camel(
115
- `${emended}By/${c.variables.join("/and/")}`,
116
- );
117
- }
118
- }
119
- };
120
-
121
- export const write =
122
- (components: ISwaggerComponents) =>
123
- (controller: IMigrateController): string => {
124
- const importer: ImportProgrammer = new ImportProgrammer(null);
125
- const references: ISwaggerSchema.IReference[] = [];
126
- const body: string = [
127
- `@${importer.external({
128
- library: "@nestjs/common",
129
- instance: "Controller",
130
- })}(${JSON.stringify(controller.path)})`,
131
- `export class ${controller.name} {`,
132
- controller.routes
133
- .map((r) =>
134
- RouteProgrammer.write(components)(references)(importer)(
135
- r,
136
- )
137
- .split("\n")
138
- .map((l) => ` ${l}`)
139
- .join("\n"),
140
- )
141
- .join("\n\n"),
142
- `}`,
143
- ].join("\n");
144
- return [
145
- ...importer.toScript(
146
- (ref) =>
147
- `${"../".repeat(
148
- StringUtil.splitWithNormalization(
149
- controller.location,
150
- ).length - 1,
151
- )}api/structures/${ref}`,
152
- ),
153
- ...(importer.empty() ? [] : [""]),
154
- body,
155
- ].join("\n");
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
+ }