All Versions
38
Latest Version
Avg Release Cycle
34 days
Latest Release
1303 days ago

Changelog History
Page 1

  • v5.1.0-next.9 Changes

    September 28, 2020

    5.1.0-next.9 (2020-09-28)

    ๐ŸŽ Performance Improvements

    • events: converts LinkedItem into POJO and regular functions (6f2de73)
    • extra: replaces object with Set in permittedFieldsOf (a9260d1)
  • v5.1.0-next.8 Changes

    September 26, 2020

    5.1.0-next.8 (2020-09-26)

    ๐ŸŽ Performance Improvements

    • rule: ensures conditions/field matcher created only when we have object/field to check (110a69d)
  • v5.1.0-next.7 Changes

    September 25, 2020

    5.1.0-next.7 (2020-09-25)

    ๐ŸŽ Performance Improvements

    • events: moves out side-effect from LinkedItem constructor (3657c7f)
  • v5.1.0-next.6 Changes

    September 25, 2020

    5.1.0-next.6 (2020-09-25)

    ๐ŸŽ Performance Improvements

    • events: handles event removal in space efficient way (71246e2)
  • v5.1.0-next.5 Changes

    September 23, 2020

    5.1.0-next.5 (2020-09-23)

    ๐Ÿ› Bug Fixes

    • ability: ensure default field matcher can match fields with partial patterns inside (362f49f), closes #388
    • angular: fixes sourcemap generation for the code built by ngc (7715263), closes #387 #382
    • condtions: adds interpreter for $and parsing instruction (3166a32)
  • v5.1.0-next.4 Changes

    August 28, 2020

    5.1.0-next.4 (2020-08-28)

    ๐ŸŽ Performance Improvements

    • ability: replaces object for storing index with ES6 Map (d1fa117)
  • v5.1.0-next.3 Changes

    August 28, 2020

    5.1.0-next.3 (2020-08-28)

    ๐ŸŽ Performance Improvements

    • ability: creates conditions and field matcher lazily (4ae7799)
  • v5.1.0-next.2 Changes

    August 27, 2020

    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 }})
    
  • v5.1.0-next.12 Changes

    November 18, 2020

    5.1.0-next.12 (2020-11-18)

    ๐Ÿ› Bug Fixes

    • ability: replaces getters with functions to ensure terser properly minifies them (386ecb6)
    • extra: makes permittedFieldsOf to iterate from the end of array (81e6409)

    ๐Ÿ”จ Code Refactoring

    • extra: makes fieldsFrom option to be mandatory for permittedFieldsOf [skip release] (df29b0d)
    • types: restricts which utility types are exported by library (e98618f)

    โช Reverts

    • ๐Ÿ— builder: reverts back AbilityBuilder generic parameter (aa7b45f)

    ๐Ÿ’ฅ BREAKING CHANGES

    types: types AliasesMap, TaggedInterface, AbilityTupleType, ToAbilityTypes, AnyObject are no longer exported by the library

    extra: makes fieldsFrom option to be mandatory for permittedFieldsO f. This reduces confusion around why permittedFieldsOf returns empty array when user can manage entity fields. So, now this logic is just explicit and clear

    Before

    import { defineAbility } from '@casl/ability';import { permittedFieldsOf } from '@casl/ability/extra';const ability = defineAbility((can) =\> {can('read', 'Article');});const fields = permittedFieldsOf(ability, 'read', 'Article'); // []
    

    After

    import { defineAbility } from '@casl/ability';import { permittedFieldsOf } from '@casl/ability/extra';const ability = defineAbility((can) =\> {can('read', 'Article');});const ARTICLE\_FIELDS = ['id', 'title', 'description'];const fields = permittedFieldsOf(ability, 'read', 'Article', {fieldsFrom: rule =\> rule.fields || ARTICLE\_FIELDS}); // ['id', 'title', 'description']
    
  • v5.1.0-next.11 Changes

    October 17, 2020

    5.1.0-next.11 (2020-10-17)

    ๐Ÿ› Bug Fixes

    • README: removes explanation duplicated from intro guide (6315aa7)

    ๐Ÿ”จ Code Refactoring

    • ruleIndex: detectSubjectType option is now responsible only for detecting subject type from objects [skip release] (ebeaadc)

    ๐Ÿ’ฅ BREAKING CHANGES

    ruleIndex: string and class (or function constructor) are the only possible subject types for now. detectSubjectType is now responsible only for detecting subject type from object

    Before

    When providing subject type it was important to handle cases when passed in argument is a string or function. As an alternative it was possible to call built-in detectSubjectType which could catch this cases:

    import { Ability } from '@casl/ability';const ability = new Ability([], {detectSubjectType(object) {if (object && typeof object === 'object') {return object.\_\_typename;}return detectSubjectType(object);});
    

    After

    There is no need to handle subject type values in detectSubjectType function anymore. It's now handled internally:

    import { Ability } from '@casl/ability';const ability = new Ability([], {detectSubjectType: object =\> object.\_\_typename});
    

    Also it's important to note that if you want it's no longer possible to use classes and strings as subject types interchangably together as it was before. Now, if you want to use classes, you should use them everywhere:

    Before

    import { defineAbility } from '@casl/ability';class Post {}const ability = defineAbility((can) =\> {can('read', Post);can('update', 'Post');});ability.can('read', 'Post') // trueability.can('read', Post) // trueability.can('update', Post) // true
    

    After

    import { defineAbility } from '@casl/ability';class Post {}const ability = defineAbility((can) =\> {can('read', Post);can('update', 'Post');});ability.can('read', 'Post') // false, 'Post' and Post are considered different nowability.can('read', Post) // trueability.can('update', Post) // false