typia 3.4.13 → 3.4.14

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 (157) hide show
  1. package/README.md +9 -8
  2. package/lib/factories/internal/iterate_metadata_object.js +4 -2
  3. package/lib/factories/internal/iterate_metadata_object.js.map +1 -1
  4. package/package.json +1 -1
  5. package/src/IValidation.ts +21 -21
  6. package/src/Primitive.ts +82 -82
  7. package/src/TypeGuardError.ts +36 -36
  8. package/src/executable/internal/CommandParser.ts +15 -15
  9. package/src/executable/internal/TypiaSetupWizard.ts +175 -175
  10. package/src/executable/typia.ts +46 -46
  11. package/src/factories/CommentFactory.ts +10 -10
  12. package/src/factories/ExpressionFactory.ts +66 -66
  13. package/src/factories/IdentifierFactory.ts +72 -72
  14. package/src/factories/LiteralFactory.ts +44 -44
  15. package/src/factories/MetadataCollection.ts +122 -122
  16. package/src/factories/MetadataFactory.ts +46 -46
  17. package/src/factories/MetadataTagFactory.ts +347 -347
  18. package/src/factories/StatementFactory.ts +60 -60
  19. package/src/factories/TemplateFactory.ts +56 -56
  20. package/src/factories/TypeFactory.ts +101 -101
  21. package/src/factories/ValueFactory.ts +12 -12
  22. package/src/factories/internal/MetadataHelper.ts +12 -12
  23. package/src/factories/internal/emplace_metadata_object.ts +140 -140
  24. package/src/factories/internal/explore_metadata.ts +91 -91
  25. package/src/factories/internal/iterate_metadata.ts +80 -80
  26. package/src/factories/internal/iterate_metadata_array.ts +29 -29
  27. package/src/factories/internal/iterate_metadata_atomic.ts +59 -59
  28. package/src/factories/internal/iterate_metadata_coalesce.ts +33 -33
  29. package/src/factories/internal/iterate_metadata_constant.ts +58 -58
  30. package/src/factories/internal/iterate_metadata_map.ts +41 -41
  31. package/src/factories/internal/iterate_metadata_native.ts +227 -227
  32. package/src/factories/internal/iterate_metadata_object.ts +48 -45
  33. package/src/factories/internal/iterate_metadata_resolve.ts +27 -27
  34. package/src/factories/internal/iterate_metadata_set.ts +33 -33
  35. package/src/factories/internal/iterate_metadata_template.ts +38 -38
  36. package/src/factories/internal/iterate_metadata_tuple.ts +45 -45
  37. package/src/factories/internal/iterate_metadata_union.ts +59 -59
  38. package/src/functional/$every.ts +11 -11
  39. package/src/functional/$guard.ts +35 -35
  40. package/src/functional/$is_email.ts +5 -5
  41. package/src/functional/$is_ipv4.ts +5 -5
  42. package/src/functional/$is_ipv6.ts +5 -5
  43. package/src/functional/$is_url.ts +5 -5
  44. package/src/functional/$is_uuid.ts +5 -5
  45. package/src/functional/$join.ts +50 -50
  46. package/src/functional/$number.ts +19 -19
  47. package/src/functional/$report.ts +15 -15
  48. package/src/functional/$rest.ts +3 -3
  49. package/src/functional/$string.ts +37 -37
  50. package/src/functional/$tail.ts +6 -6
  51. package/src/index.ts +4 -4
  52. package/src/metadata/IJsDocTagInfo.ts +10 -10
  53. package/src/metadata/IMetadata.ts +25 -25
  54. package/src/metadata/IMetadataApplication.ts +7 -7
  55. package/src/metadata/IMetadataConstant.ts +16 -16
  56. package/src/metadata/IMetadataEntry.ts +6 -6
  57. package/src/metadata/IMetadataObject.ts +29 -29
  58. package/src/metadata/IMetadataProperty.ts +11 -11
  59. package/src/metadata/IMetadataTag.ts +122 -122
  60. package/src/metadata/Metadata.ts +477 -477
  61. package/src/metadata/MetadataConstant.ts +3 -3
  62. package/src/metadata/MetadataObject.ts +131 -131
  63. package/src/metadata/MetadataProperty.ts +64 -64
  64. package/src/module.ts +1535 -1535
  65. package/src/programmers/ApplicationProgrammer.ts +55 -55
  66. package/src/programmers/AssertParseProgrammer.ts +45 -45
  67. package/src/programmers/AssertProgrammer.ts +444 -444
  68. package/src/programmers/AssertStringifyProgrammer.ts +45 -45
  69. package/src/programmers/CheckerProgrammer.ts +804 -804
  70. package/src/programmers/FeatureProgrammer.ts +327 -327
  71. package/src/programmers/IsParseProgrammer.ts +51 -51
  72. package/src/programmers/IsProgrammer.ts +172 -172
  73. package/src/programmers/IsStringifyProgrammer.ts +49 -49
  74. package/src/programmers/StringifyProgrammer.ts +756 -756
  75. package/src/programmers/ValidateParseProgrammer.ts +49 -49
  76. package/src/programmers/ValidateProgrammer.ts +236 -236
  77. package/src/programmers/ValidateStringifyProgrammer.ts +60 -60
  78. package/src/programmers/helpers/AtomicPredicator.ts +15 -15
  79. package/src/programmers/helpers/FunctionImporeter.ts +31 -31
  80. package/src/programmers/helpers/IExpressionEntry.ts +10 -10
  81. package/src/programmers/helpers/OptionPredicator.ts +11 -11
  82. package/src/programmers/helpers/StringifyJoinder.ts +111 -111
  83. package/src/programmers/helpers/StringifyPredicator.ts +18 -18
  84. package/src/programmers/helpers/UnionExplorer.ts +437 -437
  85. package/src/programmers/helpers/UnionPredicator.ts +81 -81
  86. package/src/programmers/internal/application_array.ts +45 -45
  87. package/src/programmers/internal/application_boolean.ts +17 -17
  88. package/src/programmers/internal/application_constant.ts +29 -29
  89. package/src/programmers/internal/application_default.ts +17 -17
  90. package/src/programmers/internal/application_default_string.ts +32 -32
  91. package/src/programmers/internal/application_native.ts +29 -29
  92. package/src/programmers/internal/application_number.ts +76 -76
  93. package/src/programmers/internal/application_object.ts +103 -103
  94. package/src/programmers/internal/application_schema.ts +221 -221
  95. package/src/programmers/internal/application_string.ts +49 -49
  96. package/src/programmers/internal/application_templates.ts +27 -27
  97. package/src/programmers/internal/application_tuple.ts +25 -25
  98. package/src/programmers/internal/check_array.ts +44 -44
  99. package/src/programmers/internal/check_dynamic_properties.ts +146 -146
  100. package/src/programmers/internal/check_everything.ts +25 -25
  101. package/src/programmers/internal/check_length.ts +46 -46
  102. package/src/programmers/internal/check_native.ts +9 -9
  103. package/src/programmers/internal/check_number.ts +178 -178
  104. package/src/programmers/internal/check_object.ts +42 -42
  105. package/src/programmers/internal/check_string.ts +24 -24
  106. package/src/programmers/internal/check_string_tags.ts +63 -63
  107. package/src/programmers/internal/check_template.ts +50 -50
  108. package/src/programmers/internal/decode_union_object.ts +73 -73
  109. package/src/programmers/internal/feature_object_entries.ts +49 -49
  110. package/src/programmers/internal/metadata_to_pattern.ts +31 -31
  111. package/src/programmers/internal/stringify_dynamic_properties.ts +164 -164
  112. package/src/programmers/internal/stringify_native.ts +8 -8
  113. package/src/programmers/internal/stringify_regular_properties.ts +81 -81
  114. package/src/programmers/internal/template_to_pattern.ts +15 -15
  115. package/src/schemas/IJsonApplication.ts +9 -9
  116. package/src/schemas/IJsonComponents.ts +24 -24
  117. package/src/schemas/IJsonSchema.ts +92 -92
  118. package/src/transform.ts +20 -20
  119. package/src/transformers/CallExpressionTransformer.ts +124 -124
  120. package/src/transformers/ExpressionWithArgumentTransformer.ts +66 -66
  121. package/src/transformers/FileTransformer.ts +49 -49
  122. package/src/transformers/IProject.ts +11 -11
  123. package/src/transformers/ITransformOptions.ts +4 -4
  124. package/src/transformers/NodeTransformer.ts +19 -19
  125. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +114 -114
  126. package/src/transformers/features/miscellaneous/CreateInstanceTransformer.ts +41 -41
  127. package/src/transformers/features/miscellaneous/MetadataTransformer.ts +55 -55
  128. package/src/transformers/features/parsers/AssertParseTransformer.ts +36 -36
  129. package/src/transformers/features/parsers/CreateAssertParseTransformer.ts +32 -32
  130. package/src/transformers/features/parsers/CreateIsParseTransformer.ts +32 -32
  131. package/src/transformers/features/parsers/CreateValidateParseTransformer.ts +32 -32
  132. package/src/transformers/features/parsers/IsParseTransformer.ts +36 -36
  133. package/src/transformers/features/parsers/ValidateParseTransformer.ts +36 -36
  134. package/src/transformers/features/stringifiers/AssertStringifyTransformer.ts +38 -38
  135. package/src/transformers/features/stringifiers/CreateAssertStringifyTransformer.ts +32 -32
  136. package/src/transformers/features/stringifiers/CreateIsStringifyTransformer.ts +32 -32
  137. package/src/transformers/features/stringifiers/CreateStringifyTransformer.ts +31 -31
  138. package/src/transformers/features/stringifiers/CreateValidateStringifyProgrammer.ts +32 -32
  139. package/src/transformers/features/stringifiers/IsStringifyTransformer.ts +38 -38
  140. package/src/transformers/features/stringifiers/StringifyTransformer.ts +36 -36
  141. package/src/transformers/features/stringifiers/ValidateStringifyTransformer.ts +38 -38
  142. package/src/transformers/features/validators/AssertTransformer.ts +43 -43
  143. package/src/transformers/features/validators/CreateAssertTransformer.ts +35 -35
  144. package/src/transformers/features/validators/CreateIsTransformer.ts +35 -35
  145. package/src/transformers/features/validators/CreateValidateTransformer.ts +35 -35
  146. package/src/transformers/features/validators/IsTransformer.ts +43 -43
  147. package/src/transformers/features/validators/ValidateTransformer.ts +43 -43
  148. package/src/typings/Atomic.ts +17 -17
  149. package/src/typings/ClassProperties.ts +5 -5
  150. package/src/typings/OmitNever.ts +3 -3
  151. package/src/typings/SpecialFields.ts +3 -3
  152. package/src/typings/Writable.ts +11 -11
  153. package/src/utils/ArrayUtil.ts +49 -49
  154. package/src/utils/Escaper.ts +50 -50
  155. package/src/utils/MapUtil.ts +14 -14
  156. package/src/utils/PatternUtil.ts +30 -30
  157. package/src/utils/Singleton.ts +17 -17
