or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-jest-validate

Generic configuration validation tool that helps with warnings, errors and deprecation messages as well as showing users examples of correct configuration.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/jest-validate@30.1.x

To install, run

npx @tessl/cli install tessl/npm-jest-validate@30.1.0

index.mddocs/

jest-validate

jest-validate is a generic configuration validation tool that helps with warnings, errors and deprecation messages as well as showing users examples of correct configuration. Originally developed for Jest, it provides a comprehensive validation framework for JavaScript/Node.js applications with extensive customization options.

Package Information

  • Package Name: jest-validate
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install jest-validate

Core Imports

import { validate, validateCLIOptions, multipleValidOptions, ValidationError, format, formatPrettyObject, createDidYouMeanMessage, logValidationWarning } from "jest-validate";

For CommonJS:

const { validate, validateCLIOptions, multipleValidOptions, ValidationError, format, formatPrettyObject, createDidYouMeanMessage, logValidationWarning } = require("jest-validate");

Basic Usage

import { validate, multipleValidOptions } from "jest-validate";

// Define example configuration (required)
const exampleConfig = {
  transform: {},
  testMatch: ["**/__tests__/**/*.(js|ts)"],
  verbose: false,
  timeout: 5000,
  retries: multipleValidOptions(1, false) // allows number or boolean
};

// Validate user configuration
const result = validate(userConfig, { exampleConfig });

if (result.isValid) {
  console.log("Configuration is valid!");
  if (result.hasDeprecationWarnings) {
    console.log("Note: Some deprecated options were found");
  }
}

Architecture

jest-validate is built around several key components:

  • Core Validation: validate() function that compares configurations against example schemas
  • CLI Validation: validateCLIOptions() for command-line argument validation with deprecation support
  • Type Checking: Automatic type validation based on example configurations using JavaScript's native type system
  • Multiple Type Support: multipleValidOptions() utility for options that accept different types
  • Error System: Custom ValidationError class with formatted, colorized output
  • Deprecation Management: Built-in handling for deprecated options with customizable warning messages
  • Extensible Handlers: Pluggable error, warning, and unknown option handlers

Capabilities

Configuration Validation

Core validation functionality that compares user configurations against example schemas with comprehensive error reporting and type checking.

/**
 * Validates a configuration object against an example configuration schema
 * @param config - The configuration object to validate
 * @param options - Validation options including required exampleConfig
 * @returns Validation result with deprecation warnings flag and validity status
 */
function validate(
  config: Record<string, unknown>,
  options: ValidationOptions
): { hasDeprecationWarnings: boolean; isValid: boolean };

interface ValidationOptions {
  /** Additional comment text to display with error/warning messages */
  comment?: string;
  /** Custom validation condition function for comparing option values */
  condition?: (option: unknown, validOption: unknown) => boolean;
  /** Custom deprecation handler function */
  deprecate?: (
    config: Record<string, unknown>,
    option: string,
    deprecatedOptions: DeprecatedOptions,
    options: ValidationOptions
  ) => boolean;
  /** Object mapping deprecated option names to deprecation message functions */
  deprecatedConfig?: DeprecatedOptions;
  /** Custom error handler function */
  error?: (
    option: string,
    received: unknown,
    defaultValue: unknown,
    options: ValidationOptions,
    path?: Array<string>
  ) => void;
  /** Required example configuration object that defines valid structure and types */
  exampleConfig: Record<string, unknown>;
  /** Whether to recursively validate nested objects (default: true) */
  recursive?: boolean;
  /** Array of key paths to exclude from recursive validation */
  recursiveDenylist?: Array<string>;
  /** Custom titles for error/warning messages */
  title?: Title;
  /** Custom handler for unknown/unrecognized options */
  unknown?: (
    config: Record<string, unknown>,
    exampleConfig: Record<string, unknown>,
    option: string,
    options: ValidationOptions,
    path?: Array<string>
  ) => void;
}

interface Title {
  deprecation?: string;
  error?: string;
  warning?: string;
}

type DeprecatedOptions = Record<string, DeprecatedOptionFunc>;
type DeprecatedOptionFunc = (arg: Record<string, unknown>) => string;

Usage Examples:

import { validate } from "jest-validate";

// Basic validation
const result = validate(userConfig, {
  exampleConfig: {
    verbose: true,
    testTimeout: 5000,
    setupFiles: []
  }
});

// Custom validation with deprecation handling
const result = validate(userConfig, {
  exampleConfig: { verbose: true },
  deprecatedConfig: {
    silent: () => 'Option "silent" has been replaced by "verbose"'
  },
  comment: 'See documentation at https://example.com/config'
});

// Recursive validation with denylist
const result = validate(userConfig, {
  exampleConfig: { nested: { allowed: true, ignored: {} } },
  recursive: true,
  recursiveDenylist: ['nested.ignored'] // Skip validating nested.ignored
});

CLI Options Validation

Validates command-line options against allowed option schemas with support for deprecated options, aliases, and automatic suggestion generation.

/**
 * Validates CLI options and arguments with deprecation support
 * @param argv - Parsed command-line arguments object (typically from yargs)
 * @param options - Object defining allowed options and their configuration
 * @param rawArgv - Optional raw argument array for filtering
 * @returns true if validation passes, throws ValidationError if not
 */
function validateCLIOptions(
  argv: Config.Argv,
  options: Record<string, Options> & { deprecationEntries?: DeprecatedOptions },
  rawArgv?: Array<string>
): boolean;

