{"version":3,"file":"ValidationContext.js","sourceRoot":"","sources":["../../src/validation/ValidationContext.ts"],"names":[],"mappings":"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","sourcesContent":["/** @category Validation Context */\n\nimport type { Maybe } from '../jsutils/Maybe.ts';\nimport type { ObjMap } from '../jsutils/ObjMap.ts';\n\nimport type { GraphQLError } from '../error/GraphQLError.ts';\n\nimport type {\n  DocumentNode,\n  FragmentDefinitionNode,\n  FragmentSpreadNode,\n  OperationDefinitionNode,\n  SelectionSetNode,\n  VariableDefinitionNode,\n  VariableNode,\n} from '../language/ast.ts';\nimport { Kind } from '../language/kinds.ts';\nimport type { ASTVisitor } from '../language/visitor.ts';\nimport { visit } from '../language/visitor.ts';\n\nimport type {\n  GraphQLArgument,\n  GraphQLCompositeType,\n  GraphQLEnumValue,\n  GraphQLField,\n  GraphQLInputType,\n  GraphQLOutputType,\n} from '../type/definition.ts';\nimport type { GraphQLDirective } from '../type/directives.ts';\nimport type { GraphQLSchema } from '../type/schema.ts';\n\nimport type { FragmentSignature } from '../utilities/TypeInfo.ts';\nimport { TypeInfo, visitWithTypeInfo } from '../utilities/TypeInfo.ts';\n\ntype NodeWithSelectionSet = OperationDefinitionNode | FragmentDefinitionNode;\ninterface VariableUsage {\n  readonly node: VariableNode;\n  readonly type: Maybe<GraphQLInputType>;\n  readonly parentType: Maybe<GraphQLInputType>;\n  readonly defaultValue: unknown;\n  readonly fragmentVariableDefinition: Maybe<VariableDefinitionNode>;\n}\n\n/**\n * An instance of this class is passed as the \"this\" context to all validators,\n * allowing access to commonly useful contextual information from within a\n * validation rule.\n *\n * @internal\n */\nexport class ASTValidationContext {\n  private _ast: DocumentNode;\n  private _onError: (error: GraphQLError) => void;\n  private _fragments: ObjMap<FragmentDefinitionNode> | undefined;\n  private _fragmentSpreads: Map<SelectionSetNode, Array<FragmentSpreadNode>>;\n  private _recursivelyReferencedFragments: Map<\n    OperationDefinitionNode,\n    Array<FragmentDefinitionNode>\n  >;\n\n  constructor(ast: DocumentNode, onError: (error: GraphQLError) => void) {\n    this._ast = ast;\n    this._fragments = undefined;\n    this._fragmentSpreads = new Map();\n    this._recursivelyReferencedFragments = new Map();\n    this._onError = onError;\n  }\n\n  get [Symbol.toStringTag](): string {\n    return 'ASTValidationContext';\n  }\n\n  reportError(error: GraphQLError): void {\n    this._onError(error);\n  }\n\n  getDocument(): DocumentNode {\n    return this._ast;\n  }\n\n  getFragment(name: string): Maybe<FragmentDefinitionNode> {\n    let fragments: ObjMap<FragmentDefinitionNode>;\n    if (this._fragments) {\n      fragments = this._fragments;\n    } else {\n      fragments = Object.create(null);\n      for (const defNode of this.getDocument().definitions) {\n        if (defNode.kind === Kind.FRAGMENT_DEFINITION) {\n          fragments[defNode.name.value] = defNode;\n        }\n      }\n      this._fragments = fragments;\n    }\n    return fragments[name];\n  }\n\n  getFragmentSpreads(\n    node: SelectionSetNode,\n  ): ReadonlyArray<FragmentSpreadNode> {\n    let spreads = this._fragmentSpreads.get(node);\n    if (!spreads) {\n      spreads = [];\n      const setsToVisit: Array<SelectionSetNode> = [node];\n      let set: SelectionSetNode | undefined;\n      while ((set = setsToVisit.pop())) {\n        for (const selection of set.selections) {\n          if (selection.kind === Kind.FRAGMENT_SPREAD) {\n            spreads.push(selection);\n          } else if (selection.selectionSet) {\n            setsToVisit.push(selection.selectionSet);\n          }\n        }\n      }\n      this._fragmentSpreads.set(node, spreads);\n    }\n    return spreads;\n  }\n\n  getRecursivelyReferencedFragments(\n    operation: OperationDefinitionNode,\n  ): ReadonlyArray<FragmentDefinitionNode> {\n    let fragments = this._recursivelyReferencedFragments.get(operation);\n    if (!fragments) {\n      fragments = [];\n      const collectedNames = new Set<string>();\n      const nodesToVisit: Array<SelectionSetNode> = [operation.selectionSet];\n      let node: SelectionSetNode | undefined;\n      while ((node = nodesToVisit.pop())) {\n        for (const spread of this.getFragmentSpreads(node)) {\n          const fragName = spread.name.value;\n          if (!collectedNames.has(fragName)) {\n            collectedNames.add(fragName);\n            const fragment = this.getFragment(fragName);\n            if (fragment) {\n              fragments.push(fragment);\n              nodesToVisit.push(fragment.selectionSet);\n            }\n          }\n        }\n      }\n      this._recursivelyReferencedFragments.set(operation, fragments);\n    }\n    return fragments;\n  }\n}\n\n/** @internal */\nexport type ASTValidationRule = (context: ASTValidationContext) => ASTVisitor;\n\n/** @internal */\nexport class SDLValidationContext extends ASTValidationContext {\n  private _schema: Maybe<GraphQLSchema>;\n\n  constructor(\n    ast: DocumentNode,\n    schema: Maybe<GraphQLSchema>,\n    onError: (error: GraphQLError) => void,\n  ) {\n    super(ast, onError);\n    this._schema = schema;\n  }\n\n  get hideSuggestions(): boolean {\n    return false;\n  }\n\n  override get [Symbol.toStringTag](): string {\n    return 'SDLValidationContext';\n  }\n\n  getSchema(): Maybe<GraphQLSchema> {\n    return this._schema;\n  }\n}\n\n/** @internal */\nexport type SDLValidationRule = (context: SDLValidationContext) => ASTVisitor;\n\n/** Validation context passed to query validation rules. */\nexport class ValidationContext extends ASTValidationContext {\n  private _schema: GraphQLSchema;\n  private _typeInfo: TypeInfo;\n  private _variableUsages: Map<\n    NodeWithSelectionSet,\n    ReadonlyArray<VariableUsage>\n  >;\n\n  private _recursiveVariableUsages: Map<\n    OperationDefinitionNode,\n    ReadonlyArray<VariableUsage>\n  >;\n  private _hideSuggestions: boolean;\n\n  /**\n   * Creates a ValidationContext instance.\n   * @param schema - Schema used to validate the document.\n   * @param ast - Document AST being validated.\n   * @param typeInfo - TypeInfo instance used to track traversal state.\n   * @param onError - Callback invoked for each validation error.\n   * @param hideSuggestions - Whether suggestion text should be omitted from errors.\n   * @example\n   * ```ts\n   * import { parse } from 'graphql/language';\n   * import { GraphQLError } from 'graphql/error';\n   * import { buildSchema, TypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     greeting: String\n   *   }\n   * `);\n   * const document = parse('{ greeting }');\n   * const errors = [];\n   * const context = new ValidationContext(\n   *   schema,\n   *   document,\n   *   new TypeInfo(schema),\n   *   (error) => errors.push(error),\n   * );\n   *\n   * context.reportError(new GraphQLError('Example validation error.'));\n   *\n   * context.getSchema(); // => schema\n   * errors[0].message; // => 'Example validation error.'\n   * ```\n   */\n  constructor(\n    schema: GraphQLSchema,\n    ast: DocumentNode,\n    typeInfo: TypeInfo,\n    onError: (error: GraphQLError) => void,\n    hideSuggestions?: Maybe<boolean>,\n  ) {\n    super(ast, onError);\n    this._schema = schema;\n    this._typeInfo = typeInfo;\n    this._variableUsages = new Map();\n    this._recursiveVariableUsages = new Map();\n    this._hideSuggestions = hideSuggestions ?? false;\n  }\n\n  /**\n   * Returns the value used by `Object.prototype.toString`.\n   * @returns The built-in string tag for this object.\n   */\n  override get [Symbol.toStringTag](): string {\n    return 'ValidationContext';\n  }\n\n  /**\n   * Returns whether validation error suggestions are hidden.\n   * @returns True when suggestion text should be omitted from errors.\n   */\n  get hideSuggestions(): boolean {\n    return this._hideSuggestions;\n  }\n\n  /**\n   * Returns the schema being used by this validation context.\n   * @returns The schema being validated against.\n   * @example\n   * ```ts\n   * import { parse } from 'graphql/language';\n   * import { buildSchema, TypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     greeting: String\n   *   }\n   * `);\n   * const context = new ValidationContext(\n   *   schema,\n   *   parse('{ greeting }'),\n   *   new TypeInfo(schema),\n   *   () => {},\n   * );\n   *\n   * context.getSchema().getQueryType()?.name; // => 'Query'\n   * ```\n   */\n  getSchema(): GraphQLSchema {\n    return this._schema;\n  }\n\n  /**\n   * Returns variable usages found directly within this node.\n   * @param node - The AST node to inspect or visit.\n   * @returns Variable usages found directly within this node.\n   * @example\n   * ```ts\n   * import { parse } from 'graphql/language';\n   * import { buildSchema, TypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     greeting(name: String): String\n   *   }\n   * `);\n   * const document = parse('query ($name: String) { greeting(name: $name) }');\n   * const operation = document.definitions[0];\n   * const context = new ValidationContext(\n   *   schema,\n   *   document,\n   *   new TypeInfo(schema),\n   *   () => {},\n   * );\n   *\n   * const usages = context.getVariableUsages(operation);\n   *\n   * usages[0].node.name.value; // => 'name'\n   * String(usages[0].type); // => 'String'\n   * ```\n   */\n  getVariableUsages(node: NodeWithSelectionSet): ReadonlyArray<VariableUsage> {\n    let usages = this._variableUsages.get(node);\n    if (!usages) {\n      const newUsages: Array<VariableUsage> = [];\n      const typeInfo = new TypeInfo(\n        this._schema,\n        undefined,\n        this._typeInfo.getFragmentSignatureByName(),\n      );\n      const fragmentDefinition =\n        node.kind === Kind.FRAGMENT_DEFINITION ? node : undefined;\n      visit(\n        node,\n        visitWithTypeInfo(typeInfo, {\n          VariableDefinition: () => false,\n          Variable(variable) {\n            let fragmentVariableDefinition;\n            if (fragmentDefinition) {\n              const fragmentSignature = typeInfo.getFragmentSignatureByName()(\n                fragmentDefinition.name.value,\n              );\n\n              fragmentVariableDefinition =\n                fragmentSignature?.variableDefinitions.get(variable.name.value);\n              newUsages.push({\n                node: variable,\n                type: typeInfo.getInputType(),\n                parentType: typeInfo.getParentInputType(),\n                defaultValue: undefined, // fragment variables have a variable default but no location default, which is what this default value represents\n                fragmentVariableDefinition,\n              });\n            } else {\n              newUsages.push({\n                node: variable,\n                type: typeInfo.getInputType(),\n                parentType: typeInfo.getParentInputType(),\n                defaultValue: typeInfo.getDefaultValue(),\n                fragmentVariableDefinition: undefined,\n              });\n            }\n          },\n        }),\n      );\n      usages = newUsages;\n      this._variableUsages.set(node, usages);\n    }\n    return usages;\n  }\n\n  /**\n   * Returns variable usages for an operation, including variables used by referenced fragments.\n   * @param operation - Operation definition to inspect.\n   * @returns Variable usages reachable from the operation.\n   * @example\n   * ```ts\n   * import { parse } from 'graphql/language';\n   * import { buildSchema, TypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     viewer: User\n   *   }\n   *\n   *   type User {\n   *     name(prefix: String): String\n   *   }\n   * `);\n   * const document = parse(`\n   *   query ($prefix: String) {\n   *     viewer {\n   *       ...UserName\n   *     }\n   *   }\n   *\n   *   fragment UserName on User {\n   *     name(prefix: $prefix)\n   *   }\n   * `);\n   * const operation = document.definitions[0];\n   * const context = new ValidationContext(\n   *   schema,\n   *   document,\n   *   new TypeInfo(schema),\n   *   () => {},\n   * );\n   *\n   * const usages = context.getRecursiveVariableUsages(operation);\n   *\n   * usages.map((usage) => usage.node.name.value); // => ['prefix']\n   * ```\n   */\n  getRecursiveVariableUsages(\n    operation: OperationDefinitionNode,\n  ): ReadonlyArray<VariableUsage> {\n    let usages = this._recursiveVariableUsages.get(operation);\n    if (!usages) {\n      usages = this.getVariableUsages(operation);\n      for (const frag of this.getRecursivelyReferencedFragments(operation)) {\n        usages = usages.concat(this.getVariableUsages(frag));\n      }\n      this._recursiveVariableUsages.set(operation, usages);\n    }\n    return usages;\n  }\n\n  /**\n   * Returns the current output type at this point in traversal.\n   * @returns The current output type, if known.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     greeting: String\n   *   }\n   * `);\n   * const document = parse('{ greeting }');\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let typeName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     Field: () => {\n   *       typeName = String(context.getType());\n   *     },\n   *   }),\n   * );\n   *\n   * typeName; // => 'String'\n   * ```\n   */\n  getType(): Maybe<GraphQLOutputType> {\n    return this._typeInfo.getType();\n  }\n\n  /**\n   * Returns the current parent composite type.\n   * @returns The current parent composite type, if known.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     greeting: String\n   *   }\n   * `);\n   * const document = parse('{ greeting }');\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let parentTypeName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     Field: () => {\n   *       parentTypeName = context.getParentType()?.name;\n   *     },\n   *   }),\n   * );\n   *\n   * parentTypeName; // => 'Query'\n   * ```\n   */\n  getParentType(): Maybe<GraphQLCompositeType> {\n    return this._typeInfo.getParentType();\n  }\n\n  /**\n   * Returns the current input type at this point in traversal.\n   * @returns The current input type, if known.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     reviews(limit: Int): [String]\n   *   }\n   * `);\n   * const document = parse('{ reviews(limit: 5) }');\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let inputTypeName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     Argument: () => {\n   *       inputTypeName = String(context.getInputType());\n   *     },\n   *   }),\n   * );\n   *\n   * inputTypeName; // => 'Int'\n   * ```\n   */\n  getInputType(): Maybe<GraphQLInputType> {\n    return this._typeInfo.getInputType();\n  }\n\n  // Note: continues to expose the closest enclosing valid input type if\n  // traversal descends into syntax with no corresponding GraphQL input type.\n  /**\n   * Returns the parent input type for the current input position.\n   * @returns The parent input type, if known.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   input ReviewFilter {\n   *     stars: Int\n   *   }\n   *\n   *   type Query {\n   *     reviews(filter: ReviewFilter): [String]\n   *   }\n   * `);\n   * const document = parse('{ reviews(filter: { stars: 5 }) }');\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let parentInputTypeName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     ObjectField: () => {\n   *       parentInputTypeName = String(context.getParentInputType());\n   *     },\n   *   }),\n   * );\n   *\n   * parentInputTypeName; // => 'ReviewFilter'\n   * ```\n   */\n  getParentInputType(): Maybe<GraphQLInputType> {\n    return this._typeInfo.getParentInputType();\n  }\n\n  /**\n   * Returns the current field definition.\n   * @returns The current field definition, if known.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     greeting: String\n   *   }\n   * `);\n   * const document = parse('{ greeting }');\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let fieldName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     Field: () => {\n   *       fieldName = context.getFieldDef()?.name;\n   *     },\n   *   }),\n   * );\n   *\n   * fieldName; // => 'greeting'\n   * ```\n   */\n  getFieldDef(): Maybe<GraphQLField<unknown, unknown>> {\n    return this._typeInfo.getFieldDef();\n  }\n\n  /**\n   * Returns the current directive definition.\n   * @returns The current directive definition, if known.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     greeting: String\n   *   }\n   * `);\n   * const document = parse('{ greeting @include(if: true) }');\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let directiveName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     Directive: () => {\n   *       directiveName = context.getDirective()?.name;\n   *     },\n   *   }),\n   * );\n   *\n   * directiveName; // => 'include'\n   * ```\n   */\n  getDirective(): Maybe<GraphQLDirective> {\n    return this._typeInfo.getDirective();\n  }\n\n  /**\n   * Returns the current argument definition.\n   * @returns The current argument definition, if known.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     reviews(limit: Int): [String]\n   *   }\n   * `);\n   * const document = parse('{ reviews(limit: 5) }');\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let argumentName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     Argument: () => {\n   *       argumentName = context.getArgument()?.name;\n   *     },\n   *   }),\n   * );\n   *\n   * argumentName; // => 'limit'\n   * ```\n   */\n  getArgument(): Maybe<GraphQLArgument> {\n    return this._typeInfo.getArgument();\n  }\n\n  /**\n   * Returns the fragment signature at the current traversal position.\n   * @returns The current fragment signature, if one is active.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     greeting: String\n   *   }\n   * `);\n   * const document = parse(\n   *   `\n   *     {\n   *       ...GreetingFields\n   *     }\n   *\n   *     fragment GreetingFields on Query {\n   *       greeting\n   *     }\n   *   `,\n   *   { experimentalFragmentArguments: true },\n   * );\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let fragmentName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     FragmentSpread: () => {\n   *       fragmentName = context.getFragmentSignature()?.definition.name.value;\n   *     },\n   *   }),\n   * );\n   *\n   * fragmentName; // => 'GreetingFields'\n   * ```\n   */\n  getFragmentSignature(): Maybe<FragmentSignature> {\n    return this._typeInfo.getFragmentSignature();\n  }\n\n  /**\n   * Returns the function used to look up fragment signatures by name.\n   * @returns A function that maps fragment names to fragment signatures.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   type Query {\n   *     greeting: String\n   *   }\n   * `);\n   * const document = parse(\n   *   `\n   *     {\n   *       ...GreetingFields\n   *     }\n   *\n   *     fragment GreetingFields on Query {\n   *       greeting\n   *     }\n   *   `,\n   *   { experimentalFragmentArguments: true },\n   * );\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let fragmentName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     Document: () => {\n   *       const getFragmentSignature = context.getFragmentSignatureByName();\n   *       fragmentName =\n   *         getFragmentSignature('GreetingFields')?.definition.name.value;\n   *     },\n   *   }),\n   * );\n   *\n   * fragmentName; // => 'GreetingFields'\n   * ```\n   */\n  getFragmentSignatureByName(): (\n    fragmentName: string,\n  ) => Maybe<FragmentSignature> {\n    return this._typeInfo.getFragmentSignatureByName();\n  }\n\n  /**\n   * Returns the current enum value definition.\n   * @returns The current enum value definition, if known.\n   * @example\n   * ```ts\n   * import { parse, visit } from 'graphql/language';\n   * import { buildSchema, TypeInfo, visitWithTypeInfo } from 'graphql/utilities';\n   * import { ValidationContext } from 'graphql/validation';\n   *\n   * const schema = buildSchema(`\n   *   enum Sort {\n   *     NEWEST\n   *     OLDEST\n   *   }\n   *\n   *   type Query {\n   *     reviews(sort: Sort): [String]\n   *   }\n   * `);\n   * const document = parse('{ reviews(sort: OLDEST) }');\n   * const typeInfo = new TypeInfo(schema);\n   * const context = new ValidationContext(schema, document, typeInfo, () => {});\n   * let enumValueName;\n   *\n   * visit(\n   *   document,\n   *   visitWithTypeInfo(typeInfo, {\n   *     EnumValue: () => {\n   *       enumValueName = context.getEnumValue()?.name;\n   *     },\n   *   }),\n   * );\n   *\n   * enumValueName; // => 'OLDEST'\n   * ```\n   */\n  getEnumValue(): Maybe<GraphQLEnumValue> {\n    return this._typeInfo.getEnumValue();\n  }\n}\n\n/** A function that creates an AST visitor for validating a GraphQL document. */\nexport type ValidationRule = (context: ValidationContext) => ASTVisitor;\n"]}