typia 3.4.20 → 3.4.21
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.
- package/lib/metadata/Metadata.d.ts +1 -0
- package/lib/metadata/Metadata.js +113 -22
- package/lib/metadata/Metadata.js.map +1 -1
- package/lib/programmers/internal/application_array.js +29 -27
- package/lib/programmers/internal/application_array.js.map +1 -1
- package/lib/programmers/internal/application_object.js +96 -31
- package/lib/programmers/internal/application_object.js.map +1 -1
- package/lib/programmers/internal/application_schema.js +6 -118
- package/lib/programmers/internal/application_schema.js.map +1 -1
- package/lib/programmers/internal/application_tuple.js +3 -2
- package/lib/programmers/internal/application_tuple.js.map +1 -1
- package/lib/schemas/IJsonComponents.d.ts +4 -2
- package/lib/schemas/IJsonSchema.d.ts +2 -0
- package/package.json +1 -1
- package/src/metadata/Metadata.ts +54 -0
- package/src/programmers/helpers/UnionExplorer.ts +274 -274
- package/src/programmers/internal/application_array.ts +2 -0
- package/src/programmers/internal/application_object.ts +70 -20
- package/src/programmers/internal/application_schema.ts +9 -71
- package/src/programmers/internal/application_tuple.ts +6 -2
- package/src/programmers/internal/check_array.ts +22 -22
- package/src/schemas/IJsonComponents.ts +5 -3
- package/src/schemas/IJsonSchema.ts +2 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CommentFactory } from "../../factories/CommentFactory";
|
|
2
2
|
|
|
3
3
|
import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
|
|
4
|
+
import { Metadata } from "../../metadata/Metadata";
|
|
4
5
|
import { MetadataObject } from "../../metadata/MetadataObject";
|
|
5
6
|
import { IJsonComponents } from "../../schemas/IJsonComponents";
|
|
6
7
|
|
|
@@ -24,8 +25,10 @@ export const application_object =
|
|
|
24
25
|
|
|
25
26
|
// ITERATE PROPERTIES
|
|
26
27
|
const properties: Record<string, any> = {};
|
|
27
|
-
const
|
|
28
|
-
|
|
28
|
+
const extraMeta: ISuperfluous = {
|
|
29
|
+
patternProperties: {},
|
|
30
|
+
additionalProperties: undefined,
|
|
31
|
+
};
|
|
29
32
|
const required: string[] = [];
|
|
30
33
|
|
|
31
34
|
for (const property of obj.properties) {
|
|
@@ -38,7 +41,7 @@ export const application_object =
|
|
|
38
41
|
continue;
|
|
39
42
|
|
|
40
43
|
const key: string | null = property.key.getSoleLiteral();
|
|
41
|
-
const
|
|
44
|
+
const schema: IJsonSchema | null = application_schema(options)(
|
|
42
45
|
components,
|
|
43
46
|
)(true)(property.value, {
|
|
44
47
|
deprecated:
|
|
@@ -62,21 +65,35 @@ export const application_object =
|
|
|
62
65
|
"x-typia-required": property.value.required,
|
|
63
66
|
});
|
|
64
67
|
|
|
65
|
-
if (
|
|
68
|
+
if (schema === null) continue;
|
|
66
69
|
else if (key !== null) {
|
|
67
|
-
properties[key] =
|
|
70
|
+
properties[key] = schema;
|
|
68
71
|
if (property.value.required === true) required.push(key);
|
|
69
72
|
} else {
|
|
70
73
|
const pattern: string = metadata_to_pattern(true)(property.key);
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
if (pattern === PatternUtil.STRING)
|
|
75
|
+
extraMeta.additionalProperties = [property.value, schema];
|
|
76
|
+
else
|
|
77
|
+
extraMeta.patternProperties[pattern] = [
|
|
78
|
+
property.value,
|
|
79
|
+
schema,
|
|
80
|
+
];
|
|
77
81
|
}
|
|
78
82
|
}
|
|
79
83
|
|
|
84
|
+
const extraProps = {
|
|
85
|
+
additionalProperties: extraMeta.additionalProperties?.[1],
|
|
86
|
+
patternProperties: (() => {
|
|
87
|
+
if (Object.keys(extraMeta.patternProperties).length === 0)
|
|
88
|
+
return undefined;
|
|
89
|
+
const output: Record<string, IJsonSchema> = {};
|
|
90
|
+
for (const [key, value] of Object.entries(
|
|
91
|
+
extraMeta.patternProperties,
|
|
92
|
+
))
|
|
93
|
+
output[key] = value[1];
|
|
94
|
+
return output;
|
|
95
|
+
})(),
|
|
96
|
+
};
|
|
80
97
|
const schema: IJsonComponents.IObject = {
|
|
81
98
|
$id:
|
|
82
99
|
options.purpose === "ajv"
|
|
@@ -86,18 +103,51 @@ export const application_object =
|
|
|
86
103
|
(options.purpose === "ajv" && obj.recursive) || undefined,
|
|
87
104
|
type: "object",
|
|
88
105
|
properties,
|
|
89
|
-
patternProperties: Object.keys(patternProperties).length
|
|
90
|
-
? patternProperties
|
|
91
|
-
: undefined,
|
|
92
|
-
additionalProperties: additionalProperties.length
|
|
93
|
-
? additionalProperties.length === 1
|
|
94
|
-
? additionalProperties[0]
|
|
95
|
-
: { oneOf: additionalProperties }
|
|
96
|
-
: undefined,
|
|
97
106
|
nullable,
|
|
98
107
|
required: required.length ? required : undefined,
|
|
99
108
|
description: obj.description,
|
|
100
|
-
"x-
|
|
109
|
+
"x-typia-jsDocTags": obj.jsDocTags,
|
|
110
|
+
...(options.purpose === "ajv"
|
|
111
|
+
? extraProps
|
|
112
|
+
: {
|
|
113
|
+
// swagger can't express patternProperties
|
|
114
|
+
"x-typia-additionalProperties":
|
|
115
|
+
extraProps.additionalProperties,
|
|
116
|
+
"x-typia-patternProperties": extraProps.patternProperties,
|
|
117
|
+
additionalProperties:
|
|
118
|
+
join(options)(components)(extraMeta),
|
|
119
|
+
}),
|
|
101
120
|
};
|
|
102
121
|
components.schemas[key] = schema;
|
|
103
122
|
};
|
|
123
|
+
|
|
124
|
+
const join =
|
|
125
|
+
(options: ApplicationProgrammer.IOptions) =>
|
|
126
|
+
(components: IJsonComponents) =>
|
|
127
|
+
(extra: ISuperfluous): IJsonSchema | undefined => {
|
|
128
|
+
// LIST UP METADATA
|
|
129
|
+
const elements: [Metadata, IJsonSchema][] = Object.values(
|
|
130
|
+
extra.patternProperties || {},
|
|
131
|
+
);
|
|
132
|
+
if (extra.additionalProperties)
|
|
133
|
+
elements.push(extra.additionalProperties);
|
|
134
|
+
|
|
135
|
+
// SHORT RETURN
|
|
136
|
+
if (elements.length === 0) return undefined;
|
|
137
|
+
else if (elements.length === 1) return elements[0]![1]!;
|
|
138
|
+
|
|
139
|
+
// MERGE METADATA AND GENERATE VULNERABLE SCHEMA
|
|
140
|
+
const meta: Metadata = elements
|
|
141
|
+
.map((tuple) => tuple[0])
|
|
142
|
+
.reduce((x, y) => Metadata.merge(x, y));
|
|
143
|
+
return (
|
|
144
|
+
application_schema(options)(components)(true)(meta, {
|
|
145
|
+
"x-typia-required": false,
|
|
146
|
+
}) ?? undefined
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
interface ISuperfluous {
|
|
151
|
+
additionalProperties?: [Metadata, IJsonSchema];
|
|
152
|
+
patternProperties: Record<string, [Metadata, IJsonSchema]>;
|
|
153
|
+
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { Metadata } from "../../metadata/Metadata";
|
|
2
|
-
import { MetadataConstant } from "../../metadata/MetadataConstant";
|
|
3
2
|
import { IJsonComponents } from "../../schemas/IJsonComponents";
|
|
4
3
|
import { IJsonSchema } from "../../schemas/IJsonSchema";
|
|
5
4
|
|
|
6
|
-
import { ArrayUtil } from "../../utils/ArrayUtil";
|
|
7
|
-
|
|
8
5
|
import { ApplicationProgrammer } from "../ApplicationProgrammer";
|
|
9
6
|
import { AtomicPredicator } from "../helpers/AtomicPredicator";
|
|
10
7
|
import { application_array } from "./application_array";
|
|
@@ -74,7 +71,7 @@ export const application_schema =
|
|
|
74
71
|
// ARRAY
|
|
75
72
|
for (const schema of meta.arrays.values())
|
|
76
73
|
union.push(
|
|
77
|
-
application_array(options)(components)(
|
|
74
|
+
application_array(options)(components)()(
|
|
78
75
|
schema,
|
|
79
76
|
meta.nullable,
|
|
80
77
|
attribute,
|
|
@@ -82,18 +79,11 @@ export const application_schema =
|
|
|
82
79
|
);
|
|
83
80
|
|
|
84
81
|
// TUPLE
|
|
85
|
-
for (const items of meta.tuples)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
)
|
|
90
|
-
union.push(
|
|
91
|
-
application_tuple(options)(components)(
|
|
92
|
-
items,
|
|
93
|
-
meta.nullable,
|
|
94
|
-
attribute,
|
|
95
|
-
),
|
|
96
|
-
);
|
|
82
|
+
for (const items of meta.tuples) {
|
|
83
|
+
const tuple: IJsonSchema.ITuple = application_tuple(options)(
|
|
84
|
+
components,
|
|
85
|
+
)(items, meta.nullable, attribute);
|
|
86
|
+
if (options.purpose === "ajv") union.push(tuple);
|
|
97
87
|
else {
|
|
98
88
|
if (items.length === 0)
|
|
99
89
|
throw new Error(
|
|
@@ -102,16 +92,17 @@ export const application_schema =
|
|
|
102
92
|
|
|
103
93
|
// SWAGGER DOES NOT SUPPORT TUPLE TYPE YET
|
|
104
94
|
const merged: Metadata = items.reduce((x, y) =>
|
|
105
|
-
|
|
95
|
+
Metadata.merge(x, y),
|
|
106
96
|
);
|
|
107
97
|
union.push(
|
|
108
|
-
application_array(options)(components)(
|
|
98
|
+
application_array(options)(components)(tuple)(
|
|
109
99
|
merged,
|
|
110
100
|
merged?.nullable || false,
|
|
111
101
|
attribute,
|
|
112
102
|
),
|
|
113
103
|
);
|
|
114
104
|
}
|
|
105
|
+
}
|
|
115
106
|
|
|
116
107
|
// NATIVES
|
|
117
108
|
for (const native of meta.natives)
|
|
@@ -177,57 +168,4 @@ const recursive = (
|
|
|
177
168
|
...attribute,
|
|
178
169
|
});
|
|
179
170
|
|
|
180
|
-
/**
|
|
181
|
-
* @internal
|
|
182
|
-
* @todo: not perfect
|
|
183
|
-
*/
|
|
184
|
-
function merge_metadata(x: Metadata, y: Metadata): Metadata {
|
|
185
|
-
const output: Metadata = Metadata.create({
|
|
186
|
-
any: x.any || y.any,
|
|
187
|
-
nullable: x.nullable || y.nullable,
|
|
188
|
-
required: x.required && y.required,
|
|
189
|
-
functional: x.functional || y.functional,
|
|
190
|
-
|
|
191
|
-
resolved:
|
|
192
|
-
x.resolved !== null && y.resolved !== null
|
|
193
|
-
? merge_metadata(x.resolved, y.resolved)
|
|
194
|
-
: x.resolved || y.resolved,
|
|
195
|
-
atomics: [...new Set([...x.atomics, ...y.atomics])],
|
|
196
|
-
constants: [...x.constants],
|
|
197
|
-
templates: x.templates.slice(),
|
|
198
|
-
|
|
199
|
-
rest: null,
|
|
200
|
-
arrays: x.arrays.slice(),
|
|
201
|
-
tuples: x.tuples.slice(),
|
|
202
|
-
objects: x.objects.slice(),
|
|
203
|
-
|
|
204
|
-
natives: [...new Set([...x.natives, ...y.natives])],
|
|
205
|
-
sets: x.sets.slice(),
|
|
206
|
-
maps: x.maps.slice(),
|
|
207
|
-
});
|
|
208
|
-
for (const constant of y.constants) {
|
|
209
|
-
const target: MetadataConstant = ArrayUtil.take(
|
|
210
|
-
output.constants,
|
|
211
|
-
(elem) => elem.type === constant.type,
|
|
212
|
-
() => ({
|
|
213
|
-
type: constant.type,
|
|
214
|
-
values: [],
|
|
215
|
-
}),
|
|
216
|
-
);
|
|
217
|
-
for (const value of constant.values)
|
|
218
|
-
ArrayUtil.add(target.values, value);
|
|
219
|
-
}
|
|
220
|
-
for (const array of y.arrays)
|
|
221
|
-
ArrayUtil.set(output.arrays, array, (elem) => elem.getName());
|
|
222
|
-
for (const obj of y.objects)
|
|
223
|
-
ArrayUtil.set(output.objects, obj, (elem) => elem.name);
|
|
224
|
-
|
|
225
|
-
if (x.rest !== null)
|
|
226
|
-
ArrayUtil.set(output.arrays, x.rest, (elem) => elem.getName());
|
|
227
|
-
if (y.rest !== null)
|
|
228
|
-
ArrayUtil.set(output.arrays, y.rest, (elem) => elem.getName());
|
|
229
|
-
|
|
230
|
-
return output;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
171
|
const NO_BIGINT = "Error on typia.application(): does not allow bigint type.";
|
|
@@ -17,8 +17,12 @@ export const application_tuple =
|
|
|
17
17
|
attribute: IJsonSchema.IAttribute,
|
|
18
18
|
): IJsonSchema.ITuple => ({
|
|
19
19
|
type: "array",
|
|
20
|
-
items: items.map((meta) =>
|
|
21
|
-
application_schema(options)(components)(false)(meta,
|
|
20
|
+
items: items.map((meta, i) =>
|
|
21
|
+
application_schema(options)(components)(false)(meta.rest ?? meta, {
|
|
22
|
+
...attribute,
|
|
23
|
+
"x-typia-rest":
|
|
24
|
+
i === items.length - 1 ? meta.rest !== null : undefined,
|
|
25
|
+
}),
|
|
22
26
|
),
|
|
23
27
|
nullable,
|
|
24
28
|
...attribute,
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
|
|
3
|
-
import { ExpressionFactory } from "../../factories/ExpressionFactory";
|
|
4
|
-
|
|
5
|
-
import { IMetadataTag } from "../../metadata/IMetadataTag";
|
|
6
|
-
|
|
7
|
-
import { check_array_length } from "./check_array_length";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
export function check_array(
|
|
13
|
-
input: ts.Expression,
|
|
14
|
-
tagList: IMetadataTag[],
|
|
15
|
-
): ts.Expression {
|
|
16
|
-
const conditions: ts.Expression[] = [ExpressionFactory.isArray(input)];
|
|
17
|
-
|
|
18
|
-
const length: ts.Expression | null = check_array_length(input, tagList);
|
|
19
|
-
if (length !== null) conditions.push(length);
|
|
20
|
-
|
|
21
|
-
return conditions.reduce((x, y) => ts.factory.createLogicalAnd(x, y));
|
|
22
|
-
}
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
|
|
3
|
+
import { ExpressionFactory } from "../../factories/ExpressionFactory";
|
|
4
|
+
|
|
5
|
+
import { IMetadataTag } from "../../metadata/IMetadataTag";
|
|
6
|
+
|
|
7
|
+
import { check_array_length } from "./check_array_length";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export function check_array(
|
|
13
|
+
input: ts.Expression,
|
|
14
|
+
tagList: IMetadataTag[],
|
|
15
|
+
): ts.Expression {
|
|
16
|
+
const conditions: ts.Expression[] = [ExpressionFactory.isArray(input)];
|
|
17
|
+
|
|
18
|
+
const length: ts.Expression | null = check_array_length(input, tagList);
|
|
19
|
+
if (length !== null) conditions.push(length);
|
|
20
|
+
|
|
21
|
+
return conditions.reduce((x, y) => ts.factory.createLogicalAnd(x, y));
|
|
22
|
+
}
|
|
@@ -8,6 +8,8 @@ export interface IJsonComponents {
|
|
|
8
8
|
export namespace IJsonComponents {
|
|
9
9
|
export interface IObject {
|
|
10
10
|
$id?: string;
|
|
11
|
+
$recursiveAnchor?: boolean;
|
|
12
|
+
|
|
11
13
|
type: "object";
|
|
12
14
|
nullable: boolean;
|
|
13
15
|
|
|
@@ -17,8 +19,8 @@ export namespace IJsonComponents {
|
|
|
17
19
|
|
|
18
20
|
required?: string[];
|
|
19
21
|
description?: string;
|
|
20
|
-
"x-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
"x-typia-jsDocTags"?: IJsDocTagInfo[];
|
|
23
|
+
"x-typia-patternProperties"?: Record<string, IJsonSchema>;
|
|
24
|
+
"x-typia-additionalProperties"?: IJsonSchema;
|
|
23
25
|
}
|
|
24
26
|
}
|
|
@@ -53,6 +53,7 @@ export namespace IJsonSchema {
|
|
|
53
53
|
items: IJsonSchema;
|
|
54
54
|
minItems?: number;
|
|
55
55
|
maxItems?: number;
|
|
56
|
+
"x-typia-tuple"?: ITuple;
|
|
56
57
|
}
|
|
57
58
|
export interface ITuple extends ISignificant<"array"> {
|
|
58
59
|
items: IJsonSchema[];
|
|
@@ -86,5 +87,6 @@ export namespace IJsonSchema {
|
|
|
86
87
|
"x-typia-metaTags"?: IMetadataTag[];
|
|
87
88
|
"x-typia-jsDocTags"?: IJsDocTagInfo[];
|
|
88
89
|
"x-typia-required"?: boolean;
|
|
90
|
+
"x-typia-rest"?: boolean;
|
|
89
91
|
}
|
|
90
92
|
}
|