mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-16 11:28:15 +00:00
v7 stuff lots of stuff
This commit is contained in:
Generated
+8833
-4973
File diff suppressed because it is too large
Load Diff
+40
-40
@@ -5,52 +5,52 @@
|
||||
"author": "Praveen <praveen@hasura.io> (@praveenweb)",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-export-default-from": "^7.7.4",
|
||||
"@emotion/core": "^10.0.22",
|
||||
"@emotion/styled": "^10.0.23",
|
||||
"@emotion/styled-base": "^10.0.24",
|
||||
"@mdx-js/loader": "^1.5.1",
|
||||
"@mdx-js/mdx": "^1.5.1",
|
||||
"@mdx-js/react": "^1.5.1",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.10.4",
|
||||
"@emotion/core": "^10.0.28",
|
||||
"@emotion/styled": "^10.0.27",
|
||||
"@emotion/styled-base": "^10.0.31",
|
||||
"@mdx-js/loader": "^1.6.16",
|
||||
"@mdx-js/mdx": "^1.6.16",
|
||||
"@mdx-js/react": "^1.6.16",
|
||||
"@philpl/buble": "^0.19.7",
|
||||
"@playlyfe/gql": "^2.6.2",
|
||||
"algoliasearch": "^3.35.1",
|
||||
"dotenv": "^8.2.0",
|
||||
"emotion": "^10.0.23",
|
||||
"emotion-server": "^10.0.17",
|
||||
"emotion-theming": "^10.0.19",
|
||||
"gatsby": "^2.18.10",
|
||||
"gatsby-link": "^2.2.27",
|
||||
"emotion": "^10.0.27",
|
||||
"emotion-server": "^10.0.27",
|
||||
"emotion-theming": "^10.0.27",
|
||||
"gatsby": "^2.24.27",
|
||||
"gatsby-link": "^2.4.13",
|
||||
"gatsby-plugin-algolia": "^0.5.0",
|
||||
"gatsby-plugin-emotion": "^4.1.18",
|
||||
"gatsby-plugin-gtag": "^1.0.12",
|
||||
"gatsby-plugin-layout": "^1.1.18",
|
||||
"gatsby-plugin-manifest": "^2.2.33",
|
||||
"gatsby-plugin-mdx": "^1.0.61",
|
||||
"gatsby-plugin-offline": "^3.0.29",
|
||||
"gatsby-plugin-react-helmet": "^3.1.18",
|
||||
"gatsby-plugin-emotion": "^4.3.10",
|
||||
"gatsby-plugin-gtag": "^1.0.13",
|
||||
"gatsby-plugin-layout": "^1.3.10",
|
||||
"gatsby-plugin-manifest": "^2.4.21",
|
||||
"gatsby-plugin-mdx": "^1.2.33",
|
||||
"gatsby-plugin-offline": "^3.2.21",
|
||||
"gatsby-plugin-react-helmet": "^3.3.10",
|
||||
"gatsby-plugin-remove-serviceworker": "^1.0.0",
|
||||
"gatsby-plugin-sharp": "^2.3.7",
|
||||
"gatsby-plugin-sitemap": "^2.2.24",
|
||||
"gatsby-remark-copy-linked-files": "^2.1.33",
|
||||
"gatsby-remark-images": "^3.1.37",
|
||||
"gatsby-source-filesystem": "^2.1.42",
|
||||
"gatsby-transformer-remark": "^2.6.42",
|
||||
"graphql": "^14.5.8",
|
||||
"gatsby-plugin-sharp": "^2.6.24",
|
||||
"gatsby-plugin-sitemap": "^2.4.11",
|
||||
"gatsby-remark-copy-linked-files": "^2.3.12",
|
||||
"gatsby-remark-images": "^3.3.24",
|
||||
"gatsby-source-filesystem": "^2.3.23",
|
||||
"gatsby-transformer-remark": "^2.8.27",
|
||||
"graphql": "^14.7.0",
|
||||
"is-absolute-url": "^3.0.3",
|
||||
"lodash.flatten": "^4.4.0",
|
||||
"lodash.startcase": "^4.4.0",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-feather": "^2.0.3",
|
||||
"react-github-btn": "^1.1.1",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-feather": "^2.0.8",
|
||||
"react-github-btn": "^1.2.0",
|
||||
"react-helmet": "^5.2.1",
|
||||
"react-id-generator": "^3.0.0",
|
||||
"react-instantsearch-dom": "^6.0.0",
|
||||
"react-id-generator": "^3.0.1",
|
||||
"react-instantsearch-dom": "^6.7.0",
|
||||
"react-live": "^2.2.2",
|
||||
"react-loadable": "^5.5.0",
|
||||
"styled-components": "^4.4.1",
|
||||
"styled-icons": "^9.0.1"
|
||||
"styled-icons": "^9.5.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "n/a",
|
||||
@@ -63,13 +63,13 @@
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.10.0",
|
||||
"eslint-plugin-import": "^2.20.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.2.3",
|
||||
"eslint-plugin-prettier": "^3.1.2",
|
||||
"eslint-plugin-react": "^7.19.0",
|
||||
"gatsby-plugin-remove-trailing-slashes": "^2.1.17",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.3.1",
|
||||
"eslint-plugin-prettier": "^3.1.4",
|
||||
"eslint-plugin-react": "^7.20.5",
|
||||
"gatsby-plugin-remove-trailing-slashes": "^2.3.11",
|
||||
"prettier": "^1.19.1",
|
||||
"prism-react-renderer": "^1.0.2"
|
||||
"prism-react-renderer": "^1.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ export function hasChannelPermission(
|
||||
|
||||
return permissions.every((perm) => {
|
||||
if (overwrite) {
|
||||
if (overwrite.deny & perm) return false;
|
||||
if (overwrite.allow & perm) return true;
|
||||
if (BigInt(overwrite.deny_new) & BigInt(perm)) return false;
|
||||
if (BigInt(overwrite.allow_new) & BigInt(perm)) return true;
|
||||
}
|
||||
if (channel.guildID) {
|
||||
return botHasPermission(channel.guildID, [perm]);
|
||||
@@ -122,7 +122,7 @@ export async function sendMessage(
|
||||
if (
|
||||
content.tts &&
|
||||
!botHasChannelPermissions(
|
||||
channel.guildID,
|
||||
channel.id,
|
||||
[Permissions.SEND_TTS_MESSAGES],
|
||||
)
|
||||
) {
|
||||
@@ -130,7 +130,12 @@ export async function sendMessage(
|
||||
}
|
||||
}
|
||||
|
||||
if (content.content && content.content.length > 2000) {
|
||||
if (content.embed && !botHasChannelPermissions(channel.id, [Permissions.EMBED_LINKS])) {
|
||||
throw new Error(Errors.MISSING_EMBED_LINKS)
|
||||
}
|
||||
|
||||
// Use ... for content length due to unicode characters and js .length handling
|
||||
if (content.content && [...content.content].length > 2000) {
|
||||
throw new Error(Errors.MESSAGE_MAX_LENGTH);
|
||||
}
|
||||
|
||||
@@ -315,12 +320,12 @@ export function editChannel(channel: Channel, options: ChannelEditOptions) {
|
||||
return {
|
||||
...overwrite,
|
||||
allow: overwrite.allow.reduce(
|
||||
(bits, perm) => bits |= Permissions[perm],
|
||||
0,
|
||||
(bits, perm) => bits |= BigInt(Permissions[perm]),
|
||||
BigInt(0),
|
||||
),
|
||||
deny: overwrite.deny.reduce(
|
||||
(bits, perm) => bits |= Permissions[perm],
|
||||
0,
|
||||
(bits, perm) => bits |= BigInt(Permissions[perm]),
|
||||
BigInt(0),
|
||||
),
|
||||
};
|
||||
},
|
||||
@@ -105,8 +105,14 @@ export async function createGuildChannel(
|
||||
name,
|
||||
permission_overwrites: options?.permission_overwrites?.map((perm) => ({
|
||||
...perm,
|
||||
allow: perm.allow.map((p) => Permissions[p]),
|
||||
deny: perm.deny.map((p) => Permissions[p]),
|
||||
allow: perm.allow.reduce(
|
||||
(bits, p) => bits & BigInt(Permissions[p]),
|
||||
BigInt(0),
|
||||
).toString(),
|
||||
deny: perm.deny.reduce(
|
||||
(bits, p) => bits & BigInt(Permissions[p]),
|
||||
BigInt(0),
|
||||
).toString(),
|
||||
})),
|
||||
type: options?.type || ChannelTypes.GUILD_TEXT,
|
||||
})) as ChannelCreatePayload;
|
||||
@@ -117,12 +123,16 @@ export async function createGuildChannel(
|
||||
}
|
||||
|
||||
/** Delete a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */
|
||||
export function deleteChannel(guildID: string, channelID: string, reason?: string) {
|
||||
export function deleteChannel(
|
||||
guildID: string,
|
||||
channelID: string,
|
||||
reason?: string,
|
||||
) {
|
||||
if (!botHasPermission(guildID, [Permissions.MANAGE_CHANNELS])) {
|
||||
throw new Error(Errors.MISSING_MANAGE_CHANNELS);
|
||||
}
|
||||
|
||||
return RequestManager.delete(endpoints.CHANNEL(channelID), { reason })
|
||||
return RequestManager.delete(endpoints.CHANNEL(channelID), { reason });
|
||||
}
|
||||
|
||||
/** Returns a list of guild channel objects.
|
||||
@@ -500,15 +510,18 @@ export function channelHasPermissions(
|
||||
const role = guild.roles.get(roleID);
|
||||
if (!role) return bits;
|
||||
|
||||
bits |= role.permissions;
|
||||
bits |= role.permissions.reduce(
|
||||
(bits, p) => bits & BigInt(Permissions[p]),
|
||||
BigInt(0),
|
||||
);
|
||||
|
||||
return bits;
|
||||
}, 0);
|
||||
}, BigInt(0));
|
||||
|
||||
if (permissionBits & Permissions.ADMINISTRATOR) return true;
|
||||
if (permissionBits & BigInt(Permissions.ADMINISTRATOR)) return true;
|
||||
|
||||
return permissions.every((permission) =>
|
||||
permissionBits & Permissions[permission]
|
||||
permissionBits & BigInt(Permissions[permission])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -148,8 +148,7 @@ export async function handleDiscordPayload(
|
||||
// Triggered on each shard
|
||||
eventHandlers.shardReady?.(shardID);
|
||||
if (payload.shard && shardID === payload.shard[1] - 1) {
|
||||
// Delay 10 seconds to let all the guilds on this last shard load before ready is sent
|
||||
await delay(10000);
|
||||
cache.isReady = true;
|
||||
eventHandlers.ready?.();
|
||||
}
|
||||
// Wait 5 seconds to spawn next shard
|
||||
@@ -181,6 +180,7 @@ export async function handleDiscordPayload(
|
||||
cache.unavailableGuilds.delete(options.id);
|
||||
}
|
||||
|
||||
if (!cache.isReady) return eventHandlers.guildLoaded?.(guild);
|
||||
return eventHandlers.guildCreate?.(guild);
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ export function createChannel(data: ChannelCreatePayload, guildID?: string) {
|
||||
permissions: data.permission_overwrites
|
||||
? data.permission_overwrites.map((perm) => ({
|
||||
...perm,
|
||||
allow: calculatePermissions(perm.allow),
|
||||
deny: calculatePermissions(perm.deny),
|
||||
allow: calculatePermissions(BigInt(perm.allow_new)),
|
||||
deny: calculatePermissions(BigInt(perm.deny_new)),
|
||||
}))
|
||||
: [],
|
||||
/** Whether this channel is nsfw or not */
|
||||
@@ -1,7 +1,9 @@
|
||||
import { RoleData } from "../types/role.ts";
|
||||
import { calculatePermissions } from "../utils/permissions.ts";
|
||||
|
||||
export const createRole = (data: RoleData) => ({
|
||||
...data,
|
||||
permissions: calculatePermissions(BigInt(data.permissions_new)),
|
||||
/** The @ mention of the role in a string. */
|
||||
mention: `<@&${data.id}>`,
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Timestamps } from "../types/discord.ts";
|
||||
import { Timestamps } from "./discord.ts";
|
||||
|
||||
export interface ActivityPayload {
|
||||
name: string;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Raw_Overwrite, Overwrite } from "./guild.ts";
|
||||
import { RawOverwrite, Overwrite } from "./guild.ts";
|
||||
import { Embed } from "./message.ts";
|
||||
|
||||
export interface ChannelEditOptions {
|
||||
@@ -71,14 +71,28 @@ export interface ChannelCreatePayload extends Base_Channel_Create {
|
||||
/** The type of the channel */
|
||||
type: Channel_Type;
|
||||
/** Explicit permission overwrites for members and roles */
|
||||
permission_overwrites?: Raw_Overwrite[];
|
||||
permission_overwrites?: RawOverwrite[];
|
||||
}
|
||||
|
||||
export interface CreateChannelOptions extends Base_Channel_Create {
|
||||
export interface CreateChannelOptions {
|
||||
/** The type of the channel */
|
||||
type?: ChannelTypes;
|
||||
/** The channel topic (0-1024 characters) */
|
||||
topic?: string;
|
||||
/** The bitrate (in bits) of the voice channel */
|
||||
bitrate?: number;
|
||||
/** The user limit of the voice channel */
|
||||
user_limit?: number;
|
||||
/** Amount of seconds a user has to wait before sending another message (0-21600) Bots and users with the permission MANAGE_MESSAGES or MANAGE_CHANNEL are unaffected. */
|
||||
rate_limit_per_user?: number;
|
||||
/** Sorting position of the channel */
|
||||
position?: number;
|
||||
/** Explicit permission overwrites for members and roles */
|
||||
permission_overwrites?: Overwrite[];
|
||||
/** The parent category id */
|
||||
parent_id?: string | null;
|
||||
/** Whether the channel is nsfw */
|
||||
nsfw?: boolean;
|
||||
}
|
||||
|
||||
export type Channel_Type = 0 | 1 | 2 | 4 | 5 | 6;
|
||||
@@ -16,6 +16,7 @@ export enum Errors {
|
||||
MISSING_BAN_MEMBERS = "MISSING_BAN_MEMBERS",
|
||||
MISSING_MANAGE_GUILD = "MISSING_MANAGE_GUILD",
|
||||
MISSING_VIEW_AUDIT_LOG = "MISSING_VIEW_AUDIT_LOG",
|
||||
MISSING_EMBED_LINKS = "MISSING_EMBED_LINKS",
|
||||
DELETE_MESSAGES_MIN = "DELETE_MESSAGES_MIN",
|
||||
MESSAGE_MAX_LENGTH = "MESSAGE_MAX_LENGTH",
|
||||
NICKNAMES_MAX_LENGTH = "NICKNAMES_MAX_LENGTH",
|
||||
@@ -465,7 +465,7 @@ export interface Overwrite {
|
||||
deny: Permission[];
|
||||
}
|
||||
|
||||
export interface Raw_Overwrite {
|
||||
export interface RawOverwrite {
|
||||
/** The role or user id */
|
||||
id: string;
|
||||
/** Whether this is a role or a member */
|
||||
@@ -474,6 +474,10 @@ export interface Raw_Overwrite {
|
||||
allow: number;
|
||||
/** The permissions that this id is NOT allowed to do. (This will mark it as a red x.) */
|
||||
deny: number;
|
||||
/** permission bit set for new perms until new api version released. */
|
||||
allow_new: string;
|
||||
/** permission bit set for new perms until new api version released. */
|
||||
deny_new: string;
|
||||
}
|
||||
|
||||
export interface ChannelCreate_Options {
|
||||
@@ -83,6 +83,7 @@ export interface EventHandlers {
|
||||
guildBanAdd?: (guild: Guild, user: Member | UserPayload) => unknown;
|
||||
guildBanRemove?: (guild: Guild, user: Member | UserPayload) => unknown;
|
||||
guildCreate?: (guild: Guild) => unknown;
|
||||
guildLoaded?: (guild: Guild) => unknown;
|
||||
guildUpdate?: (guild: Guild, changes: GuildUpdateChange[]) => unknown;
|
||||
guildDelete?: (guild: Guild) => unknown;
|
||||
guildEmojisUpdate?: (
|
||||
@@ -1,4 +1,4 @@
|
||||
import { StatusType } from "../types/discord.ts";
|
||||
import { StatusType } from "./discord.ts";
|
||||
|
||||
export interface ClientStatusPayload {
|
||||
/** The user's status set for an active desktop (Windows, Linux, Mac) application session */
|
||||
@@ -11,6 +11,8 @@ export interface RoleData {
|
||||
position: number;
|
||||
/** permission bit set */
|
||||
permissions: number;
|
||||
/** permission bit set */
|
||||
permissions_new: string;
|
||||
/** whether this role is managed by an integration */
|
||||
managed: boolean;
|
||||
/** whether this role is mentionable */
|
||||
@@ -6,6 +6,7 @@ import { delay } from "https://deno.land/std@0.61.0/async/delay.ts";
|
||||
import { PresenceUpdatePayload } from "../types/discord.ts";
|
||||
|
||||
export interface CacheData {
|
||||
isReady: boolean;
|
||||
guilds: Collection<string, Guild>;
|
||||
channels: Collection<string, Channel>;
|
||||
messages: Collection<string, Message>;
|
||||
@@ -14,6 +15,7 @@ export interface CacheData {
|
||||
}
|
||||
|
||||
export const cache: CacheData = {
|
||||
isReady: false,
|
||||
guilds: new Collection(),
|
||||
channels: new Collection(),
|
||||
messages: new Collection(),
|
||||
@@ -1,4 +1,7 @@
|
||||
import { Permission, Permissions } from "../types/permission.ts";
|
||||
import {
|
||||
Permission,
|
||||
Permissions,
|
||||
} from "../types/permission.ts";
|
||||
import { cache } from "./cache.ts";
|
||||
import { botID } from "../module/client.ts";
|
||||
import { Role } from "../structures/role.ts";
|
||||
@@ -14,17 +17,20 @@ export function memberHasPermission(
|
||||
if (memberID === guild.ownerID) return true;
|
||||
|
||||
const permissionBits = memberRoleIDs.map((id) =>
|
||||
guild.roles.get(id)?.permissions || 0
|
||||
guild.roles.get(id)?.permissions || []
|
||||
)
|
||||
.reduce((bits, permissions) => {
|
||||
bits |= permissions;
|
||||
bits |= permissions.reduce(
|
||||
(b, p) => b & BigInt(Permissions[p]),
|
||||
BigInt(0),
|
||||
);
|
||||
return bits;
|
||||
}, 0);
|
||||
}, BigInt(0));
|
||||
|
||||
if (permissionBits & Permissions.ADMINISTRATOR) return true;
|
||||
if (permissionBits & BigInt(Permissions.ADMINISTRATOR)) return true;
|
||||
|
||||
return permissions.every((permission) =>
|
||||
permissionBits & Permissions[permission]
|
||||
permissionBits & BigInt(Permissions[permission])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -38,14 +44,17 @@ export function botHasPermission(guildID: string, permissions: Permissions[]) {
|
||||
const permissionBits = member.roles
|
||||
.map((id) => guild.roles.get(id)!)
|
||||
.reduce((bits, data) => {
|
||||
bits |= data.permissions;
|
||||
bits |= data.permissions.reduce(
|
||||
(b, p) => b & BigInt(Permissions[p]),
|
||||
BigInt(0),
|
||||
);
|
||||
|
||||
return bits;
|
||||
}, 0);
|
||||
}, BigInt(0));
|
||||
|
||||
if (permissionBits & Permissions.ADMINISTRATOR) return true;
|
||||
if (permissionBits & BigInt(Permissions.ADMINISTRATOR)) return true;
|
||||
|
||||
return permissions.every((permission) => permissionBits & permission);
|
||||
return permissions.every((permission) => permissionBits & BigInt(permission));
|
||||
}
|
||||
|
||||
/** Checks if the bot has the permissions in a channel */
|
||||
@@ -90,14 +99,20 @@ export function hasChannelPermissions(
|
||||
|
||||
if (memberOverwrite) {
|
||||
// One of the necessary permissions is denied
|
||||
if (permissions.some((perm) => memberOverwrite.deny & perm)) {
|
||||
if (
|
||||
permissions.some((perm) =>
|
||||
BigInt(memberOverwrite.deny_new) & BigInt(perm)
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
permissions.forEach((perm) => {
|
||||
// Already allowed perm
|
||||
if (allowedPermissions.has(perm)) return;
|
||||
// This perm is allowed so we save it
|
||||
if (memberOverwrite.allow & perm) allowedPermissions.add(perm);
|
||||
if (BigInt(memberOverwrite.allow_new) & BigInt(perm)) {
|
||||
allowedPermissions.add(perm);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -106,11 +121,11 @@ export function hasChannelPermissions(
|
||||
if (
|
||||
rolesOverwrites.some((overwrite) =>
|
||||
permissions.some((perm) =>
|
||||
(overwrite.deny & perm) &&
|
||||
(BigInt(overwrite.deny_new) & BigInt(perm)) &&
|
||||
// If another role allows these perms then they are not denied
|
||||
!rolesOverwrites.some((o) => o.allow & perm) &&
|
||||
!rolesOverwrites.some((o) => BigInt(o.allow_new) & BigInt(perm)) &&
|
||||
// Make sure the memberOverwrite does not allow this perm
|
||||
!(memberOverwrite && memberOverwrite.allow & perm)
|
||||
!(memberOverwrite && BigInt(memberOverwrite.allow_new) & BigInt(perm))
|
||||
)
|
||||
)
|
||||
) {
|
||||
@@ -122,7 +137,9 @@ export function hasChannelPermissions(
|
||||
if (allowedPermissions.has(perm)) return;
|
||||
rolesOverwrites.forEach((overwrite) => {
|
||||
// This perm is allowed so we save it
|
||||
if (overwrite.allow & perm) allowedPermissions.add(perm);
|
||||
if (BigInt(overwrite.allow_new) & BigInt(perm)) {
|
||||
allowedPermissions.add(perm);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -133,14 +150,17 @@ export function hasChannelPermissions(
|
||||
) {
|
||||
if (
|
||||
permissions.some((perm) =>
|
||||
everyoneOverwrite.deny & perm && !allowedPermissions.has(perm)
|
||||
BigInt(everyoneOverwrite.deny_new) & BigInt(perm) &&
|
||||
!allowedPermissions.has(perm)
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// If all permissions are granted
|
||||
if (
|
||||
permissions.every((perm) => everyoneOverwrite.allow & perm)
|
||||
permissions.every((perm) =>
|
||||
BigInt(everyoneOverwrite.allow_new) & BigInt(perm)
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -149,9 +169,10 @@ export function hasChannelPermissions(
|
||||
return botHasPermission(guild.id, permissions);
|
||||
}
|
||||
|
||||
export function calculatePermissions(permissionBits: number) {
|
||||
export function calculatePermissions(permissionBits: bigint) {
|
||||
return Object.keys(Permissions).filter((perm) => {
|
||||
return permissionBits & Permissions[perm as Permission];
|
||||
if (typeof perm !== "number") return false;
|
||||
return permissionBits & BigInt(Permissions[perm as Permission]);
|
||||
}) as Permission[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user