typia 5.2.6 → 5.2.7-dev.20231109

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 (125) hide show
  1. package/lib/factories/ExpressionFactory.js +14 -16
  2. package/lib/factories/ExpressionFactory.js.map +1 -1
  3. package/lib/factories/JsonMetadataFactory.d.ts +1 -1
  4. package/lib/factories/JsonMetadataFactory.js +2 -2
  5. package/lib/factories/JsonMetadataFactory.js.map +1 -1
  6. package/lib/factories/LiteralFactory.js +2 -0
  7. package/lib/factories/LiteralFactory.js.map +1 -1
  8. package/lib/factories/MetadataFactory.d.ts +1 -1
  9. package/lib/factories/MetadataFactory.js +233 -168
  10. package/lib/factories/MetadataFactory.js.map +1 -1
  11. package/lib/factories/NumericRangeFactory.d.ts +2 -2
  12. package/lib/factories/NumericRangeFactory.js +41 -21
  13. package/lib/factories/NumericRangeFactory.js.map +1 -1
  14. package/lib/factories/ProtobufFactory.d.ts +1 -1
  15. package/lib/factories/ProtobufFactory.js +2 -2
  16. package/lib/factories/ProtobufFactory.js.map +1 -1
  17. package/lib/programmers/CheckerProgrammer.js +11 -16
  18. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  19. package/lib/programmers/RandomProgrammer.js +1 -1
  20. package/lib/programmers/RandomProgrammer.js.map +1 -1
  21. package/lib/programmers/http/HttpHeadersProgrammer.js +1 -1
  22. package/lib/programmers/http/HttpHeadersProgrammer.js.map +1 -1
  23. package/lib/programmers/http/HttpParameterProgrammer.js +1 -1
  24. package/lib/programmers/http/HttpParameterProgrammer.js.map +1 -1
  25. package/lib/programmers/http/HttpQueryProgrammer.js +1 -1
  26. package/lib/programmers/http/HttpQueryProgrammer.js.map +1 -1
  27. package/lib/programmers/internal/application_array.js +8 -0
  28. package/lib/programmers/internal/application_array.js.map +1 -1
  29. package/lib/programmers/internal/application_number.js +8 -1
  30. package/lib/programmers/internal/application_number.js.map +1 -1
  31. package/lib/programmers/internal/application_string.js +8 -1
  32. package/lib/programmers/internal/application_string.js.map +1 -1
  33. package/lib/programmers/internal/check_array_length.js +7 -4
  34. package/lib/programmers/internal/check_array_length.js.map +1 -1
  35. package/lib/programmers/internal/check_bigint.js +7 -4
  36. package/lib/programmers/internal/check_bigint.js.map +1 -1
  37. package/lib/programmers/internal/check_number.js +7 -4
  38. package/lib/programmers/internal/check_number.js.map +1 -1
  39. package/lib/programmers/internal/check_string.js.map +1 -1
  40. package/lib/programmers/json/JsonAssertParseProgrammer.js +1 -1
  41. package/lib/programmers/json/JsonAssertParseProgrammer.js.map +1 -1
  42. package/lib/programmers/json/JsonIsParseProgrammer.js +1 -1
  43. package/lib/programmers/json/JsonIsParseProgrammer.js.map +1 -1
  44. package/lib/programmers/json/JsonStringifyProgrammer.js +3 -8
  45. package/lib/programmers/json/JsonStringifyProgrammer.js.map +1 -1
  46. package/lib/programmers/json/JsonValidateParseProgrammer.js +1 -1
  47. package/lib/programmers/json/JsonValidateParseProgrammer.js.map +1 -1
  48. package/lib/programmers/misc/MiscCloneProgrammer.js +19 -24
  49. package/lib/programmers/misc/MiscCloneProgrammer.js.map +1 -1
  50. package/lib/programmers/misc/MiscLiteralsProgrammer.js +1 -1
  51. package/lib/programmers/misc/MiscLiteralsProgrammer.js.map +1 -1
  52. package/lib/programmers/misc/MiscPruneProgrammer.js +11 -16
  53. package/lib/programmers/misc/MiscPruneProgrammer.js.map +1 -1
  54. package/lib/programmers/notations/NotationGeneralProgrammer.js +11 -16
  55. package/lib/programmers/notations/NotationGeneralProgrammer.js.map +1 -1
  56. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js +1 -1
  57. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js.map +1 -1
  58. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js +38 -42
  59. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js.map +1 -1
  60. package/lib/programmers/protobuf/ProtobufMessageProgrammer.d.ts +1 -1
  61. package/lib/programmers/protobuf/ProtobufMessageProgrammer.js +22 -25
  62. package/lib/programmers/protobuf/ProtobufMessageProgrammer.js.map +1 -1
  63. package/lib/schemas/json/IJsonSchema.d.ts +1 -0
  64. package/lib/schemas/metadata/Metadata.js +1 -6
  65. package/lib/schemas/metadata/Metadata.js.map +1 -1
  66. package/lib/schemas/metadata/MetadataAtomic.d.ts +2 -0
  67. package/lib/schemas/metadata/MetadataAtomic.js +15 -0
  68. package/lib/schemas/metadata/MetadataAtomic.js.map +1 -1
  69. package/lib/transformers/features/json/JsonApplicationTransformer.d.ts +1 -1
  70. package/lib/transformers/features/json/JsonApplicationTransformer.js +4 -5
  71. package/lib/transformers/features/json/JsonApplicationTransformer.js.map +1 -1
  72. package/lib/transformers/features/misc/MetadataTransformer.d.ts +1 -1
  73. package/lib/transformers/features/misc/MetadataTransformer.js +3 -4
  74. package/lib/transformers/features/misc/MetadataTransformer.js.map +1 -1
  75. package/package.json +2 -2
  76. package/src/Primitive.ts +135 -135
  77. package/src/executable/TypiaSetupWizard.ts +142 -142
  78. package/src/executable/setup/CommandExecutor.ts +8 -8
  79. package/src/factories/ExpressionFactory.ts +12 -13
  80. package/src/factories/JsonMetadataFactory.ts +53 -50
  81. package/src/factories/LiteralFactory.ts +2 -0
  82. package/src/factories/MetadataCollection.ts +282 -282
  83. package/src/factories/MetadataFactory.ts +48 -18
  84. package/src/factories/NumericRangeFactory.ts +56 -17
  85. package/src/factories/ProtobufFactory.ts +5 -2
  86. package/src/factories/internal/metadata/emplace_metadata_object.ts +178 -178
  87. package/src/functional/$stoll.ts +8 -8
  88. package/src/functional/Namespace.ts +168 -168
  89. package/src/programmers/AssertProgrammer.ts +322 -322
  90. package/src/programmers/CheckerProgrammer.ts +16 -17
  91. package/src/programmers/IsProgrammer.ts +258 -258
  92. package/src/programmers/RandomProgrammer.ts +4 -1
  93. package/src/programmers/ValidateProgrammer.ts +350 -350
  94. package/src/programmers/helpers/AtomicPredicator.ts +31 -31
  95. package/src/programmers/http/HttpHeadersProgrammer.ts +4 -1
  96. package/src/programmers/http/HttpParameterProgrammer.ts +4 -1
  97. package/src/programmers/http/HttpQueryProgrammer.ts +4 -1
  98. package/src/programmers/internal/application_array.ts +8 -0
  99. package/src/programmers/internal/application_number.ts +8 -1
  100. package/src/programmers/internal/application_string.ts +8 -1
  101. package/src/programmers/internal/check_array_length.ts +5 -2
  102. package/src/programmers/internal/check_bigint.ts +5 -2
  103. package/src/programmers/internal/check_dynamic_key.ts +178 -178
  104. package/src/programmers/internal/check_dynamic_properties.ts +202 -202
  105. package/src/programmers/internal/check_number.ts +5 -2
  106. package/src/programmers/internal/check_object.ts +62 -62
  107. package/src/programmers/internal/check_string.ts +0 -1
  108. package/src/programmers/json/JsonAssertParseProgrammer.ts +1 -0
  109. package/src/programmers/json/JsonIsParseProgrammer.ts +1 -0
  110. package/src/programmers/json/JsonStringifyProgrammer.ts +959 -960
  111. package/src/programmers/json/JsonValidateParseProgrammer.ts +1 -0
  112. package/src/programmers/misc/MiscCloneProgrammer.ts +787 -786
  113. package/src/programmers/misc/MiscLiteralsProgrammer.ts +4 -1
  114. package/src/programmers/misc/MiscPruneProgrammer.ts +549 -548
  115. package/src/programmers/notations/NotationGeneralProgrammer.ts +717 -716
  116. package/src/programmers/protobuf/ProtobufDecodeProgrammer.ts +1 -0
  117. package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +872 -882
  118. package/src/programmers/protobuf/ProtobufMessageProgrammer.ts +21 -21
  119. package/src/schemas/json/IJsonSchema.ts +1 -0
  120. package/src/schemas/metadata/IMetadataTypeTag.ts +7 -0
  121. package/src/schemas/metadata/Metadata.ts +1 -6
  122. package/src/schemas/metadata/MetadataAtomic.ts +17 -0
  123. package/src/transform.ts +35 -35
  124. package/src/transformers/features/json/JsonApplicationTransformer.ts +7 -4
  125. package/src/transformers/features/misc/MetadataTransformer.ts +6 -3
