{"_id":"@anishpras/rbac","_rev":"7-d6249ad15709a1af33359e2514be7688","name":"@anishpras/rbac","dist-tags":{"latest":"2.1.1"},"versions":{"1.0.0":{"name":"@anishpras/rbac","version":"1.0.0","keywords":["rbac","authorization","permissions","access-control","security"],"author":{"name":"Anish Prashun","email":"anishprashun118@gmail.com"},"license":"MIT","_id":"@anishpras/rbac@1.0.0","maintainers":[{"name":"anishpras","email":"anishprashun118@gmail.com"}],"homepage":"https://github.com/anishpras/rbac#readme","bugs":{"url":"https://github.com/anishpras/rbac/issues"},"dist":{"shasum":"13c161d0c889238a810d6a356dd59ea9a91e0f68","tarball":"https://registry.npmjs.org/@anishpras/rbac/-/rbac-1.0.0.tgz","fileCount":17,"integrity":"sha512-JTrhIxWopXcw0XZO9Oa0jBOQ6gXuuSi92Si2xlGCCkADW4i7jBR8y/A33+ATnHmNmQ6pT+LVoOUn1hc2tsROkA==","signatures":[{"sig":"MEUCIQDo63fhhtV2fOzNxXqd3IqlLRPgHu9jHqHSZNg7DEVnFgIgcwVooRBwkg8/h3Ct0VBW42hTXg2pyRxa4fAocAY1NaQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47624},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"gitHead":"818c994de50d1d59bb2e3c390d8face0fe247c1d","scripts":{"lint":"echo 'Linting temporarily disabled'","test":"jest","build":"tsc","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","prepublishOnly":"npm run test && npm run build"},"_npmUser":{"name":"anishpras","email":"anishprashun118@gmail.com"},"repository":{"url":"git+https://github.com/anishpras/rbac.git","type":"git"},"_npmVersion":"10.9.0","description":"A fast, flexible, and production-ready role-based access control (RBAC) system for JavaScript/TypeScript applications.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","dependencies":{"fast-deep-equal":"^3.1.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.56.0","ts-jest":"^29.1.1","prettier":"^3.0.3","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@typescript-eslint/parser":"^6.7.2","@typescript-eslint/eslint-plugin":"^6.7.2"},"_npmOperationalInternal":{"tmp":"tmp/rbac_1.0.0_1743102551506_0.4701967992355436","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@anishpras/rbac","version":"1.0.1","keywords":["rbac","authorization","permissions","access-control","security"],"author":{"name":"Anish Prashun","email":"anishprashun118@gmail.com"},"license":"MIT","_id":"@anishpras/rbac@1.0.1","maintainers":[{"name":"anishpras","email":"anishprashun118@gmail.com"}],"homepage":"https://github.com/anishpras/rbac#readme","bugs":{"url":"https://github.com/anishpras/rbac/issues"},"dist":{"shasum":"9912ea67592c21c1786439f43a19e8dbccf7deac","tarball":"https://registry.npmjs.org/@anishpras/rbac/-/rbac-1.0.1.tgz","fileCount":17,"integrity":"sha512-ZVPdUqOUxD11xWUXjU6IrFSfDm6kXbvNuQZmeoS+ffY4g0We3nkev8uUiAj9BiJ20K4Ica7bGbey0POGEuUing==","signatures":[{"sig":"MEQCIHw+PogvfqGrgEhPZ+l0ldORspgdWgagNGFk3dwj4pH0AiBklty1IwrXLDb8C+379Fzy8K4h18upnh+/+4m5+2LkmA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47644},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"gitHead":"ff35917dbb53110be24c53a35abfa2b2b1421e13","scripts":{"lint":"echo 'Linting temporarily disabled'","test":"jest","build":"tsc","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","prepublishOnly":"npm run test && npm run build"},"_npmUser":{"name":"anishpras","email":"anishprashun118@gmail.com"},"repository":{"url":"git+https://github.com/anishpras/rbac.git","type":"git"},"_npmVersion":"10.9.0","description":"A fast, flexible, and production-ready role-based access control (RBAC) system for JavaScript/TypeScript applications.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","dependencies":{"fast-deep-equal":"^3.1.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.56.0","ts-jest":"^29.1.1","prettier":"^3.0.3","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@typescript-eslint/parser":"^6.7.2","@typescript-eslint/eslint-plugin":"^6.7.2"},"_npmOperationalInternal":{"tmp":"tmp/rbac_1.0.1_1743105427945_0.9082052802816696","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@anishpras/rbac","version":"1.1.0","keywords":["rbac","authorization","permissions","access-control","security"],"author":{"name":"Anish Prashun","email":"anishprashun118@gmail.com"},"license":"MIT","_id":"@anishpras/rbac@1.1.0","maintainers":[{"name":"anishpras","email":"anishprashun118@gmail.com"}],"homepage":"https://github.com/anishpras/rbac#readme","bugs":{"url":"https://github.com/anishpras/rbac/issues"},"dist":{"shasum":"e46f80935e1ac4199f2ca55901e3b2cd4042dcb4","tarball":"https://registry.npmjs.org/@anishpras/rbac/-/rbac-1.1.0.tgz","fileCount":19,"integrity":"sha512-v6TAsmdp47or8K1ekbUsf9lDoxPOFpCEH1dpegBs9S095Z41brzM5SkcU8F/wEcrtELsXReebztRCvDac7i56g==","signatures":[{"sig":"MEYCIQCXeZq9T1cXqmShl2PTzpFC15Ai8LykJ9N6BFpyQvZq1QIhAJMKj8DLgVB0yhaTeuEJ0eCdB0CFJ6xpOyeAmYQEDtVE","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48389},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"gitHead":"aef7b41817220185ac88c1ffc1b6a3325d55c89e","scripts":{"fix":"biome check --apply-safe ./src","lint":"biome check ./src","test":"jest","build":"tsc","check":"biome check ./src","format":"biome format --write ./src","prepare":"npm run build","fix:unsafe":"biome check --fix --unsafe","prepublishOnly":"npm run lint && npm run test && npm run build"},"_npmUser":{"name":"anishpras","email":"anishprashun118@gmail.com"},"repository":{"url":"git+https://github.com/anishpras/rbac.git","type":"git"},"_npmVersion":"10.9.0","description":"A fast, flexible, and production-ready role-based access control (RBAC) system for JavaScript/TypeScript applications.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","dependencies":{"fast-deep-equal":"^3.1.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@biomejs/biome":"^1.9.4"},"_npmOperationalInternal":{"tmp":"tmp/rbac_1.1.0_1743107158391_0.6913462947953812","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@anishpras/rbac","version":"2.0.0","keywords":["rbac","authorization","permissions","access-control","security"],"author":{"name":"Anish Prashun","email":"anishprashun118@gmail.com"},"license":"MIT","_id":"@anishpras/rbac@2.0.0","maintainers":[{"name":"anishpras","email":"anishprashun118@gmail.com"}],"homepage":"https://github.com/anishpras/rbac#readme","bugs":{"url":"https://github.com/anishpras/rbac/issues"},"dist":{"shasum":"3a2c337f88f16f8463f480b1d895d7d1d913c714","tarball":"https://registry.npmjs.org/@anishpras/rbac/-/rbac-2.0.0.tgz","fileCount":19,"integrity":"sha512-aNsVl6hctEI7qWgxZLxu9bpOTOARsufOIwAx9EGdAbO723bDunnOrsdrvkXGbch+RtjrWE4Uk0JqKtqtGxK9Gg==","signatures":[{"sig":"MEUCIQDmzsBubZLB5x0t2Wrbbhpe8K6TdfqzcKnfF/7Ca0/kTgIgJfh/NZrp3YFiHGHHcQtoatkxSVDqpCLTZW8XtDIdj18=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":75773},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"gitHead":"533f59a58e499f39b23beaa1d5bee737280df1f9","scripts":{"fix":"biome check --apply-safe ./src","lint":"biome check ./src","test":"jest","build":"tsc","check":"biome check ./src","format":"biome format --write ./src","prepare":"npm run build","fix:unsafe":"biome check --fix --unsafe","prepublishOnly":"npm run lint && npm run test && npm run build"},"_npmUser":{"name":"anishpras","email":"anishprashun118@gmail.com"},"repository":{"url":"git+https://github.com/anishpras/rbac.git","type":"git"},"_npmVersion":"10.9.0","description":"A fast, flexible, and production-ready role-based access control (RBAC) system for JavaScript/TypeScript applications.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","dependencies":{"fast-deep-equal":"^3.1.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@biomejs/biome":"^1.9.4"},"_npmOperationalInternal":{"tmp":"tmp/rbac_2.0.0_1743109222784_0.33944434729707584","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@anishpras/rbac","version":"2.0.1","keywords":["rbac","authorization","permissions","access-control","security"],"author":{"name":"Anish Prashun","email":"anishprashun118@gmail.com"},"license":"MIT","_id":"@anishpras/rbac@2.0.1","maintainers":[{"name":"anishpras","email":"anishprashun118@gmail.com"}],"homepage":"https://github.com/anishpras/rbac#readme","bugs":{"url":"https://github.com/anishpras/rbac/issues"},"dist":{"shasum":"65dcf5bdb59326c0d6c46bf890aa09b762de88b0","tarball":"https://registry.npmjs.org/@anishpras/rbac/-/rbac-2.0.1.tgz","fileCount":19,"integrity":"sha512-fx1ZX2Pk/UP5VJT5pstLtztgXI3I5jV7wO9K3h0Ok3Vsa9znRobqJjXSz5BXMxtQKbLsb5bNPuGc4aoORa/45w==","signatures":[{"sig":"MEUCIQC3O9XeetHuV6Mls5PgzHhWQTOCHCSTM2o2e5Fsoajr4wIgD8HiqnNnfMn9PQoj4QTOaI7rUP7zsngDYZ5NoD9wZLA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":75716},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"gitHead":"3e71fff259251b9240d7d52183bef4d33db22085","scripts":{"fix":"biome check --apply-safe ./src","lint":"biome check ./src","test":"jest","build":"tsc","check":"biome check ./src","format":"biome format --write ./src","prepare":"npm run build","fix:unsafe":"biome check --fix --unsafe","prepublishOnly":"npm run lint && npm run test && npm run build"},"_npmUser":{"name":"anishpras","email":"anishprashun118@gmail.com"},"repository":{"url":"git+https://github.com/anishpras/rbac.git","type":"git"},"_npmVersion":"10.9.0","description":"A fast, flexible, and production-ready role-based access control (RBAC) system for JavaScript/TypeScript applications.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@biomejs/biome":"^1.9.4"},"_npmOperationalInternal":{"tmp":"tmp/rbac_2.0.1_1743112204797_0.13850505788013123","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@anishpras/rbac","version":"2.1.0","keywords":["rbac","authorization","permissions","access-control","security"],"author":{"name":"Anish Prashun","email":"anishprashun118@gmail.com"},"license":"MIT","_id":"@anishpras/rbac@2.1.0","maintainers":[{"name":"anishpras","email":"anishprashun118@gmail.com"}],"homepage":"https://github.com/anishpras/rbac#readme","bugs":{"url":"https://github.com/anishpras/rbac/issues"},"dist":{"shasum":"0aa2a2949dda0cbea5cf76d18b66d61080360802","tarball":"https://registry.npmjs.org/@anishpras/rbac/-/rbac-2.1.0.tgz","fileCount":27,"integrity":"sha512-IeRr/nbOrzcYcVuIzURrujTuUfqyarVyjm7s3AiF0hk4U5TmEU3K0QqMlcDjtg0Cquin/vuWztRy/o3CSNLiXQ==","signatures":[{"sig":"MEYCIQDmXCdWIcWGOLH3eypWoFVgo/N7PHz9TwU6GWon8G1A0gIhAMuvy2NO9XohiFS39aWns+Db8CstzNXPPVZ50tbPERZM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":107638},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"gitHead":"6a151186ba87163a34fcb3ca1e59e5310f4ca37e","scripts":{"fix":"biome check --apply-safe ./src","lint":"biome check ./src","test":"jest","build":"tsc","check":"biome check ./src","format":"biome format --write ./src","minify":"node scripts/minify.js","prepare":"npm run build:prod","build:all":"npm run build && npm run build:prod","build:prod":"tsc -p tsconfig.prod.json && npm run minify","fix:unsafe":"biome check --fix --unsafe","prepublishOnly":"npm run lint && npm run test && npm run build:prod"},"_npmUser":{"name":"anishpras","email":"anishprashun118@gmail.com"},"repository":{"url":"git+https://github.com/anishpras/rbac.git","type":"git"},"_npmVersion":"10.9.0","description":"A fast, flexible, and production-ready role-based access control (RBAC) system for JavaScript/TypeScript applications.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","terser":"^5.39.0","ts-jest":"^29.1.1","typescript":"^5.2.2","@types/jest":"^29.5.5","@types/node":"^20.6.3","@biomejs/biome":"^1.9.4"},"_npmOperationalInternal":{"tmp":"tmp/rbac_2.1.0_1743112960829_0.6550808197620523","host":"s3://npm-registry-packages-npm-production"}},"2.1.1":{"name":"@anishpras/rbac","version":"2.1.1","description":"A fast, flexible, and production-ready role-based access control (RBAC) system for JavaScript/TypeScript applications.","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"require":"./dist/index.js","import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"tsc","build:prod":"tsc -p tsconfig.prod.json && npm run minify","build:all":"npm run build && npm run build:prod","minify":"node scripts/minify.js","test":"jest","lint":"biome check ./src","format":"biome format --write ./src","fix":"biome check --apply-safe ./src","fix:unsafe":"biome check --fix --unsafe","check":"biome check ./src","pkg-size":"npm pack --dry-run && tar -tvf anishpras-rbac-*.tgz | sort -k 3 -n","prepublishOnly":"npm run lint && npm run test && npm run build:release","build:release":"NODE_ENV=production tsc -p tsconfig.publish.json && npm run minify","prepare":"npm run build:release"},"keywords":["rbac","authorization","permissions","access-control","security"],"author":{"name":"Anish Prashun","email":"anishprashun118@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/anishpras/rbac.git"},"homepage":"https://github.com/anishpras/rbac#readme","bugs":{"url":"https://github.com/anishpras/rbac/issues"},"engines":{"node":">=14.0.0"},"publishConfig":{"access":"public"},"sideEffects":false,"devDependencies":{"@biomejs/biome":"^1.9.4","@types/jest":"^29.5.5","@types/node":"^20.6.3","jest":"^29.7.0","terser":"^5.39.0","ts-jest":"^29.1.1","typescript":"^5.2.2"},"_id":"@anishpras/rbac@2.1.1","gitHead":"a76f177ea7840a28a35d36c60a5cadb69aa19533","_nodeVersion":"22.12.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-n+5aJdSFIEzCmYsvKhlzDNB8Qt8dd+B7HKavytOvTOHVh+vx/j/eQFxLE9D4ZiTEMtCrSmUaRZwWHNgkh40AlQ==","shasum":"b99594b1cbe4d1b745fde9f154c60c979f12fcc1","tarball":"https://registry.npmjs.org/@anishpras/rbac/-/rbac-2.1.1.tgz","fileCount":27,"unpackedSize":43825,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCHfZF4yThUsVYwy/grT+h/8++WalTBXMdx09t/08BvWQIhAPkMk5B01HpdjKM1CEB0N0H9l596F6/HMPt0lGmOHuzs"}]},"_npmUser":{"name":"anishpras","email":"anishprashun118@gmail.com"},"directories":{},"maintainers":[{"name":"anishpras","email":"anishprashun118@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rbac_2.1.1_1743113312762_0.31840634498826814"},"_hasShrinkwrap":false}},"time":{"created":"2025-03-27T19:09:11.405Z","modified":"2025-03-27T22:08:33.148Z","1.0.0":"2025-03-27T19:09:11.720Z","1.0.1":"2025-03-27T19:57:08.174Z","1.1.0":"2025-03-27T20:25:58.570Z","2.0.0":"2025-03-27T21:00:22.977Z","2.0.1":"2025-03-27T21:50:05.009Z","2.1.0":"2025-03-27T22:02:41.128Z","2.1.1":"2025-03-27T22:08:32.977Z"},"bugs":{"url":"https://github.com/anishpras/rbac/issues"},"author":{"name":"Anish Prashun","email":"anishprashun118@gmail.com"},"license":"MIT","homepage":"https://github.com/anishpras/rbac#readme","keywords":["rbac","authorization","permissions","access-control","security"],"repository":{"type":"git","url":"git+https://github.com/anishpras/rbac.git"},"description":"A fast, flexible, and production-ready role-based access control (RBAC) system for JavaScript/TypeScript applications.","maintainers":[{"name":"anishpras","email":"anishprashun118@gmail.com"}],"readme":"# @anishpras/rbac: Role and Attribute Based Access Control\n\nA fast, flexible, and production-ready role-based access control (RBAC) system for JavaScript/TypeScript applications.\n\n## Features\n\n- 🚀 **Fast and efficient**: Optimized for speed with LRU caching\n- 🔒 **Type-safe**: Full TypeScript support\n- 🧩 **Flexible**: Define custom roles, resources, and permissions\n- 🔄 **Role hierarchy**: Support for role inheritance with robust cycle detection\n- 🛠️ **Middleware support**: Ready for Express.js and other frameworks\n- 📝 **Fluent API**: Intuitive builder pattern for configuration\n- 📊 **Runtime updates**: Modify permissions without restarting\n- 🧪 **Strict mode**: Optional throw on unrecognized roles/resources\n- 📈 **Scalable**: Designed for large-scale applications\n\n## Installation\n\n```bash\nnpm install @anishpras/rbac\n# or\nyarn add @anishpras/rbac\n# or\npnpm add @anishpras/rbac\n```\n\n## Quick Start\n\n```typescript\nimport { RBACManager, RBACBuilder } from '@anishpras/rbac';\n\n// Create a configuration using the builder\nconst config = new RBACBuilder()\n  .role('ADMIN', 'Administrator with full access')\n    .grantFullAccess('Products')\n    .grantFullAccess('News')\n    .grantFullAccess('Bookings')\n    .done()\n  .role('EDITOR', 'Editor with limited access')\n    .forResource('Products').grantAll().and()\n    .forResource('News').grantAll().and()\n    .forResource('Bookings').grantReadOnly().done()\n  .setDefaultRole('EDITOR')\n  .build();\n\n// Create the RBAC manager\nconst rbac = new RBACManager(config, {\n  cache: {\n    enabled: true,\n    maxSize: 1000,\n    ttl: 60 * 1000 // 1 minute\n  },\n  strict: false, // Avoid runtime errors in production\n  logger: {\n    debug: (msg) => console.debug(`[RBAC] ${msg}`),\n    info: (msg) => console.info(`[RBAC] ${msg}`),\n    warn: (msg) => console.warn(`[RBAC] ${msg}`),\n    error: (msg) => console.error(`[RBAC] ${msg}`)\n  }\n});\n\n// Check permissions\nconst user = {\n  id: 1,\n  roles: ['EDITOR']\n};\n\n// Check if a user can create a product\nif (rbac.userCan(user, 'Products', 'CREATE')) {\n  // User can create products\n}\n\n// Check if a user can update a booking\nif (rbac.userCan(user, 'Bookings', 'UPDATE')) {\n  // User cannot update bookings\n}\n```\n\n## Express.js Middleware Example\n\n```typescript\nimport express from 'express';\nimport { RBACManager } from '@anishpras/rbac';\n\nconst app = express();\nconst rbac = new RBACManager(config);\n\n// Middleware to protect routes\napp.get(\n  '/api/products',\n  rbac.middleware({\n    getUserRoles: (req) => req.user.roles,\n    resource: 'Products',\n    permission: 'READ',\n    onDenied: (req, res) => {\n      res.status(403).json({ error: 'Access denied' });\n    }\n  }),\n  (req, res) => {\n    // Handle the request\n  }\n);\n\n// Dynamic permission based on HTTP method\napp.all(\n  '/api/bookings/:id',\n  rbac.middleware({\n    getUserRoles: (req) => req.user.roles,\n    resource: 'Bookings',\n    permission: (req) => {\n      // Map HTTP method to permission\n      switch (req.method) {\n        case 'GET': return 'READ';\n        case 'POST': return 'CREATE';\n        case 'PUT': case 'PATCH': return 'UPDATE';\n        case 'DELETE': return 'DELETE';\n        default: return 'READ';\n      }\n    },\n    onDenied: (req, res) => {\n      res.status(403).json({ \n        error: 'Access denied',\n        message: `You don't have permission to ${req.method} bookings` \n      });\n    }\n  }),\n  (req, res) => {\n    // Handle the request\n  }\n);\n```\n\n## Understanding Role Hierarchy (Role Inheritance)\n\nThe role hierarchy feature allows roles to inherit permissions from other roles. This is one of the most powerful but sometimes confusing aspects of the library.\n\n```typescript\n// Define role hierarchy\nrbac.setRoleHierarchy({\n  'EDITOR': ['ADMIN'],  // EDITOR inherits all permissions from ADMIN\n  'VIEWER': ['EDITOR']  // VIEWER inherits all permissions from EDITOR\n});\n```\n\n**Important Clarification on Role Hierarchy**: \n\nIn the role hierarchy configuration:\n- The `key` is the **child role** (the one inheriting permissions)\n- The `array values` are the **parent roles** (the ones being inherited from)\n\nThis means:\n- `'EDITOR': ['ADMIN']` means that EDITOR inherits permissions from ADMIN, not the other way around\n- `'VIEWER': ['EDITOR']` means VIEWER inherits from EDITOR (and transitively from ADMIN too)\n\nThink of it like this:\n```\n'CHILD_ROLE': ['PARENT_ROLE_1', 'PARENT_ROLE_2']\n```\n\nLet's look at a more complete example to illustrate how role hierarchy works:\n\n```typescript\n// Define role hierarchy with more complex relationships\nrbac.setRoleHierarchy({\n  // Store roles inherit from more general roles\n  'STORE_MANAGER': ['ADMIN'],      // Store Manager inherits from Admin\n  'STORE_CLERK': ['STORE_MANAGER'], // Store Clerk inherits from Store Manager\n  \n  // Content roles also inherit\n  'CONTENT_EDITOR': ['ADMIN'],     // Content Editor inherits from Admin\n  'CONTENT_VIEWER': ['CONTENT_EDITOR'], // Content Viewer inherits from Content Editor\n  \n  // Special case: dual inheritance\n  'SUPERVISOR': ['STORE_MANAGER', 'CONTENT_EDITOR'] // Inherits from both roles\n});\n\n// Let's test some permissions\nconsole.log(rbac.can('STORE_CLERK', 'Products', 'READ')); // true if STORE_MANAGER has this permission\nconsole.log(rbac.can('SUPERVISOR', 'Content', 'PUBLISH')); // true if either parent role has this permission\n```\n\nThe library automatically handles transitive inheritance and detects circular references to prevent infinite loops.\n\n## Dynamic Permission Updates\n\nYou can modify permissions at runtime without restarting your application:\n\n```typescript\n// Add a new role\nrbac.addRole('MANAGER', {\n  description: 'Manager role',\n  permissions: {\n    'Products': ['READ', 'UPDATE'],\n    'Bookings': ['READ', 'UPDATE', 'CREATE']\n  }\n});\n\n// Grant new permissions\nrbac.grant('EDITOR', 'Reports', ['READ']);\n\n// Revoke permissions\nrbac.revoke('EDITOR', 'Bookings', ['DELETE']);\n\n// Revoke all permissions on a resource\nrbac.revoke('EDITOR', 'Bookings');\n\n// Remove a role entirely\nrbac.removeRole('GUEST');\n\n// Update the entire configuration\nrbac.updateConfig(newConfig);\n```\n\nRemember to clear the cache after making permission changes (the built-in methods like `grant()` and `revoke()` handle this automatically):\n\n```typescript\n// Manually clear the cache when needed\nrbac.clearCache();\n```\n\n## Policy Evaluation\n\nYou can evaluate policies directly:\n\n```typescript\nconst policyResult = rbac.evaluatePolicy({\n  role: 'EDITOR',\n  resource: 'Products',\n  permission: 'UPDATE'\n});\n\nconsole.log(policyResult.allowed); // boolean\nconsole.log(policyResult.reason);  // explanation string\n```\n\n## Query Available Permissions and Resources\n\n```typescript\n// Get all permissions a role has on a resource\nconst permissions = rbac.getPermissions('EDITOR', 'Products');\n// Returns: ['CREATE', 'READ', 'UPDATE', 'DELETE']\n\n// Get all resources a role has access to\nconst resources = rbac.getResources('ADMIN');\n// Returns: ['Products', 'News', 'Bookings', ...]\n\n// Get all roles in the system\nconst roles = rbac.getRoles();\n// Returns: ['ADMIN', 'EDITOR', 'VIEWER', ...]\n\n// Get cache statistics\nconst cacheStats = rbac.getCacheStats();\n// Returns: { enabled: true, size: 42 }\n```\n\n## Best Practices\n\n### 1. Use Constants for Roles, Resources and Permissions\n\nDefine constants to prevent typos and ensure consistency:\n\n```typescript\n// Define constants\nconst ROLES = {\n  ADMIN: 'ADMIN',\n  EDITOR: 'EDITOR',\n  VIEWER: 'VIEWER'\n} as const;\n\nconst RESOURCES = {\n  PRODUCTS: 'Products',\n  USERS: 'Users',\n  ORDERS: 'Orders'\n} as const;\n\nconst PERMISSIONS = {\n  CREATE: 'CREATE',\n  READ: 'READ',\n  UPDATE: 'UPDATE',\n  DELETE: 'DELETE'\n} as const;\n\n// Use constants in your code\nrbac.grant(ROLES.EDITOR, RESOURCES.PRODUCTS, [PERMISSIONS.READ, PERMISSIONS.UPDATE]);\n```\n\n### 2. Non-strict Mode in Production\n\nSet `strict: false` in production to prevent throwing errors for undefined roles or resources. This prevents service disruptions if a role is referenced that doesn't exist.\n\n```typescript\nconst rbac = new RBACManager(config, {\n  strict: process.env.NODE_ENV === 'development'\n});\n```\n\n### 3. Enable Caching\n\nAlways use caching in production for better performance:\n\n```typescript\nconst rbac = new RBACManager(config, {\n  cache: {\n    enabled: true,\n    maxSize: 1000, // Limit cache size to prevent memory issues\n    ttl: 5 * 60 * 1000 // Cache TTL of 5 minutes\n  }\n});\n```\n\n### 4. Properly Set Up Role Hierarchy\n\nRemember that in the hierarchy object:\n- The key is the child role (the one inheriting permissions)  \n- The array values are parent roles (the ones being inherited from)\n\n```typescript\n// CORRECT:\nrbac.setRoleHierarchy({\n  'EDITOR': ['ADMIN'], // EDITOR inherits from ADMIN\n});\n\n// INCORRECT (would mean ADMIN inherits from EDITOR):\nrbac.setRoleHierarchy({\n  'ADMIN': ['EDITOR']\n});\n```\n\n### 5. Use Custom Logger\n\nConfigure a custom logger to integrate with your application's logging system:\n\n```typescript\nconst rbac = new RBACManager(config, {\n  logger: {\n    debug: (msg) => myLogger.debug(`[RBAC] ${msg}`),\n    info: (msg) => myLogger.info(`[RBAC] ${msg}`),\n    warn: (msg) => myLogger.warn(`[RBAC] ${msg}`),\n    error: (msg) => myLogger.error(`[RBAC] ${msg}`)\n  }\n});\n```\n\n### 6. Implement Resource Ownership\n\nFor multi-tenant systems, combine RBAC with resource ownership checks:\n\n```typescript\n// Middleware to check both permissions and ownership\nconst checkPermissionAndOwnership = (req, res, next) => {\n  const resourceId = req.params.id;\n  const userId = req.user.id;\n  \n  // First check RBAC permissions\n  if (!rbac.userCan(req.user, 'Orders', 'UPDATE')) {\n    return res.status(403).json({ error: 'Permission denied' });\n  }\n  \n  // Then check ownership\n  orderService.getOrderById(resourceId)\n    .then(order => {\n      if (order.userId !== userId) {\n        return res.status(403).json({ error: 'Not your order' });\n      }\n      next();\n    });\n};\n```\n\n## Security Features\n\nThis package includes security-focused features to protect your application's permission system:\n\n1. **Input Validation**: All role, resource, and permission inputs are validated to prevent injection attacks and manipulation.\n\n2. **Circular Reference Detection**: Automatic detection and prevention of circular references in role hierarchies.\n\n3. **Default Deny**: The system always defaults to denying access when errors occur or when roles/permissions are undefined.\n\n4. **Deep Cloning**: All configuration objects are deep-cloned to prevent external mutation attacks.\n\n5. **Protected Cache Keys**: The caching system uses sanitized keys to prevent cache poisoning.\n\n6. **Secure Middleware**: The Express middleware is designed to securely handle errors and always default to access denial.\n\n7. **Audit Logging**: Built-in audit logging for critical permission changes and access attempts.\n\n8. **Type Safety**: TypeScript types enforce proper structure and prevent common mistakes.\n\n9. **Race Condition Protection**: Special handling to prevent race conditions during permission updates.\n\n10. **Secure Error Handling**: Error messages are designed to avoid leaking sensitive information.\n\n## Advanced Examples\n\nFor more advanced usage examples, check the `examples` directory in the repository:\n\n- `product-shop.ts`: Basic e-commerce example with standard roles\n- `express-integration.ts`: Example integration with Express.js middleware\n- `advanced-example.ts`: Complex role hierarchy with comprehensive permissions\n\n## API Reference\n\n### RBACManager\n\nThe main class for managing RBAC functionality.\n\n```typescript\n// Create a new instance\nconst rbac = new RBACManager(config, options);\n\n// Check if a role has permission\nrbac.can(role, resource, permission);\n\n// Check if a user has permission\nrbac.userCan(user, resource, permission);\n\n// Set role hierarchy\nrbac.setRoleHierarchy(hierarchy);\n\n// Update configuration\nrbac.updateConfig(config);\n\n// Add a new role\nrbac.addRole(role, definition);\n\n// Remove a role\nrbac.removeRole(role);\n\n// Grant permissions\nrbac.grant(role, resource, permission);\n\n// Revoke permissions\nrbac.revoke(role, resource, permission);\n\n// Evaluate a policy\nrbac.evaluatePolicy(policy);\n\n// Get permissions for a role on a resource\nrbac.getPermissions(role, resource);\n\n// Get all resources a role has access to\nrbac.getResources(role);\n\n// Get all roles\nrbac.getRoles();\n\n// Get the complete configuration\nrbac.getConfig();\n\n// Clear the permission cache\nrbac.clearCache();\n\n// Get cache statistics\nrbac.getCacheStats();\n\n// Create middleware\nrbac.middleware(options);\n```\n\n### RBACBuilder\n\nA fluent API for building RBAC configurations.\n\n```typescript\n// Create a new builder\nconst builder = new RBACBuilder();\n\n// Define roles and permissions\nbuilder\n  .role('ADMIN')\n    .grantFullAccess('Products')\n    .done()\n  .role('EDITOR')\n    .forResource('Products').grant('READ', 'UPDATE').and()\n    .forResource('News').grantAll().done()\n  .setDefaultRole('EDITOR');\n\n// Build the configuration\nconst config = builder.build();\n```\n\n## Build and Development\n\n### Building the Project\n\nThis project provides both development and production build options:\n\n```bash\n# Development build (with source maps and comments)\nnpm run build\n\n# Production build (minified with source maps)\nnpm run build:prod\n```\n\n### Minification\n\nThe production build automatically minifies the JavaScript output using Terser with the following optimizations:\n\n- Code compression (removing whitespace, shortening variable names)\n- Dead code elimination\n- Mangling of variable names for smaller file size\n- Preservation of license/copyright comments\n- Sourcemap generation for debugging\n\nThis results in significantly smaller file sizes while maintaining full functionality.\n\n## License\n\nMIT","readmeFilename":"README.md"}