A schema validation package that supports direct validation of MongoDB update modifier objects.
—
Validation context management for collecting validation errors, checking validity, and providing detailed error information without throwing exceptions.
The ValidationContext class provides a way to collect validation errors instead of throwing exceptions immediately.
/**
* Validation context for collecting and managing validation errors
*/
class ValidationContext {
/** Optional context name for identification */
name?: string;
/**
* Validates an object and returns success status
* @param obj - Object to validate
* @param options - Validation options
* @returns true if valid, false if validation errors occurred
*/
validate(obj: ObjectToValidate, options?: ValidationOptions): boolean;
/**
* Checks if the context currently has no validation errors
* @returns true if no errors, false if errors exist
*/
isValid(): boolean;
/**
* Gets all current validation errors
* @returns Array of ValidationError objects
*/
validationErrors(): ValidationError[];
/**
* Sets the validation errors, replacing any existing errors
* @param errors - Array of ValidationError objects to set
*/
setValidationErrors(errors: ValidationError[]): void;
/**
* Adds validation errors to the existing errors
* @param errors - Array of ValidationError objects to add
*/
addValidationErrors(errors: ValidationError[]): void;
/**
* Clears all validation errors from the context
*/
reset(): void;
/**
* Gets the first validation error for a specific key
* @param key - Field key to get error for
* @param genericKey - Generic version of key for array items
* @returns ValidationError object or undefined if no error
*/
getErrorForKey(key: string, genericKey?: string): ValidationError | undefined;
/**
* Checks if a specific key has validation errors
* @param key - Field key to check
* @param genericKey - Generic version of key for array items
* @returns true if key has errors, false otherwise
*/
keyIsInvalid(key: string, genericKey?: string): boolean;
/**
* Gets formatted error message for a specific key
* @param key - Field key to get message for
* @param genericKey - Generic version of key for array items
* @returns Error message string or empty string if no error
*/
keyErrorMessage(key: string, genericKey?: string): string;
/**
* Cleans a document using the context's schema
* @param doc - Document to clean
* @param options - Cleaning options
* @returns Cleaned document
*/
clean(doc: Record<string | number | symbol, unknown>, options?: CleanOptions): Record<string | number | symbol, unknown>;
}
interface ValidationOptions {
extendedCustomContext?: Record<string | number | symbol, unknown>;
ignore?: string[];
keys?: string[];
modifier?: boolean;
mongoObject?: any;
upsert?: boolean;
}
type ObjectToValidate = Record<string | number | symbol, unknown>;Usage Examples:
import SimpleSchema from "simpl-schema";
const userSchema = new SimpleSchema({
name: {
type: String,
min: 2,
max: 50
},
email: {
type: String,
regEx: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
},
age: {
type: Number,
min: 18,
max: 120
}
});
// Create a validation context
const context = userSchema.newContext();
// Validate invalid data
const userData = {
name: "A", // Too short
email: "invalid-email", // Invalid format
age: 15 // Too young
};
const isValid = context.validate(userData);
console.log(isValid); // false
// Get all errors
const errors = context.validationErrors();
console.log(errors);
// [
// { name: 'name', type: 'minString', value: 'A' },
// { name: 'email', type: 'regEx', value: 'invalid-email' },
// { name: 'age', type: 'minNumber', value: 15 }
// ]
// Check validity
console.log(context.isValid()); // false
// Get specific error
const nameError = context.getErrorForKey('name');
console.log(nameError); // { name: 'name', type: 'minString', value: 'A' }
// Check if specific key is invalid
console.log(context.keyIsInvalid('email')); // true
console.log(context.keyIsInvalid('nonexistent')); // false
// Get error message for key
console.log(context.keyErrorMessage('age')); // "Age must be at least 18"Methods to create and manage validation contexts.
/**
* Creates a new validation context for the schema
* @returns New ValidationContext instance
*/
newContext(): ValidationContext;
/**
* Gets or creates a named validation context that persists
* @param name - Context name for reuse and identification
* @returns Named ValidationContext instance
*/
namedContext(name?: string): ValidationContext;Usage Examples:
const userSchema = new SimpleSchema({
name: String,
email: String
});
// Create new context each time
const context1 = userSchema.newContext();
const context2 = userSchema.newContext();
console.log(context1 === context2); // false - different instances
// Use named contexts for persistence
const formContext = userSchema.namedContext('userForm');
formContext.validate({ name: 'John' }); // Invalid - missing email
// Later, get the same named context
const sameContext = userSchema.namedContext('userForm');
console.log(formContext === sameContext); // true - same instance
console.log(sameContext.validationErrors()); // Still has errors from before
// Different named context
const adminContext = userSchema.namedContext('adminForm');
console.log(adminContext.validationErrors()); // Empty - different contextMethods for managing validation errors within a context.
/**
* Manually set validation errors, replacing existing ones
* @param errors - Array of ValidationError objects
*/
setValidationErrors(errors: ValidationError[]): void;
/**
* Add additional validation errors to existing ones
* @param errors - Array of ValidationError objects to add
*/
addValidationErrors(errors: ValidationError[]): void;
/**
* Clear all validation errors from the context
*/
reset(): void;Usage Examples:
const context = userSchema.newContext();
// Manually set errors
context.setValidationErrors([
{ name: 'email', type: 'required', value: undefined },
{ name: 'age', type: 'minNumber', value: 15 }
]);
console.log(context.validationErrors().length); // 2
// Add more errors
context.addValidationErrors([
{ name: 'name', type: 'minString', value: 'A' }
]);
console.log(context.validationErrors().length); // 3
// Clear all errors
context.reset();
console.log(context.validationErrors().length); // 0
console.log(context.isValid()); // trueMethods for checking errors on specific fields.
/**
* Get the first error for a specific field key
* @param key - Field key to check
* @param genericKey - Generic key for array items (e.g., 'items.$')
* @returns ValidationError or undefined
*/
getErrorForKey(key: string, genericKey?: string): ValidationError | undefined;
/**
* Check if a specific field key is invalid
* @param key - Field key to check
* @param genericKey - Generic key for array items
* @returns true if field has errors
*/
keyIsInvalid(key: string, genericKey?: string): boolean;
/**
* Get formatted error message for a specific field key
* @param key - Field key to get message for
* @param genericKey - Generic key for array items
* @returns Error message string
*/
keyErrorMessage(key: string, genericKey?: string): string;Usage Examples:
const schema = new SimpleSchema({
name: String,
tags: [String],
'tags.$': {
type: String,
min: 2
}
});
const context = schema.newContext();
// Validate data with errors
context.validate({
name: '', // Required but empty
tags: ['ok', 'x'] // Second tag too short
});
// Check specific field errors
console.log(context.keyIsInvalid('name')); // true
console.log(context.keyIsInvalid('tags')); // false - array itself is valid
console.log(context.keyIsInvalid('tags.1')); // true - specific array item invalid
// Get specific errors
const nameError = context.getErrorForKey('name');
console.log(nameError?.type); // 'required'
const tagError = context.getErrorForKey('tags.1', 'tags.$');
console.log(tagError?.type); // 'minString'
// Get error messages
console.log(context.keyErrorMessage('name')); // "Name is required"
console.log(context.keyErrorMessage('tags.1')); // "Tags $ must be at least 2 characters"Use validation context for cleaning operations.
/**
* Clean a document using the context's schema
* @param doc - Document to clean
* @param options - Cleaning options
* @returns Cleaned document
*/
clean(doc: Record<string | number | symbol, unknown>, options?: CleanOptions): Record<string | number | symbol, unknown>;Usage Examples:
const schema = new SimpleSchema({
name: {
type: String,
trim: true
},
age: Number
});
const context = schema.newContext();
const dirtyData = {
name: ' John Doe ',
age: '25',
extra: 'field'
};
// Clean using context
const cleaned = context.clean(dirtyData, {
autoConvert: true,
trimStrings: true,
filter: true
});
console.log(cleaned);
// { name: 'John Doe', age: 25 }
// Validate the cleaned data
const isValid = context.validate(cleaned);
console.log(isValid); // trueValidate MongoDB update modifiers using validation contexts.
// ValidationContext works with modifier validation
context.validate(modifierDoc, { modifier: true });Usage Examples:
const schema = new SimpleSchema({
'profile.name': String,
'profile.age': Number,
tags: [String]
});
const context = schema.newContext();
// Validate $set modifier
const isValidSet = context.validate({
$set: {
'profile.name': 'John Doe',
'profile.age': 30
}
}, { modifier: true });
console.log(isValidSet); // true
// Validate invalid $push modifier
const isValidPush = context.validate({
$push: {
tags: null // Invalid - can't push null
}
}, { modifier: true });
console.log(isValidPush); // false
console.log(context.validationErrors());Common patterns for using validation contexts with forms.
Usage Examples:
// Form validation helper
class FormValidator {
constructor(schema, formName) {
this.schema = schema;
this.context = schema.namedContext(formName);
}
validate(formData) {
// Clean and validate
const cleaned = this.context.clean(formData, {
autoConvert: true,
trimStrings: true,
filter: true
});
const isValid = this.context.validate(cleaned);
return {
isValid,
errors: this.context.validationErrors(),
cleanedData: cleaned
};
}
getFieldError(fieldName) {
return this.context.keyErrorMessage(fieldName);
}
isFieldInvalid(fieldName) {
return this.context.keyIsInvalid(fieldName);
}
reset() {
this.context.reset();
}
}
// Usage
const userSchema = new SimpleSchema({...});
const validator = new FormValidator(userSchema, 'userRegistration');
const result = validator.validate(formData);
if (!result.isValid) {
console.log('Form errors:', result.errors);
}interface ValidationError {
/** Field name that failed validation */
name: string;
/** Type of validation error */
type: string;
/** Value that failed validation */
value: any;
/** Localized error message (optional) */
message?: string;
/** Additional error properties */
[prop: string]: any;
}Install with Tessl CLI
npx tessl i tessl/npm-simpl-schema