@@ -11,6 +11,7 @@ import { iterate_metadata_sort } from "./internal/metadata/iterate_metadata_sort
11
11
 
12
12
  import { ValidationPipe } from "../typings/ValidationPipe";
13
13
 
14
+ import { ExpressionFactory } from "./ExpressionFactory";
14
15
  import { MetadataCollection } from "./MetadataCollection";
15
16
 
16
17
  export namespace MetadataFactory {
@@ -40,7 +41,7 @@ export namespace MetadataFactory {
40
41
  }
41
42
 
42
43
  export const analyze =
43
- (checker: ts.TypeChecker) =>
44
+ (checker: ts.TypeChecker, context?: ts.TransformationContext) =>
44
45
  (options: IOptions) =>
45
46
  (collection: MetadataCollection) =>
46
47
  (type: ts.Type | null): ValidationPipe<Metadata, IError> => {
@@ -59,7 +60,9 @@ export namespace MetadataFactory {
59
60
  iterate_metadata_sort(collection)(meta);
60
61
 
61
62
  if (options.validate)
62
- errors.push(...validate(options)(options.validate)(meta));
63
+ errors.push(
64
+ ...validate(context)(options)(options.validate)(meta),
65
+ );
63
66
  return errors.length
64
67
  ? {
65
68
  success: false,
@@ -84,6 +87,7 @@ export namespace MetadataFactory {
84
87
  };
85
88
 
86
89
  const validate =
90
+ (context?: ts.TransformationContext) =>
87
91
  (options: IOptions) =>
88
92
  (functor: Validator) =>
89
93
  (meta: Metadata): IError[] => {
@@ -95,7 +99,7 @@ export namespace MetadataFactory {
95
99
  tuples: new Set(),
96
100
  aliases: new Set(),
97
101
  };
98
- validateMeta(options)(visitor)(meta, {
102
+ validateMeta(context)(options)(visitor)(meta, {
99
103
  object: null,
100
104
  property: null,
101
105
  nested: null,
@@ -107,47 +111,70 @@ export namespace MetadataFactory {
107
111
  };
108
112
 
109
113
  const validateMeta =
114
+ (context?: ts.TransformationContext) =>
110
115
  (options: IOptions) =>
111
116
  (visitor: IValidationVisitor) =>
112
117
  (meta: Metadata, explore: IExplore) => {
113
- const result: Set<string> = new Set(visitor.functor(meta, explore));
114
- if (result.size)
118
+ const result: string[] = [];
119
+ if (context !== undefined)
120
+ for (const atomic of meta.atomics)
121
+ for (const row of atomic.tags)
122
+ for (const tag of row.filter(
123
+ (t) =>
124
+ t.validate !== undefined &&
125
+ t.predicate === undefined,
126
+ ))
127
+ try {
128
+ tag.predicate = ExpressionFactory.transpile(
129
+ context,
130
+ )(tag.validate!);
131
+ } catch {
132
+ result.push(
133
+ `Unable to transpile type tag script: ${JSON.stringify(
134
+ tag.validate,
135
+ )}`,
136
+ );
137
+ tag.predicate = () => ts.factory.createTrue();
138
+ }
139
+ result.push(...visitor.functor(meta, explore));
140
+ if (result.length)
115
141
  visitor.errors.push({
116
142
  name: meta.getName(),
117
143
  explore: { ...explore },
118
- messages: [...result],
144
+ messages: [...new Set(result)],
119
145
  });
120
146
 
121
147
  for (const alias of meta.aliases)
122
- validateAlias(options)(visitor)(alias, explore);
148
+ validateAlias(context)(options)(visitor)(alias, explore);
123
149
  for (const array of meta.arrays)
124
- validateArray(options)(visitor)(array.type, explore);
150
+ validateArray(context)(options)(visitor)(array.type, explore);
125
151
  for (const tuple of meta.tuples)
126
- validateTuple(options)(visitor)(tuple.type, explore);
152
+ validateTuple(context)(options)(visitor)(tuple.type, explore);
127
153
  for (const obj of meta.objects)
128
- validateObject(options)(visitor)(obj);
154
+ validateObject(context)(options)(visitor)(obj);
129
155
  for (const set of meta.sets)
130
- validateMeta(options)(visitor)(set, explore);
156
+ validateMeta(context)(options)(visitor)(set, explore);
131
157
  for (const map of meta.maps) {
132
- validateMeta(options)(visitor)(map.key, explore);
133
- validateMeta(options)(visitor)(map.value, explore);
158
+ validateMeta(context)(options)(visitor)(map.key, explore);
159
+ validateMeta(context)(options)(visitor)(map.value, explore);
134
160
  }
135
161
 
136
162
  if (options.escape === true && meta.escaped !== null)
137
- validateMeta(options)(visitor)(meta.escaped.returns, {
163
+ validateMeta(context)(options)(visitor)(meta.escaped.returns, {
138
164
  ...explore,
139
165
  escaped: true,
140
166
  });
141
167
  };
142
168
 
143
169
  const validateAlias =
170
+ (context?: ts.TransformationContext) =>
144
171
  (options: IOptions) =>
145
172
  (visitor: IValidationVisitor) =>
146
173
  (alias: MetadataAlias, explore: IExplore) => {
147
174
  if (visitor.aliases.has(alias)) return;
148
175
  visitor.aliases.add(alias);
149
176
 
150
- validateMeta(options)(visitor)(alias.value, {
177
+ validateMeta(context)(options)(visitor)(alias.value, {
151
178
  ...explore,
152
179
  nested: alias,
153
180
  aliased: true,
@@ -155,13 +182,14 @@ export namespace MetadataFactory {
155
182
  };
156
183
 
157
184
  const validateArray =
185
+ (context?: ts.TransformationContext) =>
158
186
  (options: IOptions) =>
159
187
  (visitor: IValidationVisitor) =>
160
188
  (array: MetadataArrayType, explore: IExplore) => {
161
189
  if (visitor.arrays.has(array)) return;
162
190
  visitor.arrays.add(array);
163
191
 
164
- validateMeta(options)(visitor)(array.value, {
192
+ validateMeta(context)(options)(visitor)(array.value, {
165
193
  ...explore,
166
194
  nested: array,
167
195
  top: false,
@@ -169,6 +197,7 @@ export namespace MetadataFactory {
169
197
  };
170
198
 
171
199
  const validateTuple =
200
+ (context?: ts.TransformationContext) =>
172
201
  (options: IOptions) =>
173
202
  (visitor: IValidationVisitor) =>
174
203
  (tuple: MetadataTupleType, explore: IExplore) => {
@@ -176,7 +205,7 @@ export namespace MetadataFactory {
176
205
  visitor.tuples.add(tuple);
177
206
 
178
207
  for (const elem of tuple.elements)
179
- validateMeta(options)(visitor)(elem, {
208
+ validateMeta(context)(options)(visitor)(elem, {
180
209
  ...explore,
181
210
  nested: tuple,
182
211
  top: false,
@@ -184,6 +213,7 @@ export namespace MetadataFactory {
184
213
  };
185
214
 
186
215
  const validateObject =
216
+ (context?: ts.TransformationContext) =>
187
217
  (options: IOptions) =>
188
218
  (visitor: IValidationVisitor) =>
189
219
  (object: MetadataObject) => {
@@ -215,7 +245,7 @@ export namespace MetadataFactory {
215
245
  }
216
246
 
217
247
  for (const property of object.properties)
218
- validateMeta(options)(visitor)(property.value, {
248
+ validateMeta(context)(options)(visitor)(property.value, {
219
249
  object,
220
250
  property: property.key.isSoleLiteral()
221
251
  ? property.key.getSoleLiteral()!
@@ -6,28 +6,67 @@ import { ExpressionFactory } from "./ExpressionFactory";
6
6
 
7
7
  export namespace NumericRangeFactory {
8
8
  export const number =
9
- (context: ts.TransformationContext) =>
10
9
  (type: ProtobufAtomic.Numeric) =>
11
10
  (input: ts.Expression): ts.Expression =>
12
- ExpressionFactory.transpile(context)(NUMBER_TEXT[type])(input);
11
+ NumberPredicator[type](input);
13
12
 
14
13
  export const bigint =
15
- (context: ts.TransformationContext) =>
16
14
  (type: ProtobufAtomic.BigNumeric) =>
17
15
  (input: ts.Expression): ts.Expression =>
18
- ExpressionFactory.transpile(context)(BIGINT_TEXT[type])(input);
16
+ BigIntPredicator[type](input);
19
17
  }
20
18
 
21
- const NUMBER_TEXT = {
22
- int32: `Math.floor($input) === $input && -2147483648 <= $input && $input <= 2147483647`,
23
- uint32: `Math.floor($input) === $input && 0 <= $input && $input <= 4294967295`,
24
- int64: `Math.floor($input) === $input && -9223372036854775808 <= $input && $input <= 9223372036854775807`,
25
- uint64: `Math.floor($input) === $input && 0 <= $input && $input <= 18446744073709551615`,
26
- float: `-1.175494351e38 <= $input && $input <= 3.4028235e38`,
27
- double: `true`,
28
- };
29
-
30
- const BIGINT_TEXT = {
31
- int64: `true`,
32
- uint64: `BigInt(0) <= $input`,
33
- };
19
+ namespace NumberPredicator {
20
+ export const int32 = (input: ts.Expression) =>
21
+ ts.factory.createLogicalAnd(
22
+ integer(input),
23
+ between("-2147483648", "2147483647")(input),
24
+ );
25
+ export const uint32 = (input: ts.Expression) =>
26
+ ts.factory.createLogicalAnd(
27
+ integer(input),
28
+ between("0", "4294967295")(input),
29
+ );
30
+ export const int64 = (input: ts.Expression) =>
31
+ ts.factory.createLogicalAnd(
32
+ integer(input),
33
+ between("-9223372036854775808", "9223372036854775807")(input),
34
+ );
35
+ export const uint64 = (input: ts.Expression) =>
36
+ ts.factory.createLogicalAnd(
37
+ integer(input),
38
+ between("0", "18446744073709551615")(input),
39
+ );
40
+ export const float = (input: ts.Expression) =>
41
+ between("-1.175494351e38", "3.4028235e38")(input);
42
+ export const double = () => ts.factory.createTrue();
43
+ }
44
+
45
+ namespace BigIntPredicator {
46
+ export const int64 = () => ts.factory.createTrue();
47
+ export const uint64 = (input: ts.Expression) =>
48
+ ts.factory.createLessThanEquals(
49
+ ts.factory.createCallExpression(
50
+ ts.factory.createIdentifier("BigInt"),
51
+ undefined,
52
+ [ExpressionFactory.number(0)],
53
+ ),
54
+ input,
55
+ );
56
+ }
57
+
58
+ const integer = (input: ts.Expression) =>
59
+ ts.factory.createStrictEquality(
60
+ ts.factory.createCallExpression(
61
+ ts.factory.createIdentifier("Math.floor"),
62
+ undefined,
63
+ [input],
64
+ ),
65
+ input,
66
+ );
67
+
68
+ const between = (x: string, y: string) => (input: ts.Expression) =>
69
+ ts.factory.createLogicalAnd(
70
+ ts.factory.createLessThanEquals(ts.factory.createIdentifier(x), input),
71
+ ts.factory.createLessThanEquals(input, ts.factory.createIdentifier(y)),
72
+ );
@@ -17,12 +17,15 @@ import { MetadataFactory } from "./MetadataFactory";
17
17
  export namespace ProtobufFactory {
18
18
  export const metadata =
19
19
  (method: string) =>
20
- (checker: ts.TypeChecker) =>
20
+ (checker: ts.TypeChecker, context?: ts.TransformationContext) =>
21
21
  (collection: MetadataCollection) =>
22
22
  (type: ts.Type): Metadata => {
23
23
  // COMPOSE METADATA WITH INDIVIDUAL VALIDATIONS
24
24
  const result: ValidationPipe<Metadata, MetadataFactory.IError> =
25
- MetadataFactory.analyze(checker)({
25
+ MetadataFactory.analyze(
26
+ checker,
27
+ context,
28
+ )({
26
29
  escape: false,
27
30
  constant: true,
28
31
  absorb: true,
@@ -1,178 +1,178 @@
1
- import ts from "typescript";
2
-
3
- import { Metadata } from "../../../schemas/metadata/Metadata";
4
- import { MetadataObject } from "../../../schemas/metadata/MetadataObject";
5
- import { MetadataProperty } from "../../../schemas/metadata/MetadataProperty";
6
-
7
- import { Writable } from "../../../typings/Writable";
8
-
9
- import { ArrayUtil } from "../../../utils/ArrayUtil";
10
-
11
- import { CommentFactory } from "../../CommentFactory";
12
- import { MetadataCollection } from "../../MetadataCollection";
13
- import { MetadataFactory } from "../../MetadataFactory";
14
- import { MetadataHelper } from "./MetadataHelper";
15
- import { explore_metadata } from "./explore_metadata";
16
- import { iterate_metadata_coalesce } from "./iterate_metadata_coalesce";
17
-
18
- export const emplace_metadata_object =
19
- (checker: ts.TypeChecker) =>
20
- (options: MetadataFactory.IOptions) =>
21
- (collection: MetadataCollection) =>
22
- (errors: MetadataFactory.IError[]) =>
23
- (parent: ts.Type, nullable: boolean): MetadataObject => {
24
- // EMPLACE OBJECT
25
- const [obj, newbie] = collection.emplace(checker, parent);
26
- ArrayUtil.add(obj.nullables, nullable, (elem) => elem === nullable);
27
-
28
- if (newbie === false) return obj;
29
-
30
- // PREPARE ASSETS
31
- const isClass: boolean = parent.isClass();
32
- const pred: (node: ts.Declaration) => boolean = isClass
33
- ? (node) => {
34
- const kind: ts.SyntaxKind | undefined = node
35
- .getChildren()[0]
36
- ?.getChildren()[0]?.kind;
37
- return (
38
- kind !== ts.SyntaxKind.PrivateKeyword &&
39
- kind !== ts.SyntaxKind.ProtectedKeyword &&
40
- (ts.isParameter(node) || isProperty(node))
41
- );
42
- }
43
- : (node) => isProperty(node);
44
-
45
- const insert =
46
- (key: Metadata) =>
47
- (value: Metadata) =>
48
- (
49
- symbol: ts.Symbol | undefined,
50
- filter?: (doc: ts.JSDocTagInfo) => boolean,
51
- ): MetadataProperty => {
52
- // COMMENTS AND TAGS
53
- const description: string | null = symbol
54
- ? CommentFactory.description(symbol) ?? null
55
- : null;
56
- const jsDocTags: ts.JSDocTagInfo[] = (
57
- symbol?.getJsDocTags() ?? []
58
- ).filter(filter ?? (() => true));
59
-
60
- // THE PROPERTY
61
- const property = MetadataProperty.create({
62
- key,
63
- value,
64
- description,
65
- jsDocTags,
66
- });
67
- obj.properties.push(property);
68
- return property;
69
- };
70
-
71
- //----
72
- // REGULAR PROPERTIES
73
- //----
74
- for (const prop of parent.getApparentProperties()) {
75
- // CHECK INTERNAL TAG
76
- if (
77
- (prop.getJsDocTags(checker) ?? []).find(
78
- (tag) => tag.name === "internal",
79
- ) !== undefined
80
- )
81
- continue;
82
-
83
- // CHECK NODE IS A FORMAL PROPERTY
84
- const [node, type] = (() => {
85
- const node = prop.getDeclarations()?.[0] as
86
- | ts.PropertyDeclaration
87
- | undefined;
88
- const type: ts.Type | undefined = node
89
- ? checker.getTypeOfSymbolAtLocation(prop, node)
90
- : checker.getTypeOfPropertyOfType(parent, prop.name);
91
- return [node, type];
92
- })();
93
- if ((node && pred(node) === false) || type === undefined) continue;
94
-
95
- // GET EXACT TYPE
96
- const key: Metadata = MetadataHelper.literal_to_metadata(prop.name);
97
- const value: Metadata = explore_metadata(checker)(options)(
98
- collection,
99
- )(errors)(type, {
100
- top: false,
101
- object: obj,
102
- property: prop.name,
103
- nested: null,
104
- escaped: false,
105
- aliased: false,
106
- });
107
- Writable(value).optional =
108
- (prop.flags & ts.SymbolFlags.Optional) !== 0;
109
- insert(key)(value)(prop);
110
- }
111
-
112
- //----
113
- // DYNAMIC PROPERTIES
114
- //----
115
- for (const index of checker.getIndexInfosOfType(parent)) {
116
- // GET EXACT TYPE
117
- const analyzer = (type: ts.Type) => (property: {} | null) =>
118
- explore_metadata(checker)(options)(collection)(errors)(type, {
119
- top: false,
120
- object: obj,
121
- property,
122
- nested: null,
123
- escaped: false,
124
- aliased: false,
125
- });
126
- const key: Metadata = analyzer(index.keyType)(null);
127
- const value: Metadata = analyzer(index.type)({});
128
-
129
- if (
130
- key.atomics.length +
131
- key.constants
132
- .map((c) => c.values.length)
133
- .reduce((a, b) => a + b, 0) +
134
- key.templates.length +
135
- key.natives.filter(
136
- (type) =>
137
- type === "Boolean" ||
138
- type === "BigInt" ||
139
- type === "Number" ||
140
- type === "String",
141
- ).length !==
142
- key.size()
143
- )
144
- errors.push({
145
- name: key.getName(),
146
- explore: {
147
- top: false,
148
- object: obj,
149
- property: "[key]",
150
- nested: null,
151
- escaped: false,
152
- aliased: false,
153
- },
154
- messages: [],
155
- });
156
-
157
- // INSERT WITH REQUIRED CONFIGURATION
158
- insert(key)(value)(
159
- index.declaration?.parent
160
- ? checker.getSymbolAtLocation(index.declaration.parent)
161
- : undefined,
162
- (doc) => doc.name !== "default",
163
- );
164
- }
165
- return obj;
166
- };
167
-
168
- const isProperty = (node: ts.Declaration) =>
169
- ts.isPropertyDeclaration(node) ||
170
- ts.isPropertyAssignment(node) ||
171
- ts.isPropertySignature(node) ||
172
- ts.isTypeLiteralNode(node);
173
-
174
- const iterate_optional_coalesce = (meta: Metadata, type: ts.Type): void => {
175
- if (type.isUnionOrIntersection())
176
- type.types.forEach((child) => iterate_optional_coalesce(meta, child));
177
- else iterate_metadata_coalesce(meta, type);
178
- };
1
+ import ts from "typescript";
2
+
3
+ import { Metadata } from "../../../schemas/metadata/Metadata";
4
+ import { MetadataObject } from "../../../schemas/metadata/MetadataObject";
5
+ import { MetadataProperty } from "../../../schemas/metadata/MetadataProperty";
6
+
7
+ import { Writable } from "../../../typings/Writable";
8
+
9
+ import { ArrayUtil } from "../../../utils/ArrayUtil";
10
+
11
+ import { CommentFactory } from "../../CommentFactory";
12
+ import { MetadataCollection } from "../../MetadataCollection";
13
+ import { MetadataFactory } from "../../MetadataFactory";
14
+ import { MetadataHelper } from "./MetadataHelper";
15
+ import { explore_metadata } from "./explore_metadata";
16
+ import { iterate_metadata_coalesce } from "./iterate_metadata_coalesce";
17
+
18
+ export const emplace_metadata_object =
19
+ (checker: ts.TypeChecker) =>
20
+ (options: MetadataFactory.IOptions) =>
21
+ (collection: MetadataCollection) =>
22
+ (errors: MetadataFactory.IError[]) =>
23
+ (parent: ts.Type, nullable: boolean): MetadataObject => {
24
+ // EMPLACE OBJECT
25
+ const [obj, newbie] = collection.emplace(checker, parent);
26
+ ArrayUtil.add(obj.nullables, nullable, (elem) => elem === nullable);
27
+
28
+ if (newbie === false) return obj;
29
+
30
+ // PREPARE ASSETS
31
+ const isClass: boolean = parent.isClass();
32
+ const pred: (node: ts.Declaration) => boolean = isClass
33
+ ? (node) => {
34
+ const kind: ts.SyntaxKind | undefined = node
35
+ .getChildren()[0]
36
+ ?.getChildren()[0]?.kind;
37
+ return (
38
+ kind !== ts.SyntaxKind.PrivateKeyword &&
39
+ kind !== ts.SyntaxKind.ProtectedKeyword &&
40
+ (ts.isParameter(node) || isProperty(node))
41
+ );
42
+ }
43
+ : (node) => isProperty(node);
44
+
45
+ const insert =
46
+ (key: Metadata) =>
47
+ (value: Metadata) =>
48
+ (
49
+ symbol: ts.Symbol | undefined,
50
+ filter?: (doc: ts.JSDocTagInfo) => boolean,
51
+ ): MetadataProperty => {
52
+ // COMMENTS AND TAGS
53
+ const description: string | null = symbol
54
+ ? CommentFactory.description(symbol) ?? null
55
+ : null;
56
+ const jsDocTags: ts.JSDocTagInfo[] = (
57
+ symbol?.getJsDocTags() ?? []
58
+ ).filter(filter ?? (() => true));
59
+
60
+ // THE PROPERTY
61
+ const property = MetadataProperty.create({
62
+ key,
63
+ value,
64
+ description,
65
+ jsDocTags,
66
+ });
67
+ obj.properties.push(property);
68
+ return property;
69
+ };
70
+
71
+ //----
72
+ // REGULAR PROPERTIES
73
+ //----
74
+ for (const prop of parent.getApparentProperties()) {
75
+ // CHECK INTERNAL TAG
76
+ if (
77
+ (prop.getJsDocTags(checker) ?? []).find(
78
+ (tag) => tag.name === "internal",
79
+ ) !== undefined
80
+ )
81
+ continue;
82
+
83
+ // CHECK NODE IS A FORMAL PROPERTY
84
+ const [node, type] = (() => {
85
+ const node = prop.getDeclarations()?.[0] as
86
+ | ts.PropertyDeclaration
87
+ | undefined;
88
+ const type: ts.Type | undefined = node
89
+ ? checker.getTypeOfSymbolAtLocation(prop, node)
90
+ : checker.getTypeOfPropertyOfType(parent, prop.name);
91
+ return [node, type];
92
+ })();
93
+ if ((node && pred(node) === false) || type === undefined) continue;
94
+
95
+ // GET EXACT TYPE
96
+ const key: Metadata = MetadataHelper.literal_to_metadata(prop.name);
97
+ const value: Metadata = explore_metadata(checker)(options)(
98
+ collection,
99
+ )(errors)(type, {
100
+ top: false,
101
+ object: obj,
102
+ property: prop.name,
103
+ nested: null,
104
+ escaped: false,
105
+ aliased: false,
106
+ });
107
+ Writable(value).optional =
108
+ (prop.flags & ts.SymbolFlags.Optional) !== 0;
109
+ insert(key)(value)(prop);
110
+ }
111
+
112
+ //----
113
+ // DYNAMIC PROPERTIES
114
+ //----
115
+ for (const index of checker.getIndexInfosOfType(parent)) {
116
+ // GET EXACT TYPE
117
+ const analyzer = (type: ts.Type) => (property: {} | null) =>
118
+ explore_metadata(checker)(options)(collection)(errors)(type, {
119
+ top: false,
120
+ object: obj,
121
+ property,
122
+ nested: null,
123
+ escaped: false,
124
+ aliased: false,
125
+ });
126
+ const key: Metadata = analyzer(index.keyType)(null);
127
+ const value: Metadata = analyzer(index.type)({});
128
+
129
+ if (
130
+ key.atomics.length +
131
+ key.constants
132
+ .map((c) => c.values.length)
133
+ .reduce((a, b) => a + b, 0) +
134
+ key.templates.length +
135
+ key.natives.filter(
136
+ (type) =>
137
+ type === "Boolean" ||
138
+ type === "BigInt" ||
139
+ type === "Number" ||
140
+ type === "String",
141
+ ).length !==
142
+ key.size()
143
+ )
144
+ errors.push({
145
+ name: key.getName(),
146
+ explore: {
147
+ top: false,
148
+ object: obj,
149
+ property: "[key]",
150
+ nested: null,
151
+ escaped: false,
152
+ aliased: false,
153
+ },
154
+ messages: [],
155
+ });
156
+
157
+ // INSERT WITH REQUIRED CONFIGURATION
158
+ insert(key)(value)(
159
+ index.declaration?.parent
160
+ ? checker.getSymbolAtLocation(index.declaration.parent)
161
+ : undefined,
162
+ (doc) => doc.name !== "default",
163
+ );
164
+ }
165
+ return obj;
166
+ };
167
+
168
+ const isProperty = (node: ts.Declaration) =>
169
+ ts.isPropertyDeclaration(node) ||
170
+ ts.isPropertyAssignment(node) ||
171
+ ts.isPropertySignature(node) ||
172
+ ts.isTypeLiteralNode(node);
173
+
174
+ const iterate_optional_coalesce = (meta: Metadata, type: ts.Type): void => {
175
+ if (type.isUnionOrIntersection())
176
+ type.types.forEach((child) => iterate_optional_coalesce(meta, child));
177
+ else iterate_metadata_coalesce(meta, type);
178
+ };
@@ -1,8 +1,8 @@
1
- export const $is_bigint_string = (str: string): boolean => {
2
- try {
3
- BigInt(str);
4
- return true;
5
- } catch {
6
- return false;
7
- }
8
- };
1
+ export const $is_bigint_string = (str: string): boolean => {
2
+ try {
3
+ BigInt(str);
4
+ return true;
5
+ } catch {
6
+ return false;
7
+ }
8
+ };