typia 5.1.4 → 5.1.5-dev.20230929

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 (88) hide show
  1. package/lib/TypeGuardError.d.ts +2 -2
  2. package/lib/executable/TypiaGenerateWizard.js.map +1 -1
  3. package/lib/executable/TypiaSetupWizard.js +16 -7
  4. package/lib/executable/TypiaSetupWizard.js.map +1 -1
  5. package/lib/factories/internal/metadata/emplace_metadata_object.js +25 -6
  6. package/lib/factories/internal/metadata/emplace_metadata_object.js.map +1 -1
  7. package/lib/programmers/CheckerProgrammer.d.ts +3 -3
  8. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  9. package/lib/programmers/FeatureProgrammer.d.ts +11 -11
  10. package/lib/programmers/FeatureProgrammer.js.map +1 -1
  11. package/lib/schemas/json/IJsonComponents.d.ts +12 -12
  12. package/lib/schemas/json/IJsonSchema.d.ts +32 -32
  13. package/lib/schemas/metadata/IMetadataObject.d.ts +1 -1
  14. package/lib/transformers/ITransformOptions.d.ts +4 -4
  15. package/package.json +1 -1
  16. package/src/TypeGuardError.ts +2 -2
  17. package/src/executable/TypiaGenerateWizard.ts +2 -2
  18. package/src/executable/TypiaSetupWizard.ts +7 -3
  19. package/src/factories/MetadataCollection.ts +277 -277
  20. package/src/factories/MetadataFactory.ts +238 -238
  21. package/src/factories/MetadataTypeTagFactory.ts +325 -325
  22. package/src/factories/internal/metadata/emend_metadata_atomics.ts +41 -41
  23. package/src/factories/internal/metadata/emplace_metadata_object.ts +30 -8
  24. package/src/factories/internal/metadata/iterate_metadata_intersection.ts +259 -259
  25. package/src/functional/$HeadersReader.ts +28 -28
  26. package/src/functional/$ParameterReader.ts +31 -31
  27. package/src/functional/$QueryReader.ts +56 -56
  28. package/src/functional/Namespace.ts +142 -142
  29. package/src/http.ts +1149 -1149
  30. package/src/json.ts +648 -648
  31. package/src/misc.ts +651 -651
  32. package/src/module.ts +657 -657
  33. package/src/programmers/CheckerProgrammer.ts +11 -9
  34. package/src/programmers/FeatureProgrammer.ts +25 -17
  35. package/src/programmers/helpers/HttpMetadataUtil.ts +21 -21
  36. package/src/programmers/helpers/RandomRanger.ts +1 -1
  37. package/src/programmers/http/HttpAssertHeadersProgrammer.ts +77 -77
  38. package/src/programmers/http/HttpAssertQueryProgrammer.ts +77 -77
  39. package/src/programmers/http/HttpHeadersProgrammer.ts +339 -339
  40. package/src/programmers/http/HttpIsHeadersProgrammer.ts +87 -87
  41. package/src/programmers/http/HttpIsQueryProgrammer.ts +87 -87
  42. package/src/programmers/http/HttpParameterProgrammer.ts +104 -104
  43. package/src/programmers/http/HttpQueryProgrammer.ts +273 -273
  44. package/src/programmers/http/HttpValidateHeadersProgrammer.ts +77 -77
  45. package/src/programmers/http/HttpValidateQueryProgrammer.ts +77 -77
  46. package/src/programmers/internal/application_boolean.ts +30 -30
  47. package/src/programmers/internal/application_number.ts +90 -90
  48. package/src/programmers/internal/application_object.ts +1 -1
  49. package/src/programmers/internal/application_schema.ts +180 -180
  50. package/src/programmers/internal/application_string.ts +54 -54
  51. package/src/programmers/internal/check_array_length.ts +44 -44
  52. package/src/programmers/internal/check_bigint.ts +48 -48
  53. package/src/programmers/internal/check_number.ts +108 -108
  54. package/src/programmers/internal/check_object.ts +2 -2
  55. package/src/programmers/internal/check_string.ts +48 -48
  56. package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +882 -882
  57. package/src/protobuf.ts +887 -887
  58. package/src/schemas/json/IJsonComponents.ts +36 -34
  59. package/src/schemas/json/IJsonSchema.ts +112 -112
  60. package/src/schemas/metadata/IMetadataConstant.ts +25 -25
  61. package/src/schemas/metadata/IMetadataObject.ts +1 -1
  62. package/src/schemas/metadata/IMetadataTypeTag.ts +8 -8
  63. package/src/schemas/metadata/Metadata.ts +686 -686
  64. package/src/tags/Default.ts +15 -15
  65. package/src/tags/Format.ts +30 -30
  66. package/src/tags/Pattern.ts +9 -9
  67. package/src/tags/TagBase.ts +68 -68
  68. package/src/tags/index.ts +14 -14
  69. package/src/transformers/CallExpressionTransformer.ts +289 -289
  70. package/src/transformers/ITransformOptions.ts +4 -4
  71. package/src/transformers/features/http/CreateHttpAssertHeadersTransformer.ts +12 -12
  72. package/src/transformers/features/http/CreateHttpAssertQueryTransformer.ts +12 -12
  73. package/src/transformers/features/http/CreateHttpHeadersTransformer.ts +9 -9
  74. package/src/transformers/features/http/CreateHttpIsHeadersTransformer.ts +9 -9
  75. package/src/transformers/features/http/CreateHttpIsQueryTransformer.ts +9 -9
  76. package/src/transformers/features/http/CreateHttpParameterTransformer.ts +9 -9
  77. package/src/transformers/features/http/CreateHttpQueryTransformer.ts +9 -9
  78. package/src/transformers/features/http/CreateHttpValidateHeadersTransformer.ts +12 -12
  79. package/src/transformers/features/http/CreateHttpValidateQueryTransformer.ts +12 -12
  80. package/src/transformers/features/http/HttpAssertHeadersTransformer.ts +10 -10
  81. package/src/transformers/features/http/HttpAssertQueryTransformer.ts +10 -10
  82. package/src/transformers/features/http/HttpHeadersTransformer.ts +9 -9
  83. package/src/transformers/features/http/HttpIsHeadersTransformer.ts +9 -9
  84. package/src/transformers/features/http/HttpIsQueryTransformer.ts +9 -9
  85. package/src/transformers/features/http/HttpParameterTransformer.ts +9 -9
  86. package/src/transformers/features/http/HttpQueryTransformer.ts +9 -9
  87. package/src/transformers/features/http/HttpValidateHeadersTransformer.ts +10 -10
  88. package/src/transformers/features/http/HttpValidateQueryTransformer.ts +10 -10
