npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

graphql-mandatory-validator

v1.3.2

Published

A GraphQL schema validator using AST-only parsing for mandatory fields with default values, array validation, and composite type validation

Readme

graphql-mandatory-validator

A Node.js package for validating GraphQL schema files to ensure mandatory fields have appropriate default values. This tool helps maintain schema consistency across multiple repositories and prevents breaking changes.

Features

  • ✅ Validates mandatory GraphQL fields have default values
  • 🏗️ Validates mandatory composite types have at least one mandatory field
  • 🎯 NEW: Validates mandatory enum fields have default values
  • 🔧 Configurable scalar type defaults
  • 📁 Works with standard src/type-defs directory structure
  • 🚀 Can validate staged files (git pre-commit) or entire projects
  • 🎨 Colored terminal output with detailed error messages
  • 📦 Available as both CLI tool and programmatic API
  • 🔄 Supports multiple repositories with consistent structure

Installation

Global Installation (CLI usage)

npm install -g graphql-mandatory-validator

Local Installation (Project dependency)

npm install --save-dev graphql-mandatory-validator

CLI Usage

Basic Usage

# Validate staged .graphql files (for pre-commit hooks)
graphql-validator

# Validate all .graphql files in the project
graphql-validator --mode all

Advanced Options

# Use custom base directory
graphql-validator --base-dir schema/definitions

# Validate specific project root
graphql-validator --mode all --project-root /path/to/project

# Disable colored output
graphql-validator --no-color

# Don't exit process on validation failure
graphql-validator --no-exit

Help

graphql-validator --help

Programmatic API

Basic Usage

import { GraphQLValidator } from 'graphql-mandatory-validator';

const validator = new GraphQLValidator();

// Validate staged files
const result = await validator.validateStagedFiles();

// Validate entire project
const result = await validator.validateProject();

console.log(`Validation ${result.success ? 'passed' : 'failed'}`);
console.log(`Files checked: ${result.filesChecked}`);
console.log(`Errors found: ${result.errors.length}`);

Advanced Configuration

import { GraphQLValidator } from 'graphql-mandatory-validator';

const validator = new GraphQLValidator({
  baseDir: 'custom/graphql/path',
  colorOutput: false,
  exitOnError: false,
  scalarDefaults: {
    String: '@defaultValue(value: "")',
    Int: '@defaultValue(value: 0)',
    Float: '@defaultValue(value: 0.0)',
    Boolean: '@defaultValue(value: false)',
    ID: '@defaultValue(value: "")',
    // Add custom scalar types
    DateTime: '@defaultValue(value: "1970-01-01T00:00:00Z")',
  }
});

const result = await validator.run('all', '/path/to/project');

Validation Rules

1. Scalar Type Default Values

The validator enforces the following default values for GraphQL scalar types:

| GraphQL Type | Required Default Value | |--------------|------------------------| | String! | @defaultValue(value: "") | | Int! | @defaultValue(value: 0) | | Float! | @defaultValue(value: 0.0) | | Boolean! | @defaultValue(value: false) | | ID! | @defaultValue(value: "") |

2. Composite Type Validation

The validator ensures that if a composite type is used as a mandatory field, the composite type itself must contain at least one mandatory field.

Why this rule? If a composite type has no mandatory fields, making it mandatory doesn't provide any meaningful constraint - it could be an empty object and still satisfy the schema.

3. Enum Type Validation

NEW: The validator ensures that mandatory enum fields have appropriate default values.

Default Value Format: @defaultValue(value: "ENUM_VALUE")

Recommended Values:

  • Use "UNKNOWN" if available in the enum
  • Otherwise, use any valid enum value

Why this rule? Mandatory enum fields without defaults can break existing queries when new enum types are introduced.

Example GraphQL Schema

Scalar Type Validation

❌ Invalid (will fail validation)

type User {
  id: ID!
  name: String!
  age: Int!
  isActive: Boolean!
}

✅ Valid (passes validation)

