CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-joi

Object schema validation library for JavaScript with comprehensive validation capabilities

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

references-expressions.mddocs/

References and Expressions

Dynamic validation system supporting field references, context access, and template expressions for advanced validation scenarios.

Capabilities

Reference Function

Creates references to other fields or context values for dynamic validation.

/**
 * Creates reference to another field for dynamic validation
 * @param key - Reference key (field path or context path)
 * @param options - Optional reference configuration
 * @returns Reference object for dynamic value access
 */
function ref(key: string, options?: ReferenceOptions): Reference;

interface ReferenceOptions {
  // Separator for key path parsing (default: '.')
  separator?: string;
  
  // Context options
  contextPrefix?: string;        // Prefix for context references (default: '$')
  
  // Path options  
  ancestor?: number;             // Number of parent levels to traverse
  prefix?: {
    global?: string;             // Global context prefix (default: '/')
    local?: string;              // Local context prefix (default: '#')
    root?: string;               // Root value prefix (default: '#')
  };
  
  // Rendering options
  render?: boolean;              // Enable template rendering (default: true)
  
  // Adjustment function
  adjust?: (value: any) => any;  // Value adjustment function
  
  // Mapping function
  map?: Array<[any, any]> | Map<any, any>; // Value mapping
  
  // In-references
  in?: boolean;                  // Enable in-reference mode
}

interface Reference {
  readonly isContext: boolean;   // True if reference points to context
  readonly isGlobal: boolean;    // True if reference is global
  readonly key: string;          // Reference key
  readonly path: string[];       // Parsed key path
  readonly ancestor: number;     // Ancestor level count
  readonly prefix: string;       // Reference prefix type
  readonly root: string;         // Root identifier
  readonly display: string;      // Display representation
  readonly type: string;         // Reference type ('value' | 'context' | 'global')
}

Usage Examples:

const Joi = require('joi');

// Basic field reference
const schema = Joi.object({
    password: Joi.string().min(8),
    confirmPassword: Joi.string().valid(Joi.ref('password'))
});

// Context reference
const contextSchema = Joi.object({
    minValue: Joi.number().min(Joi.ref('$minAllowed'))
});

const { error, value } = contextSchema.validate(
    { minValue: 5 },
    { context: { minAllowed: 10 } }
);

// Nested field reference
const nestedSchema = Joi.object({
    user: Joi.object({
        name: Joi.string(),
        email: Joi.string().email()
    }),
    contact: Joi.object({
        primaryEmail: Joi.string().valid(Joi.ref('..user.email'))
    })
});

// Reference with ancestor traversal
const hierarchySchema = Joi.object({
    level1: Joi.object({
        value: Joi.string(),
        level2: Joi.object({
            compare: Joi.string().valid(Joi.ref('value', { ancestor: 1 }))
        })
    })
});

// Reference with custom separator
const customRefSchema = Joi.object({
    'field/name': Joi.string(),
    compare: Joi.string().valid(Joi.ref('field/name', { separator: '/' }))
});

In Reference Function

Creates array references for rule matching and validation.

/**
 * Creates array reference for rule matching
 * @param ref - Reference key or Reference object
 * @param options - Optional reference configuration
 * @returns Reference configured for array matching
 */
function in(ref: string | Reference, options?: ReferenceOptions): Reference;

Usage Examples:

// Array membership validation
const membershipSchema = Joi.object({
    allowedValues: Joi.array().items(Joi.string()),
    selectedValue: Joi.string().valid(Joi.in('allowedValues'))
});

const { error, value } = membershipSchema.validate({
    allowedValues: ['red', 'green', 'blue'],
    selectedValue: 'red' // Valid - 'red' is in allowedValues array
});

// Dynamic validation based on array context
const dynamicSchema = Joi.object({
    category: Joi.string().valid(Joi.in('$availableCategories'))
});

const contextValidation = dynamicSchema.validate(
    { category: 'electronics' },
    { 
        context: { 
            availableCategories: ['electronics', 'clothing', 'books'] 
        } 
    }
);

Expression Function

Creates template expressions for dynamic content generation and validation.

/**
 * Creates template expressions with dynamic placeholders
 * @param template - Template string with placeholder syntax
 * @param options - Optional template configuration
 * @returns Template object for dynamic rendering
 */
function expression(template: string, options?: TemplateOptions): Template;

// Alias for expression function
const x: typeof expression;

interface TemplateOptions {
  // Custom functions for template rendering
  functions?: Record<string, Function>;
  
  // Variable references
  reference?: boolean;           // Enable reference resolution (default: true)
}

interface Template {
  readonly isTemplate: boolean;  // Always true for template objects
  readonly source: string;       // Original template string
  
