typia 4.0.0-dev.20230520 → 4.0.0-dev.20230527

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 (220) hide show
  1. package/lib/transform.js +1 -1
  2. package/lib/transform.js.map +1 -1
  3. package/package.json +1 -1
  4. package/src/CustomValidatorMap.ts +126 -126
  5. package/src/IRandomGenerator.ts +33 -33
  6. package/src/IValidation.ts +21 -21
  7. package/src/Primitive.ts +123 -123
  8. package/src/TypeGuardError.ts +36 -36
  9. package/src/executable/TypiaGenerateWizard.ts +85 -85
  10. package/src/executable/TypiaSetupWizard.ts +133 -133
  11. package/src/executable/setup/ArgumentParser.ts +45 -45
  12. package/src/executable/setup/CommandExecutor.ts +8 -8
  13. package/src/executable/setup/FileRetriever.ts +22 -22
  14. package/src/executable/setup/PackageManager.ts +71 -71
  15. package/src/executable/setup/PluginConfigurator.ts +70 -70
  16. package/src/executable/typia.ts +52 -52
  17. package/src/factories/CommentFactory.ts +14 -14
  18. package/src/factories/ExpressionFactory.ts +77 -77
  19. package/src/factories/IdentifierFactory.ts +62 -62
  20. package/src/factories/LiteralFactory.ts +57 -57
  21. package/src/factories/MetadataCollection.ts +123 -123
  22. package/src/factories/MetadataFactory.ts +53 -53
  23. package/src/factories/MetadataTagFactory.ts +295 -295
  24. package/src/factories/StatementFactory.ts +20 -20
  25. package/src/factories/TemplateFactory.ts +64 -64
  26. package/src/factories/TypeFactory.ts +145 -145
  27. package/src/factories/ValueFactory.ts +15 -15
  28. package/src/factories/internal/metadata/MetadataHelper.ts +12 -12
  29. package/src/factories/internal/metadata/emplace_metadata_object.ts +152 -152
  30. package/src/factories/internal/metadata/explore_metadata.ts +93 -93
  31. package/src/factories/internal/metadata/iterate_metadata.ts +63 -63
  32. package/src/factories/internal/metadata/iterate_metadata_array.ts +32 -32
  33. package/src/factories/internal/metadata/iterate_metadata_atomic.ts +59 -59
  34. package/src/factories/internal/metadata/iterate_metadata_coalesce.ts +33 -33
  35. package/src/factories/internal/metadata/iterate_metadata_constant.ts +62 -62
  36. package/src/factories/internal/metadata/iterate_metadata_map.ts +41 -41
  37. package/src/factories/internal/metadata/iterate_metadata_native.ts +217 -217
  38. package/src/factories/internal/metadata/iterate_metadata_object.ts +51 -51
  39. package/src/factories/internal/metadata/iterate_metadata_resolve.ts +30 -30
  40. package/src/factories/internal/metadata/iterate_metadata_set.ts +36 -36
  41. package/src/factories/internal/metadata/iterate_metadata_template.ts +40 -40
  42. package/src/factories/internal/metadata/iterate_metadata_tuple.ts +51 -51
  43. package/src/factories/internal/metadata/iterate_metadata_union.ts +59 -59
  44. package/src/functional/$any.ts +2 -2
  45. package/src/functional/$dictionary.ts +25 -25
  46. package/src/functional/$every.ts +11 -11
  47. package/src/functional/$guard.ts +35 -35
  48. package/src/functional/$is_between.ts +2 -2
  49. package/src/functional/$is_custom.ts +14 -14
  50. package/src/functional/$is_date.ts +3 -3
  51. package/src/functional/$is_datetime.ts +2 -2
  52. package/src/functional/$is_email.ts +4 -4
  53. package/src/functional/$is_ipv4.ts +4 -4
  54. package/src/functional/$is_ipv6.ts +4 -4
  55. package/src/functional/$is_url.ts +4 -4
  56. package/src/functional/$is_uuid.ts +4 -4
  57. package/src/functional/$join.ts +46 -46
  58. package/src/functional/$number.ts +12 -12
  59. package/src/functional/$report.ts +15 -15
  60. package/src/functional/$rest.ts +3 -3
  61. package/src/functional/$string.ts +37 -37
  62. package/src/functional/$tail.ts +5 -5
  63. package/src/functional/Namespace.ts +127 -127
  64. package/src/index.ts +4 -4
  65. package/src/metadata/ICommentTag.ts +4 -4
  66. package/src/metadata/IJsDocTagInfo.ts +10 -10
  67. package/src/metadata/IMetadata.ts +26 -26
  68. package/src/metadata/IMetadataApplication.ts +7 -7
  69. package/src/metadata/IMetadataConstant.ts +16 -16
  70. package/src/metadata/IMetadataEntry.ts +6 -6
  71. package/src/metadata/IMetadataObject.ts +29 -29
  72. package/src/metadata/IMetadataProperty.ts +11 -11
  73. package/src/metadata/IMetadataTag.ts +105 -105
  74. package/src/metadata/Metadata.ts +539 -539
  75. package/src/metadata/MetadataConstant.ts +3 -3
  76. package/src/metadata/MetadataObject.ts +127 -127
  77. package/src/metadata/MetadataProperty.ts +64 -64
  78. package/src/module.ts +2038 -2038
  79. package/src/programmers/ApplicationProgrammer.ts +48 -48
  80. package/src/programmers/AssertCloneProgrammer.ts +68 -68
  81. package/src/programmers/AssertParseProgrammer.ts +66 -66
  82. package/src/programmers/AssertProgrammer.ts +274 -274
  83. package/src/programmers/AssertPruneProgrammer.ts +73 -73
  84. package/src/programmers/AssertStringifyProgrammer.ts +66 -66
  85. package/src/programmers/CheckerProgrammer.ts +897 -897
  86. package/src/programmers/CloneProgrammer.ts +387 -387
  87. package/src/programmers/FeatureProgrammer.ts +510 -510
  88. package/src/programmers/IsCloneProgrammer.ts +79 -79
  89. package/src/programmers/IsParseProgrammer.ts +72 -72
  90. package/src/programmers/IsProgrammer.ts +223 -223
  91. package/src/programmers/IsPruneProgrammer.ts +83 -83
  92. package/src/programmers/IsStringifyProgrammer.ts +77 -77
  93. package/src/programmers/LiteralsProgrammer.ts +65 -65
  94. package/src/programmers/PruneProgrammer.ts +348 -348
  95. package/src/programmers/RandomProgrammer.ts +444 -444
  96. package/src/programmers/StringifyProgrammer.ts +758 -758
  97. package/src/programmers/TypiaProgrammer.ts +141 -141
  98. package/src/programmers/ValidateCloneProgrammer.ts +93 -93
  99. package/src/programmers/ValidateParseProgrammer.ts +78 -78
  100. package/src/programmers/ValidateProgrammer.ts +317 -317
  101. package/src/programmers/ValidatePruneProgrammer.ts +86 -86
  102. package/src/programmers/ValidateStringifyProgrammer.ts +93 -93
  103. package/src/programmers/helpers/AtomicPredicator.ts +31 -31
  104. package/src/programmers/helpers/CloneJoiner.ts +138 -138
  105. package/src/programmers/helpers/FunctionImporeter.ts +56 -56
  106. package/src/programmers/helpers/ICheckEntry.ts +12 -12
  107. package/src/programmers/helpers/IExpressionEntry.ts +12 -12
  108. package/src/programmers/helpers/OptionPredicator.ts +15 -15
  109. package/src/programmers/helpers/PruneJoiner.ts +156 -156
  110. package/src/programmers/helpers/RandomJoiner.ts +165 -165
  111. package/src/programmers/helpers/RandomRanger.ts +218 -218
  112. package/src/programmers/helpers/StringifyJoinder.ts +118 -118
  113. package/src/programmers/helpers/StringifyPredicator.ts +12 -12
  114. package/src/programmers/helpers/UnionExplorer.ts +281 -281
  115. package/src/programmers/helpers/UnionPredicator.ts +81 -81
  116. package/src/programmers/helpers/disable_function_importer_declare.ts +21 -21
  117. package/src/programmers/internal/JSON_SCHEMA_PREFIX.ts +1 -1
  118. package/src/programmers/internal/application_array.ts +32 -32
  119. package/src/programmers/internal/application_boolean.ts +15 -15
  120. package/src/programmers/internal/application_constant.ts +26 -26
  121. package/src/programmers/internal/application_default.ts +17 -17
  122. package/src/programmers/internal/application_default_string.ts +33 -33
  123. package/src/programmers/internal/application_native.ts +36 -36
  124. package/src/programmers/internal/application_number.ts +71 -71
  125. package/src/programmers/internal/application_object.ts +162 -162
  126. package/src/programmers/internal/application_schema.ts +198 -198
  127. package/src/programmers/internal/application_string.ts +44 -44
  128. package/src/programmers/internal/application_templates.ts +25 -25
  129. package/src/programmers/internal/application_tuple.ts +27 -27
  130. package/src/programmers/internal/check_array.ts +31 -31
  131. package/src/programmers/internal/check_array_length.ts +35 -35
  132. package/src/programmers/internal/check_bigint.ts +95 -95
  133. package/src/programmers/internal/check_custom.ts +32 -32
  134. package/src/programmers/internal/check_dynamic_properties.ts +198 -198
  135. package/src/programmers/internal/check_everything.ts +28 -28
  136. package/src/programmers/internal/check_native.ts +22 -22
  137. package/src/programmers/internal/check_number.ts +177 -177
  138. package/src/programmers/internal/check_object.ts +65 -65
  139. package/src/programmers/internal/check_string.ts +27 -27
  140. package/src/programmers/internal/check_string_tags.ts +68 -68
  141. package/src/programmers/internal/check_template.ts +57 -57
  142. package/src/programmers/internal/check_union_array_like.ts +273 -273
  143. package/src/programmers/internal/check_union_tuple.ts +34 -34
  144. package/src/programmers/internal/decode_union_object.ts +75 -75
  145. package/src/programmers/internal/feature_object_entries.ts +64 -64
  146. package/src/programmers/internal/get_comment_tags.ts +23 -23
  147. package/src/programmers/internal/metadata_to_pattern.ts +34 -34
  148. package/src/programmers/internal/prune_object_properties.ts +63 -63
  149. package/src/programmers/internal/random_custom.ts +30 -30
  150. package/src/programmers/internal/stringify_dynamic_properties.ts +173 -173
  151. package/src/programmers/internal/stringify_native.ts +7 -7
  152. package/src/programmers/internal/stringify_regular_properties.ts +89 -89
  153. package/src/programmers/internal/template_to_pattern.ts +15 -15
  154. package/src/schemas/IJsonApplication.ts +13 -13
  155. package/src/schemas/IJsonComponents.ts +33 -33
  156. package/src/schemas/IJsonSchema.ts +134 -134
  157. package/src/transform.ts +39 -39
  158. package/src/transformers/CallExpressionTransformer.ts +183 -183
  159. package/src/transformers/FileTransformer.ts +50 -50
  160. package/src/transformers/IProject.ts +18 -18
  161. package/src/transformers/ITransformOptions.ts +62 -62
  162. package/src/transformers/ImportTransformer.ts +74 -74
  163. package/src/transformers/NodeTransformer.ts +13 -13
  164. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +107 -107
  165. package/src/transformers/features/miscellaneous/AssertCloneTransformer.ts +9 -9
  166. package/src/transformers/features/miscellaneous/AssertPruneTransformer.ts +9 -9
  167. package/src/transformers/features/miscellaneous/CloneTransformer.ts +9 -9
  168. package/src/transformers/features/miscellaneous/CreateAssertCloneTransformer.ts +9 -9
  169. package/src/transformers/features/miscellaneous/CreateAssertPruneTransformer.ts +9 -9
  170. package/src/transformers/features/miscellaneous/CreateCloneTransformer.ts +9 -9
  171. package/src/transformers/features/miscellaneous/CreateIsCloneTransformer.ts +9 -9
  172. package/src/transformers/features/miscellaneous/CreateIsPruneTransformer.ts +9 -9
  173. package/src/transformers/features/miscellaneous/CreatePruneTransformer.ts +9 -9
  174. package/src/transformers/features/miscellaneous/CreateRandomTransformer.ts +43 -43
  175. package/src/transformers/features/miscellaneous/CreateValidateCloneTransformer.ts +9 -9
  176. package/src/transformers/features/miscellaneous/CreateValidatePruneTransformer.ts +9 -9
  177. package/src/transformers/features/miscellaneous/IsCloneTransformer.ts +9 -9
  178. package/src/transformers/features/miscellaneous/IsPruneTransformer.ts +9 -9
  179. package/src/transformers/features/miscellaneous/LiteralsTransformer.ts +31 -31
  180. package/src/transformers/features/miscellaneous/MetadataTransformer.ts +56 -56
  181. package/src/transformers/features/miscellaneous/PruneTransformer.ts +9 -9
  182. package/src/transformers/features/miscellaneous/RandomTransformer.ts +46 -46
  183. package/src/transformers/features/miscellaneous/ValidateCloneTransformer.ts +9 -9
  184. package/src/transformers/features/miscellaneous/ValidatePruneTransformer.ts +9 -9
  185. package/src/transformers/features/parsers/AssertParseTransformer.ts +9 -9
  186. package/src/transformers/features/parsers/CreateAssertParseTransformer.ts +9 -9
  187. package/src/transformers/features/parsers/CreateIsParseTransformer.ts +9 -9
  188. package/src/transformers/features/parsers/CreateValidateParseTransformer.ts +9 -9
  189. package/src/transformers/features/parsers/IsParseTransformer.ts +9 -9
  190. package/src/transformers/features/parsers/ValidateParseTransformer.ts +9 -9
  191. package/src/transformers/features/stringifiers/AssertStringifyTransformer.ts +10 -10
  192. package/src/transformers/features/stringifiers/CreateAssertStringifyTransformer.ts +12 -12
  193. package/src/transformers/features/stringifiers/CreateIsStringifyTransformer.ts +9 -9
  194. package/src/transformers/features/stringifiers/CreateStringifyTransformer.ts +9 -9
  195. package/src/transformers/features/stringifiers/CreateValidateStringifyProgrammer.ts +12 -12
  196. package/src/transformers/features/stringifiers/IsStringifyTransformer.ts +9 -9
  197. package/src/transformers/features/stringifiers/StringifyTransformer.ts +9 -9
  198. package/src/transformers/features/stringifiers/ValidateStringifyTransformer.ts +10 -10
  199. package/src/transformers/features/validators/AssertTransformer.ts +11 -11
  200. package/src/transformers/features/validators/CreateAssertTransformer.ts +13 -13
  201. package/src/transformers/features/validators/CreateIsTransformer.ts +11 -11
  202. package/src/transformers/features/validators/CreateValidateTransformer.ts +13 -13
  203. package/src/transformers/features/validators/IsTransformer.ts +11 -11
  204. package/src/transformers/features/validators/ValidateTransformer.ts +11 -11
  205. package/src/transformers/internal/GenericTransformer.ts +101 -101
  206. package/src/typings/Atomic.ts +17 -17
  207. package/src/typings/ClassProperties.ts +5 -5
  208. package/src/typings/Customizable.ts +5 -5
  209. package/src/typings/OmitNever.ts +3 -3
  210. package/src/typings/SpecialFields.ts +3 -3
  211. package/src/typings/Writable.ts +11 -11
  212. package/src/utils/ArrayUtil.ts +44 -44
  213. package/src/utils/Escaper.ts +45 -45
  214. package/src/utils/MapUtil.ts +12 -12
  215. package/src/utils/PatternUtil.ts +30 -30
  216. package/src/utils/RandomGenerator.ts +81 -81
  217. package/src/utils/Singleton.ts +17 -17
  218. package/src/utils/TsNodeUtil.ts +17 -17
  219. package/src/utils/TsSymbolUtil.ts +153 -153
  220. package/src/utils/TsTypeUtil.ts +38 -38
