typia 5.3.12-dev.20240121 → 5.3.12-dev.20240122

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 (360) hide show
  1. package/package.json +1 -1
  2. package/src/AssertionGuard.ts +1 -1
  3. package/src/CamelCase.ts +114 -114
  4. package/src/IRandomGenerator.ts +35 -35
  5. package/src/IValidation.ts +21 -21
  6. package/src/PascalCase.ts +114 -114
  7. package/src/Primitive.ts +135 -135
  8. package/src/Resolved.ts +116 -116
  9. package/src/SnakeCase.ts +156 -156
  10. package/src/TypeGuardError.ts +36 -36
  11. package/src/executable/TypiaGenerateWizard.ts +83 -83
  12. package/src/executable/TypiaPatchWizard.ts +42 -42
  13. package/src/executable/TypiaSetupWizard.ts +151 -151
  14. package/src/executable/setup/ArgumentParser.ts +43 -43
  15. package/src/executable/setup/CommandExecutor.ts +8 -8
  16. package/src/executable/setup/FileRetriever.ts +22 -22
  17. package/src/executable/setup/PackageManager.ts +71 -71
  18. package/src/executable/setup/PluginConfigurator.ts +69 -69
  19. package/src/executable/typia.ts +55 -55
  20. package/src/factories/CommentFactory.ts +79 -79
  21. package/src/factories/ExpressionFactory.ts +150 -150
  22. package/src/factories/IdentifierFactory.ts +70 -70
  23. package/src/factories/JsonMetadataFactory.ts +53 -53
  24. package/src/factories/LiteralFactory.ts +47 -47
  25. package/src/factories/MetadataCollection.ts +260 -260
  26. package/src/factories/MetadataCommentTagFactory.ts +601 -601
  27. package/src/factories/MetadataFactory.ts +267 -267
  28. package/src/factories/MetadataTypeTagFactory.ts +313 -313
  29. package/src/factories/NumericRangeFactory.ts +72 -72
  30. package/src/factories/ProtobufFactory.ts +259 -259
  31. package/src/factories/StatementFactory.ts +72 -72
  32. package/src/factories/TemplateFactory.ts +56 -56
  33. package/src/factories/TypeFactory.ts +118 -118
  34. package/src/factories/ValueFactory.ts +12 -12
  35. package/src/factories/internal/metadata/MetadataHelper.ts +15 -15
  36. package/src/factories/internal/metadata/emend_metadata_atomics.ts +37 -37
  37. package/src/factories/internal/metadata/emplace_metadata_alias.ts +41 -41
  38. package/src/factories/internal/metadata/emplace_metadata_array_type.ts +38 -38
  39. package/src/factories/internal/metadata/emplace_metadata_object.ts +175 -175
  40. package/src/factories/internal/metadata/emplace_metadata_tuple.ts +57 -57
  41. package/src/factories/internal/metadata/explore_metadata.ts +28 -28
  42. package/src/factories/internal/metadata/iterate_metadata.ts +94 -94
  43. package/src/factories/internal/metadata/iterate_metadata_alias.ts +34 -34
  44. package/src/factories/internal/metadata/iterate_metadata_array.ts +37 -37
  45. package/src/factories/internal/metadata/iterate_metadata_atomic.ts +62 -62
  46. package/src/factories/internal/metadata/iterate_metadata_coalesce.ts +33 -33
  47. package/src/factories/internal/metadata/iterate_metadata_collection.ts +131 -131
  48. package/src/factories/internal/metadata/iterate_metadata_comment_tags.ts +26 -26
  49. package/src/factories/internal/metadata/iterate_metadata_constant.ts +48 -48
  50. package/src/factories/internal/metadata/iterate_metadata_intersection.ts +230 -230
  51. package/src/factories/internal/metadata/iterate_metadata_map.ts +50 -50
  52. package/src/factories/internal/metadata/iterate_metadata_native.ts +208 -208
  53. package/src/factories/internal/metadata/iterate_metadata_object.ts +43 -43
  54. package/src/factories/internal/metadata/iterate_metadata_resolve.ts +52 -52
  55. package/src/factories/internal/metadata/iterate_metadata_set.ts +41 -41
  56. package/src/factories/internal/metadata/iterate_metadata_sort.ts +61 -61
  57. package/src/factories/internal/metadata/iterate_metadata_template.ts +44 -44
  58. package/src/factories/internal/metadata/iterate_metadata_tuple.ts +37 -37
  59. package/src/factories/internal/metadata/iterate_metadata_union.ts +27 -27
  60. package/src/functional/$HeadersReader/$HeadersReader.ts +26 -26
  61. package/src/functional/$HeadersReader/index.ts +1 -1
  62. package/src/functional/$ParameterReader/$ParameterReader.ts +29 -29
  63. package/src/functional/$ParameterReader/index.ts +1 -1
  64. package/src/functional/$ProtobufReader.ts +195 -195
  65. package/src/functional/$ProtobufSizer.ts +147 -147
  66. package/src/functional/$ProtobufWriter.ts +150 -150
  67. package/src/functional/$QueryReader/$QueryReader.ts +46 -46
  68. package/src/functional/$QueryReader/index.ts +1 -1
  69. package/src/functional/$any.ts +4 -4
  70. package/src/functional/$clone.ts +4 -4
  71. package/src/functional/$convention.ts +37 -37
  72. package/src/functional/$dictionary.ts +22 -22
  73. package/src/functional/$every.ts +11 -11
  74. package/src/functional/$guard.ts +35 -35
  75. package/src/functional/$is_between.ts +2 -2
  76. package/src/functional/$join.ts +46 -46
  77. package/src/functional/$number.ts +12 -12
  78. package/src/functional/$report.ts +13 -13
  79. package/src/functional/$rest.ts +3 -3
  80. package/src/functional/$stoll.ts +8 -8
  81. package/src/functional/$string.ts +50 -50
  82. package/src/functional/$strlen.ts +7 -7
  83. package/src/functional/$tail.ts +5 -5
  84. package/src/functional/$throws.ts +10 -10
  85. package/src/functional/$varint.ts +130 -130
  86. package/src/functional/$zigzag.ts +39 -39
  87. package/src/functional/IProtobufWriter.ts +18 -18
  88. package/src/functional/Namespace/http.ts +7 -7
  89. package/src/functional/Namespace/index.ts +75 -75
  90. package/src/functional/Namespace/json.ts +15 -15
  91. package/src/functional/Namespace/misc.ts +14 -14
  92. package/src/functional/Namespace/notations.ts +23 -23
  93. package/src/functional/Namespace/protobuf.ts +20 -20
  94. package/src/functional/is.ts +10 -10
  95. package/src/http.ts +1267 -1267
  96. package/src/index.ts +4 -4
  97. package/src/notations.ts +977 -977
  98. package/src/programmers/AssertProgrammer.ts +293 -293
  99. package/src/programmers/CheckerProgrammer.ts +1025 -1025
  100. package/src/programmers/FeatureProgrammer.ts +460 -460
  101. package/src/programmers/IsProgrammer.ts +232 -232
  102. package/src/programmers/RandomProgrammer.ts +825 -825
  103. package/src/programmers/TypiaProgrammer.ts +167 -167
  104. package/src/programmers/ValidateProgrammer.ts +307 -307
  105. package/src/programmers/helpers/AtomicPredicator.ts +25 -25
  106. package/src/programmers/helpers/CloneJoiner.ts +130 -130
  107. package/src/programmers/helpers/FunctionImporeter.ts +87 -87
  108. package/src/programmers/helpers/HttpMetadataUtil.ts +21 -21
  109. package/src/programmers/helpers/ICheckEntry.ts +13 -13
  110. package/src/programmers/helpers/IExpressionEntry.ts +12 -12
  111. package/src/programmers/helpers/NotationJoiner.ts +132 -132
  112. package/src/programmers/helpers/OptionPredicator.ts +15 -15
  113. package/src/programmers/helpers/ProtobufUtil.ts +125 -125
  114. package/src/programmers/helpers/ProtobufWire.ts +34 -34
  115. package/src/programmers/helpers/PruneJoiner.ts +141 -141
  116. package/src/programmers/helpers/RandomJoiner.ts +140 -140
  117. package/src/programmers/helpers/RandomRanger.ts +171 -171
  118. package/src/programmers/helpers/StringifyJoinder.ts +105 -105
  119. package/src/programmers/helpers/StringifyPredicator.ts +12 -12
  120. package/src/programmers/helpers/UnionExplorer.ts +269 -269
  121. package/src/programmers/helpers/UnionPredicator.ts +77 -77
  122. package/src/programmers/helpers/disable_function_importer_declare.ts +32 -32
  123. package/src/programmers/http/HttpAssertHeadersProgrammer.ts +77 -77
  124. package/src/programmers/http/HttpAssertQueryProgrammer.ts +75 -75
  125. package/src/programmers/http/HttpHeadersProgrammer.ts +314 -314
  126. package/src/programmers/http/HttpIsHeadersProgrammer.ts +84 -84
  127. package/src/programmers/http/HttpIsQueryProgrammer.ts +82 -82
  128. package/src/programmers/http/HttpParameterProgrammer.ts +97 -97
  129. package/src/programmers/http/HttpQueryProgrammer.ts +252 -252
  130. package/src/programmers/http/HttpValidateHeadersProgrammer.ts +77 -77
  131. package/src/programmers/http/HttpValidateQueryProgrammer.ts +75 -75
  132. package/src/programmers/internal/JSON_SCHEMA_PREFIX.ts +1 -1
  133. package/src/programmers/internal/application_alias.ts +74 -74
  134. package/src/programmers/internal/application_array.ts +59 -59
  135. package/src/programmers/internal/application_boolean.ts +35 -35
  136. package/src/programmers/internal/application_constant.ts +25 -25
  137. package/src/programmers/internal/application_default.ts +17 -17
  138. package/src/programmers/internal/application_default_string.ts +33 -33
  139. package/src/programmers/internal/application_escaped.ts +52 -52
  140. package/src/programmers/internal/application_native.ts +34 -34
  141. package/src/programmers/internal/application_number.ts +97 -97
  142. package/src/programmers/internal/application_object.ts +183 -183
  143. package/src/programmers/internal/application_schema.ts +165 -165
  144. package/src/programmers/internal/application_string.ts +61 -61
  145. package/src/programmers/internal/application_templates.ts +24 -24
  146. package/src/programmers/internal/application_tuple.ts +54 -54
  147. package/src/programmers/internal/check_array_length.ts +45 -45
  148. package/src/programmers/internal/check_bigint.ts +49 -49
  149. package/src/programmers/internal/check_dynamic_key.ts +175 -175
  150. package/src/programmers/internal/check_dynamic_properties.ts +198 -198
  151. package/src/programmers/internal/check_everything.ts +23 -23
  152. package/src/programmers/internal/check_native.ts +21 -21
  153. package/src/programmers/internal/check_number.ts +106 -106
  154. package/src/programmers/internal/check_object.ts +60 -60
  155. package/src/programmers/internal/check_string.ts +48 -48
  156. package/src/programmers/internal/check_template.ts +61 -61
  157. package/src/programmers/internal/check_union_array_like.ts +307 -307
  158. package/src/programmers/internal/decode_union_object.ts +78 -78
  159. package/src/programmers/internal/feature_object_entries.ts +58 -58
  160. package/src/programmers/internal/metadata_to_pattern.ts +33 -33
  161. package/src/programmers/internal/prune_object_properties.ts +60 -60
  162. package/src/programmers/internal/random_custom.ts +37 -37
  163. package/src/programmers/internal/stringify_dynamic_properties.ts +157 -157
  164. package/src/programmers/internal/stringify_native.ts +7 -7
  165. package/src/programmers/internal/stringify_regular_properties.ts +81 -81
  166. package/src/programmers/internal/template_to_pattern.ts +15 -15
  167. package/src/programmers/internal/wrap_metadata_rest_tuple.ts +20 -20
  168. package/src/programmers/json/JsonApplicationProgrammer.ts +49 -49
  169. package/src/programmers/json/JsonAssertParseProgrammer.ts +67 -67
  170. package/src/programmers/json/JsonAssertStringifyProgrammer.ts +61 -61
  171. package/src/programmers/json/JsonIsParseProgrammer.ts +73 -73
  172. package/src/programmers/json/JsonIsStringifyProgrammer.ts +75 -75
  173. package/src/programmers/json/JsonStringifyProgrammer.ts +893 -893
  174. package/src/programmers/json/JsonValidateParseProgrammer.ts +64 -64
  175. package/src/programmers/json/JsonValidateStringifyProgrammer.ts +83 -83
  176. package/src/programmers/misc/MiscAssertCloneProgrammer.ts +63 -63
  177. package/src/programmers/misc/MiscAssertPruneProgrammer.ts +60 -60
  178. package/src/programmers/misc/MiscCloneProgrammer.ts +713 -713
  179. package/src/programmers/misc/MiscIsCloneProgrammer.ts +70 -70
  180. package/src/programmers/misc/MiscIsPruneProgrammer.ts +66 -66
  181. package/src/programmers/misc/MiscLiteralsProgrammer.ts +72 -72
  182. package/src/programmers/misc/MiscPruneProgrammer.ts +523 -523
  183. package/src/programmers/misc/MiscValidateCloneProgrammer.ts +80 -80
  184. package/src/programmers/misc/MiscValidatePruneProgrammer.ts +73 -73
  185. package/src/programmers/notations/NotationAssertGeneralProgrammer.ts +64 -64
  186. package/src/programmers/notations/NotationGeneralProgrammer.ts +647 -647
  187. package/src/programmers/notations/NotationIsGeneralProgrammer.ts +71 -71
  188. package/src/programmers/notations/NotationValidateGeneralProgrammer.ts +81 -81
  189. package/src/programmers/protobuf/ProtobufAssertDecodeProgrammer.ts +75 -75
  190. package/src/programmers/protobuf/ProtobufAssertEncodeProgrammer.ts +61 -61
  191. package/src/programmers/protobuf/ProtobufDecodeProgrammer.ts +607 -607
  192. package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +819 -819
  193. package/src/programmers/protobuf/ProtobufIsDecodeProgrammer.ts +82 -82
  194. package/src/programmers/protobuf/ProtobufIsEncodeProgrammer.ts +75 -75
  195. package/src/programmers/protobuf/ProtobufMessageProgrammer.ts +160 -160
  196. package/src/programmers/protobuf/ProtobufValidateDecodeProgrammer.ts +75 -75
  197. package/src/programmers/protobuf/ProtobufValidateEncodeProgrammer.ts +83 -83
  198. package/src/protobuf.ts +970 -970
  199. package/src/reflect.ts +57 -57
  200. package/src/schemas/json/IJsonApplication.ts +9 -9
  201. package/src/schemas/json/IJsonComponents.ts +19 -19
  202. package/src/schemas/json/IJsonSchema.ts +122 -122
  203. package/src/schemas/metadata/IJsDocTagInfo.ts +10 -10
  204. package/src/schemas/metadata/IMetadata.ts +34 -34
  205. package/src/schemas/metadata/IMetadataAlias.ts +12 -12
  206. package/src/schemas/metadata/IMetadataApplication.ts +7 -7
  207. package/src/schemas/metadata/IMetadataArray.ts +7 -7
  208. package/src/schemas/metadata/IMetadataArrayType.ts +10 -10
  209. package/src/schemas/metadata/IMetadataAtomic.ts +6 -6
  210. package/src/schemas/metadata/IMetadataComponents.ts +11 -11
  211. package/src/schemas/metadata/IMetadataConstant.ts +23 -23
  212. package/src/schemas/metadata/IMetadataDictionary.ts +11 -11
  213. package/src/schemas/metadata/IMetadataEntry.ts +6 -6
  214. package/src/schemas/metadata/IMetadataEscaped.ts +6 -6
  215. package/src/schemas/metadata/IMetadataObject.ts +13 -13
  216. package/src/schemas/metadata/IMetadataProperty.ts +9 -9
  217. package/src/schemas/metadata/IMetadataTuple.ts +7 -7
  218. package/src/schemas/metadata/IMetadataTupleType.ts +10 -10
  219. package/src/schemas/metadata/IMetadataTypeTag.ts +15 -15
  220. package/src/schemas/metadata/Metadata.ts +612 -612
  221. package/src/schemas/metadata/MetadataAlias.ts +61 -61
  222. package/src/schemas/metadata/MetadataApplication.ts +44 -44
  223. package/src/schemas/metadata/MetadataArray.ts +49 -49
  224. package/src/schemas/metadata/MetadataArrayType.ts +57 -57
  225. package/src/schemas/metadata/MetadataAtomic.ts +84 -84
  226. package/src/schemas/metadata/MetadataComponents.ts +98 -98
  227. package/src/schemas/metadata/MetadataConstant.ts +46 -46
  228. package/src/schemas/metadata/MetadataEscaped.ts +51 -51
  229. package/src/schemas/metadata/MetadataObject.ts +154 -154
  230. package/src/schemas/metadata/MetadataProperty.ts +56 -56
  231. package/src/schemas/metadata/MetadataTuple.ts +32 -32
  232. package/src/schemas/metadata/MetadataTupleType.ts +67 -67
  233. package/src/tags/Default.ts +15 -15
  234. package/src/tags/ExclusiveMaximum.ts +13 -13
  235. package/src/tags/ExclusiveMinimum.ts +13 -13
  236. package/src/tags/Format.ts +30 -30
  237. package/src/tags/MaxItems.ts +9 -9
  238. package/src/tags/MaxLength.ts +9 -9
  239. package/src/tags/Maximum.ts +13 -13
  240. package/src/tags/MinItems.ts +9 -9
  241. package/src/tags/MinLength.ts +9 -9
  242. package/src/tags/Minimum.ts +13 -13
  243. package/src/tags/MultipleOf.ts +15 -15
  244. package/src/tags/Pattern.ts +9 -9
  245. package/src/tags/TagBase.ts +68 -68
  246. package/src/tags/Type.ts +27 -27
  247. package/src/tags/index.ts +14 -14
  248. package/src/transform.ts +35 -35
  249. package/src/transformers/CallExpressionTransformer.ts +351 -351
  250. package/src/transformers/FileTransformer.ts +91 -91
  251. package/src/transformers/IProject.ts +15 -15
  252. package/src/transformers/ITransformOptions.ts +62 -62
  253. package/src/transformers/ImportTransformer.ts +66 -66
  254. package/src/transformers/NodeTransformer.ts +13 -13
  255. package/src/transformers/TransformerError.ts +55 -55
  256. package/src/transformers/features/AssertTransformer.ts +16 -16
  257. package/src/transformers/features/CreateAssertTransformer.ts +16 -16
  258. package/src/transformers/features/CreateIsTransformer.ts +10 -10
  259. package/src/transformers/features/CreateRandomTransformer.ts +40 -40
  260. package/src/transformers/features/CreateValidateTransformer.ts +13 -13
  261. package/src/transformers/features/IsTransformer.ts +10 -10
  262. package/src/transformers/features/RandomTransformer.ts +44 -44
  263. package/src/transformers/features/ValidateTransformer.ts +11 -11
  264. package/src/transformers/features/http/CreateHttpAssertHeadersTransformer.ts +11 -11
  265. package/src/transformers/features/http/CreateHttpAssertQueryTransformer.ts +9 -9
  266. package/src/transformers/features/http/CreateHttpHeadersTransformer.ts +9 -9
  267. package/src/transformers/features/http/CreateHttpIsHeadersTransformer.ts +9 -9
  268. package/src/transformers/features/http/CreateHttpIsQueryTransformer.ts +9 -9
  269. package/src/transformers/features/http/CreateHttpParameterTransformer.ts +9 -9
  270. package/src/transformers/features/http/CreateHttpQueryTransformer.ts +9 -9
  271. package/src/transformers/features/http/CreateHttpValidateHeadersTransformer.ts +12 -12
  272. package/src/transformers/features/http/CreateHttpValidateQueryTransformer.ts +11 -11
  273. package/src/transformers/features/http/HttpAssertHeadersTransformer.ts +9 -9
  274. package/src/transformers/features/http/HttpAssertQueryTransformer.ts +9 -9
  275. package/src/transformers/features/http/HttpHeadersTransformer.ts +9 -9
  276. package/src/transformers/features/http/HttpIsHeadersTransformer.ts +9 -9
  277. package/src/transformers/features/http/HttpIsQueryTransformer.ts +9 -9
  278. package/src/transformers/features/http/HttpParameterTransformer.ts +9 -9
  279. package/src/transformers/features/http/HttpQueryTransformer.ts +9 -9
  280. package/src/transformers/features/http/HttpValidateHeadersTransformer.ts +10 -10
  281. package/src/transformers/features/http/HttpValidateQueryTransformer.ts +9 -9
  282. package/src/transformers/features/json/JsonApplicationTransformer.ts +134 -134
  283. package/src/transformers/features/json/JsonAssertParseTransformer.ts +9 -9
  284. package/src/transformers/features/json/JsonAssertStringifyTransformer.ts +10 -10
  285. package/src/transformers/features/json/JsonCreateAssertParseTransformer.ts +9 -9
  286. package/src/transformers/features/json/JsonCreateAssertStringifyTransformer.ts +12 -12
  287. package/src/transformers/features/json/JsonCreateIsParseTransformer.ts +9 -9
  288. package/src/transformers/features/json/JsonCreateIsStringifyTransformer.ts +9 -9
  289. package/src/transformers/features/json/JsonCreateStringifyTransformer.ts +9 -9
  290. package/src/transformers/features/json/JsonCreateValidateParseTransformer.ts +11 -11
  291. package/src/transformers/features/json/JsonCreateValidateStringifyProgrammer.ts +12 -12
  292. package/src/transformers/features/json/JsonIsParseTransformer.ts +9 -9
  293. package/src/transformers/features/json/JsonIsStringifyTransformer.ts +9 -9
  294. package/src/transformers/features/json/JsonStringifyTransformer.ts +9 -9
  295. package/src/transformers/features/json/JsonValidateParseTransformer.ts +9 -9
  296. package/src/transformers/features/json/JsonValidateStringifyTransformer.ts +10 -10
  297. package/src/transformers/features/misc/MiscAssertCloneTransformer.ts +9 -9
  298. package/src/transformers/features/misc/MiscAssertPruneTransformer.ts +9 -9
  299. package/src/transformers/features/misc/MiscCloneTransformer.ts +9 -9
  300. package/src/transformers/features/misc/MiscCreateAssertCloneTransformer.ts +9 -9
  301. package/src/transformers/features/misc/MiscCreateAssertPruneTransformer.ts +9 -9
  302. package/src/transformers/features/misc/MiscCreateCloneTransformer.ts +9 -9
  303. package/src/transformers/features/misc/MiscCreateIsCloneTransformer.ts +9 -9
  304. package/src/transformers/features/misc/MiscCreateIsPruneTransformer.ts +9 -9
  305. package/src/transformers/features/misc/MiscCreatePruneTransformer.ts +9 -9
  306. package/src/transformers/features/misc/MiscCreateValidateCloneTransformer.ts +11 -11
  307. package/src/transformers/features/misc/MiscCreateValidatePruneTransformer.ts +11 -11
  308. package/src/transformers/features/misc/MiscIsCloneTransformer.ts +9 -9
  309. package/src/transformers/features/misc/MiscIsPruneTransformer.ts +9 -9
  310. package/src/transformers/features/misc/MiscLiteralsTransformer.ts +32 -32
  311. package/src/transformers/features/misc/MiscPruneTransformer.ts +9 -9
  312. package/src/transformers/features/misc/MiscValidateCloneTransformer.ts +9 -9
  313. package/src/transformers/features/misc/MiscValidatePruneTransformer.ts +9 -9
  314. package/src/transformers/features/notations/NotationAssertGeneralTransformer.ts +15 -15
  315. package/src/transformers/features/notations/NotationCreateAssertGeneralTransformer.ts +15 -15
  316. package/src/transformers/features/notations/NotationCreateGeneralTransformer.ts +15 -15
  317. package/src/transformers/features/notations/NotationCreateIsGeneralTransformer.ts +15 -15
  318. package/src/transformers/features/notations/NotationCreateValidateGeneralTransformer.ts +15 -15
  319. package/src/transformers/features/notations/NotationGeneralTransformer.ts +11 -11
  320. package/src/transformers/features/notations/NotationIsGeneralTransformer.ts +15 -15
  321. package/src/transformers/features/notations/NotationValidateGeneralTransformer.ts +15 -15
  322. package/src/transformers/features/protobuf/ProtobufAssertDecodeTransformer.ts +10 -10
  323. package/src/transformers/features/protobuf/ProtobufAssertEncodeTransformer.ts +10 -10
  324. package/src/transformers/features/protobuf/ProtobufCreateAssertDecodeTransformer.ts +12 -12
  325. package/src/transformers/features/protobuf/ProtobufCreateAssertEncodeTransformer.ts +12 -12
  326. package/src/transformers/features/protobuf/ProtobufCreateDecodeTransformer.ts +9 -9
  327. package/src/transformers/features/protobuf/ProtobufCreateEncodeTransformer.ts +9 -9
  328. package/src/transformers/features/protobuf/ProtobufCreateIsDecodeTransformer.ts +9 -9
  329. package/src/transformers/features/protobuf/ProtobufCreateIsEncodeTransformer.ts +9 -9
  330. package/src/transformers/features/protobuf/ProtobufCreateValidateDecodeTransformer.ts +12 -12
  331. package/src/transformers/features/protobuf/ProtobufCreateValidateEncodeTransformer.ts +12 -12
  332. package/src/transformers/features/protobuf/ProtobufDecodeTransformer.ts +9 -9
  333. package/src/transformers/features/protobuf/ProtobufEncodeTransformer.ts +9 -9
  334. package/src/transformers/features/protobuf/ProtobufIsDecodeTransformer.ts +9 -9
  335. package/src/transformers/features/protobuf/ProtobufIsEncodeTransformer.ts +9 -9
  336. package/src/transformers/features/protobuf/ProtobufMessageTransformer.ts +33 -33
  337. package/src/transformers/features/protobuf/ProtobufValidateDecodeTransformer.ts +10 -10
  338. package/src/transformers/features/protobuf/ProtobufValidateEncodeTransformer.ts +10 -10
  339. package/src/transformers/features/reflect/ReflectMetadataTransformer.ts +63 -63
  340. package/src/transformers/internal/GenericTransformer.ts +96 -96
  341. package/src/typings/Atomic.ts +13 -13
  342. package/src/typings/ClassProperties.ts +5 -5
  343. package/src/typings/Customizable.ts +5 -5
  344. package/src/typings/OmitNever.ts +3 -3
  345. package/src/typings/ProtobufAtomic.ts +19 -19
  346. package/src/typings/SpecialFields.ts +3 -3
  347. package/src/typings/ValidationPipe.ts +9 -9
  348. package/src/typings/Writable.ts +11 -11
  349. package/src/utils/ArrayUtil.ts +43 -43
  350. package/src/utils/Escaper.ts +46 -46
  351. package/src/utils/MapUtil.ts +12 -12
  352. package/src/utils/NameEncoder.ts +32 -32
  353. package/src/utils/NamingConvention/NamingConvention.ts +77 -77
  354. package/src/utils/NamingConvention/index.ts +1 -1
  355. package/src/utils/PatternUtil.ts +29 -29
  356. package/src/utils/RandomGenerator/RandomGenerator.ts +74 -74
  357. package/src/utils/RandomGenerator/index.ts +1 -1
  358. package/src/utils/Singleton.ts +16 -16
  359. package/src/utils/StringUtil/StringUtil.ts +2 -2
  360. package/src/utils/StringUtil/index.ts +1 -1
