typia 3.5.0-dev.20230125 → 3.5.0-dev.20230211

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 (227) hide show
  1. package/README.md +64 -71
  2. package/lib/factories/MetadataCollection.d.ts +9 -1
  3. package/lib/factories/MetadataCollection.js +75 -2
  4. package/lib/factories/MetadataCollection.js.map +1 -1
  5. package/lib/factories/internal/metadata/iterate_metadata_native.js +0 -3
  6. package/lib/factories/internal/metadata/iterate_metadata_native.js.map +1 -1
  7. package/lib/functional/$is_between.d.ts +1 -0
  8. package/lib/functional/$is_between.js +8 -0
  9. package/lib/functional/$is_between.js.map +1 -0
  10. package/lib/metadata/IMetadataTag.d.ts +3 -7
  11. package/lib/metadata/Metadata.js +2 -2
  12. package/lib/metadata/Metadata.js.map +1 -1
  13. package/lib/module.d.ts +33 -3
  14. package/lib/module.js +36 -8
  15. package/lib/module.js.map +1 -1
  16. package/lib/programmers/AssertProgrammer.js +3 -2
  17. package/lib/programmers/AssertProgrammer.js.map +1 -1
  18. package/lib/programmers/CheckerProgrammer.d.ts +2 -2
  19. package/lib/programmers/CheckerProgrammer.js +21 -16
  20. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  21. package/lib/programmers/FeatureProgrammer.d.ts +114 -18
  22. package/lib/programmers/FeatureProgrammer.js +4 -4
  23. package/lib/programmers/FeatureProgrammer.js.map +1 -1
  24. package/lib/programmers/IsProgrammer.d.ts +4 -3
  25. package/lib/programmers/IsProgrammer.js +72 -61
  26. package/lib/programmers/IsProgrammer.js.map +1 -1
  27. package/lib/programmers/PruneProgrammer.d.ts +5 -0
  28. package/lib/programmers/PruneProgrammer.js +279 -0
  29. package/lib/programmers/PruneProgrammer.js.map +1 -0
  30. package/lib/programmers/StringifyProgrammer.js +26 -21
  31. package/lib/programmers/StringifyProgrammer.js.map +1 -1
  32. package/lib/programmers/ValidateProgrammer.js +3 -2
  33. package/lib/programmers/ValidateProgrammer.js.map +1 -1
  34. package/lib/programmers/helpers/AtomicPredicator.d.ts +2 -0
  35. package/lib/programmers/helpers/AtomicPredicator.js +9 -1
  36. package/lib/programmers/helpers/AtomicPredicator.js.map +1 -1
  37. package/lib/programmers/helpers/IExpressionEntry.d.ts +2 -2
  38. package/lib/programmers/helpers/OptionPredicator.d.ts +1 -0
  39. package/lib/programmers/helpers/OptionPredicator.js +4 -0
  40. package/lib/programmers/helpers/OptionPredicator.js.map +1 -1
  41. package/lib/programmers/helpers/PruneJoiner.d.ts +8 -0
  42. package/lib/programmers/helpers/PruneJoiner.js +60 -0
  43. package/lib/programmers/helpers/PruneJoiner.js.map +1 -0
  44. package/lib/programmers/helpers/StringifyJoinder.d.ts +1 -1
  45. package/lib/programmers/helpers/StringifyJoinder.js +2 -4
  46. package/lib/programmers/helpers/StringifyJoinder.js.map +1 -1
  47. package/lib/programmers/internal/application_object.js +11 -11
  48. package/lib/programmers/internal/application_object.js.map +1 -1
  49. package/lib/programmers/internal/application_schema.js +21 -12
  50. package/lib/programmers/internal/application_schema.js.map +1 -1
  51. package/lib/programmers/internal/check_dynamic_properties.js +34 -11
  52. package/lib/programmers/internal/check_dynamic_properties.js.map +1 -1
  53. package/lib/programmers/internal/check_native.js +9 -1
  54. package/lib/programmers/internal/check_native.js.map +1 -1
  55. package/lib/programmers/internal/check_object.d.ts +1 -0
  56. package/lib/programmers/internal/check_object.js +13 -9
  57. package/lib/programmers/internal/check_object.js.map +1 -1
  58. package/lib/programmers/internal/check_union_array_like.d.ts +1 -1
  59. package/lib/programmers/internal/check_union_array_like.js +3 -1
  60. package/lib/programmers/internal/check_union_array_like.js.map +1 -1
  61. package/lib/programmers/internal/feature_object_entries.d.ts +2 -2
  62. package/lib/programmers/internal/feature_object_entries.js.map +1 -1
  63. package/lib/programmers/internal/prune_object_properties.d.ts +1 -0
  64. package/lib/programmers/internal/prune_object_properties.js +28 -0
  65. package/lib/programmers/internal/prune_object_properties.js.map +1 -0
  66. package/lib/programmers/internal/stringify_dynamic_properties.js.map +1 -1
  67. package/lib/programmers/internal/stringify_regular_properties.js.map +1 -1
  68. package/lib/transformers/CallExpressionTransformer.js +5 -3
  69. package/lib/transformers/CallExpressionTransformer.js.map +1 -1
  70. package/lib/transformers/ITransformOptions.d.ts +14 -0
  71. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js +3 -1
  72. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js.map +1 -1
  73. package/lib/transformers/features/miscellaneous/CreatePruneTransformer.d.ts +5 -0
  74. package/lib/transformers/features/miscellaneous/CreatePruneTransformer.js +17 -0
  75. package/lib/transformers/features/miscellaneous/CreatePruneTransformer.js.map +1 -0
  76. package/lib/transformers/features/miscellaneous/PruneTransformer.d.ts +5 -0
  77. package/lib/transformers/features/miscellaneous/PruneTransformer.js +34 -0
  78. package/lib/transformers/features/miscellaneous/PruneTransformer.js.map +1 -0
  79. package/package.json +5 -4
  80. package/src/factories/MetadataCollection.ts +41 -2
  81. package/src/factories/internal/metadata/iterate_metadata_native.ts +0 -5
  82. package/src/functional/$is_between.ts +7 -0
  83. package/src/metadata/IMetadataTag.ts +4 -19
  84. package/src/metadata/Metadata.ts +3 -6
  85. package/src/module.ts +91 -17
  86. package/src/programmers/AssertProgrammer.ts +3 -2
  87. package/src/programmers/CheckerProgrammer.ts +21 -13
  88. package/src/programmers/FeatureProgrammer.ts +146 -21
  89. package/src/programmers/IsProgrammer.ts +107 -87
  90. package/src/programmers/PruneProgrammer.ts +320 -0
  91. package/src/programmers/StringifyProgrammer.ts +51 -34
  92. package/src/programmers/ValidateProgrammer.ts +3 -2
  93. package/src/programmers/helpers/AtomicPredicator.ts +17 -1
  94. package/src/programmers/helpers/IExpressionEntry.ts +4 -2
  95. package/src/programmers/helpers/OptionPredicator.ts +4 -0
  96. package/src/programmers/helpers/PruneJoiner.ts +52 -0
  97. package/src/programmers/helpers/StringifyJoinder.ts +7 -4
  98. package/src/programmers/internal/application_object.ts +5 -5
  99. package/src/programmers/internal/application_schema.ts +33 -27
  100. package/src/programmers/internal/check_dynamic_properties.ts +67 -16
  101. package/src/programmers/internal/check_native.ts +14 -2
  102. package/src/programmers/internal/check_object.ts +8 -2
  103. package/src/programmers/internal/check_union_array_like.ts +4 -2
  104. package/src/programmers/internal/feature_object_entries.ts +6 -1
  105. package/src/programmers/internal/prune_object_properties.ts +60 -0
  106. package/src/programmers/internal/stringify_dynamic_properties.ts +2 -2
  107. package/src/programmers/internal/stringify_regular_properties.ts +2 -2
  108. package/src/transformers/CallExpressionTransformer.ts +15 -16
  109. package/src/transformers/ITransformOptions.ts +15 -0
  110. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +3 -1
  111. package/src/transformers/features/{protocols/MessageTransformer.ts → miscellaneous/CreatePruneTransformer.ts} +6 -7
  112. package/src/transformers/features/miscellaneous/PruneTransformer.ts +46 -0
  113. package/lib/factories/ProtocolFactory.d.ts +0 -8
  114. package/lib/factories/ProtocolFactory.js +0 -119
  115. package/lib/factories/ProtocolFactory.js.map +0 -1
  116. package/lib/factories/internal/protocols/ProtocolMetadataUtil.d.ts +0 -16
  117. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js +0 -156
  118. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js.map +0 -1
  119. package/lib/factories/internal/protocols/emplace_protocol_object.d.ts +0 -3
  120. package/lib/factories/internal/protocols/emplace_protocol_object.js +0 -44
  121. package/lib/factories/internal/protocols/emplace_protocol_object.js.map +0 -1
  122. package/lib/factories/internal/protocols/emplace_protocol_property.d.ts +0 -4
  123. package/lib/factories/internal/protocols/emplace_protocol_property.js +0 -20
  124. package/lib/factories/internal/protocols/emplace_protocol_property.js.map +0 -1
  125. package/lib/factories/internal/protocols/iterate_protocol_atomic.d.ts +0 -3
  126. package/lib/factories/internal/protocols/iterate_protocol_atomic.js +0 -69
  127. package/lib/factories/internal/protocols/iterate_protocol_atomic.js.map +0 -1
  128. package/lib/factories/internal/protocols/iterate_protocol_constant.d.ts +0 -2
  129. package/lib/factories/internal/protocols/iterate_protocol_constant.js +0 -30
  130. package/lib/factories/internal/protocols/iterate_protocol_constant.js.map +0 -1
  131. package/lib/factories/internal/protocols/iterate_protocol_main.d.ts +0 -3
  132. package/lib/factories/internal/protocols/iterate_protocol_main.js +0 -17
  133. package/lib/factories/internal/protocols/iterate_protocol_main.js.map +0 -1
  134. package/lib/factories/internal/protocols/iterate_protocol_map.d.ts +0 -4
  135. package/lib/factories/internal/protocols/iterate_protocol_map.js +0 -75
  136. package/lib/factories/internal/protocols/iterate_protocol_map.js.map +0 -1
  137. package/lib/factories/internal/protocols/iterate_protocol_metadata.d.ts +0 -5
  138. package/lib/factories/internal/protocols/iterate_protocol_metadata.js +0 -190
  139. package/lib/factories/internal/protocols/iterate_protocol_metadata.js.map +0 -1
  140. package/lib/factories/internal/protocols/iterate_protocol_native.d.ts +0 -2
  141. package/lib/factories/internal/protocols/iterate_protocol_native.js +0 -33
  142. package/lib/factories/internal/protocols/iterate_protocol_native.js.map +0 -1
  143. package/lib/factories/internal/protocols/iterate_protocol_never.d.ts +0 -1
  144. package/lib/factories/internal/protocols/iterate_protocol_never.js +0 -6
  145. package/lib/factories/internal/protocols/iterate_protocol_never.js.map +0 -1
  146. package/lib/factories/internal/protocols/iterate_protocol_object.d.ts +0 -4
  147. package/lib/factories/internal/protocols/iterate_protocol_object.js +0 -157
  148. package/lib/factories/internal/protocols/iterate_protocol_object.js.map +0 -1
  149. package/lib/factories/internal/protocols/iterate_protocol_repeated.d.ts +0 -5
  150. package/lib/factories/internal/protocols/iterate_protocol_repeated.js +0 -25
  151. package/lib/factories/internal/protocols/iterate_protocol_repeated.js.map +0 -1
  152. package/lib/factories/internal/protocols/iterate_protocol_tuple.d.ts +0 -3
  153. package/lib/factories/internal/protocols/iterate_protocol_tuple.js +0 -46
  154. package/lib/factories/internal/protocols/iterate_protocol_tuple.js.map +0 -1
  155. package/lib/functional/$proto_bytes.d.ts +0 -2
  156. package/lib/functional/$proto_bytes.js +0 -37
  157. package/lib/functional/$proto_bytes.js.map +0 -1
  158. package/lib/functional/$proto_field.d.ts +0 -10
  159. package/lib/functional/$proto_field.js +0 -42
  160. package/lib/functional/$proto_field.js.map +0 -1
  161. package/lib/functional/$proto_float.d.ts +0 -4
  162. package/lib/functional/$proto_float.js +0 -28
  163. package/lib/functional/$proto_float.js.map +0 -1
  164. package/lib/functional/$proto_i32.d.ts +0 -2
  165. package/lib/functional/$proto_i32.js +0 -23
  166. package/lib/functional/$proto_i32.js.map +0 -1
  167. package/lib/functional/$proto_i64.d.ts +0 -2
  168. package/lib/functional/$proto_i64.js +0 -31
  169. package/lib/functional/$proto_i64.js.map +0 -1
  170. package/lib/functional/$proto_size.d.ts +0 -6
  171. package/lib/functional/$proto_size.js +0 -76
  172. package/lib/functional/$proto_size.js.map +0 -1
  173. package/lib/functional/$proto_string.d.ts +0 -2
  174. package/lib/functional/$proto_string.js +0 -34
  175. package/lib/functional/$proto_string.js.map +0 -1
  176. package/lib/functional/$varint.d.ts +0 -6
  177. package/lib/functional/$varint.js +0 -99
  178. package/lib/functional/$varint.js.map +0 -1
  179. package/lib/functional/$zigzag.d.ts +0 -4
  180. package/lib/functional/$zigzag.js +0 -34
  181. package/lib/functional/$zigzag.js.map +0 -1
  182. package/lib/messages/IProtocolMap.d.ts +0 -5
  183. package/lib/messages/IProtocolMap.js +0 -3
  184. package/lib/messages/IProtocolMap.js.map +0 -1
  185. package/lib/messages/IProtocolMessage.d.ts +0 -5
  186. package/lib/messages/IProtocolMessage.js +0 -3
  187. package/lib/messages/IProtocolMessage.js.map +0 -1
  188. package/lib/messages/IProtocolProperty.d.ts +0 -12
  189. package/lib/messages/IProtocolProperty.js +0 -3
  190. package/lib/messages/IProtocolProperty.js.map +0 -1
  191. package/lib/programmers/MessageProgrammer.d.ts +0 -5
  192. package/lib/programmers/MessageProgrammer.js +0 -141
  193. package/lib/programmers/MessageProgrammer.js.map +0 -1
  194. package/lib/transformers/features/protocols/MessageTransformer.d.ts +0 -5
  195. package/lib/transformers/features/protocols/MessageTransformer.js +0 -17
  196. package/lib/transformers/features/protocols/MessageTransformer.js.map +0 -1
  197. package/lib/utils/NameEncoder.d.ts +0 -4
  198. package/lib/utils/NameEncoder.js +0 -89
  199. package/lib/utils/NameEncoder.js.map +0 -1
  200. package/src/factories/ProtocolFactory.ts +0 -92
  201. package/src/factories/internal/protocols/ProtocolMetadataUtil.ts +0 -163
  202. package/src/factories/internal/protocols/emplace_protocol_object.ts +0 -23
  203. package/src/factories/internal/protocols/emplace_protocol_property.ts +0 -12
  204. package/src/factories/internal/protocols/iterate_protocol_atomic.ts +0 -34
  205. package/src/factories/internal/protocols/iterate_protocol_constant.ts +0 -27
  206. package/src/factories/internal/protocols/iterate_protocol_main.ts +0 -19
  207. package/src/factories/internal/protocols/iterate_protocol_map.ts +0 -58
  208. package/src/factories/internal/protocols/iterate_protocol_metadata.ts +0 -96
  209. package/src/factories/internal/protocols/iterate_protocol_native.ts +0 -34
  210. package/src/factories/internal/protocols/iterate_protocol_never.ts +0 -1
  211. package/src/factories/internal/protocols/iterate_protocol_object.ts +0 -110
  212. package/src/factories/internal/protocols/iterate_protocol_repeated.ts +0 -34
  213. package/src/factories/internal/protocols/iterate_protocol_tuple.ts +0 -29
  214. package/src/functional/$proto_bytes.ts +0 -25
  215. package/src/functional/$proto_field.ts +0 -30
  216. package/src/functional/$proto_float.ts +0 -37
  217. package/src/functional/$proto_i32.ts +0 -29
  218. package/src/functional/$proto_i64.ts +0 -37
  219. package/src/functional/$proto_size.ts +0 -82
  220. package/src/functional/$proto_string.ts +0 -24
  221. package/src/functional/$varint.ts +0 -130
  222. package/src/functional/$zigzag.ts +0 -39
  223. package/src/messages/IProtocolMap.ts +0 -5
  224. package/src/messages/IProtocolMessage.ts +0 -6
  225. package/src/messages/IProtocolProperty.ts +0 -13
  226. package/src/programmers/MessageProgrammer.ts +0 -126
  227. package/src/utils/NameEncoder.ts +0 -32
