tris lovely typos

This commit is contained in:
Skillz4Killz
2021-10-25 18:35:39 +00:00
committed by GitHub
parent 4d33e1f68b
commit a42ca52c06
102 changed files with 331 additions and 277 deletions

1
mod.ts
View File

@@ -1,5 +1,4 @@
export * from "./src/bot.ts";
export * from "./src/cache.ts";
export * from "./src/handlers/mod.ts";
export * from "./src/helpers/mod.ts";
export * from "./src/rest/mod.ts";

View File

@@ -13,6 +13,10 @@ import {
higherRolePosition,
requireBotChannelPermissions,
requireBotGuildPermissions,
botHasChannelPermissions,
calculateBits,
isHigherPosition,
requireOverwritePermissions,
} from "./util/permissions.ts";
import {
checkRateLimits,
@@ -45,6 +49,7 @@ import {
DiscordenoVoiceState,
transformVoiceState,
DiscordenoMessage,
DiscordenoRole,
} from "./transformers/mod.ts";
import {
baseEndpoints,
@@ -74,7 +79,15 @@ import {
processGatewayQueue,
} from "./ws/mod.ts";
import { validateLength } from "./util/validate_length.ts";
import { delay, validateComponents, validateSlashOptionChoices, validateSlashOptions } from "./util/utils.ts";
import {
delay,
formatImageURL,
hasProperty,
validateComponents,
validateSlashCommands,
validateSlashOptionChoices,
validateSlashOptions,
} from "./util/utils.ts";
import { iconBigintToHash, iconHashToBigInt } from "./util/hash.ts";
import { calculateShardId } from "./util/calculate_shard_id.ts";
import {
@@ -296,6 +309,8 @@ import { DiscordenoEmoji, transformEmoji } from "./transformers/emoji.ts";
import { transformActivity } from "./transformers/activity.ts";
import { DiscordenoPresence, transformPresence } from "./transformers/presence.ts";
import { DiscordReady } from "./types/gateway/ready.ts";
import { urlToBase64 } from "./util/url_to_base64.ts";
import { transformAttachment } from "./transformers/attachment.ts";
export function createBot(options: CreateBotOptions) {
return {
@@ -312,6 +327,7 @@ export function createBot(options: CreateBotOptions) {
cache: {
execute: async function (
type:
| "FILTER_CATEGORY_CHILDREN_CHANNELS"
| "DELETE_MESSAGES_FROM_CHANNEL"
| "DELETE_ROLE_FROM_MEMBER"
| "BULK_DELETE_MESSAGES"
@@ -323,6 +339,7 @@ export function createBot(options: CreateBotOptions) {
| "DELETE_GUILD_FROM_MEMBER",
options: Record<string, any>
) {},
executedSlashCommands: new Set<string>(),
fetchAllMembersProcessingRequests: new Collection<string, Function>(),
messages: {
get: async function (id: bigint): Promise<DiscordenoMessage | undefined> {
@@ -351,6 +368,9 @@ export function createBot(options: CreateBotOptions) {
delete: async function (id: bigint): Promise<void> {
return;
},
size: async function (): Promise<number> {
return 0;
},
},
channels: {
get: async function (id: bigint): Promise<DiscordenoChannel | undefined> {
@@ -473,6 +493,12 @@ export function createEventHandlers(events: Partial<EventHandlers>): EventHandle
stageInstanceCreate: events.stageInstanceCreate ?? ignore,
stageInstanceDelete: events.stageInstanceDelete ?? ignore,
stageInstanceUpdate: events.stageInstanceUpdate ?? ignore,
roleCreate: events.roleCreate ?? ignore,
roleDelete: events.roleDelete ?? ignore,
roleUpdate: events.roleUpdate ?? ignore,
webhooksUpdate: events.webhooksUpdate ?? ignore,
botUpdate: events.botUpdate ?? ignore,
typingStart: events.typingStart ?? ignore,
};
}
@@ -599,6 +625,14 @@ export function createUtils(options: Partial<HelperUtils>) {
requireBotChannelPermissions,
requireBotGuildPermissions,
validateComponents,
hasProperty,
urlToBase64,
botHasChannelPermissions,
calculateBits,
isHigherPosition,
formatImageURL,
validateSlashCommands,
requireOverwritePermissions,
};
}
@@ -626,7 +660,15 @@ export interface HelperUtils {
validateSlashOptionChoices: typeof validateSlashOptionChoices;
requireBotChannelPermissions: typeof requireBotChannelPermissions;
requireBotGuildPermissions: typeof requireBotGuildPermissions;
botHasChannelPermissions: typeof botHasChannelPermissions;
validateComponents: typeof validateComponents;
hasProperty: typeof hasProperty;
urlToBase64: typeof urlToBase64;
calculateBits: typeof calculateBits;
isHigherPosition: typeof isHigherPosition;
formatImageURL: typeof formatImageURL;
validateSlashCommands: typeof validateSlashCommands;
requireOverwritePermissions: typeof requireOverwritePermissions;
}
export function createGatewayManager(
@@ -691,7 +733,7 @@ export async function stopBot(bot: Bot) {
bot.gateway.closeWS(shard.ws, 3061, "Discordeno Testing Finished! Do Not RESUME!");
});
await delay(3000);
await delay(5000);
}
export interface CreateBotOptions {
@@ -1055,12 +1097,14 @@ export interface Transformers {
emoji: typeof transformEmoji;
activity: typeof transformActivity;
presence: typeof transformPresence;
attachment: typeof transformAttachment;
}
export function createTransformers(options: Partial<Transformers>) {
return {
activity: options.activity || transformActivity,
application: options.application || transformApplication,
attachment: options.attachment || transformAttachment,
channel: options.channel || transformChannel,
emoji: options.emoji || transformEmoji,
guild: options.guild || transformGuild,
@@ -1322,6 +1366,21 @@ export interface EventHandlers {
guildDelete: (bot: Bot, id: bigint, guild?: DiscordenoGuild) => any;
guildUpdate: (bot: Bot, guild: DiscordenoGuild, cachedGuild?: DiscordenoGuild) => any;
raw: (bot: Bot, data: GatewayPayload, shardId: number) => any;
roleCreate: (bot: Bot, guild: DiscordenoGuild, role: DiscordenoRole) => any;
roleDelete: (bot: Bot, guild: DiscordenoGuild, role: DiscordenoRole) => any;
roleUpdate: (bot: Bot, guild: DiscordenoGuild, role: DiscordenoRole, oldRole?: DiscordenoRole) => any;
webhooksUpdate: (bot: Bot, payload: { channelId: bigint; guildId: bigint }) => any;
botUpdate: (bot: Bot, user: DiscordenoUser) => any;
typingStart: (
bot: Bot,
payload: {
guildId: bigint | undefined;
channelId: bigint;
userId: bigint;
timestamp: number;
member: DiscordenoMember | undefined;
}
) => any;
}
export function createBotConstants() {

View File

@@ -4,7 +4,7 @@ import type { IntegrationCreateUpdate } from "../../types/integrations/integrati
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export function handleIntegrationUpdate(bot: Bot, data: DiscordGatewayPayload) {
bot.events.integrationsUpdate(
bot.events.integrationUpdate(
bot,
bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep<IntegrationCreateUpdate>)
);

View File

@@ -3,7 +3,6 @@ import { Bot } from "../../bot.ts";
/** Gets an array of all the channels ids that are the children of this category.
* ⚠️ This does not work for custom cache users!
*/
export function categoryChildren(bot: Bot, parentChannelId: bigint) {
// TODO: Cache Filter ?
return bot.cache.channels.filter((channel) => channel.parentId === parentChannelId);
export async function categoryChildren(bot: Bot, parentChannelId: bigint) {
return await bot.cache.execute("FILTER_CATEGORY_CHILDREN_CHANNELS", { parentChannelId });
}

View File

@@ -37,8 +37,8 @@ export async function createChannel(bot: Bot, guildId: bigint, options?: CreateG
: {}
);
const discordenoChannel = bot.transformers.channel(result);
await bot.cache.channels.set(discordenoChannel.id, discordenoChannel);
const channel = bot.transformers.channel(bot, { channel: result, guildId });
await bot.cache.channels.set(channel.id, channel);
return discordenoChannel;
return channel;
}

View File

@@ -2,10 +2,10 @@ import type { Bot } from "../../bot.ts";
/** Delete a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */
export async function deleteChannel(bot: Bot, channelId: bigint, reason?: string) {
const channel = await cacheHandlers.get("channels", channelId);
const channel = await bot.cache.channels.get(channelId);
if (channel?.guildId) {
const guild = await cacheHandlers.get("guilds", channel.guildId);
const guild = await bot.cache.guilds.get(channel.guildId);
if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND);
if (guild.rulesChannelId === channelId) {

View File

@@ -1,7 +1,6 @@
import type { Channel } from "../../types/channels/channel.ts";
import type { ModifyChannel } from "../../types/channels/modify_channel.ts";
import type { Bot } from "../../bot.ts";
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
import { DiscordenoChannel } from "../../transformers/channel.ts";
/** Update a channel's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */
@@ -40,34 +39,29 @@ export async function editChannel(bot: Bot, channelId: bigint, options: ModifyCh
}
}
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Channel>>(
bot.rest,
"patch",
bot.constants.endpoints.CHANNEL_BASE(channelId),
{
name: options.name,
topic: options.topic,
bitrate: options.bitrate,
userLimit: options.userLimit,
rateLimitPerUser: options.rateLimitPerUser,
position: options.position,
parentId: options.parentId,
nsfw: options.nsfw,
type: options.type,
permissionOverwrites: options.permissionOverwrites
? options.permissionOverwrites?.map((overwrite) => {
return {
...overwrite,
allow: calculateBits(overwrite.allow),
deny: calculateBits(overwrite.deny),
};
})
: undefined,
reason,
}
);
const result = await bot.rest.runMethod<Channel>(bot.rest, "patch", bot.constants.endpoints.CHANNEL_BASE(channelId), {
name: options.name,
topic: options.topic,
bitrate: options.bitrate,
userLimit: options.userLimit,
rateLimitPerUser: options.rateLimitPerUser,
position: options.position,
parentId: options.parentId,
nsfw: options.nsfw,
type: options.type,
permissionOverwrites: options.permissionOverwrites
? options.permissionOverwrites?.map((overwrite) => {
return {
...overwrite,
allow: bot.utils.calculateBits(overwrite.allow),
deny: bot.utils.calculateBits(overwrite.deny),
};
})
: undefined,
reason,
});
return bot.transformers.channel(result);
return bot.transformers.channel(bot, { channel: result, guildId: bot.transformers.snowflake(result.guild_id!) });
}
interface EditChannelRequest {
@@ -91,7 +85,7 @@ function processEditChannelQueue(bot: Bot) {
const now = Date.now();
editChannelNameTopicQueue.forEach(async (request) => {
eventHandlers.debug?.("loop", `Running forEach loop in edit_channel file.`);
bot.events.debug(`Running forEach loop in edit_channel file.`);
if (now < request.timestamp) return;
// 10 minutes have passed so we can reset this channel again
if (!request.items.length) {
@@ -119,7 +113,7 @@ function processEditChannelQueue(bot: Bot) {
if (editChannelNameTopicQueue.size) {
setTimeout(() => {
eventHandlers.debug?.("loop", `Running setTimeout in EDIT_CHANNEL file.`);
bot.events.debug(`Running setTimeout in EDIT_CHANNEL file.`);
processEditChannelQueue(bot);
}, 60000);
} else {

View File

@@ -14,5 +14,5 @@ export async function followChannel(bot: Bot, sourceChannelId: bigint, targetCha
}
);
return data.webhookId;
return bot.transformers.snowflake(data.webhook_id);
}

View File

@@ -8,9 +8,9 @@ import type { Channel } from "../../types/channels/channel.ts";
export async function getChannel(bot: Bot, channelId: bigint, addToCache = true) {
const result = await bot.rest.runMethod<Channel>(bot.rest, "get", bot.constants.endpoints.CHANNEL_BASE(channelId));
const discordenoChannel = bot.transformers.channel({
const discordenoChannel = bot.transformers.channel(bot, {
channel: result,
guildId: result.guildId ? bot.transformers.snowflake(result.guildId) : undefined,
guildId: result.guild_id ? bot.transformers.snowflake(result.guild_id) : undefined,
});
if (addToCache) {
await bot.cache.channels.set(discordenoChannel.id, discordenoChannel);

View File

@@ -13,12 +13,12 @@ export async function getChannels(bot: Bot, guildId: bigint, addToCache = true)
(
await Promise.all(
result.map(async (res) => {
const discordenoChannel = await bot.transformers.channel({ channel: res, guildId });
const channel = bot.transformers.channel(bot, { channel: res, guildId });
if (addToCache) {
await bot.cache.channels.set(discordenoChannel.id, discordenoChannel);
await bot.cache.channels.set(channel.id, channel);
}
return discordenoChannel;
return channel;
})
)
).map((c) => [c.id, c])

View File

@@ -5,5 +5,5 @@ import type { Bot } from "../../bot.ts";
export async function getPins(bot: Bot, channelId: bigint) {
const result = await bot.rest.runMethod<Message[]>(bot.rest, "get", bot.constants.endpoints.CHANNEL_PINS(channelId));
return result.map(bot.transformers.message);
return result.map((msg) => bot.transformers.message(bot, msg));
}

View File

@@ -1,4 +1,4 @@
import type { ChannelTypes } from "../../types/channels/channel_types.ts";
import { ChannelTypes } from "../../types/channels/channel_types.ts";
import type { StageInstance } from "../../types/channels/stage_instance.ts";
import type { Bot } from "../../bot.ts";

View File

@@ -23,7 +23,7 @@ export async function startTyping(bot: Bot, channelId: bigint) {
throw new Error(bot.constants.Errors.CHANNEL_NOT_TEXT_BASED);
}
const hasSendMessagesPerm = await bot.utils.botHasChannelPermissions(bots, channelId, ["SEND_MESSAGES"]);
const hasSendMessagesPerm = await bot.utils.botHasChannelPermissions(bot, channelId, ["SEND_MESSAGES"]);
if (!hasSendMessagesPerm) {
throw new Error(bot.constants.Errors.MISSING_SEND_MESSAGES);
}

View File

@@ -2,17 +2,17 @@ import type { Bot } from "../../../bot.ts";
/** Adds a user to a thread. Requires the ability to send messages in the thread. Requires the thread is not archived. */
export async function addToThread(bot: Bot, threadId: bigint, userId: bigint) {
const thread = await bot.cache.threads.get(threadId);
if (thread) {
if (thread.archived) {
throw new Error(bot.constants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
}
// const thread = await bot.cache.threads.get(threadId);
// if (thread) {
// if (thread.archived) {
// throw new Error(bot.constants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
// }
// If a user id is provided SEND_MESSAGES is required.
const channel = await bot.cache.channels.get(thread.parentId);
// TODO: does MANAGE_THREADS override this????
if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]);
}
// // If a user id is provided SEND_MESSAGES is required.
// const channel = await bot.cache.channels.get(thread.parentId);
// // TODO: does MANAGE_THREADS override this????
// if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]);
// }
return await bot.rest.runMethod<undefined>(bot.rest, "put", bot.constants.endpoints.THREAD_USER(threadId, userId));
}

View File

@@ -2,13 +2,13 @@ import type { Bot } from "../../../bot.ts";
/** Delete a thread in your server. Bot needs MANAGE_THREADS permissions in the server. */
export async function deleteThread(bot: Bot, threadId: bigint, reason?: string) {
const thread = await bot.cache.threads.get(threadId);
if (thread) {
const channel = await bot.cache.channels.get(thread?.parentId);
if (channel?.guildId) await bot.utils.requireBotGuildPermissions(bot, channel.guildId, ["MANAGE_THREADS"]);
}
// const thread = await bot.cache.threads.get(threadId);
// if (thread) {
// const channel = await bot.cache.channels.get(thread?.parentId);
// if (channel?.guildId) await bot.utils.requireBotGuildPermissions(bot, channel.guildId, ["MANAGE_THREADS"]);
// }
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.CHANNEL_BASE(threadId), {
reason,
});
// return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.CHANNEL_BASE(threadId), {
// reason,
// });
}

View File

@@ -2,10 +2,10 @@ import type { Bot } from "../../../bot.ts";
/** Adds the bot to the thread. Cannot join an archived thread. */
export async function joinThread(bot: Bot, threadId: bigint) {
const thread = await bot.cache.threads.get(threadId);
if (thread?.archived) {
throw new Error(bot.contants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
}
// const thread = await bot.cache.threads.get(threadId);
// if (thread?.archived) {
// throw new Error(bot.constants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
// }
return await bot.rest.runMethod<undefined>(bot.rest, "put", bot.constants.endpoints.THREAD_ME(threadId));
// return await bot.rest.runMethod<undefined>(bot.rest, "put", bot.constants.endpoints.THREAD_ME(threadId));
}

View File

@@ -2,8 +2,8 @@ import type { Bot } from "../../../bot.ts";
/** Removes the bot from a thread. Requires the thread is not archived. */
export async function leaveThread(bot: Bot, threadId: bigint) {
const thread = await bot.cache.threads.get(threadId);
if (thread?.archived) throw new Error(bot.constants.Errors.CANNOT_LEAVE_ARCHIVED_THREAD);
// const thread = await bot.cache.threads.get(threadId);
// if (thread?.archived) throw new Error(bot.constants.Errors.CANNOT_LEAVE_ARCHIVED_THREAD);
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.THREAD_ME(threadId));
// return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.THREAD_ME(threadId));
}

View File

@@ -2,5 +2,5 @@ import type { Bot } from "../../../bot.ts";
/** Sets a thread channel to be locked. */
export async function lockThread(bot: Bot, threadId: bigint) {
return await bot.utils.editThread(bot, threadId, { locked: true });
// return await bot.utils.editThread(bot, threadId, { locked: true });
}

View File

@@ -2,15 +2,15 @@ import type { Bot } from "../../../bot.ts";
/** Removes a user from a thread. Requires the MANAGE_THREADS permission or that you are the creator of the thread. Also requires the thread is not archived. */
export async function removeThreadMember(bot: Bot, threadId: bigint, userId: bigint) {
const thread = await bot.cache.threads.get(threadId);
if (thread) {
if (thread.archived) throw new Error(bot.constants.Errors.CANNOT_REMOVE_FROM_ARCHIVED_THREAD);
// const thread = await bot.cache.threads.get(threadId);
// if (thread) {
// if (thread.archived) throw new Error(bot.constants.Errors.CANNOT_REMOVE_FROM_ARCHIVED_THREAD);
if (thread.ownerId !== bot.id) {
const channel = await bot.cache.channels.get(thread.parentId);
if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["MANAGE_THREADS"]);
}
}
// if (thread.ownerId !== bot.id) {
// const channel = await bot.cache.channels.get(thread.parentId);
// if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["MANAGE_THREADS"]);
// }
// }
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.THREAD_USER(threadId, userId));
// return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.THREAD_USER(threadId, userId));
}

View File

@@ -1,6 +1,6 @@
import type { StageInstance } from "../../types/channels/stage_instance.ts";
import type { Bot } from "../../bot.ts";
import type { ChannelTypes } from "../../types/channels/channel_types.ts";
import { ChannelTypes } from "../../types/channels/channel_types.ts";
/** Updates fields of an existing Stage instance. Requires the user to be a moderator of the Stage channel. */
export async function updateStageInstance(
@@ -15,7 +15,7 @@ export async function updateStageInstance(
throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE);
}
await bot.utils.requireBotChannelPermissions(channel, ["MOVE_MEMBERS", "MUTE_MEMBERS", "MANAGE_CHANNELS"]);
await bot.utils.requireBotChannelPermissions(bot, channel, ["MOVE_MEMBERS", "MUTE_MEMBERS", "MANAGE_CHANNELS"]);
}
if (

View File

@@ -14,6 +14,7 @@ import type { Bot } from "../../bot.ts";
* - When suppressed, the user will have their `request_to_speak_timestamp` removed.
*/
export async function updateBotVoiceState(
bot: Bot,
guildId: bigint,
options: UpdateSelfVoiceState | ({ userId: bigint } & UpdateOthersVoiceState)
) {
@@ -22,13 +23,13 @@ export async function updateBotVoiceState(
"patch",
bot.constants.endpoints.UPDATE_VOICE_STATE(
guildId,
bot.utils.hasOwnProperty(options, "userId") ? options.userId : undefined
bot.utils.hasProperty(options, "userId") ? options.userId : undefined
),
{
channel_id: options.channelId,
suppress: options.suppress,
request_to_speak_timestamp: options.requestToSpeakTimestamp,
user_id: options.userId,
request_to_speak_timestamp: bot.utils.hasProperty(options, "requestToSpeakTimestamp") ? options.requestToSpeakTimestamp : undefined,
user_id: bot.utils.hasProperty(options, "userId") ? options.userId : undefined
}
);
}

View File

@@ -6,7 +6,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function addDiscoverySubcategory(bot: Bot, guildId: bigint, categoryId: number) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<AddGuildDiscoverySubcategory>>(
return await bot.rest.runMethod<AddGuildDiscoverySubcategory>(
bot.rest,
"post",
bot.constants.endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId)

View File

@@ -7,7 +7,7 @@ import type { Bot } from "../../bot.ts";
export async function editDiscovery(bot: Bot, guildId: bigint, data: ModifyGuildDiscoveryMetadata) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<DiscoveryMetadata>>(
return await bot.rest.runMethod<DiscoveryMetadata>(
bot.rest,
"patch",
bot.constants.endpoints.DISCOVERY_METADATA(guildId),

View File

@@ -6,7 +6,7 @@ import type { Bot } from "../../bot.ts";
export async function getDiscovery(bot: Bot, guildId: bigint) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<DiscoveryMetadata>>(
return await bot.rest.runMethod<DiscoveryMetadata>(
bot.rest,
"get",
bot.constants.endpoints.DISCOVERY_METADATA(guildId)

View File

@@ -5,7 +5,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Returns a Collection (mapped by Id of the discovery category object) of discovery category objects that can be used when editing guilds */
export async function getDiscoveryCategories(bot: Bot) {
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<DiscoveryCategory>[]>(
const result = await bot.rest.runMethod<DiscoveryCategory[]>(
bot.rest,
"get",
bot.constants.endpoints.DISCOVERY_CATEGORIES

View File

@@ -3,7 +3,8 @@ import type { Bot } from "../../bot.ts";
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function validDiscoveryTerm(bot: Bot, term: string) {
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<ValidateDiscoverySearchTerm>>(
const result = await bot.rest.runMethod<ValidateDiscoverySearchTerm>(
bot.rest,
"get",
bot.constants.endpoints.DISCOVERY_VALID_TERM,
{ term }

View File

@@ -1,7 +1,6 @@
import type { CreateGuildEmoji } from "../../types/emojis/create_guild_emoji.ts";
import type { Emoji } from "../../types/emojis/emoji.ts";
import type { Bot } from "../../bot.ts";
import type { SnakeCasedPropertiesDeep } from "../../types/util.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) {
@@ -11,7 +10,7 @@ export async function createEmoji(bot: Bot, guildId: bigint, name: string, image
image = await bot.utils.urlToBase64(image);
}
const emoji = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Emoji>>(
const emoji = await bot.rest.runMethod<Emoji>(bot.rest,
"post",
bot.constants.endpoints.GUILD_EMOJIS(guildId),
{

View File

@@ -1,15 +1,10 @@
import type { Emoji } from "../../types/emojis/emoji.ts";
import type { ModifyGuildEmoji } from "../../types/emojis/modify_guild_emoji.ts";
import type { Bot } from "../../bot.ts";
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Modify the given emoji. Requires the MANAGE_EMOJIS permission. */
export async function editEmoji(bot: Bot, guildId: bigint, id: bigint, options: ModifyGuildEmoji) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]);
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Emoji>>(
"patch",
bot.constants.endpoints.GUILD_EMOJI(guildId, id),
options
);
return await bot.rest.runMethod<Emoji>(bot.rest, "patch", bot.constants.endpoints.GUILD_EMOJI(guildId, id), options);
}

View File

@@ -8,7 +8,7 @@ import type { Bot } from "../../bot.ts";
* ⚠️ **If you need this, you are probably doing something wrong. Always use cache.guilds.get()?.emojis
*/
export async function getEmoji(bot: Bot, guildId: bigint, emojiId: bigint, addToCache = true) {
const result = await bot.rest.runMethod<Emoji>("get", bot.constants.endpoints.GUILD_EMOJI(guildId, emojiId));
const result = await bot.rest.runMethod<Emoji>(bot.rest, "get", bot.constants.endpoints.GUILD_EMOJI(guildId, emojiId));
if (addToCache) {
const guild = await bot.cache.guilds.get(guildId);

View File

@@ -12,11 +12,11 @@ export async function getEmojis(bot: Bot, guildId: bigint, addToCache = true) {
const result = await bot.rest.runMethod<Emoji[]>(bot.rest, "get", bot.constants.endpoints.GUILD_EMOJIS(guildId));
if (addToCache) {
const guild = await bot.cache.guilds.get("guilds", guildId);
const guild = await bot.cache.guilds.get(guildId);
if (!guild) throw new Error(Errors.GUILD_NOT_FOUND);
result.forEach((emoji) => {
bot.events.debug("loop", `Running forEach loop in get_emojis file.`);
bot.events.debug(`Running forEach loop in get_emojis file.`);
guild.emojis.set(bot.transformers.snowflake(emoji.id!), emoji);
});

View File

@@ -23,7 +23,6 @@ export async function editGuild(bot: Bot, guildId: bigint, options: ModifyGuild)
const cached = await bot.cache.guilds.get(guildId);
return bot.transformers.guild(bot, {
guild: result,
shardId:
cached?.shardId || Number((BigInt(result.id) >> 22n % BigInt(bot.gateway.botGatewayData.shards)).toString()),
shardId: cached?.shardId || bot.utils.calculateShardId(bot.gateway, guildId),
});
}

View File

@@ -3,7 +3,7 @@ import type { WelcomeScreen } from "../../types/guilds/welcome_screen.ts";
import type { Bot } from "../../bot.ts";
export async function editWelcomeScreen(bot: Bot, guildId: bigint, options: ModifyGuildWelcomeScreen) {
return await bot.rest.runMethod<WelcomeScreen>("patch", bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId), {
return await bot.rest.runMethod<WelcomeScreen>(bot.rest, "patch", bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId), {
enabled: options.enabled,
welcomeScreen: options.welcomeScreen?.map((welcomeScreen) => {
return {

View File

@@ -7,9 +7,9 @@ export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuild
await bot.utils.requireBotGuildPermissions(bot, guildId, ["VIEW_AUDIT_LOG"]);
return await bot.rest.runMethod<AuditLog>(bot.rest, "get", bot.constants.endpoints.GUILD_AUDIT_LOGS(guildId), {
user_id: options.userId,
action_type: options.actionType,
before: options.before,
user_id: options?.userId,
action_type: options?.actionType,
before: options?.before,
limit: options?.limit && options.limit >= 1 && options.limit <= 100 ? options.limit : 50,
});
}

View File

@@ -22,7 +22,7 @@ export async function getGuild(
const guild = await bot.transformers.guild(bot, {
guild: result,
shardId: Number((BigInt(guildId) >> 22n) % BigInt(ws.botGatewayData.shards)),
shardId: bot.utils.calculateShardId(bot.gateway, guildId),
});
if (options.addToCache) {

View File

@@ -8,7 +8,7 @@ export async function getPruneCount(bot: Bot, guildId: bigint, options?: GetGuil
throw new Error(bot.constants.Errors.PRUNE_MAX_DAYS);
}
await bot.utils.requireBotGuildPermissions(guildId, ["KICK_MEMBERS"]);
await bot.utils.requireBotGuildPermissions(bot, guildId, ["KICK_MEMBERS"]);
const result = await bot.rest.runMethod(
bot.rest,

View File

@@ -3,7 +3,7 @@ import { Collection } from "../../util/collection.ts";
import type { Bot } from "../../bot.ts";
/** Returns a list of voice region objects for the guild. Unlike the similar /voice route, this returns VIP servers when the guild is VIP-enabled. */
export async function getVoiceRegions(boot: Bot, guildId: bigint) {
export async function getVoiceRegions(bot: Bot, guildId: bigint) {
const result = await bot.rest.runMethod<VoiceRegion[]>(
bot.rest,
"get",

View File

@@ -3,7 +3,7 @@ import type { Bot } from "../../bot.ts";
export async function getWelcomeScreen(bot: Bot, guildId: bigint) {
return await bot.rest.runMethod<WelcomeScreen>(
bot.rset,
bot.rest,
"get",
bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId)
);

View File

@@ -4,7 +4,7 @@ import type { Bot } from "../../bot.ts";
/** Returns the widget for the guild. */
export async function getWidget(bot: Bot, guildId: bigint, options?: { force: boolean }) {
if (!options?.force) {
const guild = await bot.cacahe.guilds.get(guildId);
const guild = await bot.cache.guilds.get(guildId);
if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND);
if (!guild?.widgetEnabled) throw new Error(bot.constants.Errors.GUILD_WIDGET_NOT_ENABLED);
}

View File

@@ -3,7 +3,7 @@ import type { Bot } from "../../bot.ts";
/** Returns the guild widget object. Requires the MANAGE_GUILD permission. */
export async function getWidgetSettings(bot: Bot, guildId: bigint) {
await bot.utils.requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]);
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await bot.rest.runMethod<GuildWidget>(bot.rest, "get", bot.constants.endpoints.GUILD_WIDGET(guildId));
}

View File

@@ -17,9 +17,7 @@ export function guildBannerURL(
? bot.utils.formatImageURL(
bot.constants.endpoints.GUILD_BANNER(
id,
typeof options.banner === "string"
? options.banner
: bot.utils.iconBigintToHash(options.banner, options.animated ?? true)
typeof options.banner === "string" ? options.banner : bot.utils.iconBigintToHash(options.banner)
),
options.size || 128,
options.format

View File

@@ -17,9 +17,7 @@ export function guildIconURL(
? bot.utils.formatImageURL(
bot.constants.endpoints.GUILD_ICON(
id,
typeof options.icon === "string"
? options.icon
: bot.utils.iconBigintToHash(options.icon, options.animated ?? true)
typeof options.icon === "string" ? options.icon : bot.utils.iconBigintToHash(options.icon)
),
options.size || 128,
options.format

View File

@@ -19,7 +19,7 @@ export function guildSplashURL(
id,
typeof options.splash === "string"
? options.splash
: bot.utils.iconBigintToHash(options.splash, options.animated ?? true)
: bot.utils.iconBigintToHash(options.splash)
),
options.size || 128,
options.format

View File

@@ -6,7 +6,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function getIntegrations(bot: Bot, guildId: bigint) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Integration>>(
return await bot.rest.runMethod<Integration>(
bot.rest,
"get",
bot.constants.endpoints.GUILD_INTEGRATIONS(guildId)

View File

@@ -14,7 +14,7 @@ import type { Bot } from "../../../bot.ts";
* Guild commands update **instantly**. We recommend you use guild commands for quick testing, and global commands when they're ready for public use.
*/
export async function createSlashCommand(bot: Bot, options: CreateGlobalApplicationCommand, guildId?: bigint) {
[options] = bot.utils.validateSlashCommands([options], true) as CreateGlobalApplicationCommand[];
[options] = bot.utils.validateSlashCommands(bot, [options], true) as CreateGlobalApplicationCommand[];
return await bot.rest.runMethod<ApplicationCommand>(
bot.rest,

View File

@@ -3,7 +3,7 @@ import type { Bot } from "../../../bot.ts";
/** Fetches the global command for the given Id. If a guildId is provided, the guild command will be fetched. */
export async function getSlashCommand(bot: Bot, commandId: bigint, guildId?: bigint) {
const result = await bot.rest.runMethod<ApplicationCommand>(
const result = await bot.rest.runMethod<ApplicationCommand>(bot.rest,
"get",
guildId
? bot.constants.endpoints.COMMANDS_GUILD_ID(bot.applicationId, guildId, commandId)
@@ -13,6 +13,6 @@ export async function getSlashCommand(bot: Bot, commandId: bigint, guildId?: big
return {
...result,
id: bot.transformers.snowflake(result.id),
applicationId: bot.transformers.snowflake(result.applicationId),
applicationId: bot.transformers.snowflake(result.application_id),
};
}

View File

@@ -18,7 +18,7 @@ export async function getSlashCommands(bot: Bot, guildId?: bigint) {
{
...command,
id: bot.transformers.snowflake(command.id),
applicationId: bot.transformers.snowflake(command.applicationId),
applicationId: bot.transformers.snowflake(command.application_id),
},
])
);

View File

@@ -11,7 +11,7 @@ export async function upsertSlashCommand(
options: EditGlobalApplicationCommand,
guildId?: bigint
) {
[options] = bot.utils.validateSlashCommands([options]);
[options] = bot.utils.validateSlashCommands(bot, [options]);
return await bot.rest.runMethod<ApplicationCommand>(
bot.rest,

View File

@@ -13,7 +13,7 @@ export async function upsertSlashCommands(
options: MakeRequired<EditGlobalApplicationCommand, "name">[],
guildId?: bigint
) {
options = bot.utils.validateSlashCommands(options) as MakeRequired<EditGlobalApplicationCommand, "name">[];
options = bot.utils.validateSlashCommands(bot, options) as MakeRequired<EditGlobalApplicationCommand, "name">[];
return await bot.rest.runMethod<ApplicationCommand[]>(
bot.rest,

View File

@@ -4,7 +4,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Returns the initial Interaction response. Functions the same as Get Webhook Message */
export async function getOriginalInteractionResponse(bot: Bot, token: string) {
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
const result = await bot.rest.runMethod<Message>(
bot.rest,
"get",
bot.constants.endpoints.INTERACTION_ORIGINAL_ID_TOKEN(bot.applicationId, token)

View File

@@ -32,28 +32,20 @@ export async function sendInteractionResponse(
options.data = { ...options.data, allowedMentions: { parse: [] } };
}
const allowedMentions: AllowedMentions = options.data?.allowedMentions || { parse: [] };
// If its already been executed, we need to send a followup response
if (bot.cache.executedSlashCommands.has(token)) {
return await bot.rest.runMethod(bot.rest, "post", bot.cosntants.endpoints.WEBHOOK(bot.applicationId, token), {
return await bot.rest.runMethod(bot.rest, "post", bot.constants.endpoints.WEBHOOK(bot.applicationId, token), {
content: options.data.content,
tts: options.data.tts,
embeds: options.data.embeds,
allowed_mentions: {
parse: options.data.allowedMentions.parse,
roles: options.data.allowedMentions.roles,
users: options.data.allowedMentions.users,
replied_user: options.data.allowedMentions.repliedUser,
parse: allowedMentions.parse,
roles: allowedMentions.roles,
users: allowedMentions.users,
replied_user: allowedMentions.repliedUser,
},
...(options.data.messageReference?.messageId
? {
message_reference: {
message_id: options.data.messageReference.messageId,
channel_id: options.data.messageReference.channelId,
guild_id: options.data.messageReference.guildId,
fail_if_not_exists: options.data.messageReference.failIfNotExists === true,
},
}
: {}),
file: options.data.file,
// TODO: Snakelize components??
components: options.data.components,
@@ -62,10 +54,10 @@ export async function sendInteractionResponse(
}
// Expire in 15 minutes
cache.executedSlashCommands.add(token);
bot.cache.executedSlashCommands.add(token);
setTimeout(() => {
eventHandlers.debug?.("loop", `Running setTimeout in send_interaction_response file.`);
cache.executedSlashCommands.delete(token);
bot.events.debug(`Running setTimeout in send_interaction_response file.`);
bot.cache.executedSlashCommands.delete(token);
}, 900000);
return await bot.rest.runMethod(
@@ -77,21 +69,11 @@ export async function sendInteractionResponse(
tts: options.data.tts,
embeds: options.data.embeds,
allowed_mentions: {
parse: options.data.allowedMentions.parse,
roles: options.data.allowedMentions.roles,
users: options.data.allowedMentions.users,
replied_user: options.data.allowedMentions.repliedUser,
parse: allowedMentions.parse,
roles: allowedMentions.roles,
users: allowedMentions.users,
replied_user: allowedMentions.repliedUser,
},
...(options.data.messageReference?.messageId
? {
message_reference: {
message_id: options.data.messageReference.messageId,
channel_id: options.data.messageReference.channelId,
guild_id: options.data.messageReference.guildId,
fail_if_not_exists: options.data.messageReference.failIfNotExists === true,
},
}
: {}),
file: options.data.file,
// TODO: Snakelize components??
components: options.data.components,

View File

@@ -6,7 +6,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Creates a new invite for this channel. Requires CREATE_INSTANT_INVITE */
export async function createInvite(bot: Bot, channelId: bigint, options: CreateChannelInvite = {}) {
await bot.utils.requireBotChannelPermissions(channelId, ["CREATE_INSTANT_INVITE"]);
await bot.utils.requireBotChannelPermissions(bot, channelId, ["CREATE_INSTANT_INVITE"]);
if (options.maxAge && (options.maxAge < 0 || options.maxAge > 604800)) {
throw new Error(Errors.INVITE_MAX_AGE_INVALID);
@@ -15,7 +15,7 @@ export async function createInvite(bot: Bot, channelId: bigint, options: CreateC
throw new Error(Errors.INVITE_MAX_USES_INVALID);
}
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>>(
return await bot.rest.runMethod<InviteMetadata>(
bot.rest,
"post",
bot.constants.endpoints.CHANNEL_INVITES(channelId),

View File

@@ -6,14 +6,14 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function deleteInvite(bot: Bot, channelId: bigint, inviteCode: string) {
const channel = await bot.cache.channels.get(channelId);
if (channel) {
const hasPerm = await bot.utils.botHasChannelPermissions(channel, ["MANAGE_CHANNELS"]);
const hasPerm = await bot.utils.botHasChannelPermissions(bot, channel, ["MANAGE_CHANNELS"]);
if (!hasPerm) {
await bot.utils.requireBotGuildPermissions(channel.guildId, ["MANAGE_GUILD"]);
await bot.utils.requireBotGuildPermissions(bot, channel.guildId, ["MANAGE_GUILD"]);
}
}
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>>(
return await bot.rest.runMethod<InviteMetadata>(
bot.rest,
"delete",
bot.constants.endpoints.INVITE(inviteCode)

View File

@@ -5,9 +5,9 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Gets the invites for this channel. Requires MANAGE_CHANNEL */
export async function getChannelInvites(bot: Bot, channelId: bigint) {
await bot.utils.requireBotChannelPermissions(channelId, ["MANAGE_CHANNELS"]);
await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_CHANNELS"]);
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>[]>(
const result = await bot.rest.runMethod<InviteMetadata[]>(
bot.rest,
"get",
bot.constants.endpoints.CHANNEL_INVITES(channelId)

View File

@@ -5,12 +5,12 @@ import type { Bot } from "../../bot.ts";
/** Returns an invite for the given code or throws an error if the invite doesn't exists. */
export async function getInvite(bot: Bot, inviteCode: string, options?: GetInvite) {
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>>(
return await bot.rest.runMethod<InviteMetadata>(bot.rest,
"get",
bot.constants.endpoints.INVITE(inviteCode),
{
with_counts: options.withCounts,
with_expiration: options.withExpiration,
with_counts: options?.withCounts,
with_expiration: options?.withExpiration,
}
);
}

View File

@@ -7,7 +7,8 @@ import type { Bot } from "../../bot.ts";
export async function getInvites(bot: Bot, guildId: bigint) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<InviteMetadata>[]>(
const result = await bot.rest.runMethod<InviteMetadata[]>(
bot.rest,
"get",
bot.constants.endpoints.GUILD_INVITES(guildId)
);

View File

@@ -20,7 +20,7 @@ export function avatarURL(
userId,
typeof options.avatar === "string"
? options.avatar
: bot.utils.iconBigintToHash(options.avatar, options.animated ?? true)
: bot.utils.iconBigintToHash(options.avatar)
),
options.size || 128,
options.format

View File

@@ -43,7 +43,7 @@ export async function editMember(bot: Bot, guildId: bigint, memberId: bigint, op
await bot.utils.requireBotGuildPermissions(bot, guildId, [...requiredPerms]);
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GuildMemberWithUser>>(
const result = await bot.rest.runMethod<GuildMemberWithUser>(
bot.rest,
"patch",
bot.constants.endpoints.GUILD_MEMBER(guildId, memberId),

View File

@@ -22,9 +22,9 @@ export function fetchMembers(
// You can request 1 member without the intent
// Check if intents is not 0 as proxy ws won't set intents in other instances
if (
bot.gateway.identifyPayload.intents &&
bot.intents &&
(!options?.limit || options.limit > 1) &&
!(bot.gateway.identifyPayload.intents & DiscordGatewayIntents.GuildMembers)
!(bot.intents & DiscordGatewayIntents.GuildMembers)
) {
throw new Error(bot.constants.Errors.MISSING_INTENT_GUILD_MEMBERS);
}
@@ -35,10 +35,9 @@ export function fetchMembers(
return new Promise((resolve) => {
const nonce = `${guildId}-${Date.now()}`;
// TODO: FIND A BETTER WAY TO DO THAT?
cache.fetchAllMembersProcessingRequests.set(nonce, resolve);
bot.cache.fetchAllMembersProcessingRequests.set(nonce, resolve);
bot.gateway.sendShardMessage(shardId, {
bot.gateway.sendShardMessage(bot.gateway, shardId, {
op: DiscordGatewayOpcodes.RequestGuildMembers,
d: {
guild_id: guildId,

View File

@@ -10,7 +10,7 @@ export async function getMember(bot: Bot, guildId: bigint, id: bigint, options?:
const guild = await bot.cache.guilds.get(guildId);
if (!guild && !options?.force) return;
const data = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GuildMemberWithUser>>(
const data = await bot.rest.runMethod<GuildMemberWithUser>(
bot.rest,
"get",
bot.constants.endpoints.GUILD_MEMBER(guildId, id)

View File

@@ -4,7 +4,6 @@ import type { ListGuildMembers } from "../../types/members/list_guild_members.ts
import type { Bot } from "../../bot.ts";
import { Collection } from "../../util/collection.ts";
import type { DiscordenoMember } from "../../transformers/member.ts";
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/**
* ⚠️ BEGINNER DEVS!! YOU SHOULD ALMOST NEVER NEED THIS AND YOU CAN GET FROM cache.members.get()
@@ -17,13 +16,13 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildMembers & { addToCache?: boolean }) {
// Check if intents is not 0 as proxy ws won't set intents in other instances
if (
bot.gateway.identifyPayload.intents &&
!(bot.gateway.identifyPayload.intents & DiscordGatewayIntents.GuildMembers)
bot.intents &&
!(bot.intents & DiscordGatewayIntents.GuildMembers)
) {
throw new Error(bot.cache.Errors.MISSING_INTENT_GUILD_MEMBERS);
throw new Error(bot.constants.Errors.MISSING_INTENT_GUILD_MEMBERS);
}
const guild = await cacheHandlers.get("guilds", guildId);
const guild = await bot.cache.guilds.get(guildId);
if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND);
const members = new Collection<bigint, DiscordenoMember>();
@@ -31,13 +30,13 @@ export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildM
let membersLeft = options?.limit ?? guild.memberCount;
let loops = 1;
while ((options?.limit ?? guild.memberCount) > members.size && membersLeft > 0) {
eventHandlers.debug?.("loop", "Running while loop in getMembers function.");
bot.events.debug("Running while loop in getMembers function.");
if (options?.limit && options.limit > 1000) {
console.log(`Paginating get members from REST. #${loops} / ${Math.ceil((options?.limit ?? 1) / 1000)}`);
}
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GuildMemberWithUser>[]>(
const result = await bot.rest.runMethod<GuildMemberWithUser[]>(
bot.rest,
"get",
`${bot.constants.endpoints.GUILD_MEMBERS(guildId)}?limit=${membersLeft > 1000 ? 1000 : membersLeft}${
@@ -47,7 +46,7 @@ export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildM
const discordenoMembers = await Promise.all(
result.map(async (member) => {
const discordenoMember = bot.transformers.member(member, guildId);
const discordenoMember = bot.transformers.member(bot, member, guildId);
if (options?.addToCache !== false) {
await bot.cache.members.set(discordenoMember.id, discordenoMember);
@@ -60,13 +59,13 @@ export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildM
if (!discordenoMembers.length) break;
discordenoMembers.forEach((member) => {
bot.events.debug("loop", `Running forEach loop in get_members file.`);
bot.events.debug(`Running forEach loop in get_members file.`);
members.set(member.id, member);
});
options = {
limit: options?.limit,
after: bot.transformers.snowflake(discordenoMembers[discordenoMembers.length - 1].id),
after: discordenoMembers[discordenoMembers.length - 1].id.toString(),
};
membersLeft -= 1000;

View File

@@ -1,7 +1,7 @@
import { Bot } from "../../bot.ts";
/** Kick a member from the server */
export async function kick(bot: Bot, guildId: bigint, memberId: bigint, reason?: string) {
const botsHighestRole = await bot.utils.highestRole(bot, guildId, botId);
const botsHighestRole = await bot.utils.highestRole(bot, guildId, bot.id);
const membersHighestRole = await bot.utils.highestRole(bot, guildId, memberId);
if (botsHighestRole && membersHighestRole && botsHighestRole.position <= membersHighestRole.position) {
throw new Error(bot.constants.Errors.BOTS_HIGHEST_ROLE_TOO_LOW);

View File

@@ -25,7 +25,7 @@ export async function searchMembers(
}
}
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GuildMemberWithUser>[]>(
const result = await bot.rest.runMethod<GuildMemberWithUser[]>(
bot.rest,
"get",
bot.constants.endpoints.GUILD_MEMBERS_SEARCH(guildId),

View File

@@ -10,7 +10,7 @@ export async function sendDirectMessage(bot: Bot, memberId: bigint, content: str
let dmChannel = await bot.cache.channels.get(memberId);
if (!dmChannel) {
// If not available in cache create a new one.
const dmChannelData = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Channel>>(
const dmChannelData = await bot.rest.runMethod<Channel>(
bot.rest,
"post",
bot.constants.endpoints.USER_DM,
@@ -25,5 +25,5 @@ export async function sendDirectMessage(bot: Bot, memberId: bigint, content: str
}
// If it does exist try sending a message to this user
return await bot.helpers.sendMessage(dmChannel.id, content);
return await bot.helpers.sendMessage(bot, dmChannel.id, content);
}

View File

@@ -2,7 +2,7 @@ import type { Bot } from "../../bot.ts";
/** Remove the ban for a user. Requires BAN_MEMBERS permission */
export async function unban(bot: Bot, guildId: bigint, id: bigint) {
await bot.utils.requireBotGuildPermissions(guildId, ["BAN_MEMBERS"]);
await bot.utils.requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]);
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.GUILD_BAN(guildId, id));
}

View File

@@ -12,7 +12,7 @@ export async function addReactions(
await Promise.all(reactions.map((reaction) => bot.helpers.addReaction(bot, channelId, messageId, reaction)));
} else {
for (const reaction of reactions) {
bot.events.debug("loop", "Running for of loop in addReactions function.");
bot.events.debug("Running for of loop in addReactions function.");
await bot.helpers.addReaction(bot, channelId, messageId, reaction);
}
}

View File

@@ -30,7 +30,7 @@ export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint
throw new Error(bot.constants.Errors.MESSAGE_MAX_LENGTH);
}
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
const result = await bot.rest.runMethod<Message>(
bot.rest,
"patch",
bot.constants.endpoints.CHANNEL_MESSAGE(channelId, messageId),

View File

@@ -1,7 +1,5 @@
// import { cacheHandlers } from "../../cache.ts";
import type { Message } from "../../types/messages/message.ts";
import type { Bot } from "../../bot.ts";
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Fetch a single message from the server. Requires VIEW_CHANNEL and READ_MESSAGE_HISTORY */
export async function getMessage(bot: Bot, channelId: bigint, id: bigint) {
@@ -9,7 +7,7 @@ export async function getMessage(bot: Bot, channelId: bigint, id: bigint) {
await bot.utils.requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL", "READ_MESSAGE_HISTORY"]);
}
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
const result = await bot.rest.runMethod<Message>(
bot.rest,
"get",
bot.constants.endpoints.CHANNEL_MESSAGE(channelId, id)

View File

@@ -6,7 +6,6 @@ import type {
} from "../../types/messages/get_messages.ts";
import type { Message } from "../../types/messages/message.ts";
import type { Bot } from "../../bot.ts";
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Fetches between 2-100 messages. Requires VIEW_CHANNEL and READ_MESSAGE_HISTORY */
export async function getMessages(
@@ -20,7 +19,7 @@ export async function getMessages(
throw new Error(bot.constants.Errors.INVALID_GET_MESSAGES_LIMIT);
}
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>[]>(
const result = await bot.rest.runMethod<Message[]>(
bot.rest,
"get",
bot.constants.endpoints.CHANNEL_MESSAGES(channelId),

View File

@@ -4,7 +4,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Crosspost a message in a News Channel to following channels. */
export async function publishMessage(bot: Bot, channelId: bigint, messageId: bigint) {
const data = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
const data = await bot.rest.runMethod<Message>(
bot.rest,
"post",
bot.constants.endpoints.CHANNEL_MESSAGE_CROSSPOST(channelId, messageId)

View File

@@ -73,7 +73,7 @@ export async function sendMessage(bot: Bot, channelId: bigint, content: string |
}
}
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
const result = await bot.rest.runMethod<Message>(
bot.rest,
"post",
bot.constants.endpoints.CHANNEL_MESSAGES(channelId),

View File

@@ -9,7 +9,7 @@ export async function suppressEmbeds(bot: Bot, channelId: bigint, messageId: big
await bot.utils.requireBotChannelPermissions(bot, channelId, message ? ["MANAGE_MESSAGES"] : ["SEND_MESSAGES"]);
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
const result = await bot.rest.runMethod<Message>(
bot.rest,
"patch",
bot.constants.endpoints.CHANNEL_MESSAGE(channelId, messageId),

View File

@@ -1,7 +1,6 @@
import { Errors } from "../../types/discordeno/errors.ts";
import type { User } from "../../types/users/user.ts";
import type { Bot } from "../../bot.ts";
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Modifies the bot's username or avatar.
* NOTE: username: if changed may cause the bot's discriminator to be randomized.
@@ -27,7 +26,7 @@ export async function editBotProfile(bot: Bot, options: { username?: string; bot
const avatar = options?.botAvatarURL ? await bot.utils.urlToBase64(options?.botAvatarURL) : options?.botAvatarURL;
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<User>>(bot, "patch", bot.constants.endpoints.USER_BOT, {
return await bot.rest.runMethod<User>(bot.rest, "patch", bot.constants.endpoints.USER_BOT, {
username: options.username?.trim(),
avatar,
});

View File

@@ -3,10 +3,10 @@ import { DiscordGatewayOpcodes } from "../../types/codes/gateway_opcodes.ts";
import type { StatusUpdate } from "../../types/gateway/status_update.ts";
export function editBotStatus(bot: Bot, data: Omit<StatusUpdate, "afk" | "since">) {
bot.ws.shards.forEach((shard) => {
bot.events.debug("loop", `Running forEach loop in editBotStatus function.`);
bot.gateway.shards.forEach((shard) => {
bot.events.debug(`Running forEach loop in editBotStatus function.`);
bot.ws.sendShardMessage(shard, {
bot.gateway.sendShardMessage(bot.gateway, shard, {
op: DiscordGatewayOpcodes.StatusUpdate,
d: {
since: null,

View File

@@ -4,7 +4,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Get the bots Gateway metadata that can help during the operation of large or sharded bots. */
export async function getGatewayBot(bot: Bot): Promise<GetGatewayBot> {
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<GetGatewayBot>>(
const result = await bot.rest.runMethod<GetGatewayBot>(
bot.rest,
"get",
bot.constants.endpoints.GATEWAY_BOT

View File

@@ -4,7 +4,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** This function will return the raw user payload in the rare cases you need to fetch a user directly from the API. */
export async function getUser(bot: Bot, userId: bigint) {
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<User>>(
return await bot.rest.runMethod<User>(
bot.rest,
"get",
bot.constants.endpoints.USER(userId)

View File

@@ -4,7 +4,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Get the applications info */
export async function getApplicationInfo(bot: Bot) {
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Omit<Application, "flags">>>(
return await bot.rest.runMethod<Omit<Application, "flags">>(
bot.rest,
"get",
bot.constants.endpoints.OAUTH2_APPLICATION

View File

@@ -2,7 +2,7 @@ import type { Bot } from "../../bot.ts";
/** Add a role to the member */
export async function addRole(bot: Bot, guildId: bigint, memberId: bigint, roleId: bigint, reason?: string) {
const isHigherRolePosition = await bot.utils.isHigherPosition(guildId, bot.id, roleId);
const isHigherRolePosition = await bot.utils.isHigherPosition(bot, guildId, bot.id, roleId);
if (!isHigherRolePosition) {
throw new Error(bot.constants.Errors.BOTS_HIGHEST_ROLE_TOO_LOW);
}

View File

@@ -7,7 +7,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function createRole(bot: Bot, guildId: bigint, options: CreateGuildRole, reason?: string) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]);
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Role>>(
const result = await bot.rest.runMethod<Role>(bot.rest,
"post",
bot.constants.endpoints.GUILD_ROLES(guildId),
{

View File

@@ -7,7 +7,7 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function editRole(bot: Bot, guildId: bigint, id: bigint, options: CreateGuildRole) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]);
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Role>>(
const result = await bot.rest.runMethod<Role>(
bot.rest,
"patch",
bot.constants.endpoints.GUILD_ROLE(guildId, id),

View File

@@ -2,6 +2,7 @@ import type { Role } from "../../types/permissions/role.ts";
import type { Bot } from "../../bot.ts";
import { Collection } from "../../util/collection.ts";
import { DiscordenoRole } from "../../transformers/role.ts";
/** Returns a list of role objects for the guild.
*
* ⚠️ **If you need this, you are probably doing something wrong. This is not intended for use. Your roles will be cached in your guild.**
@@ -11,7 +12,7 @@ export async function getRoles(bot: Bot, guildId: bigint, addToCache = true) {
const result = await bot.rest.runMethod<Role[]>(bot.rest, "get", bot.constants.endpoints.GUILD_ROLES(guildId));
const roleStructures = result.map((role: Role) => bot.transformers.role({ role, guildId }));
const roleStructures = result.map((role) => bot.transformers.role(bot, { role, guildId }));
const roles = new Collection(roleStructures.map((role: DiscordenoRole) => [role.id, role]));

View File

@@ -22,8 +22,8 @@ export async function createGuildFromTemplate(bot: Bot, templateCode: string, da
data
);
return bot.transformers.guild(
createdGuild,
Number((BigInt(createdGuild.id) >> 22n % BigInt(bot.ws.botGatewayData.shards)).toString())
);
return bot.transformers.guild(bot, {
guild: createdGuild,
shardId: bot.utils.calculateShardId(bot.gateway, bot.transformers.snowflake(createdGuild.id)),
});
}

View File

@@ -9,7 +9,7 @@ import type { Bot } from "../../bot.ts";
export async function getGuildTemplates(bot: Bot, guildId: bigint) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
const templates = await bot.rest.runMethod<Template[]>("get", bot.constants.endpoints.GUILD_TEMPLATES(guildId));
const templates = await bot.rest.runMethod<Template[]>(bot.rest, "get", bot.constants.endpoints.GUILD_TEMPLATES(guildId));
return new Collection(templates.map((template) => [template.code, template]));
}

View File

@@ -1,6 +1,7 @@
import type { UpdateVoiceState } from "../../types/voice/update_voice_state.ts";
import type { AtLeastOne } from "../../types/util.ts";
import type { Bot } from "../../bot.ts";
import { DiscordGatewayOpcodes } from "../../types/codes/gateway_opcodes.ts";
/** Connect or join a voice channel inside a guild. By default, the "selfDeaf" option is true. Requires `CONNECT` and `VIEW_CHANNEL` permissions. */
export async function connectToVoiceChannel(
@@ -11,8 +12,8 @@ export async function connectToVoiceChannel(
) {
await bot.utils.requireBotChannelPermissions(bot, channelId, ["CONNECT", "VIEW_CHANNEL"]);
bot.ws.sendShardMessage(bot.utils.calculateShardId(guildId), {
op: bot.constants.DiscordGatewayOpcodes.VoiceStateUpdate,
bot.gateway.sendShardMessage(bot.gateway, bot.utils.calculateShardId(bot.gateway, guildId), {
op: DiscordGatewayOpcodes.VoiceStateUpdate,
d: {
guild_id: guildId,
channel_id: channelId,

View File

@@ -9,7 +9,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
* Webhook names cannot be: 'clyde'
*/
export async function createWebhook(bot: Bot, channelId: bigint, options: CreateWebhook) {
await bot.utils.requireBotChannelPermissions(channelId, ["MANAGE_WEBHOOKS"]);
await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]);
if (
// Specific usernames that discord does not allow
@@ -19,7 +19,7 @@ export async function createWebhook(bot: Bot, channelId: bigint, options: Create
throw new Error(bot.constants.Errors.INVALID_WEBHOOK_NAME);
}
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>>(
return await bot.rest.runMethod<Webhook>(
bot.rest,
"post",
bot.constants.endpoints.CHANNEL_WEBHOOKS(channelId),

View File

@@ -4,5 +4,5 @@ import type { Bot } from "../../bot.ts";
export async function deleteWebhook(bot: Bot, channelId: bigint, webhookId: bigint) {
await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]);
return await bot.rest.runMethod<undefined>(bot.rset, "delete", bot.constants.endpoints.WEBHOOK_ID(webhookId));
return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.WEBHOOK_ID(webhookId));
}

View File

@@ -5,9 +5,9 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Edit a webhook. Requires the `MANAGE_WEBHOOKS` permission. Returns the updated webhook object on success. */
export async function editWebhook(bot: Bot, channelId: bigint, webhookId: bigint, options: ModifyWebhook) {
await bot.utils.requireBotChannelPermissions(channelId, ["MANAGE_WEBHOOKS"]);
await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]);
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>>(
return await bot.rest.runMethod<Webhook>(
bot.rest,
"patch",
bot.constants.endpoints.WEBHOOK_ID(webhookId),

View File

@@ -41,10 +41,10 @@ export async function editWebhookMessage(
}
if (options.components?.length) {
bot.utils.validateComponents(options.components);
bot.utils.validateComponents(bot, options.components);
}
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
const result = await bot.rest.runMethod<Message>(
bot.rest,
"patch",
options.messageId
@@ -54,12 +54,12 @@ export async function editWebhookMessage(
content: options.content,
embeds: options.embeds,
file: options.file,
allowed_mentions: {
parse: content.allowedMentions.parse,
roles: content.allowedMentions.roles,
users: content.allowedMentions.users,
replied_user: content.allowedMentions.repliedUser,
},
allowed_mentions: options.allowedMentions ? {
parse: options.allowedMentions.parse,
roles: options.allowedMentions.roles,
users: options.allowedMentions.users,
replied_user: options.allowedMentions.repliedUser,
} : undefined,
attachments: options.attachments,
// TODO: Snakelize components??
components: options.components,

View File

@@ -10,7 +10,7 @@ export async function editWebhookWithToken(
webhookToken: string,
options: Omit<ModifyWebhook, "channelId">
) {
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>>(
return await bot.rest.runMethod<Webhook>(
bot.rest,
"patch",
bot.constants.endpoints.WEBHOOK(webhookId, webhookToken),

View File

@@ -4,7 +4,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Returns the new webhook object for the given id. */
export async function getWebhook(bot: Bot, webhookId: bigint) {
return await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>>(
return await bot.rest.runMethod<Webhook>(
bot.rest,
"get",
bot.constants.endpoints.WEBHOOK_ID(webhookId)

View File

@@ -4,7 +4,7 @@ import type { Bot } from "../../bot.ts";
/** Returns a previously-sent webhook message from the same token. Returns a message object on success. */
export async function getWebhookMessage(bot: Bot, webhookId: bigint, webhookToken: string, messageId: bigint) {
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
const result = await bot.rest.runMethod<Message>(
bot.rest,
"get",
bot.constants.endpoints.WEBHOOK_MESSAGE(webhookId, webhookToken, messageId)

View File

@@ -7,7 +7,7 @@ import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
export async function getWebhooks(bot: Bot, guildId: bigint) {
await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_WEBHOOKS"]);
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Webhook>[]>(
const result = await bot.rest.runMethod<Webhook[]>(
bot.rest,
"get",
bot.constants.endpoints.GUILD_WEBHOOKS(guildId)

View File

@@ -2,7 +2,6 @@ import type { Bot } from "../../bot.ts";
import { DiscordAllowedMentionsTypes } from "../../types/messages/allowed_mentions_types.ts";
import type { Message } from "../../types/messages/message.ts";
import type { ExecuteWebhook } from "../../types/webhooks/execute_webhook.ts";
import type { SnakeCasedPropertiesDeep } from "../../types/util.ts";
/** Send a webhook with webhook Id and webhook token */
export async function sendWebhook(bot: Bot, webhookId: bigint, webhookToken: string, options: ExecuteWebhook) {
@@ -38,7 +37,7 @@ export async function sendWebhook(bot: Bot, webhookId: bigint, webhookToken: str
}
}
const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Message>>(
const result = await bot.rest.runMethod<Message>(
bot.rest,
"post",
`${bot.constants.endpoints.WEBHOOK(webhookId, webhookToken)}?wait=${options.wait ?? false}${

View File

@@ -4,7 +4,7 @@ import { RestManager } from "../bot.ts";
export function cleanupQueues(rest: RestManager) {
for (const [key, queue] of rest.pathQueues) {
rest.debug(`[REST - cleanupQueues] Running for of loop. ${key}`);
if (queue.length) continue;
if (queue.requests.length) continue;
// REMOVE IT FROM CACHE
rest.pathQueues.delete(key);
}

View File

@@ -57,7 +57,7 @@ export function processRequestHeaders(rest: RestManager, url: string, headers: H
}
if (ratelimited && !rest.processingRateLimitedPaths) {
rest.processRateLimitedPaths();
rest.processRateLimitedPaths(rest);
}
return ratelimited ? bucketId : undefined;
}

View File

@@ -1,4 +1,5 @@
import { RestManager } from "../bot.ts";
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
import { API_VERSION, BASE_URL, IMAGE_BASE_URL } from "../util/constants.ts";
export async function runMethod<T = any>(
@@ -8,7 +9,7 @@ export async function runMethod<T = any>(
body?: unknown,
retryCount = 0,
bucketId?: string
): Promise<T> {
): Promise<SnakeCasedPropertiesDeep<T>> {
rest.debug(
`[REST - RequestCreate] Method: ${method} | URL: ${url} | Retry Count: ${retryCount} | Bucket ID: ${bucketId} | Body: ${JSON.stringify(
body

View File

@@ -0,0 +1,35 @@
import { Bot } from "../bot.ts";
import { Attachment } from "../types/messages/attachment.ts";
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
export function transformAttachment(bot: Bot, payload: SnakeCasedPropertiesDeep<Attachment>): DiscordenoAttachment {
return {
id: bot.transformers.snowflake(payload.id),
filename: payload.filename,
contentType: payload.content_type,
size: payload.size,
url: payload.url,
proxyUrl: payload.proxy_url,
height: payload.height ?? undefined,
width: payload.width ?? undefined,
};
}
export interface DiscordenoAttachment {
/** Attachment id */
id: bigint;
/** Name of file attached */
filename: string;
/** The attachment's [media type](https://en.wikipedia.org/wiki/Media_type) */
contentType?: string;
/** Size of file in bytes */
size: number;
/** Source url of file */
url: string;
/** A proxied url of file */
proxyUrl: string;
/** Height of file (if image) */
height?: number;
/** Width of file (if image) */
width?: number;
}

View File

@@ -30,13 +30,11 @@ export function transformRole(
};
}
export interface DiscordenoRole extends Omit<Role, "tags" | "id" | "permissions"> {
export interface DiscordenoRole extends Omit<Role, "tags" | "id" | "permissions" | "hoist" | "mentionable" | "managed"> {
/** The role id */
id: bigint;
/** The bot id that is associated with this role. */
botId?: bigint;
/** If this role is the nitro boost role. */
isNitroBoostRole: boolean;
/** The integration id that is associated with this role */
integrationId?: bigint;
/** The roles guildId */

View File

@@ -49,7 +49,7 @@ export async function dispatchRequirements(bot: Bot, data: DiscordGatewayPayload
bot.events.debug(`[DISPATCH] New Guild ID has appeared: ${id} in ${data.t} event`);
const rawGuild = (await bot.helpers
.getGuild(id, {
.getGuild(bot, id, {
counts: true,
addToCache: false,
})
@@ -63,8 +63,8 @@ export async function dispatchRequirements(bot: Bot, data: DiscordGatewayPayload
bot.events.debug(`[DISPATCH] Guild ID ${id} has been found. ${rawGuild.name}`);
const [channels, botMember] = await Promise.all([
bot.helpers.getChannels(id, false),
bot.helpers.getMember(id, bot.id, { force: true }),
bot.helpers.getChannels(bot, id, false),
bot.helpers.getMember(bot, id, bot.id, { force: true }),
]).catch((error) => {
bot.events.debug(error);
return [];
@@ -78,8 +78,10 @@ export async function dispatchRequirements(bot: Bot, data: DiscordGatewayPayload
}
const guild = bot.transformers.guild(bot, {
...rawGuild,
member_count: rawGuild.approximateMemberCount,
guild: {
...rawGuild,
member_count: rawGuild.approximate_member_count,
},
shardId,
});

View File

@@ -142,7 +142,7 @@ export function validateSlashCommands(
// Taken from https://fettblog.eu/typescript-hasownproperty/
/** TS save way to check if a property exists in an object */
// deno-lint-ignore ban-types
export function hasOwnProperty<T extends {}, Y extends PropertyKey = string>(
export function hasProperty<T extends {}, Y extends PropertyKey = string>(
obj: T,
prop: Y
): obj is T & Record<Y, unknown> {

View File

@@ -1,28 +1,29 @@
import { getGatewayBot } from "../helpers/misc/get_gateway_bot.ts";
import { GatewayManager } from "../bot.ts";
import { GetGatewayBot } from "../types/gateway/get_gateway_bot.ts";
/** The handler to automatically reshard when necessary. */
export async function resharder(gateway: GatewayManager) {
gateway.botGatewayData = await getGatewayBot();
// TODO: is it possible to route this to REST?
const results = (await fetch(`https://discord.com/api/gateway/bot`, {
headers: { Authorization: gateway.token },
}).then((res) => res.json())) as GetGatewayBot;
const percentage = ((gateway.botGatewayData.shards - gateway.maxShards) / gateway.maxShards) * 100;
const percentage = ((results.shards - gateway.maxShards) / gateway.maxShards) * 100;
// Less than necessary% being used so do nothing
if (percentage < gateway.reshardPercentage) return;
// Don't have enough identify rate limits to reshard
if (gateway.botGatewayData.sessionStartLimit.remaining < gateway.botGatewayData.shards) {
if (results.sessionStartLimit.remaining < results.shards) {
return;
}
// Begin resharding
gateway.maxShards = gateway.botGatewayData.shards;
gateway.maxShards = results.shards;
// If more than 100K servers, begin switching to 16x sharding
if (gateway.maxShards && gateway.useOptimalLargeBotSharding) {
gateway.maxShards = Math.ceil(
gateway.maxShards /
(gateway.botGatewayData.sessionStartLimit.maxConcurrency === 1
? 16
: gateway.botGatewayData.sessionStartLimit.maxConcurrency)
(results.sessionStartLimit.maxConcurrency === 1 ? 16 : results.sessionStartLimit.maxConcurrency)
);
}

Some files were not shown because too many files have changed in this diff Show More