typia 3.5.0-dev.20230107 → 3.5.0-dev.20230125

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 (59) hide show
  1. package/lib/factories/internal/protocols/ProtocolMetadataUtil.d.ts +5 -0
  2. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js +80 -0
  3. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js.map +1 -1
  4. package/lib/factories/internal/protocols/emplace_protocol_object.js +0 -3
  5. package/lib/factories/internal/protocols/emplace_protocol_object.js.map +1 -1
  6. package/lib/factories/internal/protocols/iterate_protocol_map.d.ts +2 -1
  7. package/lib/factories/internal/protocols/iterate_protocol_map.js +21 -17
  8. package/lib/factories/internal/protocols/iterate_protocol_map.js.map +1 -1
  9. package/lib/factories/internal/protocols/iterate_protocol_metadata.js +34 -36
  10. package/lib/factories/internal/protocols/iterate_protocol_metadata.js.map +1 -1
  11. package/lib/factories/internal/protocols/iterate_protocol_never.d.ts +1 -0
  12. package/lib/factories/internal/protocols/iterate_protocol_never.js +6 -0
  13. package/lib/factories/internal/protocols/iterate_protocol_never.js.map +1 -0
  14. package/lib/factories/internal/protocols/iterate_protocol_object.d.ts +4 -0
  15. package/lib/factories/internal/protocols/iterate_protocol_object.js +157 -0
  16. package/lib/factories/internal/protocols/iterate_protocol_object.js.map +1 -0
  17. package/lib/factories/internal/protocols/iterate_protocol_repeated.d.ts +2 -1
  18. package/lib/factories/internal/protocols/iterate_protocol_repeated.js +5 -4
  19. package/lib/factories/internal/protocols/iterate_protocol_repeated.js.map +1 -1
  20. package/lib/factories/internal/protocols/iterate_protocol_tuple.js +1 -1
  21. package/lib/factories/internal/protocols/iterate_protocol_tuple.js.map +1 -1
  22. package/lib/messages/IProtocolMap.d.ts +5 -0
  23. package/lib/messages/IProtocolMap.js +3 -0
  24. package/lib/messages/IProtocolMap.js.map +1 -0
  25. package/lib/messages/IProtocolProperty.d.ts +2 -1
  26. package/lib/metadata/Metadata.d.ts +1 -0
  27. package/lib/metadata/Metadata.js +114 -23
  28. package/lib/metadata/Metadata.js.map +1 -1
  29. package/lib/programmers/MessageProgrammer.js +13 -6
  30. package/lib/programmers/MessageProgrammer.js.map +1 -1
  31. package/lib/programmers/internal/application_array.js +29 -27
  32. package/lib/programmers/internal/application_array.js.map +1 -1
  33. package/lib/programmers/internal/application_object.js +96 -31
  34. package/lib/programmers/internal/application_object.js.map +1 -1
  35. package/lib/programmers/internal/application_schema.js +28 -138
  36. package/lib/programmers/internal/application_schema.js.map +1 -1
  37. package/lib/programmers/internal/application_tuple.js +3 -2
  38. package/lib/programmers/internal/application_tuple.js.map +1 -1
  39. package/lib/schemas/IJsonComponents.d.ts +4 -2
  40. package/lib/schemas/IJsonSchema.d.ts +2 -0
  41. package/package.json +2 -1
  42. package/src/factories/internal/protocols/ProtocolMetadataUtil.ts +82 -0
  43. package/src/factories/internal/protocols/emplace_protocol_object.ts +1 -3
  44. package/src/factories/internal/protocols/iterate_protocol_map.ts +29 -9
  45. package/src/factories/internal/protocols/iterate_protocol_metadata.ts +38 -18
  46. package/src/factories/internal/protocols/iterate_protocol_never.ts +1 -0
  47. package/src/factories/internal/protocols/iterate_protocol_object.ts +110 -0
  48. package/src/factories/internal/protocols/iterate_protocol_repeated.ts +14 -5
  49. package/src/factories/internal/protocols/iterate_protocol_tuple.ts +5 -1
  50. package/src/messages/IProtocolMap.ts +5 -0
  51. package/src/messages/IProtocolProperty.ts +3 -1
  52. package/src/metadata/Metadata.ts +56 -1
  53. package/src/programmers/MessageProgrammer.ts +17 -7
  54. package/src/programmers/internal/application_array.ts +2 -0
  55. package/src/programmers/internal/application_object.ts +70 -20
  56. package/src/programmers/internal/application_schema.ts +15 -73
  57. package/src/programmers/internal/application_tuple.ts +6 -2
  58. package/src/schemas/IJsonComponents.ts +5 -3
  59. 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 patternProperties: Record<string, any> = {};