type User {
  id: ID! @defaultValue(value: "")
  name: String! @defaultValue(value: "")
  age: Int! @defaultValue(value: 0)
  isActive: Boolean! @defaultValue(value: false)
}

Composite Type Validation

❌ Invalid (will fail validation)

type User {
  id: ID! @defaultValue(value: "")
  profile: Profile!  # ERROR: Profile has no mandatory fields
}

type Profile {
  bio: String        # Optional field
  avatar: String     # Optional field
  website: String    # Optional field
}

Error: Mandatory composite field "profile" of type "Profile!" references a type with no mandatory fields. Type "Profile" should have at least one mandatory field.

✅ Valid (passes validation)

# Option 1: Add mandatory field to composite type
type User {
  id: ID! @defaultValue(value: "")
  profile: Profile!
}

type Profile {
  userId: ID! @defaultValue(value: "")  # Now has mandatory field
  bio: String
  avatar: String
  website: String
}

# Option 2: Make composite field optional
type User {
  id: ID! @defaultValue(value: "")
  profile: Profile   # Made optional (no !)
}

type Profile {
  bio: String
  avatar: String
  website: String
}

Enum Type Validation

❌ Invalid (will fail validation)

type Order {
  id: ID! @defaultValue(value: "")
  status: OrderStatus!     # ERROR: Missing default value
  priority: Priority!      # ERROR: Missing default value
}

Error: Mandatory field "status" of type "OrderStatus!" must have a default value. For enum types, use @defaultValue(value: "UNKNOWN") or @defaultValue(value: "<enum_value>") with one of the enum values.

✅ Valid (passes validation)

# Option 1: Using UNKNOWN (recommended)
type Order {
  id: ID! @defaultValue(value: "")
  status: OrderStatus! @defaultValue(value: "UNKNOWN")
  priority: Priority! @defaultValue(value: "UNKNOWN")
}

# Option 2: Using specific enum values
type Task {
  id: ID! @defaultValue(value: "")
  status: TaskStatus! @defaultValue(value: "PENDING")
  priority: Priority! @defaultValue(value: "MEDIUM")
}

# Option 3: Mixed approach
type Product {
  id: ID! @defaultValue(value: "")
  category: Category! @defaultValue(value: "UNKNOWN")  # Has UNKNOWN
  status: ProductStatus! @defaultValue(value: "DRAFT")  # No UNKNOWN, use first value
}

Git Pre-commit Hook Integration

Using Husky

  1. Install husky:

    npm install --save-dev husky
    npx husky install
  2. Add pre-commit hook:

    npx husky add .husky/pre-commit "graphql-validator"

Using pre-commit (Python)

Add to your .pre-commit-config.yaml:

repos:
  - repo: local
    hooks:
      - id: graphql-validator
        name: GraphQL Schema Validator
        entry: graphql-validator
        language: node
        files: \\.graphql$
        pass_filenames: false

Package.json Scripts

Add to your package.json:

{
  "scripts": {
    "validate-graphql": "graphql-validator --mode all",
    "validate-graphql:staged": "graphql-validator"
  }
}

Configuration Options

Constructor Options

interface ValidationOptions {
  baseDir?: string;           // Default: 'src/type-defs'
  scalarDefaults?: Record<string, string>;
  colorOutput?: boolean;      // Default: true
  exitOnError?: boolean;      // Default: true
}

ValidationResult

interface ValidationResult {
  success: boolean;
  errors: ValidationError[];
  filesChecked: number;
}

interface ValidationError {
  file: string;
  line: number;
  fieldName: string;
  fieldType: string;
  expectedDefault: string;
  message: string;
}

Repository Structure Requirements

This package assumes your GraphQL files are located in:

your-project/
├── src/
│   └── type-defs/
│       ├── schema1.graphql
│       ├── schema2.graphql
│       └── ...
└── package.json

You can customize the base directory using the baseDir option.

License

MIT

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Support

For issues and questions, please open an issue on the GitHub repository.