or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

graphql-resolvers.mdimage-cdn-polyfill.mdindex.mdjoi-schemas.mdruntime-compatibility.mdschema-validation.md
tile.json

joi-schemas.mddocs/

Joi Schema Types

Extended Joi validation library with Gatsby-specific extensions, complete TypeScript support, and specialized plugin validation features.

Capabilities

Joi Instance

Extended Joi validation library with Gatsby-specific rules and full TypeScript integration.

/**
 * Extended Joi instance with Gatsby-specific validation rules
 */
const Joi: PluginOptionsSchemaJoi;

ObjectSchema

Joi object schema type for plugin options validation with async support.

interface ObjectSchema {
  /**
   * Validates value asynchronously against the schema
   * @param value - Value to validate
   * @param options - Validation options
   * @returns Promise with validated value
   */
  validateAsync(value: any, options?: ValidationOptions): Promise<any>;
  
  /**
   * Validates value synchronously against the schema
   * @param value - Value to validate  
   * @param options - Validation options
   * @returns Validation result
   */
  validate(value: any, options?: ValidationOptions): ValidationResult;
  
  /**
   * Creates validation rules with pattern matching
   * @param pattern - Pattern to match against
   * @param schema - Schema for matched values
   * @returns Schema with pattern rule
   */
  pattern(pattern: RegExp, schema: Schema): ObjectSchema;
}

Schema Building

Basic Schema Types

// String validation
const stringSchema = Joi.string()
  .min(1)
  .max(100)
  .required()
  .description("User name");

// Number validation  
const numberSchema = Joi.number()
  .integer()
  .min(0)
  .max(1000)
  .default(10);
  
// Boolean validation
const booleanSchema = Joi.boolean()
  .default(false)
  .description("Enable feature");

// Array validation
const arraySchema = Joi.array()
  .items(Joi.string())
  .min(1)
  .unique()
  .default([]);

// Object validation
const objectSchema = Joi.object({
  name: Joi.string().required(),
  age: Joi.number().min(0),
  active: Joi.boolean().default(true)
});

Advanced Schema Patterns

import { Joi } from "gatsby-plugin-utils";

// Conditional validation
const conditionalSchema = Joi.object({
  type: Joi.string().valid('basic', 'advanced').required(),
  config: Joi.when('type', {
    is: 'basic',
    then: Joi.object({
      setting: Joi.string().required()
    }),
    otherwise: Joi.object({
      setting: Joi.string().required(),
      advancedOption: Joi.number().required(),
      features: Joi.array().items(Joi.string())
    })
  })
});

// Alternative schemas
const alternativeSchema = Joi.alternatives().try(
  Joi.string(),
  Joi.number(),
  Joi.object({
    custom: Joi.boolean()
  })
);

// External references
const referenceSchema = Joi.object({
  name: Joi.string().required(),
  confirmName: Joi.string().valid(Joi.ref('name')).required()
});

Gatsby-Specific Extensions

SubPlugins Validation

Special validation for Gatsby plugin arrays with automatic normalization.

/**
 * Validates arrays of Gatsby plugins
 * Accepts string names or objects with resolve/options
 * Automatically normalizes string entries to objects
 */
Joi.subPlugins(): ArraySchema;

Usage Examples:

const pluginSchema = Joi.object({
  plugins: Joi.subPlugins().description("Sub-plugins to load")
});

// Valid inputs:
const validOptions1 = {
  plugins: ["gatsby-plugin-react-helmet", "gatsby-plugin-image"]
};

const validOptions2 = {
  plugins: [
    "gatsby-plugin-react-helmet",
    {
      resolve: "gatsby-plugin-google-analytics", 
      options: {
        trackingId: "UA-12345678-1"
      }
    }
  ]
};

// Normalized output:
// plugins: [
//   { resolve: "gatsby-plugin-react-helmet" },
//   { resolve: "gatsby-plugin-google-analytics", options: { trackingId: "UA-12345678-1" } }
// ]

Environment Variable Extensions

Extension for referencing environment variables in schemas (currently disabled but available in type definitions).

/**
 * References environment variables (disabled in current version)
 * @param name - Environment variable name
 */
// .dotenv(name: string): Schema; // Currently disabled

Validation Options

interface ValidationOptions {
  /**
   * Stop on first error (default: true)
   */
  abortEarly?: boolean;
  
