typia 3.7.2 → 3.7.3

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 (32) hide show
  1. package/lib/programmers/AssertProgrammer.js +4 -2
  2. package/lib/programmers/AssertProgrammer.js.map +1 -1
  3. package/lib/programmers/ValidateProgrammer.js +3 -2
  4. package/lib/programmers/ValidateProgrammer.js.map +1 -1
  5. package/package.json +4 -2
  6. package/src/IRandomGenerator.ts +33 -33
  7. package/src/factories/IdentifierFactory.ts +81 -81
  8. package/src/factories/MetadataTagFactory.ts +302 -302
  9. package/src/metadata/ICommentTag.ts +4 -4
  10. package/src/programmers/AssertProgrammer.ts +38 -10
  11. package/src/programmers/LiteralsProgrammer.ts +65 -65
  12. package/src/programmers/RandomProgrammer.ts +413 -413
  13. package/src/programmers/ValidateProgrammer.ts +36 -9
  14. package/src/programmers/helpers/RandomJoiner.ts +161 -161
  15. package/src/programmers/helpers/RandomRanger.ts +216 -216
  16. package/src/programmers/internal/application_native.ts +32 -32
  17. package/src/programmers/internal/check_array.ts +30 -30
  18. package/src/programmers/internal/check_array_length.ts +35 -35
  19. package/src/programmers/internal/check_custom.ts +33 -33
  20. package/src/programmers/internal/check_number.ts +177 -177
  21. package/src/programmers/internal/check_object.ts +55 -55
  22. package/src/programmers/internal/check_union_array_like.ts +272 -272
  23. package/src/programmers/internal/feature_object_entries.ts +63 -63
  24. package/src/programmers/internal/get_comment_tags.ts +23 -23
  25. package/src/programmers/internal/metadata_to_pattern.ts +34 -34
  26. package/src/programmers/internal/random_custom.ts +30 -30
  27. package/src/programmers/internal/stringify_dynamic_properties.ts +168 -168
  28. package/src/programmers/internal/stringify_regular_properties.ts +84 -84
  29. package/src/transformers/CallExpressionTransformer.ts +174 -174
  30. package/src/transformers/features/miscellaneous/CreateRandomTransformer.ts +41 -41
  31. package/src/transformers/features/miscellaneous/LiteralsTransformer.ts +30 -30
  32. package/src/typings/Customizable.ts +5 -5
