typia 3.8.2 → 3.8.3

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 (173) hide show
  1. package/README.md +1 -1
  2. package/lib/Primitive.d.ts +10 -10
  3. package/lib/factories/MetadataFactory.d.ts +1 -1
  4. package/lib/factories/MetadataFactory.js +1 -1
  5. package/lib/factories/MetadataFactory.js.map +1 -1
  6. package/lib/factories/internal/metadata/emplace_metadata_object.js +3 -1
  7. package/lib/factories/internal/metadata/emplace_metadata_object.js.map +1 -1
  8. package/lib/factories/internal/metadata/iterate_metadata_tuple.js +2 -0
  9. package/lib/factories/internal/metadata/iterate_metadata_tuple.js.map +1 -1
  10. package/lib/metadata/IMetadata.d.ts +1 -0
  11. package/lib/metadata/Metadata.d.ts +1 -0
  12. package/lib/metadata/Metadata.js +5 -0
  13. package/lib/metadata/Metadata.js.map +1 -1
  14. package/lib/programmers/CheckerProgrammer.js +17 -6
  15. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  16. package/lib/programmers/internal/application_object.js +1 -0
  17. package/lib/programmers/internal/application_object.js.map +1 -1
  18. package/lib/programmers/internal/application_tuple.js +1 -1
  19. package/lib/programmers/internal/application_tuple.js.map +1 -1
  20. package/lib/schemas/IJsonSchema.d.ts +1 -0
  21. package/package.json +1 -1
  22. package/src/Primitive.ts +123 -120
  23. package/src/executable/TypiaGenerateWizard.ts +85 -85
  24. package/src/executable/TypiaSetupWizard.ts +133 -133
  25. package/src/executable/setup/CommandExecutor.ts +8 -8
  26. package/src/executable/setup/PackageManager.ts +71 -71
  27. package/src/executable/typia.ts +52 -52
  28. package/src/factories/CommentFactory.ts +14 -14
  29. package/src/factories/ExpressionFactory.ts +70 -70
  30. package/src/factories/IdentifierFactory.ts +63 -63
  31. package/src/factories/LiteralFactory.ts +39 -39
  32. package/src/factories/MetadataCollection.ts +121 -121
  33. package/src/factories/MetadataFactory.ts +62 -62
  34. package/src/factories/MetadataTagFactory.ts +297 -297
  35. package/src/factories/StatementFactory.ts +24 -24
  36. package/src/factories/TemplateFactory.ts +58 -58
  37. package/src/factories/TypeFactory.ts +124 -124
  38. package/src/factories/internal/metadata/MetadataHelper.ts +12 -12
  39. package/src/factories/internal/metadata/emplace_metadata_object.ts +143 -140
  40. package/src/factories/internal/metadata/iterate_metadata.ts +67 -67
  41. package/src/factories/internal/metadata/iterate_metadata_map.ts +41 -41
  42. package/src/factories/internal/metadata/iterate_metadata_native.ts +219 -219
  43. package/src/factories/internal/metadata/iterate_metadata_resolve.ts +27 -27
  44. package/src/factories/internal/metadata/iterate_metadata_set.ts +33 -33
  45. package/src/factories/internal/metadata/iterate_metadata_tuple.ts +48 -44
  46. package/src/factories/internal/metadata/iterate_metadata_union.ts +57 -57
  47. package/src/functional/$any.ts +2 -2
  48. package/src/functional/$is_between.ts +2 -2
  49. package/src/functional/$is_custom.ts +14 -14
  50. package/src/functional/$is_date.ts +3 -3
  51. package/src/functional/$is_datetime.ts +2 -2
  52. package/src/functional/$is_email.ts +4 -4
  53. package/src/functional/$is_ipv4.ts +4 -4
  54. package/src/functional/$is_ipv6.ts +4 -4
  55. package/src/functional/$is_url.ts +4 -4
  56. package/src/functional/$is_uuid.ts +4 -4
  57. package/src/functional/$join.ts +46 -46
  58. package/src/functional/$number.ts +12 -12
  59. package/src/functional/$rest.ts +3 -3
  60. package/src/functional/$string.ts +37 -37
  61. package/src/functional/$tail.ts +5 -5
  62. package/src/metadata/IMetadata.ts +1 -0
  63. package/src/metadata/Metadata.ts +539 -533
  64. package/src/metadata/MetadataConstant.ts +3 -3
  65. package/src/metadata/MetadataObject.ts +127 -127
  66. package/src/module.ts +2043 -2043
  67. package/src/programmers/ApplicationProgrammer.ts +62 -62
  68. package/src/programmers/AssertCloneProgrammer.ts +79 -79
  69. package/src/programmers/AssertParseProgrammer.ts +74 -74
  70. package/src/programmers/AssertProgrammer.ts +285 -285
  71. package/src/programmers/AssertPruneProgrammer.ts +76 -76
  72. package/src/programmers/AssertStringifyProgrammer.ts +74 -74
  73. package/src/programmers/CheckerProgrammer.ts +901 -875
  74. package/src/programmers/CloneProgrammer.ts +389 -389
  75. package/src/programmers/FeatureProgrammer.ts +500 -500
  76. package/src/programmers/IsCloneProgrammer.ts +86 -86
  77. package/src/programmers/IsParseProgrammer.ts +80 -80
  78. package/src/programmers/IsProgrammer.ts +212 -212
  79. package/src/programmers/IsPruneProgrammer.ts +81 -81
  80. package/src/programmers/IsStringifyProgrammer.ts +84 -84
  81. package/src/programmers/LiteralsProgrammer.ts +65 -65
  82. package/src/programmers/PruneProgrammer.ts +347 -347
  83. package/src/programmers/RandomProgrammer.ts +423 -423
  84. package/src/programmers/StringifyProgrammer.ts +798 -798
  85. package/src/programmers/TypiaProgrammer.ts +129 -129
  86. package/src/programmers/ValidateCloneProgrammer.ts +93 -93
  87. package/src/programmers/ValidateParseProgrammer.ts +78 -78
  88. package/src/programmers/ValidateProgrammer.ts +316 -316
  89. package/src/programmers/ValidatePruneProgrammer.ts +86 -86
  90. package/src/programmers/ValidateStringifyProgrammer.ts +92 -92
  91. package/src/programmers/helpers/CloneJoiner.ts +131 -131
  92. package/src/programmers/helpers/FunctionImporeter.ts +54 -54
  93. package/src/programmers/helpers/OptionPredicator.ts +15 -15
  94. package/src/programmers/helpers/PruneJoiner.ts +144 -144
  95. package/src/programmers/helpers/StringifyJoinder.ts +113 -113
  96. package/src/programmers/helpers/StringifyPredicator.ts +12 -12
  97. package/src/programmers/helpers/UnionExplorer.ts +275 -275
  98. package/src/programmers/helpers/UnionPredicator.ts +81 -81
  99. package/src/programmers/internal/application_array.ts +36 -36
  100. package/src/programmers/internal/application_boolean.ts +17 -17
  101. package/src/programmers/internal/application_constant.ts +30 -30
  102. package/src/programmers/internal/application_default_string.ts +33 -33
  103. package/src/programmers/internal/application_native.ts +32 -32
  104. package/src/programmers/internal/application_number.ts +73 -73
  105. package/src/programmers/internal/application_object.ts +155 -154
  106. package/src/programmers/internal/application_schema.ts +213 -213
  107. package/src/programmers/internal/application_string.ts +45 -45
  108. package/src/programmers/internal/application_templates.ts +26 -26
  109. package/src/programmers/internal/application_tuple.ts +31 -29
  110. package/src/programmers/internal/check_array.ts +30 -30
  111. package/src/programmers/internal/check_custom.ts +31 -31
  112. package/src/programmers/internal/check_dynamic_properties.ts +194 -194
  113. package/src/programmers/internal/check_everything.ts +28 -28
  114. package/src/programmers/internal/check_native.ts +21 -21
  115. package/src/programmers/internal/check_string_tags.ts +67 -67
  116. package/src/programmers/internal/check_union_array_like.ts +271 -271
  117. package/src/programmers/internal/check_union_tuple.ts +33 -33
  118. package/src/programmers/internal/random_custom.ts +29 -29
  119. package/src/programmers/internal/stringify_dynamic_properties.ts +167 -167
  120. package/src/programmers/internal/stringify_native.ts +7 -7
  121. package/src/programmers/internal/stringify_regular_properties.ts +83 -83
  122. package/src/schemas/IJsonSchema.ts +130 -129
  123. package/src/transform.ts +17 -17
  124. package/src/transformers/CallExpressionTransformer.ts +177 -177
  125. package/src/transformers/FileTransformer.ts +47 -47
  126. package/src/transformers/NodeTransformer.ts +13 -13
  127. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +114 -114
  128. package/src/transformers/features/miscellaneous/AssertCloneTransformer.ts +9 -9
  129. package/src/transformers/features/miscellaneous/AssertPruneTransformer.ts +9 -9
  130. package/src/transformers/features/miscellaneous/CloneTransformer.ts +9 -9
  131. package/src/transformers/features/miscellaneous/CreateAssertCloneTransformer.ts +9 -9
  132. package/src/transformers/features/miscellaneous/CreateAssertPruneTransformer.ts +9 -9
  133. package/src/transformers/features/miscellaneous/CreateCloneTransformer.ts +9 -9
  134. package/src/transformers/features/miscellaneous/CreateIsCloneTransformer.ts +9 -9
  135. package/src/transformers/features/miscellaneous/CreateIsPruneTransformer.ts +9 -9
  136. package/src/transformers/features/miscellaneous/CreatePruneTransformer.ts +9 -9
  137. package/src/transformers/features/miscellaneous/CreateRandomTransformer.ts +39 -39
  138. package/src/transformers/features/miscellaneous/CreateValidateCloneTransformer.ts +9 -9
  139. package/src/transformers/features/miscellaneous/CreateValidatePruneTransformer.ts +9 -9
  140. package/src/transformers/features/miscellaneous/IsCloneTransformer.ts +9 -9
  141. package/src/transformers/features/miscellaneous/IsPruneTransformer.ts +9 -9
  142. package/src/transformers/features/miscellaneous/LiteralsTransformer.ts +28 -28
  143. package/src/transformers/features/miscellaneous/MetadataTransformer.ts +52 -52
  144. package/src/transformers/features/miscellaneous/PruneTransformer.ts +9 -9
  145. package/src/transformers/features/miscellaneous/RandomTransformer.ts +42 -42
  146. package/src/transformers/features/miscellaneous/ValidateCloneTransformer.ts +9 -9
  147. package/src/transformers/features/miscellaneous/ValidatePruneTransformer.ts +9 -9
  148. package/src/transformers/features/parsers/AssertParseTransformer.ts +9 -9
  149. package/src/transformers/features/parsers/CreateAssertParseTransformer.ts +9 -9
  150. package/src/transformers/features/parsers/CreateIsParseTransformer.ts +9 -9
  151. package/src/transformers/features/parsers/CreateValidateParseTransformer.ts +9 -9
  152. package/src/transformers/features/parsers/IsParseTransformer.ts +9 -9
  153. package/src/transformers/features/parsers/ValidateParseTransformer.ts +9 -9
  154. package/src/transformers/features/stringifiers/AssertStringifyTransformer.ts +10 -10
  155. package/src/transformers/features/stringifiers/CreateAssertStringifyTransformer.ts +12 -12
  156. package/src/transformers/features/stringifiers/CreateIsStringifyTransformer.ts +9 -9
  157. package/src/transformers/features/stringifiers/CreateStringifyTransformer.ts +9 -9
  158. package/src/transformers/features/stringifiers/CreateValidateStringifyProgrammer.ts +12 -12
  159. package/src/transformers/features/stringifiers/IsStringifyTransformer.ts +9 -9
  160. package/src/transformers/features/stringifiers/StringifyTransformer.ts +9 -9
  161. package/src/transformers/features/stringifiers/ValidateStringifyTransformer.ts +10 -10
  162. package/src/transformers/features/validators/AssertTransformer.ts +11 -11
  163. package/src/transformers/features/validators/CreateAssertTransformer.ts +13 -13
  164. package/src/transformers/features/validators/CreateIsTransformer.ts +11 -11
  165. package/src/transformers/features/validators/CreateValidateTransformer.ts +13 -13
  166. package/src/transformers/features/validators/IsTransformer.ts +11 -11
  167. package/src/transformers/features/validators/ValidateTransformer.ts +11 -11
  168. package/src/transformers/internal/GenericTransformer.ts +97 -97
  169. package/src/utils/ArrayUtil.ts +44 -44
  170. package/src/utils/Escaper.ts +45 -45
  171. package/src/utils/MapUtil.ts +12 -12
  172. package/src/utils/PatternUtil.ts +30 -30
  173. package/src/utils/RandomGenerator.ts +81 -81
