typia 3.4.6 → 3.4.8

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 (130) hide show
  1. package/README.md +12 -2
  2. package/lib/executable/internal/CommandParser.d.ts +3 -0
  3. package/lib/executable/internal/CommandParser.js +21 -0
  4. package/lib/executable/internal/CommandParser.js.map +1 -0
  5. package/lib/executable/internal/TypiaSetupWizard.d.ts +2 -2
  6. package/lib/executable/internal/TypiaSetupWizard.js +57 -35
  7. package/lib/executable/internal/TypiaSetupWizard.js.map +1 -1
  8. package/lib/executable/typia.js +22 -21
  9. package/lib/executable/typia.js.map +1 -1
  10. package/lib/factories/internal/iterate_metadata.js +1 -1
  11. package/lib/factories/internal/iterate_metadata.js.map +1 -1
  12. package/lib/factories/internal/iterate_metadata_tuple.d.ts +1 -1
  13. package/lib/factories/internal/iterate_metadata_tuple.js +5 -13
  14. package/lib/factories/internal/iterate_metadata_tuple.js.map +1 -1
  15. package/package.json +2 -2
  16. package/src/IValidation.ts +21 -21
  17. package/src/Primitive.ts +82 -82
  18. package/src/TypeGuardError.ts +36 -36
  19. package/src/executable/internal/CommandParser.ts +15 -0
  20. package/src/executable/internal/TypiaSetupWizard.ts +108 -87
  21. package/src/executable/typia.ts +25 -14
  22. package/src/factories/CommentFactory.ts +10 -10
  23. package/src/factories/ExpressionFactory.ts +52 -52
  24. package/src/factories/IdentifierFactory.ts +72 -72
  25. package/src/factories/LiteralFactory.ts +44 -44
  26. package/src/factories/MetadataCollection.ts +122 -122
  27. package/src/factories/MetadataFactory.ts +46 -46
  28. package/src/factories/StatementFactory.ts +60 -60
  29. package/src/factories/TemplateFactory.ts +56 -56
  30. package/src/factories/TypeFactory.ts +101 -101
  31. package/src/factories/ValueFactory.ts +12 -12
  32. package/src/factories/internal/MetadataHelper.ts +12 -12
  33. package/src/factories/internal/emplace_metadata_object.ts +140 -140
  34. package/src/factories/internal/explore_metadata.ts +91 -91
  35. package/src/factories/internal/iterate_metadata.ts +1 -2
  36. package/src/factories/internal/iterate_metadata_array.ts +29 -29
  37. package/src/factories/internal/iterate_metadata_atomic.ts +59 -59
  38. package/src/factories/internal/iterate_metadata_coalesce.ts +33 -33
  39. package/src/factories/internal/iterate_metadata_constant.ts +58 -58
  40. package/src/factories/internal/iterate_metadata_map.ts +41 -41
  41. package/src/factories/internal/iterate_metadata_object.ts +45 -45
  42. package/src/factories/internal/iterate_metadata_resolve.ts +27 -27
  43. package/src/factories/internal/iterate_metadata_set.ts +33 -33
  44. package/src/factories/internal/iterate_metadata_template.ts +38 -38
  45. package/src/factories/internal/iterate_metadata_tuple.ts +45 -51
  46. package/src/factories/internal/iterate_metadata_union.ts +59 -59
  47. package/src/functional/$every.ts +11 -11
  48. package/src/functional/$guard.ts +35 -35
  49. package/src/functional/$is_email.ts +5 -5
  50. package/src/functional/$is_ipv4.ts +5 -5
  51. package/src/functional/$is_ipv6.ts +5 -5
  52. package/src/functional/$is_url.ts +5 -5
  53. package/src/functional/$is_uuid.ts +5 -5
  54. package/src/functional/$join.ts +50 -50
  55. package/src/functional/$report.ts +15 -15
  56. package/src/functional/$rest.ts +3 -3
  57. package/src/functional/$string.ts +37 -37
  58. package/src/functional/$tail.ts +6 -6
  59. package/src/metadata/IJsDocTagInfo.ts +10 -10
  60. package/src/metadata/IMetadata.ts +25 -25
  61. package/src/metadata/IMetadataApplication.ts +7 -7
  62. package/src/metadata/IMetadataConstant.ts +16 -16
  63. package/src/metadata/IMetadataEntry.ts +6 -6
  64. package/src/metadata/IMetadataObject.ts +29 -29
  65. package/src/metadata/IMetadataProperty.ts +11 -11
  66. package/src/metadata/IMetadataTag.ts +122 -122
  67. package/src/metadata/Metadata.ts +477 -477
  68. package/src/metadata/MetadataConstant.ts +3 -3
  69. package/src/metadata/MetadataObject.ts +131 -131
  70. package/src/metadata/MetadataProperty.ts +64 -64
  71. package/src/programmers/AssertParseProgrammer.ts +45 -45
  72. package/src/programmers/AssertProgrammer.ts +444 -444
  73. package/src/programmers/AssertStringifyProgrammer.ts +45 -45
  74. package/src/programmers/CheckerProgrammer.ts +798 -798
  75. package/src/programmers/FeatureProgrammer.ts +327 -327
  76. package/src/programmers/IsParseProgrammer.ts +51 -51
  77. package/src/programmers/IsProgrammer.ts +169 -169
  78. package/src/programmers/IsStringifyProgrammer.ts +49 -49
  79. package/src/programmers/ValidateParseProgrammer.ts +49 -49
  80. package/src/programmers/ValidateProgrammer.ts +236 -236
  81. package/src/programmers/ValidateStringifyProgrammer.ts +60 -60
  82. package/src/programmers/helpers/AtomicPredicator.ts +15 -15
  83. package/src/programmers/helpers/FunctionImporeter.ts +31 -31
  84. package/src/programmers/helpers/IExpressionEntry.ts +10 -10
  85. package/src/programmers/helpers/OptionPredicator.ts +18 -18
  86. package/src/programmers/helpers/StringifyJoinder.ts +111 -111
  87. package/src/programmers/helpers/StringifyPredicator.ts +18 -18
  88. package/src/programmers/helpers/UnionExplorer.ts +437 -437
  89. package/src/programmers/helpers/UnionPredicator.ts +81 -81
  90. package/src/programmers/internal/application_boolean.ts +17 -17
  91. package/src/programmers/internal/application_constant.ts +29 -29
  92. package/src/programmers/internal/application_default_string.ts +32 -32
  93. package/src/programmers/internal/application_native.ts +29 -29
  94. package/src/programmers/internal/application_schema.ts +221 -221
  95. package/src/programmers/internal/application_templates.ts +27 -27
  96. package/src/programmers/internal/application_tuple.ts +25 -25
  97. package/src/programmers/internal/check_array.ts +44 -44
  98. package/src/programmers/internal/check_dynamic_properties.ts +146 -146
  99. package/src/programmers/internal/check_everything.ts +25 -25
  100. package/src/programmers/internal/check_length.ts +46 -46
  101. package/src/programmers/internal/check_native.ts +9 -9
  102. package/src/programmers/internal/check_number.ts +181 -181
  103. package/src/programmers/internal/check_object.ts +42 -42
  104. package/src/programmers/internal/check_string.ts +24 -24
  105. package/src/programmers/internal/check_string_tags.ts +63 -63
  106. package/src/programmers/internal/check_template.ts +50 -50
  107. package/src/programmers/internal/decode_union_object.ts +73 -73
  108. package/src/programmers/internal/feature_object_entries.ts +49 -49
  109. package/src/programmers/internal/metadata_to_pattern.ts +31 -31
  110. package/src/programmers/internal/stringify_dynamic_properties.ts +164 -164
  111. package/src/programmers/internal/stringify_native.ts +8 -8
  112. package/src/programmers/internal/stringify_regular_properties.ts +81 -81
  113. package/src/programmers/internal/template_to_pattern.ts +15 -15
  114. package/src/schemas/IJsonApplication.ts +9 -9
  115. package/src/transform.ts +20 -20
  116. package/src/transformers/ExpressionWithArgumentTransformer.ts +66 -66
  117. package/src/transformers/FileTransformer.ts +49 -49
  118. package/src/transformers/IProject.ts +11 -11
  119. package/src/transformers/ITransformOptions.ts +4 -4
  120. package/src/transformers/NodeTransformer.ts +19 -19
  121. package/src/typings/Atomic.ts +17 -17
  122. package/src/typings/ClassProperties.ts +5 -5
  123. package/src/typings/OmitNever.ts +3 -3
  124. package/src/typings/SpecialFields.ts +3 -3
  125. package/src/typings/Writable.ts +11 -11
  126. package/src/utils/ArrayUtil.ts +49 -49
  127. package/src/utils/Escaper.ts +50 -50
  128. package/src/utils/MapUtil.ts +14 -14
  129. package/src/utils/PatternUtil.ts +30 -30
  130. package/src/utils/Singleton.ts +17 -17
