react-ability-kit 0.1.5 → 0.1.6

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.
Files changed (2) hide show
  1. package/README.md +97 -36
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -9,6 +9,12 @@ Keep authorization logic **out of your components** and **in one place**.
9
9
 
10
10
  Most React apps don’t plan to become permission nightmares — they just grow into one.
11
11
 
12
+ Permissions slowly spread across components as ad-hoc checks:
13
+
14
+ - `if (user.role === "admin")`
15
+ - `if (invoice.ownerId === user.id)`
16
+ - `if (permissions.includes("invoice:update"))`
17
+
12
18
  This package introduces a **policy-first** approach to permissions, so your UI stays clean and your rules stay auditable.
13
19
 
14
20
  ---
@@ -50,9 +56,9 @@ if (user && user.role !== "guest") {
50
56
 
51
57
  ### Problems this creates
52
58
 
53
- - ❌ **Logic duplication** – same rules rewritten in different places
54
- - ❌ **Rules drift** – one condition changes, others don’t
55
- - ❌ **Impossible to audit** – “Who can edit invoices?” → grep the whole repo
59
+ - ❌ **Logic duplication** – same rules rewritten in different places
60
+ - ❌ **Rules drift** – one condition changes, others don’t
61
+ - ❌ **Impossible to audit** – “Who can edit invoices?” → grep the whole repo
56
62
  - ❌ **UI inconsistencies**
57
63
  - Button visible but API rejects
58
64
  - Button hidden but API allows
@@ -87,21 +93,100 @@ User ──► Policy ──► Ability ──► UI / Components
87
93
 
88
94
  ---
89
95
 
96
+ ## Installation
97
+
98
+ ```bash
99
+ npm install react-ability
100
+ ```
101
+
102
+ or
103
+
104
+ ```bash
105
+ pnpm add react-ability
106
+ ```
107
+
108
+ or
109
+
110
+ ```bash
111
+ yarn add react-ability
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Quick start (5 minutes)
117
+
118
+ ### 1️⃣ Define your abilities (policy-first)
119
+
120
+ Create a single policy file.
121
+
122
+ ```ts
123
+ // ability.ts
124
+ import { defineAbility } from "react-ability";
125
+
126
+ export const ability = defineAbility((allow, deny, user) => {
127
+ allow("read", "Invoice");
128
+
129
+ allow(
130
+ "update",
131
+ "Invoice",
132
+ invoice => invoice.ownerId === user.id && invoice.status === "draft"
133
+ );
134
+
135
+ deny("delete", "Invoice");
136
+ });
137
+ ```
138
+
139
+ This file is your **single source of truth**.
140
+
141
+ ---
142
+
143
+ ### 2️⃣ Provide the ability to your app
144
+
145
+ ```tsx
146
+ import { AbilityProvider } from "react-ability";
147
+ import { ability } from "./ability";
148
+
149
+ export function App() {
150
+ return (
151
+ <AbilityProvider ability={ability}>
152
+ <YourApp />
153
+ </AbilityProvider>
154
+ );
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ### 3️⃣ Use permissions anywhere
161
+
162
+ #### Using the `<Can />` component
163
+
164
+ ```tsx
165
+ <Can I="update" a="Invoice" this={invoice}>
166
+ <EditButton />
167
+ </Can>
168
+ ```
169
+
170
+ #### Using the `can()` function
171
+
172
+ ```ts
173
+ const canEdit = can("update", "Invoice", invoice);
174
+ ```
175
+
176
+ ---
177
+
90
178
  ## What this package actually solves
91
179
 
92
180
  ### 1️⃣ Single source of truth for permissions
93
181
 
94
182
  ```ts
95
- // policy.ts
96
183
  allow("update", "Invoice", invoice => invoice.ownerId === user.id);
97
184
  deny("delete", "Invoice");
98
185
  ```
99
186
 
100
- **Result**
101
-
102
187
  - All rules live in one place
103
188
  - Easy to review, change, and reason about
104
- - No more scattered conditions
189
+ - No scattered conditionals
105
190
 
106
191
  ---
107
192
 
@@ -173,14 +258,6 @@ This removes an entire class of bugs.
173
258
 
174
259
  ### 5️⃣ Ownership rules become first-class
175
260
 
176
- ❌ Scattered ownership checks
177
-
178
- ```ts
179
- if (invoice.ownerId === user.id)
180
- ```
181
-
182
- ✅ Centralized ownership rule
183
-
184
261
  ```ts
185
262
  allow("update", "Invoice", invoice => invoice.ownerId === user.id);
186
263
  ```
@@ -195,17 +272,9 @@ Ownership logic is now:
195
272
 
196
273
  ### 6️⃣ Predictable SSR & hydration
197
274
 
198
- Without a system:
199
-
200
- - UI flickers
201
- - Buttons appear/disappear after hydration
202
- - Server/client logic diverges
203
-
204
- With **React Ability**:
205
-
206
- - Ability is built once from user data
207
- - Server and client agree on permissions
208
- - Stable, predictable rendering
275
+ - No permission flicker
276
+ - No server/client mismatch
277
+ - Same rules, same result everywhere
209
278
 
210
279
  ---
211
280
 
@@ -215,15 +284,7 @@ It’s not magic.
215
284
 
216
285
  It simply means:
217
286
 
218
- > Render children **only if the permission passes**.
219
-
220
- Instead of:
221
-
222
- ```tsx
223
- if (!canEdit) return null;
224
- ```
225
-
226
- You write:
287
+ > Render children **only if the permission passes**
227
288
 
228
289
  ```tsx
229
290
  <Can I="update" a="Invoice" this={invoice}>
@@ -268,7 +329,7 @@ It answers one question only:
268
329
 
269
330
  - ❌ Landing pages
270
331
  - ❌ Simple blogs
271
- - ❌ Apps with only admin / non-admin logic
332
+ - ❌ Admin / non-admin only apps
272
333
 
273
334
  ---
274
335
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-ability-kit",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",