This commit is contained in:
ITOH
2021-04-12 09:30:45 +02:00
parent 51e27d8f17
commit b9bd29ebf8
44 changed files with 268 additions and 221 deletions
@@ -1,19 +1,17 @@
import { eventHandlers } from "../../bot.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordApplicationCommandCreateUpdateDelete } from "../../types/interactions/application_command_create_update_delete.ts";
import {
ApplicationCommandCreateUpdateDelete,
DiscordApplicationCommandCreateUpdateDelete,
} from "../../types/interactions/application_command_create_update_delete.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export function handleApplicationCommandCreate(
data: DiscordGatewayPayload,
) {
const {
guild_id: guildId,
application_id: applicationId,
...rest
} = data.d as DiscordApplicationCommandCreateUpdateDelete;
eventHandlers.applicationCommandCreate?.({
...rest,
guildId,
applicationId,
});
eventHandlers.applicationCommandCreate?.(
snakeKeysToCamelCase<ApplicationCommandCreateUpdateDelete>(
data.d as DiscordApplicationCommandCreateUpdateDelete,
),
);
}
@@ -1,17 +1,15 @@
import { eventHandlers } from "../../bot.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordApplicationCommandCreateUpdateDelete } from "../../types/interactions/application_command_create_update_delete.ts";
import {
ApplicationCommandCreateUpdateDelete,
DiscordApplicationCommandCreateUpdateDelete,
} from "../../types/interactions/application_command_create_update_delete.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export function handleApplicationCommandDelete(data: DiscordGatewayPayload) {
const {
application_id: applicationId,
guild_id: guildId,
...rest
} = data.d as DiscordApplicationCommandCreateUpdateDelete;
eventHandlers.applicationCommandDelete?.({
...rest,
guildId,
applicationId,
});
eventHandlers.applicationCommandDelete?.(
snakeKeysToCamelCase<ApplicationCommandCreateUpdateDelete>(
data.d as DiscordApplicationCommandCreateUpdateDelete,
),
);
}
@@ -1,6 +1,10 @@
import { eventHandlers } from "../../bot.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordApplicationCommandCreateUpdateDelete } from "../../types/interactions/application_command_create_update_delete.ts";
import {
ApplicationCommandCreateUpdateDelete,
DiscordApplicationCommandCreateUpdateDelete,
} from "../../types/interactions/application_command_create_update_delete.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export function handleApplicationCommandUpdate(data: DiscordGatewayPayload) {
const {
@@ -9,9 +13,9 @@ export function handleApplicationCommandUpdate(data: DiscordGatewayPayload) {
...rest
} = data.d as DiscordApplicationCommandCreateUpdateDelete;
eventHandlers.applicationCommandUpdate?.({
...rest,
guildId,
applicationId,
});
eventHandlers.applicationCommandUpdate?.(
snakeKeysToCamelCase<ApplicationCommandCreateUpdateDelete>(
data.d as DiscordApplicationCommandCreateUpdateDelete,
),
);
}
+3 -3
View File
@@ -1,8 +1,8 @@
import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { Collection } from "../../util/collection.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordGuildEmojisUpdate } from "../../types/emojis/guild_emojis_update.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { Collection } from "../../util/collection.ts";
export async function handleGuildEmojisUpdate(data: DiscordGatewayPayload) {
const payload = data.d as DiscordGuildEmojisUpdate;
@@ -11,7 +11,7 @@ export async function handleGuildEmojisUpdate(data: DiscordGatewayPayload) {
const cachedEmojis = guild.emojis;
guild.emojis = new Collection(
payload.emojis.map((emoji) => [emoji.id ?? emoji.name, emoji]),
payload.emojis.map((emoji) => [emoji.id!, emoji]),
);
await cacheHandlers.set("guilds", payload.guild_id, guild);
+2
View File
@@ -30,6 +30,8 @@ export async function handleGuildUpdate(data: DiscordGatewayPayload) {
if (Array.isArray(cachedValue) && Array.isArray(value)) {
const different = (cachedValue.length !== value.length) ||
cachedValue.find((val) => !value.includes(val)) ||
// TODO: check if this really works hehe
// @ts-ignore this works ts is wrong
value.find((val) => !cachedValue.includes(val));
if (!different) return;
}
@@ -9,9 +9,9 @@ import { snakeKeysToCamelCase } from "../../util/utils.ts";
export function handleIntegrationCreate(
data: DiscordGatewayPayload,
) {
const payload = data.d as DiscordIntegrationCreateUpdate;
eventHandlers.integrationCreate?.(
snakeKeysToCamelCase(payload) as IntegrationCreateUpdate,
snakeKeysToCamelCase<IntegrationCreateUpdate>(
data.d as DiscordIntegrationCreateUpdate,
),
);
}
@@ -1,15 +1,15 @@
import { eventHandlers } from "../../bot.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { IntegrationCreateUpdate } from "../../types/integration/integration_create_update.ts";
import {
DiscordIntegrationDelete,
IntegrationDelete,
} from "../../types/integration/integration_delete.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export function handleIntegrationDelete(data: DiscordGatewayPayload) {
const payload = data.d as DiscordIntegrationDelete;
eventHandlers.integrationDelete?.(
snakeKeysToCamelCase(payload) as IntegrationDelete,
snakeKeysToCamelCase<IntegrationCreateUpdate>(
data.d as DiscordIntegrationDelete,
),
);
}
@@ -7,9 +7,9 @@ import {
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export function handleIntegrationUpdate(data: DiscordGatewayPayload) {
const payload = data.d as DiscordIntegrationCreateUpdate;
eventHandlers.integrationUpdate?.(
snakeKeysToCamelCase(payload) as IntegrationCreateUpdate,
snakeKeysToCamelCase<IntegrationCreateUpdate>(
data.d as DiscordIntegrationCreateUpdate,
),
);
}
@@ -1,10 +1,12 @@
// TODO: DM support idk need to discuss how we solve this
import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { structures } from "../../structures/mod.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { Interaction } from "../../types/mod.ts";
export async function handleInteractionCreate(data: DiscordGatewayPayload) {
const payload = data.d as InteractionCommandPayload;
const payload = data.d as Interaction;
const discordenoMember = await structures.createDiscordenoMember(
payload.member,
payload.guild_id,
+3 -3
View File
@@ -7,7 +7,7 @@ import {
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export function handleInviteCreate(data: DiscordGatewayPayload) {
const payload = data.d as DiscordInviteCreate;
eventHandlers.inviteCreate?.(snakeKeysToCamelCase(payload) as InviteCreate);
eventHandlers.inviteCreate?.(
snakeKeysToCamelCase<InviteCreate>(data.d as DiscordInviteCreate),
);
}
+3 -3
View File
@@ -7,7 +7,7 @@ import {
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export function handleInviteDelete(data: DiscordGatewayPayload) {
const payload = data.d as DiscordInviteDelete;
eventHandlers.inviteDelete?.(snakeKeysToCamelCase(payload) as InviteDelete);
eventHandlers.inviteDelete?.(
snakeKeysToCamelCase<InviteDelete>(data.d as DiscordInviteDelete),
);
}
+1 -1
View File
@@ -35,7 +35,7 @@ export async function handleGuildMemberUpdate(data: DiscordGatewayPayload) {
guild,
discordenoMember,
payload.nick!,
guildMember.nick,
guildMember.nick ?? undefined,
);
}
+6 -11
View File
@@ -2,7 +2,11 @@ import { botId, eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { structures } from "../../structures/mod.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordMessageReactionAdd } from "../../types/messages/message_reaction_add.ts";
import {
DiscordMessageReactionAdd,
MessageReactionAdd,
} from "../../types/messages/message_reaction_add.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export async function handleMessageReactionAdd(data: DiscordGatewayPayload) {
const payload = data.d as DiscordMessageReactionAdd;
@@ -41,17 +45,8 @@ export async function handleMessageReactionAdd(data: DiscordGatewayPayload) {
}
}
const uncachedOptions = {
...payload,
id: payload.message_id,
channelId: payload.channel_id,
guildId: payload.guild_id || "",
};
eventHandlers.reactionAdd?.(
uncachedOptions,
payload.emoji,
payload.user_id,
snakeKeysToCamelCase<MessageReactionAdd>(payload),
message,
);
}
@@ -1,7 +1,11 @@
import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordMessageReactionRemove } from "../../types/messages/message_reaction_remove.ts";
import {
DiscordMessageReactionRemove,
MessageReactionRemove,
} from "../../types/messages/message_reaction_remove.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export async function handleMessageReactionRemove(
data: DiscordGatewayPayload,
@@ -18,24 +22,17 @@ export async function handleMessageReactionRemove(
if (reaction) {
reaction.count--;
if (reaction.count === 0) message.reactions = message.reactions?.filter(r => r.count !== 0);
if (reaction.count === 0) {
message.reactions = message.reactions?.filter((r) => r.count !== 0);
}
if (!message.reactions?.length) message.reactions = undefined;
await cacheHandlers.set("messages", payload.message_id, message);
}
}
const uncachedOptions = {
...payload,
id: payload.message_id,
channelId: payload.channel_id,
guildId: payload.guild_id,
};
eventHandlers.reactionRemove?.(
uncachedOptions,
payload.emoji,
payload.user_id,
snakeKeysToCamelCase<MessageReactionRemove>(payload),
message,
);
}
@@ -1,7 +1,11 @@
import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordMessageReactionRemoveAll } from "../../types/messages/message_reaction_remove_all.ts";
import {
DiscordMessageReactionRemoveAll,
MessageReactionRemoveAll,
} from "../../types/messages/message_reaction_remove_all.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export async function handleMessageReactionRemoveAll(
data: DiscordGatewayPayload,
@@ -15,5 +19,8 @@ export async function handleMessageReactionRemoveAll(
await cacheHandlers.set("messages", payload.message_id, message);
}
eventHandlers.reactionRemoveAll?.(payload);
eventHandlers.reactionRemoveAll?.(
snakeKeysToCamelCase<MessageReactionRemoveAll>(payload),
message,
);
}
@@ -19,12 +19,15 @@ export async function handleMessageReactionRemoveEmoji(
),
);
if (!message.reactions.length) message.reactions = undefined
if (!message.reactions.length) message.reactions = undefined;
await cacheHandlers.set("messages", payload.message_id, message);
}
eventHandlers.reactionRemoveEmoji?.(
data.d,
payload.emoji,
payload.message_id,
payload.channel_id,
payload.guild_id,
);
}
+3 -12
View File
@@ -9,22 +9,13 @@ export async function handleMessageUpdate(data: DiscordGatewayPayload) {
const channel = await cacheHandlers.get("channels", payload.channel_id);
if (!channel) return;
const cachedMessage = await cacheHandlers.get("messages", payload.id);
if (!cachedMessage) return;
const oldMessage = {
attachments: cachedMessage.attachments,
content: cachedMessage.content,
embeds: cachedMessage.embeds,
editedTimestamp: cachedMessage.editedTimestamp,
tts: cachedMessage.tts,
pinned: cachedMessage.pinned,
};
const oldMessage = await cacheHandlers.get("messages", payload.id);
if (!oldMessage) return;
// Messages with embeds can trigger update but they wont have edited_timestamp
if (
!payload.edited_timestamp ||
(cachedMessage.content === payload.content)
(oldMessage.content === payload.content)
) {
return;
}
+8 -2
View File
@@ -1,10 +1,16 @@
import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordPresenceUpdate } from "../../types/misc/presence_update.ts";
import {
DiscordPresenceUpdate,
PresenceUpdate,
} from "../../types/misc/presence_update.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export async function handlePresenceUpdate(data: DiscordGatewayPayload) {
const payload = data.d as DiscordPresenceUpdate;
const payload = snakeKeysToCamelCase<PresenceUpdate>(
data.d as DiscordPresenceUpdate,
);
const oldPresence = await cacheHandlers.get("presences", payload.user.id);
await cacheHandlers.set("presences", payload.user.id, payload);
+3 -2
View File
@@ -4,7 +4,8 @@ import { initialMemberLoadQueue } from "../../structures/guild.ts";
import { structures } from "../../structures/mod.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordReady } from "../../types/gateway/ready.ts";
import { delay, snakeKeysToCamelCase } from "../../util/utils.ts";
import { DiscordGuildMemberWithUser } from "../../types/mod.ts";
import { camelKeysToSnakeCase, delay } from "../../util/utils.ts";
import { ws } from "../../ws/ws.ts";
export async function handleReady(
@@ -103,7 +104,7 @@ async function loaded(shardId: number) {
await Promise.allSettled(
members.map(async (member) => {
const discordenoMember = await structures.createDiscordenoMember(
snakeKeysToCamelCase(member),
camelKeysToSnakeCase<DiscordGuildMemberWithUser>(member),
guildId,
);
+8 -2
View File
@@ -1,7 +1,13 @@
import { eventHandlers } from "../../bot.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordTypingStart } from "../../types/misc/typing_start.ts";
import {
DiscordTypingStart,
TypingStart,
} from "../../types/misc/typing_start.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export function handleTypingStart(data: DiscordGatewayPayload) {
eventHandlers.typingStart?.(data.d as DiscordTypingStart);
eventHandlers.typingStart?.(
snakeKeysToCamelCase<TypingStart>(data.d as DiscordTypingStart),
);
}
+2 -1
View File
@@ -2,9 +2,10 @@ import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { structures } from "../../structures/mod.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordGuildRoleCreate } from "../../types/mod.ts";
export async function handleGuildRoleCreate(data: DiscordGatewayPayload) {
const payload = data.d as DiscordGuildRoleCreateUpdate;
const payload = data.d as DiscordGuildRoleCreate;
const guild = await cacheHandlers.get("guilds", payload.guild_id);
if (!guild) return;
+2 -1
View File
@@ -2,9 +2,10 @@ import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { structures } from "../../structures/mod.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordGuildRoleUpdate } from "../../types/mod.ts";
export async function handleGuildRoleUpdate(data: DiscordGatewayPayload) {
const payload = data.d as DiscordGuildRoleCreateUpdate;
const payload = data.d as DiscordGuildRoleUpdate;
const guild = await cacheHandlers.get("guilds", payload.guild_id);
if (!guild) return;
+7 -2
View File
@@ -1,11 +1,16 @@
import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordVoiceServerUpdate, VoiceServerUpdate } from "../../types/voice/voice_server_update.ts";
import {
DiscordVoiceServerUpdate,
VoiceServerUpdate,
} from "../../types/voice/voice_server_update.ts";
import { snakeKeysToCamelCase } from "../../util/utils.ts";
export async function handleVoiceServerUpdate(data: DiscordGatewayPayload) {
const payload = snakeKeysToCamelCase(data.d as DiscordVoiceServerUpdate) as VoiceServerUpdate;
const payload = snakeKeysToCamelCase<VoiceServerUpdate>(
data.d as DiscordVoiceServerUpdate,
);
const guild = await cacheHandlers.get("guilds", payload.guildId);
if (!guild) return;
+30 -23
View File
@@ -2,51 +2,58 @@ import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { structures } from "../../structures/mod.ts";
import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
import { DiscordVoiceState } from "../../types/voice/voice_state.ts";
import { DiscordGuildMemberWithUser } from "../../types/mod.ts";
import {
DiscordVoiceState,
VoiceState,
} from "../../types/voice/voice_state.ts";
import {
camelKeysToSnakeCase,
snakeKeysToCamelCase,
} from "../../util/utils.ts";
export async function handleVoiceStateUpdate(data: DiscordGatewayPayload) {
const payload = data.d as DiscordVoiceState;
if (!payload.guild_id) return;
const payload = snakeKeysToCamelCase<VoiceState>(
data.d as DiscordVoiceState,
);
if (!payload.guildId) return;
const guild = await cacheHandlers.get("guilds", payload.guild_id);
const guild = await cacheHandlers.get("guilds", payload.guildId);
if (!guild) return;
const member = payload.member
? await structures.createDiscordenoMember(payload.member, guild.id)
: await cacheHandlers.get("members", payload.user_id);
? await structures.createDiscordenoMember(
camelKeysToSnakeCase<DiscordGuildMemberWithUser>(payload),
guild.id,
)
: await cacheHandlers.get("members", payload.userId);
if (!member) return;
// No cached state before so lets make one for em
const cachedState = guild.voiceStates.get(payload.user_id);
const cachedState = guild.voiceStates.get(payload.userId);
guild.voiceStates.set(payload.user_id, {
...payload,
guildId: payload.guild_id,
channelId: payload.channel_id || "",
userId: payload.user_id,
sessionId: payload.session_id,
selfDeaf: payload.self_deaf,
selfMute: payload.self_mute,
selfStream: payload.self_stream || false,
});
guild.voiceStates.set(
payload.userId,
payload,
);
await cacheHandlers.set("guilds", payload.guild_id, guild);
await cacheHandlers.set("guilds", payload.guildId, guild);
if (cachedState?.channelId !== payload.channel_id) {
if (cachedState?.channelId !== payload.channelId) {
// Either joined or moved channels
if (payload.channel_id) {
if (payload.channelId) {
if (cachedState?.channelId) { // Was in a channel before
eventHandlers.voiceChannelSwitch?.(
member,
payload.channel_id,
payload.channelId,
cachedState.channelId,
);
} else { // Was not in a channel before so user just joined
eventHandlers.voiceChannelJoin?.(member, payload.channel_id);
eventHandlers.voiceChannelJoin?.(member, payload.channelId);
}
} // Left the channel
else if (cachedState?.channelId) {
guild.voiceStates.delete(payload.user_id);
guild.voiceStates.delete(payload.userId);
eventHandlers.voiceChannelLeave?.(member, cachedState.channelId);
}
}
+1 -1
View File
@@ -24,5 +24,5 @@ export async function createEmoji(
image,
});
return snakeKeysToCamelCase(result) as Emoji;
return snakeKeysToCamelCase<Emoji>(result);
}
+1 -1
View File
@@ -21,5 +21,5 @@ export async function editWidget(
},
);
return snakeKeysToCamelCase(result) as GuildWidget;
return snakeKeysToCamelCase<GuildWidget>(result);
}
+1 -1
View File
@@ -26,5 +26,5 @@ export async function getAuditLogs(
}),
);
return snakeKeysToCamelCase(result) as AuditLog;
return snakeKeysToCamelCase<AuditLog>(result);
}
+1 -1
View File
@@ -13,5 +13,5 @@ export async function getBan(guildId: string, memberId: string) {
endpoints.GUILD_BAN(guildId, memberId),
);
return snakeKeysToCamelCase(result) as Ban;
return snakeKeysToCamelCase<Ban>(result);
}
+1 -1
View File
@@ -15,6 +15,6 @@ export async function getBans(guildId: string) {
)) as DiscordBan[];
return new Collection<string, Ban>(
results.map((res) => [res.user.id, snakeKeysToCamelCase(res) as Ban]),
results.map((res) => [res.user.id, snakeKeysToCamelCase<Ban>(res)]),
);
}
+1 -1
View File
@@ -15,5 +15,5 @@ export async function getGuild(guildId: string, counts = true) {
with_counts: counts,
});
return snakeKeysToCamelCase(result) as Guild;
return snakeKeysToCamelCase<Guild>(result);
}
+1 -1
View File
@@ -7,5 +7,5 @@ import { snakeKeysToCamelCase } from "../../util/utils.ts";
export async function getGuildPreview(guildId: string) {
const result = await rest.runMethod("get", endpoints.GUILD_PREVIEW(guildId));
return snakeKeysToCamelCase(result) as GuildPreview;
return snakeKeysToCamelCase<GuildPreview>(result);
}
+5 -3
View File
@@ -10,7 +10,9 @@ export async function getVanityURL(guildId: string) {
endpoints.GUILD_VANITY_URL(guildId),
);
return snakeKeysToCamelCase(result) as
| (Partial<InviteMetadata> & Pick<InviteMetadata, "uses" | "code">)
| { code: null };
return snakeKeysToCamelCase<
(Partial<InviteMetadata> & Pick<InviteMetadata, "uses" | "code">) | {
code: null;
}
>(result);
}
+1 -1
View File
@@ -80,7 +80,7 @@ export async function createDiscordenoChannel(
guildId: rawGuildId = "",
lastPinTimestamp,
...rest
} = snakeKeysToCamelCase(data) as Channel;
} = snakeKeysToCamelCase<Channel>(data);
const props: Record<string, PropertyDescriptor> = {};
Object.keys(rest).forEach((key) => {
+4 -7
View File
@@ -18,14 +18,13 @@ import { CreateGuildBan } from "../types/guilds/create_guild_ban.ts";
import { DiscordGuild, Guild } from "../types/guilds/guild.ts";
import { DiscordGuildFeatures } from "../types/guilds/guild_features.ts";
import {
DiscordGuildMember,
DiscordGuildMemberWithUser,
GuildMember,
} from "../types/guilds/guild_member.ts";
import { ModifyGuild } from "../types/guilds/modify_guild.ts";
import { DiscordImageFormat } from "../types/misc/image_format.ts";
import { DiscordImageSize } from "../types/misc/image_size.ts";
import { PresenceUpdate } from "../types/misc/presence_update.ts";
import { DiscordUser } from "../types/users/user.ts";
import { VoiceState } from "../types/voice/voice_state.ts";
import { Collection } from "../util/collection.ts";
import {
@@ -128,7 +127,7 @@ export async function createDiscordenoGuild(
emojis,
members = [],
...rest
} = snakeKeysToCamelCase(data) as Guild;
} = snakeKeysToCamelCase<Guild>(data);
const roles = await Promise.all(
(data.roles || []).map((role) =>
@@ -189,9 +188,7 @@ export async function createDiscordenoGuild(
await Promise.allSettled(
members.map(async (member) => {
const discordenoMember = await structures.createDiscordenoMember(
camelKeysToSnakeCase(member) as Omit<DiscordGuildMember, "user"> & {
user: DiscordUser;
},
camelKeysToSnakeCase(member) as DiscordGuildMemberWithUser,
guild.id,
);
@@ -220,7 +217,7 @@ export interface DiscordenoGuild extends
| "emojis"
> {
/** Total number of members in this guild */
memberCount?: number;
memberCount: number;
/** The roles in the guild */
roles: Collection<string, DiscordenoRole>;
/** The presences of all the users in the guild. */
+5 -6
View File
@@ -9,14 +9,15 @@ import { addRole } from "../helpers/roles/add_role.ts";
import { removeRole } from "../helpers/roles/remove_role.ts";
import { CreateGuildBan } from "../types/guilds/create_guild_ban.ts";
import {
DiscordGuildMember,
DiscordGuildMemberWithUser,
GuildMember,
GuildMemberWithUser,
} from "../types/guilds/guild_member.ts";
import { ModifyGuildMember } from "../types/guilds/modify_guild_member.ts";
import { CreateMessage } from "../types/messages/create_message.ts";
import { DiscordImageFormat } from "../types/misc/image_format.ts";
import { DiscordImageSize } from "../types/misc/image_size.ts";
import { DiscordUser, User } from "../types/users/user.ts";
import { User } from "../types/users/user.ts";
import { Collection } from "../util/collection.ts";
import { createNewProp, snakeKeysToCamelCase } from "../util/utils.ts";
import { DiscordenoGuild } from "./guild.ts";
@@ -73,7 +74,7 @@ const baseMember: Partial<DiscordenoMember> = {
export async function createDiscordenoMember(
// The `user` param in `DiscordGuildMember` is optional since discord does not send it in `MESSAGE_CREATE` and `MESSAGE_UPDATE` events. But this data in there is required to build this structure so it is required in this case
data: Omit<DiscordGuildMember, "user"> & { user: DiscordUser },
data: DiscordGuildMemberWithUser,
guildId: string,
) {
const {
@@ -81,9 +82,7 @@ export async function createDiscordenoMember(
joinedAt,
premiumSince,
...rest
} = snakeKeysToCamelCase(data) as Omit<GuildMember, "user"> & {
user: DiscordUser;
};
} = snakeKeysToCamelCase<GuildMemberWithUser>(data);
const props: Record<string, ReturnType<typeof createNewProp>> = {};
+12 -14
View File
@@ -39,9 +39,8 @@ const baseMessage: Partial<DiscordenoMessage> = {
return this.member?.guilds.get(this.guildId);
},
get link() {
return `https://discord.com/channels/${this.guildId || "@me"}/${
this.channelId
}/${this.id}`;
return `https://discord.com/channels/${this.guildId ||
"@me"}/${this.channelId}/${this.id}`;
},
get mentionedRoles() {
return this.mentionedRoleIds?.map((id) => this.guild?.roles.get(id)) || [];
@@ -70,8 +69,7 @@ const baseMessage: Partial<DiscordenoMessage> = {
return addReactions(this.channelId!, this.id!, reactions, ordered);
},
reply(content) {
const contentWithMention =
typeof content === "string"
const contentWithMention = typeof content === "string"
? {
content,
mentions: { repliedUser: true },
@@ -133,21 +131,21 @@ export async function createDiscordenoMessage(data: DiscordMessage) {
mentionRoles,
editedTimestamp,
...rest
} = snakeKeysToCamelCase(data) as Message;
} = snakeKeysToCamelCase<Message>(data);
const props: Record<string, ReturnType<typeof createNewProp>> = {};
for (const key of Object.keys(rest)) {
eventHandlers.debug?.(
"loop",
`Running for of loop in createDiscordenoMessage function.`
`Running for of loop in createDiscordenoMessage function.`,
);
// @ts-ignore index signature
props[key] = createNewProp(rest[key]);
}
// Discord doesnt give guild id for getMessage() so this will fill it in
const guildIdFinal =
guildId || (await cacheHandlers.get("channels", channelId))?.guildId || "";
const guildIdFinal = guildId ||
(await cacheHandlers.get("channels", channelId))?.guildId || "";
const message: DiscordenoMessage = Object.create(baseMessage, {
...props,
@@ -167,7 +165,7 @@ export async function createDiscordenoMessage(data: DiscordMessage) {
]),
timestamp: createNewProp(Date.parse(data.timestamp)),
editedTimestamp: createNewProp(
editedTimestamp ? Date.parse(editedTimestamp) : undefined
editedTimestamp ? Date.parse(editedTimestamp) : undefined,
),
});
@@ -209,7 +207,7 @@ export interface DiscordenoMessage extends Message {
/** Delete the message */
delete(
reason?: string,
delayMilliseconds?: number
delayMilliseconds?: number,
): ReturnType<typeof deleteMessage>;
/** Edit the message */
edit(content: string | EditMessage): ReturnType<typeof editMessage>;
@@ -220,7 +218,7 @@ export interface DiscordenoMessage extends Message {
/** Add multiple reactions to the message without or without order. */
addReactions(
reactions: string[],
ordered?: boolean
ordered?: boolean,
): ReturnType<typeof addReactions>;
/** Send a inline reply to this message */
reply(content: string | CreateMessage): ReturnType<typeof sendMessage>;
@@ -230,13 +228,13 @@ export interface DiscordenoMessage extends Message {
alert(
content: string | CreateMessage,
timeout?: number,
reason?: string
reason?: string,
): Promise<void>;
/** Send a inline reply to this message but then delete it after a bit. By default it will delete after 10 seconds with no reason provided. */
alertReply(
content: string | CreateMessage,
timeout?: number,
reason?: string
reason?: string,
): Promise<unknown>;
/** Remove all reactions */
removeAllReactions(): ReturnType<typeof removeAllReactions>;
+4 -2
View File
@@ -71,9 +71,11 @@ export async function createDiscordenoRole(data: DiscordGuildRoleCreate) {
const {
tags = {},
...rest
} = snakeKeysToCamelCase({ guildId: data.guild_id, ...data.role }) as Role & {
} = snakeKeysToCamelCase<
Role & {
guildId: string;
};
}
>({ guildId: data.guild_id, ...data.role });
const props: Record<string, ReturnType<typeof createNewProp>> = {};
for (const key of Object.keys(rest)) {
+47 -30
View File
@@ -9,7 +9,6 @@ import { ApplicationCommandCreateUpdateDelete } from "../interactions/applicatio
import {
Channel,
DiscordGatewayPayload,
DiscordMessageReactionRemoveAll,
Emoji,
GatewayPayload,
IntegrationDelete,
@@ -18,6 +17,7 @@ import {
InviteDelete,
MessageReactionAdd,
MessageReactionRemove,
MessageReactionRemoveAll,
PresenceUpdate,
TypingStart,
User,
@@ -30,15 +30,15 @@ import { GuildUpdateChange } from "./guild_update_change.ts";
export interface EventHandlers {
/** Sent when a new Slash Command is created, relevant to the current user. */
applicationCommandCreate?: (
data: ApplicationCommandCreateUpdateDelete
data: ApplicationCommandCreateUpdateDelete,
) => unknown;
/** Sent when a Slash Command relevant to the current user is updated. */
applicationCommandUpdate?: (
data: ApplicationCommandCreateUpdateDelete
data: ApplicationCommandCreateUpdateDelete,
) => unknown;
/** Sent when a Slash Command relevant to the current user is deleted. */
applicationCommandDelete?: (
data: ApplicationCommandCreateUpdateDelete
data: ApplicationCommandCreateUpdateDelete,
) => unknown;
/** Sent when properties about the user change. */
botUpdate?: (user: User) => unknown;
@@ -48,23 +48,29 @@ export interface EventHandlers {
channelUpdate?: (channel: Channel, oldChannel: Channel) => unknown;
/** Sent when a channel relevant to the current user is deleted. */
channelDelete?: (channel: Channel) => unknown;
/** Sent when a message pin is updated */
channelPinsUpdate?: (
channel: DiscordenoChannel,
guild?: DiscordenoGuild,
lastPinTimestamp?: string | null,
) => unknown;
debug?: (args: string | DebugArg, data?: string) => unknown;
/** Sent before every event. Discordeno awaits the execution of this event before main event gets sent. */
dispatchRequirements?: (
data: DiscordGatewayPayload,
shardId: number
shardId: number,
) => unknown;
/** Sent when a user is banned from a guild. */
guildBanAdd?: (
guild: DiscordenoGuild,
user: User,
member?: DiscordenoMember
member?: DiscordenoMember,
) => unknown;
/** Sent when a user is unbanned from a guild. */
guildBanRemove?: (
guild: DiscordenoGuild,
user: User,
member?: DiscordenoMember
member?: DiscordenoMember,
) => unknown;
/**
* This event can be sent in three different scenarios:
@@ -77,12 +83,16 @@ export interface EventHandlers {
guildCreate?: (guild: DiscordenoGuild) => unknown;
/** This event does get sent on start when shards are loading the guilds */
guildLoaded?: (guild: DiscordenoGuild) => unknown;
/** When a guild goes unavailable this event will be ran. */
/** When a guild goes available this event will be ran. */
guildAvailable?: (guild: DiscordenoGuild) => unknown;
/** When a guild goes unavailable this event will be ran. */
guildUnavailable?: (guild: DiscordenoGuild) => unknown;
/** Sent when a guilds integration gets updated */
guildIntegrationsUpdate?: (guild: DiscordenoGuild) => unknown;
/** Sent when a guild is updated. */
guildUpdate?: (
guild: DiscordenoGuild,
changes: GuildUpdateChange[]
changes: GuildUpdateChange[],
) => unknown;
/** Sent when a guild becomes or was already unavailable due to an outage, or when the user leaves or is removed from a guild. If the `unavailable` field is not set, the user was removed from the guild. */
guildDelete?: (guild: DiscordenoGuild) => unknown;
@@ -90,54 +100,54 @@ export interface EventHandlers {
guildEmojisUpdate?: (
guild: DiscordenoGuild,
emojis: Collection<string, Emoji>,
oldEmojis: Collection<string, Emoji>
oldEmojis: Collection<string, Emoji>,
) => unknown;
/** Sent when a new user joins a guild. */
guildMemberAdd?: (
guild: DiscordenoGuild,
member: DiscordenoMember
member: DiscordenoMember,
) => unknown;
/** Sent when a user is removed from a guild (leave/kick/ban). */
guildMemberRemove?: (
guild: DiscordenoGuild,
user: User,
member?: DiscordenoMember
member?: DiscordenoMember,
) => unknown;
/** Sent when a guild member is updated. This will also fire when the user object of a guild member changes. */
guildMemberUpdate?: (
guild: DiscordenoGuild,
member: DiscordenoMember,
oldMember?: DiscordenoMember
oldMember?: DiscordenoMember,
) => unknown;
// TODO: remove this?
//heartbeat?: () => unknown;
/** Sent when a user in a guild uses a Slash Command. */
interactionCreate?: (
data: Omit<Interaction, "member"> & { member: DiscordenoMember }
data: Omit<Interaction, "member"> & { member: DiscordenoMember },
) => unknown;
/** Sent when a message is created. */
messageCreate?: (message: DiscordenoMessage) => unknown;
/** Sent when a message is deleted. */
messageDelete?: (
partial: { id: string; channel: DiscordenoChannel },
message?: DiscordenoMessage
message?: DiscordenoMessage,
) => unknown;
/** Sent when a message is updated. */
messageUpdate?: (
message: DiscordenoMessage,
oldMessage: DiscordenoMessage
oldMessage: DiscordenoMessage,
) => unknown;
/** Sent when a user updates its nickname */
nicknameUpdate?: (
guild: DiscordenoGuild,
member: DiscordenoMember,
nickname: string,
oldNickname?: string
oldNickname?: string,
) => unknown;
/** A user's presence is their current state on a guild. This event is sent when a user's presence or info, such as name or avatar, is updated. */
presenceUpdate?: (
presence: PresenceUpdate,
oldPresence?: PerformanceEntry
oldPresence?: PresenceUpdate,
) => unknown;
/** Sent before every event execution. Discordeno will not await its execution. */
raw?: (data: GatewayPayload) => unknown;
@@ -148,22 +158,24 @@ export interface EventHandlers {
/** Sent when a user adds a reaction to a message. */
reactionAdd?: (
data: MessageReactionAdd,
member?: DiscordenoMember,
message?: DiscordenoMessage
message?: DiscordenoMessage,
) => unknown;
/** Sent when a user removes a reaction from a message. */
reactionRemove?: (
data: MessageReactionRemove,
message?: DiscordenoMessage
message?: DiscordenoMessage,
) => unknown;
/** Sent when a user explicitly removes all reactions from a message. */
reactionRemoveAll?: (payload: DiscordMessageReactionRemoveAll) => unknown;
reactionRemoveAll?: (
payload: MessageReactionRemoveAll,
message?: DiscordenoMessage,
) => unknown;
/** Sent when a bot removes all instances of a given emoji from the reactions of a message. */
reactionRemoveEmoji?: (
emoji: Partial<Emoji>,
messageId: string,
channelId: string,
guildId?: string
guildId?: string,
) => unknown;
/** Sent when a guild role is created. */
roleCreate?: (guild: DiscordenoGuild, role: DiscordenoRole) => unknown;
@@ -173,19 +185,24 @@ export interface EventHandlers {
roleUpdate?: (
guild: DiscordenoGuild,
role: DiscordenoRole,
old: DiscordenoRole
old: DiscordenoRole,
) => unknown;
roleGained?: (
guild: DiscordenoGuild,
member: DiscordenoMember,
roleId: string
roleId: string,
) => unknown;
roleLost?: (
guild: DiscordenoGuild,
member: DiscordenoMember,
roleId: string
roleId: string,
) => unknown;
shardReady?: (shardId: number) => unknown;
/** Sent when a shard failed to load. */
shardFailedToLoad?: (
shardId: number,
unavailableGuildIds: Set<string>,
) => unknown;
/** Sent when a user starts typing in a channel. */
typingStart?: (data: TypingStart) => unknown;
/** Sent when a user joins a voice channel */
@@ -196,24 +213,24 @@ export interface EventHandlers {
voiceChannelSwitch?: (
member: DiscordenoMember,
channelId: string,
oldChannelId: string
oldChannelId: string,
) => unknown;
/** Sent when a voice server is updated with information for making the bot connect to a voice channel. */
voiceServerUpdate?: (
payload: VoiceServerUpdate,
guild: DiscordenoGuild
guild: DiscordenoGuild,
) => unknown;
/** Sent when someone joins/leaves/moves voice channels. */
voiceStateUpdate?: (
member: DiscordenoMember,
voiceState: VoiceState
voiceState: VoiceState,
) => unknown;
/** Sent when a guild channel's webhook is created, updated, or deleted. */
webhooksUpdate?: (channelId: string, guildId: string) => unknown;
/** Sent when a member has passed the guild's Membership Screening requirements */
membershipScreeningPassed?: (
guild: DiscordenoGuild,
member: DiscordenoMember
member: DiscordenoMember,
) => unknown;
/** Sent when an integration is created on a server such as twitch, youtube etc.. */
integrationCreate?: (data: IntegrationCreateUpdate) => unknown;
+8
View File
@@ -22,3 +22,11 @@ export interface GuildMember {
/** https://discord.com/developers/docs/resources/guild#guild-member-object */
export type DiscordGuildMember = SnakeCasedPropertiesDeep<GuildMember>;
// We use these types much since user always exists unless its a `CREATE_MESSAGE` or `MESSAGE_UPDATE` event
export type GuildMemberWithUser = Omit<GuildMember, "user"> & { user: User };
/** https://discord.com/developers/docs/resources/guild#guild-member-object */
export type DiscordGuildMemberWithUser = SnakeCasedPropertiesDeep<
GuildMemberWithUser
>;
+2 -2
View File
@@ -1,7 +1,7 @@
import { GuildMember } from "../guilds/guild_member.ts";
import { GuildMemberWithUser } from "../guilds/guild_member.ts";
import { SnakeCasedPropertiesDeep } from "../util.ts";
export interface GuildMemberAdd extends GuildMember {
export interface GuildMemberAdd extends GuildMemberWithUser {
/** id of the guild */
guildId: string;
}
+2 -2
View File
@@ -1,4 +1,4 @@
import { GuildMember } from "../guilds/guild_member.ts";
import { GuildMemberWithUser } from "../guilds/guild_member.ts";
import { PresenceUpdate } from "../misc/presence_update.ts";
import { SnakeCasedPropertiesDeep } from "../util.ts";
@@ -6,7 +6,7 @@ export interface GuildMembersChunk {
/** The id of the guild */
guildId: string;
/** Set of guild members */
members: GuildMember[];
members: GuildMemberWithUser[];
/** The chunk index in the expected chunks for this response (0 <= chunk_index < chunk_count) */
chunkIndex: number;
/** The total number of expected chunks for this response */
+1 -1
View File
@@ -43,7 +43,7 @@ export interface Message {
* Users specifically mentioned in the message
* Note: The user objects in the mentions array will only have the partial member field present in `MESSAGE_CREATE` and `MESSAGE_UPDATE` events from text-based guild channels.
*/
mentions: User[];
mentions: (User & { member?: Partial<GuildMember> })[];
/** Roles specifically mentioned in this message */
mentionRoles: string[];
/**
+2 -2
View File
@@ -1,5 +1,5 @@
import { Emoji } from "../emojis/emoji.ts";
import { GuildMember } from "../guilds/guild_member.ts";
import { GuildMemberWithUser } from "../guilds/guild_member.ts";
import { SnakeCasedPropertiesDeep } from "../util.ts";
export interface MessageReactionAdd {
@@ -12,7 +12,7 @@ export interface MessageReactionAdd {
/** The id of the guild */
guildId?: string;
/** The member who reacted if this happened in a guild */
member?: GuildMember;
member?: GuildMemberWithUser;
/** The emoji used to react */
emoji: Partial<Emoji>;
}
+2 -2
View File
@@ -1,4 +1,4 @@
import { GuildMember } from "../guilds/guild_member.ts";
import { GuildMemberWithUser } from "../guilds/guild_member.ts";
import { SnakeCasedPropertiesDeep } from "../util.ts";
export interface VoiceState {
@@ -9,7 +9,7 @@ export interface VoiceState {
/** The user id this voice state is for */
userId: string;
/** The guild member this voice state is for */
member?: GuildMember;
member?: GuildMemberWithUser;
/** The session id for this voice state */
sessionId: string;
/** Whether this user is deafened by the server */