typia 7.0.0-dev.20240920 → 7.0.0-dev.20240921

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.
@@ -13,130 +13,141 @@ import { Escaper } from "../../utils/Escaper";
13
13
  export namespace RandomJoiner {
14
14
  export type Decoder = (meta: Metadata) => ts.Expression;
15
15
 
16
- export const array =
17
- (coalesce: (method: string) => ts.Expression) =>
18
- (decoder: Decoder) =>
19
- (explore: IExplore) =>
20
- (length: ts.Expression | undefined, unique: ts.Expression | undefined) =>
21
- (item: Metadata): ts.Expression => {
22
- const generator: ts.Expression = ts.factory.createCallExpression(
23
- coalesce("array"),
24
- undefined,
25
- [
26
- ts.factory.createArrowFunction(
27
- undefined,
28
- undefined,
29
- [],
30
- undefined,
31
- undefined,
32
- decoder(item),
33
- ),
34
- ...(length
35
- ? [length]
36
- : unique
37
- ? [ts.factory.createIdentifier("undefined")]
38
- : []),
39
- ...(unique ? [unique] : []),
40
- ],
41
- );
42
- if (explore.recursive === false) return generator;
43
- return ts.factory.createConditionalExpression(
44
- ts.factory.createGreaterThanEquals(
45
- ExpressionFactory.number(5),
46
- ts.factory.createIdentifier("_depth"),
16
+ export const array = (props: {
17
+ coalesce: (method: string) => ts.Expression;
18
+ decode: Decoder;
19
+ explore: IExplore;
20
+ length: ts.Expression | undefined;
21
+ unique: ts.Expression | undefined;
22
+ metadata: Metadata;
23
+ }): ts.Expression => {
24
+ const generator: ts.Expression = ts.factory.createCallExpression(
25
+ props.coalesce("array"),
26
+ undefined,
27
+ [
28
+ ts.factory.createArrowFunction(
29
+ undefined,
30
+ undefined,
31
+ [],
32
+ undefined,
33
+ undefined,
34
+ props.decode(props.metadata),
47
35
  ),
48
- undefined,
49
- generator,
50
- undefined,
51
- ts.factory.createArrayLiteralExpression([]),
52
- );
53
- };
36
+ ...(props.length
37
+ ? [props.length]
38
+ : props.unique
39
+ ? [ts.factory.createIdentifier("undefined")]
40
+ : []),
41
+ ...(props.unique ? [props.unique] : []),
42
+ ],
43
+ );
44
+ if (props.explore.recursive === false) return generator;
45
+ return ts.factory.createConditionalExpression(
46
+ ts.factory.createGreaterThanEquals(
47
+ ExpressionFactory.number(5),
48
+ ts.factory.createIdentifier("_depth"),
49
+ ),
50
+ undefined,
51
+ generator,
52
+ undefined,
53
+ ts.factory.createArrayLiteralExpression([]),
54
+ );
55
+ };
54
56
 
55
- export const tuple = (decoder: Decoder) => (elements: Metadata[]) =>
57
+ export const tuple = (props: { decode: Decoder; elements: Metadata[] }) =>
56
58
  ts.factory.createArrayLiteralExpression(
57
- elements.map((elem) => decoder(elem.rest ?? elem)),
59
+ props.elements.map((elem) => props.decode(elem.rest ?? elem)),
58
60
  true,
59
61
  );
60
62
 
61
- export const object =
62
- (coalesce: (method: string) => ts.Expression) =>
63
- (decoder: Decoder) =>
64
- (obj: MetadataObject): ts.ConciseBody => {
65
- if (obj.properties.length === 0) return ts.factory.createIdentifier("{}");
63
+ export const object = (props: {
64
+ coalesce: (method: string) => ts.Expression;
65
+ decode: Decoder;
66
+ object: MetadataObject;
67
+ }): ts.ConciseBody => {
68
+ if (props.object.properties.length === 0)
69
+ return ts.factory.createIdentifier("{}");
66
70
 
67
- // LIST UP PROPERTIES
68
- const regular = obj.properties.filter((p) => p.key.isSoleLiteral());
69
- const dynamic = obj.properties.filter((p) => !p.key.isSoleLiteral());
71
+ // LIST UP PROPERTIES
72
+ const regular = props.object.properties.filter((p) =>
73
+ p.key.isSoleLiteral(),
74
+ );
75
+ const dynamic = props.object.properties.filter(
76
+ (p) => !p.key.isSoleLiteral(),
77
+ );
70
78
 
71
- // REGULAR OBJECT
72
- const literal: ts.ObjectLiteralExpression =
73
- ts.factory.createObjectLiteralExpression(
74
- regular.map((p) => {
75
- const str: string = p.key.getSoleLiteral()!;
76
- return ts.factory.createPropertyAssignment(
77
- Escaper.variable(str) ? str : ts.factory.createStringLiteral(str),
78
- decoder(p.value),
79
- );
80
- }),
81
- true,
82
- );
83
- if (dynamic.length === 0) return literal;
79
+ // REGULAR OBJECT
80
+ const literal: ts.ObjectLiteralExpression =
81
+ ts.factory.createObjectLiteralExpression(
82
+ regular.map((p) => {
83
+ const str: string = p.key.getSoleLiteral()!;
84
+ return ts.factory.createPropertyAssignment(
85
+ Escaper.variable(str) ? str : ts.factory.createStringLiteral(str),
86
+ props.decode(p.value),
87
+ );
88
+ }),
89
+ true,
90
+ );
91
+ if (dynamic.length === 0) return literal;
84
92
 
85
- const properties: ts.Statement[] = dynamic.map((p) =>
86
- ts.factory.createExpressionStatement(
87
- dynamicProperty(coalesce)(decoder)(p),
93
+ const properties: ts.Statement[] = dynamic.map((p) =>
94
+ ts.factory.createExpressionStatement(
95
+ dynamicProperty({
96
+ coalesce: props.coalesce,
97
+ decode: props.decode,
98
+ property: p,
99
+ }),
100
+ ),
101
+ );
102
+ return ts.factory.createBlock(
103
+ [
104
+ StatementFactory.constant(
105
+ "output",
106
+ ts.factory.createAsExpression(literal, TypeFactory.keyword("any")),
88
107
  ),
89
- );
90
- return ts.factory.createBlock(
91
- [
92
- StatementFactory.constant(
93
- "output",
94
- ts.factory.createAsExpression(literal, TypeFactory.keyword("any")),
95
- ),
96
- ...(obj.recursive
97
- ? [
98
- ts.factory.createIfStatement(
99
- ts.factory.createGreaterThanEquals(
100
- ExpressionFactory.number(5),
101
- ts.factory.createIdentifier("_depth"),
102
- ),
103
- ts.factory.createBlock(properties, true),
108
+ ...(props.object.recursive
109
+ ? [
110
+ ts.factory.createIfStatement(
111
+ ts.factory.createGreaterThanEquals(
112
+ ExpressionFactory.number(5),
113
+ ts.factory.createIdentifier("_depth"),
104
114
  ),
105
- ]
106
- : properties),
107
- ts.factory.createReturnStatement(
108
- ts.factory.createIdentifier("output"),
109
- ),
110
- ],
111
- true,
112
- );
113
- };
115
+ ts.factory.createBlock(properties, true),
116
+ ),
117
+ ]
118
+ : properties),
119
+ ts.factory.createReturnStatement(ts.factory.createIdentifier("output")),
120
+ ],
121
+ true,
122
+ );
123
+ };
114
124
 
115
- const dynamicProperty =
116
- (coalesce: (method: string) => ts.Expression) =>
117
- (decoder: Decoder) =>
118
- (p: MetadataProperty) =>
119
- ts.factory.createCallExpression(coalesce("array"), undefined, [
120
- ts.factory.createArrowFunction(
121
- undefined,
122
- undefined,
123
- [],
124
- undefined,
125
- undefined,
126
- ts.factory.createBinaryExpression(
127
- ts.factory.createElementAccessExpression(
128
- ts.factory.createIdentifier("output"),
129
- decoder(p.key),
130
- ),
131
- ts.factory.createToken(ts.SyntaxKind.EqualsToken),
132
- decoder(p.value),
125
+ const dynamicProperty = (props: {
126
+ coalesce: (method: string) => ts.Expression;
127
+ decode: Decoder;
128
+ property: MetadataProperty;
129
+ }) =>
130
+ ts.factory.createCallExpression(props.coalesce("array"), undefined, [
131
+ ts.factory.createArrowFunction(
132
+ undefined,
133
+ undefined,
134
+ [],
135
+ undefined,
136
+ undefined,
137
+ ts.factory.createBinaryExpression(
138
+ ts.factory.createElementAccessExpression(
139
+ ts.factory.createIdentifier("output"),
140
+ props.decode(props.property.key),
133
141
  ),
142
+ ts.factory.createToken(ts.SyntaxKind.EqualsToken),
143
+ props.decode(props.property.value),
134
144
  ),
135
- ts.factory.createCallExpression(coalesce("integer"), undefined, [
136
- ExpressionFactory.number(0),
137
- ExpressionFactory.number(3),
138
- ]),
139
- ]);
145
+ ),
146
+ ts.factory.createCallExpression(props.coalesce("integer"), undefined, [
147
+ ExpressionFactory.number(0),
148
+ ExpressionFactory.number(3),
149
+ ]),
150
+ ]);
140
151
  }
141
152
 
142
153
  interface IExplore {
@@ -11,34 +11,46 @@ export namespace RandomRanger {
11
11
  gap: number;
12
12
  }
13
13
 
14
- export const length =
15
- (coalesce: (method: string) => ts.Expression) =>
16
- (defs: IDefaults) =>
17
- (acc: length.IAccessors) =>
18
- (tags: IMetadataTypeTag[]): ts.Expression | undefined => {
19
- const props = {
20
- minimum: getter(tags)(acc.minimum),
21
- maximum: getter(tags)(acc.maximum),
22
- };
23
- if (props.minimum === undefined && props.maximum === undefined)
24
- return undefined;
14
+ export const length = (props: {
15
+ coalesce: (method: string) => ts.Expression;
16
+ defaults: IDefaults;
17
+ accessors: length.IAccessors;
18
+ tags: IMetadataTypeTag[];
19
+ }): ts.Expression | undefined => {
20
+ const range = {
21
+ minimum: take({
22
+ kind: props.accessors.minimum,
23
+ tags: props.tags,
24
+ }),
25
+ maximum: take({
26
+ kind: props.accessors.maximum,
27
+ tags: props.tags,
28
+ }),
29
+ };
30
+ if (range.minimum === undefined && range.maximum === undefined)
31
+ return undefined;
25
32
 
26
- if (props.maximum !== undefined && props.minimum === undefined) {
27
- if (props.maximum <= 0) {
28
- props.maximum = 0;
29
- props.minimum = 0;
30
- } else if (props.maximum < defs.gap)
31
- props.minimum = defs.minimum === 0 ? 0 : 1;
32
- }
33
- props.minimum ??= defs.minimum;
34
- props.maximum ??= defs.maximum;
35
- if (props.maximum < props.minimum) (props.maximum as number) += defs.gap;
33
+ if (range.maximum !== undefined && range.minimum === undefined) {
34
+ if (range.maximum <= 0) {
35
+ range.maximum = 0;
36
+ range.minimum = 0;
37
+ } else if (range.maximum < props.defaults.gap)
38
+ range.minimum = props.defaults.minimum === 0 ? 0 : 1;
39
+ }
40
+ range.minimum ??= props.defaults.minimum;
41
+ range.maximum ??= props.defaults.maximum;
42
+ if (range.maximum < range.minimum)
43
+ (range.maximum as number) += props.defaults.gap;
36
44
 
37
- return ts.factory.createCallExpression(coalesce("integer"), undefined, [
38
- ExpressionFactory.number(props.minimum),
39
- ExpressionFactory.number(props.maximum),
40
- ]);
41
- };
45
+ return ts.factory.createCallExpression(
46
+ props.coalesce("integer"),
47
+ undefined,
48
+ [
49
+ ExpressionFactory.number(range.minimum),
50
+ ExpressionFactory.number(range.maximum),
51
+ ],
52
+ );
53
+ };
42
54
  export namespace length {
43
55
  export interface IAccessors {
44
56
  minimum: string;
@@ -46,79 +58,109 @@ export namespace RandomRanger {
46
58
  }
47
59
  }
48
60
 
49
- export const number =
50
- (config: number.IConfig) =>
51
- (defs: IDefaults) =>
52
- (tags: IMetadataTypeTag[]): ts.Expression => {
53
- const range = {
54
- minimum: {
55
- value: getter(tags)("minimum") ?? getter(tags)("exclusiveMinimum"),
56
- exclusive: getter(tags)("exclusiveMinimum") !== undefined,
57
- },
58
- maximum: {
59
- value: getter(tags)("maximum") ?? getter(tags)("exclusiveMaximum"),
60
- exclusive: getter(tags)("exclusiveMaximum") !== undefined,
61
- },
62
- stepper: undefined,
63
- multiply: getter(tags)("multipleOf"),
64
- };
61
+ export const number = (props: {
62
+ config: number.IConfig;
63
+ defaults: IDefaults;
64
+ tags: IMetadataTypeTag[];
65
+ }): ts.Expression => {
66
+ const range = {
67
+ minimum: {
68
+ value:
69
+ take({
70
+ kind: "minimum",
71
+ tags: props.tags,
72
+ }) ??
73
+ take({
74
+ kind: "exclusiveMinimum",
75
+ tags: props.tags,
76
+ }),
77
+ exclusive:
78
+ take({
79
+ kind: "exclusiveMinimum",
80
+ tags: props.tags,
81
+ }) !== undefined,
82
+ },
83
+ maximum: {
84
+ value:
85
+ take({
86
+ kind: "maximum",
87
+ tags: props.tags,
88
+ }) ??
89
+ take({
90
+ tags: props.tags,
91
+ kind: "exclusiveMaximum",
92
+ }),
93
+ exclusive:
94
+ take({
95
+ kind: "exclusiveMaximum",
96
+ tags: props.tags,
97
+ }) !== undefined,
98
+ },
99
+ stepper: undefined,
100
+ multiply: take({
101
+ kind: "multipleOf",
102
+ tags: props.tags,
103
+ }),
104
+ };
65
105
 
66
- //----
67
- // MULTIPLIERS
68
- //----
69
- if (range.multiply !== undefined) {
70
- const { minimum, maximum } = multiplier(defs.gap)(range)(
71
- range.multiply,
72
- );
73
- return ts.factory.createMultiply(
74
- config.transform(range.multiply),
75
- config.setter([minimum, maximum]),
76
- );
77
- }
106
+ //----
107
+ // MULTIPLIERS
108
+ //----
109
+ if (range.multiply !== undefined) {
110
+ const { minimum, maximum } = multiplier({
111
+ gap: props.defaults.gap,
112
+ range,
113
+ value: range.multiply,
114
+ });
115
+ return ts.factory.createMultiply(
116
+ props.config.transform(range.multiply),
117
+ props.config.setter([minimum, maximum]),
118
+ );
119
+ }
78
120
 
79
- //----
80
- // RANGE
81
- //----
82
- // INT
83
- const integer = (value: number) => value === Math.floor(value);
84
- if (config.type === "int" || config.type === "uint") {
85
- if (range.minimum.value !== undefined) {
86
- if (range.minimum.exclusive) {
87
- range.minimum.exclusive = false;
88
- if (integer(range.minimum.value)) range.minimum.value += 1;
89
- }
90
- range.minimum.value = Math.ceil(range.minimum.value);
121
+ //----
122
+ // RANGE
123
+ //----
124
+ // INT
125
+ const integer = (value: number) => value === Math.floor(value);
126
+ if (props.config.type === "int" || props.config.type === "uint") {
127
+ if (range.minimum.value !== undefined) {
128
+ if (range.minimum.exclusive) {
129
+ range.minimum.exclusive = false;
130
+ if (integer(range.minimum.value)) range.minimum.value += 1;
91
131
  }
92
- if (range.maximum.value !== undefined) {
93
- if (range.maximum.exclusive) {
94
- range.maximum.exclusive = false;
95
- if (integer(range.maximum.value)) range.maximum.value -= 1;
96
- }
97
- range.maximum.value = Math.floor(range.maximum.value);
132
+ range.minimum.value = Math.ceil(range.minimum.value);
133
+ }
134
+ if (range.maximum.value !== undefined) {
135
+ if (range.maximum.exclusive) {
136
+ range.maximum.exclusive = false;
137
+ if (integer(range.maximum.value)) range.maximum.value -= 1;
98
138
  }
139
+ range.maximum.value = Math.floor(range.maximum.value);
99
140
  }
141
+ }
100
142
 
101
- // UNSIGNED INT
102
- if (config.type === "uint") {
103
- if (range.minimum.value === undefined) range.minimum.value = 0;
104
- else if (range.minimum.value <= 0) {
105
- range.minimum.value = 0;
106
- range.minimum.exclusive = false;
107
- }
143
+ // UNSIGNED INT
144
+ if (props.config.type === "uint") {
145
+ if (range.minimum.value === undefined) range.minimum.value = 0;
146
+ else if (range.minimum.value <= 0) {
147
+ range.minimum.value = 0;
148
+ range.minimum.exclusive = false;
108
149
  }
150
+ }
109
151
 
110
- const minimum =
111
- range.minimum.value ??
112
- (range.maximum.value !== undefined
113
- ? range.maximum.value - defs.gap
114
- : defs.minimum);
115
- const maximum =
116
- range.maximum.value ??
117
- (range.minimum.value !== undefined
118
- ? range.minimum.value + defs.gap
119
- : defs.maximum);
120
- return config.setter([minimum, maximum]);
121
- };
152
+ const minimum =
153
+ range.minimum.value ??
154
+ (range.maximum.value !== undefined
155
+ ? range.maximum.value - props.defaults.gap
156
+ : props.defaults.minimum);
157
+ const maximum =
158
+ range.maximum.value ??
159
+ (range.minimum.value !== undefined
160
+ ? range.minimum.value + props.defaults.gap
161
+ : props.defaults.maximum);
162
+ return props.config.setter([minimum, maximum]);
163
+ };
122
164
  export namespace number {
123
165
  export interface IConfig {
124
166
  setter: (args: number[]) => ts.Expression;
@@ -128,36 +170,41 @@ export namespace RandomRanger {
128
170
  }
129
171
  }
130
172
 
131
- const getter =
132
- (tags: IMetadataTypeTag[]) =>
133
- (kind: string): number | undefined => {
134
- const value: bigint | number | undefined = tags.find(
135
- (t) =>
136
- t.kind === kind &&
137
- (typeof t.value === "number" || typeof t.value === "bigint"),
138
- )?.value;
139
- return value !== undefined ? Number(value) : undefined;
140
- };
173
+ const take = (props: {
174
+ kind: string;
175
+ tags: IMetadataTypeTag[];
176
+ }): number | undefined => {
177
+ const value: bigint | number | undefined = props.tags.find(
178
+ (t) =>
179
+ t.kind === props.kind &&
180
+ (typeof t.value === "number" || typeof t.value === "bigint"),
181
+ )?.value;
182
+ return value !== undefined ? Number(value) : undefined;
183
+ };
141
184
 
142
- const multiplier = (gap: number) => (range: IRange) => (m: number) => {
185
+ const multiplier = (props: { range: IRange; gap: number; value: number }) => {
143
186
  const minimum: number =
144
- range.minimum.value === undefined
187
+ props.range.minimum.value === undefined
145
188
  ? 0
146
189
  : (() => {
147
- const x: number = m * Math.ceil(range.minimum.value / m);
148
- return range.minimum.exclusive && x === range.minimum.value
149
- ? x + m
190
+ const x: number =
191
+ props.value * Math.ceil(props.range.minimum.value / props.value);
192
+ return props.range.minimum.exclusive &&
193
+ x === props.range.minimum.value
194
+ ? x + props.value
150
195
  : x;
151
- })() / m;
196
+ })() / props.value;
152
197
  const maximum: number =
153
- range.maximum.value === undefined
154
- ? gap
198
+ props.range.maximum.value === undefined
199
+ ? props.gap
155
200
  : (() => {
156
- const y: number = m * Math.floor(range.maximum.value / m);
157
- return range.maximum.exclusive && y === range.maximum.value
158
- ? y - m
201
+ const y: number =
202
+ props.value * Math.floor(props.range.maximum.value / props.value);
203
+ return props.range.maximum.exclusive &&
204
+ y === props.range.maximum.value
205
+ ? y - props.value
159
206
  : y;
160
- })() / m;
207
+ })() / props.value;
161
208
  return { minimum, maximum };
162
209
  };
163
210
 
@@ -9,52 +9,54 @@ import { FunctionImporter } from "./FunctionImporter";
9
9
  import { IExpressionEntry } from "./IExpressionEntry";
10
10
 
11
11
  export namespace StringifyJoiner {
12
- export const object =
13
- (importer: FunctionImporter) =>
14
- (props: { entries: IExpressionEntry<ts.Expression>[] }): ts.Expression => {
15
- // CHECK AND SORT ENTRIES
16
- if (props.entries.length === 0)
17
- return ts.factory.createStringLiteral("{}");
12
+ export const object = (props: {
13
+ importer: FunctionImporter;
14
+ entries: IExpressionEntry<ts.Expression>[];
15
+ }): ts.Expression => {
16
+ // CHECK AND SORT ENTRIES
17
+ if (props.entries.length === 0) return ts.factory.createStringLiteral("{}");
18
18
 
19
- // PROPERTIES
20
- const regular: IExpressionEntry<ts.Expression>[] = props.entries.filter(
21
- (entry) => entry.key.isSoleLiteral(),
22
- );
23
- const dynamic: IExpressionEntry<ts.Expression>[] = props.entries.filter(
24
- (entry) => !entry.key.isSoleLiteral(),
25
- );
26
- const expressions: ts.Expression[] = [
27
- ...stringify_regular_properties(regular, dynamic),
28
- ...(dynamic.length
29
- ? [
30
- stringify_dynamic_properties(
31
- dynamic,
32
- regular.map((r) => r.key.getSoleLiteral()!),
33
- ),
34
- ]
35
- : []),
36
- ];
19
+ // PROPERTIES
20
+ const regular: IExpressionEntry<ts.Expression>[] = props.entries.filter(
21
+ (entry) => entry.key.isSoleLiteral(),
22
+ );
23
+ const dynamic: IExpressionEntry<ts.Expression>[] = props.entries.filter(
24
+ (entry) => !entry.key.isSoleLiteral(),
25
+ );
26
+ const expressions: ts.Expression[] = [
27
+ ...stringify_regular_properties(regular, dynamic),
28
+ ...(dynamic.length
29
+ ? [
30
+ stringify_dynamic_properties(
31
+ dynamic,
32
+ regular.map((r) => r.key.getSoleLiteral()!),
33
+ ),
34
+ ]
35
+ : []),
36
+ ];
37
37
 
38
- // POP LAST COMMA, IF REQUIRED
39
- const filtered: ts.Expression[] =
40
- (regular.length &&
41
- regular[regular.length - 1]!.meta.isRequired() &&
42
- dynamic.length === 0) ||
43
- (regular.length === 0 && dynamic.length)
44
- ? expressions
45
- : [
46
- ts.factory.createCallExpression(importer.use("tail"), undefined, [
47
- TemplateFactory.generate(expressions),
48
- ]),
49
- ];
38
+ // POP LAST COMMA, IF REQUIRED
39
+ const filtered: ts.Expression[] =
40
+ (regular.length &&
41
+ regular[regular.length - 1]!.meta.isRequired() &&
42
+ dynamic.length === 0) ||
43
+ (regular.length === 0 && dynamic.length)
44
+ ? expressions
45
+ : [
46
+ ts.factory.createCallExpression(
47
+ props.importer.use("tail"),
48
+ undefined,
49
+ [TemplateFactory.generate(expressions)],
50
+ ),
51
+ ];
50
52
 
51
- // RETURNS WITH OBJECT BRACKET
52
- return TemplateFactory.generate([
53
- ts.factory.createStringLiteral(`{`),
54
- ...filtered,
55
- ts.factory.createStringLiteral(`}`),
56
- ]);
57
- };
53
+ // RETURNS WITH OBJECT BRACKET
54
+ return TemplateFactory.generate([
55
+ ts.factory.createStringLiteral(`{`),
56
+ ...filtered,
57
+ ts.factory.createStringLiteral(`}`),
58
+ ]);
59
+ };
58
60
 
59
61
  export const array = (props: {
60
62
  input: ts.Expression;