@nestia/migrate 0.5.1 → 0.6.1

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 (103) hide show
  1. package/lib/{NestiaMigrateApplication.d.ts → MigrateApplication.d.ts} +1 -1
  2. package/lib/{NestiaMigrateApplication.js → MigrateApplication.js} +38 -32
  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} +8 -32
  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} +30 -134
  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/analyzers/RouteAnalyzer.d.ts +0 -0
  14. package/lib/analyzers/RouteAnalyzer.js +2 -0
  15. package/lib/analyzers/RouteAnalyzer.js.map +1 -0
  16. package/lib/archivers/FileArchiver.js.map +1 -1
  17. package/lib/bundles/TEMPLATE.js +10 -10
  18. package/lib/bundles/TEMPLATE.js.map +1 -1
  19. package/lib/executable/bundle.js.map +1 -1
  20. package/lib/executable/migrate.js +7 -7
  21. package/lib/executable/migrate.js.map +1 -1
  22. package/lib/module.d.ts +1 -1
  23. package/lib/module.js +1 -1
  24. package/lib/module.js.map +1 -1
  25. package/lib/programmers/DtoProgrammer.d.ts +8 -4
  26. package/lib/programmers/DtoProgrammer.js +36 -77
  27. package/lib/programmers/DtoProgrammer.js.map +1 -1
  28. package/lib/programmers/ImportProgrammer.d.ts +5 -5
  29. package/lib/programmers/ImportProgrammer.js +27 -19
  30. package/lib/programmers/ImportProgrammer.js.map +1 -1
  31. package/lib/programmers/{ControllerProgrammer.d.ts → NestControllerProgrammer.d.ts} +3 -4
  32. package/lib/programmers/NestControllerProgrammer.js +30 -0
  33. package/lib/programmers/NestControllerProgrammer.js.map +1 -0
  34. package/lib/programmers/NestMethodProgrammer.d.ts +7 -0
  35. package/lib/programmers/NestMethodProgrammer.js +103 -0
  36. package/lib/programmers/NestMethodProgrammer.js.map +1 -0
  37. package/lib/programmers/NestModuleProgrammer.d.ts +5 -0
  38. package/lib/programmers/NestModuleProgrammer.js +29 -0
  39. package/lib/programmers/NestModuleProgrammer.js.map +1 -0
  40. package/lib/programmers/NestProgrammer.d.ts +5 -0
  41. package/lib/programmers/NestProgrammer.js +60 -0
  42. package/lib/programmers/NestProgrammer.js.map +1 -0
  43. package/lib/programmers/SchemaProgrammer.d.ts +2 -1
  44. package/lib/programmers/SchemaProgrammer.js +122 -189
  45. package/lib/programmers/SchemaProgrammer.js.map +1 -1
  46. package/lib/structures/IMigrateProgram.d.ts +2 -2
  47. package/lib/structures/ISwaggerInfo.d.ts +3 -3
  48. package/lib/utils/FilePrinter.d.ts +9 -0
  49. package/lib/utils/FilePrinter.js +25 -0
  50. package/lib/utils/FilePrinter.js.map +1 -0
  51. package/lib/utils/JsonTypeChecker.d.ts +3 -1
  52. package/lib/utils/JsonTypeChecker.js +31 -18
  53. package/lib/utils/JsonTypeChecker.js.map +1 -1
  54. package/lib/utils/MapUtil.js.map +1 -1
  55. package/lib/utils/SetupWizard.js.map +1 -1
  56. package/lib/utils/StringUtil.js.map +1 -1
  57. package/package.json +8 -6
  58. package/src/MigrateApplication.ts +73 -0
  59. package/src/analyzers/ControllerAnalyzer.ts +107 -0
  60. package/src/analyzers/MethodAnalyzer.ts +315 -0
  61. package/src/analyzers/MigrateAnalyzer.ts +9 -0
  62. package/src/analyzers/RouteAnalyzer.ts +0 -0
  63. package/src/archivers/FileArchiver.ts +35 -38
  64. package/src/bundles/TEMPLATE.ts +10 -10
  65. package/src/executable/bundle.ts +72 -78
  66. package/src/executable/migrate.ts +59 -60
  67. package/src/index.ts +4 -4
  68. package/src/module.ts +4 -4
  69. package/src/programmers/DtoProgrammer.ts +74 -118
  70. package/src/programmers/ImportProgrammer.ts +98 -60
  71. package/src/programmers/NestControllerProgrammer.ts +47 -0
  72. package/src/programmers/NestMethodProgrammer.ts +211 -0
  73. package/src/programmers/NestModuleProgrammer.ts +62 -0
  74. package/src/programmers/NestProgrammer.ts +74 -0
  75. package/src/programmers/SchemaProgrammer.ts +247 -339
  76. package/src/structures/IMigrateController.ts +8 -8
  77. package/src/structures/IMigrateDto.ts +8 -8
  78. package/src/structures/IMigrateFile.ts +5 -5
  79. package/src/structures/IMigrateProgram.ts +7 -7
  80. package/src/structures/IMigrateRoute.ts +36 -36
  81. package/src/structures/IMigrateSchema.ts +4 -4
  82. package/src/structures/ISwaggeSchema.ts +82 -82
  83. package/src/structures/ISwagger.ts +20 -20
  84. package/src/structures/ISwaggerComponents.ts +7 -7
  85. package/src/structures/ISwaggerInfo.ts +57 -57
  86. package/src/structures/ISwaggerRoute.ts +52 -52
  87. package/src/structures/ISwaggerSecurity.ts +47 -47
  88. package/src/utils/FilePrinter.ts +36 -0
  89. package/src/utils/JsonTypeChecker.ts +67 -52
  90. package/src/utils/MapUtil.ts +13 -13
  91. package/src/utils/SetupWizard.ts +15 -15
  92. package/src/utils/StringUtil.ts +51 -51
  93. package/lib/NestiaMigrateApplication.js.map +0 -1
  94. package/lib/programmers/ControllerProgrammer.js.map +0 -1
  95. package/lib/programmers/MigrateProgrammer.d.ts +0 -8
  96. package/lib/programmers/MigrateProgrammer.js +0 -48
  97. package/lib/programmers/MigrateProgrammer.js.map +0 -1
  98. package/lib/programmers/RouteProgrammer.d.ts +0 -13
  99. package/lib/programmers/RouteProgrammer.js.map +0 -1
  100. package/src/NestiaMigrateApplication.ts +0 -73
  101. package/src/programmers/ControllerProgrammer.ts +0 -157
  102. package/src/programmers/MigrateProgrammer.ts +0 -62
  103. package/src/programmers/RouteProgrammer.ts +0 -506
