@casl/react 3.1.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -114,7 +114,7 @@ export default function App({ props }) {
114
114
  }
115
115
  ```
116
116
 
117
- > See [CASL guide](https://casl.js.org/v5/en/guide/intro) to learn how to define `Ability` instance.
117
+ > See [CASL guide](https://casl.js.org/v6/en/guide/intro) to learn how to define `Ability` instance.
118
118
 
119
119
  and use our `Can` component:
120
120
 
@@ -205,14 +205,22 @@ export default () => {
205
205
 
206
206
  ### Usage note on React < 16.4 with TypeScript
207
207
 
208
- If you use TypeScript and React < 16.4 make sure to add `@casl/react/contextAPIPatch.d.ts` file in your `tscofig.json`, otherwise your app won't compile:
208
+ If you use TypeScript and React < 16.4 make sure to create a file `contextAPIPatch.d.ts` file with the next content:
209
+
210
+ ```ts
211
+ declare module 'react' {
212
+ export type Consumer<T> = any;
213
+ }
214
+ ```
215
+
216
+ and include it in your `tscofig.json`, otherwise your app won't compile:
209
217
 
210
218
  ```json
211
219
  {
212
220
  // other configuration options
213
221
  "include": [
214
222
  "src/**/*",
215
- "@casl/react/contextAPIPatch.d.ts" // <-- add this line
223
+ "./contextAPIPatch.d.ts" // <-- add this line
216
224
  ]
217
225
  }
218
226
  ```
@@ -302,7 +310,16 @@ export default () => {
302
310
  };
303
311
  ```
304
312
 
