Skip to content

Commit

Permalink
feat(ability): stores ast property in Rule if conditionsMatcher
Browse files Browse the repository at this point in the history
… has `ast`

Relates to #350
  • Loading branch information
stalniy committed Aug 10, 2020
1 parent 41e53aa commit 53e5e28
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
11 changes: 11 additions & 0 deletions packages/casl-ability/spec/ability.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,17 @@ describe('Ability', () => {
it('does not allow to perform action on instance field if that instance matches conditions but field is not in specified list', () => {
expect(ability).not.to.allow('read', myPost, 'id')
})

it('has rules with `ast` property', () => {
const rule = ability.relevantRuleFor('read', 'Post');

expect(rule).to.have.property('ast').that.is.an('object');
expect(rule.ast).to.deep.equal({
field: 'author',
operator: 'eq',
value: rule.conditions.author
});
})
})
})

Expand Down
3 changes: 3 additions & 0 deletions packages/casl-ability/src/Rule.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Condition } from '@ucast/mongo2js';
import { wrapArray } from './utils';
import {
MatchConditions,
Expand Down Expand Up @@ -34,6 +35,7 @@ export class Rule<A extends Abilities, C> {
public readonly conditions!: C | undefined;
public readonly fields!: string[] | undefined;
public readonly reason!: string | undefined;
public readonly ast?: Condition

constructor(rule: RawRule<ToAbilityTypes<A>, C>, options: RuleOptions<A, C>) {
validate(rule, options);
Expand All @@ -47,6 +49,7 @@ export class Rule<A extends Abilities, C> {

if (this.conditions) {
this._matchConditions = options.conditionsMatcher!(this.conditions);
this.ast = this._matchConditions.ast;
}

if (this.fields) {
Expand Down
7 changes: 6 additions & 1 deletion packages/casl-ability/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Condition } from '@ucast/mongo2js';

type Fn = (...args: any[]) => any;
type AnyClass<ReturnType = any> = new (...args: any[]) => ReturnType;
type AnyRecord = Record<PropertyKey, any>;
Expand Down Expand Up @@ -58,7 +60,10 @@ export type ForcedSubject<T> = { readonly __caslSubjectType__: T };
type TaggedInterface<T extends string> = ForcedSubject<T> | { readonly kind: T };
type TagName<T> = T extends TaggedInterface<infer U> ? U : never;

export type MatchConditions<T extends object = AnyRecord> = (object: T) => boolean;
export type MatchConditions<T extends object = AnyRecord> = {
(object: T): boolean
ast?: Condition
};
export type ConditionsMatcher<T> = (conditions: T) => MatchConditions;
export type MatchField<T extends string> = (field: T) => boolean;
export type FieldMatcher = <T extends string>(fields: T[]) => MatchField<T>;
Expand Down

0 comments on commit 53e5e28

Please sign in to comment.