@@ -1,389 +1,389 @@
1
- import ts from "typescript";
2
-
3
- import { ExpressionFactory } from "../factories/ExpressionFactory";
4
- import { IdentifierFactory } from "../factories/IdentifierFactory";
5
- import { MetadataCollection } from "../factories/MetadataCollection";
6
- import { MetadataFactory } from "../factories/MetadataFactory";
7
- import { TypeFactory } from "../factories/TypeFactory";
8
-
9
- import { Metadata } from "../metadata/Metadata";
10
-
11
- import { IProject } from "../transformers/IProject";
12
-
13
- import { FeatureProgrammer } from "./FeatureProgrammer";
14
- import { IsProgrammer } from "./IsProgrammer";
15
- import { CloneJoiner } from "./helpers/CloneJoiner";
16
- import { FunctionImporter } from "./helpers/FunctionImporeter";
17
- import { UnionExplorer } from "./helpers/UnionExplorer";
18
- import { decode_union_object } from "./internal/decode_union_object";
19
-
20
- export namespace CloneProgrammer {
21
- /**
22
- * @deprecated Use `write()` function instead
23
- */
24
- export const generate =
25
- (project: IProject, modulo: ts.LeftHandSideExpression) =>
26
- (type: ts.Type, name?: string) =>
27
- write(project)(modulo)(type, name);
28
-
29
- export const write =
30
- (project: IProject) => (modulo: ts.LeftHandSideExpression) => {
31
- const importer: FunctionImporter = new FunctionImporter();
32
- return FeatureProgrammer.analyze(project)({
33
- ...CONFIG(project, importer),
34
- addition: (collection) => {
35
- const isFunctors =
36
- IsProgrammer.write_functors(project)(importer)(
37
- collection,
38
- );
39
- const isUnioners =
40
- IsProgrammer.write_unioners(project)(importer)(
41
- collection,
42
- );
43
-
44
- return [
45
- ...importer.declare(modulo),
46
- ...isFunctors.filter((_, i) =>
47
- importer.hasLocal(`$io${i}`),
48
- ),
49
- ...isUnioners.filter((_, i) =>
50
- importer.hasLocal(`$iu${i}`),
51
- ),
52
- ];
53
- },
54
- })(importer);
55
- };
56
-
57
- /* -----------------------------------------------------------
58
- DECODERS
59
- ----------------------------------------------------------- */
60
- const decode =
61
- (project: IProject, importer: FunctionImporter) =>
62
- (
63
- input: ts.Expression,
64
- meta: Metadata,
65
- explore: FeatureProgrammer.IExplore,
66
- ): ts.Expression => {
67
- // ANY TYPE
68
- if (
69
- meta.any ||
70
- meta.arrays.some((a) => a.any) ||
71
- meta.tuples.some((t) => t.every((e) => e.any))
72
- )
73
- return ts.factory.createCallExpression(
74
- importer.use("any"),
75
- undefined,
76
- [input],
77
- );
78
-
79
- interface IUnion {
80
- type: string;
81
- is: () => ts.Expression;
82
- value: () => ts.Expression;
83
- }
84
- const unions: IUnion[] = [];
85
-
86
- //----
87
- // LIST UP UNION TYPES
88
- //----
89
- // toJSON() METHOD
90
- if (meta.resolved !== null)
91
- unions.push({
92
- type: "resolved",
93
- is: () => IsProgrammer.decode_to_json(true)(input),
94
- value: () =>
95
- decode_to_json(project, importer)(
96
- input,
97
- meta.resolved!,
98
- explore,
99
- ),
100
- });
101
-
102
- // TUPLES
103
- for (const tuple of meta.tuples)
104
- unions.push({
105
- type: "tuple",
106
- is: () =>
107
- IsProgrammer.decode(project, importer)(
108
- input,
109
- (() => {
110
- const partial = Metadata.initialize();
111
- partial.tuples.push(tuple);
112
- return partial;
113
- })(),
114
- explore,
115
- [],
116
- [],
117
- ),
118
- value: () =>
119
- decode_tuple(project, importer)(input, tuple, explore),
120
- });
121
-
122
- // ARRAYS
123
- if (meta.arrays.length)
124
- unions.push({
125
- type: "array",
126
- is: () => ExpressionFactory.isArray(input),
127
- value: () =>
128
- explore_arrays(project, importer)(
129
- input,
130
- meta.arrays,
131
- {
132
- ...explore,
133
- from: "array",
134
- },
135
- [],
136
- [],
137
- ),
138
- });
139
-
140
- // NATIVE TYPES
141
- if (meta.sets.length)
142
- unions.push({
143
- type: "set",
144
- is: () => ExpressionFactory.isInstanceOf("Set")(input),
145
- value: () => ts.factory.createIdentifier("{}"),
146
- });
147
- if (meta.maps.length)
148
- unions.push({
149
- type: "map",
150
- is: () => ExpressionFactory.isInstanceOf("Map")(input),
151
- value: () => ts.factory.createIdentifier("{}"),
152
- });
153
- for (const native of meta.natives)
154
- unions.push({
155
- type: "native",
156
- is: () => ExpressionFactory.isInstanceOf(native)(input),
157
- value: () =>
158
- native === "Boolean" ||
159
- native === "Number" ||
160
- native === "String"
161
- ? ts.factory.createCallExpression(
162
- IdentifierFactory.access(input)("valueOf"),
163
- undefined,
164
- undefined,
165
- )
166
- : ts.factory.createIdentifier("{}"),
167
- });
168
-
169
- // OBJECTS
170
- if (meta.objects.length)
171
- unions.push({
172
- type: "object",
173
- is: () =>
174
- ExpressionFactory.isObject({
175
- checkNull: true,
176
- checkArray: false,
177
- })(input),
178
- value: () =>
179
- explore_objects(importer)(input, meta, {
180
- ...explore,
181
- from: "object",
182
- }),
183
- });
184
-
185
- // COMPOSITION
186
- let last: ts.Expression = input;
187
- for (const u of unions.reverse())
188
- last = ts.factory.createConditionalExpression(
189
- u.is(),
190
- undefined,
191
- u.value(),
192
- undefined,
193
- last,
194
- );
195
- return ts.factory.createAsExpression(
196
- last,
197
- TypeFactory.keyword("any"),
198
- );
199
- };
200
-
201
- const decode_to_json =
202
- (project: IProject, importer: FunctionImporter) =>
203
- (
204
- input: ts.Expression,
205
- resolved: Metadata,
206
- explore: FeatureProgrammer.IExplore,
207
- ): ts.Expression => {
208
- return decode(project, importer)(
209
- ts.factory.createCallExpression(
210
- IdentifierFactory.access(input)("toJSON"),
211
- undefined,
212
- [],
213
- ),
214
- resolved,
215
- explore,
216
- );
217
- };
218
-
219
- const decode_tuple =
220
- (project: IProject, importer: FunctionImporter) =>
221
- (
222
- input: ts.Expression,
223
- tuple: Metadata[],
224
- explore: FeatureProgrammer.IExplore,
225
- ): ts.Expression => {
226
- const children: ts.Expression[] = tuple
227
- .filter((m) => m.rest === null)
228
- .map((elem, index) =>
229
- decode(project, importer)(
230
- ts.factory.createElementAccessExpression(input, index),
231
- elem,
232
- {
233
- ...explore,
234
- from: "array",
235
- },
236
- ),
237
- );
238
- const rest = (() => {
239
- if (tuple.length === 0) return null;
240
-
241
- const last: Metadata = tuple[tuple.length - 1]!;
242
- const rest: Metadata | null = last.rest;
243
- if (rest === null) return null;
244
-
245
- return decode(project, importer)(
246
- ts.factory.createCallExpression(
247
- IdentifierFactory.access(input)("slice"),
248
- undefined,
249
- [ts.factory.createNumericLiteral(tuple.length - 1)],
250
- ),
251
- (() => {
252
- const wrapper: Metadata = Metadata.initialize();
253
- wrapper.arrays.push(rest);
254
- return wrapper;
255
- })(),
256
- {
257
- ...explore,
258
- start: tuple.length - 1,
259
- },
260
- );
261
- })();
262
- return CloneJoiner.tuple(children, rest);
263
- };
264
-
265
- const decode_array = (project: IProject, importer: FunctionImporter) =>
266
- FeatureProgrammer.decode_array(CONFIG(project, importer))(importer)(
267
- CloneJoiner.array,
268
- );
269
-
270
- const decode_object = (importer: FunctionImporter) =>
271
- FeatureProgrammer.decode_object({
272
- trace: false,
273
- path: false,
274
- functors: FUNCTORS,
275
- })(importer);
276
-
277
- const explore_arrays = (project: IProject, importer: FunctionImporter) =>
278
- UnionExplorer.array({
279
- checker: IsProgrammer.decode(project, importer),
280
- decoder: decode_array(project, importer),
281
- empty: ts.factory.createReturnStatement(),
282
- success: ts.factory.createTrue(),
283
- failure: (input, expected) =>
284
- create_throw_error(importer, input, expected),
285
- });
286
-
287
- const explore_objects =
288
- (importer: FunctionImporter) =>
289
- (
290
- input: ts.Expression,
291
- meta: Metadata,
292
- explore: FeatureProgrammer.IExplore,
293
- ) => {
294
- if (meta.objects.length === 1)
295
- return decode_object(importer)(
296
- input,
297
- meta.objects[0]!,
298
- explore,
299
- );
300
-
301
- return ts.factory.createCallExpression(
302
- ts.factory.createIdentifier(`${UNIONERS}${meta.union_index!}`),
303
- undefined,
304
- [input],
305
- );
306
- };
307
-
308
- /* -----------------------------------------------------------
309
- CONFIGURATIONS
310
- ----------------------------------------------------------- */
311
- const FUNCTORS = "$co";
312
- const UNIONERS = "$cu";
313
-
314
- const CONFIG = (
315
- project: IProject,
316
- importer: FunctionImporter,
317
- ): FeatureProgrammer.IConfig => ({
318
- types: {
319
- input: (type, name) =>
320
- ts.factory.createTypeReferenceNode(
321
- name ?? TypeFactory.getFullName(project.checker)(type),
322
- ),
323
- output: (type, name) =>
324
- ts.factory.createTypeReferenceNode(
325
- `typia.Primitive<${
326
- name ?? TypeFactory.getFullName(project.checker)(type)
327
- }>`,
328
- ),
329
- },
330
- functors: FUNCTORS,
331
- unioners: UNIONERS,
332
- trace: false,
333
- path: false,
334
- initializer,
335
- decoder: decode(project, importer),
336
- objector: OBJECTOR(project, importer),
337
- });
338
-
339
- const OBJECTOR = (
340
- project: IProject,
341
- importer: FunctionImporter,
342
- ): FeatureProgrammer.IConfig.IObjector => ({
343
- checker: IsProgrammer.decode(project, importer),
344
- decoder: decode_object(importer),
345
- joiner: CloneJoiner.object,
346
- unionizer: decode_union_object(IsProgrammer.decode_object(importer))(
347
- decode_object(importer),
348
- )((exp) => exp)((value, expected) =>
349
- create_throw_error(importer, value, expected),
350
- ),
351
- failure: (input, expected) =>
352
- create_throw_error(importer, input, expected),
353
- });
354
-
355
- const initializer: FeatureProgrammer.IConfig["initializer"] =
356
- ({ checker }) =>
357
- (type) => {
358
- const collection = new MetadataCollection();
359
- const meta = MetadataFactory.analyze(checker)({
360
- resolve: true,
361
- constant: true,
362
- })(collection)(type);
363
- return [collection, meta];
364
- };
365
-
366
- const create_throw_error = (
367
- importer: FunctionImporter,
368
- value: ts.Expression,
369
- expected: string,
370
- ) =>
371
- ts.factory.createExpressionStatement(
372
- ts.factory.createCallExpression(
373
- importer.use("throws"),
374
- [],
375
- [
376
- ts.factory.createObjectLiteralExpression(
377
- [
378
- ts.factory.createPropertyAssignment(
379
- "expected",
380
- ts.factory.createStringLiteral(expected),
381
- ),
382
- ts.factory.createPropertyAssignment("value", value),
383
- ],
384
- true,
385
- ),
386
- ],
387
- ),
388
- );
389
- }
1
+ import ts from "typescript";
2
+
3
+ import { ExpressionFactory } from "../factories/ExpressionFactory";
4
+ import { IdentifierFactory } from "../factories/IdentifierFactory";
5
+ import { MetadataCollection } from "../factories/MetadataCollection";
6
+ import { MetadataFactory } from "../factories/MetadataFactory";
7
+ import { TypeFactory } from "../factories/TypeFactory";
8
+
9
+ import { Metadata } from "../metadata/Metadata";
10
+
11
+ import { IProject } from "../transformers/IProject";
12
+
13
+ import { FeatureProgrammer } from "./FeatureProgrammer";
14
+ import { IsProgrammer } from "./IsProgrammer";
15
+ import { CloneJoiner } from "./helpers/CloneJoiner";
16
+ import { FunctionImporter } from "./helpers/FunctionImporeter";
17
+ import { UnionExplorer } from "./helpers/UnionExplorer";
18
+ import { decode_union_object } from "./internal/decode_union_object";
19
+
20
+ export namespace CloneProgrammer {
21
+ /**
22
+ * @deprecated Use `write()` function instead
23
+ */
24
+ export const generate =
25
+ (project: IProject, modulo: ts.LeftHandSideExpression) =>
26
+ (type: ts.Type, name?: string) =>
27
+ write(project)(modulo)(type, name);
28
+
29
+ export const write =
30
+ (project: IProject) => (modulo: ts.LeftHandSideExpression) => {
31
+ const importer: FunctionImporter = new FunctionImporter();
32
+ return FeatureProgrammer.analyze(project)({
33
+ ...CONFIG(project, importer),
34
+ addition: (collection) => {
35
+ const isFunctors =
36
+ IsProgrammer.write_functors(project)(importer)(
37
+ collection,
38
+ );
39
+ const isUnioners =
40
+ IsProgrammer.write_unioners(project)(importer)(
41
+ collection,
42
+ );
43
+
44
+ return [
45
+ ...importer.declare(modulo),
46
+ ...isFunctors.filter((_, i) =>
47
+ importer.hasLocal(`$io${i}`),
48
+ ),
49
+ ...isUnioners.filter((_, i) =>
50
+ importer.hasLocal(`$iu${i}`),
51
+ ),
52
+ ];
53
+ },
54
+ })(importer);
55
+ };
56
+
57
+ /* -----------------------------------------------------------
58
+ DECODERS
59
+ ----------------------------------------------------------- */
60
+ const decode =
61
+ (project: IProject, importer: FunctionImporter) =>
62
+ (
63
+ input: ts.Expression,
64
+ meta: Metadata,
65
+ explore: FeatureProgrammer.IExplore,
66
+ ): ts.Expression => {
67
+ // ANY TYPE
68
+ if (
69
+ meta.any ||
70
+ meta.arrays.some((a) => a.any) ||
71
+ meta.tuples.some((t) => t.every((e) => e.any))
72
+ )
73
+ return ts.factory.createCallExpression(
74
+ importer.use("any"),
75
+ undefined,
76
+ [input],
77
+ );
78
+
79
+ interface IUnion {
80
+ type: string;
81
+ is: () => ts.Expression;
82
+ value: () => ts.Expression;
83
+ }
84
+ const unions: IUnion[] = [];
85
+
86
+ //----
87
+ // LIST UP UNION TYPES
88
+ //----
89
+ // toJSON() METHOD
90
+ if (meta.resolved !== null)
91
+ unions.push({
92
+ type: "resolved",
93
+ is: () => IsProgrammer.decode_to_json(true)(input),
94
+ value: () =>
95
+ decode_to_json(project, importer)(
96
+ input,
97
+ meta.resolved!,
98
+ explore,
99
+ ),
100
+ });
101
+
102
+ // TUPLES
103
+ for (const tuple of meta.tuples)
104
+ unions.push({
105
+ type: "tuple",
106
+ is: () =>
107
+ IsProgrammer.decode(project, importer)(
108
+ input,
109
+ (() => {
110
+ const partial = Metadata.initialize();
111
+ partial.tuples.push(tuple);
112
+ return partial;
113
+ })(),
114
+ explore,
115
+ [],
116
+ [],
117
+ ),
118
+ value: () =>
119
+ decode_tuple(project, importer)(input, tuple, explore),
120
+ });
121
+
122
+ // ARRAYS
123
+ if (meta.arrays.length)
124
+ unions.push({
125
+ type: "array",
126
+ is: () => ExpressionFactory.isArray(input),
127
+ value: () =>
128
+ explore_arrays(project, importer)(
129
+ input,
130
+ meta.arrays,
131
+ {
132
+ ...explore,
133
+ from: "array",
134
+ },
135
+ [],
136
+ [],
137
+ ),
138
+ });
139
+
140
+ // NATIVE TYPES
141
+ if (meta.sets.length)
142
+ unions.push({
143
+ type: "set",
144
+ is: () => ExpressionFactory.isInstanceOf("Set")(input),
145
+ value: () => ts.factory.createIdentifier("{}"),
146
+ });
147
+ if (meta.maps.length)
148
+ unions.push({
149
+ type: "map",
150
+ is: () => ExpressionFactory.isInstanceOf("Map")(input),
151
+ value: () => ts.factory.createIdentifier("{}"),
152
+ });
153
+ for (const native of meta.natives)
154
+ unions.push({
155
+ type: "native",
156
+ is: () => ExpressionFactory.isInstanceOf(native)(input),
157
+ value: () =>
158
+ native === "Boolean" ||
159
+ native === "Number" ||
160
+ native === "String"
161
+ ? ts.factory.createCallExpression(
162
+ IdentifierFactory.access(input)("valueOf"),
163
+ undefined,
164
+ undefined,
165
+ )
166
+ : ts.factory.createIdentifier("{}"),
167
+ });
168
+
169
+ // OBJECTS
170
+ if (meta.objects.length)
171
+ unions.push({
172
+ type: "object",
173
+ is: () =>
174
+ ExpressionFactory.isObject({
175
+ checkNull: true,
176
+ checkArray: false,
177
+ })(input),
178
+ value: () =>
179
+ explore_objects(importer)(input, meta, {
180
+ ...explore,
181
+ from: "object",
182
+ }),
183
+ });
184
+
185
+ // COMPOSITION
186
+ let last: ts.Expression = input;
187
+ for (const u of unions.reverse())
188
+ last = ts.factory.createConditionalExpression(
189
+ u.is(),
190
+ undefined,
191
+ u.value(),
192
+ undefined,
193
+ last,
194
+ );
195
+ return ts.factory.createAsExpression(
196
+ last,
197
+ TypeFactory.keyword("any"),
198
+ );
199
+ };
200
+
201
+ const decode_to_json =
202
+ (project: IProject, importer: FunctionImporter) =>
203
+ (
204
+ input: ts.Expression,
205
+ resolved: Metadata,
206
+ explore: FeatureProgrammer.IExplore,
207
+ ): ts.Expression => {
208
+ return decode(project, importer)(
209
+ ts.factory.createCallExpression(
210
+ IdentifierFactory.access(input)("toJSON"),
211
+ undefined,
212
+ [],
213
+ ),
214
+ resolved,
215
+ explore,
216
+ );
217
+ };
218
+
219
+ const decode_tuple =
220
+ (project: IProject, importer: FunctionImporter) =>
221
+ (
222
+ input: ts.Expression,
223
+ tuple: Metadata[],
224
+ explore: FeatureProgrammer.IExplore,
225
+ ): ts.Expression => {
226
+ const children: ts.Expression[] = tuple
227
+ .filter((m) => m.rest === null)
228
+ .map((elem, index) =>
229
+ decode(project, importer)(
230
+ ts.factory.createElementAccessExpression(input, index),
231
+ elem,
232
+ {
233
+ ...explore,
234
+ from: "array",
235
+ },
236
+ ),
237
+ );
238
+ const rest = (() => {
239
+ if (tuple.length === 0) return null;
240
+
241
+ const last: Metadata = tuple[tuple.length - 1]!;
242
+ const rest: Metadata | null = last.rest;
243
+ if (rest === null) return null;
244
+
245
+ return decode(project, importer)(
246
+ ts.factory.createCallExpression(
247
+ IdentifierFactory.access(input)("slice"),
248
+ undefined,
249
+ [ts.factory.createNumericLiteral(tuple.length - 1)],
250
+ ),
251
+ (() => {
252
+ const wrapper: Metadata = Metadata.initialize();
253
+ wrapper.arrays.push(rest);
254
+ return wrapper;
255
+ })(),
256
+ {
257
+ ...explore,
258
+ start: tuple.length - 1,
259
+ },
260
+ );
261
+ })();
262
+ return CloneJoiner.tuple(children, rest);
263
+ };
264
+
265
+ const decode_array = (project: IProject, importer: FunctionImporter) =>
266
+ FeatureProgrammer.decode_array(CONFIG(project, importer))(importer)(
267
+ CloneJoiner.array,
268
+ );
269
+
270
+ const decode_object = (importer: FunctionImporter) =>
271
+ FeatureProgrammer.decode_object({
272
+ trace: false,
273
+ path: false,
274
+ functors: FUNCTORS,
275
+ })(importer);
276
+
277
+ const explore_arrays = (project: IProject, importer: FunctionImporter) =>
278
+ UnionExplorer.array({
279
+ checker: IsProgrammer.decode(project, importer),
280
+ decoder: decode_array(project, importer),
281
+ empty: ts.factory.createReturnStatement(),
282
+ success: ts.factory.createTrue(),
283
+ failure: (input, expected) =>
284
+ create_throw_error(importer, input, expected),
285
+ });
286
+
287
+ const explore_objects =
288
+ (importer: FunctionImporter) =>
289
+ (
290
+ input: ts.Expression,
291
+ meta: Metadata,
292
+ explore: FeatureProgrammer.IExplore,
293
+ ) => {
294
+ if (meta.objects.length === 1)
295
+ return decode_object(importer)(
296
+ input,
297
+ meta.objects[0]!,
298
+ explore,
299
+ );
300
+
301
+ return ts.factory.createCallExpression(
302
+ ts.factory.createIdentifier(`${UNIONERS}${meta.union_index!}`),
303
+ undefined,
304
+ [input],
305
+ );
306
+ };
307
+
308
+ /* -----------------------------------------------------------
309
+ CONFIGURATIONS
310
+ ----------------------------------------------------------- */
311
+ const FUNCTORS = "$co";
312
+ const UNIONERS = "$cu";
313
+
314
+ const CONFIG = (
315
+ project: IProject,
316
+ importer: FunctionImporter,
317
+ ): FeatureProgrammer.IConfig => ({
318
+ types: {
319
+ input: (type, name) =>
320
+ ts.factory.createTypeReferenceNode(
321
+ name ?? TypeFactory.getFullName(project.checker)(type),
322
+ ),
323
+ output: (type, name) =>
324
+ ts.factory.createTypeReferenceNode(
325
+ `typia.Primitive<${
326
+ name ?? TypeFactory.getFullName(project.checker)(type)
327
+ }>`,
328
+ ),
329
+ },
330
+ functors: FUNCTORS,
331
+ unioners: UNIONERS,
332
+ trace: false,
333
+ path: false,
334
+ initializer,
335
+ decoder: decode(project, importer),
336
+ objector: OBJECTOR(project, importer),
337
+ });
338
+
339
+ const OBJECTOR = (
340
+ project: IProject,
341
+ importer: FunctionImporter,
342
+ ): FeatureProgrammer.IConfig.IObjector => ({
343
+ checker: IsProgrammer.decode(project, importer),
344
+ decoder: decode_object(importer),
345
+ joiner: CloneJoiner.object,
346
+ unionizer: decode_union_object(IsProgrammer.decode_object(importer))(
347
+ decode_object(importer),
348
+ )((exp) => exp)((value, expected) =>
349
+ create_throw_error(importer, value, expected),
350
+ ),
351
+ failure: (input, expected) =>
352
+ create_throw_error(importer, input, expected),
353
+ });
354
+
355
+ const initializer: FeatureProgrammer.IConfig["initializer"] =
356
+ ({ checker }) =>
357
+ (type) => {
358
+ const collection = new MetadataCollection();
359
+ const meta = MetadataFactory.analyze(checker)({
360
+ resolve: true,
361
+ constant: true,
362
+ })(collection)(type);
363
+ return [collection, meta];
364
+ };
365
+
366
+ const create_throw_error = (
367
+ importer: FunctionImporter,
368
+ value: ts.Expression,
369
+ expected: string,
370
+ ) =>
371
+ ts.factory.createExpressionStatement(
372
+ ts.factory.createCallExpression(
373
+ importer.use("throws"),
374
+ [],
375
+ [
376
+ ts.factory.createObjectLiteralExpression(
377
+ [
378
+ ts.factory.createPropertyAssignment(
379
+ "expected",
380
+ ts.factory.createStringLiteral(expected),
381
+ ),
382
+ ts.factory.createPropertyAssignment("value", value),
383
+ ],
384
+ true,
385
+ ),
386
+ ],
387
+ ),
388
+ );
389
+ }