node_modules ignore

This commit is contained in:
oier committed 2025-05-08 23:43:47 +02:00
1 parent e19d52f172
commit 4574544c9f
65041 files changed
+10593536

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
import{buildOr as r,buildAnd as n,CompoundCondition as t}from"@ucast/mongo2js";function e(r){return Array.isArray(r)?r:[r]}function u(r,n,t){var e=r;var u=n;if(-1!==n.indexOf(".")){var i=n.split(".");u=i.pop();e=i.reduce((function(r,n){r[n]=r[n]||{};return r[n]}),r)}e[u]=t}Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);function i(r,n,t,e){var u={};var i=r.rulesFor(n,t);for(var o=0;o<i.length;o++){var a=i[o];var f=a.inverted?"$and":"$or";if(!a.conditions)if(a.inverted)break;else{delete u[f];return u}else{u[f]=u[f]||[];u[f].push(e(a))}}return u.$or?u:null}function o(r){if(!r.ast)throw new Error('Ability rule "'+JSON.stringify(r)+'" does not have "ast" property. So, cannot be used to generate AST');return r.inverted?new t("not",[r.ast]):r.ast}function a(t,e,u){var a=i(t,e,u,o);if(null===a)return null;if(!a.$and)return a.$or?r(a.$or):n([]);if(a.$or)a.$and.push(r(a.$or));return n(a.$and)}function f(r,n,t){return r.rulesFor(n,t).reduce((function(r,n){if(n.inverted||!n.conditions)return r;return Object.keys(n.conditions).reduce((function(r,t){var e=n.conditions[t];if(!e||e.constructor!==Object)u(r,t,e);return r}),r)}),{})}function c(r,n,t,e){var u=r.detectSubjectType(t);var i=r.possibleRulesFor(n,u);var o=new Set;var a=o.delete.bind(o);var f=o.add.bind(o);var c=i.length;while(c--){var v=i[c];if(v.matchesConditions(t)){var l=v.inverted?a:f;e.fieldsFrom(v).forEach(l)}}return Array.from(o)}var v=function r(n){return Array.isArray(n)?n.join(","):n};function l(r,n){return r.map((function(r){var t=[v(r.action||r.actions),"function"===typeof n?e(r.subject).map(n).join(","):v(r.subject),r.conditions||0,r.inverted?1:0,r.fields?v(r.fields):0,r.reason||""];while(t.length>0&&!t[t.length-1])t.pop();return t}))}function b(r,n){return r.map((function(r){var t=r[0],e=r[1],u=r[2],i=r[3],o=r[4],a=r[5];var f=e.split(",");var c={inverted:!!i,action:t.split(","),subject:"function"===typeof n?f.map(n):f};if(u)c.conditions=u;if(o)c.fields=o.split(",");if(a)c.reason=a;return c}))}export{l as packRules,c as permittedFieldsOf,a as rulesToAST,f as rulesToFields,i as rulesToQuery,b as unpackRules};
//# sourceMappingURL=extra.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"extra.js","sources":["../../src/utils.ts","../../src/extra.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 hasOwnProperty = (Object as any).hasOwn\n || Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);\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 (!hasOwnProperty(object, 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 (hasOwnProperty(subject, TYPE_FIELD)) {\n return subject[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 (hasOwnProperty(aliasMap, 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 }\nLine truncated
+2
View File
@@ -0,0 +1,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 a,$all as f,$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 A,within as j,nin as E,all as m,size as $,regex as M,elemMatch as O,exists as x,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,B(n.key),n)}}function S(t,r,i){if(r)_(t.prototype,r);if(i)_(t,i);Object.defineProperty(t,"prototype",{writable:false});return t}function C(){C=Object.assign?Object.assign.bind():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 C.apply(this,arguments)}function P(t,r){t.prototype=Object.create(r.prototype);t.prototype.constructor=t;R(t,r)}function R(t,r){R=Object.setPrototypeOf?Object.setPrototypeOf.bind():function t(r,i){r.__proto__=i;return r};return R(t,r)}function T(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function k(t,r){if("object"!==typeof t||null===t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var n=i.call(t,r||"default");if("object"!==typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}function B(t){var r=k(t,"string");return"symbol"===typeof r?r:String(r)}function q(t){return Array.isArray(t)?t:[t]}var z=Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);var Y="__caslSubjectType__";function D(t,r){if(r)if(!z(r,Y))Object.defineProperty(r,Y,{value:t});else if(t!==r[Y])throw new Error("Trying to cast object to subject type "+t+" but previously it was casted to "+r[Y]);return r}var L=function t(r){var i=typeof r;return"string"===i||"function"===i};var N=function t(r){return r.modelName||r.name};var G=function t(r){return"string"===typeof r?r:N(r)};function H(t){if(z(t,Y))return t[Y];return N(t.constructor)}function I(t,r,i){var n=q(r);var e=0;while(e<n.length){var u=n[e++];if(z(t,u))n=i(n,t[u])}return n}function J(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 K=function t(r,i){return r.concat(i)};function Q(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=J(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++)I(t,i[e],n)}function U(t,r){if(!r||false!==r.skipValidate)Q(t,r&&r.anyAction||"manage");return function(r){return I(t,r,K)}}function V(t,r,i){for(var n=i;n<r.length;n++)t.push(r[n])}function W(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++}V(e,t,i);V(e,r,n);return e}function X(t,r,i){var n=t.get(r);if(!n){n=i();t.set(r,n)}return n}var Z=function t(r){return r};function tt(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 rt=function(){function t(t,r,i){if(void 0===i)i=0;tt(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.origin=t;this.fields=t.fields?q(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||L(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)};S(t,[{key:"ast",get:function t(){var r=this.i();return r?r.ast:void 0}}]);return t}();function it(t,r){var i={value:t,prev:r,next:null};if(r)r.next=i;return i}function nt(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}var et=function t(r){return{value:r.value,prev:r.prev,next:r.next}};var ut=function t(){return{rules:[],merged:false}};var ot=function t(){return new Map};var st=function(){function t(t,r){if(void 0===t)t=[];if(void 0===r)r={};this.h=false;this.v={conditionsMatcher:r.coLine truncated
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,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 hasOwnProperty = (Object as any).hasOwn\n || Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);\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 (!hasOwnProperty(object, 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 (hasOwnProperty(subject, TYPE_FIELD)) {\n return subject[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 (hasOwnProperty(aliasMap, 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[]Line truncated
+2
View File
@@ -0,0 +1,2 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:true});var t=require("@ucast/mongo2js");function n(t){return Array.isArray(t)?t:[t]}function e(t,n,e){let r=t;let o=n;if(-1!==n.indexOf(".")){const e=n.split(".");o=e.pop();r=e.reduce(((t,n)=>{t[n]=t[n]||{};return t[n]}),t)}r[o]=e}Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);function r(t,n,e,r){const o={};const c=t.rulesFor(n,e);for(let t=0;t<c.length;t++){const n=c[t];const e=n.inverted?"$and":"$or";if(!n.conditions)if(n.inverted)break;else{delete o[e];return o}else{o[e]=o[e]||[];o[e].push(r(n))}}return o.$or?o:null}function o(n){if(!n.ast)throw new Error(`Ability rule "${JSON.stringify(n)}" does not have "ast" property. So, cannot be used to generate AST`);return n.inverted?new t.CompoundCondition("not",[n.ast]):n.ast}function c(n,e,c){const u=r(n,e,c,o);if(null===u)return null;if(!u.$and)return u.$or?t.buildOr(u.$or):t.buildAnd([]);if(u.$or)u.$and.push(t.buildOr(u.$or));return t.buildAnd(u.$and)}function u(t,n,r){return t.rulesFor(n,r).reduce(((t,n)=>{if(n.inverted||!n.conditions)return t;return Object.keys(n.conditions).reduce(((t,r)=>{const o=n.conditions[r];if(!o||o.constructor!==Object)e(t,r,o);return t}),t)}),{})}function s(t,n,e,r){const o=t.detectSubjectType(e);const c=t.possibleRulesFor(n,o);const u=new Set;const s=u.delete.bind(u);const i=u.add.bind(u);let f=c.length;while(f--){const t=c[f];if(t.matchesConditions(e)){const n=t.inverted?s:i;r.fieldsFrom(t).forEach(n)}}return Array.from(u)}const i=t=>Array.isArray(t)?t.join(","):t;function f(t,e){return t.map((t=>{const r=[i(t.action||t.actions),"function"===typeof e?n(t.subject).map(e).join(","):i(t.subject),t.conditions||0,t.inverted?1:0,t.fields?i(t.fields):0,t.reason||""];while(r.length>0&&!r[r.length-1])r.pop();return r}))}function l(t,n){return t.map((([t,e,r,o,c,u])=>{const s=e.split(",");const i={inverted:!!o,action:t.split(","),subject:"function"===typeof n?s.map(n):s};if(r)i.conditions=r;if(c)i.fields=c.split(",");if(u)i.reason=u;return i}))}exports.packRules=f;exports.permittedFieldsOf=s;exports.rulesToAST=c;exports.rulesToFields=u;exports.rulesToQuery=r;exports.unpackRules=l;
//# sourceMappingURL=extra.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"extra.js","sources":["../../src/utils.ts","../../src/extra.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 hasOwnProperty = (Object as any).hasOwn\n || Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);\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 (!hasOwnProperty(object, 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 (hasOwnProperty(subject, TYPE_FIELD)) {\n return subject[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 (hasOwnProperty(aliasMap, 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 }\nLine truncated
+2
View File
@@ -0,0 +1,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=Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);const i="__caslSubjectType__";function r(t,e){if(e)if(!s(e,i))Object.defineProperty(e,i,{value:t});else if(t!==e[i])throw new Error(`Trying to cast object to subject type ${t} but previously it was casted to ${e[i]}`);return e}const n=t=>{const e=typeof t;return"string"===e||"function"===e};const o=t=>t.modelName||t.name;const c=t=>"string"===typeof t?t:o(t);function u(t){if(s(t,i))return t[i];return o(t.constructor)}function h(t,i,r){let n=e(i);let o=0;while(o<n.length){const e=n[o++];if(s(t,e))n=r(n,t[e])}return n}function l(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 a=(t,e)=>t.concat(e);function f(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=l(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++)h(t,s[e],i)}function d(t,e){if(!e||false!==e.skipValidate)f(t,e&&e.anyAction||"manage");return e=>h(t,e,a)}function p(t,e,s){for(let i=s;i<e.length;i++)t.push(e[i])}function y(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++}p(r,t,s);p(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 w=t=>t;function g(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 x{constructor(t,s,i=0){g(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.origin=t;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||n(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 A(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}const M=t=>({value:t.value,prev:t.prev,next:t.next});const j=()=>({rules:[],merged:false});const E=()=>new Map;class v{constructor(t=[],e={}){this.h=false;this.l={conditionsMatcher:e.conditionsMatcher,fieldMatcher:e.fieldMatcher,resolveAction:e.resolveAction||w};this.p=e.anyAction||"manage";this.g=e.anySubjectType||"all";this.$=e.detectSubjectType||u;this.A=t;this.M=this.j(t)}get rules(){return this.A}detectSubjectType(t){if(n(t))return t;if(!t)return this.g;return this.$(t)}update(t){const e={rules:t,ability:this,target:this};this.v("update",e);this.A=t;this.M=this.j(t);this.v("updated",e);return this}j(t){const s=new Map;for(let i=t.length-1;i>=0;i--){const r=t.length-i-1;const n=new x(t[i],this.l,r);const o=e(n.action);const c=e(n.subject||this.g);if(!this.h&&n.fields)this.h=true;for(let t=0;t<c.length;t++){const e=b(s,c[t],E);for(let t=0;t<o.length;t++)b(e,o[t],j).rules.push(n)}}return s}possibleRulesFor(t,e=this.g){if(!n(e))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');const s=b(this.M,e,E);const i=b(s,t,j);if(i.merged)return i.rules;const r=t!==this.p&&s.has(this.p)?s.get(this.p).rules:void 0;let o=y(i.rules,r);if(e!==this.g)o=y(o,this.possibleRulesFor(t,this.g));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)))}actionsFor(t){if(!n(t))throw new Error('"actionsFor" accepts only subject types (i.e., string or class) as a parameter');const e=new Set;const s=this.M.get(t);if(s)Array.from(s.keys()).forEach((t=>e.add(t)));const i=t!==this.g?this.M.get(this.g):void 0;if(i)Array.from(i.keys()).forEach((t=>e.add(t)));return Array.Line truncated
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,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 hasOwnProperty = (Object as any).hasOwn\n || Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);\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 (!hasOwnProperty(object, 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 (hasOwnProperty(subject, TYPE_FIELD)) {\n return subject[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 (hasOwnProperty(aliasMap, 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[]Line truncated
+2
View File
@@ -0,0 +1,2 @@
import{buildOr as t,buildAnd as n,CompoundCondition as e}from"@ucast/mongo2js";function r(t){return Array.isArray(t)?t:[t]}function o(t,n,e){let r=t;let o=n;if(-1!==n.indexOf(".")){const e=n.split(".");o=e.pop();r=e.reduce(((t,n)=>{t[n]=t[n]||{};return t[n]}),t)}r[o]=e}Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);function c(t,n,e,r){const o={};const c=t.rulesFor(n,e);for(let t=0;t<c.length;t++){const n=c[t];const e=n.inverted?"$and":"$or";if(!n.conditions)if(n.inverted)break;else{delete o[e];return o}else{o[e]=o[e]||[];o[e].push(r(n))}}return o.$or?o:null}function u(t){if(!t.ast)throw new Error(`Ability rule "${JSON.stringify(t)}" does not have "ast" property. So, cannot be used to generate AST`);return t.inverted?new e("not",[t.ast]):t.ast}function i(e,r,o){const i=c(e,r,o,u);if(null===i)return null;if(!i.$and)return i.$or?t(i.$or):n([]);if(i.$or)i.$and.push(t(i.$or));return n(i.$and)}function f(t,n,e){return t.rulesFor(n,e).reduce(((t,n)=>{if(n.inverted||!n.conditions)return t;return Object.keys(n.conditions).reduce(((t,e)=>{const r=n.conditions[e];if(!r||r.constructor!==Object)o(t,e,r);return t}),t)}),{})}function s(t,n,e,r){const o=t.detectSubjectType(e);const c=t.possibleRulesFor(n,o);const u=new Set;const i=u.delete.bind(u);const f=u.add.bind(u);let s=c.length;while(s--){const t=c[s];if(t.matchesConditions(e)){const n=t.inverted?i:f;r.fieldsFrom(t).forEach(n)}}return Array.from(u)}const l=t=>Array.isArray(t)?t.join(","):t;function a(t,n){return t.map((t=>{const e=[l(t.action||t.actions),"function"===typeof n?r(t.subject).map(n).join(","):l(t.subject),t.conditions||0,t.inverted?1:0,t.fields?l(t.fields):0,t.reason||""];while(e.length>0&&!e[e.length-1])e.pop();return e}))}function b(t,n){return t.map((([t,e,r,o,c,u])=>{const i=e.split(",");const f={inverted:!!o,action:t.split(","),subject:"function"===typeof n?i.map(n):i};if(r)f.conditions=r;if(c)f.fields=c.split(",");if(u)f.reason=u;return f}))}export{a as packRules,s as permittedFieldsOf,i as rulesToAST,f as rulesToFields,c as rulesToQuery,b as unpackRules};
//# sourceMappingURL=extra.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"extra.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,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 y,eq as b,ne as p,lt as w,lte as g,gt as $,gte as A,within as j,nin as M,all as m,size as E,regex as v,elemMatch as x,exists as F,and as _}from"@ucast/mongo2js";function O(t){return Array.isArray(t)?t:[t]}const C=Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);const R="__caslSubjectType__";function P(t,e){if(e)if(!C(e,R))Object.defineProperty(e,R,{value:t});else if(t!==e[R])throw new Error(`Trying to cast object to subject type ${t} but previously it was casted to ${e[R]}`);return e}const S=t=>{const e=typeof t;return"string"===e||"function"===e};const T=t=>t.modelName||t.name;const B=t=>"string"===typeof t?t:T(t);function q(t){if(C(t,R))return t[R];return T(t.constructor)}function z(t,e,i){let s=O(e);let n=0;while(n<s.length){const e=s[n++];if(C(t,e))s=i(s,t[e])}return s}function D(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 Y=(t,e)=>t.concat(e);function k(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=D(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++)z(t,i[e],s)}function I(t,e){if(!e||false!==e.skipValidate)k(t,e&&e.anyAction||"manage");return e=>z(t,e,Y)}function L(t,e,i){for(let s=i;s<e.length;s++)t.push(e[s])}function U(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++}L(n,t,i);L(n,e,s);return n}function G(t,e,i){let s=t.get(e);if(!s){s=i();t.set(e,s)}return s}const H=t=>t;function J(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 K{constructor(t,e,i=0){J(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.origin=t;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||S(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 N(t,e){const i={value:t,prev:e,next:null};if(e)e.next=i;return i}function Q(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}const V=t=>({value:t.value,prev:t.prev,next:t.next});const W=()=>({rules:[],merged:false});const X=()=>new Map;class Z{constructor(t=[],e={}){this.h=false;this.l={conditionsMatcher:e.conditionsMatcher,fieldMatcher:e.fieldMatcher,resolveAction:e.resolveAction||H};this.p=e.anyAction||"manage";this.g=e.anySubjectType||"all";this.$=e.detectSubjectType||q;this.A=t;this.j=this.M(t)}get rules(){return this.A}detectSubjectType(t){if(S(t))return t;if(!t)return this.g;return this.$(t)}update(t){const e={rules:t,ability:this,target:this};this.m("update",e);this.A=t;this.j=this.M(t);this.m("updated",e);return this}M(t){const e=new Map;for(let i=t.length-1;i>=0;i--){const s=t.length-i-1;const n=new K(t[i],this.l,s);const r=O(n.action);const o=O(n.subject||this.g);if(!this.h&&n.fields)this.h=true;for(let t=0;t<o.length;t++){const i=G(e,o[t],X);for(let t=0;t<r.length;t++)G(i,r[t],W).rules.push(n)}}return e}possibleRulesFor(t,e=this.g){if(!S(e))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');const i=G(this.j,e,X);const s=G(i,t,W);if(s.merged)return s.rules;const n=t!==this.p&&i.has(this.p)?i.get(this.p).rules:void 0;let r=U(s.rules,n);if(e!==this.g)r=U(r,this.possibleRulesFor(t,this.g));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)))}actionsFor(t){if(!S(t))throw new Error('"actionsFor" accepts only subject types (iLine truncated
//# sourceMappingURL=index.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
+18
View File
@@ -0,0 +1,18 @@
import { PureAbility, AbilityOptions, AbilityOptionsOf } from './PureAbility';
import { RawRuleFrom } from './RawRule';
import { AbilityTuple } from './types';
import { MongoQuery } from './matchers/conditions';
import { Public, RawRuleOf } from './RuleIndex';
/**
* @deprecated use createMongoAbility function instead and MongoAbility<Abilities> interface.
* In the next major version PureAbility will be renamed to Ability and this class will be removed
*/
export declare class Ability<A extends AbilityTuple = AbilityTuple, C extends MongoQuery = MongoQuery> extends PureAbility<A, C> {
constructor(rules?: RawRuleFrom<A, C>[], options?: AbilityOptions<A, C>);
}
export interface AnyMongoAbility extends Public<PureAbility<any, MongoQuery>> {
}
export interface MongoAbility<A extends AbilityTuple = AbilityTuple, C extends MongoQuery = MongoQuery> extends PureAbility<A, C> {
}
export declare function createMongoAbility<T extends AnyMongoAbility = MongoAbility>(rules?: RawRuleOf<T>[], options?: AbilityOptionsOf<T>): T;
export declare function createMongoAbility<A extends AbilityTuple = AbilityTuple, C extends MongoQuery = MongoQuery>(rules?: RawRuleFrom<A, C>[], options?: AbilityOptions<A, C>): MongoAbility<A, C>;
+37
View File
@@ -0,0 +1,37 @@
import { AnyMongoAbility, MongoAbility } from './Ability';
import { ProduceGeneric } from './hkt';
import { AbilityOptionsOf, AnyAbility } from './PureAbility';
import { Generics, RawRuleOf } from './RuleIndex';
import { AbilityTuple, AnyClass, AnyObject, ExtractSubjectType as E, Normalize, SubjectType, TaggedInterface } from './types';
declare class RuleBuilder<T extends AnyAbility> {
_rule: RawRuleOf<T>;
constructor(rule: RawRuleOf<T>);
because(reason: string): this;
}
declare type AbilityFactory<T extends AnyAbility> = AnyClass<T> | ((rules?: any[], options?: any) => T);
declare type InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R> ? R : S extends (...args: any[]) => infer O ? O : S extends string ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string> ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>> : AnyObject : never;
declare type ConditionsOf<T extends AnyAbility, I extends {}> = ProduceGeneric<Generics<T>['conditions'], I>;
declare type ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any ? S extends Extract<T[1], SubjectType> ? T[0] : never : never;
declare type ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;
declare type SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;
declare type SimpleCanParams<T extends AnyAbility> = Parameters<(action: Generics<T>['abilities'] | Generics<T>['abilities'][]) => 0>;
declare type BuilderCanParameters<S extends SubjectType, I extends InstanceOf<T, S>, T extends AnyAbility> = Generics<T>['abilities'] extends AbilityTuple ? Parameters<(action: ActionOf<T, S> | ActionOf<T, S>[], subject: S | S[], conditions?: ConditionsOf<T, I>) => 0> : SimpleCanParams<T>;
declare type BuilderCanParametersWithFields<S extends SubjectType, I extends InstanceOf<T, S>, F extends string, T extends AnyAbility> = Generics<T>['abilities'] extends AbilityTuple ? Parameters<(action: ActionOf<T, S> | ActionOf<T, S>[], subject: S | S[], fields?: F | F[], conditions?: ConditionsOf<T, I>) => 0> : SimpleCanParams<T>;
declare type Keys<T> = string & keyof T;
declare type AddRule<T extends AnyAbility> = {
<I extends InstanceOf<T, S>, F extends string = Keys<I>, S extends SubjectTypeOf<T> = SubjectTypeOf<T>>(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>;
<I extends InstanceOf<T, S>, S extends SubjectTypeOf<T> = SubjectTypeOf<T>>(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>;
};
export declare class AbilityBuilder<T extends AnyAbility> {
rules: RawRuleOf<T>[];
private readonly _createAbility;
can: AddRule<T>;
cannot: AddRule<T>;
build: (options?: AbilityOptionsOf<T>) => T;
constructor(AbilityType: AbilityFactory<T>);
private _addRule;
}
declare type DSL<T extends AnyAbility, R> = (can: AbilityBuilder<T>['can'], cannot: AbilityBuilder<T>['cannot']) => R;
export declare function defineAbility<T extends AnyMongoAbility = MongoAbility>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;
export declare function defineAbility<T extends AnyMongoAbility = MongoAbility>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;
export {};
+22
View File
@@ -0,0 +1,22 @@
import { AnyAbility } from './PureAbility';
import { Normalize } from './types';
import { Generics } from './RuleIndex';
export declare type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;
/** @deprecated will be removed in the next major release */
export declare const getDefaultErrorMessage: GetErrorMessage;
declare const NativeError: new (message: string) => Error;
export declare class ForbiddenError<T extends AnyAbility> extends NativeError {
readonly ability: T;
action: Normalize<Generics<T>['abilities']>[0];
subject: Generics<T>['abilities'][1];
field?: string;
subjectType: string;
static _defaultErrorMessage: GetErrorMessage;
static setDefaultMessage(messageOrFn: string | GetErrorMessage): void;
static from<U extends AnyAbility>(ability: U): ForbiddenError<U>;
private constructor();
setMessage(message: string): this;
throwUnlessCan(...args: Parameters<T['can']>): void;
unlessCan(...args: Parameters<T['can']>): this | undefined;
}
export {};
+16
View File
@@ -0,0 +1,16 @@
import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';
import { Abilities, AbilityTuple, CanParameters } from './types';
import { Rule } from './Rule';
export interface AbilityOptions<A extends Abilities, Conditions> extends RuleIndexOptions<A, Conditions> {
}
export interface AnyAbility extends Public<PureAbility<any, any>> {
}
export interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {
}
export declare type AbilityClass<T extends AnyAbility> = new (rules?: RawRuleOf<T>[], options?: AbilityOptionsOf<T>) => T;
export declare type CreateAbility<T extends AnyAbility> = (rules?: RawRuleOf<T>[], options?: AbilityOptionsOf<T>) => T;
export declare class PureAbility<A extends Abilities = AbilityTuple, Conditions = unknown> extends RuleIndex<A, Conditions> {
can(...args: CanParameters<A>): boolean;
relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null;
cannot(...args: CanParameters<A>): boolean;
}
+21
View File
@@ -0,0 +1,21 @@
import { SubjectType, AbilityTypes, AbilityTupleType, Abilities, ToAbilityTypes } from './types';
interface BaseRawRule<Conditions> {
fields?: string | string[];
conditions?: Conditions;
/** indicates that rule forbids something (i.e., has inverted logic) */
inverted?: boolean;
/** explains the reason of why rule does not allow to do something */
reason?: string;
}
export interface ClaimRawRule<A extends string> extends BaseRawRule<undefined> {
action: A | A[];
subject?: undefined;
}
export interface SubjectRawRule<A extends string, S extends SubjectType, C> extends BaseRawRule<C> {
action: A | A[];
subject: S | S[];
}
declare type DefineRule<T extends AbilityTypes, C, Else = ClaimRawRule<Extract<T, string>>> = T extends AbilityTupleType ? SubjectRawRule<T[0], T[1], C> : Else;
export declare type RawRule<T extends AbilityTypes = AbilityTupleType, C = unknown> = DefineRule<T, C>;
export declare type RawRuleFrom<T extends Abilities, C> = RawRule<ToAbilityTypes<T>, C>;
export {};
+27
View File
@@ -0,0 +1,27 @@
import { Abilities, ToAbilityTypes, Normalize, ConditionsMatcher, FieldMatcher } from './types';
import { RawRule } from './RawRule';
declare type Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;
export interface RuleOptions<Conditions> {
conditionsMatcher?: ConditionsMatcher<Conditions>;
fieldMatcher?: FieldMatcher;
resolveAction(action: string | string[]): string | string[];
}
export declare class Rule<A extends Abilities, C> {
private _matchConditions;
private _matchField;
private readonly _options;
readonly action: Tuple<A>[0] | Tuple<A>[0][];
readonly subject: Tuple<A>[1] | Tuple<A>[1][];
readonly inverted: boolean;
readonly conditions: C | undefined;
readonly fields: string[] | undefined;
readonly reason: string | undefined;
readonly origin: RawRule<ToAbilityTypes<A>, C>;
readonly priority: number;
constructor(rule: RawRule<ToAbilityTypes<A>, C>, options: RuleOptions<C>, priority?: number);
private _conditionsMatcher;
get ast(): import("@ucast/mongo2js").Condition<unknown> | undefined;
matchesConditions(object: Normalize<A>[1] | undefined): boolean;
matchesField(field: string | undefined): boolean;
}
export {};
+68
View File
@@ -0,0 +1,68 @@
import { Rule, RuleOptions } from './Rule';
import { RawRuleFrom } from './RawRule';
import { Abilities, Normalize, SubjectType, AbilityParameters, AbilityTuple, ExtractSubjectType } from './types';
import { LinkedItem } from './structures/LinkedItem';
export interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {
detectSubjectType?(subject: Exclude<Normalize<A>[1], SubjectType>): ExtractSubjectType<Normalize<A>[1]>;
anyAction?: string;
anySubjectType?: string;
}
export declare const ɵabilities: unique symbol;
export declare const ɵconditions: unique symbol;
interface WithGenerics {
[ɵabilities]: any;
[ɵconditions]: any;
}
export declare type Public<T extends WithGenerics> = {
[K in keyof T]: T[K];
};
export interface Generics<T extends WithGenerics> {
abilities: T[typeof ɵabilities];
conditions: T[typeof ɵconditions];
}
export declare type RuleOf<T extends WithGenerics> = Rule<Generics<T>['abilities'], Generics<T>['conditions']>;
export declare type RawRuleOf<T extends WithGenerics> = RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;
export declare type RuleIndexOptionsOf<T extends WithGenerics> = RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;
interface AbilityEvent<T extends WithGenerics> {
target: T;
/** @deprecated use "target" property instead */
ability: T;
}
export interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {
rules: RawRuleOf<T>[];
}
/**
* @deprecated `on`/`emit` properly infer type without this type
* TODO(major): delete
*/
export declare type EventHandler<Event> = (event: Event) => void;
export declare type Events<T extends WithGenerics, K extends keyof EventsMap<T> = keyof EventsMap<T>> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;
interface EventsMap<T extends WithGenerics> {
update(event: UpdateEvent<T>): void;
updated(event: UpdateEvent<T>): void;
}
export declare type Unsubscribe = () => void;
declare type AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> = AbilityParameters<T, T extends AbilityTuple ? IncludeField extends true ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0 : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0 : never, (action: Extract<T, string>) => 0>;
export declare class RuleIndex<A extends Abilities, Conditions> {
private _hasPerFieldRules;
private _events?;
private _indexedRules;
private _rules;
private readonly _ruleOptions;
private readonly _detectSubjectType;
private readonly _anyAction;
private readonly _anySubjectType;
readonly [ɵabilities]: A;
readonly [ɵconditions]: Conditions;
constructor(rules?: RawRuleFrom<A, Conditions>[], options?: RuleIndexOptions<A, Conditions>);
get rules(): (import("./types").ToAbilityTypes<A> extends infer T ? T extends import("./types").ToAbilityTypes<A> ? T extends import("./types").AbilityTupleType<string, SubjectType> ? import("./RawRule").SubjectRawRule<T[0], T[1], Conditions> : import("./RawRule").ClaimRawRule<Extract<import("./types").ToAbilityTypes<A>, string>> : never : never)[];
detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]>;
update(rules: RawRuleFrom<A, Conditions>[]): Public<this>;
private _buildIndexFor;
possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[];
rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[];
actionsFor(subjectType: ExtractSubjectType<Normalize<A>[1]>): string[];
on<T extends keyof EventsMap<this>>(event: T, handler: EventsMap<Public<this>>[T]): Unsubscribe;
private _emit;
}
export {};
+49
View File
@@ -0,0 +1,49 @@
import { Condition } from '@ucast/mongo2js';
import { PureAbility, AnyAbility } from './PureAbility';
import { RuleOf } from './RuleIndex';
import { RawRule } from './RawRule';
import { Rule } from './Rule';
import { AnyObject, SubjectType, ExtractSubjectType } from './types';
export declare type RuleToQueryConverter<T extends AnyAbility> = (rule: RuleOf<T>) => object;
export interface AbilityQuery<T = object> {
$or?: T[];
$and?: T[];
}
export declare function rulesToQuery<T extends AnyAbility>(ability: T, action: Parameters<T['rulesFor']>[0], subjectType: ExtractSubjectType<Parameters<T['rulesFor']>[1]>, convert: RuleToQueryConverter<T>): AbilityQuery | null;
export declare function rulesToAST<T extends AnyAbility>(ability: T, action: Parameters<T['rulesFor']>[0], subjectType: ExtractSubjectType<Parameters<T['rulesFor']>[1]>): Condition | null;
export declare function rulesToFields<T extends PureAbility<any, AnyObject>>(ability: T, action: Parameters<T['rulesFor']>[0], subjectType: ExtractSubjectType<Parameters<T['rulesFor']>[1]>): AnyObject;
export declare type GetRuleFields<R extends Rule<any, any>> = (rule: R) => string[];
export interface PermittedFieldsOptions<T extends AnyAbility> {
fieldsFrom: GetRuleFields<RuleOf<T>>;
}
export declare function permittedFieldsOf<T extends AnyAbility>(ability: T, action: Parameters<T['can']>[0], subject: Parameters<T['can']>[1], options: PermittedFieldsOptions<T>): string[];
export declare type PackRule<T extends RawRule<any, any>> = [
string,
string
] | [
string,
string,
T['conditions']
] | [
string,
string,
T['conditions'] | 0,
1
] | [
string,
string,
T['conditions'] | 0,
1 | 0,
string
] | [
string,
string,
T['conditions'] | 0,
1 | 0,
string | 0,
string
];
export declare type PackSubjectType<T extends SubjectType> = (type: T) => string;
export declare function packRules<T extends RawRule<any, any>>(rules: T[], packSubject?: PackSubjectType<T['subject']>): PackRule<T>[];
export declare type UnpackSubjectType<T extends SubjectType> = (type: string) => T;
export declare function unpackRules<T extends RawRule<any, any>>(rules: PackRule<T>[], unpackSubject?: UnpackSubjectType<T['subject']>): T[];
+15
View File
@@ -0,0 +1,15 @@
export declare const ɵvalue: unique symbol;
export declare type Container<T> = {
[ɵvalue]?: T;
};
export declare type Unpack<T extends Container<any>> = Exclude<T[typeof ɵvalue], undefined>;
export interface Generic<T1 = unknown, T2 = unknown, T3 = unknown, T4 = unknown> {
0: T1;
1: T2;
2: T3;
3: T4;
}
export interface GenericFactory<T1 = unknown, T2 = unknown, T3 = unknown, T4 = unknown> extends Generic<T1, T2, T3, T4> {
produce: unknown;
}
export declare type ProduceGeneric<T, U> = T extends Container<any> ? (Unpack<T> & Generic<U>)['produce'] : T;
+12
View File
@@ -0,0 +1,12 @@
export * from './Ability';
export * from './PureAbility';
export * from './AbilityBuilder';
export * from './ForbiddenError';
export * from './RawRule';
export * from './hkt';
export * from './matchers/conditions';
export * from './matchers/field';
export type { SubjectClass, SubjectType, Subject, AbilityTuple, Abilities, Normalize, IfString, AbilityParameters, CanParameters, ExtractSubjectType, InferSubjects, ForcedSubject, MatchConditions, ConditionsMatcher, MatchField, FieldMatcher, } from './types';
export type { Generics, RuleOf, RawRuleOf, UpdateEvent, EventHandler, Unsubscribe } from './RuleIndex';
export * as hkt from './hkt';
export { setSubjectType as subject, detectSubjectType, createAliasResolver, wrapArray } from './utils';
+7
View File
@@ -0,0 +1,7 @@
{
"__symbolic": "module",
"version": 4,
"metadata": {},
"origins": {},
"importAs": "@casl/ability"
}
+35
View File
@@ -0,0 +1,35 @@
import { createFactory, BuildMongoQuery, DefaultOperators } from '@ucast/mongo2js';
import { ConditionsMatcher, AnyObject } from '../types';
import { Container, GenericFactory } from '../hkt';
declare const defaultInstructions: {
$eq: import("@ucast/mongo2js").FieldInstruction<unknown, import("@ucast/mongo2js").FieldParsingContext>;
$ne: import("@ucast/mongo2js").FieldInstruction<unknown, import("@ucast/mongo2js").FieldParsingContext>;
$lt: import("@ucast/mongo2js").FieldInstruction<string | number | Date, import("@ucast/mongo2js").FieldParsingContext>;
$lte: import("@ucast/mongo2js").FieldInstruction<string | number | Date, import("@ucast/mongo2js").FieldParsingContext>;
$gt: import("@ucast/mongo2js").FieldInstruction<string | number | Date, import("@ucast/mongo2js").FieldParsingContext>;
$gte: import("@ucast/mongo2js").FieldInstruction<import("@ucast/mongo2js").Comparable, import("@ucast/mongo2js").FieldParsingContext>;
$in: import("@ucast/mongo2js").FieldInstruction<unknown[], import("@ucast/mongo2js").FieldParsingContext>;
$nin: import("@ucast/mongo2js").FieldInstruction<unknown[], import("@ucast/mongo2js").FieldParsingContext>;
$all: import("@ucast/mongo2js").FieldInstruction<unknown[], import("@ucast/mongo2js").FieldParsingContext>;
$size: import("@ucast/mongo2js").FieldInstruction<number, import("@ucast/mongo2js").FieldParsingContext>;
$regex: import("@ucast/mongo2js").FieldInstruction<string | RegExp, import("@ucast/mongo2js").RegExpFieldContext>;
$options: import("@ucast/mongo2js").FieldInstruction<unknown, import("@ucast/mongo2js").FieldParsingContext>;
$elemMatch: import("@ucast/mongo2js").FieldInstruction<(import("@ucast/mongo2js").MongoQueryFieldOperators<any> & import("@ucast/mongo2js").MongoQueryTopLevelOperators<any>) | ({
[x: string]: any;
} & import("@ucast/mongo2js").MongoQueryTopLevelOperators<any>), import("@ucast/mongo2js").ObjectQueryFieldParsingContext>;
$exists: import("@ucast/mongo2js").FieldInstruction<boolean, import("@ucast/mongo2js").FieldParsingContext>;
};
interface MongoQueryFactory extends GenericFactory {
produce: MongoQuery<this[0]>;
}
declare type MergeUnion<T, Keys extends keyof T = keyof T> = {
[K in Keys]: T[K];
};
export declare type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {
toplevel: {};
field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>;
}> & Container<MongoQueryFactory>;
declare type MongoQueryMatcherFactory = (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;
export declare const buildMongoQueryMatcher: MongoQueryMatcherFactory;
export declare const mongoQueryMatcher: import("@ucast/mongo2js").Filter;
export type { MongoQueryFieldOperators, MongoQueryTopLevelOperators, MongoQueryOperators, } from '@ucast/mongo2js';
+2
View File
@@ -0,0 +1,2 @@
import { FieldMatcher } from '../types';
export declare const fieldPatternMatcher: FieldMatcher;
@@ -0,0 +1,12 @@
export interface LinkedItem<T> {
next: LinkedItem<T> | null;
prev: LinkedItem<T> | null;
readonly value: T;
}
export declare function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']): {
value: T;
prev: LinkedItem<T> | null;
next: null;
};
export declare function unlinkItem(item: LinkedItem<any>): void;
export declare const cloneLinkedItem: <T extends LinkedItem<any>>(item: T) => T;
+46
View File
@@ -0,0 +1,46 @@
import type { Condition } from '@ucast/mongo2js';
import { Container, GenericFactory } from './hkt';
declare type Fn = (...args: any[]) => any;
export declare type AnyClass<ReturnType = any> = new (...args: any[]) => ReturnType;
declare type AnyRecord = Record<PropertyKey, any>;
export declare type AnyObject = Record<PropertyKey, unknown>;
export declare type SubjectClass<N extends string = string> = AnyClass & {
modelName?: N;
};
export declare type SubjectType = string | SubjectClass;
export declare type Subject = AnyRecord | SubjectType;
export declare type AbilityTuple<X extends string = string, Y extends Subject = Subject> = [X, Y];
export declare type Abilities = AbilityTuple | string;
export declare type ToAbilityTypes<T extends Abilities> = T extends AbilityTuple ? AbilityTupleType<T[0], ExtractSubjectType<T[1]>> : Extract<T, string>;
export declare type AbilityTupleType<T extends string = string, U extends SubjectType = SubjectType> = [T, U];
export declare type AbilityTypes = string | AbilityTupleType;
export declare type Normalize<T extends Abilities> = T extends AbilityTuple ? T : [T, string];
export declare type IfString<T, U> = T extends string ? U : never;
export declare type AbilityParameters<T extends Abilities, TupleFunction extends Fn, StringFunction extends Fn = () => 0, Else = IfString<T, Parameters<StringFunction>>> = T extends AbilityTuple ? Parameters<TupleFunction> : Else;
export declare type CanParameters<T extends Abilities, IncludeField extends boolean = true> = AbilityParameters<T, T extends AbilityTuple ? IncludeField extends true ? (action: T[0], subject: T[1], field?: string) => 0 : (action: T[0], subject: T[1]) => 0 : never, (action: Extract<T, string>) => 0>;
export declare type ExtractSubjectType<S extends Subject> = Extract<S, SubjectType> | TagName<S>;
declare type SubjectClassWithCustomName<T> = AnyClass & {
modelName: T;
};
export declare type InferSubjects<T, IncludeTagName extends boolean = false> = T | (T extends AnyClass<infer I> ? I | (IncludeTagName extends true ? T extends SubjectClassWithCustomName<infer Name> ? Name : TagName<I> : never) : TagName<T>);
export interface ForcedSubject<T> {
readonly __caslSubjectType__: T;
}
export declare type TaggedInterface<T extends string> = ForcedSubject<T> | {
readonly kind: T;
} | {
readonly __typename: T;
};
declare type TagName<T> = T extends TaggedInterface<infer U> ? U : never;
interface MatchConditionsFactory extends GenericFactory<{}> {
produce: MatchConditions<this[0]>;
}
export declare type MatchConditions<T extends {} = AnyRecord> = Container<MatchConditionsFactory> & {
(object: T): boolean;
ast?: Condition;
};
export declare type ConditionsMatcher<T> = (conditions: T) => MatchConditions;
export declare type MatchField<T extends string> = (field: T) => boolean;
export declare type FieldMatcher = <T extends string>(fields: T[]) => MatchField<T>;
export declare type AliasesMap = Record<string, string | string[]>;
export {};
+17
View File
@@ -0,0 +1,17 @@
import { AnyObject, Subject, SubjectType, ForcedSubject, AliasesMap } from './types';
export declare function wrapArray<T>(value: T[] | T): T[];
export declare function setByPath(object: AnyObject, path: string, value: unknown): void;
export declare function setSubjectType<T extends string, U extends Record<PropertyKey, any>>(type: T, object: U): U & ForcedSubject<T>;
export declare const isSubjectType: (value: unknown) => value is SubjectType;
export declare const getSubjectTypeName: (value: SubjectType) => string;
export declare function detectSubjectType(subject: Exclude<Subject, SubjectType>): string;
export declare type AliasResolverOptions = {
skipValidate?: boolean;
anyAction?: string;
};
export declare function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions): (action: string | string[]) => string[];
export declare function mergePrioritized<T extends {
priority: number;
}>(array?: T[], anotherArray?: T[]): T[];
export declare function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V): V;
export declare const identity: <T>(x: T) => T;
+2
View File
@@ -0,0 +1,2 @@
(function(r,n){"object"===typeof exports&&"undefined"!==typeof module?n(exports,require("@ucast/mongo2js")):"function"===typeof define&&define.amd?define(["exports","@ucast/mongo2js"],n):(r="undefined"!==typeof globalThis?globalThis:r||self,n((r.casl=r.casl||{},r.casl.extra={}),r.ucast.mongo2js))})(this,(function(r,n){"use strict";function e(r){return Array.isArray(r)?r:[r]}function t(r,n,e){var t=r;var u=n;if(-1!==n.indexOf(".")){var o=n.split(".");u=o.pop();t=o.reduce((function(r,n){r[n]=r[n]||{};return r[n]}),r)}t[u]=e}Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);function u(r,n,e,t){var u={};var o=r.rulesFor(n,e);for(var i=0;i<o.length;i++){var f=o[i];var a=f.inverted?"$and":"$or";if(!f.conditions)if(f.inverted)break;else{delete u[a];return u}else{u[a]=u[a]||[];u[a].push(t(f))}}return u.$or?u:null}function o(r){if(!r.ast)throw new Error('Ability rule "'+JSON.stringify(r)+'" does not have "ast" property. So, cannot be used to generate AST');return r.inverted?new n.CompoundCondition("not",[r.ast]):r.ast}function i(r,e,t){var i=u(r,e,t,o);if(null===i)return null;if(!i.$and)return i.$or?n.buildOr(i.$or):n.buildAnd([]);if(i.$or)i.$and.push(n.buildOr(i.$or));return n.buildAnd(i.$and)}function f(r,n,e){return r.rulesFor(n,e).reduce((function(r,n){if(n.inverted||!n.conditions)return r;return Object.keys(n.conditions).reduce((function(r,e){var u=n.conditions[e];if(!u||u.constructor!==Object)t(r,e,u);return r}),r)}),{})}function a(r,n,e,t){var u=r.detectSubjectType(e);var o=r.possibleRulesFor(n,u);var i=new Set;var f=i.delete.bind(i);var a=i.add.bind(i);var c=o.length;while(c--){var v=o[c];if(v.matchesConditions(e)){var l=v.inverted?f:a;t.fieldsFrom(v).forEach(l)}}return Array.from(i)}var c=function r(n){return Array.isArray(n)?n.join(","):n};function v(r,n){return r.map((function(r){var t=[c(r.action||r.actions),"function"===typeof n?e(r.subject).map(n).join(","):c(r.subject),r.conditions||0,r.inverted?1:0,r.fields?c(r.fields):0,r.reason||""];while(t.length>0&&!t[t.length-1])t.pop();return t}))}function l(r,n){return r.map((function(r){var e=r[0],t=r[1],u=r[2],o=r[3],i=r[4],f=r[5];var a=t.split(",");var c={inverted:!!o,action:e.split(","),subject:"function"===typeof n?a.map(n):a};if(u)c.conditions=u;if(i)c.fields=i.split(",");if(f)c.reason=f;return c}))}r.packRules=v;r.permittedFieldsOf=a;r.rulesToAST=i;r.rulesToFields=f;r.rulesToQuery=u;r.unpackRules=l;Object.defineProperty(r,"__esModule",{value:true})}));
//# sourceMappingURL=extra.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"extra.js","sources":["../../src/utils.ts","../../src/extra.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 hasOwnProperty = (Object as any).hasOwn\n || Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);\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 (!hasOwnProperty(object, 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 (hasOwnProperty(subject, TYPE_FIELD)) {\n return subject[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 (hasOwnProperty(aliasMap, 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 }\nLine truncated
+2
View File
@@ -0,0 +1,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,a(n.key),n)}}function n(t,r,n){if(r)i(t.prototype,r);if(n)i(t,n);Object.defineProperty(t,"prototype",{writable:false});return t}function e(){e=Object.assign?Object.assign.bind():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?Object.setPrototypeOf.bind():function t(r,i){r.__proto__=i;return r};return o(t,r)}function f(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function s(t,r){if("object"!==typeof t||null===t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var n=i.call(t,r||"default");if("object"!==typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}function a(t){var r=s(t,"string");return"symbol"===typeof r?r:String(r)}function c(t){return Array.isArray(t)?t:[t]}var h=Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);var v="__caslSubjectType__";function l(t,r){if(r)if(!h(r,v))Object.defineProperty(r,v,{value:t});else if(t!==r[v])throw new Error("Trying to cast object to subject type "+t+" but previously it was casted to "+r[v]);return r}var d=function t(r){var i=typeof r;return"string"===i||"function"===i};var b=function t(r){return r.modelName||r.name};var y=function t(r){return"string"===typeof r?r:b(r)};function p(t){if(h(t,v))return t[v];return b(t.constructor)}function w(t,r,i){var n=c(r);var e=0;while(e<n.length){var u=n[e++];if(h(t,u))n=i(n,t[u])}return n}function g(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 j=function t(r,i){return r.concat(i)};function A(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=g(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++)w(t,i[e],n)}function E(t,r){if(!r||false!==r.skipValidate)A(t,r&&r.anyAction||"manage");return function(r){return w(t,r,j)}}function m(t,r,i){for(var n=i;n<r.length;n++)t.push(r[n])}function M(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++}m(e,t,i);m(e,r,n);return e}function $(t,r,i){var n=t.get(r);if(!n){n=i();t.set(r,n)}return n}var O=function t(r){return r};function x(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 _=function(){function t(t,r,i){if(void 0===i)i=0;x(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.origin=t;this.fields=t.fields?c(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||d(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 F(t,r){var i={value:t,prev:r,next:null};if(r)r.next=i;return i}function S(t){if(t.next)t.next.prev=t.prev;if(t.prev)t.prev.next=t.next;t.next=t.prev=null}var T=function t(r){return{value:r.value,prev:r.prev,next:r.next}};var C=function t(){return{rules:[],merged:false}};var P=function t(){return new Map};var R=function(){function t(t,r){if(void 0===t)t=[];if(void 0===r)r={};this.h=false;this.v={conditionsMatcher:r.conditionsMatcher,fieldMatcher:r.fieldMaLine truncated
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,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 hasOwnProperty = (Object as any).hasOwn\n || Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);\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 (!hasOwnProperty(object, 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 (hasOwnProperty(subject, TYPE_FIELD)) {\n return subject[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 (hasOwnProperty(aliasMap, 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[]Line truncated