Skip to content

Commit

Permalink
feat(angular): allows to use custom Ability instances and improves …
Browse files Browse the repository at this point in the history
…tree shaking support

Relates to #249 BREAKING CHANGE: removes `AbilityModule.forRoot()` method and default `Ability` provider.

**Before**

```js
import { AbilityModule } from '@casl/angular'

@NgModule({
  // ...
  imports: [
    AbilityModule.forRoot()
  ],
  providers: [
    // ...
  ]
})
export class AppModule {}
```

**After**

```js
import { PureAbility, Ability } from '@casl/ability'
import { AbilityModule } from '@casl/angular'

@NgModule({
  // ...
  imports: [
    AbilityModule
  ],
  providers: [
    // PureAbility is injected by `can` & `able` pipes
    { provide: PureAbility, useValue: new Ability() },
    // the next line can be added as a migration workaround
    { provide: Ability, useExisting: PureAbility },
    // ...
  ]
})
export class AppModule {}
```
  • Loading branch information
stalniy committed Feb 21, 2020
1 parent 9536205 commit 2e7a149
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 36 deletions.
4 changes: 2 additions & 2 deletions packages/casl-angular/spec/can_pipe.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AbilityBuilder } from '@casl/ability'
import { defineAbility } from '@casl/ability'
import { CanPipe } from '../dist/es6'

describe('Can pipe', () => {
Expand All @@ -7,7 +7,7 @@ describe('Can pipe', () => {
let changeDetectorRef

beforeEach(() => {
ability = AbilityBuilder.define(can => can('read', 'all'))
ability = defineAbility(can => can('read', 'all'))
changeDetectorRef = spy.interface('ChangeDetector', ['markForCheck'])
pipe = new CanPipe(ability, changeDetectorRef)
})
Expand Down
32 changes: 16 additions & 16 deletions packages/casl-angular/spec/module.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ability } from '@casl/ability'
import { PureAbility, Ability } from '@casl/ability'
import { TestBed } from '@angular/core/testing'
import { AbilityModule } from '../dist/es6'
import { App, Post } from './spec_helper'
Expand All @@ -8,25 +8,29 @@ describe('Ability', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [AbilityModule.forRoot()],
imports: [AbilityModule],
declarations: [App],
providers: [
{ provide: PureAbility, useFactory: () => new Ability() }
]
})
})

describe('module', () => {
it('provides empty `Ability` instance', () => {
const ability = TestBed.inject(Ability)

expect(ability).to.be.instanceof(Ability)
expect(ability.rules).to.be.empty
})
afterEach(() => {
if (fixture) {
fixture.destroy()
}
})

describe('module', () => {
it('provides `can` pipe', () => {
fixture = createComponent(App)

expect(fixture.nativeElement.textContent).to.equal('false')
})

fixture.destroy()
it('provides `able` pipe', () => {
fixture = createComponent(App, { pipe: 'able' })
expect(fixture.nativeElement.textContent).to.equal('false')
})
})

Expand All @@ -35,14 +39,10 @@ describe('Ability', () => {
let post

beforeEach(() => {
ability = TestBed.inject(Ability)
ability = TestBed.inject(PureAbility)
post = new Post({ author: 'me' })
})

afterEach(() => {
fixture.destroy()
})

it('updates template when `ability` is updated', () => {
fixture = createComponent(App, { post })
ability.update([{ subject: Post.name, action: 'read' }])
Expand Down
4 changes: 2 additions & 2 deletions packages/casl-angular/spec/spec_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export class App {
return [
new Component({
selector: 'app-ability',
template: '{{ "read" | able: post }}',
inputs: ['post']
template: '{{ pipe === "able" ? ("read" | able: post) : (post | can: "read") }}',
inputs: ['post', 'pipe']
})
]
}
Expand Down
6 changes: 3 additions & 3 deletions packages/casl-angular/src/can.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Pipe, ChangeDetectorRef, Inject } from '@angular/core';
import { Ability, Unsubscribe, AnyAbility, AbilityParameters } from '@casl/ability';
import { PureAbility, Unsubscribe, AnyAbility, AbilityParameters } from '@casl/ability';

class AbilityPipe<T extends AnyAbility> {
protected _unsubscribeFromAbility?: Unsubscribe;
Expand Down Expand Up @@ -30,7 +30,7 @@ class AbilityPipe<T extends AnyAbility> {
export class CanPipe<T extends AnyAbility> {
protected pipe: AbilityPipe<T>;

constructor(@Inject(Ability) ability: T, cd: ChangeDetectorRef) {
constructor(@Inject(PureAbility) ability: T, cd: ChangeDetectorRef) {
this.pipe = new AbilityPipe(ability, cd);
}

Expand All @@ -51,7 +51,7 @@ export class CanPipe<T extends AnyAbility> {
export class AblePipe<T extends AnyAbility> {
protected pipe: AbilityPipe<T>;

constructor(@Inject(Ability) ability: T, cd: ChangeDetectorRef) {
constructor(@Inject(PureAbility) ability: T, cd: ChangeDetectorRef) {
this.pipe = new AbilityPipe(ability, cd);
}

Expand Down
14 changes: 1 addition & 13 deletions packages/casl-angular/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { Ability, AnyAbility } from '@casl/ability';
import { NgModule } from '@angular/core';
import { CanPipe, AblePipe } from './can';

@NgModule({
Expand All @@ -13,15 +12,4 @@ import { CanPipe, AblePipe } from './can';
],
})
export class AbilityModule {
static forRoot<T extends AnyAbility>(): ModuleWithProviders<AbilityModule> {
return {
ngModule: AbilityModule,
providers: [
{
provide: Ability,
useFactory: () => (new Ability([]) as T)
},
]
};
}
}

0 comments on commit 2e7a149

Please sign in to comment.