react-auth-gate 0.0.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.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +653 -0
  3. package/dist/core/ruleEngine.d.ts +47 -0
  4. package/dist/core/ruleEngine.d.ts.map +1 -0
  5. package/dist/core/ruleEngine.js +138 -0
  6. package/dist/core/types.d.ts +122 -0
  7. package/dist/core/types.d.ts.map +1 -0
  8. package/dist/core/types.js +7 -0
  9. package/dist/devtools/DevPanel.d.ts +13 -0
  10. package/dist/devtools/DevPanel.d.ts.map +1 -0
  11. package/dist/devtools/DevPanel.js +308 -0
  12. package/dist/devtools/DevStore.d.ts +80 -0
  13. package/dist/devtools/DevStore.d.ts.map +1 -0
  14. package/dist/devtools/DevStore.js +152 -0
  15. package/dist/devtools/PermissionsRoot.d.ts +33 -0
  16. package/dist/devtools/PermissionsRoot.d.ts.map +1 -0
  17. package/dist/devtools/PermissionsRoot.js +46 -0
  18. package/dist/devtools/useDevRegister.d.ts +17 -0
  19. package/dist/devtools/useDevRegister.d.ts.map +1 -0
  20. package/dist/devtools/useDevRegister.js +29 -0
  21. package/dist/index.d.ts +22 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +21 -0
  24. package/dist/react/Permissioned.d.ts +41 -0
  25. package/dist/react/Permissioned.d.ts.map +1 -0
  26. package/dist/react/Permissioned.js +29 -0
  27. package/dist/react/PermissionsGate.d.ts +79 -0
  28. package/dist/react/PermissionsGate.d.ts.map +1 -0
  29. package/dist/react/PermissionsGate.js +101 -0
  30. package/dist/react/PermissionsProvider.d.ts +39 -0
  31. package/dist/react/PermissionsProvider.d.ts.map +1 -0
  32. package/dist/react/PermissionsProvider.js +93 -0
  33. package/dist/react/ProtectedRoute.d.ts +80 -0
  34. package/dist/react/ProtectedRoute.d.ts.map +1 -0
  35. package/dist/react/ProtectedRoute.js +92 -0
  36. package/dist/react/usePermission.d.ts +50 -0
  37. package/dist/react/usePermission.d.ts.map +1 -0
  38. package/dist/react/usePermission.js +71 -0
  39. package/package.json +56 -0
