diff --git a/examples/2-complex-example/src/modules/user/user.model.ts b/examples/2-complex-example/src/modules/user/user.model.ts index 8608b5d7..4de0085e 100644 --- a/examples/2-complex-example/src/modules/user/user.model.ts +++ b/examples/2-complex-example/src/modules/user/user.model.ts @@ -1,5 +1,6 @@ import { Authorized } from 'type-graphql'; +import { Unique } from 'typeorm'; import { BaseModel, EmailField, EnumField, Model, StringField } from '../../../../../src'; // Note: this must be exported and in the same file where it's attached with @EnumField @@ -10,6 +11,7 @@ export enum StringEnum { } @Model() +@Unique(['firstName', 'stringEnumField']) export class User extends BaseModel { @StringField({ maxLength: 30 }) firstName?: string; @@ -17,7 +19,7 @@ export class User extends BaseModel { @StringField({ maxLength: 50, minLength: 2 }) lastName?: string; - @EnumField('StringEnum', StringEnum, { nullable: true }) + @EnumField('StringEnum', StringEnum) stringEnumField?: StringEnum; @EmailField() diff --git a/examples/2-complex-example/tools/seed.ts b/examples/2-complex-example/tools/seed.ts index fc2acca8..ea623f29 100644 --- a/examples/2-complex-example/tools/seed.ts +++ b/examples/2-complex-example/tools/seed.ts @@ -12,10 +12,16 @@ const logger = Debug('warthog:seed'); const NUM_USERS = 100; async function seedDatabase() { - const server = getServer(); + const server = getServer({ introspection: true }); await server.start(); - const binding = await server.getBinding(); + let binding; + try { + binding = await server.getBinding(); + } catch (error) { + console.error(error); + return process.exit(1); + } for (let index = 0; index < NUM_USERS; index++) { const random = new Date() @@ -34,7 +40,8 @@ async function seedDatabase() { data: { email, firstName, - lastName + lastName, + stringEnumField: 'FOO' } }, `{ id email createdAt createdById }` diff --git a/src/core/server.ts b/src/core/server.ts index 54b6f69c..89dd4744 100644 --- a/src/core/server.ts +++ b/src/core/server.ts @@ -129,10 +129,20 @@ export class Server { } async getBinding(options: { origin?: string; token?: string } = {}): Promise { - return getRemoteBinding(`http://${this.appHost}:${this.appPort}/graphql`, { - origin: 'warthog', - ...options - }); + let binding; + try { + binding = await getRemoteBinding(`http://${this.appHost}:${this.appPort}/graphql`, { + origin: 'warthog', + ...options + }); + return binding; + } catch (error) { + if (error.result && error.result.errors) { + const messages = error.result.errors.map((item: any) => item.message); + throw new Error(JSON.stringify(messages)); + } + throw error; + } } async buildGraphQLSchema(): Promise { @@ -189,7 +199,7 @@ export class Server { }, request: options.req, // Allows consumer to add to the context object - ex. context.user - ...consumerCtx, + ...consumerCtx }; }, introspection: this.introspection, @@ -206,6 +216,7 @@ export class Server { debug('start:applyMiddleware:end'); const url = `http://${this.appHost}:${this.appPort}${this.graphQLServer.graphqlPath}`; + debug(`url: ${url}`); this.httpServer = app.listen({ port: this.appPort }, () => this.logger.info(`🚀 Server ready at ${url}`) diff --git a/src/schema/TypeORMConverter.ts b/src/schema/TypeORMConverter.ts index 48083859..f1b21b61 100644 --- a/src/schema/TypeORMConverter.ts +++ b/src/schema/TypeORMConverter.ts @@ -105,15 +105,15 @@ export function entityToCreateInput(entity: EntityMetadata): string { !column.isVersion && !SYSTEM_FIELDS.includes(column.propertyName) ) { - const graphQLType = columnToGraphQLType(column); + const graphQLDataType = columnTypeToGraphQLDataType(column); const nullable = column.isNullable ? '{ nullable: true }' : ''; const tsRequired = column.isNullable ? '?' : '!'; const tsType = columnToTypeScriptType(column); if (column.enum) { fieldTemplates += ` - @TypeGraphQLField(type => ${graphQLType}, ${nullable}) - ${column.propertyName}${tsRequired}: ${graphQLType}; + @TypeGraphQLField(type => ${graphQLDataType}, ${nullable}) + ${column.propertyName}${tsRequired}: ${graphQLDataType}; `; } else { fieldTemplates += ` @@ -146,13 +146,13 @@ export function entityToUpdateInput(entity: EntityMetadata): string { ) { // TODO: also don't allow updated foreign key fields // Example: photo.userId: String - const graphQLType = columnToGraphQLType(column); + const graphQLDataType = columnTypeToGraphQLDataType(column); const tsType = columnToTypeScriptType(column); if (column.enum) { fieldTemplates += ` - @TypeGraphQLField(type => ${graphQLType}, { nullable: true }) - ${column.propertyName}?: ${graphQLType}; + @TypeGraphQLField(type => ${graphQLDataType}, { nullable: true }) + ${column.propertyName}?: ${graphQLDataType}; `; } else { fieldTemplates += ` @@ -200,14 +200,16 @@ export function entityToWhereInput(entity: EntityMetadata): string { const { graphqlType, tsType } = columnToTypes(column); + const graphQLDataType = columnTypeToGraphQLDataType(column); + // TODO: for foreign key fields, only allow the same filters as ID below // Example: photo.userId: String if (column.isPrimary || graphqlType === GraphQLID) { fieldTemplates += ` - @TypeGraphQLField(type => ${graphqlType},{ nullable: true }) + @TypeGraphQLField(type => ${graphQLDataType},{ nullable: true }) ${column.propertyName}_eq?: string; - @TypeGraphQLField(type => [${graphqlType}], { nullable: true }) + @TypeGraphQLField(type => [${graphQLDataType}], { nullable: true }) ${column.propertyName}_in?: string[]; `; } else if (graphqlType === GraphQLString) { @@ -226,7 +228,7 @@ export function entityToWhereInput(entity: EntityMetadata): string { @TypeGraphQLField({ nullable: true }) ${column.propertyName}_endsWith?: ${tsType}; - @TypeGraphQLField(type => [${graphqlType}], { nullable: true }) + @TypeGraphQLField(type => [${graphQLDataType}], { nullable: true }) ${column.propertyName}_in?: ${tsType}[]; `; } else if (graphqlType === GraphQLFloat || graphqlType === GraphQLInt) { @@ -246,7 +248,7 @@ export function entityToWhereInput(entity: EntityMetadata): string { @TypeGraphQLField({ nullable: true }) ${column.propertyName}_lte?: ${tsType}; - @TypeGraphQLField(type => [${graphqlType}], { nullable: true }) + @TypeGraphQLField(type => [${graphQLDataType}], { nullable: true }) ${column.propertyName}_in?: ${tsType}[]; `; } else if (graphqlType === GraphQLISODateTime) { @@ -266,11 +268,11 @@ export function entityToWhereInput(entity: EntityMetadata): string { } else { // Enums will fall through here fieldTemplates += ` - @TypeGraphQLField(type => ${graphqlType}, { nullable: true }) - ${column.propertyName}_eq?: ${graphqlType}; + @TypeGraphQLField(type => ${graphQLDataType}, { nullable: true }) + ${column.propertyName}_eq?: ${graphQLDataType}; - @TypeGraphQLField(type => [${graphqlType}], { nullable: true }) - ${column.propertyName}_in?: ${graphqlType}[]; + @TypeGraphQLField(type => [${graphQLDataType}], { nullable: true }) + ${column.propertyName}_in?: ${graphQLDataType}[]; `; } }); @@ -363,7 +365,7 @@ export function columnToGraphQLType(column: ColumnMetadata): GraphQLScalarType | // Check to see if this column is an enum and return that const enumObject = getMetadataStorage().getEnum(column.entityMetadata.name, column.propertyName); if (enumObject) { - return enumObject.name; + return enumObject; } else if (column.propertyName.match(/Id$/)) { return GraphQLID; }