typia 7.0.0-dev.20240921 → 7.0.0-dev.20240922

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.
@@ -44,7 +44,7 @@ export namespace NotationGeneralProgrammer {
44
44
  type: ts.Type;
45
45
  name: string | undefined;
46
46
  }): FeatureProgrammer.IDecomposed => {
47
- const config = configure(props.rename)(props.context)(props.importer);
47
+ const config = configure(props);
48
48
  if (props.validated === false)
49
49
  config.addition = (collection) =>
50
50
  IsProgrammer.write_function_statements(props.context)(props.importer)(
@@ -89,231 +89,257 @@ export namespace NotationGeneralProgrammer {
89
89
  });
90
90
  };
91
91
 
92
- const write_array_functions =
93
- (config: FeatureProgrammer.IConfig) =>
94
- (importer: FunctionImporter) =>
95
- (collection: MetadataCollection): ts.VariableStatement[] =>
96
- collection
97
- .arrays()
98
- .filter((a) => a.recursive)
99
- .map((type, i) =>
100
- StatementFactory.constant(
101
- `${config.prefix}a${i}`,
102
- ts.factory.createArrowFunction(
103
- undefined,
104
- undefined,
105
- FeatureProgrammer.parameterDeclarations(config)(
106
- TypeFactory.keyword("any"),
107
- )(ts.factory.createIdentifier("input")),
92
+ const write_array_functions = (props: {
93
+ config: FeatureProgrammer.IConfig;
94
+ importer: FunctionImporter;
95
+ collection: MetadataCollection;
96
+ }): ts.VariableStatement[] =>
97
+ props.collection
98
+ .arrays()
99
+ .filter((a) => a.recursive)
100
+ .map((type, i) =>
101
+ StatementFactory.constant(
102
+ `${props.config.prefix}a${i}`,
103
+ ts.factory.createArrowFunction(
104
+ undefined,
105
+ undefined,
106
+ FeatureProgrammer.parameterDeclarations(props.config)(
108
107
  TypeFactory.keyword("any"),
109
- undefined,
110
- decode_array_inline(config)(importer)(
111
- ts.factory.createIdentifier("input"),
112
- MetadataArray.create({
113
- type,
114
- tags: [],
115
- }),
116
- {
117
- tracable: config.trace,
118
- source: "function",
119
- from: "array",
120
- postfix: "",
121
- },
122
- ),
123
- ),
108
+ )(ts.factory.createIdentifier("input")),
109
+ TypeFactory.keyword("any"),
110
+ undefined,
111
+ decode_array_inline({
112
+ ...props,
113
+ input: ts.factory.createIdentifier("input"),
114
+ array: MetadataArray.create({
115
+ type,
116
+ tags: [],
117
+ }),
118
+ explore: {
119
+ tracable: props.config.trace,
120
+ source: "function",
121
+ from: "array",
122
+ postfix: "",
123
+ },
124
+ }),
124
125
  ),
125
- );
126
+ ),
127
+ );
126
128
 
127
- const write_tuple_functions =
128
- (project: ITypiaContext) =>
129
- (config: FeatureProgrammer.IConfig) =>
130
- (importer: FunctionImporter) =>
131
- (collection: MetadataCollection): ts.VariableStatement[] =>
132
- collection
133
- .tuples()
134
- .filter((t) => t.recursive)
135
- .map((tuple, i) =>
136
- StatementFactory.constant(
137
- `${config.prefix}t${i}`,
138
- ts.factory.createArrowFunction(
139
- undefined,
140
- undefined,
141
- FeatureProgrammer.parameterDeclarations(config)(
142
- TypeFactory.keyword("any"),
143
- )(ts.factory.createIdentifier("input")),
129
+ const write_tuple_functions = (props: {
130
+ context: ITypiaContext;
131
+ config: FeatureProgrammer.IConfig;
132
+ importer: FunctionImporter;
133
+ collection: MetadataCollection;
134
+ }): ts.VariableStatement[] =>
135
+ props.collection
136
+ .tuples()
137
+ .filter((t) => t.recursive)
138
+ .map((tuple, i) =>
139
+ StatementFactory.constant(
140
+ `${props.config.prefix}t${i}`,
141
+ ts.factory.createArrowFunction(
142
+ undefined,
143
+ undefined,
144
+ FeatureProgrammer.parameterDeclarations(props.config)(
144
145
  TypeFactory.keyword("any"),
145
- undefined,
146
- decode_tuple_inline(project)(config)(importer)(
147
- ts.factory.createIdentifier("input"),
148
- tuple,
149
- {
150
- tracable: config.trace,
151
- source: "function",
152
- from: "array",
153
- postfix: "",
154
- },
155
- ),
156
- ),
146
+ )(ts.factory.createIdentifier("input")),
147
+ TypeFactory.keyword("any"),
148
+ undefined,
149
+ decode_tuple_inline({
150
+ ...props,
151
+ input: ts.factory.createIdentifier("input"),
152
+ tuple,
153
+ explore: {
154
+ tracable: props.config.trace,
155
+ source: "function",
156
+ from: "array",
157
+ postfix: "",
158
+ },
159
+ }),
157
160
  ),
158
- );
161
+ ),
162
+ );
159
163
 
160
164
  /* -----------------------------------------------------------
161
165
  DECODERS
162
166
  ----------------------------------------------------------- */
163
- const decode =
164
- (project: ITypiaContext) =>
165
- (config: FeatureProgrammer.IConfig) =>
166
- (importer: FunctionImporter) =>
167
- (
168
- input: ts.Expression,
169
- meta: Metadata,
170
- explore: FeatureProgrammer.IExplore,
171
- ): ts.Expression => {
172
- // ANY TYPE
173
- if (
174
- meta.any ||
175
- meta.arrays.some((a) => a.type.value.any) ||
176
- meta.tuples.some(
177
- (t) =>
178
- !!t.type.elements.length && t.type.elements.every((e) => e.any),
179
- )
167
+ const decode = (props: {
168
+ context: ITypiaContext;
169
+ config: FeatureProgrammer.IConfig;
170
+ importer: FunctionImporter;
171
+ metadata: Metadata;
172
+ explore: FeatureProgrammer.IExplore;
173
+ input: ts.Expression;
174
+ }): ts.Expression => {
175
+ // ANY TYPE
176
+ if (
177
+ props.metadata.any ||
178
+ props.metadata.arrays.some((a) => a.type.value.any) ||
179
+ props.metadata.tuples.some(
180
+ (t) => !!t.type.elements.length && t.type.elements.every((e) => e.any),
180
181
  )
181
- return ts.factory.createCallExpression(importer.use("any"), undefined, [
182
- input,
183
- ]);
184
-
185
- interface IUnion {
186
- type: string;
187
- is: () => ts.Expression;
188
- value: () => ts.Expression;
189
- }
190
- const unions: IUnion[] = [];
191
-
192
- //----
193
- // LIST UP UNION TYPES
194
- //----
195
- // FUNCTIONAL
196
- if (meta.functions.length)
197
- unions.push({
198
- type: "functional",
199
- is: () =>
200
- ts.factory.createStrictEquality(
201
- ts.factory.createStringLiteral("function"),
202
- ts.factory.createTypeOfExpression(input),
203
- ),
204
- value: () => ts.factory.createIdentifier("undefined"),
205
- });
182
+ )
183
+ return ts.factory.createCallExpression(
184
+ props.importer.use("any"),
185
+ undefined,
186
+ [props.input],
187
+ );
206
188
 
207
- // TUPLES
208
- for (const tuple of meta.tuples)
209
- unions.push({
210
- type: "tuple",
211
- is: () =>
212
- IsProgrammer.decode(project)(importer)(
213
- input,
214
- (() => {
215
- const partial = Metadata.initialize();
216
- partial.tuples.push(tuple);
217
- return partial;
218
- })(),
219
- explore,
220
- ),
221
- value: () =>
222
- decode_tuple(project)(config)(importer)(input, tuple, explore),
223
- });
189
+ interface IUnion {
190
+ type: string;
191
+ is: () => ts.Expression;
192
+ value: () => ts.Expression;
193
+ }
194
+ const unions: IUnion[] = [];
195
+
196
+ //----
197
+ // LIST UP UNION TYPES
198
+ //----
199
+ // FUNCTIONAL
200
+ if (props.metadata.functions.length)
201
+ unions.push({
202
+ type: "functional",
203
+ is: () =>
204
+ ts.factory.createStrictEquality(
205
+ ts.factory.createStringLiteral("function"),
206
+ ts.factory.createTypeOfExpression(props.input),
207
+ ),
208
+ value: () => ts.factory.createIdentifier("undefined"),
209
+ });
224
210
 
225
- // ARRAYS
226
- if (meta.arrays.length)
227
- unions.push({
228
- type: "array",
229
- is: () => ExpressionFactory.isArray(input),
230
- value: () =>
231
- explore_arrays(project)(config)(importer)(input, meta.arrays, {
232
- ...explore,
211
+ // TUPLES
212
+ for (const tuple of props.metadata.tuples)
213
+ unions.push({
214
+ type: "tuple",
215
+ is: () =>
216
+ IsProgrammer.decode(props.context)(props.importer)(
217
+ props.input,
218
+ (() => {
219
+ const partial = Metadata.initialize();
220
+ partial.tuples.push(tuple);
221
+ return partial;
222
+ })(),
223
+ props.explore,
224
+ ),
225
+ value: () =>
226
+ decode_tuple({
227
+ ...props,
228
+ tuple,
229
+ }),
230
+ });
231
+
232
+ // ARRAYS
233
+ if (props.metadata.arrays.length)
234
+ unions.push({
235
+ type: "array",
236
+ is: () => ExpressionFactory.isArray(props.input),
237
+ value: () =>
238
+ explore_arrays({
239
+ ...props,
240
+ elements: props.metadata.arrays,
241
+ explore: {
242
+ ...props.explore,
233
243
  from: "array",
234
- }),
235
- });
244
+ },
245
+ }),
246
+ });
236
247
 
237
- // NATIVE TYPES
238
- if (meta.sets.length)
239
- unions.push({
240
- type: "set",
241
- is: () => ExpressionFactory.isInstanceOf("Set")(input),
242
- value: () =>
243
- explore_sets(project)(config)(importer)(input, meta.sets, {
244
- ...explore,
248
+ // NATIVE TYPES
249
+ if (props.metadata.sets.length)
250
+ unions.push({
251
+ type: "set",
252
+ is: () => ExpressionFactory.isInstanceOf("Set")(props.input),
253
+ value: () =>
254
+ explore_sets({
255
+ ...props,
256
+ sets: props.metadata.sets,
257
+ explore: {
258
+ ...props.explore,
245
259
  from: "array",
246
- }),
247
- });
248
- if (meta.maps.length)
249
- unions.push({
250
- type: "map",
251
- is: () => ExpressionFactory.isInstanceOf("Map")(input),
252
- value: () =>
253
- explore_maps(project)(config)(importer)(input, meta.maps, {
254
- ...explore,
260
+ },
261
+ }),
262
+ });
263
+ if (props.metadata.maps.length)
264
+ unions.push({
265
+ type: "map",
266
+ is: () => ExpressionFactory.isInstanceOf("Map")(props.input),
267
+ value: () =>
268
+ explore_maps({
269
+ ...props,
270
+ maps: props.metadata.maps,
271
+ explore: {
272
+ ...props.explore,
255
273
  from: "array",
256
- }),
257
- });
258
- for (const native of meta.natives) {
259
- if (native === "WeakSet" || native === "WeakMap") continue;
260
- unions.push({
261
- type: "native",
262
- is: () => ExpressionFactory.isInstanceOf(native)(input),
263
- value: () =>
264
- native === "Boolean" || native === "Number" || native === "String"
265
- ? ts.factory.createCallExpression(
266
- IdentifierFactory.access(input)("valueOf"),
267
- undefined,
268
- undefined,
269
- )
270
- : decode_native(native)(input),
271
- });
272
- }
273
-
274
- // OBJECTS
275
- if (meta.objects.length)
276
- unions.push({
277
- type: "object",
278
- is: () =>
279
- ExpressionFactory.isObject({
280
- checkNull: true,
281
- checkArray: false,
282
- })(input),
283
- value: () =>
284
- explore_objects(config)(importer)(input, meta, {
285
- ...explore,
286
- from: "object",
287
- }),
288
- });
289
-
290
- // COMPOSITION
291
- if (unions.length === 0) return input;
292
- else if (unions.length === 1 && meta.size() === 1) {
293
- const value: ts.Expression =
294
- (meta.nullable || meta.isRequired() === false) && is_instance(meta)
295
- ? ts.factory.createConditionalExpression(
296
- input,
274
+ },
275
+ }),
276
+ });
277
+ for (const native of props.metadata.natives) {
278
+ if (native === "WeakSet" || native === "WeakMap") continue;
279
+ unions.push({
280
+ type: "native",
281
+ is: () => ExpressionFactory.isInstanceOf(native)(props.input),
282
+ value: () =>
283
+ native === "Boolean" || native === "Number" || native === "String"
284
+ ? ts.factory.createCallExpression(
285
+ IdentifierFactory.access(props.input)("valueOf"),
297
286
  undefined,
298
- unions[0]!.value(),
299
287
  undefined,
300
- input,
301
288
  )
302
- : unions[0]!.value();
303
- return ts.factory.createAsExpression(value, TypeFactory.keyword("any"));
304
- } else {
305
- let last: ts.Expression = input;
306
- for (const u of unions.reverse())
307
- last = ts.factory.createConditionalExpression(
308
- u.is(),
309
- undefined,
310
- u.value(),
311
- undefined,
312
- last,
313
- );
314
- return ts.factory.createAsExpression(last, TypeFactory.keyword("any"));
315
- }
316
- };
289
+ : decode_native({
290
+ name: native,
291
+ input: props.input,
292
+ }),
293
+ });
294
+ }
295
+
296
+ // OBJECTS
297
+ if (props.metadata.objects.length)
298
+ unions.push({
299
+ type: "object",
300
+ is: () =>
301
+ ExpressionFactory.isObject({
302
+ checkNull: true,
303
+ checkArray: false,
304
+ })(props.input),
305
+ value: () =>
306
+ explore_objects({
307
+ ...props,
308
+ explore: {
309
+ ...props.explore,
310
+ from: "object",
311
+ },
312
+ }),
313
+ });
314
+
315
+ // COMPOSITION
316
+ if (unions.length === 0) return props.input;
317
+ else if (unions.length === 1 && props.metadata.size() === 1) {
318
+ const value: ts.Expression =
319
+ (props.metadata.nullable || props.metadata.isRequired() === false) &&
320
+ is_instance(props.metadata)
321
+ ? ts.factory.createConditionalExpression(
322
+ props.input,
323
+ undefined,
324
+ unions[0]!.value(),
325
+ undefined,
326
+ props.input,
327
+ )
328
+ : unions[0]!.value();
329
+ return ts.factory.createAsExpression(value, TypeFactory.keyword("any"));
330
+ } else {
331
+ let last: ts.Expression = props.input;
332
+ for (const u of unions.reverse())
333
+ last = ts.factory.createConditionalExpression(
334
+ u.is(),
335
+ undefined,
336
+ u.value(),
337
+ undefined,
338
+ last,
339
+ );
340
+ return ts.factory.createAsExpression(last, TypeFactory.keyword("any"));
341
+ }
342
+ };
317
343
 
318
344
  const decode_object = (importer: FunctionImporter) =>
319
345
  FeatureProgrammer.decode_object({
@@ -322,348 +348,403 @@ export namespace NotationGeneralProgrammer {
322
348
  prefix: PREFIX,
323
349
  })(importer);
324
350
 
325
- const decode_array =
326
- (config: FeatureProgrammer.IConfig) =>
327
- (importer: FunctionImporter) =>
328
- (
329
- input: ts.Expression,
330
- array: MetadataArray,
331
- explore: FeatureProgrammer.IExplore,
332
- ) =>
333
- array.type.recursive
334
- ? ts.factory.createCallExpression(
335
- ts.factory.createIdentifier(
336
- importer.useLocal(`${config.prefix}a${array.type.index}`),
351
+ const decode_array = (props: {
352
+ config: FeatureProgrammer.IConfig;
353
+ importer: FunctionImporter;
354
+ input: ts.Expression;
355
+ array: MetadataArray;
356
+ explore: FeatureProgrammer.IExplore;
357
+ }) =>
358
+ props.array.type.recursive
359
+ ? ts.factory.createCallExpression(
360
+ ts.factory.createIdentifier(
361
+ props.importer.useLocal(
362
+ `${props.config.prefix}a${props.array.type.index}`,
337
363
  ),
338
- undefined,
339
- FeatureProgrammer.argumentsArray(config)({
340
- ...explore,
341
- source: "function",
342
- from: "array",
343
- })(input),
344
- )
345
- : decode_array_inline(config)(importer)(input, array, explore);
346
-
347
- const decode_array_inline =
348
- (config: FeatureProgrammer.IConfig) =>
349
- (importer: FunctionImporter) =>
350
- (
351
- input: ts.Expression,
352
- array: MetadataArray,
353
- explore: FeatureProgrammer.IExplore,
354
- ) =>
355
- FeatureProgrammer.decode_array(config)(importer)(NotationJoiner.array)(
356
- input,
357
- array,
358
- explore,
359
- );
364
+ ),
365
+ undefined,
366
+ FeatureProgrammer.argumentsArray(props.config)({
367
+ ...props.explore,
368
+ source: "function",
369
+ from: "array",
370
+ })(props.input),
371
+ )
372
+ : decode_array_inline(props);
360
373
 
361
- const decode_tuple =
362
- (project: ITypiaContext) =>
363
- (config: FeatureProgrammer.IConfig) =>
364
- (importer: FunctionImporter) =>
365
- (
366
- input: ts.Expression,
367
- tuple: MetadataTuple,
368
- explore: FeatureProgrammer.IExplore,
369
- ): ts.Expression =>
370
- tuple.type.recursive
371
- ? ts.factory.createCallExpression(
372
- ts.factory.createIdentifier(
373
- importer.useLocal(`${config.prefix}t${tuple.type.index}`),
374
+ const decode_array_inline = (props: {
375
+ config: FeatureProgrammer.IConfig;
376
+ importer: FunctionImporter;
377
+ input: ts.Expression;
378
+ array: MetadataArray;
379
+ explore: FeatureProgrammer.IExplore;
380
+ }) =>
381
+ FeatureProgrammer.decode_array(props.config)(props.importer)(
382
+ NotationJoiner.array,
383
+ )(props.input, props.array, props.explore);
384
+
385
+ const decode_tuple = (props: {
386
+ context: ITypiaContext;
387
+ config: FeatureProgrammer.IConfig;
388
+ importer: FunctionImporter;
389
+ tuple: MetadataTuple;
390
+ explore: FeatureProgrammer.IExplore;
391
+ input: ts.Expression;
392
+ }): ts.Expression =>
393
+ props.tuple.type.recursive
394
+ ? ts.factory.createCallExpression(
395
+ ts.factory.createIdentifier(
396
+ props.importer.useLocal(
397
+ `${props.config.prefix}t${props.tuple.type.index}`,
374
398
  ),
375
- undefined,
376
- FeatureProgrammer.argumentsArray(config)({
377
- ...explore,
378
- source: "function",
379
- })(input),
380
- )
381
- : decode_tuple_inline(project)(config)(importer)(
382
- input,
383
- tuple.type,
384
- explore,
385
- );
386
-
387
- const decode_tuple_inline =
388
- (project: ITypiaContext) =>
389
- (config: FeatureProgrammer.IConfig) =>
390
- (importer: FunctionImporter) =>
391
- (
392
- input: ts.Expression,
393
- tuple: MetadataTupleType,
394
- explore: FeatureProgrammer.IExplore,
395
- ): ts.Expression => {
396
- const elements: ts.Expression[] = tuple.elements
397
- .filter((m) => m.rest === null)
398
- .map((elem, index) =>
399
- decode(project)(config)(importer)(
400
- ts.factory.createElementAccessExpression(input, index),
401
- elem,
402
- {
403
- ...explore,
404
- from: "array",
405
- postfix: explore.postfix.length
406
- ? `${postfix_of_tuple(explore.postfix)}[${index}]"`
407
- : `"[${index}]"`,
408
- },
409
399
  ),
410
- );
411
- const rest = (() => {
412
- if (tuple.elements.length === 0) return null;
413
-
414
- const last: Metadata = tuple.elements.at(-1)!;
415
- const rest: Metadata | null = last.rest;
416
- if (rest === null) return null;
400
+ undefined,
401
+ FeatureProgrammer.argumentsArray(props.config)({
402
+ ...props.explore,
403
+ source: "function",
404
+ })(props.input),
405
+ )
406
+ : decode_tuple_inline({
407
+ ...props,
408
+ tuple: props.tuple.type,
409
+ });
417
410
 
418
- return decode(project)(config)(importer)(
419
- ts.factory.createCallExpression(
420
- IdentifierFactory.access(input)("slice"),
421
- undefined,
422
- [ExpressionFactory.number(tuple.elements.length - 1)],
423
- ),
424
- wrap_metadata_rest_tuple(tuple.elements.at(-1)!.rest!),
425
- {
426
- ...explore,
427
- start: tuple.elements.length - 1,
411
+ const decode_tuple_inline = (props: {
412
+ context: ITypiaContext;
413
+ config: FeatureProgrammer.IConfig;
414
+ importer: FunctionImporter;
415
+ explore: FeatureProgrammer.IExplore;
416
+ tuple: MetadataTupleType;
417
+ input: ts.Expression;
418
+ }): ts.Expression => {
419
+ const elements: ts.Expression[] = props.tuple.elements
420
+ .filter((m) => m.rest === null)
421
+ .map((elem, index) =>
422
+ decode({
423
+ ...props,
424
+ input: ts.factory.createElementAccessExpression(props.input, index),
425
+ metadata: elem,
426
+ explore: {
427
+ ...props.explore,
428
+ from: "array",
429
+ postfix: props.explore.postfix.length
430
+ ? `${postfix_of_tuple(props.explore.postfix)}[${index}]"`
431
+ : `"[${index}]"`,
428
432
  },
429
- );
430
- })();
431
- return NotationJoiner.tuple({
432
- elements,
433
- rest,
433
+ }),
434
+ );
435
+ const rest = (() => {
436
+ if (props.tuple.elements.length === 0) return null;
437
+
438
+ const last: Metadata = props.tuple.elements.at(-1)!;
439
+ const rest: Metadata | null = last.rest;
440
+ if (rest === null) return null;
441
+
442
+ return decode({
443
+ ...props,
444
+ input: ts.factory.createCallExpression(
445
+ IdentifierFactory.access(props.input)("slice"),
446
+ undefined,
447
+ [ExpressionFactory.number(props.tuple.elements.length - 1)],
448
+ ),
449
+ metadata: wrap_metadata_rest_tuple(props.tuple.elements.at(-1)!.rest!),
450
+ explore: {
451
+ ...props.explore,
452
+ start: props.tuple.elements.length - 1,
453
+ },
434
454
  });
435
- };
455
+ })();
456
+ return NotationJoiner.tuple({
457
+ elements,
458
+ rest,
459
+ });
460
+ };
436
461
 
437
462
  /* -----------------------------------------------------------
438
463
  NATIVE CLASSES
439
464
  ----------------------------------------------------------- */
440
- const decode_native = (type: string) => (input: ts.Expression) =>
441
- type === "Date"
465
+ const decode_native = (props: { name: string; input: ts.Expression }) =>
466
+ props.name === "Date"
442
467
  ? ts.factory.createNewExpression(
443
- ts.factory.createIdentifier(type),
468
+ ts.factory.createIdentifier(props.name),
444
469
  undefined,
445
- [input],
470
+ [props.input],
446
471
  )
447
- : input;
472
+ : props.input;
448
473
 
449
474
  /* -----------------------------------------------------------
450
475
  EXPLORERS FOR UNION TYPES
451
476
  ----------------------------------------------------------- */
452
- const explore_sets =
453
- (project: ITypiaContext) =>
454
- (config: FeatureProgrammer.IConfig) =>
455
- (importer: FunctionImporter) =>
456
- (
457
- input: ts.Expression,
458
- sets: Metadata[],
459
- explore: FeatureProgrammer.IExplore,
460
- ): ts.Expression =>
461
- ts.factory.createCallExpression(
462
- UnionExplorer.set({
463
- checker: IsProgrammer.decode(project)(importer),
464
- decoder: (input, array, explore) =>
465
- ts.factory.createNewExpression(
466
- ts.factory.createIdentifier("Set"),
467
- [TypeFactory.keyword("any")],
468
- [decode_array(config)(importer)(input, array, explore)],
469
- ),
470
- empty: ts.factory.createNewExpression(
477
+ const explore_sets = (props: {
478
+ context: ITypiaContext;
479
+ config: FeatureProgrammer.IConfig;
480
+ importer: FunctionImporter;
481
+ input: ts.Expression;
482
+ explore: FeatureProgrammer.IExplore;
483
+ sets: Metadata[];
484
+ }): ts.Expression =>
485
+ ts.factory.createCallExpression(
486
+ UnionExplorer.set({
487
+ checker: IsProgrammer.decode(props.context)(props.importer),
488
+ decoder: (input, array, explore) =>
489
+ ts.factory.createNewExpression(
471
490
  ts.factory.createIdentifier("Set"),
472
491
  [TypeFactory.keyword("any")],
473
- [],
492
+ [
493
+ decode_array({
494
+ config: props.config,
495
+ importer: props.importer,
496
+ input,
497
+ array,
498
+ explore,
499
+ }),
500
+ ],
474
501
  ),
475
- success: ts.factory.createTrue(),
476
- failure: (input, expected) =>
477
- create_throw_error(importer)(expected)(input),
478
- })([])(input, sets, explore),
479
- undefined,
480
- undefined,
481
- );
502
+ empty: ts.factory.createNewExpression(
503
+ ts.factory.createIdentifier("Set"),
504
+ [TypeFactory.keyword("any")],
505
+ [],
506
+ ),
507
+ success: ts.factory.createTrue(),
508
+ failure: (input, expected) =>
509
+ create_throw_error({ importer: props.importer, expected, input }),
510
+ })([])(props.input, props.sets, props.explore),
511
+ undefined,
512
+ undefined,
513
+ );
482
514
 
483
- const explore_maps =
484
- (project: ITypiaContext) =>
485
- (config: FeatureProgrammer.IConfig) =>
486
- (importer: FunctionImporter) =>
487
- (
488
- input: ts.Expression,
489
- maps: Metadata.Entry[],
490
- explore: FeatureProgrammer.IExplore,
491
- ): ts.Expression =>
492
- ts.factory.createCallExpression(
493
- UnionExplorer.map({
494
- checker: (top, entry, explore) => {
495
- const func = IsProgrammer.decode(project)(importer);
496
- return ts.factory.createLogicalAnd(
497
- func(ts.factory.createElementAccessExpression(top, 0), entry[0], {
498
- ...explore,
499
- postfix: `${explore.postfix}[0]`,
500
- }),
501
- func(ts.factory.createElementAccessExpression(top, 1), entry[1], {
502
- ...explore,
503
- postfix: `${explore.postfix}[1]`,
504
- }),
505
- );
506
- },
507
- decoder: (input, array, explore) =>
508
- ts.factory.createNewExpression(
509
- ts.factory.createIdentifier("Map"),
510
- [TypeFactory.keyword("any"), TypeFactory.keyword("any")],
511
- [decode_array(config)(importer)(input, array, explore)],
512
- ),
513
- empty: ts.factory.createNewExpression(
515
+ const explore_maps = (props: {
516
+ context: ITypiaContext;
517
+ config: FeatureProgrammer.IConfig;
518
+ importer: FunctionImporter;
519
+ input: ts.Expression;
520
+ maps: Metadata.Entry[];
521
+ explore: FeatureProgrammer.IExplore;
522
+ }): ts.Expression =>
523
+ ts.factory.createCallExpression(
524
+ UnionExplorer.map({
525
+ checker: (top, entry, explore) => {
526
+ const func = IsProgrammer.decode(props.context)(props.importer);
527
+ return ts.factory.createLogicalAnd(
528
+ func(ts.factory.createElementAccessExpression(top, 0), entry[0], {
529
+ ...explore,
530
+ postfix: `${explore.postfix}[0]`,
531
+ }),
532
+ func(ts.factory.createElementAccessExpression(top, 1), entry[1], {
533
+ ...explore,
534
+ postfix: `${explore.postfix}[1]`,
535
+ }),
536
+ );
537
+ },
538
+ decoder: (input, array, explore) =>
539
+ ts.factory.createNewExpression(
514
540
  ts.factory.createIdentifier("Map"),
515
541
  [TypeFactory.keyword("any"), TypeFactory.keyword("any")],
516
- [],
542
+ [
543
+ decode_array({
544
+ config: props.config,
545
+ importer: props.importer,
546
+ input,
547
+ array,
548
+ explore,
549
+ }),
550
+ ],
517
551
  ),
518
- success: ts.factory.createTrue(),
519
- failure: (input, expected) =>
520
- create_throw_error(importer)(expected)(input),
521
- })([])(input, maps, explore),
522
- undefined,
523
- undefined,
524
- );
525
-
526
- const explore_objects =
527
- (config: FeatureProgrammer.IConfig) =>
528
- (importer: FunctionImporter) =>
529
- (
530
- input: ts.Expression,
531
- meta: Metadata,
532
- explore: FeatureProgrammer.IExplore,
533
- ) => {
534
- if (meta.objects.length === 1)
535
- return decode_object(importer)(input, meta.objects[0]!, explore);
536
-
537
- return ts.factory.createCallExpression(
538
- ts.factory.createIdentifier(
539
- importer.useLocal(`${PREFIX}u${meta.union_index!}`),
552
+ empty: ts.factory.createNewExpression(
553
+ ts.factory.createIdentifier("Map"),
554
+ [TypeFactory.keyword("any"), TypeFactory.keyword("any")],
555
+ [],
540
556
  ),
541
- undefined,
542
- FeatureProgrammer.argumentsArray(config)(explore)(input),
557
+ success: ts.factory.createTrue(),
558
+ failure: (input, expected) =>
559
+ create_throw_error({ importer: props.importer, expected, input }),
560
+ })([])(props.input, props.maps, props.explore),
561
+ undefined,
562
+ undefined,
563
+ );
564
+
565
+ const explore_objects = (props: {
566
+ config: FeatureProgrammer.IConfig;
567
+ importer: FunctionImporter;
568
+ input: ts.Expression;
569
+ metadata: Metadata;
570
+ explore: FeatureProgrammer.IExplore;
571
+ }) => {
572
+ if (props.metadata.objects.length === 1)
573
+ return decode_object(props.importer)(
574
+ props.input,
575
+ props.metadata.objects[0]!,
576
+ props.explore,
543
577
  );
544
- };
578
+ return ts.factory.createCallExpression(
579
+ ts.factory.createIdentifier(
580
+ props.importer.useLocal(`${PREFIX}u${props.metadata.union_index!}`),
581
+ ),
582
+ undefined,
583
+ FeatureProgrammer.argumentsArray(props.config)(props.explore)(
584
+ props.input,
585
+ ),
586
+ );
587
+ };
545
588
 
546
- const explore_arrays =
547
- (project: ITypiaContext) =>
548
- (config: FeatureProgrammer.IConfig) =>
549
- (importer: FunctionImporter) =>
550
- (
551
- input: ts.Expression,
552
- elements: MetadataArray[],
553
- explore: FeatureProgrammer.IExplore,
554
- ): ts.Expression =>
555
- explore_array_like_union_types(config)(importer)(
556
- UnionExplorer.array({
557
- checker: IsProgrammer.decode(project)(importer),
558
- decoder: decode_array(config)(importer),
559
- empty: ts.factory.createIdentifier("[]"),
560
- success: ts.factory.createTrue(),
561
- failure: (input, expected) =>
562
- create_throw_error(importer)(expected)(input),
563
- }),
564
- )(input, elements, explore);
565
-
566
- const explore_array_like_union_types =
567
- (config: FeatureProgrammer.IConfig) =>
568
- (importer: FunctionImporter) =>
569
- <T extends MetadataArray | MetadataTuple>(
570
- factory: (
571
- parameters: ts.ParameterDeclaration[],
572
- ) => (
573
- input: ts.Expression,
574
- elements: T[],
575
- explore: FeatureProgrammer.IExplore,
576
- ) => ts.ArrowFunction,
577
- ) =>
578
- (
589
+ const explore_arrays = (props: {
590
+ context: ITypiaContext;
591
+ config: FeatureProgrammer.IConfig;
592
+ importer: FunctionImporter;
593
+ input: ts.Expression;
594
+ elements: MetadataArray[];
595
+ explore: FeatureProgrammer.IExplore;
596
+ }): ts.Expression =>
597
+ explore_array_like_union_types({
598
+ ...props,
599
+ factory: UnionExplorer.array({
600
+ checker: IsProgrammer.decode(props.context)(props.importer),
601
+ decoder: (input, array, explore) =>
602
+ decode_array({
603
+ config: props.config,
604
+ importer: props.importer,
605
+ input,
606
+ array,
607
+ explore,
608
+ }),
609
+ empty: ts.factory.createIdentifier("[]"),
610
+ success: ts.factory.createTrue(),
611
+ failure: (input, expected) =>
612
+ create_throw_error({
613
+ importer: props.importer,
614
+ expected,
615
+ input,
616
+ }),
617
+ }),
618
+ });
619
+
620
+ const explore_array_like_union_types = <
621
+ T extends MetadataArray | MetadataTuple,
622
+ >(props: {
623
+ config: FeatureProgrammer.IConfig;
624
+ importer: FunctionImporter;
625
+ factory: (
626
+ parameters: ts.ParameterDeclaration[],
627
+ ) => (
579
628
  input: ts.Expression,
580
629
  elements: T[],
581
630
  explore: FeatureProgrammer.IExplore,
582
- ): ts.Expression => {
583
- const arrow =
584
- (parameters: ts.ParameterDeclaration[]) =>
585
- (explore: FeatureProgrammer.IExplore) =>
586
- (input: ts.Expression): ts.ArrowFunction =>
587
- factory(parameters)(input, elements, explore);
588
- if (elements.every((e) => e.type.recursive === false))
589
- ts.factory.createCallExpression(
590
- arrow([])(explore)(input),
591
- undefined,
592
- [],
593
- );
594
-
595
- explore = {
596
- ...explore,
597
- source: "function",
598
- from: "array",
599
- };
600
- return ts.factory.createCallExpression(
601
- ts.factory.createIdentifier(
602
- importer.emplaceUnion(
603
- config.prefix,
604
- elements.map((e) => e.type.name).join(" | "),
605
- () =>
606
- arrow(
607
- FeatureProgrammer.parameterDeclarations(config)(
608
- TypeFactory.keyword("any"),
609
- )(ts.factory.createIdentifier("input")),
610
- )({
611
- ...explore,
612
- postfix: "",
613
- })(ts.factory.createIdentifier("input")),
614
- ),
615
- ),
631
+ ) => ts.ArrowFunction;
632
+ input: ts.Expression;
633
+ elements: T[];
634
+ explore: FeatureProgrammer.IExplore;
635
+ }): ts.Expression => {
636
+ const arrow =
637
+ (parameters: ts.ParameterDeclaration[]) =>
638
+ (explore: FeatureProgrammer.IExplore) =>
639
+ (input: ts.Expression): ts.ArrowFunction =>
640
+ props.factory(parameters)(input, props.elements, explore);
641
+ if (props.elements.every((e) => e.type.recursive === false))
642
+ ts.factory.createCallExpression(
643
+ arrow([])(props.explore)(props.input),
616
644
  undefined,
617
- FeatureProgrammer.argumentsArray(config)(explore)(input),
645
+ [],
618
646
  );
647
+
648
+ const explore: FeatureProgrammer.IExplore = {
649
+ ...props.explore,
650
+ source: "function",
651
+ from: "array",
619
652
  };
653
+ return ts.factory.createCallExpression(
654
+ ts.factory.createIdentifier(
655
+ props.importer.emplaceUnion(
656
+ props.config.prefix,
657
+ props.elements.map((e) => e.type.name).join(" | "),
658
+ () =>
659
+ arrow(
660
+ FeatureProgrammer.parameterDeclarations(props.config)(
661
+ TypeFactory.keyword("any"),
662
+ )(ts.factory.createIdentifier("input")),
663
+ )({
664
+ ...explore,
665
+ postfix: "",
666
+ })(ts.factory.createIdentifier("input")),
667
+ ),
668
+ ),
669
+ undefined,
670
+ FeatureProgrammer.argumentsArray(props.config)(explore)(props.input),
671
+ );
672
+ };
620
673
 
621
674
  /* -----------------------------------------------------------
622
675
  CONFIGURATIONS
623
676
  ----------------------------------------------------------- */
624
677
  const PREFIX = "$c";
625
678
 
626
- const configure =
627
- (rename: (str: string) => string) =>
628
- (project: ITypiaContext) =>
629
- (importer: FunctionImporter): FeatureProgrammer.IConfig => {
630
- const config: FeatureProgrammer.IConfig = {
631
- types: {
632
- input: (type, name) =>
633
- ts.factory.createTypeReferenceNode(
634
- name ?? TypeFactory.getFullName(project.checker)(type),
635
- ),
636
- output: (type, name) =>
637
- ts.factory.createTypeReferenceNode(
638
- returnType(rename)(
639
- name ?? TypeFactory.getFullName(project.checker)(type),
640
- ),
679
+ const configure = (props: {
680
+ rename: (str: string) => string;
681
+ context: ITypiaContext;
682
+ importer: FunctionImporter;
683
+ }): FeatureProgrammer.IConfig => {
684
+ const config: FeatureProgrammer.IConfig = {
685
+ types: {
686
+ input: (type, name) =>
687
+ ts.factory.createTypeReferenceNode(
688
+ name ?? TypeFactory.getFullName(props.context.checker)(type),
689
+ ),
690
+ output: (type, name) =>
691
+ ts.factory.createTypeReferenceNode(
692
+ returnType(props.rename)(
693
+ name ?? TypeFactory.getFullName(props.context.checker)(type),
641
694
  ),
642
- },
643
- prefix: PREFIX,
644
- trace: false,
645
- path: false,
646
- initializer,
647
- decoder: () => decode(project)(config)(importer),
648
- objector: {
649
- checker: () => IsProgrammer.decode(project)(importer),
650
- decoder: () => decode_object(importer),
651
- joiner: NotationJoiner.object(rename),
652
- unionizer: decode_union_object(
653
- IsProgrammer.decode_object(project)(importer),
654
- )(decode_object(importer))((exp) => exp)((input, expected) =>
655
- create_throw_error(importer)(expected)(input),
656
695
  ),
657
- failure: (input, expected) =>
658
- create_throw_error(importer)(expected)(input),
659
- },
660
- generator: {
661
- arrays: () => write_array_functions(config)(importer),
662
- tuples: () => write_tuple_functions(project)(config)(importer),
663
- },
664
- };
665
- return config;
696
+ },
697
+ prefix: PREFIX,
698
+ trace: false,
699
+ path: false,
700
+ initializer,
701
+ decoder: () => (input, metadata, explore) =>
702
+ decode({
703
+ context: props.context,
704
+ config,
705
+ importer: props.importer,
706
+ metadata,
707
+ explore,
708
+ input,
709
+ }),
710
+ objector: {
711
+ checker: () => IsProgrammer.decode(props.context)(props.importer),
712
+ decoder: () => decode_object(props.importer),
713
+ joiner: NotationJoiner.object(props.rename),
714
+ unionizer: decode_union_object(
715
+ IsProgrammer.decode_object(props.context)(props.importer),
716
+ )(decode_object(props.importer))((exp) => exp)((input, expected) =>
717
+ create_throw_error({
718
+ importer: props.importer,
719
+ expected,
720
+ input,
721
+ }),
722
+ ),
723
+ failure: (input, expected) =>
724
+ create_throw_error({
725
+ importer: props.importer,
726
+ expected,
727
+ input,
728
+ }),
729
+ },
730
+ generator: {
731
+ arrays: () => (collection) =>
732
+ write_array_functions({
733
+ importer: props.importer,
734
+ config,
735
+ collection,
736
+ }),
737
+ tuples: () => (collection) =>
738
+ write_tuple_functions({
739
+ context: props.context,
740
+ importer: props.importer,
741
+ config,
742
+ collection,
743
+ }),
744
+ },
666
745
  };
746
+ return config;
747
+ };
667
748
 
668
749
  const initializer: FeatureProgrammer.IConfig["initializer"] =
669
750
  (project) => (importer) => (type) => {
@@ -686,28 +767,29 @@ export namespace NotationGeneralProgrammer {
686
767
  return [collection, result.data];
687
768
  };
688
769
 
689
- const create_throw_error =
690
- (importer: FunctionImporter) =>
691
- (expected: string) =>
692
- (value: ts.Expression) =>
693
- ts.factory.createExpressionStatement(
694
- ts.factory.createCallExpression(
695
- importer.use("throws"),
696
- [],
697
- [
698
- ts.factory.createObjectLiteralExpression(
699
- [
700
- ts.factory.createPropertyAssignment(
701
- "expected",
702
- ts.factory.createStringLiteral(expected),
703
- ),
704
- ts.factory.createPropertyAssignment("value", value),
705
- ],
706
- true,
707
- ),
708
- ],
709
- ),
710
- );
770
+ const create_throw_error = (props: {
771
+ importer: FunctionImporter;
772
+ expected: string;
773
+ input: ts.Expression;
774
+ }) =>
775
+ ts.factory.createExpressionStatement(
776
+ ts.factory.createCallExpression(
777
+ props.importer.use("throws"),
778
+ [],
779
+ [
780
+ ts.factory.createObjectLiteralExpression(
781
+ [
782
+ ts.factory.createPropertyAssignment(
783
+ "expected",
784
+ ts.factory.createStringLiteral(props.expected),
785
+ ),
786
+ ts.factory.createPropertyAssignment("value", props.input),
787
+ ],
788
+ true,
789
+ ),
790
+ ],
791
+ ),
792
+ );
711
793
 
712
794
  const is_instance = (meta: Metadata): boolean =>
713
795
  !!meta.objects.length ||