1.0.1 โ€ข Published 6 months ago

bodhi-form-validations v1.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

Bodhi Form Validations

A powerful, zero-dependency form validation library for modern web applications. Built with TypeScript and designed for developers who need robust, flexible, and type-safe form validation.

npm version TypeScript License: MIT

๐Ÿš€ Quick Start

npm install bodhi-form-validations
import validate from 'bodhi-form-validations';

// Simple email validation
const emailResult = validate.isEmail('user@example.com');
// { isValid: true, message: 'Valid email' }

// Advanced password validation
const passwordResult = validate.isPassword('MyPass123!', {
  minLength: 8,
  requireUppercase: true,
  requireNumbers: true
});
// { isValid: true, message: 'Valid password', strength: 0.8 }

// Form validation
const formResult = validate.isObject({
  email: 'user@example.com',
  password: 'MyPass123!',
  age: 25
}, {
  requiredFields: ['email', 'password'],
  fieldValidators: {
    email: (value) => validate.isEmail(value),
    password: (value) => validate.isPassword(value, { minLength: 8 }),
    age: (value) => validate.isNumber(value, { min: 18 })
  }
});

โœจ Why Choose Bodhi Form Validations?

  • ๐ŸŽฏ Type-Safe: Full TypeScript support with comprehensive type definitions
  • ๐Ÿ”ง Flexible: Customize validation rules to match your exact requirements
  • ๐ŸŒ Framework Agnostic: Works seamlessly with React, Vue, Angular, or vanilla JS
  • ๐Ÿ“ฆ Zero Dependencies: Lightweight and efficient, no external dependencies
  • ๐Ÿ” Detailed Feedback: Rich validation results with messages and strength indicators
  • ๐ŸŒ International: Support for various formats across different locales
  • โšก Performance: Optimized for handling complex form validations
  • ๐Ÿ›ก๏ธ Security: Built-in rules for secure password validation

๐Ÿ“‹ Available Validations

// Email Validation
validate.isEmail('user@example.com', {
  allowSubdomains: true,    // Allow subdomain emails
  allowInternational: true  // Allow international characters
});

// Password Validation
validate.isPassword('MySecurePass123!', {
  minLength: 8,            // Minimum length requirement
  requireUppercase: true,  // Must contain uppercase letters
  requireNumbers: true,    // Must contain numbers
  requireSymbols: true     // Must contain special characters
});

// Phone Number Validation
validate.isPhone('+1-555-123-4567', {
  country: 'US',           // Country-specific format
  requireCountryCode: true // Must include country code
});

// Date Validation
validate.isDate('2025-01-25', {
  minDate: '2025-01-01',   // Minimum allowed date
  maxDate: '2025-12-31',   // Maximum allowed date
  allowFuture: true        // Allow future dates
});

// Number Validation
validate.isNumber('42.5', {
  min: 0,                  // Minimum value
  max: 100,                // Maximum value
  precision: 2             // Decimal places
});

๐ŸŽจ Framework Integration Examples

React Hook Example

import { useState } from 'react';
import validate from 'bodhi-form-validations';

function useFormValidation(initialValue = '') {
  const [value, setValue] = useState(initialValue);
  const [error, setError] = useState('');

  const validateField = (validator) => {
    const result = validator(value);
    setError(result.isValid ? '' : result.message);
    return result.isValid;
  };

  return { value, setValue, error, validateField };
}

// Usage in component
function LoginForm() {
  const email = useFormValidation('');
  
  const handleSubmit = (e) => {
    e.preventDefault();
    if (email.validateField(value => validate.isEmail(value))) {
      // Proceed with form submission
    }
  };

  return (
    <input
      value={email.value}
      onChange={e => email.setValue(e.target.value)}
      error={email.error}
    />
  );
}

Table of Contents

Features

  • ๐Ÿš€ Full TypeScript support with type definitions and interfaces
  • ๐Ÿ“ Comprehensive validation rules for common form fields
  • โš™๏ธ Highly customizable options for each validation type
  • ๐ŸŒ International support for phone numbers and postal codes
  • ๐Ÿ’ช Zero dependencies - lightweight and efficient
  • ๐Ÿ“ฑ Browser and Node.js compatible
  • ๐Ÿ”’ Strong password validation with strength indicators
  • ๐ŸŒ Multiple country formats support
  • ๐Ÿ”„ Async validation support
  • ๐Ÿ“‹ Detailed error messages in multiple languages
  • โšก Fast and efficient validation algorithms
  • ๐Ÿงช Well-tested with high coverage

Validation Types

Validation Types Overview Table

CategoryValidation TypeFunction NameDescriptionOptions
User InputUsernameisUsernameValidates usernamesminLength, maxLength, allowSpecialChars
EmailisEmailValidates email addressesallowInternational, strictDomain
PasswordisStrongPasswordValidates password strengthminLength, requireUppercase, requireNumbers, requireSpecialChars
PhoneisPhoneValidates phone numberscountry, requireCountryCode, allowSpaces
NumbersNumberisNumberValidates numeric valuesmin, max, allowDecimals, precision
IntegerisIntegerValidates whole numbersmin, max, allowNegative
FloatisFloatValidates decimal numbersmin, max, precision, allowScientific
ArraysArrayisArrayValidates arraysminLength, maxLength, unique, sortOrder
MatrixisMatrixValidates 2D arraysdimensions, allowJagged
ObjectsObjectisObjectValidates objectsrequiredFields, optionalFields, strict
SchemaisSchemaValidates against schemaschema, strict, additionalProps
DatesDateisDateValidates datesformat, min, max
DateRangeisDateRangeValidates date rangesminRange, maxRange, allowWeekends
AgeisAgeValidates ageminAge, maxAge, referenceDate
FilesFileisFileValidates filesmaxSize, allowedTypes, maxDimensions
ImageisImageValidates imagesmaxSize, allowedFormats, dimensions
DocumentisDocumentValidates documentsmaxSize, allowedTypes
AddressAddressisAddressValidates addressesrequireStreet, requireCity, requireZip
PostalCodeisPostalCodeValidates postal codescountry, format
FinancialCurrencyisCurrencyValidates currency amountscurrency, decimals, symbol
CreditCardisCreditCardValidates credit cardstype, validateCVV
ColorsColorisColorValidates color codesformat, allowAlpha
NetworkURLisURLValidates URLsprotocols, requireProtocol
IPisIPAddressValidates IP addressesversion, allowPrivate
TimeTimeisTimeValidates timeformat, allowSeconds
TimeZoneisTimeZoneValidates timezonesformat, allowUTC
DocumentsSSNisSSNValidates SSNsformat, allowMasked
PassportisPassportValidates passport numberscountry, format

Validation Types Diagram

