import { GraphQLError, GraphQLFieldResolver, GraphQLInputType, GraphQLSchema, IntrospectionObjectType, IntrospectionType } from 'graphql'; import pluralize from 'pluralize'; import { DataResolver, TypeGenerator } from './GraphQLGenieInterfaces'; import { InputGenerator } from './InputGenerator'; import { Relations, getAllResolver, getRootMatchFields } from './TypeGeneratorUtilities'; import { camelCase, isArray, isEmpty } from 'lodash'; import { GenerateGetAll } from './GenerateGetAll'; export class GenerateGetOne implements TypeGenerator { private objectName: string; private types: IntrospectionObjectType[]; private schema: GraphQLSchema; private dataResolver: DataResolver; private fields: object; private resolvers: Map>; private currInputObjectTypes: Map; private schemaInfo: IntrospectionType[]; private relations: Relations; private getAllResolvers: Map>; constructor(dataResolver: DataResolver, objectName: string, types: IntrospectionObjectType[], $schema: GraphQLSchema, $currInputObjectTypes: Map, $schemaInfo: IntrospectionType[], $relations: Relations, $getAll: GenerateGetAll) { this.dataResolver = dataResolver; this.objectName = objectName; this.types = types; this.schema = $schema; this.currInputObjectTypes = $currInputObjectTypes; this.schemaInfo = $schemaInfo; this.relations = $relations; this.fields = {}; this.resolvers = new Map>(); this.getAllResolvers = $getAll && $getAll.resolvers ? $getAll.resolvers : new Map>(); this.generate(); } generate() { this.types.forEach(type => { const schemaType = this.schema.getType(type.name); const generator = new InputGenerator(schemaType, null, this.currInputObjectTypes, this.schemaInfo, this.schema, this.relations); const args = Object.assign( { where: { type: generator.generateWhereUniqueInput() } }, getRootMatchFields(generator.generateWhereUniqueInput()) ); const fieldName = `${camelCase(type.name)}`; const allFieldName = `${camelCase(pluralize(type.name))}`; this.fields[fieldName] = { type: `${type.name}`, args }; const allResolver = this.getAllResolvers.get(allFieldName) || getAllResolver(this.dataResolver, this.schema, type); this.resolvers.set(fieldName, async (root: any, args: { [key: string]: any }, context, info) => { if (isEmpty(args)) { throw new GraphQLError('Singular queries must have an argument'); } let resolveResult = await allResolver.apply(this, [root, args, context, info]); if (isArray(resolveResult)) { resolveResult = resolveResult.length > 0 ? resolveResult[0] : null; } return resolveResult; }); }); } public getResolvers(): Map>> { return new Map([[this.objectName, this.resolvers]]); } public getFieldsOnObject(): Map { return new Map([[this.objectName, this.fields]]); } }