@@ -0,0 +1,80 @@
1
+ /**
2
+ * DevStore
3
+ *
4
+ * Centralized state management for dev tools.
5
+ * Tracks all permission evaluations and provides override capabilities.
6
+ */
7
+ import type { PermissionEvaluation, DevToolsState } from '../core/types';
8
+ /**
9
+ * Dev tools store
10
+ * Simple observable pattern for managing dev panel state
11
+ */
12
+ export declare class DevStore {
13
+ private state;
14
+ private listeners;
15
+ /**
16
+ * Get current state
17
+ */
18
+ getState(): DevToolsState;
19
+ /**
20
+ * Subscribe to state changes
21
+ */
22
+ subscribe(listener: (state: DevToolsState) => void): () => void;
23
+ /**
24
+ * Notify all listeners of state change
25
+ */
26
+ private notify;
27
+ /**
28
+ * Add a permission evaluation
29
+ */
30
+ addEvaluation(evaluation: PermissionEvaluation): void;
31
+ /**
32
+ * Clear all evaluations
33
+ */
34
+ clearEvaluations(): void;
35
+ /**
36
+ * Toggle panel open/closed
37
+ */
38
+ togglePanel(): void;
39
+ /**
40
+ * Set panel open state
41
+ */
42
+ setOpen(isOpen: boolean): void;
43
+ /**
44
+ * Set override user for testing
45
+ */
46
+ setOverrideUser(user: any): void;
47
+ /**
48
+ * Set override roles for testing
49
+ */
50
+ setOverrideRoles(roles: string[] | undefined): void;
51
+ /**
52
+ * Set override permissions for testing
53
+ */
54
+ setOverridePermissions(permissions: string[] | undefined): void;
55
+ /**
56
+ * Set override flags for testing
57
+ */
58
+ setOverrideFlags(flags: Record<string, boolean> | undefined): void;
59
+ /**
60
+ * Toggle a specific role
61
+ */
62
+ toggleRole(role: string, currentRoles: string[]): void;
63
+ /**
64
+ * Toggle a specific permission
65
+ */
66
+ togglePermission(permission: string, currentPermissions: string[]): void;
67
+ /**
68
+ * Toggle a feature flag
69
+ */
70
+ toggleFlag(flag: string, currentFlags: Record<string, boolean>): void;
71
+ /**
72
+ * Reset all overrides
73
+ */
74
+ resetOverrides(): void;
75
+ }
76
+ /**
77
+ * Global dev store instance
78
+ */
79
+ export declare const devStore: DevStore;
80
+ //# sourceMappingURL=DevStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevStore.d.ts","sourceRoot":"","sources":["../../src/devtools/DevStore.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzE;;;GAGG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAOX;IAEF,OAAO,CAAC,SAAS,CAAkD;IAEnE;;OAEG;IACH,QAAQ,IAAI,aAAa;IAIzB;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,MAAM,IAAI;IAS/D;;OAEG;IACH,OAAO,CAAC,MAAM;IAKd;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,oBAAoB;IAK9C;;OAEG;IACH,gBAAgB;IAKhB;;OAEG;IACH,WAAW;IAKX;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,OAAO;IAKvB;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,GAAG;IAKzB;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS;IAK5C;;OAEG;IACH,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS;IAKxD;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAK3D;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE;IAa/C;;OAEG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE;IAajE;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAO9D;;OAEG;IACH,cAAc;CAOf;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ,UAAiB,CAAC"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * DevStore
3
+ *
4
+ * Centralized state management for dev tools.
5
+ * Tracks all permission evaluations and provides override capabilities.
6
+ */
7
+ /**
8
+ * Dev tools store
9
+ * Simple observable pattern for managing dev panel state
10
+ */
11
+ export class DevStore {
12
+ constructor() {
13
+ this.state = {
14
+ evaluations: [],
15
+ isOpen: false,
16
+ overrideUser: undefined,
17
+ overrideRoles: undefined,
18
+ overridePermissions: undefined,
19
+ overrideFlags: undefined,
20
+ };
21
+ this.listeners = new Set();
22
+ }
23
+ /**
24
+ * Get current state
25
+ */
26
+ getState() {
27
+ return { ...this.state };
28
+ }
29
+ /**
30
+ * Subscribe to state changes
31
+ */
32
+ subscribe(listener) {
33
+ this.listeners.add(listener);
34
+ // Return unsubscribe function
35
+ return () => {
36
+ this.listeners.delete(listener);
37
+ };
38
+ }
39
+ /**
40
+ * Notify all listeners of state change
41
+ */
42
+ notify() {
43
+ const currentState = this.getState();
44
+ this.listeners.forEach((listener) => listener(currentState));
45
+ }
46
+ /**
47
+ * Add a permission evaluation
48
+ */
49
+ addEvaluation(evaluation) {
50
+ this.state.evaluations = [evaluation, ...this.state.evaluations].slice(0, 100); // Keep last 100
51
+ this.notify();
52
+ }
53
+ /**
54
+ * Clear all evaluations
55
+ */
56
+ clearEvaluations() {
57
+ this.state.evaluations = [];
58
+ this.notify();
59
+ }
60
+ /**
61
+ * Toggle panel open/closed
62
+ */
63
+ togglePanel() {
64
+ this.state.isOpen = !this.state.isOpen;
65
+ this.notify();
66
+ }
67
+ /**
68
+ * Set panel open state
69
+ */
70
+ setOpen(isOpen) {
71
+ this.state.isOpen = isOpen;
72
+ this.notify();
73
+ }
74
+ /**
75
+ * Set override user for testing
76
+ */
77
+ setOverrideUser(user) {
78
+ this.state.overrideUser = user;
79
+ this.notify();
80
+ }
81
+ /**
82
+ * Set override roles for testing
83
+ */
84
+ setOverrideRoles(roles) {
85
+ this.state.overrideRoles = roles;
86
+ this.notify();
87
+ }
88
+ /**
89
+ * Set override permissions for testing
90
+ */
91
+ setOverridePermissions(permissions) {
92
+ this.state.overridePermissions = permissions;
93
+ this.notify();
94
+ }
95
+ /**
96
+ * Set override flags for testing
97
+ */
98
+ setOverrideFlags(flags) {
99
+ this.state.overrideFlags = flags;
100
+ this.notify();
101
+ }
102
+ /**
103
+ * Toggle a specific role
104
+ */
105
+ toggleRole(role, currentRoles) {
106
+ const overrideRoles = this.state.overrideRoles || [...currentRoles];
107
+ const index = overrideRoles.indexOf(role);
108
+ if (index > -1) {
109
+ overrideRoles.splice(index, 1);
110
+ }
111
+ else {
112
+ overrideRoles.push(role);
113
+ }
114
+ this.setOverrideRoles(overrideRoles.length > 0 ? overrideRoles : undefined);
115
+ }
116
+ /**
117
+ * Toggle a specific permission
118
+ */
119
+ togglePermission(permission, currentPermissions) {
120
+ const overridePermissions = this.state.overridePermissions || [...currentPermissions];
121
+ const index = overridePermissions.indexOf(permission);
122
+ if (index > -1) {
123
+ overridePermissions.splice(index, 1);
124
+ }
125
+ else {
126
+ overridePermissions.push(permission);
127
+ }
128
+ this.setOverridePermissions(overridePermissions.length > 0 ? overridePermissions : undefined);
129
+ }
130
+ /**
131
+ * Toggle a feature flag
132
+ */
133
+ toggleFlag(flag, currentFlags) {
134
+ const overrideFlags = this.state.overrideFlags || { ...currentFlags };
135
+ overrideFlags[flag] = !overrideFlags[flag];
136
+ this.setOverrideFlags(overrideFlags);
137
+ }
138
+ /**
139
+ * Reset all overrides
140
+ */
141
+ resetOverrides() {
142
+ this.state.overrideUser = undefined;
143
+ this.state.overrideRoles = undefined;
144
+ this.state.overridePermissions = undefined;
145
+ this.state.overrideFlags = undefined;
146
+ this.notify();
147
+ }
148
+ }
149
+ /**
150
+ * Global dev store instance
151
+ */
152
+ export const devStore = new DevStore();
@@ -0,0 +1,33 @@
1
+ /**
2
+ * PermissionsRoot
3
+ *
4
+ * Enhanced wrapper around PermissionsProvider that automatically
5
+ * integrates the Dev Panel in development mode.
6
+ */
7
+ import React, { ReactNode } from 'react';
8
+ import type { PermissionsConfig } from '../core/types';
9
+ interface PermissionsRootProps<TUser = any> extends PermissionsConfig<TUser> {
10
+ children: ReactNode;
11
+ }
12
+ /**
13
+ * PermissionsRoot Component
14
+ *
15
+ * Use this instead of PermissionsProvider to get automatic Dev Panel integration.
16
+ * In production, this behaves exactly like PermissionsProvider.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { PermissionsRoot } from 'react-permissions-gate';
21
+ *
22
+ * <PermissionsRoot
23
+ * user={currentUser}
24
+ * roles={['admin']}
25
+ * rules={rules}
26
+ * >
27
+ * <App />
28
+ * </PermissionsRoot>
29
+ * ```
30
+ */
31
+ export declare function PermissionsRoot<TUser = any>(props: PermissionsRootProps<TUser>): React.JSX.Element;
32
+ export {};
33
+ //# sourceMappingURL=PermissionsRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionsRoot.d.ts","sourceRoot":"","sources":["../../src/devtools/PermissionsRoot.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,UAAU,oBAAoB,CAAC,KAAK,GAAG,GAAG,CAAE,SAAQ,iBAAiB,CAAC,KAAK,CAAC;IAC1E,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,oBAAoB,CAAC,KAAK,CAAC,qBA6B9E"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * PermissionsRoot
3
+ *
4
+ * Enhanced wrapper around PermissionsProvider that automatically
5
+ * integrates the Dev Panel in development mode.
6
+ */
7
+ import React from 'react';
8
+ import { PermissionsProvider } from '../react/PermissionsProvider';
9
+ import { DevPanel } from './DevPanel';
10
+ import { useDevRegister, useDevToolsState } from './useDevRegister';
11
+ /**
12
+ * PermissionsRoot Component
13
+ *
14
+ * Use this instead of PermissionsProvider to get automatic Dev Panel integration.
15
+ * In production, this behaves exactly like PermissionsProvider.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * import { PermissionsRoot } from 'react-permissions-gate';
20
+ *
21
+ * <PermissionsRoot
22
+ * user={currentUser}
23
+ * roles={['admin']}
24
+ * rules={rules}
25
+ * >
26
+ * <App />
27
+ * </PermissionsRoot>
28
+ * ```
29
+ */
30
+ export function PermissionsRoot(props) {
31
+ const registerEvaluation = useDevRegister();
32
+ const devState = useDevToolsState();
33
+ // Apply dev tools overrides if they exist
34
+ const effectiveRoles = devState.overrideRoles ?? props.roles ?? [];
35
+ const effectivePermissions = devState.overridePermissions ?? props.permissions ?? [];
36
+ const effectiveFlags = devState.overrideFlags ?? props.flags ?? {};
37
+ // Create a key to force remount when overrides change
38
+ const overrideKey = JSON.stringify({
39
+ roles: devState.overrideRoles,
40
+ permissions: devState.overridePermissions,
41
+ flags: devState.overrideFlags,
42
+ });
43
+ return (React.createElement(PermissionsProvider, { key: overrideKey, ...props, roles: effectiveRoles, permissions: effectivePermissions, flags: effectiveFlags, onEvaluationRegister: registerEvaluation },
44
+ props.children,
45
+ React.createElement(DevPanel, null)));
46
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * useDevRegister Hook
3
+ *
4
+ * Internal hook used by the PermissionsProvider to integrate
5
+ * with dev tools and track evaluations.
6
+ */
7
+ import type { PermissionEvaluation, DevToolsState } from '../core/types';
8
+ /**
9
+ * Hook to register permission evaluations with dev tools
10
+ * Returns a callback that should be passed to PermissionsProvider
11
+ */
12
+ export declare function useDevRegister(): (evaluation: PermissionEvaluation) => void;
13
+ /**
14
+ * Hook to subscribe to dev tools state
15
+ */
16
+ export declare function useDevToolsState(): DevToolsState;
17
+ //# sourceMappingURL=useDevRegister.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDevRegister.d.ts","sourceRoot":"","sources":["../../src/devtools/useDevRegister.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,cAAc,iBACwB,oBAAoB,UAKzE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAShD"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * useDevRegister Hook
3
+ *
4
+ * Internal hook used by the PermissionsProvider to integrate
5
+ * with dev tools and track evaluations.
6
+ */
7
+ import { useCallback, useEffect, useState } from 'react';
8
+ import { devStore } from './DevStore';
9
+ /**
10
+ * Hook to register permission evaluations with dev tools
11
+ * Returns a callback that should be passed to PermissionsProvider
12
+ */
13
+ export function useDevRegister() {
14
+ const registerEvaluation = useCallback((evaluation) => {
15
+ devStore.addEvaluation(evaluation);
16
+ }, []);
17
+ return registerEvaluation;
18
+ }
19
+ /**
20
+ * Hook to subscribe to dev tools state
21
+ */
22
+ export function useDevToolsState() {
23
+ const [state, setState] = useState(devStore.getState());
24
+ useEffect(() => {
25
+ const unsubscribe = devStore.subscribe(setState);
26
+ return unsubscribe;
27
+ }, []);
28
+ return state;
29
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * react-permissions-gate
3
+ *
4
+ * A production-grade React authorization framework for RBAC, PBAC, ABAC,
5
+ * feature flags, and async permission checks.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export type { PermissionContext, PermissionRule, PermissionRulesMap, PermissionCheck, PermissionMode, PermissionsConfig, PermissionsContextValue, PermissionEvaluation, RuleEvaluationResult, DevToolsState, } from './core/types';
10
+ export { PermissionsProvider, usePermissionsContext } from './react/PermissionsProvider';
11
+ export { PermissionsGate } from './react/PermissionsGate';
12
+ export type { PermissionsGateProps } from './react/PermissionsGate';
13
+ export { Permissioned } from './react/Permissioned';
14
+ export type { PermissionedProps } from './react/Permissioned';
15
+ export { ProtectedRoute } from './react/ProtectedRoute';
16
+ export type { ProtectedRouteProps } from './react/ProtectedRoute';
17
+ export { usePermission, usePermissionValue } from './react/usePermission';
18
+ export { PermissionsRoot } from './devtools/PermissionsRoot';
19
+ export { DevPanel } from './devtools/DevPanel';
20
+ export { devStore } from './devtools/DevStore';
21
+ export { evaluatePermission, evaluateRule, resolveStringRule, createPermissionContext, } from './core/ruleEngine';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGlE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * react-permissions-gate
3
+ *
4
+ * A production-grade React authorization framework for RBAC, PBAC, ABAC,
5
+ * feature flags, and async permission checks.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ // React components
10
+ export { PermissionsProvider, usePermissionsContext } from './react/PermissionsProvider';
11
+ export { PermissionsGate } from './react/PermissionsGate';
12
+ export { Permissioned } from './react/Permissioned';
13
+ export { ProtectedRoute } from './react/ProtectedRoute';
14
+ // Hooks
15
+ export { usePermission, usePermissionValue } from './react/usePermission';
16
+ // Dev tools (auto-integrated root)
17
+ export { PermissionsRoot } from './devtools/PermissionsRoot';
18
+ export { DevPanel } from './devtools/DevPanel';
19
+ export { devStore } from './devtools/DevStore';
20
+ // Core utilities (advanced usage)
21
+ export { evaluatePermission, evaluateRule, resolveStringRule, createPermissionContext, } from './core/ruleEngine';
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Permissioned Component
3
+ *
4
+ * Render-prop version of PermissionsGate for more control.
5
+ * Passes the permission result to a render function.
6
+ */
7
+ import React, { ReactNode } from 'react';
8
+ import type { PermissionCheck } from '../core/types';
9
+ export interface PermissionedProps<TUser = any, TResource = any> {
10
+ /**
11
+ * Permission check to evaluate
12
+ */
13
+ allow: PermissionCheck<TUser, TResource>;
14
+ /**
15
+ * Resource to check permission against
16
+ */
17
+ resource?: TResource;
18
+ /**
19
+ * Render function that receives permission result
20
+ */
21
+ children: (allowed: boolean, loading: boolean) => ReactNode;
22
+ }
23
+ /**
24
+ * Permissioned Component
25
+ *
26
+ * Render-prop pattern for permission checking.
27
+ * Gives you full control over how to render based on permission state.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * <Permissioned allow="user.edit" resource={user}>
32
+ * {(allowed, loading) => (
33
+ * <button disabled={!allowed || loading}>
34
+ * {loading ? 'Checking...' : allowed ? 'Edit' : 'View Only'}
35
+ * </button>
36
+ * )}
37
+ * </Permissioned>
38
+ * ```
39
+ */
40
+ export declare function Permissioned<TUser = any, TResource = any>({ allow, resource, children, }: PermissionedProps<TUser, TResource>): React.JSX.Element;
41
+ //# sourceMappingURL=Permissioned.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Permissioned.d.ts","sourceRoot":"","sources":["../../src/react/Permissioned.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,WAAW,iBAAiB,CAAC,KAAK,GAAG,GAAG,EAAE,SAAS,GAAG,GAAG;IAC7D;;OAEG;IACH,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAEzC;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;CAC7D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,KAAK,GAAG,GAAG,EAAE,SAAS,GAAG,GAAG,EAAE,EACzD,KAAK,EACL,QAAQ,EACR,QAAQ,GACT,EAAE,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,qBAIrC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Permissioned Component
3
+ *
4
+ * Render-prop version of PermissionsGate for more control.
5
+ * Passes the permission result to a render function.
6
+ */
7
+ import React from 'react';
8
+ import { usePermission } from './usePermission';
9
+ /**
10
+ * Permissioned Component
11
+ *
12
+ * Render-prop pattern for permission checking.
13
+ * Gives you full control over how to render based on permission state.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <Permissioned allow="user.edit" resource={user}>
18
+ * {(allowed, loading) => (
19
+ * <button disabled={!allowed || loading}>
20
+ * {loading ? 'Checking...' : allowed ? 'Edit' : 'View Only'}
21
+ * </button>
22
+ * )}
23
+ * </Permissioned>
24
+ * ```
25
+ */
26
+ export function Permissioned({ allow, resource, children, }) {
27
+ const { allowed, loading } = usePermission(allow, resource);
28
+ return React.createElement(React.Fragment, null, children(allowed, loading));
29
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * PermissionsGate Component
3
+ *
4
+ * Declarative permission boundary for your components.
5
+ * Automatically hides or disables children based on permission checks.
6
+ */
7
+ import React, { ReactNode } from 'react';
8
+ import type { PermissionCheck, PermissionMode } from '../core/types';
9
+ export interface PermissionsGateProps<TUser = any, TResource = any> {
10
+ /**
11
+ * Primary permission check
12
+ * Can be a string, array of strings, or inline rule function
13
+ */
14
+ allow?: PermissionCheck<TUser, TResource>;
15
+ /**
16
+ * Array of permissions where ANY must pass (OR logic)
17
+ * Alternative to `allow` - cannot be used together
18
+ */
19
+ any?: string[];
20
+ /**
21
+ * Array of permissions where ALL must pass (AND logic)
22
+ * Alternative to `allow` - cannot be used together
23
+ */
24
+ all?: string[];
25
+ /**
26
+ * Resource to check permission against
27
+ */
28
+ resource?: TResource;
29
+ /**
30
+ * Fallback content to render when permission is denied
31
+ * If not provided and mode is 'hide', nothing is rendered
32
+ */
33
+ fallback?: ReactNode;
34
+ /**
35
+ * How to handle denied permissions:
36
+ * - 'hide': Don't render children at all (default)
37
+ * - 'disable': Render children but add disabled prop
38
+ */
39
+ mode?: PermissionMode;
40
+ /**
41
+ * Children to protect with permission check
42
+ */
43
+ children: ReactNode;
44
+ }
45
+ /**
46
+ * PermissionsGate Component
47
+ *
48
+ * Wraps components with permission-based access control.
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * // Hide button if user can't edit
53
+ * <PermissionsGate allow="user.edit" resource={user}>
54
+ * <EditButton />
55
+ * </PermissionsGate>
56
+ *
57
+ * // Disable button instead of hiding
58
+ * <PermissionsGate allow="post.delete" resource={post} mode="disable">
59
+ * <DeleteButton />
60
+ * </PermissionsGate>
61
+ *
62
+ * // Check multiple permissions (any)
63
+ * <PermissionsGate any={["admin", "moderator"]}>
64
+ * <AdminPanel />
65
+ * </PermissionsGate>
66
+ *
67
+ * // Check multiple permissions (all)
68
+ * <PermissionsGate all={["post.edit", "post.publish"]}>
69
+ * <PublishButton />
70
+ * </PermissionsGate>
71
+ *
72
+ * // Show fallback when denied
73
+ * <PermissionsGate allow="premium.feature" fallback={<UpgradePrompt />}>
74
+ * <PremiumFeature />
75
+ * </PermissionsGate>
76
+ * ```
77
+ */
78
+ export declare function PermissionsGate<TUser = any, TResource = any>({ allow, any, all, resource, fallback, mode, children, }: PermissionsGateProps<TUser, TResource>): React.JSX.Element | null;
79
+ //# sourceMappingURL=PermissionsGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionsGate.d.ts","sourceRoot":"","sources":["../../src/react/PermissionsGate.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAAE,SAAS,EAA8B,MAAM,OAAO,CAAC;AAErE,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAErE,MAAM,WAAW,oBAAoB,CAAC,KAAK,GAAG,GAAG,EAAE,SAAS,GAAG,GAAG;IAChE;;;OAGG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAE1C;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IAEf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IAEf;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;OAIG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IAEtB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,eAAe,CAAC,KAAK,GAAG,GAAG,EAAE,SAAS,GAAG,GAAG,EAAE,EAC5D,KAAK,EACL,GAAG,EACH,GAAG,EACH,QAAQ,EACR,QAAQ,EACR,IAAa,EACb,QAAQ,GACT,EAAE,oBAAoB,CAAC,KAAK,EAAE,SAAS,CAAC,4BA2CxC"}