graph TD
    A[Bodhi Form Validation] --> B[User Input]
    A --> C[Numbers]
    A --> D[Arrays]
    A --> E[Objects]
    A --> F[Dates]
    A --> G[Files]
    A --> H[Address]
    A --> I[Financial]
    A --> J[Colors]
    A --> K[Network]
    A --> L[Time]
    A --> M[Documents]

    B --> B1[Username]
    B --> B2[Email]
    B --> B3[Password]
    B --> B4[Phone]

    C --> C1[Number]
    C --> C2[Integer]
    C --> C3[Float]

    D --> D1[Array]
    D --> D2[Matrix]

    E --> E1[Object]
    E --> E2[Schema]

    F --> F1[Date]
    F --> F2[DateRange]
    F --> F3[Age]

    G --> G1[File]
    G --> G2[Image]
    G --> G3[Document]

    H --> H1[Address]
    H --> H2[PostalCode]

    I --> I1[Currency]
    I --> I2[CreditCard]

    J --> J1[Color]

    K --> K1[URL]
    K --> K2[IP]

    L --> L1[Time]
    L --> L2[TimeZone]

    M --> M1[SSN]
    M --> M2[Passport]

    classDef category fill:#f9f,stroke:#333,stroke-width:2px;
    classDef type fill:#bbf,stroke:#333,stroke-width:1px;
    
    class A,B,C,D,E,F,G,H,I,J,K,L,M category;
    class B1,B2,B3,B4,C1,C2,C3,D1,D2,E1,E2,F1,F2,F3,G1,G2,G3,H1,H2,I1,I2,J1,K1,K2,L1,L2,M1,M2 type;

Quick Reference Examples

// User Input Validations
const usernameValid = validate.isUsername('john_doe', { minLength: 3, maxLength: 20 });
const emailValid = validate.isEmail('user@example.com', { allowInternational: true });
const passwordValid = validate.isStrongPassword('P@ssw0rd123', { minLength: 8 });
const phoneValid = validate.isPhone('+1-555-123-4567', { country: 'US' });

// Number Validations
const numberValid = validate.isNumber('123.45', { min: 0, max: 1000 });
const integerValid = validate.isInteger('42', { allowNegative: false });
const floatValid = validate.isFloat('3.14159', { precision: 5 });

// Array Validations
const arrayValid = validate.isArray(['a', 'b', 'c'], { unique: true });
const matrixValid = validate.isMatrix([[1, 2], [3, 4]], { dimensions: [2, 2] });

// Date Validations
const dateValid = validate.isDate('2025-01-24', { format: 'YYYY-MM-DD' });
const ageValid = validate.isAge('1990-01-01', { minAge: 18 });

// File Validations
const fileValid = validate.isFile(fileObject, { maxSize: '10MB' });
const imageValid = validate.isImage(imageFile, { maxDimensions: [1920, 1080] });

// Address Validations
const addressValid = validate.isAddress({
    street: '123 Main St',
    city: 'San Francisco',
    zip: '94105'
});

// Financial Validations
const currencyValid = validate.isCurrency('$1,234.56', { currency: 'USD' });
const creditCardValid = validate.isCreditCard('4111111111111111', { type: 'visa' });

// Network Validations
const urlValid = validate.isURL('https://example.com', { requireProtocol: true });
const ipValid = validate.isIPAddress('192.168.1.1', { version: 'v4' });

Detailed Validation Examples

User Input Validation

Username Validation

import validate from 'bodhi-form-validations';

// Basic username validation
const basicUsername = validate.isUsername('john_doe');
console.log(basicUsername.isValid); // true

// Advanced username validation
const advancedUsername = validate.isUsername('john.doe@123', {
  minLength: 5,
  maxLength: 20,
  allowSpecialChars: true,
  allowedChars: 'a-zA-Z0-9._@',
  bannedUsernames: ['admin', 'root'],
  caseSensitive: false
});

if (!advancedUsername.isValid) {
  console.error(advancedUsername.message);
}

Email Validation

// Basic email validation
const basicEmail = validate.isEmail('user@example.com');

// Advanced email validation
const advancedEmail = validate.isEmail('user.name+tag@subdomain.example.co.uk', {
  allowInternational: true,
  strictDomain: true,
  allowPlusAddressing: true,
  bannedDomains: ['tempmail.com'],
  validateMX: true
});

// Custom domain validation
const workEmail = validate.isEmail('john@company.com', {
  allowedDomains: ['company.com', 'company.org'],
  errorMessage: 'Please use your company email'
});

Password Validation

// Basic password validation
const basicPassword = validate.isStrongPassword('MyP@ssw0rd');