305
- > See [Define rules](https://casl.js.org/v5/en/guide/define-rules) to get more information of how to define `Ability`
313
+ > See [Define rules](https://casl.js.org/v6/en/guide/define-rules) to get more information of how to define `Ability`
314
+
315
+ ## `useAbility` usage within hooks
316
+
317
+ Using the return value `ability` of `const ability = useAbility(AbilityContext)` within a hook dependencies won't trigger a rerender when the rules are updated. You have to specify `ability.rules`:
318
+
319
+ ```jsx
320
+ const posts = React.useMemo(() => getPosts(ability), [ability.rules]);
321
+ // ✅ calling ability.update will update the list of posts
322
+ ```
306
323
 
307
324
  ## Want to help?
308
325
 
@@ -310,7 +327,7 @@ Want to file a bug, contribute some code, or improve documentation? Excellent! R
310
327
 
311
328
  If you'd like to help us sustain our community and project, consider [to become a financial contributor on Open Collective](https://opencollective.com/casljs/contribute)
312
329
 
313
- > See [Support CASL](https://casl.js.org/v5/en/support-casljs) for details
330
+ > See [Support CASL](https://casl.js.org/v6/en/support-casljs) for details
314
331
 
315
332
  ## License
316
333
 
@@ -1,2 +1,2 @@
1
- import t,{PureComponent as n,createElement as r}from"react";function i(t,n){for(var r=0;r<n.length;r++){var i=n[r];i.enumerable=i.enumerable||false;i.configurable=true;if("value"in i)i.writable=true;Object.defineProperty(t,i.key,i)}}function u(t,n,r){if(n)i(t.prototype,n);if(r)i(t,r);return t}function e(){e=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var i in r)if(Object.prototype.hasOwnProperty.call(r,i))t[i]=r[i]}return t};return e.apply(this,arguments)}function o(t,n){t.prototype=Object.create(n.prototype);t.prototype.constructor=t;f(t,n)}function f(t,n){f=Object.setPrototypeOf||function t(n,r){n.__proto__=r;return n};return f(t,n)}var c=function t(){};var s=function(t){o(n,t);function n(){var n;for(var r=arguments.length,i=new Array(r),u=0;u<r;u++)i[u]=arguments[u];n=t.call.apply(t,[this].concat(i))||this;n.t=false;n.i=null;n.u=c;return n}var r=n.prototype;r.componentWillUnmount=function t(){this.u()};r.o=function _connectToAbility(t){var n=this;if(t===this.i)return;this.u();this.i=null;if(t){this.i=t;this.u=t.on("updated",(function(){return n.forceUpdate()}))}};r.h=function t(){var n=this.props;var r=n.of||n.a||n.an||n.this||n.on;var i=n.not?"cannot":"can";return n.ability[i](n.I||n.do,r,n.field)};r.render=function t(){this.o(this.props.ability);this.t=this.h();return this.props.passThrough||this.t?this.v():null};r.v=function t(){var n=this.props,r=n.children,i=n.ability;var u="function"===typeof r?r(this.t,i):r;return u};u(n,[{key:"allowed",get:function t(){return this.t}}]);return n}(n);function a(t){var n,r;return r=n=function(t){o(n,t);function n(){return t.apply(this,arguments)||this}return n}(s),n.defaultProps={ability:t},r}function h(t){return function(n){return r(t,{children:function t(i){return r(s,e({ability:i},n))}})}}function useAbility(n){if("production"!==process.env.NODE_ENV&&"function"!==typeof t.useContext)throw new Error("You must use React >= 16.8 in order to use useAbility()");var r=t.useContext(n);var i=t.useState(),u=i[0],e=i[1];t.useEffect((function(){return r.on("updated",(function(t){if(t.rules!==u)e(t.rules)}))}),[]);return r}export{s as Can,a as createCanBoundTo,h as createContextualCan,useAbility};
1
+ import t,{PureComponent as r,createElement as n}from"react";function i(t,r){if("object"!=typeof t||!t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var i=n.call(t,r||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}function u(t){var r=i(t,"string");return"symbol"==typeof r?r:String(r)}function e(t,r){for(var n=0;n<r.length;n++){var i=r[n];i.enumerable=i.enumerable||false;i.configurable=true;if("value"in i)i.writable=true;Object.defineProperty(t,u(i.key),i)}}function o(t,r,n){if(r)e(t.prototype,r);if(n)e(t,n);Object.defineProperty(t,"prototype",{writable:false});return t}function f(){f=Object.assign?Object.assign.bind():function(t){for(var r=1;r<arguments.length;r++){var n=arguments[r];for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i))t[i]=n[i]}return t};return f.apply(this,arguments)}function c(t,r){t.prototype=Object.create(r.prototype);t.prototype.constructor=t;a(t,r)}function a(t,r){a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function t(r,n){r.__proto__=n;return r};return a(t,r)}var s=function t(){};var v=function(t){c(r,t);function r(){var r;for(var n=arguments.length,i=new Array(n),u=0;u<n;u++)i[u]=arguments[u];r=t.call.apply(t,[this].concat(i))||this;r.t=false;r.i=null;r.u=s;return r}var n=r.prototype;n.componentWillUnmount=function t(){this.u()};n.o=function _connectToAbility(t){var r=this;if(t===this.i)return;this.u();this.i=null;if(t){this.i=t;this.u=t.on("updated",(function(){return r.forceUpdate()}))}};n.v=function t(){var r=this.props;var n=r.of||r.a||r.an||r.this||r.on;var i=r.not?"cannot":"can";return r.ability[i](r.I||r.do,n,r.field)};n.render=function t(){this.o(this.props.ability);this.t=this.v();return this.props.passThrough||this.t?this.h():null};n.h=function t(){var r=this.props,n=r.children,i=r.ability;var u=typeof n==="function"?n(this.t,i):n;return u};o(r,[{key:"allowed",get:function t(){return this.t}}]);return r}(r);function h(t){var r;return r=function(t){c(r,t);function r(){return t.apply(this,arguments)||this}return r}(v),r.defaultProps={ability:t},r}function l(t){return function(r){return n(t,{children:function t(i){return n(v,f({ability:i},r))}})}}function useAbility(r){if(process.env.NODE_ENV!=="production"&&typeof t.useContext!=="function")throw new Error("You must use React >= 16.8 in order to use useAbility()");var n=t.useContext(r);var i=t.useState(),u=i[0],e=i[1];t.useEffect((function(){return n.on("updated",(function(t){if(t.rules!==u)e(t.rules)}))}),[]);return n}export{v as Can,h as createCanBoundTo,l as createContextualCan,useAbility};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/Can.ts","../../src/factory.ts","../../src/hooks/useAbility.ts"],"sourcesContent":["import { PureComponent, ReactNode } from 'react';\nimport {\n Unsubscribe,\n AbilityTuple,\n SubjectType,\n AnyAbility,\n Generics,\n Abilities,\n IfString,\n} from '@casl/ability';\n\nconst noop = () => {};\n\ntype AbilityCanProps<\n T extends Abilities,\n Else = IfString<T, { do: T } | { I: T }>\n> = T extends AbilityTuple\n ? { do: T[0], on: T[1], field?: string } |\n { I: T[0], a: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], an: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], this: Exclude<T[1], SubjectType>, field?: string }\n : Else;\n\ninterface ExtraProps {\n not?: boolean\n passThrough?: boolean\n}\n\ninterface CanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\ninterface BoundCanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability?: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\nexport type CanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & CanExtraProps<T>;\nexport type BoundCanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & BoundCanExtraProps<T>;\n\nexport class Can<\n T extends AnyAbility,\n IsBound extends boolean = false\n> extends PureComponent<IsBound extends true ? BoundCanProps<T> : CanProps<T>> {\n private _isAllowed: boolean = false;\n private _ability: T | null = null;\n private _unsubscribeFromAbility: Unsubscribe = noop;\n\n componentWillUnmount() {\n this._unsubscribeFromAbility();\n }\n\n private _connectToAbility(ability?: T) {\n if (ability === this._ability) {\n return;\n }\n\n this._unsubscribeFromAbility();\n this._ability = null;\n\n if (ability) {\n this._ability = ability;\n this._unsubscribeFromAbility = ability.on('updated', () => this.forceUpdate());\n }\n }\n\n get allowed() {\n return this._isAllowed;\n }\n\n private _canRender(): boolean {\n const props: any = this.props;\n const subject = props.of || props.a || props.an || props.this || props.on;\n const can = props.not ? 'cannot' : 'can';\n\n return props.ability[can](props.I || props.do, subject, props.field);\n }\n\n render() {\n this._connectToAbility(this.props.ability);\n this._isAllowed = this._canRender();\n return this.props.passThrough || this._isAllowed ? this._renderChildren() : null;\n }\n\n private _renderChildren() {\n const { children, ability } = this.props;\n const elements = typeof children === 'function'\n ? children(this._isAllowed, ability as any)\n : children;\n\n return elements as ReactNode;\n }\n}\n","import { createElement as h, ComponentClass, Consumer, FunctionComponent } from 'react';\nimport { AnyAbility } from '@casl/ability';\nimport { Can, BoundCanProps } from './Can';\n\ninterface BoundCanClass<T extends AnyAbility> extends ComponentClass<BoundCanProps<T>> {\n new (props: BoundCanProps<T>, context?: any): Can<T, true>\n}\n\nexport function createCanBoundTo<T extends AnyAbility>(ability: T): BoundCanClass<T> {\n return class extends Can<T, true> {\n static defaultProps = { ability } as BoundCanClass<T>['defaultProps'];\n };\n}\n\nexport function createContextualCan<T extends AnyAbility>(\n Getter: Consumer<T>\n): FunctionComponent<BoundCanProps<T>> {\n return (props: BoundCanProps<T>) => h(Getter, {\n children: (ability: T) => h(Can, {\n ability,\n ...props,\n } as any)\n });\n}\n","import React from 'react';\nimport { AnyAbility } from '@casl/ability';\n\nexport function useAbility<T extends AnyAbility>(context: React.Context<T>): T {\n if (process.env.NODE_ENV !== 'production' && typeof React.useContext !== 'function') {\n /* istanbul ignore next */\n throw new Error('You must use React >= 16.8 in order to use useAbility()');\n }\n\n const ability = React.useContext<T>(context);\n const [rules, setRules] = React.useState<T['rules']>();\n\n React.useEffect(() => ability.on('updated', (event) => {\n if (event.rules !== rules) {\n setRules(event.rules);\n }\n }), []);\n\n return ability;\n}\n"],"names":["noop","Can","_isAllowed","_ability","_unsubscribeFromAbility","componentWillUnmount","_connectToAbility","ability","this","on","_this2","forceUpdate","_canRender","props","subject","of","a","an","can","not","I","do","field","render","passThrough","_renderChildren","children","elements","PureComponent","createCanBoundTo","defaultProps","createContextualCan","Getter","h","useAbility","context","process","env","NODE_ENV","React","useContext","Error","useState","rules","setRules","useEffect","event"],"mappings":"6qBAWA,IAAMA,EAAO,SAAPA,UAgCOC,2JAIHC,EAAsB,QACtBC,EAAqB,OACrBC,EAAuCJ,+BAE/CK,qBAAA,kBACOD,OAGCE,EAAR,2BAA0BC,iBACpBA,IAAYC,KAAKL,cAIhBC,SACAD,EAAW,QAEZI,EAAS,MACNJ,EAAWI,OACXH,EAA0BG,EAAQE,GAAG,WAAW,kBAAMC,EAAKC,qBAQ5DC,EAAR,iBACQC,EAAaL,KAAKK,UAClBC,EAAUD,EAAME,IAAMF,EAAMG,GAAKH,EAAMI,IAAMJ,EAAML,MAAQK,EAAMJ,OACjES,EAAML,EAAMM,IAAM,SAAW,aAE5BN,EAAMN,QAAQW,GAAKL,EAAMO,GAAKP,EAAMQ,GAAIP,EAASD,EAAMS,UAGhEC,OAAA,kBACOjB,EAAkBE,KAAKK,MAAMN,cAC7BL,EAAaM,KAAKI,WAChBJ,KAAKK,MAAMW,aAAehB,KAAKN,EAAaM,KAAKiB,IAAoB,QAGtEA,EAAR,mBACgCjB,KAAKK,MAA3Ba,IAAAA,SAAUnB,IAAAA,YACZoB,EAA+B,oBAAbD,EACpBA,EAASlB,KAAKN,EAAYK,GAC1BmB,SAEGC,2BAxBT,oBACSnB,KAAKN,gBAxBN0B,GCtCH,SAASC,EAAuCtB,qGAChCN,KACZ6B,aAAe,CAAEvB,QAAAA,KAIrB,SAASwB,EACdC,UAEO,SAACnB,UAA4BoB,EAAED,EAAQ,CAC5CN,SAAU,WAACnB,UAAe0B,EAAEhC,KAC1BM,QAAAA,GACGM,QCjBF,SAASqB,WAAiCC,MAClB,eAAzBC,QAAQC,IAAIC,UAAyD,oBAArBC,EAAMC,iBAElD,IAAIC,MAAM,+DAGZlC,EAAUgC,EAAMC,WAAcL,SACVI,EAAMG,WAAzBC,OAAOC,OAEdL,EAAMM,WAAU,kBAAMtC,EAAQE,GAAG,WAAW,SAACqC,MACvCA,EAAMH,QAAUA,EAClBC,EAASE,EAAMH,YAEf,WAEGpC"}
1
+ {"version":3,"file":"index.js","sources":["../../src/Can.ts","../../src/factory.ts","../../src/hooks/useAbility.ts"],"sourcesContent":["import { PureComponent, ReactNode } from 'react';\nimport {\n Unsubscribe,\n AbilityTuple,\n SubjectType,\n AnyAbility,\n Generics,\n Abilities,\n IfString,\n} from '@casl/ability';\n\nconst noop = () => {};\n\ntype AbilityCanProps<\n T extends Abilities,\n Else = IfString<T, { do: T } | { I: T }>\n> = T extends AbilityTuple\n ? { do: T[0], on: T[1], field?: string } |\n { I: T[0], a: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], an: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], this: Exclude<T[1], SubjectType>, field?: string }\n : Else;\n\ninterface ExtraProps {\n not?: boolean\n passThrough?: boolean\n}\n\ninterface CanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\ninterface BoundCanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability?: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\nexport type CanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & CanExtraProps<T>;\nexport type BoundCanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & BoundCanExtraProps<T>;\n\nexport class Can<\n T extends AnyAbility,\n IsBound extends boolean = false\n> extends PureComponent<IsBound extends true ? BoundCanProps<T> : CanProps<T>> {\n private _isAllowed: boolean = false;\n private _ability: T | null = null;\n private _unsubscribeFromAbility: Unsubscribe = noop;\n\n componentWillUnmount() {\n this._unsubscribeFromAbility();\n }\n\n private _connectToAbility(ability?: T) {\n if (ability === this._ability) {\n return;\n }\n\n this._unsubscribeFromAbility();\n this._ability = null;\n\n if (ability) {\n this._ability = ability;\n this._unsubscribeFromAbility = ability.on('updated', () => this.forceUpdate());\n }\n }\n\n get allowed() {\n return this._isAllowed;\n }\n\n private _canRender(): boolean {\n const props: any = this.props;\n const subject = props.of || props.a || props.an || props.this || props.on;\n const can = props.not ? 'cannot' : 'can';\n\n return props.ability[can](props.I || props.do, subject, props.field);\n }\n\n render() {\n this._connectToAbility(this.props.ability);\n this._isAllowed = this._canRender();\n return this.props.passThrough || this._isAllowed ? this._renderChildren() : null;\n }\n\n private _renderChildren() {\n const { children, ability } = this.props;\n const elements = typeof children === 'function'\n ? children(this._isAllowed, ability as any)\n : children;\n\n return elements as ReactNode;\n }\n}\n","import { createElement as h, ComponentClass, Consumer, FunctionComponent } from 'react';\nimport { AnyAbility } from '@casl/ability';\nimport { Can, BoundCanProps } from './Can';\n\ninterface BoundCanClass<T extends AnyAbility> extends ComponentClass<BoundCanProps<T>> {\n new (props: BoundCanProps<T>, context?: any): Can<T, true>\n}\n\nexport function createCanBoundTo<T extends AnyAbility>(ability: T): BoundCanClass<T> {\n return class extends Can<T, true> {\n static defaultProps = { ability } as BoundCanClass<T>['defaultProps'];\n };\n}\n\nexport function createContextualCan<T extends AnyAbility>(\n Getter: Consumer<T>\n): FunctionComponent<BoundCanProps<T>> {\n return (props: BoundCanProps<T>) => h(Getter, {\n children: (ability: T) => h(Can, {\n ability,\n ...props,\n } as any)\n });\n}\n","import React from 'react';\nimport { AnyAbility } from '@casl/ability';\n\nexport function useAbility<T extends AnyAbility>(context: React.Context<T>): T {\n if (process.env.NODE_ENV !== 'production' && typeof React.useContext !== 'function') {\n /* istanbul ignore next */\n throw new Error('You must use React >= 16.8 in order to use useAbility()');\n }\n\n const ability = React.useContext<T>(context);\n const [rules, setRules] = React.useState<T['rules']>();\n\n React.useEffect(() => ability.on('updated', (event) => {\n if (event.rules !== rules) {\n setRules(event.rules);\n }\n }), []);\n\n return ability;\n}\n"],"names":["noop","Can","_PureComponent","_inheritsLoose","_this","_len","arguments","length","args","Array","_key","call","apply","this","concat","_isAllowed","_ability","_unsubscribeFromAbility","_proto","prototype","componentWillUnmount","_connectToAbility","ability","_this2","on","forceUpdate","_canRender","props","subject","of","a","an","can","not","I","do","field","render","passThrough","_renderChildren","_this$props","children","elements","_createClass","key","get","PureComponent","createCanBoundTo","_Class","_Can","defaultProps","createContextualCan","Getter","h","_extends","useAbility","context","process","env","NODE_ENV","React","useContext","Error","_React$useState","useState","rules","setRules","useEffect","event"],"mappings":"imCAWA,IAAMA,EAAO,SAAPA,MAgCOC,IAAAA,WAAGC,GAAAC,EAAAF,EAAAC,GAAA,SAAAD,IAAA,IAAAG,EAAA,IAAA,IAAAC,EAAAC,UAAAC,OAAAC,EAAAC,IAAAA,MAAAJ,GAAAK,EAAA,EAAAA,EAAAL,EAAAK,IAAAF,EAAAE,GAAAJ,UAAAI,GAAAN,EAAAF,EAAAS,KAAAC,MAAAV,EAAA,CAAAW,MAAAC,OAAAN,KAAAK,KAAAT,EAINW,EAAsB,MAAKX,EAC3BY,EAAqB,KAAIZ,EACzBa,EAAuCjB,EAAI,OAAAI,CAAA,CAAA,IAAAc,EAAAjB,EAAAkB,UAAAD,EAEnDE,qBAAA,SAAAA,IACEP,KAAKI,KACNC,EAEOG,EAAR,SAAAA,kBAA0BC,GAAa,IAAAC,EAAAV,KACrC,GAAIS,IAAYT,KAAKG,EACnB,OAGFH,KAAKI,IACLJ,KAAKG,EAAW,KAEhB,GAAIM,EAAS,CACXT,KAAKG,EAAWM,EAChBT,KAAKI,EAA0BK,EAAQE,GAAG,WAAW,WAAA,OAAMD,EAAKE,gBAClE,GACDP,EAMOQ,EAAR,SAAAA,IACE,IAAMC,EAAad,KAAKc,MACxB,IAAMC,EAAUD,EAAME,IAAMF,EAAMG,GAAKH,EAAMI,IAAMJ,EAAMd,MAAQc,EAAMH,GACvE,IAAMQ,EAAML,EAAMM,IAAM,SAAW,MAEnC,OAAON,EAAML,QAAQU,GAAKL,EAAMO,GAAKP,EAAMQ,GAAIP,EAASD,EAAMS,QAC/DlB,EAEDmB,OAAA,SAAAA,IACExB,KAAKQ,EAAkBR,KAAKc,MAAML,SAClCT,KAAKE,EAAaF,KAAKa,IACvB,OAAOb,KAAKc,MAAMW,aAAezB,KAAKE,EAAaF,KAAK0B,IAAoB,MAC7ErB,EAEOqB,EAAR,SAAAA,IACE,IAAAC,EAA8B3B,KAAKc,MAA3Bc,EAAQD,EAARC,SAAUnB,EAAOkB,EAAPlB,QAClB,IAAMoB,SAAkBD,IAAa,WACjCA,EAAS5B,KAAKE,EAAYO,GAC1BmB,EAEJ,OAAOC,GACRC,EAAA1C,EAAA,CAAA,CAAA2C,IAAA,UAAAC,IAzBD,SAAAA,IACE,OAAOhC,KAAKE,CACd,KAAC,OAAAd,CAAA,EAzBO6C,GCtCH,SAASC,EAAuCzB,GAA8B,IAAA0B,EACnF,OAAAA,WAAAC,GAAA9C,EAAA6C,EAAAC,GAAA,SAAAD,IAAA,OAAAC,EAAArC,MAAAC,KAAAP,YAAAO,IAAA,CAAA,OAAAmC,CAAA,EAAqB/C,GAAG+C,EACfE,aAAe,CAAE5B,QAAAA,GAAS0B,CAErC,CAEO,SAASG,EACdC,GAEA,OAAO,SAACzB,GAAuB,OAAK0B,EAAED,EAAQ,CAC5CX,SAAU,SAAAA,EAACnB,GAAU,OAAK+B,EAAEpD,EAAGqD,EAAA,CAC7BhC,QAAAA,GACGK,GACI,GACT,CACJ,CCpBO,SAAS4B,WAAiCC,GAC/C,GAAIC,QAAQC,IAAIC,WAAa,qBAAuBC,EAAMC,aAAe,WAEvE,MAAM,IAAIC,MAAM,2DAGlB,IAAMxC,EAAUsC,EAAMC,WAAcL,GACpC,IAAAO,EAA0BH,EAAMI,WAAzBC,EAAKF,EAAA,GAAEG,EAAQH,EAAA,GAEtBH,EAAMO,WAAU,WAAA,OAAM7C,EAAQE,GAAG,WAAW,SAAC4C,GAC3C,GAAIA,EAAMH,QAAUA,EAClBC,EAASE,EAAMH,MAEnB,GAAE,GAAE,IAEJ,OAAO3C,CACT"}
@@ -1,2 +1,2 @@
1
- import t,{PureComponent as i,createElement as n}from"react";const s=()=>{};class e extends i{constructor(...t){super(...t);this.t=false;this.i=null;this.o=s}componentWillUnmount(){this.o()}u(t){if(t===this.i)return;this.o();this.i=null;if(t){this.i=t;this.o=t.on("updated",(()=>this.forceUpdate()))}}get allowed(){return this.t}h(){const t=this.props;const i=t.of||t.a||t.an||t.this||t.on;const n=t.not?"cannot":"can";return t.ability[n](t.I||t.do,i,t.field)}render(){this.u(this.props.ability);this.t=this.h();return this.props.passThrough||this.t?this.l():null}l(){const{children:t,ability:i}=this.props;const n="function"===typeof t?t(this.t,i):t;return n}}function r(t){var i,n;return n=i=class extends e{},i.defaultProps={ability:t},n}function o(t){return i=>n(t,{children:t=>n(e,Object.assign({ability:t},i))})}function useAbility(i){if("production"!==process.env.NODE_ENV&&"function"!==typeof t.useContext)throw new Error("You must use React >= 16.8 in order to use useAbility()");const n=t.useContext(i);const[s,e]=t.useState();t.useEffect((()=>n.on("updated",(t=>{if(t.rules!==s)e(t.rules)}))),[]);return n}export{e as Can,r as createCanBoundTo,o as createContextualCan,useAbility};
1
+ import t,{PureComponent as i,createElement as n}from"react";const s=()=>{};class e extends i{constructor(...t){super(...t);this.t=false;this.i=null;this.o=s}componentWillUnmount(){this.o()}u(t){if(t===this.i)return;this.o();this.i=null;if(t){this.i=t;this.o=t.on("updated",(()=>this.forceUpdate()))}}get allowed(){return this.t}h(){const t=this.props;const i=t.of||t.a||t.an||t.this||t.on;const n=t.not?"cannot":"can";return t.ability[n](t.I||t.do,i,t.field)}render(){this.u(this.props.ability);this.t=this.h();return this.props.passThrough||this.t?this.l():null}l(){const{children:t,ability:i}=this.props;const n=typeof t==="function"?t(this.t,i):t;return n}}function r(t){var i;return i=class extends e{},i.defaultProps={ability:t},i}function o(t){return i=>n(t,{children:t=>n(e,Object.assign({ability:t},i))})}function useAbility(i){if(process.env.NODE_ENV!=="production"&&typeof t.useContext!=="function")throw new Error("You must use React >= 16.8 in order to use useAbility()");const n=t.useContext(i);const[s,e]=t.useState();t.useEffect((()=>n.on("updated",(t=>{if(t.rules!==s)e(t.rules)}))),[]);return n}export{e as Can,r as createCanBoundTo,o as createContextualCan,useAbility};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../src/Can.ts","../../src/factory.ts","../../src/hooks/useAbility.ts"],"sourcesContent":["import { PureComponent, ReactNode } from 'react';\nimport {\n Unsubscribe,\n AbilityTuple,\n SubjectType,\n AnyAbility,\n Generics,\n Abilities,\n IfString,\n} from '@casl/ability';\n\nconst noop = () => {};\n\ntype AbilityCanProps<\n T extends Abilities,\n Else = IfString<T, { do: T } | { I: T }>\n> = T extends AbilityTuple\n ? { do: T[0], on: T[1], field?: string } |\n { I: T[0], a: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], an: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], this: Exclude<T[1], SubjectType>, field?: string }\n : Else;\n\ninterface ExtraProps {\n not?: boolean\n passThrough?: boolean\n}\n\ninterface CanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\ninterface BoundCanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability?: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\nexport type CanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & CanExtraProps<T>;\nexport type BoundCanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & BoundCanExtraProps<T>;\n\nexport class Can<\n T extends AnyAbility,\n IsBound extends boolean = false\n> extends PureComponent<IsBound extends true ? BoundCanProps<T> : CanProps<T>> {\n private _isAllowed: boolean = false;\n private _ability: T | null = null;\n private _unsubscribeFromAbility: Unsubscribe = noop;\n\n componentWillUnmount() {\n this._unsubscribeFromAbility();\n }\n\n private _connectToAbility(ability?: T) {\n if (ability === this._ability) {\n return;\n }\n\n this._unsubscribeFromAbility();\n this._ability = null;\n\n if (ability) {\n this._ability = ability;\n this._unsubscribeFromAbility = ability.on('updated', () => this.forceUpdate());\n }\n }\n\n get allowed() {\n return this._isAllowed;\n }\n\n private _canRender(): boolean {\n const props: any = this.props;\n const subject = props.of || props.a || props.an || props.this || props.on;\n const can = props.not ? 'cannot' : 'can';\n\n return props.ability[can](props.I || props.do, subject, props.field);\n }\n\n render() {\n this._connectToAbility(this.props.ability);\n this._isAllowed = this._canRender();\n return this.props.passThrough || this._isAllowed ? this._renderChildren() : null;\n }\n\n private _renderChildren() {\n const { children, ability } = this.props;\n const elements = typeof children === 'function'\n ? children(this._isAllowed, ability as any)\n : children;\n\n return elements as ReactNode;\n }\n}\n","import { createElement as h, ComponentClass, Consumer, FunctionComponent } from 'react';\nimport { AnyAbility } from '@casl/ability';\nimport { Can, BoundCanProps } from './Can';\n\ninterface BoundCanClass<T extends AnyAbility> extends ComponentClass<BoundCanProps<T>> {\n new (props: BoundCanProps<T>, context?: any): Can<T, true>\n}\n\nexport function createCanBoundTo<T extends AnyAbility>(ability: T): BoundCanClass<T> {\n return class extends Can<T, true> {\n static defaultProps = { ability } as BoundCanClass<T>['defaultProps'];\n };\n}\n\nexport function createContextualCan<T extends AnyAbility>(\n Getter: Consumer<T>\n): FunctionComponent<BoundCanProps<T>> {\n return (props: BoundCanProps<T>) => h(Getter, {\n children: (ability: T) => h(Can, {\n ability,\n ...props,\n } as any)\n });\n}\n","import React from 'react';\nimport { AnyAbility } from '@casl/ability';\n\nexport function useAbility<T extends AnyAbility>(context: React.Context<T>): T {\n if (process.env.NODE_ENV !== 'production' && typeof React.useContext !== 'function') {\n /* istanbul ignore next */\n throw new Error('You must use React >= 16.8 in order to use useAbility()');\n }\n\n const ability = React.useContext<T>(context);\n const [rules, setRules] = React.useState<T['rules']>();\n\n React.useEffect(() => ability.on('updated', (event) => {\n if (event.rules !== rules) {\n setRules(event.rules);\n }\n }), []);\n\n return ability;\n}\n"],"names":["noop","Can","PureComponent","_isAllowed","_ability","_unsubscribeFromAbility","componentWillUnmount","_connectToAbility","ability","this","on","forceUpdate","_canRender","props","subject","of","a","an","can","not","I","do","field","render","passThrough","_renderChildren","children","elements","createCanBoundTo","defaultProps","createContextualCan","Getter","h","useAbility","context","process","env","NODE_ENV","React","useContext","Error","rules","setRules","useState","useEffect","event"],"mappings":"4DAWA,MAAMA,EAAO,OAgCN,MAAMC,UAGHC,qCACAC,EAAsB,WACtBC,EAAqB,UACrBC,EAAuCL,EAE/CM,4BACOD,IAGCE,EAAkBC,MACpBA,IAAYC,KAAKL,cAIhBC,SACAD,EAAW,QAEZI,EAAS,MACNJ,EAAWI,OACXH,EAA0BG,EAAQE,GAAG,WAAW,IAAMD,KAAKE,sCAK3DF,KAAKN,EAGNS,UACAC,EAAaJ,KAAKI,YAClBC,EAAUD,EAAME,IAAMF,EAAMG,GAAKH,EAAMI,IAAMJ,EAAMJ,MAAQI,EAAMH,SACjEQ,EAAML,EAAMM,IAAM,SAAW,aAE5BN,EAAML,QAAQU,GAAKL,EAAMO,GAAKP,EAAMQ,GAAIP,EAASD,EAAMS,OAGhEC,cACOhB,EAAkBE,KAAKI,MAAML,cAC7BL,EAAaM,KAAKG,WAChBH,KAAKI,MAAMW,aAAef,KAAKN,EAAaM,KAAKgB,IAAoB,KAGtEA,UACAC,SAAEA,EAAFlB,QAAYA,GAAYC,KAAKI,YAC7Bc,EAA+B,oBAAbD,EACpBA,EAASjB,KAAKN,EAAYK,GAC1BkB,SAEGC,GCrFJ,SAASC,EAAuCpB,sBAC9C,cAAcP,MACZ4B,aAAe,CAAErB,QAAAA,KAIrB,SAASsB,EACdC,UAEQlB,GAA4BmB,EAAED,EAAQ,CAC5CL,SAAWlB,GAAewB,EAAE/B,iBAC1BO,QAAAA,GACGK,MCjBF,SAASoB,WAAiCC,MAClB,eAAzBC,QAAQC,IAAIC,UAAyD,oBAArBC,EAAMC,iBAElD,IAAIC,MAAM,iEAGZhC,EAAU8B,EAAMC,WAAcL,SAC7BO,EAAOC,GAAYJ,EAAMK,WAEhCL,EAAMM,WAAU,IAAMpC,EAAQE,GAAG,WAAYmC,OACvCA,EAAMJ,QAAUA,EAClBC,EAASG,EAAMJ,WAEf,WAEGjC"}
1
+ {"version":3,"file":"index.mjs","sources":["../../src/Can.ts","../../src/factory.ts","../../src/hooks/useAbility.ts"],"sourcesContent":["import { PureComponent, ReactNode } from 'react';\nimport {\n Unsubscribe,\n AbilityTuple,\n SubjectType,\n AnyAbility,\n Generics,\n Abilities,\n IfString,\n} from '@casl/ability';\n\nconst noop = () => {};\n\ntype AbilityCanProps<\n T extends Abilities,\n Else = IfString<T, { do: T } | { I: T }>\n> = T extends AbilityTuple\n ? { do: T[0], on: T[1], field?: string } |\n { I: T[0], a: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], an: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], this: Exclude<T[1], SubjectType>, field?: string }\n : Else;\n\ninterface ExtraProps {\n not?: boolean\n passThrough?: boolean\n}\n\ninterface CanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\ninterface BoundCanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability?: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\nexport type CanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & CanExtraProps<T>;\nexport type BoundCanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & BoundCanExtraProps<T>;\n\nexport class Can<\n T extends AnyAbility,\n IsBound extends boolean = false\n> extends PureComponent<IsBound extends true ? BoundCanProps<T> : CanProps<T>> {\n private _isAllowed: boolean = false;\n private _ability: T | null = null;\n private _unsubscribeFromAbility: Unsubscribe = noop;\n\n componentWillUnmount() {\n this._unsubscribeFromAbility();\n }\n\n private _connectToAbility(ability?: T) {\n if (ability === this._ability) {\n return;\n }\n\n this._unsubscribeFromAbility();\n this._ability = null;\n\n if (ability) {\n this._ability = ability;\n this._unsubscribeFromAbility = ability.on('updated', () => this.forceUpdate());\n }\n }\n\n get allowed() {\n return this._isAllowed;\n }\n\n private _canRender(): boolean {\n const props: any = this.props;\n const subject = props.of || props.a || props.an || props.this || props.on;\n const can = props.not ? 'cannot' : 'can';\n\n return props.ability[can](props.I || props.do, subject, props.field);\n }\n\n render() {\n this._connectToAbility(this.props.ability);\n this._isAllowed = this._canRender();\n return this.props.passThrough || this._isAllowed ? this._renderChildren() : null;\n }\n\n private _renderChildren() {\n const { children, ability } = this.props;\n const elements = typeof children === 'function'\n ? children(this._isAllowed, ability as any)\n : children;\n\n return elements as ReactNode;\n }\n}\n","import { createElement as h, ComponentClass, Consumer, FunctionComponent } from 'react';\nimport { AnyAbility } from '@casl/ability';\nimport { Can, BoundCanProps } from './Can';\n\ninterface BoundCanClass<T extends AnyAbility> extends ComponentClass<BoundCanProps<T>> {\n new (props: BoundCanProps<T>, context?: any): Can<T, true>\n}\n\nexport function createCanBoundTo<T extends AnyAbility>(ability: T): BoundCanClass<T> {\n return class extends Can<T, true> {\n static defaultProps = { ability } as BoundCanClass<T>['defaultProps'];\n };\n}\n\nexport function createContextualCan<T extends AnyAbility>(\n Getter: Consumer<T>\n): FunctionComponent<BoundCanProps<T>> {\n return (props: BoundCanProps<T>) => h(Getter, {\n children: (ability: T) => h(Can, {\n ability,\n ...props,\n } as any)\n });\n}\n","import React from 'react';\nimport { AnyAbility } from '@casl/ability';\n\nexport function useAbility<T extends AnyAbility>(context: React.Context<T>): T {\n if (process.env.NODE_ENV !== 'production' && typeof React.useContext !== 'function') {\n /* istanbul ignore next */\n throw new Error('You must use React >= 16.8 in order to use useAbility()');\n }\n\n const ability = React.useContext<T>(context);\n const [rules, setRules] = React.useState<T['rules']>();\n\n React.useEffect(() => ability.on('updated', (event) => {\n if (event.rules !== rules) {\n setRules(event.rules);\n }\n }), []);\n\n return ability;\n}\n"],"names":["noop","Can","PureComponent","constructor","args","super","this","_isAllowed","_ability","_unsubscribeFromAbility","componentWillUnmount","_connectToAbility","ability","on","forceUpdate","allowed","_canRender","props","subject","of","a","an","can","not","I","do","field","render","passThrough","_renderChildren","children","elements","createCanBoundTo","_Class","defaultProps","createContextualCan","Getter","h","Object","assign","useAbility","context","process","env","NODE_ENV","React","useContext","Error","rules","setRules","useState","useEffect","event"],"mappings":"4DAWA,MAAMA,EAAOA,OAgCN,MAAMC,UAGHC,EAAqEC,WAAAA,IAAAC,GAAAC,SAAAD,GAAAE,KACrEC,EAAsB,MAAKD,KAC3BE,EAAqB,KAAIF,KACzBG,EAAuCT,CAAI,CAEnDU,oBAAAA,GACEJ,KAAKG,GACP,CAEQE,CAAAA,CAAkBC,GACxB,GAAIA,IAAYN,KAAKE,EACnB,OAGFF,KAAKG,IACLH,KAAKE,EAAW,KAEhB,GAAII,EAAS,CACXN,KAAKE,EAAWI,EAChBN,KAAKG,EAA0BG,EAAQC,GAAG,WAAW,IAAMP,KAAKQ,eAClE,CACF,CAEA,WAAIC,GACF,OAAOT,KAAKC,CACd,CAEQS,CAAAA,GACN,MAAMC,EAAaX,KAAKW,MACxB,MAAMC,EAAUD,EAAME,IAAMF,EAAMG,GAAKH,EAAMI,IAAMJ,EAAMX,MAAQW,EAAMJ,GACvE,MAAMS,EAAML,EAAMM,IAAM,SAAW,MAEnC,OAAON,EAAML,QAAQU,GAAKL,EAAMO,GAAKP,EAAMQ,GAAIP,EAASD,EAAMS,MAChE,CAEAC,MAAAA,GACErB,KAAKK,EAAkBL,KAAKW,MAAML,SAClCN,KAAKC,EAAaD,KAAKU,IACvB,OAAOV,KAAKW,MAAMW,aAAetB,KAAKC,EAAaD,KAAKuB,IAAoB,IAC9E,CAEQA,CAAAA,GACN,MAAMC,SAAEA,EAAQlB,QAAEA,GAAYN,KAAKW,MACnC,MAAMc,SAAkBD,IAAa,WACjCA,EAASxB,KAAKC,EAAYK,GAC1BkB,EAEJ,OAAOC,CACT,ECtFK,SAASC,EAAuCpB,GAA8B,IAAAqB,EACnF,OAAAA,EAAO,cAAchC,IAEpBgC,EADQC,aAAe,CAAEtB,WAASqB,CAErC,CAEO,SAASE,EACdC,GAEA,OAAQnB,GAA4BoB,EAAED,EAAQ,CAC5CN,SAAWlB,GAAeyB,EAAEpC,EAAGqC,OAAAC,OAAA,CAC7B3B,WACGK,KAGT,CCpBO,SAASuB,WAAiCC,GAC/C,GAAIC,QAAQC,IAAIC,WAAa,qBAAuBC,EAAMC,aAAe,WAEvE,MAAM,IAAIC,MAAM,2DAGlB,MAAMnC,EAAUiC,EAAMC,WAAcL,GACpC,MAAOO,EAAOC,GAAYJ,EAAMK,WAEhCL,EAAMM,WAAU,IAAMvC,EAAQC,GAAG,WAAYuC,IAC3C,GAAIA,EAAMJ,QAAUA,EAClBC,EAASG,EAAMJ,MACjB,KACE,IAEJ,OAAOpC,CACT"}
@@ -1,6 +1,6 @@
1
1
  import { PureComponent, ReactNode } from 'react';
