typia 7.0.0-dev.20240922 → 7.0.0-dev.20240923

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.
@@ -11,6 +11,7 @@ import { ValueFactory } from "../../factories/ValueFactory";
11
11
  import { Metadata } from "../../schemas/metadata/Metadata";
12
12
  import { MetadataArray } from "../../schemas/metadata/MetadataArray";
13
13
  import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic";
14
+ import { MetadataObject } from "../../schemas/metadata/MetadataObject";
14
15
  import { MetadataTuple } from "../../schemas/metadata/MetadataTuple";
15
16
  import { MetadataTupleType } from "../../schemas/metadata/MetadataTupleType";
16
17
 
@@ -19,8 +20,6 @@ import { ITypiaContext } from "../../transformers/ITypiaContext";
19
20
 
20
21
  import { Atomic } from "../../typings/Atomic";
21
22
 
22
- import { ArrayUtil } from "../../utils/ArrayUtil";
23
-
24
23
  import { FeatureProgrammer } from "../FeatureProgrammer";
25
24
  import { IsProgrammer } from "../IsProgrammer";
26
25
  import { AtomicPredicator } from "../helpers/AtomicPredicator";
@@ -45,9 +44,7 @@ export namespace JsonStringifyProgrammer {
45
44
  type: ts.Type;
46
45
  name: string | undefined;
47
46
  }): FeatureProgrammer.IDecomposed => {
48
- const config: FeatureProgrammer.IConfig = configure(props.context)(
49
- props.importer,
50
- );
47
+ const config: FeatureProgrammer.IConfig = configure(props);
51
48
  if (props.validated === false)
52
49
  config.addition = (collection) =>
53
50
  IsProgrammer.write_function_statements(props.context)(props.importer)(
@@ -87,589 +84,631 @@ export namespace JsonStringifyProgrammer {
87
84
  });
88
85
  };
89
86
 
