@nestia/migrate 0.6.0 → 0.6.2

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 (85) hide show
  1. package/lib/{NestiaMigrateApplication.d.ts → MigrateApplication.d.ts} +2 -2
  2. package/lib/{NestiaMigrateApplication.js → MigrateApplication.js} +54 -29
  3. package/lib/MigrateApplication.js.map +1 -0
  4. package/lib/analyzers/ControllerAnalyzer.d.ts +5 -0
  5. package/lib/{programmers/ControllerProgrammer.js → analyzers/ControllerAnalyzer.js} +19 -37
  6. package/lib/analyzers/ControllerAnalyzer.js.map +1 -0
  7. package/lib/analyzers/MethodAnalyzer.d.ts +9 -0
  8. package/lib/{programmers/RouteProgrammer.js → analyzers/MethodAnalyzer.js} +24 -112
  9. package/lib/analyzers/MethodAnalyzer.js.map +1 -0
  10. package/lib/analyzers/MigrateAnalyzer.d.ts +4 -0
  11. package/lib/analyzers/MigrateAnalyzer.js +12 -0
  12. package/lib/analyzers/MigrateAnalyzer.js.map +1 -0
  13. package/lib/archivers/FileArchiver.d.ts +3 -3
  14. package/lib/archivers/FileArchiver.js +16 -7
  15. package/lib/archivers/FileArchiver.js.map +1 -1
  16. package/lib/executable/migrate.js +18 -9
  17. package/lib/executable/migrate.js.map +1 -1
  18. package/lib/module.d.ts +1 -1
  19. package/lib/module.js +1 -1
  20. package/lib/module.js.map +1 -1
  21. package/lib/programmers/ApiFileProgrammer.d.ts +17 -0
  22. package/lib/programmers/ApiFileProgrammer.js +28 -0
  23. package/lib/programmers/ApiFileProgrammer.js.map +1 -0
  24. package/lib/programmers/ApiFunctionProgrammer.d.ts +13 -0
  25. package/lib/programmers/ApiFunctionProgrammer.js +85 -0
  26. package/lib/programmers/ApiFunctionProgrammer.js.map +1 -0
  27. package/lib/programmers/ApiNamespaceProgrammer.d.ts +13 -0
  28. package/lib/programmers/ApiNamespaceProgrammer.js +134 -0
  29. package/lib/programmers/ApiNamespaceProgrammer.js.map +1 -0
  30. package/lib/programmers/ApiProgrammer.d.ts +5 -0
  31. package/lib/programmers/ApiProgrammer.js +62 -0
  32. package/lib/programmers/ApiProgrammer.js.map +1 -0
  33. package/lib/programmers/DtoProgrammer.js +2 -2
  34. package/lib/programmers/DtoProgrammer.js.map +1 -1
  35. package/lib/programmers/ImportProgrammer.d.ts +2 -1
  36. package/lib/programmers/ImportProgrammer.js +19 -4
  37. package/lib/programmers/ImportProgrammer.js.map +1 -1
  38. package/lib/programmers/{ControllerProgrammer.d.ts → NestControllerProgrammer.d.ts} +1 -3
  39. package/lib/programmers/NestControllerProgrammer.js +31 -0
  40. package/lib/programmers/NestControllerProgrammer.js.map +1 -0
  41. package/lib/programmers/{RouteProgrammer.d.ts → NestMethodProgrammer.d.ts} +1 -7
  42. package/lib/programmers/NestMethodProgrammer.js +118 -0
  43. package/lib/programmers/NestMethodProgrammer.js.map +1 -0
  44. package/lib/programmers/{ModuleProgrammer.d.ts → NestModuleProgrammer.d.ts} +1 -1
  45. package/lib/programmers/{ModuleProgrammer.js → NestModuleProgrammer.js} +6 -6
  46. package/lib/programmers/NestModuleProgrammer.js.map +1 -0
  47. package/lib/programmers/{MigrateProgrammer.d.ts → NestProgrammer.d.ts} +1 -3
  48. package/lib/programmers/{MigrateProgrammer.js → NestProgrammer.js} +10 -14
  49. package/lib/programmers/NestProgrammer.js.map +1 -0
  50. package/lib/programmers/SchemaProgrammer.d.ts +1 -1
  51. package/lib/programmers/SchemaProgrammer.js +17 -17
  52. package/lib/programmers/SchemaProgrammer.js.map +1 -1
  53. package/lib/structures/IMigrateRoute.d.ts +13 -4
  54. package/lib/utils/SetupWizard.js +0 -3
  55. package/lib/utils/SetupWizard.js.map +1 -1
  56. package/lib/utils/StringUtil.d.ts +1 -0
  57. package/lib/utils/StringUtil.js +4 -2
  58. package/lib/utils/StringUtil.js.map +1 -1
  59. package/package.json +1 -1
  60. package/src/{NestiaMigrateApplication.ts → MigrateApplication.ts} +32 -22
  61. package/src/{programmers/ControllerProgrammer.ts → analyzers/ControllerAnalyzer.ts} +123 -155
  62. package/src/{programmers/RouteProgrammer.ts → analyzers/MethodAnalyzer.ts} +20 -218
  63. package/src/analyzers/MigrateAnalyzer.ts +9 -0
  64. package/src/archivers/FileArchiver.ts +10 -7
  65. package/src/executable/migrate.ts +8 -8
  66. package/src/module.ts +1 -1
  67. package/src/programmers/ApiFileProgrammer.ts +51 -0
  68. package/src/programmers/ApiFunctionProgrammer.ts +177 -0
  69. package/src/programmers/ApiNamespaceProgrammer.ts +395 -0
  70. package/src/programmers/ApiProgrammer.ts +68 -0
  71. package/src/programmers/DtoProgrammer.ts +3 -3
  72. package/src/programmers/ImportProgrammer.ts +37 -21
  73. package/src/programmers/NestControllerProgrammer.ts +48 -0
  74. package/src/programmers/NestMethodProgrammer.ts +228 -0
  75. package/src/programmers/{ModuleProgrammer.ts → NestModuleProgrammer.ts} +1 -1
  76. package/src/programmers/{MigrateProgrammer.ts → NestProgrammer.ts} +11 -12
  77. package/src/programmers/SchemaProgrammer.ts +22 -25
  78. package/src/structures/IMigrateRoute.ts +13 -5
  79. package/src/utils/SetupWizard.ts +0 -3
  80. package/src/utils/StringUtil.ts +11 -2
  81. package/lib/NestiaMigrateApplication.js.map +0 -1
  82. package/lib/programmers/ControllerProgrammer.js.map +0 -1
  83. package/lib/programmers/MigrateProgrammer.js.map +0 -1
  84. package/lib/programmers/ModuleProgrammer.js.map +0 -1
  85. package/lib/programmers/RouteProgrammer.js.map +0 -1
