typia 5.0.0-dev.20230823 → 5.0.0-dev.2023084

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 (217) hide show
  1. package/lib/Primitive.d.ts +14 -12
  2. package/lib/Resolved.d.ts +46 -0
  3. package/lib/{schemas/metadata/IMetadataResolved.js → Resolved.js} +1 -1
  4. package/lib/Resolved.js.map +1 -0
  5. package/lib/factories/MetadataFactory.d.ts +1 -1
  6. package/lib/factories/MetadataTagFactory.js +10 -8
  7. package/lib/factories/MetadataTagFactory.js.map +1 -1
  8. package/lib/factories/ProtobufFactory.js +4 -3
  9. package/lib/factories/ProtobufFactory.js.map +1 -1
  10. package/lib/factories/internal/metadata/emend_metadata_atomics.js +6 -6
  11. package/lib/factories/internal/metadata/emend_metadata_atomics.js.map +1 -1
  12. package/lib/factories/internal/metadata/explore_metadata.js +3 -3
  13. package/lib/factories/internal/metadata/explore_metadata.js.map +1 -1
  14. package/lib/factories/internal/metadata/iterate_metadata_atomic.js +1 -1
  15. package/lib/factories/internal/metadata/iterate_metadata_atomic.js.map +1 -1
  16. package/lib/factories/internal/metadata/iterate_metadata_collection.js +6 -6
  17. package/lib/factories/internal/metadata/iterate_metadata_collection.js.map +1 -1
  18. package/lib/factories/internal/metadata/iterate_metadata_native.js +2 -10
  19. package/lib/factories/internal/metadata/iterate_metadata_native.js.map +1 -1
  20. package/lib/factories/internal/metadata/iterate_metadata_resolve.js +6 -6
  21. package/lib/factories/internal/metadata/iterate_metadata_resolve.js.map +1 -1
  22. package/lib/factories/internal/metadata/iterate_metadata_sort.js +2 -2
  23. package/lib/factories/internal/metadata/iterate_metadata_sort.js.map +1 -1
  24. package/lib/functional/$ProtobufWriter.js.map +1 -1
  25. package/lib/json.d.ts +15 -15
  26. package/lib/misc.d.ts +42 -42
  27. package/lib/module.d.ts +18 -17
  28. package/lib/module.js +1 -0
  29. package/lib/module.js.map +1 -1
  30. package/lib/programmers/AssertProgrammer.js +1 -1
  31. package/lib/programmers/AssertProgrammer.js.map +1 -1
  32. package/lib/programmers/CheckerProgrammer.js +7 -7
  33. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  34. package/lib/programmers/IsProgrammer.js +2 -2
  35. package/lib/programmers/IsProgrammer.js.map +1 -1
  36. package/lib/programmers/RandomProgrammer.js +311 -136
  37. package/lib/programmers/RandomProgrammer.js.map +1 -1
  38. package/lib/programmers/ValidateProgrammer.js +1 -1
  39. package/lib/programmers/ValidateProgrammer.js.map +1 -1
  40. package/lib/programmers/helpers/AtomicPredicator.js +2 -2
  41. package/lib/programmers/helpers/AtomicPredicator.js.map +1 -1
  42. package/lib/programmers/helpers/FunctionImporeter.d.ts +2 -0
  43. package/lib/programmers/helpers/FunctionImporeter.js +2 -1
  44. package/lib/programmers/helpers/FunctionImporeter.js.map +1 -1
  45. package/lib/programmers/helpers/ProtobufUtil.js +2 -2
  46. package/lib/programmers/helpers/ProtobufUtil.js.map +1 -1
  47. package/lib/programmers/helpers/StringifyPredicator.js +1 -2
  48. package/lib/programmers/helpers/StringifyPredicator.js.map +1 -1
  49. package/lib/programmers/helpers/disable_function_importer_declare.js +1 -0
  50. package/lib/programmers/helpers/disable_function_importer_declare.js.map +1 -1
  51. package/lib/programmers/internal/application_default_string.js +2 -2
  52. package/lib/programmers/internal/application_default_string.js.map +1 -1
  53. package/lib/programmers/internal/application_resolved.d.ts +2 -2
  54. package/lib/programmers/internal/application_resolved.js.map +1 -1
  55. package/lib/programmers/internal/application_schema.js +7 -7
  56. package/lib/programmers/internal/application_schema.js.map +1 -1
  57. package/lib/programmers/internal/metadata_to_pattern.js +4 -4
  58. package/lib/programmers/internal/metadata_to_pattern.js.map +1 -1
  59. package/lib/programmers/internal/stringify_dynamic_properties.js +2 -1
  60. package/lib/programmers/internal/stringify_dynamic_properties.js.map +1 -1
  61. package/lib/programmers/json/JsonStringifyProgrammer.js +20 -14
  62. package/lib/programmers/json/JsonStringifyProgrammer.js.map +1 -1
  63. package/lib/programmers/misc/MiscAssertCloneProgrammer.js +1 -1
  64. package/lib/programmers/misc/MiscAssertCloneProgrammer.js.map +1 -1
  65. package/lib/programmers/misc/MiscCloneProgrammer.js +114 -33
  66. package/lib/programmers/misc/MiscCloneProgrammer.js.map +1 -1
  67. package/lib/programmers/misc/MiscIsCloneProgrammer.js +1 -1
  68. package/lib/programmers/misc/MiscIsCloneProgrammer.js.map +1 -1
  69. package/lib/programmers/misc/MiscLiteralsProgrammer.js +3 -3
  70. package/lib/programmers/misc/MiscLiteralsProgrammer.js.map +1 -1
  71. package/lib/programmers/misc/MiscPruneProgrammer.js +2 -2
  72. package/lib/programmers/misc/MiscPruneProgrammer.js.map +1 -1
  73. package/lib/programmers/misc/MiscValidateCloneProgrammer.js +1 -1
  74. package/lib/programmers/misc/MiscValidateCloneProgrammer.js.map +1 -1
  75. package/lib/programmers/protobuf/ProtobufAssertDecodeProgrammer.js +3 -3
  76. package/lib/programmers/protobuf/ProtobufAssertDecodeProgrammer.js.map +1 -1
  77. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js +3 -3
  78. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js.map +1 -1
  79. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js +1 -1
  80. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js.map +1 -1
  81. package/lib/programmers/protobuf/ProtobufIsDecodeProgrammer.js +2 -2
  82. package/lib/programmers/protobuf/ProtobufIsDecodeProgrammer.js.map +1 -1
  83. package/lib/programmers/protobuf/ProtobufValidateDecodeProgrammer.js +1 -1
  84. package/lib/programmers/protobuf/ProtobufValidateDecodeProgrammer.js.map +1 -1
  85. package/lib/protobuf.d.ts +631 -10
  86. package/lib/protobuf.js +13 -13
  87. package/lib/protobuf.js.map +1 -1
  88. package/lib/schemas/metadata/IMetadata.d.ts +4 -4
  89. package/lib/schemas/metadata/IMetadataAtomic.d.ts +12 -0
  90. package/lib/schemas/metadata/IMetadataAtomic.js +3 -0
  91. package/lib/schemas/metadata/IMetadataAtomic.js.map +1 -0
  92. package/lib/schemas/metadata/{IMetadataResolved.d.ts → IMetadataEscaped.d.ts} +1 -1
  93. package/lib/schemas/metadata/IMetadataEscaped.js +3 -0
  94. package/lib/schemas/metadata/IMetadataEscaped.js.map +1 -0
  95. package/lib/schemas/metadata/Metadata.d.ts +4 -4
  96. package/lib/schemas/metadata/Metadata.js +64 -59
  97. package/lib/schemas/metadata/Metadata.js.map +1 -1
  98. package/lib/schemas/metadata/{MetadataResolved.d.ts → MetadataEscaped.d.ts} +3 -3
  99. package/lib/schemas/metadata/{MetadataResolved.js → MetadataEscaped.js} +11 -11
  100. package/lib/schemas/metadata/MetadataEscaped.js.map +1 -0
  101. package/lib/tags/ExclusiveMaximum.d.ts +8 -0
  102. package/lib/tags/ExclusiveMaximum.js +3 -0
  103. package/lib/tags/ExclusiveMaximum.js.map +1 -0
  104. package/lib/tags/ExclusiveMinimum.d.ts +8 -0
  105. package/lib/tags/ExclusiveMinimum.js +3 -0
  106. package/lib/tags/ExclusiveMinimum.js.map +1 -0
  107. package/lib/tags/Format.d.ts +8 -0
  108. package/lib/tags/Format.js +3 -0
  109. package/lib/tags/Format.js.map +1 -0
  110. package/lib/tags/MaxItems.d.ts +8 -0
  111. package/lib/tags/MaxItems.js +3 -0
  112. package/lib/tags/MaxItems.js.map +1 -0
  113. package/lib/tags/MaxLength.d.ts +8 -0
  114. package/lib/tags/MaxLength.js +3 -0
  115. package/lib/tags/MaxLength.js.map +1 -0
  116. package/lib/tags/Maximum.d.ts +8 -0
  117. package/lib/tags/Maximum.js +3 -0
  118. package/lib/tags/Maximum.js.map +1 -0
  119. package/lib/tags/MinItems.d.ts +8 -0
  120. package/lib/tags/MinItems.js +3 -0
  121. package/lib/tags/MinItems.js.map +1 -0
  122. package/lib/tags/MinLength.d.ts +8 -0
  123. package/lib/tags/MinLength.js +3 -0
  124. package/lib/tags/MinLength.js.map +1 -0
  125. package/lib/tags/Minimum.d.ts +8 -0
  126. package/lib/tags/Minimum.js +3 -0
  127. package/lib/tags/Minimum.js.map +1 -0
  128. package/lib/tags/MultipleOf.d.ts +8 -0
  129. package/lib/tags/MultipleOf.js +3 -0
  130. package/lib/tags/MultipleOf.js.map +1 -0
  131. package/lib/tags/Pattern.d.ts +8 -0
  132. package/lib/tags/Pattern.js +3 -0
  133. package/lib/tags/Pattern.js.map +1 -0
  134. package/lib/tags/TagBase.d.ts +10 -0
  135. package/lib/tags/TagBase.js +3 -0
  136. package/lib/tags/TagBase.js.map +1 -0
  137. package/lib/tags/Type.d.ts +13 -0
  138. package/lib/tags/Type.js +3 -0
  139. package/lib/tags/Type.js.map +1 -0
  140. package/lib/tags/index.d.ts +12 -0
  141. package/lib/tags/index.js +29 -0
  142. package/lib/tags/index.js.map +1 -0
  143. package/lib/transformers/features/json/JsonApplicationTransformer.js +2 -2
  144. package/lib/transformers/features/json/JsonApplicationTransformer.js.map +1 -1
  145. package/lib/transformers/features/misc/MetadataTransformer.js +1 -1
  146. package/lib/transformers/features/misc/MetadataTransformer.js.map +1 -1
  147. package/lib/utils/RandomGenerator.js +3 -2
  148. package/lib/utils/RandomGenerator.js.map +1 -1
  149. package/package.json +2 -1
  150. package/src/Primitive.ts +135 -131
  151. package/src/Resolved.ts +116 -0
  152. package/src/factories/MetadataFactory.ts +46 -46
  153. package/src/factories/MetadataTagFactory.ts +366 -364
  154. package/src/factories/ProtobufFactory.ts +268 -266
  155. package/src/factories/internal/metadata/emend_metadata_atomics.ts +35 -33
  156. package/src/factories/internal/metadata/explore_metadata.ts +38 -38
  157. package/src/factories/internal/metadata/iterate_metadata_atomic.ts +63 -59
  158. package/src/factories/internal/metadata/iterate_metadata_collection.ts +133 -133
  159. package/src/factories/internal/metadata/iterate_metadata_native.ts +210 -219
  160. package/src/factories/internal/metadata/iterate_metadata_resolve.ts +49 -49
  161. package/src/factories/internal/metadata/iterate_metadata_sort.ts +69 -69
  162. package/src/functional/$ProtobufWriter.ts +151 -151
  163. package/src/json.ts +648 -648
  164. package/src/misc.ts +651 -651
  165. package/src/module.ts +709 -708
  166. package/src/programmers/AssertProgrammer.ts +281 -279
  167. package/src/programmers/CheckerProgrammer.ts +1174 -1173
  168. package/src/programmers/IsProgrammer.ts +241 -239
  169. package/src/programmers/RandomProgrammer.ts +874 -578
  170. package/src/programmers/ValidateProgrammer.ts +307 -305
  171. package/src/programmers/helpers/AtomicPredicator.ts +31 -31
  172. package/src/programmers/helpers/FunctionImporeter.ts +91 -89
  173. package/src/programmers/helpers/ProtobufUtil.ts +29 -29
  174. package/src/programmers/helpers/StringifyPredicator.ts +12 -13
  175. package/src/programmers/helpers/disable_function_importer_declare.ts +32 -27
  176. package/src/programmers/internal/application_default_string.ts +37 -33
  177. package/src/programmers/internal/application_resolved.ts +55 -55
  178. package/src/programmers/internal/application_schema.ts +157 -157
  179. package/src/programmers/internal/metadata_to_pattern.ts +34 -34
  180. package/src/programmers/internal/stringify_dynamic_properties.ts +171 -171
  181. package/src/programmers/json/JsonStringifyProgrammer.ts +995 -987
  182. package/src/programmers/misc/MiscAssertCloneProgrammer.ts +71 -71
  183. package/src/programmers/misc/MiscCloneProgrammer.ts +775 -587
  184. package/src/programmers/misc/MiscIsCloneProgrammer.ts +78 -78
  185. package/src/programmers/misc/MiscLiteralsProgrammer.ts +64 -64
  186. package/src/programmers/misc/MiscPruneProgrammer.ts +544 -542
  187. package/src/programmers/misc/MiscValidateCloneProgrammer.ts +85 -85
  188. package/src/programmers/protobuf/ProtobufAssertDecodeProgrammer.ts +75 -66
  189. package/src/programmers/protobuf/ProtobufDecodeProgrammer.ts +673 -669
  190. package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +814 -814
  191. package/src/programmers/protobuf/ProtobufIsDecodeProgrammer.ts +85 -75
  192. package/src/programmers/protobuf/ProtobufValidateDecodeProgrammer.ts +75 -75
  193. package/src/protobuf.ts +881 -249
  194. package/src/schemas/metadata/IMetadata.ts +27 -28
  195. package/src/schemas/metadata/IMetadataAtomic.ts +13 -0
  196. package/src/schemas/metadata/{IMetadataResolved.ts → IMetadataEscaped.ts} +6 -6
  197. package/src/schemas/metadata/Metadata.ts +643 -637
  198. package/src/schemas/metadata/{MetadataResolved.ts → MetadataEscaped.ts} +51 -51
  199. package/src/tags/ExclusiveMaximum.ts +8 -0
  200. package/src/tags/ExclusiveMinimum.ts +8 -0
  201. package/src/tags/Format.ts +29 -0
  202. package/src/tags/MaxItems.ts +8 -0
  203. package/src/tags/MaxLength.ts +8 -0
  204. package/src/tags/Maximum.ts +8 -0
  205. package/src/tags/MinItems.ts +8 -0
  206. package/src/tags/MinLength.ts +8 -0
  207. package/src/tags/Minimum.ts +8 -0
  208. package/src/tags/MultipleOf.ts +10 -0
  209. package/src/tags/Pattern.ts +8 -0
  210. package/src/tags/TagBase.ts +17 -0
  211. package/src/tags/Type.ts +30 -0
  212. package/src/tags/index.ts +12 -0
  213. package/src/transformers/features/json/JsonApplicationTransformer.ts +111 -111
  214. package/src/transformers/features/misc/MetadataTransformer.ts +53 -53
  215. package/src/utils/RandomGenerator.ts +83 -81
  216. package/lib/schemas/metadata/IMetadataResolved.js.map +0 -1
  217. package/lib/schemas/metadata/MetadataResolved.js.map +0 -1
