{"_id":"@codeforbreakfast/eslint-effect","_rev":"12-fe4e09b2b3e366d26a12bc8f1a42a651","name":"@codeforbreakfast/eslint-effect","dist-tags":{"latest":"0.8.5"},"versions":{"0.3.1":{"name":"@codeforbreakfast/eslint-effect","version":"0.3.1","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.3.1","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"d01326941b38dc255e036b6257506c03b428a2fe","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.3.1.tgz","fileCount":24,"integrity":"sha512-aIPbB/27IqtMp7oGRvOKrJ99J9TxpxfNvQ6b/kuwZmyaI4znggPgAFc4KBqP+lPBT+K+mEsyCSx1Cj4CrlOIkg==","signatures":[{"sig":"MEYCIQD32eHzFkMFfQXfsXyE9txAEgPkSSSJVCAIcnanmH91zAIhAJl0bP/n42Sq+QjzIsWevKRqizzw/t4imn2Xt82h1Yqr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47734},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"1500c6b967551211b5ba7909fbe38d348f1d745e","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","typecheck":"tsc --noEmit","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"graemef","email":"graemef@gmail.com"},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.1","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.1","eslint":"9.36.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.45.0"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.3.1_1759730194747_0.04000983611375242","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@codeforbreakfast/eslint-effect","version":"0.4.0","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.4.0","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"35b2320c258e676085630e717179f2096834d892","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.4.0.tgz","fileCount":25,"integrity":"sha512-ozohRqz0fuOV5l1BWbty02RsU9sEyNDKuwW4wLlmQVTFfUpV28BKjiwTZiiWyjxk1Ho2f/ssq/fxAyWTMhgAdg==","signatures":[{"sig":"MEYCIQDr959dnJayO/DSBnydgRk7CCd5/m5iZQMjI+cyt6rpTgIhAJQ0BAKacXKXIK6oN7ye/CxFtfbNN4eF5y1iQIpD0ILX","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":53525},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"efdca8c19bb1d2208878323b4da9f31c767d590b","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","typecheck":"tsc --noEmit","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.1","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.1","eslint":"9.36.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.45.0"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.4.0_1759736438758_0.6437884146027066","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@codeforbreakfast/eslint-effect","version":"0.5.0","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.5.0","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"b9b0272616e45010288eb38e55a0981d230888b2","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.5.0.tgz","fileCount":28,"integrity":"sha512-L0Xne8QM29s2czlMIXbPpxz8M0cO8h3cAfJ0h5mnQUdTqwqmINrYayDbu4Br5pWGC28THXFZW6fUdVgdTKzBzg==","signatures":[{"sig":"MEQCICIhflx6xDs4K3AbPDdI6jBJPdzTI/PRuSg9+2f8NHqTAiAA7bwGYk1wp1yoW5/4C9GWaD890DMm/zws2sST+jSlIQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":72051},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"37f4fc8c1953c6018760271ab3d6b8c4d30ec88c","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","typecheck":"tsc --noEmit","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.1","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.1","eslint":"9.36.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.45.0"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.5.0_1759854550107_0.5882942311243502","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@codeforbreakfast/eslint-effect","version":"0.5.1","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.5.1","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"8d54ce312cbcd28d87e5eaf7e037ab98836e51fd","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.5.1.tgz","fileCount":28,"integrity":"sha512-z9jTKIUmovO8E58seB0Rsv6dcTiRf+zcLkZ/2mRd5Y67BsDcba1RZSV5/GovAaxiWrl1fuQIaSadhmhYEEAlJg==","signatures":[{"sig":"MEQCIEjkIlnip9UtJHO2LZSw5OturS1ZkoKchfQ71its8xhIAiBoxxYxFjqFSuESv9u5u3CLNWOPsRXAtI8d//OfhlRHIw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.5.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":72155},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"d73b2ba6e93202dcde351d82d086bf03b398b9cf","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","typecheck":"tsc --noEmit","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.1","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.1","eslint":"9.36.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.45.0"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.5.1_1759857589957_0.6076387273703474","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@codeforbreakfast/eslint-effect","version":"0.6.0","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.6.0","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"41b41c0a6156df7e41d8db635856e1ed1602dc3b","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.6.0.tgz","fileCount":28,"integrity":"sha512-wZtQtGBSn7JuTJmkEcPzHOlv6Xte0ShNQAiE4YFa+wXMJefjtPsql+VqQaERQ8DGmjUYV5+7NwDmVk5TXWPU/Q==","signatures":[{"sig":"MEUCIASOdpxQ+McjNK8S3dD/LUGCb/xm2SgfM8WGiiou98vYAiEAvk4FamIdLle3ThRczvlgNTp1+1FVE2+BwQUUgL15kcQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":73406},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"4ae12022a87429f7d3c63fefe1b76d36ac20b2f1","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","typecheck":"tsc --noEmit","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.1","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.1","eslint":"9.36.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.45.0"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.6.0_1759865366146_0.2686905969548228","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@codeforbreakfast/eslint-effect","version":"0.7.0","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.7.0","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"a93bfece4f675b8b8de28eb15ba820e44b759da4","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.7.0.tgz","fileCount":31,"integrity":"sha512-7pSDeC85yfrs/ehDHuOTUhKbCBt4fIAYNl5jeJPXU0rRgSrnoN7QIZylrUkNb17FSDNL9etvPyy4ujWlLcIQBA==","signatures":[{"sig":"MEUCIQCnA8C4bRcH/qY7qa5LQucRE+nGTu/NANndFMNFuEho2gIgUlIzNBckF9srGo37VkCSDtZoEtKbHnhHTktqt1cuDLE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":97212},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"a08bc28abdeee0246774319e45da970b1a47a151","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","typecheck":"tsc --noEmit","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.1","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.4","eslint":"9.36.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.45.0"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.7.0_1760169352155_0.20390860105051778","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@codeforbreakfast/eslint-effect","version":"0.8.0","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.8.0","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"e1f504e8cf0cb24b7220f5e8eb7e8b8cd90f4018","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.8.0.tgz","fileCount":47,"integrity":"sha512-Y2SroH9RvVdGULeTO8vH3OYDHAQNrTmvqS4x5U920De/h7rOpflLYJkCUwkhSnIkiwPBFb5LmfYDQiR/AL8KJw==","signatures":[{"sig":"MEQCIGszYSvYuYODtU+SS3+kL7qUSXY8JTPwf9D3Dmluqx+9AiBadeK90MPX0i8yGsQgo8gyLTVHmyPRAxW6T5X2go9ncw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":140465},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"6b33e587b5948de08c6fcfd7bebc0f93e22cd24b","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","lint:fix":"eslint test --ext .ts,.tsx --fix","typecheck":"tsc --noEmit","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.1","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.4","eslint":"9.36.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.45.0"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.8.0_1760267626700_0.22815321834390434","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"@codeforbreakfast/eslint-effect","version":"0.8.1","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.8.1","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"a4d75d884a38079e85776f9c2717994b141454de","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.8.1.tgz","fileCount":47,"integrity":"sha512-oLEnCTo9SA7qmjEeCPvpWsq2ginEIWaX8kjZPwDc24cEQM1elqKgkRLW+aMIM7hH+3Vw1gJlTHQrv4odq26BKg==","signatures":[{"sig":"MEUCIGAgbBUTkYczzmukLEvjvGvsKnGV0S0JP+00WAGhgZDOAiEA3ErOgXt1bDijBurghS1hQeZ7jjQMiaY0UnArS8tqa34=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.8.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":140465},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"9a0cf95148b537619dc335179b79babe00392378","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","lint:fix":"eslint test --ext .ts,.tsx --fix","typecheck":"tsc --noEmit","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.1","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.4","eslint":"9.37.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.46.0"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.8.1_1760269903224_0.07330312095165614","host":"s3://npm-registry-packages-npm-production"}},"0.8.2":{"name":"@codeforbreakfast/eslint-effect","version":"0.8.2","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.8.2","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"e638e693cb69ccffc9f9088e6b852ee5f087a4c7","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.8.2.tgz","fileCount":47,"integrity":"sha512-m3nDf/xQvd1fOwFxSfVtT8UozKDZpLuDaS2MlqiBGRYUwNY8lMXu92Pjhv9gSAWqKa4VbLPj0zHX6FoezeNhEA==","signatures":[{"sig":"MEQCIFJHiOMAxok8g18JSao47vXOdXJ73nJ1Q6Yc+vXtCyb6AiA/5SLRV9cXXez7ogqnTSGfDkkRU78+KTxwmn6c1g2BXQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.8.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":148388},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"209ef435978ce052d57ea888fdc847b07011a674","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","lint:fix":"eslint test --ext .ts,.tsx --fix","typecheck":"tsc --noEmit","validate:docs":"bun ../../scripts/validate-markdown-examples.ts","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.2","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.4","eslint":"9.37.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.46.0"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.8.2_1760430179270_0.9727089065210746","host":"s3://npm-registry-packages-npm-production"}},"0.8.3":{"name":"@codeforbreakfast/eslint-effect","version":"0.8.3","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.8.3","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"a00648d5082ddd4cf6d42756d85973cffc783b61","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.8.3.tgz","fileCount":47,"integrity":"sha512-gcDPyLsqFyK3XFlzXs2G6RcCaKlCcdWtnYCeqkOh6gcdxXuulS4hKQ7sHquvrOwfOepKXEGevoc+7Rwfsil0PA==","signatures":[{"sig":"MEYCIQDXnO8sXIt8wkmXWkGWy3kPZT4QAUbjzZWPDJe6g4jYJQIhAJndxWQqNVu1ij5uE9Rx9zIE9JRVsRp5vDeHL/BOht0R","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.8.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":148388},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"8aeb86d53d72d178720c7a9543b57a8a85177f25","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","lint:fix":"eslint test --ext .ts,.tsx --fix","typecheck":"tsc --noEmit","validate:docs":"bun ../../scripts/validate-markdown-examples.ts","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.2","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.4","eslint":"9.38.0","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.46.2"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.8.3_1761488004813_0.11698077851534538","host":"s3://npm-registry-packages-npm-production"}},"0.8.4":{"name":"@codeforbreakfast/eslint-effect","version":"0.8.4","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"author":{"name":"CodeForBreakfast"},"license":"MIT","_id":"@codeforbreakfast/eslint-effect@0.8.4","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"dist":{"shasum":"2e934602beecc81b712bcb2ed7ea0abec1a207ed","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.8.4.tgz","fileCount":47,"integrity":"sha512-dm0mUDrTIg5sA4lOre96cJIJjgzw6M2WJ/YP2MhFT7oeJO5+DeE/rk1NUH9+Qb9OaKR1zBetR26QHuz32tqjuw==","signatures":[{"sig":"MEQCIEZIcZTtFVhMe9Qsjdr9EAeHlLSn/zX3MYoGk8RbuplCAiAS24N+4xCsRiz32mbtGTYCUSb8UubJ2uyW/MM4CGnohg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.8.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":149146},"type":"module","exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"gitHead":"ddd4e26bd3ae5c5bc48b3dc81ddf336a9ce7d95a","scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","test":"bun run lint && bun run typecheck","lint:fix":"eslint test --ext .ts,.tsx --fix","typecheck":"tsc --noEmit","validate:docs":"bun ../../scripts/validate-markdown-examples.ts","validate:pack":"bun pm pack --dry-run","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"repository":{"url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","type":"git","directory":"packages/eslint-effect"},"_npmVersion":"11.6.2","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"effect":"3.18.4","eslint":"9.39.1","typescript":"5.9.3","@typescript-eslint/eslint-plugin":"8.46.3"},"peerDependencies":{"eslint":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-effect_0.8.4_1763205759961_0.5455169426559536","host":"s3://npm-registry-packages-npm-production"}},"0.8.5":{"name":"@codeforbreakfast/eslint-effect","version":"0.8.5","description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","type":"module","license":"MIT","author":{"name":"CodeForBreakfast"},"repository":{"type":"git","url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","directory":"packages/eslint-effect"},"keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"publishConfig":{"access":"public"},"exports":{".":"./src/index.js","./rules":"./src/rules/index.js","./configs":"./src/configs.js"},"scripts":{"lint":"eslint test --ext .ts,.tsx --report-unused-disable-directives","lint:fix":"eslint test --ext .ts,.tsx --fix","typecheck":"tsc --noEmit","test":"bun run lint && bun run typecheck","validate:pack":"bun pm pack --dry-run","validate:docs":"bun ../../scripts/validate-markdown-examples.ts","check:publishable":"npm view $npm_package_name@$npm_package_version version >/dev/null 2>&1 && exit 1 || exit 0"},"peerDependencies":{"eslint":">=8.0.0"},"devDependencies":{"eslint":"9.39.1","@typescript-eslint/eslint-plugin":"8.46.3","typescript":"5.9.3","effect":"3.19.9"},"gitHead":"dc9291553d278cb59572e9fb1569fe0c01194eea","_id":"@codeforbreakfast/eslint-effect@0.8.5","bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","_nodeVersion":"20.19.6","_npmVersion":"11.6.2","dist":{"integrity":"sha512-kLPfNVgBMEXRR2lGtm4SwATNW6hVy2aU50cIk5CB1TuSR9bptXiILBnMRqNF1skBvztCdRKQl+2OaLD3/gtrjw==","shasum":"129c4512a174c69b8544a73bd643395cf452e3e0","tarball":"https://registry.npmjs.org/@codeforbreakfast/eslint-effect/-/eslint-effect-0.8.5.tgz","fileCount":47,"unpackedSize":149146,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codeforbreakfast%2feslint-effect@0.8.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHXCPEFeqa+W+xEt1rQ1lu7Wzl5mF2OieOCIRB77YJktAiBmUhzp/fOAQgYvYxYTyww+wps/s63x94v0DL2P+JJ33g=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:06f713fb-c24d-4965-900b-72505adf150d"}},"directories":{},"maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/eslint-effect_0.8.5_1765443327663_0.5107196806181902"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-06T05:56:34.598Z","modified":"2025-12-11T08:55:28.199Z","0.3.1":"2025-10-06T05:56:34.971Z","0.4.0":"2025-10-06T07:40:38.948Z","0.5.0":"2025-10-07T16:29:10.318Z","0.5.1":"2025-10-07T17:19:50.154Z","0.6.0":"2025-10-07T19:29:26.336Z","0.7.0":"2025-10-11T07:55:52.361Z","0.8.0":"2025-10-12T11:13:46.894Z","0.8.1":"2025-10-12T11:51:43.444Z","0.8.2":"2025-10-14T08:22:59.426Z","0.8.3":"2025-10-26T14:13:25.013Z","0.8.4":"2025-11-15T11:22:40.242Z","0.8.5":"2025-12-11T08:55:27.808Z"},"bugs":{"url":"https://github.com/CodeForBreakfast/eventsourcing/issues"},"author":{"name":"CodeForBreakfast"},"license":"MIT","homepage":"https://github.com/CodeForBreakfast/eventsourcing#readme","keywords":["eslint","eslint-plugin","effect","effect-ts","functional-programming","typescript","linting"],"repository":{"type":"git","url":"git+https://github.com/CodeForBreakfast/eventsourcing.git","directory":"packages/eslint-effect"},"description":"ESLint rules and configurations for Effect projects enforcing functional programming best practices","maintainers":[{"name":"graemef","email":"graemef@gmail.com"}],"readme":"# @codeforbreakfast/eslint-effect\n\nESLint rules and configurations for Effect projects that enforce functional programming best practices and idiomatic Effect code patterns.\n\n## Installation\n\n```bash\nnpm install --save-dev @codeforbreakfast/eslint-effect\n# or\nbun add --dev @codeforbreakfast/eslint-effect\n```\n\n## Features\n\nThis package provides:\n\n- **Custom ESLint Rules** for Effect-specific patterns\n- **Syntax Restrictions** to enforce functional programming principles\n- **Pre-configured Rule Sets** for different contexts\n- **Functional Immutability Rules** tailored for Effect types\n\n## Custom Rules\n\n### `no-unnecessary-pipe-wrapper`\n\nDetects unnecessary function wrappers around single pipe operations.\n\n❌ Bad:\n\n```typescript\nimport { pipe } from 'effect';\n\ndeclare const transform: (x: unknown) => unknown;\n\nconst fn = (x: unknown) => pipe(x, transform);\n```\n\n✅ Good:\n\n```typescript\ndeclare const transform: (x: unknown) => unknown;\n\nconst fn = transform;\n```\n\n### `no-eta-expansion`\n\nDetects unnecessary function wrappers (eta-expansion) that only pass parameters directly to another function. Also known as \"prefer point-free style.\"\n\n❌ Bad:\n\n```typescript\nimport { Console } from 'effect';\n\ndeclare const doSomething: (x: number) => unknown;\ndeclare const processData: (a: string, b: number) => unknown;\n\nconst logError = (msg: string) => Console.error(msg);\nconst transform = (x: number) => doSomething(x);\nconst handler = (a: string, b: number) => processData(a, b);\n```\n\n✅ Good:\n\n```typescript\nimport { Console } from 'effect';\n\ndeclare const doSomething: (x: number) => unknown;\ndeclare const processData: (a: string, b: number) => unknown;\n\nconst logError = Console.error;\nconst transform = doSomething;\nconst handler = processData;\n```\n\n**Rationale**: In functional programming, eta-reduction (λx.f(x) → f) eliminates unnecessary indirection. When a function only passes its parameters directly to another function without any transformation, the wrapper adds no value and reduces readability.\n\n### `no-unnecessary-function-alias`\n\nDetects unnecessary function aliases that provide no semantic value. When a constant is assigned directly to another function without adding clarity or abstraction, it should be inlined at the call site.\n\n❌ Bad:\n\n```typescript\nimport { Array, Ref } from 'effect';\n\ndeclare const ref: Ref.Ref<unknown>;\ndeclare const arr: readonly unknown[];\ndeclare function useOnce(val: unknown): void;\ndeclare function useTwice(val: unknown): void;\n\nconst getState = Ref.get;\nconst transform = Array.map;\n\n// Used only once or twice\nuseOnce(getState(ref));\nuseTwice(transform(arr, (x: unknown) => (x as number) * 2));\n```\n\n✅ Good:\n\n```typescript\nimport { Array, Ref, Stream } from 'effect';\n\ndeclare const ref: Ref.Ref<unknown>;\ndeclare const arr: readonly unknown[];\ndeclare function useOnce(val: unknown): void;\ndeclare function useTwice(val: unknown): void;\n\n// Inline when used infrequently\nuseOnce(Ref.get(ref));\nuseTwice(Array.map(arr, (x: unknown) => (x as number) * 2));\n\n// OR keep the alias if it adds semantic value\n// eslint-disable-next-line effect/no-unnecessary-function-alias -- Alias clarifies stream processing context\nconst collectStreamResults = Stream.runCollect;\n```\n\n**Configuration:**\n\n- `maxReferences` (default: `2`) - Maximum number of references before alias is considered justified\n\n```javascript\n{\n  rules: {\n    'effect/no-unnecessary-function-alias': ['warn', {\n      maxReferences: 3,  // Allow aliases used 3+ times\n    }]\n  }\n}\n```\n\n**Rationale**: Function aliases that are used only once or twice add cognitive overhead without meaningful benefit. They force readers to jump between the alias definition and usage site. Direct function calls are more straightforward. However, aliases that are used frequently (3+ times) or that add semantic clarity through their name should be kept.\n\n### `prefer-match-tag`\n\nEnforces `Match.tag()` over `Match.when()` for `_tag` discriminators.\n\n❌ Bad:\n\n```typescript\nimport { Match, pipe } from 'effect';\n\ntype Tagged = { _tag: 'Success' } | { _tag: 'Error' };\ndeclare const value: Tagged;\ndeclare const handler: (val: { _tag: 'Success' }) => unknown;\n\npipe(Match.value(value), Match.when({ _tag: 'Success' }, handler));\n```\n\n✅ Good:\n\n```typescript\nimport { Match, pipe } from 'effect';\n\ntype Tagged = { _tag: 'Success' } | { _tag: 'Error' };\ndeclare const value: Tagged;\ndeclare const handler: (val: { _tag: 'Success' }) => unknown;\n\npipe(Match.value(value), Match.tag('Success', handler));\n```\n\n### `prefer-match-over-conditionals`\n\nEncourages declarative `Match` patterns over imperative `if` statements in Effect callbacks.\n\n❌ Bad:\n\n```typescript\nimport { Effect, Match, pipe } from 'effect';\n\ntype TaggedValue = { _tag: 'Success' } | { _tag: 'Error' };\ndeclare const handleSuccess: (x: { _tag: 'Success' }) => Effect.Effect<unknown>;\ndeclare const handleError: (x: TaggedValue) => Effect.Effect<unknown>;\ndeclare const effectValue: Effect.Effect<TaggedValue>;\n\npipe(\n  effectValue,\n  Effect.flatMap((x: TaggedValue) => {\n    if (x._tag === 'Success') return handleSuccess(x);\n    return handleError(x);\n  })\n);\n```\n\n✅ Good:\n\n```typescript\nimport { Effect, Match, pipe } from 'effect';\n\ntype TaggedValue = { _tag: 'Success' } | { _tag: 'Error' };\ndeclare const handleSuccess: (x: { _tag: 'Success' }) => Effect.Effect<unknown>;\ndeclare const handleError: (x: TaggedValue) => Effect.Effect<unknown>;\ndeclare const effectValue: Effect.Effect<TaggedValue>;\n\npipe(\n  effectValue,\n  Effect.flatMap((x: TaggedValue) =>\n    pipe(Match.value(x), Match.tag('Success', handleSuccess), Match.orElse(handleError))\n  )\n);\n```\n\n### `prefer-effect-if-over-match-boolean`\n\nEnforces `Effect.if` over `Match.value` for boolean conditionals. `Match.value` should be reserved for pattern matching on multiple values, not simple true/false branches.\n\n❌ Bad:\n\n```typescript\nimport { Effect, Match, pipe } from 'effect';\n\ndeclare const isValid: boolean;\ndeclare const user: { isAdmin: boolean };\ndeclare function grantAccess(): Effect.Effect<unknown>;\ndeclare function denyAccess(): Effect.Effect<unknown>;\n\npipe(\n  isValid,\n  Match.value,\n  Match.when(true, () => Effect.succeed('valid')),\n  Match.when(false, () => Effect.fail('invalid')),\n  Match.exhaustive\n);\n\npipe(\n  user.isAdmin,\n  Match.value,\n  Match.when(true, () => grantAccess()),\n  Match.when(false, () => denyAccess()),\n  Match.exhaustive\n);\n```\n\n✅ Good:\n\n```typescript\nimport { Effect } from 'effect';\n\ndeclare const isValid: boolean;\ndeclare const user: { isAdmin: boolean };\ndeclare function grantAccess(): Effect.Effect<unknown>;\ndeclare function denyAccess(): Effect.Effect<unknown>;\n\nEffect.if(isValid, {\n  onTrue: () => Effect.succeed('valid'),\n  onFalse: () => Effect.fail('invalid'),\n});\n\nEffect.if(user.isAdmin, {\n  onTrue: () => grantAccess(),\n  onFalse: () => denyAccess(),\n});\n```\n\n**Rationale**: `Match.value` is designed for pattern matching on discriminated unions and multiple values. Using it for simple boolean conditions is verbose and obscures intent. `Effect.if` is explicit, concise, and clearly communicates boolean branching logic.\n\n### `prefer-match-over-ternary`\n\nEncourages declarative `Match.value` patterns over ternary operators when pattern matching on non-boolean values or selecting between function calls.\n\n**Note**: For boolean conditions returning Effects, use `Effect.if` instead (see `prefer-effect-if-over-match-boolean` rule above).\n\n❌ Bad:\n\n```typescript\nimport { Option, Stream } from 'effect';\n\ntype FilterFn = (v: unknown) => boolean;\ndeclare const filter: FilterFn | undefined;\ndeclare const stream: Stream.Stream<unknown>;\ndeclare function processValue(val: number): unknown;\ndeclare function getDefault(): unknown;\ndeclare function finalizeTask(): unknown;\ndeclare function continueTask(): unknown;\n\nconst result = filter !== undefined ? Stream.filter(stream, filter) : stream;\n\nconst handler = (option: Option.Option<number>) =>\n  Option.isSome(option) ? processValue(option.value) : getDefault();\n\nconst processStatus = (status: 'pending' | 'active' | 'complete') =>\n  status === 'complete' ? finalizeTask() : continueTask();\n```\n\n✅ Good:\n\n```typescript\nimport { Match, Option, pipe, Stream } from 'effect';\n\ntype FilterFn = (v: unknown) => boolean;\ndeclare const filter: FilterFn | undefined;\ndeclare const stream: Stream.Stream<unknown>;\ndeclare function processValue(val: number): unknown;\ndeclare function getDefault(): unknown;\ndeclare function finalizeTask(): unknown;\ndeclare function continueTask(): unknown;\n\nconst result = pipe(\n  filter,\n  Match.value,\n  Match.when(Match.undefined, () => stream),\n  Match.orElse((f) => Stream.filter(stream, f))\n);\n\nconst handler = (option: Option.Option<number>) =>\n  pipe(\n    option,\n    Match.value,\n    Match.when({ _tag: 'Some' }, (opt) => processValue(opt.value)),\n    Match.orElse(getDefault)\n  );\n\nconst processStatus = (status: 'pending' | 'active' | 'complete') =>\n  pipe(status, Match.value, Match.when('complete', finalizeTask), Match.orElse(continueTask));\n```\n\n**For boolean conditions with Effects, use `Effect.if`:**\n\n```typescript\nimport { Effect } from 'effect';\n\ndeclare const condition: boolean;\n\n// Boolean condition returning Effects - use Effect.if, NOT Match.value\nconst result = Effect.if(condition, {\n  onTrue: () => Effect.succeed(42),\n  onFalse: () => Effect.fail('error'),\n});\n```\n\n**Rationale**: Ternary operators are imperative and less composable than `Match` patterns. Using `Match.value` provides better composability for pattern matching on values like optional types, union types, or non-boolean conditions. However, for simple boolean conditionals returning Effects, `Effect.if` is the preferred pattern as it's more explicit and type-safe. Plain value ternaries (not function calls) are allowed as they're appropriate for simple value selection.\n\n### `no-switch-statement`\n\nForbids switch statements in functional Effect code. Switch statements are imperative and don't provide exhaustiveness checking. Use `Match` for type-safe, exhaustive pattern matching.\n\n❌ Bad:\n\n```typescript\nimport { Match, pipe } from 'effect';\n\ntype Event = { type: 'Created' } | { type: 'Updated' } | { type: 'Other' };\ndeclare const event: Event;\ndeclare function handleCreated(e: Event): unknown;\ndeclare function handleUpdated(e: Event): unknown;\ndeclare function handleUnknown(e: Event): unknown;\n\nfunction processEvent() {\n  switch (event.type) {\n    case 'Created':\n      return handleCreated(event);\n    case 'Updated':\n      return handleUpdated(event);\n    default:\n      return handleUnknown(event);\n  }\n}\n```\n\n✅ Good:\n\n```typescript\nimport { Match, pipe } from 'effect';\n\ntype Event = { type: 'Created' } | { type: 'Updated' } | { type: 'Other' };\ndeclare const event: Event;\ndeclare function handleCreated(e: Event): unknown;\ndeclare function handleUpdated(e: Event): unknown;\ndeclare function handleUnknown(e: Event): unknown;\n\npipe(\n  Match.value(event),\n  Match.when({ type: 'Created' }, handleCreated),\n  Match.when({ type: 'Updated' }, handleUpdated),\n  Match.orElse(handleUnknown)\n);\n```\n\n**For discriminated unions with `_tag`:**\n\n```typescript\nimport { Match, pipe } from 'effect';\n\ntype TaggedEither = { _tag: 'Right'; value: unknown } | { _tag: 'Left'; error: unknown };\ndeclare const either: TaggedEither;\ndeclare function handleRight(val: { _tag: 'Right'; value: unknown }): unknown;\ndeclare function handleLeft(val: { _tag: 'Left'; error: unknown }): unknown;\n\npipe(\n  Match.value(either),\n  Match.tag('Right', handleRight),\n  Match.tag('Left', handleLeft),\n  Match.exhaustive\n);\n```\n\n### `no-if-statement`\n\nForbids if statements in functional Effect code. If statements are imperative and don't compose well. Use `Effect.if` for boolean conditionals with Effects, `Match.value` for pattern matching, or type-specific matchers for declarative control flow.\n\n❌ Bad:\n\n```typescript\nimport { Effect, Option, pipe } from 'effect';\n\ndeclare const todoState: { deleted: boolean };\ndeclare const event: { type: string; data: { title: string } };\ndeclare const option: Option.Option<string>;\ndeclare const state: Option.Option<{ deleted: boolean }>;\ndeclare const defaultValue: string;\n\n// Bad pattern 1\nfunction check1() {\n  if (todoState.deleted) {\n    return Effect.fail(new Error('Cannot complete deleted TODO'));\n  }\n  return Effect.succeed(todoState);\n}\n\n// Bad pattern 2\nfunction check2() {\n  if (event.type === 'TodoCreated') {\n    return Effect.succeed({ title: event.data.title, completed: false });\n  }\n  return pipe(state, Option.match({ onNone: () => defaultValue, onSome: (s) => s }));\n}\n\n// Bad pattern 3\nfunction check3() {\n  if (Option.isSome(option)) {\n    return option.value;\n  }\n  return defaultValue;\n}\n```\n\n✅ Good:\n\n```typescript\nimport { Effect, Option, Match, pipe } from 'effect';\n\ndeclare const todoState: { deleted: boolean };\ndeclare const event: { type: string; data: { title: string } };\ndeclare const option: Option.Option<string>;\ndeclare const state: Option.Option<{ deleted: boolean }>;\ndeclare const defaultValue: string;\ndeclare const condition: boolean;\n\n// Boolean conditionals with Effects\nEffect.if(todoState.deleted, {\n  onTrue: () => Effect.fail(new Error('Cannot complete deleted TODO')),\n  onFalse: () => Effect.succeed(todoState),\n});\n\n// Pattern matching on discriminated unions\npipe(\n  event,\n  Match.value,\n  Match.when({ type: 'TodoCreated' }, (e) =>\n    Effect.succeed({ title: e.data.title, completed: false })\n  ),\n  Match.orElse((e) => pipe(state, Option.match({ onNone: () => defaultValue, onSome: (s) => s })))\n);\n\n// Option/Either with built-in matchers\npipe(\n  option,\n  Option.getOrElse(() => defaultValue)\n);\n\n// Simple value selection - use ternary operators\nconst x = condition ? 'yes' : 'no';\n```\n\n**Rationale**: If statements break functional composition and make code harder to reason about. They don't provide exhaustiveness checking for pattern matching and can't be easily composed in pipes. Using `Effect.if`, `Match.value`, or type-specific matchers like `Option.match` provides better type safety, exhaustiveness checking, and composability. Ternary operators are still allowed for simple value selection as they're appropriate for plain values.\n\n### `prefer-schema-validation-over-assertions`\n\nDiscourages type assertions in Effect callbacks in favor of runtime validation.\n\n❌ Bad:\n\n```typescript\nimport { Effect } from 'effect';\n\ntype MyType = { value: string };\ndeclare function handler(x: MyType): unknown;\n\nEffect.map((x: unknown) => handler(x as MyType));\n```\n\n✅ Good:\n\n```typescript\nimport { Effect, pipe, Schema } from 'effect';\n\ntype MyType = { value: string };\ndeclare const MyTypeSchema: Schema.Schema<MyType>;\ndeclare const input: Effect.Effect<unknown>;\ndeclare function handler(x: MyType): unknown;\n\npipe(input, Effect.flatMap(Schema.decodeUnknown(MyTypeSchema)), Effect.map(handler));\n```\n\n### `suggest-currying-opportunity`\n\nSuggests currying user-defined functions to eliminate arrow function wrappers in pipe chains. By default, only suggests currying when parameters are already in the right order (no reordering needed) and limits to single-level currying for readability.\n\n#### ✅ Will Suggest (good pattern - params already at end):\n\n```typescript\nimport { Effect } from 'effect';\n\ndeclare const myEffect: Effect.Effect<unknown>;\ndeclare function logError(message: string, error: unknown): Effect.Effect<void>;\n\n// Before\nEffect.catchAll(myEffect, (error) => logError('Failed', error));\n\n// After currying (params already in right order)\nconst logErrorCurried = (message: string) => (error: unknown) =>\n  Effect.sync(() => console.error(message, error));\n\nEffect.catchAll(myEffect, logErrorCurried('Failed'));\n```\n\n#### ⚠️ Won't Suggest by Default (would require parameter reordering):\n\n```typescript\nimport { Effect } from 'effect';\n\ndeclare const myEffect: Effect.Effect<unknown>;\ndeclare function logError(error: unknown, message: string): Effect.Effect<void>;\n\n// This would break semantic order - error should come before message\nEffect.catchAll(myEffect, (error) => logError(error, 'Failed'));\n\n// Would require changing to: logError = (message) => (error) => ...\n// But semantically, error should come first in the return object\n```\n\n#### ⚠️ Won't Suggest by Default (would create deep currying):\n\n```typescript\nimport { Effect } from 'effect';\n\ndeclare const myEffect: Effect.Effect<unknown>;\ndeclare function processData(prefix: string, suffix: string, data: unknown): unknown;\n\n// Would create 2-level currying: (prefix) => (suffix) => (data) => ...\nEffect.map(myEffect, (data) => processData('prefix', 'suffix', data));\n\n// Too many parentheses at call site: processData('prefix')('suffix')\n```\n\n**Configuration Options:**\n\n- `allowReordering` (default: `false`) - Allow suggestions even when parameters would need reordering\n- `maxCurriedParams` (default: `1`, max: `3`) - Maximum number of curried parameters to suggest\n\n```javascript\n{\n  rules: {\n    'effect/suggest-currying-opportunity': ['warn', {\n      allowReordering: true,    // Allow parameter reordering suggestions\n      maxCurriedParams: 2,      // Allow up to 2-level currying\n    }]\n  }\n}\n```\n\n**Note:** This rule only triggers on user-defined functions, not Effect library functions.\n\n### `no-intermediate-effect-variables`\n\nForbids storing Effect/Stream/pipe results in intermediate variables when they should be inlined into pipe chains. Configuration data like Schedule constants, retry policies, and Effect values passed as parameters are allowed.\n\n❌ Bad (should inline):\n\n```typescript\nimport { Effect, pipe, Schema } from 'effect';\n\ntype User = { id: string; name: string };\ndeclare const userId: string;\ndeclare const UserSchema: Schema.Schema<User>;\ndeclare const data: unknown;\ndeclare function fetchUser(id: string): Effect.Effect<User>;\ndeclare function validateUser(u: User): Effect.Effect<User>;\ndeclare function formatUserData(u: User): unknown;\ndeclare function processUser(u: User): User;\ndeclare function saveToDatabase(u: User): Effect.Effect<void>;\n\n// Breaking up the pipe chain for a single use\nconst userEffect = fetchUser(userId);\nconst result = pipe(userEffect, Effect.flatMap(validateUser), Effect.map(formatUserData));\n\n// Storing intermediate pipe results used once\nfunction processData() {\n  const validated = pipe(data, Schema.decodeUnknown(UserSchema));\n  const processed = Effect.map(validated, processUser);\n  return Effect.flatMap(processed, saveToDatabase);\n}\n\n// Schema defined but only used once\nconst UserIdSchema = pipe(Schema.String, Schema.nonEmptyString());\nexport const decodeUserId = Schema.decode(UserIdSchema); // Only usage\n```\n\n✅ Good (inline pipeline values):\n\n```typescript\nimport { Effect, pipe, Schema } from 'effect';\n\ntype User = { id: string; name: string };\ndeclare const userId: string;\ndeclare const UserSchema: Schema.Schema<User>;\ndeclare const data: unknown;\ndeclare function fetchUser(id: string): Effect.Effect<User>;\ndeclare function validateUser(u: User): Effect.Effect<User>;\ndeclare function formatUserData(u: User): unknown;\ndeclare function processUser(u: User): User;\ndeclare function saveToDatabase(u: User): Effect.Effect<void>;\n\n// Single cohesive pipe chain\nconst result = pipe(fetchUser(userId), Effect.flatMap(validateUser), Effect.map(formatUserData));\n\n// All transformations in one composition\nfunction processData() {\n  return pipe(\n    data,\n    Schema.decodeUnknown(UserSchema),\n    Effect.map(processUser),\n    Effect.flatMap(saveToDatabase)\n  );\n}\n\n// Schema inlined directly\nexport const decodeUserId = Schema.decode(pipe(Schema.String, Schema.nonEmptyString()));\n```\n\n✅ Good (configuration data):\n\n```typescript\nimport { Effect, pipe, Schedule } from 'effect';\n\ndeclare const operation: Effect.Effect<unknown>;\n\n// Schedule constants used as configuration\nconst retrySchedule = pipe(\n  Schedule.exponential('100 millis'),\n  Schedule.union(Schedule.spaced('1 second'))\n);\nconst result = pipe(operation, Effect.retry(retrySchedule));\n\n// Effect values used as parameters\nconst defaultValue = Effect.succeed(42);\nconst combined = pipe(\n  Effect.succeed(1),\n  Effect.zipWith(defaultValue, (a, b) => a + b)\n);\n```\n\n✅ Good (multiple uses - legitimate reuse):\n\n```typescript\nimport { Context, Effect, Layer, pipe } from 'effect';\n\ndeclare class PgClientService extends Context.Tag('PgClient')<PgClientService, unknown>() {}\ndeclare const createPgClient: Effect.Effect<unknown>;\ndeclare const Migration: { layer: Layer.Layer<unknown> };\ndeclare const EventStore: { layer: Layer.Layer<unknown> };\ndeclare function it(name: string, fn: () => unknown): void;\n\n// Layer reused in multiple compositions\nconst PgLive = Layer.effect(PgClientService, createPgClient);\nconst Layer1 = pipe(Migration.layer, Layer.provide(PgLive)); // Use 1\nconst Layer2 = pipe(EventStore.layer, Layer.provide(PgLive)); // Use 2\n\n// Effect reused across test cases\nconst setupTest = Effect.gen(function* () {\n  yield* Effect.void;\n});\nit('test 1', () =>\n  pipe(\n    setupTest,\n    Effect.flatMap(() => Effect.void)\n  )); // Use 1\nit('test 2', () =>\n  pipe(\n    setupTest,\n    Effect.flatMap(() => Effect.void)\n  )); // Use 2\n```\n\n✅ Good (execution results are plain values):\n\n```typescript\nimport { Effect, Either, pipe } from 'effect';\n\ntype Request = { token: string };\ndeclare const req: Request;\ndeclare function authenticate(r: Request): Effect.Effect<string, Error>;\n\n// runSync returns a plain value, not an Effect\nfunction handleAuth() {\n  const authResult = Effect.runSync(pipe(authenticate(req), Effect.either));\n  if (Either.isLeft(authResult)) {\n    return { json: () => ({ error: authResult.left }) };\n  }\n  return { json: () => ({ token: authResult.right }) };\n}\n```\n\n**Rationale**: Intermediate pipeline variables break the flow of pipe composition. Configuration data like Schedule constants and Effect values used as parameters to Effect operations are legitimate building blocks and should be extracted. Multiple uses also justify variable extraction.\n\n**Note:** This is an aggressive rule included in the `pipeStrict` config.\n\n## Rule Presets\n\n### Recommended Presets\n\n#### `recommended` ⭐\n\n**Recommended for most projects** - Core Effect best practices without controversial rules:\n\n- All Effect plugin rules\n- Forbids classes (except Effect tags/errors)\n- Forbids `Effect.runSync`/`runPromise` in production\n- Enforces `Effect.andThen()` over `Effect.flatMap(() => )`\n- Enforces `Effect.as()` over `Effect.map(() => value)`\n- Forbids method-based `.pipe()` (use standalone `pipe()`)\n- Forbids curried function calls (use `pipe` instead)\n- Forbids identity functions in transformations\n- Enforces proper pipe argument order\n\n**Does NOT include:**\n\n- `Effect.gen` ban (opt-in with `noGen`)\n- `_tag` access ban (opt-in with `preferMatch`)\n- Strict pipe rules (opt-in with `pipeStrict`)\n\n#### `strict`\n\n**For zealots** - Everything in `recommended` plus all opinionated rules:\n\n- All `recommended` rules\n- Forbids `Effect.gen` (use `pipe` instead)\n- Forbids direct `_tag` access (use type guards or `Match`)\n- Forbids ALL `switch` statements (use `Match.value` for pattern matching)\n- Forbids ALL `if` statements (use `Effect.if`, `Match.value`, or type-specific matchers)\n- Forbids nested `pipe()` calls\n- Forbids multiple `pipe()` calls in one function\n\n### Opt-in Configs\n\nMix these with `recommended` to customize your rules:\n\n#### `noGen`\n\nForbids `Effect.gen` in favor of `pipe` composition. **Controversial** - some teams prefer gen!\n\n#### `preferMatch`\n\nForbids direct `_tag` access, ALL `switch` statements, and ALL `if` statements. Encourages declarative `Match` patterns, `Effect.if` for boolean conditionals, and type-specific matchers.\n\n#### `pipeStrict`\n\nEnforces strict pipe composition rules:\n\n- Forbids nested `pipe()` calls\n- Forbids multiple `pipe()` calls per function\n- Forbids storing pipe/Effect results in single-use intermediate variables\n\n#### `plugin`\n\nPlugin rules only, no syntax restrictions.\n\n### Functional Immutability\n\n#### `functionalImmutabilityRules`\n\nLeverages `eslint-plugin-functional` with Effect-aware configuration:\n\n- Enforces readonly types with Effect type exceptions\n- Forbids `let` bindings\n- Enforces immutable data patterns\n- Forbids loops (use `Effect.forEach`, `Array.map`, etc.)\n\n## Usage\n\n### Recommended Setup\n\nStart with `recommended` for sensible defaults:\n\n```javascript\nimport effectPlugin from '@codeforbreakfast/eslint-effect';\n\nexport default [\n  {\n    ...effectPlugin.configs.recommended,\n    files: ['**/*.ts', '**/*.tsx'],\n    plugins: {\n      effect: effectPlugin,\n    },\n  },\n];\n```\n\n### Add Opinionated Rules\n\nOpt-in to stricter rules as needed:\n\n```javascript\nimport effectPlugin from '@codeforbreakfast/eslint-effect';\n\nexport default [\n  {\n    ...effectPlugin.configs.recommended,\n    files: ['**/*.ts', '**/*.tsx'],\n    plugins: {\n      effect: effectPlugin,\n    },\n  },\n  // Forbid Effect.gen\n  {\n    ...effectPlugin.configs.noGen,\n    files: ['src/**/*.ts'],\n  },\n  // Enforce strict pipe rules\n  {\n    ...effectPlugin.configs.pipeStrict,\n    files: ['src/**/*.ts'],\n  },\n  // Or just use strict for everything\n  {\n    ...effectPlugin.configs.strict,\n    files: ['src/**/*.ts'],\n    plugins: {\n      effect: effectPlugin,\n    },\n  },\n];\n```\n\n### With Functional Immutability\n\nRequires `eslint-plugin-functional`:\n\n```javascript\nimport functionalPlugin from 'eslint-plugin-functional';\nimport effectPlugin from '@codeforbreakfast/eslint-effect';\n\nexport default [\n  {\n    files: ['**/*.ts'],\n    plugins: {\n      functional: functionalPlugin,\n    },\n    rules: effectPlugin.configs.functionalImmutabilityRules,\n  },\n  {\n    ...effectPlugin.configs.recommended,\n    files: ['**/*.ts'],\n    plugins: {\n      effect: effectPlugin,\n    },\n  },\n];\n```\n\n### Disabling Individual Rules\n\nAll syntax restriction rules are exposed as named ESLint rules, making it easy to disable specific rules:\n\n```javascript\nimport effectPlugin from '@codeforbreakfast/eslint-effect';\n\nexport default [\n  {\n    ...effectPlugin.configs.recommended,\n    files: ['scripts/**/*.ts'],\n    plugins: {\n      effect: effectPlugin,\n    },\n    rules: {\n      // Allow runPromise/runSync in scripts (application entry points)\n      'effect/no-runPromise': 'off',\n      'effect/no-runSync': 'off',\n    },\n  },\n];\n```\n\n**Available named rules:**\n\n- `effect/no-classes` - Forbid classes except Effect tags/errors\n- `effect/no-runSync` - Forbid Effect.runSync\n- `effect/no-runPromise` - Forbid Effect.runPromise\n- `effect/prefer-andThen` - Use andThen over flatMap(() => ...)\n- `effect/prefer-as` - Use as over map(() => value)\n- `effect/no-gen` - Forbid Effect.gen (opt-in via `noGen` config)\n- `effect/no-unnecessary-pipe-wrapper` - Detect unnecessary pipe wrappers\n- `effect/no-eta-expansion` - Detect unnecessary function wrappers (prefer point-free style)\n- `effect/no-unnecessary-function-alias` - Detect unnecessary function aliases\n- `effect/prefer-match-tag` - Use Match.tag over Match.when for \\_tag\n- `effect/prefer-match-over-conditionals` - Use Match over if statements\n- `effect/prefer-effect-if-over-match-boolean` - Use Effect.if over Match.value for boolean conditionals\n- `effect/prefer-match-over-ternary` - Use Match.value over ternary operators for non-boolean pattern matching\n- `effect/no-switch-statement` - Forbid ALL switch statements (use Match.value instead)\n- `effect/no-if-statement` - Forbid ALL if statements (use Effect.if, Match.value, or type-specific matchers instead)\n- `effect/prefer-schema-validation-over-assertions` - Use Schema over type assertions\n- `effect/suggest-currying-opportunity` - Suggest currying to eliminate arrow function wrappers\n- `effect/no-intermediate-effect-variables` - Forbid storing pipe/Effect results in single-use intermediate variables (opt-in via `pipeStrict` config)\n\n## Available Exports\n\n### Default Export (Recommended)\n\n```typescript\n// @ts-nocheck - Package types available at runtime\nimport effectPlugin from '@codeforbreakfast/eslint-effect';\n\neffectPlugin.rules; // All custom rules\neffectPlugin.meta; // Plugin metadata\n\n// Configs\neffectPlugin.configs.recommended; // ⭐ Recommended for most projects\neffectPlugin.configs.strict; // All rules including opinionated ones\neffectPlugin.configs.noGen; // Opt-in: forbid Effect.gen\neffectPlugin.configs.preferMatch; // Opt-in: forbid _tag access\neffectPlugin.configs.pipeStrict; // Opt-in: strict pipe rules\neffectPlugin.configs.plugin; // Plugin rules only\neffectPlugin.configs.functionalImmutabilityRules; // Functional immutability rules object\n```\n\nEach config (except `functionalImmutabilityRules`) is a complete ESLint flat config object with:\n\n- `name`: Config identifier\n- `rules`: Rule configuration\n- `plugins`: Required plugins (where applicable)\n\n### Named Exports\n\n```typescript\n// @ts-nocheck - Package types available at runtime\nimport {\n  rules, // All custom rules (for plugin registration)\n  functionalImmutabilityRules, // Functional immutability rules object\n} from '@codeforbreakfast/eslint-effect';\n```\n\n### Scoped Imports\n\n```javascript\nimport rules from '@codeforbreakfast/eslint-effect/rules';\n```\n\n## Philosophy\n\nThis package enforces a strict functional programming style with Effect:\n\n1. **Composition over Generation**: Prefer `pipe` composition over `Effect.gen`\n2. **Type Safety**: Use runtime validation (Schema) over type assertions\n3. **Declarative Patterns**: Use `Match` over imperative conditionals\n4. **Immutability**: Enforce readonly types and immutable data patterns\n5. **Boundary Execution**: Run effects only at application boundaries\n\n## License\n\nMIT © CodeForBreakfast\n","readmeFilename":"README.md"}