90
- const write_array_functions =
91
- (config: FeatureProgrammer.IConfig) =>
92
- (importer: FunctionImporter) =>
93
- (collection: MetadataCollection): ts.VariableStatement[] =>
94
- collection
95
- .arrays()
96
- .filter((a) => a.recursive)
97
- .map((type, i) =>
98
- StatementFactory.constant(
99
- `${config.prefix}a${i}`,
100
- ts.factory.createArrowFunction(
101
- undefined,
102
- undefined,
103
- FeatureProgrammer.parameterDeclarations(config)(
104
- TypeFactory.keyword("any"),
105
- )(ts.factory.createIdentifier("input")),
87
+ const write_array_functions = (props: {
88
+ config: FeatureProgrammer.IConfig;
89
+ importer: FunctionImporter;
90
+ collection: MetadataCollection;
91
+ }): ts.VariableStatement[] =>
92
+ props.collection
93
+ .arrays()
94
+ .filter((a) => a.recursive)
95
+ .map((type, i) =>
96
+ StatementFactory.constant(
97
+ `${props.config.prefix}a${i}`,
98
+ ts.factory.createArrowFunction(
99
+ undefined,
100
+ undefined,
101
+ FeatureProgrammer.parameterDeclarations(props.config)(
106
102
  TypeFactory.keyword("any"),
107
- undefined,
108
- decode_array_inline(config)(importer)(
109
- ts.factory.createIdentifier("input"),
110
- MetadataArray.create({
111
- type,
112
- tags: [],
113
- }),
114
- {
115
- tracable: config.trace,
116
- source: "function",
117
- from: "array",
118
- postfix: "",
119
- },
120
- ),
121
- ),
103
+ )(ts.factory.createIdentifier("input")),
104
+ TypeFactory.keyword("any"),
105
+ undefined,
106
+ decode_array_inline({
107
+ config: props.config,
108
+ importer: props.importer,
109
+ input: ts.factory.createIdentifier("input"),
110
+ array: MetadataArray.create({
111
+ type,
112
+ tags: [],
113
+ }),
114
+ explore: {
115
+ tracable: props.config.trace,
116
+ source: "function",
117
+ from: "array",
118
+ postfix: "",
119
+ },
120
+ }),
122
121
  ),
123
- );
122
+ ),
123
+ );
124
124
 
125
- const write_tuple_functions =
126
- (project: ITypiaContext) =>
127
- (config: FeatureProgrammer.IConfig) =>
128
- (importer: FunctionImporter) =>
129
- (collection: MetadataCollection): ts.VariableStatement[] =>
130
- collection
131
- .tuples()
132
- .filter((t) => t.recursive)
133
- .map((tuple, i) =>
134
- StatementFactory.constant(
135
- `${config.prefix}t${i}`,
136
- ts.factory.createArrowFunction(
137
- undefined,
138
- undefined,
139
- FeatureProgrammer.parameterDeclarations(config)(
140
- TypeFactory.keyword("any"),
141
- )(ts.factory.createIdentifier("input")),
125
+ const write_tuple_functions = (props: {
126
+ context: ITypiaContext;
127
+ config: FeatureProgrammer.IConfig;
128
+ importer: FunctionImporter;
129
+ collection: MetadataCollection;
130
+ }): ts.VariableStatement[] =>
131
+ props.collection
132
+ .tuples()
133
+ .filter((t) => t.recursive)
134
+ .map((tuple, i) =>
135
+ StatementFactory.constant(
136
+ `${props.config.prefix}t${i}`,
137
+ ts.factory.createArrowFunction(
138
+ undefined,
139
+ undefined,
140
+ FeatureProgrammer.parameterDeclarations(props.config)(
142
141
  TypeFactory.keyword("any"),
143
- undefined,
144
- decode_tuple_inline(project)(config)(importer)(
145
- ts.factory.createIdentifier("input"),
146
- tuple,
147
- {
148
- tracable: config.trace,
149
- source: "function",
150
- from: "array",
151
- postfix: "",
152
- },
153
- ),
154
- ),
142
+ )(ts.factory.createIdentifier("input")),
143
+ TypeFactory.keyword("any"),
144
+ undefined,
145
+ decode_tuple_inline({
146
+ context: props.context,
147
+ config: props.config,
148
+ importer: props.importer,
149
+ input: ts.factory.createIdentifier("input"),
150
+ tuple,
151
+ explore: {
152
+ tracable: props.config.trace,
153
+ source: "function",
154
+ from: "array",
155
+ postfix: "",
156
+ },
157
+ }),
155
158
  ),
156
- );
159
+ ),
160
+ );
157
161
 
158
162
  /* -----------------------------------------------------------
159
163
  DECODERS
160
164
  ----------------------------------------------------------- */
161
- const decode =
162
- (project: ITypiaContext) =>
163
- (config: FeatureProgrammer.IConfig) =>
164
- (importer: FunctionImporter) =>
165
- (
166
- input: ts.Expression,
167
- metadata: Metadata,
168
- explore: FeatureProgrammer.IExplore,
169
- ): ts.Expression => {
170
- // ANY TYPE
171
- if (metadata.any === true)
172
- return wrap_required(
173
- input,
174
- metadata,
175
- explore,
176
- )(
177
- wrap_functional({
178
- input,
179
- metadata,
180
- explore,
181
- expression: ts.factory.createCallExpression(
182
- ts.factory.createIdentifier("JSON.stringify"),
165
+ const decode = (props: {
166
+ context: ITypiaContext;
167
+ config: FeatureProgrammer.IConfig;
168
+ importer: FunctionImporter;
169
+ input: ts.Expression;
170
+ metadata: Metadata;
171
+ explore: FeatureProgrammer.IExplore;
172
+ }): ts.Expression => {
173
+ // ANY TYPE
174
+ if (props.metadata.any === true)
175
+ return wrap_required({
176
+ input: props.input,
177
+ metadata: props.metadata,
178
+ explore: props.explore,
179
+ expression: wrap_functional({
180
+ input: props.input,
181
+ metadata: props.metadata,
182
+ explore: props.explore,
183
+ expression: ts.factory.createCallExpression(
184
+ ts.factory.createIdentifier("JSON.stringify"),
185
+ undefined,
186
+ [props.input],
187
+ ),
188
+ }),
189
+ });
190
+
191
+ // ONLY NULL OR UNDEFINED
192
+ const size: number = props.metadata.size();
193
+ if (
194
+ size === 0 &&
195
+ (props.metadata.isRequired() === false ||
196
+ props.metadata.nullable === true)
197
+ ) {
198
+ if (
199
+ props.metadata.isRequired() === false &&
200
+ props.metadata.nullable === true
201
+ )
202
+ return props.explore.from === "array"
203
+ ? ts.factory.createStringLiteral("null")
204
+ : ts.factory.createConditionalExpression(
205
+ ts.factory.createStrictEquality(
206
+ ts.factory.createNull(),
207
+ props.input,
208
+ ),
183
209
  undefined,
184
- [input],
185
- ),
210
+ ts.factory.createStringLiteral("null"),
211
+ undefined,
212
+ ts.factory.createIdentifier("undefined"),
213
+ );
214
+ else if (props.metadata.isRequired() === false)
215
+ return props.explore.from === "array"
216
+ ? ts.factory.createStringLiteral("null")
217
+ : ts.factory.createIdentifier("undefined");
218
+ else return ts.factory.createStringLiteral("null");
219
+ }
220
+
221
+ //----
222
+ // LIST UP UNION TYPES
223
+ //----
224
+ const unions: IUnion[] = [];
225
+
226
+ // toJSON() METHOD
227
+ if (props.metadata.escaped !== null)
228
+ unions.push({
229
+ type: "resolved",
230
+ is:
231
+ props.metadata.escaped.original.size() === 1 &&
232
+ props.metadata.escaped.original.natives[0] === "Date"
233
+ ? () => check_native("Date")(props.input)
234
+ : () => IsProgrammer.decode_to_json(false)(props.input),
235
+ value: () =>
236
+ decode_to_json({
237
+ ...props,
238
+ metadata: props.metadata.escaped!.returns,
186
239
  }),
187
- );
240
+ });
241
+ else if (props.metadata.functions.length)
242
+ unions.push({
243
+ type: "functional",
244
+ is: () => IsProgrammer.decode_functional(props.input),
245
+ value: () => decode_functional(props.explore),
246
+ });
188
247
 
189
- // ONLY NULL OR UNDEFINED
190
- const size: number = metadata.size();
191
- if (
192
- size === 0 &&
193
- (metadata.isRequired() === false || metadata.nullable === true)
194
- ) {
195
- if (metadata.isRequired() === false && metadata.nullable === true)
196
- return explore.from === "array"
197
- ? ts.factory.createStringLiteral("null")
198
- : ts.factory.createConditionalExpression(
199
- ts.factory.createStrictEquality(ts.factory.createNull(), input),
200
- undefined,
201
- ts.factory.createStringLiteral("null"),
202
- undefined,
203
- ts.factory.createIdentifier("undefined"),
204
- );
205
- else if (metadata.isRequired() === false)
206
- return explore.from === "array"
207
- ? ts.factory.createStringLiteral("null")
208
- : ts.factory.createIdentifier("undefined");
209
- else return ts.factory.createStringLiteral("null");
248
+ // TEMPLATES
249
+ if (props.metadata.templates.length)
250
+ if (AtomicPredicator.template(props.metadata)) {
251
+ const partial = Metadata.initialize();
252
+ partial.atomics.push(
253
+ MetadataAtomic.create({ type: "string", tags: [] }),
254
+ ),
255
+ unions.push({
256
+ type: "template literal",
257
+ is: () =>
258
+ IsProgrammer.decode(props.context)(props.importer)(
259
+ props.input,
260
+ partial,
261
+ props.explore,
262
+ ),
263
+ value: () =>
264
+ decode_atomic({
265
+ ...props,
266
+ type: "string",
267
+ }),
268
+ });
210
269
  }
211
270
 
212
- //----
213
- // LIST UP UNION TYPES
214
- //----
215
- const unions: IUnion[] = [];
216
-
217
- // toJSON() METHOD
218
- if (metadata.escaped !== null)
271
+ // CONSTANTS
272
+ for (const constant of props.metadata.constants)
273
+ if (
274
+ AtomicPredicator.constant({
275
+ metadata: props.metadata,
276
+ name: constant.type,
277
+ }) === false
278
+ )
279
+ continue;
280
+ else if (constant.type !== "string")
219
281
  unions.push({
220
- type: "resolved",
221
- is:
222
- metadata.escaped.original.size() === 1 &&
223
- metadata.escaped.original.natives[0] === "Date"
224
- ? () => check_native("Date")(input)
225
- : () => IsProgrammer.decode_to_json(false)(input),
226
- value: () =>
227
- decode_to_json(project)(config)(importer)(
228
- input,
229
- metadata.escaped!.returns,
230
- explore,
282
+ type: "atomic",
283
+ is: () =>
284
+ IsProgrammer.decode(props.context)(props.importer)(
285
+ props.input,
286
+ (() => {
287
+ const partial = Metadata.initialize();
288
+ partial.atomics.push(
289
+ MetadataAtomic.create({
290
+ type: constant.type,
291
+ tags: [],
292
+ }),
293
+ );
294
+ return partial;
295
+ })(),
296
+ props.explore,
231
297
  ),
298
+ value: () =>
299
+ decode_atomic({
300
+ ...props,
301
+ type: constant.type,
302
+ }),
232
303
  });
233
- else if (metadata.functions.length)
304
+ else if (props.metadata.templates.length === 0)
234
305
  unions.push({
235
- type: "functional",
236
- is: () => IsProgrammer.decode_functional(input),
237
- value: () => decode_functional(explore),
306
+ type: "const string",
307
+ is: () =>
308
+ IsProgrammer.decode(props.context)(props.importer)(
309
+ props.input,
310
+ (() => {
311
+ const partial = Metadata.initialize();
312
+ partial.atomics.push(
313
+ MetadataAtomic.create({
314
+ type: "string",
315
+ tags: [],
316
+ }),
317
+ );
318
+ return partial;
319
+ })(),
320
+ props.explore,
321
+ ),
322
+ value: () =>
323
+ decode_constant_string({
324
+ ...props,
325
+ values: [...constant.values.map((v) => v.value)] as string[],
326
+ }),
238
327
  });
239
328
 
240
- // TEMPLATES
329
+ /// ATOMICS
330
+ for (const a of props.metadata.atomics)
241
331
  if (
242
- metadata.templates.length ||
243
- ArrayUtil.has(metadata.constants, (c) => c.type === "string")
332
+ AtomicPredicator.atomic({
333
+ metadata: props.metadata,
334
+ name: a.type,
335
+ })
244
336
  )
245
- if (AtomicPredicator.template(metadata)) {
246
- const partial = Metadata.initialize();
247
- partial.atomics.push(
248
- MetadataAtomic.create({ type: "string", tags: [] }),
249
- ),
250
- unions.push({
251
- type: "template literal",
252
- is: () =>
253
- IsProgrammer.decode(project)(importer)(input, partial, explore),
254
- value: () =>
255
- decode_atomic(project)(importer)(input, "string", explore),
256
- });
257
- }
258
-
259
- // CONSTANTS
260
- for (const constant of metadata.constants)
261
- if (
262
- AtomicPredicator.constant({
263
- metadata,
264
- name: constant.type,
265
- }) === false
266
- )
267
- continue;
268
- else if (constant.type !== "string")
269
- unions.push({
270
- type: "atomic",
271
- is: () =>
272
- IsProgrammer.decode(project)(importer)(
273
- input,
274
- (() => {
275
- const partial = Metadata.initialize();
276
- partial.atomics.push(
277
- MetadataAtomic.create({
278
- type: constant.type,
279
- tags: [],
280
- }),
281
- );
282
- return partial;
283
- })(),
284
- explore,
285
- ),
286
- value: () =>
287
- decode_atomic(project)(importer)(input, constant.type, explore),
288
- });
289
- else if (metadata.templates.length === 0)
290
- unions.push({
291
- type: "const string",
292
- is: () =>
293
- IsProgrammer.decode(project)(importer)(
294
- input,
295
- (() => {
296
- const partial = Metadata.initialize();
297
- partial.atomics.push(
298
- MetadataAtomic.create({
299
- type: "string",
300
- tags: [],
301
- }),
302
- );
303
- return partial;
304
- })(),
305
- explore,
306
- ),
307
- value: () =>
308
- decode_constant_string(project)(importer)(
309
- input,
310
- [...constant.values.map((v) => v.value)] as string[],
311
- explore,
312
- ),
313
- });
314
-
315
- /// ATOMICS
316
- for (const a of metadata.atomics)
317
- if (
318
- AtomicPredicator.atomic({
319
- metadata,
320
- name: a.type,
321
- })
322
- )
323
- unions.push({
324
- type: "atomic",
325
- is: () =>
326
- IsProgrammer.decode(project)(importer)(
327
- input,
328
- (() => {
329
- const partial = Metadata.initialize();
330
- partial.atomics.push(a);
331
- return partial;
332
- })(),
333
- explore,
334
- ),
335
- value: () =>
336
- decode_atomic(project)(importer)(input, a.type, explore),
337
- });
338
-
339
- // TUPLES
340
- for (const tuple of metadata.tuples)
341
337
  unions.push({
342
- type: "tuple",
338
+ type: "atomic",
343
339
  is: () =>
344
- IsProgrammer.decode(project)(importer)(
345
- input,
340
+ IsProgrammer.decode(props.context)(props.importer)(
341
+ props.input,
346
342
  (() => {
347
343
  const partial = Metadata.initialize();
348
- partial.tuples.push(tuple);
344
+ partial.atomics.push(a);
349
345
  return partial;
350
346
  })(),
351
- explore,
347
+ props.explore,
352
348
  ),
353
349
  value: () =>
354
- decode_tuple(project)(config)(importer)(input, tuple, explore),
350
+ decode_atomic({
351
+ ...props,
352
+ type: a.type,
353
+ }),
355
354
  });
356
355
 
357
- // ARRAYS
358
- if (metadata.arrays.length) {
359
- const value: () => ts.Expression =
360
- metadata.arrays.length === 1
361
- ? () =>
362
- decode_array(config)(importer)(input, metadata.arrays[0]!, {
363
- ...explore,
364
- from: "array",
365
- })
366
- : metadata.arrays.some((elem) => elem.type.value.any)
367
- ? () =>
368
- ts.factory.createCallExpression(
369
- ts.factory.createIdentifier("JSON.stringify"),
370
- undefined,
371
- [input],
372
- )
373
- : () =>
374
- explore_arrays(project)(config)(importer)(
375
- input,
376
- metadata.arrays,
377
- {
378
- ...explore,
379
- from: "array",
380
- },
381
- );
356
+ // TUPLES
357
+ for (const tuple of props.metadata.tuples)
358
+ unions.push({
359
+ type: "tuple",
360
+ is: () =>
361
+ IsProgrammer.decode(props.context)(props.importer)(
362
+ props.input,
363
+ (() => {
364
+ const partial = Metadata.initialize();
365
+ partial.tuples.push(tuple);
366
+ return partial;
367
+ })(),
368
+ props.explore,
369
+ ),
370
+ value: () =>
371
+ decode_tuple({
372
+ ...props,
373
+ tuple,
374
+ }),
375
+ });
382
376
 
383
- unions.push({
384
- type: "array",
385
- is: () => ExpressionFactory.isArray(input),
386
- value,
387
- });
388
- }
377
+ // ARRAYS
378
+ if (props.metadata.arrays.length) {
379
+ const value: () => ts.Expression =
380
+ props.metadata.arrays.length === 1
381
+ ? () =>
382
+ decode_array({
383
+ ...props,
384
+ array: props.metadata.arrays[0]!,
385
+ explore: {
386
+ ...props.explore,
387
+ from: "array",
388
+ },
389
+ })
390
+ : props.metadata.arrays.some((elem) => elem.type.value.any)
391
+ ? () =>
392
+ ts.factory.createCallExpression(
393
+ ts.factory.createIdentifier("JSON.stringify"),
394
+ undefined,
395
+ [props.input],
396
+ )
397
+ : () =>
398
+ explore_arrays({
399
+ ...props,
400
+ elements: props.metadata.arrays,
401
+ explore: {
402
+ ...props.explore,
403
+ from: "array",
404
+ },
405
+ });
389
406
 
390
- // BUILT-IN CLASSES
391
- if (metadata.natives.length)
392
- for (const native of metadata.natives)
393
- unions.push({
394
- type: "object",
395
- is: () => check_native(native)(input),
396
- value: () =>
397
- AtomicPredicator.native(native)
398
- ? decode_atomic(project)(importer)(
399
- input,
400
- native.toLowerCase() as Atomic.Literal,
401
- explore,
402
- )
403
- : ts.factory.createStringLiteral("{}"),
404
- });
407
+ unions.push({
408
+ type: "array",
409
+ is: () => ExpressionFactory.isArray(props.input),
410
+ value,
411
+ });
412
+ }
405
413
 
406
- // SETS
407
- if (metadata.sets.length)
414
+ // BUILT-IN CLASSES
415
+ if (props.metadata.natives.length)
416
+ for (const native of props.metadata.natives)
408
417
  unions.push({
409
418
  type: "object",
410
- is: () => ExpressionFactory.isInstanceOf("Set")(input),
411
- value: () => ts.factory.createStringLiteral("{}"),
419
+ is: () => check_native(native)(props.input),
420
+ value: () =>
421
+ AtomicPredicator.native(native)
422
+ ? decode_atomic({
423
+ ...props,
424
+ type: native.toLowerCase() as Atomic.Literal,
425
+ })
426
+ : ts.factory.createStringLiteral("{}"),
412
427
  });
413
428
 
414
- // MAPS
415
- if (metadata.maps.length)
416
- unions.push({
417
- type: "object",
418
- is: () => ExpressionFactory.isInstanceOf("Map")(input),
419
- value: () => ts.factory.createStringLiteral("{}"),
420
- });
429
+ // SETS
430
+ if (props.metadata.sets.length)
431
+ unions.push({
432
+ type: "object",
433
+ is: () => ExpressionFactory.isInstanceOf("Set")(props.input),
434
+ value: () => ts.factory.createStringLiteral("{}"),
435
+ });
421
436
 
422
- // OBJECTS
423
- if (metadata.objects.length)
424
- unions.push({
425
- type: "object",
426
- is: () =>
427
- ExpressionFactory.isObject({
428
- checkNull: true,
429
- checkArray: metadata.objects.some((obj) =>
430
- obj.properties.every(
431
- (prop) =>
432
- !prop.key.isSoleLiteral() || !prop.value.isRequired(),
433
- ),
437
+ // MAPS
438
+ if (props.metadata.maps.length)
439
+ unions.push({
440
+ type: "object",
441
+ is: () => ExpressionFactory.isInstanceOf("Map")(props.input),
442
+ value: () => ts.factory.createStringLiteral("{}"),
443
+ });
444
+
445
+ // OBJECTS
446
+ if (props.metadata.objects.length)
447
+ unions.push({
448
+ type: "object",
449
+ is: () =>
450
+ ExpressionFactory.isObject({
451
+ checkNull: true,
452
+ checkArray: props.metadata.objects.some((objects) =>
453
+ objects.properties.every(
454
+ (prop) => !prop.key.isSoleLiteral() || !prop.value.isRequired(),
434
455
  ),
435
- })(input),
436
- value: () =>
437
- explore_objects(config)(importer)(input, metadata, {
438
- ...explore,
456
+ ),
457
+ })(props.input),
458
+ value: () =>
459
+ explore_objects({
460
+ ...props,
461
+ explore: {
462
+ ...props.explore,
439
463
  from: "object",
440
- }),
441
- });
464
+ },
465
+ }),
466
+ });
442
467
 
443
- //----
444
- // RETURNS
445
- //----
446
- // CHECK NULL AND UNDEFINED
447
- const wrapper = (output: ts.Expression) =>
448
- wrap_required(
449
- input,
450
- metadata,
451
- explore,
452
- )(wrap_nullable(input, metadata)(output));
468
+ //----
469
+ // RETURNS
470
+ //----
471
+ // CHECK NULL AND UNDEFINED
472
+ const wrapper = (output: ts.Expression) =>
473
+ wrap_required({
474
+ input: props.input,
475
+ metadata: props.metadata,
476
+ explore: props.explore,
477
+ expression: wrap_nullable({
478
+ input: props.input,
479
+ metadata: props.metadata,
480
+ expression: output,
481
+ }),
482
+ });
453
483
 
454
- // DIRECT RETURN
455
- if (unions.length === 0)
456
- return ts.factory.createCallExpression(
457
- ts.factory.createIdentifier("JSON.stringify"),
458
- undefined,
459
- [input],
460
- );
461
- else if (unions.length === 1) return wrapper(unions[0]!.value());
484
+ // DIRECT RETURN
485
+ if (unions.length === 0)
486
+ return ts.factory.createCallExpression(
487
+ ts.factory.createIdentifier("JSON.stringify"),
488
+ undefined,
489
+ [props.input],
490
+ );
491
+ else if (unions.length === 1) return wrapper(unions[0]!.value());
462
492
 
463
- // RETURN WITH TYPE CHECKING
464
- return wrapper(
465
- ts.factory.createCallExpression(
466
- ts.factory.createArrowFunction(
467
- undefined,
468
- undefined,
469
- [],
470
- undefined,
471
- undefined,
472
- iterate({
473
- importer,
474
- input,
475
- unions,
476
- expected: metadata.getName(),
477
- }),
478
- ),
493
+ // RETURN WITH TYPE CHECKING
494
+ return wrapper(
495
+ ts.factory.createCallExpression(
496
+ ts.factory.createArrowFunction(
497
+ undefined,
498
+ undefined,
499
+ [],
479
500
  undefined,
480
501
  undefined,
502
+ iterate({
503
+ importer: props.importer,
504
+ input: props.input,
505
+ expected: props.metadata.getName(),
506
+ unions,
507
+ }),
481
508
  ),
482
- );
483
- };
509
+ undefined,
510
+ undefined,
511
+ ),
512
+ );
513
+ };
484
514
 
485
- const decode_object = (importer: FunctionImporter) =>
515
+ const decode_object = (props: {
516
+ importer: FunctionImporter;
517
+ input: ts.Expression;
518
+ object: MetadataObject;
519
+ explore: FeatureProgrammer.IExplore;
520
+ }): ts.CallExpression =>
486
521
  FeatureProgrammer.decode_object({
487
522
  trace: false,
488
523
  path: false,
489
524
  prefix: PREFIX,
490
- })(importer);
491
-
492
- const decode_array =
493
- (config: FeatureProgrammer.IConfig) =>
494
- (importer: FunctionImporter) =>
495
- (
496
- input: ts.Expression,
497
- array: MetadataArray,
498
- explore: FeatureProgrammer.IExplore,
499
- ) =>
500
- array.type.recursive
501
- ? ts.factory.createCallExpression(
502
- ts.factory.createIdentifier(
503
- importer.useLocal(`${config.prefix}a${array.type.index}`),
504
- ),
505
- undefined,
506
- FeatureProgrammer.argumentsArray(config)({
507
- ...explore,
508
- source: "function",
509
- from: "array",
510
- })(input),
511
- )
512
- : decode_array_inline(config)(importer)(input, array, explore);
513
-
514
- const decode_array_inline =
515
- (config: FeatureProgrammer.IConfig) =>
516
- (importer: FunctionImporter) =>
517
- (
518
- input: ts.Expression,
519
- array: MetadataArray,
520
- explore: FeatureProgrammer.IExplore,
521
- ) =>
522
- FeatureProgrammer.decode_array(config)(importer)(StringifyJoiner.array)(
523
- input,
524
- array,
525
- explore,
526
- );
525
+ })(props.importer)(props.input, props.object, props.explore);
527
526
 
528
- const decode_tuple =
529
- (project: ITypiaContext) =>
530
- (config: FeatureProgrammer.IConfig) =>
531
- (importer: FunctionImporter) =>
532
- (
533
- input: ts.Expression,
534
- tuple: MetadataTuple,
535
- explore: FeatureProgrammer.IExplore,
536
- ): ts.Expression =>
537
- tuple.type.recursive
538
- ? ts.factory.createCallExpression(
539
- ts.factory.createIdentifier(
540
- importer.useLocal(`${config.prefix}t${tuple.type.index}`),
527
+ const decode_array = (props: {
528
+ config: FeatureProgrammer.IConfig;
529
+ importer: FunctionImporter;
530
+ input: ts.Expression;
531
+ array: MetadataArray;
532
+ explore: FeatureProgrammer.IExplore;
533
+ }) =>
534
+ props.array.type.recursive
535
+ ? ts.factory.createCallExpression(
536
+ ts.factory.createIdentifier(
537
+ props.importer.useLocal(
538
+ `${props.config.prefix}a${props.array.type.index}`,
541
539
  ),
542
- undefined,
543
- FeatureProgrammer.argumentsArray(config)({
544
- ...explore,
545
- source: "function",
546
- })(input),
547
- )
548
- : decode_tuple_inline(project)(config)(importer)(
549
- input,
550
- tuple.type,
551
- explore,
552
- );
553
-
554
- const decode_tuple_inline =
555
- (project: ITypiaContext) =>
556
- (config: FeatureProgrammer.IConfig) =>
557
- (importer: FunctionImporter) =>
558
- (
559
- input: ts.Expression,
560
- tuple: MetadataTupleType,
561
- explore: FeatureProgrammer.IExplore,
562
- ): ts.Expression => {
563
- const elements: ts.Expression[] = tuple.elements
564
- .filter((elem) => elem.rest === null)
565
- .map((elem, index) =>
566
- decode(project)(config)(importer)(
567
- ts.factory.createElementAccessExpression(input, index),
568
- elem,
569
- {
570
- ...explore,
571
- from: "array",
572
- postfix: explore.postfix.length
573
- ? `${postfix_of_tuple(explore.postfix)}[${index}]"`
574
- : `"[${index}]"`,
575
- },
576
540
  ),
577
- );
578
- const rest = (() => {
579
- if (tuple.elements.length === 0) return null;
580
- const last = tuple.elements.at(-1)!;
581
- if (last.rest === null) return null;
582
-
583
- const code = decode(project)(config)(importer)(
584
- ts.factory.createCallExpression(
585
- IdentifierFactory.access(input)("slice"),
586
- undefined,
587
- [ExpressionFactory.number(tuple.elements.length - 1)],
541
+ undefined,
542
+ FeatureProgrammer.argumentsArray(props.config)({
543
+ ...props.explore,
544
+ source: "function",
545
+ from: "array",
546
+ })(props.input),
547
+ )
548
+ : decode_array_inline(props);
549
+
550
+ const decode_array_inline = (props: {
551
+ config: FeatureProgrammer.IConfig;
552
+ importer: FunctionImporter;
553
+ input: ts.Expression;
554
+ array: MetadataArray;
555
+ explore: FeatureProgrammer.IExplore;
556
+ }) =>
557
+ FeatureProgrammer.decode_array(props.config)(props.importer)(
558
+ StringifyJoiner.array,
559
+ )(props.input, props.array, props.explore);
560
+
561
+ const decode_tuple = (props: {
562
+ context: ITypiaContext;
563
+ config: FeatureProgrammer.IConfig;
564
+ importer: FunctionImporter;
565
+ input: ts.Expression;
566
+ tuple: MetadataTuple;
567
+ explore: FeatureProgrammer.IExplore;
568
+ }): ts.Expression =>
569
+ props.tuple.type.recursive
570
+ ? ts.factory.createCallExpression(
571
+ ts.factory.createIdentifier(
572
+ props.importer.useLocal(
573
+ `${props.config.prefix}t${props.tuple.type.index}`,
574
+ ),
588
575
  ),
589
- wrap_metadata_rest_tuple(tuple.elements.at(-1)!.rest!),
590
- {
591
- ...explore,
592
- start: tuple.elements.length - 1,
576
+ undefined,
577
+ FeatureProgrammer.argumentsArray(props.config)({
578
+ ...props.explore,
579
+ source: "function",
580
+ })(props.input),
581
+ )
582
+ : decode_tuple_inline({
583
+ ...props,
584
+ tuple: props.tuple.type,
585
+ });
586
+
587
+ const decode_tuple_inline = (props: {
588
+ context: ITypiaContext;
589
+ config: FeatureProgrammer.IConfig;
590
+ importer: FunctionImporter;
591
+ input: ts.Expression;
592
+ tuple: MetadataTupleType;
593
+ explore: FeatureProgrammer.IExplore;
594
+ }): ts.Expression => {
595
+ const elements: ts.Expression[] = props.tuple.elements
596
+ .filter((elem) => elem.rest === null)
597
+ .map((elem, index) =>
598
+ decode({
599
+ ...props,
600
+ input: ts.factory.createElementAccessExpression(props.input, index),
601
+ metadata: elem,
602
+ explore: {
603
+ ...props.explore,
604
+ from: "array",
605
+ postfix: props.explore.postfix.length
606
+ ? `${postfix_of_tuple(props.explore.postfix)}[${index}]"`
607
+ : `"[${index}]"`,
593
608
  },
594
- );
595
- return ts.factory.createCallExpression(
596
- importer.use("rest"),
609
+ }),
610
+ );
611
+ const rest = (() => {
612
+ if (props.tuple.elements.length === 0) return null;
613
+ const last = props.tuple.elements.at(-1)!;
614
+ if (last.rest === null) return null;
615
+
616
+ const code = decode({
617
+ ...props,
618
+ input: ts.factory.createCallExpression(
619
+ IdentifierFactory.access(props.input)("slice"),
597
620
  undefined,
598
- [code],
599
- );
600
- })();
601
- return StringifyJoiner.tuple({
602
- elements,
603
- rest,
621
+ [ExpressionFactory.number(props.tuple.elements.length - 1)],
622
+ ),
623
+ metadata: wrap_metadata_rest_tuple(props.tuple.elements.at(-1)!.rest!),
624
+ explore: {
625
+ ...props.explore,
626
+ start: props.tuple.elements.length - 1,
627
+ },
604
628
  });
605
- };
629
+ return ts.factory.createCallExpression(
630
+ props.importer.use("rest"),
631
+ undefined,
632
+ [code],
633
+ );
634
+ })();
635
+ return StringifyJoiner.tuple({
636
+ elements,
637
+ rest,
638
+ });
639
+ };
606
640
 
607
- const decode_atomic =
608
- (project: ITypiaContext) =>
609
- (importer: FunctionImporter) =>
610
- (
611
- input: ts.Expression,
612
- type: string,
613
- explore: FeatureProgrammer.IExplore,
614
- ) => {
615
- if (type === "string")
616
- return ts.factory.createCallExpression(
617
- importer.use("string"),
641
+ const decode_atomic = (props: {
642
+ context: ITypiaContext;
643
+ importer: FunctionImporter;
644
+ input: ts.Expression;
645
+ type: string;
646
+ explore: FeatureProgrammer.IExplore;
647
+ }): ts.Expression => {
648
+ if (props.type === "string")
649
+ return ts.factory.createCallExpression(
650
+ props.importer.use("string"),
651
+ undefined,
652
+ [props.input],
653
+ );
654
+ else if (
655
+ props.type === "number" &&
656
+ OptionPredicator.numeric(props.context.options)
657
+ )
658
+ props = {
659
+ ...props,
660
+ input: ts.factory.createCallExpression(
661
+ props.importer.use("number"),
662
+ undefined,
663
+ [props.input],
664
+ ),
665
+ };
666
+
667
+ return props.explore.from !== "top"
668
+ ? props.input
669
+ : ts.factory.createCallExpression(
670
+ IdentifierFactory.access(props.input)("toString"),
618
671
  undefined,
619
- [input],
620
- );
621
- else if (type === "number" && OptionPredicator.numeric(project.options))
622
- input = ts.factory.createCallExpression(
623
- importer.use("number"),
624
672
  undefined,
625
- [input],
626
673
  );
674
+ };
627
675
 
628
- return explore.from !== "top"
629
- ? input
630
- : ts.factory.createCallExpression(
631
- IdentifierFactory.access(input)("toString"),
632
- undefined,
633
- undefined,
634
- );
635
- };
636
-
637
- const decode_constant_string =
638
- (project: ITypiaContext) =>
639
- (importer: FunctionImporter) =>
640
- (
641
- input: ts.Expression,
642
- values: string[],
643
- explore: FeatureProgrammer.IExplore,
644
- ): ts.Expression => {
645
- if (values.every((v) => !StringifyPredicator.require_escape(v)))
646
- return [
647
- ts.factory.createStringLiteral('"'),
648
- input,
649
- ts.factory.createStringLiteral('"'),
650
- ].reduce((x, y) => ts.factory.createAdd(x, y));
651
- else return decode_atomic(project)(importer)(input, "string", explore);
652
- };
676
+ const decode_constant_string = (props: {
677
+ context: ITypiaContext;
678
+ importer: FunctionImporter;
679
+ input: ts.Expression;
680
+ values: string[];
681
+ explore: FeatureProgrammer.IExplore;
682
+ }): ts.Expression => {
683
+ if (props.values.every((v) => !StringifyPredicator.require_escape(v)))
684
+ return [
685
+ ts.factory.createStringLiteral('"'),
686
+ props.input,
687
+ ts.factory.createStringLiteral('"'),
688
+ ].reduce((x, y) => ts.factory.createAdd(x, y));
689
+ return decode_atomic({
690
+ ...props,
691
+ type: "string",
692
+ });
693
+ };
653
694
 
654
- const decode_to_json =
655
- (project: ITypiaContext) =>
656
- (config: FeatureProgrammer.IConfig) =>
657
- (importer: FunctionImporter) =>
658
- (
659
- input: ts.Expression,
660
- resolved: Metadata,
661
- explore: FeatureProgrammer.IExplore,
662
- ): ts.Expression => {
663
- return decode(project)(config)(importer)(
664
- ts.factory.createCallExpression(
665
- IdentifierFactory.access(input)("toJSON"),
666
- undefined,
667
- [],
668
- ),
669
- resolved,
670
- explore,
671
- );
672
- };
695
+ const decode_to_json = (props: {
696
+ context: ITypiaContext;
697
+ config: FeatureProgrammer.IConfig;
698
+ importer: FunctionImporter;
699
+ input: ts.Expression;
700
+ metadata: Metadata;
701
+ explore: FeatureProgrammer.IExplore;
702
+ }): ts.Expression => {
703
+ return decode({
704
+ ...props,
705
+ input: ts.factory.createCallExpression(
706
+ IdentifierFactory.access(props.input)("toJSON"),
707
+ undefined,
708
+ [],
709
+ ),
710
+ });
711
+ };
673
712
 
674
713
  const decode_functional = (explore: FeatureProgrammer.IExplore) =>
675
714
  explore.from === "array"
@@ -679,137 +718,165 @@ export namespace JsonStringifyProgrammer {
679
718
  /* -----------------------------------------------------------
680
719
  EXPLORERS
681
720
  ----------------------------------------------------------- */
682
- const explore_objects =
683
- (config: FeatureProgrammer.IConfig) =>
684
- (importer: FunctionImporter) =>
685
- (
686
- input: ts.Expression,
687
- meta: Metadata,
688
- explore: FeatureProgrammer.IExplore,
689
- ) =>
690
- meta.objects.length === 1
691
- ? decode_object(importer)(input, meta.objects[0]!, explore)
692
- : ts.factory.createCallExpression(
693
- ts.factory.createIdentifier(
694
- importer.useLocal(`${PREFIX}u${meta.union_index!}`),
695
- ),
696
- undefined,
697
- FeatureProgrammer.argumentsArray(config)(explore)(input),
698
- );
699
-
700
- const explore_arrays =
701
- (project: ITypiaContext) =>
702
- (config: FeatureProgrammer.IConfig) =>
703
- (importer: FunctionImporter) =>
704
- (
705
- input: ts.Expression,
706
- elements: MetadataArray[],
707
- explore: FeatureProgrammer.IExplore,
708
- ): ts.Expression =>
709
- explore_array_like_union_types(config)(importer)(
721
+ const explore_objects = (props: {
722
+ config: FeatureProgrammer.IConfig;
723
+ importer: FunctionImporter;
724
+ input: ts.Expression;
725
+ metadata: Metadata;
726
+ explore: FeatureProgrammer.IExplore;
727
+ }) =>
728
+ props.metadata.objects.length === 1
729
+ ? decode_object({
730
+ importer: props.importer,
731
+ input: props.input,
732
+ object: props.metadata.objects[0]!,
733
+ explore: props.explore,
734
+ })
735
+ : ts.factory.createCallExpression(
736
+ ts.factory.createIdentifier(
737
+ props.importer.useLocal(`${PREFIX}u${props.metadata.union_index!}`),
738
+ ),
739
+ undefined,
740
+ FeatureProgrammer.argumentsArray(props.config)(props.explore)(
741
+ props.input,
742
+ ),
743
+ );
744
+
745
+ const explore_arrays = (props: {
746
+ context: ITypiaContext;
747
+ config: FeatureProgrammer.IConfig;
748
+ importer: FunctionImporter;
749
+ input: ts.Expression;
750
+ elements: MetadataArray[];
751
+ explore: FeatureProgrammer.IExplore;
752
+ }): ts.Expression =>
753
+ explore_array_like_union_types({
754
+ ...props,
755
+ factory: (next) =>
710
756
  UnionExplorer.array({
711
- checker: IsProgrammer.decode(project)(importer),
712
- decoder: decode_array(config)(importer),
757
+ checker: IsProgrammer.decode(props.context)(props.importer),
758
+ decoder: (input, array, explore) =>
759
+ decode_array({
760
+ config: props.config,
761
+ importer: props.importer,
762
+ input,
763
+ array,
764
+ explore,
765
+ }),
713
766
  empty: ts.factory.createStringLiteral("[]"),
714
767
  success: ts.factory.createTrue(),
715
768
  failure: (input, expected) =>
716
- create_throw_error({ importer, expected, input }),
769
+ create_throw_error({
770
+ importer: props.importer,
771
+ expected,
772
+ input,
773
+ }),
774
+ })(next.parameters)(next.input, next.elements, next.explore),
775
+ });
776
+
777
+ const explore_array_like_union_types = <
778
+ T extends MetadataArray | MetadataTuple,
779
+ >(props: {
780
+ config: FeatureProgrammer.IConfig;
781
+ importer: FunctionImporter;
782
+ factory: (next: {
783
+ parameters: ts.ParameterDeclaration[];
784
+ input: ts.Expression;
785
+ elements: T[];
786
+ explore: FeatureProgrammer.IExplore;
787
+ }) => ts.ArrowFunction;
788
+ input: ts.Expression;
789
+ elements: T[];
790
+ explore: FeatureProgrammer.IExplore;
791
+ }): ts.Expression => {
792
+ const arrow = (next: {
793
+ parameters: ts.ParameterDeclaration[];
794
+ explore: FeatureProgrammer.IExplore;
795
+ input: ts.Expression;
796
+ }): ts.ArrowFunction =>
797
+ props.factory({
798
+ elements: props.elements,
799
+ parameters: next.parameters,
800
+ input: next.input,
801
+ explore: next.explore,
802
+ });
803
+ if (props.elements.every((e) => e.type.recursive === false))
804
+ ts.factory.createCallExpression(
805
+ arrow({
806
+ parameters: [],
807
+ explore: props.explore,
808
+ input: props.input,
717
809
  }),
718
- )(input, elements, explore);
719
-
720
- const explore_array_like_union_types =
721
- (config: FeatureProgrammer.IConfig) =>
722
- (importer: FunctionImporter) =>
723
- <T extends MetadataArray | MetadataTuple>(
724
- factory: (
725
- parameters: ts.ParameterDeclaration[],
726
- ) => (
727
- input: ts.Expression,
728
- elements: T[],
729
- explore: FeatureProgrammer.IExplore,
730
- ) => ts.ArrowFunction,
731
- ) =>
732
- (
733
- input: ts.Expression,
734
- elements: T[],
735
- explore: FeatureProgrammer.IExplore,
736
- ): ts.Expression => {
737
- const arrow =
738
- (parameters: ts.ParameterDeclaration[]) =>
739
- (explore: FeatureProgrammer.IExplore) =>
740
- (input: ts.Expression): ts.ArrowFunction =>
741
- factory(parameters)(input, elements, explore);
742
- if (elements.every((e) => e.type.recursive === false))
743
- ts.factory.createCallExpression(
744
- arrow([])(explore)(input),
745
- undefined,
746
- [],
747
- );
810
+ undefined,
811
+ [],
812
+ );
748
813
 
749
- explore = {
750
- ...explore,
751
- source: "function",
752
- from: "array",
753
- };
754
- return ts.factory.createCallExpression(
755
- ts.factory.createIdentifier(
756
- importer.emplaceUnion(
757
- config.prefix,
758
- elements.map((e) => e.type.name).join(" | "),
759
- () =>
760
- arrow(
761
- FeatureProgrammer.parameterDeclarations(config)(
762
- TypeFactory.keyword("any"),
763
- )(ts.factory.createIdentifier("input")),
764
- )({
814
+ const explore: FeatureProgrammer.IExplore = {
815
+ ...props.explore,
816
+ source: "function",
817
+ from: "array",
818
+ };
819
+ return ts.factory.createCallExpression(
820
+ ts.factory.createIdentifier(
821
+ props.importer.emplaceUnion(
822
+ props.config.prefix,
823
+ props.elements.map((e) => e.type.name).join(" | "),
824
+ () =>
825
+ arrow({
826
+ parameters: FeatureProgrammer.parameterDeclarations(props.config)(
827
+ TypeFactory.keyword("any"),
828
+ )(ts.factory.createIdentifier("input")),
829
+ explore: {
765
830
  ...explore,
766
831
  postfix: "",
767
- })(ts.factory.createIdentifier("input")),
768
- ),
832
+ },
833
+ input: ts.factory.createIdentifier("input"),
834
+ }),
769
835
  ),
770
- undefined,
771
- FeatureProgrammer.argumentsArray(config)(explore)(input),
772
- );
773
- };
836
+ ),
837
+ undefined,
838
+ FeatureProgrammer.argumentsArray(props.config)(explore)(props.input),
839
+ );
840
+ };
774
841
 
775
842
  /* -----------------------------------------------------------
776
843
  RETURN SCRIPTS
777
844
  ----------------------------------------------------------- */
778
- const wrap_required = (
779
- input: ts.Expression,
780
- meta: Metadata,
781
- explore: FeatureProgrammer.IExplore,
782
- ): ((expression: ts.Expression) => ts.Expression) => {
783
- if (meta.isRequired() === true && meta.any === false)
784
- return (expression) => expression;
785
- return (expression) =>
786
- ts.factory.createConditionalExpression(
787
- ts.factory.createStrictInequality(
788
- ts.factory.createIdentifier("undefined"),
789
- input,
790
- ),
791
- undefined,
792
- expression,
793
- undefined,
794
- explore.from === "array"
795
- ? ts.factory.createStringLiteral("null")
796
- : ts.factory.createIdentifier("undefined"),
797
- );
845
+ const wrap_required = (props: {
846
+ input: ts.Expression;
847
+ metadata: Metadata;
848
+ explore: FeatureProgrammer.IExplore;
849
+ expression: ts.Expression;
850
+ }): ts.Expression => {
851
+ if (props.metadata.isRequired() === true && props.metadata.any === false)
852
+ return props.expression;
853
+ return ts.factory.createConditionalExpression(
854
+ ts.factory.createStrictInequality(
855
+ ts.factory.createIdentifier("undefined"),
856
+ props.input,
857
+ ),
858
+ undefined,
859
+ props.expression,
860
+ undefined,
861
+ props.explore.from === "array"
862
+ ? ts.factory.createStringLiteral("null")
863
+ : ts.factory.createIdentifier("undefined"),
864
+ );
798
865
  };
799
866
 
800
- const wrap_nullable = (
801
- input: ts.Expression,
802
- meta: Metadata,
803
- ): ((expression: ts.Expression) => ts.Expression) => {
804
- if (meta.nullable === false) return (expression) => expression;
805
- return (expression) =>
806
- ts.factory.createConditionalExpression(
807
- ts.factory.createStrictInequality(ts.factory.createNull(), input),
808
- undefined,
809
- expression,
810
- undefined,
811
- ts.factory.createStringLiteral("null"),
812
- );
867
+ const wrap_nullable = (props: {
868
+ input: ts.Expression;
869
+ metadata: Metadata;
870
+ expression: ts.Expression;
871
+ }): ts.Expression => {
872
+ if (props.metadata.nullable === false) return props.expression;
873
+ return ts.factory.createConditionalExpression(
874
+ ts.factory.createStrictInequality(ts.factory.createNull(), props.input),
875
+ undefined,
876
+ props.expression,
877
+ undefined,
878
+ ts.factory.createStringLiteral("null"),
879
+ );
813
880
  };
814
881
 
815
882
  const wrap_functional = (props: {
@@ -855,52 +922,93 @@ export namespace JsonStringifyProgrammer {
855
922
  ----------------------------------------------------------- */
856
923
  const PREFIX = "$s";
857
924
 
858
- const configure =
859
- (project: ITypiaContext) =>
860
- (importer: FunctionImporter): FeatureProgrammer.IConfig => {
861
- const config: FeatureProgrammer.IConfig<ts.Expression> = {
862
- types: {
863
- input: (type, name) =>
864
- ts.factory.createTypeReferenceNode(
865
- name ?? TypeFactory.getFullName(project.checker)(type),
866
- ),
867
- output: () => TypeFactory.keyword("string"),
868
- },
869
- prefix: PREFIX,
870
- trace: false,
871
- path: false,
872
- initializer,
873
- decoder: () => decode(project)(config)(importer),
874
- objector: {
875
- checker: () => IsProgrammer.decode(project)(importer),
876
- decoder: () => decode_object(importer),
877
- joiner: (props) =>
878
- StringifyJoiner.object({
879
- ...props,
880
- importer,
881
- }),
882
- unionizer: decode_union_object(
883
- IsProgrammer.decode_object(project)(importer),
884
- )(decode_object(importer))((exp) => exp)((input, expected) =>
885
- create_throw_error({ importer, expected, input }),
925
+ const configure = (props: {
926
+ context: ITypiaContext;
927
+ importer: FunctionImporter;
928
+ }): FeatureProgrammer.IConfig => {
929
+ const config: FeatureProgrammer.IConfig<ts.Expression> = {
930
+ types: {
931
+ input: (type, name) =>
932
+ ts.factory.createTypeReferenceNode(
933
+ name ?? TypeFactory.getFullName(props.context.checker)(type),
886
934
  ),
887
- failure: (input, expected) =>
888
- create_throw_error({ importer, expected, input }),
889
- },
890
- generator: {
891
- arrays: () => write_array_functions(config)(importer),
892
- tuples: () => write_tuple_functions(project)(config)(importer),
893
- },
894
- };
895
- return config;
935
+ output: () => TypeFactory.keyword("string"),
936
+ },
937
+ prefix: PREFIX,
938
+ trace: false,
939
+ path: false,
940
+ initializer,
941
+ decoder: () => (input, metadata, explore) =>
942
+ decode({
943
+ config,
944
+ context: props.context,
945
+ importer: props.importer,
946
+ input,
947
+ metadata,
948
+ explore,
949
+ }),
950
+ objector: {
951
+ checker: () => IsProgrammer.decode(props.context)(props.importer),
952
+ decoder: () => (input, object, explore) =>
953
+ decode_object({
954
+ importer: props.importer,
955
+ input,
956
+ object,
957
+ explore,
958
+ }),
959
+ joiner: (next) =>
960
+ StringifyJoiner.object({
961
+ ...next,
962
+ importer: props.importer,
963
+ }),
964
+ unionizer: decode_union_object(
965
+ IsProgrammer.decode_object(props.context)(props.importer),
966
+ )((input, object, explore) =>
967
+ decode_object({
968
+ importer: props.importer,
969
+ input,
970
+ object,
971
+ explore,
972
+ }),
973
+ )((exp) => exp)((input, expected) =>
974
+ create_throw_error({
975
+ importer: props.importer,
976
+ expected,
977
+ input,
978
+ }),
979
+ ),
980
+ failure: (input, expected) =>
981
+ create_throw_error({
982
+ importer: props.importer,
983
+ expected,
984
+ input,
985
+ }),
986
+ },
987
+ generator: {
988
+ arrays: () => (collection) =>
989
+ write_array_functions({
990
+ config,
991
+ importer: props.importer,
992
+ collection,
993
+ }),
994
+ tuples: () => (collection) =>
995
+ write_tuple_functions({
996
+ config,
997
+ context: props.context,
998
+ importer: props.importer,
999
+ collection,
1000
+ }),
1001
+ },
896
1002
  };
1003
+ return config;
1004
+ };
897
1005
 
898
1006
  const initializer: FeatureProgrammer.IConfig["initializer"] =
899
- (project) => (importer) => (type) =>
1007
+ (context) => (importer) => (type) =>
900
1008
  JsonMetadataFactory.analyze({
901
1009
  method: `typia.json.${importer.method}`,
902
- checker: project.checker,
903
- transformer: project.transformer,
1010
+ checker: context.checker,
1011
+ transformer: context.transformer,
904
1012
  type,
905
1013
  });
906
1014