or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-execution.mderror-handling.mdexecution-engine.mdindex.mdlanguage-processing.mdschema-utilities.mdtype-system.mdvalidation-system.md
tile.json

validation-system.mddocs/

Validation System

The validation system implements all GraphQL specification validation rules with extensible validation context and support for custom validation rules.

Capabilities

Document Validation

Validate GraphQL documents against a schema using the complete set of GraphQL validation rules.

/**
 * Validate a GraphQL document against a schema
 * @param schema - GraphQL schema to validate against
 * @param documentAST - Parsed GraphQL document to validate
 * @param rules - Validation rules to apply (defaults to specifiedRules)
 * @returns Array of validation errors (empty if valid)
 */
function validate(
  schema: GraphQLSchema,
  documentAST: DocumentNode,
  rules?: ReadonlyArray<ValidationRule>
): ReadonlyArray<GraphQLError>;

/**
 * Type definition for validation rules
 */
type ValidationRule = (context: ValidationContext) => ASTVisitor;

Usage Examples:

import { validate, parse, buildSchema, specifiedRules } from "graphql";

const schema = buildSchema(`
  type Query {
    user(id: ID!): User
  }
  
  type User {
    id: ID!
    name: String!
  }
`);

// Validate a valid document
const validDocument = parse(`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
    }
  }
`);

const validationErrors = validate(schema, validDocument);
console.log(validationErrors.length); // 0 - no errors

// Validate an invalid document
const invalidDocument = parse(`
  query GetUser {
    user(id: "123") {
      id
      nonExistentField
    }
  }
`);

const errors = validate(schema, invalidDocument);
console.log(errors.map(error => error.message));
// ["Cannot query field \"nonExistentField\" on type \"User\"."]

// Validate with custom rules
const customErrors = validate(schema, documentAST, [
  ...specifiedRules,
  NoDeprecatedCustomRule
]);

Validation Context

Validation context provides schema information and error reporting during validation.

/**
 * Context object passed to validation rules with schema and document information
 */
class ValidationContext {
  constructor(schema: GraphQLSchema, ast: DocumentNode, typeInfo: TypeInfo);
  
  /** Report a validation error */
  reportError(error: GraphQLError): void;
  
  /** Get all reported errors */
  getErrors(): ReadonlyArray<GraphQLError>;
  
  /** Get the GraphQL schema */
  getSchema(): GraphQLSchema;
  
  /** Get the document AST */
  getDocument(): DocumentNode;
  
  /** Get fragment definition by name */
  getFragment(name: string): FragmentDefinitionNode | undefined;
  
  /** Get all fragment definitions */
  getFragmentSpreads(node: SelectionSetNode): ReadonlyArray<FragmentSpreadNode>;
  
  /** Get recursively referenced fragments */
  getRecursivelyReferencedFragments(operation: OperationDefinitionNode): ReadonlyArray<FragmentDefinitionNode>;
  
  /** Get variable usages in a node */
  getRecursiveVariableUsages(node: OperationDefinitionNode | FragmentDefinitionNode): ReadonlyArray<VariableUsage>;
  
  /** Get type information tracker */
  getType(): Maybe<GraphQLOutputType>;
  getParentType(): Maybe<GraphQLCompositeType>;
  getInputType(): Maybe<GraphQLInputType>;
  getParentInputType(): Maybe<GraphQLInputType>;
  getFieldDef(): Maybe<GraphQLField<any, any>>;
  getDirective(): Maybe<GraphQLDirective>;
  getArgument(): Maybe<GraphQLArgument>;
}

interface VariableUsage {
  readonly node: VariableNode;
  readonly type: Maybe<GraphQLInputType>;
  readonly defaultValue: unknown;
}

Validation Rule Collections

Pre-defined collections of validation rules for different use cases.

/**
 * All validation rules specified in the GraphQL specification
 */
const specifiedRules: ReadonlyArray<ValidationRule>;

/**
 * Recommended subset of validation rules for production use
 * Excludes some expensive rules like MaxIntrospectionDepthRule
 */
