push latest to get easier to make new prs

This commit is contained in:
Skillz4Killz
2021-10-30 15:22:01 +00:00
committed by GitHub
parent 37ba129212
commit 3a02c3fa09
12 changed files with 209 additions and 91 deletions

View File

@@ -40,7 +40,9 @@ export function createCache(
executedSlashCommands: new Set(),
} as AsyncCache;
cache.execute = createExecute(cache);
cache.execute = async function () {
throw new Error("Async Cache requires a custom execute function to be implemented.");
};
return cache;
}
@@ -161,25 +163,30 @@ export type CacheExecutor = (
| "DELETE_CHANNELS_FROM_GUILD"
| "DELETE_GUILD_FROM_MEMBER",
options: Record<string, any>
) => Promise<undefined>;
) => Promise<any>;
export function createExecute(cache: Cache | AsyncCache): CacheExecutor {
// @ts-ignore no time to look into these errors now
return async (type, options) => {
if (type === "DELETE_MESSAGES_FROM_CHANNEL") {
await cache.messages.forEach(async (message) => {
// @ts-ignore me smarter than u
if (BigInt(message.channelId) === options.channelId) {
await cache.messages.delete(BigInt(message.id));
}
});
export function createExecute(cache: Cache): CacheExecutor {
return function (type, options) {
switch (type) {
case "DELETE_MESSAGES_FROM_CHANNEL":
cache.messages.forEach((message) => {
if (message.channelId === options.channelId) {
cache.messages.delete(message.id);
}
});
return;
case "BULK_DELETE_MESSAGES":
return options.messageIds
.map((id: bigint) => {
const cached = cache.messages.get(id);
if (!cached) return;
return undefined;
cache.messages.delete(id);
return cached;
})
.filter((m: DiscordenoMessage) => m);
}
// switch type {
// case ""
// }
};
}

View File

@@ -7,12 +7,16 @@ export async function handleMessageDeleteBulk(bot: Bot, data: DiscordGatewayPayl
const payload = data.d as SnakeCasedPropertiesDeep<MessageDeleteBulk>;
const ids = payload.ids.map((id) => bot.transformers.snowflake(id));
const messages = await bot.cache.execute("BULK_DELETE_MESSAGES", { messageIds: ids });
const messages = (await bot.cache.execute("BULK_DELETE_MESSAGES", { messageIds: ids })) || [];
ids.forEach((id) => {
// @ts-ignore let itoh fix cache typings hes the king of typigns and cache
const msg = messages.find((m) => m.id === id);
const message = msg ? bot.transformers.message(bot, msg) : undefined;
const message = msg
? bot.utils.hasProperty(msg, "authorId")
? msg
: bot.transformers.message(bot, msg)
: undefined;
bot.events.messageDelete(
bot,

View File

@@ -3,21 +3,18 @@ import type { Emoji } from "../../types/emojis/emoji.ts";
import type { Bot } from "../../bot.ts";
/** Create an emoji in the server. Emojis and animated emojis have a maximum file size of 256kb. Attempting to upload an emoji larger than this limit will fail and return 400 Bad Request and an error message, but not a JSON status code. If a URL is provided to the image parameter, Discordeno will automatically convert it to a base64 string internally. */
export async function createEmoji(bot: Bot, guildId: bigint, name: string, image: string, options: CreateGuildEmoji) {
export async function createEmoji(bot: Bot, guildId: bigint, options: CreateGuildEmoji) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]);
if (image && !image.startsWith("data:image/")) {
image = await bot.utils.urlToBase64(image);
if (options.image && !options.image.startsWith("data:image/")) {
options.image = await bot.utils.urlToBase64(options.image);
}
const emoji = await bot.rest.runMethod<Emoji>(bot.rest,
const emoji = await bot.rest.runMethod<Emoji>(
bot.rest,
"post",
bot.constants.endpoints.GUILD_EMOJIS(guildId),
{
...options,
name,
image,
}
options
);
return {

View File

@@ -13,7 +13,7 @@ export async function deleteMessages(bot: Bot, channelId: bigint, ids: bigint[],
}
return await bot.rest.runMethod<undefined>(bot.rest, "post", bot.constants.endpoints.CHANNEL_BULK_DELETE(channelId), {
messages: ids.splice(0, 100),
messages: ids.splice(0, 100).map(id => id.toString()),
reason,
});
}

View File

@@ -42,6 +42,7 @@ export function createRequestBody(rest: RestManager, queuedRequest: { request: R
headers["Content-Type"] = "application/json";
}
if (!queuedRequest.payload.body) headers["Content-Length"] = "0";
return {
headers,
body: (queuedRequest.payload.body?.file || JSON.stringify(queuedRequest.payload.body)) as FormData | string,

View File

@@ -53,10 +53,10 @@ export async function processGlobalQueue(rest: RestManager) {
try {
// CUSTOM HANDLER FOR USER TO LOG OR WHATEVER WHENEVER A FETCH IS MADE
rest.debug(`[REST - fetching] ${JSON.stringify(request.payload)}`);
rest.debug(`[REST - fetching] URL: ${request.urlToUse} | ${JSON.stringify(request.payload)}`);
const response = await fetch(request.urlToUse, rest.createRequestBody(rest, request));
rest.debug(`[REST - fetched] ${JSON.stringify(request.payload)}`);
rest.debug(`[REST - fetched] URL: ${request.urlToUse} | ${JSON.stringify(request.payload)}`);
const bucketIdFromHeaders = rest.processRequestHeaders(rest, request.basicURL, response.headers);
// SET THE BUCKET Id IF IT WAS PRESENT
@@ -115,32 +115,13 @@ export async function processGlobalQueue(rest: RestManager) {
// SOMETIMES DISCORD RETURNS AN EMPTY 204 RESPONSE THAT CAN'T BE MADE TO JSON
if (response.status === 204) {
rest.debug(`[REST - FetchSuccess] ${JSON.stringify(request.payload)}`);
rest.debug(`[REST - FetchSuccess] URL: ${request.urlToUse} | ${JSON.stringify(request.payload)}`);
// REMOVE FROM QUEUE
rest.globalQueue.shift();
request.request.respond({ status: 204 });
} else {
// CONVERT THE RESPONSE TO JSON
const json = await response.json();
// IF THE RESPONSE WAS RATE LIMITED, HANDLE ACCORDINGLY
// if (json.retry_after || json.message === "You are being rate limited.") {
// // IF IT HAS MAXED RETRIES SOMETHING SERIOUSLY WRONG. CANCEL OUT.
// if (request.payload.retryCount >= rest.maxRetryCount) {
// rest.eventHandlers.retriesMaxed(request.payload);
// request.request.respond({
// status: 200,
// body: JSON.stringify({
// error: "The request was rate limited and it maxed out the retries limit.",
// }),
// });
// // REMOVE ITEM FROM QUEUE TO PREVENT RETRY
// rest.globalQueue.shift();
// continue;
// }
// // SINCE IT WAS RATELIMITE, RETRY AGAIN
// continue;
// }
rest.debug(`[REST - fetchSuccess] ${JSON.stringify(request.payload)}`);
// REMOVE FROM QUEUE

View File

@@ -5,7 +5,7 @@ export function processRateLimitedPaths(rest: RestManager) {
const now = Date.now();
for (const [key, value] of rest.ratelimitedPaths.entries()) {
rest.debug(`[REST - processRateLimitedPaths] Running forEach loop.`);
rest.debug(`[REST - processRateLimitedPaths] Running for of loop.`);
// IF THE TIME HAS NOT REACHED CANCEL
if (value.resetTimestamp > now) continue;
@@ -18,13 +18,12 @@ export function processRateLimitedPaths(rest: RestManager) {
// ALL PATHS ARE CLEARED CAN CANCEL OUT!
if (!rest.ratelimitedPaths.size) {
rest.processingRateLimitedPaths = false;
return;
} else {
rest.processingRateLimitedPaths = true;
// RECHECK IN 1 SECOND
setTimeout(() => {
rest.debug(`[REST - processRateLimitedPaths] Running setTimeout.`);
processRateLimitedPaths(rest);
rest.processRateLimitedPaths(rest);
}, 1000);
}
}
}

View File

@@ -1,5 +1,5 @@
import { Bot } from "../bot.ts";
import { Interaction } from "../types/mod.ts";
import { ApplicationCommandInteractionData, ButtonData, DiscordInteractionTypes, Interaction, SelectMenuData } from "../types/mod.ts";
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
import { DiscordenoMember, DiscordenoUser } from "./member.ts";
import { DiscordenoMessage } from "./message.ts";
@@ -23,12 +23,12 @@ export function transformInteraction(bot: Bot, payload: SnakeCasedPropertiesDeep
channelId: payload.channel_id ? bot.transformers.snowflake(payload.channel_id) : undefined,
member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId, user.id) : undefined,
// TODO: CamelCase INTERACTION DATA
// @ts-ignore
data: payload.data,
};
}
export interface DiscordenoInteraction
extends Omit<Interaction, "id" | "applicationId" | "guildId" | "channelId" | "member" | "user" | "message"> {
export interface DiscordenoInteraction {
/** Id of the interaction */
id: bigint;
/** Id of the application this interaction is for */
@@ -43,4 +43,12 @@ export interface DiscordenoInteraction
user: DiscordenoUser;
/** For the message the button was attached to */
message?: DiscordenoMessage;
/** The type of interaction */
type: DiscordInteractionTypes;
/** A continuation token for responding to the interaction */
token: string;
/** Read-only property, always `1` */
version: 1;
data?: ApplicationCommandInteractionData | ButtonData | SelectMenuData;
}

View File

@@ -5,5 +5,7 @@ export interface CreateGuildEmoji {
/** The 128x128 emoji image */
image: string;
/** Roles allowed to use this emoji */
roles: bigint[];
}
roles?: bigint[];
/** The reason you are creating this emoji */
reason?: string;
}

View File

@@ -0,0 +1,76 @@
import { Bot } from "../../../src/bot.ts";
import { assertEquals, assertExists } from "../../deps.ts";
import { delayUntil } from "../../utils.ts";
export async function addReactionTest(
bot: Bot,
guildId: bigint,
channelId: bigint,
options: { custom: boolean; single: boolean, ordered: boolean; },
t: Deno.TestContext
) {
const message = await bot.helpers.sendMessage(channelId, "Hello World!");
// Assertions
assertExists(message);
// Delay the execution by 5 seconds to allow MESSAGE_CREATE event to be processed
await delayUntil(10000, () => bot.cache.messages.has(message.id));
if (!bot.cache.messages.has(message.id)) {
throw new Error("The message seemed to be sent but it was not cached.");
}
let emojiId = "❤";
let emojiIds = ["❤", "😃"];
if (options.custom) {
if (options.single) {
emojiId = `<:blamewolf:${
(
await bot.helpers.createEmoji(guildId, {
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
// roles: [],
})
).id
}>`;
} else {
emojiIds = [
`<:blamewolf:${
(
await bot.helpers.createEmoji(guildId, {
name: "blamewolf",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
// roles: [],
})
).id
}>`,
`<:blamewolf2:${
(
await bot.helpers.createEmoji(guildId, {
name: "blamewolf2",
image: "https://cdn.discordapp.com/emojis/814955268123000832.png",
// roles: [],
})
).id
}>`,
];
}
}
let reactions = 0;
bot.events.reactionAdd = function (bot, payload) {
if (payload.messageId !== message.id) return;
reactions++;
};
if (options.single) await bot.helpers.addReaction(message.channelId, message.id, emojiId);
else await bot.helpers.addReactions(message.channelId, message.id, emojiIds, options.ordered);
await delayUntil(10000, () => reactions === (options.single ? 1 : emojiIds.length));
assertEquals(reactions, options.single ? 1 : emojiIds.length);
}

View File

@@ -2,8 +2,8 @@ import { Bot } from "../../../src/bot.ts";
import { assertExists } from "../../deps.ts";
import { delayUntil } from "../../utils.ts";
import { CreateMessage } from "../../../src/types/messages/create_message.ts";
import { DiscordMessageComponentTypes } from "https://raw.githubusercontent.com/discordeno/discordeno/cool-stuff/src/types/messages/components/message_component_types.ts";
import { DiscordButtonStyles } from "https://raw.githubusercontent.com/discordeno/discordeno/cool-stuff/src/types/messages/components/button_styles.ts";
import { DiscordMessageComponentTypes } from "../../../src/types/messages/components/message_component_types.ts";
import { DiscordButtonStyles } from "../../../src/types/messages/components/button_styles.ts";
async function ifItFailsBlameWolf(bot: Bot, channelId: bigint, content: string | CreateMessage) {
const message = await bot.helpers.sendMessage(channelId, content);

View File

@@ -14,6 +14,7 @@ import {
// CONDUCT LOCAL TESTS FIRST BEFORE RUNNING API TEST
import "./local.ts";
import { getMessageTest } from "./helpers/messages/getMessage.ts";
import { addReactionTest } from "./helpers/messages/addReaction.ts";
Deno.test("[Bot] - Starting Tests", async (t) => {
// CHANGE TO TRUE WHEN DEBUGGING SANITIZATION ERRORS
@@ -37,7 +38,7 @@ Deno.test("[Bot] - Starting Tests", async (t) => {
},
// debug: console.log,
}),
intents: ["Guilds", "GuildMessages"],
intents: ["Guilds", "GuildMessages", "GuildMessageReactions"],
cache: {
isAsync: false,
},
@@ -100,13 +101,13 @@ Deno.test("[Bot] - Starting Tests", async (t) => {
},
...sanitizeMode,
}),
t.step({
name: "[message] send message with components",
fn: async (t) => {
await sendMessageWithComponents(bot, channel.id, t);
},
...sanitizeMode,
}),
// t.step({
// name: "[message] send message with components",
// fn: async (t) => {
// await sendMessageWithComponents(bot, channel.id, t);
// },
// ...sanitizeMode,
// }),
t.step({
name: "[message] delete message without a reason",
fn: async (t) => {
@@ -128,27 +129,69 @@ Deno.test("[Bot] - Starting Tests", async (t) => {
},
...sanitizeMode,
}),
t.step({
name: "[message] delete messages with a reason",
fn: async (t) => {
await deleteMessagesWithReasonTest(bot, channel.id, t);
},
...sanitizeMode,
}),
t.step({
name: "[message] fetch a message",
fn: async (t) => {
await getMessageTest(bot, channel.id, t);
},
...sanitizeMode,
}),
t.step({
name: "[message] fetch messages",
fn: async (t) => {
await getMessagesTest(bot, channel.id, t);
},
...sanitizeMode,
}),
// t.step({
// name: "[message] delete messages with a reason",
// fn: async (t) => {
// await deleteMessagesWithReasonTest(bot, channel.id, t);
// },
// ...sanitizeMode,
// }),
// t.step({
// name: "[message] fetch a message",
// fn: async (t) => {
// await getMessageTest(bot, channel.id, t);
// },
// ...sanitizeMode,
// }),
// t.step({
// name: "[message] fetch messages",
// fn: async (t) => {
// await getMessagesTest(bot, channel.id, t);
// },
// ...sanitizeMode,
// }),
// t.step({
// name: "[message] add a reaction",
// fn: async (t) => {
// await addReactionTest(bot, guild.id, channel.id, { custom: false, single: true, ordered: false }, t);
// },
// ...sanitizeMode,
// }),
// t.step({
// name: "[message] add a custom reaction",
// fn: async (t) => {
// await addReactionTest(bot, guild.id, channel.id, { custom: true, single: true, ordered: false }, t);
// },
// ...sanitizeMode,
// }),
// t.step({
// name: "[message] add multiple reactions",
// fn: async (t) => {
// await addReactionTest(bot, guild.id, channel.id, { custom: false, single: false, ordered: false }, t);
// },
// ...sanitizeMode,
// }),
// t.step({
// name: "[message] add multiple custom reactions",
// fn: async (t) => {
// await addReactionTest(bot, guild.id, channel.id, { custom: true, single: false, ordered: false }, t);
// },
// ...sanitizeMode,
// }),
// t.step({
// name: "[message] add multiple reactions in order",
// fn: async (t) => {
// await addReactionTest(bot, guild.id, channel.id, { custom: false, single: false, ordered: true }, t);
// },
// ...sanitizeMode,
// }),
// t.step({
// name: "[message] add multiple custom reactions in order",
// fn: async (t) => {
// await addReactionTest(bot, guild.id, channel.id, { custom: true, single: false, ordered: true }, t);
// },
// ...sanitizeMode,
// }),
]);
});
});