@shield-acl/react
Version:
Sistema ACL (Access Control List) inteligente e granular para aplicações React
1,411 lines (1,393 loc) • 45.8 kB
text/typescript
import * as react_jsx_runtime from 'react/jsx-runtime';
import * as _shield_acl_core from '@shield-acl/core';
import { ACLEngine, User, PermissionAction, ResourceType, EvaluationResult, PermissionRule, RoleName, Role } from '@shield-acl/core';
import * as react from 'react';
import { ReactNode, ReactElement } from 'react';
/**
* Valor do contexto ACL
*/
interface ACLContextValue<TContext = any> {
engine: ACLEngine<TContext>;
user: User<TContext> | null;
setUser: (user: User<TContext> | null) => void;
can: (action: PermissionAction, resource?: ResourceType, context?: TContext) => boolean;
evaluate: (action: PermissionAction, resource?: ResourceType, context?: TContext) => EvaluationResult;
}
/**
* Props do Provider
*/
interface ACLProviderProps<TContext = any> {
engine: ACLEngine<TContext>;
user?: User<TContext> | null;
children: React.ReactNode;
}
/**
* Provider do ACL para React
*/
declare function ACLProvider<TContext = any>({ engine, user: initialUser, children, }: ACLProviderProps<TContext>): react_jsx_runtime.JSX.Element;
/**
* Hook para acessar o contexto ACL
*/
declare function useACLContext<TContext = any>(): ACLContextValue<TContext>;
/**
* Hook principal do ACL que expõe todas as funcionalidades
*
* @returns Objeto com métodos e estado do ACL
*
* @example
* ```tsx
* const { can, cannot, evaluate, user, setUser } = useACL()
*
* if (can("posts.create")) {
* // Usuário pode criar posts
* }
*
* const result = evaluate("posts.edit", "posts", { postId: 123 })
* console.log(result.reason)
* ```
*/
declare function useACL<TContext = any>(): {
user: User<TContext> | null;
setUser: (user: User<TContext> | null) => void;
can: (action: PermissionAction, resource?: ResourceType, context?: TContext | undefined) => boolean;
cannot: (action: PermissionAction, resource?: ResourceType, context?: TContext) => boolean;
evaluate: (action: PermissionAction, resource?: ResourceType, context?: TContext | undefined) => _shield_acl_core.EvaluationResult;
permissions: () => PermissionRule<TContext>[];
roles: () => RoleName[];
engine: _shield_acl_core.ACLEngine<TContext>;
clearCache: () => void;
};
/**
* Type helper para inferir o tipo de contexto do useACL
*/
type UseACLReturn<TContext = any> = ReturnType<typeof useACL<TContext>>;
/**
* Hook para verificação simples de permissão com memoização
*
* @param action - Ação a verificar
* @param resource - Recurso opcional
* @param context - Contexto adicional opcional
* @returns boolean indicando se tem permissão
*
* @example
* ```tsx
* // Verificação simples
* const canCreatePost = useCan("posts.create")
*
* // Com recurso
* const canEditUser = useCan("users.edit", "users")
*
* // Com contexto
* const canEditSpecificPost = useCan("posts.edit", "posts", { postId: 123 })
*
* if (canCreatePost) {
* return <CreatePostButton />
* }
* ```
*/
declare function useCan<TContext = any>(action: PermissionAction, resource?: ResourceType, context?: TContext): boolean;
/**
* Hook para verificação negativa de permissão com memoização
* Útil quando você quer mostrar algo quando o usuário NÃO tem permissão
*
* @param action - Ação a verificar
* @param resource - Recurso opcional
* @param context - Contexto adicional opcional
* @returns boolean indicando se NÃO tem permissão
*
* @example
* ```tsx
* const cannotDelete = useCannot("posts.delete", "posts", { postId: 123 })
*
* if (cannotDelete) {
* return <DisabledDeleteButton />
* }
* ```
*/
declare function useCannot<TContext = any>(action: PermissionAction, resource?: ResourceType, context?: TContext): boolean;
/**
* Estrutura de uma verificação de permissão
*/
interface PermissionCheck<TContext = any> {
action: PermissionAction;
resource?: ResourceType;
context?: TContext;
}
/**
* Hook que verifica se o usuário tem QUALQUER uma das permissões listadas (OR)
*
* @param permissions - Array de permissões para verificar
* @returns boolean indicando se tem pelo menos uma das permissões
*
* @example
* ```tsx
* // Verificar se pode criar OU editar posts
* const canModifyPosts = useCanAny([
* { action: "posts.create" },
* { action: "posts.edit" }
* ])
*
* // Com recursos diferentes
* const canAccessContent = useCanAny([
* { action: "posts.read", resource: "posts" },
* { action: "pages.read", resource: "pages" },
* { action: "admin.access" }
* ])
*
* // Com contexto específico
* const canInteractWithPost = useCanAny([
* { action: "posts.edit", resource: "posts", context: { postId: 123 } },
* { action: "posts.moderate", resource: "posts" },
* { action: "admin.override" }
* ])
* ```
*/
declare function useCanAny<TContext = any>(permissions: PermissionCheck<TContext>[]): boolean;
/**
* Versão simplificada do useCanAny que aceita apenas ações como strings
*
* @param actions - Array de ações para verificar
* @returns boolean indicando se tem pelo menos uma das permissões
*
* @example
* ```tsx
* // Verificação simples de múltiplas ações
* const canManageUsers = useCanAnyAction([
* "users.create",
* "users.edit",
* "users.delete"
* ])
* ```
*/
declare function useCanAnyAction(actions: PermissionAction[]): boolean;
/**
* Hook que verifica se o usuário tem TODAS as permissões listadas (AND)
*
* @param permissions - Array de permissões para verificar
* @returns boolean indicando se tem todas as permissões
*
* @example
* ```tsx
* // Verificar se pode criar E editar posts (ambas necessárias)
* const canFullyManagePosts = useCanAll([
* { action: "posts.create" },
* { action: "posts.edit" },
* { action: "posts.delete" }
* ])
*
* // Verificar múltiplas permissões com recursos
* const hasFullAccess = useCanAll([
* { action: "users.read", resource: "users" },
* { action: "users.write", resource: "users" },
* { action: "settings.manage" }
* ])
*
* // Com contexto específico
* const canFullyControlPost = useCanAll([
* { action: "posts.edit", resource: "posts", context: { postId: 123 } },
* { action: "posts.publish", resource: "posts", context: { postId: 123 } },
* { action: "posts.delete", resource: "posts", context: { postId: 123 } }
* ])
* ```
*/
declare function useCanAll<TContext = any>(permissions: PermissionCheck<TContext>[]): boolean;
/**
* Versão simplificada do useCanAll que aceita apenas ações como strings
*
* @param actions - Array de ações para verificar
* @returns boolean indicando se tem todas as permissões
*
* @example
* ```tsx
* // Verificação simples de múltiplas ações
* const hasCompleteUserAccess = useCanAllActions([
* "users.read",
* "users.create",
* "users.edit",
* "users.delete"
* ])
* ```
*/
declare function useCanAllActions(actions: PermissionAction[]): boolean;
/**
* Interface com helpers CRUD para permissões
*/
interface PermissionHelpers<TContext = any> {
canRead: (resource: ResourceType, context?: TContext) => boolean;
canCreate: (resource: ResourceType, context?: TContext) => boolean;
canUpdate: (resource: ResourceType, context?: TContext) => boolean;
canDelete: (resource: ResourceType, context?: TContext) => boolean;
canManage: (resource: ResourceType, context?: TContext) => boolean;
canList: (resource: ResourceType, context?: TContext) => boolean;
canView: (resource: ResourceType, context?: TContext) => boolean;
canEdit: (resource: ResourceType, context?: TContext) => boolean;
canModify: (resource: ResourceType, context?: TContext) => boolean;
canAccess: (resource: ResourceType, context?: TContext) => boolean;
}
/**
* Hook que fornece helpers CRUD para verificação de permissões
* Segue convenções comuns de nomenclatura de ações
*
* @returns Objeto com métodos helper para verificações CRUD
*
* @example
* ```tsx
* const { canRead, canCreate, canUpdate, canDelete, canManage } = usePermissionHelpers()
*
* // Verificações CRUD básicas
* if (canRead("posts")) {
* // Pode ler posts
* }
*
* if (canCreate("posts")) {
* // Pode criar posts
* }
*
* // Com contexto
* if (canUpdate("posts", { postId: 123, authorId: 456 })) {
* // Pode atualizar este post específico
* }
*
* // Verificar permissão total (manage geralmente inclui todas as outras)
* if (canManage("users")) {
* // Tem controle total sobre usuários
* }
* ```
*/
declare function usePermissionHelpers<TContext = any>(): PermissionHelpers<TContext>;
/**
* Hook para verificar permissões CRUD de um recurso específico
* Útil quando você está trabalhando com um único recurso
*
* @param resource - O recurso para verificar permissões
* @returns Objeto com métodos CRUD pré-configurados para o recurso
*
* @example
* ```tsx
* const postPermissions = useResourcePermissions("posts")
*
* if (postPermissions.canCreate()) {
* // Pode criar posts
* }
*
* if (postPermissions.canUpdate({ postId: 123 })) {
* // Pode atualizar este post específico
* }
* ```
*/
declare function useResourcePermissions<TContext = any>(resource: ResourceType): {
canRead: (context?: TContext) => boolean;
canCreate: (context?: TContext) => boolean;
canUpdate: (context?: TContext) => boolean;
canDelete: (context?: TContext) => boolean;
canManage: (context?: TContext) => boolean;
canList: (context?: TContext) => boolean;
canView: (context?: TContext) => boolean;
canEdit: (context?: TContext) => boolean;
canModify: (context?: TContext) => boolean;
canAccess: (context?: TContext) => boolean;
};
/**
* Estrutura detalhada de permissões do usuário
*/
interface UserPermissionsInfo<TContext = any> {
/** Todas as permissões efetivas (incluindo herdadas) */
all: PermissionRule<TContext>[];
/** Permissões diretas do usuário (não herdadas) */
direct: PermissionRule<TContext>[];
/** Permissões herdadas das roles */
inherited: PermissionRule<TContext>[];
/** Permissões agrupadas por role */
byRole: Record<RoleName, PermissionRule<TContext>[]>;
/** Permissões de negação (deny) */
denials: PermissionRule<TContext>[];
/** Permissões de permissão (allow) */
allowances: PermissionRule<TContext>[];
/** Lista única de ações disponíveis */
actions: string[];
/** Lista única de recursos disponíveis */
resources: string[];
/** Contagem total de permissões */
count: number;
}
/**
* Hook que lista todas as permissões efetivas do usuário atual
* Fornece uma visão detalhada e organizada das permissões
*
* @returns Objeto com informações detalhadas sobre as permissões
*
* @example
* ```tsx
* const permissions = usePermissions()
*
* // Listar todas as permissões
* console.log(`Total de permissões: ${permissions.count}`)
* permissions.all.forEach(perm => {
* console.log(`- ${perm.action} on ${perm.resource}`)
* })
*
* // Ver permissões por role
* Object.entries(permissions.byRole).forEach(([role, perms]) => {
* console.log(`Role ${role}: ${perms.length} permissões`)
* })
*
* // Verificar negações explícitas
* if (permissions.denials.length > 0) {
* console.warn("Existem negações explícitas:")
* permissions.denials.forEach(denial => {
* console.warn(`- Negado: ${denial.action}`)
* })
* }
*
* // Listar ações únicas disponíveis
* console.log("Ações disponíveis:", permissions.actions)
*
* // Listar recursos únicos
* console.log("Recursos acessíveis:", permissions.resources)
* ```
*/
declare function usePermissions<TContext = any>(): UserPermissionsInfo<TContext>;
/**
* Hook simplificado que retorna apenas o array de permissões
*
* @returns Array de todas as permissões efetivas
*
* @example
* ```tsx
* const permissions = usePermissionsList()
*
* permissions.forEach(perm => {
* console.log(`${perm.action} on ${perm.resource}`)
* })
* ```
*/
declare function usePermissionsList<TContext = any>(): PermissionRule<TContext>[];
/**
* Hook que retorna apenas as ações disponíveis ao usuário
*
* @returns Array de ações únicas
*
* @example
* ```tsx
* const actions = useAvailableActions()
*
* // ["posts.create", "posts.edit", "users.read", ...]
* console.log("Ações disponíveis:", actions)
* ```
*/
declare function useAvailableActions(): string[];
/**
* Hook que retorna apenas os recursos acessíveis ao usuário
*
* @returns Array de recursos únicos
*
* @example
* ```tsx
* const resources = useAvailableResources()
*
* // ["posts", "users", "settings", ...]
* console.log("Recursos acessíveis:", resources)
* ```
*/
declare function useAvailableResources(): string[];
/**
* Resultado da verificação múltipla de permissões
*/
interface MultiplePermissionResult<TContext = any> {
/** Indica se TODAS as permissões foram permitidas */
allAllowed: boolean;
/** Indica se ALGUMA permissão foi permitida */
anyAllowed: boolean;
/** Indica se NENHUMA permissão foi permitida */
noneAllowed: boolean;
/** Contagem de permissões permitidas */
allowedCount: number;
/** Contagem de permissões negadas */
deniedCount: number;
/** Resultados individuais indexados por chave */
results: Record<string, boolean>;
/** Detalhes completos de avaliação indexados por chave */
details: Record<string, EvaluationResult>;
/** Lista de permissões permitidas */
allowed: PermissionCheck<TContext>[];
/** Lista de permissões negadas */
denied: PermissionCheck<TContext>[];
}
/**
* Hook que verifica múltiplas permissões e retorna um objeto detalhado com os resultados
*
* @param permissions - Array de permissões para verificar
* @param keys - Array opcional de chaves customizadas para indexar resultados
* @returns Objeto com resultados detalhados de todas as verificações
*
* @example
* ```tsx
* // Verificar múltiplas permissões com análise detalhada
* const permissionCheck = useCanMultiple([
* { action: "posts.create" },
* { action: "posts.edit", resource: "posts" },
* { action: "posts.delete", resource: "posts" },
* { action: "users.manage", resource: "users" }
* ])
*
* // Verificar status geral
* if (permissionCheck.allAllowed) {
* console.log("Tem todas as permissões!")
* } else if (permissionCheck.anyAllowed) {
* console.log(`Tem ${permissionCheck.allowedCount} de ${permissions.length} permissões`)
* }
*
* // Verificar permissões específicas por índice
* if (permissionCheck.results["posts.create"]) {
* // Pode criar posts
* }
*
* // Com chaves customizadas
* const namedCheck = useCanMultiple(
* [
* { action: "posts.create" },
* { action: "posts.edit", resource: "posts" }
* ],
* ["createPost", "editPost"] // Chaves customizadas
* )
*
* if (namedCheck.results.createPost) {
* // Pode criar posts
* }
*
* // Acessar detalhes da avaliação
* console.log(namedCheck.details.editPost.reason)
* ```
*/
declare function useCanMultiple<TContext = any>(permissions: PermissionCheck<TContext>[], keys?: string[]): MultiplePermissionResult<TContext>;
/**
* Hook simplificado que retorna apenas o mapa de resultados booleanos
*
* @param permissions - Array de permissões para verificar
* @param keys - Array opcional de chaves customizadas
* @returns Objeto com resultados booleanos indexados por chave
*
* @example
* ```tsx
* const canMap = useCanMap([
* { action: "posts.create" },
* { action: "posts.edit" },
* { action: "posts.delete" }
* ])
*
* // { "posts.create": true, "posts.edit": true, "posts.delete": false }
*
* if (canMap["posts.create"] && canMap["posts.edit"]) {
* // Pode criar e editar
* }
* ```
*/
declare function useCanMap<TContext = any>(permissions: PermissionCheck<TContext>[], keys?: string[]): Record<string, boolean>;
/**
* Hook que verifica permissões e retorna array de booleanos na mesma ordem
*
* @param permissions - Array de permissões para verificar
* @returns Array de booleanos na mesma ordem das permissões
*
* @example
* ```tsx
* const [canCreate, canEdit, canDelete] = useCanArray([
* { action: "posts.create" },
* { action: "posts.edit" },
* { action: "posts.delete" }
* ])
*
* if (canCreate && canEdit) {
* // Pode criar e editar
* }
* ```
*/
declare function useCanArray<TContext = any>(permissions: PermissionCheck<TContext>[]): boolean[];
/**
* Interface completa de ACL para um recurso específico
*/
interface ResourceACL<TContext = any> {
/** Nome do recurso */
resource: ResourceType;
/** Verificações CRUD básicas */
canRead: (context?: TContext) => boolean;
canCreate: (context?: TContext) => boolean;
canUpdate: (context?: TContext) => boolean;
canDelete: (context?: TContext) => boolean;
canManage: (context?: TContext) => boolean;
/** Aliases comuns */
canList: (context?: TContext) => boolean;
canView: (context?: TContext) => boolean;
canEdit: (context?: TContext) => boolean;
canModify: (context?: TContext) => boolean;
canAccess: (context?: TContext) => boolean;
/** Verificação customizada de ação */
can: (action: PermissionAction, context?: TContext) => boolean;
cannot: (action: PermissionAction, context?: TContext) => boolean;
/** Status geral de permissões CRUD */
permissions: {
read: boolean;
create: boolean;
update: boolean;
delete: boolean;
manage: boolean;
};
/** Helpers de verificação múltipla */
hasAnyPermission: boolean;
hasAllCrudPermissions: boolean;
hasReadOnlyAccess: boolean;
hasWriteAccess: boolean;
hasFullAccess: boolean;
/** Lista de ações disponíveis para este recurso */
availableActions: string[];
}
/**
* Hook contextual que fornece interface completa de ACL para um recurso específico
* Automaticamente deduz e organiza todas as permissões relacionadas ao recurso
*
* @param resource - O recurso para contextualizar as permissões
* @returns Objeto com interface completa de ACL para o recurso
*
* @example
* ```tsx
* // Em um componente de gerenciamento de posts
* const postsACL = useResourceACL("posts")
*
* // Verificações CRUD básicas
* if (!postsACL.canRead()) {
* return <AccessDenied />
* }
*
* return (
* <div>
* <PostList />
*
* {postsACL.canCreate() && (
* <CreatePostButton />
* )}
*
* {postsACL.hasWriteAccess && (
* <BulkActions />
* )}
*
* {postsACL.hasFullAccess && (
* <AdminPanel />
* )}
* </div>
* )
*
* // Em um componente de item específico
* function PostItem({ post }) {
* const postsACL = useResourceACL("posts")
*
* // Verificação com contexto
* const canEditThis = postsACL.canEdit({ postId: post.id })
* const canDeleteThis = postsACL.canDelete({ postId: post.id })
*
* return (
* <div>
* <h3>{post.title}</h3>
* {canEditThis && <EditButton />}
* {canDeleteThis && <DeleteButton />}
* </div>
* )
* }
* ```
*/
declare function useResourceACL<TContext = any>(resource: ResourceType): ResourceACL<TContext>;
/**
* Hook que retorna um mapa de ACL para múltiplos recursos
* Útil quando você precisa verificar permissões de vários recursos de uma vez
*
* @param resources - Array de recursos
* @returns Mapa de recursos para suas interfaces ACL
*
* @example
* ```tsx
* const acls = useMultipleResourceACL(["posts", "users", "settings"])
*
* if (acls.posts.canCreate() && acls.users.canRead()) {
* // Pode criar posts e ler usuários
* }
* ```
*/
declare function useMultipleResourceACL<TContext = any>(resources: ResourceType[]): Record<ResourceType, ResourceACL<TContext>>;
/**
* Estado reativo de uma permissão
*/
interface PermissionState {
/** Valor atual da permissão */
allowed: boolean;
/** Está carregando/processando */
loading: boolean;
/** Erro se houver */
error: Error | null;
/** Timestamp da última verificação */
lastChecked: number;
/** Força uma nova verificação */
refresh: () => void;
}
/**
* Opções para o hook usePermissionState
*/
interface UsePermissionStateOptions {
/** Intervalo de auto-atualização em ms (0 = desabilitado) */
refreshInterval?: number;
/** Callback quando a permissão muda */
onChange?: (newValue: boolean, oldValue: boolean) => void;
/** Suspender verificações quando false */
enabled?: boolean;
/** Valor inicial enquanto carrega */
initialValue?: boolean;
}
/**
* Hook que cria um estado reativo de permissão que auto-atualiza quando user/contexto muda
* Útil para componentes que precisam reagir a mudanças de permissões em tempo real
*
* @param action - Ação a monitorar
* @param resource - Recurso opcional
* @param context - Contexto adicional
* @param options - Opções de configuração
* @returns Estado reativo da permissão
*
* @example
* ```tsx
* // Estado reativo simples
* function FeatureToggle() {
* const permission = usePermissionState("feature.premium")
*
* if (permission.loading) {
* return <Spinner />
* }
*
* return (
* <div>
* <Switch checked={permission.allowed} disabled />
* <span>Premium Feature: {permission.allowed ? "Enabled" : "Disabled"}</span>
* <button onClick={permission.refresh}>Recheck</button>
* </div>
* )
* }
*
* // Com auto-refresh e callback
* function LivePermissionMonitor() {
* const [log, setLog] = useState<string[]>([])
*
* const permission = usePermissionState("admin.access", undefined, undefined, {
* refreshInterval: 5000, // Verifica a cada 5 segundos
* onChange: (newValue, oldValue) => {
* setLog(prev => [...prev, `Changed from ${oldValue} to ${newValue} at ${new Date().toLocaleTimeString()}`])
* }
* })
*
* return (
* <div>
* <h3>Admin Access: {permission.allowed ? "✓" : "✗"}</h3>
* <p>Last checked: {new Date(permission.lastChecked).toLocaleTimeString()}</p>
* <ul>
* {log.map((entry, i) => <li key={i}>{entry}</li>)}
* </ul>
* </div>
* )
* }
* ```
*/
declare function usePermissionState<TContext = any>(action: PermissionAction, resource?: ResourceType, context?: TContext, options?: UsePermissionStateOptions): PermissionState;
/**
* Hook que monitora múltiplas permissões com estado reativo
*
* @param permissions - Array de permissões para monitorar
* @param options - Opções de configuração
* @returns Mapa de estados de permissão
*
* @example
* ```tsx
* const permissions = useMultiplePermissionStates([
* { action: "posts.create", key: "createPost" },
* { action: "posts.edit", resource: "posts", key: "editPost" },
* { action: "posts.delete", resource: "posts", key: "deletePost" }
* ])
*
* return (
* <div>
* <Button
* disabled={!permissions.createPost.allowed}
* loading={permissions.createPost.loading}
* >
* Create Post
* </Button>
*
* <Button
* disabled={!permissions.editPost.allowed}
* variant={permissions.editPost.allowed ? "primary" : "secondary"}
* >
* Edit Post
* </Button>
* </div>
* )
* ```
*/
declare function useMultiplePermissionStates<TContext = any>(permissions: Array<{
action: PermissionAction;
resource?: ResourceType;
context?: TContext;
key: string;
}>, options?: Omit<UsePermissionStateOptions, "onChange">): Record<string, PermissionState>;
/**
* Hook que retorna um estado booleano reativo para uma permissão
* Versão simplificada do usePermissionState
*
* @param action - Ação a verificar
* @param resource - Recurso opcional
* @param context - Contexto adicional
* @returns Tupla [allowed, loading, refresh]
*
* @example
* ```tsx
* const [canEdit, loading, refresh] = usePermissionBoolean("posts.edit", "posts")
*
* if (loading) return <Spinner />
*
* return (
* <Button disabled={!canEdit} onClick={handleEdit}>
* Edit Post
* </Button>
* )
* ```
*/
declare function usePermissionBoolean<TContext = any>(action: PermissionAction, resource?: ResourceType, context?: TContext): [boolean, boolean, () => void];
/**
* Permissão condicional
*/
interface ConditionalPermission<TContext = any> {
/** Condição para verificar a permissão */
condition: boolean | (() => boolean);
/** Ação da permissão */
action: PermissionAction;
/** Recurso opcional */
resource?: ResourceType;
/** Contexto adicional */
context?: TContext;
/** Valor padrão quando condição é false */
defaultValue?: boolean;
}
/**
* Resultado de verificação condicional
*/
interface ConditionalResult {
/** Se a permissão foi concedida */
allowed: boolean;
/** Se a condição foi atendida */
conditionMet: boolean;
/** Se a verificação foi pulada devido à condição */
skipped: boolean;
/** Razão da decisão */
reason: string;
}
/**
* Hook que verifica permissões apenas quando certas condições são verdadeiras
* Útil para otimizar verificações e implementar lógica condicional complexa
*
* @param permissions - Array de permissões condicionais
* @returns Mapa de resultados condicionais
*
* @example
* ```tsx
* // Verificar permissões baseadas em condições
* function ConditionalActions({ post, user }) {
* const isAuthor = post.authorId === user.id
* const isPublished = post.status === "published"
* const isDraft = post.status === "draft"
*
* const permissions = useConditionalPermissions([
* {
* // Só verifica se pode editar se for o autor
* condition: isAuthor,
* action: "posts.edit",
* resource: "posts",
* context: { postId: post.id }
* },
* {
* // Só verifica se pode publicar se for rascunho
* condition: isDraft,
* action: "posts.publish",
* resource: "posts"
* },
* {
* // Só verifica se pode despublicar se estiver publicado
* condition: isPublished,
* action: "posts.unpublish",
* resource: "posts",
* defaultValue: false // Nega por padrão se condição não for atendida
* }
* ])
*
* return (
* <div>
* {permissions[0].allowed && (
* <Button onClick={handleEdit}>
* Editar (você é o autor)
* </Button>
* )}
*
* {permissions[1].allowed && (
* <Button onClick={handlePublish}>
* Publicar Rascunho
* </Button>
* )}
*
* {permissions[2].conditionMet && permissions[2].allowed && (
* <Button onClick={handleUnpublish}>
* Despublicar
* </Button>
* )}
* </div>
* )
* }
* ```
*/
declare function useConditionalPermissions<TContext = any>(permissions: ConditionalPermission<TContext>[]): ConditionalResult[];
/**
* Hook para uma única permissão condicional
*
* @param condition - Condição para verificar
* @param action - Ação a verificar
* @param resource - Recurso opcional
* @param context - Contexto adicional
* @param defaultValue - Valor padrão quando condição é false
* @returns Resultado da verificação condicional
*
* @example
* ```tsx
* // Verificar permissão apenas se usuário for premium
* const premiumFeature = useConditionalPermission(
* user.isPremium,
* "features.premium",
* undefined,
* undefined,
* false // Nega acesso se não for premium
* )
*
* if (!premiumFeature.conditionMet) {
* return <UpgradePrompt />
* }
*
* if (!premiumFeature.allowed) {
* return <AccessDenied />
* }
*
* return <PremiumFeature />
* ```
*/
declare function useConditionalPermission<TContext = any>(condition: boolean | (() => boolean), action: PermissionAction, resource?: ResourceType, context?: TContext, defaultValue?: boolean): ConditionalResult;
/**
* Hook que cria uma função para verificação condicional de permissões
* Útil quando você precisa verificar permissões dinamicamente
*
* @returns Função para verificar permissões condicionalmente
*
* @example
* ```tsx
* const checkConditional = useConditionalChecker()
*
* // Em um evento
* const handleAction = (item) => {
* const canProcess = checkConditional(
* item.status === "pending",
* "items.process",
* "items",
* { itemId: item.id }
* )
*
* if (!canProcess.conditionMet) {
* alert("Item não está pendente")
* return
* }
*
* if (!canProcess.allowed) {
* alert("Sem permissão para processar")
* return
* }
*
* processItem(item)
* }
* ```
*/
declare function useConditionalChecker<TContext = any>(): (condition: boolean | (() => boolean), action: PermissionAction, resource?: ResourceType, context?: TContext, defaultValue?: boolean) => ConditionalResult;
/**
* Hook que combina múltiplas condições com operadores lógicos
*
* @param mode - "all" (AND) ou "any" (OR)
* @param conditions - Array de condições
* @param action - Ação a verificar
* @param resource - Recurso opcional
* @param context - Contexto adicional
* @returns Resultado da verificação
*
* @example
* ```tsx
* // Verificar se TODAS as condições são verdadeiras
* const canPerformComplexAction = useCombinedConditionalPermission(
* "all",
* [
* user.isVerified,
* user.accountAge > 30,
* !user.isSuspended
* ],
* "actions.complex"
* )
*
* // Verificar se QUALQUER condição é verdadeira
* const canAccessFeature = useCombinedConditionalPermission(
* "any",
* [
* user.isPremium,
* user.isAdmin,
* user.hasTrialAccess
* ],
* "features.special"
* )
* ```
*/
declare function useCombinedConditionalPermission<TContext = any>(mode: "all" | "any", conditions: Array<boolean | (() => boolean)>, action: PermissionAction, resource?: ResourceType, context?: TContext, defaultValue?: boolean): ConditionalResult;
/**
* Hook que fornece acesso direto ao método evaluate com memoização
* Útil quando você precisa não apenas do resultado booleano, mas também dos detalhes da avaliação
*
* @returns Função evaluate memoizada
*
* @example
* ```tsx
* const evaluate = useEvaluate()
*
* // Avaliar com detalhes
* const result = evaluate("posts.edit", "posts", { postId: 123 })
*
* if (!result.allowed) {
* console.log(`Acesso negado: ${result.reason}`)
*
* if (result.matchedRule?.deny) {
* alert("Você foi explicitamente negado desta ação")
* }
* }
*
* // Em um formulário com feedback detalhado
* function PermissionFeedback({ action, resource }) {
* const evaluate = useEvaluate()
* const result = evaluate(action, resource)
*
* return (
* <div className={result.allowed ? "text-green" : "text-red"}>
* {result.allowed ? "✓" : "✗"} {action}
* {!result.allowed && (
* <small>{result.reason}</small>
* )}
* </div>
* )
* }
* ```
*/
declare function useEvaluate<TContext = any>(): (action: PermissionAction, resource?: ResourceType, context?: TContext | undefined) => EvaluationResult;
/**
* Hook que avalia uma permissão específica e retorna o resultado memoizado
* Similar ao useCan, mas retorna o objeto EvaluationResult completo
*
* @param action - Ação a avaliar
* @param resource - Recurso opcional
* @param context - Contexto adicional opcional
* @returns Resultado completo da avaliação
*
* @example
* ```tsx
* const editResult = useEvaluationResult("posts.edit", "posts", { postId: 123 })
*
* if (!editResult.allowed) {
* return (
* <Tooltip content={editResult.reason}>
* <Button disabled>
* Editar (sem permissão)
* </Button>
* </Tooltip>
* )
* }
* ```
*/
declare function useEvaluationResult<TContext = any>(action: PermissionAction, resource?: ResourceType, context?: TContext): EvaluationResult;
/**
* Hook que fornece funções utilitárias para debug e análise de permissões
*
* @returns Objeto com funções de análise
*
* @example
* ```tsx
* const { explainDenial, findMatchingRule, testPermission } = usePermissionAnalysis()
*
* // Explicar por que uma permissão foi negada
* const explanation = explainDenial("admin.delete", "users")
* console.log(explanation)
* // "Negado: No matching permission found (default deny)"
*
* // Encontrar qual regra está sendo aplicada
* const rule = findMatchingRule("posts.edit", "posts")
* if (rule) {
* console.log(`Matched rule: ${rule.action} on ${rule.resource}`)
* }
*
* // Testar permissão com diferentes contextos
* const scenarios = testPermission("posts.edit", "posts", [
* { postId: 1, authorId: 123 },
* { postId: 2, authorId: 456 },
* { postId: 3, authorId: 789 }
* ])
* ```
*/
declare function usePermissionAnalysis<TContext = any>(): {
explainDenial: (action: PermissionAction, resource?: ResourceType, context?: TContext) => string;
findMatchingRule: (action: PermissionAction, resource?: ResourceType, context?: TContext) => _shield_acl_core.PermissionRule<any> | null;
testPermission: (action: PermissionAction, resource?: ResourceType, contexts?: TContext[]) => {
allowed: boolean;
reason?: string;
matchedRule?: _shield_acl_core.PermissionRule;
context: TContext;
}[] | {
allowed: boolean;
reason?: string;
matchedRule?: _shield_acl_core.PermissionRule;
context: undefined;
}[];
};
/**
* Informações sobre a hierarquia de roles
*/
interface RoleHierarchyInfo<TContext = any> {
/** Todas as roles do usuário (incluindo herdadas) */
allRoles: RoleName[];
/** Roles diretas do usuário (não herdadas) */
directRoles: RoleName[];
/** Roles herdadas através de outras roles */
inheritedRoles: RoleName[];
/** Mapa de herança (role -> roles que ela herda) */
inheritanceMap: Record<RoleName, RoleName[]>;
/** Árvore de hierarquia completa */
hierarchyTree: RoleHierarchyNode[];
/** Verifica se usuário tem uma role específica (direta ou herdada) */
hasRole: (roleName: RoleName) => boolean;
/** Verifica se usuário tem alguma das roles listadas */
hasAnyRole: (roleNames: RoleName[]) => boolean;
/** Verifica se usuário tem todas as roles listadas */
hasAllRoles: (roleNames: RoleName[]) => boolean;
/** Obtém detalhes completos de uma role */
getRoleDetails: (roleName: RoleName) => Role<TContext> | undefined;
}
/**
* Nó da árvore de hierarquia
*/
interface RoleHierarchyNode {
name: RoleName;
direct: boolean;
children: RoleHierarchyNode[];
}
/**
* Hook que fornece informações detalhadas sobre a hierarquia de roles do usuário
*
* @returns Objeto com informações e métodos sobre hierarquia de roles
*
* @example
* ```tsx
* const roleHierarchy = useRoleHierarchy()
*
* // Verificar roles
* if (roleHierarchy.hasRole("admin")) {
* // É admin (direto ou herdado)
* }
*
* if (roleHierarchy.hasAnyRole(["editor", "moderator"])) {
* // Tem pelo menos uma das roles
* }
*
* // Visualizar hierarquia
* console.log("Roles diretas:", roleHierarchy.directRoles)
* console.log("Roles herdadas:", roleHierarchy.inheritedRoles)
* console.log("Todas as roles:", roleHierarchy.allRoles)
*
* // Analisar herança
* Object.entries(roleHierarchy.inheritanceMap).forEach(([role, inherits]) => {
* console.log(`${role} herda de: ${inherits.join(", ")}`)
* })
*
* // Componente de visualização
* function RoleTreeView() {
* const { hierarchyTree } = useRoleHierarchy()
*
* return (
* <ul>
* {hierarchyTree.map(node => (
* <RoleNode key={node.name} node={node} />
* ))}
* </ul>
* )
* }
* ```
*/
declare function useRoleHierarchy<TContext = any>(): RoleHierarchyInfo<TContext>;
/**
* Hook simplificado que retorna apenas se o usuário tem determinadas roles
*
* @param roleNames - Role ou array de roles para verificar
* @param mode - "any" (OR) ou "all" (AND), padrão é "any"
* @returns boolean indicando se tem as roles
*
* @example
* ```tsx
* // Verificar uma role
* const isAdmin = useHasRole("admin")
*
* // Verificar múltiplas roles (OR)
* const canModerate = useHasRole(["moderator", "admin"])
*
* // Verificar múltiplas roles (AND)
* const isSuperUser = useHasRole(["admin", "developer"], "all")
* ```
*/
declare function useHasRole(roleNames: RoleName | RoleName[], mode?: "any" | "all"): boolean;
/**
* Hook que retorna informações sobre uma role específica
*
* @param roleName - Nome da role
* @returns Detalhes da role ou undefined
*
* @example
* ```tsx
* const adminRole = useRoleInfo("admin")
*
* if (adminRole) {
* console.log(`Role ${adminRole.name} tem ${adminRole.permissions.length} permissões`)
* console.log(`Herda de: ${adminRole.inherits?.join(", ") || "nenhuma"}`)
* }
* ```
*/
declare function useRoleInfo<TContext = any>(roleName: RoleName): Role<TContext> | undefined;
/**
* Callback para mudança de permissão
*/
type PermissionChangeCallback<TContext = any> = (newValue: boolean, previousValue: boolean, context: {
action: PermissionAction;
resource?: ResourceType;
user: User<TContext> | null;
}) => void;
/**
* Hook que monitora mudanças em uma permissão específica
* Útil para reagir quando permissões mudam (ex: após login/logout ou mudança de roles)
*
* @param action - Ação a monitorar
* @param resource - Recurso opcional
* @param callback - Função chamada quando a permissão muda
*
* @example
* ```tsx
* // Monitorar mudança em permissão específica
* usePermissionChange("posts.create", undefined, (canCreate, couldCreate) => {
* if (canCreate && !couldCreate) {
* toast.success("Agora você pode criar posts!")
* } else if (!canCreate && couldCreate) {
* toast.warning("Você não pode mais criar posts")
* }
* })
*
* // Com recurso específico
* usePermissionChange("users.edit", "users", (canEdit, couldEdit, context) => {
* console.log(`Permissão mudou de ${couldEdit} para ${canEdit}`)
* console.log(`Usuário atual: ${context.user?.id}`)
* })
*
* // Em um componente que precisa reagir a mudanças
* function FeatureGate({ children }) {
* const [isEnabled, setIsEnabled] = useState(false)
* const can = useCan("feature.access")
*
* usePermissionChange("feature.access", undefined, (newValue) => {
* setIsEnabled(newValue)
* if (newValue) {
* loadFeatureData()
* } else {
* clearFeatureData()
* }
* })
*
* return isEnabled ? children : null
* }
* ```
*/
declare function usePermissionChange<TContext = any>(action: PermissionAction, resource: ResourceType | undefined, callback: PermissionChangeCallback<TContext>): void;
/**
* Hook que monitora mudanças em múltiplas permissões
*
* @param permissions - Array de permissões para monitorar
* @param callback - Função chamada quando qualquer permissão muda
*
* @example
* ```tsx
* // Monitorar múltiplas permissões
* useMultiplePermissionChange(
* [
* { action: "posts.create" },
* { action: "posts.edit", resource: "posts" },
* { action: "posts.delete", resource: "posts" }
* ],
* (changes) => {
* changes.forEach(({ action, resource, newValue, previousValue }) => {
* if (newValue !== previousValue) {
* console.log(`${action} mudou de ${previousValue} para ${newValue}`)
* }
* })
* }
* )
* ```
*/
declare function useMultiplePermissionChange<TContext = any>(permissions: Array<{
action: PermissionAction;
resource?: ResourceType;
}>, callback: (changes: Array<{
action: PermissionAction;
resource?: ResourceType;
newValue: boolean;
previousValue: boolean;
}>) => void): void;
/**
* Hook que executa um efeito quando o usuário ganha ou perde uma permissão
*
* @param action - Ação a monitorar
* @param resource - Recurso opcional
* @param onGain - Callback quando ganha a permissão
* @param onLose - Callback quando perde a permissão
*
* @example
* ```tsx
* // Executar ações quando ganha/perde permissão
* usePermissionEffect(
* "admin.access",
* undefined,
* () => {
* // Ganhou acesso admin
* loadAdminDashboard()
* showAdminMenu()
* },
* () => {
* // Perdeu acesso admin
* redirectToHome()
* hideAdminMenu()
* }
* )
* ```
*/
declare function usePermissionEffect<TContext = any>(action: PermissionAction, resource: ResourceType | undefined, onGain?: () => void, onLose?: () => void): void;
/**
* Hook que retorna uma função para verificar se uma permissão mudou
* Útil para verificações manuais ou condicionais
*
* @returns Função para registrar e verificar mudanças
*
* @example
* ```tsx
* const checkPermissionChange = usePermissionChangeDetector()
*
* // Registrar estado inicial
* const tracker = checkPermissionChange("posts.create")
*
* // Mais tarde, verificar se mudou
* setTimeout(() => {
* if (tracker.hasChanged()) {
* console.log(`Mudou de ${tracker.previousValue} para ${tracker.currentValue}`)
* }
* }, 5000)
* ```
*/
declare function usePermissionChangeDetector<TContext = any>(): (action: PermissionAction, resource?: ResourceType) => {
action: string;
resource: string | undefined;
previousValue: boolean;
readonly currentValue: boolean;
hasChanged(): boolean;
};
/**
* Props para componentes de renderização condicional
*/
interface CanProps<TContext = any> {
action: PermissionAction;
resource?: ResourceType;
context?: TContext;
children: ReactNode;
fallback?: ReactNode;
passThrough?: boolean;
}
interface CannotProps<TContext = any> extends Omit<CanProps<TContext>, "fallback"> {
}
/**
* Componente para renderização condicional baseada em permissões
* Renderiza children apenas se usuário TEM a permissão
*/
declare function Can<TContext = any>({ action, resource, context, children, fallback, passThrough, }: CanProps<TContext>): react_jsx_runtime.JSX.Element;
/**
* Componente inverso - renderiza apenas se usuário NÃO tem permissão
*/
declare function Cannot<TContext = any>({ action, resource, context, children, passThrough, }: CannotProps<TContext>): react_jsx_runtime.JSX.Element | null;
/**
* Componente para renderizar diferentes conteúdos baseado em permissão
*/
interface IfCanProps<TContext = any> {
action: string;
resource?: string;
context?: TContext;
yes: React.ReactNode;
no?: React.ReactNode;
}
declare function IfCan<TContext = any>({ action, resource, context, yes, no, }: IfCanProps<TContext>): react_jsx_runtime.JSX.Element;
/**
* Componente para verificar múltiplas permissões (ANY)
*/
interface CanAnyProps<TContext = any> {
permissions: Array<{
action: string;
resource?: string;
context?: TContext;
}>;
children: React.ReactNode;
fallback?: React.ReactNode;
}
declare function CanAny<TContext = any>({ permissions, children, fallback, }: CanAnyProps<TContext>): react_jsx_runtime.JSX.Element;
/**
* Componente para verificar múltiplas permissões (ALL)
*/
interface CanAllProps<TContext = any> {
permissions: Array<{
action: string;
resource?: string;
context?: TContext;
}>;
children: React.ReactNode;
fallback?: React.ReactNode;
}
declare function CanAll<TContext = any>({ permissions, children, fallback, }: CanAllProps<TContext>): react_jsx_runtime.JSX.Element;
/**
* HOC (Higher Order Component) para adicionar verificação de permissão
*/
declare function withCan<P extends object, TContext = any>(Component: React.ComponentType<P>, action: string, resource?: string, options?: {
fallback?: React.ComponentType<P>;
redirectTo?: string;
onDenied?: () => void;
}): (props: P & {
context?: TContext;
}) => react_jsx_runtime.JSX.Element | null;
/**
* Componente para aplicar classes CSS baseado em permissões
*/
interface PermissionClassProps<TContext = any> {
action: string;
resource?: string;
context?: TContext;
className: string;
deniedClassName?: string;
children: React.ReactElement;
}
declare function PermissionClass<TContext = any>({ action, resource, context, className, deniedClassName, children, }: PermissionClassProps<TContext>): ReactElement<any, string | react.JSXElementConstructor<any>> | null;
export { type ACLContextValue, ACLProvider, type ACLProviderProps, Can, CanAll, type CanAllProps, CanAny, type CanAnyProps, type CanProps, Cannot, type CannotProps, type ConditionalPermission, type ConditionalResult, IfCan, type IfCanProps, type MultiplePermissionResult, type PermissionChangeCallback, type PermissionCheck, PermissionClass, type PermissionClassProps, type PermissionHelpers, type PermissionState, type ResourceACL, type RoleHierarchyInfo, type RoleHierarchyNode, type UseACLReturn, type UsePermissionStateOptions, type UserPermissionsInfo, useACL, useACLContext, useAvailableActions, useAvailableResources, useCan, useCanAll, useCanAllActions, useCanAny, useCanAnyAction, useCanArray, useCanMap, useCanMultiple, useCannot, useCombinedConditionalPermission, useConditionalChecker, useConditionalPermission, useConditionalPermissions, useEvaluate, useEvaluationResult, useHasRole, useMultiplePermissionChange, useMultiplePermissionStates, useMultipleResourceACL, usePermissionAnalysis, usePermissionBoolean, usePermissionChange, usePermissionChangeDetector, usePermissionEffect, usePermissionHelpers, usePermissionState, usePermissions, usePermissionsList, useResourceACL, useResourcePermissions, useRoleHierarchy, useRoleInfo, withCan };