refactor!: fix some spelling mistakes (#2144)

* refactor!: fix some spelling mistakes
This fixes some spelling mistakes around the code base. Note not all are fixed.

* subComponent
This commit is contained in:
ITOH
2022-03-31 14:16:34 +02:00
committed by GitHub
parent bcaa43ab7d
commit 9980856eef
50 changed files with 493 additions and 370 deletions
+4 -4
View File
@@ -55,7 +55,7 @@ import { transformAttachment } from "./transformers/attachment.ts";
import { transformEmbed } from "./transformers/embed.ts"; import { transformEmbed } from "./transformers/embed.ts";
import { transformComponent } from "./transformers/component.ts"; import { transformComponent } from "./transformers/component.ts";
import { transformWebhook } from "./transformers/webhook.ts"; import { transformWebhook } from "./transformers/webhook.ts";
import { transformAuditlogEntry } from "./transformers/auditlogEntry.ts"; import { transformAuditLogEntry } from "./transformers/auditLogEntry.ts";
import { transformApplicationCommandPermission } from "./transformers/applicationCommandPermission.ts"; import { transformApplicationCommandPermission } from "./transformers/applicationCommandPermission.ts";
import { calculateBits, calculatePermissions } from "./util/permissions.ts"; import { calculateBits, calculatePermissions } from "./util/permissions.ts";
import { transformScheduledEvent } from "./transformers/scheduledEvent.ts"; import { transformScheduledEvent } from "./transformers/scheduledEvent.ts";
@@ -120,7 +120,7 @@ import { Embed } from "./transformers/embed.ts";
import { Webhook } from "./transformers/webhook.ts"; import { Webhook } from "./transformers/webhook.ts";
import { Component } from "./transformers/component.ts"; import { Component } from "./transformers/component.ts";
import { ApplicationCommand } from "./transformers/applicationCommand.ts"; import { ApplicationCommand } from "./transformers/applicationCommand.ts";
import { AuditLogEntry } from "./transformers/auditlogEntry.ts"; import { AuditLogEntry } from "./transformers/auditLogEntry.ts";
import { ApplicationCommandOption } from "./transformers/applicationCommandOption.ts"; import { ApplicationCommandOption } from "./transformers/applicationCommandOption.ts";
import { ApplicationCommandPermission } from "./transformers/applicationCommandPermission.ts"; import { ApplicationCommandPermission } from "./transformers/applicationCommandPermission.ts";
import { WelcomeScreen } from "./transformers/welcomeScreen.ts"; import { WelcomeScreen } from "./transformers/welcomeScreen.ts";
@@ -411,7 +411,7 @@ export interface Transformers {
embed: (bot: Bot, payload: DiscordEmbed) => Embed; embed: (bot: Bot, payload: DiscordEmbed) => Embed;
component: (bot: Bot, payload: DiscordComponent) => Component; component: (bot: Bot, payload: DiscordComponent) => Component;
webhook: (bot: Bot, payload: DiscordWebhook) => Webhook; webhook: (bot: Bot, payload: DiscordWebhook) => Webhook;
auditlogEntry: (bot: Bot, payload: DiscordAuditLogEntry) => AuditLogEntry; auditLogEntry: (bot: Bot, payload: DiscordAuditLogEntry) => AuditLogEntry;
applicationCommand: (bot: Bot, payload: DiscordApplicationCommand) => ApplicationCommand; applicationCommand: (bot: Bot, payload: DiscordApplicationCommand) => ApplicationCommand;
applicationCommandOption: (bot: Bot, payload: DiscordApplicationCommandOption) => ApplicationCommandOption; applicationCommandOption: (bot: Bot, payload: DiscordApplicationCommandOption) => ApplicationCommandOption;
applicationCommandPermission: ( applicationCommandPermission: (
@@ -460,7 +460,7 @@ export function createTransformers(options: Partial<Transformers>) {
voiceState: options.voiceState || transformVoiceState, voiceState: options.voiceState || transformVoiceState,
snowflake: options.snowflake || snowflakeToBigint, snowflake: options.snowflake || snowflakeToBigint,
webhook: options.webhook || transformWebhook, webhook: options.webhook || transformWebhook,
auditlogEntry: options.auditlogEntry || transformAuditlogEntry, auditLogEntry: options.auditLogEntry || transformAuditLogEntry,
applicationCommand: options.applicationCommand || applicationCommand: options.applicationCommand ||
transformApplicationCommand, transformApplicationCommand,
applicationCommandOption: options.applicationCommandOption || applicationCommandOption: options.applicationCommandOption ||
+1 -1
View File
@@ -27,7 +27,7 @@ export function createShard(gateway: GatewayManager, shardId: number) {
return; return;
case 3063: // Resharded case 3063: // Resharded
case 3064: // Resuming case 3064: // Resuming
case 3065: // Reidentifying case 3065: // Re-identifying
case 3066: // Missing ACK case 3066: // Missing ACK
// Will restart shard manually // Will restart shard manually
return gateway.debug("GW CLOSED_RECONNECT", { shardId, payload: event }); return gateway.debug("GW CLOSED_RECONNECT", { shardId, payload: event });
+1 -1
View File
@@ -73,7 +73,7 @@ export async function handleOnMessage(gateway: GatewayManager, message: any, sha
// We need to wait for a random amount of time between 1 and 5: https://discord.com/developers/docs/topics/gateway#resuming // We need to wait for a random amount of time between 1 and 5: https://discord.com/developers/docs/topics/gateway#resuming
await delay(Math.floor((Math.random() * 4 + 1) * 1000)); await delay(Math.floor((Math.random() * 4 + 1) * 1000));
// When d is false we need to reidentify // When d is false we need to re-identify
if (!messageData.d) { if (!messageData.d) {
await gateway.identify(gateway, shardId, gateway.maxShards); await gateway.identify(gateway, shardId, gateway.maxShards);
break; break;
+1 -1
View File
@@ -7,7 +7,7 @@ export function identify(gateway: GatewayManager, shardId: number, maxShards: nu
// Need to clear the old heartbeat interval // Need to clear the old heartbeat interval
const oldShard = gateway.shards.get(shardId); const oldShard = gateway.shards.get(shardId);
if (oldShard) { if (oldShard) {
gateway.closeWS(oldShard.ws, 3065, "Reidentifying closure of old shard"); gateway.closeWS(oldShard.ws, 3065, "Re-identifying closure of old shard");
clearInterval(oldShard.heartbeat.intervalId); clearInterval(oldShard.heartbeat.intervalId);
} }
+6 -6
View File
@@ -36,7 +36,7 @@ export async function resharder(
} }
// USE ANY CUSTOMIZED OPTIONS FROM OLD GATEWAY // USE ANY CUSTOMIZED OPTIONS FROM OLD GATEWAY
// @ts-ignore TODO: fix this dynamica assignment // @ts-ignore TODO: fix this dynamical assignment
gateway[key] = oldGateway[key as keyof typeof oldGateway]; gateway[key] = oldGateway[key as keyof typeof oldGateway];
} }
@@ -83,7 +83,7 @@ export async function resharder(
}) as Promise<GatewayManager>; }) as Promise<GatewayManager>;
} }
/** Handler that by default will check all new shards are online in the new gateway. The handler can be overriden if you have multiple servers to communicate through redis pubsub or whatever you prefer. */ /** Handler that by default will check all new shards are online in the new gateway. The handler can be overridden if you have multiple servers to communicate through redis pubsub or whatever you prefer. */
export async function resharderIsPending( export async function resharderIsPending(
gateway: GatewayManager, gateway: GatewayManager,
oldGateway: GatewayManager, oldGateway: GatewayManager,
@@ -98,7 +98,7 @@ export async function resharderIsPending(
return false; return false;
} }
/** Handler that by default closes all shards in the old gateway. Can be overriden if you have multiple servers and you want to communicate through redis pubsub or whatever you prefer. */ /** Handler that by default closes all shards in the old gateway. Can be overridden if you have multiple servers and you want to communicate through redis pubsub or whatever you prefer. */
export async function resharderCloseOldShards(oldGateway: GatewayManager) { export async function resharderCloseOldShards(oldGateway: GatewayManager) {
// SHUT DOWN ALL SHARDS IF NOTHING IN QUEUE // SHUT DOWN ALL SHARDS IF NOTHING IN QUEUE
oldGateway.shards.forEach((shard) => { oldGateway.shards.forEach((shard) => {
@@ -122,7 +122,7 @@ export async function resharderCloseOldShards(oldGateway: GatewayManager) {
}); });
} }
/** Handler that by default will check to see if resharding should occur. Can be overriden if you have multiple servers and you want to communicate through redis pubsub or whatever you prefer. */ /** Handler that by default will check to see if resharding should occur. Can be overridden if you have multiple servers and you want to communicate through redis pubsub or whatever you prefer. */
export async function startReshardingChecks(gateway: GatewayManager) { export async function startReshardingChecks(gateway: GatewayManager) {
gateway.debug("GW DEBUG", "[Resharding] Checking if resharding is needed."); gateway.debug("GW DEBUG", "[Resharding] Checking if resharding is needed.");
@@ -144,9 +144,9 @@ export async function startReshardingChecks(gateway: GatewayManager) {
return gateway.resharding.resharder(gateway, results); return gateway.resharding.resharder(gateway, results);
} }
/** Handler that by default will save the new shard id for each guild this becomes ready in new gateway. This can be overriden to save the shard ids in a redis cache layer or whatever you prefer. These ids will be used later to update all guilds. */ /** Handler that by default will save the new shard id for each guild this becomes ready in new gateway. This can be overridden to save the shard ids in a redis cache layer or whatever you prefer. These ids will be used later to update all guilds. */
export async function markNewGuildShardId(guildIds: bigint[], shardId: number) { export async function markNewGuildShardId(guildIds: bigint[], shardId: number) {
// PLACEHOLDER TO LET YOU MARK A GUILD ID AND SHARDID FOR LATER USE ONCE RESHARDED // PLACEHOLDER TO LET YOU MARK A GUILD ID AND SHARD ID FOR LATER USE ONCE RESHARDED
} }
/** Handler that by default does not do anything since by default the library will not cache. */ /** Handler that by default does not do anything since by default the library will not cache. */
+1 -1
View File
@@ -30,7 +30,7 @@ export interface DiscordenoShard {
/** The id of the interval, useful for stopping the interval if ws closed. */ /** The id of the interval, useful for stopping the interval if ws closed. */
intervalId: number; intervalId: number;
}; };
/** The items/requestst that are in queue to be sent to this shard websocket. */ /** The items/requests that are in queue to be sent to this shard websocket. */
queue: WebSocketRequest[]; queue: WebSocketRequest[];
/** Whether or not the queue for this shard is being processed. */ /** Whether or not the queue for this shard is being processed. */
processingQueue: boolean; processingQueue: boolean;
+1 -1
View File
@@ -5,7 +5,7 @@ import { OverwriteReadable } from "./editChannelOverwrite.ts";
/** Create a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */ /** Create a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */
export async function createChannel(bot: Bot, guildId: bigint, options?: CreateGuildChannel, reason?: string) { export async function createChannel(bot: Bot, guildId: bigint, options?: CreateGuildChannel, reason?: string) {
// BITRATES ARE IN THOUSANDS SO IF USER PROVIDES 32 WE CONVERT TO 32000 // BITRATE IS IN THOUSANDS SO IF USER PROVIDES 32 WE CONVERT TO 32000
if (options?.bitrate && options.bitrate < 1000) options.bitrate *= 1000; if (options?.bitrate && options.bitrate < 1000) options.bitrate *= 1000;
const result = await bot.rest.runMethod<DiscordChannel>( const result = await bot.rest.runMethod<DiscordChannel>(
+1 -1
View File
@@ -9,7 +9,7 @@ export async function editChannel(bot: Bot, channelId: bigint, options: ModifyCh
if (options.name || options.topic) { if (options.name || options.topic) {
const request = editChannelNameTopicQueue.get(channelId); const request = editChannelNameTopicQueue.get(channelId);
if (!request) { if (!request) {
// If this hasnt been done before simply add 1 for it // If this hasn't been done before simply add 1 for it
editChannelNameTopicQueue.set(channelId, { editChannelNameTopicQueue.set(channelId, {
channelId: channelId, channelId: channelId,
amount: 1, amount: 1,
+1 -1
View File
@@ -33,7 +33,7 @@ export async function editDiscovery(bot: Bot, guildId: bigint, data: ModifyGuild
export interface ModifyGuildDiscoveryMetadata { export interface ModifyGuildDiscoveryMetadata {
/** The id of the primary discovery category. Default: 0 */ /** The id of the primary discovery category. Default: 0 */
primaryCategoryId?: number | null; primaryCategoryId?: number | null;
/** Up to 10 discovery search kekywords. Default: null */ /** Up to 10 discovery search keywords. Default: null */
keywords?: string[] | null; keywords?: string[] | null;
/** Whether guild info is shown when custom emojis are clicked. Default: true */ /** Whether guild info is shown when custom emojis are clicked. Default: true */
emojiDiscoverabilityEnabled?: boolean | null; emojiDiscoverabilityEnabled?: boolean | null;
+1 -1
View File
@@ -24,7 +24,7 @@ export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuild
return { return {
users: auditlog.users.map((user) => bot.transformers.user(bot, user)), users: auditlog.users.map((user) => bot.transformers.user(bot, user)),
webhook: auditlog.webhooks.map((hook) => bot.transformers.webhook(bot, hook)), webhook: auditlog.webhooks.map((hook) => bot.transformers.webhook(bot, hook)),
auditLogEntries: auditlog.audit_log_entries.map((entry) => bot.transformers.auditlogEntry(bot, entry)), auditLogEntries: auditlog.audit_log_entries.map((entry) => bot.transformers.auditLogEntry(bot, entry)),
integrations: auditlog.integrations.map((integration) => ({ integrations: auditlog.integrations.map((integration) => ({
id: integration.id ? bot.transformers.snowflake(integration.id) : undefined, id: integration.id ? bot.transformers.snowflake(integration.id) : undefined,
name: integration.name, name: integration.name,
@@ -42,27 +42,27 @@ export async function editInteractionResponse(
})), })),
components: options.components?.map((component) => ({ components: options.components?.map((component) => ({
type: component.type, type: component.type,
components: component.components.map((subcomponent) => { components: component.components.map((subComponent) => {
if (subcomponent.type === MessageComponentTypes.InputText) { if (subComponent.type === MessageComponentTypes.InputText) {
return { return {
type: subcomponent.type, type: subComponent.type,
style: subcomponent.style, style: subComponent.style,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_length: subcomponent.minLength ?? subcomponent.required === false ? 0 : subcomponent.minLength, min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subcomponent.maxLength, max_length: subComponent.maxLength,
}; };
} }
if (subcomponent.type === MessageComponentTypes.SelectMenu) { if (subComponent.type === MessageComponentTypes.SelectMenu) {
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_values: subcomponent.minValues, min_values: subComponent.minValues,
max_values: subcomponent.maxValues, max_values: subComponent.maxValues,
options: subcomponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
description: option.description, description: option.description,
@@ -79,19 +79,19 @@ export async function editInteractionResponse(
} }
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
style: subcomponent.style, style: subComponent.style,
emoji: "emoji" in subcomponent && subcomponent.emoji emoji: "emoji" in subComponent && subComponent.emoji
? { ? {
id: subcomponent.emoji.id?.toString(), id: subComponent.emoji.id?.toString(),
name: subcomponent.emoji.name, name: subComponent.emoji.name,
animated: subcomponent.emoji.animated, animated: subComponent.emoji.animated,
} }
: undefined, : undefined,
url: "url" in subcomponent ? subcomponent.url : undefined, url: "url" in subComponent ? subComponent.url : undefined,
disabled: "disabled" in subcomponent ? subcomponent.disabled : undefined, disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
}; };
}), }),
})), })),
@@ -39,27 +39,27 @@ export async function editFollowupMessage(
})), })),
components: options.components?.map((component) => ({ components: options.components?.map((component) => ({
type: component.type, type: component.type,
components: component.components.map((subcomponent) => { components: component.components.map((subComponent) => {
if (subcomponent.type === MessageComponentTypes.InputText) { if (subComponent.type === MessageComponentTypes.InputText) {
return { return {
type: subcomponent.type, type: subComponent.type,
style: subcomponent.style, style: subComponent.style,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_length: subcomponent.minLength ?? subcomponent.required === false ? 0 : subcomponent.minLength, min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subcomponent.maxLength, max_length: subComponent.maxLength,
}; };
} }
if (subcomponent.type === MessageComponentTypes.SelectMenu) { if (subComponent.type === MessageComponentTypes.SelectMenu) {
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_values: subcomponent.minValues, min_values: subComponent.minValues,
max_values: subcomponent.maxValues, max_values: subComponent.maxValues,
options: subcomponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
description: option.description, description: option.description,
@@ -76,19 +76,19 @@ export async function editFollowupMessage(
} }
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
style: subcomponent.style, style: subComponent.style,
emoji: subcomponent.emoji emoji: subComponent.emoji
? { ? {
id: subcomponent.emoji.id?.toString(), id: subComponent.emoji.id?.toString(),
name: subcomponent.emoji.name, name: subComponent.emoji.name,
animated: subcomponent.emoji.animated, animated: subComponent.emoji.animated,
} }
: undefined, : undefined,
url: subcomponent.url, url: subComponent.url,
disabled: subcomponent.disabled, disabled: subComponent.disabled,
}; };
}), }),
})), })),
+29 -29
View File
@@ -37,27 +37,27 @@ export async function sendInteractionResponse(
title: options.data.title, title: options.data.title,
components: options.data.components?.map((component) => ({ components: options.data.components?.map((component) => ({
type: component.type, type: component.type,
components: component.components.map((subcomponent) => { components: component.components.map((subComponent) => {
if (subcomponent.type === MessageComponentTypes.InputText) { if (subComponent.type === MessageComponentTypes.InputText) {
return { return {
type: subcomponent.type, type: subComponent.type,
style: subcomponent.style, style: subComponent.style,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_length: subcomponent.minLength ?? subcomponent.required === false ? 0 : subcomponent.minLength, min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subcomponent.maxLength, max_length: subComponent.maxLength,
}; };
} }
if (subcomponent.type === MessageComponentTypes.SelectMenu) { if (subComponent.type === MessageComponentTypes.SelectMenu) {
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_values: subcomponent.minValues, min_values: subComponent.minValues,
max_values: subcomponent.maxValues, max_values: subComponent.maxValues,
options: subcomponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
description: option.description, description: option.description,
@@ -74,19 +74,19 @@ export async function sendInteractionResponse(
} }
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
style: subcomponent.style, style: subComponent.style,
emoji: "emoji" in subcomponent && subcomponent.emoji emoji: "emoji" in subComponent && subComponent.emoji
? { ? {
id: subcomponent.emoji.id?.toString(), id: subComponent.emoji.id?.toString(),
name: subcomponent.emoji.name, name: subComponent.emoji.name,
animated: subcomponent.emoji.animated, animated: subComponent.emoji.animated,
} }
: undefined, : undefined,
url: "url" in subcomponent ? subcomponent.url : undefined, url: "url" in subComponent ? subComponent.url : undefined,
disabled: "disabled" in subcomponent ? subcomponent.disabled : undefined, disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
}; };
}), }),
})), })),
@@ -130,7 +130,7 @@ export interface InteractionResponse {
export interface InteractionApplicationCommandCallbackData { export interface InteractionApplicationCommandCallbackData {
/** The message contents (up to 2000 characters) */ /** The message contents (up to 2000 characters) */
content?: string; content?: string;
/** true if this is a TTS message */ /** True if this is a TTS message */
tts?: boolean; tts?: boolean;
/** Embedded `rich` content (up to 6000 characters) */ /** Embedded `rich` content (up to 6000 characters) */
embeds?: Embed[]; embeds?: Embed[];
@@ -144,9 +144,9 @@ export interface InteractionApplicationCommandCallbackData {
title?: string; title?: string;
/** The components you would like to have sent in this message */ /** The components you would like to have sent in this message */
components?: MessageComponents; components?: MessageComponents;
/** message flags combined as a bitfield (only SUPPRESS_EMBEDS and EPHEMERAL can be set) */ /** Message flags combined as a bit field (only SUPPRESS_EMBEDS and EPHEMERAL can be set) */
flags?: number; flags?: number;
/** autocomplete choices (max of 25 choices) */ /** Autocomplete choices (max of 25 choices) */
choices?: ApplicationCommandOptionChoice[]; choices?: ApplicationCommandOptionChoice[];
} }
+1 -1
View File
@@ -42,7 +42,7 @@ export interface CreateChannelInvite {
maxUses?: number; maxUses?: number;
/** Whether this invite only grants temporary membership. Default: false */ /** Whether this invite only grants temporary membership. Default: false */
temporary?: boolean; temporary?: boolean;
/** If true, don't try to reuse simmilar invite (useful for creating many unique one time use invites). Default: false */ /** If true, don't try to reuse similar invite (useful for creating many unique one time use invites). Default: false */
unique?: boolean; unique?: boolean;
/** The type of target for this voice channel invite */ /** The type of target for this voice channel invite */
targetType?: InviteTargetTypes; targetType?: InviteTargetTypes;
+27 -27
View File
@@ -33,27 +33,27 @@ export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint
file: content.file, file: content.file,
components: content.components?.map((component) => ({ components: content.components?.map((component) => ({
type: component.type, type: component.type,
components: component.components.map((subcomponent) => { components: component.components.map((subComponent) => {
if (subcomponent.type === MessageComponentTypes.InputText) { if (subComponent.type === MessageComponentTypes.InputText) {
return { return {
type: subcomponent.type, type: subComponent.type,
style: subcomponent.style, style: subComponent.style,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_length: subcomponent.minLength ?? subcomponent.required === false ? 0 : subcomponent.minLength, min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subcomponent.maxLength, max_length: subComponent.maxLength,
}; };
} }
if (subcomponent.type === MessageComponentTypes.SelectMenu) { if (subComponent.type === MessageComponentTypes.SelectMenu) {
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_values: subcomponent.minValues, min_values: subComponent.minValues,
max_values: subcomponent.maxValues, max_values: subComponent.maxValues,
options: subcomponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
description: option.description, description: option.description,
@@ -70,19 +70,19 @@ export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint
} }
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
style: subcomponent.style, style: subComponent.style,
emoji: "emoji" in subcomponent && subcomponent.emoji emoji: "emoji" in subComponent && subComponent.emoji
? { ? {
id: subcomponent.emoji.id?.toString(), id: subComponent.emoji.id?.toString(),
name: subcomponent.emoji.name, name: subComponent.emoji.name,
animated: subcomponent.emoji.animated, animated: subComponent.emoji.animated,
} }
: undefined, : undefined,
url: "url" in subcomponent ? subcomponent.url : undefined, url: "url" in subComponent ? subComponent.url : undefined,
disabled: "disabled" in subcomponent ? subcomponent.disabled : undefined, disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
}; };
}), }),
})), })),
@@ -98,7 +98,7 @@ export interface EditMessage {
content?: string | null; content?: string | null;
/** Embedded `rich` content (up to 6000 characters) */ /** Embedded `rich` content (up to 6000 characters) */
embeds?: Embed[] | null; embeds?: Embed[] | null;
/** Edit the flags of the message (only `SUPRESS_EMBEDS` can currently be set/unset) */ /** Edit the flags of the message (only `SUPPRESS_EMBEDS` can currently be set/unset) */
flags?: 4 | null; flags?: 4 | null;
/** The contents of the file being sent/edited */ /** The contents of the file being sent/edited */
file?: FileContent | FileContent[] | null; file?: FileContent | FileContent[] | null;
+26 -26
View File
@@ -25,27 +25,27 @@ export async function sendMessage(bot: Bot, channelId: bigint, content: CreateMe
file: content.file, file: content.file,
components: content.components?.map((component) => ({ components: content.components?.map((component) => ({
type: component.type, type: component.type,
components: component.components.map((subcomponent) => { components: component.components.map((subComponent) => {
if (subcomponent.type === MessageComponentTypes.InputText) { if (subComponent.type === MessageComponentTypes.InputText) {
return { return {
type: subcomponent.type, type: subComponent.type,
style: subcomponent.style, style: subComponent.style,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_length: subcomponent.minLength ?? subcomponent.required === false ? 0 : subcomponent.minLength, min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subcomponent.maxLength, max_length: subComponent.maxLength,
}; };
} }
if (subcomponent.type === MessageComponentTypes.SelectMenu) { if (subComponent.type === MessageComponentTypes.SelectMenu) {
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_values: subcomponent.minValues, min_values: subComponent.minValues,
max_values: subcomponent.maxValues, max_values: subComponent.maxValues,
options: subcomponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
description: option.description, description: option.description,
@@ -62,19 +62,19 @@ export async function sendMessage(bot: Bot, channelId: bigint, content: CreateMe
} }
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
style: subcomponent.style, style: subComponent.style,
emoji: "emoji" in subcomponent && subcomponent.emoji emoji: "emoji" in subComponent && subComponent.emoji
? { ? {
id: subcomponent.emoji.id?.toString(), id: subComponent.emoji.id?.toString(),
name: subcomponent.emoji.name, name: subComponent.emoji.name,
animated: subcomponent.emoji.animated, animated: subComponent.emoji.animated,
} }
: undefined, : undefined,
url: "url" in subcomponent ? subcomponent.url : undefined, url: "url" in subComponent ? subComponent.url : undefined,
disabled: "disabled" in subcomponent ? subcomponent.disabled : undefined, disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
}; };
}), }),
})), })),
+26 -26
View File
@@ -45,27 +45,27 @@ export async function editWebhookMessage(
})), })),
components: options.components?.map((component) => ({ components: options.components?.map((component) => ({
type: component.type, type: component.type,
components: component.components.map((subcomponent) => { components: component.components.map((subComponent) => {
if (subcomponent.type === MessageComponentTypes.InputText) { if (subComponent.type === MessageComponentTypes.InputText) {
return { return {
type: subcomponent.type, type: subComponent.type,
style: subcomponent.style, style: subComponent.style,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_length: subcomponent.minLength ?? subcomponent.required === false ? 0 : subcomponent.minLength, min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength,
max_length: subcomponent.maxLength, max_length: subComponent.maxLength,
}; };
} }
if (subcomponent.type === MessageComponentTypes.SelectMenu) { if (subComponent.type === MessageComponentTypes.SelectMenu) {
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
placeholder: subcomponent.placeholder, placeholder: subComponent.placeholder,
min_values: subcomponent.minValues, min_values: subComponent.minValues,
max_values: subcomponent.maxValues, max_values: subComponent.maxValues,
options: subcomponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
description: option.description, description: option.description,
@@ -82,19 +82,19 @@ export async function editWebhookMessage(
} }
return { return {
type: subcomponent.type, type: subComponent.type,
custom_id: subcomponent.customId, custom_id: subComponent.customId,
label: subcomponent.label, label: subComponent.label,
style: subcomponent.style, style: subComponent.style,
emoji: "emoji" in subcomponent && subcomponent.emoji emoji: "emoji" in subComponent && subComponent.emoji
? { ? {
id: subcomponent.emoji.id?.toString(), id: subComponent.emoji.id?.toString(),
name: subcomponent.emoji.name, name: subComponent.emoji.name,
animated: subcomponent.emoji.animated, animated: subComponent.emoji.animated,
} }
: undefined, : undefined,
url: "url" in subcomponent ? subcomponent.url : undefined, url: "url" in subComponent ? subComponent.url : undefined,
disabled: "disabled" in subcomponent ? subcomponent.disabled : undefined, disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
}; };
}), }),
})), })),
+1 -1
View File
@@ -43,7 +43,7 @@ export function setupCacheRemovals<B extends Bot>(bot: BotWithCache<B>) {
bot.handlers.CHANNEL_DELETE = function (_, data, shardId) { bot.handlers.CHANNEL_DELETE = function (_, data, shardId) {
const payload = data.d as DiscordChannel; const payload = data.d as DiscordChannel;
// HANDLER BEFORE DELETING, BECAUSE HANDLER RUNS TRANSFORMER WHICH RECACHES // HANDLER BEFORE DELETING, BECAUSE HANDLER RUNS TRANSFORMER WHICH REACHES
CHANNEL_DELETE(bot, data, shardId); CHANNEL_DELETE(bot, data, shardId);
const id = bot.transformers.snowflake(payload.id); const id = bot.transformers.snowflake(payload.id);
+1 -1
View File
@@ -9,7 +9,7 @@ export function enableCacheSweepers<B extends Bot>(bot: BotWithCache<B>) {
// Reset activity for next interval // Reset activity for next interval
if (bot.activeGuildIds.delete(guild.id)) return false; if (bot.activeGuildIds.delete(guild.id)) return false;
// This is inactive guild. Not a single thing has happened for atleast 30 minutes. // This is inactive guild. Not a single thing has happened for at least 30 minutes.
// Not a reaction, not a message, not any event! // Not a reaction, not a message, not any event!
bot.dispatchedGuildIds.add(guild.id); bot.dispatchedGuildIds.add(guild.id);
+1 -1
View File
@@ -29,4 +29,4 @@ bot.fastFileLoader([
startBot(bot); startBot(bot);
``` ```
Make sure to ignore `fileloader.ts` in git as it is (re)generated whever you (re)start the bot. Make sure to ignore `fileloader.ts` in git as it is (re)generated where you (re)start the bot.
+1 -1
View File
@@ -16,7 +16,7 @@ export async function sendDirectMessage(
// IF ID IS CACHED SEND MESSAGE DIRECTLY // IF ID IS CACHED SEND MESSAGE DIRECTLY
if (cachedChannelId) return bot.helpers.sendMessage(cachedChannelId, content); if (cachedChannelId) return bot.helpers.sendMessage(cachedChannelId, content);
// CREATE A NEW DM CHANNEL AND PULCK ITS ID // CREATE A NEW DM CHANNEL AND PLUCK ITS ID
const channel = (await bot.helpers.getDmChannel(userId)); const channel = (await bot.helpers.getDmChannel(userId));
// CACHE IT FOR FUTURE REQUESTS // CACHE IT FOR FUTURE REQUESTS
+26 -26
View File
@@ -15,92 +15,92 @@ export function validateComponents(bot: Bot, components: MessageComponents) {
throw new Error("Too many components."); throw new Error("Too many components.");
} else if ( } else if (
component.components?.length > 1 && component.components?.length > 1 &&
component.components.some((subcomponent) => subcomponent.type === MessageComponentTypes.SelectMenu) component.components.some((subComponent) => subComponent.type === MessageComponentTypes.SelectMenu)
) { ) {
throw new Error("Select component must be alone."); throw new Error("Select component must be alone.");
} }
for (const subcomponent of component.components) { for (const subComponent of component.components) {
if ( if (
subcomponent.customId && subComponent.customId &&
!bot.utils.validateLength(subcomponent.customId, { max: 100 }) !bot.utils.validateLength(subComponent.customId, { max: 100 })
) { ) {
throw new Error("The custom id in the component is too big."); throw new Error("The custom id in the component is too big.");
} }
// 5 Link buttons can not have a customId // 5 Link buttons can not have a customId
if (subcomponent.type === MessageComponentTypes.Button) { if (subComponent.type === MessageComponentTypes.Button) {
if (subcomponent.style === ButtonStyles.Link && subcomponent.customId) { if (subComponent.style === ButtonStyles.Link && subComponent.customId) {
throw new Error("Link buttons can not have custom ids."); throw new Error("Link buttons can not have custom ids.");
} }
// Other buttons must have a customId // Other buttons must have a customId
if ( if (
!subcomponent.customId && subcomponent.style !== ButtonStyles.Link !subComponent.customId && subComponent.style !== ButtonStyles.Link
) { ) {
throw new Error( throw new Error(
"The button requires a custom id if it is not a link button.", "The button requires a custom id if it is not a link button.",
); );
} }
if (!bot.utils.validateLength(subcomponent.label, { max: 80 })) { if (!bot.utils.validateLength(subComponent.label, { max: 80 })) {
throw new Error("The label can not be longer than 80 characters."); throw new Error("The label can not be longer than 80 characters.");
} }
subcomponent.emoji = makeEmojiFromString(subcomponent.emoji); subComponent.emoji = makeEmojiFromString(subComponent.emoji);
} }
if (subcomponent.type === MessageComponentTypes.SelectMenu) { if (subComponent.type === MessageComponentTypes.SelectMenu) {
if ( if (
subcomponent.placeholder && subComponent.placeholder &&
!bot.utils.validateLength(subcomponent.placeholder, { max: 150 }) !bot.utils.validateLength(subComponent.placeholder, { max: 150 })
) { ) {
throw new Error( throw new Error(
"The component placeholder can not be longer than 150 characters.", "The component placeholder can not be longer than 150 characters.",
); );
} }
if (subcomponent.minValues) { if (subComponent.minValues) {
if (subcomponent.minValues < 1) { if (subComponent.minValues < 1) {
throw new Error( throw new Error(
"The min values must be more than 1 in a select component.", "The min values must be more than 1 in a select component.",
); );
} }
if (subcomponent.minValues > 25) { if (subComponent.minValues > 25) {
throw new Error( throw new Error(
"The min values must be less than 25 in a select component.", "The min values must be less than 25 in a select component.",
); );
} }
if (!subcomponent.maxValues) { if (!subComponent.maxValues) {
subcomponent.maxValues = subcomponent.minValues; subComponent.maxValues = subComponent.minValues;
} }
if (subcomponent.minValues > subcomponent.maxValues) { if (subComponent.minValues > subComponent.maxValues) {
throw new Error( throw new Error(
"The select component can not have a min values higher than a max values.", "The select component can not have a min values higher than a max values.",
); );
} }
} }
if (subcomponent.maxValues) { if (subComponent.maxValues) {
if (subcomponent.maxValues < 1) { if (subComponent.maxValues < 1) {
throw new Error( throw new Error(
"The max values must be more than 1 in a select component.", "The max values must be more than 1 in a select component.",
); );
} }
if (subcomponent.maxValues > 25) { if (subComponent.maxValues > 25) {
throw new Error( throw new Error(
"The max values must be less than 25 in a select component.", "The max values must be less than 25 in a select component.",
); );
} }
} }
if (subcomponent.options.length < 1) { if (subComponent.options.length < 1) {
throw new Error("You need atleast 1 option in the select component."); throw new Error("You need at least 1 option in the select component.");
} }
if (subcomponent.options.length > 25) { if (subComponent.options.length > 25) {
throw new Error( throw new Error(
"You can not have more than 25 options in the select component.", "You can not have more than 25 options in the select component.",
); );
@@ -108,10 +108,10 @@ export function validateComponents(bot: Bot, components: MessageComponents) {
let defaults = 0; let defaults = 0;
for (const option of subcomponent.options) { for (const option of subComponent.options) {
if (option.default) { if (option.default) {
defaults++; defaults++;
if (defaults > (subcomponent.maxValues || 25)) { if (defaults > (subComponent.maxValues || 25)) {
throw new Error("You chose too many default options."); throw new Error("You chose too many default options.");
} }
} }
+3 -3
View File
@@ -23,7 +23,7 @@ export function calculateBasePermissions(
if (!guild || !member) return 8n; if (!guild || !member) return 8n;
let permissions = 0n; let permissions = 0n;
// Calculate the role permissions bits, @everyone role is not in memberRoleIds so we need to pass guildId manualy // Calculate the role permissions bits, @everyone role is not in memberRoleIds so we need to pass guildId manually
permissions |= [...member.roles, guild.id] permissions |= [...member.roles, guild.id]
.map((id) => guild.roles.get(id)?.permissions) .map((id) => guild.roles.get(id)?.permissions)
// Removes any edge case undefined // Removes any edge case undefined
@@ -211,13 +211,13 @@ export function getMissingChannelPermissions(
member: bigint | Member, member: bigint | Member,
permissions: PermissionStrings[], permissions: PermissionStrings[],
) { ) {
// First we need the role permissino bits this member has // First we need the role permission bits this member has
const permissionBits = calculateChannelOverwrites( const permissionBits = calculateChannelOverwrites(
bot, bot,
channel, channel,
member, member,
); );
// Second returnn the members missing permissions // Second return the members missing permissions
return missingPermissions(permissionBits, permissions); return missingPermissions(permissionBits, permissions);
} }
+2 -2
View File
@@ -2,8 +2,8 @@ import { RestManager } from "../bot.ts";
/** Check the rate limits for a url or a bucket. */ /** Check the rate limits for a url or a bucket. */
export function checkRateLimits(rest: RestManager, url: string) { export function checkRateLimits(rest: RestManager, url: string) {
const ratelimited = rest.ratelimitedPaths.get(url); const ratelimited = rest.rateLimitedPaths.get(url);
const global = rest.ratelimitedPaths.get("global"); const global = rest.rateLimitedPaths.get("global");
const now = Date.now(); const now = Date.now();
if (ratelimited && now < ratelimited.resetTimestamp) { if (ratelimited && now < ratelimited.resetTimestamp) {
+2 -2
View File
@@ -11,7 +11,7 @@ export async function processGlobalQueue(rest: RestManager) {
rest.globalQueueProcessing = true; rest.globalQueueProcessing = true;
while (rest.globalQueue.length) { while (rest.globalQueue.length) {
// IF THE BOT IS GLOBALLY RATELIMITED TRY AGAIN // IF THE BOT IS GLOBALLY RATE LIMITED TRY AGAIN
if (rest.globallyRateLimited) { if (rest.globallyRateLimited) {
setTimeout(() => { setTimeout(() => {
rest.debug(`[REST - processGlobalQueue] Globally rate limited, running setTimeout.`); rest.debug(`[REST - processGlobalQueue] Globally rate limited, running setTimeout.`);
@@ -41,7 +41,7 @@ export async function processGlobalQueue(rest: RestManager) {
// REMOVES ANY POTENTIAL INVALID CONFLICTS // REMOVES ANY POTENTIAL INVALID CONFLICTS
if (!request) continue; if (!request) continue;
// CHECK RATELIMITS FOR 429 REPEATS // CHECK RATE LIMITS FOR 429 REPEATS
// IF THIS URL IS STILL RATE LIMITED, TRY AGAIN // IF THIS URL IS STILL RATE LIMITED, TRY AGAIN
const urlResetIn = rest.checkRateLimits(rest, request.basicURL); const urlResetIn = rest.checkRateLimits(rest, request.basicURL);
// IF A BUCKET EXISTS, CHECK THE BUCKET'S RATE LIMITS // IF A BUCKET EXISTS, CHECK THE BUCKET'S RATE LIMITS
+2 -2
View File
@@ -9,7 +9,7 @@ export function processQueue(rest: RestManager, id: string) {
rest.debug(`[REST - processQueue] Running while loop.`); rest.debug(`[REST - processQueue] Running while loop.`);
// SELECT THE FIRST ITEM FROM THIS QUEUE // SELECT THE FIRST ITEM FROM THIS QUEUE
const queuedRequest = queue.requests[0]; const queuedRequest = queue.requests[0];
// IF THIS DOESNT HAVE ANY ITEMS JUST CANCEL, THE CLEANER WILL REMOVE IT. // IF THIS DOESN'T HAVE ANY ITEMS JUST CANCEL, THE CLEANER WILL REMOVE IT.
if (!queuedRequest) break; if (!queuedRequest) break;
const basicURL = rest.simplifyUrl(queuedRequest.request.url, queuedRequest.request.method.toUpperCase()); const basicURL = rest.simplifyUrl(queuedRequest.request.url, queuedRequest.request.method.toUpperCase());
@@ -37,7 +37,7 @@ export function processQueue(rest: RestManager, id: string) {
const bucketResetIn = queuedRequest.payload.bucketId const bucketResetIn = queuedRequest.payload.bucketId
? rest.checkRateLimits(rest, queuedRequest.payload.bucketId) ? rest.checkRateLimits(rest, queuedRequest.payload.bucketId)
: false; : false;
// THIS BUCKET IS STILL RATELIMITED, RE-ADD TO QUEUE // THIS BUCKET IS STILL RATE LIMITED, RE-ADD TO QUEUE
if (bucketResetIn) continue; if (bucketResetIn) continue;
// EXECUTE THE REQUEST // EXECUTE THE REQUEST
+3 -3
View File
@@ -4,19 +4,19 @@ import { RestManager } from "../bot.ts";
export function processRateLimitedPaths(rest: RestManager) { export function processRateLimitedPaths(rest: RestManager) {
const now = Date.now(); const now = Date.now();
for (const [key, value] of rest.ratelimitedPaths.entries()) { for (const [key, value] of rest.rateLimitedPaths.entries()) {
rest.debug(`[REST - processRateLimitedPaths] Running for of loop. ${value.resetTimestamp - now}`); rest.debug(`[REST - processRateLimitedPaths] Running for of loop. ${value.resetTimestamp - now}`);
// IF THE TIME HAS NOT REACHED CANCEL // IF THE TIME HAS NOT REACHED CANCEL
if (value.resetTimestamp > now) continue; if (value.resetTimestamp > now) continue;
// RATE LIMIT IS OVER, DELETE THE RATE LIMITER // RATE LIMIT IS OVER, DELETE THE RATE LIMITER
rest.ratelimitedPaths.delete(key); rest.rateLimitedPaths.delete(key);
// IF IT WAS GLOBAL ALSO MARK THE GLOBAL VALUE AS FALSE // IF IT WAS GLOBAL ALSO MARK THE GLOBAL VALUE AS FALSE
if (key === "global") rest.globallyRateLimited = false; if (key === "global") rest.globallyRateLimited = false;
} }
// ALL PATHS ARE CLEARED CAN CANCEL OUT! // ALL PATHS ARE CLEARED CAN CANCEL OUT!
if (!rest.ratelimitedPaths.size) { if (!rest.rateLimitedPaths.size) {
rest.processingRateLimitedPaths = false; rest.processingRateLimitedPaths = false;
} else { } else {
rest.processingRateLimitedPaths = true; rest.processingRateLimitedPaths = true;
+10 -10
View File
@@ -1,8 +1,8 @@
import { RestManager } from "../bot.ts"; import { RestManager } from "../bot.ts";
/** Processes the rate limit headers and determines if it needs to be ratelimited and returns the bucket id if available */ /** Processes the rate limit headers and determines if it needs to be rate limited and returns the bucket id if available */
export function processRequestHeaders(rest: RestManager, url: string, headers: Headers) { export function processRequestHeaders(rest: RestManager, url: string, headers: Headers) {
let ratelimited = false; let rateLimited = false;
// GET ALL NECESSARY HEADERS // GET ALL NECESSARY HEADERS
const remaining = headers.get("x-ratelimit-remaining"); const remaining = headers.get("x-ratelimit-remaining");
@@ -14,10 +14,10 @@ export function processRequestHeaders(rest: RestManager, url: string, headers: H
// IF THERE IS NO REMAINING RATE LIMIT, MARK IT AS RATE LIMITED // IF THERE IS NO REMAINING RATE LIMIT, MARK IT AS RATE LIMITED
if (remaining === "0") { if (remaining === "0") {
ratelimited = true; rateLimited = true;
// SAVE THE URL AS LIMITED, IMPORTANT FOR NEW REQUESTS BY USER WITHOUT BUCKET // SAVE THE URL AS LIMITED, IMPORTANT FOR NEW REQUESTS BY USER WITHOUT BUCKET
rest.ratelimitedPaths.set(url, { rest.rateLimitedPaths.set(url, {
url, url,
resetTimestamp: reset, resetTimestamp: reset,
bucketId, bucketId,
@@ -25,7 +25,7 @@ export function processRequestHeaders(rest: RestManager, url: string, headers: H
// SAVE THE BUCKET AS LIMITED SINCE DIFFERENT URLS MAY SHARE A BUCKET // SAVE THE BUCKET AS LIMITED SINCE DIFFERENT URLS MAY SHARE A BUCKET
if (bucketId) { if (bucketId) {
rest.ratelimitedPaths.set(bucketId, { rest.rateLimitedPaths.set(bucketId, {
url, url,
resetTimestamp: reset, resetTimestamp: reset,
bucketId, bucketId,
@@ -39,16 +39,16 @@ export function processRequestHeaders(rest: RestManager, url: string, headers: H
const globalReset = Date.now() + Number(retryAfter) * 1000; const globalReset = Date.now() + Number(retryAfter) * 1000;
rest.debug(`[REST = Globally Rate Limited] URL: ${url} | Global Rest: ${globalReset}`); rest.debug(`[REST = Globally Rate Limited] URL: ${url} | Global Rest: ${globalReset}`);
rest.globallyRateLimited = true; rest.globallyRateLimited = true;
ratelimited = true; rateLimited = true;
rest.ratelimitedPaths.set("global", { rest.rateLimitedPaths.set("global", {
url: "global", url: "global",
resetTimestamp: globalReset, resetTimestamp: globalReset,
bucketId, bucketId,
}); });
if (bucketId) { if (bucketId) {
rest.ratelimitedPaths.set(bucketId, { rest.rateLimitedPaths.set(bucketId, {
url: "global", url: "global",
resetTimestamp: globalReset, resetTimestamp: globalReset,
bucketId, bucketId,
@@ -56,8 +56,8 @@ export function processRequestHeaders(rest: RestManager, url: string, headers: H
} }
} }
if (ratelimited && !rest.processingRateLimitedPaths) { if (rateLimited && !rest.processingRateLimitedPaths) {
rest.processRateLimitedPaths(rest); rest.processRateLimitedPaths(rest);
} }
return ratelimited ? bucketId : undefined; return rateLimited ? bucketId : undefined;
} }
+1 -1
View File
@@ -27,7 +27,7 @@ export const rest = {
processingQueue: false, processingQueue: false,
processingRateLimitedPaths: false, processingRateLimitedPaths: false,
globallyRateLimited: false, globallyRateLimited: false,
ratelimitedPaths: new Map<string, RestRateLimitedPath>(), rateLimitedPaths: new Map<string, RestRateLimitedPath>(),
eventHandlers: { eventHandlers: {
// BY DEFAULT WE WILL LOG ALL ERRORS TO CONSOLE. USER CAN CHOOSE TO OVERRIDE // BY DEFAULT WE WILL LOG ALL ERRORS TO CONSOLE. USER CAN CHOOSE TO OVERRIDE
error: function (...args: unknown[]) {}, error: function (...args: unknown[]) {},
+1 -1
View File
@@ -58,7 +58,7 @@ export function createRestManager(options: CreateRestManagerOptions) {
urlToUse: string; urlToUse: string;
}[], }[],
globalQueueProcessing: false, globalQueueProcessing: false,
ratelimitedPaths: new Map<string, RestRateLimitedPath>(), rateLimitedPaths: new Map<string, RestRateLimitedPath>(),
debug: options.debug || function (_text: string) {}, debug: options.debug || function (_text: string) {},
checkRateLimits: options.checkRateLimits || checkRateLimits, checkRateLimits: options.checkRateLimits || checkRateLimits,
cleanupQueues: options.cleanupQueues || cleanupQueues, cleanupQueues: options.cleanupQueues || cleanupQueues,
+1 -1
View File
@@ -29,7 +29,7 @@ export async function runMethod<T = any>(
); );
const errorStack = new Error("Location:"); const errorStack = new Error("Location:");
// @ts-ignore Breaks deno deploy. Luca said add tsignore until it's fixed // @ts-ignore Breaks deno deploy. Luca said add ts-ignore until it's fixed
Error.captureStackTrace(errorStack); Error.captureStackTrace(errorStack);
// For proxies we don't need to do any of the legwork so we just forward the request // For proxies we don't need to do any of the legwork so we just forward the request
+2 -2
View File
@@ -1,6 +1,6 @@
/** /**
* Credits: github.com/abalabahaha/eris lib/rest/RequestHandler.js#L397 * Credits: github.com/abalabahaha/eris lib/rest/RequestHandler.js#L397
* Modified for our usecase * Modified for our use-case
*/ */
/** Split a url to separate rate limit buckets based on major/minor parameters. */ /** Split a url to separate rate limit buckets based on major/minor parameters. */
@@ -16,7 +16,7 @@ export function simplifyUrl(url: string, method: string) {
route = route.substring(0, route.indexOf("/reactions") + "/reactions".length); route = route.substring(0, route.indexOf("/reactions") + "/reactions".length);
} }
// Delete Messsage endpoint has its own ratelimit // Delete Message endpoint has its own rate limit
if (method === "DELETE" && route.endsWith("/messages/skillzPrefersID")) { if (method === "DELETE" && route.endsWith("/messages/skillzPrefersID")) {
route = method + route; route = method + route;
} }
+27 -27
View File
@@ -1,7 +1,7 @@
// deno-lint-ignore-file no-explicit-any // deno-lint-ignore-file no-explicit-any
import { bold, cyan, gray, italic, red, yellow } from "../../deps.ts"; import { bold, cyan, gray, italic, red, yellow } from "../../deps.ts";
export enum Loglevels { export enum LogLevels {
Debug, Debug,
Info, Info,
Warn, Warn,
@@ -9,31 +9,31 @@ export enum Loglevels {
Fatal, Fatal,
} }
const prefixes = new Map<Loglevels, string>([ const prefixes = new Map<LogLevels, string>([
[Loglevels.Debug, "DEBUG"], [LogLevels.Debug, "DEBUG"],
[Loglevels.Info, "INFO"], [LogLevels.Info, "INFO"],
[Loglevels.Warn, "WARN"], [LogLevels.Warn, "WARN"],
[Loglevels.Error, "ERROR"], [LogLevels.Error, "ERROR"],
[Loglevels.Fatal, "FATAL"], [LogLevels.Fatal, "FATAL"],
]); ]);
const noColor: (str: string) => string = (msg) => msg; const noColor: (str: string) => string = (msg) => msg;
const colorFunctions = new Map<Loglevels, (str: string) => string>([ const colorFunctions = new Map<LogLevels, (str: string) => string>([
[Loglevels.Debug, gray], [LogLevels.Debug, gray],
[Loglevels.Info, cyan], [LogLevels.Info, cyan],
[Loglevels.Warn, yellow], [LogLevels.Warn, yellow],
[Loglevels.Error, (str: string) => red(str)], [LogLevels.Error, (str: string) => red(str)],
[Loglevels.Fatal, (str: string) => red(bold(italic(str)))], [LogLevels.Fatal, (str: string) => red(bold(italic(str)))],
]); ]);
export function logger({ export function logger({
logLevel = Loglevels.Info, logLevel = LogLevels.Info,
name, name,
}: { }: {
logLevel?: Loglevels; logLevel?: LogLevels;
name?: string; name?: string;
} = {}) { } = {}) {
function log(level: Loglevels, ...args: any[]) { function log(level: LogLevels, ...args: any[]) {
if (level < logLevel) return; if (level < logLevel) return;
let color = colorFunctions.get(level); let color = colorFunctions.get(level);
@@ -48,43 +48,43 @@ export function logger({
]; ];
switch (level) { switch (level) {
case Loglevels.Debug: case LogLevels.Debug:
return console.debug(...log); return console.debug(...log);
case Loglevels.Info: case LogLevels.Info:
return console.info(...log); return console.info(...log);
case Loglevels.Warn: case LogLevels.Warn:
return console.warn(...log); return console.warn(...log);
case Loglevels.Error: case LogLevels.Error:
return console.error(...log); return console.error(...log);
case Loglevels.Fatal: case LogLevels.Fatal:
return console.error(...log); return console.error(...log);
default: default:
return console.log(...log); return console.log(...log);
} }
} }
function setLevel(level: Loglevels) { function setLevel(level: LogLevels) {
logLevel = level; logLevel = level;
} }
function debug(...args: any[]) { function debug(...args: any[]) {
log(Loglevels.Debug, ...args); log(LogLevels.Debug, ...args);
} }
function info(...args: any[]) { function info(...args: any[]) {
log(Loglevels.Info, ...args); log(LogLevels.Info, ...args);
} }
function warn(...args: any[]) { function warn(...args: any[]) {
log(Loglevels.Warn, ...args); log(LogLevels.Warn, ...args);
} }
function error(...args: any[]) { function error(...args: any[]) {
log(Loglevels.Error, ...args); log(LogLevels.Error, ...args);
} }
function fatal(...args: any[]) { function fatal(...args: any[]) {
log(Loglevels.Fatal, ...args); log(LogLevels.Fatal, ...args);
} }
return { return {
@@ -74,7 +74,7 @@ export async function executeSlashCommand(
// Load the language for this guild // Load the language for this guild
if (interaction.guildId && !serverLanguages.has(interaction.guildId)) { if (interaction.guildId && !serverLanguages.has(interaction.guildId)) {
// TODO: Check if this is deferable // TODO: Check if this is deferrable
await replyToInteraction(bot, interaction, { await replyToInteraction(bot, interaction, {
type: InteractionResponseTypes.DeferredChannelMessageWithSource, type: InteractionResponseTypes.DeferredChannelMessageWithSource,
}); });
+2 -2
View File
@@ -36,7 +36,7 @@ if (DEVELOPMENT) {
logger.info(`[DEV MODE] Updating slash commands for dev server.`); logger.info(`[DEV MODE] Updating slash commands for dev server.`);
await updateDevCommands(bot); await updateDevCommands(bot);
} else { } else {
// THIS WILL UPDATE ALL YOUR GLOBAL COMMANDS ON BOOTUP // THIS WILL UPDATE ALL YOUR GLOBAL COMMANDS ON STARTUP
// await updateGlobalCommands(bot); // await updateGlobalCommands(bot);
} }
@@ -87,7 +87,7 @@ async function handleRequest(conn: Deno.Conn) {
bot.events.raw(bot, json.data, json.shardId); bot.events.raw(bot, json.data, json.shardId);
if (json.data.t && json.data.t !== "RESUMED") { if (json.data.t && json.data.t !== "RESUMED") {
// When a guild or something isnt in cache this will fetch it before doing anything else // When a guild or something isn't in cache this will fetch it before doing anything else
if (!["READY", "GUILD_LOADED_DD"].includes(json.data.t)) { if (!["READY", "GUILD_LOADED_DD"].includes(json.data.t)) {
await bot.events.dispatchRequirements(bot, json.data, json.shardId); await bot.events.dispatchRequirements(bot, json.data, json.shardId);
// WE ALSO WANT TO UPDATE GUILD SLASH IF NECESSARY AT THIS POINT // WE ALSO WANT TO UPDATE GUILD SLASH IF NECESSARY AT THIS POINT
+1 -1
View File
@@ -251,7 +251,7 @@ export type ConvertArgumentDefinitionsToArgs<
: // deno-lint-ignore ban-types : // deno-lint-ignore ban-types
{}; {};
} }
: // SUBCOMMANDGROUP : // SUBCOMMAND GROUP
T[P] extends SubcommandGroupArgumentDefinition<infer N> ? { T[P] extends SubcommandGroupArgumentDefinition<infer N> ? {
[_ in getName<N>]?: ConvertArgumentDefinitionsToArgs< [_ in getName<N>]?: ConvertArgumentDefinitionsToArgs<
T[P]["options"] T[P]["options"]
+1 -1
View File
@@ -36,7 +36,7 @@ export class Components extends Array<ActionRow> {
this.addActionRow(); this.addActionRow();
row = this[this.length - 1]; row = this[this.length - 1];
// Apperandly there are already 5 Full Action Rows so don't add the button // Apparently there are already 5 Full Action Rows so don't add the button
if (row.components.length === 5) return this; if (row.components.length === 5) return this;
} }
+2 -2
View File
@@ -117,12 +117,12 @@ export function stringToMilliseconds(text: string) {
export function chunkStrings( export function chunkStrings(
array: string[], array: string[],
size = 2000, size = 2000,
lineSeperator = "\n", lineSeparator = "\n",
) { ) {
const responses: string[] = []; const responses: string[] = [];
let response = ""; let response = "";
for (const text of array) { for (const text of array) {
const nextText = response.length && lineSeperator ? `${lineSeperator}${text}` : text; const nextText = response.length && lineSeparator ? `${lineSeparator}${text}` : text;
if (response.length + nextText.length >= size) { if (response.length + nextText.length >= size) {
responses.push(response); responses.push(response);
response = ""; response = "";
+27 -27
View File
@@ -1,7 +1,7 @@
// deno-lint-ignore-file no-explicit-any // deno-lint-ignore-file no-explicit-any
import { bold, cyan, gray, italic, red, yellow } from "../../deps.ts"; import { bold, cyan, gray, italic, red, yellow } from "../../deps.ts";
export enum Loglevels { export enum LogLevels {
Debug, Debug,
Info, Info,
Warn, Warn,
@@ -9,31 +9,31 @@ export enum Loglevels {
Fatal, Fatal,
} }
const prefixes = new Map<Loglevels, string>([ const prefixes = new Map<LogLevels, string>([
[Loglevels.Debug, "DEBUG"], [LogLevels.Debug, "DEBUG"],
[Loglevels.Info, "INFO"], [LogLevels.Info, "INFO"],
[Loglevels.Warn, "WARN"], [LogLevels.Warn, "WARN"],
[Loglevels.Error, "ERROR"], [LogLevels.Error, "ERROR"],
[Loglevels.Fatal, "FATAL"], [LogLevels.Fatal, "FATAL"],
]); ]);
const noColor: (str: string) => string = (msg) => msg; const noColor: (str: string) => string = (msg) => msg;
const colorFunctions = new Map<Loglevels, (str: string) => string>([ const colorFunctions = new Map<LogLevels, (str: string) => string>([
[Loglevels.Debug, gray], [LogLevels.Debug, gray],
[Loglevels.Info, cyan], [LogLevels.Info, cyan],
[Loglevels.Warn, yellow], [LogLevels.Warn, yellow],
[Loglevels.Error, (str: string) => red(str)], [LogLevels.Error, (str: string) => red(str)],
[Loglevels.Fatal, (str: string) => red(bold(italic(str)))], [LogLevels.Fatal, (str: string) => red(bold(italic(str)))],
]); ]);
export function logger({ export function logger({
logLevel = Loglevels.Info, logLevel = LogLevels.Info,
name, name,
}: { }: {
logLevel?: Loglevels; logLevel?: LogLevels;
name?: string; name?: string;
} = {}) { } = {}) {
function log(level: Loglevels, ...args: any[]) { function log(level: LogLevels, ...args: any[]) {
if (level < logLevel) return; if (level < logLevel) return;
let color = colorFunctions.get(level); let color = colorFunctions.get(level);
@@ -48,43 +48,43 @@ export function logger({
]; ];
switch (level) { switch (level) {
case Loglevels.Debug: case LogLevels.Debug:
return console.debug(...log); return console.debug(...log);
case Loglevels.Info: case LogLevels.Info:
return console.info(...log); return console.info(...log);
case Loglevels.Warn: case LogLevels.Warn:
return console.warn(...log); return console.warn(...log);
case Loglevels.Error: case LogLevels.Error:
return console.error(...log); return console.error(...log);
case Loglevels.Fatal: case LogLevels.Fatal:
return console.error(...log); return console.error(...log);
default: default:
return console.log(...log); return console.log(...log);
} }
} }
function setLevel(level: Loglevels) { function setLevel(level: LogLevels) {
logLevel = level; logLevel = level;
} }
function debug(...args: any[]) { function debug(...args: any[]) {
log(Loglevels.Debug, ...args); log(LogLevels.Debug, ...args);
} }
function info(...args: any[]) { function info(...args: any[]) {
log(Loglevels.Info, ...args); log(LogLevels.Info, ...args);
} }
function warn(...args: any[]) { function warn(...args: any[]) {
log(Loglevels.Warn, ...args); log(LogLevels.Warn, ...args);
} }
function error(...args: any[]) { function error(...args: any[]) {
log(Loglevels.Error, ...args); log(LogLevels.Error, ...args);
} }
function fatal(...args: any[]) { function fatal(...args: any[]) {
log(Loglevels.Fatal, ...args); log(LogLevels.Fatal, ...args);
} }
return { return {
+1 -1
View File
@@ -141,7 +141,7 @@ function convertOptionValue(
return [translateOptions?.[option.name] ?? option.name, final]; return [translateOptions?.[option.name] ?? option.name, final];
} }
// THE REST OF OPTIONS DON'T NEED ANY CONVERTION // THE REST OF OPTIONS DON'T NEED ANY CONVERSION
// SAVE THE ARGUMENT WITH THE CORRECT NAME // SAVE THE ARGUMENT WITH THE CORRECT NAME
// @ts-ignore ts leave me alone // @ts-ignore ts leave me alone
return [translateOptions?.[option.name] ?? option.name, option.value]; return [translateOptions?.[option.name] ?? option.name, option.value];
+3 -3
View File
@@ -6,7 +6,7 @@ export default async function hasPermissionLevel(
command: Command<any>, command: Command<any>,
payload: Interaction, payload: Interaction,
) { ) {
// This command doesnt require a perm level so allow the command. // This command doesn't require a perm level so allow the command.
if (!command.permissionLevels) return true; if (!command.permissionLevels) return true;
// If a custom function was provided // If a custom function was provided
@@ -15,9 +15,9 @@ export default async function hasPermissionLevel(
} }
// If an array of perm levels was provided // If an array of perm levels was provided
for (const permlevel of command.permissionLevels) { for (const permLevel of command.permissionLevels) {
// If this user has one of the allowed perm level, the loop is canceled and command is allowed. // If this user has one of the allowed perm level, the loop is canceled and command is allowed.
if (await PermissionLevelHandlers[permlevel](payload, command)) return true; if (await PermissionLevelHandlers[permLevel](payload, command)) return true;
} }
// None of the perm levels were met. So cancel the command // None of the perm levels were met. So cancel the command
@@ -200,7 +200,7 @@ events.interactionCreate = async (rawBot, interaction) => {
// Check if command has execute // Check if command has execute
if (!cmd.execute) { if (!cmd.execute) {
logger.error(`Command ${cmdName} is missing execute.`); logger.error(`Command ${cmdName} is missing execute.`);
sendBasicReponse(data.id, data.token, "This command is not configured to be executed."); sendBasicResponse(data.id, data.token, "This command is not configured to be executed.");
return; return;
} }
+27 -27
View File
@@ -1,7 +1,7 @@
// deno-lint-ignore-file no-explicit-any // deno-lint-ignore-file no-explicit-any
import { bold, cyan, gray, italic, red, yellow } from "../../deps.ts"; import { bold, cyan, gray, italic, red, yellow } from "../../deps.ts";
export enum Loglevels { export enum LogLevels {
Debug, Debug,
Info, Info,
Warn, Warn,
@@ -9,31 +9,31 @@ export enum Loglevels {
Fatal, Fatal,
} }
const prefixes = new Map<Loglevels, string>([ const prefixes = new Map<LogLevels, string>([
[Loglevels.Debug, "DEBUG"], [LogLevels.Debug, "DEBUG"],
[Loglevels.Info, "INFO"], [LogLevels.Info, "INFO"],
[Loglevels.Warn, "WARN"], [LogLevels.Warn, "WARN"],
[Loglevels.Error, "ERROR"], [LogLevels.Error, "ERROR"],
[Loglevels.Fatal, "FATAL"], [LogLevels.Fatal, "FATAL"],
]); ]);
const noColor: (str: string) => string = (msg) => msg; const noColor: (str: string) => string = (msg) => msg;
const colorFunctions = new Map<Loglevels, (str: string) => string>([ const colorFunctions = new Map<LogLevels, (str: string) => string>([
[Loglevels.Debug, gray], [LogLevels.Debug, gray],
[Loglevels.Info, cyan], [LogLevels.Info, cyan],
[Loglevels.Warn, yellow], [LogLevels.Warn, yellow],
[Loglevels.Error, (str: string) => red(str)], [LogLevels.Error, (str: string) => red(str)],
[Loglevels.Fatal, (str: string) => red(bold(italic(str)))], [LogLevels.Fatal, (str: string) => red(bold(italic(str)))],
]); ]);
export function logger({ export function logger({
logLevel = Loglevels.Info, logLevel = LogLevels.Info,
name, name,
}: { }: {
logLevel?: Loglevels; logLevel?: LogLevels;
name?: string; name?: string;
} = {}) { } = {}) {
function log(level: Loglevels, ...args: any[]) { function log(level: LogLevels, ...args: any[]) {
if (level < logLevel) return; if (level < logLevel) return;
let color = colorFunctions.get(level); let color = colorFunctions.get(level);
@@ -48,43 +48,43 @@ export function logger({
]; ];
switch (level) { switch (level) {
case Loglevels.Debug: case LogLevels.Debug:
return console.debug(...log); return console.debug(...log);
case Loglevels.Info: case LogLevels.Info:
return console.info(...log); return console.info(...log);
case Loglevels.Warn: case LogLevels.Warn:
return console.warn(...log); return console.warn(...log);
case Loglevels.Error: case LogLevels.Error:
return console.error(...log); return console.error(...log);
case Loglevels.Fatal: case LogLevels.Fatal:
return console.error(...log); return console.error(...log);
default: default:
return console.log(...log); return console.log(...log);
} }
} }
function setLevel(level: Loglevels) { function setLevel(level: LogLevels) {
logLevel = level; logLevel = level;
} }
function debug(...args: any[]) { function debug(...args: any[]) {
log(Loglevels.Debug, ...args); log(LogLevels.Debug, ...args);
} }
function info(...args: any[]) { function info(...args: any[]) {
log(Loglevels.Info, ...args); log(LogLevels.Info, ...args);
} }
function warn(...args: any[]) { function warn(...args: any[]) {
log(Loglevels.Warn, ...args); log(LogLevels.Warn, ...args);
} }
function error(...args: any[]) { function error(...args: any[]) {
log(Loglevels.Error, ...args); log(LogLevels.Error, ...args);
} }
function fatal(...args: any[]) { function fatal(...args: any[]) {
log(Loglevels.Fatal, ...args); log(LogLevels.Fatal, ...args);
} }
return { return {
+133
View File
@@ -0,0 +1,133 @@
import { Bot } from "../bot.ts";
import { DiscordAuditLogEntry } from "../types/discord.ts";
import { Optionalize } from "../types/shared.ts";
export function transformAuditLogEntry(bot: Bot, payload: DiscordAuditLogEntry) {
const auditLogEntry = {
id: bot.transformers.snowflake(payload.id),
changes: payload.changes?.map((change) => {
switch (change.key) {
case "$add":
case "$remove":
return {
key: change.key,
new: change.new_value?.map((val) => ({
id: val.id ? bot.transformers.snowflake(val.id) : undefined,
name: val.name,
})),
old: change.old_value?.map((val) => ({
id: val?.id ? bot.transformers.snowflake(val.id) : undefined,
name: val?.name,
})),
};
case "discovery_splash_hash":
case "banner_hash":
case "rules_channel_id":
case "public_updates_channel_id":
case "icon_hash":
case "image_hash":
case "splash_hash":
case "owner_id":
case "widget_channel_id":
case "system_channel_id":
case "application_id":
case "permissions":
case "allow":
case "deny":
case "channel_id":
case "inviter_id":
case "avatar_hash":
case "id":
return {
key: change.key,
old: change.old_value ? bot.transformers.snowflake(change.old_value) : undefined,
new: change.new_value ? bot.transformers.snowflake(change.new_value) : undefined,
};
case "name":
case "description":
case "preferred_locale":
case "region":
case "afk_channel_id":
case "vanity_url_code":
case "topic":
case "code":
case "nick":
case "location":
return {
key: change.key,
old: change.old_value,
new: change.new_value,
};
case "afk_timeout":
case "mfa_level":
case "verification_level":
case "explicit_content_filter":
case "default_message_notifications":
case "prune_delete_days":
case "position":
case "bitrate":
case "rate_limit_per_user":
case "color":
case "max_uses":
case "uses":
case "max_age":
case "expire_behavior":
case "expire_grace_period":
case "user_limit":
case "privacy_level":
case "entity_type":
case "status":
return {
key: change.key,
old: change.old_value ? Number(change.old_value) : undefined,
new: change.new_value ? Number(change.new_value) : undefined,
};
case "widget_enabled":
case "nsfw":
case "hoist":
case "mentionable":
case "temporary":
case "deaf":
case "mute":
case "enable_emoticons":
return {
key: change.key,
old: change.old_value ?? false,
new: change.new_value ?? false,
};
case "permission_overwrites":
return {
key: change.key,
old: change.old_value,
new: change.new_value,
};
default:
return {
key: change.key,
old: change.old_value,
new: change.new_value,
};
}
}),
userId: payload.user_id ? bot.transformers.snowflake(payload.user_id) : undefined,
targetId: payload.target_id ? bot.transformers.snowflake(payload.target_id) : undefined,
actionType: payload.action_type,
options: payload.options
? {
deleteMemberDays: payload.options.delete_member_days ? Number(payload.options.delete_member_days) : 0,
membersRemoved: payload.options.members_removed ? Number(payload.options.members_removed) : 0,
channelId: payload.options.channel_id ? bot.transformers.snowflake(payload.options.channel_id) : undefined,
messageId: payload.options.message_id ? bot.transformers.snowflake(payload.options.message_id) : undefined,
count: payload.options.count ? Number(payload.options.count) : 0,
id: payload.options.id ? bot.transformers.snowflake(payload.options.id) : undefined,
type: Number(payload.options.type),
roleName: payload.options.role_name,
}
: undefined,
reason: payload.reason,
};
return auditLogEntry as Optionalize<typeof auditLogEntry>;
}
export interface AuditLogEntry extends ReturnType<typeof transformAuditLogEntry> {}
+1 -1
View File
@@ -6,7 +6,7 @@ export * from "./applicationCommand.ts";
export * from "./applicationCommandOption.ts"; export * from "./applicationCommandOption.ts";
export * from "./applicationCommandPermission.ts"; export * from "./applicationCommandPermission.ts";
export * from "./attachment.ts"; export * from "./attachment.ts";
export * from "./auditlogEntry.ts"; export * from "./auditLogEntry.ts";
export * from "./channel.ts"; export * from "./channel.ts";
export * from "./component.ts"; export * from "./component.ts";
export * from "./embed.ts"; export * from "./embed.ts";
+4 -4
View File
@@ -18,7 +18,7 @@ export const GuildToggle = {
/** Whether the guild has access to set an invite splash background */ /** Whether the guild has access to set an invite splash background */
inviteSplash: 1n << 5n, inviteSplash: 1n << 5n,
/** Whether the guild has access to set 384kbps bitrate in voice (previously VIP voice servers) */ /** Whether the guild has access to set 384 kbps bitrate in voice (previously VIP voice servers) */
vipRegions: 1n << 6n, vipRegions: 1n << 6n,
/** Whether the guild has access to set a vanity URL */ /** Whether the guild has access to set a vanity URL */
vanityUrl: 1n << 7n, vanityUrl: 1n << 7n,
@@ -26,7 +26,7 @@ export const GuildToggle = {
verified: 1n << 8n, verified: 1n << 8n,
/** Whether the guild is partnered */ /** Whether the guild is partnered */
partnered: 1n << 9n, partnered: 1n << 9n,
/** Whether the guild can enable welcome screen, Membership Screening, stage channels and discovery, and recives community updates */ /** Whether the guild can enable welcome screen, Membership Screening, stage channels and discovery, and receives community updates */
community: 1n << 10n, community: 1n << 10n,
/** Whether the guild has access to use commerce features (i.e. create store channels) */ /** Whether the guild has access to use commerce features (i.e. create store channels) */
commerce: 1n << 11n, commerce: 1n << 11n,
@@ -130,7 +130,7 @@ export class GuildToggles extends ToggleBitfieldBigint {
get inviteSplash() { get inviteSplash() {
return this.has("inviteSplash"); return this.has("inviteSplash");
} }
/** Whether the guild has access to set 384kbps bitrate in voice (previously VIP voice servers) */ /** Whether the guild has access to set 384 kbps bitrate in voice (previously VIP voice servers) */
get vipRegions() { get vipRegions() {
return this.has("vipRegions"); return this.has("vipRegions");
} }
@@ -146,7 +146,7 @@ export class GuildToggles extends ToggleBitfieldBigint {
get partnered() { get partnered() {
return this.has("partnered"); return this.has("partnered");
} }
/** Whether the guild can enable welcome screen, Membership Screening, stage channels and discovery, and recives community updates */ /** Whether the guild can enable welcome screen, Membership Screening, stage channels and discovery, and receives community updates */
get community() { get community() {
return this.has("community"); return this.has("community");
} }
+2 -2
View File
@@ -2,7 +2,7 @@ import { DiscordRole } from "../../types/discord.ts";
import { ToggleBitfield } from "./ToggleBitfield.ts"; import { ToggleBitfield } from "./ToggleBitfield.ts";
export const RoleToggle = { export const RoleToggle = {
/** If this role is showed seperately in the user listing */ /** If this role is showed separately in the user listing */
hoist: 1 << 0, hoist: 1 << 0,
/** Whether this role is managed by an integration */ /** Whether this role is managed by an integration */
managed: 1 << 1, managed: 1 << 1,
@@ -22,7 +22,7 @@ export class RoleToggles extends ToggleBitfield {
if (role.tags?.premium_subscriber === null) this.add(RoleToggle.premiumSubscriber); if (role.tags?.premium_subscriber === null) this.add(RoleToggle.premiumSubscriber);
} }
/** If this role is showed seperately in the user listing */ /** If this role is showed separately in the user listing */
get hoist() { get hoist() {
return this.has("hoist"); return this.has("hoist");
} }
+15 -25
View File
@@ -214,7 +214,7 @@ export interface DiscordMember {
roles: string[]; roles: string[];
/** When the user joined the guild */ /** When the user joined the guild */
joined_at: string; joined_at: string;
/** When the user started boosing the guild */ /** When the user started boosting the guild */
premium_since?: string | null; premium_since?: string | null;
/** The permissions this member has in the guild. Only present on interaction events. */ /** The permissions this member has in the guild. Only present on interaction events. */
permissions?: string; permissions?: string;
@@ -444,7 +444,7 @@ export type DiscordWebhook = DiscordIncomingWebhook | DiscordApplicationWebhook;
export interface DiscordIncomingWebhook { export interface DiscordIncomingWebhook {
/** The type of the webhook */ /** The type of the webhook */
type: WebhookTypes; type: WebhookTypes;
/** The secure token of the webhook (returned for Incomming Webhooks) */ /** The secure token of the webhook (returned for Incoming Webhooks) */
token?: string; token?: string;
/** The url used for executing the webhook (returned by the webhooks OAuth2 flow) */ /** The url used for executing the webhook (returned by the webhooks OAuth2 flow) */
url?: string; url?: string;
@@ -472,7 +472,7 @@ export interface DiscordIncomingWebhook {
export interface DiscordApplicationWebhook { export interface DiscordApplicationWebhook {
/** The type of the webhook */ /** The type of the webhook */
type: WebhookTypes.Application; type: WebhookTypes.Application;
/** The secure token of the webhook (returned for Incomming Webhooks) */ /** The secure token of the webhook (returned for Incoming Webhooks) */
token?: string; token?: string;
/** The url used for executing the webhook (returned by the webhooks OAuth2 flow) */ /** The url used for executing the webhook (returned by the webhooks OAuth2 flow) */
url?: string; url?: string;
@@ -499,7 +499,7 @@ export interface DiscordApplicationWebhook {
/** https://discord.com/developers/docs/resources/guild#guild-object */ /** https://discord.com/developers/docs/resources/guild#guild-object */
export interface DiscordGuild { export interface DiscordGuild {
/** Guild name (2-100 characaters, excluding trailing and leading whitespace) */ /** Guild name (2-100 characters, excluding trailing and leading whitespace) */
name: string; name: string;
/** True if the user is the owner of the guild */ /** True if the user is the owner of the guild */
owner?: boolean; owner?: boolean;
@@ -529,7 +529,7 @@ export interface DiscordGuild {
max_presences?: number | null; max_presences?: number | null;
/** The maximum number of members for the guild */ /** The maximum number of members for the guild */
max_members?: number; max_members?: number;
/** The vaniy url code for the guild */ /** The vanity url code for the guild */
vanity_url_code: string | null; vanity_url_code: string | null;
/** The description of a Community guild */ /** The description of a Community guild */
description: string | null; description: string | null;
@@ -606,7 +606,7 @@ export interface DiscordGuild {
export interface DiscordRole { export interface DiscordRole {
/** Role id */ /** Role id */
id: string; id: string;
/** If this role is showed seperately in the user listing */ /** If this role is showed separately in the user listing */
hoist: boolean; hoist: boolean;
/** Permission bit set */ /** Permission bit set */
permissions: string; permissions: string;
@@ -735,7 +735,7 @@ export interface DiscordChannel {
parent_id?: string | null; parent_id?: string | null;
/** When the last pinned message was pinned. This may be null in events such as GUILD_CREATE when a message is not pinned. */ /** When the last pinned message was pinned. This may be null in events such as GUILD_CREATE when a message is not pinned. */
last_pin_timestamp?: string | null; last_pin_timestamp?: string | null;
/** Thread-specifig fields not needed by other channels */ /** Thread-specific fields not needed by other channels */
thread_metadata?: DiscordThreadMetadata; thread_metadata?: DiscordThreadMetadata;
/** Thread member object for the current user, if they have joined the thread, only included on certain API endpoints */ /** Thread member object for the current user, if they have joined the thread, only included on certain API endpoints */
member?: DiscordThreadMember; member?: DiscordThreadMember;
@@ -803,7 +803,6 @@ export interface DiscordThreadMetadata {
locked: boolean; locked: boolean;
/** whether non-moderators can add other non-moderators to a thread; only available on private threads */ /** whether non-moderators can add other non-moderators to a thread; only available on private threads */
invitable?: boolean; invitable?: boolean;
/** Timestamp when the thread's archive status was last changed, used for calculating recent activity */ /** Timestamp when the thread's archive status was last changed, used for calculating recent activity */
archive_timestamp: string; archive_timestamp: string;
/** Timestamp when the thread was created; only populated for threads created after 2022-01-09 */ /** Timestamp when the thread was created; only populated for threads created after 2022-01-09 */
@@ -818,7 +817,6 @@ export interface DiscordThreadMemberBase {
export interface DiscordThreadMember { export interface DiscordThreadMember {
/** Any user-thread settings, currently only used for notifications */ /** Any user-thread settings, currently only used for notifications */
flags: number; flags: number;
/** The id of the thread */ /** The id of the thread */
id: string; id: string;
/** The id of the user */ /** The id of the user */
@@ -830,7 +828,6 @@ export interface DiscordThreadMember {
export interface DiscordThreadMemberGuildCreate { export interface DiscordThreadMemberGuildCreate {
/** Any user-thread settings, currently only used for notifications */ /** Any user-thread settings, currently only used for notifications */
flags: number; flags: number;
/** The time the current user last joined the thread */ /** The time the current user last joined the thread */
join_timestamp: string; join_timestamp: string;
} }
@@ -853,7 +850,6 @@ export interface DiscordActivity {
instance?: boolean; instance?: boolean;
/** Activity flags `OR`d together, describes what the payload includes */ /** Activity flags `OR`d together, describes what the payload includes */
flags?: number; flags?: number;
/** Unix timestamps for start and/or end of the game */ /** Unix timestamps for start and/or end of the game */
timestamps?: DiscordActivityTimestamps; timestamps?: DiscordActivityTimestamps;
/** Application id for the game */ /** Application id for the game */
@@ -894,7 +890,6 @@ export interface DiscordActivityEmoji {
name: string; name: string;
/** Whether this emoji is animated */ /** Whether this emoji is animated */
animated?: boolean; animated?: boolean;
/** The id of the emoji */ /** The id of the emoji */
id?: string; id?: string;
} }
@@ -903,7 +898,6 @@ export interface DiscordActivityEmoji {
export interface DiscordActivityParty { export interface DiscordActivityParty {
/** Used to show the party's current and maximum size */ /** Used to show the party's current and maximum size */
size?: [currentSize: number, maxSize: number]; size?: [currentSize: number, maxSize: number];
/** The id of the party */ /** The id of the party */
id?: string; id?: string;
} }
@@ -914,7 +908,6 @@ export interface DiscordActivityAssets {
large_text?: string; large_text?: string;
/** Text displayed when hovering over the small image of the activity */ /** Text displayed when hovering over the small image of the activity */
small_text?: string; small_text?: string;
/** The id for a large asset of the activity, usually a snowflake */ /** The id for a large asset of the activity, usually a snowflake */
large_image?: string; large_image?: string;
/** The id for a small asset of the activity, usually a snowflake */ /** The id for a small asset of the activity, usually a snowflake */
@@ -943,7 +936,6 @@ export interface DiscordActivityButton {
export interface DiscordOverwrite { export interface DiscordOverwrite {
/** Either 0 (role) or 1 (member) */ /** Either 0 (role) or 1 (member) */
type: OverwriteTypes; type: OverwriteTypes;
/** Role or user id */ /** Role or user id */
id: string; id: string;
/** Permission bit set */ /** Permission bit set */
@@ -1277,9 +1269,7 @@ export interface DiscordInteraction {
version: 1; version: 1;
/** For the message the button was attached to */ /** For the message the button was attached to */
message?: DiscordMessage; message?: DiscordMessage;
data?: DiscordInteractionData; data?: DiscordInteractionData;
/** The selected language of the invoking user */ /** The selected language of the invoking user */
locale?: string; locale?: string;
/** The guild's preferred locale, if invoked in a guild */ /** The guild's preferred locale, if invoked in a guild */
@@ -1398,7 +1388,7 @@ export interface DiscordAuditLogEntry {
user_id: string | null; user_id: string | null;
/** id of the entry */ /** id of the entry */
id: string; id: string;
/** Type of action that occured */ /** Type of action that occurred */
action_type: AuditLogEvents; action_type: AuditLogEvents;
/** Additional info for certain action types */ /** Additional info for certain action types */
options?: DiscordOptionalAuditEntryInfo; options?: DiscordOptionalAuditEntryInfo;
@@ -1449,7 +1439,7 @@ export type DiscordAuditLogChange =
| "mfa_level" | "mfa_level"
| "verification_level" | "verification_level"
| "explicit_content_filter" | "explicit_content_filter"
| "default_messagae_notifications" | "default_message_notifications"
| "prune_delete_days" | "prune_delete_days"
| "position" | "position"
| "bitrate" | "bitrate"
@@ -1653,11 +1643,11 @@ export interface DiscordApplicationCommand {
description_localizations?: Localization; description_localizations?: Localization;
/** The parameters for the command */ /** The parameters for the command */
options?: DiscordApplicationCommandOption[]; options?: DiscordApplicationCommandOption[];
/** Whether the command is enbaled by default when the app is added to a guild */ /** Whether the command is enabled by default when the app is added to a guild */
default_permission?: boolean; default_permission?: boolean;
/** The type of command. By default this is a application command(ChatInput). */ /** The type of command. By default this is a application command(ChatInput). */
type?: ApplicationCommandTypes; type?: ApplicationCommandTypes;
/** Autoincrementing version identifier updated during substantial record changes */ /** Auto incrementing version identifier updated during substantial record changes */
version: string; version: string;
} }
@@ -1771,7 +1761,7 @@ export interface DiscordGuildPreview {
export interface DiscordDiscoveryCategory { export interface DiscordDiscoveryCategory {
/** Numeric id of the category */ /** Numeric id of the category */
id: number; id: number;
/** The name of this category, in mutliple languages */ /** The name of this category, in multiple languages */
name: DiscordDiscoveryName; name: DiscordDiscoveryName;
/** Whether this category can be set as a guild's primary category */ /** Whether this category can be set as a guild's primary category */
is_primary: boolean; is_primary: boolean;
@@ -1793,7 +1783,7 @@ export interface DiscordDiscoveryMetadata {
keywords: string[] | null; keywords: string[] | null;
/** Whether guild info is shown when custom emojis from this guild are clicked */ /** Whether guild info is shown when custom emojis from this guild are clicked */
emoji_discoverability_enabled: boolean; emoji_discoverability_enabled: boolean;
/** When the server's partner applicationo was accepted or denied, for applications via Server Settings */ /** When the server's partner application was accepted or denied, for applications via Server Settings */
partner_actioned_timestamp: string | null; partner_actioned_timestamp: string | null;
/** When the server applied for partnership, if it has a pending application */ /** When the server applied for partnership, if it has a pending application */
partner_application_timestamp: string | null; partner_application_timestamp: string | null;
@@ -2044,7 +2034,7 @@ export interface DiscordTemplate {
& { id: number } & { id: number }
)[]; )[];
}; };
/** Whether the template has unsynced changes */ /** Whether the template has un-synced changes */
is_dirty: boolean | null; is_dirty: boolean | null;
} }
@@ -2223,7 +2213,7 @@ export interface DiscordVoiceRegion {
name: string; name: string;
/** true for a single server that is closest to the current user's client */ /** true for a single server that is closest to the current user's client */
optimal: boolean; optimal: boolean;
/** Whether this is a deprecated voice region (avoid swithing to these) */ /** Whether this is a deprecated voice region (avoid switching to these) */
deprecated: boolean; deprecated: boolean;
/** Whether this is a custom voice region (used for events/etc) */ /** Whether this is a custom voice region (used for events/etc) */
custom: boolean; custom: boolean;
+8 -8
View File
@@ -11,7 +11,7 @@ export enum PremiumTypes {
export enum UserFlags { export enum UserFlags {
None, None,
DiscordEmployee = 1 << 0, DiscordEmployee = 1 << 0,
ParteneredServerOwner = 1 << 1, PartneredServerOwner = 1 << 1,
HypeSquadEvents = 1 << 2, HypeSquadEvents = 1 << 2,
BugHunterLevel1 = 1 << 3, BugHunterLevel1 = 1 << 3,
HouseBravery = 1 << 6, HouseBravery = 1 << 6,
@@ -170,7 +170,7 @@ export interface BaseRole {
export enum GuildFeatures { export enum GuildFeatures {
/** Guild has access to set an invite splash background */ /** Guild has access to set an invite splash background */
InviteSplash = "INVITE_SPLASH", InviteSplash = "INVITE_SPLASH",
/** Guild has access to set 384kbps bitrate in voice (previously VIP voice servers) */ /** Guild has access to set 384 kbps bitrate in voice (previously VIP voice servers) */
VipRegions = "VIP_REGIONS", VipRegions = "VIP_REGIONS",
/** Guild has access to set a vanity URL */ /** Guild has access to set a vanity URL */
VanityUrl = "VANITY_URL", VanityUrl = "VANITY_URL",
@@ -178,7 +178,7 @@ export enum GuildFeatures {
Verified = "VERIFIED", Verified = "VERIFIED",
/** Guild is partnered */ /** Guild is partnered */
Partnered = "PARTNERED", Partnered = "PARTNERED",
/** Guild can enable welcome screen, Membership Screening, stage channels and discovery, and recives community updates */ /** Guild can enable welcome screen, Membership Screening, stage channels and discovery, and receives community updates */
Community = "COMMUNITY", Community = "COMMUNITY",
/** Guild has access to use commerce features (i.e. create store channels) */ /** Guild has access to use commerce features (i.e. create store channels) */
Commerce = "COMMERCE", Commerce = "COMMERCE",
@@ -350,7 +350,7 @@ export enum StickerTypes {
/** https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types */ /** https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types */
export enum StickerFormatTypes { export enum StickerFormatTypes {
Png = 1, Png = 1,
Apng, APng,
Lottie, Lottie,
} }
@@ -1224,10 +1224,10 @@ export enum Errors {
BUTTON_REQUIRES_CUSTOM_ID = "BUTTON_REQUIRES_CUSTOM_ID", BUTTON_REQUIRES_CUSTOM_ID = "BUTTON_REQUIRES_CUSTOM_ID",
COMPONENT_SELECT_MUST_BE_ALONE = "COMPONENT_SELECT_MUST_BE_ALONE", COMPONENT_SELECT_MUST_BE_ALONE = "COMPONENT_SELECT_MUST_BE_ALONE",
COMPONENT_PLACEHOLDER_TOO_BIG = "COMPONENT_PLACEHOLDER_TOO_BIG", COMPONENT_PLACEHOLDER_TOO_BIG = "COMPONENT_PLACEHOLDER_TOO_BIG",
COMPONENT_SELECT_MINVALUE_TOO_LOW = "COMPONENT_SELECT_MINVALUE_TOO_LOW", COMPONENT_SELECT_MIN_VALUE_TOO_LOW = "COMPONENT_SELECT_MIN_VALUE_TOO_LOW",
COMPONENT_SELECT_MINVALUE_TOO_MANY = "COMPONENT_SELECT_MINVALUE_TOO_MANY", COMPONENT_SELECT_MIN_VALUE_TOO_MANY = "COMPONENT_SELECT_MIN_VALUE_TOO_MANY",
COMPONENT_SELECT_MAXVALUE_TOO_LOW = "COMPONENT_SELECT_MAXVALUE_TOO_LOW", COMPONENT_SELECT_MAX_VALUE_TOO_LOW = "COMPONENT_SELECT_MAX_VALUE_TOO_LOW",
COMPONENT_SELECT_MAXVALUE_TOO_MANY = "COMPONENT_SELECT_MAXVALUE_TOO_MANY", COMPONENT_SELECT_MAX_VALUE_TOO_MANY = "COMPONENT_SELECT_MAX_VALUE_TOO_MANY",
COMPONENT_SELECT_OPTIONS_TOO_LOW = "COMPONENT_SELECT_OPTIONS_TOO_LOW", COMPONENT_SELECT_OPTIONS_TOO_LOW = "COMPONENT_SELECT_OPTIONS_TOO_LOW",
COMPONENT_SELECT_OPTIONS_TOO_MANY = "COMPONENT_SELECT_OPTIONS_TOO_MANY", COMPONENT_SELECT_OPTIONS_TOO_MANY = "COMPONENT_SELECT_OPTIONS_TOO_MANY",
SELECT_OPTION_LABEL_TOO_BIG = "SELECT_OPTION_LABEL_TOO_BIG", SELECT_OPTION_LABEL_TOO_BIG = "SELECT_OPTION_LABEL_TOO_BIG",
+1 -1
View File
@@ -46,7 +46,7 @@ export class Collection<K, V> extends Map<K, V> {
} }
set(key: K, value: V) { set(key: K, value: V) {
// When this collection is maxSizeed make sure we can add first // When this collection is maxSized make sure we can add first
if ((this.maxSize || this.maxSize === 0) && this.size >= this.maxSize) { if ((this.maxSize || this.maxSize === 0) && this.size >= this.maxSize) {
return this; return this;
} }