UNPKG

@commitspark/graphql-api

Version:

GraphQL API to store and manage structured data with Git

167 lines (147 loc) 5.24 kB
import { generateQueriesAndMutations, generateTypeNameQuery, } from './queries-mutations-generator' import { IExecutableSchemaDefinition, makeExecutableSchema, } from '@graphql-tools/schema' import { analyzeSchema } from './schema-analyzer' import { generateIdInputTypeStrings, generateObjectInputTypeStrings, generateUnionInputTypeStrings, } from './input-type-generator' import { generateSchemaRootTypeStrings } from './schema-root-type-generator' import { printSchemaWithDirectives } from '@graphql-tools/utils' import { unionTypeResolver } from './resolvers/query-mutation-resolvers/union-type-resolver' import { ApolloContext } from '../client' import { GraphQLFieldResolver, GraphQLTypeResolver } from 'graphql' import { getValidationResult } from './schema-validator' import { EntryData } from '@commitspark/git-adapter' import { createObjectTypeFieldResolvers } from './resolvers/object-type-field-default-value-resolver-generator' import { createError, ErrorCode } from './errors' export async function generateSchema( context: ApolloContext, ): Promise<IExecutableSchemaDefinition> { const originalSchemaString = await context.gitAdapter.getSchema( context.getCurrentRef(), ) const schema = makeExecutableSchema({ typeDefs: originalSchemaString, }) const validationResult = getValidationResult(schema) if (validationResult.length > 0) { throw createError(`Invalid schema.`, ErrorCode.BAD_SCHEMA, { schema: printSchemaWithDirectives(schema), argumentValue: validationResult.join('\n'), }) } const schemaAnalyzerResult = analyzeSchema(schema) const filteredOriginalSchemaString = printSchemaWithDirectives(schema) + '\n' const generatedIdInputTypeStrings = generateIdInputTypeStrings(schemaAnalyzerResult) const generatedQueriesMutations = generateQueriesAndMutations( schemaAnalyzerResult.entryDirectiveTypes, ) const generatedTypeNameQuery = generateTypeNameQuery() const generatedEntryReferenceResolvers: Record< string, Record< string, GraphQLFieldResolver< Record<string, any>, ApolloContext, any, Promise<EntryData | EntryData[] | null> > > > = {} const generatedObjectInputTypeStrings = generateObjectInputTypeStrings( schemaAnalyzerResult.objectTypes, ) const generatedUnionInputTypeStrings = generateUnionInputTypeStrings( schemaAnalyzerResult.unionTypes, ) const generatedSchemaRootTypeStrings = generateSchemaRootTypeStrings( generatedQueriesMutations, generatedTypeNameQuery, ) const generatedSchemaString = `schema { query: Query mutation: Mutation } ${generatedSchemaRootTypeStrings}` const generatedUnionTypeResolvers: Record<string, UnionTypeResolver> = {} for (const unionType of schemaAnalyzerResult.unionTypes) { generatedUnionTypeResolvers[unionType.name] = { __resolveType: unionTypeResolver, } } const generatedObjectTypeFieldResolvers = createObjectTypeFieldResolvers(schema) const generatedQueryResolvers: Record< string, GraphQLFieldResolver<any, ApolloContext> > = {} const generatedMutationResolvers: Record< string, GraphQLFieldResolver<any, ApolloContext> > = {} for (const element of generatedQueriesMutations) { generatedQueryResolvers[element.queryEvery.name] = element.queryEvery.resolver generatedQueryResolvers[element.queryById.name] = element.queryById.resolver generatedMutationResolvers[element.createMutation.name] = element.createMutation.resolver generatedMutationResolvers[element.updateMutation.name] = element.updateMutation.resolver generatedMutationResolvers[element.deleteMutation.name] = element.deleteMutation.resolver } generatedQueryResolvers[generatedTypeNameQuery.name] = generatedTypeNameQuery.resolver const allGeneratedResolvers: Record< string, Record< string, | GraphQLFieldResolver<any, ApolloContext> | GraphQLTypeResolver<any, ApolloContext> > > = { Query: generatedQueryResolvers, Mutation: generatedMutationResolvers, } for (const typeName of Object.keys(generatedUnionTypeResolvers)) { allGeneratedResolvers[typeName] = { ...(allGeneratedResolvers[typeName] ?? {}), ...generatedUnionTypeResolvers[typeName], } } for (const typeName of Object.keys(generatedObjectTypeFieldResolvers)) { allGeneratedResolvers[typeName] = { ...(allGeneratedResolvers[typeName] ?? {}), ...generatedObjectTypeFieldResolvers[typeName], } } for (const typeName of Object.keys(generatedEntryReferenceResolvers)) { allGeneratedResolvers[typeName] = { ...(allGeneratedResolvers[typeName] ?? {}), ...generatedEntryReferenceResolvers[typeName], } } const typeDefs = [ filteredOriginalSchemaString, generatedSchemaString, generatedIdInputTypeStrings.join('\n'), generatedObjectInputTypeStrings.join('\n'), generatedUnionInputTypeStrings.join('\n'), ].filter((typeDef) => typeDef.length > 0) return { typeDefs: typeDefs, resolvers: allGeneratedResolvers, } } interface UnionTypeResolver { __resolveType: GraphQLTypeResolver<any, ApolloContext> }