typia 5.5.5 → 5.5.6-dev.20240319

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