{"id":28237019,"url":"https://github.com/bytebodger/allow","last_synced_at":"2025-10-19T03:42:47.733Z","repository":{"id":57167209,"uuid":"340457069","full_name":"bytebodger/allow","owner":"bytebodger","description":"Runtime data validation for JavaScript","archived":false,"fork":false,"pushed_at":"2021-04-07T02:47:16.000Z","size":633,"stargazers_count":12,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-19T00:17:34.010Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@toolz/allow","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/bytebodger.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-19T18:33:16.000Z","updated_at":"2024-09-03T12:34:19.000Z","dependencies_parsed_at":"2022-08-30T15:21:58.553Z","dependency_job_id":null,"html_url":"https://github.com/bytebodger/allow","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytebodger%2Fallow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytebodger%2Fallow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytebodger%2Fallow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytebodger%2Fallow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bytebodger","download_url":"https://codeload.github.com/bytebodger/allow/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytebodger%2Fallow/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259101130,"owners_count":22805209,"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":"2025-05-19T00:17:16.610Z","updated_at":"2025-10-19T03:42:42.670Z","avatar_url":"https://github.com/bytebodger.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# allow\n\n`allow`\nis a library that checks data types and _allows_ the script to continue if they pass the check. If the check fails, the script can throw an `Error`, or emit a warning, or invoke a custom callback. The package was written to ensure that only the \"right\" kind of data is allowed into the body of a function / method / component / etc. The intention is to provide effective _runtime_ validation of data before it reaches application logic.\n\nAnother goal is to eliminate the need for unit tests that only test a function's / method's operation when it receives the \"wrong\" kind of data. By validating that data at runtime, we are ensuring that the internal logic of the function / method is only invoked if it has been supplied with data of the expected type.\n\n**NOTE:** This library is designed for \"vanilla\" JS. If you are working in a React project, it's recommended to consider using `@toolz/allow-react`, which offers special behavior for evaluating React elements.\n\n## Usage\n\nAfter installation, import the package:\n\n```javascript\nimport { allow } from '@toolz/allow';\n```\n\nOnce imported, the assumed usage is directly after the entry to any function / method / component / etc. The idea is to check the integrity of provided inputs before further computation proceeds. This would typically look like this:\n\n```javascript\nconst addSalesTax = originalPrice =\u003e {\n   allow.aNumber(originalPrice, 0);\n   /*\n      ...proceed with the rest of the function\n    */\n}\n```\n\nIn the above example, the assumption is that `originalPrice` should _always_ be a number. If any other data type is provided for `originalPrice`, the `allow`check will fail. This means that a value of `'32.99'`will fail (because it's a string).  `null`will fail. Boolean values will fail. Anything that is _not_ a number will fail. In this example, the second argument (which is optional), indicates the minimum acceptable value of the number. In this case, we don't want negative values for `originalPrice`, so nothing below `0`will pass the check.\n\n## Methods\n\n### .aBoolean()\n\n```javascript\nconst doSomething = someValue =\u003e {\n   allow.aBoolean(someValue);\n   /*\n      This is NOT \"truthy\".  It fails if anything other than a Boolean is \n      provided. This means that it fails on 'TRUE'/'FALSE' (because they're \n      strings), on 1/0 (because they're numbers), or any other value that is \n      not a pure TRUE/FALSE\n    */\n}\n```\n\n### .aFunction()\n\n```javascript\nconst doSomething = theCallback =\u003e {\n   allow.aFunction(theCallback);\n   /*\n      This will fail unless a function is provided as the value for \n      theCallback. It doesn't care what's inside the function. It can even be\n      blank, like:\n      () =\u003e {}\n      But it must be a function of some kind.\n      Please note that, in JavaScript, a class is virtually indistinguishable\n      from a function (since \"class\" is just syntactic sugar). For this reason,\n      a class will also pass this check.\n    */\n}\n```\n\n### .anArray()\n\n```javascript\nconst doSomething = theArray =\u003e {\n   allow.anArray(theArray);\n   /*\n       This will fail unless an array is provided as the value for theArray.  \n       The check doesn't examine the contents of the array. It can be an \n       empty array, like:\n       [] \n       But it must be an array of some kind.\n     */\n}\n```\n\n```javascript\nconst doSomething = theArray =\u003e {\n   allow.anArray(theArray, 1);\n   /*\n       The second argument of anArray() is the minimum length of the array. \n       So, by setting this value to 1, it ensures that theArray is a \n       non-empty array.\n     */\n}\n```\n\n```javascript\nconst doSomething = theArray =\u003e {\n   allow.anArray(theArray, 2, 50);\n   /*\n       This ensures that theArray is an array, that has no fewer than 2 \n       elements, and no more than 50 elements.\n     */\n}\n```\n\n### .anArrayOfArrays()\n\n```javascript\nconst doSomething = theArrays =\u003e {\n   allow.anArrayOfArrays(theArrays);\n   /*\n       This will fail unless an array is provided as the value for \n       theArrays. It will also fail if any of elements inside theArrays \n       are not also arrays. It does not inspect the contents of the arrays \n       inside theArrays. They can be empty arrays, like:\n       [[], [], []]\n       But they must be arrays of some kind.\n     */\n}\n```\n\n```javascript\nconst doSomething = theArrays =\u003e {\n   allow.anArrayOfArrays(theArrays, 1);\n   /*\n       The second argument of anArrayOfArrays() is the minimum length of the \n       array. So, by setting this value to 1, it ensures that theArrays is \n       a non-empty array-of-arrays.\n     */\n}\n```\n\n```javascript\nconst doSomething = theArrays =\u003e {\n   allow.anArrayOfArrays(theArrays, 2, 50);\n   /*\n       This ensures that theArrays is an array, that all of its elements \n       are arrays, that it has no fewer than 2 elements, and no more than 50 \n       elements.\n     */\n}\n```\n\n### .anArrayOfInstances()\n\n```javascript\nconst person = {\n   firstName: '',\n   lastName: '',\n   middleInitial: '',\n}\n\nconst doSomething = thePeople =\u003e {\n   allow.anArrayOfInstances(thePeople, person);\n   /*\n       This will fail unless an array is provided as the value for \n       thePeople. It will also fail if any of the elements inside thePeople\n       are not objects, and if those objects do not have all the keys present\n       in the model object (in this case: person). It does not inspect the \n       types of data held in those keys, and it will allow additional keys \n       that do not exist in the model object. But it expects every object \n       in the array to have all of the keys present in the model.\n     */\n}\n```\n\n```javascript\nconst person = {\n   firstName: '',\n   lastName: '',\n   middleInitial: '',\n}\n\nconst doSomething = thePeople =\u003e {\n   allow.anArrayOfInstances(thePeople, person, 1);\n   /*\n       The third argument of anArrayOfInstances() is the minimum length of \n       the array. So, by setting this value to 1, it ensures that thePeople is \n       a non-empty array of \"person\" instances.\n     */\n}\n```\n\n```javascript\nconst person = {\n   firstName: '',\n   lastName: '',\n   middleInitial: '',\n}\n\nconst doSomething = thePeople =\u003e {\n   allow.anArrayOfInstances(thePeople, person, 2, 50);\n   /*\n       This ensures that thePeople is an array of \"person\" instances, that it\n       has no fewer than 2 elements, and no more than 50 elements.\n     */\n}\n```\n\n### .anArrayOfIntegers()\n\n```javascript\nconst doSomething = theNumbers =\u003e {\n   allow.anArrayOfIntegers(theNumbers);\n   /*\n       This will fail unless an array is provided as the value for \n       theNumbers. It will also fail if any of elements inside theNumbers \n       are not also integers. This means that it will fail on any non-numeric\n       value, and it will also fail on any number that is not a \"whole\" \n       number. It will accept decimal values, as long as those decimals \n       evaluate to a whole number. So this works:\n       [1.0, 3.00, 42.0]\n       But this does not:\n       [1.0, 3.14, 42.0]\n     */\n}\n```\n\n```javascript\nconst doSomething = theNumbers =\u003e {\n   allow.anArrayOfIntegers(theNumbers, 1);\n   /*\n       The second argument of anArrayOfIntegers() is the minimum length of \n       the array. So, by setting this value to 1, it ensures that theNumbers\n       is a non-empty array of integers.\n     */\n}\n```\n\n```javascript\nconst doSomething = theNumbers =\u003e {\n   allow.anArrayOfIntegers(theNumbers, 2, 50);\n   /*\n       This ensures that theNumbers is an array of integers, that it has no \n       fewer than 2 elements, and no more than 50 elements.\n     */\n}\n```\n\n### .anArrayOfNumbers()\n\n```javascript\nconst doSomething = theNumbers =\u003e {\n   allow.anArrayOfNumbers(theNumbers);\n   /*\n       This will fail unless an array is provided as the value for \n       theNumbers. It will also fail if any of elements inside theNumbers \n       are not also numbers.\n     */\n}\n```\n\n```javascript\nconst doSomething = theNumbers =\u003e {\n   allow.anArrayOfNumbers(theNumbers, 1);\n   /*\n       The third argument of anArrayOfNumbers() is the minimum length of \n       the array. So, by setting this value to 1, it ensures that theNumbers\n       is a non-empty array of integers.\n     */\n}\n```\n\n```javascript\nconst doSomething = theNumbers =\u003e {\n   allow.anArrayOfNumbers(theNumbers, 2, 50);\n   /*\n       This ensures that theNumbers is an array of integers, that it has no \n       fewer than 2 elements, and no more than 50 elements.\n     */\n}\n```\n\n### .anArrayOfObjects()\n\n```javascript\nconst doSomething = theObjects =\u003e {\n   allow.anArrayOfObjects(theObjects);\n   /*\n       This will fail unless an array is provided as the value for \n       theObjects. It will also fail if any of the elements inside theObjects \n       are not also objects. It does not inspect the contents of the objects \n       inside theObjects. They can be empty objects, like:\n       [{}, {}, {}]\n       But they must be objects of some kind.\n     */\n}\n```\n\n```javascript\nconst doSomething = theObjects =\u003e {\n   allow.anArrayOfObjects(theObjects, 1);\n   /*\n       The second argument of anArrayOfObjects() is the minimum length of the \n       array. So, by setting this value to 1, it ensures that theObjects is \n       a non-empty array-of-objects.\n     */\n}\n```\n\n```javascript\nconst doSomething = theObjects =\u003e {\n   allow.anArrayOfObjects(theObjects, 2, 50);\n   /*\n       This ensures that theObjects is an array, that all of its elements \n       are objects, that it has no fewer than 2 elements, and no more than 50 \n       elements.\n     */\n}\n```\n\n### .anArrayOfStrings()\n\n```javascript\nconst doSomething = theStrings =\u003e {\n   allow.anArrayOfStrings(theStrings);\n   /*\n       This will fail unless an array is provided as the value for \n       theStrings. It will also fail if any of the elements inside theStrings \n       are not also strings. It does not inspect the contents of the strings \n       inside theStrings. They can be empty strings, like:\n       ['', '', '']\n       But they must be strings of some kind.\n     */\n}\n```\n\n```javascript\nconst doSomething = theStrings =\u003e {\n   allow.anArrayOfStrings(theStrings, 1);\n   /*\n       The second argument of anArrayOfStrings() is the minimum length of the \n       array. So, by setting this value to 1, it ensures that theStrings is \n       a non-empty array-of-strings.\n     */\n}\n```\n\n```javascript\nconst doSomething = theStrings =\u003e {\n   allow.anArrayOfStrings(theStrings, 2, 50);\n   /*\n       This ensures that theStrings is an array, that all of its elements \n       are strings, that it has no fewer than 2 elements, and no more than 50 \n       elements.\n     */\n}\n```\n\n### .anInstanceOf()\n\n```javascript\nconst person = {\n   firstName: '',\n   lastName: '',\n   middleInitial: '',\n}\n\nconst doSomething = thePerson =\u003e {\n   allow.anInstanceOf(thePerson, person);\n   /*\n       This is a (purposely forgiving) check to ensure that the provided object\n       is of a similar type to a reference object. This only checks that the\n       provided object has all of the same keys that are present in the\n       reference object.  It does not look at the types of data held in those\n       keys. It allows additional keys that don't exist in the reference\n       object. These objects will pass the check against the person reference:\n       \n       {\n          firstName: 'Bob',\n          lastName: 'Doe',\n          middleInitial: null, // this does not check to ensure that \n                               // middleInitial is a string\n       }\n       \n       {\n          firstName: 'Bob',\n          lastName: 'Doe',\n          middleInitial: 'K',\n          favoriteIceCream: 'vanilla' // the check does not fail based upon any\n                                      // \"extra\" keys\n       }\n       \n       This object will fail the check against the person reference:\n       \n       {\n          firstName: 'Bob',\n          lastName: 'Doe',\n          // the middleInitial key is missing\n       }\n     */\n}\n```\n\n```javascript\nconst person = {\n   firstName: '',\n   lastName: '',\n   middleInitial: '',\n   address: {},\n   children: [],\n}\n\nconst doSomething = thePerson =\u003e {\n   allow.anInstanceOf(thePerson, person);\n   /*\n       Although anInstanceOf() does not check data types (string, number, \n       etc.), it does check to ensure that keys containing objects or \n       arrays in the model object also contain objects or arrays in the\n       supplied object. This object will fails the check against the person\n       reference:\n       \n       {\n         firstName: 'Bob',\n         lastName: 'Doe',\n         middleInitial: 'I',\n         address: '101 Main Street',\n         children: 4,\n       }\n       \n       This check is not recursive, meaning that anInstanceOf() only checks\n       to ensure that address is an object and children is an array.  It makes\n       no attempt to ensure that any objects/arrays below the first level of\n       keys exist in the supplied object.\n     */\n}\n```\n\n### .anInteger()\n\n```javascript\nconst doSomething = theNumber =\u003e {\n   allow.anInteger(theNumber);\n   /*\n       This will fail unless an integer is provided as the value for\n       theNumber. It will fail on any non-numeric value.  It will also\n       fail on any numbers that are not \"whole\" numbers.  Values like\n       1.00 or 42.0 are fine.  But 3.14 will fail, because it is not\n       an integer.\n     */\n}\n```\n\n```javascript\nconst doSomething = theNumber =\u003e {\n   allow.anInteger(theNumber, 0);\n   /*\n       The second argument of anInteger() is the minimum value of theNumber. \n       So, by setting this value to 0, it ensures that theNumber is a \n       non-negative integer.\n     */\n}\n```\n\n```javascript\nconst doSomething = theNumber =\u003e {\n   allow.anInteger(theNumber, 2, 50);\n   /*\n       This ensures that theNumber is an integer, that the value is no less\n       than 2, and no greater than 50.\n     */\n}\n```\n\n### .anObject()\n\n```javascript\nconst doSomething = theObject =\u003e {\n   allow.anObject(theObject);\n   /*\n       This ensures that theObject is an object. In JavaScript, an array is\n       seen as having typeof 'object', but an array will fail this check.\n       Similarly, NULL is seen as having typeof 'object', but it will also\n       fail this check. \n     */\n}\n```\n\n```javascript\nconst doSomething = theObject =\u003e {\n   allow.anObject(theObject, 1);\n   /*\n       The second argument of anObject() is the minimum number of keys that\n       must be present in theObject. So, by setting this value to 1, it ensures\n       that theObject is a non-empty object.\n     */\n}\n```\n\n```javascript\nconst doSomething = theObject =\u003e {\n   allow.anObject(theObject, 2, 50);\n   /*\n       This ensures that theObject is an object, with no fewer than two keys,\n       and no more than 50 keys.\n     */\n}\n```\n\n### .aString()\n\n```javascript\nconst doSomething = theString =\u003e {\n   allow.aString(theString);\n   /*\n       This will fail unless a string is provided as the value for theString.  \n       The check doesn't examine the contents of the string. It can be an \n       empty string, like:\n       ''\n       But it must be a string of some kind.\n     */\n}\n```\n\n```javascript\nconst doSomething = theString =\u003e {\n   allow.aString(theString, 1);\n   /*\n       The second argument of aString() is the minimum length of the string. \n       So, by setting this value to 1, it ensures that theString is a \n       non-empty string.\n     */\n}\n```\n\n```javascript\nconst doSomething = theString =\u003e {\n   allow.aString(theString, 2, 50);\n   /*\n       This ensures that theString is a string, that has no fewer than 2 \n       characters, and no more than 50 characters.\n     */\n}\n```\n\n### .getAllowNull()\n\n```javascript\nconsole.log(allow.getAllowNull()); // false\n/*\n   allowNull is Boolean. The default value is FALSE. When set to\n   TRUE, all of the checks will pass if the provided value is NULL. \n */\n```\n\n### .getFailureBehavior()\n\n```javascript\nconsole.log(allow.getFailureBehavior()); // 'throw'\n/*\n   The behavior has three possible values:\n      throw\n      warn\n      ignore\n   'throw' is the default value.\n */\n```\n\n### .getOnFailure()\n\n```javascript\nallow.getOnFailure();\n/*\n   returns whatever function has been set to be called onFailure\n */\n```\n\n### .oneOf()\n\nThis can be called two different ways - by passing in a reference array or a reference object.\n\n```javascript\nconst days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat'];\n\nconst doSomething = theDay =\u003e {\n   allow.oneOf(theDay, days);\n   /*\n      This ensures that theDay matches one of the values in the days array.\n    */\n}\n```\n\n```javascript\nconst days = {\n   0: 'Sun',\n   1: 'Mon',\n   2: 'Tue',\n   3: 'Wed',\n   4: 'Thur',\n   5: 'Fri',\n   6: 'Sat',\n}\n\nconst doSomething = theDay =\u003e {\n   allow.oneOf(theDay, days);\n   /*\n      This ensures that theDay matches one of the values in the days object.\n      It does not try to check against any of the keys in the key/value pairs.\n      It only checks against the values.\n    */\n}\n```\n\nThe first value passed into `oneOf()` must be a primitive. It cannot be an object, an array, or a function.\n\n### .setAllowNull()\n\n```javascript\nconst thisIsNull = null;\nallow.anArray(thisIsNull); // this throws an Error\nallow.setAllowNull(true);\nallow.anArray(thisIsNull); // this does NOT throw an Error\n/*\n   setAllowNull() requires a Boolean as its only argument. By default, the\n   values checked in by the allow methods are not nullable. But this behavior\n   can be toggled with setAllowNull(). \n   If sessionStorage is available, the allowNull value will be set there.\n   This allows the setting to be saved once in the lifecycle of the app.\n */\n```\n\n### .setFailureBehavior()\n\n```javascript\nallow.setFailureBehavior(allow.failureBehavior.WARN);\n/*\n   setFailureBehavior() requires one of the following three values:\n      'throw'\n      'warn'\n      'ignore'\n   'throw' is the default value.  Throwing an Error will halt JavaScript\n   execution.  \n   'warn' will spawn warnings to be displayed in the console.\n   'ignore' will turn off all warnings and cease the throwing of all Errors.\n   If sessionStorage is available, the failureBehavior value will be set there.\n   This allows the setting to be saved once in the lifecycle of the app.\n */\n```\n\n### .setOnFailure()\n\n```javascript\nconst myCustomErrorHandler = (value, message) =\u003e {\n   // do the custom error handling...\n}\n\nallow.setFailureBehavior(allow.failureBehavior.IGNORE);\nallow.setOnFailure(myCustomErrorHandler);\n/*\n   The onFailure handler is called before any warning is displayed and before\n   any Error is thrown.  Setting an onFailure callback does not halt the\n   further error handling provide by allow.  If you want to turn off\n   those features, you must use setFailureBehavior().\n   \n   When the onFailure method is invoked, it will be called with two arguments:\n      The original value that failed validation\n      The message spawned by that failed validation\n */\n```\n\n## Chaining\n\nA successful call to any of the `allow` validation methods always returns `allow`. This enables the chaining of multiple checks on a single line of code. That would look something like this:\n\n```javascript\nconst doSomething = (patient, isAlive, age) =\u003e {\n   allow.anObject(patient, 1).aBoolean(isAlive).aNumber(age, 0, 130);\n   /*\n      This ensures that patient is a non-empty object\n      AND that isAlive is a Boolean\n      AND that age is a non-negative number no greater than 130\n    */\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytebodger%2Fallow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbytebodger%2Fallow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytebodger%2Fallow/lists"}