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'] and AbilityBuilder['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 and cannot methods of AbilityBuilder now restricts what fields and operators can be used inside conditions (i.e., MongoQuery). Also these methods now suggests object fields based on passed instance

    Before

    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 }})