<commit_before>import {reduce, isArray} from 'lodash';
import {
  GraphQLList,
  GraphQLNonNull,
  GraphQLID,
  GraphQLObjectType,
  GraphQLSchema,
  GraphQLBoolean,
  GraphQLFloat
} from 'graphql';
import {
  mutationWithClientMutationId,
  connectionArgs,
  connectionDefinitions,
  globalIdField
} from 'graphql-relay';
import model from './../model';
import {
  GraphQLViewer,
  nodeInterface,
  getTypeFields,
  getArguments,
  setTypeFields
} from './../type';
import type from './../type';
import {
  idToCursor,
  getIdFetcher,
  connectionFromModel
} from './../query';
import query from './../query';
import {addHooks} from '../utils';
import viewerInstance from '../model/viewer';
import {toCollectionName} from 'mongoose/lib/utils';
import createInputObject from '../type/custom/to-input-object';

const idField = {
  name: 'id',
  type: new GraphQLNonNull(GraphQLID)
};

function getSingularQueryField(graffitiModel, type, hooks = {}) {
  const {name} = type;
  const {singular} = hooks;
  const singularName = name.toLowerCase();

  return {
    [singularName]: {
      type,
      args: {
        id: idField
      },
      resolve: addHooks(query.getOneResolver(graffitiModel), singular)
    }
  };
}

function getPluralQueryField(graffitiModel, type, hooks = {}) {
  const {name} = type;
  const {plural} = hooks;
  const pluralName = toCollectionName(name);

  return {
    [pluralName]: {
      type: new GraphQLList(type),
      args: getArguments(type, {
        id: {
          type: new GraphQLList(GraphQLID),
          description: `The ID of a ${name}`
        },
        ids: {
          type: new GraphQLList(GraphQLID),
          description: `The ID of a ${name}`
        }
      }),
      resolve: addHooks(query.getListResolver(graffitiModel), plural)
    }
  };
}

function getQueryField(graffitiModel, type, hooks) {
  return {
    ...getSingularQueryField(graffitiModel, type, hooks),
    ...getPluralQueryField(graffitiModel, type, hooks)
  };
}

function getConnectionField(graffitiModel, type, hooks = {}) {
  const {name} = type;
  const {plural} = hooks;
  const pluralName = toCollectionName(name.toLowerCase());
  const {connectionType} = connectionDefinitions({name, nodeType: type, connectionFields: {
    count: {
      name: 'count',
      type: GraphQLFloat
    }
  }});

  return {
    [pluralName]: {
      args: getArguments(type, connectionArgs),
      type: connectionType,
      resolve: addHooks((rootValue, args, info) => connectionFromModel(graffitiModel, args, info), plural)
    }
  };
}