// Advanced password strength validation
const advancedPassword = validate.isStrongPassword('MySecureP@ssw0rd123', {
  minLength: 12,
  maxLength: 64,
  requireUppercase: true,
  requireLowercase: true,
  requireNumbers: true,
  requireSpecialChars: true,
  minUniqueChars: 8,
  maxRepeatingChars: 2,
  bannedPasswords: ['Password123!', 'Admin123!'],
  customRegex: /^(?=.*[!@#$%^&*])/,
  errorMessages: {
    tooShort: 'Password must be at least 12 characters',
    noUppercase: 'Include at least one uppercase letter',
    noSpecialChar: 'Include at least one special character'
  }
});

// Password strength indicator
if (advancedPassword.isValid) {
  console.log(`Password strength: ${advancedPassword.strength}/4`);
  console.log(`Suggestions: ${advancedPassword.suggestions.join(', ')}`);
}

Phone Number Validation

// Basic phone validation
const basicPhone = validate.isPhone('555-123-4567');

// International phone validation
const usPhone = validate.isPhone('+1 (555) 123-4567', {
  country: 'US',
  requireCountryCode: true,
  allowSpaces: true,
  allowHyphens: true,
  allowParentheses: true
});

const ukPhone = validate.isPhone('+44 20 7123 4567', {
  country: 'UK',
  format: 'international'
});

const indianPhone = validate.isPhone('+91 98765-43210', {
  country: 'IN',
  mobileOnly: true
});

Number Validation

Basic Number Validation

// Integer validation
const integerCheck = validate.isNumber('42', {
  integer: true,
  min: 0,
  max: 100
});

// Decimal validation
const decimalCheck = validate.isNumber('3.14159', {
  allowDecimals: true,
  precision: 5,
  min: 0,
  max: 10
});

// Scientific notation
const scientificCheck = validate.isNumber('1.23e-4', {
  allowScientific: true,
  allowNegative: true
});

Currency and Financial Validation

// Basic currency validation
const basicCurrency = validate.isCurrency('$1,234.56');

// Advanced currency validation
const advancedCurrency = validate.isCurrency('โ‚ฌ1.234,56', {
  currency: 'EUR',
  locale: 'de-DE',
  allowNegative: false,
  requireSymbol: true,
  symbolPosition: 'prefix'
});

// Custom format
const customCurrency = validate.isCurrency('1,234.56 USD', {
  format: '0,0.00 CCC',
  decimals: 2,
  thousandsSeparator: ',',
  decimalSeparator: '.'
});

Date and Time Validation

Date Validation

// Basic date validation
const basicDate = validate.isDate('2025-01-24');

// Advanced date validation
const advancedDate = validate.isDate('24/01/2025', {
  format: 'DD/MM/YYYY',
  min: '2024-01-01',
  max: '2025-12-31',
  allowWeekends: false,
  allowHolidays: false
});

// Age validation
const ageCheck = validate.isAge('1990-01-01', {
  minAge: 18,
  maxAge: 100,
  referenceDate: '2025-01-24'
});

// Date range validation
const dateRange = validate.isDateRange({
  start: '2025-01-01',
  end: '2025-12-31'
}, {
  minRange: '1 month',
  maxRange: '1 year',
  allowWeekends: true
});

Array and Object Validation

Array Validation

// Basic array validation
const basicArray = validate.isArray(['a', 'b', 'c'], {
  minLength: 1,
  maxLength: 5
});

// Advanced array validation
const advancedArray = validate.isArray([1, 2, 3, 4, 5], {
  unique: true,
  sortOrder: 'ascending',
  type: 'number',
  itemValidator: (item) => item > 0 && item < 10
});

// Matrix validation
const matrixCheck = validate.isMatrix([
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
], {
  dimensions: [3, 3],
  allowJagged: false,
  itemValidator: (item) => Number.isInteger(item)
});

Object Validation

// Basic object validation
const basicObject = validate.isObject({
  name: 'John',
  age: 30
}, {
  requiredFields: ['name', 'age']
});

// Advanced object validation
const advancedObject = validate.isObject({
  username: 'john_doe',
  email: 'john@example.com',
  settings: {
    theme: 'dark',
    notifications: true
  }
}, {
  schema: {
    username: { type: 'string', required: true },
    email: { type: 'email', required: true },
    settings: {
      type: 'object',
      properties: {
        theme: { type: 'string', enum: ['light', 'dark'] },
        notifications: { type: 'boolean' }
      }
    }
  },
  strict: true,
  additionalProperties: false
});

File Validation

File Upload Validation

// Basic file validation
const basicFile = validate.isFile(fileObject, {
  maxSize: '10MB',
  allowedTypes: ['pdf', 'doc', 'docx']
});

// Image file validation
const imageFile = validate.isImage(imageObject, {
  maxSize: '5MB',
  allowedTypes: ['jpg', 'png', 'gif'],
  maxDimensions: [1920, 1080],
  minDimensions: [100, 100],
  aspectRatio: '16:9'
});

// Document validation
const documentFile = validate.isDocument(docObject, {
  maxSize: '20MB',
  allowedTypes: ['pdf', 'doc', 'docx', 'xls', 'xlsx'],
  allowPassword: false,
  validateContent: true
});

Network Validation

URL Validation

// Basic URL validation
const basicUrl = validate.isURL('https://example.com');

// Advanced URL validation
const advancedUrl = validate.isURL('https://api.example.com/data?id=123', {
  protocols: ['https'],
  requireProtocol: true,
  allowQueryParams: true,
  allowFragments: false,
  allowedDomains: ['example.com', 'api.example.com'],
  validateDNS: true
});

IP Address Validation

// IPv4 validation
const ipv4 = validate.isIPAddress('192.168.1.1', {
  version: 'v4',
  allowPrivate: true,
  allowLoopback: false
});

// IPv6 validation
const ipv6 = validate.isIPAddress('2001:0db8:85a3:0000:0000:8a2e:0370:7334', {
  version: 'v6',
  allowCompressed: true,
  allowIPv4Mapped: false
});

Complete Form Validation Example

interface UserForm {
  username: string;
  email: string;
  password: string;
  age: number;
  phone: string;
  address: {
    street: string;
    city: string;
    zip: string;
  };
  preferences: string[];
}

const validateUserForm = (form: UserForm) => {
  const validations = {
    username: validate.isUsername(form.username, {
      minLength: 3,
      maxLength: 20
    }),
    email: validate.isEmail(form.email),
    password: validate.isStrongPassword(form.password),
    age: validate.isNumber(form.age, {
      min: 18,
      max: 120,
      integer: true
    }),
    phone: validate.isPhone(form.phone, {
      country: 'US',
      requireCountryCode: true
    }),
    address: validate.isObject(form.address, {
      requiredFields: ['street', 'city', 'zip'],
      schema: {
        street: { type: 'string', minLength: 5 },
        city: { type: 'string' },
        zip: { type: 'string', pattern: '\\d{5}' }
      }
    }),
    preferences: validate.isArray(form.preferences, {
      minLength: 1,
      maxLength: 5,
      unique: true
    })
  };

  const errors: Record<string, string> = {};
  let isValid = true;

  Object.entries(validations).forEach(([field, result]) => {
    if (!result.isValid) {
      errors[field] = result.message;
      isValid = false;
    }
  });

  return {
    isValid,
    errors,
    validatedData: isValid ? form : null
  };
};

// Usage example
const formData: UserForm = {
  username: 'john_doe',
  email: 'john@example.com',
  password: 'SecureP@ss123',
  age: 25,
  phone: '+1-555-123-4567',
  address: {
    street: '123 Main St',
    city: 'San Francisco',
    zip: '94105'
  },
  preferences: ['dark_theme', 'notifications_on']
};

const validationResult = validateUserForm(formData);
if (validationResult.isValid) {
  console.log('Form is valid!', validationResult.validatedData);
} else {
  console.error('Form validation failed:', validationResult.errors);
}

Installation

Install using npm:

npm install bodhi-form-validations

Install using yarn:

yarn add bodhi-form-validations

Install using pnpm:

pnpm add bodhi-form-validations

Usage

TypeScript Usage

The library provides full TypeScript support with type definitions. Here's how to use it in a TypeScript project:

import validate from 'bodhi-form-validations';

// Basic usage
const emailResult = validate.isEmail('user@example.com');
console.log(emailResult.isValid); // true
console.log(emailResult.message); // "Valid email"

// With options
const passwordResult = validate.isStrongPassword('MyPassword123!', {
  minLength: 10,
  requireUppercase: true,
  requireNumbers: true,
  requireSpecialChars: true
});

// Using type definitions
interface UserForm {
  username: string;
  email: string;
  age: number;
  birthDate: Date;
}

const validateUserForm = (form: UserForm) => {
  const validations = {
    username: validate.isUsername(form.username, {
      minLength: 3,
      maxLength: 20,
      allowSpecialChars: false
    }),
    email: validate.isEmail(form.email),
    age: validate.isNumber(form.age, {
      min: 18,
      max: 120,
      integer: true
    }),
    birthDate: validate.isDateInRange(form.birthDate, {
      minAge: 18,
      maxAge: 120
    })
  };

  return Object.entries(validations).reduce((errors, [field, result]) => {
    if (!result.isValid) {
      errors[field] = result.message;
    }
    return errors;
  }, {} as Record<string, string>);
};

JavaScript Usage

In JavaScript projects, you can use the library with CommonJS or ES Modules:

// ES Modules
import validate from 'bodhi-form-validations';

// CommonJS
const validate = require('bodhi-form-validations');

// Basic form validation
const form = {
  username: 'johndoe',
  email: 'john@example.com',
  phone: '+1-555-123-4567',
  address: {
    street: '123 Main St',
    city: 'San Francisco',
    zip: '94105'
  }
};

const validateForm = (formData) => {
  const errors = {};
  
  // Username validation
  const usernameResult = validate.isUsername(formData.username);
  if (!usernameResult.isValid) {
    errors.username = usernameResult.message;
  }
  
  // Email validation
  const emailResult = validate.isEmail(formData.email);
  if (!emailResult.isValid) {
    errors.email = emailResult.message;
  }
  
  // Phone validation
  const phoneResult = validate.isPhone(formData.phone);
  if (!phoneResult.isValid) {
    errors.phone = phoneResult.message;
  }
  
  // Address validation
  const addressResult = validate.isAddress(formData.address, {
    requireStreet: true,
    requireCity: true,
    requireZip: true
  });
  if (!addressResult.isValid) {
    errors.address = addressResult.message;
  }
  
  return {
    isValid: Object.keys(errors).length === 0,
    errors
  };
};

// Usage
const validation = validateForm(form);
if (!validation.isValid) {
  console.error('Form validation failed:', validation.errors);
}

React Usage

Example of using the library in a React component:

import React, { useState } from 'react';
import validate from 'bodhi-form-validations';

interface FormData {
  username: string;
  email: string;
  password: string;
}

const RegistrationForm: React.FC = () => {
  const [formData, setFormData] = useState<FormData>({
    username: '',
    email: '',
    password: ''
  });
  const [errors, setErrors] = useState<Partial<Record<keyof FormData, string>>>({});

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
    
    // Real-time validation
    let validationResult;
    switch (name) {
      case 'username':
        validationResult = validate.isUsername(value);
        break;
      case 'email':
        validationResult = validate.isEmail(value);
        break;
      case 'password':
        validationResult = validate.isStrongPassword(value);
        break;
    }
    
    setErrors(prev => ({
      ...prev,
      [name]: validationResult.isValid ? '' : validationResult.message
    }));
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    // Final validation before submission
    const validations = {
      username: validate.isUsername(formData.username),
      email: validate.isEmail(formData.email),
      password: validate.isStrongPassword(formData.password)
    };

    const newErrors = Object.entries(validations).reduce((acc, [field, result]) => {
      if (!result.isValid) {
        acc[field] = result.message;
      }
      return acc;
    }, {});

    if (Object.keys(newErrors).length === 0) {
      // Form is valid, proceed with submission
      console.log('Form submitted:', formData);
    } else {
      setErrors(newErrors);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <input
          type="text"
          name="username"
          value={formData.username}
          onChange={handleChange}
          placeholder="Username"
        />
        {errors.username && <span className="error">{errors.username}</span>}
      </div>
      <div>
        <input
          type="email"
          name="email"
          value={formData.email}
          onChange={handleChange}
          placeholder="Email"
        />
        {errors.email && <span className="error">{errors.email}</span>}
      </div>
      <div>
        <input
          type="password"
          name="password"
          value={formData.password}
          onChange={handleChange}
          placeholder="Password"
        />
        {errors.password && <span className="error">{errors.password}</span>}
      </div>
      <button type="submit">Register</button>
    </form>
  );
};

export default RegistrationForm;

Vue.js Usage

Example of using the library in a Vue.js component:

<template>
  <form @submit.prevent="handleSubmit">
    <div>
      <input
        v-model="formData.username"
        @input="validateField('username')"
        placeholder="Username"
      />
      <span v-if="errors.username" class="error">{{ errors.username }}</span>
    </div>
    <div>
      <input
        v-model="formData.email"
        @input="validateField('email')"
        placeholder="Email"
      />
      <span v-if="errors.email" class="error">{{ errors.email }}</span>
    </div>
    <div>
      <input
        v-model="formData.password"
        type="password"
        @input="validateField('password')"
        placeholder="Password"
      />
      <span v-if="errors.password" class="error">{{ errors.password }}</span>
    </div>
    <button type="submit">Register</button>
  </form>
</template>

<script>
import validate from 'bodhi-form-validations';

export default {
  data() {
    return {
      formData: {
        username: '',
        email: '',
        password: ''
      },
      errors: {}
    };
  },
  methods: {
    validateField(fieldName) {
      let validationResult;
      
      switch (fieldName) {
        case 'username':
          validationResult = validate.isUsername(this.formData.username);
          break;
        case 'email':
          validationResult = validate.isEmail(this.formData.email);
          break;
        case 'password':
          validationResult = validate.isStrongPassword(this.formData.password);
          break;
      }
      
      this.$set(this.errors, fieldName, 
        validationResult.isValid ? '' : validationResult.message
      );
    },
    handleSubmit() {
      // Validate all fields
      Object.keys(this.formData).forEach(this.validateField);
      
      // Check if there are any errors
      if (!Object.values(this.errors).some(error => error)) {
        // Form is valid, proceed with submission
        console.log('Form submitted:', this.formData);
      }
    }
  }
};
</script>

Advanced Examples

Custom Password Validation Rules

const passwordResult = validate.isStrongPassword('MyPassword123!', {
  minLength: 10,
  maxLength: 50,
  requireUppercase: true,
  requireLowercase: true,
  requireNumbers: true,
  requireSpecialChars: true,
  allowSpaces: false,
  minStrength: 4
});

if (passwordResult.isValid) {
  console.log(`Password strength: ${passwordResult.strength}/4`);
} else {
  console.log(`Password error: ${passwordResult.message}`);
}

International Phone Number Validation

// US phone number
const usPhone = validate.isPhone('(555) 123-4567', {
  country: 'US',
  allowSpaces: true
});

// UK phone number with country code
const ukPhone = validate.isPhone('+44 20 7123 4567', {
  country: 'UK',
  requireCountryCode: true
});

// Indian phone number
const inPhone = validate.isPhone('+91 98765 43210', {
  country: 'IN',
  allowSpaces: true
});

URL Validation with Custom Rules

// HTTPS only URL
const secureUrl = validate.isURL('https://example.com', {
  requireProtocol: true,
  allowedProtocols: ['https:']
});

// URL without query parameters
const cleanUrl = validate.isURL('https://api.example.com/data', {
  allowQueryParams: false,
  allowFragments: false
});

API Reference

File Validation

validate.isFile(file: File, options?: {
  maxSize?: number;         // default: 5MB
  allowedTypes?: string[];  // e.g., ['image/jpeg', 'image/png']
  minWidth?: number;        // for images
  minHeight?: number;       // for images
  maxWidth?: number;        // for images
  maxHeight?: number;       // for images
  aspectRatio?: number;     // width/height
})

Address Validation

validate.isAddress(address: {
  street: string;
  city: string;
  state: string;
  zip: string;
  country: string;
}, options?: {
  requireStreet?: boolean;  // default: true
  requireCity?: boolean;    // default: true
  requireState?: boolean;   // default: true
  requireZip?: boolean;     // default: true
  requireCountry?: boolean; // default: true
  allowPOBox?: boolean;     // default: true
})

Money/Currency Validation

validate.isMoney(amount: string | number, options?: {
  currency?: string;        // default: 'USD'
  minAmount?: number;       // default: 0
  maxAmount?: number;       // default: Number.MAX_SAFE_INTEGER
  allowNegative?: boolean;  // default: false
  decimals?: number;        // default: 2
})

Color Validation

validate.isColor(color: string, options?: {
  format?: 'hex' | 'rgb' | 'rgba' | 'hsl' | 'any'; // default: 'any'
  allowAlpha?: boolean;     // default: true
})

IP Address Validation

validate.isIPAddress(ip: string, options?: {
  version?: 'v4' | 'v6' | 'any';  // default: 'any'
  allowPrivate?: boolean;         // default: true
  allowReserved?: boolean;        // default: false
})

Social Security Number (SSN) Validation

validate.isSSN(ssn: string, options?: {
  country?: 'US' | 'CA';           // default: 'US'
  format?: 'masked' | 'unmasked';  // default: 'masked'
})

Time Validation

validate.isTime(time: string, options?: {
  format?: '12h' | '24h';    // default: '24h'
  allowSeconds?: boolean;     // default: true
  minTime?: string;          // optional
  maxTime?: string;          // optional
})

Geographic Coordinates Validation

validate.isLatLng(coords: { 
  lat: number; 
  lng: number 
}, options?: {
  precision?: number;                // default: 6
  format?: 'decimal' | 'dms';        // default: 'decimal'
})

Advanced Examples

Custom Password Validation Rules

const passwordResult = validate.isStrongPassword('MyPassword123!', {
  minLength: 10,
  maxLength: 50,
  requireUppercase: true,
  requireLowercase: true,
  requireNumbers: true,
  requireSpecialChars: true,
  allowSpaces: false,
  minStrength: 4
});

if (passwordResult.isValid) {
  console.log(`Password strength: ${passwordResult.strength}/4`);
} else {
  console.log(`Password error: ${passwordResult.message}`);
}

International Phone Number Validation

// US phone number
const usPhone = validate.isPhone('(555) 123-4567', {
  country: 'US',
  allowSpaces: true
});

// UK phone number with country code
const ukPhone = validate.isPhone('+44 20 7123 4567', {
  country: 'UK',
  requireCountryCode: true
});

// Indian phone number
const inPhone = validate.isPhone('+91 98765 43210', {
  country: 'IN',
  allowSpaces: true
});

URL Validation with Custom Rules

// HTTPS only URL
const secureUrl = validate.isURL('https://example.com', {
  requireProtocol: true,
  allowedProtocols: ['https:']
});

// URL without query parameters
const cleanUrl = validate.isURL('https://api.example.com/data', {
  allowQueryParams: false,
  allowFragments: false
});

Error Handling

The library provides detailed error messages for each validation failure:

const validations = {
  weakPassword: validate.isStrongPassword('weak', {
    minLength: 8,
    requireSymbols: true
  }),
  invalidEmail: validate.isEmail('invalid@email'),
  invalidPhone: validate.isPhone('123', { country: 'US' })
};

// Handle errors
Object.entries(validations).forEach(([field, result]) => {
  if (!result.isValid) {
    console.log(`${field} error: ${result.message}`);
  }
});

TypeScript Support

The library includes comprehensive TypeScript definitions:

import validate, { 
  ValidationResult,
  PasswordOptions,
  EmailOptions,
  PhoneOptions
} from 'bodhi-form-validations';

// Type-safe options
const passwordOptions: PasswordOptions = {
  minLength: 8,
  requireSymbols: true
};

// Type-safe result
const result: ValidationResult = validate.isPassword('password123', passwordOptions);

Development

Prerequisites

  • Node.js (>= 14.x)
  • npm or yarn or pnpm

Local Development

  1. Clone the repository:
git clone https://github.com/BODHEESH/bodhi-form-validation.git
cd bodhi-form-validation
  1. Install dependencies:
npm install
  1. Build the package:
npm run build
  1. Run tests:
npm test

Building for Production

The package uses TypeScript for development and outputs both CommonJS and ES Modules:

# Build once
npm run build

# Build in watch mode
npm run build:watch

Build outputs:

  • dist/index.js - CommonJS module
  • dist/index.d.ts - TypeScript declarations
  • dist/index.esm.js - ES Module

Running Tests

The package includes comprehensive tests:

# Run all tests
npm test

# Run tests in watch mode
npm test:watch

# Run tests with coverage
npm test:coverage

Code Quality

We maintain high code quality standards:

# Run linter
npm run lint

# Fix linting issues
npm run lint:fix

# Format code
npm run format

Publishing

To publish a new version:

  1. Update version in package.json:
npm version patch  # for bug fixes
npm version minor  # for new features
npm version major  # for breaking changes
  1. Build and test:
npm run build
npm test
  1. Publish to npm:
npm login
npm publish

Troubleshooting

Common Issues

  1. TypeScript Import Issues
// โŒ Wrong
import { validate } from 'bodhi-form-validations';

// โœ… Correct
import validate from 'bodhi-form-validations';
  1. React Integration
// โŒ Wrong
const [errors, setErrors] = useState([]);

// โœ… Correct
const [errors, setErrors] = useState<Record<string, string>>({});
  1. Vue.js Reactivity
// โŒ Wrong
this.errors[field] = result.message;

// โœ… Correct
this.$set(this.errors, field, result.message);

Performance Optimization

  1. Debounce Validation
import { debounce } from 'lodash';

const debouncedValidate = debounce((value) => {
  const result = validate.isEmail(value);
  setError(result.message);
}, 300);
  1. Batch Validation
// โŒ Inefficient
Object.keys(form).forEach(key => {
  validate[key](form[key]);
});

// โœ… Efficient
const results = Object.entries(form).reduce((acc, [key, value]) => {
  acc[key] = validate[key](value);
  return acc;
}, {});

Security Considerations

  1. Password Validation
  • Use isStrongPassword instead of basic isPassword
  • Enable all security checks
  • Use custom banned password lists
const passwordValidation = validate.isStrongPassword(password, {
  minLength: 12,
  maxLength: 50,
  requireUppercase: true,
  requireLowercase: true,
  requireNumbers: true,
  requireSymbols: true,
  bannedPasswords: ['password123', 'admin123'],
  maxRepeatingChars: 2
});
  1. Input Sanitization
  • Always sanitize user input
  • Use strict validation modes
  • Validate on both client and server
const userInput = validate.isUsername(input, {
  strictMode: true,
  allowedChars: 'a-zA-Z0-9_-',
  sanitize: true
});

Browser Support

The library supports all modern browsers and IE11+:

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)
  • IE11 (with polyfills)

Required polyfills for IE11:

  • Promise
  • Object.entries
  • Array.from

Size Optimization

The package supports tree-shaking. Import only what you need:

// โŒ Imports everything
import validate from 'bodhi-form-validations';

// โœ… Import only what you need
import { isEmail, isPhone } from 'bodhi-form-validations/lite';

Best Practices

Real-time Validation

// Validate on input change
inputElement.addEventListener('input', (e) => {
  const result = validate.isUsername(e.target.value);
  showError(result.message);
});

Custom Error Messages

const result = validate.isPassword(password, {
  minLength: 8,
  requireSymbols: true
});

Form Submission

const validateForm = (data) => {
  const validations = {
    username: validate.isUsername(data.username),
    email: validate.isEmail(data.email),
    password: validate.isPassword(data.password)
  };

  return Object.entries(validations).reduce((errors, [field, result]) => {
    if (!result.isValid) {
      errors[field] = result.message;
    }
    return errors;
  }, {});
};

Contributing

We welcome contributions! Here's how you can help:

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Please make sure to update tests as appropriate and adhere to the existing coding style.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

  • Star this repository
  • Create issues for bug reports and feature requests
  • Follow the author on GitHub
  • Consider contributing to the project

Made with โค๏ธ by BODHEESH

Framework Integration Guides

React Hook Example

import { useState, useCallback } from 'react';
import validate from 'bodhi-form-validations';

// Custom hook for form validation
const useFormValidation = (initialValues: any) => {
  const [values, setValues] = useState(initialValues);
  const [errors, setErrors] = useState({});
  const [isSubmitting, setIsSubmitting] = useState(false);

  const validateField = useCallback((name: string, value: any) => {
    let validationResult;
    
    switch (name) {
      case 'email':
        validationResult = validate.isEmail(value);
        break;
      case 'password':
        validationResult = validate.isStrongPassword(value);
        break;
      case 'phone':
        validationResult = validate.isPhone(value);
        break;
      // Add more validations as needed
    }

    setErrors(prev => ({
      ...prev,
      [name]: validationResult?.isValid ? '' : validationResult?.message
    }));

    return validationResult?.isValid;
  }, []);

  const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setValues(prev => ({ ...prev, [name]: value }));
    validateField(name, value);
  }, [validateField]);

  const handleSubmit = useCallback(async (e: React.FormEvent) => {
    e.preventDefault();
    setIsSubmitting(true);

    const isValid = Object.keys(values).every(key => validateField(key, values[key]));

    if (isValid) {
      // Submit form
      console.log('Form is valid', values);
    }

    setIsSubmitting(false);
  }, [values, validateField]);

  return {
    values,
    errors,
    isSubmitting,
    handleChange,
    handleSubmit,
    validateField
  };
};

