import { getNamedType, GraphQLInterfaceType, GraphQLObjectType, isEnumType, isInterfaceType, isScalarType } from 'graphql' import { fieldComment, typeComment } from '../common/comment' import { RenderContext } from '../common/RenderContext' import { toArgsString } from '../common/toArgsString' import { requestTypeName } from './requestTypeName' export const objectType = (type: GraphQLObjectType | GraphQLInterfaceType, ctx: RenderContext) => { const fieldStrings = Object.keys(type.getFields()).map(fieldName => { const field = type.getFields()[fieldName] const types: string[] = [] const resolvedType = getNamedType(field.type) const resolvable = !(isEnumType(resolvedType) || isScalarType(resolvedType)) const argsPresent = field.args.length > 0 const argsString = toArgsString(field) const argsOptional = !argsString.match(/[^?]:/) if (argsPresent) { if (resolvable) { types.push(`[${argsString},${requestTypeName(resolvedType)}]`) } else { types.push(`[${argsString}]`) } } if (!argsPresent || argsOptional) { if (resolvable) { types.push(`${requestTypeName(resolvedType)}`) } else { types.push('boolean|number') } } return `${fieldComment(field)}${field.name}?:${types.join('|')}` }) if (isInterfaceType(type) && ctx.schema) { ctx.schema .getPossibleTypes(type) .map(t => `on_${t.name}?:${requestTypeName(t)}`) .forEach(s => fieldStrings.push(s)) } fieldStrings.push('__typename?:boolean|number') fieldStrings.push('__scalar?:boolean|number') ctx.addCodeBlock(`${typeComment(type)}export interface ${requestTypeName(type)}{${fieldStrings.join(',')}}`) }