{"id":17148910,"url":"https://github.com/planttheidea/switchem","last_synced_at":"2025-07-23T10:31:20.680Z","repository":{"id":65512074,"uuid":"112880332","full_name":"planttheidea/switchem","owner":"planttheidea","description":"An extensible, functional switch with a chainable API","archived":false,"fork":false,"pushed_at":"2019-05-04T02:41:45.000Z","size":279,"stargazers_count":35,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-17T11:05:40.479Z","etag":null,"topics":["functional-programming","javascript"],"latest_commit_sha":null,"homepage":null,"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/planttheidea.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}},"created_at":"2017-12-02T22:03:22.000Z","updated_at":"2023-04-17T18:27:14.000Z","dependencies_parsed_at":"2023-01-26T19:31:28.271Z","dependency_job_id":null,"html_url":"https://github.com/planttheidea/switchem","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/planttheidea/switchem","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planttheidea%2Fswitchem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planttheidea%2Fswitchem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planttheidea%2Fswitchem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planttheidea%2Fswitchem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/planttheidea","download_url":"https://codeload.github.com/planttheidea/switchem/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/planttheidea%2Fswitchem/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266473575,"owners_count":23934497,"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","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"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":["functional-programming","javascript"],"created_at":"2024-10-14T21:30:22.400Z","updated_at":"2025-07-23T10:31:20.643Z","avatar_url":"https://github.com/planttheidea.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# switchem\n\n\u003cimg src=\"https://img.shields.io/badge/build-passing-brightgreen.svg\"/\u003e\n\u003cimg src=\"https://img.shields.io/badge/coverage-100%25-brightgreen.svg\"/\u003e\n\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\"/\u003e\n\nAn extensible, functional switch with a chainable API\n\n## Table of contents\n\n* [Usage](#usage)\n* [switchem API](#switchem-api)\n  * [default](#default)\n  * [is](#is)\n  * [match](#match)\n  * [merge](#merge)\n  * [not](#not)\n* [Options](#options)\n  * [runMatchCallback](#runmatchcallback)\n* [Additional methods](#additional-methods)\n  * [addCustomCase](#addcustomcase)\n* [Browser support](#browser-support)\n* [Development](#development)\n\n## Usage\n\n```javascript\nimport switchem, { addCustomCase } from \"switchem\";\n\n// create switch statements with the chainable API\nconst sw1 = switchem()\n  .is(\"foo\", \"I am foo\")\n  .not(\"bar\", \"I am not bar\")\n  .default(\"I must be bar!\");\n\nconsole.log(sw1.match(\"baz\")); // I am not bar\nconsole.log(sw1.match(\"bar\")); // I must be bar!\n\n// extend existing switch statements by simply adding to them\nconst sw2 = sw1.is(value =\u003e {\n  return value === \"bar\";\n}, \"I am actually bar\");\n\nconsole.log(sw2.match(\"baz\")); // I am not bar\nconsole.log(sw2.match(\"bar\")); // I am actually bar\n\n// or add commonly-used cases for reuse\naddCustomCase(\"isDivisibleBy\", (testValue, matchValue) =\u003e {\n  return matchValue % testValue === 0;\n});\n\nconsole.log(\n  switchem()\n    .isDivisibleBy(7, \"divisible by seven\")\n    .match(49)\n); // divisible by seven\n```\n\n## switchem API\n\n#### default\n\n_default(defaultValue: any): Switchem_\n\nSet the default value for the switch, which is returned if none of the cases match.\n\n```javascript\nconst sw = switchem().default(\"default\");\n```\n\n#### is\n\n_is(testValue: any, matchResult: ?any = true): Switchem_\n\nAdd a case statement that tests for equality with the `matchValue`.\n\n```javascript\nconst sw = switchem()\n  // functions are executed passing the switched value\n  .is(value =\u003e {\n    return value % 2 === 0;\n  }, \"I am an even number\")\n  // regex values are tested via re.test()\n  .is(/bar/g, \"I contain bar\")\n  // NaN value comparisons are supported\n  .is(NaN, \"I am a NaN\")\n  // static values test for strict equality\n  .is(\"foo\", \"I am foo\");\n\nconsole.log(sw.match(4)); // I am an even number\nconsole.log(sw.match(\"bar\")); // I contain bar\nconsole.log(sw.match(\"foo\")); // I am foo\n```\n\nIf you provide a function as a `matchResult`, by default this will be called with both the `testValue` and the\n`matchValue`\n\n```javascript\nconst sw = switchem().is('foo', (testValue, matchValue) =\u003e {\n  return `${matchValue} match found: ${testValue}`.\n});\n\nconsole.log(sw.match('foo')); // foo match found: foo\n```\n\nThis setting can be disabled by setting `runMatchCallback` to `false` in `options`.\n\n#### match\n\n_match(matchValue: any): any_\n\nFind the match for `matchValue` based on the existing cases provided in the switch.\n\n```javascript\nconst sw = switchem().is(\"foo\", \"I am foo\");\n\nconsole.log(sw.match(\"foo\")); // I am foo\n```\n\n#### merge\n\n_merge(...switchems: Array\u003cSwitchem\u003e): Switchem_\n\nMerge the `switchem` instances passed into a new, combined instance.\n\n```javascript\nconst original = switchem();\nconst first = switchem()\n  .default(\"defaultValue\")\n  .is(\"first\", \"I am first\");\nconst second = switchem({ runMatchCallback: false }).is(\n  \"second\",\n  \"I am second\"\n);\n\nconst merged = original.merge(first, second);\n\n// merged is the same as\n// switchem({runMatchCallback: false})\n//   .default('defaultValue');\n//   .is('first', 'I am first')\n//   .is('second', 'I am second')\n```\n\n#### not\n\n_not(testValue: any, matchResult: ?any = true): Switchem_\n\nAdd a case statement that tests for non-equality with the `matchValue`.\n\n```javascript\nconst sw = switchem()\n  // functions are executed passing the switched value\n  .not(value =\u003e {\n    return value % 2 === 0;\n  }, \"I am an odd number\")\n  // regex values are tested via re.test()\n  .not(/bar/g, \"I do not contain bar\")\n  // static values test for strict equality\n  .not(\"foo\", \"I am not foo\");\n\nconsole.log(sw.match(3)); // I am an odd number\nconsole.log(sw.match(\"bar\")); // I am not foo\nconsole.log(sw.match(\"foo\")); // I do not contain bar\n```\n\nIf you provide a function as a `matchResult`, by default this will be called with both the `testValue` and the\n`matchValue`\n\n```javascript\nconst sw = switchem().not('foo', (testValue, matchValue) =\u003e {\n  return `${matchValue} non-match found: ${testValue}`.\n});\n\nconsole.log(sw.match('bar')); // bar non-match found: foo\n```\n\nThis setting can be disabled by setting `runMatchCallback` to `false` in `options`.\n\n## Options\n\n#### runMatchCallback\n\n_boolean, defaults to true_\n\nWhen this option is `true`, then any functions that are used as `matchResult` values will be executed upon match.\n\n```javascript\nconst sw = switchem().is(\"foo\", (testValue, matchValue) =\u003e {\n  return [matchValue, testValue];\n});\n\nconsole.log(sw.match(\"foo\")); // ['foo', 'foo']\n```\n\nWhen set to `false`, the method is returned like standard values.\n\n```javascript\nconst sw = switchem({ runMatchCallback: false }).is(\n  \"foo\",\n  (testValue, matchValue) =\u003e {\n    return [matchValue, testValue];\n  }\n);\n\nconsole.log(sw.match(\"foo\")); // (testValue, matchValue) =\u003e { return [matchValue, testValue]; }\n```\n\n## Additional methods\n\n#### addCustomCase\n\n_addCustomCase(name: string, method: function, isNot: ?boolean): void_\n\nAdds a custom case method to the `switchem` prototype, which provides convenient reuse of a commonly-applied case.\n\n```javascript\n// use existing utility methods\nimport { contains } from \"ramda\";\nimport { addCustomCase } from \"switchem\";\n\naddCustomCase(\"contains\", contains);\n\nconst sw1 = switchem().contains(\"bar\", \"I contain bar!\");\n\nconsole.log(sw1.match([\"foo\", \"bar\", \"baz\"])); // I contain bar!\n\n// or add your own\naddCustomCase(\n  \"notDivisibleBy\",\n  (testValue, matchValue) =\u003e {\n    return matchValue % testValue === 0;\n  },\n  true\n);\n\nconst sw2 = switchem().notDivisibleBy(7, \"not divisible by seven\");\n\nconsole.log(s2.match(12)); // not divisible by seven\n```\n\nThis method will be available for all uses of `switchem` after execution, so it is recommended to run this method as\nearly in your app initialization as possible.\n\n## Browser support\n\n* Chrome (all versions)\n* Firefox (all versions)\n* Edge (all versions)\n* Opera 15+\n* IE 9+\n* Safari 6+\n* iOS 8+\n* Android 4+\n\n## Development\n\nStandard stuff, clone the repo and `npm install` dependencies. The npm scripts available:\n\n* `build` =\u003e run rolup to build `dist` files\n* `dev` =\u003e run webpack dev server to run example app / playground\n* `dist` =\u003e runs `build` and `build-minified`\n* `lint` =\u003e run ESLint against all files in the `src` folder\n* `prepublish` =\u003e runs `compile-for-publish`\n* `prepublish:compile` =\u003e run `lint`, `test:coverage`, `transpile:es`, `transpile:lib`, `dist`\n* `test` =\u003e run AVA test functions with `NODE_ENV=test`\n* `test:coverage` =\u003e run `test` but with `nyc` for coverage checker\n* `test:watch` =\u003e run `test`, but with persistent watcher\n* `transpile:lib` =\u003e run babel against all files in `src` to create files in `lib`\n* `transpile:es` =\u003e run babel against all files in `src` to create files in `es`, preserving ES2015 modules (for\n  [`pkg.module`](https://github.com/rollup/rollup/wiki/pkg.module))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplanttheidea%2Fswitchem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplanttheidea%2Fswitchem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplanttheidea%2Fswitchem/lists"}