{"_id":"@arnosaine/is","_rev":"13-ff803988dcb1c420310f5b08f28f4dc8","name":"@arnosaine/is","dist-tags":{"latest":"0.2.9"},"versions":{"0.1.0":{"name":"@arnosaine/is","version":"0.1.0","author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.1.0","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"e196f2a6334cb2e9077ef45cfaa4907ecbaa34f5","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.1.0.tgz","fileCount":6,"integrity":"sha512-AyAdSi2vEPMI3guu0UBMBDGLwrsedOgzxgb0Fcl/mdIq27z+8TSFAYwCiUi4dEnn1nRh0UKQsnZqaxuA6Eu5zA==","signatures":[{"sig":"MEQCIE3Png0fZzkjxfDeq+c/6BBkbemxF53A0cuKJn+XlcC3AiAm9Tx20kSkGQbxPlW7F52hJCTdTM8JDjuPNdA1UqdPIw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":30292},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"8efe4a153e4c0abaca72f9998dd706f64bef9c2e","scripts":{"build":"tsc","start":"tsc --watch","release":"npm run build && changeset version && changeset publish","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.5.2","description":"Conditional rendering","directories":{},"_nodeVersion":"20.13.1","dependencies":{"lodash-es":"^4.17.21","@remix-run/react":"^2.8.1"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.1.0_1716625256726_0.1537500437462136","host":"s3://npm-registry-packages"}},"0.1.1":{"name":"@arnosaine/is","version":"0.1.1","author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.1.1","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"7471ef7ab894dbba587906857701f0b3819a5619","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.1.1.tgz","fileCount":6,"integrity":"sha512-kVSL+Ej5I5kW2YLpPBqrmUJ0OdW+AL8BjlZbjoHzA1MBTFlGkQH2i4shxgyHdR5ZfmBUm0n8VHx8hoajjTdkBw==","signatures":[{"sig":"MEYCIQD2C4+bWhI4hJCq/6fnDCE1fHn2cemvjLHvNUlx1th7MgIhAL14X2DCCgiu3xWv7SmwNIIy1v+a9plKjUp+gs/NWpEq","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":31513},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"9b6a1f790025ce8e139eb3c90d0c259f5efadfb6","scripts":{"build":"tsc","start":"tsc --watch","release":"npm run build && changeset version && changeset publish","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.5.2","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.13.1","dependencies":{"lodash-es":"^4.17.21","@remix-run/react":"^2.8.1"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.1.1_1716662145018_0.8910929440261881","host":"s3://npm-registry-packages"}},"0.1.2":{"name":"@arnosaine/is","version":"0.1.2","author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.1.2","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"d323db42b82c666fada506fb3b29a632fc55739e","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.1.2.tgz","fileCount":6,"integrity":"sha512-cV7ZRsghQRFjTUhLHbkbqvhz8oSZKqpwvvMWGfcroKfbn6fI8BHsM61mX94VA/DNc2L/3AwDqlqalwUT8Ay3Ig==","signatures":[{"sig":"MEUCIQDicUQZEG8Htg+a7Ghypa4qcWiDUjrkFQnADjpS2gwwxQIgcAqifweiO+Zx7BJ+7SZT3ccCGvFmf+0sKoh9oW4FVO0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":32329},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"0146793031a0fef73ef5686d93aeaad8cbab4ca6","scripts":{"build":"tsc","start":"tsc --watch","release":"npm run build && changeset version && changeset publish","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.5.2","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.13.1","dependencies":{"lodash-es":"^4.17.21","@remix-run/react":"^2.8.1"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.1.2_1716910100159_0.8273297048621568","host":"s3://npm-registry-packages"}},"0.1.3":{"name":"@arnosaine/is","version":"0.1.3","author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.1.3","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"1772eb33065e004fb9ea0a05bbcc0b50a348672a","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.1.3.tgz","fileCount":6,"integrity":"sha512-65nGloEy+LPiQj8niw7ugy1P5zEMGrhFycSu0hc6Tsdnu3hGw8yce2wd67SEdIUYULzwdXud3jMUAPpSNiMk0g==","signatures":[{"sig":"MEQCIBVChnyxKgWx0AMyCJDH3UO8KdQG9Xg2VjB/d+CRL6ReAiBTQ9uH5W5T8eKvlXRHwE5Ip0FBsR88YsnZhpyZovyy7Q==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":33946},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"348d0ea06f37c5685111e6302f97617d53d757ba","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.7.0","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.14.0","dependencies":{"lodash-es":"^4.17.21","@remix-run/react":"^2.8.1"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.1.3_1717946256601_0.9173453876916084","host":"s3://npm-registry-packages"}},"0.2.0":{"name":"@arnosaine/is","version":"0.2.0","author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.2.0","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"943ca5881a5c238a417860a7f82fe33b69b3af82","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.0.tgz","fileCount":6,"integrity":"sha512-nFzj9k5qAvGDM3/PTgSPkHCioRLxBcPUXhF4xBfvDunLQK5ggLl/Je+ZUXoOYq5nwwq4DmvY8REmn/ot+1DP4g==","signatures":[{"sig":"MEUCIBflPPx3a1JENeB3/uA3lh3VwB3Tvn0ONAe7O6sxm55xAiEAjbMvUKCiDXRCKm8yaUF/lQdlGYm58IMgLPNhOCZ3vV4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":33766},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"1179ec8f950fc7103b85d02feadcae4abd350b9b","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.7.0","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.14.0","dependencies":{"lodash-es":"^4.17.21","@remix-run/react":"^2.8.1"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.2.0_1717948425344_0.30770953396758505","host":"s3://npm-registry-packages"}},"0.2.1":{"name":"@arnosaine/is","version":"0.2.1","author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.2.1","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"8bbd76e869d3894de5ecfbfd4466eac49b4c2e6f","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.1.tgz","fileCount":10,"integrity":"sha512-HD+BRmEwKtuyXfCfmnLbjUbdmIYBf8qy2FVURhdjZUUdLR90BWRDb1u7DdCSDWgQf7hvQ88itrOB8CVsgvnuKg==","signatures":[{"sig":"MEUCIGK+HgA5jTrFLHrYiVR82aJyU+AofPVLLxW4IajT4HRgAiEAgsmWZvlo4iW0pLF4NZ48ypbFM57G8iItnQuI8uy2TqY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":35779},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"44adbfa330c1f578cd8b3314b19165544adf1abe","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.7.0","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.14.0","dependencies":{"lodash-es":"^4.17.21","@remix-run/react":"^2.8.1"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.2.1_1718025451065_0.3883267306993867","host":"s3://npm-registry-packages"}},"0.2.2":{"name":"@arnosaine/is","version":"0.2.2","author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.2.2","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"efca59c209c549ec4ba3f7cbcf9be9ba2e37b684","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.2.tgz","fileCount":10,"integrity":"sha512-pBlzkNxugwX8NesaJ2VEFA7ejSysmbjm/MCTG1VkWMAvSQo2cNYgTYxG0SHLdHC+o0w3x3KydEuhYgIsox9qhQ==","signatures":[{"sig":"MEYCIQDfLpJ6N3u/YiHmbrhN5cl+GA/7LS2qe1+43li2NYDoiwIhAMfF1l1smrsxD+OnmqETepN5mJlwGXqg4v9V9arc6Asq","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":36188},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"b3082c72173f2c84f652a6d3e92d8a494ea4225f","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.7.0","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.14.0","dependencies":{"lodash-es":"^4.17.21","react-router":"^6.23.1"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.2.2_1718126549066_0.606594506751525","host":"s3://npm-registry-packages"}},"0.2.3":{"name":"@arnosaine/is","version":"0.2.3","keywords":["react","conditional-rendering","feature-flags","authentication","permissions","conditional-logic","remix","react-router","dynamic-content","a/b-testing","role-based-access-control","rbac"],"author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.2.3","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"d9ac387c9596bf5ef3e6eb0a50116e229e2ba488","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.3.tgz","fileCount":10,"integrity":"sha512-rXOnW8JvGqcp9sMUpKy5nFjcJ6IyaYj6N6fdvVB3BknrxikM7kNgDTpRRKDN/MWQ+LSNSgnDxmWPSy9QjuqTLw==","signatures":[{"sig":"MEUCIDnYD+pP2tD/l1DP8XK/PXgacaLUU4NSi2tfbZluM5eoAiEArMBlJXdJ5fL54uwbgTgamhRkt3nrLxHJA3Cq/AiC/ss=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":36457},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"d3675ed1b8d6285969e8dce8784f108bb35022d0","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.7.0","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.14.0","dependencies":{"lodash-es":"^4.17.21","react-router":"^6.23.1"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.2.3_1718874776524_0.7781542944060755","host":"s3://npm-registry-packages"}},"0.2.4":{"name":"@arnosaine/is","version":"0.2.4","keywords":["react","conditional-rendering","feature-flags","authentication","permissions","conditional-logic","remix","react-router","dynamic-content","a/b-testing","role-based-access-control","rbac"],"author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.2.4","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"ede62cbaa7a0e42c0d4eca254c04be78f8f3e7d0","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.4.tgz","fileCount":10,"integrity":"sha512-BEgAIm9tSEraIZHk6vqo6tEqSU9renJ59lpm/dc4RHavAx4Hmwf8vx+2DWXnkV48px4Ksjo1JyhqMxf1KGMTcg==","signatures":[{"sig":"MEQCIBKJRacZbbWlTVOgF7iqevLY3PCn2H5+JNBeCOdUMjQxAiAqB24Tx8hKduGKgmf9c3KozGDzqOicnhhyTfeEj0kbrw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37133},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"f9ec820594da035bd1772934ae34a1e23e07b137","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.7.0","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.15.1","dependencies":{"lodash-es":"^4.17.21","react-router":"^6.23.1"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.2.4_1722372278303_0.6511340101992622","host":"s3://npm-registry-packages"}},"0.2.5":{"name":"@arnosaine/is","version":"0.2.5","keywords":["react","conditional-rendering","feature-flags","authentication","permissions","conditional-logic","remix","react-router","dynamic-content","a/b-testing","role-based-access-control","rbac"],"author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.2.5","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"2be1981f726ef3368feaf0a4c25e7dd76966756d","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.5.tgz","fileCount":10,"integrity":"sha512-wm/vq1C/nUBXQca0JN/vmeIEnwR5LBNNAXNSOvQfKQU2VAu8wNkzJek9ZCyMr/I9CI0R97ODfRC59iPZgBZyjQ==","signatures":[{"sig":"MEYCIQCMh0p0Q1h/uoVPv+GuFTCLiMR+Ynzmow6ePeMdyHWh7wIhAIiqdjc9890qD1Wf0embzj9yI5hSKqMmfG3+7Wh1VaiS","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37075},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"9e6bdaad7374f9cbc10737112c9c4e6b5a88af12","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.7.0","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.15.1","dependencies":{"lodash-es":"^4.17.21","react-router":"^6.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.2.5_1722547256894_0.4147061193973922","host":"s3://npm-registry-packages"}},"0.2.6":{"name":"@arnosaine/is","version":"0.2.6","keywords":["react","conditional-rendering","feature-flags","authentication","permissions","conditional-logic","remix","react-router","dynamic-content","a/b-testing","role-based-access-control","rbac"],"author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.2.6","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"fa8a95baa6d54986e14a9780e3ecf08a42170cfe","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.6.tgz","fileCount":10,"integrity":"sha512-fSn3rpamYtZuPXSkr59F+mXWdvhWV+u8KgP+4Yi8ckMWjHVT+KK5CvgrK/LXMvsc7skKieZlk5SgbsDEAUISZw==","signatures":[{"sig":"MEUCIQD59pPPgAnhxpiPbpRh6c8pnzT9ygFm+WQmmwuklIGcqQIgRuGDU+rOeBoBGsa/qqk17Gws2FlHw8zYR/yl4K9GREE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37119},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"0742f1c03b112ed9beabc297d985b5a12539c614","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.7.0","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.15.1","dependencies":{"lodash-es":"^4.17.21","react-router":"^6.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.2.6_1722594744873_0.25658485426029287","host":"s3://npm-registry-packages"}},"0.2.7":{"name":"@arnosaine/is","version":"0.2.7","keywords":["react","conditional-rendering","feature-flags","authentication","permissions","conditional-logic","remix","react-router","dynamic-content","a/b-testing","role-based-access-control","rbac"],"author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.2.7","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"9e1fbd4a94d4eb713d57c760d2f45790f228e49c","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.7.tgz","fileCount":10,"integrity":"sha512-GZsWNoT+ZI1WUdt/ub36RkurlUfrWWrBMHWpzvhDA9xO/4chDfh5pUIVYV0OaCds+wzGOIqi5YO8GCCPbq36kg==","signatures":[{"sig":"MEUCIDNZ7y3LJ/zY9wXnFhhXDJeDJh62jGStv+xpx7RLBrHxAiEAqUoHowncebLmrdv/Z44t99s0zIGmpp5nTpA6vkLCK84=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37081},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"e4b2c29e54c0ee5c4cf82e0ca405cec19cef001c","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.8.2","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.18.1","dependencies":{"lodash-es":"^4.17.21","react-router":"^6.0.0 || ^7.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":"*","react-dom":"*"},"_npmOperationalInternal":{"tmp":"tmp/is_0.2.7_1737095234895_0.8706514642914247","host":"s3://npm-registry-packages-npm-production"}},"0.2.8":{"name":"@arnosaine/is","version":"0.2.8","keywords":["react","conditional-rendering","feature-flags","authentication","permissions","conditional-logic","remix","react-router","dynamic-content","a/b-testing","role-based-access-control","rbac"],"author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","_id":"@arnosaine/is@0.2.8","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"homepage":"https://github.com/ArnoSaine/is","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"dist":{"shasum":"8c5544255e423c167d3b29f9b1d695d0cd1d990a","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.8.tgz","fileCount":10,"integrity":"sha512-6oOZVpEF6ZQocUIs7Q3tme+TcdXSIRM4EKR/KC/NdlE7r8m8ORc5iMYY8hfRlevocK9gfpAt37tAaKxqtJQq2w==","signatures":[{"sig":"MEUCIQCSl2GJSgMCxLGwDk9h7qm8VYky/yT6tW1mc7+JFSOzKwIgBU7jvr9MABqumQWQmkULbmeT0HRP81USIJaQluEJ3bs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38641},"main":"./lib/main.js","type":"module","types":"./lib/main.d.ts","gitHead":"3f8b4716dd3b502b44636d58fe09b436f7df0352","scripts":{"dev":"tsc --watch","test":"node --test && tsc --project tsconfig.test.json","build":"tsc","release":"npm run build && npm test && changeset version && changeset publish","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\"","build:examples":"./build-examples.sh","start:examples":"serve public/ --listen 3000"},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"repository":{"url":"git+https://github.com/ArnoSaine/is.git","type":"git"},"workspaces":[".","examples/*"],"_npmVersion":"10.8.2","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","directories":{},"_nodeVersion":"20.18.1","dependencies":{"lodash-es":"^4.17.21"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.5","@types/react":"^18.2.20","concurrently":"^8.2.2","@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@remix-run/react":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react-dom":"^18.2.7"},"peerDependencies":{"react":">=18","react-dom":">=18","react-router":">=6"},"_npmOperationalInternal":{"tmp":"tmp/is_0.2.8_1737626463633_0.3108086078752914","host":"s3://npm-registry-packages-npm-production"}},"0.2.9":{"name":"@arnosaine/is","version":"0.2.9","description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","keywords":["react","conditional-rendering","feature-flags","authentication","permissions","conditional-logic","remix","react-router","dynamic-content","a/b-testing","role-based-access-control","rbac"],"homepage":"https://github.com/ArnoSaine/is","repository":{"type":"git","url":"git+https://github.com/ArnoSaine/is.git"},"license":"ISC","author":{"name":"Arno Saine","email":"arno@mowhi.com"},"type":"module","main":"./lib/main.js","workspaces":[".","examples/*"],"scripts":{"build":"tsc","build:examples":"./build-examples.sh","dev":"tsc --watch","release":"npm run build && npm test && changeset version && changeset publish","start:examples":"serve public/ --listen 3000","test":"node --test && tsc --project tsconfig.test.json","test:watch":"concurrently \"node --test --watch\" \"tsc --project tsconfig.test.json --watch\""},"dependencies":{"lodash-es":"^4.17.21"},"devDependencies":{"@changesets/cli":"^2.27.3","@remix-run/node":"^2.8.1","@remix-run/react":"^2.8.1","@types/lodash-es":"^4.17.12","@types/react":"^18.2.20","@types/react-dom":"^18.2.7","concurrently":"^8.2.2","typescript":"^5.4.5"},"peerDependencies":{"react":">=18","react-dom":">=18","react-router":">=6"},"publishConfig":{"access":"public","tag":"latest"},"_id":"@arnosaine/is@0.2.9","gitHead":"2d7c6d17e54a6b94e5bd7624bd389c0955abcafb","types":"./lib/main.d.ts","bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"_nodeVersion":"20.18.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-O+mvtOma2NQcacszkla97TuinNQpXbmTogYwcvQh5t0x/2cOe193g/+GcKpocuCPnBeB6wySaBqMSHWkleMCcA==","shasum":"8166923c83e62bef5022f7dda1b905a3b97cb8a0","tarball":"https://registry.npmjs.org/@arnosaine/is/-/is-0.2.9.tgz","fileCount":10,"unpackedSize":39412,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD+m+GImZok55FXUaltVdIKfR0CJ9H5+8MvqvzsC8NgIQIgC7ToZX07+9kr4GtGeTcLAwLe7kdi4GUgmoNxbhM+fxc="}]},"_npmUser":{"name":"arnosaine","email":"arno@mowhi.com"},"directories":{},"maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/is_0.2.9_1737645073695_0.21489073971817918"},"_hasShrinkwrap":false}},"time":{"created":"2024-05-25T08:20:56.545Z","modified":"2025-01-23T15:11:14.061Z","0.1.0":"2024-05-25T08:20:56.924Z","0.1.1":"2024-05-25T18:35:45.229Z","0.1.2":"2024-05-28T15:28:20.422Z","0.1.3":"2024-06-09T15:17:36.754Z","0.2.0":"2024-06-09T15:53:45.540Z","0.2.1":"2024-06-10T13:17:31.182Z","0.2.2":"2024-06-11T17:22:29.224Z","0.2.3":"2024-06-20T09:12:56.690Z","0.2.4":"2024-07-30T20:44:38.591Z","0.2.5":"2024-08-01T21:20:57.234Z","0.2.6":"2024-08-02T10:32:25.050Z","0.2.7":"2025-01-17T06:27:15.114Z","0.2.8":"2025-01-23T10:01:03.834Z","0.2.9":"2025-01-23T15:11:13.869Z"},"bugs":{"url":"https://github.com/ArnoSaine/is/issues"},"author":{"name":"Arno Saine","email":"arno@mowhi.com"},"license":"ISC","homepage":"https://github.com/ArnoSaine/is","keywords":["react","conditional-rendering","feature-flags","authentication","permissions","conditional-logic","remix","react-router","dynamic-content","a/b-testing","role-based-access-control","rbac"],"repository":{"type":"git","url":"git+https://github.com/ArnoSaine/is.git"},"description":"Feature Flags, Roles and Permissions-based rendering, A/B Testing, Experimental Features, and more in React.","maintainers":[{"name":"arnosaine","email":"arno@mowhi.com"}],"readme":"# @arnosaine/is\n\n[Feature Flags](#feature-flags), [Roles and Permissions-based rendering](#user-roles-and-permissions), [A/B Testing, Experimental Features](#ab-testing-experimental-features), and [more](#application-variants-by-the-domain) in React.\n\n## Key Features\n\n- Declarative syntax for conditionally rendering components\n- Support for various data sources, including context, hooks, and API responses\n- Customizable with default conditions and dynamic values\n\n[Create](#create-is--useis) a custom [`<Is>`](#is) component and [`useIs`](#useis) hook for any conditional rendering use cases.\n\nOr create [shortcut components](#shortcut-components-and-hooks) like `<IsAuthenticated>`, `<HasRole>` / `<Role>` and `<HasPermission>` / `<Can>`, and hooks like `useIsAuthenticated`, `useHasRole` / `useRole` and `useHasPermission` / `useCan`, for the most common use cases.\n\nIf you are using React Router or Remix, use [`createFromLoader`](#setup) to also create [`loadIs`](#loadis) loader and utility functions like [`authenticated`](#utilities).\n\n## Contents\n\n- [Demos](#demos)\n- [Getting Started](#getting-started)\n  - [Create `<Is>` & `useIs`](#create-is--useis)\n  - [Use `<Is>` & `useIs`](#use-is--useis)\n- [Ideas](#ideas)\n  - [Feature Flags](#feature-flags)\n    - [Hardcoded Features](#hardcoded-features)\n    - [Build Time Features](#build-time-features)\n    - [Runtime Features](#runtime-features)\n    - [A/B Testing, Experimental Features](#ab-testing-experimental-features)\n    - [Enable All Features in Preview Mode](#enable-all-features-in-preview-mode)\n    - [Usage](#usage)\n  - [Application Variants by the Domain](#application-variants-by-the-domain)\n    - [Usage](#usage-1)\n  - [User Roles and Permissions](#user-roles-and-permissions)\n    - [Usage](#usage-2)\n  - [Is a Specific Day](#is-a-specific-day)\n    - [Usage](#usage-3)\n  - [Shortcut Components and Hooks](#shortcut-components-and-hooks)\n    - [For a Very Specific Use Case](#for-a-very-specific-use-case)\n- [Loader (React Router / Remix)](#loader-react-router--remix)\n  - [Setup](#setup)\n  - [Using `loadIs`](#using-loadis)\n  - [Utilities](#utilities)\n- [API](#api)\n  - [`create`](#create)\n  - [`createFromLoader`](#createfromloader)\n  - [`<Is>`](#is)\n  - [`useIs`](#useis)\n  - [`loadIs`](#loadis)\n  - [`is`](#is-1)\n  - [`toBooleanValues`](#tobooleanvalues)\n- [Types](#types)\n  - [`Value`](#value)\n  - [`Values`](#values)\n  - [`Conditions`](#conditions)\n\n## Demos\n\n- [React Router](https://arnosaine.github.io/is/react-router-project/)\n- [Remix](https://arnosaine.github.io/is/remix-project/)\n- [Vite](https://arnosaine.github.io/is/vite-project/)\n\n## Getting Started\n\nHere, we create a component and a hook to check if the user is authenticated or if experimental features are enabled. We get the user from `UserContext`. Experimental features are enabled on `preview.*` domains, for example, at http://preview.localhost:5173.\n\n### Create `<Is>` & `useIs`\n\n`./is.ts`:\n\n```tsx\nimport { create } from \"@arnosaine/is\";\nimport { use } from \"react\";\nimport UserContext from \"./UserContext\";\n\nconst [Is, useIs] = create(function useValues() {\n  const user = use(UserContext);\n\n  const isExperimental = location.hostname.startsWith(\"preview.\");\n\n  // Or, get the value from the user context, a hook call, or another\n  // source.\n  // const isExperimental = user?.roles?.includes(\"developer\") ?? false;\n\n  return {\n    // The property names become the prop and hook param names.\n    // Allowed types: boolean | number | string | boolean[] | number[] |\n    // string[].\n    authenticated: Boolean(user),\n    experimental: isExperimental,\n    // ...\n  };\n});\n\nexport { Is, useIs };\n```\n\n### Use `<Is>` & `useIs`\n\n```tsx\nimport { Is, useIs } from \"./is\";\n\n// Component\n\n<Is authenticated fallback=\"Please log in\">\n  Welcome back!\n</Is>;\n\n<Is experimental>\n  <SomeExperimentalFeature />\n</Is>;\n\n// Hook\n\nconst isAuthenticated = useIs({ authenticated: true }); // boolean\nconst isExperimental = useIs({ experimental: true }); // boolean\n```\n\n> ℹ️ Consider lazy loading if the conditional code becomes large. Otherwise, the conditional code is included in the bundle, even if it's not rendered. Additionally, do not use this method if the non-rendered code should remain secret.\n\n## Ideas\n\n### Feature Flags\n\n#### Hardcoded Features\n\nA list of hardcoded features is perhaps the simplest method and can still improve the project workflow. For example, some features can be enabled in the `release` branch, while different features can be enabled in the `main` or `feature` branches.\n\n`./is.ts`:\n\n```tsx\nimport { create } from \"@arnosaine/is\";\n\nconst [Is, useIs] = create(function useValues() {\n  return {\n    // Hardcoded features\n    feature: [\"feature-abc\", \"feature-xyz\"] as const,\n    // ...\n  };\n});\n\nexport { Is, useIs };\n```\n\n#### Build Time Features\n\nRead the enabled features from an environment variable at build time:\n\n`.env`:\n\n```sh\nFEATURES=[\"feature-abc\",\"feature-xyz\"]\n```\n\n`./is.ts`:\n\n```tsx\nimport { create } from \"@arnosaine/is\";\n\nconst [Is, useIs] = create(function useValues() {\n  return {\n    // Read the enabled features from an environment variable at build\n    // time\n    feature: JSON.parse(import.meta.env.FEATURES ?? \"[]\"),\n    // ...\n  };\n});\n\nexport { Is, useIs };\n```\n\n#### Runtime Features\n\nRead the enabled features from a config file or an API at runtime:\n\n`public/config.json`:\n\n```json\n{\n  \"features\": [\"feature-abc\", \"feature-xyz\"]\n}\n```\n\n`./is.ts`:\n\n```tsx\nimport { create } from \"@arnosaine/is\";\nimport { use } from \"react\"; // React v19\n\nasync function getConfig() {\n  const response = await fetch(import.meta.env.BASE_URL + \"config.json\");\n  return response.json();\n}\n\nconst configPromise = getConfig();\n\nconst [Is, useIs] = create(function useValues() {\n  const config = use(configPromise);\n\n  return {\n    feature: config.features,\n    // ...\n  };\n});\n\nexport { Is, useIs };\n```\n\n#### A/B Testing, Experimental Features\n\nEnable some features based on other values:\n\n`./is.ts`:\n\n```tsx\nimport { create } from \"@arnosaine/is\";\n\nconst [Is, useIs] = create(function useValues() {\n  const features = [\n    /*...*/\n  ];\n\n  // Enable some features only in development mode:\n  if (import.meta.env.MODE === \"development\") {\n    features.push(\"new-login-form\");\n  }\n\n  // Or, enable some features only on `dev.*` domains, for example, at\n  // http://dev.localhost:5173:\n  if (location.hostname.startsWith(\"dev.\")) {\n    features.push(\"new-landing-page\");\n  }\n\n  return {\n    feature: features,\n    // ...\n  };\n});\n\nexport { Is, useIs };\n```\n\n#### Enable All Features in Preview Mode\n\n`./is.ts`:\n\n```tsx\nimport { create } from \"@arnosaine/is\";\n\nconst [Is, useIs] = create(function useValues() {\n  const features = [\n    /*...*/\n  ];\n\n  const isPreview = location.hostname.startsWith(\"preview.\");\n\n  return {\n    feature: isPreview\n      ? // In preview mode, all features are enabled.\n        // Typed as string to accept any string as a feature name.\n        (true as unknown as string)\n      : features,\n    // ...\n  };\n});\n\nexport { Is, useIs };\n```\n\n#### Usage\n\nIt does not matter how the features are defined; using the `<Is>` and `useIs` is the same:\n\n```tsx\nimport { Is, useIs } from \"./is\";\n\n// Component\n\n<Is feature=\"new-login-form\" fallback={<OldLoginForm />}>\n  <NewLoginForm />\n</Is>;\n\n// Hook\n\nconst showNewLoginForm = useIs({ feature: \"new-login-form\" });\n```\n\n### Application Variants by the Domain\n\n> ℹ️ In the browser, `location.hostname` is a constant, and `location.hostname === \"example.com\" && <p>This appears only on example.com</p>` could be all you need. You might still choose to use the Is pattern for consistency and for server-side actions and loaders.\n\n`./is.ts`:\n\n```tsx\nimport { create } from \"@arnosaine/is\";\n\nconst [Is, useIs] = create(function useValues() {\n  const domain = location.hostname.endsWith(\".localhost\")\n    ? // On <domain>.localhost, get subdomain.\n      location.hostname.slice(0, -\".localhost\".length)\n    : location.hostname;\n\n  return {\n    variant: domain,\n    // ...\n  };\n});\n\nexport { Is, useIs };\n```\n\n#### Usage\n\n```tsx\nimport { Is, useIs } from \"./is\";\n\n// Component\n\n<Is variant=\"example.com\">\n  <p>This appears only on example.com</p>\n</Is>;\n\n// Hook\n\nconst isExampleDotCom = useIs({ variant: \"example.com\" });\n```\n\n### User Roles and Permissions\n\n`./is.ts`:\n\n```tsx\nimport { create } from \"@arnosaine/is\";\nimport { use } from \"react\";\nimport UserContext from \"./UserContext\";\n\nconst [Is, useIs] = create(function useValues() {\n  const user = use(UserContext);\n\n  return {\n    authenticated: Boolean(user),\n    role: user?.roles, // [\"admin\", ...]\n    permission: user?.permissions, // [\"create-articles\", ...]\n    // ...\n  };\n});\n\nexport { Is, useIs };\n```\n\n#### Usage\n\n```tsx\nimport { Is, useIs } from \"./is\";\n\n// Component\n\n<Is authenticated fallback=\"Please log in\">\n  Welcome back!\n</Is>;\n\n<Is role=\"admin\">\n  <AdminPanel />\n</Is>;\n\n<Is permission=\"update-articles\">\n  <button>Edit</button>\n</Is>;\n\n// Hook\n\nconst isAuthenticated = useIs({ authenticated: true });\nconst isAdmin = useIs({ role: \"admin\" });\nconst canUpdateArticles = useIs({ permission: \"update-articles\" });\n```\n\n### Is a Specific Day\n\n`./is.ts`:\n\n```tsx\nimport { create } from \"@arnosaine/is\";\nimport { easter } from \"date-easter\";\nimport { isSameDay } from \"date-fns\";\n\nconst [Is, useIs] = create(function useValues() {\n  return {\n    easter: isSameDay(new Date(easter()), new Date()),\n    // ...\n  };\n});\n\nexport { Is, useIs };\n```\n\n#### Usage\n\n```tsx\nimport { Is, useIs } from \"./is\";\n\n// Component\n\n<Is easter>🐣🐣🐣</Is>;\n\n// Hook\n\nconst isEaster = useIs({ easter: true });\n```\n\n### Shortcut Components and Hooks\n\n```tsx\nimport { create } from \"@arnosaine/is\";\nimport { use } from \"react\";\nimport UserContext from \"./UserContext\";\n\nconst [IsAuthenticated, useIsAuthenticated] = create(\n  function useValues() {\n    const user = use(UserContext);\n\n    return { authenticated: Boolean(user) };\n  },\n  { authenticated: true } // Default props / hook params\n);\n\n<IsAuthenticated fallback=\"Please log in\">Welcome back!</IsAuthenticated>;\n\nconst isAuthenticated = useIsAuthenticated();\n```\n\n```tsx\nimport { create, toBooleanValues } from \"@arnosaine/is\";\nimport { use } from \"react\";\nimport UserContext from \"./UserContext\";\n\nconst [HasRole, useHasRole] = create(function useValues() {\n  const user = use(UserContext);\n\n  // Create object { [role: string]: true }\n  return Object.fromEntries((user?.roles ?? []).map((role) => [role, true]));\n});\n\n<HasRole admin>\n  <AdminPanel />\n</HasRole>;\n\nconst isAdmin = useHasRole({ admin: true });\n\n// Same with toBooleanValues utility\nconst [Role, useRole] = create(() => toBooleanValues(use(UserContext)?.roles));\n\n<Role admin>\n  <AdminPanel />\n</Role>;\n\nconst isAdmin = useRole({ admin: true });\n```\n\n```tsx\nimport { create, toBooleanValues } from \"@arnosaine/is\";\nimport { use } from \"react\";\nimport UserContext from \"./UserContext\";\n\nconst [HasPermission, useHasPermission] = create(function useValues() {\n  const user = use(UserContext);\n\n  // Create object { [permission: string]: true }\n  return Object.fromEntries(\n    (user?.permissions ?? []).map((permission) => [permission, true])\n  );\n});\n\n<HasPermission update-articles>\n  <button>Edit</button>\n</HasPermission>;\n\nconst canUpdateArticles = useHasPermission({ \"update-articles\": true });\n\n// Same with toBooleanValues utility\nconst [Can, useCan] = create(() =>\n  toBooleanValues(use(UserContext)?.permissions)\n);\n\n<Can update-articles>\n  <button>Edit</button>\n</Can>;\n\nconst canUpdateArticles = useCan({ \"update-articles\": true });\n```\n\n#### For a Very Specific Use Case\n\n```tsx\nimport { create } from \"@arnosaine/is\";\nimport { use } from \"react\";\nimport UserContext from \"./UserContext\";\n\nconst [CanUpdateArticles, useCanUpdateArticles] = create(\n  function useValues() {\n    const user = use(UserContext);\n\n    return {\n      updateArticles: user?.permissions?.includes(\"update-articles\") ?? false,\n    };\n  },\n  { updateArticles: true } // Default props / hook params\n);\n\n<CanUpdateArticles>\n  <button>Edit</button>\n</CanUpdateArticles>;\n\nconst canUpdateArticles = useCanUpdateArticles();\n```\n\n## Loader (React Router / Remix)\n\n### Setup\n\n1. Create `<Is>`, `useIs` & `loadIs` using [`createFromLoader`](#createfromloader).\n\n   `./app/is.ts`:\n\n   ```tsx\n   import { createFromLoader } from \"@arnosaine/is\";\n   import { loadConfig, loadUser } from \"./loaders\";\n\n   const [Is, useIs, loadIs] = createFromLoader(async (args) => {\n     const { hostname } = new URL(args.request.url);\n     const isPreview = hostname.startsWith(\"preview.\");\n     const user = await loadUser(args);\n     const config = await loadConfig(args);\n\n     return {\n       authenticated: Boolean(user),\n       feature: config?.features,\n       preview: isPreview,\n       role: user?.roles,\n       // ...\n     };\n   });\n\n   export { Is, useIs, loadIs };\n   ```\n\n   `./app/root.tsx`:\n\n2. Return `...is` from the root `loader` / `clientLoader`. See [options](#parameters-1) to use other route.\n\n   ```tsx\n   import { loadIs } from \"./is\";\n\n   export const loader = async (args: LoaderFunctionArgs) => {\n     const is = await loadIs(args);\n\n     return {\n       ...is,\n       // ...other loader data...\n     };\n   };\n   ```\n\n> ℹ️ The root `ErrorBoundary` does not have access to the root `loader` data. Since the root `Layout` export is shared with the root `ErrorBoundary`, if you use `<Is>` or `useIs` in the `Layout` export, consider prefixing all routes with `_.` (pathless route) and using `ErrorBoundary` in [`routes/_.tsx`](examples/remix-project/app/routes/_.tsx) to catch errors before they reach the root `ErrorBoundary`.\n\n### Using `loadIs`\n\n```tsx\nimport { loadIs } from \"./is\";\n\n// Or clientLoader\nexport const loader = async (args: LoaderFunctionArgs) => {\n  const is = await loadIs(args);\n\n  const isAuthenticated = is({ authenticated: true });\n  const hasFeatureABC = is({ feature: \"feature-abc\" });\n  const isPreview = is({ preview: true });\n  const isAdmin = is({ role: \"admin\" });\n\n  // ...\n};\n```\n\n### Utilities\n\n> ℹ️ See Remix example [utils/auth.ts](examples/remix-project/utils/auth.ts) and [utils/response.ts](examples/remix-project/utils/response.ts) for more examples.\n\n`./app/utils/auth.tsx`:\n\n```tsx\nimport { loaderFunctionArgs } from \"@remix-run/node\";\nimport { loadIs } from \"./is\";\n\nexport const authenticated = async (\n  args: LoaderFunctionArgs,\n  role?: string | string[]\n) => {\n  const is = await loadIs(args);\n\n  // Ensure user is authenticated\n  if (!is({ authenticated: true })) {\n    throw new Response(\"Unauthorized\", {\n      status: 401,\n    });\n  }\n\n  // If the optional role parameter is available, ensure the user has\n  // the required roles\n  if (!is({ role })) {\n    throw new Response(\"Forbidden\", {\n      status: 403,\n    });\n  }\n};\n```\n\n```tsx\nimport { authenticated } from \"./utils/auth\";\n\nexport const loader = async (args: LoaderFunctionArgs) => {\n  await authenticated(args, \"admin\");\n\n  // User is authenticated and has the role \"admin\".\n\n  // ...\n};\n```\n\n## API\n\n### `create`\n\nCall `create` to declare the [`Is`](#is) component and the [`useIs`](#useis) hook.\n\n```ts\nconst [Is, useIs] = create(useValues, defaultConditions?);\n```\n\nThe names `Is` and `useIs` are recommended for a multi-purpose component and hook. For single-purpose use, you can name them accordingly. The optional `defaultConditions` parameter is also often useful for single-purpose implementations.\n\n```ts\nconst [IsAuthenticated, useIsAuthenticated] = create(\n  () => {\n    // Retrieve the user. Since this is a hook, using other hooks and\n    // context is allowed.\n    const user = { name: \"Example\" }; // Example: use(UserContext)\n    return { authenticated: Boolean(user) };\n  },\n  { authenticated: true }\n);\n```\n\n#### Parameters\n\n- `useValues`: A React hook that acquires and computes the current [`values`](#values) for the comparison logic.\n- **optional** `defaultConditions`: The default props/params for [`Is`](#is) and [`useIs`](#useis).\n- **optional** `options`: An options object for configuring the behavior.\n  - **optional** `method` (`\"every\" | \"some\"`): Default: `\"some\"`. Specifies how to match array type values and conditions. Use `\"some\"` to require only some conditions to match the values, or `\"every\"` to require all conditions to match.\n\n#### Returns\n\n`create` returns an array containing the [`Is`](#is) component and the [`useIs`](#useis) hook.\n\n### `createFromLoader`\n\nCall `createFromLoader` to declare the [`Is`](#is) component the [`useIs`](#useis) hook and the [`loadIs`](#loadis) loader.\n\n```ts\nconst [Is, useIs, loadIs] = createFromLoader(loadValues, defaultConditions?, options?);\n```\n\nThe names `Is`, `useIs` and `loadIs` are recommended for a multi-purpose component, hook, and loader. For single-purpose use, you can name them accordingly. The optional `defaultConditions` parameter is also often useful for single-purpose implementations.\n\n```ts\nconst [IsAuthenticated, useIsAuthenticated, loadIsAuthenticated] =\n  createFromLoader(\n    async (args) => {\n      // Retrieve the user. Since this is a loader, using await and\n      // other loaders is allowed.\n      const user = await loadUser(args);\n      return { authenticated: Boolean(user) };\n    },\n    { authenticated: true }\n  );\n```\n\n#### Parameters\n\n- `loadValues`: A React Router / Remix loader function that acquires and computes the current [`values`](#values) for the comparison logic.\n- **optional** `defaultConditions`: The default props/params for [`Is`](#is), [`useIs`](#useis) and [`is`](#is-1).\n- **optional** `options`: An options object for configuring the behavior.\n  - **optional** `method` (`\"every\" | \"some\"`): Default: `\"some\"`. Specifies how to match array type values and conditions. Use `\"some\"` to require only some conditions to match the values, or `\"every\"` to require all conditions to match.\n  - **optional** `prop`: Default: `\"__is_values\"`. [`is`](#is-1) object (function) property that is expected to be returned in the root loader data.\n  - **optional** `routeId`: Default: The root route ID (`\"root\"` or `\"0\"`). The route that provides the `is.__is_values` from its loader. Example: `\"routes/admin\"`.\n\n#### Returns\n\n`createFromLoader` returns an array containing the [`Is`](#is) component, the [`useIs`](#useis) hook and the [`loadIs`](#loadis) loader.\n\n### `<Is>`\n\n#### Props\n\n- `...conditions`: Conditions are merged with the `defaultConditions` and then compared to the [`useValues`](#parameters) / [`loadValues`](#parameters-1) return value. If multiple conditions are given, all must match their corresponding values. For any array-type condition:\n  - If the corresponding value is also an array and `options.method` is `\"some\"` (default), the value array must include at least one of the condition entries. If `options.method` is `\"every\"`, the value array must include all condition entries.\n  - If the corresponding value is not an array, the value must be one of the condition entries.\n- **optional** `children`: The UI you intend to render if all conditions match.\n- **optional** `fallback`: The UI you intend to render if some condition does not match.\n\n#### Usage\n\n```tsx\n<Is authenticated fallback=\"Please log in\">\n  Welcome back!\n</Is>\n\n<IsAuthenticated fallback=\"Please log in\">Welcome back!</IsAuthenticated>\n```\n\n### `useIs`\n\n#### Parameters\n\n- `conditions`: Conditions are merged with the `defaultConditions` and then compared to the [`useValues`](#parameters) / [`loadValues`](#parameters-1) return value. If multiple conditions are given, all must match their corresponding values. For any array-type condition:\n  - If the corresponding value is also an array and `options.method` is `\"some\"` (default), the value array must include at least one of the condition entries. If `options.method` is `\"every\"`, the value array must include all condition entries.\n  - If the corresponding value is not an array, the value must be one of the condition entries.\n\n#### Returns\n\n`useIs` returns `true` if all conditions match, `false` otherwise.\n\n#### Usage\n\n```tsx\nconst isAuthenticated = useIs({ authenticated: true });\nconst isAuthenticated = useIsAuthenticated();\n```\n\n### `loadIs`\n\n#### Parameters\n\n- `args`: React Router / Remix `LoaderFunctionArgs`, `ActionFunctionArgs`, `ClientLoaderFunctionArgs`, or `ClientActionFunctionArgs`.\n\n#### Returns\n\n`loadIs` returns a `Promise` that resolves to the [`is`](#is-1) function.\n\n#### Usage\n\n```tsx\nexport const loader = async (args: LoaderFunctionArgs) => {\n  const is = await loadIs(args);\n  const authenticated = await loadIsAuthenticated(args);\n\n  const isAuthenticated = is({ authenticated: true });\n  const isAuthenticated = authenticated();\n  // ...\n};\n```\n\n### `is`\n\n`is` function is the awaited return value of calling [`loadIs`](#loadis).\n\n#### Parameters\n\n- `conditions`: Conditions are merged with the `defaultConditions` and then compared to the [`useValues`](#parameters) / [`loadValues`](#parameters-1) return value. If multiple conditions are given, all must match their corresponding values. For any array-type condition:\n  - If the corresponding value is also an array and `options.method` is `\"some\"` (default), the value array must include at least one of the condition entries. If `options.method` is `\"every\"`, the value array must include all condition entries.\n  - If the corresponding value is not an array, the value must be one of the condition entries.\n\n#### Returns\n\n`is` returns a `true` if all conditions match, `false` otherwise.\n\n#### Usage\n\nIn `root.tsx` you must also return `...is` from the `loader` / `clientLoader`. See [options](#parameters-1) to use other route.\n\n```tsx\nexport const loader = async (args: LoaderFunctionArgs) => {\n  const is = await loadIs(args);\n\n  return {\n    ...is,\n    // ...other loader data...\n  };\n};\n```\n\n### `toBooleanValues`\n\nCall `toBooleanValues` to convert an array of strings to an object with `true` values.\n\n```ts\nconst permissionList = [\n  \"create-articles\",\n  \"read-articles\",\n  \"update-articles\",\n  \"delete-articles\",\n];\nconst permissionValues = toBooleanValues(permissions);\n// { \"create-articles\": true, \"read-articles\": true, ... }\n```\n\n#### Parameters\n\n- **optional** `strings`: An array of strings.\n\n#### Returns\n\n`toBooleanValues` returns an object with `true` values.\n\n## Types\n\n### `Value`\n\n- Type `Value` is `boolean | number | string`.\n- It may also be more specific, like a union of `string` values.\n\n#### Example\n\n```ts\nconst features = [\"feature-abc\", \"feature-xyz\"] as const;\n\n// \"feature-abc\" | \"feature-xyz\"\ntype Feature = (typeof features)[number];\n```\n\n### `Values`\n\n- Type `Values` is `Record<string, Value | Value[]>`.\n\n#### Example\n\n```json\n{\n  \"authenticated\": true,\n  \"roles\": [\"admin\"],\n  \"permissions\": [\n    \"create-articles\",\n    \"read-articles\",\n    \"update-articles\",\n    \"delete-articles\"\n  ]\n}\n```\n\n### `Conditions`\n\n- Type `Conditions` is `Partial<Values>`.\n\n#### Example\n\n```json\n{\n  \"roles\": \"admin\"\n}\n```\n","readmeFilename":"README.md"}