From 3a8b8a8bf434f58930568bdd91460be321c44a7b Mon Sep 17 00:00:00 2001 From: Patrick McLaughlin Date: Mon, 5 Feb 2024 15:28:51 -0500 Subject: [PATCH] fix: deduplicate enum values when simplifying unions --- packages/openapi-generator/src/optimize.ts | 20 ++++++++++--------- .../openapi-generator/test/optimize.test.ts | 17 ++++++++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/packages/openapi-generator/src/optimize.ts b/packages/openapi-generator/src/optimize.ts index 29795567..c245e2fe 100644 --- a/packages/openapi-generator/src/optimize.ts +++ b/packages/openapi-generator/src/optimize.ts @@ -42,17 +42,19 @@ export function simplifyUnion(schema: Schema, optimize: OptimizeFn): Schema { const innerSchemas = schema.schemas.map(optimize); - const literals: Record = { - string: [], - number: [], - integer: [], - boolean: [], - null: [], + const literals: Record> = { + string: new Set(), + number: new Set(), + integer: new Set(), + boolean: new Set(), + null: new Set(), }; const remainder: Schema[] = []; innerSchemas.forEach((innerSchema) => { if (isPrimitive(innerSchema) && innerSchema.enum !== undefined) { - literals[innerSchema.type].push(...innerSchema.enum); + innerSchema.enum.forEach((value) => { + literals[innerSchema.type].add(value); + }); } else { remainder.push(innerSchema); } @@ -62,8 +64,8 @@ export function simplifyUnion(schema: Schema, optimize: OptimizeFn): Schema { schemas: remainder, }; for (const [key, value] of Object.entries(literals)) { - if (value.length > 0) { - result.schemas.push({ type: key as any, enum: value }); + if (value.size > 0) { + result.schemas.push({ type: key as any, enum: Array.from(value) }); } } diff --git a/packages/openapi-generator/test/optimize.test.ts b/packages/openapi-generator/test/optimize.test.ts index 2de212cc..69238fa6 100644 --- a/packages/openapi-generator/test/optimize.test.ts +++ b/packages/openapi-generator/test/optimize.test.ts @@ -95,3 +95,20 @@ test('undefined property unions are simplified', () => { assert.deepStrictEqual(optimize(input), expected); }); + +test('enums are deduplicated', () => { + const input: Schema = { + type: 'union', + schemas: [ + { type: 'string', enum: ['foo'] }, + { type: 'string', enum: ['foo', 'bar'] }, + ], + }; + + const expected: Schema = { + type: 'string', + enum: ['foo', 'bar'], + }; + + assert.deepStrictEqual(optimize(input), expected); +});