const recommendedRules: ReadonlyArray<ValidationRule>;

Usage Examples:

import { validate, specifiedRules, recommendedRules } from "graphql";

// Use all specification rules (default)
const allErrors = validate(schema, document, specifiedRules);

// Use recommended rules for better performance
const prodErrors = validate(schema, document, recommendedRules);

// Use specific rules only
const customRules = [
  FieldsOnCorrectTypeRule,
  KnownArgumentNamesRule,
  ProvidedRequiredArgumentsRule
];
const limitedErrors = validate(schema, document, customRules);

Individual Validation Rules

Document Structure Rules

Rules that validate the overall structure and organization of GraphQL documents.

/**
 * Validates that document contains only executable definitions
 */
const ExecutableDefinitionsRule: ValidationRule;

/**
 * Validates that anonymous operations are alone in the document
 */
const LoneAnonymousOperationRule: ValidationRule;

/**
 * Validates that subscription operations have a single root field
 */
const SingleFieldSubscriptionsRule: ValidationRule;

Field and Fragment Rules

Rules that validate field selections and fragment usage.

/**
 * Validates that fields exist on their parent types
 */
const FieldsOnCorrectTypeRule: ValidationRule;

/**
 * Validates that fragments are defined on composite types
 */
const FragmentsOnCompositeTypesRule: ValidationRule;

/**
 * Validates that fragment spreads reference defined fragments
 */
const KnownFragmentNamesRule: ValidationRule;

/**
 * Validates that fragments don't create reference cycles
 */
const NoFragmentCyclesRule: ValidationRule;

/**
 * Validates that all defined fragments are used
 */
const NoUnusedFragmentsRule: ValidationRule;

/**
 * Validates that fragment spreads are type-compatible
 */
const PossibleFragmentSpreadsRule: ValidationRule;

/**
 * Validates that overlapping fields can be merged
 */
const OverlappingFieldsCanBeMergedRule: ValidationRule;

Argument and Variable Rules

Rules that validate arguments and variable usage.

/**
 * Validates that field and directive arguments are defined
 */
const KnownArgumentNamesRule: ValidationRule;

/**
 * Validates that required arguments are provided
 */
const ProvidedRequiredArgumentsRule: ValidationRule;

/**
 * Validates that argument names are unique within field/directive
 */
const UniqueArgumentNamesRule: ValidationRule;

/**
 * Validates that variables are defined before use
 */
const NoUndefinedVariablesRule: ValidationRule;

/**
 * Validates that all defined variables are used
 */
const NoUnusedVariablesRule: ValidationRule;

/**
 * Validates that variable names are unique within operation
 */
const UniqueVariableNamesRule: ValidationRule;

/**
 * Validates that variables have input types
 */
const VariablesAreInputTypesRule: ValidationRule;

/**
 * Validates that variables are used in compatible positions
 */
const VariablesInAllowedPositionRule: ValidationRule;

Directive Rules

Rules that validate directive usage.

/**
 * Validates that directives are defined and used in valid locations
 */
const KnownDirectivesRule: ValidationRule;

/**
 * Validates that non-repeatable directives appear once per location
 */
const UniqueDirectivesPerLocationRule: ValidationRule;

Type and Value Rules

Rules that validate types and literal values.

/**
 * Validates that referenced types are defined in the schema
 */
const KnownTypeNamesRule: ValidationRule;

/**
 * Validates that leaf fields don't have selections
 */
const ScalarLeafsRule: ValidationRule;

/**
 * Validates that literal values match their expected types
 */
const ValuesOfCorrectTypeRule: ValidationRule;

Uniqueness Rules

Rules that ensure uniqueness of various GraphQL constructs.

/**
 * Validates that fragment names are unique within document
 */
const UniqueFragmentNamesRule: ValidationRule;

/**
 * Validates that input object field names are unique
 */
const UniqueInputFieldNamesRule: ValidationRule;

/**
 * Validates that operation names are unique within document
 */
const UniqueOperationNamesRule: ValidationRule;

SDL-Specific Validation Rules