@@ -1,637 +1,643 @@
1
- import { Atomic } from "../../typings/Atomic";
2
- import { ClassProperties } from "../../typings/ClassProperties";
3
- import { Writable } from "../../typings/Writable";
4
-
5
- import { ArrayUtil } from "../../utils/ArrayUtil";
6
-
7
- import { IMetadata } from "./IMetadata";
8
- import { IMetadataCollection } from "./IMetadataCollection";
9
- import { IMetadataDictionary } from "./IMetadataDictionary";
10
- import { MetadataAlias } from "./MetadataAlias";
11
- import { MetadataArray } from "./MetadataArray";
12
- import { MetadataConstant } from "./MetadataConstant";
13
- import { MetadataObject } from "./MetadataObject";
14
- import { MetadataProperty } from "./MetadataProperty";
15
- import { MetadataResolved } from "./MetadataResolved";
16
- import { MetadataTuple } from "./MetadataTuple";
17
-
18
- export class Metadata {
19
- public any: boolean;
20
- public required: boolean;
21
- public optional: boolean;
22
- public nullable: boolean;
23
- public functional: boolean;
24
-
25
- public resolved: MetadataResolved | null;
26
- public atomics: Atomic.Literal[];
27
- public constants: MetadataConstant[];
28
- public templates: Metadata[][];
29
-
30
- public rest: Metadata | null;
31
- public aliases: MetadataAlias[];
32
- public arrays: MetadataArray[];
33
- public tuples: MetadataTuple[];
34
- public objects: MetadataObject[];
35
-
36
- public natives: string[];
37
- public sets: Metadata[];
38
- public maps: Metadata.Entry[];
39
-
40
- /** @internal */ private name_?: string;
41
- /** @internal */ private parent_resolved_: boolean = false;
42
- /** @internal */ public union_index?: number;
43
- /** @internal */ public fixed_?: number | null;
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.optional = props.optional;
55
- this.nullable = props.nullable;
56
- this.functional = props.functional;
57
-
58
- this.resolved = props.resolved;
59
- this.atomics = props.atomics;
60
- this.constants = props.constants;
61
- this.templates = props.templates;
62
-
63
- this.rest = props.rest;
64
- this.arrays = props.arrays;
65
- this.tuples = props.tuples;
66
- this.objects = props.objects;
67
- this.aliases = props.aliases;
68
-
69
- this.natives = props.natives;
70
- this.sets = props.sets;
71
- this.maps = props.maps;
72
- }
73
-
74
- /**
75
- * @internal
76
- */
77
- public static create(props: ClassProperties<Metadata>): Metadata {
78
- return new Metadata(props);
79
- }
80
-
81
- /**
82
- * @internal
83
- */
84
- public static initialize(parentResolved: boolean = false): Metadata {
85
- const meta: Metadata = this.create({
86
- any: false,
87
- nullable: false,
88
- required: true,
89
- optional: false,
90
- functional: false,
91
-
92
- resolved: null,
93
- constants: [],
94
- atomics: [],
95
- templates: [],
96
- arrays: [],
97
- tuples: [],
98
- objects: [],
99
- aliases: [],
100
-
101
- rest: null,
102
- natives: [],
103
- sets: [],
104
- maps: [],
105
- });
106
- meta.parent_resolved_ = parentResolved;
107
- return meta;
108
- }
109
-
110
- public toJSON(): IMetadata {
111
- return {
112
- any: this.any,
113
- required: this.required,
114
- optional: this.optional,
115
- nullable: this.nullable,
116
- functional: this.functional,
117
-
118
- atomics: this.atomics.slice(),
119
- constants: JSON.parse(JSON.stringify(this.constants)),
120
- templates: this.templates.map((tpl) =>
121
- tpl.map((meta) => meta.toJSON()),
122
- ),
123
- resolved: this.resolved ? this.resolved.toJSON() : null,
124
-
125
- rest: this.rest ? this.rest.toJSON() : null,
126
- arrays: this.arrays.map((array) => array.name),
127
- tuples: this.tuples.map((tuple) => tuple.name),
128
- objects: this.objects.map((obj) => obj.name),
129
- aliases: this.aliases.map((alias) => alias.name),
130
-
131
- natives: this.natives.slice(),
132
- sets: this.sets.map((meta) => meta.toJSON()),
133
- maps: this.maps.map((entry) => ({
134
- key: entry.key.toJSON(),
135
- value: entry.value.toJSON(),
136
- })),
137
- };
138
- }
139
-
140
- public static from(
141
- meta: IMetadata,
142
- collection: IMetadataCollection,
143
- ): Metadata {
144
- const dict: IMetadataDictionary = {
145
- objects: new Map(
146
- collection.objects.map((obj) => [
147
- obj.name,
148
- MetadataObject._From_without_properties(obj),
149
- ]),
150
- ),
151
- aliases: new Map(
152
- collection.aliases.map((alias) => [
153
- alias.name,
154
- MetadataAlias._From_without_value(alias),
155
- ]),
156
- ),
157
- arrays: new Map(
158
- collection.arrays.map((arr) => [
159
- arr.name,
160
- MetadataArray._From_without_value(arr),
161
- ]),
162
- ),
163
- tuples: new Map(
164
- collection.tuples.map((tpl) => [
165
- tpl.name,
166
- MetadataTuple._From_without_elements(tpl),
167
- ]),
168
- ),
169
- };
170
-
171
- for (const obj of collection.objects) {
172
- const initialized = dict.objects.get(obj.name)!;
173
- initialized.properties.push(
174
- ...obj.properties.map((prop) =>
175
- MetadataProperty._From(prop, dict),
176
- ),
177
- );
178
- }
179
- for (const alias of collection.aliases)
180
- Writable(dict.aliases.get(alias.name)!).value = this._From(
181
- alias.value,
182
- dict,
183
- );
184
- for (const array of collection.arrays)
185
- Writable(dict.arrays.get(array.name)!).value = this._From(
186
- array.value,
187
- dict,
188
- );
189
- for (const tuple of collection.tuples)
190
- Writable(dict.tuples.get(tuple.name)!).elements =
191
- tuple.elements.map((elem) => this._From(elem, dict));
192
-
193
- return this._From(meta, dict);
194
- }
195
-
196
- /**
197
- * @internal
198
- */
199
- public static _From(meta: IMetadata, dict: IMetadataDictionary): Metadata {
200
- return this.create({
201
- any: meta.any,
202
- required: meta.required,
203
- optional: meta.optional,
204
- nullable: meta.nullable,
205
- functional: meta.functional,
206
-
207
- constants: JSON.parse(JSON.stringify(meta.constants)),
208
- atomics: meta.atomics.slice(),
209
- templates: meta.templates.map((tpl) =>
210
- tpl.map((meta) => this._From(meta, dict)),
211
- ),
212
- resolved: meta.resolved
213
- ? MetadataResolved._From(meta.resolved, dict)
214
- : null,
215
-
216
- rest: meta.rest ? this._From(meta.rest, dict) : null,
217
- arrays: meta.arrays.map((id) => {
218
- const array = dict.arrays.get(id);
219
- if (array === undefined)
220
- throw new Error(
221
- `Error on Metadata.from(): failed to find array "${id}".`,
222
- );
223
- return array;
224
- }),
225
- tuples: meta.tuples.map((id) => {
226
- const tuple = dict.tuples.get(id);
227
- if (tuple === undefined)
228
- throw new Error(
229
- `Error on Metadata.from(): failed to find tuple "${id}".`,
230
- );
231
- return tuple;
232
- }),
233
- objects: meta.objects.map((name) => {
234
- const found = dict.objects.get(name);
235
- if (found === undefined)
236
- throw new Error(
237
- `Error on Metadata.from(): failed to find object "${name}".`,
238
- );
239
- return found;
240
- }),
241
- aliases: meta.aliases.map((alias) => {
242
- const found = dict.aliases.get(alias);
243
- if (found === undefined)
244
- throw new Error(
245
- `Error on Metadata.from(): failed to find alias "${alias}".`,
246
- );
247
- return found;
248
- }),
249
-
250
- natives: meta.natives.slice(),
251
- sets: meta.sets.map((meta) => this._From(meta, dict)),
252
- maps: meta.maps.map((entry) => ({
253
- key: this._From(entry.key, dict),
254
- value: this._From(entry.value, dict),
255
- })),
256
- });
257
- }
258
-
259
- /* -----------------------------------------------------------
260
- ACCESSORS
261
- ----------------------------------------------------------- */
262
- public getName(): string {
263
- this.name_ ??= getName(this);
264
- return this.name_;
265
- }
266
-
267
- public empty(): boolean {
268
- return this.bucket() === 0 || this.size() === 0;
269
- }
270
-
271
- public size(): number {
272
- return (
273
- (this.any ? 1 : 0) +
274
- (this.resolved ? 1 : 0) +
275
- (this.functional ? 1 : 0) +
276
- (this.rest ? this.rest.size() : 0) +
277
- this.templates.length +
278
- this.atomics.length +
279
- this.constants
280
- .map((c) => c.values.length)
281
- .reduce((x, y) => x + y, 0) +
282
- this.arrays.length +
283
- this.tuples.length +
284
- this.natives.length +
285
- this.maps.length +
286
- this.sets.length +
287
- this.objects.length +
288
- this.aliases.length
289
- );
290
- }
291
-
292
- /**
293
- * @internal
294
- */
295
- public binarySize(): number {
296
- return (
297
- new Set([
298
- ...this.atomics,
299
- ...this.constants.map((c) => c.type),
300
- ...(this.templates.length ? ["string"] : []),
301
- ]).size +
302
- this.arrays.length +
303
- this.tuples.length +
304
- this.natives.length +
305
- this.objects.length +
306
- this.maps.length
307
- );
308
- }
309
-
310
- public bucket(): number {
311
- return (
312
- (this.any ? 1 : 0) +
313
- (this.resolved ? 1 : 0) +
314
- (this.functional ? 1 : 0) +
315
- (this.templates.length ? 1 : 0) +
316
- (this.atomics.length ? 1 : 0) +
317
- (this.constants.length ? 1 : 0) +
318
- (this.rest ? this.rest.size() : 0) +
319
- (this.arrays.length ? 1 : 0) +
320
- (this.tuples.length ? 1 : 0) +
321
- (this.natives.length ? 1 : 0) +
322
- (this.sets.length ? 1 : 0) +
323
- (this.maps.length ? 1 : 0) +
324
- (this.objects.length ? 1 : 0) +
325
- (this.aliases.length ? 1 : 0)
326
- );
327
- }
328
-
329
- public isConstant(): boolean {
330
- return this.bucket() === (this.constants.length ? 1 : 0);
331
- }
332
-
333
- public isRequired(): boolean {
334
- return this.required === true && this.optional === false;
335
- }
336
-
337
- /**
338
- * @internal
339
- */
340
- public isUnionBucket(): boolean {
341
- const size: number = this.bucket();
342
- const emended: number =
343
- !!this.atomics.length && !!this.constants.length ? size - 1 : size;
344
- return emended > 1;
345
- }
346
-
347
- /**
348
- * @internal
349
- */
350
- public isBinaryUnion(): boolean {
351
- return this.binarySize() > 1;
352
- }
353
-
354
- /**
355
- * @internal
356
- */
357
- public getSoleLiteral(): string | null {
358
- if (
359
- this.size() === 1 &&
360
- this.constants.length === 1 &&
361
- this.constants[0]!.type === "string" &&
362
- this.constants[0]!.values.length === 1
363
- )
364
- return this.constants[0]!.values[0] as string;
365
- else return null;
366
- }
367
-
368
- public isSoleLiteral(): boolean {
369
- return this.getSoleLiteral() !== null;
370
- }
371
-
372
- /**
373
- * @internal
374
- */
375
- public isParentResolved(): boolean {
376
- return this.parent_resolved_;
377
- }
378
- }
379
- export namespace Metadata {
380
- export const intersects = (x: Metadata, y: Metadata): boolean => {
381
- // CHECK ANY & OPTIONAL
382
- if (x.any || y.any) return true;
383
- if (x.isRequired() === false && false === y.isRequired()) return true;
384
- if (x.nullable === true && true === y.nullable) return true;
385
- if (x.functional === true && y.functional === true) return true;
386
-
387
- //----
388
- // INSTANCES
389
- //----
390
- // ARRAYS
391
- if (x.arrays.length && y.arrays.length) return true;
392
- if (x.tuples.length && y.tuples.length) return true;
393
- if (x.objects.length && y.objects.length) return true;
394
- if (x.aliases.length && y.aliases.length) return true;
395
-
396
- // NATIVES
397
- if (x.natives.length && y.natives.length)
398
- if (x.natives.some((xn) => y.natives.some((yn) => xn === yn)))
399
- return true;
400
-
401
- //----
402
- // VALUES
403
- //----
404
- // ATOMICS
405
- for (const atomic of x.atomics)
406
- if (y.atomics.includes(atomic)) return true;
407
-
408
- // CONSTANTS
409
- for (const constant of x.constants) {
410
- const opposite: MetadataConstant | undefined = y.constants.find(
411
- (elem) => elem.type === constant.type,
412
- );
413
- if (opposite === undefined) continue;
414
-
415
- const values: Set<any> = new Set([
416
- ...constant.values,
417
- ...opposite.values,
418
- ]);
419
- if (values.size !== constant.values.length + opposite.values.length)
420
- return true;
421
- }
422
- return false;
423
- };
424
-
425
- export const covers = (
426
- x: Metadata,
427
- y: Metadata,
428
- level: number = 0,
429
- ): boolean => {
430
- // CHECK ANY
431
- if (x === y) return false;
432
- else if (x.any) return true;
433
- else if (y.any) return false;
434
-
435
- //----
436
- // INSTANCES
437
- //----
438
- if (level === 0) {
439
- // ARRAYS
440
- for (const ya of y.arrays)
441
- if (
442
- !x.arrays.some((xa) =>
443
- covers(xa.value, ya.value, level + 1),
444
- )
445
- ) {
446
- return false;
447
- }
448
-
449
- // TUPLES
450
- for (const yt of y.tuples)
451
- if (
452
- yt.elements.length !== 0 &&
453
- x.tuples.some(
454
- (xt) =>
455
- xt.elements.length >= yt.elements.length &&
456
- xt.elements
457
- .slice(yt.elements.length)
458
- .every((xv, i) =>
459
- covers(xv, yt.elements[i]!, level + 1),
460
- ),
461
- ) === false
462
- )
463
- return false;
464
- }
465
-
466
- // OBJECTS
467
- for (const yo of y.objects)
468
- if (x.objects.some((xo) => MetadataObject.covers(xo, yo)) === false)
469
- return false;
470
-
471
- // ALIASES
472
- for (const yd of y.aliases)
473
- if (x.aliases.some((xd) => xd.name === yd.name) === false)
474
- return false;
475
-
476
- // NATIVES
477
- for (const yn of y.natives)
478
- if (x.natives.some((xn) => xn === yn) === false) return false;
479
-
480
- // SETS
481
- for (const ys of y.sets)
482
- if (x.sets.some((xs) => covers(xs, ys)) === false) return false;
483
-
484
- //----
485
- // VALUES
486
- //----
487
- // ATOMICS
488
- if (y.atomics.some((atomic) => x.atomics.includes(atomic) === false))
489
- return false;
490
-
491
- // CONSTANTS
492
- for (const yc of y.constants) {
493
- if (x.atomics.some((type) => yc.type === type)) continue;
494
- const xc: MetadataConstant | undefined = x.constants.find(
495
- (elem) => elem.type === yc.type,
496
- );
497
- if (xc === undefined) return false;
498
- else if (
499
- (yc.values as number[]).some(
500
- (yv) => xc.values.includes(yv as never) === false,
501
- )
502
- )
503
- return false;
504
- }
505
-
506
- // FUNCTIONAL
507
- if (x.functional === false && y.functional) return false;
508
-
509
- // SUCCESS
510
- return true;
511
- };
512
-
513
- /**
514
- * @internal
515
- */
516
- export const merge = (x: Metadata, y: Metadata): Metadata => {
517
- const output: Metadata = Metadata.create({
518
- any: x.any || y.any,
519
- nullable: x.nullable || y.nullable,
520
- required: x.required && y.required,
521
- optional: x.optional || y.optional,
522
- functional: x.functional || y.functional,
523
-
524
- resolved:
525
- x.resolved !== null && y.resolved !== null
526
- ? //? merge(x.resolved, y.resolved)
527
- MetadataResolved.create({
528
- original: merge(
529
- x.resolved.original,
530
- y.resolved.original,
531
- ),
532
- returns: merge(
533
- x.resolved.returns,
534
- y.resolved.returns,
535
- ),
536
- })
537
- : x.resolved ?? y.resolved,
538
- atomics: [...new Set([...x.atomics, ...y.atomics])],
539
- constants: [...x.constants],
540
- templates: x.templates.slice(),
541
-
542
- rest:
543
- x.rest !== null && y.rest !== null
544
- ? merge(x.rest, y.rest)
545
- : x.rest ?? y.rest,
546
- arrays: x.arrays.slice(),
547
- tuples: x.tuples.slice(),
548
- objects: x.objects.slice(),
549
- aliases: x.aliases.slice(),
550
-
551
- natives: [...new Set([...x.natives, ...y.natives])],
552
- sets: x.sets.slice(),
553
- maps: x.maps.slice(),
554
- });
555
- for (const constant of y.constants) {
556
- const target: MetadataConstant = ArrayUtil.take(
557
- output.constants,
558
- (elem) => elem.type === constant.type,
559
- () => ({
560
- type: constant.type,
561
- values: [],
562
- }),
563
- );
564
- for (const value of constant.values)
565
- ArrayUtil.add(target.values, value);
566
- }
567
- for (const array of y.arrays)
568
- ArrayUtil.set(output.arrays, array, (elem) => elem.name);
569
- for (const tuple of y.tuples)
570
- ArrayUtil.set(output.tuples, tuple, (elem) => elem.name);
571
- for (const obj of y.objects)
572
- ArrayUtil.set(output.objects, obj, (elem) => elem.name);
573
- for (const alias of y.aliases)
574
- ArrayUtil.set(output.aliases, alias, (elem) => elem.name);
575
-
576
- return output;
577
- };
578
- }
579
-
580
- const getName = (metadata: Metadata): string => {
581
- if (metadata.any === true) return "any";
582
-
583
- const elements: string[] = [];
584
-
585
- // OPTIONAL
586
- if (metadata.nullable === true) elements.push("null");
587
- if (metadata.isRequired() === false) elements.push("undefined");
588
-
589
- // ATOMIC
590
- for (const type of metadata.atomics) {
591
- elements.push(type);
592
- }
593
- for (const constant of metadata.constants)
594
- for (const value of constant.values)
595
- elements.push(JSON.stringify(value));
596
- for (const template of metadata.templates)
597
- elements.push(
598
- "`" +
599
- template
600
- .map((child) =>
601
- child.isConstant() && child.size() === 1
602
- ? child.constants[0]!.values[0]!
603
- : `$\{${child.getName()}\}`,
604
- )
605
- .join("")
606
- .split("`")
607
- .join("\\`") +
608
- "`",
609
- );
610
-
611
- // NATIVES
612
- for (const native of metadata.natives) elements.push(native);
613
- for (const set of metadata.sets) elements.push(`Set<${set.getName()}>`);
614
- for (const map of metadata.maps)
615
- elements.push(`Map<${map.key.getName()}, ${map.value.getName()}>`);
616
-
617
- // INSTANCES
618
- if (metadata.rest !== null) elements.push(`...${metadata.rest.getName()}`);
619
- for (const tuple of metadata.tuples) elements.push(tuple.name);
620
- for (const array of metadata.arrays) elements.push(array.name);
621
- for (const object of metadata.objects) elements.push(object.name);
622
- for (const alias of metadata.aliases) elements.push(alias.name);
623
- if (metadata.resolved !== null) elements.push(metadata.resolved.getName());
624
-
625
- // RETURNS
626
- if (elements.length === 0) return "unknown";
627
- else if (elements.length === 1) return elements[0]!;
628
-
629
- elements.sort();
630
- return `(${elements.join(" | ")})`;
631
- };
632
- export namespace Metadata {
633
- export interface Entry {
634
- key: Metadata;
635
- value: Metadata;
636
- }
637
- }
1
+ import { ClassProperties } from "../../typings/ClassProperties";
2
+ import { Writable } from "../../typings/Writable";
3
+
4
+ import { ArrayUtil } from "../../utils/ArrayUtil";
5
+
6
+ import { IMetadata } from "./IMetadata";
7
+ import { IMetadataAtomic } from "./IMetadataAtomic";
8
+ import { IMetadataCollection } from "./IMetadataCollection";
9
+ import { IMetadataDictionary } from "./IMetadataDictionary";
10
+ import { MetadataAlias } from "./MetadataAlias";
11
+ import { MetadataArray } from "./MetadataArray";
12
+ import { MetadataConstant } from "./MetadataConstant";
13
+ import { MetadataEscaped } from "./MetadataEscaped";
14
+ import { MetadataObject } from "./MetadataObject";
15
+ import { MetadataProperty } from "./MetadataProperty";
16
+ import { MetadataTuple } from "./MetadataTuple";
17
+
18
+ export class Metadata {
19
+ public any: boolean;
20
+ public required: boolean;
21
+ public optional: boolean;
22
+ public nullable: boolean;
23
+ public functional: boolean;
24
+
25
+ public escaped: MetadataEscaped | null;
26
+ public atomics: IMetadataAtomic[];
27
+ public constants: MetadataConstant[];
28
+ public templates: Metadata[][];
29
+
30
+ public rest: Metadata | null;
31
+ public aliases: MetadataAlias[];
32
+ public arrays: MetadataArray[];
33
+ public tuples: MetadataTuple[];
34
+ public objects: MetadataObject[];
35
+
36
+ public natives: string[];
37
+ public sets: Metadata[];
38
+ public maps: Metadata.Entry[];
39
+
40
+ /** @internal */ private name_?: string;
41
+ /** @internal */ private parent_resolved_: boolean = false;
42
+ /** @internal */ public union_index?: number;
43
+ /** @internal */ public fixed_?: number | null;
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.optional = props.optional;
55
+ this.nullable = props.nullable;
56
+ this.functional = props.functional;
57
+
58
+ this.escaped = props.escaped;
59
+ this.atomics = props.atomics;
60
+ this.constants = props.constants;
61
+ this.templates = props.templates;
62
+
63
+ this.rest = props.rest;
64
+ this.arrays = props.arrays;
65
+ this.tuples = props.tuples;
66
+ this.objects = props.objects;
67
+ this.aliases = props.aliases;
68
+
69
+ this.natives = props.natives;
70
+ this.sets = props.sets;
71
+ this.maps = props.maps;
72
+ }
73
+
74
+ /**
75
+ * @internal
76
+ */
77
+ public static create(props: ClassProperties<Metadata>): Metadata {
78
+ return new Metadata(props);
79
+ }
80
+
81
+ /**
82
+ * @internal
83
+ */
84
+ public static initialize(parentResolved: boolean = false): Metadata {
85
+ const meta: Metadata = this.create({
86
+ any: false,
87
+ nullable: false,
88
+ required: true,
89
+ optional: false,
90
+ functional: false,
91
+
92
+ escaped: null,
93
+ constants: [],
94
+ atomics: [],
95
+ templates: [],
96
+ arrays: [],
97
+ tuples: [],
98
+ objects: [],
99
+ aliases: [],
100
+
101
+ rest: null,
102
+ natives: [],
103
+ sets: [],
104
+ maps: [],
105
+ });
106
+ meta.parent_resolved_ = parentResolved;
107
+ return meta;
108
+ }
109
+
110
+ public toJSON(): IMetadata {
111
+ return {
112
+ any: this.any,
113
+ required: this.required,
114
+ optional: this.optional,
115
+ nullable: this.nullable,
116
+ functional: this.functional,
117
+
118
+ atomics: JSON.parse(JSON.stringify(this.atomics)),
119
+ constants: JSON.parse(JSON.stringify(this.constants)),
120
+ templates: this.templates.map((tpl) =>
121
+ tpl.map((meta) => meta.toJSON()),
122
+ ),
123
+ escaped: this.escaped ? this.escaped.toJSON() : null,
124
+
125
+ rest: this.rest ? this.rest.toJSON() : null,
126
+ arrays: this.arrays.map((array) => array.name),
127
+ tuples: this.tuples.map((tuple) => tuple.name),
128
+ objects: this.objects.map((obj) => obj.name),
129
+ aliases: this.aliases.map((alias) => alias.name),
130
+
131
+ natives: this.natives.slice(),
132
+ sets: this.sets.map((meta) => meta.toJSON()),
133
+ maps: this.maps.map((entry) => ({
134
+ key: entry.key.toJSON(),
135
+ value: entry.value.toJSON(),
136
+ })),
137
+ };
138
+ }
139
+
140
+ public static from(
141
+ meta: IMetadata,
142
+ collection: IMetadataCollection,
143
+ ): Metadata {
144
+ const dict: IMetadataDictionary = {
145
+ objects: new Map(
146
+ collection.objects.map((obj) => [
147
+ obj.name,
148
+ MetadataObject._From_without_properties(obj),
149
+ ]),
150
+ ),
151
+ aliases: new Map(
152
+ collection.aliases.map((alias) => [
153
+ alias.name,
154
+ MetadataAlias._From_without_value(alias),
155
+ ]),
156
+ ),
157
+ arrays: new Map(
158
+ collection.arrays.map((arr) => [
159
+ arr.name,
160
+ MetadataArray._From_without_value(arr),
161
+ ]),
162
+ ),
163
+ tuples: new Map(
164
+ collection.tuples.map((tpl) => [
165
+ tpl.name,
166
+ MetadataTuple._From_without_elements(tpl),
167
+ ]),
168
+ ),
169
+ };
170
+
171
+ for (const obj of collection.objects) {
172
+ const initialized = dict.objects.get(obj.name)!;
173
+ initialized.properties.push(
174
+ ...obj.properties.map((prop) =>
175
+ MetadataProperty._From(prop, dict),
176
+ ),
177
+ );
178
+ }
179
+ for (const alias of collection.aliases)
180
+ Writable(dict.aliases.get(alias.name)!).value = this._From(
181
+ alias.value,
182
+ dict,
183
+ );
184
+ for (const array of collection.arrays)
185
+ Writable(dict.arrays.get(array.name)!).value = this._From(
186
+ array.value,
187
+ dict,
188
+ );
189
+ for (const tuple of collection.tuples)
190
+ Writable(dict.tuples.get(tuple.name)!).elements =
191
+ tuple.elements.map((elem) => this._From(elem, dict));
192
+
193
+ return this._From(meta, dict);
194
+ }
195
+
196
+ /**
197
+ * @internal
198
+ */
199
+ public static _From(meta: IMetadata, dict: IMetadataDictionary): Metadata {
200
+ return this.create({
201
+ any: meta.any,
202
+ required: meta.required,
203
+ optional: meta.optional,
204
+ nullable: meta.nullable,
205
+ functional: meta.functional,
206
+
207
+ constants: JSON.parse(JSON.stringify(meta.constants)),
208
+ atomics: JSON.parse(JSON.stringify(meta.atomics)),
209
+ templates: meta.templates.map((tpl) =>
210
+ tpl.map((meta) => this._From(meta, dict)),
211
+ ),
212
+ escaped: meta.escaped
213
+ ? MetadataEscaped._From(meta.escaped, dict)
214
+ : null,
215
+
216
+ rest: meta.rest ? this._From(meta.rest, dict) : null,
217
+ arrays: meta.arrays.map((id) => {
218
+ const array = dict.arrays.get(id);
219
+ if (array === undefined)
220
+ throw new Error(
221
+ `Error on Metadata.from(): failed to find array "${id}".`,
222
+ );
223
+ return array;
224
+ }),
225
+ tuples: meta.tuples.map((id) => {
226
+ const tuple = dict.tuples.get(id);
227
+ if (tuple === undefined)
228
+ throw new Error(
229
+ `Error on Metadata.from(): failed to find tuple "${id}".`,
230
+ );
231
+ return tuple;
232
+ }),
233
+ objects: meta.objects.map((name) => {
234
+ const found = dict.objects.get(name);
235
+ if (found === undefined)
236
+ throw new Error(
237
+ `Error on Metadata.from(): failed to find object "${name}".`,
238
+ );
239
+ return found;
240
+ }),
241
+ aliases: meta.aliases.map((alias) => {
242
+ const found = dict.aliases.get(alias);
243
+ if (found === undefined)
244
+ throw new Error(
245
+ `Error on Metadata.from(): failed to find alias "${alias}".`,
246
+ );
247
+ return found;
248
+ }),
249
+
250
+ natives: meta.natives.slice(),
251
+ sets: meta.sets.map((meta) => this._From(meta, dict)),
252
+ maps: meta.maps.map((entry) => ({
253
+ key: this._From(entry.key, dict),
254
+ value: this._From(entry.value, dict),
255
+ })),
256
+ });
257
+ }
258
+
259
+ /* -----------------------------------------------------------
260
+ ACCESSORS
261
+ ----------------------------------------------------------- */
262
+ public getName(): string {
263
+ this.name_ ??= getName(this);
264
+ return this.name_;
265
+ }
266
+
267
+ public empty(): boolean {
268
+ return this.bucket() === 0 || this.size() === 0;
269
+ }
270
+
271
+ public size(): number {
272
+ return (
273
+ (this.any ? 1 : 0) +
274
+ (this.escaped ? 1 : 0) +
275
+ (this.functional ? 1 : 0) +
276
+ (this.rest ? this.rest.size() : 0) +
277
+ this.templates.length +
278
+ this.atomics.length +
279
+ this.constants
280
+ .map((c) => c.values.length)
281
+ .reduce((x, y) => x + y, 0) +
282
+ this.arrays.length +
283
+ this.tuples.length +
284
+ this.natives.length +
285
+ this.maps.length +
286
+ this.sets.length +
287
+ this.objects.length +
288
+ this.aliases.length
289
+ );
290
+ }
291
+
292
+ /**
293
+ * @internal
294
+ */
295
+ public binarySize(): number {
296
+ return (
297
+ new Set<string>([
298
+ ...this.atomics.map((a) => a.type),
299
+ ...this.constants.map((c) => c.type),
300
+ ...(this.templates.length ? ["string"] : []),
301
+ ]).size +
302
+ this.arrays.length +
303
+ this.tuples.length +
304
+ this.natives.length +
305
+ this.objects.length +
306
+ this.maps.length
307
+ );
308
+ }
309
+
310
+ public bucket(): number {
311
+ return (
312
+ (this.any ? 1 : 0) +
313
+ (this.escaped ? 1 : 0) +
314
+ (this.functional ? 1 : 0) +
315
+ (this.templates.length ? 1 : 0) +
316
+ (this.atomics.length ? 1 : 0) +
317
+ (this.constants.length ? 1 : 0) +
318
+ (this.rest ? this.rest.size() : 0) +
319
+ (this.arrays.length ? 1 : 0) +
320
+ (this.tuples.length ? 1 : 0) +
321
+ (this.natives.length ? 1 : 0) +
322
+ (this.sets.length ? 1 : 0) +
323
+ (this.maps.length ? 1 : 0) +
324
+ (this.objects.length ? 1 : 0) +
325
+ (this.aliases.length ? 1 : 0)
326
+ );
327
+ }
328
+
329
+ public isConstant(): boolean {
330
+ return this.bucket() === (this.constants.length ? 1 : 0);
331
+ }
332
+
333
+ public isRequired(): boolean {
334
+ return this.required === true && this.optional === false;
335
+ }
336
+
337
+ /**
338
+ * @internal
339
+ */
340
+ public isUnionBucket(): boolean {
341
+ const size: number = this.bucket();
342
+ const emended: number =
343
+ !!this.atomics.length && !!this.constants.length ? size - 1 : size;
344
+ return emended > 1;
345
+ }
346
+
347
+ /**
348
+ * @internal
349
+ */
350
+ public isBinaryUnion(): boolean {
351
+ return this.binarySize() > 1;
352
+ }
353
+
354
+ /**
355
+ * @internal
356
+ */
357
+ public getSoleLiteral(): string | null {
358
+ if (
359
+ this.size() === 1 &&
360
+ this.constants.length === 1 &&
361
+ this.constants[0]!.type === "string" &&
362
+ this.constants[0]!.values.length === 1
363
+ )
364
+ return this.constants[0]!.values[0] as string;
365
+ else return null;
366
+ }
367
+
368
+ public isSoleLiteral(): boolean {
369
+ return this.getSoleLiteral() !== null;
370
+ }
371
+
372
+ /**
373
+ * @internal
374
+ */
375
+ public isParentResolved(): boolean {
376
+ return this.parent_resolved_;
377
+ }
378
+ }
379
+ export namespace Metadata {
380
+ export const intersects = (x: Metadata, y: Metadata): boolean => {
381
+ // CHECK ANY & OPTIONAL
382
+ if (x.any || y.any) return true;
383
+ if (x.isRequired() === false && false === y.isRequired()) return true;
384
+ if (x.nullable === true && true === y.nullable) return true;
385
+ if (x.functional === true && y.functional === true) return true;
386
+
387
+ //----
388
+ // INSTANCES
389
+ //----
390
+ // ARRAYS
391
+ if (x.arrays.length && y.arrays.length) return true;
392
+ if (x.tuples.length && y.tuples.length) return true;
393
+ if (x.objects.length && y.objects.length) return true;
394
+ if (x.aliases.length && y.aliases.length) return true;
395
+
396
+ // NATIVES
397
+ if (x.natives.length && y.natives.length)
398
+ if (x.natives.some((xn) => y.natives.some((yn) => xn === yn)))
399
+ return true;
400
+
401
+ //----
402
+ // VALUES
403
+ //----
404
+ // ATOMICS
405
+ for (const atomic of x.atomics)
406
+ if (y.atomics.some((ya) => atomic.type === ya.type)) return true;
407
+
408
+ // CONSTANTS
409
+ for (const constant of x.constants) {
410
+ const opposite: MetadataConstant | undefined = y.constants.find(
411
+ (elem) => elem.type === constant.type,
412
+ );
413
+ if (opposite === undefined) continue;
414
+
415
+ const values: Set<any> = new Set([
416
+ ...constant.values,
417
+ ...opposite.values,
418
+ ]);
419
+ if (values.size !== constant.values.length + opposite.values.length)
420
+ return true;
421
+ }
422
+ return false;
423
+ };
424
+
425
+ export const covers = (
426
+ x: Metadata,
427
+ y: Metadata,
428
+ level: number = 0,
429
+ ): boolean => {
430
+ // CHECK ANY
431
+ if (x === y) return false;
432
+ else if (x.any) return true;
433
+ else if (y.any) return false;
434
+
435
+ //----
436
+ // INSTANCES
437
+ //----
438
+ if (level === 0) {
439
+ // ARRAYS
440
+ for (const ya of y.arrays)
441
+ if (
442
+ !x.arrays.some((xa) =>
443
+ covers(xa.value, ya.value, level + 1),
444
+ )
445
+ ) {
446
+ return false;
447
+ }
448
+
449
+ // TUPLES
450
+ for (const yt of y.tuples)
451
+ if (
452
+ yt.elements.length !== 0 &&
453
+ x.tuples.some(
454
+ (xt) =>
455
+ xt.elements.length >= yt.elements.length &&
456
+ xt.elements
457
+ .slice(yt.elements.length)
458
+ .every((xv, i) =>
459
+ covers(xv, yt.elements[i]!, level + 1),
460
+ ),
461
+ ) === false
462
+ )
463
+ return false;
464
+ }
465
+
466
+ // OBJECTS
467
+ for (const yo of y.objects)
468
+ if (x.objects.some((xo) => MetadataObject.covers(xo, yo)) === false)
469
+ return false;
470
+
471
+ // ALIASES
472
+ for (const yd of y.aliases)
473
+ if (x.aliases.some((xd) => xd.name === yd.name) === false)
474
+ return false;
475
+
476
+ // NATIVES
477
+ for (const yn of y.natives)
478
+ if (x.natives.some((xn) => xn === yn) === false) return false;
479
+
480
+ // SETS
481
+ for (const ys of y.sets)
482
+ if (x.sets.some((xs) => covers(xs, ys)) === false) return false;
483
+
484
+ //----
485
+ // VALUES
486
+ //----
487
+ // ATOMICS
488
+ if (
489
+ y.atomics.some(
490
+ (ya) => x.atomics.some((xa) => xa.type === ya.type) === false,
491
+ )
492
+ )
493
+ return false;
494
+
495
+ // CONSTANTS
496
+ for (const yc of y.constants) {
497
+ if (x.atomics.some((atom) => yc.type === atom.type)) continue;
498
+ const xc: MetadataConstant | undefined = x.constants.find(
499
+ (elem) => elem.type === yc.type,
500
+ );
501
+ if (xc === undefined) return false;
502
+ else if (
503
+ (yc.values as number[]).some(
504
+ (yv) => xc.values.includes(yv as never) === false,
505
+ )
506
+ )
507
+ return false;
508
+ }
509
+
510
+ // FUNCTIONAL
511
+ if (x.functional === false && y.functional) return false;
512
+
513
+ // SUCCESS
514
+ return true;
515
+ };
516
+
517
+ /**
518
+ * @internal
519
+ */
520
+ export const merge = (x: Metadata, y: Metadata): Metadata => {
521
+ const output: Metadata = Metadata.create({
522
+ any: x.any || y.any,
523
+ nullable: x.nullable || y.nullable,
524
+ required: x.required && y.required,
525
+ optional: x.optional || y.optional,
526
+ functional: x.functional || y.functional,
527
+
528
+ escaped:
529
+ x.escaped !== null && y.escaped !== null
530
+ ? //? merge(x.resolved, y.resolved)
531
+ MetadataEscaped.create({
532
+ original: merge(
533
+ x.escaped.original,
534
+ y.escaped.original,
535
+ ),
536
+ returns: merge(x.escaped.returns, y.escaped.returns),
537
+ })
538
+ : x.escaped ?? y.escaped,
539
+ atomics: [
540
+ ...new Set([
541
+ ...x.atomics.map((a) => a.type),
542
+ ...y.atomics.map((a) => a.type),
543
+ ]),
544
+ ].map((type) => ({ type, tags: [] })),
545
+ constants: [...x.constants],
546
+ templates: x.templates.slice(),
547
+
548
+ rest:
549
+ x.rest !== null && y.rest !== null
550
+ ? merge(x.rest, y.rest)
551
+ : x.rest ?? y.rest,
552
+ arrays: x.arrays.slice(),
553
+ tuples: x.tuples.slice(),
554
+ objects: x.objects.slice(),
555
+ aliases: x.aliases.slice(),
556
+
557
+ natives: [...new Set([...x.natives, ...y.natives])],
558
+ sets: x.sets.slice(),
559
+ maps: x.maps.slice(),
560
+ });
561
+ for (const constant of y.constants) {
562
+ const target: MetadataConstant = ArrayUtil.take(
563
+ output.constants,
564
+ (elem) => elem.type === constant.type,
565
+ () => ({
566
+ type: constant.type,
567
+ values: [],
568
+ }),
569
+ );
570
+ for (const value of constant.values)
571
+ ArrayUtil.add(target.values, value);
572
+ }
573
+ for (const array of y.arrays)
574
+ ArrayUtil.set(output.arrays, array, (elem) => elem.name);
575
+ for (const tuple of y.tuples)
576
+ ArrayUtil.set(output.tuples, tuple, (elem) => elem.name);
577
+ for (const obj of y.objects)
578
+ ArrayUtil.set(output.objects, obj, (elem) => elem.name);
579
+ for (const alias of y.aliases)
580
+ ArrayUtil.set(output.aliases, alias, (elem) => elem.name);
581
+
582
+ return output;
583
+ };
584
+ }
585
+
586
+ const getName = (metadata: Metadata): string => {
587
+ if (metadata.any === true) return "any";
588
+
589
+ const elements: string[] = [];
590
+
591
+ // OPTIONAL
592
+ if (metadata.nullable === true) elements.push("null");
593
+ if (metadata.isRequired() === false) elements.push("undefined");
594
+
595
+ // ATOMIC
596
+ for (const atom of metadata.atomics) {
597
+ elements.push(atom.type);
598
+ }
599
+ for (const constant of metadata.constants)
600
+ for (const value of constant.values)
601
+ elements.push(JSON.stringify(value));
602
+ for (const template of metadata.templates)
603
+ elements.push(
604
+ "`" +
605
+ template
606
+ .map((child) =>
607
+ child.isConstant() && child.size() === 1
608
+ ? child.constants[0]!.values[0]!
609
+ : `$\{${child.getName()}\}`,
610
+ )
611
+ .join("")
612
+ .split("`")
613
+ .join("\\`") +
614
+ "`",
615
+ );
616
+
617
+ // NATIVES
618
+ for (const native of metadata.natives) elements.push(native);
619
+ for (const set of metadata.sets) elements.push(`Set<${set.getName()}>`);
620
+ for (const map of metadata.maps)
621
+ elements.push(`Map<${map.key.getName()}, ${map.value.getName()}>`);
622
+
623
+ // INSTANCES
624
+ if (metadata.rest !== null) elements.push(`...${metadata.rest.getName()}`);
625
+ for (const tuple of metadata.tuples) elements.push(tuple.name);
626
+ for (const array of metadata.arrays) elements.push(array.name);
627
+ for (const object of metadata.objects) elements.push(object.name);
628
+ for (const alias of metadata.aliases) elements.push(alias.name);
629
+ if (metadata.escaped !== null) elements.push(metadata.escaped.getName());
630
+
631
+ // RETURNS
632
+ if (elements.length === 0) return "unknown";
633
+ else if (elements.length === 1) return elements[0]!;
634
+
635
+ elements.sort();
636
+ return `(${elements.join(" | ")})`;
637
+ };
638
+ export namespace Metadata {
639
+ export interface Entry {
640
+ key: Metadata;
641
+ value: Metadata;
642
+ }
643
+ }