function getMutationField(graffitiModel, type, viewer, hooks = {}, allowMongoIDMutation) {
  const {name} = type;
  const {mutation} = hooks;

  const fields = getTypeFields(type);
  const inputFields = reduce(fields, (inputFields, field) => {
    if (field.type instanceof GraphQLObjectType) {
      if (field.type.name.endsWith('Connection')) {
        inputFields[field.name] = {
          name: field.name,
          type: new GraphQLList(GraphQLID)
        };
      } else if (field.type.mongooseEmbedded) {
        inputFields[field.name] = {
          name: field.name,
          type: createInputObject(field.type)
        };
      } else {
        inputFields[field.name] = {
          name: field.name,
          type: GraphQLID
        };
      }
    }

    if (field.type instanceof GraphQLList && field.type.ofType instanceof GraphQLObjectType) {
      // TODO support objects nested in lists
    } else if (!(field.type instanceof GraphQLObjectType)
        && field.name !== 'id' && field.name !== '__v'
        && (allowMongoIDMutation || field.name !== '_id')) {
      inputFields[field.name] = field;
    }

    return inputFields;
  }, {});

  const updateInputFields = reduce(fields, (inputFields, field) => {
    if (field.type instanceof GraphQLObjectType && field.type.name.endsWith('Connection')) {
      inputFields[`${field.name}_add`] = {
        name: field.name,
        type: new GraphQLList(GraphQLID)<commit_msg>feat(schema): add support for objects nested in lists<commit_after>import {reduce, isArray} from 'lodash';
import {
  GraphQLList,
  GraphQLNonNull,
  GraphQLID,
  GraphQLObjectType,
  GraphQLSchema,
  GraphQLBoolean,
  GraphQLFloat
} from 'graphql';
import {
  mutationWithClientMutationId,
  connectionArgs,
  connectionDefinitions,
  globalIdField
} from 'graphql-relay';
import model from './../model';
import {
  GraphQLViewer,
  nodeInterface,
  getTypeFields,
  getArguments,
  setTypeFields
} from './../type';
import type from './../type';
import {
  idToCursor,
  getIdFetcher,
  connectionFromModel
} from './../query';
import query from './../query';
import {addHooks} from '../utils';
import viewerInstance from '../model/viewer';
import {toCollectionName} from 'mongoose/lib/utils';
import createInputObject from '../type/custom/to-input-object';

const idField = {
  name: 'id',
  type: new GraphQLNonNull(GraphQLID)
};

function getSingularQueryField(graffitiModel, type, hooks = {}) {
  const {name} = type;
  const {singular} = hooks;
  const singularName = name.toLowerCase();

  return {
    [singularName]: {
      type,
      args: {
        id: idField
      },
      resolve: addHooks(query.getOneResolver(graffitiModel), singular)
    }
  };
}

function getPluralQueryField(graffitiModel, type, hooks = {}) {
  const {name} = type;
  const {plural} = hooks;
  const pluralName = toCollectionName(name);

  return {
    [pluralName]: {
      type: new GraphQLList(type),
      args: getArguments(type, {
        id: {
          type: new GraphQLList(GraphQLID),
          description: `The ID of a ${name}`
        },
        ids: {
          type: new GraphQLList(GraphQLID),
          description: `The ID of a ${name}`
        }
      }),
      resolve: addHooks(query.getListResolver(graffitiModel), plural)
    }
  };
}

function getQueryField(graffitiModel, type, hooks) {
  return {
    ...getSingularQueryField(graffitiModel, type, hooks),
    ...getPluralQueryField(graffitiModel, type, hooks)
  };
}

function getConnectionField(graffitiModel, type, hooks = {}) {
  const {name} = type;
  const {plural} = hooks;
  const pluralName = toCollectionName(name.toLowerCase());
  const {connectionType} = connectionDefinitions({name, nodeType: type, connectionFields: {
    count: {
      name: 'count',
      type: GraphQLFloat
    }
  }});

  return {
    [pluralName]: {
      args: getArguments(type, connectionArgs),
      type: connectionType,
      resolve: addHooks((rootValue, args, info) => connectionFromModel(graffitiModel, args, info), plural)
    }
  };
}

function getMutationField(graffitiModel, type, viewer, hooks = {}, allowMongoIDMutation) {
  const {name} = type;
  const {mutation} = hooks;

  const fields = getTypeFields(type);
  const inputFields = reduce(fields, (inputFields, field) => {
    if (field.type instanceof GraphQLObjectType) {
      if (field.type.name.endsWith('Connection')) {
        inputFields[field.name] = {
          name: field.name,
          type: new GraphQLList(GraphQLID)
        };
      } else if (field.type.mongooseEmbedded) {
        inputFields[field.name] = {
          name: field.name,
          type: createInputObject(field.type)
        };
      } else {
        inputFields[field.name] = {
          name: field.name,
          type: GraphQLID
        };
      }
    }

    if (field.type instanceof GraphQLList && field.type.ofType instanceof GraphQLObjectType) {
      inputFields[field.name] = {
        name: field.name,
        type: new GraphQLList(createInputObject(field.type.ofType))
      };
    } else if (!(field.type instanceof GraphQLObjectType)
        && field.name !== 'id' && field.name !== '__v'
        && (allowMongoIDMutation || field.name !== '_id')) {
      inputFields[field.name] = field;
    }

    return inputFields;
  }, {});

  const updateInputFields = reduce(fields, (inputFields, field) => {
    if (field.type instanceof GraphQLObjectType && field.type.name.endsWith('Connection')) {
      inputFields[`${field.name}_add`] = {
        name: field.name,
        type: new GraphQLList(GraphQLID)
{'fraction_non_alphanumeric': 0.1323801306545051, 'fraction_numerical': 0.0, 'mean_word_length': 3.065130260521042, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6774465', 'n_tokens_mistral': 2530, 'n_tokens_neox': 2521, 'n_words': 560}