@casl/react 0.7.0 → 0.8.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,50 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ # [@casl/react-v0.8.1](https://github.com/stalniy/casl/compare/@casl/react@0.8.0...@casl/react@0.8.1) (2018-11-08)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **react:** moves this.connectToAbility to the setState callback ([#129](https://github.com/stalniy/casl/issues/129)) ([9d0c839](https://github.com/stalniy/casl/commit/9d0c839)), closes [#128](https://github.com/stalniy/casl/issues/128)
11
+
12
+ # [@casl/react-v0.8.0](https://github.com/stalniy/casl/compare/@casl/react@0.7.2...@casl/react@0.8.0) (2018-09-03)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **README:** changes links to [@casl](https://github.com/casl)/ability to point to npm package instead to git root [skip ci] ([a74086b](https://github.com/stalniy/casl/commit/a74086b)), closes [#102](https://github.com/stalniy/casl/issues/102)
18
+
19
+
20
+ ### Features
21
+
22
+ * **react:can:** adds `an` alias to `on` prop ([748ea64](https://github.com/stalniy/casl/commit/748ea64))
23
+ * **react:can:** adds `passThrough` option ([045318c](https://github.com/stalniy/casl/commit/045318c)), closes [#105](https://github.com/stalniy/casl/issues/105)
24
+ * **react:can:** adds support for multiple <Can> children ([c022b32](https://github.com/stalniy/casl/commit/c022b32))
25
+ * **react:can:** updates typescript declarations ([70953ed](https://github.com/stalniy/casl/commit/70953ed))
26
+ * **react:can:** updates typescript declarations ([213dcde](https://github.com/stalniy/casl/commit/213dcde))
27
+
28
+
29
+ ### Performance Improvements
30
+
31
+ * **react:can:** moves prop type checks undef `if`, so they can be removed for production builds ([4bebf0b](https://github.com/stalniy/casl/commit/4bebf0b))
32
+
33
+ # [@casl/react-v0.7.2](https://github.com/stalniy/casl/compare/@casl/react@0.7.1...@casl/react@0.7.2) (2018-07-29)
34
+
35
+
36
+ ### Bug Fixes
37
+
38
+ * **react:** makes `not` prop to be optional ([8f841bf](https://github.com/stalniy/casl/commit/8f841bf)), closes [#95](https://github.com/stalniy/casl/issues/95)
39
+
40
+ <a name="@casl/react-v0.7.1"></a>
41
+ # [@casl/react-v0.7.1](https://github.com/stalniy/casl/compare/@casl/react@0.7.0...@casl/react@0.7.1) (2018-07-02)
42
+
43
+
44
+ ### Bug Fixes
45
+
46
+ * **package:** changes location of ES5M modules ([2b1ad4e](https://github.com/stalniy/casl/commit/2b1ad4e)), closes [#89](https://github.com/stalniy/casl/issues/89)
47
+
1
48
  <a name="@casl/react-v0.7.0"></a>
2
49
  # [@casl/react-v0.7.0](https://github.com/stalniy/casl/compare/@casl/react@0.6.0...@casl/react@0.7.0) (2018-06-15)
3
50
 
@@ -12,9 +59,6 @@
12
59
 
13
60
  * **vue:** adds can component ([42ee540](https://github.com/stalniy/casl/commit/42ee540)), closes [#63](https://github.com/stalniy/casl/issues/63)
14
61
 
15
- # Change Log
16
-
17
-
18
62
 
19
63
  <a name="@casl/react-v0.6.0"></a>
20
64
  # [@casl/react-v0.6.0](https://github.com/stalniy/casl/compare/@casl/react@0.5.0...@casl/react@0.6.0) (2018-05-28)
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CASL React [![@casl/react NPM version](https://badge.fury.io/js/%40casl%2Freact.svg)](https://badge.fury.io/js/%40casl%2Freact) [![](https://img.shields.io/npm/dm/%40casl%2Freact.svg)](https://www.npmjs.com/package/%40casl%2Freact) [![CASL Documentation](https://img.shields.io/badge/documentation-available-brightgreen.svg)](https://stalniy.github.io/casl/) [![CASL Join the chat at https://gitter.im/stalniy-casl/casl](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/stalniy-casl/casl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2
2
 
3
- This package allows to integrate [@casl/ability](/packages/casl-ability) into [React][react] application. So, you can show or hide UI elements based on user ability to see them.
3
+ This package allows to integrate [@casl/ability][casl-ability] into [React][react] application. So, you can show or hide UI elements based on user ability to see them.
4
4
 
5
5
  ## Installation
6
6
 
@@ -21,7 +21,7 @@ This component accepts children and 4 properties (see [Property names and aliase
21
21
 
22
22
  ```jsx
23
23
  <Can I="create" a="Post" ability={ability}>
24
- () => <button onClick={this.createPost.bind(this)}>Create Post</button>
24
+ {() => <button onClick={this.createPost.bind(this)}>Create Post</button>}
25
25
  </Can>
26
26
  ```
27
27
 
@@ -62,7 +62,7 @@ import Can from './Can'
62
62
  export function button() {
63
63
  return (
64
64
  <Can I="create" a="Post">
65
- () => <button onClick={this.createPost.bind(this)}>Create Post</button>
65
+ {() => <button onClick={this.createPost.bind(this)}>Create Post</button>}
66
66
  </Can>
67
67
  )
68
68
  }
@@ -108,7 +108,7 @@ export class TodoApp extends Component {
108
108
  render() {
109
109
  return (
110
110
  <Can I="create" a="Todo">
111
- () => <button onClick={this.createTodo.bind(this)}>Create Todo</button>
111
+ {() => <button onClick={this.createTodo.bind(this)}>Create Todo</button>}
112
112
  </Can>
113
113
  )
114
114
  }
@@ -171,7 +171,7 @@ export class LoginComponent extends Component {
171
171
  ```
172
172
 
173
173
  Obviously, in this case your server API should provide the list of user abilities in `rules` field of the response.
174
- See [@casl/ability](/packages/casl-ability) package for more information on how to define abilities.
174
+ See [@casl/ability][casl-ability] package for more information on how to define abilities.
175
175
 
176
176
  ### 3. Property names and aliases
177
177
 
@@ -180,13 +180,13 @@ For example, the code below reads as `Can I create a Post`.
180
180
 
181
181
  ```jsx
182
182
  <Can I="create" a="Post">
183
- () => <button onClick={...}>Create Post</button>
183
+ {() => <button onClick={...}>Create Post</button>}
184
184
  </Can>
185
185
  ```
186
186
 
187
187
  There are several other property aliases which allow to construct a readable question:
188
188
 
189
- * use `a` alias when you check by Type
189
+ * use `a` (or `an`) alias when you check by Type
190
190
 
191
191
  ```jsx
192
192
  <Can I="read" a="Post">...</Can>
@@ -227,6 +227,14 @@ There are several other property aliases which allow to construct a readable que
227
227
  <Can not I="read" a="Post">...</Can>
228
228
  ```
229
229
 
230
+ * use `passThrough` if you want to customize behavior of `<Can>` component, for example disable button instead of hiding it:
231
+
232
+ ```jsx
233
+ <Can I="read" a="Post" passThrough>
234
+ {can => <button disabled={!can}>Save</button>}
235
+ </Can>
236
+ ```
237
+
230
238
 
231
239
  ## Want to help?
232
240
 
@@ -240,3 +248,4 @@ Want to file a bug, contribute some code, or improve documentation? Excellent! R
240
248
  [react]: https://reactjs.org/
241
249
  [casl-react-example]: https://github.com/stalniy/casl-react-example
242
250
  [react-ctx-api]: https://medium.com/dailyjs/reacts-%EF%B8%8F-new-context-api-70c9fe01596b
251
+ [casl-ability]: https://www.npmjs.com/package/@casl/ability
@@ -0,0 +1,228 @@
1
+ import React, { PureComponent, Fragment, createElement } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Ability } from '@casl/ability';
4
+
5
+ var classCallCheck = function (instance, Constructor) {
6
+ if (!(instance instanceof Constructor)) {
7
+ throw new TypeError("Cannot call a class as a function");
8
+ }
9
+ };
10
+
11
+ var createClass = function () {
12
+ function defineProperties(target, props) {
13
+ for (var i = 0; i < props.length; i++) {
14
+ var descriptor = props[i];
15
+ descriptor.enumerable = descriptor.enumerable || false;
16
+ descriptor.configurable = true;
17
+ if ("value" in descriptor) descriptor.writable = true;
18
+ Object.defineProperty(target, descriptor.key, descriptor);
19
+ }
20
+ }
21
+
22
+ return function (Constructor, protoProps, staticProps) {
23
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
24
+ if (staticProps) defineProperties(Constructor, staticProps);
25
+ return Constructor;
26
+ };
27
+ }();
28
+
29
+ var inherits = function (subClass, superClass) {
30
+ if (typeof superClass !== "function" && superClass !== null) {
31
+ throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
32
+ }
33
+
34
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
35
+ constructor: {
36
+ value: subClass,
37
+ enumerable: false,
38
+ writable: true,
39
+ configurable: true
40
+ }
41
+ });
42
+ if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
43
+ };
44
+
45
+ var possibleConstructorReturn = function (self, call) {
46
+ if (!self) {
47
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
48
+ }
49
+
50
+ return call && (typeof call === "object" || typeof call === "function") ? call : self;
51
+ };
52
+
53
+ var noop = function noop() {};
54
+ var _renderChildren = Fragment ? function (children) {
55
+ return createElement.apply(null, [Fragment, null].concat(children));
56
+ } : React.Children.only;
57
+ var propTypes = {};
58
+
59
+ if (process.env.NODE_ENV !== 'production') {
60
+ var REQUIRED_OBJECT_OR_STRING = PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired;
61
+
62
+ var alias = function alias(names, validate) {
63
+ return function (props) {
64
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
65
+ args[_key - 1] = arguments[_key];
66
+ }
67
+
68
+ // eslint-disable-line
69
+ if (!names.split(' ').some(function (name) {
70
+ return props[name];
71
+ })) {
72
+ return validate.apply(undefined, [props].concat(args));
73
+ }
74
+ };
75
+ };
76
+
77
+ propTypes = {
78
+ I: alias('do', PropTypes.string.isRequired),
79
+ a: alias('on this of an', REQUIRED_OBJECT_OR_STRING),
80
+ an: alias('on this of a', REQUIRED_OBJECT_OR_STRING),
81
+ of: alias('on a this an', REQUIRED_OBJECT_OR_STRING),
82
+ this: alias('on a of an', REQUIRED_OBJECT_OR_STRING),
83
+ do: alias('I', PropTypes.string.isRequired),
84
+ on: alias('this a of an', REQUIRED_OBJECT_OR_STRING),
85
+ not: PropTypes.bool,
86
+ passThrough: PropTypes.bool,
87
+ children: PropTypes.any.isRequired,
88
+ ability: PropTypes.instanceOf(Ability).isRequired
89
+ };
90
+ }
91
+
92
+ var Can = function (_PureComponent) {
93
+ inherits(Can, _PureComponent);
94
+
95
+ function Can() {
96
+ classCallCheck(this, Can);
97
+
98
+ for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
99
+ args[_key2] = arguments[_key2];
100
+ }
101
+
102
+ var _this = possibleConstructorReturn(this, _PureComponent.call.apply(_PureComponent, [this].concat(args)));
103
+
104
+ _this.unsubscribeFromAbility = noop;
105
+ _this.state = {
106
+ ability: _this.props.ability,
107
+ allowed: false
108
+ };
109
+ return _this;
110
+ }
111
+
112
+ Can.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) {
113
+ var _this2 = this;
114
+
115
+ if (props.ability && this.state.ability !== props.ability) {
116
+ this.setState({ ability: props.ability }, function () {
117
+ _this2.connectToAbility(_this2.state.ability);
118
+ });
119
+ } else {
120
+ this.recheck(props);
121
+ }
122
+ };
123
+
124
+ Can.prototype.componentWillMount = function componentWillMount() {
125
+ this.connectToAbility(this.state.ability);
126
+ };
127
+
128
+ Can.prototype.componentWillUnmount = function componentWillUnmount() {
129
+ this.unsubscribeFromAbility();
130
+ };
131
+
132
+ Can.prototype.connectToAbility = function connectToAbility(ability) {
133
+ var _this3 = this;
134
+
135
+ this.unsubscribeFromAbility();
136
+
137
+ if (ability) {
138
+ this.unsubscribeFromAbility = ability.on('updated', function () {
139
+ return _this3.recheck();
140
+ });
141
+ this.recheck();
142
+ }
143
+ };
144
+
145
+ Can.prototype.recheck = function recheck(props) {
146
+ return this.setState({ allowed: this.check(props) });
147
+ };
148
+
149
+ Can.prototype.check = function check() {
150
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
151
+
152
+ var params = props || this.props;
153
+
154
+ var _split = (params.I || params.do).split(/\s+/),
155
+ action = _split[0],
156
+ field = _split[1];
157
+
158
+ var subject = params.of || params.a || params.this || params.on;
159
+ var can = params.not ? 'cannot' : 'can';
160
+
161
+ return this.state.ability[can](action, subject, field);
162
+ };
163
+
164
+ Can.prototype.render = function render() {
165
+ var canRender = this.props.passThrough || this.state.allowed;
166
+ return canRender ? this.renderChildren() : null;
167
+ };
168
+
169
+ Can.prototype.renderChildren = function renderChildren() {
170
+ var children = this.props.children;
171
+
172
+ var elements = typeof children === 'function' ? children(this.state.allowed, this.state.ability) : children;
173
+
174
+ return _renderChildren(elements);
175
+ };
176
+
177
+ createClass(Can, [{
178
+ key: 'allowed',
179
+ get: function get$$1() {
180
+ return this.state.allowed;
181
+ }
182
+ }]);
183
+ return Can;
184
+ }(PureComponent);
185
+
186
+ Can.propTypes = propTypes;
187
+
188
+ function createCanBoundTo(ability) {
189
+ var _class, _temp;
190
+
191
+ return _temp = _class = function (_Can) {
192
+ inherits(BoundCan, _Can);
193
+
194
+ function BoundCan() {
195
+ classCallCheck(this, BoundCan);
196
+
197
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
198
+ args[_key] = arguments[_key];
199
+ }
200
+
201
+ var _this = possibleConstructorReturn(this, _Can.call.apply(_Can, [this].concat(args)));
202
+
203
+ _this.state.ability = _this.state.ability || ability;
204
+ return _this;
205
+ }
206
+
207
+ return BoundCan;
208
+ }(Can), _class.propTypes = Object.assign({}, Can.propTypes, {
209
+ ability: PropTypes.instanceOf(Ability)
210
+ }), _temp;
211
+ }
212
+
213
+ function createContextualCan(Consumer) {
214
+ return function ContextualCan(props) {
215
+ return createElement(Consumer, null, function (ability) {
216
+ return createElement(Can, {
217
+ ability: props.ability || ability,
218
+ I: props.I || props.do,
219
+ a: props.on || props.a || props.an || props.of || props.this,
220
+ not: props.not,
221
+ children: props.children,
222
+ passThrough: props.passThrough
223
+ });
224
+ });
225
+ };
226
+ }
227
+
228
+ export { Can, createCanBoundTo, createContextualCan };
package/dist/es6/index.js CHANGED
@@ -1,17 +1,34 @@
1
- import React, { PureComponent, createElement } from 'react';
1
+ import React, { PureComponent, Fragment, createElement } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Ability } from '@casl/ability';
4
4
 
5
5
  const noop = () => {};
6
- const REQUIRED_OBJECT_OR_STRING = PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired;
6
+ const renderChildren = Fragment ? children => createElement.apply(null, [Fragment, null].concat(children)) : React.Children.only;
7
+ let propTypes = {};
7
8
 
8
- function alias(names, validate) {
9
- return (props, ...args) => {
9
+ if (process.env.NODE_ENV !== 'production') {
10
+ const REQUIRED_OBJECT_OR_STRING = PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired;
11
+
12
+ const alias = (names, validate) => (props, ...args) => {
10
13
  // eslint-disable-line
11
14
  if (!names.split(' ').some(name => props[name])) {
12
15
  return validate(props, ...args);
13
16
  }
14
17
  };
18
+
19
+ propTypes = {
20
+ I: alias('do', PropTypes.string.isRequired),
21
+ a: alias('on this of an', REQUIRED_OBJECT_OR_STRING),
22
+ an: alias('on this of a', REQUIRED_OBJECT_OR_STRING),
23
+ of: alias('on a this an', REQUIRED_OBJECT_OR_STRING),
24
+ this: alias('on a of an', REQUIRED_OBJECT_OR_STRING),
25
+ do: alias('I', PropTypes.string.isRequired),
26
+ on: alias('this a of an', REQUIRED_OBJECT_OR_STRING),
27
+ not: PropTypes.bool,
28
+ passThrough: PropTypes.bool,
29
+ children: PropTypes.any.isRequired,
30
+ ability: PropTypes.instanceOf(Ability).isRequired
31
+ };
15
32
  }
16
33
 
17
34
  class Can extends PureComponent {
@@ -32,8 +49,9 @@ class Can extends PureComponent {
32
49
 
33
50
  componentWillReceiveProps(props) {
34
51
  if (props.ability && this.state.ability !== props.ability) {
35
- this.setState({ ability: props.ability });
36
- this.connectToAbility(props.ability);
52
+ this.setState({ ability: props.ability }, () => {
53
+ this.connectToAbility(this.state.ability);
54
+ });
37
55
  } else {
38
56
  this.recheck(props);
39
57
  }
@@ -70,26 +88,18 @@ class Can extends PureComponent {
70
88
  }
71
89
 
72
90
  render() {
73
- return this.state.allowed ? this.renderChildren() : null;
91
+ const canRender = this.props.passThrough || this.state.allowed;
92
+ return canRender ? this.renderChildren() : null;
74
93
  }
75
94
 
76
95
  renderChildren() {
77
96
  const { children } = this.props;
97
+ const elements = typeof children === 'function' ? children(this.state.allowed, this.state.ability) : children;
78
98
 
79
- return typeof children === 'function' ? children(this.state.ability) : React.Children.only(children);
99
+ return renderChildren(elements);
80
100
  }
81
101
  }
82
- Can.propTypes = {
83
- I: alias('do', PropTypes.string.isRequired),
84
- a: alias('on this of', REQUIRED_OBJECT_OR_STRING),
85
- of: alias('on a this', REQUIRED_OBJECT_OR_STRING),
86
- this: alias('on a of', REQUIRED_OBJECT_OR_STRING),
87
- do: alias('I', PropTypes.string.isRequired),
88
- on: alias('this a of', REQUIRED_OBJECT_OR_STRING),
89
- not: PropTypes.bool,
90
- children: PropTypes.any.isRequired,
91
- ability: PropTypes.instanceOf(Ability).isRequired
92
- };
102
+ Can.propTypes = propTypes;
93
103
 
94
104
  function createCanBoundTo(ability) {
95
105
  var _class, _temp;
@@ -110,9 +120,10 @@ function createContextualCan(Consumer) {
110
120
  return createElement(Consumer, null, ability => createElement(Can, {
111
121
  ability: props.ability || ability,
112
122
  I: props.I || props.do,
113
- a: props.a || props.of || props.this || props.on,
123
+ a: props.on || props.a || props.an || props.of || props.this,
114
124
  not: props.not,
115
- children: props.children
125
+ children: props.children,
126
+ passThrough: props.passThrough
116
127
  }));
117
128
  };
118
129
  }
package/dist/umd/index.js CHANGED
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react"),require("prop-types"),require("@casl/ability")):"function"==typeof define&&define.amd?define(["exports","react","prop-types","@casl/ability"],e):e((t.casl=t.casl||{},t.casl.react={}),t.React,t.React.PropTypes,t.casl)}(this,function(t,n,i,r){"use strict";var e="default"in n?n.default:n;i=i&&i.hasOwnProperty("default")?i.default:i;var l=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},a=function(){function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),t}}(),c=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},u=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},s=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return function(t,e){var n=[],i=!0,r=!1,o=void 0;try{for(var a,l=t[Symbol.iterator]();!(i=(a=l.next()).done)&&(n.push(a.value),!e||n.length!==e);i=!0);}catch(t){r=!0,o=t}finally{try{!i&&l.return&&l.return()}finally{if(r)throw o}}return n}(t,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")},f=function(){},o=i.oneOfType([i.object,i.string]).isRequired;function y(r,o){return function(e){for(var t=arguments.length,n=Array(1<t?t-1:0),i=1;i<t;i++)n[i-1]=arguments[i];if(!r.split(" ").some(function(t){return e[t]}))return o.apply(void 0,[e].concat(n))}}var p=function(t){function o(){var t;l(this,o);for(var e=arguments.length,n=Array(e),i=0;i<e;i++)n[i]=arguments[i];var r=u(this,(t=o.__proto__||Object.getPrototypeOf(o)).call.apply(t,[this].concat(n)));return r.unsubscribeFromAbility=f,r.state={ability:r.props.ability,allowed:!1},r}return c(o,t),a(o,[{key:"componentWillReceiveProps",value:function(t){t.ability&&this.state.ability!==t.ability?(this.setState({ability:t.ability}),this.connectToAbility(t.ability)):this.recheck(t)}},{key:"componentWillMount",value:function(){this.connectToAbility(this.state.ability)}},{key:"componentWillUnmount",value:function(){this.unsubscribeFromAbility()}},{key:"connectToAbility",value:function(t){var e=this;this.unsubscribeFromAbility(),t&&(this.unsubscribeFromAbility=t.on("updated",function(){return e.recheck()}),this.recheck())}},{key:"recheck",value:function(t){return this.setState({allowed:this.check(t)})}},{key:"check",value:function(){var t=(0<arguments.length&&void 0!==arguments[0]?arguments[0]:null)||this.props,e=(t.I||t.do).split(/\s+/),n=s(e,2),i=n[0],r=n[1],o=t.of||t.a||t.this||t.on,a=t.not?"cannot":"can";return this.state.ability[a](i,o,r)}},{key:"render",value:function(){return this.state.allowed?this.renderChildren():null}},{key:"renderChildren",value:function(){var t=this.props.children;return"function"==typeof t?t(this.state.ability):e.Children.only(t)}},{key:"allowed",get:function(){return this.state.allowed}}]),o}(n.PureComponent);p.propTypes={I:y("do",i.string.isRequired),a:y("on this of",o),of:y("on a this",o),this:y("on a of",o),do:y("I",i.string.isRequired),on:y("this a of",o),not:i.bool,children:i.any.isRequired,ability:i.instanceOf(r.Ability).isRequired},t.Can=p,t.createCanBoundTo=function(a){var t,e;return e=t=function(t){function o(){var t;l(this,o);for(var e=arguments.length,n=Array(e),i=0;i<e;i++)n[i]=arguments[i];var r=u(this,(t=o.__proto__||Object.getPrototypeOf(o)).call.apply(t,[this].concat(n)));return r.state.ability=r.state.ability||a,r}return c(o,p),o}(),t.propTypes=Object.assign({},p.propTypes,{ability:i.instanceOf(r.Ability)}),e},t.createContextualCan=function(t){return function(e){return n.createElement(t,null,function(t){return n.createElement(p,{ability:e.ability||t,I:e.I||e.do,a:e.a||e.of||e.this||e.on,not:e.not,children:e.children})})}},Object.defineProperty(t,"__esModule",{value:!0})});
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react"),require("prop-types"),require("@casl/ability")):"function"==typeof define&&define.amd?define(["exports","react","prop-types","@casl/ability"],e):e((t.casl=t.casl||{},t.casl.react={}),t.React,t.React.PropTypes,t.casl)}(this,function(t,n,i,o){"use strict";var e="default"in n?n.default:n;i=i&&i.hasOwnProperty("default")?i.default:i;var s=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},a=function(){function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),t}}(),c=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},l=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},u=function(){},p=n.Fragment?function(t){return n.createElement.apply(null,[n.Fragment,null].concat(t))}:e.Children.only,r={};if("production"!==process.env.NODE_ENV){var f=i.oneOfType([i.object,i.string]).isRequired,y=function(o,r){return function(e){for(var t=arguments.length,n=Array(1<t?t-1:0),i=1;i<t;i++)n[i-1]=arguments[i];if(!o.split(" ").some(function(t){return e[t]}))return r.apply(void 0,[e].concat(n))}};r={I:y("do",i.string.isRequired),a:y("on this of an",f),an:y("on this of a",f),of:y("on a this an",f),this:y("on a of an",f),do:y("I",i.string.isRequired),on:y("this a of an",f),not:i.bool,passThrough:i.bool,children:i.any.isRequired,ability:i.instanceOf(o.Ability).isRequired}}var h=function(o){function r(){s(this,r);for(var t=arguments.length,e=Array(t),n=0;n<t;n++)e[n]=arguments[n];var i=l(this,o.call.apply(o,[this].concat(e)));return i.unsubscribeFromAbility=u,i.state={ability:i.props.ability,allowed:!1},i}return c(r,o),r.prototype.componentWillReceiveProps=function(t){var e=this;t.ability&&this.state.ability!==t.ability?this.setState({ability:t.ability},function(){e.connectToAbility(e.state.ability)}):this.recheck(t)},r.prototype.componentWillMount=function(){this.connectToAbility(this.state.ability)},r.prototype.componentWillUnmount=function(){this.unsubscribeFromAbility()},r.prototype.connectToAbility=function(t){var e=this;this.unsubscribeFromAbility(),t&&(this.unsubscribeFromAbility=t.on("updated",function(){return e.recheck()}),this.recheck())},r.prototype.recheck=function(t){return this.setState({allowed:this.check(t)})},r.prototype.check=function(){var t=(0<arguments.length&&void 0!==arguments[0]?arguments[0]:null)||this.props,e=(t.I||t.do).split(/\s+/),n=e[0],i=e[1],o=t.of||t.a||t.this||t.on,r=t.not?"cannot":"can";return this.state.ability[r](n,o,i)},r.prototype.render=function(){return this.props.passThrough||this.state.allowed?this.renderChildren():null},r.prototype.renderChildren=function(){var t=this.props.children,e="function"==typeof t?t(this.state.allowed,this.state.ability):t;return p(e)},a(r,[{key:"allowed",get:function(){return this.state.allowed}}]),r}(n.PureComponent);h.propTypes=r,t.Can=h,t.createCanBoundTo=function(a){var t,e;return e=t=function(o){function r(){s(this,r);for(var t=arguments.length,e=Array(t),n=0;n<t;n++)e[n]=arguments[n];var i=l(this,o.call.apply(o,[this].concat(e)));return i.state.ability=i.state.ability||a,i}return c(r,o),r}(h),t.propTypes=Object.assign({},h.propTypes,{ability:i.instanceOf(o.Ability)}),e},t.createContextualCan=function(t){return function(e){return n.createElement(t,null,function(t){return n.createElement(h,{ability:e.ability||t,I:e.I||e.do,a:e.on||e.a||e.an||e.of||e.this,not:e.not,children:e.children,passThrough:e.passThrough})})}},Object.defineProperty(t,"__esModule",{value:!0})});
package/index.d.ts CHANGED
@@ -7,6 +7,9 @@ type BaseProps = {
7
7
  } | {
8
8
  I: string
9
9
  a: string
10
+ } | {
11
+ I: string
12
+ an: string
10
13
  } | {
11
14
  I: string
12
15
  of: any
@@ -17,12 +20,14 @@ type BaseProps = {
17
20
 
18
21
  type CanPropsStrict = BaseProps & {
19
22
  ability: Ability
20
- not: boolean
23
+ not?: boolean
24
+ passThrough?: boolean
21
25
  }
22
26
 
23
27
  type CanProps = BaseProps & {
24
28
  ability?: Ability
25
- not: boolean
29
+ not?: boolean
30
+ passThrough?: boolean
26
31
  }
27
32
 
28
33
  declare class CanComponent<T> extends PureComponent<T> {
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@casl/react",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
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
- "module": "index.js",
6
+ "module": "dist/es5m/index.js",
7
7
  "es2015": "dist/es6/index.js",
8
8
  "typings": "./index.d.ts",
9
9
  "repository": {
@@ -39,7 +39,7 @@
39
39
  "npm": "^6.0.0"
40
40
  },
41
41
  "peerDependencies": {
42
- "@casl/ability": "^2.0.0-alpha.1",
42
+ "@casl/ability": "^2.0.0",
43
43
  "prop-types": "^15.0.0",
44
44
  "react": "^15.0.0 || ^16.0.0"
45
45
  },
@@ -48,7 +48,6 @@
48
48
  "check-prop-types": "^1.1.2",
49
49
  "prop-types": "^15.6.0",
50
50
  "react": "^16.3.0",
51
- "react-test-renderer": "^16.3.0",
52
- "semantic-release": "^15.5.0"
51
+ "react-test-renderer": "^16.3.0"
53
52
  }
54
53
  }
package/index.js DELETED
@@ -1,262 +0,0 @@
1
- import React, { PureComponent, createElement } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { Ability } from '@casl/ability';
4
-
5
- var classCallCheck = function (instance, Constructor) {
6
- if (!(instance instanceof Constructor)) {
7
- throw new TypeError("Cannot call a class as a function");
8
- }
9
- };
10
-
11
- var createClass = function () {
12
- function defineProperties(target, props) {
13
- for (var i = 0; i < props.length; i++) {
14
- var descriptor = props[i];
15
- descriptor.enumerable = descriptor.enumerable || false;
16
- descriptor.configurable = true;
17
- if ("value" in descriptor) descriptor.writable = true;
18
- Object.defineProperty(target, descriptor.key, descriptor);
19
- }
20
- }
21
-
22
- return function (Constructor, protoProps, staticProps) {
23
- if (protoProps) defineProperties(Constructor.prototype, protoProps);
24
- if (staticProps) defineProperties(Constructor, staticProps);
25
- return Constructor;
26
- };
27
- }();
28
-
29
- var inherits = function (subClass, superClass) {
30
- if (typeof superClass !== "function" && superClass !== null) {
31
- throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
32
- }
33
-
34
- subClass.prototype = Object.create(superClass && superClass.prototype, {
35
- constructor: {
36
- value: subClass,
37
- enumerable: false,
38
- writable: true,
39
- configurable: true
40
- }
41
- });
42
- if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
43
- };
44
-
45
- var possibleConstructorReturn = function (self, call) {
46
- if (!self) {
47
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
48
- }
49
-
50
- return call && (typeof call === "object" || typeof call === "function") ? call : self;
51
- };
52
-
53
- var slicedToArray = function () {
54
- function sliceIterator(arr, i) {
55
- var _arr = [];
56
- var _n = true;
57
- var _d = false;
58
- var _e = undefined;
59
-
60
- try {
61
- for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
62
- _arr.push(_s.value);
63
-
64
- if (i && _arr.length === i) break;
65
- }
66
- } catch (err) {
67
- _d = true;
68
- _e = err;
69
- } finally {
70
- try {
71
- if (!_n && _i["return"]) _i["return"]();
72
- } finally {
73
- if (_d) throw _e;
74
- }
75
- }
76
-
77
- return _arr;
78
- }
79
-
80
- return function (arr, i) {
81
- if (Array.isArray(arr)) {
82
- return arr;
83
- } else if (Symbol.iterator in Object(arr)) {
84
- return sliceIterator(arr, i);
85
- } else {
86
- throw new TypeError("Invalid attempt to destructure non-iterable instance");
87
- }
88
- };
89
- }();
90
-
91
- var noop = function noop() {};
92
- var REQUIRED_OBJECT_OR_STRING = PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired;
93
-
94
- function alias(names, validate) {
95
- return function (props) {
96
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
97
- args[_key - 1] = arguments[_key];
98
- }
99
-
100
- // eslint-disable-line
101
- if (!names.split(' ').some(function (name) {
102
- return props[name];
103
- })) {
104
- return validate.apply(undefined, [props].concat(args));
105
- }
106
- };
107
- }
108
-
109
- var Can = function (_PureComponent) {
110
- inherits(Can, _PureComponent);
111
-
112
- function Can() {
113
- var _ref;
114
-
115
- classCallCheck(this, Can);
116
-
117
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
118
- args[_key2] = arguments[_key2];
119
- }
120
-
121
- var _this = possibleConstructorReturn(this, (_ref = Can.__proto__ || Object.getPrototypeOf(Can)).call.apply(_ref, [this].concat(args)));
122
-
123
- _this.unsubscribeFromAbility = noop;
124
- _this.state = {
125
- ability: _this.props.ability,
126
- allowed: false
127
- };
128
- return _this;
129
- }
130
-
131
- createClass(Can, [{
132
- key: 'componentWillReceiveProps',
133
- value: function componentWillReceiveProps(props) {
134
- if (props.ability && this.state.ability !== props.ability) {
135
- this.setState({ ability: props.ability });
136
- this.connectToAbility(props.ability);
137
- } else {
138
- this.recheck(props);
139
- }
140
- }
141
- }, {
142
- key: 'componentWillMount',
143
- value: function componentWillMount() {
144
- this.connectToAbility(this.state.ability);
145
- }
146
- }, {
147
- key: 'componentWillUnmount',
148
- value: function componentWillUnmount() {
149
- this.unsubscribeFromAbility();
150
- }
151
- }, {
152
- key: 'connectToAbility',
153
- value: function connectToAbility(ability) {
154
- var _this2 = this;
155
-
156
- this.unsubscribeFromAbility();
157
-
158
- if (ability) {
159
- this.unsubscribeFromAbility = ability.on('updated', function () {
160
- return _this2.recheck();
161
- });
162
- this.recheck();
163
- }
164
- }
165
- }, {
166
- key: 'recheck',
167
- value: function recheck(props) {
168
- return this.setState({ allowed: this.check(props) });
169
- }
170
- }, {
171
- key: 'check',
172
- value: function check() {
173
- var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
174
-
175
- var params = props || this.props;
176
-
177
- var _split = (params.I || params.do).split(/\s+/),
178
- _split2 = slicedToArray(_split, 2),
179
- action = _split2[0],
180
- field = _split2[1];
181
-
182
- var subject = params.of || params.a || params.this || params.on;
183
- var can = params.not ? 'cannot' : 'can';
184
-
185
- return this.state.ability[can](action, subject, field);
186
- }
187
- }, {
188
- key: 'render',
189
- value: function render() {
190
- return this.state.allowed ? this.renderChildren() : null;
191
- }
192
- }, {
193
- key: 'renderChildren',
194
- value: function renderChildren() {
195
- var children = this.props.children;
196
-
197
-
198
- return typeof children === 'function' ? children(this.state.ability) : React.Children.only(children);
199
- }
200
- }, {
201
- key: 'allowed',
202
- get: function get$$1() {
203
- return this.state.allowed;
204
- }
205
- }]);
206
- return Can;
207
- }(PureComponent);
208
-
209
- Can.propTypes = {
210
- I: alias('do', PropTypes.string.isRequired),
211
- a: alias('on this of', REQUIRED_OBJECT_OR_STRING),
212
- of: alias('on a this', REQUIRED_OBJECT_OR_STRING),
213
- this: alias('on a of', REQUIRED_OBJECT_OR_STRING),
214
- do: alias('I', PropTypes.string.isRequired),
215
- on: alias('this a of', REQUIRED_OBJECT_OR_STRING),
216
- not: PropTypes.bool,
217
- children: PropTypes.any.isRequired,
218
- ability: PropTypes.instanceOf(Ability).isRequired
219
- };
220
-
221
- function createCanBoundTo(ability) {
222
- var _class, _temp;
223
-
224
- return _temp = _class = function (_Can) {
225
- inherits(BoundCan, _Can);
226
-
227
- function BoundCan() {
228
- var _ref;
229
-
230
- classCallCheck(this, BoundCan);
231
-
232
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
233
- args[_key] = arguments[_key];
234
- }
235
-
236
- var _this = possibleConstructorReturn(this, (_ref = BoundCan.__proto__ || Object.getPrototypeOf(BoundCan)).call.apply(_ref, [this].concat(args)));
237
-
238
- _this.state.ability = _this.state.ability || ability;
239
- return _this;
240
- }
241
-
242
- return BoundCan;
243
- }(Can), _class.propTypes = Object.assign({}, Can.propTypes, {
244
- ability: PropTypes.instanceOf(Ability)
245
- }), _temp;
246
- }
247
-
248
- function createContextualCan(Consumer) {
249
- return function ContextualCan(props) {
250
- return createElement(Consumer, null, function (ability) {
251
- return createElement(Can, {
252
- ability: props.ability || ability,
253
- I: props.I || props.do,
254
- a: props.a || props.of || props.this || props.on,
255
- not: props.not,
256
- children: props.children
257
- });
258
- });
259
- };
260
- }
261
-
262
- export { Can, createCanBoundTo, createContextualCan };