typia 3.4.13 → 3.4.15

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 (270) hide show
  1. package/README.md +9 -8
  2. package/lib/executable/internal/TypiaSetupWizard.js +1 -1
  3. package/lib/executable/internal/TypiaSetupWizard.js.map +1 -1
  4. package/lib/factories/MetadataFactory.d.ts +1 -0
  5. package/lib/factories/MetadataFactory.js +1 -1
  6. package/lib/factories/MetadataFactory.js.map +1 -1
  7. package/lib/factories/MetadataTagFactory.js +4 -1
  8. package/lib/factories/MetadataTagFactory.js.map +1 -1
  9. package/lib/factories/internal/{MetadataHelper.d.ts → metadata/MetadataHelper.d.ts} +1 -1
  10. package/lib/factories/internal/{MetadataHelper.js → metadata/MetadataHelper.js} +1 -1
  11. package/lib/factories/internal/metadata/MetadataHelper.js.map +1 -0
  12. package/lib/factories/internal/{emplace_metadata_object.d.ts → metadata/emplace_metadata_object.d.ts} +3 -3
  13. package/lib/factories/internal/{emplace_metadata_object.js → metadata/emplace_metadata_object.js} +5 -5
  14. package/lib/factories/internal/metadata/emplace_metadata_object.js.map +1 -0
  15. package/lib/factories/internal/{explore_metadata.d.ts → metadata/explore_metadata.d.ts} +3 -3
  16. package/lib/factories/internal/{explore_metadata.js → metadata/explore_metadata.js} +5 -3
  17. package/lib/factories/internal/metadata/explore_metadata.js.map +1 -0
  18. package/lib/factories/internal/{iterate_metadata.d.ts → metadata/iterate_metadata.d.ts} +3 -3
  19. package/lib/factories/internal/{iterate_metadata.js → metadata/iterate_metadata.js} +1 -1
  20. package/lib/factories/internal/metadata/iterate_metadata.js.map +1 -0
  21. package/lib/factories/internal/{iterate_metadata_array.d.ts → metadata/iterate_metadata_array.d.ts} +3 -3
  22. package/lib/factories/internal/{iterate_metadata_array.js → metadata/iterate_metadata_array.js} +1 -1
  23. package/lib/factories/internal/metadata/iterate_metadata_array.js.map +1 -0
  24. package/lib/factories/internal/{iterate_metadata_atomic.d.ts → metadata/iterate_metadata_atomic.d.ts} +1 -1
  25. package/lib/factories/internal/{iterate_metadata_atomic.js → metadata/iterate_metadata_atomic.js} +1 -1
  26. package/lib/factories/internal/metadata/iterate_metadata_atomic.js.map +1 -0
  27. package/lib/factories/internal/{iterate_metadata_coalesce.d.ts → metadata/iterate_metadata_coalesce.d.ts} +1 -1
  28. package/lib/factories/internal/{iterate_metadata_coalesce.js → metadata/iterate_metadata_coalesce.js} +2 -2
  29. package/lib/factories/internal/metadata/iterate_metadata_coalesce.js.map +1 -0
  30. package/lib/factories/internal/{iterate_metadata_constant.d.ts → metadata/iterate_metadata_constant.d.ts} +2 -2
  31. package/lib/factories/internal/{iterate_metadata_constant.js → metadata/iterate_metadata_constant.js} +1 -1
  32. package/lib/factories/internal/metadata/iterate_metadata_constant.js.map +1 -0
  33. package/lib/factories/internal/{iterate_metadata_map.d.ts → metadata/iterate_metadata_map.d.ts} +3 -3
  34. package/lib/factories/internal/{iterate_metadata_map.js → metadata/iterate_metadata_map.js} +2 -2
  35. package/lib/factories/internal/metadata/iterate_metadata_map.js.map +1 -0
  36. package/lib/factories/internal/{iterate_metadata_native.d.ts → metadata/iterate_metadata_native.d.ts} +1 -1
  37. package/lib/factories/internal/{iterate_metadata_native.js → metadata/iterate_metadata_native.js} +2 -2
  38. package/lib/factories/internal/metadata/iterate_metadata_native.js.map +1 -0
  39. package/lib/factories/internal/{iterate_metadata_object.d.ts → metadata/iterate_metadata_object.d.ts} +3 -3
  40. package/lib/factories/internal/{iterate_metadata_object.js → metadata/iterate_metadata_object.js} +7 -5
  41. package/lib/factories/internal/metadata/iterate_metadata_object.js.map +1 -0
  42. package/lib/factories/internal/{iterate_metadata_resolve.d.ts → metadata/iterate_metadata_resolve.d.ts} +3 -3
  43. package/lib/factories/internal/{iterate_metadata_resolve.js → metadata/iterate_metadata_resolve.js} +2 -2
  44. package/lib/factories/internal/metadata/iterate_metadata_resolve.js.map +1 -0
  45. package/lib/factories/internal/{iterate_metadata_set.d.ts → metadata/iterate_metadata_set.d.ts} +3 -3
  46. package/lib/factories/internal/{iterate_metadata_set.js → metadata/iterate_metadata_set.js} +2 -2
  47. package/lib/factories/internal/metadata/iterate_metadata_set.js.map +1 -0
  48. package/lib/factories/internal/{iterate_metadata_template.d.ts → metadata/iterate_metadata_template.d.ts} +3 -3
  49. package/lib/factories/internal/{iterate_metadata_template.js → metadata/iterate_metadata_template.js} +0 -0
  50. package/lib/factories/internal/metadata/iterate_metadata_template.js.map +1 -0
  51. package/lib/factories/internal/{iterate_metadata_tuple.d.ts → metadata/iterate_metadata_tuple.d.ts} +3 -3
  52. package/lib/factories/internal/{iterate_metadata_tuple.js → metadata/iterate_metadata_tuple.js} +3 -3
  53. package/lib/factories/internal/metadata/iterate_metadata_tuple.js.map +1 -0
  54. package/lib/factories/internal/{iterate_metadata_union.d.ts → metadata/iterate_metadata_union.d.ts} +3 -3
  55. package/lib/factories/internal/{iterate_metadata_union.js → metadata/iterate_metadata_union.js} +3 -3
  56. package/lib/factories/internal/metadata/iterate_metadata_union.js.map +1 -0
  57. package/lib/functional/$number.js +2 -9
  58. package/lib/functional/$number.js.map +1 -1
  59. package/lib/programmers/AssertParseProgrammer.js +12 -1
  60. package/lib/programmers/AssertParseProgrammer.js.map +1 -1
  61. package/lib/programmers/AssertProgrammer.js +2 -1
  62. package/lib/programmers/AssertProgrammer.js.map +1 -1
  63. package/lib/programmers/AssertStringifyProgrammer.js +13 -2
  64. package/lib/programmers/AssertStringifyProgrammer.js.map +1 -1
  65. package/lib/programmers/CheckerProgrammer.js +6 -0
  66. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  67. package/lib/programmers/IsParseProgrammer.js +12 -1
  68. package/lib/programmers/IsParseProgrammer.js.map +1 -1
  69. package/lib/programmers/IsProgrammer.js +5 -2
  70. package/lib/programmers/IsProgrammer.js.map +1 -1
  71. package/lib/programmers/IsStringifyProgrammer.js +13 -2
  72. package/lib/programmers/IsStringifyProgrammer.js.map +1 -1
  73. package/lib/programmers/StringifyProgrammer.js +5 -0
  74. package/lib/programmers/StringifyProgrammer.js.map +1 -1
  75. package/lib/programmers/ValidateParseProgrammer.js +12 -1
  76. package/lib/programmers/ValidateParseProgrammer.js.map +1 -1
  77. package/lib/programmers/ValidateProgrammer.js +2 -1
  78. package/lib/programmers/ValidateProgrammer.js.map +1 -1
  79. package/lib/programmers/ValidateStringifyProgrammer.js +13 -2
  80. package/lib/programmers/ValidateStringifyProgrammer.js.map +1 -1
  81. package/lib/programmers/helpers/OptionPredicator.d.ts +2 -1
  82. package/lib/programmers/helpers/OptionPredicator.js +7 -3
  83. package/lib/programmers/helpers/OptionPredicator.js.map +1 -1
  84. package/lib/programmers/internal/application_schema.js +7 -3
  85. package/lib/programmers/internal/application_schema.js.map +1 -1
  86. package/lib/programmers/internal/check_bigint.d.ts +3 -0
  87. package/lib/programmers/internal/check_bigint.js +97 -0
  88. package/lib/programmers/internal/check_bigint.js.map +1 -0
  89. package/lib/programmers/internal/check_number.js +21 -22
  90. package/lib/programmers/internal/check_number.js.map +1 -1
  91. package/lib/schemas/IJsonSchema.d.ts +3 -5
  92. package/lib/transformers/ITransformOptions.d.ts +42 -1
  93. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js +4 -0
  94. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js.map +1 -1
  95. package/lib/transformers/features/stringifiers/StringifyTransformer.js +12 -1
  96. package/lib/transformers/features/stringifiers/StringifyTransformer.js.map +1 -1
  97. package/package.json +3 -2
  98. package/src/IValidation.ts +21 -21
  99. package/src/Primitive.ts +82 -82
  100. package/src/TypeGuardError.ts +36 -36
  101. package/src/executable/internal/CommandParser.ts +15 -15
  102. package/src/executable/internal/TypiaSetupWizard.ts +173 -175
  103. package/src/executable/typia.ts +46 -46
  104. package/src/factories/CommentFactory.ts +10 -10
  105. package/src/factories/ExpressionFactory.ts +66 -66
  106. package/src/factories/IdentifierFactory.ts +72 -72
  107. package/src/factories/LiteralFactory.ts +44 -44
  108. package/src/factories/MetadataCollection.ts +122 -122
  109. package/src/factories/MetadataFactory.ts +47 -46
  110. package/src/factories/MetadataTagFactory.ts +351 -347
  111. package/src/factories/StatementFactory.ts +60 -60
  112. package/src/factories/TemplateFactory.ts +56 -56
  113. package/src/factories/TypeFactory.ts +101 -101
  114. package/src/factories/ValueFactory.ts +12 -12
  115. package/src/factories/internal/{MetadataHelper.ts → metadata/MetadataHelper.ts} +12 -12
  116. package/src/factories/internal/{emplace_metadata_object.ts → metadata/emplace_metadata_object.ts} +140 -140
  117. package/src/factories/internal/{explore_metadata.ts → metadata/explore_metadata.ts} +92 -91
  118. package/src/factories/internal/{iterate_metadata.ts → metadata/iterate_metadata.ts} +80 -80
  119. package/src/factories/internal/{iterate_metadata_array.ts → metadata/iterate_metadata_array.ts} +29 -29
  120. package/src/factories/internal/{iterate_metadata_atomic.ts → metadata/iterate_metadata_atomic.ts} +59 -59
  121. package/src/factories/internal/{iterate_metadata_coalesce.ts → metadata/iterate_metadata_coalesce.ts} +33 -33
  122. package/src/factories/internal/{iterate_metadata_constant.ts → metadata/iterate_metadata_constant.ts} +58 -58
  123. package/src/factories/internal/{iterate_metadata_map.ts → metadata/iterate_metadata_map.ts} +41 -41
  124. package/src/factories/internal/{iterate_metadata_native.ts → metadata/iterate_metadata_native.ts} +227 -227
  125. package/src/factories/internal/{iterate_metadata_object.ts → metadata/iterate_metadata_object.ts} +48 -45
  126. package/src/factories/internal/{iterate_metadata_resolve.ts → metadata/iterate_metadata_resolve.ts} +27 -27
  127. package/src/factories/internal/{iterate_metadata_set.ts → metadata/iterate_metadata_set.ts} +33 -33
  128. package/src/factories/internal/{iterate_metadata_template.ts → metadata/iterate_metadata_template.ts} +38 -38
  129. package/src/factories/internal/{iterate_metadata_tuple.ts → metadata/iterate_metadata_tuple.ts} +45 -45
  130. package/src/factories/internal/{iterate_metadata_union.ts → metadata/iterate_metadata_union.ts} +59 -59
  131. package/src/functional/$every.ts +11 -11
  132. package/src/functional/$guard.ts +35 -35
  133. package/src/functional/$is_email.ts +5 -5
  134. package/src/functional/$is_ipv4.ts +5 -5
  135. package/src/functional/$is_ipv6.ts +5 -5
  136. package/src/functional/$is_url.ts +5 -5
  137. package/src/functional/$is_uuid.ts +5 -5
  138. package/src/functional/$join.ts +50 -50
  139. package/src/functional/$number.ts +12 -19
  140. package/src/functional/$report.ts +15 -15
  141. package/src/functional/$rest.ts +3 -3
  142. package/src/functional/$string.ts +37 -37
  143. package/src/functional/$tail.ts +6 -6
  144. package/src/index.ts +4 -4
  145. package/src/metadata/IJsDocTagInfo.ts +10 -10
  146. package/src/metadata/IMetadata.ts +25 -25
  147. package/src/metadata/IMetadataApplication.ts +7 -7
  148. package/src/metadata/IMetadataConstant.ts +16 -16
  149. package/src/metadata/IMetadataEntry.ts +6 -6
  150. package/src/metadata/IMetadataObject.ts +29 -29
  151. package/src/metadata/IMetadataProperty.ts +11 -11
  152. package/src/metadata/IMetadataTag.ts +122 -122
  153. package/src/metadata/Metadata.ts +477 -477
  154. package/src/metadata/MetadataConstant.ts +3 -3
  155. package/src/metadata/MetadataObject.ts +131 -131
  156. package/src/metadata/MetadataProperty.ts +64 -64
  157. package/src/module.ts +1535 -1535
  158. package/src/programmers/ApplicationProgrammer.ts +55 -55
  159. package/src/programmers/AssertParseProgrammer.ts +55 -45
  160. package/src/programmers/AssertProgrammer.ts +445 -444
  161. package/src/programmers/AssertStringifyProgrammer.ts +65 -45
  162. package/src/programmers/CheckerProgrammer.ts +810 -804
  163. package/src/programmers/FeatureProgrammer.ts +327 -327
  164. package/src/programmers/IsParseProgrammer.ts +61 -51
  165. package/src/programmers/IsProgrammer.ts +175 -172
  166. package/src/programmers/IsStringifyProgrammer.ts +69 -49
  167. package/src/programmers/StringifyProgrammer.ts +762 -756
  168. package/src/programmers/ValidateParseProgrammer.ts +59 -49
  169. package/src/programmers/ValidateProgrammer.ts +237 -236
  170. package/src/programmers/ValidateStringifyProgrammer.ts +80 -60
  171. package/src/programmers/helpers/AtomicPredicator.ts +15 -15
  172. package/src/programmers/helpers/FunctionImporeter.ts +31 -31
  173. package/src/programmers/helpers/IExpressionEntry.ts +10 -10
  174. package/src/programmers/helpers/OptionPredicator.ts +15 -11
  175. package/src/programmers/helpers/StringifyJoinder.ts +111 -111
  176. package/src/programmers/helpers/StringifyPredicator.ts +18 -18
  177. package/src/programmers/helpers/UnionExplorer.ts +437 -437
  178. package/src/programmers/helpers/UnionPredicator.ts +81 -81
  179. package/src/programmers/internal/application_array.ts +45 -45
  180. package/src/programmers/internal/application_boolean.ts +17 -17
  181. package/src/programmers/internal/application_constant.ts +29 -29
  182. package/src/programmers/internal/application_default.ts +17 -17
  183. package/src/programmers/internal/application_default_string.ts +32 -32
  184. package/src/programmers/internal/application_native.ts +29 -29
  185. package/src/programmers/internal/application_number.ts +76 -76
  186. package/src/programmers/internal/application_object.ts +103 -103
  187. package/src/programmers/internal/application_schema.ts +228 -221
  188. package/src/programmers/internal/application_string.ts +49 -49
  189. package/src/programmers/internal/application_templates.ts +27 -27
  190. package/src/programmers/internal/application_tuple.ts +25 -25
  191. package/src/programmers/internal/check_array.ts +44 -44
  192. package/src/programmers/internal/check_bigint.ts +85 -0
  193. package/src/programmers/internal/check_dynamic_properties.ts +146 -146
  194. package/src/programmers/internal/check_everything.ts +25 -25
  195. package/src/programmers/internal/check_length.ts +46 -46
  196. package/src/programmers/internal/check_native.ts +9 -9
  197. package/src/programmers/internal/check_number.ts +175 -178
  198. package/src/programmers/internal/check_object.ts +42 -42
  199. package/src/programmers/internal/check_string.ts +24 -24
  200. package/src/programmers/internal/check_string_tags.ts +63 -63
  201. package/src/programmers/internal/check_template.ts +50 -50
  202. package/src/programmers/internal/decode_union_object.ts +73 -73
  203. package/src/programmers/internal/feature_object_entries.ts +49 -49
  204. package/src/programmers/internal/metadata_to_pattern.ts +31 -31
  205. package/src/programmers/internal/stringify_dynamic_properties.ts +164 -164
  206. package/src/programmers/internal/stringify_native.ts +8 -8
  207. package/src/programmers/internal/stringify_regular_properties.ts +81 -81
  208. package/src/programmers/internal/template_to_pattern.ts +15 -15
  209. package/src/schemas/IJsonApplication.ts +9 -9
  210. package/src/schemas/IJsonComponents.ts +24 -24
  211. package/src/schemas/IJsonSchema.ts +90 -92
  212. package/src/transform.ts +20 -20
  213. package/src/transformers/CallExpressionTransformer.ts +124 -124
  214. package/src/transformers/ExpressionWithArgumentTransformer.ts +66 -66
  215. package/src/transformers/FileTransformer.ts +49 -49
  216. package/src/transformers/IProject.ts +11 -11
  217. package/src/transformers/ITransformOptions.ts +47 -4
  218. package/src/transformers/NodeTransformer.ts +19 -19
  219. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +119 -114
  220. package/src/transformers/features/miscellaneous/MetadataTransformer.ts +55 -55
  221. package/src/transformers/features/parsers/AssertParseTransformer.ts +36 -36
  222. package/src/transformers/features/parsers/CreateAssertParseTransformer.ts +32 -32
  223. package/src/transformers/features/parsers/CreateIsParseTransformer.ts +32 -32
  224. package/src/transformers/features/parsers/CreateValidateParseTransformer.ts +32 -32
  225. package/src/transformers/features/parsers/IsParseTransformer.ts +36 -36
  226. package/src/transformers/features/parsers/ValidateParseTransformer.ts +36 -36
  227. package/src/transformers/features/stringifiers/AssertStringifyTransformer.ts +38 -38
  228. package/src/transformers/features/stringifiers/CreateAssertStringifyTransformer.ts +32 -32
  229. package/src/transformers/features/stringifiers/CreateIsStringifyTransformer.ts +32 -32
  230. package/src/transformers/features/stringifiers/CreateStringifyTransformer.ts +31 -31
  231. package/src/transformers/features/stringifiers/CreateValidateStringifyProgrammer.ts +32 -32
  232. package/src/transformers/features/stringifiers/IsStringifyTransformer.ts +38 -38
  233. package/src/transformers/features/stringifiers/StringifyTransformer.ts +46 -36
  234. package/src/transformers/features/stringifiers/ValidateStringifyTransformer.ts +38 -38
  235. package/src/transformers/features/validators/AssertTransformer.ts +43 -43
  236. package/src/transformers/features/validators/CreateAssertTransformer.ts +35 -35
  237. package/src/transformers/features/validators/CreateIsTransformer.ts +35 -35
  238. package/src/transformers/features/validators/CreateValidateTransformer.ts +35 -35
  239. package/src/transformers/features/validators/IsTransformer.ts +43 -43
  240. package/src/transformers/features/validators/ValidateTransformer.ts +43 -43
  241. package/src/typings/Atomic.ts +17 -17
  242. package/src/typings/ClassProperties.ts +5 -5
  243. package/src/typings/OmitNever.ts +3 -3
  244. package/src/typings/SpecialFields.ts +3 -3
  245. package/src/typings/Writable.ts +11 -11
  246. package/src/utils/ArrayUtil.ts +49 -49
  247. package/src/utils/Escaper.ts +50 -50
  248. package/src/utils/MapUtil.ts +14 -14
  249. package/src/utils/PatternUtil.ts +30 -30
  250. package/src/utils/Singleton.ts +17 -17
  251. package/lib/factories/internal/MetadataHelper.js.map +0 -1
  252. package/lib/factories/internal/emplace_metadata_object.js.map +0 -1
  253. package/lib/factories/internal/explore_metadata.js.map +0 -1
  254. package/lib/factories/internal/iterate_metadata.js.map +0 -1
  255. package/lib/factories/internal/iterate_metadata_array.js.map +0 -1
  256. package/lib/factories/internal/iterate_metadata_atomic.js.map +0 -1
  257. package/lib/factories/internal/iterate_metadata_coalesce.js.map +0 -1
  258. package/lib/factories/internal/iterate_metadata_constant.js.map +0 -1
  259. package/lib/factories/internal/iterate_metadata_map.js.map +0 -1
  260. package/lib/factories/internal/iterate_metadata_native.js.map +0 -1
  261. package/lib/factories/internal/iterate_metadata_object.js.map +0 -1
  262. package/lib/factories/internal/iterate_metadata_resolve.js.map +0 -1
  263. package/lib/factories/internal/iterate_metadata_set.js.map +0 -1
  264. package/lib/factories/internal/iterate_metadata_template.js.map +0 -1
  265. package/lib/factories/internal/iterate_metadata_tuple.js.map +0 -1
  266. package/lib/factories/internal/iterate_metadata_union.js.map +0 -1
  267. package/lib/transformers/features/miscellaneous/CreateInstanceTransformer.d.ts +0 -5
  268. package/lib/transformers/features/miscellaneous/CreateInstanceTransformer.js +0 -29
  269. package/lib/transformers/features/miscellaneous/CreateInstanceTransformer.js.map +0 -1
  270. package/src/transformers/features/miscellaneous/CreateInstanceTransformer.ts +0 -41
