All files utilities.ts

0% Statements 0/6
100% Branches 0/0
0% Functions 0/1
0% Lines 0/6
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 115                                                                                                                                                                                                                                     
import { DocumentNode } from 'graphql';
 
import { graphql } from './graphql';
 
export function filter(doc: DocumentNode, data: any): any {
  const resolver = (
    fieldName: string,
    root: any,
    args: any,
    context: any,
    info: any,
  ) => {
    return root[info.resultKey];
  };
 
  return graphql(resolver, doc, data);
}
 
// TODO: we should probably make check call propType and then throw,
// rather than the other way round, to avoid constructing stack traces
// for things like oneOf uses in React. At this stage I doubt many people
// are using this like that, but in the future, who knows?
export function check(doc: DocumentNode, data: any): void {
  const resolver = (
    fieldName: string,
    root: any,
    args: any,
    context: any,
    info: any,
  ) => {
    if (!{}.hasOwnProperty.call(root, info.resultKey)) {
      throw new Error(`${info.resultKey} missing on ${root}`);
    }
    return root[info.resultKey];
  };
 
  graphql(
    resolver,
    doc,
    data,
    {},
    {},
    {
      fragmentMatcher: () => false,
    },
  );
}
 
// Lifted/adapted from
//   https://github.com/facebook/react/blob/master/src/isomorphic/classic/types/ReactPropTypes.js
const ANONYMOUS = '<<anonymous>>';
function PropTypeError(message) {
  this.message = message;
  this.stack = '';
}
// Make `instanceof Error` still work for returned errors.
PropTypeError.prototype = Error.prototype;
 
const reactPropTypeLocationNames = {
  prop: 'prop',
  context: 'context',
  childContext: 'child context',
};
 
function createChainableTypeChecker(validate) {
  function checkType(
    isRequired,
    props,
    propName,
    componentName,
    location,
    propFullName,
  ) {
    componentName = componentName || ANONYMOUS;
    propFullName = propFullName || propName;
    if (props[propName] == null) {
      const locationName = reactPropTypeLocationNames[location];
      if (isRequired) {
        if (props[propName] === null) {
          return new PropTypeError(
            `The ${locationName} \`${propFullName}\` is marked as required ` +
              `in \`${componentName}\`, but its value is \`null\`.`,
          );
        }
        return new PropTypeError(
          `The ${locationName} \`${propFullName}\` is marked as required in ` +
            `\`${componentName}\`, but its value is \`undefined\`.`,
        );
      }
      return null;
    } else {
      return validate(props, propName, componentName, location, propFullName);
    }
  }
 
  const chainedCheckType = checkType.bind(null, false);
  chainedCheckType.isRequired = checkType.bind(null, true);
 
  return chainedCheckType;
}
 
export function propType(doc) {
  return createChainableTypeChecker((props, propName) => {
    const prop = props[propName];
    try {
      check(doc, prop);
      return null;
    } catch (e) {
      // Need a much better error.
      // Also we aren't checking for extra fields
      return e;
    }
  });
}