typia 7.0.0-dev.20240929 → 7.0.0-dev.20241001

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 (172) hide show
  1. package/lib/index.mjs +25 -25
  2. package/lib/index.mjs.map +1 -1
  3. package/lib/programmers/AssertProgrammer.js +34 -27
  4. package/lib/programmers/AssertProgrammer.js.map +1 -1
  5. package/lib/programmers/CheckerProgrammer.d.ts +5 -1
  6. package/lib/programmers/CheckerProgrammer.js +432 -348
  7. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  8. package/lib/programmers/FeatureProgrammer.d.ts +91 -28
  9. package/lib/programmers/FeatureProgrammer.js +165 -138
  10. package/lib/programmers/FeatureProgrammer.js.map +1 -1
  11. package/lib/programmers/IsProgrammer.d.ts +5 -1
  12. package/lib/programmers/IsProgrammer.js +87 -66
  13. package/lib/programmers/IsProgrammer.js.map +1 -1
  14. package/lib/programmers/RandomProgrammer.js +83 -68
  15. package/lib/programmers/RandomProgrammer.js.map +1 -1
  16. package/lib/programmers/TypiaProgrammer.d.ts +2 -2
  17. package/lib/programmers/TypiaProgrammer.js +79 -75
  18. package/lib/programmers/TypiaProgrammer.js.map +1 -1
  19. package/lib/programmers/ValidateProgrammer.js +45 -19
  20. package/lib/programmers/ValidateProgrammer.js.map +1 -1
  21. package/lib/programmers/helpers/CloneJoiner.js +4 -1
  22. package/lib/programmers/helpers/CloneJoiner.js.map +1 -1
  23. package/lib/programmers/helpers/NotationJoiner.d.ts +2 -1
  24. package/lib/programmers/helpers/NotationJoiner.js +34 -33
  25. package/lib/programmers/helpers/NotationJoiner.js.map +1 -1
  26. package/lib/programmers/helpers/PruneJoiner.js +4 -1
  27. package/lib/programmers/helpers/PruneJoiner.js.map +1 -1
  28. package/lib/programmers/helpers/RandomJoiner.d.ts +1 -1
  29. package/lib/programmers/helpers/RandomJoiner.js.map +1 -1
  30. package/lib/programmers/helpers/RandomRanger.js.map +1 -1
  31. package/lib/programmers/helpers/StringifyJoinder.js +4 -1
  32. package/lib/programmers/helpers/StringifyJoinder.js.map +1 -1
  33. package/lib/programmers/helpers/StringifyPredicator.d.ts +1 -1
  34. package/lib/programmers/helpers/StringifyPredicator.js +4 -3
  35. package/lib/programmers/helpers/StringifyPredicator.js.map +1 -1
  36. package/lib/programmers/helpers/UnionExplorer.d.ts +52 -12
  37. package/lib/programmers/helpers/UnionExplorer.js +184 -120
  38. package/lib/programmers/helpers/UnionExplorer.js.map +1 -1
  39. package/lib/programmers/helpers/UnionPredicator.d.ts +1 -1
  40. package/lib/programmers/helpers/UnionPredicator.js +7 -7
  41. package/lib/programmers/http/HttpFormDataProgrammer.js +77 -70
  42. package/lib/programmers/http/HttpFormDataProgrammer.js.map +1 -1
  43. package/lib/programmers/http/HttpHeadersProgrammer.js +69 -68
  44. package/lib/programmers/http/HttpHeadersProgrammer.js.map +1 -1
  45. package/lib/programmers/http/HttpQueryProgrammer.js +69 -62
  46. package/lib/programmers/http/HttpQueryProgrammer.js.map +1 -1
  47. package/lib/programmers/internal/application_escaped.js +4 -4
  48. package/lib/programmers/internal/application_escaped.js.map +1 -1
  49. package/lib/programmers/internal/application_templates.js +8 -2
  50. package/lib/programmers/internal/application_templates.js.map +1 -1
  51. package/lib/programmers/internal/application_union_discriminator.d.ts +1 -1
  52. package/lib/programmers/internal/application_union_discriminator.js +6 -6
  53. package/lib/programmers/internal/application_union_discriminator.js.map +1 -1
  54. package/lib/programmers/internal/application_v30_object.js +6 -3
  55. package/lib/programmers/internal/application_v30_object.js.map +1 -1
  56. package/lib/programmers/internal/application_v31_object.js +4 -1
  57. package/lib/programmers/internal/application_v31_object.js.map +1 -1
  58. package/lib/programmers/internal/check_array_length.js +21 -26
  59. package/lib/programmers/internal/check_array_length.js.map +1 -1
  60. package/lib/programmers/internal/check_bigint.js +18 -26
  61. package/lib/programmers/internal/check_bigint.js.map +1 -1
  62. package/lib/programmers/internal/check_dynamic_key.d.ts +1 -5
  63. package/lib/programmers/internal/check_dynamic_key.js +109 -91
  64. package/lib/programmers/internal/check_dynamic_key.js.map +1 -1
  65. package/lib/programmers/internal/check_dynamic_properties.js +88 -90
  66. package/lib/programmers/internal/check_dynamic_properties.js.map +1 -1
  67. package/lib/programmers/internal/check_native.js +8 -5
  68. package/lib/programmers/internal/check_native.js.map +1 -1
  69. package/lib/programmers/internal/check_number.js +59 -65
  70. package/lib/programmers/internal/check_number.js.map +1 -1
  71. package/lib/programmers/internal/check_object.js +31 -22
  72. package/lib/programmers/internal/check_object.js.map +1 -1
  73. package/lib/programmers/internal/check_string.js +18 -26
  74. package/lib/programmers/internal/check_string.js.map +1 -1
  75. package/lib/programmers/internal/check_template.js +20 -21
  76. package/lib/programmers/internal/check_template.js.map +1 -1
  77. package/lib/programmers/internal/check_union_array_like.js +68 -53
  78. package/lib/programmers/internal/check_union_array_like.js.map +1 -1
  79. package/lib/programmers/internal/decode_union_object.js +59 -49
  80. package/lib/programmers/internal/decode_union_object.js.map +1 -1
  81. package/lib/programmers/internal/feature_object_entries.js +31 -33
  82. package/lib/programmers/internal/feature_object_entries.js.map +1 -1
  83. package/lib/programmers/internal/llm_schema_escaped.js +29 -11
  84. package/lib/programmers/internal/llm_schema_escaped.js.map +1 -1
  85. package/lib/programmers/internal/llm_schema_object.js +4 -1
  86. package/lib/programmers/internal/llm_schema_object.js.map +1 -1
  87. package/lib/programmers/internal/metadata_to_pattern.js +44 -41
  88. package/lib/programmers/internal/metadata_to_pattern.js.map +1 -1
  89. package/lib/programmers/internal/postfix_of_tuple.d.ts +1 -1
  90. package/lib/programmers/internal/postfix_of_tuple.js +3 -0
  91. package/lib/programmers/internal/postfix_of_tuple.js.map +1 -1
  92. package/lib/programmers/internal/prune_object_properties.js +6 -3
  93. package/lib/programmers/internal/prune_object_properties.js.map +1 -1
  94. package/lib/programmers/internal/random_custom.js +8 -14
  95. package/lib/programmers/internal/random_custom.js.map +1 -1
  96. package/lib/programmers/internal/stringify_dynamic_properties.js +4 -1
  97. package/lib/programmers/internal/stringify_dynamic_properties.js.map +1 -1
  98. package/lib/programmers/internal/stringify_regular_properties.js +4 -4
  99. package/lib/programmers/internal/stringify_regular_properties.js.map +1 -1
  100. package/lib/programmers/internal/template_to_pattern.js +10 -5
  101. package/lib/programmers/internal/template_to_pattern.js.map +1 -1
  102. package/lib/programmers/internal/wrap_metadata_rest_tuple.d.ts +1 -2
  103. package/lib/programmers/internal/wrap_metadata_rest_tuple.js +3 -0
  104. package/lib/programmers/internal/wrap_metadata_rest_tuple.js.map +1 -1
  105. package/lib/programmers/json/JsonStringifyProgrammer.js +154 -91
  106. package/lib/programmers/json/JsonStringifyProgrammer.js.map +1 -1
  107. package/lib/programmers/misc/MiscCloneProgrammer.js +221 -154
  108. package/lib/programmers/misc/MiscCloneProgrammer.js.map +1 -1
  109. package/lib/programmers/misc/MiscPruneProgrammer.js +139 -89
  110. package/lib/programmers/misc/MiscPruneProgrammer.js.map +1 -1
  111. package/lib/programmers/notations/NotationGeneralProgrammer.d.ts +4 -1
  112. package/lib/programmers/notations/NotationGeneralProgrammer.js +257 -148
  113. package/lib/programmers/notations/NotationGeneralProgrammer.js.map +1 -1
  114. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js +32 -24
  115. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js.map +1 -1
  116. package/lib/utils/NamingConvention/NamingConvention.js +41 -47
  117. package/lib/utils/NamingConvention/NamingConvention.js.map +1 -1
  118. package/package.json +1 -1
  119. package/src/programmers/AssertProgrammer.ts +44 -37
  120. package/src/programmers/CheckerProgrammer.ts +394 -358
  121. package/src/programmers/FeatureProgrammer.ts +327 -267
  122. package/src/programmers/IsProgrammer.ts +93 -76
  123. package/src/programmers/RandomProgrammer.ts +18 -9
  124. package/src/programmers/TypiaProgrammer.ts +48 -34
  125. package/src/programmers/ValidateProgrammer.ts +56 -29
  126. package/src/programmers/helpers/CloneJoiner.ts +4 -1
  127. package/src/programmers/helpers/NotationJoiner.ts +85 -83
  128. package/src/programmers/helpers/ProtobufUtil.ts +2 -2
  129. package/src/programmers/helpers/PruneJoiner.ts +4 -1
  130. package/src/programmers/helpers/RandomJoiner.ts +5 -2
  131. package/src/programmers/helpers/RandomRanger.ts +8 -1
  132. package/src/programmers/helpers/StringifyJoinder.ts +4 -1
  133. package/src/programmers/helpers/StringifyPredicator.ts +4 -3
  134. package/src/programmers/helpers/UnionExplorer.ts +277 -179
  135. package/src/programmers/helpers/UnionPredicator.ts +5 -5
  136. package/src/programmers/http/HttpFormDataProgrammer.ts +135 -114
  137. package/src/programmers/http/HttpHeadersProgrammer.ts +145 -120
  138. package/src/programmers/http/HttpQueryProgrammer.ts +137 -116
  139. package/src/programmers/internal/application_escaped.ts +6 -6
  140. package/src/programmers/internal/application_templates.ts +8 -6
  141. package/src/programmers/internal/application_union_discriminator.ts +6 -6
  142. package/src/programmers/internal/application_v30_object.ts +6 -3
  143. package/src/programmers/internal/application_v31_object.ts +4 -1
  144. package/src/programmers/internal/application_v31_tuple.ts +1 -1
  145. package/src/programmers/internal/check_array_length.ts +31 -30
  146. package/src/programmers/internal/check_bigint.ts +31 -31
  147. package/src/programmers/internal/check_dynamic_key.ts +155 -126
  148. package/src/programmers/internal/check_dynamic_properties.ts +152 -154
  149. package/src/programmers/internal/check_native.ts +11 -5
  150. package/src/programmers/internal/check_number.ts +88 -84
  151. package/src/programmers/internal/check_object.ts +45 -31
  152. package/src/programmers/internal/check_string.ts +31 -30
  153. package/src/programmers/internal/check_template.ts +34 -32
  154. package/src/programmers/internal/check_union_array_like.ts +245 -228
  155. package/src/programmers/internal/decode_union_object.ts +92 -75
  156. package/src/programmers/internal/feature_object_entries.ts +36 -36
  157. package/src/programmers/internal/llm_schema_escaped.ts +36 -13
  158. package/src/programmers/internal/llm_schema_object.ts +4 -1
  159. package/src/programmers/internal/metadata_to_pattern.ts +31 -23
  160. package/src/programmers/internal/postfix_of_tuple.ts +3 -0
  161. package/src/programmers/internal/prune_object_properties.ts +6 -3
  162. package/src/programmers/internal/random_custom.ts +24 -23
  163. package/src/programmers/internal/stringify_dynamic_properties.ts +4 -1
  164. package/src/programmers/internal/stringify_regular_properties.ts +7 -7
  165. package/src/programmers/internal/template_to_pattern.ts +12 -4
  166. package/src/programmers/internal/wrap_metadata_rest_tuple.ts +3 -0
  167. package/src/programmers/json/JsonStringifyProgrammer.ts +151 -104
  168. package/src/programmers/misc/MiscCloneProgrammer.ts +255 -204
  169. package/src/programmers/misc/MiscPruneProgrammer.ts +149 -116
  170. package/src/programmers/notations/NotationGeneralProgrammer.ts +307 -211
  171. package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +25 -21
  172. package/src/utils/NamingConvention/NamingConvention.ts +40 -42
