@via-profit/ability 3.4.1 → 3.5.1

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;
@@ -346,7 +364,11 @@ class AbilityExplain {
346
364
  toString(indent = 0) {
347
365
  const pad = ' '.repeat(indent);
348
366
  const mark = this.match.code === AbilityMatch.match.code ? '✓' : '✗';
349
- let out = `${pad}${mark} ${this.type} «${this.name}» is ${this.match.code}`;
367
+ let out = '';
368
+ if (this.type === 'policy') {
369
+ out += '\n';
370
+ }
371
+ out += `${pad}${mark} ${this.type} «${this.name}» is ${this.match.code}`;
350
372
  this.children.forEach(child => {
351
373
  out += '\n' + child.toString(indent + 1);
352
374
  });
@@ -444,14 +466,14 @@ class AbilityPolicy {
444
466
  * @param resource - The resource to check
445
467
  * @param environment - The user environment object
446
468
  */
447
- async check(resource, environment) {
469
+ check(resource, environment) {
448
470
  this.matchState = AbilityMatch.mismatch;
449
471
  if (!this.ruleSet.length) {
450
472
  return this.matchState;
451
473
  }
452
474
  const rulesetCheckStates = [];
453
475
  for (const ruleSet of this.ruleSet) {
454
- const state = await ruleSet.check(resource, environment);
476
+ const state = ruleSet.check(resource, environment);
455
477
  rulesetCheckStates.push(state);
456
478
  if (AbilityCompare.and.isEqual(this.compareMethod) && AbilityMatch.mismatch.isEqual(state)) {
457
479
  return this.matchState; // mismatch
@@ -500,6 +522,12 @@ class AbilityPolicyEffect extends AbilityCode {
500
522
  static permit = new AbilityPolicyEffect('permit');
501
523
  }
502
524
 
525
+ class AbilityResultState extends AbilityCode {
526
+ static allow = new AbilityResultState('allow');
527
+ static deny = new AbilityResultState('deny');
528
+ static neutral = new AbilityResultState('neutral');
529
+ }
530
+
503
531
  class AbilityResult {
504
532
  /**
505
533
  * Already checked policies (after call the policy.check())
@@ -527,40 +555,38 @@ class AbilityResult {
527
555
  }
528
556
  return null;
529
557
  }
530
- isAllowed() {
531
- const effect = this.getLastEffectOfMatchedPolicy();
532
- return effect?.isEqual(AbilityPolicyEffect.permit) ?? false;
533
- }
534
- isDenied() {
535
- const effect = this.getLastEffectOfMatchedPolicy();
536
- return effect?.isEqual(AbilityPolicyEffect.deny) ?? true;
537
- }
538
- /**
539
- * Get the last effect of the policy
540
- *
541
- * @returns {AbilityPolicyEffect | null}
542
- */
543
- getLastEffectOfMatchedPolicy() {
544
- for (let i = this.policies.length - 1; i >= 0; i--) {
545
- const p = this.policies[i];
558
+ getFinalState() {
559
+ let state = AbilityResultState.neutral;
560
+ for (const p of this.policies) {
546
561
  if (p.matchState.isEqual(AbilityMatch.match)) {
547
- return p.effect;
562
+ if (p.effect.isEqual(AbilityPolicyEffect.permit)) {
563
+ state = AbilityResultState.allow;
564
+ }
565
+ else if (p.effect.isEqual(AbilityPolicyEffect.deny)) {
566
+ state = AbilityResultState.deny;
567
+ }
568
+ }
569
+ else if (p.matchState.isEqual(AbilityMatch.mismatch)) {
570
+ state = AbilityResultState.neutral;
548
571
  }
549
572
  }
550
- return null;
573
+ return state;
574
+ }
575
+ isAllowed() {
576
+ return this.getFinalState().isEqual(AbilityResultState.allow);
577
+ }
578
+ isDenied() {
579
+ return this.getFinalState().isNotEqual(AbilityResultState.allow);
551
580
  }
552
581
  }
553
582
 
554
583
  class AbilityResolver {
555
584
  policies;
556
- cache;
557
585
  constructor(
558
586
  /**
559
587
  * `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
588
  */
561
- policyOrListOfPolicies, options) {
562
- const { cache } = options || {};
563
- this.cache = cache;
589
+ policyOrListOfPolicies) {
564
590
  this.policies = Array.isArray(policyOrListOfPolicies)
565
591
  ? policyOrListOfPolicies
566
592
  : [policyOrListOfPolicies];
@@ -572,30 +598,18 @@ class AbilityResolver {
572
598
  * @param resource - Resource
573
599
  * @param environment
574
600
  */
575
- async resolve(permission, resource, environment) {
601
+ resolve(permission, resource, environment) {
576
602
  const filteredPolicies = this.policies.filter(policy => AbilityResolver.isInPermissionContain(policy.permission, String(permission).replace(/^permission\./, '')));
577
603
  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);
604
+ const policyMatchState = policy.check(resource, environment);
588
605
  if (policyMatchState === AbilityMatch.pending) {
589
606
  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
607
  }
591
- if (this.cache) {
592
- await this.cache.set(cacheKey, policyMatchState);
593
- }
594
608
  }
595
609
  return new AbilityResult(filteredPolicies);
596
610
  }
597
- async enforce(permission, resource, environment) {
598
- const result = await this.resolve(permission, resource, environment);
611
+ enforce(permission, resource, environment) {
612
+ const result = this.resolve(permission, resource, environment);
599
613
  if (result.isDenied()) {
600
614
  const lastPolicy = result.getLastMatchedPolicy();
601
615
  if (lastPolicy) {
@@ -618,18 +632,6 @@ class AbilityResolver {
618
632
  return chunk === '*' || longer[i] === '*' || chunk === longer[i];
619
633
  });
620
634
  }
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
635
  }
634
636
 
635
637
  /**
@@ -776,7 +778,7 @@ class AbilityRule {
776
778
  * @param resource - The resource to check
777
779
  * @param environment
778
780
  */
779
- async check(resource, environment) {
781
+ check(resource, environment) {
780
782
  const [subjectValue, resourceValue] = this.extractValues(resource, environment);
781
783
  const handler = this.operatorHandlers[this.condition.literal];
782
784
  const result = handler(subjectValue, resourceValue);
@@ -979,14 +981,14 @@ class AbilityRuleSet {
979
981
  rules.forEach(rule => this.addRule(rule));
980
982
  return this;
981
983
  }
982
- async check(resources, environment) {
984
+ check(resources, environment) {
983
985
  this.state = AbilityMatch.mismatch;
984
986
  if (!this.rules.length) {
985
987
  return this.state;
986
988
  }
987
989
  const ruleCheckStates = [];
988
990
  for (const rule of this.rules) {
989
- const state = await rule.check(resources, environment);
991
+ const state = rule.check(resources, environment);
990
992
  ruleCheckStates.push(state);
991
993
  if (AbilityCompare.and.isEqual(this.compareMethod) && AbilityMatch.mismatch.isEqual(state)) {
992
994
  return this.state; // mismatch
@@ -1035,79 +1037,6 @@ class AbilityRuleSet {
1035
1037
  }
1036
1038
  }
1037
1039
 
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
1040
  class AbilityJSONParser {
1112
1041
  /**
1113
1042
  * Parses an array of policy configurations into an array of AbilityPolicy instances.
@@ -2185,9 +2114,7 @@ class AbilityDSLParser {
2185
2114
  return best;
2186
2115
  }
2187
2116
  levenshteinDistance(a, b) {
2188
- const matrix = Array(b.length + 1)
2189
- .fill(null)
2190
- .map(() => Array(a.length + 1).fill(null));
2117
+ const matrix = Array.from({ length: b.length + 1 }, () => Array.from({ length: a.length + 1 }, () => 0));
2191
2118
  for (let i = 0; i <= a.length; i++)
2192
2119
  matrix[0][i] = i;
2193
2120
  for (let j = 0; j <= b.length; j++)
@@ -2262,7 +2189,6 @@ exports.AbilityExplain = AbilityExplain;
2262
2189
  exports.AbilityExplainPolicy = AbilityExplainPolicy;
2263
2190
  exports.AbilityExplainRule = AbilityExplainRule;
2264
2191
  exports.AbilityExplainRuleSet = AbilityExplainRuleSet;
2265
- exports.AbilityInMemoryCache = AbilityInMemoryCache;
2266
2192
  exports.AbilityJSONParser = AbilityJSONParser;
2267
2193
  exports.AbilityMatch = AbilityMatch;
2268
2194
  exports.AbilityParserError = AbilityParserError;
@@ -2270,6 +2196,7 @@ exports.AbilityPolicy = AbilityPolicy;
2270
2196
  exports.AbilityPolicyEffect = AbilityPolicyEffect;
2271
2197
  exports.AbilityResolver = AbilityResolver;
2272
2198
  exports.AbilityResult = AbilityResult;
2199
+ exports.AbilityResultState = AbilityResultState;
2273
2200
  exports.AbilityRule = AbilityRule;
2274
2201
  exports.AbilityRuleSet = AbilityRuleSet;
2275
2202
  exports.AbilityTypeGenerator = AbilityTypeGenerator;
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.1",
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;