import { buildASTSchema, assertValidSchema, GraphQLSchema } from 'graphql' import { ListrTask } from 'listr' import { Config } from '../config' import { requireModuleFromPath } from '../helpers/files' import { customFetchSchema, fetchSchema, SchemaFetcher } from '../schema/fetchSchema' import { loadSchema } from 'graphql-toolkit' export const schemaTask = (config: Config): ListrTask => { if (config.endpoint) { const endpoint = config.endpoint return { title: `fetching schema using ${config.post ? 'POST' : 'GET'} ${endpoint}`, task: async ctx => { ctx.schema = await fetchSchema(endpoint, config.post) }, } } else if (config.fetcher) { const fetcher = config.fetcher return { title: 'fetching schema using custom fetcher', task: async ctx => { const resolvedFetcher = typeof fetcher === 'string' ? requireModuleFromPath([fetcher]) : fetcher ctx.schema = await customFetchSchema(resolvedFetcher, config.options && config.options.schemaValidation) }, } } else if (config.schema) { const schema = config.schema return { title: 'loading schema', task: async ctx => { const options = config.options && config.options.schemaBuild const document = await loadSchema(schema) ctx.schema = document instanceof GraphQLSchema ? document : buildASTSchema(document, options) try { assertValidSchema(ctx.schema) } catch (e) { if (e.message === 'Query root type must be provided.') return throw e } }, } } else { throw new Error('either `endpoint`, `fetcher` or `schema` must be defined in the config') } }