// Usage in component
const SignupForm = () => {
  const {
    values,
    errors,
    isSubmitting,
    handleChange,
    handleSubmit
  } = useFormValidation({
    email: '',
    password: '',
    phone: ''
  });

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <input
          name="email"
          value={values.email}
          onChange={handleChange}
          placeholder="Email"
        />
        {errors.email && <span className="error">{errors.email}</span>}
      </div>
      {/* Add more form fields */}
      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? 'Submitting...' : 'Submit'}
      </button>
    </form>
  );
};

Vue 3 Composition API Example

import { ref, reactive } from 'vue';
import validate from 'bodhi-form-validations';

// Composable for form validation
export function useFormValidation(initialValues: any) {
  const values = reactive(initialValues);
  const errors = reactive({});
  const isSubmitting = ref(false);

  const validateField = (name: string, value: any) => {
    let validationResult;
    
    switch (name) {
      case 'email':
        validationResult = validate.isEmail(value);
        break;
      case 'password':
        validationResult = validate.isStrongPassword(value);
        break;
      // Add more validations
    }

    errors[name] = validationResult?.isValid ? '' : validationResult?.message;
    return validationResult?.isValid;
  };

  const handleSubmit = async (e: Event) => {
    e.preventDefault();
    isSubmitting.value = true;

    const isValid = Object.keys(values).every(key => 
      validateField(key, values[key])
    );

    if (isValid) {
      // Submit form
      console.log('Form is valid', values);
    }

    isSubmitting.value = false;
  };

  return {
    values,
    errors,
    isSubmitting,
    validateField,
    handleSubmit
  };
}