@@ -16,61 +16,68 @@ import { check_object } from "./internal/check_object";
16
16
  import { feature_object_entries } from "./internal/feature_object_entries";
17
17
 
18
18
  export namespace IsProgrammer {
19
- export const CONFIG = (
20
- options?: Partial<CONFIG.IOptions>,
21
- ): CheckerProgrammer.IConfig => ({
22
- functors: "$io",
23
- unioners: "$iu",
24
- trace: false,
25
- path: false,
26
- equals: !!options?.object,
27
- numeric: OptionPredicator.numeric({
28
- numeric: options?.numeric,
29
- }),
30
- combiner: () => (type: "and" | "or") => {
31
- const initial: ts.TrueLiteral | ts.FalseLiteral =
32
- type === "and"
33
- ? ts.factory.createTrue()
34
- : ts.factory.createFalse();
35
- const binder =
36
- type === "and"
37
- ? ts.factory.createLogicalAnd
38
- : ts.factory.createLogicalOr;
39
- return (
40
- _input: ts.Expression,
41
- binaries: CheckerProgrammer.IBinary[],
42
- ) =>
43
- binaries.length
44
- ? binaries
45
- .map((binary) => binary.expression)
46
- .reduce((x, y) => binder(x, y))
47
- : initial;
48
- },
49
- joiner: {
50
- object:
51
- options?.object ||
52
- check_object({
53
- equals: !!options?.object,
54
- assert: true,
55
- reduce: ts.factory.createLogicalAnd,
56
- positive: ts.factory.createTrue(),
57
- superfluous: () => ts.factory.createFalse(),
58
- }),
59
- array: (input, arrow) =>
60
- ts.factory.createCallExpression(
61
- IdentifierFactory.join(input, "every"),
62
- undefined,
63
- [arrow],
64
- ),
65
- failure: () => ts.factory.createFalse(),
66
- },
67
- success: ts.factory.createTrue(),
68
- });
19
+ export const CONFIG =
20
+ (options?: Partial<CONFIG.IOptions>) =>
21
+ (importer: FunctionImporter): CheckerProgrammer.IConfig => ({
22
+ functors: "$io",
23
+ unioners: "$iu",
24
+ trace: false,
25
+ path: false,
26
+ equals: !!options?.object,
27
+ numeric: OptionPredicator.numeric({
28
+ numeric: options?.numeric,
29
+ }),
30
+ combiner: () => (type: "and" | "or") => {
31
+ const initial: ts.TrueLiteral | ts.FalseLiteral =
32
+ type === "and"
33
+ ? ts.factory.createTrue()
34
+ : ts.factory.createFalse();
35
+ const binder =
36
+ type === "and"
37
+ ? ts.factory.createLogicalAnd
38
+ : ts.factory.createLogicalOr;
39
+ return (
40
+ _input: ts.Expression,
41
+ binaries: CheckerProgrammer.IBinary[],
42
+ ) =>
43
+ binaries.length
44
+ ? binaries
45
+ .map((binary) => binary.expression)
46
+ .reduce((x, y) => binder(x, y))
47
+ : initial;
48
+ },
49
+ joiner: {
50
+ object:
51
+ options?.object ||
52
+ check_object({
53
+ equals: !!options?.object,
54
+ undefined: OptionPredicator.undefined({
55
+ undefined: options?.undefined,
56
+ }),
57
+ assert: true,
58
+ reduce: ts.factory.createLogicalAnd,
59
+ positive: ts.factory.createTrue(),
60
+ superfluous: () => ts.factory.createFalse(),
61
+ })(importer),
62
+ array: (input, arrow) =>
63
+ ts.factory.createCallExpression(
64
+ IdentifierFactory.join(input, "every"),
65
+ undefined,
66
+ [arrow],
67
+ ),
68
+ failure: () => ts.factory.createFalse(),
69
+ },
70
+ success: ts.factory.createTrue(),
71
+ });
69
72
 
70
73
  export namespace CONFIG {
71
74
  export interface IOptions {
72
75
  numeric: boolean;
73
- object: (entries: IExpressionEntry[]) => ts.Expression;
76
+ undefined: boolean;
77
+ object: (
78
+ input: ts.Expression,
79
+ entries: IExpressionEntry<ts.Expression>[],
80
+ ) => ts.Expression;
74
81
  }
75
82
  }
76
83
 
@@ -88,45 +95,48 @@ export namespace IsProgrammer {
88
95
  const config = CONFIG({
89
96
  object: check_object({
90
97
  equals,
98
+ undefined: OptionPredicator.undefined(project.options),
91
99
  assert: true,
92
100
  reduce: ts.factory.createLogicalAnd,
93
101
  positive: ts.factory.createTrue(),
94
102
  superfluous: () => ts.factory.createFalse(),
95
- }),
103
+ })(importer),
96
104
  numeric: OptionPredicator.numeric(project.options),
97
- });
105
+ })(importer);
98
106
  config.trace = equals;
