CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-graphql

JavaScript reference implementation for GraphQL query language and runtime

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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)
]);

docs

core-execution.md

error-handling.md

execution-engine.md

index.md

language-processing.md

schema-utilities.md

type-system.md

validation-system.md

tile.json