/** * Hooks for ACL gating in the UI. * * The server is the source of truth for access; these hooks just declutter * the UI so users don't see actions they can't perform. Two layers compose: * * 1. Backend ACL exposed via `/_describe` — schema-level `list`/`delete` * and field-level `read`/`create`/`update`. * 2. App-side `permissions` block in the consumer's resource config, * checked client-only (handy for hiding features that the backend * doesn't yet have ACL on). * * The user's roles come from the JWT (decoded by ``). When * either source is missing or empty, access is open (matches the * backend's behaviour when a schema declares no ACL). */ type AclOp = 'list' | 'create' | 'read' | 'update' | 'delete'; interface AclResult { allowed: boolean; /** Set of roles the JWT carries. */ userRoles: ReadonlySet; /** Set of roles the backend says are required. Empty means no gate. */ requiredRoles: ReadonlySet; } /** * Can the current user perform a resource-level operation? * `read`/`create`/`update`/`delete` map to describe's schema-level slots * where applicable; `list` follows the backend's `acl.list` slot. Custom * `permissions.{op}` from the consumer config layers on top — denial in * either layer denies overall. */ declare function useResourcePerm(path: string, op: AclOp): AclResult; /** * Can the current user read/create/update a specific field? * Returns `{ allowed: false }` to drive `hidden` on a form widget, or * `disabled` on a column. The server still enforces — this is purely * for UX. */ declare function useFieldAcl(path: string, fieldName: string, op: 'read' | 'create' | 'update'): AclResult; export { type AclOp, type AclResult, useFieldAcl, useResourcePerm };