{"id":23468257,"url":"https://github.com/dwtechs/antity.js","last_synced_at":"2026-03-14T22:43:41.386Z","repository":{"id":268599073,"uuid":"904719855","full_name":"DWTechs/Antity.js","owner":"DWTechs","description":"Open source library for easy entity management","archived":false,"fork":false,"pushed_at":"2026-03-09T19:54:00.000Z","size":379,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-10T01:10:48.238Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DWTechs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-17T12:30:36.000Z","updated_at":"2026-03-09T19:54:03.000Z","dependencies_parsed_at":"2024-12-17T19:30:34.433Z","dependency_job_id":"7ab53521-7ab7-4559-b533-5c73f6b10715","html_url":"https://github.com/DWTechs/Antity.js","commit_stats":null,"previous_names":["dwtechs/antity.js"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/DWTechs/Antity.js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FAntity.js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FAntity.js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FAntity.js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FAntity.js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DWTechs","download_url":"https://codeload.github.com/DWTechs/Antity.js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FAntity.js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30520755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-14T19:51:21.629Z","status":"ssl_error","status_checked_at":"2026-03-14T19:51:12.959Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-24T13:50:29.802Z","updated_at":"2026-03-14T22:43:41.378Z","avatar_url":"https://github.com/DWTechs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n[![License: MIT](https://img.shields.io/npm/l/@dwtechs/antity.svg?color=brightgreen)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40dwtechs%2Fantity.svg)](https://www.npmjs.com/package/@dwtechs/antity)\n[![last version release date](https://img.shields.io/github/release-date/DWTechs/Antity.js)](https://www.npmjs.com/package/@dwtechs/antity)\n![Jest:coverage](https://img.shields.io/badge/Jest:coverage-72%25-brightgreen.svg)\n\n- [Synopsis](#synopsis)\n- [Support](#support)\n- [Installation](#installation)\n- [Usage](#usage)\n- [API Reference](#api-reference)\n- [Contributors](#contributors)\n- [Stack](#stack)\n\n\n## Synopsis\n\n**[Antity.js](https://github.com/DWTechs/Antity.js)** is an Open source library for easy entity management.\n\n- 🪶 Very lightweight\n- 🧪 Thoroughly tested\n- 🚚 Shipped as EcmaScrypt module\n- 📝 Written in Typescript\n\n\n## Support\n\n- node: 22\n\nThis is the oldest targeted versions. The library should work properly on older versions of Node.js but we do not support it officially.  \n\n\n## Installation\n\n```bash\n$ npm i @dwtechs/antity\n```\n\n\n## Usage\n\n\n```javascript\n\nimport { Entity } from \"@dwtechs/antity\";\nimport { normalizeName, normalizeNickname } from \"@dwtechs/checkard\";\n\nconst entity = new Entity(\"consumers\", [\n  {\n    key: \"id\",\n    type: \"integer\",\n    min: 0,\n    max: 120,\n    isTypeChecked: true,\n    requiredFor: [\"PUT\"],\n    isPrivate: true,\n    sanitizer: null,\n    normalizer: null,\n    validator: null,\n  },\n  {\n    key: \"firstName\",\n    type: \"string\",\n    min: 0,\n    max: 255,\n    isTypeChecked: true,\n    requiredFor: [\"PUT\"],\n    isPrivate: true,\n    sanitizer: null,\n    normalizer: normalizeName,\n    validator: null,\n  },\n  {\n    key: \"lastName\",\n    type: \"string\",\n    min: 0,\n    max: 255,\n    isTypeChecked: true,\n    requiredFor: [\"PUT\"],\n    isPrivate: true,\n    sanitizer: null,\n    normalizer: normalizeName,\n    validator: null,\n  },\n  {\n    key: \"nickname\",\n    type: \"string\",\n    min: 0,\n    max: 255,\n    isTypeChecked: true,\n    requiredFor: [\"PUT\"],\n    isPrivate: true,\n    sanitizer: null,\n    normalizer: normalizeNickname,\n    validator: null,\n  },\n]);\n\n// add a consumer. Used when logging in from user service\nrouter.post(\"/\", entity.normalizeArray, entity.validateArray, ...);\n// or use check method to normalize and validate array at once\nrouter.put(\"/\", entity.check, ...);\n\n```\n\n## API Reference\n\n\n```javascript\n\ntype Type = \n  \"boolean\" |\n  \"string\" |\n  \"number\" |\n  \"integer\" |\n  \"float\" |\n  \"even\" |\n  \"odd\" |\n  \"positive\" |\n  \"negative\" |\n  \"powerOfTwo\" |\n  \"ascii\" |\n  \"array\" |\n  \"jwt\" |\n  \"symbol\" |\n  \"password\" |\n  \"email\" |\n  \"regex\" |\n  \"json\" |\n  \"ipAddress\" |\n  \"slug\" |\n  \"hexadecimal\" |\n  \"date\" |\n  \"timestamp\" |\n  \"function\" |\n  \"htmlElement\" |\n  \"htmlEventAttribute\" |\n  \"node\" |\n  \"object\";\n            \ntype Method = \"PATCH\" | \"PUT\" | \"POST\";\n\nclass Property {\n  key: string;\n  type: Type;\n  min: number | Date | null;\n  max: number | Date | null;\n  requiredFor: Method[];\n  isPrivate: boolean;\n  isTypeChecked: boolean;\n  sanitizer: Function | null;\n  normalizer: Function | null;\n  validator: Function | null;\n};\n\nclass Entity {\n  constructor(name: string, properties: Property[]);\n  get name(): string;\n  get privateProps(): string[];\n  get properties(): Property[];\n  set name(name: string);\n  \n  /**\n   * Returns a single property object matching the given key.\n   *\n   * - Searches the entity's properties for a property with the specified key\n   * - Useful for dynamic validation, normalization, or documentation\n   *\n   * @param {string} key - The property key to look up\n   * @returns {Property | undefined} The Property object if found, otherwise undefined\n   *\n   * **Input Properties Required:**\n   * - `key` (string) - Property key to look up\n   *\n   * **Output Properties:**\n   * - Property object matching the key, or undefined if not found\n   *\n   * @example\n   * ```typescript\n   * const prop = entity.getProp('firstName');\n   * // prop contains the Property object for 'firstName' or undefined\n   * ```\n   */\n  getProp(key: string): Property | undefined;\n\n  /**\n   * Returns all properties configured for a given REST method.\n   *\n   * - Filters the entity's properties by the specified method (e.g., 'POST', 'GET')\n   * - Useful for dynamic validation, normalization, or documentation\n   *\n   * @param {Method} method - The REST method to filter properties by (e.g., 'POST', 'GET')\n   * @returns {Property[]} Array of Property objects associated with the method\n   *\n   * **Input Properties Required:**\n   * - `method` (string) - REST method to filter by\n   *\n   * **Output Properties:**\n   * - Array of Property objects matching the method\n   *\n   * @example\n   * ```typescript\n   * const postProps = entity.getPropsByMethod('POST');\n   * // postProps contains all properties relevant for POST requests\n   * ```\n   */\n  getPropsByMethod(method: Method): Property[];\n  \n  /**\n   * Normalizes an array of records by applying sanitization and normalization\n   * rules defined in the properties of the class.\n   *\n   * - Applies sanitization if `sanitize: true`\n   * - Applies normalization if `normalize: true`\n   * - Mutates req.body.rows or req.body with sanitized/normalized values\n   * - Calls next(error) on failure, next() on success\n   *\n   * @param {Request} req - Express request object containing rows\n   * @param {Response} _res - Express response object (not used)\n   * @param {NextFunction} next - Express next function\n   *\n   * @returns {void}\n   *\n   * **Input Properties Required:**\n   * - `req.body.rows` (array) or `req.body` (array) - Array of objects to normalize\n   * - Each property config can specify sanitize, normalize, etc.\n   *\n   * **Output Properties:**\n   * - Mutates array with sanitized/normalized values\n   * - Calls next(error) if normalization fails, next() if all pass\n   *\n   * @example\n   * ```typescript\n   * router.post('/entities', entity.normalizeArray, (req, res) =\u003e {\n   *   // req.body.rows are now sanitized and normalized\n   *   res.json({ success: true });\n   * });\n   * ```\n   */\n  normalizeArray: (req: Request, _res: Response, next: NextFunction) =\u003e void;\n  \n  /**\n   * Normalizes a single record by applying sanitization and normalization\n   * rules defined in the properties of the class.\n   *\n   * - Applies sanitization if `sanitize: true`\n   * - Applies normalization if `normalize: true`\n   * - Mutates req.body with sanitized/normalized values\n   * - Calls next(error) on failure, next() on success\n   *\n   * @param {Request} req - Express request object containing a single record\n   * @param {Response} _res - Express response object (not used)\n   * @param {NextFunction} next - Express next function\n   *\n   * @returns {void}\n   *\n   * **Input Properties Required:**\n   * - `req.body` (object) - Single object to normalize\n   * - Each property config can specify sanitize, normalize, etc.\n   *\n   * **Output Properties:**\n   * - Mutates `req.body` with sanitized/normalized values\n   * - Calls next(error) if normalization fails, next() if success\n   *\n   * @example\n   * ```typescript\n   * router.post('/entity', entity.normalizeOne, (req, res) =\u003e {\n   *   // req.body is now sanitized and normalized\n   *   res.json({ success: true });\n   * });\n   * ```\n   */\n  normalizeOne: (req: Request, _res: Response, next: NextFunction) =\u003e void;\n  \n  /**\n   * Validates an array of rows according to property config and HTTP method.\n   *\n   * - Checks required properties and validates values\n   * - Calls next(error) on failure, next() on success\n   *\n   * @param {Request} req - Express request object containing rows\n   * @param {Response} _res - Express response object (not used)\n   * @param {NextFunction} next - Express next function\n   *\n   * @returns {void}\n   *\n   * **Input Properties Required:**\n   * - `req.body.rows` (array) or `req.body` (array) - Array of objects to validate\n   * - Each property config can specify validate, required, etc.\n   *\n   * **Output Properties:**\n   * - Calls next(error) if any row fails validation, next() if all pass\n   *\n   * @example\n   * ```typescript\n   * router.post('/entities', entity.validateArray, (req, res) =\u003e {\n   *   // req.body.rows are now validated\n   *   res.json({ success: true });\n   * });\n   * ```\n   */\n  validateArray: (req: Request, _res: Response, next: NextFunction) =\u003e void;\n  \n  /**\n   * Validates a single record according to property config and HTTP method.\n   *\n   * - Checks required properties and validates values\n   * - Calls next(error) on failure, next() on success\n   *\n   * @param {Request} req - Express request object containing a single record\n   * @param {Response} _res - Express response object (not used)\n   * @param {NextFunction} next - Express next function\n   *\n   * @returns {void}\n   *\n   * **Input Properties Required:**\n   * - `req.body` (object) - Single object to validate\n   * - Each property config can specify validate, required, etc.\n   *\n   * **Output Properties:**\n   * - Calls next(error) if validation fails, next() if success\n   *\n   * @example\n   * ```typescript\n   * router.post('/entity', entity.validateOne, (req, res) =\u003e {\n   *   // req.body is now validated\n   *   res.json({ success: true });\n   * });\n   * ```\n   */\n  validateOne: (req: Request, _res: Response, next: NextFunction) =\u003e void;\n\n```\n**normalizeArray()**, **normalizeOne()**, **validateArray()**, and **validateOne()** methods are made to be used as Express.js middlewares.\n\n- **normalizeArray()** and **validateArray()** will look for data in the **req.body.rows** parameter or **req.body** as an array.\n- **normalizeOne()** and **validateOne()** will look for data in the **req.body** parameter as a single object.\n\n\n### Password validation\n\nPassword validation will have the following options by default : \n\n```javascript\nconst PWD_MIN_LENGTH = 9;\nconst PWD_MAX_LENGTH = 20;\nconst PWD_NUMBERS = true; // password must contain a number\nconst PWD_UPPERCASE = true; // password must contain an uppercase letter\nconst PWD_LOWERCASE = true; // password must contain a lowercase letter\nconst PWD_SYMBOLS = true; //  password must contain at least one of the following symbol character : !@#%*_-+=:?\u003e\u003c./()\n```\n\n#### Environment variables\n\nYou can update password default validator by setting the following environment variables :\n\n```javascript\n  PWD_MIN_LENGTH_POLICY,\n  PWD_MAX_LENGTH_POLICY,\n  PWD_NUMBERS_POLICY,\n  PWD_UPPERCASE_POLICY,\n  PWD_LOWERCASE_POLICY,\n  PWD_SYMBOLS_POLICY\n```\n\nProperties **min** and **max** of the password properties will override default and environement variable if set.\n\n\n### Available options for a property\n\nAny of these can be passed into the options object for each function.\n\n| Name            | Type                     |               Description                        |  Default value  |  \n| :-------------- | :----------------------- | :----------------------------------------------- | :-------------- |\n| key             | string                   | Name of the property                             |\n| type            | Type                     | Type of the property                             |\n| min             | number \\| Date           | Minimum value if applicable                      | 0 \\| 1900-01-01\n| max             | number \\| Date           | Maximum value if applicable                      | 999999999 \\| 2200-12-31\n| requiredFor     | Methods[]                | Property is required for the listed methods only | [ \"POST\", \"PUT\", \"PATCH\" ]\n| isPrivate       | boolean                  | Property should not be sent in the response      | false\n| isTypeChecked   | boolean                  | Strict type check at validation                  | false\n| sanitizer       | ((v:any) =\u003e any) \\| null | Custom sanitizer function                        | null\n| normalizer      | ((v:any) =\u003e any) \\| null | Custom Normalizer function                       | null\n| validator       | ((v:any, min:number, max:number, typeCheck:boolean) =\u003e any) \\| null         | Custom validator | null\n\n* *Min and max parameters are not used for boolean type*\n* *TypeCheck Parameter is not used for boolean, string and array types*\n\n\n## Contributors\n\nAntity.js is still in development and we would be glad to get all the help you can provide.\nTo contribute please read **[contributor.md](https://github.com/DWTechs/Antity.js/blob/main/contributor.md)** for detailed installation guide.\n\n\n## Stack\n\n| Purpose         |                    Choice                    |                                                     Motivation |\n| :-------------- | :------------------------------------------: | -------------------------------------------------------------: |\n| repository      |        [Github](https://github.com/)         |     hosting for software development version control using Git |\n| package manager |     [npm](https://www.npmjs.com/get-npm)     |                                default node.js package manager |\n| language        | [TypeScript](https://www.typescriptlang.org) | static type checking along with the latest ECMAScript features |\n| module bundler  |      [Rollup](https://rollupjs.org)          |                        advanced module bundler for ES6 modules |\n| unit testing    |          [Jest](https://jestjs.io/)          |                  delightful testing with a focus on simplicity |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwtechs%2Fantity.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdwtechs%2Fantity.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwtechs%2Fantity.js/lists"}