{"_id":"@bsuite/dry-lint","_rev":"10-d271adbeedeb46c8e01276e16ed546f7","name":"@bsuite/dry-lint","dist-tags":{"latest":"1.0.2"},"versions":{"0.1.0":{"name":"@bsuite/dry-lint","version":"0.1.0","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"license":"UNLICENSED","_id":"@bsuite/dry-lint@0.1.0","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"homepage":"https://github.com/GaryOcean428/bsuite#readme","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"dist":{"shasum":"0964ed9189d2fbad65dcfe9863f2917b0dd1098d","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-0.1.0.tgz","fileCount":16,"integrity":"sha512-2sDWqEzz+0dNbdT4qRUrMltG1tIMdXFGssXjphJJSkO5u9E1rM1mE4VTgvMEdSaDie/PDEOVzLWcn1LMzYHu0A==","signatures":[{"sig":"MEUCIEucdxlByfUQGs82xu6hVei92G7AGIbKc1w2565fcYV6AiEA/7j7NRVgSt0s2vvibKQixWTBveAtxngQQbwfRT5eqm8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57661},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ownership-map":"./src/ownership-map.json"},"gitHead":"bd0dea331e83d5abcd87496e0348cd9a37b8db23","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"garyocean428","email":"braden.lang77@gmail.com"},"repository":{"url":"git+https://github.com/GaryOcean428/bsuite.git","type":"git","directory":"packages/dry-lint"},"_npmVersion":"11.7.0","description":"ESLint plugin enforcing the BSuite one-shot architecture (single owner per Supabase entity table).","directories":{},"_nodeVersion":"25.2.1","dependencies":{"@typescript-eslint/utils":"^8.21.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.18.0","vitest":"^3.2.4","typescript":"~5.7.3","@types/node":"^20.14.0","@typescript-eslint/parser":"^8.21.0","@typescript-eslint/rule-tester":"^8.21.0"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dry-lint_0.1.0_1777112713658_0.6781620584977985","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bsuite/dry-lint","version":"0.1.1","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"license":"UNLICENSED","_id":"@bsuite/dry-lint@0.1.1","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"homepage":"https://github.com/GaryOcean428/bsuite#readme","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"dist":{"shasum":"2b65d08bc3fe4d5ecf6a71b62a5dd434b0348ad2","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-0.1.1.tgz","fileCount":16,"integrity":"sha512-2oXVFM06gzoi1qwR6WBGF2Fksc7CzBvPPod4eeT+dIaYUtwb8EKiIp/0Z6T0kWqwHzLOy4YqgB8yfqrWbkqyqQ==","signatures":[{"sig":"MEYCIQDxpZBHiwFMEHHrPxvbQvX99emlNfCBv5y4sk3Itht3bgIhAIBXDN8tT8rx18ZmOVfipJ0eUBMNxJVW+Am2qSZKwV0U","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":59335},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ownership-map":"./src/ownership-map.json"},"gitHead":"d64c01cbee855111251fc2e04ad4ce4e8b98c7fa","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"garyocean428","email":"braden.lang77@gmail.com"},"repository":{"url":"git+https://github.com/GaryOcean428/bsuite.git","type":"git","directory":"packages/dry-lint"},"_npmVersion":"11.7.0","description":"ESLint plugin enforcing the BSuite one-shot architecture (single owner per Supabase entity table).","directories":{},"_nodeVersion":"25.2.1","dependencies":{"@typescript-eslint/utils":"^8.21.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.18.0","vitest":"^3.2.4","typescript":"~5.7.3","@types/node":"^20.14.0","@typescript-eslint/parser":"^8.21.0","@typescript-eslint/rule-tester":"^8.21.0"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dry-lint_0.1.1_1777113603728_0.7112184543482589","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bsuite/dry-lint","version":"0.1.2","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"license":"UNLICENSED","_id":"@bsuite/dry-lint@0.1.2","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"homepage":"https://github.com/GaryOcean428/bsuite#readme","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"dist":{"shasum":"ad584d3a153516ba27d6343274ceb759e13d336b","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-0.1.2.tgz","fileCount":16,"integrity":"sha512-y7eO9x6rUJa3xP+3uPIAoOo1iIWbcacAMUde+tGc4N6CzcbtpoxMvBRTh2WIQdUSIqerh5z4sROC/oZFMbNOIg==","signatures":[{"sig":"MEQCIAE3G6N3MM7kRdrtfiHP8mdkpJRYINgMlq9uCVYADblEAiArhFhZCcIvBsiXGIOxhpYraAM+7GJgUN9W95mkpYmI1w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":60854},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ownership-map":"./src/ownership-map.json"},"gitHead":"ca34df050246f8f314228713d66b2904c939a96b","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"garyocean428","email":"braden.lang77@gmail.com"},"repository":{"url":"git+https://github.com/GaryOcean428/bsuite.git","type":"git","directory":"packages/dry-lint"},"_npmVersion":"11.7.0","description":"ESLint plugin enforcing the BSuite one-shot architecture (single owner per Supabase entity table).","directories":{},"_nodeVersion":"25.2.1","dependencies":{"@typescript-eslint/utils":"^8.21.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.18.0","vitest":"^3.2.4","typescript":"~5.7.3","@types/node":"^20.14.0","@typescript-eslint/parser":"^8.21.0","@typescript-eslint/rule-tester":"^8.21.0"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dry-lint_0.1.2_1777252102045_0.5128571048864936","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bsuite/dry-lint","version":"0.2.0","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"license":"UNLICENSED","_id":"@bsuite/dry-lint@0.2.0","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"homepage":"https://github.com/GaryOcean428/bsuite#readme","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"dist":{"shasum":"f6234f9e8561ee855ef606ace3c463d2429ee90c","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-0.2.0.tgz","fileCount":16,"integrity":"sha512-7fbaNvrPpsqCW7uoumW8N2nhIwJKtpeECCpF9HR2xvJnrJzmjr238uzg7lCUX0SG86vrbAOlmIFpHE+u4TTmjA==","signatures":[{"sig":"MEQCIGpLGA5EyQKc07KOpdFf+W5yXIHjhDaGu6ijae16fx40AiBr+HXg4fl04T+5zL/aXntDpdCejwHOGsR0SAXe5glA9A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":68244},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ownership-map":"./src/ownership-map.json"},"gitHead":"c55aac508dfc5987ea0fa419fcaca0499cd8060b","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"garyocean428","email":"braden.lang77@gmail.com"},"repository":{"url":"git+https://github.com/GaryOcean428/bsuite.git","type":"git","directory":"packages/dry-lint"},"_npmVersion":"11.7.0","description":"ESLint plugin enforcing the BSuite one-shot architecture (single owner per Supabase entity table).","directories":{},"_nodeVersion":"25.2.1","dependencies":{"@typescript-eslint/utils":"^8.21.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.18.0","vitest":"^3.2.4","typescript":"~5.7.3","@types/node":"^20.14.0","@typescript-eslint/parser":"^8.21.0","@typescript-eslint/rule-tester":"^8.21.0"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dry-lint_0.2.0_1777257558276_0.7854964325057849","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@bsuite/dry-lint","version":"0.4.0","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"license":"UNLICENSED","_id":"@bsuite/dry-lint@0.4.0","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"homepage":"https://github.com/GaryOcean428/bsuite#readme","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"dist":{"shasum":"a3fdb3e187780634580ac6b461f14f9ebf8053ba","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-0.4.0.tgz","fileCount":24,"integrity":"sha512-BZJxUBnf+y25jHWWb+BAvuF0HnWGYTtgvuv5R1izlyxRvwy9RiAZ3D88MCQqzf7mNWg/ccBi2fEZHByx4pGZHQ==","signatures":[{"sig":"MEUCIQDpu9jm34SvzYIVsPqRHNnuP5hznzrXQenfpox6sk4rnQIgaf6krGVZQHaJIIC1r63RkoOM/ZA2Bq3fIo/p/F/Z6nk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94063},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ownership-map":"./src/ownership-map.json"},"gitHead":"335cae7befafb081a9f2912c3d1a504f7f53466c","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"garyocean428","email":"braden.lang77@gmail.com"},"repository":{"url":"git+https://github.com/GaryOcean428/bsuite.git","type":"git","directory":"packages/dry-lint"},"_npmVersion":"11.11.0","description":"ESLint plugin enforcing BSuite one-shot architecture (single-owner Supabase entity tables) and the OAuth callback bridge contract.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"@typescript-eslint/utils":"^8.59.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.4.2","eslint":"^9.39.4","vitest":"^4.1.5","typescript":"~5.9.3","@types/node":"^24.12.2","@typescript-eslint/parser":"^8.59.2","@typescript-eslint/rule-tester":"^8.59.2"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dry-lint_0.4.0_1778052897484_0.8836001082970184","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@bsuite/dry-lint","version":"0.5.0","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"license":"UNLICENSED","_id":"@bsuite/dry-lint@0.5.0","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"homepage":"https://github.com/GaryOcean428/bsuite#readme","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"dist":{"shasum":"6307c82416ee26667abb9b4cfadb572cc2698ec1","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-0.5.0.tgz","fileCount":28,"integrity":"sha512-Cc6664ZkUETxWjKybtcEjKTgXopDHNLQF7d/7ZWLD1eieKCT8AXj/bw4PlIQZnDtZ8JpoXIaApWq+L2HB5LnCQ==","signatures":[{"sig":"MEUCIQDJMsLG+E8uFYfSKr0LFKoi/KwYuBICbr0SPZ/VNrpbywIgQHN+0huelytDfD/ovkMlbvqgLQH9o/LLbDW5Pt/hGwI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113743},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ownership-map":"./src/ownership-map.json"},"gitHead":"fc531c9de561d0a105bbe494825faddd0af45017","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f04a6dcd-39ca-4da0-9923-a9907c42d2b8"}},"repository":{"url":"git+https://github.com/GaryOcean428/bsuite.git","type":"git","directory":"packages/dry-lint"},"_npmVersion":"11.9.0","description":"ESLint plugin enforcing BSuite one-shot architecture (single-owner Supabase entity tables) and the OAuth callback bridge contract.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"@typescript-eslint/utils":"^8.59.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.4.2","eslint":"^9.39.4","vitest":"^4.1.5","typescript":"~5.9.3","@types/node":"^24.12.2","@typescript-eslint/parser":"^8.59.2","@typescript-eslint/rule-tester":"^8.59.2"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dry-lint_0.5.0_1780480985157_0.8141214255964284","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@bsuite/dry-lint","version":"0.6.0","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"license":"UNLICENSED","_id":"@bsuite/dry-lint@0.6.0","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"homepage":"https://github.com/GaryOcean428/bsuite#readme","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"dist":{"shasum":"344a99dbd526f0233ad4650adff7098d5c7cb8e1","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-0.6.0.tgz","fileCount":32,"integrity":"sha512-xn4EuWxCpqSad82q4QjUqD/3qI+sML9GKyP6/JzEIOJeAeRJWtYaD1dlyC4v2brz8007WT7z0zCes28RiiLWmg==","signatures":[{"sig":"MEYCIQDeXHoslwNq/lGTTUyeyZ1xrtR1WFzSHZTA3GjkoKe/DQIhAOdnqzEswZDnftFBzI2DKChioBJK1GjJ/wudcIm2L2+s","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":135331},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ownership-map":"./src/ownership-map.json"},"gitHead":"e5eef1937b6c9c21113ff462f38fc17f91ffc28d","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f04a6dcd-39ca-4da0-9923-a9907c42d2b8"}},"repository":{"url":"git+https://github.com/GaryOcean428/bsuite.git","type":"git","directory":"packages/dry-lint"},"_npmVersion":"11.9.0","description":"ESLint plugin enforcing BSuite one-shot architecture (single-owner Supabase entity tables) and the OAuth callback bridge contract.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"@typescript-eslint/utils":"^8.61.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.16","eslint":"^10.4.1","vitest":"^4.1.8","typescript":"~6.0.3","@types/node":"^25.9.2","@typescript-eslint/parser":"^8.61.0","@typescript-eslint/rule-tester":"^8.61.0"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dry-lint_0.6.0_1784542307568_0.11827194046094269","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@bsuite/dry-lint","version":"1.0.0","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"license":"UNLICENSED","_id":"@bsuite/dry-lint@1.0.0","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"homepage":"https://github.com/GaryOcean428/bsuite#readme","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"dist":{"shasum":"8e4faf4bb4696b7d79827c8d405107d239125d24","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-1.0.0.tgz","fileCount":32,"integrity":"sha512-HPCO7t91XROw6yTQgxaAwpklur4VirI4wHv4iv37mgF93ntVti7A61jeKSNq2REbChepHOl8zXwJCWbd7W41vw==","signatures":[{"sig":"MEYCIQCWNxdCqiZThPduYmsIBC1iA8Bge47hAk2G7S8rvxqz9AIhANI0/iYClQgjAqHVZPCFQRJuq1EoH8RW6DsIbWYoMWyY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":135262},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ownership-map":"./src/ownership-map.json"},"gitHead":"f02dcdea811b44f0500f34c197b2b46022cff27c","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f04a6dcd-39ca-4da0-9923-a9907c42d2b8"}},"repository":{"url":"git+https://github.com/GaryOcean428/bsuite.git","type":"git","directory":"packages/dry-lint"},"_npmVersion":"11.9.0","description":"ESLint plugin enforcing BSuite one-shot architecture (single-owner Supabase entity tables) and the OAuth callback bridge contract.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"@typescript-eslint/utils":"^8.61.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.16","eslint":"^10.4.1","vitest":"^4.1.8","typescript":"~6.0.3","@types/node":"^25.9.2","@typescript-eslint/parser":"^8.61.0","@typescript-eslint/rule-tester":"^8.61.0"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dry-lint_1.0.0_1784771049267_0.3225499092724202","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@bsuite/dry-lint","version":"1.0.1","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"license":"UNLICENSED","_id":"@bsuite/dry-lint@1.0.1","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"homepage":"https://github.com/GaryOcean428/bsuite#readme","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"dist":{"shasum":"2a36a5c866d2212239945c4f96b5f2f80aab6950","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-1.0.1.tgz","fileCount":32,"integrity":"sha512-JU3DaGSOlN5DQ/uhxw4nCo+EY4a+qweD3TJFoJRUUKTyYHfDB0adEMGduOxJE9pvaH0lY9WwBhMrVhrLnfVLfQ==","signatures":[{"sig":"MEUCIQD7W1OFGLkZ1IHnANS26VWPKsenvBZTG8rllt3YmlK30wIgT9wuNHPqN1Bu+ZRbhraopT2w5AjBfLlbKrt8/UB5dD4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":141835},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ownership-map":"./src/ownership-map.json"},"gitHead":"8ceb697002cbca08ac6c0c9b19c7f7d431fc9acb","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f04a6dcd-39ca-4da0-9923-a9907c42d2b8"}},"repository":{"url":"git+https://github.com/GaryOcean428/bsuite.git","type":"git","directory":"packages/dry-lint"},"_npmVersion":"11.9.0","description":"ESLint plugin enforcing BSuite one-shot architecture (single-owner Supabase entity tables) and the OAuth callback bridge contract.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"@typescript-eslint/utils":"^8.61.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.16","eslint":"^10.4.1","vitest":"^4.1.8","typescript":"~6.0.3","@types/node":"^25.9.2","@typescript-eslint/parser":"^8.61.0","@typescript-eslint/rule-tester":"^8.61.0"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dry-lint_1.0.1_1784896400643_0.059945098906080796","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@bsuite/dry-lint","version":"1.0.2","description":"ESLint plugin enforcing BSuite one-shot architecture (single-owner Supabase entity tables) and the OAuth callback bridge contract.","type":"module","license":"UNLICENSED","repository":{"type":"git","url":"git+https://github.com/GaryOcean428/bsuite.git","directory":"packages/dry-lint"},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./ownership-map":"./src/ownership-map.json"},"scripts":{"build":"tsc -p tsconfig.build.json && node scripts/copy-assets.mjs","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit"},"keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"devDependencies":{"@types/node":"^25.9.2","@typescript-eslint/parser":"^8.61.0","@typescript-eslint/rule-tester":"^8.61.0","eslint":"^10.4.1","typescript":"~6.0.3","vite":"^8.0.16","vitest":"^4.1.8","esbuild":"^0.28.1"},"dependencies":{"@typescript-eslint/utils":"^8.61.0"},"peerDependencies":{"eslint":">=9.0.0"},"publishConfig":{"access":"public"},"packageManager":"pnpm@10.33.3","gitHead":"e9f17483fa97337703d3a22e2e2d31b28df89173","_id":"@bsuite/dry-lint@1.0.2","bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"homepage":"https://github.com/GaryOcean428/bsuite#readme","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-qj+uhfdeW4mUfZHTMMkEzPgx+uRjK/oEgnljgGVQPBqwOtRBm39jl5U6FEdWJ7n2K4t5eRtiHXCegUp8OWH9QQ==","shasum":"3df520dacec1039333590e2ca956d79faacea078","tarball":"https://registry.npmjs.org/@bsuite/dry-lint/-/dry-lint-1.0.2.tgz","fileCount":32,"unpackedSize":143050,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC42S2t//+rnFIQcTI89P3LrNxObQBPf3Kdx/1XX4mY9AiBSHmXULI/fn5LPwPLlejuVZfvZNkNa9ofwKSLMp5yhYQ=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f04a6dcd-39ca-4da0-9923-a9907c42d2b8"}},"directories":{},"maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dry-lint_1.0.2_1787377238636_0.49851976311662693"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-25T10:25:13.556Z","modified":"2026-08-22T05:40:38.969Z","0.1.0":"2026-04-25T10:25:13.796Z","0.1.1":"2026-04-25T10:40:03.867Z","0.1.2":"2026-04-27T01:08:22.176Z","0.2.0":"2026-04-27T02:39:18.405Z","0.4.0":"2026-05-06T07:34:57.667Z","0.5.0":"2026-06-03T10:03:05.382Z","0.6.0":"2026-07-20T10:11:47.733Z","1.0.0":"2026-07-23T01:44:09.404Z","1.0.1":"2026-07-24T12:33:20.771Z","1.0.2":"2026-08-22T05:40:38.788Z"},"bugs":{"url":"https://github.com/GaryOcean428/bsuite/issues"},"license":"UNLICENSED","homepage":"https://github.com/GaryOcean428/bsuite#readme","keywords":["eslint","eslintplugin","eslint-plugin","bsuite","supabase"],"repository":{"type":"git","url":"git+https://github.com/GaryOcean428/bsuite.git","directory":"packages/dry-lint"},"description":"ESLint plugin enforcing BSuite one-shot architecture (single-owner Supabase entity tables) and the OAuth callback bridge contract.","maintainers":[{"name":"garyocean428","email":"braden.lang77@gmail.com"}],"readme":"# @bsuite/dry-lint\n\nESLint flat-config plugin that enforces the BSuite **one-shot architecture** — every Supabase entity table has a single canonical owner app, and other apps may READ but never WRITE to it.\n\nThe plugin ships four rules:\n\n| Rule | Default | Purpose |\n|------|---------|---------|\n| `bsuite/no-cross-app-write` | `error` | Errors when an app calls `.from('<table>').{insert,update,upsert,delete}()` against a table owned by a different app per the ownership map. |\n| `bsuite/no-raw-entity-select` | `warn` | Flags raw `.select()` reads against canonical entity tables — encourages going through the typed entity-service layer. |\n| `bsuite/no-uuid-input-placeholder` | `error` | Flags `<Input placeholder=\"UUID of …\">` and similar UUID-prompting placeholders on `<Input>`/`<input>`/`<Textarea>`/`<textarea>`. Operators must pick from a canonical entity selector, not paste a UUID by hand. |\n| `bsuite/oauth-callback-must-bridge` | `error` | Errors when a file calls `exchangeCodeForTokens()` without a corresponding `supabase.auth.setSession()` bridge — prevents the BSU→app handoff from leaving the user anonymous. |\n\nThe ownership map lives at [`src/ownership-map.json`](./src/ownership-map.json) and is sourced from `docs/20260227-dry-one-shot-architecture-v1.04A.md §1` plus the V5–V10 findings in `docs/20260423-cross-app-write-audit-v1.00W.md`.\n\n## `bsuite/no-uuid-input-placeholder`\n\nForces operators to use canonical entity selectors instead of free-text UUID inputs. Triggered after the 2026-06-01 sweep (PRs #933–#939) which replaced raw UUID inputs across 16 CRM7 pages.\n\n### Detected pattern\n\n```tsx\n// ❌ flagged — operator should pick, not paste\n<Input placeholder=\"UUID of host employer\" />\n<Input placeholder=\"Enter apprentice UUID\" />\n<Input placeholder=\"Apprentice UUID\" />\n```\n\n### Canonical fix\n\n```tsx\n// ✅ pick from a canonical entity selector\nimport { EmployerSelector } from '@/components/entity/selectors';\n\n<EmployerSelector\n  value={hostEmployerId}\n  onSelect={(entity) => setHostEmployerId(entity?.id ?? '')}\n/>\n```\n\nIf no selector exists, build one mirroring the `IncidentSelector` I4 pattern (tenant-scoped via explicit `.eq('tenant_id', …)` on top of RLS).\n\n### Allowed escapes\n\n- Test, spec, stories, and `__mocks__` paths are skipped automatically.\n- Inline `// eslint-disable-next-line bsuite/no-uuid-input-placeholder` for genuinely-no-canonical-entity surfaces (developer-only debug tools). Document why with a comment.\n\n---\n\n## Install\n\n```bash\npnpm add -D @bsuite/dry-lint\n```\n\nThe plugin is ESLint v9 flat-config compatible. It declares `eslint >=9` as a peer dependency.\n\n---\n\n## Usage\n\n### Recommended — one-line wire-up\n\n```ts\n// eslint.config.ts\nimport bsuiteDryLint from '@bsuite/dry-lint';\n\nexport default [\n  bsuiteDryLint.configs.recommended, // bsuite/no-cross-app-write: error\n  // ...rest of your config\n];\n```\n\n### Warn-only (useful during phased rollout)\n\n```ts\nimport bsuiteDryLint from '@bsuite/dry-lint';\n\nexport default [\n  bsuiteDryLint.configs.warn, // bsuite/no-cross-app-write: warn\n];\n```\n\n### Manual wiring with options\n\n```ts\nimport bsuiteDryLint from '@bsuite/dry-lint';\n\nexport default [\n  {\n    plugins: { bsuite: bsuiteDryLint },\n    rules: {\n      'bsuite/no-cross-app-write': [\n        'error',\n        {\n          // Override the auto-detected app (default: inferred from file path)\n          appOverride: 'crm7',\n          // Also report writes to tables not in the ownership map (default: false)\n          warnOnUnknownTable: true,\n        },\n      ],\n    },\n  },\n];\n```\n\n---\n\n## How app detection works\n\nThe rule needs to know which app a file belongs to so it can compare against the ownership map. **Every real app config passes an explicit `appOverride`** (see the \"Configuration\" examples above — each app's `eslint.config.js` sets `{ appOverride: '<app>' }`), so in practice `appOverride` is what actually determines the app in production; the automatic detector below only runs when `appOverride` is omitted.\n\nDetection (`detectAppFromPath()`, `src/app-detection.ts`) walks up from the linted **file's own directory** looking for the nearest `package.json`, bounded at the first `.git` marker (file or directory — covers git-worktree checkouts, where `.git` is a file pointing at the real gitdir). The `package.json` `name` field is matched against:\n\n| `package.json` `name` | App key |\n|---|---|\n| `business-suite-unified` | `bsu` |\n| `crm7-complete`, `crm7` | `crm7` |\n| `conduit` | `conduit` |\n| `braden-app` | `braden` |\n| `r80-calculator`, `r80.3` | `r80` |\n| `throughput` | `throughput` |\n| any `@bsuite/*` scoped package | `shared` |\n\nIf no `package.json` is found before the `.git` boundary, or its `name` doesn't match, the rule no-ops on that file (fail closed — a missed detection is always safe; a false attribution is not).\n\n**bsuite#1623:** an earlier version of this detector matched path SEGMENTS instead (e.g. treating any `crm7` directory-name segment as the CRM7 app). That broke for the platform's standard `git worktree add /home/<user>/Desktop/Dev/<app>-<feature>-worktree` convention — a worktree checked out as a SIBLING of `bsuite/` with a directory name that doesn't literally equal the app name — and misattributed such files to whichever known app name happened to appear anywhere in the path (including a contributor's own home directory). The `package.json`-based walk above is immune to checkout directory naming entirely.\n\nYou can override detection per-config-block via the `appOverride` option — and every shipped app config does.\n\n---\n\n## How write detection works\n\nThe rule walks the AST for any call expression where the callee is a member access ending in one of `insert`, `update`, `upsert`, or `delete`. It then walks back along the query-builder chain until it finds the closest `.from('<literal>')` call and resolves the table name.\n\nThe chain walk handles:\n\n- Direct calls — `supabase.from('x').insert(...)`\n- Chained query-builder calls — `supabase.from('x').select('*').eq('id', 1).update(...)`\n- `await`-wrapped calls\n- Calls preceded by any number of intermediate `.from()`-irrelevant query methods\n\nIt does NOT report:\n\n- Reads (`.select(...)`)\n- Calls where the table name is a non-literal expression (e.g. a variable). This is intentional — we'd rather miss a few cases than spam false positives.\n- Calls in files outside any known app.\n\n---\n\n## Adding a new table to the ownership map\n\nEach entry uses **EXACTLY ONE** of `owner` (single canonical write surface) or `writers` (multi-writer admin co-ownership, `@bsuite/dry-lint@0.2.0`+). Setting both is a schema error.\n\n### Single-owner entry (most common)\n\n1. Open [`src/ownership-map.json`](./src/ownership-map.json).\n2. Add an entry under `tables`:\n\n   ```jsonc\n   {\n     \"tables\": {\n       \"your_new_table\": {\n         \"owner\": \"crm7\",        // one of: bsu, crm7, conduit, braden, r80, throughput, shared, all\n         \"readers\": [\"bsu\"],     // apps that may .select() but never write\n         \"$comment\": \"Optional context, e.g. audit reference.\"\n       }\n     }\n   }\n   ```\n\n3. Use `\"shared\"` if the table is co-owned by 2+ apps with a documented audit-trail / append-only pattern (e.g. `wage_calculation_snapshots`).\n4. Use `\"all\"` for explicit event-sink tables (e.g. `bi_metrics`).\n\n### Multi-writer entry (PHASE-3c, v0.2.0+)\n\nFor admin-CRUD tables co-owned by an explicit allow-list of apps (e.g. `tenants` + `user_tenants`, where BSU is the platform owner and CRM7's tenant-management edge function performs legitimate org-admin operations under RLS):\n\n```jsonc\n{\n  \"tables\": {\n    \"your_co_owned_table\": {\n      \"writers\": [\"bsu\", \"crm7\"],   // explicit allow-list — at least one app\n      \"readers\": [\"r80\", \"conduit\"], // apps that may .select() only\n      \"$comment\": \"Why this is multi-writer rather than single-owner.\"\n    }\n  }\n}\n```\n\nThe rule will pass writes from any listed app and flag writes from non-listed apps with a `crossAppWriteMultiWriter` message.\n\n### Versioning\n\nBump the `@bsuite/dry-lint` version (patch for new tables, minor for owner moves or schema additions) and republish.\n\n---\n\n## Owner keys\n\n| Key | App | Repo |\n|-----|-----|------|\n| `bsu` | business-suite-unified | `business-suite-unified/` |\n| `crm7` | CRM7 | `crm7/` |\n| `conduit` | Conduit (recruitment ATS) | `conduit/` |\n| `braden` | braden.com.au corporate site | `braden/` |\n| `r80` | R80.3 wage calculator | `R80.3/` |\n| `throughput` | Throughput (idea management) | `throughput/` |\n| `shared` | Co-owned by multiple apps (audit-trail / append-only) | n/a |\n| `all` | Event sink — any app may write | n/a |\n\n---\n\n## Known violations and enforcement posture\n\nConsumer apps should wire `bsuite/no-cross-app-write` as `error`. Pre-existing\nlegacy write paths must be isolated with narrow per-file overrides in the\nconsumer ESLint config; do not keep the base rule in warn-mode.\n\nThe 2026-04-27 Phase 2D promotion moved BSU, CRM7, Conduit, R80.3, Braden, and\nThroughput to error-level enforcement while preserving documented exception\nsets for the Phase 5 ownership-relocation work.\n\nRun the dry-run helper after ownership-map edits to identify any exception list\nthat can be removed:\n\n```bash\npnpm --filter @bsuite/dry-lint build\nnode packages/dry-lint/scripts/dry-run.mjs\n```\n\n---\n\n## Development\n\n```bash\n# Install (use --ignore-workspace until package is added to pnpm-workspace.yaml)\ncd packages/dry-lint && pnpm install --ignore-workspace\n\n# Build\npnpm build\n\n# Run tests\npnpm test\n```\n","readmeFilename":"README.md"}