graphql#GraphQLID TypeScript Examples

The following examples show how to use graphql#GraphQLID. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: schema_builder.ts    From graphql-mesh with MIT License 5 votes vote down vote up
/**
 * Returns the GraphQL scalar type matching the given JSON schema type
 */
function getScalarType<TSource, TContext, TArgs>({
  def,
  data,
}: CreateOrReuseSimpleTypeParams<TSource, TContext, TArgs>): GraphQLScalarType {
  switch (def.targetGraphQLType) {
    case 'id':
      def.graphQLType = GraphQLID;
      break;
    case 'string':
      def.graphQLType = GraphQLString;
      break;
    case 'integer':
      def.graphQLType = GraphQLInt;
      break;
    case 'int64':
      def.graphQLType = GraphQLBigInt;
      break;
    case 'number':
      def.graphQLType = GraphQLFloat;
      break;
    case 'float':
      def.graphQLType = GraphQLFloat;
      break;
    case 'boolean':
      def.graphQLType = GraphQLBoolean;
      break;
    case 'json':
      def.graphQLType = GraphQLJSON;
      break;
    case 'dateTime':
      def.graphQLType = GraphQLDateTime;
      break;
    default:
      throw new Error(`Cannot process schema type '${def.targetGraphQLType}'.`);
  }

  return def.graphQLType as GraphQLScalarType;
}
Example #2
Source File: scalars.ts    From squid with GNU General Public License v3.0 5 votes vote down vote up
ID = GraphQLID
Example #3
Source File: typeNameFromGraphQLType.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
describe('Swift code generation: Types', () => {
  let helpers: Helpers;

  beforeEach(() => {
    helpers = new Helpers({});
  });

  describe('#typeNameFromGraphQLType()', () => {
    it('should return String? for GraphQLString', () => {
      expect(helpers.typeNameFromGraphQLType(GraphQLString)).toBe('String?');
    });

    it('should return String for GraphQLNonNull(GraphQLString)', () => {
      expect(helpers.typeNameFromGraphQLType(new GraphQLNonNull(GraphQLString))).toBe('String');
    });

    it('should return [String?]? for GraphQLList(GraphQLString)', () => {
      expect(helpers.typeNameFromGraphQLType(new GraphQLList(GraphQLString))).toBe('[String?]?');
    });

    it('should return [String?] for GraphQLNonNull(GraphQLList(GraphQLString))', () => {
      expect(helpers.typeNameFromGraphQLType(new GraphQLNonNull(new GraphQLList(GraphQLString)))).toBe('[String?]');
    });

    it('should return [String]? for GraphQLList(GraphQLNonNull(GraphQLString))', () => {
      expect(helpers.typeNameFromGraphQLType(new GraphQLList(new GraphQLNonNull(GraphQLString)))).toBe('[String]?');
    });

    it('should return [String] for GraphQLNonNull(GraphQLList(GraphQLNonNull(GraphQLString)))', () => {
      expect(helpers.typeNameFromGraphQLType(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))))).toBe('[String]');
    });

    it('should return [[String?]?]? for GraphQLList(GraphQLList(GraphQLString))', () => {
      expect(helpers.typeNameFromGraphQLType(new GraphQLList(new GraphQLList(GraphQLString)))).toBe('[[String?]?]?');
    });

    it('should return [[String?]]? for GraphQLList(GraphQLNonNull(GraphQLList(GraphQLString)))', () => {
      expect(helpers.typeNameFromGraphQLType(new GraphQLList(new GraphQLNonNull(new GraphQLList(GraphQLString))))).toBe('[[String?]]?');
    });

    it('should return Int? for GraphQLInt', () => {
      expect(helpers.typeNameFromGraphQLType(GraphQLInt)).toBe('Int?');
    });

    it('should return Double? for GraphQLFloat', () => {
      expect(helpers.typeNameFromGraphQLType(GraphQLFloat)).toBe('Double?');
    });

    it('should return Bool? for GraphQLBoolean', () => {
      expect(helpers.typeNameFromGraphQLType(GraphQLBoolean)).toBe('Bool?');
    });

    it('should return GraphQLID? for GraphQLID', () => {
      expect(helpers.typeNameFromGraphQLType(GraphQLID)).toBe('GraphQLID?');
    });

    it('should return String? for a custom scalar type', () => {
      expect(helpers.typeNameFromGraphQLType(new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('String?');
    });

    it('should return a passed through custom scalar type with the passthroughCustomScalars option', () => {
      helpers.options.passthroughCustomScalars = true;
      helpers.options.customScalarsPrefix = '';

      expect(helpers.typeNameFromGraphQLType(new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe(
        'CustomScalarType?'
      );
    });

    it('should return a passed through custom scalar type with a prefix with the customScalarsPrefix option', () => {
      helpers.options.passthroughCustomScalars = true;
      helpers.options.customScalarsPrefix = 'My';

      expect(helpers.typeNameFromGraphQLType(new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe(
        'MyCustomScalarType?'
      );
    });
  });
});
Example #4
Source File: types.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
builtInScalarMap = {
  [GraphQLString.name]: 'string',
  [GraphQLInt.name]: 'number',
  [GraphQLFloat.name]: 'number',
  [GraphQLBoolean.name]: 'boolean',
  [GraphQLID.name]: 'string',
}
Example #5
Source File: helpers.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
builtInScalarMap = {
  [GraphQLString.name]: 'String',
  [GraphQLInt.name]: 'Int',
  [GraphQLFloat.name]: 'Double',
  [GraphQLBoolean.name]: 'Bool',
  [GraphQLID.name]: 'GraphQLID',
}
Example #6
Source File: helpers.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
builtInScalarMap = {
  [GraphQLString.name]: t.stringTypeAnnotation(),
  [GraphQLInt.name]: t.numberTypeAnnotation(),
  [GraphQLFloat.name]: t.numberTypeAnnotation(),
  [GraphQLBoolean.name]: t.booleanTypeAnnotation(),
  [GraphQLID.name]: t.stringTypeAnnotation(),
}
Example #7
Source File: getBody.test.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
describe('getBody', () => {
  const arg: GraphQLArgument = {
    name: 'id',
    type: GraphQLID,
  };
  const blogArticle = new GraphQLObjectType({
    name: 'BlogArticle',
    fields: {
      id: { type: GraphQLID },
      content: { type: GraphQLString },
    },
  });

  const schema = new GraphQLSchema({
    query: new GraphQLObjectType({
      name: 'Query',
      fields: {
        article: {
          args: { id: { type: GraphQLID } },
          type: blogArticle,
        },
      },
    }),
  });
  const mockFields = {
    filed1: 'field1',
    field2: 'field2',
  };

  beforeEach(() => {
    getFields.mockReturnValue(mockFields);
  });

  it('should return a list of arguments', () => {
    const query = schema.getQueryType().getFields().article;
    expect(getBody(query, schema, maxDepth, { useExternalFragmentForS3Object: true })).toEqual({
      args: [{ name: 'id', value: '$id' }],
      ...mockFields,
    });
    expect(getFields).toHaveBeenCalledWith(query, schema, maxDepth, { useExternalFragmentForS3Object: true });
  });
});
Example #8
Source File: getArgs.test.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
describe('getArgs', () => {
  const id: GraphQLArgument = {
    name: 'id',
    type: GraphQLID,
    defaultValue: '1',
  };

  const query: GraphQLArgument = {
    name: 'query',
    type: GraphQLString,
  };

  const blogArticle = new GraphQLObjectType({
    name: 'BlogArticle',
    fields: {
      id: { type: GraphQLID },
      content: { type: GraphQLString },
    },
  });

  const schema = new GraphQLSchema({
    query: new GraphQLObjectType({
      name: 'Query',
      fields: {
        searchArticle: {
          args: { id, query },
          type: blogArticle,
        },
      },
    }),
  });

  beforeEach(() => {
    jest.resetAllMocks();
    isRequired.mockReturnValue(false);
    getType.mockReturnValue({ name: 'mockType' });
    isRequiredList.mockReturnValue(false);
    isList.mockReturnValue(false);
  });

  it('should return arguments', () => {
    isList.mockReturnValueOnce(true);
    const query = schema.getQueryType().getFields().searchArticle;
    expect(getArgs(query.args)).toEqual([
      {
        name: 'id',
        type: 'mockType',
        defaultValue: '1',
        isRequired: false,
        isList: true,
        isListRequired: false,
      },
      {
        name: 'query',
        type: 'mockType',
        defaultValue: undefined,
        isRequired: false,
        isList: false,
        isListRequired: false,
      },
    ]);
    expect(getType).toHaveBeenCalledTimes(2);
    expect(getType.mock.calls[0][0]).toEqual(GraphQLID);
    expect(getType.mock.calls[1][0]).toEqual(GraphQLString);

    expect(isRequired).toHaveBeenCalledTimes(2);
    expect(isRequired.mock.calls[0][0]).toEqual(query.args[0].type);
    expect(isRequired.mock.calls[1][0]).toEqual(query.args[1].type);

    expect(isList).toHaveBeenCalledTimes(2);
    expect(isRequiredList).toHaveBeenCalledTimes(2);
  });
});
Example #9
Source File: custom-type-resolver.ts    From graphql-mesh with MIT License 5 votes vote down vote up
ID = GraphQLID;
Example #10
Source File: custom-type-resolver.ts    From graphql-mesh with MIT License 5 votes vote down vote up
ENTITIES = new GraphQLList(GraphQLID);
Example #11
Source File: custom-type-resolver.ts    From graphql-mesh with MIT License 5 votes vote down vote up
ENTITY = GraphQLID;
Example #12
Source File: custom-type-resolver.ts    From graphql-mesh with MIT License 5 votes vote down vote up
IDREFS = new GraphQLList(GraphQLID);
Example #13
Source File: custom-type-resolver.ts    From graphql-mesh with MIT License 5 votes vote down vote up
IDREF = GraphQLID;
Example #14
Source File: index.ts    From graphql-mesh with MIT License 4 votes vote down vote up
transformSchema(schema: GraphQLSchema, rawSource: SubschemaConfig) {
    const federationConfig: FederationConfig<any> = {};

    rawSource.merge = {};
    if (this.config?.types) {
      const queryType = schema.getQueryType();
      const queryTypeFields = queryType.getFields();
      for (const type of this.config.types) {
        rawSource.merge[type.name] = {};
        const fields: FederationFieldsConfig = {};
        if (type.config?.fields) {
          for (const field of type.config.fields) {
            fields[field.name] = field.config;
            rawSource.merge[type.name].fields = rawSource.merge[type.name].fields || {};
            rawSource.merge[type.name].fields[field.name] = rawSource.merge[type.name].fields[field.name] || {};
            if (field.config.requires) {
              rawSource.merge[type.name].fields[field.name].computed = true;
              rawSource.merge[type.name].fields[field.name].selectionSet = `{ ${field.config.requires} }`;
            }
          }
        }
        // If a field is a key field, it should be GraphQLID

        if (type.config?.keyFields) {
          rawSource.merge[type.name].selectionSet = `{ ${type.config.keyFields.join(' ')} }`;
          for (const fieldName of type.config.keyFields) {
            const objectType = schema.getType(type.name) as GraphQLObjectType;
            if (objectType) {
              const existingType = objectType.getFields()[fieldName].type;
              objectType.getFields()[fieldName].type = isNonNullType(existingType)
                ? new GraphQLNonNull(GraphQLID)
                : GraphQLID;
            }
          }
        }

        let resolveReference: MergedTypeResolver<any>;
        if (type.config?.resolveReference) {
          const resolveReferenceConfig = type.config.resolveReference;
          if (typeof resolveReferenceConfig === 'string') {
            const fn$ = loadFromModuleExportExpression<any>(resolveReferenceConfig, {
              cwd: this.baseDir,
              defaultExportName: 'default',
              importFn: this.importFn,
            });
            resolveReference = (...args: any[]) => fn$.then(fn => fn(...args));
          } else if (typeof resolveReferenceConfig === 'function') {
            resolveReference = resolveReferenceConfig;
          } else {
            const queryField = queryTypeFields[resolveReferenceConfig.queryFieldName];
            const keyArg = resolveReferenceConfig.keyArg || queryField.args[0].name;
            const keyField = type.config.keyFields[0];
            const isBatch = isListType(queryField.args.find(arg => arg.name === keyArg));
            resolveReference = async (root, context, info) => {
              const result = await context[this.apiName].Query[queryField.name]({
                root,
                ...(isBatch
                  ? {
                      key: root[keyField],
                      argsFromKeys: (keys: string[]) => ({
                        [keyArg]: keys,
                      }),
                    }
                  : {
                      args: {
                        [keyArg]: root[keyField],
                      },
                    }),
                context,
                info,
              });
              return {
                ...root,
                ...result,
              };
            };
          }
          rawSource.merge[type.name].resolve = resolveReference;
        }
        federationConfig[type.name] = {
          ...type.config,
          resolveReference,
          fields,
        };
      }
    }

    const entityTypes = Object.fromEntries(
      Object.entries(federationConfig)
        .filter(([, { keyFields }]) => keyFields?.length)
        .map(([objectName]) => {
          const type = schema.getType(objectName);
          if (!isObjectType(type)) {
            throw new Error(`Type "${objectName}" is not an object type and can't have a key directive`);
          }
          return [objectName, type];
        })
    );

    const hasEntities = !!Object.keys(entityTypes).length;

    const sdlWithFederationDirectives = addFederationAnnotations(printSchemaWithDirectives(schema), federationConfig);

    const schemaWithFederationQueryType = mapSchema(schema, {
      [MapperKind.QUERY]: type => {
        const config = type.toConfig();
        return new GraphQLObjectType({
          ...config,
          fields: {
            ...config.fields,
            ...(hasEntities && {
              _entities: entitiesField,
              _service: {
                ...serviceField,
                resolve: () => ({ sdl: sdlWithFederationDirectives }),
              },
            }),
          },
        });
      },
    });

    const schemaWithUnionType = mapSchema(schemaWithFederationQueryType, {
      [MapperKind.UNION_TYPE]: type => {
        if (type.name === EntityType.name) {
          return new GraphQLUnionType({
            ...EntityType.toConfig(),
            types: Object.values(entityTypes),
          });
        }
        return type;
      },
    });

    // Not using transformSchema since it will remove resolveReference
    Object.entries(federationConfig).forEach(([objectName, currentFederationConfig]) => {
      if (currentFederationConfig.resolveReference) {
        const type = schemaWithUnionType.getType(objectName);
        if (!isObjectType(type)) {
          throw new Error(`Type "${objectName}" is not an object type and can't have a resolveReference function`);
        }
        type.resolveObject = currentFederationConfig.resolveReference;
      }
    });

    return schemaWithUnionType;
  }
Example #15
Source File: index.ts    From graphql-mesh with MIT License 4 votes vote down vote up
async getMeshSource() {
    const { schemaHeaders, serviceName, operationHeaders } = this.config;

    const thriftAST = await this.idl.getWithSet(async () => {
      const rawThrift = await readFileOrUrl<string>(this.config.idl, {
        allowUnknownExtensions: true,
        cwd: this.baseDir,
        headers: schemaHeaders,
      });
      const parseResult = parse(rawThrift, { organize: false });
      if (parseResult.type === SyntaxType.ThriftErrors) {
        throw new AggregateError(parseResult.errors);
      }
      return parseResult;
    });

    const enumTypeMap = new Map<string, GraphQLEnumType>();
    const outputTypeMap = new Map<string, GraphQLOutputType>();
    const inputTypeMap = new Map<string, GraphQLInputType>();
    const rootFields: GraphQLFieldConfigMap<any, any> = {};
    const annotations: IThriftAnnotations = {};
    const methodAnnotations: IMethodAnnotations = {};
    const methodNames: string[] = [];
    const methodParameters: {
      [methodName: string]: number;
    } = {};

    type TypeVal = BaseTypeVal | ListTypeVal | SetTypeVal | MapTypeVal | EnumTypeVal | StructTypeVal | VoidTypeVal;
    type BaseTypeVal = {
      id?: number;
      type: TType.BOOL | TType.BYTE | TType.DOUBLE | TType.I16 | TType.I32 | TType.I64 | TType.STRING;
    };
    type ListTypeVal = { id?: number; type: TType.LIST; elementType: TypeVal };
    type SetTypeVal = { id?: number; type: TType.SET; elementType: TypeVal };
    type MapTypeVal = { id?: number; type: TType.MAP; keyType: TypeVal; valType: TypeVal };
    type EnumTypeVal = { id?: number; type: TType.ENUM };
    type StructTypeVal = { id?: number; type: TType.STRUCT; name: string; fields: TypeMap };
    type VoidTypeVal = { id?: number; type: TType.VOID };
    type TypeMap = Record<string, TypeVal>;
    const topTypeMap: TypeMap = {};

    class MeshThriftClient<Context = any> extends ThriftClient<Context> {
      public static readonly serviceName: string = serviceName;
      public static readonly annotations: IThriftAnnotations = annotations;
      public static readonly methodAnnotations: IMethodAnnotations = methodAnnotations;
      public static readonly methodNames: Array<string> = methodNames;
      public readonly _serviceName: string = serviceName;
      public readonly _annotations: IThriftAnnotations = annotations;
      public readonly _methodAnnotations: IMethodAnnotations = methodAnnotations;
      public readonly _methodNames: Array<string> = methodNames;
      public readonly _methodParameters?: {
        [methodName: string]: number;
      } = methodParameters;

      writeType(typeVal: TypeVal, value: any, output: TProtocol) {
        switch (typeVal.type) {
          case TType.BOOL:
            output.writeBool(value);
            break;
          case TType.BYTE:
            output.writeByte(value);
            break;
          case TType.DOUBLE:
            output.writeDouble(value);
            break;
          case TType.I16:
            output.writeI16(value);
            break;
          case TType.I32:
            output.writeI32(value);
            break;
          case TType.I64:
            output.writeI64(value.toString());
            break;
          case TType.STRING:
            output.writeString(value);
            break;
          case TType.STRUCT: {
            output.writeStructBegin(typeVal.name);
            const typeMap = typeVal.fields;
            for (const argName in value) {
              const argType = typeMap[argName];
              const argVal = value[argName];
              if (argType) {
                output.writeFieldBegin(argName, argType.type, argType.id);
                this.writeType(argType, argVal, output);
                output.writeFieldEnd();
              }
            }
            output.writeFieldStop();
            output.writeStructEnd();
            break;
          }
          case TType.ENUM:
            // TODO: A
            break;
          case TType.MAP: {
            const keys = Object.keys(value);
            output.writeMapBegin(typeVal.keyType.type, typeVal.valType.type, keys.length);
            for (const key of keys) {
              this.writeType(typeVal.keyType, key, output);
              const val = value[key];
              this.writeType(typeVal.valType, val, output);
            }
            output.writeMapEnd();
            break;
          }
          case TType.LIST:
            output.writeListBegin(typeVal.elementType.type, value.length);
            for (const element of value) {
              this.writeType(typeVal.elementType, element, output);
            }
            output.writeListEnd();
            break;
          case TType.SET:
            output.writeSetBegin(typeVal.elementType.type, value.length);
            for (const element of value) {
              this.writeType(typeVal.elementType, element, output);
            }
            output.writeSetEnd();
            break;
        }
      }

      readType(type: TType, input: TProtocol): any {
        switch (type) {
          case TType.BOOL:
            return input.readBool();
          case TType.BYTE:
            return input.readByte();
          case TType.DOUBLE:
            return input.readDouble();
          case TType.I16:
            return input.readI16();
          case TType.I32:
            return input.readI32();
          case TType.I64:
            return BigInt(input.readI64().toString());
          case TType.STRING:
            return input.readString();
          case TType.STRUCT: {
            const result: any = {};
            input.readStructBegin();
            while (true) {
              const field: IThriftField = input.readFieldBegin();
              const fieldType = field.fieldType;
              const fieldName = field.fieldName || 'success';
              if (fieldType === TType.STOP) {
                break;
              }
              result[fieldName] = this.readType(fieldType, input);
              input.readFieldEnd();
            }
            input.readStructEnd();
            return result;
          }
          case TType.ENUM:
            // TODO: A
            break;
          case TType.MAP: {
            const result: any = {};
            const map = input.readMapBegin();
            for (let i = 0; i < map.size; i++) {
              const key = this.readType(map.keyType, input);
              const value = this.readType(map.valueType, input);
              result[key] = value;
            }
            input.readMapEnd();
            return result;
          }
          case TType.LIST: {
            const result: any[] = [];
            const list = input.readListBegin();
            for (let i = 0; i < list.size; i++) {
              const element = this.readType(list.elementType, input);
              result.push(element);
            }
            input.readListEnd();
            return result;
          }
          case TType.SET: {
            const result: any[] = [];
            const list = input.readSetBegin();
            for (let i = 0; i < list.size; i++) {
              const element = this.readType(list.elementType, input);
              result.push(element);
            }
            input.readSetEnd();
            return result;
          }
        }
      }

      async doRequest(methodName: string, args: any, fields: TypeMap, context?: any) {
        const Transport = this.transport;
        const Protocol = this.protocol;
        const writer: TTransport = new Transport();
        const output: TProtocol = new Protocol(writer);
        const id = this.incrementRequestId();
        output.writeMessageBegin(methodName, MessageType.CALL, id);
        this.writeType(
          {
            name: pascalCase(methodName) + '__Args',
            type: TType.STRUCT,
            fields,
            id,
          },
          args,
          output
        );
        output.writeMessageEnd();
        const data: Buffer = await this.connection.send(writer.flush(), context);
        const reader: TTransport = this.transport.receiver(data);
        const input: TProtocol = new Protocol(reader);
        const { fieldName, messageType }: IThriftMessage = input.readMessageBegin();
        if (fieldName === methodName) {
          if (messageType === MessageType.EXCEPTION) {
            const err: TApplicationException = TApplicationExceptionCodec.decode(input);
            input.readMessageEnd();
            return Promise.reject(err);
          } else {
            const result = this.readType(TType.STRUCT, input);
            input.readMessageEnd();
            if (result.success != null) {
              return result.success;
            } else {
              throw new TApplicationException(
                TApplicationExceptionType.UNKNOWN,
                methodName + ' failed: unknown result'
              );
            }
          }
        } else {
          throw new TApplicationException(
            TApplicationExceptionType.WRONG_METHOD_NAME,
            'Received a response to an unknown RPC function: ' + fieldName
          );
        }
      }
    }
    const thriftHttpClient = createHttpClient(MeshThriftClient, {
      ...this.config,
      requestOptions: {
        headers: operationHeaders,
      },
    });

    function processComments(comments: Comment[]) {
      return comments.map(comment => comment.value).join('\n');
    }

    function getGraphQLFunctionType(
      functionType: FunctionType,
      id = Math.random()
    ): { outputType: GraphQLOutputType; inputType: GraphQLInputType; typeVal: TypeVal } {
      let inputType: GraphQLInputType;
      let outputType: GraphQLOutputType;
      let typeVal: TypeVal;
      switch (functionType.type) {
        case SyntaxType.BinaryKeyword:
        case SyntaxType.StringKeyword:
          inputType = GraphQLString;
          outputType = GraphQLString;
          break;
        case SyntaxType.DoubleKeyword:
          inputType = GraphQLFloat;
          outputType = GraphQLFloat;
          typeVal = typeVal! || { type: TType.DOUBLE };
          break;
        case SyntaxType.VoidKeyword:
          typeVal = typeVal! || { type: TType.VOID };
          inputType = GraphQLVoid;
          outputType = GraphQLVoid;
          break;
        case SyntaxType.BoolKeyword:
          typeVal = typeVal! || { type: TType.BOOL };
          inputType = GraphQLBoolean;
          outputType = GraphQLBoolean;
          break;
        case SyntaxType.I8Keyword:
          inputType = GraphQLInt;
          outputType = GraphQLInt;
          typeVal = typeVal! || { type: TType.I08 };
          break;
        case SyntaxType.I16Keyword:
          inputType = GraphQLInt;
          outputType = GraphQLInt;
          typeVal = typeVal! || { type: TType.I16 };
          break;
        case SyntaxType.I32Keyword:
          inputType = GraphQLInt;
          outputType = GraphQLInt;
          typeVal = typeVal! || { type: TType.I32 };
          break;
        case SyntaxType.ByteKeyword:
          inputType = GraphQLByte;
          outputType = GraphQLByte;
          typeVal = typeVal! || { type: TType.BYTE };
          break;
        case SyntaxType.I64Keyword:
          inputType = GraphQLBigInt;
          outputType = GraphQLBigInt;
          typeVal = typeVal! || { type: TType.I64 };
          break;
        case SyntaxType.ListType: {
          const ofTypeList = getGraphQLFunctionType(functionType.valueType, id);
          inputType = new GraphQLList(ofTypeList.inputType);
          outputType = new GraphQLList(ofTypeList.outputType);
          typeVal = typeVal! || { type: TType.LIST, elementType: ofTypeList.typeVal };
          break;
        }
        case SyntaxType.SetType: {
          const ofSetType = getGraphQLFunctionType(functionType.valueType, id);
          inputType = new GraphQLList(ofSetType.inputType);
          outputType = new GraphQLList(ofSetType.outputType);
          typeVal = typeVal! || { type: TType.SET, elementType: ofSetType.typeVal };
          break;
        }
        case SyntaxType.MapType: {
          inputType = GraphQLJSON;
          outputType = GraphQLJSON;
          const ofTypeKey = getGraphQLFunctionType(functionType.keyType, id);
          const ofTypeValue = getGraphQLFunctionType(functionType.valueType, id);
          typeVal = typeVal! || { type: TType.MAP, keyType: ofTypeKey.typeVal, valType: ofTypeValue.typeVal };
          break;
        }
        case SyntaxType.Identifier: {
          const typeName = functionType.value;
          if (enumTypeMap.has(typeName)) {
            const enumType = enumTypeMap.get(typeName)!;
            inputType = enumType;
            outputType = enumType;
          }
          if (inputTypeMap.has(typeName)) {
            inputType = inputTypeMap.get(typeName)!;
          }
          if (outputTypeMap.has(typeName)) {
            outputType = outputTypeMap.get(typeName)!;
          }
          typeVal = topTypeMap[typeName];
          break;
        }
        default:
          throw new Error(`Unknown function type: ${util.inspect(functionType)}!`);
      }
      return {
        inputType: inputType!,
        outputType: outputType!,
        typeVal: {
          ...typeVal!,
          id,
        },
      };
    }

    const { args: commonArgs, contextVariables } = parseInterpolationStrings(Object.values(operationHeaders || {}));

    const headersFactory = getInterpolatedHeadersFactory(operationHeaders);

    for (const statement of thriftAST.body) {
      switch (statement.type) {
        case SyntaxType.EnumDefinition:
          enumTypeMap.set(
            statement.name.value,
            new GraphQLEnumType({
              name: statement.name.value,
              description: processComments(statement.comments),
              values: statement.members.reduce(
                (prev, curr) => ({
                  ...prev,
                  [curr.name.value]: {
                    description: processComments(curr.comments),
                    value: curr.name.value,
                  },
                }),
                {} as GraphQLEnumValueConfigMap
              ),
            })
          );
          break;
        case SyntaxType.StructDefinition: {
          const structName = statement.name.value;
          const description = processComments(statement.comments);
          const objectFields: GraphQLFieldConfigMap<any, any> = {};
          const inputObjectFields: GraphQLInputFieldConfigMap = {};
          const structTypeVal: StructTypeVal = {
            id: Math.random(),
            name: structName,
            type: TType.STRUCT,
            fields: {},
          };
          topTypeMap[structName] = structTypeVal;
          const structFieldTypeMap = structTypeVal.fields;
          for (const field of statement.fields) {
            const fieldName = field.name.value;
            let fieldOutputType: GraphQLOutputType;
            let fieldInputType: GraphQLInputType;
            const description = processComments(field.comments);
            const processedFieldTypes = getGraphQLFunctionType(field.fieldType, field.fieldID?.value);
            fieldOutputType = processedFieldTypes.outputType;
            fieldInputType = processedFieldTypes.inputType;

            if (field.requiredness === 'required') {
              fieldOutputType = new GraphQLNonNull(fieldOutputType);
              fieldInputType = new GraphQLNonNull(fieldInputType);
            }

            objectFields[fieldName] = {
              type: fieldOutputType,
              description,
            };
            inputObjectFields[fieldName] = {
              type: fieldInputType,
              description,
            };
            structFieldTypeMap[fieldName] = processedFieldTypes.typeVal;
          }
          outputTypeMap.set(
            structName,
            new GraphQLObjectType({
              name: structName,
              description,
              fields: objectFields,
            })
          );
          inputTypeMap.set(
            structName,
            new GraphQLInputObjectType({
              name: structName + 'Input',
              description,
              fields: inputObjectFields,
            })
          );
          break;
        }
        case SyntaxType.ServiceDefinition:
          for (const fnIndex in statement.functions) {
            const fn = statement.functions[fnIndex];
            const fnName = fn.name.value;
            const description = processComments(fn.comments);
            const { outputType: returnType } = getGraphQLFunctionType(fn.returnType, Number(fnIndex) + 1);
            const args: GraphQLFieldConfigArgumentMap = {};
            for (const argName in commonArgs) {
              const typeNameOrType = commonArgs[argName].type;
              args[argName] = {
                type:
                  typeof typeNameOrType === 'string' ? inputTypeMap.get(typeNameOrType) : typeNameOrType || GraphQLID,
              };
            }
            const fieldTypeMap: TypeMap = {};
            for (const field of fn.fields) {
              const fieldName = field.name.value;
              const fieldDescription = processComments(field.comments);
              let { inputType: fieldType, typeVal } = getGraphQLFunctionType(field.fieldType, field.fieldID?.value);
              if (field.requiredness === 'required') {
                fieldType = new GraphQLNonNull(fieldType);
              }
              args[fieldName] = {
                type: fieldType,
                description: fieldDescription,
              };
              fieldTypeMap[fieldName] = typeVal;
            }
            rootFields[fnName] = {
              type: returnType,
              description,
              args,
              resolve: async (root, args, context, info) =>
                thriftHttpClient.doRequest(fnName, args, fieldTypeMap, {
                  headers: headersFactory({ root, args, context, info, env: process.env }),
                }),
            };
            methodNames.push(fnName);
            methodAnnotations[fnName] = { annotations: {}, fieldAnnotations: {} };
            methodParameters[fnName] = fn.fields.length + 1;
          }
          break;
        case SyntaxType.TypedefDefinition: {
          const { inputType, outputType } = getGraphQLFunctionType(statement.definitionType, Math.random());
          const typeName = statement.name.value;
          inputTypeMap.set(typeName, inputType);
          outputTypeMap.set(typeName, outputType);
          break;
        }
      }
    }

    const queryObjectType = new GraphQLObjectType({
      name: 'Query',
      fields: rootFields,
    });

    const schema = new GraphQLSchema({
      query: queryObjectType,
    });

    return {
      schema,
      contextVariables,
    };
  }
Example #16
Source File: helpers.ts    From amplify-codegen with Apache License 2.0 4 votes vote down vote up
describe('Flow typeAnnotationFromGraphQLType', () => {
  test('String', () => {
    expect(typeAnnotationFromGraphQLType(GraphQLString)).toMatchObject(t.nullableTypeAnnotation(t.stringTypeAnnotation()));
  });

  test('Int', () => {
    expect(typeAnnotationFromGraphQLType(GraphQLInt)).toMatchObject(t.nullableTypeAnnotation(t.numberTypeAnnotation()));
  });

  test('Float', () => {
    expect(typeAnnotationFromGraphQLType(GraphQLFloat)).toMatchObject(t.nullableTypeAnnotation(t.numberTypeAnnotation()));
  });

  test('Boolean', () => {
    expect(typeAnnotationFromGraphQLType(GraphQLBoolean)).toMatchObject(t.nullableTypeAnnotation(t.booleanTypeAnnotation()));
  });

  test('ID', () => {
    expect(typeAnnotationFromGraphQLType(GraphQLID)).toMatchObject(t.nullableTypeAnnotation(t.stringTypeAnnotation()));
  });

  test('String!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(GraphQLString))).toMatchObject(t.stringTypeAnnotation());
  });

  test('Int!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(GraphQLInt))).toMatchObject(t.numberTypeAnnotation());
  });

  test('Float!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(GraphQLFloat))).toMatchObject(t.numberTypeAnnotation());
  });

  test('Boolean!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(GraphQLBoolean))).toMatchObject(t.booleanTypeAnnotation());
  });

  test('ID!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(GraphQLID))).toMatchObject(t.stringTypeAnnotation());
  });

  // TODO: Test GenericTypeAnnotation

  test('[String]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(GraphQLString))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.stringTypeAnnotation())))
    );
  });

  test('[Int]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(GraphQLInt))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.numberTypeAnnotation())))
    );
  });

  test('[Float]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(GraphQLFloat))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.numberTypeAnnotation())))
    );
  });

  test('[Boolean]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(GraphQLBoolean))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.booleanTypeAnnotation())))
    );
  });

  test('[ID]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(GraphQLID))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.stringTypeAnnotation())))
    );
  });

  test('[String]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(GraphQLString)))).toMatchObject(
      t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.stringTypeAnnotation()))
    );
  });

  test('[Int]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(GraphQLInt)))).toMatchObject(
      t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.numberTypeAnnotation()))
    );
  });
  test('[Float]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(GraphQLFloat)))).toMatchObject(
      t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.numberTypeAnnotation()))
    );
  });

  test('[Boolean]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(GraphQLBoolean)))).toMatchObject(
      t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.booleanTypeAnnotation()))
    );
  });

  test('[ID]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(GraphQLID)))).toMatchObject(
      t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.stringTypeAnnotation()))
    );
  });

  test('[String!]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(new GraphQLNonNull(GraphQLString)))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.stringTypeAnnotation()))
    );
  });

  test('[Int!]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(new GraphQLNonNull(GraphQLInt)))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.numberTypeAnnotation()))
    );
  });

  test('[Float!]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(new GraphQLNonNull(GraphQLFloat)))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.numberTypeAnnotation()))
    );
  });

  test('[Boolean!]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(new GraphQLNonNull(GraphQLBoolean)))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.booleanTypeAnnotation()))
    );
  });

  test('[ID!]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(new GraphQLNonNull(GraphQLID)))).toMatchObject(
      t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.stringTypeAnnotation()))
    );
  });

  test('[String!]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))))).toMatchObject(
      t.arrayTypeAnnotation(t.stringTypeAnnotation())
    );
  });

  test('[Int!]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLInt))))).toMatchObject(
      t.arrayTypeAnnotation(t.numberTypeAnnotation())
    );
  });

  test('[Float!]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLFloat))))).toMatchObject(
      t.arrayTypeAnnotation(t.numberTypeAnnotation())
    );
  });

  test('[Boolean!]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLBoolean))))).toMatchObject(
      t.arrayTypeAnnotation(t.booleanTypeAnnotation())
    );
  });

  test('[ID!]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLID))))).toMatchObject(
      t.arrayTypeAnnotation(t.stringTypeAnnotation())
    );
  });

  test('[[String]]', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLList(new GraphQLList(GraphQLString)))).toMatchObject(
      t.nullableTypeAnnotation(
        t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.stringTypeAnnotation()))))
      )
    );
  });

  test('[[String]]!', () => {
    expect(typeAnnotationFromGraphQLType(new GraphQLNonNull(new GraphQLList(new GraphQLList(GraphQLString))))).toMatchObject(
      t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.arrayTypeAnnotation(t.nullableTypeAnnotation(t.stringTypeAnnotation()))))
    );
  });

  test('Custom Scalar', () => {
    const OddType = new GraphQLScalarType({
      name: 'Odd',
      serialize(value) {
        return value % 2 === 1 ? value : null;
      },
    });

    expect(typeAnnotationFromGraphQLType(OddType)).toMatchObject(t.nullableTypeAnnotation(t.genericTypeAnnotation(t.identifier('Odd'))));
  });
});
Example #17
Source File: index.ts    From graphql-mesh with MIT License 4 votes vote down vote up
async getMeshSource(): Promise<MeshSource> {
    const {
      addLimitArgument,
      baseUrl,
      customFetch,
      genericPayloadArgName,
      operationHeaders,
      qs,
      selectQueryOrMutationField,
    } = this.config;

    let fetch: WindowOrWorkerGlobalScope['fetch'];
    if (customFetch) {
      fetch = await loadFromModuleExportExpression(customFetch, {
        defaultExportName: 'default',
        cwd: this.baseDir,
        importFn: this.importFn,
      });
    } else {
      fetch = getCachedFetch(this.cache);
    }

    const spec = await this.getCachedSpec(fetch);

    const headersFactory = getInterpolatedHeadersFactory(operationHeaders);
    const queryStringFactoryMap = new Map<string, ResolverDataBasedFactory<string>>();
    for (const queryName in qs || {}) {
      queryStringFactoryMap.set(queryName, getInterpolatedStringFactory(qs[queryName]));
    }
    const searchParamsFactory = (resolverData: ResolverData, searchParams: URLSearchParams) => {
      for (const queryName in qs || {}) {
        searchParams.set(queryName, queryStringFactoryMap.get(queryName)(resolverData));
      }
      return searchParams;
    };

    const { schema } = await createGraphQLSchema(spec, {
      fetch,
      baseUrl,
      operationIdFieldNames: this.config.operationIdFieldNames,
      fillEmptyResponses: true,
      includeHttpDetails: this.config.includeHttpDetails,
      provideErrorExtensions: this.config.provideErrorExtensions,
      genericPayloadArgName: genericPayloadArgName === undefined ? false : genericPayloadArgName,
      selectQueryOrMutationField:
        selectQueryOrMutationField === undefined
          ? {}
          : selectQueryOrMutationField.reduce((acc, curr) => {
              let operationType: GraphQLOperationType;
              switch (curr.type) {
                case 'Query':
                  operationType = GraphQLOperationType.Query;
                  break;
                case 'Mutation':
                  operationType = GraphQLOperationType.Mutation;
                  break;
              }
              return {
                ...acc,
                [curr.title]: {
                  ...acc[curr.title],
                  [curr.path]: {
                    ...((acc[curr.title] && acc[curr.title][curr.path]) || {}),
                    [curr.method]: operationType,
                  },
                },
              };
            }, {} as OasTitlePathMethodObject<GraphQLOperationType>),
      addLimitArgument: addLimitArgument === undefined ? true : addLimitArgument,
      sendOAuthTokenInQuery: true,
      viewer: false,
      equivalentToMessages: true,
      pubsub: this.pubsub,
      logger: this.logger,
      resolverMiddleware: (getResolverParams, originalFactory) => (root, args, context, info: any) => {
        const resolverData: ResolverData = { root, args, context, info, env: process.env };
        const resolverParams = getResolverParams();
        resolverParams.requestOptions = {
          headers: headersFactory(resolverData),
        };
        resolverParams.qs = qs;

        /* FIXME: baseUrl is coming from Fastify Request
        if (context?.baseUrl) {
          resolverParams.baseUrl = context.baseUrl;
        }
        */

        if (baseUrl) {
          resolverParams.baseUrl = stringInterpolator.parse(baseUrl, resolverData);
        }

        if (resolverParams.baseUrl) {
          const urlObj = new URL(resolverParams.baseUrl);
          searchParamsFactory(resolverData, urlObj.searchParams);
        } else {
          this.logger.debug(
            () =>
              `Warning: There is no 'baseUrl' defined for this OpenAPI definition. We recommend you to define one manually!`
          );
        }

        if (context?.fetch) {
          resolverParams.fetch = context.fetch;
        }

        if (context?.qs) {
          resolverParams.qs = context.qs;
        }

        return originalFactory(() => resolverParams, this.logger)(root, args, context, info);
      },
    });

    const { args, contextVariables } = parseInterpolationStrings(Object.values(operationHeaders || {}));

    const rootFields = [
      ...Object.values(schema.getQueryType()?.getFields() || {}),
      ...Object.values(schema.getMutationType()?.getFields() || {}),
      ...Object.values(schema.getSubscriptionType()?.getFields() || {}),
    ];

    await Promise.all(
      rootFields.map(rootField =>
        Promise.all(
          Object.entries(args).map(async ([argName, { type }]) =>
            (rootField?.args as GraphQLArgument[]).push({
              name: argName,
              description: undefined,
              defaultValue: undefined,
              extensions: undefined,
              astNode: undefined,
              deprecationReason: undefined,
              type: (typeof type === 'string' ? (schema.getType(type) as GraphQLInputType) : type) || GraphQLID,
            })
          )
        )
      )
    );

    contextVariables.push('fetch' /*, 'baseUrl' */);

    return {
      schema,
      contextVariables,
    };
  }