@nestia/sdk 3.0.0-dev.20231209 → 3.0.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 (168) hide show
  1. package/README.md +12 -9
  2. package/assets/config/nestia.config.ts +82 -79
  3. package/lib/INestiaConfig.d.ts +28 -6
  4. package/lib/NestiaSdkApplication.js +12 -10
  5. package/lib/NestiaSdkApplication.js.map +1 -1
  6. package/lib/analyses/ConfigAnalyzer.js +1 -1
  7. package/lib/analyses/ConfigAnalyzer.js.map +1 -1
  8. package/lib/analyses/ControllerAnalyzer.js +30 -15
  9. package/lib/analyses/ControllerAnalyzer.js.map +1 -1
  10. package/lib/analyses/ExceptionAnalyzer.js +35 -6
  11. package/lib/analyses/ExceptionAnalyzer.js.map +1 -1
  12. package/lib/analyses/ImportAnalyzer.d.ts +1 -2
  13. package/lib/analyses/ImportAnalyzer.js +2 -2
  14. package/lib/analyses/ImportAnalyzer.js.map +1 -1
  15. package/lib/analyses/PathAnalyzer.d.ts +2 -4
  16. package/lib/analyses/PathAnalyzer.js +27 -11
  17. package/lib/analyses/PathAnalyzer.js.map +1 -1
  18. package/lib/analyses/ReflectAnalyzer.js +34 -22
  19. package/lib/analyses/ReflectAnalyzer.js.map +1 -1
  20. package/lib/analyses/SecurityAnalyzer.js +13 -8
  21. package/lib/analyses/SecurityAnalyzer.js.map +1 -1
  22. package/lib/executable/internal/NestiaConfigLoader.js +300 -220
  23. package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
  24. package/lib/executable/sdk.js +11 -11
  25. package/lib/generates/CloneGenerator.d.ts +6 -0
  26. package/lib/generates/CloneGenerator.js +62 -0
  27. package/lib/generates/CloneGenerator.js.map +1 -0
  28. package/lib/generates/E2eGenerator.d.ts +2 -1
  29. package/lib/generates/E2eGenerator.js +2 -2
  30. package/lib/generates/E2eGenerator.js.map +1 -1
  31. package/lib/generates/SdkGenerator.js +3 -11
  32. package/lib/generates/SdkGenerator.js.map +1 -1
  33. package/lib/generates/SwaggerGenerator.d.ts +2 -0
  34. package/lib/generates/SwaggerGenerator.js +119 -62
  35. package/lib/generates/SwaggerGenerator.js.map +1 -1
  36. package/lib/generates/internal/E2eFileProgrammer.d.ts +2 -1
  37. package/lib/generates/internal/E2eFileProgrammer.js +49 -53
  38. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  39. package/lib/generates/internal/FilePrinter.d.ts +10 -0
  40. package/lib/generates/internal/FilePrinter.js +46 -0
  41. package/lib/generates/internal/FilePrinter.js.map +1 -0
  42. package/lib/{utils → generates/internal}/ImportDictionary.d.ts +2 -1
  43. package/lib/{utils → generates/internal}/ImportDictionary.js +20 -14
  44. package/lib/generates/internal/ImportDictionary.js.map +1 -0
  45. package/lib/generates/internal/SdkAliasCollection.d.ts +12 -0
  46. package/lib/generates/internal/SdkAliasCollection.js +97 -0
  47. package/lib/generates/internal/SdkAliasCollection.js.map +1 -0
  48. package/lib/generates/internal/SdkCloneProgrammer.d.ts +12 -0
  49. package/lib/generates/internal/SdkCloneProgrammer.js +99 -0
  50. package/lib/generates/internal/SdkCloneProgrammer.js.map +1 -0
  51. package/lib/generates/internal/SdkFileProgrammer.d.ts +2 -1
  52. package/lib/generates/internal/SdkFileProgrammer.js +27 -28
  53. package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
  54. package/lib/generates/internal/SdkFunctionProgrammer.d.ts +7 -2
  55. package/lib/generates/internal/SdkFunctionProgrammer.js +115 -322
  56. package/lib/generates/internal/SdkFunctionProgrammer.js.map +1 -1
  57. package/lib/generates/internal/SdkImportWizard.d.ts +1 -1
  58. package/lib/generates/internal/SdkNamespaceProgrammer.d.ts +11 -0
  59. package/lib/generates/internal/SdkNamespaceProgrammer.js +180 -0
  60. package/lib/generates/internal/SdkNamespaceProgrammer.js.map +1 -0
  61. package/lib/generates/internal/SdkRouteProgrammer.d.ts +7 -0
  62. package/lib/generates/internal/SdkRouteProgrammer.js +55 -0
  63. package/lib/generates/internal/SdkRouteProgrammer.js.map +1 -0
  64. package/lib/generates/internal/SdkSimulationProgrammer.d.ts +8 -2
  65. package/lib/generates/internal/SdkSimulationProgrammer.js +103 -89
  66. package/lib/generates/internal/SdkSimulationProgrammer.js.map +1 -1
  67. package/lib/generates/internal/SdkTypeProgrammer.d.ts +9 -0
  68. package/lib/generates/internal/SdkTypeProgrammer.js +228 -0
  69. package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -0
  70. package/lib/generates/internal/SwaggerSchemaGenerator.d.ts +4 -4
  71. package/lib/generates/internal/SwaggerSchemaGenerator.js +30 -28
  72. package/lib/generates/internal/SwaggerSchemaGenerator.js.map +1 -1
  73. package/lib/structures/IController.d.ts +4 -2
  74. package/lib/structures/IRoute.d.ts +5 -4
  75. package/lib/structures/ISwaggerLazyProperty.d.ts +2 -2
  76. package/lib/structures/ISwaggerLazySchema.d.ts +2 -2
  77. package/lib/structures/ParamCategory.d.ts +1 -1
  78. package/lib/structures/TypeEntry.js +2 -2
  79. package/lib/structures/TypeEntry.js.map +1 -1
  80. package/lib/utils/StringUtil.d.ts +3 -0
  81. package/lib/utils/StringUtil.js +8 -0
  82. package/lib/utils/StringUtil.js.map +1 -0
  83. package/package.json +12 -16
  84. package/src/INestiaConfig.ts +30 -6
  85. package/src/NestiaSdkApplication.ts +255 -253
  86. package/src/analyses/AccessorAnalyzer.ts +60 -60
  87. package/src/analyses/ConfigAnalyzer.ts +147 -147
  88. package/src/analyses/ControllerAnalyzer.ts +42 -19
  89. package/src/analyses/ExceptionAnalyzer.ts +148 -115
  90. package/src/analyses/GenericAnalyzer.ts +51 -51
  91. package/src/analyses/ImportAnalyzer.ts +1 -2
  92. package/src/analyses/PathAnalyzer.ts +110 -98
  93. package/src/analyses/ReflectAnalyzer.ts +39 -35
  94. package/src/analyses/SecurityAnalyzer.ts +24 -20
  95. package/src/executable/internal/CommandParser.ts +15 -15
  96. package/src/executable/internal/NestiaConfigLoader.ts +67 -67
  97. package/src/executable/internal/NestiaSdkCommand.ts +60 -60
  98. package/src/executable/sdk.ts +73 -73
  99. package/src/generates/CloneGenerator.ts +62 -0
  100. package/src/generates/E2eGenerator.ts +66 -64
  101. package/src/generates/SdkGenerator.ts +84 -96
  102. package/src/generates/SwaggerGenerator.ts +145 -53
  103. package/src/generates/internal/E2eFileProgrammer.ts +182 -123
  104. package/src/generates/internal/FilePrinter.ts +53 -0
  105. package/src/{utils → generates/internal}/ImportDictionary.ts +35 -13
  106. package/src/generates/internal/SdkAliasCollection.ts +152 -0
  107. package/src/generates/internal/SdkCloneProgrammer.ts +155 -0
  108. package/src/generates/internal/SdkDistributionComposer.ts +91 -91
  109. package/src/generates/internal/SdkFileProgrammer.ts +115 -106
  110. package/src/generates/internal/SdkFunctionProgrammer.ts +298 -518
  111. package/src/generates/internal/SdkImportWizard.ts +55 -55
  112. package/src/generates/internal/SdkNamespaceProgrammer.ts +510 -0
  113. package/src/generates/internal/SdkRouteDirectory.ts +17 -17
  114. package/src/generates/internal/SdkRouteProgrammer.ts +83 -0
  115. package/src/generates/internal/SdkSimulationProgrammer.ts +365 -133
  116. package/src/generates/internal/SdkTypeProgrammer.ts +386 -0
  117. package/src/generates/internal/SwaggerSchemaGenerator.ts +437 -427
  118. package/src/generates/internal/SwaggerSchemaValidator.ts +198 -198
  119. package/src/index.ts +4 -4
  120. package/src/module.ts +2 -2
  121. package/src/structures/IController.ts +94 -95
  122. package/src/structures/IErrorReport.ts +6 -6
  123. package/src/structures/INestiaProject.ts +13 -13
  124. package/src/structures/INormalizedInput.ts +20 -20
  125. package/src/structures/IRoute.ts +53 -53
  126. package/src/structures/ISwaggerLazyProperty.ts +2 -2
  127. package/src/structures/ISwaggerLazySchema.ts +2 -2
  128. package/src/structures/ITypeTuple.ts +6 -6
  129. package/src/structures/MethodType.ts +5 -5
  130. package/src/structures/ParamCategory.ts +1 -1
  131. package/src/structures/TypeEntry.ts +1 -1
  132. package/src/utils/ArrayUtil.ts +26 -26
  133. package/src/utils/FileRetriever.ts +22 -22
  134. package/src/utils/MapUtil.ts +14 -14
  135. package/src/utils/PathUtil.ts +10 -10
  136. package/src/utils/SourceFinder.ts +66 -66
  137. package/src/utils/StringUtil.ts +6 -0
  138. package/src/utils/StripEnums.ts +5 -5
  139. package/assets/bundle/api/utils/NestiaSimulator.ts +0 -70
  140. package/lib/generates/internal/SdkDtoGenerator.d.ts +0 -9
  141. package/lib/generates/internal/SdkDtoGenerator.js +0 -294
  142. package/lib/generates/internal/SdkDtoGenerator.js.map +0 -1
  143. package/lib/generates/internal/SdkTypeDefiner.d.ts +0 -11
  144. package/lib/generates/internal/SdkTypeDefiner.js +0 -82
  145. package/lib/generates/internal/SdkTypeDefiner.js.map +0 -1
  146. package/lib/structures/ISwagger.d.ts +0 -72
  147. package/lib/structures/ISwagger.js +0 -3
  148. package/lib/structures/ISwagger.js.map +0 -1
  149. package/lib/structures/ISwaggerComponents.d.ts +0 -26
  150. package/lib/structures/ISwaggerComponents.js +0 -3
  151. package/lib/structures/ISwaggerComponents.js.map +0 -1
  152. package/lib/structures/ISwaggerInfo.d.ts +0 -71
  153. package/lib/structures/ISwaggerInfo.js +0 -3
  154. package/lib/structures/ISwaggerInfo.js.map +0 -1
  155. package/lib/structures/ISwaggerRoute.d.ts +0 -47
  156. package/lib/structures/ISwaggerRoute.js +0 -3
  157. package/lib/structures/ISwaggerRoute.js.map +0 -1
  158. package/lib/structures/ISwaggerSecurityScheme.d.ts +0 -56
  159. package/lib/structures/ISwaggerSecurityScheme.js +0 -3
  160. package/lib/structures/ISwaggerSecurityScheme.js.map +0 -1
  161. package/lib/utils/ImportDictionary.js.map +0 -1
  162. package/src/generates/internal/SdkDtoGenerator.ts +0 -424
  163. package/src/generates/internal/SdkTypeDefiner.ts +0 -119
  164. package/src/structures/ISwagger.ts +0 -91
  165. package/src/structures/ISwaggerComponents.ts +0 -29
  166. package/src/structures/ISwaggerInfo.ts +0 -80
  167. package/src/structures/ISwaggerRoute.ts +0 -51
  168. package/src/structures/ISwaggerSecurityScheme.ts +0 -65
