/**
 * @beignet/core/entitlements
 *
 * Provider-neutral product access primitives for Beignet applications.
 */
type MaybePromise<T> = T | Promise<T>;
/**
 * Stable app-defined capability key, such as "issues.create".
 */
export type EntitlementKey = string;
/**
 * Principal whose product access is being checked.
 */
export type EntitlementSubject = {
    /**
     * App-defined subject type, commonly "tenant" or "account".
     */
    type: string;
    /**
     * Stable subject identifier.
     */
    id: string;
};
/**
 * Input for checking whether a subject has access to a capability.
 */
export type EntitlementCheckInput<TKey extends EntitlementKey = EntitlementKey> = {
    /**
     * Capability being checked.
     */
    entitlement: TKey;
    /**
     * Tenant, account, or other app-owned subject whose product access is checked.
     */
    subject: EntitlementSubject;
};
/**
 * An entitlement decision that allows the capability.
 */
export type EntitlementAllowedDecision = {
    allowed: true;
};
/**
 * An entitlement decision that denies the capability.
 */
export type EntitlementDeniedDecision = {
    allowed: false;
    reason?: string;
    code?: string;
    details?: unknown;
};
/**
 * Normalized entitlement decision.
 */
export type EntitlementDecision = EntitlementAllowedDecision | EntitlementDeniedDecision;
/**
 * Value an entitlement resolver may return.
 */
export type EntitlementResolverResult = boolean | EntitlementDecision;
/**
 * Entitlement port method that produced a decision.
 */
export type EntitlementDecisionSource = "can" | "inspect" | "require";
/**
 * Optional context for entitlement checks.
 */
export type EntitlementCheckOptions<TContext = unknown> = {
    /**
     * Application context used for the check. Observers can use this to copy
     * request correlation fields without coupling the resolver to app context.
     */
    ctx?: TContext;
    /**
     * Source to report to observers. Port methods set this automatically.
     */
    source?: EntitlementDecisionSource;
};
/**
 * App-facing product access port.
 */
export type EntitlementsPort<TKey extends EntitlementKey = EntitlementKey, TContext = unknown> = {
    /**
     * Return only whether the capability is allowed.
     */
    can(input: EntitlementCheckInput<TKey>, options?: EntitlementCheckOptions<TContext>): Promise<boolean>;
    /**
     * Return the full allow/deny decision without throwing.
     */
    inspect(input: EntitlementCheckInput<TKey>, options?: EntitlementCheckOptions<TContext>): Promise<EntitlementDecision>;
};
/**
 * Function that decides whether an entitlement is granted.
 */
export type EntitlementResolver<TKey extends EntitlementKey = EntitlementKey> = (input: EntitlementCheckInput<TKey>) => MaybePromise<EntitlementResolverResult>;
/**
 * Best-effort entitlement decision observation emitted by an entitlements port.
 *
 * Observers are diagnostic only. They do not participate in entitlement
 * control flow and thrown/rejected observer errors are ignored.
 */
export type EntitlementDecisionObservation<TContext = unknown, TKey extends EntitlementKey = EntitlementKey> = {
    /**
     * Port helper that produced the decision.
     */
    source: EntitlementDecisionSource;
    /**
     * Application context passed by the caller, when available.
     */
    ctx?: TContext;
    /**
     * Capability being evaluated.
     */
    entitlement: TKey;
    /**
     * Subject whose product access is checked.
     */
    subject: EntitlementSubject;
    /**
     * Normalized decision, when resolver evaluation returned normally.
     */
    decision?: EntitlementDecision;
    /**
     * Error thrown by the resolver, when evaluation failed.
     */
    error?: unknown;
    /**
     * Resolver duration, excluding observer work.
     */
    durationMs: number;
    /**
     * Correlation fields copied from the context when present.
     */
    requestId?: string;
    traceId?: string;
    spanId?: string;
    parentSpanId?: string;
    traceparent?: string;
};
/**
 * Best-effort observer called after each entitlement decision or resolver
 * error.
 */