@@ -1,295 +1,295 @@
1
- import { JSDocTagInfo } from "typescript";
2
-
3
- import { IMetadataTag } from "../metadata/IMetadataTag";
4
- import { Metadata } from "../metadata/Metadata";
5
-
6
- export namespace MetadataTagFactory {
7
- export const generate =
8
- (metadata: Metadata) =>
9
- (tagList: JSDocTagInfo[]) =>
10
- (identifier: () => string): IMetadataTag[] => {
11
- const output: IMetadataTag[] = [];
12
- for (const tag of tagList) {
13
- const elem: IMetadataTag | null = parse(
14
- identifier,
15
- metadata,
16
- tag,
17
- output,
18
- );
19
- if (elem !== null) output.push(elem);
20
- }
21
- return output;
22
- };
23
-
24
- const parse = (
25
- identifier: () => string,
26
- metadata: Metadata,
27
- tag: JSDocTagInfo,
28
- output: IMetadataTag[],
29
- ): IMetadataTag | null => {
30
- const closure = _PARSER[tag.name];
31
- if (closure === undefined) return null;
32
-
33
- const text: string | undefined = tag.text?.[0]?.text;
34
- if (text === undefined)
35
- throw new Error(`${LABEL}: no tag value on ${identifier()}`);
36
-
37
- return closure(identifier, metadata, text, output);
38
- };
39
-
40
- /**
41
- * @internal
42
- */
43
- export const _PARSER: Record<
44
- string,
45
- (
46
- identifier: () => string,
47
- metadata: Metadata,
48
- text: string,
49
- output: IMetadataTag[],
50
- ) => IMetadataTag | null
51
- > = {
52
- /* -----------------------------------------------------------
53
- ARRAY
54
- ----------------------------------------------------------- */
55
- items: (identifier, metadata, text, output) => {
56
- validate(identifier, metadata, output, "items", "array", [
57
- "minItems",
58
- ]);
59
- return {
60
- kind: "items",
61
- value: parse_number(identifier, text),
62
- };
63
- },
64
- minItems: (identifier, metadata, text, output) => {
65
- validate(identifier, metadata, output, "minItems", "array", [
66
- "items",
67
- ]);
68
- return {
69
- kind: "minItems",
70
- value: parse_number(identifier, text),
71
- };
72
- },
73
- maxItems: (identifier, metadata, text, output) => {
74
- validate(identifier, metadata, output, "maxItems", "array", [
75
- "items",
76
- ]);
77
- return {
78
- kind: "maxItems",
79
- value: parse_number(identifier, text),
80
- };
81
- },
82
-
83
- /* -----------------------------------------------------------
84
- NUMBER
85
- ----------------------------------------------------------- */
86
- type: (_identifier, metadata, text, _output) => {
87
- return has_atomic(metadata)("number") &&
88
- (text === "int" || text === "uint")
89
- ? { kind: "type", value: text }
90
- : null;
91
- },
92
- minimum: (identifier, metadata, text, output) => {
93
- validate(identifier, metadata, output, "minimum", "number", [
94
- "exclusiveMinimum",
95
- ]);
96
- return {
97
- kind: "minimum",
98
- value: parse_number(identifier, text),
99
- };
100
- },
101
- maximum: (identifier, metadata, text, output) => {
102
- validate(identifier, metadata, output, "maximum", "number", [
103
- "exclusiveMaximum",
104
- ]);
105
- return {
106
- kind: "maximum",
107
- value: parse_number(identifier, text),
108
- };
109
- },
110
- exclusiveMinimum: (identifier, metadata, text, output) => {
111
- validate(
112
- identifier,
113
- metadata,
114
- output,
115
- "exclusiveMinimum",
116
- "number",
117
- ["minimum"],
118
- );
119
- return {
120
- kind: "exclusiveMinimum",
121
- value: parse_number(identifier, text),
122
- };
123
- },
124
- exclusiveMaximum: (identifier, metadata, text, output) => {
125
- validate(
126
- identifier,
127
- metadata,
128
- output,
129
- "exclusiveMaximum",
130
- "number",
131
- ["maximum"],
132
- );
133
- return {
134
- kind: "exclusiveMaximum",
135
- value: parse_number(identifier, text),
136
- };
137
- },
138
- multipleOf: (identifier, metadata, text, output) => {
139
- validate(identifier, metadata, output, "multipleOf", "number", [
140
- "step",
141
- ]);
142
- return {
143
- kind: "multipleOf",
144
- value: parse_number(identifier, text),
145
- };
146
- },
147
- step: (identifier, metadata, text, output) => {
148
- validate(identifier, metadata, output, "step", "number", [
149
- "multipleOf",
150
- ]);
151
-
152
- const minimum: boolean = output.some(
153
- (tag) =>
154
- tag.kind === "minimum" || tag.kind === "exclusiveMinimum",
155
- );
156
- if (minimum === undefined)
157
- throw new Error(
158
- `${LABEL}: step requires minimum or exclusiveMinimum tag on "${identifier()}".`,
159
- );
160
-
161
- return {
162
- kind: "step",
163
- value: parse_number(identifier, text),
164
- };
165
- },
166
-
167
- /* -----------------------------------------------------------
168
- STRING
169
- ----------------------------------------------------------- */
170
- format: (identifier, metadata, str, output) => {
171
- validate(identifier, metadata, output, "format", "string", [
172
- "pattern",
173
- ]);
174
-
175
- // Ignore arbitrary @format values in the internal metadata,
176
- // these are currently only supported on the typia.application() API.
177
- const value: IMetadataTag.IFormat["value"] | undefined =
178
- FORMATS.get(str);
179
- if (value === undefined) return null;
180
- return {
181
- kind: "format",
182
- value,
183
- };
184
- },
185
- pattern: (identifier, metadata, value, output) => {
186
- validate(identifier, metadata, output, "pattern", "string", [
187
- "format",
188
- ]);
189
- return {
190
- kind: "pattern",
191
- value,
192
- };
193
- },
194
- length: (identifier, metadata, text, output) => {
195
- validate(identifier, metadata, output, "length", "string", [
196
- "minLength",
197
- "maxLength",
198
- ]);
199
- return {
200
- kind: "length",
201
- value: parse_number(identifier, text),
202
- };
203
- },
204
- minLength: (identifier, metadata, text, output) => {
205
- validate(identifier, metadata, output, "minLength", "string", [
206
- "length",
207
- ]);
208
- return {
209
- kind: "minLength",
210
- value: parse_number(identifier, text),
211
- };
212
- },
213
- maxLength: (identifier, metadata, text, output) => {
214
- validate(identifier, metadata, output, "maxLength", "string", [
215
- "length",
216
- ]);
217
- return {
218
- kind: "maxLength",
219
- value: parse_number(identifier, text),
220
- };
221
- },
222
- };
223
- }
224
-
225
- const parse_number = (identifier: () => string, str: string): number => {
226
- const value: number = Number(str);
227
- if (isNaN(value) === true)
228
- throw new Error(`${LABEL}: invalid number on "${identifier()}".`);
229
- return value;
230
- };
231
-
232
- const LABEL = "Error on typia.MetadataTagFactory.generate()";
233
- const FORMATS: Map<string, IMetadataTag.IFormat["value"]> = new Map([
234
- ["uuid", "uuid"],
235
- ["email", "email"],
236
- ["url", "url"],
237
- ["ipv4", "ipv4"],
238
- ["ipv6", "ipv6"],
239
- ["date", "date"],
240
- ["datetime", "datetime"],
241
- ["date-time", "datetime"],
242
- ["dateTime", "datetime"],
243
- ]);
244
-
245
- const WRONG_TYPE = (
246
- tag: string,
247
- type: "string" | "number" | "array",
248
- identifier: () => string,
249
- ) => `${LABEL}: ${tag} requires ${type} type, but no "${identifier()}".`;
250
-
251
- const validate = (
252
- identifier: () => string,
253
- metadata: Metadata,
254
- output: IMetadataTag[],
255
- kind: IMetadataTag["kind"],
256
- type: "array" | "string" | "number",
257
- neighbors: IMetadataTag["kind"][],
258
- ): void => {
259
- // TYPE CHECKING
260
- if (type === "array") {
261
- if (has_array(metadata) === false)
262
- throw new Error(WRONG_TYPE(kind, "array", identifier));
263
- } else if (has_atomic(metadata)(type) === false)
264
- throw new Error(WRONG_TYPE(kind, type, identifier));
265
-
266
- // DUPLICATED TAG
267
- if (output.some((tag) => tag.kind === kind))
268
- throw new Error(
269
- `${LABEL}: duplicated ${kind} tags on "${identifier()}".`,
270
- );
271
-
272
- // NEIGHBOR TAG
273
- for (const name of neighbors)
274
- if (output.some((tag) => tag.kind === name))
275
- throw new Error(
276
- `${LABEL}: ${kind} and ${name} tags on "${identifier()}".`,
277
- );
278
- };
279
-
280
- const has_atomic =
281
- (metadata: Metadata) =>
282
- (type: "string" | "number"): boolean =>
283
- metadata.atomics.find(
284
- type === "number"
285
- ? (atom: string) => atom === type || atom === "bigint"
286
- : (atom: string) => atom === type,
287
- ) !== undefined ||
288
- metadata.arrays.some((child) => has_atomic(child)(type)) ||
289
- metadata.tuples.some((tuple) =>
290
- tuple.some((child) => has_atomic(child)(type)),
291
- );
292
-
293
- const has_array = (metadata: Metadata): boolean =>
294
- metadata.arrays.length !== 0 ||
295
- metadata.tuples.some((tuple) => tuple.some((child) => has_array(child)));
1
+ import { JSDocTagInfo } from "typescript";
2
+
3
+ import { IMetadataTag } from "../metadata/IMetadataTag";
4
+ import { Metadata } from "../metadata/Metadata";
5
+
6
+ export namespace MetadataTagFactory {
7
+ export const generate =
8
+ (metadata: Metadata) =>
9
+ (tagList: JSDocTagInfo[]) =>
10
+ (identifier: () => string): IMetadataTag[] => {
11
+ const output: IMetadataTag[] = [];
12
+ for (const tag of tagList) {
13
+ const elem: IMetadataTag | null = parse(
14
+ identifier,
15
+ metadata,
16
+ tag,
17
+ output,
18
+ );
19
+ if (elem !== null) output.push(elem);
20
+ }
21
+ return output;
22
+ };
23
+
24
+ const parse = (
25
+ identifier: () => string,
26
+ metadata: Metadata,
27
+ tag: JSDocTagInfo,
28
+ output: IMetadataTag[],
29
+ ): IMetadataTag | null => {
30
+ const closure = _PARSER[tag.name];
31
+ if (closure === undefined) return null;
32
+
33
+ const text: string | undefined = tag.text?.[0]?.text;
34
+ if (text === undefined)
35
+ throw new Error(`${LABEL}: no tag value on ${identifier()}`);
36
+
37
+ return closure(identifier, metadata, text, output);
38
+ };
39
+
40
+ /**
41
+ * @internal
42
+ */
43
+ export const _PARSER: Record<
44
+ string,
45
+ (
46
+ identifier: () => string,
47
+ metadata: Metadata,
48
+ text: string,
49
+ output: IMetadataTag[],
50
+ ) => IMetadataTag | null
51
+ > = {
52
+ /* -----------------------------------------------------------
53
+ ARRAY
54
+ ----------------------------------------------------------- */
55
+ items: (identifier, metadata, text, output) => {
56
+ validate(identifier, metadata, output, "items", "array", [
57
+ "minItems",
58
+ ]);
59
+ return {
60
+ kind: "items",
61
+ value: parse_number(identifier, text),
62
+ };
63
+ },
64
+ minItems: (identifier, metadata, text, output) => {
65
+ validate(identifier, metadata, output, "minItems", "array", [
66
+ "items",
67
+ ]);
68
+ return {
69
+ kind: "minItems",
70
+ value: parse_number(identifier, text),
71
+ };
72
+ },
73
+ maxItems: (identifier, metadata, text, output) => {
74
+ validate(identifier, metadata, output, "maxItems", "array", [
75
+ "items",
76
+ ]);
77
+ return {
78
+ kind: "maxItems",
79
+ value: parse_number(identifier, text),
80
+ };
81
+ },
82
+
83
+ /* -----------------------------------------------------------
84
+ NUMBER
85
+ ----------------------------------------------------------- */
86
+ type: (_identifier, metadata, text, _output) => {
87
+ return has_atomic(metadata)("number") &&
88
+ (text === "int" || text === "uint")
89
+ ? { kind: "type", value: text }
90
+ : null;
91
+ },
92
+ minimum: (identifier, metadata, text, output) => {
93
+ validate(identifier, metadata, output, "minimum", "number", [
94
+ "exclusiveMinimum",
95
+ ]);
96
+ return {
97
+ kind: "minimum",
98
+ value: parse_number(identifier, text),
99
+ };
100
+ },
101
+ maximum: (identifier, metadata, text, output) => {
102
+ validate(identifier, metadata, output, "maximum", "number", [
103
+ "exclusiveMaximum",
104
+ ]);
105
+ return {
106
+ kind: "maximum",
107
+ value: parse_number(identifier, text),
108
+ };
109
+ },
110
+ exclusiveMinimum: (identifier, metadata, text, output) => {
111
+ validate(
112
+ identifier,
113
+ metadata,
114
+ output,
115
+ "exclusiveMinimum",
116
+ "number",
117
+ ["minimum"],
118
+ );
119
+ return {
120
+ kind: "exclusiveMinimum",
121
+ value: parse_number(identifier, text),
122
+ };
123
+ },
124
+ exclusiveMaximum: (identifier, metadata, text, output) => {
125
+ validate(
126
+ identifier,
127
+ metadata,
128
+ output,
129
+ "exclusiveMaximum",
130
+ "number",
131
+ ["maximum"],
132
+ );
133
+ return {
134
+ kind: "exclusiveMaximum",
135
+ value: parse_number(identifier, text),
136
+ };
137
+ },
138
+ multipleOf: (identifier, metadata, text, output) => {
139
+ validate(identifier, metadata, output, "multipleOf", "number", [
140
+ "step",
141
+ ]);
142
+ return {
143
+ kind: "multipleOf",
144
+ value: parse_number(identifier, text),
145
+ };
146
+ },
147
+ step: (identifier, metadata, text, output) => {
148
+ validate(identifier, metadata, output, "step", "number", [
149
+ "multipleOf",
150
+ ]);
151
+
152
+ const minimum: boolean = output.some(
153
+ (tag) =>
154
+ tag.kind === "minimum" || tag.kind === "exclusiveMinimum",
155
+ );
156
+ if (minimum === undefined)
157
+ throw new Error(
158
+ `${LABEL}: step requires minimum or exclusiveMinimum tag on "${identifier()}".`,
159
+ );
160
+
161
+ return {
162
+ kind: "step",
163
+ value: parse_number(identifier, text),
164
+ };
165
+ },
166
+
167
+ /* -----------------------------------------------------------
168
+ STRING
169
+ ----------------------------------------------------------- */
170
+ format: (identifier, metadata, str, output) => {
171
+ validate(identifier, metadata, output, "format", "string", [
172
+ "pattern",
173
+ ]);
174
+
175
+ // Ignore arbitrary @format values in the internal metadata,
176
+ // these are currently only supported on the typia.application() API.
177
+ const value: IMetadataTag.IFormat["value"] | undefined =
178
+ FORMATS.get(str);
179
+ if (value === undefined) return null;
180
+ return {
181
+ kind: "format",
182
+ value,
183
+ };
184
+ },
185
+ pattern: (identifier, metadata, value, output) => {
186
+ validate(identifier, metadata, output, "pattern", "string", [
187
+ "format",
188
+ ]);
189
+ return {
190
+ kind: "pattern",
191
+ value,
192
+ };
193
+ },
194
+ length: (identifier, metadata, text, output) => {
195
+ validate(identifier, metadata, output, "length", "string", [
196
+ "minLength",
197
+ "maxLength",
198
+ ]);
199
+ return {
200
+ kind: "length",
201
+ value: parse_number(identifier, text),
202
+ };
203
+ },
204
+ minLength: (identifier, metadata, text, output) => {
205
+ validate(identifier, metadata, output, "minLength", "string", [
206
+ "length",
207
+ ]);
208
+ return {
209
+ kind: "minLength",
210
+ value: parse_number(identifier, text),
211
+ };
212
+ },
213
+ maxLength: (identifier, metadata, text, output) => {
214
+ validate(identifier, metadata, output, "maxLength", "string", [
215
+ "length",
216
+ ]);
217
+ return {
218
+ kind: "maxLength",
219
+ value: parse_number(identifier, text),
220
+ };
221
+ },
222
+ };
223
+ }
224
+
225
+ const parse_number = (identifier: () => string, str: string): number => {
226
+ const value: number = Number(str);
227
+ if (isNaN(value) === true)
228
+ throw new Error(`${LABEL}: invalid number on "${identifier()}".`);
229
+ return value;
230
+ };
231
+
232
+ const LABEL = "Error on typia.MetadataTagFactory.generate()";
233
+ const FORMATS: Map<string, IMetadataTag.IFormat["value"]> = new Map([
234
+ ["uuid", "uuid"],
235
+ ["email", "email"],
236
+ ["url", "url"],
237
+ ["ipv4", "ipv4"],
238
+ ["ipv6", "ipv6"],
239
+ ["date", "date"],
240
+ ["datetime", "datetime"],
241
+ ["date-time", "datetime"],
242
+ ["dateTime", "datetime"],
243
+ ]);
244
+
245
+ const WRONG_TYPE = (
246
+ tag: string,
247
+ type: "string" | "number" | "array",
248
+ identifier: () => string,
249
+ ) => `${LABEL}: ${tag} requires ${type} type, but no "${identifier()}".`;
250
+
251
+ const validate = (
252
+ identifier: () => string,
253
+ metadata: Metadata,
254
+ output: IMetadataTag[],
255
+ kind: IMetadataTag["kind"],
256
+ type: "array" | "string" | "number",
257
+ neighbors: IMetadataTag["kind"][],
258
+ ): void => {
259
+ // TYPE CHECKING
260
+ if (type === "array") {
261
+ if (has_array(metadata) === false)
262
+ throw new Error(WRONG_TYPE(kind, "array", identifier));
263
+ } else if (has_atomic(metadata)(type) === false)
264
+ throw new Error(WRONG_TYPE(kind, type, identifier));
265
+
266
+ // DUPLICATED TAG
267
+ if (output.some((tag) => tag.kind === kind))
268
+ throw new Error(
269
+ `${LABEL}: duplicated ${kind} tags on "${identifier()}".`,
270
+ );
271
+
272
+ // NEIGHBOR TAG
273
+ for (const name of neighbors)
274
+ if (output.some((tag) => tag.kind === name))
275
+ throw new Error(
276
+ `${LABEL}: ${kind} and ${name} tags on "${identifier()}".`,
277
+ );
278
+ };
279
+
280
+ const has_atomic =
281
+ (metadata: Metadata) =>
282
+ (type: "string" | "number"): boolean =>
283
+ metadata.atomics.find(
284
+ type === "number"
285
+ ? (atom: string) => atom === type || atom === "bigint"
286
+ : (atom: string) => atom === type,
287
+ ) !== undefined ||
288
+ metadata.arrays.some((child) => has_atomic(child)(type)) ||
289
+ metadata.tuples.some((tuple) =>
290
+ tuple.some((child) => has_atomic(child)(type)),
291
+ );
292
+
293
+ const has_array = (metadata: Metadata): boolean =>
294
+ metadata.arrays.length !== 0 ||
295
+ metadata.tuples.some((tuple) => tuple.some((child) => has_array(child)));
@@ -1,20 +1,20 @@
1
- import type ts from "typescript/lib/tsclibrary";
2
-
3
- export namespace StatementFactory {
4
- export const constant =
5
- (tsc: typeof ts) => (name: string, initializer?: ts.Expression) =>
6
- tsc.factory.createVariableStatement(
7
- undefined,
8
- tsc.factory.createVariableDeclarationList(
9
- [
10
- tsc.factory.createVariableDeclaration(
11
- name,
12
- undefined,
13
- undefined,
14
- initializer,
15
- ),
16
- ],
17
- tsc.NodeFlags.Const,
18
- ),
19
- );
20
- }
1
+ import type ts from "typescript/lib/tsclibrary";
2
+
3
+ export namespace StatementFactory {
4
+ export const constant =
5
+ (tsc: typeof ts) => (name: string, initializer?: ts.Expression) =>
6
+ tsc.factory.createVariableStatement(
7
+ undefined,
8
+ tsc.factory.createVariableDeclarationList(
9
+ [
10
+ tsc.factory.createVariableDeclaration(
11
+ name,
12
+ undefined,
13
+ undefined,
14
+ initializer,
15
+ ),
16
+ ],
17
+ tsc.NodeFlags.Const,
18
+ ),
19
+ );
20
+ }