@@ -1,347 +1,255 @@
1
+ import ts from "typescript";
2
+ import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
3
+ import { TypeFactory } from "typia/lib/factories/TypeFactory";
4
+ import { FormatCheatSheet } from "typia/lib/tags/internal/FormatCheatSheet";
1
5
  import { Escaper } from "typia/lib/utils/Escaper";
2
6
 
3
7
  import { ISwaggerSchema } from "../structures/ISwaggeSchema";
4
8
  import { ISwaggerComponents } from "../structures/ISwaggerComponents";
5
- import { JsonTypeChecker } from "../utils/JsonTypeChecker";
9
+ import { FilePrinter } from "../utils/FilePrinter";
10
+ import { SwaggerTypeChecker } from "../utils/JsonTypeChecker";
6
11
  import { ImportProgrammer } from "./ImportProgrammer";
7
12
 
8
13
  export namespace SchemaProgrammer {
9
- export const write =
10
- (components: ISwaggerComponents) =>
11
- (references: ISwaggerSchema.IReference[]) =>
12
- (importer: ImportProgrammer) =>
13
- (schema: ISwaggerSchema): string =>
14
- writeSchema(components)(references)(importer)(() => () => {})(true)(
15
- schema,
16
- );
17
-
18
- type CommentTagger = (tag: string) => (value?: string) => void;
19
-
20
- const writeSchema =
21
- (components: ISwaggerComponents) =>
22
- (references: ISwaggerSchema.IReference[]) =>
23
- (importer: ImportProgrammer) =>
24
- (commentTagger: CommentTagger) =>
25
- (final: boolean) =>
26
- (schema: ISwaggerSchema): string => {
27
- // SPECIAL TYPES
28
- if (JsonTypeChecker.isUnknown(schema)) return "any";
29
-
30
- const type: string = (() => {
31
- if (JsonTypeChecker.isAnyOf(schema))
32
- return (
33
- "(" +
34
- schema.anyOf
35
- .map(
36
- writeSchema(components)(references)(importer)(
37
- commentTagger,
38
- )(false),
39
- )
40
- .join(" | ") +
41
- ")"
42
- );
43
- else if (JsonTypeChecker.isOneOf(schema))
44
- return schema.oneOf
45
- .map(
46
- writeSchema(components)(references)(importer)(
47
- commentTagger,
48
- )(false),
49
- )
50
- .join(" | ");
51
- // ATOMIC TYPES
52
- if (JsonTypeChecker.isNullOnly(schema)) return writeNullOnly();
53
- else if (JsonTypeChecker.isBoolean(schema))
54
- return writeBoolean(importer)(commentTagger)(schema);
55
- else if (
56
- JsonTypeChecker.isInteger(schema) ||
57
- JsonTypeChecker.isNumber(schema)
58
- )
59
- return writeNumber(importer)(commentTagger)(schema);
60
- else if (JsonTypeChecker.isString(schema))
61
- return writeString(importer)(commentTagger)(schema);
62
- // INSTANCE TYPES
63
- else if (JsonTypeChecker.isArray(schema))
64
- return writeArray(components)(references)(importer)(
65
- commentTagger,
66
- )(schema);
67
- else if (JsonTypeChecker.isObject(schema))
68
- return writeObject(components)(references)(importer)(
69
- schema,
70
- );
71
- else if (JsonTypeChecker.isReference(schema)) {
72
- references.push(schema);
73
- return importer.dto(
74
- schema.$ref.replace(`#/components/schemas/`, ``),
75
- );
76
- } else return "any";
77
- })();
78
- if (type === "any" || final === false) return type;
79
- return isNullable(components)(schema) ? `null | ${type}` : type;
80
- };
81
-
82
- const isNullable =
83
- (components: ISwaggerComponents) =>
84
- (schema: ISwaggerSchema): boolean => {
85
- if (JsonTypeChecker.isAnyOf(schema))
86
- return schema.anyOf.some(isNullable(components));
87
- else if (JsonTypeChecker.isOneOf(schema))
88
- return schema.oneOf.some(isNullable(components));
89
- else if (JsonTypeChecker.isReference(schema)) {
90
- const $id = schema.$ref.replace("#/components/schemas/", "");
91
- const target = (components.schemas ?? {})[$id];
92
- return target === undefined
93
- ? false
94
- : isNullable(components)(target);
95
- }
96
- return (schema as ISwaggerSchema.IString).nullable === true;
97
- };
98
-
99
- const writeNullOnly = (): string => "null";
100
-
101
- const writeBoolean =
102
- (importer: ImportProgrammer) =>
103
- (tagger: CommentTagger) =>
104
- (schema: ISwaggerSchema.IBoolean): string => {
105
- if (schema.enum?.length) {
106
- if (schema.default !== undefined)
107
- tagger("default")(schema.default.toString());
108
- return schema.enum.join(" | ");
109
- }
110
- const intersection: string[] = ["boolean"];
111
- if (schema.default !== undefined)
112
- intersection.push(
113
- importer.tag("Default", String(schema.default)),
114
- );
115
- return intersection.length === 1
116
- ? intersection[0]
117
- : "(" + intersection.join(" & ") + ")";
118
- };
119
-
120
- const writeNumber =
121
- (importer: ImportProgrammer) =>
122
- (commentTagger: CommentTagger) =>
123
- (schema: ISwaggerSchema.IInteger | ISwaggerSchema.INumber): string => {
124
- if (schema.enum?.length) {
125
- if (schema.default !== undefined)
126
- commentTagger("default")(schema.default.toString());
127
- return schema.enum.join(" | ");
128
- }
129
-
130
- const intersection: string[] = ["number"];
131
- if (schema.default !== undefined)
132
- intersection.push(importer.tag("Default", schema.default));
133
- if (schema.type === "integer")
134
- intersection.push(importer.tag("Type", "int32"));
135
- if (schema.minimum !== undefined)
136
- intersection.push(
137
- importer.tag(
138
- schema.exclusiveMinimum
139
- ? "ExclusiveMinimum"
140
- : "Minimum",
141
- schema.minimum,
142
- ),
143
- );
144
- if (schema.maximum !== undefined)
145
- intersection.push(
146
- importer.tag(
147
- schema.exclusiveMaximum
148
- ? "ExclusiveMaximum"
149
- : "Maximum",
150
- schema.maximum,
151
- ),
152
- );
153
- if (schema.multipleOf !== undefined)
154
- intersection.push(
155
- importer.tag("MultipleOf", schema.multipleOf),
156
- );
157
- return intersection.length === 1
158
- ? intersection[0]
159
- : "(" + intersection.join(" & ") + ")";
160
- };
161
- const writeString =
162
- (importer: ImportProgrammer) =>
163
- (commentTagger: CommentTagger) =>
164
- (schema: ISwaggerSchema.IString): string => {
165
- if (schema.enum?.length) {
166
- if (schema.default !== undefined)
167
- commentTagger("default")(schema.default.toString());
168
- return schema.enum
169
- .map((str) => JSON.stringify(str))
170
- .join(" | ");
171
- }
172
-
173
- const intersection: string[] = ["string"];
174
- if (schema.default !== undefined)
175
- intersection.push(importer.tag("Default", schema.default));
176
- if (schema.format !== undefined && FORMATS.has(schema.format))
177
- intersection.push(importer.tag("Format", schema.format));
178
- if (schema.pattern !== undefined)
179
- intersection.push(importer.tag("Pattern", schema.pattern));
180
- if (schema.minLength !== undefined)
181
- intersection.push(importer.tag("MinLength", schema.minLength));
182
- if (schema.maxLength !== undefined)
183
- intersection.push(importer.tag("MaxLength", schema.maxLength));
184
- return intersection.length === 1
185
- ? intersection[0]
186
- : "(" + intersection.join(" & ") + ")";
187
- };
188
-
189
- const writeArray =
190
- (components: ISwaggerComponents) =>
191
- (references: ISwaggerSchema.IReference[]) =>
192
- (importer: ImportProgrammer) =>
193
- (commentTagger: CommentTagger) =>
194
- (schema: ISwaggerSchema.IArray): string => {
195
- if (schema["x-typia-tuple"])
196
- return `[${schema["x-typia-tuple"].items
197
- .map(writeTupleElement(components)(references)(importer))
198
- .join(", ")}]`;
199
- const intersection: string[] = [
200
- `Array<${writeSchema(components)(references)(importer)(
201
- commentTagger,
202
- )(true)(schema.items)}>`,
203
- ];
204
- if (schema.minItems !== undefined)
205
- intersection.push(importer.tag("MinItems", schema.minItems));
206
- if (schema.maxItems !== undefined)
207
- intersection.push(importer.tag("MaxItems", schema.maxItems));
208
-
209
- return intersection.length === 1
210
- ? intersection[0]
211
- : "(" + intersection.join(" & ") + ")";
212
- };
213
- const writeTupleElement =
214
- (components: ISwaggerComponents) =>
215
- (references: ISwaggerSchema.IReference[]) =>
216
- (importer: ImportProgrammer) =>
217
- (schema: ISwaggerSchema): string => {
218
- const name: string = writeSchema(components)(references)(importer)(
219
- () => () => {},
220
- )(true)(schema);
221
- return schema["x-typia-optional"]
222
- ? `${name}?`
223
- : schema["x-typia-rest"]
224
- ? `...${name}[]`
225
- : name;
226
- };
227
-
228
- const writeObject =
229
- (components: ISwaggerComponents) =>
230
- (references: ISwaggerSchema.IReference[]) =>
231
- (importer: ImportProgrammer) =>
232
- (schema: ISwaggerSchema.IObject): string => {
233
- const entries = Object.entries(schema.properties ?? {});
234
- return typeof schema.additionalProperties === "object"
235
- ? entries.length
236
- ? `${writeStaticObject(components)(references)(importer)(
237
- schema,
238
- )} & ${writeDynamicObject(components)(references)(
239
- importer,
240
- )(schema.additionalProperties)}`
241
- : writeDynamicObject(components)(references)(importer)(
242
- schema.additionalProperties,
243
- )
244
- : writeStaticObject(components)(references)(importer)(schema);
245
- };
246
- const writeStaticObject =
247
- (components: ISwaggerComponents) =>
248
- (references: ISwaggerSchema.IReference[]) =>
249
- (importer: ImportProgrammer) =>
250
- (schema: ISwaggerSchema.IObject): string =>
251
- [
252
- "{",
253
- ...Object.entries(schema.properties ?? {})
254
- .map(([key, value]) =>
255
- writeProperty(components)(references)(importer)(key)(
256
- (schema.required ?? []).some((r) => r === key),
257
- )(value),
258
- )
259
- .map(tab(4)),
260
- "}",
261
- ].join("\n");
262
- const writeDynamicObject =
263
- (components: ISwaggerComponents) =>
264
- (references: ISwaggerSchema.IReference[]) =>
265
- (importer: ImportProgrammer) =>
266
- (additional: ISwaggerSchema): string => {
267
- return [
268
- "{",
269
- tab(4)(
270
- writeProperty(components)(references)(importer)(
271
- "[key: string]",
272
- true,
273
- )(true)(additional),
274
- ),
275
- "}",
276
- ].join("\n");
277
- };
278
-
279
- const writeProperty =
280
- (components: ISwaggerComponents) =>
281
- (references: ISwaggerSchema.IReference[]) =>
282
- (importer: ImportProgrammer) =>
283
- (key: string, ensureVariable: boolean = false) =>
284
- (required: boolean) =>
285
- (schema: ISwaggerSchema): string => {
286
- const content: string[] = [];
287
- const commentTagger = (tag: string) => (value?: string) => {
288
- const exists: boolean =
289
- (!!schema.description?.length &&
290
- schema.description.includes(`@${tag}`)) ||
291
- content.some((line) => line.includes(`@${tag}`));
292
- if (exists === false)
293
- if (value?.length) content.push(`@${tag} ${value}`);
294
- else content.push(`@${tag}`);
295
- };
296
- if (schema.description) {
297
- content.push(...schema.description.split("\n"));
298
- if (!schema.description.split("\n").at(-1)?.startsWith("@"))
299
- content.push("");
300
- }
301
-
302
- // STARTS FROM TITLE
303
- if (schema.title) commentTagger("@title")(schema.title);
304
-
305
- // GET TYPE WITH SPECIAL TAGS
306
- const type: string =
307
- writeSchema(components)(references)(importer)(commentTagger)(
308
- true,
309
- )(schema);
310
-
311
- // ENDS WITH DEPRECATED TAG
312
- if (schema.deprecated) commentTagger("@deprecated")();
313
-
314
- const description: string =
315
- content.length === 0
316
- ? ""
317
- : [
318
- "/**",
319
- ...content.map((line) => ` * ${line}`),
320
- " */",
321
- "",
322
- ].join("\n");
323
- return `${description}${
324
- ensureVariable === false && Escaper.variable(key) === false
325
- ? JSON.stringify(key)
326
- : key
327
- }${required ? "" : "?"}: ${required ? type : `undefined | ${type}`};`;
328
- };
329
-
330
- const tab =
331
- (size: number) =>
332
- (str: string): string =>
333
- str
334
- .split("\n")
335
- .map((l) => `${" ".repeat(size)}${l}`)
336
- .join("\n");
14
+ /* -----------------------------------------------------------
15
+ FACADE
16
+ ----------------------------------------------------------- */
17
+ export const write =
18
+ (importer: ImportProgrammer) =>
19
+ (components: ISwaggerComponents) =>
20
+ (schema: ISwaggerSchema): ts.TypeNode => {
21
+ const union: ts.TypeNode[] = [];
22
+ if (SwaggerTypeChecker.isUnknown(schema))
23
+ return TypeFactory.keyword("any");
24
+ else if (SwaggerTypeChecker.isNullOnly(schema)) return createNode("null");
25
+ else if (SwaggerTypeChecker.isNullable(components)(schema))
26
+ union.push(createNode("null"));
27
+
28
+ const type: ts.TypeNode = (() => {
29
+ // ATOMIC
30
+ if (SwaggerTypeChecker.isBoolean(schema)) return writeBoolean(schema);
31
+ else if (SwaggerTypeChecker.isInteger(schema))
32
+ return writeInteger(importer)(schema);
33
+ else if (SwaggerTypeChecker.isNumber(schema))
34
+ return writeNumber(importer)(schema);
35
+ // INSTANCES
36
+ else if (SwaggerTypeChecker.isString(schema))
37
+ return writeString(importer)(schema);
38
+ else if (SwaggerTypeChecker.isArray(schema))
39
+ return writeArray(importer)(components)(schema);
40
+ else if (SwaggerTypeChecker.isObject(schema))
41
+ return writeObject(importer)(components)(schema);
42
+ else if (SwaggerTypeChecker.isReference(schema))
43
+ return writeReference(importer)(schema);
44
+ // NESTED UNION
45
+ else if (SwaggerTypeChecker.isAnyOf(schema))
46
+ return writeUnion(importer)(components)(schema.anyOf);
47
+ else if (SwaggerTypeChecker.isOneOf(schema))
48
+ return writeUnion(importer)(components)(schema.oneOf);
49
+ else return TypeFactory.keyword("any");
50
+ })();
51
+ union.push(type);
52
+
53
+ if (union.length === 0) return TypeFactory.keyword("any");
54
+ else if (union.length === 1) return union[0];
55
+ return ts.factory.createUnionTypeNode(union);
56
+ };
57
+
58
+ /* -----------------------------------------------------------
59
+ ATOMICS
60
+ ----------------------------------------------------------- */
61
+ const writeBoolean = (schema: ISwaggerSchema.IBoolean): ts.TypeNode => {
62
+ if (schema.enum?.length)
63
+ return ts.factory.createLiteralTypeNode(
64
+ schema.enum[0] ? ts.factory.createTrue() : ts.factory.createFalse(),
65
+ );
66
+ return TypeFactory.keyword("boolean");
67
+ };
68
+
69
+ const writeInteger =
70
+ (importer: ImportProgrammer) =>
71
+ (schema: ISwaggerSchema.IInteger): ts.TypeNode =>
72
+ writeNumeric(() => [
73
+ TypeFactory.keyword("number"),
74
+ importer.tag("Type", "int32"),
75
+ ])(importer)(schema);
76
+
77
+ const writeNumber =
78
+ (importer: ImportProgrammer) =>
79
+ (schema: ISwaggerSchema.INumber): ts.TypeNode =>
80
+ writeNumeric(() => [TypeFactory.keyword("number")])(importer)(schema);
81
+
82
+ const writeNumeric =
83
+ (factory: () => ts.TypeNode[]) =>
84
+ (importer: ImportProgrammer) =>
85
+ (schema: ISwaggerSchema.IInteger | ISwaggerSchema.INumber): ts.TypeNode => {
86
+ if (schema.enum?.length)
87
+ return ts.factory.createUnionTypeNode(
88
+ schema.enum.map((i) =>
89
+ ts.factory.createLiteralTypeNode(ExpressionFactory.number(i)),
90
+ ),
91
+ );
92
+ const intersection: ts.TypeNode[] = factory();
93
+ if (schema.default !== undefined)
94
+ intersection.push(importer.tag("Default", schema.default));
95
+ if (schema.minimum !== undefined)
96
+ intersection.push(
97
+ importer.tag(
98
+ schema.exclusiveMinimum ? "ExclusiveMinimum" : "Minimum",
99
+ schema.minimum,
100
+ ),
101
+ );
102
+ if (schema.maximum !== undefined)
103
+ intersection.push(
104
+ importer.tag(
105
+ schema.exclusiveMaximum ? "ExclusiveMaximum" : "Maximum",
106
+ schema.maximum,
107
+ ),
108
+ );
109
+ if (schema.multipleOf !== undefined)
110
+ intersection.push(importer.tag("MultipleOf", schema.multipleOf));
111
+
112
+ return intersection.length === 1
113
+ ? intersection[0]
114
+ : ts.factory.createIntersectionTypeNode(intersection);
115
+ };
116
+
117
+ const writeString =
118
+ (importer: ImportProgrammer) =>
119
+ (schema: ISwaggerSchema.IString): ts.TypeNode => {
120
+ const intersection: ts.TypeNode[] = [TypeFactory.keyword("string")];
121
+ if (schema.default !== undefined)
122
+ intersection.push(importer.tag("Default", schema.default));
123
+ if (schema.minLength !== undefined)
124
+ intersection.push(importer.tag("MinLength", schema.minLength));
125
+ if (schema.maxLength !== undefined)
126
+ intersection.push(importer.tag("MaxLength", schema.maxLength));
127
+ if (schema.pattern !== undefined)
128
+ intersection.push(importer.tag("Pattern", schema.pattern));
129
+ if (
130
+ schema.format !== undefined &&
131
+ (FormatCheatSheet as Record<string, string>)[schema.format] !==
132
+ undefined
133
+ )
134
+ intersection.push(importer.tag("Format", schema.format));
135
+ return intersection.length === 1
136
+ ? intersection[0]
137
+ : ts.factory.createIntersectionTypeNode(intersection);
138
+ };
139
+
140
+ /* -----------------------------------------------------------
141
+ INSTANCES
142
+ ----------------------------------------------------------- */
143
+ const writeArray =
144
+ (importer: ImportProgrammer) =>
145
+ (components: ISwaggerComponents) =>
146
+ (schema: ISwaggerSchema.IArray): ts.TypeNode => {
147
+ const intersection: ts.TypeNode[] = [
148
+ ts.factory.createArrayTypeNode(
149
+ write(importer)(components)(schema.items),
150
+ ),
151
+ ];
152
+ if (schema.minItems !== undefined)
153
+ intersection.push(importer.tag("MinItems", schema.minItems));
154
+ if (schema.maxItems !== undefined)
155
+ intersection.push(importer.tag("MaxItems", schema.maxItems));
156
+ return intersection.length === 1
157
+ ? intersection[0]
158
+ : ts.factory.createIntersectionTypeNode(intersection);
159
+ };
160
+
161
+ const writeObject =
162
+ (importer: ImportProgrammer) =>
163
+ (components: ISwaggerComponents) =>
164
+ (schema: ISwaggerSchema.IObject): ts.TypeNode => {
165
+ const regular = () =>
166
+ ts.factory.createTypeLiteralNode(
167
+ Object.entries(schema.properties ?? []).map(([key, value]) =>
168
+ writeRegularProperty(importer)(components)(schema.required ?? [])(
169
+ key,
170
+ value,
171
+ ),
172
+ ),
173
+ );
174
+ const dynamic = () =>
175
+ ts.factory.createTypeLiteralNode([
176
+ writeDynamicProperty(importer)(components)(
177
+ schema.additionalProperties as ISwaggerSchema,
178
+ ),
179
+ ]);
180
+ return FilePrinter.description(
181
+ !!schema.properties?.length &&
182
+ typeof schema.additionalProperties === "object"
183
+ ? ts.factory.createIntersectionTypeNode([regular(), dynamic()])
184
+ : typeof schema.additionalProperties === "object"
185
+ ? dynamic()
186
+ : regular(),
187
+ writeComment(schema),
188
+ );
189
+ };
190
+
191
+ const writeRegularProperty =
192
+ (importer: ImportProgrammer) =>
193
+ (components: ISwaggerComponents) =>
194
+ (required: string[]) =>
195
+ (key: string, value: ISwaggerSchema) =>
196
+ FilePrinter.description(
197
+ ts.factory.createPropertySignature(
198
+ undefined,
199
+ Escaper.variable(key)
200
+ ? ts.factory.createIdentifier(key)
201
+ : ts.factory.createStringLiteral(key),
202
+ required.includes(key)
203
+ ? undefined
204
+ : ts.factory.createToken(ts.SyntaxKind.QuestionToken),
205
+ write(importer)(components)(value),
206
+ ),
207
+ writeComment(value),
208
+ );
209
+
210
+ const writeDynamicProperty =
211
+ (importer: ImportProgrammer) =>
212
+ (components: ISwaggerComponents) =>
213
+ (value: ISwaggerSchema) =>
214
+ FilePrinter.description(
215
+ ts.factory.createIndexSignature(
216
+ undefined,
217
+ [
218
+ ts.factory.createParameterDeclaration(
219
+ undefined,
220
+ undefined,
221
+ ts.factory.createIdentifier("key"),
222
+ undefined,
223
+ TypeFactory.keyword("string"),
224
+ ),
225
+ ],
226
+ write(importer)(components)(value),
227
+ ),
228
+ writeComment(value),
229
+ );
230
+
231
+ const writeReference =
232
+ (importer: ImportProgrammer) =>
233
+ (schema: ISwaggerSchema.IReference): ts.TypeReferenceNode =>
234
+ importer.dto(schema.$ref.split("/").at(-1)!);
235
+
236
+ /* -----------------------------------------------------------
237
+ UNIONS
238
+ ----------------------------------------------------------- */
239
+ const writeUnion =
240
+ (importer: ImportProgrammer) =>
241
+ (components: ISwaggerComponents) =>
242
+ (elements: ISwaggerSchema[]): ts.UnionTypeNode =>
243
+ ts.factory.createUnionTypeNode(elements.map(write(importer)(components)));
337
244
  }