// Usage in component
<script setup lang="ts">
const {
  values,
  errors,
  isSubmitting,
  validateField,
  handleSubmit
} = useFormValidation({
  email: '',
  password: ''
});
</script>

<template>
  <form @submit="handleSubmit">
    <div>
      <input
        v-model="values.email"
        @input="validateField('email', values.email)"
        placeholder="Email"
      />
      <span v-if="errors.email" class="error">{{ errors.email }}</span>
    </div>
    <!-- Add more form fields -->
    <button :disabled="isSubmitting">
      {{ isSubmitting ? 'Submitting...' : 'Submit' }}
    </button>
  </form>
</template>

Common Patterns and Best Practices

1. Debounced Validation

import { debounce } from 'lodash';

const debouncedValidate = debounce((value: string) => {
  const result = validate.isEmail(value);
  setError(result.message);
}, 300);

// Usage in input
<input
  onChange={(e) => debouncedValidate(e.target.value)}
  placeholder="Email"
/>

2. Async Validation with API

const validateUsername = async (username: string) => {
  const formatResult = validate.isUsername(username);
  if (!formatResult.isValid) {
    return formatResult;
  }

  // Check availability with API
  try {
    const response = await fetch(`/api/check-username/${username}`);
    const { available } = await response.json();
    
    return {
      isValid: available,
      message: available ? 'Username available' : 'Username already taken'
    };
  } catch (error) {
    return {
      isValid: false,
      message: 'Error checking username availability'
    };
  }
};

