{"_id":"accesscontrol","_rev":"29-3772747f5b429ad8b23d130a7d6ab77f","name":"accesscontrol","dist-tags":{"latest":"3.1.0"},"versions":{"1.0.0":{"name":"accesscontrol","version":"1.0.0","keywords":["access","access-control","role","attribute","grant","deny","allow","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@1.0.0","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"03625fdc2ef05d1bcbce9ce62305651ae0e732ca","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-1.0.0.tgz","integrity":"sha512-9jbcqzgOQ8SergpIPiIxfpC6SCh9++2sUBnbLApO7c7N5A0ZFCneJN/G4JBPkoKNmpCWRf1AldZ7MocKJrZrJA==","signatures":[{"sig":"MEUCIAqZZlUK9BhupjhlzeDyi5naYijr8xc/NSqNjjz3yWshAiEA1g5qqAg+oybYd3yV+yb7WwJpYpgkGSWR3Pfw5ta0iAI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"03625fdc2ef05d1bcbce9ce62305651ae0e732ca","gitHead":"b75c39fa581238bad293e8f3cbc6d4ddb680aac1","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"3.10.5","description":"Role and Attribute based Access Control for Node.js","directories":{"test":"test"},"_nodeVersion":"4.4.7","dependencies":{"notation":"^1.0.0"},"devDependencies":{"babel":"^6.5.2","grunt":"^1.0.1","eslint":"^3.5.0","matchdep":"^1.0.1","grunt-babel":"^6.0.0","grunt-docma":"^0.6.4","eslint-config-xo":"^0.15.4","babel-preset-es2015":"^6.14.0","grunt-contrib-clean":"^1.0.0","grunt-jasmine-nodejs":"^1.5.4"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol-1.0.0.tgz_1473785938801_0.6612245915457606","host":"packages-16-east.internal.npmjs.com"}},"1.0.1":{"name":"accesscontrol","version":"1.0.1","keywords":["access","access-control","role","attribute","grant","deny","allow","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@1.0.1","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"c8e284752908c8786765ff5b8d4eff274761ccfe","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-1.0.1.tgz","integrity":"sha512-EL7v9GkCDhmvciqWogwVZWAAQvfVyBcmMvec7sU3/XAmEgKj3dIKnhO9e5cePTHsg/kRQZ2VbsrqXeiF9CzmNA==","signatures":[{"sig":"MEYCIQDUGroKVqFFNXHUUkZ+c87W5fduF7+t8T6/ZHdMtBS+jQIhAPlCpdVbsKelwkVq3D8R2A241pikihHO5T7CqWTwB0gm","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js","build","LICENSE"],"_shasum":"c8e284752908c8786765ff5b8d4eff274761ccfe","gitHead":"31c88107901717b5ebc99602b2a1208b2b22095d","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"3.10.3","description":"Role and Attribute based Access Control for Node.js","directories":{"test":"test"},"_nodeVersion":"4.5.0","dependencies":{"notation":"^1.0.0"},"devDependencies":{"babel":"^6.5.2","grunt":"^1.0.1","eslint":"^3.5.0","matchdep":"^1.0.1","grunt-babel":"^6.0.0","grunt-docma":"^0.6.4","eslint-config-xo":"^0.15.4","babel-preset-es2015":"^6.14.0","grunt-contrib-clean":"^1.0.0","grunt-jasmine-nodejs":"^1.5.4"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol-1.0.1.tgz_1478652509337_0.2524778749793768","host":"packages-12-west.internal.npmjs.com"}},"1.5.0":{"name":"accesscontrol","version":"1.5.0","keywords":["access","access-control","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@1.5.0","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"d698acb9cfe595b1a8e0365bc6521eb3c40ac53d","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-1.5.0.tgz","integrity":"sha512-jb0tAeIm/q0uxW+Srj4ugsA0h85WjtQZ3RgQOKfsmA9JlC0O+8w0Ej9155QtbeoGX4h+n2jjrMN+ueb5rozZOA==","signatures":[{"sig":"MEUCIQCwIGcWTY/oln04vWu5DziNvLTvJI3+SxmX4LcSouy+RgIgAyv+ZzcKGLEehUyoS8H80rZGF0lNOABqOz2f0F7sH+8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["index.js","lib","LICENSE"],"types":"lib/AccessControl","_shasum":"d698acb9cfe595b1a8e0365bc6521eb3c40ac53d","gitHead":"a430ed200ac4afe9b16179692c2b7127bed79dcc","scripts":{"docs":"tsc && docma -c ./docma.config.json","test":"npm run build && node test","build":"npm run clean && mkdirp ./lib && tsc","clean":"rimraf ./lib"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"4.3.0","description":"Role and Attribute based Access Control for Node.js","directories":{"lib":"./lib","test":"./test"},"_nodeVersion":"6.9.2","dependencies":{"notation":"^1.0.0"},"devDependencies":{"ncp":"^2.0.0","docma":"^1.4.7","mkdirp":"^0.5.1","rimraf":"^2.6.1","jasmine":"^2.5.3","typescript":"^2.2.1","@types/node":"^7.0.5","jasmine-console-reporter":"^1.2.7"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol-1.5.0.tgz_1489203718773_0.1146268795710057","host":"packages-18-east.internal.npmjs.com"}},"1.5.1":{"name":"accesscontrol","version":"1.5.1","keywords":["access","access-control","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@1.5.1","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"7e1ea849a35d82d44600592fc40bf5a38de4eaa7","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-1.5.1.tgz","integrity":"sha512-Vz3uacQEiIwRbkQepzg1GYx+5BtnHbYY1nt6IE8xopa3sN96btpvnQPbIt8yezWOWkg07v+X5I902Xt6DOrmqQ==","signatures":[{"sig":"MEUCIHpbKlFWqCq6+WK+b594uvptZatYfazydfbWu7nit3zuAiEA/faBeoIu5OgFbuGORJHq3F6aRFtv8/Wcno2pqykwTf0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"./index.js","_from":".","files":["index.js","lib","LICENSE"],"types":"./lib/index.d.ts","_shasum":"7e1ea849a35d82d44600592fc40bf5a38de4eaa7","gitHead":"ae395dd8bc1b3c654f68d603cc8b04aa10328554","scripts":{"docs":"docma -c ./docma.config.json","test":"npm run build && node test","build":"npm run clean && mkdirp ./lib && tsc","clean":"rimraf ./lib"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"4.6.1","description":"Role and Attribute based Access Control for Node.js","directories":{"lib":"./lib","test":"./test"},"_nodeVersion":"6.9.2","dependencies":{"notation":"^1.0.0"},"devDependencies":{"ncp":"^2.0.0","docma":"^1.5.1","mkdirp":"^0.5.1","rimraf":"^2.6.1","jasmine":"^2.6.0","typescript":"^2.3.3","@types/node":"^7.0.22","jasmine-console-reporter":"^1.2.7"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol-1.5.1.tgz_1495591745869_0.7516126378905028","host":"s3://npm-registry-packages"}},"1.5.2":{"name":"accesscontrol","version":"1.5.2","keywords":["access","access-control","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@1.5.2","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"e03e42bd9ceadfaa2fcef51c50fc18f9bb3b0a48","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-1.5.2.tgz","integrity":"sha512-2/dWmmMkosk6rF6QMBUjs0FdZcdyyVr3o69pT+KF+3CATo0gQtqpSjwIIaWSAMcJojN5jXnyNeGXInESlT0iqw==","signatures":[{"sig":"MEUCIQCqlW83Tqzf8klDmdjYuPnL6HtQa7Ht/BcCs7K+K9FYFwIgY3HSctbtjdKyEX3kJxxv89KnK1x/KQMYEo34UEUUSY0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"./index.js","_from":".","files":["index.js","lib","LICENSE"],"types":"./lib/index.d.ts","_shasum":"e03e42bd9ceadfaa2fcef51c50fc18f9bb3b0a48","gitHead":"15bee52d32711880004ee5fe4511c40ecefe8b9a","scripts":{"docs":"docma -c ./docma.config.json","test":"npm run build && node test","build":"npm run clean && mkdirp ./lib && tsc","clean":"rimraf ./lib"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"4.6.1","description":"Role and Attribute based Access Control for Node.js","directories":{"lib":"./lib","test":"./test"},"_nodeVersion":"6.9.2","dependencies":{"notation":"^1.0.0"},"devDependencies":{"ncp":"^2.0.0","docma":"^1.5.1","mkdirp":"^0.5.1","rimraf":"^2.6.1","jasmine":"^2.6.0","typescript":"^2.3.3","@types/node":"^8.0.7","jasmine-console-reporter":"^1.2.7"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol-1.5.2.tgz_1499015103443_0.2870355169288814","host":"s3://npm-registry-packages"}},"1.5.3":{"name":"accesscontrol","version":"1.5.3","keywords":["access","access-control","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@1.5.3","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"195bc7c2fcd71aec2edcea84b24fd05240939edc","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-1.5.3.tgz","integrity":"sha512-5KLgafxYFcZGxhuvIoEOApLtpgJW83v2N2L0mWX5pHPSCXTrxqX4NEPH4NGGJfOsWTgWObjZTPlvsMHydkkzUQ==","signatures":[{"sig":"MEUCIGjVAitVu3AaNVZ2W1dj8UkotSiuHYycuq8dNnqnBkBGAiEAqJq1IV/zrntbE4YlMOZHkDXhopvA8VRFQQQEJ7mNdJ8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"./index.js","files":["index.js","lib","LICENSE"],"types":"./lib/index.d.ts","gitHead":"c2a75bf5de02fa40a5a4723e5266f8a51169f149","scripts":{"docs":"docma -c ./docma.config.json","test":"npm run build && node test","build":"npm run clean && mkdirp ./lib && tsc","clean":"rimraf ./lib"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"5.3.0","description":"Role and Attribute based Access Control for Node.js","directories":{"lib":"./lib","test":"./test"},"_nodeVersion":"6.11.2","dependencies":{"notation":"^1.0.0"},"devDependencies":{"ncp":"^2.0.0","docma":"^1.5.1","mkdirp":"^0.5.1","rimraf":"^2.6.1","jasmine":"^2.7.0","typescript":"^2.4.2","@types/node":"^8.0.24","jasmine-console-reporter":"^1.2.7"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol-1.5.3.tgz_1503624882649_0.8158761507365853","host":"s3://npm-registry-packages"}},"1.5.4":{"name":"accesscontrol","version":"1.5.4","keywords":["access","access-control","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@1.5.4","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"bbd272c92e911ded6bfc61cc3bb18994cfd94435","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-1.5.4.tgz","integrity":"sha512-hGXXl/sQZ0E++ffWfl0PS/VkhGLTUSEKpK7Rvdbj5grWlO4Apk1tLifVzVyw2aSAuj/s0kUPmL1kro6/eQwXcQ==","signatures":[{"sig":"MEUCIBubjg/FHw2TgoSPvwZ+qgPcWABKv7o/fVMFBzh1Xs1jAiEAwhkmKg1VcQovMDg6DwXhhtlFbm39qwYNU3twFW1xb2w=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"./index.js","files":["index.js","lib","LICENSE"],"types":"./lib/index.d.ts","gitHead":"5bbdecd48ba43f3695ce9fba04dbc4b50e30a8cf","scripts":{"docs":"docma -c ./docma.config.json","test":"npm run build && node test","build":"npm run clean && mkdirp ./lib && tsc","clean":"rimraf ./lib"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"5.4.1","description":"Role and Attribute based Access Control for Node.js","directories":{"lib":"./lib","test":"./test"},"_nodeVersion":"6.11.2","dependencies":{"notation":"^1.0.0"},"devDependencies":{"ncp":"^2.0.0","docma":"^1.5.1","mkdirp":"^0.5.1","rimraf":"^2.6.1","jasmine":"^2.7.0","typescript":"^2.4.2","@types/node":"^8.0.24","jasmine-console-reporter":"^1.2.7"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol-1.5.4.tgz_1506027769079_0.9851010455749929","host":"s3://npm-registry-packages"}},"2.0.0":{"name":"accesscontrol","version":"2.0.0","keywords":["access","access-control","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@2.0.0","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"d1b44c6f06f6fab2814e997e636bddac78484731","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-2.0.0.tgz","integrity":"sha512-qU09OrIAiTB2l85xjTsUbI1AIap0j4rtalx7hRiahUfC+uyd7FwvLeDD2d/sZA5xEgCswHAHCi1icVBHvTOeHQ==","signatures":[{"sig":"MEUCIBTtJYBEBFNKHxbl6EzQ7LjFI5J8ZTrw9JJE+49vrD28AiEAx58ol3Xbs8FxAHLOt4j6tfVC5AvEYbiTk2D0tImvK6o=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"./index.js","files":["index.js","lib","LICENSE"],"types":"./lib/index.d.ts","gitHead":"29685fc4985a76c119feba63e146908f69c440f6","scripts":{"docs":"docma -c ./docma.config.json","test":"npm run build && node test","build":"npm run clean && mkdirp ./lib && tsc","clean":"rimraf ./lib"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"5.4.2","description":"Role and Attribute based Access Control for Node.js","directories":{"lib":"./lib","test":"./test"},"_nodeVersion":"6.11.2","dependencies":{"notation":"^1.3.5"},"devDependencies":{"ncp":"^2.0.0","docma":"^1.5.1","mkdirp":"^0.5.1","rimraf":"^2.6.2","jasmine":"^2.8.0","typescript":"^2.5.3","@types/node":"^8.0.32","jasmine-console-reporter":"^2.0.1"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol-2.0.0.tgz_1507220471380_0.9229102991521358","host":"s3://npm-registry-packages"}},"2.2.0":{"name":"accesscontrol","version":"2.2.0","keywords":["access","access-control","acl","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user","glob","wildcard","policy","scope","context"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@2.2.0","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"b84b657464547e61889ee1a9c848d34662f4e5fd","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-2.2.0.tgz","integrity":"sha512-Y8nOMrIkATF3Cn8Bjbi/2foCqX26RSS3sAf7mBxpY4Iz7TTO3tOefdphoL18naP5JDSs8mq7aO2X1bzNEbzsTw==","signatures":[{"sig":"MEQCIFx3kHBa5WzNA3LkVBFh4SFUVzP2q2LfSD4We//t4Y1FAiA43z99Pm2mcGfGUqaZCBnauznIKrRs6xxJRvGLzJzjTg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"jest":{"roots":["<rootDir>/src","<rootDir>/lib","<rootDir>/test"],"testMatch":["**/test/(*.)?(spec|test).ts"],"transform":{"^.+\\.tsx?$":"<rootDir>/node_modules/ts-jest/preprocessor.js"},"mapCoverage":true,"testEnvironment":"node","coverageDirectory":"./test/.coverage","collectCoverageFrom":["src/**/*.ts","!src/index.ts","!**/IAccessInfo.ts","!**/IQueryInfo.ts"],"moduleFileExtensions":["ts","tsx","js","json"],"testPathIgnorePatterns":["/backup/","/.coverage/"]},"main":"./index.js","files":["index.js","lib","LICENSE"],"types":"./lib/index.d.ts","scripts":{"deps":"yarn upgrade-interactive && snyk test","docs":"docma -c ./docma.config.json","test":"yarn run build && jest --verbose --no-cache","vuls":"snyk test","build":"yarn run clean && mkdirp ./lib && tsc","clean":"rimraf ./lib","cover":"yarn run build && jest --coverage --verbose --no-cache","test!":"yarn jest --verbose --no-cache","cover!":"yarn jest --coverage --verbose --no-cache","report":"open ./test/.coverage/lcov-report/index.html","coveralls":"cat ./test/.coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js -v"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"description":"Role and Attribute based Access Control for Node.js","directories":{},"licenseText":"The MIT License\n\nCopyright (c) 2017, Onur Yıldırım <onur@cutepilot.com>. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","dependencies":{"notation":"^1.3.5"},"devDependencies":{"ncp":"^2.0.0","snyk":"^1.49.4","docma":"^1.5.1","mkdirp":"^0.5.1","rimraf":"^2.6.2","ts-jest":"^21.2.3","jest-cli":"^21.2.1","coveralls":"^3.0.0","typescript":"^2.5.3","@types/jest":"^21.1.6","@types/node":"^8.0.32"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol-2.2.0.tgz_1511666771455_0.8357167006470263","host":"s3://npm-registry-packages"}},"2.2.1":{"name":"accesscontrol","version":"2.2.1","keywords":["access","access-control","acl","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user","glob","wildcard","policy","scope","context"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@2.2.1","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://github.com/onury/accesscontrol#readme","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"c942c48e330841c619682309a8c3aeec6bec66eb","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-2.2.1.tgz","fileCount":31,"integrity":"sha512-52EvFk/J9EF+w4mYQoKnOTkEMj01R1U5n2fc1dai6x1xkgOks3DGkx01qQL2cKFxGmE4Tn1krAU3jJA9L1NMkg==","signatures":[{"sig":"MEUCIEDGTtZMFC+YiIhEQX2GoG4V8y+EQXcp9VuTdYIFCOlDAiEAsBlLCAJwqyXHIuWDCaWZNc0pE3zbQarCP3AOSI4xOrQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":183980},"jest":{"roots":["<rootDir>/src","<rootDir>/lib","<rootDir>/test"],"testMatch":["**/test/(*.)?(spec|test).ts"],"transform":{"^.+\\.tsx?$":"<rootDir>/node_modules/ts-jest/preprocessor.js"},"testEnvironment":"node","coverageDirectory":"./test/.coverage","collectCoverageFrom":["src/**/*.ts","!src/index.ts","!**/IAccessInfo.ts","!**/IQueryInfo.ts"],"moduleFileExtensions":["ts","tsx","js","json"],"testPathIgnorePatterns":["/backup/","/.coverage/"]},"main":"./index.js","files":["index.js","lib","LICENSE"],"types":"./lib/index.d.ts","gitHead":"c239e1789b4640999cf13b0c1d80b0ff9ad50f48","scripts":{"deps":"npm-check -u && snyk test","docs":"docma -c ./docma.config.json","test":"npm run build && jest --verbose --no-cache","vuls":"snyk test","build":"npm run clean && mkdirp ./lib && tsc","clean":"rimraf ./lib","cover":"npm run build && jest --coverage --verbose --no-cache","test!":"jest --verbose --no-cache","cover!":"jest --coverage --verbose --no-cache","report":"open ./test/.coverage/lcov-report/index.html","coveralls":"cat ./test/.coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js -v"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"5.6.0","description":"Role and Attribute based Access Control for Node.js","directories":{"lib":"./lib","test":"./test"},"_nodeVersion":"8.9.3","dependencies":{"notation":"^1.3.6"},"_hasShrinkwrap":false,"devDependencies":{"ncp":"^2.0.0","snyk":"^1.69.9","docma":"^1.5.3","mkdirp":"^0.5.1","rimraf":"^2.6.2","ts-jest":"^22.0.4","jest-cli":"^22.4.2","coveralls":"^3.0.0","typescript":"^2.7.2","@types/jest":"^22.1.3","@types/node":"^9.4.6"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol_2.2.1_1519443556285_0.46634307065534997","host":"s3://npm-registry-packages"}},"3.0.0":{"name":"accesscontrol","version":"3.0.0","keywords":["access","access-control","acl","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user","glob","wildcard","policy","scope","context"],"author":{"name":"Onur Yildirim","email":"onur@cutepilot.com"},"license":"MIT","_id":"accesscontrol@3.0.0","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"homepage":"https://onury.io/accesscontrol","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"dist":{"shasum":"1b9a6e9e5a74693e35d63a7c97dd2350668fd036","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-3.0.0.tgz","fileCount":135,"integrity":"sha512-lmHyLBKJtPAr2hrvgAKPA6d0FpRAvFMA2jLRBzJk49/H4jmhu3hx9o2Rfcv5bNkr5UbENX7h+VWFx/b3B3uT5w==","signatures":[{"sig":"MEUCIA3Qyc48Q5YTTf5UZtVAjsnL2fuMYHNNKMRFRzzLYhoBAiEAv2w0l3fCKcSIGi65CMV1JNWX7yMa0v9QJLgg7KviL08=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":465408},"main":"./lib/index.js","type":"module","types":"./lib/index.d.ts","module":"./lib/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./lib/index.d.ts","import":"./lib/index.js","default":"./lib/index.js"},"./package.json":"./package.json"},"gitHead":"260e67d3b4a4bc5e78f98481ae6550713c0507ef","scripts":{"docs":"npm --prefix site run build","lint":"biome check src test","test":"vitest run","build":"tsc --project tsconfig.build.json","cover":"vitest run --coverage","format":"biome check --write src test","pretest":"npm run lint && npm run typecheck","docs:dev":"npm --prefix site run dev","mutation":"stryker run","docs:host":"npm --prefix site run dev:host","typecheck":"tsc --noEmit --project tsconfig.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"overrides":{"qs":"^6.15.2","jsdom":"^26"},"repository":{"url":"git+https://github.com/onury/accesscontrol.git","type":"git"},"_npmVersion":"10.9.8","description":"Role and Attribute based Access Control for Node.js","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"notation":"3.0.1"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^25.9.3","tsconfig-oy":"^2.0.0","@biomejs/biome":"^2.5.0","biome-config-oy":"^1.0.0","@stryker-mutator/core":"^9.6.1","@vitest/coverage-istanbul":"^4.1.8","@stryker-mutator/vitest-runner":"^9.6.1"},"_npmOperationalInternal":{"tmp":"tmp/accesscontrol_3.0.0_1782265114056_0.8214870328249169","host":"s3://npm-registry-packages-npm-production"}},"3.1.0":{"name":"accesscontrol","version":"3.1.0","description":"Role and Attribute based Access Control for Node.js","homepage":"https://onury.io/accesscontrol","author":{"name":"Onur Yıldırım","email":"onur@cutepilot.com"},"license":"MIT","bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"repository":{"type":"git","url":"git+https://github.com/onury/accesscontrol.git"},"type":"module","main":"./lib/index.js","module":"./lib/index.js","types":"./lib/index.d.ts","exports":{".":{"types":"./lib/index.d.ts","import":"./lib/index.js","default":"./lib/index.js"},"./package.json":"./package.json"},"sideEffects":false,"engines":{"node":">=20"},"scripts":{"lint":"biome check src test","format":"biome check --write src test","build":"tsc --project tsconfig.build.json","typecheck":"tsc --noEmit --project tsconfig.json","pretest":"npm run lint && npm run typecheck","test":"vitest run","cover":"vitest run --coverage","mutation":"stryker run","docs":"npm --prefix site run build","docs:dev":"npm --prefix site run dev","docs:host":"npm --prefix site run dev:host","prepublishOnly":"npm run build"},"keywords":["access","access-control","acl","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user","glob","wildcard","policy","scope","context"],"dependencies":{"dtrexp":"1.0.1","notation":"3.0.1"},"overrides":{"jsdom":"^26","qs":"^6.15.2"},"devDependencies":{"@biomejs/biome":"^2.5.0","@stryker-mutator/core":"^9.6.1","@stryker-mutator/vitest-runner":"^9.6.1","@types/node":"^25.9.3","@vitest/coverage-istanbul":"^4.1.8","biome-config-oy":"^1.0.0","tsconfig-oy":"^2.0.0","typescript":"^6.0.3","vitest":"^4.1.8"},"gitHead":"43b250ab258dff1c4b2a50536b5e2751c21aacc9","_id":"accesscontrol@3.1.0","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-uZwa8MnKhNec8tauCeZHaQVISLblXNlPZxKMGsp/fpol6iqp6ChSiU4oXqmSauy+Z4EwUayuPGLaVk0ynT3lXA==","shasum":"285ac1feb614c0807f7bbd34f7c8d45736705785","tarball":"https://registry.npmjs.org/accesscontrol/-/accesscontrol-3.1.0.tgz","fileCount":135,"unpackedSize":491401,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDe3/37gCd+F+Vg2bPedAPPimoGWZhwZs7w0Gf19nj4KQIhAPk7VUew2/NA4upQ3RevuQxglrOqrRNZ2+aJ+wrE5Dwg"}]},"_npmUser":{"name":"onury","email":"onur@cutepilot.com"},"directories":{},"maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/accesscontrol_3.1.0_1784179289713_0.4363510797136603"},"_hasShrinkwrap":false}},"time":{"created":"2016-09-13T16:59:01.040Z","modified":"2026-07-16T05:21:30.022Z","1.0.0":"2016-09-13T16:59:01.040Z","1.0.1":"2016-11-09T00:48:31.313Z","1.5.0":"2017-03-11T03:41:59.502Z","1.5.1":"2017-05-24T02:09:07.150Z","1.5.2":"2017-07-02T17:05:04.573Z","1.5.3":"2017-08-25T01:34:43.773Z","1.5.4":"2017-09-21T21:02:50.208Z","2.0.0":"2017-10-05T16:21:12.601Z","2.2.0":"2017-11-26T03:26:12.486Z","2.2.1":"2018-02-24T03:39:16.387Z","3.0.0":"2026-06-24T01:38:34.240Z","3.1.0":"2026-07-16T05:21:29.866Z"},"bugs":{"url":"https://github.com/onury/accesscontrol/issues"},"author":{"name":"Onur Yıldırım","email":"onur@cutepilot.com"},"license":"MIT","homepage":"https://onury.io/accesscontrol","keywords":["access","access-control","acl","role","attribute","grant","deny","allow","reject","permission","action","possession","rbac","abac","crud","create","read","update","delete","resource","express","admin","user","glob","wildcard","policy","scope","context"],"repository":{"type":"git","url":"git+https://github.com/onury/accesscontrol.git"},"description":"Role and Attribute based Access Control for Node.js","maintainers":[{"name":"onury","email":"onur@cutepilot.com"}],"readme":"<p align=\"center\">\n    <a href=\"https://onury.io/accesscontrol\"><img src=\"https://raw.githubusercontent.com/onury/accesscontrol/master/ac-caution.svg\" alt=\"AccessControl.js\" width=\"100%\" /></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/onury/accesscontrol/actions/workflows/ci.yml\"><img src=\"https://github.com/onury/accesscontrol/actions/workflows/ci.yml/badge.svg\" alt=\"build\" /></a>\n  <a href=\"#security--quality\"><img src=\"https://img.shields.io/badge/coverage-100%25-2BB150?logo=vitest&logoColor=%23FDC72B&style=flat\" alt=\"coverage\" /></a>\n  <a href=\"https://stryker-mutator.io/docs/\"><img src=\"https://img.shields.io/badge/mutation-88%25-2BB150?style=flat\" alt=\"mutation score\" /></a>\n  <a href=\"https://www.npmjs.com/package/accesscontrol\"><img src=\"https://img.shields.io/npm/v/accesscontrol.svg?style=flat&label=&color=%23C6234B&logo=npm\" alt=\"version\" /></a>\n  <a href=\"https://www.npmjs.com/package/accesscontrol\"><img src=\"https://img.shields.io/npm/dt/accesscontrol.svg?style=flat&color=2BB150\" alt=\"downloads\" /></a>\n  <a href=\"https://gist.github.com/onury/d3f3d765d7db2e8b2d050d14315f2ac7\"><img src=\"https://img.shields.io/badge/ESM-F7DF1E?style=flat\" alt=\"ESM\" /></a>\n  <a href=\"https://www.typescriptlang.org/\"><img src=\"https://img.shields.io/badge/TS-3260C7?style=flat\" alt=\"TS\" /></a>\n  <a href=\"https://github.com/onury/accesscontrol/blob/master/LICENSE\"><img src=\"https://img.shields.io/npm/l/accesscontrol.svg?style=flat&color=blue\" alt=\"license\" /></a>\n  <a href=\"https://onury.io/accesscontrol\"><img src=\"https://img.shields.io/badge/docs-onury.io-c27cf4?style=flat\" alt=\"documentation\" /></a>\n</p>\n\n\n> This module is **ESM** 🔆. Please [**read this**](https://gist.github.com/onury/d3f3d765d7db2e8b2d050d14315f2ac7).\n\n📖 &nbsp;**Full documentation & guides:** &nbsp;**[onury.io/accesscontrol](https://onury.io/accesscontrol)**\n\n### Role and Attribute Based Access Control for Node.js\n\nMany [RBAC][rbac] (Role-Based Access Control) implementations differ, but the\nbasics are widely adopted since they simulate real-life role (job) assignments.\nBut as data gets more complex, you need to define policies on resources,\nsubjects, even environments — this is [ABAC][abac] (Attribute-Based Access\nControl). Merging the best of both (see this [NIST paper][nist-paper]),\nAccessControl implements RBAC basics **and** ABAC conditions, ownership, and\nmandatory gates.\n\n> [!TIP]\n> **v3** adds a real policy engine: conditions, enforced ownership, custom\n> actions, `require()` gates, groups/categories, async checks and audit events.\n> &nbsp;✨ **[What's new in v3 →](https://onury.io/accesscontrol/whats-new/)** &nbsp;·&nbsp; ⬆️ **[Migrating from v2 →](https://onury.io/accesscontrol/migration/)**\n\n## Core Features\n\n- Chainable, friendly API — e.g. `ac.can(role).createOwn(resource)`.\n- Role hierarchical **inheritance** with **deny-overrides** (deny always wins).\n- **Conditions** (`.where()`) — declarative ABAC with a readable expression syntax.\n- **Enforced ownership** — `own` actually verifies the record belongs to the user.\n- **Custom actions** beyond CRUD via `.action()` / `.do()`.\n- **`require()` gates** — mandatory restrictions at global / category / resource scope.\n- **Groups & categories** (`/`) — bounded bulk grants; the safe alternative to `*`.\n- **Async checks** + custom condition functions (`defineCondition`, `grantedAsync`).\n- **Events** — an `access` audit stream, plus `change` / `error`.\n- Glob-notation **attribute filtering** of data (with nested objects).\n- Define grants **at once** (object or DB rows) or **one by one**; `lock()` the model.\n- **Fail-closed checks** — `tryCan()` never throws; a failure can't become \"allow\".\n- **Hardened** — prototype-pollution-safe, ReDoS-guarded opt-in regex, redacted\n  error messages with stable `err.code`, optional Unicode charset.\n- No **silent** errors. **Fast** (in-memory). Strongly **typed**. ESM.\n- **Battle-tested** — 100% coverage, mutation-tested, adversarial + property-fuzz suites; both runtime dependencies (`notation`, `dtrexp` — same author) pinned exactly, zero production advisories.\n\n## Installation\n\n```sh\nnpm i accesscontrol\n```\n\n```js\nimport { AccessControl } from 'accesscontrol';\n```\n\n## Quick Start\n\n```js\nconst ac = new AccessControl();\n\nac.grant('user')                      // define or modify a role\n    .createOwn('video')               // ≡ .createOwn('video', ['*'])\n    .deleteOwn('video')\n    .readAny('video')\n  .grant('admin')                     // switch role, keep the chain\n    .extend('user')                   // inherit user's grants\n    .updateAny('video', ['title'])    // explicit attributes\n    .deleteAny('video');\n\nac.can('user').createOwn('video').granted;    // true\nac.can('admin').updateAny('video').attributes; // ['title']\n```\n\n## Guide\n\n### Roles & Inheritance\n\nCreate roles by calling `.grant(role)` or `.deny(role)`. Roles inherit other\nroles with `.extend()`; grants are **additive**, and an explicit `deny` always\nwins — even over inherited grants.\n\n```js\nac.grant('user').readAny('post', ['*']);\nac.grant('moderator').extend('user');\nac.deny('moderator').readAny('post', ['secret']);   // carve a field back\n\nac.can('moderator').readAny('post').attributes;     // ['*', '!secret']\n```\n\n`deny` does not cascade across possession: `deny create:any` still leaves\n`create:own`.\n\n### Actions — CRUD and Custom\n\nThe CRUD helpers (`createAny`, `readOwn`, `updateAny`, `deleteOwn`, …) are sugar\nover the generic `.action()` / `.do()`, which accept **any** action name:\n\n```js\nac.grant('editor').action('publish', 'article', ['*']);      // publish (any)\nac.grant('author').action('publish:own', 'article', ['*']);  // ownership-gated\n\nac.can('author', { user, article }).do('publish:own', 'article').granted;\nac.can('admin').do('update', 'post').granted; // CRUD via .do()\n```\n\n### Resources, Attributes & Filtering\n\nAttributes use [glob notation][glob] with negation and nested paths. `filter()`\nreturns a copy with only the allowed fields.\n\n```js\nac.grant('user').readOwn('account', ['*', '!password', 'profile.*']);\n\nconst perm = ac.can('user').readOwn('account');\nperm.attributes;            // ['*', '!password', 'profile.*']\nperm.filter(accountRecord); // record without `password`\n```\n\n### Possession & Ownership\n\n`any` means any record; `own` means the requester owns it. Tell AccessControl how\nownership is determined and pass the record in the check context — `own` is then\n**enforced**:\n\n```js\nconst ac = new AccessControl({}, { policy: { ownerField: 'ownerId' } });\nac.grant('user').updateOwn('order', ['*']);\n\nac.can('user', { user: { id: 7 }, order: { ownerId: 7 } }).updateOwn('order').granted; // true\nac.can('user', { user: { id: 7 }, order: { ownerId: 9 } }).updateOwn('order').granted; // false\n```\n\nA custom resolver (`policy.owner`) wins over `ownerField`. With no resolver\nconfigured, `own` keeps its v2 behavior (selects the attribute set; you enforce\nownership). A blanket `any` grant still satisfies an `own` check.\n\n### Conditions — `.where()` and `.with()`\n\nAttach a condition that decides whether a grant applies. Supply per-check data\nvia `can(role, context)`, the fluent `.with()`, or `check({ context })`.\n\n```js\nac.grant('manager')\n  .where('$.order.value <= 100000')\n  .updateAny('order', ['*']);\n\nac.can('manager').with({ order: { value: 5000 } }).updateAny('order').granted; // true\n```\n\nOperators: `== != > >= < <=`, `in`, `contains`, `matches`, `startsWith`, `endsWith`, `before` / `after` / `between` / `during`, `cidr`; combine with `{ and, or, not }`.\n\n`==` / `!=` are **strict** (no coercion; `===` / `!==` accepted as aliases), and a literal's type is inferred from how it's written — `100` is a number, `\"100\"` a string — so quote string values you don't want coerced. The time helper `$.now.*` is auto-injected. Conditions also accept canonical JSON (`['$.order.value', '<=', 100000]`), which is what gets stored/serialized.\n\nTemporal schedules use [dtrexp](https://dtrexp.org) expressions — compact date-time ranges and recurrences, evaluated in `context.tz`:\n\n```js\n// editors publish only on weekdays, 09:00–18:00\nac.grant('editor').during('T0900:1800 E1:5').updateAny('post');\n// same thing in condition sugar — combine it with anything:\nac.grant('editor').where('$.now during \"T0900:1800 E1:5\"').updateAny('post');\n```\n\n> [!NOTE]\n> The `matches` (regex) operator is **opt-in** — enable `engine.allowRegex`\n> (it's a ReDoS surface). Patterns are then screened for catastrophic\n> backtracking. See [Security](https://onury.io/accesscontrol/security/).\n\nSee the [conditions docs](https://onury.io/accesscontrol/concepts/conditions/).\n\n### Mandatory Gates — `require()` \n\n`.where()` conditionally **grants**; `.require()` is an independent gate that can\nonly **restrict**. `granted = (a grant matches) AND (every applicable gate passes)`.\n\n```js\nac.require('$.env == \"prod\"');                            // global\nac.category('billing').require('$.ip cidr 10.0.0.0/8');  // per category\nac.resource('billing/invoice').require('$.mfa == true'); // per resource\n```\n\nA gate **fails closed** when its context property is missing: `$.env` resolves to\n`undefined`, so `$.env == \"prod\"` is `false` and the check is denied (`reason:\n'require_failed'`). One sharp edge — a *negative* operator fails **open** on\nabsence (`undefined != 'dev'` is `true`), so prefer the positive assertion form\n(`$.env == \"prod\"`) for gates. See the [gates docs](https://onury.io/accesscontrol/concepts/gates/).\n\n### Groups & Categories — Bounded Bulk Grants\n\nDeclare your vocabulary with `setup()`, then grant to a **group** or **category**\nonce; members inherit dynamically. `media/photo` and `legal/photo` never collide.\n\n```js\nac.setup({\n  roles:     { admins: ['admin', 'moderator'], _: ['user'] },\n  resources: { media: ['photo', 'video'], _: ['profile'] },\n});\nac.grant('admins').readAny('media');                    // group × category\nac.can('admins/admin').readAny('media/photo').granted;  // true\n\nac.group('admins').getRoles();        // ['admins/admin', 'admins/moderator']\nac.category('media').getResources();  // ['media/photo', 'media/video']\n```\n\n`setup()`'s `roles`/`resources` also accept a plain array when you don't need\ngrouping (`roles: ['user', 'admin']`).\n\n### Strict Mode\n\n`policy.strict` (boolean or per-key object) turns on loud typo-protection.\nDefaults: `checks` and `roles` **on** (secure), `actions` and `resources` **off**.\n\n```js\nnew AccessControl(grants, { policy: { strict: { actions: true, resources: true } } });\n// an unknown action/resource throws instead of silently returning granted:false\n```\n\n### Async Checks & Custom Functions\n\nRegister business logic and reference it from a grant or gate as `{ fn, args }`\n(JSON-serializable). Declarative checks stay synchronous; custom/async ones use\n`grantedAsync` / `checkAsync`.\n\n```js\nac.defineCondition('ipAllowed', async (ctx, args) => isAllowed(ctx.ip, args.cidr));\nac.grant('admin').where({ fn: 'ipAllowed', args: { cidr: '10.0.0.0/8' } }).readAny('server');\n\nawait ac.can('admin', { ip }).readAny('server').grantedAsync;\n```\n\n### Events & Audit\n\nA dependency-free emitter. `access` fires on every resolved check (granted and\ndenied) — your audit log, with a denial `reason`. Listeners are observational and\nisolated; a throwing listener never breaks a check.\n\n```js\nac.on('access', (e) => audit(e));   // { roles, resource, action, granted, reason, ... }\nac.on('change', (e) => log(e.type));\nac.on('error', (e) => report(e.error));\n```\n\n### Serialization (for Databases)\n\n```js\nconst rows = ac.getGrantsList();          // flat, DB-friendly rows (+ $extend rows)\nconst restored = new AccessControl(rows); // round-trips identically\nac.getGrants();                           // the object form (frozen copy)\nac.getRequirements();                     // require() gates by scope\nac.getVocabulary();                       // setup() input: { roles, resources, actions }\n\n// or persist/restore the whole model (grants + gates + vocabulary) in one call:\nawait db.savePolicy(JSON.stringify(ac.snapshot()));\nconst ac2 = new AccessControl().restore(await db.loadPolicy());\n```\n\nBoth object and list inputs are accepted by the constructor and `setGrants()`.\nSee **[examples/](./examples)** for a full grants model, an SQL schema, and an\nExpress integration.\n\n### `engine` vs `policy` vs `context`\n\nThe constructor takes `new AccessControl(grants, { engine, policy, context })` —\nthree concerns: **`engine`** (library mechanics & security: `pathPrefix`,\n`allowRegex`, `charset`, `safeErrors`), **`policy`** (your authorization model:\n`ownerField`/`owner`, `strict`, allow-lists), and **`context`** (ambient data\nconditions read via `$.`). Rule of thumb: *library → `engine`, your domain →\n`policy`, condition data → `context`.*\n\n### Express Middleware\n\n```js\nfunction authorize(action, resource, loadRecord) {\n  return async (req, res, next) => {\n    const record = loadRecord ? await loadRecord(req) : undefined;\n    const ctx = { env: process.env.NODE_ENV, user: req.user, [resource]: record };\n    const perm = ac.can(req.user.role, ctx).action(action, resource);\n    if (!perm.granted) return res.status(403).end();\n    req.permission = perm;\n    next();\n  };\n}\n\nrouter.get('/articles/:id', authorize('read:any', 'article'), async (req, res) => {\n  const article = await db.findArticle(req.params.id);\n  res.json(req.permission.filter(article)); // filtered to granted attributes\n});\n```\n\nA fuller version (ownership, custom actions, audit) lives in\n[`examples/express-middleware.example.ts`](./examples/express-middleware.example.ts).\n\n## Security & Quality\n\nAuthorization is sensitive, so AccessControl is hardened against the bug classes\nthat matter for an access-control library — and clear about the decisions left to\nyou.\n\n- **Fail-closed by design.** Denials return `granted: false`; only genuine faults\n  throw. Use `tryCan()` on the request path so a thrown error can never become an\n  accidental *allow*. Errors carry a stable `err.code`.\n- **Prototype-pollution-safe.** The gadget names `__proto__` / `prototype` /\n  `constructor` are rejected, and every name-keyed lookup uses `Object.hasOwn`, so\n  a name like `toString` is treated as data, never a prototype member.\n- **ReDoS-guarded.** The `matches` regex operator is opt-in (`engine.allowRegex`);\n  enabled, patterns are screened for catastrophic backtracking. Condition nesting\n  depth is bounded.\n- **No info leaks by default.** `engine.safeErrors` (on by default) keeps\n  caller-supplied values out of error messages; immutable getters and `lock()`\n  prevent tampering.\n- **Homograph-aware names.** ASCII by default; `Charset.UNICODE` is opt-in with a\n  documented homograph caveat.\n\n> [!IMPORTANT]\n> On the request path, treat a thrown error as **deny**, never allow — or just\n> use `tryCan()`, which never throws.\n\n> [!NOTE]\n> **Quality bar:** 100% coverage (statements/branches/functions/lines),\n> mutation-tested (Stryker), plus an adversarial security suite and a seeded\n> property fuzzer. Its runtime dependencies (`notation` and `dtrexp`, both from\n> the same author) are pinned exactly; `npm audit --omit=dev` reports zero\n> advisories. Full details: **[Security Considerations][security]**.\n\n## Documentation\n\nSee the full documentation & API reference @ [onury.io/accesscontrol](https://onury.io/accesscontrol)\n\n## Related Projects\n\n- [**nestjs-accesscontrol**](https://github.com/onury/nestjs-accesscontrol) — The official NestJS integration for this package: fluent CRUD decorators, a fail-closed guard, and attribute filtering.\n- [**notation**](https://github.com/onury/notation) — Read, modify, and filter the contents of objects and arrays via dot/bracket notation strings or glob patterns.\n- [**dtrexp**](https://github.com/DTRExp/dtrexp-js) — Compact date-time range & recurrence expressions, evaluated by coverage — the engine behind the `during` operator. Spec & docs @ [dtrexp.org](https://dtrexp.org).\n- [**configuard**](https://github.com/onury/configuard) — Turn flat config rows from a database table into a nested, typed configuration object — with `${...}` templating and accessor-based (ABAC) filtering.\n\n## License\n\n© 2026, Onur Yıldırım. [**MIT**][license] License.\n\n[license]:https://github.com/onury/accesscontrol/blob/master/LICENSE\n[docs]:https://onury.io/accesscontrol/\n[security]:https://onury.io/accesscontrol/security/\n[best]:https://onury.io/accesscontrol/best-practices/\n[rbac]:https://en.wikipedia.org/wiki/Role-based_access_control\n[abac]:https://en.wikipedia.org/wiki/Attribute-Based_Access_Control\n[glob]:https://github.com/onury/notation\n[nist-paper]:http://csrc.nist.gov/groups/SNS/rbac/documents/kuhn-coyne-weil-10.pdf\n[changelog]:https://github.com/onury/accesscontrol/blob/master/CHANGELOG.md\n","readmeFilename":"README.md","users":{"jasher":true,"minhna":true,"ctmackay":true,"redbabel":true,"shaunieb":true,"byteshiva":true,"cognivator":true,"rocket0191":true,"kodekracker":true}}