https://github.com/dwtechs/antity.js
Open source library for easy entity management
https://github.com/dwtechs/antity.js
Last synced: 3 months ago
JSON representation
Open source library for easy entity management
- Host: GitHub
- URL: https://github.com/dwtechs/antity.js
- Owner: DWTechs
- License: mit
- Created: 2024-12-17T12:30:36.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2026-03-09T19:54:00.000Z (3 months ago)
- Last Synced: 2026-03-10T01:10:48.238Z (3 months ago)
- Language: JavaScript
- Homepage:
- Size: 370 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://opensource.org/licenses/MIT)
[](https://www.npmjs.com/package/@dwtechs/antity)
[](https://www.npmjs.com/package/@dwtechs/antity)

- [Synopsis](#synopsis)
- [Support](#support)
- [Installation](#installation)
- [Usage](#usage)
- [API Reference](#api-reference)
- [Contributors](#contributors)
- [Stack](#stack)
## Synopsis
**[Antity.js](https://github.com/DWTechs/Antity.js)** is an Open source library for easy entity management.
- ๐ชถ Very lightweight
- ๐งช Thoroughly tested
- ๐ Shipped as EcmaScrypt module
- ๐ Written in Typescript
## Support
- node: 22
This is the oldest targeted versions. The library should work properly on older versions of Node.js but we do not support it officially.
## Installation
```bash
$ npm i @dwtechs/antity
```
## Usage
```javascript
import { Entity } from "@dwtechs/antity";
import { normalizeName, normalizeNickname } from "@dwtechs/checkard";
const entity = new Entity("consumers", [
{
key: "id",
type: "integer",
min: 0,
max: 120,
isTypeChecked: true,
requiredFor: ["PUT"],
isPrivate: true,
sanitizer: null,
normalizer: null,
validator: null,
},
{
key: "firstName",
type: "string",
min: 0,
max: 255,
isTypeChecked: true,
requiredFor: ["PUT"],
isPrivate: true,
sanitizer: null,
normalizer: normalizeName,
validator: null,
},
{
key: "lastName",
type: "string",
min: 0,
max: 255,
isTypeChecked: true,
requiredFor: ["PUT"],
isPrivate: true,
sanitizer: null,
normalizer: normalizeName,
validator: null,
},
{
key: "nickname",
type: "string",
min: 0,
max: 255,
isTypeChecked: true,
requiredFor: ["PUT"],
isPrivate: true,
sanitizer: null,
normalizer: normalizeNickname,
validator: null,
},
]);
// add a consumer. Used when logging in from user service
router.post("/", entity.normalizeArray, entity.validateArray, ...);
// or use check method to normalize and validate array at once
router.put("/", entity.check, ...);
```
## API Reference
```javascript
type Type =
"boolean" |
"string" |
"number" |
"integer" |
"float" |
"even" |
"odd" |
"positive" |
"negative" |
"powerOfTwo" |
"ascii" |
"array" |
"jwt" |
"symbol" |
"password" |
"email" |
"regex" |
"json" |
"ipAddress" |
"slug" |
"hexadecimal" |
"date" |
"timestamp" |
"function" |
"htmlElement" |
"htmlEventAttribute" |
"node" |
"object";
type Method = "PATCH" | "PUT" | "POST";
class Property {
key: string;
type: Type;
min: number | Date | null;
max: number | Date | null;
requiredFor: Method[];
isPrivate: boolean;
isTypeChecked: boolean;
sanitizer: Function | null;
normalizer: Function | null;
validator: Function | null;
};
class Entity {
constructor(name: string, properties: Property[]);
get name(): string;
get privateProps(): string[];
get properties(): Property[];
set name(name: string);
/**
* Returns a single property object matching the given key.
*
* - Searches the entity's properties for a property with the specified key
* - Useful for dynamic validation, normalization, or documentation
*
* @param {string} key - The property key to look up
* @returns {Property | undefined} The Property object if found, otherwise undefined
*
* **Input Properties Required:**
* - `key` (string) - Property key to look up
*
* **Output Properties:**
* - Property object matching the key, or undefined if not found
*
* @example
* ```typescript
* const prop = entity.getProp('firstName');
* // prop contains the Property object for 'firstName' or undefined
* ```
*/
getProp(key: string): Property | undefined;
/**
* Returns all properties configured for a given REST method.
*
* - Filters the entity's properties by the specified method (e.g., 'POST', 'GET')
* - Useful for dynamic validation, normalization, or documentation
*
* @param {Method} method - The REST method to filter properties by (e.g., 'POST', 'GET')
* @returns {Property[]} Array of Property objects associated with the method
*
* **Input Properties Required:**
* - `method` (string) - REST method to filter by
*
* **Output Properties:**
* - Array of Property objects matching the method
*
* @example
* ```typescript
* const postProps = entity.getPropsByMethod('POST');
* // postProps contains all properties relevant for POST requests
* ```
*/
getPropsByMethod(method: Method): Property[];
/**
* Normalizes an array of records by applying sanitization and normalization
* rules defined in the properties of the class.
*
* - Applies sanitization if `sanitize: true`
* - Applies normalization if `normalize: true`
* - Mutates req.body.rows or req.body with sanitized/normalized values
* - Calls next(error) on failure, next() on success
*
* @param {Request} req - Express request object containing rows
* @param {Response} _res - Express response object (not used)
* @param {NextFunction} next - Express next function
*
* @returns {void}
*
* **Input Properties Required:**
* - `req.body.rows` (array) or `req.body` (array) - Array of objects to normalize
* - Each property config can specify sanitize, normalize, etc.
*
* **Output Properties:**
* - Mutates array with sanitized/normalized values
* - Calls next(error) if normalization fails, next() if all pass
*
* @example
* ```typescript
* router.post('/entities', entity.normalizeArray, (req, res) => {
* // req.body.rows are now sanitized and normalized
* res.json({ success: true });
* });
* ```
*/
normalizeArray: (req: Request, _res: Response, next: NextFunction) => void;
/**
* Normalizes a single record by applying sanitization and normalization
* rules defined in the properties of the class.
*
* - Applies sanitization if `sanitize: true`
* - Applies normalization if `normalize: true`
* - Mutates req.body with sanitized/normalized values
* - Calls next(error) on failure, next() on success
*
* @param {Request} req - Express request object containing a single record
* @param {Response} _res - Express response object (not used)
* @param {NextFunction} next - Express next function
*
* @returns {void}
*
* **Input Properties Required:**
* - `req.body` (object) - Single object to normalize
* - Each property config can specify sanitize, normalize, etc.
*
* **Output Properties:**
* - Mutates `req.body` with sanitized/normalized values
* - Calls next(error) if normalization fails, next() if success
*
* @example
* ```typescript
* router.post('/entity', entity.normalizeOne, (req, res) => {
* // req.body is now sanitized and normalized
* res.json({ success: true });
* });
* ```
*/
normalizeOne: (req: Request, _res: Response, next: NextFunction) => void;
/**
* Validates an array of rows according to property config and HTTP method.
*
* - Checks required properties and validates values
* - Calls next(error) on failure, next() on success
*
* @param {Request} req - Express request object containing rows
* @param {Response} _res - Express response object (not used)
* @param {NextFunction} next - Express next function
*
* @returns {void}
*
* **Input Properties Required:**
* - `req.body.rows` (array) or `req.body` (array) - Array of objects to validate
* - Each property config can specify validate, required, etc.
*
* **Output Properties:**
* - Calls next(error) if any row fails validation, next() if all pass
*
* @example
* ```typescript
* router.post('/entities', entity.validateArray, (req, res) => {
* // req.body.rows are now validated
* res.json({ success: true });
* });
* ```
*/
validateArray: (req: Request, _res: Response, next: NextFunction) => void;
/**
* Validates a single record according to property config and HTTP method.
*
* - Checks required properties and validates values
* - Calls next(error) on failure, next() on success
*
* @param {Request} req - Express request object containing a single record
* @param {Response} _res - Express response object (not used)
* @param {NextFunction} next - Express next function
*
* @returns {void}
*
* **Input Properties Required:**
* - `req.body` (object) - Single object to validate
* - Each property config can specify validate, required, etc.
*
* **Output Properties:**
* - Calls next(error) if validation fails, next() if success
*
* @example
* ```typescript
* router.post('/entity', entity.validateOne, (req, res) => {
* // req.body is now validated
* res.json({ success: true });
* });
* ```
*/
validateOne: (req: Request, _res: Response, next: NextFunction) => void;
```
**normalizeArray()**, **normalizeOne()**, **validateArray()**, and **validateOne()** methods are made to be used as Express.js middlewares.
- **normalizeArray()** and **validateArray()** will look for data in the **req.body.rows** parameter or **req.body** as an array.
- **normalizeOne()** and **validateOne()** will look for data in the **req.body** parameter as a single object.
### Password validation
Password validation will have the following options by default :
```javascript
const PWD_MIN_LENGTH = 9;
const PWD_MAX_LENGTH = 20;
const PWD_NUMBERS = true; // password must contain a number
const PWD_UPPERCASE = true; // password must contain an uppercase letter
const PWD_LOWERCASE = true; // password must contain a lowercase letter
const PWD_SYMBOLS = true; // password must contain at least one of the following symbol character : !@#%*_-+=:?><./()
```
#### Environment variables
You can update password default validator by setting the following environment variables :
```javascript
PWD_MIN_LENGTH_POLICY,
PWD_MAX_LENGTH_POLICY,
PWD_NUMBERS_POLICY,
PWD_UPPERCASE_POLICY,
PWD_LOWERCASE_POLICY,
PWD_SYMBOLS_POLICY
```
Properties **min** and **max** of the password properties will override default and environement variable if set.
### Available options for a property
Any of these can be passed into the options object for each function.
| Name | Type | Description | Default value |
| :-------------- | :----------------------- | :----------------------------------------------- | :-------------- |
| key | string | Name of the property |
| type | Type | Type of the property |
| min | number \| Date | Minimum value if applicable | 0 \| 1900-01-01
| max | number \| Date | Maximum value if applicable | 999999999 \| 2200-12-31
| requiredFor | Methods[] | Property is required for the listed methods only | [ "POST", "PUT", "PATCH" ]
| isPrivate | boolean | Property should not be sent in the response | false
| isTypeChecked | boolean | Strict type check at validation | false
| sanitizer | ((v:any) => any) \| null | Custom sanitizer function | null
| normalizer | ((v:any) => any) \| null | Custom Normalizer function | null
| validator | ((v:any, min:number, max:number, typeCheck:boolean) => any) \| null | Custom validator | null
* *Min and max parameters are not used for boolean type*
* *TypeCheck Parameter is not used for boolean, string and array types*
## Contributors
Antity.js is still in development and we would be glad to get all the help you can provide.
To contribute please read **[contributor.md](https://github.com/DWTechs/Antity.js/blob/main/contributor.md)** for detailed installation guide.
## Stack
| Purpose | Choice | Motivation |
| :-------------- | :------------------------------------------: | -------------------------------------------------------------: |
| repository | [Github](https://github.com/) | hosting for software development version control using Git |
| package manager | [npm](https://www.npmjs.com/get-npm) | default node.js package manager |
| language | [TypeScript](https://www.typescriptlang.org) | static type checking along with the latest ECMAScript features |
| module bundler | [Rollup](https://rollupjs.org) | advanced module bundler for ES6 modules |
| unit testing | [Jest](https://jestjs.io/) | delightful testing with a focus on simplicity |