@@ -1,155 +1,123 @@
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
- }
1
+ import { Escaper } from "typia/lib/utils/Escaper";
2
+
3
+ import { ISwagger } from "../module";
4
+ import { IMigrateController } from "../structures/IMigrateController";
5
+ import { IMigrateRoute } from "../structures/IMigrateRoute";
6
+ import { MapUtil } from "../utils/MapUtil";
7
+ import { StringUtil } from "../utils/StringUtil";
8
+ import { MethodAnalzyer } from "./MethodAnalyzer";
9
+
10
+ export namespace ControllerAnalyzer {
11
+ export const analyze = (swagger: ISwagger): IMigrateController[] => {
12
+ const dict: Map<string, IMigrateRoute[]> = new Map();
13
+
14
+ // GATHER ROUTES
15
+ for (const [path, collection] of Object.entries(swagger.paths)) {
16
+ // PREPARE DIRECTORIES
17
+ const location: string = StringUtil.splitWithNormalization(path)
18
+ .filter((str) => str[0] !== "{" && str[0] !== ":")
19
+ .join("/");
20
+ for (const s of sequence(location)) MapUtil.take(dict)(s)(() => []);
21
+
22
+ // INSERT ROUTES TO THE LAST DIRECTORY
23
+ const routes: IMigrateRoute[] = MapUtil.take(dict)(location)(() => []);
24
+ for (const [method, value] of Object.entries(collection)) {
25
+ const r: IMigrateRoute | null = MethodAnalzyer.analyze(swagger)({
26
+ path,
27
+ method,
28
+ })(value);
29
+ if (r !== null) routes.push(r);
30
+ }
31
+ }
32
+
33
+ // ABSORB STANDALONE ROUTES
34
+ const emended: Map<string, IMigrateRoute[]> = new Map(
35
+ [...dict.entries()].sort((a, b) => a[0].localeCompare(b[0])),
36
+ );
37
+ for (const [location, routes] of emended) {
38
+ if (routes.length !== 1) continue;
39
+ for (const s of sequence(location).slice(0, 1)) {
40
+ const parent = emended.get(s);
41
+ if (parent) {
42
+ parent.push(...routes);
43
+ emended.delete(location);
44
+ break;
45
+ }
46
+ }
47
+ }
48
+
49
+ // GENERATE CONTROLLERS
50
+ return [...emended.entries()]
51
+ .filter(([_l, routes]) => !!routes.length)
52
+ .map(([location, routes]) => {
53
+ const prefix: string = StringUtil.commonPrefix(
54
+ routes.map((r) => r.path),
55
+ );
56
+ for (const r of routes)
57
+ r.path = StringUtil.reJoinWithDecimalParameters(
58
+ r.path.replace(prefix, ""),
59
+ );
60
+ const controller: IMigrateController = {
61
+ name: StringUtil.pascal(location) + "Controller",
62
+ path: StringUtil.reJoinWithDecimalParameters(prefix),
63
+ location: "src/controllers/" + location,
64
+ routes,
65
+ };
66
+ if (controller.name === "Controller") controller.name = "__Controller";
67
+ emend(controller);
68
+ return controller;
69
+ });
70
+ };
71
+
72
+ const sequence = (location: string): string[] =>
73
+ StringUtil.splitWithNormalization(location)
74
+ .map((_str, i, entire) => entire.slice(0, i + 1).join("/"))
75
+ .slice(0, -1)
76
+ .reverse();
77
+
78
+ const emend = (controller: IMigrateController): void => {
79
+ interface IRouteCapsule {
80
+ variables: string[];
81
+ route: IMigrateRoute;
82
+ }
83
+ const dict: Map<string, IRouteCapsule[]> = new Map();
84
+ for (const route of controller.routes) {
85
+ const additional: string[] = StringUtil.splitWithNormalization(
86
+ route.path,
87
+ );
88
+ const statics: string[] = additional.filter((str) => str[0] !== ":");
89
+ if (statics.length) route.name = StringUtil.camel(statics.join("/"));
90
+ else
91
+ MapUtil.take(dict)(route.method)(() => []).push({
92
+ variables: additional
93
+ .filter((str) => str[0] === ":")
94
+ .map((str) => str.substring(1)),
95
+ route,
96
+ });
97
+ }
98
+ for (const [method, capsules] of dict) {
99
+ const emended: string = method === "delete" ? "erase" : method;
100
+ for (const c of capsules) {
101
+ const empty: boolean = c.variables.length === 0;
102
+ c.route.name = empty
103
+ ? emended
104
+ : StringUtil.camel(`${emended}By/${c.variables.join("/and/")}`);
105
+ }
106
+ }
107
+ for (const method of controller.routes) {
108
+ if (Escaper.variable(method.name) === false)
109
+ method.name = "_" + method.name;
110
+ for (const spec of [method.headers, method.query, method.body])
111
+ if (spec)
112
+ spec.key = StringUtil.escapeDuplicate(
113
+ method.parameters.map((p) => p.key),
114
+ )(spec.key);
115
+ }
116
+ controller.routes.forEach(
117
+ (r, i) =>
118
+ (r.name = StringUtil.escapeDuplicate(
119
+ controller.routes.filter((_r, j) => i !== j).map((x) => x.name),
120
+ )(r.name)),
121
+ );
122
+ };
123
+ }
@@ -1,24 +1,13 @@
1
- import ts from "typescript";
2
- import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
3
- import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory";
4
- import { TypeFactory } from "typia/lib/factories/TypeFactory";
5
1
  import { Escaper } from "typia/lib/utils/Escaper";
