npm package: @miyax/validatorjs
Description: Miyax Validator JS - A powerful JavaScript validation library inspired by Laravel Validation Rules
Author: José Antonio Sánchez
Latest version: 1.2.1

> 📖 **[Leer en Español](README-ES.md)**


# @miyax/validatorjs

A powerful and flexible JavaScript validation library inspired by [Laravel Validation Rules](https://laravel.com/docs/12.x/validation#available-validation-rules).


[![NPM Version](https://img.shields.io/npm/v/@miyax/validatorjs.svg)](https://www.npmjs.com/package/@miyax/validatorjs)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Size](https://img.shields.io/bundlephobia/minzip/@miyax/validatorjs.svg)](https://bundlephobia.com/result?p=@miyax/validatorjs)
[![Stars](https://img.shields.io/github/stars/xerifandtomas/miyax-validatorjs.svg?style=social)](https://github.com/xerifandtomas/miyax-validatorjs)

## 📦 Installation

```bash
npm install @miyax/validatorjs
```

```bash
yarn add @miyax/validatorjs
```

## 🚀 Usage Example

```javascript
import { validate } from '@miyax/validatorjs';

// Form data
const userData = {
  name: 'John Doe',
  email: 'john@example.com',
  age: 28,
  password: 'myPassword123'
};

// Validation rules
const rules = {
  name: 'required|string|min:2|max:50',
  email: 'required|email',
  age: 'required|numeric|min:18|max:99',
  password: 'required|string|min:8'
};

// Validate
const result = validate(userData, rules);

if (result.valid) {
  console.log('✅ Valid user');
} else {
  console.log('❌ Errors found:');
  result.errors.forEach(error => {
    console.log(`  • ${error.field}: ${error.message}`);
  });
}
```

## 📋 Implemented Rules

### String Rules
- `alpha` - Letters only (a-zA-Z)
- `alpha_num` - Letters and numbers
- `alpha_dash` - Letters, numbers, hyphens and underscores
- `ascii` - ASCII characters only
- `email` - Valid email
- `json` - Valid JSON
- `lowercase` - Lowercase only
- `uppercase` - Uppercase only
- `string` - Must be string
- `url` - Valid URL
- `uuid` - Valid UUID
- `hex_color` - Hexadecimal color
- `starts_with:value` - Starts with value
- `ends_with:value` - Ends with value
- `doesnt_start_with:value` - Doesn't start with value
- `doesnt_end_with:value` - Doesn't end with value
- `regex:pattern` - Matches regular expression
- `not_regex:pattern` - Doesn't match regular expression

### Numeric Rules
- `numeric` - Valid number
- `integer` - Integer number
- `decimal:min,max` - Decimals (min-max places)
- `digits:value` - Exactly N digits
- `digits_between:min,max` - Between min and max digits
- `min_digits:value` - Minimum N digits
- `max_digits:value` - Maximum N digits
- `multiple_of:value` - Multiple of value
- `greater_than:value` - Greater than value
- `greater_than_or_equal:value` - Greater than or equal to value
- `less_than:value` - Less than value
- `less_than_or_equal:value` - Less than or equal to value

### Array Rules
- `array` - Must be array
- `distinct` - Unique elements
- `contains:value` - Contains value
- `doesnt_contain:value` - Doesn't contain value
- `in_array:field` - Value is in field array
- `in:val1,val2,val3` - Value is in list
- `not_in:val1,val2,val3` - Value is not in list

### Date Rules
- `date` - Valid date
- `date_format:format` - Specific date format
- `before:date` - Before date
- `before_or_equal:date` - Before or equal to date
- `after:date` - After date
- `after_or_equal:date` - After or equal to date
- `date_equals:date` - Equal to date
- `timezone` - Valid timezone

### File Rules
- `file` - Must be file
- `image` - Must be image
- `mimes:jpg,png` - Allowed MIME types
- `mimetypes:image/*` - Allowed MIME categories
- `extensions:jpg,png` - Allowed extensions
- `dimensions` - Image dimensions validation

### Contextual Rules
- `min:value` - Minimum value/size
- `max:value` - Maximum value/size
- `between:min,max` - Between two values/sizes
- `size:value` - Exact size
- `same:field` - Same as another field
- `different:field` - Different from another field

### Utility Rules
- `required` - Required field
- `required_if:field,value` - Required if another field has value
- `filled` - Not empty (if present)
- `nullable` - Allows null values
- `boolean` - Boolean value
- `present` - Must be present
- `present_if:field,value` - Present if another field has value
- `missing` - Must not be present
- `missing_if:field,value` - Missing if another field has value
- `sometimes` - Validate only if present


### `Validator` Class

```javascript
import { Validator } from '@miyax/validatorjs/core';

const validator = new Validator();

// Available methods
validator.validate(data, rules, options);
validator.addRule(name, validatorFn, message);
validator.setMessages(messages);
validator.passes(data, rules);
validator.fails(data, rules);
```

### `createValidator()` Helper

```javascript
import { createValidator } from '@miyax/validatorjs';

const validator = createValidator();
// Equivalent to: new Validator()
```

## 🚀 Framework Examples

### React
```jsx
import React, { useState } from 'react';
import { validate } from '@miyax/validatorjs';

function ContactForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });
  const [errors, setErrors] = useState({});

  const handleSubmit = (e) => {
    e.preventDefault();

    const rules = {
      name: 'required|string|min:2',
      email: 'required|email',
      message: 'required|string|min:10'
    };

    const result = validate(formData, rules);

    if (result.valid) {
      // Submit form
      console.log('Submitting...', formData);
      setErrors({});
    } else {
      // Show errors
      const errorMap = {};
      result.errors.forEach(error => {
        errorMap[error.field] = error.message;
      });
      setErrors(errorMap);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Name"
        value={formData.name}
        onChange={(e) => setFormData({...formData, name: e.target.value})}
      />
      {errors.name && <span className="error">{errors.name}</span>}

      {/* More fields... */}

      <button type="submit">Submit</button>
    </form>
  );
}
```

### Vue 3
```vue
<template>
  <form @submit.prevent="handleSubmit">
    <input
      v-model="form.email"
      type="email"
      placeholder="Email"
      :class="{ error: errors.email }"
    />
    <span v-if="errors.email" class="error-text">{{ errors.email }}</span>

    <button type="submit">Submit</button>
  </form>
</template>

<script setup>
import { ref, reactive } from 'vue';
import { validate } from '@miyax/validatorjs';

const form = reactive({
  email: '',
  password: ''
});

const errors = ref({});

const handleSubmit = () => {
  const rules = {
    email: 'required|email',
    password: 'required|string|min:8'
  };

  const result = validate(form, rules);

  if (result.valid) {
    // Process form
    console.log('Valid form');
    errors.value = {};
  } else {
    // Show errors
    errors.value = result.errors.reduce((acc, error) => {
      acc[error.field] = error.message;
      return acc;
    }, {});
  }
};
</script>
```

## 🤔 FAQ

### How to add Spanish messages?

```javascript
import { Validator } from '@miyax/validatorjs';

const validator = new Validator();

validator.setMessages({
  required: 'The :attribute field is required',
  email: 'The :attribute field must be a valid email',
  min: 'The :attribute field must have at least :param characters',
  max: 'The :attribute field cannot have more than :param characters'
});
```

### How to validate nested forms?

```javascript
import { validate } from '@miyax/validatorjs';

// Complete example with nested object validation
const formData = {
  personal: {
    firstName: 'John',
    lastName: 'Doe',
    contact: {
      email: 'john@example.com',
      phone: '+1234567890'
    }
  },
  preferences: {
    newsletter: true,
    theme: 'dark'
  }
};

const rules = {
  'personal.firstName': 'required|string|min:2',
  'personal.lastName': 'required|string|min:2',
  'personal.contact.email': 'required|email',
  'personal.contact.phone': 'required|string|min:9',
  'preferences.newsletter': 'required|boolean',
  'preferences.theme': 'required|in:light,dark,auto'
};

const result = validate(formData, rules);

// The result will include specific errors with full paths
if (!result.valid) {
  result.errors.forEach(error => {
    console.log(`Error in ${error.field}: ${error.message}`);
  });
}
```

### Does it work with async/await?

```javascript
async function validateAsync(data, rules) {
  // Validation is synchronous, but you can use it in async context
  const result = validate(data, rules);

  if (result.valid) {
    // Continue with async operations
    await saveToDatabase(data);
  }

  return result;
}
```

## 🤝 Contributing

Contributions are welcome!

1. Fork the project
2. Create a branch: `git checkout -b feature/new-rule`
3. Commit: `git commit -m 'Add new validation rule'`
4. Push: `git push origin feature/new-rule`
5. Open a Pull Request

---

<div align="center">

**🚀 Made with ❤️ for the JavaScript community!**

</div>