Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
react-relay / lib / inferRelayFieldsFromData.js
Size: Mime:
/**
 * Copyright 2013-2015, 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 inferRelayFieldsFromData
 * @typechecks
 * 
 */

'use strict';

var _Object$keys = require('babel-runtime/core-js/object/keys')['default'];

var GraphQLStoreDataHandler = require('./GraphQLStoreDataHandler');
var RelayConnectionInterface = require('./RelayConnectionInterface');
var RelayNodeInterface = require('./RelayNodeInterface');
var RelayQuery = require('./RelayQuery');

var forEachObject = require('fbjs/lib/forEachObject');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');

var ARGUMENTS = /^(\w+)(?:\((.+?)\))?$/;
var ARGUMENT_NAME = /(\w+)(?=\s*:)/;
var DEPRECATED_CALLS = /^\w+(?:\.\w+\(.*?\))+$/;
var DEPRECATED_CALL = /^(\w+)\((.*?)\)$/;
var NODE = RelayConnectionInterface.NODE;
var EDGES = RelayConnectionInterface.EDGES;
var ANY_TYPE = RelayNodeInterface.ANY_TYPE;
var ID = RelayNodeInterface.ID;

var idField = RelayQuery.Field.build({
  fieldName: ID,
  type: 'String'
});
var cursorField = RelayQuery.Field.build({
  fieldName: 'cursor',
  type: 'String'
});

/**
 * @internal
 *
 * Given a record-like object, infers fields that could be used to fetch them.
 * Properties that are fetched via fields with arguments can be encoded by
 * serializing the arguments in property keys.
 */
function inferRelayFieldsFromData(data) {
  var fields = [];
  forEachObject(data, function (value, key) {
    if (!GraphQLStoreDataHandler.isMetadataKey(key)) {
      fields.push(inferField(value, key));
    }
  });
  return fields;
}

function inferField(value, key) {
  var metadata = {
    isPlural: false
  };
  var children = undefined;
  if (Array.isArray(value)) {
    var element = value[0];
    if (element && typeof element === 'object') {
      children = inferRelayFieldsFromData(element);
    } else {
      children = [];
    }
    metadata.isPlural = true;
  } else if (typeof value === 'object' && value !== null) {
    children = inferRelayFieldsFromData(value);
  } else {
    children = [];
  }
  if (key === NODE) {
    children.push(idField);
  } else if (key === EDGES) {
    children.push(cursorField);
  }
  return buildField(key, children, metadata);
}

function buildField(key, children, metadata) {
  var fieldName = key;
  var calls = null;
  if (DEPRECATED_CALLS.test(key)) {
    process.env.NODE_ENV !== 'production' ? warning(false, 'inferRelayFieldsFromData(): Encountered an optimistic payload with ' + 'a deprecated field call string, `%s`. Use valid GraphQL OSS syntax.', key) : undefined;
    var parts = key.split('.');
    if (parts.length > 1) {
      fieldName = parts.shift();
      calls = parts.map(function (callString) {
        var captures = callString.match(DEPRECATED_CALL);
        !captures ? process.env.NODE_ENV !== 'production' ? invariant(false, 'inferRelayFieldsFromData(): Malformed data key, `%s`.', key) : invariant(false) : undefined;
        var value = captures[2].split(',');
        return {
          name: captures[1],
          value: value.length === 1 ? value[0] : value
        };
      });
    }
  } else {
    var captures = key.match(ARGUMENTS);
    !captures ? process.env.NODE_ENV !== 'production' ? invariant(false, 'inferRelayFieldsFromData(): Malformed data key, `%s`.', key) : invariant(false) : undefined;
    fieldName = captures[1];
    if (captures[2]) {
      try {
        (function () {
          // Relay does not currently have a GraphQL argument parser, so...
          var args = JSON.parse('{' + captures[2].replace(ARGUMENT_NAME, '"$1"') + '}');
          calls = _Object$keys(args).map(function (name) {
            return { name: name, value: args[name] };
          });
        })();
      } catch (error) {
        !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'inferRelayFieldsFromData(): Malformed or unsupported data key, ' + '`%s`. Only booleans, strings, and numbers are currenly supported, ' + 'and commas are required. Parse failure reason was `%s`.', key, error.message) : invariant(false) : undefined;
      }
    }
  }
  return RelayQuery.Field.build({
    calls: calls,
    children: children,
    fieldName: fieldName,
    metadata: metadata,
    type: ANY_TYPE
  });
}

module.exports = inferRelayFieldsFromData;