typia 3.8.0-dev.20230420-2 → 3.8.0-dev.20230426

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 (34) hide show
  1. package/README.md +4 -3
  2. package/lib/Primitive.d.ts +7 -1
  3. package/lib/factories/CommentFactory.d.ts +4 -0
  4. package/lib/factories/CommentFactory.js.map +1 -1
  5. package/lib/factories/internal/metadata/iterate_metadata.js +0 -6
  6. package/lib/factories/internal/metadata/iterate_metadata.js.map +1 -1
  7. package/lib/module.d.ts +3 -3
  8. package/lib/programmers/AssertParseProgrammer.js +1 -1
  9. package/lib/programmers/AssertParseProgrammer.js.map +1 -1
  10. package/lib/programmers/ValidateParseProgrammer.js +1 -1
  11. package/lib/programmers/ValidateParseProgrammer.js.map +1 -1
  12. package/lib/programmers/helpers/PruneJoiner.d.ts +1 -1
  13. package/lib/programmers/helpers/PruneJoiner.js +29 -2
  14. package/lib/programmers/helpers/PruneJoiner.js.map +1 -1
  15. package/lib/programmers/internal/application_schema.js +4 -2
  16. package/lib/programmers/internal/application_schema.js.map +1 -1
  17. package/lib/schemas/IJsonSchema.d.ts +9 -4
  18. package/package.json +2 -2
  19. package/src/Primitive.ts +17 -1
  20. package/src/factories/CommentFactory.ts +0 -1
  21. package/src/factories/internal/metadata/iterate_metadata.ts +1 -14
  22. package/src/module.ts +6 -6
  23. package/src/programmers/AssertParseProgrammer.ts +7 -4
  24. package/src/programmers/AssertProgrammer.ts +285 -285
  25. package/src/programmers/CheckerProgrammer.ts +875 -875
  26. package/src/programmers/FeatureProgrammer.ts +500 -500
  27. package/src/programmers/ValidateParseProgrammer.ts +4 -1
  28. package/src/programmers/ValidateProgrammer.ts +316 -316
  29. package/src/programmers/helpers/PruneJoiner.ts +94 -2
  30. package/src/programmers/internal/application_schema.ts +12 -2
  31. package/src/programmers/internal/check_custom.ts +31 -31
  32. package/src/programmers/internal/check_dynamic_properties.ts +194 -194
  33. package/src/programmers/internal/check_object.ts +55 -55
  34. package/src/schemas/IJsonSchema.ts +11 -3
@@ -6,22 +6,34 @@ import { MetadataObject } from "../../metadata/MetadataObject";
6
6
 
7
7
  import { ArrayUtil } from "../../utils/ArrayUtil";
8
8
 
9
+ import { metadata_to_pattern } from "../internal/metadata_to_pattern";
9
10
  import { prune_object_properties } from "../internal/prune_object_properties";
10
11
  import { IExpressionEntry } from "./IExpressionEntry";
11
12
 
