typia 3.7.1 → 3.7.2

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 (53) hide show
  1. package/README.md +3 -1
  2. package/lib/module.d.ts +33 -0
  3. package/lib/module.js +5 -1
  4. package/lib/module.js.map +1 -1
  5. package/lib/programmers/LiteralsProgrammer.d.ts +5 -0
  6. package/lib/programmers/LiteralsProgrammer.js +75 -0
  7. package/lib/programmers/LiteralsProgrammer.js.map +1 -0
  8. package/lib/transformers/CallExpressionTransformer.js +2 -0
  9. package/lib/transformers/CallExpressionTransformer.js.map +1 -1
  10. package/lib/transformers/ImportTransformer.js +8 -1
  11. package/lib/transformers/ImportTransformer.js.map +1 -1
  12. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js +6 -3
  13. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js.map +1 -1
  14. package/lib/transformers/features/miscellaneous/CreateRandomTransformer.js +4 -2
  15. package/lib/transformers/features/miscellaneous/CreateRandomTransformer.js.map +1 -1
  16. package/lib/transformers/features/miscellaneous/LiteralsTransformer.d.ts +5 -0
  17. package/lib/transformers/features/miscellaneous/LiteralsTransformer.js +21 -0
  18. package/lib/transformers/features/miscellaneous/LiteralsTransformer.js.map +1 -0
  19. package/lib/transformers/features/miscellaneous/MetadataTransformer.js +4 -2
  20. package/lib/transformers/features/miscellaneous/MetadataTransformer.js.map +1 -1
  21. package/lib/transformers/features/miscellaneous/RandomTransformer.js +4 -2
  22. package/lib/transformers/features/miscellaneous/RandomTransformer.js.map +1 -1
  23. package/package.json +2 -2
  24. package/src/IRandomGenerator.ts +33 -33
  25. package/src/factories/IdentifierFactory.ts +81 -81
  26. package/src/factories/MetadataTagFactory.ts +302 -302
  27. package/src/metadata/ICommentTag.ts +4 -4
  28. package/src/module.ts +43 -0
  29. package/src/programmers/LiteralsProgrammer.ts +65 -0
  30. package/src/programmers/RandomProgrammer.ts +413 -413
  31. package/src/programmers/helpers/RandomJoiner.ts +161 -161
  32. package/src/programmers/helpers/RandomRanger.ts +216 -216
  33. package/src/programmers/internal/application_native.ts +32 -32
  34. package/src/programmers/internal/check_array.ts +30 -30
  35. package/src/programmers/internal/check_array_length.ts +35 -35
  36. package/src/programmers/internal/check_custom.ts +33 -33
  37. package/src/programmers/internal/check_number.ts +177 -177
  38. package/src/programmers/internal/check_object.ts +55 -55
  39. package/src/programmers/internal/check_union_array_like.ts +272 -272
  40. package/src/programmers/internal/feature_object_entries.ts +63 -63
  41. package/src/programmers/internal/get_comment_tags.ts +23 -23
  42. package/src/programmers/internal/metadata_to_pattern.ts +34 -34
  43. package/src/programmers/internal/random_custom.ts +30 -30
  44. package/src/programmers/internal/stringify_dynamic_properties.ts +168 -168
  45. package/src/programmers/internal/stringify_regular_properties.ts +84 -84
  46. package/src/transformers/CallExpressionTransformer.ts +174 -172
  47. package/src/transformers/ImportTransformer.ts +9 -3
  48. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +8 -9
  49. package/src/transformers/features/miscellaneous/CreateRandomTransformer.ts +41 -43
  50. package/src/transformers/features/miscellaneous/LiteralsTransformer.ts +30 -0
  51. package/src/transformers/features/miscellaneous/MetadataTransformer.ts +5 -6
  52. package/src/transformers/features/miscellaneous/RandomTransformer.ts +6 -8
  53. package/src/typings/Customizable.ts +5 -5
