# enforce-js

> Data enforcer syntax for verbose validations

Latest version **1.2.9** (published 2018-10-26) · MIT license · 0 weekly downloads

## Install

```sh
npm install enforce-js
pnpm add enforce-js
yarn add enforce-js
bun add enforce-js
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.2.9 |
| Published | 2018-10-26 |
| First published | 2018-02-09 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 1 |
| Unpacked size | 74.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Jake Josol |
| Maintainers | jiggermix |
| Keywords | enforce, validations |

## Links

- npm: https://www.npmjs.com/package/enforce-js
- Repository: https://github.com/dividedbyzeroco/enforce-js
- Homepage: https://github.com/dividedbyzeroco/enforce-js#readme
- Issues: https://github.com/dividedbyzeroco/enforce-js/issues
- npm.io page: https://npm.io/package/enforce-js

## Dependencies (1)

- [moment-timezone](https://npm.io/package/moment-timezone.md) ^0.5.4

## Alternatives

- [@sindresorhus/slugify](https://npm.io/package/@sindresorhus/slugify.md) — 3.7M weekly downloads
- [solid-js](https://npm.io/package/solid-js.md) — 2.7M weekly downloads
- [expo-glass-effect](https://npm.io/package/expo-glass-effect.md) — 2.5M weekly downloads
- [nanoassert](https://npm.io/package/nanoassert.md) — 780.8K weekly downloads
- [@ffmpeg/ffmpeg](https://npm.io/package/@ffmpeg/ffmpeg.md) — 529.5K weekly downloads

## Recent versions

- 1.2.9 (latest) — 2018-10-26
- 1.2.8 — 2018-10-26
- 1.2.7 — 2018-05-24
- 1.2.6 — 2018-02-20
- 1.2.5 — 2018-02-14
- 1.2.2 — 2018-02-14
- 1.2.1 — 2018-02-12
- 1.2.0 — 2018-02-12
- 1.1.0 — 2018-02-09
- 1.0.10-readme — 2018-02-09
- 1.0.10 — 2018-02-09
- 1.0.9 — 2018-02-09
- 1.0.8 — 2018-02-09
- 1.0.7 — 2018-02-09
- 1.0.6 — 2018-02-09
- … 6 more at https://npm.io/package/enforce-js/versions

## 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
```

---
_Source: https://npm.io/package/enforce-js · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