@@ -1,41 +1,41 @@
1
- import { Metadata } from "../../../schemas/metadata/Metadata";
2
- import { MetadataAtomic } from "../../../schemas/metadata/MetadataAtomic";
3
-
4
- import { ArrayUtil } from "../../../utils/ArrayUtil";
5
-
6
- export const emend_metadata_atomics = (meta: Metadata) => {
7
- // ATOMICS
8
- for (const a of meta.atomics) {
9
- const index: number = meta.constants.findIndex(
10
- (c) => c.type === a.type,
11
- );
12
- if (index !== -1) meta.constants.splice(index, 1);
13
- }
14
-
15
- // BOOLEAN
16
- {
17
- const index: number = meta.constants.findIndex(
18
- (c) => c.type === "boolean",
19
- );
20
- if (index !== -1 && meta.constants[index]!.values.length === 2) {
21
- const temp = meta.constants.splice(index, 1)[0]!;
22
- ArrayUtil.take(
23
- meta.atomics,
24
- (a) => a.type === "boolean",
25
- () =>
26
- MetadataAtomic.create({
27
- type: "boolean" as const,
28
- tags: temp.tags ?? [],
29
- }),
30
- );
31
- temp.tags = undefined;
32
- }
33
- }
34
-
35
- // TEMPLATE
36
- if (
37
- meta.templates.length &&
38
- meta.atomics.find((a) => a.type === "string") !== undefined
39
- )
40
- meta.templates.splice(0, meta.templates.length);
41
- };
1
+ import { Metadata } from "../../../schemas/metadata/Metadata";
2
+ import { MetadataAtomic } from "../../../schemas/metadata/MetadataAtomic";
3
+
4
+ import { ArrayUtil } from "../../../utils/ArrayUtil";
5
+
6
+ export const emend_metadata_atomics = (meta: Metadata) => {
7
+ // ATOMICS
8
+ for (const a of meta.atomics) {
9
+ const index: number = meta.constants.findIndex(
10
+ (c) => c.type === a.type,
11
+ );
12
+ if (index !== -1) meta.constants.splice(index, 1);
13
+ }
14
+
15
+ // BOOLEAN
16
+ {
17
+ const index: number = meta.constants.findIndex(
18
+ (c) => c.type === "boolean",
19
+ );
20
+ if (index !== -1 && meta.constants[index]!.values.length === 2) {
21
+ const temp = meta.constants.splice(index, 1)[0]!;
22
+ ArrayUtil.take(
23
+ meta.atomics,
24
+ (a) => a.type === "boolean",
25
+ () =>
26
+ MetadataAtomic.create({
27
+ type: "boolean" as const,
28
+ tags: temp.tags ?? [],
29
+ }),
30
+ );
31
+ temp.tags = undefined;
32
+ }
33
+ }
34
+
35
+ // TEMPLATE
36
+ if (
37
+ meta.templates.length &&
38
+ meta.atomics.find((a) => a.type === "string") !== undefined
39
+ )
40
+ meta.templates.splice(0, meta.templates.length);
41
+ };
@@ -13,6 +13,7 @@ import { MetadataCollection } from "../../MetadataCollection";
13
13
  import { MetadataFactory } from "../../MetadataFactory";
