fmt files damn son

This commit is contained in:
ayntee
2021-04-12 23:13:37 +04:00
parent fb42d03944
commit 1cbc1b8f82
45 changed files with 443 additions and 281 deletions

View File

@@ -10,6 +10,7 @@ Discordeno follows [Semantic Versioning](https://semver.org/)
![Lint](https://github.com/discordeno/discordeno/workflows/Lint/badge.svg)
![Test](https://github.com/discordeno/discordeno/workflows/Test/badge.svg)
[![Coverage](https://img.shields.io/codecov/c/gh/discordeno/discordeno)](https://codecov.io/gh/discordeno/discordeno)
## Features
- **Secure & stable**: Discordeno is actively maintained to ensure great

View File

@@ -32,9 +32,13 @@ export async function startBot(config: BotConfig) {
ws.identifyPayload.token = `Bot ${config.token}`;
rest.token = `Bot ${config.token}`;
ws.identifyPayload.intents = config.intents.reduce(
(bits, next) =>
(bits |= typeof next === "string" ? DiscordGatewayIntents[next] : next),
0
(
bits,
next,
) => (bits |= typeof next === "string"
? DiscordGatewayIntents[next]
: next),
0,
);
// Initial API connection to get info about bots connection
@@ -47,9 +51,13 @@ export async function startBot(config: BotConfig) {
proxyWSURL = ws.botGatewayData.url;
identifyPayload.token = config.token;
identifyPayload.intents = config.intents.reduce(
(bits, next) =>
(bits |= typeof next === "string" ? DiscordGatewayIntents[next] : next),
0
(
bits,
next,
) => (bits |= typeof next === "string"
? DiscordGatewayIntents[next]
: next),
0,
);
identifyPayload.shard = [0, ws.botGatewayData.shards];
@@ -95,9 +103,13 @@ export async function startBigBrainBot(data: BigBrainBotConfig) {
}
identifyPayload.intents = data.intents.reduce(
(bits, next) =>
(bits |= typeof next === "string" ? DiscordGatewayIntents[next] : next),
0
(
bits,
next,
) => (bits |= typeof next === "string"
? DiscordGatewayIntents[next]
: next),
0,
);
// PROXY DOESNT NEED US SPAWNING SHARDS

View File

@@ -4,6 +4,6 @@ import { cacheHandlers } from "../../cache.ts";
export function categoryChildren(id: string) {
return cacheHandlers.filter(
"channels",
(channel) => channel.parentId === id
(channel) => channel.parentId === id,
);
}

View File

@@ -12,14 +12,14 @@ export async function createGuild(options: CreateGuild) {
const result = (await rest.runMethod(
"post",
endpoints.GUILDS,
options
options,
)) as DiscordGuild;
const guild = await structures.createDiscordenoGuild(result, 0);
// MANUALLY CACHE THE GUILD
await cacheHandlers.set("guilds", guild.id, guild);
// MANUALLY CACHE THE BOT
await getMember(guild.id, botId)
await getMember(guild.id, botId);
return guild;
}

View File

@@ -73,7 +73,10 @@ export async function editMember(
endpoints.GUILD_MEMBER(guildId, memberId),
options,
) as DiscordGuildMember;
const member = await structures.createDiscordenoMember(snakeKeysToCamelCase(result), guildId);
const member = await structures.createDiscordenoMember(
snakeKeysToCamelCase(result),
guildId,
);
return member;
}

View File

@@ -9,7 +9,7 @@ import { requireBotChannelPermissions } from "../../util/permissions.ts";
/** Edit the message. */
export async function editMessage(
message: Message,
content: string | MessageContent
content: string | MessageContent,
) {
if (message.author.id !== botId) {
throw "You can only edit a message that was sent by the bot.";
@@ -30,7 +30,7 @@ export async function editMessage(
const result = await rest.runMethod(
"patch",
endpoints.CHANNEL_MESSAGE(message.channelId, message.id),
content
content,
);
return structures.createDiscordenoMessage(result as DiscordMessage);

View File

@@ -16,7 +16,7 @@ export async function getMessage(channelId: string, id: string) {
const result = (await rest.runMethod(
"get",
endpoints.CHANNEL_MESSAGE(channelId, id)
endpoints.CHANNEL_MESSAGE(channelId, id),
)) as DiscordMessage;
return structures.createDiscordenoMessage(result);

View File

@@ -7,7 +7,7 @@ import { endpoints } from "../../util/constants.ts";
export async function publishMessage(channelId: string, messageId: string) {
const data = (await rest.runMethod(
"post",
endpoints.CHANNEL_MESSAGE_CROSSPOST(channelId, messageId)
endpoints.CHANNEL_MESSAGE_CROSSPOST(channelId, messageId),
)) as DiscordMessage;
return structures.createDiscordenoMessage(data);

View File

@@ -14,7 +14,7 @@ import { camelKeysToSnakeCase } from "../../util/utils.ts";
/** Send a message to the channel. Requires SEND_MESSAGES permission. */
export async function sendMessage(
channelId: string,
content: string | CreateMessage
content: string | CreateMessage,
) {
if (typeof content === "string") content = { content };
@@ -56,18 +56,18 @@ export async function sendMessage(
if (content.allowedMentions.users?.length) {
if (
content.allowedMentions.parse?.includes(
DiscordAllowedMentionsTypes.UserMentions
DiscordAllowedMentionsTypes.UserMentions,
)
) {
content.allowedMentions.parse = content.allowedMentions.parse.filter(
(p) => p !== "users"
(p) => p !== "users",
);
}
if (content.allowedMentions.users.length > 100) {
content.allowedMentions.users = content.allowedMentions.users.slice(
0,
100
100,
);
}
}
@@ -75,18 +75,18 @@ export async function sendMessage(
if (content.allowedMentions.roles?.length) {
if (
content.allowedMentions.parse?.includes(
DiscordAllowedMentionsTypes.RoleMentions
DiscordAllowedMentionsTypes.RoleMentions,
)
) {
content.allowedMentions.parse = content.allowedMentions.parse.filter(
(p) => p !== "roles"
(p) => p !== "roles",
);
}
if (content.allowedMentions.roles.length > 100) {
content.allowedMentions.roles = content.allowedMentions.roles.slice(
0,
100
100,
);
}
}
@@ -99,14 +99,13 @@ export async function sendMessage(
...content,
...(content.messageReference?.messageId
? {
messageReference: {
...content.messageReference,
failIfNotExists:
content.messageReference.failIfNotExists === true,
},
}
messageReference: {
...content.messageReference,
failIfNotExists: content.messageReference.failIfNotExists === true,
},
}
: {}),
})
}),
)) as DiscordMessage;
return structures.createDiscordenoMessage(result);

View File

@@ -7,7 +7,7 @@ export function editBotStatus(data: Omit<StatusUpdate, "afk" | "since">) {
ws.shards.forEach((shard) => {
eventHandlers.debug?.(
"loop",
`Running forEach loop in editBotStatus function.`
`Running forEach loop in editBotStatus function.`,
);
shard.ws.send(
JSON.stringify({
@@ -17,7 +17,7 @@ export function editBotStatus(data: Omit<StatusUpdate, "afk" | "since">) {
afk: false,
...data,
},
})
}),
);
});
}

View File

@@ -1,5 +1,8 @@
import { rest } from "../../rest/rest.ts";
import { DiscordGetGatewayBot, GetGatewayBot } from "../../types/gateway/get_gateway_bot.ts";
import {
DiscordGetGatewayBot,
GetGatewayBot,
} from "../../types/gateway/get_gateway_bot.ts";
import { endpoints } from "../../util/constants.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";

View File

@@ -13,7 +13,7 @@ export async function getGuildTemplates(guildId: string) {
const templates = (await rest.runMethod(
"get",
endpoints.GUILD_TEMPLATES(guildId)
endpoints.GUILD_TEMPLATES(guildId),
)) as DiscordTemplate[];
return templates.map((template) => structures.createTemplateStruct(template));

View File

@@ -19,7 +19,7 @@ export async function editWebhook(
{
...options,
channel_id: options.channelId,
}
},
);
return snakeKeysToCamelCase<Webhook>(result);

View File

@@ -10,7 +10,7 @@ import { endpoints } from "../../util/constants.ts";
export async function executeWebhook(
webhookId: string,
webhookToken: string,
options: ExecuteWebhook
options: ExecuteWebhook,
) {
if (!options.content && !options.file && !options.embeds) {
throw new Error(Errors.INVALID_WEBHOOK_OPTIONS);
@@ -28,18 +28,18 @@ export async function executeWebhook(
if (options.allowedMentions.users?.length) {
if (
options.allowedMentions.parse.includes(
DiscordAllowedMentionsTypes.UserMentions
DiscordAllowedMentionsTypes.UserMentions,
)
) {
options.allowedMentions.parse = options.allowedMentions.parse.filter(
(p) => p !== "users"
(p) => p !== "users",
);
}
if (options.allowedMentions.users.length > 100) {
options.allowedMentions.users = options.allowedMentions.users.slice(
0,
100
100,
);
}
}
@@ -47,18 +47,18 @@ export async function executeWebhook(
if (options.allowedMentions.roles?.length) {
if (
options.allowedMentions.parse.includes(
DiscordAllowedMentionsTypes.RoleMentions
DiscordAllowedMentionsTypes.RoleMentions,
)
) {
options.allowedMentions.parse = options.allowedMentions.parse.filter(
(p) => p !== "roles"
(p) => p !== "roles",
);
}
if (options.allowedMentions.roles.length > 100) {
options.allowedMentions.roles = options.allowedMentions.roles.slice(
0,
100
100,
);
}
}
@@ -73,7 +73,7 @@ export async function executeWebhook(
...options,
allowed_mentions: options.allowedMentions,
avatar_url: options.avatarUrl,
}
},
);
if (!options.wait) return;

View File

@@ -20,7 +20,7 @@ export function createRequestBody(queuedRequest: {
// IF A REASON IS PROVIDED ENCODE IT IN HEADERS
if (queuedRequest.payload.body?.reason) {
headers["X-Audit-Log-Reason"] = encodeURIComponent(
queuedRequest.payload.body.reason as string
queuedRequest.payload.body.reason as string,
);
}
@@ -30,11 +30,11 @@ export function createRequestBody(queuedRequest: {
form.append(
"file",
(queuedRequest.payload.body.file as FileContent).blob,
(queuedRequest.payload.body.file as FileContent).name
(queuedRequest.payload.body.file as FileContent).name,
);
form.append(
"payload_json",
JSON.stringify({ ...queuedRequest.payload.body, file: undefined })
JSON.stringify({ ...queuedRequest.payload.body, file: undefined }),
);
queuedRequest.payload.body.file = form;
} else if (
@@ -46,8 +46,7 @@ export function createRequestBody(queuedRequest: {
return {
headers,
body:
(queuedRequest.payload.body?.file ||
body: (queuedRequest.payload.body?.file ||
JSON.stringify(queuedRequest.payload.body)) as FormData | string,
method: queuedRequest.request.method.toUpperCase(),
};

View File

@@ -11,14 +11,14 @@ export async function processQueue(id: string) {
while (queue.length) {
rest.eventHandlers.debug?.(
"loop",
"Running while loop in processQueue function."
"Running while loop in processQueue function.",
);
// IF THE BOT IS GLOBALLY RATELIMITED TRY AGAIN
if (rest.globallyRateLimited) {
setTimeout(async () => {
eventHandlers.debug?.(
"loop",
`Running setTimeout in processQueue function.`
`Running setTimeout in processQueue function.`,
);
await processQueue(id);
}, 1000);
@@ -32,7 +32,7 @@ export async function processQueue(id: string) {
const basicURL = rest.simplifyUrl(
queuedRequest.request.url,
queuedRequest.request.method.toUpperCase()
queuedRequest.request.method.toUpperCase(),
);
// IF THIS URL IS STILL RATE LIMITED, TRY AGAIN
@@ -53,18 +53,19 @@ export async function processQueue(id: string) {
// EXECUTE THE REQUEST
// IF THIS IS A GET REQUEST, CHANGE THE BODY TO QUERY PARAMETERS
const query =
queuedRequest.request.method.toUpperCase() === "GET" &&
queuedRequest.payload.body
? Object.entries(queuedRequest.payload.body)
.map(
([key, value]) =>
`${encodeURIComponent(key)}=${encodeURIComponent(
value as string
)}`
)
.join("&")
: "";
const query = queuedRequest.request.method.toUpperCase() === "GET" &&
queuedRequest.payload.body
? Object.entries(queuedRequest.payload.body)
.map(
([key, value]) =>
`${encodeURIComponent(key)}=${
encodeURIComponent(
value as string,
)
}`,
)
.join("&")
: "";
const urlToUse =
queuedRequest.request.method.toUpperCase() === "GET" && query
? `${queuedRequest.request.url}?${query}`
@@ -76,13 +77,13 @@ export async function processQueue(id: string) {
try {
const response = await fetch(
urlToUse,
rest.createRequestBody(queuedRequest)
rest.createRequestBody(queuedRequest),
);
rest.eventHandlers.fetched(queuedRequest.payload);
const bucketIdFromHeaders = rest.processRequestHeaders(
basicURL,
response.headers
response.headers,
);
// SET THE BUCKET Id IF IT WAS PRESENT
if (bucketIdFromHeaders) {

View File

@@ -8,7 +8,7 @@ export function processRateLimitedPaths() {
for (const [key, value] of rest.ratelimitedPaths.entries()) {
rest.eventHandlers.debug?.(
"loop",
`Running forEach loop in process_rate_limited_paths file.`
`Running forEach loop in process_rate_limited_paths file.`,
);
// IF THE TIME HAS NOT REACHED CANCEL
if (value.resetTimestamp > now) return;
@@ -29,7 +29,7 @@ export function processRateLimitedPaths() {
setTimeout(() => {
eventHandlers.debug?.(
"loop",
`Running setTimeout in processRateLimitedPaths function.`
`Running setTimeout in processRateLimitedPaths function.`,
);
processRateLimitedPaths();
}, 1000);

View File

@@ -4,7 +4,7 @@ import { rest, RestPayload, RestRequest } from "./rest.ts";
/** Processes a request and assigns it to a queue or creates a queue if none exists for it. */
export async function processRequest(
request: RestRequest,
payload: RestPayload
payload: RestPayload,
) {
const route = request.url.substring(request.url.indexOf("api/"));
const parts = route.split("/");

View File

@@ -6,7 +6,7 @@ export async function runMethod<T = any>(
url: string,
body?: unknown,
retryCount = 0,
bucketId?: string
bucketId?: string,
): Promise<T> {
rest.eventHandlers.debug?.("requestCreate", {
method,
@@ -52,7 +52,7 @@ export async function runMethod<T = any>(
bucketId,
body: body as Record<string, unknown> | undefined,
retryCount,
}
},
);
});
}

View File

@@ -13,20 +13,21 @@ export function simplifyUrl(url: string, method: string) {
.replace(/\/reactions\/[^/]+/g, "/reactions/skillzPrefersID")
.replace(
/^\/webhooks\/(\d+)\/[A-Za-z0-9-_]{64,}/,
"/webhooks/$1/:itohIsAHoti"
"/webhooks/$1/:itohIsAHoti",
);
// GENERAL /reactions and /reactions/emoji/@me share the buckets
if (route.includes("/reactions"))
if (route.includes("/reactions")) {
route = route.substring(
0,
route.indexOf("/reactions") + "/reactions".length
route.indexOf("/reactions") + "/reactions".length,
);
}
// Delete Messsage endpoint has its own ratelimit
if (method === "DELETE" && route.endsWith("/messages/skillzPrefersID")) {
route = method + route;
}
return route;
}

View File

@@ -50,4 +50,4 @@ export function createTemplateStruct(
export interface DiscordenoTemplate extends Template {
sourceGuild?: DiscordenoGuild;
}
}

View File

@@ -1,4 +1,4 @@
export enum DiscordOverwriteTypes {
ROLE,
MEMBER
ROLE,
MEMBER,
}

View File

@@ -10,28 +10,27 @@ import { PermissionStrings } from "../types/permissions/permission_strings.ts";
async function getCached(
table: "guilds",
key: string | DiscordenoGuild
key: string | DiscordenoGuild,
): Promise<DiscordenoGuild | undefined>;
async function getCached(
table: "channels",
key: string | DiscordenoChannel
key: string | DiscordenoChannel,
): Promise<DiscordenoChannel | undefined>;
async function getCached(
table: "members",
key: string | DiscordenoMember
key: string | DiscordenoMember,
): Promise<DiscordenoMember | undefined>;
async function getCached(
table: "guilds" | "channels" | "members",
key: string | DiscordenoGuild | DiscordenoChannel | DiscordenoMember
key: string | DiscordenoGuild | DiscordenoChannel | DiscordenoMember,
) {
const cached =
typeof key === "string"
? // @ts-ignore TS is wrong here
await cacheHandlers.get(table, key)
: key;
const cached = typeof key === "string"
? // @ts-ignore TS is wrong here
await cacheHandlers.get(table, key)
: key;
if (!cached || typeof cached === "string") {
throw new Error(
Errors[`${table.slice(0, -1).toUpperCase()}_NOT_FOUND` as Errors]
Errors[`${table.slice(0, -1).toUpperCase()}_NOT_FOUND` as Errors],
);
}
@@ -41,7 +40,7 @@ async function getCached(
/** Calculates the permissions this member has in the given guild */
export async function calculateBasePermissions(
guildOrId: string | DiscordenoGuild,
memberOrId: string | DiscordenoMember
memberOrId: string | DiscordenoMember,
) {
const guild = await getCached("guilds", guildOrId);
const member = await getCached("members", memberOrId);
@@ -68,7 +67,7 @@ export async function calculateBasePermissions(
/** Calculates the permissions this member has for the given Channel */
export async function calculateChannelOverwrites(
channelOrId: string | DiscordenoChannel,
memberOrId: string | DiscordenoMember
memberOrId: string | DiscordenoMember,
) {
const channel = await getCached("channels", channelOrId);
@@ -81,12 +80,12 @@ export async function calculateChannelOverwrites(
// Get all the role permissions this member already has
let permissions = BigInt(
await calculateBasePermissions(channel.guildId, member)
await calculateBasePermissions(channel.guildId, member),
);
// First calculate @everyone overwrites since these have the lowest priority
const overwriteEveryone = channel?.permissionOverwrites?.find(
(overwrite) => overwrite.id === (channel as DiscordenoChannel).guildId
(overwrite) => overwrite.id === (channel as DiscordenoChannel).guildId,
);
if (overwriteEveryone) {
// First remove denied permissions since denied < allowed
@@ -113,7 +112,7 @@ export async function calculateChannelOverwrites(
// Third calculate member specific overwrites since these have the highest priority
const overwriteMember = overwrites?.find(
(overwrite) => overwrite.id === (member as DiscordenoMember).id
(overwrite) => overwrite.id === (member as DiscordenoMember).id,
);
if (overwriteMember) {
permissions &= ~BigInt(overwriteMember.deny);
@@ -126,14 +125,15 @@ export async function calculateChannelOverwrites(
/** Checks if the given permission bits are matching the given permissions. `ADMINISTRATOR` always returns `true` */
export function validatePermissions(
permissionBits: string,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
if (BigInt(permissionBits) & 8n) return true;
return permissions.every(
(permission) =>
// Check if permission is in permissionBits
BigInt(permissionBits) & BigInt(DiscordBitwisePermissionFlags[permission])
BigInt(permissionBits) &
BigInt(DiscordBitwisePermissionFlags[permission]),
);
}
@@ -141,7 +141,7 @@ export function validatePermissions(
export async function hasGuildPermissions(
guild: string | DiscordenoGuild,
member: string | DiscordenoMember,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
// First we need the role permission bits this member has
const basePermissions = await calculateBasePermissions(guild, member);
@@ -152,7 +152,7 @@ export async function hasGuildPermissions(
/** Checks if the bot has these permissions in the given guild */
export function botHasGuildPermissions(
guild: string | DiscordenoGuild,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
// Since Bot is a normal member we can use the hasRolePermissions() function
return hasGuildPermissions(guild, botId, permissions);
@@ -162,7 +162,7 @@ export function botHasGuildPermissions(
export async function hasChannelPermissions(
channel: string | DiscordenoChannel,
member: string | DiscordenoMember,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
// First we need the overwrite bits this member has
const channelOverwrites = await calculateChannelOverwrites(channel, member);
@@ -173,7 +173,7 @@ export async function hasChannelPermissions(
/** Checks if the bot has these permissions f0r the given channel */
export function botHasChannelPermissions(
channel: string | DiscordenoChannel,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
// Since Bot is a normal member we can use the hasRolePermissions() function
return hasChannelPermissions(channel, botId, permissions);
@@ -182,7 +182,7 @@ export function botHasChannelPermissions(
/** Returns the permissions that are not in the given permissionBits */
export function missingPermissions(
permissionBits: string,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
if (BigInt(permissionBits) & 8n) return [];
@@ -191,7 +191,7 @@ export function missingPermissions(
!(
BigInt(permissionBits) &
BigInt(DiscordBitwisePermissionFlags[permission])
)
),
);
}
@@ -199,7 +199,7 @@ export function missingPermissions(
export async function getMissingGuildPermissions(
guild: string | DiscordenoGuild,
member: string | DiscordenoMember,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
// First we need the role permissino bits this member has
const permissionBits = await calculateBasePermissions(guild, member);
@@ -211,7 +211,7 @@ export async function getMissingGuildPermissions(
export async function getMissingChannelPermissions(
channel: string | DiscordenoChannel,
member: string | DiscordenoMember,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
// First we need the role permissino bits this member has
const permissionBits = await calculateChannelOverwrites(channel, member);
@@ -223,7 +223,7 @@ export async function getMissingChannelPermissions(
export async function requireGuildPermissions(
guild: string | DiscordenoGuild,
member: string | DiscordenoMember,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
const missing = await getMissingGuildPermissions(guild, member, permissions);
if (missing.length) {
@@ -235,7 +235,7 @@ export async function requireGuildPermissions(
/** Throws an error if the bot does not have all permissions */
export function requireBotGuildPermissions(
guild: string | DiscordenoGuild,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
// Since Bot is a normal member we can use the throwOnMissingGuildPermission() function
return requireGuildPermissions(guild, botId, permissions);
@@ -245,12 +245,12 @@ export function requireBotGuildPermissions(
export async function requireChannelPermissions(
channel: string | DiscordenoChannel,
member: string | DiscordenoMember,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
const missing = await getMissingChannelPermissions(
channel,
member,
permissions
permissions,
);
if (missing.length) {
// If the member is missing a permission throw an Error
@@ -261,7 +261,7 @@ export async function requireChannelPermissions(
/** Throws an error if the bot has not all of the given channel permissions */
export function requireBotChannelPermissions(
channel: string | DiscordenoChannel,
permissions: PermissionStrings[]
permissions: PermissionStrings[],
) {
// Since Bot is a normal member we can use the throwOnMissingChannelPermission() function
return requireChannelPermissions(channel, botId, permissions);
@@ -293,14 +293,16 @@ export function calculateBits(permissions: PermissionStrings[]) {
/** Gets the highest role from the member in this guild */
export async function highestRole(
guildOrId: string | DiscordenoGuild,
memberOrId: string | DiscordenoMember
memberOrId: string | DiscordenoMember,
) {
const guild = await getCached("guilds", guildOrId);
if (!guild) throw new Error(Errors.GUILD_NOT_FOUND);
// Get the roles from the member
const memberRoles = (await getCached("members", memberOrId))?.guilds.get(guild.id)
const memberRoles = (await getCached("members", memberOrId))?.guilds.get(
guild.id,
)
?.roles;
// This member has no roles so the highest one is the @everyone role
if (!memberRoles) return guild.roles.get(guild.id)!;
@@ -331,7 +333,7 @@ export async function highestRole(
export async function higherRolePosition(
guildOrId: string | DiscordenoGuild,
roleId: string,
otherRoleId: string
otherRoleId: string,
) {
const guild = await getCached("guilds", guildOrId);
@@ -353,7 +355,7 @@ export async function higherRolePosition(
export async function isHigherPosition(
guildOrId: string | DiscordenoGuild,
memberId: string,
compareRoleId: string
compareRoleId: string,
) {
const guild = await getCached("guilds", guildOrId);

View File

@@ -27,7 +27,7 @@ export async function handleOnMessage(message: any, shardId: number) {
if (typeof message !== "string") return;
const messageData = JSON.parse(message) as DiscordGatewayPayload;
ws.log("RAW", { shardId, payload: messageData});
ws.log("RAW", { shardId, payload: messageData });
switch (messageData.op) {
case DiscordGatewayOpcodes.Hello:

View File

@@ -11,8 +11,11 @@ export async function resharder() {
if (percentage < ws.reshardPercentage) return;
// Don't have enough identify rate limits to reshard
if (ws.botGatewayData.sessionStartLimit.remaining < ws.botGatewayData.shards)
if (
ws.botGatewayData.sessionStartLimit.remaining < ws.botGatewayData.shards
) {
return;
}
// Begin resharding
ws.maxShards = ws.botGatewayData.shards;

View File

@@ -24,15 +24,19 @@ export async function startGateway(options: StartGatewayOptions) {
setInterval(ws.resharder, 1000 * 60 * 60);
ws.identifyPayload.intents = options.intents.reduce(
(bits, next) =>
(bits |= typeof next === "string" ? DiscordGatewayIntents[next] : next),
0
(
bits,
next,
) => (bits |= typeof next === "string"
? DiscordGatewayIntents[next]
: next),
0,
);
ws.botGatewayData = snakeKeysToCamelCase(
await fetch(`https://discord.com/api/gateway/bot`, {
headers: { Authorization: ws.identifyPayload.token },
}).then((res) => res.json())
}).then((res) => res.json()),
) as GetGatewayBot;
ws.maxShards = options.maxShards || ws.botGatewayData.shards;

View File

@@ -34,7 +34,10 @@ Deno.test({
),
);
// Delay the execution by 5 seconds to allow CHANNEL_CREATE event to be processed
await delayUntil(10000, () => channels.every((c) => cache.channels.has(c.id)));
await delayUntil(
10000,
() => channels.every((c) => cache.channels.has(c.id)),
);
// If every channel is not present in the cache, error out
if (!channels.every((c) => cache.channels.has(c.id))) {

View File

@@ -5,7 +5,7 @@ import { DiscordChannelTypes } from "../../src/types/channels/channel_types.ts";
import { CreateGuildChannel } from "../../src/types/guilds/create_guild_channel.ts";
import { createChannel } from "../../src/helpers/channels/create_channel.ts";
import { delayUntil } from "../util/delay_until.ts";
import { DiscordOverwriteTypes } from "../../src/types/channels/overwrite_types.ts"
import { DiscordOverwriteTypes } from "../../src/types/channels/overwrite_types.ts";
import { botId } from "../../src/bot.ts";
async function ifItFailsBlameWolf(options: CreateGuildChannel, save = false) {
@@ -26,19 +26,22 @@ async function ifItFailsBlameWolf(options: CreateGuildChannel, save = false) {
if (options.topic && channel.topic !== options.topic) {
throw new Error(
"The channel was supposed to have a topic but it does not appear to be the same topic."
"The channel was supposed to have a topic but it does not appear to be the same topic.",
);
}
if (options.bitrate && channel.bitrate !== options.bitrate) {
throw new Error(
"The channel was supposed to have a bitrate but it does not appear to be the same bitrate."
"The channel was supposed to have a bitrate but it does not appear to be the same bitrate.",
);
}
if (options.permissionOverwrites && channel.permissionOverwrites.length !== options.permissionOverwrites.length) {
if (
options.permissionOverwrites &&
channel.permissionOverwrites.length !== options.permissionOverwrites.length
) {
throw new Error(
"The channel was supposed to have a permissionOverwrites but it does not appear to be the same permissionOverwrites."
"The channel was supposed to have a permissionOverwrites but it does not appear to be the same permissionOverwrites.",
);
}
}
@@ -59,7 +62,7 @@ Deno.test({
name: "Discordeno-test",
type: DiscordChannelTypes.GUILD_CATEGORY,
},
true
true,
);
},
...defaultTestOptions,
@@ -89,7 +92,7 @@ Deno.test({
name: "Discordeno-test",
type: DiscordChannelTypes.GUILD_VOICE,
},
true
true,
);
},
...defaultTestOptions,
@@ -104,7 +107,7 @@ Deno.test({
type: DiscordChannelTypes.GUILD_VOICE,
bitrate: 32000,
},
true
true,
);
},
...defaultTestOptions,
@@ -119,7 +122,7 @@ Deno.test({
type: DiscordChannelTypes.GUILD_VOICE,
userLimit: 32,
},
true
true,
);
},
...defaultTestOptions,
@@ -133,7 +136,7 @@ Deno.test({
name: "Discordeno-test",
rateLimitPerUser: 2423,
},
true
true,
);
},
...defaultTestOptions,
@@ -162,7 +165,7 @@ Deno.test({
},
],
},
true
true,
);
},
...defaultTestOptions,

View File

@@ -5,7 +5,7 @@ import { DiscordChannelTypes } from "../../src/types/channels/channel_types.ts";
import { CreateGuildChannel } from "../../src/types/guilds/create_guild_channel.ts";
import { createChannel } from "../../src/helpers/channels/create_channel.ts";
import { delayUntil } from "../util/delay_until.ts";
import { DiscordOverwriteTypes } from "../../src/types/channels/overwrite_types.ts"
import { DiscordOverwriteTypes } from "../../src/types/channels/overwrite_types.ts";
import { botId } from "../../src/bot.ts";
import { deleteChannelOverwrite } from "../../src/helpers/channels/delete_channel_overwrite.ts";
@@ -23,19 +23,25 @@ async function ifItFailsBlameWolf(options: CreateGuildChannel, save = false) {
throw new Error("The channel seemed to be created but it was not cached.");
}
if (options.permissionOverwrites && channel.permissionOverwrites.length !== options.permissionOverwrites.length) {
if (
options.permissionOverwrites &&
channel.permissionOverwrites.length !== options.permissionOverwrites.length
) {
throw new Error(
"The channel was supposed to have a permissionOverwrites but it does not appear to be the same permissionOverwrites."
"The channel was supposed to have a permissionOverwrites but it does not appear to be the same permissionOverwrites.",
);
}
await deleteChannelOverwrite(channel.guildId, channel.id, botId);
await delayUntil(10000, () => cache.channels.get(channel.id)?.permissionOverwrites?.length === 0);
await delayUntil(
10000,
() => cache.channels.get(channel.id)?.permissionOverwrites?.length === 0,
);
if (cache.channels.get(channel.id)?.permissionOverwrites?.length !== 0) {
throw new Error(
"The channel permission overwrite was supposed to be deleted but it does not appear to be."
"The channel permission overwrite was supposed to be deleted but it does not appear to be.",
);
}
}
@@ -55,7 +61,7 @@ Deno.test({
},
],
},
true
true,
);
},
...defaultTestOptions,

View File

@@ -1,5 +1,5 @@
import { defaultTestOptions, tempData } from "../ws/start_bot.ts";
import {assertEquals, assertExists} from "../deps.ts";
import { assertEquals, assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { createEmoji } from "../../src/helpers/emojis/create_emoji.ts";
import { delayUntil } from "../util/delay_until.ts";
@@ -8,21 +8,27 @@ Deno.test({
name: "[emoji] create an emoji",
async fn() {
const emoji = await createEmoji(
tempData.guildId,
"blamewolf",
"https://cdn.discordapp.com/emojis/814955268123000832.png",
{
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
roles: [],
}
tempData.guildId,
"blamewolf",
"https://cdn.discordapp.com/emojis/814955268123000832.png",
{
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
roles: [],
},
);
assertExists(emoji);
assertExists(emoji);
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id),
);
assertEquals(cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id), true)
assertEquals(
cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id),
true,
);
},
...defaultTestOptions,
});

View File

@@ -3,43 +3,52 @@ import { assertEquals, assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { createEmoji } from "../../src/helpers/emojis/create_emoji.ts";
import { delayUntil } from "../util/delay_until.ts";
import {deleteEmoji} from "../../src/helpers/emojis/delete_emoji.ts";
import { deleteEmoji } from "../../src/helpers/emojis/delete_emoji.ts";
async function ifItFailsBlameWolf(reason?: string) {
const emoji = await createEmoji(
tempData.guildId,
"blamewolf",
"https://cdn.discordapp.com/emojis/814955268123000832.png",
{
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
roles: [],
}
);
const emoji = await createEmoji(
tempData.guildId,
"blamewolf",
"https://cdn.discordapp.com/emojis/814955268123000832.png",
{
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
roles: [],
},
);
assertExists(emoji);
assertExists(emoji);
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id),
);
await deleteEmoji(tempData.guildId, emoji.id!, reason);
await deleteEmoji(tempData.guildId, emoji.id!, reason);
await delayUntil(10000, () => !cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id));
await delayUntil(
10000,
() => !cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id),
);
assertEquals(cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id), false)
assertEquals(
cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id),
false,
);
}
Deno.test({
name: "[emoji] delete an emoji without a reason",
async fn() {
await ifItFailsBlameWolf();
await ifItFailsBlameWolf();
},
...defaultTestOptions,
});
Deno.test({
name: "[emoji] delete an emoji with a reason",
async fn() {
await ifItFailsBlameWolf("with a reason");
},
...defaultTestOptions,
name: "[emoji] delete an emoji with a reason",
async fn() {
await ifItFailsBlameWolf("with a reason");
},
...defaultTestOptions,
});

View File

@@ -3,33 +3,44 @@ import { assertEquals, assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { createEmoji } from "../../src/helpers/emojis/create_emoji.ts";
import { delayUntil } from "../util/delay_until.ts";
import {editEmoji} from "../../src/helpers/emojis/edit_emoji.ts";
import { editEmoji } from "../../src/helpers/emojis/edit_emoji.ts";
Deno.test({
name: "[emoji] edit an emoji",
async fn() {
const emoji = await createEmoji(
tempData.guildId,
"blamewolf",
"https://cdn.discordapp.com/emojis/814955268123000832.png",
{
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
roles: [],
}
tempData.guildId,
"blamewolf",
"https://cdn.discordapp.com/emojis/814955268123000832.png",
{
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
roles: [],
},
);
assertExists(emoji);
assertExists(emoji);
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id),
);
await editEmoji(tempData.guildId, emoji.id, {
name: "blamewolf_infinite"
name: "blamewolf_infinite",
});
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.emojis?.get(emoji.id)?.name === "blamewolf_infinite");
await delayUntil(
10000,
() =>
cache.guilds.get(tempData.guildId)?.emojis?.get(emoji.id)?.name ===
"blamewolf_infinite",
);
assertEquals(cache.guilds.get(tempData.guildId)?.emojis?.get(emoji.id)?.name, "blamewolf_infinite")
assertEquals(
cache.guilds.get(tempData.guildId)?.emojis?.get(emoji.id)?.name,
"blamewolf_infinite",
);
},
...defaultTestOptions,
});

View File

@@ -3,33 +3,42 @@ import { assertEquals, assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { createEmoji } from "../../src/helpers/emojis/create_emoji.ts";
import { delayUntil } from "../util/delay_until.ts";
import {getEmoji} from "../../src/helpers/emojis/get_emoji.ts";
import { getEmoji } from "../../src/helpers/emojis/get_emoji.ts";
Deno.test({
name: "[emoji] get an emoji",
async fn() {
const emoji = await createEmoji(
tempData.guildId,
"blamewolf",
"https://cdn.discordapp.com/emojis/814955268123000832.png",
{
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
roles: [],
}
tempData.guildId,
"blamewolf",
"https://cdn.discordapp.com/emojis/814955268123000832.png",
{
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
roles: [],
},
);
assertExists(emoji);
assertExists(emoji);
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id),
);
cache.guilds.get(tempData.guildId)?.emojis?.delete(emoji.id);
cache.guilds.get(tempData.guildId)?.emojis?.delete(emoji.id);
await getEmoji(tempData.guildId, emoji.id!);
await getEmoji(tempData.guildId, emoji.id!);
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id),
);
assertEquals(cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id), true);
assertEquals(
cache.guilds.get(tempData.guildId)?.emojis?.has(emoji.id),
true,
);
},
...defaultTestOptions,
});

View File

@@ -5,15 +5,18 @@ import { delayUntil } from "../util/delay_until.ts";
import { getEmojis } from "../../src/helpers/mod.ts";
Deno.test({
name: "[emoji] get emojis",
async fn() {
cache.guilds.get(tempData.guildId)?.emojis?.clear();
name: "[emoji] get emojis",
async fn() {
cache.guilds.get(tempData.guildId)?.emojis?.clear();
await getEmojis(tempData.guildId);
await getEmojis(tempData.guildId);
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.emojis?.size > 0);
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.emojis?.size > 0,
);
assertEquals(cache.guilds.get(tempData.guildId)?.emojis?.size > 0, true);
},
...defaultTestOptions,
assertEquals(cache.guilds.get(tempData.guildId)?.emojis?.size > 0, true);
},
...defaultTestOptions,
});

View File

@@ -21,7 +21,11 @@ Deno.test({
await delayUntil(10000, () => cache.guilds.has(guild.id));
if (!cache.guilds.has(guild.id)) {
throw new Error(`The guild seemed to be created but it was not cached. ${JSON.stringify(guild)}`);
throw new Error(
`The guild seemed to be created but it was not cached. ${
JSON.stringify(guild)
}`,
);
}
},
...defaultTestOptions,

View File

@@ -33,7 +33,7 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", custom = false) {
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
roles: [],
}
},
)
).id
}>`;
@@ -47,7 +47,7 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", custom = false) {
await delayUntil(
10000,
() => cache.messages.get(message.id)?.reactions?.length === 1
() => cache.messages.get(message.id)?.reactions?.length === 1,
);
assertEquals(
@@ -55,9 +55,9 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", custom = false) {
.get(message.id)
?.reactions?.filter(
(reaction: DiscordReaction) =>
reaction.emoji?.name === (custom ? "blamewolf" : "❤")
reaction.emoji?.name === (custom ? "blamewolf" : "❤"),
).length,
1
1,
);
}

View File

@@ -1,10 +1,13 @@
import { defaultTestOptions, tempData } from "../ws/start_bot.ts";
import {assertEquals, assertExists} from "../deps.ts";
import { assertEquals, assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { sendMessage } from "../../src/helpers/messages/send_message.ts";
import { delayUntil } from "../util/delay_until.ts";
async function ifItFailsBlameWolf(type: "getter" | "raw", content: "string" | "embed" | "reply" = "string") {
async function ifItFailsBlameWolf(
type: "getter" | "raw",
content: "string" | "embed" | "reply" = "string",
) {
const channel = cache.channels.get(tempData.channelId);
assertExists(channel);
@@ -17,8 +20,8 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", content: "string" | "e
title: "Hello, Embed!",
description: "This is an embedded message.",
color: 0x41ebf4,
fields: []
}
fields: [],
},
};
} else if (content === "reply") {
const message = await sendMessage(channel.id, "Test Message");
@@ -31,20 +34,20 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", content: "string" | "e
messageContent = {
content: "Hi",
allowedMentions: {
repliedUser: true
repliedUser: true,
},
messageReference: {
messageId: message.id,
channelId: channel.id,
guildId: tempData.guildId,
failIfNotExists: true
}
}
failIfNotExists: true,
},
};
}
const message = type === "raw"
? await sendMessage(channel.id, messageContent)
: await channel.send(messageContent);
? await sendMessage(channel.id, messageContent)
: await channel.send(messageContent);
// Assertions
assertExists(message);
@@ -57,11 +60,14 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", content: "string" | "e
}
if (content === "string") {
assertEquals(cache.messages.get(message.id)?.content, messageContent)
assertEquals(cache.messages.get(message.id)?.content, messageContent);
} else if (content === "embed") {
assertEquals(cache.messages.get(message.id)?.embeds?.length, 1);
} else {
assertEquals(cache.messages.get(message.id)?.messageReference.messageId, secondMessageId)
assertEquals(
cache.messages.get(message.id)?.messageReference.messageId,
secondMessageId,
);
}
}
@@ -124,14 +130,17 @@ Deno.test({
// Wait few seconds for the channel create event to arrive and cache it
await delayUntil(10000, () => cache.messages.has(message.id));
const reply = await message.reply('Welcome!');
const reply = await message.reply("Welcome!");
await delayUntil(10000, () => cache.messages.has(reply.id));
if (!cache.messages.has(reply.id)) {
throw new Error("The message seemed to be sent but it was not cached.");
}
assertEquals(cache.messages.get(reply.id)?.messageReference.messageId, message.id)
assertEquals(
cache.messages.get(reply.id)?.messageReference.messageId,
message.id,
);
},
...defaultTestOptions,
});

View File

@@ -1,10 +1,10 @@
import { defaultTestOptions, tempData } from "../ws/start_bot.ts";
import {assertEquals, assertExists} from "../deps.ts";
import { assertEquals, assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { delayUntil } from "../util/delay_until.ts";
import {addRole} from "../../src/helpers/roles/add_role.ts";
import {createRole} from "../../src/helpers/roles/create_role.ts";
import {botId} from "../../src/bot.ts";
import { addRole } from "../../src/helpers/roles/add_role.ts";
import { createRole } from "../../src/helpers/roles/create_role.ts";
import { botId } from "../../src/bot.ts";
async function ifItFailsBlameWolf(type: "getter" | "raw", reason?: string) {
const role = await createRole(tempData.guildId, {
@@ -14,7 +14,10 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", reason?: string) {
assertExists(role);
// Delay the execution by 5 seconds to allow GUILD_ROLE_CREATE event to be processed
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.roles.has(role.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.roles.has(role.id),
);
if (!cache.guilds.get(tempData.guildId)?.roles.has(role.id)) {
throw new Error(`The role seemed to be created but it was not cached.`);
@@ -27,15 +30,26 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", reason?: string) {
}
// Delay the execution by 5 seconds to allow GUILD_MEMBER_UPDATE event to be processed
await delayUntil(10000, () => cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(role.id));
await delayUntil(
10000,
() =>
cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(
role.id,
),
);
assertEquals(cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(role.id), true);
assertEquals(
cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(
role.id,
),
true,
);
}
Deno.test({
name: "[role] add a role without a reason",
async fn() {
await ifItFailsBlameWolf("raw")
await ifItFailsBlameWolf("raw");
},
...defaultTestOptions,
});
@@ -43,7 +57,7 @@ Deno.test({
Deno.test({
name: "[role] add a role with a reason",
async fn() {
await ifItFailsBlameWolf("raw", "with a reason")
await ifItFailsBlameWolf("raw", "with a reason");
},
...defaultTestOptions,
});
@@ -51,7 +65,7 @@ Deno.test({
Deno.test({
name: "[role] member.addRole() without a reason",
async fn() {
await ifItFailsBlameWolf("getter")
await ifItFailsBlameWolf("getter");
},
...defaultTestOptions,
});
@@ -59,7 +73,7 @@ Deno.test({
Deno.test({
name: "[role] member.addRole() with a reason",
async fn() {
await ifItFailsBlameWolf("getter", "with a reason")
await ifItFailsBlameWolf("getter", "with a reason");
},
...defaultTestOptions,
});

View File

@@ -1,8 +1,8 @@
import { defaultTestOptions, tempData } from "../ws/start_bot.ts";
import {assertExists} from "../deps.ts";
import { assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { delayUntil } from "../util/delay_until.ts";
import {createRole} from "../../src/helpers/roles/create_role.ts";
import { createRole } from "../../src/helpers/roles/create_role.ts";
async function ifItFailsBlameWolf(reason?: string) {
const role = await createRole(tempData.guildId, {
@@ -12,7 +12,10 @@ async function ifItFailsBlameWolf(reason?: string) {
assertExists(role);
// Delay the execution by 5 seconds to allow GUILD_ROLE_CREATE event to be processed
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.roles.has(role.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.roles.has(role.id),
);
if (!cache.guilds.get(tempData.guildId)?.roles.has(role.id)) {
throw new Error(`The role seemed to be created but it was not cached.`);
@@ -22,7 +25,7 @@ async function ifItFailsBlameWolf(reason?: string) {
Deno.test({
name: "[role] create a role without a reason",
async fn() {
await ifItFailsBlameWolf()
await ifItFailsBlameWolf();
},
...defaultTestOptions,
});
@@ -30,7 +33,7 @@ Deno.test({
Deno.test({
name: "[role] create a role with a reason",
async fn() {
await ifItFailsBlameWolf( "with a reason")
await ifItFailsBlameWolf("with a reason");
},
...defaultTestOptions,
});

View File

@@ -1,9 +1,9 @@
import { defaultTestOptions, tempData } from "../ws/start_bot.ts";
import {assertExists} from "../deps.ts";
import { assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { delayUntil } from "../util/delay_until.ts";
import {createRole} from "../../src/helpers/roles/create_role.ts";
import {deleteRole} from "../../src/helpers/roles/delete_role.ts";
import { createRole } from "../../src/helpers/roles/create_role.ts";
import { deleteRole } from "../../src/helpers/roles/delete_role.ts";
async function ifItFailsBlameWolf(reason?: string) {
const role = await createRole(tempData.guildId, {
@@ -13,7 +13,10 @@ async function ifItFailsBlameWolf(reason?: string) {
assertExists(role);
// Delay the execution by 5 seconds to allow GUILD_ROLE_CREATE event to be processed
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.roles.has(role.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.roles.has(role.id),
);
if (!cache.guilds.get(tempData.guildId)?.roles.has(role.id)) {
throw new Error(`The role seemed to be created but it was not cached.`);
@@ -22,17 +25,22 @@ async function ifItFailsBlameWolf(reason?: string) {
await deleteRole(tempData.guildId, role.id);
// Delay the execution by 5 seconds to allow GUILD_ROLE_CREATE event to be processed
await delayUntil(10000, () => !cache.guilds.get(tempData.guildId)?.roles.has(role.id));
await delayUntil(
10000,
() => !cache.guilds.get(tempData.guildId)?.roles.has(role.id),
);
if (cache.guilds.get(tempData.guildId)?.roles.has(role.id)) {
throw new Error(`The role should have been deleted but it is still in cache.`);
throw new Error(
`The role should have been deleted but it is still in cache.`,
);
}
}
Deno.test({
name: "[role] delete a role without a reason",
async fn() {
await ifItFailsBlameWolf()
await ifItFailsBlameWolf();
},
...defaultTestOptions,
});
@@ -40,7 +48,7 @@ Deno.test({
Deno.test({
name: "[role] delete a role with a reason",
async fn() {
await ifItFailsBlameWolf( "with a reason")
await ifItFailsBlameWolf("with a reason");
},
...defaultTestOptions,
});

View File

@@ -1,9 +1,9 @@
import { defaultTestOptions, tempData } from "../ws/start_bot.ts";
import {assertEquals, assertExists} from "../deps.ts";
import { assertEquals, assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { delayUntil } from "../util/delay_until.ts";
import {createRole} from "../../src/helpers/roles/create_role.ts";
import {editRole} from "../../src/helpers/roles/edit_role.ts";
import { createRole } from "../../src/helpers/roles/create_role.ts";
import { editRole } from "../../src/helpers/roles/edit_role.ts";
Deno.test({
name: "[role] edit a role",
@@ -15,20 +15,32 @@ Deno.test({
assertExists(role);
// Delay the execution by 5 seconds to allow GUILD_ROLE_CREATE event to be processed
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.roles.has(role.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.roles.has(role.id),
);
if (!cache.guilds.get(tempData.guildId)?.roles.has(role.id)) {
throw new Error(`The role seemed to be created but it was not cached.`);
}
await editRole(tempData.guildId, role.id, {
name: "#rememberAyntee"
name: "#rememberAyntee",
});
// Delay the execution by 5 seconds to allow GUILD_ROLE_UPDATE event to be processed
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.roles.get(role.id)?.name === "#rememberAyntee");
await delayUntil(
10000,
() =>
cache.guilds.get(tempData.guildId)?.roles.get(role.id)?.name ===
"#rememberAyntee",
);
assertEquals(cache.guilds.get(tempData.guildId)?.roles.get(role.id)?.name === "#rememberAyntee", true);
assertEquals(
cache.guilds.get(tempData.guildId)?.roles.get(role.id)?.name ===
"#rememberAyntee",
true,
);
},
...defaultTestOptions,
});

View File

@@ -1,9 +1,9 @@
import { defaultTestOptions, tempData } from "../ws/start_bot.ts";
import {assertEquals} from "../deps.ts";
import { assertEquals } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { delayUntil } from "../util/delay_until.ts";
import {botId} from "../../src/bot.ts";
import {getRoles} from "../../src/helpers/roles/get_roles.ts";
import { botId } from "../../src/bot.ts";
import { getRoles } from "../../src/helpers/roles/get_roles.ts";
Deno.test({
name: "[role] get roles",
@@ -12,9 +12,16 @@ Deno.test({
await getRoles(tempData.guildId);
await delayUntil(10000, () => cache.members.get(botId)?.guilds.get(tempData.guildId).roles.length > 0);
await delayUntil(
10000,
() =>
cache.members.get(botId)?.guilds.get(tempData.guildId).roles.length > 0,
);
assertEquals(cache.members.get(botId)?.guilds.get(tempData.guildId).roles.length > 0, true);
assertEquals(
cache.members.get(botId)?.guilds.get(tempData.guildId).roles.length > 0,
true,
);
},
...defaultTestOptions,
});

View File

@@ -1,11 +1,11 @@
import { defaultTestOptions, tempData } from "../ws/start_bot.ts";
import {assertEquals, assertExists} from "../deps.ts";
import { assertEquals, assertExists } from "../deps.ts";
import { cache } from "../../src/cache.ts";
import { delayUntil } from "../util/delay_until.ts";
import {addRole} from "../../src/helpers/roles/add_role.ts";
import {createRole} from "../../src/helpers/roles/create_role.ts";
import {botId} from "../../src/bot.ts";
import {removeRole} from "../../src/helpers/roles/remove_role.ts";
import { addRole } from "../../src/helpers/roles/add_role.ts";
import { createRole } from "../../src/helpers/roles/create_role.ts";
import { botId } from "../../src/bot.ts";
import { removeRole } from "../../src/helpers/roles/remove_role.ts";
async function ifItFailsBlameWolf(type: "getter" | "raw", reason?: string) {
const role = await createRole(tempData.guildId, {
@@ -15,7 +15,10 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", reason?: string) {
assertExists(role);
// Delay the execution by 5 seconds to allow GUILD_ROLE_CREATE event to be processed
await delayUntil(10000, () => cache.guilds.get(tempData.guildId)?.roles.has(role.id));
await delayUntil(
10000,
() => cache.guilds.get(tempData.guildId)?.roles.has(role.id),
);
if (!cache.guilds.get(tempData.guildId)?.roles.has(role.id)) {
throw new Error(`The role seemed to be created but it was not cached.`);
@@ -28,24 +31,45 @@ async function ifItFailsBlameWolf(type: "getter" | "raw", reason?: string) {
}
// Delay the execution by 5 seconds to allow GUILD_MEMBER_UPDATE event to be processed
await delayUntil(10000, () => cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(role.id));
await delayUntil(
10000,
() =>
cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(
role.id,
),
);
if (type === "raw") {
await removeRole(tempData.guildId, botId, role.id, reason);
} else {
await cache.members.get(botId).removeRole(tempData.guildId, role.id, reason);
await cache.members.get(botId).removeRole(
tempData.guildId,
role.id,
reason,
);
}
// Delay the execution by 5 seconds to allow GUILD_MEMBER_UPDATE event to be processed
await delayUntil(10000, () => !cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(role.id));
await delayUntil(
10000,
() =>
!cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(
role.id,
),
);
assertEquals(cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(role.id), false);
assertEquals(
cache.members.get(botId)?.guilds.get(tempData.guildId).roles.includes(
role.id,
),
false,
);
}
Deno.test({
name: "[role] remove a role without a reason",
async fn() {
await ifItFailsBlameWolf("raw")
await ifItFailsBlameWolf("raw");
},
...defaultTestOptions,
});
@@ -53,7 +77,7 @@ Deno.test({
Deno.test({
name: "[role] remove a role with a reason",
async fn() {
await ifItFailsBlameWolf("raw", "with a reason")
await ifItFailsBlameWolf("raw", "with a reason");
},
...defaultTestOptions,
});
@@ -61,7 +85,7 @@ Deno.test({
Deno.test({
name: "[role] member.removeRole() without a reason",
async fn() {
await ifItFailsBlameWolf("getter")
await ifItFailsBlameWolf("getter");
},
...defaultTestOptions,
});
@@ -69,7 +93,7 @@ Deno.test({
Deno.test({
name: "[role] member.removeRole() with a reason",
async fn() {
await ifItFailsBlameWolf("getter", "with a reason")
await ifItFailsBlameWolf("getter", "with a reason");
},
...defaultTestOptions,
});

View File

@@ -1,11 +1,14 @@
export async function delayUntil(maxMs: number, isReady: () => boolean, timeoutTime= 100): Promise<void> {
export async function delayUntil(
maxMs: number,
isReady: () => boolean,
timeoutTime = 100,
): Promise<void> {
const maxTime = Date.now() + maxMs;
function hackyFix(resolve: () => void) {
if (isReady() || Date.now() >= maxTime) {
resolve();
}
else {
} else {
setTimeout(async () => {
await hackyFix(resolve);
resolve();
@@ -13,5 +16,5 @@ export async function delayUntil(maxMs: number, isReady: () => boolean, timeoutT
}
}
return new Promise(resolve => hackyFix(resolve));
return new Promise((resolve) => hackyFix(resolve));
}

View File

@@ -4,7 +4,7 @@ import { deleteServer } from "../../src/helpers/guilds/delete_server.ts";
import { delay } from "../../src/util/utils.ts";
import { ws } from "../../src/ws/ws.ts";
import { assertExists } from "../deps.ts";
import {delayUntil} from "../util/delay_until.ts";
import { delayUntil } from "../util/delay_until.ts";
// Set necessary settings
// Disables the logger which logs everything