{"id":17458947,"url":"https://github.com/caseywebb/badbadnotgood","last_synced_at":"2026-01-20T04:31:47.690Z","repository":{"id":35206806,"uuid":"215920524","full_name":"caseyWebb/badbadnotgood","owner":"caseyWebb","description":"✅ A functional validation library. There are many like it, but this one is mine.","archived":false,"fork":false,"pushed_at":"2023-03-06T11:58:08.000Z","size":2184,"stargazers_count":1,"open_issues_count":12,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-18T07:12:31.923Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/caseyWebb.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}},"created_at":"2019-10-18T01:56:49.000Z","updated_at":"2022-01-10T17:23:59.000Z","dependencies_parsed_at":"2024-10-20T19:48:33.335Z","dependency_job_id":null,"html_url":"https://github.com/caseyWebb/badbadnotgood","commit_stats":{"total_commits":535,"total_committers":3,"mean_commits":"178.33333333333334","dds":0.2186915887850467,"last_synced_commit":"f91297deb7585ce3c56821fd248eabfd122ff3cd"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caseyWebb%2Fbadbadnotgood","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caseyWebb%2Fbadbadnotgood/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caseyWebb%2Fbadbadnotgood/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caseyWebb%2Fbadbadnotgood/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/caseyWebb","download_url":"https://codeload.github.com/caseyWebb/badbadnotgood/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247592495,"owners_count":20963532,"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-18T04:38:03.265Z","updated_at":"2026-01-20T04:31:47.660Z","avatar_url":"https://github.com/caseyWebb.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# badbadnotgood\n\n\u003e Functional validation, built for composition.\n\n[![NPM Version][npm-version-shield]][npm-version]\n[![NPM Downloads][npm-stats-shield]][npm-stats]\n[![License][license-shield]][license]\n[![TypeScript][typescript-shield]][typescript]\n[![Build Status][build-status-shield]][build-status]\n[![Coverage Status][codecov-shield]][codecov]\n\n## Usage\n\n```typescript\nimport {\n  all,\n  any,\n  onlyIf,\n  not,\n  divisibleBy\n  equals,\n  minLength,\n} from 'badbadnotgood'\n\n// Simple validation\nconst isFoo = equals('foo')\nisFoo('foo') // { isValid: true, messages: [] }\nisFoo('bar') // { isValid: false, messages: [] }\n\n// With validation messages\nconst isBar = equals('bar', 'Value must be \"bar\"')\nisFoo('foo') // { isValid: false, messages: ['Value must be \"bar\"'] }\nisFoo('bar') // { isValid: true, messages: [] }\n\n// Negated\nconst isNotFoo = not(equals('foo'), 'Value must not be \"foo\"')\nisNotFoo('foo') // { isValid: false, messages: ['Value must not be \"foo\"']}\nisNotFoo('bar') // { isValid: true, messages: [] }\n\n// Composed, with single message\nconst isFooOrBar = any(\n  [equals('foo'), equals('bar')],\n  'Value must be \"foo\" or \"bar\"'\n)\nisFooOrBar('foo') // { isValid: true, messages: [] }\nisFooOrBar('baz') // { isValid: false, messages: ['Value must be \"foo\" or \"bar\"'] }\n\n// Composed, with multiple messages\nconst isDivisibleBy3And4 = all([\n  divisibleBy(3, 'Not divisible by 3'),\n  divisibleBy(4, 'Not divisible by 4')\n])\nisDivisibleBy3And4(12) // { isValid: true, messages: [] }\nisDivisibleBy3And4(6) // { isValid: false, messages: [\"Not divisible by 4\"] }\nisDivisibleBy3And4(1) // { isValid: false, messages: [\"Not divisible by 3\", \"Not divisible by 4\"] }\n\n// Conditional validation\nconst atLeast6CharsUnlessFoo = onlyIf(\n  not(equals('foo')),\n  minLength(6, 'Must be at least 6 characters')\n)\natLeast6CharsUnlessFoo('foo') // { isValid: true, messages: [] }\natLeast6CharsUnlessFoo('bar') // { isValid: false, messages: [\"Must be at least 6 characters\"] }\natLeast6CharsUnlessFoo('foobar') // { isValid: true, messages: [] }\n\n// Arrays\nconst allAreFoo = forEach(equals('foo', 'Item is not \"foo\"'), 'All items must be \"foo\"')\nallAreFoo(['foo']) // { isValid: true, messages: [] }\nallAreFoo(['foo', 'bar']) // { isValid: false, messages: ['All items must be \"foo\"', { index: 1, messages: ['Item is not \"foo\"] }] }\n```\n\n[npm-version]: https://npmjs.com/package/badbadnotgood\n[npm-version-shield]: https://img.shields.io/npm/v/badbadnotgood.svg\n[npm-stats]: http://npm-stat.com/charts.html?package=badbadnotgood\u0026author=\u0026from=\u0026to=\n[npm-stats-shield]: https://img.shields.io/npm/dt/badbadnotgood.svg?maxAge=2592000\n[license]: ./LICENSE\n[license-shield]: https://img.shields.io/npm/l/badbadnotgood.svg\n[typescript]: https://www.typescriptlang.org/\n[typescript-shield]: https://img.shields.io/badge/definitions-TypeScript-blue.svg\n[build-status]: https://github.com/caseyWebb/badbadnotgood/actions/workflows/nodejs.yml\n[build-status-shield]: https://img.shields.io/github/workflow/status/caseyWebb/badbadnotgood/Node%20CI/master\n[codecov]: https://codecov.io/gh/caseyWebb/badbadnotgood\n[codecov-shield]: https://img.shields.io/codecov/c/github/caseyWebb/badbadnotgood.svg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaseywebb%2Fbadbadnotgood","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcaseywebb%2Fbadbadnotgood","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaseywebb%2Fbadbadnotgood/lists"}