99
107
 
100
- if (equals === false)
101
- config.decoder = (input, target, explore, tags) => {
108
+ config.decoder = (input, target, explore, tags) => {
109
+ if (
110
+ target.size() === 1 &&
111
+ target.objects.length === 1 &&
112
+ target.required === true &&
113
+ target.nullable === false
114
+ ) {
115
+ // ONLY WHEN OBJECT WITH SOME ATOMIC PROPERTIES
116
+ const obj: MetadataObject = target.objects[0]!;
102
117
  if (
103
- target.size() === 1 &&
104
- target.objects.length === 1 &&
105
- target.required === true &&
106
- target.nullable === false
107
- ) {
108
- // ONLY WHEN OBJECT WITH SOME ATOMIC PROPERTIES
109
- const obj: MetadataObject = target.objects[0]!;
110
- if (obj._Is_simple())
111
- return ts.factory.createLogicalAnd(
112
- ExpressionFactory.isObject(input, {
113
- checkNull: true,
114
- checkArray: false,
115
- }),
116
- config.joiner.object(
117
- feature_object_entries(config as any)(obj)(
118
- input,
119
- ),
120
- ),
121
- );
122
- }
123
- return CheckerProgrammer.decode(project, config, importer)(
124
- input,
125
- target,
126
- explore,
127
- tags,
128
- );
129
- };
118
+ obj._Is_simple() &&
119
+ (equals === false ||
120
+ OptionPredicator.undefined(project.options) === false)
121
+ )
122
+ return ts.factory.createLogicalAnd(
123
+ ExpressionFactory.isObject(input, {
124
+ checkNull: true,
125
+ checkArray: false,
126
+ }),
127
+ config.joiner.object(
128
+ input,
129
+ feature_object_entries(config as any)(obj)(input),
130
+ ),
131
+ );
132
+ }
133
+ return CheckerProgrammer.decode(project, config, importer)(
134
+ input,
135
+ target,
136
+ explore,
137
+ tags,
138
+ );
139
+ };
130
140
 
