text: /**
   * Copyright (c) 2013-present, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   *
   * 
   * @providesModule RelayFlowParser
   * @format
   */
  
  'use strict';
  
  var _toConsumableArray3 = _interopRequireDefault(require('babel-runtime/helpers/toConsumableArray'));
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  
  var _require = require('./RelaySchemaUtils'),
      isOperationDefinitionAST = _require.isOperationDefinitionAST;
  
  var _require2 = require('graphql'),
      ArgumentsOfCorrectTypeRule = _require2.ArgumentsOfCorrectTypeRule,
      DefaultValuesOfCorrectTypeRule = _require2.DefaultValuesOfCorrectTypeRule,
      FieldsOnCorrectTypeRule = _require2.FieldsOnCorrectTypeRule,
      formatError = _require2.formatError,
      FragmentsOnCompositeTypesRule = _require2.FragmentsOnCompositeTypesRule,
      KnownArgumentNamesRule = _require2.KnownArgumentNamesRule,
      KnownTypeNamesRule = _require2.KnownTypeNamesRule,
      parse = _require2.parse,
      PossibleFragmentSpreadsRule = _require2.PossibleFragmentSpreadsRule,
      ProvidedNonNullArgumentsRule = _require2.ProvidedNonNullArgumentsRule,
      Source = _require2.Source,
      validate = _require2.validate,
      VariablesInAllowedPositionRule = _require2.VariablesInAllowedPositionRule;
  
  var RELAY_CLASSIC_MUTATION = '__RelayClassicMutation__';
  
  /**
   * Validates that a given DocumentNode is properly formed. Returns an Array
   * of ValidationErrors if there are errors.
   */
  function validateDocument(document, documentName, schema) {
    require('fbjs/lib/invariant')(document.definitions.length === 1, 'You supplied a GraphQL document named `%s` with %d definitions, but ' + 'it must have exactly one definition.', documentName, document.definitions.length);
    var definition = document.definitions[0];
    var isMutation = definition.kind === 'OperationDefinition' && definition.operation === 'mutation';
  
    var rules = [ArgumentsOfCorrectTypeRule, DefaultValuesOfCorrectTypeRule, FieldsOnCorrectTypeRule, FragmentsOnCompositeTypesRule, KnownArgumentNamesRule, KnownTypeNamesRule, PossibleFragmentSpreadsRule, VariablesInAllowedPositionRule];
    if (!isMutation) {
      rules.push(ProvidedNonNullArgumentsRule);
    }
    var validationErrors = validate(schema, document, rules);
  
    if (validationErrors && validationErrors.length > 0) {
      return validationErrors.map(formatError);
    }
    return null;
  }
  
  /**
   * Parses a given string containing one or more GraphQL operations into an array
   * of GraphQL documents.
   */
  function parseRelayGraphQL(source, schema) {
    var sourceName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'default';
  
    // We need to ignore these directives. The RelayParser cannot handle these
    // directives, so this needs to happen here.
    var PATTERN_LIST = ['@relay(pattern:true)', '@fixme_fat_interface'];
    var strippedSource = source.replace(/ /g, '');
    var patternFound = PATTERN_LIST.some(function (pattern) {
      var isSubstring = strippedSource.indexOf(pattern) !== -1;
      if (isSubstring) {
        console.warn('Skipping Relay.QL template string because it contains ' + pattern + ': ' + sourceName);
      }
      return isSubstring;
    });
    if (patternFound) {
      return [];
    }
  
    var ast = null;
    try {
      ast = parse(new Source(source, sourceName));
    } catch (e) {
      console.error('\n-- GraphQL Parsing Error --\n');
      console.error(['File:  ' + sourceName, 'Error: ' + e.message].join('\n'));
      return [];
    }
  
    var validationErrors = validateDocument(ast, sourceName, schema);
    if (validationErrors) {
      var errorMessages = [];
      var sourceLines = source.split('\n');
      validationErrors.forEach(function (_ref) {
        var message = _ref.message,
            locations = _ref.locations;
  
        errorMessages.push(message);
        console.error('\n-- GraphQL Validation Error --\n');
        console.error(['File:  ' + sourceName, 'Error: ' + message, 'Source:'].join('\n'));
        locations.forEach(function (location) {
          var preview = sourceLines[location.line - 1];
          if (preview) {
            console.error(['> ', '> ' + preview, '> ' + ' '.repeat(location.column - 1) + '^^^'].join('\n'));
          }
        });
      });
      return [];
    }
  
    var _ast = ast,
        definitions = _ast.definitions;
  
    definitions.forEach(function (definition) {
      if (definition.kind !== 'OperationDefinition' || definition.operation !== 'mutation') {
        return;
      }
  
      var selections = definition.selectionSet.selections;
      // As of now, FB mutations should only have one input.
      require('fbjs/lib/invariant')(selections.length <= 1, 'Mutations should only have one argument, ' + selections.length + ' found.');
  
      var mutationField = selections[0];
      require('fbjs/lib/invariant')(mutationField.kind === 'Field', 'RelayFlowParser: Expected the first selection of a mutation to be a ' + 'field, got `%s`.', mutationField.kind);
      if (definition.name == null) {
        // We need to manually add a `name` and a selection to each `selectionSet`
        // in order for this to be a valid GraphQL document. The RelayParser will
        // throw an error if we give it a "classic" mutation. `__typename` is a
        // valid field in *all* mutation payloads.
        definition.name = {
          kind: 'Name',
          value: RELAY_CLASSIC_MUTATION
        };
        mutationField.selectionSet = {
          kind: 'SelectionSet',
          selections: [{
            kind: 'Field',
            name: {
              kind: 'Name',
              value: '__typename'
            }
          }]
        };
      }
    });
  
    var nodes = [];
    definitions.forEach(function (definition) {
      if (isOperationDefinitionAST(definition)) {
        nodes.push(require('./RelayParser').transform(schema, definition));
      }
    });
    return nodes;
  }
  
  /**
   * Parses each extracted template literal from an array of ExtractedRelayTags
   * into a GraphQL Document type. Each element in the returned array is a
   * ExtractedGQLDocuments type which includes the filename.
   */
  function transformFiles(extractedTags, schema) {
    var gqlMapping = [];
    extractedTags.forEach(function (file) {
      var documents = [];
      file.tags.forEach(function (tag) {
        var transformed = parseRelayGraphQL(tag, schema, file.filename);
        if (transformed.length) {
          documents.push.apply(documents, (0, _toConsumableArray3['default'])(transformed));
        }
      });
  
      if (documents.length) {
        gqlMapping.push({
          filename: file.filename,
          documents: documents
        });
      }
    });
    return gqlMapping;
  }
  
  module.exports = {
    transformFiles: transformFiles,
    parse: parseRelayGraphQL,
    RELAY_CLASSIC_MUTATION: RELAY_CLASSIC_MUTATION
  };