An open API service indexing awesome lists of open source software.

https://github.com/huntergera/yh-validator

A lightweight form validation library with modular functions
https://github.com/huntergera/yh-validator

email-validation form-validation formik javascript-library lightweight modular npm-package password-validation phone-validation react react-form typescript username-validation validation-library validator yup

Last synced: 7 months ago
JSON representation

A lightweight form validation library with modular functions

Awesome Lists containing this project

README

          

# πŸ“¦yh-validator
[![npm version](https://img.shields.io/npm/v/yh-validator.svg)](https://www.npmjs.com/package/yh-validator)
[![npm downloads](https://img.shields.io/npm/dm/yh-validator.svg)](https://www.npmjs.com/package/yh-validator)
[![license](https://img.shields.io/npm/l/yh-validator.svg)](https://github.com/huntergera/yh-validator/main/LICENSE)

A lightweight, modular form validation library written in **TypeScript**, designed to be framework-agnostic and easy to use in any JavaScript or TypeScript project.

---

## πŸš€ Features

- πŸ“§ Email validation
- πŸ“ž International phone number validation (with country support)
- πŸ” Configurable password strength validation
- πŸ‘€ Flexible username validation
- ↔️ Deep equality comparison for objects and arrays
- πŸ›  Modular structure β€” import only what you need
- πŸ“¦ Lightweight and dependency-minimized
- πŸ” TypeScript-first with full type safety

---

## πŸ“¦ Installation

```
npm install yh-validator
```
or
```
yarn add yh-validator
```

## ⚠️ Tree-shaking notice
To ensure optimal bundle size, import validators directly from their paths, for example:
```ts
import { isEmail } from "yh-validator/isEmail";
import { isPhone } from "yh-validator/isPhone";
import { isStrongPassword } from "yh-validator/isStrongPassword";
```

## ✨ Usage
### πŸ“§ Validate Email
```ts
import { isEmail } from 'yh-validator/isEmail';

console.log(isEmail('test@example.com')); // true
console.log(isEmail('invalid-email')); // false
```

### πŸ“ž Validate Phone Number
```ts
import { isPhone } from 'yh-validator/isPhone';

// With international format
console.log(isPhone('+380961234567')); // true

// With country code
console.log(isPhone('0961234567', 'UA')); // true

// Invalid
console.log(isPhone('12345')); // false
```

### πŸ” Validate Password Strength
The `isStrongPassword` function returns an object containing `valid: boolean` and an `errors: string[]` array, providing detailed feedback on why a password might not meet the criteria.
```ts
import { isStrongPassword } from 'yh-validator/isStrongPassword';

// Basic usage with default options (min 8 chars, 1 uppercase, 1 lowercase, 1 number, 1 special char)
const result1 = isStrongPassword('StrongP@ss1');
console.log(result1.valid); // true
console.log(result1.errors); // []

// Password missing required elements
const result2 = isStrongPassword('weakpassword');
console.log(result2.valid); // false
console.log(result2.errors); // ["Password must contain at least 1 uppercase letter(s).", "Password must contain at least 1 number(s).", "Password must contain at least 1 special character(s)."]

// Custom options
const result3 = isStrongPassword('simple123', {
minLength: 6,
minUppercase: 0,
minLowercase: 0,
minNumbers: 1,
minSpecialChars: 0,
});
console.log(result3.valid); // true
console.log(result3.errors); // [] (valid based on custom relaxed rules)

const result4 = isStrongPassword('tooShort', { minLength: 10 });
console.log(result4.valid); // false
console.log(result4.errors); // ["Password must be at least 10 characters long."]
```

### πŸ‘€ Validate Username
The `isUsername` function provides configurable rules for validating usernames, returning a detailed result object.
```ts
import { isUsername } from 'yh-validator/isUsername';

// Basic usage with default options (min 3, max 30, alphanumeric, dashes, underscores, periods allowed)
const result1 = isUsername('john_doe123');
console.log(result1.valid); // true
console.log(result1.errors); // []

// Username too short
const result2 = isUsername('ab');
console.log(result2.valid); // false
console.log(result2.errors[0]); // ["Username must be at least 3 characters long."]

// Username with disallowed characters (e.g., !)
const result3 = isUsername('user!name');
console.log(result3.valid); // false
console.log(result3.errors[0]); // ["Username contains disallowed characters."]

// Custom options: allow spaces, longer minLength, specific blacklist
const result4 = isUsername('My User Name', {
minLength: 5,
allowSpaces: true,
blacklist: ['admin', 'guest']
});
console.log(result4.valid); // true
console.log(result4.errors); // []

// Custom options: check against a specific blacklist
const result5 = isUsername('admin', { blacklist: ['admin', 'root'] });
console.log(result5.valid); // false
console.log(result5.errors); // ["Username is reserved or not allowed."]
```

### ↔️ Equality Comparison
```ts
import { isEqual } from 'yh-validator/isEqual';

console.log(isEqual('hello', 'hello')); // true
```

## 🧩 Integration with Schema Validation Libraries
You can easily integrate `yh-validator` functions with popular schema validation libraries like `Zod`, `Yup` and others using their custom validation methods. These libraries typically allow you to define custom validation rules that return a boolean (valid/invalid) or throw an error with a custom message.

### Integrating with Zod
(You'll need to install `zod`: `npm install zod`)
```ts
import { z } from 'zod';
import { isEmail } from 'yh-validator/isEmail';
import { isStrongPassword } from 'yh-validator/isStrongPassword';

export const registrationSchema = z.object({
username: z.string().min(1, { message: "Username is required" }),

email: z.string()
.min(1, 'Email is required')
.refine((value) => isEmail(value), 'Enter a valid email address'),

password: z.string()
.min(8, { message: "Password must be at least 8 characters long." }) // Base Zod length check
.refine((value) => {
// Use isStrongPassword to check complexity
const result = isStrongPassword(value);
return result.valid; // Zod's .refine expects a boolean
}, (value) => {
// If validation fails, Zod calls this function to get the error message.
// Re-run isStrongPassword to get the detailed errors to display.
const result = isStrongPassword(value);
return { message: result.errors[0] || "Password is not strong enough." };
}),
});
```

### Integrating with Yup
(You'll need to install `yup`: `npm install yup`)
```ts
import * as yup from 'yup';
import { isEmail } from 'yh-validator/isEmail';
import { isStrongPassword } from 'yh-validator/isStrongPassword';

export const userProfileSchema = yup.object().shape({
email: yup.string()
.required('Email is required.')
.test(
'is-valid-email',
'Please enter a valid email address.',
(value) => value ? isEmail(value) : false
),

password: yup.string()
.required('Password is required.')
.min(8, 'Password must be at least 8 characters long (base check).') // Optional: you can add a base length measurement Yup
.test(
'is-strong-password',
'', // Empty string as message, we will generate dynamic message
function (value) {
if (!value) return false; // Handle empty/null values if not caught by .required()

const result = isStrongPassword(value, {
minLength: 8, // Ensure this matches or is greater than Yup's .min()
minUppercase: 1,
minLowercase: 1,
minNumbers: 1,
minSpecialChars: 1,
});

if (!result.valid) {
// If validation fails, use this.createError to provide detailed message
return this.createError({ message: result.errors[0] || "Password is not strong enough." });
}
return true; // Password is strong
}
),
});
```

## πŸ“˜ API Reference
`isEmail(email: string): boolean`

Validates whether the string is a well-formed email address.

`isPhone(phoneNumber: string, countryCode?: string): boolean`

Validates international phone numbers. If no `countryCode` is provided, assumes the number starts with `+`.

`phoneNumber` β€” phone string to validate

`countryCode` β€” (optional) ISO 2-letter country code (e.g. `"US"`, `"UA"`)

Internally uses the [`phone`](https://www.npmjs.com/package/phone) library.

`isStrongPassword(password: string, options?: PasswordValidationOptions): PasswordValidationResult`

Validates the strength of a password based on configurable criteria.
- `password` (string): The password string to validate.
- `options` (object, optional): An object to customize validation criteria.
- `minLength` (number): Minimum total length of the password (default: 8).
- `minUppercase` (number): Minimum number of uppercase letters (default: 1).
- `minLowercase` (number): Minimum number of lowercase letters (default: 1).
- `minNumbers` (number): Minimum number of digits (default: 1).
- `minSpecialChars` (number): Minimum number of special characters (default: 1).
- Returns: `PasswordValidationResult` - An object `{ valid: boolean; errors: string[] }`.
- `valid:` true if the password meets all criteria, false otherwise.
- `errors:` An array of strings, each describing a failed validation criterion.

`PasswordValidationOptions` Interface:
```ts
interface PasswordValidationOptions {
minLength?: number; // Default: 8
minUppercase?: number; // Default: 1
minLowercase?: number; // Default: 1
minNumbers?: number; // Default: 1
minSpecialChars?: number; // Default: 1
}
```
`PasswordValidationResult` Interface:
```ts
interface PasswordValidationResult {
valid: boolean; // True if all validation rules passed
errors: string[]; // Array of error messages if validation failed
}
```
`isUsername(username: string, options?: UsernameValidationOptions): UsernameValidationResult`
Validates a username based on configurable criteria, including length, allowed characters, and format.
- `username` (string): The username string to validate.
- `options` (object, optional): An object to customize validation criteria.
- `minLength` (number): Minimum total length of the username `(default: 3)`.
- `maxLength` (number): Maximum total length of the username `(default: 30)`.
- `allowSpaces` (boolean): Allow spaces within the username `(default: false)`.
- `allowDashes` (boolean): Allow hyphens - `(default: true)`.
- `allowUnderscores` (boolean): Allow underscores _ `(default: true)`.
- `allowPeriods` (boolean): Allow periods . `(default: true)`.
- `noLeadingTrailingSpecialChars` (boolean): Disallow special characters or spaces at the start or end `(default: true).
- `noConsecutiveSpecialChars` (boolean): Disallow two or more consecutive special characters like -- or __ `(default: true)`.
- `blacklist` (string[]): An array of usernames that are explicitly disallowed (case-insensitive) `(default: [])`.
- Returns: `UserNameValidationResult` - An object `{ valid: boolean; errors: string[] }`.
- valid: true if the userName meets all criteria, false otherwise.
- errors: An array of strings, each describing a failed validation criterion.

`UserNameValidationOptions` Interface:
```ts
interface UserNameValidationOptions {
minLength?: number;
maxLength?: number;
allowSpaces?: boolean;
allowDashes?: boolean;
allowUnderscores?: boolean;
allowPeriods?: boolean;
noLeadingTrailingSpecialChars?: boolean;
noConsecutiveSpecialChars?: boolean;
blacklist?: string[];
}
```
`UserNameValidationResult` Interface:
```ts
interface UserNameValidationResult {
valid: boolean;
errors: string[];
}
```
`isEqual(a: string, b: string): boolean`
- `a (string)`: The first value to compare.
- `b (string)`: The second value to compare.
- Returns: boolean - true if the two values are equal, false otherwise.

## πŸ§ͺ Running Tests
```
npm test
```
Uses Vitest for unit testing.

## πŸ“ Project Structure
```
src/
β”œβ”€β”€ isEmail.ts # Email validator
β”œβ”€β”€ isPhone.ts # Phone validator
β”œβ”€β”€ isPassworStrong.ts # Password validator
β”œβ”€β”€ isUsername.ts # userName validator
β”œβ”€β”€ isEqual.ts # equality comparison
└── index.ts # Exports

tests/
β”œβ”€β”€ email.test.ts
β”œβ”€β”€ isEqual.test.ts
β”œβ”€β”€ password.test.ts
β”œβ”€β”€ phone.test.ts
└── userName.test.ts
```

## ❓ Why this exists
There are many username validation libraries β€” but most either:
- lack of flexibility in character rules,
- don’t support Formik/Yup integration well,
- or don’t support things like blacklists or special character positioning.

yh-validator was built to provide strict, customizable username validation with minimal dependencies β€” usable in modern React forms or plain JavaScript.

## πŸ“„ License
MIT
This project is licensed under the [MIT License](https://github.com/huntergera/yh-validator/blob/master/LICENSE).

## πŸ“« Contact
Feel free to reach out if you have suggestions or need help integrating this package.

GitHub: [@huntergera](https://github.com/huntergera)

Email: [yuriihieorhiu@gmail.com](mailto:yuriihieorhiu@gmail.com)