CASL v5.1.0-next.2 Release Notes
Release Date: 2020-08-27 // over 3 years ago-
5.1.0-next.2 (2020-08-27)
๐ Features
- ๐ builder: improves typings for AbilityBuilder [skip release] (ebd4d17), closes #379
- ๐ builder: improves typings of
AbilityBuilder['can']
andAbilityBuilder['cannot']
methods [skip release] (98ffbfc), closes #333
๐ Performance Improvements
- events: utilizes LinkedList for storing event handlers (e2fd265)
- rules: improves merging logic of rules of subject and
manage all
(6f8a13a)
๐ฅ BREAKING CHANGES
๐ builder: changes main generic parameter to be a class instead of instance and makes
defineAbility
to accept options as the 2nd argument.Before
import { AbilityBuilder, defineAbility, Ability } from '@casl/ability';const resolveAction = (action: string) =\> {/\* custom implementation \*/ };const ability = defineAbility({ resolveAction }, (can) =\> can('read', 'Item'));const builder = new AbilityBuilder\<Ability\>(Ability);
After
import { AbilityBuilder, defineAbility, Ability } from '@casl/ability';const resolveAction = (action: string) =\> {/\* custom implementation \*/ };const ability = defineAbility((can) =\> can('read', 'Item'), { resolveAction });const builder = new AbilityBuilder(Ability); // first argument is now mandatory!
The 1st parameter to
AbilityBuilder
is now madatory. This allows to infer generic parameters from it and makes AbilityType that is built to be explicit.๐ builder:
can
andcannot
methods ofAbilityBuilder
now restricts what fields and operators can be used inside conditions (i.e.,MongoQuery
). Also these methods now suggests object fields based on passed instanceBefore
import { AbilityBuilder, Ability, AbilityClass } from '@casl/ability';interface Person {kind: 'Person'firstName: stringlastName: stringage: numberaddress: {street: stringcity: string}}type AppAbility = Ability\<['read', Person | Person['kind']]\>;cons AppAbility = Ability as AbilityClass\<AppAbility\>;cons { can } = new AbilityBuilder(AppAbility);can('read', 'Person', {'address.street': 'Somewhere in the world',fistName: 'John' // unintentional typo});can('read', 'Person', ['fistName', 'lastName'], { // no intellisense for fieldsage: { $gt: 18 }})
After
โ๏ธ Because provided keys in the example above doesn't exist on
Person
interface, TypeScript throws an error. So, we are safe from typos! But what about dot notation? It's also supported but in more typesafe way:import { AbilityBuilder, Ability, AbilityClass } from '@casl/ability';interface Person {kind: 'Person'firstName: stringlastName: stringage: numberaddress: {street: stringcity: string}}type AppAbility = Ability\<['read', Person | Person['kind']]\>;cons AppAbility = Ability as AbilityClass\<AppAbility\>;cons { can } = new AbilityBuilder(AppAbility);interface PersonQuery extends Person {'address.street': Person['address']['street']'address.city': Person['address']['city']}can\<PersonQuery\>('read', 'Person', {'address.street': 'Somewhere in the world',fistName: 'John' // unintentional typo});can\<PersonQuery\>('read', 'Person', ['firstName', 'lastName'], {age: { $gt: 18 }})
Intellisense and type checking for fields is also implemented! To be able to use wildcards in fields just add additional generic parameter:
can\<PersonQuery, 'address.\*'\>('read', 'Person', ['firstName', 'address.\*'], {age: { $gt: 18 }})