@@ -0,0 +1,386 @@
1
+ import ts from "typescript";
2
+ import { IJsDocTagInfo } from "typia";
3
+ import { ExpressionFactory } from "typia/lib/factories/ExpressionFactory";
4
+ import { TypeFactory } from "typia/lib/factories/TypeFactory";
5
+ import { IMetadataTypeTag } from "typia/lib/schemas/metadata/IMetadataTypeTag";
6
+ import { Metadata } from "typia/lib/schemas/metadata/Metadata";
7
+ import { MetadataAlias } from "typia/lib/schemas/metadata/MetadataAlias";
8
+ import { MetadataArray } from "typia/lib/schemas/metadata/MetadataArray";
9
+ import { MetadataAtomic } from "typia/lib/schemas/metadata/MetadataAtomic";
10
+ import { MetadataEscaped } from "typia/lib/schemas/metadata/MetadataEscaped";
11
+ import { MetadataObject } from "typia/lib/schemas/metadata/MetadataObject";
12
+ import { MetadataProperty } from "typia/lib/schemas/metadata/MetadataProperty";
13
+ import { MetadataTuple } from "typia/lib/schemas/metadata/MetadataTuple";
14
+ import { Escaper } from "typia/lib/utils/Escaper";
15
+
16
+ import { INestiaConfig } from "../../INestiaConfig";
17
+ import { FilePrinter } from "./FilePrinter";
18
+ import { ImportDictionary } from "./ImportDictionary";
19
+ import { MetadataConstantValue } from "typia/lib/schemas/metadata/MetadataConstantValue";
20
+
21
+ export namespace SdkTypeProgrammer {
22
+ /* -----------------------------------------------------------
23
+ FACADE
24
+ ----------------------------------------------------------- */
25
+ export const write =
26
+ (config: INestiaConfig) =>
27
+ (importer: ImportDictionary) =>
28
+ (meta: Metadata, parentEscaped: boolean = false): ts.TypeNode => {
29
+ const union: ts.TypeNode[] = [];
30
+
31
+ // COALESCES
32
+ if (meta.any) union.push(TypeFactory.keyword("any"));
33
+ if (meta.nullable) union.push(writeNode("null"));
34
+ if (meta.isRequired() === false) union.push(writeNode("undefined"));
35
+ if (parentEscaped === false && meta.escaped)
36
+ union.push(write_escaped(config)(importer)(meta.escaped));
37
+
38
+ // ATOMIC TYPES
39
+ for (const c of meta.constants)
40
+ for (const value of c.values) union.push(write_constant(value));
41
+ for (const tpl of meta.templates)
42
+ union.push(write_template(config)(importer)(tpl));
43
+ for (const atom of meta.atomics) union.push(write_atomic(importer)(atom));
44
+
45
+ // OBJECT TYPES
46
+ for (const tuple of meta.tuples)
47
+ union.push(write_tuple(config)(importer)(tuple));
48
+ for (const array of meta.arrays)
49
+ union.push(write_array(config)(importer)(array));
50
+ for (const object of meta.objects)
51
+ if (
52
+ object.name === "object" ||
53
+ object.name === "__type" ||
54
+ object.name.startsWith("__type.") ||
55
+ object.name === "__object" ||
56
+ object.name.startsWith("__object.")
57
+ )
58
+ union.push(write_object(config)(importer)(object));
59
+ else union.push(write_alias(config)(importer)(object));
60
+ for (const alias of meta.aliases)
61
+ union.push(write_alias(config)(importer)(alias));
62
+ for (const native of meta.natives)
63
+ if (native === "Blob" || native === "File")
64
+ union.push(write_native(native));
65
+
66
+ return union.length === 1
67
+ ? union[0]
68
+ : ts.factory.createUnionTypeNode(union);
69
+ };
70
+
71
+ export const write_object =
72
+ (config: INestiaConfig) =>
73
+ (importer: ImportDictionary) =>
74
+ (object: MetadataObject): ts.TypeNode => {
75
+ const regular = object.properties.filter((p) => p.key.isSoleLiteral());
76
+ const dynamic = object.properties.filter((p) => !p.key.isSoleLiteral());
77
+ return FilePrinter.description(
78
+ regular.length && dynamic.length
79
+ ? ts.factory.createIntersectionTypeNode([
80
+ write_regular_property(config)(importer)(regular),
81
+ ...dynamic.map(write_dynamic_property(config)(importer)),
82
+ ])
83
+ : dynamic.length
84
+ ? ts.factory.createIntersectionTypeNode(
85
+ dynamic.map(write_dynamic_property(config)(importer)),
86
+ )
87
+ : write_regular_property(config)(importer)(regular),
88
+ writeComment([])(object.description ?? null, object.jsDocTags),
89
+ );
90
+ };
91
+
92
+ const write_escaped =
93
+ (config: INestiaConfig) =>
94
+ (importer: ImportDictionary) =>
95
+ (meta: MetadataEscaped): ts.TypeNode => {
96
+ if (
97
+ meta.original.size() === 1 &&
98
+ meta.original.natives.length === 1 &&
99
+ meta.original.natives[0] === "Date"
100
+ )
101
+ return ts.factory.createIntersectionTypeNode([
102
+ TypeFactory.keyword("string"),
103
+ writeTag(importer)({
104
+ name: "Format",
105
+ value: "date-time",
106
+ } as IMetadataTypeTag),
107
+ ]);
108
+ return write(config)(importer)(meta.returns, true);
109
+ };
110
+
111
+ /* -----------------------------------------------------------
112
+ ATOMICS
113
+ ----------------------------------------------------------- */
114
+ const write_constant = (value: MetadataConstantValue) => {
115
+ if (typeof value.value === "boolean")
116
+ return ts.factory.createLiteralTypeNode(
117
+ value ? ts.factory.createTrue() : ts.factory.createFalse(),
118
+ );
119
+ else if (typeof value.value === "bigint")
120
+ return ts.factory.createLiteralTypeNode(
121
+ value.value < BigInt(0)
122
+ ? ts.factory.createPrefixUnaryExpression(
123
+ ts.SyntaxKind.MinusToken,
124
+ ts.factory.createBigIntLiteral((-value).toString()),
125
+ )
126
+ : ts.factory.createBigIntLiteral(value.toString()),
127
+ );
128
+ else if (typeof value === "number")
129
+ return ts.factory.createLiteralTypeNode(ExpressionFactory.number(value));
130
+ return ts.factory.createLiteralTypeNode(
131
+ ts.factory.createStringLiteral(value.value as string),
132
+ );
133
+ };
134
+
135
+ const write_template =
136
+ (config: INestiaConfig) =>
137
+ (importer: ImportDictionary) =>
138
+ (meta: Metadata[]): ts.TypeNode => {
139
+ const head: boolean = meta[0].isSoleLiteral();
140
+ const spans: [ts.TypeNode | null, string | null][] = [];
141
+ for (const elem of meta.slice(head ? 1 : 0)) {
142
+ const last =
143
+ spans.at(-1) ??
144
+ (() => {
145
+ const tuple = [null!, null!] as [ts.TypeNode | null, string | null];
146
+ spans.push(tuple);
147
+ return tuple;
148
+ })();
149
+ if (elem.isSoleLiteral())
150
+ if (last[1] === null) last[1] = String(elem.constants[0].values[0].value);
151
+ else
152
+ spans.push([
153
+ ts.factory.createLiteralTypeNode(
154
+ ts.factory.createStringLiteral(
155
+ String(elem.constants[0].values[0].value),
156
+ ),
157
+ ),
158
+ null,
159
+ ]);
160
+ else if (last[0] === null) last[0] = write(config)(importer)(elem);
161
+ else spans.push([write(config)(importer)(elem), null]);
162
+ }
163
+ return ts.factory.createTemplateLiteralType(
164
+ ts.factory.createTemplateHead(
165
+ head ? (meta[0].constants[0].values[0].value as string) : "",
166
+ ),
167
+ spans
168
+ .filter(([node]) => node !== null)
169
+ .map(([node, str], i, array) =>
170
+ ts.factory.createTemplateLiteralTypeSpan(
171
+ node!,
172
+ (i !== array.length - 1
173
+ ? ts.factory.createTemplateMiddle
174
+ : ts.factory.createTemplateTail)(str ?? ""),
175
+ ),
176
+ ),
177
+ );
178
+ };
179
+
180
+ const write_atomic =
181
+ (importer: ImportDictionary) =>
182
+ (meta: MetadataAtomic): ts.TypeNode =>
183
+ write_type_tag_matrix(importer)(
184
+ ts.factory.createKeywordTypeNode(
185
+ meta.type === "boolean"
186
+ ? ts.SyntaxKind.BooleanKeyword
187
+ : meta.type === "bigint"
188
+ ? ts.SyntaxKind.BigIntKeyword
189
+ : meta.type === "number"
190
+ ? ts.SyntaxKind.NumberKeyword
191
+ : ts.SyntaxKind.StringKeyword,
192
+ ),
193
+ meta.tags,
194
+ );
195
+
196
+ /* -----------------------------------------------------------
197
+ INSTANCES
198
+ ----------------------------------------------------------- */
199
+ const write_array =
200
+ (config: INestiaConfig) =>
201
+ (importer: ImportDictionary) =>
202
+ (meta: MetadataArray): ts.TypeNode =>
203
+ write_type_tag_matrix(importer)(
204
+ ts.factory.createArrayTypeNode(
205
+ write(config)(importer)(meta.type.value),
206
+ ),
207
+ meta.tags,
208
+ );
209
+
210
+ const write_tuple =
211
+ (config: INestiaConfig) =>
212
+ (importer: ImportDictionary) =>
213
+ (meta: MetadataTuple): ts.TypeNode =>
214
+ ts.factory.createTupleTypeNode(
215
+ meta.type.elements.map((elem) =>
216
+ elem.rest
217
+ ? ts.factory.createRestTypeNode(
218
+ ts.factory.createArrayTypeNode(
219
+ write(config)(importer)(elem.rest),
220
+ ),
221
+ )
222
+ : elem.optional
223
+ ? ts.factory.createOptionalTypeNode(write(config)(importer)(elem))
224
+ : write(config)(importer)(elem),
225
+ ),
226
+ );
227
+
228
+ const write_regular_property =
229
+ (config: INestiaConfig) =>
230
+ (importer: ImportDictionary) =>
231
+ (properties: MetadataProperty[]): ts.TypeLiteralNode =>
232
+ ts.factory.createTypeLiteralNode(
233
+ properties.map((p) =>
234
+ FilePrinter.description(
235
+ ts.factory.createPropertySignature(
236
+ undefined,
237
+ Escaper.variable(String(p.key.constants[0].values[0].value))
238
+ ? ts.factory.createIdentifier(
239
+ String(p.key.constants[0].values[0].value),
240
+ )
241
+ : ts.factory.createStringLiteral(
242
+ String(p.key.constants[0].values[0].value),
243
+ ),
244
+ p.value.isRequired() === false
245
+ ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
246
+ : undefined,
247
+ SdkTypeProgrammer.write(config)(importer)(p.value),
248
+ ),
249
+ writeComment(p.value.atomics)(p.description, p.jsDocTags),
250
+ ),
251
+ ),
252
+ );
253
+
254
+ const write_dynamic_property =
255
+ (config: INestiaConfig) =>
256
+ (importer: ImportDictionary) =>
257
+ (property: MetadataProperty): ts.TypeLiteralNode =>
258
+ ts.factory.createTypeLiteralNode([
259
+ FilePrinter.description(
260
+ ts.factory.createIndexSignature(
261
+ undefined,
262
+ [
263
+ ts.factory.createParameterDeclaration(
264
+ undefined,
265
+ undefined,
266
+ ts.factory.createIdentifier("key"),
267
+ undefined,
268
+ SdkTypeProgrammer.write(config)(importer)(property.key),
269
+ ),
270
+ ],
271
+ SdkTypeProgrammer.write(config)(importer)(property.value),
272
+ ),
273
+ writeComment(property.value.atomics)(
274
+ property.description,
275
+ property.jsDocTags,
276
+ ),
277
+ ),
278
+ ]);
279
+
280
+ const write_alias =
281
+ (config: INestiaConfig) =>
282
+ (importer: ImportDictionary) =>
283
+ (meta: MetadataAlias | MetadataObject): ts.TypeNode => {
284
+ importInternalFile(config)(importer)(meta.name);
285
+ return ts.factory.createTypeReferenceNode(meta.name);
286
+ };
287
+
288
+ const write_native = (name: string): ts.TypeNode =>
289
+ ts.factory.createTypeReferenceNode(name);
290
+
291
+ /* -----------------------------------------------------------
292
+ MISCELLANEOUS
293
+ ----------------------------------------------------------- */
294
+ const write_type_tag_matrix =
295
+ (importer: ImportDictionary) =>
296
+ (base: ts.TypeNode, matrix: IMetadataTypeTag[][]): ts.TypeNode => {
297
+ matrix = matrix.filter((row) => row.length !== 0);
298
+ if (matrix.length === 0) return base;
299
+ else if (matrix.length === 1)
300
+ return ts.factory.createIntersectionTypeNode([
301
+ base,
302
+ ...matrix[0].map((tag) => writeTag(importer)(tag)),
303
+ ]);
304
+ return ts.factory.createIntersectionTypeNode([
305
+ base,
306
+ ts.factory.createUnionTypeNode(
307
+ matrix.map((row) =>
308
+ row.length === 1
309
+ ? writeTag(importer)(row[0])
310
+ : ts.factory.createIntersectionTypeNode(
311
+ row.map((tag) => writeTag(importer)(tag)),
312
+ ),
313
+ ),
314
+ ),
315
+ ]);
316
+ };
317
+ }
318
+
319
+ const writeNode = (text: string) => ts.factory.createTypeReferenceNode(text);
320
+ const writeTag = (importer: ImportDictionary) => (tag: IMetadataTypeTag) => {
321
+ const instance: string = tag.name.split("<")[0];
322
+ return ts.factory.createTypeReferenceNode(
323
+ importer.external({
324
+ type: true,
325
+ library: `typia/lib/tags/${instance}`,
326
+ instance,
327
+ }),
328
+ [
329
+ ts.factory.createLiteralTypeNode(
330
+ typeof tag.value === "boolean"
331
+ ? tag.value
332
+ ? ts.factory.createTrue()
333
+ : ts.factory.createFalse()
334
+ : typeof tag.value === "bigint"
335
+ ? tag.value < BigInt(0)
336
+ ? ts.factory.createPrefixUnaryExpression(
337
+ ts.SyntaxKind.MinusToken,
338
+ ts.factory.createBigIntLiteral((-tag.value).toString()),
339
+ )
340
+ : ts.factory.createBigIntLiteral(tag.value.toString())
341
+ : typeof tag.value === "number"
342
+ ? ExpressionFactory.number(tag.value)
343
+ : ts.factory.createStringLiteral(tag.value),
344
+ ),
345
+ ],
346
+ );
347
+ };
348
+ const writeComment =
349
+ (atomics: MetadataAtomic[]) =>
350
+ (description: string | null, jsDocTags: IJsDocTagInfo[]): string => {
351
+ const lines: string[] = [];
352
+ if (description?.length)
353
+ lines.push(...description.split("\n").map((s) => `${s}`));
354
+
355
+ const filtered: IJsDocTagInfo[] =
356
+ !!atomics.length && !!jsDocTags?.length
357
+ ? jsDocTags.filter(
358
+ (tag) =>
359
+ !atomics.some((a) =>
360
+ a.tags.some((r) => r.some((t) => t.kind === tag.name)),
361
+ ),
362
+ )
363
+ : jsDocTags ?? [];
364
+
365
+ if (description?.length && filtered.length) lines.push("");
366
+ if (filtered.length)
367
+ lines.push(
368
+ ...filtered.map((t) =>
369
+ t.text?.length
370
+ ? `@${t.name} ${t.text.map((e) => e.text).join("")}`
371
+ : `@${t.name}`,
372
+ ),
373
+ );
374
+ return lines.join("\n");
375
+ };
376
+
377
+ const importInternalFile =
378
+ (config: INestiaConfig) => (importer: ImportDictionary) => (name: string) => {
379
+ const top = name.split(".")[0];
380
+ if (importer.file === `${config.output}/structures/${top}.ts`) return;
381
+ importer.internal({
382
+ type: true,
383
+ file: `${config.output}/structures/${name.split(".")[0]}`,
384
+ instance: top,
385
+ });
386
+ };