export enum ApiPermissions { Owner = "OWNER" , ManageAccess = "MANAGE_ACCESS" , EditConfig = "EDIT_CONFIG" , ReadConfig = "READ_CONFIG" , ViewGuild = "VIEW_GUILD" } const reverseApiPermissions = Object . entries ( ApiPermissions ) . reduce ( ( map , [ key , value ] ) => { map [ value ] = key ; return map ; } , { } ) ; export const permissionNames = { [ ApiPermissions . Owner ] : "Server owner" , [ ApiPermissions . ManageAccess ] : "Bot manager" , [ ApiPermissions . EditConfig ] : "Bot operator" , [ ApiPermissions . ReadConfig ] : "Read config" , [ ApiPermissions . ViewGuild ] : "View server" , } ; export type TPermissionHierarchy = Array < ApiPermissions | [ ApiPermissions , TPermissionHierarchy ] > ; export const permissionHierarchy = [ [ ApiPermissions . Owner , [ [ ApiPermissions . ManageAccess , [ [ ApiPermissions . EditConfig , [ [ ApiPermissions . ReadConfig , [ ApiPermissions . ViewGuild , ] ] , ] ] , ] ] , ] ] , ] ; export function permissionArrToSet ( permissions ) { return new Set ( permissions . filter ( ( p ) => reverseApiPermissions [ p ] ) ) as Set < ApiPermissions > ; } /**
 * Checks whether granted permissions include the specified permission, taking into account permission hierarchy i.e.
 * that in the case of nested permissions, having a top level permission implicitly grants you any permissions nested
 * under it as well
 */ export function hasPermission ( grantedPermissions , permissionToCheck ) { if ( grantedPermissions . has ( permissionToCheck ) ) { return true ; } if ( checkTreeForPermission ( permissionHierarchy , grantedPermissions , permissionToCheck ) ) { return true ; } return false ; } function checkTreeForPermission ( tree , grantedPermissions , permission ) { for ( const item of tree ) { const [ perm , nested ] = Array . isArray ( item ) ? item : [ item ] ; if ( grantedPermissions . has ( perm ) ) { if ( nested && treeIncludesPermission ( nested , permission ) ) { return true ; } continue ; } if ( nested && checkTreeForPermission ( nested , grantedPermissions , permission ) ) { return true ; } } return false ; } function treeIncludesPermission ( tree , permission ) { for ( const item of tree ) { const [ perm , nested ] = Array . isArray ( item ) ? item : [ item ] ; if ( perm === permission ) { return true ; } const nestedResult = nested && treeIncludesPermission ( nested , permission ) ; if ( nestedResult ) { return true ; } } return false ; }