text: import { cloneDeep } from './util/cloneDeep';
  import { checkDocument, getOperationDefinitionOrDie, getFragmentDefinitions, createFragmentMap, } from './getFromAST';
  var TYPENAME_FIELD = {
      kind: 'Field',
      name: {
          kind: 'Name',
          value: '__typename',
      },
  };
  function isNotEmpty(op, fragments) {
      return (op.selectionSet.selections.filter(function (selectionSet) {
          return !(selectionSet &&
              selectionSet.kind === 'FragmentSpread' &&
              !isNotEmpty(fragments[selectionSet.name.value], fragments));
      }).length > 0);
  }
  function getDirectiveMatcher(directives) {
      return function directiveMatcher(directive) {
          return directives.some(function (dir) {
              if (dir.name && dir.name === directive.name.value)
                  return true;
              if (dir.test && dir.test(directive))
                  return true;
              return false;
          });
      };
  }
  function addTypenameToSelectionSet(selectionSet, isRoot) {
      if (isRoot === void 0) { isRoot = false; }
      if (selectionSet.selections) {
          if (!isRoot) {
              var alreadyHasThisField = selectionSet.selections.some(function (selection) {
                  return (selection.kind === 'Field' &&
                      selection.name.value === '__typename');
              });
              if (!alreadyHasThisField) {
                  selectionSet.selections.push(TYPENAME_FIELD);
              }
          }
          selectionSet.selections.forEach(function (selection) {
              if (selection.kind === 'Field') {
                  if (selection.name.value.lastIndexOf('__', 0) !== 0 &&
                      selection.selectionSet) {
                      addTypenameToSelectionSet(selection.selectionSet);
                  }
              }
              else if (selection.kind === 'InlineFragment') {
                  if (selection.selectionSet) {
                      addTypenameToSelectionSet(selection.selectionSet);
                  }
              }
          });
      }
  }
  function removeDirectivesFromSelectionSet(directives, selectionSet) {
      if (!selectionSet.selections)
          return selectionSet;
      var agressiveRemove = directives.some(function (dir) { return dir.remove; });
      selectionSet.selections = selectionSet.selections
          .map(function (selection) {
          if (selection.kind !== 'Field' ||
              !selection ||
              !selection.directives)
              return selection;
          var directiveMatcher = getDirectiveMatcher(directives);
          var remove;
          selection.directives = selection.directives.filter(function (directive) {
              var shouldKeep = !directiveMatcher(directive);
              if (!remove && !shouldKeep && agressiveRemove)
                  remove = true;
              return shouldKeep;
          });
          return remove ? null : selection;
      })
          .filter(function (x) { return !!x; });
      selectionSet.selections.forEach(function (selection) {
          if ((selection.kind === 'Field' || selection.kind === 'InlineFragment') &&
              selection.selectionSet) {
              removeDirectivesFromSelectionSet(directives, selection.selectionSet);
          }
      });
      return selectionSet;
  }
  export function removeDirectivesFromDocument(directives, doc) {
      var docClone = cloneDeep(doc);
      docClone.definitions.forEach(function (definition) {
          removeDirectivesFromSelectionSet(directives, definition.selectionSet);
      });
      var operation = getOperationDefinitionOrDie(docClone);
      var fragments = createFragmentMap(getFragmentDefinitions(docClone));
      return isNotEmpty(operation, fragments) ? docClone : null;
  }
  var added = new Map();
  export function addTypenameToDocument(doc) {
      checkDocument(doc);
      var cached = added.get(doc);
      if (cached)
          return cached;
      var docClone = cloneDeep(doc);
      docClone.definitions.forEach(function (definition) {
          var isRoot = definition.kind === 'OperationDefinition';
          addTypenameToSelectionSet(definition.selectionSet, isRoot);
      });
      added.set(doc, docClone);
      return docClone;
  }
  var connectionRemoveConfig = {
      test: function (directive) {
          var willRemove = directive.name.value === 'connection';
          if (willRemove) {
              if (!directive.arguments ||
                  !directive.arguments.some(function (arg) { return arg.name.value === 'key'; })) {
                  console.warn('Removing an @connection directive even though it does not have a key. ' +
                      'You may want to use the key parameter to specify a store key.');
              }
          }
          return willRemove;
      },
  };
  var removed = new Map();
  export function removeConnectionDirectiveFromDocument(doc) {
      checkDocument(doc);
      var cached = removed.get(doc);
      if (cached)
          return cached;
      var docClone = removeDirectivesFromDocument([connectionRemoveConfig], doc);
      removed.set(doc, docClone);
      return docClone;
  }
  function hasDirectivesInSelectionSet(directives, selectionSet, nestedCheck) {
      if (nestedCheck === void 0) { nestedCheck = true; }
      if (!(selectionSet && selectionSet.selections)) {
          return false;
      }
      var matchedSelections = selectionSet.selections.filter(function (selection) {
          return hasDirectivesInSelection(directives, selection, nestedCheck);
      });
      return matchedSelections.length > 0;
  }
  function hasDirectivesInSelection(directives, selection, nestedCheck) {
      if (nestedCheck === void 0) { nestedCheck = true; }
      if (selection.kind !== 'Field' || !selection) {
          return true;
      }
      if (!selection.directives) {
          return false;
      }
      var directiveMatcher = getDirectiveMatcher(directives);
      var matchedDirectives = selection.directives.filter(directiveMatcher);
      return (matchedDirectives.length > 0 ||
          (nestedCheck &&
              hasDirectivesInSelectionSet(directives, selection.selectionSet, nestedCheck)));
  }
  function getDirectivesFromSelectionSet(directives, selectionSet) {
      selectionSet.selections = selectionSet.selections
          .filter(function (selection) {
          return hasDirectivesInSelection(directives, selection, true);
      })
          .map(function (selection) {
          if (hasDirectivesInSelection(directives, selection, false)) {
              return selection;
          }
          if ((selection.kind === 'Field' || selection.kind === 'InlineFragment') &&
              selection.selectionSet) {
              selection.selectionSet = getDirectivesFromSelectionSet(directives, selection.selectionSet);
          }
          return selection;
      });
      return selectionSet;
  }
  export function getDirectivesFromDocument(directives, doc, includeAllFragments) {
      if (includeAllFragments === void 0) { includeAllFragments = false; }
      checkDocument(doc);
      var docClone = cloneDeep(doc);
      docClone.definitions = docClone.definitions.map(function (definition) {
          if ((definition.kind === 'OperationDefinition' ||
              (definition.kind === 'FragmentDefinition' && !includeAllFragments)) &&
              definition.selectionSet) {
              definition.selectionSet = getDirectivesFromSelectionSet(directives, definition.selectionSet);
          }
          return definition;
      });
      var operation = getOperationDefinitionOrDie(docClone);
      var fragments = createFragmentMap(getFragmentDefinitions(docClone));
      return isNotEmpty(operation, fragments) ? docClone : null;
  }
  //# sourceMappingURL=transform.js.map