//#region src/index.ts
var TenancyError = class extends Error {};
var TenantNotFoundError = class extends TenancyError {
	tenantId;
	name = "TenantNotFoundError";
	constructor(message, tenantId) {
		super(message);
		this.tenantId = tenantId;
	}
};
var NotAMemberError = class extends TenancyError {
	tenantId;
	userId;
	name = "NotAMemberError";
	constructor(message, tenantId, userId) {
		super(message);
		this.tenantId = tenantId;
		this.userId = userId;
	}
};
var MembershipFrozenError = class extends TenancyError {
	tenantId;
	userId;
	name = "MembershipFrozenError";
	constructor(message, tenantId, userId) {
		super(message);
		this.tenantId = tenantId;
		this.userId = userId;
	}
};
var ScopeViolationError = class extends TenancyError {
	tenantId;
	name = "ScopeViolationError";
	constructor(message, tenantId) {
		super(message);
		this.tenantId = tenantId;
	}
};
function randomId() {
	return crypto.randomUUID();
}
function createMemoryTenancyStore() {
	const tenants = /* @__PURE__ */ new Map();
	const bySlug = /* @__PURE__ */ new Map();
	const memberships = /* @__PURE__ */ new Map();
	const memberKey = (tenantId, userId) => `${tenantId}:${userId}`;
	return {
		async createTenant(input) {
			const tenant = {
				id: randomId(),
				slug: input.slug,
				name: input.name,
				status: input.status ?? "active",
				ownerId: input.ownerId,
				createdAt: /* @__PURE__ */ new Date()
			};
			tenants.set(tenant.id, tenant);
			bySlug.set(tenant.slug, tenant.id);
			return tenant;
		},
		async getTenant(tenantId) {
			return tenants.get(tenantId) ?? null;
		},
		async getTenantBySlug(slug) {
			const id = bySlug.get(slug);
			return id ? tenants.get(id) ?? null : null;
		},
		async suspendTenant(tenantId) {
			const tenant = tenants.get(tenantId);
			if (!tenant) throw new TenantNotFoundError("tenant not found", tenantId);
			const updated = {
				...tenant,
				status: "suspended"
			};
			tenants.set(tenantId, updated);
			return updated;
		},
		async addMember(membership) {
			memberships.set(memberKey(membership.tenantId, membership.userId), { ...membership });
			return membership;
		},
		async removeMember(tenantId, userId) {
			memberships.delete(memberKey(tenantId, userId));
		},
		async setMemberRole(tenantId, userId, roleKey) {
			const key = memberKey(tenantId, userId);
			const existing = memberships.get(key);
			if (!existing) throw new NotAMemberError("not a member", tenantId, userId);
			const updated = {
				...existing,
				roleKey
			};
			memberships.set(key, updated);
			return updated;
		},
		async freezeMember(tenantId, userId) {
			const key = memberKey(tenantId, userId);
			const existing = memberships.get(key);
			if (!existing) throw new NotAMemberError("not a member", tenantId, userId);
			const updated = {
				...existing,
				status: "frozen"
			};
			memberships.set(key, updated);
			return updated;
		},
		async listMembers(tenantId) {
			return [...memberships.values()].filter((m) => m.tenantId === tenantId);
		},
		async getMembership(tenantId, userId) {
			return memberships.get(memberKey(tenantId, userId)) ?? null;
		}
	};
}
async function resolveCapabilitiesClosed(store, rbac, userId, tenantId) {
	const tenant = await store.getTenant(tenantId);
	if (!tenant || tenant.status !== "active") return [];
	const membership = await store.getMembership(tenantId, userId);
	if (!membership || membership.status !== "active") return [];
	return rbac.resolveCapabilities({
		userId,
		tenantId,
		roleKey: membership.roleKey
	});
}
function createTenancy(deps) {
	const { store, isolation, rbac } = deps;
	return {
		...isolation ? { scopeQuerier: (q, tenantId) => isolation.scopeQuerier(q, tenantId) } : {},
		resolveCapabilities: (userId, tenantId) => resolveCapabilitiesClosed(store, rbac, userId, tenantId),
		createTenant: (input) => store.createTenant(input),
		getTenant: (tenantId) => store.getTenant(tenantId),
		suspendTenant: async (tenantId) => {
			return await store.suspendTenant(tenantId);
		},
		addMember: (membership) => store.addMember(membership),
		removeMember: (tenantId, userId) => store.removeMember(tenantId, userId),
		setMemberRole: (tenantId, userId, roleKey) => store.setMemberRole(tenantId, userId, roleKey),
		freezeMember: (tenantId, userId) => store.freezeMember(tenantId, userId),
		listMembers: (tenantId) => store.listMembers(tenantId)
	};
}
//#endregion
export { MembershipFrozenError, NotAMemberError, ScopeViolationError, TenancyError, TenantNotFoundError, createMemoryTenancyStore, createTenancy };
