typia 9.7.2 → 10.0.0-dev.20251107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +153 -153
  3. package/lib/factories/ProtobufFactory.js +1 -1
  4. package/lib/factories/ProtobufFactory.mjs +1 -1
  5. package/lib/programmers/internal/json_schema_station.d.mts +2 -2
  6. package/lib/programmers/internal/json_schema_station.d.ts +2 -2
  7. package/lib/programmers/llm/LlmApplicationProgrammer.js +5 -1
  8. package/lib/programmers/llm/LlmApplicationProgrammer.js.map +1 -1
  9. package/lib/programmers/llm/LlmApplicationProgrammer.mjs +5 -1
  10. package/lib/programmers/llm/LlmSchemaProgrammer.js +1 -4
  11. package/lib/programmers/llm/LlmSchemaProgrammer.js.map +1 -1
  12. package/lib/programmers/llm/LlmSchemaProgrammer.mjs +1 -35
  13. package/package.json +121 -121
  14. package/src/AssertionGuard.ts +41 -41
  15. package/src/CamelCase.ts +75 -75
  16. package/src/IRandomGenerator.ts +337 -337
  17. package/src/IReadableURLSearchParams.ts +9 -9
  18. package/src/PascalCase.ts +71 -71
  19. package/src/Primitive.ts +90 -90
  20. package/src/Resolved.ts +72 -72
  21. package/src/SnakeCase.ts +127 -127
  22. package/src/TypeGuardError.ts +216 -216
  23. package/src/factories/MetadataCollection.ts +270 -270
  24. package/src/factories/MetadataCommentTagFactory.ts +632 -632
  25. package/src/factories/MetadataFactory.ts +402 -402
  26. package/src/factories/ProtobufFactory.ts +873 -873
  27. package/src/functional.ts +705 -705
  28. package/src/http.ts +972 -972
  29. package/src/internal/_ProtobufReader.ts +188 -188
  30. package/src/internal/_ProtobufSizer.ts +137 -137
  31. package/src/internal/_ProtobufWriter.ts +135 -135
  32. package/src/internal/_jsonStringifyString.ts +42 -42
  33. package/src/json.ts +643 -643
  34. package/src/llm.ts +615 -615
  35. package/src/misc.ts +594 -594
  36. package/src/module.ts +889 -889
  37. package/src/notations.ts +751 -751
  38. package/src/programmers/FeatureProgrammer.ts +605 -605
  39. package/src/programmers/ImportProgrammer.ts +179 -179
  40. package/src/programmers/RandomProgrammer.ts +1195 -1195
  41. package/src/programmers/helpers/ProtobufWire.ts +34 -34
  42. package/src/programmers/internal/check_array_length.ts +43 -43
  43. package/src/programmers/internal/check_bigint.ts +46 -46
  44. package/src/programmers/internal/check_dynamic_key.ts +197 -197
  45. package/src/programmers/internal/check_dynamic_properties.ts +231 -231
  46. package/src/programmers/internal/check_everything.ts +21 -21
  47. package/src/programmers/internal/check_native.ts +23 -23
  48. package/src/programmers/internal/check_number.ts +108 -108
  49. package/src/programmers/internal/check_object.ts +72 -72
  50. package/src/programmers/internal/check_string.ts +46 -46
  51. package/src/programmers/internal/check_template.ts +46 -46
  52. package/src/programmers/internal/check_union_array_like.ts +331 -331
  53. package/src/programmers/internal/decode_union_object.ts +110 -110
  54. package/src/programmers/internal/feature_object_entries.ts +59 -59
  55. package/src/programmers/internal/json_schema_escaped.ts +78 -78
  56. package/src/programmers/internal/json_schema_object.ts +150 -150
  57. package/src/programmers/internal/json_schema_station.ts +2 -2
  58. package/src/programmers/internal/metadata_to_pattern.ts +40 -40
  59. package/src/programmers/internal/postfix_of_tuple.ts +3 -3
  60. package/src/programmers/internal/prune_object_properties.ts +69 -69
  61. package/src/programmers/internal/stringify_dynamic_properties.ts +158 -158
  62. package/src/programmers/internal/stringify_native.ts +5 -5
  63. package/src/programmers/internal/stringify_regular_properties.ts +77 -77
  64. package/src/programmers/internal/template_to_pattern.ts +21 -21
  65. package/src/programmers/internal/wrap_metadata_rest_tuple.ts +21 -21
  66. package/src/programmers/json/JsonStringifyProgrammer.ts +1124 -1124
  67. package/src/programmers/llm/LlmApplicationProgrammer.ts +10 -1
  68. package/src/programmers/llm/LlmSchemaProgrammer.ts +2 -7
  69. package/src/protobuf.ts +820 -820
  70. package/src/reflect.ts +46 -46
  71. package/src/schemas/json/IJsonApplication.ts +77 -77
  72. package/src/schemas/json/IJsonSchemaCollection.ts +212 -212
  73. package/src/schemas/json/IJsonSchemaUnit.ts +263 -263
  74. package/src/schemas/metadata/IMetadataTypeTag.ts +14 -14
  75. package/src/schemas/metadata/Metadata.ts +669 -669
  76. package/src/schemas/metadata/MetadataAliasType.ts +57 -57
  77. package/src/schemas/metadata/MetadataApplication.ts +40 -40
  78. package/src/schemas/metadata/MetadataArray.ts +47 -47
  79. package/src/schemas/metadata/MetadataArrayType.ts +51 -51
  80. package/src/schemas/metadata/MetadataAtomic.ts +85 -85
  81. package/src/schemas/metadata/MetadataEscaped.ts +45 -45
  82. package/src/schemas/metadata/MetadataFunction.ts +45 -45
  83. package/src/schemas/metadata/MetadataObject.ts +46 -46
  84. package/src/schemas/metadata/MetadataObjectType.ts +137 -137
  85. package/src/schemas/metadata/MetadataParameter.ts +52 -52
  86. package/src/schemas/metadata/MetadataProperty.ts +53 -53
  87. package/src/schemas/metadata/MetadataTemplate.ts +78 -78
  88. package/src/schemas/metadata/MetadataTuple.ts +28 -28
  89. package/src/schemas/metadata/MetadataTupleType.ts +61 -61
  90. package/src/tags/Constant.ts +47 -47
  91. package/src/tags/ContentMediaType.ts +27 -27
  92. package/src/tags/Default.ts +52 -52
  93. package/src/tags/Example.ts +56 -56
  94. package/src/tags/Examples.ts +56 -56
  95. package/src/tags/ExclusiveMaximum.ts +44 -44
  96. package/src/tags/ExclusiveMinimum.ts +44 -44
  97. package/src/tags/Format.ts +78 -78
  98. package/src/tags/JsonSchemaPlugin.ts +36 -36
  99. package/src/tags/MaxItems.ts +31 -31
  100. package/src/tags/MaxLength.ts +25 -25
  101. package/src/tags/Maximum.ts +39 -39
  102. package/src/tags/MinItems.ts +31 -31
  103. package/src/tags/MinLength.ts +25 -25
  104. package/src/tags/Minimum.ts +39 -39
  105. package/src/tags/MultipleOf.ts +42 -42
  106. package/src/tags/Pattern.ts +49 -49
  107. package/src/tags/Sequence.ts +37 -37
  108. package/src/tags/TagBase.ts +102 -102
  109. package/src/tags/Type.ts +64 -64
  110. package/src/tags/UniqueItems.ts +34 -34
  111. package/src/tags/internal/FormatCheatSheet.ts +71 -71
  112. package/src/transformers/ITransformOptions.ts +70 -70
  113. package/src/transformers/ImportTransformer.ts +253 -253
  114. package/src/transformers/NoTransformConfigurationError.ts +16 -16
  115. package/src/transformers/features/llm/LlmApplicationTransformer.ts +224 -224
  116. package/src/typings/Equal.ts +18 -18
