@via-profit/ability 3.0.1 → 3.1.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.
@@ -0,0 +1,8 @@
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
+ }
@@ -0,0 +1,12 @@
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
+ }
@@ -0,0 +1,21 @@
1
+ import AbilityCode from './AbilityCode';
2
+ export type AbilityConditionCodeType = '=' | '<>' | '>' | '<' | '>=' | '<=' | 'in' | 'not in' | 'contains' | 'not contains' | 'length greater than' | 'length less than' | 'length equals';
3
+ export type AbilityConditionLiteralType = 'equals' | 'not_equals' | 'contains' | 'no_contains' | 'in' | 'not_in' | 'greater_than' | 'less_than' | 'less_or_equal' | 'greater_or_equal' | 'length_greater_than' | 'length_less_than' | 'length_equals';
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 fromLiteral(literal: AbilityConditionLiteralType): AbilityCondition;
19
+ get literal(): AbilityConditionLiteralType;
20
+ }
21
+ export default AbilityCondition;
@@ -1,7 +1,7 @@
1
1
  import AbilityRule from './AbilityRule';
2
- import AbilityRuleSet from '~/AbilityRuleSet';
3
- import AbilityPolicy from '~/AbilityPolicy';
4
- import AbilityMatch from '~/AbilityMatch';
2
+ import AbilityRuleSet from '../core/AbilityRuleSet';
3
+ import AbilityPolicy from '../core/AbilityPolicy';
4
+ import AbilityMatch from '../core/AbilityMatch';
5
5
  export type AbilityExplainConfig = {
6
6
  readonly type: AbilityExplainType;
7
7
  readonly name: string;
@@ -3,6 +3,8 @@ export type Primitive = string | number | boolean | null | undefined;
3
3
  export type NestedDict<T = Primitive> = {
4
4
  [key: string]: NestedDict<T> | T;
5
5
  };
6
+ export type ResourceObject = Record<string, unknown>;
7
+ export type ResourcesMap = Record<string, ResourceObject>;
6
8
  export declare class AbilityParser {
7
9
  /**
8
10
  * Sets a value in a nested object structure based on a dot/bracket notation path.
@@ -2,9 +2,10 @@ import AbilityRuleSet, { AbilityRuleSetConfig } from './AbilityRuleSet';
2
2
  import AbilityMatch from './AbilityMatch';
3
3
  import AbilityCompare, { AbilityCompareCodeType } from './AbilityCompare';
4
4
  import AbilityPolicyEffect, { AbilityPolicyEffectCodeType } from './AbilityPolicyEffect';
5
- import { AbilityExplain } from '~/AbilityExplain';
5
+ import { AbilityExplain } from './AbilityExplain';
6
+ import { ResourceObject } from './AbilityParser';
6
7
  export type AbilityPolicyConfig = {
7
- readonly action: string;
8
+ readonly permission: string;
8
9
  readonly effect: AbilityPolicyEffectCodeType;
9
10
  readonly compareMethod: AbilityCompareCodeType;
10
11
  readonly ruleSet: readonly AbilityRuleSetConfig[];
@@ -14,16 +15,16 @@ export type AbilityPolicyConfig = {
14
15
  export type AbilityPolicyConstructorProps = {
15
16
  id: string;
16
17
  name: string;
17
- action: string;
18
+ permission: string;
18
19
  effect: AbilityPolicyEffect;
19
20
  compareMethod?: AbilityCompare;
20
21
  };
21
- export declare class AbilityPolicy<Resources extends object = object> {
22
+ export declare class AbilityPolicy<Resource extends ResourceObject = Record<string, unknown>, Environment = unknown> {
22
23
  matchState: AbilityMatch;
23
24
  /**
24
25
  * List of rules
25
26
  */
26
- ruleSet: AbilityRuleSet[];
27
+ ruleSet: AbilityRuleSet<Resource, Environment>[];
27
28
  /**
28
29
  * Policy effect
29
30
  */
@@ -45,31 +46,39 @@ export declare class AbilityPolicy<Resources extends object = object> {
45
46
  id: string;
46
47
  /**
47
48
  * Running the `enforce` or `resolve` method
48
- * will select only those from all passed policies that fall under the specified action.
49
+ * will select only those from all passed policies that fall under the specified permission key.
49
50
  */
50
- action: string;
51
+ permission: string;
51
52
  constructor(params: AbilityPolicyConstructorProps);
52
53
  /**
53
54
  * Add rule set to the policy
54
55
  * @param ruleSet - The rule set to add
55
56
  */
56
- addRuleSet(ruleSet: AbilityRuleSet): this;
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;
57
63
  /**
58
64
  * Check if the policy is matched
59
- * @param resources - The resource to check
65
+ * @param resource - The resource to check
66
+ * @param environment - The user environment object
60
67
  */
61
- check(resources: Resources): AbilityMatch;
68
+ check(resource: Resource, environment?: Environment): Promise<AbilityMatch>;
62
69
  explain(): AbilityExplain;
63
70
  /**
64
71
  * Parses an array of policy configurations into an array of AbilityPolicy instances.
65
72
  * @param configs - Array of policy configurations
66
73
  * @returns Array of AbilityPolicy instances
67
74
  */
68
- static parseAll<Resources extends object = object>(configs: readonly AbilityPolicyConfig[]): AbilityPolicy<Resources>[];
75
+ static fromJSONAll<Resource extends ResourceObject, Environment = unknown>(configs: readonly AbilityPolicyConfig[]): AbilityPolicy<Resource, Environment>[];
69
76
  /**
70
77
  * Parse the config JSON format to Policy class instance
71
78
  */
72
- static parse<Resources extends object = object>(config: AbilityPolicyConfig): AbilityPolicy<Resources>;
73
- export(): AbilityPolicyConfig;
79
+ static fromJSON<Resource extends ResourceObject = Record<string, unknown>, Environment = unknown>(config: AbilityPolicyConfig): AbilityPolicy<Resource, Environment>;
80
+ static fromDSL<Resource extends ResourceObject = Record<string, unknown>, Environment = unknown>(dsl: string): AbilityPolicy<Resource, Environment>;
81
+ toJSON(): AbilityPolicyConfig;
82
+ toString(): string;
74
83
  }
75
84
  export default AbilityPolicy;
@@ -0,0 +1,35 @@
1
+ import AbilityPolicy from './AbilityPolicy';
2
+ import { AbilityResult } from './AbilityResult';
3
+ import { ResourcesMap } from './AbilityParser';
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;
@@ -0,0 +1,27 @@
1
+ import { AbilityExplain } from './AbilityExplain';
2
+ import { ResourceObject } from './AbilityParser';
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
+ }
@@ -0,0 +1,77 @@
1
+ import AbilityMatch from './AbilityMatch';
2
+ import AbilityCondition, { AbilityConditionCodeType } from './AbilityCondition';
3
+ export type AbilityRuleConfig = {
4
+ readonly id?: string | null;
5
+ readonly name?: string | null;
6
+ /**
7
+ * Subject key path like a 'user.name'
8
+ */
9
+ readonly subject: string;
10
+ /**
11
+ * Resource key path like a 'user.name' or value
12
+ */
13
+ readonly resource: string | number | boolean | null | (string | number | boolean | null)[];
14
+ readonly condition: AbilityConditionCodeType;
15
+ };
16
+ export type AbilityRuleConstructorProps = Omit<AbilityRuleConfig, 'condition'> & {
17
+ readonly condition: AbilityCondition;
18
+ };
19
+ /**
20
+ * Represents a rule that defines a condition to be checked against a subject and resource.
21
+ */
22
+ export declare class AbilityRule<Resources extends object = object, Environment = unknown> {
23
+ /**
24
+ * Subject key path like a 'user.name'
25
+ */
26
+ subject: string;
27
+ /**
28
+ * Resource key path like a 'user.name' or value
29
+ */
30
+ resource: AbilityRuleConfig['resource'];
31
+ condition: AbilityCondition;
32
+ name: string;
33
+ id: string;
34
+ state: AbilityMatch;
35
+ /**
36
+ * Creates an instance of AbilityRule.
37
+ * @param {string} params.id - The unique identifier of the rule.
38
+ * @param {string} params.name - The name of the rule.
39
+ * @param {AbilityCondition} params.condition - The condition to evaluate.
40
+ * @param {string} params.subject - The subject of the rule.
41
+ * @param {string} params.resource - The resource to compare against.
42
+ * @param params
43
+ */
44
+ constructor(params: AbilityRuleConstructorProps);
45
+ /**
46
+ * Check if the rule is matched
47
+ * @param resource - The resource to check
48
+ * @param environment
49
+ */
50
+ check(resource: Resources | null, environment?: Environment): Promise<AbilityMatch>;
51
+ /**
52
+ * Extract values from the resourceData
53
+ * @param resourceData - The resourceData to extract values from
54
+ * @param environment - Environment data
55
+ */
56
+ extractValues(resourceData: Resources | null, environment?: Environment | null): [AbilityRuleConfig['resource'] | undefined, AbilityRuleConfig['resource'] | undefined];
57
+ /**
58
+ * Get the value of the object by dot notation
59
+ * @param resource - The object to get the value from
60
+ * @param desc - The dot notation string
61
+ */
62
+ getDotNotationValue<T = unknown>(resource: unknown, desc: string): T | undefined;
63
+ toString(): string;
64
+ static fromJSON<Resources extends object, Environment = unknown>(config: AbilityRuleConfig): AbilityRule<Resources, Environment>;
65
+ static equals<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
66
+ static notEquals<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
67
+ static contains<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
68
+ static notContains<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
69
+ static notIn<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
70
+ static in<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
71
+ static notEqual<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
72
+ static lessThan<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
73
+ static lessOrEqual<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
74
+ static moreThan<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
75
+ static moreOrEqual<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
76
+ }
77
+ export default AbilityRule;
@@ -1,6 +1,7 @@
1
1
  import AbilityRule, { AbilityRuleConfig } from './AbilityRule';
2
2
  import AbilityCompare, { AbilityCompareCodeType } from './AbilityCompare';
3
3
  import AbilityMatch from './AbilityMatch';
4
+ import { ResourceObject } from './AbilityParser';
4
5
  export type AbilityRuleSetConfig = {
5
6
  readonly id?: string | null;
6
7
  readonly name?: string | null;
@@ -12,12 +13,12 @@ export type AbilityRuleSetConstructorProps = {
12
13
  readonly name?: string | null;
13
14
  readonly compareMethod: AbilityCompare;
14
15
  };
15
- export declare class AbilityRuleSet<Resources extends object = object> {
16
+ export declare class AbilityRuleSet<Resources extends ResourceObject = Record<string, unknown>, Environment = unknown> {
16
17
  state: AbilityMatch;
17
18
  /**
18
19
  * List of rules
19
20
  */
20
- rules: AbilityRule[];
21
+ rules: AbilityRule<Resources, Environment>[];
21
22
  /**
22
23
  * Rules compare method.\
23
24
  * For the «and» method the rule will be permitted if all\
@@ -34,15 +35,15 @@ export declare class AbilityRuleSet<Resources extends object = object> {
34
35
  */
35
36
  id: string;
36
37
  constructor(params: AbilityRuleSetConstructorProps);
37
- addRule(rule: AbilityRule): this;
38
- addRules(rules: AbilityRule[]): this;
39
- check(resources: Resources | null): AbilityMatch;
38
+ addRule(rule: AbilityRule<Resources, Environment>): this;
39
+ addRules(rules: AbilityRule<Resources, Environment>[]): this;
40
+ check(resources: Resources | null, environment?: Environment): Promise<AbilityMatch>;
41
+ toString(): string;
40
42
  /**
41
43
  * Parse the config JSON format to Group class instance
42
44
  */
43
- static parse<Resource extends object = object>(config: AbilityRuleSetConfig): AbilityRuleSet<Resource>;
44
- export(): AbilityRuleSetConfig;
45
- static and(rules: AbilityRule[]): AbilityRuleSet<object>;
46
- static or(rules: AbilityRule[]): AbilityRuleSet<object>;
45
+ static fromJSON<Resource extends ResourceObject = Record<string, unknown>, Environment = unknown>(config: AbilityRuleSetConfig): AbilityRuleSet<Resource, Environment>;
46
+ static and(rules: AbilityRule[]): AbilityRuleSet<Record<string, unknown>, unknown>;
47
+ static or(rules: AbilityRule[]): AbilityRuleSet<Record<string, unknown>, unknown>;
47
48
  }
48
49
  export default AbilityRuleSet;
package/dist/index.d.ts CHANGED
@@ -1,12 +1,19 @@
1
- export * from './AbilityCode';
2
- export * from './AbilityCompare';
3
- export * from './AbilityCondition';
4
- export * from './AbilityError';
5
- export * from './AbilityMatch';
6
- export * from './AbilityParser';
7
- export * from './AbilityPolicy';
8
- export * from './AbilityPolicyEffect';
9
- export * from './AbilityResolver';
10
- export * from './AbilityRule';
11
- export * from './AbilityRuleSet';
12
- export * from './AbilityExplain';
1
+ export * from './core/AbilityCode';
2
+ export * from './core/AbilityCompare';
3
+ export * from './core/AbilityCondition';
4
+ export * from './core/AbilityError';
5
+ export * from './core/AbilityMatch';
6
+ export * from './core/AbilityParser';
7
+ export * from './core/AbilityPolicy';
8
+ export * from './core/AbilityPolicyEffect';
9
+ export * from './core/AbilityResolver';
10
+ export * from './core/AbilityRule';
11
+ export * from './core/AbilityRuleSet';
12
+ export * from './core/AbilityExplain';
13
+ export * from './core/AbilityResult';
14
+ export * from './cache/AbilityCacheAdapter';
15
+ export * from './cache/AbilityInMemoryCache';
16
+ export * from './parsers/json/AbilityJSONParser';
17
+ export * from './parsers/dsl/AbilityDSLParser';
18
+ export * from './parsers/dsl/AbilityDSLLexer';
19
+ export * from './parsers/dsl/AbilityDSLToken';