{"id":20962196,"url":"https://github.com/developerdizzle/valerie","last_synced_at":"2025-04-11T20:10:28.417Z","repository":{"id":57390128,"uuid":"41927139","full_name":"developerdizzle/valerie","owner":"developerdizzle","description":"Simple javascript object validator","archived":false,"fork":false,"pushed_at":"2016-05-09T23:07:28.000Z","size":99,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-25T16:07:26.512Z","etag":null,"topics":["functional","javascript","validation"],"latest_commit_sha":null,"homepage":null,"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/developerdizzle.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2015-09-04T16:50:41.000Z","updated_at":"2017-03-16T17:54:29.000Z","dependencies_parsed_at":"2022-09-15T05:21:14.956Z","dependency_job_id":null,"html_url":"https://github.com/developerdizzle/valerie","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/developerdizzle%2Fvalerie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developerdizzle%2Fvalerie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developerdizzle%2Fvalerie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developerdizzle%2Fvalerie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/developerdizzle","download_url":"https://codeload.github.com/developerdizzle/valerie/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248262433,"owners_count":21074308,"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":["functional","javascript","validation"],"created_at":"2024-11-19T02:24:13.254Z","updated_at":"2025-04-11T20:10:28.393Z","avatar_url":"https://github.com/developerdizzle.png","language":"JavaScript","readme":"# valerie [![Build Status](https://travis-ci.org/developerdizzle/valerie.svg?branch=master)](https://travis-ci.org/developerdizzle/valerie) [![devDependency Status](https://david-dm.org/developerdizzle/valerie.svg)](https://david-dm.org/developerdizzle/valerie) [![devDependency Status](https://david-dm.org/developerdizzle/valerie/dev-status.svg)](https://david-dm.org/developerdizzle/valerie#info=devDependencies)\n\nSimple javascript object validator\n\nThe goal of this project is to provide a simple, intuitive, extensible, independent, and isomorphic javascript object validation library.\n\n## What makes Valerie any different from other validation libs?\n\n* No dependencies\n* Very lightweight\n* Easy to use both server- and browser-side\n* Validation rules are standard functions (keep it simple)\n* Supports async/promise-based validation rules\n* [Custom rules](#custom-rules) are super easy to make\n* Custom error messages for all built-in rules\n* Source uses ES6/7 features (transpiled to ES5 for browsers)\n* Full tests and linting\n\n## Usage\n\nImport the function and built-in rules\n\n```js\nimport createValidator from 'valerie';\nimport { number, oneOf } from 'valerie/rules';\nimport { range, required } from 'valerie/rules/extended';\n```\n\nCompose the validation schema for our object\n\n```js\nconst schema = {\n  id: [required('id is required'), number('id must be a number')],\n  name: {\n    first: required('first name is required'),\n    last: required('last name is required')\n  },\n  age: range(0, 123, 'must be a normal human age'),\n  favoriteColor: oneOf(['blue', 'red', 'yellow'], 'must be a primary color')\n};\n```\n\nCreate the object validator, which is a function taking a single object parameter, and returns a `Promise` which resolves to an array containing errors.  The array will be empty if there are no errors.\n\n```js\nconst validate = createValidator(schema);\n```\n\nValidate\n```js\n\nconst input = {\n  id: 10,\n  name: {\n    first: 'foo'\n  },\n  age: 99,\n  favoriteColor: 'potato'\n};\n\n// ES7\nconst errors = await validate(input);\n\n// ES6\nvalidate(input).then(errors =\u003e {\n  // tell the user about the errors!\n})\n\n// ES5\nvalidate(input).then(function(errors) {\n  // tell the user about the errors!\n});\n\n/*\n[\n  {\n    property: 'name.last',\n    message: 'last name is required'\n  },\n  {\n    property: 'favoriteColor',\n    message: 'must be a primary color'\n  }\n]\n*/\n\n// or just get the first error\nconst errors = await validate(input, 1);\n\n/*\n[\n  {\n    property: 'name.last',\n    message: 'last name is required'\n  }\n]\n*/\n\n```\n\n## Rules\n\nValidation rules are just simple functions that take a single input, the value to validate, and return `undefined` if valid, or an error message if not.\n\nThe built-in rule objects exported from `valerie/rules` are functions that take a set of options and return the rule function itself.\n\nExample:\n\n```js\nimport { is } from 'valerie/rules';\n\nconst isTrue = is(true, 'value must be true');\n\nisTrue(false); // 'value must be true';\nisTrue(true); // undefined\n```\n\n## Simple rules\n\nThe simple rules are largely based on the fundamental javascript operations.\n\n### Equality rules\n\n#### `is(target, [message = \"is\"])`\n\nTests if a value is strictly equal (`===`) to a target value.\n\n - `target`: what the validated value should equal\n - `message`: optional custom error message\n\n```js\nconst isBar = equalTo('bar', 'foo must be bar');\n\nconst validate = createValidator({ foo: isBar });\n\nconst errors = await validate({ foo: 'bar' });\n```\n\n#### `equalTo(target, [message = \"equalTo\"])`\n\nTests if a value is loosely equal (`==`) to a target value.\n\n - `target`: what the validated value should equal\n - `message`: optional custom error message\n\n```js\nconst isBar = equalTo('bar', 'foo must be bar');\n\nconst validate = createValidator({ foo: isBar });\n\nconst errors = await validate({ foo: new String('bar') });\n```\n\n### Numeric rules\n\n#### `number([message = \"number\"])`\n\nTests if a value is a number (`!isNaN`).\n\n - `message`: optional custom error message\n\n```js\nconst isNumber = number(foo 'must be a number');\n\nconst validate = createValidator({ foo: isNumber });\n\nconst errors = await validate({ foo: Math.PI });\n```\n\n#### `greaterThan(target, [message = \"greaterThan\"])`\n\nTests if a value is greater than (`\u003e`) a target value.\n\n - `target`: what the validated value should be greater than\n - `message`: optional custom error message\n\n```js\nconst isPositive = greaterThan(0, 'foo must be positive');\n\nconst validate = createValidator({ foo: isPositive });\n\nconst errors = await validate({ foo: 1 });\n```\n\n#### `lessThan(target, [message = \"lessThan\"])`\n\nTests if a value is less than (`\u003c`) a target value.\n\n - `target`: what the validated value should be less than\n - `message`: optional custom error message\n\n```js\nconst isNegative = lessThan(0, 'foo must be negative');\n\nconst validate = createValidator({ foo: isNegative });\n\nconst errors = await validate({ foo: -1 });\n```\n\n### Array rules\n\n#### `array([message = \"array\"])`\n\nTests if a value is an array (`Array.isArray`).\n\n - `message`: optional custom error message\n\n```js\nconst isArray = array('foo must be an array');\n\nconst validate = createValidator({ foo: isArray });\n\nconst errors = await validate({ foo: ['bar', 'baz'] });\n```\n\n#### `contains(item, [message = \"contains\"])`\n\nTests if a value contains (`indexOf`) an item.\n\n - `item`: item that value should contain\n - `message`: optional custom error message\n\n```js\nconst containsBar = contains('bar', 'foo must contain bar');\n\nconst validate = createValidator({ foo: containsBar });\n\nconst errors = await validate({ foo: ['bar'] });\n```\n\n#### `oneOf(options, [message = \"oneOf\"])`\n\nTests if a value is equal to (`===`) an item in an `Array`.\n\n - `options`: array of items to check against\n - `message`: optional custom error message\n\n```js\nconst isPrimaryColor = oneOf(['red', 'blue', 'yellow'], 'foo must be a primary color');\n\nconst validate = createValidator({ foo: isPrimaryColor });\n\nconst errors = await validate({ foo: 'blue' });\n```\n\n### Type rules\n\n#### `isInstanceOf(type, [message = \"isInstanceOf\"])`\n\nTests if a value is an instance of a class (`instanceof`).\n\n - `type`: what the validated value should be an instance of\n - `message`: optional custom error message\n\n```js\nconst isBar = isInstanceOf(Bar, 'foo must be bar');\n\nconst validate = createValidator({ foo: isBar });\n\nconst errors = await validate({ foo: new Bar() });\n```\n\n#### `isTypeOf(type, [message = \"isTypeOf\"])`\n\nTests if a value is of a given type (`typeof`).\n\n - `type`: what the validated value should be a type of\n - `message`: optional custom error message\n\n```js\nconst isString = isTypeOf(Bar, 'foo must be a string');\n\nconst validate = createValidator({ foo: isString });\n\nconst errors = await validate({ foo: 'bar' });\n```\n\n#### `hasProperty(property, [message = \"hasProperty\"])`\n\nTests if an object has a child property (`hasOwnProperty`).\n\n - `property`: name of the property\n - `message`: optional custom error message\n\n```js\nconst hasBar = hasProperty('bar', 'foo must have bar property');\n\nconst validate = createValidator({ foo: hasBar });\n\nconst errors = await validate({\n    foo: {\n        bar: true\n    }\n});\n```\n\n### Logical operators\n\nThese rules take one or more rules as input and return new, compoud rule.\n\n#### `async and(rules, [message = \"and\"])`\n\nTests if a value is valid against all rules within an `Array`.\n\n - `rules`: array of rules to validate against\n - `message`: optional custom error message\n\n```js\nconst isArrayContainingBar = and([array(), contains('bar')], 'foo must be an array containing \"bar\"');\n\nconst validate = createValidator({ foo: isArrayContainingBar });\n\nconst errors = await validate({ foo: ['bar', 'baz', 'qux'] );\n```\n\n#### `async or(rules, [message = \"or\"])`\n\nTests if a value is is valid against at least one rule within an `Array` of rules.\n\n - `rules`: array of rules to validate against\n - `message`: optional custom error message\n\n```js\nconst isNumberOrX = or([number(), equals('x')], 'foo must be a number or the letter \"x\"');\n\nconst validate = createValidator({ foo: isNumberOrX });\n\nconst errors = await validate({ foo: 'x' );\n```\n\n#### `async not(rule, [message = \"not\"])`\n\nTests if a value is _not_ valid against rule.\n\n - `rule`: rule to validate against\n - `message`: optional custom error message\n\n```js\nconst isNotNumber = not(number(), 'foo must not be a number');\n\nconst validate = createValidator({ foo: isNotNumber });\n\nconst errors = await validate({ foo: 'bar' );\n```\n\n### Other rules\n\n#### `regex(pattern, [message = \"regex\"])`\n\nTests if a value matches a regex (`.match`)\n\n - `pattern`: regexp (`RegExp` or `/pattern/`)\n - `message`: optional custom error message\n\n```js\nconst isEMail = regex(/^\\S+@\\S+$/, 'foo must be an email address');\n\nconst validate = createValidator({ foo: isEMail });\n\nconst errors = await validate({ foo: 'bar@baz.com' });\n```\n\n\n## Extended Rules\n\nExtended rules use the simple rules to form more complex logic\n\n### `async range(min, max, [message = \"range\"])`\n\nTests if a value is between two values.  Generally want to use with `number`.  Depends on `and`, `or`, `greaterThan`, `lessThan`, and `equalTo`.\n\n - `min`: minimum value, inclusive\n - `max`: maximum value, inclusive\n - `message`: optional custom error message\n\n```js\nconst isNumber = number('foo must be a number');\nconst isHumanAge = range(0, 123, 'foo must be a human age');\n\nconst validate = createValidator({ foo: [isNumber, isHumanAge] });\n\nconst errors = await validate({ foo: 100 });\n```\n\n#### `async required([message = \"required\"])`\n\nTests if a value exists (not `undefined`, not an empty string, not an empty array).  Depends on `and`, `defined`, and `notEmpty`.\n\n - `message`: optional custom error message\n\n```js\nconst isRequired = required('foo is required');\n\nconst validate = createValidator({ foo: isRequired });\n\nconst errors = await validate({ foo: 'bar' );\n```\n\n## Custom Rules\n\nCustom rules are easy to implement.  They're simply functions that take a single value and return an error message for failure, and `undefined` for passing.\n\n```js\nconst isEven = value =\u003e {\n  if (value % 2 !== 0) return 'value must be even';\n};\n\nisEven(4); // undefined\nisEven(5); // value must be even\n\nconst validate = createValidator({\n  foo: isEven\n});\n\nconst errors = await validate({\n  foo: 5\n});\n\n/* \n[\n  {\n    property: 'foo',\n    message: 'value must be even'\n  }\n]\n*/\n\n```\n\nBuilt-in rules use currying to allow options and custom error messages to be set.  You can follow this technique like so:\n\n```js\nconst divisibleBy = (divisor, message = 'divisibleBy') =\u003e {\n  return value =\u003e {\n    if (value % divisor !== 0) return message;\n  }\n};\n\nconst isDivisibleBy3 = divisibleBy(3, 'value must divisibly by 3');\n```\n\nCheck out the [other rules](https://github.com/developerdizzle/valerie/tree/master/src/rules) for more examples.\n\n## TODO:\n\n* Rules\n    * `email`\n* Examples of client- and server-side usage\n* Example of promise rule\n* Compare to other libs\n    * https://github.com/hapijs/joi (large)\n    * https://github.com/molnarg/js-schema (no custom messages)\n    * https://github.com/ansman/validate.js ","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeveloperdizzle%2Fvalerie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeveloperdizzle%2Fvalerie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeveloperdizzle%2Fvalerie/lists"}