All files / src mutation-hoc.tsx

88.89% Statements 32/36
77.78% Branches 14/18
83.33% Functions 5/6
93.75% Lines 30/32
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 8327x   27x   27x   27x 27x             27x             19x     19x     38x   19x 19x   19x     19x 19x 19x 19x 19x 28x 28x   28x           28x 7x               28x     28x 28x 28x         3x     28x         19x     19x      
import * as React from 'react';
import { DocumentNode } from 'graphql';
const hoistNonReactStatics = require('hoist-non-react-statics');
 
import { parser } from './parser';
import { MutationOpts, OperationOption, OptionProps, MutateProps } from './types';
import { default as Mutation } from './Mutation';
import {
  defaultMapPropsToOptions,
  getDisplayName,
  calculateVariablesFromProps,
  GraphQLBase,
} from './hoc-utils';
 
export function mutation<
  TProps extends TGraphQLVariables | {} = {},
  TData = {},
  TGraphQLVariables = {},
  TChildProps = Partial<MutateProps<TData, TGraphQLVariables>>
>(
  document: DocumentNode,
  IoperationOptions: OperationOption<TProps, TData, TGraphQLVariables, TChildProps> = {},
) {
  // this is memoized so if coming from `graphql` there is nearly no extra cost
  const operation = parser(document);
  // extract options
 
  const { options = defaultMapPropsToOptions, alias = 'Apollo' } = operationOptions;
 
  let mapPropsToOptions = options as (props: any) => MutationOpts;
  Iif (typeof mapPropsToOptions !== 'function') mapPropsToOptions = () => options as MutationOpts;
 
  return (
    WrappedComponent: React.ComponentType<TChildProps & TProps>,
  ): React.ComponentClass<TProps> => {
    const graphQLDisplayName = `${alias}(${getDisplayName(WrappedComponent)})`;
    class GraphQL extends GraphQLBase<TProps, TChildProps> {
      static displayName = graphQLDisplayName;
      static WrappedComponent = WrappedComponent;
      render() {
        let props = this.props;
        const opts = mapPropsToOptions(props);
 
        Iif (operationOptions.withRef) {
          this.withRef = true;
          props = Object.assign({}, props, {
            ref: this.setWrappedInstance,
          });
        }
        if (!opts.variables && operation.variables.length > 0) {
          opts.variables = calculateVariablesFromProps(
            operation,
            props,
            graphQLDisplayName,
            getDisplayName(WrappedComponent),
          );
        }
 
        return (
          <Mutation {...opts} mutation={document} ignoreResults>
            {(mutate, _result) => {
              const name = operationOptions.name || 'mutate';
              let childProps = { [name]: mutate };
              if (operationOptions.props) {
                const newResult: OptionProps<TProps, TData, TGraphQLVariables> = {
                  [name]: mutate,
                  ownProps: props,
                };
                childProps = operationOptions.props(newResult) as any;
              }
 
              return <WrappedComponent {...props} {...childProps} />;
            }}
          </Mutation>
        );
      }
    }
 
    // Make sure we preserve any custom statics on the original component.
    return hoistNonReactStatics(GraphQL, WrappedComponent, {});
  };
}