import { type AddIntegrity, type AnyCell, type Default, equals, } from "commonfabric"; export type AdminSubject = AnyCell | object; export interface AdminRoleAssignment { readonly subject: Subject; readonly displayName: string; } export type ActiveAdminRole< Subject extends AdminSubject, Integrity extends string, > = AddIntegrity, readonly [Integrity]>; export type AdminManagerCredential = AddIntegrity< { readonly canManageAdmins: true }, readonly [Integrity] >; export interface AdminRegistryStoredValue { readonly admins?: readonly Role[]; readonly everyoneIsAdmin?: boolean; } export type EmptyAdminRegistryValue = Record; export type AdminRegistryValue = | AdminRegistryStoredValue | Default; export const adminManagerCredentialIsActive = ( credential: | { readonly canManageAdmins?: boolean } | null | undefined, ): boolean => credential?.canManageAdmins === true; export const adminRegistryEntries = ( registry: { get(): AdminRegistryValue | undefined; }, ): Role[] => Array.from( (registry.get() as AdminRegistryStoredValue | undefined) ?.admins ?? [], ); export const adminRegistryEveryoneIsAdmin = ( registry: { get(): AdminRegistryValue | undefined; }, ): boolean => { const stored = registry.get() as AdminRegistryStoredValue | undefined; if (stored?.everyoneIsAdmin === false) { return false; } const roles = adminRegistryEntries(registry); if (roles.length === 0) { return true; } return stored?.everyoneIsAdmin === true; }; export const activeAdminRoleForSubject = < Subject extends AdminSubject, Role extends AdminRoleAssignment, >( roles: readonly Role[], subject: Subject | undefined, ): Role | undefined => subject === undefined ? undefined : roles.find((role) => equals(role.subject, subject)); export const subjectHasAdminRole = < Subject extends AdminSubject, Role extends AdminRoleAssignment, >( roles: readonly Role[], subject: Subject | undefined, ): boolean => activeAdminRoleForSubject(roles, subject) !== undefined;