131
141
  // GENERATE CHECKER
132
142
  return CheckerProgrammer.generate(project, config, importer, () =>
@@ -137,21 +147,31 @@ export namespace IsProgrammer {
137
147
  export const generate_functors = (
138
148
  project: IProject,
139
149
  importer: FunctionImporter,
140
- ) => CheckerProgrammer.generate_functors(project, CONFIG(), importer);
150
+ ) =>
151
+ CheckerProgrammer.generate_functors(
152
+ project,
153
+ CONFIG()(importer),
154
+ importer,
155
+ );
141
156
 
142
157
  export const generate_unioners = (
143
158
  project: IProject,
144
159
  importer: FunctionImporter,
145
- ) => CheckerProgrammer.generate_unioners(project, CONFIG(), importer);
160
+ ) =>
161
+ CheckerProgrammer.generate_unioners(
162
+ project,
163
+ CONFIG()(importer),
164
+ importer,
165
+ );
146
166
 
147
167
  /* -----------------------------------------------------------
148
168
  DECODERS
149
169
  ----------------------------------------------------------- */
150
170
  export const decode = (project: IProject, importer: FunctionImporter) =>
151
- CheckerProgrammer.decode(project, CONFIG(), importer);
171
+ CheckerProgrammer.decode(project, CONFIG()(importer), importer);
152
172
 