@@ -20,8 +20,8 @@ import { feature_object_entries } from "./internal/feature_object_entries";
20
20
 
21
21
  export namespace FeatureProgrammer {
22
22
  /* -----------------------------------------------------------
23
- PARAMETERS
24
- ----------------------------------------------------------- */
23
+ PARAMETERS
24
+ ----------------------------------------------------------- */
25
25
  export interface IConfig<Output extends ts.ConciseBody = ts.ConciseBody> {
26
26
  types: IConfig.ITypes;
27
27
 
@@ -45,16 +45,20 @@ export namespace FeatureProgrammer {
45
45
  /**
46
46
  * Initializer of metadata.
47
47
  */
48
- initializer: (
49
- context: ITypiaContext,
50
- ) => (
51
- importer: FunctionImporter,
52
- ) => (type: ts.Type) => [MetadataCollection, Metadata];
48
+ initializer: (props: {
49
+ context: ITypiaContext;
50
+ importer: FunctionImporter;
51
+ type: ts.Type;
52
+ }) => [MetadataCollection, Metadata];
53
53
 
54
54
  /**
55
55
  * Decoder, station of every types.
56
56
  */
57
- decoder: () => Decoder<Metadata, Output>;
57
+ decoder: (props: {
58
+ metadata: Metadata;
59
+ input: ts.Expression;
60
+ explore: IExplore;
61
+ }) => Output;
58
62
 
59
63
  /**
60
64
  * Object configurator.
@@ -76,12 +80,20 @@ export namespace FeatureProgrammer {
76
80
  /**
77
81
  * Type checker when union object type comes.
78
82
  */
79
- checker: () => Decoder<Metadata, ts.Expression>;
83
+ checker: (props: {
84
+ metadata: Metadata;
85
+ input: ts.Expression;
86
+ explore: IExplore;
87
+ }) => ts.Expression;
80
88
 
81
89
  /**
82
90
  * Decoder, function call expression generator of specific typed objects.
83
91
  */
84
- decoder: () => Decoder<MetadataObject, ts.Expression>;
92
+ decoder: (props: {
93
+ input: ts.Expression;
94
+ object: MetadataObject;
95
+ explore: IExplore;
96
+ }) => ts.Expression;
85
97
 
86
98
  /**
87
99
  * Joiner of expressions from properties.
@@ -98,21 +110,23 @@ export namespace FeatureProgrammer {
98
110
  * Expression of an algorithm specifying object type and calling
99
111
  * the `decoder` function of the specified object type.
100
112
  */
101
- unionizer: Decoder<MetadataObject[], ts.Expression>;
113
+ unionizer: (props: {
114
+ objects: MetadataObject[];
115
+ input: ts.Expression;
116
+ explore: IExplore;
117
+ }) => ts.Expression;
102
118
 
103
119
  /**
104
120
  * Handler of union type specification failure.
105
121
  *
106
- * @param value Expression of input parameter
107
- * @param expected Expected type name
108
- * @param explore Exploration info
122
+ * @param props Properties of failure
109
123
  * @returns Statement of failure
110
124
  */
111
- failure(
112
- value: ts.Expression,
113
- expected: string,
114
- explore?: undefined | IExplore,
115
- ): ts.Statement;
125
+ failure(props: {
126
+ input: ts.Expression;
127
+ expected: string;
128
+ explore?: undefined | IExplore;
129
+ }): ts.Statement;
116
130
 
117
131
  /**
118
132
  * Transformer of type checking expression by discrimination.
@@ -153,18 +167,17 @@ export namespace FeatureProgrammer {
153
167
  * iteration type checking would be happend. In such circumstance, you
154
168
  * can wrap the condition with additional function.
155
169
  *
156
- * @param condition Current condition
157
- * @returns A function wrapped current condition
170
+ * @param props Properties of condition
171
+ * @returns The wrapper expression
158
172
  */
159
173
  full?:
160
174
  | undefined
161
- | ((
162
- condition: ts.Expression,
163
- ) => (
164
- input: ts.Expression,
165
- expected: string,
166
- explore: IExplore,
167
- ) => ts.Expression);
175
+ | ((props: {
176
+ condition: ts.Expression;
177
+ input: ts.Expression;
178
+ expected: string;
179
+ explore: IExplore;
180
+ }) => ts.Expression);
168
181
 
169
182
  /**
170
183
  * Return type.
@@ -174,12 +187,12 @@ export namespace FeatureProgrammer {
174
187
  export interface IGenerator {
175
188
  objects?:
176
189
  | undefined
177
- | (() => (col: MetadataCollection) => ts.VariableStatement[]);
190
+ | ((collection: MetadataCollection) => ts.VariableStatement[]);
178
191
  unions?:
179
192
  | undefined
180
- | (() => (col: MetadataCollection) => ts.VariableStatement[]);
181
- arrays(): (col: MetadataCollection) => ts.VariableStatement[];
182
- tuples(): (col: MetadataCollection) => ts.VariableStatement[];
193
+ | ((collection: MetadataCollection) => ts.VariableStatement[]);
194
+ arrays: (collection: MetadataCollection) => ts.VariableStatement[];
195
+ tuples: (collection: MetadataCollection) => ts.VariableStatement[];
183
196
  }
184
197
  }
185
198
 
@@ -191,9 +204,14 @@ export namespace FeatureProgrammer {
191
204
  start?: undefined | number;
192
205
  }
193
206
 
194
- export interface Decoder<T, Output extends ts.ConciseBody = ts.ConciseBody> {
195
- (input: ts.Expression, target: T, explore: IExplore): Output;
196
- }
207
+ export type Decoder<
208
+ T,
209
+ Output extends ts.ConciseBody = ts.ConciseBody,
210
+ > = (props: {
211
+ input: ts.Expression;
212
+ definition: T;
213
+ explore: IExplore;
214
+ }) => Output;
197
215
 
198
216
  /* -----------------------------------------------------------
199
217
  GENERATORS
@@ -218,15 +236,17 @@ export namespace FeatureProgrammer {
218
236
  type: ts.Type;
219
237
  name: string | undefined;
220
238
  }): IComposed => {
221
- const [collection, meta] = props.config.initializer(props.context)(
222
- props.importer,
223
- )(props.type);
239
+ const [collection, metadata] = props.config.initializer(props);
224
240
  return {
225
- body: props.config.decoder()(ValueFactory.INPUT(), meta, {
226
- tracable: props.config.path || props.config.trace,
227
- source: "top",
228
- from: "top",
229
- postfix: '""',
241
+ body: props.config.decoder({
242
+ input: ValueFactory.INPUT(),
243
+ metadata,
244
+ explore: {
245
+ tracable: props.config.path || props.config.trace,
246
+ source: "top",
247
+ from: "top",
248
+ postfix: '""',
249
+ },
230
250
  }),
231
251
  statements: props.config.addition
232
252
  ? props.config.addition(collection)
@@ -234,7 +254,7 @@ export namespace FeatureProgrammer {
234
254
  functions: {
235
255
  ...Object.fromEntries(
236
256
  (
237
- props.config.generator.objects?.()(collection) ??
257
+ props.config.generator.objects?.(collection) ??
238
258
  write_object_functions({
239
259
  ...props,
240
260
  collection,
@@ -243,24 +263,29 @@ export namespace FeatureProgrammer {
243
263
  ),
244
264
  ...Object.fromEntries(
245
265
  (
246
- props.config.generator.unions?.() ??
247
- write_union_functions(props.config)
248
- )(collection).map((v, i) => [`${props.config.prefix}u${i}`, v]),
266
+ props.config.generator.unions?.(collection) ??
267
+ write_union_functions({
268
+ config: props.config,
269
+ collection,
270
+ })
271
+ ).map((v, i) => [`${props.config.prefix}u${i}`, v]),
249
272
  ),
250
273
  ...Object.fromEntries(
251
274
  props.config.generator
252
- .arrays()(collection)
275
+ .arrays(collection)
253
276
  .map((v, i) => [`${props.config.prefix}a${i}`, v]),
254
277
  ),
255
278
  ...Object.fromEntries(
256
279
  props.config.generator
257
- .tuples()(collection)
280
+ .tuples(collection)
258
281
  .map((v, i) => [`${props.config.prefix}t${i}`, v]),
259
282
  ),
260
283
  },
261
- parameters: parameterDeclarations(props.config)(
262
- props.config.types.input(props.type, props.name),
263
- )(ValueFactory.INPUT()),
284
+ parameters: parameterDeclarations({
285
+ config: props.config,
286
+ type: props.config.types.input(props.type, props.name),
287
+ input: ValueFactory.INPUT(),
288
+ }),
264
289
  response: props.config.types.output(props.type, props.name),
265
290
  };
266
291
  };
@@ -290,73 +315,81 @@ export namespace FeatureProgrammer {
290
315
  undefined,
291
316
  );
292
317
 
293
- export const write =
294
- (context: ITypiaContext) =>
295
- (config: IConfig) =>
296
- (importer: FunctionImporter) =>
297
- (type: ts.Type, name?: string): ts.ArrowFunction => {
298
- const [collection, meta] = config.initializer(context)(importer)(type);
299
-
300
- // ITERATE OVER ALL METADATA
301
- const output: ts.ConciseBody = config.decoder()(
302
- ValueFactory.INPUT(),
303
- meta,
304
- {
305
- tracable: config.path || config.trace,
306
- source: "top",
307
- from: "top",
308
- postfix: '""',
309
- },
310
- );
311
-
312
- // RETURNS THE OPTIMAL ARROW FUNCTION
313
- const functions = {
314
- objects:
315
- config.generator.objects?.()(collection) ??
316
- write_object_functions({
317
- config,
318
- importer,
319
- collection,
320
- }),
321
- unions: (config.generator.unions?.() ?? write_union_functions(config))(
318
+ export const write = (props: {
319
+ context: ITypiaContext;
320
+ config: IConfig;
321
+ importer: FunctionImporter;
322
+ type: ts.Type;
323
+ name?: string | undefined;
324
+ }): ts.ArrowFunction => {
325
+ // ITERATE OVER ALL METADATA
326
+ const [collection, metadata] = props.config.initializer(props);
327
+ const output: ts.ConciseBody = props.config.decoder({
328
+ metadata,
329
+ input: ValueFactory.INPUT(),
330
+ explore: {
331
+ tracable: props.config.path || props.config.trace,
332
+ source: "top",
333
+ from: "top",
334
+ postfix: '""',
335
+ },
336
+ });
337
+
338
+ // RETURNS THE OPTIMAL ARROW FUNCTION
339
+ const functions = {
340
+ objects:
341
+ props.config.generator.objects?.(collection) ??
342
+ write_object_functions({
343
+ config: props.config,
344
+ importer: props.importer,
322
345
  collection,
323
- ),
324
- arrays: config.generator.arrays()(collection),
325
- tuples: config.generator.tuples()(collection),
326
- };
327
- const added: ts.Statement[] = (config.addition ?? (() => []))(collection);
328
-
329
- return ts.factory.createArrowFunction(
330
- undefined,
331
- undefined,
332
- parameterDeclarations(config)(config.types.input(type, name))(
333
- ValueFactory.INPUT(),
334
- ),
335
- config.types.output(type, name),
336
- undefined,
337
- ts.factory.createBlock(
338
- [
339
- ...added,
340
- ...functions.objects.filter((_, i) =>
341
- importer.hasLocal(`${config.prefix}o${i}`),
342
- ),
343
- ...functions.unions.filter((_, i) =>
344
- importer.hasLocal(`${config.prefix}u${i}`),
345
- ),
346
- ...functions.arrays.filter((_, i) =>
347
- importer.hasLocal(`${config.prefix}a${i}`),
348
- ),
349
- ...functions.tuples.filter((_, i) =>
350
- importer.hasLocal(`${config.prefix}t${i}`),
351
- ),
352
- ...(ts.isBlock(output)
353
- ? output.statements
354
- : [ts.factory.createReturnStatement(output)]),
355
- ],
356
- true,
357
- ),
358
- );
346
+ }),
347
+ unions:
348
+ props.config.generator.unions?.(collection) ??
349
+ write_union_functions({
350
+ config: props.config,
351
+ collection,
352
+ }),
353
+ arrays: props.config.generator.arrays(collection),
354
+ tuples: props.config.generator.tuples(collection),
359
355
  };
356
+ const added: ts.Statement[] = (props.config.addition ?? (() => []))(
357
+ collection,
358
+ );
359
+
360
+ return ts.factory.createArrowFunction(
361
+ undefined,
362
+ undefined,
363
+ parameterDeclarations({
364
+ config: props.config,
365
+ type: props.config.types.input(props.type, props.name),
366
+ input: ValueFactory.INPUT(),
367
+ }),
368
+ props.config.types.output(props.type, props.name),
369
+ undefined,
370
+ ts.factory.createBlock(
371
+ [
372
+ ...added,
373
+ ...functions.objects.filter((_, i) =>
374
+ props.importer.hasLocal(`${props.config.prefix}o${i}`),
375
+ ),
376
+ ...functions.unions.filter((_, i) =>
377
+ props.importer.hasLocal(`${props.config.prefix}u${i}`),
378
+ ),
379
+ ...functions.arrays.filter((_, i) =>
380
+ props.importer.hasLocal(`${props.config.prefix}a${i}`),
381
+ ),
382
+ ...functions.tuples.filter((_, i) =>
383
+ props.importer.hasLocal(`${props.config.prefix}t${i}`),
384
+ ),
385
+ ...(ts.isBlock(output)
386
+ ? output.statements
387
+ : [ts.factory.createReturnStatement(output)]),
388
+ ],
389
+ true,
390
+ ),
391
+ );
392
+ };
360
393
 
361
394
  export const write_object_functions = (props: {
362
395
  config: IConfig;
@@ -369,188 +402,215 @@ export namespace FeatureProgrammer {
369
402
  ts.factory.createArrowFunction(
370
403
  undefined,
371
404
  undefined,
372
- parameterDeclarations(props.config)(TypeFactory.keyword("any"))(
373
- ValueFactory.INPUT(),
374
- ),
405
+ parameterDeclarations({
406
+ config: props.config,
407
+ type: TypeFactory.keyword("any"),
408
+ input: ValueFactory.INPUT(),
409
+ }),
375
410
  props.config.objector.type ?? TypeFactory.keyword("any"),
376
411
  undefined,
377
412
  props.config.objector.joiner({
378
413
  input: ts.factory.createIdentifier("input"),
379
- entries: feature_object_entries(props.config)(props.importer)(
414
+ entries: feature_object_entries({
415
+ config: props.config,
416
+ importer: props.importer,
417
+ input: ts.factory.createIdentifier("input"),
380
418
  object,
381
- )(ts.factory.createIdentifier("input")),
419
+ }),
382
420
  object,
383
421
  }),
384
422
  ),
385
423
  ),
386
424
  );
387
425
 
388
- export const write_union_functions =
389
- (config: IConfig) => (collection: MetadataCollection) =>
390
- collection
391
- .unions()
392
- .map((union, i) =>
393
- StatementFactory.constant(
394
- `${config.prefix}u${i}`,
395
- write_union(config)(union),
396
- ),
397
- );
398
-
399
- const write_union = (config: IConfig) => {
400
- const explorer = UnionExplorer.object(config);
401
- const input = ValueFactory.INPUT();
426
+ export const write_union_functions = (props: {
427
+ config: IConfig;
428
+ collection: MetadataCollection;
429
+ }) =>
430
+ props.collection.unions().map((union, i) =>
431
+ StatementFactory.constant(
432
+ `${props.config.prefix}u${i}`,
433
+ write_union({
434
+ config: props.config,
435
+ objects: union,
436
+ }),
437
+ ),
438
+ );
402
439
 
403
- return (meta: MetadataObject[]) =>
404
- ts.factory.createArrowFunction(
405
- undefined,
406
- undefined,
407
- parameterDeclarations(config)(TypeFactory.keyword("any"))(
408
- ValueFactory.INPUT(),
409
- ),
410
- TypeFactory.keyword("any"),
411
- undefined,
412
- explorer(input, meta, {
413
- tracable: config.path || config.trace,
440
+ const write_union = (props: { config: IConfig; objects: MetadataObject[] }) =>
441
+ ts.factory.createArrowFunction(
442
+ undefined,
443
+ undefined,
444
+ parameterDeclarations({
445
+ config: props.config,
446
+ type: TypeFactory.keyword("any"),
447
+ input: ValueFactory.INPUT(),
448
+ }),
449
+ TypeFactory.keyword("any"),
450
+ undefined,
451
+ UnionExplorer.object({
452
+ config: props.config,
453
+ objects: props.objects,
454
+ input: ValueFactory.INPUT(),
455
+ explore: {
456
+ tracable: props.config.path || props.config.trace,
414
457
  source: "function",
415
458
  from: "object",
416
459
  postfix: "",
417
- }),
418
- );
419
- };
460
+ },
461
+ }),
462
+ );
420
463
 
421
464
  /* -----------------------------------------------------------
422
465
  DECODERS
423
466
  ----------------------------------------------------------- */
424
- export const decode_array =
425
- (config: Pick<IConfig, "trace" | "path" | "decoder" | "prefix">) =>
426
- (importer: FunctionImporter) =>
427
- (
428
- combiner: (props: {
429
- input: ts.Expression;
430
- arrow: ts.ArrowFunction;
431
- }) => ts.Expression,
432
- ) => {
433
- const rand: string = importer.increment().toString();
434
- const tail =
435
- config.path || config.trace
436
- ? [
437
- IdentifierFactory.parameter(
438
- "_index" + rand,
439
- TypeFactory.keyword("number"),
440
- ),
441
- ]
442
- : [];
443
- return (
444
- input: ts.Expression,
445
- array: MetadataArray,
446
- explore: IExplore,
447
- ) => {
448
- const arrow: ts.ArrowFunction = ts.factory.createArrowFunction(
449
- undefined,
450
- undefined,
451
- [
452
- IdentifierFactory.parameter("elem", TypeFactory.keyword("any")),
453
- ...tail,
454
- ],
455
- undefined,
456
- undefined,
457
- config.decoder()(ValueFactory.INPUT("elem"), array.type.value, {
458
- tracable: explore.tracable,
459
- source: explore.source,
460
- from: "array",
461
- postfix: index(explore.start ?? null)(explore.postfix)(rand),
467
+ export const decode_array = (props: {
468
+ config: Pick<IConfig, "trace" | "path" | "decoder" | "prefix">;
469
+ importer: FunctionImporter;
470
+ combiner: (next: {
471
+ input: ts.Expression;
472
+ arrow: ts.ArrowFunction;
473
+ }) => ts.Expression;
474
+ array: MetadataArray;
475
+ input: ts.Expression;
476
+ explore: IExplore;
477
+ }) => {
478
+ const rand: string = props.importer.increment().toString();
479
+ const tail =
480
+ props.config.path || props.config.trace
481
+ ? [
482
+ IdentifierFactory.parameter(
483
+ "_index" + rand,
484
+ TypeFactory.keyword("number"),
485
+ ),
486
+ ]
487
+ : [];
488
+ const arrow: ts.ArrowFunction = ts.factory.createArrowFunction(
489
+ undefined,
490
+ undefined,
491
+ [
492
+ IdentifierFactory.parameter("elem", TypeFactory.keyword("any")),
493
+ ...tail,
494
+ ],
495
+ undefined,
496
+ undefined,
497
+ props.config.decoder({
498
+ input: ValueFactory.INPUT("elem"),
499
+ metadata: props.array.type.value,
500
+ explore: {
501
+ tracable: props.explore.tracable,
502
+ source: props.explore.source,
503
+ from: "array",
504
+ postfix: index({
505
+ start: props.explore.start ?? null,
506
+ postfix: props.explore.postfix,
507
+ rand,
462
508
  }),
463
- );
464
- return combiner({
465
- input,
466
- arrow,
467
- });
468
- };
469
- };
509
+ },
510
+ }),
511
+ );
512
+ return props.combiner({
513
+ input: props.input,
514
+ arrow,
515
+ });
516
+ };
470
517
 
471
- export const decode_object =
472
- (config: Pick<IConfig, "trace" | "path" | "prefix">) =>
473
- (importer: FunctionImporter) =>
474
- (input: ts.Expression, obj: MetadataObject, explore: IExplore) =>
475
- ts.factory.createCallExpression(
476
- ts.factory.createIdentifier(
477
- importer.useLocal(`${config.prefix}o${obj.index}`),
478
- ),
479
- undefined,
480
- argumentsArray(config)(explore)(input),
481
- );
518
+ export const decode_object = (props: {
519
+ config: Pick<IConfig, "trace" | "path" | "prefix">;
520
+ importer: FunctionImporter;
521
+ object: MetadataObject;
522
+ input: ts.Expression;
523
+ explore: IExplore;
524
+ }) =>
525
+ ts.factory.createCallExpression(
526
+ ts.factory.createIdentifier(
527
+ props.importer.useLocal(`${props.config.prefix}o${props.object.index}`),
528
+ ),
529
+ undefined,
530
+ argumentsArray(props),
531
+ );
482
532
 
483
533
  /* -----------------------------------------------------------
484
534
  UTILITIES FOR INTERNAL FUNCTIONS
485
535
  ----------------------------------------------------------- */
486
- export const index =
487
- (start: number | null) => (prev: string) => (rand: string) => {
488
- const tail: string =
489
- start !== null
490
- ? `"[" + (${start} + _index${rand}) + "]"`
491
- : `"[" + _index${rand} + "]"`;
492
- if (prev === "") return tail;
493
- else if (prev[prev.length - 1] === `"`)
494
- return prev.substring(0, prev.length - 1) + tail.substring(1);
495
- return prev + ` + ${tail}`;
496
- };
536
+ export const index = (props: {
537
+ start: number | null;
538
+ postfix: string;
539
+ rand: string;
540
+ }) => {
541
+ const tail: string =
542
+ props.start !== null
543
+ ? `"[" + (${props.start} + _index${props.rand}) + "]"`
544
+ : `"[" + _index${props.rand} + "]"`;
545
+ if (props.postfix === "") return tail;
546
+ else if (props.postfix[props.postfix.length - 1] === `"`)
547
+ return (
548
+ props.postfix.substring(0, props.postfix.length - 1) + tail.substring(1)
549
+ );
550
+ return props.postfix + ` + ${tail}`;
551
+ };
497
552
 
498
- export const argumentsArray =
499
- (config: Pick<IConfig, "path" | "trace">) =>
500
- (explore: FeatureProgrammer.IExplore) => {
501
- const tail: ts.Expression[] =
502
- config.path === false && config.trace === false
503
- ? []
504
- : config.path === true && config.trace === true
553
+ export const argumentsArray = (props: {
554
+ config: Pick<IConfig, "path" | "trace">;
555
+ input: ts.Expression;
556
+ explore: FeatureProgrammer.IExplore;
557
+ }) => {
558
+ const tail: ts.Expression[] =
559
+ props.config.path === false && props.config.trace === false
560
+ ? []
561
+ : props.config.path === true && props.config.trace === true
562
+ ? [
563
+ ts.factory.createIdentifier(
564
+ props.explore.postfix
565
+ ? `_path + ${props.explore.postfix}`
566
+ : "_path",
567
+ ),
568
+ props.explore.source === "function"
569
+ ? ts.factory.createIdentifier(
570
+ `${props.explore.tracable} && _exceptionable`,
571
+ )
572
+ : props.explore.tracable
573
+ ? ts.factory.createTrue()
574
+ : ts.factory.createFalse(),
575
+ ]
576
+ : props.config.path === true
505
577
  ? [
506
578
  ts.factory.createIdentifier(
507
- explore.postfix ? `_path + ${explore.postfix}` : "_path",
579
+ props.explore.postfix
580
+ ? `_path + ${props.explore.postfix}`
581
+ : "_path",
508
582
  ),
509
- explore.source === "function"
583
+ ]
584
+ : [
585
+ props.explore.source === "function"
510
586
  ? ts.factory.createIdentifier(
511
- `${explore.tracable} && _exceptionable`,
587
+ `${props.explore.tracable} && _exceptionable`,
512
588
  )
513
- : explore.tracable
589
+ : props.explore.tracable
514
590
  ? ts.factory.createTrue()
515
591
  : ts.factory.createFalse(),
516
- ]
517
- : config.path === true
518
- ? [
519
- ts.factory.createIdentifier(
520
- explore.postfix ? `_path + ${explore.postfix}` : "_path",
521
- ),
522
- ]
523
- : [
524
- explore.source === "function"
525
- ? ts.factory.createIdentifier(
526
- `${explore.tracable} && _exceptionable`,
527
- )
528
- : explore.tracable
529
- ? ts.factory.createTrue()
530
- : ts.factory.createFalse(),
531
- ];
532
- return (input: ts.Expression) => [input, ...tail];
533
- };
592
+ ];
593
+ return [props.input, ...tail];
594
+ };
534
595
 
535
- export const parameterDeclarations =
536
- (props: Pick<CheckerProgrammer.IConfig, "path" | "trace">) =>
537
- (type: ts.TypeNode) => {
538
- const tail: ts.ParameterDeclaration[] = [];
539
- if (props.path)
540
- tail.push(
541
- IdentifierFactory.parameter("_path", TypeFactory.keyword("string")),
542
- );
543
- if (props.trace)
544
- tail.push(
545
- IdentifierFactory.parameter(
546
- "_exceptionable",
547
- TypeFactory.keyword("boolean"),
548
- ts.factory.createTrue(),
549
- ),
550
- );
551
- return (input: ts.Identifier): ts.ParameterDeclaration[] => [
552
- IdentifierFactory.parameter(input, type),
553
- ...tail,
554
- ];
555
- };
596
+ export const parameterDeclarations = (props: {
597
+ config: Pick<CheckerProgrammer.IConfig, "path" | "trace">;
598
+ type: ts.TypeNode;
599
+ input: ts.Identifier;
600
+ }) => {
601
+ const tail: ts.ParameterDeclaration[] = [];
602
+ if (props.config.path)
603
+ tail.push(
604
+ IdentifierFactory.parameter("_path", TypeFactory.keyword("string")),
605
+ );
606
+ if (props.config.trace)
607
+ tail.push(
608
+ IdentifierFactory.parameter(
609
+ "_exceptionable",
610
+ TypeFactory.keyword("boolean"),
611
+ ts.factory.createTrue(),
612
+ ),
613
+ );
614
+ return [IdentifierFactory.parameter(props.input, props.type), ...tail];
615
+ };
556
616
  }