export type EntitlementDecisionObserver<TContext = unknown, TKey extends EntitlementKey = EntitlementKey> = (observation: EntitlementDecisionObservation<TContext, TKey>) => MaybePromise<void>;
/**
 * Options for `createEntitlements(...)`.
 */
export type CreateEntitlementsOptions<TKey extends EntitlementKey = EntitlementKey, TContext = unknown> = {
    /**
     * Resolver that maps app-owned product state to an entitlement decision.
     */
    inspect: EntitlementResolver<TKey>;
    /**
     * Optional best-effort observer for entitlement decisions.
     *
     * This hook is diagnostic only: it cannot change decisions or thrown errors.
     */
    onDecision?: EntitlementDecisionObserver<TContext, TKey>;
};
/**
 * Static grant map keyed by subject key.
 */
export type StaticEntitlementGrantMap<TKey extends EntitlementKey = EntitlementKey> = Record<string, readonly TKey[]>;
/**
 * Options for `createStaticEntitlements(...)`.
 */
export type CreateStaticEntitlementsOptions<TKey extends EntitlementKey = EntitlementKey, TContext = unknown> = {
    /**
     * Granted capabilities keyed by subject. The default key is
     * `${subject.type}:${subject.id}`.
     */
    grants: StaticEntitlementGrantMap<TKey>;
    /**
     * Optional subject key mapper.
     */
    subjectKey?: (subject: EntitlementSubject) => string;
    /**
     * Default denial decision fields.
     */
    denied?: Omit<EntitlementDeniedDecision, "allowed">;
    /**
     * Optional best-effort observer for entitlement decisions.
     */
    onDecision?: EntitlementDecisionObserver<TContext, TKey>;
};
/**
 * Options accepted by `requireEntitlement(...)`.
 */
export type RequireEntitlementOptions<TKey extends EntitlementKey = EntitlementKey> = {
    /**
     * Create the error to throw instead of the framework default.
     */
    error?: (decision: EntitlementDeniedDecision, input: EntitlementCheckInput<TKey>) => unknown;
};
/**
 * Context shape consumed by `requireEntitlement(...)`.
 */
export type EntitlementsContext<TKey extends EntitlementKey = EntitlementKey> = {
    ports: {
        entitlements: EntitlementsPort<TKey>;
    };
};
/**
 * Error thrown by `requireEntitlement(...)` when product access is denied.
 */
export declare class EntitlementRequiredError extends Error {
    readonly code: string;
    readonly status = 403;
    readonly details?: unknown;
    readonly entitlement: string;
    readonly subject: EntitlementSubject;
    constructor(input: EntitlementCheckInput, decision?: EntitlementDeniedDecision);
}
/**
 * Create an explicit allow decision.
 */
export declare function allowEntitlement(): EntitlementAllowedDecision;
/**
 * Create an explicit deny decision.
 */
export declare function denyEntitlement(reasonOrDecision?: string | Omit<EntitlementDeniedDecision, "allowed">): EntitlementDeniedDecision;
/**
 * Create an entitlement port from an app-owned resolver.
 */
export declare function createEntitlements<TKey extends EntitlementKey = EntitlementKey, TContext = unknown>(options: CreateEntitlementsOptions<TKey, TContext>): EntitlementsPort<TKey, TContext>;
/**
 * Create a static entitlement port for tests, starters, and simple apps.
 */
export declare function createStaticEntitlements<TKey extends EntitlementKey = EntitlementKey, TContext = unknown>(options: CreateStaticEntitlementsOptions<TKey, TContext>): EntitlementsPort<TKey, TContext>;
/**
 * Require an entitlement or throw a framework-owned 403 error.
 */
export declare function requireEntitlement<TKey extends EntitlementKey = EntitlementKey>(ctx: EntitlementsContext<TKey>, input: EntitlementCheckInput<TKey>, options?: RequireEntitlementOptions<TKey>): Promise<EntitlementAllowedDecision>;
export {};
//# sourceMappingURL=index.d.ts.map