export { A as ASSIGNABLE_WORKSPACE_ROLES, a as AssignableWorkspaceRole, b as ORGANIZATION_ROLES, c as ORGANIZATION_ROLE_RANK, O as OrganizationRole, S as SandboxWorkspaceRole, W as WORKSPACE_ROLES, d as WORKSPACE_ROLE_RANK, e as WorkspaceCollaborationAccess, f as WorkspaceRole, g as canManageWorkspaceMemberRole, h as hasOrganizationRole, i as hasWorkspaceRole, j as isAssignableWorkspaceRole, o as organizationRoleGrantsWorkspaceOwner, r as resolveWorkspaceRole, w as workspaceRoleToCollaborationAccess, k as workspaceRoleToSandboxRole } from '../roles-CLtYKHHl.js';

/**
 * Pure invite-token helpers — generation, shape validation, and expiry math.
 * No I/O: the members API persists/looks up tokens; these functions only
 * produce well-formed tokens and decide, given values the caller already
 * loaded, whether an invite is usable.
 *
 * A token is an opaque high-entropy URL-safe string. It is the bearer secret
 * in `/invite/:token`, so it must be unguessable and never derived from the
 * email or workspace. `generateInviteToken` uses Web Crypto (`crypto`), which
 * is present in Workers, Node 18+, Deno, and browsers — no Node-only import,
 * so this stays a pure leaf.
 */
/** Cryptographically-random, URL-safe (base64url) invite token. */
declare function generateInviteToken(): string;
/** True when `value` has the shape of an invite token (not whether it exists). */
declare function isInviteTokenShape(value: unknown): value is string;
/** A pending invite row, narrowed to the fields invite acceptance reasons over. */
interface InviteTokenState {
    /** null until accepted — a non-null value means the invite was already used. */
    acceptedAt: Date | number | null | undefined;
    /** Email the invite was addressed to, if any. */
    inviteEmail?: string | null;
    /** Optional hard expiry; omit/undefined for invites that never expire. */
    expiresAt?: Date | number | null;
}
type InviteRejectionReason = 'already-accepted' | 'expired' | 'email-mismatch';
interface InviteValidationResult {
    ok: boolean;
    reason?: InviteRejectionReason;
}
/**
 * Decide whether a loaded invite can be accepted by `acceptingEmail` at `now`.
 * Pure: the caller has already fetched the row by token; this only judges it.
 * Email match is case-insensitive and only enforced when the invite was
 * addressed to a specific email (an open invite has no `inviteEmail`).
 */
declare function validateInviteToken(invite: InviteTokenState, opts?: {
    acceptingEmail?: string | null;
    now?: Date;
}): InviteValidationResult;

export { type InviteRejectionReason, type InviteTokenState, type InviteValidationResult, generateInviteToken, isInviteTokenShape, validateInviteToken };
