@pyreon/permissions 0.7.0 → 0.9.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 +78 -0
- package/package.json +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# @pyreon/permissions
|
|
2
|
+
|
|
3
|
+
Reactive permissions for Pyreon. Type-safe, signal-driven, universal — works with RBAC, ABAC, feature flags, and subscription tiers. Any model maps to string keys with boolean or predicate values.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @pyreon/permissions
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { createPermissions } from '@pyreon/permissions'
|
|
15
|
+
|
|
16
|
+
const can = createPermissions({
|
|
17
|
+
'posts.read': true,
|
|
18
|
+
'posts.create': true,
|
|
19
|
+
'posts.update': (post: Post) => post.authorId === currentUserId(),
|
|
20
|
+
'users.manage': false,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
can('posts.read') // true — reactive in effects/JSX
|
|
24
|
+
can('posts.update', myPost) // evaluates predicate
|
|
25
|
+
can.not('billing.export') // true if denied
|
|
26
|
+
can.all('posts.read', 'posts.create') // true if both granted
|
|
27
|
+
can.any('posts.read', 'users.manage') // true if any granted
|
|
28
|
+
|
|
29
|
+
// Update after login / role change
|
|
30
|
+
can.set(fromRole(user.role))
|
|
31
|
+
can.patch({ 'billing.export': true })
|
|
32
|
+
|
|
33
|
+
// Reactive in JSX
|
|
34
|
+
{() => can('posts.delete') && <DeleteButton />}
|
|
35
|
+
{() => can('users.manage') && <AdminPanel />}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Wildcards
|
|
39
|
+
|
|
40
|
+
`'posts.*'` matches any `posts.X`. `'*'` matches everything (superadmin).
|
|
41
|
+
|
|
42
|
+
## Context Pattern
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { PermissionsProvider, usePermissions } from '@pyreon/permissions'
|
|
46
|
+
|
|
47
|
+
<PermissionsProvider instance={can}>
|
|
48
|
+
<App />
|
|
49
|
+
</PermissionsProvider>
|
|
50
|
+
|
|
51
|
+
// In any child component:
|
|
52
|
+
const can = usePermissions()
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## API
|
|
56
|
+
|
|
57
|
+
### `createPermissions(initial?)`
|
|
58
|
+
|
|
59
|
+
Create a reactive permissions instance. Permission values are `boolean` (static) or `(context?) => boolean` (predicate).
|
|
60
|
+
|
|
61
|
+
| Method | Description |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| `can(key, context?)` | Check a permission (reactive) |
|
|
64
|
+
| `can.not(key)` | Inverse check |
|
|
65
|
+
| `can.all(...keys)` | True if all granted |
|
|
66
|
+
| `can.any(...keys)` | True if any granted |
|
|
67
|
+
| `can.set(map)` | Replace all permissions |
|
|
68
|
+
| `can.patch(map)` | Merge permissions |
|
|
69
|
+
| `can.granted()` | `Computed<string[]>` of all granted keys |
|
|
70
|
+
| `can.entries()` | `Computed<[key, value][]>` for introspection |
|
|
71
|
+
|
|
72
|
+
### `PermissionsProvider` / `usePermissions()`
|
|
73
|
+
|
|
74
|
+
Context pattern for dependency injection, SSR, and testing.
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/permissions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Reactive permissions for Pyreon — type-safe, signal-driven, universal",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"typecheck": "tsc --noEmit"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@pyreon/core": ">=0.
|
|
44
|
-
"@pyreon/reactivity": ">=0.
|
|
43
|
+
"@pyreon/core": ">=0.7.0 <0.8.0",
|
|
44
|
+
"@pyreon/reactivity": ">=0.7.0 <0.8.0"
|
|
45
45
|
}
|
|
46
46
|
}
|