-
-
Notifications
You must be signed in to change notification settings - Fork 676
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #233 from 19majkel94/typedefs-resolvers
Add support for typeDefs and resolvers ecosystem compatibility
- Loading branch information
Showing
9 changed files
with
697 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { | ||
GraphQLScalarType, | ||
GraphQLFieldResolver, | ||
GraphQLTypeResolver, | ||
GraphQLIsTypeOfFn, | ||
} from "graphql"; | ||
|
||
export interface ResolversMap<TSource = any, TContext = any> { | ||
[key: string]: | ||
| ResolverObject<TSource, TContext> | ||
| ResolverOptions<TSource, TContext> | ||
| GraphQLScalarType | ||
| EnumResolver; | ||
} | ||
|
||
export interface ResolverObject<TSource = any, TContext = any> { | ||
[key: string]: ResolverOptions<TSource, TContext>; | ||
} | ||
|
||
export interface EnumResolver { | ||
[key: string]: string | number; | ||
} | ||
|
||
export interface ResolverOptions<TSource = any, TContext = any> { | ||
fragment?: string; | ||
resolve?: GraphQLFieldResolver<TSource, TContext>; | ||
subscribe?: GraphQLFieldResolver<TSource, TContext>; | ||
__resolveType?: GraphQLTypeResolver<TSource, TContext>; | ||
__isTypeOf?: GraphQLIsTypeOfFn<TSource, TContext>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { printSchema } from "graphql"; | ||
|
||
import { BuildSchemaOptions, buildSchema } from "./buildSchema"; | ||
import { createResolversMap } from "./createResolversMap"; | ||
|
||
export async function buildTypeDefsAndResolvers(options: BuildSchemaOptions) { | ||
const schema = await buildSchema(options); | ||
const typeDefs = printSchema(schema); | ||
const resolvers = createResolversMap(schema); | ||
return { typeDefs, resolvers }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { | ||
GraphQLScalarType, | ||
GraphQLEnumType, | ||
GraphQLObjectType, | ||
GraphQLInterfaceType, | ||
GraphQLUnionType, | ||
GraphQLFieldMap, | ||
GraphQLSchema, | ||
GraphQLTypeResolver, | ||
GraphQLAbstractType, | ||
} from "graphql"; | ||
|
||
import { ResolversMap, EnumResolver, ResolverObject } from "../interfaces"; | ||
|
||
export function createResolversMap(schema: GraphQLSchema): ResolversMap { | ||
const typeMap = schema.getTypeMap(); | ||
return Object.keys(typeMap) | ||
.filter(typeName => !typeName.includes("__")) | ||
.reduce<ResolversMap>((resolversMap, typeName) => { | ||
const type = typeMap[typeName]; | ||
if (type instanceof GraphQLObjectType) { | ||
resolversMap[typeName] = { | ||
__isTypeOf: type.isTypeOf || undefined, | ||
...generateFieldsResolvers(type.getFields()), | ||
}; | ||
} | ||
if (type instanceof GraphQLInterfaceType) { | ||
resolversMap[typeName] = { | ||
__resolveType: generateTypeResolver(type, schema), | ||
...generateFieldsResolvers(type.getFields()), | ||
}; | ||
} | ||
if (type instanceof GraphQLScalarType) { | ||
resolversMap[typeName] = type; | ||
} | ||
if (type instanceof GraphQLEnumType) { | ||
const enumValues = type.getValues(); | ||
resolversMap[typeName] = enumValues.reduce<EnumResolver>((enumMap, { name, value }) => { | ||
enumMap[name] = value; | ||
return enumMap; | ||
}, {}); | ||
} | ||
if (type instanceof GraphQLUnionType) { | ||
resolversMap[typeName] = { | ||
__resolveType: generateTypeResolver(type, schema), | ||
}; | ||
} | ||
return resolversMap; | ||
}, {}); | ||
} | ||
|
||
function generateTypeResolver( | ||
abstractType: GraphQLAbstractType, | ||
schema: GraphQLSchema, | ||
): GraphQLTypeResolver<any, any> { | ||
if (abstractType.resolveType) { | ||
return async (source, context, info) => { | ||
const detectedType = await abstractType.resolveType!(source, context, info); | ||
if (detectedType instanceof GraphQLObjectType) { | ||
return detectedType.name; | ||
} | ||
return detectedType; | ||
}; | ||
} | ||
|
||
const possibleObjectTypes = schema.getPossibleTypes(abstractType); | ||
return async (source, context, info) => { | ||
for (const objectType of possibleObjectTypes) { | ||
if (objectType.isTypeOf && (await objectType.isTypeOf(source, context, info))) { | ||
return objectType.name; | ||
} | ||
} | ||
return null; | ||
}; | ||
} | ||
|
||
function generateFieldsResolvers(fields: GraphQLFieldMap<any, any>): ResolverObject { | ||
return Object.keys(fields).reduce<ResolverObject>((fieldsMap, fieldName) => { | ||
const field = fields[fieldName]; | ||
fieldsMap[fieldName] = { | ||
subscribe: field.subscribe, | ||
resolve: field.resolve, | ||
}; | ||
return fieldsMap; | ||
}, {}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export { buildSchema, buildSchemaSync, BuildSchemaOptions } from "./buildSchema"; | ||
export { buildTypeDefsAndResolvers } from "./buildTypeDefsAndResolvers"; | ||
export { emitSchemaDefinitionFile, emitSchemaDefinitionFileSync } from "./emitSchemaDefinitionFile"; | ||
export { useContainer, ContainerType, ContainerGetter, UseContainerOptions } from "./container"; |
Oops, something went wrong.