{"_id":"relations","_rev":"32-6980aa28a4140458162b185a3d94565b","name":"relations","description":"entity relationship, role, and permissions API for Node.js","dist-tags":{"latest":"0.5.0"},"versions":{"0.1.0":{"name":"relations","version":"0.1.0","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","pegjs":"~0.7.0","async":"~0.1.22"},"devDependencies":{"mocha":"*","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","_id":"relations@0.1.0","dist":{"shasum":"b41dbd9fd20f03ab325990bda1b044e183ff2de7","tarball":"https://registry.npmjs.org/relations/-/relations-0.1.0.tgz","integrity":"sha512-fdmlwW2xXVzxks+E3FMRp5SzQixm+L/fghne0vUZlVezUR0lNk5abWbRUxY8j6ywvc+r7b7JeZ9+r7gZwXZVDg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHQnaCjQgYK14K8QpIlsSYJZ41FO7YR/KaP01BKclQ95AiEAtB6ERM/iDm9jK25PuH1AHZaMaSxNLmerYEEXpmZEG1s="}]},"_npmVersion":"1.1.59","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.1.1":{"name":"relations","version":"0.1.1","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","_id":"relations@0.1.1","dist":{"shasum":"4799cec2eda3ef98c06fb83b00cfb171daaa325b","tarball":"https://registry.npmjs.org/relations/-/relations-0.1.1.tgz","integrity":"sha512-VefSS0kNiyK4vFeOoSvadaHWH3DVhITx/Fxh1ioxzzicYTYnvu1PNuDr7Qmg+qGXfh89s219u2wECPy1bbnwyw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE1lVpXY+L7zj6rwI7i9aOFa//AIWBdi26vA7vBv3wXyAiAF/DArin1W1Hc87T0k04toJuM9ZlJ/+tChF7/V+PKqMQ=="}]},"_npmVersion":"1.1.59","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.2.0":{"name":"relations","version":"0.2.0","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","_id":"relations@0.2.0","dist":{"shasum":"3c0b7e06236f53d7b1af7a5970fae1c7c005181c","tarball":"https://registry.npmjs.org/relations/-/relations-0.2.0.tgz","integrity":"sha512-ijGcJhsj8TZfhpbFrZgXLPi/sT0Ujol7wFXdtxxKxhng4dE90Kx3BadLlU1rzlaHiVy6cPTZg083Yhro4389cA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCPFF3MpFOYRIMk6sqHYBkJQyQc7V5d5xheS9CNYalV2QIhALxE3GVLDphK6gbUwehvv4sHQJJSteO9aVumLxF7N2rZ"}]},"_npmVersion":"1.1.59","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.2.1":{"name":"relations","version":"0.2.1","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","_id":"relations@0.2.1","dist":{"shasum":"3555976002ce9da50247b9445f5c20f0c8435af9","tarball":"https://registry.npmjs.org/relations/-/relations-0.2.1.tgz","integrity":"sha512-8xBQQpPwLFKroIvaDAG9QDYNJYmrjv8NoUUy89iiDg9ANqu66j+3ygcNMNnH2GPD2qTX8yzFmt2nfkUW8k6n3A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICMRmSp+tU6zOhqwGODEjACGYSSC2gme0oRcSloT3/DFAiEA1D4ZxuFHA3WbvZFK86PomTgj0ULn8NVzPHQ/UBsacxk="}]},"_npmVersion":"1.1.59","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.3.0":{"name":"relations","version":"0.3.0","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","_id":"relations@0.3.0","dist":{"shasum":"b194119721336b4b4039c59ce4ba42f0c219f6eb","tarball":"https://registry.npmjs.org/relations/-/relations-0.3.0.tgz","integrity":"sha512-Z6bhHSryAoivsgrPyiBUqC+u7De3btasjKi/lSHZuWe62tJLDWH5oR+jp5g0YjVJIvHq2H0ooJ/exO17d7KEGA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHJnPEaaZx0JkxvBGovbsGWcJIx2dE6RxOgJ/N/MzfQyAiBI8Lhy+OSVo9w4OILSmWKH00ni0njSpO9BuYlMnHhQaQ=="}]},"_from":".","_npmVersion":"1.2.11","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.3.1":{"name":"relations","version":"0.3.1","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","_id":"relations@0.3.1","dist":{"shasum":"a22df7a125bfbeb976d9286fc4f20d3852746e7b","tarball":"https://registry.npmjs.org/relations/-/relations-0.3.1.tgz","integrity":"sha512-Bt/K5vm7x/n/EtchUpDO+vDaEyw0m3wKNUL+SC8Sm6nr1Fh3+JvCwGAa8oE0PB/ejap0Gwa7z5s7VQaBEWCpaQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHrEH0JalFqV5Kuw1sh/e8X33UMZWsILqFVG0qzAkUfjAiBqCNWkHbVDtNVoUoW/R2IvKtnC2caRV5jVxKiOH+CuTg=="}]},"_from":".","_npmVersion":"1.2.14","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.3.2":{"name":"relations","version":"0.3.2","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","bugs":{"url":"https://github.com/carlos8f/node-relations/issues"},"_id":"relations@0.3.2","dist":{"shasum":"4ee3d8c53ff4e15a1a2e199f5e1a3a09349d4a25","tarball":"https://registry.npmjs.org/relations/-/relations-0.3.2.tgz","integrity":"sha512-/yp/HVvdzT2dg4B+twgrGOdmrJbfBDw6hLNq2pluTgGw5xVOZOYawT19pLAdhV4FG0uljIZ8xmIPdBGXlDXD4Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDjSrNkracRlQmOqLv24P+gAim7YnMUuSglICffWnBNSQIhAOzpuibau3MMx84V05PED81nK7bMFfiWywBFNAiNO8Lg"}]},"_from":".","_npmVersion":"1.2.32","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.4.0":{"name":"relations","version":"0.4.0","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","bugs":{"url":"https://github.com/carlos8f/node-relations/issues"},"_id":"relations@0.4.0","dist":{"shasum":"fad08f4074720e6ff82cf4acba0d8276434324e4","tarball":"https://registry.npmjs.org/relations/-/relations-0.4.0.tgz","integrity":"sha512-Sl8ullhYt49zgs/LhdrpyhkCYbieKM2TNfFSy130uKQ+Dl036qWoAfkpIeSdO0VXBGBukgHcHMl+2tlHH++dFg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFvEupLqvUm1zjzvrU8sghPZ5N3PfBQzrjbk2e7EZ8cgAiEA78mW55HIFlhxE9u2mXI7U1PZ6FOegeWzppwHqXI/u/E="}]},"_from":".","_npmVersion":"1.3.8","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.4.1":{"name":"relations","version":"0.4.1","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","bugs":{"url":"https://github.com/carlos8f/node-relations/issues"},"_id":"relations@0.4.1","dist":{"shasum":"d6deaac20ddf73e19cfa7c4e54f632994252f0c4","tarball":"https://registry.npmjs.org/relations/-/relations-0.4.1.tgz","integrity":"sha512-cACDNVkKgJ6PM+vRIfp8dFV9V1wc/3ZkIga6GkVeYJS4OYwSY/FFSTAEAJUk8nDCZGUduOLudNUvXVSGSyXj7A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHqooPflmJ3bZzk2G0COKPR2uMbXLe6KKbnZPuAC33fzAiAY9WgCebk6HXrNJK5VE1E2VY6Qtpu4Wlg+P02y0qzW8g=="}]},"_from":".","_npmVersion":"1.3.8","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.4.2":{"name":"relations","version":"0.4.2","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","bugs":{"url":"https://github.com/carlos8f/node-relations/issues"},"_id":"relations@0.4.2","dist":{"shasum":"84347ee4aed985826395ed689803a11d24c4c86c","tarball":"https://registry.npmjs.org/relations/-/relations-0.4.2.tgz","integrity":"sha512-ttUzcmpkrEFQny1wwaRzEPCoetiD2/B9hx44TyR/+cB0CBC9E+mvNWoxGJX9pnR54WpvE9JNP+Ivsjc8EPFN6g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDCKsSflf9rtAEOWUPCjdLlys5RecD1q2erwfWyARXavwIhAM6gb5V8l5jZFEQFdKAKR2UXy1KFwV2q1nPcMAedEjzM"}]},"_from":".","_npmVersion":"1.3.8","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.4.3":{"name":"relations","version":"0.4.3","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","bugs":{"url":"https://github.com/carlos8f/node-relations/issues"},"_id":"relations@0.4.3","dist":{"shasum":"77580f8868afe65610336b0a6986340c55aa61e8","tarball":"https://registry.npmjs.org/relations/-/relations-0.4.3.tgz","integrity":"sha512-vnjneq2JTL5hE96VAOrmBflv8aiBhc1Ub3yICp6+HY+6yyEPPEugufqZccLQ3kMURzcoc8d7gaJEbP/4KZKSSg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDYUbGAB5lPO8jCREAt8QL7cedBNKi+inGEU0YZksIpMwIhAKPoytf1sjeuhM2ecLZoXViyonoqALcNptA9CFsGMrck"}]},"_from":".","_npmVersion":"1.3.8","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.4.4":{"name":"relations","version":"0.4.4","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"mocha":"*","pegjs":"~0.7.0","mysql":"2.0.0-alpha3","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","bugs":{"url":"https://github.com/carlos8f/node-relations/issues"},"_id":"relations@0.4.4","dist":{"shasum":"160e9c54edd8c1c25304087ccd80980832abe43a","tarball":"https://registry.npmjs.org/relations/-/relations-0.4.4.tgz","integrity":"sha512-QZT6YJ/CgF3r5JJ8VQYqJV/x2z34u9zVj2saL3k5JMPjHqJ7sIQE+oyBevUHaoad16b44vmyUp9RA6lWVUpRoA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDoYhD8GYEJGyUs7qN0hSTh7ud2ny8ru1dHOaQ7YxQgVQIhANYX9YyZOv5J3W+CY15sfMUT/dgDQzZTXZw+VIBAWjrZ"}]},"_from":".","_npmVersion":"1.4.4","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}]},"0.5.0":{"name":"relations","version":"0.5.0","description":"entity relationship, role, and permissions API for Node.js","main":"index.js","dependencies":{"eventflow":"0.0.6","async":"~0.1.22"},"devDependencies":{"idgen":"^2.0.2","mocha":"*","mysql":"2.0.0-alpha3","pegjs":"~0.7.0","redis":"~0.8.1"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"license":"MIT","gitHead":"6b8b5d3ff276bffa74fe23e5cb9c3fac09af9519","bugs":{"url":"https://github.com/carlos8f/node-relations/issues"},"_id":"relations@0.5.0","_shasum":"340a21ca7ad56e633390145f0b19b48ac4fa76e1","_from":".","_npmVersion":"1.4.14","_npmUser":{"name":"carlos8f","email":"carlos@s8f.org"},"maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}],"dist":{"shasum":"340a21ca7ad56e633390145f0b19b48ac4fa76e1","tarball":"https://registry.npmjs.org/relations/-/relations-0.5.0.tgz","integrity":"sha512-jomYcTYreWn6GOxTQ/vFtFGkCuvxyEb9CT5klcNct+aHSDZ9rtlv9OPwTGqsOAsrrhugWKG72a/92j5rOgAuDA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHO+kbWqkgvZRpGemQh4dVUguqUh1Ok4/booNljdzVc4AiEAsogx/IydP9gJGKa8qMwIzv+FegpSeHq9P+QCnZerQWc="}]}}},"readme":"relations\n=========\n\nentity relationship, role, and permissions API for Node.js\n\n[![build status](https://secure.travis-ci.org/carlos8f/node-relations.png)](http://travis-ci.org/carlos8f/node-relations)\n\n**relations** is a simple permissions API which uses a natural language approach.\n\nContexts\n--------\n\nFirst, you'll create a **context**, which contains a list of roles which map to\nactions. Here we'll create a context called `repos`, to model Github repositories.\n\n```js\nvar relations = require('relations');\n\nrelations.define('repos', {\n  owner: ['pull', 'push', 'administrate'],\n  collaborator: ['pull', 'push'],\n  watcher: ['pull']\n});\n```\n\nDefining the context makes available a method on `relations` that matches the\ncontext name, in this case, `relations.repos()`. For permission checks, this is\nthe only method we'll need to call.\n\n### Dynamic roles\n\nTo add or modify roles at runtime, you can also use the following methods:\n\n```js\n// add a role dynamically\nrelations.repos.addRole('scientist', ['test', 'hyphothesize']);\n// update the actions for a role\nrelations.repos.updateRole('scientist', ['test', 'hypothesize', 'absquatulate']);\n// remove a role\nrelations.repos.removeRole('scientist');\n```\n\n**Please note** that the role -> action map is defined exclusively in the code,\nand not stored. If you run a cluster of servers, and choose to use dynamic roles,\nyou must call `addRole()` etc on ALL servers in the cluster (I suggest using\npub/sub).\n\nDeclarations\n------------\n\nNow, we need to tell our app who has those roles for which repos.\n\n```js\nrelations.repos('Carlos is the owner of buffet.');\n```\n\nThis assigns the role `owner` to the subject `Carlos` for the object `buffet`.\n\n### Token replacements\n\nNote that the API has multiple syntaxes, and this is functionally equivalent:\n\n```js\nrelations.repos(':user is owner of :repo', {user: 'Carlos', repo: 'buffet'});\n```\n\nAs is this:\n\n```js\nrelations.repos('%s is an owner of %s', 'Carlos', 'buffet');\n```\n\nTo assign a role which should apply to all objects, simply leave the object out\nof the sentence:\n\n```js\nrelations.repos('%s is a watcher.', 'Brian');\n```\n\n**Note: Using token replacements is recommended, to prevent injection attacks!**\n\n### Syntax\n\nThe syntax for a **declaration** consists of:\n\n```\n<subject> is [ a / an / the ] <role> [ [ of / to / from / in / with ] <object> ] [.]\n```\n\nVerb question\n-------------\n\nTo ask if a user can perform an action:\n\n```js\nrelations.repos('Can %s pull?', 'Brian', function (err, can) {\n  // can = true (based on \"watcher\" role)\n});\n```\n\nWe can also check if an action can be performed on a specific object:\n\n```js\nrelations.repos('Can %s push to buffet?', 'Brian', function (err, can) {\n  // can = false (Brian doesn't have \"owner\" or \"collaborator\" roles)\n});\n```\n\n### Syntax\n\nThe syntax for an **verb question** consists of:\n\n```\n( Can | can ) <subject> <verb> [ [ of / to / from / in / with ] <object> ] [?]\n```\n\nRole question\n-------------\n\nTo check if a user has a role:\n\n```js\nrelations.repos('Is %s a collaborator of %s?', 'Brian', 'buffet', function (err, is) {\n  // is = false\n});\n```\n\nWe can also leave the object out to check for a global role:\n\n```js\nrelations.repos('Is %s a %s?', 'Brian', 'watcher', function (err, is) {\n  // is = true\n});\n```\n\n### Syntax\n\nThe syntax for a **role question** consists of:\n\n```\n( Is | is ) <subject> [ a / an / the ] <role> [ [ of / to / from / in / with ] <object> ] [?]\n```\n\nVerb request\n------------\n\nIn addition to true/false checks, **relations** can return an array of objects\nwhich match certain criteria. For example:\n\n```js\nrelations.repos('What can %s pull from?', 'Carlos', function (err, repos) {\n  // repos = ['buffet']\n});\n```\n\n### Syntax\n\nThe syntax for a **verb request** consists of:\n\n```\n( What | what ) can <subject> <verb> [ of / to / from / in / with ] [?]\n```\n\nRole request\n------------\n\nAlso, we can ask for an array of objects a user has a role for:\n\n```js\nrelations.repos('What is %s the owner of?', 'Carlos', function (err, repos) {\n  // repos = ['buffet']\n});\n```\n\n### Syntax\n\nThe syntax for a **role request** consists of:\n\n```\n( What | what ) is <subject> [ a / an / the ] <role> [ of / to / from / in / with ] [?]\n```\n\nVerb subject request\n--------------------\n\nTo request an array of subjects who can perform an action on an object:\n\n```js\nrelations.repos('Who can pull from %s?', 'buffet', function (err, users) {\n  // users = ['Carlos']\n});\n```\n\n### Syntax\n\n```\n( Who | who ) can <verb> [ of / to / from / in / with ] <object> [?]\n```\n\nRole subject request\n--------------------\n\nTo request an array of subjects who have a role for an object:\n\n```js\nrelations.repos('Who is the owner of %s?', 'buffet', function (err, users) {\n  // users = ['Carlos']\n});\n```\n\n### Syntax\n\n```\n( Who | who ) is [ a / an / the ] <role> [ of / to / from / in / with ] <object> [?]\n```\n\nObject verb request\n-------------------\n\nTo request an array of verbs a subject can perform on an object:\n\n```js\nrelations.repos('What actions can %s do with %s?', 'Carlos', 'buffet', function (err, verbs) {\n  // verbs = ['pull', 'push', 'administrate']\n});\n```\n\n### Syntax\n\n```\nWhat actions can <subject> do [ of / to / from / in / with ] <object> [?]\n```\n\nObject-Role map request\n-----------------------\n\nTo get a map of object->role pairs for a subject:\n\n```js\nrelations.repos('Describe what %s can do', 'Carlos', function (err, map) {\n  // map = { '': [ 'watcher' ],\n             'buffet': [ 'owner' ] }\n});\n```\n\n### Syntax\n\n```\n[ Describe / detail / explain / get ] what <subject> can do [.]\n```\n\nSubject-Role map request\n-----------------------\n\nTo get a map of subject->role pairs, optionally pertaining to an object:\n\n```js\nrelations.repos('Get who can act', function (err, map) {\n  // map = { 'carlos': [ 'watcher' ],\n             'brian': [ 'watcher' ] }\n});\n```\n\n```js\nrelations.repos('Explain who can act on %s', 'buffet', function (err, map) {\n  // map = { 'carlos': [ 'owner' ] }\n});\n```\n\n### Syntax\n\n```\n[ Describe / detail / explain / get ] who can act [ on <object> ] [.]\n```\n\nRevocation\n----------\n\nTo revoke a role:\n\n```js\nrelations.repos('%s is not the owner of %s', 'Carlos', 'buffet');\n```\n\n### Syntax\n\n```\n<subject> ( is not | isn't ) [ a / an / the ] <role> [ [ of / to / from / in / with ] <object> ] [.]\n```\n\nPersistence\n-----------\n\nData can be persisted through [database plugins](#pluggable-data-store) or a flat\nfile. To use a flat file, initialize `relations` like this:\n\n```js\nvar relations = require('relations');\nrelations.use(relations.stores.memory, {dataFile: '/path/to/datafile.json'});\n```\n\n`relations` will store and load data, as a JSON blob, in the specified file.\n\nPluggable data store\n--------------------\n\nTwo additional data stores are provided: Redis and MySQL.\n\n### Redis store\n\nTo use the redis store, your app must make a\n[node_redis](https://github.com/mranney/node_redis) client and pass it like so:\n\n```js\nvar relations = require('relations')\n  , redis = require('redis')\n\nrelations.use(relations.stores.redis, {\n  client: redis.createClient(),\n  prefix: 'optional-key-prefix'\n});\n```\n\n### MySQL store\n\nTo use the MySQL store, your app must make a\n[node-mysql](https://github.com/felixge/node-mysql) client and pass it like so:\n\n```js\nvar relations = require('relations')\n  , mysql = require('mysql')\n\nrelations.use(relations.stores.mysql, {client: mysql.createConnection({user: 'root', database: 'test'})});\n```\n\n### Make your own store\n\nA **relations** store is simply a node module that exports an event emitter\nand responds to the following events:\n\n#### `init` (options, cb)\n\nInitialize the store with `options` (from `relations.use()`) and call `cb(err)`\nwhen done.\n\n#### `declaration` (cmd, cb)\n\nRespond to a declaration and call `cb()` when done. `cmd` will be an object\ncontaining the properties:\n\n- ctx - context object\n- subject\n- role\n- object (optional)\n\n#### `revocation` (cmd, cb)\n\nRespond to a revocation and call `cb()` when done. `cmd` will be an object\ncontaining the properties:\n\n- ctx - context object\n- subject\n- role\n- object (optional)\n\n### `verb-question` (cmd, cb)\n\nRespond to a verb question and call `cb(err, /* boolean */ can)` with the result.\n`cmd` will be an object containing the properties:\n\n- ctx - context object\n- subject\n- verb\n- object (optional)\n\n### `role-question` (cmd, cb)\n\nRespond to a role question and call `cb(err, /* boolean */ is)` with the result.\n`cmd` will be an object containing the properties:\n\n- ctx - context object\n- subject\n- role\n- object (optional)\n\n### `verb-request` (cmd, cb)\n\nRespond to a verb request and call `cb(err, /* array */ objects)` with the result.\n`cmd` will be an object containing the properties:\n\n- ctx - context object\n- subject\n- verb\n\n### `role-request` (cmd, cb)\n\nRespond to a role request and call `cb(err, /* array */ objects)` with the result.\n`cmd` will be an object containing the properties:\n\n- ctx - context object\n- subject\n- role\n\n### `verb-subject-request` (cmd, cb)\n\nRespond to a verb subject request and call `cb(err, /* array */ subjects)` with\nthe result. `cmd` will be an object containing the properties:\n\n- ctx - context object\n- verb\n- object\n\n### `role-subject-request` (cmd, cb)\n\nRespond to a role subject request and call `cb(err, /* array */ subjects)` with\nthe result. `cmd` will be an object containing the properties:\n\n- ctx - context object\n- role\n- object\n\n### `object-verb-request` (cmd, cb)\n\nRespond to an object verb request and call `cb(err, /* array */ verbs)` with\nthe result. `cmd` will be an object containing the properties:\n\n- ctx - context object\n- object\n- subject\n\n### `object-role-map-request` (cmd, cb)\n\nRespond to an object-role map request and call `cb(err, /* object */ map)` with\nthe result. `cmd` will be an object containing the properties:\n\n- ctx - context object\n- subject\n\n### `subject-role-map-request` (cmd, cb)\n\nRespond to a subject-role map request and call `cb(err, /* object */ map)` with\nthe result. `cmd` will be an object containing the properties:\n\n- ctx - context object\n- object (optional)\n\n### `reset` (cb)\n\nReset the store, dumping all storage and structure, calling `cb(err)` when done.\n\n- - -\n\n### Developed by [Terra Eclipse](http://www.terraeclipse.com)\nTerra Eclipse, Inc. is a nationally recognized political technology and\nstrategy firm located in Aptos, CA and Washington, D.C.\n\n- - -\n\n### License: MIT\n\n- Copyright (C) 2012 Carlos Rodriguez (http://s8f.org/)\n- Copyright (C) 2012 Terra Eclipse, Inc. (http://www.terraeclipse.com/)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the &quot;Software&quot;), 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 furnished\nto 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 &quot;AS IS&quot;, 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 THE\nSOFTWARE.\n","maintainers":[{"name":"carlos8f","email":"carlos@s8f.org"}],"time":{"modified":"2022-06-26T10:53:32.838Z","created":"2012-10-15T21:12:02.409Z","0.1.0":"2012-10-15T21:12:03.901Z","0.1.1":"2012-10-15T22:19:59.977Z","0.2.0":"2012-10-16T00:38:44.809Z","0.2.1":"2012-12-15T20:13:31.952Z","0.3.0":"2013-03-05T20:10:36.897Z","0.3.1":"2013-03-11T19:05:23.765Z","0.3.2":"2013-07-19T20:13:51.344Z","0.4.0":"2013-08-26T22:18:45.749Z","0.4.1":"2013-09-17T02:03:20.178Z","0.4.2":"2013-09-25T23:03:54.002Z","0.4.3":"2013-10-02T00:56:06.042Z","0.4.4":"2014-05-05T18:31:52.942Z","0.5.0":"2014-08-06T21:43:39.888Z"},"author":{"name":"Carlos Rodriguez","email":"carlos@s8f.org","url":"http://s8f.org/"},"repository":{"type":"git","url":"git://github.com/carlos8f/node-relations.git"},"homepage":"https://github.com/carlos8f/node-relations","keywords":["acl","access","data","model","granular"],"bugs":{"url":"https://github.com/carlos8f/node-relations/issues"},"license":"MIT","readmeFilename":"README.md","users":{"rocket0191":true,"sinfex":true,"deividasjackus":true}}