@via-profit/ability 3.4.1 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -130,7 +130,7 @@ class AbilityCondition extends AbilityCode {
130
130
  case 'never':
131
131
  return 'never';
132
132
  default:
133
- throw new Error(`Unknown condition code: ${this.code}`);
133
+ throw new Error(`Unknown condition code: ${String(this.code)}`);
134
134
  }
135
135
  }
136
136
  }
@@ -167,8 +167,11 @@ class AbilityTypeGenerator {
167
167
  const subjectPath = rule.subject;
168
168
  const existingType = typeStructure[action][subjectPath];
169
169
  const ruleType = this.determineTypeFromRule(rule);
170
- // If a type already exists for this path, create a union
170
+ if (!ruleType) {
171
+ return;
172
+ }
171
173
  if (existingType && existingType !== ruleType) {
174
+ // If a type already exists for this path, create a union
172
175
  typeStructure[action][subjectPath] = `${existingType} | ${ruleType}`;
173
176
  }
174
177
  else {
@@ -187,6 +190,10 @@ class AbilityTypeGenerator {
187
190
  * @returns TypeScript type as string
188
191
  */
189
192
  determineTypeFromRule(rule) {
193
+ if (rule.condition.isEqual(AbilityCondition.never) ||
194
+ rule.condition.isEqual(AbilityCondition.always)) {
195
+ return null;
196
+ }
190
197
  // Numeric comparisons - always number
191
198
  if (rule.condition.isEqual(AbilityCondition.greater_than) ||
192
199
  rule.condition.isEqual(AbilityCondition.less_than) ||
@@ -213,8 +220,9 @@ class AbilityTypeGenerator {
213
220
  */
214
221
  getArrayType(resource) {
215
222
  if (Array.isArray(resource)) {
216
- if (resource.length === 0)
223
+ if (resource.length === 0) {
217
224
  return 'any[]';
225
+ }
218
226
  // Determine types of array elements
219
227
  const elementTypes = new Set(resource.map(item => this.getPrimitiveType(item)));
220
228
  const elementType = elementTypes.size === 1
@@ -232,10 +240,12 @@ class AbilityTypeGenerator {
232
240
  * @returns TypeScript primitive type as string
233
241
  */
234
242
  getPrimitiveType(value) {
235
- if (value === null)
243
+ if (value === null) {
236
244
  return 'null';
237
- if (value === undefined)
245
+ }
246
+ if (value === undefined) {
238
247
  return 'undefined';
248
+ }
239
249
  switch (typeof value) {
240
250
  case 'string':
241
251
  return 'string';
@@ -294,12 +304,20 @@ class AbilityTypeGenerator {
294
304
  let output = '// Automatically generated by via-profit/ability\n';
295
305
  output += '// Do not edit manually\n';
296
306
  output += 'export type Resources = {\n';
297
- // Sort actions for stable output
298
307
  const sortedActions = Object.keys(structure).sort();
299
308
  sortedActions.forEach(action => {
300
- output += ` ['${action}']: {\n`;
301
- output += this.formatNestedObject(structure[action], 4);
302
- output += ' };\n';
309
+ const actionObj = structure[action];
310
+ const isEmpty = Object.keys(actionObj).length === 0;
311
+ if (isEmpty) {
312
+ // Пустой объект → undefined
313
+ output += ` ['${action}']: undefined;\n`;
314
+ }
315
+ else {
316
+ // Непустой объект → как раньше
317
+ output += ` ['${action}']: {\n`;
318
+ output += this.formatNestedObject(actionObj, 4);
319
+ output += ' };\n';
320
+ }
303
321
  });
304
322
  output += '}\n';
305
323
  return output;
@@ -444,14 +462,14 @@ class AbilityPolicy {
444
462
  * @param resource - The resource to check
445
463
  * @param environment - The user environment object
446
464
  */
447
- async check(resource, environment) {
465
+ check(resource, environment) {
448
466
  this.matchState = AbilityMatch.mismatch;
449
467
  if (!this.ruleSet.length) {
450
468
  return this.matchState;
451
469
  }
452
470
  const rulesetCheckStates = [];
453
471
  for (const ruleSet of this.ruleSet) {
454
- const state = await ruleSet.check(resource, environment);
472
+ const state = ruleSet.check(resource, environment);
455
473
  rulesetCheckStates.push(state);
456
474
  if (AbilityCompare.and.isEqual(this.compareMethod) && AbilityMatch.mismatch.isEqual(state)) {
457
475
  return this.matchState; // mismatch
@@ -553,14 +571,11 @@ class AbilityResult {
553
571
 
554
572
  class AbilityResolver {
555
573
  policies;
556
- cache;
557
574
  constructor(
558
575
  /**
559
576
  * `Important!` The incorrect Resources type was intentionally passed to AbilityPolicy so that TypeScript could suggest the name of the permission and the structure of its resource in the parse method.
560
577
  */
561
- policyOrListOfPolicies, options) {
562
- const { cache } = options || {};
563
- this.cache = cache;
578
+ policyOrListOfPolicies) {
564
579
  this.policies = Array.isArray(policyOrListOfPolicies)
565
580
  ? policyOrListOfPolicies
566
581
  : [policyOrListOfPolicies];
@@ -572,30 +587,18 @@ class AbilityResolver {
572
587
  * @param resource - Resource
573
588
  * @param environment
574
589
  */
575
- async resolve(permission, resource, environment) {
590
+ resolve(permission, resource, environment) {
576
591
  const filteredPolicies = this.policies.filter(policy => AbilityResolver.isInPermissionContain(policy.permission, String(permission).replace(/^permission\./, '')));
577
592
  for (const policy of filteredPolicies) {
578
- const cacheKey = this.cache ? this.makeCacheKey(policy.id, resource, environment) : '';
579
- // cache
580
- if (this.cache) {
581
- const cached = await this.cache.get(cacheKey);
582
- if (cached !== undefined) {
583
- policy.matchState = cached;
584
- continue;
585
- }
586
- }
587
- const policyMatchState = await policy.check(resource, environment);
593
+ const policyMatchState = policy.check(resource, environment);
588
594
  if (policyMatchState === AbilityMatch.pending) {
589
595
  throw new AbilityError(`The policy "${policy.name}" is still in a pending state. Make sure to call "check" to evaluate the policy before resolving permissions.`);
590
596
  }
591
- if (this.cache) {
592
- await this.cache.set(cacheKey, policyMatchState);
593
- }
594
597
  }
595
598
  return new AbilityResult(filteredPolicies);
596
599
  }
597
- async enforce(permission, resource, environment) {
598
- const result = await this.resolve(permission, resource, environment);
600
+ enforce(permission, resource, environment) {
601
+ const result = this.resolve(permission, resource, environment);
599
602
  if (result.isDenied()) {
600
603
  const lastPolicy = result.getLastMatchedPolicy();
601
604
  if (lastPolicy) {
@@ -618,18 +621,6 @@ class AbilityResolver {
618
621
  return chunk === '*' || longer[i] === '*' || chunk === longer[i];
619
622
  });
620
623
  }
621
- makeCacheKey(policyId, resource, environment) {
622
- if (!this.cache) {
623
- return '';
624
- }
625
- return `policy:${policyId}:res:${this.cache.serialize(resource)}:env:${this.cache.serialize(environment)}`;
626
- }
627
- async invalidatePolicy(policyId) {
628
- await this.cache?.deleteByPrefix(policyId);
629
- }
630
- async invalidateCache() {
631
- await this.cache?.clear();
632
- }
633
624
  }
634
625
 
635
626
  /**
@@ -776,7 +767,7 @@ class AbilityRule {
776
767
  * @param resource - The resource to check
777
768
  * @param environment
778
769
  */
779
- async check(resource, environment) {
770
+ check(resource, environment) {
780
771
  const [subjectValue, resourceValue] = this.extractValues(resource, environment);
781
772
  const handler = this.operatorHandlers[this.condition.literal];
782
773
  const result = handler(subjectValue, resourceValue);
@@ -979,14 +970,14 @@ class AbilityRuleSet {
979
970
  rules.forEach(rule => this.addRule(rule));
980
971
  return this;
981
972
  }
982
- async check(resources, environment) {
973
+ check(resources, environment) {
983
974
  this.state = AbilityMatch.mismatch;
984
975
  if (!this.rules.length) {
985
976
  return this.state;
986
977
  }
987
978
  const ruleCheckStates = [];
988
979
  for (const rule of this.rules) {
989
- const state = await rule.check(resources, environment);
980
+ const state = rule.check(resources, environment);
990
981
  ruleCheckStates.push(state);
991
982
  if (AbilityCompare.and.isEqual(this.compareMethod) && AbilityMatch.mismatch.isEqual(state)) {
992
983
  return this.state; // mismatch
@@ -1035,79 +1026,6 @@ class AbilityRuleSet {
1035
1026
  }
1036
1027
  }
1037
1028
 
1038
- class AbilityInMemoryCache {
1039
- store = new Map();
1040
- async get(key) {
1041
- const entry = this.store.get(key);
1042
- if (!entry)
1043
- return undefined;
1044
- if (Date.now() > entry.expires) {
1045
- this.store.delete(key);
1046
- return undefined;
1047
- }
1048
- return entry.value;
1049
- }
1050
- async set(key, value, ttlSeconds = 60) {
1051
- this.store.set(key, {
1052
- value,
1053
- expires: Date.now() + ttlSeconds * 1000,
1054
- });
1055
- }
1056
- serialize(input) {
1057
- return this.fastHash(this.stableStringify(input));
1058
- }
1059
- async delete(key) {
1060
- this.store.delete(key);
1061
- }
1062
- async clear() {
1063
- this.store.clear();
1064
- }
1065
- async deleteByPrefix(prefix) {
1066
- for (const key of this.store.keys()) {
1067
- if (key.startsWith(prefix)) {
1068
- this.store.delete(key);
1069
- }
1070
- }
1071
- }
1072
- fastHash(str) {
1073
- let hash = 5381;
1074
- for (let i = 0; i < str.length; i++) {
1075
- hash = (hash * 33) ^ str.charCodeAt(i);
1076
- }
1077
- return (hash >>> 0).toString(36);
1078
- }
1079
- stableStringify(obj) {
1080
- if (obj === null)
1081
- return 'null';
1082
- const type = typeof obj;
1083
- if (type === 'string')
1084
- return JSON.stringify(obj);
1085
- if (type === 'number' || type === 'boolean')
1086
- return String(obj);
1087
- if (type === 'undefined')
1088
- return 'undefined';
1089
- if (Array.isArray(obj)) {
1090
- let out = '[';
1091
- for (let i = 0; i < obj.length; i++) {
1092
- if (i > 0)
1093
- out += ',';
1094
- out += this.stableStringify(obj[i]);
1095
- }
1096
- return out + ']';
1097
- }
1098
- const keys = Object.keys(obj);
1099
- keys.sort();
1100
- let out = '{';
1101
- for (let i = 0; i < keys.length; i++) {
1102
- const k = keys[i];
1103
- if (i > 0)
1104
- out += ',';
1105
- out += k + ':' + this.stableStringify(obj[k]);
1106
- }
1107
- return out + '}';
1108
- }
1109
- }
1110
-
1111
1029
  class AbilityJSONParser {
1112
1030
  /**
1113
1031
  * Parses an array of policy configurations into an array of AbilityPolicy instances.
@@ -2185,9 +2103,7 @@ class AbilityDSLParser {
2185
2103
  return best;
2186
2104
  }
2187
2105
  levenshteinDistance(a, b) {
2188
- const matrix = Array(b.length + 1)
2189
- .fill(null)
2190
- .map(() => Array(a.length + 1).fill(null));
2106
+ const matrix = Array.from({ length: b.length + 1 }, () => Array.from({ length: a.length + 1 }, () => 0));
2191
2107
  for (let i = 0; i <= a.length; i++)
2192
2108
  matrix[0][i] = i;
2193
2109
  for (let j = 0; j <= b.length; j++)
@@ -2262,7 +2178,6 @@ exports.AbilityExplain = AbilityExplain;
2262
2178
  exports.AbilityExplainPolicy = AbilityExplainPolicy;
2263
2179
  exports.AbilityExplainRule = AbilityExplainRule;
2264
2180
  exports.AbilityExplainRuleSet = AbilityExplainRuleSet;
2265
- exports.AbilityInMemoryCache = AbilityInMemoryCache;
2266
2181
  exports.AbilityJSONParser = AbilityJSONParser;
2267
2182
  exports.AbilityMatch = AbilityMatch;
2268
2183
  exports.AbilityParserError = AbilityParserError;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@via-profit/ability",
3
3
  "support": "https://via-profit.ru",
4
- "version": "3.4.1",
4
+ "version": "3.5.0",
5
5
  "description": "Via-Profit Ability service",
6
6
  "keywords": [
7
7
  "ability",
@@ -43,31 +43,32 @@
43
43
  ],
44
44
  "license": "MIT",
45
45
  "devDependencies": {
46
- "@eslint/js": "^9.13.0",
46
+ "@eslint/js": "^10.0.1",
47
47
  "@jagi/jest-transform-graphql": "^1.0.2",
48
- "@jest/types": "^29.6.3",
48
+ "@jest/types": "^30.3.0",
49
49
  "@rollup/plugin-alias": "^6.0.0",
50
50
  "@rollup/plugin-commonjs": "^29.0.2",
51
51
  "@rollup/plugin-node-resolve": "^16.0.3",
52
52
  "@rollup/plugin-typescript": "^12.3.0",
53
- "@types/jest": "^29.5.13",
54
- "@types/node": "^22.7.7",
55
- "@types/nodemon": "^1.19.6",
56
- "concurrently": "^9.0.1",
57
- "cross-env": "^7.0.3",
58
- "eslint": "^9.13.0",
59
- "globals": "^15.11.0",
60
- "jest": "^29.7.0",
53
+ "@types/jest": "^30.0.0",
54
+ "@types/node": "^25.5.0",
55
+ "concurrently": "^9.2.1",
56
+ "cross-env": "^10.1.0",
57
+ "eslint": "^10.1.0",
58
+ "eslint-plugin-jest": "^29.15.1",
59
+ "globals": "^17.4.0",
60
+ "jest": "^30.3.0",
61
61
  "jest-transform-graphql": "^2.1.0",
62
- "nodemon": "^3.1.7",
63
- "prettier": "^3.3.3",
64
- "rollup": "^4.60.0",
62
+ "nodemon": "^3.1.14",
63
+ "prettier": "^3.8.1",
64
+ "rollup": "^4.60.1",
65
65
  "rollup-plugin-copy": "^3.5.0",
66
+ "rollup-plugin-dts": "^6.4.1",
66
67
  "tinybench": "^6.0.0",
67
- "ts-jest": "^29.2.5",
68
- "ts-loader": "^9.5.1",
68
+ "ts-jest": "^29.4.9",
69
+ "ts-loader": "^9.5.4",
69
70
  "ts-node": "^10.9.2",
70
- "typescript": "^5.6.3",
71
- "typescript-eslint": "^8.10.0"
71
+ "typescript": "^6.0.2",
72
+ "typescript-eslint": "^8.58.0"
72
73
  }
73
74
  }
@@ -1,8 +0,0 @@
1
- export interface AbilityCacheAdapter {
2
- get<T = unknown>(key: string): Promise<T | undefined>;
3
- set<T = unknown>(key: string, value: T, ttlSeconds?: number): Promise<void>;
4
- serialize<T = unknown>(input: T): string;
5
- delete(key: string): Promise<void>;
6
- clear(): Promise<void>;
7
- deleteByPrefix(prefix: string): Promise<void>;
8
- }
@@ -1,12 +0,0 @@
1
- import { AbilityCacheAdapter } from '../cache/AbilityCacheAdapter';
2
- export declare class AbilityInMemoryCache implements AbilityCacheAdapter {
3
- private store;
4
- get<T>(key: string): Promise<T | undefined>;
5
- set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
6
- serialize(input: unknown): string;
7
- delete(key: string): Promise<void>;
8
- clear(): Promise<void>;
9
- deleteByPrefix(prefix: string): Promise<void>;
10
- private fastHash;
11
- private stableStringify;
12
- }
@@ -1,8 +0,0 @@
1
- export declare class AbilityCode<Code extends string | number> {
2
- _code: Code;
3
- constructor(code: Code);
4
- get code(): Code;
5
- isEqual(compareWith: AbilityCode<Code> | null): boolean;
6
- isNotEqual(compareWith: AbilityCode<Code> | null): boolean;
7
- }
8
- export default AbilityCode;
@@ -1,7 +0,0 @@
1
- import AbilityCode from './AbilityCode';
2
- export type AbilityCompareCodeType = 'and' | 'or';
3
- export declare class AbilityCompare extends AbilityCode<AbilityCompareCodeType> {
4
- static and: AbilityCompare;
5
- static or: AbilityCompare;
6
- }
7
- export default AbilityCompare;
@@ -1,23 +0,0 @@
1
- import AbilityCode from './AbilityCode';
2
- export type AbilityConditionCodeType = '=' | '<>' | '>' | '<' | '>=' | '<=' | 'in' | 'not in' | 'contains' | 'not contains' | 'length greater than' | 'length less than' | 'length equals' | 'always' | 'never';
3
- export type AbilityConditionLiteralType = 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'in' | 'not_in' | 'greater_than' | 'less_than' | 'less_or_equal' | 'greater_or_equal' | 'length_greater_than' | 'length_less_than' | 'length_equals' | 'always' | 'never';
4
- export declare class AbilityCondition extends AbilityCode<AbilityConditionCodeType> {
5
- static equals: AbilityCondition;
6
- static not_equals: AbilityCondition;
7
- static greater_than: AbilityCondition;
8
- static less_than: AbilityCondition;
9
- static less_or_equal: AbilityCondition;
10
- static greater_or_equal: AbilityCondition;
11
- static in: AbilityCondition;
12
- static not_in: AbilityCondition;
13
- static contains: AbilityCondition;
14
- static not_contains: AbilityCondition;
15
- static length_greater_than: AbilityCondition;
16
- static length_less_than: AbilityCondition;
17
- static length_equals: AbilityCondition;
18
- static always: AbilityCondition;
19
- static never: AbilityCondition;
20
- static fromLiteral(literal: AbilityConditionLiteralType): AbilityCondition;
21
- get literal(): AbilityConditionLiteralType;
22
- }
23
- export default AbilityCondition;
@@ -1,6 +0,0 @@
1
- export declare class AbilityError extends Error {
2
- constructor(message: string, options?: ErrorOptions);
3
- }
4
- export declare class AbilityParserError extends Error {
5
- constructor(message: string, options?: ErrorOptions);
6
- }
@@ -1,27 +0,0 @@
1
- import AbilityRule from './AbilityRule';
2
- import AbilityRuleSet from '../core/AbilityRuleSet';
3
- import AbilityPolicy from '../core/AbilityPolicy';
4
- import AbilityMatch from '../core/AbilityMatch';
5
- export type AbilityExplainConfig = {
6
- readonly type: AbilityExplainType;
7
- readonly name: string;
8
- readonly match: AbilityMatch;
9
- };
10
- export declare class AbilityExplain {
11
- readonly type: AbilityExplainType;
12
- readonly children: AbilityExplain[];
13
- readonly name: string;
14
- readonly match: AbilityMatch;
15
- constructor(config: AbilityExplainConfig, children?: AbilityExplain[]);
16
- toString(indent?: number): string;
17
- }
18
- export declare class AbilityExplainRule extends AbilityExplain {
19
- constructor(rule: AbilityRule);
20
- }
21
- export declare class AbilityExplainRuleSet extends AbilityExplain {
22
- constructor(ruleSet: AbilityRuleSet);
23
- }
24
- export declare class AbilityExplainPolicy extends AbilityExplain {
25
- constructor(policy: AbilityPolicy);
26
- }
27
- export type AbilityExplainType = 'policy' | 'rule' | 'ruleSet';
@@ -1,8 +0,0 @@
1
- import AbilityCode from './AbilityCode';
2
- export type AbilityMatchCodeType = 'pending' | 'match' | 'mismatch';
3
- export declare class AbilityMatch extends AbilityCode<AbilityMatchCodeType> {
4
- static pending: AbilityMatch;
5
- static match: AbilityMatch;
6
- static mismatch: AbilityMatch;
7
- }
8
- export default AbilityMatch;
@@ -1,79 +0,0 @@
1
- import AbilityRuleSet, { AbilityRuleSetConfig } from './AbilityRuleSet';
2
- import AbilityMatch from './AbilityMatch';
3
- import AbilityCompare, { AbilityCompareCodeType } from './AbilityCompare';
4
- import AbilityPolicyEffect, { AbilityPolicyEffectCodeType } from './AbilityPolicyEffect';
5
- import { AbilityExplain } from './AbilityExplain';
6
- import { ResourceObject } from './AbilityTypeGenerator';
7
- export type AbilityPolicyConfig = {
8
- readonly permission: string;
9
- readonly effect: AbilityPolicyEffectCodeType;
10
- readonly compareMethod: AbilityCompareCodeType;
11
- readonly ruleSet: readonly AbilityRuleSetConfig[];
12
- readonly id: string;
13
- readonly name: string;
14
- };
15
- export type AbilityPolicyConstructorProps = {
16
- id: string;
17
- name: string;
18
- permission: string;
19
- effect: AbilityPolicyEffect;
20
- compareMethod?: AbilityCompare;
21
- };
22
- export declare class AbilityPolicy<Resource extends ResourceObject = Record<string, unknown>, Environment = unknown> {
23
- matchState: AbilityMatch;
24
- /**
25
- * List of rules
26
- */
27
- ruleSet: AbilityRuleSet<Resource, Environment>[];
28
- /**
29
- * Policy effect
30
- */
31
- effect: AbilityPolicyEffect;
32
- /**
33
- * Rules compare method.\
34
- * For the «and» method the rule will be permitted if all\
35
- * rules will be returns «permit» status and for the «or» - if\
36
- * one of the rules returns as «permit»
37
- */
38
- compareMethod: AbilityCompare;
39
- /**
40
- * Policy name
41
- */
42
- name: string;
43
- /**
44
- * Policy ID
45
- */
46
- id: string;
47
- /**
48
- * Running the `enforce` or `resolve` method
49
- * will select only those from all passed policies that fall under the specified permission key.
50
- */
51
- permission: string;
52
- constructor(params: AbilityPolicyConstructorProps);
53
- /**
54
- * Add rule set to the policy
55
- * @param ruleSet - The rule set to add
56
- */
57
- addRuleSet(ruleSet: AbilityRuleSet<Resource, Environment>): this;
58
- /**
59
- * Add rule set to the policy
60
- * @param ruleSets - The array of rule set to add
61
- */
62
- addRuleSets(ruleSets: readonly AbilityRuleSet<Resource, Environment>[]): this;
63
- /**
64
- * Check if the policy is matched
65
- * @param resource - The resource to check
66
- * @param environment - The user environment object
67
- */
68
- check(resource: Resource, environment?: Environment): Promise<AbilityMatch>;
69
- explain(): AbilityExplain;
70
- copyWith(props: Partial<{
71
- id: string;
72
- name: string;
73
- permission: string;
74
- effect: AbilityPolicyEffect;
75
- compareMethod: AbilityCompare;
76
- ruleSet: AbilityRuleSet<Resource, Environment>[];
77
- }>): AbilityPolicy<Resource, Environment>;
78
- }
79
- export default AbilityPolicy;
@@ -1,7 +0,0 @@
1
- import AbilityCode from './AbilityCode';
2
- export type AbilityPolicyEffectCodeType = 'deny' | 'permit';
3
- export declare class AbilityPolicyEffect extends AbilityCode<AbilityPolicyEffectCodeType> {
4
- static deny: AbilityPolicyEffect;
5
- static permit: AbilityPolicyEffect;
6
- }
7
- export default AbilityPolicyEffect;
@@ -1,35 +0,0 @@
1
- import AbilityPolicy from './AbilityPolicy';
2
- import { AbilityResult } from './AbilityResult';
3
- import { ResourcesMap } from './AbilityTypeGenerator';
4
- import { AbilityCacheAdapter } from '../cache/AbilityCacheAdapter';
5
- export type AbilityResolverOptions = {
6
- readonly cache?: AbilityCacheAdapter | null;
7
- };
8
- export declare class AbilityResolver<Resources extends ResourcesMap, Environment = unknown> {
9
- private policies;
10
- private readonly cache?;
11
- constructor(
12
- /**
13
- * `Important!` The incorrect Resources type was intentionally passed to AbilityPolicy so that TypeScript could suggest the name of the permission and the structure of its resource in the parse method.
14
- */
15
- policyOrListOfPolicies: readonly AbilityPolicy<Resources>[] | AbilityPolicy<Resources>, options?: AbilityResolverOptions);
16
- /**
17
- * Resolve policy for the resource and permission key
18
- *
19
- * @param permission - Permission key
20
- * @param resource - Resource
21
- * @param environment
22
- */
23
- resolve<Permission extends keyof Resources>(permission: Permission, resource: Resources[Permission], environment?: Environment): Promise<AbilityResult<Resources[Permission]>>;
24
- enforce<Permission extends keyof Resources>(permission: Permission, resource: Resources[Permission], environment?: Environment): Promise<void | never>;
25
- /**
26
- * Check if the permission key is contained in another permission key
27
- * @param permissionA - The first permission to check
28
- * @param permissionB - The second permission to check
29
- */
30
- static isInPermissionContain(permissionA: string, permissionB: string): boolean;
31
- private makeCacheKey;
32
- invalidatePolicy(policyId: string): Promise<void>;
33
- invalidateCache(): Promise<void>;
34
- }
35
- export default AbilityResolver;
@@ -1,27 +0,0 @@
1
- import { AbilityExplain } from './AbilityExplain';
2
- import { ResourceObject } from './AbilityTypeGenerator';
3
- import AbilityPolicy from './AbilityPolicy';
4
- import AbilityPolicyEffect from './AbilityPolicyEffect';
5
- export declare class AbilityResult<Resource extends ResourceObject = Record<string, unknown>> {
6
- /**
7
- * Already checked policies (after call the policy.check())
8
- */
9
- readonly policies: readonly AbilityPolicy<Resource>[];
10
- constructor(policies: readonly AbilityPolicy<Resource>[]);
11
- /**
12
- * Returns a list of explanations for each policy involved in the ability evaluation.
13
- * Each item describes how a specific policy contributed to the final permission result.
14
- *
15
- * Useful for debugging, logging, or building UI tools that visualize permission logic.
16
- */
17
- explain(): readonly AbilityExplain[];
18
- getLastMatchedPolicy(): AbilityPolicy<Resource> | null;
19
- isAllowed(): boolean;
20
- isDenied(): boolean;
21
- /**
22
- * Get the last effect of the policy
23
- *
24
- * @returns {AbilityPolicyEffect | null}
25
- */
26
- getLastEffectOfMatchedPolicy(): AbilityPolicyEffect | null;
27
- }