API: Guantr.prototype.cannot.any
The cannot.any sub-method performs a batch permission check — it returns true if any check in the array is denied. It is the logical negation of can.all.
Use this for decisions that need to detect if at least one action is unavailable (e.g. "should we warn the user that some features are locked?").
Signature
ts
cannot.any(
checks: Array<[action: string, resource: [resourceKey: string, resourceInstance: object]]>,
): Promise<boolean>;Parameters
checks: An array of check tuples. Each tuple is[action, [resourceKey, resourceInstance]].
Returns
Promise<boolean>:trueas soon as any check is denied (short-circuits).falseif no check is denied (all are granted).falsefor an empty array (vacuous false).
Implementation
ts
cannot.any(checks) === !(await can.all(checks));This means:
- If all checks are granted →
can.allreturnstrue→cannot.anyreturnsfalse. - If any check is denied →
can.allreturnsfalse→cannot.anyreturnstrue.
How it works
- Resolves context once and shares it across all checks.
- Delegates to
can.all— if any check fails,can.allreturnsfalse, socannot.anyreturnstrue. - Short-circuits when a check is denied (via
can.all's short-circuit on firstfalse).
Empty array behavior
Returns false (vacuous false — no check in an empty set is denied):
ts
await guantr.cannot.any([]); // falseContext sharing
Context is resolved once, then shared across all checks through the underlying can.all call.
Examples
Basic usage
ts
// Check if any action is denied for this user on this post
const anyRestricted = await guantr.cannot.any([
['delete', ['post', post]],
['archive', ['post', post]],
]);
// true if at least ONE action is deniedWith no rules (implicitly denied)
ts
// No rules exist → all permissions are implicitly denied
// So "any denied" is true
const result = await guantr.cannot.any([
['delete', ['post', { id: 1 }]],
['archive', ['post', { id: 1 }]],
]);
// true (both are implicitly denied → "any" is true)Short-circuit: first denied check
ts
// 'delete' is denied, so 'archive' is never evaluated
const result = await guantr.cannot.any([
['read', ['post', post]], // allowed → continue
['delete', ['post', post]], // denied → short-circuit, return true
['archive', ['post', post]], // never evaluated
]);
// trueAll allowed
ts
// User has full access — all checks pass
const result = await guantr.cannot.any([
['read', ['post', post]], // allowed
['update', ['post', post]], // allowed
]);
// false — nothing is deniedUI pattern: show a warning
ts
const hasRestrictions = await guantr.cannot.any([
['delete', ['post', post]],
['archive', ['post', post]],
['pin', ['post', post]],
]);
if (hasRestrictions) {
// Show a warning: "Some actions are restricted for this post"
}See also
cannot.all— Check if all permissions are denied.can.all— Check if all permissions are granted.can.any— Check if any permission is granted.cannot— Single permission check.