typia 7.0.0-dev.20240923 → 7.0.0-dev.20240924

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.
@@ -9,6 +9,7 @@ import { TypeFactory } from "../../factories/TypeFactory";
9
9
 
10
10
  import { Metadata } from "../../schemas/metadata/Metadata";
11
11
  import { MetadataArray } from "../../schemas/metadata/MetadataArray";
12
+ import { MetadataObject } from "../../schemas/metadata/MetadataObject";
12
13
  import { MetadataTuple } from "../../schemas/metadata/MetadataTuple";
13
14
  import { MetadataTupleType } from "../../schemas/metadata/MetadataTupleType";
14
15
 
@@ -33,7 +34,7 @@ export namespace MiscPruneProgrammer {
33
34
  type: ts.Type;
34
35
  name: string | undefined;
35
36
  }): FeatureProgrammer.IDecomposed => {
36
- const config = configure(props.context)(props.importer);
37
+ const config = configure(props);
37
38
  if (props.validated === false)
38
39
  config.addition = (collection) =>
39
40
  IsProgrammer.write_function_statements(props.context)(props.importer)(
@@ -73,457 +74,551 @@ export namespace MiscPruneProgrammer {
73
74
  });
74
75
  };
75
76
 
76
- const write_array_functions =
77
- (config: FeatureProgrammer.IConfig) =>
78
- (importer: FunctionImporter) =>
79
- (collection: MetadataCollection): ts.VariableStatement[] =>
80
- collection
81
- .arrays()
82
- .filter((a) => a.recursive)
83
- .map((type, i) =>
84
- StatementFactory.constant(
85
- `${config.prefix}a${i}`,
86
- ts.factory.createArrowFunction(
87
- undefined,
88
- undefined,
89
- FeatureProgrammer.parameterDeclarations(config)(
90
- TypeFactory.keyword("any"),
91
- )(ts.factory.createIdentifier("input")),
77
+ const write_array_functions = (props: {
78
+ config: FeatureProgrammer.IConfig;
79
+ importer: FunctionImporter;
80
+ collection: MetadataCollection;
81
+ }): ts.VariableStatement[] =>
82
+ props.collection
83
+ .arrays()
84
+ .filter((a) => a.recursive)
85
+ .map((type, i) =>
86
+ StatementFactory.constant(
87
+ `${props.config.prefix}a${i}`,
88
+ ts.factory.createArrowFunction(
89
+ undefined,
90
+ undefined,
91
+ FeatureProgrammer.parameterDeclarations(props.config)(
92
92
  TypeFactory.keyword("any"),
93
- undefined,
94
- decode_array_inline(config)(importer)(
95
- ts.factory.createIdentifier("input"),
96
- MetadataArray.create({
97
- type,
98
- tags: [],
99
- }),
100
- {
101
- tracable: config.trace,
102
- source: "function",
103
- from: "array",
104
- postfix: "",
105
- },
106
- ),
107
- ),
93
+ )(ts.factory.createIdentifier("input")),
94
+ TypeFactory.keyword("any"),
95
+ undefined,
96
+ decode_array_inline({
97
+ config: props.config,
98
+ importer: props.importer,
99
+ input: ts.factory.createIdentifier("input"),
100
+ array: MetadataArray.create({
101
+ type,
102
+ tags: [],
103
+ }),
104
+ explore: {
105
+ tracable: props.config.trace,
106
+ source: "function",
107
+ from: "array",
108
+ postfix: "",
109
+ },
110
+ }),
108
111
  ),
109
- );
112
+ ),
113
+ );
110
114
 
111
- const write_tuple_functions =
112
- (project: ITypiaContext) =>
113
- (config: FeatureProgrammer.IConfig) =>
114
- (importer: FunctionImporter) =>
115
- (collection: MetadataCollection): ts.VariableStatement[] =>
116
- collection
117
- .tuples()
118
- .filter((t) => t.recursive)
119
- .map((tuple, i) =>
120
- StatementFactory.constant(
121
- `${config.prefix}t${i}`,
122
- ts.factory.createArrowFunction(
123
- undefined,
124
- undefined,
125
- FeatureProgrammer.parameterDeclarations(config)(
126
- TypeFactory.keyword("any"),
127
- )(ts.factory.createIdentifier("input")),
115
+ const write_tuple_functions = (props: {
116
+ context: ITypiaContext;
117
+ config: FeatureProgrammer.IConfig;
118
+ importer: FunctionImporter;
119
+ collection: MetadataCollection;
120
+ }): ts.VariableStatement[] =>
121
+ props.collection
122
+ .tuples()
123
+ .filter((t) => t.recursive)
124
+ .map((tuple, i) =>
125
+ StatementFactory.constant(
126
+ `${props.config.prefix}t${i}`,
127
+ ts.factory.createArrowFunction(
128
+ undefined,
129
+ undefined,
130
+ FeatureProgrammer.parameterDeclarations(props.config)(
128
131
  TypeFactory.keyword("any"),
129
- undefined,
130
- decode_tuple_inline(project)(config)(importer)(
131
- ts.factory.createIdentifier("input"),
132
- tuple,
133
- {
134
- tracable: config.trace,
135
- source: "function",
136
- from: "array",
137
- postfix: "",
138
- },
139
- ),
140
- ),
132
+ )(ts.factory.createIdentifier("input")),
133
+ TypeFactory.keyword("any"),
134
+ undefined,
135
+ decode_tuple_inline({
136
+ context: props.context,
137
+ config: props.config,
138
+ importer: props.importer,
139
+ input: ts.factory.createIdentifier("input"),
140
+ tuple,
141
+ explore: {
142
+ tracable: props.config.trace,
143
+ source: "function",
144
+ from: "array",
145
+ postfix: "",
146
+ },
147
+ }),
141
148
  ),
142
- );
149
+ ),
150
+ );
143
151
 
144
152
  /* -----------------------------------------------------------
145
153
  DECODERS
146
154
  ----------------------------------------------------------- */
147
- const decode =
148
- (project: ITypiaContext) =>
149
- (config: FeatureProgrammer.IConfig) =>
150
- (importer: FunctionImporter) =>
151
- (
152
- input: ts.Expression,
153
- meta: Metadata,
154
- explore: FeatureProgrammer.IExplore,
155
- ): ts.ConciseBody => {
156
- if (filter(meta) === false) return ts.factory.createBlock([]);
157
-
158
- interface IUnion {
159
- type: string;
160
- is: () => ts.Expression;
161
- value: () => ts.Expression | ts.Block | ts.ReturnStatement;
162
- }
163
- const unions: IUnion[] = [];
164
-
165
- //----
166
- // LIST UP UNION TYPES
167
- //----
168
- // TUPLES
169
- for (const tuple of meta.tuples.filter((tuple) =>
170
- tuple.type.elements.some((e) => filter(e.rest ?? e)),
171
- ))
172
- unions.push({
173
- type: "tuple",
174
- is: () =>
175
- IsProgrammer.decode(project)(importer)(
176
- input,
177
- (() => {
178
- const partial = Metadata.initialize();
179
- partial.tuples.push(tuple);
180
- return partial;
181
- })(),
182
- explore,
183
- ),
184
- value: () =>
185
- decode_tuple(project)(config)(importer)(input, tuple, explore),
186
- });
155
+ const decode = (props: {
156
+ context: ITypiaContext;
157
+ config: FeatureProgrammer.IConfig;
158
+ importer: FunctionImporter;
159
+ input: ts.Expression;
160
+ metadata: Metadata;
161
+ explore: FeatureProgrammer.IExplore;
162
+ }): ts.ConciseBody => {
163
+ if (filter(props.metadata) === false) return ts.factory.createBlock([]);
164
+
165
+ interface IUnion {
166
+ type: string;
167
+ is: () => ts.Expression;
168
+ value: () => ts.Expression | ts.Block | ts.ReturnStatement;
169
+ }
170
+ const unions: IUnion[] = [];
171
+
172
+ //----
173
+ // LIST UP UNION TYPES
174
+ //----
175
+ // TUPLES
176
+ for (const tuple of props.metadata.tuples.filter((tuple) =>
177
+ tuple.type.elements.some((e) => filter(e.rest ?? e)),
178
+ ))
179
+ unions.push({
180
+ type: "tuple",
181
+ is: () =>
182
+ IsProgrammer.decode(props.context)(props.importer)(
183
+ props.input,
184
+ (() => {
185
+ const partial = Metadata.initialize();
186
+ partial.tuples.push(tuple);
187
+ return partial;
188
+ })(),
189
+ props.explore,
190
+ ),
191
+ value: () =>
192
+ decode_tuple({
193
+ ...props,
194
+ tuple,
195
+ }),
196
+ });
187
197
 
188
- // ARRAYS
189
- if (meta.arrays.filter((a) => filter(a.type.value)).length)
190
- unions.push({
191
- type: "array",
192
- is: () => ExpressionFactory.isArray(input),
193
- value: () =>
194
- explore_arrays(project)(config)(importer)(input, meta.arrays, {
195
- ...explore,
198
+ // ARRAYS
199
+ if (props.metadata.arrays.filter((a) => filter(a.type.value)).length)
200
+ unions.push({
201
+ type: "array",
202
+ is: () => ExpressionFactory.isArray(props.input),
203
+ value: () =>
204
+ explore_arrays({
205
+ ...props,
206
+ arrays: props.metadata.arrays,
207
+ explore: {
208
+ ...props.explore,
196
209
  from: "array",
197
- }),
198
- });
210
+ },
211
+ }),
212
+ });
199
213
 
200
- // BUILT-IN CLASSES
201
- if (meta.natives.length)
202
- for (const native of meta.natives)
203
- unions.push({
204
- type: "native",
205
- is: () => ExpressionFactory.isInstanceOf(native)(input),
206
- value: () => ts.factory.createReturnStatement(),
207
- });
208
- if (meta.sets.length)
209
- unions.push({
210
- type: "set",
211
- is: () => ExpressionFactory.isInstanceOf("Set")(input),
212
- value: () => ts.factory.createReturnStatement(),
213
- });
214
- if (meta.maps.length)
214
+ // BUILT-IN CLASSES
215
+ if (props.metadata.natives.length)
216
+ for (const native of props.metadata.natives)
215
217
  unions.push({
216
- type: "map",
217
- is: () => ExpressionFactory.isInstanceOf("Map")(input),
218
+ type: "native",
219
+ is: () => ExpressionFactory.isInstanceOf(native)(props.input),
218
220
  value: () => ts.factory.createReturnStatement(),
219
221
  });
222
+ if (props.metadata.sets.length)
223
+ unions.push({
224
+ type: "set",
225
+ is: () => ExpressionFactory.isInstanceOf("Set")(props.input),
226
+ value: () => ts.factory.createReturnStatement(),
227
+ });
228
+ if (props.metadata.maps.length)
229
+ unions.push({
230
+ type: "map",
231
+ is: () => ExpressionFactory.isInstanceOf("Map")(props.input),
232
+ value: () => ts.factory.createReturnStatement(),
233
+ });
220
234
 
221
- // OBJECTS
222
- if (meta.objects.length)
223
- unions.push({
224
- type: "object",
225
- is: () =>
226
- ExpressionFactory.isObject({
227
- checkNull: true,
228
- checkArray: false,
229
- })(input),
230
- value: () =>
231
- explore_objects(config)(importer)(input, meta, {
232
- ...explore,
235
+ // OBJECTS
236
+ if (props.metadata.objects.length)
237
+ unions.push({
238
+ type: "object",
239
+ is: () =>
240
+ ExpressionFactory.isObject({
241
+ checkNull: true,
242
+ checkArray: false,
243
+ })(props.input),
244
+ value: () =>
245
+ explore_objects({
246
+ ...props,
247
+ explore: {
248
+ ...props.explore,
233
249
  from: "object",
234
- }),
235
- });
250
+ },
251
+ }),
252
+ });
236
253
 
237
- //----
238
- // STATEMENTS
239
- //----
240
- const converter = (v: ts.Expression | ts.Block | ts.ReturnStatement) =>
241
- ts.isReturnStatement(v) || ts.isBlock(v)
242
- ? v
243
- : ts.factory.createExpressionStatement(v);
254
+ //----
255
+ // STATEMENTS
256
+ //----
257
+ const converter = (v: ts.Expression | ts.Block | ts.ReturnStatement) =>
258
+ ts.isReturnStatement(v) || ts.isBlock(v)
259
+ ? v
260
+ : ts.factory.createExpressionStatement(v);
244
261
 
245
- const statements: ts.Statement[] = unions.map((u) =>
246
- ts.factory.createIfStatement(u.is(), converter(u.value())),
247
- );
248
- return ts.factory.createBlock(statements, true);
249
- };
262
+ const statements: ts.Statement[] = unions.map((u) =>
263
+ ts.factory.createIfStatement(u.is(), converter(u.value())),
264
+ );
265
+ return ts.factory.createBlock(statements, true);
266
+ };
250
267
 
251
- const decode_object = (importer: FunctionImporter) =>
268
+ const decode_object = (props: {
269
+ importer: FunctionImporter;
270
+ input: ts.Expression;
271
+ object: MetadataObject;
272
+ explore: FeatureProgrammer.IExplore;
273
+ }) =>
252
274
  FeatureProgrammer.decode_object({
253
275
  trace: false,
254
276
  path: false,
255
277
  prefix: PREFIX,
256
- })(importer);
257
-
258
- const decode_array =
259
- (config: FeatureProgrammer.IConfig) =>
260
- (importer: FunctionImporter) =>
261
- (
262
- input: ts.Expression,
263
- array: MetadataArray,
264
- explore: FeatureProgrammer.IExplore,
265
- ) =>
266
- array.type.recursive
267
- ? ts.factory.createCallExpression(
268
- ts.factory.createIdentifier(
269
- importer.useLocal(`${config.prefix}a${array.type.index}`),
270
- ),
271
- undefined,
272
- FeatureProgrammer.argumentsArray(config)({
273
- ...explore,
274
- source: "function",
275
- from: "array",
276
- })(input),
277
- )
278
- : decode_array_inline(config)(importer)(input, array, explore);
279
-
280
- const decode_array_inline =
281
- (config: FeatureProgrammer.IConfig) =>
282
- (importer: FunctionImporter) =>
283
- (
284
- input: ts.Expression,
285
- array: MetadataArray,
286
- explore: FeatureProgrammer.IExplore,
287
- ): ts.Expression =>
288
- FeatureProgrammer.decode_array(config)(importer)(PruneJoiner.array)(
289
- input,
290
- array,
291
- explore,
292
- );
278
+ })(props.importer)(props.input, props.object, props.explore);
293
279
 
