This commit is contained in:
Skillz4Killz
2022-08-28 11:18:53 +00:00
committed by GitHub
176 changed files with 934 additions and 611 deletions

View File

@@ -1,10 +1,16 @@
import type { Bot } from "../../bot.ts";
import { ChannelTypes } from "../../types/shared.ts";
import { Channel } from "../../transformers/channel.ts";
import { DiscordChannel } from "../../types/discord.ts";
import { ChannelTypes } from "../../types/shared.ts";
import { OverwriteReadable } from "./editChannelOverwrite.ts";
/** 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,
): Promise<Channel> {
// BITRATE IS IN THOUSANDS SO IF USER PROVIDES 32 WE CONVERT TO 32000
if (options?.bitrate && options.bitrate < 1000) options.bitrate *= 1000;

View File

@@ -1,8 +1,9 @@
import type { Bot } from "../../bot.ts";
import { StageInstance } from "../../transformers/stageInstance.ts";
import { DiscordStageInstance } from "../../types/discord.ts";
/** Creates a new Stage instance associated to a Stage channel. Requires the user to be a moderator of the Stage channel. */
export async function createStageInstance(bot: Bot, options: CreateStageInstance) {
export async function createStageInstance(bot: Bot, options: CreateStageInstance): Promise<StageInstance> {
const result = await bot.rest.runMethod<DiscordStageInstance>(
bot.rest,
"POST",

View File

@@ -1,9 +1,8 @@
import type { Bot } from "../../bot.ts";
import { DiscordChannel } from "../../types/discord.ts";
/** Delete a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. Bot needs MANAGE_THREADS permissions in the server if deleting thread. */
export async function deleteChannel(bot: Bot, channelId: bigint, reason?: string) {
await bot.rest.runMethod<DiscordChannel>(
export async function deleteChannel(bot: Bot, channelId: bigint, reason?: string): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"DELETE",
bot.constants.routes.CHANNEL(channelId),

View File

@@ -1,8 +1,8 @@
import type { Bot } from "../../bot.ts";
/** Delete the channel permission overwrites for a user or role in this channel. Requires `MANAGE_ROLES` permission. */
export async function deleteChannelOverwrite(bot: Bot, channelId: bigint, overwriteId: bigint) {
await bot.rest.runMethod<undefined>(
export async function deleteChannelOverwrite(bot: Bot, channelId: bigint, overwriteId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"DELETE",
bot.constants.routes.CHANNEL_OVERWRITE(channelId, overwriteId),

View File

@@ -1,6 +1,6 @@
import type { Bot } from "../../bot.ts";
/** Deletes the Stage instance. Requires the user to be a moderator of the Stage channel. */
export async function deleteStageInstance(bot: Bot, channelId: bigint) {
await bot.rest.runMethod(bot.rest, "DELETE", bot.constants.routes.STAGE_INSTANCE(channelId));
export async function deleteStageInstance(bot: Bot, channelId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "DELETE", bot.constants.routes.STAGE_INSTANCE(channelId));
}

View File

@@ -5,7 +5,12 @@ import { ChannelTypes, VideoQualityModes } from "../../types/shared.ts";
import { OverwriteReadable } from "./editChannelOverwrite.ts";
/** Update a channel's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */
export async function editChannel(bot: Bot, channelId: bigint, options: ModifyChannel, reason?: string) {
export async function editChannel(
bot: Bot,
channelId: bigint,
options: ModifyChannel,
reason?: string,
): Promise<Channel> {
if (options.name || options.topic) {
const request = editChannelNameTopicQueue.get(channelId);
if (!request) {
@@ -81,7 +86,7 @@ interface EditChannelRequest {
const editChannelNameTopicQueue = new Map<bigint, EditChannelRequest>();
let editChannelProcessing = false;
function processEditChannelQueue(bot: Bot) {
function processEditChannelQueue(bot: Bot): void {
if (!editChannelProcessing) return;
const now = Date.now();

View File

@@ -6,8 +6,8 @@ export async function editChannelOverwrite(
bot: Bot,
channelId: bigint,
overwrite: OverwriteReadable,
) {
await bot.rest.runMethod<undefined>(
): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"PUT",
bot.constants.routes.CHANNEL_OVERWRITE(channelId, overwrite.id),

View File

@@ -2,8 +2,8 @@ import type { Bot } from "../../bot.ts";
import { DiscordFollowedChannel } from "../../types/discord.ts";
/** Follow a News Channel to send messages to a target channel. Requires the `MANAGE_WEBHOOKS` permission in the target channel. Returns the webhook id. */
export async function followChannel(bot: Bot, sourceChannelId: bigint, targetChannelId: bigint) {
const data = await bot.rest.runMethod<DiscordFollowedChannel>(
export async function followChannel(bot: Bot, sourceChannelId: bigint, targetChannelId: bigint): Promise<bigint> {
const result = await bot.rest.runMethod<DiscordFollowedChannel>(
bot.rest,
"POST",
bot.constants.routes.CHANNEL_FOLLOW(sourceChannelId),
@@ -12,5 +12,5 @@ export async function followChannel(bot: Bot, sourceChannelId: bigint, targetCha
},
);
return bot.transformers.snowflake(data.webhook_id);
return bot.transformers.snowflake(result.webhook_id);
}

View File

@@ -1,14 +1,15 @@
import type { Bot } from "../../../bot.ts";
import { Channel } from "../../../transformers/channel.ts";
import { Embed } from "../../../transformers/embed.ts";
import { DiscordChannel } from "../../../types/discord.ts";
import { AllowedMentions, FileContent, MessageComponents } from "../../../types/mod.ts";
import { Embed } from "../../../transformers/embed.ts";
/** Creates a new public thread from an existing message. Returns a thread channel. */
export async function createForumPost(
bot: Bot,
channelId: bigint,
options: CreateForumPostWithMessage,
) {
): Promise<Channel> {
const result = await bot.rest.runMethod<DiscordChannel>(
bot.rest,
"POST",

View File

@@ -1,8 +1,9 @@
import type { Bot } from "../../bot.ts";
import { Channel } from "../../transformers/channel.ts";
import { DiscordChannel } from "../../types/discord.ts";
/** Fetches a single channel object from the api. */
export async function getChannel(bot: Bot, channelId: bigint) {
export async function getChannel(bot: Bot, channelId: bigint): Promise<Channel> {
const result = await bot.rest.runMethod<DiscordChannel>(
bot.rest,
"GET",

View File

@@ -1,17 +1,20 @@
import { Collection } from "../../util/collection.ts";
import type { Bot } from "../../bot.ts";
import { Webhook } from "../../transformers/webhook.ts";
import { DiscordWebhook } from "../../types/discord.ts";
import { Collection } from "../../util/collection.ts";
/** Gets the webhooks for this channel. Requires MANAGE_WEBHOOKS */
export async function getChannelWebhooks(bot: Bot, channelId: bigint) {
const result = await bot.rest.runMethod<DiscordWebhook[]>(
export async function getChannelWebhooks(bot: Bot, channelId: bigint): Promise<Collection<bigint, Webhook>> {
const results = await bot.rest.runMethod<DiscordWebhook[]>(
bot.rest,
"GET",
bot.constants.routes.CHANNEL_WEBHOOKS(channelId),
);
return new Collection(result.map((hook) => {
const webhook = bot.transformers.webhook(bot, hook);
return [webhook.id, webhook];
}));
return new Collection(
results.map((result) => {
const webhook = bot.transformers.webhook(bot, result);
return [webhook.id, webhook];
}),
);
}

View File

@@ -1,16 +1,20 @@
import { Collection } from "../../util/collection.ts";
import type { Bot } from "../../bot.ts";
import { Channel } from "../../transformers/channel.ts";
import { DiscordChannel } from "../../types/discord.ts";
import { Collection } from "../../util/collection.ts";
/** Returns a list of guild channel objects. */
export async function getChannels(bot: Bot, guildId: bigint) {
const result = await bot.rest.runMethod<DiscordChannel[]>(
export async function getChannels(bot: Bot, guildId: bigint): Promise<Collection<bigint, Channel>> {
const results = await bot.rest.runMethod<DiscordChannel[]>(
bot.rest,
"GET",
bot.constants.routes.GUILD_CHANNELS(guildId),
);
return new Collection(
result.map((res) => bot.transformers.channel(bot, { channel: res, guildId })).map((c) => [c.id, c]),
results.map((result) => {
const channel = bot.transformers.channel(bot, { channel: result, guildId });
return [channel.id, channel];
}),
);
}

View File

@@ -1,13 +1,20 @@
import type { Bot } from "../../bot.ts";
import { Message } from "../../transformers/message.ts";
import { DiscordMessage } from "../../types/discord.ts";
import { Collection } from "../../util/collection.ts";
/** Get pinned messages in this channel. */
export async function getPins(bot: Bot, channelId: bigint) {
const result = await bot.rest.runMethod<DiscordMessage[]>(
export async function getPins(bot: Bot, channelId: bigint): Promise<Collection<bigint, Message>> {
const results = await bot.rest.runMethod<DiscordMessage[]>(
bot.rest,
"GET",
bot.constants.routes.CHANNEL_PINS(channelId),
);
return result.map((msg) => bot.transformers.message(bot, msg));
return new Collection(
results.map((result) => {
const message = bot.transformers.message(bot, result);
return [message.id, message];
}),
);
}

View File

@@ -1,8 +1,9 @@
import type { Bot } from "../../bot.ts";
import { StageInstance } from "../../transformers/stageInstance.ts";
import { DiscordStageInstance } from "../../types/discord.ts";
/** Gets the stage instance associated with the Stage channel, if it exists. */
export async function getStageInstance(bot: Bot, channelId: bigint) {
export async function getStageInstance(bot: Bot, channelId: bigint): Promise<StageInstance> {
const result = await bot.rest.runMethod<DiscordStageInstance>(
bot.rest,
"GET",

View File

@@ -5,6 +5,6 @@ import type { Bot } from "../../bot.ts";
* However, if a bot is responding to a command and expects the computation to take a few seconds,
* this endpoint may be called to let the user know that the bot is processing their message.
*/
export async function startTyping(bot: Bot, channelId: bigint) {
await bot.rest.runMethod<undefined>(bot.rest, "POST", bot.constants.routes.CHANNEL_TYPING(channelId));
export async function startTyping(bot: Bot, channelId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "POST", bot.constants.routes.CHANNEL_TYPING(channelId));
}

View File

@@ -1,23 +1,25 @@
import type { Bot } from "../../bot.ts";
/** Modify the positions of channels on the guild. Requires MANAGE_CHANNELS permission. Only channels to be modified are required. */
export async function swapChannels(bot: Bot, guildId: bigint, channelPositions: ModifyGuildChannelPositions[]) {
export async function swapChannels(
bot: Bot,
guildId: bigint,
channelPositions: ModifyGuildChannelPositions[],
): Promise<void> {
if (!channelPositions.length) {
throw "You must provide at least one channels to be moved.";
throw new Error("You must provide at least one channels to be moved.");
}
await bot.rest.runMethod<undefined>(
return await bot.rest.runMethod<void>(
bot.rest,
"PATCH",
bot.constants.routes.GUILD_CHANNELS(guildId),
channelPositions.map((channelPosition) => {
return {
id: channelPosition.id,
position: channelPosition.position,
lock_positions: channelPosition.lockPositions,
parent_id: channelPosition.parentId,
};
}),
channelPositions.map((channelPosition) => ({
id: channelPosition.id,
position: channelPosition.position,
lock_positions: channelPosition.lockPositions,
parent_id: channelPosition.parentId,
})),
);
}

View File

@@ -1,6 +1,6 @@
import type { Bot } from "../../../bot.ts";
/** Adds a user to a thread. Requires the ability to send messages in the thread. Requires the thread is not archived. */
export async function addToThread(bot: Bot, threadId: bigint, userId: bigint) {
await bot.rest.runMethod<undefined>(bot.rest, "PUT", bot.constants.routes.THREAD_USER(threadId, userId));
export async function addToThread(bot: Bot, threadId: bigint, userId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "PUT", bot.constants.routes.THREAD_USER(threadId, userId));
}

View File

@@ -1,10 +1,16 @@
import type { Bot } from "../../../bot.ts";
import { Channel, ThreadMember } from "../../../mod.ts";
import { DiscordListActiveThreads } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
export type ActiveThreads = {
threads: Collection<bigint, Channel>;
members: Collection<bigint, ThreadMember>;
};
/** Returns all active threads in the guild, including public and private threads. Threads are ordered by their `id`, in descending order. */
export async function getActiveThreads(bot: Bot, guildId: bigint) {
const result = await bot.rest.runMethod<DiscordListActiveThreads>(
export async function getActiveThreads(bot: Bot, guildId: bigint): Promise<ActiveThreads> {
const results = await bot.rest.runMethod<DiscordListActiveThreads>(
bot.rest,
"GET",
bot.constants.routes.THREAD_ACTIVE(guildId),
@@ -12,15 +18,15 @@ export async function getActiveThreads(bot: Bot, guildId: bigint) {
return {
threads: new Collection(
result.threads.map((t) => {
const thread = bot.transformers.channel(bot, { channel: t });
results.threads.map((result) => {
const thread = bot.transformers.channel(bot, { channel: result });
return [thread.id, thread];
}),
),
members: new Collection(
result.members.map((m) => {
const member = bot.transformers.threadMember(bot, m);
return [member.id, member];
results.members.map((result) => {
const member = bot.transformers.threadMember(bot, result);
return [member.id!, member];
}),
),
};

View File

@@ -1,6 +1,11 @@
import { Collection } from "../../../util/collection.ts";
import type { Bot } from "../../../bot.ts";
import { DiscordListArchivedThreads } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
import { ActiveThreads } from "./getActiveThreads.ts";
export type ArchivedThreads = ActiveThreads & {
hasMore: boolean;
};
/** Get the archived threads for this channel, defaults to public */
export async function getArchivedThreads(
@@ -9,33 +14,33 @@ export async function getArchivedThreads(
options?: ListArchivedThreads & {
type?: "public" | "private" | "privateJoinedThreads";
},
) {
let url = options?.type === "privateJoinedThreads"
): Promise<ArchivedThreads> {
const url = options?.type === "privateJoinedThreads"
? bot.constants.routes.THREAD_ARCHIVED_PRIVATE_JOINED(channelId, options)
: options?.type === "private"
? bot.constants.routes.THREAD_ARCHIVED_PRIVATE(channelId, options)
: bot.constants.routes.THREAD_ARCHIVED_PUBLIC(channelId, options);
const result = (await bot.rest.runMethod<DiscordListArchivedThreads>(
const results = await bot.rest.runMethod<DiscordListArchivedThreads>(
bot.rest,
"GET",
url,
));
);
return {
threads: new Collection(
result.threads.map((t) => {
const thread = bot.transformers.channel(bot, { channel: t });
results.threads.map((result) => {
const thread = bot.transformers.channel(bot, { channel: result });
return [thread.id, thread];
}),
),
members: new Collection(
result.members.map((m) => {
const member = bot.transformers.threadMember(bot, m);
return [member.id, member];
results.members.map((result) => {
const member = bot.transformers.threadMember(bot, result);
return [member.id!, member];
}),
),
hasMore: result.has_more,
hasMore: results.has_more,
};
}

View File

@@ -1,18 +1,14 @@
import type { Bot } from "../../../bot.ts";
import { ThreadMember } from "../../../transformers/threadMember.ts";
import { DiscordThreadMember } from "../../../types/discord.ts";
/** Returns thread members objects that are members of the thread. */
export async function getThreadMember(bot: Bot, threadId: bigint, userId: bigint) {
export async function getThreadMember(bot: Bot, threadId: bigint, userId: bigint): Promise<ThreadMember> {
const result = await bot.rest.runMethod<DiscordThreadMember>(
bot.rest,
"GET",
bot.constants.routes.THREAD_USER(threadId, userId),
);
return {
id: result.id ? bot.transformers.snowflake(result.id) : undefined,
userId: result.user_id ? bot.transformers.snowflake(result.user_id) : undefined,
joinTimestamp: Date.parse(result.join_timestamp),
flags: result.flags,
};
return bot.transformers.threadMember(bot, result);
}

View File

@@ -1,18 +1,20 @@
import type { Bot } from "../../../bot.ts";
import { ThreadMember } from "../../../transformers/threadMember.ts";
import { DiscordThreadMember } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
/** Returns thread members objects that are members of the thread. */
export async function getThreadMembers(bot: Bot, threadId: bigint) {
const result = await bot.rest.runMethod<DiscordThreadMember[]>(
export async function getThreadMembers(bot: Bot, threadId: bigint): Promise<Collection<bigint, ThreadMember>> {
const results = await bot.rest.runMethod<DiscordThreadMember[]>(
bot.rest,
"GET",
bot.constants.routes.THREAD_MEMBERS(threadId),
);
// return result;
return new Collection(result.map((res) => {
const member = bot.transformers.threadMember(bot, res);
return [member.id, member];
}));
return new Collection(
results.map((result) => {
const member = bot.transformers.threadMember(bot, result);
return [member.id!, member];
}),
);
}

View File

@@ -1,6 +1,6 @@
import type { Bot } from "../../../bot.ts";
/** Adds the bot to the thread. Cannot join an archived thread. */
export async function joinThread(bot: Bot, threadId: bigint) {
await bot.rest.runMethod<undefined>(bot.rest, "PUT", bot.constants.routes.THREAD_ME(threadId));
export async function joinThread(bot: Bot, threadId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "PUT", bot.constants.routes.THREAD_ME(threadId));
}

View File

@@ -1,6 +1,6 @@
import type { Bot } from "../../../bot.ts";
/** Removes the bot from a thread. Requires the thread is not archived. */
export async function leaveThread(bot: Bot, threadId: bigint) {
await bot.rest.runMethod<undefined>(bot.rest, "DELETE", bot.constants.routes.THREAD_ME(threadId));
export async function leaveThread(bot: Bot, threadId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "DELETE", bot.constants.routes.THREAD_ME(threadId));
}

View File

@@ -1,6 +1,10 @@
import type { Bot } from "../../../bot.ts";
/** Removes a user from a thread. Requires the MANAGE_THREADS permission or that you are the creator of the thread. Also requires the thread is not archived. */
export async function removeThreadMember(bot: Bot, threadId: bigint, userId: bigint) {
await bot.rest.runMethod<undefined>(bot.rest, "DELETE", bot.constants.routes.THREAD_USER(threadId, userId));
export async function removeThreadMember(bot: Bot, threadId: bigint, userId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"DELETE",
bot.constants.routes.THREAD_USER(threadId, userId),
);
}

View File

@@ -1,4 +1,5 @@
import type { Bot } from "../../../bot.ts";
import { Channel } from "../../../transformers/channel.ts";
import { DiscordChannel } from "../../../types/discord.ts";
/** Creates a new public thread from an existing message. Returns a thread channel. */
@@ -7,7 +8,7 @@ export async function startThreadWithMessage(
channelId: bigint,
messageId: bigint,
options: StartThreadWithMessage,
) {
): Promise<Channel> {
const result = await bot.rest.runMethod<DiscordChannel>(
bot.rest,
"POST",

View File

@@ -1,9 +1,14 @@
import type { Bot } from "../../../bot.ts";
import { Channel } from "../../../transformers/channel.ts";
import { DiscordChannel } from "../../../types/discord.ts";
import { ChannelTypes } from "../../../types/shared.ts";
/** Creates a new private thread. Returns a thread channel. */
export async function startThreadWithoutMessage(bot: Bot, channelId: bigint, options: StartThreadWithoutMessage) {
export async function startThreadWithoutMessage(
bot: Bot,
channelId: bigint,
options: StartThreadWithoutMessage,
): Promise<Channel> {
const result = await bot.rest.runMethod<DiscordChannel>(
bot.rest,
"POST",

View File

@@ -1,4 +1,5 @@
import type { Bot } from "../../bot.ts";
import { StageInstance } from "../../transformers/stageInstance.ts";
import { DiscordStageInstance } from "../../types/discord.ts";
import { AtLeastOne } from "../../types/shared.ts";
@@ -7,7 +8,7 @@ export async function updateStageInstance(
bot: Bot,
channelId: bigint,
data: AtLeastOne<Pick<DiscordStageInstance, "topic">>,
) {
): Promise<StageInstance> {
const result = await bot.rest.runMethod<DiscordStageInstance>(
bot.rest,
"PATCH",

View File

@@ -10,8 +10,8 @@ import type { Bot } from "../../bot.ts";
* - You are able to set `request_to_speak_timestamp` to any present or future time.
* - When suppressed, the user will have their `request_to_speak_timestamp` removed.
*/
export async function updateBotVoiceState(bot: Bot, guildId: bigint, options: UpdateSelfVoiceState) {
await bot.rest.runMethod(bot.rest, "PATCH", bot.constants.routes.UPDATE_VOICE_STATE(guildId), {
export async function updateBotVoiceState(bot: Bot, guildId: bigint, options: UpdateSelfVoiceState): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "PATCH", bot.constants.routes.UPDATE_VOICE_STATE(guildId), {
channel_id: options.channelId,
suppress: options.suppress,
request_to_speak_timestamp: options.requestToSpeakTimestamp
@@ -31,8 +31,8 @@ export async function updateBotVoiceState(bot: Bot, guildId: bigint, options: Up
* - You are able to set `request_to_speak_timestamp` to any present or future time.
* - When suppressed, the user will have their `request_to_speak_timestamp` removed.
*/
export async function updateUserVoiceState(bot: Bot, guildId: bigint, options: UpdateOthersVoiceState) {
await bot.rest.runMethod(
export async function updateUserVoiceState(bot: Bot, guildId: bigint, options: UpdateOthersVoiceState): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"PATCH",
bot.constants.routes.UPDATE_VOICE_STATE(guildId, options.userId),

View File

@@ -1,9 +1,8 @@
import type { Bot } from "../../bot.ts";
import { DiscordAddGuildDiscoverySubcategory } from "../../types/discord.ts";
/** Add a discovery subcategory to the guild. Requires the `MANAGE_GUILD` permission. */
export async function addDiscoverySubcategory(bot: Bot, guildId: bigint, categoryId: number) {
await bot.rest.runMethod<DiscordAddGuildDiscoverySubcategory>(
export async function addDiscoverySubcategory(bot: Bot, guildId: bigint, categoryId: number): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"POST",
bot.constants.routes.DISCOVERY_SUBCATEGORY(guildId, categoryId),

View File

@@ -0,0 +1,10 @@
import type { Bot } from "../../bot.ts";
/** Deletes a discovery subcategory from the guild. Requires the MANAGE_GUILD permission. Returns a 204 No Content on success. */
export async function deleteDiscoverySubcategory(bot: Bot, guildId: bigint, categoryId: number): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"DELETE",
bot.constants.routes.DISCOVERY_SUBCATEGORY(guildId, categoryId),
);
}

View File

@@ -1,8 +1,13 @@
import type { Bot } from "../../bot.ts";
import { DiscordDiscoveryMetadata } from "../../types/discord.ts";
import { DiscoveryMetadata } from "./getDiscovery.ts";
/** Modify the discovery metadata for the guild. Requires the MANAGE_GUILD permission. Returns the updated discovery metadata object on success. */
export async function editDiscovery(bot: Bot, guildId: bigint, data: ModifyGuildDiscoveryMetadata) {
export async function editDiscovery(
bot: Bot,
guildId: bigint,
data: ModifyGuildDiscoveryMetadata,
): Promise<DiscoveryMetadata> {
const result = await bot.rest.runMethod<DiscordDiscoveryMetadata>(
bot.rest,
"PATCH",
@@ -16,7 +21,7 @@ export async function editDiscovery(bot: Bot, guildId: bigint, data: ModifyGuild
return {
guildId,
primaryCategoryId: result.primary_category_id,
primaryCategoryId: BigInt(result.primary_category_id),
keywords: result.keywords ?? undefined,
emojiDiscoverabilityEnabled: result.emoji_discoverability_enabled,
partnerActionedTimestamp: result.partner_actioned_timestamp

View File

@@ -1,8 +1,18 @@
import type { Bot } from "../../bot.ts";
import { DiscordDiscoveryMetadata } from "../../types/discord.ts";
export type DiscoveryMetadata = {
guildId: bigint;
primaryCategoryId: number;
keywords?: string[];
emojiDiscoverabilityEnabled: boolean;
partnerActionedTimestamp?: number;
partnerApplicationTimestamp?: number;
categoryIds: number[];
};
/** Returns the discovery metadata object for the guild. Requires the `MANAGE_GUILD` permission. */
export async function getDiscovery(bot: Bot, guildId: bigint) {
export async function getDiscovery(bot: Bot, guildId: bigint): Promise<DiscoveryMetadata> {
const result = await bot.rest.runMethod<DiscordDiscoveryMetadata>(
bot.rest,
"GET",

View File

@@ -1,16 +1,30 @@
import { Collection } from "../../util/collection.ts";
import type { Bot } from "../../bot.ts";
import { DiscordDiscoveryCategory } from "../../types/discord.ts";
import { Collection } from "../../util/collection.ts";
export type DiscoveryCategory = {
id: bigint;
name: DiscoveryName;
isPrimary: boolean;
};
export type DiscoveryName = {
default: string;
localizations?: Record<string, string>;
};
/** Returns a Collection (mapped by Id of the discovery category object) of discovery category objects that can be used when editing guilds */
export async function getDiscoveryCategories(bot: Bot) {
const result = await bot.rest.runMethod<DiscordDiscoveryCategory[]>(
export async function getDiscoveryCategories(bot: Bot): Promise<Collection<bigint, DiscoveryCategory>> {
const results = await bot.rest.runMethod<DiscordDiscoveryCategory[]>(
bot.rest,
"GET",
bot.constants.routes.DISCOVERY_CATEGORIES(),
);
return new Collection<number, DiscordDiscoveryCategory>(
result.map((category) => [category.id, category]),
return new Collection(
results.map((result) => {
const category = { id: BigInt(result.id), name: result.name, isPrimary: result.is_primary };
return [category.id, category];
}),
);
}

View File

@@ -1,7 +1,7 @@
import type { Bot } from "../../bot.ts";
import { DiscordValidateDiscoverySearchTerm } from "../../types/discord.ts";
export async function validDiscoveryTerm(bot: Bot, term: string) {
export async function getIsValidDiscoveryTerm(bot: Bot, term: string): Promise<boolean> {
const result = await bot.rest.runMethod<DiscordValidateDiscoverySearchTerm>(
bot.rest,
"GET",

View File

@@ -1,6 +1,6 @@
export * from "./addDiscoverySubcategory.ts";
export * from "./deleteDiscoverySubcategory.ts";
export * from "./editDiscovery.ts";
export * from "./getDiscovery.ts";
export * from "./getDiscoveryCategories.ts";
export * from "./removeDiscoverySubcategory.ts";
export * from "./validDiscoveryTerm.ts";
export * from "./getIsValidDiscoveryTerm.ts";

View File

@@ -1,10 +0,0 @@
import type { Bot } from "../../bot.ts";
/** Removes a discovery subcategory from the guild. Requires the MANAGE_GUILD permission. Returns a 204 No Content on success. */
export async function removeDiscoverySubcategory(bot: Bot, guildId: bigint, categoryId: number) {
await bot.rest.runMethod<undefined>(
bot.rest,
"DELETE",
bot.constants.routes.DISCOVERY_SUBCATEGORY(guildId, categoryId),
);
}

View File

@@ -1,13 +1,14 @@
import type { Bot } from "../../bot.ts";
import { Emoji } from "../../transformers/emoji.ts";
import { DiscordEmoji } from "../../types/discord.ts";
/** Create an emoji in the server */
export async function createEmoji(bot: Bot, guildId: bigint, options: CreateGuildEmoji) {
export async function createEmoji(bot: Bot, guildId: bigint, options: CreateGuildEmoji): Promise<Emoji> {
if (options.image && !options.image.startsWith("data:image/")) {
options.image = await bot.utils.urlToBase64(options.image);
}
const emoji = await bot.rest.runMethod<DiscordEmoji>(
const result = await bot.rest.runMethod<DiscordEmoji>(
bot.rest,
"POST",
bot.constants.routes.GUILD_EMOJIS(guildId),
@@ -19,7 +20,7 @@ export async function createEmoji(bot: Bot, guildId: bigint, options: CreateGuil
},
);
return bot.transformers.emoji(bot, emoji);
return bot.transformers.emoji(bot, result);
}
/** https://discord.com/developers/docs/resources/emoji#create-guild-emoji */

View File

@@ -1,8 +1,8 @@
import type { Bot } from "../../bot.ts";
/** Delete the given emoji. Requires the MANAGE_EMOJIS permission. Returns 204 No Content on success. */
export async function deleteEmoji(bot: Bot, guildId: bigint, id: bigint, reason?: string) {
await bot.rest.runMethod<undefined>(bot.rest, "DELETE", bot.constants.routes.GUILD_EMOJI(guildId, id), {
export async function deleteEmoji(bot: Bot, guildId: bigint, id: bigint, reason?: string): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "DELETE", bot.constants.routes.GUILD_EMOJI(guildId, id), {
reason,
});
}

View File

@@ -1,8 +1,9 @@
import type { Bot } from "../../bot.ts";
import { Emoji } from "../../transformers/emoji.ts";
import { DiscordEmoji } from "../../types/discord.ts";
/** Modify the given emoji. Requires the MANAGE_EMOJIS permission. */
export async function editEmoji(bot: Bot, guildId: bigint, id: bigint, options: ModifyGuildEmoji) {
export async function editEmoji(bot: Bot, guildId: bigint, id: bigint, options: ModifyGuildEmoji): Promise<Emoji> {
const result = await bot.rest.runMethod<DiscordEmoji>(
bot.rest,
"PATCH",

View File

@@ -1,10 +1,11 @@
import type { Bot } from "../../bot.ts";
import { Emoji } from "../../transformers/emoji.ts";
import { DiscordEmoji } from "../../types/discord.ts";
/**
* Returns an emoji for the given guild and emoji Id.
*/
export async function getEmoji(bot: Bot, guildId: bigint, emojiId: bigint) {
export async function getEmoji(bot: Bot, guildId: bigint, emojiId: bigint): Promise<Emoji> {
const result = await bot.rest.runMethod<DiscordEmoji>(
bot.rest,
"GET",

View File

@@ -1,6 +1,6 @@
import { Bot } from "../../bot.ts";
/** Creates a url to the emoji from the Discord CDN. */
export function emojiUrl(bot: Bot, id: bigint, animated = false) {
export function getEmojiURL(_bot: Bot, id: bigint, animated = false): string {
return `https://cdn.discordapp.com/emojis/${id}.${animated ? "gif" : "png"}`;
}

View File

@@ -1,16 +1,22 @@
import type { Bot } from "../../bot.ts";
import { Emoji } from "../../transformers/emoji.ts";
import { DiscordEmoji } from "../../types/discord.ts";
import { Collection } from "../../util/collection.ts";
/**
* Returns a list of emojis for the given guild.
*/
export async function getEmojis(bot: Bot, guildId: bigint) {
const result = await bot.rest.runMethod<DiscordEmoji[]>(
export async function getEmojis(bot: Bot, guildId: bigint): Promise<Collection<bigint, Emoji>> {
const results = await bot.rest.runMethod<DiscordEmoji[]>(
bot.rest,
"GET",
bot.constants.routes.GUILD_EMOJIS(guildId),
);
return new Collection(result.map((e) => [bot.transformers.snowflake(e.id!), bot.transformers.emoji(bot, e)]));
return new Collection(
results.map((result) => {
const emoji = bot.transformers.emoji(bot, result);
return [emoji.id!, emoji];
}),
);
}

View File

@@ -1,6 +1,7 @@
export * from "./createEmoji.ts";
export * from "./deleteEmoji.ts";
export * from "./editEmoji.ts";
export * from "./emojiUrl.ts";
export * from "./getEmoji.ts";
export * from "./getEmojis.ts";
export * from "./getEmojiUrl.ts";

View File

@@ -1,4 +1,5 @@
import { Bot } from "../../../bot.ts";
import { AutoModerationRule } from "../../../transformers/automodRule.ts";
import {
AutoModerationActionType,
AutoModerationEventTypes,
@@ -8,8 +9,12 @@ import {
} from "../../../types/discord.ts";
/** Get a rule currently configured for guild. */
export async function createAutomodRule(bot: Bot, guildId: bigint, options: CreateAutoModerationRuleOptions) {
const rule = await bot.rest.runMethod<DiscordAutoModerationRule>(
export async function createAutomodRule(
bot: Bot,
guildId: bigint,
options: CreateAutoModerationRuleOptions,
): Promise<AutoModerationRule> {
const result = await bot.rest.runMethod<DiscordAutoModerationRule>(
bot.rest,
"POST",
bot.constants.routes.AUTOMOD_RULES(guildId),
@@ -38,7 +43,7 @@ export async function createAutomodRule(bot: Bot, guildId: bigint, options: Crea
},
);
return bot.transformers.automodRule(bot, rule);
return bot.transformers.automodRule(bot, result);
}
export interface CreateAutoModerationRuleOptions {

View File

@@ -1,8 +1,8 @@
import { Bot } from "../../../bot.ts";
/** Delete a rule currently configured for guild. */
export async function deleteAutomodRule(bot: Bot, guildId: bigint, ruleId: bigint, reason?: string) {
await bot.rest.runMethod<undefined>(
export async function deleteAutomodRule(bot: Bot, guildId: bigint, ruleId: bigint, reason?: string): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"DELETE",
bot.constants.routes.AUTOMOD_RULE(guildId, ruleId),

View File

@@ -1,4 +1,5 @@
import { Bot } from "../../../bot.ts";
import { AutoModerationRule } from "../../../transformers/automodRule.ts";
import {
AutoModerationActionType,
AutoModerationEventTypes,
@@ -7,8 +8,12 @@ import {
} from "../../../types/discord.ts";
/** Edit a rule currently configured for guild. */
export async function editAutomodRule(bot: Bot, guildId: bigint, options: Partial<EditAutoModerationRuleOptions>) {
const rule = await bot.rest.runMethod<DiscordAutoModerationRule>(
export async function editAutomodRule(
bot: Bot,
guildId: bigint,
options: Partial<EditAutoModerationRuleOptions>,
): Promise<AutoModerationRule> {
const result = await bot.rest.runMethod<DiscordAutoModerationRule>(
bot.rest,
"PATCH",
bot.constants.routes.AUTOMOD_RULES(guildId),
@@ -36,7 +41,7 @@ export async function editAutomodRule(bot: Bot, guildId: bigint, options: Partia
},
);
return bot.transformers.automodRule(bot, rule);
return bot.transformers.automodRule(bot, result);
}
export interface EditAutoModerationRuleOptions {

View File

@@ -1,14 +1,14 @@
import { Bot } from "../../../bot.ts";
import { AutoModerationRule } from "../../../transformers/automodRule.ts";
import { DiscordAutoModerationRule } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
/** Get a rule currently configured for guild. */
export async function getAutomodRule(bot: Bot, guildId: bigint, ruleId: bigint) {
const rule = await bot.rest.runMethod<DiscordAutoModerationRule>(
export async function getAutomodRule(bot: Bot, guildId: bigint, ruleId: bigint): Promise<AutoModerationRule> {
const result = await bot.rest.runMethod<DiscordAutoModerationRule>(
bot.rest,
"GET",
bot.constants.routes.AUTOMOD_RULE(guildId, ruleId),
);
return bot.transformers.automodRule(bot, rule);
return bot.transformers.automodRule(bot, result);
}

View File

@@ -1,17 +1,20 @@
import { Bot } from "../../../bot.ts";
import { AutoModerationRule } from "../../../transformers/automodRule.ts";
import { DiscordAutoModerationRule } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
/** Get a list of all rules currently configured for guild. */
export async function getAutomodRules(bot: Bot, guildId: bigint) {
const rules = await bot.rest.runMethod<DiscordAutoModerationRule[]>(
export async function getAutomodRules(bot: Bot, guildId: bigint): Promise<Collection<bigint, AutoModerationRule>> {
const results = await bot.rest.runMethod<DiscordAutoModerationRule[]>(
bot.rest,
"GET",
bot.constants.routes.AUTOMOD_RULES(guildId),
);
return new Collection(rules.map((r) => {
const rule = bot.transformers.automodRule(bot, r);
return [rule.id, rule];
}));
return new Collection(
results.map((result) => {
const rule = bot.transformers.automodRule(bot, result);
return [rule.id, rule];
}),
);
}

View File

@@ -1,5 +1,5 @@
export * from "./createAutomodRule.ts";
export * from "./deleteAutomodRule.ts";
export * from "./editAutomodRule.ts";
export * from "./getAutomodRule.ts";
export * from "./getAutomodRules.ts";
export * from "./createAutomodRule.ts";
export * from "./editAutomodRule.ts";
export * from "./deleteAutomodRule.ts";

View File

@@ -1,5 +1,6 @@
import type { Bot } from "../../bot.ts";
import { Channel } from "../../transformers/channel.ts";
import { Guild } from "../../transformers/guild.ts";
import { Role } from "../../transformers/role.ts";
import { DiscordGuild } from "../../types/discord.ts";
import {
@@ -10,7 +11,7 @@ import {
} from "../../types/shared.ts";
/** Create a new guild. Returns a guild object on success. Fires a Guild Create Gateway event. This endpoint can be used only by bots in less than 10 guilds. */
export async function createGuild(bot: Bot, options: CreateGuild) {
export async function createGuild(bot: Bot, options: CreateGuild): Promise<Guild> {
const result = await bot.rest.runMethod<DiscordGuild>(bot.rest, "POST", bot.constants.routes.GUILDS(), {
name: options.name,
afk_channel_id: options.afkChannelId,

View File

@@ -1,6 +1,6 @@
import type { Bot } from "../../bot.ts";
/** Delete a guild permanently. User must be owner. Returns 204 No Content on success. Fires a Guild Delete Gateway event. */
export async function deleteGuild(bot: Bot, guildId: bigint) {
await bot.rest.runMethod<undefined>(bot.rest, "DELETE", bot.constants.routes.GUILD(guildId));
export async function deleteGuild(bot: Bot, guildId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "DELETE", bot.constants.routes.GUILD(guildId));
}

View File

@@ -1,4 +1,5 @@
import type { Bot } from "../../bot.ts";
import { Guild } from "../../transformers/guild.ts";
import { DiscordGuild } from "../../types/discord.ts";
import {
DefaultMessageNotificationLevels,
@@ -9,7 +10,7 @@ import {
} from "../../types/shared.ts";
/** Modify a guilds settings. Requires the MANAGE_GUILD permission. */
export async function editGuild(bot: Bot, guildId: bigint, options: ModifyGuild, shardId: number) {
export async function editGuild(bot: Bot, guildId: bigint, options: ModifyGuild, shardId: number): Promise<Guild> {
if (options.icon && !options.icon.startsWith("data:image/")) {
options.icon = await bot.utils.urlToBase64(options.icon);
}
@@ -50,10 +51,7 @@ export async function editGuild(bot: Bot, guildId: bigint, options: ModifyGuild,
},
);
return bot.transformers.guild(bot, {
guild: result,
shardId,
});
return bot.transformers.guild(bot, { guild: result, shardId });
}
/** https://discord.com/developers/docs/resources/guild#modify-guild */

View File

@@ -1,7 +1,12 @@
import type { Bot } from "../../bot.ts";
import { WelcomeScreen } from "../../transformers/welcomeScreen.ts";
import { DiscordWelcomeScreen } from "../../types/discord.ts";
export async function editWelcomeScreen(bot: Bot, guildId: bigint, options: ModifyGuildWelcomeScreen) {
export async function editWelcomeScreen(
bot: Bot,
guildId: bigint,
options: ModifyGuildWelcomeScreen,
): Promise<WelcomeScreen> {
const result = await bot.rest.runMethod<DiscordWelcomeScreen>(
bot.rest,
"PATCH",

View File

@@ -1,8 +1,14 @@
import type { Bot } from "../../bot.ts";
import { GuildWidgetSettings } from "../../transformers/widgetSettings.ts";
import { DiscordGuildWidgetSettings } from "../../types/discord.ts";
/** Modify a guild widget object for the guild. Requires the MANAGE_GUILD permission. */
export async function editWidget(bot: Bot, guildId: bigint, enabled: boolean, channelId?: string | null) {
export async function editWidget(
bot: Bot,
guildId: bigint,
enabled: boolean,
channelId?: string | null,
): Promise<GuildWidgetSettings> {
const result = await bot.rest.runMethod<DiscordGuildWidgetSettings>(
bot.rest,
"PATCH",

View File

@@ -1,22 +1,41 @@
import type { Bot } from "../../bot.ts";
import { AuditLogEntry } from "../../transformers/auditLogEntry.ts";
import { AutoModerationRule } from "../../transformers/automodRule.ts";
import { Channel } from "../../transformers/channel.ts";
import { Integration } from "../../transformers/integration.ts";
import { User } from "../../transformers/member.ts";
import { ScheduledEvent } from "../../transformers/scheduledEvent.ts";
import { Webhook } from "../../transformers/webhook.ts";
import { DiscordAuditLog } from "../../types/discord.ts";
import { AuditLogEvents } from "../../types/shared.ts";
/** Returns the audit logs for the guild. Requires VIEW AUDIT LOGS permission */
export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuildAuditLog) {
if (options?.limit) options.limit = options.limit >= 1 && options.limit <= 100 ? options.limit : 50;
export type AuditLog = {
auditLogEntries: AuditLogEntry[];
autoModerationRules?: AutoModerationRule[];
guildScheduledEvents?: ScheduledEvent[];
integrations: Partial<Omit<Integration, "guildId">>[];
threads: Channel[];
users: User[];
webhooks: Webhook[];
};
const auditlog = await bot.rest.runMethod<DiscordAuditLog>(
/** Returns the audit logs for the guild. Requires VIEW_AUDIT_LOGS permission */
export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuildAuditLog): Promise<AuditLog> {
if (options?.limit) {
options.limit = options.limit >= 1 && options.limit <= 100 ? options.limit : 50;
}
const result = await bot.rest.runMethod<DiscordAuditLog>(
bot.rest,
"GET",
bot.constants.routes.GUILD_AUDIT_LOGS(guildId, options),
);
return {
users: auditlog.users.map((user) => bot.transformers.user(bot, user)),
webhook: auditlog.webhooks.map((hook) => bot.transformers.webhook(bot, hook)),
auditLogEntries: auditlog.audit_log_entries.map((entry) => bot.transformers.auditLogEntry(bot, entry)),
integrations: auditlog.integrations.map((integration) => ({
auditLogEntries: result.audit_log_entries.map((entry) => bot.transformers.auditLogEntry(bot, entry)),
autoModerationRules: result.auto_moderation_rules?.map((rule) => bot.transformers.automodRule(bot, rule)),
guildScheduledEvents: result.guild_scheduled_events?.map((event) => bot.transformers.scheduledEvent(bot, event)),
integrations: result.integrations.map((integration) => ({
id: integration.id ? bot.transformers.snowflake(integration.id) : undefined,
name: integration.name,
type: integration.type,
@@ -27,10 +46,12 @@ export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuild
expireBehavior: integration.expire_behavior,
expireGracePeriod: integration.expire_grace_period,
user: integration.user ? bot.transformers.user(bot, integration.user) : undefined,
account: {
id: integration.account?.id ? bot.transformers.snowflake(integration.account.id) : undefined,
name: integration.account?.name,
},
account: integration.account
? {
id: bot.transformers.snowflake(integration.account.id),
name: integration.account.name,
}
: undefined,
syncedAt: integration.synced_at ? Date.parse(integration.synced_at) : undefined,
subscriberCount: integration.subscriber_count,
revoked: integration.revoked,
@@ -44,8 +65,9 @@ export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuild
}
: undefined,
})),
threads: auditlog.threads.map((thread) => bot.transformers.channel(bot, { channel: thread, guildId })),
scheduledEvents: auditlog.guild_scheduled_events?.map((event) => bot.transformers.scheduledEvent(bot, event)),
threads: result.threads.map((thread) => bot.transformers.channel(bot, { channel: thread, guildId })),
users: result.users.map((user) => bot.transformers.user(bot, user)),
webhooks: result.webhooks.map((hook) => bot.transformers.webhook(bot, hook)),
};
}

View File

@@ -1,19 +1,20 @@
import type { Bot } from "../../bot.ts";
import { VoiceRegions } from "../../transformers/voiceRegion.ts";
import { DiscordVoiceRegion } from "../../types/discord.ts";
import { Collection } from "../../util/collection.ts";
/** Returns an array of voice regions that can be used when creating servers. */
export async function getAvailableVoiceRegions(bot: Bot) {
const result = await bot.rest.runMethod<DiscordVoiceRegion[]>(
export async function getAvailableVoiceRegions(bot: Bot): Promise<Collection<string, VoiceRegions>> {
const results = await bot.rest.runMethod<DiscordVoiceRegion[]>(
bot.rest,
"GET",
bot.constants.routes.VOICE_REGIONS(),
);
return new Collection(
result.map((region) => {
const voiceRegion = bot.transformers.voiceRegion(bot, region);
return [voiceRegion.id, voiceRegion];
results.map((result) => {
const region = bot.transformers.voiceRegion(bot, result);
return [region.id, region];
}),
);
}

View File

@@ -1,8 +1,14 @@
import type { Bot } from "../../bot.ts";
import { User } from "../../transformers/member.ts";
import { DiscordBan } from "../../types/discord.ts";
export type Ban = {
reason?: string;
user: User;
};
/** Returns a ban object for the given user or a 404 not found if the ban cannot be found. Requires the BAN_MEMBERS permission. */
export async function getBan(bot: Bot, guildId: bigint, memberId: bigint) {
export async function getBan(bot: Bot, guildId: bigint, memberId: bigint): Promise<Ban> {
const result = await bot.rest.runMethod<DiscordBan>(
bot.rest,
"GET",
@@ -10,7 +16,7 @@ export async function getBan(bot: Bot, guildId: bigint, memberId: bigint) {
);
return {
reason: result.reason,
reason: result.reason ?? undefined,
user: bot.transformers.user(bot, result.user),
};
}

View File

@@ -1,24 +1,27 @@
import type { Bot } from "../../bot.ts";
import { Collection } from "../../util/collection.ts";
import { DiscordBan } from "../../types/discord.ts";
import { User } from "../../transformers/member.ts";
import { Collection } from "../../util/collection.ts";
import { Ban } from "./getBan.ts";
/** Returns a list of ban objects for the users banned from this guild. Requires the BAN_MEMBERS permission. */
export async function getBans(bot: Bot, guildId: bigint, options?: GetBans) {
export async function getBans(bot: Bot, guildId: bigint, options?: GetBans): Promise<Collection<bigint, Ban>> {
const results = await bot.rest.runMethod<DiscordBan[]>(
bot.rest,
"GET",
bot.constants.routes.GUILD_BANS(guildId, options),
);
return new Collection<bigint, { reason?: string; user: User }>(
results.map((res) => [
bot.transformers.snowflake(res.user.id),
{
reason: res.reason ?? undefined,
user: bot.transformers.user(bot, res.user),
},
]),
return new Collection(
results.map<[bigint, Ban]>((result) => {
const user = bot.transformers.user(bot, result.user);
return [
user.id,
{
reason: result.reason ?? undefined,
user: user,
},
];
}),
);
}

View File

@@ -1,4 +1,5 @@
import type { Bot } from "../../bot.ts";
import { Guild } from "../../transformers/guild.ts";
import { DiscordGuild } from "../../types/discord.ts";
/**
@@ -11,7 +12,7 @@ export async function getGuild(
options: { counts?: boolean } = {
counts: true,
},
) {
): Promise<Guild> {
const result = await bot.rest.runMethod<DiscordGuild>(
bot.rest,
"GET",

View File

@@ -1,8 +1,8 @@
import type { Bot } from "../../bot.ts";
import { ImageFormat, ImageSize } from "../members/avatarUrl.ts";
import { ImageFormat, ImageSize } from "../members/getAvatarUrl.ts";
/** The full URL of the banner from Discords CDN. Undefined if no banner is set. */
export function guildBannerURL(
export function getGuildBannerURL(
bot: Bot,
id: bigint,
options: {
@@ -10,7 +10,7 @@ export function guildBannerURL(
size?: ImageSize;
format?: ImageFormat;
},
) {
): string | undefined {
return options.banner
? bot.utils.formatImageURL(
bot.constants.routes.GUILD_BANNER(

View File

@@ -1,8 +1,8 @@
import type { Bot } from "../../bot.ts";
import { ImageFormat, ImageSize } from "../members/avatarUrl.ts";
import { ImageFormat, ImageSize } from "../members/getAvatarUrl.ts";
/** The full URL of the icon from Discords CDN. Undefined when no icon is set. */
export function guildIconURL(
export function getGuildIconURL(
bot: Bot,
id: bigint,
icon: bigint | undefined,
@@ -10,7 +10,7 @@ export function guildIconURL(
size?: ImageSize;
format?: ImageFormat;
},
) {
): string | undefined {
return icon
? bot.utils.formatImageURL(
bot.constants.routes.GUILD_ICON(

View File

@@ -1,8 +1,25 @@
import type { Bot } from "../../bot.ts";
import { Emoji } from "../../transformers/emoji.ts";
import { Sticker } from "../../transformers/sticker.ts";
import { DiscordGuildPreview } from "../../types/discord.ts";
import { GuildFeatures } from "../../types/shared.ts";
export type GuildPreview = {
id: bigint;
name?: string;
icon?: string;
splash?: string;
discoverySplash?: string;
emojis?: Emoji[];
features: GuildFeatures[];
approximateMemberCount: number;
approximatePresenceCount: number;
description?: string;
stickers: Sticker[];
};
/** Returns the guild preview object for the given id. If the bot is not in the guild, then the guild must be Discoverable. */
export async function getGuildPreview(bot: Bot, guildId: bigint) {
export async function getGuildPreview(bot: Bot, guildId: bigint): Promise<GuildPreview> {
const result = await bot.rest.runMethod<DiscordGuildPreview>(
bot.rest,
"GET",

View File

@@ -1,8 +1,8 @@
import type { Bot } from "../../bot.ts";
import { ImageFormat, ImageSize } from "../members/avatarUrl.ts";
import { ImageFormat, ImageSize } from "../members/getAvatarUrl.ts";
/** The full URL of the splash from Discords CDN. Undefined if no splash is set. */
export function guildSplashURL(
export function getGuildSplashURL(
bot: Bot,
id: bigint,
splash: bigint | undefined,
@@ -10,7 +10,7 @@ export function guildSplashURL(
size?: ImageSize;
format?: ImageFormat;
},
) {
): string | undefined {
return splash
? bot.utils.formatImageURL(
bot.constants.routes.GUILD_SPLASH(

View File

@@ -1,17 +1,21 @@
import type { Bot } from "../../bot.ts";
interface DiscordPrunedCount {
pruned: number;
}
/** Check how many members would be removed from the server in a prune operation. Requires the KICK_MEMBERS permission */
export async function getPruneCount(bot: Bot, guildId: bigint, options?: GetGuildPruneCountQuery) {
export async function getPruneCount(bot: Bot, guildId: bigint, options?: GetGuildPruneCountQuery): Promise<number> {
if (options?.days && options.days < 1) throw new Error(bot.constants.Errors.PRUNE_MIN_DAYS);
if (options?.days && options.days > 30) throw new Error(bot.constants.Errors.PRUNE_MAX_DAYS);
const result = await bot.rest.runMethod(
const result = await bot.rest.runMethod<DiscordPrunedCount>(
bot.rest,
"GET",
bot.constants.routes.GUILD_PRUNE(guildId),
);
return result.pruned as number;
return result.pruned;
}
/** https://discord.com/developers/docs/resources/guild#get-guild-prune-count */

View File

@@ -1,16 +1,15 @@
import type { Bot } from "../../bot.ts";
import { DiscordInviteMetadata } from "../../types/discord.ts";
export type VanityUrl = {
code?: string;
uses: number;
};
/** Returns the code and uses of the vanity url for this server if it is enabled else `code` will be null. Requires the `MANAGE_GUILD` permission. */
export async function getVanityUrl(bot: Bot, guildId: bigint) {
const result = await bot.rest.runMethod<Partial<DiscordInviteMetadata>>(
export async function getVanityUrl(bot: Bot, guildId: bigint): Promise<VanityUrl> {
return await bot.rest.runMethod<VanityUrl>(
bot.rest,
"GET",
bot.constants.routes.GUILD_VANITY_URL(guildId),
);
return {
uses: result.uses,
code: result.code,
};
}

View File

@@ -1,18 +1,19 @@
import { Collection } from "../../util/collection.ts";
import type { Bot } from "../../bot.ts";
import { VoiceRegions } from "../../transformers/voiceRegion.ts";
import { DiscordVoiceRegion } from "../../types/discord.ts";
import { Collection } from "../../util/collection.ts";
/** Returns a list of voice region objects for the guild. Unlike the similar /voice route, this returns VIP servers when the guild is VIP-enabled. */
export async function getVoiceRegions(bot: Bot, guildId: bigint) {
const result = await bot.rest.runMethod<DiscordVoiceRegion[]>(
export async function getVoiceRegions(bot: Bot, guildId: bigint): Promise<Collection<string, VoiceRegions>> {
const results = await bot.rest.runMethod<DiscordVoiceRegion[]>(
bot.rest,
"GET",
bot.constants.routes.GUILD_REGIONS(guildId),
);
return new Collection(
result.map((reg) => {
const region = bot.transformers.voiceRegion(bot, reg);
results.map((result) => {
const region = bot.transformers.voiceRegion(bot, result);
return [region.id, region];
}),
);

View File

@@ -1,8 +1,9 @@
import type { Bot } from "../../bot.ts";
import { WelcomeScreen } from "../../transformers/welcomeScreen.ts";
import { DiscordWelcomeScreen } from "../../types/discord.ts";
/** Returns the Welcome Screen object for the guild. Requires the `MANAGE_GUILD` permission. */
export async function getWelcomeScreen(bot: Bot, guildId: bigint) {
export async function getWelcomeScreen(bot: Bot, guildId: bigint): Promise<WelcomeScreen> {
const result = await bot.rest.runMethod<DiscordWelcomeScreen>(
bot.rest,
"GET",

View File

@@ -1,8 +1,9 @@
import type { Bot } from "../../bot.ts";
import { GuildWidget } from "../../transformers/widget.ts";
import { DiscordGuildWidget } from "../../types/discord.ts";
/** Returns the widget for the guild. */
export async function getWidget(bot: Bot, guildId: bigint) {
export async function getWidget(bot: Bot, guildId: bigint): Promise<GuildWidget> {
const result = await bot.rest.runMethod<DiscordGuildWidget>(
bot.rest,
"GET",

View File

@@ -1,7 +1,7 @@
import type { Bot } from "../../bot.ts";
/** Returns the widget image URL for the guild. */
export async function getWidgetImageURL(bot: Bot, guildId: bigint, options?: GetGuildWidgetImageQuery) {
export function getWidgetImageURL(bot: Bot, guildId: bigint, options?: GetGuildWidgetImageQuery): string {
return bot.constants.routes.GUILD_WIDGET_IMAGE(guildId, options?.style);
}

View File

@@ -1,8 +1,9 @@
import type { Bot } from "../../bot.ts";
import { GuildWidgetSettings } from "../../transformers/widgetSettings.ts";
import { DiscordGuildWidgetSettings } from "../../types/discord.ts";
/** Returns a guild widget settings object. Requires the MANAGE_GUILD permission. */
export async function getWidgetSettings(bot: Bot, guildId: bigint) {
export async function getWidgetSettings(bot: Bot, guildId: bigint): Promise<GuildWidgetSettings> {
const result = await bot.rest.runMethod<DiscordGuildWidgetSettings>(
bot.rest,
"GET",

View File

@@ -1,6 +1,6 @@
import type { Bot } from "../../bot.ts";
/** Leave a guild */
export async function leaveGuild(bot: Bot, guildId: bigint) {
await bot.rest.runMethod<undefined>(bot.rest, "DELETE", bot.constants.routes.GUILD_LEAVE(guildId));
export async function leaveGuild(bot: Bot, guildId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "DELETE", bot.constants.routes.GUILD_LEAVE(guildId));
}

View File

@@ -1,5 +1,5 @@
export * from "./scheduledEvents/mod.ts";
export * from "./automod/mod.ts";
export * from "./scheduledEvents/mod.ts";
export * from "./createGuild.ts";
export * from "./deleteGuild.ts";
@@ -11,7 +11,10 @@ export * from "./getAvailableVoiceRegions.ts";
export * from "./getBan.ts";
export * from "./getBans.ts";
export * from "./getGuild.ts";
export * from "./getGuildBannerUrl.ts";
export * from "./getGuildIconUrl.ts";
export * from "./getGuildPreview.ts";
export * from "./getGuildSplashUrl.ts";
export * from "./getPruneCount.ts";
export * from "./getVanityUrl.ts";
export * from "./getVoiceRegions.ts";
@@ -19,7 +22,5 @@ export * from "./getWelcomeScreen.ts";
export * from "./getWidget.ts";
export * from "./getWidgetImageUrl.ts";
export * from "./getWidgetSettings.ts";
export * from "./guildBannerUrl.ts";
export * from "./guildIconUrl.ts";
export * from "./guildSplashUrl.ts";
export * from "./leaveGuild.ts";

View File

@@ -1,9 +1,14 @@
import { Bot } from "../../../bot.ts";
import { ScheduledEvent } from "../../../transformers/scheduledEvent.ts";
import { DiscordScheduledEvent } from "../../../types/discord.ts";
import { ScheduledEventEntityType, ScheduledEventPrivacyLevel } from "../../../types/shared.ts";
/** Create a guild scheduled event in the guild. A guild can have a maximum of 100 events with `SCHEDULED` or `ACTIVE` status at any time. */
export async function createScheduledEvent(bot: Bot, guildId: bigint, options: CreateScheduledEvent) {
export async function createScheduledEvent(
bot: Bot,
guildId: bigint,
options: CreateScheduledEvent,
): Promise<ScheduledEvent> {
if (!bot.utils.validateLength(options.name, { min: 1, max: 100 })) {
throw new Error("Name must be between 1-100 characters.");
}
@@ -26,7 +31,7 @@ export async function createScheduledEvent(bot: Bot, guildId: bigint, options: C
throw new Error("Cannot schedule event to end before starting.");
}
const event = await bot.rest.runMethod<DiscordScheduledEvent>(
const result = await bot.rest.runMethod<DiscordScheduledEvent>(
bot.rest,
"POST",
bot.constants.routes.GUILD_SCHEDULED_EVENTS(guildId),
@@ -43,7 +48,7 @@ export async function createScheduledEvent(bot: Bot, guildId: bigint, options: C
},
);
return bot.transformers.scheduledEvent(bot, event);
return bot.transformers.scheduledEvent(bot, result);
}
export interface CreateScheduledEvent {

View File

@@ -1,8 +1,8 @@
import { Bot } from "../../../bot.ts";
/** Delete a scheduled event. */
export async function deleteScheduledEvent(bot: Bot, guildId: bigint, eventId: bigint) {
await bot.rest.runMethod<undefined>(
export async function deleteScheduledEvent(bot: Bot, guildId: bigint, eventId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"DELETE",
bot.constants.routes.GUILD_SCHEDULED_EVENT(guildId, eventId),

View File

@@ -1,4 +1,5 @@
import { Bot } from "../../../bot.ts";
import { ScheduledEvent } from "../../../transformers/scheduledEvent.ts";
import { DiscordScheduledEvent } from "../../../types/discord.ts";
import { ScheduledEventEntityType, ScheduledEventPrivacyLevel, ScheduledEventStatus } from "../../../types/shared.ts";
@@ -8,7 +9,7 @@ export async function editScheduledEvent(
guildId: bigint,
eventId: bigint,
options: Partial<EditScheduledEvent>,
) {
): Promise<ScheduledEvent> {
if (options.name && !bot.utils.validateLength(options.name, { min: 1, max: 100 })) {
throw new Error("Name must be between 1-100 characters.");
}
@@ -22,7 +23,7 @@ export async function editScheduledEvent(
throw new Error("Cannot schedule event to end before starting.");
}
const event = await bot.rest.runMethod<DiscordScheduledEvent>(
const result = await bot.rest.runMethod<DiscordScheduledEvent>(
bot.rest,
"PATCH",
bot.constants.routes.GUILD_SCHEDULED_EVENT(guildId, eventId),
@@ -40,7 +41,7 @@ export async function editScheduledEvent(
},
);
return bot.transformers.scheduledEvent(bot, event);
return bot.transformers.scheduledEvent(bot, result);
}
export interface EditScheduledEvent {

View File

@@ -1,4 +1,5 @@
import { Bot } from "../../../bot.ts";
import { ScheduledEvent } from "../../../transformers/scheduledEvent.ts";
import { DiscordScheduledEvent } from "../../../types/discord.ts";
/** Get a guild scheduled event. */
@@ -7,14 +8,12 @@ export async function getScheduledEvent(
guildId: bigint,
eventId: bigint,
options?: { withUserCount?: boolean },
) {
const event = await bot.rest.runMethod<DiscordScheduledEvent>(
): Promise<ScheduledEvent> {
const result = await bot.rest.runMethod<DiscordScheduledEvent>(
bot.rest,
"GET",
bot.constants.routes.GUILD_SCHEDULED_EVENT(guildId, eventId, options?.withUserCount),
);
if (!event?.id) return;
return bot.transformers.scheduledEvent(bot, event);
return bot.transformers.scheduledEvent(bot, result);
}

View File

@@ -34,7 +34,7 @@ export async function getScheduledEventUsers(
if (options.before) url += `&before=${options.before}`;
}
const result = await bot.rest.runMethod<{ user: DiscordUser; member?: DiscordMember }[]>(
const results = await bot.rest.runMethod<{ user: DiscordUser; member?: DiscordMember }[]>(
bot.rest,
"GET",
url,
@@ -42,17 +42,17 @@ export async function getScheduledEventUsers(
if (!options?.withMember) {
return new Collection(
result.map((res) => {
const user = bot.transformers.user(bot, res.user);
results.map((result) => {
const user = bot.transformers.user(bot, result.user);
return [user.id, user];
}),
);
}
return new Collection(
result.map((res) => {
const user = bot.transformers.user(bot, res.user);
const member: Member = bot.transformers.member(bot, res.member!, guildId, user.id);
results.map((result) => {
const user = bot.transformers.user(bot, result.user);
const member = bot.transformers.member(bot, result.member!, guildId, user.id);
return [user.id, { member, user }];
}),

View File

@@ -4,16 +4,20 @@ import { DiscordScheduledEvent } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
/** Get a list of guild scheduled event for the given guild. */
export async function getScheduledEvents(bot: Bot, guildId: bigint, options?: GetScheduledEvents) {
const events = await bot.rest.runMethod<DiscordScheduledEvent[]>(
export async function getScheduledEvents(
bot: Bot,
guildId: bigint,
options?: GetScheduledEvents,
): Promise<Collection<bigint, ScheduledEvent>> {
const results = await bot.rest.runMethod<DiscordScheduledEvent[]>(
bot.rest,
"GET",
bot.constants.routes.GUILD_SCHEDULED_EVENTS(guildId, options?.withUserCount),
);
return new Collection<bigint, ScheduledEvent>(
events.map((e) => {
const event = bot.transformers.scheduledEvent(bot, e);
return new Collection(
results.map((result) => {
const event = bot.transformers.scheduledEvent(bot, result);
return [event.id, event];
}),
);

View File

@@ -1,6 +1,6 @@
import type { Bot } from "../../bot.ts";
/** Delete the attached integration object for the guild with this id. Requires MANAGE_GUILD permission. */
export async function deleteIntegration(bot: Bot, guildId: bigint, id: bigint) {
await bot.rest.runMethod<undefined>(bot.rest, "DELETE", bot.constants.routes.GUILD_INTEGRATION(guildId, id));
export async function deleteIntegration(bot: Bot, guildId: bigint, id: bigint): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "DELETE", bot.constants.routes.GUILD_INTEGRATION(guildId, id));
}

View File

@@ -1,34 +1,35 @@
import type { Bot } from "../../bot.ts";
import { Collection } from "../../util/collection.ts";
import { Integration } from "../../transformers/integration.ts";
import { DiscordIntegration } from "../../types/discord.ts";
import { Collection } from "../../util/collection.ts";
/** Returns a list of integrations for the guild. Requires the MANAGE_GUILD permission. */
export async function getIntegrations(bot: Bot, guildId: bigint) {
const result = await bot.rest.runMethod<DiscordIntegration[]>(
export async function getIntegrations(bot: Bot, guildId: bigint): Promise<Collection<bigint, Integration>> {
const results = await bot.rest.runMethod<DiscordIntegration[]>(
bot.rest,
"GET",
bot.constants.routes.GUILD_INTEGRATIONS(guildId),
);
return new Collection(
result.map((res) => {
results.map((result) => {
const integration = bot.transformers.integration(bot, {
guild_id: guildId.toString(),
id: res.id,
name: res.name,
type: res.type,
enabled: res.enabled,
syncing: res.syncing,
role_id: res.role_id,
enable_emoticons: res.enable_emoticons,
expire_behavior: res.expire_behavior,
expire_grace_period: res.expire_grace_period,
user: res.user,
account: res.account,
synced_at: res.synced_at,
subscriber_count: res.subscriber_count,
revoked: res.revoked,
application: res.application,
id: result.id,
name: result.name,
type: result.type,
enabled: result.enabled,
syncing: result.syncing,
role_id: result.role_id,
enable_emoticons: result.enable_emoticons,
expire_behavior: result.expire_behavior,
expire_grace_period: result.expire_grace_period,
user: result.user,
account: result.account,
synced_at: result.synced_at,
subscriber_count: result.subscriber_count,
revoked: result.revoked,
application: result.application,
});
return [integration.id, integration];
}),

View File

@@ -1,5 +1,5 @@
import type { Bot } from "../../../bot.ts";
import { ApplicationCommandOption, ApplicationCommandTypes, Localization } from "../../../mod.ts";
import { ApplicationCommand, ApplicationCommandOption, ApplicationCommandTypes, Localization } from "../../../mod.ts";
import { DiscordApplicationCommand, DiscordApplicationCommandOption } from "../../../types/discord.ts";
import { AtLeastOne, PermissionStrings } from "../../../types/shared.ts";
@@ -18,7 +18,7 @@ export async function createApplicationCommand(
bot: Bot,
options: CreateApplicationCommand | CreateContextApplicationCommand,
guildId?: bigint,
) {
): Promise<ApplicationCommand> {
const result = await bot.rest.runMethod<DiscordApplicationCommand>(
bot.rest,
"POST",

View File

@@ -1,8 +1,8 @@
import type { Bot } from "../../../bot.ts";
/** Deletes a application command. */
export async function deleteApplicationCommand(bot: Bot, id: bigint, guildId?: bigint) {
await bot.rest.runMethod<undefined>(
export async function deleteApplicationCommand(bot: Bot, id: bigint, guildId?: bigint): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"DELETE",
guildId

View File

@@ -1,8 +1,8 @@
import type { Bot } from "../../../bot.ts";
/** To delete your response to a application command. If a message id is not provided, it will default to deleting the original response. */
export async function deleteInteractionResponse(bot: Bot, token: string, messageId?: bigint) {
await bot.rest.runMethod<undefined>(
export async function deleteInteractionResponse(bot: Bot, token: string, messageId?: bigint): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"DELETE",
messageId

View File

@@ -1,4 +1,5 @@
import type { Bot } from "../../../bot.ts";
import { ApplicationCommandPermission } from "../../../transformers/applicationCommandPermission.ts";
import { DiscordGuildApplicationCommandPermissions } from "../../../types/discord.ts";
import { ApplicationCommandPermissionTypes } from "../../../types/shared.ts";
@@ -10,7 +11,7 @@ export async function editApplicationCommandPermissions(
/** Bearer token which has the `applications.commands.permissions.update` scope and also access to this guild. */
bearerToken: string,
options: ApplicationCommandPermissions[],
) {
): Promise<ApplicationCommandPermission> {
const result = await bot.rest.runMethod<DiscordGuildApplicationCommandPermissions>(
bot.rest,
"PUT",

View File

@@ -1,4 +1,6 @@
import type { Bot } from "../../../bot.ts";
import { Message } from "../../../transformers/message.ts";
import { DiscordMessage } from "../../../types/discord.ts";
import { MessageComponentTypes } from "../../../types/shared.ts";
import { EditWebhookMessage } from "../../webhooks/editWebhookMessage.ts";
@@ -10,8 +12,8 @@ export async function editInteractionResponse(
/** Id of the message you want to edit if undefined the initial response message will be edited */
messageId?: bigint;
},
) {
const result = await bot.rest.runMethod(
): Promise<Message | undefined> {
const result = await bot.rest.runMethod<DiscordMessage>(
bot.rest,
"PATCH",
options.messageId
@@ -101,7 +103,7 @@ export async function editInteractionResponse(
);
// If the original message was edited, this will not return a message
if (!options.messageId) return result as undefined;
if (!options.messageId) return;
return bot.transformers.message(bot, result);
}

View File

@@ -1,8 +1,9 @@
import type { Bot } from "../../../bot.ts";
import { ApplicationCommand } from "../../../transformers/applicationCommand.ts";
import { DiscordApplicationCommand } from "../../../types/discord.ts";
/** Fetches the global command for the given Id. If a guildId is provided, the guild command will be fetched. */
export async function getApplicationCommand(bot: Bot, commandId: bigint, options?: GetApplicationCommand) {
export async function getApplicationCommand(bot: Bot, commandId: bigint, options?: GetApplicationCommand): Promise<ApplicationCommand> {
const result = await bot.rest.runMethod<DiscordApplicationCommand>(
bot.rest,
"GET",

View File

@@ -1,8 +1,13 @@
import type { Bot } from "../../../bot.ts";
import { ApplicationCommandPermission } from "../../../transformers/applicationCommandPermission.ts";
import { DiscordGuildApplicationCommandPermissions } from "../../../types/discord.ts";
/** Fetches command permissions for a specific command for your application in a guild. Returns a GuildApplicationCommandPermissions object. */
export async function getApplicationCommandPermission(bot: Bot, guildId: bigint, commandId: bigint) {
export async function getApplicationCommandPermission(
bot: Bot,
guildId: bigint,
commandId: bigint,
): Promise<ApplicationCommandPermission> {
const result = await bot.rest.runMethod<DiscordGuildApplicationCommandPermissions>(
bot.rest,
"GET",

View File

@@ -1,19 +1,23 @@
import type { Bot } from "../../../bot.ts";
import { ApplicationCommandPermission } from "../../../transformers/applicationCommandPermission.ts";
import { DiscordGuildApplicationCommandPermissions } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
/** Fetches command permissions for all commands for your application in a guild. Returns an array of GuildApplicationCommandPermissions objects. */
export async function getApplicationCommandPermissions(bot: Bot, guildId: bigint) {
const result = await bot.rest.runMethod<DiscordGuildApplicationCommandPermissions[]>(
export async function getApplicationCommandPermissions(
bot: Bot,
guildId: bigint,
): Promise<Collection<bigint, ApplicationCommandPermission>> {
const results = await bot.rest.runMethod<DiscordGuildApplicationCommandPermissions[]>(
bot.rest,
"GET",
bot.constants.routes.COMMANDS_PERMISSIONS(bot.applicationId, guildId),
);
return new Collection(
result.map((res) => {
const perms = bot.transformers.applicationCommandPermission(bot, res);
return [perms.id, perms];
results.map((result) => {
const permission = bot.transformers.applicationCommandPermission(bot, result);
return [permission.id, permission];
}),
);
}

View File

@@ -1,10 +1,14 @@
import { Collection } from "../../../util/collection.ts";
import type { Bot } from "../../../bot.ts";
import { ApplicationCommand } from "../../../transformers/applicationCommand.ts";
import { DiscordApplicationCommand } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
/** Fetch all the commands for your application. If a guild id is not provided, it will fetch global commands. */
export async function getApplicationCommands(bot: Bot, guildId?: bigint) {
const result = await bot.rest.runMethod<DiscordApplicationCommand[]>(
export async function getApplicationCommands(
bot: Bot,
guildId?: bigint,
): Promise<Collection<bigint, ApplicationCommand>> {
const results = await bot.rest.runMethod<DiscordApplicationCommand[]>(
bot.rest,
"GET",
guildId
@@ -13,8 +17,8 @@ export async function getApplicationCommands(bot: Bot, guildId?: bigint) {
);
return new Collection(
result.map((res) => {
const command = bot.transformers.applicationCommand(bot, res);
results.map((result) => {
const command = bot.transformers.applicationCommand(bot, result);
return [command.id, command];
}),
);

View File

@@ -1,12 +1,13 @@
import type { Bot } from "../../../bot.ts";
import { ApplicationCommand } from "../../../transformers/applicationCommand.ts";
import { DiscordApplicationCommand } from "../../../types/discord.ts";
import { AtLeastOne } from "../../../types/shared.ts";
import {
CreateApplicationCommand,
CreateContextApplicationCommand,
isContextApplicationCommand,
makeOptionsForCommand,
makeOptionsForCommand
} from "./createApplicationCommand.ts";
import { DiscordApplicationCommand } from "../../../types/discord.ts";
import { AtLeastOne } from "../../../types/shared.ts";
/**
* Edit an existing application command. If this command did not exist, it will create it.
@@ -16,7 +17,7 @@ export async function upsertApplicationCommand(
commandId: bigint,
options: AtLeastOne<CreateApplicationCommand> | AtLeastOne<CreateContextApplicationCommand>,
guildId?: bigint,
) {
): Promise<ApplicationCommand> {
const result = await bot.rest.runMethod<DiscordApplicationCommand>(
bot.rest,
"PATCH",

View File

@@ -1,4 +1,6 @@
import type { Bot } from "../../../bot.ts";
import { ApplicationCommand } from "../../../transformers/applicationCommand.ts";
import { DiscordApplicationCommand } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
import {
CreateApplicationCommand,
@@ -6,8 +8,6 @@ import {
isContextApplicationCommand,
makeOptionsForCommand,
} from "./createApplicationCommand.ts";
import { DiscordApplicationCommand } from "../../../types/discord.ts";
import { MakeRequired } from "../../../types/shared.ts";
/**
* Bulk edit existing application commands. If a command does not exist, it will create it.
@@ -18,8 +18,8 @@ export async function upsertApplicationCommands(
bot: Bot,
options: (UpsertApplicationCommands | CreateContextApplicationCommand)[],
guildId?: bigint,
) {
const result = await bot.rest.runMethod<DiscordApplicationCommand[]>(
): Promise<Collection<bigint, ApplicationCommand>> {
const results = await bot.rest.runMethod<DiscordApplicationCommand[]>(
bot.rest,
"PUT",
guildId
@@ -40,8 +40,8 @@ export async function upsertApplicationCommands(
);
return new Collection(
result.map((res) => {
const command = bot.transformers.applicationCommand(bot, res);
results.map((result) => {
const command = bot.transformers.applicationCommand(bot, result);
return [command.id, command];
}),
);

View File

@@ -1,8 +1,8 @@
import { Bot } from "../../../bot.ts";
/** Deletes a followup message for an Interaction. Functions the same as delete webhook message, however this uses your interaction token instead of bot token. Does not support ephemeral followups. */
export async function deleteFollowupMessage(bot: Bot, interactionToken: string, messageId: bigint) {
await bot.rest.runMethod<undefined>(
export async function deleteFollowupMessage(bot: Bot, interactionToken: string, messageId: bigint): Promise<void> {
return await bot.rest.runMethod<void>(
bot.rest,
"DELETE",
bot.constants.routes.WEBHOOK_MESSAGE(bot.applicationId, interactionToken, messageId),

View File

@@ -1,4 +1,5 @@
import { Bot } from "../../../bot.ts";
import { Message } from "../../../transformers/message.ts";
import { DiscordMessage } from "../../../types/discord.ts";
import { MessageComponentTypes } from "../../../types/shared.ts";
import { EditWebhookMessage } from "../../webhooks/editWebhookMessage.ts";
@@ -9,7 +10,7 @@ export async function editFollowupMessage(
interactionToken: string,
messageId: bigint,
options: EditWebhookMessage,
) {
): Promise<Message> {
const result = await bot.rest.runMethod<DiscordMessage>(
bot.rest,
"PATCH",

View File

@@ -1,8 +1,9 @@
import { Bot } from "../../../bot.ts";
import { Message } from "../../../transformers/message.ts";
import { DiscordMessage } from "../../../types/discord.ts";
/** Returns a followup message for an Interaction. Functions the same as get webhook message, however this uses your interaction token instead of bot token. Does not support ephemeral followups. */
export async function getFollowupMessage(bot: Bot, interactionToken: string, messageId: bigint) {
export async function getFollowupMessage(bot: Bot, interactionToken: string, messageId: bigint): Promise<Message> {
const result = await bot.rest.runMethod<DiscordMessage>(
bot.rest,
"GET",

View File

@@ -1,8 +1,9 @@
import type { Bot } from "../../bot.ts";
import { Message } from "../../transformers/message.ts";
import { DiscordMessage } from "../../types/discord.ts";
/** Returns the initial Interaction response. Functions the same as Get Webhook Message */
export async function getOriginalInteractionResponse(bot: Bot, token: string) {
export async function getOriginalInteractionResponse(bot: Bot, token: string): Promise<Message> {
const result = await bot.rest.runMethod<DiscordMessage>(
bot.rest,
"GET",

View File

@@ -1,5 +1,5 @@
import type { Bot } from "../../bot.ts";
import { Embed } from "../../mod.ts";
import { Embed, Message } from "../../mod.ts";
import { DiscordMessage } from "../../types/discord.ts";
import { AllowedMentions, FileContent, MessageComponents } from "../../types/discordeno.ts";
import { InteractionResponseTypes } from "../../types/shared.ts";
@@ -15,7 +15,7 @@ export async function sendInteractionResponse(
id: bigint,
token: string,
options: InteractionResponse,
) {
): Promise<Message | undefined> {
// If no mentions are provided, force disable mentions
if (!options.data?.allowedMentions) {
options.data = { ...options.data, allowedMentions: { parse: [] } };

View File

@@ -1,9 +1,10 @@
import type { Bot } from "../../bot.ts";
import { DiscordInvite } from "../../types/discord.ts";
import { InviteTargetTypes } from "../../types/shared.ts";
import { TargetTypes } from "../../types/shared.ts";
import { Invite } from "./getInvite.ts";
/** Creates a new invite for this channel. Requires CREATE_INSTANT_INVITE */
export async function createInvite(bot: Bot, channelId: bigint, options: CreateChannelInvite = {}) {
export async function createInvite(bot: Bot, channelId: bigint, options: CreateChannelInvite = {}): Promise<Invite> {
const result = await bot.rest.runMethod<DiscordInvite>(
bot.rest,
"POST",
@@ -14,8 +15,8 @@ export async function createInvite(bot: Bot, channelId: bigint, options: CreateC
temporary: options.temporary,
unique: options.unique,
target_type: options.targetType,
target_user_id: options.targetUserId,
target_application_id: options.targetApplicationId,
target_user_id: options.targetUserId?.toString(),
target_application_id: options.targetApplicationId?.toString(),
},
);
@@ -45,9 +46,9 @@ export interface CreateChannelInvite {
/** If true, don't try to reuse similar invite (useful for creating many unique one time use invites). Default: false */
unique?: boolean;
/** The type of target for this voice channel invite */
targetType?: InviteTargetTypes;
targetType?: TargetTypes;
/** The id of the user whose stream to display for this invite, required if `target_type` is 1, the user must be streaming in the channel */
targetUserId?: string;
targetUserId?: bigint;
/** The id of the embedded application to open for this invite, required if `target_type` is 2, the application must have the `EMBEDDED` flag */
targetApplicationId?: string;
targetApplicationId?: bigint;
}

View File

@@ -1,7 +1,6 @@
import type { Bot } from "../../bot.ts";
import { DiscordInviteMetadata } from "../../types/discord.ts";
/** Deletes an invite for the given code. Requires `MANAGE_CHANNELS` or `MANAGE_GUILD` permission */
export async function deleteInvite(bot: Bot, inviteCode: string) {
await bot.rest.runMethod<DiscordInviteMetadata>(bot.rest, "DELETE", bot.constants.routes.INVITE(inviteCode));
export async function deleteInvite(bot: Bot, inviteCode: string): Promise<void> {
return await bot.rest.runMethod<void>(bot.rest, "DELETE", bot.constants.routes.INVITE(inviteCode));
}

View File

@@ -1,25 +1,45 @@
import { Collection } from "../../util/collection.ts";
import type { Bot } from "../../bot.ts";
import { DiscordInviteMetadata } from "../../types/discord.ts";
import { TargetTypes } from "../../types/shared.ts";
import { Collection } from "../../util/collection.ts";
import { InviteMetadata } from "./getInvite.ts";
/** Gets the invites for this channel. Requires MANAGE_CHANNEL */
export async function getChannelInvites(bot: Bot, channelId: bigint) {
const result = await bot.rest.runMethod<DiscordInviteMetadata[]>(
export async function getChannelInvites(bot: Bot, channelId: bigint): Promise<Collection<string, InviteMetadata>> {
const results = await bot.rest.runMethod<DiscordInviteMetadata[]>(
bot.rest,
"GET",
bot.constants.routes.CHANNEL_INVITES(channelId),
);
return new Collection(
result.map((invite) => [
invite.code,
{
uses: invite.uses,
maxUses: invite.max_uses,
maxAge: invite.max_age,
temporary: invite.temporary,
createdAt: Date.parse(invite.created_at),
},
]),
results.map<[string, InviteMetadata]>((result) => {
const invite = {
code: result.code,
guildId: result.guild?.id ? bot.transformers.snowflake(result.guild.id) : undefined,
channelId: result.channel?.id ? bot.transformers.snowflake(result.channel.id) : undefined,
inviter: result.inviter ? bot.transformers.user(bot, result.inviter) : undefined,
targetType: result.target_type
? (result.target_type === 1 ? TargetTypes.Stream : TargetTypes.EmbeddedApplication)
: undefined,
targetUser: result.target_user ? bot.transformers.user(bot, result.target_user) : undefined,
targetApplicationId: result.target_application?.id
? bot.transformers.snowflake(result.target_application.id)
: undefined,
approximatePresenceCount: result.approximate_presence_count,
approximateMemberCount: result.approximate_member_count,
expiresAt: result.expires_at ? Date.parse(result.expires_at) : undefined,
guildScheduledEvent: result.guild_scheduled_event
? bot.transformers.scheduledEvent(bot, result.guild_scheduled_event)
: undefined,
// Metadata structure
uses: result.uses,
maxUses: result.max_uses,
maxAge: result.max_age,
temporary: result.temporary,
createdAt: Date.parse(result.created_at),
};
return [invite.code, invite];
}),
);
}

View File

@@ -1,8 +1,31 @@
import type { Bot } from "../../bot.ts";
import { ScheduledEvent, TargetTypes, User } from "../../mod.ts";
import { DiscordInviteMetadata } from "../../types/discord.ts";
export type Invite = {
code: string;
guildId?: bigint;
channelId?: bigint;
inviter?: User;
targetType?: TargetTypes;
targetUser?: User;
targetApplicationId?: bigint;
approximatePresenceCount?: number;
approximateMemberCount?: number;
expiresAt?: number;
guildScheduledEvent?: ScheduledEvent;
};
export type InviteMetadata = Invite & {
uses: number;
maxUses: number;
maxAge: number;
temporary: boolean;
createdAt: number;
};
/** Returns an invite for the given code or throws an error if the invite doesn't exists. */
export async function getInvite(bot: Bot, inviteCode: string, options?: GetInvite) {
export async function getInvite(bot: Bot, inviteCode: string, options?: GetInvite): Promise<Invite> {
const result = await bot.rest.runMethod<DiscordInviteMetadata>(
bot.rest,
"GET",
@@ -14,7 +37,9 @@ export async function getInvite(bot: Bot, inviteCode: string, options?: GetInvit
guildId: result.guild?.id ? bot.transformers.snowflake(result.guild.id) : undefined,
channelId: result.channel?.id ? bot.transformers.snowflake(result.channel.id) : undefined,
inviter: result.inviter ? bot.transformers.user(bot, result.inviter) : undefined,
targetType: result.target_type,
targetType: result.target_type
? (result.target_type === 1 ? TargetTypes.Stream : TargetTypes.EmbeddedApplication)
: undefined,
targetUser: result.target_user ? bot.transformers.user(bot, result.target_user) : undefined,
targetApplicationId: result.target_application?.id
? bot.transformers.snowflake(result.target_application.id)

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