typia 4.2.0 → 4.2.1

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.
@@ -1,165 +1,165 @@
1
- import { CommentFactory } from "../../factories/CommentFactory";
2
-
3
- import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
4
- import { Metadata } from "../../metadata/Metadata";
5
- import { MetadataObject } from "../../metadata/MetadataObject";
6
- import { IJsonComponents } from "../../schemas/IJsonComponents";
7
-
8
- import { PatternUtil } from "../../utils/PatternUtil";
9
-
10
- import { IJsonSchema } from "../../module";
11
- import { ApplicationProgrammer } from "../ApplicationProgrammer";
12
- import { JSON_COMPONENTS_PREFIX } from "./JSON_SCHEMA_PREFIX";
13
- import { application_schema } from "./application_schema";
14
- import { metadata_to_pattern } from "./metadata_to_pattern";
15
-
16
- /**
17
- * @internal
18
- */
19
- export const application_object =
20
- (options: ApplicationProgrammer.IOptions) =>
21
- (components: IJsonComponents) =>
22
- (obj: MetadataObject) =>
23
- (nullable: boolean): IJsonSchema.IReference => {
24
- const key: string =
25
- options.purpose === "ajv"
26
- ? obj.name
27
- : `${obj.name}${nullable ? ".Nullable" : ""}`;
28
- const $id: string = `${JSON_COMPONENTS_PREFIX}/schemas/${key}`;
29
- const output = { $ref: $id };
30
-
31
- // TEMPORARY ASSIGNMENT
32
- if (components.schemas?.[key] !== undefined) return output;
33
- components.schemas ??= {};
34
- components.schemas[key] = {} as any;
35
-
36
- // ITERATE PROPERTIES
37
- const properties: Record<string, any> = {};
38
- const extraMeta: ISuperfluous = {
39
- patternProperties: {},
40
- additionalProperties: undefined,
41
- };
42
- const required: string[] = [];
43
-
44
- for (const property of obj.properties) {
45
- if (
46
- // FUNCTIONAL TYPE
47
- property.value.functional === true &&
48
- property.value.nullable === false &&
49
- property.value.isRequired() === true &&
50
- property.value.size() === 0
51
- )
52
- continue;
53
- else if (property.jsDocTags.find((tag) => tag.name === "hidden"))
54
- continue; // THE HIDDEN TAG
55
-
56
- const key: string | null = property.key.getSoleLiteral();
57
- const schema: IJsonSchema | null = application_schema(options)(
58
- true,
59
- )(components)(property.value)({
60
- deprecated:
61
- property.jsDocTags.some(
62
- (tag) => tag.name === "deprecated",
63
- ) || undefined,
64
- title: (() => {
65
- const info: IJsDocTagInfo | undefined =
66
- property.jsDocTags.find((tag) => tag.name === "title");
67
- return info?.text?.length
68
- ? CommentFactory.merge(info.text)
69
- : undefined;
70
- })(),
71
- description: property.description ?? undefined,
72
- "x-typia-metaTags": property.tags.length
73
- ? property.tags
74
- : undefined,
75
- "x-typia-jsDocTags": property.jsDocTags.length
76
- ? property.jsDocTags
77
- : undefined,
78
- "x-typia-required": property.value.required,
79
- "x-typia-optional": property.value.optional,
80
- });
81
-
82
- if (schema === null) continue;
83
- else if (key !== null) {
84
- properties[key] = schema;
85
- if (property.value.isRequired() === true) required.push(key);
86
- } else {
87
- const pattern: string = metadata_to_pattern(true)(property.key);
88
- if (pattern === PatternUtil.STRING)
89
- extraMeta.additionalProperties = [property.value, schema];
90
- else
91
- extraMeta.patternProperties[pattern] = [
92
- property.value,
93
- schema,
94
- ];
95
- }
96
- }
97
-
98
- const extraProps = {
99
- additionalProperties: extraMeta.additionalProperties?.[1],
100
- patternProperties: (() => {
101
- if (Object.keys(extraMeta.patternProperties).length === 0)
102
- return undefined;
103
- const output: Record<string, IJsonSchema> = {};
104
- for (const [key, value] of Object.entries(
105
- extraMeta.patternProperties,
106
- ))
107
- output[key] = value[1];
108
- return output;
109
- })(),
110
- };
111
- const schema: IJsonComponents.IObject = {
112
- $id: options.purpose === "ajv" ? $id : undefined,
113
- // $recursiveAnchor:
114
- // (options.purpose === "ajv" && obj.recursive) || undefined,
115
- type: "object",
116
- properties,
117
- nullable: options.purpose === "swagger" ? nullable : undefined,
118
- required: required.length ? required : undefined,
119
- description: obj.description,
120
- "x-typia-jsDocTags": obj.jsDocTags,
121
- ...(options.purpose === "ajv"
122
- ? extraProps
123
- : {
124
- // swagger can't express patternProperties
125
- "x-typia-additionalProperties":
126
- extraProps.additionalProperties,
127
- "x-typia-patternProperties": extraProps.patternProperties,
128
- additionalProperties:
129
- join(options)(components)(extraMeta),
130
- }),
131
- };
132
- components.schemas[key] = schema;
133
- return output;
134
- };
135
-
136
- const join =
137
- (options: ApplicationProgrammer.IOptions) =>
138
- (components: IJsonComponents) =>
139
- (extra: ISuperfluous): IJsonSchema | undefined => {
140
- // LIST UP METADATA
141
- const elements: [Metadata, IJsonSchema][] = Object.values(
142
- extra.patternProperties || {},
143
- );
144
- if (extra.additionalProperties)
145
- elements.push(extra.additionalProperties);
146
-
147
- // SHORT RETURN
148
- if (elements.length === 0) return undefined;
149
- else if (elements.length === 1) return elements[0]![1]!;
150
-
151
- // MERGE METADATA AND GENERATE VULNERABLE SCHEMA
152
- const meta: Metadata = elements
153
- .map((tuple) => tuple[0])
154
- .reduce((x, y) => Metadata.merge(x, y));
155
- return (
156
- application_schema(options)(true)(components)(meta)({
157
- "x-typia-required": false,
158
- }) ?? undefined
159
- );
160
- };
161
-
162
- interface ISuperfluous {
163
- additionalProperties?: [Metadata, IJsonSchema];
164
- patternProperties: Record<string, [Metadata, IJsonSchema]>;
165
- }
1
+ import { CommentFactory } from "../../factories/CommentFactory";
2
+
3
+ import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
4
+ import { Metadata } from "../../metadata/Metadata";
5
+ import { MetadataObject } from "../../metadata/MetadataObject";
6
+ import { IJsonComponents } from "../../schemas/IJsonComponents";
7
+
8
+ import { PatternUtil } from "../../utils/PatternUtil";
9
+
10
+ import { IJsonSchema } from "../../module";
11
+ import { ApplicationProgrammer } from "../ApplicationProgrammer";
12
+ import { JSON_COMPONENTS_PREFIX } from "./JSON_SCHEMA_PREFIX";
13
+ import { application_schema } from "./application_schema";
14
+ import { metadata_to_pattern } from "./metadata_to_pattern";
15
+
16
+ /**
17
+ * @internal
18
+ */
19
+ export const application_object =
20
+ (options: ApplicationProgrammer.IOptions) =>
21
+ (components: IJsonComponents) =>
22
+ (obj: MetadataObject) =>
23
+ (nullable: boolean): IJsonSchema.IReference => {
24
+ const key: string =
25
+ options.purpose === "ajv"
26
+ ? obj.name
27
+ : `${obj.name}${nullable ? ".Nullable" : ""}`;
28
+ const $id: string = `${JSON_COMPONENTS_PREFIX}/schemas/${key}`;
29
+ const output = { $ref: $id };
30
+
31
+ // TEMPORARY ASSIGNMENT
32
+ if (components.schemas?.[key] !== undefined) return output;
33
+ components.schemas ??= {};
34
+ components.schemas[key] = {} as any;
35
+
36
+ // ITERATE PROPERTIES
37
+ const properties: Record<string, any> = {};
38
+ const extraMeta: ISuperfluous = {
39
+ patternProperties: {},
40
+ additionalProperties: undefined,
41
+ };
42
+ const required: string[] = [];
43
+
44
+ for (const property of obj.properties) {
45
+ if (
46
+ // FUNCTIONAL TYPE
47
+ property.value.functional === true &&
48
+ property.value.nullable === false &&
49
+ property.value.isRequired() === true &&
50
+ property.value.size() === 0
51
+ )
52
+ continue;
53
+ else if (property.jsDocTags.find((tag) => tag.name === "hidden"))
54
+ continue; // THE HIDDEN TAG
55
+
56
+ const key: string | null = property.key.getSoleLiteral();
57
+ const schema: IJsonSchema | null = application_schema(options)(
58
+ true,
59
+ )(components)(property.value)({
60
+ deprecated:
61
+ property.jsDocTags.some(
62
+ (tag) => tag.name === "deprecated",
63
+ ) || undefined,
64
+ title: (() => {
65
+ const info: IJsDocTagInfo | undefined =
66
+ property.jsDocTags.find((tag) => tag.name === "title");
67
+ return info?.text?.length
68
+ ? CommentFactory.merge(info.text)
69
+ : undefined;
70
+ })(),
71
+ description: property.description ?? undefined,
72
+ "x-typia-metaTags": property.tags.length
73
+ ? property.tags
74
+ : undefined,
75
+ "x-typia-jsDocTags": property.jsDocTags.length
76
+ ? property.jsDocTags
77
+ : undefined,
78
+ "x-typia-required": property.value.required,
79
+ "x-typia-optional": property.value.optional,
80
+ });
81
+
82
+ if (schema === null) continue;
83
+ else if (key !== null) {
84
+ properties[key] = schema;
85
+ if (property.value.isRequired() === true) required.push(key);
86
+ } else {
87
+ const pattern: string = metadata_to_pattern(true)(property.key);
88
+ if (pattern === PatternUtil.STRING)
89
+ extraMeta.additionalProperties = [property.value, schema];
90
+ else
91
+ extraMeta.patternProperties[pattern] = [
92
+ property.value,
93
+ schema,
94
+ ];
95
+ }
96
+ }
97
+
98
+ const extraProps = {
99
+ additionalProperties: extraMeta.additionalProperties?.[1],
100
+ patternProperties: (() => {
101
+ if (Object.keys(extraMeta.patternProperties).length === 0)
102
+ return undefined;
103
+ const output: Record<string, IJsonSchema> = {};
104
+ for (const [key, value] of Object.entries(
105
+ extraMeta.patternProperties,
106
+ ))
107
+ output[key] = value[1];
108
+ return output;
109
+ })(),
110
+ };
111
+ const schema: IJsonComponents.IObject = {
112
+ $id: options.purpose === "ajv" ? $id : undefined,
113
+ // $recursiveAnchor:
114
+ // (options.purpose === "ajv" && obj.recursive) || undefined,
115
+ type: "object",
116
+ properties,
117
+ nullable: options.purpose === "swagger" ? nullable : undefined,
118
+ required: required.length ? required : undefined,
119
+ description: obj.description,
120
+ "x-typia-jsDocTags": obj.jsDocTags,
121
+ ...(options.purpose === "ajv"
122
+ ? extraProps
123
+ : {
124
+ // swagger can't express patternProperties
125
+ "x-typia-additionalProperties":
126
+ extraProps.additionalProperties,
127
+ "x-typia-patternProperties": extraProps.patternProperties,
128
+ additionalProperties:
129
+ join(options)(components)(extraMeta),
130
+ }),
131
+ };
132
+ components.schemas[key] = schema;
133
+ return output;
134
+ };
135
+
136
+ const join =
137
+ (options: ApplicationProgrammer.IOptions) =>
138
+ (components: IJsonComponents) =>
139
+ (extra: ISuperfluous): IJsonSchema | undefined => {
140
+ // LIST UP METADATA
141
+ const elements: [Metadata, IJsonSchema][] = Object.values(
142
+ extra.patternProperties || {},
143
+ );
144
+ if (extra.additionalProperties)
145
+ elements.push(extra.additionalProperties);
146
+
147
+ // SHORT RETURN
148
+ if (elements.length === 0) return undefined;
149
+ else if (elements.length === 1) return elements[0]![1]!;
150
+
151
+ // MERGE METADATA AND GENERATE VULNERABLE SCHEMA
152
+ const meta: Metadata = elements
153
+ .map((tuple) => tuple[0])
154
+ .reduce((x, y) => Metadata.merge(x, y));
155
+ return (
156
+ application_schema(options)(true)(components)(meta)({
157
+ "x-typia-required": false,
158
+ }) ?? undefined
159
+ );
160
+ };
161
+
162
+ interface ISuperfluous {
163
+ additionalProperties?: [Metadata, IJsonSchema];
164
+ patternProperties: Record<string, [Metadata, IJsonSchema]>;
165
+ }