@@ -1,1195 +1,1195 @@
1
- import { OpenApi } from "@samchon/openapi";
2
- import ts from "typescript";
3
-
4
- import { ExpressionFactory } from "../factories/ExpressionFactory";
5
- import { IdentifierFactory } from "../factories/IdentifierFactory";
6
- import { LiteralFactory } from "../factories/LiteralFactory";
7
- import { MetadataCollection } from "../factories/MetadataCollection";
8
- import { MetadataCommentTagFactory } from "../factories/MetadataCommentTagFactory";
9
- import { MetadataFactory } from "../factories/MetadataFactory";
10
- import { StatementFactory } from "../factories/StatementFactory";
11
- import { TemplateFactory } from "../factories/TemplateFactory";
12
- import { TypeFactory } from "../factories/TypeFactory";
13
-
14
- import { Metadata } from "../schemas/metadata/Metadata";
15
- import { MetadataArray } from "../schemas/metadata/MetadataArray";
16
- import { MetadataArrayType } from "../schemas/metadata/MetadataArrayType";
17
- import { MetadataAtomic } from "../schemas/metadata/MetadataAtomic";
18
- import { MetadataMap } from "../schemas/metadata/MetadataMap";
19
- import { MetadataObjectType } from "../schemas/metadata/MetadataObjectType";
20
- import { MetadataSet } from "../schemas/metadata/MetadataSet";
21
- import { MetadataTemplate } from "../schemas/metadata/MetadataTemplate";
22
- import { MetadataTuple } from "../schemas/metadata/MetadataTuple";
23
- import { MetadataTupleType } from "../schemas/metadata/MetadataTupleType";
24
-
25
- import { ITypiaContext } from "../transformers/ITypiaContext";
26
- import { TransformerError } from "../transformers/TransformerError";
27
-
28
- import { StringUtil } from "../utils/StringUtil";
29
-
30
- import { FeatureProgrammer } from "./FeatureProgrammer";
31
- import { FunctionProgrammer } from "./helpers/FunctionProgrammer";
32
- import { RandomJoiner } from "./helpers/RandomJoiner";
33
- import { json_schema_array } from "./internal/json_schema_array";
34
- import { json_schema_bigint } from "./internal/json_schema_bigint";
35
- import { json_schema_boolean } from "./internal/json_schema_boolean";
36
- import { json_schema_number } from "./internal/json_schema_number";
37
- import { json_schema_string } from "./internal/json_schema_string";
38
-
39
- export namespace RandomProgrammer {
40
- export interface IProps {
41
- context: ITypiaContext;
42
- modulo: ts.LeftHandSideExpression;
43
- type: ts.Type;
44
- name: string | undefined;
45
- init: ts.Expression | undefined;
46
- }
47
- export interface IDecomposeProps {
48
- context: ITypiaContext;
49
- functor: FunctionProgrammer;
50
- type: ts.Type;
51
- name: string | undefined;
52
- init: ts.Expression | undefined;
53
- }
54
-
55
- export const decompose = (
56
- props: IDecomposeProps,
57
- ): FeatureProgrammer.IDecomposed => {
58
- const collection: MetadataCollection = new MetadataCollection();
59
- const result = MetadataFactory.analyze({
60
- checker: props.context.checker,
61
- transformer: props.context.transformer,
62
- options: {
63
- escape: false,
64
- constant: true,
65
- absorb: true,
66
- validate: (meta) => {
67
- const output: string[] = [];
68
- if (meta.natives.some((native) => native.name === "WeakSet"))
69
- output.push(`WeakSet is not supported.`);
70
- else if (meta.natives.some((native) => native.name === "WeakMap"))
71
- output.push(`WeakMap is not supported.`);
72
- return output;
73
- },
74
- },
75
- collection,
76
- type: props.type,
77
- });
78
- if (result.success === false)
79
- throw TransformerError.from({
80
- code: props.functor.method,
81
- errors: result.errors,
82
- });
83
-
84
- // GENERATE FUNCTION
85
- const functions: Record<string, ts.VariableStatement> = Object.fromEntries([
86
- ...write_object_functions({
87
- context: props.context,
88
- functor: props.functor,
89
- collection,
90
- }).map((v, i) => [Prefix.object(i), v]),
91
- ...write_array_functions({
92
- context: props.context,
93
- functor: props.functor,
94
- collection,
95
- }).map((v, i) => [Prefix.array(i), v]),
96
- ...write_tuple_functions({
97
- context: props.context,
98
- functor: props.functor,
99
- collection,
100
- }).map((v, i) => [Prefix.tuple(i), v]),
101
- ]);
102
- const arrow: ts.ArrowFunction = ts.factory.createArrowFunction(
103
- undefined,
104
- undefined,
105
- [
106
- IdentifierFactory.parameter(
107
- "generator",
108
- ts.factory.createTypeReferenceNode("Partial", [
109
- props.context.importer.type({
110
- file: "typia",
111
- name: "IRandomGenerator",
112
- }),
113
- ]),
114
- props.init ?? ts.factory.createToken(ts.SyntaxKind.QuestionToken),
115
- ),
116
- ],
117
- props.context.importer.type({
118
- file: "typia",
119
- name: "Resolved",
120
- arguments: [
121
- ts.factory.createTypeReferenceNode(
122
- props.name ??
123
- TypeFactory.getFullName({
124
- checker: props.context.checker,
125
- type: props.type,
126
- }),
127
- ),
128
- ],
129
- }),
130
- undefined,
131
- ts.factory.createBlock(
132
- [
133
- ts.factory.createExpressionStatement(
134
- ts.factory.createBinaryExpression(
135
- ts.factory.createIdentifier("_generator"),
136
- ts.SyntaxKind.EqualsToken,
137
- ts.factory.createIdentifier("generator"),
138
- ),
139
- ),
140
- ts.factory.createReturnStatement(
141
- decode({
142
- context: props.context,
143
- functor: props.functor,
144
- explore: {
145
- function: false,
146
- recursive: false,
147
- },
148
- metadata: result.data,
149
- }),
150
- ),
151
- ],
152
- true,
153
- ),
154
- );
155
- return {
156
- functions,
157
- statements: [
158
- StatementFactory.mut({
159
- name: "_generator",
160
- type: ts.factory.createUnionTypeNode([
161
- ts.factory.createTypeReferenceNode("Partial", [
162
- props.context.importer.type({
163
- file: "typia",
164
- name: "IRandomGenerator",
165
- }),
166
- ]),
167
- ts.factory.createTypeReferenceNode("undefined"),
168
- ]),
169
- }),
170
- ],
171
- arrow,
172
- };
173
- };
174
-
175
- export const write = (props: IProps) => {
176
- const functor: FunctionProgrammer = new FunctionProgrammer(
177
- props.modulo.getText(),
178
- );
179
- const result: FeatureProgrammer.IDecomposed = decompose({
180
- ...props,
181
- functor,
182
- });
183
- return FeatureProgrammer.writeDecomposed({
184
- modulo: props.modulo,
185
- functor,
186
- result,
187
- });
188
- };
189
-
190
- const write_object_functions = (props: {
191
- context: ITypiaContext;
192
- functor: FunctionProgrammer;
193
- collection: MetadataCollection;
194
- }): ts.VariableStatement[] =>
195
- props.collection.objects().map((obj, i) =>
196
- StatementFactory.constant({
197
- name: Prefix.object(i),
198
- value: ts.factory.createArrowFunction(
199
- undefined,
200
- undefined,
201
- [
202
- IdentifierFactory.parameter(
203
- "_recursive",
204
- TypeFactory.keyword("boolean"),
205
- ts.factory.createIdentifier(String(obj.recursive)),
206
- ),
207
- IdentifierFactory.parameter(
208
- "_depth",
209
- TypeFactory.keyword("number"),
210
- ExpressionFactory.number(0),
211
- ),
212
- ],
213
- TypeFactory.keyword("any"),
214
- undefined,
215
- RandomJoiner.object({
216
- decode: (metadata) =>
217
- decode({
218
- context: props.context,
219
- functor: props.functor,
220
- explore: {
221
- recursive: obj.recursive,
222
- function: true,
223
- },
224
- metadata,
225
- }),
226
- object: obj,
227
- }),
228
- ),
229
- }),
230
- );
231
-
232
- const write_array_functions = (props: {
233
- context: ITypiaContext;
234
- functor: FunctionProgrammer;
235
- collection: MetadataCollection;
236
- }): ts.VariableStatement[] =>
237
- props.collection
238
- .arrays()
239
- .filter((a) => a.recursive)
240
- .map((array, i) =>
241
- StatementFactory.constant({
242
- name: Prefix.array(i),
243
- value: ts.factory.createArrowFunction(
244
- undefined,
245
- undefined,
246
- [
247
- IdentifierFactory.parameter(
248
- "_schema",
249
- TypeFactory.keyword("boolean"),
250
- ),
251
- IdentifierFactory.parameter(
252
- "_recursive",
253
- TypeFactory.keyword("boolean"),
254
- ts.factory.createTrue(),
255
- ),
256
- IdentifierFactory.parameter(
257
- "_depth",
258
- TypeFactory.keyword("number"),
259
- ExpressionFactory.number(0),
260
- ),
261
- ],
262
- TypeFactory.keyword("any"),
263
- undefined,
264
- RandomJoiner.array({
265
- decode: (metadata) =>
266
- decode({
267
- context: props.context,
268
- functor: props.functor,
269
- explore: {
270
- recursive: true,
271
- function: true,
272
- },
273
- metadata,
274
- }),
275
- recursive: true,
276
- expression: coalesce({
277
- context: props.context,
278
- method: "array",
279
- internal: "randomArray",
280
- }),
281
- array,
282
- schema: undefined,
283
- }),
284
- ),
285
- }),
286
- );
287
-
288
- const write_tuple_functions = (props: {
289
- context: ITypiaContext;
290
- functor: FunctionProgrammer;
291
- collection: MetadataCollection;
292
- }): ts.VariableStatement[] =>
293
- props.collection
294
- .tuples()
295
- .filter((a) => a.recursive)
296
- .map((tuple, i) =>
297
- StatementFactory.constant({
298
- name: Prefix.tuple(i),
299
- value: ts.factory.createArrowFunction(
300
- undefined,
301
- undefined,
302
- [
303
- IdentifierFactory.parameter(
304
- "_recursive",
305
- TypeFactory.keyword("boolean"),
306
- ts.factory.createTrue(),
307
- ),
308
- IdentifierFactory.parameter(
309
- "_depth",
310
- TypeFactory.keyword("number"),
311
- ExpressionFactory.number(0),
312
- ),
313
- ],
314
- TypeFactory.keyword("any"),
315
- undefined,
316
- RandomJoiner.tuple({
317
- decode: (metadata) =>
318
- decode({
319
- context: props.context,
320
- functor: props.functor,
321
- explore: {
322
- function: true,
323
- recursive: true,
324
- },
325
- metadata,
326
- }),
327
- elements: tuple.elements,
328
- }),
329
- ),
330
- }),
331
- );
332
-
333
- /* -----------------------------------------------------------
334
- DECODERS
335
- ----------------------------------------------------------- */
336
- const decode = (props: {
337
- context: ITypiaContext;
338
- functor: FunctionProgrammer;
339
- explore: IExplore;
340
- metadata: Metadata;
341
- }): ts.Expression => {
342
- const expressions: ts.Expression[] = [];
343
- if (props.metadata.any === true)
344
- expressions.push(ts.factory.createStringLiteral("any type used..."));
345
-
346
- // NULL COALESCING
347
- if (
348
- props.metadata.isRequired() === false ||
349
- props.metadata.functions.length !== 0
350
- )
351
- expressions.push(ts.factory.createIdentifier("undefined"));
352
- if (props.metadata.nullable === true)
353
- expressions.push(ts.factory.createNull());
354
-
355
- // CONSTANT TYPES
356
- for (const constant of props.metadata.constants)
357
- for (const { value } of constant.values)
358
- expressions.push(
359
- constant.type === "boolean"
360
- ? value === true
361
- ? ts.factory.createTrue()
362
- : ts.factory.createFalse()
363
- : constant.type === "bigint"
364
- ? ExpressionFactory.bigint(value as bigint)
365
- : constant.type === "number"
366
- ? ExpressionFactory.number(value as number)
367
- : ts.factory.createStringLiteral(value as string),
368
- );
369
-
370
- // ATOMIC VARIABLES
371
- for (const template of props.metadata.templates)
372
- expressions.push(
373
- decode_template({
374
- ...props,
375
- template,
376
- }),
377
- );
378
- for (const atomic of props.metadata.atomics)
379
- expressions.push(
380
- ...decode_atomic({
381
- context: props.context,
382
- atomic,
383
- }),
384
- );
385
-
386
- // INSTANCE TYPES
387
- if (props.metadata.escaped)
388
- expressions.push(
389
- decode({
390
- ...props,
391
- metadata: props.metadata.escaped.returns,
392
- }),
393
- );
394
- for (const array of props.metadata.arrays)
395
- expressions.push(
396
- ...decode_array({
397
- ...props,
398
- array,
399
- }),
400
- );
401
- for (const tuple of props.metadata.tuples)
402
- expressions.push(
403
- decode_tuple({
404
- ...props,
405
- tuple,
406
- }),
407
- );
408
- for (const object of props.metadata.objects)
409
- expressions.push(
410
- decode_object({
411
- ...props,
412
- object: object.type,
413
- }),
414
- );
415
- for (const native of props.metadata.natives)
416
- expressions.push(
417
- decode_native({
418
- context: props.context,
419
- functor: props.functor,
420
- explore: props.explore,
421
- name: native.name,
422
- }),
423
- );
424
- for (const set of props.metadata.sets)
425
- expressions.push(
426
- decode_set({
427
- ...props,
428
- set,
429
- }),
430
- );
431
- for (const entry of props.metadata.maps)
432
- expressions.push(
433
- decode_map({
434
- ...props,
435
- map: entry,
436
- }),
437
- );
438
-
439
- // PICK UP A TYPE
440
- if (expressions.length === 1) return expressions[0]!;
441
- return ts.factory.createCallExpression(
442
- ts.factory.createCallExpression(
443
- props.context.importer.internal("randomPick"),
444
- undefined,
445
- [
446
- ts.factory.createArrayLiteralExpression(
447
- expressions.map((expr) =>
448
- ts.factory.createArrowFunction(
449
- undefined,
450
- undefined,
451
- [],
452
- undefined,
453
- undefined,
454
- expr,
455
- ),
456
- ),
457
- true,
458
- ),
459
- ],
460
- ),
461
- undefined,
462
- undefined,
463
- );
464
- };
465
-
466
- const decode_atomic = (props: {
467
- context: ITypiaContext;
468
- atomic: MetadataAtomic;
469
- }) => {
470
- const schemaList: OpenApi.IJsonSchema[] =
471
- props.atomic.type === "boolean"
472
- ? json_schema_boolean(props.atomic)
473
- : props.atomic.type === "string"
474
- ? json_schema_string(props.atomic)
475
- : props.atomic.type === "bigint"
476
- ? json_schema_bigint(props.atomic)
477
- : json_schema_number(props.atomic);
478
- return schemaList.map((schema) => {
479
- interface IComposed {
480
- method: string;
481
- internal: string;
482
- arguments: ts.Expression[];
483
- }
484
- const composed = ((): IComposed => {
485
- if (props.atomic.type === "string") {
486
- const string: OpenApi.IJsonSchema.IString =
487
- schema as OpenApi.IJsonSchema.IString;
488
- if (string.format !== undefined) {
489
- const format: string = string.format!;
490
- if (format === "date-time")
491
- return {
492
- method: "datetime",
493
- internal: "randomFormatDatetime",
494
- arguments: [],
495
- };
496
- return {
497
- method: format
498
- .split("-")
499
- .map((s, i) => (i === 0 ? s : StringUtil.capitalize(s)))
500
- .join(""),
501
- internal: `randomFormat${format
502
- .split("-")
503
- .map(StringUtil.capitalize)
504
- .join("")}`,
505
- arguments: [],
506
- };
507
- } else if (string.pattern !== undefined)
508
- return {
509
- method: "pattern",
510
- internal: "randomPattern",
511
- arguments: [
512
- ts.factory.createNewExpression(
513
- ts.factory.createIdentifier("RegExp"),
514
- undefined,
515
- [
516
- ts.factory.createStringLiteral(
517
- (schema as OpenApi.IJsonSchema.IString).pattern!,
518
- ),
519
- ],
520
- ),
521
- ],
522
- };
523
- } else if (props.atomic.type === "number") {
524
- const number:
525
- | OpenApi.IJsonSchema.INumber
526
- | OpenApi.IJsonSchema.IInteger = schema as
527
- | OpenApi.IJsonSchema.INumber
528
- | OpenApi.IJsonSchema.IInteger;
529
- if (number.type === "integer")
530
- return {
531
- method: "integer",
532
- internal: "randomInteger",
533
- arguments: [LiteralFactory.write(schema)],
534
- };
535
- } else if (props.atomic.type === "boolean")
536
- return {
537
- method: props.atomic.type,
538
- internal: "randomBoolean",
539
- arguments: [],
540
- };
541
- return {
542
- method: props.atomic.type,
543
- internal: `random${StringUtil.capitalize(props.atomic.type)}`,
544
- arguments: [LiteralFactory.write(schema)],
545
- };
546
- })();
547
- return ts.factory.createCallExpression(
548
- ExpressionFactory.coalesce(
549
- ts.factory.createPropertyAccessChain(
550
- ts.factory.createIdentifier("_generator"),
551
- ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
552
- ts.factory.createIdentifier(composed.method),
553
- ),
554
- props.context.importer.internal(composed.internal),
555
- ),
556
- undefined,
557
- composed.arguments,
558
- );
559
- });
560
- };
561
-
562
- const decode_template = (props: {
563
- context: ITypiaContext;
564
- functor: FunctionProgrammer;
565
- explore: IExplore;
566
- template: MetadataTemplate;
567
- }) =>
568
- TemplateFactory.generate(
569
- props.template.row.map((metadata) =>
570
- decode({
571
- ...props,
572
- metadata,
573
- }),
574
- ),
575
- );
576
-
577
- const decode_array = (props: {
578
- context: ITypiaContext;
579
- functor: FunctionProgrammer;
580
- explore: IExplore;
581
- array: MetadataArray;
582
- }): ts.Expression[] => {
583
- const components: OpenApi.IComponents = {};
584
- const schemaList: OpenApi.IJsonSchema.IArray[] = json_schema_array({
585
- components,
586
- array: props.array,
587
- }) as OpenApi.IJsonSchema.IArray[];
588
- if (props.array.type.recursive)
589
- return schemaList.map((schema) =>
590
- ts.factory.createCallExpression(
591
- ts.factory.createIdentifier(
592
- props.functor.useLocal(Prefix.array(props.array.type.index!)),
593
- ),
594
- undefined,
595
- [
596
- ts.factory.createObjectLiteralExpression(
597
- Object.entries(schema)
598
- .filter(([key]) => key !== "items")
599
- .map(([key, value]) =>
600
- ts.factory.createPropertyAssignment(
601
- key,
602
- LiteralFactory.write(value),
603
- ),
604
- ),
605
- true,
606
- ),
607
- ],
608
- ),
609
- );
610
- return schemaList.map((schema) =>
611
- RandomJoiner.array({
612
- decode: (metadata) =>
613
- decode({
614
- ...props,
615
- metadata,
616
- }),
617
- expression: coalesce({
618
- context: props.context,
619
- method: "array",
620
- internal: "randomArray",
621
- }),
622
- array: props.array.type,
623
- recursive: props.explore.recursive,
624
- schema,
625
- }),
626
- );
627
- };
628
-
629
- const decode_tuple = (props: {
630
- context: ITypiaContext;
631
- functor: FunctionProgrammer;
632
- explore: IExplore;
633
- tuple: MetadataTuple;
634
- }): ts.Expression =>
635
- props.tuple.type.recursive
636
- ? ts.factory.createCallExpression(
637
- ts.factory.createIdentifier(
638
- props.functor.useLocal(Prefix.tuple(props.tuple.type.index!)),
639
- ),
640
- undefined,
641
- [
642
- ts.factory.createTrue(),
643
- props.explore.recursive
644
- ? ts.factory.createAdd(
645
- ExpressionFactory.number(1),
646
- ts.factory.createIdentifier("_depth"),
647
- )
648
- : ExpressionFactory.number(0),
649
- ],
650
- )
651
- : RandomJoiner.tuple({
652
- decode: (metadata) =>
653
- decode({
654
- ...props,
655
- metadata,
656
- }),
657
- elements: props.tuple.type.elements,
658
- });
659
-
660
- const decode_object = (props: {
661
- functor: FunctionProgrammer;
662
- explore: IExplore;
663
- object: MetadataObjectType;
664
- }) =>
665
- ts.factory.createCallExpression(
666
- ts.factory.createIdentifier(
667
- props.functor.useLocal(Prefix.object(props.object.index)),
668
- ),
669
- undefined,
670
- props.explore.function
671
- ? [
672
- props.explore.recursive
673
- ? ts.factory.createTrue()
674
- : ts.factory.createIdentifier("_recursive"),
675
- ts.factory.createConditionalExpression(
676
- ts.factory.createIdentifier("_recursive"),
677
- undefined,
678
- ts.factory.createAdd(
679
- ExpressionFactory.number(1),
680
- ts.factory.createIdentifier("_depth"),
681
- ),
682
- undefined,
683
- ts.factory.createIdentifier("_depth"),
684
- ),
685
- ]
686
- : undefined,
687
- );
688
-
689
- /* -----------------------------------------------------------
690
- NATIVE CLASSES
691
- ----------------------------------------------------------- */
692
- const decode_set = (props: {
693
- context: ITypiaContext;
694
- functor: FunctionProgrammer;
695
- explore: IExplore;
696
- set: MetadataSet;
697
- }) =>
698
- ts.factory.createNewExpression(
699
- ts.factory.createIdentifier("Set"),
700
- undefined,
701
- [
702
- decode_array({
703
- ...props,
704
- array: MetadataArray.create({
705
- tags: [],
706
- type: MetadataArrayType.create({
707
- value: props.set.value,
708
- recursive: false,
709
- index: null,
710
- nullables: [],
711
- name: props.set.getName(),
712
- }),
713
- }),
714
- })[0]!,
715
- ],
716
- );
717
-
718
- const decode_map = (props: {
719
- context: ITypiaContext;
720
- functor: FunctionProgrammer;
721
- explore: IExplore;
722
- map: MetadataMap;
723
- }) =>
724
- ts.factory.createNewExpression(
725
- ts.factory.createIdentifier("Map"),
726
- undefined,
727
- [
728
- decode_array({
729
- ...props,
730
- array: MetadataArray.create({
731
- tags: [],
732
- type: MetadataArrayType.create({
733
- name: props.map.getName(),
734
- index: null,
735
- recursive: false,
736
- nullables: [],
737
- value: Metadata.create({
738
- ...Metadata.initialize(),
739
- tuples: [
740
- (() => {
741
- const type = MetadataTupleType.create({
742
- name: `[${props.map.key.getName()}, ${props.map.value.getName()}]`,
743
- index: null,
744
- recursive: false,
745
- nullables: [],
746
- elements: [props.map.key, props.map.value],
747
- });
748
- type.of_map = true;
749
- return MetadataTuple.create({
750
- type,
751
- tags: [],
752
- });
753
- })(),
754
- ],
755
- }),
756
- }),
757
- }),
758
- })[0]!,
759
- ],
760
- );
761
-
762
- const decode_native = (props: {
763
- context: ITypiaContext;
764
- functor: FunctionProgrammer;
765
- explore: IExplore;
766
- name: string;
767
- }): ts.Expression => {
768
- if (
769
- props.name === "Boolean" ||
770
- props.name === "Number" ||
771
- props.name === "BigInt" ||
772
- props.name === "String"
773
- )
774
- return decode_atomic({
775
- context: props.context,
776
- atomic: MetadataAtomic.create({
777
- type: props.name.toLowerCase() as "string",
778
- tags: [],
779
- }),
780
- })[0]!;
781
- else if (props.name === "Date") return decode_native_date(props.context);
782
- else if (
783
- props.name === "Uint8Array" ||
784
- props.name === "Uint8ClampedArray" ||
785
- props.name === "Uint16Array" ||
786
- props.name === "Uint32Array" ||
787
- props.name === "BigUint64Array" ||
788
- props.name === "Int8Array" ||
789
- props.name === "Int16Array" ||
790
- props.name === "Int32Array" ||
791
- props.name === "BigInt64Array" ||
792
- props.name === "Float32Array" ||
793
- props.name === "Float64Array"
794
- )
795
- return decode_native_byte_array({
796
- ...props,
797
- name: props.name,
798
- });
799
- else if (props.name === "ArrayBuffer" || props.name === "SharedArrayBuffer")
800
- return decode_native_array_buffer({
801
- ...props,
802
- name: props.name,
803
- });
804
- else if (props.name === "DataView") return decode_native_data_view(props);
805
- else if (props.name === "Blob") return decode_native_blob(props);
806
- else if (props.name === "File") return decode_native_file(props);
807
- else if (props.name === "RegExp") return decode_regexp(props.context);
808
- else
809
- return ts.factory.createNewExpression(
810
- ts.factory.createIdentifier(props.name),
811
- undefined,
812
- [],
813
- );
814
- };
815
-
816
- const decode_native_date = (context: ITypiaContext) =>
817
- ts.factory.createNewExpression(
818
- ts.factory.createIdentifier("Date"),
819
- undefined,
820
- [
821
- ts.factory.createCallExpression(
822
- coalesce({
823
- context,
824
- method: "datetime",
825
- internal: "randomFormatDatetime",
826
- }),
827
- undefined,
828
- [],
829
- ),
830
- ],
831
- );
832
-
833
- const decode_native_byte_array = (props: {
834
- context: ITypiaContext;
835
- functor: FunctionProgrammer;
836
- explore: IExplore;
837
- name:
838
- | "Uint8Array"
839
- | "Uint8ClampedArray"
840
- | "Uint16Array"
841
- | "Uint32Array"
842
- | "BigUint64Array"
843
- | "Int8Array"
844
- | "Int16Array"
845
- | "Int32Array"
846
- | "BigInt64Array"
847
- | "Float32Array"
848
- | "Float64Array";
849
- }): ts.Expression => {
850
- new BigInt64Array();
851
- const [type, minimum, maximum]: [string, number, number] = (() => {
852
- if (props.name === "Uint8Array" || props.name === "Uint8ClampedArray")
853
- return ["uint32", 0, 255];
854
- else if (props.name === "Uint16Array") return ["uint32", 0, 65535];
855
- else if (props.name === "Uint32Array") return ["uint32", 0, 4294967295];
856
- else if (props.name === "BigUint64Array")
857
- return ["uint64", 0, 18446744073709551615];
858
- else if (props.name === "Int8Array") return ["int32", -128, 127];
859
- else if (props.name === "Int16Array") return ["int32", -32768, 32767];
860
- else if (props.name === "Int32Array")
861
- return ["int32", -2147483648, 2147483647];
862
- else if (props.name === "BigInt64Array")
863
- return ["uint64", -9223372036854775808, 9223372036854775807];
864
- else if (props.name === "Float32Array")
865
- return ["float", -1.175494351e38, 3.4028235e38];
866
- return ["double", Number.MIN_VALUE, Number.MAX_VALUE];
867
- })();
868
- const atomic: "bigint" | "number" =
869
- props.name === "BigInt64Array" || props.name === "BigUint64Array"
870
- ? "bigint"
871
- : "number";
872
- const value: Metadata = Metadata.create({
873
- ...Metadata.initialize(),
874
- atomics: [
875
- MetadataAtomic.create({
876
- type: atomic,
877
- tags: [
878
- [
879
- ...MetadataCommentTagFactory.get({
880
- kind: "type",
881
- type: atomic,
882
- value: type,
883
- }),
884
- ...MetadataCommentTagFactory.get({
885
- kind: "minimum",
886
- type: "number",
887
- value: minimum.toString(),
888
- }),
889
- ...MetadataCommentTagFactory.get({
890
- kind: "maximum",
891
- type: "number",
892
- value: maximum.toString(),
893
- }),
894
- ],
895
- ],
896
- }),
897
- ],
898
- });
899
- return ts.factory.createNewExpression(
900
- ts.factory.createIdentifier(props.name),
901
- [],
902
- decode_array({
903
- context: props.context,
904
- functor: props.functor,
905
- explore: props.explore,
906
- array: MetadataArray.create({
907
- tags: [],
908
- type: MetadataArrayType.create({
909
- name: `${props.name}<${atomic}>`,
910
- value,
911
- recursive: false,
912
- index: null,
913
- nullables: [],
914
- }),
915
- }),
916
- }),
917
- );
918
- };
919
-
920
- const decode_native_blob = (props: {
921
- context: ITypiaContext;
922
- functor: FunctionProgrammer;
923
- explore: IExplore;
924
- }) =>
925
- ts.factory.createNewExpression(
926
- ts.factory.createIdentifier("Blob"),
927
- undefined,
928
- [
929
- ts.factory.createArrayLiteralExpression(
930
- [
931
- decode_native_byte_array({
932
- context: props.context,
933
- functor: props.functor,
934
- explore: props.explore,
935
- name: "Uint8Array",
936
- }),
937
- ],
938
- true,
939
- ),
940
- ],
941
- );
942
-
943
- const decode_native_file = (props: {
944
- context: ITypiaContext;
945
- functor: FunctionProgrammer;
946
- explore: IExplore;
947
- }) =>
948
- ts.factory.createNewExpression(
949
- ts.factory.createIdentifier("File"),
950
- undefined,
951
- [
952
- ts.factory.createArrayLiteralExpression(
953
- [
954
- decode_native_byte_array({
955
- context: props.context,
956
- functor: props.functor,
957
- explore: props.explore,
958
- name: "Uint8Array",
959
- }),
960
- ],
961
- true,
962
- ),
963
- ts.factory.createTemplateExpression(ts.factory.createTemplateHead(""), [
964
- ts.factory.createTemplateSpan(
965
- writeRangedString({
966
- context: props.context,
967
- minLength: 1,
968
- maxLength: 8,
969
- }),
970
- ts.factory.createTemplateMiddle("."),
971
- ),
972
- ts.factory.createTemplateSpan(
973
- writeRangedString({
974
- context: props.context,
975
- minLength: 3,
976
- maxLength: 3,
977
- }),
978
- ts.factory.createTemplateTail(""),
979
- ),
980
- ]),
981
- ],
982
- );
983
-
984
- const decode_native_array_buffer = (props: {
985
- context: ITypiaContext;
986
- functor: FunctionProgrammer;
987
- explore: IExplore;
988
- name: "ArrayBuffer" | "SharedArrayBuffer";
989
- }): ts.Expression =>
990
- props.name === "ArrayBuffer"
991
- ? IdentifierFactory.access(
992
- decode_native_byte_array({
993
- context: props.context,
994
- functor: props.functor,
995
- explore: props.explore,
996
- name: "Uint8Array",
997
- }),
998
- "buffer",
999
- )
1000
- : ExpressionFactory.selfCall(
1001
- ts.factory.createBlock(
1002
- [
1003
- StatementFactory.constant({
1004
- name: "length",
1005
- value: decode_atomic({
1006
- context: props.context,
1007
- atomic: MetadataAtomic.create({
1008
- type: "number",
1009
- tags: [
1010
- MetadataCommentTagFactory.get({
1011
- type: "number",
1012
- kind: "type",
1013
- value: "uint32",
1014
- }),
1015
- ],
1016
- }),
1017
- })[0]!,
1018
- }),
1019
- StatementFactory.constant({
1020
- name: "buffer",
1021
- value: ts.factory.createNewExpression(
1022
- ts.factory.createIdentifier("SharedArrayBuffer"),
1023
- [],
1024
- [ts.factory.createIdentifier("length")],
1025
- ),
1026
- }),
1027
- StatementFactory.constant({
1028
- name: "bytes",
1029
- value: ts.factory.createNewExpression(
1030
- ts.factory.createIdentifier("Uint8Array"),
1031
- [],
1032
- [ts.factory.createIdentifier("buffer")],
1033
- ),
1034
- }),
1035
- ts.factory.createExpressionStatement(
1036
- ts.factory.createCallExpression(
1037
- IdentifierFactory.access(
1038
- ts.factory.createIdentifier("bytes"),
1039
- "set",
1040
- ),
1041
- undefined,
1042
- [
1043
- ts.factory.createCallExpression(
1044
- ts.factory.createPropertyAccessExpression(
1045
- ts.factory.createCallExpression(
1046
- ts.factory.createPropertyAccessExpression(
1047
- ts.factory.createNewExpression(
1048
- ts.factory.createIdentifier("Array"),
1049
- undefined,
1050
- [ts.factory.createIdentifier("length")],
1051
- ),
1052
- ts.factory.createIdentifier("fill"),
1053
- ),
1054
- undefined,
1055
- [ts.factory.createNumericLiteral("0")],
1056
- ),
1057
- ts.factory.createIdentifier("map"),
1058
- ),
1059
- undefined,
1060
- [
1061
- ts.factory.createArrowFunction(
1062
- undefined,
1063
- undefined,
1064
- [],
1065
- undefined,
1066
- undefined,
1067
- decode_atomic({
1068
- context: props.context,
1069
- atomic: MetadataAtomic.create({
1070
- type: "number",
1071
- tags: [
1072
- [
1073
- ...MetadataCommentTagFactory.get({
1074
- kind: "type",
1075
- type: "number",
1076
- value: "uint32",
1077
- }),
1078
- ...MetadataCommentTagFactory.get({
1079
- kind: "minimum",
1080
- type: "number",
1081
- value: "0",
1082
- }),
1083
- ...MetadataCommentTagFactory.get({
1084
- kind: "maximum",
1085
- type: "number",
1086
- value: "255",
1087
- }),
1088
- ],
1089
- ],
1090
- }),
1091
- })[0]!,
1092
- ),
1093
- ],
1094
- ),
1095
- ExpressionFactory.number(0),
1096
- ],
1097
- ),
1098
- ),
1099
- ts.factory.createReturnStatement(
1100
- ts.factory.createIdentifier("buffer"),
1101
- ),
1102
- ],
1103
- true,
1104
- ),
1105
- );
1106
-
1107
- const decode_native_data_view = (props: {
1108
- context: ITypiaContext;
1109
- functor: FunctionProgrammer;
1110
- explore: IExplore;
1111
- }) =>
1112
- ts.factory.createNewExpression(
1113
- ts.factory.createIdentifier("DataView"),
1114
- [],
1115
- [
1116
- IdentifierFactory.access(
1117
- decode_native_byte_array({
1118
- context: props.context,
1119
- functor: props.functor,
1120
- explore: props.explore,
1121
- name: "Uint8Array",
1122
- }),
1123
- "buffer",
1124
- ),
1125
- ],
1126
- );
1127
-
1128
- const decode_regexp = (context: ITypiaContext) =>
1129
- ts.factory.createNewExpression(
1130
- ts.factory.createIdentifier("RegExp"),
1131
- [],
1132
- [
1133
- ts.factory.createCallExpression(
1134
- coalesce({
1135
- context,
1136
- method: "regex",
1137
- internal: "randomFormatRegex",
1138
- }),
1139
- undefined,
1140
- undefined,
1141
- ),
1142
- ],
1143
- );
1144
-
1145
- const writeRangedString = (props: {
1146
- context: ITypiaContext;
1147
- minLength: number;
1148
- maxLength: number;
1149
- }): ts.CallExpression =>
1150
- decode_atomic({
1151
- context: props.context,
1152
- atomic: MetadataAtomic.create({
1153
- type: "string",
1154
- tags: [
1155
- [
1156
- ...MetadataCommentTagFactory.get({
1157
- kind: "minLength",
1158
- type: "string",
1159
- value: props.minLength.toString(),
1160
- }),
1161
- ...MetadataCommentTagFactory.get({
1162
- kind: "maxLength",
1163
- type: "string",
1164
- value: props.maxLength.toString(),
1165
- }),
1166
- ],
1167
- ],
1168
- }),
1169
- })[0]!;
1170
- }
1171
-
1172
- const coalesce = (props: {
1173
- context: ITypiaContext;
1174
- method: string;
1175
- internal: string;
1176
- }): ts.Expression =>
1177
- ExpressionFactory.coalesce(
1178
- ts.factory.createPropertyAccessChain(
1179
- ts.factory.createIdentifier("_generator"),
1180
- ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
1181
- ts.factory.createIdentifier(props.method),
1182
- ),
1183
- props.context.importer.internal(props.internal),
1184
- );
1185
-
1186
- interface IExplore {
1187
- function: boolean;
1188
- recursive: boolean;
1189
- }
1190
-
1191
- const Prefix = {
1192
- object: (i: number) => `_ro${i}`,
1193
- array: (i: number) => `_ra${i}`,
1194
- tuple: (i: number) => `_rt${i}`,
1195
- };
1
+ import { OpenApi } from "@samchon/openapi";
2
+ import ts from "typescript";
3
+
4
+ import { ExpressionFactory } from "../factories/ExpressionFactory";
5
+ import { IdentifierFactory } from "../factories/IdentifierFactory";
6
+ import { LiteralFactory } from "../factories/LiteralFactory";
7
+ import { MetadataCollection } from "../factories/MetadataCollection";
8
+ import { MetadataCommentTagFactory } from "../factories/MetadataCommentTagFactory";
9
+ import { MetadataFactory } from "../factories/MetadataFactory";
10
+ import { StatementFactory } from "../factories/StatementFactory";
11
+ import { TemplateFactory } from "../factories/TemplateFactory";
12
+ import { TypeFactory } from "../factories/TypeFactory";
13
+
14
+ import { Metadata } from "../schemas/metadata/Metadata";
15
+ import { MetadataArray } from "../schemas/metadata/MetadataArray";
16
+ import { MetadataArrayType } from "../schemas/metadata/MetadataArrayType";
17
+ import { MetadataAtomic } from "../schemas/metadata/MetadataAtomic";
18
+ import { MetadataMap } from "../schemas/metadata/MetadataMap";
19
+ import { MetadataObjectType } from "../schemas/metadata/MetadataObjectType";
20
+ import { MetadataSet } from "../schemas/metadata/MetadataSet";
21
+ import { MetadataTemplate } from "../schemas/metadata/MetadataTemplate";
22
+ import { MetadataTuple } from "../schemas/metadata/MetadataTuple";
23
+ import { MetadataTupleType } from "../schemas/metadata/MetadataTupleType";
24
+
25
+ import { ITypiaContext } from "../transformers/ITypiaContext";
26
+ import { TransformerError } from "../transformers/TransformerError";
27
+
28
+ import { StringUtil } from "../utils/StringUtil";
29
+
30
+ import { FeatureProgrammer } from "./FeatureProgrammer";
31
+ import { FunctionProgrammer } from "./helpers/FunctionProgrammer";
32
+ import { RandomJoiner } from "./helpers/RandomJoiner";
33
+ import { json_schema_array } from "./internal/json_schema_array";
34
+ import { json_schema_bigint } from "./internal/json_schema_bigint";
35
+ import { json_schema_boolean } from "./internal/json_schema_boolean";
36
+ import { json_schema_number } from "./internal/json_schema_number";
37
+ import { json_schema_string } from "./internal/json_schema_string";
38
+
39
+ export namespace RandomProgrammer {
40
+ export interface IProps {
41
+ context: ITypiaContext;
42
+ modulo: ts.LeftHandSideExpression;
43
+ type: ts.Type;
44
+ name: string | undefined;
45
+ init: ts.Expression | undefined;
46
+ }
47
+ export interface IDecomposeProps {
48
+ context: ITypiaContext;
49
+ functor: FunctionProgrammer;
50
+ type: ts.Type;
51
+ name: string | undefined;
52
+ init: ts.Expression | undefined;
53
+ }
54
+
55
+ export const decompose = (
56
+ props: IDecomposeProps,
57
+ ): FeatureProgrammer.IDecomposed => {
58
+ const collection: MetadataCollection = new MetadataCollection();
59
+ const result = MetadataFactory.analyze({
60
+ checker: props.context.checker,
61
+ transformer: props.context.transformer,
62
+ options: {
63
+ escape: false,
64
+ constant: true,
65
+ absorb: true,
66
+ validate: (meta) => {
67
+ const output: string[] = [];
68
+ if (meta.natives.some((native) => native.name === "WeakSet"))
69
+ output.push(`WeakSet is not supported.`);
70
+ else if (meta.natives.some((native) => native.name === "WeakMap"))
71
+ output.push(`WeakMap is not supported.`);
72
+ return output;
73
+ },
74
+ },
75
+ collection,
76
+ type: props.type,
77
+ });
78
+ if (result.success === false)
79
+ throw TransformerError.from({
80
+ code: props.functor.method,
81
+ errors: result.errors,
82
+ });
83
+
84
+ // GENERATE FUNCTION
85
+ const functions: Record<string, ts.VariableStatement> = Object.fromEntries([
86
+ ...write_object_functions({
87
+ context: props.context,
88
+ functor: props.functor,
89
+ collection,
90
+ }).map((v, i) => [Prefix.object(i), v]),
91
+ ...write_array_functions({
92
+ context: props.context,
93
+ functor: props.functor,
94
+ collection,
95
+ }).map((v, i) => [Prefix.array(i), v]),
96
+ ...write_tuple_functions({
97
+ context: props.context,
98
+ functor: props.functor,
99
+ collection,
100
+ }).map((v, i) => [Prefix.tuple(i), v]),
101
+ ]);
102
+ const arrow: ts.ArrowFunction = ts.factory.createArrowFunction(
103
+ undefined,
104
+ undefined,
105
+ [
106
+ IdentifierFactory.parameter(
107
+ "generator",
108
+ ts.factory.createTypeReferenceNode("Partial", [
109
+ props.context.importer.type({
110
+ file: "typia",
111
+ name: "IRandomGenerator",
112
+ }),
113
+ ]),
114
+ props.init ?? ts.factory.createToken(ts.SyntaxKind.QuestionToken),
115
+ ),
116
+ ],
117
+ props.context.importer.type({
118
+ file: "typia",
119
+ name: "Resolved",
120
+ arguments: [
121
+ ts.factory.createTypeReferenceNode(
122
+ props.name ??
123
+ TypeFactory.getFullName({
124
+ checker: props.context.checker,
125
+ type: props.type,
126
+ }),
127
+ ),
128
+ ],
129
+ }),
130
+ undefined,
131
+ ts.factory.createBlock(
132
+ [
133
+ ts.factory.createExpressionStatement(
134
+ ts.factory.createBinaryExpression(
135
+ ts.factory.createIdentifier("_generator"),
136
+ ts.SyntaxKind.EqualsToken,
137
+ ts.factory.createIdentifier("generator"),
138
+ ),
139
+ ),
140
+ ts.factory.createReturnStatement(
141
+ decode({
142
+ context: props.context,
143
+ functor: props.functor,
144
+ explore: {
145
+ function: false,
146
+ recursive: false,
147
+ },
148
+ metadata: result.data,
149
+ }),
150
+ ),
151
+ ],
152
+ true,
153
+ ),
154
+ );
155
+ return {
156
+ functions,
157
+ statements: [
158
+ StatementFactory.mut({
159
+ name: "_generator",
160
+ type: ts.factory.createUnionTypeNode([
161
+ ts.factory.createTypeReferenceNode("Partial", [
162
+ props.context.importer.type({
163
+ file: "typia",
164
+ name: "IRandomGenerator",
165
+ }),
166
+ ]),
167
+ ts.factory.createTypeReferenceNode("undefined"),
168
+ ]),
169
+ }),
170
+ ],
171
+ arrow,
172
+ };
173
+ };
174
+
175
+ export const write = (props: IProps) => {
176
+ const functor: FunctionProgrammer = new FunctionProgrammer(
177
+ props.modulo.getText(),
178
+ );
179
+ const result: FeatureProgrammer.IDecomposed = decompose({
180
+ ...props,
181
+ functor,
182
+ });
183
+ return FeatureProgrammer.writeDecomposed({
184
+ modulo: props.modulo,
185
+ functor,
186
+ result,
187
+ });
188
+ };
189
+
190
+ const write_object_functions = (props: {
191
+ context: ITypiaContext;
192
+ functor: FunctionProgrammer;
193
+ collection: MetadataCollection;
194
+ }): ts.VariableStatement[] =>
195
+ props.collection.objects().map((obj, i) =>
196
+ StatementFactory.constant({
197
+ name: Prefix.object(i),
198
+ value: ts.factory.createArrowFunction(
199
+ undefined,
200
+ undefined,
201
+ [
202
+ IdentifierFactory.parameter(
203
+ "_recursive",
204
+ TypeFactory.keyword("boolean"),
205
+ ts.factory.createIdentifier(String(obj.recursive)),
206
+ ),
207
+ IdentifierFactory.parameter(
208
+ "_depth",
209
+ TypeFactory.keyword("number"),
210
+ ExpressionFactory.number(0),
211
+ ),
212
+ ],
213
+ TypeFactory.keyword("any"),
214
+ undefined,
215
+ RandomJoiner.object({
216
+ decode: (metadata) =>
217
+ decode({
218
+ context: props.context,
219
+ functor: props.functor,
220
+ explore: {
221
+ recursive: obj.recursive,
222
+ function: true,
223
+ },
224
+ metadata,
225
+ }),
226
+ object: obj,
227
+ }),
228
+ ),
229
+ }),
230
+ );
231
+
232
+ const write_array_functions = (props: {
233
+ context: ITypiaContext;
234
+ functor: FunctionProgrammer;
235
+ collection: MetadataCollection;
236
+ }): ts.VariableStatement[] =>
237
+ props.collection
238
+ .arrays()
239
+ .filter((a) => a.recursive)
240
+ .map((array, i) =>
241
+ StatementFactory.constant({
242
+ name: Prefix.array(i),
243
+ value: ts.factory.createArrowFunction(
244
+ undefined,
245
+ undefined,
246
+ [
247
+ IdentifierFactory.parameter(
248
+ "_schema",
249
+ TypeFactory.keyword("boolean"),
250
+ ),
251
+ IdentifierFactory.parameter(
252
+ "_recursive",
253
+ TypeFactory.keyword("boolean"),
254
+ ts.factory.createTrue(),
255
+ ),
256
+ IdentifierFactory.parameter(
257
+ "_depth",
258
+ TypeFactory.keyword("number"),
259
+ ExpressionFactory.number(0),
260
+ ),
261
+ ],
262
+ TypeFactory.keyword("any"),
263
+ undefined,
264
+ RandomJoiner.array({
265
+ decode: (metadata) =>
266
+ decode({
267
+ context: props.context,
268
+ functor: props.functor,
269
+ explore: {
270
+ recursive: true,
271
+ function: true,
272
+ },
273
+ metadata,
274
+ }),
275
+ recursive: true,
276
+ expression: coalesce({
277
+ context: props.context,
278
+ method: "array",
279
+ internal: "randomArray",
280
+ }),
281
+ array,
282
+ schema: undefined,
283
+ }),
284
+ ),
285
+ }),
286
+ );
287
+
288
+ const write_tuple_functions = (props: {
289
+ context: ITypiaContext;
290
+ functor: FunctionProgrammer;
291
+ collection: MetadataCollection;
292
+ }): ts.VariableStatement[] =>
293
+ props.collection
294
+ .tuples()
295
+ .filter((a) => a.recursive)
296
+ .map((tuple, i) =>
297
+ StatementFactory.constant({
298
+ name: Prefix.tuple(i),
299
+ value: ts.factory.createArrowFunction(
300
+ undefined,
301
+ undefined,
302
+ [
303
+ IdentifierFactory.parameter(
304
+ "_recursive",
305
+ TypeFactory.keyword("boolean"),
306
+ ts.factory.createTrue(),
307
+ ),
308
+ IdentifierFactory.parameter(
309
+ "_depth",
310
+ TypeFactory.keyword("number"),
311
+ ExpressionFactory.number(0),
312
+ ),
313
+ ],
314
+ TypeFactory.keyword("any"),
315
+ undefined,
316
+ RandomJoiner.tuple({
317
+ decode: (metadata) =>
318
+ decode({
319
+ context: props.context,
320
+ functor: props.functor,
321
+ explore: {
322
+ function: true,
323
+ recursive: true,
324
+ },
325
+ metadata,
326
+ }),
327
+ elements: tuple.elements,
328
+ }),
329
+ ),
330
+ }),
331
+ );
332
+
333
+ /* -----------------------------------------------------------
334
+ DECODERS
335
+ ----------------------------------------------------------- */
336
+ const decode = (props: {
337
+ context: ITypiaContext;
338
+ functor: FunctionProgrammer;
339
+ explore: IExplore;
340
+ metadata: Metadata;
341
+ }): ts.Expression => {
342
+ const expressions: ts.Expression[] = [];
343
+ if (props.metadata.any === true)
344
+ expressions.push(ts.factory.createStringLiteral("any type used..."));
345
+
346
+ // NULL COALESCING
347
+ if (
348
+ props.metadata.isRequired() === false ||
349
+ props.metadata.functions.length !== 0
350
+ )
351
+ expressions.push(ts.factory.createIdentifier("undefined"));
352
+ if (props.metadata.nullable === true)
353
+ expressions.push(ts.factory.createNull());
354
+
355
+ // CONSTANT TYPES
356
+ for (const constant of props.metadata.constants)
357
+ for (const { value } of constant.values)
358
+ expressions.push(
359
+ constant.type === "boolean"
360
+ ? value === true
361
+ ? ts.factory.createTrue()
362
+ : ts.factory.createFalse()
363
+ : constant.type === "bigint"
364
+ ? ExpressionFactory.bigint(value as bigint)
365
+ : constant.type === "number"
366
+ ? ExpressionFactory.number(value as number)
367
+ : ts.factory.createStringLiteral(value as string),
368
+ );
369
+
370
+ // ATOMIC VARIABLES
371
+ for (const template of props.metadata.templates)
372
+ expressions.push(
373
+ decode_template({
374
+ ...props,
375
+ template,
376
+ }),
377
+ );
378
+ for (const atomic of props.metadata.atomics)
379
+ expressions.push(
380
+ ...decode_atomic({
381
+ context: props.context,
382
+ atomic,
383
+ }),
384
+ );
385
+
386
+ // INSTANCE TYPES
387
+ if (props.metadata.escaped)
388
+ expressions.push(
389
+ decode({
390
+ ...props,
391
+ metadata: props.metadata.escaped.returns,
392
+ }),
393
+ );
394
+ for (const array of props.metadata.arrays)
395
+ expressions.push(
396
+ ...decode_array({
397
+ ...props,
398
+ array,
399
+ }),
400
+ );
401
+ for (const tuple of props.metadata.tuples)
402
+ expressions.push(
403
+ decode_tuple({
404
+ ...props,
405
+ tuple,
406
+ }),
407
+ );
408
+ for (const object of props.metadata.objects)
409
+ expressions.push(
410
+ decode_object({
411
+ ...props,
412
+ object: object.type,
413
+ }),
414
+ );
415
+ for (const native of props.metadata.natives)
416
+ expressions.push(
417
+ decode_native({
418
+ context: props.context,
419
+ functor: props.functor,
420
+ explore: props.explore,
421
+ name: native.name,
422
+ }),
423
+ );
424
+ for (const set of props.metadata.sets)
425
+ expressions.push(
426
+ decode_set({
427
+ ...props,
428
+ set,
429
+ }),
430
+ );
431
+ for (const entry of props.metadata.maps)
432
+ expressions.push(
433
+ decode_map({
434
+ ...props,
435
+ map: entry,
436
+ }),
437
+ );
438
+
439
+ // PICK UP A TYPE
440
+ if (expressions.length === 1) return expressions[0]!;
441
+ return ts.factory.createCallExpression(
442
+ ts.factory.createCallExpression(
443
+ props.context.importer.internal("randomPick"),
444
+ undefined,
445
+ [
446
+ ts.factory.createArrayLiteralExpression(
447
+ expressions.map((expr) =>
448
+ ts.factory.createArrowFunction(
449
+ undefined,
450
+ undefined,
451
+ [],
452
+ undefined,
453
+ undefined,
454
+ expr,
455
+ ),
456
+ ),
457
+ true,
458
+ ),
459
+ ],
460
+ ),
461
+ undefined,
462
+ undefined,
463
+ );
464
+ };
465
+
466
+ const decode_atomic = (props: {
467
+ context: ITypiaContext;
468
+ atomic: MetadataAtomic;
469
+ }) => {
470
+ const schemaList: OpenApi.IJsonSchema[] =
471
+ props.atomic.type === "boolean"
472
+ ? json_schema_boolean(props.atomic)
473
+ : props.atomic.type === "string"
474
+ ? json_schema_string(props.atomic)
475
+ : props.atomic.type === "bigint"
476
+ ? json_schema_bigint(props.atomic)
477
+ : json_schema_number(props.atomic);
478
+ return schemaList.map((schema) => {
479
+ interface IComposed {
480
+ method: string;
481
+ internal: string;
482
+ arguments: ts.Expression[];
483
+ }
484
+ const composed = ((): IComposed => {
485
+ if (props.atomic.type === "string") {
486
+ const string: OpenApi.IJsonSchema.IString =
487
+ schema as OpenApi.IJsonSchema.IString;
488
+ if (string.format !== undefined) {
489
+ const format: string = string.format!;
490
+ if (format === "date-time")
491
+ return {
492
+ method: "datetime",
493
+ internal: "randomFormatDatetime",
494
+ arguments: [],
495
+ };
496
+ return {
497
+ method: format
498
+ .split("-")
499
+ .map((s, i) => (i === 0 ? s : StringUtil.capitalize(s)))
500
+ .join(""),
501
+ internal: `randomFormat${format
502
+ .split("-")
503
+ .map(StringUtil.capitalize)
504
+ .join("")}`,
505
+ arguments: [],
506
+ };
507
+ } else if (string.pattern !== undefined)
508
+ return {
509
+ method: "pattern",
510
+ internal: "randomPattern",
511
+ arguments: [
512
+ ts.factory.createNewExpression(
513
+ ts.factory.createIdentifier("RegExp"),
514
+ undefined,
515
+ [
516
+ ts.factory.createStringLiteral(
517
+ (schema as OpenApi.IJsonSchema.IString).pattern!,
518
+ ),
519
+ ],
520
+ ),
521
+ ],
522
+ };
523
+ } else if (props.atomic.type === "number") {
524
+ const number:
525
+ | OpenApi.IJsonSchema.INumber
526
+ | OpenApi.IJsonSchema.IInteger = schema as
527
+ | OpenApi.IJsonSchema.INumber
528
+ | OpenApi.IJsonSchema.IInteger;
529
+ if (number.type === "integer")
530
+ return {
531
+ method: "integer",
532
+ internal: "randomInteger",
533
+ arguments: [LiteralFactory.write(schema)],
534
+ };
535
+ } else if (props.atomic.type === "boolean")
536
+ return {
537
+ method: props.atomic.type,
538
+ internal: "randomBoolean",
539
+ arguments: [],
540
+ };
541
+ return {
542
+ method: props.atomic.type,
543
+ internal: `random${StringUtil.capitalize(props.atomic.type)}`,
544
+ arguments: [LiteralFactory.write(schema)],
545
+ };
546
+ })();
547
+ return ts.factory.createCallExpression(
548
+ ExpressionFactory.coalesce(
549
+ ts.factory.createPropertyAccessChain(
550
+ ts.factory.createIdentifier("_generator"),
551
+ ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
552
+ ts.factory.createIdentifier(composed.method),
553
+ ),
554
+ props.context.importer.internal(composed.internal),
555
+ ),
556
+ undefined,
557
+ composed.arguments,
558
+ );
559
+ });
560
+ };
561
+
562
+ const decode_template = (props: {
563
+ context: ITypiaContext;
564
+ functor: FunctionProgrammer;
565
+ explore: IExplore;
566
+ template: MetadataTemplate;
567
+ }) =>
568
+ TemplateFactory.generate(
569
+ props.template.row.map((metadata) =>
570
+ decode({
571
+ ...props,
572
+ metadata,
573
+ }),
574
+ ),
575
+ );
576
+
577
+ const decode_array = (props: {
578
+ context: ITypiaContext;
579
+ functor: FunctionProgrammer;
580
+ explore: IExplore;
581
+ array: MetadataArray;
582
+ }): ts.Expression[] => {
583
+ const components: OpenApi.IComponents = {};
584
+ const schemaList: OpenApi.IJsonSchema.IArray[] = json_schema_array({
585
+ components,
586
+ array: props.array,
587
+ }) as OpenApi.IJsonSchema.IArray[];
588
+ if (props.array.type.recursive)
589
+ return schemaList.map((schema) =>
590
+ ts.factory.createCallExpression(
591
+ ts.factory.createIdentifier(
592
+ props.functor.useLocal(Prefix.array(props.array.type.index!)),
593
+ ),
594
+ undefined,
595
+ [
596
+ ts.factory.createObjectLiteralExpression(
597
+ Object.entries(schema)
598
+ .filter(([key]) => key !== "items")
599
+ .map(([key, value]) =>
600
+ ts.factory.createPropertyAssignment(
601
+ key,
602
+ LiteralFactory.write(value),
603
+ ),
604
+ ),
605
+ true,
606
+ ),
607
+ ],
608
+ ),
609
+ );
610
+ return schemaList.map((schema) =>
611
+ RandomJoiner.array({
612
+ decode: (metadata) =>
613
+ decode({
614
+ ...props,
615
+ metadata,
616
+ }),
617
+ expression: coalesce({
618
+ context: props.context,
619
+ method: "array",
620
+ internal: "randomArray",
621
+ }),
622
+ array: props.array.type,
623
+ recursive: props.explore.recursive,
624
+ schema,
625
+ }),
626
+ );
627
+ };
628
+
629
+ const decode_tuple = (props: {
630
+ context: ITypiaContext;
631
+ functor: FunctionProgrammer;
632
+ explore: IExplore;
633
+ tuple: MetadataTuple;
634
+ }): ts.Expression =>
635
+ props.tuple.type.recursive
636
+ ? ts.factory.createCallExpression(
637
+ ts.factory.createIdentifier(
638
+ props.functor.useLocal(Prefix.tuple(props.tuple.type.index!)),
639
+ ),
640
+ undefined,
641
+ [
642
+ ts.factory.createTrue(),
643
+ props.explore.recursive
644
+ ? ts.factory.createAdd(
645
+ ExpressionFactory.number(1),
646
+ ts.factory.createIdentifier("_depth"),
647
+ )
648
+ : ExpressionFactory.number(0),
649
+ ],
650
+ )
651
+ : RandomJoiner.tuple({
652
+ decode: (metadata) =>
653
+ decode({
654
+ ...props,
655
+ metadata,
656
+ }),
657
+ elements: props.tuple.type.elements,
658
+ });
659
+
660
+ const decode_object = (props: {
661
+ functor: FunctionProgrammer;
662
+ explore: IExplore;
663
+ object: MetadataObjectType;
664
+ }) =>
665
+ ts.factory.createCallExpression(
666
+ ts.factory.createIdentifier(
667
+ props.functor.useLocal(Prefix.object(props.object.index)),
668
+ ),
669
+ undefined,
670
+ props.explore.function
671
+ ? [
672
+ props.explore.recursive
673
+ ? ts.factory.createTrue()
674
+ : ts.factory.createIdentifier("_recursive"),
675
+ ts.factory.createConditionalExpression(
676
+ ts.factory.createIdentifier("_recursive"),
677
+ undefined,
678
+ ts.factory.createAdd(
679
+ ExpressionFactory.number(1),
680
+ ts.factory.createIdentifier("_depth"),
681
+ ),
682
+ undefined,
683
+ ts.factory.createIdentifier("_depth"),
684
+ ),
685
+ ]
686
+ : undefined,
687
+ );
688
+
689
+ /* -----------------------------------------------------------
690
+ NATIVE CLASSES
691
+ ----------------------------------------------------------- */
692
+ const decode_set = (props: {
693
+ context: ITypiaContext;
694
+ functor: FunctionProgrammer;
695
+ explore: IExplore;
696
+ set: MetadataSet;
697
+ }) =>
698
+ ts.factory.createNewExpression(
699
+ ts.factory.createIdentifier("Set"),
700
+ undefined,
701
+ [
702
+ decode_array({
703
+ ...props,
704
+ array: MetadataArray.create({
705
+ tags: [],
706
+ type: MetadataArrayType.create({
707
+ value: props.set.value,
708
+ recursive: false,
709
+ index: null,
710
+ nullables: [],
711
+ name: props.set.getName(),
712
+ }),
713
+ }),
714
+ })[0]!,
715
+ ],
716
+ );
717
+
718
+ const decode_map = (props: {
719
+ context: ITypiaContext;
720
+ functor: FunctionProgrammer;
721
+ explore: IExplore;
722
+ map: MetadataMap;
723
+ }) =>
724
+ ts.factory.createNewExpression(
725
+ ts.factory.createIdentifier("Map"),
726
+ undefined,
727
+ [
728
+ decode_array({
729
+ ...props,
730
+ array: MetadataArray.create({
731
+ tags: [],
732
+ type: MetadataArrayType.create({
733
+ name: props.map.getName(),
734
+ index: null,
735
+ recursive: false,
736
+ nullables: [],
737
+ value: Metadata.create({
738
+ ...Metadata.initialize(),
739
+ tuples: [
740
+ (() => {
741
+ const type = MetadataTupleType.create({
742
+ name: `[${props.map.key.getName()}, ${props.map.value.getName()}]`,
743
+ index: null,
744
+ recursive: false,
745
+ nullables: [],
746
+ elements: [props.map.key, props.map.value],
747
+ });
748
+ type.of_map = true;
749
+ return MetadataTuple.create({
750
+ type,
751
+ tags: [],
752
+ });
753
+ })(),
754
+ ],
755
+ }),
756
+ }),
757
+ }),
758
+ })[0]!,
759
+ ],
760
+ );
761
+
762
+ const decode_native = (props: {
763
+ context: ITypiaContext;
764
+ functor: FunctionProgrammer;
765
+ explore: IExplore;
766
+ name: string;
767
+ }): ts.Expression => {
768
+ if (
769
+ props.name === "Boolean" ||
770
+ props.name === "Number" ||
771
+ props.name === "BigInt" ||
772
+ props.name === "String"
773
+ )
774
+ return decode_atomic({
775
+ context: props.context,
776
+ atomic: MetadataAtomic.create({
777
+ type: props.name.toLowerCase() as "string",
778
+ tags: [],
779
+ }),
780
+ })[0]!;
781
+ else if (props.name === "Date") return decode_native_date(props.context);
782
+ else if (
783
+ props.name === "Uint8Array" ||
784
+ props.name === "Uint8ClampedArray" ||
785
+ props.name === "Uint16Array" ||
786
+ props.name === "Uint32Array" ||
787
+ props.name === "BigUint64Array" ||
788
+ props.name === "Int8Array" ||
789
+ props.name === "Int16Array" ||
790
+ props.name === "Int32Array" ||
791
+ props.name === "BigInt64Array" ||
792
+ props.name === "Float32Array" ||
793
+ props.name === "Float64Array"
794
+ )
795
+ return decode_native_byte_array({
796
+ ...props,
797
+ name: props.name,
798
+ });
799
+ else if (props.name === "ArrayBuffer" || props.name === "SharedArrayBuffer")
800
+ return decode_native_array_buffer({
801
+ ...props,
802
+ name: props.name,
803
+ });
804
+ else if (props.name === "DataView") return decode_native_data_view(props);
805
+ else if (props.name === "Blob") return decode_native_blob(props);
806
+ else if (props.name === "File") return decode_native_file(props);
807
+ else if (props.name === "RegExp") return decode_regexp(props.context);
808
+ else
809
+ return ts.factory.createNewExpression(
810
+ ts.factory.createIdentifier(props.name),
811
+ undefined,
812
+ [],
813
+ );
814
+ };
815
+
816
+ const decode_native_date = (context: ITypiaContext) =>
817
+ ts.factory.createNewExpression(
818
+ ts.factory.createIdentifier("Date"),
819
+ undefined,
820
+ [
821
+ ts.factory.createCallExpression(
822
+ coalesce({
823
+ context,
824
+ method: "datetime",
825
+ internal: "randomFormatDatetime",
826
+ }),
827
+ undefined,
828
+ [],
829
+ ),
830
+ ],
831
+ );
832
+
833
+ const decode_native_byte_array = (props: {
834
+ context: ITypiaContext;
835
+ functor: FunctionProgrammer;
836
+ explore: IExplore;
837
+ name:
838
+ | "Uint8Array"
839
+ | "Uint8ClampedArray"
840
+ | "Uint16Array"
841
+ | "Uint32Array"
842
+ | "BigUint64Array"
843
+ | "Int8Array"
844
+ | "Int16Array"
845
+ | "Int32Array"
846
+ | "BigInt64Array"
847
+ | "Float32Array"
848
+ | "Float64Array";
849
+ }): ts.Expression => {
850
+ new BigInt64Array();
851
+ const [type, minimum, maximum]: [string, number, number] = (() => {
852
+ if (props.name === "Uint8Array" || props.name === "Uint8ClampedArray")
853
+ return ["uint32", 0, 255];
854
+ else if (props.name === "Uint16Array") return ["uint32", 0, 65535];
855
+ else if (props.name === "Uint32Array") return ["uint32", 0, 4294967295];
856
+ else if (props.name === "BigUint64Array")
857
+ return ["uint64", 0, 18446744073709551615];
858
+ else if (props.name === "Int8Array") return ["int32", -128, 127];
859
+ else if (props.name === "Int16Array") return ["int32", -32768, 32767];
860
+ else if (props.name === "Int32Array")
861
+ return ["int32", -2147483648, 2147483647];
862
+ else if (props.name === "BigInt64Array")
863
+ return ["uint64", -9223372036854775808, 9223372036854775807];
864
+ else if (props.name === "Float32Array")
865
+ return ["float", -1.175494351e38, 3.4028235e38];
866
+ return ["double", Number.MIN_VALUE, Number.MAX_VALUE];
867
+ })();
868
+ const atomic: "bigint" | "number" =
869
+ props.name === "BigInt64Array" || props.name === "BigUint64Array"
870
+ ? "bigint"
871
+ : "number";
872
+ const value: Metadata = Metadata.create({
873
+ ...Metadata.initialize(),
874
+ atomics: [
875
+ MetadataAtomic.create({
876
+ type: atomic,
877
+ tags: [
878
+ [
879
+ ...MetadataCommentTagFactory.get({
880
+ kind: "type",
881
+ type: atomic,
882
+ value: type,
883
+ }),
884
+ ...MetadataCommentTagFactory.get({
885
+ kind: "minimum",
886
+ type: "number",
887
+ value: minimum.toString(),
888
+ }),
889
+ ...MetadataCommentTagFactory.get({
890
+ kind: "maximum",
891
+ type: "number",
892
+ value: maximum.toString(),
893
+ }),
894
+ ],
895
+ ],
896
+ }),
897
+ ],
898
+ });
899
+ return ts.factory.createNewExpression(
900
+ ts.factory.createIdentifier(props.name),
901
+ [],
902
+ decode_array({
903
+ context: props.context,
904
+ functor: props.functor,
905
+ explore: props.explore,
906
+ array: MetadataArray.create({
907
+ tags: [],
908
+ type: MetadataArrayType.create({
909
+ name: `${props.name}<${atomic}>`,
910
+ value,
911
+ recursive: false,
912
+ index: null,
913
+ nullables: [],
914
+ }),
915
+ }),
916
+ }),
917
+ );
918
+ };
919
+
920
+ const decode_native_blob = (props: {
921
+ context: ITypiaContext;
922
+ functor: FunctionProgrammer;
923
+ explore: IExplore;
924
+ }) =>
925
+ ts.factory.createNewExpression(
926
+ ts.factory.createIdentifier("Blob"),
927
+ undefined,
928
+ [
929
+ ts.factory.createArrayLiteralExpression(
930
+ [
931
+ decode_native_byte_array({
932
+ context: props.context,
933
+ functor: props.functor,
934
+ explore: props.explore,
935
+ name: "Uint8Array",
936
+ }),
937
+ ],
938
+ true,
939
+ ),
940
+ ],
941
+ );
942
+
943
+ const decode_native_file = (props: {
944
+ context: ITypiaContext;
945
+ functor: FunctionProgrammer;
946
+ explore: IExplore;
947
+ }) =>
948
+ ts.factory.createNewExpression(
949
+ ts.factory.createIdentifier("File"),
950
+ undefined,
951
+ [
952
+ ts.factory.createArrayLiteralExpression(
953
+ [
954
+ decode_native_byte_array({
955
+ context: props.context,
956
+ functor: props.functor,
957
+ explore: props.explore,
958
+ name: "Uint8Array",
959
+ }),
960
+ ],
961
+ true,
962
+ ),
963
+ ts.factory.createTemplateExpression(ts.factory.createTemplateHead(""), [
964
+ ts.factory.createTemplateSpan(
965
+ writeRangedString({
966
+ context: props.context,
967
+ minLength: 1,
968
+ maxLength: 8,
969
+ }),
970
+ ts.factory.createTemplateMiddle("."),
971
+ ),
972
+ ts.factory.createTemplateSpan(
973
+ writeRangedString({
974
+ context: props.context,
975
+ minLength: 3,
976
+ maxLength: 3,
977
+ }),
978
+ ts.factory.createTemplateTail(""),
979
+ ),
980
+ ]),
981
+ ],
982
+ );
983
+
984
+ const decode_native_array_buffer = (props: {
985
+ context: ITypiaContext;
986
+ functor: FunctionProgrammer;
987
+ explore: IExplore;
988
+ name: "ArrayBuffer" | "SharedArrayBuffer";
989
+ }): ts.Expression =>
990
+ props.name === "ArrayBuffer"
991
+ ? IdentifierFactory.access(
992
+ decode_native_byte_array({
993
+ context: props.context,
994
+ functor: props.functor,
995
+ explore: props.explore,
996
+ name: "Uint8Array",
997
+ }),
998
+ "buffer",
999
+ )
1000
+ : ExpressionFactory.selfCall(
1001
+ ts.factory.createBlock(
1002
+ [
1003
+ StatementFactory.constant({
1004
+ name: "length",
1005
+ value: decode_atomic({
1006
+ context: props.context,
1007
+ atomic: MetadataAtomic.create({
1008
+ type: "number",
1009
+ tags: [
1010
+ MetadataCommentTagFactory.get({
1011
+ type: "number",
1012
+ kind: "type",
1013
+ value: "uint32",
1014
+ }),
1015
+ ],
1016
+ }),
1017
+ })[0]!,
1018
+ }),
1019
+ StatementFactory.constant({
1020
+ name: "buffer",
1021
+ value: ts.factory.createNewExpression(
1022
+ ts.factory.createIdentifier("SharedArrayBuffer"),
1023
+ [],
1024
+ [ts.factory.createIdentifier("length")],
1025
+ ),
1026
+ }),
1027
+ StatementFactory.constant({
1028
+ name: "bytes",
1029
+ value: ts.factory.createNewExpression(
1030
+ ts.factory.createIdentifier("Uint8Array"),
1031
+ [],
1032
+ [ts.factory.createIdentifier("buffer")],
1033
+ ),
1034
+ }),
1035
+ ts.factory.createExpressionStatement(
1036
+ ts.factory.createCallExpression(
1037
+ IdentifierFactory.access(
1038
+ ts.factory.createIdentifier("bytes"),
1039
+ "set",
1040
+ ),
1041
+ undefined,
1042
+ [
1043
+ ts.factory.createCallExpression(
1044
+ ts.factory.createPropertyAccessExpression(
1045
+ ts.factory.createCallExpression(
1046
+ ts.factory.createPropertyAccessExpression(
1047
+ ts.factory.createNewExpression(
1048
+ ts.factory.createIdentifier("Array"),
1049
+ undefined,
1050
+ [ts.factory.createIdentifier("length")],
1051
+ ),
1052
+ ts.factory.createIdentifier("fill"),
1053
+ ),
1054
+ undefined,
1055
+ [ts.factory.createNumericLiteral("0")],
1056
+ ),
1057
+ ts.factory.createIdentifier("map"),
1058
+ ),
1059
+ undefined,
1060
+ [
1061
+ ts.factory.createArrowFunction(
1062
+ undefined,
1063
+ undefined,
1064
+ [],
1065
+ undefined,
1066
+ undefined,
1067
+ decode_atomic({
1068
+ context: props.context,
1069
+ atomic: MetadataAtomic.create({
1070
+ type: "number",
1071
+ tags: [
1072
+ [
1073
+ ...MetadataCommentTagFactory.get({
1074
+ kind: "type",
1075
+ type: "number",
1076
+ value: "uint32",
1077
+ }),
1078
+ ...MetadataCommentTagFactory.get({
1079
+ kind: "minimum",
1080
+ type: "number",
1081
+ value: "0",
1082
+ }),
1083
+ ...MetadataCommentTagFactory.get({
1084
+ kind: "maximum",
1085
+ type: "number",
1086
+ value: "255",
1087
+ }),
1088
+ ],
1089
+ ],
1090
+ }),
1091
+ })[0]!,
1092
+ ),
1093
+ ],
1094
+ ),
1095
+ ExpressionFactory.number(0),
1096
+ ],
1097
+ ),
1098
+ ),
1099
+ ts.factory.createReturnStatement(
1100
+ ts.factory.createIdentifier("buffer"),
1101
+ ),
1102
+ ],
1103
+ true,
1104
+ ),
1105
+ );
1106
+
1107
+ const decode_native_data_view = (props: {
1108
+ context: ITypiaContext;
1109
+ functor: FunctionProgrammer;
1110
+ explore: IExplore;
1111
+ }) =>
1112
+ ts.factory.createNewExpression(
1113
+ ts.factory.createIdentifier("DataView"),
1114
+ [],
1115
+ [
1116
+ IdentifierFactory.access(
1117
+ decode_native_byte_array({
1118
+ context: props.context,
1119
+ functor: props.functor,
1120
+ explore: props.explore,
1121
+ name: "Uint8Array",
1122
+ }),
1123
+ "buffer",
1124
+ ),
1125
+ ],
1126
+ );
1127
+
1128
+ const decode_regexp = (context: ITypiaContext) =>
1129
+ ts.factory.createNewExpression(
1130
+ ts.factory.createIdentifier("RegExp"),
1131
+ [],
1132
+ [
1133
+ ts.factory.createCallExpression(
1134
+ coalesce({
1135
+ context,
1136
+ method: "regex",
1137
+ internal: "randomFormatRegex",
1138
+ }),
1139
+ undefined,
1140
+ undefined,
1141
+ ),
1142
+ ],
1143
+ );
1144
+
1145
+ const writeRangedString = (props: {
1146
+ context: ITypiaContext;
1147
+ minLength: number;
1148
+ maxLength: number;
1149
+ }): ts.CallExpression =>
1150
+ decode_atomic({
1151
+ context: props.context,
1152
+ atomic: MetadataAtomic.create({
1153
+ type: "string",
1154
+ tags: [
1155
+ [
1156
+ ...MetadataCommentTagFactory.get({
1157
+ kind: "minLength",
1158
+ type: "string",
1159
+ value: props.minLength.toString(),
1160
+ }),
1161
+ ...MetadataCommentTagFactory.get({
1162
+ kind: "maxLength",
1163
+ type: "string",
1164
+ value: props.maxLength.toString(),
1165
+ }),
1166
+ ],
1167
+ ],
1168
+ }),
1169
+ })[0]!;
1170
+ }
1171
+
1172
+ const coalesce = (props: {
1173
+ context: ITypiaContext;
1174
+ method: string;
1175
+ internal: string;
1176
+ }): ts.Expression =>
1177
+ ExpressionFactory.coalesce(
1178
+ ts.factory.createPropertyAccessChain(
1179
+ ts.factory.createIdentifier("_generator"),
1180
+ ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
1181
+ ts.factory.createIdentifier(props.method),
1182
+ ),
1183
+ props.context.importer.internal(props.internal),
1184
+ );
1185
+
1186
+ interface IExplore {
1187
+ function: boolean;
1188
+ recursive: boolean;
1189
+ }
1190
+
1191
+ const Prefix = {
1192
+ object: (i: number) => `_ro${i}`,
1193
+ array: (i: number) => `_ra${i}`,
1194
+ tuple: (i: number) => `_rt${i}`,
1195
+ };