@@ -1,1025 +1,1025 @@
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 { StatementFactory } from "../factories/StatementFactory";
8
- import { TypeFactory } from "../factories/TypeFactory";
9
- import { ValueFactory } from "../factories/ValueFactory";
10
-
11
- import { Metadata } from "../schemas/metadata/Metadata";
12
- import { MetadataArray } from "../schemas/metadata/MetadataArray";
13
- import { MetadataObject } from "../schemas/metadata/MetadataObject";
14
- import { MetadataTuple } from "../schemas/metadata/MetadataTuple";
15
- import { MetadataTupleType } from "../schemas/metadata/MetadataTupleType";
16
-
17
- import { IProject } from "../transformers/IProject";
18
- import { TransformerError } from "../transformers/TransformerError";
19
-
20
- import { FeatureProgrammer } from "./FeatureProgrammer";
21
- import { AtomicPredicator } from "./helpers/AtomicPredicator";
22
- import { FunctionImporter } from "./helpers/FunctionImporeter";
23
- import { ICheckEntry } from "./helpers/ICheckEntry";
24
- import { IExpressionEntry } from "./helpers/IExpressionEntry";
25
- import { OptionPredicator } from "./helpers/OptionPredicator";
26
- import { UnionExplorer } from "./helpers/UnionExplorer";
27
- import { check_array_length } from "./internal/check_array_length";
28
- import { check_bigint } from "./internal/check_bigint";
29
- import { check_native } from "./internal/check_native";
30
- import { check_number } from "./internal/check_number";
31
- import { check_string } from "./internal/check_string";
32
- import { check_template } from "./internal/check_template";
33
- import { decode_union_object } from "./internal/decode_union_object";
34
- import { wrap_metadata_rest_tuple } from "./internal/wrap_metadata_rest_tuple";
35
-
36
- export namespace CheckerProgrammer {
37
- export interface IConfig {
38
- prefix: string;
39
- path: boolean;
40
- trace: boolean;
41
- equals: boolean;
42
- numeric: boolean;
43
- addition?: () => ts.Statement[];
44
- decoder?: () => FeatureProgrammer.Decoder<Metadata, ts.Expression>;
45
- combiner: IConfig.Combiner;
46
- atomist: (
47
- explore: IExplore,
48
- ) => (check: ICheckEntry) => (input: ts.Expression) => ts.Expression;
49
- joiner: IConfig.IJoiner;
50
- success: ts.Expression;
51
- }
52
- export namespace IConfig {
53
- export interface Combiner {
54
- (explorer: IExplore): {
55
- (logic: "and" | "or"): {
56
- (
57
- input: ts.Expression,
58
- binaries: IBinary[],
59
- expected: string,
60
- ): ts.Expression;
61
- };
62
- };
63
- }
64
- export interface IJoiner {
65
- object(input: ts.Expression, entries: IExpressionEntry[]): ts.Expression;
66
- array(input: ts.Expression, arrow: ts.ArrowFunction): ts.Expression;
67
- tuple?: undefined | ((exprs: ts.Expression[]) => ts.Expression);
68
-
69
- failure(
70
- value: ts.Expression,
71
- expected: string,
72
- explore?: undefined | FeatureProgrammer.IExplore,
73
- ): ts.Expression;
74
- is?(expression: ts.Expression): ts.Expression;
75
- required?(exp: ts.Expression): ts.Expression;
76
- full?:
77
- | undefined
78
- | ((
79
- condition: ts.Expression,
80
- ) => (
81
- input: ts.Expression,
82
- expected: string,
83
- explore: IExplore,
84
- ) => ts.Expression);
85
- }
86
- }
87
- export type IExplore = FeatureProgrammer.IExplore;
88
-
89
- export interface IBinary {
90
- expression: ts.Expression;
91
- combined: boolean;
92
- }
93
-
94
- /* -----------------------------------------------------------
95
- WRITERS
96
- ----------------------------------------------------------- */
97
- export const write =
98
- (project: IProject) => (config: IConfig) => (importer: FunctionImporter) =>
99
- FeatureProgrammer.write(project)(configure(project)(config)(importer))(
100
- importer,
101
- );
102
-
103
- export const write_object_functions =
104
- (project: IProject) => (config: IConfig) => (importer: FunctionImporter) =>
105
- FeatureProgrammer.write_object_functions(
106
- configure(project)(config)(importer),
107
- )(importer);
108
-
109
- export const write_union_functions =
110
- (project: IProject) => (config: IConfig) => (importer: FunctionImporter) =>
111
- FeatureProgrammer.write_union_functions(
112
- configure(project)({ ...config, numeric: false })(importer),
113
- );
114
-
115
- export const write_array_functions =
116
- (project: IProject) =>
117
- (config: IConfig) =>
118
- (importer: FunctionImporter) =>
119
- (collection: MetadataCollection): ts.VariableStatement[] =>
120
- collection
121
- .arrays()
122
- .filter((a) => a.recursive)
123
- .map((type, i) =>
124
- StatementFactory.constant(
125
- `${config.prefix}a${i}`,
126
- ts.factory.createArrowFunction(
127
- undefined,
128
- undefined,
129
- FeatureProgrammer.parameterDeclarations(config)(
130
- TypeFactory.keyword("any"),
131
- )(ts.factory.createIdentifier("input")),
132
- TypeFactory.keyword("any"),
133
- undefined,
134
- decode_array_inline(project)(config)(importer)(
135
- ts.factory.createIdentifier("input"),
136
- MetadataArray.create({
137
- type,
138
- tags: [],
139
- }),
140
- {
141
- tracable: config.trace,
142
- source: "function",
143
- from: "array",
144
- postfix: "",
145
- },
146
- ),
147
- ),
148
- ),
149
- );
150
-
151
- export const write_tuple_functions =
152
- (project: IProject) =>
153
- (config: IConfig) =>
154
- (importer: FunctionImporter) =>
155
- (collection: MetadataCollection): ts.VariableStatement[] =>
156
- collection
157
- .tuples()
158
- .filter((t) => t.recursive)
159
- .map((tuple, i) =>
160
- StatementFactory.constant(
161
- `${config.prefix}t${i}`,
162
- ts.factory.createArrowFunction(
163
- undefined,
164
- undefined,
165
- FeatureProgrammer.parameterDeclarations(config)(
166
- TypeFactory.keyword("any"),
167
- )(ts.factory.createIdentifier("input")),
168
- TypeFactory.keyword("any"),
169
- undefined,
170
- decode_tuple_inline(project)(config)(importer)(
171
- ts.factory.createIdentifier("input"),
172
- tuple,
173
- {
174
- tracable: config.trace,
175
- source: "function",
176
- from: "array",
177
- postfix: "",
178
- },
179
- ),
180
- ),
181
- ),
182
- );
183
-
184
- const configure =
185
- (project: IProject) =>
186
- (config: IConfig) =>
187
- (importer: FunctionImporter): FeatureProgrammer.IConfig => ({
188
- types: {
189
- input: () => TypeFactory.keyword("any"),
190
- output: (type, name) =>
191
- ts.factory.createTypePredicateNode(
192
- undefined,
193
- "input",
194
- ts.factory.createTypeReferenceNode(
195
- name ?? TypeFactory.getFullName(project.checker)(type),
196
- ),
197
- ),
198
- },
199
- trace: config.trace,
200
- path: config.path,
201
- prefix: config.prefix,
202
- initializer: (project) => (importer) => (type) => {
203
- const collection: MetadataCollection = new MetadataCollection();
204
- const result = MetadataFactory.analyze(
205
- project.checker,
206
- project.context,
207
- )({
208
- escape: false,
209
- constant: true,
210
- absorb: true,
211
- })(collection)(type);
212
- if (result.success === false)
213
- throw TransformerError.from(`typia.${importer.method}`)(
214
- result.errors,
215
- );
216
- return [collection, result.data];
217
- },
218
- addition: config.addition,
219
- decoder: () => config.decoder?.() ?? decode(project)(config)(importer),
220
- objector: {
221
- checker: () => config.decoder?.() ?? decode(project)(config)(importer),
222
- decoder: () => decode_object(config)(importer),
223
- joiner: config.joiner.object,
224
- unionizer: config.equals
225
- ? decode_union_object(decode_object(config)(importer))(
226
- (input, obj, explore) =>
227
- decode_object(config)(importer)(input, obj, {
228
- ...explore,
229
- tracable: true,
230
- }),
231
- )(config.joiner.is ?? ((expr) => expr))((value, expected) =>
232
- ts.factory.createReturnStatement(
233
- config.joiner.failure(value, expected),
234
- ),
235
- )
236
- : (input, targets, explore) =>
237
- config.combiner(explore)("or")(
238
- input,
239
- targets.map((obj) => ({
240
- expression: decode_object(config)(importer)(
241
- input,
242
- obj,
243
- explore,
244
- ),
245
- combined: true,
246
- })),
247
- `(${targets.map((t) => t.name).join(" | ")})`,
248
- ),
249
- failure: (value, expected) =>
250
- ts.factory.createReturnStatement(
251
- config.joiner.failure(value, expected),
252
- ),
253
- is: config.joiner.is,
254
- required: config.joiner.required,
255
- full: config.joiner.full,
256
- type: TypeFactory.keyword("boolean"),
257
- },
258
- generator: {
259
- unions: config.numeric
260
- ? () =>
261
- FeatureProgrammer.write_union_functions(
262
- configure(project)({ ...config, numeric: false })(importer),
263
- )
264
- : undefined,
265
- arrays: () => write_array_functions(project)(config)(importer),
266
- tuples: () => write_tuple_functions(project)(config)(importer),
267
- },
268
- });
269
-
270
- /* -----------------------------------------------------------
271
- DECODERS
272
- ----------------------------------------------------------- */
273
- /**
274
- * @internal
275
- */
276
- export const decode =
277
- (project: IProject) =>
278
- (config: IConfig) =>
279
- (importer: FunctionImporter) =>
280
- (
281
- input: ts.Expression,
282
- meta: Metadata,
283
- explore: IExplore,
284
- ): ts.Expression => {
285
- if (meta.any) return config.success;
286
-
287
- const top: IBinary[] = [];
288
- const binaries: IBinary[] = [];
289
- const add = create_add(binaries)(input);
290
- const getConstantValue = (value: number | string | bigint | boolean) => {
291
- if (typeof value === "string")
292
- return ts.factory.createStringLiteral(value);
293
- else if (typeof value === "bigint")
294
- return ExpressionFactory.bigint(value);
295
- return ts.factory.createIdentifier(value.toString());
296
- };
297
-
298
- //----
299
- // CHECK OPTIONAL
300
- //----
301
- // @todo -> should be elaborated
302
- const checkOptional: boolean = meta.empty() || meta.isUnionBucket();
303
-
304
- // NULLABLE
305
- if (checkOptional || meta.nullable)
306
- (meta.nullable ? add : create_add(top)(input))(
307
- meta.nullable,
308
- ValueFactory.NULL(),
309
- );
310
-
311
- // UNDEFINDABLE
312
- if (checkOptional || !meta.isRequired())
313
- (meta.isRequired() ? create_add(top)(input) : add)(
314
- !meta.isRequired(),
315
- ValueFactory.UNDEFINED(),
316
- );
317
-
318
- // FUNCTIONAL
319
- if (meta.functional === true)
320
- if (OptionPredicator.functional(project.options) || meta.size() !== 1)
321
- add(
322
- true,
323
- ts.factory.createStringLiteral("function"),
324
- ValueFactory.TYPEOF(input),
325
- );
326
- else
327
- binaries.push({
328
- combined: false,
329
- expression: config.success,
330
- });
331
-
332
- //----
333
- // VALUES
334
- //----
335
- // CONSTANT VALUES
336
- for (const constant of meta.constants)
337
- if (AtomicPredicator.constant(meta)(constant.type))
338
- for (const val of constant.values) add(true, getConstantValue(val));
339
-
340
- // ATOMIC VALUES
341
- for (const atom of meta.atomics)
342
- if (AtomicPredicator.atomic(meta)(atom.type) === false) continue;
343
- else if (atom.type === "number")
344
- binaries.push({
345
- expression: config.atomist(explore)(
346
- check_number(project, config.numeric)(atom)(input),
347
- )(input),
348
- combined: false,
349
- });
350
- else if (atom.type === "bigint")
351
- binaries.push({
352
- expression: config.atomist(explore)(
353
- check_bigint(project)(atom)(input),
354
- )(input),
355
- combined: false,
356
- });
357
- else if (atom.type === "string")
358
- binaries.push({
359
- expression: config.atomist(explore)(
360
- check_string(project)(atom)(input),
361
- )(input),
362
- combined: false,
363
- });
364
- else
365
- add(
366
- true,
367
- ts.factory.createStringLiteral(atom.type),
368
- ValueFactory.TYPEOF(input),
369
- );
370
-
371
- // TEMPLATE LITERAL VALUES
372
- if (meta.templates.length)
373
- if (AtomicPredicator.template(meta))
374
- binaries.push({
375
- expression: config.atomist(explore)(
376
- check_template(meta.templates)(input),
377
- )(input),
378
- combined: false,
379
- });
380
-
381
- // NATIVE CLASSES
382
- for (const native of meta.natives)
383
- binaries.push({
384
- expression: check_native(native)(input),
385
- combined: false,
386
- });
387
-
388
- //----
389
- // INSTANCES
390
- //----
391
- interface IInstance {
392
- pre: ts.Expression;
393
- body: ts.Expression | null;
394
- expected: string;
395
- }
396
- const instances: IInstance[] = [];
397
- const prepare =
398
- (pre: ts.Expression, expected: string) =>
399
- (body: ts.Expression | null) =>
400
- instances.push({
401
- pre,
402
- expected,
403
- body,
404
- });
405
-
406
- // SETS
407
- if (meta.sets.length) {
408
- const install = prepare(
409
- check_native("Set")(input),
410
- meta.sets.map((elem) => `Set<${elem.getName()}>`).join(" | "),
411
- );
412
- if (meta.sets.some((elem) => elem.any)) install(null);
413
- else
414
- install(
415
- explore_sets(project)(config)(importer)(input, meta.sets, {
416
- ...explore,
417
- from: "array",
418
- }),
419
- );
420
- }
421
-
422
- // MAPS
423
- if (meta.maps.length) {
424
- const install = prepare(
425
- check_native("Map")(input),
426
- meta.maps
427
- .map(({ key, value }) => `Map<${key}, ${value}>`)
428
- .join(" | "),
429
- );
430
- if (meta.maps.some((elem) => elem.key.any && elem.value.any))
431
- install(null);
432
- else
433
- install(
434
- explore_maps(project)(config)(importer)(input, meta.maps, {
435
- ...explore,
436
- from: "array",
437
- }),
438
- );
439
- }
440
-
441
- // ARRAYS AND TUPLES
442
- if (meta.tuples.length + meta.arrays.length > 0) {
443
- const install = prepare(
444
- config.atomist(explore)({
445
- expected: [
446
- ...meta.tuples.map((t) => t.type.name),
447
- ...meta.arrays.map((a) => a.getName()),
448
- ].join(" | "),
449
- expression: ExpressionFactory.isArray(input),
450
- conditions: [],
451
- })(input),
452
- [...meta.tuples, ...meta.arrays]
453
- .map((elem) => elem.type.name)
454
- .join(" | "),
455
- );
456
- if (meta.arrays.length === 0)
457
- if (meta.tuples.length === 1)
458
- install(
459
- decode_tuple(project)(config)(importer)(input, meta.tuples[0]!, {
460
- ...explore,
461
- from: "array",
462
- }),
463
- );
464
- // TUPLE ONLY
465
- else
466
- install(
467
- explore_tuples(project)(config)(importer)(input, meta.tuples, {
468
- ...explore,
469
- from: "array",
470
- }),
471
- );
472
- else if (meta.arrays.some((elem) => elem.type.value.any)) install(null);
473
- else if (meta.tuples.length === 0)
474
- if (meta.arrays.length === 1)
475
- // ARRAY ONLY
476
- install(
477
- decode_array(project)(config)(importer)(input, meta.arrays[0]!, {
478
- ...explore,
479
- from: "array",
480
- }),
481
- );
482
- else
483
- install(
484
- explore_arrays(project)(config)(importer)(input, meta.arrays, {
485
- ...explore,
486
- from: "array",
487
- }),
488
- );
489
- else
490
- install(
491
- explore_arrays_and_tuples(project)(config)(importer)(
492
- input,
493
- [...meta.tuples, ...meta.arrays],
494
- explore,
495
- ),
496
- );
497
- }
498
-
499
- // OBJECT
500
- if (meta.objects.length > 0)
501
- prepare(
502
- ExpressionFactory.isObject({
503
- checkNull: true,
504
- checkArray: meta.objects.some((obj) =>
505
- obj.properties.every(
506
- (prop) => !prop.key.isSoleLiteral() || !prop.value.isRequired(),
507
- ),
508
- ),
509
- })(input),
510
- meta.objects.map((obj) => obj.name).join(" | "),
511
- )(
512
- explore_objects(config)(importer)(input, meta, {
513
- ...explore,
514
- from: "object",
515
- }),
516
- );
517
-
518
- if (instances.length) {
519
- const transformer =
520
- (merger: (x: ts.Expression, y: ts.Expression) => ts.Expression) =>
521
- (ins: IInstance) =>
522
- ins.body
523
- ? {
524
- expression: merger(ins.pre, ins.body),
525
- combined: true,
526
- }
527
- : {
528
- expression: ins.pre,
529
- combined: false,
530
- };
531
- if (instances.length === 1)
532
- binaries.push(
533
- transformer((pre, body) =>
534
- config.combiner(explore)("and")(
535
- input,
536
- [pre, body].map((expression) => ({
537
- expression,
538
- combined: expression !== pre,
539
- })),
540
- meta.getName(),
541
- ),
542
- )(instances[0]!),
543
- );
544
- else
545
- binaries.push({
546
- expression: config.combiner(explore)("or")(
547
- input,
548
- instances.map(transformer(ts.factory.createLogicalAnd)),
549
- meta.getName(),
550
- ),
551
- combined: true,
552
- });
553
- }
554
-
555
- //----
556
- // COMBINE CONDITIONS
557
- //----
558
- return top.length && binaries.length
559
- ? config.combiner(explore)("and")(
560
- input,
561
- [
562
- ...top,
563
- {
564
- expression: config.combiner(explore)("or")(
565
- input,
566
- binaries,
567
- meta.getName(),
568
- ),
569
- combined: true,
570
- },
571
- ],
572
- meta.getName(),
573
- )
574
- : binaries.length
575
- ? config.combiner(explore)("or")(input, binaries, meta.getName())
576
- : config.success;
577
- };
578
-
579
- export const decode_object =
580
- (config: IConfig) => (importer: FunctionImporter) => {
581
- const func = FeatureProgrammer.decode_object(config)(importer);
582
- return (input: ts.Expression, obj: MetadataObject, explore: IExplore) => {
583
- obj.validated = true;
584
- return func(input, obj, explore);
585
- };
586
- };
587
-
588
- const decode_array =
589
- (project: IProject) =>
590
- (config: IConfig) =>
591
- (importer: FunctionImporter) =>
592
- (input: ts.Expression, array: MetadataArray, explore: IExplore) => {
593
- if (array.type.recursive === false)
594
- return decode_array_inline(project)(config)(importer)(
595
- input,
596
- array,
597
- explore,
598
- );
599
-
600
- explore = {
601
- ...explore,
602
- source: "function",
603
- from: "array",
604
- };
605
- return ts.factory.createLogicalOr(
606
- ts.factory.createCallExpression(
607
- ts.factory.createIdentifier(
608
- importer.useLocal(`${config.prefix}a${array.type.index}`),
609
- ),
610
- undefined,
611
- FeatureProgrammer.argumentsArray(config)({
612
- ...explore,
613
- source: "function",
614
- from: "array",
615
- })(input),
616
- ),
617
- config.joiner.failure(input, array.type.name, explore),
618
- );
619
- };
620
-
621
- const decode_array_inline =
622
- (project: IProject) =>
623
- (config: IConfig) =>
624
- (importer: FunctionImporter) =>
625
- (
626
- input: ts.Expression,
627
- array: MetadataArray,
628
- explore: IExplore,
629
- ): ts.Expression => {
630
- const length = check_array_length(project)(array)(input);
631
- const main = FeatureProgrammer.decode_array({
632
- prefix: config.prefix,
633
- trace: config.trace,
634
- path: config.path,
635
- decoder: () => decode(project)(config)(importer),
636
- })(importer)(config.joiner.array)(input, array, explore);
637
- return length.expression === null && length.conditions.length === 0
638
- ? main
639
- : ts.factory.createLogicalAnd(
640
- config.atomist(explore)(length)(input),
641
- main,
642
- );
643
- };
644
-
645
- const decode_tuple =
646
- (project: IProject) =>
647
- (config: IConfig) =>
648
- (importer: FunctionImporter) =>
649
- (
650
- input: ts.Expression,
651
- tuple: MetadataTuple,
652
- explore: IExplore,
653
- ): ts.Expression => {
654
- if (tuple.type.recursive === false)
655
- return decode_tuple_inline(project)(config)(importer)(
656
- input,
657
- tuple.type,
658
- explore,
659
- );
660
- explore = {
661
- ...explore,
662
- source: "function",
663
- from: "array",
664
- };
665
- return ts.factory.createLogicalOr(
666
- ts.factory.createCallExpression(
667
- ts.factory.createIdentifier(
668
- importer.useLocal(`${config.prefix}t${tuple.type.index}`),
669
- ),
670
- undefined,
671
- FeatureProgrammer.argumentsArray(config)({
672
- ...explore,
673
- source: "function",
674
- })(input),
675
- ),
676
- config.joiner.failure(input, tuple.type.name, explore),
677
- );
678
- };
679
-
680
- const decode_tuple_inline =
681
- (project: IProject) =>
682
- (config: IConfig) =>
683
- (importer: FunctionImporter) =>
684
- (
685
- input: ts.Expression,
686
- tuple: MetadataTupleType,
687
- explore: IExplore,
688
- ): ts.Expression => {
689
- const binaries: ts.Expression[] = tuple.elements
690
- .filter((meta) => meta.rest === null)
691
- .map((meta, index) =>
692
- decode(project)(config)(importer)(
693
- ts.factory.createElementAccessExpression(input, index),
694
- meta,
695
- {
696
- ...explore,
697
- from: "array",
698
- postfix: explore.postfix.length
699
- ? `${explore.postfix.slice(0, -1)}[${index}]"`
700
- : `"[${index}]"`,
701
- },
702
- ),
703
- );
704
- const rest: ts.Expression | null =
705
- tuple.elements.length && tuple.elements.at(-1)!.rest !== null
706
- ? decode(project)(config)(importer)(
707
- ts.factory.createCallExpression(
708
- IdentifierFactory.access(input)("slice"),
709
- undefined,
710
- [ExpressionFactory.number(tuple.elements.length - 1)],
711
- ),
712
- wrap_metadata_rest_tuple(tuple.elements.at(-1)!.rest!),
713
- {
714
- ...explore,
715
- start: tuple.elements.length - 1,
716
- },
717
- )
718
- : null;
719
-
720
- const arrayLength = ts.factory.createPropertyAccessExpression(
721
- input,
722
- "length",
723
- );
724
- return config.combiner(explore)("and")(
725
- input,
726
- [
727
- ...(rest === null
728
- ? tuple.elements.every((t) => t.optional === false)
729
- ? [
730
- {
731
- combined: false,
732
- expression: ts.factory.createStrictEquality(
733
- arrayLength,
734
- ExpressionFactory.number(tuple.elements.length),
735
- ),
736
- },
737
- ]
738
- : [
739
- {
740
- combined: false,
741
- expression: ts.factory.createLogicalAnd(
742
- ts.factory.createLessThanEquals(
743
- ExpressionFactory.number(
744
- tuple.elements.filter((t) => t.optional === false)
745
- .length,
746
- ),
747
- arrayLength,
748
- ),
749
- ts.factory.createGreaterThanEquals(
750
- ExpressionFactory.number(tuple.elements.length),
751
- arrayLength,
752
- ),
753
- ),
754
- },
755
- ]
756
- : []),
757
- ...(config.joiner.tuple
758
- ? [
759
- {
760
- expression: config.joiner.tuple(binaries),
761
- combined: true,
762
- },
763
- ]
764
- : binaries.map((expression) => ({
765
- expression,
766
- combined: true,
767
- }))),
768
- ...(rest !== null
769
- ? [
770
- {
771
- expression: rest,
772
- combined: true,
773
- },
774
- ]
775
- : []),
776
- ],
777
- `[${tuple.elements.map((t) => t.getName()).join(", ")}]`,
778
- );
779
- };
780
-
781
- /* -----------------------------------------------------------
782
- UNION TYPE EXPLORERS
783
- ----------------------------------------------------------- */
784
- const explore_sets =
785
- (project: IProject) =>
786
- (config: IConfig) =>
787
- (importer: FunctionImporter) =>
788
- (
789
- input: ts.Expression,
790
- sets: Metadata[],
791
- explore: IExplore,
792
- ): ts.Expression =>
793
- ts.factory.createCallExpression(
794
- UnionExplorer.set({
795
- checker: decode(project)(config)(importer),
796
- decoder: decode_array(project)(config)(importer),
797
- empty: config.success,
798
- success: config.success,
799
- failure: (input, expected, explore) =>
800
- ts.factory.createReturnStatement(
801
- config.joiner.failure(input, expected, explore),
802
- ),
803
- })([])(input, sets, explore),
804
- undefined,
805
- undefined,
806
- );
807
-
808
- const explore_maps =
809
- (project: IProject) =>
810
- (config: IConfig) =>
811
- (importer: FunctionImporter) =>
812
- (
813
- input: ts.Expression,
814
- maps: Metadata.Entry[],
815
- explore: IExplore,
816
- ): ts.Expression =>
817
- ts.factory.createCallExpression(
818
- UnionExplorer.map({
819
- checker: (input, entry, explore) => {
820
- const func = decode(project)(config)(importer);
821
- return ts.factory.createLogicalAnd(
822
- func(
823
- ts.factory.createElementAccessExpression(input, 0),
824
- entry[0],
825
- {
826
- ...explore,
827
- postfix: `${explore.postfix}[0]`,
828
- },
829
- ),
830
- func(
831
- ts.factory.createElementAccessExpression(input, 1),
832
- entry[1],
833
- {
834
- ...explore,
835
- postfix: `${explore.postfix}[1]`,
836
- },
837
- ),
838
- );
839
- },
840
- decoder: decode_array(project)(config)(importer),
841
- empty: config.success,
842
- success: config.success,
843
- failure: (input, expected, explore) =>
844
- ts.factory.createReturnStatement(
845
- config.joiner.failure(input, expected, explore),
846
- ),
847
- })([])(input, maps, explore),
848
- undefined,
849
- undefined,
850
- );
851
-
852
- const explore_tuples =
853
- (project: IProject) =>
854
- (config: IConfig) =>
855
- (importer: FunctionImporter) =>
856
- (
857
- input: ts.Expression,
858
- tuples: MetadataTuple[],
859
- explore: IExplore,
860
- ): ts.Expression =>
861
- explore_array_like_union_types(config)(importer)(
862
- UnionExplorer.tuple({
863
- checker: decode_tuple(project)(config)(importer),
864
- decoder: decode_tuple(project)(config)(importer),
865
- empty: config.success,
866
- success: config.success,
867
- failure: (input, expected, explore) =>
868
- ts.factory.createReturnStatement(
869
- config.joiner.failure(input, expected, explore),
870
- ),
871
- }),
872
- )(input, tuples, explore);
873
-
874
- const explore_arrays =
875
- (project: IProject) =>
876
- (config: IConfig) =>
877
- (importer: FunctionImporter) =>
878
- (
879
- input: ts.Expression,
880
- arrays: MetadataArray[],
881
- explore: IExplore,
882
- ): ts.Expression =>
883
- explore_array_like_union_types(config)(importer)(
884
- UnionExplorer.array({
885
- checker: decode(project)(config)(importer),
886
- decoder: decode_array(project)(config)(importer),
887
- empty: config.success,
888
- success: config.success,
889
- failure: (input, expected, explore) =>
890
- ts.factory.createReturnStatement(
891
- config.joiner.failure(input, expected, explore),
892
- ),
893
- }),
894
- )(input, arrays, explore);
895
-
896
- const explore_arrays_and_tuples =
897
- (project: IProject) =>
898
- (config: IConfig) =>
899
- (importer: FunctionImporter) =>
900
- (
901
- input: ts.Expression,
902
- elements: Array<MetadataArray | MetadataTuple>,
903
- explore: IExplore,
904
- ): ts.Expression =>
905
- explore_array_like_union_types(config)(importer)(
906
- UnionExplorer.array_or_tuple({
907
- checker: (front, target, explore, array) =>
908
- target instanceof MetadataTuple
909
- ? decode_tuple(project)(config)(importer)(front, target, explore)
910
- : config.atomist(explore)({
911
- expected: elements
912
- .map((elem) =>
913
- elem instanceof MetadataArray
914
- ? elem.getName()
915
- : elem.type.name,
916
- )
917
- .join(" | "),
918
- expression: decode(project)(config)(importer)(
919
- front,
920
- target,
921
- explore,
922
- ),
923
- conditions: [],
924
- })(array),
925
- decoder: (input, target, explore) =>
926
- target instanceof MetadataTuple
927
- ? decode_tuple(project)(config)(importer)(input, target, explore)
928
- : decode_array(project)(config)(importer)(input, target, explore),
929
- empty: config.success,
930
- success: config.success,
931
- failure: (input, expected, explore) =>
932
- ts.factory.createReturnStatement(
933
- config.joiner.failure(input, expected, explore),
934
- ),
935
- }),
936
- )(input, elements, explore);
937
-
938
- const explore_array_like_union_types =
939
- (config: IConfig) =>
940
- (importer: FunctionImporter) =>
941
- <T extends MetadataArray | MetadataTuple>(
942
- factory: (
943
- parameters: ts.ParameterDeclaration[],
944
- ) => (
945
- input: ts.Expression,
946
- elements: T[],
947
- explore: IExplore,
948
- ) => ts.ArrowFunction,
949
- ) =>
950
- (input: ts.Expression, elements: T[], explore: IExplore): ts.Expression => {
951
- const arrow =
952
- (parameters: ts.ParameterDeclaration[]) =>
953
- (explore: IExplore) =>
954
- (input: ts.Expression): ts.ArrowFunction =>
955
- factory(parameters)(input, elements, explore);
956
- if (elements.every((e) => e.type.recursive === false))
957
- ts.factory.createCallExpression(
958
- arrow([])(explore)(input),
959
- undefined,
960
- [],
961
- );
962
- explore = {
963
- ...explore,
964
- source: "function",
965
- from: "array",
966
- };
967
- return ts.factory.createLogicalOr(
968
- ts.factory.createCallExpression(
969
- ts.factory.createIdentifier(
970
- importer.emplaceUnion(
971
- config.prefix,
972
- elements.map((e) => e.type.name).join(" | "),
973
- () =>
974
- arrow(
975
- FeatureProgrammer.parameterDeclarations(config)(
976
- TypeFactory.keyword("any"),
977
- )(ts.factory.createIdentifier("input")),
978
- )({
979
- ...explore,
980
- postfix: "",
981
- })(ts.factory.createIdentifier("input")),
982
- ),
983
- ),
984
- undefined,
985
- FeatureProgrammer.argumentsArray(config)(explore)(input),
986
- ),
987
- config.joiner.failure(
988
- input,
989
- elements.map((e) => e.type.name).join(" | "),
990
- explore,
991
- ),
992
- );
993
- };
994
-
995
- const explore_objects =
996
- (config: IConfig) =>
997
- (importer: FunctionImporter) =>
998
- (input: ts.Expression, meta: Metadata, explore: IExplore) =>
999
- meta.objects.length === 1
1000
- ? decode_object(config)(importer)(input, meta.objects[0]!, explore)
1001
- : ts.factory.createCallExpression(
1002
- ts.factory.createIdentifier(
1003
- importer.useLocal(`${config.prefix}u${meta.union_index!}`),
1004
- ),
1005
- undefined,
1006
- FeatureProgrammer.argumentsArray(config)(explore)(input),
1007
- );
1008
- }
1009
-
1010
- const create_add =
1011
- (binaries: CheckerProgrammer.IBinary[]) =>
1012
- (defaultInput: ts.Expression) =>
1013
- (
1014
- exact: boolean,
1015
- left: ts.Expression,
1016
- right: ts.Expression = defaultInput,
1017
- ) => {
1018
- const factory = exact
1019
- ? ts.factory.createStrictEquality
1020
- : ts.factory.createStrictInequality;
1021
- binaries.push({
1022
- expression: factory(left, right),
1023
- combined: false,
1024
- });
1025
- };
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 { StatementFactory } from "../factories/StatementFactory";
8
+ import { TypeFactory } from "../factories/TypeFactory";
9
+ import { ValueFactory } from "../factories/ValueFactory";
10
+
11
+ import { Metadata } from "../schemas/metadata/Metadata";
12
+ import { MetadataArray } from "../schemas/metadata/MetadataArray";
13
+ import { MetadataObject } from "../schemas/metadata/MetadataObject";
14
+ import { MetadataTuple } from "../schemas/metadata/MetadataTuple";
15
+ import { MetadataTupleType } from "../schemas/metadata/MetadataTupleType";
16
+
17
+ import { IProject } from "../transformers/IProject";
18
+ import { TransformerError } from "../transformers/TransformerError";
19
+
20
+ import { FeatureProgrammer } from "./FeatureProgrammer";
21
+ import { AtomicPredicator } from "./helpers/AtomicPredicator";
22
+ import { FunctionImporter } from "./helpers/FunctionImporeter";
23
+ import { ICheckEntry } from "./helpers/ICheckEntry";
24
+ import { IExpressionEntry } from "./helpers/IExpressionEntry";
25
+ import { OptionPredicator } from "./helpers/OptionPredicator";
26
+ import { UnionExplorer } from "./helpers/UnionExplorer";
27
+ import { check_array_length } from "./internal/check_array_length";
28
+ import { check_bigint } from "./internal/check_bigint";
29
+ import { check_native } from "./internal/check_native";
30
+ import { check_number } from "./internal/check_number";
31
+ import { check_string } from "./internal/check_string";
32
+ import { check_template } from "./internal/check_template";
33
+ import { decode_union_object } from "./internal/decode_union_object";
34
+ import { wrap_metadata_rest_tuple } from "./internal/wrap_metadata_rest_tuple";
35
+
36
+ export namespace CheckerProgrammer {
37
+ export interface IConfig {
38
+ prefix: string;
39
+ path: boolean;
40
+ trace: boolean;
41
+ equals: boolean;
42
+ numeric: boolean;
43
+ addition?: () => ts.Statement[];
44
+ decoder?: () => FeatureProgrammer.Decoder<Metadata, ts.Expression>;
45
+ combiner: IConfig.Combiner;
46
+ atomist: (
47
+ explore: IExplore,
48
+ ) => (check: ICheckEntry) => (input: ts.Expression) => ts.Expression;
49
+ joiner: IConfig.IJoiner;
50
+ success: ts.Expression;
51
+ }
52
+ export namespace IConfig {
53
+ export interface Combiner {
54
+ (explorer: IExplore): {
55
+ (logic: "and" | "or"): {
56
+ (
57
+ input: ts.Expression,
58
+ binaries: IBinary[],
59
+ expected: string,
60
+ ): ts.Expression;
61
+ };
62
+ };
63
+ }
64
+ export interface IJoiner {
65
+ object(input: ts.Expression, entries: IExpressionEntry[]): ts.Expression;
66
+ array(input: ts.Expression, arrow: ts.ArrowFunction): ts.Expression;
67
+ tuple?: undefined | ((exprs: ts.Expression[]) => ts.Expression);
68
+
69
+ failure(
70
+ value: ts.Expression,
71
+ expected: string,
72
+ explore?: undefined | FeatureProgrammer.IExplore,
73
+ ): ts.Expression;
74
+ is?(expression: ts.Expression): ts.Expression;
75
+ required?(exp: ts.Expression): ts.Expression;
76
+ full?:
77
+ | undefined
78
+ | ((
79
+ condition: ts.Expression,
80
+ ) => (
81
+ input: ts.Expression,
82
+ expected: string,
83
+ explore: IExplore,
84
+ ) => ts.Expression);
85
+ }
86
+ }
87
+ export type IExplore = FeatureProgrammer.IExplore;
88
+
89
+ export interface IBinary {
90
+ expression: ts.Expression;
91
+ combined: boolean;
92
+ }
93
+
94
+ /* -----------------------------------------------------------
95
+ WRITERS
96
+ ----------------------------------------------------------- */
97
+ export const write =
98
+ (project: IProject) => (config: IConfig) => (importer: FunctionImporter) =>
99
+ FeatureProgrammer.write(project)(configure(project)(config)(importer))(
100
+ importer,
101
+ );
102
+
103
+ export const write_object_functions =
104
+ (project: IProject) => (config: IConfig) => (importer: FunctionImporter) =>
105
+ FeatureProgrammer.write_object_functions(
106
+ configure(project)(config)(importer),
107
+ )(importer);
108
+
109
+ export const write_union_functions =
110
+ (project: IProject) => (config: IConfig) => (importer: FunctionImporter) =>
111
+ FeatureProgrammer.write_union_functions(
112
+ configure(project)({ ...config, numeric: false })(importer),
113
+ );
114
+
115
+ export const write_array_functions =
116
+ (project: IProject) =>
117
+ (config: IConfig) =>
118
+ (importer: FunctionImporter) =>
119
+ (collection: MetadataCollection): ts.VariableStatement[] =>
120
+ collection
121
+ .arrays()
122
+ .filter((a) => a.recursive)
123
+ .map((type, i) =>
124
+ StatementFactory.constant(
125
+ `${config.prefix}a${i}`,
126
+ ts.factory.createArrowFunction(
127
+ undefined,
128
+ undefined,
129
+ FeatureProgrammer.parameterDeclarations(config)(
130
+ TypeFactory.keyword("any"),
131
+ )(ts.factory.createIdentifier("input")),
132
+ TypeFactory.keyword("any"),
133
+ undefined,
134
+ decode_array_inline(project)(config)(importer)(
135
+ ts.factory.createIdentifier("input"),
136
+ MetadataArray.create({
137
+ type,
138
+ tags: [],
139
+ }),
140
+ {
141
+ tracable: config.trace,
142
+ source: "function",
143
+ from: "array",
144
+ postfix: "",
145
+ },
146
+ ),
147
+ ),
148
+ ),
149
+ );
150
+
151
+ export const write_tuple_functions =
152
+ (project: IProject) =>
153
+ (config: IConfig) =>
154
+ (importer: FunctionImporter) =>
155
+ (collection: MetadataCollection): ts.VariableStatement[] =>
156
+ collection
157
+ .tuples()
158
+ .filter((t) => t.recursive)
159
+ .map((tuple, i) =>
160
+ StatementFactory.constant(
161
+ `${config.prefix}t${i}`,
162
+ ts.factory.createArrowFunction(
163
+ undefined,
164
+ undefined,
165
+ FeatureProgrammer.parameterDeclarations(config)(
166
+ TypeFactory.keyword("any"),
167
+ )(ts.factory.createIdentifier("input")),
168
+ TypeFactory.keyword("any"),
169
+ undefined,
170
+ decode_tuple_inline(project)(config)(importer)(
171
+ ts.factory.createIdentifier("input"),
172
+ tuple,
173
+ {
174
+ tracable: config.trace,
175
+ source: "function",
176
+ from: "array",
177
+ postfix: "",
178
+ },
179
+ ),
180
+ ),
181
+ ),
182
+ );
183
+
184
+ const configure =
185
+ (project: IProject) =>
186
+ (config: IConfig) =>
187
+ (importer: FunctionImporter): FeatureProgrammer.IConfig => ({
188
+ types: {
189
+ input: () => TypeFactory.keyword("any"),
190
+ output: (type, name) =>
191
+ ts.factory.createTypePredicateNode(
192
+ undefined,
193
+ "input",
194
+ ts.factory.createTypeReferenceNode(
195
+ name ?? TypeFactory.getFullName(project.checker)(type),
196
+ ),
197
+ ),
198
+ },
199
+ trace: config.trace,
200
+ path: config.path,
201
+ prefix: config.prefix,
202
+ initializer: (project) => (importer) => (type) => {
203
+ const collection: MetadataCollection = new MetadataCollection();
204
+ const result = MetadataFactory.analyze(
205
+ project.checker,
206
+ project.context,
207
+ )({
208
+ escape: false,
209
+ constant: true,
210
+ absorb: true,
211
+ })(collection)(type);
212
+ if (result.success === false)
213
+ throw TransformerError.from(`typia.${importer.method}`)(
214
+ result.errors,
215
+ );
216
+ return [collection, result.data];
217
+ },
218
+ addition: config.addition,
219
+ decoder: () => config.decoder?.() ?? decode(project)(config)(importer),
220
+ objector: {
221
+ checker: () => config.decoder?.() ?? decode(project)(config)(importer),
222
+ decoder: () => decode_object(config)(importer),
223
+ joiner: config.joiner.object,
224
+ unionizer: config.equals
225
+ ? decode_union_object(decode_object(config)(importer))(
226
+ (input, obj, explore) =>
227
+ decode_object(config)(importer)(input, obj, {
228
+ ...explore,
229
+ tracable: true,
230
+ }),
231
+ )(config.joiner.is ?? ((expr) => expr))((value, expected) =>
232
+ ts.factory.createReturnStatement(
233
+ config.joiner.failure(value, expected),
234
+ ),
235
+ )
236
+ : (input, targets, explore) =>
237
+ config.combiner(explore)("or")(
238
+ input,
239
+ targets.map((obj) => ({
240
+ expression: decode_object(config)(importer)(
241
+ input,
242
+ obj,
243
+ explore,
244
+ ),
245
+ combined: true,
246
+ })),
247
+ `(${targets.map((t) => t.name).join(" | ")})`,
248
+ ),
249
+ failure: (value, expected) =>
250
+ ts.factory.createReturnStatement(
251
+ config.joiner.failure(value, expected),
252
+ ),
253
+ is: config.joiner.is,
254
+ required: config.joiner.required,
255
+ full: config.joiner.full,
256
+ type: TypeFactory.keyword("boolean"),
257
+ },
258
+ generator: {
259
+ unions: config.numeric
260
+ ? () =>
261
+ FeatureProgrammer.write_union_functions(
262
+ configure(project)({ ...config, numeric: false })(importer),
263
+ )
264
+ : undefined,
265
+ arrays: () => write_array_functions(project)(config)(importer),
266
+ tuples: () => write_tuple_functions(project)(config)(importer),
267
+ },
268
+ });
269
+
270
+ /* -----------------------------------------------------------
271
+ DECODERS
272
+ ----------------------------------------------------------- */
273
+ /**
274
+ * @internal
275
+ */
276
+ export const decode =
277
+ (project: IProject) =>
278
+ (config: IConfig) =>
279
+ (importer: FunctionImporter) =>
280
+ (
281
+ input: ts.Expression,
282
+ meta: Metadata,
283
+ explore: IExplore,
284
+ ): ts.Expression => {
285
+ if (meta.any) return config.success;
286
+
287
+ const top: IBinary[] = [];
288
+ const binaries: IBinary[] = [];
289
+ const add = create_add(binaries)(input);
290
+ const getConstantValue = (value: number | string | bigint | boolean) => {
291
+ if (typeof value === "string")
292
+ return ts.factory.createStringLiteral(value);
293
+ else if (typeof value === "bigint")
294
+ return ExpressionFactory.bigint(value);
295
+ return ts.factory.createIdentifier(value.toString());
296
+ };
297
+
298
+ //----
299
+ // CHECK OPTIONAL
300
+ //----
301
+ // @todo -> should be elaborated
302
+ const checkOptional: boolean = meta.empty() || meta.isUnionBucket();
303
+
304
+ // NULLABLE
305
+ if (checkOptional || meta.nullable)
306
+ (meta.nullable ? add : create_add(top)(input))(
307
+ meta.nullable,
308
+ ValueFactory.NULL(),
309
+ );
310
+
311
+ // UNDEFINDABLE
312
+ if (checkOptional || !meta.isRequired())
313
+ (meta.isRequired() ? create_add(top)(input) : add)(
314
+ !meta.isRequired(),
315
+ ValueFactory.UNDEFINED(),
316
+ );
317
+
318
+ // FUNCTIONAL
319
+ if (meta.functional === true)
320
+ if (OptionPredicator.functional(project.options) || meta.size() !== 1)
321
+ add(
322
+ true,
323
+ ts.factory.createStringLiteral("function"),
324
+ ValueFactory.TYPEOF(input),
325
+ );
326
+ else
327
+ binaries.push({
328
+ combined: false,
329
+ expression: config.success,
330
+ });
331
+
332
+ //----
333
+ // VALUES
334
+ //----
335
+ // CONSTANT VALUES
336
+ for (const constant of meta.constants)
337
+ if (AtomicPredicator.constant(meta)(constant.type))
338
+ for (const val of constant.values) add(true, getConstantValue(val));
339
+
340
+ // ATOMIC VALUES
341
+ for (const atom of meta.atomics)
342
+ if (AtomicPredicator.atomic(meta)(atom.type) === false) continue;
343
+ else if (atom.type === "number")
344
+ binaries.push({
345
+ expression: config.atomist(explore)(
346
+ check_number(project, config.numeric)(atom)(input),
347
+ )(input),
348
+ combined: false,
349
+ });
350
+ else if (atom.type === "bigint")
351
+ binaries.push({
352
+ expression: config.atomist(explore)(
353
+ check_bigint(project)(atom)(input),
354
+ )(input),
355
+ combined: false,
356
+ });
357
+ else if (atom.type === "string")
358
+ binaries.push({
359
+ expression: config.atomist(explore)(
360
+ check_string(project)(atom)(input),
361
+ )(input),
362
+ combined: false,
363
+ });
364
+ else
365
+ add(
366
+ true,
367
+ ts.factory.createStringLiteral(atom.type),
368
+ ValueFactory.TYPEOF(input),
369
+ );
370
+
371
+ // TEMPLATE LITERAL VALUES
372
+ if (meta.templates.length)
373
+ if (AtomicPredicator.template(meta))
374
+ binaries.push({
375
+ expression: config.atomist(explore)(
376
+ check_template(meta.templates)(input),
377
+ )(input),
378
+ combined: false,
379
+ });
380
+
381
+ // NATIVE CLASSES
382
+ for (const native of meta.natives)
383
+ binaries.push({
384
+ expression: check_native(native)(input),
385
+ combined: false,
386
+ });
387
+
388
+ //----
389
+ // INSTANCES
390
+ //----
391
+ interface IInstance {
392
+ pre: ts.Expression;
393
+ body: ts.Expression | null;
394
+ expected: string;
395
+ }
396
+ const instances: IInstance[] = [];
397
+ const prepare =
398
+ (pre: ts.Expression, expected: string) =>
399
+ (body: ts.Expression | null) =>
400
+ instances.push({
401
+ pre,
402
+ expected,
403
+ body,
404
+ });
405
+
406
+ // SETS
407
+ if (meta.sets.length) {
408
+ const install = prepare(
409
+ check_native("Set")(input),
410
+ meta.sets.map((elem) => `Set<${elem.getName()}>`).join(" | "),
411
+ );
412
+ if (meta.sets.some((elem) => elem.any)) install(null);
413
+ else
414
+ install(
415
+ explore_sets(project)(config)(importer)(input, meta.sets, {
416
+ ...explore,
417
+ from: "array",
418
+ }),
419
+ );
420
+ }
421
+
422
+ // MAPS
423
+ if (meta.maps.length) {
424
+ const install = prepare(
425
+ check_native("Map")(input),
426
+ meta.maps
427
+ .map(({ key, value }) => `Map<${key}, ${value}>`)
428
+ .join(" | "),
429
+ );
430
+ if (meta.maps.some((elem) => elem.key.any && elem.value.any))
431
+ install(null);
432
+ else
433
+ install(
434
+ explore_maps(project)(config)(importer)(input, meta.maps, {
435
+ ...explore,
436
+ from: "array",
437
+ }),
438
+ );
439
+ }
440
+
441
+ // ARRAYS AND TUPLES
442
+ if (meta.tuples.length + meta.arrays.length > 0) {
443
+ const install = prepare(
444
+ config.atomist(explore)({
445
+ expected: [
446
+ ...meta.tuples.map((t) => t.type.name),
447
+ ...meta.arrays.map((a) => a.getName()),
448
+ ].join(" | "),
449
+ expression: ExpressionFactory.isArray(input),
450
+ conditions: [],
451
+ })(input),
452
+ [...meta.tuples, ...meta.arrays]
453
+ .map((elem) => elem.type.name)
454
+ .join(" | "),
455
+ );
456
+ if (meta.arrays.length === 0)
457
+ if (meta.tuples.length === 1)
458
+ install(
459
+ decode_tuple(project)(config)(importer)(input, meta.tuples[0]!, {
460
+ ...explore,
461
+ from: "array",
462
+ }),
463
+ );
464
+ // TUPLE ONLY
465
+ else
466
+ install(
467
+ explore_tuples(project)(config)(importer)(input, meta.tuples, {
468
+ ...explore,
469
+ from: "array",
470
+ }),
471
+ );
472
+ else if (meta.arrays.some((elem) => elem.type.value.any)) install(null);
473
+ else if (meta.tuples.length === 0)
474
+ if (meta.arrays.length === 1)
475
+ // ARRAY ONLY
476
+ install(
477
+ decode_array(project)(config)(importer)(input, meta.arrays[0]!, {
478
+ ...explore,
479
+ from: "array",
480
+ }),
481
+ );
482
+ else
483
+ install(
484
+ explore_arrays(project)(config)(importer)(input, meta.arrays, {
485
+ ...explore,
486
+ from: "array",
487
+ }),
488
+ );
489
+ else
490
+ install(
491
+ explore_arrays_and_tuples(project)(config)(importer)(
492
+ input,
493
+ [...meta.tuples, ...meta.arrays],
494
+ explore,
495
+ ),
496
+ );
497
+ }
498
+
499
+ // OBJECT
500
+ if (meta.objects.length > 0)
501
+ prepare(
502
+ ExpressionFactory.isObject({
503
+ checkNull: true,
504
+ checkArray: meta.objects.some((obj) =>
505
+ obj.properties.every(
506
+ (prop) => !prop.key.isSoleLiteral() || !prop.value.isRequired(),
507
+ ),
508
+ ),
509
+ })(input),
510
+ meta.objects.map((obj) => obj.name).join(" | "),
511
+ )(
512
+ explore_objects(config)(importer)(input, meta, {
513
+ ...explore,
514
+ from: "object",
515
+ }),
516
+ );
517
+
518
+ if (instances.length) {
519
+ const transformer =
520
+ (merger: (x: ts.Expression, y: ts.Expression) => ts.Expression) =>
521
+ (ins: IInstance) =>
522
+ ins.body
523
+ ? {
524
+ expression: merger(ins.pre, ins.body),
525
+ combined: true,
526
+ }
527
+ : {
528
+ expression: ins.pre,
529
+ combined: false,
530
+ };
531
+ if (instances.length === 1)
532
+ binaries.push(
533
+ transformer((pre, body) =>
534
+ config.combiner(explore)("and")(
535
+ input,
536
+ [pre, body].map((expression) => ({
537
+ expression,
538
+ combined: expression !== pre,
539
+ })),
540
+ meta.getName(),
541
+ ),
542
+ )(instances[0]!),
543
+ );
544
+ else
545
+ binaries.push({
546
+ expression: config.combiner(explore)("or")(
547
+ input,
548
+ instances.map(transformer(ts.factory.createLogicalAnd)),
549
+ meta.getName(),
550
+ ),
551
+ combined: true,
552
+ });
553
+ }
554
+
555
+ //----
556
+ // COMBINE CONDITIONS
557
+ //----
558
+ return top.length && binaries.length
559
+ ? config.combiner(explore)("and")(
560
+ input,
561
+ [
562
+ ...top,
563
+ {
564
+ expression: config.combiner(explore)("or")(
565
+ input,
566
+ binaries,
567
+ meta.getName(),
568
+ ),
569
+ combined: true,
570
+ },
571
+ ],
572
+ meta.getName(),
573
+ )
574
+ : binaries.length
575
+ ? config.combiner(explore)("or")(input, binaries, meta.getName())
576
+ : config.success;
577
+ };
578
+
579
+ export const decode_object =
580
+ (config: IConfig) => (importer: FunctionImporter) => {
581
+ const func = FeatureProgrammer.decode_object(config)(importer);
582
+ return (input: ts.Expression, obj: MetadataObject, explore: IExplore) => {
583
+ obj.validated = true;
584
+ return func(input, obj, explore);
585
+ };
586
+ };
587
+
588
+ const decode_array =
589
+ (project: IProject) =>
590
+ (config: IConfig) =>
591
+ (importer: FunctionImporter) =>
592
+ (input: ts.Expression, array: MetadataArray, explore: IExplore) => {
593
+ if (array.type.recursive === false)
594
+ return decode_array_inline(project)(config)(importer)(
595
+ input,
596
+ array,
597
+ explore,
598
+ );
599
+
600
+ explore = {
601
+ ...explore,
602
+ source: "function",
603
+ from: "array",
604
+ };
605
+ return ts.factory.createLogicalOr(
606
+ ts.factory.createCallExpression(
607
+ ts.factory.createIdentifier(
608
+ importer.useLocal(`${config.prefix}a${array.type.index}`),
609
+ ),
610
+ undefined,
611
+ FeatureProgrammer.argumentsArray(config)({
612
+ ...explore,
613
+ source: "function",
614
+ from: "array",
615
+ })(input),
616
+ ),
617
+ config.joiner.failure(input, array.type.name, explore),
618
+ );
619
+ };
620
+
621
+ const decode_array_inline =
622
+ (project: IProject) =>
623
+ (config: IConfig) =>
624
+ (importer: FunctionImporter) =>
625
+ (
626
+ input: ts.Expression,
627
+ array: MetadataArray,
628
+ explore: IExplore,
629
+ ): ts.Expression => {
630
+ const length = check_array_length(project)(array)(input);
631
+ const main = FeatureProgrammer.decode_array({
632
+ prefix: config.prefix,
633
+ trace: config.trace,
634
+ path: config.path,
635
+ decoder: () => decode(project)(config)(importer),
636
+ })(importer)(config.joiner.array)(input, array, explore);
637
+ return length.expression === null && length.conditions.length === 0
638
+ ? main
639
+ : ts.factory.createLogicalAnd(
640
+ config.atomist(explore)(length)(input),
641
+ main,
642
+ );
643
+ };
644
+
645
+ const decode_tuple =
646
+ (project: IProject) =>
647
+ (config: IConfig) =>
648
+ (importer: FunctionImporter) =>
649
+ (
650
+ input: ts.Expression,
651
+ tuple: MetadataTuple,
652
+ explore: IExplore,
653
+ ): ts.Expression => {
654
+ if (tuple.type.recursive === false)
655
+ return decode_tuple_inline(project)(config)(importer)(
656
+ input,
657
+ tuple.type,
658
+ explore,
659
+ );
660
+ explore = {
661
+ ...explore,
662
+ source: "function",
663
+ from: "array",
664
+ };
665
+ return ts.factory.createLogicalOr(
666
+ ts.factory.createCallExpression(
667
+ ts.factory.createIdentifier(
668
+ importer.useLocal(`${config.prefix}t${tuple.type.index}`),
669
+ ),
670
+ undefined,
671
+ FeatureProgrammer.argumentsArray(config)({
672
+ ...explore,
673
+ source: "function",
674
+ })(input),
675
+ ),
676
+ config.joiner.failure(input, tuple.type.name, explore),
677
+ );
678
+ };
679
+
680
+ const decode_tuple_inline =
681
+ (project: IProject) =>
682
+ (config: IConfig) =>
683
+ (importer: FunctionImporter) =>
684
+ (
685
+ input: ts.Expression,
686
+ tuple: MetadataTupleType,
687
+ explore: IExplore,
688
+ ): ts.Expression => {
689
+ const binaries: ts.Expression[] = tuple.elements
690
+ .filter((meta) => meta.rest === null)
691
+ .map((meta, index) =>
692
+ decode(project)(config)(importer)(
693
+ ts.factory.createElementAccessExpression(input, index),
694
+ meta,
695
+ {
696
+ ...explore,
697
+ from: "array",
698
+ postfix: explore.postfix.length
699
+ ? `${explore.postfix.slice(0, -1)}[${index}]"`
700
+ : `"[${index}]"`,
701
+ },
702
+ ),
703
+ );
704
+ const rest: ts.Expression | null =
705
+ tuple.elements.length && tuple.elements.at(-1)!.rest !== null
706
+ ? decode(project)(config)(importer)(
707
+ ts.factory.createCallExpression(
708
+ IdentifierFactory.access(input)("slice"),
709
+ undefined,
710
+ [ExpressionFactory.number(tuple.elements.length - 1)],
711
+ ),
712
+ wrap_metadata_rest_tuple(tuple.elements.at(-1)!.rest!),
713
+ {
714
+ ...explore,
715
+ start: tuple.elements.length - 1,
716
+ },
717
+ )
718
+ : null;
719
+
720
+ const arrayLength = ts.factory.createPropertyAccessExpression(
721
+ input,
722
+ "length",
723
+ );
724
+ return config.combiner(explore)("and")(
725
+ input,
726
+ [
727
+ ...(rest === null
728
+ ? tuple.elements.every((t) => t.optional === false)
729
+ ? [
730
+ {
731
+ combined: false,
732
+ expression: ts.factory.createStrictEquality(
733
+ arrayLength,
734
+ ExpressionFactory.number(tuple.elements.length),
735
+ ),
736
+ },
737
+ ]
738
+ : [
739
+ {
740
+ combined: false,
741
+ expression: ts.factory.createLogicalAnd(
742
+ ts.factory.createLessThanEquals(
743
+ ExpressionFactory.number(
744
+ tuple.elements.filter((t) => t.optional === false)
745
+ .length,
746
+ ),
747
+ arrayLength,
748
+ ),
749
+ ts.factory.createGreaterThanEquals(
750
+ ExpressionFactory.number(tuple.elements.length),
751
+ arrayLength,
752
+ ),
753
+ ),
754
+ },
755
+ ]
756
+ : []),
757
+ ...(config.joiner.tuple
758
+ ? [
759
+ {
760
+ expression: config.joiner.tuple(binaries),
761
+ combined: true,
762
+ },
763
+ ]
764
+ : binaries.map((expression) => ({
765
+ expression,
766
+ combined: true,
767
+ }))),
768
+ ...(rest !== null
769
+ ? [
770
+ {
771
+ expression: rest,
772
+ combined: true,
773
+ },
774
+ ]
775
+ : []),
776
+ ],
777
+ `[${tuple.elements.map((t) => t.getName()).join(", ")}]`,
778
+ );
779
+ };
780
+
781
+ /* -----------------------------------------------------------
782
+ UNION TYPE EXPLORERS
783
+ ----------------------------------------------------------- */
784
+ const explore_sets =
785
+ (project: IProject) =>
786
+ (config: IConfig) =>
787
+ (importer: FunctionImporter) =>
788
+ (
789
+ input: ts.Expression,
790
+ sets: Metadata[],
791
+ explore: IExplore,
792
+ ): ts.Expression =>
793
+ ts.factory.createCallExpression(
794
+ UnionExplorer.set({
795
+ checker: decode(project)(config)(importer),
796
+ decoder: decode_array(project)(config)(importer),
797
+ empty: config.success,
798
+ success: config.success,
799
+ failure: (input, expected, explore) =>
800
+ ts.factory.createReturnStatement(
801
+ config.joiner.failure(input, expected, explore),
802
+ ),
803
+ })([])(input, sets, explore),
804
+ undefined,
805
+ undefined,
806
+ );
807
+
808
+ const explore_maps =
809
+ (project: IProject) =>
810
+ (config: IConfig) =>
811
+ (importer: FunctionImporter) =>
812
+ (
813
+ input: ts.Expression,
814
+ maps: Metadata.Entry[],
815
+ explore: IExplore,
816
+ ): ts.Expression =>
817
+ ts.factory.createCallExpression(
818
+ UnionExplorer.map({
819
+ checker: (input, entry, explore) => {
820
+ const func = decode(project)(config)(importer);
821
+ return ts.factory.createLogicalAnd(
822
+ func(
823
+ ts.factory.createElementAccessExpression(input, 0),
824
+ entry[0],
825
+ {
826
+ ...explore,
827
+ postfix: `${explore.postfix}[0]`,
828
+ },
829
+ ),
830
+ func(
831
+ ts.factory.createElementAccessExpression(input, 1),
832
+ entry[1],
833
+ {
834
+ ...explore,
835
+ postfix: `${explore.postfix}[1]`,
836
+ },
837
+ ),
838
+ );
839
+ },
840
+ decoder: decode_array(project)(config)(importer),
841
+ empty: config.success,
842
+ success: config.success,
843
+ failure: (input, expected, explore) =>
844
+ ts.factory.createReturnStatement(
845
+ config.joiner.failure(input, expected, explore),
846
+ ),
847
+ })([])(input, maps, explore),
848
+ undefined,
849
+ undefined,
850
+ );
851
+
852
+ const explore_tuples =
853
+ (project: IProject) =>
854
+ (config: IConfig) =>
855
+ (importer: FunctionImporter) =>
856
+ (
857
+ input: ts.Expression,
858
+ tuples: MetadataTuple[],
859
+ explore: IExplore,
860
+ ): ts.Expression =>
861
+ explore_array_like_union_types(config)(importer)(
862
+ UnionExplorer.tuple({
863
+ checker: decode_tuple(project)(config)(importer),
864
+ decoder: decode_tuple(project)(config)(importer),
865
+ empty: config.success,
866
+ success: config.success,
867
+ failure: (input, expected, explore) =>
868
+ ts.factory.createReturnStatement(
869
+ config.joiner.failure(input, expected, explore),
870
+ ),
871
+ }),
872
+ )(input, tuples, explore);
873
+
874
+ const explore_arrays =
875
+ (project: IProject) =>
876
+ (config: IConfig) =>
877
+ (importer: FunctionImporter) =>
878
+ (
879
+ input: ts.Expression,
880
+ arrays: MetadataArray[],
881
+ explore: IExplore,
882
+ ): ts.Expression =>
883
+ explore_array_like_union_types(config)(importer)(
884
+ UnionExplorer.array({
885
+ checker: decode(project)(config)(importer),
886
+ decoder: decode_array(project)(config)(importer),
887
+ empty: config.success,
888
+ success: config.success,
889
+ failure: (input, expected, explore) =>
890
+ ts.factory.createReturnStatement(
891
+ config.joiner.failure(input, expected, explore),
892
+ ),
893
+ }),
894
+ )(input, arrays, explore);
895
+
896
+ const explore_arrays_and_tuples =
897
+ (project: IProject) =>
898
+ (config: IConfig) =>
899
+ (importer: FunctionImporter) =>
900
+ (
901
+ input: ts.Expression,
902
+ elements: Array<MetadataArray | MetadataTuple>,
903
+ explore: IExplore,
904
+ ): ts.Expression =>
905
+ explore_array_like_union_types(config)(importer)(
906
+ UnionExplorer.array_or_tuple({
907
+ checker: (front, target, explore, array) =>
908
+ target instanceof MetadataTuple
909
+ ? decode_tuple(project)(config)(importer)(front, target, explore)
910
+ : config.atomist(explore)({
911
+ expected: elements
912
+ .map((elem) =>
913
+ elem instanceof MetadataArray
914
+ ? elem.getName()
915
+ : elem.type.name,
916
+ )
917
+ .join(" | "),
918
+ expression: decode(project)(config)(importer)(
919
+ front,
920
+ target,
921
+ explore,
922
+ ),
923
+ conditions: [],
924
+ })(array),
925
+ decoder: (input, target, explore) =>
926
+ target instanceof MetadataTuple
927
+ ? decode_tuple(project)(config)(importer)(input, target, explore)
928
+ : decode_array(project)(config)(importer)(input, target, explore),
929
+ empty: config.success,
930
+ success: config.success,
931
+ failure: (input, expected, explore) =>
932
+ ts.factory.createReturnStatement(
933
+ config.joiner.failure(input, expected, explore),
934
+ ),
935
+ }),
936
+ )(input, elements, explore);
937
+
938
+ const explore_array_like_union_types =
939
+ (config: IConfig) =>
940
+ (importer: FunctionImporter) =>
941
+ <T extends MetadataArray | MetadataTuple>(
942
+ factory: (
943
+ parameters: ts.ParameterDeclaration[],
944
+ ) => (
945
+ input: ts.Expression,
946
+ elements: T[],
947
+ explore: IExplore,
948
+ ) => ts.ArrowFunction,
949
+ ) =>
950
+ (input: ts.Expression, elements: T[], explore: IExplore): ts.Expression => {
951
+ const arrow =
952
+ (parameters: ts.ParameterDeclaration[]) =>
953
+ (explore: IExplore) =>
954
+ (input: ts.Expression): ts.ArrowFunction =>
955
+ factory(parameters)(input, elements, explore);
956
+ if (elements.every((e) => e.type.recursive === false))
957
+ ts.factory.createCallExpression(
958
+ arrow([])(explore)(input),
959
+ undefined,
960
+ [],
961
+ );
962
+ explore = {
963
+ ...explore,
964
+ source: "function",
965
+ from: "array",
966
+ };
967
+ return ts.factory.createLogicalOr(
968
+ ts.factory.createCallExpression(
969
+ ts.factory.createIdentifier(
970
+ importer.emplaceUnion(
971
+ config.prefix,
972
+ elements.map((e) => e.type.name).join(" | "),
973
+ () =>
974
+ arrow(
975
+ FeatureProgrammer.parameterDeclarations(config)(
976
+ TypeFactory.keyword("any"),
977
+ )(ts.factory.createIdentifier("input")),
978
+ )({
979
+ ...explore,
980
+ postfix: "",
981
+ })(ts.factory.createIdentifier("input")),
982
+ ),
983
+ ),
984
+ undefined,
985
+ FeatureProgrammer.argumentsArray(config)(explore)(input),
986
+ ),
987
+ config.joiner.failure(
988
+ input,
989
+ elements.map((e) => e.type.name).join(" | "),
990
+ explore,
991
+ ),
992
+ );
993
+ };
994
+
995
+ const explore_objects =
996
+ (config: IConfig) =>
997
+ (importer: FunctionImporter) =>
998
+ (input: ts.Expression, meta: Metadata, explore: IExplore) =>
999
+ meta.objects.length === 1
1000
+ ? decode_object(config)(importer)(input, meta.objects[0]!, explore)
1001
+ : ts.factory.createCallExpression(
1002
+ ts.factory.createIdentifier(
1003
+ importer.useLocal(`${config.prefix}u${meta.union_index!}`),
1004
+ ),
1005
+ undefined,
1006
+ FeatureProgrammer.argumentsArray(config)(explore)(input),
1007
+ );
1008
+ }
1009
+
1010
+ const create_add =
1011
+ (binaries: CheckerProgrammer.IBinary[]) =>
1012
+ (defaultInput: ts.Expression) =>
1013
+ (
1014
+ exact: boolean,
1015
+ left: ts.Expression,
1016
+ right: ts.Expression = defaultInput,
1017
+ ) => {
1018
+ const factory = exact
1019
+ ? ts.factory.createStrictEquality
1020
+ : ts.factory.createStrictInequality;
1021
+ binaries.push({
1022
+ expression: factory(left, right),
1023
+ combined: false,
1024
+ });
1025
+ };