From df6334d04ec9a7cfea52a5a1d8071e8a5a38479b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=B8cker-Larsen?= Date: Sat, 31 Mar 2018 20:18:21 +0800 Subject: [PATCH] v0.5.0 --- dist/browser-acl.js | 2 +- dist/browser-acl.js.map | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/browser-acl.js b/dist/browser-acl.js index 2eabec9..f0ff760 100644 --- a/dist/browser-acl.js +++ b/dist/browser-acl.js @@ -1,2 +1,2 @@ -module.exports=function(e){function t(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/",t(t.s=0)}([function(e,t,r){e.exports=r(1)},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{},r=t.strict,i=void 0!==r&&r;n(this,e),this.strict=i,this.rules=new Map,this.policies=new Map,this.registry=new WeakMap}return i(e,[{key:"rule",value:function(e,t){var r=this,n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],i=this.subjectMapper(t);return(Array.isArray(e)?e:[e]).forEach(function(e){var t=r.rules.get(i)||{};t[e]=n,r.rules.set(i,t)}),this}},{key:"policy",value:function(e,t){var r="function"==typeof e?new e:e,n=this.subjectMapper(t);return this.policies.set(n,r),this}},{key:"register",value:function(e,t){return this.registry.set(e,t),this}},{key:"can",value:function(e,t,r){var n=this.subjectMapper(r),i=this.policies.get(n)||this.rules.get(n);if(void 0===i){if(this.strict)throw new Error('Unknown subject "'+n+'"');return!1}if("function"==typeof i[t]){for(var o=arguments.length,s=Array(o>3?o-3:0),u=3;u3?n-3:0),o=3;o3?n-3:0),o=3;o1&&void 0!==arguments[1]?arguments[1]:null,r=this.subjectMapper(e);if(this.rules.has(r)){if(t){return delete this.rules.get(r)[t],this}this.rules.delete(r)}return this}},{key:"removePolicy",value:function(e){var t=this.subjectMapper(e);return this.policies.delete(t),this}},{key:"removeAll",value:function(e){return this.removeRules(e),this.removePolicy(e),this}}]),e}();t.default=o}]); +module.exports=function(e){function t(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/",t(t.s=0)}([function(e,t,r){e.exports=r(1)},function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),r.d(t,"GlobalRule",function(){return o}),r.d(t,"default",function(){return s});var i=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{},r=t.strict,i=void 0!==r&&r;n(this,e),this.strict=i,this.rules=new Map,this.policies=new Map,this.registry=new WeakMap}return i(e,[{key:"rule",value:function(e,t){var r=this,n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];u(t)&&(n=t,t=o);var i=this.subjectMapper(t);return(Array.isArray(e)?e:[e]).forEach(function(e){var t=r.rules.get(i)||{};t[e]=n,r.rules.set(i,t)}),this}},{key:"policy",value:function(e,t){var r="function"==typeof e?new e:e,n=this.subjectMapper(t);return this.policies.set(n,r),this}},{key:"register",value:function(e,t){return this.registry.set(e,t),this}},{key:"can",value:function(e,t,r){r=void 0===r?o:r;var n=this.subjectMapper(r),i=this.policies.get(n)||this.rules.get(n);if(void 0===i){if(this.strict)throw new Error('Unknown subject "'+n+'"');return!1}if("function"==typeof i[t]){for(var u=arguments.length,s=Array(u>3?u-3:0),a=3;a3?n-3:0),o=3;o3?n-3:0),o=3;o1&&void 0!==arguments[1]?arguments[1]:null,r=this.subjectMapper(e);if(this.rules.has(r)){if(t){return delete this.rules.get(r)[t],this}this.rules.delete(r)}return this}},{key:"removePolicy",value:function(e){var t=this.subjectMapper(e);return this.policies.delete(t),this}},{key:"removeAll",value:function(e){return this.removeRules(e),this.removePolicy(e),this}}]),e}()}]); //# sourceMappingURL=browser-acl.js.map \ No newline at end of file diff --git a/dist/browser-acl.js.map b/dist/browser-acl.js.map index 2bdffbf..064afa5 100644 --- a/dist/browser-acl.js.map +++ b/dist/browser-acl.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///browser-acl.js","webpack:///webpack/bootstrap 4af3caab4ad21c92e6d0","webpack:///./index.js"],"names":["module","exports","modules","__webpack_require__","moduleId","installedModules","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","__webpack_exports__","_classCallCheck","instance","Constructor","TypeError","value","_createClass","defineProperties","target","props","length","descriptor","writable","key","protoProps","staticProps","Acl","_ref","arguments","undefined","_ref$strict","strict","this","rules","Map","policies","registry","WeakMap","verbs","subject","_this","test","subjectName","subjectMapper","Array","isArray","forEach","verb","set","policy","policy_","klass","user","Error","_len","args","_key","Boolean","apply","concat","subjects","_len2","_key2","_this2","some","can","_len3","_key3","_this3","every","User","acl","slice","isFun","has","constructor","delete","removeRules","removePolicy"],"mappings":"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","file":"browser-acl.js","sourcesContent":["module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/*!************************!*\\\n !*** multi ./index.js ***!\n \\************************/\n/*! dynamic exports provided */\n/*! all exports used */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(/*! /Users/mblarsen/workspace/mblarsen/browser-acl/index.js */1);\n\n\n/***/ }),\n/* 1 */\n/*!******************!*\\\n !*** ./index.js ***!\n \\******************/\n/*! exports provided: default */\n/*! all exports used */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Simple ACL library for the browser inspired by Laravel's guards and policies.\n * @class Acl\n */\nvar Acl = function () {\n\n /**\n * browser-acl\n *\n * @access public\n * @param {Boolean} {strict=false}={} Errors out on unknown verbs when true\n * @returns {Acl}\n */\n function Acl() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n _ref$strict = _ref.strict,\n strict = _ref$strict === undefined ? false : _ref$strict;\n\n _classCallCheck(this, Acl);\n\n this.strict = strict;\n this.rules = new Map();\n this.policies = new Map();\n this.registry = new WeakMap();\n }\n\n /**\n * You add rules by providing a verb, a subject and an optional\n * test (that otherwise defaults to true).\n *\n * If the test is a function it will be evaluated with the params:\n * user, subject, and subjectName. The test value is ultimately evaluated\n * for truthiness.\n *\n * Examples:\n *\n * ```javascript\n * acl.rule('create', Post)\n * acl.rule('edit', Post, (user, post) => post.userId === user.id)\n * acl.rule('edit', Post, (user, post, verb, any, other, value, passed) => true)\n * acl.rule('delete', Post, false) // deleting disabled\n * ```\n *\n * @access public\n * @param {Array|string} verbs\n * @param {Function|Object|string} subject\n * @param {Boolean} test=true\n * @returns {Acl}\n */\n\n\n _createClass(Acl, [{\n key: 'rule',\n value: function rule(verbs, subject) {\n var _this = this;\n\n var test = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n\n var subjectName = this.subjectMapper(subject);\n var verbs_ = Array.isArray(verbs) ? verbs : [verbs];\n verbs_.forEach(function (verb) {\n var rules = _this.rules.get(subjectName) || {};\n rules[verb] = test;\n _this.rules.set(subjectName, rules);\n });\n return this;\n }\n\n /**\n * You can group related rules into policies for a subject. The policies\n * properties are verbs and they can plain values or functions.\n *\n * If the policy is a function it will be new'ed up before use.\n *\n * ```javascript\n * class Post {\n * constructor() {\n * this.view = true // no need for a functon\n *\n * this.delete = false // not really necessary since an abscent\n * // verb has the same result\n * },\n * edit(user, post, verb, any, other, value, passed) {\n * return post.id === user.id\n * }\n * }\n * ```\n *\n * Policies are useful for grouping rules and adding more complex logic.\n *\n * @access public\n * @param {Object} policy A policy with properties that are verbs\n * @param {Function|Object|string} subject\n * @returns {Acl}\n */\n\n }, {\n key: 'policy',\n value: function policy(_policy, subject) {\n var policy_ = typeof _policy === 'function' ? new _policy() : _policy;\n var subjectName = this.subjectMapper(subject);\n this.policies.set(subjectName, policy_);\n return this;\n }\n\n /**\n * Explicitly map a class or constructor function to a name.\n *\n * You would want to do this in case your code is heavily\n * minified in which case the default mapper cannot use the\n * simple \"reflection\" to resolve the subject name.\n *\n * Note: If you override the subjectMapper this is not used,\n * bud it can be used manually through `this.registry`.\n *\n * @access public\n * @param {Function} klass A class or constructor function\n * @param {string} subjectName\n */\n\n }, {\n key: 'register',\n value: function register(klass, subjectName) {\n this.registry.set(klass, subjectName);\n return this;\n }\n\n /**\n * Performs a test if a user can perform action on subject.\n *\n * The action is a verb and the subject can be anything the\n * subjectMapper can map to a subject name.\n *\n * E.g. if you can to test if a user can delete a post you would\n * pass the actual post. Where as if you are testing us a user\n * can create a post you would pass the class function or a\n * string.\n *\n * ```javascript\n * acl->can(user, 'create', Post)\n * acl->can(user, 'edit', post)\n * acl->can(user, 'edit', post, any, other, value, passed)\n * ```\n *\n * Note that these are also available on the user if you've used\n * the mixin:\n *\n * ```javascript\n * user->can('create', Post)\n * user->can('edit', post)\n * ```\n *\n * @access public\n * @param {Object} user\n * @param {string} verb\n * @param {Function|Object|string} subject\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n\n }, {\n key: 'can',\n value: function can(user, verb, subject) {\n var subjectName = this.subjectMapper(subject);\n var rules = this.policies.get(subjectName) || this.rules.get(subjectName);\n\n if (typeof rules === 'undefined') {\n if (this.strict) {\n throw new Error('Unknown subject \"' + subjectName + '\"');\n }\n return false;\n }\n\n if (typeof rules[verb] === 'function') {\n for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {\n args[_key - 3] = arguments[_key];\n }\n\n return Boolean(rules[verb].apply(rules, [user, subject, subjectName].concat(args)));\n }\n\n if (this.strict && typeof rules[verb] === 'undefined') {\n throw new Error('Unknown verb \"' + verb + '\"');\n }\n\n return Boolean(rules[verb]);\n }\n\n /**\n * Like can but subject is an array where only some has to be\n * true for the rule to match.\n *\n * Note the subjects do not need to be of the same kind.\n *\n * @access public\n * @param {Object} user\n * @param {Array} subjects\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n\n }, {\n key: 'some',\n value: function some(user, verb, subjects) {\n for (var _len2 = arguments.length, args = Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {\n args[_key2 - 3] = arguments[_key2];\n }\n\n var _this2 = this;\n\n return subjects.some(function (s) {\n return _this2.can.apply(_this2, [user, verb, s].concat(args));\n });\n }\n\n /**\n * Like can but subject is an array where all has to be\n * true for the rule to match.\n *\n * Note the subjects do not need to be of the same kind.\n *\n * @access public\n * @param {Object} user\n * @param {Array} subjects\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n\n }, {\n key: 'every',\n value: function every(user, verb, subjects) {\n for (var _len3 = arguments.length, args = Array(_len3 > 3 ? _len3 - 3 : 0), _key3 = 3; _key3 < _len3; _key3++) {\n args[_key3 - 3] = arguments[_key3];\n }\n\n var _this3 = this;\n\n return subjects.every(function (s) {\n return _this3.can.apply(_this3, [user, verb, s].concat(args));\n });\n }\n\n /**\n * Mix in augments your user class with a `can` function object. This\n * is optional and you can always call `can` directly on your\n * Acl instance.\n *\n * ```\n * user.can()\n * user.can.some()\n * user.can.every()\n * ```\n *\n * @access public\n * @param {Function} User A user class or contructor function\n */\n\n }, {\n key: 'mixin',\n value: function mixin(User) {\n var acl = this;\n User.prototype.can = function () {\n return acl.can.apply(acl, [this].concat(Array.prototype.slice.call(arguments)));\n };\n User.prototype.can.every = function () {\n return acl.every.apply(acl, [this].concat(Array.prototype.slice.call(arguments)));\n };\n User.prototype.can.some = function () {\n return acl.some.apply(acl, [this].concat(Array.prototype.slice.call(arguments)));\n };\n return this;\n }\n\n /**\n * Rules are grouped by subjects and this default mapper tries to\n * map any non falsy input to a subject name.\n *\n * This is important when you want to try a verb against a rule\n * passing in an instance of a class.\n *\n * - strings becomes subjects\n * - function's names are used for subject\n * - objects's constructor name is used for subject\n *\n * Override this function if your models do not match this approach.\n *\n * E.g. say that you are using plain data objects with a type property\n * to indicate the \"class\" of the object.\n *\n * ```javascript\n * acl.subjectMapper = s => typeof s === 'string' ? s : s.type\n * ```\n *\n * `can` will now use this function when you pass in your objects.\n *\n * See {@link #register register()} for how to manually map\n * classes to subject name.\n *\n * @access public\n * @param {Function|Object|string} subject\n * @returns {string} A subject\n */\n\n }, {\n key: 'subjectMapper',\n value: function subjectMapper(subject) {\n if (typeof subject === 'string') {\n return subject;\n }\n var isFun = typeof subject === 'function';\n if (isFun && this.registry.has(subject)) {\n return this.registry.get(subject);\n }\n if (!isFun && this.registry.has(subject.constructor)) {\n return this.registry.get(subject.constructor);\n }\n return isFun ? subject.name : subject.constructor.name;\n }\n\n /**\n * Removes all rules, policies, and registrations\n *\n * @returns {Acl}\n */\n\n }, {\n key: 'reset',\n value: function reset() {\n this.rules = new Map();\n this.policies = new Map();\n this.registry = new WeakMap();\n return this;\n }\n\n /**\n * Remove rules for subject\n *\n * Optionally limit to a single verb.\n *\n * @param {Object|Function|String} subject\n * @param {?String} [verb=null] an optional verb\n * @returns {Acl}\n */\n\n }, {\n key: 'removeRules',\n value: function removeRules(subject) {\n var verb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n\n var subjectName = this.subjectMapper(subject);\n if (this.rules.has(subjectName)) {\n if (verb) {\n var rules = this.rules.get(subjectName);\n delete rules[verb];\n return this;\n }\n this.rules.delete(subjectName);\n }\n return this;\n }\n\n /**\n * Remove policy for subject\n *\n * @param {Object|Function|String} subject\n * @returns {Acl}\n */\n\n }, {\n key: 'removePolicy',\n value: function removePolicy(subject) {\n var subjectName = this.subjectMapper(subject);\n this.policies.delete(subjectName);\n return this;\n }\n\n /**\n * Convenience method for removing all rules and policies for a subject\n *\n * @param {Object|Function|String} subject\n * @returns {Acl}\n */\n\n }, {\n key: 'removeAll',\n value: function removeAll(subject) {\n this.removeRules(subject);\n this.removePolicy(subject);\n return this;\n }\n }]);\n\n return Acl;\n}();\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Acl);\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// browser-acl.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 4af3caab4ad21c92e6d0","/**\n * Simple ACL library for the browser inspired by Laravel's guards and policies.\n * @class Acl\n */\nclass Acl {\n\n /**\n * browser-acl\n *\n * @access public\n * @param {Boolean} {strict=false}={} Errors out on unknown verbs when true\n * @returns {Acl}\n */\n constructor({strict = false} = {}) {\n this.strict = strict\n this.rules = new Map()\n this.policies = new Map()\n this.registry = new WeakMap()\n }\n\n /**\n * You add rules by providing a verb, a subject and an optional\n * test (that otherwise defaults to true).\n *\n * If the test is a function it will be evaluated with the params:\n * user, subject, and subjectName. The test value is ultimately evaluated\n * for truthiness.\n *\n * Examples:\n *\n * ```javascript\n * acl.rule('create', Post)\n * acl.rule('edit', Post, (user, post) => post.userId === user.id)\n * acl.rule('edit', Post, (user, post, verb, any, other, value, passed) => true)\n * acl.rule('delete', Post, false) // deleting disabled\n * ```\n *\n * @access public\n * @param {Array|string} verbs\n * @param {Function|Object|string} subject\n * @param {Boolean} test=true\n * @returns {Acl}\n */\n rule(verbs, subject, test = true) {\n const subjectName = this.subjectMapper(subject)\n const verbs_ = Array.isArray(verbs) ? verbs : [verbs]\n verbs_.forEach(verb => {\n const rules = this.rules.get(subjectName) || {}\n rules[verb] = test\n this.rules.set(subjectName, rules)\n })\n return this\n }\n\n /**\n * You can group related rules into policies for a subject. The policies\n * properties are verbs and they can plain values or functions.\n *\n * If the policy is a function it will be new'ed up before use.\n *\n * ```javascript\n * class Post {\n * constructor() {\n * this.view = true // no need for a functon\n *\n * this.delete = false // not really necessary since an abscent\n * // verb has the same result\n * },\n * edit(user, post, verb, any, other, value, passed) {\n * return post.id === user.id\n * }\n * }\n * ```\n *\n * Policies are useful for grouping rules and adding more complex logic.\n *\n * @access public\n * @param {Object} policy A policy with properties that are verbs\n * @param {Function|Object|string} subject\n * @returns {Acl}\n */\n policy(policy, subject) {\n const policy_ = typeof policy === 'function' ? new policy() : policy\n const subjectName = this.subjectMapper(subject)\n this.policies.set(subjectName, policy_)\n return this\n }\n\n /**\n * Explicitly map a class or constructor function to a name.\n *\n * You would want to do this in case your code is heavily\n * minified in which case the default mapper cannot use the\n * simple \"reflection\" to resolve the subject name.\n *\n * Note: If you override the subjectMapper this is not used,\n * bud it can be used manually through `this.registry`.\n *\n * @access public\n * @param {Function} klass A class or constructor function\n * @param {string} subjectName\n */\n register(klass, subjectName) {\n this.registry.set(klass, subjectName)\n return this\n }\n\n /**\n * Performs a test if a user can perform action on subject.\n *\n * The action is a verb and the subject can be anything the\n * subjectMapper can map to a subject name.\n *\n * E.g. if you can to test if a user can delete a post you would\n * pass the actual post. Where as if you are testing us a user\n * can create a post you would pass the class function or a\n * string.\n *\n * ```javascript\n * acl->can(user, 'create', Post)\n * acl->can(user, 'edit', post)\n * acl->can(user, 'edit', post, any, other, value, passed)\n * ```\n *\n * Note that these are also available on the user if you've used\n * the mixin:\n *\n * ```javascript\n * user->can('create', Post)\n * user->can('edit', post)\n * ```\n *\n * @access public\n * @param {Object} user\n * @param {string} verb\n * @param {Function|Object|string} subject\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n can(user, verb, subject, ...args) {\n const subjectName = this.subjectMapper(subject)\n let rules = this.policies.get(subjectName) || this.rules.get(subjectName)\n\n if (typeof rules === 'undefined') {\n if (this.strict) {\n throw new Error(`Unknown subject \"${subjectName}\"`)\n }\n return false\n }\n\n if (typeof rules[verb] === 'function') {\n return Boolean(rules[verb](user, subject, subjectName, ...args))\n }\n\n if (this.strict && typeof rules[verb] === 'undefined') {\n throw new Error(`Unknown verb \"${verb}\"`)\n }\n\n return Boolean(rules[verb])\n }\n\n /**\n * Like can but subject is an array where only some has to be\n * true for the rule to match.\n *\n * Note the subjects do not need to be of the same kind.\n *\n * @access public\n * @param {Object} user\n * @param {Array} subjects\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n some(user, verb, subjects, ...args) {\n return subjects.some(s => this.can(user, verb, s, ...args))\n }\n\n /**\n * Like can but subject is an array where all has to be\n * true for the rule to match.\n *\n * Note the subjects do not need to be of the same kind.\n *\n * @access public\n * @param {Object} user\n * @param {Array} subjects\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n every(user, verb, subjects, ...args) {\n return subjects.every(s => this.can(user, verb, s, ...args))\n }\n\n /**\n * Mix in augments your user class with a `can` function object. This\n * is optional and you can always call `can` directly on your\n * Acl instance.\n *\n * ```\n * user.can()\n * user.can.some()\n * user.can.every()\n * ```\n *\n * @access public\n * @param {Function} User A user class or contructor function\n */\n mixin(User) {\n const acl = this\n User.prototype.can = function () {\n return acl.can(this, ...arguments)\n }\n User.prototype.can.every = function () {\n return acl.every(this, ...arguments)\n }\n User.prototype.can.some = function () {\n return acl.some(this, ...arguments)\n }\n return this\n }\n\n /**\n * Rules are grouped by subjects and this default mapper tries to\n * map any non falsy input to a subject name.\n *\n * This is important when you want to try a verb against a rule\n * passing in an instance of a class.\n *\n * - strings becomes subjects\n * - function's names are used for subject\n * - objects's constructor name is used for subject\n *\n * Override this function if your models do not match this approach.\n *\n * E.g. say that you are using plain data objects with a type property\n * to indicate the \"class\" of the object.\n *\n * ```javascript\n * acl.subjectMapper = s => typeof s === 'string' ? s : s.type\n * ```\n *\n * `can` will now use this function when you pass in your objects.\n *\n * See {@link #register register()} for how to manually map\n * classes to subject name.\n *\n * @access public\n * @param {Function|Object|string} subject\n * @returns {string} A subject\n */\n subjectMapper(subject) {\n if (typeof subject === 'string') { return subject }\n const isFun = typeof subject === 'function'\n if (isFun && this.registry.has(subject)) { return this.registry.get(subject) }\n if (!isFun && this.registry.has(subject.constructor)) { return this.registry.get(subject.constructor) }\n return isFun ? subject.name : subject.constructor.name\n }\n\n /**\n * Removes all rules, policies, and registrations\n *\n * @returns {Acl}\n */\n reset() {\n this.rules = new Map()\n this.policies = new Map()\n this.registry = new WeakMap()\n return this\n }\n\n /**\n * Remove rules for subject\n *\n * Optionally limit to a single verb.\n *\n * @param {Object|Function|String} subject\n * @param {?String} [verb=null] an optional verb\n * @returns {Acl}\n */\n removeRules(subject, verb = null) {\n const subjectName = this.subjectMapper(subject)\n if (this.rules.has(subjectName)) {\n if (verb) {\n const rules = this.rules.get(subjectName)\n delete rules[verb]\n return this\n }\n this.rules.delete(subjectName)\n }\n return this\n }\n\n /**\n * Remove policy for subject\n *\n * @param {Object|Function|String} subject\n * @returns {Acl}\n */\n removePolicy(subject) {\n const subjectName = this.subjectMapper(subject)\n this.policies.delete(subjectName)\n return this\n }\n\n /**\n * Convenience method for removing all rules and policies for a subject\n *\n * @param {Object|Function|String} subject\n * @returns {Acl}\n */\n removeAll(subject) {\n this.removeRules(subject)\n this.removePolicy(subject)\n return this\n }\n}\n\nexport default Acl\n\n\n\n// WEBPACK FOOTER //\n// ./index.js"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///browser-acl.js","webpack:///webpack/bootstrap ae43e8332ba730bd90b1","webpack:///./index.js"],"names":["module","exports","modules","__webpack_require__","moduleId","installedModules","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","__webpack_exports__","_classCallCheck","instance","Constructor","TypeError","value","GlobalRule","Acl","_createClass","defineProperties","target","props","length","descriptor","writable","key","protoProps","staticProps","isNameless","fn","_ref","arguments","undefined","_ref$strict","strict","this","rules","Map","policies","registry","WeakMap","verbs","subject","_this","test","subjectName","subjectMapper","Array","isArray","forEach","verb","set","policy","policy_","klass","user","Error","_len","args","_key","Boolean","apply","concat","subjects","_len2","_key2","_this2","some","can","_len3","_key3","_this3","every","User","acl","slice","isFun","has","constructor","delete","removeRules","removePolicy"],"mappings":"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","file":"browser-acl.js","sourcesContent":["module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/*!************************!*\\\n !*** multi ./index.js ***!\n \\************************/\n/*! dynamic exports provided */\n/*! all exports used */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(/*! /Users/mblarsen/workspace/mblarsen/browser-acl/index.js */1);\n\n\n/***/ }),\n/* 1 */\n/*!******************!*\\\n !*** ./index.js ***!\n \\******************/\n/*! exports provided: GlobalRule, default */\n/*! all exports used */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"GlobalRule\", function() { return GlobalRule; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Acl; });\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar GlobalRule = 'GLOBAL_RULE';\n\nvar isNameless = function isNameless(fn) {\n return typeof fn === 'function' && fn.name === '';\n};\n\n/**\n * Simple ACL library for the browser inspired by Laravel's guards and policies.\n */\n\nvar Acl = function () {\n\n /**\n * browser-acl\n *\n * @access public\n * @param {Object} options\n * @param {Boolean} {strict=false}={} Errors out on unknown verbs when true\n * @returns {Acl}\n */\n function Acl() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n _ref$strict = _ref.strict,\n strict = _ref$strict === undefined ? false : _ref$strict;\n\n _classCallCheck(this, Acl);\n\n this.strict = strict;\n this.rules = new Map();\n this.policies = new Map();\n this.registry = new WeakMap();\n }\n\n /**\n * You add rules by providing a verb, a subject and an optional\n * test (that otherwise defaults to true).\n *\n * If the test is a function it will be evaluated with the params:\n * user, subject, and subjectName. The test value is ultimately evaluated\n * for truthiness.\n *\n * Examples:\n *\n * ```javascript\n * acl.rule('create', Post)\n * acl.rule('edit', Post, (user, post) => post.userId === user.id)\n * acl.rule('edit', Post, (user, post, verb, additionalParameter, secondAdditionalParameter) => true)\n * acl.rule('delete', Post, false) // deleting disabled\n * acl.rule('purgeInactive', user => user.isAdmin) // global rule\n * ```\n *\n * @access public\n * @param {Array|string} verbs\n * @param {Function|Object|string} subject?\n * @param {Boolean|Function} test=true\n * @returns {Acl}\n */\n\n\n _createClass(Acl, [{\n key: 'rule',\n value: function rule(verbs, subject) {\n var _this = this;\n\n var test = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n\n if (isNameless(subject)) {\n test = subject;\n subject = GlobalRule;\n }\n var subjectName = this.subjectMapper(subject);\n var verbs_ = Array.isArray(verbs) ? verbs : [verbs];\n verbs_.forEach(function (verb) {\n var rules = _this.rules.get(subjectName) || {};\n rules[verb] = test;\n _this.rules.set(subjectName, rules);\n });\n return this;\n }\n\n /**\n * You can group related rules into policies for a subject. The policies\n * properties are verbs and they can plain values or functions.\n *\n * If the policy is a function it will be new'ed up before use.\n *\n * ```javascript\n * class Post {\n * constructor() {\n * this.view = true // no need for a functon\n *\n * this.delete = false // not really necessary since an abscent\n * // verb has the same result\n * },\n * edit(user, post, verb, additionalParameter, secondAdditionalParameter) {\n * return post.id === user.id\n * }\n * }\n * ```\n *\n * Policies are useful for grouping rules and adding more complex logic.\n *\n * @access public\n * @param {Object} policy A policy with properties that are verbs\n * @param {Function|Object|string} subject\n * @returns {Acl}\n */\n\n }, {\n key: 'policy',\n value: function policy(_policy, subject) {\n var policy_ = typeof _policy === 'function' ? new _policy() : _policy;\n var subjectName = this.subjectMapper(subject);\n this.policies.set(subjectName, policy_);\n return this;\n }\n\n /**\n * Explicitly map a class or constructor function to a name.\n *\n * You would want to do this in case your code is heavily\n * minified in which case the default mapper cannot use the\n * simple \"reflection\" to resolve the subject name.\n *\n * Note: If you override the subjectMapper this is not used,\n * bud it can be used manually through `this.registry`.\n *\n * @access public\n * @param {Function} klass A class or constructor function\n * @param {string} subjectName\n */\n\n }, {\n key: 'register',\n value: function register(klass, subjectName) {\n this.registry.set(klass, subjectName);\n return this;\n }\n\n /**\n * Performs a test if a user can perform action on subject.\n *\n * The action is a verb and the subject can be anything the\n * subjectMapper can map to a subject name.\n *\n * E.g. if you can to test if a user can delete a post you would\n * pass the actual post. Where as if you are testing us a user\n * can create a post you would pass the class function or a\n * string.\n *\n * ```javascript\n * acl->can(user, 'create', Post)\n * acl->can(user, 'edit', post)\n * acl->can(user, 'edit', post, additionalParameter, secondAdditionalParameter)\n * ```\n *\n * Note that these are also available on the user if you've used\n * the mixin:\n *\n * ```javascript\n * user->can('create', Post)\n * user->can('edit', post)\n * ```\n *\n * @access public\n * @param {Object} user\n * @param {string} verb\n * @param {Function|Object|string} subject\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n\n }, {\n key: 'can',\n value: function can(user, verb, subject) {\n subject = typeof subject === 'undefined' ? GlobalRule : subject;\n var subjectName = this.subjectMapper(subject);\n\n var rules = this.policies.get(subjectName) || this.rules.get(subjectName);\n\n if (typeof rules === 'undefined') {\n if (this.strict) {\n throw new Error('Unknown subject \"' + subjectName + '\"');\n }\n return false;\n }\n\n if (typeof rules[verb] === 'function') {\n for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {\n args[_key - 3] = arguments[_key];\n }\n\n return Boolean(rules[verb].apply(rules, [user, subject, subjectName].concat(args)));\n }\n\n if (this.strict && typeof rules[verb] === 'undefined') {\n throw new Error('Unknown verb \"' + verb + '\"');\n }\n\n return Boolean(rules[verb]);\n }\n\n /**\n * Like can but subject is an array where only some has to be\n * true for the rule to match.\n *\n * Note the subjects do not need to be of the same kind.\n *\n * @access public\n * @param {Object} user\n * @param {Array} subjects\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n\n }, {\n key: 'some',\n value: function some(user, verb, subjects) {\n for (var _len2 = arguments.length, args = Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {\n args[_key2 - 3] = arguments[_key2];\n }\n\n var _this2 = this;\n\n return subjects.some(function (s) {\n return _this2.can.apply(_this2, [user, verb, s].concat(args));\n });\n }\n\n /**\n * Like can but subject is an array where all has to be\n * true for the rule to match.\n *\n * Note the subjects do not need to be of the same kind.\n *\n * @access public\n * @param {Object} user\n * @param {Array} subjects\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n\n }, {\n key: 'every',\n value: function every(user, verb, subjects) {\n for (var _len3 = arguments.length, args = Array(_len3 > 3 ? _len3 - 3 : 0), _key3 = 3; _key3 < _len3; _key3++) {\n args[_key3 - 3] = arguments[_key3];\n }\n\n var _this3 = this;\n\n return subjects.every(function (s) {\n return _this3.can.apply(_this3, [user, verb, s].concat(args));\n });\n }\n\n /**\n * Mix in augments your user class with a `can` function object. This\n * is optional and you can always call `can` directly on your\n * Acl instance.\n *\n * ```\n * user.can()\n * user.can.some()\n * user.can.every()\n * ```\n *\n * @access public\n * @param {Function} User A user class or contructor function\n */\n\n }, {\n key: 'mixin',\n value: function mixin(User) {\n var acl = this;\n User.prototype.can = function () {\n return acl.can.apply(acl, [this].concat(Array.prototype.slice.call(arguments)));\n };\n User.prototype.can.every = function () {\n return acl.every.apply(acl, [this].concat(Array.prototype.slice.call(arguments)));\n };\n User.prototype.can.some = function () {\n return acl.some.apply(acl, [this].concat(Array.prototype.slice.call(arguments)));\n };\n return this;\n }\n\n /**\n * Rules are grouped by subjects and this default mapper tries to\n * map any non falsy input to a subject name.\n *\n * This is important when you want to try a verb against a rule\n * passing in an instance of a class.\n *\n * - strings becomes subjects\n * - function's names are used for subject\n * - objects's constructor name is used for subject\n *\n * Override this function if your models do not match this approach.\n *\n * E.g. say that you are using plain data objects with a type property\n * to indicate the \"class\" of the object.\n *\n * ```javascript\n * acl.subjectMapper = s => typeof s === 'string' ? s : s.type\n * ```\n *\n * `can` will now use this function when you pass in your objects.\n *\n * See {@link #register register()} for how to manually map\n * classes to subject name.\n *\n * @access public\n * @param {Function|Object|string} subject\n * @returns {string} A subject\n */\n\n }, {\n key: 'subjectMapper',\n value: function subjectMapper(subject) {\n if (typeof subject === 'string') {\n return subject;\n }\n var isFun = typeof subject === 'function';\n if (isFun && this.registry.has(subject)) {\n return this.registry.get(subject);\n }\n if (!isFun && this.registry.has(subject.constructor)) {\n return this.registry.get(subject.constructor);\n }\n return isFun ? subject.name : subject.constructor.name;\n }\n\n /**\n * Removes all rules, policies, and registrations\n *\n * @returns {Acl}\n */\n\n }, {\n key: 'reset',\n value: function reset() {\n this.rules = new Map();\n this.policies = new Map();\n this.registry = new WeakMap();\n return this;\n }\n\n /**\n * Remove rules for subject\n *\n * Optionally limit to a single verb.\n *\n * @param {Object|Function|String} subject\n * @param {?String} [verb=null] an optional verb\n * @returns {Acl}\n */\n\n }, {\n key: 'removeRules',\n value: function removeRules(subject) {\n var verb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n\n var subjectName = this.subjectMapper(subject);\n if (this.rules.has(subjectName)) {\n if (verb) {\n var rules = this.rules.get(subjectName);\n delete rules[verb];\n return this;\n }\n this.rules.delete(subjectName);\n }\n return this;\n }\n\n /**\n * Remove policy for subject\n *\n * @param {Object|Function|String} subject\n * @returns {Acl}\n */\n\n }, {\n key: 'removePolicy',\n value: function removePolicy(subject) {\n var subjectName = this.subjectMapper(subject);\n this.policies.delete(subjectName);\n return this;\n }\n\n /**\n * Convenience method for removing all rules and policies for a subject\n *\n * @param {Object|Function|String} subject\n * @returns {Acl}\n */\n\n }, {\n key: 'removeAll',\n value: function removeAll(subject) {\n this.removeRules(subject);\n this.removePolicy(subject);\n return this;\n }\n }]);\n\n return Acl;\n}();\n\n\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// browser-acl.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap ae43e8332ba730bd90b1","\nexport const GlobalRule = 'GLOBAL_RULE'\n\nconst isNameless = fn => typeof fn === 'function' && fn.name === ''\n\n/**\n * Simple ACL library for the browser inspired by Laravel's guards and policies.\n */\nexport default class Acl {\n\n /**\n * browser-acl\n *\n * @access public\n * @param {Object} options\n * @param {Boolean} {strict=false}={} Errors out on unknown verbs when true\n * @returns {Acl}\n */\n constructor({strict = false} = {}) {\n this.strict = strict\n this.rules = new Map()\n this.policies = new Map()\n this.registry = new WeakMap()\n }\n\n /**\n * You add rules by providing a verb, a subject and an optional\n * test (that otherwise defaults to true).\n *\n * If the test is a function it will be evaluated with the params:\n * user, subject, and subjectName. The test value is ultimately evaluated\n * for truthiness.\n *\n * Examples:\n *\n * ```javascript\n * acl.rule('create', Post)\n * acl.rule('edit', Post, (user, post) => post.userId === user.id)\n * acl.rule('edit', Post, (user, post, verb, additionalParameter, secondAdditionalParameter) => true)\n * acl.rule('delete', Post, false) // deleting disabled\n * acl.rule('purgeInactive', user => user.isAdmin) // global rule\n * ```\n *\n * @access public\n * @param {Array|string} verbs\n * @param {Function|Object|string} subject?\n * @param {Boolean|Function} test=true\n * @returns {Acl}\n */\n rule(verbs, subject, test = true) {\n if (isNameless(subject)) {\n test = subject\n subject = GlobalRule\n }\n const subjectName = this.subjectMapper(subject)\n const verbs_ = Array.isArray(verbs) ? verbs : [verbs]\n verbs_.forEach(verb => {\n const rules = this.rules.get(subjectName) || {}\n rules[verb] = test\n this.rules.set(subjectName, rules)\n })\n return this\n }\n\n /**\n * You can group related rules into policies for a subject. The policies\n * properties are verbs and they can plain values or functions.\n *\n * If the policy is a function it will be new'ed up before use.\n *\n * ```javascript\n * class Post {\n * constructor() {\n * this.view = true // no need for a functon\n *\n * this.delete = false // not really necessary since an abscent\n * // verb has the same result\n * },\n * edit(user, post, verb, additionalParameter, secondAdditionalParameter) {\n * return post.id === user.id\n * }\n * }\n * ```\n *\n * Policies are useful for grouping rules and adding more complex logic.\n *\n * @access public\n * @param {Object} policy A policy with properties that are verbs\n * @param {Function|Object|string} subject\n * @returns {Acl}\n */\n policy(policy, subject) {\n const policy_ = typeof policy === 'function' ? new policy() : policy\n const subjectName = this.subjectMapper(subject)\n this.policies.set(subjectName, policy_)\n return this\n }\n\n /**\n * Explicitly map a class or constructor function to a name.\n *\n * You would want to do this in case your code is heavily\n * minified in which case the default mapper cannot use the\n * simple \"reflection\" to resolve the subject name.\n *\n * Note: If you override the subjectMapper this is not used,\n * bud it can be used manually through `this.registry`.\n *\n * @access public\n * @param {Function} klass A class or constructor function\n * @param {string} subjectName\n */\n register(klass, subjectName) {\n this.registry.set(klass, subjectName)\n return this\n }\n\n /**\n * Performs a test if a user can perform action on subject.\n *\n * The action is a verb and the subject can be anything the\n * subjectMapper can map to a subject name.\n *\n * E.g. if you can to test if a user can delete a post you would\n * pass the actual post. Where as if you are testing us a user\n * can create a post you would pass the class function or a\n * string.\n *\n * ```javascript\n * acl->can(user, 'create', Post)\n * acl->can(user, 'edit', post)\n * acl->can(user, 'edit', post, additionalParameter, secondAdditionalParameter)\n * ```\n *\n * Note that these are also available on the user if you've used\n * the mixin:\n *\n * ```javascript\n * user->can('create', Post)\n * user->can('edit', post)\n * ```\n *\n * @access public\n * @param {Object} user\n * @param {string} verb\n * @param {Function|Object|string} subject\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n can(user, verb, subject, ...args) {\n subject = typeof subject === 'undefined' ? GlobalRule : subject\n const subjectName = this.subjectMapper(subject)\n\n let rules = this.policies.get(subjectName) || this.rules.get(subjectName)\n\n if (typeof rules === 'undefined') {\n if (this.strict) {\n throw new Error(`Unknown subject \"${subjectName}\"`)\n }\n return false\n }\n\n if (typeof rules[verb] === 'function') {\n return Boolean(rules[verb](user, subject, subjectName, ...args))\n }\n\n if (this.strict && typeof rules[verb] === 'undefined') {\n throw new Error(`Unknown verb \"${verb}\"`)\n }\n\n return Boolean(rules[verb])\n }\n\n /**\n * Like can but subject is an array where only some has to be\n * true for the rule to match.\n *\n * Note the subjects do not need to be of the same kind.\n *\n * @access public\n * @param {Object} user\n * @param {Array} subjects\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n some(user, verb, subjects, ...args) {\n return subjects.some(s => this.can(user, verb, s, ...args))\n }\n\n /**\n * Like can but subject is an array where all has to be\n * true for the rule to match.\n *\n * Note the subjects do not need to be of the same kind.\n *\n * @access public\n * @param {Object} user\n * @param {Array} subjects\n * @param {...*} args Any other param is passed into rule\n * @return Boolean\n */\n every(user, verb, subjects, ...args) {\n return subjects.every(s => this.can(user, verb, s, ...args))\n }\n\n /**\n * Mix in augments your user class with a `can` function object. This\n * is optional and you can always call `can` directly on your\n * Acl instance.\n *\n * ```\n * user.can()\n * user.can.some()\n * user.can.every()\n * ```\n *\n * @access public\n * @param {Function} User A user class or contructor function\n */\n mixin(User) {\n const acl = this\n User.prototype.can = function () {\n return acl.can(this, ...arguments)\n }\n User.prototype.can.every = function () {\n return acl.every(this, ...arguments)\n }\n User.prototype.can.some = function () {\n return acl.some(this, ...arguments)\n }\n return this\n }\n\n /**\n * Rules are grouped by subjects and this default mapper tries to\n * map any non falsy input to a subject name.\n *\n * This is important when you want to try a verb against a rule\n * passing in an instance of a class.\n *\n * - strings becomes subjects\n * - function's names are used for subject\n * - objects's constructor name is used for subject\n *\n * Override this function if your models do not match this approach.\n *\n * E.g. say that you are using plain data objects with a type property\n * to indicate the \"class\" of the object.\n *\n * ```javascript\n * acl.subjectMapper = s => typeof s === 'string' ? s : s.type\n * ```\n *\n * `can` will now use this function when you pass in your objects.\n *\n * See {@link #register register()} for how to manually map\n * classes to subject name.\n *\n * @access public\n * @param {Function|Object|string} subject\n * @returns {string} A subject\n */\n subjectMapper(subject) {\n if (typeof subject === 'string') { return subject }\n const isFun = typeof subject === 'function'\n if (isFun && this.registry.has(subject)) { return this.registry.get(subject) }\n if (!isFun && this.registry.has(subject.constructor)) { return this.registry.get(subject.constructor) }\n return isFun ? subject.name : subject.constructor.name\n }\n\n /**\n * Removes all rules, policies, and registrations\n *\n * @returns {Acl}\n */\n reset() {\n this.rules = new Map()\n this.policies = new Map()\n this.registry = new WeakMap()\n return this\n }\n\n /**\n * Remove rules for subject\n *\n * Optionally limit to a single verb.\n *\n * @param {Object|Function|String} subject\n * @param {?String} [verb=null] an optional verb\n * @returns {Acl}\n */\n removeRules(subject, verb = null) {\n const subjectName = this.subjectMapper(subject)\n if (this.rules.has(subjectName)) {\n if (verb) {\n const rules = this.rules.get(subjectName)\n delete rules[verb]\n return this\n }\n this.rules.delete(subjectName)\n }\n return this\n }\n\n /**\n * Remove policy for subject\n *\n * @param {Object|Function|String} subject\n * @returns {Acl}\n */\n removePolicy(subject) {\n const subjectName = this.subjectMapper(subject)\n this.policies.delete(subjectName)\n return this\n }\n\n /**\n * Convenience method for removing all rules and policies for a subject\n *\n * @param {Object|Function|String} subject\n * @returns {Acl}\n */\n removeAll(subject) {\n this.removeRules(subject)\n this.removePolicy(subject)\n return this\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./index.js"],"sourceRoot":""} \ No newline at end of file diff --git a/package.json b/package.json index b6dd57e..30ae672 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "browser-acl", "description": "Simple ACL library for the browser inspired by Laravel's guards and policies.", - "version": "0.4.0", + "version": "0.5.0", "author": "Michael Bøcker-Larsen ", "main": "dist/browser-acl.js", "files": [