//#region src/index.ts
var AuthError = class extends Error {};
var InvalidSessionError = class extends AuthError {
	reason;
	name = "InvalidSessionError";
	constructor(message, reason) {
		super(message);
		this.reason = reason;
	}
};
var RevokedSessionError = class extends AuthError {
	userId;
	name = "RevokedSessionError";
	constructor(message, userId) {
		super(message);
		this.userId = userId;
	}
};
var RateLimitedError = class extends AuthError {
	scope;
	name = "RateLimitedError";
	constructor(message, scope) {
		super(message);
		this.scope = scope;
	}
};
var EngineMismatchError = class extends AuthError {
	name = "EngineMismatchError";
	constructor(message) {
		super(message);
	}
};
var PermissionDeniedError = class extends AuthError {
	permission;
	principal;
	name = "PermissionDeniedError";
	constructor(message, permission, principal) {
		super(message);
		this.permission = permission;
		this.principal = principal;
	}
};
var RoleDeniedError = class extends AuthError {
	role;
	principal;
	name = "RoleDeniedError";
	constructor(message, role, principal) {
		super(message);
		this.role = role;
		this.principal = principal;
	}
};
var UserNotFoundError = class extends AuthError {
	userId;
	name = "UserNotFoundError";
	constructor(message, userId) {
		super(message);
		this.userId = userId;
	}
};
const _cookieReCache = /* @__PURE__ */ new Map();
function cookieRe(name) {
	const cached = _cookieReCache.get(name);
	if (cached) return cached;
	const re = new RegExp(`(?:^|;\\s*)${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}=([^;]+)`);
	_cookieReCache.set(name, re);
	return re;
}
async function getSession(headers, engine, opts) {
	try {
		const h = headers instanceof Headers ? headers : new Headers(headers);
		const cookieName = opts?.accessCookieName ?? "access_token";
		let token = null;
		const auth = h.get("authorization");
		if (auth?.startsWith("Bearer ")) token = auth.slice(7).trim() || null;
		if (!token) token = (h.get("cookie") ?? "").match(cookieRe(cookieName))?.[1]?.trim() ?? null;
		if (!token) return null;
		return await engine.verifySession(token);
	} catch {
		return null;
	}
}
function createAuth(engine) {
	return {
		getSession: (headers, opts) => getSession(headers, engine, opts),
		signIn: (credentials) => engine.signIn(credentials),
		signOut: (sessionId, refreshToken) => engine.signOut(sessionId, refreshToken),
		refresh: (refreshToken) => engine.refresh(refreshToken)
	};
}
function hasPermission(principal, permission) {
	return principal.capabilities?.includes(permission) ?? false;
}
function isAtLeastRole(principal, role, hierarchy) {
	const targetIdx = hierarchy.indexOf(role);
	if (targetIdx < 0) return false;
	for (const r of principal.roles) {
		const idx = hierarchy.indexOf(r);
		if (idx >= 0 && idx >= targetIdx) return true;
	}
	return false;
}
function requirePermission(permission) {
	return (principal) => {
		if (!principal) throw new InvalidSessionError("no session", "missing_principal");
		if (!hasPermission(principal, permission)) throw new PermissionDeniedError(`permission denied: ${permission}`, permission, principal);
		return principal;
	};
}
/**
* Role gate — the role-based twin of `requirePermission`. Returns a resolver:
*   - `principal == null`              → throws `InvalidSessionError`
*   - `!isAtLeastRole(p, role, hier)`  → throws `RoleDeniedError`
*   - else                             → returns the principal
*
* Use with engines that populate `Principal.roles` (the custom engine does; `requirePermission`
* is capability-based and inert there). Host admin guard:
* `requireRole('admin', HIERARCHY)(await getSession(headers, engine))`.
*/
function requireRole(role, hierarchy) {
	return (principal) => {
		if (!principal) throw new InvalidSessionError("no session", "missing_principal");
		if (!isAtLeastRole(principal, role, hierarchy)) throw new RoleDeniedError(`role denied: ${role}`, role, principal);
		return principal;
	};
}
//#endregion
export { AuthError, EngineMismatchError, InvalidSessionError, PermissionDeniedError, RateLimitedError, RevokedSessionError, RoleDeniedError, UserNotFoundError, createAuth, getSession, hasPermission, isAtLeastRole, requirePermission, requireRole };