  /**
   * Allow unknown object keys (default: false)
   */
  allowUnknown?: boolean;
  
  /**
   * Enable schema caching (default: false)
   */
  cache?: boolean;
  
  /**
   * External data context for references
   */
  context?: Record<string, any>;
  
  /**
   * Convert values to required types (default: true)
   */
  convert?: boolean;
  
  /**
   * Validate external rules (default: true)
   */
  externals?: boolean;
  
  /**
   * Custom error messages
   */
  messages?: Record<string, string>;
  
  /**
   * Include warnings in async validation (default: false)
   */
  warnings?: boolean;
}

Complete Schema Example

import { Joi } from "gatsby-plugin-utils";

const completePluginSchema = Joi.object({
  // Required API configuration
  apiKey: Joi.string()
    .required()
    .description("API authentication key"),
    
  apiUrl: Joi.string()
    .uri({ scheme: ['http', 'https'] })
    .default("https://api.example.com")
    .description("API base URL"),
    
  // Optional timeout settings
  timeout: Joi.number()
    .integer()
    .min(1000)
    .max(60000)
    .default(10000)
    .description("Request timeout in milliseconds"),
    
  retries: Joi.number()
    .integer()
    .min(0)
    .max(5)
    .default(3)
    .description("Number of retry attempts"),
    
  // Feature toggles
  features: Joi.object({
    enableCache: Joi.boolean().default(true),
    enableMetrics: Joi.boolean().default(false),
    enableDebug: Joi.boolean().default(false)
  }).default({}),
  
  // Data processing options
  processing: Joi.object({
    batchSize: Joi.number().integer().min(1).max(1000).default(100),
    parallel: Joi.boolean().default(false),
    format: Joi.string().valid('json', 'xml', 'csv').default('json')
  }).default({}),
  
  // Sub-plugins using Gatsby extension
  plugins: Joi.subPlugins().description("Additional plugins to load"),
  
  // Conditional validation based on environment
  environment: Joi.string().valid('development', 'production', 'test').default('production'),
  devOptions: Joi.when('environment', {
    is: 'development',
    then: Joi.object({
      hotReload: Joi.boolean().default(true),
      verbose: Joi.boolean().default(true)
    }),
    otherwise: Joi.forbidden()
  }),
  
  // Array of endpoints with validation
  endpoints: Joi.array().items(
    Joi.object({
      name: Joi.string().required(),
      path: Joi.string().required(),
      method: Joi.string().valid('GET', 'POST', 'PUT', 'DELETE').default('GET'),
      headers: Joi.object().pattern(/.*/, Joi.string())
    })
  ).min(1).unique('name'),
  
  // File path validation
  outputPath: Joi.string()
    .required()
    .description("Output directory path"),
    
  // Pattern matching for dynamic configuration
  dynamicConfig: Joi.object().pattern(
    /^config_\w+$/,
    Joi.alternatives().try(
      Joi.string(),
      Joi.number(),
      Joi.boolean()
    )
  )
}).required();

// Usage in gatsby-node.js
exports.pluginOptionsSchema = ({ Joi }) => completePluginSchema;

Type Definitions

The library provides complete TypeScript definitions for all Joi functionality:

interface PluginOptionsSchemaJoi {
  string(): StringSchema;
  number(): NumberSchema;  
  boolean(): BooleanSchema;
  array(): ArraySchema;
  object(schema?: SchemaMap): ObjectSchema;
  alternatives(): AlternativesSchema;
  any(): AnySchema;
  
  // Gatsby-specific extensions
  subPlugins(): ArraySchema;
  
  // Validation utilities
  validate(value: any, schema: Schema, options?: ValidationOptions): ValidationResult;
  attempt(value: any, schema: Schema, options?: ValidationOptions): any;
  compile(schema: SchemaLike): Schema;
  
  // Reference utilities
  ref(key: string, options?: ReferenceOptions): Reference;
  when(ref: string | Reference, options: WhenOptions): AlternativesSchema;
}

interface ValidationResult {
  error?: ValidationError;
  value: any;
  warning?: ValidationError;
}

interface ValidationError extends Error {
  details: Array<{
    message: string;
    path: Array<string>;
    type: string;
    context?: Record<string, any>;
  }>;
}