graphql#TypeNode TypeScript Examples

The following examples show how to use graphql#TypeNode. 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: generate-query.ts    From graphql-query-generator with MIT License 6 votes vote down vote up
export function getTypeName(type: TypeNode): string {
  if (type.kind === Kind.NAMED_TYPE) {
    return type.name.value
  } else if (type.kind === Kind.LIST_TYPE) {
    return getTypeName(type.type)
  } else if (type.kind === Kind.NON_NULL_TYPE) {
    return getTypeName(type.type)
  } else {
    throw new Error(`Cannot get name of type: ${type}`)
  }
}
Example #2
Source File: generate-query.ts    From graphql-query-generator with MIT License 6 votes vote down vote up
function getVariableDefinition(
  name: string,
  type: TypeNode
): VariableDefinitionNode {
  return {
    kind: Kind.VARIABLE_DEFINITION,
    type: type,
    variable: {
      kind: Kind.VARIABLE,
      name: getName(name)
    }
  }
}
Example #3
Source File: generate-query.ts    From graphql-query-generator with MIT License 6 votes vote down vote up
/**
 * Given a type node, return the named type node
 */
function unwrapType(type: TypeNode): NamedTypeNode {
  if (type.kind === 'ListType' || type.kind === 'NonNullType') {
    return unwrapType(type.type)
  } else {
    return type
  }
}
Example #4
Source File: generate-query.ts    From graphql-query-generator with MIT License 6 votes vote down vote up
/**
 * Given a type node, determine if it is some kind of list node, whether it be
 * non-null list or nested list, or any combination of which
 */
function isListType(type: TypeNode): boolean {
  if (type.kind === 'NamedType') {
    return false
  } else {
    if (type.kind === 'ListType') {
      return true
    } else {
      return isListType(type.type)
    }
  }
}
Example #5
Source File: get-type-info.ts    From amplify-codegen with Apache License 2.0 6 votes vote down vote up
export function getTypeInfo(typeNode: TypeNode, schema: GraphQLSchema): TypeInfo {
  if (typeNode.kind === 'NamedType') {
    return {
      type: typeNode.name.value,
      isNullable: true,
      isList: false,
      baseType: schema.getType(typeNode.name.value),
    };
  } else if (typeNode.kind === 'NonNullType' && typeNode.type.kind === 'ListType') {
    return {
      ...getTypeInfo(typeNode.type.type, schema),
      isList: true,
      isListNullable: false,
    };
  } else if (typeNode.kind === 'NonNullType') {
    return {
      ...getTypeInfo(typeNode.type, schema),
      isNullable: false,
    };
  } else if (typeNode.kind === 'ListType') {
    return {
      ...getTypeInfo(typeNode.type, schema),
      isList: true,
      isListNullable: true,
    };
  }
  return {
    isList: false,
    isNullable: false,
    type: typeNode,
  };
}
Example #6
Source File: generate-query.d.ts    From graphql-query-generator with MIT License 5 votes vote down vote up
export declare function getTypeName(type: TypeNode): string;
Example #7
Source File: provide-variables.d.ts    From graphql-query-generator with MIT License 5 votes vote down vote up
export declare function getDefaultArgValue(schema: GraphQLSchema, config: InternalConfiguration, type: TypeNode): any;
Example #8
Source File: generate-query.ts    From graphql-query-generator with MIT License 5 votes vote down vote up
function isMandatoryType(type: TypeNode): boolean {
  return type.kind === Kind.NON_NULL_TYPE
}
Example #9
Source File: generate-query.ts    From graphql-query-generator with MIT License 5 votes vote down vote up
/**
 * For a given listSize directive, return a default value for it
 */
