@nestia/migrate 0.12.0 → 0.13.0-dev.20240411

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 (147) hide show
  1. package/lib/MigrateApplication.d.ts +3 -4
  2. package/lib/MigrateApplication.js +5160 -947
  3. package/lib/MigrateApplication.js.map +1 -1
  4. package/lib/analyzers/MigrateControllerAnalyzer.js +2 -1
  5. package/lib/analyzers/MigrateControllerAnalyzer.js.map +1 -1
  6. package/lib/analyzers/MigrateMethodAnalyzer.d.ts +2 -2
  7. package/lib/analyzers/MigrateMethodAnalyzer.js +60 -143
  8. package/lib/analyzers/MigrateMethodAnalyzer.js.map +1 -1
  9. package/lib/bundles/NEST_TEMPLATE.js +2 -2
  10. package/lib/bundles/NEST_TEMPLATE.js.map +1 -1
  11. package/lib/bundles/SDK_TEMPLATE.js +1 -1
  12. package/lib/bundles/SDK_TEMPLATE.js.map +1 -1
  13. package/lib/factories/TypeLiteralFactory.d.ts +4 -0
  14. package/lib/factories/TypeLiteralFactory.js +35 -0
  15. package/lib/factories/TypeLiteralFactory.js.map +1 -0
  16. package/lib/internal/MigrateCommander.js +2 -2
  17. package/lib/internal/MigrateCommander.js.map +1 -1
  18. package/lib/module.d.ts +0 -6
  19. package/lib/module.js +0 -6
  20. package/lib/module.js.map +1 -1
  21. package/lib/programmers/MigrateApiFileProgrammer.d.ts +2 -2
  22. package/lib/programmers/MigrateApiFileProgrammer.js.map +1 -1
  23. package/lib/programmers/MigrateApiFunctionProgrammer.d.ts +3 -3
  24. package/lib/programmers/MigrateApiFunctionProgrammer.js.map +1 -1
  25. package/lib/programmers/MigrateApiNamespaceProgrammer.d.ts +2 -2
  26. package/lib/programmers/MigrateApiNamespaceProgrammer.js.map +1 -1
  27. package/lib/programmers/MigrateApiProgrammer.js +2 -2
  28. package/lib/programmers/MigrateApiProgrammer.js.map +1 -1
  29. package/lib/programmers/MigrateApiSimulatationProgrammer.d.ts +3 -3
  30. package/lib/programmers/MigrateApiSimulatationProgrammer.js.map +1 -1
  31. package/lib/programmers/MigrateApiStartProgrammer.js +8 -8
  32. package/lib/programmers/MigrateApiStartProgrammer.js.map +1 -1
  33. package/lib/programmers/MigrateDtoProgrammer.d.ts +2 -2
  34. package/lib/programmers/MigrateDtoProgrammer.js.map +1 -1
  35. package/lib/programmers/MigrateE2eFileProgrammer.d.ts +3 -3
  36. package/lib/programmers/MigrateE2eFileProgrammer.js.map +1 -1
  37. package/lib/programmers/MigrateE2eProgrammer.js +1 -1
  38. package/lib/programmers/MigrateE2eProgrammer.js.map +1 -1
  39. package/lib/programmers/MigrateImportProgrammer.d.ts +1 -1
  40. package/lib/programmers/MigrateImportProgrammer.js +2 -4
  41. package/lib/programmers/MigrateImportProgrammer.js.map +1 -1
  42. package/lib/programmers/MigrateNestControllerProgrammer.d.ts +2 -2
  43. package/lib/programmers/MigrateNestControllerProgrammer.js.map +1 -1
  44. package/lib/programmers/MigrateNestMethodProgrammer.d.ts +2 -2
  45. package/lib/programmers/MigrateNestMethodProgrammer.js.map +1 -1
  46. package/lib/programmers/MigrateNestProgrammer.js +2 -2
  47. package/lib/programmers/MigrateNestProgrammer.js.map +1 -1
  48. package/lib/programmers/MigrateSchemaProgrammer.d.ts +2 -3
  49. package/lib/programmers/MigrateSchemaProgrammer.js +151 -28
  50. package/lib/programmers/MigrateSchemaProgrammer.js.map +1 -1
  51. package/lib/structures/IMigrateDto.d.ts +2 -2
  52. package/lib/structures/IMigrateProgram.d.ts +3 -4
  53. package/lib/structures/IMigrateRoute.d.ts +6 -6
  54. package/lib/utils/OpenApiTypeChecker.d.ts +15 -0
  55. package/lib/utils/OpenApiTypeChecker.js +28 -0
  56. package/lib/utils/OpenApiTypeChecker.js.map +1 -0
  57. package/package.json +4 -3
  58. package/src/MigrateApplication.ts +81 -86
  59. package/src/analyzers/MigrateControllerAnalyzer.ts +7 -5
  60. package/src/analyzers/MigrateMethodAnalyzer.ts +103 -179
  61. package/src/bundles/NEST_TEMPLATE.ts +2 -2
  62. package/src/bundles/SDK_TEMPLATE.ts +1 -1
  63. package/src/factories/TypeLiteralFactory.ts +57 -0
  64. package/src/internal/MigrateCommander.ts +4 -4
  65. package/src/module.ts +0 -6
  66. package/src/programmers/MigrateApiFileProgrammer.ts +2 -2
  67. package/src/programmers/MigrateApiFunctionProgrammer.ts +3 -3
  68. package/src/programmers/MigrateApiNamespaceProgrammer.ts +5 -5
  69. package/src/programmers/MigrateApiProgrammer.ts +4 -2
  70. package/src/programmers/MigrateApiSimulatationProgrammer.ts +4 -4
  71. package/src/programmers/MigrateApiStartProgrammer.ts +8 -8
  72. package/src/programmers/MigrateDtoProgrammer.ts +5 -6
  73. package/src/programmers/MigrateE2eFileProgrammer.ts +4 -4
  74. package/src/programmers/MigrateE2eProgrammer.ts +3 -3
  75. package/src/programmers/MigrateImportProgrammer.ts +117 -121
  76. package/src/programmers/MigrateNestControllerProgrammer.ts +2 -2
  77. package/src/programmers/MigrateNestMethodProgrammer.ts +6 -7
  78. package/src/programmers/MigrateNestProgrammer.ts +2 -2
  79. package/src/programmers/MigrateSchemaProgrammer.ts +355 -263
  80. package/src/structures/IMigrateDto.ts +2 -2
  81. package/src/structures/IMigrateProgram.ts +4 -4
  82. package/src/structures/IMigrateRoute.ts +6 -6
  83. package/src/utils/OpenApiTypeChecker.ts +73 -0
  84. package/lib/structures/ISwagger.d.ts +0 -18
  85. package/lib/structures/ISwagger.js +0 -3
  86. package/lib/structures/ISwagger.js.map +0 -1
  87. package/lib/structures/ISwaggerComponents.d.ts +0 -12
  88. package/lib/structures/ISwaggerComponents.js +0 -3
  89. package/lib/structures/ISwaggerComponents.js.map +0 -1
  90. package/lib/structures/ISwaggerInfo.d.ts +0 -71
  91. package/lib/structures/ISwaggerInfo.js +0 -3
  92. package/lib/structures/ISwaggerInfo.js.map +0 -1
  93. package/lib/structures/ISwaggerRoute.d.ts +0 -15
  94. package/lib/structures/ISwaggerRoute.js +0 -3
  95. package/lib/structures/ISwaggerRoute.js.map +0 -1
  96. package/lib/structures/ISwaggerRouteBodyContent.d.ts +0 -14
  97. package/lib/structures/ISwaggerRouteBodyContent.js +0 -3
  98. package/lib/structures/ISwaggerRouteBodyContent.js.map +0 -1
  99. package/lib/structures/ISwaggerRouteHeader.d.ts +0 -0
  100. package/lib/structures/ISwaggerRouteHeader.js +0 -2
  101. package/lib/structures/ISwaggerRouteHeader.js.map +0 -1
  102. package/lib/structures/ISwaggerRouteParameter.d.ts +0 -13
  103. package/lib/structures/ISwaggerRouteParameter.js +0 -3
  104. package/lib/structures/ISwaggerRouteParameter.js.map +0 -1
  105. package/lib/structures/ISwaggerRouteRequestBody.d.ts +0 -11
  106. package/lib/structures/ISwaggerRouteRequestBody.js +0 -3
  107. package/lib/structures/ISwaggerRouteRequestBody.js.map +0 -1
  108. package/lib/structures/ISwaggerRouteResponse.d.ts +0 -10
  109. package/lib/structures/ISwaggerRouteResponse.js +0 -3
  110. package/lib/structures/ISwaggerRouteResponse.js.map +0 -1
  111. package/lib/structures/ISwaggerSchema.d.ts +0 -75
  112. package/lib/structures/ISwaggerSchema.js +0 -3
  113. package/lib/structures/ISwaggerSchema.js.map +0 -1
  114. package/lib/structures/ISwaggerSecurityScheme.d.ts +0 -40
  115. package/lib/structures/ISwaggerSecurityScheme.js +0 -3
  116. package/lib/structures/ISwaggerSecurityScheme.js.map +0 -1
  117. package/lib/structures/ISwaggerV20.d.ts +0 -8
  118. package/lib/structures/ISwaggerV20.js +0 -3
  119. package/lib/structures/ISwaggerV20.js.map +0 -1
  120. package/lib/structures/ISwaggerV31.d.ts +0 -9
  121. package/lib/structures/ISwaggerV31.js +0 -3
  122. package/lib/structures/ISwaggerV31.js.map +0 -1
  123. package/lib/utils/OpenApiConverter.d.ts +0 -5
  124. package/lib/utils/OpenApiConverter.js +0 -1568
  125. package/lib/utils/OpenApiConverter.js.map +0 -1
  126. package/lib/utils/SwaggerComponentsExplorer.d.ts +0 -9
  127. package/lib/utils/SwaggerComponentsExplorer.js +0 -29
  128. package/lib/utils/SwaggerComponentsExplorer.js.map +0 -1
  129. package/lib/utils/SwaggerTypeChecker.d.ts +0 -16
  130. package/lib/utils/SwaggerTypeChecker.js +0 -34
  131. package/lib/utils/SwaggerTypeChecker.js.map +0 -1
  132. package/src/structures/ISwagger.ts +0 -23
  133. package/src/structures/ISwaggerComponents.ts +0 -13
  134. package/src/structures/ISwaggerInfo.ts +0 -80
  135. package/src/structures/ISwaggerRoute.ts +0 -20
  136. package/src/structures/ISwaggerRouteBodyContent.ts +0 -15
  137. package/src/structures/ISwaggerRouteHeader.ts +0 -0
  138. package/src/structures/ISwaggerRouteParameter.ts +0 -14
  139. package/src/structures/ISwaggerRouteRequestBody.ts +0 -12
  140. package/src/structures/ISwaggerRouteResponse.ts +0 -11
  141. package/src/structures/ISwaggerSchema.ts +0 -90
  142. package/src/structures/ISwaggerSecurityScheme.ts +0 -47
  143. package/src/structures/ISwaggerV20.ts +0 -10
  144. package/src/structures/ISwaggerV31.ts +0 -10
  145. package/src/utils/OpenApiConverter.ts +0 -19
  146. package/src/utils/SwaggerComponentsExplorer.ts +0 -43
  147. package/src/utils/SwaggerTypeChecker.ts +0 -67
