diff --git a/lib/decorators/api-property.decorator.ts b/lib/decorators/api-property.decorator.ts index 0a30425f6..5f5fe7416 100644 --- a/lib/decorators/api-property.decorator.ts +++ b/lib/decorators/api-property.decorator.ts @@ -6,7 +6,7 @@ import { createPropertyDecorator, getTypeIsArrayTuple } from './helpers'; export interface ApiPropertyOptions extends Omit { name?: string; - enum?: any[] | Record; + enum?: any[] | Record | (() => (any[] | Record)); enumName?: string; } diff --git a/lib/utils/enum.utils.ts b/lib/utils/enum.utils.ts index 9ddab59b7..8ea9634d9 100644 --- a/lib/utils/enum.utils.ts +++ b/lib/utils/enum.utils.ts @@ -3,7 +3,11 @@ import { SchemaObject } from '../interfaces/open-api-spec.interface'; import { SchemaObjectMetadata } from '../interfaces/schema-object-metadata.interface'; import { SwaggerEnumType } from '../types/swagger-enum.type'; -export function getEnumValues(enumType: SwaggerEnumType): string[] | number[] { +export function getEnumValues(enumType: SwaggerEnumType | (() => SwaggerEnumType)): string[] | number[] { + if (typeof enumType === 'function') { + return getEnumValues(enumType()); + } + if (Array.isArray(enumType)) { return enumType as string[]; } diff --git a/test/explorer/swagger-explorer.spec.ts b/test/explorer/swagger-explorer.spec.ts index 2870f7923..06f451f9b 100644 --- a/test/explorer/swagger-explorer.spec.ts +++ b/test/explorer/swagger-explorer.spec.ts @@ -89,6 +89,12 @@ describe('SwaggerExplorer', () => { isArray: true }) enumArr: LettersEnum; + + @ApiProperty({ + enum: () => LettersEnum, + enumName: 'LettersEnum', + }) + enumFunction: LettersEnum; } @Controller('') @@ -229,7 +235,7 @@ describe('SwaggerExplorer', () => { expect(routes[0].root!.method).toEqual('post'); expect(routes[0].root!.path).toEqual('/globalPrefix/modulePath/foos'); expect(routes[0].root!.summary).toEqual('Create foo'); - expect(routes[0].root!.parameters.length).toEqual(5); + expect(routes[0].root!.parameters.length).toEqual(6); expect(routes[0].root!.parameters).toEqual([ { in: 'query', @@ -278,6 +284,14 @@ describe('SwaggerExplorer', () => { }, type: 'array' } + }, + { + in: 'query', + name: 'enumFunction', + required: true, + schema: { + $ref: '#/components/schemas/LettersEnum' + } } ]); expect(routes[0].root!.requestBody).toEqual({ diff --git a/test/services/schema-object-factory.spec.ts b/test/services/schema-object-factory.spec.ts index 2a7546734..531ab1290 100644 --- a/test/services/schema-object-factory.spec.ts +++ b/test/services/schema-object-factory.spec.ts @@ -38,6 +38,12 @@ describe('SchemaObjectFactory', () => { Third = 3 } + enum HairColour { + Brown = 'Brown', + Blond = 'Blond', + Ginger = 'Ginger', + } + class CreatePersonDto { @ApiProperty() name: string; @@ -57,13 +63,19 @@ describe('SchemaObjectFactory', () => { @ApiProperty({ enum: Ranking, enumName: 'Ranking', isArray: true }) rankings: Ranking[]; + + @ApiProperty({ enum: () => HairColour, enumName: 'HairColour' }) + hairColour: HairColour; + + @ApiProperty({ enum: () => ['Pizza', 'Burger', 'Salad'], enumName: 'Food', isArray: true }) + favouriteFoods: string[]; } it('should explore enum', () => { const schemas: Record = {}; schemaObjectFactory.exploreModelSchema(Person, schemas); - expect(Object.keys(schemas)).toHaveLength(4); + expect(Object.keys(schemas)).toHaveLength(6); expect(schemas).toHaveProperty('Role'); expect(schemas.Role).toEqual({ @@ -78,6 +90,10 @@ describe('SchemaObjectFactory', () => { type: 'number', enum: [1, 2, 3] }); + expect(schemas.HairColour).toEqual({ + type: 'string', + enum: ['Brown', 'Blond', 'Ginger'] + }); expect(schemas).toHaveProperty('Person'); expect(schemas.Person).toEqual({ type: 'object', @@ -102,13 +118,22 @@ describe('SchemaObjectFactory', () => { items: { $ref: '#/components/schemas/Ranking' } + }, + 'favouriteFoods': { + 'items': { + '$ref': '#/components/schemas/Food' + }, + 'type': 'array' + }, + 'hairColour': { + '$ref': '#/components/schemas/HairColour' } }, - required: ['role', 'roles', 'groups', 'rankings'] + required: ['role', 'roles', 'groups', 'rankings', 'hairColour', 'favouriteFoods'] }); schemaObjectFactory.exploreModelSchema(CreatePersonDto, schemas); - expect(Object.keys(schemas)).toHaveLength(5); + expect(Object.keys(schemas)).toHaveLength(7); expect(schemas).toHaveProperty('CreatePersonDto'); expect(schemas.CreatePersonDto).toEqual({ type: 'object',