@@ -1,437 +1,437 @@
1
- import ts from "typescript";
2
-
3
- import { ExpressionFactory } from "../../factories/ExpressionFactory";
4
- import { IdentifierFactory } from "../../factories/IdentifierFactory";
5
- import { StatementFactory } from "../../factories/StatementFactory";
6
-
7
- import { IMetadataTag } from "../../metadata/IMetadataTag";
8
- import { Metadata } from "../../metadata/Metadata";
9
- import { MetadataObject } from "../../metadata/MetadataObject";
10
-
11
- import { CheckerProgrammer } from "../CheckerProgrammer";
12
- import { FeatureProgrammer } from "../FeatureProgrammer";
13
- import { UnionPredicator } from "./UnionPredicator";
14
-
15
- export namespace UnionExplorer {
16
- export interface Decoder<T> {
17
- (
18
- input: ts.Expression,
19
- target: T,
20
- explore: FeatureProgrammer.IExplore,
21
- tags: IMetadataTag[],
22
- ): ts.Expression;
23
- }
24
- export type ObjectCombiner = Decoder<MetadataObject[]>;
25
-
26
- export function object(
27
- config: FeatureProgrammer.IConfig,
28
- level: number = 0,
29
- ) {
30
- return function (
31
- input: ts.Expression,
32
- targets: MetadataObject[],
33
- explore: FeatureProgrammer.IExplore,
34
- tags: IMetadataTag[],
35
- ): ts.Expression {
36
- // BREAKER
37
- if (targets.length === 1)
38
- return config.objector.decoder(
39
- input,
40
- targets[0]!,
41
- explore,
42
- tags,
43
- );
44
-
45
- const expected: string = `(${targets
46
- .map((t) => t.name)
47
- .join(" | ")})`;
48
-
49
- // POSSIBLE TO SPECIALIZE?
50
- const specList = UnionPredicator.object(targets);
51
- if (specList.length === 0) {
52
- const condition: ts.Expression = config.objector.unionizer(
53
- input,
54
- targets,
55
- {
56
- ...explore,
57
- tracable: false,
58
- },
59
- tags,
60
- );
61
- return config.objector.full
62
- ? config.objector.full(condition)(input, expected, explore)
63
- : condition;
64
- }
65
- const remained: MetadataObject[] = targets.filter(
66
- (t) => specList.find((s) => s.object === t) === undefined,
67
- );
68
-
69
- // DO SPECIALIZE
70
- const conditions: ts.IfStatement[] = specList
71
- .filter((spec) => spec.property.key.getSoleLiteral() !== null)
72
- .map((spec) => {
73
- const key: string = spec.property.key.getSoleLiteral()!;
74
- const accessor: ts.Expression = IdentifierFactory.join(
75
- input,
76
- key,
77
- );
78
- const pred: ts.Expression = spec.neighbour
79
- ? config.objector.checker(
80
- accessor,
81
- spec.property.value,
82
- {
83
- ...explore,
84
- tracable: false,
85
- postfix: IdentifierFactory.postfix(key),
86
- },
87
- tags,
88
- )
89
- : (config.objector.required || ((exp) => exp))(
90
- ExpressionFactory.isRequired(accessor),
91
- );
92
- return ts.factory.createIfStatement(
93
- (config.objector.is || ((exp) => exp))(pred),
94
- ts.factory.createReturnStatement(
95
- config.objector.decoder(
96
- input,
97
- spec.object,
98
- explore,
99
- tags,
100
- ),
101
- ),
102
- );
103
- });
104
-
105
- // RETURNS WITH CONDITIONS
106
- return ts.factory.createCallExpression(
107
- ts.factory.createArrowFunction(
108
- undefined,
109
- undefined,
110
- [],
111
- undefined,
112
- undefined,
113
- ts.factory.createBlock(
114
- [
115
- ...conditions,
116
- remained.length
117
- ? ts.factory.createReturnStatement(
118
- object(config, level + 1)(
119
- input,
120
- remained,
121
- explore,
122
- tags,
123
- ),
124
- )
125
- : config.objector.failure(
126
- input,
127
- expected,
128
- explore,
129
- ),
130
- ],
131
- true,
132
- ),
133
- ),
134
- undefined,
135
- undefined,
136
- );
137
- };
138
- }
139
-
140
- export const array = (props: array.IProps) =>
141
- iterate<Metadata>({
142
- size: (input) => IdentifierFactory.join(input, "length"),
143
- front: (input) =>
144
- ts.factory.createElementAccessExpression(input, 0),
145
- array: (input) => input,
146
- name: (t) => `Array<${t.getName()}>`,
147
- })(props);
148
- export namespace array {
149
- export type IProps = iterate.IProps<Metadata>;
150
- }
151
-
152
- export const set = (props: set.IProps) =>
153
- iterate<Metadata>({
154
- size: (input) => IdentifierFactory.join(input, "size"),
155
- front: (input) =>
156
- IdentifierFactory.join(
157
- ts.factory.createCallExpression(
158
- IdentifierFactory.join(
159
- ts.factory.createCallExpression(
160
- IdentifierFactory.join(input, "values"),
161
- undefined,
162
- undefined,
163
- ),
164
- "next",
165
- ),
166
- undefined,
167
- undefined,
168
- ),
169
- "value",
170
- ),
171
- array: (input) =>
172
- ts.factory.createArrayLiteralExpression(
173
- [ts.factory.createSpreadElement(input)],
174
- false,
175
- ),
176
- name: (t) => `Set<${t.getName()}>`,
177
- })(props);
178
- export namespace set {
179
- export type IProps = iterate.IProps<Metadata>;
180
- }
181
-
182
- export const map = (props: map.IProps) =>
183
- iterate<[Metadata, Metadata]>({
184
- size: (input) => IdentifierFactory.join(input, "size"),
185
- front: (input) =>
186
- IdentifierFactory.join(
187
- ts.factory.createCallExpression(
188
- IdentifierFactory.join(
189
- ts.factory.createCallExpression(
190
- IdentifierFactory.join(input, "entries"),
191
- undefined,
192
- undefined,
193
- ),
194
- "next",
195
- ),
196
- undefined,
197
- undefined,
198
- ),
199
- "value",
200
- ),
201
- array: (input) =>
202
- ts.factory.createArrayLiteralExpression(
203
- [ts.factory.createSpreadElement(input)],
204
- false,
205
- ),
206
- name: ([k, v]) => `Map<${k.getName()}, ${v.getName()}>`,
207
- })(props);
208
-
209
- export namespace map {
210
- export type IProps = iterate.IProps<[Metadata, Metadata]>;
211
- }
212
-
213
- const iterate =
214
- <T>(accessor: iterate.IAccessor<T>) =>
215
- (props: iterate.IProps<T>) =>
216
- (
217
- input: ts.Expression,
218
- targets: T[],
219
- explore: FeatureProgrammer.IExplore,
220
- tags: IMetadataTag[],
221
- ): ts.Expression => {
222
- if (targets.length === 1)
223
- return props.decoder(
224
- accessor.array(input),
225
- targets[0]!,
226
- explore,
227
- tags,
228
- );
229
-
230
- //----
231
- // LIST UP VARIABLES
232
- //----
233
- // TUPLES
234
- const tupleListVariable: ts.VariableStatement =
235
- StatementFactory.constant(
236
- "tupleList",
237
- ts.factory.createArrayLiteralExpression(
238
- targets.map((meta) =>
239
- ts.factory.createArrayLiteralExpression([
240
- ts.factory.createArrowFunction(
241
- undefined,
242
- undefined,
243
- [IdentifierFactory.parameter("branch")],
244
- undefined,
245
- undefined,
246
- props.checker(
247
- ts.factory.createIdentifier("branch"),
248
- meta,
249
- {
250
- ...explore,
251
- tracable: false,
252
- postfix: `"[0]"`,
253
- },
254
- tags,
255
- ),
256
- ),
257
- ts.factory.createArrowFunction(
258
- undefined,
259
- undefined,
260
- [IdentifierFactory.parameter("branch")],
261
- undefined,
262
- undefined,
263
- props.decoder(
264
- ts.factory.createIdentifier("branch"),
265
- meta,
266
- {
267
- ...explore,
268
- tracable: true,
269
- },
270
- tags,
271
- ),
272
- ),
273
- ]),
274
- ),
275
- ),
276
- );
277
-
278
- // FILTERED TUPLES
279
- const filteredVariable = StatementFactory.constant(
280
- "filtered",
281
- ts.factory.createCallExpression(
282
- ts.factory.createIdentifier("tupleList.filter"),
283
- undefined,
284
- [
285
- ts.factory.createArrowFunction(
286
- undefined,
287
- undefined,
288
- [IdentifierFactory.parameter("tuple")],
289
- undefined,
290
- undefined,
291
- ts.factory.createStrictEquality(
292
- props.success,
293
- ts.factory.createCallExpression(
294
- ts.factory.createIdentifier("tuple[0]"),
295
- undefined,
296
- [ts.factory.createIdentifier("front")],
297
- ),
298
- ),
299
- ),
300
- ],
301
- ),
302
- );
303
-
304
- //----
305
- // STATEMENTS
306
- //----
307
- // ONLY ONE TYPE
308
- const uniqueStatement = ts.factory.createIfStatement(
309
- ts.factory.createStrictEquality(
310
- ts.factory.createNumericLiteral(1),
311
- ts.factory.createIdentifier("filtered.length"),
312
- ),
313
- ts.factory.createReturnStatement(
314
- ts.factory.createCallExpression(
315
- ts.factory.createIdentifier(`filtered[0][1]`),
316
- undefined,
317
- [accessor.array(input)],
318
- ),
319
- ),
320
- );
321
-
322
- // UNION TYPE
323
- const forOfStatement = ts.factory.createForOfStatement(
324
- undefined,
325
- ts.factory.createVariableDeclarationList(
326
- [ts.factory.createVariableDeclaration("tuple")],
327
- ts.NodeFlags.Const,
328
- ),
329
- // StatementFactory.variable(ts.NodeFlags.Const, "tuple"),
330
- ts.factory.createIdentifier("filtered"),
331
- ts.factory.createIfStatement(
332
- ts.factory.createCallExpression(
333
- IdentifierFactory.join(
334
- ts.factory.createIdentifier("array"),
335
- "every",
336
- ),
337
- undefined,
338
- [
339
- ts.factory.createArrowFunction(
340
- undefined,
341
- undefined,
342
- [IdentifierFactory.parameter("value")],
343
- undefined,
344
- undefined,
345
- ts.factory.createStrictEquality(
346
- props.success,
347
- ts.factory.createCallExpression(
348
- ts.factory.createIdentifier("tuple[0]"),
349
- undefined,
350
- [ts.factory.createIdentifier("value")],
351
- ),
352
- ),
353
- ),
354
- ],
355
- ),
356
- ts.factory.createReturnStatement(
357
- ts.factory.createCallExpression(
358
- ts.factory.createIdentifier(`tuple[1]`),
359
- undefined,
360
- [ts.factory.createIdentifier("array")],
361
- ),
362
- ),
363
- ),
364
- );
365
- const unionStatement = ts.factory.createIfStatement(
366
- ts.factory.createLessThan(
367
- ts.factory.createNumericLiteral(1),
368
- ts.factory.createIdentifier("filtered.length"),
369
- ),
370
- forOfStatement,
371
- );
372
-
373
- const block = [
374
- // ARRAY.LENGTH := 0
375
- ts.factory.createIfStatement(
376
- ts.factory.createStrictEquality(
377
- ts.factory.createNumericLiteral(0),
378
- accessor.size(input),
379
- ),
380
- ts.factory.createReturnStatement(props.empty),
381
- ),
382
-
383
- // UNION PREDICATORS
384
- tupleListVariable,
385
- StatementFactory.constant("front", accessor.front(input)),
386
- filteredVariable,
387
- uniqueStatement,
388
-
389
- // CONDITIONAL STATEMENTS
390
- StatementFactory.constant("array", accessor.array(input)),
391
- unionStatement,
392
- props.failure(
393
- input,
394
- `(${targets.map((t) => accessor.name(t)).join(" | ")})`,
395
- explore,
396
- ),
397
- ];
398
-
399
- return ts.factory.createCallExpression(
400
- ts.factory.createArrowFunction(
401
- undefined,
402
- undefined,
403
- [],
404
- undefined,
405
- undefined,
406
- ts.factory.createBlock(block, true),
407
- ),
408
- undefined,
409
- undefined,
410
- );
411
- };
412
- namespace iterate {
413
- export interface IProps<T> {
414
- checker(
415
- input: ts.Expression,
416
- target: T,
417
- explore: FeatureProgrammer.IExplore,
418
- tags: IMetadataTag[],
419
- ): ts.Expression;
420
- decoder: Decoder<T>;
421
- empty: ts.Expression;
422
- success: ts.Expression;
423
- failure(
424
- input: ts.Expression,
425
- expected: string,
426
- explore: CheckerProgrammer.IExplore,
427
- ): ts.Statement;
428
- }
429
-
430
- export interface IAccessor<T> {
431
- name(metadata: T): string;
432
- size(input: ts.Expression): ts.Expression;
433
- front(input: ts.Expression): ts.Expression;
434
- array(input: ts.Expression): ts.Expression;
435
- }
436
- }
437
- }
1
+ import ts from "typescript";
2
+
3
+ import { ExpressionFactory } from "../../factories/ExpressionFactory";
4
+ import { IdentifierFactory } from "../../factories/IdentifierFactory";
5
+ import { StatementFactory } from "../../factories/StatementFactory";
6
+
7
+ import { IMetadataTag } from "../../metadata/IMetadataTag";
8
+ import { Metadata } from "../../metadata/Metadata";
9
+ import { MetadataObject } from "../../metadata/MetadataObject";
10
+
11
+ import { CheckerProgrammer } from "../CheckerProgrammer";
12
+ import { FeatureProgrammer } from "../FeatureProgrammer";
13
+ import { UnionPredicator } from "./UnionPredicator";
14
+
15
+ export namespace UnionExplorer {
16
+ export interface Decoder<T> {
17
+ (
18
+ input: ts.Expression,
19
+ target: T,
20
+ explore: FeatureProgrammer.IExplore,
21
+ tags: IMetadataTag[],
22
+ ): ts.Expression;
23
+ }
24
+ export type ObjectCombiner = Decoder<MetadataObject[]>;
25
+
26
+ export function object(
27
+ config: FeatureProgrammer.IConfig,
28
+ level: number = 0,
29
+ ) {
30
+ return function (
31
+ input: ts.Expression,
32
+ targets: MetadataObject[],
33
+ explore: FeatureProgrammer.IExplore,
34
+ tags: IMetadataTag[],
35
+ ): ts.Expression {
36
+ // BREAKER
37
+ if (targets.length === 1)
38
+ return config.objector.decoder(
39
+ input,
40
+ targets[0]!,
41
+ explore,
42
+ tags,
43
+ );
44
+
45
+ const expected: string = `(${targets
46
+ .map((t) => t.name)
47
+ .join(" | ")})`;
48
+
49
+ // POSSIBLE TO SPECIALIZE?
50
+ const specList = UnionPredicator.object(targets);
51
+ if (specList.length === 0) {
52
+ const condition: ts.Expression = config.objector.unionizer(
53
+ input,
54
+ targets,
55
+ {
56
+ ...explore,
57
+ tracable: false,
58
+ },
59
+ tags,
60
+ );
61
+ return config.objector.full
62
+ ? config.objector.full(condition)(input, expected, explore)
63
+ : condition;
64
+ }
65
+ const remained: MetadataObject[] = targets.filter(
66
+ (t) => specList.find((s) => s.object === t) === undefined,
67
+ );
68
+
69
+ // DO SPECIALIZE
70
+ const conditions: ts.IfStatement[] = specList
71
+ .filter((spec) => spec.property.key.getSoleLiteral() !== null)
72
+ .map((spec) => {
73
+ const key: string = spec.property.key.getSoleLiteral()!;
74
+ const accessor: ts.Expression = IdentifierFactory.join(
75
+ input,
76
+ key,
77
+ );
78
+ const pred: ts.Expression = spec.neighbour
79
+ ? config.objector.checker(
80
+ accessor,
81
+ spec.property.value,
82
+ {
83
+ ...explore,
84
+ tracable: false,
85
+ postfix: IdentifierFactory.postfix(key),
86
+ },
87
+ tags,
88
+ )
89
+ : (config.objector.required || ((exp) => exp))(
90
+ ExpressionFactory.isRequired(accessor),
91
+ );
92
+ return ts.factory.createIfStatement(
93
+ (config.objector.is || ((exp) => exp))(pred),
94
+ ts.factory.createReturnStatement(
95
+ config.objector.decoder(
96
+ input,
97
+ spec.object,
98
+ explore,
99
+ tags,
100
+ ),
101
+ ),
102
+ );
103
+ });
104
+
105
+ // RETURNS WITH CONDITIONS
106
+ return ts.factory.createCallExpression(
107
+ ts.factory.createArrowFunction(
108
+ undefined,
109
+ undefined,
110
+ [],
111
+ undefined,
112
+ undefined,
113
+ ts.factory.createBlock(
114
+ [
115
+ ...conditions,
116
+ remained.length
117
+ ? ts.factory.createReturnStatement(
118
+ object(config, level + 1)(
119
+ input,
120
+ remained,
121
+ explore,
122
+ tags,
123
+ ),
124
+ )
125
+ : config.objector.failure(
126
+ input,
127
+ expected,
128
+ explore,
129
+ ),
130
+ ],
131
+ true,
132
+ ),
133
+ ),
134
+ undefined,
135
+ undefined,
136
+ );
137
+ };
138
+ }
139
+
140
+ export const array = (props: array.IProps) =>
141
+ iterate<Metadata>({
142
+ size: (input) => IdentifierFactory.join(input, "length"),
143
+ front: (input) =>
144
+ ts.factory.createElementAccessExpression(input, 0),
145
+ array: (input) => input,
146
+ name: (t) => `Array<${t.getName()}>`,
147
+ })(props);
148
+ export namespace array {
149
+ export type IProps = iterate.IProps<Metadata>;
150
+ }
151
+
152
+ export const set = (props: set.IProps) =>
153
+ iterate<Metadata>({
154
+ size: (input) => IdentifierFactory.join(input, "size"),
155
+ front: (input) =>
156
+ IdentifierFactory.join(
157
+ ts.factory.createCallExpression(
158
+ IdentifierFactory.join(
159
+ ts.factory.createCallExpression(
160
+ IdentifierFactory.join(input, "values"),
161
+ undefined,
162
+ undefined,
163
+ ),
164
+ "next",
165
+ ),
166
+ undefined,
167
+ undefined,
168
+ ),
169
+ "value",
170
+ ),
171
+ array: (input) =>
172
+ ts.factory.createArrayLiteralExpression(
173
+ [ts.factory.createSpreadElement(input)],
174
+ false,
175
+ ),
176
+ name: (t) => `Set<${t.getName()}>`,
177
+ })(props);
178
+ export namespace set {
179
+ export type IProps = iterate.IProps<Metadata>;
180
+ }
181
+
182
+ export const map = (props: map.IProps) =>
183
+ iterate<[Metadata, Metadata]>({
184
+ size: (input) => IdentifierFactory.join(input, "size"),
185
+ front: (input) =>
186
+ IdentifierFactory.join(
187
+ ts.factory.createCallExpression(
188
+ IdentifierFactory.join(
189
+ ts.factory.createCallExpression(
190
+ IdentifierFactory.join(input, "entries"),
191
+ undefined,
192
+ undefined,
193
+ ),
194
+ "next",
195
+ ),
196
+ undefined,
197
+ undefined,
198
+ ),
199
+ "value",
200
+ ),
201
+ array: (input) =>
202
+ ts.factory.createArrayLiteralExpression(
203
+ [ts.factory.createSpreadElement(input)],
204
+ false,
205
+ ),
206
+ name: ([k, v]) => `Map<${k.getName()}, ${v.getName()}>`,
207
+ })(props);
208
+
209
+ export namespace map {
210
+ export type IProps = iterate.IProps<[Metadata, Metadata]>;
211
+ }
212
+
213
+ const iterate =
214
+ <T>(accessor: iterate.IAccessor<T>) =>
215
+ (props: iterate.IProps<T>) =>
216
+ (
217
+ input: ts.Expression,
218
+ targets: T[],
219
+ explore: FeatureProgrammer.IExplore,
220
+ tags: IMetadataTag[],
221
+ ): ts.Expression => {
222
+ if (targets.length === 1)
223
+ return props.decoder(
224
+ accessor.array(input),
225
+ targets[0]!,
226
+ explore,
227
+ tags,
228
+ );
229
+
230
+ //----
231
+ // LIST UP VARIABLES
232
+ //----
233
+ // TUPLES
234
+ const tupleListVariable: ts.VariableStatement =
235
+ StatementFactory.constant(
236
+ "tupleList",
237
+ ts.factory.createArrayLiteralExpression(
238
+ targets.map((meta) =>
239
+ ts.factory.createArrayLiteralExpression([
240
+ ts.factory.createArrowFunction(
241
+ undefined,
242
+ undefined,
243
+ [IdentifierFactory.parameter("branch")],
244
+ undefined,
245
+ undefined,
246
+ props.checker(
247
+ ts.factory.createIdentifier("branch"),
248
+ meta,
249
+ {
250
+ ...explore,
251
+ tracable: false,
252
+ postfix: `"[0]"`,
253
+ },
254
+ tags,
255
+ ),
256
+ ),
257
+ ts.factory.createArrowFunction(
258
+ undefined,
259
+ undefined,
260
+ [IdentifierFactory.parameter("branch")],
261
+ undefined,
262
+ undefined,
263
+ props.decoder(
264
+ ts.factory.createIdentifier("branch"),
265
+ meta,
266
+ {
267
+ ...explore,
268
+ tracable: true,
269
+ },
270
+ tags,
271
+ ),
272
+ ),
273
+ ]),
274
+ ),
275
+ ),
276
+ );
277
+
278
+ // FILTERED TUPLES
279
+ const filteredVariable = StatementFactory.constant(
280
+ "filtered",
281
+ ts.factory.createCallExpression(
282
+ ts.factory.createIdentifier("tupleList.filter"),
283
+ undefined,
284
+ [
285
+ ts.factory.createArrowFunction(
286
+ undefined,
287
+ undefined,
288
+ [IdentifierFactory.parameter("tuple")],
289
+ undefined,
290
+ undefined,
291
+ ts.factory.createStrictEquality(
292
+ props.success,
293
+ ts.factory.createCallExpression(
294
+ ts.factory.createIdentifier("tuple[0]"),
295
+ undefined,
296
+ [ts.factory.createIdentifier("front")],
297
+ ),
298
+ ),
299
+ ),
300
+ ],
301
+ ),
302
+ );
303
+
304
+ //----
305
+ // STATEMENTS
306
+ //----
307
+ // ONLY ONE TYPE
308
+ const uniqueStatement = ts.factory.createIfStatement(
309
+ ts.factory.createStrictEquality(
310
+ ts.factory.createNumericLiteral(1),
311
+ ts.factory.createIdentifier("filtered.length"),
312
+ ),
313
+ ts.factory.createReturnStatement(
314
+ ts.factory.createCallExpression(
315
+ ts.factory.createIdentifier(`filtered[0][1]`),
316
+ undefined,
317
+ [accessor.array(input)],
318
+ ),
319
+ ),
320
+ );
321
+
322
+ // UNION TYPE
323
+ const forOfStatement = ts.factory.createForOfStatement(
324
+ undefined,
325
+ ts.factory.createVariableDeclarationList(
326
+ [ts.factory.createVariableDeclaration("tuple")],
327
+ ts.NodeFlags.Const,
328
+ ),
329
+ // StatementFactory.variable(ts.NodeFlags.Const, "tuple"),
330
+ ts.factory.createIdentifier("filtered"),
331
+ ts.factory.createIfStatement(
332
+ ts.factory.createCallExpression(
333
+ IdentifierFactory.join(
334
+ ts.factory.createIdentifier("array"),
335
+ "every",
336
+ ),
337
+ undefined,
338
+ [
339
+ ts.factory.createArrowFunction(
340
+ undefined,
341
+ undefined,
342
+ [IdentifierFactory.parameter("value")],
343
+ undefined,
344
+ undefined,
345
+ ts.factory.createStrictEquality(
346
+ props.success,
347
+ ts.factory.createCallExpression(
348
+ ts.factory.createIdentifier("tuple[0]"),
349
+ undefined,
350
+ [ts.factory.createIdentifier("value")],
351
+ ),
352
+ ),
353
+ ),
354
+ ],
355
+ ),
356
+ ts.factory.createReturnStatement(
357
+ ts.factory.createCallExpression(
358
+ ts.factory.createIdentifier(`tuple[1]`),
359
+ undefined,
360
+ [ts.factory.createIdentifier("array")],
361
+ ),
362
+ ),
363
+ ),
364
+ );
365
+ const unionStatement = ts.factory.createIfStatement(
366
+ ts.factory.createLessThan(
367
+ ts.factory.createNumericLiteral(1),
368
+ ts.factory.createIdentifier("filtered.length"),
369
+ ),
370
+ forOfStatement,
371
+ );
372
+
373
+ const block = [
374
+ // ARRAY.LENGTH := 0
375
+ ts.factory.createIfStatement(
376
+ ts.factory.createStrictEquality(
377
+ ts.factory.createNumericLiteral(0),
378
+ accessor.size(input),
379
+ ),
380
+ ts.factory.createReturnStatement(props.empty),
381
+ ),
382
+
383
+ // UNION PREDICATORS
384
+ tupleListVariable,
385
+ StatementFactory.constant("front", accessor.front(input)),
386
+ filteredVariable,
387
+ uniqueStatement,
388
+
389
+ // CONDITIONAL STATEMENTS
390
+ StatementFactory.constant("array", accessor.array(input)),
391
+ unionStatement,
392
+ props.failure(
393
+ input,
394
+ `(${targets.map((t) => accessor.name(t)).join(" | ")})`,
395
+ explore,
396
+ ),
397
+ ];
398
+
399
+ return ts.factory.createCallExpression(
400
+ ts.factory.createArrowFunction(
401
+ undefined,
402
+ undefined,
403
+ [],
404
+ undefined,
405
+ undefined,
406
+ ts.factory.createBlock(block, true),
407
+ ),
408
+ undefined,
409
+ undefined,
410
+ );
411
+ };
412
+ namespace iterate {
413
+ export interface IProps<T> {
414
+ checker(
415
+ input: ts.Expression,
416
+ target: T,
417
+ explore: FeatureProgrammer.IExplore,
418
+ tags: IMetadataTag[],
419
+ ): ts.Expression;
420
+ decoder: Decoder<T>;
421
+ empty: ts.Expression;
422
+ success: ts.Expression;
423
+ failure(
424
+ input: ts.Expression,
425
+ expected: string,
426
+ explore: CheckerProgrammer.IExplore,
427
+ ): ts.Statement;
428
+ }
429
+
430
+ export interface IAccessor<T> {
431
+ name(metadata: T): string;
432
+ size(input: ts.Expression): ts.Expression;
433
+ front(input: ts.Expression): ts.Expression;
434
+ array(input: ts.Expression): ts.Expression;
435
+ }
436
+ }
437
+ }