@@ -1,263 +1,355 @@
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";
5
- import { Escaper } from "typia/lib/utils/Escaper";
6
-
7
- import { ISwaggerComponents } from "../structures/ISwaggerComponents";
8
- import { ISwaggerSchema } from "../structures/ISwaggerSchema";
9
- import { FilePrinter } from "../utils/FilePrinter";
10
- import { SwaggerTypeChecker } from "../utils/SwaggerTypeChecker";
11
- import { MigrateImportProgrammer } from "./MigrateImportProgrammer";
12
-
13
- export namespace MigrateSchemaProgrammer {
14
- /* -----------------------------------------------------------
15
- FACADE
16
- ----------------------------------------------------------- */
17
- export const write =
18
- (components: ISwaggerComponents) =>
19
- (importer: MigrateImportProgrammer) =>
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(components)(importer)(schema);
40
- else if (SwaggerTypeChecker.isObject(schema))
41
- return writeObject(components)(importer)(schema);
42
- else if (SwaggerTypeChecker.isReference(schema))
43
- return writeReference(importer)(schema);
44
- // NESTED UNION
45
- else if (SwaggerTypeChecker.isAnyOf(schema))
46
- return writeUnion(components)(importer)(schema.anyOf);
47
- else if (SwaggerTypeChecker.isOneOf(schema))
48
- return writeUnion(components)(importer)(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: MigrateImportProgrammer) =>
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: MigrateImportProgrammer) =>
79
- (schema: ISwaggerSchema.INumber): ts.TypeNode =>
80
- writeNumeric(() => [TypeFactory.keyword("number")])(importer)(schema);
81
-
82
- const writeNumeric =
83
- (factory: () => ts.TypeNode[]) =>
84
- (importer: MigrateImportProgrammer) =>
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: MigrateImportProgrammer) =>
119
- (schema: ISwaggerSchema.IString): ts.TypeNode => {
120
- if (schema.format === "binary")
121
- return ts.factory.createTypeReferenceNode("File");
122
-
123
- const intersection: ts.TypeNode[] = [TypeFactory.keyword("string")];
124
- if (schema.default !== undefined)
125
- intersection.push(importer.tag("Default", schema.default));
126
- if (schema.minLength !== undefined)
127
- intersection.push(importer.tag("MinLength", schema.minLength));
128
- if (schema.maxLength !== undefined)
129
- intersection.push(importer.tag("MaxLength", schema.maxLength));
130
- if (schema.pattern !== undefined)
131
- intersection.push(importer.tag("Pattern", schema.pattern));
132
- if (
133
- schema.format !== undefined &&
134
- (FormatCheatSheet as Record<string, string>)[schema.format] !==
135
- undefined
136
- )
137
- intersection.push(importer.tag("Format", schema.format));
138
- return intersection.length === 1
139
- ? intersection[0]
140
- : ts.factory.createIntersectionTypeNode(intersection);
141
- };
142
-
143
- /* -----------------------------------------------------------
144
- INSTANCES
145
- ----------------------------------------------------------- */
146
- const writeArray =
147
- (components: ISwaggerComponents) =>
148
- (importer: MigrateImportProgrammer) =>
149
- (schema: ISwaggerSchema.IArray): ts.TypeNode => {
150
- const intersection: ts.TypeNode[] = [
151
- ts.factory.createArrayTypeNode(
152
- write(components)(importer)(schema.items),
153
- ),
154
- ];
155
- if (schema.minItems !== undefined)
156
- intersection.push(importer.tag("MinItems", schema.minItems));
157
- if (schema.maxItems !== undefined)
158
- intersection.push(importer.tag("MaxItems", schema.maxItems));
159
- return intersection.length === 1
160
- ? intersection[0]
161
- : ts.factory.createIntersectionTypeNode(intersection);
162
- };
163
-
164
- const writeObject =
165
- (components: ISwaggerComponents) =>
166
- (importer: MigrateImportProgrammer) =>
167
- (schema: ISwaggerSchema.IObject): ts.TypeNode => {
168
- const regular = () =>
169
- ts.factory.createTypeLiteralNode(
170
- Object.entries(schema.properties ?? []).map(([key, value]) =>
171
- writeRegularProperty(components)(importer)(schema.required ?? [])(
172
- key,
173
- value,
174
- ),
175
- ),
176
- );
177
- const dynamic = () =>
178
- ts.factory.createTypeLiteralNode([
179
- writeDynamicProperty(components)(importer)(
180
- schema.additionalProperties as ISwaggerSchema,
181
- ),
182
- ]);
183
- return !!schema.properties?.length &&
184
- typeof schema.additionalProperties === "object"
185
- ? ts.factory.createIntersectionTypeNode([regular(), dynamic()])
186
- : typeof schema.additionalProperties === "object"
187
- ? dynamic()
188
- : regular();
189
- };
190
-
191
- const writeRegularProperty =
192
- (components: ISwaggerComponents) =>
193
- (importer: MigrateImportProgrammer) =>
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(components)(importer)(value),
206
- ),
207
- writeComment(value),
208
- );
209
-
210
- const writeDynamicProperty =
211
- (components: ISwaggerComponents) =>
212
- (importer: MigrateImportProgrammer) =>
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(components)(importer)(value),
227
- ),
228
- writeComment(value),
229
- );
230
-
231
- const writeReference =
232
- (importer: MigrateImportProgrammer) =>
233
- (
234
- schema: ISwaggerSchema.IReference,
235
- ): ts.TypeReferenceNode | ts.KeywordTypeNode => {
236
- if (schema.$ref.startsWith("#/components/schemas") === false)
237
- return TypeFactory.keyword("any");
238
- const name: string = schema.$ref.split("/").at(-1)!;
239
- return name === ""
240
- ? TypeFactory.keyword("any")
241
- : importer.dto(schema.$ref.split("/").at(-1)!);
242
- };
243
-
244
- /* -----------------------------------------------------------
245
- UNIONS
246
- ----------------------------------------------------------- */
247
- const writeUnion =
248
- (components: ISwaggerComponents) =>
249
- (importer: MigrateImportProgrammer) =>
250
- (elements: ISwaggerSchema[]): ts.UnionTypeNode =>
251
- ts.factory.createUnionTypeNode(elements.map(write(components)(importer)));
252
- }
253
- const createNode = (text: string) => ts.factory.createTypeReferenceNode(text);
254
- const writeComment = (schema: ISwaggerSchema): string =>
255
- [
256
- ...(schema.description?.length ? [schema.description] : []),
257
- ...(schema.description?.length &&
258
- (schema.title !== undefined || schema.deprecated === true)
259
- ? [""]
260
- : []),
261
- ...(schema.title !== undefined ? [`@title ${schema.title}`] : []),
262
- ...(schema.deprecated === true ? [`@deprecated`] : []),
263
- ].join("\n");
1
+ import { OpenApi } from "@samchon/openapi";
2
+ import ts from "typescript";
3
+ import typia from "typia";
4
+ import { TypeFactory } from "typia/lib/factories/TypeFactory";
5
+ import { FormatCheatSheet } from "typia/lib/tags/internal/FormatCheatSheet";
6
+ import { Escaper } from "typia/lib/utils/Escaper";
7
+
8
+ import { FilePrinter } from "../utils/FilePrinter";
9
+ import { OpenApiTypeChecker } from "../utils/OpenApiTypeChecker";
10
+ import { MigrateImportProgrammer } from "./MigrateImportProgrammer";
11
+
12
+ export namespace MigrateSchemaProgrammer {
13
+ /* -----------------------------------------------------------
14
+ FACADE
15
+ ----------------------------------------------------------- */
16
+ export const write =
17
+ (components: OpenApi.IComponents) =>
18
+ (importer: MigrateImportProgrammer) =>
19
+ (schema: OpenApi.IJsonSchema): ts.TypeNode => {
20
+ // CONSIDER ANY TYPE CASE
21
+ const union: ts.TypeNode[] = [];
22
+ if (OpenApiTypeChecker.isUnknown(schema))
23
+ return TypeFactory.keyword("any");
24
+
25
+ // ITERATION
26
+ const type: ts.TypeNode = (() => {
27
+ // ATOMIC
28
+ if (OpenApiTypeChecker.isConstant(schema))
29
+ return writeConstant(importer)(schema);
30
+ else if (OpenApiTypeChecker.isBoolean(schema))
31
+ return writeBoolean(importer)(schema);
32
+ else if (OpenApiTypeChecker.isInteger(schema))
33
+ return writeInteger(importer)(schema);
34
+ else if (OpenApiTypeChecker.isNumber(schema))
35
+ return writeNumber(importer)(schema);
36
+ else if (OpenApiTypeChecker.isString(schema))
37
+ return writeString(importer)(schema);
38
+ // INSTANCES
39
+ else if (OpenApiTypeChecker.isArray(schema))
40
+ return writeArray(components)(importer)(schema);
41
+ else if (OpenApiTypeChecker.isTuple(schema))
42
+ return writeTuple(components)(importer)(schema);
43
+ else if (OpenApiTypeChecker.isObject(schema))
44
+ return writeObject(components)(importer)(schema);
45
+ else if (OpenApiTypeChecker.isReference(schema))
46
+ return writeReference(importer)(schema);
47
+ // UNION
48
+ else if (OpenApiTypeChecker.isOneOf(schema))
49
+ return writeUnion(components)(importer)(schema.oneOf);
50
+ else if (OpenApiTypeChecker.isNull(schema)) return createNode("null");
51
+ else return TypeFactory.keyword("any");
52
+ })();
53
+ union.push(type);
54
+
55
+ // DETERMINE
56
+ if (union.length === 0) return TypeFactory.keyword("any");
57
+ else if (union.length === 1) return union[0];
58
+ return ts.factory.createUnionTypeNode(union);
59
+ };
60
+
61
+ /* -----------------------------------------------------------
62
+ ATOMICS
63
+ ----------------------------------------------------------- */
64
+ const writeConstant =
65
+ (importer: MigrateImportProgrammer) =>
66
+ (schema: OpenApi.IJsonSchema.IConstant): ts.TypeNode => {
67
+ const intersection: ts.TypeNode[] = [
68
+ ts.factory.createLiteralTypeNode(
69
+ typeof schema.const === "boolean"
70
+ ? schema.const === true
71
+ ? ts.factory.createTrue()
72
+ : ts.factory.createFalse()
73
+ : typeof schema.const === "number"
74
+ ? schema.const < 0
75
+ ? ts.factory.createPrefixUnaryExpression(
76
+ ts.SyntaxKind.MinusToken,
77
+ ts.factory.createNumericLiteral(-schema.const),
78
+ )
79
+ : ts.factory.createNumericLiteral(schema.const)
80
+ : ts.factory.createStringLiteral(schema.const),
81
+ ),
82
+ ];
83
+ writePlugin({
84
+ importer,
85
+ regular: typia.misc.literals<keyof OpenApi.IJsonSchema.IConstant>(),
86
+ intersection,
87
+ })(schema);
88
+ return intersection.length === 1
89
+ ? intersection[0]
90
+ : ts.factory.createIntersectionTypeNode(intersection);
91
+ };
92
+
93
+ const writeBoolean =
94
+ (importer: MigrateImportProgrammer) =>
95
+ (schema: OpenApi.IJsonSchema.IBoolean): ts.TypeNode => {
96
+ const intersection: ts.TypeNode[] = [TypeFactory.keyword("boolean")];
97
+ writePlugin({
98
+ importer,
99
+ regular: typia.misc.literals<keyof OpenApi.IJsonSchema.IBoolean>(),
100
+ intersection,
101
+ })(schema);
102
+ return intersection.length === 1
103
+ ? intersection[0]
104
+ : ts.factory.createIntersectionTypeNode(intersection);
105
+ };
106
+
107
+ const writeInteger =
108
+ (importer: MigrateImportProgrammer) =>
109
+ (schema: OpenApi.IJsonSchema.IInteger): ts.TypeNode =>
110
+ writeNumeric(() => [
111
+ TypeFactory.keyword("number"),
112
+ importer.tag("Type", "int32"),
113
+ ])(importer)(schema);
114
+
115
+ const writeNumber =
116
+ (importer: MigrateImportProgrammer) =>
117
+ (schema: OpenApi.IJsonSchema.INumber): ts.TypeNode =>
118
+ writeNumeric(() => [TypeFactory.keyword("number")])(importer)(schema);
119
+
120
+ const writeNumeric =
121
+ (factory: () => ts.TypeNode[]) =>
122
+ (importer: MigrateImportProgrammer) =>
123
+ (
124
+ schema: OpenApi.IJsonSchema.IInteger | OpenApi.IJsonSchema.INumber,
125
+ ): ts.TypeNode => {
126
+ const intersection: ts.TypeNode[] = factory();
127
+ if (schema.default !== undefined)
128
+ intersection.push(importer.tag("Default", schema.default));
129
+ if (schema.minimum !== undefined)
130
+ intersection.push(
131
+ importer.tag(
132
+ schema.exclusiveMinimum ? "ExclusiveMinimum" : "Minimum",
133
+ schema.minimum,
134
+ ),
135
+ );
136
+ if (schema.maximum !== undefined)
137
+ intersection.push(
138
+ importer.tag(
139
+ schema.exclusiveMaximum ? "ExclusiveMaximum" : "Maximum",
140
+ schema.maximum,
141
+ ),
142
+ );
143
+ if (schema.multipleOf !== undefined)
144
+ intersection.push(importer.tag("MultipleOf", schema.multipleOf));
145
+ writePlugin({
146
+ importer,
147
+ regular: typia.misc.literals<keyof OpenApi.IJsonSchema.INumber>(),
148
+ intersection,
149
+ })(schema);
150
+ return intersection.length === 1
151
+ ? intersection[0]
152
+ : ts.factory.createIntersectionTypeNode(intersection);
153
+ };
154
+
155
+ const writeString =
156
+ (importer: MigrateImportProgrammer) =>
157
+ (schema: OpenApi.IJsonSchema.IString): ts.TypeNode => {
158
+ if (schema.format === "binary")
159
+ return ts.factory.createTypeReferenceNode("File");
160
+
161
+ const intersection: ts.TypeNode[] = [TypeFactory.keyword("string")];
162
+ if (schema.default !== undefined)
163
+ intersection.push(importer.tag("Default", schema.default));
164
+ if (schema.minLength !== undefined)
165
+ intersection.push(importer.tag("MinLength", schema.minLength));
166
+ if (schema.maxLength !== undefined)
167
+ intersection.push(importer.tag("MaxLength", schema.maxLength));
168
+ if (schema.pattern !== undefined)
169
+ intersection.push(importer.tag("Pattern", schema.pattern));
170
+ if (
171
+ schema.format !== undefined &&
172
+ (FormatCheatSheet as Record<string, string>)[schema.format] !==
173
+ undefined
174
+ )
175
+ intersection.push(importer.tag("Format", schema.format));
176
+ if (schema.contentMediaType !== undefined)
177
+ intersection.push(
178
+ importer.tag("ContentMediaType", schema.contentMediaType),
179
+ );
180
+ writePlugin({
181
+ importer,
182
+ regular: typia.misc.literals<keyof OpenApi.IJsonSchema.IString>(),
183
+ intersection,
184
+ })(schema);
185
+ return intersection.length === 1
186
+ ? intersection[0]
187
+ : ts.factory.createIntersectionTypeNode(intersection);
188
+ };
189
+
190
+ /* -----------------------------------------------------------
191
+ INSTANCES
192
+ ----------------------------------------------------------- */
193
+ const writeArray =
194
+ (components: OpenApi.IComponents) =>
195
+ (importer: MigrateImportProgrammer) =>
196
+ (schema: OpenApi.IJsonSchema.IArray): ts.TypeNode => {
197
+ const intersection: ts.TypeNode[] = [
198
+ ts.factory.createArrayTypeNode(
199
+ write(components)(importer)(schema.items),
200
+ ),
201
+ ];
202
+ if (schema.minItems !== undefined)
203
+ intersection.push(importer.tag("MinItems", schema.minItems));
204
+ if (schema.maxItems !== undefined)
205
+ intersection.push(importer.tag("MaxItems", schema.maxItems));
206
+ writePlugin({
207
+ importer,
208
+ regular: typia.misc.literals<keyof OpenApi.IJsonSchema.IArray>(),
209
+ intersection,
210
+ })(schema);
211
+ return intersection.length === 1
212
+ ? intersection[0]
213
+ : ts.factory.createIntersectionTypeNode(intersection);
214
+ };
215
+
216
+ const writeTuple =
217
+ (components: OpenApi.IComponents) =>
218
+ (importer: MigrateImportProgrammer) =>
219
+ (schema: OpenApi.IJsonSchema.ITuple): ts.TypeNode => {
220
+ const tuple: ts.TypeNode = ts.factory.createTupleTypeNode([
221
+ ...schema.prefixItems.map(write(components)(importer)),
222
+ ...(typeof schema.additionalItems === "object" &&
223
+ schema.additionalItems !== null
224
+ ? [
225
+ ts.factory.createRestTypeNode(
226
+ write(components)(importer)(schema.additionalItems),
227
+ ),
228
+ ]
229
+ : []),
230
+ ]);
231
+ const intersection: ts.TypeNode[] = [tuple];
232
+ writePlugin({
233
+ importer,
234
+ regular: typia.misc.literals<keyof OpenApi.IJsonSchema.ITuple>(),
235
+ intersection,
236
+ })(schema);
237
+ return intersection.length === 1
238
+ ? intersection[0]
239
+ : ts.factory.createIntersectionTypeNode(intersection);
240
+ };
241
+
242
+ const writeObject =
243
+ (components: OpenApi.IComponents) =>
244
+ (importer: MigrateImportProgrammer) =>
245
+ (schema: OpenApi.IJsonSchema.IObject): ts.TypeNode => {
246
+ const regular = () =>
247
+ ts.factory.createTypeLiteralNode(
248
+ Object.entries(schema.properties ?? []).map(([key, value]) =>
249
+ writeRegularProperty(components)(importer)(schema.required ?? [])(
250
+ key,
251
+ value,
252
+ ),
253
+ ),
254
+ );
255
+ const dynamic = () =>
256
+ ts.factory.createTypeLiteralNode([
257
+ writeDynamicProperty(components)(importer)(
258
+ schema.additionalProperties as OpenApi.IJsonSchema,
259
+ ),
260
+ ]);
261
+ return !!schema.properties?.length &&
262
+ typeof schema.additionalProperties === "object"
263
+ ? ts.factory.createIntersectionTypeNode([regular(), dynamic()])
264
+ : typeof schema.additionalProperties === "object"
265
+ ? dynamic()
266
+ : regular();
267
+ };
268
+
269
+ const writeRegularProperty =
270
+ (components: OpenApi.IComponents) =>
271
+ (importer: MigrateImportProgrammer) =>
272
+ (required: string[]) =>
273
+ (key: string, value: OpenApi.IJsonSchema) =>
274
+ FilePrinter.description(
275
+ ts.factory.createPropertySignature(
276
+ undefined,
277
+ Escaper.variable(key)
278
+ ? ts.factory.createIdentifier(key)
279
+ : ts.factory.createStringLiteral(key),
280
+ required.includes(key)
281
+ ? undefined
282
+ : ts.factory.createToken(ts.SyntaxKind.QuestionToken),
283
+ write(components)(importer)(value),
284
+ ),
285
+ writeComment(value),
286
+ );
287
+
288
+ const writeDynamicProperty =
289
+ (components: OpenApi.IComponents) =>
290
+ (importer: MigrateImportProgrammer) =>
291
+ (value: OpenApi.IJsonSchema) =>
292
+ FilePrinter.description(
293
+ ts.factory.createIndexSignature(
294
+ undefined,
295
+ [
296
+ ts.factory.createParameterDeclaration(
297
+ undefined,
298
+ undefined,
299
+ ts.factory.createIdentifier("key"),
300
+ undefined,
301
+ TypeFactory.keyword("string"),
302
+ ),
303
+ ],
304
+ write(components)(importer)(value),
305
+ ),
306
+ writeComment(value),
307
+ );
308
+
309
+ const writeReference =
310
+ (importer: MigrateImportProgrammer) =>
311
+ (
312
+ schema: OpenApi.IJsonSchema.IReference,
313
+ ): ts.TypeReferenceNode | ts.KeywordTypeNode => {
314
+ if (schema.$ref.startsWith("#/components/schemas") === false)
315
+ return TypeFactory.keyword("any");
316
+ const name: string = schema.$ref.split("/").at(-1)!;
317
+ return name === ""
318
+ ? TypeFactory.keyword("any")
319
+ : importer.dto(schema.$ref.split("/").at(-1)!);
320
+ };
321
+
322
+ /* -----------------------------------------------------------
323
+ UNIONS
324
+ ----------------------------------------------------------- */
325
+ const writeUnion =
326
+ (components: OpenApi.IComponents) =>
327
+ (importer: MigrateImportProgrammer) =>
328
+ (elements: OpenApi.IJsonSchema[]): ts.UnionTypeNode =>
329
+ ts.factory.createUnionTypeNode(elements.map(write(components)(importer)));
330
+ }
331
+ const createNode = (text: string) => ts.factory.createTypeReferenceNode(text);
332
+ const writeComment = (schema: OpenApi.IJsonSchema): string =>
333
+ [
334
+ ...(schema.description?.length ? [schema.description] : []),
335
+ ...(schema.description?.length &&
336
+ (schema.title !== undefined || schema.deprecated === true)
337
+ ? [""]
338
+ : []),
339
+ ...(schema.title !== undefined ? [`@title ${schema.title}`] : []),
340
+ ...(schema.deprecated === true ? [`@deprecated`] : []),
341
+ ].join("\n");
342
+ const writePlugin =
343
+ (props: {
344
+ importer: MigrateImportProgrammer;
345
+ regular: string[];
346
+ intersection: ts.TypeNode[];
347
+ }) =>
348
+ (schema: any) => {
349
+ const extra: any = {};
350
+ for (const [key, value] of Object.entries(schema))
351
+ if (value !== undefined && false === props.regular.includes(key))
352
+ extra[key] = value;
353
+ if (Object.keys(extra).length !== 0)
354
+ props.intersection.push(props.importer.tag("JsonSchemaPlugin", extra));
355
+ };
@@ -1,8 +1,8 @@
1
- import { ISwaggerSchema } from "./ISwaggerSchema";
1
+ import { OpenApi } from "@samchon/openapi";
2
2
 
3
3
  export interface IMigrateDto {
4
4
  name: string;
5
5
  location: string;
6
- schema: ISwaggerSchema | null;
6
+ schema: OpenApi.IJsonSchema | null;
7
7
  children: IMigrateDto[];
8
8
  }