14
14
  import { MetadataHelper } from "./MetadataHelper";
15
15
  import { explore_metadata } from "./explore_metadata";
16
+ import { iterate_metadata_coalesce } from "./iterate_metadata_coalesce";
16
17
 
17
18
  export const emplace_metadata_object =
18
19
  (checker: ts.TypeChecker) =>
@@ -81,17 +82,12 @@ export const emplace_metadata_object =
81
82
 
82
83
  // CHECK NODE IS A FORMAL PROPERTY
83
84
  const [node, type] = (() => {
84
- const node = (prop.getDeclarations() ?? [])[0] as
85
+ const node = prop.getDeclarations()?.[0] as
85
86
  | ts.PropertyDeclaration
86
87
  | undefined;
87
88
  const type: ts.Type | undefined = node
88
89
  ? checker.getTypeOfSymbolAtLocation(prop, node)
89
- : "getTypeOfPropertyOfType" in checker
90
- ? (checker as any).getTypeOfPropertyOfType(
91
- parent,
92
- prop.name,
93
- )
94
- : undefined;
90
+ : checker.getTypeOfPropertyOfType(parent, prop.name);
95
91
  return [node, type];
96
92
  })();
97
93
  if ((node && pred(node) === false) || type === undefined) continue;
@@ -110,7 +106,21 @@ export const emplace_metadata_object =
110
106
  });
111
107
 
112
108
  // OPTIONAL, BUT CAN BE RQUIRED BY `Required<T>` TYPE
113
- if (node?.questionToken) Writable(value).optional = true;
109
+ if (node?.questionToken) {
110
+ const valueType = checker.getTypeOfPropertyOfType(
111
+ parent,
112
+ prop.name,
113
+ );
114
+ if (valueType === undefined || isOptional(valueType) === true)
115
+ Writable(value).optional = true;
116
+ } else if (!!node && value.isRequired() === true) {
117
+ const valueType = checker.getTypeOfPropertyOfType(
118
+ parent,
119
+ prop.name,
120
+ );
121
+ if (valueType && isOptional(valueType) === true)
122
+ Writable(value).optional = true;
123
+ }
114
124
  insert(key)(value)(prop);