Rules that apply specifically to Schema Definition Language documents.

/**
 * Validates that schema definition appears at most once
 */
const LoneSchemaDefinitionRule: ValidationRule;

/**
 * Validates that operation types are unique in schema definition
 */
const UniqueOperationTypesRule: ValidationRule;

/**
 * Validates that type names are unique within schema
 */
const UniqueTypeNamesRule: ValidationRule;

/**
 * Validates that enum value names are unique within enum
 */
const UniqueEnumValueNamesRule: ValidationRule;

/**
 * Validates that field names are unique within object/interface types
 */
const UniqueFieldDefinitionNamesRule: ValidationRule;

/**
 * Validates that argument names are unique within field definitions
 */
const UniqueArgumentDefinitionNamesRule: ValidationRule;

/**
 * Validates that directive names are unique within schema
 */
const UniqueDirectiveNamesRule: ValidationRule;

/**
 * Validates that type extensions are valid
 */
const PossibleTypeExtensionsRule: ValidationRule;

Custom Validation Rules

Additional validation rules for specific use cases.

/**
 * Custom rule to disallow deprecated fields and arguments
 */
const NoDeprecatedCustomRule: ValidationRule;

/**
 * Custom rule to disallow schema introspection queries
 */
const NoSchemaIntrospectionCustomRule: ValidationRule;

/**
 * Rule to limit introspection query depth for security
 */
const MaxIntrospectionDepthRule: ValidationRule;

Usage Examples:

import { 
  validate, 
  NoDeprecatedCustomRule,
  NoSchemaIntrospectionCustomRule 
} from "graphql";

// Create custom validation with security rules
const securityRules = [
  NoSchemaIntrospectionCustomRule,
  MaxIntrospectionDepthRule,
  NoDeprecatedCustomRule
];

const errors = validate(schema, document, [
  ...specifiedRules,
  ...securityRules
]);

// Custom validation rule example
const NoLongFieldNamesRule = (context) => ({
  Field(node) {
    if (node.name.value.length > 20) {
      context.reportError(
        new GraphQLError(
          `Field name "${node.name.value}" is too long`,
          { nodes: node }
        )
      );
    }
  }
});

const customErrors = validate(schema, document, [
  ...specifiedRules,
  NoLongFieldNamesRule
]);

Creating Custom Validation Rules

Rule Function Structure

/**
 * Create a custom validation rule
 * @param context - Validation context
 * @returns AST visitor object
 */
type ValidationRule = (context: ValidationContext) => ASTVisitor;

/**
 * Example custom validation rule
 */
const ExampleCustomRule: ValidationRule = (context) => ({
  // Visit field nodes
  Field(node) {
    // Perform validation logic
    if (shouldReportError(node)) {
      context.reportError(
        new GraphQLError('Custom validation error', { nodes: node })
      );
    }
  },
  
  // Visit other node types
  Directive(node) {
    // Additional validation logic
  }
});

Usage Examples:

import { GraphQLError, ValidationRule } from "graphql";

// Rule to prevent fields starting with underscore (except introspection)
const NoUnderscoreFieldsRule: ValidationRule = (context) => ({
  Field(node) {
    const fieldName = node.name.value;
    if (fieldName.startsWith('_') && !fieldName.startsWith('__')) {
      context.reportError(
        new GraphQLError(
          `Field names cannot start with underscore: "${fieldName}"`,
          { nodes: node }
        )
      );
    }
  }
});

// Rule to limit query depth
const MaxDepthRule = (maxDepth: number): ValidationRule => (context) => {
  let depth = 0;
  
  return {
    Field: {
      enter() {
        depth++;
        if (depth > maxDepth) {
          context.reportError(
            new GraphQLError(
              `Query depth exceeds maximum of ${maxDepth}`,
              { nodes: context.getDocument() }
            )
          );
        }
      },
      leave() {
        depth--;
      }
    }
  };
};

// Use custom rules
const errors = validate(schema, document, [
  ...specifiedRules,
  NoUnderscoreFieldsRule,
  MaxDepthRule(10)
]);