typia 3.4.15 → 3.5.0-dev.20221222

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 (169) hide show
  1. package/README.md +48 -7
  2. package/lib/factories/MetadataCollection.d.ts +1 -9
  3. package/lib/factories/MetadataCollection.js +2 -75
  4. package/lib/factories/MetadataCollection.js.map +1 -1
  5. package/lib/factories/ProtocolFactory.d.ts +8 -0
  6. package/lib/factories/ProtocolFactory.js +119 -0
  7. package/lib/factories/ProtocolFactory.js.map +1 -0
  8. package/lib/factories/internal/protocols/ProtocolMetadataUtil.d.ts +11 -0
  9. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js +76 -0
  10. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js.map +1 -0
  11. package/lib/factories/internal/protocols/emplace_protocol_object.d.ts +3 -0
  12. package/lib/factories/internal/protocols/emplace_protocol_object.js +47 -0
  13. package/lib/factories/internal/protocols/emplace_protocol_object.js.map +1 -0
  14. package/lib/factories/internal/protocols/emplace_protocol_property.d.ts +4 -0
  15. package/lib/factories/internal/protocols/emplace_protocol_property.js +20 -0
  16. package/lib/factories/internal/protocols/emplace_protocol_property.js.map +1 -0
  17. package/lib/factories/internal/protocols/iterate_protocol_atomic.d.ts +3 -0
  18. package/lib/factories/internal/protocols/iterate_protocol_atomic.js +69 -0
  19. package/lib/factories/internal/protocols/iterate_protocol_atomic.js.map +1 -0
  20. package/lib/factories/internal/protocols/iterate_protocol_constant.d.ts +2 -0
  21. package/lib/factories/internal/protocols/iterate_protocol_constant.js +30 -0
  22. package/lib/factories/internal/protocols/iterate_protocol_constant.js.map +1 -0
  23. package/lib/factories/internal/protocols/iterate_protocol_main.d.ts +3 -0
  24. package/lib/factories/internal/protocols/iterate_protocol_main.js +17 -0
  25. package/lib/factories/internal/protocols/iterate_protocol_main.js.map +1 -0
  26. package/lib/factories/internal/protocols/iterate_protocol_map.d.ts +3 -0
  27. package/lib/factories/internal/protocols/iterate_protocol_map.js +71 -0
  28. package/lib/factories/internal/protocols/iterate_protocol_map.js.map +1 -0
  29. package/lib/factories/internal/protocols/iterate_protocol_metadata.d.ts +5 -0
  30. package/lib/factories/internal/protocols/iterate_protocol_metadata.js +192 -0
  31. package/lib/factories/internal/protocols/iterate_protocol_metadata.js.map +1 -0
  32. package/lib/factories/internal/protocols/iterate_protocol_native.d.ts +2 -0
  33. package/lib/factories/internal/protocols/iterate_protocol_native.js +33 -0
  34. package/lib/factories/internal/protocols/iterate_protocol_native.js.map +1 -0
  35. package/lib/factories/internal/protocols/iterate_protocol_repeated.d.ts +4 -0
  36. package/lib/factories/internal/protocols/iterate_protocol_repeated.js +24 -0
  37. package/lib/factories/internal/protocols/iterate_protocol_repeated.js.map +1 -0
  38. package/lib/factories/internal/protocols/iterate_protocol_tuple.d.ts +3 -0
  39. package/lib/factories/internal/protocols/iterate_protocol_tuple.js +46 -0
  40. package/lib/factories/internal/protocols/iterate_protocol_tuple.js.map +1 -0
  41. package/lib/functional/$proto_bytes.d.ts +2 -0
  42. package/lib/functional/$proto_bytes.js +37 -0
  43. package/lib/functional/$proto_bytes.js.map +1 -0
  44. package/lib/functional/$proto_field.d.ts +10 -0
  45. package/lib/functional/$proto_field.js +42 -0
  46. package/lib/functional/$proto_field.js.map +1 -0
  47. package/lib/functional/$proto_float.d.ts +4 -0
  48. package/lib/functional/$proto_float.js +28 -0
  49. package/lib/functional/$proto_float.js.map +1 -0
  50. package/lib/functional/$proto_i32.d.ts +2 -0
  51. package/lib/functional/$proto_i32.js +23 -0
  52. package/lib/functional/$proto_i32.js.map +1 -0
  53. package/lib/functional/$proto_i64.d.ts +2 -0
  54. package/lib/functional/$proto_i64.js +31 -0
  55. package/lib/functional/$proto_i64.js.map +1 -0
  56. package/lib/functional/$proto_size.d.ts +6 -0
  57. package/lib/functional/$proto_size.js +76 -0
  58. package/lib/functional/$proto_size.js.map +1 -0
  59. package/lib/functional/$proto_string.d.ts +2 -0
  60. package/lib/functional/$proto_string.js +34 -0
  61. package/lib/functional/$proto_string.js.map +1 -0
  62. package/lib/functional/$varint.d.ts +6 -0
  63. package/lib/functional/$varint.js +99 -0
  64. package/lib/functional/$varint.js.map +1 -0
  65. package/lib/functional/$zigzag.d.ts +4 -0
  66. package/lib/functional/$zigzag.js +34 -0
  67. package/lib/functional/$zigzag.js.map +1 -0
  68. package/lib/messages/IProtocolMessage.d.ts +5 -0
  69. package/lib/messages/IProtocolMessage.js +3 -0
  70. package/lib/messages/IProtocolMessage.js.map +1 -0
  71. package/lib/messages/IProtocolProperty.d.ts +11 -0
  72. package/lib/messages/IProtocolProperty.js +3 -0
  73. package/lib/messages/IProtocolProperty.js.map +1 -0
  74. package/lib/metadata/IMetadataTag.d.ts +7 -3
  75. package/lib/metadata/Metadata.js +1 -1
  76. package/lib/metadata/Metadata.js.map +1 -1
  77. package/lib/module.d.ts +2 -0
  78. package/lib/module.js +5 -1
  79. package/lib/module.js.map +1 -1
  80. package/lib/programmers/MessageProgrammer.d.ts +5 -0
  81. package/lib/programmers/MessageProgrammer.js +134 -0
  82. package/lib/programmers/MessageProgrammer.js.map +1 -0
  83. package/lib/programmers/internal/application_object.js +9 -9
  84. package/lib/programmers/internal/application_object.js.map +1 -1
  85. package/lib/programmers/internal/application_schema.js +5 -3
  86. package/lib/programmers/internal/application_schema.js.map +1 -1
  87. package/lib/transformers/CallExpressionTransformer.js +3 -1
  88. package/lib/transformers/CallExpressionTransformer.js.map +1 -1
  89. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js +1 -3
  90. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js.map +1 -1
  91. package/lib/transformers/features/protocols/MessageTransformer.d.ts +5 -0
  92. package/lib/transformers/features/protocols/MessageTransformer.js +17 -0
  93. package/lib/transformers/features/protocols/MessageTransformer.js.map +1 -0
  94. package/lib/utils/NameEncoder.d.ts +4 -0
  95. package/lib/utils/NameEncoder.js +89 -0
  96. package/lib/utils/NameEncoder.js.map +1 -0
  97. package/package.json +2 -3
  98. package/src/executable/internal/TypiaSetupWizard.ts +173 -173
  99. package/src/factories/MetadataCollection.ts +83 -122
  100. package/src/factories/MetadataFactory.ts +47 -47
  101. package/src/factories/MetadataTagFactory.ts +351 -351
  102. package/src/factories/ProtocolFactory.ts +92 -0
  103. package/src/factories/internal/metadata/MetadataHelper.ts +12 -12
  104. package/src/factories/internal/metadata/emplace_metadata_object.ts +140 -140
  105. package/src/factories/internal/metadata/explore_metadata.ts +92 -92
  106. package/src/factories/internal/metadata/iterate_metadata.ts +80 -80
  107. package/src/factories/internal/metadata/iterate_metadata_array.ts +29 -29
  108. package/src/factories/internal/metadata/iterate_metadata_atomic.ts +59 -59
  109. package/src/factories/internal/metadata/iterate_metadata_coalesce.ts +33 -33
  110. package/src/factories/internal/metadata/iterate_metadata_constant.ts +58 -58
  111. package/src/factories/internal/metadata/iterate_metadata_map.ts +41 -41
  112. package/src/factories/internal/metadata/iterate_metadata_native.ts +227 -227
  113. package/src/factories/internal/metadata/iterate_metadata_object.ts +48 -48
  114. package/src/factories/internal/metadata/iterate_metadata_resolve.ts +27 -27
  115. package/src/factories/internal/metadata/iterate_metadata_set.ts +33 -33
  116. package/src/factories/internal/metadata/iterate_metadata_template.ts +38 -38
  117. package/src/factories/internal/metadata/iterate_metadata_tuple.ts +45 -45
  118. package/src/factories/internal/metadata/iterate_metadata_union.ts +59 -59
  119. package/src/factories/internal/protocols/ProtocolMetadataUtil.ts +81 -0
  120. package/src/factories/internal/protocols/emplace_protocol_object.ts +25 -0
  121. package/src/factories/internal/protocols/emplace_protocol_property.ts +12 -0
  122. package/src/factories/internal/protocols/iterate_protocol_atomic.ts +34 -0
  123. package/src/factories/internal/protocols/iterate_protocol_constant.ts +27 -0
  124. package/src/factories/internal/protocols/iterate_protocol_main.ts +19 -0
  125. package/src/factories/internal/protocols/iterate_protocol_map.ts +38 -0
  126. package/src/factories/internal/protocols/iterate_protocol_metadata.ts +76 -0
  127. package/src/factories/internal/protocols/iterate_protocol_native.ts +34 -0
  128. package/src/factories/internal/protocols/iterate_protocol_repeated.ts +25 -0
  129. package/src/factories/internal/protocols/iterate_protocol_tuple.ts +25 -0
  130. package/src/functional/$number.ts +12 -12
  131. package/src/functional/$proto_bytes.ts +25 -0
  132. package/src/functional/$proto_field.ts +30 -0
  133. package/src/functional/$proto_float.ts +37 -0
  134. package/src/functional/$proto_i32.ts +29 -0
  135. package/src/functional/$proto_i64.ts +37 -0
  136. package/src/functional/$proto_size.ts +82 -0
  137. package/src/functional/$proto_string.ts +24 -0
  138. package/src/functional/$varint.ts +130 -0
  139. package/src/functional/$zigzag.ts +39 -0
  140. package/src/messages/IProtocolMessage.ts +6 -0
  141. package/src/messages/IProtocolProperty.ts +11 -0
  142. package/src/metadata/IMetadataTag.ts +137 -122
  143. package/src/metadata/Metadata.ts +479 -477
  144. package/src/module.ts +1547 -1535
  145. package/src/programmers/AssertParseProgrammer.ts +55 -55
  146. package/src/programmers/AssertProgrammer.ts +445 -445
  147. package/src/programmers/AssertStringifyProgrammer.ts +65 -65
  148. package/src/programmers/CheckerProgrammer.ts +810 -810
  149. package/src/programmers/IsParseProgrammer.ts +61 -61
  150. package/src/programmers/IsProgrammer.ts +175 -175
  151. package/src/programmers/IsStringifyProgrammer.ts +69 -69
  152. package/src/programmers/MessageProgrammer.ts +116 -0
  153. package/src/programmers/StringifyProgrammer.ts +762 -762
  154. package/src/programmers/ValidateParseProgrammer.ts +59 -59
  155. package/src/programmers/ValidateProgrammer.ts +237 -237
  156. package/src/programmers/ValidateStringifyProgrammer.ts +80 -80
  157. package/src/programmers/helpers/OptionPredicator.ts +15 -15
  158. package/src/programmers/internal/application_default.ts +17 -17
  159. package/src/programmers/internal/application_object.ts +5 -5
  160. package/src/programmers/internal/application_schema.ts +231 -228
  161. package/src/programmers/internal/check_bigint.ts +85 -85
  162. package/src/programmers/internal/check_number.ts +175 -175
  163. package/src/schemas/IJsonSchema.ts +90 -90
  164. package/src/transformers/CallExpressionTransformer.ts +131 -124
  165. package/src/transformers/ITransformOptions.ts +47 -47
  166. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +117 -119
  167. package/src/transformers/features/protocols/MessageTransformer.ts +32 -0
  168. package/src/transformers/features/stringifiers/StringifyTransformer.ts +46 -46
  169. package/src/utils/NameEncoder.ts +32 -0
