From fad6ee96b3e338db54d64f3d875c9265e0e70c11 Mon Sep 17 00:00:00 2001 From: Gabriel Lam Date: Tue, 3 Oct 2023 15:30:25 -0700 Subject: [PATCH] fix(): Derive enum types correctly when defined as an array #2615 If an enum property is decorated with `isArray: true`, its type should be derived from the type of the enum item, rather than as an `array`. --- lib/services/schema-object-factory.ts | 8 +++- test/services/schema-object-factory.spec.ts | 44 ++++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/lib/services/schema-object-factory.ts b/lib/services/schema-object-factory.ts index 7120a5dea..a9ef89cda 100644 --- a/lib/services/schema-object-factory.ts +++ b/lib/services/schema-object-factory.ts @@ -300,8 +300,14 @@ export class SchemaObjectFactory { const $ref = getSchemaPath(enumName); if (!(enumName in schemas)) { + const enumType: string = ( + metadata.isArray + ? metadata.items['type'] + : metadata.type + ) ?? 'string'; + schemas[enumName] = { - type: metadata.type as string ?? 'string', + type: enumType, enum: metadata.isArray && metadata.items ? metadata.items['enum'] diff --git a/test/services/schema-object-factory.spec.ts b/test/services/schema-object-factory.spec.ts index 0e6f81389..f81263591 100644 --- a/test/services/schema-object-factory.spec.ts +++ b/test/services/schema-object-factory.spec.ts @@ -32,6 +32,12 @@ describe('SchemaObjectFactory', () => { Neighboard = 'neighboard' } + enum Ranking { + First = 1, + Second = 2, + Third = 3 + } + class CreatePersonDto { @ApiProperty() name: string; @@ -42,21 +48,36 @@ describe('SchemaObjectFactory', () => { class Person { @ApiProperty({ enum: Role, enumName: 'Role' }) role: Role; + @ApiProperty({ enum: Role, enumName: 'Role', isArray: true }) roles: Role[]; + + @ApiProperty({ enum: Group, enumName: 'Group', isArray: true }) + groups: Group[]; + + @ApiProperty({ enum: Ranking, enumName: 'Ranking', isArray: true }) + rankings: Ranking[]; } it('should explore enum', () => { const schemas: Record = {}; schemaObjectFactory.exploreModelSchema(Person, schemas); - expect(Object.keys(schemas)).toHaveLength(2); + expect(Object.keys(schemas)).toHaveLength(4); expect(schemas).toHaveProperty('Role'); expect(schemas.Role).toEqual({ type: 'string', enum: ['admin', 'user'] }); + expect(schemas.Group).toEqual({ + type: 'string', + enum: ['user', 'guest', 'family', 'neighboard'] + }); + expect(schemas.Ranking).toEqual({ + type: 'number', + enum: [1, 2, 3] + }); expect(schemas).toHaveProperty('Person'); expect(schemas.Person).toEqual({ type: 'object', @@ -69,14 +90,25 @@ describe('SchemaObjectFactory', () => { items: { $ref: '#/components/schemas/Role' } + }, + groups: { + type: 'array', + items: { + $ref: '#/components/schemas/Group' + } + }, + rankings: { + type: 'array', + items: { + $ref: '#/components/schemas/Ranking' + } } }, - required: ['role', 'roles'] + required: ['role', 'roles', 'groups', 'rankings'] }); - schemaObjectFactory.exploreModelSchema(CreatePersonDto, schemas); - expect(Object.keys(schemas)).toHaveLength(3); + expect(Object.keys(schemas)).toHaveLength(5); expect(schemas).toHaveProperty('CreatePersonDto'); expect(schemas.CreatePersonDto).toEqual({ type: 'object', @@ -276,9 +308,9 @@ describe('SchemaObjectFactory', () => { isArray: false }; const schemas = {}; - + schemaObjectFactory.createEnumSchemaType('field', metadata, schemas); - + expect(schemas).toEqual({ MyEnum: { enum: [1, 2, 3], type: 'number' } }); }); });