Object schema validation library for JavaScript with comprehensive validation capabilities
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core validation functions for executing validation with comprehensive error handling and configuration options.
Validates a value against a schema and throws a ValidationError if validation fails.
/**
* Validates value against schema, throws ValidationError on failure
* @param value - Value to validate
* @param schema - Schema to validate against
* @param message - Optional custom error message or Error object
* @param options - Optional validation options
* @returns Validated and potentially transformed value
* @throws ValidationError if validation fails
*/
function assert(
value: any,
schema: SchemaLike,
message?: string | Error,
options?: ValidationOptions
): any;Usage Examples:
const Joi = require('joi');
const schema = Joi.string().min(3);
try {
// Successful validation returns the value
const result = Joi.assert('hello', schema);
console.log(result); // 'hello'
// Failed validation throws error
Joi.assert('hi', schema); // Throws ValidationError
} catch (error) {
console.log(error.message); // "value" length must be at least 3 characters long
}
// With custom message
try {
Joi.assert('hi', schema, 'Username too short');
} catch (error) {
console.log(error.message); // Username too short "value" length must be at least 3 characters long
}
// With Error object
try {
Joi.assert('hi', schema, new Error('Custom validation failed'));
} catch (error) {
console.log(error.message); // Custom validation failed
}Validates a value against a schema and returns the validated value or throws an error.
/**
* Validates value against schema, returns value or throws error
* @param value - Value to validate
* @param schema - Schema to validate against
* @param message - Optional custom error message or Error object
* @param options - Optional validation options
* @returns Validated and potentially transformed value
* @throws ValidationError if validation fails
*/
function attempt(
value: any,
schema: SchemaLike,
message?: string | Error,
options?: ValidationOptions
): any;Usage Examples:
const schema = Joi.object({
name: Joi.string().required(),
age: Joi.number().integer().min(0)
});
try {
const user = Joi.attempt({
name: 'John',
age: '25' // String will be converted to number
}, schema);
console.log(user); // { name: 'John', age: 25 }
console.log(typeof user.age); // 'number'
} catch (error) {
console.log('Validation failed:', error.message);
}Converts a literal schema description into a joi schema object.
/**
* Converts literal schema description to joi schema object
* @param schema - Schema-like object or joi schema
* @param options - Optional compilation options
* @returns Compiled joi schema
*/
function compile(schema: SchemaLike, options?: CompileOptions): Schema;
interface CompileOptions {
legacy?: boolean;
}Usage Examples:
// Compile from literal object
const literalSchema = {
name: Joi.string().required(),
age: Joi.number()
};
const compiledSchema = Joi.compile(literalSchema);
// Use the compiled schema
const { error, value } = compiledSchema.validate({
name: 'Alice',
age: 30
});
// Compile with options
const legacySchema = Joi.compile(literalSchema, { legacy: true });Validates preference objects to ensure they contain valid configuration options.
/**
* Validates preference objects for correct configuration
* @param prefs - Preferences object to validate
* @throws Error if preferences are invalid
*/
function checkPreferences(prefs: ValidationOptions): void;Usage Examples:
// Valid preferences
Joi.checkPreferences({
abortEarly: false,
allowUnknown: true,
convert: false
});
// Invalid preferences will throw
try {
Joi.checkPreferences({
invalidOption: true,
convert: 'maybe' // Should be boolean
});
} catch (error) {
console.log('Invalid preferences:', error.message);
}Every schema instance provides validation methods for executing validation.
interface BaseSchema<T = any> {
/**
* Synchronous validation returning result object
* @param value - Value to validate
* @param options - Optional validation options
* @returns ValidationResult with error and value properties
*/
validate(value: any, options?: ValidationOptions): ValidationResult<T>;
/**
* Asynchronous validation returning Promise
* @param value - Value to validate
* @param options - Optional validation options
* @returns Promise resolving to validated value or rejecting with ValidationError
*/
validateAsync(value: any, options?: ValidationOptions): Promise<T>;
/**
* Validation that throws on error, returns value on success
* @param value - Value to validate
* @param options - Optional validation options
* @returns Validated value
* @throws ValidationError if validation fails
*/
attempt(value: any, options?: ValidationOptions): T;
/**
* Validation that throws on error with detailed annotation
* @param value - Value to validate
* @param options - Optional validation options
* @returns Validated value
* @throws ValidationError if validation fails
*/
assert(value: any, options?: ValidationOptions): T;
}
interface ValidationResult<T = any> {
error?: ValidationError;
value: T;
warning?: ValidationError;
}Usage Examples:
const schema = Joi.object({
username: Joi.string().min(3).required(),
email: Joi.string().email()
});
const data = { username: 'jo', email: 'invalid-email' };
// Synchronous validation
const result = schema.validate(data);
if (result.error) {
console.log('Validation errors:', result.error.details);
} else {
console.log('Valid data:', result.value);
}
// Asynchronous validation
try {
const validData = await schema.validateAsync(data);
console.log('Valid data:', validData);
} catch (error) {
console.log('Validation failed:', error.details);
}
// Using attempt method
try {
const validData = schema.attempt(data);
console.log('Valid data:', validData);
} catch (error) {
console.log('Validation failed:', error.message);
}
// Using assert method
try {
const validData = schema.assert(data);
console.log('Valid data:', validData);
} catch (error) {
console.log('Detailed error:', error.annotate());
}interface ValidationOptions {
// Validation behavior
abortEarly?: boolean; // Stop on first error (default: true)
allowUnknown?: boolean; // Allow unknown object keys (default: false)
cache?: boolean; // Enable validation caching (default: true)
convert?: boolean; // Enable type conversion (default: true)
debug?: boolean; // Enable debug mode (default: false)
externals?: boolean; // Process external validation (default: true)
noDefaults?: boolean; // Disable default value assignment (default: false)
nonEnumerables?: boolean; // Include non-enumerable properties (default: false)
presence?: PresenceMode; // Default presence requirement
skipFunctions?: boolean; // Skip function properties (default: false)
warnings?: boolean; // Enable warning collection (default: false)
// Unknown value handling
stripUnknown?: boolean | {
arrays?: boolean; // Strip unknown array items
objects?: boolean; // Strip unknown object keys
};
// Context and messages
context?: any; // Validation context object
messages?: LanguageMessages; // Custom error messages
// Date handling
dateFormat?: 'date' | 'iso' | 'string' | 'time' | 'utc';
// Error formatting
errors?: ErrorFormattingOptions;
}
interface ErrorFormattingOptions {
escapeHtml?: boolean; // Escape HTML in error messages
label?: 'path' | 'key' | false; // Label format in error messages
language?: string; // Language for error messages
render?: boolean; // Render error templates (default: true)
stack?: boolean; // Include stack traces (default: false)
wrap?: {
label?: string | false; // Characters around labels
array?: string | false; // Characters around arrays
string?: string | false; // Characters around strings
};
}
type PresenceMode = 'optional' | 'required' | 'forbidden';
type LanguageMessages = Record<string, string | Record<string, string>>;Usage Examples:
const schema = Joi.object({
name: Joi.string(),
age: Joi.number()
});
// Custom validation options
const options = {
abortEarly: false, // Collect all errors
allowUnknown: true, // Allow extra properties
convert: false, // Disable type conversion
stripUnknown: {
objects: true // Remove unknown object keys
},
messages: {
'string.base': 'Custom string error message'
}
};
const result = schema.validate(data, options);
// Context-aware validation
const contextOptions = {
context: {
userId: 123,
role: 'admin'
}
};
const contextResult = schema.validate(data, contextOptions);interface ValidationError extends Error {
name: 'ValidationError';
isJoi: true;
details: ValidationErrorItem[];
_original: any;
/**
* Returns formatted error message with annotations
* @returns Annotated error string
*/
annotate(): string;
}
interface ValidationErrorItem {
message: string; // Error message
path: (string | number)[]; // Path to the error location
type: string; // Error type identifier
context?: { // Error context
key?: string; // Field key
label?: string; // Field label
value?: any; // Invalid value
[key: string]: any; // Additional context
};
}Usage Examples:
const schema = Joi.object({
nested: Joi.object({
value: Joi.string().required()
})
});
const { error } = schema.validate({ nested: {} });
if (error) {
console.log('Error details:', error.details);
// [{
// message: '"nested.value" is required',
// path: ['nested', 'value'],
// type: 'any.required',
// context: { key: 'value', label: 'nested.value' }
// }]
console.log('Annotated error:', error.annotate());
console.log('Original value:', error._original);
console.log('Is joi error:', error.isJoi); // true
}