338
-
339
- const FORMATS = new Set([
340
- "email",
341
- "uuid",
342
- "ipv4",
343
- "ipv6",
344
- "url",
345
- "date",
346
- "date-time",
347
- ]);
245
+ const createNode = (text: string) => ts.factory.createTypeReferenceNode(text);
246
+ const writeComment = (schema: ISwaggerSchema): string =>
247
+ [
248
+ ...(schema.description?.length ? [schema.description] : []),
249
+ ...(schema.description?.length &&
250
+ (schema.title !== undefined || schema.deprecated === true)
251
+ ? [""]
252
+ : []),
253
+ ...(schema.title !== undefined ? [`@title ${schema.title}`] : []),
254
+ ...(schema.deprecated === true ? [`@deprecated`] : []),
255
+ ].join("\n");
@@ -1,8 +1,8 @@
1
- import { IMigrateRoute } from "./IMigrateRoute";
2
-
3
- export interface IMigrateController {
4
- name: string;
5
- path: string;
6
- location: string;
7
- routes: IMigrateRoute[];
8
- }
1
+ import { IMigrateRoute } from "./IMigrateRoute";
2
+
3
+ export interface IMigrateController {
4
+ name: string;
5
+ path: string;
6
+ location: string;
7
+ routes: IMigrateRoute[];
8
+ }
@@ -1,8 +1,8 @@
1
- import { ISwaggerSchema } from "./ISwaggeSchema";
2
-
3
- export interface IMigrateDto {
4
- name: string;
5
- location: string;
6
- schema: ISwaggerSchema | null;
7
- children: IMigrateDto[];
8
- }
1
+ import { ISwaggerSchema } from "./ISwaggeSchema";
2
+
3
+ export interface IMigrateDto {
4
+ name: string;
5
+ location: string;
6
+ schema: ISwaggerSchema | null;
7
+ children: IMigrateDto[];
8
+ }
@@ -1,5 +1,5 @@
1
- export interface IMigrateFile {
2
- location: string;
3
- file: string;
4
- content: string;
5
- }
1
+ export interface IMigrateFile {
2
+ location: string;
3
+ file: string;
4
+ content: string;
5
+ }