CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-simpl-schema

A schema validation package that supports direct validation of MongoDB update modifier objects.

Pending
Overview
Eval results
Files

validation.mddocs/

Validation

Comprehensive validation system supporting object validation, MongoDB modifiers, custom validators, and detailed error reporting.

Capabilities

Object Validation

Primary validation method that throws errors on validation failure.

/**
 * Validates an object against the schema, throwing an error if validation fails
 * @param obj - Object to validate
 * @param options - Validation options
 * @throws ValidationError if validation fails
 */
validate(obj: any, options?: ValidationOptions): void;

interface ValidationOptions {
  /** Extended custom context for validation functions */
  extendedCustomContext?: Record<string | number | symbol, unknown>;
  /** Array of field keys to ignore during validation */
  ignore?: string[];
  /** Array of field keys to validate (validates only these keys) */
  keys?: string[];
  /** Whether to validate as MongoDB modifier document */
  modifier?: boolean;
  /** MongoObject instance for modifier validation */
  mongoObject?: any;
  /** Whether this is an upsert operation */
  upsert?: boolean;
}

Usage Examples:

import SimpleSchema from "simpl-schema";

const userSchema = new SimpleSchema({
  name: String,
  email: String,
  age: Number
});

// Basic validation - throws on error
try {
  userSchema.validate({ name: "John", email: "john@example.com", age: 25 });
  console.log("Valid!");
} catch (error) {
  console.log("Validation failed:", error.message);
}

// Validate specific keys only
userSchema.validate(
  { name: "John", age: 25 }, 
  { keys: ['name', 'age'] }
);

// Validate MongoDB modifier document
userSchema.validate(
  { $set: { name: "John Doe" } },
  { modifier: true }
);

Static Validation

Class-level validation method for one-off validations without creating schema instances.

/**
 * Static validation method for validating against schema definitions
 * @param obj - Object to validate
 * @param schema - Schema instance or definition to validate against
 * @param options - Validation options
 * @throws ValidationError if validation fails
 */
static validate(obj: any, schema: SimpleSchema | SchemaDefinition, options?: ValidationOptions): void;

Usage Examples:

// Validate against schema definition directly
SimpleSchema.validate(
  { name: "John", age: 25 },
  { name: String, age: Number }
);

// Validate against existing schema
const userSchema = new SimpleSchema({ name: String, age: Number });
SimpleSchema.validate({ name: "John", age: 25 }, userSchema);

Async Validation

Async validation method that returns validation errors as a promise instead of throwing.

/**
 * Validates an object and returns validation errors as a promise
 * @param obj - Object to validate
 * @param options - Validation options
 * @returns Promise that resolves to array of validation errors
 */
async validateAndReturnErrorsPromise(obj: any, options: ValidationOptions): Promise<ValidationError[]>;

Usage Examples:

const userSchema = new SimpleSchema({
  name: { type: String, min: 2 },
  email: { type: String, regEx: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ },
  age: { type: Number, min: 0 }
});

// Async validation that returns errors instead of throwing
const errors = await userSchema.validateAndReturnErrorsPromise({
  name: "J",           // Too short
  email: "invalid",    // Invalid format
  age: -5             // Below minimum
});

console.log(errors);
// [
//   { name: 'name', type: 'minString', value: 'J', message: 'Name must be at least 2 characters' },
//   { name: 'email', type: 'regEx', value: 'invalid', message: 'Email failed regular expression validation' },
//   { name: 'age', type: 'minNumber', value: -5, message: 'Age must be at least 0' }
// ]

// Handle validation in async context
try {
  const validationErrors = await userSchema.validateAndReturnErrorsPromise(userData);
  if (validationErrors.length > 0) {
    // Handle validation errors
    validationErrors.forEach(error => {
      console.log(`Field ${error.name}: ${error.message}`);
    });
  } else {
    console.log('Validation passed!');
  }
} catch (error) {
  console.log('Validation system error:', error);
}