@@ -1,216 +1,216 @@
1
- import ts from "typescript";
2
-
3
- import { IMetadataTag } from "../../metadata/IMetadataTag";
4
-
5
- export namespace RandomRanger {
6
- export interface IDefaults {
7
- minimum: number;
8
- maximum: number;
9
- gap: number;
10
- }
11
-
12
- export const length =
13
- (coalesce: (method: string) => ts.Expression) =>
14
- (defs: IDefaults) =>
15
- (acc: length.IAccessors) =>
16
- (tags: IMetadataTag[]): ts.Expression | undefined => {
17
- const props = {
18
- fixed: getter(tags)(acc.fixed),
19
- minimum: getter(tags)(acc.minimum),
20
- maximum: getter(tags)(acc.maximum),
21
- };
22
- if (props.fixed !== undefined)
23
- return ts.factory.createNumericLiteral(props.fixed);
24
- else if (props.minimum === undefined && props.maximum === undefined)
25
- return undefined;
26
-
27
- props.minimum ??= defs.minimum;
28
- props.maximum ??= defs.maximum;
29
- if (props.maximum <= props.minimum)
30
- (props.maximum as number) += defs.gap;
31
-
32
- return ts.factory.createCallExpression(
33
- coalesce("integer"),
34
- undefined,
35
- [
36
- ts.factory.createNumericLiteral(props.minimum),
37
- ts.factory.createNumericLiteral(props.maximum),
38
- ],
39
- );
40
- };
41
- export namespace length {
42
- export interface IAccessors {
43
- minimum: IMetadataTag["kind"];
44
- maximum: IMetadataTag["kind"];
45
- fixed: IMetadataTag["kind"];
46
- }
47
- }
48
-
49
- export const number =
50
- (config: number.IConfig) =>
51
- (defs: IDefaults) =>
52
- (tags: IMetadataTag[]): ts.Expression => {
53
- const range = {
54
- minimum: {
55
- value:
56
- getter(tags)("minimum") ??
57
- getter(tags)("exclusiveMinimum"),
58
- exclusive: getter(tags)("exclusiveMinimum") !== undefined,
59
- },
60
- maximum: {
61
- value:
62
- getter(tags)("maximum") ??
63
- getter(tags)("exclusiveMaximum"),
64
- exclusive: getter(tags)("exclusiveMaximum") !== undefined,
65
- },
66
- step: getter(tags)("step"),
67
- multiply: getter(tags)("multipleOf"),
68
- };
69
- if (Object.values(range).every((v) => v !== undefined))
70
- return config.setter([]);
71
-
72
- //----
73
- // MULTIPLIERS
74
- //----
75
- // STEP
76
- if (range.step !== undefined) {
77
- const { intercept, minimum, maximum } = stepper(defs.gap)(
78
- range,
79
- )(range.step);
80
- return ts.factory.createAdd(
81
- config.transform(intercept),
82
- ts.factory.createMultiply(
83
- config.transform(range.step),
84
- config.setter([minimum, maximum]),
85
- ),
86
- );
87
- }
88
- // MULTIPLE-OF
89
- else if (range.multiply !== undefined) {
90
- const { minimum, maximum } = multiplier(defs.gap)(range)(
91
- range.multiply,
92
- );
93
- return ts.factory.createMultiply(
94
- config.transform(range.multiply),
95
- config.setter([minimum, maximum]),
96
- );
97
- }
98
-
99
- //----
100
- // RANGE
101
- //----
102
- // INT
103
- const integer = (value: number) => value === Math.floor(value);
104
- if (
105
- tags.find(
106
- (t) => t.kind === "type" && t.value.indexOf("int") !== -1,
107
- ) !== undefined
108
- ) {
109
- if (range.minimum.value !== undefined) {
110
- if (range.minimum.exclusive) {
111
- range.minimum.exclusive = false;
112
- if (integer(range.minimum.value))
113
- range.minimum.value += 1;
114
- }
115
- range.minimum.value = Math.ceil(range.minimum.value);
116
- }
117
- if (range.maximum.value !== undefined) {
118
- if (range.maximum.exclusive) {
119
- range.maximum.exclusive = false;
120
- if (integer(range.maximum.value))
121
- range.maximum.value -= 1;
122
- }
123
- range.maximum.value = Math.floor(range.maximum.value);
124
- }
125
- }
126
-
127
- // UNSIGNED INT
128
- if (
129
- tags.find(
130
- (t) => t.kind === "type" && t.value.indexOf("uint") === 0,
131
- ) !== undefined
132
- ) {
133
- if (range.minimum.value === undefined) range.minimum.value = 0;
134
- else if (range.minimum.value <= 0) {
135
- range.minimum.value = 0;
136
- range.minimum.exclusive = false;
137
- }
138
- }
139
-
140
- const minimum =
141
- range.minimum.value ??
142
- (range.maximum.value !== undefined
143
- ? range.maximum.value - defs.gap
144
- : defs.minimum);
145
- const maximum =
146
- range.maximum.value ??
147
- (range.minimum.value !== undefined
148
- ? range.minimum.value + defs.gap
149
- : defs.maximum);
150
- return config.setter([minimum, maximum]);
151
- };
152
- export namespace number {
153
- export interface IConfig {
154
- setter: (args: number[]) => ts.Expression;
155
- transform: (value: number) => ts.Expression;
156
- type: "int" | "uint" | "double";
157
- }
158
- }
159
- }
160
-
161
- const getter =
162
- (tags: IMetadataTag[]) =>
163
- (kind: IMetadataTag["kind"]): number | undefined =>
164
- tags.find((t) => t.kind === kind)?.value as number | undefined;
165
-
166
- const stepper = (gap: number) => (range: IRange) => (s: number) => {
167
- const intercept: number = range.minimum.value!;
168
- const minimum: number = range.minimum.exclusive ? 1 : 0;
169
- if (range.maximum.value === undefined)
170
- return {
171
- intercept,
172
- minimum,
173
- maximum: gap,
174
- };
175
-
176
- const y: number = Math.floor(range.maximum.value - intercept) / s;
177
- return {
178
- intercept,
179
- minimum,
180
- maximum:
181
- range.maximum.exclusive && intercept + y * s === range.maximum.value
182
- ? y - 1
183
- : y,
184
- };
185
- };
186
-
187
- const multiplier = (gap: number) => (range: IRange) => (m: number) => {
188
- const minimum: number =
189
- range.minimum.value === undefined
190
- ? 0
191
- : (() => {
192
- const x: number = m * Math.ceil(range.minimum.value / m);
193
- return range.minimum.exclusive && x === range.minimum.value
194
- ? x + m
195
- : x;
196
- })() / m;
197
- const maximum: number =
198
- range.maximum.value === undefined
199
- ? gap
200
- : (() => {
201
- const y: number = m * Math.floor(range.maximum.value / m);
202
- return range.maximum.exclusive && y === range.maximum.value
203
- ? y - m
204
- : y;
205
- })() / m;
206
- return { minimum, maximum };
207
- };
208
-
209
- interface IRange {
210
- minimum: IScalar;
211
- maximum: IScalar;
212
- }
213
- interface IScalar {
214
- value?: number;
215
- exclusive: boolean;
216
- }
1
+ import ts from "typescript";
2
+
3
+ import { IMetadataTag } from "../../metadata/IMetadataTag";
4
+
5
+ export namespace RandomRanger {
6
+ export interface IDefaults {
7
+ minimum: number;
8
+ maximum: number;
9
+ gap: number;
10
+ }
11
+
12
+ export const length =
13
+ (coalesce: (method: string) => ts.Expression) =>
14
+ (defs: IDefaults) =>
15
+ (acc: length.IAccessors) =>
16
+ (tags: IMetadataTag[]): ts.Expression | undefined => {
17
+ const props = {
18
+ fixed: getter(tags)(acc.fixed),
19
+ minimum: getter(tags)(acc.minimum),
20
+ maximum: getter(tags)(acc.maximum),
21
+ };
22
+ if (props.fixed !== undefined)
23
+ return ts.factory.createNumericLiteral(props.fixed);
24
+ else if (props.minimum === undefined && props.maximum === undefined)
25
+ return undefined;
26
+
27
+ props.minimum ??= defs.minimum;
28
+ props.maximum ??= defs.maximum;
29
+ if (props.maximum <= props.minimum)
30
+ (props.maximum as number) += defs.gap;
31
+
32
+ return ts.factory.createCallExpression(
33
+ coalesce("integer"),
34
+ undefined,
35
+ [
36
+ ts.factory.createNumericLiteral(props.minimum),
37
+ ts.factory.createNumericLiteral(props.maximum),
38
+ ],
39
+ );
40
+ };
41
+ export namespace length {
42
+ export interface IAccessors {
43
+ minimum: IMetadataTag["kind"];
44
+ maximum: IMetadataTag["kind"];
45
+ fixed: IMetadataTag["kind"];
46
+ }
47
+ }
48
+
49
+ export const number =
50
+ (config: number.IConfig) =>
51
+ (defs: IDefaults) =>
52
+ (tags: IMetadataTag[]): ts.Expression => {
53
+ const range = {
54
+ minimum: {
55
+ value:
56
+ getter(tags)("minimum") ??
57
+ getter(tags)("exclusiveMinimum"),
58
+ exclusive: getter(tags)("exclusiveMinimum") !== undefined,
59
+ },
60
+ maximum: {
61
+ value:
62
+ getter(tags)("maximum") ??
63
+ getter(tags)("exclusiveMaximum"),
64
+ exclusive: getter(tags)("exclusiveMaximum") !== undefined,
65
+ },
66
+ step: getter(tags)("step"),
67
+ multiply: getter(tags)("multipleOf"),
68
+ };
69
+ if (Object.values(range).every((v) => v !== undefined))
70
+ return config.setter([]);
71
+
72
+ //----
73
+ // MULTIPLIERS
74
+ //----
75
+ // STEP
76
+ if (range.step !== undefined) {
77
+ const { intercept, minimum, maximum } = stepper(defs.gap)(
78
+ range,
79
+ )(range.step);
80
+ return ts.factory.createAdd(
81
+ config.transform(intercept),
82
+ ts.factory.createMultiply(
83
+ config.transform(range.step),
84
+ config.setter([minimum, maximum]),
85
+ ),
86
+ );
87
+ }
88
+ // MULTIPLE-OF
89
+ else if (range.multiply !== undefined) {
90
+ const { minimum, maximum } = multiplier(defs.gap)(range)(
91
+ range.multiply,
92
+ );
93
+ return ts.factory.createMultiply(
94
+ config.transform(range.multiply),
95
+ config.setter([minimum, maximum]),
96
+ );
97
+ }
98
+
99
+ //----
100
+ // RANGE
101
+ //----
102
+ // INT
103
+ const integer = (value: number) => value === Math.floor(value);
104
+ if (
105
+ tags.find(
106
+ (t) => t.kind === "type" && t.value.indexOf("int") !== -1,
107
+ ) !== undefined
108
+ ) {
109
+ if (range.minimum.value !== undefined) {
110
+ if (range.minimum.exclusive) {
111
+ range.minimum.exclusive = false;
112
+ if (integer(range.minimum.value))
113
+ range.minimum.value += 1;
114
+ }
115
+ range.minimum.value = Math.ceil(range.minimum.value);
116
+ }
117
+ if (range.maximum.value !== undefined) {
118
+ if (range.maximum.exclusive) {
119
+ range.maximum.exclusive = false;
120
+ if (integer(range.maximum.value))
121
+ range.maximum.value -= 1;
122
+ }
123
+ range.maximum.value = Math.floor(range.maximum.value);
124
+ }
125
+ }
126
+
127
+ // UNSIGNED INT
128
+ if (
129
+ tags.find(
130
+ (t) => t.kind === "type" && t.value.indexOf("uint") === 0,
131
+ ) !== undefined
132
+ ) {
133
+ if (range.minimum.value === undefined) range.minimum.value = 0;
134
+ else if (range.minimum.value <= 0) {
135
+ range.minimum.value = 0;
136
+ range.minimum.exclusive = false;
137
+ }
138
+ }
139
+
140
+ const minimum =
141
+ range.minimum.value ??
142
+ (range.maximum.value !== undefined
143
+ ? range.maximum.value - defs.gap
144
+ : defs.minimum);
145
+ const maximum =
146
+ range.maximum.value ??
147
+ (range.minimum.value !== undefined
148
+ ? range.minimum.value + defs.gap
149
+ : defs.maximum);
150
+ return config.setter([minimum, maximum]);
151
+ };
152
+ export namespace number {
153
+ export interface IConfig {
154
+ setter: (args: number[]) => ts.Expression;
155
+ transform: (value: number) => ts.Expression;
156
+ type: "int" | "uint" | "double";
157
+ }
158
+ }
159
+ }
160
+
161
+ const getter =
162
+ (tags: IMetadataTag[]) =>
163
+ (kind: IMetadataTag["kind"]): number | undefined =>
164
+ tags.find((t) => t.kind === kind)?.value as number | undefined;
165
+
166
+ const stepper = (gap: number) => (range: IRange) => (s: number) => {
167
+ const intercept: number = range.minimum.value!;
168
+ const minimum: number = range.minimum.exclusive ? 1 : 0;
169
+ if (range.maximum.value === undefined)
170
+ return {
171
+ intercept,
172
+ minimum,
173
+ maximum: gap,
174
+ };
175
+
176
+ const y: number = Math.floor(range.maximum.value - intercept) / s;
177
+ return {
178
+ intercept,
179
+ minimum,
180
+ maximum:
181
+ range.maximum.exclusive && intercept + y * s === range.maximum.value
182
+ ? y - 1
183
+ : y,
184
+ };
185
+ };
186
+
187
+ const multiplier = (gap: number) => (range: IRange) => (m: number) => {
188
+ const minimum: number =
189
+ range.minimum.value === undefined
190
+ ? 0
191
+ : (() => {
192
+ const x: number = m * Math.ceil(range.minimum.value / m);
193
+ return range.minimum.exclusive && x === range.minimum.value
194
+ ? x + m
195
+ : x;
196
+ })() / m;
197
+ const maximum: number =
198
+ range.maximum.value === undefined
199
+ ? gap
200
+ : (() => {
201
+ const y: number = m * Math.floor(range.maximum.value / m);
202
+ return range.maximum.exclusive && y === range.maximum.value
203
+ ? y - m
204
+ : y;
205
+ })() / m;
206
+ return { minimum, maximum };
207
+ };
208
+
209
+ interface IRange {
210
+ minimum: IScalar;
211
+ maximum: IScalar;
212
+ }
213
+ interface IScalar {
214
+ value?: number;
215
+ exclusive: boolean;
216
+ }
@@ -1,32 +1,32 @@
1
- import { IJsonComponents } from "../../schemas/IJsonComponents";
2
-
3
- import { IJsonSchema } from "../../module";
4
- import { ApplicationProgrammer } from "../ApplicationProgrammer";
5
-
6
- /**
7
- * @internal
8
- */
9
- export const application_native =
10
- (options: ApplicationProgrammer.IOptions) =>
11
- (components: IJsonComponents) =>
12
- (name: string) =>
13
- (
14
- nullable: boolean,
15
- attribute: IJsonSchema.IAttribute,
16
- ): IJsonSchema.IReference => {
17
- const key: string = name + (nullable ? ".Nullable" : "");
18
- if (components.schemas[key] === undefined)
19
- components.schemas[key] = {
20
- type: "object",
21
- $id:
22
- options.purpose === "ajv"
23
- ? options.prefix + "/" + key
24
- : undefined,
25
- properties: {},
26
- nullable,
27
- };
28
- return {
29
- $ref: `#/components/schemas/${name}`,
30
- ...attribute,
31
- };
32
- };
1
+ import { IJsonComponents } from "../../schemas/IJsonComponents";
2
+
3
+ import { IJsonSchema } from "../../module";
4
+ import { ApplicationProgrammer } from "../ApplicationProgrammer";
5
+
6
+ /**
7
+ * @internal
8
+ */
9
+ export const application_native =
10
+ (options: ApplicationProgrammer.IOptions) =>
11
+ (components: IJsonComponents) =>
12
+ (name: string) =>
13
+ (
14
+ nullable: boolean,
15
+ attribute: IJsonSchema.IAttribute,
16
+ ): IJsonSchema.IReference => {
17
+ const key: string = name + (nullable ? ".Nullable" : "");
18
+ if (components.schemas[key] === undefined)
19
+ components.schemas[key] = {
20
+ type: "object",
21
+ $id:
22
+ options.purpose === "ajv"
23
+ ? options.prefix + "/" + key
24
+ : undefined,
25
+ properties: {},
26
+ nullable,
27
+ };
28
+ return {
29
+ $ref: `#/components/schemas/${name}`,
30
+ ...attribute,
31
+ };
32
+ };
@@ -1,30 +1,30 @@
1
- import ts from "typescript";
2
-
3
- import { ExpressionFactory } from "../../factories/ExpressionFactory";
4
- import { IdentifierFactory } from "../../factories/IdentifierFactory";
5
-
6
- import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
7
- import { IMetadataTag } from "../../metadata/IMetadataTag";
8
-
9
- import { FunctionImporter } from "../helpers/FunctionImporeter";
10
- import { ICheckEntry } from "../helpers/ICheckEntry";
11
- import { check_array_length } from "./check_array_length";
12
- import { check_custom } from "./check_custom";
13
-
14
- /**
15
- * @internal
16
- */
17
- export const check_array =
18
- (importer: FunctionImporter) =>
19
- (metaTags: IMetadataTag[]) =>
20
- (jsDocTags: IJsDocTagInfo[]) =>
21
- (input: ts.Expression): ICheckEntry => ({
22
- expression: ExpressionFactory.isArray(input),
23
- tags: [
24
- ...check_array_length(metaTags)(
25
- IdentifierFactory.join(input, "length"),
26
- ),
27
- ...check_custom("array", "Array")(importer)(jsDocTags)(input),
28
- // check custom array for legacy (3.7.0)
29
- ],
30
- });
1
+ import ts from "typescript";
2
+
3
+ import { ExpressionFactory } from "../../factories/ExpressionFactory";
4
+ import { IdentifierFactory } from "../../factories/IdentifierFactory";
5
+
6
+ import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
7
+ import { IMetadataTag } from "../../metadata/IMetadataTag";
8
+
9
+ import { FunctionImporter } from "../helpers/FunctionImporeter";
10
+ import { ICheckEntry } from "../helpers/ICheckEntry";
11
+ import { check_array_length } from "./check_array_length";
12
+ import { check_custom } from "./check_custom";
13
+
14
+ /**
15
+ * @internal
16
+ */
17
+ export const check_array =
18
+ (importer: FunctionImporter) =>
19
+ (metaTags: IMetadataTag[]) =>
20
+ (jsDocTags: IJsDocTagInfo[]) =>
21
+ (input: ts.Expression): ICheckEntry => ({
22
+ expression: ExpressionFactory.isArray(input),
23
+ tags: [
24
+ ...check_array_length(metaTags)(
25
+ IdentifierFactory.join(input, "length"),
26
+ ),
27
+ ...check_custom("array", "Array")(importer)(jsDocTags)(input),
28
+ // check custom array for legacy (3.7.0)
29
+ ],
30
+ });
@@ -1,35 +1,35 @@
1
- import ts from "typescript";
2
-
3
- import { IMetadataTag } from "../../metadata/IMetadataTag";
4
-
5
- /**
6
- * @internal
7
- */
8
- export const check_array_length =
9
- (metaTags: IMetadataTag[]) => (input: ts.Expression) =>
10
- metaTags
11
- .map((tag) => ({
12
- tag,
13
- expression:
14
- tag.kind === "items"
15
- ? ts.factory.createStrictEquality(
16
- ts.factory.createNumericLiteral(tag.value),
17
- input,
18
- )
19
- : tag.kind === "minItems"
20
- ? ts.factory.createLessThanEquals(
21
- ts.factory.createNumericLiteral(tag.value),
22
- input,
23
- )
24
- : tag.kind === "maxItems"
25
- ? ts.factory.createGreaterThanEquals(
26
- ts.factory.createNumericLiteral(tag.value),
27
- input,
28
- )
29
- : null!,
30
- }))
31
- .filter((tuple) => tuple.expression !== null)
32
- .map(({ tag, expression }) => ({
33
- expected: `Array.length (@${tag.kind} ${tag.value})`,
34
- expression,
35
- }));
1
+ import ts from "typescript";
2
+
3
+ import { IMetadataTag } from "../../metadata/IMetadataTag";
4
+
5
+ /**
6
+ * @internal
7
+ */
8
+ export const check_array_length =
9
+ (metaTags: IMetadataTag[]) => (input: ts.Expression) =>
10
+ metaTags
11
+ .map((tag) => ({
12
+ tag,
13
+ expression:
14
+ tag.kind === "items"
15
+ ? ts.factory.createStrictEquality(
16
+ ts.factory.createNumericLiteral(tag.value),
17
+ input,
18
+ )
19
+ : tag.kind === "minItems"
20
+ ? ts.factory.createLessThanEquals(
21
+ ts.factory.createNumericLiteral(tag.value),
22
+ input,
23
+ )
24
+ : tag.kind === "maxItems"
25
+ ? ts.factory.createGreaterThanEquals(
26
+ ts.factory.createNumericLiteral(tag.value),
27
+ input,
28
+ )
29
+ : null!,
30
+ }))
31
+ .filter((tuple) => tuple.expression !== null)
32
+ .map(({ tag, expression }) => ({
33
+ expected: `Array.length (@${tag.kind} ${tag.value})`,
34
+ expression,
35
+ }));