6
2
 
3
+ import { ISwagger } from "../module";
7
4
  import { IMigrateRoute } from "../structures/IMigrateRoute";
8
5
  import { ISwaggerSchema } from "../structures/ISwaggeSchema";
9
- import { ISwagger } from "../structures/ISwagger";
10
- import { ISwaggerComponents } from "../structures/ISwaggerComponents";
11
6
  import { ISwaggerRoute } from "../structures/ISwaggerRoute";
12
- import { FilePrinter } from "../utils/FilePrinter";
13
7
  import { SwaggerTypeChecker } from "../utils/JsonTypeChecker";
14
8
  import { StringUtil } from "../utils/StringUtil";
15
- import { ImportProgrammer } from "./ImportProgrammer";
16
- import { SchemaProgrammer } from "./SchemaProgrammer";
17
9
 
18
- export namespace RouteProgrammer {
19
- /* -----------------------------------------------------------
20
- ANALYZERS
21
- ----------------------------------------------------------- */
10
+ export namespace MethodAnalzyer {
22
11
  export const analyze =
23
12
  (swagger: ISwagger) =>
24
13
  (props: { path: string; method: string }) =>
@@ -172,14 +161,18 @@ export namespace RouteProgrammer {
172
161
  name: "@lazy",
173
162
  path: props.path,
174
163
  method: props.method,
175
- headers,
164
+ headers: headers
165
+ ? {
166
+ key: "headers",
167
+ schema: headers,
168
+ }
169
+ : null,
176
170
  parameters: (route.parameters ?? [])
177
171
  .filter((p) => p.in === "path")
178
172
  .map((p, i) => ({
179
173
  key: (() => {
180
174
  let key: string = StringUtil.normalize(parameterNames[i]);
181
175
  if (Escaper.variable(key)) return key;
182
-
183
176
  while (true) {
184
177
  key = "_" + key;
185
178
  if (!parameterNames.some((s) => s === key)) return key;
@@ -190,7 +183,12 @@ export namespace RouteProgrammer {
190
183
  description: p.schema.description ?? p.description,
191
184
  },
192
185
  })),
193
- query,
186
+ query: query
187
+ ? {
188
+ key: "query",
189
+ schema: query,
190
+ }
191
+ : null,
194
192
  body,
195
193
  success,
196
194
  exceptions: Object.fromEntries(
@@ -209,8 +207,9 @@ export namespace RouteProgrammer {
209
207
  },
210
208
  ]),
211
209
  ),
210
+ deprecated: route.deprecated ?? false,
212
211
  description: describe(route),
213
- "x-nestia-jsDocTags": route["x-nestia-jsDocTags"],
212
+ tags: route.tags ?? [],
214
213
  };
215
214
  };
216
215
 
@@ -285,6 +284,7 @@ export namespace RouteProgrammer {
285
284
  const { schema } = json[1];
286
285
  return {
287
286
  type: "application/json",
287
+ key: "body",
288
288
  schema: isNotObjectLiteral(schema) ? schema : emplacer(schema),
289
289
  "x-nestia-encrypted": meta["x-nestia-encrypted"],
290
290
  };
@@ -297,12 +297,14 @@ export namespace RouteProgrammer {
297
297
  const { schema } = query[1];
298
298
  return {
299
299
  type: "application/x-www-form-urlencoded",
300
+ key: "body",
300
301
  schema: isNotObjectLiteral(schema) ? schema : emplacer(schema),
301
302
  };
302
303
  }
303
304
 
304
305
  const text = entries.find((e) => e[0].includes("text/plain"));
305
- if (text) return { type: "text/plain", schema: { type: "string" } };
306
+ if (text)
307
+ return { type: "text/plain", key: "body", schema: { type: "string" } };
306
308
  return false;
307
309
  };
308
310
 
@@ -314,206 +316,6 @@ export namespace RouteProgrammer {
314
316
  swagger.components.schemas[name] = schema;
315
317
  return { $ref: `#/components/schemas/${name}` };
316
318
  };
317
-
318
- /* -----------------------------------------------------------
319
- WRITERS
320
- ----------------------------------------------------------- */
321
- export const write =
322
- (components: ISwaggerComponents) =>
323
- (importer: ImportProgrammer) =>
324
- (route: IMigrateRoute): ts.MethodDeclaration => {
325
- const output: ts.TypeNode = route.success
326
- ? SchemaProgrammer.write(importer)(components)(route.success.schema)
327
- : TypeFactory.keyword("void");
328
-
329
- const method: ts.MethodDeclaration = ts.factory.createMethodDeclaration(
330
- [
331
- ...writeMethodDecorators(components)(importer)(route),
332
- ts.factory.createToken(ts.SyntaxKind.PublicKeyword),
333
- ts.factory.createToken(ts.SyntaxKind.AsyncKeyword),
334
- ],
335
- undefined,
336
- route.name,
337
- undefined,
338
- undefined,
339
- writeParameters(importer)(components)(route),
340
- ts.factory.createTypeReferenceNode("Promise", [output]),
341
- ts.factory.createBlock(
342
- [
343
- ...[
344
- ...route.parameters.map((p) => StringUtil.normalize(p.key)),
345
- ...(route.headers ? ["headers"] : []),
346
- ...(route.query ? ["query"] : []),
347
- ...(route.body ? ["body"] : []),
348
- ].map((str) =>
349
- ts.factory.createExpressionStatement(
350
- ts.factory.createIdentifier(str),
351
- ),
352
- ),
353
- ts.factory.createReturnStatement(
354
- ts.factory.createCallExpression(
355
- ts.factory.createIdentifier(
356
- importer.external({
357
- library: "typia",
358
- instance: "random",
359
- }),
360
- ),
361
- [output],
362
- undefined,
363
- ),
364
- ),
365
- ],
366
- true,
367
- ),
368
- );
369
- return FilePrinter.description(method, route.description ?? "");
370
- };
371
-
372
- const writeMethodDecorators =
373
- (components: ISwaggerComponents) =>
374
- (importer: ImportProgrammer) =>
375
- (route: IMigrateRoute): ts.Decorator[] => {
376
- const external =
377
- (lib: string) =>
378
- (instance: string): ts.Identifier =>
379
- ts.factory.createIdentifier(
380
- importer.external({ library: lib, instance }),
381
- );
382
- const router = (instance: string) =>
383
- ts.factory.createDecorator(
384
- ts.factory.createCallExpression(
385
- IdentifierFactory.access(external("@nestia/core")(instance))(
386
- StringUtil.capitalize(route.method),
387
- ),
388
- [],
389
- [ts.factory.createStringLiteral(route.path)],
390
- ),
391
- );
392
-
393
- const decorators: ts.Decorator[] = [];
394
- if (route.success?.["x-nestia-encrypted"])
395
- decorators.push(router("EncryptedRoute"));
396
- else if (route.success?.type === "text/plain")
397
- decorators.push(
398
- ts.factory.createDecorator(
399
- ts.factory.createCallExpression(
400
- external("@nestjs/common")(StringUtil.capitalize(route.method)),
401
- [],
402
- [ts.factory.createStringLiteral(route.path)],
403
- ),
404
- ),
405
- );
406
- else if (route.success?.type === "application/x-www-form-urlencoded")
407
- decorators.push(router("TypedQuery"));
408
- else if (route.success?.type === "application/json")
409
- decorators.push(router("TypedRoute"));
410
- else if (route.method === "head")
411
- decorators.push(
412
- ts.factory.createDecorator(
413
- ts.factory.createCallExpression(
414
- external("@nestjs/common")("Head"),
415
- [],
416
- [ts.factory.createStringLiteral(route.path)],
417
- ),
418
- ),
419
- );
420
- for (const [key, value] of Object.entries(route.exceptions ?? {}))
421
- decorators.push(
422
- ts.factory.createDecorator(
423
- ts.factory.createCallExpression(
424
- external("@nestia/core")("TypedException"),
425
- [SchemaProgrammer.write(importer)(components)(value.schema)],
426
- [
427
- isNaN(Number(key))
428
- ? ts.factory.createStringLiteral(key)
429
- : ExpressionFactory.number(Number(key)),
430
- ...(value.description?.length
431
- ? [ts.factory.createStringLiteral(value.description)]
432
- : []),
433
- ],
434
- ),
435
- ),
436
- );
437
- return decorators;
438
- };
439
-
440
- const writeParameters =
441
- (importer: ImportProgrammer) =>
442
- (components: ISwaggerComponents) =>
443
- (route: IMigrateRoute): ts.ParameterDeclaration[] => [
444
- ...route.parameters.map(({ key, schema: value }) =>
445
- ts.factory.createParameterDeclaration(
446
- [
447
- ts.factory.createDecorator(
448
- ts.factory.createCallExpression(
449
- ts.factory.createIdentifier(
450
- importer.external({
451
- library: "@nestia/core",
452
- instance: "TypedParam",
453
- }),
454
- ),
455
- undefined,
456
- [ts.factory.createStringLiteral(key)],
457
- ),
458
- ),
459
- ],
460
- undefined,
461
- StringUtil.normalize(key),
462
- undefined,
463
- SchemaProgrammer.write(importer)(components)(value),
464
- ),
465
- ),
466
- ...(route.headers
467
- ? [
468
- writeDtoParameter({ method: "TypedHeaders", variable: "headers" })(
469
- importer,
470
- )(components)(route.headers),
471
- ]
472
- : []),
473
- ...(route.query
474
- ? [
475
- writeDtoParameter({ method: "TypedQuery", variable: "query" })(
476
- importer,
477
- )(components)(route.query),
478
- ]
479
- : []),
480
- ...(route.body
481
- ? [
482
- writeDtoParameter({
483
- method: route.body?.["x-nestia-encrypted"]
484
- ? "EncryptedBody"
485
- : "TypedBody",
486
- variable: "body",
487
- })(importer)(components)(route.body.schema),
488
- ]
489
- : []),
490
- ];
491
-
492
- const writeDtoParameter =
493
- (accessor: { method: string; variable: string }) =>
494
- (importer: ImportProgrammer) =>
495
- (components: ISwaggerComponents) =>
496
- (schema: ISwaggerSchema): ts.ParameterDeclaration =>
497
- ts.factory.createParameterDeclaration(
498
- [
499
- ts.factory.createDecorator(
500
- ts.factory.createCallExpression(
501
- ts.factory.createIdentifier(
502
- importer.external({
503
- library: "@nestia/core",
504
- instance: accessor.method,
505
- }),
506
- ),
507
- undefined,
508
- undefined,
509
- ),
510
- ),
511
- ],
512
- undefined,
513
- StringUtil.normalize(accessor.variable),
514
- undefined,
515
- SchemaProgrammer.write(importer)(components)(schema),
516
- );
517
319
  }
518
320
 
519
321
  const SUPPORTED_METHODS: Set<string> = new Set([
@@ -0,0 +1,9 @@
1
+ import { IMigrateProgram, ISwagger } from "../module";
2
+ import { ControllerAnalyzer } from "./ControllerAnalyzer";
3
+
4
+ export namespace MigrateAnalyzer {
5
+ export const analyze = (swagger: ISwagger): IMigrateProgram => ({
6
+ swagger,
7
+ controllers: ControllerAnalyzer.analyze(swagger),
8
+ });
9
+ }
@@ -2,18 +2,21 @@ import { IMigrateFile } from "../structures/IMigrateFile";
2
2
 
3
3
  export namespace FileArchiver {
4
4
  export interface IOperator {
5
- mkdir(path: string): void;
6
- writeFile(path: string, content: string): void;
5
+ mkdir(path: string): Promise<void>;
6
+ writeFile(path: string, content: string): Promise<void>;
7
7
  }
8
8
 
9
9
  export const archive =
10
10
  (operator: IOperator) =>
11
11
  (output: string) =>
12
- (files: IMigrateFile[]): void => {
12
+ async (files: IMigrateFile[]): Promise<void> => {
13
13
  const visited: Set<string> = new Set();
14
14
  for (const f of files) {
15
- mkdir(operator.mkdir)(output)(visited)(f.location);
16
- operator.writeFile([output, f.location, f.file].join("/"), f.content);
15
+ await mkdir(operator.mkdir)(output)(visited)(f.location);
16
+ await operator.writeFile(
17
+ [output, f.location, f.file].join("/"),
18
+ f.content,
19
+ );
17
20
  }
18
21
  };
19
22
 
@@ -21,14 +24,14 @@ export namespace FileArchiver {
21
24
  (creator: (path: string) => void) =>
22
25
  (output: string) =>
23
26
  (visited: Set<string>) =>
24
- (path: string): void => {
27
+ async (path: string): Promise<void> => {
25
28
  const sequence: string[] = path
26
29
  .split("/")
27
30
  .map((_str, i, entire) => entire.slice(0, i + 1).join("/"));
28
31
  for (const s of sequence)
29
32
  if (visited.has(s) === false)
30
33
  try {
31
- creator([output, s].join("/"));
34
+ await creator([output, s].join("/"));
32
35
  visited.add(s);
33
36
  } catch {}
34
37
  };
@@ -2,7 +2,7 @@
2
2
  import fs from "fs";
3
3
  import path from "path";
4
4
 
5
- import { NestiaMigrateApplication } from "../NestiaMigrateApplication";
5
+ import { MigrateApplication } from "../MigrateApplication";
6
6
  import { ISwagger } from "../structures/ISwagger";
7
7
  import { SetupWizard } from "../utils/SetupWizard";
8
8
 
@@ -18,7 +18,7 @@ function halt(desc: string): never {
18
18
  process.exit(-1);
19
19
  }
20
20
 
21
- const main = (argv: string[]) => {
21
+ const main = async (argv: string[]): Promise<void> => {
22
22
  const resolve = (str: string | undefined) =>
23
23
  str ? path.resolve(str).split("\\").join("/") : undefined;
24
24
  const input: string | undefined = resolve(argv[0]);
@@ -47,13 +47,13 @@ const main = (argv: string[]) => {
47
47
  })();
48
48
 
49
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);
50
+ const app: MigrateApplication = new MigrateApplication(swagger);
51
+ await app.generate(output);
55
52
 
56
53
  // RUN SCRIPTS
57
54
  SetupWizard.setup(output);
58
55
  };
59
- main(process.argv.slice(2));
56
+ main(process.argv.slice(2)).catch((exp) => {
57
+ console.error(exp);
58
+ process.exit(-1);
59
+ });