<commit_before>import * as graphqlFetch from 'graphql-fetch';
import {
  parse,
  print,
  visit,
  TypeInfo,
  extendSchema,
  visitWithTypeInfo,
  buildClientSchema,
  introspectionQuery,
} from 'graphql';

import { fakeSchema } from './fake_schema';

export function proxyMiddleware(url) {
  const remoteServer = graphqlFetch(url) as
    (query:String, vars?:any, opts?:any) => Promise<any>;

  return remoteServer(introspectionQuery).then(introspection => {
    //TODO: check for errors
    const serverSchema = buildClientSchema(introspection.data);
    return (extensionIDL, request, params) => {
      const extensionAST = parse(extensionIDL);
      const extensionFields = getExtensionFields(extensionAST);
      const schema = extendSchema(serverSchema, extensionAST);
      fakeSchema(schema);

      //TODO fail if params.operationName set
      //TODO copy headers
      const originalQuery = params.query;
      if (!originalQuery)
        return { schema };

      const query = stripQuery(schema, originalQuery, extensionFields);
      console.log(query);
      //TODO: also cleanup params
      return remoteServer(query, params.variables).then(responce => {
        //TODO proxy error
        return { schema, rootValue: responce.data};
      });
    };
  })
}

function getExtensionFields(extensionAST) {
  return {
    Person: ['pet']
  };
}

const typenameAST = {
  kind: 'Field',
  name: {
    kind: 'Name',
    value: '__typename',
  },
};

function stripQuery(schema, query, extensionFields) {
  const queryAST = parse(query);
  const typeInfo = new TypeInfo(schema);

  //TODO: inline all fragments
  const changedAST = visit(queryAST, visitWithTypeInfo(typeInfo, {
    Field() {
      const typeName = typeInfo.getParentType().name;
      const fieldName = typeInfo.getFieldDef().name;

      if ((extensionFields[typeName] || []).includes(fieldName))
        return null;
    },
    SelectionSet: {
      leave(node) {
        return {
          kind: node.kind,
          selections: [
            ...node.selections,
            typenameAST,
          ],
        };
      }
    },
  }), null);

  return print(changedAST);
}
<commit_msg>Use constants for AST kind values<commit_after>import * as graphqlFetch from 'graphql-fetch';
import {
  Kind,
  parse,
  print,
  visit,
  TypeInfo,
  extendSchema,
  visitWithTypeInfo,
  buildClientSchema,
  introspectionQuery,
} from 'graphql';

import { fakeSchema } from './fake_schema';

export function proxyMiddleware(url) {
  const remoteServer = graphqlFetch(url) as
    (query:String, vars?:any, opts?:any) => Promise<any>;

  return remoteServer(introspectionQuery).then(introspection => {
    //TODO: check for errors
    const serverSchema = buildClientSchema(introspection.data);
    return (extensionIDL, request, params) => {
      const extensionAST = parse(extensionIDL);
      const extensionFields = getExtensionFields(extensionAST);
      const schema = extendSchema(serverSchema, extensionAST);
      fakeSchema(schema);

      //TODO fail if params.operationName set
      //TODO copy headers
      const originalQuery = params.query;
      if (!originalQuery)
        return { schema };

      const query = stripQuery(schema, originalQuery, extensionFields);
      console.log(query);
      //TODO: also cleanup params
      return remoteServer(query, params.variables).then(responce => {
        //TODO proxy error
        return { schema, rootValue: responce.data};
      });
    };
  })
}

function getExtensionFields(extensionAST) {
  return {
    Person: ['pet']
  };
}

const typenameAST = {
  kind: Kind.FIELD,
  name: {
    kind: Kind.NAME,
    value: '__typename',
  },
};

function stripQuery(schema, query, extensionFields) {
  const queryAST = parse(query);
  const typeInfo = new TypeInfo(schema);

  //TODO: inline all fragments
  const changedAST = visit(queryAST, visitWithTypeInfo(typeInfo, {
    [Kind.FIELD]: () => {
      const typeName = typeInfo.getParentType().name;
      const fieldName = typeInfo.getFieldDef().name;

      if ((extensionFields[typeName] || []).includes(fieldName))
        return null;
    },
    [Kind.SELECTION_SET]: {
      leave(node) {
        return {
          kind: node.kind,
          selections: [
            ...node.selections,
            typenameAST,
          ],
        };
      }
    },
  }), null);

  return print(changedAST);
}

{'fraction_non_alphanumeric': 0.11861313868613138, 'fraction_numerical': 0.0, 'mean_word_length': 2.9468946894689467, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 14, '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': '2153243', 'n_tokens_mistral': 1278, 'n_tokens_neox': 1266, 'n_words': 298}