153
- export const decode_object = () =>
154
- CheckerProgrammer.decode_object(CONFIG());
173
+ export const decode_object = (importer: FunctionImporter) =>
174
+ CheckerProgrammer.decode_object(CONFIG()(importer));
155
175
 
156
176
  export function decode_to_json(input: ts.Expression): ts.Expression {
157
177
  return ts.factory.createLogicalAnd(
@@ -0,0 +1,320 @@
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
+
8
+ import { Metadata } from "../metadata/Metadata";
9
+
10
+ import { IProject } from "../transformers/IProject";
11
+
12
+ import { FeatureProgrammer } from "./FeatureProgrammer";
13
+ import { IsProgrammer } from "./IsProgrammer";
14
+ import { FunctionImporter } from "./helpers/FunctionImporeter";
15
+ import { PruneJoiner } from "./helpers/PruneJoiner";
16
+ import { UnionExplorer } from "./helpers/UnionExplorer";
17
+ import { decode_union_object } from "./internal/decode_union_object";
18
+
19
+ export namespace PruneProgrammer {
20
+ export function generate(
21
+ project: IProject,
22
+ modulo: ts.LeftHandSideExpression,
23
+ ) {
24
+ const importer: FunctionImporter = new FunctionImporter();
25
+ return FeatureProgrammer.generate(
26
+ project,
27
+ CONFIG(project, importer),
28
+ importer,
29
+ (collection) => {
30
+ const isFunctors = IsProgrammer.generate_functors(
31
+ project,
32
+ importer,
33
+ )(collection);
34
+ const isUnioners = IsProgrammer.generate_unioners(
35
+ project,
36
+ importer,
37
+ )(collection);
38
+
39
+ return [
40
+ ...importer.declare(modulo),
41
+ ...isFunctors,
42
+ ...isUnioners,
43
+ ];
44
+ },
45
+ );
46
+ }
47
+
48
+ /* -----------------------------------------------------------
49
+ DECODERS
50
+ ----------------------------------------------------------- */
51
+ const decode =
52
+ (project: IProject, importer: FunctionImporter) =>
53
+ (
54
+ input: ts.Expression,
55
+ meta: Metadata,
56
+ explore: FeatureProgrammer.IExplore,
57
+ ): ts.ConciseBody => {
58
+ if (filter(meta) === false) return ts.factory.createBlock([]);
59
+
60
+ interface IUnion {
61
+ type: string;
62
+ is: () => ts.Expression;
63
+ value: () => ts.Expression | ts.Block | ts.ReturnStatement;
64
+ }
65
+ const unions: IUnion[] = [];
66
+
67
+ //----
68
+ // LIST UP UNION TYPES
69
+ //----
70
+ // TUPLES
71
+ for (const tuple of meta.tuples.filter((t) =>
72
+ t.some((e) => filter(e.rest ?? e)),
73
+ ))
74
+ unions.push({
75
+ type: "tuple",
76
+ is: () =>
77
+ IsProgrammer.decode(project, importer)(
78
+ input,
79
+ (() => {
80
+ const partial = Metadata.initialize();
81
+ partial.tuples.push(tuple);
82
+ return partial;
83
+ })(),
84
+ explore,
85
+ [],
86
+ ),
87
+ value: () =>
88
+ decode_tuple(project, importer)(input, tuple, explore),
89
+ });
90
+
91
+ // ARRAYS
92
+ if (meta.arrays.filter(filter).length)
93
+ unions.push({
94
+ type: "array",
95
+ is: () => ExpressionFactory.isArray(input),
96
+ value: () =>
97
+ explore_arrays(project, importer)(
98
+ input,
99
+ meta.arrays,
100
+ {
101
+ ...explore,
102
+ from: "array",
103
+ },
104
+ [],
105
+ ),
106
+ });
107
+
108
+ // BUILT-IN CLASSES
109
+ if (meta.natives.length)
110
+ for (const native of meta.natives)
111
+ unions.push({
112
+ type: "native",
113
+ is: () => ExpressionFactory.isInstanceOf(input, native),
114
+ value: () => ts.factory.createReturnStatement(),
115
+ });
116
+ if (meta.sets.length)
117
+ unions.push({
118
+ type: "set",
119
+ is: () => ExpressionFactory.isInstanceOf(input, "Set"),
120
+ value: () => ts.factory.createReturnStatement(),
121
+ });
122
+ if (meta.maps.length)
123
+ unions.push({
124
+ type: "map",
125
+ is: () => ExpressionFactory.isInstanceOf(input, "Map"),
126
+ value: () => ts.factory.createReturnStatement(),
127
+ });
128
+
129
+ // OBJECTS
130
+ if (meta.objects.length)
131
+ unions.push({
132
+ type: "object",
133
+ is: () =>
134
+ ExpressionFactory.isObject(input, {
135
+ checkNull: true,
136
+ checkArray: false,
137
+ }),
138
+ value: () =>
139
+ explore_objects(input, meta, {
140
+ ...explore,
141
+ from: "object",
142
+ }),
143
+ });
144
+
145
+ //----
146
+ // STATEMENTS
147
+ //----
148
+ const value = (v: ts.Expression | ts.Block | ts.ReturnStatement) =>
149
+ ts.isReturnStatement(v) || ts.isBlock(v)
150
+ ? v
151
+ : ts.factory.createExpressionStatement(v);
152
+ const statements: ts.Statement[] = unions.map((u) =>
153
+ ts.factory.createIfStatement(u.is(), value(u.value())),
154
+ );
155
+ return ts.factory.createBlock(statements, true);
156
+ };
157
+
158
+ const decode_tuple =
159
+ (project: IProject, importer: FunctionImporter) =>
160
+ (
161
+ input: ts.Expression,
162
+ tuple: Metadata[],
163
+ explore: FeatureProgrammer.IExplore,
164
+ ): ts.Block => {
165
+ const children: ts.ConciseBody[] = tuple
166
+ .map((elem, index) => [elem, index] as const)
167
+ .filter(([elem]) => filter(elem) && elem.rest === null)
168
+ .map(([elem, index]) =>
169
+ decode(project, importer)(
170
+ ts.factory.createElementAccessExpression(input, index),
171
+ elem,
172
+ {
173
+ ...explore,
174
+ from: "array",
175
+ },
176
+ ),
177
+ );
178
+ const rest = (() => {
179
+ if (tuple.length === 0) return null;
180
+
181
+ const last: Metadata = tuple[tuple.length - 1]!;
182
+ const rest: Metadata | null = last.rest;
183
+ if (rest === null || filter(rest) === false) return null;
184
+
185
+ return decode(project, importer)(
186
+ ts.factory.createCallExpression(
187
+ IdentifierFactory.join(input, "slice"),
188
+ undefined,
189
+ [ts.factory.createNumericLiteral(tuple.length - 1)],
190
+ ),
191
+ (() => {
192
+ const wrapper: Metadata = Metadata.initialize();
193
+ wrapper.arrays.push(rest);
194
+ return wrapper;
195
+ })(),
196
+ {
197
+ ...explore,
198
+ start: tuple.length - 1,
199
+ },
200
+ );
201
+ })();
202
+ return PruneJoiner.tuple(children, rest);
203
+ };
204
+
205
+ const decode_array = (project: IProject, importer: FunctionImporter) =>
206
+ FeatureProgrammer.decode_array(
207
+ CONFIG(project, importer),
208
+ importer,
209
+ PruneJoiner.array,
210
+ );
211
+
212
+ const decode_object = () =>
213
+ FeatureProgrammer.decode_object({
214
+ trace: false,
215
+ path: false,
216
+ functors: FUNCTORS,
217
+ });
218
+
219
+ const explore_arrays = (project: IProject, importer: FunctionImporter) =>
220
+ UnionExplorer.array({
221
+ checker: IsProgrammer.decode(project, importer),
222
+ decoder: decode_array(project, importer),
223
+ empty: ts.factory.createReturnStatement(),
224
+ success: ts.factory.createTrue(),
225
+ failure: (input, expected) =>
226
+ create_throw_error(importer, input, expected),
227
+ });
228
+
229
+ const explore_objects = (
230
+ input: ts.Expression,
231
+ meta: Metadata,
232
+ explore: FeatureProgrammer.IExplore,
233
+ ) => {
234
+ if (meta.objects.length === 1)
235
+ return decode_object()(input, meta.objects[0]!, explore);
236
+
237
+ return ts.factory.createCallExpression(
238
+ ts.factory.createIdentifier(`${UNIONERS}${meta.union_index!}`),
239
+ undefined,
240
+ [input],
241
+ );
242
+ };
243
+
244
+ const filter = (meta: Metadata): boolean =>
245
+ meta.any === false &&
246
+ (meta.objects.length !== 0 ||
247
+ meta.tuples.some((t) => t.some((e) => filter(e.rest ?? e))) ||
248
+ meta.arrays.some((e) => filter(e)));
249
+
250
+ /* -----------------------------------------------------------
251
+ CONFIGURATIONS
252
+ ----------------------------------------------------------- */
253
+ const FUNCTORS = "$po";
254
+ const UNIONERS = "$pu";
255
+
256
+ const CONFIG = (
257
+ project: IProject,
258
+ importer: FunctionImporter,
259
+ ): FeatureProgrammer.IConfig => ({
260
+ functors: FUNCTORS,
261
+ unioners: UNIONERS,
262
+ trace: false,
263
+ path: false,
264
+ initializer,
265
+ decoder: decode(project, importer),
266
+ objector: OBJECTOR(project, importer),
267
+ });
268
+
269
+ const OBJECTOR = (
270
+ project: IProject,
271
+ importer: FunctionImporter,
272
+ ): FeatureProgrammer.IConfig.IObjector => ({
273
+ checker: IsProgrammer.decode(project, importer),
274
+ decoder: decode_object(),
275
+ joiner: PruneJoiner.object,
276
+ unionizer: decode_union_object(IsProgrammer.decode_object(importer))(
277
+ decode_object(),
278
+ )((exp) => exp)((value, expected) =>
279
+ create_throw_error(importer, value, expected),
280
+ ),
281
+ failure: (input, expected) =>
282
+ create_throw_error(importer, input, expected),
283
+ });
284
+
285
+ const initializer: FeatureProgrammer.IConfig["initializer"] = (
286
+ { checker },
287
+ type,
288
+ ) => {
289
+ const collection = new MetadataCollection();
290
+ const meta = MetadataFactory.generate(checker, collection, type, {
291
+ resolve: false,
292
+ constant: true,
293
+ });
294
+ return [collection, meta];
295
+ };
296
+
297
+ const create_throw_error = (
298
+ importer: FunctionImporter,
299
+ value: ts.Expression,
300
+ expected: string,
301
+ ) =>
302
+ ts.factory.createExpressionStatement(
303
+ ts.factory.createCallExpression(
304
+ importer.use("throws"),
305
+ [],
306
+ [
307
+ ts.factory.createObjectLiteralExpression(
308
+ [
309
+ ts.factory.createPropertyAssignment(
310
+ "expected",
311
+ ts.factory.createStringLiteral(expected),
312
+ ),
313
+ ts.factory.createPropertyAssignment("value", value),
314
+ ],
315
+ true,
316
+ ),
317
+ ],
318
+ ),
319
+ );
320
+ }