Skip to content

Commit

Permalink
feat(ability): removes deprecated methods
Browse files Browse the repository at this point in the history
`ability.throwUnlessCan(...args)` is now replaced with `ForbiddenError.from(ability).throwUnlessCan(...args)`.

Fixes #257 BREAKING CHANGES
  • Loading branch information
stalniy committed Feb 4, 2020
1 parent f9e8add commit 8d358a0
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 29 deletions.
26 changes: 7 additions & 19 deletions packages/casl-ability/src/ability.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ForbiddenError from './error';
import Rule from './rule';
import { RawRule } from './RawRule';
import { wrapArray, getSubjectName, clone } from './utils';
Expand Down Expand Up @@ -98,23 +97,22 @@ export class Ability {
return this;
}

const payload: UpdateEvent = { rules, ability: this };
const event: UpdateEvent = { rules, ability: this };

this._emit('update', payload);
this._emit('update', event);
this[PRIVATE_FIELD].originalRules = rules.slice(0);
this[PRIVATE_FIELD].mergedRules = Object.create(null);

const index = this.buildIndexFor(rules);

if (process.env.NODE_ENV !== 'production' && index.isAllInverted && rules.length) {
if (index.isAllInverted) {
// eslint-disable-next-line
console.warn('[casl]: Ability contains only inverted rules. That means user will not be able to do any actions. This will be changed to Error throw in the next major version')
console.warn('Make sure your ability has allowable rules, not only inverted ones. Otherwise `ability.can` will always return `false`.');
}

this[PRIVATE_FIELD].indexedRules = index.rules;
this[PRIVATE_FIELD].hasPerFieldRules = index.hasPerFieldRules;

this._emit('updated', payload);
this._emit('updated', event);

return this;
}
Expand Down Expand Up @@ -150,7 +148,7 @@ export class Ability {
}

return {
isAllInverted,
isAllInverted: isAllInverted && rules.length > 0,
hasPerFieldRules,
rules: indexedRules,
};
Expand All @@ -174,8 +172,7 @@ export class Ability {

can(action: string, subject: AbilitySubject, field?: string): boolean {
if (field && typeof field !== 'string') {
// eslint-disable-next-line
throw new Error('Ability.can expects 3rd parameter to be a string. See https://stalniy.github.io/casl/abilities/2017/07/21/check-abilities.html#checking-fields for details')
throw new Error('Ability.can expects 3rd parameter to be a string. See https://stalniy.github.io/casl/abilities/2017/07/21/check-abilities.html#checking-fields for details');
}

const rule = this.relevantRuleFor(action, subject, field);
Expand Down Expand Up @@ -238,15 +235,6 @@ export class Ability {
return !this.can(...args);
}

throwUnlessCan(...args: CanArgsType) {
// eslint-disable-next-line
console.warn(`
Ability.throwUnlessCan is deprecated and will be removed in 4.x version.
Please use "ForbiddenError.from(ability).throwUnlessCan(...)" instead.
`.trim());
ForbiddenError.from(this).throwUnlessCan(...args);
}

on(event: 'update' | 'updated', handler: EventHandler<UpdateEvent>): Unsubscribe;
on<T extends AbilityEvent>(event: string, handler: EventHandler<T>): Unsubscribe {
const { events } = this[PRIVATE_FIELD];
Expand Down
15 changes: 5 additions & 10 deletions packages/casl-ability/src/error.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AbilitySubject, GetSubjectName } from './types';
import Rule from './rule';
import { Ability } from './ability';
import { AbilitySubject } from './types';

export type GetErrorMessage = (error: ForbiddenError) => string;

Expand All @@ -13,22 +13,17 @@ type ForbiddenErrorMeta = {
subjectName: string
};

interface AbilityLike {
relevantRuleFor(action: string, subject: AbilitySubject, field?: string): Rule | null;
subjectName: GetSubjectName
}

interface ForbiddenErrorType {
(this: ForbiddenError, message: string, options?: ForbiddenErrorMeta): void
from: (ability: AbilityLike) => ForbiddenError
from: (ability: Ability) => ForbiddenError
setDefaultMessage(messageOrFn: string | GetErrorMessage): void
}

type ExtendedError = Error & ForbiddenErrorMeta;

interface ForbiddenError extends ExtendedError {
_customMessage: string | null
_ability?: AbilityLike
_ability?: Ability

setMessage(message: string | null): this
throwUnlessCan(action: string, subject: AbilitySubject, field?: string): void
Expand Down Expand Up @@ -60,7 +55,7 @@ const ForbiddenError: ForbiddenErrorType = Object.assign(
}
},

from(ability: AbilityLike): ForbiddenError {
from(ability: Ability): ForbiddenError {
const error = new (this as any)('');
Object.defineProperty(error, '_ability', { value: ability });
return error;
Expand Down

0 comments on commit 8d358a0

Please sign in to comment.