115
125
  }
116
126
 
@@ -148,3 +158,15 @@ const isProperty = (node: ts.Declaration) =>
148
158
  ts.isPropertyAssignment(node) ||
149
159
  ts.isPropertySignature(node) ||
150
160
  ts.isTypeLiteralNode(node);
161
+
162
+ const isOptional = (type: ts.Type): boolean => {
163
+ const meta: Metadata = Metadata.initialize();
164
+ iterate_optional_coalesce(meta, type);
165
+ return !meta.isRequired();
166
+ };
167
+
168
+ const iterate_optional_coalesce = (meta: Metadata, type: ts.Type): void => {
169
+ if (type.isUnionOrIntersection())
170
+ type.types.forEach((child) => iterate_optional_coalesce(meta, child));
171
+ else iterate_metadata_coalesce(meta, type);
172
+ };
@@ -1,259 +1,259 @@
1
- import ts from "typescript";
2
-
3
- import { IMetadataConstant } from "../../../schemas/metadata/IMetadataConstant";
4
- import { IMetadataTypeTag } from "../../../schemas/metadata/IMetadataTypeTag";
5
- import { Metadata } from "../../../schemas/metadata/Metadata";
6
- import { MetadataAtomic } from "../../../schemas/metadata/MetadataAtomic";
7
-
8
- import { ArrayUtil } from "../../../utils/ArrayUtil";
9
-
10
- import { MetadataCollection } from "../../MetadataCollection";
11
- import { MetadataFactory } from "../../MetadataFactory";
12
- import { MetadataTypeTagFactory } from "../../MetadataTypeTagFactory";
13
- import { explore_metadata } from "./explore_metadata";
14
- import { iterate_metadata } from "./iterate_metadata";
15
- import { iterate_metadata_array } from "./iterate_metadata_array";
16
-
17
- export const iterate_metadata_intersection =
18
- (checker: ts.TypeChecker) =>
19
- (options: MetadataFactory.IOptions) =>
20
- (collection: MetadataCollection) =>
21
- (errors: MetadataFactory.IError[]) =>
22
- (
23
- meta: Metadata,
24
- type: ts.Type,
25
- explore: MetadataFactory.IExplore,
26
- ): boolean => {
27
- if (!type.isIntersection()) return false;
28
- else if (
29
- type.types.every(
30
- (child) =>
31
- (child.getFlags() & ts.TypeFlags.Object) !== 0 &&
32
- !checker.isArrayType(child) &&
33
- !checker.isTupleType(child),
34
- )
35
- )
36
- return false;
37
-
38
- // COSTRUCT FAKE METADATA LIST
39
- const fakeCollection: MetadataCollection = new MetadataCollection();
40
- const fakeErrors: MetadataFactory.IError[] = [];
41
- const children: Metadata[] = [
42
- ...new Map(
43
- type.types.map((t) => {
44
- const m: Metadata = explore_metadata(checker)({
45
- ...options,
46
- absorb: true,
47
- })(fakeCollection)(fakeErrors)(t, {
48
- ...explore,
49
- aliased: false,
50
- });
51
- return [m.getName(), m] as const;
52
- }),
53
- ).values(),
54
- ];
55
- if (fakeErrors.length) {
56
- errors.push(...fakeErrors);
57
- return true;
58
- }
59
-
60
- // ONLY ONE CHILD AFTER REMOVING DUPLICATES
61
- if (children.length === 1) {
62
- iterate_metadata(checker)(options)(collection)(errors)(
63
- meta,
64
- type.types[0]!,
65
- explore,
66
- );
67
- return true;
68
- } else if (
69
- // ONLY OBJECT TYPES -> SPECIAL LOGIC FOR TS V5.2
70
- children.every((c) => c.objects.length === 1 && c.size() === 1)
71
- )
72
- return false;
73
-
74
- // CONSIDER BOOLEAN TYPE CASE
75
- const booleanLiteral: boolean | null = (() => {
76
- const found = children.find(
77
- (c) =>
78
- c.size() === 1 &&
79
- c.constants.length === 1 &&
80
- c.constants[0]!.type === "boolean",
81
- )?.constants[0]?.values[0];
82
- if (found === undefined) return null;
83
- return children.every(
84
- (c) =>
85
- c.atomics.length === 0 ||
86
- c.atomics.every((a) => a.type !== "boolean"),
87
- )
88
- ? (found as boolean)
89
- : null;
90
- })();
91
- if (
92
- booleanLiteral !== null &&
93
- meta.boolean_literal_intersected_ === true
94
- ) {
95
- (
96
- meta.constants.find((c) => c.type === "boolean")!
97
- .values as boolean[]
98
- ).push(booleanLiteral);
99
- return true;
100
- }
101
-
102
- // VALIDATE EACH TYPES
103
- const individuals: (readonly [Metadata, number])[] = children
104
- .map((child, i) => [child, i] as const)
105
- .filter(
106
- ([c]) =>
107
- c.size() === 1 &&
108
- (c.atomics.length === 1 ||
109
- (c.constants.length === 1 &&
110
- c.constants[0]!.type === "boolean") ||
111
- c.arrays.length === 1),
112
- );
113
- const constants: Metadata[] = children.filter(
114
- (m) =>
115
- m.size() ===
116
- m.constants
117
- .map((c) => c.values.length)
118
- .reduce((a, b) => a + b, 0) +
119
- m.templates.length &&
120
- !(m.size() === 1 && m.constants[0]!.type === "boolean"),
121
- );
122
- const objects: Metadata[] = children.filter(
123
- (c) =>
124
- c.nullable === false &&
125
- c.isRequired() === true &&
126
- c.objects.length &&
127
- c.objects.length === c.size() &&
128
- c.objects.every((o) =>
129
- o.properties.every((p) => p.value.optional),
130
- ),
131
- );
132
- const atomics: Set<"boolean" | "bigint" | "number" | "string"> =
133
- new Set(
134
- individuals
135
- .map(([c]) => [
136
- ...c.atomics.map((a) => a.type),
137
- ...c.constants
138
- .filter((l) => l.type === "boolean")
139
- .map((l) => l.type),
140
- ])
141
- .flat(),
142
- );
143
- const arrays: Set<string> = new Set(
144
- individuals.map(([c]) => c.arrays.map((a) => a.type.name)).flat(),
145
- );
146
-
147
- // ESCAPE WHEN ONLY CONSTANT TYPES EXIST
148
- if (
149
- atomics.size + arrays.size > 1 ||
150
- individuals.length + objects.length + constants.length !==
151
- children.length
152
- ) {
153
- errors.push({
154
- name: children.map((c) => c.getName()).join(" & "),
155
- explore: { ...explore },
156
- messages: ["nonsensible intersection"],
157
- });
158
- return true;
159
- } else if (
160
- atomics.size === 0 &&
161
- arrays.size === 0 &&
162
- constants.length
163
- ) {
164
- for (const m of constants) {
165
- for (const tpl of m.templates)
166
- ArrayUtil.add(
167
- meta.templates,
168
- tpl,
169
- (a, b) =>
170
- a.map((ab) => ab.getName()).join(" | ") ===
171
- b.map((bb) => bb.getName()).join(" | "),
172
- );
173
- for (const c of m.constants) {
174
- const oldbie = meta.constants.find(
175
- (o) => o.type === c.type,
176
- );
177
- if (oldbie)
178
- for (const elem of c.values)
179
- ArrayUtil.add(
180
- oldbie.values,
181
- elem,
182
- (a, b) => a === b,
183
- );
184
- else meta.constants.push({ ...c });
185
- }
186
- }
187
- return true;
188
- }
189
-
190
- // RE-GENERATE TYPE
191
- const target: "boolean" | "bigint" | "number" | "string" | "array" =
192
- booleanLiteral
193
- ? "boolean"
194
- : atomics.size
195
- ? atomics.values().next().value
196
- : "array";
197
- if (
198
- target === "boolean" ||
199
- target === "bigint" ||
200
- target === "number" ||
201
- target === "string"
202
- )
203
- if (booleanLiteral === null)
204
- ArrayUtil.add(
205
- meta.atomics,
206
- MetadataAtomic.create({
207
- type: atomics.values().next().value as "string",
208
- tags: [],
209
- }),
210
- (a, b) => a.type === b.type,
211
- );
212
- else
213
- ArrayUtil.take<IMetadataConstant>(
214
- meta.constants,
215
- (x) => x.type === "boolean",
216
- () => ({
217
- type: "boolean",
218
- values: [booleanLiteral],
219
- }),
220
- );
221
- else if (target === "array") {
222
- const name: string = arrays.values().next().value;
223
- if (!meta.arrays.some((a) => a.type.name === name)) {
224
- iterate_metadata_array(checker)(options)(collection)(errors)(
225
- meta,
226
- type.types[
227
- individuals.find((i) => i[0].arrays.length === 1)![1]
228
- ]!,
229
- {
230
- ...explore,
231
- aliased: false,
232
- escaped: false,
233
- },
234
- );
235
- }
236
- }
237
-
238
- // ASSIGN TAGS
239
- if (objects.length) {
240
- const tags: IMetadataTypeTag[] = MetadataTypeTagFactory.analyze(
241
- errors,
242
- )(target)(objects.map((om) => om.objects).flat(), explore);
243
- if (tags.length)
244
- if (target === "array") meta.arrays.at(-1)!.tags.push(tags);
245
- else if (booleanLiteral === null)
246
- meta.atomics
247
- .find((a) => a.type === target)!
248
- .tags.push(tags);
249
- else {
250
- const constant: IMetadataConstant = meta.constants.find(
251
- (c) => c.type === "boolean",
252
- )!;
253
- constant.tags ??= [];
254
- constant.tags.push(tags);
255
- }
256
- }
257
- if (booleanLiteral !== null) meta.boolean_literal_intersected_ = true;
258
- return true;
259
- };
1
+ import ts from "typescript";
2
+
3
+ import { IMetadataConstant } from "../../../schemas/metadata/IMetadataConstant";
4
+ import { IMetadataTypeTag } from "../../../schemas/metadata/IMetadataTypeTag";
5
+ import { Metadata } from "../../../schemas/metadata/Metadata";
6
+ import { MetadataAtomic } from "../../../schemas/metadata/MetadataAtomic";
7
+
8
+ import { ArrayUtil } from "../../../utils/ArrayUtil";
9
+
10
+ import { MetadataCollection } from "../../MetadataCollection";
11
+ import { MetadataFactory } from "../../MetadataFactory";
12
+ import { MetadataTypeTagFactory } from "../../MetadataTypeTagFactory";
13
+ import { explore_metadata } from "./explore_metadata";
14
+ import { iterate_metadata } from "./iterate_metadata";
15
+ import { iterate_metadata_array } from "./iterate_metadata_array";
16
+
17
+ export const iterate_metadata_intersection =
18
+ (checker: ts.TypeChecker) =>
19
+ (options: MetadataFactory.IOptions) =>
20
+ (collection: MetadataCollection) =>
21
+ (errors: MetadataFactory.IError[]) =>
22
+ (
23
+ meta: Metadata,
24
+ type: ts.Type,
25
+ explore: MetadataFactory.IExplore,
26
+ ): boolean => {
27
+ if (!type.isIntersection()) return false;
28
+ else if (
29
+ type.types.every(
30
+ (child) =>
31
+ (child.getFlags() & ts.TypeFlags.Object) !== 0 &&
32
+ !checker.isArrayType(child) &&
33
+ !checker.isTupleType(child),
34
+ )
35
+ )
36
+ return false;
37
+
38
+ // COSTRUCT FAKE METADATA LIST
39
+ const fakeCollection: MetadataCollection = new MetadataCollection();
40
+ const fakeErrors: MetadataFactory.IError[] = [];
41
+ const children: Metadata[] = [
42
+ ...new Map(
43
+ type.types.map((t) => {
44
+ const m: Metadata = explore_metadata(checker)({
45
+ ...options,
46
+ absorb: true,
47
+ })(fakeCollection)(fakeErrors)(t, {
48
+ ...explore,
49
+ aliased: false,
50
+ });
51
+ return [m.getName(), m] as const;
52
+ }),
53
+ ).values(),
54
+ ];
55
+ if (fakeErrors.length) {
56
+ errors.push(...fakeErrors);
57
+ return true;
58
+ }
59
+
60
+ // ONLY ONE CHILD AFTER REMOVING DUPLICATES
61
+ if (children.length === 1) {
62
+ iterate_metadata(checker)(options)(collection)(errors)(
63
+ meta,
64
+ type.types[0]!,
65
+ explore,
66
+ );
67
+ return true;
68
+ } else if (
69
+ // ONLY OBJECT TYPES -> SPECIAL LOGIC FOR TS V5.2
70
+ children.every((c) => c.objects.length === 1 && c.size() === 1)
71
+ )
72
+ return false;
73
+
74
+ // CONSIDER BOOLEAN TYPE CASE
75
+ const booleanLiteral: boolean | null = (() => {
76
+ const found = children.find(
77
+ (c) =>
78
+ c.size() === 1 &&
79
+ c.constants.length === 1 &&
80
+ c.constants[0]!.type === "boolean",
81
+ )?.constants[0]?.values[0];
82
+ if (found === undefined) return null;
83
+ return children.every(
84
+ (c) =>
85
+ c.atomics.length === 0 ||
86
+ c.atomics.every((a) => a.type !== "boolean"),
87
+ )
88
+ ? (found as boolean)
89
+ : null;
90
+ })();
91
+ if (
92
+ booleanLiteral !== null &&
93
+ meta.boolean_literal_intersected_ === true
94
+ ) {
95
+ (
96
+ meta.constants.find((c) => c.type === "boolean")!
97
+ .values as boolean[]
98
+ ).push(booleanLiteral);
99
+ return true;
100
+ }
101
+
102
+ // VALIDATE EACH TYPES
103
+ const individuals: (readonly [Metadata, number])[] = children
104
+ .map((child, i) => [child, i] as const)
105
+ .filter(
106
+ ([c]) =>
107
+ c.size() === 1 &&
108
+ (c.atomics.length === 1 ||
109
+ (c.constants.length === 1 &&
110
+ c.constants[0]!.type === "boolean") ||
111
+ c.arrays.length === 1),
112
+ );
113
+ const constants: Metadata[] = children.filter(
114
+ (m) =>
115
+ m.size() ===
116
+ m.constants
117
+ .map((c) => c.values.length)
118
+ .reduce((a, b) => a + b, 0) +
119
+ m.templates.length &&
120
+ !(m.size() === 1 && m.constants[0]!.type === "boolean"),
121
+ );
122
+ const objects: Metadata[] = children.filter(
123
+ (c) =>
124
+ c.nullable === false &&
125
+ c.isRequired() === true &&
126
+ c.objects.length &&
127
+ c.objects.length === c.size() &&
128
+ c.objects.every((o) =>
129
+ o.properties.every((p) => p.value.optional),
130
+ ),
131
+ );
132
+ const atomics: Set<"boolean" | "bigint" | "number" | "string"> =
133
+ new Set(
134
+ individuals
135
+ .map(([c]) => [
136
+ ...c.atomics.map((a) => a.type),
137
+ ...c.constants
138
+ .filter((l) => l.type === "boolean")
139
+ .map((l) => l.type),
140
+ ])
141
+ .flat(),
142
+ );
143
+ const arrays: Set<string> = new Set(
144
+ individuals.map(([c]) => c.arrays.map((a) => a.type.name)).flat(),
145
+ );
146
+
147
+ // ESCAPE WHEN ONLY CONSTANT TYPES EXIST
148
+ if (
149
+ atomics.size + arrays.size > 1 ||
150
+ individuals.length + objects.length + constants.length !==
151
+ children.length
152
+ ) {
153
+ errors.push({
154
+ name: children.map((c) => c.getName()).join(" & "),
155
+ explore: { ...explore },
156
+ messages: ["nonsensible intersection"],
157
+ });
158
+ return true;
159
+ } else if (
160
+ atomics.size === 0 &&
161
+ arrays.size === 0 &&
162
+ constants.length
163
+ ) {
164
+ for (const m of constants) {
165
+ for (const tpl of m.templates)
166
+ ArrayUtil.add(
167
+ meta.templates,
168
+ tpl,
169
+ (a, b) =>
170
+ a.map((ab) => ab.getName()).join(" | ") ===
171
+ b.map((bb) => bb.getName()).join(" | "),
172
+ );
173
+ for (const c of m.constants) {
174
+ const oldbie = meta.constants.find(
175
+ (o) => o.type === c.type,
176
+ );
177
+ if (oldbie)
178
+ for (const elem of c.values)
179
+ ArrayUtil.add(
180
+ oldbie.values,
181
+ elem,
182
+ (a, b) => a === b,
183
+ );
184
+ else meta.constants.push({ ...c });
185
+ }
186
+ }
187
+ return true;
188
+ }
189
+
190
+ // RE-GENERATE TYPE
191
+ const target: "boolean" | "bigint" | "number" | "string" | "array" =
192
+ booleanLiteral
193
+ ? "boolean"
194
+ : atomics.size
195
+ ? atomics.values().next().value
196
+ : "array";
197
+ if (
198
+ target === "boolean" ||
199
+ target === "bigint" ||
200
+ target === "number" ||
201
+ target === "string"
202
+ )
203
+ if (booleanLiteral === null)
204
+ ArrayUtil.add(
205
+ meta.atomics,
206
+ MetadataAtomic.create({
207
+ type: atomics.values().next().value as "string",
208
+ tags: [],
209
+ }),
210
+ (a, b) => a.type === b.type,
211
+ );
212
+ else
213
+ ArrayUtil.take<IMetadataConstant>(
214
+ meta.constants,
215
+ (x) => x.type === "boolean",
216
+ () => ({
217
+ type: "boolean",
218
+ values: [booleanLiteral],
219
+ }),
220
+ );
221
+ else if (target === "array") {
222
+ const name: string = arrays.values().next().value;
223
+ if (!meta.arrays.some((a) => a.type.name === name)) {
224
+ iterate_metadata_array(checker)(options)(collection)(errors)(
225
+ meta,
226
+ type.types[
227
+ individuals.find((i) => i[0].arrays.length === 1)![1]
228
+ ]!,
229
+ {
230
+ ...explore,
231
+ aliased: false,
232
+ escaped: false,
233
+ },
234
+ );
235
+ }
236
+ }
237
+
238
+ // ASSIGN TAGS
239
+ if (objects.length) {
240
+ const tags: IMetadataTypeTag[] = MetadataTypeTagFactory.analyze(
241
+ errors,
242
+ )(target)(objects.map((om) => om.objects).flat(), explore);
243
+ if (tags.length)
244
+ if (target === "array") meta.arrays.at(-1)!.tags.push(tags);
245
+ else if (booleanLiteral === null)
246
+ meta.atomics
247
+ .find((a) => a.type === target)!
248
+ .tags.push(tags);
249
+ else {
250
+ const constant: IMetadataConstant = meta.constants.find(
251
+ (c) => c.type === "boolean",
252
+ )!;
253
+ constant.tags ??= [];
254
+ constant.tags.push(tags);
255
+ }
256
+ }
257
+ if (booleanLiteral !== null) meta.boolean_literal_intersected_ = true;
258
+ return true;
259
+ };