CASL 4.0. — What’s inside?

stalniy

Sergii Stotskyi

Posted on April 18, 2020

CASL 4.0. — What’s inside?

First time you’ve heard about CASL? You may want to read “What is CASL?”.

I’m glad to announce that CASL 4.0 was released few days ago and brought several powerful possibilities on our desk:

Type Safety

@casl/* packages were rewritten to TypeScript. This makes your apps safer and developer experience more enjoyable. Let’s see how:

I know I know… I was one of those skeptics who have never liked TypeScript until recent time. It’s really powerful now, especially inference logic!

Starting from 4.0 Ability class accepts 2 generic parameters:

  • application abilities (actions defined for subjects)
  • conditions shape

This allows you restrict what actions can be applied on specified subjects. For example, in a blog app which has Article, Comment, and User entities, logged in user can:

  • read, create, update, delete Articles
  • read, create, update Comments
  • read other Users

And we can express this as

import { Ability } from '@casl/ability';

type AppAbilities = [
  'read' | 'update' | 'delete' | 'create',
  'Article' | 'Comment' | 'User'
];

export type AppAbility = Ability<AppAbilities>;
Enter fullscreen mode Exit fullscreen mode

Or even stricter

import { Ability } from '@casl/ability';

type AppAbilities = 
  ['create' | 'read' | 'update' | 'delete', 'Article'] |
  ['create' | 'read' | 'update', 'Comment'] |
  ['read', 'User']
;

export type AppAbility = Ability<AppAbilities>;
Enter fullscreen mode Exit fullscreen mode

This allows TypeScript to check that you don’t make a typo in action or subject name at compile time! Moreover, IDE (e.g., VSCode) will suggest possible options to choose from:

CASL Typescript VSCode hints

This types hints works even in your favorite frontend libraries, thanks to complementary packages! So, you will get hints for React’s Can component and Vue’s $can function in templates. The nice thing about VSCode is that it uses typescript definition files even for JavaScript files, so you will get better IDE support for JavaScript apps as well. Isn’t that cool?

To get more details about new TypeScript support in CASL, read about it in the docs.

Smaller library size

The library is smaller, ~4.5KB mingzipped (together with sift.js!) and has better support for tree-shaking. This was achieved thanks to terser.js minifier and several breaking changes that you can find in the CHANGELOG.

Starting from 4.0, there are classes that allows to create Ability instance:

  • PureAbility base class that implements core logic
  • Ability that extends PureAbility and configures it to use mongoQueryMatcher and fieldPatternMatcher

This was done in order to be able to shake out sift.js dependency in case you don’t use conditions at all or when you implement a custom matcher. As a result AbilityBuilder now accepts Ability class as a first argument. By default, the argument is PureAbility, so if you used AbilityBuilder.extract, you will need to change it from:

const { can, cannot, rules } = AbilityBuilder.extract();  
// rule definitions  
const ability = new Ability(rules);
Enter fullscreen mode Exit fullscreen mode

to

const { can, cannot, rules } = new AbilityBuilder(Ability);  
// rule definitions  
const ability = new Ability(rules);
Enter fullscreen mode Exit fullscreen mode

Customization

In 4.0, you can customize Ability instance behavior. Do you want to extend MongoDB query with custom operator, use json-schema or arrow functions as conditions? Not a problem anymore, just implement a custom conditionsMatcher.

To get more in depth details, read Customize Ability in the docs.

Better subject type detection support

If you use Plain Old JavaScript Objects as models, you have a simpler option to specify subject type now. No need to provide custom detectSubjectType function (subjectName option was renamed to detectSubjectType), just use subject helper:

import { defineAbility, subject as an } from '@casl/ability';

const object = {
  title: 'My article', 
  description: '...',
};

ability.can('read', an('Article', object));

// or

const article = an.bind(null, 'Article');
ability.can('read', article(object));
Enter fullscreen mode Exit fullscreen mode

To get better understanding of how CASL detect subject type, check Subject Type Detection page.

Much better documentation

Documentation was completely rewritten. First of all, now it’s a Single Page Application written on top of awesome lit-html and lit-element libraries (the final mingzipped size of the app is 47KB for modern browsers! It even somehow works in IE11). It’s available for offline usage, all documentation texts less than 1MB, so don’t worry it won’t take much of your disk :)

Now it’s organized and easily extendable. It also tries to be beginner friendly and have cookbook and examples sections! Every complementary package now have a separate page with documentation for it, so you don’t need to look for README files through repository.

The Future

CASL gets more and more attraction from developers. This requires additional time to write new features, complementary packages, documentation and answering questions in gitter chat. Besides doing my best to do all of this, I need to use my unique talents to fill important roles for the organization, otherwise my wife would expel me a long time ago ;)

I like CASL and like to contribute to Open Source. That’s why I’m seeking for a way to work more on Open Source projects. Thankfully, there are platforms that help to support people like me. And I’m thrilled to announce thatCASL is now on Open Collective!

If you want to get more details about what Open Collective is, and you can contribute, please read Sustaining CASL development

If you have the same vision of the world, and you like CASL, your contributions are very welcome! You are not restricted to financial contributions, as usually you can just share CASL with your colleague from another project, help to answer questions in gitter chat and triage issues, share your examples of CASL integrations, and contribute code and documentation! Finally, you can become a core contributor and support CASL on regular basis.

How do I migrate?

CASL has introduced several breaking changes in all @casl/* packages, so please spend time reading CHANGELOG.md of the packages you use. You can find all changes (including breaking ones) in that file of each package in casl repository.

If you find any issues or something is unclear, please fill in an issue on github.

Where can I start as a beginner?

As of now, CASL has quite good documentation, so start from the Guide. Then move to documentation for the frontend or backend package of your choice and read it. Later you can check existing articles that explains how to integrate CASL in popular frameworks:

Despite the fact, that they are a bit outdated, CASL was not changed much during its lifetime, so they are still relevant.


Thanks for trusting CASL! I hope CASL made permission management in your app as easy as pie

💖 💪 🙅 🚩
stalniy
Sergii Stotskyi

Posted on April 18, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

CASL. Pursuing Perfection I: Why?
javascript CASL. Pursuing Perfection I: Why?

October 28, 2020

CASL 4.0. — What’s inside?
javascript CASL 4.0. — What’s inside?

April 18, 2020