Skip to content

Commit

Permalink
fix(): Derive enum types correctly when defined as an array nestjs#2615
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
IodizedGabe committed Oct 3, 2023
1 parent e403f9e commit fad6ee9
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 7 deletions.
8 changes: 7 additions & 1 deletion lib/services/schema-object-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down
44 changes: 38 additions & 6 deletions test/services/schema-object-factory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ describe('SchemaObjectFactory', () => {
Neighboard = 'neighboard'
}

enum Ranking {
First = 1,
Second = 2,
Third = 3
}

class CreatePersonDto {
@ApiProperty()
name: string;
Expand All @@ -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<string, SchemasObject> = {};
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',
Expand All @@ -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',
Expand Down Expand Up @@ -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' } });
});
});
Expand Down

0 comments on commit fad6ee9

Please sign in to comment.