Skip to content

Commit c074cdd

Browse files
committed
fix(openapi-typescript): fix array minItems/maxItems tuple generation algorithm
The loop was incorrectly generating tuples from 0 to (max-min) elements instead of min to max elements. For example, minItems: 1, maxItems: 3 was producing [] | [T] | [T, T] instead of [T] | [T, T] | [T, T, T].
1 parent e9d3c68 commit c074cdd

File tree

2 files changed

+98
-3
lines changed

2 files changed

+98
-3
lines changed

packages/openapi-typescript/src/transform/schema-object.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,9 @@ function transformSchemaObjectCore(schemaObject: SchemaObject, options: Transfor
381381
} else if ((schemaObject.maxItems as number) > 0) {
382382
// if maxItems is set, then return a union of all permutations of possible tuple types
383383
const members: ts.TypeNode[] = [];
384-
// populate 1 short of min …
385-
for (let i = 0; i <= (max ?? 0) - min; i++) {
384+
for (let i = min; i <= (max ?? 0); i++) {
386385
const elements: ts.TypeNode[] = [];
387-
for (let j = min; j < i + min; j++) {
386+
for (let j = 0; j < i; j++) {
388387
elements.push(itemType);
389388
}
390389
members.push(ts.factory.createTupleTypeNode(elements));

packages/openapi-typescript/test/transform/schema-object/array.test.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,102 @@ describe("transformSchemaObject > array", () => {
161161
want: `[
162162
string,
163163
string
164+
]`,
165+
options: {
166+
...DEFAULT_OPTIONS,
167+
ctx: { ...DEFAULT_OPTIONS.ctx, arrayLength: true },
168+
},
169+
},
170+
],
171+
[
172+
"options > arrayLength: true > minItems: 1, maxItems: 3",
173+
{
174+
given: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 3 },
175+
want: `[
176+
string
177+
] | [
178+
string,
179+
string
180+
] | [
181+
string,
182+
string,
183+
string
184+
]`,
185+
options: {
186+
...DEFAULT_OPTIONS,
187+
ctx: { ...DEFAULT_OPTIONS.ctx, arrayLength: true },
188+
},
189+
},
190+
],
191+
[
192+
"options > arrayLength: true > minItems: 0, maxItems: 2 (starts from empty)",
193+
{
194+
given: { type: "array", items: { type: "string" }, minItems: 0, maxItems: 2 },
195+
want: `[
196+
] | [
197+
string
198+
] | [
199+
string,
200+
string
201+
]`,
202+
options: {
203+
...DEFAULT_OPTIONS,
204+
ctx: { ...DEFAULT_OPTIONS.ctx, arrayLength: true },
205+
},
206+
},
207+
],
208+
[
209+
"options > arrayLength: true > minItems: 3, maxItems: 5 (larger range)",
210+
{
211+
given: { type: "array", items: { type: "number" }, minItems: 3, maxItems: 5 },
212+
want: `[
213+
number,
214+
number,
215+
number
216+
] | [
217+
number,
218+
number,
219+
number,
220+
number
221+
] | [
222+
number,
223+
number,
224+
number,
225+
number,
226+
number
227+
]`,
228+
options: {
229+
...DEFAULT_OPTIONS,
230+
ctx: { ...DEFAULT_OPTIONS.ctx, arrayLength: true },
231+
},
232+
},
233+
],
234+
[
235+
"options > arrayLength: true > minItems: 2, maxItems: 3 with object items",
236+
{
237+
given: {
238+
type: "array",
239+
items: { type: "object", properties: { id: { type: "string" } } },
240+
minItems: 2,
241+
maxItems: 3,
242+
},
243+
want: `[
244+
{
245+
id?: string;
246+
},
247+
{
248+
id?: string;
249+
}
250+
] | [
251+
{
252+
id?: string;
253+
},
254+
{
255+
id?: string;
256+
},
257+
{
258+
id?: string;
259+
}
164260
]`,
165261
options: {
166262
...DEFAULT_OPTIONS,

0 commit comments

Comments
 (0)