https://github.com/dividedbyzeroco/enforce-js
Data enforcer syntax for verbose validations
https://github.com/dividedbyzeroco/enforce-js
Last synced: 5 months ago
JSON representation
Data enforcer syntax for verbose validations
- Host: GitHub
- URL: https://github.com/dividedbyzeroco/enforce-js
- Owner: dividedbyzeroco
- Created: 2018-02-09T11:30:14.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2018-11-09T04:00:48.000Z (over 7 years ago)
- Last Synced: 2025-08-09T05:36:20.124Z (11 months ago)
- Language: TypeScript
- Size: 33.2 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# Enforce JS
Enforcing data validations through readable definitions
## Introduction
`enforce` is a data validation tool that allows you to assert rules on supplied variables and parameters, using a human-friendly format.
## Getting Started
To install `enforce`, run the following code in your npm project.
```javascript
npm install --save enforce-js
```
After installing, simply import the module.
```javascript
import enforce from 'enforce-js';
```
## Syntax
To `enforce` validation on a variable, simply follow the syntax below.
```javascript
enforce`${{ variable }} as dataType, rule1, rule2, ...`;
```
### Example
```javascript
// Validate a variable
const message = 'Hello, world!';
enforce`${{ message }} as a string, with 5 to 20 characters`; // ok
```
> NOTE: `enforce` uses double brackets as a shortcut to `{ variable: variable }`
## Regular Data Types
`enforce` supports primitive javascript data types, which by default, are __non-nullable__. To explictly define a variable to be nullable, use the `optional` keyword.
> NOTE: Non-nullable in `enforce` means the value can either be `undefined` or the specified data type. It cannot be a javascript `null` object.
- 'a string'
- 'a number'
- 'a boolean'
- 'an array'
- 'an object'
- 'a function'
- 'an optional string'
- 'an optional number'
- 'an optional boolean'
- 'an optional array'
- 'an optional object'
- 'an optional function'
- 'a value'
- 'any value'
## Rules
Additional rules can help further validate a supplied variable. If the below rules do not meet the requirements of what may be needed, you may use the `and matches REGEXP` rule in order to fill the gap, or you can try [Extending Rules](#extending-rules).
- 'with `MIN` to `MAX` characters' (MIN: number, MAX: number)
- 'with `MIN` or more characters' (MIN: number)
- 'with up to `MAX` characters' (MAX: number)
- 'greater than `MIN`' (MIN: number)
- 'greater than or equal to `MIN`' (MIN: number)
- 'less than `MAX`' (MAX: number)
- 'less than or equal to `MAX`' (MAX: number)
- 'and matches `REGEXP`' (REGEXP: regular expression)
## Validating Classes
`enforce` also supports validating class-type objects. To validate whether a supplied variable or parameter is an instance of a class, you can directly supply the class as a data type.
```javascript
class Animal { /* class definition */ }
const dog = new Animal();
enforce`${{ dog }} as an ${{ Animal }}`; // ok
class Dog extends Animal { /* class definition */ }
const corgi = new Dog();
enforce`${{ corgi }} as a ${{ Dog }}`; // ok
enforce`${{ corgi }} as an ${{ Animal }}`; // ok
enforce`${{ dog }} as a ${{ Dog }}`; // error!
```
## Catching Errors
By default, if a given parameter does not meet the rules provided, a `ValidationError` will be thrown with a message containing the original definition. To better handle the error, an additional `name` parameter is also supplied to let you know which parameter was invalid.
```javascript
const countingNumber = -1;
enforce`${{ countingNumber }} as a number, greater than or equal to 0`;
// OUTPUT
// error.message: 'countingNumber' must be a number, greater than or equal to 0
// error.name: countingNumber
```
The recommended approach is to have a try-catch block that retrieves the invalid parameter.
```javascript
import enforce, { ValidationError } from 'enforce-js';
try {
const countingNumber = -1;
enforce`${{ countingNumber }} as a number, greater than or equal to 0`;
}
catch(err) {
if(err instanceof ValidationError) {
console.error(`The error message was: ${err.message}, and the invalid parameter is: ${err.name}`);
}
}
```
> NOTE: `enforce` format is also validated and throws a `FormatError` when the supplied definition is invalid.
```javascript
import enforce, { FormatError } from 'enforce-js';
try {
const countingNumber = -1;
enforce`${{ countingNumber }} as a postive number, and is the square root of 4`;
}
catch(err) {
if(err instanceof FormatError) {
console.error(`The error message was: ${err.message}, and the invalid parameter is: ${err.name}`);
}
}
```
## Extending Rules
If you need additional rules currently not supported by `enforce`, you can extend the library by using the `.extend()` method.
```javascript
enforce.extend(REGEXP, VALIDATOR);
// REGEXP = Regular Expression matching the rule
// VALIDATOR = Function that will check if the supplied value is valid
```
### Example
```javascript
// Extend a new rule
enforce.extend(/^and is equal to \d{1,}$/i, (val, rule) => {
// e.g. rule == 'is equal to 5'
const number = parseInt(rule.slice(rule.lastIndexOf(' ')));
return val === number;
});
// Enforce the new rule
const thisNumber = 5;
enforce`${{ thisNumber }} as a number, and is equal to 5`;
```
## Examples
```javascript
// Import module
import enforce, { ValidationError } from 'enforce-js';
// Validate a variable
const message = 'Hello, world!';
enforce`${{ message }} as a string, with 5 to 20 characters`; // ok
// Validate function parameters
const register = ({ username, name, password, age, options }) => {
try {
enforce`${{ username }} as a string`;
enforce`${{ name }} as an optional string`;
enforce`${{ password }} as a string, with 6 to 8 characters`;
enforce`${{ password }} as a password, with 6 to 8 characters, and matches /^\\d{6,8}$/i`;
enforce`${{ age }} as a number, greater than 18`;
enforce`${{ options }} as an optional object`;
const { messages } = options;
enforce`${{ messages }} as a boolean`;
/* function definition */
}
catch(err) {
if(err instanceof ValidationError) {
return `Invalid Parameter: ${err.name}`;
}
}
}
// Use function
const result = register({
username: 'tardisblue', // ok
name: 'Amy Pond', // ok
password: '1234', // error!
age: 21 // ok
});
// result: `Invalid Parameter: password`
// Validate if an object is an instance of a class
class Post { /* class definition */ }
const post = new Post();
enforce`${{ post }} as a ${{ Post }}`; // ok
```