typia 7.0.0-dev.20241011 → 7.0.0-dev.20241012

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 (250) hide show
  1. package/lib/factories/MetadataCollection.d.ts +4 -4
  2. package/lib/factories/MetadataCollection.js +6 -4
  3. package/lib/factories/MetadataCollection.js.map +1 -1
  4. package/lib/factories/MetadataFactory.d.ts +2 -2
  5. package/lib/factories/MetadataFactory.js +8 -2
  6. package/lib/factories/MetadataFactory.js.map +1 -1
  7. package/lib/factories/MetadataTypeTagFactory.d.ts +2 -2
  8. package/lib/factories/MetadataTypeTagFactory.js +6 -6
  9. package/lib/factories/MetadataTypeTagFactory.js.map +1 -1
  10. package/lib/factories/MetadataTypeTagSchemaFactory.d.ts +2 -2
  11. package/lib/factories/MetadataTypeTagSchemaFactory.js +1 -1
  12. package/lib/factories/MetadataTypeTagSchemaFactory.js.map +1 -1
  13. package/lib/factories/ProtobufFactory.js +12 -22
  14. package/lib/factories/ProtobufFactory.js.map +1 -1
  15. package/lib/factories/internal/metadata/emplace_metadata_object.d.ts +2 -2
  16. package/lib/factories/internal/metadata/iterate_metadata_collection.js +2 -1
  17. package/lib/factories/internal/metadata/iterate_metadata_collection.js.map +1 -1
  18. package/lib/factories/internal/metadata/iterate_metadata_comment_tags.d.ts +2 -2
  19. package/lib/factories/internal/metadata/iterate_metadata_intersection.js +5 -2
  20. package/lib/factories/internal/metadata/iterate_metadata_intersection.js.map +1 -1
  21. package/lib/factories/internal/metadata/iterate_metadata_object.js +5 -1
  22. package/lib/factories/internal/metadata/iterate_metadata_object.js.map +1 -1
  23. package/lib/factories/internal/metadata/iterate_metadata_sort.js +6 -2
  24. package/lib/factories/internal/metadata/iterate_metadata_sort.js.map +1 -1
  25. package/lib/internal/$ProtobufSizer.js +1 -8
  26. package/lib/internal/$ProtobufSizer.js.map +1 -1
  27. package/lib/json.d.ts +1 -1
  28. package/lib/module.d.ts +1 -1
  29. package/lib/module.js +1 -1
  30. package/lib/module.js.map +1 -1
  31. package/lib/programmers/CheckerProgrammer.d.ts +2 -2
  32. package/lib/programmers/CheckerProgrammer.js +5 -3
  33. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  34. package/lib/programmers/FeatureProgrammer.d.ts +5 -5
  35. package/lib/programmers/FeatureProgrammer.js.map +1 -1
  36. package/lib/programmers/IsProgrammer.d.ts +2 -2
  37. package/lib/programmers/RandomProgrammer.js +1 -1
  38. package/lib/programmers/RandomProgrammer.js.map +1 -1
  39. package/lib/programmers/helpers/ProtobufUtil.d.ts +2 -2
  40. package/lib/programmers/helpers/ProtobufUtil.js.map +1 -1
  41. package/lib/programmers/helpers/PruneJoiner.d.ts +2 -2
  42. package/lib/programmers/helpers/RandomJoiner.d.ts +2 -2
  43. package/lib/programmers/helpers/UnionExplorer.d.ts +3 -3
  44. package/lib/programmers/helpers/UnionExplorer.js.map +1 -1
  45. package/lib/programmers/helpers/UnionPredicator.d.ts +3 -3
  46. package/lib/programmers/helpers/UnionPredicator.js.map +1 -1
  47. package/lib/programmers/http/HttpFormDataProgrammer.js +1 -1
  48. package/lib/programmers/http/HttpFormDataProgrammer.js.map +1 -1
  49. package/lib/programmers/http/HttpHeadersProgrammer.js +1 -1
  50. package/lib/programmers/http/HttpHeadersProgrammer.js.map +1 -1
  51. package/lib/programmers/http/HttpQueryProgrammer.js +2 -2
  52. package/lib/programmers/http/HttpQueryProgrammer.js.map +1 -1
  53. package/lib/programmers/internal/application_union_discriminator.js +2 -2
  54. package/lib/programmers/internal/application_union_discriminator.js.map +1 -1
  55. package/lib/programmers/internal/application_v30_alias.js +1 -1
  56. package/lib/programmers/internal/application_v30_alias.js.map +1 -1
  57. package/lib/programmers/internal/application_v30_schema.js +1 -1
  58. package/lib/programmers/internal/application_v30_schema.js.map +1 -1
  59. package/lib/programmers/internal/application_v31_alias.js +1 -1
  60. package/lib/programmers/internal/application_v31_alias.js.map +1 -1
  61. package/lib/programmers/internal/application_v31_schema.js +1 -1
  62. package/lib/programmers/internal/application_v31_schema.js.map +1 -1
  63. package/lib/programmers/internal/llm_schema_object.js +1 -1
  64. package/lib/programmers/internal/llm_schema_object.js.map +1 -1
  65. package/lib/programmers/internal/llm_schema_station.js +2 -2
  66. package/lib/programmers/internal/llm_schema_station.js.map +1 -1
  67. package/lib/programmers/internal/prune_object_properties.js.map +1 -1
  68. package/lib/programmers/json/JsonApplicationProgrammer.js +6 -5
  69. package/lib/programmers/json/JsonApplicationProgrammer.js.map +1 -1
  70. package/lib/programmers/json/JsonSchemasProgrammer.d.ts +1 -1
  71. package/lib/programmers/json/JsonStringifyProgrammer.js +3 -3
  72. package/lib/programmers/json/JsonStringifyProgrammer.js.map +1 -1
  73. package/lib/programmers/llm/LlmApplicationProgrammer.js +7 -6
  74. package/lib/programmers/llm/LlmApplicationProgrammer.js.map +1 -1
  75. package/lib/programmers/llm/LlmSchemaProgrammer.js +1 -1
  76. package/lib/programmers/llm/LlmSchemaProgrammer.js.map +1 -1
  77. package/lib/programmers/misc/MiscCloneProgrammer.js +1 -1
  78. package/lib/programmers/misc/MiscCloneProgrammer.js.map +1 -1
  79. package/lib/programmers/misc/MiscPruneProgrammer.js +1 -1
  80. package/lib/programmers/misc/MiscPruneProgrammer.js.map +1 -1
  81. package/lib/programmers/notations/NotationGeneralProgrammer.js +1 -1
  82. package/lib/programmers/notations/NotationGeneralProgrammer.js.map +1 -1
  83. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js +6 -6
  84. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js.map +1 -1
  85. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js +1 -1
  86. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js.map +1 -1
  87. package/lib/programmers/protobuf/ProtobufMessageProgrammer.js +3 -3
  88. package/lib/programmers/protobuf/ProtobufMessageProgrammer.js.map +1 -1
  89. package/lib/schemas/json/IJsonSchemaCollection.js +3 -0
  90. package/lib/schemas/json/IJsonSchemaCollection.js.map +1 -0
  91. package/lib/schemas/metadata/IMetadata.d.ts +4 -1
  92. package/lib/schemas/metadata/IMetadataArray.d.ts +1 -2
  93. package/lib/schemas/metadata/IMetadataComponents.d.ts +2 -2
  94. package/lib/schemas/metadata/IMetadataDictionary.d.ts +2 -2
  95. package/lib/schemas/metadata/IMetadataObject.d.ts +2 -8
  96. package/lib/schemas/metadata/IMetadataObjectType.d.ts +11 -0
  97. package/lib/schemas/{json/IJsonSchemaList.js → metadata/IMetadataObjectType.js} +1 -1
  98. package/lib/schemas/metadata/IMetadataObjectType.js.map +1 -0
  99. package/lib/schemas/metadata/IMetadataTuple.d.ts +1 -2
  100. package/lib/schemas/metadata/Metadata.js +14 -15
  101. package/lib/schemas/metadata/Metadata.js.map +1 -1
  102. package/lib/schemas/metadata/MetadataArray.js +1 -1
  103. package/lib/schemas/metadata/MetadataArray.js.map +1 -1
  104. package/lib/schemas/metadata/MetadataComponents.d.ts +2 -2
  105. package/lib/schemas/metadata/MetadataComponents.js +2 -2
  106. package/lib/schemas/metadata/MetadataComponents.js.map +1 -1
  107. package/lib/schemas/metadata/MetadataObject.d.ts +8 -12
  108. package/lib/schemas/metadata/MetadataObject.js +44 -82
  109. package/lib/schemas/metadata/MetadataObject.js.map +1 -1
  110. package/lib/schemas/metadata/MetadataObjectType.d.ts +20 -0
  111. package/lib/schemas/metadata/MetadataObjectType.js +106 -0
  112. package/lib/schemas/metadata/MetadataObjectType.js.map +1 -0
  113. package/lib/schemas/metadata/MetadataTuple.js +1 -1
  114. package/lib/schemas/metadata/MetadataTuple.js.map +1 -1
  115. package/lib/transformers/TransformerError.js.map +1 -1
  116. package/package.json +2 -2
  117. package/src/executable/TypiaGenerateWizard.ts +83 -83
  118. package/src/executable/TypiaSetupWizard.ts +174 -174
  119. package/src/executable/setup/ArgumentParser.ts +42 -42
  120. package/src/executable/setup/FileRetriever.ts +19 -19
  121. package/src/executable/setup/PackageManager.ts +87 -87
  122. package/src/factories/IdentifierFactory.ts +89 -89
  123. package/src/factories/MetadataCollection.ts +280 -278
  124. package/src/factories/MetadataFactory.ts +11 -5
  125. package/src/factories/MetadataTypeTagFactory.ts +386 -385
  126. package/src/factories/MetadataTypeTagSchemaFactory.ts +82 -82
  127. package/src/factories/NumericRangeFactory.ts +72 -72
  128. package/src/factories/ProtobufFactory.ts +14 -28
  129. package/src/factories/StatementFactory.ts +90 -90
  130. package/src/factories/TemplateFactory.ts +64 -64
  131. package/src/factories/TypeFactory.ts +140 -140
  132. package/src/factories/internal/metadata/emplace_metadata_alias.ts +32 -32
  133. package/src/factories/internal/metadata/emplace_metadata_array_type.ts +39 -39
  134. package/src/factories/internal/metadata/emplace_metadata_object.ts +2 -2
  135. package/src/factories/internal/metadata/emplace_metadata_tuple.ts +56 -56
  136. package/src/factories/internal/metadata/explore_metadata.ts +30 -30
  137. package/src/factories/internal/metadata/iterate_metadata.ts +54 -54
  138. package/src/factories/internal/metadata/iterate_metadata_alias.ts +28 -28
  139. package/src/factories/internal/metadata/iterate_metadata_array.ts +63 -63
  140. package/src/factories/internal/metadata/iterate_metadata_atomic.ts +62 -62
  141. package/src/factories/internal/metadata/iterate_metadata_coalesce.ts +28 -28
  142. package/src/factories/internal/metadata/iterate_metadata_collection.ts +4 -3
  143. package/src/factories/internal/metadata/iterate_metadata_comment_tags.ts +2 -2
  144. package/src/factories/internal/metadata/iterate_metadata_constant.ts +76 -76
  145. package/src/factories/internal/metadata/iterate_metadata_escape.ts +49 -49
  146. package/src/factories/internal/metadata/iterate_metadata_intersection.ts +219 -216
  147. package/src/factories/internal/metadata/iterate_metadata_map.ts +52 -52
  148. package/src/factories/internal/metadata/iterate_metadata_native.ts +236 -236
  149. package/src/factories/internal/metadata/iterate_metadata_object.ts +35 -27
  150. package/src/factories/internal/metadata/iterate_metadata_set.ts +39 -39
  151. package/src/factories/internal/metadata/iterate_metadata_sort.ts +87 -83
  152. package/src/factories/internal/metadata/iterate_metadata_template.ts +42 -42
  153. package/src/factories/internal/metadata/iterate_metadata_tuple.ts +26 -26
  154. package/src/factories/internal/metadata/iterate_metadata_union.ts +19 -19
  155. package/src/internal/$ProtobufSizer.ts +1 -7
  156. package/src/json.ts +1 -1
  157. package/src/module.ts +1 -1
  158. package/src/programmers/CheckerProgrammer.ts +7 -5
  159. package/src/programmers/FeatureProgrammer.ts +9 -6
  160. package/src/programmers/IsProgrammer.ts +2 -2
  161. package/src/programmers/RandomProgrammer.ts +3 -3
  162. package/src/programmers/functional/FunctionalIsFunctionProgrammer.ts +72 -72
  163. package/src/programmers/functional/FunctionalIsParametersProgrammer.ts +113 -113
  164. package/src/programmers/functional/FunctionalIsReturnProgrammer.ts +116 -116
  165. package/src/programmers/functional/internal/FunctionalGeneralProgrammer.ts +34 -34
  166. package/src/programmers/helpers/AtomicPredicator.ts +35 -35
  167. package/src/programmers/helpers/CloneJoiner.ts +143 -143
  168. package/src/programmers/helpers/HttpMetadataUtil.ts +21 -21
  169. package/src/programmers/helpers/NotationJoiner.ts +144 -144
  170. package/src/programmers/helpers/ProtobufUtil.ts +125 -125
  171. package/src/programmers/helpers/PruneJoiner.ts +148 -148
  172. package/src/programmers/helpers/RandomJoiner.ts +2 -2
  173. package/src/programmers/helpers/StringifyPredicator.ts +13 -13
  174. package/src/programmers/helpers/UnionExplorer.ts +372 -372
  175. package/src/programmers/helpers/UnionPredicator.ts +79 -77
  176. package/src/programmers/http/HttpFormDataProgrammer.ts +3 -3
  177. package/src/programmers/http/HttpHeadersProgrammer.ts +3 -3
  178. package/src/programmers/http/HttpQueryProgrammer.ts +4 -4
  179. package/src/programmers/internal/application_array.ts +56 -56
  180. package/src/programmers/internal/application_bigint.ts +25 -25
  181. package/src/programmers/internal/application_boolean.ts +25 -25
  182. package/src/programmers/internal/application_escaped.ts +96 -96
  183. package/src/programmers/internal/application_number.ts +25 -25
  184. package/src/programmers/internal/application_plugin.ts +19 -19
  185. package/src/programmers/internal/application_string.ts +25 -25
  186. package/src/programmers/internal/application_templates.ts +64 -64
  187. package/src/programmers/internal/application_union_discriminator.ts +35 -35
  188. package/src/programmers/internal/application_v30_alias.ts +59 -59
  189. package/src/programmers/internal/application_v30_native.ts +29 -29
  190. package/src/programmers/internal/application_v30_object.ts +165 -165
  191. package/src/programmers/internal/application_v30_schema.ts +220 -220
  192. package/src/programmers/internal/application_v30_tuple.ts +33 -33
  193. package/src/programmers/internal/application_v31_alias.ts +47 -47
  194. package/src/programmers/internal/application_v31_constant.ts +29 -29
  195. package/src/programmers/internal/application_v31_native.ts +25 -25
  196. package/src/programmers/internal/application_v31_object.ts +147 -147
  197. package/src/programmers/internal/application_v31_schema.ts +215 -215
  198. package/src/programmers/internal/application_v31_tuple.ts +22 -22
  199. package/src/programmers/internal/check_array_length.ts +46 -46
  200. package/src/programmers/internal/check_bigint.ts +49 -49
  201. package/src/programmers/internal/check_everything.ts +23 -23
  202. package/src/programmers/internal/check_native.ts +27 -27
  203. package/src/programmers/internal/check_number.ts +111 -111
  204. package/src/programmers/internal/check_string.ts +49 -49
  205. package/src/programmers/internal/check_template.ts +48 -48
  206. package/src/programmers/internal/check_union_array_like.ts +334 -334
  207. package/src/programmers/internal/decode_union_object.ts +116 -116
  208. package/src/programmers/internal/feature_object_entries.ts +2 -2
  209. package/src/programmers/internal/llm_schema_array.ts +22 -22
  210. package/src/programmers/internal/llm_schema_escaped.ts +84 -84
  211. package/src/programmers/internal/llm_schema_object.ts +132 -132
  212. package/src/programmers/internal/llm_schema_station.ts +190 -190
  213. package/src/programmers/internal/metadata_to_pattern.ts +42 -42
  214. package/src/programmers/internal/postfix_of_tuple.ts +5 -5
  215. package/src/programmers/internal/prune_object_properties.ts +2 -2
  216. package/src/programmers/internal/stringify_dynamic_properties.ts +162 -162
  217. package/src/programmers/internal/stringify_regular_properties.ts +81 -81
  218. package/src/programmers/internal/template_to_pattern.ts +23 -23
  219. package/src/programmers/internal/wrap_metadata_rest_tuple.ts +23 -23
  220. package/src/programmers/json/JsonApplicationProgrammer.ts +3 -3
  221. package/src/programmers/json/JsonSchemasProgrammer.ts +1 -1
  222. package/src/programmers/json/JsonStringifyProgrammer.ts +5 -5
  223. package/src/programmers/llm/LlmApplicationProgrammer.ts +4 -4
  224. package/src/programmers/llm/LlmSchemaProgrammer.ts +1 -1
  225. package/src/programmers/misc/MiscCloneProgrammer.ts +3 -3
  226. package/src/programmers/misc/MiscPruneProgrammer.ts +3 -3
  227. package/src/programmers/notations/NotationGeneralProgrammer.ts +3 -3
  228. package/src/programmers/protobuf/ProtobufDecodeProgrammer.ts +11 -11
  229. package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +8 -8
  230. package/src/programmers/protobuf/ProtobufMessageProgrammer.ts +201 -201
  231. package/src/schemas/json/{IJsonSchemaList.ts → IJsonSchemaCollection.ts} +22 -22
  232. package/src/schemas/metadata/IMetadata.ts +4 -1
  233. package/src/schemas/metadata/IMetadataArray.ts +1 -2
  234. package/src/schemas/metadata/IMetadataComponents.ts +2 -2
  235. package/src/schemas/metadata/IMetadataDictionary.ts +11 -11
  236. package/src/schemas/metadata/IMetadataObject.ts +6 -13
  237. package/src/schemas/metadata/IMetadataObjectType.ts +13 -0
  238. package/src/schemas/metadata/IMetadataTuple.ts +1 -2
  239. package/src/schemas/metadata/Metadata.ts +616 -616
  240. package/src/schemas/metadata/MetadataArray.ts +1 -1
  241. package/src/schemas/metadata/MetadataComponents.ts +98 -98
  242. package/src/schemas/metadata/MetadataObject.ts +48 -139
  243. package/src/schemas/metadata/MetadataObjectType.ts +149 -0
  244. package/src/schemas/metadata/MetadataTuple.ts +1 -1
  245. package/src/transformers/TransformerError.ts +8 -7
  246. package/src/transformers/features/json/JsonSchemasTransformer.ts +1 -1
  247. package/src/utils/MapUtil.ts +14 -14
  248. package/src/utils/NameEncoder.ts +32 -32
  249. package/lib/schemas/json/IJsonSchemaList.js.map +0 -1
  250. /package/lib/schemas/json/{IJsonSchemaList.d.ts → IJsonSchemaCollection.d.ts} +0 -0
