Skip to content

Instantly share code, notes, and snippets.

@langpavel
Created December 1, 2020 17:10
Show Gist options
  • Save langpavel/63b7b605277c378bc78743e71f3ea2d9 to your computer and use it in GitHub Desktop.
Save langpavel/63b7b605277c378bc78743e71f3ea2d9 to your computer and use it in GitHub Desktop.
GraphQL AST Type Definitions converted to data structures from `graphql/language/ast.d.ts`
/**
* Types as data from 'graphql/language/ast.d.ts'
*/
import type { ASTNode } from 'graphql/language/ast';
export interface ASTNodeFieldInfo {
readonly optional?: boolean;
readonly isArray?: boolean;
readonly type: string;
readonly possibleTypes?: readonly string[];
}
export interface ASTNodeInfo {
readonly type: keyof typeof ASTNodeTypes;
readonly kind: ASTNode['kind'];
readonly fields: Record<string, ASTNodeFieldInfo>;
}
export const ExecutableDefinitionNodeTypes = [
'OperationDefinitionNode',
'FragmentDefinitionNode',
] as const;
export const TypeDefinitionNodeTypes = [
'ScalarTypeDefinitionNode',
'ObjectTypeDefinitionNode',
'InterfaceTypeDefinitionNode',
'UnionTypeDefinitionNode',
'EnumTypeDefinitionNode',
'InputObjectTypeDefinitionNode',
] as const;
export const TypeExtensionNodeTypes = [
'ScalarTypeExtensionNode',
'ObjectTypeExtensionNode',
'InterfaceTypeExtensionNode',
'UnionTypeExtensionNode',
'EnumTypeExtensionNode',
'InputObjectTypeExtensionNode',
] as const;
export const TypeSystemDefinitionNodeTypes = [
'SchemaDefinitionNode',
...TypeDefinitionNodeTypes,
'DirectiveDefinitionNode',
] as const;
export const TypeSystemExtensionNodeTypes = [
'SchemaExtensionNode',
...TypeExtensionNodeTypes,
] as const;
export const DefinitionNode = [
...ExecutableDefinitionNodeTypes,
...TypeSystemDefinitionNodeTypes,
...TypeSystemExtensionNodeTypes,
] as const;
export const ValueNodeTypes = [
'VariableNode',
'IntValueNode',
'FloatValueNode',
'StringValueNode',
'BooleanValueNode',
'NullValueNode',
'EnumValueNode',
'ListValueNode',
'ObjectValueNode',
] as const;
export const TypeNodeTypes = ['NamedTypeNode', 'ListTypeNode', 'NonNullTypeNode'] as const;
export const SelectionNodeTypes = ['FieldNode', 'FragmentSpreadNode', 'InlineFragmentNode'];
export const NameNode = {
type: 'NameNode',
kind: 'Name',
fields: {},
} as const;
export const DocumentNode = {
type: 'DocumentNode',
kind: 'Document',
fields: {
definitions: {
isArray: true,
type: 'DefinitionNode',
possibleTypes: DefinitionNode,
},
},
} as const;
export const OperationDefinitionNode = {
type: 'OperationDefinitionNode',
kind: 'OperationDefinition',
fields: {
operation: { type: 'OperationTypeNode' },
name: { optional: true, type: 'NameNode' },
variableDefinitions: { optional: true, isArray: true, type: 'VariableDefinitionNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
selectionSet: { type: 'SelectionSetNode' },
},
} as const;
export type OperationTypeNode = 'query' | 'mutation' | 'subscription';
export const VariableDefinitionNode = {
type: 'VariableDefinitionNode',
kind: 'VariableDefinition',
fields: {
variable: { type: 'VariableNode' },
type: { type: 'TypeNode', possibleTypes: TypeNodeTypes },
defaultValue: { optional: true, type: 'ValueNode', possibleTypes: ValueNodeTypes },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
},
} as const;
export const VariableNode = {
type: 'VariableNode',
kind: 'Variable',
fields: {
name: { type: 'NameNode' },
},
} as const;
export const SelectionSetNode = {
type: 'SelectionSetNode',
kind: 'SelectionSet',
fields: {
selections: { isArray: true, type: 'SelectionNode', possibleTypes: SelectionNodeTypes },
},
} as const;
export const FieldNode = {
type: 'FieldNode',
kind: 'Field',
fields: {
alias: { optional: true, type: 'NameNode' },
name: { type: 'NameNode' },
arguments: { optional: true, isArray: true, type: 'ArgumentNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
selectionSet: { optional: true, type: 'SelectionSetNode' },
},
} as const;
export const ArgumentNode = {
type: 'ArgumentNode',
kind: 'Argument',
fields: {
name: { type: 'NameNode' },
value: { type: 'ValueNode', possibleTypes: ValueNodeTypes },
},
} as const;
// Fragments
export const FragmentSpreadNode = {
type: 'FragmentSpreadNode',
kind: 'FragmentSpread',
fields: {
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
},
} as const;
export const InlineFragmentNode = {
type: 'InlineFragmentNode',
kind: 'InlineFragment',
fields: {
typeCondition: { optional: true, type: 'NamedTypeNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
selectionSet: { type: 'SelectionSetNode' },
},
} as const;
export const FragmentDefinitionNode = {
type: 'FragmentDefinitionNode',
kind: 'FragmentDefinition',
fields: {
name: { type: 'NameNode' },
// Note: fragment variable definitions are experimental and may be changed
// or removed in the future.
variableDefinitions: { optional: true, isArray: true, type: 'VariableDefinitionNode' },
typeCondition: { type: 'NamedTypeNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
selectionSet: { type: 'SelectionSetNode' },
},
} as const;
export const IntValueNode = {
type: 'IntValueNode',
kind: 'IntValue',
fields: {
value: { type: 'string' },
},
} as const;
export const FloatValueNode = {
type: 'FloatValueNode',
kind: 'FloatValue',
fields: {
value: { type: 'string' },
},
} as const;
export const StringValueNode = {
type: 'StringValueNode',
kind: 'StringValue',
fields: {
value: { type: 'string' },
block: { optional: true, type: 'boolean' },
},
} as const;
export const BooleanValueNode = {
type: 'BooleanValueNode',
kind: 'BooleanValue',
fields: {
value: { type: 'boolean' },
},
} as const;
export const NullValueNode = {
type: 'NullValueNode',
kind: 'NullValue',
fields: {},
} as const;
export const EnumValueNode = {
type: 'EnumValueNode',
kind: 'EnumValue',
fields: {
value: { type: 'string' },
},
} as const;
export const ListValueNode = {
type: 'ListValueNode',
kind: 'ListValue',
fields: {
values: { isArray: true, type: 'ValueNode', possibleTypes: ValueNodeTypes },
},
} as const;
export const ObjectValueNode = {
type: 'ObjectValueNode',
kind: 'ObjectValue',
fields: {
fields: { isArray: true, type: 'ObjectFieldNode' },
},
} as const;
export const ObjectFieldNode = {
type: 'ObjectFieldNode',
kind: 'ObjectField',
fields: {
name: { type: 'NameNode' },
value: { type: 'ValueNode', possibleTypes: ValueNodeTypes },
},
} as const;
// Directives
export const DirectiveNode = {
type: 'DirectiveNode',
kind: 'Directive',
fields: {
name: { type: 'NameNode' },
arguments: { optional: true, isArray: true, type: 'ArgumentNode' },
},
} as const;
// Type Reference
export const NamedTypeNode = {
type: 'NamedTypeNode',
kind: 'NamedType',
fields: {
name: { type: 'NameNode' },
},
} as const;
export const ListTypeNode = {
type: 'ListTypeNode',
kind: 'ListType',
fields: {
type: { type: 'TypeNode', possibleTypes: TypeNodeTypes },
},
} as const;
export const NonNullTypeNode = {
type: 'NonNullTypeNode',
kind: 'NonNullType',
fields: {
type: { type: 'NamedOrListTypeNode', possibleTypes: ['NamedTypeNode', 'ListTypeNode'] },
},
} as const;
// Type System Definition
export const SchemaDefinitionNode = {
type: 'SchemaDefinitionNode',
kind: 'SchemaDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
operationTypes: { isArray: true, type: 'OperationTypeDefinitionNode' },
},
} as const;
export const OperationTypeDefinitionNode = {
type: 'OperationTypeDefinitionNode',
kind: 'OperationTypeDefinition',
fields: {
operation: { type: 'OperationTypeNode' },
type: { type: 'NamedTypeNode' },
},
} as const;
// Type Definition
export const ScalarTypeDefinitionNode = {
type: 'ScalarTypeDefinitionNode',
kind: 'ScalarTypeDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
},
} as const;
export const ObjectTypeDefinitionNode = {
type: 'ObjectTypeDefinitionNode',
kind: 'ObjectTypeDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
interfaces: { optional: true, isArray: true, type: 'NamedTypeNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
fields: { optional: true, isArray: true, type: 'FieldDefinitionNode' },
},
} as const;
export const FieldDefinitionNode = {
type: 'FieldDefinitionNode',
kind: 'FieldDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
arguments: { optional: true, isArray: true, type: 'InputValueDefinitionNode' },
type: { type: 'TypeNode', possibleTypes: TypeNodeTypes },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
},
} as const;
export const InputValueDefinitionNode = {
type: 'InputValueDefinitionNode',
kind: 'InputValueDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
type: { type: 'TypeNode', possibleTypes: TypeNodeTypes },
defaultValue: { optional: true, type: 'ValueNode', possibleTypes: ValueNodeTypes },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
},
} as const;
export const InterfaceTypeDefinitionNode = {
type: 'InterfaceTypeDefinitionNode',
kind: 'InterfaceTypeDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
interfaces: { optional: true, isArray: true, type: 'NamedTypeNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
fields: { optional: true, isArray: true, type: 'FieldDefinitionNode' },
},
} as const;
export const UnionTypeDefinitionNode = {
type: 'UnionTypeDefinitionNode',
kind: 'UnionTypeDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
types: { optional: true, isArray: true, type: 'NamedTypeNode' },
},
} as const;
export const EnumTypeDefinitionNode = {
type: 'EnumTypeDefinitionNode',
kind: 'EnumTypeDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
values: { optional: true, isArray: true, type: 'EnumValueDefinitionNode' },
},
} as const;
export const EnumValueDefinitionNode = {
type: 'EnumValueDefinitionNode',
kind: 'EnumValueDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
},
} as const;
export const InputObjectTypeDefinitionNode = {
type: 'InputObjectTypeDefinitionNode',
kind: 'InputObjectTypeDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
fields: { optional: true, isArray: true, type: 'InputValueDefinitionNode' },
},
} as const;
// Directive Definitions
export const DirectiveDefinitionNode = {
type: 'DirectiveDefinitionNode',
kind: 'DirectiveDefinition',
fields: {
description: { optional: true, type: 'StringValueNode' },
name: { type: 'NameNode' },
arguments: { optional: true, isArray: true, type: 'InputValueDefinitionNode' },
repeatable: { type: 'boolean' },
locations: { isArray: true, type: 'NameNode' },
},
} as const;
// Type System Extensions
export const SchemaExtensionNode = {
type: 'SchemaExtensionNode',
kind: 'SchemaExtension',
fields: {
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
operationTypes: { optional: true, isArray: true, type: 'OperationTypeDefinitionNode' },
},
} as const;
// Type Extensions
export const ScalarTypeExtensionNode = {
type: 'ScalarTypeExtensionNode',
kind: 'ScalarTypeExtension',
fields: {
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
},
} as const;
export const ObjectTypeExtensionNode = {
type: 'ObjectTypeExtensionNode',
kind: 'ObjectTypeExtension',
fields: {
name: { type: 'NameNode' },
interfaces: { optional: true, isArray: true, type: 'NamedTypeNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
fields: { optional: true, isArray: true, type: 'FieldDefinitionNode' },
},
} as const;
export const InterfaceTypeExtensionNode = {
type: 'InterfaceTypeExtensionNode',
kind: 'InterfaceTypeExtension',
fields: {
name: { type: 'NameNode' },
interfaces: { optional: true, isArray: true, type: 'NamedTypeNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
fields: { optional: true, isArray: true, type: 'FieldDefinitionNode' },
},
} as const;
export const UnionTypeExtensionNode = {
type: 'UnionTypeExtensionNode',
kind: 'UnionTypeExtension',
fields: {
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
types: { optional: true, isArray: true, type: 'NamedTypeNode' },
},
} as const;
export const EnumTypeExtensionNode = {
type: 'EnumTypeExtensionNode',
kind: 'EnumTypeExtension',
fields: {
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
values: { optional: true, isArray: true, type: 'EnumValueDefinitionNode' },
},
} as const;
export const InputObjectTypeExtensionNode = {
type: 'InputObjectTypeExtensionNode',
kind: 'InputObjectTypeExtension',
fields: {
name: { type: 'NameNode' },
directives: { optional: true, isArray: true, type: 'DirectiveNode' },
fields: { optional: true, isArray: true, type: 'InputValueDefinitionNode' },
},
} as const;
export const ASTNodeTypes: Record<string, ASTNodeInfo> = {
NameNode,
DocumentNode,
OperationDefinitionNode,
VariableDefinitionNode,
VariableNode,
SelectionSetNode,
FieldNode,
ArgumentNode,
FragmentSpreadNode,
InlineFragmentNode,
FragmentDefinitionNode,
IntValueNode,
FloatValueNode,
StringValueNode,
BooleanValueNode,
NullValueNode,
EnumValueNode,
ListValueNode,
ObjectValueNode,
ObjectFieldNode,
DirectiveNode,
NamedTypeNode,
ListTypeNode,
NonNullTypeNode,
SchemaDefinitionNode,
OperationTypeDefinitionNode,
ScalarTypeDefinitionNode,
ObjectTypeDefinitionNode,
FieldDefinitionNode,
InputValueDefinitionNode,
InterfaceTypeDefinitionNode,
UnionTypeDefinitionNode,
EnumTypeDefinitionNode,
EnumValueDefinitionNode,
InputObjectTypeDefinitionNode,
DirectiveDefinitionNode,
SchemaExtensionNode,
ScalarTypeExtensionNode,
ObjectTypeExtensionNode,
InterfaceTypeExtensionNode,
UnionTypeExtensionNode,
EnumTypeExtensionNode,
InputObjectTypeExtensionNode,
};
export const ASTKindToNode: Record<ASTNode['kind'], ASTNodeInfo> = {
[NameNode.kind]: NameNode,
[DocumentNode.kind]: DocumentNode,
[OperationDefinitionNode.kind]: OperationDefinitionNode,
[VariableDefinitionNode.kind]: VariableDefinitionNode,
[VariableNode.kind]: VariableNode,
[SelectionSetNode.kind]: SelectionSetNode,
[FieldNode.kind]: FieldNode,
[ArgumentNode.kind]: ArgumentNode,
[FragmentSpreadNode.kind]: FragmentSpreadNode,
[InlineFragmentNode.kind]: InlineFragmentNode,
[FragmentDefinitionNode.kind]: FragmentDefinitionNode,
[IntValueNode.kind]: IntValueNode,
[FloatValueNode.kind]: FloatValueNode,
[StringValueNode.kind]: StringValueNode,
[BooleanValueNode.kind]: BooleanValueNode,
[NullValueNode.kind]: NullValueNode,
[EnumValueNode.kind]: EnumValueNode,
[ListValueNode.kind]: ListValueNode,
[ObjectValueNode.kind]: ObjectValueNode,
[ObjectFieldNode.kind]: ObjectFieldNode,
[DirectiveNode.kind]: DirectiveNode,
[NamedTypeNode.kind]: NamedTypeNode,
[ListTypeNode.kind]: ListTypeNode,
[NonNullTypeNode.kind]: NonNullTypeNode,
[SchemaDefinitionNode.kind]: SchemaDefinitionNode,
[OperationTypeDefinitionNode.kind]: OperationTypeDefinitionNode,
[ScalarTypeDefinitionNode.kind]: ScalarTypeDefinitionNode,
[ObjectTypeDefinitionNode.kind]: ObjectTypeDefinitionNode,
[FieldDefinitionNode.kind]: FieldDefinitionNode,
[InputValueDefinitionNode.kind]: InputValueDefinitionNode,
[InterfaceTypeDefinitionNode.kind]: InterfaceTypeDefinitionNode,
[UnionTypeDefinitionNode.kind]: UnionTypeDefinitionNode,
[EnumTypeDefinitionNode.kind]: EnumTypeDefinitionNode,
[EnumValueDefinitionNode.kind]: EnumValueDefinitionNode,
[InputObjectTypeDefinitionNode.kind]: InputObjectTypeDefinitionNode,
[DirectiveDefinitionNode.kind]: DirectiveDefinitionNode,
[SchemaExtensionNode.kind]: SchemaExtensionNode,
[ScalarTypeExtensionNode.kind]: ScalarTypeExtensionNode,
[ObjectTypeExtensionNode.kind]: ObjectTypeExtensionNode,
[InterfaceTypeExtensionNode.kind]: InterfaceTypeExtensionNode,
[UnionTypeExtensionNode.kind]: UnionTypeExtensionNode,
[EnumTypeExtensionNode.kind]: EnumTypeExtensionNode,
[InputObjectTypeExtensionNode.kind]: InputObjectTypeExtensionNode,
} as const;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment