import { GraphQLInputType, GraphQLNonNull, GraphQLOutputType, isListType, isNamedType, isNonNullType, isScalarType } from 'graphql' const render = ( type: GraphQLOutputType | GraphQLInputType, nonNull: boolean, root: boolean, undefinableValues: boolean, undefinableFields: boolean, wrap: (x: string) => string = x => x ): string => { if (root) { if (undefinableFields) { if (isNonNullType(type)) { return `: ${render(type.ofType, true, false, undefinableValues, undefinableFields, wrap)}` } else { const rendered = render(type, true, false, undefinableValues, undefinableFields, wrap) return undefinableValues ? `?: ${rendered}` : `?: (${rendered} | null)` } } else { return `: ${render(type, false, false, undefinableValues, undefinableFields, wrap)}` } } if (isNamedType(type)) { let typeName = type.name // if is a scalar use the scalar interface to not expose reserved words if (isScalarType(type)) { typeName = `Scalars['${typeName}']` } const typing = wrap(typeName) if (undefinableValues) { return nonNull ? typing : `(${typing} | undefined)` } else { return nonNull ? typing : `(${typing} | null)` } } if (isListType(type)) { const typing = `${render(type.ofType, false, false, undefinableValues, undefinableFields, wrap)}[]` if (undefinableValues) { return nonNull ? typing : `(${typing} | undefined)` } else { return nonNull ? typing : `(${typing} | null)` } } return render((<GraphQLNonNull<any>>type).ofType, true, false, undefinableValues, undefinableFields, wrap) } export const renderTyping = ( type: GraphQLOutputType | GraphQLInputType, undefinableValues: boolean, undefinableFields: boolean, root = true, wrap: any = undefined ) => render(type, false, root, undefinableValues, undefinableFields, wrap)