@@ -1,413 +1,413 @@
1
- import ts from "typescript";
2
-
3
- import { ExpressionFactory } from "../factories/ExpressionFactory";
4
- import { IdentifierFactory } from "../factories/IdentifierFactory";
5
- import { MetadataCollection } from "../factories/MetadataCollection";
6
- import { MetadataFactory } from "../factories/MetadataFactory";
7
- import { StatementFactory } from "../factories/StatementFactory";
8
- import { TemplateFactory } from "../factories/TemplateFactory";
9
- import { TypeFactory } from "../factories/TypeFactory";
10
-
11
- import { ICommentTag } from "../metadata/ICommentTag";
12
- import { IMetadataTag } from "../metadata/IMetadataTag";
13
- import { Metadata } from "../metadata/Metadata";
14
-
15
- import { IProject } from "../transformers/IProject";
16
-
17
- import { FunctionImporter } from "./helpers/FunctionImporeter";
18
- import { RandomJoiner } from "./helpers/RandomJoiner";
19
- import { RandomRanger } from "./helpers/RandomRanger";
20
- import { random_custom } from "./internal/random_custom";
21
-
22
- export namespace RandomProgrammer {
23
- export function generate(
24
- project: IProject,
25
- modulo: ts.LeftHandSideExpression,
26
- init?: ts.Expression,
27
- ) {
28
- const importer: FunctionImporter = new FunctionImporter();
29
- return (type: ts.Type, name?: string) => {
30
- // INITIALIZE METADATA
31
- const collection: MetadataCollection = new MetadataCollection();
32
- const meta: Metadata = MetadataFactory.generate(
33
- project.checker,
34
- collection,
35
- type,
36
- {
37
- resolve: true,
38
- constant: true,
39
- },
40
- );
41
-
42
- // GENERATE FUNCTION
43
- const functors: ts.VariableStatement[] =
44
- generate_functors(importer)(collection);
45
- const output: ts.Expression = decode(importer)({
46
- object: false,
47
- recursive: false,
48
- })(meta, [], []);
49
-
50
- return ts.factory.createArrowFunction(
51
- undefined,
52
- undefined,
53
- [
54
- IdentifierFactory.parameter(
55
- "generator",
56
- ts.factory.createTypeReferenceNode(
57
- "Partial<typia.IRandomGenerator>",
58
- ),
59
- init ??
60
- ts.factory.createToken(ts.SyntaxKind.QuestionToken),
61
- ),
62
- ],
63
- ts.factory.createTypeReferenceNode(
64
- `typia.Primitive<${
65
- name ?? TypeFactory.getFullName(project.checker, type)
66
- }>`,
67
- ),
68
- undefined,
69
- ts.factory.createBlock(
70
- [
71
- ...importer.declare(modulo),
72
- ...functors,
73
- ts.factory.createReturnStatement(output),
74
- ],
75
- true,
76
- ),
77
- );
78
- };
79
- }
80
-
81
- const generate_functors =
82
- (importer: FunctionImporter) => (collection: MetadataCollection) =>
83
- collection.objects().map((obj, i) =>
84
- StatementFactory.constant(
85
- FUNCTOR(i),
86
- ts.factory.createArrowFunction(
87
- undefined,
88
- undefined,
89
- [
90
- IdentifierFactory.parameter(
91
- "_recursive",
92
- TypeFactory.keyword("boolean"),
93
- ts.factory.createIdentifier(
94
- String(obj.recursive),
95
- ),
96
- ),
97
- IdentifierFactory.parameter(
98
- "_depth",
99
- TypeFactory.keyword("number"),
100
- ts.factory.createNumericLiteral(0),
101
- ),
102
- ],
103
- TypeFactory.keyword("any"),
104
- undefined,
105
- RandomJoiner.object(COALESCE(importer))(
106
- decode(importer)({
107
- recursive: obj.recursive,
108
- object: true,
109
- }),
110
- )(obj),
111
- ),
112
- ),
113
- );
114
-
115
- /* -----------------------------------------------------------
116
- DECODERS
117
- ----------------------------------------------------------- */
118
- const decode =
119
- (importer: FunctionImporter) =>
120
- (explore: IExplore) =>
121
- (
122
- meta: Metadata,
123
- tags: IMetadataTag[],
124
- comments: ICommentTag[],
125
- ): ts.Expression => {
126
- const expressions: ts.Expression[] = [];
127
- if (meta.any)
128
- expressions.push(
129
- ts.factory.createStringLiteral(
130
- "fucking any type exists...",
131
- ),
132
- );
133
-
134
- // NULL COALESCING
135
- if (meta.required === false)
136
- expressions.push(ts.factory.createIdentifier("undefined"));
137
- if (meta.nullable === true)
138
- expressions.push(ts.factory.createNull());
139
-
140
- // CONSTANT TYPES
141
- for (const constant of meta.constants)
142
- for (const value of constant.values)
143
- expressions.push(decode_atomic(value));
144
-
145
- // ATOMIC VARIABLES
146
- for (const template of meta.templates)
147
- expressions.push(decode_template(importer)(explore)(template));
148
- for (const atomic of meta.atomics)
149
- if (atomic === "boolean")
150
- expressions.push(decode_boolean(importer));
151
- else if (atomic === "number")
152
- expressions.push(decode_number(importer)(tags)(comments));
153
- else if (atomic === "string")
154
- expressions.push(decode_string(importer)(tags)(comments));
155
- else if (atomic === "bigint")
156
- expressions.push(decode_bigint(importer)(tags)(comments));
157
-
158
- // INSTANCE TYPES
159
- if (meta.resolved)
160
- expressions.push(
161
- decode(importer)(explore)(meta.resolved, tags, comments),
162
- );
163
- for (const t of meta.tuples)
164
- expressions.push(
165
- RandomJoiner.tuple(decode(importer)(explore))(
166
- t,
167
- tags,
168
- comments,
169
- ),
170
- );
171
- for (const a of meta.arrays) {
172
- const array = RandomJoiner.array(COALESCE(importer))(
173
- decode(importer)(explore),
174
- )(a, tags, comments);
175
- expressions.push(
176
- explore.recursive && a.objects.length
177
- ? ts.factory.createConditionalExpression(
178
- ts.factory.createLogicalAnd(
179
- ts.factory.createIdentifier("_recursive"),
180
- ts.factory.createLessThan(
181
- ts.factory.createNumericLiteral(5),
182
- ts.factory.createIdentifier("_depth"),
183
- ),
184
- ),
185
- undefined,
186
- ts.factory.createIdentifier("[]"),
187
- undefined,
188
- array,
189
- )
190
- : array,
191
- );
192
- }
193
- for (const o of meta.objects)
194
- expressions.push(
195
- ts.factory.createCallExpression(
196
- ts.factory.createIdentifier(FUNCTOR(o.index)),
197
- undefined,
198
- explore.object
199
- ? [
200
- explore.recursive
201
- ? ts.factory.createTrue()
202
- : ts.factory.createIdentifier(
203
- "_recursive",
204
- ),
205
- ts.factory.createConditionalExpression(
206
- ts.factory.createIdentifier("_recursive"),
207
- undefined,
208
- ts.factory.createAdd(
209
- ts.factory.createNumericLiteral(1),
210
- ts.factory.createIdentifier("_depth"),
211
- ),
212
- undefined,
213
- ts.factory.createIdentifier("_depth"),
214
- ),
215
- ]
216
- : undefined,
217
- ),
218
- );
219
- for (const native of meta.natives)
220
- if (native === "Boolean")
221
- expressions.push(decode_boolean(importer));
222
- else if (native === "Number")
223
- expressions.push(decode_number(importer)(tags)(comments));
224
- else if (native === "String")
225
- expressions.push(decode_string(importer)(tags)(comments));
226
- else expressions.push(ts.factory.createIdentifier("{}"));
227
- if (meta.sets.length || meta.maps.length)
228
- expressions.push(ts.factory.createIdentifier("{}"));
229
-
230
- // PRIMITIVE TYPES
231
- if (expressions.length === 1) return expressions[0]!;
232
- return ts.factory.createCallExpression(
233
- ts.factory.createCallExpression(
234
- importer.use("pick"),
235
- undefined,
236
- [
237
- ts.factory.createArrayLiteralExpression(
238
- expressions.map((expr) =>
239
- ts.factory.createArrowFunction(
240
- undefined,
241
- undefined,
242
- [],
243
- undefined,
244
- undefined,
245
- expr,
246
- ),
247
- ),
248
- true,
249
- ),
250
- ],
251
- ),
252
- undefined,
253
- undefined,
254
- );
255
- };
256
-
257
- const decode_boolean = (importer: FunctionImporter) =>
258
- ts.factory.createCallExpression(
259
- COALESCE(importer)("boolean"),
260
- undefined,
261
- undefined,
262
- );
263
-
264
- const decode_atomic = (value: Atomic) =>
265
- typeof value === "boolean"
266
- ? ts.factory.createIdentifier(value.toString())
267
- : typeof value === "number"
268
- ? ts.factory.createNumericLiteral(value)
269
- : typeof value === "string"
270
- ? ts.factory.createStringLiteral(value)
271
- : ts.factory.createBigIntLiteral(value.toString());
272
-
273
- const decode_template =
274
- (importer: FunctionImporter) =>
275
- (explore: IExplore) =>
276
- (template: Metadata[]) =>
277
- TemplateFactory.generate(
278
- template.map((meta) => decode(importer)(explore)(meta, [], [])),
279
- );
280
-
281
- const decode_number =
282
- (importer: FunctionImporter) =>
283
- (tags: IMetadataTag[]) =>
284
- (comments: ICommentTag[]): ts.Expression => {
285
- const type = tags.find(
286
- (t) => t.kind === "type" && t.value === "uint",
287
- )
288
- ? "int"
289
- : tags.find((t) => t.kind === "type" && t.value === "int")
290
- ? "uint"
291
- : "double";
292
- return random_custom(COALESCE(importer))("number")(comments)(
293
- RandomRanger.number({
294
- type,
295
- transform: (value) =>
296
- ts.factory.createNumericLiteral(value),
297
- setter: (args) =>
298
- ts.factory.createCallExpression(
299
- type === "double" &&
300
- tags.every(
301
- (t) =>
302
- t.kind !== "multipleOf" &&
303
- t.kind !== "step",
304
- )
305
- ? COALESCE(importer)("number")
306
- : COALESCE(importer)("integer"),
307
- undefined,
308
- args.map((val) =>
309
- ts.factory.createNumericLiteral(val),
310
- ),
311
- ),
312
- })({
313
- minimum: 0,
314
- maximum: 100,
315
- gap: 10,
316
- })(tags),
317
- );
318
- };
319
-
320
- const decode_bigint =
321
- (importer: FunctionImporter) =>
322
- (tags: IMetadataTag[]) =>
323
- (comments: ICommentTag[]): ts.Expression =>
324
- random_custom(COALESCE(importer))("bigint")(comments)(
325
- RandomRanger.number({
326
- type: tags.find(
327
- (t) => t.kind === "type" && t.value === "uint",
328
- )
329
- ? "uint"
330
- : "int",
331
- transform: (value) =>
332
- ts.factory.createCallExpression(
333
- ts.factory.createIdentifier("BigInt"),
334
- undefined,
335
- [ts.factory.createStringLiteral(value.toString())],
336
- ),
337
- setter: (args) =>
338
- ts.factory.createCallExpression(
339
- COALESCE(importer)("bigint"),
340
- undefined,
341
- args.map((value) =>
342
- ts.factory.createCallExpression(
343
- ts.factory.createIdentifier("BigInt"),
344
- undefined,
345
- [
346
- ts.factory.createStringLiteral(
347
- value.toString(),
348
- ),
349
- ],
350
- ),
351
- ),
352
- ),
353
- })({
354
- minimum: 0,
355
- maximum: 100,
356
- gap: 10,
357
- })(tags),
358
- );
359
-
360
- const decode_string =
361
- (importer: FunctionImporter) =>
362
- (tags: IMetadataTag[]) =>
363
- (comments: ICommentTag[]): ts.Expression =>
364
- random_custom(COALESCE(importer))("string")(comments)(
365
- (() => {
366
- for (const t of tags)
367
- if (t.kind === "format")
368
- return ts.factory.createCallExpression(
369
- COALESCE(importer)(t.value),
370
- undefined,
371
- undefined,
372
- );
373
- else if (t.kind === "pattern")
374
- return ts.factory.createCallExpression(
375
- COALESCE(importer)("pattern"),
376
- undefined,
377
- [ts.factory.createIdentifier(`/${t.value}/`)],
378
- );
379
-
380
- const tail = RandomRanger.length(COALESCE(importer))({
381
- minimum: 5,
382
- maximum: 25,
383
- gap: 5,
384
- })({
385
- fixed: "length",
386
- minimum: "minLength",
387
- maximum: "maxLength",
388
- })(tags);
389
- return ts.factory.createCallExpression(
390
- COALESCE(importer)("string"),
391
- undefined,
392
- tail ? [tail] : undefined,
393
- );
394
- })(),
395
- );
396
- }
397
-
398
- type Atomic = boolean | number | string | bigint;
399
- interface IExplore {
400
- object: boolean;
401
- recursive: boolean;
402
- }
403
-
404
- const FUNCTOR = (i: number) => `$ro${i}`;
405
- const COALESCE = (importer: FunctionImporter) => (name: string) =>
406
- ExpressionFactory.coalesce(
407
- ts.factory.createPropertyAccessChain(
408
- ts.factory.createIdentifier("generator"),
409
- ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
410
- ts.factory.createIdentifier(name),
411
- ),
412
- IdentifierFactory.join(importer.use("generator"), name),
413
- );
1
+ import ts from "typescript";
2
+
3
+ import { ExpressionFactory } from "../factories/ExpressionFactory";
4
+ import { IdentifierFactory } from "../factories/IdentifierFactory";
5
+ import { MetadataCollection } from "../factories/MetadataCollection";
6
+ import { MetadataFactory } from "../factories/MetadataFactory";
7
+ import { StatementFactory } from "../factories/StatementFactory";
8
+ import { TemplateFactory } from "../factories/TemplateFactory";
9
+ import { TypeFactory } from "../factories/TypeFactory";
10
+
11
+ import { ICommentTag } from "../metadata/ICommentTag";
12
+ import { IMetadataTag } from "../metadata/IMetadataTag";
13
+ import { Metadata } from "../metadata/Metadata";
14
+
15
+ import { IProject } from "../transformers/IProject";
16
+
17
+ import { FunctionImporter } from "./helpers/FunctionImporeter";
18
+ import { RandomJoiner } from "./helpers/RandomJoiner";
19
+ import { RandomRanger } from "./helpers/RandomRanger";
20
+ import { random_custom } from "./internal/random_custom";
21
+
22
+ export namespace RandomProgrammer {
23
+ export function generate(
24
+ project: IProject,
25
+ modulo: ts.LeftHandSideExpression,
26
+ init?: ts.Expression,
27
+ ) {
28
+ const importer: FunctionImporter = new FunctionImporter();
29
+ return (type: ts.Type, name?: string) => {
30
+ // INITIALIZE METADATA
31
+ const collection: MetadataCollection = new MetadataCollection();
32
+ const meta: Metadata = MetadataFactory.generate(
33
+ project.checker,
34
+ collection,
35
+ type,
36
+ {
37
+ resolve: true,
38
+ constant: true,
39
+ },
40
+ );
41
+
42
+ // GENERATE FUNCTION
43
+ const functors: ts.VariableStatement[] =
44
+ generate_functors(importer)(collection);
45
+ const output: ts.Expression = decode(importer)({
46
+ object: false,
47
+ recursive: false,
48
+ })(meta, [], []);
49
+
50
+ return ts.factory.createArrowFunction(
51
+ undefined,
52
+ undefined,
53
+ [
54
+ IdentifierFactory.parameter(
55
+ "generator",
56
+ ts.factory.createTypeReferenceNode(
57
+ "Partial<typia.IRandomGenerator>",
58
+ ),
59
+ init ??
60
+ ts.factory.createToken(ts.SyntaxKind.QuestionToken),
61
+ ),
62
+ ],
63
+ ts.factory.createTypeReferenceNode(
64
+ `typia.Primitive<${
65
+ name ?? TypeFactory.getFullName(project.checker, type)
66
+ }>`,
67
+ ),
68
+ undefined,
69
+ ts.factory.createBlock(
70
+ [
71
+ ...importer.declare(modulo),
72
+ ...functors,
73
+ ts.factory.createReturnStatement(output),
74
+ ],
75
+ true,
76
+ ),
77
+ );
78
+ };
79
+ }
80
+
81
+ const generate_functors =
82
+ (importer: FunctionImporter) => (collection: MetadataCollection) =>
83
+ collection.objects().map((obj, i) =>
84
+ StatementFactory.constant(
85
+ FUNCTOR(i),
86
+ ts.factory.createArrowFunction(
87
+ undefined,
88
+ undefined,
89
+ [
90
+ IdentifierFactory.parameter(
91
+ "_recursive",
92
+ TypeFactory.keyword("boolean"),
93
+ ts.factory.createIdentifier(
94
+ String(obj.recursive),
95
+ ),
96
+ ),
97
+ IdentifierFactory.parameter(
98
+ "_depth",
99
+ TypeFactory.keyword("number"),
100
+ ts.factory.createNumericLiteral(0),
101
+ ),
102
+ ],
103
+ TypeFactory.keyword("any"),
104
+ undefined,
105
+ RandomJoiner.object(COALESCE(importer))(
106
+ decode(importer)({
107
+ recursive: obj.recursive,
108
+ object: true,
109
+ }),
110
+ )(obj),
111
+ ),
112
+ ),
113
+ );
114
+
115
+ /* -----------------------------------------------------------
116
+ DECODERS
117
+ ----------------------------------------------------------- */
118
+ const decode =
119
+ (importer: FunctionImporter) =>
120
+ (explore: IExplore) =>
121
+ (
122
+ meta: Metadata,
123
+ tags: IMetadataTag[],
124
+ comments: ICommentTag[],
125
+ ): ts.Expression => {
126
+ const expressions: ts.Expression[] = [];
127
+ if (meta.any)
128
+ expressions.push(
129
+ ts.factory.createStringLiteral(
130
+ "fucking any type exists...",
131
+ ),
132
+ );
133
+
134
+ // NULL COALESCING
135
+ if (meta.required === false)
136
+ expressions.push(ts.factory.createIdentifier("undefined"));
137
+ if (meta.nullable === true)
138
+ expressions.push(ts.factory.createNull());
139
+
140
+ // CONSTANT TYPES
141
+ for (const constant of meta.constants)
142
+ for (const value of constant.values)
143
+ expressions.push(decode_atomic(value));
144
+
145
+ // ATOMIC VARIABLES
146
+ for (const template of meta.templates)
147
+ expressions.push(decode_template(importer)(explore)(template));
148
+ for (const atomic of meta.atomics)
149
+ if (atomic === "boolean")
150
+ expressions.push(decode_boolean(importer));
151
+ else if (atomic === "number")
152
+ expressions.push(decode_number(importer)(tags)(comments));
153
+ else if (atomic === "string")
154
+ expressions.push(decode_string(importer)(tags)(comments));
155
+ else if (atomic === "bigint")
156
+ expressions.push(decode_bigint(importer)(tags)(comments));
157
+
158
+ // INSTANCE TYPES
159
+ if (meta.resolved)
160
+ expressions.push(
161
+ decode(importer)(explore)(meta.resolved, tags, comments),
162
+ );
163
+ for (const t of meta.tuples)
164
+ expressions.push(
165
+ RandomJoiner.tuple(decode(importer)(explore))(
166
+ t,
167
+ tags,
168
+ comments,
169
+ ),
170
+ );
171
+ for (const a of meta.arrays) {
172
+ const array = RandomJoiner.array(COALESCE(importer))(
173
+ decode(importer)(explore),
174
+ )(a, tags, comments);
175
+ expressions.push(
176
+ explore.recursive && a.objects.length
177
+ ? ts.factory.createConditionalExpression(
178
+ ts.factory.createLogicalAnd(
179
+ ts.factory.createIdentifier("_recursive"),
180
+ ts.factory.createLessThan(
181
+ ts.factory.createNumericLiteral(5),
182
+ ts.factory.createIdentifier("_depth"),
183
+ ),
184
+ ),
185
+ undefined,
186
+ ts.factory.createIdentifier("[]"),
187
+ undefined,
188
+ array,
189
+ )
190
+ : array,
191
+ );
192
+ }
193
+ for (const o of meta.objects)
194
+ expressions.push(
195
+ ts.factory.createCallExpression(
196
+ ts.factory.createIdentifier(FUNCTOR(o.index)),
197
+ undefined,
198
+ explore.object
199
+ ? [
200
+ explore.recursive
201
+ ? ts.factory.createTrue()
202
+ : ts.factory.createIdentifier(
203
+ "_recursive",
204
+ ),
205
+ ts.factory.createConditionalExpression(
206
+ ts.factory.createIdentifier("_recursive"),
207
+ undefined,
208
+ ts.factory.createAdd(
209
+ ts.factory.createNumericLiteral(1),
210
+ ts.factory.createIdentifier("_depth"),
211
+ ),
212
+ undefined,
213
+ ts.factory.createIdentifier("_depth"),
214
+ ),
215
+ ]
216
+ : undefined,
217
+ ),
218
+ );
219
+ for (const native of meta.natives)
220
+ if (native === "Boolean")
221
+ expressions.push(decode_boolean(importer));
222
+ else if (native === "Number")
223
+ expressions.push(decode_number(importer)(tags)(comments));
224
+ else if (native === "String")
225
+ expressions.push(decode_string(importer)(tags)(comments));
226
+ else expressions.push(ts.factory.createIdentifier("{}"));
227
+ if (meta.sets.length || meta.maps.length)
228
+ expressions.push(ts.factory.createIdentifier("{}"));
229
+
230
+ // PRIMITIVE TYPES
231
+ if (expressions.length === 1) return expressions[0]!;
232
+ return ts.factory.createCallExpression(
233
+ ts.factory.createCallExpression(
234
+ importer.use("pick"),
235
+ undefined,
236
+ [
237
+ ts.factory.createArrayLiteralExpression(
238
+ expressions.map((expr) =>
239
+ ts.factory.createArrowFunction(
240
+ undefined,
241
+ undefined,
242
+ [],
243
+ undefined,
244
+ undefined,
245
+ expr,
246
+ ),
247
+ ),
248
+ true,
249
+ ),
250
+ ],
251
+ ),
252
+ undefined,
253
+ undefined,
254
+ );
255
+ };
256
+
257
+ const decode_boolean = (importer: FunctionImporter) =>
258
+ ts.factory.createCallExpression(
259
+ COALESCE(importer)("boolean"),
260
+ undefined,
261
+ undefined,
262
+ );
263
+
264
+ const decode_atomic = (value: Atomic) =>
265
+ typeof value === "boolean"
266
+ ? ts.factory.createIdentifier(value.toString())
267
+ : typeof value === "number"
268
+ ? ts.factory.createNumericLiteral(value)
269
+ : typeof value === "string"
270
+ ? ts.factory.createStringLiteral(value)
271
+ : ts.factory.createBigIntLiteral(value.toString());
272
+
273
+ const decode_template =
274
+ (importer: FunctionImporter) =>
275
+ (explore: IExplore) =>
276
+ (template: Metadata[]) =>
277
+ TemplateFactory.generate(
278
+ template.map((meta) => decode(importer)(explore)(meta, [], [])),
279
+ );
280
+
281
+ const decode_number =
282
+ (importer: FunctionImporter) =>
283
+ (tags: IMetadataTag[]) =>
284
+ (comments: ICommentTag[]): ts.Expression => {
285
+ const type = tags.find(
286
+ (t) => t.kind === "type" && t.value === "uint",
287
+ )
288
+ ? "int"
289
+ : tags.find((t) => t.kind === "type" && t.value === "int")
290
+ ? "uint"
291
+ : "double";
292
+ return random_custom(COALESCE(importer))("number")(comments)(
293
+ RandomRanger.number({
294
+ type,
295
+ transform: (value) =>
296
+ ts.factory.createNumericLiteral(value),
297
+ setter: (args) =>
298
+ ts.factory.createCallExpression(
299
+ type === "double" &&
300
+ tags.every(
301
+ (t) =>
302
+ t.kind !== "multipleOf" &&
303
+ t.kind !== "step",
304
+ )
305
+ ? COALESCE(importer)("number")
306
+ : COALESCE(importer)("integer"),
307
+ undefined,
308
+ args.map((val) =>
309
+ ts.factory.createNumericLiteral(val),
310
+ ),
311
+ ),
312
+ })({
313
+ minimum: 0,
314
+ maximum: 100,
315
+ gap: 10,
316
+ })(tags),
317
+ );
318
+ };
319
+
320
+ const decode_bigint =
321
+ (importer: FunctionImporter) =>
322
+ (tags: IMetadataTag[]) =>
323
+ (comments: ICommentTag[]): ts.Expression =>
324
+ random_custom(COALESCE(importer))("bigint")(comments)(
325
+ RandomRanger.number({
326
+ type: tags.find(
327
+ (t) => t.kind === "type" && t.value === "uint",
328
+ )
329
+ ? "uint"
330
+ : "int",
331
+ transform: (value) =>
332
+ ts.factory.createCallExpression(
333
+ ts.factory.createIdentifier("BigInt"),
334
+ undefined,
335
+ [ts.factory.createStringLiteral(value.toString())],
336
+ ),
337
+ setter: (args) =>
338
+ ts.factory.createCallExpression(
339
+ COALESCE(importer)("bigint"),
340
+ undefined,
341
+ args.map((value) =>
342
+ ts.factory.createCallExpression(
343
+ ts.factory.createIdentifier("BigInt"),
344
+ undefined,
345
+ [
346
+ ts.factory.createStringLiteral(
347
+ value.toString(),
348
+ ),
349
+ ],
350
+ ),
351
+ ),
352
+ ),
353
+ })({
354
+ minimum: 0,
355
+ maximum: 100,
356
+ gap: 10,
357
+ })(tags),
358
+ );
359
+
360
+ const decode_string =
361
+ (importer: FunctionImporter) =>
362
+ (tags: IMetadataTag[]) =>
363
+ (comments: ICommentTag[]): ts.Expression =>
364
+ random_custom(COALESCE(importer))("string")(comments)(
365
+ (() => {
366
+ for (const t of tags)
367
+ if (t.kind === "format")
368
+ return ts.factory.createCallExpression(
369
+ COALESCE(importer)(t.value),
370
+ undefined,
371
+ undefined,
372
+ );
373
+ else if (t.kind === "pattern")
374
+ return ts.factory.createCallExpression(
375
+ COALESCE(importer)("pattern"),
376
+ undefined,
377
+ [ts.factory.createIdentifier(`/${t.value}/`)],
378
+ );
379
+
380
+ const tail = RandomRanger.length(COALESCE(importer))({
381
+ minimum: 5,
382
+ maximum: 25,
383
+ gap: 5,
384
+ })({
385
+ fixed: "length",
386
+ minimum: "minLength",
387
+ maximum: "maxLength",
388
+ })(tags);
389
+ return ts.factory.createCallExpression(
390
+ COALESCE(importer)("string"),
391
+ undefined,
392
+ tail ? [tail] : undefined,
393
+ );
394
+ })(),
395
+ );
396
+ }
397
+
398
+ type Atomic = boolean | number | string | bigint;
399
+ interface IExplore {
400
+ object: boolean;
401
+ recursive: boolean;
402
+ }
403
+
404
+ const FUNCTOR = (i: number) => `$ro${i}`;
405
+ const COALESCE = (importer: FunctionImporter) => (name: string) =>
406
+ ExpressionFactory.coalesce(
407
+ ts.factory.createPropertyAccessChain(
408
+ ts.factory.createIdentifier("generator"),
409
+ ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
410
+ ts.factory.createIdentifier(name),
411
+ ),
412
+ IdentifierFactory.join(importer.use("generator"), name),
413
+ );