allow structures to be overriden

This commit is contained in:
Skillz
2020-09-12 11:03:27 -04:00
parent 6266b044f7
commit 035cb1360d
11 changed files with 107 additions and 73 deletions
+3 -3
View File
@@ -1,10 +1,10 @@
import { cache } from "../utils/cache.ts";
import { ChannelCreatePayload, ChannelTypes } from "../types/channel.ts";
import { createChannel } from "../structures/channel.ts";
import { eventHandlers } from "../module/client.ts";
import { structures } from "../structures/mod.ts";
export const handleInternalChannelCreate = (data: ChannelCreatePayload) => {
const channel = createChannel(data);
const channel = structures.createChannel(data);
cache.channels.set(channel.id, channel);
if (channel.guildID) {
const guild = cache.guilds.get(channel.guildID);
@@ -15,7 +15,7 @@ export const handleInternalChannelCreate = (data: ChannelCreatePayload) => {
export const handleInternalChannelUpdate = (data: ChannelCreatePayload) => {
const cachedChannel = cache.channels.get(data.id);
const channel = createChannel(data);
const channel = structures.createChannel(data);
cache.channels.set(channel.id, channel);
if (!cachedChannel) return;
+5 -5
View File
@@ -8,7 +8,6 @@ import { Errors } from "../types/errors.ts";
import { RequestManager } from "../module/requestManager.ts";
import { endpoints } from "../constants/discord.ts";
import { MessageCreateOptions } from "../types/message.ts";
import { createMessage } from "../structures/message.ts";
import {
GetMessagesAfter,
GetMessagesBefore,
@@ -20,6 +19,7 @@ import {
FollowedChannelPayload,
} from "../types/channel.ts";
import { logYellow } from "../utils/logger.ts";
import { structures } from "../structures/mod.ts";
/** Checks if a user id or a role id has permission in this channel */
export function hasChannelPermission(
@@ -63,7 +63,7 @@ export async function getMessage(channel: Channel, id: string) {
const result = await RequestManager.get(
endpoints.CHANNEL_MESSAGE(channel.id, id),
) as MessageCreateOptions;
return createMessage(result);
return structures.createMessage(result);
}
/** Fetches between 2-100 messages. Requires VIEW_CHANNEL and READ_MESSAGE_HISTORY */
@@ -97,7 +97,7 @@ export async function getMessages(
endpoints.CHANNEL_MESSAGES(channel.id),
options,
)) as MessageCreateOptions[];
return result.map((res) => createMessage(res));
return result.map((res) => structures.createMessage(res));
}
/** Get pinned messages in this channel. */
@@ -105,7 +105,7 @@ export async function getPins(channelID: string) {
const result = (await RequestManager.get(
endpoints.CHANNEL_PINS(channelID),
)) as MessageCreateOptions[];
return result.map((res) => createMessage(res));
return result.map((res) => structures.createMessage(res));
}
/** Send a message to the channel. Requires SEND_MESSAGES permission. */
@@ -177,7 +177,7 @@ export async function sendMessage(
},
);
return createMessage(result as MessageCreateOptions);
return structures.createMessage(result as MessageCreateOptions);
}
/** Delete messages from the channel. 2-100. Requires the MANAGE_MESSAGES permission */
+7 -12
View File
@@ -1,13 +1,8 @@
import { Guild } from "../structures/guild.ts";
import { createChannel } from "../structures/channel.ts";
import { formatImageURL } from "../utils/cdn.ts";
import { botHasPermission } from "../utils/permissions.ts";
import { RequestManager } from "../module/requestManager.ts";
import { endpoints } from "../constants/discord.ts";
import { Errors } from "../types/errors.ts";
import { Permissions, Permission } from "../types/permission.ts";
import {
@@ -32,15 +27,15 @@ import {
UserPayload,
} from "../types/guild.ts";
import { RoleData } from "../types/role.ts";
import { createRole } from "../structures/role.ts";
import { Intents } from "../types/options.ts";
import { identifyPayload } from "../module/client.ts";
import { requestAllMembers } from "../module/shardingManager.ts";
import { MemberCreatePayload } from "../types/member.ts";
import { cache } from "../utils/cache.ts";
import { createMember, Member } from "../structures/member.ts";
import { Member } from "../structures/member.ts";
import { urlToBase64 } from "../utils/utils.ts";
import { Collection } from "../utils/collection.ts";
import { structures } from "../structures/mod.ts";
/** Gets an array of all the channels ids that are the children of this category. */
export function categoryChildrenIDs(guild: Guild, id: string) {
@@ -120,7 +115,7 @@ export async function createGuildChannel(
type: options?.type || ChannelTypes.GUILD_TEXT,
})) as ChannelCreatePayload;
const channel = createChannel(result);
const channel = structures.createChannel(result);
guild.channels.set(result.id, channel);
return channel;
}
@@ -147,7 +142,7 @@ export async function getChannels(guildID: string, addToCache = true) {
endpoints.GUILD_CHANNELS(guildID),
) as ChannelCreatePayload[];
return result.map((res) => {
const channel = createChannel(res, guildID);
const channel = structures.createChannel(res, guildID);
if (addToCache) {
cache.channels.set(channel.id, channel);
}
@@ -163,7 +158,7 @@ export async function getChannel(channelID: string, addToCache = true) {
const result = await RequestManager.get(
endpoints.GUILD_CHANNEL(channelID),
) as ChannelCreatePayload;
const channel = createChannel(result, result.guild_id);
const channel = structures.createChannel(result, result.guild_id);
if (addToCache) cache.channels.set(channel.id, channel);
return channel;
}
@@ -194,7 +189,7 @@ export async function getMember(guildID: string, id: string) {
endpoints.GUILD_MEMBER(guildID, id),
) as MemberCreatePayload;
const member = createMember(data, guild);
const member = structures.createMember(data, guild);
guild.members.set(id, member);
return member;
}
@@ -300,7 +295,7 @@ export async function createGuildRole(
);
const roleData = result as RoleData;
const role = createRole(roleData);
const role = structures.createRole(roleData);
const guild = cache.guilds.get(guildID);
guild?.roles.set(role.id, role);
return role;
+2 -2
View File
@@ -13,9 +13,9 @@ import { Errors } from "../types/errors.ts";
import { RequestManager } from "../module/requestManager.ts";
import { MessageContent, DMChannelCreatePayload } from "../types/channel.ts";
import { cache } from "../utils/cache.ts";
import { createChannel } from "../structures/channel.ts";
import { EditMemberOptions } from "../types/member.ts";
import { sendMessage } from "./channel.ts";
import { structures } from "../structures/mod.ts";
/** The users custom avatar or the default avatar if you don't have a member object. */
export function rawAvatarURL(
@@ -108,7 +108,7 @@ export async function sendDirectMessage(
) as DMChannelCreatePayload;
// Channel create event will have added this channel to the cache
cache.channels.delete(dmChannelData.id);
const channel = createChannel(dmChannelData);
const channel = structures.createChannel(dmChannelData);
// Recreate the channel and add it undert he users id
cache.channels.set(memberID, channel);
dmChannel = channel;
+4 -3
View File
@@ -1,4 +1,4 @@
import { Message, createMessage } from "../structures/message.ts";
import { Message } from "../structures/message.ts";
import { delay } from "https://deno.land/std@0.67.0/async/delay.ts";
import { botID } from "../module/client.ts";
import { Permissions } from "../types/permission.ts";
@@ -9,6 +9,7 @@ import { botHasChannelPermissions } from "../utils/permissions.ts";
import { MessageContent } from "../types/channel.ts";
import { UserPayload } from "../types/guild.ts";
import { MessageCreateOptions } from "../types/message.ts";
import { structures } from "../structures/mod.ts";
/** Delete a message */
export async function deleteMessage(
@@ -221,7 +222,7 @@ export async function editMessage(
endpoints.CHANNEL_MESSAGE(message.channelID, message.id),
content,
);
return createMessage(result as MessageCreateOptions);
return structures.createMessage(result as MessageCreateOptions);
}
export async function publishMessage(channelID: string, messageID: string) {
@@ -229,5 +230,5 @@ export async function publishMessage(channelID: string, messageID: string) {
endpoints.CHANNEL_MESSAGE_CROSSPOST(channelID, messageID),
) as MessageCreateOptions;
return createMessage(data);
return structures.createMessage(data);
}
+2 -2
View File
@@ -8,9 +8,9 @@ import { Permissions } from "../types/permission.ts";
import { Errors } from "../types/errors.ts";
import { RequestManager } from "../module/requestManager.ts";
import { endpoints } from "../constants/discord.ts";
import { createMessage } from "../structures/message.ts";
import { MessageCreateOptions } from "../types/message.ts";
import { urlToBase64 } from "../utils/utils.ts";
import { structures } from "../structures/mod.ts";
/** Create a new webhook. Requires the MANAGE_WEBHOOKS permission. Returns a webhook object on success. Webhook names follow our naming restrictions that can be found in our Usernames and Nicknames documentation, with the following additional stipulations:
*
@@ -98,7 +98,7 @@ export async function executeWebhook(
);
if (!options.wait) return;
return createMessage(result as MessageCreateOptions);
return structures.createMessage(result as MessageCreateOptions);
}
export function getWebhook(webhookID: string) {
+21 -15
View File
@@ -23,7 +23,7 @@ import {
handleInternalChannelDelete,
} from "../events/channels.ts";
import { ChannelCreatePayload } from "../types/channel.ts";
import { createGuild, Guild } from "../structures/guild.ts";
import { Guild } from "../structures/guild.ts";
import {
CreateGuildPayload,
GuildDeletePayload,
@@ -43,8 +43,6 @@ import {
handleInternalGuildDelete,
} from "../events/guilds.ts";
import { cache } from "../utils/cache.ts";
import { createMember } from "../structures/member.ts";
import { createRole } from "../structures/role.ts";
import {
MessageCreateOptions,
MessageDeletePayload,
@@ -53,7 +51,6 @@ import {
BaseMessageReactionPayload,
MessageReactionRemoveEmojiPayload,
} from "../types/message.ts";
import { createMessage } from "../structures/message.ts";
import { GuildUpdateChange } from "../types/options.ts";
import {
createBasicShard,
@@ -61,6 +58,7 @@ import {
botGatewayStatusRequest,
} from "./basicShard.ts";
import { BotStatusRequest } from "../utils/utils.ts";
import { structures } from "../structures/mod.ts";
let shardCounter = 0;
let basicSharding = false;
@@ -176,7 +174,10 @@ export async function handleDiscordPayload(
return;
}
const guild = createGuild(data.d as CreateGuildPayload, shardID);
const guild = structures.createGuild(
data.d as CreateGuildPayload,
shardID,
);
handleInternalGuildCreate(guild);
if (cache.unavailableGuilds.get(options.id)) {
cache.unavailableGuilds.delete(options.id);
@@ -278,7 +279,7 @@ export async function handleDiscordPayload(
const memberCount = guild.memberCount + 1;
guild.memberCount = memberCount;
const member = createMember(
const member = structures.createMember(
options,
guild,
);
@@ -318,7 +319,7 @@ export async function handleDiscordPayload(
deaf: cachedMember?.deaf || false,
mute: cachedMember?.mute || false,
};
const member = createMember(
const member = structures.createMember(
newMemberData,
guild,
);
@@ -357,7 +358,7 @@ export async function handleDiscordPayload(
options.members.forEach((member) => {
guild.members.set(
member.user.id,
createMember(
structures.createMember(
member,
guild,
),
@@ -398,7 +399,7 @@ export async function handleDiscordPayload(
if (!guild) return;
if (data.t === "GUILD_ROLE_CREATE") {
const role = createRole(options.role);
const role = structures.createRole(options.role);
const roles = guild.roles.set(options.role.id, role);
guild.roles = roles;
return eventHandlers.roleCreate?.(guild, role);
@@ -408,7 +409,7 @@ export async function handleDiscordPayload(
if (!cachedRole) return;
if (data.t === "GUILD_ROLE_UPDATE") {
const role = createRole(options.role);
const role = structures.createRole(options.role);
return eventHandlers.roleUpdate?.(guild, role, cachedRole);
}
}
@@ -418,7 +419,7 @@ export async function handleDiscordPayload(
const channel = cache.channels.get(options.channel_id);
if (channel) channel.lastMessageID = options.id;
const message = createMessage(options);
const message = structures.createMessage(options);
// Cache the message
cache.messages.set(options.id, message);
const guild = options.guild_id
@@ -429,7 +430,7 @@ export async function handleDiscordPayload(
// If in a guild cache the author as a member
guild?.members.set(
options.author.id,
createMember(
structures.createMember(
{ ...options.member, user: options.author },
guild,
),
@@ -441,7 +442,10 @@ export async function handleDiscordPayload(
if (mention.member) {
guild?.members.set(
mention.id,
createMember({ ...mention.member, user: mention }, guild),
structures.createMember(
{ ...mention.member, user: mention },
guild,
),
);
}
});
@@ -533,7 +537,7 @@ export async function handleDiscordPayload(
const guild = cache.guilds.get(options.guild_id);
guild?.members.set(
options.member.user.id,
createMember(
structures.createMember(
options.member,
guild,
),
@@ -608,7 +612,9 @@ export async function handleDiscordPayload(
if (!guild) return;
const member = guild.members.get(payload.user_id) ||
(payload.member ? createMember(payload.member, guild) : undefined);
(payload.member
? structures.createMember(payload.member, guild)
: undefined);
if (!member) return;
// No cached state before so lets make one for em
+9 -8
View File
@@ -1,10 +1,9 @@
import { CreateGuildPayload } from "../types/guild.ts";
import { Collection } from "../utils/collection.ts";
import { createRole } from "./role.ts";
import { createMember, Member } from "./member.ts";
import { createChannel } from "./channel.ts";
import { structures } from "./mod.ts";
import { Member } from "./member.ts";
export const createGuild = (data: CreateGuildPayload, shardID: number) => {
export function createGuild(data: CreateGuildPayload, shardID: number) {
const {
owner_id: ownerID,
afk_channel_id: afkChannelID,
@@ -60,14 +59,16 @@ export const createGuild = (data: CreateGuildPayload, shardID: number) => {
preferredLocale,
/** The roles in the guild */
roles: new Collection(data.roles.map((r) => [r.id, createRole(r)])),
roles: new Collection(
data.roles.map((r) => [r.id, structures.createRole(r)]),
),
/** When this guild was joined at. */
joinedAt: Date.parse(joinedAt),
/** The users in this guild. */
members: new Collection<string, Member>(),
/** The channels in the guild */
channels: new Collection(
data.channels.map((c) => [c.id, createChannel(c, data.id)]),
data.channels.map((c) => [c.id, structures.createChannel(c, data.id)]),
),
/** The presences of all the users in the guild. */
presences: new Collection(data.presences.map((p) => [p.user.id, p])),
@@ -87,10 +88,10 @@ export const createGuild = (data: CreateGuildPayload, shardID: number) => {
};
data.members.forEach((m) =>
guild.members.set(m.user.id, createMember(m, guild))
guild.members.set(m.user.id, structures.createMember(m, guild))
);
return guild;
};
}
export interface Guild extends ReturnType<typeof createGuild> {}
+20 -18
View File
@@ -1,16 +1,27 @@
import { MemberCreatePayload } from "../types/member.ts";
import { Guild } from "./guild.ts";
import { cache } from "../utils/cache.ts";
export const createMember = (data: MemberCreatePayload, guild: Guild) => {
export function createMember(data: MemberCreatePayload, guild: Guild) {
const {
joined_at: joinedAt,
premium_since: premiumSince,
...rest
} = data;
const {
mfa_enabled: mfaEnabled,
premium_type: premiumType,
...user
} = data.user;
const member = {
...data,
...rest,
// Only use those that we have not removed above
user: user,
/** When the user joined the guild */
joinedAt: Date.parse(data.joined_at),
joinedAt: Date.parse(joinedAt),
/** When the user used their nitro boost on the server. */
premiumSince: data.premium_since
? Date.parse(data.premium_since)
: undefined,
premiumSince: premiumSince ? Date.parse(premiumSince) : undefined,
/** The full username#discriminator */
tag: `${data.user.username}#${data.user.discriminator}`,
/** The user mention with nickname if possible */
@@ -18,20 +29,11 @@ export const createMember = (data: MemberCreatePayload, guild: Guild) => {
/** The guild id where this member exists */
guildID: guild.id,
/** Whether or not this user has 2FA enabled. */
mfaEnabled: data.user.mfa_enabled,
mfaEnabled,
/** The premium type for this user */
premiumType: data.user.premium_type,
/** Gets the guild object from cache for this member. This is a method instead of a prop to preserve memory. */
guild: () => cache.guilds.get(guild.id)!,
premiumType,
};
// Remove excess properties to preserve cache.
// delete member.joined_at;
// delete member.premium_since;
// delete member.user.mfa_enabled;
// delete member.user.premium_type;
return member;
};
+27
View File
@@ -0,0 +1,27 @@
import { createChannel } from "./channel.ts";
import { createGuild } from "./guild.ts";
import { createMember } from "./member.ts";
import { createMessage } from "./message.ts";
import { createRole } from "./role.ts";
/** This is the placeholder where the structure creation functions are kept. */
export let structures = {
createChannel,
createGuild,
createMember,
createMessage,
createRole,
};
export type Structures = typeof structures[keyof typeof structures];
/** This function is used to update/reload/customize the internal structure of Discordeno.
*
* ⚠️ **ADVANCED USE ONLY: If you customize this in a wrong way, you could potentially create many new errors/bugs. Please take caution when using this.
*/
export function updateStructures(newStructures: Structures) {
structures = {
...structures,
...newStructures,
};
}
+4 -2
View File
@@ -1,9 +1,11 @@
import { RoleData } from "../types/role.ts";
export const createRole = (data: RoleData) => ({
export function createRole(data: RoleData) {
return {
...data,
/** The @ mention of the role in a string. */
mention: `<@&${data.id}>`,
});
};
}
export interface Role extends ReturnType<typeof createRole> {}