interface Options {
  /** Alias for the option (single string or array of strings) */
  alias?: string | string[];
  /** Additional option properties from yargs */
  [key: string]: any;
}

type Config.Argv = Record<string, unknown>;

Usage Examples:

import { validateCLIOptions } from "jest-validate";

// Define allowed CLI options
const allowedOptions = {
  verbose: { alias: 'v' },
  config: { alias: 'c' },
  watch: { alias: 'w' },
  help: { alias: 'h' }
};

// Validate CLI arguments
try {
  validateCLIOptions(parsedArgs, allowedOptions);
  console.log("CLI options are valid");
} catch (error) {
  console.error(error.message);
}

// With deprecation entries
const optionsWithDeprecation = {
  ...allowedOptions,
  deprecationEntries: {
    runInBand: () => 'Option "runInBand" has been replaced by "maxWorkers=1"'
  }
};

validateCLIOptions(parsedArgs, optionsWithDeprecation);

Multiple Valid Options

Utility for creating configuration options that accept multiple types, enabling flexible API design while maintaining type safety.

/**
 * Creates a configuration that accepts multiple valid types for a single option
 * Uses internal symbol marking to allow validation against multiple type examples
 * @param args - Variable number of example values of different types
 * @returns Array containing the examples, marked internally for multi-type validation
 */
function multipleValidOptions<T extends Array<unknown>>(...args: T): T[number];

Usage Examples:

import { validate, multipleValidOptions } from "jest-validate";

// Allow string or number for maxWorkers
const exampleConfig = {
  maxWorkers: multipleValidOptions("50%", 4),
  verbose: multipleValidOptions(true, "full"), // boolean or specific string
  timeout: multipleValidOptions(5000, "30s") // number or string
};

const result = validate({
  maxWorkers: "75%", // Valid - matches string type
  verbose: true,     // Valid - matches boolean type  
  timeout: "45s"     // Valid - matches string type
}, { exampleConfig });

Error Handling

Custom error class for validation failures with formatted, colorized output designed for developer-friendly error messages.

/**
 * Custom error class for validation failures with formatted output
 */
class ValidationError extends Error {
  override name: string;
  override message: string;
  
  /**
   * Creates a new validation error with formatted message
   * @param name - Error name/title to display
   * @param message - Main error message content
   * @param comment - Optional additional comment or documentation reference
   */
  constructor(name: string, message: string, comment?: string | null);
}

Utility Functions

Helper functions for formatting values and creating user-friendly error messages.

/**
 * Formats values for display in error messages
 * @param value - Value to format (any type)
 * @returns Formatted string representation
 */
function format(value: unknown): string;

/**
 * Formats values as pretty-printed objects for display
 * @param value - Value to format (any type)
 * @returns Pretty-formatted string representation with indentation
 */
function formatPrettyObject(value: unknown): string;

/**
 * Creates suggestion messages for similar option names using edit distance
 * @param unrecognized - The unrecognized option name
 * @param allowedOptions - Array of valid option names
 * @returns Suggestion message or empty string if no close matches
 */
function createDidYouMeanMessage(
  unrecognized: string,
  allowedOptions: Array<string>
): string;

/**
 * Logs validation warnings to console with formatted output
 * @param name - Warning name/title
 * @param message - Warning message content
 * @param comment - Optional additional comment
 */
function logValidationWarning(
  name: string,
  message: string,
  comment?: string | null
): void;

Usage Examples:

import { ValidationError, format, createDidYouMeanMessage } from "jest-validate";

// Custom error handling
try {
  // Some validation logic
  throw new ValidationError(
    "Custom Validation Error",
    `Invalid value: ${format(userValue)}`,
    "Check the documentation for valid options"
  );
} catch (error) {
  console.error(error.message); // Formatted, colorized output
}

// Generate suggestions
const suggestion = createDidYouMeanMessage("verbos", ["verbose", "version"]);
console.log(suggestion); // "Did you mean verbose?"

// Format various value types
console.log(format("hello"));     // "hello"
console.log(format(42));          // 42
console.log(format([1, 2, 3]));   // [1, 2, 3]
console.log(format(undefined));   // undefined

// Format with pretty printing for objects
console.log(formatPrettyObject({ name: "test", value: 42 }));
// Output:
// {
//   "name": "test",
//   "value": 42
// }

Advanced Configuration

Custom Validation Conditions

import { validate } from "jest-validate";

const result = validate(userConfig, {
  exampleConfig: { port: 3000 },
  condition: (option, validOption) => {
    // Custom logic for port validation
    if (typeof option === 'number' && typeof validOption === 'number') {
      return option > 0 && option < 65536;
    }
    return option === validOption;
  }
});

Custom Error Handlers

import { validate, ValidationError } from "jest-validate";

const result = validate(userConfig, {
  exampleConfig: { timeout: 5000 },
  error: (option, received, defaultValue, options, path) => {
    const fullPath = path ? `${path.join('.')}.${option}` : option;
    throw new ValidationError(
      "Configuration Error",
      `Option "${fullPath}" expected ${typeof defaultValue} but got ${typeof received}`,
      "Please check your configuration file"
    );
  }
});

Handling Unknown Options

import { validate } from "jest-validate";

const result = validate(userConfig, {
  exampleConfig: { knownOption: true },
  unknown: (config, exampleConfig, option, options, path) => {
    const fullPath = path ? `${path.join('.')}.${option}` : option;
    console.warn(`Unknown option "${fullPath}" will be ignored`);
    // Could also delete the unknown option: delete config[option];
  }
});