@@ -1,477 +1,477 @@
1
- import { Atomic } from "../typings/Atomic";
2
- import { ClassProperties } from "../typings/ClassProperties";
3
-
4
- import { IMetadata } from "./IMetadata";
5
- import { IMetadataObject } from "./IMetadataObject";
6
- import { MetadataConstant } from "./MetadataConstant";
7
- import { MetadataObject } from "./MetadataObject";
8
- import { MetadataProperty } from "./MetadataProperty";
9
-
10
- export class Metadata {
11
- public readonly any: boolean;
12
- public readonly required: boolean;
13
- public readonly nullable: boolean;
14
- public readonly functional: boolean;
15
-
16
- public readonly resolved: Metadata | null;
17
- public readonly atomics: Atomic.Literal[];
18
- public readonly constants: MetadataConstant[];
19
- public readonly templates: Metadata[][];
20
-
21
- public readonly rest: Metadata | null;
22
- public readonly arrays: Metadata[];
23
- public readonly tuples: Metadata[][];
24
- public readonly objects: MetadataObject[];
25
-
26
- public readonly natives: string[];
27
- public readonly sets: Metadata[];
28
- public readonly maps: Metadata.Entry[];
29
-
30
- /**
31
- * @internal
32
- */
33
- private name_: string | undefined = undefined;
34
-
35
- /**
36
- * @internal
37
- */
38
- private parent_resolved_: boolean = false;
39
-
40
- /**
41
- * @internal
42
- */
43
- public union_index?: number;
44
-
45
- /* -----------------------------------------------------------
46
- CONSTRUCTORS
47
- ----------------------------------------------------------- */
48
- /**
49
- * @hidden
50
- */
51
- private constructor(props: ClassProperties<Metadata>) {
52
- this.any = props.any;
53
- this.required = props.required;
54
- this.nullable = props.nullable;
55
- this.functional = props.functional;
56
-
57
- this.resolved = props.resolved;
58
- this.atomics = props.atomics;
59
- this.constants = props.constants;
60
- this.templates = props.templates;
61
-
62
- this.rest = props.rest;
63
- this.arrays = props.arrays;
64
- this.tuples = props.tuples;
65
- this.objects = props.objects;
66
-
67
- this.natives = props.natives;
68
- this.sets = props.sets;
69
- this.maps = props.maps;
70
- }
71
-
72
- /**
73
- * @internal
74
- */
75
- public static create(props: ClassProperties<Metadata>): Metadata {
76
- return new Metadata(props);
77
- }
78
-
79
- /**
80
- * @internal
81
- */
82
- public static initialize(parentResolved: boolean = false): Metadata {
83
- const meta: Metadata = this.create({
84
- any: false,
85
- nullable: false,
86
- required: true,
87
- functional: false,
88
-
89
- resolved: null,
90
- constants: [],
91
- atomics: [],
92
- templates: [],
93
- arrays: [],
94
- tuples: [],
95
- objects: [],
96
-
97
- rest: null,
98
- natives: [],
99
- sets: [],
100
- maps: [],
101
- });
102
- meta.parent_resolved_ = parentResolved;
103
- return meta;
104
- }
105
-
106
- public toJSON(): IMetadata {
107
- return {
108
- any: this.any,
109
- required: this.required,
110
- nullable: this.nullable,
111
- functional: this.functional,
112
-
113
- atomics: this.atomics.slice(),
114
- constants: JSON.parse(JSON.stringify(this.constants)),
115
- templates: this.templates.map((tpl) =>
116
- tpl.map((meta) => meta.toJSON()),
117
- ),
118
- resolved: this.resolved ? this.resolved.toJSON() : null,
119
-
120
- rest: this.rest ? this.rest.toJSON() : null,
121
- arrays: this.arrays.map((meta) => meta.toJSON()),
122
- tuples: this.tuples.map((meta) =>
123
- meta.map((meta) => meta.toJSON()),
124
- ),
125
- objects: this.objects.map((obj) => obj.name),
126
-
127
- natives: this.natives.slice(),
128
- sets: this.sets.map((meta) => meta.toJSON()),
129
- maps: this.maps.map((entry) => ({
130
- key: entry.key.toJSON(),
131
- value: entry.value.toJSON(),
132
- })),
133
- };
134
- }
135
-
136
- public static from(meta: IMetadata, objects: IMetadataObject[]): Metadata {
137
- const dict: Map<string, MetadataObject> = new Map();
138
- for (const obj of objects)
139
- dict.set(obj.name, MetadataObject._From_without_properties(obj));
140
-
141
- for (const obj of objects) {
142
- const initialized = dict.get(obj.name)!;
143
- initialized.properties.push(
144
- ...obj.properties.map((prop) =>
145
- MetadataProperty._From(prop, dict),
146
- ),
147
- );
148
- }
149
- return this._From(meta, dict);
150
- }
151
-
152
- /**
153
- * @internal
154
- */
155
- public static _From(
156
- meta: IMetadata,
157
- objects: Map<string, MetadataObject>,
158
- ): Metadata {
159
- return this.create({
160
- any: meta.any,
161
- required: meta.required,
162
- nullable: meta.nullable,
163
- functional: meta.functional,
164
-
165
- constants: JSON.parse(JSON.stringify(meta.constants)),
166
- atomics: meta.atomics.slice(),
167
- templates: meta.templates.map((tpl) =>
168
- tpl.map((meta) => this._From(meta, objects)),
169
- ),
170
- resolved: meta.resolved ? this._From(meta.resolved, objects) : null,
171
-
172
- rest: meta.rest ? this._From(meta.rest, objects) : null,
173
- arrays: meta.arrays.map((meta) => this._From(meta, objects)),
174
- tuples: meta.tuples.map((tuple) =>
175
- tuple.map((meta) => this._From(meta, objects)),
176
- ),
177
- objects: meta.objects.map((name) => {
178
- const found = objects.get(name);
179
- if (found === undefined)
180
- throw new Error(
181
- `Error on Metadata.from(): failed to find object "${name}".`,
182
- );
183
- return found;
184
- }),
185
-
186
- natives: meta.natives.slice(),
187
- sets: meta.sets.map((meta) => this._From(meta, objects)),
188
- maps: meta.maps.map((entry) => ({
189
- key: this._From(entry.key, objects),
190
- value: this._From(entry.value, objects),
191
- })),
192
- });
193
- }
194
-
195
- /* -----------------------------------------------------------
196
- ACCESSORS
197
- ----------------------------------------------------------- */
198
- public getName(): string {
199
- this.name_ ||= getName(this);
200
- return this.name_;
201
- }
202
-
203
- public empty(): boolean {
204
- return this.bucket() === 0 || this.size() === 0;
205
- }
206
- public size(): number {
207
- return (
208
- (this.resolved ? 1 : 0) +
209
- (this.functional ? 1 : 0) +
210
- this.templates.length +
211
- this.atomics.length +
212
- this.constants
213
- .map((c) => c.values.length)
214
- .reduce((x, y) => x + y, 0) +
215
- (this.rest ? this.rest.size() : 0) +
216
- this.arrays.length +
217
- this.tuples.length +
218
- this.objects.length +
219
- this.natives.length +
220
- this.sets.length +
221
- this.maps.length
222
- );
223
- }
224
- public bucket(): number {
225
- return (
226
- (this.resolved ? 1 : 0) +
227
- (this.functional ? 1 : 0) +
228
- (this.templates.length ? 1 : 0) +
229
- (this.atomics.length ? 1 : 0) +
230
- (this.constants.length ? 1 : 0) +
231
- (this.rest ? this.rest.size() : 0) +
232
- (this.arrays.length ? 1 : 0) +
233
- (this.tuples.length ? 1 : 0) +
234
- (this.objects.length ? 1 : 0) +
235
- (this.natives.length ? 1 : 0) +
236
- (this.sets.length ? 1 : 0) +
237
- (this.maps.length ? 1 : 0)
238
- );
239
- }
240
- public isConstant(): boolean {
241
- return this.bucket() === (this.constants.length ? 1 : 0);
242
- }
243
-
244
- /**
245
- * @internal
246
- */
247
- public isUnionBucket(): boolean {
248
- const size: number = this.bucket();
249
- const emended: number = this.constants.length ? size - 1 : size;
250
- return emended > 1;
251
- }
252
-
253
- /**
254
- * @internal
255
- */
256
- public getSoleLiteral(): string | null {
257
- if (
258
- this.size() === 1 &&
259
- this.constants.length === 1 &&
260
- this.constants[0]!.type === "string" &&
261
- this.constants[0]!.values.length === 1
262
- )
263
- return this.constants[0]!.values[0] as string;
264
- else return null;
265
- }
266
-
267
- /**
268
- * @internal
269
- */
270
- public isSoleLiteral(): boolean {
271
- return this.getSoleLiteral() !== null;
272
- }
273
-
274
- /**
275
- * @internal
276
- */
277
- public isParentResolved(): boolean {
278
- return this.parent_resolved_;
279
- }
280
- }
281
- export namespace Metadata {
282
- export function intersects(
283
- x: Metadata,
284
- y: Metadata,
285
- deep: boolean,
286
- ): boolean {
287
- // CHECK ANY & OPTIONAL
288
- if (x.any || y.any) return true;
289
- if (x.required === false && false === y.required) return true;
290
- if (x.nullable === true && true === y.nullable) return true;
291
-
292
- //----
293
- // INSTANCES
294
- //----
295
- // ARRAYS AND OBJECTS
296
- if (deep === true) {
297
- for (const xa of x.arrays)
298
- for (const ya of y.arrays)
299
- if (intersects(xa, ya, deep)) {
300
- return true;
301
- }
302
- for (const xo of x.objects)
303
- for (const yo of y.objects)
304
- if (MetadataObject.intersects(xo, yo)) {
305
- return true;
306
- }
307
- } else {
308
- if (x.arrays.length && y.arrays.length) return true;
309
- if (x.objects.length && y.objects.length) return true;
310
- }
311
-
312
- // TUPLES
313
- for (const xt of x.tuples)
314
- for (const yt of y.tuples)
315
- if (
316
- xt
317
- .slice(0, Math.min(xt.length, yt.length))
318
- .some((xv, i) => intersects(xv, yt[i]!, deep))
319
- )
320
- return true;
321
-
322
- //----
323
- // VALUES
324
- //----
325
- // ATOMICS
326
- for (const atomic of x.atomics)
327
- if (y.atomics.includes(atomic)) return true;
328
-
329
- // CONSTANTS
330
- for (const constant of x.constants) {
331
- const opposite: MetadataConstant | undefined = y.constants.find(
332
- (elem) => elem.type === constant.type,
333
- );
334
- if (opposite === undefined) continue;
335
-
336
- const values: Set<any> = new Set([
337
- ...constant.values,
338
- ...opposite.values,
339
- ]);
340
- if (values.size !== constant.values.length + opposite.values.length)
341
- return true;
342
- }
343
-
344
- // FUNCTIONAL
345
- if (x.functional === true && y.functional === true) return true;
346
-
347
- return false;
348
- }
349
-
350
- export function covers(x: Metadata, y: Metadata): boolean {
351
- // CHECK ANY
352
- if (x.any) return true;
353
- else if (y.any) return false;
354
-
355
- //----
356
- // INSTANCES
357
- //----
358
- // ARRAYS
359
- for (const ya of y.arrays)
360
- if (x.arrays.some((xa) => covers(xa, ya) === true) === false)
361
- return false;
362
-
363
- // OBJECTS
364
- for (const yo of y.objects)
365
- if (x.objects.some((xo) => MetadataObject.covers(xo, yo)) === false)
366
- return false;
367
-
368
- // TUPLES
369
- for (const yt of y.tuples)
370
- if (
371
- x.tuples.some(
372
- (xt) =>
373
- xt.length >= yt.length &&
374
- xt
375
- .slice(yt.length)
376
- .every((xv, i) => covers(xv, yt[i]!)),
377
- ) === false
378
- )
379
- return false;
380
-
381
- // NATIVES
382
-
383
- // SETS
384
- for (const ys of y.sets)
385
- if (x.sets.some((xs) => covers(xs, ys)) === false) return false;
386
-
387
- //----
388
- // VALUES
389
- //----
390
- // ATOMICS
391
- if (y.atomics.some((atomic) => x.atomics.includes(atomic) === false))
392
- return false;
393
-
394
- // CONSTANTS
395
- for (const yc of y.constants) {
396
- const xc: MetadataConstant | undefined = x.constants.find(
397
- (elem) => elem.type === yc.type,
398
- );
399
- if (xc === undefined) return false;
400
- else if (
401
- (yc.values as number[]).some(
402
- (yv) => xc.values.includes(yv as never) === false,
403
- )
404
- )
405
- return false;
406
- }
407
-
408
- // FUNCTIONAL
409
- if (x.functional === false && y.functional) return false;
410
-
411
- // SUCCESS
412
- return true;
413
- }
414
- }
415
-
416
- function getName(metadata: Metadata): string {
417
- if (metadata.any === true) return "any";
418
-
419
- const elements: string[] = [];
420
-
421
- // OPTIONAL
422
- if (metadata.nullable === true) elements.push("null");
423
- if (metadata.required === false) elements.push("undefined");
424
-
425
- // ATOMIC
426
- for (const type of metadata.atomics) {
427
- elements.push(type);
428
- }
429
- for (const constant of metadata.constants)
430
- for (const value of constant.values)
431
- elements.push(JSON.stringify(value));
432
- for (const template of metadata.templates)
433
- elements.push(
434
- "`" +
435
- template
436
- .map((child) =>
437
- child.isConstant() && child.size() === 1
438
- ? child.constants[0]!.values[0]!
439
- : `$\{${child.getName()}\}`,
440
- )
441
- .join("")
442
- .split("`")
443
- .join("\\`") +
444
- "`",
445
- );
446
-
447
- // ARRAY
448
- if (metadata.rest !== null) elements.push(`...${metadata.rest.getName()}`);
449
- for (const tuple of metadata.tuples)
450
- elements.push(`[${tuple.map((elem) => elem.getName()).join(", ")}]`);
451
- for (const array of metadata.arrays)
452
- elements.push(`Array<${array.getName()}>`);
453
-
454
- // OBJECT
455
- for (const object of metadata.objects)
456
- elements.push(`Resolve<${object.name}>`);
457
- if (metadata.resolved !== null) elements.push(metadata.resolved.getName());
458
-
459
- // NATIVES
460
- for (const native of metadata.natives) elements.push(native);
461
- for (const set of metadata.sets) elements.push(`Set<${set.getName()}>`);
462
- for (const map of metadata.maps)
463
- elements.push(`Map<${map.key.getName()}, ${map.value.getName()}>`);
464
-
465
- // RETURNS
466
- if (elements.length === 0) return "unknown";
467
- else if (elements.length === 1) return elements[0]!;
468
-
469
- elements.sort();
470
- return `(${elements.join(" | ")})`;
471
- }
472
- export namespace Metadata {
473
- export interface Entry {
474
- key: Metadata;
475
- value: Metadata;
476
- }
477
- }
1
+ import { Atomic } from "../typings/Atomic";
2
+ import { ClassProperties } from "../typings/ClassProperties";
3
+
4
+ import { IMetadata } from "./IMetadata";
5
+ import { IMetadataObject } from "./IMetadataObject";
6
+ import { MetadataConstant } from "./MetadataConstant";
7
+ import { MetadataObject } from "./MetadataObject";
8
+ import { MetadataProperty } from "./MetadataProperty";
9
+
10
+ export class Metadata {
11
+ public readonly any: boolean;
12
+ public readonly required: boolean;
13
+ public readonly nullable: boolean;
14
+ public readonly functional: boolean;
15
+
16
+ public readonly resolved: Metadata | null;
17
+ public readonly atomics: Atomic.Literal[];
18
+ public readonly constants: MetadataConstant[];
19
+ public readonly templates: Metadata[][];
20
+
21
+ public readonly rest: Metadata | null;
22
+ public readonly arrays: Metadata[];
23
+ public readonly tuples: Metadata[][];
24
+ public readonly objects: MetadataObject[];
25
+
26
+ public readonly natives: string[];
27
+ public readonly sets: Metadata[];
28
+ public readonly maps: Metadata.Entry[];
29
+
30
+ /**
31
+ * @internal
32
+ */
33
+ private name_: string | undefined = undefined;
34
+
35
+ /**
36
+ * @internal
37
+ */
38
+ private parent_resolved_: boolean = false;
39
+
40
+ /**
41
+ * @internal
42
+ */
43
+ public union_index?: number;
44
+
45
+ /* -----------------------------------------------------------
46
+ CONSTRUCTORS
47
+ ----------------------------------------------------------- */
48
+ /**
49
+ * @hidden
50
+ */
51
+ private constructor(props: ClassProperties<Metadata>) {
52
+ this.any = props.any;
53
+ this.required = props.required;
54
+ this.nullable = props.nullable;
55
+ this.functional = props.functional;
56
+
57
+ this.resolved = props.resolved;
58
+ this.atomics = props.atomics;
59
+ this.constants = props.constants;
60
+ this.templates = props.templates;
61
+
62
+ this.rest = props.rest;
63
+ this.arrays = props.arrays;
64
+ this.tuples = props.tuples;
65
+ this.objects = props.objects;
66
+
67
+ this.natives = props.natives;
68
+ this.sets = props.sets;
69
+ this.maps = props.maps;
70
+ }
71
+
72
+ /**
73
+ * @internal
74
+ */
75
+ public static create(props: ClassProperties<Metadata>): Metadata {
76
+ return new Metadata(props);
77
+ }
78
+
79
+ /**
80
+ * @internal
81
+ */
82
+ public static initialize(parentResolved: boolean = false): Metadata {
83
+ const meta: Metadata = this.create({
84
+ any: false,
85
+ nullable: false,
86
+ required: true,
87
+ functional: false,
88
+
89
+ resolved: null,
90
+ constants: [],
91
+ atomics: [],
92
+ templates: [],
93
+ arrays: [],
94
+ tuples: [],
95
+ objects: [],
96
+
97
+ rest: null,
98
+ natives: [],
99
+ sets: [],
100
+ maps: [],
101
+ });
102
+ meta.parent_resolved_ = parentResolved;
103
+ return meta;
104
+ }
105
+
106
+ public toJSON(): IMetadata {
107
+ return {
108
+ any: this.any,
109
+ required: this.required,
110
+ nullable: this.nullable,
111
+ functional: this.functional,
112
+
113
+ atomics: this.atomics.slice(),
114
+ constants: JSON.parse(JSON.stringify(this.constants)),
115
+ templates: this.templates.map((tpl) =>
116
+ tpl.map((meta) => meta.toJSON()),
117
+ ),
118
+ resolved: this.resolved ? this.resolved.toJSON() : null,
119
+
120
+ rest: this.rest ? this.rest.toJSON() : null,
121
+ arrays: this.arrays.map((meta) => meta.toJSON()),
122
+ tuples: this.tuples.map((meta) =>
123
+ meta.map((meta) => meta.toJSON()),
124
+ ),
125
+ objects: this.objects.map((obj) => obj.name),
126
+
127
+ natives: this.natives.slice(),
128
+ sets: this.sets.map((meta) => meta.toJSON()),
129
+ maps: this.maps.map((entry) => ({
130
+ key: entry.key.toJSON(),
131
+ value: entry.value.toJSON(),
132
+ })),
133
+ };
134
+ }
135
+
136
+ public static from(meta: IMetadata, objects: IMetadataObject[]): Metadata {
137
+ const dict: Map<string, MetadataObject> = new Map();
138
+ for (const obj of objects)
139
+ dict.set(obj.name, MetadataObject._From_without_properties(obj));
140
+
141
+ for (const obj of objects) {
142
+ const initialized = dict.get(obj.name)!;
143
+ initialized.properties.push(
144
+ ...obj.properties.map((prop) =>
145
+ MetadataProperty._From(prop, dict),
146
+ ),
147
+ );
148
+ }
149
+ return this._From(meta, dict);
150
+ }
151
+
152
+ /**
153
+ * @internal
154
+ */
155
+ public static _From(
156
+ meta: IMetadata,
157
+ objects: Map<string, MetadataObject>,
158
+ ): Metadata {
159
+ return this.create({
160
+ any: meta.any,
161
+ required: meta.required,
162
+ nullable: meta.nullable,
163
+ functional: meta.functional,
164
+
165
+ constants: JSON.parse(JSON.stringify(meta.constants)),
166
+ atomics: meta.atomics.slice(),
167
+ templates: meta.templates.map((tpl) =>
168
+ tpl.map((meta) => this._From(meta, objects)),
169
+ ),
170
+ resolved: meta.resolved ? this._From(meta.resolved, objects) : null,
171
+
172
+ rest: meta.rest ? this._From(meta.rest, objects) : null,
173
+ arrays: meta.arrays.map((meta) => this._From(meta, objects)),
174
+ tuples: meta.tuples.map((tuple) =>
175
+ tuple.map((meta) => this._From(meta, objects)),
176
+ ),
177
+ objects: meta.objects.map((name) => {
178
+ const found = objects.get(name);
179
+ if (found === undefined)
180
+ throw new Error(
181
+ `Error on Metadata.from(): failed to find object "${name}".`,
182
+ );
183
+ return found;
184
+ }),
185
+
186
+ natives: meta.natives.slice(),
187
+ sets: meta.sets.map((meta) => this._From(meta, objects)),
188
+ maps: meta.maps.map((entry) => ({
189
+ key: this._From(entry.key, objects),
190
+ value: this._From(entry.value, objects),
191
+ })),
192
+ });
193
+ }
194
+
195
+ /* -----------------------------------------------------------
196
+ ACCESSORS
197
+ ----------------------------------------------------------- */
198
+ public getName(): string {
199
+ this.name_ ||= getName(this);
200
+ return this.name_;
201
+ }
202
+
203
+ public empty(): boolean {
204
+ return this.bucket() === 0 || this.size() === 0;
205
+ }
206
+ public size(): number {
207
+ return (
208
+ (this.resolved ? 1 : 0) +
209
+ (this.functional ? 1 : 0) +
210
+ this.templates.length +
211
+ this.atomics.length +
212
+ this.constants
213
+ .map((c) => c.values.length)
214
+ .reduce((x, y) => x + y, 0) +
215
+ (this.rest ? this.rest.size() : 0) +
216
+ this.arrays.length +
217
+ this.tuples.length +
218
+ this.objects.length +
219
+ this.natives.length +
220
+ this.sets.length +
221
+ this.maps.length
222
+ );
223
+ }
224
+ public bucket(): number {
225
+ return (
226
+ (this.resolved ? 1 : 0) +
227
+ (this.functional ? 1 : 0) +
228
+ (this.templates.length ? 1 : 0) +
229
+ (this.atomics.length ? 1 : 0) +
230
+ (this.constants.length ? 1 : 0) +
231
+ (this.rest ? this.rest.size() : 0) +
232
+ (this.arrays.length ? 1 : 0) +
233
+ (this.tuples.length ? 1 : 0) +
234
+ (this.objects.length ? 1 : 0) +
235
+ (this.natives.length ? 1 : 0) +
236
+ (this.sets.length ? 1 : 0) +
237
+ (this.maps.length ? 1 : 0)
238
+ );
239
+ }
240
+ public isConstant(): boolean {
241
+ return this.bucket() === (this.constants.length ? 1 : 0);
242
+ }
243
+
244
+ /**
245
+ * @internal
246
+ */
247
+ public isUnionBucket(): boolean {
248
+ const size: number = this.bucket();
249
+ const emended: number = this.constants.length ? size - 1 : size;
250
+ return emended > 1;
251
+ }
252
+
253
+ /**
254
+ * @internal
255
+ */
256
+ public getSoleLiteral(): string | null {
257
+ if (
258
+ this.size() === 1 &&
259
+ this.constants.length === 1 &&
260
+ this.constants[0]!.type === "string" &&
261
+ this.constants[0]!.values.length === 1
262
+ )
263
+ return this.constants[0]!.values[0] as string;
264
+ else return null;
265
+ }
266
+
267
+ /**
268
+ * @internal
269
+ */
270
+ public isSoleLiteral(): boolean {
271
+ return this.getSoleLiteral() !== null;
272
+ }
273
+
274
+ /**
275
+ * @internal
276
+ */
277
+ public isParentResolved(): boolean {
278
+ return this.parent_resolved_;
279
+ }
280
+ }
281
+ export namespace Metadata {
282
+ export function intersects(
283
+ x: Metadata,
284
+ y: Metadata,
285
+ deep: boolean,
286
+ ): boolean {
287
+ // CHECK ANY & OPTIONAL
288
+ if (x.any || y.any) return true;
289
+ if (x.required === false && false === y.required) return true;
290
+ if (x.nullable === true && true === y.nullable) return true;
291
+
292
+ //----
293
+ // INSTANCES
294
+ //----
295
+ // ARRAYS AND OBJECTS
296
+ if (deep === true) {
297
+ for (const xa of x.arrays)
298
+ for (const ya of y.arrays)
299
+ if (intersects(xa, ya, deep)) {
300
+ return true;
301
+ }
302
+ for (const xo of x.objects)
303
+ for (const yo of y.objects)
304
+ if (MetadataObject.intersects(xo, yo)) {
305
+ return true;
306
+ }
307
+ } else {
308
+ if (x.arrays.length && y.arrays.length) return true;
309
+ if (x.objects.length && y.objects.length) return true;
310
+ }
311
+
312
+ // TUPLES
313
+ for (const xt of x.tuples)
314
+ for (const yt of y.tuples)
315
+ if (
316
+ xt
317
+ .slice(0, Math.min(xt.length, yt.length))
318
+ .some((xv, i) => intersects(xv, yt[i]!, deep))
319
+ )
320
+ return true;
321
+
322
+ //----
323
+ // VALUES
324
+ //----
325
+ // ATOMICS
326
+ for (const atomic of x.atomics)
327
+ if (y.atomics.includes(atomic)) return true;
328
+
329
+ // CONSTANTS
330
+ for (const constant of x.constants) {
331
+ const opposite: MetadataConstant | undefined = y.constants.find(
332
+ (elem) => elem.type === constant.type,
333
+ );
334
+ if (opposite === undefined) continue;
335
+
336
+ const values: Set<any> = new Set([
337
+ ...constant.values,
338
+ ...opposite.values,
339
+ ]);
340
+ if (values.size !== constant.values.length + opposite.values.length)
341
+ return true;
342
+ }
343
+
344
+ // FUNCTIONAL
345
+ if (x.functional === true && y.functional === true) return true;
346
+
347
+ return false;
348
+ }
349
+
350
+ export function covers(x: Metadata, y: Metadata): boolean {
351
+ // CHECK ANY
352
+ if (x.any) return true;
353
+ else if (y.any) return false;
354
+
355
+ //----
356
+ // INSTANCES
357
+ //----
358
+ // ARRAYS
359
+ for (const ya of y.arrays)
360
+ if (x.arrays.some((xa) => covers(xa, ya) === true) === false)
361
+ return false;
362
+
363
+ // OBJECTS
364
+ for (const yo of y.objects)
365
+ if (x.objects.some((xo) => MetadataObject.covers(xo, yo)) === false)
366
+ return false;
367
+
368
+ // TUPLES
369
+ for (const yt of y.tuples)
370
+ if (
371
+ x.tuples.some(
372
+ (xt) =>
373
+ xt.length >= yt.length &&
374
+ xt
375
+ .slice(yt.length)
376
+ .every((xv, i) => covers(xv, yt[i]!)),
377
+ ) === false
378
+ )
379
+ return false;
380
+
381
+ // NATIVES
382
+
383
+ // SETS
384
+ for (const ys of y.sets)
385
+ if (x.sets.some((xs) => covers(xs, ys)) === false) return false;
386
+
387
+ //----
388
+ // VALUES
389
+ //----
390
+ // ATOMICS
391
+ if (y.atomics.some((atomic) => x.atomics.includes(atomic) === false))
392
+ return false;
393
+
394
+ // CONSTANTS
395
+ for (const yc of y.constants) {
396
+ const xc: MetadataConstant | undefined = x.constants.find(
397
+ (elem) => elem.type === yc.type,
398
+ );
399
+ if (xc === undefined) return false;
400
+ else if (
401
+ (yc.values as number[]).some(
402
+ (yv) => xc.values.includes(yv as never) === false,
403
+ )
404
+ )
405
+ return false;
406
+ }
407
+
408
+ // FUNCTIONAL
409
+ if (x.functional === false && y.functional) return false;
410
+
411
+ // SUCCESS
412
+ return true;
413
+ }
414
+ }
415
+
416
+ function getName(metadata: Metadata): string {
417
+ if (metadata.any === true) return "any";
418
+
419
+ const elements: string[] = [];
420
+
421
+ // OPTIONAL
422
+ if (metadata.nullable === true) elements.push("null");
423
+ if (metadata.required === false) elements.push("undefined");
424
+
425
+ // ATOMIC
426
+ for (const type of metadata.atomics) {
427
+ elements.push(type);
428
+ }
429
+ for (const constant of metadata.constants)
430
+ for (const value of constant.values)
431
+ elements.push(JSON.stringify(value));
432
+ for (const template of metadata.templates)
433
+ elements.push(
434
+ "`" +
435
+ template
436
+ .map((child) =>
437
+ child.isConstant() && child.size() === 1
438
+ ? child.constants[0]!.values[0]!
439
+ : `$\{${child.getName()}\}`,
440
+ )
441
+ .join("")
442
+ .split("`")
443
+ .join("\\`") +
444
+ "`",
445
+ );
446
+
447
+ // ARRAY
448
+ if (metadata.rest !== null) elements.push(`...${metadata.rest.getName()}`);
449
+ for (const tuple of metadata.tuples)
450
+ elements.push(`[${tuple.map((elem) => elem.getName()).join(", ")}]`);
451
+ for (const array of metadata.arrays)
452
+ elements.push(`Array<${array.getName()}>`);
453
+
454
+ // OBJECT
455
+ for (const object of metadata.objects)
456
+ elements.push(`Resolve<${object.name}>`);
457
+ if (metadata.resolved !== null) elements.push(metadata.resolved.getName());
458
+
459
+ // NATIVES
460
+ for (const native of metadata.natives) elements.push(native);
461
+ for (const set of metadata.sets) elements.push(`Set<${set.getName()}>`);
462
+ for (const map of metadata.maps)
463
+ elements.push(`Map<${map.key.getName()}, ${map.value.getName()}>`);
464
+
465
+ // RETURNS
466
+ if (elements.length === 0) return "unknown";
467
+ else if (elements.length === 1) return elements[0]!;
468
+
469
+ elements.sort();
470
+ return `(${elements.join(" | ")})`;
471
+ }
472
+ export namespace Metadata {
473
+ export interface Entry {
474
+ key: Metadata;
475
+ value: Metadata;
476
+ }
477
+ }