typia 3.6.0-dev.20230219 → 3.6.0-dev.20230225

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