
import {
  type GraphQLField, type GraphQLFieldResolver,
  defaultFieldResolver,
} from "graphql";

export namespace wrapResolver {
  export type Target<Source, Context, Args> =
    GraphQLField<Source, Context, Args>;

  export type Arguments<Source, Context, Args> =
    Parameters<GraphQLFieldResolver<Source, Context, Args>>;

  export type Wrapper<Source, Context, Args> = (
    resolver: GraphQLFieldResolver<Source, Context, Args>,
    ...rest: Arguments<Source, Context, Args>
  ) => unknown;
}

export function wrapResolver<
  Source = unknown, Context = unknown, Args = Record<string, unknown>
> (
  target: GraphQLField<Source, Context, Args>,
  wrapper: wrapResolver.Wrapper<Source, Context, Args>
) {
  const resolver = target.resolve ?? defaultFieldResolver;

  target.resolve = function resolve (
    ...args: wrapResolver.Arguments<Source, Context, Args>
  ) {
    return wrapper(resolver, ...args);
  };
}
