feat(core): Add AbortSignal support. (#9042)

* feat: add abort signal to guilds api

* feat: add to application commands, channels, and users classes

* chore: finish up

* chore: centralize types

* chore: make requested changes

* chore: make requested changes

* refactor: consistently use empty objects

* Update packages/core/src/api/webhook.ts

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>

* chore: make requested changes

* refactor: update `setVoiceState` after rebase

* chore: requested changes

* refactor: use -types interface for query

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
This commit is contained in:
Suneet Tipirneni
2023-04-01 17:11:37 -04:00
committed by GitHub
parent e2f39ccc32
commit 907eb1b470
12 changed files with 959 additions and 444 deletions

View File

@@ -1,4 +1,4 @@
import { makeURLSearchParams, type RawFile, type REST } from '@discordjs/rest';
import { makeURLSearchParams, type RawFile, type REST, type RequestData } from '@discordjs/rest';
import {
Routes,
type RESTDeleteAPIChannelResult,
@@ -33,15 +33,18 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#create-message}
* @param channelId - The id of the channel to send the message in
* @param data - The data to use when sending the message
* @param body - The data to use when sending the message
* @param options - The options to use when sending the message
*/
public async createMessage(
channelId: Snowflake,
{ files, ...body }: RESTPostAPIChannelMessageJSONBody & { files?: RawFile[] },
{ signal }: Pick<RequestData, 'signal'> = {},
) {
return this.rest.post(Routes.channelMessages(channelId), {
files,
body,
signal,
}) as Promise<RESTPostAPIChannelMessageResult>;
}
@@ -51,16 +54,19 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#edit-message}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to edit
* @param data - The data to use when editing the message
* @param body - The data to use when editing the message
* @param options - The options to use when editing the message
*/
public async editMessage(
channelId: Snowflake,
messageId: Snowflake,
{ files, ...body }: RESTPostAPIChannelMessageJSONBody & { files?: RawFile[] },
{ signal }: Pick<RequestData, 'signal'>,
) {
return this.rest.patch(Routes.channelMessage(channelId, messageId), {
files,
body,
signal,
}) as Promise<RESTPatchAPIChannelMessageResult>;
}
@@ -71,16 +77,19 @@ export class ChannelsAPI {
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to get the reactions for
* @param emoji - The emoji to get the reactions for
* @param options - The options to use when fetching the reactions
* @param query - The query options to use when fetching the reactions
* @param options - The options for fetching the message reactions
*/
public async getMessageReactions(
channelId: Snowflake,
messageId: Snowflake,
emoji: string,
options: RESTGetAPIChannelMessageReactionUsersQuery = {},
query: RESTGetAPIChannelMessageReactionUsersQuery = {},
{ signal }: Pick<RequestData, 'signal'> = {},
) {
return this.rest.get(Routes.channelMessageReaction(channelId, messageId, encodeURIComponent(emoji)), {
query: makeURLSearchParams(options),
query: makeURLSearchParams(query),
signal,
}) as Promise<RESTGetAPIChannelMessageReactionUsersResult>;
}
@@ -91,9 +100,17 @@ export class ChannelsAPI {
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to delete the reaction for
* @param emoji - The emoji to delete the reaction for
* @param options - The options for deleting the reaction
*/
public async deleteOwnMessageReaction(channelId: Snowflake, messageId: Snowflake, emoji: string) {
await this.rest.delete(Routes.channelMessageOwnReaction(channelId, messageId, encodeURIComponent(emoji)));
public async deleteOwnMessageReaction(
channelId: Snowflake,
messageId: Snowflake,
emoji: string,
{ signal }: Pick<RequestData, 'signal'> = {},
) {
await this.rest.delete(Routes.channelMessageOwnReaction(channelId, messageId, encodeURIComponent(emoji)), {
signal,
});
}
/**
@@ -104,9 +121,18 @@ export class ChannelsAPI {
* @param messageId - The id of the message to delete the reaction for
* @param emoji - The emoji to delete the reaction for
* @param userId - The id of the user to delete the reaction for
* @param options - The options for deleting the reaction
*/
public async deleteUserMessageReaction(channelId: Snowflake, messageId: Snowflake, emoji: string, userId: Snowflake) {
await this.rest.delete(Routes.channelMessageUserReaction(channelId, messageId, encodeURIComponent(emoji), userId));
public async deleteUserMessageReaction(
channelId: Snowflake,
messageId: Snowflake,
emoji: string,
userId: Snowflake,
{ signal }: Pick<RequestData, 'signal'> = {},
) {
await this.rest.delete(Routes.channelMessageUserReaction(channelId, messageId, encodeURIComponent(emoji), userId), {
signal,
});
}
/**
@@ -115,9 +141,14 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#delete-all-reactions}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to delete the reactions for
* @param options - The options for deleting the reactions
*/
public async deleteAllMessageReactions(channelId: Snowflake, messageId: Snowflake) {
await this.rest.delete(Routes.channelMessageAllReactions(channelId, messageId));
public async deleteAllMessageReactions(
channelId: Snowflake,
messageId: Snowflake,
{ signal }: Pick<RequestData, 'signal'> = {},
) {
await this.rest.delete(Routes.channelMessageAllReactions(channelId, messageId), { signal });
}
/**
@@ -127,9 +158,15 @@ export class ChannelsAPI {
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to delete the reactions for
* @param emoji - The emoji to delete the reactions for
* @param options - The options for deleting the reactions
*/
public async deleteAllMessageReactionsForEmoji(channelId: Snowflake, messageId: Snowflake, emoji: string) {
await this.rest.delete(Routes.channelMessageReaction(channelId, messageId, encodeURIComponent(emoji)));
public async deleteAllMessageReactionsForEmoji(
channelId: Snowflake,
messageId: Snowflake,
emoji: string,
{ signal }: Pick<RequestData, 'signal'> = {},
) {
await this.rest.delete(Routes.channelMessageReaction(channelId, messageId, encodeURIComponent(emoji)), { signal });
}
/**
@@ -139,9 +176,15 @@ export class ChannelsAPI {
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to add the reaction to
* @param emoji - The emoji to add the reaction with
* @param options - The options for adding the reaction
*/
public async addMessageReaction(channelId: Snowflake, messageId: Snowflake, emoji: string) {
await this.rest.put(Routes.channelMessageOwnReaction(channelId, messageId, encodeURIComponent(emoji)));
public async addMessageReaction(
channelId: Snowflake,
messageId: Snowflake,
emoji: string,
{ signal }: Pick<RequestData, 'signal'> = {},
) {
await this.rest.put(Routes.channelMessageOwnReaction(channelId, messageId, encodeURIComponent(emoji)), { signal });
}
/**
@@ -149,9 +192,10 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#get-channel}
* @param channelId - The id of the channel
* @param options - The options for fetching the channel
*/
public async get(channelId: Snowflake) {
return this.rest.get(Routes.channel(channelId)) as Promise<RESTGetAPIChannelResult>;
public async get(channelId: Snowflake, { signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.get(Routes.channel(channelId), { signal }) as Promise<RESTGetAPIChannelResult>;
}
/**
@@ -159,10 +203,15 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#modify-channel}
* @param channelId - The id of the channel to edit
* @param data - The new channel data
* @param body - The new channel data
* @param options - The options for editing the channel
*/
public async edit(channelId: Snowflake, data: RESTPatchAPIChannelJSONBody) {
return this.rest.patch(Routes.channel(channelId), { body: data }) as Promise<RESTPatchAPIChannelResult>;
public async edit(
channelId: Snowflake,
body: RESTPatchAPIChannelJSONBody,
{ signal }: Pick<RequestData, 'signal'> = {},
) {
return this.rest.patch(Routes.channel(channelId), { body, signal }) as Promise<RESTPatchAPIChannelResult>;
}
/**
@@ -170,9 +219,10 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#deleteclose-channel}
* @param channelId - The id of the channel to delete
* @param options - The options for deleting the channel
*/
public async delete(channelId: Snowflake) {
return this.rest.delete(Routes.channel(channelId)) as Promise<RESTDeleteAPIChannelResult>;
public async delete(channelId: Snowflake, { signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.delete(Routes.channel(channelId), { signal }) as Promise<RESTDeleteAPIChannelResult>;
}
/**
@@ -180,11 +230,17 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#get-channel-messages}
* @param channelId - The id of the channel to fetch messages from
* @param options - The options to use when fetching messages
* @param query - The query options to use when fetching messages
* @param options - The options for fetching the messages
*/
public async getMessages(channelId: Snowflake, options: RESTGetAPIChannelMessagesQuery = {}) {
public async getMessages(
channelId: Snowflake,
query: RESTGetAPIChannelMessagesQuery = {},
{ signal }: Pick<RequestData, 'signal'> = {},
) {
return this.rest.get(Routes.channelMessages(channelId), {
query: makeURLSearchParams(options),
query: makeURLSearchParams(query),
signal,
}) as Promise<RESTGetAPIChannelMessagesResult>;
}
@@ -193,9 +249,10 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#trigger-typing-indicator}
* @param channelId - The id of the channel to show the typing indicator in
* @param options - The options for showing the typing indicator
*/
public async showTyping(channelId: Snowflake) {
await this.rest.post(Routes.channelTyping(channelId));
public async showTyping(channelId: Snowflake, { signal }: Pick<RequestData, 'signal'> = {}) {
await this.rest.post(Routes.channelTyping(channelId), { signal });
}
/**
@@ -203,9 +260,10 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#get-pinned-messages}
* @param channelId - The id of the channel to fetch pinned messages from
* @param options - The options for fetching the pinned messages
*/
public async getPins(channelId: Snowflake) {
return this.rest.get(Routes.channelPins(channelId)) as Promise<RESTGetAPIChannelPinsResult>;
public async getPins(channelId: Snowflake, { signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.get(Routes.channelPins(channelId), { signal }) as Promise<RESTGetAPIChannelPinsResult>;
}
/**
@@ -214,10 +272,14 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#pin-message}
* @param channelId - The id of the channel to pin the message in
* @param messageId - The id of the message to pin
* @param reason - The reason for pinning the message
* @param options - The options for pinning the message
*/
public async pinMessage(channelId: Snowflake, messageId: Snowflake, reason?: string) {
await this.rest.put(Routes.channelPin(channelId, messageId), { reason });
public async pinMessage(
channelId: Snowflake,
messageId: Snowflake,
{ reason, signal }: Pick<RequestData, 'reason' | 'signal'> = {},
) {
await this.rest.put(Routes.channelPin(channelId, messageId), { reason, signal });
}
/**
@@ -226,10 +288,14 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#delete-message}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to delete
* @param reason - The reason for deleting the message
* @param options - The options for deleting the message
*/
public async deleteMessage(channelId: Snowflake, messageId: Snowflake, reason?: string) {
await this.rest.delete(Routes.channelMessage(channelId, messageId), { reason });
public async deleteMessage(
channelId: Snowflake,
messageId: Snowflake,
{ reason, signal }: Pick<RequestData, 'reason' | 'signal'> = {},
) {
await this.rest.delete(Routes.channelMessage(channelId, messageId), { reason, signal });
}
/**
@@ -238,9 +304,14 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#bulk-delete-messages}
* @param channelId - The id of the channel the messages are in
* @param messageIds - The ids of the messages to delete
* @param options - The options for deleting the messages
*/
public async bulkDeleteMessages(channelId: Snowflake, messageIds: Snowflake[], reason?: string): Promise<void> {
await this.rest.post(Routes.channelBulkDelete(channelId), { reason, body: { messages: messageIds } });
public async bulkDeleteMessages(
channelId: Snowflake,
messageIds: Snowflake[],
{ reason, signal }: Pick<RequestData, 'reason' | 'signal'> = {},
): Promise<void> {
await this.rest.post(Routes.channelBulkDelete(channelId), { reason, body: { messages: messageIds }, signal });
}
/**
@@ -249,9 +320,12 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#get-channel-message}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to fetch
* @param options - The options for fetching the message
*/
public async getMessage(channelId: Snowflake, messageId: Snowflake) {
return this.rest.get(Routes.channelMessage(channelId, messageId)) as Promise<RESTGetAPIChannelMessageResult>;
public async getMessage(channelId: Snowflake, messageId: Snowflake, { signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.get(Routes.channelMessage(channelId, messageId), {
signal,
}) as Promise<RESTGetAPIChannelMessageResult>;
}
/**
@@ -260,11 +334,16 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#crosspost-message}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to crosspost
* @param options - The options for crossposting the message
*/
public async crosspostMessage(channelId: Snowflake, messageId: Snowflake) {
return this.rest.post(
Routes.channelMessageCrosspost(channelId, messageId),
) as Promise<RESTPostAPIChannelMessageCrosspostResult>;
public async crosspostMessage(
channelId: Snowflake,
messageId: Snowflake,
{ signal }: Pick<RequestData, 'signal'> = {},
) {
return this.rest.post(Routes.channelMessageCrosspost(channelId, messageId), {
signal,
}) as Promise<RESTPostAPIChannelMessageCrosspostResult>;
}
/**
@@ -273,10 +352,14 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#unpin-message}
* @param channelId - The id of the channel to unpin the message in
* @param messageId - The id of the message to unpin
* @param reason - The reason for unpinning the message
* @param options - The options for unpinning the message
*/
public async unpinMessage(channelId: Snowflake, messageId: Snowflake, reason?: string) {
await this.rest.delete(Routes.channelPin(channelId, messageId), { reason });
public async unpinMessage(
channelId: Snowflake,
messageId: Snowflake,
{ reason, signal }: Pick<RequestData, 'reason' | 'signal'> = {},
) {
await this.rest.delete(Routes.channelPin(channelId, messageId), { reason, signal });
}
/**
@@ -285,10 +368,16 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#follow-announcement-channel}
* @param channelId - The id of the announcement channel to follow
* @param webhookChannelId - The id of the webhook channel to follow the announcements in
* @param options - The options for following the announcement channel
*/
public async followAnnouncements(channelId: Snowflake, webhookChannelId: Snowflake) {
public async followAnnouncements(
channelId: Snowflake,
webhookChannelId: Snowflake,
{ signal }: Pick<RequestData, 'signal'> = {},
) {
return this.rest.post(Routes.channelFollowers(channelId), {
body: { webhook_channel_id: webhookChannelId },
signal,
}) as Promise<RESTPostAPIChannelFollowersResult>;
}
@@ -297,12 +386,18 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#create-channel-invite}
* @param channelId - The id of the channel to create an invite for
* @param data - The data to use when creating the invite
* @param body - The data to use when creating the invite
* @param options - The options for creating the invite
*/
public async createInvite(channelId: Snowflake, data: RESTPostAPIChannelInviteJSONBody, reason?: string) {
public async createInvite(
channelId: Snowflake,
body: RESTPostAPIChannelInviteJSONBody,
{ reason, signal }: Pick<RequestData, 'reason' | 'signal'> = {},
) {
return this.rest.post(Routes.channelInvites(channelId), {
reason,
body: data,
body,
signal,
}) as Promise<RESTPostAPIChannelInviteResult>;
}
@@ -311,9 +406,10 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#get-channel-invites}
* @param channelId - The id of the channel to fetch invites from
* @param options - The options for fetching the invites
*/
public async getInvites(channelId: Snowflake) {
return this.rest.get(Routes.channelInvites(channelId)) as Promise<RESTGetAPIChannelInvitesResult>;
public async getInvites(channelId: Snowflake, { signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.get(Routes.channelInvites(channelId), { signal }) as Promise<RESTGetAPIChannelInvitesResult>;
}
/**
@@ -323,15 +419,18 @@ export class ChannelsAPI {
* @see {@link https://discord.com/developers/docs/resources/channel#list-private-archived-threads}
* @param channelId - The id of the channel to fetch archived threads from
* @param archivedStatus - The archived status of the threads to fetch
* @param options - The options to use when fetching archived threads
* @param query - The options to use when fetching archived threads
* @param options - The options for fetching archived threads
*/
public async getArchivedThreads(
channelId: Snowflake,
archivedStatus: 'private' | 'public',
options: RESTGetAPIChannelThreadsArchivedQuery = {},
query: RESTGetAPIChannelThreadsArchivedQuery = {},
{ signal }: Pick<RequestData, 'signal'> = {},
) {
return this.rest.get(Routes.channelThreads(channelId, archivedStatus), {
query: makeURLSearchParams(options),
query: makeURLSearchParams(query),
signal,
}) as Promise<RESTGetAPIChannelUsersThreadsArchivedResult>;
}
@@ -340,14 +439,17 @@ export class ChannelsAPI {
*
* @see {@link https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads}
* @param channelId - The id of the channel to fetch joined archived threads from
* @param options - The options to use when fetching joined archived threads
* @param query - The options to use when fetching joined archived threads
* @param options - The options for fetching joined archived threads
*/
public async getJoinedPrivateArchivedThreads(
channelId: Snowflake,
options: RESTGetAPIChannelThreadsArchivedQuery = {},
query: RESTGetAPIChannelThreadsArchivedQuery = {},
{ signal }: Pick<RequestData, 'signal'> = {},
) {
return this.rest.get(Routes.channelJoinedArchivedThreads(channelId), {
query: makeURLSearchParams(options),
query: makeURLSearchParams(query),
signal,
}) as Promise<RESTGetAPIChannelUsersThreadsArchivedResult>;
}