@@ -1,477 +1,479 @@
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
+
207
+ public size(): number {
208
+ return (
209
+ (this.resolved ? 1 : 0) +
210
+ (this.functional ? 1 : 0) +
211
+ this.templates.length +
212
+ this.atomics.length +
213
+ this.constants
214
+ .map((c) => c.values.length)
215
+ .reduce((x, y) => x + y, 0) +
216
+ (this.rest ? this.rest.size() : 0) +
217
+ this.arrays.length +
218
+ this.tuples.length +
219
+ this.objects.length +
220
+ this.natives.length +
221
+ this.sets.length +
222
+ this.maps.length
223
+ );
224
+ }
225
+
226
+ public bucket(): number {
227
+ return (
228
+ (this.resolved ? 1 : 0) +
229
+ (this.functional ? 1 : 0) +
230
+ (this.templates.length ? 1 : 0) +
231
+ (this.atomics.length ? 1 : 0) +
232
+ (this.constants.length ? 1 : 0) +
233
+ (this.rest ? this.rest.size() : 0) +
234
+ (this.arrays.length ? 1 : 0) +
235
+ (this.tuples.length ? 1 : 0) +
236
+ (this.objects.length ? 1 : 0) +
237
+ (this.natives.length ? 1 : 0) +
238
+ (this.sets.length ? 1 : 0) +
239
+ (this.maps.length ? 1 : 0)
240
+ );
241
+ }
242
+
243
+ public isConstant(): boolean {
244
+ return this.bucket() === (this.constants.length ? 1 : 0);
245
+ }
246
+
247
+ /**
248
+ * @internal
249
+ */
250
+ public isUnionBucket(): boolean {
251
+ const size: number = this.bucket();
252
+ const emended: number = this.constants.length ? size - 1 : size;
253
+ return emended > 1;
254
+ }
255
+
256
+ /**
257
+ * @internal
258
+ */
259
+ public getSoleLiteral(): string | null {
260
+ if (
261
+ this.size() === 1 &&
262
+ this.constants.length === 1 &&
263
+ this.constants[0]!.type === "string" &&
264
+ this.constants[0]!.values.length === 1
265
+ )
266
+ return this.constants[0]!.values[0] as string;
267
+ else return null;
268
+ }
269
+
270
+ /**
271
+ * @internal
272
+ */
273
+ public isSoleLiteral(): boolean {
274
+ return this.getSoleLiteral() !== null;
275
+ }
276
+
277
+ /**
278
+ * @internal
279
+ */
280
+ public isParentResolved(): boolean {
281
+ return this.parent_resolved_;
282
+ }
283
+ }
284
+ export namespace Metadata {
285
+ export function intersects(
286
+ x: Metadata,
287
+ y: Metadata,
288
+ deep: boolean,
289
+ ): boolean {
290
+ // CHECK ANY & OPTIONAL
291
+ if (x.any || y.any) return true;
292
+ if (x.required === false && false === y.required) return true;
293
+ if (x.nullable === true && true === y.nullable) return true;
294
+
295
+ //----
296
+ // INSTANCES
297
+ //----
298
+ // ARRAYS AND OBJECTS
299
+ if (deep === true) {
300
+ for (const xa of x.arrays)
301
+ for (const ya of y.arrays)
302
+ if (intersects(xa, ya, deep)) {
303
+ return true;
304
+ }
305
+ for (const xo of x.objects)
306
+ for (const yo of y.objects)
307
+ if (MetadataObject.intersects(xo, yo)) {
308
+ return true;
309
+ }
310
+ } else {
311
+ if (x.arrays.length && y.arrays.length) return true;
312
+ if (x.objects.length && y.objects.length) return true;
313
+ }
314
+
315
+ // TUPLES
316
+ for (const xt of x.tuples)
317
+ for (const yt of y.tuples)
318
+ if (
319
+ xt
320
+ .slice(0, Math.min(xt.length, yt.length))
321
+ .some((xv, i) => intersects(xv, yt[i]!, deep))
322
+ )
323
+ return true;
324
+
325
+ //----
326
+ // VALUES
327
+ //----
328
+ // ATOMICS
329
+ for (const atomic of x.atomics)
330
+ if (y.atomics.includes(atomic)) return true;
331
+
332
+ // CONSTANTS
333
+ for (const constant of x.constants) {
334
+ const opposite: MetadataConstant | undefined = y.constants.find(
335
+ (elem) => elem.type === constant.type,
336
+ );
337
+ if (opposite === undefined) continue;
338
+
339
+ const values: Set<any> = new Set([
340
+ ...constant.values,
341
+ ...opposite.values,
342
+ ]);
343
+ if (values.size !== constant.values.length + opposite.values.length)
344
+ return true;
345
+ }
346
+
347
+ // FUNCTIONAL
348
+ if (x.functional === true && y.functional === true) return true;
349
+
350
+ return false;
351
+ }
352
+
353
+ export function covers(x: Metadata, y: Metadata): boolean {
354
+ // CHECK ANY
355
+ if (x.any) return true;
356
+ else if (y.any) return false;
357
+
358
+ //----
359
+ // INSTANCES
360
+ //----
361
+ // ARRAYS
362
+ for (const ya of y.arrays)
363
+ if (x.arrays.some((xa) => covers(xa, ya) === true) === false)
364
+ return false;
365
+
366
+ // OBJECTS
367
+ for (const yo of y.objects)
368
+ if (x.objects.some((xo) => MetadataObject.covers(xo, yo)) === false)
369
+ return false;
370
+
371
+ // TUPLES
372
+ for (const yt of y.tuples)
373
+ if (
374
+ x.tuples.some(
375
+ (xt) =>
376
+ xt.length >= yt.length &&
377
+ xt
378
+ .slice(yt.length)
379
+ .every((xv, i) => covers(xv, yt[i]!)),
380
+ ) === false
381
+ )
382
+ return false;
383
+
384
+ // NATIVES
385
+
386
+ // SETS
387
+ for (const ys of y.sets)
388
+ if (x.sets.some((xs) => covers(xs, ys)) === false) return false;
389
+
390
+ //----
391
+ // VALUES
392
+ //----
393
+ // ATOMICS
394
+ if (y.atomics.some((atomic) => x.atomics.includes(atomic) === false))
395
+ return false;
396
+
397
+ // CONSTANTS
398
+ for (const yc of y.constants) {
399
+ const xc: MetadataConstant | undefined = x.constants.find(
400
+ (elem) => elem.type === yc.type,
401
+ );
402
+ if (xc === undefined) return false;
403
+ else if (
404
+ (yc.values as number[]).some(
405
+ (yv) => xc.values.includes(yv as never) === false,
406
+ )
407
+ )
408
+ return false;
409
+ }
410
+
411
+ // FUNCTIONAL
412
+ if (x.functional === false && y.functional) return false;
413
+
414
+ // SUCCESS
415
+ return true;
416
+ }
417
+ }
418
+
419
+ function getName(metadata: Metadata): string {
420
+ if (metadata.any === true) return "any";
421
+
422
+ const elements: string[] = [];
423
+
424
+ // OPTIONAL
425
+ if (metadata.nullable === true) elements.push("null");
426
+ if (metadata.required === false) elements.push("undefined");
427
+
428
+ // ATOMIC
429
+ for (const type of metadata.atomics) {
430
+ elements.push(type);
431
+ }
432
+ for (const constant of metadata.constants)
433
+ for (const value of constant.values)
434
+ elements.push(JSON.stringify(value));
435
+ for (const template of metadata.templates)
436
+ elements.push(
437
+ "`" +
438
+ template
439
+ .map((child) =>
440
+ child.isConstant() && child.size() === 1
441
+ ? child.constants[0]!.values[0]!
442
+ : `$\{${child.getName()}\}`,
443
+ )
444
+ .join("")
445
+ .split("`")
446
+ .join("\\`") +
447
+ "`",
448
+ );
449
+
450
+ // ARRAY
451
+ if (metadata.rest !== null) elements.push(`...${metadata.rest.getName()}`);
452
+ for (const tuple of metadata.tuples)
453
+ elements.push(`[${tuple.map((elem) => elem.getName()).join(", ")}]`);
454
+ for (const array of metadata.arrays)
455
+ elements.push(`Array<${array.getName()}>`);
456
+
457
+ // OBJECT
458
+ for (const object of metadata.objects) elements.push(object.name);
459
+ if (metadata.resolved !== null) elements.push(metadata.resolved.getName());
460
+
461
+ // NATIVES
462
+ for (const native of metadata.natives) elements.push(native);
463
+ for (const set of metadata.sets) elements.push(`Set<${set.getName()}>`);
464
+ for (const map of metadata.maps)
465
+ elements.push(`Map<${map.key.getName()}, ${map.value.getName()}>`);
466
+
467
+ // RETURNS
468
+ if (elements.length === 0) return "unknown";
469
+ else if (elements.length === 1) return elements[0]!;
470
+
471
+ elements.sort();
472
+ return `(${elements.join(" | ")})`;
473
+ }
474
+ export namespace Metadata {
475
+ export interface Entry {
476
+ key: Metadata;
477
+ value: Metadata;
478
+ }
479
+ }