diff --git a/src/schema/TypeORMConverter.ts b/src/schema/TypeORMConverter.ts index 2d184df5..aec07b3b 100644 --- a/src/schema/TypeORMConverter.ts +++ b/src/schema/TypeORMConverter.ts @@ -47,10 +47,18 @@ export function columnToTypeScriptType(column: ColumnMetadata): string { export function generateEnumMapImports(): string[] { const imports: string[] = []; const enumMap = getMetadataStorage().enumMap; + // Keep track of already imported items so that we don't attempt to import twice in the event the + // enum is used in multiple models + const imported = new Set(); Object.keys(enumMap).forEach((tableName: string) => { Object.keys(enumMap[tableName]).forEach((columnName: string) => { const enumColumn = enumMap[tableName][columnName]; + if (imported.has(enumColumn.name)) { + return; + } + imported.add(enumColumn.name); + const filename = filenameToImportPath(enumColumn.filename); imports.push(`import { ${enumColumn.name} } from '${filename}' `); diff --git a/src/test/functional/__snapshots__/schema.test.ts.snap b/src/test/functional/__snapshots__/schema.test.ts.snap index fd8d6b23..dbf51365 100644 --- a/src/test/functional/__snapshots__/schema.test.ts.snap +++ b/src/test/functional/__snapshots__/schema.test.ts.snap @@ -152,6 +152,7 @@ type Dish implements BaseGraphQLObject { deletedById: String version: Int! name: String! + stringEnumField: StringEnum kitchenSink: KitchenSink! kitchenSinkId: String! } @@ -163,6 +164,7 @@ type DishConnection { input DishCreateInput { name: String! + stringEnumField: StringEnum kitchenSinkId: ID! } @@ -175,12 +177,15 @@ enum DishOrderByInput { deletedAt_DESC name_ASC name_DESC + stringEnumField_ASC + stringEnumField_DESC kitchenSinkId_ASC kitchenSinkId_DESC } input DishUpdateInput { name: String + stringEnumField: StringEnum kitchenSinkId: ID } @@ -214,6 +219,8 @@ input DishWhereInput { name_startsWith: String name_endsWith: String name_in: [String!] + stringEnumField_eq: StringEnum + stringEnumField_in: [StringEnum!] kitchenSinkId_eq: ID kitchenSinkId_in: [ID!] } diff --git a/src/test/generated/binding.ts b/src/test/generated/binding.ts index 2921cf89..145fe9a7 100644 --- a/src/test/generated/binding.ts +++ b/src/test/generated/binding.ts @@ -60,6 +60,8 @@ export type DishOrderByInput = 'createdAt_ASC' | 'deletedAt_DESC' | 'name_ASC' | 'name_DESC' | + 'stringEnumField_ASC' | + 'stringEnumField_DESC' | 'kitchenSinkId_ASC' | 'kitchenSinkId_DESC' @@ -177,11 +179,13 @@ export interface BaseWhereInput { export interface DishCreateInput { name: String + stringEnumField?: StringEnum | null kitchenSinkId: ID_Output } export interface DishUpdateInput { name?: String | null + stringEnumField?: StringEnum | null kitchenSinkId?: ID_Input | null } @@ -215,6 +219,8 @@ export interface DishWhereInput { name_startsWith?: String | null name_endsWith?: String | null name_in?: String[] | String | null + stringEnumField_eq?: StringEnum | null + stringEnumField_in?: StringEnum[] | StringEnum | null kitchenSinkId_eq?: ID_Input | null kitchenSinkId_in?: ID_Output[] | ID_Output | null } @@ -475,6 +481,7 @@ export interface Dish extends BaseGraphQLObject { deletedById?: String | null version: Int name: String + stringEnumField?: StringEnum | null kitchenSink: KitchenSink kitchenSinkId: String } diff --git a/src/test/generated/classes.ts b/src/test/generated/classes.ts index 3171a428..c37ec6bf 100644 --- a/src/test/generated/classes.ts +++ b/src/test/generated/classes.ts @@ -802,6 +802,9 @@ export enum DishOrderByEnum { name_ASC = "name_ASC", name_DESC = "name_DESC", + stringEnumField_ASC = "stringEnumField_ASC", + stringEnumField_DESC = "stringEnumField_DESC", + kitchenSinkId_ASC = "kitchenSinkId_ASC", kitchenSinkId_DESC = "kitchenSinkId_DESC" } @@ -899,6 +902,12 @@ export class DishWhereInput { @TypeGraphQLField(() => [String], { nullable: true }) name_in?: string[]; + @TypeGraphQLField(() => StringEnum, { nullable: true }) + stringEnumField_eq?: StringEnum; + + @TypeGraphQLField(() => [StringEnum], { nullable: true }) + stringEnumField_in?: StringEnum[]; + @TypeGraphQLField(() => ID, { nullable: true }) kitchenSinkId_eq?: string; @@ -917,6 +926,9 @@ export class DishCreateInput { @TypeGraphQLField() name!: string; + @TypeGraphQLField(() => StringEnum, { nullable: true }) + stringEnumField?: StringEnum; + @TypeGraphQLField(() => ID) kitchenSinkId!: string; } @@ -926,6 +938,9 @@ export class DishUpdateInput { @TypeGraphQLField({ nullable: true }) name?: string; + @TypeGraphQLField(() => StringEnum, { nullable: true }) + stringEnumField?: StringEnum; + @TypeGraphQLField(() => ID, { nullable: true }) kitchenSinkId?: string; } diff --git a/src/test/generated/schema.graphql b/src/test/generated/schema.graphql index 552fe2f9..aea00e66 100644 --- a/src/test/generated/schema.graphql +++ b/src/test/generated/schema.graphql @@ -149,6 +149,7 @@ type Dish implements BaseGraphQLObject { deletedById: String version: Int! name: String! + stringEnumField: StringEnum kitchenSink: KitchenSink! kitchenSinkId: String! } @@ -160,6 +161,7 @@ type DishConnection { input DishCreateInput { name: String! + stringEnumField: StringEnum kitchenSinkId: ID! } @@ -172,12 +174,15 @@ enum DishOrderByInput { deletedAt_DESC name_ASC name_DESC + stringEnumField_ASC + stringEnumField_DESC kitchenSinkId_ASC kitchenSinkId_DESC } input DishUpdateInput { name: String + stringEnumField: StringEnum kitchenSinkId: ID } @@ -211,6 +216,8 @@ input DishWhereInput { name_startsWith: String name_endsWith: String name_in: [String!] + stringEnumField_eq: StringEnum + stringEnumField_in: [StringEnum!] kitchenSinkId_eq: ID kitchenSinkId_in: [ID!] } diff --git a/src/test/modules/dish/dish.model.ts b/src/test/modules/dish/dish.model.ts index 63cc895b..2007534f 100644 --- a/src/test/modules/dish/dish.model.ts +++ b/src/test/modules/dish/dish.model.ts @@ -1,12 +1,19 @@ -import { BaseModel, ManyToOne, Model, StringField } from '../../../'; +import { BaseModel, EnumField, ManyToOne, Model, StringField } from '../../../'; import { KitchenSink } from '../kitchen-sink/kitchen-sink.model'; +import { StringEnum } from '../shared'; +export { StringEnum }; // Warthog requires this + @Model() export class Dish extends BaseModel { @StringField({ maxLength: 40 }) name?: string; + // Exercises the case where multiple models import the same enum + @EnumField('StringEnum', StringEnum, { nullable: true }) + stringEnumField?: StringEnum; + @ManyToOne( () => KitchenSink, (kitchenSink: KitchenSink) => kitchenSink.dishes, diff --git a/src/test/modules/kitchen-sink/kitchen-sink.model.ts b/src/test/modules/kitchen-sink/kitchen-sink.model.ts index a39ea5ab..c1cf18cd 100644 --- a/src/test/modules/kitchen-sink/kitchen-sink.model.ts +++ b/src/test/modules/kitchen-sink/kitchen-sink.model.ts @@ -24,12 +24,8 @@ import { import { Dish } from '../dish/dish.model'; -// Note: this must be exported and in the same file where it's attached with @EnumField -// Also - must use string enums -export enum StringEnum { - FOO = 'FOO', - BAR = 'BAR' -} +import { StringEnum } from '../shared'; +export { StringEnum }; // Warthog requires this @Model() export class KitchenSink extends BaseModel { diff --git a/src/test/modules/shared.ts b/src/test/modules/shared.ts new file mode 100644 index 00000000..a8ec3009 --- /dev/null +++ b/src/test/modules/shared.ts @@ -0,0 +1,5 @@ +// Also - must use string enums +export enum StringEnum { + FOO = 'FOO', + BAR = 'BAR' +}