nest-rs-authz 0.2.0

CASL-style authorization for nestrs: one ability definition driving an access gate, a SeaORM query pre-filter, and response field-masking. Transport bindings (`http`, `graphql`, `mcp`) live behind Cargo features; the database-coupled extractors (`Bind`, `bind`, `LoaderScope`, `WsDataContext`) live in `nest-rs-seaorm` so the engine stays free of a data-layer dependency.
Documentation
//! The caller's [`Ability`] as ambient, request-scoped state.
//!
//! A singleton service cannot hold per-request state, yet transparent
//! row-level filtering needs the caller's `Ability` reachable from inside a
//! service method without threading it through every signature. A task-local
//! bridges that: the HTTP surface installs it for the duration of the handler;
//! `nestrs-seaorm`'s `Repo` reads it back. Outside a request the task-local
//! is unset and [`current_ability`] returns `None` (an unscoped query).

use std::future::Future;
use std::sync::Arc;

use crate::Ability;

tokio::task_local! {
    static ABILITY: Arc<Ability>;
}

/// The ambient [`Ability`], or `None` outside a request (or a request that
/// runs no authorization).
pub fn current_ability() -> Option<Arc<Ability>> {
    ABILITY.try_with(Arc::clone).ok()
}

pub async fn with_ability<F: Future>(ability: Arc<Ability>, fut: F) -> F::Output {
    ABILITY.scope(ability, fut).await
}