UNPKG

@envelop/on-resolve

Version:

This plugin allows you to hook into resolves of every field in the GraphQL schema.

55 lines (54 loc) 2.71 kB
import { defaultFieldResolver, isIntrospectionType, isObjectType, } from 'graphql'; import { handleMaybePromise, mapMaybePromise } from '@whatwg-node/promise-helpers'; /** * Wraps the provided schema by hooking into the resolvers of every field. * * Use the `onResolve` argument to manipulate the resolver and its results/errors. */ export function useOnResolve(onResolve, opts = { skipIntrospection: true }) { const hasWrappedResolveSymbol = Symbol('hasWrappedResolve'); return { onSchemaChange({ schema: _schema }) { const schema = _schema; if (!schema) return; // nothing to do if schema is missing for (const type of Object.values(schema.getTypeMap())) { if ((!opts.skipIntrospection || !isIntrospectionType(type)) && isObjectType(type)) { for (const field of Object.values(type.getFields())) { if (field[hasWrappedResolveSymbol]) continue; let resolver = (field.resolve || defaultFieldResolver); field.resolve = (root, args, context, info) => handleMaybePromise(() => onResolve({ root, args, context, info, resolver, replaceResolver: newResolver => { resolver = newResolver; }, }), afterResolve => { if (typeof afterResolve === 'function') { return handleMaybePromise(() => resolver(root, args, context, info), result => mapMaybePromise(afterResolve({ result, setResult: newResult => { result = newResult; }, }), () => result), errorResult => handleMaybePromise(() => afterResolve({ result: errorResult, setResult: newResult => { errorResult = newResult; }, }), () => { throw errorResult; })); } return resolver(root, args, context, info); }); field[hasWrappedResolveSymbol] = true; } } } }, }; }