@@ -1,804 +1,810 @@
1
- import ts from "typescript";
2
-
3
- import { ExpressionFactory } from "../factories/ExpressionFactory";
4
- import { IdentifierFactory } from "../factories/IdentifierFactory";
5
- import { MetadataCollection } from "../factories/MetadataCollection";
6
- import { MetadataFactory } from "../factories/MetadataFactory";
7
- import { ValueFactory } from "../factories/ValueFactory";
8
-
9
- import { IMetadataTag } from "../metadata/IMetadataTag";
10
- import { Metadata } from "../metadata/Metadata";
11
- import { MetadataObject } from "../metadata/MetadataObject";
12
-
13
- import { IProject } from "../transformers/IProject";
14
-
15
- import { FeatureProgrammer } from "./FeatureProgrammer";
16
- import { FunctionImporter } from "./helpers/FunctionImporeter";
17
- import { IExpressionEntry } from "./helpers/IExpressionEntry";
18
- import { OptionPredicator } from "./helpers/OptionPredicator";
19
- import { UnionExplorer } from "./helpers/UnionExplorer";
20
- import { check_array } from "./internal/check_array";
21
- import { check_native } from "./internal/check_native";
22
- import { check_number } from "./internal/check_number";
23
- import { check_string } from "./internal/check_string";
24
- import { check_template } from "./internal/check_template";
25
- import { decode_union_object } from "./internal/decode_union_object";
26
-
27
- export namespace CheckerProgrammer {
28
- export interface IConfig {
29
- functors: string;
30
- unioners: string;
31
- path: boolean;
32
- trace: boolean;
33
- equals: boolean;
34
- numeric: boolean;
35
- combiner: IConfig.Combiner;
36
- decoder?: FeatureProgrammer.Decoder<Metadata>;
37
- joiner: IConfig.IJoiner;
38
- success: ts.Expression;
39
- }
40
- export namespace IConfig {
41
- export interface Combiner {
42
- (explorer: IExplore): {
43
- (logic: "and" | "or"): {
44
- (
45
- input: ts.Expression,
46
- binaries: IBinary[],
47
- expected: string,
48
- ): ts.Expression;
49
- };
50
- };
51
- }
52
- export interface IJoiner {
53
- object(entries: IExpressionEntry[]): ts.Expression;
54
- array(input: ts.Expression, arrow: ts.ArrowFunction): ts.Expression;
55
- tuple?(exprs: ts.Expression[]): ts.Expression;
56
-
57
- failure(
58
- value: ts.Expression,
59
- expected: string,
60
- explore?: FeatureProgrammer.IExplore,
61
- ): ts.Expression;
62
- is?(expression: ts.Expression): ts.Expression;
63
- required?(exp: ts.Expression): ts.Expression;
64
- full?: (
65
- condition: ts.Expression,
66
- ) => (
67
- input: ts.Expression,
68
- expected: string,
69
- explore: IExplore,
70
- ) => ts.Expression;
71
- }
72
- }
73
- export import IExplore = FeatureProgrammer.IExplore;
74
-
75
- export interface IBinary {
76
- expression: ts.Expression;
77
- combined: boolean;
78
- }
79
-
80
- /* -----------------------------------------------------------
81
- GENERATORS
82
- ----------------------------------------------------------- */
83
- export function generate(
84
- project: IProject,
85
- config: IConfig,
86
- importer: FunctionImporter,
87
- addition?: () => ts.Statement[],
88
- ) {
89
- return FeatureProgrammer.generate(
90
- project,
91
- CONFIG(project, config, importer),
92
- importer,
93
- () => (addition ? (addition ? addition() : []) : undefined),
94
- );
95
- }
96
-
97
- export const generate_functors = (
98
- project: IProject,
99
- config: IConfig,
100
- importer: FunctionImporter,
101
- ) =>
102
- FeatureProgrammer.generate_functors(
103
- CONFIG(project, config, importer),
104
- importer,
105
- );
106
-
107
- export const generate_unioners = (
108
- project: IProject,
109
- config: IConfig,
110
- importer: FunctionImporter,
111
- ) =>
112
- FeatureProgrammer.generate_unioners(
113
- CONFIG(project, { ...config, numeric: false }, importer),
114
- );
115
-
116
- function CONFIG(
117
- project: IProject,
118
- config: IConfig,
119
- importer: FunctionImporter,
120
- ): FeatureProgrammer.IConfig {
121
- const output: FeatureProgrammer.IConfig = {
122
- trace: config.trace,
123
- path: config.path,
124
- functors: config.functors,
125
- unioners: config.unioners,
126
- initializer: ({ checker }, type) => {
127
- const collection: MetadataCollection = new MetadataCollection();
128
- const meta: Metadata = MetadataFactory.generate(
129
- checker,
130
- collection,
131
- type,
132
- {
133
- resolve: false,
134
- constant: true,
135
- },
136
- );
137
- return [collection, meta];
138
- },
139
- decoder: config.decoder || decode(project, config, importer),
140
- objector: {
141
- checker: config.decoder || decode(project, config, importer),
142
- decoder: decode_object(config),
143
- joiner: config.joiner.object,
144
- unionizer: config.equals
145
- ? decode_union_object(decode_object(config))(
146
- (input, obj, explore) =>
147
- decode_object(config)(input, obj, {
148
- ...explore,
149
- tracable: true,
150
- }),
151
- )(config.joiner.is || ((expr) => expr))(
152
- (value, expected) =>
153
- ts.factory.createReturnStatement(
154
- config.joiner.failure(value, expected),
155
- ),
156
- )
157
- : (input, targets, explore) =>
158
- config.combiner(explore)("or")(
159
- input,
160
- targets.map((obj) => ({
161
- expression: decode_object(config)(
162
- input,
163
- obj,
164
- explore,
165
- ),
166
- combined: true,
167
- })),
168
- `(${targets.map((t) => t.name).join(" | ")})`,
169
- ),
170
- failure: (value, expected) =>
171
- ts.factory.createReturnStatement(
172
- config.joiner.failure(value, expected),
173
- ),
174
- is: config.joiner.is,
175
- required: config.joiner.required,
176
- full: config.joiner.full,
177
- },
178
- };
179
- if (config.numeric === true)
180
- output.generator = {
181
- unioners: FeatureProgrammer.generate_unioners(
182
- CONFIG(project, { ...config, numeric: false }, importer),
183
- ),
184
- };
185
- return output;
186
- }
187
-
188
- /* -----------------------------------------------------------
189
- DECODERS
190
- ----------------------------------------------------------- */
191
- export function decode(
192
- project: IProject,
193
- config: IConfig,
194
- importer: FunctionImporter,
195
- ): (
196
- input: ts.Expression,
197
- meta: Metadata,
198
- explore: IExplore,
199
- tags: IMetadataTag[],
200
- ) => ts.Expression;
201
-
202
- /**
203
- * @internal
204
- */
205
- export function decode(
206
- project: IProject,
207
- config: IConfig,
208
- importer: FunctionImporter,
209
- checkTupleLength: boolean,
210
- ): (
211
- input: ts.Expression,
212
- meta: Metadata,
213
- explore: IExplore,
214
- tags: IMetadataTag[],
215
- ) => ts.Expression;
216
-
217
- /**
218
- * @internal
219
- */
220
- export function decode(
221
- project: IProject,
222
- config: IConfig,
223
- importer: FunctionImporter,
224
- checkTupleLength: boolean = true,
225
- ) {
226
- return function (
227
- input: ts.Expression,
228
- meta: Metadata,
229
- explore: IExplore,
230
- tags: IMetadataTag[],
231
- ): ts.Expression {
232
- if (meta.any) return config.success;
233
-
234
- const top: IBinary[] = [];
235
- const binaries: IBinary[] = [];
236
- const add = create_add(binaries)(input);
237
- const getConstantValue = (
238
- value: number | string | bigint | boolean,
239
- ) =>
240
- typeof value === "string"
241
- ? ts.factory.createStringLiteral(value)
242
- : ts.factory.createIdentifier(value.toString());
243
-
244
- //----
245
- // CHECK OPTIONAL
246
- //----
247
- const checkOptional: boolean = meta.empty() || meta.isUnionBucket();
248
-
249
- // NULLABLE
250
- if (
251
- checkOptional ||
252
- meta.nullable
253
- // || (meta.objects.length && meta.size() !== meta.objects.length)
254
- )
255
- (meta.nullable ? add : create_add(top)(input))(
256
- meta.nullable,
257
- ValueFactory.NULL(),
258
- );
259
-
260
- // UNDEFINDABLE
261
- if (checkOptional || !meta.required)
262
- (meta.required ? create_add(top)(input) : add)(
263
- !meta.required,
264
- ValueFactory.UNDEFINED(),
265
- );
266
-
267
- // FUNCTIONAL
268
- if (meta.functional === true)
269
- if (
270
- OptionPredicator.functional(project.options) ||
271
- meta.size() !== 1
272
- )
273
- add(
274
- true,
275
- ts.factory.createStringLiteral("function"),
276
- ValueFactory.TYPEOF(input),
277
- );
278
- else
279
- binaries.push({
280
- combined: false,
281
- expression: config.success,
282
- });
283
-
284
- //----
285
- // VALUES
286
- //----
287
- // CONSTANT VALUES
288
- for (const constant of meta.constants)
289
- for (const val of constant.values)
290
- add(true, getConstantValue(val));
291
-
292
- // ATOMIC VALUES
293
- for (const type of meta.atomics)
294
- if (type === "number")
295
- binaries.push({
296
- expression: check_number(project, config.numeric)(
297
- input,
298
- tags,
299
- ),
300
- combined: false,
301
- });
302
- else if (type === "string")
303
- binaries.push({
304
- expression: check_string(importer)(input, tags),
305
- combined: false,
306
- });
307
- else
308
- add(
309
- true,
310
- ts.factory.createStringLiteral(type),
311
- ValueFactory.TYPEOF(input),
312
- );
313
-
314
- // TEMPLATE LITERAL VALUES
315
- if (meta.templates.length)
316
- binaries.push({
317
- expression: check_template(importer)(
318
- input,
319
- meta.templates,
320
- tags,
321
- ),
322
- combined: false,
323
- });
324
-
325
- //----
326
- // INSTANCES
327
- //----
328
- // TUPLE
329
- if (meta.tuples.length > 0) {
330
- const inner: ts.Expression[] = [];
331
- for (const tuple of meta.tuples)
332
- inner.push(
333
- decode_tuple(
334
- project,
335
- config,
336
- importer,
337
- checkTupleLength,
338
- )(input, tuple, explore, tags),
339
- );
340
-
341
- // ADD
342
- binaries.push({
343
- expression: config.combiner(explore)("and")(
344
- input,
345
- [
346
- ...(checkTupleLength
347
- ? [
348
- {
349
- expression:
350
- ExpressionFactory.isArray(input),
351
- combined: false,
352
- },
353
- ]
354
- : []),
355
- ...inner.map((expression) => ({
356
- expression,
357
- combined: true,
358
- })),
359
- ],
360
- meta.getName(),
361
- ),
362
- combined: true,
363
- });
364
- }
365
-
366
- // ARRAY
367
- if (meta.arrays.length > 0)
368
- if (meta.arrays.every((elem) => elem.any))
369
- binaries.push({
370
- expression: check_array(input, tags),
371
- combined: false,
372
- });
373
- else
374
- binaries.push({
375
- expression: config.combiner(explore)("and")(
376
- input,
377
- [
378
- ...(checkTupleLength
379
- ? [
380
- {
381
- expression: check_array(
382
- input,
383
- tags,
384
- ),
385
- combined: false,
386
- },
387
- ]
388
- : []),
389
- {
390
- expression: explore_array(
391
- project,
392
- config,
393
- importer,
394
- )(
395
- input,
396
- meta.arrays,
397
- {
398
- ...explore,
399
- from: "array",
400
- },
401
- tags,
402
- ),
403
- combined: true,
404
- },
405
- ],
406
- meta.getName(),
407
- ),
408
- combined: true,
409
- });
410
-
411
- // OBJECT
412
- if (meta.objects.length > 0)
413
- binaries.push({
414
- expression: config.combiner(explore)("and")(
415
- input,
416
- [
417
- {
418
- expression: ExpressionFactory.isObject(input, {
419
- checkNull: true,
420
- checkArray: meta.objects.some((obj) =>
421
- obj.properties.every(
422
- (prop) =>
423
- !prop.key.isSoleLiteral() ||
424
- !prop.value.required,
425
- ),
426
- ),
427
- }),
428
- combined: false,
429
- },
430
- {
431
- expression: explore_objects(config)(
432
- input,
433
- meta,
434
- {
435
- ...explore,
436
- from: "object",
437
- },
438
- ),
439
- combined: true,
440
- },
441
- ],
442
- meta.getName(),
443
- ),
444
- combined: true,
445
- });
446
-
447
- // NATIVE CLASSES
448
- for (const native of meta.natives)
449
- binaries.push({
450
- expression: check_native(native)(input),
451
- combined: false,
452
- });
453
-
454
- // SETS
455
- if (meta.sets.length)
456
- if (meta.sets.every((elem) => elem.any))
457
- binaries.push({
458
- combined: false,
459
- expression: check_native("Set")(input),
460
- });
461
- else
462
- binaries.push({
463
- combined: true,
464
- expression: config.combiner(explore)("and")(
465
- input,
466
- [
467
- {
468
- combined: false,
469
- expression: check_native("Set")(input),
470
- },
471
- {
472
- combined: true,
473
- expression: explore_set(
474
- project,
475
- config,
476
- importer,
477
- )(
478
- input,
479
- meta.sets,
480
- {
481
- ...explore,
482
- from: "array",
483
- },
484
- [],
485
- ),
486
- },
487
- ],
488
- meta.getName(),
489
- ),
490
- });
491
-
492
- // MAPS
493
- if (meta.maps.length)
494
- if (meta.maps.every((elem) => elem.key.any && elem.value.any))
495
- binaries.push({
496
- expression: check_native("Map")(input),
497
- combined: false,
498
- });
499
- else
500
- binaries.push({
501
- combined: true,
502
- expression: config.combiner(explore)("and")(
503
- input,
504
- [
505
- {
506
- combined: false,
507
- expression: check_native("Map")(input),
508
- },
509
- {
510
- combined: true,
511
- expression: explore_map(
512
- project,
513
- config,
514
- importer,
515
- )(
516
- input,
517
- meta.maps.map((m) => [m.key, m.value]),
518
- {
519
- ...explore,
520
- from: "array",
521
- },
522
- [],
523
- ),
524
- },
525
- ],
526
- meta.getName(),
527
- ),
528
- });
529
-
530
- // COMBINE CONDITIONS
531
- return top.length && binaries.length
532
- ? config.combiner(explore)("and")(
533
- input,
534
- [
535
- ...top,
536
- {
537
- expression: config.combiner(explore)("or")(
538
- input,
539
- binaries,
540
- meta.getName(),
541
- ),
542
- combined: true,
543
- },
544
- ],
545
- meta.getName(),
546
- )
547
- : binaries.length
548
- ? config.combiner(explore)("or")(
549
- input,
550
- binaries,
551
- meta.getName(),
552
- )
553
- : config.success;
554
- };
555
- }
556
-
557
- function decode_tuple(
558
- project: IProject,
559
- config: IConfig,
560
- importer: FunctionImporter,
561
- checkLength: boolean,
562
- ) {
563
- return function (
564
- input: ts.Expression,
565
- tuple: Array<Metadata>,
566
- explore: IExplore,
567
- tagList: IMetadataTag[],
568
- ): ts.Expression {
569
- const binaries: ts.Expression[] = tuple
570
- .filter((meta) => meta.rest === null)
571
- .map((meta, index) =>
572
- decode(project, config, importer)(
573
- ts.factory.createElementAccessExpression(input, index),
574
- meta,
575
- {
576
- ...explore,
577
- from: "array",
578
- postfix: explore.postfix.length
579
- ? `${explore.postfix.slice(0, -1)}[${index}]"`
580
- : `[${index}]`,
581
- },
582
- tagList,
583
- ),
584
- );
585
- const rest: ts.Expression | null =
586
- tuple.length && tuple[tuple.length - 1]!.rest !== null
587
- ? decode(project, config, importer, false)(
588
- ts.factory.createCallExpression(
589
- IdentifierFactory.join(input, "slice"),
590
- undefined,
591
- [
592
- ts.factory.createNumericLiteral(
593
- tuple.length - 1,
594
- ),
595
- ],
596
- ),
597
- (() => {
598
- const wrapper: Metadata = Metadata.initialize();
599
- wrapper.arrays.push(
600
- tuple[tuple.length - 1]!.rest!,
601
- );
602
- return wrapper;
603
- })(),
604
- {
605
- ...explore,
606
- start: tuple.length - 1,
607
- },
608
- tagList,
609
- )
610
- : null;
611
-
612
- return config.combiner(explore)("and")(
613
- input,
614
- [
615
- ...(checkLength && rest === null
616
- ? [
617
- {
618
- combined: false,
619
- expression: ts.factory.createStrictEquality(
620
- ts.factory.createPropertyAccessExpression(
621
- input,
622
- "length",
623
- ),
624
- ts.factory.createNumericLiteral(
625
- tuple.length,
626
- ),
627
- ),
628
- },
629
- ]
630
- : []),
631
- ...(config.joiner.tuple
632
- ? [
633
- {
634
- expression: config.joiner.tuple(binaries),
635
- combined: true,
636
- },
637
- ]
638
- : binaries.map((expression) => ({
639
- expression,
640
- combined: true,
641
- }))),
642
- ...(rest !== null
643
- ? [
644
- {
645
- expression: rest,
646
- combined: true,
647
- },
648
- ]
649
- : []),
650
- ],
651
- `[${tuple.map((t) => t.getName()).join(", ")}]`,
652
- );
653
- };
654
- }
655
-
656
- function decode_array(
657
- project: IProject,
658
- config: IConfig,
659
- importer: FunctionImporter,
660
- checkTupleLength: boolean,
661
- ) {
662
- return FeatureProgrammer.decode_array(
663
- {
664
- trace: config.trace,
665
- path: config.path,
666
- decoder: decode(project, config, importer, checkTupleLength),
667
- },
668
- importer,
669
- config.joiner.array,
670
- );
671
- }
672
-
673
- export function decode_object(config: IConfig) {
674
- const func = FeatureProgrammer.decode_object(config);
675
- return function (
676
- input: ts.Expression,
677
- obj: MetadataObject,
678
- explore: IExplore,
679
- ) {
680
- obj.validated = true;
681
- return func(input, obj, explore);
682
- };
683
- }
684
-
685
- const explore_array = (
686
- project: IProject,
687
- config: IConfig,
688
- importer: FunctionImporter,
689
- ) =>
690
- UnionExplorer.array({
691
- checker: decode(project, config, importer),
692
- decoder: decode_array(project, config, importer, true),
693
- empty: config.success,
694
- success: config.success,
695
- failure: (input, expected, explore) =>
696
- ts.factory.createReturnStatement(
697
- config.joiner.failure(input, expected, explore),
698
- ),
699
- });
700
-
701
- const explore_set = (
702
- project: IProject,
703
- config: IConfig,
704
- importer: FunctionImporter,
705
- ) =>
706
- UnionExplorer.set({
707
- checker: decode(project, config, importer),
708
- decoder: decode_array(project, config, importer, true),
709
- empty: config.success,
710
- success: config.success,
711
- failure: (input, expected, explore) =>
712
- ts.factory.createReturnStatement(
713
- config.joiner.failure(input, expected, explore),
714
- ),
715
- });
716
-
717
- const explore_map = (
718
- project: IProject,
719
- config: IConfig,
720
- importer: FunctionImporter,
721
- ) =>
722
- UnionExplorer.map({
723
- checker: (input, entry, explore) => {
724
- const func = decode(project, config, importer);
725
- return ts.factory.createLogicalAnd(
726
- func(
727
- ts.factory.createElementAccessExpression(input, 0),
728
- entry[0],
729
- { ...explore, postfix: `${explore.postfix}[0]` },
730
- [],
731
- ),
732
- func(
733
- ts.factory.createElementAccessExpression(input, 1),
734
- entry[1],
735
- { ...explore, postfix: `${explore.postfix}[1]` },
736
- [],
737
- ),
738
- );
739
- },
740
- decoder: (input, target, explore) =>
741
- decode_array(project, config, importer, false)(
742
- input,
743
- Metadata.create({
744
- any: false,
745
- nullable: false,
746
- required: true,
747
- functional: false,
748
- resolved: null,
749
- constants: [],
750
- atomics: [],
751
- templates: [],
752
- rest: null,
753
- arrays: [],
754
- tuples: [target],
755
- objects: [],
756
- natives: [],
757
- sets: [],
758
- maps: [],
759
- }),
760
- explore,
761
- [],
762
- ),
763
- empty: config.success,
764
- success: config.success,
765
- failure: (input, expected, explore) =>
766
- ts.factory.createReturnStatement(
767
- config.joiner.failure(input, expected, explore),
768
- ),
769
- });
770
-
771
- const explore_objects = (config: IConfig) => {
772
- const objector = decode_object(config);
773
-
774
- return (input: ts.Expression, meta: Metadata, explore: IExplore) => {
775
- if (meta.objects.length === 1)
776
- return objector(input, meta.objects[0]!, explore);
777
-
778
- return ts.factory.createCallExpression(
779
- ts.factory.createIdentifier(
780
- `${config.unioners}${meta.union_index!}`,
781
- ),
782
- undefined,
783
- FeatureProgrammer.get_object_arguments(config)(explore)(input),
784
- );
785
- };
786
- };
787
- }
788
-
789
- const create_add =
790
- (binaries: CheckerProgrammer.IBinary[]) =>
791
- (defaultInput: ts.Expression) =>
792
- (
793
- exact: boolean,
794
- left: ts.Expression,
795
- right: ts.Expression = defaultInput,
796
- ) => {
797
- const factory = exact
798
- ? ts.factory.createStrictEquality
799
- : ts.factory.createStrictInequality;
800
- binaries.push({
801
- expression: factory(left, right),
802
- combined: false,
803
- });
804
- };
1
+ import ts from "typescript";
2
+
3
+ import { ExpressionFactory } from "../factories/ExpressionFactory";
4
+ import { IdentifierFactory } from "../factories/IdentifierFactory";
5
+ import { MetadataCollection } from "../factories/MetadataCollection";
6
+ import { MetadataFactory } from "../factories/MetadataFactory";
7
+ import { ValueFactory } from "../factories/ValueFactory";
8
+
9
+ import { IMetadataTag } from "../metadata/IMetadataTag";
10
+ import { Metadata } from "../metadata/Metadata";
11
+ import { MetadataObject } from "../metadata/MetadataObject";
12
+
13
+ import { IProject } from "../transformers/IProject";
14
+
15
+ import { FeatureProgrammer } from "./FeatureProgrammer";
16
+ import { FunctionImporter } from "./helpers/FunctionImporeter";
17
+ import { IExpressionEntry } from "./helpers/IExpressionEntry";
18
+ import { OptionPredicator } from "./helpers/OptionPredicator";
19
+ import { UnionExplorer } from "./helpers/UnionExplorer";
20
+ import { check_array } from "./internal/check_array";
21
+ import { check_bigint } from "./internal/check_bigint";
22
+ import { check_native } from "./internal/check_native";
23
+ import { check_number } from "./internal/check_number";
24
+ import { check_string } from "./internal/check_string";
25
+ import { check_template } from "./internal/check_template";
26
+ import { decode_union_object } from "./internal/decode_union_object";
27
+
28
+ export namespace CheckerProgrammer {
29
+ export interface IConfig {
30
+ functors: string;
31
+ unioners: string;
32
+ path: boolean;
33
+ trace: boolean;
34
+ equals: boolean;
35
+ numeric: boolean;
36
+ combiner: IConfig.Combiner;
37
+ decoder?: FeatureProgrammer.Decoder<Metadata>;
38
+ joiner: IConfig.IJoiner;
39
+ success: ts.Expression;
40
+ }
41
+ export namespace IConfig {
42
+ export interface Combiner {
43
+ (explorer: IExplore): {
44
+ (logic: "and" | "or"): {
45
+ (
46
+ input: ts.Expression,
47
+ binaries: IBinary[],
48
+ expected: string,
49
+ ): ts.Expression;
50
+ };
51
+ };
52
+ }
53
+ export interface IJoiner {
54
+ object(entries: IExpressionEntry[]): ts.Expression;
55
+ array(input: ts.Expression, arrow: ts.ArrowFunction): ts.Expression;
56
+ tuple?(exprs: ts.Expression[]): ts.Expression;
57
+
58
+ failure(
59
+ value: ts.Expression,
60
+ expected: string,
61
+ explore?: FeatureProgrammer.IExplore,
62
+ ): ts.Expression;
63
+ is?(expression: ts.Expression): ts.Expression;
64
+ required?(exp: ts.Expression): ts.Expression;
65
+ full?: (
66
+ condition: ts.Expression,
67
+ ) => (
68
+ input: ts.Expression,
69
+ expected: string,
70
+ explore: IExplore,
71
+ ) => ts.Expression;
72
+ }
73
+ }
74
+ export import IExplore = FeatureProgrammer.IExplore;
75
+
76
+ export interface IBinary {
77
+ expression: ts.Expression;
78
+ combined: boolean;
79
+ }
80
+
81
+ /* -----------------------------------------------------------
82
+ GENERATORS
83
+ ----------------------------------------------------------- */
84
+ export function generate(
85
+ project: IProject,
86
+ config: IConfig,
87
+ importer: FunctionImporter,
88
+ addition?: () => ts.Statement[],
89
+ ) {
90
+ return FeatureProgrammer.generate(
91
+ project,
92
+ CONFIG(project, config, importer),
93
+ importer,
94
+ () => (addition ? (addition ? addition() : []) : undefined),
95
+ );
96
+ }
97
+
98
+ export const generate_functors = (
99
+ project: IProject,
100
+ config: IConfig,
101
+ importer: FunctionImporter,
102
+ ) =>
103
+ FeatureProgrammer.generate_functors(
104
+ CONFIG(project, config, importer),
105
+ importer,
106
+ );
107
+
108
+ export const generate_unioners = (
109
+ project: IProject,
110
+ config: IConfig,
111
+ importer: FunctionImporter,
112
+ ) =>
113
+ FeatureProgrammer.generate_unioners(
114
+ CONFIG(project, { ...config, numeric: false }, importer),
115
+ );
116
+
117
+ function CONFIG(
118
+ project: IProject,
119
+ config: IConfig,
120
+ importer: FunctionImporter,
121
+ ): FeatureProgrammer.IConfig {
122
+ const output: FeatureProgrammer.IConfig = {
123
+ trace: config.trace,
124
+ path: config.path,
125
+ functors: config.functors,
126
+ unioners: config.unioners,
127
+ initializer: ({ checker }, type) => {
128
+ const collection: MetadataCollection = new MetadataCollection();
129
+ const meta: Metadata = MetadataFactory.generate(
130
+ checker,
131
+ collection,
132
+ type,
133
+ {
134
+ resolve: false,
135
+ constant: true,
136
+ },
137
+ );
138
+ return [collection, meta];
139
+ },
140
+ decoder: config.decoder || decode(project, config, importer),
141
+ objector: {
142
+ checker: config.decoder || decode(project, config, importer),
143
+ decoder: decode_object(config),
144
+ joiner: config.joiner.object,
145
+ unionizer: config.equals
146
+ ? decode_union_object(decode_object(config))(
147
+ (input, obj, explore) =>
148
+ decode_object(config)(input, obj, {
149
+ ...explore,
150
+ tracable: true,
151
+ }),
152
+ )(config.joiner.is || ((expr) => expr))(
153
+ (value, expected) =>
154
+ ts.factory.createReturnStatement(
155
+ config.joiner.failure(value, expected),
156
+ ),
157
+ )
158
+ : (input, targets, explore) =>
159
+ config.combiner(explore)("or")(
160
+ input,
161
+ targets.map((obj) => ({
162
+ expression: decode_object(config)(
163
+ input,
164
+ obj,
165
+ explore,
166
+ ),
167
+ combined: true,
168
+ })),
169
+ `(${targets.map((t) => t.name).join(" | ")})`,
170
+ ),
171
+ failure: (value, expected) =>
172
+ ts.factory.createReturnStatement(
173
+ config.joiner.failure(value, expected),
174
+ ),
175
+ is: config.joiner.is,
176
+ required: config.joiner.required,
177
+ full: config.joiner.full,
178
+ },
179
+ };
180
+ if (config.numeric === true)
181
+ output.generator = {
182
+ unioners: FeatureProgrammer.generate_unioners(
183
+ CONFIG(project, { ...config, numeric: false }, importer),
184
+ ),
185
+ };
186
+ return output;
187
+ }
188
+
189
+ /* -----------------------------------------------------------
190
+ DECODERS
191
+ ----------------------------------------------------------- */
192
+ export function decode(
193
+ project: IProject,
194
+ config: IConfig,
195
+ importer: FunctionImporter,
196
+ ): (
197
+ input: ts.Expression,
198
+ meta: Metadata,
199
+ explore: IExplore,
200
+ tags: IMetadataTag[],
201
+ ) => ts.Expression;
202
+
203
+ /**
204
+ * @internal
205
+ */
206
+ export function decode(
207
+ project: IProject,
208
+ config: IConfig,
209
+ importer: FunctionImporter,
210
+ checkTupleLength: boolean,
211
+ ): (
212
+ input: ts.Expression,
213
+ meta: Metadata,
214
+ explore: IExplore,
215
+ tags: IMetadataTag[],
216
+ ) => ts.Expression;
217
+
218
+ /**
219
+ * @internal
220
+ */
221
+ export function decode(
222
+ project: IProject,
223
+ config: IConfig,
224
+ importer: FunctionImporter,
225
+ checkTupleLength: boolean = true,
226
+ ) {
227
+ return function (
228
+ input: ts.Expression,
229
+ meta: Metadata,
230
+ explore: IExplore,
231
+ tags: IMetadataTag[],
232
+ ): ts.Expression {
233
+ if (meta.any) return config.success;
234
+
235
+ const top: IBinary[] = [];
236
+ const binaries: IBinary[] = [];
237
+ const add = create_add(binaries)(input);
238
+ const getConstantValue = (
239
+ value: number | string | bigint | boolean,
240
+ ) =>
241
+ typeof value === "string"
242
+ ? ts.factory.createStringLiteral(value)
243
+ : ts.factory.createIdentifier(value.toString());
244
+
245
+ //----
246
+ // CHECK OPTIONAL
247
+ //----
248
+ const checkOptional: boolean = meta.empty() || meta.isUnionBucket();
249
+
250
+ // NULLABLE
251
+ if (
252
+ checkOptional ||
253
+ meta.nullable
254
+ // || (meta.objects.length && meta.size() !== meta.objects.length)
255
+ )
256
+ (meta.nullable ? add : create_add(top)(input))(
257
+ meta.nullable,
258
+ ValueFactory.NULL(),
259
+ );
260
+
261
+ // UNDEFINDABLE
262
+ if (checkOptional || !meta.required)
263
+ (meta.required ? create_add(top)(input) : add)(
264
+ !meta.required,
265
+ ValueFactory.UNDEFINED(),
266
+ );
267
+
268
+ // FUNCTIONAL
269
+ if (meta.functional === true)
270
+ if (
271
+ OptionPredicator.functional(project.options) ||
272
+ meta.size() !== 1
273
+ )
274
+ add(
275
+ true,
276
+ ts.factory.createStringLiteral("function"),
277
+ ValueFactory.TYPEOF(input),
278
+ );
279
+ else
280
+ binaries.push({
281
+ combined: false,
282
+ expression: config.success,
283
+ });
284
+
285
+ //----
286
+ // VALUES
287
+ //----
288
+ // CONSTANT VALUES
289
+ for (const constant of meta.constants)
290
+ for (const val of constant.values)
291
+ add(true, getConstantValue(val));
292
+
293
+ // ATOMIC VALUES
294
+ for (const type of meta.atomics)
295
+ if (type === "number")
296
+ binaries.push({
297
+ expression: check_number(project, config.numeric)(
298
+ input,
299
+ tags,
300
+ ),
301
+ combined: false,
302
+ });
303
+ else if (type === "bigint")
304
+ binaries.push({
305
+ expression: check_bigint(input, tags),
306
+ combined: false,
307
+ });
308
+ else if (type === "string")
309
+ binaries.push({
310
+ expression: check_string(importer)(input, tags),
311
+ combined: false,
312
+ });
313
+ else
314
+ add(
315
+ true,
316
+ ts.factory.createStringLiteral(type),
317
+ ValueFactory.TYPEOF(input),
318
+ );
319
+
320
+ // TEMPLATE LITERAL VALUES
321
+ if (meta.templates.length)
322
+ binaries.push({
323
+ expression: check_template(importer)(
324
+ input,
325
+ meta.templates,
326
+ tags,
327
+ ),
328
+ combined: false,
329
+ });
330
+
331
+ //----
332
+ // INSTANCES
333
+ //----
334
+ // TUPLE
335
+ if (meta.tuples.length > 0) {
336
+ const inner: ts.Expression[] = [];
337
+ for (const tuple of meta.tuples)
338
+ inner.push(
339
+ decode_tuple(
340
+ project,
341
+ config,
342
+ importer,
343
+ checkTupleLength,
344
+ )(input, tuple, explore, tags),
345
+ );
346
+
347
+ // ADD
348
+ binaries.push({
349
+ expression: config.combiner(explore)("and")(
350
+ input,
351
+ [
352
+ ...(checkTupleLength
353
+ ? [
354
+ {
355
+ expression:
356
+ ExpressionFactory.isArray(input),
357
+ combined: false,
358
+ },
359
+ ]
360
+ : []),
361
+ ...inner.map((expression) => ({
362
+ expression,
363
+ combined: true,
364
+ })),
365
+ ],
366
+ meta.getName(),
367
+ ),
368
+ combined: true,
369
+ });
370
+ }
371
+
372
+ // ARRAY
373
+ if (meta.arrays.length > 0)
374
+ if (meta.arrays.every((elem) => elem.any))
375
+ binaries.push({
376
+ expression: check_array(input, tags),
377
+ combined: false,
378
+ });
379
+ else
380
+ binaries.push({
381
+ expression: config.combiner(explore)("and")(
382
+ input,
383
+ [
384
+ ...(checkTupleLength
385
+ ? [
386
+ {
387
+ expression: check_array(
388
+ input,
389
+ tags,
390
+ ),
391
+ combined: false,
392
+ },
393
+ ]
394
+ : []),
395
+ {
396
+ expression: explore_array(
397
+ project,
398
+ config,
399
+ importer,
400
+ )(
401
+ input,
402
+ meta.arrays,
403
+ {
404
+ ...explore,
405
+ from: "array",
406
+ },
407
+ tags,
408
+ ),
409
+ combined: true,
410
+ },
411
+ ],
412
+ meta.getName(),
413
+ ),
414
+ combined: true,
415
+ });
416
+
417
+ // OBJECT
418
+ if (meta.objects.length > 0)
419
+ binaries.push({
420
+ expression: config.combiner(explore)("and")(
421
+ input,
422
+ [
423
+ {
424
+ expression: ExpressionFactory.isObject(input, {
425
+ checkNull: true,
426
+ checkArray: meta.objects.some((obj) =>
427
+ obj.properties.every(
428
+ (prop) =>
429
+ !prop.key.isSoleLiteral() ||
430
+ !prop.value.required,
431
+ ),
432
+ ),
433
+ }),
434
+ combined: false,
435
+ },
436
+ {
437
+ expression: explore_objects(config)(
438
+ input,
439
+ meta,
440
+ {
441
+ ...explore,
442
+ from: "object",
443
+ },
444
+ ),
445
+ combined: true,
446
+ },
447
+ ],
448
+ meta.getName(),
449
+ ),
450
+ combined: true,
451
+ });
452
+
453
+ // NATIVE CLASSES
454
+ for (const native of meta.natives)
455
+ binaries.push({
456
+ expression: check_native(native)(input),
457
+ combined: false,
458
+ });
459
+
460
+ // SETS
461
+ if (meta.sets.length)
462
+ if (meta.sets.every((elem) => elem.any))
463
+ binaries.push({
464
+ combined: false,
465
+ expression: check_native("Set")(input),
466
+ });
467
+ else
468
+ binaries.push({
469
+ combined: true,
470
+ expression: config.combiner(explore)("and")(
471
+ input,
472
+ [
473
+ {
474
+ combined: false,
475
+ expression: check_native("Set")(input),
476
+ },
477
+ {
478
+ combined: true,
479
+ expression: explore_set(
480
+ project,
481
+ config,
482
+ importer,
483
+ )(
484
+ input,
485
+ meta.sets,
486
+ {
487
+ ...explore,
488
+ from: "array",
489
+ },
490
+ [],
491
+ ),
492
+ },
493
+ ],
494
+ meta.getName(),
495
+ ),
496
+ });
497
+
498
+ // MAPS
499
+ if (meta.maps.length)
500
+ if (meta.maps.every((elem) => elem.key.any && elem.value.any))
501
+ binaries.push({
502
+ expression: check_native("Map")(input),
503
+ combined: false,
504
+ });
505
+ else
506
+ binaries.push({
507
+ combined: true,
508
+ expression: config.combiner(explore)("and")(
509
+ input,
510
+ [
511
+ {
512
+ combined: false,
513
+ expression: check_native("Map")(input),
514
+ },
515
+ {
516
+ combined: true,
517
+ expression: explore_map(
518
+ project,
519
+ config,
520
+ importer,
521
+ )(
522
+ input,
523
+ meta.maps.map((m) => [m.key, m.value]),
524
+ {
525
+ ...explore,
526
+ from: "array",
527
+ },
528
+ [],
529
+ ),
530
+ },
531
+ ],
532
+ meta.getName(),
533
+ ),
534
+ });
535
+
536
+ // COMBINE CONDITIONS
537
+ return top.length && binaries.length
538
+ ? config.combiner(explore)("and")(
539
+ input,
540
+ [
541
+ ...top,
542
+ {
543
+ expression: config.combiner(explore)("or")(
544
+ input,
545
+ binaries,
546
+ meta.getName(),
547
+ ),
548
+ combined: true,
549
+ },
550
+ ],
551
+ meta.getName(),
552
+ )
553
+ : binaries.length
554
+ ? config.combiner(explore)("or")(
555
+ input,
556
+ binaries,
557
+ meta.getName(),
558
+ )
559
+ : config.success;
560
+ };
561
+ }
562
+
563
+ function decode_tuple(
564
+ project: IProject,
565
+ config: IConfig,
566
+ importer: FunctionImporter,
567
+ checkLength: boolean,
568
+ ) {
569
+ return function (
570
+ input: ts.Expression,
571
+ tuple: Array<Metadata>,
572
+ explore: IExplore,
573
+ tagList: IMetadataTag[],
574
+ ): ts.Expression {
575
+ const binaries: ts.Expression[] = tuple
576
+ .filter((meta) => meta.rest === null)
577
+ .map((meta, index) =>
578
+ decode(project, config, importer)(
579
+ ts.factory.createElementAccessExpression(input, index),
580
+ meta,
581
+ {
582
+ ...explore,
583
+ from: "array",
584
+ postfix: explore.postfix.length
585
+ ? `${explore.postfix.slice(0, -1)}[${index}]"`
586
+ : `[${index}]`,
587
+ },
588
+ tagList,
589
+ ),
590
+ );
591
+ const rest: ts.Expression | null =
592
+ tuple.length && tuple[tuple.length - 1]!.rest !== null
593
+ ? decode(project, config, importer, false)(
594
+ ts.factory.createCallExpression(
595
+ IdentifierFactory.join(input, "slice"),
596
+ undefined,
597
+ [
598
+ ts.factory.createNumericLiteral(
599
+ tuple.length - 1,
600
+ ),
601
+ ],
602
+ ),
603
+ (() => {
604
+ const wrapper: Metadata = Metadata.initialize();
605
+ wrapper.arrays.push(
606
+ tuple[tuple.length - 1]!.rest!,
607
+ );
608
+ return wrapper;
609
+ })(),
610
+ {
611
+ ...explore,
612
+ start: tuple.length - 1,
613
+ },
614
+ tagList,
615
+ )
616
+ : null;
617
+
618
+ return config.combiner(explore)("and")(
619
+ input,
620
+ [
621
+ ...(checkLength && rest === null
622
+ ? [
623
+ {
624
+ combined: false,
625
+ expression: ts.factory.createStrictEquality(
626
+ ts.factory.createPropertyAccessExpression(
627
+ input,
628
+ "length",
629
+ ),
630
+ ts.factory.createNumericLiteral(
631
+ tuple.length,
632
+ ),
633
+ ),
634
+ },
635
+ ]
636
+ : []),
637
+ ...(config.joiner.tuple
638
+ ? [
639
+ {
640
+ expression: config.joiner.tuple(binaries),
641
+ combined: true,
642
+ },
643
+ ]
644
+ : binaries.map((expression) => ({
645
+ expression,
646
+ combined: true,
647
+ }))),
648
+ ...(rest !== null
649
+ ? [
650
+ {
651
+ expression: rest,
652
+ combined: true,
653
+ },
654
+ ]
655
+ : []),
656
+ ],
657
+ `[${tuple.map((t) => t.getName()).join(", ")}]`,
658
+ );
659
+ };
660
+ }
661
+
662
+ function decode_array(
663
+ project: IProject,
664
+ config: IConfig,
665
+ importer: FunctionImporter,
666
+ checkTupleLength: boolean,
667
+ ) {
668
+ return FeatureProgrammer.decode_array(
669
+ {
670
+ trace: config.trace,
671
+ path: config.path,
672
+ decoder: decode(project, config, importer, checkTupleLength),
673
+ },
674
+ importer,
675
+ config.joiner.array,
676
+ );
677
+ }
678
+
679
+ export function decode_object(config: IConfig) {
680
+ const func = FeatureProgrammer.decode_object(config);
681
+ return function (
682
+ input: ts.Expression,
683
+ obj: MetadataObject,
684
+ explore: IExplore,
685
+ ) {
686
+ obj.validated = true;
687
+ return func(input, obj, explore);
688
+ };
689
+ }
690
+
691
+ const explore_array = (
692
+ project: IProject,
693
+ config: IConfig,
694
+ importer: FunctionImporter,
695
+ ) =>
696
+ UnionExplorer.array({
697
+ checker: decode(project, config, importer),
698
+ decoder: decode_array(project, config, importer, true),
699
+ empty: config.success,
700
+ success: config.success,
701
+ failure: (input, expected, explore) =>
702
+ ts.factory.createReturnStatement(
703
+ config.joiner.failure(input, expected, explore),
704
+ ),
705
+ });
706
+
707
+ const explore_set = (
708
+ project: IProject,
709
+ config: IConfig,
710
+ importer: FunctionImporter,
711
+ ) =>
712
+ UnionExplorer.set({
713
+ checker: decode(project, config, importer),
714
+ decoder: decode_array(project, config, importer, true),
715
+ empty: config.success,
716
+ success: config.success,
717
+ failure: (input, expected, explore) =>
718
+ ts.factory.createReturnStatement(
719
+ config.joiner.failure(input, expected, explore),
720
+ ),
721
+ });
722
+
723
+ const explore_map = (
724
+ project: IProject,
725
+ config: IConfig,
726
+ importer: FunctionImporter,
727
+ ) =>
728
+ UnionExplorer.map({
729
+ checker: (input, entry, explore) => {
730
+ const func = decode(project, config, importer);
731
+ return ts.factory.createLogicalAnd(
732
+ func(
733
+ ts.factory.createElementAccessExpression(input, 0),
734
+ entry[0],
735
+ { ...explore, postfix: `${explore.postfix}[0]` },
736
+ [],
737
+ ),
738
+ func(
739
+ ts.factory.createElementAccessExpression(input, 1),
740
+ entry[1],
741
+ { ...explore, postfix: `${explore.postfix}[1]` },
742
+ [],
743
+ ),
744
+ );
745
+ },
746
+ decoder: (input, target, explore) =>
747
+ decode_array(project, config, importer, false)(
748
+ input,
749
+ Metadata.create({
750
+ any: false,
751
+ nullable: false,
752
+ required: true,
753
+ functional: false,
754
+ resolved: null,
755
+ constants: [],
756
+ atomics: [],
757
+ templates: [],
758
+ rest: null,
759
+ arrays: [],
760
+ tuples: [target],
761
+ objects: [],
762
+ natives: [],
763
+ sets: [],
764
+ maps: [],
765
+ }),
766
+ explore,
767
+ [],
768
+ ),
769
+ empty: config.success,
770
+ success: config.success,
771
+ failure: (input, expected, explore) =>
772
+ ts.factory.createReturnStatement(
773
+ config.joiner.failure(input, expected, explore),
774
+ ),
775
+ });
776
+
777
+ const explore_objects = (config: IConfig) => {
778
+ const objector = decode_object(config);
779
+
780
+ return (input: ts.Expression, meta: Metadata, explore: IExplore) => {
781
+ if (meta.objects.length === 1)
782
+ return objector(input, meta.objects[0]!, explore);
783
+
784
+ return ts.factory.createCallExpression(
785
+ ts.factory.createIdentifier(
786
+ `${config.unioners}${meta.union_index!}`,
787
+ ),
788
+ undefined,
789
+ FeatureProgrammer.get_object_arguments(config)(explore)(input),
790
+ );
791
+ };
792
+ };
793
+ }
794
+
795
+ const create_add =
796
+ (binaries: CheckerProgrammer.IBinary[]) =>
797
+ (defaultInput: ts.Expression) =>
798
+ (
799
+ exact: boolean,
800
+ left: ts.Expression,
801
+ right: ts.Expression = defaultInput,
802
+ ) => {
803
+ const factory = exact
804
+ ? ts.factory.createStrictEquality
805
+ : ts.factory.createStrictInequality;
806
+ binaries.push({
807
+ expression: factory(left, right),
808
+ combined: false,
809
+ });
810
+ };