12
13
  export namespace PruneJoiner {
13
14
  export const object = (
14
- _input: ts.Expression,
15
+ input: ts.Expression,
15
16
  entries: IExpressionEntry[],
16
17
  obj: MetadataObject,
17
18
  ): ts.ConciseBody => {
19
+ // PREPARE ASSETS
20
+ const regular = entries.filter((entry) => entry.key.isSoleLiteral());
21
+ const dynamic = entries.filter((entry) => !entry.key.isSoleLiteral());
22
+
18
23
  const statements: ts.Statement[] = ArrayUtil.flat(
19
- entries.map((entry) =>
24
+ regular.map((entry) =>
20
25
  ts.isBlock(entry.expression)
21
26
  ? [...entry.expression.statements]
22
27
  : [ts.factory.createExpressionStatement(entry.expression)],
23
28
  ),
24
29
  );
30
+ if (dynamic.length)
31
+ statements.push(
32
+ ts.factory.createExpressionStatement(
33
+ iterate_dynamic_properties({ regular, dynamic })(input),
34
+ ),
35
+ );
36
+
25
37
  statements.push(prune_object_properties(obj));
26
38
  return ts.factory.createBlock(statements, true);
27
39
  };
@@ -50,3 +62,83 @@ export namespace PruneJoiner {
50
62
  return ts.factory.createBlock(statements, true);
51
63
  };
52
64
  }
65
+
66
+ const iterate_dynamic_properties =
67
+ (props: { regular: IExpressionEntry[]; dynamic: IExpressionEntry[] }) =>
68
+ (input: ts.Expression) =>
69
+ ts.factory.createCallExpression(
70
+ IdentifierFactory.join(
71
+ ts.factory.createCallExpression(
72
+ ts.factory.createIdentifier("Object.entries"),
73
+ undefined,
74
+ [input],
75
+ ),
76
+ "forEach",
77
+ ),
78
+ undefined,
79
+ [
80
+ ts.factory.createArrowFunction(
81
+ undefined,
82
+ undefined,
83
+ [
84
+ IdentifierFactory.parameter(
85
+ ts.factory.createArrayBindingPattern(
86
+ ["key", "value"].map((l) =>
87
+ ts.factory.createBindingElement(
88
+ undefined,
89
+ undefined,
90
+ ts.factory.createIdentifier(l),
91
+ undefined,
92
+ ),
93
+ ),
94
+ ),
95
+ ),
96
+ ],
97
+ undefined,
98
+ undefined,
99
+ ts.factory.createBlock(
100
+ [
101
+ ts.factory.createIfStatement(
102
+ ts.factory.createStrictEquality(
103
+ ts.factory.createIdentifier("undefined"),
104
+ ts.factory.createIdentifier("value"),
105
+ ),
106
+ ts.factory.createReturnStatement(),
107
+ ),
108
+ ...props.regular.map(({ key }) =>
109
+ ts.factory.createIfStatement(
110
+ ts.factory.createStrictEquality(
111
+ ts.factory.createStringLiteral(
112
+ key.getSoleLiteral()!,
113
+ ),
114
+ ts.factory.createIdentifier("key"),
115
+ ),
116
+ ts.factory.createReturnStatement(),
117
+ ),
118
+ ),
119
+ ...props.dynamic.map((dynamic) =>
120
+ ts.factory.createIfStatement(
121
+ ts.factory.createCallExpression(
122
+ ts.factory.createIdentifier(
123
+ `RegExp(/${metadata_to_pattern(
124
+ true,
125
+ )(dynamic.key)}/).test`,
126
+ ),
127
+ undefined,
128
+ [ts.factory.createIdentifier("key")],
129
+ ),
130
+ ts.isBlock(dynamic.expression)
131
+ ? dynamic.expression
132
+ : ts.factory.createBlock([
133
+ ts.factory.createExpressionStatement(
134
+ dynamic.expression,
135
+ ),
136
+ ]),
137
+ ),
138
+ ),
139
+ ],
140
+ true,
141
+ ),
142
+ ),
143
+ ],
144
+ );
@@ -26,7 +26,11 @@ export const application_schema =
26
26
  attribute: IJsonSchema.IAttribute,
27
27
  ): BlockNever extends true ? IJsonSchema | null : IJsonSchema => {
28
28
  // VULNERABLE CASE
29
- if (meta.any === true) return {};
29
+ if (meta.any === true)
30
+ return {
31
+ ...attribute,
32
+ type: undefined,
33
+ };
30
34
  else if (meta.nullable && meta.empty())
31
35
  return { type: "null", ...attribute };
32
36
 
@@ -173,7 +177,13 @@ export const application_schema =
173
177
  //----
174
178
  // RETURNS
175
179
  //----
176
- if (union.length === 0) return blockNever === true ? null! : {};
180
+ if (union.length === 0)
181
+ return blockNever === true
182
+ ? null!
183
+ : {
184
+ ...attribute,
185
+ type: undefined,
186
+ };
177
187
  else if (union.length === 1) return union[0]!;
178
188
  return { oneOf: union, ...attribute };
179
189
  };
