You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@casl/ability

Package Overview
Dependencies
Maintainers
1
Versions
88
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@casl/ability - npm Package Compare versions

Comparing version
5.4.2
to
5.4.3
+7
-0
CHANGELOG.md

@@ -5,2 +5,9 @@ # Change Log

## [5.4.3](https://github.com/stalniy/casl/compare/@casl/ability@5.4.2...@casl/ability@5.4.3) (2021-08-17)
### Bug Fixes
* **release:** force release because of disable pre/post hook execution of pnpm ([39c20f6](https://github.com/stalniy/casl/commit/39c20f60d9bbaaa31dff8d5ed11286fae72db558))
## [5.4.2](https://github.com/stalniy/casl/compare/@casl/ability@5.4.1...@casl/ability@5.4.2) (2021-08-17)

@@ -7,0 +14,0 @@

+1
-1

@@ -1,2 +0,2 @@

import{createFactory as t,$eq as r,$ne as i,$lt as n,$lte as e,$gt as u,$gte as o,$in as s,$nin as f,$all as a,$size as c,$regex as h,$options as v,$elemMatch as l,$exists as d,eq as b,ne as y,lt as p,lte as w,gt as g,gte as E,within as A,nin as $,all as j,size as m,regex as M,elemMatch as x,exists as O,and as F}from"@ucast/mongo2js";function _(t,r){for(var i=0;i<r.length;i++){var n=r[i];n.enumerable=n.enumerable||false;n.configurable=true;if("value"in n)n.writable=true;Object.defineProperty(t,n.key,n)}}function P(t,r,i){if(r)_(t.prototype,r);if(i)_(t,i);return t}function R(){R=Object.assign||function(t){for(var r=1;r<arguments.length;r++){var i=arguments[r];for(var n in i)if(Object.prototype.hasOwnProperty.call(i,n))t[n]=i[n]}return t};return R.apply(this,arguments)}function k(t,r){t.prototype=Object.create(r.prototype);t.prototype.constructor=t;B(t,r)}function B(t,r){B=Object.setPrototypeOf||function t(r,i){r.__proto__=i;return r};return B(t,r)}function C(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function T(t){return Array.isArray(t)?t:[t]}var q="__caslSubjectType__";function z(t,r){if(r)if(!r.hasOwnProperty(q))Object.defineProperty(r,q,{value:t});else if(t!==r[q])throw new Error("Trying to cast object to subject type "+t+" but previously it was casted to "+r[q]);return r}var S=function t(r){var i=typeof r;return"string"===i||"function"===i};var Y=function t(r){return r.modelName||r.name};var D=function t(r){return"string"===typeof r?r:Y(r)};function L(t){if(t.hasOwnProperty(q))return t[q];return Y(t.constructor)}function G(t,r,i){var n=T(r);var e=0;while(e<n.length){var u=n[e++];if(t.hasOwnProperty(u))n=i(n,t[u])}return n}function H(t,r){if("string"===typeof r&&-1!==t.indexOf(r))return r;for(var i=0;i<r.length;i++)if(-1!==t.indexOf(r[i]))return r[i];return null}var I=function t(r,i){return r.concat(i)};function J(t,r){if(r in t)throw new Error('Cannot use "'+r+"\" as an alias because it's reserved action.");var i=Object.keys(t);var n=function t(i,n){var e=H(i,n);if(e)throw new Error("Detected cycle "+e+" -> "+i.join(", "));var u="string"===typeof n&&n===r||-1!==i.indexOf(r)||Array.isArray(n)&&-1!==n.indexOf(r);if(u)throw new Error('Cannot make an alias to "'+r+'" because this is reserved action');return i.concat(n)};for(var e=0;e<i.length;e++)G(t,i[e],n)}function K(t,r){if(!r||false!==r.skipValidate)J(t,r&&r.anyAction||"manage");return function(r){return G(t,r,I)}}function N(t,r,i){for(var n=i;n<r.length;n++)t.push(r[n])}function Q(t,r){if(!t||!t.length)return r||[];if(!r||!r.length)return t||[];var i=0;var n=0;var e=[];while(i<t.length&&n<r.length)if(t[i].priority<r[n].priority){e.push(t[i]);i++}else{e.push(r[n]);n++}N(e,t,i);N(e,r,n);return e}function U(t,r,i){var n=t.get(r);if(!n){n=i();t.set(r,n)}return n}var V=function t(r){return r};function W(t,r){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!r.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!r.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}var X=function(){function t(t,r,i){if(void 0===i)i=0;W(t,r);this.action=r.resolveAction(t.action);this.subject=t.subject;this.inverted=!!t.inverted;this.conditions=t.conditions;this.reason=t.reason;this.fields=t.fields?T(t.fields):void 0;this.priority=i;this.t=r}var r=t.prototype;r.i=function t(){if(this.conditions&&!this.u)this.u=this.t.conditionsMatcher(this.conditions);return this.u};r.matchesConditions=function t(r){if(!this.conditions)return true;if(!r||S(r))return!this.inverted;var i=this.i();return i(r)};r.matchesField=function t(r){if(!this.fields)return true;if(!r)return!this.inverted;if(this.fields&&!this.o)this.o=this.t.fieldMatcher(this.fields);return this.o(r)};P(t,[{key:"ast",get:function t(){var r=this.i();return r?r.ast:void 0}}]);return t}();function Z(t,r){var i={value:t,prev:r,next:null};if(r)r.next=i;return i}function tt(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}var rt=function t(r){return{value:r.value,prev:r.prev,next:r.next}};var it=function t(){return{rules:[],merged:false}};var nt=function t(){return new Map};var et=function t(r,i){if(!r.h&&i.fields)r.h=true};var ut=function(){function t(t,r){if(void 0===t)t=[];if(void 0===r)r={};this.h=false;this.v=new Map;this.l={conditionsMatcher:r.conditionsMatcher,fieldMatcher:r.fieldMatcher,resolveAction:r.resolveAction||V};this.p=r.anyAction||"manage";this.g=r.anySubjectType||"all";this.A=r.detectSubjectType||L;this.$=t;this.j=this.m(t)}var r=t.prototype;r.detectSubjectType=function t(r){if(S(r))return r;if(!r)return this.g;return this.A(r)};r.update=function t(r){var i={rules:r,ability:this,target:this};this.M("update",i);this.$=r;this.j=this.m(r);this.M("updated",i);return this};r.m=function t(r){var i=new Map;for(var n=r.length-1;n>=0;n--){var e=r.length-n-1;var u=new X(r[n],this.l,e);var o=T(u.action);var s=T(u.subject||this.g);et(this,u);for(var f=0;f<s.length;f++){var a=U(i,s[f],nt);for(var c=0;c<o.length;c++)U(a,o[c],it).rules.push(u)}}return i};r.possibleRulesFor=function t(r,i){if(void 0===i)i=this.g;if(!S(i))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');var n=U(this.j,i,nt);var e=U(n,r,it);if(e.merged)return e.rules;var u=r!==this.p&&n.has(this.p)?n.get(this.p).rules:void 0;var o=Q(e.rules,u);if(i!==this.g)o=Q(o,this.possibleRulesFor(r,this.g));e.rules=o;e.merged=true;return o};r.rulesFor=function t(r,i,n){var e=this.possibleRulesFor(r,i);if(n&&"string"!==typeof n)throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");if(!this.h)return e;return e.filter((function(t){return t.matchesField(n)}))};r.on=function t(r,i){var n=this;var e=this.v.get(r)||null;var u=Z(i,e);this.v.set(r,u);return function(){if(!u.next&&!u.prev&&n.v.get(r)===u)n.v.delete(r);else tt(u)}};r.M=function t(r,i){var n=this.v.get(r)||null;while(null!==n){var e=n.prev?rt(n.prev):null;n.value(i);n=e}};P(t,[{key:"rules",get:function t(){return this.$}}]);return t}();var ot=function(t){k(PureAbility,t);function PureAbility(){return t.apply(this,arguments)||this}var r=PureAbility.prototype;r.can=function t(){var r=this.relevantRuleFor.apply(this,arguments);return!!r&&!r.inverted};r.relevantRuleFor=function t(r,i,n){var e=this.detectSubjectType(i);var u=this.rulesFor(r,e,n);for(var o=0,s=u.length;o<s;o++)if(u[o].matchesConditions(i))return u[o];return null};r.cannot=function t(){return!this.can.apply(this,arguments)};return PureAbility}(ut);var st={$eq:r,$ne:i,$lt:n,$lte:e,$gt:u,$gte:o,$in:s,$nin:f,$all:a,$size:c,$regex:h,$options:v,$elemMatch:l,$exists:d};var ft={eq:b,ne:y,lt:p,lte:w,gt:g,gte:E,in:A,nin:$,all:j,size:m,regex:M,elemMatch:x,exists:O,and:F};var at=function r(i,n,e){return t(R({},st,i),R({},ft,n),e)};var ct=t(st,ft);var ht=/[-/\\^$+?.()|[\]{}]/g;var vt=/\.?\*+\.?/g;var lt=/\*+/;var dt=/\./g;function bt(t,r,i){var n="*"===i[0]||"."===t[0]&&"."===t[t.length-1]?"+":"*";var e=-1===t.indexOf("**")?"[^.]":".";var u=t.replace(dt,"\\$&").replace(lt,e+n);return r+t.length===i.length?"(?:"+u+")?":u}function yt(t,r,i){if("."===t&&("*"===i[r-1]||"*"===i[r+1]))return t;return"\\"+t}function pt(t){var r=t.map((function(t){return t.replace(ht,yt).replace(vt,bt)}));var i=r.length>1?"(?:"+r.join("|")+")":r[0];return new RegExp("^"+i+"$")}var wt=function t(r){var i;return function(t){if("undefined"===typeof i)i=r.every((function(t){return-1===t.indexOf("*")}))?null:pt(r);return null===i?-1!==r.indexOf(t):i.test(t)}};var gt=function(t){k(Ability,t);function Ability(r,i){if(void 0===r)r=[];if(void 0===i)i={};return t.call(this,r,R({conditionsMatcher:ct,fieldMatcher:wt},i))||this}return Ability}(ot);var Et=function(){function t(t){this.O=t}var r=t.prototype;r.because=function t(r){this.O.reason=r;return this};return t}();var At=function(){function AbilityBuilder(t){this.rules=[];this.F=t;this.can=this.can.bind(this);this.cannot=this.cannot.bind(this);this.build=this.build.bind(this)}var t=AbilityBuilder.prototype;t.can=function t(r,i,n,e){var u={action:r};if(i){u.subject=i;if(Array.isArray(n)||"string"===typeof n)u.fields=n;else if("undefined"!==typeof n)u.conditions=n;if("undefined"!==typeof e)u.conditions=e}this.rules.push(u);return new Et(u)};t.cannot=function t(r,i,n,e){var u=this.can(r,i,n,e);u.O.inverted=true;return u};t.build=function t(r){return new this.F(this.rules,r)};return AbilityBuilder}();function defineAbility(t,r){var i=new At(gt);var n=t(i.can,i.cannot);if(n&&"function"===typeof n.then)return n.then((function(){return i.build(r)}));return i.build(r)}var $t=function t(r){return'Cannot execute "'+r.action+'" on "'+r.subjectType+'"'};var jt=function t(r){this.message=r};jt.prototype=Object.create(Error.prototype);var mt=function(t){k(ForbiddenError,t);ForbiddenError.setDefaultMessage=function t(r){this._="string"===typeof r?function(){return r}:r};ForbiddenError.from=function t(r){return new this(r)};function ForbiddenError(r){var i;i=t.call(this,"")||this;i.ability=r;if("function"===typeof Error.captureStackTrace){i.name="ForbiddenError";Error.captureStackTrace(C(i),i.constructor)}return i}var r=ForbiddenError.prototype;r.setMessage=function t(r){this.message=r;return this};r.throwUnlessCan=function t(){var r;var i=(r=this.ability).relevantRuleFor.apply(r,arguments);if(i&&!i.inverted)return;this.action=arguments.length<=0?void 0:arguments[0];this.subject=arguments.length<=1?void 0:arguments[1];this.subjectType=D(this.ability.detectSubjectType(arguments.length<=1?void 0:arguments[1]));this.field=arguments.length<=2?void 0:arguments[2];var n=i?i.reason:"";this.message=this.message||n||this.constructor._(this);throw this};return ForbiddenError}(jt);mt._=$t;var Mt=Object.freeze({__proto__:null});export{gt as Ability,At as AbilityBuilder,mt as ForbiddenError,ot as PureAbility,at as buildMongoQueryMatcher,K as createAliasResolver,defineAbility,L as detectSubjectType,wt as fieldPatternMatcher,$t as getDefaultErrorMessage,Mt as hkt,ct as mongoQueryMatcher,z as subject,T as wrapArray};
import{createFactory as t,$eq as r,$ne as i,$lt as n,$lte as e,$gt as u,$gte as o,$in as s,$nin as f,$all as a,$size as c,$regex as h,$options as v,$elemMatch as l,$exists as d,eq as b,ne as y,lt as p,lte as w,gt as g,gte as E,within as A,nin as $,all as j,size as m,regex as M,elemMatch as x,exists as O,and as F}from"@ucast/mongo2js";function _(t,r){for(var i=0;i<r.length;i++){var n=r[i];n.enumerable=n.enumerable||false;n.configurable=true;if("value"in n)n.writable=true;Object.defineProperty(t,n.key,n)}}function P(t,r,i){if(r)_(t.prototype,r);if(i)_(t,i);return t}function R(){R=Object.assign||function(t){for(var r=1;r<arguments.length;r++){var i=arguments[r];for(var n in i)if(Object.prototype.hasOwnProperty.call(i,n))t[n]=i[n]}return t};return R.apply(this,arguments)}function k(t,r){t.prototype=Object.create(r.prototype);t.prototype.constructor=t;B(t,r)}function B(t,r){B=Object.setPrototypeOf||function t(r,i){r.__proto__=i;return r};return B(t,r)}function C(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function T(t){return Array.isArray(t)?t:[t]}var q="__caslSubjectType__";function z(t,r){if(r)if(!r.hasOwnProperty(q))Object.defineProperty(r,q,{value:t});else if(t!==r[q])throw new Error("Trying to cast object to subject type "+t+" but previously it was casted to "+r[q]);return r}var S=function t(r){var i=typeof r;return"string"===i||"function"===i};var Y=function t(r){return r.modelName||r.name};var D=function t(r){return"string"===typeof r?r:Y(r)};function L(t){if(t.hasOwnProperty(q))return t[q];return Y(t.constructor)}function G(t,r,i){var n=T(r);var e=0;while(e<n.length){var u=n[e++];if(t.hasOwnProperty(u))n=i(n,t[u])}return n}function H(t,r){if("string"===typeof r&&-1!==t.indexOf(r))return r;for(var i=0;i<r.length;i++)if(-1!==t.indexOf(r[i]))return r[i];return null}var I=function t(r,i){return r.concat(i)};function J(t,r){if(r in t)throw new Error('Cannot use "'+r+"\" as an alias because it's reserved action.");var i=Object.keys(t);var n=function t(i,n){var e=H(i,n);if(e)throw new Error("Detected cycle "+e+" -> "+i.join(", "));var u="string"===typeof n&&n===r||-1!==i.indexOf(r)||Array.isArray(n)&&-1!==n.indexOf(r);if(u)throw new Error('Cannot make an alias to "'+r+'" because this is reserved action');return i.concat(n)};for(var e=0;e<i.length;e++)G(t,i[e],n)}function K(t,r){if(!r||false!==r.skipValidate)J(t,r&&r.anyAction||"manage");return function(r){return G(t,r,I)}}function N(t,r,i){for(var n=i;n<r.length;n++)t.push(r[n])}function Q(t,r){if(!t||!t.length)return r||[];if(!r||!r.length)return t||[];var i=0;var n=0;var e=[];while(i<t.length&&n<r.length)if(t[i].priority<r[n].priority){e.push(t[i]);i++}else{e.push(r[n]);n++}N(e,t,i);N(e,r,n);return e}function U(t,r,i){var n=t.get(r);if(!n){n=i();t.set(r,n)}return n}var V=function t(r){return r};function W(t,r){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!r.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!r.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}var X=function(){function t(t,r,i){if(void 0===i)i=0;W(t,r);this.action=r.resolveAction(t.action);this.subject=t.subject;this.inverted=!!t.inverted;this.conditions=t.conditions;this.reason=t.reason;this.fields=t.fields?T(t.fields):void 0;this.priority=i;this.t=r}var r=t.prototype;r.i=function t(){if(this.conditions&&!this.u)this.u=this.t.conditionsMatcher(this.conditions);return this.u};r.matchesConditions=function t(r){if(!this.conditions)return true;if(!r||S(r))return!this.inverted;var i=this.i();return i(r)};r.matchesField=function t(r){if(!this.fields)return true;if(!r)return!this.inverted;if(this.fields&&!this.o)this.o=this.t.fieldMatcher(this.fields);return this.o(r)};P(t,[{key:"ast",get:function t(){var r=this.i();return r?r.ast:void 0}}]);return t}();function Z(t,r){var i={value:t,prev:r,next:null};if(r)r.next=i;return i}function tt(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}var rt=function t(r){return{value:r.value,prev:r.prev,next:r.next}};var it=function t(){return{rules:[],merged:false}};var nt=function t(){return new Map};var et=function t(r,i){if(!r.h&&i.fields)r.h=true};var ut=function(){function t(t,r){if(void 0===t)t=[];if(void 0===r)r={};this.h=false;this.v=new Map;this.l={conditionsMatcher:r.conditionsMatcher,fieldMatcher:r.fieldMatcher,resolveAction:r.resolveAction||V};this.p=r.anyAction||"manage";this.g=r.anySubjectType||"all";this.A=r.detectSubjectType||L;this.$=t;this.j=this.m(t)}var r=t.prototype;r.detectSubjectType=function t(r){if(S(r))return r;if(!r)return this.g;return this.A(r)};r.update=function t(r){var i={rules:r,ability:this,target:this};this.M("update",i);this.$=r;this.j=this.m(r);this.M("updated",i);return this};r.m=function t(r){var i=new Map;for(var n=r.length-1;n>=0;n--){var e=r.length-n-1;var u=new X(r[n],this.l,e);var o=T(u.action);var s=T(u.subject||this.g);et(this,u);for(var f=0;f<s.length;f++){var a=U(i,s[f],nt);for(var c=0;c<o.length;c++)U(a,o[c],it).rules.push(u)}}return i};r.possibleRulesFor=function t(r,i){if(void 0===i)i=this.g;if(!S(i))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');var n=U(this.j,i,nt);var e=U(n,r,it);if(e.merged)return e.rules;var u=r!==this.p&&n.has(this.p)?n.get(this.p).rules:void 0;var o=Q(e.rules,u);if(i!==this.g)o=Q(o,this.possibleRulesFor(r,this.g));e.rules=o;e.merged=true;return o};r.rulesFor=function t(r,i,n){var e=this.possibleRulesFor(r,i);if(n&&"string"!==typeof n)throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");if(!this.h)return e;return e.filter((function(t){return t.matchesField(n)}))};r.on=function t(r,i){var n=this;var e=this.v.get(r)||null;var u=Z(i,e);this.v.set(r,u);return function(){var t=n.v.get(r);if(!u.next&&!u.prev&&t===u)n.v.delete(r);else if(u===t)n.v.set(r,u.prev);tt(u)}};r.M=function t(r,i){var n=this.v.get(r)||null;while(null!==n){var e=n.prev?rt(n.prev):null;n.value(i);n=e}};P(t,[{key:"rules",get:function t(){return this.$}}]);return t}();var ot=function(t){k(PureAbility,t);function PureAbility(){return t.apply(this,arguments)||this}var r=PureAbility.prototype;r.can=function t(){var r=this.relevantRuleFor.apply(this,arguments);return!!r&&!r.inverted};r.relevantRuleFor=function t(r,i,n){var e=this.detectSubjectType(i);var u=this.rulesFor(r,e,n);for(var o=0,s=u.length;o<s;o++)if(u[o].matchesConditions(i))return u[o];return null};r.cannot=function t(){return!this.can.apply(this,arguments)};return PureAbility}(ut);var st={$eq:r,$ne:i,$lt:n,$lte:e,$gt:u,$gte:o,$in:s,$nin:f,$all:a,$size:c,$regex:h,$options:v,$elemMatch:l,$exists:d};var ft={eq:b,ne:y,lt:p,lte:w,gt:g,gte:E,in:A,nin:$,all:j,size:m,regex:M,elemMatch:x,exists:O,and:F};var at=function r(i,n,e){return t(R({},st,i),R({},ft,n),e)};var ct=t(st,ft);var ht=/[-/\\^$+?.()|[\]{}]/g;var vt=/\.?\*+\.?/g;var lt=/\*+/;var dt=/\./g;function bt(t,r,i){var n="*"===i[0]||"."===t[0]&&"."===t[t.length-1]?"+":"*";var e=-1===t.indexOf("**")?"[^.]":".";var u=t.replace(dt,"\\$&").replace(lt,e+n);return r+t.length===i.length?"(?:"+u+")?":u}function yt(t,r,i){if("."===t&&("*"===i[r-1]||"*"===i[r+1]))return t;return"\\"+t}function pt(t){var r=t.map((function(t){return t.replace(ht,yt).replace(vt,bt)}));var i=r.length>1?"(?:"+r.join("|")+")":r[0];return new RegExp("^"+i+"$")}var wt=function t(r){var i;return function(t){if("undefined"===typeof i)i=r.every((function(t){return-1===t.indexOf("*")}))?null:pt(r);return null===i?-1!==r.indexOf(t):i.test(t)}};var gt=function(t){k(Ability,t);function Ability(r,i){if(void 0===r)r=[];if(void 0===i)i={};return t.call(this,r,R({conditionsMatcher:ct,fieldMatcher:wt},i))||this}return Ability}(ot);var Et=function(){function t(t){this.O=t}var r=t.prototype;r.because=function t(r){this.O.reason=r;return this};return t}();var At=function(){function AbilityBuilder(t){this.rules=[];this.F=t;this.can=this.can.bind(this);this.cannot=this.cannot.bind(this);this.build=this.build.bind(this)}var t=AbilityBuilder.prototype;t.can=function t(r,i,n,e){var u={action:r};if(i){u.subject=i;if(Array.isArray(n)||"string"===typeof n)u.fields=n;else if("undefined"!==typeof n)u.conditions=n;if("undefined"!==typeof e)u.conditions=e}this.rules.push(u);return new Et(u)};t.cannot=function t(r,i,n,e){var u=this.can(r,i,n,e);u.O.inverted=true;return u};t.build=function t(r){return new this.F(this.rules,r)};return AbilityBuilder}();function defineAbility(t,r){var i=new At(gt);var n=t(i.can,i.cannot);if(n&&"function"===typeof n.then)return n.then((function(){return i.build(r)}));return i.build(r)}var $t=function t(r){return'Cannot execute "'+r.action+'" on "'+r.subjectType+'"'};var jt=function t(r){this.message=r};jt.prototype=Object.create(Error.prototype);var mt=function(t){k(ForbiddenError,t);ForbiddenError.setDefaultMessage=function t(r){this._="string"===typeof r?function(){return r}:r};ForbiddenError.from=function t(r){return new this(r)};function ForbiddenError(r){var i;i=t.call(this,"")||this;i.ability=r;if("function"===typeof Error.captureStackTrace){i.name="ForbiddenError";Error.captureStackTrace(C(i),i.constructor)}return i}var r=ForbiddenError.prototype;r.setMessage=function t(r){this.message=r;return this};r.throwUnlessCan=function t(){var r;var i=(r=this.ability).relevantRuleFor.apply(r,arguments);if(i&&!i.inverted)return;this.action=arguments.length<=0?void 0:arguments[0];this.subject=arguments.length<=1?void 0:arguments[1];this.subjectType=D(this.ability.detectSubjectType(arguments.length<=1?void 0:arguments[1]));this.field=arguments.length<=2?void 0:arguments[2];var n=i?i.reason:"";this.message=this.message||n||this.constructor._(this);throw this};return ForbiddenError}(jt);mt._=$t;var Mt=Object.freeze({__proto__:null});export{gt as Ability,At as AbilityBuilder,mt as ForbiddenError,ot as PureAbility,at as buildMongoQueryMatcher,K as createAliasResolver,defineAbility,L as detectSubjectType,wt as fieldPatternMatcher,$t as getDefaultErrorMessage,Mt as hkt,ct as mongoQueryMatcher,z as subject,T as wrapArray};
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../../src/utils.ts","../../src/Rule.ts","../../src/structures/LinkedItem.ts","../../src/RuleIndex.ts","../../src/PureAbility.ts","../../src/matchers/conditions.ts","../../src/matchers/field.ts","../../src/Ability.ts","../../src/AbilityBuilder.ts","../../src/ForbiddenError.ts"],"sourcesContent":["import { AnyObject, Subject, SubjectType, SubjectClass, ForcedSubject, AliasesMap } from './types';\n\nexport function wrapArray<T>(value: T[] | T): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function setByPath(object: AnyObject, path: string, value: unknown): void {\n let ref = object;\n let lastKey = path;\n\n if (path.indexOf('.') !== -1) {\n const keys = path.split('.');\n\n lastKey = keys.pop()!;\n ref = keys.reduce((res, prop) => {\n res[prop] = res[prop] || {};\n return res[prop] as AnyObject;\n }, object);\n }\n\n ref[lastKey] = value;\n}\n\nconst TYPE_FIELD = '__caslSubjectType__';\nexport function setSubjectType<\n T extends string,\n U extends Record<PropertyKey, any>\n>(type: T, object: U): U & ForcedSubject<T> {\n if (object) {\n if (!object.hasOwnProperty(TYPE_FIELD)) {\n Object.defineProperty(object, TYPE_FIELD, { value: type });\n } else if (type !== object[TYPE_FIELD]) {\n throw new Error(`Trying to cast object to subject type ${type} but previously it was casted to ${object[TYPE_FIELD]}`);\n }\n }\n\n return object as U & ForcedSubject<T>;\n}\n\nexport const isSubjectType = (value: unknown): value is SubjectType => {\n const type = typeof value;\n return type === 'string' || type === 'function';\n};\n\nconst getSubjectClassName = (value: SubjectClass) => value.modelName || value.name;\nexport const getSubjectTypeName = (value: SubjectType) => {\n return typeof value === 'string' ? value : getSubjectClassName(value);\n};\n\nexport function detectSubjectType(subject: Exclude<Subject, SubjectType>): string {\n if (subject.hasOwnProperty(TYPE_FIELD)) {\n return (subject as any)[TYPE_FIELD];\n }\n\n return getSubjectClassName(subject.constructor as SubjectClass);\n}\n\ntype AliasMerge = (actions: string[], action: string | string[]) => string[];\nfunction expandActions(aliasMap: AliasesMap, rawActions: string | string[], merge: AliasMerge) {\n let actions = wrapArray(rawActions);\n let i = 0;\n\n while (i < actions.length) {\n const action = actions[i++];\n\n if (aliasMap.hasOwnProperty(action)) {\n actions = merge(actions, aliasMap[action]);\n }\n }\n\n return actions;\n}\n\nfunction findDuplicate(actions: string[], actionToFind: string | string[]) {\n if (typeof actionToFind === 'string' && actions.indexOf(actionToFind) !== -1) {\n return actionToFind;\n }\n\n for (let i = 0; i < actionToFind.length; i++) {\n if (actions.indexOf(actionToFind[i]) !== -1) return actionToFind[i];\n }\n\n return null;\n}\n\nconst defaultAliasMerge: AliasMerge = (actions, action) => actions.concat(action);\nfunction validateForCycles(aliasMap: AliasesMap, reservedAction: string) {\n if (reservedAction in aliasMap) {\n throw new Error(`Cannot use \"${reservedAction}\" as an alias because it's reserved action.`);\n }\n\n const keys = Object.keys(aliasMap);\n const mergeAliasesAndDetectCycles: AliasMerge = (actions, action) => {\n const duplicate = findDuplicate(actions, action);\n if (duplicate) throw new Error(`Detected cycle ${duplicate} -> ${actions.join(', ')}`);\n\n const isUsingReservedAction = typeof action === 'string' && action === reservedAction\n || actions.indexOf(reservedAction) !== -1\n || Array.isArray(action) && action.indexOf(reservedAction) !== -1;\n if (isUsingReservedAction) throw new Error(`Cannot make an alias to \"${reservedAction}\" because this is reserved action`);\n\n return actions.concat(action);\n };\n\n for (let i = 0; i < keys.length; i++) {\n expandActions(aliasMap, keys[i], mergeAliasesAndDetectCycles);\n }\n}\n\nexport type AliasResolverOptions = { skipValidate?: boolean; anyAction?: string };\nexport function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions) {\n if (!options || options.skipValidate !== false) {\n validateForCycles(aliasMap, options && options.anyAction || 'manage');\n }\n\n return (action: string | string[]) => expandActions(aliasMap, action, defaultAliasMerge);\n}\n\nfunction copyArrayTo<T>(dest: T[], target: T[], start: number) {\n for (let i = start; i < target.length; i++) {\n dest.push(target[i]);\n }\n}\n\nexport function mergePrioritized<T extends { priority: number }>(\n array?: T[],\n anotherArray?: T[]\n): T[] {\n if (!array || !array.length) {\n return anotherArray || [];\n }\n\n if (!anotherArray || !anotherArray.length) {\n return array || [];\n }\n\n let i = 0;\n let j = 0;\n const merged: T[] = [];\n\n while (i < array.length && j < anotherArray.length) {\n if (array[i].priority < anotherArray[j].priority) {\n merged.push(array[i]);\n i++;\n } else {\n merged.push(anotherArray[j]);\n j++;\n }\n }\n\n copyArrayTo(merged, array, i);\n copyArrayTo(merged, anotherArray, j);\n\n return merged;\n}\n\nexport function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V) {\n let value = map.get(key);\n\n if (!value) {\n value = defaultValue();\n map.set(key, value);\n }\n\n return value;\n}\n\nexport const identity = <T>(x: T) => x;\n","import { wrapArray, isSubjectType } from './utils';\nimport {\n MatchConditions,\n MatchField,\n Abilities,\n ToAbilityTypes,\n Normalize,\n ConditionsMatcher,\n FieldMatcher,\n} from './types';\nimport { RawRule, RawRuleFrom } from './RawRule';\n\ntype Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;\n\nfunction validate(rule: RawRuleFrom<Abilities, any>, options: RuleOptions<any>) {\n if (Array.isArray(rule.fields) && !rule.fields.length) {\n throw new Error('`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa');\n }\n\n if (rule.fields && !options.fieldMatcher) {\n throw new Error('You need to pass \"fieldMatcher\" option in order to restrict access by fields');\n }\n\n if (rule.conditions && !options.conditionsMatcher) {\n throw new Error('You need to pass \"conditionsMatcher\" option in order to restrict access by conditions');\n }\n}\n\nexport interface RuleOptions<Conditions> {\n conditionsMatcher?: ConditionsMatcher<Conditions>\n fieldMatcher?: FieldMatcher\n resolveAction(action: string | string[]): string | string[]\n}\n\nexport class Rule<A extends Abilities, C> {\n private _matchConditions: MatchConditions | undefined;\n private _matchField: MatchField<string> | undefined;\n private readonly _options!: RuleOptions<C>;\n public readonly action!: Tuple<A>[0] | Tuple<A>[0][];\n public readonly subject!: Tuple<A>[1] | Tuple<A>[1][];\n public readonly inverted!: boolean;\n public readonly conditions!: C | undefined;\n public readonly fields!: string[] | undefined;\n public readonly reason!: string | undefined;\n public readonly priority!: number;\n\n constructor(\n rule: RawRule<ToAbilityTypes<A>, C>,\n options: RuleOptions<C>,\n priority: number = 0\n ) {\n validate(rule, options);\n\n this.action = options.resolveAction(rule.action);\n this.subject = rule.subject!;\n this.inverted = !!rule.inverted;\n this.conditions = rule.conditions;\n this.reason = rule.reason;\n this.fields = rule.fields ? wrapArray(rule.fields) : undefined;\n this.priority = priority;\n this._options = options;\n }\n\n private _conditionsMatcher() {\n if (this.conditions && !this._matchConditions) {\n this._matchConditions = this._options.conditionsMatcher!(this.conditions);\n }\n\n return this._matchConditions!;\n }\n\n get ast() {\n const matches = this._conditionsMatcher();\n return matches ? matches.ast : undefined;\n }\n\n matchesConditions(object: Normalize<A>[1] | undefined): boolean {\n if (!this.conditions) {\n return true;\n }\n\n if (!object || isSubjectType(object)) {\n return !this.inverted;\n }\n\n const matches = this._conditionsMatcher();\n return matches(object as Record<string, unknown>);\n }\n\n matchesField(field: string | undefined): boolean {\n if (!this.fields) {\n return true;\n }\n\n if (!field) {\n return !this.inverted;\n }\n\n if (this.fields && !this._matchField) {\n this._matchField = this._options.fieldMatcher!(this.fields);\n }\n\n return this._matchField!(field);\n }\n}\n","export interface LinkedItem<T> {\n next: LinkedItem<T> | null\n prev: LinkedItem<T> | null\n readonly value: T\n}\n\nexport function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']) {\n const item = { value, prev, next: null };\n\n if (prev) {\n prev.next = item;\n }\n\n return item;\n}\n\nexport function unlinkItem(item: LinkedItem<any>) {\n if (item.next) {\n item.next.prev = item.prev;\n }\n\n if (item.prev) {\n item.prev.next = item.next;\n }\n\n item.next = item.prev = null; // eslint-disable-line\n}\n\nexport const cloneLinkedItem = <T extends LinkedItem<any>>(item: T): T => ({\n value: item.value,\n prev: item.prev,\n next: item.next,\n} as T);\n","import { Rule, RuleOptions } from './Rule';\nimport { RawRuleFrom } from './RawRule';\nimport {\n Abilities,\n Normalize,\n SubjectType,\n AbilityParameters,\n AbilityTuple,\n ExtractSubjectType\n} from './types';\nimport { wrapArray, detectSubjectType, mergePrioritized, getOrDefault, identity, isSubjectType } from './utils';\nimport { LinkedItem, linkedItem, unlinkItem, cloneLinkedItem } from './structures/LinkedItem';\n\nexport interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {\n detectSubjectType?(\n subject: Exclude<Normalize<A>[1], SubjectType>\n ): ExtractSubjectType<Normalize<A>[1]>;\n anyAction?: string;\n anySubjectType?: string;\n}\n\ndeclare const $abilities: unique symbol;\ndeclare const $conditions: unique symbol;\ninterface WithGenerics {\n [$abilities]: any\n [$conditions]: any\n}\nexport type Public<T extends WithGenerics> = { [K in keyof T]: T[K] };\nexport interface Generics<T extends WithGenerics> {\n abilities: T[typeof $abilities],\n conditions: T[typeof $conditions]\n}\n\nexport type RuleOf<T extends WithGenerics> =\n Rule<Generics<T>['abilities'], Generics<T>['conditions']>;\nexport type RawRuleOf<T extends WithGenerics> =\n RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;\n\nexport type RuleIndexOptionsOf<T extends WithGenerics> =\n RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;\n\ninterface AbilityEvent<T extends WithGenerics> {\n target: T\n /** @deprecated use \"target\" property instead */\n ability: T\n}\n\nexport interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {\n rules: RawRuleOf<T>[]\n}\n/**\n * @deprecated `on`/`emit` properly infer type without this type\n * TODO(major): delete\n */\nexport type EventHandler<Event> = (event: Event) => void;\n\nexport type Events<\n T extends WithGenerics,\n K extends keyof EventsMap<T> = keyof EventsMap<T>\n> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;\n\ninterface EventsMap<T extends WithGenerics> {\n update(event: UpdateEvent<T>): void\n updated(event: UpdateEvent<T>): void\n}\n\ntype IndexTree<A extends Abilities, C> = Map<SubjectType, Map<string, {\n rules: Rule<A, C>[],\n merged: boolean\n}>>;\n\nexport type Unsubscribe = () => void;\n\nconst defaultActionEntry = () => ({\n rules: [] as unknown as Rule<any, any>[],\n merged: false\n});\nconst defaultSubjectEntry = () => new Map<string, ReturnType<typeof defaultActionEntry>>();\nconst analyze = (index: any, rule: Rule<any, any>) => {\n if (!index._hasPerFieldRules && rule.fields) {\n index._hasPerFieldRules = true;\n }\n};\n\ntype AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> =\n AbilityParameters<\n T,\n T extends AbilityTuple\n ? IncludeField extends true\n ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0\n : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0\n : never,\n (action: Extract<T, string>) => 0\n >;\n\nexport class RuleIndex<A extends Abilities, Conditions> {\n private _hasPerFieldRules: boolean = false;\n private _events: Events<this> = new Map();\n private _indexedRules!: IndexTree<A, Conditions>;\n private _rules!: RawRuleFrom<A, Conditions>[];\n private readonly _ruleOptions!: RuleOptions<Conditions>;\n private readonly _detectSubjectType!: Required<RuleIndexOptions<A, Conditions>>['detectSubjectType'];\n private readonly _anyAction: string;\n private readonly _anySubjectType: string;\n readonly [$abilities]!: A;\n readonly [$conditions]!: Conditions;\n\n constructor(\n rules: RawRuleFrom<A, Conditions>[] = [],\n options: RuleIndexOptions<A, Conditions> = {}\n ) {\n this._ruleOptions = {\n conditionsMatcher: options.conditionsMatcher,\n fieldMatcher: options.fieldMatcher,\n resolveAction: options.resolveAction || identity,\n };\n this._anyAction = options.anyAction || 'manage';\n this._anySubjectType = options.anySubjectType || 'all';\n this._detectSubjectType = options.detectSubjectType || detectSubjectType;\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n }\n\n get rules() {\n return this._rules;\n }\n\n detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]> {\n if (isSubjectType(object)) return object;\n if (!object) return this._anySubjectType;\n return this._detectSubjectType(object as Exclude<Normalize<A>[1], SubjectType>);\n }\n\n update(rules: RawRuleFrom<A, Conditions>[]): Public<this> {\n const event = {\n rules,\n ability: this,\n target: this\n } as unknown as UpdateEvent<this>;\n\n this._emit('update', event);\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n this._emit('updated', event);\n\n return this;\n }\n\n private _buildIndexFor(rawRules: RawRuleFrom<A, Conditions>[]) {\n const indexedRules: IndexTree<A, Conditions> = new Map();\n\n for (let i = rawRules.length - 1; i >= 0; i--) {\n const priority = rawRules.length - i - 1;\n const rule = new Rule(rawRules[i], this._ruleOptions, priority);\n const actions = wrapArray(rule.action);\n const subjects = wrapArray(rule.subject || this._anySubjectType);\n analyze(this, rule);\n\n for (let k = 0; k < subjects.length; k++) {\n const subjectRules = getOrDefault(indexedRules, subjects[k], defaultSubjectEntry);\n\n for (let j = 0; j < actions.length; j++) {\n getOrDefault(subjectRules, actions[j], defaultActionEntry).rules.push(rule);\n }\n }\n }\n\n return indexedRules;\n }\n\n possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[]\n possibleRulesFor(\n action: string,\n subjectType: SubjectType = this._anySubjectType\n ): Rule<A, Conditions>[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"possibleRulesFor\" accepts only subject types (i.e., string or class) as the 2nd parameter');\n }\n\n const subjectRules = getOrDefault(this._indexedRules, subjectType, defaultSubjectEntry);\n const actionRules = getOrDefault(subjectRules, action, defaultActionEntry);\n\n if (actionRules.merged) {\n return actionRules.rules;\n }\n\n const anyActionRules = action !== this._anyAction && subjectRules.has(this._anyAction)\n ? subjectRules.get(this._anyAction)!.rules\n : undefined;\n let rules = mergePrioritized(actionRules.rules, anyActionRules);\n\n if (subjectType !== this._anySubjectType) {\n rules = mergePrioritized(rules, (this as any).possibleRulesFor(action, this._anySubjectType));\n }\n\n actionRules.rules = rules;\n actionRules.merged = true;\n\n return rules;\n }\n\n rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[]\n rulesFor(action: string, subjectType?: SubjectType, field?: string): Rule<A, Conditions>[] {\n const rules: Rule<A, Conditions>[] = (this as any).possibleRulesFor(action, subjectType);\n\n if (field && typeof field !== 'string') {\n throw new Error('The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details');\n }\n\n if (!this._hasPerFieldRules) {\n return rules;\n }\n\n return rules.filter(rule => rule.matchesField(field));\n }\n\n on<T extends keyof EventsMap<this>>(\n event: T,\n handler: EventsMap<Public<this>>[T]\n ): Unsubscribe {\n const head = this._events.get(event) || null;\n const item = linkedItem(handler, head);\n this._events.set(event, item);\n\n return () => {\n if (!item.next && !item.prev && this._events.get(event) === item) {\n this._events.delete(event);\n } else {\n unlinkItem(item);\n }\n };\n }\n\n private _emit<T extends keyof EventsMap<this>>(\n name: T,\n payload: Parameters<EventsMap<this>[T]>[0]\n ) {\n let current = this._events.get(name) || null;\n while (current !== null) {\n const prev = current.prev ? cloneLinkedItem(current.prev) : null;\n current.value(payload);\n current = prev;\n }\n }\n}\n","import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';\nimport { Abilities, AbilityTuple, CanParameters, Subject } from './types';\nimport { Rule } from './Rule';\n\nexport interface AbilityOptions<A extends Abilities, Conditions>\n extends RuleIndexOptions<A, Conditions> {}\nexport interface AnyAbility extends Public<PureAbility<any, any>> {}\nexport interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {}\nexport type AbilityClass<T extends AnyAbility> = new (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport class PureAbility<\n A extends Abilities = AbilityTuple,\n Conditions = unknown\n> extends RuleIndex<A, Conditions> {\n can(...args: CanParameters<A>): boolean {\n const rule = this.relevantRuleFor(...args);\n return !!rule && !rule.inverted;\n }\n\n relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null {\n const subjectType = this.detectSubjectType(subject);\n const rules = (this as any).rulesFor(action, subjectType, field);\n\n for (let i = 0, length = rules.length; i < length; i++) {\n if (rules[i].matchesConditions(subject)) {\n return rules[i];\n }\n }\n\n return null;\n }\n\n cannot(...args: CanParameters<A>): boolean {\n return !this.can(...args);\n }\n}\n","import {\n $eq,\n eq,\n $ne,\n ne,\n $lt,\n lt,\n $lte,\n lte,\n $gt,\n gt,\n $gte,\n gte,\n $in,\n within,\n $nin,\n nin,\n $all,\n all,\n $size,\n size,\n $regex,\n $options,\n regex,\n $elemMatch,\n elemMatch,\n $exists,\n exists,\n and,\n createFactory,\n BuildMongoQuery,\n DefaultOperators,\n} from '@ucast/mongo2js';\nimport { ConditionsMatcher, AnyObject } from '../types';\nimport { Container, GenericFactory } from '../hkt';\n\nconst defaultInstructions = {\n $eq,\n $ne,\n $lt,\n $lte,\n $gt,\n $gte,\n $in,\n $nin,\n $all,\n $size,\n $regex,\n $options,\n $elemMatch,\n $exists,\n};\nconst defaultInterpreters = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n in: within,\n nin,\n all,\n size,\n regex,\n elemMatch,\n exists,\n and,\n};\n\ninterface MongoQueryFactory extends GenericFactory {\n produce: MongoQuery<this[0]>\n}\n\ntype MergeUnion<T extends {}, Keys extends keyof T = keyof T> = { [K in Keys]: T[K] };\nexport type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {\n toplevel: {},\n field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>\n}> & Container<MongoQueryFactory>;\n\ntype MongoQueryMatcherFactory =\n (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;\nexport const buildMongoQueryMatcher = ((instructions, interpreters, options) => createFactory(\n { ...defaultInstructions, ...instructions },\n { ...defaultInterpreters, ...interpreters },\n options\n)) as MongoQueryMatcherFactory;\n\nexport const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);\nexport type {\n MongoQueryFieldOperators,\n MongoQueryTopLevelOperators,\n MongoQueryOperators,\n} from '@ucast/mongo2js';\n","import { FieldMatcher } from '../types';\n\nconst REGEXP_SPECIAL_CHARS = /[-/\\\\^$+?.()|[\\]{}]/g;\nconst REGEXP_ANY = /\\.?\\*+\\.?/g;\nconst REGEXP_STARS = /\\*+/;\nconst REGEXP_DOT = /\\./g;\n\nfunction detectRegexpPattern(match: string, index: number, string: string): string {\n const quantifier = string[0] === '*' || match[0] === '.' && match[match.length - 1] === '.'\n ? '+'\n : '*';\n const matcher = match.indexOf('**') === -1 ? '[^.]' : '.';\n const pattern = match.replace(REGEXP_DOT, '\\\\$&')\n .replace(REGEXP_STARS, matcher + quantifier);\n\n return index + match.length === string.length ? `(?:${pattern})?` : pattern;\n}\n\nfunction escapeRegexp(match: string, index: number, string: string): string {\n if (match === '.' && (string[index - 1] === '*' || string[index + 1] === '*')) {\n return match;\n }\n\n return `\\\\${match}`;\n}\n\nfunction createPattern(fields: string[]) {\n const patterns = fields.map(field => field\n .replace(REGEXP_SPECIAL_CHARS, escapeRegexp)\n .replace(REGEXP_ANY, detectRegexpPattern));\n const pattern = patterns.length > 1 ? `(?:${patterns.join('|')})` : patterns[0];\n\n return new RegExp(`^${pattern}$`);\n}\n\nexport const fieldPatternMatcher: FieldMatcher = (fields) => {\n let pattern: RegExp | null;\n\n return (field) => {\n if (typeof pattern === 'undefined') {\n pattern = fields.every(f => f.indexOf('*') === -1)\n ? null\n : createPattern(fields);\n }\n\n return pattern === null\n ? fields.indexOf(field) !== -1\n : pattern.test(field);\n };\n};\n","import { PureAbility, AbilityOptions } from './PureAbility';\nimport { RawRuleFrom } from './RawRule';\nimport { AbilityTuple } from './types';\nimport { MongoQuery, mongoQueryMatcher } from './matchers/conditions';\nimport { fieldPatternMatcher } from './matchers/field';\nimport { Public } from './RuleIndex';\n\nexport class Ability<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {\n constructor(rules: RawRuleFrom<A, C>[] = [], options: AbilityOptions<A, C> = {}) {\n super(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n }\n}\n\nexport interface AnyMongoAbility extends Public<Ability<any, MongoQuery>> {}\n","import { Ability, AnyMongoAbility } from './Ability';\nimport { AnyAbility, AbilityOptionsOf, AbilityClass } from './PureAbility';\nimport { RawRuleOf, Generics } from './RuleIndex';\nimport {\n ExtractSubjectType as E,\n AbilityTuple,\n SubjectType,\n TaggedInterface,\n Normalize,\n AnyObject,\n AnyClass,\n} from './types';\nimport { ProduceGeneric } from './hkt';\n\nclass RuleBuilder<T extends AnyAbility> {\n public _rule!: RawRuleOf<T>;\n\n constructor(rule: RawRuleOf<T>) {\n this._rule = rule;\n }\n\n because(reason: string): this {\n this._rule.reason = reason;\n return this;\n }\n}\n\ntype InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R>\n ? R\n : S extends string\n ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string>\n ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>>\n : AnyObject\n : never;\ntype ConditionsOf<T extends AnyAbility, I extends {}> =\n ProduceGeneric<Generics<T>['conditions'], I>;\ntype ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any\n ? S extends T[1] ? T[0] : never\n : never;\ntype ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;\ntype SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;\n\ntype SimpleCanParams<T extends AnyAbility> = Parameters<(\n action: Generics<T>['abilities'] | Generics<T>['abilities'][]\n) => 0>;\ntype BuilderCanParameters<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\n\ntype BuilderCanParametersWithFields<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n F extends string,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n fields?: F | F[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\ntype Keys<T> = string & keyof T;\n\nexport class AbilityBuilder<T extends AnyAbility> {\n public rules: RawRuleOf<T>[] = [];\n private _AbilityType!: AnyClass<T>;\n\n constructor(AbilityType: AnyClass<T>) {\n this._AbilityType = AbilityType;\n this.can = this.can.bind(this as any);\n this.cannot = this.cannot.bind(this as any);\n this.build = this.build.bind(this as any);\n }\n\n can<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n can<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n can(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ): RuleBuilder<T> {\n const rule = { action } as RawRuleOf<T>;\n\n if (subject) {\n rule.subject = subject;\n\n if (Array.isArray(conditionsOrFields) || typeof conditionsOrFields === 'string') {\n rule.fields = conditionsOrFields;\n } else if (typeof conditionsOrFields !== 'undefined') {\n rule.conditions = conditionsOrFields;\n }\n\n if (typeof conditions !== 'undefined') {\n rule.conditions = conditions;\n }\n }\n\n this.rules.push(rule);\n\n return new RuleBuilder(rule);\n }\n\n cannot<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n cannot<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n cannot(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions'],\n ): RuleBuilder<T> {\n const builder = (this as any).can(action, subject, conditionsOrFields, conditions);\n builder._rule.inverted = true;\n return builder;\n }\n\n build(options?: AbilityOptionsOf<T>) {\n return new this._AbilityType(this.rules, options);\n }\n}\n\ntype DSL<T extends AnyAbility, R> = (\n can: AbilityBuilder<T>['can'],\n cannot: AbilityBuilder<T>['cannot']\n) => R;\n\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void | Promise<void>>, options?: AbilityOptionsOf<T>): T | Promise<T> {\n const builder = new AbilityBuilder(Ability as unknown as AbilityClass<T>);\n const result = define(builder.can, builder.cannot);\n\n if (result && typeof result.then === 'function') {\n return result.then(() => builder.build(options));\n }\n\n return builder.build(options);\n}\n","import { AnyAbility } from './PureAbility';\nimport { Normalize } from './types';\nimport { Generics } from './RuleIndex';\nimport { getSubjectTypeName } from './utils';\n\nexport type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;\nexport const getDefaultErrorMessage: GetErrorMessage = error => `Cannot execute \"${error.action}\" on \"${error.subjectType}\"`;\n\nconst NativeError = function NError(this: Error, message: string) {\n this.message = message;\n} as unknown as new (message: string) => Error;\n\nNativeError.prototype = Object.create(Error.prototype);\n\nexport class ForbiddenError<T extends AnyAbility> extends NativeError {\n public readonly ability!: T;\n public action!: Normalize<Generics<T>['abilities']>[0];\n public subject!: Generics<T>['abilities'][1];\n public field?: string;\n public subjectType!: string;\n\n static _defaultErrorMessage = getDefaultErrorMessage;\n\n static setDefaultMessage(messageOrFn: string | GetErrorMessage) {\n this._defaultErrorMessage = typeof messageOrFn === 'string' ? () => messageOrFn : messageOrFn;\n }\n\n static from<U extends AnyAbility>(ability: U) {\n return new this<U>(ability);\n }\n\n private constructor(ability: T) {\n super('');\n this.ability = ability;\n\n if (typeof Error.captureStackTrace === 'function') {\n this.name = 'ForbiddenError';\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n setMessage(message: string) {\n this.message = message;\n return this;\n }\n\n throwUnlessCan(...args: Parameters<T['can']>) {\n const rule = this.ability.relevantRuleFor(...args);\n\n if (rule && !rule.inverted) {\n return;\n }\n\n this.action = args[0];\n this.subject = args[1];\n this.subjectType = getSubjectTypeName(this.ability.detectSubjectType(args[1]));\n this.field = args[2];\n\n const reason = rule ? rule.reason : '';\n // eslint-disable-next-line no-underscore-dangle\n this.message = this.message || reason || (this.constructor as any)._defaultErrorMessage(this);\n throw this; // eslint-disable-line\n }\n}\n"],"names":["wrapArray","value","Array","isArray","TYPE_FIELD","setSubjectType","type","object","hasOwnProperty","Object","defineProperty","Error","isSubjectType","getSubjectClassName","modelName","name","getSubjectTypeName","detectSubjectType","subject","constructor","expandActions","aliasMap","rawActions","merge","actions","i","length","action","findDuplicate","actionToFind","indexOf","defaultAliasMerge","concat","validateForCycles","reservedAction","keys","mergeAliasesAndDetectCycles","duplicate","join","isUsingReservedAction","createAliasResolver","options","skipValidate","anyAction","copyArrayTo","dest","target","start","push","mergePrioritized","array","anotherArray","j","merged","priority","getOrDefault","map","key","defaultValue","get","set","identity","x","validate","rule","fields","fieldMatcher","conditions","conditionsMatcher","Rule","resolveAction","inverted","reason","undefined","_options","_conditionsMatcher","this","_matchConditions","matchesConditions","matches","matchesField","field","_matchField","ast","linkedItem","prev","item","next","unlinkItem","cloneLinkedItem","defaultActionEntry","rules","defaultSubjectEntry","Map","analyze","index","_hasPerFieldRules","RuleIndex","_events","_ruleOptions","_anyAction","_anySubjectType","anySubjectType","_detectSubjectType","_rules","_indexedRules","_buildIndexFor","update","event","ability","_emit","rawRules","indexedRules","subjects","k","subjectRules","possibleRulesFor","subjectType","actionRules","anyActionRules","has","rulesFor","filter","on","handler","head","_this","delete","payload","current","PureAbility","can","relevantRuleFor","cannot","defaultInstructions","$eq","$ne","$lt","$lte","$gt","$gte","$in","$nin","$all","$size","$regex","$options","$elemMatch","$exists","defaultInterpreters","eq","ne","lt","lte","gt","gte","in","within","nin","all","size","regex","elemMatch","exists","and","buildMongoQueryMatcher","instructions","interpreters","createFactory","mongoQueryMatcher","REGEXP_SPECIAL_CHARS","REGEXP_ANY","REGEXP_STARS","REGEXP_DOT","detectRegexpPattern","match","string","quantifier","matcher","pattern","replace","escapeRegexp","createPattern","patterns","RegExp","fieldPatternMatcher","every","f","test","Ability","_PureAbility","RuleBuilder","_rule","because","AbilityBuilder","AbilityType","_AbilityType","bind","build","conditionsOrFields","builder","defineAbility","define","result","then","getDefaultErrorMessage","error","NativeError","NError","message","prototype","create","ForbiddenError","setDefaultMessage","messageOrFn","_defaultErrorMessage","from","captureStackTrace","setMessage","throwUnlessCan"],"mappings":"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"}
{"version":3,"file":"index.js","sources":["../../src/utils.ts","../../src/Rule.ts","../../src/structures/LinkedItem.ts","../../src/RuleIndex.ts","../../src/PureAbility.ts","../../src/matchers/conditions.ts","../../src/matchers/field.ts","../../src/Ability.ts","../../src/AbilityBuilder.ts","../../src/ForbiddenError.ts"],"sourcesContent":["import { AnyObject, Subject, SubjectType, SubjectClass, ForcedSubject, AliasesMap } from './types';\n\nexport function wrapArray<T>(value: T[] | T): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function setByPath(object: AnyObject, path: string, value: unknown): void {\n let ref = object;\n let lastKey = path;\n\n if (path.indexOf('.') !== -1) {\n const keys = path.split('.');\n\n lastKey = keys.pop()!;\n ref = keys.reduce((res, prop) => {\n res[prop] = res[prop] || {};\n return res[prop] as AnyObject;\n }, object);\n }\n\n ref[lastKey] = value;\n}\n\nconst TYPE_FIELD = '__caslSubjectType__';\nexport function setSubjectType<\n T extends string,\n U extends Record<PropertyKey, any>\n>(type: T, object: U): U & ForcedSubject<T> {\n if (object) {\n if (!object.hasOwnProperty(TYPE_FIELD)) {\n Object.defineProperty(object, TYPE_FIELD, { value: type });\n } else if (type !== object[TYPE_FIELD]) {\n throw new Error(`Trying to cast object to subject type ${type} but previously it was casted to ${object[TYPE_FIELD]}`);\n }\n }\n\n return object as U & ForcedSubject<T>;\n}\n\nexport const isSubjectType = (value: unknown): value is SubjectType => {\n const type = typeof value;\n return type === 'string' || type === 'function';\n};\n\nconst getSubjectClassName = (value: SubjectClass) => value.modelName || value.name;\nexport const getSubjectTypeName = (value: SubjectType) => {\n return typeof value === 'string' ? value : getSubjectClassName(value);\n};\n\nexport function detectSubjectType(subject: Exclude<Subject, SubjectType>): string {\n if (subject.hasOwnProperty(TYPE_FIELD)) {\n return (subject as any)[TYPE_FIELD];\n }\n\n return getSubjectClassName(subject.constructor as SubjectClass);\n}\n\ntype AliasMerge = (actions: string[], action: string | string[]) => string[];\nfunction expandActions(aliasMap: AliasesMap, rawActions: string | string[], merge: AliasMerge) {\n let actions = wrapArray(rawActions);\n let i = 0;\n\n while (i < actions.length) {\n const action = actions[i++];\n\n if (aliasMap.hasOwnProperty(action)) {\n actions = merge(actions, aliasMap[action]);\n }\n }\n\n return actions;\n}\n\nfunction findDuplicate(actions: string[], actionToFind: string | string[]) {\n if (typeof actionToFind === 'string' && actions.indexOf(actionToFind) !== -1) {\n return actionToFind;\n }\n\n for (let i = 0; i < actionToFind.length; i++) {\n if (actions.indexOf(actionToFind[i]) !== -1) return actionToFind[i];\n }\n\n return null;\n}\n\nconst defaultAliasMerge: AliasMerge = (actions, action) => actions.concat(action);\nfunction validateForCycles(aliasMap: AliasesMap, reservedAction: string) {\n if (reservedAction in aliasMap) {\n throw new Error(`Cannot use \"${reservedAction}\" as an alias because it's reserved action.`);\n }\n\n const keys = Object.keys(aliasMap);\n const mergeAliasesAndDetectCycles: AliasMerge = (actions, action) => {\n const duplicate = findDuplicate(actions, action);\n if (duplicate) throw new Error(`Detected cycle ${duplicate} -> ${actions.join(', ')}`);\n\n const isUsingReservedAction = typeof action === 'string' && action === reservedAction\n || actions.indexOf(reservedAction) !== -1\n || Array.isArray(action) && action.indexOf(reservedAction) !== -1;\n if (isUsingReservedAction) throw new Error(`Cannot make an alias to \"${reservedAction}\" because this is reserved action`);\n\n return actions.concat(action);\n };\n\n for (let i = 0; i < keys.length; i++) {\n expandActions(aliasMap, keys[i], mergeAliasesAndDetectCycles);\n }\n}\n\nexport type AliasResolverOptions = { skipValidate?: boolean; anyAction?: string };\nexport function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions) {\n if (!options || options.skipValidate !== false) {\n validateForCycles(aliasMap, options && options.anyAction || 'manage');\n }\n\n return (action: string | string[]) => expandActions(aliasMap, action, defaultAliasMerge);\n}\n\nfunction copyArrayTo<T>(dest: T[], target: T[], start: number) {\n for (let i = start; i < target.length; i++) {\n dest.push(target[i]);\n }\n}\n\nexport function mergePrioritized<T extends { priority: number }>(\n array?: T[],\n anotherArray?: T[]\n): T[] {\n if (!array || !array.length) {\n return anotherArray || [];\n }\n\n if (!anotherArray || !anotherArray.length) {\n return array || [];\n }\n\n let i = 0;\n let j = 0;\n const merged: T[] = [];\n\n while (i < array.length && j < anotherArray.length) {\n if (array[i].priority < anotherArray[j].priority) {\n merged.push(array[i]);\n i++;\n } else {\n merged.push(anotherArray[j]);\n j++;\n }\n }\n\n copyArrayTo(merged, array, i);\n copyArrayTo(merged, anotherArray, j);\n\n return merged;\n}\n\nexport function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V) {\n let value = map.get(key);\n\n if (!value) {\n value = defaultValue();\n map.set(key, value);\n }\n\n return value;\n}\n\nexport const identity = <T>(x: T) => x;\n","import { wrapArray, isSubjectType } from './utils';\nimport {\n MatchConditions,\n MatchField,\n Abilities,\n ToAbilityTypes,\n Normalize,\n ConditionsMatcher,\n FieldMatcher,\n} from './types';\nimport { RawRule, RawRuleFrom } from './RawRule';\n\ntype Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;\n\nfunction validate(rule: RawRuleFrom<Abilities, any>, options: RuleOptions<any>) {\n if (Array.isArray(rule.fields) && !rule.fields.length) {\n throw new Error('`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa');\n }\n\n if (rule.fields && !options.fieldMatcher) {\n throw new Error('You need to pass \"fieldMatcher\" option in order to restrict access by fields');\n }\n\n if (rule.conditions && !options.conditionsMatcher) {\n throw new Error('You need to pass \"conditionsMatcher\" option in order to restrict access by conditions');\n }\n}\n\nexport interface RuleOptions<Conditions> {\n conditionsMatcher?: ConditionsMatcher<Conditions>\n fieldMatcher?: FieldMatcher\n resolveAction(action: string | string[]): string | string[]\n}\n\nexport class Rule<A extends Abilities, C> {\n private _matchConditions: MatchConditions | undefined;\n private _matchField: MatchField<string> | undefined;\n private readonly _options!: RuleOptions<C>;\n public readonly action!: Tuple<A>[0] | Tuple<A>[0][];\n public readonly subject!: Tuple<A>[1] | Tuple<A>[1][];\n public readonly inverted!: boolean;\n public readonly conditions!: C | undefined;\n public readonly fields!: string[] | undefined;\n public readonly reason!: string | undefined;\n public readonly priority!: number;\n\n constructor(\n rule: RawRule<ToAbilityTypes<A>, C>,\n options: RuleOptions<C>,\n priority: number = 0\n ) {\n validate(rule, options);\n\n this.action = options.resolveAction(rule.action);\n this.subject = rule.subject!;\n this.inverted = !!rule.inverted;\n this.conditions = rule.conditions;\n this.reason = rule.reason;\n this.fields = rule.fields ? wrapArray(rule.fields) : undefined;\n this.priority = priority;\n this._options = options;\n }\n\n private _conditionsMatcher() {\n if (this.conditions && !this._matchConditions) {\n this._matchConditions = this._options.conditionsMatcher!(this.conditions);\n }\n\n return this._matchConditions!;\n }\n\n get ast() {\n const matches = this._conditionsMatcher();\n return matches ? matches.ast : undefined;\n }\n\n matchesConditions(object: Normalize<A>[1] | undefined): boolean {\n if (!this.conditions) {\n return true;\n }\n\n if (!object || isSubjectType(object)) {\n return !this.inverted;\n }\n\n const matches = this._conditionsMatcher();\n return matches(object as Record<string, unknown>);\n }\n\n matchesField(field: string | undefined): boolean {\n if (!this.fields) {\n return true;\n }\n\n if (!field) {\n return !this.inverted;\n }\n\n if (this.fields && !this._matchField) {\n this._matchField = this._options.fieldMatcher!(this.fields);\n }\n\n return this._matchField!(field);\n }\n}\n","export interface LinkedItem<T> {\n next: LinkedItem<T> | null\n prev: LinkedItem<T> | null\n readonly value: T\n}\n\nexport function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']) {\n const item = { value, prev, next: null };\n\n if (prev) {\n prev.next = item;\n }\n\n return item;\n}\n\nexport function unlinkItem(item: LinkedItem<any>) {\n if (item.next) {\n item.next.prev = item.prev;\n }\n\n if (item.prev) {\n item.prev.next = item.next;\n }\n\n item.next = item.prev = null; // eslint-disable-line\n}\n\nexport const cloneLinkedItem = <T extends LinkedItem<any>>(item: T): T => ({\n value: item.value,\n prev: item.prev,\n next: item.next,\n} as T);\n","import { Rule, RuleOptions } from './Rule';\nimport { RawRuleFrom } from './RawRule';\nimport {\n Abilities,\n Normalize,\n SubjectType,\n AbilityParameters,\n AbilityTuple,\n ExtractSubjectType\n} from './types';\nimport { wrapArray, detectSubjectType, mergePrioritized, getOrDefault, identity, isSubjectType } from './utils';\nimport { LinkedItem, linkedItem, unlinkItem, cloneLinkedItem } from './structures/LinkedItem';\n\nexport interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {\n detectSubjectType?(\n subject: Exclude<Normalize<A>[1], SubjectType>\n ): ExtractSubjectType<Normalize<A>[1]>;\n anyAction?: string;\n anySubjectType?: string;\n}\n\ndeclare const $abilities: unique symbol;\ndeclare const $conditions: unique symbol;\ninterface WithGenerics {\n [$abilities]: any\n [$conditions]: any\n}\nexport type Public<T extends WithGenerics> = { [K in keyof T]: T[K] };\nexport interface Generics<T extends WithGenerics> {\n abilities: T[typeof $abilities],\n conditions: T[typeof $conditions]\n}\n\nexport type RuleOf<T extends WithGenerics> =\n Rule<Generics<T>['abilities'], Generics<T>['conditions']>;\nexport type RawRuleOf<T extends WithGenerics> =\n RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;\n\nexport type RuleIndexOptionsOf<T extends WithGenerics> =\n RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;\n\ninterface AbilityEvent<T extends WithGenerics> {\n target: T\n /** @deprecated use \"target\" property instead */\n ability: T\n}\n\nexport interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {\n rules: RawRuleOf<T>[]\n}\n/**\n * @deprecated `on`/`emit` properly infer type without this type\n * TODO(major): delete\n */\nexport type EventHandler<Event> = (event: Event) => void;\n\nexport type Events<\n T extends WithGenerics,\n K extends keyof EventsMap<T> = keyof EventsMap<T>\n> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;\n\ninterface EventsMap<T extends WithGenerics> {\n update(event: UpdateEvent<T>): void\n updated(event: UpdateEvent<T>): void\n}\n\ntype IndexTree<A extends Abilities, C> = Map<SubjectType, Map<string, {\n rules: Rule<A, C>[],\n merged: boolean\n}>>;\n\nexport type Unsubscribe = () => void;\n\nconst defaultActionEntry = () => ({\n rules: [] as unknown as Rule<any, any>[],\n merged: false\n});\nconst defaultSubjectEntry = () => new Map<string, ReturnType<typeof defaultActionEntry>>();\nconst analyze = (index: any, rule: Rule<any, any>) => {\n if (!index._hasPerFieldRules && rule.fields) {\n index._hasPerFieldRules = true;\n }\n};\n\ntype AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> =\n AbilityParameters<\n T,\n T extends AbilityTuple\n ? IncludeField extends true\n ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0\n : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0\n : never,\n (action: Extract<T, string>) => 0\n >;\n\nexport class RuleIndex<A extends Abilities, Conditions> {\n private _hasPerFieldRules: boolean = false;\n private _events: Events<this> = new Map();\n private _indexedRules!: IndexTree<A, Conditions>;\n private _rules!: RawRuleFrom<A, Conditions>[];\n private readonly _ruleOptions!: RuleOptions<Conditions>;\n private readonly _detectSubjectType!: Required<RuleIndexOptions<A, Conditions>>['detectSubjectType'];\n private readonly _anyAction: string;\n private readonly _anySubjectType: string;\n readonly [$abilities]!: A;\n readonly [$conditions]!: Conditions;\n\n constructor(\n rules: RawRuleFrom<A, Conditions>[] = [],\n options: RuleIndexOptions<A, Conditions> = {}\n ) {\n this._ruleOptions = {\n conditionsMatcher: options.conditionsMatcher,\n fieldMatcher: options.fieldMatcher,\n resolveAction: options.resolveAction || identity,\n };\n this._anyAction = options.anyAction || 'manage';\n this._anySubjectType = options.anySubjectType || 'all';\n this._detectSubjectType = options.detectSubjectType || detectSubjectType;\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n }\n\n get rules() {\n return this._rules;\n }\n\n detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]> {\n if (isSubjectType(object)) return object;\n if (!object) return this._anySubjectType;\n return this._detectSubjectType(object as Exclude<Normalize<A>[1], SubjectType>);\n }\n\n update(rules: RawRuleFrom<A, Conditions>[]): Public<this> {\n const event = {\n rules,\n ability: this,\n target: this\n } as unknown as UpdateEvent<this>;\n\n this._emit('update', event);\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n this._emit('updated', event);\n\n return this;\n }\n\n private _buildIndexFor(rawRules: RawRuleFrom<A, Conditions>[]) {\n const indexedRules: IndexTree<A, Conditions> = new Map();\n\n for (let i = rawRules.length - 1; i >= 0; i--) {\n const priority = rawRules.length - i - 1;\n const rule = new Rule(rawRules[i], this._ruleOptions, priority);\n const actions = wrapArray(rule.action);\n const subjects = wrapArray(rule.subject || this._anySubjectType);\n analyze(this, rule);\n\n for (let k = 0; k < subjects.length; k++) {\n const subjectRules = getOrDefault(indexedRules, subjects[k], defaultSubjectEntry);\n\n for (let j = 0; j < actions.length; j++) {\n getOrDefault(subjectRules, actions[j], defaultActionEntry).rules.push(rule);\n }\n }\n }\n\n return indexedRules;\n }\n\n possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[]\n possibleRulesFor(\n action: string,\n subjectType: SubjectType = this._anySubjectType\n ): Rule<A, Conditions>[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"possibleRulesFor\" accepts only subject types (i.e., string or class) as the 2nd parameter');\n }\n\n const subjectRules = getOrDefault(this._indexedRules, subjectType, defaultSubjectEntry);\n const actionRules = getOrDefault(subjectRules, action, defaultActionEntry);\n\n if (actionRules.merged) {\n return actionRules.rules;\n }\n\n const anyActionRules = action !== this._anyAction && subjectRules.has(this._anyAction)\n ? subjectRules.get(this._anyAction)!.rules\n : undefined;\n let rules = mergePrioritized(actionRules.rules, anyActionRules);\n\n if (subjectType !== this._anySubjectType) {\n rules = mergePrioritized(rules, (this as any).possibleRulesFor(action, this._anySubjectType));\n }\n\n actionRules.rules = rules;\n actionRules.merged = true;\n\n return rules;\n }\n\n rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[]\n rulesFor(action: string, subjectType?: SubjectType, field?: string): Rule<A, Conditions>[] {\n const rules: Rule<A, Conditions>[] = (this as any).possibleRulesFor(action, subjectType);\n\n if (field && typeof field !== 'string') {\n throw new Error('The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details');\n }\n\n if (!this._hasPerFieldRules) {\n return rules;\n }\n\n return rules.filter(rule => rule.matchesField(field));\n }\n\n on<T extends keyof EventsMap<this>>(\n event: T,\n handler: EventsMap<Public<this>>[T]\n ): Unsubscribe {\n const tail = this._events.get(event) || null;\n const item = linkedItem(handler, tail);\n this._events.set(event, item);\n\n return () => {\n const currentTail = this._events.get(event);\n\n if (!item.next && !item.prev && currentTail === item) {\n this._events.delete(event);\n } else if (item === currentTail) {\n this._events.set(event, item.prev);\n }\n\n unlinkItem(item);\n };\n }\n\n private _emit<T extends keyof EventsMap<this>>(\n name: T,\n payload: Parameters<EventsMap<this>[T]>[0]\n ) {\n let current = this._events.get(name) || null;\n while (current !== null) {\n const prev = current.prev ? cloneLinkedItem(current.prev) : null;\n current.value(payload);\n current = prev;\n }\n }\n}\n","import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';\nimport { Abilities, AbilityTuple, CanParameters, Subject } from './types';\nimport { Rule } from './Rule';\n\nexport interface AbilityOptions<A extends Abilities, Conditions>\n extends RuleIndexOptions<A, Conditions> {}\nexport interface AnyAbility extends Public<PureAbility<any, any>> {}\nexport interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {}\nexport type AbilityClass<T extends AnyAbility> = new (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport class PureAbility<\n A extends Abilities = AbilityTuple,\n Conditions = unknown\n> extends RuleIndex<A, Conditions> {\n can(...args: CanParameters<A>): boolean {\n const rule = this.relevantRuleFor(...args);\n return !!rule && !rule.inverted;\n }\n\n relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null {\n const subjectType = this.detectSubjectType(subject);\n const rules = (this as any).rulesFor(action, subjectType, field);\n\n for (let i = 0, length = rules.length; i < length; i++) {\n if (rules[i].matchesConditions(subject)) {\n return rules[i];\n }\n }\n\n return null;\n }\n\n cannot(...args: CanParameters<A>): boolean {\n return !this.can(...args);\n }\n}\n","import {\n $eq,\n eq,\n $ne,\n ne,\n $lt,\n lt,\n $lte,\n lte,\n $gt,\n gt,\n $gte,\n gte,\n $in,\n within,\n $nin,\n nin,\n $all,\n all,\n $size,\n size,\n $regex,\n $options,\n regex,\n $elemMatch,\n elemMatch,\n $exists,\n exists,\n and,\n createFactory,\n BuildMongoQuery,\n DefaultOperators,\n} from '@ucast/mongo2js';\nimport { ConditionsMatcher, AnyObject } from '../types';\nimport { Container, GenericFactory } from '../hkt';\n\nconst defaultInstructions = {\n $eq,\n $ne,\n $lt,\n $lte,\n $gt,\n $gte,\n $in,\n $nin,\n $all,\n $size,\n $regex,\n $options,\n $elemMatch,\n $exists,\n};\nconst defaultInterpreters = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n in: within,\n nin,\n all,\n size,\n regex,\n elemMatch,\n exists,\n and,\n};\n\ninterface MongoQueryFactory extends GenericFactory {\n produce: MongoQuery<this[0]>\n}\n\ntype MergeUnion<T extends {}, Keys extends keyof T = keyof T> = { [K in Keys]: T[K] };\nexport type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {\n toplevel: {},\n field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>\n}> & Container<MongoQueryFactory>;\n\ntype MongoQueryMatcherFactory =\n (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;\nexport const buildMongoQueryMatcher = ((instructions, interpreters, options) => createFactory(\n { ...defaultInstructions, ...instructions },\n { ...defaultInterpreters, ...interpreters },\n options\n)) as MongoQueryMatcherFactory;\n\nexport const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);\nexport type {\n MongoQueryFieldOperators,\n MongoQueryTopLevelOperators,\n MongoQueryOperators,\n} from '@ucast/mongo2js';\n","import { FieldMatcher } from '../types';\n\nconst REGEXP_SPECIAL_CHARS = /[-/\\\\^$+?.()|[\\]{}]/g;\nconst REGEXP_ANY = /\\.?\\*+\\.?/g;\nconst REGEXP_STARS = /\\*+/;\nconst REGEXP_DOT = /\\./g;\n\nfunction detectRegexpPattern(match: string, index: number, string: string): string {\n const quantifier = string[0] === '*' || match[0] === '.' && match[match.length - 1] === '.'\n ? '+'\n : '*';\n const matcher = match.indexOf('**') === -1 ? '[^.]' : '.';\n const pattern = match.replace(REGEXP_DOT, '\\\\$&')\n .replace(REGEXP_STARS, matcher + quantifier);\n\n return index + match.length === string.length ? `(?:${pattern})?` : pattern;\n}\n\nfunction escapeRegexp(match: string, index: number, string: string): string {\n if (match === '.' && (string[index - 1] === '*' || string[index + 1] === '*')) {\n return match;\n }\n\n return `\\\\${match}`;\n}\n\nfunction createPattern(fields: string[]) {\n const patterns = fields.map(field => field\n .replace(REGEXP_SPECIAL_CHARS, escapeRegexp)\n .replace(REGEXP_ANY, detectRegexpPattern));\n const pattern = patterns.length > 1 ? `(?:${patterns.join('|')})` : patterns[0];\n\n return new RegExp(`^${pattern}$`);\n}\n\nexport const fieldPatternMatcher: FieldMatcher = (fields) => {\n let pattern: RegExp | null;\n\n return (field) => {\n if (typeof pattern === 'undefined') {\n pattern = fields.every(f => f.indexOf('*') === -1)\n ? null\n : createPattern(fields);\n }\n\n return pattern === null\n ? fields.indexOf(field) !== -1\n : pattern.test(field);\n };\n};\n","import { PureAbility, AbilityOptions } from './PureAbility';\nimport { RawRuleFrom } from './RawRule';\nimport { AbilityTuple } from './types';\nimport { MongoQuery, mongoQueryMatcher } from './matchers/conditions';\nimport { fieldPatternMatcher } from './matchers/field';\nimport { Public } from './RuleIndex';\n\nexport class Ability<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {\n constructor(rules: RawRuleFrom<A, C>[] = [], options: AbilityOptions<A, C> = {}) {\n super(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n }\n}\n\nexport interface AnyMongoAbility extends Public<Ability<any, MongoQuery>> {}\n","import { Ability, AnyMongoAbility } from './Ability';\nimport { AnyAbility, AbilityOptionsOf, AbilityClass } from './PureAbility';\nimport { RawRuleOf, Generics } from './RuleIndex';\nimport {\n ExtractSubjectType as E,\n AbilityTuple,\n SubjectType,\n TaggedInterface,\n Normalize,\n AnyObject,\n AnyClass,\n} from './types';\nimport { ProduceGeneric } from './hkt';\n\nclass RuleBuilder<T extends AnyAbility> {\n public _rule!: RawRuleOf<T>;\n\n constructor(rule: RawRuleOf<T>) {\n this._rule = rule;\n }\n\n because(reason: string): this {\n this._rule.reason = reason;\n return this;\n }\n}\n\ntype InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R>\n ? R\n : S extends string\n ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string>\n ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>>\n : AnyObject\n : never;\ntype ConditionsOf<T extends AnyAbility, I extends {}> =\n ProduceGeneric<Generics<T>['conditions'], I>;\ntype ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any\n ? S extends T[1] ? T[0] : never\n : never;\ntype ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;\ntype SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;\n\ntype SimpleCanParams<T extends AnyAbility> = Parameters<(\n action: Generics<T>['abilities'] | Generics<T>['abilities'][]\n) => 0>;\ntype BuilderCanParameters<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\n\ntype BuilderCanParametersWithFields<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n F extends string,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n fields?: F | F[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\ntype Keys<T> = string & keyof T;\n\nexport class AbilityBuilder<T extends AnyAbility> {\n public rules: RawRuleOf<T>[] = [];\n private _AbilityType!: AnyClass<T>;\n\n constructor(AbilityType: AnyClass<T>) {\n this._AbilityType = AbilityType;\n this.can = this.can.bind(this as any);\n this.cannot = this.cannot.bind(this as any);\n this.build = this.build.bind(this as any);\n }\n\n can<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n can<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n can(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ): RuleBuilder<T> {\n const rule = { action } as RawRuleOf<T>;\n\n if (subject) {\n rule.subject = subject;\n\n if (Array.isArray(conditionsOrFields) || typeof conditionsOrFields === 'string') {\n rule.fields = conditionsOrFields;\n } else if (typeof conditionsOrFields !== 'undefined') {\n rule.conditions = conditionsOrFields;\n }\n\n if (typeof conditions !== 'undefined') {\n rule.conditions = conditions;\n }\n }\n\n this.rules.push(rule);\n\n return new RuleBuilder(rule);\n }\n\n cannot<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n cannot<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n cannot(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions'],\n ): RuleBuilder<T> {\n const builder = (this as any).can(action, subject, conditionsOrFields, conditions);\n builder._rule.inverted = true;\n return builder;\n }\n\n build(options?: AbilityOptionsOf<T>) {\n return new this._AbilityType(this.rules, options);\n }\n}\n\ntype DSL<T extends AnyAbility, R> = (\n can: AbilityBuilder<T>['can'],\n cannot: AbilityBuilder<T>['cannot']\n) => R;\n\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void | Promise<void>>, options?: AbilityOptionsOf<T>): T | Promise<T> {\n const builder = new AbilityBuilder(Ability as unknown as AbilityClass<T>);\n const result = define(builder.can, builder.cannot);\n\n if (result && typeof result.then === 'function') {\n return result.then(() => builder.build(options));\n }\n\n return builder.build(options);\n}\n","import { AnyAbility } from './PureAbility';\nimport { Normalize } from './types';\nimport { Generics } from './RuleIndex';\nimport { getSubjectTypeName } from './utils';\n\nexport type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;\nexport const getDefaultErrorMessage: GetErrorMessage = error => `Cannot execute \"${error.action}\" on \"${error.subjectType}\"`;\n\nconst NativeError = function NError(this: Error, message: string) {\n this.message = message;\n} as unknown as new (message: string) => Error;\n\nNativeError.prototype = Object.create(Error.prototype);\n\nexport class ForbiddenError<T extends AnyAbility> extends NativeError {\n public readonly ability!: T;\n public action!: Normalize<Generics<T>['abilities']>[0];\n public subject!: Generics<T>['abilities'][1];\n public field?: string;\n public subjectType!: string;\n\n static _defaultErrorMessage = getDefaultErrorMessage;\n\n static setDefaultMessage(messageOrFn: string | GetErrorMessage) {\n this._defaultErrorMessage = typeof messageOrFn === 'string' ? () => messageOrFn : messageOrFn;\n }\n\n static from<U extends AnyAbility>(ability: U) {\n return new this<U>(ability);\n }\n\n private constructor(ability: T) {\n super('');\n this.ability = ability;\n\n if (typeof Error.captureStackTrace === 'function') {\n this.name = 'ForbiddenError';\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n setMessage(message: string) {\n this.message = message;\n return this;\n }\n\n throwUnlessCan(...args: Parameters<T['can']>) {\n const rule = this.ability.relevantRuleFor(...args);\n\n if (rule && !rule.inverted) {\n return;\n }\n\n this.action = args[0];\n this.subject = args[1];\n this.subjectType = getSubjectTypeName(this.ability.detectSubjectType(args[1]));\n this.field = args[2];\n\n const reason = rule ? rule.reason : '';\n // eslint-disable-next-line no-underscore-dangle\n this.message = this.message || reason || (this.constructor as any)._defaultErrorMessage(this);\n throw this; // eslint-disable-line\n }\n}\n"],"names":["wrapArray","value","Array","isArray","TYPE_FIELD","setSubjectType","type","object","hasOwnProperty","Object","defineProperty","Error","isSubjectType","getSubjectClassName","modelName","name","getSubjectTypeName","detectSubjectType","subject","constructor","expandActions","aliasMap","rawActions","merge","actions","i","length","action","findDuplicate","actionToFind","indexOf","defaultAliasMerge","concat","validateForCycles","reservedAction","keys","mergeAliasesAndDetectCycles","duplicate","join","isUsingReservedAction","createAliasResolver","options","skipValidate","anyAction","copyArrayTo","dest","target","start","push","mergePrioritized","array","anotherArray","j","merged","priority","getOrDefault","map","key","defaultValue","get","set","identity","x","validate","rule","fields","fieldMatcher","conditions","conditionsMatcher","Rule","resolveAction","inverted","reason","undefined","_options","_conditionsMatcher","this","_matchConditions","matchesConditions","matches","matchesField","field","_matchField","ast","linkedItem","prev","item","next","unlinkItem","cloneLinkedItem","defaultActionEntry","rules","defaultSubjectEntry","Map","analyze","index","_hasPerFieldRules","RuleIndex","_events","_ruleOptions","_anyAction","_anySubjectType","anySubjectType","_detectSubjectType","_rules","_indexedRules","_buildIndexFor","update","event","ability","_emit","rawRules","indexedRules","subjects","k","subjectRules","possibleRulesFor","subjectType","actionRules","anyActionRules","has","rulesFor","filter","on","handler","tail","currentTail","_this","delete","payload","current","PureAbility","can","relevantRuleFor","cannot","defaultInstructions","$eq","$ne","$lt","$lte","$gt","$gte","$in","$nin","$all","$size","$regex","$options","$elemMatch","$exists","defaultInterpreters","eq","ne","lt","lte","gt","gte","in","within","nin","all","size","regex","elemMatch","exists","and","buildMongoQueryMatcher","instructions","interpreters","createFactory","mongoQueryMatcher","REGEXP_SPECIAL_CHARS","REGEXP_ANY","REGEXP_STARS","REGEXP_DOT","detectRegexpPattern","match","string","quantifier","matcher","pattern","replace","escapeRegexp","createPattern","patterns","RegExp","fieldPatternMatcher","every","f","test","Ability","_PureAbility","RuleBuilder","_rule","because","AbilityBuilder","AbilityType","_AbilityType","bind","build","conditionsOrFields","builder","defineAbility","define","result","then","getDefaultErrorMessage","error","NativeError","NError","message","prototype","create","ForbiddenError","setDefaultMessage","messageOrFn","_defaultErrorMessage","from","captureStackTrace","setMessage","throwUnlessCan"],"mappings":"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"}

@@ -1,2 +0,2 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:true});var t=require("@ucast/mongo2js");function e(t){return Array.isArray(t)?t:[t]}const s="__caslSubjectType__";function i(t,e){if(e)if(!e.hasOwnProperty(s))Object.defineProperty(e,s,{value:t});else if(t!==e[s])throw new Error(`Trying to cast object to subject type ${t} but previously it was casted to ${e[s]}`);return e}const r=t=>{const e=typeof t;return"string"===e||"function"===e};const n=t=>t.modelName||t.name;const o=t=>"string"===typeof t?t:n(t);function c(t){if(t.hasOwnProperty(s))return t[s];return n(t.constructor)}function u(t,s,i){let r=e(s);let n=0;while(n<r.length){const e=r[n++];if(t.hasOwnProperty(e))r=i(r,t[e])}return r}function h(t,e){if("string"===typeof e&&-1!==t.indexOf(e))return e;for(let s=0;s<e.length;s++)if(-1!==t.indexOf(e[s]))return e[s];return null}const l=(t,e)=>t.concat(e);function a(t,e){if(e in t)throw new Error(`Cannot use "${e}" as an alias because it's reserved action.`);const s=Object.keys(t);const i=(t,s)=>{const i=h(t,s);if(i)throw new Error(`Detected cycle ${i} -> ${t.join(", ")}`);const r="string"===typeof s&&s===e||-1!==t.indexOf(e)||Array.isArray(s)&&-1!==s.indexOf(e);if(r)throw new Error(`Cannot make an alias to "${e}" because this is reserved action`);return t.concat(s)};for(let e=0;e<s.length;e++)u(t,s[e],i)}function f(t,e){if(!e||false!==e.skipValidate)a(t,e&&e.anyAction||"manage");return e=>u(t,e,l)}function d(t,e,s){for(let i=s;i<e.length;i++)t.push(e[i])}function p(t,e){if(!t||!t.length)return e||[];if(!e||!e.length)return t||[];let s=0;let i=0;const r=[];while(s<t.length&&i<e.length)if(t[s].priority<e[i].priority){r.push(t[s]);s++}else{r.push(e[i]);i++}d(r,t,s);d(r,e,i);return r}function b(t,e,s){let i=t.get(e);if(!i){i=s();t.set(e,i)}return i}const y=t=>t;function w(t,e){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!e.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!e.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}class g{constructor(t,s,i=0){w(t,s);this.action=s.resolveAction(t.action);this.subject=t.subject;this.inverted=!!t.inverted;this.conditions=t.conditions;this.reason=t.reason;this.fields=t.fields?e(t.fields):void 0;this.priority=i;this.t=s}i(){if(this.conditions&&!this.o)this.o=this.t.conditionsMatcher(this.conditions);return this.o}get ast(){const t=this.i();return t?t.ast:void 0}matchesConditions(t){if(!this.conditions)return true;if(!t||r(t))return!this.inverted;const e=this.i();return e(t)}matchesField(t){if(!this.fields)return true;if(!t)return!this.inverted;if(this.fields&&!this.u)this.u=this.t.fieldMatcher(this.fields);return this.u(t)}}function $(t,e){const s={value:t,prev:e,next:null};if(e)e.next=s;return s}function x(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}const E=t=>({value:t.value,prev:t.prev,next:t.next});const v=()=>({rules:[],merged:false});const A=()=>new Map;const m=(t,e)=>{if(!t.h&&e.fields)t.h=true};class M{constructor(t=[],e={}){this.h=false;this.l=new Map;this.p={conditionsMatcher:e.conditionsMatcher,fieldMatcher:e.fieldMatcher,resolveAction:e.resolveAction||y};this.g=e.anyAction||"manage";this.$=e.anySubjectType||"all";this.v=e.detectSubjectType||c;this.A=t;this.m=this.M(t)}get rules(){return this.A}detectSubjectType(t){if(r(t))return t;if(!t)return this.$;return this.v(t)}update(t){const e={rules:t,ability:this,target:this};this.j("update",e);this.A=t;this.m=this.M(t);this.j("updated",e);return this}M(t){const s=new Map;for(let i=t.length-1;i>=0;i--){const r=t.length-i-1;const n=new g(t[i],this.p,r);const o=e(n.action);const c=e(n.subject||this.$);m(this,n);for(let t=0;t<c.length;t++){const e=b(s,c[t],A);for(let t=0;t<o.length;t++)b(e,o[t],v).rules.push(n)}}return s}possibleRulesFor(t,e=this.$){if(!r(e))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');const s=b(this.m,e,A);const i=b(s,t,v);if(i.merged)return i.rules;const n=t!==this.g&&s.has(this.g)?s.get(this.g).rules:void 0;let o=p(i.rules,n);if(e!==this.$)o=p(o,this.possibleRulesFor(t,this.$));i.rules=o;i.merged=true;return o}rulesFor(t,e,s){const i=this.possibleRulesFor(t,e);if(s&&"string"!==typeof s)throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");if(!this.h)return i;return i.filter((t=>t.matchesField(s)))}on(t,e){const s=this.l.get(t)||null;const i=$(e,s);this.l.set(t,i);return()=>{if(!i.next&&!i.prev&&this.l.get(t)===i)this.l.delete(t);else x(i)}}j(t,e){let s=this.l.get(t)||null;while(null!==s){const t=s.prev?E(s.prev):null;s.value(e);s=t}}}class PureAbility extends M{can(...t){const e=this.relevantRuleFor(...t);return!!e&&!e.inverted}relevantRuleFor(t,e,s){const i=this.detectSubjectType(e);const r=this.rulesFor(t,i,s);for(let t=0,s=r.length;t<s;t++)if(r[t].matchesConditions(e))return r[t];return null}cannot(...t){return!this.can(...t)}}const j={$eq:t.$eq,$ne:t.$ne,$lt:t.$lt,$lte:t.$lte,$gt:t.$gt,$gte:t.$gte,$in:t.$in,$nin:t.$nin,$all:t.$all,$size:t.$size,$regex:t.$regex,$options:t.$options,$elemMatch:t.$elemMatch,$exists:t.$exists};const _={eq:t.eq,ne:t.ne,lt:t.lt,lte:t.lte,gt:t.gt,gte:t.gte,in:t.within,nin:t.nin,all:t.all,size:t.size,regex:t.regex,elemMatch:t.elemMatch,exists:t.exists,and:t.and};const F=(e,s,i)=>t.createFactory(Object.assign({},j,e),Object.assign({},_,s),i);const O=t.createFactory(j,_);const C=/[-/\\^$+?.()|[\]{}]/g;const R=/\.?\*+\.?/g;const T=/\*+/;const q=/\./g;function B(t,e,s){const i="*"===s[0]||"."===t[0]&&"."===t[t.length-1]?"+":"*";const r=-1===t.indexOf("**")?"[^.]":".";const n=t.replace(q,"\\$&").replace(T,r+i);return e+t.length===s.length?`(?:${n})?`:n}function P(t,e,s){if("."===t&&("*"===s[e-1]||"*"===s[e+1]))return t;return`\\${t}`}function S(t){const e=t.map((t=>t.replace(C,P).replace(R,B)));const s=e.length>1?`(?:${e.join("|")})`:e[0];return new RegExp(`^${s}$`)}const z=t=>{let e;return s=>{if("undefined"===typeof e)e=t.every((t=>-1===t.indexOf("*")))?null:S(t);return null===e?-1!==t.indexOf(s):e.test(s)}};class Ability extends PureAbility{constructor(t=[],e={}){super(t,Object.assign({conditionsMatcher:O,fieldMatcher:z},e))}}class D{constructor(t){this._=t}because(t){this._.reason=t;return this}}class AbilityBuilder{constructor(t){this.rules=[];this.F=t;this.can=this.can.bind(this);this.cannot=this.cannot.bind(this);this.build=this.build.bind(this)}can(t,e,s,i){const r={action:t};if(e){r.subject=e;if(Array.isArray(s)||"string"===typeof s)r.fields=s;else if("undefined"!==typeof s)r.conditions=s;if("undefined"!==typeof i)r.conditions=i}this.rules.push(r);return new D(r)}cannot(t,e,s,i){const r=this.can(t,e,s,i);r._.inverted=true;return r}build(t){return new this.F(this.rules,t)}}function defineAbility(t,e){const s=new AbilityBuilder(Ability);const i=t(s.can,s.cannot);if(i&&"function"===typeof i.then)return i.then((()=>s.build(e)));return s.build(e)}const Y=t=>`Cannot execute "${t.action}" on "${t.subjectType}"`;const k=function t(e){this.message=e};k.prototype=Object.create(Error.prototype);class ForbiddenError extends k{static setDefaultMessage(t){this.O="string"===typeof t?()=>t:t}static from(t){return new this(t)}constructor(t){super("");this.ability=t;if("function"===typeof Error.captureStackTrace){this.name="ForbiddenError";Error.captureStackTrace(this,this.constructor)}}setMessage(t){this.message=t;return this}throwUnlessCan(...t){const e=this.ability.relevantRuleFor(...t);if(e&&!e.inverted)return;this.action=t[0];this.subject=t[1];this.subjectType=o(this.ability.detectSubjectType(t[1]));this.field=t[2];const s=e?e.reason:"";this.message=this.message||s||this.constructor.O(this);throw this}}ForbiddenError.O=Y;var I=Object.freeze({__proto__:null});exports.Ability=Ability;exports.AbilityBuilder=AbilityBuilder;exports.ForbiddenError=ForbiddenError;exports.PureAbility=PureAbility;exports.buildMongoQueryMatcher=F;exports.createAliasResolver=f;exports.defineAbility=defineAbility;exports.detectSubjectType=c;exports.fieldPatternMatcher=z;exports.getDefaultErrorMessage=Y;exports.hkt=I;exports.mongoQueryMatcher=O;exports.subject=i;exports.wrapArray=e;
"use strict";Object.defineProperty(exports,"__esModule",{value:true});var t=require("@ucast/mongo2js");function e(t){return Array.isArray(t)?t:[t]}const s="__caslSubjectType__";function i(t,e){if(e)if(!e.hasOwnProperty(s))Object.defineProperty(e,s,{value:t});else if(t!==e[s])throw new Error(`Trying to cast object to subject type ${t} but previously it was casted to ${e[s]}`);return e}const r=t=>{const e=typeof t;return"string"===e||"function"===e};const n=t=>t.modelName||t.name;const o=t=>"string"===typeof t?t:n(t);function c(t){if(t.hasOwnProperty(s))return t[s];return n(t.constructor)}function u(t,s,i){let r=e(s);let n=0;while(n<r.length){const e=r[n++];if(t.hasOwnProperty(e))r=i(r,t[e])}return r}function h(t,e){if("string"===typeof e&&-1!==t.indexOf(e))return e;for(let s=0;s<e.length;s++)if(-1!==t.indexOf(e[s]))return e[s];return null}const l=(t,e)=>t.concat(e);function a(t,e){if(e in t)throw new Error(`Cannot use "${e}" as an alias because it's reserved action.`);const s=Object.keys(t);const i=(t,s)=>{const i=h(t,s);if(i)throw new Error(`Detected cycle ${i} -> ${t.join(", ")}`);const r="string"===typeof s&&s===e||-1!==t.indexOf(e)||Array.isArray(s)&&-1!==s.indexOf(e);if(r)throw new Error(`Cannot make an alias to "${e}" because this is reserved action`);return t.concat(s)};for(let e=0;e<s.length;e++)u(t,s[e],i)}function f(t,e){if(!e||false!==e.skipValidate)a(t,e&&e.anyAction||"manage");return e=>u(t,e,l)}function d(t,e,s){for(let i=s;i<e.length;i++)t.push(e[i])}function p(t,e){if(!t||!t.length)return e||[];if(!e||!e.length)return t||[];let s=0;let i=0;const r=[];while(s<t.length&&i<e.length)if(t[s].priority<e[i].priority){r.push(t[s]);s++}else{r.push(e[i]);i++}d(r,t,s);d(r,e,i);return r}function b(t,e,s){let i=t.get(e);if(!i){i=s();t.set(e,i)}return i}const y=t=>t;function w(t,e){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!e.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!e.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}class g{constructor(t,s,i=0){w(t,s);this.action=s.resolveAction(t.action);this.subject=t.subject;this.inverted=!!t.inverted;this.conditions=t.conditions;this.reason=t.reason;this.fields=t.fields?e(t.fields):void 0;this.priority=i;this.t=s}i(){if(this.conditions&&!this.o)this.o=this.t.conditionsMatcher(this.conditions);return this.o}get ast(){const t=this.i();return t?t.ast:void 0}matchesConditions(t){if(!this.conditions)return true;if(!t||r(t))return!this.inverted;const e=this.i();return e(t)}matchesField(t){if(!this.fields)return true;if(!t)return!this.inverted;if(this.fields&&!this.u)this.u=this.t.fieldMatcher(this.fields);return this.u(t)}}function $(t,e){const s={value:t,prev:e,next:null};if(e)e.next=s;return s}function x(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}const E=t=>({value:t.value,prev:t.prev,next:t.next});const v=()=>({rules:[],merged:false});const A=()=>new Map;const m=(t,e)=>{if(!t.h&&e.fields)t.h=true};class M{constructor(t=[],e={}){this.h=false;this.l=new Map;this.p={conditionsMatcher:e.conditionsMatcher,fieldMatcher:e.fieldMatcher,resolveAction:e.resolveAction||y};this.g=e.anyAction||"manage";this.$=e.anySubjectType||"all";this.v=e.detectSubjectType||c;this.A=t;this.m=this.M(t)}get rules(){return this.A}detectSubjectType(t){if(r(t))return t;if(!t)return this.$;return this.v(t)}update(t){const e={rules:t,ability:this,target:this};this.j("update",e);this.A=t;this.m=this.M(t);this.j("updated",e);return this}M(t){const s=new Map;for(let i=t.length-1;i>=0;i--){const r=t.length-i-1;const n=new g(t[i],this.p,r);const o=e(n.action);const c=e(n.subject||this.$);m(this,n);for(let t=0;t<c.length;t++){const e=b(s,c[t],A);for(let t=0;t<o.length;t++)b(e,o[t],v).rules.push(n)}}return s}possibleRulesFor(t,e=this.$){if(!r(e))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');const s=b(this.m,e,A);const i=b(s,t,v);if(i.merged)return i.rules;const n=t!==this.g&&s.has(this.g)?s.get(this.g).rules:void 0;let o=p(i.rules,n);if(e!==this.$)o=p(o,this.possibleRulesFor(t,this.$));i.rules=o;i.merged=true;return o}rulesFor(t,e,s){const i=this.possibleRulesFor(t,e);if(s&&"string"!==typeof s)throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");if(!this.h)return i;return i.filter((t=>t.matchesField(s)))}on(t,e){const s=this.l.get(t)||null;const i=$(e,s);this.l.set(t,i);return()=>{const e=this.l.get(t);if(!i.next&&!i.prev&&e===i)this.l.delete(t);else if(i===e)this.l.set(t,i.prev);x(i)}}j(t,e){let s=this.l.get(t)||null;while(null!==s){const t=s.prev?E(s.prev):null;s.value(e);s=t}}}class PureAbility extends M{can(...t){const e=this.relevantRuleFor(...t);return!!e&&!e.inverted}relevantRuleFor(t,e,s){const i=this.detectSubjectType(e);const r=this.rulesFor(t,i,s);for(let t=0,s=r.length;t<s;t++)if(r[t].matchesConditions(e))return r[t];return null}cannot(...t){return!this.can(...t)}}const j={$eq:t.$eq,$ne:t.$ne,$lt:t.$lt,$lte:t.$lte,$gt:t.$gt,$gte:t.$gte,$in:t.$in,$nin:t.$nin,$all:t.$all,$size:t.$size,$regex:t.$regex,$options:t.$options,$elemMatch:t.$elemMatch,$exists:t.$exists};const _={eq:t.eq,ne:t.ne,lt:t.lt,lte:t.lte,gt:t.gt,gte:t.gte,in:t.within,nin:t.nin,all:t.all,size:t.size,regex:t.regex,elemMatch:t.elemMatch,exists:t.exists,and:t.and};const F=(e,s,i)=>t.createFactory(Object.assign({},j,e),Object.assign({},_,s),i);const O=t.createFactory(j,_);const C=/[-/\\^$+?.()|[\]{}]/g;const R=/\.?\*+\.?/g;const T=/\*+/;const q=/\./g;function B(t,e,s){const i="*"===s[0]||"."===t[0]&&"."===t[t.length-1]?"+":"*";const r=-1===t.indexOf("**")?"[^.]":".";const n=t.replace(q,"\\$&").replace(T,r+i);return e+t.length===s.length?`(?:${n})?`:n}function P(t,e,s){if("."===t&&("*"===s[e-1]||"*"===s[e+1]))return t;return`\\${t}`}function S(t){const e=t.map((t=>t.replace(C,P).replace(R,B)));const s=e.length>1?`(?:${e.join("|")})`:e[0];return new RegExp(`^${s}$`)}const z=t=>{let e;return s=>{if("undefined"===typeof e)e=t.every((t=>-1===t.indexOf("*")))?null:S(t);return null===e?-1!==t.indexOf(s):e.test(s)}};class Ability extends PureAbility{constructor(t=[],e={}){super(t,Object.assign({conditionsMatcher:O,fieldMatcher:z},e))}}class D{constructor(t){this._=t}because(t){this._.reason=t;return this}}class AbilityBuilder{constructor(t){this.rules=[];this.F=t;this.can=this.can.bind(this);this.cannot=this.cannot.bind(this);this.build=this.build.bind(this)}can(t,e,s,i){const r={action:t};if(e){r.subject=e;if(Array.isArray(s)||"string"===typeof s)r.fields=s;else if("undefined"!==typeof s)r.conditions=s;if("undefined"!==typeof i)r.conditions=i}this.rules.push(r);return new D(r)}cannot(t,e,s,i){const r=this.can(t,e,s,i);r._.inverted=true;return r}build(t){return new this.F(this.rules,t)}}function defineAbility(t,e){const s=new AbilityBuilder(Ability);const i=t(s.can,s.cannot);if(i&&"function"===typeof i.then)return i.then((()=>s.build(e)));return s.build(e)}const Y=t=>`Cannot execute "${t.action}" on "${t.subjectType}"`;const k=function t(e){this.message=e};k.prototype=Object.create(Error.prototype);class ForbiddenError extends k{static setDefaultMessage(t){this.O="string"===typeof t?()=>t:t}static from(t){return new this(t)}constructor(t){super("");this.ability=t;if("function"===typeof Error.captureStackTrace){this.name="ForbiddenError";Error.captureStackTrace(this,this.constructor)}}setMessage(t){this.message=t;return this}throwUnlessCan(...t){const e=this.ability.relevantRuleFor(...t);if(e&&!e.inverted)return;this.action=t[0];this.subject=t[1];this.subjectType=o(this.ability.detectSubjectType(t[1]));this.field=t[2];const s=e?e.reason:"";this.message=this.message||s||this.constructor.O(this);throw this}}ForbiddenError.O=Y;var I=Object.freeze({__proto__:null});exports.Ability=Ability;exports.AbilityBuilder=AbilityBuilder;exports.ForbiddenError=ForbiddenError;exports.PureAbility=PureAbility;exports.buildMongoQueryMatcher=F;exports.createAliasResolver=f;exports.defineAbility=defineAbility;exports.detectSubjectType=c;exports.fieldPatternMatcher=z;exports.getDefaultErrorMessage=Y;exports.hkt=I;exports.mongoQueryMatcher=O;exports.subject=i;exports.wrapArray=e;
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../../src/utils.ts","../../src/Rule.ts","../../src/structures/LinkedItem.ts","../../src/RuleIndex.ts","../../src/PureAbility.ts","../../src/matchers/conditions.ts","../../src/matchers/field.ts","../../src/Ability.ts","../../src/AbilityBuilder.ts","../../src/ForbiddenError.ts"],"sourcesContent":["import { AnyObject, Subject, SubjectType, SubjectClass, ForcedSubject, AliasesMap } from './types';\n\nexport function wrapArray<T>(value: T[] | T): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function setByPath(object: AnyObject, path: string, value: unknown): void {\n let ref = object;\n let lastKey = path;\n\n if (path.indexOf('.') !== -1) {\n const keys = path.split('.');\n\n lastKey = keys.pop()!;\n ref = keys.reduce((res, prop) => {\n res[prop] = res[prop] || {};\n return res[prop] as AnyObject;\n }, object);\n }\n\n ref[lastKey] = value;\n}\n\nconst TYPE_FIELD = '__caslSubjectType__';\nexport function setSubjectType<\n T extends string,\n U extends Record<PropertyKey, any>\n>(type: T, object: U): U & ForcedSubject<T> {\n if (object) {\n if (!object.hasOwnProperty(TYPE_FIELD)) {\n Object.defineProperty(object, TYPE_FIELD, { value: type });\n } else if (type !== object[TYPE_FIELD]) {\n throw new Error(`Trying to cast object to subject type ${type} but previously it was casted to ${object[TYPE_FIELD]}`);\n }\n }\n\n return object as U & ForcedSubject<T>;\n}\n\nexport const isSubjectType = (value: unknown): value is SubjectType => {\n const type = typeof value;\n return type === 'string' || type === 'function';\n};\n\nconst getSubjectClassName = (value: SubjectClass) => value.modelName || value.name;\nexport const getSubjectTypeName = (value: SubjectType) => {\n return typeof value === 'string' ? value : getSubjectClassName(value);\n};\n\nexport function detectSubjectType(subject: Exclude<Subject, SubjectType>): string {\n if (subject.hasOwnProperty(TYPE_FIELD)) {\n return (subject as any)[TYPE_FIELD];\n }\n\n return getSubjectClassName(subject.constructor as SubjectClass);\n}\n\ntype AliasMerge = (actions: string[], action: string | string[]) => string[];\nfunction expandActions(aliasMap: AliasesMap, rawActions: string | string[], merge: AliasMerge) {\n let actions = wrapArray(rawActions);\n let i = 0;\n\n while (i < actions.length) {\n const action = actions[i++];\n\n if (aliasMap.hasOwnProperty(action)) {\n actions = merge(actions, aliasMap[action]);\n }\n }\n\n return actions;\n}\n\nfunction findDuplicate(actions: string[], actionToFind: string | string[]) {\n if (typeof actionToFind === 'string' && actions.indexOf(actionToFind) !== -1) {\n return actionToFind;\n }\n\n for (let i = 0; i < actionToFind.length; i++) {\n if (actions.indexOf(actionToFind[i]) !== -1) return actionToFind[i];\n }\n\n return null;\n}\n\nconst defaultAliasMerge: AliasMerge = (actions, action) => actions.concat(action);\nfunction validateForCycles(aliasMap: AliasesMap, reservedAction: string) {\n if (reservedAction in aliasMap) {\n throw new Error(`Cannot use \"${reservedAction}\" as an alias because it's reserved action.`);\n }\n\n const keys = Object.keys(aliasMap);\n const mergeAliasesAndDetectCycles: AliasMerge = (actions, action) => {\n const duplicate = findDuplicate(actions, action);\n if (duplicate) throw new Error(`Detected cycle ${duplicate} -> ${actions.join(', ')}`);\n\n const isUsingReservedAction = typeof action === 'string' && action === reservedAction\n || actions.indexOf(reservedAction) !== -1\n || Array.isArray(action) && action.indexOf(reservedAction) !== -1;\n if (isUsingReservedAction) throw new Error(`Cannot make an alias to \"${reservedAction}\" because this is reserved action`);\n\n return actions.concat(action);\n };\n\n for (let i = 0; i < keys.length; i++) {\n expandActions(aliasMap, keys[i], mergeAliasesAndDetectCycles);\n }\n}\n\nexport type AliasResolverOptions = { skipValidate?: boolean; anyAction?: string };\nexport function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions) {\n if (!options || options.skipValidate !== false) {\n validateForCycles(aliasMap, options && options.anyAction || 'manage');\n }\n\n return (action: string | string[]) => expandActions(aliasMap, action, defaultAliasMerge);\n}\n\nfunction copyArrayTo<T>(dest: T[], target: T[], start: number) {\n for (let i = start; i < target.length; i++) {\n dest.push(target[i]);\n }\n}\n\nexport function mergePrioritized<T extends { priority: number }>(\n array?: T[],\n anotherArray?: T[]\n): T[] {\n if (!array || !array.length) {\n return anotherArray || [];\n }\n\n if (!anotherArray || !anotherArray.length) {\n return array || [];\n }\n\n let i = 0;\n let j = 0;\n const merged: T[] = [];\n\n while (i < array.length && j < anotherArray.length) {\n if (array[i].priority < anotherArray[j].priority) {\n merged.push(array[i]);\n i++;\n } else {\n merged.push(anotherArray[j]);\n j++;\n }\n }\n\n copyArrayTo(merged, array, i);\n copyArrayTo(merged, anotherArray, j);\n\n return merged;\n}\n\nexport function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V) {\n let value = map.get(key);\n\n if (!value) {\n value = defaultValue();\n map.set(key, value);\n }\n\n return value;\n}\n\nexport const identity = <T>(x: T) => x;\n","import { wrapArray, isSubjectType } from './utils';\nimport {\n MatchConditions,\n MatchField,\n Abilities,\n ToAbilityTypes,\n Normalize,\n ConditionsMatcher,\n FieldMatcher,\n} from './types';\nimport { RawRule, RawRuleFrom } from './RawRule';\n\ntype Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;\n\nfunction validate(rule: RawRuleFrom<Abilities, any>, options: RuleOptions<any>) {\n if (Array.isArray(rule.fields) && !rule.fields.length) {\n throw new Error('`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa');\n }\n\n if (rule.fields && !options.fieldMatcher) {\n throw new Error('You need to pass \"fieldMatcher\" option in order to restrict access by fields');\n }\n\n if (rule.conditions && !options.conditionsMatcher) {\n throw new Error('You need to pass \"conditionsMatcher\" option in order to restrict access by conditions');\n }\n}\n\nexport interface RuleOptions<Conditions> {\n conditionsMatcher?: ConditionsMatcher<Conditions>\n fieldMatcher?: FieldMatcher\n resolveAction(action: string | string[]): string | string[]\n}\n\nexport class Rule<A extends Abilities, C> {\n private _matchConditions: MatchConditions | undefined;\n private _matchField: MatchField<string> | undefined;\n private readonly _options!: RuleOptions<C>;\n public readonly action!: Tuple<A>[0] | Tuple<A>[0][];\n public readonly subject!: Tuple<A>[1] | Tuple<A>[1][];\n public readonly inverted!: boolean;\n public readonly conditions!: C | undefined;\n public readonly fields!: string[] | undefined;\n public readonly reason!: string | undefined;\n public readonly priority!: number;\n\n constructor(\n rule: RawRule<ToAbilityTypes<A>, C>,\n options: RuleOptions<C>,\n priority: number = 0\n ) {\n validate(rule, options);\n\n this.action = options.resolveAction(rule.action);\n this.subject = rule.subject!;\n this.inverted = !!rule.inverted;\n this.conditions = rule.conditions;\n this.reason = rule.reason;\n this.fields = rule.fields ? wrapArray(rule.fields) : undefined;\n this.priority = priority;\n this._options = options;\n }\n\n private _conditionsMatcher() {\n if (this.conditions && !this._matchConditions) {\n this._matchConditions = this._options.conditionsMatcher!(this.conditions);\n }\n\n return this._matchConditions!;\n }\n\n get ast() {\n const matches = this._conditionsMatcher();\n return matches ? matches.ast : undefined;\n }\n\n matchesConditions(object: Normalize<A>[1] | undefined): boolean {\n if (!this.conditions) {\n return true;\n }\n\n if (!object || isSubjectType(object)) {\n return !this.inverted;\n }\n\n const matches = this._conditionsMatcher();\n return matches(object as Record<string, unknown>);\n }\n\n matchesField(field: string | undefined): boolean {\n if (!this.fields) {\n return true;\n }\n\n if (!field) {\n return !this.inverted;\n }\n\n if (this.fields && !this._matchField) {\n this._matchField = this._options.fieldMatcher!(this.fields);\n }\n\n return this._matchField!(field);\n }\n}\n","export interface LinkedItem<T> {\n next: LinkedItem<T> | null\n prev: LinkedItem<T> | null\n readonly value: T\n}\n\nexport function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']) {\n const item = { value, prev, next: null };\n\n if (prev) {\n prev.next = item;\n }\n\n return item;\n}\n\nexport function unlinkItem(item: LinkedItem<any>) {\n if (item.next) {\n item.next.prev = item.prev;\n }\n\n if (item.prev) {\n item.prev.next = item.next;\n }\n\n item.next = item.prev = null; // eslint-disable-line\n}\n\nexport const cloneLinkedItem = <T extends LinkedItem<any>>(item: T): T => ({\n value: item.value,\n prev: item.prev,\n next: item.next,\n} as T);\n","import { Rule, RuleOptions } from './Rule';\nimport { RawRuleFrom } from './RawRule';\nimport {\n Abilities,\n Normalize,\n SubjectType,\n AbilityParameters,\n AbilityTuple,\n ExtractSubjectType\n} from './types';\nimport { wrapArray, detectSubjectType, mergePrioritized, getOrDefault, identity, isSubjectType } from './utils';\nimport { LinkedItem, linkedItem, unlinkItem, cloneLinkedItem } from './structures/LinkedItem';\n\nexport interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {\n detectSubjectType?(\n subject: Exclude<Normalize<A>[1], SubjectType>\n ): ExtractSubjectType<Normalize<A>[1]>;\n anyAction?: string;\n anySubjectType?: string;\n}\n\ndeclare const $abilities: unique symbol;\ndeclare const $conditions: unique symbol;\ninterface WithGenerics {\n [$abilities]: any\n [$conditions]: any\n}\nexport type Public<T extends WithGenerics> = { [K in keyof T]: T[K] };\nexport interface Generics<T extends WithGenerics> {\n abilities: T[typeof $abilities],\n conditions: T[typeof $conditions]\n}\n\nexport type RuleOf<T extends WithGenerics> =\n Rule<Generics<T>['abilities'], Generics<T>['conditions']>;\nexport type RawRuleOf<T extends WithGenerics> =\n RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;\n\nexport type RuleIndexOptionsOf<T extends WithGenerics> =\n RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;\n\ninterface AbilityEvent<T extends WithGenerics> {\n target: T\n /** @deprecated use \"target\" property instead */\n ability: T\n}\n\nexport interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {\n rules: RawRuleOf<T>[]\n}\n/**\n * @deprecated `on`/`emit` properly infer type without this type\n * TODO(major): delete\n */\nexport type EventHandler<Event> = (event: Event) => void;\n\nexport type Events<\n T extends WithGenerics,\n K extends keyof EventsMap<T> = keyof EventsMap<T>\n> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;\n\ninterface EventsMap<T extends WithGenerics> {\n update(event: UpdateEvent<T>): void\n updated(event: UpdateEvent<T>): void\n}\n\ntype IndexTree<A extends Abilities, C> = Map<SubjectType, Map<string, {\n rules: Rule<A, C>[],\n merged: boolean\n}>>;\n\nexport type Unsubscribe = () => void;\n\nconst defaultActionEntry = () => ({\n rules: [] as unknown as Rule<any, any>[],\n merged: false\n});\nconst defaultSubjectEntry = () => new Map<string, ReturnType<typeof defaultActionEntry>>();\nconst analyze = (index: any, rule: Rule<any, any>) => {\n if (!index._hasPerFieldRules && rule.fields) {\n index._hasPerFieldRules = true;\n }\n};\n\ntype AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> =\n AbilityParameters<\n T,\n T extends AbilityTuple\n ? IncludeField extends true\n ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0\n : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0\n : never,\n (action: Extract<T, string>) => 0\n >;\n\nexport class RuleIndex<A extends Abilities, Conditions> {\n private _hasPerFieldRules: boolean = false;\n private _events: Events<this> = new Map();\n private _indexedRules!: IndexTree<A, Conditions>;\n private _rules!: RawRuleFrom<A, Conditions>[];\n private readonly _ruleOptions!: RuleOptions<Conditions>;\n private readonly _detectSubjectType!: Required<RuleIndexOptions<A, Conditions>>['detectSubjectType'];\n private readonly _anyAction: string;\n private readonly _anySubjectType: string;\n readonly [$abilities]!: A;\n readonly [$conditions]!: Conditions;\n\n constructor(\n rules: RawRuleFrom<A, Conditions>[] = [],\n options: RuleIndexOptions<A, Conditions> = {}\n ) {\n this._ruleOptions = {\n conditionsMatcher: options.conditionsMatcher,\n fieldMatcher: options.fieldMatcher,\n resolveAction: options.resolveAction || identity,\n };\n this._anyAction = options.anyAction || 'manage';\n this._anySubjectType = options.anySubjectType || 'all';\n this._detectSubjectType = options.detectSubjectType || detectSubjectType;\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n }\n\n get rules() {\n return this._rules;\n }\n\n detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]> {\n if (isSubjectType(object)) return object;\n if (!object) return this._anySubjectType;\n return this._detectSubjectType(object as Exclude<Normalize<A>[1], SubjectType>);\n }\n\n update(rules: RawRuleFrom<A, Conditions>[]): Public<this> {\n const event = {\n rules,\n ability: this,\n target: this\n } as unknown as UpdateEvent<this>;\n\n this._emit('update', event);\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n this._emit('updated', event);\n\n return this;\n }\n\n private _buildIndexFor(rawRules: RawRuleFrom<A, Conditions>[]) {\n const indexedRules: IndexTree<A, Conditions> = new Map();\n\n for (let i = rawRules.length - 1; i >= 0; i--) {\n const priority = rawRules.length - i - 1;\n const rule = new Rule(rawRules[i], this._ruleOptions, priority);\n const actions = wrapArray(rule.action);\n const subjects = wrapArray(rule.subject || this._anySubjectType);\n analyze(this, rule);\n\n for (let k = 0; k < subjects.length; k++) {\n const subjectRules = getOrDefault(indexedRules, subjects[k], defaultSubjectEntry);\n\n for (let j = 0; j < actions.length; j++) {\n getOrDefault(subjectRules, actions[j], defaultActionEntry).rules.push(rule);\n }\n }\n }\n\n return indexedRules;\n }\n\n possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[]\n possibleRulesFor(\n action: string,\n subjectType: SubjectType = this._anySubjectType\n ): Rule<A, Conditions>[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"possibleRulesFor\" accepts only subject types (i.e., string or class) as the 2nd parameter');\n }\n\n const subjectRules = getOrDefault(this._indexedRules, subjectType, defaultSubjectEntry);\n const actionRules = getOrDefault(subjectRules, action, defaultActionEntry);\n\n if (actionRules.merged) {\n return actionRules.rules;\n }\n\n const anyActionRules = action !== this._anyAction && subjectRules.has(this._anyAction)\n ? subjectRules.get(this._anyAction)!.rules\n : undefined;\n let rules = mergePrioritized(actionRules.rules, anyActionRules);\n\n if (subjectType !== this._anySubjectType) {\n rules = mergePrioritized(rules, (this as any).possibleRulesFor(action, this._anySubjectType));\n }\n\n actionRules.rules = rules;\n actionRules.merged = true;\n\n return rules;\n }\n\n rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[]\n rulesFor(action: string, subjectType?: SubjectType, field?: string): Rule<A, Conditions>[] {\n const rules: Rule<A, Conditions>[] = (this as any).possibleRulesFor(action, subjectType);\n\n if (field && typeof field !== 'string') {\n throw new Error('The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details');\n }\n\n if (!this._hasPerFieldRules) {\n return rules;\n }\n\n return rules.filter(rule => rule.matchesField(field));\n }\n\n on<T extends keyof EventsMap<this>>(\n event: T,\n handler: EventsMap<Public<this>>[T]\n ): Unsubscribe {\n const head = this._events.get(event) || null;\n const item = linkedItem(handler, head);\n this._events.set(event, item);\n\n return () => {\n if (!item.next && !item.prev && this._events.get(event) === item) {\n this._events.delete(event);\n } else {\n unlinkItem(item);\n }\n };\n }\n\n private _emit<T extends keyof EventsMap<this>>(\n name: T,\n payload: Parameters<EventsMap<this>[T]>[0]\n ) {\n let current = this._events.get(name) || null;\n while (current !== null) {\n const prev = current.prev ? cloneLinkedItem(current.prev) : null;\n current.value(payload);\n current = prev;\n }\n }\n}\n","import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';\nimport { Abilities, AbilityTuple, CanParameters, Subject } from './types';\nimport { Rule } from './Rule';\n\nexport interface AbilityOptions<A extends Abilities, Conditions>\n extends RuleIndexOptions<A, Conditions> {}\nexport interface AnyAbility extends Public<PureAbility<any, any>> {}\nexport interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {}\nexport type AbilityClass<T extends AnyAbility> = new (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport class PureAbility<\n A extends Abilities = AbilityTuple,\n Conditions = unknown\n> extends RuleIndex<A, Conditions> {\n can(...args: CanParameters<A>): boolean {\n const rule = this.relevantRuleFor(...args);\n return !!rule && !rule.inverted;\n }\n\n relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null {\n const subjectType = this.detectSubjectType(subject);\n const rules = (this as any).rulesFor(action, subjectType, field);\n\n for (let i = 0, length = rules.length; i < length; i++) {\n if (rules[i].matchesConditions(subject)) {\n return rules[i];\n }\n }\n\n return null;\n }\n\n cannot(...args: CanParameters<A>): boolean {\n return !this.can(...args);\n }\n}\n","import {\n $eq,\n eq,\n $ne,\n ne,\n $lt,\n lt,\n $lte,\n lte,\n $gt,\n gt,\n $gte,\n gte,\n $in,\n within,\n $nin,\n nin,\n $all,\n all,\n $size,\n size,\n $regex,\n $options,\n regex,\n $elemMatch,\n elemMatch,\n $exists,\n exists,\n and,\n createFactory,\n BuildMongoQuery,\n DefaultOperators,\n} from '@ucast/mongo2js';\nimport { ConditionsMatcher, AnyObject } from '../types';\nimport { Container, GenericFactory } from '../hkt';\n\nconst defaultInstructions = {\n $eq,\n $ne,\n $lt,\n $lte,\n $gt,\n $gte,\n $in,\n $nin,\n $all,\n $size,\n $regex,\n $options,\n $elemMatch,\n $exists,\n};\nconst defaultInterpreters = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n in: within,\n nin,\n all,\n size,\n regex,\n elemMatch,\n exists,\n and,\n};\n\ninterface MongoQueryFactory extends GenericFactory {\n produce: MongoQuery<this[0]>\n}\n\ntype MergeUnion<T extends {}, Keys extends keyof T = keyof T> = { [K in Keys]: T[K] };\nexport type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {\n toplevel: {},\n field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>\n}> & Container<MongoQueryFactory>;\n\ntype MongoQueryMatcherFactory =\n (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;\nexport const buildMongoQueryMatcher = ((instructions, interpreters, options) => createFactory(\n { ...defaultInstructions, ...instructions },\n { ...defaultInterpreters, ...interpreters },\n options\n)) as MongoQueryMatcherFactory;\n\nexport const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);\nexport type {\n MongoQueryFieldOperators,\n MongoQueryTopLevelOperators,\n MongoQueryOperators,\n} from '@ucast/mongo2js';\n","import { FieldMatcher } from '../types';\n\nconst REGEXP_SPECIAL_CHARS = /[-/\\\\^$+?.()|[\\]{}]/g;\nconst REGEXP_ANY = /\\.?\\*+\\.?/g;\nconst REGEXP_STARS = /\\*+/;\nconst REGEXP_DOT = /\\./g;\n\nfunction detectRegexpPattern(match: string, index: number, string: string): string {\n const quantifier = string[0] === '*' || match[0] === '.' && match[match.length - 1] === '.'\n ? '+'\n : '*';\n const matcher = match.indexOf('**') === -1 ? '[^.]' : '.';\n const pattern = match.replace(REGEXP_DOT, '\\\\$&')\n .replace(REGEXP_STARS, matcher + quantifier);\n\n return index + match.length === string.length ? `(?:${pattern})?` : pattern;\n}\n\nfunction escapeRegexp(match: string, index: number, string: string): string {\n if (match === '.' && (string[index - 1] === '*' || string[index + 1] === '*')) {\n return match;\n }\n\n return `\\\\${match}`;\n}\n\nfunction createPattern(fields: string[]) {\n const patterns = fields.map(field => field\n .replace(REGEXP_SPECIAL_CHARS, escapeRegexp)\n .replace(REGEXP_ANY, detectRegexpPattern));\n const pattern = patterns.length > 1 ? `(?:${patterns.join('|')})` : patterns[0];\n\n return new RegExp(`^${pattern}$`);\n}\n\nexport const fieldPatternMatcher: FieldMatcher = (fields) => {\n let pattern: RegExp | null;\n\n return (field) => {\n if (typeof pattern === 'undefined') {\n pattern = fields.every(f => f.indexOf('*') === -1)\n ? null\n : createPattern(fields);\n }\n\n return pattern === null\n ? fields.indexOf(field) !== -1\n : pattern.test(field);\n };\n};\n","import { PureAbility, AbilityOptions } from './PureAbility';\nimport { RawRuleFrom } from './RawRule';\nimport { AbilityTuple } from './types';\nimport { MongoQuery, mongoQueryMatcher } from './matchers/conditions';\nimport { fieldPatternMatcher } from './matchers/field';\nimport { Public } from './RuleIndex';\n\nexport class Ability<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {\n constructor(rules: RawRuleFrom<A, C>[] = [], options: AbilityOptions<A, C> = {}) {\n super(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n }\n}\n\nexport interface AnyMongoAbility extends Public<Ability<any, MongoQuery>> {}\n","import { Ability, AnyMongoAbility } from './Ability';\nimport { AnyAbility, AbilityOptionsOf, AbilityClass } from './PureAbility';\nimport { RawRuleOf, Generics } from './RuleIndex';\nimport {\n ExtractSubjectType as E,\n AbilityTuple,\n SubjectType,\n TaggedInterface,\n Normalize,\n AnyObject,\n AnyClass,\n} from './types';\nimport { ProduceGeneric } from './hkt';\n\nclass RuleBuilder<T extends AnyAbility> {\n public _rule!: RawRuleOf<T>;\n\n constructor(rule: RawRuleOf<T>) {\n this._rule = rule;\n }\n\n because(reason: string): this {\n this._rule.reason = reason;\n return this;\n }\n}\n\ntype InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R>\n ? R\n : S extends string\n ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string>\n ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>>\n : AnyObject\n : never;\ntype ConditionsOf<T extends AnyAbility, I extends {}> =\n ProduceGeneric<Generics<T>['conditions'], I>;\ntype ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any\n ? S extends T[1] ? T[0] : never\n : never;\ntype ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;\ntype SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;\n\ntype SimpleCanParams<T extends AnyAbility> = Parameters<(\n action: Generics<T>['abilities'] | Generics<T>['abilities'][]\n) => 0>;\ntype BuilderCanParameters<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\n\ntype BuilderCanParametersWithFields<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n F extends string,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n fields?: F | F[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\ntype Keys<T> = string & keyof T;\n\nexport class AbilityBuilder<T extends AnyAbility> {\n public rules: RawRuleOf<T>[] = [];\n private _AbilityType!: AnyClass<T>;\n\n constructor(AbilityType: AnyClass<T>) {\n this._AbilityType = AbilityType;\n this.can = this.can.bind(this as any);\n this.cannot = this.cannot.bind(this as any);\n this.build = this.build.bind(this as any);\n }\n\n can<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n can<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n can(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ): RuleBuilder<T> {\n const rule = { action } as RawRuleOf<T>;\n\n if (subject) {\n rule.subject = subject;\n\n if (Array.isArray(conditionsOrFields) || typeof conditionsOrFields === 'string') {\n rule.fields = conditionsOrFields;\n } else if (typeof conditionsOrFields !== 'undefined') {\n rule.conditions = conditionsOrFields;\n }\n\n if (typeof conditions !== 'undefined') {\n rule.conditions = conditions;\n }\n }\n\n this.rules.push(rule);\n\n return new RuleBuilder(rule);\n }\n\n cannot<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n cannot<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n cannot(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions'],\n ): RuleBuilder<T> {\n const builder = (this as any).can(action, subject, conditionsOrFields, conditions);\n builder._rule.inverted = true;\n return builder;\n }\n\n build(options?: AbilityOptionsOf<T>) {\n return new this._AbilityType(this.rules, options);\n }\n}\n\ntype DSL<T extends AnyAbility, R> = (\n can: AbilityBuilder<T>['can'],\n cannot: AbilityBuilder<T>['cannot']\n) => R;\n\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void | Promise<void>>, options?: AbilityOptionsOf<T>): T | Promise<T> {\n const builder = new AbilityBuilder(Ability as unknown as AbilityClass<T>);\n const result = define(builder.can, builder.cannot);\n\n if (result && typeof result.then === 'function') {\n return result.then(() => builder.build(options));\n }\n\n return builder.build(options);\n}\n","import { AnyAbility } from './PureAbility';\nimport { Normalize } from './types';\nimport { Generics } from './RuleIndex';\nimport { getSubjectTypeName } from './utils';\n\nexport type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;\nexport const getDefaultErrorMessage: GetErrorMessage = error => `Cannot execute \"${error.action}\" on \"${error.subjectType}\"`;\n\nconst NativeError = function NError(this: Error, message: string) {\n this.message = message;\n} as unknown as new (message: string) => Error;\n\nNativeError.prototype = Object.create(Error.prototype);\n\nexport class ForbiddenError<T extends AnyAbility> extends NativeError {\n public readonly ability!: T;\n public action!: Normalize<Generics<T>['abilities']>[0];\n public subject!: Generics<T>['abilities'][1];\n public field?: string;\n public subjectType!: string;\n\n static _defaultErrorMessage = getDefaultErrorMessage;\n\n static setDefaultMessage(messageOrFn: string | GetErrorMessage) {\n this._defaultErrorMessage = typeof messageOrFn === 'string' ? () => messageOrFn : messageOrFn;\n }\n\n static from<U extends AnyAbility>(ability: U) {\n return new this<U>(ability);\n }\n\n private constructor(ability: T) {\n super('');\n this.ability = ability;\n\n if (typeof Error.captureStackTrace === 'function') {\n this.name = 'ForbiddenError';\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n setMessage(message: string) {\n this.message = message;\n return this;\n }\n\n throwUnlessCan(...args: Parameters<T['can']>) {\n const rule = this.ability.relevantRuleFor(...args);\n\n if (rule && !rule.inverted) {\n return;\n }\n\n this.action = args[0];\n this.subject = args[1];\n this.subjectType = getSubjectTypeName(this.ability.detectSubjectType(args[1]));\n this.field = args[2];\n\n const reason = rule ? rule.reason : '';\n // eslint-disable-next-line no-underscore-dangle\n this.message = this.message || reason || (this.constructor as any)._defaultErrorMessage(this);\n throw this; // eslint-disable-line\n }\n}\n"],"names":["wrapArray","value","Array","isArray","TYPE_FIELD","setSubjectType","type","object","hasOwnProperty","Object","defineProperty","Error","isSubjectType","getSubjectClassName","modelName","name","getSubjectTypeName","detectSubjectType","subject","constructor","expandActions","aliasMap","rawActions","merge","actions","i","length","action","findDuplicate","actionToFind","indexOf","defaultAliasMerge","concat","validateForCycles","reservedAction","keys","mergeAliasesAndDetectCycles","duplicate","join","isUsingReservedAction","createAliasResolver","options","skipValidate","anyAction","copyArrayTo","dest","target","start","push","mergePrioritized","array","anotherArray","j","merged","priority","getOrDefault","map","key","defaultValue","get","set","identity","x","validate","rule","fields","fieldMatcher","conditions","conditionsMatcher","Rule","resolveAction","inverted","reason","undefined","_options","_conditionsMatcher","this","_matchConditions","matches","ast","matchesConditions","matchesField","field","_matchField","linkedItem","prev","item","next","unlinkItem","cloneLinkedItem","defaultActionEntry","rules","defaultSubjectEntry","Map","analyze","index","_hasPerFieldRules","RuleIndex","_events","_ruleOptions","_anyAction","_anySubjectType","anySubjectType","_detectSubjectType","_rules","_indexedRules","_buildIndexFor","update","event","ability","_emit","rawRules","indexedRules","subjects","k","subjectRules","possibleRulesFor","subjectType","actionRules","anyActionRules","has","rulesFor","filter","on","handler","head","delete","payload","current","PureAbility","can","args","relevantRuleFor","cannot","defaultInstructions","$eq","$ne","$lt","$lte","$gt","$gte","$in","$nin","$all","$size","$regex","$options","$elemMatch","$exists","defaultInterpreters","eq","ne","lt","lte","gt","gte","in","within","nin","all","size","regex","elemMatch","exists","and","buildMongoQueryMatcher","instructions","interpreters","createFactory","mongoQueryMatcher","REGEXP_SPECIAL_CHARS","REGEXP_ANY","REGEXP_STARS","REGEXP_DOT","detectRegexpPattern","match","string","quantifier","matcher","pattern","replace","escapeRegexp","createPattern","patterns","RegExp","fieldPatternMatcher","every","f","test","Ability","RuleBuilder","_rule","because","AbilityBuilder","AbilityType","_AbilityType","bind","build","conditionsOrFields","builder","defineAbility","define","result","then","getDefaultErrorMessage","error","NativeError","NError","message","prototype","create","ForbiddenError","messageOrFn","_defaultErrorMessage","captureStackTrace","setMessage","throwUnlessCan"],"mappings":"uGAEO,SAASA,EAAaC,UACpBC,MAAMC,QAAQF,GAASA,EAAQ,CAACA,GAoBzC,MAAMG,EAAa,sBACZ,SAASC,EAGdC,EAASC,MACLA,MACGA,EAAOC,eAAeJ,GACzBK,OAAOC,eAAeH,EAAQH,EAAY,CAAEH,MAAOK,SAC9C,GAAIA,IAASC,EAAOH,SACnB,IAAIO,MAAO,yCAAwCL,qCAAwCC,EAAOH,aAIrGG,EAGF,MAAMK,EAAiBX,UACtBK,SAAcL,QACJ,WAATK,GAA8B,aAATA,GAG9B,MAAMO,EAAuBZ,GAAwBA,EAAMa,WAAab,EAAMc,KACvE,MAAMC,EAAsBf,GACT,kBAAVA,EAAqBA,EAAQY,EAAoBZ,GAG1D,SAASgB,EAAkBC,MAC5BA,EAAQV,eAAeJ,UACjBc,EAAgBd,UAGnBS,EAAoBK,EAAQC,aAIrC,SAASC,EAAcC,EAAsBC,EAA+BC,OACtEC,EAAUxB,EAAUsB,OACpBG,EAAI,QAEDA,EAAID,EAAQE,OAAQ,OACnBC,EAASH,EAAQC,QAEnBJ,EAASb,eAAemB,GAC1BH,EAAUD,EAAMC,EAASH,EAASM,WAI/BH,EAGT,SAASI,EAAcJ,EAAmBK,MACZ,kBAAjBA,IAAgE,IAAnCL,EAAQM,QAAQD,UAC/CA,MAGJ,IAAIJ,EAAI,EAAGA,EAAII,EAAaH,OAAQD,QACG,IAAtCD,EAAQM,QAAQD,EAAaJ,IAAY,OAAOI,EAAaJ,UAG5D,KAGT,MAAMM,EAAgC,CAACP,EAASG,IAAWH,EAAQQ,OAAOL,GAC1E,SAASM,EAAkBZ,EAAsBa,MAC3CA,KAAkBb,QACd,IAAIV,MAAO,eAAcuB,sDAG3BC,EAAO1B,OAAO0B,KAAKd,SACnBe,EAA0C,CAACZ,EAASG,WAClDU,EAAYT,EAAcJ,EAASG,MACrCU,EAAW,MAAM,IAAI1B,MAAO,kBAAiB0B,QAAgBb,EAAQc,KAAK,eAExEC,EAA0C,kBAAXZ,GAAuBA,IAAWO,IAC7B,IAArCV,EAAQM,QAAQI,IAChBhC,MAAMC,QAAQwB,KAA+C,IAApCA,EAAOG,QAAQI,MACzCK,EAAuB,MAAM,IAAI5B,MAAO,4BAA2BuB,6CAEhEV,EAAQQ,OAAOL,QAGnB,IAAIF,EAAI,EAAGA,EAAIU,EAAKT,OAAQD,IAC/BL,EAAcC,EAAUc,EAAKV,GAAIW,GAK9B,SAASI,EAAoBnB,EAAsBoB,OACnDA,GAAoC,QAAzBA,EAAQC,aACtBT,EAAkBZ,EAAUoB,GAAWA,EAAQE,WAAa,iBAGtDhB,GAA8BP,EAAcC,EAAUM,EAAQI,GAGxE,SAASa,EAAeC,EAAWC,EAAaC,OACzC,IAAItB,EAAIsB,EAAOtB,EAAIqB,EAAOpB,OAAQD,IACrCoB,EAAKG,KAAKF,EAAOrB,IAId,SAASwB,EACdC,EACAC,OAEKD,IAAUA,EAAMxB,cACZyB,GAAgB,OAGpBA,IAAiBA,EAAazB,cAC1BwB,GAAS,OAGdzB,EAAI,MACJ2B,EAAI,QACFC,EAAc,SAEb5B,EAAIyB,EAAMxB,QAAU0B,EAAID,EAAazB,UACtCwB,EAAMzB,GAAG6B,SAAWH,EAAaC,GAAGE,SAAU,CAChDD,EAAOL,KAAKE,EAAMzB,IAClBA,QACK,CACL4B,EAAOL,KAAKG,EAAaC,IACzBA,IAIJR,EAAYS,EAAQH,EAAOzB,GAC3BmB,EAAYS,EAAQF,EAAcC,UAE3BC,EAGF,SAASE,EAAmBC,EAAgBC,EAAQC,OACrDzD,EAAQuD,EAAIG,IAAIF,OAEfxD,EAAO,CACVA,EAAQyD,IACRF,EAAII,IAAIH,EAAKxD,UAGRA,EAGF,MAAM4D,EAAeC,GAASA,ECzJrC,SAASC,EAASC,EAAmCvB,MAC/CvC,MAAMC,QAAQ6D,EAAKC,UAAYD,EAAKC,OAAOvC,aACvC,IAAIf,MAAM,wEAGdqD,EAAKC,SAAWxB,EAAQyB,mBACpB,IAAIvD,MAAM,mFAGdqD,EAAKG,aAAe1B,EAAQ2B,wBACxB,IAAIzD,MAAM,yFAUb,MAAM0D,EAYXlD,YACE6C,EACAvB,EACAa,EAAmB,GAEnBS,EAASC,EAAMvB,QAEVd,OAASc,EAAQ6B,cAAcN,EAAKrC,aACpCT,QAAU8C,EAAK9C,aACfqD,WAAaP,EAAKO,cAClBJ,WAAaH,EAAKG,gBAClBK,OAASR,EAAKQ,YACdP,OAASD,EAAKC,OAASjE,EAAUgE,EAAKC,aAAUQ,OAChDnB,SAAWA,OACXoB,EAAWjC,EAGVkC,OACFC,KAAKT,aAAeS,KAAKC,OACtBA,EAAmBD,KAAKF,EAASN,kBAAmBQ,KAAKT,mBAGzDS,KAAKC,kBAINC,EAAUF,KAAKD,WACdG,EAAUA,EAAQC,SAAMN,EAGjCO,kBAAkBzE,OACXqE,KAAKT,kBACD,SAGJ5D,GAAUK,EAAcL,UACnBqE,KAAKL,eAGTO,EAAUF,KAAKD,WACdG,EAAQvE,GAGjB0E,aAAaC,OACNN,KAAKX,cACD,SAGJiB,SACKN,KAAKL,YAGXK,KAAKX,SAAWW,KAAKO,OAClBA,EAAcP,KAAKF,EAASR,aAAcU,KAAKX,eAG/CW,KAAKO,EAAaD,IChGtB,SAASE,EAAcnF,EAAUoF,SAChCC,EAAO,CAAErF,MAAAA,EAAOoF,KAAAA,EAAME,KAAM,SAE9BF,EACFA,EAAKE,KAAOD,SAGPA,EAGF,SAASE,EAAWF,MACrBA,EAAKC,KACPD,EAAKC,KAAKF,KAAOC,EAAKD,QAGpBC,EAAKD,KACPC,EAAKD,KAAKE,KAAOD,EAAKC,KAGxBD,EAAKC,KAAOD,EAAKD,KAAO,KAGnB,MAAMI,EAA8CH,KACzDrF,MAAOqF,EAAKrF,MACZoF,KAAMC,EAAKD,KACXE,KAAMD,EAAKC,OC0Cb,MAAMG,EAAqB,MACzBC,MAAO,GACPtC,OAAQ,QAEV,MAAMuC,EAAsB,IAAM,IAAIC,IACtC,MAAMC,EAAU,CAACC,EAAY/B,SACtB+B,EAAMC,GAAqBhC,EAAKC,OACnC8B,EAAMC,EAAoB,MAevB,MAAMC,EAYX9E,YACEwE,EAAsC,GACtClD,EAA2C,SAbrCuD,EAA6B,WAC7BE,EAAwB,IAAIL,SAc7BM,EAAe,CAClB/B,kBAAmB3B,EAAQ2B,kBAC3BF,aAAczB,EAAQyB,aACtBI,cAAe7B,EAAQ6B,eAAiBT,QAErCuC,EAAa3D,EAAQE,WAAa,cAClC0D,EAAkB5D,EAAQ6D,gBAAkB,WAC5CC,EAAqB9D,EAAQxB,mBAAqBA,OAClDuF,EAASb,OACTc,EAAgB7B,KAAK8B,EAAef,sBAIlCf,KAAK4B,EAGdvF,kBAAkBV,MACZK,EAAcL,GAAS,OAAOA,MAC7BA,EAAQ,OAAOqE,KAAKyB,SAClBzB,KAAK2B,EAAmBhG,GAGjCoG,OAAOhB,SACCiB,EAAQ,CACZjB,MAAAA,EACAkB,QAASjC,KACT9B,OAAQ8B,WAGLkC,EAAM,SAAUF,QAChBJ,EAASb,OACTc,EAAgB7B,KAAK8B,EAAef,QACpCmB,EAAM,UAAWF,UAEfhC,KAGD8B,EAAeK,SACfC,EAAyC,IAAInB,QAE9C,IAAIpE,EAAIsF,EAASrF,OAAS,EAAGD,GAAK,EAAGA,IAAK,OACvC6B,EAAWyD,EAASrF,OAASD,EAAI,QACjCuC,EAAO,IAAIK,EAAK0C,EAAStF,GAAImD,KAAKuB,EAAc7C,SAChD9B,EAAUxB,EAAUgE,EAAKrC,cACzBsF,EAAWjH,EAAUgE,EAAK9C,SAAW0D,KAAKyB,GAChDP,EAAQlB,KAAMZ,OAET,IAAIkD,EAAI,EAAGA,EAAID,EAASvF,OAAQwF,IAAK,OAClCC,EAAe5D,EAAayD,EAAcC,EAASC,GAAItB,OAExD,IAAIxC,EAAI,EAAGA,EAAI5B,EAAQE,OAAQ0B,IAClCG,EAAa4D,EAAc3F,EAAQ4B,GAAIsC,GAAoBC,MAAM3C,KAAKgB,WAKrEgD,EAITI,iBACEzF,EACA0F,EAA2BzC,KAAKyB,OAE3BzF,EAAcyG,SACX,IAAI1G,MAAM,oGAGZwG,EAAe5D,EAAaqB,KAAK6B,EAAeY,EAAazB,SAC7D0B,EAAc/D,EAAa4D,EAAcxF,EAAQ+D,MAEnD4B,EAAYjE,cACPiE,EAAY3B,YAGf4B,EAAiB5F,IAAWiD,KAAKwB,GAAce,EAAaK,IAAI5C,KAAKwB,GACvEe,EAAaxD,IAAIiB,KAAKwB,GAAaT,WACnClB,MACAkB,EAAQ1C,EAAiBqE,EAAY3B,MAAO4B,MAE5CF,IAAgBzC,KAAKyB,EACvBV,EAAQ1C,EAAiB0C,EAAQf,KAAawC,iBAAiBzF,EAAQiD,KAAKyB,IAG9EiB,EAAY3B,MAAQA,EACpB2B,EAAYjE,OAAS,YAEdsC,EAIT8B,SAAS9F,EAAgB0F,EAA2BnC,SAC5CS,EAAgCf,KAAawC,iBAAiBzF,EAAQ0F,MAExEnC,GAA0B,kBAAVA,QACZ,IAAIvE,MAAM,qJAGbiE,KAAKoB,SACDL,SAGFA,EAAM+B,QAAO1D,GAAQA,EAAKiB,aAAaC,KAGhDyC,GACEf,EACAgB,SAEMC,EAAOjD,KAAKsB,EAAQvC,IAAIiD,IAAU,WAClCtB,EAAOF,EAAWwC,EAASC,QAC5B3B,EAAQtC,IAAIgD,EAAOtB,SAEjB,SACAA,EAAKC,OAASD,EAAKD,MAAQT,KAAKsB,EAAQvC,IAAIiD,KAAWtB,OACrDY,EAAQ4B,OAAOlB,QAEpBpB,EAAWF,IAKTwB,EACN/F,EACAgH,OAEIC,EAAUpD,KAAKsB,EAAQvC,IAAI5C,IAAS,WACrB,OAAZiH,EAAkB,OACjB3C,EAAO2C,EAAQ3C,KAAOI,EAAgBuC,EAAQ3C,MAAQ,KAC5D2C,EAAQ/H,MAAM8H,GACdC,EAAU3C,ICpOT,MAAM4C,oBAGHhC,EACRiC,OAAOC,SACCnE,EAAOY,KAAKwD,mBAAmBD,WAC5BnE,IAASA,EAAKO,SAIzB6D,gBAAgBzG,EAAgBT,EAAmBgE,SAC3CmC,EAAczC,KAAK3D,kBAAkBC,SACrCyE,EAASf,KAAa6C,SAAS9F,EAAQ0F,EAAanC,OAErD,IAAIzD,EAAI,EAAGC,EAASiE,EAAMjE,OAAQD,EAAIC,EAAQD,OAC7CkE,EAAMlE,GAAGuD,kBAAkB9D,UACtByE,EAAMlE,UAIV,KAGT4G,UAAUF,UACAvD,KAAKsD,OAAOC,ICDxB,MAAMG,EAAsB,KAC1BC,UACAC,UACAC,WACAC,WACAC,WACAC,WACAC,WACAC,YACAC,aACAC,eACAC,kBACAC,sBACAC,qBACAC,WAEF,MAAMC,EAAsB,IAC1BC,QACAC,QACAC,SACAC,SACAC,SACAC,MACAC,GAAIC,aACJC,UACAC,WACAC,aACAC,kBACAC,mBACAC,aACAC,aAeWC,EAA0B,CAACC,EAAcC,EAAc9H,IAAY+H,iCACzElC,EAAwBgC,oBACxBjB,EAAwBkB,GAC7B9H,SAGWgI,EAAoBD,gBAAclC,EAAqBe,GCrFpE,MAAMqB,EAAuB,uBAC7B,MAAMC,EAAa,aACnB,MAAMC,EAAe,MACrB,MAAMC,EAAa,MAEnB,SAASC,EAAoBC,EAAehF,EAAeiF,SACnDC,EAA2B,MAAdD,EAAO,IAA2B,MAAbD,EAAM,IAA0C,MAA5BA,EAAMA,EAAMrJ,OAAS,GAC7E,IACA,UACEwJ,GAAmC,IAAzBH,EAAMjJ,QAAQ,MAAe,OAAS,UAChDqJ,EAAUJ,EAAMK,QAAQP,EAAY,QACvCO,QAAQR,EAAcM,EAAUD,UAE5BlF,EAAQgF,EAAMrJ,SAAWsJ,EAAOtJ,OAAU,MAAKyJ,MAAcA,EAGtE,SAASE,EAAaN,EAAehF,EAAeiF,MACpC,MAAVD,IAAwC,MAAtBC,EAAOjF,EAAQ,IAAoC,MAAtBiF,EAAOjF,EAAQ,WACzDgF,QAGD,KAAIA,IAGd,SAASO,EAAcrH,SACfsH,EAAWtH,EAAOT,KAAI0B,GAASA,EAClCkG,QAAQV,EAAsBW,GAC9BD,QAAQT,EAAYG,WACjBK,EAAUI,EAAS7J,OAAS,EAAK,MAAK6J,EAASjJ,KAAK,QAAUiJ,EAAS,UAEtE,IAAIC,OAAQ,IAAGL,YAGXM,EAAqCxH,QAC5CkH,SAEIjG,OACiB,qBAAZiG,EACTA,EAAUlH,EAAOyH,OAAMC,IAAyB,IAApBA,EAAE7J,QAAQ,OAClC,KACAwJ,EAAcrH,UAGD,OAAZkH,GACwB,IAA3BlH,EAAOnC,QAAQoD,GACfiG,EAAQS,KAAK1G,KCxCd,MAAM2G,gBAGH5D,YACR9G,YAAYwE,EAA6B,GAAIlD,EAAgC,UACrEkD,iBACJvB,kBAAmBqG,EACnBvG,aAAcuH,GACXhJ,KCDT,MAAMqJ,EAGJ3K,YAAY6C,QACL+H,EAAQ/H,EAGfgI,QAAQxH,QACDuH,EAAMvH,OAASA,SACbI,MAiDJ,MAAMqH,eAIX9K,YAAY+K,QAHLvG,MAAwB,QAIxBwG,EAAeD,OACfhE,IAAMtD,KAAKsD,IAAIkE,KAAKxH,WACpByD,OAASzD,KAAKyD,OAAO+D,KAAKxH,WAC1ByH,MAAQzH,KAAKyH,MAAMD,KAAKxH,MAY/BsD,IACEvG,EACAT,EACAoL,EACAnI,SAEMH,EAAO,CAAErC,OAAAA,MAEXT,EAAS,CACX8C,EAAK9C,QAAUA,KAEXhB,MAAMC,QAAQmM,IAAqD,kBAAvBA,EAC9CtI,EAAKC,OAASqI,OACT,GAAkC,qBAAvBA,EAChBtI,EAAKG,WAAamI,KAGM,qBAAfnI,EACTH,EAAKG,WAAaA,OAIjBwB,MAAM3C,KAAKgB,UAET,IAAI8H,EAAY9H,GAYzBqE,OACE1G,EACAT,EACAoL,EACAnI,SAEMoI,EAAW3H,KAAasD,IAAIvG,EAAQT,EAASoL,EAAoBnI,GACvEoI,EAAQR,EAAMxH,SAAW,YAClBgI,EAGTF,MAAM5J,UACG,IAAImC,KAAKuH,EAAavH,KAAKe,MAAOlD,IAetC,SAAS+J,cAEdC,EAAsChK,SAChC8J,EAAU,IAAIN,eAAeJ,eAC7Ba,EAASD,EAAOF,EAAQrE,IAAKqE,EAAQlE,WAEvCqE,GAAiC,oBAAhBA,EAAOC,YACnBD,EAAOC,MAAK,IAAMJ,EAAQF,MAAM5J,YAGlC8J,EAAQF,MAAM5J,SC/JVmK,EAA0CC,GAAU,mBAAkBA,EAAMlL,eAAekL,EAAMxF,eAE9G,MAAMyF,EAAc,SAASC,EAAoBC,QAC1CA,QAAUA,GAGjBF,EAAYG,UAAYxM,OAAOyM,OAAOvM,MAAMsM,WAErC,MAAME,uBAA6CL,2BAS/BM,QAClBC,EAA8C,kBAAhBD,EAA2B,IAAMA,EAAcA,cAGlDvG,UACzB,IAAIjC,KAAQiC,GAGb1F,YAAY0F,SACZ,SACDA,QAAUA,KAEwB,oBAA5BlG,MAAM2M,kBAAkC,MAC5CvM,KAAO,iBACZJ,MAAM2M,kBAAkB1I,KAAMA,KAAKzD,cAIvCoM,WAAWP,QACJA,QAAUA,SACRpI,KAGT4I,kBAAkBrF,SACVnE,EAAOY,KAAKiC,QAAQuB,mBAAmBD,MAEzCnE,IAASA,EAAKO,qBAIb5C,OAASwG,EAAK,QACdjH,QAAUiH,EAAK,QACfd,YAAcrG,EAAmB4D,KAAKiC,QAAQ5F,kBAAkBkH,EAAK,UACrEjD,MAAQiD,EAAK,SAEZ3D,EAASR,EAAOA,EAAKQ,OAAS,QAE/BwI,QAAUpI,KAAKoI,SAAWxI,GAAWI,KAAKzD,YAAoBkM,EAAqBzI,YAClFA,MA/CGuI,eAOJE,EAAuBT"}
{"version":3,"file":"index.js","sources":["../../src/utils.ts","../../src/Rule.ts","../../src/structures/LinkedItem.ts","../../src/RuleIndex.ts","../../src/PureAbility.ts","../../src/matchers/conditions.ts","../../src/matchers/field.ts","../../src/Ability.ts","../../src/AbilityBuilder.ts","../../src/ForbiddenError.ts"],"sourcesContent":["import { AnyObject, Subject, SubjectType, SubjectClass, ForcedSubject, AliasesMap } from './types';\n\nexport function wrapArray<T>(value: T[] | T): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function setByPath(object: AnyObject, path: string, value: unknown): void {\n let ref = object;\n let lastKey = path;\n\n if (path.indexOf('.') !== -1) {\n const keys = path.split('.');\n\n lastKey = keys.pop()!;\n ref = keys.reduce((res, prop) => {\n res[prop] = res[prop] || {};\n return res[prop] as AnyObject;\n }, object);\n }\n\n ref[lastKey] = value;\n}\n\nconst TYPE_FIELD = '__caslSubjectType__';\nexport function setSubjectType<\n T extends string,\n U extends Record<PropertyKey, any>\n>(type: T, object: U): U & ForcedSubject<T> {\n if (object) {\n if (!object.hasOwnProperty(TYPE_FIELD)) {\n Object.defineProperty(object, TYPE_FIELD, { value: type });\n } else if (type !== object[TYPE_FIELD]) {\n throw new Error(`Trying to cast object to subject type ${type} but previously it was casted to ${object[TYPE_FIELD]}`);\n }\n }\n\n return object as U & ForcedSubject<T>;\n}\n\nexport const isSubjectType = (value: unknown): value is SubjectType => {\n const type = typeof value;\n return type === 'string' || type === 'function';\n};\n\nconst getSubjectClassName = (value: SubjectClass) => value.modelName || value.name;\nexport const getSubjectTypeName = (value: SubjectType) => {\n return typeof value === 'string' ? value : getSubjectClassName(value);\n};\n\nexport function detectSubjectType(subject: Exclude<Subject, SubjectType>): string {\n if (subject.hasOwnProperty(TYPE_FIELD)) {\n return (subject as any)[TYPE_FIELD];\n }\n\n return getSubjectClassName(subject.constructor as SubjectClass);\n}\n\ntype AliasMerge = (actions: string[], action: string | string[]) => string[];\nfunction expandActions(aliasMap: AliasesMap, rawActions: string | string[], merge: AliasMerge) {\n let actions = wrapArray(rawActions);\n let i = 0;\n\n while (i < actions.length) {\n const action = actions[i++];\n\n if (aliasMap.hasOwnProperty(action)) {\n actions = merge(actions, aliasMap[action]);\n }\n }\n\n return actions;\n}\n\nfunction findDuplicate(actions: string[], actionToFind: string | string[]) {\n if (typeof actionToFind === 'string' && actions.indexOf(actionToFind) !== -1) {\n return actionToFind;\n }\n\n for (let i = 0; i < actionToFind.length; i++) {\n if (actions.indexOf(actionToFind[i]) !== -1) return actionToFind[i];\n }\n\n return null;\n}\n\nconst defaultAliasMerge: AliasMerge = (actions, action) => actions.concat(action);\nfunction validateForCycles(aliasMap: AliasesMap, reservedAction: string) {\n if (reservedAction in aliasMap) {\n throw new Error(`Cannot use \"${reservedAction}\" as an alias because it's reserved action.`);\n }\n\n const keys = Object.keys(aliasMap);\n const mergeAliasesAndDetectCycles: AliasMerge = (actions, action) => {\n const duplicate = findDuplicate(actions, action);\n if (duplicate) throw new Error(`Detected cycle ${duplicate} -> ${actions.join(', ')}`);\n\n const isUsingReservedAction = typeof action === 'string' && action === reservedAction\n || actions.indexOf(reservedAction) !== -1\n || Array.isArray(action) && action.indexOf(reservedAction) !== -1;\n if (isUsingReservedAction) throw new Error(`Cannot make an alias to \"${reservedAction}\" because this is reserved action`);\n\n return actions.concat(action);\n };\n\n for (let i = 0; i < keys.length; i++) {\n expandActions(aliasMap, keys[i], mergeAliasesAndDetectCycles);\n }\n}\n\nexport type AliasResolverOptions = { skipValidate?: boolean; anyAction?: string };\nexport function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions) {\n if (!options || options.skipValidate !== false) {\n validateForCycles(aliasMap, options && options.anyAction || 'manage');\n }\n\n return (action: string | string[]) => expandActions(aliasMap, action, defaultAliasMerge);\n}\n\nfunction copyArrayTo<T>(dest: T[], target: T[], start: number) {\n for (let i = start; i < target.length; i++) {\n dest.push(target[i]);\n }\n}\n\nexport function mergePrioritized<T extends { priority: number }>(\n array?: T[],\n anotherArray?: T[]\n): T[] {\n if (!array || !array.length) {\n return anotherArray || [];\n }\n\n if (!anotherArray || !anotherArray.length) {\n return array || [];\n }\n\n let i = 0;\n let j = 0;\n const merged: T[] = [];\n\n while (i < array.length && j < anotherArray.length) {\n if (array[i].priority < anotherArray[j].priority) {\n merged.push(array[i]);\n i++;\n } else {\n merged.push(anotherArray[j]);\n j++;\n }\n }\n\n copyArrayTo(merged, array, i);\n copyArrayTo(merged, anotherArray, j);\n\n return merged;\n}\n\nexport function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V) {\n let value = map.get(key);\n\n if (!value) {\n value = defaultValue();\n map.set(key, value);\n }\n\n return value;\n}\n\nexport const identity = <T>(x: T) => x;\n","import { wrapArray, isSubjectType } from './utils';\nimport {\n MatchConditions,\n MatchField,\n Abilities,\n ToAbilityTypes,\n Normalize,\n ConditionsMatcher,\n FieldMatcher,\n} from './types';\nimport { RawRule, RawRuleFrom } from './RawRule';\n\ntype Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;\n\nfunction validate(rule: RawRuleFrom<Abilities, any>, options: RuleOptions<any>) {\n if (Array.isArray(rule.fields) && !rule.fields.length) {\n throw new Error('`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa');\n }\n\n if (rule.fields && !options.fieldMatcher) {\n throw new Error('You need to pass \"fieldMatcher\" option in order to restrict access by fields');\n }\n\n if (rule.conditions && !options.conditionsMatcher) {\n throw new Error('You need to pass \"conditionsMatcher\" option in order to restrict access by conditions');\n }\n}\n\nexport interface RuleOptions<Conditions> {\n conditionsMatcher?: ConditionsMatcher<Conditions>\n fieldMatcher?: FieldMatcher\n resolveAction(action: string | string[]): string | string[]\n}\n\nexport class Rule<A extends Abilities, C> {\n private _matchConditions: MatchConditions | undefined;\n private _matchField: MatchField<string> | undefined;\n private readonly _options!: RuleOptions<C>;\n public readonly action!: Tuple<A>[0] | Tuple<A>[0][];\n public readonly subject!: Tuple<A>[1] | Tuple<A>[1][];\n public readonly inverted!: boolean;\n public readonly conditions!: C | undefined;\n public readonly fields!: string[] | undefined;\n public readonly reason!: string | undefined;\n public readonly priority!: number;\n\n constructor(\n rule: RawRule<ToAbilityTypes<A>, C>,\n options: RuleOptions<C>,\n priority: number = 0\n ) {\n validate(rule, options);\n\n this.action = options.resolveAction(rule.action);\n this.subject = rule.subject!;\n this.inverted = !!rule.inverted;\n this.conditions = rule.conditions;\n this.reason = rule.reason;\n this.fields = rule.fields ? wrapArray(rule.fields) : undefined;\n this.priority = priority;\n this._options = options;\n }\n\n private _conditionsMatcher() {\n if (this.conditions && !this._matchConditions) {\n this._matchConditions = this._options.conditionsMatcher!(this.conditions);\n }\n\n return this._matchConditions!;\n }\n\n get ast() {\n const matches = this._conditionsMatcher();\n return matches ? matches.ast : undefined;\n }\n\n matchesConditions(object: Normalize<A>[1] | undefined): boolean {\n if (!this.conditions) {\n return true;\n }\n\n if (!object || isSubjectType(object)) {\n return !this.inverted;\n }\n\n const matches = this._conditionsMatcher();\n return matches(object as Record<string, unknown>);\n }\n\n matchesField(field: string | undefined): boolean {\n if (!this.fields) {\n return true;\n }\n\n if (!field) {\n return !this.inverted;\n }\n\n if (this.fields && !this._matchField) {\n this._matchField = this._options.fieldMatcher!(this.fields);\n }\n\n return this._matchField!(field);\n }\n}\n","export interface LinkedItem<T> {\n next: LinkedItem<T> | null\n prev: LinkedItem<T> | null\n readonly value: T\n}\n\nexport function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']) {\n const item = { value, prev, next: null };\n\n if (prev) {\n prev.next = item;\n }\n\n return item;\n}\n\nexport function unlinkItem(item: LinkedItem<any>) {\n if (item.next) {\n item.next.prev = item.prev;\n }\n\n if (item.prev) {\n item.prev.next = item.next;\n }\n\n item.next = item.prev = null; // eslint-disable-line\n}\n\nexport const cloneLinkedItem = <T extends LinkedItem<any>>(item: T): T => ({\n value: item.value,\n prev: item.prev,\n next: item.next,\n} as T);\n","import { Rule, RuleOptions } from './Rule';\nimport { RawRuleFrom } from './RawRule';\nimport {\n Abilities,\n Normalize,\n SubjectType,\n AbilityParameters,\n AbilityTuple,\n ExtractSubjectType\n} from './types';\nimport { wrapArray, detectSubjectType, mergePrioritized, getOrDefault, identity, isSubjectType } from './utils';\nimport { LinkedItem, linkedItem, unlinkItem, cloneLinkedItem } from './structures/LinkedItem';\n\nexport interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {\n detectSubjectType?(\n subject: Exclude<Normalize<A>[1], SubjectType>\n ): ExtractSubjectType<Normalize<A>[1]>;\n anyAction?: string;\n anySubjectType?: string;\n}\n\ndeclare const $abilities: unique symbol;\ndeclare const $conditions: unique symbol;\ninterface WithGenerics {\n [$abilities]: any\n [$conditions]: any\n}\nexport type Public<T extends WithGenerics> = { [K in keyof T]: T[K] };\nexport interface Generics<T extends WithGenerics> {\n abilities: T[typeof $abilities],\n conditions: T[typeof $conditions]\n}\n\nexport type RuleOf<T extends WithGenerics> =\n Rule<Generics<T>['abilities'], Generics<T>['conditions']>;\nexport type RawRuleOf<T extends WithGenerics> =\n RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;\n\nexport type RuleIndexOptionsOf<T extends WithGenerics> =\n RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;\n\ninterface AbilityEvent<T extends WithGenerics> {\n target: T\n /** @deprecated use \"target\" property instead */\n ability: T\n}\n\nexport interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {\n rules: RawRuleOf<T>[]\n}\n/**\n * @deprecated `on`/`emit` properly infer type without this type\n * TODO(major): delete\n */\nexport type EventHandler<Event> = (event: Event) => void;\n\nexport type Events<\n T extends WithGenerics,\n K extends keyof EventsMap<T> = keyof EventsMap<T>\n> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;\n\ninterface EventsMap<T extends WithGenerics> {\n update(event: UpdateEvent<T>): void\n updated(event: UpdateEvent<T>): void\n}\n\ntype IndexTree<A extends Abilities, C> = Map<SubjectType, Map<string, {\n rules: Rule<A, C>[],\n merged: boolean\n}>>;\n\nexport type Unsubscribe = () => void;\n\nconst defaultActionEntry = () => ({\n rules: [] as unknown as Rule<any, any>[],\n merged: false\n});\nconst defaultSubjectEntry = () => new Map<string, ReturnType<typeof defaultActionEntry>>();\nconst analyze = (index: any, rule: Rule<any, any>) => {\n if (!index._hasPerFieldRules && rule.fields) {\n index._hasPerFieldRules = true;\n }\n};\n\ntype AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> =\n AbilityParameters<\n T,\n T extends AbilityTuple\n ? IncludeField extends true\n ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0\n : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0\n : never,\n (action: Extract<T, string>) => 0\n >;\n\nexport class RuleIndex<A extends Abilities, Conditions> {\n private _hasPerFieldRules: boolean = false;\n private _events: Events<this> = new Map();\n private _indexedRules!: IndexTree<A, Conditions>;\n private _rules!: RawRuleFrom<A, Conditions>[];\n private readonly _ruleOptions!: RuleOptions<Conditions>;\n private readonly _detectSubjectType!: Required<RuleIndexOptions<A, Conditions>>['detectSubjectType'];\n private readonly _anyAction: string;\n private readonly _anySubjectType: string;\n readonly [$abilities]!: A;\n readonly [$conditions]!: Conditions;\n\n constructor(\n rules: RawRuleFrom<A, Conditions>[] = [],\n options: RuleIndexOptions<A, Conditions> = {}\n ) {\n this._ruleOptions = {\n conditionsMatcher: options.conditionsMatcher,\n fieldMatcher: options.fieldMatcher,\n resolveAction: options.resolveAction || identity,\n };\n this._anyAction = options.anyAction || 'manage';\n this._anySubjectType = options.anySubjectType || 'all';\n this._detectSubjectType = options.detectSubjectType || detectSubjectType;\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n }\n\n get rules() {\n return this._rules;\n }\n\n detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]> {\n if (isSubjectType(object)) return object;\n if (!object) return this._anySubjectType;\n return this._detectSubjectType(object as Exclude<Normalize<A>[1], SubjectType>);\n }\n\n update(rules: RawRuleFrom<A, Conditions>[]): Public<this> {\n const event = {\n rules,\n ability: this,\n target: this\n } as unknown as UpdateEvent<this>;\n\n this._emit('update', event);\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n this._emit('updated', event);\n\n return this;\n }\n\n private _buildIndexFor(rawRules: RawRuleFrom<A, Conditions>[]) {\n const indexedRules: IndexTree<A, Conditions> = new Map();\n\n for (let i = rawRules.length - 1; i >= 0; i--) {\n const priority = rawRules.length - i - 1;\n const rule = new Rule(rawRules[i], this._ruleOptions, priority);\n const actions = wrapArray(rule.action);\n const subjects = wrapArray(rule.subject || this._anySubjectType);\n analyze(this, rule);\n\n for (let k = 0; k < subjects.length; k++) {\n const subjectRules = getOrDefault(indexedRules, subjects[k], defaultSubjectEntry);\n\n for (let j = 0; j < actions.length; j++) {\n getOrDefault(subjectRules, actions[j], defaultActionEntry).rules.push(rule);\n }\n }\n }\n\n return indexedRules;\n }\n\n possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[]\n possibleRulesFor(\n action: string,\n subjectType: SubjectType = this._anySubjectType\n ): Rule<A, Conditions>[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"possibleRulesFor\" accepts only subject types (i.e., string or class) as the 2nd parameter');\n }\n\n const subjectRules = getOrDefault(this._indexedRules, subjectType, defaultSubjectEntry);\n const actionRules = getOrDefault(subjectRules, action, defaultActionEntry);\n\n if (actionRules.merged) {\n return actionRules.rules;\n }\n\n const anyActionRules = action !== this._anyAction && subjectRules.has(this._anyAction)\n ? subjectRules.get(this._anyAction)!.rules\n : undefined;\n let rules = mergePrioritized(actionRules.rules, anyActionRules);\n\n if (subjectType !== this._anySubjectType) {\n rules = mergePrioritized(rules, (this as any).possibleRulesFor(action, this._anySubjectType));\n }\n\n actionRules.rules = rules;\n actionRules.merged = true;\n\n return rules;\n }\n\n rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[]\n rulesFor(action: string, subjectType?: SubjectType, field?: string): Rule<A, Conditions>[] {\n const rules: Rule<A, Conditions>[] = (this as any).possibleRulesFor(action, subjectType);\n\n if (field && typeof field !== 'string') {\n throw new Error('The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details');\n }\n\n if (!this._hasPerFieldRules) {\n return rules;\n }\n\n return rules.filter(rule => rule.matchesField(field));\n }\n\n on<T extends keyof EventsMap<this>>(\n event: T,\n handler: EventsMap<Public<this>>[T]\n ): Unsubscribe {\n const tail = this._events.get(event) || null;\n const item = linkedItem(handler, tail);\n this._events.set(event, item);\n\n return () => {\n const currentTail = this._events.get(event);\n\n if (!item.next && !item.prev && currentTail === item) {\n this._events.delete(event);\n } else if (item === currentTail) {\n this._events.set(event, item.prev);\n }\n\n unlinkItem(item);\n };\n }\n\n private _emit<T extends keyof EventsMap<this>>(\n name: T,\n payload: Parameters<EventsMap<this>[T]>[0]\n ) {\n let current = this._events.get(name) || null;\n while (current !== null) {\n const prev = current.prev ? cloneLinkedItem(current.prev) : null;\n current.value(payload);\n current = prev;\n }\n }\n}\n","import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';\nimport { Abilities, AbilityTuple, CanParameters, Subject } from './types';\nimport { Rule } from './Rule';\n\nexport interface AbilityOptions<A extends Abilities, Conditions>\n extends RuleIndexOptions<A, Conditions> {}\nexport interface AnyAbility extends Public<PureAbility<any, any>> {}\nexport interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {}\nexport type AbilityClass<T extends AnyAbility> = new (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport class PureAbility<\n A extends Abilities = AbilityTuple,\n Conditions = unknown\n> extends RuleIndex<A, Conditions> {\n can(...args: CanParameters<A>): boolean {\n const rule = this.relevantRuleFor(...args);\n return !!rule && !rule.inverted;\n }\n\n relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null {\n const subjectType = this.detectSubjectType(subject);\n const rules = (this as any).rulesFor(action, subjectType, field);\n\n for (let i = 0, length = rules.length; i < length; i++) {\n if (rules[i].matchesConditions(subject)) {\n return rules[i];\n }\n }\n\n return null;\n }\n\n cannot(...args: CanParameters<A>): boolean {\n return !this.can(...args);\n }\n}\n","import {\n $eq,\n eq,\n $ne,\n ne,\n $lt,\n lt,\n $lte,\n lte,\n $gt,\n gt,\n $gte,\n gte,\n $in,\n within,\n $nin,\n nin,\n $all,\n all,\n $size,\n size,\n $regex,\n $options,\n regex,\n $elemMatch,\n elemMatch,\n $exists,\n exists,\n and,\n createFactory,\n BuildMongoQuery,\n DefaultOperators,\n} from '@ucast/mongo2js';\nimport { ConditionsMatcher, AnyObject } from '../types';\nimport { Container, GenericFactory } from '../hkt';\n\nconst defaultInstructions = {\n $eq,\n $ne,\n $lt,\n $lte,\n $gt,\n $gte,\n $in,\n $nin,\n $all,\n $size,\n $regex,\n $options,\n $elemMatch,\n $exists,\n};\nconst defaultInterpreters = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n in: within,\n nin,\n all,\n size,\n regex,\n elemMatch,\n exists,\n and,\n};\n\ninterface MongoQueryFactory extends GenericFactory {\n produce: MongoQuery<this[0]>\n}\n\ntype MergeUnion<T extends {}, Keys extends keyof T = keyof T> = { [K in Keys]: T[K] };\nexport type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {\n toplevel: {},\n field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>\n}> & Container<MongoQueryFactory>;\n\ntype MongoQueryMatcherFactory =\n (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;\nexport const buildMongoQueryMatcher = ((instructions, interpreters, options) => createFactory(\n { ...defaultInstructions, ...instructions },\n { ...defaultInterpreters, ...interpreters },\n options\n)) as MongoQueryMatcherFactory;\n\nexport const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);\nexport type {\n MongoQueryFieldOperators,\n MongoQueryTopLevelOperators,\n MongoQueryOperators,\n} from '@ucast/mongo2js';\n","import { FieldMatcher } from '../types';\n\nconst REGEXP_SPECIAL_CHARS = /[-/\\\\^$+?.()|[\\]{}]/g;\nconst REGEXP_ANY = /\\.?\\*+\\.?/g;\nconst REGEXP_STARS = /\\*+/;\nconst REGEXP_DOT = /\\./g;\n\nfunction detectRegexpPattern(match: string, index: number, string: string): string {\n const quantifier = string[0] === '*' || match[0] === '.' && match[match.length - 1] === '.'\n ? '+'\n : '*';\n const matcher = match.indexOf('**') === -1 ? '[^.]' : '.';\n const pattern = match.replace(REGEXP_DOT, '\\\\$&')\n .replace(REGEXP_STARS, matcher + quantifier);\n\n return index + match.length === string.length ? `(?:${pattern})?` : pattern;\n}\n\nfunction escapeRegexp(match: string, index: number, string: string): string {\n if (match === '.' && (string[index - 1] === '*' || string[index + 1] === '*')) {\n return match;\n }\n\n return `\\\\${match}`;\n}\n\nfunction createPattern(fields: string[]) {\n const patterns = fields.map(field => field\n .replace(REGEXP_SPECIAL_CHARS, escapeRegexp)\n .replace(REGEXP_ANY, detectRegexpPattern));\n const pattern = patterns.length > 1 ? `(?:${patterns.join('|')})` : patterns[0];\n\n return new RegExp(`^${pattern}$`);\n}\n\nexport const fieldPatternMatcher: FieldMatcher = (fields) => {\n let pattern: RegExp | null;\n\n return (field) => {\n if (typeof pattern === 'undefined') {\n pattern = fields.every(f => f.indexOf('*') === -1)\n ? null\n : createPattern(fields);\n }\n\n return pattern === null\n ? fields.indexOf(field) !== -1\n : pattern.test(field);\n };\n};\n","import { PureAbility, AbilityOptions } from './PureAbility';\nimport { RawRuleFrom } from './RawRule';\nimport { AbilityTuple } from './types';\nimport { MongoQuery, mongoQueryMatcher } from './matchers/conditions';\nimport { fieldPatternMatcher } from './matchers/field';\nimport { Public } from './RuleIndex';\n\nexport class Ability<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {\n constructor(rules: RawRuleFrom<A, C>[] = [], options: AbilityOptions<A, C> = {}) {\n super(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n }\n}\n\nexport interface AnyMongoAbility extends Public<Ability<any, MongoQuery>> {}\n","import { Ability, AnyMongoAbility } from './Ability';\nimport { AnyAbility, AbilityOptionsOf, AbilityClass } from './PureAbility';\nimport { RawRuleOf, Generics } from './RuleIndex';\nimport {\n ExtractSubjectType as E,\n AbilityTuple,\n SubjectType,\n TaggedInterface,\n Normalize,\n AnyObject,\n AnyClass,\n} from './types';\nimport { ProduceGeneric } from './hkt';\n\nclass RuleBuilder<T extends AnyAbility> {\n public _rule!: RawRuleOf<T>;\n\n constructor(rule: RawRuleOf<T>) {\n this._rule = rule;\n }\n\n because(reason: string): this {\n this._rule.reason = reason;\n return this;\n }\n}\n\ntype InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R>\n ? R\n : S extends string\n ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string>\n ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>>\n : AnyObject\n : never;\ntype ConditionsOf<T extends AnyAbility, I extends {}> =\n ProduceGeneric<Generics<T>['conditions'], I>;\ntype ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any\n ? S extends T[1] ? T[0] : never\n : never;\ntype ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;\ntype SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;\n\ntype SimpleCanParams<T extends AnyAbility> = Parameters<(\n action: Generics<T>['abilities'] | Generics<T>['abilities'][]\n) => 0>;\ntype BuilderCanParameters<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\n\ntype BuilderCanParametersWithFields<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n F extends string,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n fields?: F | F[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\ntype Keys<T> = string & keyof T;\n\nexport class AbilityBuilder<T extends AnyAbility> {\n public rules: RawRuleOf<T>[] = [];\n private _AbilityType!: AnyClass<T>;\n\n constructor(AbilityType: AnyClass<T>) {\n this._AbilityType = AbilityType;\n this.can = this.can.bind(this as any);\n this.cannot = this.cannot.bind(this as any);\n this.build = this.build.bind(this as any);\n }\n\n can<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n can<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n can(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ): RuleBuilder<T> {\n const rule = { action } as RawRuleOf<T>;\n\n if (subject) {\n rule.subject = subject;\n\n if (Array.isArray(conditionsOrFields) || typeof conditionsOrFields === 'string') {\n rule.fields = conditionsOrFields;\n } else if (typeof conditionsOrFields !== 'undefined') {\n rule.conditions = conditionsOrFields;\n }\n\n if (typeof conditions !== 'undefined') {\n rule.conditions = conditions;\n }\n }\n\n this.rules.push(rule);\n\n return new RuleBuilder(rule);\n }\n\n cannot<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n cannot<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n cannot(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions'],\n ): RuleBuilder<T> {\n const builder = (this as any).can(action, subject, conditionsOrFields, conditions);\n builder._rule.inverted = true;\n return builder;\n }\n\n build(options?: AbilityOptionsOf<T>) {\n return new this._AbilityType(this.rules, options);\n }\n}\n\ntype DSL<T extends AnyAbility, R> = (\n can: AbilityBuilder<T>['can'],\n cannot: AbilityBuilder<T>['cannot']\n) => R;\n\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void | Promise<void>>, options?: AbilityOptionsOf<T>): T | Promise<T> {\n const builder = new AbilityBuilder(Ability as unknown as AbilityClass<T>);\n const result = define(builder.can, builder.cannot);\n\n if (result && typeof result.then === 'function') {\n return result.then(() => builder.build(options));\n }\n\n return builder.build(options);\n}\n","import { AnyAbility } from './PureAbility';\nimport { Normalize } from './types';\nimport { Generics } from './RuleIndex';\nimport { getSubjectTypeName } from './utils';\n\nexport type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;\nexport const getDefaultErrorMessage: GetErrorMessage = error => `Cannot execute \"${error.action}\" on \"${error.subjectType}\"`;\n\nconst NativeError = function NError(this: Error, message: string) {\n this.message = message;\n} as unknown as new (message: string) => Error;\n\nNativeError.prototype = Object.create(Error.prototype);\n\nexport class ForbiddenError<T extends AnyAbility> extends NativeError {\n public readonly ability!: T;\n public action!: Normalize<Generics<T>['abilities']>[0];\n public subject!: Generics<T>['abilities'][1];\n public field?: string;\n public subjectType!: string;\n\n static _defaultErrorMessage = getDefaultErrorMessage;\n\n static setDefaultMessage(messageOrFn: string | GetErrorMessage) {\n this._defaultErrorMessage = typeof messageOrFn === 'string' ? () => messageOrFn : messageOrFn;\n }\n\n static from<U extends AnyAbility>(ability: U) {\n return new this<U>(ability);\n }\n\n private constructor(ability: T) {\n super('');\n this.ability = ability;\n\n if (typeof Error.captureStackTrace === 'function') {\n this.name = 'ForbiddenError';\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n setMessage(message: string) {\n this.message = message;\n return this;\n }\n\n throwUnlessCan(...args: Parameters<T['can']>) {\n const rule = this.ability.relevantRuleFor(...args);\n\n if (rule && !rule.inverted) {\n return;\n }\n\n this.action = args[0];\n this.subject = args[1];\n this.subjectType = getSubjectTypeName(this.ability.detectSubjectType(args[1]));\n this.field = args[2];\n\n const reason = rule ? rule.reason : '';\n // eslint-disable-next-line no-underscore-dangle\n this.message = this.message || reason || (this.constructor as any)._defaultErrorMessage(this);\n throw this; // eslint-disable-line\n }\n}\n"],"names":["wrapArray","value","Array","isArray","TYPE_FIELD","setSubjectType","type","object","hasOwnProperty","Object","defineProperty","Error","isSubjectType","getSubjectClassName","modelName","name","getSubjectTypeName","detectSubjectType","subject","constructor","expandActions","aliasMap","rawActions","merge","actions","i","length","action","findDuplicate","actionToFind","indexOf","defaultAliasMerge","concat","validateForCycles","reservedAction","keys","mergeAliasesAndDetectCycles","duplicate","join","isUsingReservedAction","createAliasResolver","options","skipValidate","anyAction","copyArrayTo","dest","target","start","push","mergePrioritized","array","anotherArray","j","merged","priority","getOrDefault","map","key","defaultValue","get","set","identity","x","validate","rule","fields","fieldMatcher","conditions","conditionsMatcher","Rule","resolveAction","inverted","reason","undefined","_options","_conditionsMatcher","this","_matchConditions","matches","ast","matchesConditions","matchesField","field","_matchField","linkedItem","prev","item","next","unlinkItem","cloneLinkedItem","defaultActionEntry","rules","defaultSubjectEntry","Map","analyze","index","_hasPerFieldRules","RuleIndex","_events","_ruleOptions","_anyAction","_anySubjectType","anySubjectType","_detectSubjectType","_rules","_indexedRules","_buildIndexFor","update","event","ability","_emit","rawRules","indexedRules","subjects","k","subjectRules","possibleRulesFor","subjectType","actionRules","anyActionRules","has","rulesFor","filter","on","handler","tail","currentTail","delete","payload","current","PureAbility","can","args","relevantRuleFor","cannot","defaultInstructions","$eq","$ne","$lt","$lte","$gt","$gte","$in","$nin","$all","$size","$regex","$options","$elemMatch","$exists","defaultInterpreters","eq","ne","lt","lte","gt","gte","in","within","nin","all","size","regex","elemMatch","exists","and","buildMongoQueryMatcher","instructions","interpreters","createFactory","mongoQueryMatcher","REGEXP_SPECIAL_CHARS","REGEXP_ANY","REGEXP_STARS","REGEXP_DOT","detectRegexpPattern","match","string","quantifier","matcher","pattern","replace","escapeRegexp","createPattern","patterns","RegExp","fieldPatternMatcher","every","f","test","Ability","RuleBuilder","_rule","because","AbilityBuilder","AbilityType","_AbilityType","bind","build","conditionsOrFields","builder","defineAbility","define","result","then","getDefaultErrorMessage","error","NativeError","NError","message","prototype","create","ForbiddenError","messageOrFn","_defaultErrorMessage","captureStackTrace","setMessage","throwUnlessCan"],"mappings":"uGAEO,SAASA,EAAaC,UACpBC,MAAMC,QAAQF,GAASA,EAAQ,CAACA,GAoBzC,MAAMG,EAAa,sBACZ,SAASC,EAGdC,EAASC,MACLA,MACGA,EAAOC,eAAeJ,GACzBK,OAAOC,eAAeH,EAAQH,EAAY,CAAEH,MAAOK,SAC9C,GAAIA,IAASC,EAAOH,SACnB,IAAIO,MAAO,yCAAwCL,qCAAwCC,EAAOH,aAIrGG,EAGF,MAAMK,EAAiBX,UACtBK,SAAcL,QACJ,WAATK,GAA8B,aAATA,GAG9B,MAAMO,EAAuBZ,GAAwBA,EAAMa,WAAab,EAAMc,KACvE,MAAMC,EAAsBf,GACT,kBAAVA,EAAqBA,EAAQY,EAAoBZ,GAG1D,SAASgB,EAAkBC,MAC5BA,EAAQV,eAAeJ,UACjBc,EAAgBd,UAGnBS,EAAoBK,EAAQC,aAIrC,SAASC,EAAcC,EAAsBC,EAA+BC,OACtEC,EAAUxB,EAAUsB,OACpBG,EAAI,QAEDA,EAAID,EAAQE,OAAQ,OACnBC,EAASH,EAAQC,QAEnBJ,EAASb,eAAemB,GAC1BH,EAAUD,EAAMC,EAASH,EAASM,WAI/BH,EAGT,SAASI,EAAcJ,EAAmBK,MACZ,kBAAjBA,IAAgE,IAAnCL,EAAQM,QAAQD,UAC/CA,MAGJ,IAAIJ,EAAI,EAAGA,EAAII,EAAaH,OAAQD,QACG,IAAtCD,EAAQM,QAAQD,EAAaJ,IAAY,OAAOI,EAAaJ,UAG5D,KAGT,MAAMM,EAAgC,CAACP,EAASG,IAAWH,EAAQQ,OAAOL,GAC1E,SAASM,EAAkBZ,EAAsBa,MAC3CA,KAAkBb,QACd,IAAIV,MAAO,eAAcuB,sDAG3BC,EAAO1B,OAAO0B,KAAKd,SACnBe,EAA0C,CAACZ,EAASG,WAClDU,EAAYT,EAAcJ,EAASG,MACrCU,EAAW,MAAM,IAAI1B,MAAO,kBAAiB0B,QAAgBb,EAAQc,KAAK,eAExEC,EAA0C,kBAAXZ,GAAuBA,IAAWO,IAC7B,IAArCV,EAAQM,QAAQI,IAChBhC,MAAMC,QAAQwB,KAA+C,IAApCA,EAAOG,QAAQI,MACzCK,EAAuB,MAAM,IAAI5B,MAAO,4BAA2BuB,6CAEhEV,EAAQQ,OAAOL,QAGnB,IAAIF,EAAI,EAAGA,EAAIU,EAAKT,OAAQD,IAC/BL,EAAcC,EAAUc,EAAKV,GAAIW,GAK9B,SAASI,EAAoBnB,EAAsBoB,OACnDA,GAAoC,QAAzBA,EAAQC,aACtBT,EAAkBZ,EAAUoB,GAAWA,EAAQE,WAAa,iBAGtDhB,GAA8BP,EAAcC,EAAUM,EAAQI,GAGxE,SAASa,EAAeC,EAAWC,EAAaC,OACzC,IAAItB,EAAIsB,EAAOtB,EAAIqB,EAAOpB,OAAQD,IACrCoB,EAAKG,KAAKF,EAAOrB,IAId,SAASwB,EACdC,EACAC,OAEKD,IAAUA,EAAMxB,cACZyB,GAAgB,OAGpBA,IAAiBA,EAAazB,cAC1BwB,GAAS,OAGdzB,EAAI,MACJ2B,EAAI,QACFC,EAAc,SAEb5B,EAAIyB,EAAMxB,QAAU0B,EAAID,EAAazB,UACtCwB,EAAMzB,GAAG6B,SAAWH,EAAaC,GAAGE,SAAU,CAChDD,EAAOL,KAAKE,EAAMzB,IAClBA,QACK,CACL4B,EAAOL,KAAKG,EAAaC,IACzBA,IAIJR,EAAYS,EAAQH,EAAOzB,GAC3BmB,EAAYS,EAAQF,EAAcC,UAE3BC,EAGF,SAASE,EAAmBC,EAAgBC,EAAQC,OACrDzD,EAAQuD,EAAIG,IAAIF,OAEfxD,EAAO,CACVA,EAAQyD,IACRF,EAAII,IAAIH,EAAKxD,UAGRA,EAGF,MAAM4D,EAAeC,GAASA,ECzJrC,SAASC,EAASC,EAAmCvB,MAC/CvC,MAAMC,QAAQ6D,EAAKC,UAAYD,EAAKC,OAAOvC,aACvC,IAAIf,MAAM,wEAGdqD,EAAKC,SAAWxB,EAAQyB,mBACpB,IAAIvD,MAAM,mFAGdqD,EAAKG,aAAe1B,EAAQ2B,wBACxB,IAAIzD,MAAM,yFAUb,MAAM0D,EAYXlD,YACE6C,EACAvB,EACAa,EAAmB,GAEnBS,EAASC,EAAMvB,QAEVd,OAASc,EAAQ6B,cAAcN,EAAKrC,aACpCT,QAAU8C,EAAK9C,aACfqD,WAAaP,EAAKO,cAClBJ,WAAaH,EAAKG,gBAClBK,OAASR,EAAKQ,YACdP,OAASD,EAAKC,OAASjE,EAAUgE,EAAKC,aAAUQ,OAChDnB,SAAWA,OACXoB,EAAWjC,EAGVkC,OACFC,KAAKT,aAAeS,KAAKC,OACtBA,EAAmBD,KAAKF,EAASN,kBAAmBQ,KAAKT,mBAGzDS,KAAKC,kBAINC,EAAUF,KAAKD,WACdG,EAAUA,EAAQC,SAAMN,EAGjCO,kBAAkBzE,OACXqE,KAAKT,kBACD,SAGJ5D,GAAUK,EAAcL,UACnBqE,KAAKL,eAGTO,EAAUF,KAAKD,WACdG,EAAQvE,GAGjB0E,aAAaC,OACNN,KAAKX,cACD,SAGJiB,SACKN,KAAKL,YAGXK,KAAKX,SAAWW,KAAKO,OAClBA,EAAcP,KAAKF,EAASR,aAAcU,KAAKX,eAG/CW,KAAKO,EAAaD,IChGtB,SAASE,EAAcnF,EAAUoF,SAChCC,EAAO,CAAErF,MAAAA,EAAOoF,KAAAA,EAAME,KAAM,SAE9BF,EACFA,EAAKE,KAAOD,SAGPA,EAGF,SAASE,EAAWF,MACrBA,EAAKC,KACPD,EAAKC,KAAKF,KAAOC,EAAKD,QAGpBC,EAAKD,KACPC,EAAKD,KAAKE,KAAOD,EAAKC,KAGxBD,EAAKC,KAAOD,EAAKD,KAAO,KAGnB,MAAMI,EAA8CH,KACzDrF,MAAOqF,EAAKrF,MACZoF,KAAMC,EAAKD,KACXE,KAAMD,EAAKC,OC0Cb,MAAMG,EAAqB,MACzBC,MAAO,GACPtC,OAAQ,QAEV,MAAMuC,EAAsB,IAAM,IAAIC,IACtC,MAAMC,EAAU,CAACC,EAAY/B,SACtB+B,EAAMC,GAAqBhC,EAAKC,OACnC8B,EAAMC,EAAoB,MAevB,MAAMC,EAYX9E,YACEwE,EAAsC,GACtClD,EAA2C,SAbrCuD,EAA6B,WAC7BE,EAAwB,IAAIL,SAc7BM,EAAe,CAClB/B,kBAAmB3B,EAAQ2B,kBAC3BF,aAAczB,EAAQyB,aACtBI,cAAe7B,EAAQ6B,eAAiBT,QAErCuC,EAAa3D,EAAQE,WAAa,cAClC0D,EAAkB5D,EAAQ6D,gBAAkB,WAC5CC,EAAqB9D,EAAQxB,mBAAqBA,OAClDuF,EAASb,OACTc,EAAgB7B,KAAK8B,EAAef,sBAIlCf,KAAK4B,EAGdvF,kBAAkBV,MACZK,EAAcL,GAAS,OAAOA,MAC7BA,EAAQ,OAAOqE,KAAKyB,SAClBzB,KAAK2B,EAAmBhG,GAGjCoG,OAAOhB,SACCiB,EAAQ,CACZjB,MAAAA,EACAkB,QAASjC,KACT9B,OAAQ8B,WAGLkC,EAAM,SAAUF,QAChBJ,EAASb,OACTc,EAAgB7B,KAAK8B,EAAef,QACpCmB,EAAM,UAAWF,UAEfhC,KAGD8B,EAAeK,SACfC,EAAyC,IAAInB,QAE9C,IAAIpE,EAAIsF,EAASrF,OAAS,EAAGD,GAAK,EAAGA,IAAK,OACvC6B,EAAWyD,EAASrF,OAASD,EAAI,QACjCuC,EAAO,IAAIK,EAAK0C,EAAStF,GAAImD,KAAKuB,EAAc7C,SAChD9B,EAAUxB,EAAUgE,EAAKrC,cACzBsF,EAAWjH,EAAUgE,EAAK9C,SAAW0D,KAAKyB,GAChDP,EAAQlB,KAAMZ,OAET,IAAIkD,EAAI,EAAGA,EAAID,EAASvF,OAAQwF,IAAK,OAClCC,EAAe5D,EAAayD,EAAcC,EAASC,GAAItB,OAExD,IAAIxC,EAAI,EAAGA,EAAI5B,EAAQE,OAAQ0B,IAClCG,EAAa4D,EAAc3F,EAAQ4B,GAAIsC,GAAoBC,MAAM3C,KAAKgB,WAKrEgD,EAITI,iBACEzF,EACA0F,EAA2BzC,KAAKyB,OAE3BzF,EAAcyG,SACX,IAAI1G,MAAM,oGAGZwG,EAAe5D,EAAaqB,KAAK6B,EAAeY,EAAazB,SAC7D0B,EAAc/D,EAAa4D,EAAcxF,EAAQ+D,MAEnD4B,EAAYjE,cACPiE,EAAY3B,YAGf4B,EAAiB5F,IAAWiD,KAAKwB,GAAce,EAAaK,IAAI5C,KAAKwB,GACvEe,EAAaxD,IAAIiB,KAAKwB,GAAaT,WACnClB,MACAkB,EAAQ1C,EAAiBqE,EAAY3B,MAAO4B,MAE5CF,IAAgBzC,KAAKyB,EACvBV,EAAQ1C,EAAiB0C,EAAQf,KAAawC,iBAAiBzF,EAAQiD,KAAKyB,IAG9EiB,EAAY3B,MAAQA,EACpB2B,EAAYjE,OAAS,YAEdsC,EAIT8B,SAAS9F,EAAgB0F,EAA2BnC,SAC5CS,EAAgCf,KAAawC,iBAAiBzF,EAAQ0F,MAExEnC,GAA0B,kBAAVA,QACZ,IAAIvE,MAAM,qJAGbiE,KAAKoB,SACDL,SAGFA,EAAM+B,QAAO1D,GAAQA,EAAKiB,aAAaC,KAGhDyC,GACEf,EACAgB,SAEMC,EAAOjD,KAAKsB,EAAQvC,IAAIiD,IAAU,WAClCtB,EAAOF,EAAWwC,EAASC,QAC5B3B,EAAQtC,IAAIgD,EAAOtB,SAEjB,WACCwC,EAAclD,KAAKsB,EAAQvC,IAAIiD,OAEhCtB,EAAKC,OAASD,EAAKD,MAAQyC,IAAgBxC,OACzCY,EAAQ6B,OAAOnB,QACf,GAAItB,IAASwC,OACb5B,EAAQtC,IAAIgD,EAAOtB,EAAKD,MAG/BG,EAAWF,IAIPwB,EACN/F,EACAiH,OAEIC,EAAUrD,KAAKsB,EAAQvC,IAAI5C,IAAS,WACrB,OAAZkH,EAAkB,OACjB5C,EAAO4C,EAAQ5C,KAAOI,EAAgBwC,EAAQ5C,MAAQ,KAC5D4C,EAAQhI,MAAM+H,GACdC,EAAU5C,ICxOT,MAAM6C,oBAGHjC,EACRkC,OAAOC,SACCpE,EAAOY,KAAKyD,mBAAmBD,WAC5BpE,IAASA,EAAKO,SAIzB8D,gBAAgB1G,EAAgBT,EAAmBgE,SAC3CmC,EAAczC,KAAK3D,kBAAkBC,SACrCyE,EAASf,KAAa6C,SAAS9F,EAAQ0F,EAAanC,OAErD,IAAIzD,EAAI,EAAGC,EAASiE,EAAMjE,OAAQD,EAAIC,EAAQD,OAC7CkE,EAAMlE,GAAGuD,kBAAkB9D,UACtByE,EAAMlE,UAIV,KAGT6G,UAAUF,UACAxD,KAAKuD,OAAOC,ICDxB,MAAMG,EAAsB,KAC1BC,UACAC,UACAC,WACAC,WACAC,WACAC,WACAC,WACAC,YACAC,aACAC,eACAC,kBACAC,sBACAC,qBACAC,WAEF,MAAMC,EAAsB,IAC1BC,QACAC,QACAC,SACAC,SACAC,SACAC,MACAC,GAAIC,aACJC,UACAC,WACAC,aACAC,kBACAC,mBACAC,aACAC,aAeWC,EAA0B,CAACC,EAAcC,EAAc/H,IAAYgI,iCACzElC,EAAwBgC,oBACxBjB,EAAwBkB,GAC7B/H,SAGWiI,EAAoBD,gBAAclC,EAAqBe,GCrFpE,MAAMqB,EAAuB,uBAC7B,MAAMC,EAAa,aACnB,MAAMC,EAAe,MACrB,MAAMC,EAAa,MAEnB,SAASC,EAAoBC,EAAejF,EAAekF,SACnDC,EAA2B,MAAdD,EAAO,IAA2B,MAAbD,EAAM,IAA0C,MAA5BA,EAAMA,EAAMtJ,OAAS,GAC7E,IACA,UACEyJ,GAAmC,IAAzBH,EAAMlJ,QAAQ,MAAe,OAAS,UAChDsJ,EAAUJ,EAAMK,QAAQP,EAAY,QACvCO,QAAQR,EAAcM,EAAUD,UAE5BnF,EAAQiF,EAAMtJ,SAAWuJ,EAAOvJ,OAAU,MAAK0J,MAAcA,EAGtE,SAASE,EAAaN,EAAejF,EAAekF,MACpC,MAAVD,IAAwC,MAAtBC,EAAOlF,EAAQ,IAAoC,MAAtBkF,EAAOlF,EAAQ,WACzDiF,QAGD,KAAIA,IAGd,SAASO,EAActH,SACfuH,EAAWvH,EAAOT,KAAI0B,GAASA,EAClCmG,QAAQV,EAAsBW,GAC9BD,QAAQT,EAAYG,WACjBK,EAAUI,EAAS9J,OAAS,EAAK,MAAK8J,EAASlJ,KAAK,QAAUkJ,EAAS,UAEtE,IAAIC,OAAQ,IAAGL,YAGXM,EAAqCzH,QAC5CmH,SAEIlG,OACiB,qBAAZkG,EACTA,EAAUnH,EAAO0H,OAAMC,IAAyB,IAApBA,EAAE9J,QAAQ,OAClC,KACAyJ,EAActH,UAGD,OAAZmH,GACwB,IAA3BnH,EAAOnC,QAAQoD,GACfkG,EAAQS,KAAK3G,KCxCd,MAAM4G,gBAGH5D,YACR/G,YAAYwE,EAA6B,GAAIlD,EAAgC,UACrEkD,iBACJvB,kBAAmBsG,EACnBxG,aAAcwH,GACXjJ,KCDT,MAAMsJ,EAGJ5K,YAAY6C,QACLgI,EAAQhI,EAGfiI,QAAQzH,QACDwH,EAAMxH,OAASA,SACbI,MAiDJ,MAAMsH,eAIX/K,YAAYgL,QAHLxG,MAAwB,QAIxByG,EAAeD,OACfhE,IAAMvD,KAAKuD,IAAIkE,KAAKzH,WACpB0D,OAAS1D,KAAK0D,OAAO+D,KAAKzH,WAC1B0H,MAAQ1H,KAAK0H,MAAMD,KAAKzH,MAY/BuD,IACExG,EACAT,EACAqL,EACApI,SAEMH,EAAO,CAAErC,OAAAA,MAEXT,EAAS,CACX8C,EAAK9C,QAAUA,KAEXhB,MAAMC,QAAQoM,IAAqD,kBAAvBA,EAC9CvI,EAAKC,OAASsI,OACT,GAAkC,qBAAvBA,EAChBvI,EAAKG,WAAaoI,KAGM,qBAAfpI,EACTH,EAAKG,WAAaA,OAIjBwB,MAAM3C,KAAKgB,UAET,IAAI+H,EAAY/H,GAYzBsE,OACE3G,EACAT,EACAqL,EACApI,SAEMqI,EAAW5H,KAAauD,IAAIxG,EAAQT,EAASqL,EAAoBpI,GACvEqI,EAAQR,EAAMzH,SAAW,YAClBiI,EAGTF,MAAM7J,UACG,IAAImC,KAAKwH,EAAaxH,KAAKe,MAAOlD,IAetC,SAASgK,cAEdC,EAAsCjK,SAChC+J,EAAU,IAAIN,eAAeJ,eAC7Ba,EAASD,EAAOF,EAAQrE,IAAKqE,EAAQlE,WAEvCqE,GAAiC,oBAAhBA,EAAOC,YACnBD,EAAOC,MAAK,IAAMJ,EAAQF,MAAM7J,YAGlC+J,EAAQF,MAAM7J,SC/JVoK,EAA0CC,GAAU,mBAAkBA,EAAMnL,eAAemL,EAAMzF,eAE9G,MAAM0F,EAAc,SAASC,EAAoBC,QAC1CA,QAAUA,GAGjBF,EAAYG,UAAYzM,OAAO0M,OAAOxM,MAAMuM,WAErC,MAAME,uBAA6CL,2BAS/BM,QAClBC,EAA8C,kBAAhBD,EAA2B,IAAMA,EAAcA,cAGlDxG,UACzB,IAAIjC,KAAQiC,GAGb1F,YAAY0F,SACZ,SACDA,QAAUA,KAEwB,oBAA5BlG,MAAM4M,kBAAkC,MAC5CxM,KAAO,iBACZJ,MAAM4M,kBAAkB3I,KAAMA,KAAKzD,cAIvCqM,WAAWP,QACJA,QAAUA,SACRrI,KAGT6I,kBAAkBrF,SACVpE,EAAOY,KAAKiC,QAAQwB,mBAAmBD,MAEzCpE,IAASA,EAAKO,qBAIb5C,OAASyG,EAAK,QACdlH,QAAUkH,EAAK,QACff,YAAcrG,EAAmB4D,KAAKiC,QAAQ5F,kBAAkBmH,EAAK,UACrElD,MAAQkD,EAAK,SAEZ5D,EAASR,EAAOA,EAAKQ,OAAS,QAE/ByI,QAAUrI,KAAKqI,SAAWzI,GAAWI,KAAKzD,YAAoBmM,EAAqB1I,YAClFA,MA/CGwI,eAOJE,EAAuBT"}

@@ -1,2 +0,2 @@

import{createFactory as t,$eq as e,$ne as i,$lt as s,$lte as n,$gt as r,$gte as o,$in as c,$nin as u,$all as h,$size as l,$regex as a,$options as f,$elemMatch as d,$exists as p,eq as b,ne as y,lt as w,lte as g,gt as $,gte as m,within as E,nin as A,all as j,size as v,regex as x,elemMatch as M,exists as _,and as F}from"@ucast/mongo2js";function O(t){return Array.isArray(t)?t:[t]}const C="__caslSubjectType__";function R(t,e){if(e)if(!e.hasOwnProperty(C))Object.defineProperty(e,C,{value:t});else if(t!==e[C])throw new Error(`Trying to cast object to subject type ${t} but previously it was casted to ${e[C]}`);return e}const T=t=>{const e=typeof t;return"string"===e||"function"===e};const B=t=>t.modelName||t.name;const P=t=>"string"===typeof t?t:B(t);function S(t){if(t.hasOwnProperty(C))return t[C];return B(t.constructor)}function q(t,e,i){let s=O(e);let n=0;while(n<s.length){const e=s[n++];if(t.hasOwnProperty(e))s=i(s,t[e])}return s}function z(t,e){if("string"===typeof e&&-1!==t.indexOf(e))return e;for(let i=0;i<e.length;i++)if(-1!==t.indexOf(e[i]))return e[i];return null}const D=(t,e)=>t.concat(e);function Y(t,e){if(e in t)throw new Error(`Cannot use "${e}" as an alias because it's reserved action.`);const i=Object.keys(t);const s=(t,i)=>{const s=z(t,i);if(s)throw new Error(`Detected cycle ${s} -> ${t.join(", ")}`);const n="string"===typeof i&&i===e||-1!==t.indexOf(e)||Array.isArray(i)&&-1!==i.indexOf(e);if(n)throw new Error(`Cannot make an alias to "${e}" because this is reserved action`);return t.concat(i)};for(let e=0;e<i.length;e++)q(t,i[e],s)}function k(t,e){if(!e||false!==e.skipValidate)Y(t,e&&e.anyAction||"manage");return e=>q(t,e,D)}function I(t,e,i){for(let s=i;s<e.length;s++)t.push(e[s])}function L(t,e){if(!t||!t.length)return e||[];if(!e||!e.length)return t||[];let i=0;let s=0;const n=[];while(i<t.length&&s<e.length)if(t[i].priority<e[s].priority){n.push(t[i]);i++}else{n.push(e[s]);s++}I(n,t,i);I(n,e,s);return n}function U(t,e,i){let s=t.get(e);if(!s){s=i();t.set(e,s)}return s}const G=t=>t;function H(t,e){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!e.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!e.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}class J{constructor(t,e,i=0){H(t,e);this.action=e.resolveAction(t.action);this.subject=t.subject;this.inverted=!!t.inverted;this.conditions=t.conditions;this.reason=t.reason;this.fields=t.fields?O(t.fields):void 0;this.priority=i;this.t=e}i(){if(this.conditions&&!this.o)this.o=this.t.conditionsMatcher(this.conditions);return this.o}get ast(){const t=this.i();return t?t.ast:void 0}matchesConditions(t){if(!this.conditions)return true;if(!t||T(t))return!this.inverted;const e=this.i();return e(t)}matchesField(t){if(!this.fields)return true;if(!t)return!this.inverted;if(this.fields&&!this.u)this.u=this.t.fieldMatcher(this.fields);return this.u(t)}}function K(t,e){const i={value:t,prev:e,next:null};if(e)e.next=i;return i}function N(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}const Q=t=>({value:t.value,prev:t.prev,next:t.next});const V=()=>({rules:[],merged:false});const W=()=>new Map;const X=(t,e)=>{if(!t.h&&e.fields)t.h=true};class Z{constructor(t=[],e={}){this.h=false;this.l=new Map;this.p={conditionsMatcher:e.conditionsMatcher,fieldMatcher:e.fieldMatcher,resolveAction:e.resolveAction||G};this.g=e.anyAction||"manage";this.$=e.anySubjectType||"all";this.m=e.detectSubjectType||S;this.A=t;this.j=this.v(t)}get rules(){return this.A}detectSubjectType(t){if(T(t))return t;if(!t)return this.$;return this.m(t)}update(t){const e={rules:t,ability:this,target:this};this.M("update",e);this.A=t;this.j=this.v(t);this.M("updated",e);return this}v(t){const e=new Map;for(let i=t.length-1;i>=0;i--){const s=t.length-i-1;const n=new J(t[i],this.p,s);const r=O(n.action);const o=O(n.subject||this.$);X(this,n);for(let t=0;t<o.length;t++){const i=U(e,o[t],W);for(let t=0;t<r.length;t++)U(i,r[t],V).rules.push(n)}}return e}possibleRulesFor(t,e=this.$){if(!T(e))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');const i=U(this.j,e,W);const s=U(i,t,V);if(s.merged)return s.rules;const n=t!==this.g&&i.has(this.g)?i.get(this.g).rules:void 0;let r=L(s.rules,n);if(e!==this.$)r=L(r,this.possibleRulesFor(t,this.$));s.rules=r;s.merged=true;return r}rulesFor(t,e,i){const s=this.possibleRulesFor(t,e);if(i&&"string"!==typeof i)throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");if(!this.h)return s;return s.filter((t=>t.matchesField(i)))}on(t,e){const i=this.l.get(t)||null;const s=K(e,i);this.l.set(t,s);return()=>{if(!s.next&&!s.prev&&this.l.get(t)===s)this.l.delete(t);else N(s)}}M(t,e){let i=this.l.get(t)||null;while(null!==i){const t=i.prev?Q(i.prev):null;i.value(e);i=t}}}class PureAbility extends Z{can(...t){const e=this.relevantRuleFor(...t);return!!e&&!e.inverted}relevantRuleFor(t,e,i){const s=this.detectSubjectType(e);const n=this.rulesFor(t,s,i);for(let t=0,i=n.length;t<i;t++)if(n[t].matchesConditions(e))return n[t];return null}cannot(...t){return!this.can(...t)}}const tt={$eq:e,$ne:i,$lt:s,$lte:n,$gt:r,$gte:o,$in:c,$nin:u,$all:h,$size:l,$regex:a,$options:f,$elemMatch:d,$exists:p};const et={eq:b,ne:y,lt:w,lte:g,gt:$,gte:m,in:E,nin:A,all:j,size:v,regex:x,elemMatch:M,exists:_,and:F};const it=(e,i,s)=>t(Object.assign({},tt,e),Object.assign({},et,i),s);const st=t(tt,et);const nt=/[-/\\^$+?.()|[\]{}]/g;const rt=/\.?\*+\.?/g;const ot=/\*+/;const ct=/\./g;function ut(t,e,i){const s="*"===i[0]||"."===t[0]&&"."===t[t.length-1]?"+":"*";const n=-1===t.indexOf("**")?"[^.]":".";const r=t.replace(ct,"\\$&").replace(ot,n+s);return e+t.length===i.length?`(?:${r})?`:r}function ht(t,e,i){if("."===t&&("*"===i[e-1]||"*"===i[e+1]))return t;return`\\${t}`}function lt(t){const e=t.map((t=>t.replace(nt,ht).replace(rt,ut)));const i=e.length>1?`(?:${e.join("|")})`:e[0];return new RegExp(`^${i}$`)}const at=t=>{let e;return i=>{if("undefined"===typeof e)e=t.every((t=>-1===t.indexOf("*")))?null:lt(t);return null===e?-1!==t.indexOf(i):e.test(i)}};class Ability extends PureAbility{constructor(t=[],e={}){super(t,Object.assign({conditionsMatcher:st,fieldMatcher:at},e))}}class ft{constructor(t){this._=t}because(t){this._.reason=t;return this}}class AbilityBuilder{constructor(t){this.rules=[];this.F=t;this.can=this.can.bind(this);this.cannot=this.cannot.bind(this);this.build=this.build.bind(this)}can(t,e,i,s){const n={action:t};if(e){n.subject=e;if(Array.isArray(i)||"string"===typeof i)n.fields=i;else if("undefined"!==typeof i)n.conditions=i;if("undefined"!==typeof s)n.conditions=s}this.rules.push(n);return new ft(n)}cannot(t,e,i,s){const n=this.can(t,e,i,s);n._.inverted=true;return n}build(t){return new this.F(this.rules,t)}}function defineAbility(t,e){const i=new AbilityBuilder(Ability);const s=t(i.can,i.cannot);if(s&&"function"===typeof s.then)return s.then((()=>i.build(e)));return i.build(e)}const dt=t=>`Cannot execute "${t.action}" on "${t.subjectType}"`;const pt=function t(e){this.message=e};pt.prototype=Object.create(Error.prototype);class ForbiddenError extends pt{static setDefaultMessage(t){this.O="string"===typeof t?()=>t:t}static from(t){return new this(t)}constructor(t){super("");this.ability=t;if("function"===typeof Error.captureStackTrace){this.name="ForbiddenError";Error.captureStackTrace(this,this.constructor)}}setMessage(t){this.message=t;return this}throwUnlessCan(...t){const e=this.ability.relevantRuleFor(...t);if(e&&!e.inverted)return;this.action=t[0];this.subject=t[1];this.subjectType=P(this.ability.detectSubjectType(t[1]));this.field=t[2];const i=e?e.reason:"";this.message=this.message||i||this.constructor.O(this);throw this}}ForbiddenError.O=dt;var bt=Object.freeze({__proto__:null});export{Ability,AbilityBuilder,ForbiddenError,PureAbility,it as buildMongoQueryMatcher,k as createAliasResolver,defineAbility,S as detectSubjectType,at as fieldPatternMatcher,dt as getDefaultErrorMessage,bt as hkt,st as mongoQueryMatcher,R as subject,O as wrapArray};
import{createFactory as t,$eq as e,$ne as i,$lt as s,$lte as n,$gt as r,$gte as o,$in as c,$nin as u,$all as h,$size as l,$regex as a,$options as f,$elemMatch as d,$exists as p,eq as b,ne as y,lt as w,lte as g,gt as $,gte as m,within as E,nin as A,all as j,size as v,regex as x,elemMatch as M,exists as _,and as F}from"@ucast/mongo2js";function O(t){return Array.isArray(t)?t:[t]}const C="__caslSubjectType__";function R(t,e){if(e)if(!e.hasOwnProperty(C))Object.defineProperty(e,C,{value:t});else if(t!==e[C])throw new Error(`Trying to cast object to subject type ${t} but previously it was casted to ${e[C]}`);return e}const T=t=>{const e=typeof t;return"string"===e||"function"===e};const B=t=>t.modelName||t.name;const P=t=>"string"===typeof t?t:B(t);function S(t){if(t.hasOwnProperty(C))return t[C];return B(t.constructor)}function q(t,e,i){let s=O(e);let n=0;while(n<s.length){const e=s[n++];if(t.hasOwnProperty(e))s=i(s,t[e])}return s}function z(t,e){if("string"===typeof e&&-1!==t.indexOf(e))return e;for(let i=0;i<e.length;i++)if(-1!==t.indexOf(e[i]))return e[i];return null}const D=(t,e)=>t.concat(e);function Y(t,e){if(e in t)throw new Error(`Cannot use "${e}" as an alias because it's reserved action.`);const i=Object.keys(t);const s=(t,i)=>{const s=z(t,i);if(s)throw new Error(`Detected cycle ${s} -> ${t.join(", ")}`);const n="string"===typeof i&&i===e||-1!==t.indexOf(e)||Array.isArray(i)&&-1!==i.indexOf(e);if(n)throw new Error(`Cannot make an alias to "${e}" because this is reserved action`);return t.concat(i)};for(let e=0;e<i.length;e++)q(t,i[e],s)}function k(t,e){if(!e||false!==e.skipValidate)Y(t,e&&e.anyAction||"manage");return e=>q(t,e,D)}function I(t,e,i){for(let s=i;s<e.length;s++)t.push(e[s])}function L(t,e){if(!t||!t.length)return e||[];if(!e||!e.length)return t||[];let i=0;let s=0;const n=[];while(i<t.length&&s<e.length)if(t[i].priority<e[s].priority){n.push(t[i]);i++}else{n.push(e[s]);s++}I(n,t,i);I(n,e,s);return n}function U(t,e,i){let s=t.get(e);if(!s){s=i();t.set(e,s)}return s}const G=t=>t;function H(t,e){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!e.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!e.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}class J{constructor(t,e,i=0){H(t,e);this.action=e.resolveAction(t.action);this.subject=t.subject;this.inverted=!!t.inverted;this.conditions=t.conditions;this.reason=t.reason;this.fields=t.fields?O(t.fields):void 0;this.priority=i;this.t=e}i(){if(this.conditions&&!this.o)this.o=this.t.conditionsMatcher(this.conditions);return this.o}get ast(){const t=this.i();return t?t.ast:void 0}matchesConditions(t){if(!this.conditions)return true;if(!t||T(t))return!this.inverted;const e=this.i();return e(t)}matchesField(t){if(!this.fields)return true;if(!t)return!this.inverted;if(this.fields&&!this.u)this.u=this.t.fieldMatcher(this.fields);return this.u(t)}}function K(t,e){const i={value:t,prev:e,next:null};if(e)e.next=i;return i}function N(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}const Q=t=>({value:t.value,prev:t.prev,next:t.next});const V=()=>({rules:[],merged:false});const W=()=>new Map;const X=(t,e)=>{if(!t.h&&e.fields)t.h=true};class Z{constructor(t=[],e={}){this.h=false;this.l=new Map;this.p={conditionsMatcher:e.conditionsMatcher,fieldMatcher:e.fieldMatcher,resolveAction:e.resolveAction||G};this.g=e.anyAction||"manage";this.$=e.anySubjectType||"all";this.m=e.detectSubjectType||S;this.A=t;this.j=this.v(t)}get rules(){return this.A}detectSubjectType(t){if(T(t))return t;if(!t)return this.$;return this.m(t)}update(t){const e={rules:t,ability:this,target:this};this.M("update",e);this.A=t;this.j=this.v(t);this.M("updated",e);return this}v(t){const e=new Map;for(let i=t.length-1;i>=0;i--){const s=t.length-i-1;const n=new J(t[i],this.p,s);const r=O(n.action);const o=O(n.subject||this.$);X(this,n);for(let t=0;t<o.length;t++){const i=U(e,o[t],W);for(let t=0;t<r.length;t++)U(i,r[t],V).rules.push(n)}}return e}possibleRulesFor(t,e=this.$){if(!T(e))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');const i=U(this.j,e,W);const s=U(i,t,V);if(s.merged)return s.rules;const n=t!==this.g&&i.has(this.g)?i.get(this.g).rules:void 0;let r=L(s.rules,n);if(e!==this.$)r=L(r,this.possibleRulesFor(t,this.$));s.rules=r;s.merged=true;return r}rulesFor(t,e,i){const s=this.possibleRulesFor(t,e);if(i&&"string"!==typeof i)throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");if(!this.h)return s;return s.filter((t=>t.matchesField(i)))}on(t,e){const i=this.l.get(t)||null;const s=K(e,i);this.l.set(t,s);return()=>{const e=this.l.get(t);if(!s.next&&!s.prev&&e===s)this.l.delete(t);else if(s===e)this.l.set(t,s.prev);N(s)}}M(t,e){let i=this.l.get(t)||null;while(null!==i){const t=i.prev?Q(i.prev):null;i.value(e);i=t}}}class PureAbility extends Z{can(...t){const e=this.relevantRuleFor(...t);return!!e&&!e.inverted}relevantRuleFor(t,e,i){const s=this.detectSubjectType(e);const n=this.rulesFor(t,s,i);for(let t=0,i=n.length;t<i;t++)if(n[t].matchesConditions(e))return n[t];return null}cannot(...t){return!this.can(...t)}}const tt={$eq:e,$ne:i,$lt:s,$lte:n,$gt:r,$gte:o,$in:c,$nin:u,$all:h,$size:l,$regex:a,$options:f,$elemMatch:d,$exists:p};const et={eq:b,ne:y,lt:w,lte:g,gt:$,gte:m,in:E,nin:A,all:j,size:v,regex:x,elemMatch:M,exists:_,and:F};const it=(e,i,s)=>t(Object.assign({},tt,e),Object.assign({},et,i),s);const st=t(tt,et);const nt=/[-/\\^$+?.()|[\]{}]/g;const rt=/\.?\*+\.?/g;const ot=/\*+/;const ct=/\./g;function ut(t,e,i){const s="*"===i[0]||"."===t[0]&&"."===t[t.length-1]?"+":"*";const n=-1===t.indexOf("**")?"[^.]":".";const r=t.replace(ct,"\\$&").replace(ot,n+s);return e+t.length===i.length?`(?:${r})?`:r}function ht(t,e,i){if("."===t&&("*"===i[e-1]||"*"===i[e+1]))return t;return`\\${t}`}function lt(t){const e=t.map((t=>t.replace(nt,ht).replace(rt,ut)));const i=e.length>1?`(?:${e.join("|")})`:e[0];return new RegExp(`^${i}$`)}const at=t=>{let e;return i=>{if("undefined"===typeof e)e=t.every((t=>-1===t.indexOf("*")))?null:lt(t);return null===e?-1!==t.indexOf(i):e.test(i)}};class Ability extends PureAbility{constructor(t=[],e={}){super(t,Object.assign({conditionsMatcher:st,fieldMatcher:at},e))}}class ft{constructor(t){this._=t}because(t){this._.reason=t;return this}}class AbilityBuilder{constructor(t){this.rules=[];this.F=t;this.can=this.can.bind(this);this.cannot=this.cannot.bind(this);this.build=this.build.bind(this)}can(t,e,i,s){const n={action:t};if(e){n.subject=e;if(Array.isArray(i)||"string"===typeof i)n.fields=i;else if("undefined"!==typeof i)n.conditions=i;if("undefined"!==typeof s)n.conditions=s}this.rules.push(n);return new ft(n)}cannot(t,e,i,s){const n=this.can(t,e,i,s);n._.inverted=true;return n}build(t){return new this.F(this.rules,t)}}function defineAbility(t,e){const i=new AbilityBuilder(Ability);const s=t(i.can,i.cannot);if(s&&"function"===typeof s.then)return s.then((()=>i.build(e)));return i.build(e)}const dt=t=>`Cannot execute "${t.action}" on "${t.subjectType}"`;const pt=function t(e){this.message=e};pt.prototype=Object.create(Error.prototype);class ForbiddenError extends pt{static setDefaultMessage(t){this.O="string"===typeof t?()=>t:t}static from(t){return new this(t)}constructor(t){super("");this.ability=t;if("function"===typeof Error.captureStackTrace){this.name="ForbiddenError";Error.captureStackTrace(this,this.constructor)}}setMessage(t){this.message=t;return this}throwUnlessCan(...t){const e=this.ability.relevantRuleFor(...t);if(e&&!e.inverted)return;this.action=t[0];this.subject=t[1];this.subjectType=P(this.ability.detectSubjectType(t[1]));this.field=t[2];const i=e?e.reason:"";this.message=this.message||i||this.constructor.O(this);throw this}}ForbiddenError.O=dt;var bt=Object.freeze({__proto__:null});export{Ability,AbilityBuilder,ForbiddenError,PureAbility,it as buildMongoQueryMatcher,k as createAliasResolver,defineAbility,S as detectSubjectType,at as fieldPatternMatcher,dt as getDefaultErrorMessage,bt as hkt,st as mongoQueryMatcher,R as subject,O as wrapArray};
//# sourceMappingURL=index.mjs.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.mjs","sources":["../../src/utils.ts","../../src/Rule.ts","../../src/structures/LinkedItem.ts","../../src/RuleIndex.ts","../../src/PureAbility.ts","../../src/matchers/conditions.ts","../../src/matchers/field.ts","../../src/Ability.ts","../../src/AbilityBuilder.ts","../../src/ForbiddenError.ts"],"sourcesContent":["import { AnyObject, Subject, SubjectType, SubjectClass, ForcedSubject, AliasesMap } from './types';\n\nexport function wrapArray<T>(value: T[] | T): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function setByPath(object: AnyObject, path: string, value: unknown): void {\n let ref = object;\n let lastKey = path;\n\n if (path.indexOf('.') !== -1) {\n const keys = path.split('.');\n\n lastKey = keys.pop()!;\n ref = keys.reduce((res, prop) => {\n res[prop] = res[prop] || {};\n return res[prop] as AnyObject;\n }, object);\n }\n\n ref[lastKey] = value;\n}\n\nconst TYPE_FIELD = '__caslSubjectType__';\nexport function setSubjectType<\n T extends string,\n U extends Record<PropertyKey, any>\n>(type: T, object: U): U & ForcedSubject<T> {\n if (object) {\n if (!object.hasOwnProperty(TYPE_FIELD)) {\n Object.defineProperty(object, TYPE_FIELD, { value: type });\n } else if (type !== object[TYPE_FIELD]) {\n throw new Error(`Trying to cast object to subject type ${type} but previously it was casted to ${object[TYPE_FIELD]}`);\n }\n }\n\n return object as U & ForcedSubject<T>;\n}\n\nexport const isSubjectType = (value: unknown): value is SubjectType => {\n const type = typeof value;\n return type === 'string' || type === 'function';\n};\n\nconst getSubjectClassName = (value: SubjectClass) => value.modelName || value.name;\nexport const getSubjectTypeName = (value: SubjectType) => {\n return typeof value === 'string' ? value : getSubjectClassName(value);\n};\n\nexport function detectSubjectType(subject: Exclude<Subject, SubjectType>): string {\n if (subject.hasOwnProperty(TYPE_FIELD)) {\n return (subject as any)[TYPE_FIELD];\n }\n\n return getSubjectClassName(subject.constructor as SubjectClass);\n}\n\ntype AliasMerge = (actions: string[], action: string | string[]) => string[];\nfunction expandActions(aliasMap: AliasesMap, rawActions: string | string[], merge: AliasMerge) {\n let actions = wrapArray(rawActions);\n let i = 0;\n\n while (i < actions.length) {\n const action = actions[i++];\n\n if (aliasMap.hasOwnProperty(action)) {\n actions = merge(actions, aliasMap[action]);\n }\n }\n\n return actions;\n}\n\nfunction findDuplicate(actions: string[], actionToFind: string | string[]) {\n if (typeof actionToFind === 'string' && actions.indexOf(actionToFind) !== -1) {\n return actionToFind;\n }\n\n for (let i = 0; i < actionToFind.length; i++) {\n if (actions.indexOf(actionToFind[i]) !== -1) return actionToFind[i];\n }\n\n return null;\n}\n\nconst defaultAliasMerge: AliasMerge = (actions, action) => actions.concat(action);\nfunction validateForCycles(aliasMap: AliasesMap, reservedAction: string) {\n if (reservedAction in aliasMap) {\n throw new Error(`Cannot use \"${reservedAction}\" as an alias because it's reserved action.`);\n }\n\n const keys = Object.keys(aliasMap);\n const mergeAliasesAndDetectCycles: AliasMerge = (actions, action) => {\n const duplicate = findDuplicate(actions, action);\n if (duplicate) throw new Error(`Detected cycle ${duplicate} -> ${actions.join(', ')}`);\n\n const isUsingReservedAction = typeof action === 'string' && action === reservedAction\n || actions.indexOf(reservedAction) !== -1\n || Array.isArray(action) && action.indexOf(reservedAction) !== -1;\n if (isUsingReservedAction) throw new Error(`Cannot make an alias to \"${reservedAction}\" because this is reserved action`);\n\n return actions.concat(action);\n };\n\n for (let i = 0; i < keys.length; i++) {\n expandActions(aliasMap, keys[i], mergeAliasesAndDetectCycles);\n }\n}\n\nexport type AliasResolverOptions = { skipValidate?: boolean; anyAction?: string };\nexport function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions) {\n if (!options || options.skipValidate !== false) {\n validateForCycles(aliasMap, options && options.anyAction || 'manage');\n }\n\n return (action: string | string[]) => expandActions(aliasMap, action, defaultAliasMerge);\n}\n\nfunction copyArrayTo<T>(dest: T[], target: T[], start: number) {\n for (let i = start; i < target.length; i++) {\n dest.push(target[i]);\n }\n}\n\nexport function mergePrioritized<T extends { priority: number }>(\n array?: T[],\n anotherArray?: T[]\n): T[] {\n if (!array || !array.length) {\n return anotherArray || [];\n }\n\n if (!anotherArray || !anotherArray.length) {\n return array || [];\n }\n\n let i = 0;\n let j = 0;\n const merged: T[] = [];\n\n while (i < array.length && j < anotherArray.length) {\n if (array[i].priority < anotherArray[j].priority) {\n merged.push(array[i]);\n i++;\n } else {\n merged.push(anotherArray[j]);\n j++;\n }\n }\n\n copyArrayTo(merged, array, i);\n copyArrayTo(merged, anotherArray, j);\n\n return merged;\n}\n\nexport function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V) {\n let value = map.get(key);\n\n if (!value) {\n value = defaultValue();\n map.set(key, value);\n }\n\n return value;\n}\n\nexport const identity = <T>(x: T) => x;\n","import { wrapArray, isSubjectType } from './utils';\nimport {\n MatchConditions,\n MatchField,\n Abilities,\n ToAbilityTypes,\n Normalize,\n ConditionsMatcher,\n FieldMatcher,\n} from './types';\nimport { RawRule, RawRuleFrom } from './RawRule';\n\ntype Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;\n\nfunction validate(rule: RawRuleFrom<Abilities, any>, options: RuleOptions<any>) {\n if (Array.isArray(rule.fields) && !rule.fields.length) {\n throw new Error('`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa');\n }\n\n if (rule.fields && !options.fieldMatcher) {\n throw new Error('You need to pass \"fieldMatcher\" option in order to restrict access by fields');\n }\n\n if (rule.conditions && !options.conditionsMatcher) {\n throw new Error('You need to pass \"conditionsMatcher\" option in order to restrict access by conditions');\n }\n}\n\nexport interface RuleOptions<Conditions> {\n conditionsMatcher?: ConditionsMatcher<Conditions>\n fieldMatcher?: FieldMatcher\n resolveAction(action: string | string[]): string | string[]\n}\n\nexport class Rule<A extends Abilities, C> {\n private _matchConditions: MatchConditions | undefined;\n private _matchField: MatchField<string> | undefined;\n private readonly _options!: RuleOptions<C>;\n public readonly action!: Tuple<A>[0] | Tuple<A>[0][];\n public readonly subject!: Tuple<A>[1] | Tuple<A>[1][];\n public readonly inverted!: boolean;\n public readonly conditions!: C | undefined;\n public readonly fields!: string[] | undefined;\n public readonly reason!: string | undefined;\n public readonly priority!: number;\n\n constructor(\n rule: RawRule<ToAbilityTypes<A>, C>,\n options: RuleOptions<C>,\n priority: number = 0\n ) {\n validate(rule, options);\n\n this.action = options.resolveAction(rule.action);\n this.subject = rule.subject!;\n this.inverted = !!rule.inverted;\n this.conditions = rule.conditions;\n this.reason = rule.reason;\n this.fields = rule.fields ? wrapArray(rule.fields) : undefined;\n this.priority = priority;\n this._options = options;\n }\n\n private _conditionsMatcher() {\n if (this.conditions && !this._matchConditions) {\n this._matchConditions = this._options.conditionsMatcher!(this.conditions);\n }\n\n return this._matchConditions!;\n }\n\n get ast() {\n const matches = this._conditionsMatcher();\n return matches ? matches.ast : undefined;\n }\n\n matchesConditions(object: Normalize<A>[1] | undefined): boolean {\n if (!this.conditions) {\n return true;\n }\n\n if (!object || isSubjectType(object)) {\n return !this.inverted;\n }\n\n const matches = this._conditionsMatcher();\n return matches(object as Record<string, unknown>);\n }\n\n matchesField(field: string | undefined): boolean {\n if (!this.fields) {\n return true;\n }\n\n if (!field) {\n return !this.inverted;\n }\n\n if (this.fields && !this._matchField) {\n this._matchField = this._options.fieldMatcher!(this.fields);\n }\n\n return this._matchField!(field);\n }\n}\n","export interface LinkedItem<T> {\n next: LinkedItem<T> | null\n prev: LinkedItem<T> | null\n readonly value: T\n}\n\nexport function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']) {\n const item = { value, prev, next: null };\n\n if (prev) {\n prev.next = item;\n }\n\n return item;\n}\n\nexport function unlinkItem(item: LinkedItem<any>) {\n if (item.next) {\n item.next.prev = item.prev;\n }\n\n if (item.prev) {\n item.prev.next = item.next;\n }\n\n item.next = item.prev = null; // eslint-disable-line\n}\n\nexport const cloneLinkedItem = <T extends LinkedItem<any>>(item: T): T => ({\n value: item.value,\n prev: item.prev,\n next: item.next,\n} as T);\n","import { Rule, RuleOptions } from './Rule';\nimport { RawRuleFrom } from './RawRule';\nimport {\n Abilities,\n Normalize,\n SubjectType,\n AbilityParameters,\n AbilityTuple,\n ExtractSubjectType\n} from './types';\nimport { wrapArray, detectSubjectType, mergePrioritized, getOrDefault, identity, isSubjectType } from './utils';\nimport { LinkedItem, linkedItem, unlinkItem, cloneLinkedItem } from './structures/LinkedItem';\n\nexport interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {\n detectSubjectType?(\n subject: Exclude<Normalize<A>[1], SubjectType>\n ): ExtractSubjectType<Normalize<A>[1]>;\n anyAction?: string;\n anySubjectType?: string;\n}\n\ndeclare const $abilities: unique symbol;\ndeclare const $conditions: unique symbol;\ninterface WithGenerics {\n [$abilities]: any\n [$conditions]: any\n}\nexport type Public<T extends WithGenerics> = { [K in keyof T]: T[K] };\nexport interface Generics<T extends WithGenerics> {\n abilities: T[typeof $abilities],\n conditions: T[typeof $conditions]\n}\n\nexport type RuleOf<T extends WithGenerics> =\n Rule<Generics<T>['abilities'], Generics<T>['conditions']>;\nexport type RawRuleOf<T extends WithGenerics> =\n RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;\n\nexport type RuleIndexOptionsOf<T extends WithGenerics> =\n RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;\n\ninterface AbilityEvent<T extends WithGenerics> {\n target: T\n /** @deprecated use \"target\" property instead */\n ability: T\n}\n\nexport interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {\n rules: RawRuleOf<T>[]\n}\n/**\n * @deprecated `on`/`emit` properly infer type without this type\n * TODO(major): delete\n */\nexport type EventHandler<Event> = (event: Event) => void;\n\nexport type Events<\n T extends WithGenerics,\n K extends keyof EventsMap<T> = keyof EventsMap<T>\n> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;\n\ninterface EventsMap<T extends WithGenerics> {\n update(event: UpdateEvent<T>): void\n updated(event: UpdateEvent<T>): void\n}\n\ntype IndexTree<A extends Abilities, C> = Map<SubjectType, Map<string, {\n rules: Rule<A, C>[],\n merged: boolean\n}>>;\n\nexport type Unsubscribe = () => void;\n\nconst defaultActionEntry = () => ({\n rules: [] as unknown as Rule<any, any>[],\n merged: false\n});\nconst defaultSubjectEntry = () => new Map<string, ReturnType<typeof defaultActionEntry>>();\nconst analyze = (index: any, rule: Rule<any, any>) => {\n if (!index._hasPerFieldRules && rule.fields) {\n index._hasPerFieldRules = true;\n }\n};\n\ntype AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> =\n AbilityParameters<\n T,\n T extends AbilityTuple\n ? IncludeField extends true\n ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0\n : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0\n : never,\n (action: Extract<T, string>) => 0\n >;\n\nexport class RuleIndex<A extends Abilities, Conditions> {\n private _hasPerFieldRules: boolean = false;\n private _events: Events<this> = new Map();\n private _indexedRules!: IndexTree<A, Conditions>;\n private _rules!: RawRuleFrom<A, Conditions>[];\n private readonly _ruleOptions!: RuleOptions<Conditions>;\n private readonly _detectSubjectType!: Required<RuleIndexOptions<A, Conditions>>['detectSubjectType'];\n private readonly _anyAction: string;\n private readonly _anySubjectType: string;\n readonly [$abilities]!: A;\n readonly [$conditions]!: Conditions;\n\n constructor(\n rules: RawRuleFrom<A, Conditions>[] = [],\n options: RuleIndexOptions<A, Conditions> = {}\n ) {\n this._ruleOptions = {\n conditionsMatcher: options.conditionsMatcher,\n fieldMatcher: options.fieldMatcher,\n resolveAction: options.resolveAction || identity,\n };\n this._anyAction = options.anyAction || 'manage';\n this._anySubjectType = options.anySubjectType || 'all';\n this._detectSubjectType = options.detectSubjectType || detectSubjectType;\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n }\n\n get rules() {\n return this._rules;\n }\n\n detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]> {\n if (isSubjectType(object)) return object;\n if (!object) return this._anySubjectType;\n return this._detectSubjectType(object as Exclude<Normalize<A>[1], SubjectType>);\n }\n\n update(rules: RawRuleFrom<A, Conditions>[]): Public<this> {\n const event = {\n rules,\n ability: this,\n target: this\n } as unknown as UpdateEvent<this>;\n\n this._emit('update', event);\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n this._emit('updated', event);\n\n return this;\n }\n\n private _buildIndexFor(rawRules: RawRuleFrom<A, Conditions>[]) {\n const indexedRules: IndexTree<A, Conditions> = new Map();\n\n for (let i = rawRules.length - 1; i >= 0; i--) {\n const priority = rawRules.length - i - 1;\n const rule = new Rule(rawRules[i], this._ruleOptions, priority);\n const actions = wrapArray(rule.action);\n const subjects = wrapArray(rule.subject || this._anySubjectType);\n analyze(this, rule);\n\n for (let k = 0; k < subjects.length; k++) {\n const subjectRules = getOrDefault(indexedRules, subjects[k], defaultSubjectEntry);\n\n for (let j = 0; j < actions.length; j++) {\n getOrDefault(subjectRules, actions[j], defaultActionEntry).rules.push(rule);\n }\n }\n }\n\n return indexedRules;\n }\n\n possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[]\n possibleRulesFor(\n action: string,\n subjectType: SubjectType = this._anySubjectType\n ): Rule<A, Conditions>[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"possibleRulesFor\" accepts only subject types (i.e., string or class) as the 2nd parameter');\n }\n\n const subjectRules = getOrDefault(this._indexedRules, subjectType, defaultSubjectEntry);\n const actionRules = getOrDefault(subjectRules, action, defaultActionEntry);\n\n if (actionRules.merged) {\n return actionRules.rules;\n }\n\n const anyActionRules = action !== this._anyAction && subjectRules.has(this._anyAction)\n ? subjectRules.get(this._anyAction)!.rules\n : undefined;\n let rules = mergePrioritized(actionRules.rules, anyActionRules);\n\n if (subjectType !== this._anySubjectType) {\n rules = mergePrioritized(rules, (this as any).possibleRulesFor(action, this._anySubjectType));\n }\n\n actionRules.rules = rules;\n actionRules.merged = true;\n\n return rules;\n }\n\n rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[]\n rulesFor(action: string, subjectType?: SubjectType, field?: string): Rule<A, Conditions>[] {\n const rules: Rule<A, Conditions>[] = (this as any).possibleRulesFor(action, subjectType);\n\n if (field && typeof field !== 'string') {\n throw new Error('The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details');\n }\n\n if (!this._hasPerFieldRules) {\n return rules;\n }\n\n return rules.filter(rule => rule.matchesField(field));\n }\n\n on<T extends keyof EventsMap<this>>(\n event: T,\n handler: EventsMap<Public<this>>[T]\n ): Unsubscribe {\n const head = this._events.get(event) || null;\n const item = linkedItem(handler, head);\n this._events.set(event, item);\n\n return () => {\n if (!item.next && !item.prev && this._events.get(event) === item) {\n this._events.delete(event);\n } else {\n unlinkItem(item);\n }\n };\n }\n\n private _emit<T extends keyof EventsMap<this>>(\n name: T,\n payload: Parameters<EventsMap<this>[T]>[0]\n ) {\n let current = this._events.get(name) || null;\n while (current !== null) {\n const prev = current.prev ? cloneLinkedItem(current.prev) : null;\n current.value(payload);\n current = prev;\n }\n }\n}\n","import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';\nimport { Abilities, AbilityTuple, CanParameters, Subject } from './types';\nimport { Rule } from './Rule';\n\nexport interface AbilityOptions<A extends Abilities, Conditions>\n extends RuleIndexOptions<A, Conditions> {}\nexport interface AnyAbility extends Public<PureAbility<any, any>> {}\nexport interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {}\nexport type AbilityClass<T extends AnyAbility> = new (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport class PureAbility<\n A extends Abilities = AbilityTuple,\n Conditions = unknown\n> extends RuleIndex<A, Conditions> {\n can(...args: CanParameters<A>): boolean {\n const rule = this.relevantRuleFor(...args);\n return !!rule && !rule.inverted;\n }\n\n relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null {\n const subjectType = this.detectSubjectType(subject);\n const rules = (this as any).rulesFor(action, subjectType, field);\n\n for (let i = 0, length = rules.length; i < length; i++) {\n if (rules[i].matchesConditions(subject)) {\n return rules[i];\n }\n }\n\n return null;\n }\n\n cannot(...args: CanParameters<A>): boolean {\n return !this.can(...args);\n }\n}\n","import {\n $eq,\n eq,\n $ne,\n ne,\n $lt,\n lt,\n $lte,\n lte,\n $gt,\n gt,\n $gte,\n gte,\n $in,\n within,\n $nin,\n nin,\n $all,\n all,\n $size,\n size,\n $regex,\n $options,\n regex,\n $elemMatch,\n elemMatch,\n $exists,\n exists,\n and,\n createFactory,\n BuildMongoQuery,\n DefaultOperators,\n} from '@ucast/mongo2js';\nimport { ConditionsMatcher, AnyObject } from '../types';\nimport { Container, GenericFactory } from '../hkt';\n\nconst defaultInstructions = {\n $eq,\n $ne,\n $lt,\n $lte,\n $gt,\n $gte,\n $in,\n $nin,\n $all,\n $size,\n $regex,\n $options,\n $elemMatch,\n $exists,\n};\nconst defaultInterpreters = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n in: within,\n nin,\n all,\n size,\n regex,\n elemMatch,\n exists,\n and,\n};\n\ninterface MongoQueryFactory extends GenericFactory {\n produce: MongoQuery<this[0]>\n}\n\ntype MergeUnion<T extends {}, Keys extends keyof T = keyof T> = { [K in Keys]: T[K] };\nexport type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {\n toplevel: {},\n field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>\n}> & Container<MongoQueryFactory>;\n\ntype MongoQueryMatcherFactory =\n (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;\nexport const buildMongoQueryMatcher = ((instructions, interpreters, options) => createFactory(\n { ...defaultInstructions, ...instructions },\n { ...defaultInterpreters, ...interpreters },\n options\n)) as MongoQueryMatcherFactory;\n\nexport const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);\nexport type {\n MongoQueryFieldOperators,\n MongoQueryTopLevelOperators,\n MongoQueryOperators,\n} from '@ucast/mongo2js';\n","import { FieldMatcher } from '../types';\n\nconst REGEXP_SPECIAL_CHARS = /[-/\\\\^$+?.()|[\\]{}]/g;\nconst REGEXP_ANY = /\\.?\\*+\\.?/g;\nconst REGEXP_STARS = /\\*+/;\nconst REGEXP_DOT = /\\./g;\n\nfunction detectRegexpPattern(match: string, index: number, string: string): string {\n const quantifier = string[0] === '*' || match[0] === '.' && match[match.length - 1] === '.'\n ? '+'\n : '*';\n const matcher = match.indexOf('**') === -1 ? '[^.]' : '.';\n const pattern = match.replace(REGEXP_DOT, '\\\\$&')\n .replace(REGEXP_STARS, matcher + quantifier);\n\n return index + match.length === string.length ? `(?:${pattern})?` : pattern;\n}\n\nfunction escapeRegexp(match: string, index: number, string: string): string {\n if (match === '.' && (string[index - 1] === '*' || string[index + 1] === '*')) {\n return match;\n }\n\n return `\\\\${match}`;\n}\n\nfunction createPattern(fields: string[]) {\n const patterns = fields.map(field => field\n .replace(REGEXP_SPECIAL_CHARS, escapeRegexp)\n .replace(REGEXP_ANY, detectRegexpPattern));\n const pattern = patterns.length > 1 ? `(?:${patterns.join('|')})` : patterns[0];\n\n return new RegExp(`^${pattern}$`);\n}\n\nexport const fieldPatternMatcher: FieldMatcher = (fields) => {\n let pattern: RegExp | null;\n\n return (field) => {\n if (typeof pattern === 'undefined') {\n pattern = fields.every(f => f.indexOf('*') === -1)\n ? null\n : createPattern(fields);\n }\n\n return pattern === null\n ? fields.indexOf(field) !== -1\n : pattern.test(field);\n };\n};\n","import { PureAbility, AbilityOptions } from './PureAbility';\nimport { RawRuleFrom } from './RawRule';\nimport { AbilityTuple } from './types';\nimport { MongoQuery, mongoQueryMatcher } from './matchers/conditions';\nimport { fieldPatternMatcher } from './matchers/field';\nimport { Public } from './RuleIndex';\n\nexport class Ability<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {\n constructor(rules: RawRuleFrom<A, C>[] = [], options: AbilityOptions<A, C> = {}) {\n super(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n }\n}\n\nexport interface AnyMongoAbility extends Public<Ability<any, MongoQuery>> {}\n","import { Ability, AnyMongoAbility } from './Ability';\nimport { AnyAbility, AbilityOptionsOf, AbilityClass } from './PureAbility';\nimport { RawRuleOf, Generics } from './RuleIndex';\nimport {\n ExtractSubjectType as E,\n AbilityTuple,\n SubjectType,\n TaggedInterface,\n Normalize,\n AnyObject,\n AnyClass,\n} from './types';\nimport { ProduceGeneric } from './hkt';\n\nclass RuleBuilder<T extends AnyAbility> {\n public _rule!: RawRuleOf<T>;\n\n constructor(rule: RawRuleOf<T>) {\n this._rule = rule;\n }\n\n because(reason: string): this {\n this._rule.reason = reason;\n return this;\n }\n}\n\ntype InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R>\n ? R\n : S extends string\n ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string>\n ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>>\n : AnyObject\n : never;\ntype ConditionsOf<T extends AnyAbility, I extends {}> =\n ProduceGeneric<Generics<T>['conditions'], I>;\ntype ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any\n ? S extends T[1] ? T[0] : never\n : never;\ntype ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;\ntype SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;\n\ntype SimpleCanParams<T extends AnyAbility> = Parameters<(\n action: Generics<T>['abilities'] | Generics<T>['abilities'][]\n) => 0>;\ntype BuilderCanParameters<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\n\ntype BuilderCanParametersWithFields<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n F extends string,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n fields?: F | F[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\ntype Keys<T> = string & keyof T;\n\nexport class AbilityBuilder<T extends AnyAbility> {\n public rules: RawRuleOf<T>[] = [];\n private _AbilityType!: AnyClass<T>;\n\n constructor(AbilityType: AnyClass<T>) {\n this._AbilityType = AbilityType;\n this.can = this.can.bind(this as any);\n this.cannot = this.cannot.bind(this as any);\n this.build = this.build.bind(this as any);\n }\n\n can<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n can<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n can(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ): RuleBuilder<T> {\n const rule = { action } as RawRuleOf<T>;\n\n if (subject) {\n rule.subject = subject;\n\n if (Array.isArray(conditionsOrFields) || typeof conditionsOrFields === 'string') {\n rule.fields = conditionsOrFields;\n } else if (typeof conditionsOrFields !== 'undefined') {\n rule.conditions = conditionsOrFields;\n }\n\n if (typeof conditions !== 'undefined') {\n rule.conditions = conditions;\n }\n }\n\n this.rules.push(rule);\n\n return new RuleBuilder(rule);\n }\n\n cannot<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n cannot<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n cannot(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions'],\n ): RuleBuilder<T> {\n const builder = (this as any).can(action, subject, conditionsOrFields, conditions);\n builder._rule.inverted = true;\n return builder;\n }\n\n build(options?: AbilityOptionsOf<T>) {\n return new this._AbilityType(this.rules, options);\n }\n}\n\ntype DSL<T extends AnyAbility, R> = (\n can: AbilityBuilder<T>['can'],\n cannot: AbilityBuilder<T>['cannot']\n) => R;\n\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void | Promise<void>>, options?: AbilityOptionsOf<T>): T | Promise<T> {\n const builder = new AbilityBuilder(Ability as unknown as AbilityClass<T>);\n const result = define(builder.can, builder.cannot);\n\n if (result && typeof result.then === 'function') {\n return result.then(() => builder.build(options));\n }\n\n return builder.build(options);\n}\n","import { AnyAbility } from './PureAbility';\nimport { Normalize } from './types';\nimport { Generics } from './RuleIndex';\nimport { getSubjectTypeName } from './utils';\n\nexport type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;\nexport const getDefaultErrorMessage: GetErrorMessage = error => `Cannot execute \"${error.action}\" on \"${error.subjectType}\"`;\n\nconst NativeError = function NError(this: Error, message: string) {\n this.message = message;\n} as unknown as new (message: string) => Error;\n\nNativeError.prototype = Object.create(Error.prototype);\n\nexport class ForbiddenError<T extends AnyAbility> extends NativeError {\n public readonly ability!: T;\n public action!: Normalize<Generics<T>['abilities']>[0];\n public subject!: Generics<T>['abilities'][1];\n public field?: string;\n public subjectType!: string;\n\n static _defaultErrorMessage = getDefaultErrorMessage;\n\n static setDefaultMessage(messageOrFn: string | GetErrorMessage) {\n this._defaultErrorMessage = typeof messageOrFn === 'string' ? () => messageOrFn : messageOrFn;\n }\n\n static from<U extends AnyAbility>(ability: U) {\n return new this<U>(ability);\n }\n\n private constructor(ability: T) {\n super('');\n this.ability = ability;\n\n if (typeof Error.captureStackTrace === 'function') {\n this.name = 'ForbiddenError';\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n setMessage(message: string) {\n this.message = message;\n return this;\n }\n\n throwUnlessCan(...args: Parameters<T['can']>) {\n const rule = this.ability.relevantRuleFor(...args);\n\n if (rule && !rule.inverted) {\n return;\n }\n\n this.action = args[0];\n this.subject = args[1];\n this.subjectType = getSubjectTypeName(this.ability.detectSubjectType(args[1]));\n this.field = args[2];\n\n const reason = rule ? rule.reason : '';\n // eslint-disable-next-line no-underscore-dangle\n this.message = this.message || reason || (this.constructor as any)._defaultErrorMessage(this);\n throw this; // eslint-disable-line\n }\n}\n"],"names":["wrapArray","value","Array","isArray","TYPE_FIELD","setSubjectType","type","object","hasOwnProperty","Object","defineProperty","Error","isSubjectType","getSubjectClassName","modelName","name","getSubjectTypeName","detectSubjectType","subject","constructor","expandActions","aliasMap","rawActions","merge","actions","i","length","action","findDuplicate","actionToFind","indexOf","defaultAliasMerge","concat","validateForCycles","reservedAction","keys","mergeAliasesAndDetectCycles","duplicate","join","isUsingReservedAction","createAliasResolver","options","skipValidate","anyAction","copyArrayTo","dest","target","start","push","mergePrioritized","array","anotherArray","j","merged","priority","getOrDefault","map","key","defaultValue","get","set","identity","x","validate","rule","fields","fieldMatcher","conditions","conditionsMatcher","Rule","resolveAction","inverted","reason","undefined","_options","_conditionsMatcher","this","_matchConditions","matches","ast","matchesConditions","matchesField","field","_matchField","linkedItem","prev","item","next","unlinkItem","cloneLinkedItem","defaultActionEntry","rules","defaultSubjectEntry","Map","analyze","index","_hasPerFieldRules","RuleIndex","_events","_ruleOptions","_anyAction","_anySubjectType","anySubjectType","_detectSubjectType","_rules","_indexedRules","_buildIndexFor","update","event","ability","_emit","rawRules","indexedRules","subjects","k","subjectRules","possibleRulesFor","subjectType","actionRules","anyActionRules","has","rulesFor","filter","on","handler","head","delete","payload","current","PureAbility","can","args","relevantRuleFor","cannot","defaultInstructions","$eq","$ne","$lt","$lte","$gt","$gte","$in","$nin","$all","$size","$regex","$options","$elemMatch","$exists","defaultInterpreters","eq","ne","lt","lte","gt","gte","in","within","nin","all","size","regex","elemMatch","exists","and","buildMongoQueryMatcher","instructions","interpreters","createFactory","mongoQueryMatcher","REGEXP_SPECIAL_CHARS","REGEXP_ANY","REGEXP_STARS","REGEXP_DOT","detectRegexpPattern","match","string","quantifier","matcher","pattern","replace","escapeRegexp","createPattern","patterns","RegExp","fieldPatternMatcher","every","f","test","Ability","RuleBuilder","_rule","because","AbilityBuilder","AbilityType","_AbilityType","bind","build","conditionsOrFields","builder","defineAbility","define","result","then","getDefaultErrorMessage","error","NativeError","NError","message","prototype","create","ForbiddenError","messageOrFn","_defaultErrorMessage","captureStackTrace","setMessage","throwUnlessCan"],"mappings":"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"}
{"version":3,"file":"index.mjs","sources":["../../src/utils.ts","../../src/Rule.ts","../../src/structures/LinkedItem.ts","../../src/RuleIndex.ts","../../src/PureAbility.ts","../../src/matchers/conditions.ts","../../src/matchers/field.ts","../../src/Ability.ts","../../src/AbilityBuilder.ts","../../src/ForbiddenError.ts"],"sourcesContent":["import { AnyObject, Subject, SubjectType, SubjectClass, ForcedSubject, AliasesMap } from './types';\n\nexport function wrapArray<T>(value: T[] | T): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function setByPath(object: AnyObject, path: string, value: unknown): void {\n let ref = object;\n let lastKey = path;\n\n if (path.indexOf('.') !== -1) {\n const keys = path.split('.');\n\n lastKey = keys.pop()!;\n ref = keys.reduce((res, prop) => {\n res[prop] = res[prop] || {};\n return res[prop] as AnyObject;\n }, object);\n }\n\n ref[lastKey] = value;\n}\n\nconst TYPE_FIELD = '__caslSubjectType__';\nexport function setSubjectType<\n T extends string,\n U extends Record<PropertyKey, any>\n>(type: T, object: U): U & ForcedSubject<T> {\n if (object) {\n if (!object.hasOwnProperty(TYPE_FIELD)) {\n Object.defineProperty(object, TYPE_FIELD, { value: type });\n } else if (type !== object[TYPE_FIELD]) {\n throw new Error(`Trying to cast object to subject type ${type} but previously it was casted to ${object[TYPE_FIELD]}`);\n }\n }\n\n return object as U & ForcedSubject<T>;\n}\n\nexport const isSubjectType = (value: unknown): value is SubjectType => {\n const type = typeof value;\n return type === 'string' || type === 'function';\n};\n\nconst getSubjectClassName = (value: SubjectClass) => value.modelName || value.name;\nexport const getSubjectTypeName = (value: SubjectType) => {\n return typeof value === 'string' ? value : getSubjectClassName(value);\n};\n\nexport function detectSubjectType(subject: Exclude<Subject, SubjectType>): string {\n if (subject.hasOwnProperty(TYPE_FIELD)) {\n return (subject as any)[TYPE_FIELD];\n }\n\n return getSubjectClassName(subject.constructor as SubjectClass);\n}\n\ntype AliasMerge = (actions: string[], action: string | string[]) => string[];\nfunction expandActions(aliasMap: AliasesMap, rawActions: string | string[], merge: AliasMerge) {\n let actions = wrapArray(rawActions);\n let i = 0;\n\n while (i < actions.length) {\n const action = actions[i++];\n\n if (aliasMap.hasOwnProperty(action)) {\n actions = merge(actions, aliasMap[action]);\n }\n }\n\n return actions;\n}\n\nfunction findDuplicate(actions: string[], actionToFind: string | string[]) {\n if (typeof actionToFind === 'string' && actions.indexOf(actionToFind) !== -1) {\n return actionToFind;\n }\n\n for (let i = 0; i < actionToFind.length; i++) {\n if (actions.indexOf(actionToFind[i]) !== -1) return actionToFind[i];\n }\n\n return null;\n}\n\nconst defaultAliasMerge: AliasMerge = (actions, action) => actions.concat(action);\nfunction validateForCycles(aliasMap: AliasesMap, reservedAction: string) {\n if (reservedAction in aliasMap) {\n throw new Error(`Cannot use \"${reservedAction}\" as an alias because it's reserved action.`);\n }\n\n const keys = Object.keys(aliasMap);\n const mergeAliasesAndDetectCycles: AliasMerge = (actions, action) => {\n const duplicate = findDuplicate(actions, action);\n if (duplicate) throw new Error(`Detected cycle ${duplicate} -> ${actions.join(', ')}`);\n\n const isUsingReservedAction = typeof action === 'string' && action === reservedAction\n || actions.indexOf(reservedAction) !== -1\n || Array.isArray(action) && action.indexOf(reservedAction) !== -1;\n if (isUsingReservedAction) throw new Error(`Cannot make an alias to \"${reservedAction}\" because this is reserved action`);\n\n return actions.concat(action);\n };\n\n for (let i = 0; i < keys.length; i++) {\n expandActions(aliasMap, keys[i], mergeAliasesAndDetectCycles);\n }\n}\n\nexport type AliasResolverOptions = { skipValidate?: boolean; anyAction?: string };\nexport function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions) {\n if (!options || options.skipValidate !== false) {\n validateForCycles(aliasMap, options && options.anyAction || 'manage');\n }\n\n return (action: string | string[]) => expandActions(aliasMap, action, defaultAliasMerge);\n}\n\nfunction copyArrayTo<T>(dest: T[], target: T[], start: number) {\n for (let i = start; i < target.length; i++) {\n dest.push(target[i]);\n }\n}\n\nexport function mergePrioritized<T extends { priority: number }>(\n array?: T[],\n anotherArray?: T[]\n): T[] {\n if (!array || !array.length) {\n return anotherArray || [];\n }\n\n if (!anotherArray || !anotherArray.length) {\n return array || [];\n }\n\n let i = 0;\n let j = 0;\n const merged: T[] = [];\n\n while (i < array.length && j < anotherArray.length) {\n if (array[i].priority < anotherArray[j].priority) {\n merged.push(array[i]);\n i++;\n } else {\n merged.push(anotherArray[j]);\n j++;\n }\n }\n\n copyArrayTo(merged, array, i);\n copyArrayTo(merged, anotherArray, j);\n\n return merged;\n}\n\nexport function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V) {\n let value = map.get(key);\n\n if (!value) {\n value = defaultValue();\n map.set(key, value);\n }\n\n return value;\n}\n\nexport const identity = <T>(x: T) => x;\n","import { wrapArray, isSubjectType } from './utils';\nimport {\n MatchConditions,\n MatchField,\n Abilities,\n ToAbilityTypes,\n Normalize,\n ConditionsMatcher,\n FieldMatcher,\n} from './types';\nimport { RawRule, RawRuleFrom } from './RawRule';\n\ntype Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;\n\nfunction validate(rule: RawRuleFrom<Abilities, any>, options: RuleOptions<any>) {\n if (Array.isArray(rule.fields) && !rule.fields.length) {\n throw new Error('`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa');\n }\n\n if (rule.fields && !options.fieldMatcher) {\n throw new Error('You need to pass \"fieldMatcher\" option in order to restrict access by fields');\n }\n\n if (rule.conditions && !options.conditionsMatcher) {\n throw new Error('You need to pass \"conditionsMatcher\" option in order to restrict access by conditions');\n }\n}\n\nexport interface RuleOptions<Conditions> {\n conditionsMatcher?: ConditionsMatcher<Conditions>\n fieldMatcher?: FieldMatcher\n resolveAction(action: string | string[]): string | string[]\n}\n\nexport class Rule<A extends Abilities, C> {\n private _matchConditions: MatchConditions | undefined;\n private _matchField: MatchField<string> | undefined;\n private readonly _options!: RuleOptions<C>;\n public readonly action!: Tuple<A>[0] | Tuple<A>[0][];\n public readonly subject!: Tuple<A>[1] | Tuple<A>[1][];\n public readonly inverted!: boolean;\n public readonly conditions!: C | undefined;\n public readonly fields!: string[] | undefined;\n public readonly reason!: string | undefined;\n public readonly priority!: number;\n\n constructor(\n rule: RawRule<ToAbilityTypes<A>, C>,\n options: RuleOptions<C>,\n priority: number = 0\n ) {\n validate(rule, options);\n\n this.action = options.resolveAction(rule.action);\n this.subject = rule.subject!;\n this.inverted = !!rule.inverted;\n this.conditions = rule.conditions;\n this.reason = rule.reason;\n this.fields = rule.fields ? wrapArray(rule.fields) : undefined;\n this.priority = priority;\n this._options = options;\n }\n\n private _conditionsMatcher() {\n if (this.conditions && !this._matchConditions) {\n this._matchConditions = this._options.conditionsMatcher!(this.conditions);\n }\n\n return this._matchConditions!;\n }\n\n get ast() {\n const matches = this._conditionsMatcher();\n return matches ? matches.ast : undefined;\n }\n\n matchesConditions(object: Normalize<A>[1] | undefined): boolean {\n if (!this.conditions) {\n return true;\n }\n\n if (!object || isSubjectType(object)) {\n return !this.inverted;\n }\n\n const matches = this._conditionsMatcher();\n return matches(object as Record<string, unknown>);\n }\n\n matchesField(field: string | undefined): boolean {\n if (!this.fields) {\n return true;\n }\n\n if (!field) {\n return !this.inverted;\n }\n\n if (this.fields && !this._matchField) {\n this._matchField = this._options.fieldMatcher!(this.fields);\n }\n\n return this._matchField!(field);\n }\n}\n","export interface LinkedItem<T> {\n next: LinkedItem<T> | null\n prev: LinkedItem<T> | null\n readonly value: T\n}\n\nexport function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']) {\n const item = { value, prev, next: null };\n\n if (prev) {\n prev.next = item;\n }\n\n return item;\n}\n\nexport function unlinkItem(item: LinkedItem<any>) {\n if (item.next) {\n item.next.prev = item.prev;\n }\n\n if (item.prev) {\n item.prev.next = item.next;\n }\n\n item.next = item.prev = null; // eslint-disable-line\n}\n\nexport const cloneLinkedItem = <T extends LinkedItem<any>>(item: T): T => ({\n value: item.value,\n prev: item.prev,\n next: item.next,\n} as T);\n","import { Rule, RuleOptions } from './Rule';\nimport { RawRuleFrom } from './RawRule';\nimport {\n Abilities,\n Normalize,\n SubjectType,\n AbilityParameters,\n AbilityTuple,\n ExtractSubjectType\n} from './types';\nimport { wrapArray, detectSubjectType, mergePrioritized, getOrDefault, identity, isSubjectType } from './utils';\nimport { LinkedItem, linkedItem, unlinkItem, cloneLinkedItem } from './structures/LinkedItem';\n\nexport interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {\n detectSubjectType?(\n subject: Exclude<Normalize<A>[1], SubjectType>\n ): ExtractSubjectType<Normalize<A>[1]>;\n anyAction?: string;\n anySubjectType?: string;\n}\n\ndeclare const $abilities: unique symbol;\ndeclare const $conditions: unique symbol;\ninterface WithGenerics {\n [$abilities]: any\n [$conditions]: any\n}\nexport type Public<T extends WithGenerics> = { [K in keyof T]: T[K] };\nexport interface Generics<T extends WithGenerics> {\n abilities: T[typeof $abilities],\n conditions: T[typeof $conditions]\n}\n\nexport type RuleOf<T extends WithGenerics> =\n Rule<Generics<T>['abilities'], Generics<T>['conditions']>;\nexport type RawRuleOf<T extends WithGenerics> =\n RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;\n\nexport type RuleIndexOptionsOf<T extends WithGenerics> =\n RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;\n\ninterface AbilityEvent<T extends WithGenerics> {\n target: T\n /** @deprecated use \"target\" property instead */\n ability: T\n}\n\nexport interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {\n rules: RawRuleOf<T>[]\n}\n/**\n * @deprecated `on`/`emit` properly infer type without this type\n * TODO(major): delete\n */\nexport type EventHandler<Event> = (event: Event) => void;\n\nexport type Events<\n T extends WithGenerics,\n K extends keyof EventsMap<T> = keyof EventsMap<T>\n> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;\n\ninterface EventsMap<T extends WithGenerics> {\n update(event: UpdateEvent<T>): void\n updated(event: UpdateEvent<T>): void\n}\n\ntype IndexTree<A extends Abilities, C> = Map<SubjectType, Map<string, {\n rules: Rule<A, C>[],\n merged: boolean\n}>>;\n\nexport type Unsubscribe = () => void;\n\nconst defaultActionEntry = () => ({\n rules: [] as unknown as Rule<any, any>[],\n merged: false\n});\nconst defaultSubjectEntry = () => new Map<string, ReturnType<typeof defaultActionEntry>>();\nconst analyze = (index: any, rule: Rule<any, any>) => {\n if (!index._hasPerFieldRules && rule.fields) {\n index._hasPerFieldRules = true;\n }\n};\n\ntype AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> =\n AbilityParameters<\n T,\n T extends AbilityTuple\n ? IncludeField extends true\n ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0\n : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0\n : never,\n (action: Extract<T, string>) => 0\n >;\n\nexport class RuleIndex<A extends Abilities, Conditions> {\n private _hasPerFieldRules: boolean = false;\n private _events: Events<this> = new Map();\n private _indexedRules!: IndexTree<A, Conditions>;\n private _rules!: RawRuleFrom<A, Conditions>[];\n private readonly _ruleOptions!: RuleOptions<Conditions>;\n private readonly _detectSubjectType!: Required<RuleIndexOptions<A, Conditions>>['detectSubjectType'];\n private readonly _anyAction: string;\n private readonly _anySubjectType: string;\n readonly [$abilities]!: A;\n readonly [$conditions]!: Conditions;\n\n constructor(\n rules: RawRuleFrom<A, Conditions>[] = [],\n options: RuleIndexOptions<A, Conditions> = {}\n ) {\n this._ruleOptions = {\n conditionsMatcher: options.conditionsMatcher,\n fieldMatcher: options.fieldMatcher,\n resolveAction: options.resolveAction || identity,\n };\n this._anyAction = options.anyAction || 'manage';\n this._anySubjectType = options.anySubjectType || 'all';\n this._detectSubjectType = options.detectSubjectType || detectSubjectType;\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n }\n\n get rules() {\n return this._rules;\n }\n\n detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]> {\n if (isSubjectType(object)) return object;\n if (!object) return this._anySubjectType;\n return this._detectSubjectType(object as Exclude<Normalize<A>[1], SubjectType>);\n }\n\n update(rules: RawRuleFrom<A, Conditions>[]): Public<this> {\n const event = {\n rules,\n ability: this,\n target: this\n } as unknown as UpdateEvent<this>;\n\n this._emit('update', event);\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n this._emit('updated', event);\n\n return this;\n }\n\n private _buildIndexFor(rawRules: RawRuleFrom<A, Conditions>[]) {\n const indexedRules: IndexTree<A, Conditions> = new Map();\n\n for (let i = rawRules.length - 1; i >= 0; i--) {\n const priority = rawRules.length - i - 1;\n const rule = new Rule(rawRules[i], this._ruleOptions, priority);\n const actions = wrapArray(rule.action);\n const subjects = wrapArray(rule.subject || this._anySubjectType);\n analyze(this, rule);\n\n for (let k = 0; k < subjects.length; k++) {\n const subjectRules = getOrDefault(indexedRules, subjects[k], defaultSubjectEntry);\n\n for (let j = 0; j < actions.length; j++) {\n getOrDefault(subjectRules, actions[j], defaultActionEntry).rules.push(rule);\n }\n }\n }\n\n return indexedRules;\n }\n\n possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[]\n possibleRulesFor(\n action: string,\n subjectType: SubjectType = this._anySubjectType\n ): Rule<A, Conditions>[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"possibleRulesFor\" accepts only subject types (i.e., string or class) as the 2nd parameter');\n }\n\n const subjectRules = getOrDefault(this._indexedRules, subjectType, defaultSubjectEntry);\n const actionRules = getOrDefault(subjectRules, action, defaultActionEntry);\n\n if (actionRules.merged) {\n return actionRules.rules;\n }\n\n const anyActionRules = action !== this._anyAction && subjectRules.has(this._anyAction)\n ? subjectRules.get(this._anyAction)!.rules\n : undefined;\n let rules = mergePrioritized(actionRules.rules, anyActionRules);\n\n if (subjectType !== this._anySubjectType) {\n rules = mergePrioritized(rules, (this as any).possibleRulesFor(action, this._anySubjectType));\n }\n\n actionRules.rules = rules;\n actionRules.merged = true;\n\n return rules;\n }\n\n rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[]\n rulesFor(action: string, subjectType?: SubjectType, field?: string): Rule<A, Conditions>[] {\n const rules: Rule<A, Conditions>[] = (this as any).possibleRulesFor(action, subjectType);\n\n if (field && typeof field !== 'string') {\n throw new Error('The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details');\n }\n\n if (!this._hasPerFieldRules) {\n return rules;\n }\n\n return rules.filter(rule => rule.matchesField(field));\n }\n\n on<T extends keyof EventsMap<this>>(\n event: T,\n handler: EventsMap<Public<this>>[T]\n ): Unsubscribe {\n const tail = this._events.get(event) || null;\n const item = linkedItem(handler, tail);\n this._events.set(event, item);\n\n return () => {\n const currentTail = this._events.get(event);\n\n if (!item.next && !item.prev && currentTail === item) {\n this._events.delete(event);\n } else if (item === currentTail) {\n this._events.set(event, item.prev);\n }\n\n unlinkItem(item);\n };\n }\n\n private _emit<T extends keyof EventsMap<this>>(\n name: T,\n payload: Parameters<EventsMap<this>[T]>[0]\n ) {\n let current = this._events.get(name) || null;\n while (current !== null) {\n const prev = current.prev ? cloneLinkedItem(current.prev) : null;\n current.value(payload);\n current = prev;\n }\n }\n}\n","import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';\nimport { Abilities, AbilityTuple, CanParameters, Subject } from './types';\nimport { Rule } from './Rule';\n\nexport interface AbilityOptions<A extends Abilities, Conditions>\n extends RuleIndexOptions<A, Conditions> {}\nexport interface AnyAbility extends Public<PureAbility<any, any>> {}\nexport interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {}\nexport type AbilityClass<T extends AnyAbility> = new (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport class PureAbility<\n A extends Abilities = AbilityTuple,\n Conditions = unknown\n> extends RuleIndex<A, Conditions> {\n can(...args: CanParameters<A>): boolean {\n const rule = this.relevantRuleFor(...args);\n return !!rule && !rule.inverted;\n }\n\n relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null {\n const subjectType = this.detectSubjectType(subject);\n const rules = (this as any).rulesFor(action, subjectType, field);\n\n for (let i = 0, length = rules.length; i < length; i++) {\n if (rules[i].matchesConditions(subject)) {\n return rules[i];\n }\n }\n\n return null;\n }\n\n cannot(...args: CanParameters<A>): boolean {\n return !this.can(...args);\n }\n}\n","import {\n $eq,\n eq,\n $ne,\n ne,\n $lt,\n lt,\n $lte,\n lte,\n $gt,\n gt,\n $gte,\n gte,\n $in,\n within,\n $nin,\n nin,\n $all,\n all,\n $size,\n size,\n $regex,\n $options,\n regex,\n $elemMatch,\n elemMatch,\n $exists,\n exists,\n and,\n createFactory,\n BuildMongoQuery,\n DefaultOperators,\n} from '@ucast/mongo2js';\nimport { ConditionsMatcher, AnyObject } from '../types';\nimport { Container, GenericFactory } from '../hkt';\n\nconst defaultInstructions = {\n $eq,\n $ne,\n $lt,\n $lte,\n $gt,\n $gte,\n $in,\n $nin,\n $all,\n $size,\n $regex,\n $options,\n $elemMatch,\n $exists,\n};\nconst defaultInterpreters = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n in: within,\n nin,\n all,\n size,\n regex,\n elemMatch,\n exists,\n and,\n};\n\ninterface MongoQueryFactory extends GenericFactory {\n produce: MongoQuery<this[0]>\n}\n\ntype MergeUnion<T extends {}, Keys extends keyof T = keyof T> = { [K in Keys]: T[K] };\nexport type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {\n toplevel: {},\n field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>\n}> & Container<MongoQueryFactory>;\n\ntype MongoQueryMatcherFactory =\n (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;\nexport const buildMongoQueryMatcher = ((instructions, interpreters, options) => createFactory(\n { ...defaultInstructions, ...instructions },\n { ...defaultInterpreters, ...interpreters },\n options\n)) as MongoQueryMatcherFactory;\n\nexport const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);\nexport type {\n MongoQueryFieldOperators,\n MongoQueryTopLevelOperators,\n MongoQueryOperators,\n} from '@ucast/mongo2js';\n","import { FieldMatcher } from '../types';\n\nconst REGEXP_SPECIAL_CHARS = /[-/\\\\^$+?.()|[\\]{}]/g;\nconst REGEXP_ANY = /\\.?\\*+\\.?/g;\nconst REGEXP_STARS = /\\*+/;\nconst REGEXP_DOT = /\\./g;\n\nfunction detectRegexpPattern(match: string, index: number, string: string): string {\n const quantifier = string[0] === '*' || match[0] === '.' && match[match.length - 1] === '.'\n ? '+'\n : '*';\n const matcher = match.indexOf('**') === -1 ? '[^.]' : '.';\n const pattern = match.replace(REGEXP_DOT, '\\\\$&')\n .replace(REGEXP_STARS, matcher + quantifier);\n\n return index + match.length === string.length ? `(?:${pattern})?` : pattern;\n}\n\nfunction escapeRegexp(match: string, index: number, string: string): string {\n if (match === '.' && (string[index - 1] === '*' || string[index + 1] === '*')) {\n return match;\n }\n\n return `\\\\${match}`;\n}\n\nfunction createPattern(fields: string[]) {\n const patterns = fields.map(field => field\n .replace(REGEXP_SPECIAL_CHARS, escapeRegexp)\n .replace(REGEXP_ANY, detectRegexpPattern));\n const pattern = patterns.length > 1 ? `(?:${patterns.join('|')})` : patterns[0];\n\n return new RegExp(`^${pattern}$`);\n}\n\nexport const fieldPatternMatcher: FieldMatcher = (fields) => {\n let pattern: RegExp | null;\n\n return (field) => {\n if (typeof pattern === 'undefined') {\n pattern = fields.every(f => f.indexOf('*') === -1)\n ? null\n : createPattern(fields);\n }\n\n return pattern === null\n ? fields.indexOf(field) !== -1\n : pattern.test(field);\n };\n};\n","import { PureAbility, AbilityOptions } from './PureAbility';\nimport { RawRuleFrom } from './RawRule';\nimport { AbilityTuple } from './types';\nimport { MongoQuery, mongoQueryMatcher } from './matchers/conditions';\nimport { fieldPatternMatcher } from './matchers/field';\nimport { Public } from './RuleIndex';\n\nexport class Ability<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {\n constructor(rules: RawRuleFrom<A, C>[] = [], options: AbilityOptions<A, C> = {}) {\n super(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n }\n}\n\nexport interface AnyMongoAbility extends Public<Ability<any, MongoQuery>> {}\n","import { Ability, AnyMongoAbility } from './Ability';\nimport { AnyAbility, AbilityOptionsOf, AbilityClass } from './PureAbility';\nimport { RawRuleOf, Generics } from './RuleIndex';\nimport {\n ExtractSubjectType as E,\n AbilityTuple,\n SubjectType,\n TaggedInterface,\n Normalize,\n AnyObject,\n AnyClass,\n} from './types';\nimport { ProduceGeneric } from './hkt';\n\nclass RuleBuilder<T extends AnyAbility> {\n public _rule!: RawRuleOf<T>;\n\n constructor(rule: RawRuleOf<T>) {\n this._rule = rule;\n }\n\n because(reason: string): this {\n this._rule.reason = reason;\n return this;\n }\n}\n\ntype InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R>\n ? R\n : S extends string\n ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string>\n ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>>\n : AnyObject\n : never;\ntype ConditionsOf<T extends AnyAbility, I extends {}> =\n ProduceGeneric<Generics<T>['conditions'], I>;\ntype ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any\n ? S extends T[1] ? T[0] : never\n : never;\ntype ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;\ntype SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;\n\ntype SimpleCanParams<T extends AnyAbility> = Parameters<(\n action: Generics<T>['abilities'] | Generics<T>['abilities'][]\n) => 0>;\ntype BuilderCanParameters<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\n\ntype BuilderCanParametersWithFields<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n F extends string,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n fields?: F | F[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\ntype Keys<T> = string & keyof T;\n\nexport class AbilityBuilder<T extends AnyAbility> {\n public rules: RawRuleOf<T>[] = [];\n private _AbilityType!: AnyClass<T>;\n\n constructor(AbilityType: AnyClass<T>) {\n this._AbilityType = AbilityType;\n this.can = this.can.bind(this as any);\n this.cannot = this.cannot.bind(this as any);\n this.build = this.build.bind(this as any);\n }\n\n can<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n can<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n can(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ): RuleBuilder<T> {\n const rule = { action } as RawRuleOf<T>;\n\n if (subject) {\n rule.subject = subject;\n\n if (Array.isArray(conditionsOrFields) || typeof conditionsOrFields === 'string') {\n rule.fields = conditionsOrFields;\n } else if (typeof conditionsOrFields !== 'undefined') {\n rule.conditions = conditionsOrFields;\n }\n\n if (typeof conditions !== 'undefined') {\n rule.conditions = conditions;\n }\n }\n\n this.rules.push(rule);\n\n return new RuleBuilder(rule);\n }\n\n cannot<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n cannot<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n cannot(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions'],\n ): RuleBuilder<T> {\n const builder = (this as any).can(action, subject, conditionsOrFields, conditions);\n builder._rule.inverted = true;\n return builder;\n }\n\n build(options?: AbilityOptionsOf<T>) {\n return new this._AbilityType(this.rules, options);\n }\n}\n\ntype DSL<T extends AnyAbility, R> = (\n can: AbilityBuilder<T>['can'],\n cannot: AbilityBuilder<T>['cannot']\n) => R;\n\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void | Promise<void>>, options?: AbilityOptionsOf<T>): T | Promise<T> {\n const builder = new AbilityBuilder(Ability as unknown as AbilityClass<T>);\n const result = define(builder.can, builder.cannot);\n\n if (result && typeof result.then === 'function') {\n return result.then(() => builder.build(options));\n }\n\n return builder.build(options);\n}\n","import { AnyAbility } from './PureAbility';\nimport { Normalize } from './types';\nimport { Generics } from './RuleIndex';\nimport { getSubjectTypeName } from './utils';\n\nexport type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;\nexport const getDefaultErrorMessage: GetErrorMessage = error => `Cannot execute \"${error.action}\" on \"${error.subjectType}\"`;\n\nconst NativeError = function NError(this: Error, message: string) {\n this.message = message;\n} as unknown as new (message: string) => Error;\n\nNativeError.prototype = Object.create(Error.prototype);\n\nexport class ForbiddenError<T extends AnyAbility> extends NativeError {\n public readonly ability!: T;\n public action!: Normalize<Generics<T>['abilities']>[0];\n public subject!: Generics<T>['abilities'][1];\n public field?: string;\n public subjectType!: string;\n\n static _defaultErrorMessage = getDefaultErrorMessage;\n\n static setDefaultMessage(messageOrFn: string | GetErrorMessage) {\n this._defaultErrorMessage = typeof messageOrFn === 'string' ? () => messageOrFn : messageOrFn;\n }\n\n static from<U extends AnyAbility>(ability: U) {\n return new this<U>(ability);\n }\n\n private constructor(ability: T) {\n super('');\n this.ability = ability;\n\n if (typeof Error.captureStackTrace === 'function') {\n this.name = 'ForbiddenError';\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n setMessage(message: string) {\n this.message = message;\n return this;\n }\n\n throwUnlessCan(...args: Parameters<T['can']>) {\n const rule = this.ability.relevantRuleFor(...args);\n\n if (rule && !rule.inverted) {\n return;\n }\n\n this.action = args[0];\n this.subject = args[1];\n this.subjectType = getSubjectTypeName(this.ability.detectSubjectType(args[1]));\n this.field = args[2];\n\n const reason = rule ? rule.reason : '';\n // eslint-disable-next-line no-underscore-dangle\n this.message = this.message || reason || (this.constructor as any)._defaultErrorMessage(this);\n throw this; // eslint-disable-line\n }\n}\n"],"names":["wrapArray","value","Array","isArray","TYPE_FIELD","setSubjectType","type","object","hasOwnProperty","Object","defineProperty","Error","isSubjectType","getSubjectClassName","modelName","name","getSubjectTypeName","detectSubjectType","subject","constructor","expandActions","aliasMap","rawActions","merge","actions","i","length","action","findDuplicate","actionToFind","indexOf","defaultAliasMerge","concat","validateForCycles","reservedAction","keys","mergeAliasesAndDetectCycles","duplicate","join","isUsingReservedAction","createAliasResolver","options","skipValidate","anyAction","copyArrayTo","dest","target","start","push","mergePrioritized","array","anotherArray","j","merged","priority","getOrDefault","map","key","defaultValue","get","set","identity","x","validate","rule","fields","fieldMatcher","conditions","conditionsMatcher","Rule","resolveAction","inverted","reason","undefined","_options","_conditionsMatcher","this","_matchConditions","matches","ast","matchesConditions","matchesField","field","_matchField","linkedItem","prev","item","next","unlinkItem","cloneLinkedItem","defaultActionEntry","rules","defaultSubjectEntry","Map","analyze","index","_hasPerFieldRules","RuleIndex","_events","_ruleOptions","_anyAction","_anySubjectType","anySubjectType","_detectSubjectType","_rules","_indexedRules","_buildIndexFor","update","event","ability","_emit","rawRules","indexedRules","subjects","k","subjectRules","possibleRulesFor","subjectType","actionRules","anyActionRules","has","rulesFor","filter","on","handler","tail","currentTail","delete","payload","current","PureAbility","can","args","relevantRuleFor","cannot","defaultInstructions","$eq","$ne","$lt","$lte","$gt","$gte","$in","$nin","$all","$size","$regex","$options","$elemMatch","$exists","defaultInterpreters","eq","ne","lt","lte","gt","gte","in","within","nin","all","size","regex","elemMatch","exists","and","buildMongoQueryMatcher","instructions","interpreters","createFactory","mongoQueryMatcher","REGEXP_SPECIAL_CHARS","REGEXP_ANY","REGEXP_STARS","REGEXP_DOT","detectRegexpPattern","match","string","quantifier","matcher","pattern","replace","escapeRegexp","createPattern","patterns","RegExp","fieldPatternMatcher","every","f","test","Ability","RuleBuilder","_rule","because","AbilityBuilder","AbilityType","_AbilityType","bind","build","conditionsOrFields","builder","defineAbility","define","result","then","getDefaultErrorMessage","error","NativeError","NError","message","prototype","create","ForbiddenError","messageOrFn","_defaultErrorMessage","captureStackTrace","setMessage","throwUnlessCan"],"mappings":"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"}

@@ -1,2 +0,2 @@

(function(t,r){"object"===typeof exports&&"undefined"!==typeof module?r(exports,require("@ucast/mongo2js")):"function"===typeof define&&define.amd?define(["exports","@ucast/mongo2js"],r):(t="undefined"!==typeof globalThis?globalThis:t||self,r(t.casl={},t.ucast.mongo2js))})(this,(function(t,r){"use strict";function i(t,r){for(var i=0;i<r.length;i++){var n=r[i];n.enumerable=n.enumerable||false;n.configurable=true;if("value"in n)n.writable=true;Object.defineProperty(t,n.key,n)}}function n(t,r,n){if(r)i(t.prototype,r);if(n)i(t,n);return t}function e(){e=Object.assign||function(t){for(var r=1;r<arguments.length;r++){var i=arguments[r];for(var n in i)if(Object.prototype.hasOwnProperty.call(i,n))t[n]=i[n]}return t};return e.apply(this,arguments)}function u(t,r){t.prototype=Object.create(r.prototype);t.prototype.constructor=t;o(t,r)}function o(t,r){o=Object.setPrototypeOf||function t(r,i){r.__proto__=i;return r};return o(t,r)}function s(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function f(t){return Array.isArray(t)?t:[t]}var a="__caslSubjectType__";function c(t,r){if(r)if(!r.hasOwnProperty(a))Object.defineProperty(r,a,{value:t});else if(t!==r[a])throw new Error("Trying to cast object to subject type "+t+" but previously it was casted to "+r[a]);return r}var h=function t(r){var i=typeof r;return"string"===i||"function"===i};var v=function t(r){return r.modelName||r.name};var l=function t(r){return"string"===typeof r?r:v(r)};function d(t){if(t.hasOwnProperty(a))return t[a];return v(t.constructor)}function b(t,r,i){var n=f(r);var e=0;while(e<n.length){var u=n[e++];if(t.hasOwnProperty(u))n=i(n,t[u])}return n}function y(t,r){if("string"===typeof r&&-1!==t.indexOf(r))return r;for(var i=0;i<r.length;i++)if(-1!==t.indexOf(r[i]))return r[i];return null}var p=function t(r,i){return r.concat(i)};function w(t,r){if(r in t)throw new Error('Cannot use "'+r+"\" as an alias because it's reserved action.");var i=Object.keys(t);var n=function t(i,n){var e=y(i,n);if(e)throw new Error("Detected cycle "+e+" -> "+i.join(", "));var u="string"===typeof n&&n===r||-1!==i.indexOf(r)||Array.isArray(n)&&-1!==n.indexOf(r);if(u)throw new Error('Cannot make an alias to "'+r+'" because this is reserved action');return i.concat(n)};for(var e=0;e<i.length;e++)b(t,i[e],n)}function g(t,r){if(!r||false!==r.skipValidate)w(t,r&&r.anyAction||"manage");return function(r){return b(t,r,p)}}function E(t,r,i){for(var n=i;n<r.length;n++)t.push(r[n])}function j(t,r){if(!t||!t.length)return r||[];if(!r||!r.length)return t||[];var i=0;var n=0;var e=[];while(i<t.length&&n<r.length)if(t[i].priority<r[n].priority){e.push(t[i]);i++}else{e.push(r[n]);n++}E(e,t,i);E(e,r,n);return e}function A(t,r,i){var n=t.get(r);if(!n){n=i();t.set(r,n)}return n}var $=function t(r){return r};function m(t,r){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!r.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!r.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}var x=function(){function t(t,r,i){if(void 0===i)i=0;m(t,r);this.action=r.resolveAction(t.action);this.subject=t.subject;this.inverted=!!t.inverted;this.conditions=t.conditions;this.reason=t.reason;this.fields=t.fields?f(t.fields):void 0;this.priority=i;this.t=r}var r=t.prototype;r.i=function t(){if(this.conditions&&!this.u)this.u=this.t.conditionsMatcher(this.conditions);return this.u};r.matchesConditions=function t(r){if(!this.conditions)return true;if(!r||h(r))return!this.inverted;var i=this.i();return i(r)};r.matchesField=function t(r){if(!this.fields)return true;if(!r)return!this.inverted;if(this.fields&&!this.o)this.o=this.t.fieldMatcher(this.fields);return this.o(r)};n(t,[{key:"ast",get:function t(){var r=this.i();return r?r.ast:void 0}}]);return t}();function M(t,r){var i={value:t,prev:r,next:null};if(r)r.next=i;return i}function O(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}var _=function t(r){return{value:r.value,prev:r.prev,next:r.next}};var F=function t(){return{rules:[],merged:false}};var T=function t(){return new Map};var P=function t(r,i){if(!r.h&&i.fields)r.h=true};var R=function(){function t(t,r){if(void 0===t)t=[];if(void 0===r)r={};this.h=false;this.v=new Map;this.l={conditionsMatcher:r.conditionsMatcher,fieldMatcher:r.fieldMatcher,resolveAction:r.resolveAction||$};this.p=r.anyAction||"manage";this.g=r.anySubjectType||"all";this.j=r.detectSubjectType||d;this.A=t;this.$=this.m(t)}var r=t.prototype;r.detectSubjectType=function t(r){if(h(r))return r;if(!r)return this.g;return this.j(r)};r.update=function t(r){var i={rules:r,ability:this,target:this};this.M("update",i);this.A=r;this.$=this.m(r);this.M("updated",i);return this};r.m=function t(r){var i=new Map;for(var n=r.length-1;n>=0;n--){var e=r.length-n-1;var u=new x(r[n],this.l,e);var o=f(u.action);var s=f(u.subject||this.g);P(this,u);for(var a=0;a<s.length;a++){var c=A(i,s[a],T);for(var h=0;h<o.length;h++)A(c,o[h],F).rules.push(u)}}return i};r.possibleRulesFor=function t(r,i){if(void 0===i)i=this.g;if(!h(i))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');var n=A(this.$,i,T);var e=A(n,r,F);if(e.merged)return e.rules;var u=r!==this.p&&n.has(this.p)?n.get(this.p).rules:void 0;var o=j(e.rules,u);if(i!==this.g)o=j(o,this.possibleRulesFor(r,this.g));e.rules=o;e.merged=true;return o};r.rulesFor=function t(r,i,n){var e=this.possibleRulesFor(r,i);if(n&&"string"!==typeof n)throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");if(!this.h)return e;return e.filter((function(t){return t.matchesField(n)}))};r.on=function t(r,i){var n=this;var e=this.v.get(r)||null;var u=M(i,e);this.v.set(r,u);return function(){if(!u.next&&!u.prev&&n.v.get(r)===u)n.v.delete(r);else O(u)}};r.M=function t(r,i){var n=this.v.get(r)||null;while(null!==n){var e=n.prev?_(n.prev):null;n.value(i);n=e}};n(t,[{key:"rules",get:function t(){return this.A}}]);return t}();var k=function(t){u(PureAbility,t);function PureAbility(){return t.apply(this,arguments)||this}var r=PureAbility.prototype;r.can=function t(){var r=this.relevantRuleFor.apply(this,arguments);return!!r&&!r.inverted};r.relevantRuleFor=function t(r,i,n){var e=this.detectSubjectType(i);var u=this.rulesFor(r,e,n);for(var o=0,s=u.length;o<s;o++)if(u[o].matchesConditions(i))return u[o];return null};r.cannot=function t(){return!this.can.apply(this,arguments)};return PureAbility}(R);var q={$eq:r.$eq,$ne:r.$ne,$lt:r.$lt,$lte:r.$lte,$gt:r.$gt,$gte:r.$gte,$in:r.$in,$nin:r.$nin,$all:r.$all,$size:r.$size,$regex:r.$regex,$options:r.$options,$elemMatch:r.$elemMatch,$exists:r.$exists};var B={eq:r.eq,ne:r.ne,lt:r.lt,lte:r.lte,gt:r.gt,gte:r.gte,in:r.within,nin:r.nin,all:r.all,size:r.size,regex:r.regex,elemMatch:r.elemMatch,exists:r.exists,and:r.and};var C=function t(i,n,u){return r.createFactory(e({},q,i),e({},B,n),u)};var z=r.createFactory(q,B);var S=/[-/\\^$+?.()|[\]{}]/g;var Y=/\.?\*+\.?/g;var D=/\*+/;var L=/\./g;function G(t,r,i){var n="*"===i[0]||"."===t[0]&&"."===t[t.length-1]?"+":"*";var e=-1===t.indexOf("**")?"[^.]":".";var u=t.replace(L,"\\$&").replace(D,e+n);return r+t.length===i.length?"(?:"+u+")?":u}function H(t,r,i){if("."===t&&("*"===i[r-1]||"*"===i[r+1]))return t;return"\\"+t}function I(t){var r=t.map((function(t){return t.replace(S,H).replace(Y,G)}));var i=r.length>1?"(?:"+r.join("|")+")":r[0];return new RegExp("^"+i+"$")}var J=function t(r){var i;return function(t){if("undefined"===typeof i)i=r.every((function(t){return-1===t.indexOf("*")}))?null:I(r);return null===i?-1!==r.indexOf(t):i.test(t)}};var K=function(t){u(Ability,t);function Ability(r,i){if(void 0===r)r=[];if(void 0===i)i={};return t.call(this,r,e({conditionsMatcher:z,fieldMatcher:J},i))||this}return Ability}(k);var N=function(){function t(t){this.O=t}var r=t.prototype;r.because=function t(r){this.O.reason=r;return this};return t}();var Q=function(){function AbilityBuilder(t){this.rules=[];this._=t;this.can=this.can.bind(this);this.cannot=this.cannot.bind(this);this.build=this.build.bind(this)}var t=AbilityBuilder.prototype;t.can=function t(r,i,n,e){var u={action:r};if(i){u.subject=i;if(Array.isArray(n)||"string"===typeof n)u.fields=n;else if("undefined"!==typeof n)u.conditions=n;if("undefined"!==typeof e)u.conditions=e}this.rules.push(u);return new N(u)};t.cannot=function t(r,i,n,e){var u=this.can(r,i,n,e);u.O.inverted=true;return u};t.build=function t(r){return new this._(this.rules,r)};return AbilityBuilder}();function defineAbility(t,r){var i=new Q(K);var n=t(i.can,i.cannot);if(n&&"function"===typeof n.then)return n.then((function(){return i.build(r)}));return i.build(r)}var U=function t(r){return'Cannot execute "'+r.action+'" on "'+r.subjectType+'"'};var V=function t(r){this.message=r};V.prototype=Object.create(Error.prototype);var W=function(t){u(ForbiddenError,t);ForbiddenError.setDefaultMessage=function t(r){this.F="string"===typeof r?function(){return r}:r};ForbiddenError.from=function t(r){return new this(r)};function ForbiddenError(r){var i;i=t.call(this,"")||this;i.ability=r;if("function"===typeof Error.captureStackTrace){i.name="ForbiddenError";Error.captureStackTrace(s(i),i.constructor)}return i}var r=ForbiddenError.prototype;r.setMessage=function t(r){this.message=r;return this};r.throwUnlessCan=function t(){var r;var i=(r=this.ability).relevantRuleFor.apply(r,arguments);if(i&&!i.inverted)return;this.action=arguments.length<=0?void 0:arguments[0];this.subject=arguments.length<=1?void 0:arguments[1];this.subjectType=l(this.ability.detectSubjectType(arguments.length<=1?void 0:arguments[1]));this.field=arguments.length<=2?void 0:arguments[2];var n=i?i.reason:"";this.message=this.message||n||this.constructor.F(this);throw this};return ForbiddenError}(V);W.F=U;var X=Object.freeze({__proto__:null});t.Ability=K;t.AbilityBuilder=Q;t.ForbiddenError=W;t.PureAbility=k;t.buildMongoQueryMatcher=C;t.createAliasResolver=g;t.defineAbility=defineAbility;t.detectSubjectType=d;t.fieldPatternMatcher=J;t.getDefaultErrorMessage=U;t.hkt=X;t.mongoQueryMatcher=z;t.subject=c;t.wrapArray=f;Object.defineProperty(t,"__esModule",{value:true})}));
(function(t,r){"object"===typeof exports&&"undefined"!==typeof module?r(exports,require("@ucast/mongo2js")):"function"===typeof define&&define.amd?define(["exports","@ucast/mongo2js"],r):(t="undefined"!==typeof globalThis?globalThis:t||self,r(t.casl={},t.ucast.mongo2js))})(this,(function(t,r){"use strict";function i(t,r){for(var i=0;i<r.length;i++){var n=r[i];n.enumerable=n.enumerable||false;n.configurable=true;if("value"in n)n.writable=true;Object.defineProperty(t,n.key,n)}}function n(t,r,n){if(r)i(t.prototype,r);if(n)i(t,n);return t}function e(){e=Object.assign||function(t){for(var r=1;r<arguments.length;r++){var i=arguments[r];for(var n in i)if(Object.prototype.hasOwnProperty.call(i,n))t[n]=i[n]}return t};return e.apply(this,arguments)}function u(t,r){t.prototype=Object.create(r.prototype);t.prototype.constructor=t;o(t,r)}function o(t,r){o=Object.setPrototypeOf||function t(r,i){r.__proto__=i;return r};return o(t,r)}function s(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function f(t){return Array.isArray(t)?t:[t]}var a="__caslSubjectType__";function c(t,r){if(r)if(!r.hasOwnProperty(a))Object.defineProperty(r,a,{value:t});else if(t!==r[a])throw new Error("Trying to cast object to subject type "+t+" but previously it was casted to "+r[a]);return r}var h=function t(r){var i=typeof r;return"string"===i||"function"===i};var v=function t(r){return r.modelName||r.name};var l=function t(r){return"string"===typeof r?r:v(r)};function d(t){if(t.hasOwnProperty(a))return t[a];return v(t.constructor)}function b(t,r,i){var n=f(r);var e=0;while(e<n.length){var u=n[e++];if(t.hasOwnProperty(u))n=i(n,t[u])}return n}function y(t,r){if("string"===typeof r&&-1!==t.indexOf(r))return r;for(var i=0;i<r.length;i++)if(-1!==t.indexOf(r[i]))return r[i];return null}var p=function t(r,i){return r.concat(i)};function w(t,r){if(r in t)throw new Error('Cannot use "'+r+"\" as an alias because it's reserved action.");var i=Object.keys(t);var n=function t(i,n){var e=y(i,n);if(e)throw new Error("Detected cycle "+e+" -> "+i.join(", "));var u="string"===typeof n&&n===r||-1!==i.indexOf(r)||Array.isArray(n)&&-1!==n.indexOf(r);if(u)throw new Error('Cannot make an alias to "'+r+'" because this is reserved action');return i.concat(n)};for(var e=0;e<i.length;e++)b(t,i[e],n)}function g(t,r){if(!r||false!==r.skipValidate)w(t,r&&r.anyAction||"manage");return function(r){return b(t,r,p)}}function E(t,r,i){for(var n=i;n<r.length;n++)t.push(r[n])}function j(t,r){if(!t||!t.length)return r||[];if(!r||!r.length)return t||[];var i=0;var n=0;var e=[];while(i<t.length&&n<r.length)if(t[i].priority<r[n].priority){e.push(t[i]);i++}else{e.push(r[n]);n++}E(e,t,i);E(e,r,n);return e}function A(t,r,i){var n=t.get(r);if(!n){n=i();t.set(r,n)}return n}var $=function t(r){return r};function m(t,r){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!r.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!r.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}var x=function(){function t(t,r,i){if(void 0===i)i=0;m(t,r);this.action=r.resolveAction(t.action);this.subject=t.subject;this.inverted=!!t.inverted;this.conditions=t.conditions;this.reason=t.reason;this.fields=t.fields?f(t.fields):void 0;this.priority=i;this.t=r}var r=t.prototype;r.i=function t(){if(this.conditions&&!this.u)this.u=this.t.conditionsMatcher(this.conditions);return this.u};r.matchesConditions=function t(r){if(!this.conditions)return true;if(!r||h(r))return!this.inverted;var i=this.i();return i(r)};r.matchesField=function t(r){if(!this.fields)return true;if(!r)return!this.inverted;if(this.fields&&!this.o)this.o=this.t.fieldMatcher(this.fields);return this.o(r)};n(t,[{key:"ast",get:function t(){var r=this.i();return r?r.ast:void 0}}]);return t}();function M(t,r){var i={value:t,prev:r,next:null};if(r)r.next=i;return i}function O(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}var _=function t(r){return{value:r.value,prev:r.prev,next:r.next}};var F=function t(){return{rules:[],merged:false}};var T=function t(){return new Map};var P=function t(r,i){if(!r.h&&i.fields)r.h=true};var R=function(){function t(t,r){if(void 0===t)t=[];if(void 0===r)r={};this.h=false;this.v=new Map;this.l={conditionsMatcher:r.conditionsMatcher,fieldMatcher:r.fieldMatcher,resolveAction:r.resolveAction||$};this.p=r.anyAction||"manage";this.g=r.anySubjectType||"all";this.j=r.detectSubjectType||d;this.A=t;this.$=this.m(t)}var r=t.prototype;r.detectSubjectType=function t(r){if(h(r))return r;if(!r)return this.g;return this.j(r)};r.update=function t(r){var i={rules:r,ability:this,target:this};this.M("update",i);this.A=r;this.$=this.m(r);this.M("updated",i);return this};r.m=function t(r){var i=new Map;for(var n=r.length-1;n>=0;n--){var e=r.length-n-1;var u=new x(r[n],this.l,e);var o=f(u.action);var s=f(u.subject||this.g);P(this,u);for(var a=0;a<s.length;a++){var c=A(i,s[a],T);for(var h=0;h<o.length;h++)A(c,o[h],F).rules.push(u)}}return i};r.possibleRulesFor=function t(r,i){if(void 0===i)i=this.g;if(!h(i))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');var n=A(this.$,i,T);var e=A(n,r,F);if(e.merged)return e.rules;var u=r!==this.p&&n.has(this.p)?n.get(this.p).rules:void 0;var o=j(e.rules,u);if(i!==this.g)o=j(o,this.possibleRulesFor(r,this.g));e.rules=o;e.merged=true;return o};r.rulesFor=function t(r,i,n){var e=this.possibleRulesFor(r,i);if(n&&"string"!==typeof n)throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");if(!this.h)return e;return e.filter((function(t){return t.matchesField(n)}))};r.on=function t(r,i){var n=this;var e=this.v.get(r)||null;var u=M(i,e);this.v.set(r,u);return function(){var t=n.v.get(r);if(!u.next&&!u.prev&&t===u)n.v.delete(r);else if(u===t)n.v.set(r,u.prev);O(u)}};r.M=function t(r,i){var n=this.v.get(r)||null;while(null!==n){var e=n.prev?_(n.prev):null;n.value(i);n=e}};n(t,[{key:"rules",get:function t(){return this.A}}]);return t}();var k=function(t){u(PureAbility,t);function PureAbility(){return t.apply(this,arguments)||this}var r=PureAbility.prototype;r.can=function t(){var r=this.relevantRuleFor.apply(this,arguments);return!!r&&!r.inverted};r.relevantRuleFor=function t(r,i,n){var e=this.detectSubjectType(i);var u=this.rulesFor(r,e,n);for(var o=0,s=u.length;o<s;o++)if(u[o].matchesConditions(i))return u[o];return null};r.cannot=function t(){return!this.can.apply(this,arguments)};return PureAbility}(R);var q={$eq:r.$eq,$ne:r.$ne,$lt:r.$lt,$lte:r.$lte,$gt:r.$gt,$gte:r.$gte,$in:r.$in,$nin:r.$nin,$all:r.$all,$size:r.$size,$regex:r.$regex,$options:r.$options,$elemMatch:r.$elemMatch,$exists:r.$exists};var B={eq:r.eq,ne:r.ne,lt:r.lt,lte:r.lte,gt:r.gt,gte:r.gte,in:r.within,nin:r.nin,all:r.all,size:r.size,regex:r.regex,elemMatch:r.elemMatch,exists:r.exists,and:r.and};var C=function t(i,n,u){return r.createFactory(e({},q,i),e({},B,n),u)};var z=r.createFactory(q,B);var S=/[-/\\^$+?.()|[\]{}]/g;var Y=/\.?\*+\.?/g;var D=/\*+/;var L=/\./g;function G(t,r,i){var n="*"===i[0]||"."===t[0]&&"."===t[t.length-1]?"+":"*";var e=-1===t.indexOf("**")?"[^.]":".";var u=t.replace(L,"\\$&").replace(D,e+n);return r+t.length===i.length?"(?:"+u+")?":u}function H(t,r,i){if("."===t&&("*"===i[r-1]||"*"===i[r+1]))return t;return"\\"+t}function I(t){var r=t.map((function(t){return t.replace(S,H).replace(Y,G)}));var i=r.length>1?"(?:"+r.join("|")+")":r[0];return new RegExp("^"+i+"$")}var J=function t(r){var i;return function(t){if("undefined"===typeof i)i=r.every((function(t){return-1===t.indexOf("*")}))?null:I(r);return null===i?-1!==r.indexOf(t):i.test(t)}};var K=function(t){u(Ability,t);function Ability(r,i){if(void 0===r)r=[];if(void 0===i)i={};return t.call(this,r,e({conditionsMatcher:z,fieldMatcher:J},i))||this}return Ability}(k);var N=function(){function t(t){this.O=t}var r=t.prototype;r.because=function t(r){this.O.reason=r;return this};return t}();var Q=function(){function AbilityBuilder(t){this.rules=[];this._=t;this.can=this.can.bind(this);this.cannot=this.cannot.bind(this);this.build=this.build.bind(this)}var t=AbilityBuilder.prototype;t.can=function t(r,i,n,e){var u={action:r};if(i){u.subject=i;if(Array.isArray(n)||"string"===typeof n)u.fields=n;else if("undefined"!==typeof n)u.conditions=n;if("undefined"!==typeof e)u.conditions=e}this.rules.push(u);return new N(u)};t.cannot=function t(r,i,n,e){var u=this.can(r,i,n,e);u.O.inverted=true;return u};t.build=function t(r){return new this._(this.rules,r)};return AbilityBuilder}();function defineAbility(t,r){var i=new Q(K);var n=t(i.can,i.cannot);if(n&&"function"===typeof n.then)return n.then((function(){return i.build(r)}));return i.build(r)}var U=function t(r){return'Cannot execute "'+r.action+'" on "'+r.subjectType+'"'};var V=function t(r){this.message=r};V.prototype=Object.create(Error.prototype);var W=function(t){u(ForbiddenError,t);ForbiddenError.setDefaultMessage=function t(r){this.F="string"===typeof r?function(){return r}:r};ForbiddenError.from=function t(r){return new this(r)};function ForbiddenError(r){var i;i=t.call(this,"")||this;i.ability=r;if("function"===typeof Error.captureStackTrace){i.name="ForbiddenError";Error.captureStackTrace(s(i),i.constructor)}return i}var r=ForbiddenError.prototype;r.setMessage=function t(r){this.message=r;return this};r.throwUnlessCan=function t(){var r;var i=(r=this.ability).relevantRuleFor.apply(r,arguments);if(i&&!i.inverted)return;this.action=arguments.length<=0?void 0:arguments[0];this.subject=arguments.length<=1?void 0:arguments[1];this.subjectType=l(this.ability.detectSubjectType(arguments.length<=1?void 0:arguments[1]));this.field=arguments.length<=2?void 0:arguments[2];var n=i?i.reason:"";this.message=this.message||n||this.constructor.F(this);throw this};return ForbiddenError}(V);W.F=U;var X=Object.freeze({__proto__:null});t.Ability=K;t.AbilityBuilder=Q;t.ForbiddenError=W;t.PureAbility=k;t.buildMongoQueryMatcher=C;t.createAliasResolver=g;t.defineAbility=defineAbility;t.detectSubjectType=d;t.fieldPatternMatcher=J;t.getDefaultErrorMessage=U;t.hkt=X;t.mongoQueryMatcher=z;t.subject=c;t.wrapArray=f;Object.defineProperty(t,"__esModule",{value:true})}));
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../../src/utils.ts","../../src/Rule.ts","../../src/structures/LinkedItem.ts","../../src/RuleIndex.ts","../../src/PureAbility.ts","../../src/matchers/conditions.ts","../../src/matchers/field.ts","../../src/Ability.ts","../../src/AbilityBuilder.ts","../../src/ForbiddenError.ts"],"sourcesContent":["import { AnyObject, Subject, SubjectType, SubjectClass, ForcedSubject, AliasesMap } from './types';\n\nexport function wrapArray<T>(value: T[] | T): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function setByPath(object: AnyObject, path: string, value: unknown): void {\n let ref = object;\n let lastKey = path;\n\n if (path.indexOf('.') !== -1) {\n const keys = path.split('.');\n\n lastKey = keys.pop()!;\n ref = keys.reduce((res, prop) => {\n res[prop] = res[prop] || {};\n return res[prop] as AnyObject;\n }, object);\n }\n\n ref[lastKey] = value;\n}\n\nconst TYPE_FIELD = '__caslSubjectType__';\nexport function setSubjectType<\n T extends string,\n U extends Record<PropertyKey, any>\n>(type: T, object: U): U & ForcedSubject<T> {\n if (object) {\n if (!object.hasOwnProperty(TYPE_FIELD)) {\n Object.defineProperty(object, TYPE_FIELD, { value: type });\n } else if (type !== object[TYPE_FIELD]) {\n throw new Error(`Trying to cast object to subject type ${type} but previously it was casted to ${object[TYPE_FIELD]}`);\n }\n }\n\n return object as U & ForcedSubject<T>;\n}\n\nexport const isSubjectType = (value: unknown): value is SubjectType => {\n const type = typeof value;\n return type === 'string' || type === 'function';\n};\n\nconst getSubjectClassName = (value: SubjectClass) => value.modelName || value.name;\nexport const getSubjectTypeName = (value: SubjectType) => {\n return typeof value === 'string' ? value : getSubjectClassName(value);\n};\n\nexport function detectSubjectType(subject: Exclude<Subject, SubjectType>): string {\n if (subject.hasOwnProperty(TYPE_FIELD)) {\n return (subject as any)[TYPE_FIELD];\n }\n\n return getSubjectClassName(subject.constructor as SubjectClass);\n}\n\ntype AliasMerge = (actions: string[], action: string | string[]) => string[];\nfunction expandActions(aliasMap: AliasesMap, rawActions: string | string[], merge: AliasMerge) {\n let actions = wrapArray(rawActions);\n let i = 0;\n\n while (i < actions.length) {\n const action = actions[i++];\n\n if (aliasMap.hasOwnProperty(action)) {\n actions = merge(actions, aliasMap[action]);\n }\n }\n\n return actions;\n}\n\nfunction findDuplicate(actions: string[], actionToFind: string | string[]) {\n if (typeof actionToFind === 'string' && actions.indexOf(actionToFind) !== -1) {\n return actionToFind;\n }\n\n for (let i = 0; i < actionToFind.length; i++) {\n if (actions.indexOf(actionToFind[i]) !== -1) return actionToFind[i];\n }\n\n return null;\n}\n\nconst defaultAliasMerge: AliasMerge = (actions, action) => actions.concat(action);\nfunction validateForCycles(aliasMap: AliasesMap, reservedAction: string) {\n if (reservedAction in aliasMap) {\n throw new Error(`Cannot use \"${reservedAction}\" as an alias because it's reserved action.`);\n }\n\n const keys = Object.keys(aliasMap);\n const mergeAliasesAndDetectCycles: AliasMerge = (actions, action) => {\n const duplicate = findDuplicate(actions, action);\n if (duplicate) throw new Error(`Detected cycle ${duplicate} -> ${actions.join(', ')}`);\n\n const isUsingReservedAction = typeof action === 'string' && action === reservedAction\n || actions.indexOf(reservedAction) !== -1\n || Array.isArray(action) && action.indexOf(reservedAction) !== -1;\n if (isUsingReservedAction) throw new Error(`Cannot make an alias to \"${reservedAction}\" because this is reserved action`);\n\n return actions.concat(action);\n };\n\n for (let i = 0; i < keys.length; i++) {\n expandActions(aliasMap, keys[i], mergeAliasesAndDetectCycles);\n }\n}\n\nexport type AliasResolverOptions = { skipValidate?: boolean; anyAction?: string };\nexport function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions) {\n if (!options || options.skipValidate !== false) {\n validateForCycles(aliasMap, options && options.anyAction || 'manage');\n }\n\n return (action: string | string[]) => expandActions(aliasMap, action, defaultAliasMerge);\n}\n\nfunction copyArrayTo<T>(dest: T[], target: T[], start: number) {\n for (let i = start; i < target.length; i++) {\n dest.push(target[i]);\n }\n}\n\nexport function mergePrioritized<T extends { priority: number }>(\n array?: T[],\n anotherArray?: T[]\n): T[] {\n if (!array || !array.length) {\n return anotherArray || [];\n }\n\n if (!anotherArray || !anotherArray.length) {\n return array || [];\n }\n\n let i = 0;\n let j = 0;\n const merged: T[] = [];\n\n while (i < array.length && j < anotherArray.length) {\n if (array[i].priority < anotherArray[j].priority) {\n merged.push(array[i]);\n i++;\n } else {\n merged.push(anotherArray[j]);\n j++;\n }\n }\n\n copyArrayTo(merged, array, i);\n copyArrayTo(merged, anotherArray, j);\n\n return merged;\n}\n\nexport function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V) {\n let value = map.get(key);\n\n if (!value) {\n value = defaultValue();\n map.set(key, value);\n }\n\n return value;\n}\n\nexport const identity = <T>(x: T) => x;\n","import { wrapArray, isSubjectType } from './utils';\nimport {\n MatchConditions,\n MatchField,\n Abilities,\n ToAbilityTypes,\n Normalize,\n ConditionsMatcher,\n FieldMatcher,\n} from './types';\nimport { RawRule, RawRuleFrom } from './RawRule';\n\ntype Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;\n\nfunction validate(rule: RawRuleFrom<Abilities, any>, options: RuleOptions<any>) {\n if (Array.isArray(rule.fields) && !rule.fields.length) {\n throw new Error('`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa');\n }\n\n if (rule.fields && !options.fieldMatcher) {\n throw new Error('You need to pass \"fieldMatcher\" option in order to restrict access by fields');\n }\n\n if (rule.conditions && !options.conditionsMatcher) {\n throw new Error('You need to pass \"conditionsMatcher\" option in order to restrict access by conditions');\n }\n}\n\nexport interface RuleOptions<Conditions> {\n conditionsMatcher?: ConditionsMatcher<Conditions>\n fieldMatcher?: FieldMatcher\n resolveAction(action: string | string[]): string | string[]\n}\n\nexport class Rule<A extends Abilities, C> {\n private _matchConditions: MatchConditions | undefined;\n private _matchField: MatchField<string> | undefined;\n private readonly _options!: RuleOptions<C>;\n public readonly action!: Tuple<A>[0] | Tuple<A>[0][];\n public readonly subject!: Tuple<A>[1] | Tuple<A>[1][];\n public readonly inverted!: boolean;\n public readonly conditions!: C | undefined;\n public readonly fields!: string[] | undefined;\n public readonly reason!: string | undefined;\n public readonly priority!: number;\n\n constructor(\n rule: RawRule<ToAbilityTypes<A>, C>,\n options: RuleOptions<C>,\n priority: number = 0\n ) {\n validate(rule, options);\n\n this.action = options.resolveAction(rule.action);\n this.subject = rule.subject!;\n this.inverted = !!rule.inverted;\n this.conditions = rule.conditions;\n this.reason = rule.reason;\n this.fields = rule.fields ? wrapArray(rule.fields) : undefined;\n this.priority = priority;\n this._options = options;\n }\n\n private _conditionsMatcher() {\n if (this.conditions && !this._matchConditions) {\n this._matchConditions = this._options.conditionsMatcher!(this.conditions);\n }\n\n return this._matchConditions!;\n }\n\n get ast() {\n const matches = this._conditionsMatcher();\n return matches ? matches.ast : undefined;\n }\n\n matchesConditions(object: Normalize<A>[1] | undefined): boolean {\n if (!this.conditions) {\n return true;\n }\n\n if (!object || isSubjectType(object)) {\n return !this.inverted;\n }\n\n const matches = this._conditionsMatcher();\n return matches(object as Record<string, unknown>);\n }\n\n matchesField(field: string | undefined): boolean {\n if (!this.fields) {\n return true;\n }\n\n if (!field) {\n return !this.inverted;\n }\n\n if (this.fields && !this._matchField) {\n this._matchField = this._options.fieldMatcher!(this.fields);\n }\n\n return this._matchField!(field);\n }\n}\n","export interface LinkedItem<T> {\n next: LinkedItem<T> | null\n prev: LinkedItem<T> | null\n readonly value: T\n}\n\nexport function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']) {\n const item = { value, prev, next: null };\n\n if (prev) {\n prev.next = item;\n }\n\n return item;\n}\n\nexport function unlinkItem(item: LinkedItem<any>) {\n if (item.next) {\n item.next.prev = item.prev;\n }\n\n if (item.prev) {\n item.prev.next = item.next;\n }\n\n item.next = item.prev = null; // eslint-disable-line\n}\n\nexport const cloneLinkedItem = <T extends LinkedItem<any>>(item: T): T => ({\n value: item.value,\n prev: item.prev,\n next: item.next,\n} as T);\n","import { Rule, RuleOptions } from './Rule';\nimport { RawRuleFrom } from './RawRule';\nimport {\n Abilities,\n Normalize,\n SubjectType,\n AbilityParameters,\n AbilityTuple,\n ExtractSubjectType\n} from './types';\nimport { wrapArray, detectSubjectType, mergePrioritized, getOrDefault, identity, isSubjectType } from './utils';\nimport { LinkedItem, linkedItem, unlinkItem, cloneLinkedItem } from './structures/LinkedItem';\n\nexport interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {\n detectSubjectType?(\n subject: Exclude<Normalize<A>[1], SubjectType>\n ): ExtractSubjectType<Normalize<A>[1]>;\n anyAction?: string;\n anySubjectType?: string;\n}\n\ndeclare const $abilities: unique symbol;\ndeclare const $conditions: unique symbol;\ninterface WithGenerics {\n [$abilities]: any\n [$conditions]: any\n}\nexport type Public<T extends WithGenerics> = { [K in keyof T]: T[K] };\nexport interface Generics<T extends WithGenerics> {\n abilities: T[typeof $abilities],\n conditions: T[typeof $conditions]\n}\n\nexport type RuleOf<T extends WithGenerics> =\n Rule<Generics<T>['abilities'], Generics<T>['conditions']>;\nexport type RawRuleOf<T extends WithGenerics> =\n RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;\n\nexport type RuleIndexOptionsOf<T extends WithGenerics> =\n RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;\n\ninterface AbilityEvent<T extends WithGenerics> {\n target: T\n /** @deprecated use \"target\" property instead */\n ability: T\n}\n\nexport interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {\n rules: RawRuleOf<T>[]\n}\n/**\n * @deprecated `on`/`emit` properly infer type without this type\n * TODO(major): delete\n */\nexport type EventHandler<Event> = (event: Event) => void;\n\nexport type Events<\n T extends WithGenerics,\n K extends keyof EventsMap<T> = keyof EventsMap<T>\n> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;\n\ninterface EventsMap<T extends WithGenerics> {\n update(event: UpdateEvent<T>): void\n updated(event: UpdateEvent<T>): void\n}\n\ntype IndexTree<A extends Abilities, C> = Map<SubjectType, Map<string, {\n rules: Rule<A, C>[],\n merged: boolean\n}>>;\n\nexport type Unsubscribe = () => void;\n\nconst defaultActionEntry = () => ({\n rules: [] as unknown as Rule<any, any>[],\n merged: false\n});\nconst defaultSubjectEntry = () => new Map<string, ReturnType<typeof defaultActionEntry>>();\nconst analyze = (index: any, rule: Rule<any, any>) => {\n if (!index._hasPerFieldRules && rule.fields) {\n index._hasPerFieldRules = true;\n }\n};\n\ntype AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> =\n AbilityParameters<\n T,\n T extends AbilityTuple\n ? IncludeField extends true\n ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0\n : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0\n : never,\n (action: Extract<T, string>) => 0\n >;\n\nexport class RuleIndex<A extends Abilities, Conditions> {\n private _hasPerFieldRules: boolean = false;\n private _events: Events<this> = new Map();\n private _indexedRules!: IndexTree<A, Conditions>;\n private _rules!: RawRuleFrom<A, Conditions>[];\n private readonly _ruleOptions!: RuleOptions<Conditions>;\n private readonly _detectSubjectType!: Required<RuleIndexOptions<A, Conditions>>['detectSubjectType'];\n private readonly _anyAction: string;\n private readonly _anySubjectType: string;\n readonly [$abilities]!: A;\n readonly [$conditions]!: Conditions;\n\n constructor(\n rules: RawRuleFrom<A, Conditions>[] = [],\n options: RuleIndexOptions<A, Conditions> = {}\n ) {\n this._ruleOptions = {\n conditionsMatcher: options.conditionsMatcher,\n fieldMatcher: options.fieldMatcher,\n resolveAction: options.resolveAction || identity,\n };\n this._anyAction = options.anyAction || 'manage';\n this._anySubjectType = options.anySubjectType || 'all';\n this._detectSubjectType = options.detectSubjectType || detectSubjectType;\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n }\n\n get rules() {\n return this._rules;\n }\n\n detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]> {\n if (isSubjectType(object)) return object;\n if (!object) return this._anySubjectType;\n return this._detectSubjectType(object as Exclude<Normalize<A>[1], SubjectType>);\n }\n\n update(rules: RawRuleFrom<A, Conditions>[]): Public<this> {\n const event = {\n rules,\n ability: this,\n target: this\n } as unknown as UpdateEvent<this>;\n\n this._emit('update', event);\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n this._emit('updated', event);\n\n return this;\n }\n\n private _buildIndexFor(rawRules: RawRuleFrom<A, Conditions>[]) {\n const indexedRules: IndexTree<A, Conditions> = new Map();\n\n for (let i = rawRules.length - 1; i >= 0; i--) {\n const priority = rawRules.length - i - 1;\n const rule = new Rule(rawRules[i], this._ruleOptions, priority);\n const actions = wrapArray(rule.action);\n const subjects = wrapArray(rule.subject || this._anySubjectType);\n analyze(this, rule);\n\n for (let k = 0; k < subjects.length; k++) {\n const subjectRules = getOrDefault(indexedRules, subjects[k], defaultSubjectEntry);\n\n for (let j = 0; j < actions.length; j++) {\n getOrDefault(subjectRules, actions[j], defaultActionEntry).rules.push(rule);\n }\n }\n }\n\n return indexedRules;\n }\n\n possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[]\n possibleRulesFor(\n action: string,\n subjectType: SubjectType = this._anySubjectType\n ): Rule<A, Conditions>[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"possibleRulesFor\" accepts only subject types (i.e., string or class) as the 2nd parameter');\n }\n\n const subjectRules = getOrDefault(this._indexedRules, subjectType, defaultSubjectEntry);\n const actionRules = getOrDefault(subjectRules, action, defaultActionEntry);\n\n if (actionRules.merged) {\n return actionRules.rules;\n }\n\n const anyActionRules = action !== this._anyAction && subjectRules.has(this._anyAction)\n ? subjectRules.get(this._anyAction)!.rules\n : undefined;\n let rules = mergePrioritized(actionRules.rules, anyActionRules);\n\n if (subjectType !== this._anySubjectType) {\n rules = mergePrioritized(rules, (this as any).possibleRulesFor(action, this._anySubjectType));\n }\n\n actionRules.rules = rules;\n actionRules.merged = true;\n\n return rules;\n }\n\n rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[]\n rulesFor(action: string, subjectType?: SubjectType, field?: string): Rule<A, Conditions>[] {\n const rules: Rule<A, Conditions>[] = (this as any).possibleRulesFor(action, subjectType);\n\n if (field && typeof field !== 'string') {\n throw new Error('The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details');\n }\n\n if (!this._hasPerFieldRules) {\n return rules;\n }\n\n return rules.filter(rule => rule.matchesField(field));\n }\n\n on<T extends keyof EventsMap<this>>(\n event: T,\n handler: EventsMap<Public<this>>[T]\n ): Unsubscribe {\n const head = this._events.get(event) || null;\n const item = linkedItem(handler, head);\n this._events.set(event, item);\n\n return () => {\n if (!item.next && !item.prev && this._events.get(event) === item) {\n this._events.delete(event);\n } else {\n unlinkItem(item);\n }\n };\n }\n\n private _emit<T extends keyof EventsMap<this>>(\n name: T,\n payload: Parameters<EventsMap<this>[T]>[0]\n ) {\n let current = this._events.get(name) || null;\n while (current !== null) {\n const prev = current.prev ? cloneLinkedItem(current.prev) : null;\n current.value(payload);\n current = prev;\n }\n }\n}\n","import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';\nimport { Abilities, AbilityTuple, CanParameters, Subject } from './types';\nimport { Rule } from './Rule';\n\nexport interface AbilityOptions<A extends Abilities, Conditions>\n extends RuleIndexOptions<A, Conditions> {}\nexport interface AnyAbility extends Public<PureAbility<any, any>> {}\nexport interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {}\nexport type AbilityClass<T extends AnyAbility> = new (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport class PureAbility<\n A extends Abilities = AbilityTuple,\n Conditions = unknown\n> extends RuleIndex<A, Conditions> {\n can(...args: CanParameters<A>): boolean {\n const rule = this.relevantRuleFor(...args);\n return !!rule && !rule.inverted;\n }\n\n relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null {\n const subjectType = this.detectSubjectType(subject);\n const rules = (this as any).rulesFor(action, subjectType, field);\n\n for (let i = 0, length = rules.length; i < length; i++) {\n if (rules[i].matchesConditions(subject)) {\n return rules[i];\n }\n }\n\n return null;\n }\n\n cannot(...args: CanParameters<A>): boolean {\n return !this.can(...args);\n }\n}\n","import {\n $eq,\n eq,\n $ne,\n ne,\n $lt,\n lt,\n $lte,\n lte,\n $gt,\n gt,\n $gte,\n gte,\n $in,\n within,\n $nin,\n nin,\n $all,\n all,\n $size,\n size,\n $regex,\n $options,\n regex,\n $elemMatch,\n elemMatch,\n $exists,\n exists,\n and,\n createFactory,\n BuildMongoQuery,\n DefaultOperators,\n} from '@ucast/mongo2js';\nimport { ConditionsMatcher, AnyObject } from '../types';\nimport { Container, GenericFactory } from '../hkt';\n\nconst defaultInstructions = {\n $eq,\n $ne,\n $lt,\n $lte,\n $gt,\n $gte,\n $in,\n $nin,\n $all,\n $size,\n $regex,\n $options,\n $elemMatch,\n $exists,\n};\nconst defaultInterpreters = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n in: within,\n nin,\n all,\n size,\n regex,\n elemMatch,\n exists,\n and,\n};\n\ninterface MongoQueryFactory extends GenericFactory {\n produce: MongoQuery<this[0]>\n}\n\ntype MergeUnion<T extends {}, Keys extends keyof T = keyof T> = { [K in Keys]: T[K] };\nexport type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {\n toplevel: {},\n field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>\n}> & Container<MongoQueryFactory>;\n\ntype MongoQueryMatcherFactory =\n (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;\nexport const buildMongoQueryMatcher = ((instructions, interpreters, options) => createFactory(\n { ...defaultInstructions, ...instructions },\n { ...defaultInterpreters, ...interpreters },\n options\n)) as MongoQueryMatcherFactory;\n\nexport const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);\nexport type {\n MongoQueryFieldOperators,\n MongoQueryTopLevelOperators,\n MongoQueryOperators,\n} from '@ucast/mongo2js';\n","import { FieldMatcher } from '../types';\n\nconst REGEXP_SPECIAL_CHARS = /[-/\\\\^$+?.()|[\\]{}]/g;\nconst REGEXP_ANY = /\\.?\\*+\\.?/g;\nconst REGEXP_STARS = /\\*+/;\nconst REGEXP_DOT = /\\./g;\n\nfunction detectRegexpPattern(match: string, index: number, string: string): string {\n const quantifier = string[0] === '*' || match[0] === '.' && match[match.length - 1] === '.'\n ? '+'\n : '*';\n const matcher = match.indexOf('**') === -1 ? '[^.]' : '.';\n const pattern = match.replace(REGEXP_DOT, '\\\\$&')\n .replace(REGEXP_STARS, matcher + quantifier);\n\n return index + match.length === string.length ? `(?:${pattern})?` : pattern;\n}\n\nfunction escapeRegexp(match: string, index: number, string: string): string {\n if (match === '.' && (string[index - 1] === '*' || string[index + 1] === '*')) {\n return match;\n }\n\n return `\\\\${match}`;\n}\n\nfunction createPattern(fields: string[]) {\n const patterns = fields.map(field => field\n .replace(REGEXP_SPECIAL_CHARS, escapeRegexp)\n .replace(REGEXP_ANY, detectRegexpPattern));\n const pattern = patterns.length > 1 ? `(?:${patterns.join('|')})` : patterns[0];\n\n return new RegExp(`^${pattern}$`);\n}\n\nexport const fieldPatternMatcher: FieldMatcher = (fields) => {\n let pattern: RegExp | null;\n\n return (field) => {\n if (typeof pattern === 'undefined') {\n pattern = fields.every(f => f.indexOf('*') === -1)\n ? null\n : createPattern(fields);\n }\n\n return pattern === null\n ? fields.indexOf(field) !== -1\n : pattern.test(field);\n };\n};\n","import { PureAbility, AbilityOptions } from './PureAbility';\nimport { RawRuleFrom } from './RawRule';\nimport { AbilityTuple } from './types';\nimport { MongoQuery, mongoQueryMatcher } from './matchers/conditions';\nimport { fieldPatternMatcher } from './matchers/field';\nimport { Public } from './RuleIndex';\n\nexport class Ability<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {\n constructor(rules: RawRuleFrom<A, C>[] = [], options: AbilityOptions<A, C> = {}) {\n super(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n }\n}\n\nexport interface AnyMongoAbility extends Public<Ability<any, MongoQuery>> {}\n","import { Ability, AnyMongoAbility } from './Ability';\nimport { AnyAbility, AbilityOptionsOf, AbilityClass } from './PureAbility';\nimport { RawRuleOf, Generics } from './RuleIndex';\nimport {\n ExtractSubjectType as E,\n AbilityTuple,\n SubjectType,\n TaggedInterface,\n Normalize,\n AnyObject,\n AnyClass,\n} from './types';\nimport { ProduceGeneric } from './hkt';\n\nclass RuleBuilder<T extends AnyAbility> {\n public _rule!: RawRuleOf<T>;\n\n constructor(rule: RawRuleOf<T>) {\n this._rule = rule;\n }\n\n because(reason: string): this {\n this._rule.reason = reason;\n return this;\n }\n}\n\ntype InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R>\n ? R\n : S extends string\n ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string>\n ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>>\n : AnyObject\n : never;\ntype ConditionsOf<T extends AnyAbility, I extends {}> =\n ProduceGeneric<Generics<T>['conditions'], I>;\ntype ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any\n ? S extends T[1] ? T[0] : never\n : never;\ntype ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;\ntype SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;\n\ntype SimpleCanParams<T extends AnyAbility> = Parameters<(\n action: Generics<T>['abilities'] | Generics<T>['abilities'][]\n) => 0>;\ntype BuilderCanParameters<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\n\ntype BuilderCanParametersWithFields<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n F extends string,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n fields?: F | F[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\ntype Keys<T> = string & keyof T;\n\nexport class AbilityBuilder<T extends AnyAbility> {\n public rules: RawRuleOf<T>[] = [];\n private _AbilityType!: AnyClass<T>;\n\n constructor(AbilityType: AnyClass<T>) {\n this._AbilityType = AbilityType;\n this.can = this.can.bind(this as any);\n this.cannot = this.cannot.bind(this as any);\n this.build = this.build.bind(this as any);\n }\n\n can<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n can<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n can(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ): RuleBuilder<T> {\n const rule = { action } as RawRuleOf<T>;\n\n if (subject) {\n rule.subject = subject;\n\n if (Array.isArray(conditionsOrFields) || typeof conditionsOrFields === 'string') {\n rule.fields = conditionsOrFields;\n } else if (typeof conditionsOrFields !== 'undefined') {\n rule.conditions = conditionsOrFields;\n }\n\n if (typeof conditions !== 'undefined') {\n rule.conditions = conditions;\n }\n }\n\n this.rules.push(rule);\n\n return new RuleBuilder(rule);\n }\n\n cannot<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n cannot<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n cannot(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions'],\n ): RuleBuilder<T> {\n const builder = (this as any).can(action, subject, conditionsOrFields, conditions);\n builder._rule.inverted = true;\n return builder;\n }\n\n build(options?: AbilityOptionsOf<T>) {\n return new this._AbilityType(this.rules, options);\n }\n}\n\ntype DSL<T extends AnyAbility, R> = (\n can: AbilityBuilder<T>['can'],\n cannot: AbilityBuilder<T>['cannot']\n) => R;\n\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void | Promise<void>>, options?: AbilityOptionsOf<T>): T | Promise<T> {\n const builder = new AbilityBuilder(Ability as unknown as AbilityClass<T>);\n const result = define(builder.can, builder.cannot);\n\n if (result && typeof result.then === 'function') {\n return result.then(() => builder.build(options));\n }\n\n return builder.build(options);\n}\n","import { AnyAbility } from './PureAbility';\nimport { Normalize } from './types';\nimport { Generics } from './RuleIndex';\nimport { getSubjectTypeName } from './utils';\n\nexport type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;\nexport const getDefaultErrorMessage: GetErrorMessage = error => `Cannot execute \"${error.action}\" on \"${error.subjectType}\"`;\n\nconst NativeError = function NError(this: Error, message: string) {\n this.message = message;\n} as unknown as new (message: string) => Error;\n\nNativeError.prototype = Object.create(Error.prototype);\n\nexport class ForbiddenError<T extends AnyAbility> extends NativeError {\n public readonly ability!: T;\n public action!: Normalize<Generics<T>['abilities']>[0];\n public subject!: Generics<T>['abilities'][1];\n public field?: string;\n public subjectType!: string;\n\n static _defaultErrorMessage = getDefaultErrorMessage;\n\n static setDefaultMessage(messageOrFn: string | GetErrorMessage) {\n this._defaultErrorMessage = typeof messageOrFn === 'string' ? () => messageOrFn : messageOrFn;\n }\n\n static from<U extends AnyAbility>(ability: U) {\n return new this<U>(ability);\n }\n\n private constructor(ability: T) {\n super('');\n this.ability = ability;\n\n if (typeof Error.captureStackTrace === 'function') {\n this.name = 'ForbiddenError';\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n setMessage(message: string) {\n this.message = message;\n return this;\n }\n\n throwUnlessCan(...args: Parameters<T['can']>) {\n const rule = this.ability.relevantRuleFor(...args);\n\n if (rule && !rule.inverted) {\n return;\n }\n\n this.action = args[0];\n this.subject = args[1];\n this.subjectType = getSubjectTypeName(this.ability.detectSubjectType(args[1]));\n this.field = args[2];\n\n const reason = rule ? rule.reason : '';\n // eslint-disable-next-line no-underscore-dangle\n this.message = this.message || reason || (this.constructor as any)._defaultErrorMessage(this);\n throw this; // eslint-disable-line\n }\n}\n"],"names":["wrapArray","value","Array","isArray","TYPE_FIELD","setSubjectType","type","object","hasOwnProperty","Object","defineProperty","Error","isSubjectType","getSubjectClassName","modelName","name","getSubjectTypeName","detectSubjectType","subject","constructor","expandActions","aliasMap","rawActions","merge","actions","i","length","action","findDuplicate","actionToFind","indexOf","defaultAliasMerge","concat","validateForCycles","reservedAction","keys","mergeAliasesAndDetectCycles","duplicate","join","isUsingReservedAction","createAliasResolver","options","skipValidate","anyAction","copyArrayTo","dest","target","start","push","mergePrioritized","array","anotherArray","j","merged","priority","getOrDefault","map","key","defaultValue","get","set","identity","x","validate","rule","fields","fieldMatcher","conditions","conditionsMatcher","Rule","resolveAction","inverted","reason","undefined","_options","_conditionsMatcher","this","_matchConditions","matchesConditions","matches","matchesField","field","_matchField","ast","linkedItem","prev","item","next","unlinkItem","cloneLinkedItem","defaultActionEntry","rules","defaultSubjectEntry","Map","analyze","index","_hasPerFieldRules","RuleIndex","_events","_ruleOptions","_anyAction","_anySubjectType","anySubjectType","_detectSubjectType","_rules","_indexedRules","_buildIndexFor","update","event","ability","_emit","rawRules","indexedRules","subjects","k","subjectRules","possibleRulesFor","subjectType","actionRules","anyActionRules","has","rulesFor","filter","on","handler","head","_this","delete","payload","current","PureAbility","can","relevantRuleFor","cannot","defaultInstructions","$eq","$ne","$lt","$lte","$gt","$gte","$in","$nin","$all","$size","$regex","$options","$elemMatch","$exists","defaultInterpreters","eq","ne","lt","lte","gt","gte","in","within","nin","all","size","regex","elemMatch","exists","and","buildMongoQueryMatcher","instructions","interpreters","createFactory","mongoQueryMatcher","REGEXP_SPECIAL_CHARS","REGEXP_ANY","REGEXP_STARS","REGEXP_DOT","detectRegexpPattern","match","string","quantifier","matcher","pattern","replace","escapeRegexp","createPattern","patterns","RegExp","fieldPatternMatcher","every","f","test","Ability","_PureAbility","RuleBuilder","_rule","because","AbilityBuilder","AbilityType","_AbilityType","bind","build","conditionsOrFields","builder","defineAbility","define","result","then","getDefaultErrorMessage","error","NativeError","NError","message","prototype","create","ForbiddenError","setDefaultMessage","messageOrFn","_defaultErrorMessage","from","captureStackTrace","setMessage","throwUnlessCan"],"mappings":"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"}
{"version":3,"file":"index.js","sources":["../../src/utils.ts","../../src/Rule.ts","../../src/structures/LinkedItem.ts","../../src/RuleIndex.ts","../../src/PureAbility.ts","../../src/matchers/conditions.ts","../../src/matchers/field.ts","../../src/Ability.ts","../../src/AbilityBuilder.ts","../../src/ForbiddenError.ts"],"sourcesContent":["import { AnyObject, Subject, SubjectType, SubjectClass, ForcedSubject, AliasesMap } from './types';\n\nexport function wrapArray<T>(value: T[] | T): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function setByPath(object: AnyObject, path: string, value: unknown): void {\n let ref = object;\n let lastKey = path;\n\n if (path.indexOf('.') !== -1) {\n const keys = path.split('.');\n\n lastKey = keys.pop()!;\n ref = keys.reduce((res, prop) => {\n res[prop] = res[prop] || {};\n return res[prop] as AnyObject;\n }, object);\n }\n\n ref[lastKey] = value;\n}\n\nconst TYPE_FIELD = '__caslSubjectType__';\nexport function setSubjectType<\n T extends string,\n U extends Record<PropertyKey, any>\n>(type: T, object: U): U & ForcedSubject<T> {\n if (object) {\n if (!object.hasOwnProperty(TYPE_FIELD)) {\n Object.defineProperty(object, TYPE_FIELD, { value: type });\n } else if (type !== object[TYPE_FIELD]) {\n throw new Error(`Trying to cast object to subject type ${type} but previously it was casted to ${object[TYPE_FIELD]}`);\n }\n }\n\n return object as U & ForcedSubject<T>;\n}\n\nexport const isSubjectType = (value: unknown): value is SubjectType => {\n const type = typeof value;\n return type === 'string' || type === 'function';\n};\n\nconst getSubjectClassName = (value: SubjectClass) => value.modelName || value.name;\nexport const getSubjectTypeName = (value: SubjectType) => {\n return typeof value === 'string' ? value : getSubjectClassName(value);\n};\n\nexport function detectSubjectType(subject: Exclude<Subject, SubjectType>): string {\n if (subject.hasOwnProperty(TYPE_FIELD)) {\n return (subject as any)[TYPE_FIELD];\n }\n\n return getSubjectClassName(subject.constructor as SubjectClass);\n}\n\ntype AliasMerge = (actions: string[], action: string | string[]) => string[];\nfunction expandActions(aliasMap: AliasesMap, rawActions: string | string[], merge: AliasMerge) {\n let actions = wrapArray(rawActions);\n let i = 0;\n\n while (i < actions.length) {\n const action = actions[i++];\n\n if (aliasMap.hasOwnProperty(action)) {\n actions = merge(actions, aliasMap[action]);\n }\n }\n\n return actions;\n}\n\nfunction findDuplicate(actions: string[], actionToFind: string | string[]) {\n if (typeof actionToFind === 'string' && actions.indexOf(actionToFind) !== -1) {\n return actionToFind;\n }\n\n for (let i = 0; i < actionToFind.length; i++) {\n if (actions.indexOf(actionToFind[i]) !== -1) return actionToFind[i];\n }\n\n return null;\n}\n\nconst defaultAliasMerge: AliasMerge = (actions, action) => actions.concat(action);\nfunction validateForCycles(aliasMap: AliasesMap, reservedAction: string) {\n if (reservedAction in aliasMap) {\n throw new Error(`Cannot use \"${reservedAction}\" as an alias because it's reserved action.`);\n }\n\n const keys = Object.keys(aliasMap);\n const mergeAliasesAndDetectCycles: AliasMerge = (actions, action) => {\n const duplicate = findDuplicate(actions, action);\n if (duplicate) throw new Error(`Detected cycle ${duplicate} -> ${actions.join(', ')}`);\n\n const isUsingReservedAction = typeof action === 'string' && action === reservedAction\n || actions.indexOf(reservedAction) !== -1\n || Array.isArray(action) && action.indexOf(reservedAction) !== -1;\n if (isUsingReservedAction) throw new Error(`Cannot make an alias to \"${reservedAction}\" because this is reserved action`);\n\n return actions.concat(action);\n };\n\n for (let i = 0; i < keys.length; i++) {\n expandActions(aliasMap, keys[i], mergeAliasesAndDetectCycles);\n }\n}\n\nexport type AliasResolverOptions = { skipValidate?: boolean; anyAction?: string };\nexport function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions) {\n if (!options || options.skipValidate !== false) {\n validateForCycles(aliasMap, options && options.anyAction || 'manage');\n }\n\n return (action: string | string[]) => expandActions(aliasMap, action, defaultAliasMerge);\n}\n\nfunction copyArrayTo<T>(dest: T[], target: T[], start: number) {\n for (let i = start; i < target.length; i++) {\n dest.push(target[i]);\n }\n}\n\nexport function mergePrioritized<T extends { priority: number }>(\n array?: T[],\n anotherArray?: T[]\n): T[] {\n if (!array || !array.length) {\n return anotherArray || [];\n }\n\n if (!anotherArray || !anotherArray.length) {\n return array || [];\n }\n\n let i = 0;\n let j = 0;\n const merged: T[] = [];\n\n while (i < array.length && j < anotherArray.length) {\n if (array[i].priority < anotherArray[j].priority) {\n merged.push(array[i]);\n i++;\n } else {\n merged.push(anotherArray[j]);\n j++;\n }\n }\n\n copyArrayTo(merged, array, i);\n copyArrayTo(merged, anotherArray, j);\n\n return merged;\n}\n\nexport function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V) {\n let value = map.get(key);\n\n if (!value) {\n value = defaultValue();\n map.set(key, value);\n }\n\n return value;\n}\n\nexport const identity = <T>(x: T) => x;\n","import { wrapArray, isSubjectType } from './utils';\nimport {\n MatchConditions,\n MatchField,\n Abilities,\n ToAbilityTypes,\n Normalize,\n ConditionsMatcher,\n FieldMatcher,\n} from './types';\nimport { RawRule, RawRuleFrom } from './RawRule';\n\ntype Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;\n\nfunction validate(rule: RawRuleFrom<Abilities, any>, options: RuleOptions<any>) {\n if (Array.isArray(rule.fields) && !rule.fields.length) {\n throw new Error('`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa');\n }\n\n if (rule.fields && !options.fieldMatcher) {\n throw new Error('You need to pass \"fieldMatcher\" option in order to restrict access by fields');\n }\n\n if (rule.conditions && !options.conditionsMatcher) {\n throw new Error('You need to pass \"conditionsMatcher\" option in order to restrict access by conditions');\n }\n}\n\nexport interface RuleOptions<Conditions> {\n conditionsMatcher?: ConditionsMatcher<Conditions>\n fieldMatcher?: FieldMatcher\n resolveAction(action: string | string[]): string | string[]\n}\n\nexport class Rule<A extends Abilities, C> {\n private _matchConditions: MatchConditions | undefined;\n private _matchField: MatchField<string> | undefined;\n private readonly _options!: RuleOptions<C>;\n public readonly action!: Tuple<A>[0] | Tuple<A>[0][];\n public readonly subject!: Tuple<A>[1] | Tuple<A>[1][];\n public readonly inverted!: boolean;\n public readonly conditions!: C | undefined;\n public readonly fields!: string[] | undefined;\n public readonly reason!: string | undefined;\n public readonly priority!: number;\n\n constructor(\n rule: RawRule<ToAbilityTypes<A>, C>,\n options: RuleOptions<C>,\n priority: number = 0\n ) {\n validate(rule, options);\n\n this.action = options.resolveAction(rule.action);\n this.subject = rule.subject!;\n this.inverted = !!rule.inverted;\n this.conditions = rule.conditions;\n this.reason = rule.reason;\n this.fields = rule.fields ? wrapArray(rule.fields) : undefined;\n this.priority = priority;\n this._options = options;\n }\n\n private _conditionsMatcher() {\n if (this.conditions && !this._matchConditions) {\n this._matchConditions = this._options.conditionsMatcher!(this.conditions);\n }\n\n return this._matchConditions!;\n }\n\n get ast() {\n const matches = this._conditionsMatcher();\n return matches ? matches.ast : undefined;\n }\n\n matchesConditions(object: Normalize<A>[1] | undefined): boolean {\n if (!this.conditions) {\n return true;\n }\n\n if (!object || isSubjectType(object)) {\n return !this.inverted;\n }\n\n const matches = this._conditionsMatcher();\n return matches(object as Record<string, unknown>);\n }\n\n matchesField(field: string | undefined): boolean {\n if (!this.fields) {\n return true;\n }\n\n if (!field) {\n return !this.inverted;\n }\n\n if (this.fields && !this._matchField) {\n this._matchField = this._options.fieldMatcher!(this.fields);\n }\n\n return this._matchField!(field);\n }\n}\n","export interface LinkedItem<T> {\n next: LinkedItem<T> | null\n prev: LinkedItem<T> | null\n readonly value: T\n}\n\nexport function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']) {\n const item = { value, prev, next: null };\n\n if (prev) {\n prev.next = item;\n }\n\n return item;\n}\n\nexport function unlinkItem(item: LinkedItem<any>) {\n if (item.next) {\n item.next.prev = item.prev;\n }\n\n if (item.prev) {\n item.prev.next = item.next;\n }\n\n item.next = item.prev = null; // eslint-disable-line\n}\n\nexport const cloneLinkedItem = <T extends LinkedItem<any>>(item: T): T => ({\n value: item.value,\n prev: item.prev,\n next: item.next,\n} as T);\n","import { Rule, RuleOptions } from './Rule';\nimport { RawRuleFrom } from './RawRule';\nimport {\n Abilities,\n Normalize,\n SubjectType,\n AbilityParameters,\n AbilityTuple,\n ExtractSubjectType\n} from './types';\nimport { wrapArray, detectSubjectType, mergePrioritized, getOrDefault, identity, isSubjectType } from './utils';\nimport { LinkedItem, linkedItem, unlinkItem, cloneLinkedItem } from './structures/LinkedItem';\n\nexport interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {\n detectSubjectType?(\n subject: Exclude<Normalize<A>[1], SubjectType>\n ): ExtractSubjectType<Normalize<A>[1]>;\n anyAction?: string;\n anySubjectType?: string;\n}\n\ndeclare const $abilities: unique symbol;\ndeclare const $conditions: unique symbol;\ninterface WithGenerics {\n [$abilities]: any\n [$conditions]: any\n}\nexport type Public<T extends WithGenerics> = { [K in keyof T]: T[K] };\nexport interface Generics<T extends WithGenerics> {\n abilities: T[typeof $abilities],\n conditions: T[typeof $conditions]\n}\n\nexport type RuleOf<T extends WithGenerics> =\n Rule<Generics<T>['abilities'], Generics<T>['conditions']>;\nexport type RawRuleOf<T extends WithGenerics> =\n RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;\n\nexport type RuleIndexOptionsOf<T extends WithGenerics> =\n RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;\n\ninterface AbilityEvent<T extends WithGenerics> {\n target: T\n /** @deprecated use \"target\" property instead */\n ability: T\n}\n\nexport interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {\n rules: RawRuleOf<T>[]\n}\n/**\n * @deprecated `on`/`emit` properly infer type without this type\n * TODO(major): delete\n */\nexport type EventHandler<Event> = (event: Event) => void;\n\nexport type Events<\n T extends WithGenerics,\n K extends keyof EventsMap<T> = keyof EventsMap<T>\n> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;\n\ninterface EventsMap<T extends WithGenerics> {\n update(event: UpdateEvent<T>): void\n updated(event: UpdateEvent<T>): void\n}\n\ntype IndexTree<A extends Abilities, C> = Map<SubjectType, Map<string, {\n rules: Rule<A, C>[],\n merged: boolean\n}>>;\n\nexport type Unsubscribe = () => void;\n\nconst defaultActionEntry = () => ({\n rules: [] as unknown as Rule<any, any>[],\n merged: false\n});\nconst defaultSubjectEntry = () => new Map<string, ReturnType<typeof defaultActionEntry>>();\nconst analyze = (index: any, rule: Rule<any, any>) => {\n if (!index._hasPerFieldRules && rule.fields) {\n index._hasPerFieldRules = true;\n }\n};\n\ntype AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> =\n AbilityParameters<\n T,\n T extends AbilityTuple\n ? IncludeField extends true\n ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0\n : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0\n : never,\n (action: Extract<T, string>) => 0\n >;\n\nexport class RuleIndex<A extends Abilities, Conditions> {\n private _hasPerFieldRules: boolean = false;\n private _events: Events<this> = new Map();\n private _indexedRules!: IndexTree<A, Conditions>;\n private _rules!: RawRuleFrom<A, Conditions>[];\n private readonly _ruleOptions!: RuleOptions<Conditions>;\n private readonly _detectSubjectType!: Required<RuleIndexOptions<A, Conditions>>['detectSubjectType'];\n private readonly _anyAction: string;\n private readonly _anySubjectType: string;\n readonly [$abilities]!: A;\n readonly [$conditions]!: Conditions;\n\n constructor(\n rules: RawRuleFrom<A, Conditions>[] = [],\n options: RuleIndexOptions<A, Conditions> = {}\n ) {\n this._ruleOptions = {\n conditionsMatcher: options.conditionsMatcher,\n fieldMatcher: options.fieldMatcher,\n resolveAction: options.resolveAction || identity,\n };\n this._anyAction = options.anyAction || 'manage';\n this._anySubjectType = options.anySubjectType || 'all';\n this._detectSubjectType = options.detectSubjectType || detectSubjectType;\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n }\n\n get rules() {\n return this._rules;\n }\n\n detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]> {\n if (isSubjectType(object)) return object;\n if (!object) return this._anySubjectType;\n return this._detectSubjectType(object as Exclude<Normalize<A>[1], SubjectType>);\n }\n\n update(rules: RawRuleFrom<A, Conditions>[]): Public<this> {\n const event = {\n rules,\n ability: this,\n target: this\n } as unknown as UpdateEvent<this>;\n\n this._emit('update', event);\n this._rules = rules;\n this._indexedRules = this._buildIndexFor(rules);\n this._emit('updated', event);\n\n return this;\n }\n\n private _buildIndexFor(rawRules: RawRuleFrom<A, Conditions>[]) {\n const indexedRules: IndexTree<A, Conditions> = new Map();\n\n for (let i = rawRules.length - 1; i >= 0; i--) {\n const priority = rawRules.length - i - 1;\n const rule = new Rule(rawRules[i], this._ruleOptions, priority);\n const actions = wrapArray(rule.action);\n const subjects = wrapArray(rule.subject || this._anySubjectType);\n analyze(this, rule);\n\n for (let k = 0; k < subjects.length; k++) {\n const subjectRules = getOrDefault(indexedRules, subjects[k], defaultSubjectEntry);\n\n for (let j = 0; j < actions.length; j++) {\n getOrDefault(subjectRules, actions[j], defaultActionEntry).rules.push(rule);\n }\n }\n }\n\n return indexedRules;\n }\n\n possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[]\n possibleRulesFor(\n action: string,\n subjectType: SubjectType = this._anySubjectType\n ): Rule<A, Conditions>[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"possibleRulesFor\" accepts only subject types (i.e., string or class) as the 2nd parameter');\n }\n\n const subjectRules = getOrDefault(this._indexedRules, subjectType, defaultSubjectEntry);\n const actionRules = getOrDefault(subjectRules, action, defaultActionEntry);\n\n if (actionRules.merged) {\n return actionRules.rules;\n }\n\n const anyActionRules = action !== this._anyAction && subjectRules.has(this._anyAction)\n ? subjectRules.get(this._anyAction)!.rules\n : undefined;\n let rules = mergePrioritized(actionRules.rules, anyActionRules);\n\n if (subjectType !== this._anySubjectType) {\n rules = mergePrioritized(rules, (this as any).possibleRulesFor(action, this._anySubjectType));\n }\n\n actionRules.rules = rules;\n actionRules.merged = true;\n\n return rules;\n }\n\n rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[]\n rulesFor(action: string, subjectType?: SubjectType, field?: string): Rule<A, Conditions>[] {\n const rules: Rule<A, Conditions>[] = (this as any).possibleRulesFor(action, subjectType);\n\n if (field && typeof field !== 'string') {\n throw new Error('The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details');\n }\n\n if (!this._hasPerFieldRules) {\n return rules;\n }\n\n return rules.filter(rule => rule.matchesField(field));\n }\n\n on<T extends keyof EventsMap<this>>(\n event: T,\n handler: EventsMap<Public<this>>[T]\n ): Unsubscribe {\n const tail = this._events.get(event) || null;\n const item = linkedItem(handler, tail);\n this._events.set(event, item);\n\n return () => {\n const currentTail = this._events.get(event);\n\n if (!item.next && !item.prev && currentTail === item) {\n this._events.delete(event);\n } else if (item === currentTail) {\n this._events.set(event, item.prev);\n }\n\n unlinkItem(item);\n };\n }\n\n private _emit<T extends keyof EventsMap<this>>(\n name: T,\n payload: Parameters<EventsMap<this>[T]>[0]\n ) {\n let current = this._events.get(name) || null;\n while (current !== null) {\n const prev = current.prev ? cloneLinkedItem(current.prev) : null;\n current.value(payload);\n current = prev;\n }\n }\n}\n","import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';\nimport { Abilities, AbilityTuple, CanParameters, Subject } from './types';\nimport { Rule } from './Rule';\n\nexport interface AbilityOptions<A extends Abilities, Conditions>\n extends RuleIndexOptions<A, Conditions> {}\nexport interface AnyAbility extends Public<PureAbility<any, any>> {}\nexport interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {}\nexport type AbilityClass<T extends AnyAbility> = new (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport class PureAbility<\n A extends Abilities = AbilityTuple,\n Conditions = unknown\n> extends RuleIndex<A, Conditions> {\n can(...args: CanParameters<A>): boolean {\n const rule = this.relevantRuleFor(...args);\n return !!rule && !rule.inverted;\n }\n\n relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null {\n const subjectType = this.detectSubjectType(subject);\n const rules = (this as any).rulesFor(action, subjectType, field);\n\n for (let i = 0, length = rules.length; i < length; i++) {\n if (rules[i].matchesConditions(subject)) {\n return rules[i];\n }\n }\n\n return null;\n }\n\n cannot(...args: CanParameters<A>): boolean {\n return !this.can(...args);\n }\n}\n","import {\n $eq,\n eq,\n $ne,\n ne,\n $lt,\n lt,\n $lte,\n lte,\n $gt,\n gt,\n $gte,\n gte,\n $in,\n within,\n $nin,\n nin,\n $all,\n all,\n $size,\n size,\n $regex,\n $options,\n regex,\n $elemMatch,\n elemMatch,\n $exists,\n exists,\n and,\n createFactory,\n BuildMongoQuery,\n DefaultOperators,\n} from '@ucast/mongo2js';\nimport { ConditionsMatcher, AnyObject } from '../types';\nimport { Container, GenericFactory } from '../hkt';\n\nconst defaultInstructions = {\n $eq,\n $ne,\n $lt,\n $lte,\n $gt,\n $gte,\n $in,\n $nin,\n $all,\n $size,\n $regex,\n $options,\n $elemMatch,\n $exists,\n};\nconst defaultInterpreters = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n in: within,\n nin,\n all,\n size,\n regex,\n elemMatch,\n exists,\n and,\n};\n\ninterface MongoQueryFactory extends GenericFactory {\n produce: MongoQuery<this[0]>\n}\n\ntype MergeUnion<T extends {}, Keys extends keyof T = keyof T> = { [K in Keys]: T[K] };\nexport type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {\n toplevel: {},\n field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>\n}> & Container<MongoQueryFactory>;\n\ntype MongoQueryMatcherFactory =\n (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;\nexport const buildMongoQueryMatcher = ((instructions, interpreters, options) => createFactory(\n { ...defaultInstructions, ...instructions },\n { ...defaultInterpreters, ...interpreters },\n options\n)) as MongoQueryMatcherFactory;\n\nexport const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);\nexport type {\n MongoQueryFieldOperators,\n MongoQueryTopLevelOperators,\n MongoQueryOperators,\n} from '@ucast/mongo2js';\n","import { FieldMatcher } from '../types';\n\nconst REGEXP_SPECIAL_CHARS = /[-/\\\\^$+?.()|[\\]{}]/g;\nconst REGEXP_ANY = /\\.?\\*+\\.?/g;\nconst REGEXP_STARS = /\\*+/;\nconst REGEXP_DOT = /\\./g;\n\nfunction detectRegexpPattern(match: string, index: number, string: string): string {\n const quantifier = string[0] === '*' || match[0] === '.' && match[match.length - 1] === '.'\n ? '+'\n : '*';\n const matcher = match.indexOf('**') === -1 ? '[^.]' : '.';\n const pattern = match.replace(REGEXP_DOT, '\\\\$&')\n .replace(REGEXP_STARS, matcher + quantifier);\n\n return index + match.length === string.length ? `(?:${pattern})?` : pattern;\n}\n\nfunction escapeRegexp(match: string, index: number, string: string): string {\n if (match === '.' && (string[index - 1] === '*' || string[index + 1] === '*')) {\n return match;\n }\n\n return `\\\\${match}`;\n}\n\nfunction createPattern(fields: string[]) {\n const patterns = fields.map(field => field\n .replace(REGEXP_SPECIAL_CHARS, escapeRegexp)\n .replace(REGEXP_ANY, detectRegexpPattern));\n const pattern = patterns.length > 1 ? `(?:${patterns.join('|')})` : patterns[0];\n\n return new RegExp(`^${pattern}$`);\n}\n\nexport const fieldPatternMatcher: FieldMatcher = (fields) => {\n let pattern: RegExp | null;\n\n return (field) => {\n if (typeof pattern === 'undefined') {\n pattern = fields.every(f => f.indexOf('*') === -1)\n ? null\n : createPattern(fields);\n }\n\n return pattern === null\n ? fields.indexOf(field) !== -1\n : pattern.test(field);\n };\n};\n","import { PureAbility, AbilityOptions } from './PureAbility';\nimport { RawRuleFrom } from './RawRule';\nimport { AbilityTuple } from './types';\nimport { MongoQuery, mongoQueryMatcher } from './matchers/conditions';\nimport { fieldPatternMatcher } from './matchers/field';\nimport { Public } from './RuleIndex';\n\nexport class Ability<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {\n constructor(rules: RawRuleFrom<A, C>[] = [], options: AbilityOptions<A, C> = {}) {\n super(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n }\n}\n\nexport interface AnyMongoAbility extends Public<Ability<any, MongoQuery>> {}\n","import { Ability, AnyMongoAbility } from './Ability';\nimport { AnyAbility, AbilityOptionsOf, AbilityClass } from './PureAbility';\nimport { RawRuleOf, Generics } from './RuleIndex';\nimport {\n ExtractSubjectType as E,\n AbilityTuple,\n SubjectType,\n TaggedInterface,\n Normalize,\n AnyObject,\n AnyClass,\n} from './types';\nimport { ProduceGeneric } from './hkt';\n\nclass RuleBuilder<T extends AnyAbility> {\n public _rule!: RawRuleOf<T>;\n\n constructor(rule: RawRuleOf<T>) {\n this._rule = rule;\n }\n\n because(reason: string): this {\n this._rule.reason = reason;\n return this;\n }\n}\n\ntype InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R>\n ? R\n : S extends string\n ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string>\n ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>>\n : AnyObject\n : never;\ntype ConditionsOf<T extends AnyAbility, I extends {}> =\n ProduceGeneric<Generics<T>['conditions'], I>;\ntype ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any\n ? S extends T[1] ? T[0] : never\n : never;\ntype ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;\ntype SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;\n\ntype SimpleCanParams<T extends AnyAbility> = Parameters<(\n action: Generics<T>['abilities'] | Generics<T>['abilities'][]\n) => 0>;\ntype BuilderCanParameters<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\n\ntype BuilderCanParametersWithFields<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n F extends string,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n fields?: F | F[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\ntype Keys<T> = string & keyof T;\n\nexport class AbilityBuilder<T extends AnyAbility> {\n public rules: RawRuleOf<T>[] = [];\n private _AbilityType!: AnyClass<T>;\n\n constructor(AbilityType: AnyClass<T>) {\n this._AbilityType = AbilityType;\n this.can = this.can.bind(this as any);\n this.cannot = this.cannot.bind(this as any);\n this.build = this.build.bind(this as any);\n }\n\n can<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n can<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n can(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ): RuleBuilder<T> {\n const rule = { action } as RawRuleOf<T>;\n\n if (subject) {\n rule.subject = subject;\n\n if (Array.isArray(conditionsOrFields) || typeof conditionsOrFields === 'string') {\n rule.fields = conditionsOrFields;\n } else if (typeof conditionsOrFields !== 'undefined') {\n rule.conditions = conditionsOrFields;\n }\n\n if (typeof conditions !== 'undefined') {\n rule.conditions = conditions;\n }\n }\n\n this.rules.push(rule);\n\n return new RuleBuilder(rule);\n }\n\n cannot<\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>\n cannot<\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>\n cannot(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions'],\n ): RuleBuilder<T> {\n const builder = (this as any).can(action, subject, conditionsOrFields, conditions);\n builder._rule.inverted = true;\n return builder;\n }\n\n build(options?: AbilityOptionsOf<T>) {\n return new this._AbilityType(this.rules, options);\n }\n}\n\ntype DSL<T extends AnyAbility, R> = (\n can: AbilityBuilder<T>['can'],\n cannot: AbilityBuilder<T>['cannot']\n) => R;\n\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void | Promise<void>>, options?: AbilityOptionsOf<T>): T | Promise<T> {\n const builder = new AbilityBuilder(Ability as unknown as AbilityClass<T>);\n const result = define(builder.can, builder.cannot);\n\n if (result && typeof result.then === 'function') {\n return result.then(() => builder.build(options));\n }\n\n return builder.build(options);\n}\n","import { AnyAbility } from './PureAbility';\nimport { Normalize } from './types';\nimport { Generics } from './RuleIndex';\nimport { getSubjectTypeName } from './utils';\n\nexport type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;\nexport const getDefaultErrorMessage: GetErrorMessage = error => `Cannot execute \"${error.action}\" on \"${error.subjectType}\"`;\n\nconst NativeError = function NError(this: Error, message: string) {\n this.message = message;\n} as unknown as new (message: string) => Error;\n\nNativeError.prototype = Object.create(Error.prototype);\n\nexport class ForbiddenError<T extends AnyAbility> extends NativeError {\n public readonly ability!: T;\n public action!: Normalize<Generics<T>['abilities']>[0];\n public subject!: Generics<T>['abilities'][1];\n public field?: string;\n public subjectType!: string;\n\n static _defaultErrorMessage = getDefaultErrorMessage;\n\n static setDefaultMessage(messageOrFn: string | GetErrorMessage) {\n this._defaultErrorMessage = typeof messageOrFn === 'string' ? () => messageOrFn : messageOrFn;\n }\n\n static from<U extends AnyAbility>(ability: U) {\n return new this<U>(ability);\n }\n\n private constructor(ability: T) {\n super('');\n this.ability = ability;\n\n if (typeof Error.captureStackTrace === 'function') {\n this.name = 'ForbiddenError';\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n setMessage(message: string) {\n this.message = message;\n return this;\n }\n\n throwUnlessCan(...args: Parameters<T['can']>) {\n const rule = this.ability.relevantRuleFor(...args);\n\n if (rule && !rule.inverted) {\n return;\n }\n\n this.action = args[0];\n this.subject = args[1];\n this.subjectType = getSubjectTypeName(this.ability.detectSubjectType(args[1]));\n this.field = args[2];\n\n const reason = rule ? rule.reason : '';\n // eslint-disable-next-line no-underscore-dangle\n this.message = this.message || reason || (this.constructor as any)._defaultErrorMessage(this);\n throw this; // eslint-disable-line\n }\n}\n"],"names":["wrapArray","value","Array","isArray","TYPE_FIELD","setSubjectType","type","object","hasOwnProperty","Object","defineProperty","Error","isSubjectType","getSubjectClassName","modelName","name","getSubjectTypeName","detectSubjectType","subject","constructor","expandActions","aliasMap","rawActions","merge","actions","i","length","action","findDuplicate","actionToFind","indexOf","defaultAliasMerge","concat","validateForCycles","reservedAction","keys","mergeAliasesAndDetectCycles","duplicate","join","isUsingReservedAction","createAliasResolver","options","skipValidate","anyAction","copyArrayTo","dest","target","start","push","mergePrioritized","array","anotherArray","j","merged","priority","getOrDefault","map","key","defaultValue","get","set","identity","x","validate","rule","fields","fieldMatcher","conditions","conditionsMatcher","Rule","resolveAction","inverted","reason","undefined","_options","_conditionsMatcher","this","_matchConditions","matchesConditions","matches","matchesField","field","_matchField","ast","linkedItem","prev","item","next","unlinkItem","cloneLinkedItem","defaultActionEntry","rules","defaultSubjectEntry","Map","analyze","index","_hasPerFieldRules","RuleIndex","_events","_ruleOptions","_anyAction","_anySubjectType","anySubjectType","_detectSubjectType","_rules","_indexedRules","_buildIndexFor","update","event","ability","_emit","rawRules","indexedRules","subjects","k","subjectRules","possibleRulesFor","subjectType","actionRules","anyActionRules","has","rulesFor","filter","on","handler","tail","currentTail","_this","delete","payload","current","PureAbility","can","relevantRuleFor","cannot","defaultInstructions","$eq","$ne","$lt","$lte","$gt","$gte","$in","$nin","$all","$size","$regex","$options","$elemMatch","$exists","defaultInterpreters","eq","ne","lt","lte","gt","gte","in","within","nin","all","size","regex","elemMatch","exists","and","buildMongoQueryMatcher","instructions","interpreters","createFactory","mongoQueryMatcher","REGEXP_SPECIAL_CHARS","REGEXP_ANY","REGEXP_STARS","REGEXP_DOT","detectRegexpPattern","match","string","quantifier","matcher","pattern","replace","escapeRegexp","createPattern","patterns","RegExp","fieldPatternMatcher","every","f","test","Ability","_PureAbility","RuleBuilder","_rule","because","AbilityBuilder","AbilityType","_AbilityType","bind","build","conditionsOrFields","builder","defineAbility","define","result","then","getDefaultErrorMessage","error","NativeError","NError","message","prototype","create","ForbiddenError","setDefaultMessage","messageOrFn","_defaultErrorMessage","from","captureStackTrace","setMessage","throwUnlessCan"],"mappings":"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"}
{
"name": "@casl/ability",
"version": "5.4.2",
"version": "5.4.3",
"description": "CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access",

@@ -5,0 +5,0 @@ "funding": "https://github.com/stalniy/casl/blob/master/BACKERS.md",

@@ -9,2 +9,6 @@ # [CASL Ability](https://stalniy.github.io/casl/) [![@casl/ability NPM version](https://badge.fury.io/js/%40casl%2Fability.svg)](https://badge.fury.io/js/%40casl%2Fability) [![](https://img.shields.io/npm/dm/%40casl%2Fability.svg)](https://www.npmjs.com/package/%40casl%2Fability) [![CASL Documentation](https://img.shields.io/badge/documentation-available-brightgreen.svg)](https://stalniy.github.io/casl/) [![CASL Join the chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/stalniy-casl/casl)

npm install @casl/ability
# or
pnpm install @casl/ability
# or
yarn add @casl/ability
```

@@ -11,0 +15,0 @@