Validator Functions

Create reusable validator functions for repeated validation scenarios.

/**
 * Returns a validator function that can be called repeatedly
 * @param options - Validation options with additional configuration
 * @returns Function that validates objects and returns boolean or throws
 */
validator(options?: ValidationOptions & {
  clean?: boolean;
  returnErrorsPromise?: boolean;
}): Function;

/**
 * Returns a form-specific validator function that returns errors as a promise
 * @param options - Form validation options
 * @returns Function that validates and returns promise with validation errors
 */
getFormValidator(options?: ValidationOptions): (obj: Record<string, any>) => Promise<ValidationError[]>;

Usage Examples:

const userSchema = new SimpleSchema({
  name: String,
  email: String
});

// Create validator that throws on error
const validateUser = userSchema.validator();
validateUser({ name: "John", email: "john@example.com" });

// Create validator that cleans before validating
const cleanAndValidate = userSchema.validator({ clean: true });

// Create validator that returns promise with errors
const asyncValidator = userSchema.validator({ returnErrorsPromise: true });
asyncValidator(userData).then(errors => {
  if (errors.length > 0) {
    console.log("Validation errors:", errors);
  }
});

// Create form validator (always returns promise with errors)
const formValidator = userSchema.getFormValidator();
formValidator(formData).then(errors => {
  if (errors.length > 0) {
    // Display form errors to user
    errors.forEach(error => {
      displayFieldError(error.name, error.message);
    });
  } else {
    // Submit form
    submitForm(formData);
  }
});

Validation Contexts

Create validation contexts for collecting errors without throwing exceptions.

/**
 * Creates a new validation context for this schema
 * @returns New ValidationContext instance
 */
newContext(): ValidationContext;

/**
 * Gets or creates a named validation context
 * @param name - Context name for reuse
 * @returns Named ValidationContext instance
 */
namedContext(name?: string): ValidationContext;

Usage Examples:

const userSchema = new SimpleSchema({
  name: String,
  email: String
});

// Create new context
const context = userSchema.newContext();
const isValid = context.validate({ name: "John" }); // false
if (!isValid) {
  console.log(context.validationErrors()); // Array of errors
}

// Use named context for persistence
const formContext = userSchema.namedContext('userForm');
formContext.validate(formData);
// Later, reuse the same context
const sameContext = userSchema.namedContext('userForm');
console.log(sameContext.validationErrors());

Custom Validators

Add custom validation logic at the schema or field level.

/**
 * Adds a custom validator function to this schema instance
 * @param func - Validator function to add
 */
addValidator(func: ValidatorFunction): void;

/**
 * Adds a document-level validator function to this schema instance
 * @param func - Document validator function to add
 */
addDocValidator(func: DocValidatorFunction): void;

/**
 * Adds a custom validator function globally to all schema instances
 * @param func - Validator function to add globally
 */
static addValidator(func: ValidatorFunction): void;

/**
 * Adds a document-level validator function globally to all schema instances
 * @param func - Document validator function to add globally
 */
static addDocValidator(func: DocValidatorFunction): void;

// Validator function types
type ValidatorFunction = (this: ValidatorContext) => void | undefined | boolean | string | ValidationErrorResult;
type DocValidatorFunction = (this: DocValidatorContext, obj: Record<string, unknown>) => ValidationError[];

interface ValidatorContext {
  key: string;
  keyPath: string;
  value: any;
  definition: StandardSchemaKeyDefinitionWithSimpleTypes;
  isSet: boolean;
  operator: string | null;
  validationContext: ValidationContext;
  field(key: string): FieldInfo<any>;
  siblingField(key: string): FieldInfo<any>;
  addValidationErrors(errors: ValidationError[]): void;
}

Usage Examples:

// Field-level custom validator
const userSchema = new SimpleSchema({
  email: {
    type: String,
    custom() {
      if (!this.value.includes('@')) {
        return 'emailInvalid';
      }
    }
  },
  password: {
    type: String,
    min: 8,
    custom() {
      if (!/[A-Z]/.test(this.value)) {
        return 'passwordNeedsUppercase';
      }
    }
  }
});

// Schema-level custom validator
userSchema.addValidator(function() {
  if (this.key === 'confirmPassword') {
    const password = this.field('password').value;
    if (password !== this.value) {
      return 'passwordMismatch';
    }
  }
});

// Document-level validator
userSchema.addDocValidator(function(obj) {
  const errors = [];
  if (obj.age < 18 && obj.hasAccount) {
    errors.push({
      name: 'hasAccount',
      type: 'minorWithAccount',
      value: obj.hasAccount
    });
  }
  return errors;
});

// Global validator affecting all schemas
SimpleSchema.addValidator(function() {
  if (this.key.endsWith('Email') && this.isSet) {
    if (!this.value.includes('@')) {
      return 'mustBeEmail';
    }
  }
});

MongoDB Modifier Validation

Validate MongoDB update modifier documents like $set, $unset, $push, etc.

// Enable modifier validation in options
interface ValidationOptions {
  /** Whether to validate as MongoDB modifier document */
  modifier?: boolean;
  /** MongoObject instance for advanced modifier validation */
  mongoObject?: any;
  /** Whether this is an upsert operation */
  upsert?: boolean;
}

Usage Examples:

const userSchema = new SimpleSchema({
  'profile.name': String,
  'profile.age': Number,
  tags: [String],
  lastLogin: Date
});

// Validate $set modifier
userSchema.validate({
  $set: {
    'profile.name': 'John Doe',
    'profile.age': 30
  }
}, { modifier: true });

// Validate $push modifier
userSchema.validate({
  $push: {
    tags: 'javascript'
  }
}, { modifier: true });

// Validate $unset modifier
userSchema.validate({
  $unset: {
    'profile.age': ""
  }
}, { modifier: true });

// Complex modifier with multiple operations
userSchema.validate({
  $set: { 'profile.name': 'Jane Doe' },
  $push: { tags: 'react' },
  $currentDate: { lastLogin: true }
}, { modifier: true });

Async Validation

Handle validation operations that return promises for async validation scenarios.

/**
 * Validates and returns errors as a promise
 * @param obj - Object to validate
 * @param options - Validation options
 * @returns Promise resolving to array of ValidationError objects
 */
validateAndReturnErrorsPromise(obj: any, options: ValidationOptions): Promise<ValidationError[]>;

Usage Examples:

const userSchema = new SimpleSchema({
  username: {
    type: String,
    custom() {
      // Simulate async validation (e.g., checking uniqueness)
      return new Promise((resolve) => {
        setTimeout(() => {
          if (this.value === 'admin') {
            resolve('usernameNotAllowed');
          } else {
            resolve();
          }
        }, 100);
      });
    }
  }
});

// Use async validation
userSchema.validateAndReturnErrorsPromise({ username: 'admin' })
  .then(errors => {
    if (errors.length > 0) {
      console.log('Validation errors:', errors);
    } else {
      console.log('Valid!');
    }
  });

Types

interface ValidationError {
  /** Localized error message */
  message?: string;
  /** Field name that failed validation */
  name: string;
  /** Type of validation error */
  type: string;
  /** Value that failed validation */
  value: any;
  /** Additional error properties */
  [prop: string]: any;
}

interface ValidationErrorResult {
  type: string;
  value?: any;
  message?: string;
}

interface FieldInfo<ValueType> {
  value: ValueType;
  isSet: boolean;
  operator: string | null;
}

Install with Tessl CLI

npx tessl i tessl/npm-simpl-schema

docs

data-cleaning.md

index.md

schema-definition.md

schema-introspection.md

utility-functions.md

validation-context.md

validation.md

tile.json