function getListSizeDirectiveDefaultValue(
  listSizeDirective: DirectiveNode,
  typeNode: TypeNode,
  config: InternalConfiguration,
  schema: GraphQLSchema
) {
  // if requiredOneSlicingArg is false then we do not add anything because none of the slicingArguments are required
  const requireOneSlicingArg = getRequireOneSlicingArgument(listSizeDirective)
  if (
    requireOneSlicingArg &&
    (requireOneSlicingArg.value as BooleanValueNode).value === false
  ) {
    return undefined
  }

  const slicingArgumentsArg = getSlicingArguments(listSizeDirective)
  if (!slicingArgumentsArg) return undefined

  /**
   * Already checked slicingArgumentsArguments is a list
   *
   * Extract paths from slicingArgumentsArguments
   */
  const slicingArgumentsPaths = (slicingArgumentsArg.value as ListValueNode).values.map(
    (value) => {
      if (value.kind === 'StringValue') return value.value
    }
  )

  if (slicingArgumentsPaths.length > 0) {
    const slicingArgumentsTokenizedPath = slicingArgumentsPaths[0].split('.')
    return getListSizeDirectiveDefaultValueHelper(
      slicingArgumentsTokenizedPath,
      typeNode,
      config,
      schema
    )
  }
}
Example #10
Source File: generate-query.ts    From graphql-query-generator with MIT License 5 votes vote down vote up
function getListSizeDirectiveDefaultValueHelper(
  tokenizedPath: string[],
  typeNode: TypeNode,
  config: InternalConfiguration,
  schema: GraphQLSchema
) {
  if (tokenizedPath.length === 0) {
    return undefined
  }

  if (tokenizedPath.length === 1) {
    return getDefaultArgValue(schema, config, typeNode)
  }

  const result = {}

  const namedType = unwrapType(typeNode)
  if (namedType.kind === 'NamedType') {
    const type = schema.getType(namedType.name.value)
    if (type.astNode?.kind === 'InputObjectTypeDefinition') {
      const nextType = type.astNode.fields.find((field) => {
        return field.name.value === tokenizedPath[1]
      })

      const value = getListSizeDirectiveDefaultValueHelper(
        tokenizedPath.slice(1),
        nextType.type,
        config,
        schema
      )

      // Add value depending if it is a list or not
      if (!isListType(typeNode)) {
        result[tokenizedPath[1]] = value
      } else {
        result[tokenizedPath[1]] = [value]
      }
    }
  }

  return result
}
Example #11
Source File: provide-variables.ts    From graphql-query-generator with MIT License 5 votes vote down vote up
export function getDefaultArgValue(
  schema: GraphQLSchema,
  config: InternalConfiguration,
  type: TypeNode
) {
  if (type.kind === 'NonNullType') {
    return getDefaultArgValue(schema, config, type.type)
  } else if (type.kind === 'ListType') {
    return [getDefaultArgValue(schema, config, type.type)]
  } else {
    // Built in GraphQL scalars
    if (type.name.value === 'Int') {
      return 10
    } else if (type.name.value === 'Float') {
      return 10.0
    } else if (type.name.value === 'Boolean') {
      return true
    }

    // Recurse if the type is an input object
    const typeDef = schema.getType(type.name.value)
    if (typeDef && typeDef.astNode?.kind === 'InputObjectTypeDefinition') {
      const fields = typeDef.astNode?.fields
      if (fields) {
        // Identify requiredArguments
        const requiredArguments = Object.entries(fields)
          .map(([_, value]) => value)
          .filter((type) => {
            return considerArgument(type, config)
          })

        // Recurse into required arguments and compose object value
        return requiredArguments.reduce((obj, arg) => {
          obj[arg.name.value] = getDefaultArgValue(schema, config, arg.type)
          return obj
        }, {})
      }
    }
  }

  // Unknown default value
  return 'PLACEHOLDER'
}
Example #12
Source File: gqlTypes.ts    From ra-data-prisma with MIT License 5 votes vote down vote up
listType = (type: TypeNode): ListTypeNode => ({
  kind: Kind.LIST_TYPE,
  type,
})
Example #13
Source File: gqlTypes.ts    From ra-data-prisma with MIT License 5 votes vote down vote up
variableDefinition = (
  variable: VariableNode,
  type: TypeNode,
): VariableDefinitionNode => ({
  kind: Kind.VARIABLE_DEFINITION,
  variable,
  type,
})
Example #14
Source File: relay-connection-types.ts    From graphql-eslint with MIT License 4 votes vote down vote up
rule: GraphQLESLintRule = {
  meta: {
    type: 'problem',
    docs: {
      category: 'Schema',
      description: [
        'Set of rules to follow Relay specification for Connection types.',
        '',
        '- Any type whose name ends in "Connection" is considered by spec to be a `Connection type`',
        '- Connection type must be an Object type',
        '- Connection type must contain a field `edges` that return a list type that wraps an edge type',
        '- Connection type must contain a field `pageInfo` that return a non-null `PageInfo` Object type',
      ].join('\n'),
      url: 'https://github.com/B2o5T/graphql-eslint/blob/master/docs/rules/relay-connection-types.md',
      isDisabledForAllConfig: true,
      examples: [
        {
          title: 'Incorrect',
          code: /* GraphQL */ `
            type UserPayload { # should be an Object type with \`Connection\` suffix
              edges: UserEdge! # should return a list type
              pageInfo: PageInfo # should return a non-null \`PageInfo\` Object type
            }
          `,
        },
        {
          title: 'Correct',
          code: /* GraphQL */ `
            type UserConnection {
              edges: [UserEdge]
              pageInfo: PageInfo!
            }
          `,
        },
      ],
    },
    messages: {
      // Connection types
      [MUST_BE_OBJECT_TYPE]: 'Connection type must be an Object type.',
      [MUST_HAVE_CONNECTION_SUFFIX]: 'Connection type must have `Connection` suffix.',
      [MUST_CONTAIN_FIELD_EDGES]: 'Connection type must contain a field `edges` that return a list type.',
      [MUST_CONTAIN_FIELD_PAGE_INFO]:
        'Connection type must contain a field `pageInfo` that return a non-null `PageInfo` Object type.',
      [EDGES_FIELD_MUST_RETURN_LIST_TYPE]: '`edges` field must return a list type.',
      [PAGE_INFO_FIELD_MUST_RETURN_NON_NULL_TYPE]: '`pageInfo` field must return a non-null `PageInfo` Object type.',
    },
    schema: [],
  },
  create(context) {
    return {
      [notConnectionTypesSelector](node) {
        context.report({ node, messageId: MUST_BE_OBJECT_TYPE });
      },
      ':matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value!=/Connection$/]'(
        node: GraphQLESTreeNode<ObjectTypeDefinitionNode>
      ) {
        if (hasEdgesField(node) && hasPageInfoField(node)) {
          context.report({ node: node.name, messageId: MUST_HAVE_CONNECTION_SUFFIX });
        }
      },
      ':matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/Connection$/]'(
        node: GraphQLESTreeNode<ObjectTypeDefinitionNode>
      ) {
        if (!hasEdgesField(node)) {
          context.report({ node: node.name, messageId: MUST_CONTAIN_FIELD_EDGES });
        }
        if (!hasPageInfoField(node)) {
          context.report({ node: node.name, messageId: MUST_CONTAIN_FIELD_PAGE_INFO });
        }
      },
      ':matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/Connection$/] > FieldDefinition[name.value=edges] > .gqlType'(
        node: GraphQLESTreeNode<TypeNode>
      ) {
        const isListType =
          node.kind === Kind.LIST_TYPE || (node.kind === Kind.NON_NULL_TYPE && node.gqlType.kind === Kind.LIST_TYPE);
        if (!isListType) {
          context.report({ node, messageId: EDGES_FIELD_MUST_RETURN_LIST_TYPE });
        }
      },
      ':matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/Connection$/] > FieldDefinition[name.value=pageInfo] > .gqlType'(
        node: GraphQLESTreeNode<TypeNode>
      ) {
        const isNonNullPageInfoType =
          node.kind === Kind.NON_NULL_TYPE &&
          node.gqlType.kind === Kind.NAMED_TYPE &&
          node.gqlType.name.value === 'PageInfo';
        if (!isNonNullPageInfoType) {
          context.report({ node, messageId: PAGE_INFO_FIELD_MUST_RETURN_NON_NULL_TYPE });
        }
      },
    };
  },
}
Example #15
Source File: relay-edge-types.ts    From graphql-eslint with MIT License 4 votes vote down vote up
rule: GraphQLESLintRule<[EdgeTypesConfig], true> = {
  meta: {
    type: 'problem',
    docs: {
      category: 'Schema',
      description: [
        'Set of rules to follow Relay specification for Edge types.',
        '',
        "- A type that is returned in list form by a connection type's `edges` field is considered by this spec to be an Edge type",
        '- Edge type must be an Object type',
        '- Edge type must contain a field `node` that return either Scalar, Enum, Object, Interface, Union, or a non-null wrapper around one of those types. Notably, this field cannot return a list',
        '- Edge type must contain a field `cursor` that return either String, Scalar, or a non-null wrapper around one of those types',
        '- Edge type name must end in "Edge" _(optional)_',
        "- Edge type's field `node` must implement `Node` interface _(optional)_",
        '- A list type should only wrap an edge type _(optional)_',
      ].join('\n'),
      url: `https://github.com/B2o5T/graphql-eslint/blob/master/docs/rules/${RULE_ID}.md`,
      isDisabledForAllConfig: true,
      requiresSchema: true,
      examples: [
        {
          title: 'Correct',
          code: /* GraphQL */ `
            type UserConnection {
              edges: [UserEdge]
              pageInfo: PageInfo!
            }
          `,
        },
      ],
    },
    messages: {
      [MESSAGE_MUST_BE_OBJECT_TYPE]: 'Edge type must be an Object type.',
      [MESSAGE_MISSING_EDGE_SUFFIX]: 'Edge type must have "Edge" suffix.',
      [MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE]: 'A list type should only wrap an edge type.',
      [MESSAGE_SHOULD_IMPLEMENTS_NODE]: "Edge type's field `node` must implement `Node` interface.",
    },
    schema: {
      type: 'array',
      maxItems: 1,
      items: {
        type: 'object',
        additionalProperties: false,
        minProperties: 1,
        properties: {
          withEdgeSuffix: {
            type: 'boolean',
            default: true,
            description: 'Edge type name must end in "Edge".',
          },
          shouldImplementNode: {
            type: 'boolean',
            default: true,
            description: "Edge type's field `node` must implement `Node` interface.",
          },
          listTypeCanWrapOnlyEdgeType: {
            type: 'boolean',
            default: true,
            description: 'A list type should only wrap an edge type.',
          },
        },
      },
    },
  },
  create(context) {
    const schema = requireGraphQLSchemaFromContext(RULE_ID, context);
    const edgeTypes = getEdgeTypes(schema);
    const options: EdgeTypesConfig = {
      withEdgeSuffix: true,
      shouldImplementNode: true,
      listTypeCanWrapOnlyEdgeType: true,
      ...context.options[0],
    };

    const isNamedOrNonNullNamed = (node: GraphQLESTreeNode<TypeNode>): boolean =>
      node.kind === Kind.NAMED_TYPE || (node.kind === Kind.NON_NULL_TYPE && node.gqlType.kind === Kind.NAMED_TYPE);

    const checkNodeField = (node: GraphQLESTreeNode<ObjectTypeDefinitionNode>): void => {
      const nodeField = node.fields.find(field => field.name.value === 'node');
      const message =
        'return either a Scalar, Enum, Object, Interface, Union, or a non-null wrapper around one of those types.';
      if (!nodeField) {
        context.report({
          node: node.name,
          message: `Edge type must contain a field \`node\` that ${message}`,
        });
      } else if (!isNamedOrNonNullNamed(nodeField.gqlType)) {
        context.report({ node: nodeField.name, message: `Field \`node\` must ${message}` });
      } else if (options.shouldImplementNode) {
        const nodeReturnTypeName = getTypeName(nodeField.gqlType.rawNode());
        const type = schema.getType(nodeReturnTypeName);
        if (!isObjectType(type)) {
          return;
        }
        const implementsNode = type.astNode.interfaces.some(n => n.name.value === 'Node');
        if (!implementsNode) {
          context.report({ node: node.name, messageId: MESSAGE_SHOULD_IMPLEMENTS_NODE });
        }
      }
    };

    const checkCursorField = (node: GraphQLESTreeNode<ObjectTypeDefinitionNode>): void => {
      const cursorField = node.fields.find(field => field.name.value === 'cursor');
      const message = 'return either a String, Scalar, or a non-null wrapper wrapper around one of those types.';
      if (!cursorField) {
        context.report({
          node: node.name,
          message: `Edge type must contain a field \`cursor\` that ${message}`,
        });
        return;
      }
      const typeName = getTypeName(cursorField.rawNode());
      if (
        !isNamedOrNonNullNamed(cursorField.gqlType) ||
        (typeName !== 'String' && !isScalarType(schema.getType(typeName)))
      ) {
        context.report({ node: cursorField.name, message: `Field \`cursor\` must ${message}` });
      }
    };

    const listeners: GraphQLESLintRuleListener<true> = {
      ':matches(ObjectTypeDefinition, ObjectTypeExtension)[name.value=/Connection$/] > FieldDefinition[name.value=edges] > .gqlType Name'(
        node: GraphQLESTreeNode<NameNode>
      ) {
        const type = schema.getType(node.value);
        if (!isObjectType(type)) {
          context.report({ node, messageId: MESSAGE_MUST_BE_OBJECT_TYPE });
        }
      },
      ':matches(ObjectTypeDefinition, ObjectTypeExtension)'(node: GraphQLESTreeNode<ObjectTypeDefinitionNode>) {
        const typeName = node.name.value;
        if (edgeTypes.has(typeName)) {
          checkNodeField(node);
          checkCursorField(node);
          if (options.withEdgeSuffix && !typeName.endsWith('Edge')) {
            context.report({ node: node.name, messageId: MESSAGE_MISSING_EDGE_SUFFIX });
          }
        }
      },
    };

    if (options.listTypeCanWrapOnlyEdgeType) {
      listeners['FieldDefinition > .gqlType'] = (node: GraphQLESTreeNode<TypeNode>) => {
        if (
          node.kind === Kind.LIST_TYPE ||
          (node.kind === Kind.NON_NULL_TYPE && node.gqlType.kind === Kind.LIST_TYPE)
        ) {
          const typeName = getTypeName(node.rawNode());
          if (!edgeTypes.has(typeName)) {
            context.report({ node, messageId: MESSAGE_LIST_TYPE_ONLY_EDGE_TYPE });
          }
        }
      };
    }

    return listeners;
  },
}