A lightweight, flexible validation library for JavaScript that works in both browser and Node.js environments. https://www.npmjs.com/package/hakim
Hakim provides a powerful yet simple validation system that handles both string and numeric values with the same API. This is particularly useful for browser environments where form inputs are often strings even when representing numbers.
Key features:
- Unified validation for strings and numbers
- Composable validation rules for complex validations
- Flexible logic operators (AND/OR) for combining rules
- Extensible plugin system for custom validators
- Modern ES module format with browser and Node.js support
To install via npm:
npm install hakimImport Hakim in your JavaScript project:
// ESM import
import Hakim, { anyOf } from 'hakim';
// Or in browser with script tag
<script src="path/to/hakim.js"></script>The core concept of Hakim is simple:
const validator = new Hakim(rules);
validator.validate(value); // returns true or falseWhere rules is an array of validation rules, and each rule consists of a validator and an operand:
[{is: "number"}, {is: "integer"}]In the above example, is is the validator and "number" is the operand. Each rule is executed in order, and all rules must pass for the validation to succeed (AND logic by default).
- Unified validation for both numbers and strings
- Multiple rules can be combined to create complex validations
- Configurable logic operators (AND/OR) for rule processing
- Support for nested rule groups
Basic validation:
import Hakim from 'hakim';
// Validate an integer
new Hakim([{is: "number"}, {is: "integer"}]).validate(2); // true
new Hakim([{is: "number"}, {is: "integer"}]).validate("2"); // true
new Hakim([{is: "number"}, {is: "integer"}]).validate(2.5); // false
// Validate an email
new Hakim([{is: "email"}]).validate("[email protected]"); // trueUsing OR logic with anyOf:
import Hakim, { anyOf } from 'hakim';
// Value must be empty OR a number OR an email
new Hakim(anyOf([
{is: "empty"},
{is: "number"},
{is: "email"}
])).validate("[email protected]"); // trueNested rules:
// Must be empty OR (a number AND an integer)
new Hakim([
{is: "empty"},
[{is: "number"}, {is: "integer"}]
]).validate(""); // trueHakim provides a rich set of validators to create expressive validation rules:
| Validator | Description |
|---|---|
is |
Checks if a value matches a predefined entity type (e.g., number, email) |
isNot |
Negates the is validator |
equal |
Checks if a value equals the operand (uses ==) |
match |
Tests if a string matches a regular expression pattern |
required |
Checks if a value is not empty |
| Validator | Description |
|---|---|
gt |
Greater than |
lt |
Less than |
goe |
Greater than or equal |
loe |
Less than or equal |
dplacesGt |
Decimal places greater than |
dplacesLt |
Decimal places less than |
dlengthOf |
Decimal places equals |
| Validator | Description |
|---|---|
lengthOf |
String length equals |
lengthGt |
String length greater than |
lengthLt |
String length less than |
beginWithSub |
String begins with a substring |
notBeginWithSub |
String does not begin with a substring |
hasString |
String contains a substring |
| Validator | Description |
|---|---|
are |
All characters in string belong to a character set |
exists |
String contains characters from a character set |
startWithSet |
String starts with a character from a set |
notStartWithSet |
String does not start with a character from a set |
Entity types are used with the is and isNot validators to check if a value represents a specific type of data:
| Entity | Description |
|---|---|
number |
Validates if value is a number (or string representing a number) |
integer |
Validates if value is an integer |
decimal |
Validates if value is a decimal number |
positive |
Validates if value is a positive number |
negative |
Validates if value is a negative number |
email |
Validates if value is a valid email address |
empty |
Validates if value is "", null, undefined or [] |
ip |
Validates if value is a valid IP address |
url |
Validates if value is a valid URL |
string |
Validates if value is a string |
Example:
// Check if value is a number
new Hakim([{is: "number"}]).validate("123"); // true
// Check if value is an email
new Hakim([{is: "email"}]).validate("[email protected]"); // trueCharacter sets are used with the are, exists, startWithSet, and notStartWithSet validators:
| Character Set | Description |
|---|---|
latin |
Latin letters (a-z, A-Z) |
enLetter |
English letters (same as latin) |
digit |
Numeric digits (0-9) |
Example:
// Check if all characters are digits
new Hakim([{are: "digit"}]).validate("12345"); // true
new Hakim([{are: "digit"}]).validate("123a5"); // false
// Check if string contains any digits
new Hakim([{exists: "digit"}]).validate("abc123"); // trueBy default, Hakim processes rules with AND logic (all rules must pass), but you can change this using the anyOf function for OR logic:
All rules must pass for validation to succeed:
// Value must be a number AND an integer
new Hakim([{is: "number"}, {is: "integer"}]).validate("123"); // true
new Hakim([{is: "number"}, {is: "integer"}]).validate("123.4"); // falseUsing anyOf to enable OR logic (any rule passing means validation success):
import Hakim, { anyOf } from 'hakim';
// Value can be either empty OR a number
new Hakim(anyOf([
{is: "empty"},
{is: "number"}
])).validate(""); // true
new Hakim(anyOf([
{is: "empty"},
{is: "number"}
])).validate("123"); // trueYou can create complex validations by nesting rule groups:
// Must be either empty OR (a number AND positive)
new Hakim([
{is: "empty"},
[{is: "number"}, {is: "positive"}]
]).validate("123"); // true
// Must be (a number AND an integer) OR (a string AND not empty)
new Hakim(anyOf([
[{is: "number"}, {is: "integer"}],
[{is: "string"}, {required: true}]
])).validate("hello"); // trueYou can extend Hakim with custom validators using the extend method:
// Add a 'binary' entity type
Hakim.extend('something', 'binary', function(value) {
return /^[01]+$/.test(value);
});
// Now you can use it in validation
new Hakim([{is: "binary"}]).validate("1010"); // true
new Hakim([{is: "binary"}]).validate("1234"); // false// Add a 'hex' character set
Hakim.extend('characterSets', 'hex', function(char) {
return /^[0-9a-fA-F]$/.test(char);
});
// Now you can use it in validation
new Hakim([{are: "hex"}]).validate("a1f5"); // trueHakim is designed to work in all modern browsers. The library is provided as both ES modules and CommonJS formats:
built/hakim.js- ES module formatbuilt/hakim.cjs- CommonJS format
The library includes comprehensive test cases for both browser and Node.js environments:
# Run tests in Node.js
npm run test:node
# Run tests in browser
npm run test:browserThis project is licensed under the LGPL-3.0-or-later