@@ -1,385 +1,386 @@
1
- import { IMetadataTypeTag } from "../schemas/metadata/IMetadataTypeTag";
2
- import { Metadata } from "../schemas/metadata/Metadata";
3
- import { MetadataObject } from "../schemas/metadata/MetadataObject";
4
- import { MetadataProperty } from "../schemas/metadata/MetadataProperty";
5
-
6
- import { MetadataFactory } from "./MetadataFactory";
7
- import { MetadataTypeTagSchemaFactory } from "./MetadataTypeTagSchemaFactory";
8
-
9
- export namespace MetadataTypeTagFactory {
10
- export const analyze = (props: {
11
- errors: MetadataFactory.IError[];
12
- type: "boolean" | "bigint" | "number" | "string" | "array";
13
- objects: MetadataObject[];
14
- explore: MetadataFactory.IExplore;
15
- }): IMetadataTypeTag[] => {
16
- const messages: string[] = [];
17
- const report = (next: {
18
- property: string | null;
19
- message: string;
20
- }): false => {
21
- messages.push(
22
- `the property ${
23
- next.property === null
24
- ? `["typia.tag"]`
25
- : `["typia.tag.${next.property}"]`
26
- } ${next.message}.`,
27
- );
28
- return false;
29
- };
30
-
31
- //----
32
- // VALIDATION PROCESS
33
- //----
34
- const filtered: MetadataObject[] = props.objects.filter((obj) => {
35
- // ONLY ONE PROPERTY
36
- if (obj.properties.length !== 1) return false;
37
-
38
- // THE TAG.TYPE PROPERTY MUST BE
39
- const top: MetadataProperty = obj.properties[0]!;
40
- if (
41
- top.key.getSoleLiteral() !== "typia.tag" ||
42
- top.value.size() !== 1 ||
43
- top.value.objects.length !== 1
44
- )
45
- return false;
46
- else if (top.value.optional === false)
47
- return report({
48
- property: null,
49
- message: "must be optional object",
50
- });
51
-
52
- // CHECK LIST OF PROPERTIES
53
- const tag: MetadataObject = top.value.objects[0]!;
54
- const statics: string[] = tag.properties
55
- .map((p) => p.key.getSoleLiteral()!)
56
- .filter((str) => str !== null);
57
- if (ESSENTIAL_FIELDS.some((f) => !statics.includes(f)))
58
- return report({
59
- property: null,
60
- message: `must have at least three properties - ${ESSENTIAL_FIELDS.map(
61
- (str) => `'${str}'`,
62
- ).join(", ")}`,
63
- });
64
-
65
- const each: boolean[] = tag.properties.map((p) => {
66
- const key: string | null = p.key.getSoleLiteral();
67
- if (key === null) return true;
68
- else if (FIELDS.includes(key) === false) return true;
69
- return validate_property({
70
- report,
71
- key,
72
- value: p.value,
73
- });
74
- });
75
- return each.every((v) => v === true);
76
- });
77
- if (filtered.length === 0) return [];
78
-
79
- //----
80
- // CONSTRUCT TYPE TAGS
81
- //----
82
- // CREATE 1ST
83
- const tagList: Array<ITypeTag | null> = filtered.map((object) =>
84
- create_metadata_type_tag({
85
- report,
86
- object,
87
- }),
88
- );
89
-
90
- const output: IMetadataTypeTag[] = [];
91
- for (const tag of tagList)
92
- if (tag !== null)
93
- output.push({
94
- target: tag.target.some((str) => str === props.type)
95
- ? props.type
96
- : null!,
97
- name: tag.name,
98
- kind: tag.kind,
99
- value: tag.value,
100
- validate: tag.validate[props.type]!,
101
- exclusive: tag.exclusive,
102
- schema: tag.schema,
103
- });
104
- validate({
105
- report,
106
- type: props.type,
107
- tags: output,
108
- });
109
-
110
- if (messages.length > 0) {
111
- props.errors.push({
112
- name: [props.type, ...props.objects.map((o) => o.name)].join(" & "),
113
- explore: props.explore,
114
- messages,
115
- });
116
- return [];
117
- }
118
- return output;
119
- };
120
-
121
- export const validate = (props: {
122
- report: (next: { property: string | null; message: string }) => false;
123
- type: "boolean" | "bigint" | "number" | "string" | "array";
124
- tags: IMetadataTypeTag[];
125
- }): boolean => {
126
- let success: boolean = true;
127
- for (const tag of props.tags)
128
- if (tag.target !== props.type) {
129
- success &&= props.report({
130
- property: null,
131
- message: `target must constains ${props.type} type`,
132
- });
133
- }
134
-
135
- props.tags.forEach((tag, i) => {
136
- if (tag.exclusive === false) return;
137
- else if (tag.exclusive === true) {
138
- const some: boolean = props.tags.some(
139
- (opposite, j) => i !== j && opposite.kind === tag.kind,
140
- );
141
- if (some === true)
142
- success &&= props.report({
143
- property: null,
144
- message: `kind '${tag.kind}' can't be duplicated`,
145
- });
146
- } else if (Array.isArray(tag.exclusive)) {
147
- const some: IMetadataTypeTag | undefined = props.tags.find(
148
- (opposite, j) =>
149
- i !== j &&
150
- opposite.kind === tag.kind &&
151
- (tag.exclusive as string[]).includes(opposite.name),
152
- );
153
- if (some !== undefined)
154
- success ??= props.report({
155
- property: null,
156
- message: `kind '${tag.kind}' can't be used with '${some.name}'`,
157
- });
158
- }
159
- });
160
- return success;
161
- };
162
-
163
- const validate_property = (props: {
164
- report: (next: { property: string | null; message: string }) => false;
165
- key: string;
166
- value: Metadata;
167
- }): boolean => {
168
- if (
169
- // TARGET
170
- props.key === "target" &&
171
- (props.value.constants.length !== 1 ||
172
- props.value.constants[0]!.values.length !== props.value.size() ||
173
- props.value.constants[0]!.values.some(
174
- (v) =>
175
- v.value !== "boolean" &&
176
- v.value !== "bigint" &&
177
- v.value !== "number" &&
178
- v.value !== "string" &&
179
- v.value !== "array",
180
- ))
181
- )
182
- return props.report({
183
- property: props.key,
184
- message: `must be one of 'boolean', 'bigint', 'number', 'string', 'array'`,
185
- });
186
- else if (
187
- // KIND
188
- props.key === "kind" &&
189
- (props.value.size() !== 1 ||
190
- props.value.constants.length !== 1 ||
191
- props.value.constants[0]!.type !== "string" ||
192
- props.value.constants[0]!.values.length !== 1)
193
- )
194
- return props.report({
195
- property: props.key,
196
- message: "must be a string literal type",
197
- });
198
- else if (
199
- // VALUE
200
- props.key === "value" &&
201
- (props.value.size() > 1 ||
202
- (props.value.size() !== 0 &&
203
- (props.value.constants.length !== 1 ||
204
- props.value.constants[0]!.values.length !== 1)))
205
- )
206
- return props.report({
207
- property: props.key,
208
- message: "must be a constant literal type or undefined value",
209
- });
210
- else if (props.key === "exclusive") return get_exclusive(props) !== null;
211
- else if (props.key === "validate") {
212
- //----
213
- // VALIDATE
214
- //----
215
- // UNDEFINED CASE
216
- if (
217
- props.value.size() === 0 &&
218
- props.value.isRequired() === false &&
219
- props.value.nullable === false
220
- )
221
- return true;
222
-
223
- // STRING CASE
224
- if (
225
- props.value.size() === 1 &&
226
- props.value.constants.length === 1 &&
227
- props.value.constants[0]!.type === "string" &&
228
- (props.value.constants[0]!.values.length === 1) === true
229
- )
230
- return true;
231
-
232
- // RECORD<TARGET, STRING>
233
- const target: string[] | undefined = props.value.objects[0]?.properties
234
- .map((p) => p.key.getSoleLiteral()!)
235
- .filter((str) => str !== null) as string[] | undefined;
236
- if (target === undefined)
237
- return props.report({
238
- property: "target",
239
- message: `must be one of 'boolean', 'bigint', 'number', 'string', 'array'`,
240
- });
241
- const variadic: boolean =
242
- props.value.size() === 1 &&
243
- props.value.objects.length === 1 &&
244
- props.value.objects[0]!.properties.every(
245
- (vp) =>
246
- vp.value.size() === 1 &&
247
- vp.value.isRequired() &&
248
- vp.value.nullable === false &&
249
- vp.value.constants.length === 1 &&
250
- vp.value.constants[0]!.type === "string" &&
251
- vp.value.constants[0]!.values.length === 1 &&
252
- target.includes(vp.key.getSoleLiteral()!),
253
- );
254
- if (variadic === false)
255
- return props.report({
256
- property: props.key,
257
- message: `must be a string literal type or Record<Target, string> type.`,
258
- });
259
- }
260
- return true;
261
- };
262
-
263
- const create_metadata_type_tag = (props: {
264
- report: (next: { property: string | null; message: string }) => false;
265
- object: MetadataObject;
266
- }): ITypeTag | null => {
267
- const find = (key: string): MetadataProperty | undefined =>
268
- props.object.properties[0]?.value.objects[0]?.properties.find(
269
- (p) => p.key.getSoleLiteral() === key,
270
- );
271
-
272
- const target = find("target")!.value.constants[0]!.values.map(
273
- (v) => v.value,
274
- ) as ITypeTag["target"];
275
- const kind: string = find("kind")!.value.constants[0]!.values[0]!
276
- .value as string;
277
- const value: boolean | bigint | number | string | undefined =
278
- find("value")?.value.constants[0]?.values[0]!.value;
279
- const exclusive: string[] | boolean | null = get_exclusive({
280
- report: props.report,
281
- key: "exclusive",
282
- value: find("exclusive")?.value,
283
- });
284
- if (exclusive === null) return null;
285
-
286
- const validate: Record<string, string> = (() => {
287
- const validate = find("validate")?.value;
288
- if (!validate || validate.size() === 0) return {};
289
- else if (validate.constants.length)
290
- return Object.fromEntries(
291
- target.map((t) => [
292
- t,
293
- validate.constants[0]!.values[0]!.value as string,
294
- ]),
295
- );
296
- return Object.fromEntries(
297
- validate.objects[0]!.properties.map((p) => [
298
- p.key.getSoleLiteral()!,
299
- p.value.constants[0]!.values[0]!.value as string,
300
- ]),
301
- );
302
- })();
303
- const schema: object | undefined = (() => {
304
- const p: Metadata | undefined = find("schema")?.value;
305
- if (p === undefined) return undefined;
306
- else if (p.size() === 0 && p.isRequired() === false) return undefined;
307
- else if (
308
- p.size() === 1 &&
309
- p.nullable === false &&
310
- p.isRequired() === true &&
311
- p.any === false
312
- )
313
- return MetadataTypeTagSchemaFactory.object({
314
- report: (message) =>
315
- props.report({
316
- property: "schema",
317
- message,
318
- }),
319
- object: p.objects[0]!,
320
- });
321
- props.report({
322
- property: "schema",
323
- message: "must be an object type",
324
- });
325
- return undefined;
326
- })();
327
- return {
328
- name: props.object.name,
329
- target,
330
- kind,
331
- value,
332
- validate,
333
- exclusive: exclusive ?? false,
334
- schema,
335
- };
336
- };
337
-
338
- const get_exclusive = (props: {
339
- report: (next: { property: string | null; message: string }) => false;
340
- key: string;
341
- value: Metadata | undefined;
342
- }): boolean | string[] | null => {
343
- if (props.value === undefined) return false;
344
- else if (
345
- props.value.size() === 1 &&
346
- props.value.constants.length === 1 &&
347
- props.value.constants[0]!.type === "boolean" &&
348
- props.value.constants[0]!.values.length === 1
349
- )
350
- return props.value.constants[0]!.values[0]!.value as boolean;
351
- else if (
352
- props.value.size() === 1 &&
353
- props.value.tuples.length === 1 &&
354
- props.value.tuples[0]!.type.elements.every(
355
- (elem) =>
356
- elem.size() === 1 &&
357
- elem.constants.length === 1 &&
358
- elem.constants[0]!.type === "string" &&
359
- elem.constants[0]!.values.length === 1,
360
- )
361
- )
362
- return props.value.tuples[0]!.type.elements.map(
363
- (elem) => elem.constants[0]!.values[0]!.value as string,
364
- );
365
- props.report({
366
- property: props.key,
367
- message:
368
- "must a boolean literal type or a tuple of string literal types.",
369
- });
370
- return null;
371
- };
372
- }
373
-
374
- interface ITypeTag {
375
- name: string;
376
- target: Array<"bigint" | "number" | "string" | "array">;
377
- kind: string;
378
- value?: undefined | boolean | bigint | number | string;
379
- validate: Record<string, string>;
380
- exclusive: boolean | string[];
381
- schema?: undefined | any;
382
- }
383
-
384
- const ESSENTIAL_FIELDS = ["target", "kind", "value"];
385
- const FIELDS = [...ESSENTIAL_FIELDS, "validate", "exclusive"];
1
+ import { IMetadataTypeTag } from "../schemas/metadata/IMetadataTypeTag";
2
+ import { Metadata } from "../schemas/metadata/Metadata";
3
+ import { MetadataObjectType } from "../schemas/metadata/MetadataObjectType";
4
+ import { MetadataProperty } from "../schemas/metadata/MetadataProperty";
5
+
6
+ import { MetadataFactory } from "./MetadataFactory";
7
+ import { MetadataTypeTagSchemaFactory } from "./MetadataTypeTagSchemaFactory";
8
+
9
+ export namespace MetadataTypeTagFactory {
10
+ export const analyze = (props: {
11
+ errors: MetadataFactory.IError[];
12
+ type: "boolean" | "bigint" | "number" | "string" | "array";
13
+ objects: MetadataObjectType[];
14
+ explore: MetadataFactory.IExplore;
15
+ }): IMetadataTypeTag[] => {
16
+ const messages: string[] = [];
17
+ const report = (next: {
18
+ property: string | null;
19
+ message: string;
20
+ }): false => {
21
+ messages.push(
22
+ `the property ${
23
+ next.property === null
24
+ ? `["typia.tag"]`
25
+ : `["typia.tag.${next.property}"]`
26
+ } ${next.message}.`,
27
+ );
28
+ return false;
29
+ };
30
+
31
+ //----
32
+ // VALIDATION PROCESS
33
+ //----
34
+ const filtered: MetadataObjectType[] = props.objects.filter((obj) => {
35
+ // ONLY ONE PROPERTY
36
+ if (obj.properties.length !== 1) return false;
37
+
38
+ // THE TAG.TYPE PROPERTY MUST BE
39
+ const top: MetadataProperty = obj.properties[0]!;
40
+ if (
41
+ top.key.getSoleLiteral() !== "typia.tag" ||
42
+ top.value.size() !== 1 ||
43
+ top.value.objects.length !== 1
44
+ )
45
+ return false;
46
+ else if (top.value.optional === false)
47
+ return report({
48
+ property: null,
49
+ message: "must be optional object",
50
+ });
51
+
52
+ // CHECK LIST OF PROPERTIES
53
+ const tag: MetadataObjectType = top.value.objects[0]!.type;
54
+ const statics: string[] = tag.properties
55
+ .map((p) => p.key.getSoleLiteral()!)
56
+ .filter((str) => str !== null);
57
+ if (ESSENTIAL_FIELDS.some((f) => !statics.includes(f)))
58
+ return report({
59
+ property: null,
60
+ message: `must have at least three properties - ${ESSENTIAL_FIELDS.map(
61
+ (str) => `'${str}'`,
62
+ ).join(", ")}`,
63
+ });
64
+
65
+ const each: boolean[] = tag.properties.map((p) => {
66
+ const key: string | null = p.key.getSoleLiteral();
67
+ if (key === null) return true;
68
+ else if (FIELDS.includes(key) === false) return true;
69
+ return validate_property({
70
+ report,
71
+ key,
72
+ value: p.value,
73
+ });
74
+ });
75
+ return each.every((v) => v === true);
76
+ });
77
+ if (filtered.length === 0) return [];
78
+
79
+ //----
80
+ // CONSTRUCT TYPE TAGS
81
+ //----
82
+ // CREATE 1ST
83
+ const tagList: Array<ITypeTag | null> = filtered.map((object) =>
84
+ create_metadata_type_tag({
85
+ report,
86
+ object,
87
+ }),
88
+ );
89
+
90
+ const output: IMetadataTypeTag[] = [];
91
+ for (const tag of tagList)
92
+ if (tag !== null)
93
+ output.push({
94
+ target: tag.target.some((str) => str === props.type)
95
+ ? props.type
96
+ : null!,
97
+ name: tag.name,
98
+ kind: tag.kind,
99
+ value: tag.value,
100
+ validate: tag.validate[props.type]!,
101
+ exclusive: tag.exclusive,
102
+ schema: tag.schema,
103
+ });
104
+ validate({
105
+ report,
106
+ type: props.type,
107
+ tags: output,
108
+ });
109
+
110
+ if (messages.length > 0) {
111
+ props.errors.push({
112
+ name: [props.type, ...props.objects.map((o) => o.name)].join(" & "),
113
+ explore: props.explore,
114
+ messages,
115
+ });
116
+ return [];
117
+ }
118
+ return output;
119
+ };
120
+
121
+ export const validate = (props: {
122
+ report: (next: { property: string | null; message: string }) => false;
123
+ type: "boolean" | "bigint" | "number" | "string" | "array";
124
+ tags: IMetadataTypeTag[];
125
+ }): boolean => {
126
+ let success: boolean = true;
127
+ for (const tag of props.tags)
128
+ if (tag.target !== props.type) {
129
+ success &&= props.report({
130
+ property: null,
131
+ message: `target must constains ${props.type} type`,
132
+ });
133
+ }
134
+
135
+ props.tags.forEach((tag, i) => {
136
+ if (tag.exclusive === false) return;
137
+ else if (tag.exclusive === true) {
138
+ const some: boolean = props.tags.some(
139
+ (opposite, j) => i !== j && opposite.kind === tag.kind,
140
+ );
141
+ if (some === true)
142
+ success &&= props.report({
143
+ property: null,
144
+ message: `kind '${tag.kind}' can't be duplicated`,
145
+ });
146
+ } else if (Array.isArray(tag.exclusive)) {
147
+ const some: IMetadataTypeTag | undefined = props.tags.find(
148
+ (opposite, j) =>
149
+ i !== j &&
150
+ opposite.kind === tag.kind &&
151
+ (tag.exclusive as string[]).includes(opposite.name),
152
+ );
153
+ if (some !== undefined)
154
+ success ??= props.report({
155
+ property: null,
156
+ message: `kind '${tag.kind}' can't be used with '${some.name}'`,
157
+ });
158
+ }
159
+ });
160
+ return success;
161
+ };
162
+
163
+ const validate_property = (props: {
164
+ report: (next: { property: string | null; message: string }) => false;
165
+ key: string;
166
+ value: Metadata;
167
+ }): boolean => {
168
+ if (
169
+ // TARGET
170
+ props.key === "target" &&
171
+ (props.value.constants.length !== 1 ||
172
+ props.value.constants[0]!.values.length !== props.value.size() ||
173
+ props.value.constants[0]!.values.some(
174
+ (v) =>
175
+ v.value !== "boolean" &&
176
+ v.value !== "bigint" &&
177
+ v.value !== "number" &&
178
+ v.value !== "string" &&
179
+ v.value !== "array",
180
+ ))
181
+ )
182
+ return props.report({
183
+ property: props.key,
184
+ message: `must be one of 'boolean', 'bigint', 'number', 'string', 'array'`,
185
+ });
186
+ else if (
187
+ // KIND
188
+ props.key === "kind" &&
189
+ (props.value.size() !== 1 ||
190
+ props.value.constants.length !== 1 ||
191
+ props.value.constants[0]!.type !== "string" ||
192
+ props.value.constants[0]!.values.length !== 1)
193
+ )
194
+ return props.report({
195
+ property: props.key,
196
+ message: "must be a string literal type",
197
+ });
198
+ else if (
199
+ // VALUE
200
+ props.key === "value" &&
201
+ (props.value.size() > 1 ||
202
+ (props.value.size() !== 0 &&
203
+ (props.value.constants.length !== 1 ||
204
+ props.value.constants[0]!.values.length !== 1)))
205
+ )
206
+ return props.report({
207
+ property: props.key,
208
+ message: "must be a constant literal type or undefined value",
209
+ });
210
+ else if (props.key === "exclusive") return get_exclusive(props) !== null;
211
+ else if (props.key === "validate") {
212
+ //----
213
+ // VALIDATE
214
+ //----
215
+ // UNDEFINED CASE
216
+ if (
217
+ props.value.size() === 0 &&
218
+ props.value.isRequired() === false &&
219
+ props.value.nullable === false
220
+ )
221
+ return true;
222
+
223
+ // STRING CASE
224
+ if (
225
+ props.value.size() === 1 &&
226
+ props.value.constants.length === 1 &&
227
+ props.value.constants[0]!.type === "string" &&
228
+ (props.value.constants[0]!.values.length === 1) === true
229
+ )
230
+ return true;
231
+
232
+ // RECORD<TARGET, STRING>
233
+ const target: string[] | undefined =
234
+ props.value.objects[0]?.type.properties
235
+ .map((p) => p.key.getSoleLiteral()!)
236
+ .filter((str) => str !== null) as string[] | undefined;
237
+ if (target === undefined)
238
+ return props.report({
239
+ property: "target",
240
+ message: `must be one of 'boolean', 'bigint', 'number', 'string', 'array'`,
241
+ });
242
+ const variadic: boolean =
243
+ props.value.size() === 1 &&
244
+ props.value.objects.length === 1 &&
245
+ props.value.objects[0]!.type.properties.every(
246
+ (vp) =>
247
+ vp.value.size() === 1 &&
248
+ vp.value.isRequired() &&
249
+ vp.value.nullable === false &&
250
+ vp.value.constants.length === 1 &&
251
+ vp.value.constants[0]!.type === "string" &&
252
+ vp.value.constants[0]!.values.length === 1 &&
253
+ target.includes(vp.key.getSoleLiteral()!),
254
+ );
255
+ if (variadic === false)
256
+ return props.report({
257
+ property: props.key,
258
+ message: `must be a string literal type or Record<Target, string> type.`,
259
+ });
260
+ }
261
+ return true;
262
+ };
263
+
264
+ const create_metadata_type_tag = (props: {
265
+ report: (next: { property: string | null; message: string }) => false;
266
+ object: MetadataObjectType;
267
+ }): ITypeTag | null => {
268
+ const find = (key: string): MetadataProperty | undefined =>
269
+ props.object.properties[0]?.value.objects[0]?.type.properties.find(
270
+ (p) => p.key.getSoleLiteral() === key,
271
+ );
272
+
273
+ const target = find("target")!.value.constants[0]!.values.map(
274
+ (v) => v.value,
275
+ ) as ITypeTag["target"];
276
+ const kind: string = find("kind")!.value.constants[0]!.values[0]!
277
+ .value as string;
278
+ const value: boolean | bigint | number | string | undefined =
279
+ find("value")?.value.constants[0]?.values[0]!.value;
280
+ const exclusive: string[] | boolean | null = get_exclusive({
281
+ report: props.report,
282
+ key: "exclusive",
283
+ value: find("exclusive")?.value,
284
+ });
285
+ if (exclusive === null) return null;
286
+
287
+ const validate: Record<string, string> = (() => {
288
+ const validate = find("validate")?.value;
289
+ if (!validate || validate.size() === 0) return {};
290
+ else if (validate.constants.length)
291
+ return Object.fromEntries(
292
+ target.map((t) => [
293
+ t,
294
+ validate.constants[0]!.values[0]!.value as string,
295
+ ]),
296
+ );
297
+ return Object.fromEntries(
298
+ validate.objects[0]!.type.properties.map((p) => [
299
+ p.key.getSoleLiteral()!,
300
+ p.value.constants[0]!.values[0]!.value as string,
301
+ ]),
302
+ );
303
+ })();
304
+ const schema: object | undefined = (() => {
305
+ const p: Metadata | undefined = find("schema")?.value;
306
+ if (p === undefined) return undefined;
307
+ else if (p.size() === 0 && p.isRequired() === false) return undefined;
308
+ else if (
309
+ p.size() === 1 &&
310
+ p.nullable === false &&
311
+ p.isRequired() === true &&
312
+ p.any === false
313
+ )
314
+ return MetadataTypeTagSchemaFactory.object({
315
+ report: (message) =>
316
+ props.report({
317
+ property: "schema",
318
+ message,
319
+ }),
320
+ object: p.objects[0]!.type,
321
+ });
322
+ props.report({
323
+ property: "schema",
324
+ message: "must be an object type",
325
+ });
326
+ return undefined;
327
+ })();
328
+ return {
329
+ name: props.object.name,
330
+ target,
331
+ kind,
332
+ value,
333
+ validate,
334
+ exclusive: exclusive ?? false,
335
+ schema,
336
+ };
337
+ };
338
+
339
+ const get_exclusive = (props: {
340
+ report: (next: { property: string | null; message: string }) => false;
341
+ key: string;
342
+ value: Metadata | undefined;
343
+ }): boolean | string[] | null => {
344
+ if (props.value === undefined) return false;
345
+ else if (
346
+ props.value.size() === 1 &&
347
+ props.value.constants.length === 1 &&
348
+ props.value.constants[0]!.type === "boolean" &&
349
+ props.value.constants[0]!.values.length === 1
350
+ )
351
+ return props.value.constants[0]!.values[0]!.value as boolean;
352
+ else if (
353
+ props.value.size() === 1 &&
354
+ props.value.tuples.length === 1 &&
355
+ props.value.tuples[0]!.type.elements.every(
356
+ (elem) =>
357
+ elem.size() === 1 &&
358
+ elem.constants.length === 1 &&
359
+ elem.constants[0]!.type === "string" &&
360
+ elem.constants[0]!.values.length === 1,
361
+ )
362
+ )
363
+ return props.value.tuples[0]!.type.elements.map(
364
+ (elem) => elem.constants[0]!.values[0]!.value as string,
365
+ );
366
+ props.report({
367
+ property: props.key,
368
+ message:
369
+ "must a boolean literal type or a tuple of string literal types.",
370
+ });
371
+ return null;
372
+ };
373
+ }
374
+
375
+ interface ITypeTag {
376
+ name: string;
377
+ target: Array<"bigint" | "number" | "string" | "array">;
378
+ kind: string;
379
+ value?: undefined | boolean | bigint | number | string;
380
+ validate: Record<string, string>;
381
+ exclusive: boolean | string[];
382
+ schema?: undefined | any;
383
+ }
384
+
385
+ const ESSENTIAL_FIELDS = ["target", "kind", "value"];
386
+ const FIELDS = [...ESSENTIAL_FIELDS, "validate", "exclusive"];