UNPKG

graphql-compose

Version:

GraphQL schema builder from different data sources with middleware extensions.

136 lines (111 loc) 3.06 kB
/* @flow */ /* eslint-disable no-use-before-define */ import { GraphQLObjectType, GraphQLInputObjectType, getNamedType, } from 'graphql'; import TypeComposer from './typeComposer'; import InputTypeComposer from './inputTypeComposer'; import Resolver from './resolver'; import type { GraphQLInputType, GraphQLOutputType, } from './definition'; /** * fieldName * @argName * #resolver */ export function typeByPath( src: TypeComposer | InputTypeComposer | Resolver<*, *>, path: string | Array<string> ) { const parts = Array.isArray(path) ? path : String(path).split('.'); if (parts.length === 0) { return src; } if (src instanceof TypeComposer) { return typeByPathTC(src, parts); } else if (src instanceof InputTypeComposer) { return typeByPathITC(src, parts); } else if (src instanceof Resolver) { return typeByPathRSV(src, parts); } return src; } export function typeByPathTC( tc: TypeComposer, parts: Array<string> ) { if (!tc) return undefined; if (parts.length === 0) return tc; const name = parts[0]; if (!name) return undefined; const nextName = parts[1]; if (name.startsWith('$')) { const restParts = parts.slice(1); const resolver = tc.getResolver(name.substring(1)); if (resolver) { if (restParts.length > 0) { return typeByPathRSV(resolver, restParts); } return resolver; } return undefined; } if (nextName && nextName.startsWith('@')) { const arg = tc.getFieldArg(name, nextName.substring(1)); return processType(arg && arg.type, parts.slice(2)); } const fieldType = tc.getFieldType(name); return processType(fieldType, parts.slice(1)); } export function typeByPathITC( itc: InputTypeComposer, parts: Array<string> ) { if (!itc) return undefined; if (parts.length === 0) return itc; const fieldType = itc.getFieldType(parts[0]); return processType(fieldType, parts.slice(1)); } function typeByPathRSV( rsv: Resolver<*, *>, parts: Array<string> ) { if (!rsv) return undefined; if (parts.length === 0) return rsv; const name = parts[0]; if (!name) return undefined; if (name.startsWith('@')) { const arg = rsv.getArg(name.substring(1)); if (!arg) return undefined; return processType(arg.type, parts.slice(1)); } return processType(rsv.getType(), parts); } export function processType( type: GraphQLOutputType | GraphQLInputType | void | null, restParts: Array<string> ): mixed { if (!type) return undefined; const unwrappedType = getNamedType(type); if (unwrappedType instanceof GraphQLObjectType) { const tc = new TypeComposer(unwrappedType); if (restParts.length > 0) { return typeByPathTC(tc, restParts); } return tc; } else if (unwrappedType instanceof GraphQLInputObjectType) { const itc = new InputTypeComposer(unwrappedType); if (restParts.length > 0) { return typeByPathITC(itc, restParts); } return itc; } if (restParts.length > 0) { return undefined; } return unwrappedType; }