3. Custom Validation Rules

const validatePassword = (password: string) => {
  // First use built-in validation
  const baseResult = validate.isStrongPassword(password);
  if (!baseResult.isValid) {
    return baseResult;
  }

  // Add custom rules
  const customRules = [
    {
      test: (p: string) => !/(.)\1{2,}/.test(p),
      message: 'Password cannot contain repeating characters'
    },
    {
      test: (p: string) => !/12345|qwerty|password/i.test(p),
      message: 'Password contains common patterns'
    }
  ];

  for (const rule of customRules) {
    if (!rule.test(password)) {
      return {
        isValid: false,
        message: rule.message
      };
    }
  }

  return baseResult;
};

4. Form Group Validation

const validatePasswordGroup = (password: string, confirmPassword: string) => {
  // First validate individual passwords
  const passwordResult = validate.isStrongPassword(password);
  if (!passwordResult.isValid) {
    return passwordResult;
  }

  // Then validate match
  if (password !== confirmPassword) {
    return {
      isValid: false,
      message: 'Passwords do not match'
    };
  }

  return {
    isValid: true,
    message: 'Passwords match'
  };
};

5. Conditional Validation

const validateShippingAddress = (address: any, isInternational: boolean) => {
  const baseRules = {
    street: { required: true, minLength: 5 },
    city: { required: true },
    country: { required: true }
  };

  const domesticRules = {
    ...baseRules,
    zip: { pattern: '^\\d{5}$' }
  };

  const internationalRules = {
    ...baseRules,
    zip: { required: true },
    province: { required: true }
  };

  const rules = isInternational ? internationalRules : domesticRules;
  
  return validate.isObject(address, {
    schema: rules,
    strict: true
  });
};

