docs: function getFields(graffitiModels, {
      hooks = {}, mutation = true, allowMongoIDMutation = false,
      customQueries = {}, customMutations = {}
    } = {}) {
    const types = type.getTypes(graffitiModels);
    const { viewer, singular } = hooks;
  
    const viewerFields = reduce(types, (fields, type, key) => {
      type.name = type.name || key;
      const graffitiModel = graffitiModels[type.name];
      return {
        ...fields,
        ...getConnectionField(graffitiModel, type, hooks),
        ...getSingularQueryField(graffitiModel, type, hooks)
      };
    }, {
      id: globalIdField('Viewer')
    });
    setTypeFields(GraphQLViewer, viewerFields);
  
    const viewerField = {
      name: 'Viewer',
      type: GraphQLViewer,
      resolve: addHooks(() => viewerInstance, viewer)
    };
  
    const { queries, mutations } = reduce(types, ({ queries, mutations }, type, key) => {
      type.name = type.name || key;
      const graffitiModel = graffitiModels[type.name];
      return {
        queries: {
          ...queries,
          ...getQueryField(graffitiModel, type, hooks)
        },
        mutations: {
          ...mutations,
          ...getMutationField(graffitiModel, type, viewerField, hooks, allowMongoIDMutation)
        }
      };
    }, {
      queries: isFunction(customQueries)
        ? customQueries(mapValues(types, (type) => createInputObject(type)), types)
        : customQueries,
      mutations: isFunction(customMutations)
        ? customMutations(mapValues(types, (type) => createInputObject(type)), types)
        : customMutations
    });
  
    const RootQuery = new GraphQLObjectType({
      name: 'RootQuery',
      fields: {
        ...queries,
        viewer: viewerField,
        node: {
          name: 'node',
          description: 'Fetches an object given its ID',
          type: nodeInterface,
          args: {
            id: {
              type: new GraphQLNonNull(GraphQLID),
              description: 'The ID of an object'
            }
          },
          resolve: addHooks(getIdFetcher(graffitiModels), singular)
        }
      }
    });
  
    const RootMutation = new GraphQLObjectType({
      name: 'RootMutation',
      fields: mutations
    });
  
    const fields = {
      query: RootQuery
    };
  
    if (mutation) {
      fields.mutation = RootMutation;
    }
  
    return fields;
  }