@@ -1,31 +1,31 @@
1
- import ts from "typescript";
2
-
3
- import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
4
-
5
- import { FunctionImporter } from "../helpers/FunctionImporeter";
6
- import { ICheckEntry } from "../helpers/ICheckEntry";
7
- import { get_comment_tags } from "./get_comment_tags";
8
-
9
- /**
10
- * @internal
11
- */
12
- export const check_custom =
13
- (type: string, alias?: string) =>
14
- (importer: FunctionImporter) =>
15
- (jsDocTags: IJsDocTagInfo[]) =>
16
- (input: ts.Expression): ICheckEntry.ITag[] =>
17
- get_comment_tags(true)(jsDocTags).map((tag) => ({
18
- expected: `${alias ?? type} (@${tag.name}${
19
- tag.value?.length ? ` ${tag.value}` : ""
20
- })`,
21
- expression: ts.factory.createCallExpression(
22
- importer.use("is_custom"),
23
- undefined,
24
- [
25
- ts.factory.createStringLiteral(tag.name),
26
- ts.factory.createStringLiteral(type),
27
- ts.factory.createStringLiteral(tag.value ?? ""),
28
- input,
29
- ],
30
- ),
31
- }));
1
+ import ts from "typescript";
2
+
3
+ import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
4
+
5
+ import { FunctionImporter } from "../helpers/FunctionImporeter";
6
+ import { ICheckEntry } from "../helpers/ICheckEntry";
7
+ import { get_comment_tags } from "./get_comment_tags";
8
+
9
+ /**
10
+ * @internal
11
+ */
12
+ export const check_custom =
13
+ (type: string, alias?: string) =>
14
+ (importer: FunctionImporter) =>
15
+ (jsDocTags: IJsDocTagInfo[]) =>
16
+ (input: ts.Expression): ICheckEntry.ITag[] =>
17
+ get_comment_tags(true)(jsDocTags).map((tag) => ({
18
+ expected: `${alias ?? type} (@${tag.name}${
19
+ tag.value?.length ? ` ${tag.value}` : ""
20
+ })`,
21
+ expression: ts.factory.createCallExpression(
22
+ importer.use("is_custom"),
23
+ undefined,
24
+ [
25
+ ts.factory.createStringLiteral(tag.name),
26
+ ts.factory.createStringLiteral(type),
27
+ ts.factory.createStringLiteral(tag.value ?? ""),
28
+ input,
29
+ ],
30
+ ),
31
+ }));
@@ -1,194 +1,194 @@
1
- import ts from "typescript";
2
-
3
- import { IdentifierFactory } from "../../factories/IdentifierFactory";
4
- import { StatementFactory } from "../../factories/StatementFactory";
5
-
6
- import { FunctionImporter } from "../helpers/FunctionImporeter";
7
- import { IExpressionEntry } from "../helpers/IExpressionEntry";
8
- import { check_everything } from "./check_everything";
9
- import { check_object } from "./check_object";
10
- import { metadata_to_pattern } from "./metadata_to_pattern";
11
-
12
- /**
13
- * @internal
14
- */
15
- export const check_dynamic_properties =
16
- (props: check_object.IProps) =>
17
- (importer: FunctionImporter) =>
18
- (
19
- input: ts.Expression,
20
- regular: IExpressionEntry<ts.Expression>[],
21
- dynamic: IExpressionEntry<ts.Expression>[],
22
- ): ts.Expression => {
23
- const length = IdentifierFactory.access(
24
- ts.factory.createCallExpression(
25
- ts.factory.createIdentifier("Object.keys"),
26
- undefined,
27
- [input],
28
- ),
29
- )("length");
30
- const left: ts.Expression | null =
31
- props.equals === true && dynamic.length === 0
32
- ? props.undefined === true ||
33
- regular.every((r) => r.meta.required)
34
- ? ts.factory.createStrictEquality(
35
- ts.factory.createNumericLiteral(
36
- regular.filter((r) => r.meta.required).length,
37
- ),
38
- length,
39
- )
40
- : ts.factory.createCallExpression(
41
- importer.use("is_between"),
42
- [],
43
- [
44
- length,
45
- ts.factory.createNumericLiteral(
46
- regular.filter((r) => r.meta.required).length,
47
- ),
48
- ts.factory.createNumericLiteral(regular.length),
49
- ],
50
- )
51
- : null;
52
- if (
53
- props.undefined === false &&
54
- left !== null &&
55
- regular.every((r) => r.meta.required)
56
- )
57
- return left;
58
-
59
- const criteria = props.entries
60
- ? ts.factory.createCallExpression(props.entries, undefined, [
61
- ts.factory.createCallExpression(
62
- ts.factory.createIdentifier("Object.keys"),
63
- undefined,
64
- [input],
65
- ),
66
- check_dynamic_property(props)(input, regular, dynamic),
67
- ])
68
- : ts.factory.createCallExpression(
69
- IdentifierFactory.access(
70
- ts.factory.createCallExpression(
71
- ts.factory.createIdentifier("Object.keys"),
72
- undefined,
73
- [input],
74
- ),
75
- )(props.assert ? "every" : "map"),
76
- undefined,
77
- [check_dynamic_property(props)(input, regular, dynamic)],
78
- );
79
- const right: ts.Expression = (props.halt || ((elem) => elem))(
80
- props.assert ? criteria : check_everything(criteria),
81
- );
82
- return left
83
- ? (props.undefined
84
- ? ts.factory.createLogicalOr
85
- : ts.factory.createLogicalAnd)(left, right)
86
- : right;
87
- };
88
-
89
- const check_dynamic_property =
90
- (props: check_object.IProps) =>
91
- (
92
- input: ts.Expression,
93
- regular: IExpressionEntry<ts.Expression>[],
94
- dynamic: IExpressionEntry<ts.Expression>[],
95
- ) => {
96
- //----
97
- // IF CONDITIONS
98
- //----
99
- // PREPARE ASSETS
100
- const key = ts.factory.createIdentifier("key");
101
- const value = ts.factory.createIdentifier("value");
102
-
103
- const statements: ts.Statement[] = [];
104
- const add = (exp: ts.Expression, output: ts.Expression) =>
105
- statements.push(
106
- ts.factory.createIfStatement(
107
- exp,
108
- ts.factory.createReturnStatement(output),
109
- ),
110
- );
111
-
112
- // GATHER CONDITIONS
113
- if (props.equals === true && regular.length)
114
- add(is_regular_property(regular), props.positive);
115
- statements.push(
116
- StatementFactory.constant(
117
- "value",
118
- ts.factory.createElementAccessExpression(input, key),
119
- ),
120
- );
121
- if (props.undefined === true)
122
- add(
123
- ts.factory.createStrictEquality(
124
- ts.factory.createIdentifier("undefined"),
125
- value,
126
- ),
127
- props.positive,
128
- );
129
-
130
- for (const entry of dynamic)
131
- add(
132
- ts.factory.createCallExpression(
133
- ts.factory.createIdentifier(
134
- `RegExp(/${metadata_to_pattern(true)(
135
- entry.key,
136
- )}/).test`,
137
- ),
138
- undefined,
139
- [key],
140
- ),
141
- entry.expression,
142
- );
143
-
144
- //----
145
- // FUNCTION BODY
146
- //----
147
- // CLOSURE BLOCK
148
- const block: ts.Block = ts.factory.createBlock(
149
- [
150
- ...statements,
151
- ts.factory.createReturnStatement(
152
- props.equals === true
153
- ? props.superfluous(value)
154
- : props.positive,
155
- ),
156
- ],
157
- true,
158
- );
159
-
160
- // RETURNS
161
- return ts.factory.createArrowFunction(
162
- undefined,
163
- undefined,
164
- [IdentifierFactory.parameter("key")],
165
- undefined,
166
- undefined,
167
- block,
168
- );
169
- };
170
-
171
- const is_regular_property = (regular: IExpressionEntry[]) =>
172
- ts.factory.createCallExpression(
173
- IdentifierFactory.access(
174
- ts.factory.createArrayLiteralExpression(
175
- regular.map((entry) =>
176
- ts.factory.createStringLiteral(entry.key.getSoleLiteral()!),
177
- ),
178
- ),
179
- )("some"),
180
- undefined,
181
- [
182
- ts.factory.createArrowFunction(
183
- undefined,
184
- undefined,
185
- [IdentifierFactory.parameter("prop")],
186
- undefined,
187
- undefined,
188
- ts.factory.createStrictEquality(
189
- ts.factory.createIdentifier("key"),
190
- ts.factory.createIdentifier("prop"),
191
- ),
192
- ),
193
- ],
194
- );
1
+ import ts from "typescript";
2
+
3
+ import { IdentifierFactory } from "../../factories/IdentifierFactory";
4
+ import { StatementFactory } from "../../factories/StatementFactory";
5
+
6
+ import { FunctionImporter } from "../helpers/FunctionImporeter";
7
+ import { IExpressionEntry } from "../helpers/IExpressionEntry";
8
+ import { check_everything } from "./check_everything";
9
+ import { check_object } from "./check_object";
10
+ import { metadata_to_pattern } from "./metadata_to_pattern";
11
+
12
+ /**
13
+ * @internal
14
+ */
15
+ export const check_dynamic_properties =
16
+ (props: check_object.IProps) =>
17
+ (importer: FunctionImporter) =>
18
+ (
19
+ input: ts.Expression,
20
+ regular: IExpressionEntry<ts.Expression>[],
21
+ dynamic: IExpressionEntry<ts.Expression>[],
22
+ ): ts.Expression => {
23
+ const length = IdentifierFactory.access(
24
+ ts.factory.createCallExpression(
25
+ ts.factory.createIdentifier("Object.keys"),
26
+ undefined,
27
+ [input],
28
+ ),
29
+ )("length");
30
+ const left: ts.Expression | null =
31
+ props.equals === true && dynamic.length === 0
32
+ ? props.undefined === true ||
33
+ regular.every((r) => r.meta.required)
34
+ ? ts.factory.createStrictEquality(
35
+ ts.factory.createNumericLiteral(
36
+ regular.filter((r) => r.meta.required).length,
37
+ ),
38
+ length,
39
+ )
40
+ : ts.factory.createCallExpression(
41
+ importer.use("is_between"),
42
+ [],
43
+ [
44
+ length,
45
+ ts.factory.createNumericLiteral(
46
+ regular.filter((r) => r.meta.required).length,
47
+ ),
48
+ ts.factory.createNumericLiteral(regular.length),
49
+ ],
50
+ )
51
+ : null;
52
+ if (
53
+ props.undefined === false &&
54
+ left !== null &&
55
+ regular.every((r) => r.meta.required)
56
+ )
57
+ return left;
58
+
59
+ const criteria = props.entries
60
+ ? ts.factory.createCallExpression(props.entries, undefined, [
61
+ ts.factory.createCallExpression(
62
+ ts.factory.createIdentifier("Object.keys"),
63
+ undefined,
64
+ [input],
65
+ ),
66
+ check_dynamic_property(props)(input, regular, dynamic),
67
+ ])
68
+ : ts.factory.createCallExpression(
69
+ IdentifierFactory.access(
70
+ ts.factory.createCallExpression(
71
+ ts.factory.createIdentifier("Object.keys"),
72
+ undefined,
73
+ [input],
74
+ ),
75
+ )(props.assert ? "every" : "map"),
76
+ undefined,
77
+ [check_dynamic_property(props)(input, regular, dynamic)],
78
+ );
79
+ const right: ts.Expression = (props.halt || ((elem) => elem))(
80
+ props.assert ? criteria : check_everything(criteria),
81
+ );
82
+ return left
83
+ ? (props.undefined
84
+ ? ts.factory.createLogicalOr
85
+ : ts.factory.createLogicalAnd)(left, right)
86
+ : right;
87
+ };
88
+
89
+ const check_dynamic_property =
90
+ (props: check_object.IProps) =>
91
+ (
92
+ input: ts.Expression,
93
+ regular: IExpressionEntry<ts.Expression>[],
94
+ dynamic: IExpressionEntry<ts.Expression>[],
95
+ ) => {
96
+ //----
97
+ // IF CONDITIONS
98
+ //----
99
+ // PREPARE ASSETS
100
+ const key = ts.factory.createIdentifier("key");
101
+ const value = ts.factory.createIdentifier("value");
102
+
103
+ const statements: ts.Statement[] = [];
104
+ const add = (exp: ts.Expression, output: ts.Expression) =>
105
+ statements.push(
106
+ ts.factory.createIfStatement(
107
+ exp,
108
+ ts.factory.createReturnStatement(output),
109
+ ),
110
+ );
111
+
112
+ // GATHER CONDITIONS
113
+ if (props.equals === true && regular.length)
114
+ add(is_regular_property(regular), props.positive);
115
+ statements.push(
116
+ StatementFactory.constant(
117
+ "value",
118
+ ts.factory.createElementAccessExpression(input, key),
119
+ ),
120
+ );
121
+ if (props.undefined === true)
122
+ add(
123
+ ts.factory.createStrictEquality(
124
+ ts.factory.createIdentifier("undefined"),
125
+ value,
126
+ ),
127
+ props.positive,
128
+ );
129
+
130
+ for (const entry of dynamic)
131
+ add(
132
+ ts.factory.createCallExpression(
133
+ ts.factory.createIdentifier(
134
+ `RegExp(/${metadata_to_pattern(true)(
135
+ entry.key,
136
+ )}/).test`,
137
+ ),
138
+ undefined,
139
+ [key],
140
+ ),
141
+ entry.expression,
142
+ );
143
+
144
+ //----
145
+ // FUNCTION BODY
146
+ //----
147
+ // CLOSURE BLOCK
148
+ const block: ts.Block = ts.factory.createBlock(
149
+ [
150
+ ...statements,
151
+ ts.factory.createReturnStatement(
152
+ props.equals === true
153
+ ? props.superfluous(value)
154
+ : props.positive,
155
+ ),
156
+ ],
157
+ true,
158
+ );
159
+
160
+ // RETURNS
161
+ return ts.factory.createArrowFunction(
162
+ undefined,
163
+ undefined,
164
+ [IdentifierFactory.parameter("key")],
165
+ undefined,
166
+ undefined,
167
+ block,
168
+ );
169
+ };
170
+
171
+ const is_regular_property = (regular: IExpressionEntry[]) =>
172
+ ts.factory.createCallExpression(
173
+ IdentifierFactory.access(
174
+ ts.factory.createArrayLiteralExpression(
175
+ regular.map((entry) =>
176
+ ts.factory.createStringLiteral(entry.key.getSoleLiteral()!),
177
+ ),
178
+ ),
179
+ )("some"),
180
+ undefined,
181
+ [
182
+ ts.factory.createArrowFunction(
183
+ undefined,
184
+ undefined,
185
+ [IdentifierFactory.parameter("prop")],
186
+ undefined,
187
+ undefined,
188
+ ts.factory.createStrictEquality(
189
+ ts.factory.createIdentifier("key"),
190
+ ts.factory.createIdentifier("prop"),
191
+ ),
192
+ ),
193
+ ],
194
+ );