todo/data/schema/nodes.js (110 lines of code) (raw):

// @flow /* eslint flowtype/require-return-type: 'off' */ import { GraphQLBoolean, GraphQLInt, GraphQLNonNull, GraphQLObjectType, GraphQLString, type GraphQLInterfaceType, type GraphQLFieldConfig, type GraphQLFieldConfigArgumentMap, } from 'graphql'; import { connectionArgs, connectionDefinitions, connectionFromArray, fromGlobalId, globalIdField, nodeDefinitions, } from 'graphql-relay'; import { Todo, User, USER_ID, getTodoOrThrow, getTodos, getUserOrThrow, } from '../database'; // $FlowFixMe graphql-relay types not available in flow-typed, strengthen this typing const {nodeInterface, nodeField} = (nodeDefinitions( (globalId: string): ?{} => { const {type, id}: {id: string, type: string} = fromGlobalId(globalId); if (type === 'Todo') { return (getTodoOrThrow(id): $FlowFixMe); } else if (type === 'User') { return (getUserOrThrow(id): $FlowFixMe); } return null; }, (obj: {}): ?GraphQLObjectType => { if (obj instanceof Todo) { return GraphQLTodo; } else if (obj instanceof User) { return GraphQLUser; } return null; }, ): { nodeField: GraphQLFieldConfig<$FlowFixMe, $FlowFixMe>, nodeInterface: GraphQLInterfaceType, nodesField: GraphQLFieldConfig<$FlowFixMe, $FlowFixMe>, }); const GraphQLTodo: GraphQLObjectType = new GraphQLObjectType({ name: 'Todo', fields: { id: globalIdField('Todo'), text: { type: new GraphQLNonNull(GraphQLString), resolve: (todo: Todo): string => todo.text, }, complete: { type: new GraphQLNonNull(GraphQLBoolean), resolve: (todo: Todo): boolean => todo.complete, }, }, interfaces: [nodeInterface], }); const {connectionType: TodosConnection, edgeType: GraphQLTodoEdge} = (connectionDefinitions({ name: 'Todo', nodeType: GraphQLTodo, }): { connectionType: GraphQLObjectType, edgeType: GraphQLObjectType, }); // $FlowFixMe[cannot-spread-indexer] const todosArgs: GraphQLFieldConfigArgumentMap = { status: { type: GraphQLString, defaultValue: 'any', }, ...connectionArgs, }; const GraphQLUser: GraphQLObjectType = new GraphQLObjectType({ name: 'User', fields: { id: globalIdField('User'), userId: { type: new GraphQLNonNull(GraphQLString), resolve: (): string => USER_ID, }, todos: { type: TodosConnection, args: todosArgs, // eslint-disable-next-line flowtype/require-parameter-type resolve: (root: {}, {status, after, before, first, last}) => connectionFromArray([...getTodos(status)], { after, before, first, last, }), }, totalCount: { type: new GraphQLNonNull(GraphQLInt), resolve: (): number => getTodos().length, }, completedCount: { type: new GraphQLNonNull(GraphQLInt), resolve: (): number => getTodos('completed').length, }, }, interfaces: [nodeInterface], }); export {nodeField, GraphQLTodo, GraphQLTodoEdge, GraphQLUser};