# All files / domains/field/compiler resolver.ts

78.91% Statements 101/128
69.79% Branches 67/96
95.83% Functions 23/24
91.76% Lines 78/85

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    11520x
    104x
    93x
    1x
    196x
    104x

    20x
    104x
    104x
    312x

    198x
    416x
    416x
    416x
    416x
    198x
    94x

    124x
    20x

    218x
    416x
    104x

    20x
    20x
    20x
    20x
    20x

    69x
    69x
    74x

    69x
    63x

    6x
    7x

    5x

    20x
    20x
    20x
    18x
    10x

    8x
    8x

    8x

    34x
    3x

    31x
    31x
    29x

    2x

    85x

    85x
    85x
    85x
    85x
    35x
    35x
    35x
    35x

    35x
    144x

    35x
    6x

    35x

    35x
    34x
    34x
    14x

    14x
    14x

    20x
    20x

     import { GraphQLFieldResolver } from 'graphql';
    import {
      InjectorsIndex,
      InjectorResolver,
      injectorRegistry,
    } from '~/domains/inject';
    import {
      fieldAfterHooksRegistry,
      fieldBeforeHooksRegistry,
      HookExecutor,
    } from '~/domains/hooks';
    import { getParameterNames } from '~/services/utils';

    import {I isSchemaRoot, getSchemaRootInstance } from '~/domains/schema';

    interface ArIgsMap {
      [argName: Istring]: any;
    }

    interface ComputeArgsOptions {
      args: ArgsMap;
      injectors: InjectorsIndex;
      injectorToValueMapper: (injector: InjectorResolver) => any;
    }
    E
    async function performHooksExecution(
      hooks: HookExecutor[],
      source: any,
      args: any,
      context: any,
      info: any,
    ) {
      if (!hooks) {
        return;
      }
      // all hooks are executed in parrell instead of sequence. We wait for them all to be resolved before we continue
      return await Promise.all(
        hooks.map(hook => {
          return hook({ source, args, context, info });
        }),
      );
    }

    function computeFinalArgs(
      func: Function,
      { args, injectors, injectorToValueMapper }: ComputeArgsOptions,
    ) {
      const paramNames = getParameterNames(func);
      return paramNames.map((paramName, index) => {
        if (args && args.hasOwnProperty(paramName)) {
          return args[paramName];
        }

        const injector = injectors[index];

        if (!injector) {
          return null;
        }

        return injectorToValueMapper(injector);
      });
    }

    function getFieldOfTarget(instance: any, prototype: any, fieldName: string) {
      if (!instance) {
        return prototype[fieldName];
      }I

      const instanceField = instance[fieldName];

      if (instanceField !== undefined) {
        return instanceField;
      }

      return prototype[fieldName];
    }

    export function compileFieldResolver(
      target: Function,
      fieldName: string,
    ): GraphQLFieldResolver<any, any> {
      // const config = fieldsRegistry.get(target, fieldName);
      const injectors = injectorRegistry.getAll(target)[fieldName];
      const beforeHooks = fieldBeforeHooksRegistry.get(target, fieldName);
      const afterHooks = fieldAfterHooksRegistry.get(target, fieldName);

      return async (source: any, args = null, context = null, info = null) => {
        if (isSchemaRoot(target)) {
          source = getSchemaRootInstance(target);
        }I

        awaiIt performHooksExecution(beforeHooks, source, args, context, info);
        const instanceField = getFieldOfTarget(source, target.prototype, fieldName);

        if (typeof instanceField !== 'function') {
          await performHooksExecution(afterHooks, source, args, context, info);
          return instanceField;
        }

        const instanceFieldFunc = instanceField as Function;

        const params = computeFinalArgs(instanceFieldFunc, {
          args: args || {},
          injectors: injectors || {},
          injectorToValueMapper: injector =>
            injector.apply(source, [{ source, args, context, info }]),
        });

        const result = await instanceFieldFunc.apply(source, params);

        await performHooksExecution(afterHooks, source, args, context, info); // TODO: Consider adding resolve return to hook callback
        return result;
      };
    }