6. Dynamic Form Validation

interface DynamicField {
  type: 'text' | 'email' | 'phone' | 'number' | 'date';
  name: string;
  required: boolean;
  rules?: Record<string, any>;
}

const validateDynamicForm = (fields: DynamicField[], values: Record<string, any>) => {
  const errors: Record<string, string> = {};

  fields.forEach(field => {
    if (!field.required && !values[field.name]) {
      return; // Skip optional empty fields
    }

    let result;
    const value = values[field.name];

    switch (field.type) {
      case 'email':
        result = validate.isEmail(value, field.rules);
        break;
      case 'phone':
        result = validate.isPhone(value, field.rules);
        break;
      case 'number':
        result = validate.isNumber(value, field.rules);
        break;
      case 'date':
        result = validate.isDate(value, field.rules);
        break;
      default:
        result = validate.isText(value, field.rules);
    }

    if (!result.isValid) {
      errors[field.name] = result.message;
    }
  });

  return {
    isValid: Object.keys(errors).length === 0,
    errors
  };
};

// Usage example
const formFields: DynamicField[] = [
  {
    type: 'email',
    name: 'email',
    required: true,
    rules: { allowInternational: true }
  },
  {
    type: 'phone',
    name: 'phone',
    required: false,
    rules: { country: 'US' }
  },
  {
    type: 'date',
    name: 'birthdate',
    required: true,
    rules: { minAge: 18 }
  }
];

const formValues = {
  email: 'user@example.com',
  phone: '+1-555-123-4567',
  birthdate: '2000-01-01'
};

const validation = validateDynamicForm(formFields, formValues);

7. Multi-Step Form Validation

interface FormStep {
  fields: string[];
  validator: (values: Record<string, any>) => ValidationResult;
}

class MultiStepFormValidator {
  private steps: FormStep[];
  private currentStep: number;
  private values: Record<string, any>;

  constructor(steps: FormStep[]) {
    this.steps = steps;
    this.currentStep = 0;
    this.values = {};
  }

  validateCurrentStep(stepValues: Record<string, any>): ValidationResult {
    const step = this.steps[this.currentStep];
    return step.validator(stepValues);
  }

  validateAllPreviousSteps(): boolean {
    for (let i = 0; i < this.currentStep; i++) {
      const step = this.steps[i];
      const stepValues = this.extractStepValues(step.fields);
      const result = step.validator(stepValues);
      if (!result.isValid) return false;
    }
    return true;
  }

  private extractStepValues(fields: string[]): Record<string, any> {
    return fields.reduce((acc, field) => {
      acc[field] = this.values[field];
      return acc;
    }, {});
  }

  nextStep(stepValues: Record<string, any>): ValidationResult {
    const validation = this.validateCurrentStep(stepValues);
    if (validation.isValid) {
      this.values = { ...this.values, ...stepValues };
      this.currentStep++;
    }
    return validation;
  }

  previousStep(): void {
    if (this.currentStep > 0) {
      this.currentStep--;
    }
  }

  getProgress(): number {
    return ((this.currentStep + 1) / this.steps.length) * 100;
  }
}

// Usage example
const personalInfoValidator: FormStep = {
  fields: ['name', 'email'],
  validator: (values) => {
    const nameValid = validate.isUsername(values.name);
    const emailValid = validate.isEmail(values.email);
    
    return {
      isValid: nameValid.isValid && emailValid.isValid,
      errors: {
        name: nameValid.message,
        email: emailValid.message
      }
    };
  }
};

const addressValidator: FormStep = {
  fields: ['street', 'city', 'zip'],
  validator: (values) => {
    return validate.isObject(values, {
      schema: {
        street: { type: 'string', minLength: 5 },
        city: { type: 'string', required: true },
        zip: { type: 'string', pattern: '\\d{5}' }
      }
    });
  }
};

const form = new MultiStepFormValidator([
  personalInfoValidator,
  addressValidator
]);

8. Cross-Field Validation

interface UserRegistration {
  password: string;
  confirmPassword: string;
  birthDate: string;
  graduationDate: string;
  startDate: string;
  endDate: string;
}

const validateCrossFields = (data: UserRegistration) => {
  const errors: Record<string, string> = {};

  // Password match validation
  const passwordMatch = validate.isEqual(data.password, data.confirmPassword, {
    errorMessage: 'Passwords must match'
  });
  if (!passwordMatch.isValid) {
    errors.confirmPassword = passwordMatch.message;
  }

  // Date sequence validation
  const dates = {
    birth: new Date(data.birthDate),
    graduation: new Date(data.graduationDate),
    start: new Date(data.startDate),
    end: new Date(data.endDate)
  };

  // Validate date sequence
  if (dates.graduation < dates.birth) {
    errors.graduationDate = 'Graduation date cannot be before birth date';
  }

  if (dates.start < dates.graduation) {
    errors.startDate = 'Start date cannot be before graduation date';
  }

  if (dates.end < dates.start) {
    errors.endDate = 'End date cannot be before start date';
  }

  return {
    isValid: Object.keys(errors).length === 0,
    errors
  };
};

9. Nested Object Validation

interface NestedForm {
  user: {
    profile: {
      personal: {
        name: string;
        age: number;
      };
      contact: {
        email: string;
        phone?: string;
      };
    };
    settings: {
      notifications: {
        email: boolean;
        sms: boolean;
      };
      theme: string;
    };
  };
}

const validateNestedObject = (data: NestedForm) => {
  return validate.isObject(data, {
    schema: {
      user: {
        type: 'object',
        properties: {
          profile: {
            type: 'object',
            properties: {
              personal: {
                type: 'object',
                properties: {
                  name: { type: 'string', minLength: 2 },
                  age: { type: 'number', min: 18 }
                }
              },
              contact: {
                type: 'object',
                properties: {
                  email: { type: 'email' },
                  phone: { type: 'phone', optional: true }
                }
              }
            }
          },
          settings: {
            type: 'object',
            properties: {
              notifications: {
                type: 'object',
                properties: {
                  email: { type: 'boolean' },
                  sms: { type: 'boolean' }
                }
              },
              theme: { type: 'string', enum: ['light', 'dark'] }
            }
          }
        }
      }
    }
  });
};

10. Array Field Validation

interface Contact {
  name: string;
  email: string;
  phone?: string;
}

