{"id":16823369,"url":"https://github.com/digitalbrainjs/define-accessor2","last_synced_at":"2025-09-10T17:45:50.100Z","repository":{"id":35114116,"uuid":"208443067","full_name":"DigitalBrainJS/define-accessor2","owner":"DigitalBrainJS","description":"Define feature-rich accessors/properties for your classes","archived":false,"fork":false,"pushed_at":"2023-01-05T16:20:00.000Z","size":850,"stargazers_count":1,"open_issues_count":11,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-12T01:24:57.094Z","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DigitalBrainJS.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-14T13:18:35.000Z","updated_at":"2022-12-13T18:23:55.000Z","dependencies_parsed_at":"2023-01-15T14:06:52.514Z","dependency_job_id":null,"html_url":"https://github.com/DigitalBrainJS/define-accessor2","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalBrainJS%2Fdefine-accessor2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalBrainJS%2Fdefine-accessor2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalBrainJS%2Fdefine-accessor2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalBrainJS%2Fdefine-accessor2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DigitalBrainJS","download_url":"https://codeload.github.com/DigitalBrainJS/define-accessor2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247318746,"owners_count":20919483,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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-10-13T11:07:47.977Z","updated_at":"2025-04-05T10:14:41.549Z","avatar_url":"https://github.com/DigitalBrainJS.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# define-accessor2\r\n[![Build Status](https://travis-ci.com/DigitalBrainJS/define-accessor2.svg?branch=master)](https://travis-ci.com/DigitalBrainJS/define-accessor2)\r\n[![](https://badgen.net/npm/license/define-accessor2)](https://unpkg.com/define-accessor2/dist/define-accessor2.umd.js)\r\n[![Coverage Status](https://coveralls.io/repos/github/DigitalBrainJS/define-accessor2/badge.svg?branch=master)](https://coveralls.io/github/DigitalBrainJS/define-accessor2?branch=master)\r\n[![](https://badgen.net/github/issues/DigitalBrainJS/define-accessor2)](https://github.com/DigitalBrainJS/define-accessor2/issues)\r\n[![](https://badgen.net/github/stars/DigitalBrainJS/define-accessor2)](https://github.com/DigitalBrainJS/define-accessor2/stargazers)\r\n\r\n:star: Define feature-rich properties using decorators or plain functions. An extended version of Object.defineProperty :star:\r\n\r\n# Features\r\n- no dependencies\r\n- supports decorators for methods and class properties\r\n- supports legacy and current draft of decorator specification\r\n- lazy properties\r\n- cached properties - cache the value returned by the accessor getter. Cached value can be flushed later\r\n- validation hook\r\n- Joi validation out of the box\r\n- built-in basic type system (see [Built-in types](#built-in-types))\r\n- automatically flushes getter cache after changing related properties\r\n- defining custom validators\r\n- isolated contexts to define validators in a local scope\r\n- chaining methods - can create chaining methods like get**PropName** and set**PropName**\r\n- type predicates (isNumber, isNull etc)\r\n\r\n## Installation\r\n\r\nInstall for node.js using npm/yarn:\r\n\r\n``` bash\r\n$ npm install define-property2 --save\r\n```\r\n\r\n``` bash\r\n$ yarn add define-property2\r\n```\r\n\r\n````javascript\r\nconst {defineAccessor}= require('define-accessor2');\r\n````\r\n## Playground\r\n\r\n1) Clone `https://github.com/DigitalBrainJS/define-accessor2.git` repo\r\n2) Run `npm install` to install dev-dependencies\r\n3) Open `sandbox/sandbox.js` file with a basic example of using library decorators\r\n4) Run this file using `npm run sandbox` or `npm run sandbox:watch` command to see the result\r\n\r\n## Usage examples\r\n\r\nA basic example of using library decorators (with [plugin-proposal-decorators](https://babeljs.io/docs/en/babel-plugin-proposal-decorators)\r\nand [plugin-proposal-class-properties](https://babeljs.io/docs/en/babel-plugin-proposal-class-properties) babel plugins):\r\n````javascript\r\nconst {type, string, number, array} = require(\"define-accessor2\");\r\n\r\nclass Cat {\r\n    @string\r\n    name = '';\r\n    @type(string | number)\r\n    foo = 123;\r\n    @array\r\n    bar = [];\r\n}\r\n\r\nconst cat = new Cat();\r\ncat.name = 'Lucky'; // Ok\r\ncat.foo = 123;\r\ncat.foo = '123';\r\ncat.bar = [1, 2, 3];\r\n\r\ncat.name = 123; // TypeError: Property name accepts String, but number given\r\ncat.foo = true; // TypeError: Property foo accepts String|Number, but boolean given\r\ncat.bar= {}; //Property bar accepts Array, but object given\r\n````\r\nMore complex:\r\n````javascript\r\nconst {type, cached, touches, validate, accessor, defineValidator, string}= require('define-accessor2');\r\nconst hash = require('object-hash');\r\nconst validator= require('validator');\r\nconst Joi= require('@hapi/joi');\r\n\r\n//import all methods as validators predicates\r\ndefineValidator(validator);\r\n\r\nclass Model{\r\n    // cached value\r\n    @cached\r\n    get sha(){\r\n        console.log('calc sha');\r\n        return hash(this);\r\n    }\r\n    // this prop affects 'sha' prop\r\n    @touches('sha')\r\n    @string\r\n    name= 'anonymous';\r\n\r\n    @touches('sha')\r\n    @type('number|string')\r\n    foo= 30;\r\n    // configure all the necessary accessor features in one decorator (recommended way)\r\n    @accessor({\r\n        touches: 'sha',\r\n        validate: 'isEmail'\r\n    })\r\n    email= '';\r\n    // Joi validator can be used out of the box for complex properties validation\r\n    @validate(Joi.array().items(Joi.string()))\r\n    labels= [];\r\n}\r\n\r\nconst model= new Model();\r\n\r\nconsole.log(model.name); // 'anonymous'\r\nconsole.log(model.sha); // calc sha\r\nconsole.log(model.sha); // just return the cached value\r\nmodel.name= 'admin';\r\nconsole.log(model.sha); // calc sha\r\nmodel.email= 'admin@google.com';\r\nconsole.log(model.sha);\r\nmodel.foo= true;\r\nmodel.labels= ['123'];\r\n````\r\nJust using plain functions without any decorators\r\n````javascript\r\n     const {defineAccessor, TYPE_NUMBER, TYPE_STRING}= require('define-accessor2');\r\n     const obj= {};\r\n\r\n     defineAccessor(obj, 'someProp', {\r\n         type: 'string|number'\r\n     });\r\n     //or using type bit mask\r\n     defineAccessor(obj, 'someProp', {\r\n         type: TYPE_STRING|TYPE_NUMBER\r\n     });\r\n````\r\nValidate with Joi:\r\n````javascript\r\n     const {defineAccessor}= require('define-accessor2');\r\n     const Joi = require('@hapi/joi');\r\n     const user= {};\r\n\r\n     defineAccessor(user, 'age', {\r\n        validate: Joi.number().integer().min(0).max(100),\r\n        set(newValue, prevValue){\r\n            //do some work\r\n            return newValue; //set newValue to the property age\r\n        }\r\n     });\r\n\r\n    user.age= 30; //ok, now age= 30\r\n    user.age= 150; //ValidationError: value (150) is not valid for property (age). Reason: \"value\" must be less than or equal to 100\r\n````\r\nCustom validator:\r\n````javascript\r\n     //import library and create a new context for a local validator definition\r\n     const {defineAccessor, defineValidator}= require('define-accessor2').newContext();\r\n     const validator= require('validator');\r\n     const model= {};\r\n\r\n    defineValidator({\r\n        mongoId: validator.isMongoId\r\n    });\r\n\r\n    defineAccessor(model, 'id', {\r\n        validate: 'mongoId'\r\n    });\r\n````\r\n````javascript\r\nconst {defineAccessor, flushAccessor}= require('define-accessor2');\r\nconst hash = require('object-hash');\r\n\r\nconst obj= {};\r\n\r\nconst normalize = (str)=\u003e str.replace(/^\\w/, (str)=\u003e str.toUpperCase());\r\n\r\nconst {_name}= defineAccessor(obj, {\r\n    hash: {\r\n        get(){\r\n            return hash(this);\r\n        },\r\n        cached: true\r\n    },\r\n    name: {\r\n        validate(value, {reject, set}){\r\n            typeof value!=='string' \u0026\u0026 reject('must be a string');\r\n            value= value.trim();\r\n            !/^[a-zA-Z]+$/.test(value) \u0026\u0026 reject('only a-zA-Z allowed');\r\n            // alternative way to reject\r\n            if( value.length\u003c= 3) return 'length should be greater than 3';\r\n            // returning other values than 'true' and 'undefined' treated, as rejection,\r\n            // strings are considered as rejection reason\r\n            set(value); // change the value\r\n        },\r\n        set: normalize,\r\n        touches: ['hash'],\r\n        value: 'Jon'\r\n    },\r\n\r\n    email: {\r\n        validate: validator.isEmail\r\n    }\r\n\r\n}, {prefix: '_'})\r\n\r\n````\r\n\r\n## Functional diagram\r\n![Accessor functional diagram](https://github.com/DigitalBrainJS/define-accessor2/raw/master/public/accessor.png)\r\n\r\n## API\r\n\r\n\u003ca name=\"module_define-accessor2\"\u003e\u003c/a\u003e\n\n## define-accessor2\n\n* [define-accessor2](#module_define-accessor2)\n    * [module.exports](#exp_module_define-accessor2--module.exports) ⏏\n        * _instance_\n            * [.defineAccessor(obj, prop, [descriptor])](#module_define-accessor2--module.exports+defineAccessor) ⇒ \u003ccode\u003ePrivatePropKey\u003c/code\u003e\n            * [.defineAccessor(obj, props, [descriptor])](#module_define-accessor2--module.exports+defineAccessor) ⇒ \u003ccode\u003eArray.\u0026lt;PrivatePropKey\u0026gt;\u003c/code\u003e\n            * [.defineAccessor(obj, props, [options])](#module_define-accessor2--module.exports+defineAccessor) ⇒ \u003ccode\u003eObject.\u0026lt;PrivatePropKey\u0026gt;\u003c/code\u003e\n            * [.flushAccessor(obj, ...props)](#module_define-accessor2--module.exports+flushAccessor) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\n            * [.privateSymbol(obj, prop)](#module_define-accessor2--module.exports+privateSymbol) ⇒ \u003ccode\u003eSymbol\u003c/code\u003e \\| \u003ccode\u003enull\u003c/code\u003e\n            * [.defineValidator(name, fn)](#module_define-accessor2--module.exports+defineValidator) ⇒ \u003ccode\u003ethis\u003c/code\u003e\n            * [.defineValidator(validators)](#module_define-accessor2--module.exports+defineValidator)\n            * [.newContext()](#module_define-accessor2--module.exports+newContext) ⇒ \u003ccode\u003eContext\u003c/code\u003e\n            * [.accessor(accessorDescriptor)](#module_define-accessor2--module.exports+accessor) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.accessor([get], [set], [accessorDescriptor])](#module_define-accessor2--module.exports+accessor) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.lazy()](#module_define-accessor2--module.exports+lazy) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.cached()](#module_define-accessor2--module.exports+cached) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.chains()](#module_define-accessor2--module.exports+chains) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.type(type)](#module_define-accessor2--module.exports+type) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.validate(validator)](#module_define-accessor2--module.exports+validate) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.touches(props)](#module_define-accessor2--module.exports+touches) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.undefined()](#module_define-accessor2--module.exports+undefined) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.null()](#module_define-accessor2--module.exports+null) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.boolean()](#module_define-accessor2--module.exports+boolean) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.number()](#module_define-accessor2--module.exports+number) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.string()](#module_define-accessor2--module.exports+string) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.function()](#module_define-accessor2--module.exports+function) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.object()](#module_define-accessor2--module.exports+object) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.symbol()](#module_define-accessor2--module.exports+symbol) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.bigint()](#module_define-accessor2--module.exports+bigint) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.integer()](#module_define-accessor2--module.exports+integer) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.infinity()](#module_define-accessor2--module.exports+infinity) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.nan()](#module_define-accessor2--module.exports+nan) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.date()](#module_define-accessor2--module.exports+date) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.promise()](#module_define-accessor2--module.exports+promise) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.regexp()](#module_define-accessor2--module.exports+regexp) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.error()](#module_define-accessor2--module.exports+error) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.set()](#module_define-accessor2--module.exports+set) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n            * [.map()](#module_define-accessor2--module.exports+map) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n        * _inner_\n            * [~Context](#module_define-accessor2--module.exports..Context)\n            * [~SetterFunction](#module_define-accessor2--module.exports..SetterFunction) ⇒ \u003ccode\u003eany\u003c/code\u003e\n            * [~GetterFunction](#module_define-accessor2--module.exports..GetterFunction) ⇒ \u003ccode\u003eany\u003c/code\u003e\n            * [~ValidateFunction](#module_define-accessor2--module.exports..ValidateFunction) ⇒ \u003ccode\u003eBoolean\u003c/code\u003e\n            * [~PropertyKey](#module_define-accessor2--module.exports..PropertyKey) : \u003ccode\u003eString\u003c/code\u003e \\| \u003ccode\u003eSymbol\u003c/code\u003e\n            * [~PrivatePropKey](#module_define-accessor2--module.exports..PrivatePropKey) : \u003ccode\u003eSymbol\u003c/code\u003e\n            * [~AccessorDescriptor](#module_define-accessor2--module.exports..AccessorDescriptor) : \u003ccode\u003eObject\u003c/code\u003e\n            * [~ValidatorPredicate](#module_define-accessor2--module.exports..ValidatorPredicate) ⇒ \u003ccode\u003eBoolean\u003c/code\u003e\n            * [~BasicType](#module_define-accessor2--module.exports..BasicType) : \u003ccode\u003eNumber\u003c/code\u003e \\| \u003ccode\u003eString\u003c/code\u003e\n            * [~AssertionFunction](#module_define-accessor2--module.exports..AssertionFunction) ⇒ \u003ccode\u003eBoolean\u003c/code\u003e\n\n\u003ca name=\"exp_module_define-accessor2--module.exports\"\u003e\u003c/a\u003e\n\n### module.exports ⏏\nThe default library context. Call context.newContext() to\rreturn a new context inherited from the current.\rThis allows you to create an isolated library scope, which does not affect any others in case of defining a custom validator.\n\n**Kind**: Exported member  \n\u003ca name=\"module_define-accessor2--module.exports+defineAccessor\"\u003e\u003c/a\u003e\n\n#### module.exports.defineAccessor(obj, prop, [descriptor]) ⇒ \u003ccode\u003ePrivatePropKey\u003c/code\u003e\nDefines a single accessor\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| obj | \u003ccode\u003eObject\u003c/code\u003e | target object |\n| prop | \u003ccode\u003ePropertyKey\u003c/code\u003e | property key |\n| [descriptor] | \u003ccode\u003eAccessorDescriptor\u003c/code\u003e |  |\n\n**Example**  \n```js\ndefineAccessor(obj, \"age\", {\r    get(){\r        return 99;\r    }\r})\r\n     \n```\n\u003ca name=\"module_define-accessor2--module.exports+defineAccessor\"\u003e\u003c/a\u003e\n\n#### module.exports.defineAccessor(obj, props, [descriptor]) ⇒ \u003ccode\u003eArray.\u0026lt;PrivatePropKey\u0026gt;\u003c/code\u003e\nDefines several accessors with the same descriptor\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| obj | \u003ccode\u003eObject\u003c/code\u003e | target object |\n| props | \u003ccode\u003eArray.\u0026lt;PropertyKey\u0026gt;\u003c/code\u003e | properties list |\n| [descriptor] | \u003ccode\u003eAccessorDescriptor\u003c/code\u003e |  |\n\n**Example**  \n```js\ndefineAccessor(obj, [\"name\", \"surname\"], {\r    get(privateValue, propKey){\r        switch(propKey){\r            case 'name':\r             return 'John';\r            case 'surname':\r             return 'Connor';\r        }\r    }\r})\r\n     \n```\n\u003ca name=\"module_define-accessor2--module.exports+defineAccessor\"\u003e\u003c/a\u003e\n\n#### module.exports.defineAccessor(obj, props, [options]) ⇒ \u003ccode\u003eObject.\u0026lt;PrivatePropKey\u0026gt;\u003c/code\u003e\nDefines several accessors using hash map\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n**Returns**: \u003ccode\u003eObject.\u0026lt;PrivatePropKey\u0026gt;\u003c/code\u003e - object of private properties that refer to the defined accessors  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| obj | \u003ccode\u003eObject\u003c/code\u003e | target object |\n| props | \u003ccode\u003eObject.\u0026lt;PropertyKey\u0026gt;\u003c/code\u003e | properties hash map |\n| [options] | \u003ccode\u003eObject\u003c/code\u003e |  |\n| [options.prefix] | \u003ccode\u003eString\u003c/code\u003e | add prefix for each property key of the returned object |\n\n**Example**  \n```js\nconst {_name, _surname}= defineAccessor(obj, {\r    name: {\r        get(){\r            return 'John';\r        }\r    },\r\r    surname: {\r        get(){\r            return 'Connor';\r        }\r    }\r}, {\r    prefix: '_'\r})\n```\n\u003ca name=\"module_define-accessor2--module.exports+flushAccessor\"\u003e\u003c/a\u003e\n\n#### module.exports.flushAccessor(obj, ...props) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\nflush accessor's cache\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n**Returns**: \u003ccode\u003eboolean\u003c/code\u003e - true if flushed successfully  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| obj | \u003ccode\u003eObject\u003c/code\u003e | target object |\n| ...props | \u003ccode\u003ePropertyKey\u003c/code\u003e | public accessor's key |\n\n**Example**  \n```js\ndefineAccessor(obj, \"hash\", {\r    get(){\r        return calcObjectSHA(this);\r    }\r})\rflushAccessor(obj, 'hash')\n```\n\u003ca name=\"module_define-accessor2--module.exports+privateSymbol\"\u003e\u003c/a\u003e\n\n#### module.exports.privateSymbol(obj, prop) ⇒ \u003ccode\u003eSymbol\u003c/code\u003e \\| \u003ccode\u003enull\u003c/code\u003e\nretrieve the private accessor symbol assigned to the accessor\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type |\n| --- | --- |\n| obj | \u003ccode\u003eObject\u003c/code\u003e | \n| prop | \u003ccode\u003ePropertyKey\u003c/code\u003e | \n\n\u003ca name=\"module_define-accessor2--module.exports+defineValidator\"\u003e\u003c/a\u003e\n\n#### module.exports.defineValidator(name, fn) ⇒ \u003ccode\u003ethis\u003c/code\u003e\nDefines a new validator in the current library context\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| name | \u003ccode\u003eString\u003c/code\u003e | validator's name |\n| fn | \u003ccode\u003eValidatorPredicate\u003c/code\u003e | validator predicate function |\n\n**Example**  \n```js\nconst validator = require('validator');\rdefineValidator('email', validator.isEmail);\r\n     \n```\n\u003ca name=\"module_define-accessor2--module.exports+defineValidator\"\u003e\u003c/a\u003e\n\n#### module.exports.defineValidator(validators)\nDefines a new validator in the current library context\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type |\n| --- | --- |\n| validators | \u003ccode\u003eObject\u003c/code\u003e | \n\n**Example**  \n```js\nconst validator = require('validator');\rdefineValidator({\r email: validator.isEmail,\r ip: validator.isIP\r});\n```\n\u003ca name=\"module_define-accessor2--module.exports+newContext\"\u003e\u003c/a\u003e\n\n#### module.exports.newContext() ⇒ \u003ccode\u003eContext\u003c/code\u003e\ncreates a new library context\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n**Example**  \n```js\nconst {defineAccessor, flushAccessor, defineValidator}= require('define-accessor2').newContext()\r//define custom validators for the current and inherited from the current contexts only\rdefineValidator({\r    even: (value)=\u003e typeof value \u0026\u0026 value % 2===0,\r    odd: (value)=\u003e typeof value \u0026\u0026 Math.abs(value % 2)===1,\r});\n```\n\u003ca name=\"module_define-accessor2--module.exports+accessor\"\u003e\u003c/a\u003e\n\n#### module.exports.accessor(accessorDescriptor) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\naccessor decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param |\n| --- |\n| accessorDescriptor | \n\n\u003ca name=\"module_define-accessor2--module.exports+accessor\"\u003e\u003c/a\u003e\n\n#### module.exports.accessor([get], [set], [accessorDescriptor]) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| [get] | \u003ccode\u003efunction\u003c/code\u003e | getter function, can be omitted |\n| [set] | \u003ccode\u003efunction\u003c/code\u003e | setter function, can be omitted |\n| [accessorDescriptor] | \u003ccode\u003eAccessorDescriptor\u003c/code\u003e | accessor descriptor |\n\n\u003ca name=\"module_define-accessor2--module.exports+lazy\"\u003e\u003c/a\u003e\n\n#### module.exports.lazy() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nlazy decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+cached\"\u003e\u003c/a\u003e\n\n#### module.exports.cached() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\ncached decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+chains\"\u003e\u003c/a\u003e\n\n#### module.exports.chains() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\ncached decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+type\"\u003e\u003c/a\u003e\n\n#### module.exports.type(type) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\ntype decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type |\n| --- | --- |\n| type | \u003ccode\u003eBasicType\u003c/code\u003e | \n\n\u003ca name=\"module_define-accessor2--module.exports+validate\"\u003e\u003c/a\u003e\n\n#### module.exports.validate(validator) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nvalidate decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type |\n| --- | --- |\n| validator | \u003ccode\u003eBasicType\u003c/code\u003e | \n\n\u003ca name=\"module_define-accessor2--module.exports+touches\"\u003e\u003c/a\u003e\n\n#### module.exports.touches(props) ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\ntouches decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type |\n| --- | --- |\n| props | \u003ccode\u003ePropertyKey\u003c/code\u003e \\| \u003ccode\u003eArray.\u0026lt;PropertyKey\u0026gt;\u003c/code\u003e | \n\n\u003ca name=\"module_define-accessor2--module.exports+undefined\"\u003e\u003c/a\u003e\n\n#### module.exports.undefined() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nUndefined decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+null\"\u003e\u003c/a\u003e\n\n#### module.exports.null() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nNull decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+boolean\"\u003e\u003c/a\u003e\n\n#### module.exports.boolean() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nBoolean decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+number\"\u003e\u003c/a\u003e\n\n#### module.exports.number() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nNumber decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+string\"\u003e\u003c/a\u003e\n\n#### module.exports.string() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nstring decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+function\"\u003e\u003c/a\u003e\n\n#### module.exports.function() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nFunction decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+object\"\u003e\u003c/a\u003e\n\n#### module.exports.object() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nObject decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+symbol\"\u003e\u003c/a\u003e\n\n#### module.exports.symbol() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nSymbol decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+bigint\"\u003e\u003c/a\u003e\n\n#### module.exports.bigint() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nBigInt decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+integer\"\u003e\u003c/a\u003e\n\n#### module.exports.integer() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nInteger decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+infinity\"\u003e\u003c/a\u003e\n\n#### module.exports.infinity() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nInfinity decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+nan\"\u003e\u003c/a\u003e\n\n#### module.exports.nan() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nNaN decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+date\"\u003e\u003c/a\u003e\n\n#### module.exports.date() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nDate decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+promise\"\u003e\u003c/a\u003e\n\n#### module.exports.promise() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nPromise decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+regexp\"\u003e\u003c/a\u003e\n\n#### module.exports.regexp() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nRegExp decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+error\"\u003e\u003c/a\u003e\n\n#### module.exports.error() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nError decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+set\"\u003e\u003c/a\u003e\n\n#### module.exports.set() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nSet decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports+map\"\u003e\u003c/a\u003e\n\n#### module.exports.map() ⇒ \u003ccode\u003eMethodDecorator\u003c/code\u003e\nMap decorator\n\n**Kind**: instance method of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports..Context\"\u003e\u003c/a\u003e\n\n#### module.exports~Context\nLibrary context class\n\n**Kind**: inner class of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports..SetterFunction\"\u003e\u003c/a\u003e\n\n#### module.exports~SetterFunction ⇒ \u003ccode\u003eany\u003c/code\u003e\n**Kind**: inner typedef of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n**Returns**: \u003ccode\u003eany\u003c/code\u003e - value to store in the private property  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| newValue | \u003ccode\u003eany\u003c/code\u003e | new value to set |\n| currentValue | \u003ccode\u003eany\u003c/code\u003e | current private value |\n| propKey | \u003ccode\u003ePropertyKey\u003c/code\u003e | public property key |\n| privateKey | \u003ccode\u003ePrivatePropKey\u003c/code\u003e | private property key |\n\n\u003ca name=\"module_define-accessor2--module.exports..GetterFunction\"\u003e\u003c/a\u003e\n\n#### module.exports~GetterFunction ⇒ \u003ccode\u003eany\u003c/code\u003e\n**Kind**: inner typedef of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| currentValue | \u003ccode\u003eany\u003c/code\u003e | current private value |\n| propKey | \u003ccode\u003ePropertyKey\u003c/code\u003e | public property key |\n\n\u003ca name=\"module_define-accessor2--module.exports..ValidateFunction\"\u003e\u003c/a\u003e\n\n#### module.exports~ValidateFunction ⇒ \u003ccode\u003eBoolean\u003c/code\u003e\n**Kind**: inner typedef of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n**Throws**:\n\n- Error\n\n\n| Param | Type | Description |\n| --- | --- | --- |\n| value | \u003ccode\u003eany\u003c/code\u003e | value to validate |\n| propKey | \u003ccode\u003ePropertyKey\u003c/code\u003e | public property key |\n\n\u003ca name=\"module_define-accessor2--module.exports..PropertyKey\"\u003e\u003c/a\u003e\n\n#### module.exports~PropertyKey : \u003ccode\u003eString\u003c/code\u003e \\| \u003ccode\u003eSymbol\u003c/code\u003e\n**Kind**: inner typedef of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports..PrivatePropKey\"\u003e\u003c/a\u003e\n\n#### module.exports~PrivatePropKey : \u003ccode\u003eSymbol\u003c/code\u003e\n**Kind**: inner typedef of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports..AccessorDescriptor\"\u003e\u003c/a\u003e\n\n#### module.exports~AccessorDescriptor : \u003ccode\u003eObject\u003c/code\u003e\nAccessor's descriptor.\n\n**Kind**: inner typedef of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n**Properties**\n\n| Name | Type | Default | Description |\n| --- | --- | --- | --- |\n| [get] | \u003ccode\u003eGetterFunction\u003c/code\u003e | \u003ccode\u003e\u003c/code\u003e | getter function |\n| [set] | \u003ccode\u003eSetterFunction\u003c/code\u003e | \u003ccode\u003e\u003c/code\u003e | setter function |\n| [writable] | \u003ccode\u003eBoolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e | if setter is not present indicates whether accessor's value can be set |\n| [enumerable] | \u003ccode\u003eBoolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e |  |\n| [configurable] | \u003ccode\u003eBoolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e |  |\n| [cached] | \u003ccode\u003eBoolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e | cache getter result until it will be flushed by flushAccessor or other related accessor |\n| [lazy] | \u003ccode\u003eBoolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e | indicates whether the accessor should be a lazy computing property |\n| [virtual] | \u003ccode\u003eBoolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e | if true a private property is not created |\n| [chains] | \u003ccode\u003eBoolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e | create get/set chains for property (like getPropName()/setPropName(value)) |\n| [touches] | \u003ccode\u003ePropertyKey\u003c/code\u003e \\| \u003ccode\u003eArray.\u0026lt;PropertyKey\u0026gt;\u003c/code\u003e | \u003ccode\u003e\u003c/code\u003e | a key of accessor whose value depends on this |\n| [type] | \u003ccode\u003eBasicType\u003c/code\u003e | \u003ccode\u003e\u003c/code\u003e | built-type |\n| [validate] | \u003ccode\u003eValidateFunction\u003c/code\u003e | \u003ccode\u003e\u003c/code\u003e | validator function |\n| [value] | \u003ccode\u003e\\*\u003c/code\u003e |  | value to set after initialization |\n\n\u003ca name=\"module_define-accessor2--module.exports..ValidatorPredicate\"\u003e\u003c/a\u003e\n\n#### module.exports~ValidatorPredicate ⇒ \u003ccode\u003eBoolean\u003c/code\u003e\n**Kind**: inner typedef of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| value | \u003ccode\u003eany\u003c/code\u003e | value to test |\n\n\u003ca name=\"module_define-accessor2--module.exports..BasicType\"\u003e\u003c/a\u003e\n\n#### module.exports~BasicType : \u003ccode\u003eNumber\u003c/code\u003e \\| \u003ccode\u003eString\u003c/code\u003e\nBasic type.\n\n**Kind**: inner typedef of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n\u003ca name=\"module_define-accessor2--module.exports..AssertionFunction\"\u003e\u003c/a\u003e\n\n#### module.exports~AssertionFunction ⇒ \u003ccode\u003eBoolean\u003c/code\u003e\n**Kind**: inner typedef of [\u003ccode\u003emodule.exports\u003c/code\u003e](#exp_module_define-accessor2--module.exports)  \n**Returns**: \u003ccode\u003eBoolean\u003c/code\u003e - false if test failed  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| value | \u003ccode\u003eAny\u003c/code\u003e | value to test |\n\n\r\n## Built-in types\r\nThe library's type system consist of native JS types and extended pseudotypes.\r\nThe following types do not overlap, unlike native javascript types.\r\nFor example, null is not an object, NaN is not a number, and so on.\r\n- Undefined (TYPE_UNDEFINED)\r\n- Null (TYPE_NULL)\r\n- Boolean (TYPE_BOOLEAN)\r\n- Number (TYPE_NUMBER)\r\n- String (TYPE_STRING)\r\n- Function (TYPE_FUNCTION)\r\n- Object (TYPE_OBJECT)\r\n- Symbol (TYPE_SYMBOL)\r\n- BigInt (TYPE_BIGINT)\r\n- Array (TYPE_ARRAY)\r\n- Infinity (TYPE_INFINITY)\r\n- NaN (TYPE_NAN)\r\n- Date (TYPE_DATE)\r\n- Promise (TYPE_PROMISE)\r\n- RegExp (TYPE_REGEXP)\r\n- Error (TYPE_ERROR)\r\n- Set (TYPE_SET)\r\n- Map (TYPE_MAP)\r\n\r\nAn exception is the integer pseudotype which is an integer and a number types.\r\n- Integer (TYPE_INTEGER)\r\n\r\nSpecial type:\r\n- Any (TYPE_ANY)\r\n\r\n*There are predicates for each type named like isUndefined(value), isNumber(value) etc.*\r\n\r\nYou can combine these types:\r\n- type: 'string|number' // strings\r\n- type: TYPE_STRING|TYPE_NUMBER //bit mask\r\n- type: string|number // decorators are implicitly converted to a type bit mask using the valueOf() internal method\r\n\r\n### Decorators\r\nThe library supports both versions of the decorators specification (legacy \u0026 current draft).\r\nThere are following decorators:\r\n- lazy\r\n- cached\r\n- touches\r\n- type\r\n- validate\r\n- accessor\r\n- and decorators for each basic type (string, number, array etc. see [Built-in types](#built-in-types))\r\nEach decorator has valueOf method that returns a type bit mask, so it's possible to pass decorators as a type:\r\n`@type(number|string)`\r\n\r\n## Contribution\r\nFeel free to fork, open issues, enhance or create pull requests.\r\n## License\r\n\r\nThe MIT License\r\nCopyright (c) 2019 Dmitriy Mozgovoy \u003crobotshara@gmail.com\u003e\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbrainjs%2Fdefine-accessor2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalbrainjs%2Fdefine-accessor2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbrainjs%2Fdefine-accessor2/lists"}