2
2
  import { AbilityTuple, SubjectType, AnyAbility, Generics, Abilities, IfString } from '@casl/ability';
3
- declare type AbilityCanProps<T extends Abilities, Else = IfString<T, {
3
+ type AbilityCanProps<T extends Abilities, Else = IfString<T, {
4
4
  do: T;
5
5
  } | {
6
6
  I: T;
@@ -33,8 +33,8 @@ interface BoundCanExtraProps<T extends AnyAbility> extends ExtraProps {
33
33
  ability?: T;
34
34
  children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode);
35
35
  }
36
- export declare type CanProps<T extends AnyAbility> = AbilityCanProps<Generics<T>['abilities']> & CanExtraProps<T>;
37
- export declare type BoundCanProps<T extends AnyAbility> = AbilityCanProps<Generics<T>['abilities']> & BoundCanExtraProps<T>;
36
+ export type CanProps<T extends AnyAbility> = AbilityCanProps<Generics<T>['abilities']> & CanExtraProps<T>;
37
+ export type BoundCanProps<T extends AnyAbility> = AbilityCanProps<Generics<T>['abilities']> & BoundCanExtraProps<T>;
38
38
  export declare class Can<T extends AnyAbility, IsBound extends boolean = false> extends PureComponent<IsBound extends true ? BoundCanProps<T> : CanProps<T>> {
39
39
  private _isAllowed;
40
40
  private _ability;
package/dist/umd/index.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(t,n){"object"===typeof exports&&"undefined"!==typeof module?n(exports,require("react")):"function"===typeof define&&define.amd?define(["exports","react"],n):(t="undefined"!==typeof globalThis?globalThis:t||self,n((t.casl=t.casl||{},t.casl.react={}),t.React))})(this,(function(t,n){"use strict";function i(t){return t&&"object"===typeof t&&"default"in t?t:{default:t}}var r=i(n);function e(t,n){for(var i=0;i<n.length;i++){var r=n[i];r.enumerable=r.enumerable||false;r.configurable=true;if("value"in r)r.writable=true;Object.defineProperty(t,r.key,r)}}function u(t,n,i){if(n)e(t.prototype,n);if(i)e(t,i);return t}function o(){o=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var i=arguments[n];for(var r in i)if(Object.prototype.hasOwnProperty.call(i,r))t[r]=i[r]}return t};return o.apply(this,arguments)}function f(t,n){t.prototype=Object.create(n.prototype);t.prototype.constructor=t;c(t,n)}function c(t,n){c=Object.setPrototypeOf||function t(n,i){n.__proto__=i;return n};return c(t,n)}var s=function t(){};var a=function(t){f(n,t);function n(){var n;for(var i=arguments.length,r=new Array(i),e=0;e<i;e++)r[e]=arguments[e];n=t.call.apply(t,[this].concat(r))||this;n.t=false;n.i=null;n.u=s;return n}var i=n.prototype;i.componentWillUnmount=function t(){this.u()};i.o=function _connectToAbility(t){var n=this;if(t===this.i)return;this.u();this.i=null;if(t){this.i=t;this.u=t.on("updated",(function(){return n.forceUpdate()}))}};i.h=function t(){var n=this.props;var i=n.of||n.a||n.an||n.this||n.on;var r=n.not?"cannot":"can";return n.ability[r](n.I||n.do,i,n.field)};i.render=function t(){this.o(this.props.ability);this.t=this.h();return this.props.passThrough||this.t?this.l():null};i.l=function t(){var n=this.props,i=n.children,r=n.ability;var e="function"===typeof i?i(this.t,r):i;return e};u(n,[{key:"allowed",get:function t(){return this.t}}]);return n}(n.PureComponent);function h(t){var n,i;return i=n=function(t){f(n,t);function n(){return t.apply(this,arguments)||this}return n}(a),n.defaultProps={ability:t},i}function l(t){return function(i){return n.createElement(t,{children:function t(r){return n.createElement(a,o({ability:r},i))}})}}function useAbility(t){if("production"!==process.env.NODE_ENV&&"function"!==typeof r["default"].useContext)throw new Error("You must use React >= 16.8 in order to use useAbility()");var n=r["default"].useContext(t);var i=r["default"].useState(),e=i[0],u=i[1];r["default"].useEffect((function(){return n.on("updated",(function(t){if(t.rules!==e)u(t.rules)}))}),[]);return n}t.Can=a;t.createCanBoundTo=h;t.createContextualCan=l;t.useAbility=useAbility;Object.defineProperty(t,"__esModule",{value:true})}));
1
+ (function(t,n){typeof exports==="object"&&typeof module!=="undefined"?n(exports,require("react")):typeof define==="function"&&define.amd?define(["exports","react"],n):(t=typeof globalThis!=="undefined"?globalThis:t||self,n((t.casl=t.casl||{},t.casl.react={}),t.React))})(this,(function(t,n){"use strict";function r(t,n){if("object"!=typeof t||!t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var i=r.call(t,n||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===n?String:Number)(t)}function i(t){var n=r(t,"string");return"symbol"==typeof n?n:String(n)}function e(t,n){for(var r=0;r<n.length;r++){var e=n[r];e.enumerable=e.enumerable||false;e.configurable=true;if("value"in e)e.writable=true;Object.defineProperty(t,i(e.key),e)}}function u(t,n,r){if(n)e(t.prototype,n);if(r)e(t,r);Object.defineProperty(t,"prototype",{writable:false});return t}function o(){o=Object.assign?Object.assign.bind():function(t){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var i in r)if(Object.prototype.hasOwnProperty.call(r,i))t[i]=r[i]}return t};return o.apply(this,arguments)}function f(t,n){t.prototype=Object.create(n.prototype);t.prototype.constructor=t;c(t,n)}function c(t,n){c=Object.setPrototypeOf?Object.setPrototypeOf.bind():function t(n,r){n.__proto__=r;return n};return c(t,n)}var s=function t(){};var a=function(t){f(n,t);function n(){var n;for(var r=arguments.length,i=new Array(r),e=0;e<r;e++)i[e]=arguments[e];n=t.call.apply(t,[this].concat(i))||this;n.t=false;n.i=null;n.u=s;return n}var r=n.prototype;r.componentWillUnmount=function t(){this.u()};r.o=function _connectToAbility(t){var n=this;if(t===this.i)return;this.u();this.i=null;if(t){this.i=t;this.u=t.on("updated",(function(){return n.forceUpdate()}))}};r.l=function t(){var n=this.props;var r=n.of||n.a||n.an||n.this||n.on;var i=n.not?"cannot":"can";return n.ability[i](n.I||n.do,r,n.field)};r.render=function t(){this.o(this.props.ability);this.t=this.l();return this.props.passThrough||this.t?this.h():null};r.h=function t(){var n=this.props,r=n.children,i=n.ability;var e=typeof r==="function"?r(this.t,i):r;return e};u(n,[{key:"allowed",get:function t(){return this.t}}]);return n}(n.PureComponent);function l(t){var n;return n=function(t){f(n,t);function n(){return t.apply(this,arguments)||this}return n}(a),n.defaultProps={ability:t},n}function h(t){return function(r){return n.createElement(t,{children:function t(i){return n.createElement(a,o({ability:i},r))}})}}function useAbility(t){if(process.env.NODE_ENV!=="production"&&typeof n.useContext!=="function")throw new Error("You must use React >= 16.8 in order to use useAbility()");var r=n.useContext(t);var i=n.useState(),e=i[0],u=i[1];n.useEffect((function(){return r.on("updated",(function(t){if(t.rules!==e)u(t.rules)}))}),[]);return r}t.Can=a;t.createCanBoundTo=l;t.createContextualCan=h;t.useAbility=useAbility}));
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/Can.ts","../../src/factory.ts","../../src/hooks/useAbility.ts"],"sourcesContent":["import { PureComponent, ReactNode } from 'react';\nimport {\n Unsubscribe,\n AbilityTuple,\n SubjectType,\n AnyAbility,\n Generics,\n Abilities,\n IfString,\n} from '@casl/ability';\n\nconst noop = () => {};\n\ntype AbilityCanProps<\n T extends Abilities,\n Else = IfString<T, { do: T } | { I: T }>\n> = T extends AbilityTuple\n ? { do: T[0], on: T[1], field?: string } |\n { I: T[0], a: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], an: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], this: Exclude<T[1], SubjectType>, field?: string }\n : Else;\n\ninterface ExtraProps {\n not?: boolean\n passThrough?: boolean\n}\n\ninterface CanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\ninterface BoundCanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability?: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\nexport type CanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & CanExtraProps<T>;\nexport type BoundCanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & BoundCanExtraProps<T>;\n\nexport class Can<\n T extends AnyAbility,\n IsBound extends boolean = false\n> extends PureComponent<IsBound extends true ? BoundCanProps<T> : CanProps<T>> {\n private _isAllowed: boolean = false;\n private _ability: T | null = null;\n private _unsubscribeFromAbility: Unsubscribe = noop;\n\n componentWillUnmount() {\n this._unsubscribeFromAbility();\n }\n\n private _connectToAbility(ability?: T) {\n if (ability === this._ability) {\n return;\n }\n\n this._unsubscribeFromAbility();\n this._ability = null;\n\n if (ability) {\n this._ability = ability;\n this._unsubscribeFromAbility = ability.on('updated', () => this.forceUpdate());\n }\n }\n\n get allowed() {\n return this._isAllowed;\n }\n\n private _canRender(): boolean {\n const props: any = this.props;\n const subject = props.of || props.a || props.an || props.this || props.on;\n const can = props.not ? 'cannot' : 'can';\n\n return props.ability[can](props.I || props.do, subject, props.field);\n }\n\n render() {\n this._connectToAbility(this.props.ability);\n this._isAllowed = this._canRender();\n return this.props.passThrough || this._isAllowed ? this._renderChildren() : null;\n }\n\n private _renderChildren() {\n const { children, ability } = this.props;\n const elements = typeof children === 'function'\n ? children(this._isAllowed, ability as any)\n : children;\n\n return elements as ReactNode;\n }\n}\n","import { createElement as h, ComponentClass, Consumer, FunctionComponent } from 'react';\nimport { AnyAbility } from '@casl/ability';\nimport { Can, BoundCanProps } from './Can';\n\ninterface BoundCanClass<T extends AnyAbility> extends ComponentClass<BoundCanProps<T>> {\n new (props: BoundCanProps<T>, context?: any): Can<T, true>\n}\n\nexport function createCanBoundTo<T extends AnyAbility>(ability: T): BoundCanClass<T> {\n return class extends Can<T, true> {\n static defaultProps = { ability } as BoundCanClass<T>['defaultProps'];\n };\n}\n\nexport function createContextualCan<T extends AnyAbility>(\n Getter: Consumer<T>\n): FunctionComponent<BoundCanProps<T>> {\n return (props: BoundCanProps<T>) => h(Getter, {\n children: (ability: T) => h(Can, {\n ability,\n ...props,\n } as any)\n });\n}\n","import React from 'react';\nimport { AnyAbility } from '@casl/ability';\n\nexport function useAbility<T extends AnyAbility>(context: React.Context<T>): T {\n if (process.env.NODE_ENV !== 'production' && typeof React.useContext !== 'function') {\n /* istanbul ignore next */\n throw new Error('You must use React >= 16.8 in order to use useAbility()');\n }\n\n const ability = React.useContext<T>(context);\n const [rules, setRules] = React.useState<T['rules']>();\n\n React.useEffect(() => ability.on('updated', (event) => {\n if (event.rules !== rules) {\n setRules(event.rules);\n }\n }), []);\n\n return ability;\n}\n"],"names":["noop","Can","_isAllowed","_ability","_unsubscribeFromAbility","componentWillUnmount","_connectToAbility","ability","this","on","_this2","forceUpdate","_canRender","props","subject","of","a","an","can","not","I","do","field","render","passThrough","_renderChildren","children","elements","PureComponent","createCanBoundTo","defaultProps","createContextualCan","Getter","h","useAbility","context","process","env","NODE_ENV","React","useContext","Error","useState","rules","setRules","useEffect","event"],"mappings":"q/BAWA,IAAMA,EAAO,SAAPA,UAgCOC,2JAIHC,EAAsB,QACtBC,EAAqB,OACrBC,EAAuCJ,+BAE/CK,qBAAA,kBACOD,OAGCE,EAAR,2BAA0BC,iBACpBA,IAAYC,KAAKL,cAIhBC,SACAD,EAAW,QAEZI,EAAS,MACNJ,EAAWI,OACXH,EAA0BG,EAAQE,GAAG,WAAW,kBAAMC,EAAKC,qBAQ5DC,EAAR,iBACQC,EAAaL,KAAKK,UAClBC,EAAUD,EAAME,IAAMF,EAAMG,GAAKH,EAAMI,IAAMJ,EAAML,MAAQK,EAAMJ,OACjES,EAAML,EAAMM,IAAM,SAAW,aAE5BN,EAAMN,QAAQW,GAAKL,EAAMO,GAAKP,EAAMQ,GAAIP,EAASD,EAAMS,UAGhEC,OAAA,kBACOjB,EAAkBE,KAAKK,MAAMN,cAC7BL,EAAaM,KAAKI,WAChBJ,KAAKK,MAAMW,aAAehB,KAAKN,EAAaM,KAAKiB,IAAoB,QAGtEA,EAAR,mBACgCjB,KAAKK,MAA3Ba,IAAAA,SAAUnB,IAAAA,YACZoB,EAA+B,oBAAbD,EACpBA,EAASlB,KAAKN,EAAYK,GAC1BmB,SAEGC,2BAxBT,oBACSnB,KAAKN,gBAxBN0B,iBCtCH,SAASC,EAAuCtB,qGAChCN,KACZ6B,aAAe,CAAEvB,QAAAA,KAIrB,SAASwB,EACdC,UAEO,SAACnB,UAA4BoB,gBAAED,EAAQ,CAC5CN,SAAU,WAACnB,UAAe0B,gBAAEhC,KAC1BM,QAAAA,GACGM,QCjBF,SAASqB,WAAiCC,MAClB,eAAzBC,QAAQC,IAAIC,UAAyD,oBAArBC,aAAMC,iBAElD,IAAIC,MAAM,+DAGZlC,EAAUgC,aAAMC,WAAcL,SACVI,aAAMG,WAAzBC,OAAOC,OAEdL,aAAMM,WAAU,kBAAMtC,EAAQE,GAAG,WAAW,SAACqC,MACvCA,EAAMH,QAAUA,EAClBC,EAASE,EAAMH,YAEf,WAEGpC"}
1
+ {"version":3,"file":"index.js","sources":["../../src/Can.ts","../../src/factory.ts","../../src/hooks/useAbility.ts"],"sourcesContent":["import { PureComponent, ReactNode } from 'react';\nimport {\n Unsubscribe,\n AbilityTuple,\n SubjectType,\n AnyAbility,\n Generics,\n Abilities,\n IfString,\n} from '@casl/ability';\n\nconst noop = () => {};\n\ntype AbilityCanProps<\n T extends Abilities,\n Else = IfString<T, { do: T } | { I: T }>\n> = T extends AbilityTuple\n ? { do: T[0], on: T[1], field?: string } |\n { I: T[0], a: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], an: Extract<T[1], SubjectType>, field?: string } |\n { I: T[0], this: Exclude<T[1], SubjectType>, field?: string }\n : Else;\n\ninterface ExtraProps {\n not?: boolean\n passThrough?: boolean\n}\n\ninterface CanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\ninterface BoundCanExtraProps<T extends AnyAbility> extends ExtraProps {\n ability?: T\n children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode)\n}\n\nexport type CanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & CanExtraProps<T>;\nexport type BoundCanProps<T extends AnyAbility> =\n AbilityCanProps<Generics<T>['abilities']> & BoundCanExtraProps<T>;\n\nexport class Can<\n T extends AnyAbility,\n IsBound extends boolean = false\n> extends PureComponent<IsBound extends true ? BoundCanProps<T> : CanProps<T>> {\n private _isAllowed: boolean = false;\n private _ability: T | null = null;\n private _unsubscribeFromAbility: Unsubscribe = noop;\n\n componentWillUnmount() {\n this._unsubscribeFromAbility();\n }\n\n private _connectToAbility(ability?: T) {\n if (ability === this._ability) {\n return;\n }\n\n this._unsubscribeFromAbility();\n this._ability = null;\n\n if (ability) {\n this._ability = ability;\n this._unsubscribeFromAbility = ability.on('updated', () => this.forceUpdate());\n }\n }\n\n get allowed() {\n return this._isAllowed;\n }\n\n private _canRender(): boolean {\n const props: any = this.props;\n const subject = props.of || props.a || props.an || props.this || props.on;\n const can = props.not ? 'cannot' : 'can';\n\n return props.ability[can](props.I || props.do, subject, props.field);\n }\n\n render() {\n this._connectToAbility(this.props.ability);\n this._isAllowed = this._canRender();\n return this.props.passThrough || this._isAllowed ? this._renderChildren() : null;\n }\n\n private _renderChildren() {\n const { children, ability } = this.props;\n const elements = typeof children === 'function'\n ? children(this._isAllowed, ability as any)\n : children;\n\n return elements as ReactNode;\n }\n}\n","import { createElement as h, ComponentClass, Consumer, FunctionComponent } from 'react';\nimport { AnyAbility } from '@casl/ability';\nimport { Can, BoundCanProps } from './Can';\n\ninterface BoundCanClass<T extends AnyAbility> extends ComponentClass<BoundCanProps<T>> {\n new (props: BoundCanProps<T>, context?: any): Can<T, true>\n}\n\nexport function createCanBoundTo<T extends AnyAbility>(ability: T): BoundCanClass<T> {\n return class extends Can<T, true> {\n static defaultProps = { ability } as BoundCanClass<T>['defaultProps'];\n };\n}\n\nexport function createContextualCan<T extends AnyAbility>(\n Getter: Consumer<T>\n): FunctionComponent<BoundCanProps<T>> {\n return (props: BoundCanProps<T>) => h(Getter, {\n children: (ability: T) => h(Can, {\n ability,\n ...props,\n } as any)\n });\n}\n","import React from 'react';\nimport { AnyAbility } from '@casl/ability';\n\nexport function useAbility<T extends AnyAbility>(context: React.Context<T>): T {\n if (process.env.NODE_ENV !== 'production' && typeof React.useContext !== 'function') {\n /* istanbul ignore next */\n throw new Error('You must use React >= 16.8 in order to use useAbility()');\n }\n\n const ability = React.useContext<T>(context);\n const [rules, setRules] = React.useState<T['rules']>();\n\n React.useEffect(() => ability.on('updated', (event) => {\n if (event.rules !== rules) {\n setRules(event.rules);\n }\n }), []);\n\n return ability;\n}\n"],"names":["noop","Can","_PureComponent","_inheritsLoose","_this","_len","arguments","length","args","Array","_key","call","apply","this","concat","_isAllowed","_ability","_unsubscribeFromAbility","_proto","prototype","componentWillUnmount","_connectToAbility","ability","_this2","on","forceUpdate","_canRender","props","subject","of","a","an","can","not","I","do","field","render","passThrough","_renderChildren","_this$props","children","elements","_createClass","key","get","PureComponent","createCanBoundTo","_Class","_Can","defaultProps","createContextualCan","Getter","h","createElement","_extends","useAbility","context","process","env","NODE_ENV","React","useContext","Error","_React$useState","useState","rules","setRules","useEffect","event"],"mappings":"q1CAWA,IAAMA,EAAO,SAAPA,MAgCOC,IAAAA,WAAGC,GAAAC,EAAAF,EAAAC,GAAA,SAAAD,IAAA,IAAAG,EAAA,IAAA,IAAAC,EAAAC,UAAAC,OAAAC,EAAAC,IAAAA,MAAAJ,GAAAK,EAAA,EAAAA,EAAAL,EAAAK,IAAAF,EAAAE,GAAAJ,UAAAI,GAAAN,EAAAF,EAAAS,KAAAC,MAAAV,EAAA,CAAAW,MAAAC,OAAAN,KAAAK,KAAAT,EAINW,EAAsB,MAAKX,EAC3BY,EAAqB,KAAIZ,EACzBa,EAAuCjB,EAAI,OAAAI,CAAA,CAAA,IAAAc,EAAAjB,EAAAkB,UAAAD,EAEnDE,qBAAA,SAAAA,IACEP,KAAKI,KACNC,EAEOG,EAAR,SAAAA,kBAA0BC,GAAa,IAAAC,EAAAV,KACrC,GAAIS,IAAYT,KAAKG,EACnB,OAGFH,KAAKI,IACLJ,KAAKG,EAAW,KAEhB,GAAIM,EAAS,CACXT,KAAKG,EAAWM,EAChBT,KAAKI,EAA0BK,EAAQE,GAAG,WAAW,WAAA,OAAMD,EAAKE,gBAClE,GACDP,EAMOQ,EAAR,SAAAA,IACE,IAAMC,EAAad,KAAKc,MACxB,IAAMC,EAAUD,EAAME,IAAMF,EAAMG,GAAKH,EAAMI,IAAMJ,EAAMd,MAAQc,EAAMH,GACvE,IAAMQ,EAAML,EAAMM,IAAM,SAAW,MAEnC,OAAON,EAAML,QAAQU,GAAKL,EAAMO,GAAKP,EAAMQ,GAAIP,EAASD,EAAMS,QAC/DlB,EAEDmB,OAAA,SAAAA,IACExB,KAAKQ,EAAkBR,KAAKc,MAAML,SAClCT,KAAKE,EAAaF,KAAKa,IACvB,OAAOb,KAAKc,MAAMW,aAAezB,KAAKE,EAAaF,KAAK0B,IAAoB,MAC7ErB,EAEOqB,EAAR,SAAAA,IACE,IAAAC,EAA8B3B,KAAKc,MAA3Bc,EAAQD,EAARC,SAAUnB,EAAOkB,EAAPlB,QAClB,IAAMoB,SAAkBD,IAAa,WACjCA,EAAS5B,KAAKE,EAAYO,GAC1BmB,EAEJ,OAAOC,GACRC,EAAA1C,EAAA,CAAA,CAAA2C,IAAA,UAAAC,IAzBD,SAAAA,IACE,OAAOhC,KAAKE,CACd,KAAC,OAAAd,CAAA,EAzBO6C,EAAaA,eCtChB,SAASC,EAAuCzB,GAA8B,IAAA0B,EACnF,OAAAA,WAAAC,GAAA9C,EAAA6C,EAAAC,GAAA,SAAAD,IAAA,OAAAC,EAAArC,MAAAC,KAAAP,YAAAO,IAAA,CAAA,OAAAmC,CAAA,EAAqB/C,GAAG+C,EACfE,aAAe,CAAE5B,QAAAA,GAAS0B,CAErC,CAEO,SAASG,EACdC,GAEA,OAAO,SAACzB,GAAuB,OAAK0B,EAAAA,cAAED,EAAQ,CAC5CX,SAAU,SAAAA,EAACnB,GAAU,OAAK+B,EAACC,cAACrD,EAAGsD,EAAA,CAC7BjC,QAAAA,GACGK,GACI,GACT,CACJ,CCpBO,SAAS6B,WAAiCC,GAC/C,GAAIC,QAAQC,IAAIC,WAAa,qBAAuBC,EAAMC,aAAe,WAEvE,MAAM,IAAIC,MAAM,2DAGlB,IAAMzC,EAAUuC,EAAMC,WAAcL,GACpC,IAAAO,EAA0BH,EAAMI,WAAzBC,EAAKF,EAAA,GAAEG,EAAQH,EAAA,GAEtBH,EAAMO,WAAU,WAAA,OAAM9C,EAAQE,GAAG,WAAW,SAAC6C,GAC3C,GAAIA,EAAMH,QAAUA,EAClBC,EAASE,EAAMH,MAEnB,GAAE,GAAE,IAEJ,OAAO5C,CACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@casl/react",
3
- "version": "3.1.0",
3
+ "version": "4.0.0",
4
4
  "description": "React component for CASL which makes it easy to add permissions in any React application",
5
5
  "main": "dist/umd/index.js",
6
6
  "module": "dist/es5m/index.js",
@@ -48,8 +48,8 @@
48
48
  "@casl/ability": "^6.0.0",
49
49
  "@casl/dx": "workspace:^1.0.0",
50
50
  "@testing-library/react-hooks": "^4.0.1",
51
- "@types/jest": "^28.0.0",
52
- "@types/node": "^14.0.5",
51
+ "@types/jest": "^29.0.0",
52
+ "@types/node": "^20.0.0",
53
53
  "@types/react": "^18.0.0",
54
54
  "chai": "^4.1.0",
55
55
  "chai-spies": "^1.0.0",
@@ -1,3 +0,0 @@
1
- declare module 'react' {
2
- export type Consumer<T> = any;
3
- }