const validateContactList = (contacts: Contact[]) => {
  // First validate array properties
  const arrayValidation = validate.isArray(contacts, {
    minLength: 1,
    maxLength: 10,
    unique: true,
    uniqueBy: 'email' // Check uniqueness by email
  });

  if (!arrayValidation.isValid) {
    return arrayValidation;
  }

  // Then validate each contact
  const errors: Record<number, Record<string, string>> = {};
  let isValid = true;

  contacts.forEach((contact, index) => {
    const contactValidation = validate.isObject(contact, {
      schema: {
        name: { type: 'string', required: true, minLength: 2 },
        email: { type: 'email', required: true },
        phone: { type: 'phone', required: false }
      }
    });

    if (!contactValidation.isValid) {
      errors[index] = contactValidation.errors;
      isValid = false;
    }
  });

  return {
    isValid,
    errors,
    arrayErrors: arrayValidation.errors
  };
};

// Usage example
const contacts = [
  {
    name: 'John Doe',
    email: 'john@example.com',
    phone: '+1-555-123-4567'
  },
  {
    name: 'Jane Smith',
    email: 'jane@example.com'
  }
];

const validation = validateContactList(contacts);

11. Conditional Chain Validation

const validateChain = (value: any, rules: Array<(val: any) => ValidationResult>) => {
  for (const rule of rules) {
    const result = rule(value);
    if (!result.isValid) {
      return result;
    }
  }

  return { isValid: true, message: 'All validations passed' };
};

// Usage example
const validateUsername = (username: string) => {
  const rules = [
    // Basic format check
    (val: string) => validate.isUsername(val, { minLength: 3 }),
    
    // No special characters except underscore
    (val: string) => validate.matches(val, /^[a-zA-Z0-9_]+$/),
    
    // No consecutive underscores
    (val: string) => validate.not(val, /__/),
    
    // Must start with a letter
    (val: string) => validate.matches(val, /^[a-zA-Z]/),
    
    // Custom business logic
    async (val: string) => {
      // Check if username is available
      const available = await checkUsernameAvailability(val);
      return {
        isValid: available,
        message: available ? 'Username is available' : 'Username is taken'
      };
    }
  ];

  return validateChain(username, rules);
};

Follow these instructions to make the following change to my code document.

Instruction: Update README with better organization and conclusion

Code Edit:

{{ ... content until the last example ... }}

## Quick Start Guide

### 1. Installation
```bash
npm install bodhi-form-validations
# or
yarn add bodhi-form-validations

2. Basic Usage

import validate from 'bodhi-form-validations';

// Simple email validation
const emailResult = validate.isEmail('user@example.com');
console.log(emailResult.isValid); // true

// Password validation
const passwordResult = validate.isStrongPassword('MyP@ssw0rd');
console.log(passwordResult.isValid); // true

3. Form Validation

const formData = {
  username: 'johndoe',
  email: 'john@example.com',
  password: 'SecureP@ss123',
  age: 25
};

const formValidation = {
  username: validate.isUsername(formData.username),
  email: validate.isEmail(formData.email),
  password: validate.isStrongPassword(formData.password),
  age: validate.isNumber(formData.age, { min: 18 })
};

const isFormValid = Object.values(formValidation)
  .every(result => result.isValid);

Usage Order and Best Practices

  1. Start with Basic Validations

    • Begin with simple field validations
    • Use appropriate validation functions for each field type
    • Handle required/optional fields appropriately
  2. Add Complex Validations

    • Implement cross-field validations
    • Add conditional validation rules
    • Use validation chains for complex rules
  3. Implement Form-Level Validation

    • Combine individual field validations
    • Add form-wide validation rules
    • Handle submission validation
  4. Error Handling

    • Collect and organize validation errors
    • Display user-friendly error messages
    • Implement real-time validation feedback
  5. Performance Optimization

    • Use debouncing for real-time validation
    • Implement validation caching where appropriate
    • Optimize validation chains

Support and Community

Getting Help

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Conclusion

Bodhi Form Validations provides a comprehensive solution for form validation in JavaScript/TypeScript applications. Key benefits include:

  • Type Safety: Full TypeScript support with comprehensive type definitions
  • Flexibility: Customize validation rules to match your exact requirements
  • Extensibility: Easy to extend with custom validation rules
  • Framework Agnostic: Works with any JavaScript framework
  • Performance: Optimized for both small and large forms
  • Developer Experience: Clear error messages and intuitive API

Future Development

We're constantly improving Bodhi Form Validations. Upcoming features include:

  • More validation patterns
  • Additional framework integrations
  • Enhanced performance optimizations
  • Extended documentation and examples

Version Compatibility

  • Requires Node.js 12.0.0 or later
  • Compatible with all major browsers
  • TypeScript 4.0.0 or later for type definitions

Final Notes

  • Always check the documentation for the latest updates
  • Join our community discussions
  • Report issues and suggest features through GitHub
  • Consider contributing to the project

Made with โค๏ธ by BODHEESH

License

MIT ยฉ BODHEESH

bodhibodhi-form-validationsbodhi-form-validationbodhi form validationbodhi form validationsbodhi form validation librarybodhi form validations librarybodhi form validation packagebodhi form validations packagebodhi form validation typescriptbodhi form validations typescriptbodhi form validation typescript librarybodhi form validations typescript librarybodhi form validation typescript packagebodhi form validations typescript packagebodhi form validation reactbodhi form validations reactbodhi form validation react librarybodhi form validations react librarybodhi form validation react packagebodhi form validations react packagebodhi form validation react typescriptbodhi form validations react typescriptbodhi form validation react typescript librarybodhi form validations react typescript librarybodhi form validation react typescript packagebodhi form validations react typescript packagebodhi form validation react typescript reactbodhi form validations react typescript reactbodhi form validation react typescript react librarybodhi form validations react typescript react librarybodhi form validation react typescript react packagebodhi form validations react typescript react packagebodhi form validation react typescript react typescriptbodhi form validations react typescript react typescriptbodhi form validation react typescript react typescript librarybodhi form validations react typescript react typescript librarybodhi form validation react typescript react typescript packagebodhi form validations react typescript react typescript packagebodhi form validation react typescript react typescript reactbodhi form validations react typescript react typescript reactbodhi form validation react typescript react typescript react librarybodhi form validations react typescript react typescript react librarybodhi form validation react typescript react typescript react packagebodhi form validations react typescript react typescript react packagebodhi form validation react typescript react typescript react typescriptbodhi form validations react typescript react typescript react typescriptbodhi form validation react typescript react typescript react typescript librarybodhi form validations react typescript react typescript react typescript librarybodhi form validation react typescript react typescript react typescript packagebodhi form validations react typescript react typescript react typescript packageform validationreact form validationformsimple form validationtypescriptvalidationformsinput validationcredit card validationphone validationemail validationpassword validationpostal code validation
1.0.1

6 months ago

1.0.0

6 months ago