28
- const additionalProperties: IJsonSchema[] = [];
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 value: IJsonSchema | null = application_schema(options)(
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 (value === null) continue;
68
+ if (schema === null) continue;
66
69
  else if (key !== null) {
67
- properties[key] = value;
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
- options.purpose === "swagger" ||
73
- pattern === PatternUtil.STRING
74
- )
75
- additionalProperties.push(value);
76
- else patternProperties[pattern] = value;
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-typia_jsDocTags": obj.jsDocTags,
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[id] = 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,9 +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
5
  import { NameEncoder } from "../../utils/NameEncoder";
8
6
 
9
7
  import { ApplicationProgrammer } from "../ApplicationProgrammer";
@@ -75,7 +73,7 @@ export const application_schema =
75
73
  // ARRAY
76
74
  for (const schema of meta.arrays.values())
77
75
  union.push(
78
- application_array(options)(components)(
76
+ application_array(options)(components)()(
79
77
  schema,
80
78
  meta.nullable,
81
79
  attribute,
@@ -83,36 +81,33 @@ export const application_schema =
83
81
  );
84
82
 
85
83
  // TUPLE
86
- for (const items of meta.tuples)
87
- if (
84
+ for (const items of meta.tuples) {
85
+ const tuple: IJsonSchema.ITuple = application_tuple(options)(
86
+ components,
87
+ )(items, meta.nullable, attribute);
88
+ if (options.purpose === "swagger" && items.length === 0)
89
+ throw new Error(
90
+ "Error on typia.application(): swagger does not support zero length tuple type.",
91
+ );
92
+ else if (
88
93
  options.purpose === "ajv" &&
89
- items.every((i) => i.rest === null)
94
+ !items[items.length - 1]?.rest
90
95
  )
91
- union.push(
92
- application_tuple(options)(components)(
93
- items,
94
- meta.nullable,
95
- attribute,
96
- ),
97
- );
96
+ union.push(tuple);
98
97
  else {
99
- if (items.length === 0)
100
- throw new Error(
101
- "Error on typia.application(): swagger does not support zero length tuple type.",
102
- );
103
-
104
98
  // SWAGGER DOES NOT SUPPORT TUPLE TYPE YET
105
99
  const merged: Metadata = items.reduce((x, y) =>
106
- merge_metadata(x, y),
100
+ Metadata.merge(x, y),
107
101
  );
108
102
  union.push(
109
- application_array(options)(components)(
103
+ application_array(options)(components)(tuple)(
110
104
  merged,
111
105
  merged?.nullable || false,
112
106
  attribute,
113
107
  ),
114
108
  );
115
109
  }
110
+ }
116
111
 
117
112
  // NATIVES
118
113
  for (const native of meta.natives)
@@ -180,57 +175,4 @@ const recursive = (
180
175
  ...attribute,
181
176
  });
182
177
 
183
- /**
184
- * @internal
185
- * @todo: not perfect
186
- */
187
- function merge_metadata(x: Metadata, y: Metadata): Metadata {
188
- const output: Metadata = Metadata.create({
189
- any: x.any || y.any,
190
- nullable: x.nullable || y.nullable,
191
- required: x.required && y.required,
192
- functional: x.functional || y.functional,
193
-
194
- resolved:
195
- x.resolved !== null && y.resolved !== null
196
- ? merge_metadata(x.resolved, y.resolved)
197
- : x.resolved || y.resolved,
198
- atomics: [...new Set([...x.atomics, ...y.atomics])],
199
- constants: [...x.constants],
200
- templates: x.templates.slice(),
201
-
202
- rest: null,
203
- arrays: x.arrays.slice(),
204
- tuples: x.tuples.slice(),
205
- objects: x.objects.slice(),
206
-
207
- natives: [...new Set([...x.natives, ...y.natives])],
208
- sets: x.sets.slice(),
209
- maps: x.maps.slice(),
210
- });
211
- for (const constant of y.constants) {
212
- const target: MetadataConstant = ArrayUtil.take(
213
- output.constants,
214
- (elem) => elem.type === constant.type,
215
- () => ({
216
- type: constant.type,
217
- values: [],
218
- }),
219
- );
220
- for (const value of constant.values)
221
- ArrayUtil.add(target.values, value);
222
- }
223
- for (const array of y.arrays)
224
- ArrayUtil.set(output.arrays, array, (elem) => elem.getName());
225
- for (const obj of y.objects)
226
- ArrayUtil.set(output.objects, obj, (elem) => elem.name);
227
-
228
- if (x.rest !== null)
229
- ArrayUtil.set(output.arrays, x.rest, (elem) => elem.getName());
230
- if (y.rest !== null)
231
- ArrayUtil.set(output.arrays, y.rest, (elem) => elem.getName());
232
-
233
- return output;
234
- }
235
-
236
178
  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, attribute),
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,
@@ -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-typia_jsDocTags"?: IJsDocTagInfo[];
21
-
22
- $recursiveAnchor?: boolean;
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
  }