diff --git a/dist/browser-acl.js b/dist/browser-acl.js index 617e65a..58f62c2 100644 --- a/dist/browser-acl.js +++ b/dist/browser-acl.js @@ -1,2 +1,2 @@ -(function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="/",e(e.s=0)})([function(t,e,n){t.exports=n(1)},function(t,e,n){"use strict";function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var o=function(){function t(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{},n=e.strict,o=void 0!==n&&n;r(this,t),this.strict=o,this.rules=new Map,this.policies=new Map}return o(t,[{key:"rule",value:function(t,e){var n=this,r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],o=this.subjectMapper(e);return(Array.isArray(t)?t:[t]).forEach(function(t){var e=n.rules.get(o)||{};e[t]=r,n.rules.set(o,e)}),this}},{key:"policy",value:function(t,e){var n=("function"==typeof t&&new t,this.subjectMapper(e));return this.policies.set(n,t),this}},{key:"can",value:function(t,e,n){var r=this.subjectMapper(n),o=this.policies.get(r)||this.rules.get(r)||{};if("function"==typeof o[e])return Boolean(o[e](t,n,r));if(this.strict&&void 0===o[e])throw new Error('Unknown verb "'+e+'"');return Boolean(o[e])}},{key:"mixin",value:function(t){var e=this;t.prototype.can=function(){return e.can.apply(e,[this].concat(Array.prototype.slice.call(arguments)))}}},{key:"subjectMapper",value:function(t){return"string"==typeof t?t:"function"==typeof t?t.name:t.constructor.name}}]),t}();e.default=i}]); +module.exports=function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="/",e(e.s=0)}([function(t,e,n){t.exports=n(1)},function(t,e,n){"use strict";function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var o=function(){function t(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{},n=e.strict,o=void 0!==n&&n;r(this,t),this.strict=o,this.rules=new Map,this.policies=new Map}return o(t,[{key:"rule",value:function(t,e){var n=this,r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],o=this.subjectMapper(e);return(Array.isArray(t)?t:[t]).forEach(function(t){var e=n.rules.get(o)||{};e[t]=r,n.rules.set(o,e)}),this}},{key:"policy",value:function(t,e){var n=("function"==typeof t&&new t,this.subjectMapper(e));return this.policies.set(n,t),this}},{key:"can",value:function(t,e,n){var r=this.subjectMapper(n),o=this.policies.get(r)||this.rules.get(r)||{};if("function"==typeof o[e])return Boolean(o[e](t,n,r));if(this.strict&&void 0===o[e])throw new Error('Unknown verb "'+e+'"');return Boolean(o[e])}},{key:"mixin",value:function(t){var e=this;t.prototype.can=function(){return e.can.apply(e,[this].concat(Array.prototype.slice.call(arguments)))}}},{key:"subjectMapper",value:function(t){return"string"==typeof t?t:"function"==typeof t?t.name:t.constructor.name}}]),t}();e.default=i}]); //# 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 5af3331..c67185b 100644 --- a/dist/browser-acl.js.map +++ b/dist/browser-acl.js.map @@ -1 +1 @@ -{"version":3,"sources":["/Users/mblarsen/workspace/mblarsen/browser-acl/browser-acl.js","/Users/mblarsen/workspace/mblarsen/browser-acl/webpack/bootstrap ed053f871b8235ef7f3a","/Users/mblarsen/workspace/mblarsen/browser-acl/index.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","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","verbs","subject","_this","test","subjectName","subjectMapper","Array","isArray","forEach","verb","set","policy","subject_","user","Boolean","Error","User","acl","can","apply","concat","slice","constructor"],"mappings":"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","file":"browser-acl.js","sourcesContent":["/******/ (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 }\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 thruthiness.\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, subject) {\n * return subject.id === user.id\n * }\n * }\n * ```\n *\n * Policies are useful for grouping rules and adding more comples 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 subject_ = this.subjectMapper(subject);\n this.policies.set(subject_, _policy);\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 * ```\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 * @return Boolean\n */\n\n }, {\n key: 'can',\n value: function can(user, verb, subject) {\n var subject_ = this.subjectMapper(subject);\n var rules = this.policies.get(subject_) || this.rules.get(subject_) || {};\n if (typeof rules[verb] === 'function') {\n return Boolean(rules[verb](user, subject, subject_));\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 * Mix in augments your user class with a `can` function. This\n * is optional and you can always call `can` directly on your\n * Acl instance.\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 }\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 = subject => subject.type\n * ```\n *\n * `can` will now use this function when you pass in your objects.\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 return typeof subject === 'function' ? subject.name : subject.constructor.name;\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 ed053f871b8235ef7f3a","/**\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 }\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 thruthiness.\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, subject) {\n * return subject.id === user.id\n * }\n * }\n * ```\n *\n * Policies are useful for grouping rules and adding more comples 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 subject_ = this.subjectMapper(subject)\n this.policies.set(subject_, policy)\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 * ```\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 * @return Boolean\n */\n can(user, verb, subject) {\n const subject_ = this.subjectMapper(subject)\n const rules = this.policies.get(subject_) || this.rules.get(subject_) || {}\n if (typeof rules[verb] === 'function') {\n return Boolean(rules[verb](user, subject, subject_))\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 * Mix in augments your user class with a `can` function. This\n * is optional and you can always call `can` directly on your\n * Acl instance.\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 }\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 = subject => subject.type\n * ```\n *\n * `can` will now use this function when you pass in your objects.\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 return typeof subject === 'function'\n ? subject.name\n : subject.constructor.name\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":["/Users/mblarsen/workspace/mblarsen/browser-acl/browser-acl.js","/Users/mblarsen/workspace/mblarsen/browser-acl/webpack/bootstrap a0d3176f8d81e2be3ffa","/Users/mblarsen/workspace/mblarsen/browser-acl/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","verbs","subject","_this","test","subjectName","subjectMapper","Array","isArray","forEach","verb","set","policy","subject_","user","Boolean","Error","User","acl","can","apply","concat","slice","constructor"],"mappings":"AAAAA,OAAOC,QACE,SAAUC,GCGnB,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAH,OAGA,IAAAD,GAAAK,EAAAD,IACAE,EAAAF,EACAG,GAAA,EACAN,WAUA,OANAC,GAAAE,GAAAI,KAAAR,EAAAC,QAAAD,IAAAC,QAAAE,GAGAH,EAAAO,GAAA,EAGAP,EAAAC,QAvBA,GAAAI,KA4DA,OAhCAF,GAAAM,EAAAP,EAGAC,EAAAO,EAAAL,EAGAF,EAAAQ,EAAA,SAAAV,EAAAW,EAAAC,GACAV,EAAAW,EAAAb,EAAAW,IACAG,OAAAC,eAAAf,EAAAW,GACAK,cAAA,EACAC,YAAA,EACAC,IAAAN,KAMAV,EAAAiB,EAAA,SAAApB,GACA,GAAAa,GAAAb,KAAAqB,WACA,WAA2B,MAAArB,GAAA,SAC3B,WAAiC,MAAAA,GAEjC,OADAG,GAAAQ,EAAAE,EAAA,IAAAA,GACAA,GAIAV,EAAAW,EAAA,SAAAQ,EAAAC,GAAsD,MAAAR,QAAAS,UAAAC,eAAAjB,KAAAc,EAAAC,IAGtDpB,EAAAuB,EAAA,IAGAvB,IAAAwB,EAAA,KDYM,SAAU3B,EAAQC,EAASE,GAEjCH,EAAOC,QAAUE,EAAkF,IAU7F,SAAUH,EAAQ4B,EAAqBzB,GAE7C,YAIA,SAAS0B,GAAgBC,EAAUC,GAAe,KAAMD,YAAoBC,IAAgB,KAAM,IAAIC,WAAU,qCAHhHjB,OAAOC,eAAeY,EAAqB,cAAgBK,OAAO,GAClE,IAAIC,GAAe,WAAc,QAASC,GAAiBC,EAAQC,GAAS,IAAK,GAAI/B,GAAI,EAAGA,EAAI+B,EAAMC,OAAQhC,IAAK,CAAE,GAAIiC,GAAaF,EAAM/B,EAAIiC,GAAWrB,WAAaqB,EAAWrB,aAAc,EAAOqB,EAAWtB,cAAe,EAAU,SAAWsB,KAAYA,EAAWC,UAAW,GAAMzB,OAAOC,eAAeoB,EAAQG,EAAWE,IAAKF,IAAiB,MAAO,UAAUR,EAAaW,EAAYC,GAAiJ,MAA9HD,IAAYP,EAAiBJ,EAAYP,UAAWkB,GAAiBC,GAAaR,EAAiBJ,EAAaY,GAAqBZ,MErF1hBa,EF6FI,WEpFR,QAAAA,KAAmC,GAAAC,GAAAC,UAAAR,OAAA,OAAAS,KAAAD,UAAA,GAAAA,UAAA,MAAAE,EAAAH,EAAtBI,aAAsBF,KAAAC,IAAAnB,GAAAqB,KAAAN,GACjCM,KAAKD,OAASA,EACdC,KAAKC,MAAQ,GAAIC,KACjBF,KAAKG,SAAW,GAAID,KFiRtB,MA3JAlB,GAAaU,IACXH,IAAK,OACLR,MAAO,SEvGJqB,EAAOC,GAAsB,GAAAC,GAAAN,KAAbO,IAAaX,UAAAR,OAAA,OAAAS,KAAAD,UAAA,KAAAA,UAAA,GAC1BY,EAAcR,KAAKS,cAAcJ,EAOvC,QANeK,MAAMC,QAAQP,GAASA,GAASA,IACxCQ,QAAQ,SAAAC,GACb,GAAMZ,GAAQK,EAAKL,MAAMhC,IAAIuC,MAC7BP,GAAMY,GAAQN,EACdD,EAAKL,MAAMa,IAAIN,EAAaP,KAEvBD,QF2IPT,IAAK,SACLR,MAAO,SE9GFgC,EAAQV,GACb,GACMW,IAD4B,kBAAXD,IAAwB,GAAIA,GAClCf,KAAKS,cAAcJ,GAEpC,OADAL,MAAKG,SAASW,IAAIE,EAAUD,GACrBf,QFiJPT,IAAK,MACLR,MAAO,SEjHLkC,EAAMJ,EAAMR,GACd,GAAMW,GAAWhB,KAAKS,cAAcJ,GAC9BJ,EAAQD,KAAKG,SAASlC,IAAI+C,IAAahB,KAAKC,MAAMhC,IAAI+C,MAC5D,IAA2B,kBAAhBf,GAAMY,GACf,MAAOK,SAAQjB,EAAMY,GAAMI,EAAMZ,EAASW,GAG5C,IAAIhB,KAAKD,YAAiC,KAAhBE,EAAMY,GAC9B,KAAM,IAAIM,OAAJ,iBAA2BN,EAA3B,IAGR,OAAOK,SAAQjB,EAAMY,OF6HrBtB,IAAK,QACLR,MAAO,SEpHHqC,GACJ,GAAMC,GAAMrB,IACZoB,GAAK9C,UAAUgD,IAAM,WACnB,MAAOD,GAAIC,IAAJC,MAAAF,GAAQrB,MAARwB,OAAAd,MAAApC,UAAAmD,MAAAnE,KAAiBsC,iBFoJ1BL,IAAK,gBACLR,MAAO,SEvHKsB,GACZ,MAAuB,gBAAZA,GAA+BA,EAChB,kBAAZA,GACVA,EAAQ3C,KACR2C,EAAQqB,YAAYhE,SF2HnBgC,IEvHThB,GAAA","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 }\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 thruthiness.\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, subject) {\n * return subject.id === user.id\n * }\n * }\n * ```\n *\n * Policies are useful for grouping rules and adding more comples 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 subject_ = this.subjectMapper(subject);\n this.policies.set(subject_, _policy);\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 * ```\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 * @return Boolean\n */\n\n }, {\n key: 'can',\n value: function can(user, verb, subject) {\n var subject_ = this.subjectMapper(subject);\n var rules = this.policies.get(subject_) || this.rules.get(subject_) || {};\n if (typeof rules[verb] === 'function') {\n return Boolean(rules[verb](user, subject, subject_));\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 * Mix in augments your user class with a `can` function. This\n * is optional and you can always call `can` directly on your\n * Acl instance.\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 }\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 = subject => subject.type\n * ```\n *\n * `can` will now use this function when you pass in your objects.\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 return typeof subject === 'function' ? subject.name : subject.constructor.name;\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 a0d3176f8d81e2be3ffa","/**\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 }\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 thruthiness.\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, subject) {\n * return subject.id === user.id\n * }\n * }\n * ```\n *\n * Policies are useful for grouping rules and adding more comples 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 subject_ = this.subjectMapper(subject)\n this.policies.set(subject_, policy)\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 * ```\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 * @return Boolean\n */\n can(user, verb, subject) {\n const subject_ = this.subjectMapper(subject)\n const rules = this.policies.get(subject_) || this.rules.get(subject_) || {}\n if (typeof rules[verb] === 'function') {\n return Boolean(rules[verb](user, subject, subject_))\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 * Mix in augments your user class with a `can` function. This\n * is optional and you can always call `can` directly on your\n * Acl instance.\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 }\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 = subject => subject.type\n * ```\n *\n * `can` will now use this function when you pass in your objects.\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 return typeof subject === 'function'\n ? subject.name\n : subject.constructor.name\n }\n}\n\nexport default Acl\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 4b99884..b30ba35 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.1.5", + "version": "0.2.0", "main": "dist/browser-acl.js", "files": [ "dist"