294
- const decode_tuple =
295
- (project: ITypiaContext) =>
296
- (config: FeatureProgrammer.IConfig) =>
297
- (importer: FunctionImporter) =>
298
- (
299
- input: ts.Expression,
300
- tuple: MetadataTuple,
301
- explore: FeatureProgrammer.IExplore,
302
- ): ts.Expression | ts.Block =>
303
- tuple.type.recursive
304
- ? ts.factory.createCallExpression(
305
- ts.factory.createIdentifier(
306
- importer.useLocal(`${config.prefix}t${tuple.type.index}`),
280
+ const decode_array = (props: {
281
+ config: FeatureProgrammer.IConfig;
282
+ importer: FunctionImporter;
283
+ input: ts.Expression;
284
+ array: MetadataArray;
285
+ explore: FeatureProgrammer.IExplore;
286
+ }) =>
287
+ props.array.type.recursive
288
+ ? ts.factory.createCallExpression(
289
+ ts.factory.createIdentifier(
290
+ props.importer.useLocal(
291
+ `${props.config.prefix}a${props.array.type.index}`,
307
292
  ),
308
- undefined,
309
- FeatureProgrammer.argumentsArray(config)({
310
- ...explore,
311
- source: "function",
312
- })(input),
313
- )
314
- : decode_tuple_inline(project)(config)(importer)(
315
- input,
316
- tuple.type,
317
- explore,
318
- );
319
-
320
- const decode_tuple_inline =
321
- (project: ITypiaContext) =>
322
- (config: FeatureProgrammer.IConfig) =>
323
- (importer: FunctionImporter) =>
324
- (
325
- input: ts.Expression,
326
- tuple: MetadataTupleType,
327
- explore: FeatureProgrammer.IExplore,
328
- ): ts.Block => {
329
- const elements: ts.ConciseBody[] = tuple.elements
330
- .map((elem, index) => [elem, index] as const)
331
- .filter(([elem]) => filter(elem) && elem.rest === null)
332
- .map(([elem, index]) =>
333
- decode(project)(config)(importer)(
334
- ts.factory.createElementAccessExpression(input, index),
335
- elem,
336
- {
337
- ...explore,
338
- from: "array",
339
- postfix: explore.postfix.length
340
- ? `${postfix_of_tuple(explore.postfix)}[${index}]"`
341
- : `"[${index}]"`,
342
- },
343
293
  ),
344
- );
345
- const rest = (() => {
346
- if (tuple.elements.length === 0) return null;
347
-
348
- const last: Metadata = tuple.elements.at(-1)!;
349
- const rest: Metadata | null = last.rest;
350
- if (rest === null || filter(rest) === false) return null;
351
-
352
- return decode(project)(config)(importer)(
353
- ts.factory.createCallExpression(
354
- IdentifierFactory.access(input)("slice"),
355
- undefined,
356
- [ExpressionFactory.number(tuple.elements.length - 1)],
294
+ undefined,
295
+ FeatureProgrammer.argumentsArray(props.config)({
296
+ ...props.explore,
297
+ source: "function",
298
+ from: "array",
299
+ })(props.input),
300
+ )
301
+ : decode_array_inline(props);
302
+
303
+ const decode_array_inline = (props: {
304
+ config: FeatureProgrammer.IConfig;
305
+ importer: FunctionImporter;
306
+ input: ts.Expression;
307
+ array: MetadataArray;
308
+ explore: FeatureProgrammer.IExplore;
309
+ }): ts.Expression =>
310
+ FeatureProgrammer.decode_array(props.config)(props.importer)(
311
+ PruneJoiner.array,
312
+ )(props.input, props.array, props.explore);
313
+
314
+ const decode_tuple = (props: {
315
+ context: ITypiaContext;
316
+ config: FeatureProgrammer.IConfig;
317
+ importer: FunctionImporter;
318
+ input: ts.Expression;
319
+ tuple: MetadataTuple;
320
+ explore: FeatureProgrammer.IExplore;
321
+ }): ts.Expression | ts.Block =>
322
+ props.tuple.type.recursive
323
+ ? ts.factory.createCallExpression(
324
+ ts.factory.createIdentifier(
325
+ props.importer.useLocal(
326
+ `${props.config.prefix}t${props.tuple.type.index}`,
327
+ ),
357
328
  ),
358
- wrap_metadata_rest_tuple(tuple.elements.at(-1)!.rest!),
359
- {
360
- ...explore,
361
- start: tuple.elements.length - 1,
329
+ undefined,
330
+ FeatureProgrammer.argumentsArray(props.config)({
331
+ ...props.explore,
332
+ source: "function",
333
+ })(props.input),
334
+ )
335
+ : decode_tuple_inline({
336
+ ...props,
337
+ tuple: props.tuple.type,
338
+ });
339
+
340
+ const decode_tuple_inline = (props: {
341
+ context: ITypiaContext;
342
+ config: FeatureProgrammer.IConfig;
343
+ importer: FunctionImporter;
344
+ input: ts.Expression;
345
+ tuple: MetadataTupleType;
346
+ explore: FeatureProgrammer.IExplore;
347
+ }): ts.Block => {
348
+ const elements: ts.ConciseBody[] = props.tuple.elements
349
+ .map((elem, index) => [elem, index] as const)
350
+ .filter(([elem]) => filter(elem) && elem.rest === null)
351
+ .map(([elem, index]) =>
352
+ decode({
353
+ context: props.context,
354
+ config: props.config,
355
+ importer: props.importer,
356
+ input: ts.factory.createElementAccessExpression(props.input, index),
357
+ metadata: elem,
358
+ explore: {
359
+ ...props.explore,
360
+ from: "array",
361
+ postfix: props.explore.postfix.length
362
+ ? `${postfix_of_tuple(props.explore.postfix)}[${index}]"`
363
+ : `"[${index}]"`,
362
364
  },
363
- );
364
- })();
365
- return PruneJoiner.tuple({
366
- elements,
367
- rest,
365
+ }),
366
+ );
367
+ const rest = (() => {
368
+ if (props.tuple.elements.length === 0) return null;
369
+
370
+ const last: Metadata = props.tuple.elements.at(-1)!;
371
+ const rest: Metadata | null = last.rest;
372
+ if (rest === null || filter(rest) === false) return null;
373
+
374
+ return decode({
375
+ context: props.context,
376
+ config: props.config,
377
+ importer: props.importer,
378
+ input: ts.factory.createCallExpression(
379
+ IdentifierFactory.access(props.input)("slice"),
380
+ undefined,
381
+ [ExpressionFactory.number(props.tuple.elements.length - 1)],
382
+ ),
383
+ metadata: wrap_metadata_rest_tuple(props.tuple.elements.at(-1)!.rest!),
384
+ explore: {
385
+ ...props.explore,
386
+ start: props.tuple.elements.length - 1,
387
+ },
368
388
  });
369
- };
389
+ })();
390
+ return PruneJoiner.tuple({
391
+ elements,
392
+ rest,
393
+ });
394
+ };
370
395
 
371
396
  /* -----------------------------------------------------------
372
397
  UNION TYPE EXPLORERS
373
398
  ----------------------------------------------------------- */
374
- const explore_objects =
375
- (config: FeatureProgrammer.IConfig) =>
376
- (importer: FunctionImporter) =>
377
- (
378
- input: ts.Expression,
379
- meta: Metadata,
380
- explore: FeatureProgrammer.IExplore,
381
- ) => {
382
- if (meta.objects.length === 1)
383
- return decode_object(importer)(input, meta.objects[0]!, explore);
384
-
385
- return ts.factory.createCallExpression(
386
- ts.factory.createIdentifier(
387
- importer.useLocal(`${PREFIX}u${meta.union_index!}`),
388
- ),
389
- undefined,
390
- FeatureProgrammer.argumentsArray(config)(explore)(input),
391
- );
392
- };
399
+ const explore_objects = (props: {
400
+ config: FeatureProgrammer.IConfig;
401
+ importer: FunctionImporter;
402
+ input: ts.Expression;
403
+ metadata: Metadata;
404
+ explore: FeatureProgrammer.IExplore;
405
+ }) => {
406
+ if (props.metadata.objects.length === 1)
407
+ return decode_object({
408
+ ...props,
409
+ object: props.metadata.objects[0]!,
410
+ });
393
411
 
394
- const explore_arrays =
395
- (project: ITypiaContext) =>
396
- (config: FeatureProgrammer.IConfig) =>
397
- (importer: FunctionImporter) =>
398
- (
399
- input: ts.Expression,
400
- elements: MetadataArray[],
401
- explore: FeatureProgrammer.IExplore,
402
- ): ts.Expression =>
403
- explore_array_like_union_types(config)(importer)(
412
+ return ts.factory.createCallExpression(
413
+ ts.factory.createIdentifier(
414
+ props.importer.useLocal(`${PREFIX}u${props.metadata.union_index!}`),
415
+ ),
416
+ undefined,
417
+ FeatureProgrammer.argumentsArray(props.config)(props.explore)(
418
+ props.input,
419
+ ),
420
+ );
421
+ };
422
+
423
+ const explore_arrays = (props: {
424
+ context: ITypiaContext;
425
+ config: FeatureProgrammer.IConfig;
426
+ importer: FunctionImporter;
427
+ input: ts.Expression;
428
+ arrays: MetadataArray[];
429
+ explore: FeatureProgrammer.IExplore;
430
+ }): ts.Expression =>
431
+ explore_array_like_union_types({
432
+ ...props,
433
+ elements: props.arrays,
434
+ factory: (next) =>
404
435
  UnionExplorer.array({
405
- checker: IsProgrammer.decode(project)(importer),
406
- decoder: decode_array(config)(importer),
436
+ checker: IsProgrammer.decode(props.context)(props.importer),
437
+ decoder: (input, array, explore) =>
438
+ decode_array({
439
+ config: props.config,
440
+ importer: props.importer,
441
+ input,
442
+ array,
443
+ explore,
444
+ }),
407
445
  empty: ts.factory.createStringLiteral("[]"),
408
446
  success: ts.factory.createTrue(),
409
447
  failure: (input, expected) =>
410
- create_throw_error(importer)(expected)(input),
448
+ create_throw_error({
449
+ importer: props.importer,
450
+ expected,
451
+ input,
452
+ }),
453
+ })(next.parameters)(next.input, next.elements, next.explore),
454
+ });
455
+
456
+ const explore_array_like_union_types = <
457
+ T extends MetadataArray | MetadataTuple,
458
+ >(props: {
459
+ config: FeatureProgrammer.IConfig;
460
+ importer: FunctionImporter;
461
+ factory: (next: {
462
+ parameters: ts.ParameterDeclaration[];
463
+ input: ts.Expression;
464
+ elements: T[];
465
+ explore: FeatureProgrammer.IExplore;
466
+ }) => ts.ArrowFunction;
467
+ input: ts.Expression;
468
+ elements: T[];
469
+ explore: FeatureProgrammer.IExplore;
470
+ }): ts.Expression => {
471
+ const arrow = (next: {
472
+ parameters: ts.ParameterDeclaration[];
473
+ explore: FeatureProgrammer.IExplore;
474
+ input: ts.Expression;
475
+ }): ts.ArrowFunction =>
476
+ props.factory({
477
+ elements: props.elements,
478
+ parameters: next.parameters,
479
+ input: next.input,
480
+ explore: next.explore,
481
+ });
482
+ if (props.elements.every((e) => e.type.recursive === false))
483
+ ts.factory.createCallExpression(
484
+ arrow({
485
+ parameters: [],
486
+ explore: props.explore,
487
+ input: props.input,
411
488
  }),
412
- )(input, elements, explore);
413
-
414
- const explore_array_like_union_types =
415
- (config: FeatureProgrammer.IConfig) =>
416
- (importer: FunctionImporter) =>
417
- <T extends MetadataArray | MetadataTuple>(
418
- factory: (
419
- parameters: ts.ParameterDeclaration[],
420
- ) => (
421
- input: ts.Expression,
422
- elements: T[],
423
- explore: FeatureProgrammer.IExplore,
424
- ) => ts.ArrowFunction,
425
- ) =>
426
- (
427
- input: ts.Expression,
428
- elements: T[],
429
- explore: FeatureProgrammer.IExplore,
430
- ): ts.Expression => {
431
- const arrow =
432
- (parameters: ts.ParameterDeclaration[]) =>
433
- (explore: FeatureProgrammer.IExplore) =>
434
- (input: ts.Expression): ts.ArrowFunction =>
435
- factory(parameters)(input, elements, explore);
436
- if (elements.every((e) => e.type.recursive === false))
437
- ts.factory.createCallExpression(
438
- arrow([])(explore)(input),
439
- undefined,
440
- [],
441
- );
489
+ undefined,
490
+ [],
491
+ );
442
492
 
443
- explore = {
444
- ...explore,
445
- source: "function",
446
- from: "array",
447
- };
448
- return ts.factory.createCallExpression(
449
- ts.factory.createIdentifier(
450
- importer.emplaceUnion(
451
- config.prefix,
452
- elements.map((e) => e.type.name).join(" | "),
453
- () =>
454
- arrow(
455
- FeatureProgrammer.parameterDeclarations(config)(
456
- TypeFactory.keyword("any"),
457
- )(ts.factory.createIdentifier("input")),
458
- )({
493
+ const explore: FeatureProgrammer.IExplore = {
494
+ ...props.explore,
495
+ source: "function",
496
+ from: "array",
497
+ };
498
+ return ts.factory.createCallExpression(
499
+ ts.factory.createIdentifier(
500
+ props.importer.emplaceUnion(
501
+ props.config.prefix,
502
+ props.elements.map((e) => e.type.name).join(" | "),
503
+ () =>
504
+ arrow({
505
+ parameters: FeatureProgrammer.parameterDeclarations(props.config)(
506
+ TypeFactory.keyword("any"),
507
+ )(ts.factory.createIdentifier("input")),
508
+ explore: {
459
509
  ...explore,
460
510
  postfix: "",
461
- })(ts.factory.createIdentifier("input")),
462
- ),
511
+ },
512
+ input: ts.factory.createIdentifier("input"),
513
+ }),
463
514
  ),
464
- undefined,
465
- FeatureProgrammer.argumentsArray(config)(explore)(input),
466
- );
467
- };
515
+ ),
516
+ undefined,
517
+ FeatureProgrammer.argumentsArray(props.config)(props.explore)(
518
+ props.input,
519
+ ),
520
+ );
521
+ };
468
522
 
469
523
  // @todo -> must filter out recursive visit
470
- const filter = (meta: Metadata): boolean =>
471
- meta.any === false &&
472
- (meta.objects.length !== 0 ||
473
- meta.tuples.some(
524
+ const filter = (metadata: Metadata): boolean =>
525
+ metadata.any === false &&
526
+ (metadata.objects.length !== 0 ||
527
+ metadata.tuples.some(
474
528
  (t) =>
475
529
  !!t.type.elements.length &&
476
530
  t.type.elements.some((e) => filter(e.rest ?? e)),
477
531
  ) ||
478
- meta.arrays.some((e) => filter(e.type.value)));
532
+ metadata.arrays.some((e) => filter(e.type.value)));
479
533
 
480
534
  /* -----------------------------------------------------------
481
535
  CONFIGURATIONS
482
536
  ----------------------------------------------------------- */
483
537
  const PREFIX = "$p";
484
538
 
485
- const configure =
486
- (project: ITypiaContext) =>
487
- (importer: FunctionImporter): FeatureProgrammer.IConfig => {
488
- const config: FeatureProgrammer.IConfig = {
489
- types: {
490
- input: (type, name) =>
491
- ts.factory.createTypeReferenceNode(
492
- name ?? TypeFactory.getFullName(project.checker)(type),
493
- ),
494
- output: () => TypeFactory.keyword("void"),
495
- },
496
- prefix: PREFIX,
497
- trace: false,
498
- path: false,
499
- initializer,
500
- decoder: () => decode(project)(config)(importer),
501
- objector: {
502
- checker: () => IsProgrammer.decode(project)(importer),
503
- decoder: () => decode_object(importer),
504
- joiner: PruneJoiner.object,
505
- unionizer: decode_union_object(
506
- IsProgrammer.decode_object(project)(importer),
507
- )(decode_object(importer))((exp) => exp)((value, expected) =>
508
- create_throw_error(importer)(expected)(value),
539
+ const configure = (props: {
540
+ context: ITypiaContext;
541
+ importer: FunctionImporter;
542
+ }): FeatureProgrammer.IConfig => {
543
+ const config: FeatureProgrammer.IConfig = {
544
+ types: {
545
+ input: (type, name) =>
546
+ ts.factory.createTypeReferenceNode(
547
+ name ?? TypeFactory.getFullName(props.context.checker)(type),
509
548
  ),
510
- failure: (input, expected) =>
511
- create_throw_error(importer)(expected)(input),
512
- },
513
- generator: {
514
- arrays: () => write_array_functions(config)(importer),
515
- tuples: () => write_tuple_functions(project)(config)(importer),
516
- },
517
- };
518
- return config;
549
+ output: () => TypeFactory.keyword("void"),
550
+ },
551
+ prefix: PREFIX,
552
+ trace: false,
553
+ path: false,
554
+ initializer,
555
+ decoder: () => (input, metadata, explore) =>
556
+ decode({
557
+ context: props.context,
558
+ importer: props.importer,
559
+ config,
560
+ input,
561
+ metadata,
562
+ explore,
563
+ }),
564
+ objector: {
565
+ checker: () => IsProgrammer.decode(props.context)(props.importer),
566
+ decoder: () => (input, object, explore) =>
567
+ decode_object({
568
+ importer: props.importer,
569
+ input,
570
+ object,
571
+ explore,
572
+ }),
573
+ joiner: PruneJoiner.object,
574
+ unionizer: decode_union_object(
575
+ IsProgrammer.decode_object(props.context)(props.importer),
576
+ )((input, object, explore) =>
577
+ decode_object({
578
+ importer: props.importer,
579
+ input,
580
+ object,
581
+ explore,
582
+ }),
583
+ )((exp) => exp)((input, expected) =>
584
+ create_throw_error({
585
+ importer: props.importer,
586
+ expected,
587
+ input,
588
+ }),
589
+ ),
590
+ failure: (input, expected) =>
591
+ create_throw_error({
592
+ importer: props.importer,
593
+ expected,
594
+ input,
595
+ }),
596
+ },
597
+ generator: {
598
+ arrays: () => (collection) =>
599
+ write_array_functions({
600
+ config,
601
+ importer: props.importer,
602
+ collection,
603
+ }),
604
+ tuples: () => (collection) =>
605
+ write_tuple_functions({
606
+ config,
607
+ context: props.context,
608
+ importer: props.importer,
609
+ collection,
610
+ }),
611
+ },
519
612
  };
613
+ return config;
614
+ };
520
615
 
521
616
  const initializer: FeatureProgrammer.IConfig["initializer"] =
522
- (project) => (importer) => (type) => {
617
+ (context) => (importer) => (type) => {
523
618
  const collection = new MetadataCollection();
524
619
  const result = MetadataFactory.analyze({
525
- checker: project.checker,
526
- transformer: project.transformer,
620
+ checker: context.checker,
621
+ transformer: context.transformer,
527
622
  options: {
528
623
  escape: false,
529
624
  constant: true,
@@ -539,26 +634,27 @@ export namespace MiscPruneProgrammer {
539
634
  return [collection, result.data];
540
635
  };
541
636
 
542
- const create_throw_error =
543
- (importer: FunctionImporter) =>
544
- (expected: string) =>
545
- (value: ts.Expression) =>
546
- ts.factory.createExpressionStatement(
547
- ts.factory.createCallExpression(
548
- importer.use("throws"),
549
- [],
550
- [
551
- ts.factory.createObjectLiteralExpression(
552
- [
553
- ts.factory.createPropertyAssignment(
554
- "expected",
555
- ts.factory.createStringLiteral(expected),
556
- ),
557
- ts.factory.createPropertyAssignment("value", value),
558
- ],
559
- true,
560
- ),
561
- ],
562
- ),
563
- );
637
+ const create_throw_error = (props: {
638
+ importer: FunctionImporter;
639
+ expected: string;
640
+ input: ts.Expression;
641
+ }) =>
642
+ ts.factory.createExpressionStatement(
643
+ ts.factory.createCallExpression(
644
+ props.importer.use("throws"),
645
+ [],
646
+ [
647
+ ts.factory.createObjectLiteralExpression(
648
+ [
649
+ ts.factory.createPropertyAssignment(
650
+ "expected",
651
+ ts.factory.createStringLiteral(props.expected),
652
+ ),
653
+ ts.factory.createPropertyAssignment("value", props.input),
654
+ ],
655
+ true,
656
+ ),
657
+ ],
658
+ ),
659
+ );
564
660
  }