  /**
   * Renders template with provided context
   * @param context - Rendering context with variables
   * @param prefs - Optional preferences
   * @param local - Local context variables
   * @param options - Rendering options
   * @returns Rendered string
   */
  render(
    context: any, 
    prefs?: any, 
    local?: any, 
    options?: any
  ): string;
}

Usage Examples:

// Basic template expression
const messageTemplate = Joi.expression('Hello {#name}, you are {#age} years old');

// Custom error messages with templates
const customSchema = Joi.string()
    .min(3)
    .message(Joi.expression('Field {#label} must be at least {#limit} characters, got {#value}'));

// Dynamic validation with templates
const dynamicValidation = Joi.object({
    name: Joi.string().required(),
    greeting: Joi.string().valid(Joi.expression('Hello {#name}'))
});

// Template with functions
const advancedTemplate = Joi.expression('User {#name|uppercase} has {#posts|length} posts', {
    functions: {
        uppercase: (value) => value.toUpperCase(),
        length: (array) => array ? array.length : 0
    }
});

// Using x alias
const shortTemplate = Joi.x('Welcome {#user.name}!');

Reference Utilities

Utility functions for working with references and templates.

/**
 * Checks if value is a reference object
 * @param ref - Value to check
 * @returns True if value is Reference object
 */
function isRef(ref: any): ref is Reference;

/**
 * Checks if value is a template expression
 * @param expression - Value to check  
 * @returns True if value is Template object
 */
function isExpression(expression: any): expression is Template;

Usage Examples:

const ref = Joi.ref('field');
const template = Joi.expression('Hello {#name}');
const string = 'regular string';

console.log(Joi.isRef(ref));        // true
console.log(Joi.isRef(template));   // false
console.log(Joi.isRef(string));     // false

console.log(Joi.isExpression(template)); // true
console.log(Joi.isExpression(ref));      // false
console.log(Joi.isExpression(string));   // false

Advanced Reference Patterns

Conditional Validation with References

const conditionalSchema = Joi.object({
    type: Joi.string().valid('user', 'admin'),
    permissions: Joi.array()
        .when('type', {
            is: 'admin',
            then: Joi.array().min(1),
            otherwise: Joi.array().max(0)
        })
});

Complex Object Relationships

const relationshipSchema = Joi.object({
    startDate: Joi.date(),
    endDate: Joi.date().greater(Joi.ref('startDate')),
    duration: Joi.number().when('startDate', {
        is: Joi.exist(),
        then: Joi.number().min(1),
        otherwise: Joi.forbidden()
    })
});

Dynamic Array Validation

const dynamicArraySchema = Joi.object({
    maxItems: Joi.number().integer().min(1),
    items: Joi.array().max(Joi.ref('maxItems')),
    selectedItems: Joi.array()
        .items(Joi.string().valid(Joi.in('items')))
        .unique()
});

Template-Based Error Messages

const customErrorSchema = Joi.object({
    username: Joi.string()
        .min(3)
        .max(20)
        .messages({
            'string.min': Joi.expression('Username {#label} must be at least {#limit} characters'),
            'string.max': Joi.expression('Username {#label} cannot exceed {#limit} characters')
        }),
    
    email: Joi.string()
        .email()
        .message(Joi.expression('Please provide a valid email address for {#label}'))
});

Context-Aware Validation

Global Context References

const globalContextSchema = Joi.object({
    userLevel: Joi.string().valid(Joi.ref('/user.level')),
    maxUpload: Joi.number().max(Joi.ref('/limits.upload'))
});

// Validation with global context
const result = globalContextSchema.validate(data, {
    context: {
        '/': {
            user: { level: 'premium' },
            limits: { upload: 1000000 }
        }
    }
});

Local Context References

const localContextSchema = Joi.object({
    priority: Joi.string().valid(Joi.ref('#priorities')),
    category: Joi.string().valid(Joi.ref('#categories'))
});

// Local context validation
const localResult = localContextSchema.validate(data, {
    context: {
        priorities: ['low', 'medium', 'high'],
        categories: ['bug', 'feature', 'enhancement']
    }
});

Template Functions

Built-in Template Functions

// String manipulation functions
const stringTemplate = Joi.expression('{#name|lowercase|trim}');

// Array functions  
const arrayTemplate = Joi.expression('Found {#items|length} items');

// Date functions
const dateTemplate = Joi.expression('Created on {#createdAt|date("YYYY-MM-DD")}');

// Custom functions
const customTemplate = Joi.expression('{#value|multiply(2)|format}', {
    functions: {
        multiply: (value, factor) => value * factor,
        format: (value) => `$${value.toFixed(2)}`
    }
});

docs

extensions-customization.md

index.md

references-expressions.md

schema-types.md

utility-functions.md

validation-methods.md

tile.json