refactor: improve typings and docs related to threads (#5991)

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
This commit is contained in:
Shubham Parihar
2021-07-04 01:08:38 +05:30
committed by GitHub
parent 7e3001191c
commit 4bf49809f2
4 changed files with 94 additions and 76 deletions

View File

@@ -7,7 +7,7 @@ const Collection = require('../util/Collection');
const { ChannelTypes } = require('../util/Constants'); const { ChannelTypes } = require('../util/Constants');
/** /**
* Manages API methods for ThreadChannels and stores their cache. * Manages API methods for {@link ThreadChannel} objects and stores their cache.
* @extends {BaseManager} * @extends {BaseManager}
*/ */
class ThreadManager extends BaseManager { class ThreadManager extends BaseManager {
@@ -35,7 +35,7 @@ class ThreadManager extends BaseManager {
} }
/** /**
* Data that can be resolved to give a Thread Channel object. This can be: * Data that can be resolved to a Thread Channel object. This can be:
* * A ThreadChannel object * * A ThreadChannel object
* * A Snowflake * * A Snowflake
* @typedef {ThreadChannel|Snowflake} ThreadChannelResolvable * @typedef {ThreadChannel|Snowflake} ThreadChannelResolvable
@@ -60,7 +60,8 @@ class ThreadManager extends BaseManager {
*/ */
/** /**
* A number that is allowed to be the duration in minutes before a thread is automatically archived. This can be: * A number that is allowed to be the duration (in minutes) of inactivity after which a thread is automatically
* archived. This can be:
* * `60` (1 hour) * * `60` (1 hour)
* * `1440` (1 day) * * `1440` (1 day)
* * `4320` (3 days) <warn>This is only available when the guild has the `THREE_DAY_THREAD_ARCHIVE` feature.</warn> * * `4320` (3 days) <warn>This is only available when the guild has the `THREE_DAY_THREAD_ARCHIVE` feature.</warn>
@@ -69,20 +70,22 @@ class ThreadManager extends BaseManager {
*/ */
/** /**
* Options for creating a thread <warn>Only one of `startMessage` or `type` can be defined. * Options for creating a thread. <warn>Only one of `startMessage` or `type` can be defined.</warn>
* If `startMessage` is defined, `type` is automatically defined and cannot be changed.</warn>
* @typedef {Object} ThreadCreateOptions * @typedef {Object} ThreadCreateOptions
* @property {string} name The name of the new Thread * @property {string} name The name of the new thread
* @property {ThreadAutoArchiveDuration} autoArchiveDuration How long before the thread is automatically archived * @property {ThreadAutoArchiveDuration} autoArchiveDuration The amount of time (in minutes) after which the thread
* @property {MessageResolvable} [startMessage] The message to start a thread from * should automatically archive in case of no recent activity
* @property {ThreadChannelType|number} [type='public_thread'] The type of thread to create * @property {MessageResolvable} [startMessage] The message to start a thread from. <warn>If this is defined then type
* <warn>When creating threads in a `news` channel this is ignored and is always `news_thread`</warn> * of thread gets automatically defined and cannot be changed. The provided `type` field will be ignored</warn>
* @property {ThreadChannelType|number} [type] The type of thread to create. Defaults to `public_thread` if created in
* a {@link TextChannel} <warn>When creating threads in a {@link NewsChannel} this is ignored and is always
* `news_thread`</warn>
* @property {string} [reason] Reason for creating the thread * @property {string} [reason] Reason for creating the thread
*/ */
/** /**
* Creates a new thread in the channel. * Creates a new thread in the channel.
* @param {ThreadCreateOptions} [options] Options * @param {ThreadCreateOptions} [options] Options to create a new thread
* @returns {Promise<ThreadChannel>} * @returns {Promise<ThreadChannel>}
* @example * @example
* // Create a new public thread * // Create a new public thread
@@ -92,7 +95,7 @@ class ThreadManager extends BaseManager {
* autoArchiveDuration: 60, * autoArchiveDuration: 60,
* reason: 'Needed a separate thread for food', * reason: 'Needed a separate thread for food',
* }) * })
* .then(console.log) * .then(threadChannel => console.log(threadChannel))
* .catch(console.error); * .catch(console.error);
* @example * @example
* // Create a new private thread * // Create a new private thread
@@ -103,7 +106,7 @@ class ThreadManager extends BaseManager {
* type: 'private_thread', * type: 'private_thread',
* reason: 'Needed a separate thread for moderation', * reason: 'Needed a separate thread for moderation',
* }) * })
* .then(console.log) * .then(threadChannel => console.log(threadChannel))
* .catch(console.error); * .catch(console.error);
*/ */
async create({ name, autoArchiveDuration, startMessage, type, reason } = {}) { async create({ name, autoArchiveDuration, startMessage, type, reason } = {}) {
@@ -141,11 +144,10 @@ class ThreadManager extends BaseManager {
/** /**
* Obtains a thread from Discord, or the channel cache if it's already available. * Obtains a thread from Discord, or the channel cache if it's already available.
* @param {ThreadChannelResolvable|FetchThreadsOptions} [options] If a ThreadChannelResolvable, the thread to fetch. * @param {ThreadChannelResolvable|FetchThreadsOptions} [options] The options to fetch threads. If it is a
* If undefined, fetches all active threads. * ThreadChannelResolvable then the specified thread will be fetched. Fetches all active threads if `undefined`
* If an Object, fetches the specified threads. * @param {BaseFetchOptions} [cacheOptions] Additional options for this fetch. <warn>The `force` field gets ignored
* @param {BaseFetchOptions} [cacheOptions] Additional options for this fetch * if `options` is not a ThreadChannelResolvable</warn>
* only applies when fetching a single thread
* @returns {Promise<?(ThreadChannel|FetchedThreads)>} * @returns {Promise<?(ThreadChannel|FetchedThreads)>}
* @example * @example
* // Fetch a thread by its id * // Fetch a thread by its id
@@ -164,10 +166,10 @@ class ThreadManager extends BaseManager {
} }
/** /**
* Data that can be resolved to give a Date object. This can be: * Data that can be resolved to a Date object. This can be:
* * A Date object * * A Date object
* * A number representing a timestamp * * A number representing a timestamp
* * An ISO8601 string * * An [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) string
* @typedef {Date|number|string} DateResolvable * @typedef {Date|number|string} DateResolvable
*/ */
@@ -175,24 +177,23 @@ class ThreadManager extends BaseManager {
* The options used to fetch archived threads. * The options used to fetch archived threads.
* @typedef {Object} FetchArchivedThreadOptions * @typedef {Object} FetchArchivedThreadOptions
* @property {string} [type='public'] The type of threads to fetch, either `public` or `private` * @property {string} [type='public'] The type of threads to fetch, either `public` or `private`
* @property {boolean} [fetchAll=false] When type is `private` whether to fetch **all** archived threads, * @property {boolean} [fetchAll=false] Whether to fetch **all** archived threads when type is `private`.
* requires `MANAGE_THREADS` if true * Requires `MANAGE_THREADS` if true
* @property {DateResolvable|ThreadChannelResolvable} [before] Identifier for a Date or Snowflake * @property {DateResolvable|ThreadChannelResolvable} [before] Only return threads that were created before this Date
* to get threads that were created before it, * or Snowflake. <warn>Must be a {@link ThreadChannelResolvable} when type is `private` and fetchAll is `false`</warn>
* must be a ThreadChannelResolvable when type is `private` and fetchAll is `false`
* @property {number} [limit] Maximum number of threads to return * @property {number} [limit] Maximum number of threads to return
*/ */
/** /**
* The data returned from a thread fetch that returns multiple threads. * The data returned from a thread fetch that returns multiple threads.
* @typedef {Object} FetchedThreads * @typedef {Object} FetchedThreads
* @property {Collection<Snowflake, ThreadChannel>} threads The threads fetched, with any members returned * @property {Collection<Snowflake, ThreadChannel>} threads The threads that were fetched, with any members returned
* @property {?boolean} hasMore Whether there are potentially additional threads that require a subsequent call * @property {?boolean} hasMore Whether there are potentially additional threads that require a subsequent call
*/ */
/** /**
* Obtains a set of archived threads from Discord, requires `READ_MESSAGE_HISTORY` in the parent channel. * Obtains a set of archived threads from Discord, requires `READ_MESSAGE_HISTORY` in the parent channel.
* @param {FetchArchivedThreadOptions} [options] The options to use when fetch archived threads * @param {FetchArchivedThreadOptions} [options] The options to fetch archived threads
* @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already * @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already
* @returns {Promise<FetchedThreads>} * @returns {Promise<FetchedThreads>}
*/ */

View File

@@ -26,7 +26,7 @@ class ThreadChannel extends Channel {
this.guild = guild; this.guild = guild;
/** /**
* A manager of the messages set to this thread * A manager of the messages sent to this thread
* @type {MessageManager} * @type {MessageManager}
*/ */
this.messages = new MessageManager(this); this.messages = new MessageManager(this);
@@ -52,7 +52,7 @@ class ThreadChannel extends Channel {
if ('parent_id' in data) { if ('parent_id' in data) {
/** /**
* The ID of the parent channel to this thread * The ID of the parent channel of this thread
* @type {Snowflake} * @type {Snowflake}
*/ */
this.parentID = data.parent_id; this.parentID = data.parent_id;
@@ -66,20 +66,21 @@ class ThreadChannel extends Channel {
this.locked = data.thread_metadata.locked ?? false; this.locked = data.thread_metadata.locked ?? false;
/** /**
* Whether the thread is active (false) or archived (true) * Whether the thread is archived
* @type {boolean} * @type {boolean}
*/ */
this.archived = data.thread_metadata.archived; this.archived = data.thread_metadata.archived;
/** /**
* How long in minutes after recent activity before the thread is automatically archived * The amount of time (in minutes) after which the thread will automatically archive in case of no recent activity
* @type {number} * @type {number}
*/ */
this.autoArchiveDuration = data.thread_metadata.auto_archive_duration; this.autoArchiveDuration = data.thread_metadata.auto_archive_duration;
/** /**
* The timestamp when the thread's archive status was last changed * The timestamp when the thread's archive status was last changed
* <info>If the thread was never archived or unarchived, this is set when it's created</info> * <info>If the thread was never archived or unarchived, this is the timestamp at which the thread was
* created</info>
* @type {number} * @type {number}
*/ */
this.archiveTimestamp = new Date(data.thread_metadata.archive_timestamp).getTime(); this.archiveTimestamp = new Date(data.thread_metadata.archive_timestamp).getTime();
@@ -87,7 +88,7 @@ class ThreadChannel extends Channel {
if ('owner_id' in data) { if ('owner_id' in data) {
/** /**
* The id of the member that created this thread * The id of the member who created this thread
* @type {?Snowflake} * @type {?Snowflake}
*/ */
this.ownerID = data.owner_id; this.ownerID = data.owner_id;
@@ -111,7 +112,7 @@ class ThreadChannel extends Channel {
if ('rate_limit_per_user' in data) { if ('rate_limit_per_user' in data) {
/** /**
* The ratelimit per user for this thread in seconds * The ratelimit per user for this thread (in seconds)
* @type {number} * @type {number}
*/ */
this.rateLimitPerUser = data.rate_limit_per_user ?? 0; this.rateLimitPerUser = data.rate_limit_per_user ?? 0;
@@ -120,8 +121,8 @@ class ThreadChannel extends Channel {
if ('message_count' in data) { if ('message_count' in data) {
/** /**
* The approximate count of messages in this thread * The approximate count of messages in this thread
* <info>This value will not count above 50 even when there are more than 50 messages * <info>This stops counting at 50. If you need an approximate value higher than that, use
* If you need an approximate value higher than this, use ThreadChannel#messages.cache.size</info> * `ThreadChannel#messages.cache.size`</info>
* @type {number} * @type {number}
*/ */
this.messageCount = data.message_count; this.messageCount = data.message_count;
@@ -130,7 +131,8 @@ class ThreadChannel extends Channel {
if ('member_count' in data) { if ('member_count' in data) {
/** /**
* The approximate count of users in this thread * The approximate count of users in this thread
* <info>This value will not count above 50 even when there are more than 50 members</info> * <info>This stops counting at 50. If you need an approximate value higher than that, use
* `ThreadChannel#members.cache.size`</info>
* @type {number} * @type {number}
*/ */
this.memberCount = data.member_count; this.memberCount = data.member_count;
@@ -141,7 +143,7 @@ class ThreadChannel extends Channel {
} }
/** /**
* A collection of the guild member objects for each of this thread's members * A collection of associated guild member objects of this thread's members
* @type {Collection<Snowflake, GuildMember>} * @type {Collection<Snowflake, GuildMember>}
* @readonly * @readonly
*/ */
@@ -150,8 +152,8 @@ class ThreadChannel extends Channel {
} }
/** /**
* The time when the thread's archive status was last changed * The time at which this thread's archive status was last changed
* <info>If the thread was never archived or unarchived, this is set when it's created</info> * <info>If the thread was never archived or unarchived, this is the time at which the thread was created</info>
* @type {Date} * @type {Date}
* @readonly * @readonly
*/ */
@@ -185,7 +187,8 @@ class ThreadChannel extends Channel {
} }
/** /**
* Gets the overall set of permissions for a member or role in this threads' parent, taking into account overwrites. * Gets the overall set of permissions for a member or role in this thread's parent channel, taking overwrites into
* account.
* @param {GuildMemberResolvable|RoleResolvable} memberOrRole The member or role to obtain the overall permissions for * @param {GuildMemberResolvable|RoleResolvable} memberOrRole The member or role to obtain the overall permissions for
* @returns {?Readonly<Permissions>} * @returns {?Readonly<Permissions>}
*/ */
@@ -194,20 +197,25 @@ class ThreadChannel extends Channel {
} }
/** /**
* Edits the thread. * The options used to edit a thread channel
* @param {APIChannel} data The new data for the thread * @typedef {Object} ThreadEditData
* @param {string} [data.name] The new name for the trhead * @property {string} [name] The new name for the thread
* @param {boolean} [data.archived] Whether the thread is archived * @property {boolean} [archived] Whether the thread is archived
* @param {number} [data.autoArchiveDuration] How long in minutes before the thread is automatically archived, * @property {ThreadAutoArchiveDuration} [autoArchiveDuration] The amount of time (in minutes) after which the thread
* one of `60`, `1440`, `4320`, or `10080` * should automatically archive in case of no recent activity
* @param {number} [data.rateLimitPerUser] The ratelimit per user for the thread in seconds * @property {number} [rateLimitPerUser] The ratelimit per user for the thread in seconds
* @param {boolean} [data.locked] Whether the thread is locked * @property {boolean} [locked] Whether the thread is locked
*/
/**
* Edits this thread.
* @param {ThreadEditData} data The new data for this thread
* @param {string} [reason] Reason for editing this thread * @param {string} [reason] Reason for editing this thread
* @returns {Promise<ThreadChannel>} * @returns {Promise<ThreadChannel>}
* @example * @example
* // Edit a thread * // Edit a thread
* thread.edit({ name: 'new-thread' }) * thread.edit({ name: 'new-thread' })
* .then(console.log) * .then(editedThread => console.log(editedThread))
* .catch(console.error); * .catch(console.error);
*/ */
async edit(data, reason) { async edit(data, reason) {
@@ -231,7 +239,7 @@ class ThreadChannel extends Channel {
* @param {string} [reason] Reason for archiving or unarchiving * @param {string} [reason] Reason for archiving or unarchiving
* @returns {Promise<ThreadChannel>} * @returns {Promise<ThreadChannel>}
* @example * @example
* // Set the thread to archived * // Archive the thread
* thread.setArchived(true) * thread.setArchived(true)
* .then(newThread => console.log(`Thread is now ${newThread.archived ? 'archived' : 'active'}`)) * .then(newThread => console.log(`Thread is now ${newThread.archived ? 'archived' : 'active'}`))
* .catch(console.error); * .catch(console.error);
@@ -241,15 +249,16 @@ class ThreadChannel extends Channel {
} }
/** /**
* Sets the duration before the channel is automatically archived. * Sets the duration after which the thread will automatically archive in case of no recent activity.
* @param {ThreadAutoArchiveDuration} autoArchiveDuration How long before the thread is automatically archived * @param {ThreadAutoArchiveDuration} autoArchiveDuration The amount of time (in minutes) after which the thread
* @param {string} [reason] Reason for changing the archive time * should automatically archive in case of no recent activity
* @param {string} [reason] Reason for changing the auto archive duration
* @returns {Promise<ThreadChannel>} * @returns {Promise<ThreadChannel>}
* @example * @example
* // Set the thread auto archive time to 1 hour * // Set the thread's auto archive time to 1 hour
* thread.setAutoArchiveDuration(60) * thread.setAutoArchiveDuration(60)
* .then(newThread => { * .then(newThread => {
* console.log(`Thread will now archive after ${newThread.autoArchiveDuration}`); * console.log(`Thread will now archive after ${newThread.autoArchiveDuration} minutes of inactivity`);
* }); * });
* .catch(console.error); * .catch(console.error);
*/ */
@@ -273,12 +282,12 @@ class ThreadChannel extends Channel {
} }
/** /**
* Sets a new name for the thread. * Sets a new name for this thread.
* @param {string} name The new name for the thread * @param {string} name The new name for the thread
* @param {string} [reason] Reason for changing the thread's name * @param {string} [reason] Reason for changing the thread's name
* @returns {Promise<ThreadChannel>} * @returns {Promise<ThreadChannel>}
* @example * @example
* // Set a new thread name * // Change the thread's name
* thread.setName('not_general') * thread.setName('not_general')
* .then(newThread => console.log(`Thread's new name is ${newThread.name}`)) * .then(newThread => console.log(`Thread's new name is ${newThread.name}`))
* .catch(console.error); * .catch(console.error);
@@ -375,7 +384,7 @@ class ThreadChannel extends Channel {
* @example * @example
* // Delete the thread * // Delete the thread
* thread.delete('cleaning out old threads') * thread.delete('cleaning out old threads')
* .then(console.log) * .then(deletedThread => console.log(deletedThread))
* .catch(console.error); * .catch(console.error);
*/ */
delete(reason) { delete(reason) {

View File

@@ -47,7 +47,7 @@ class ThreadMember extends Base {
} }
/** /**
* The guild member that this thread member instance represents * The guild member associated with this thread member
* @type {?GuildMember} * @type {?GuildMember}
* @readonly * @readonly
*/ */
@@ -65,7 +65,7 @@ class ThreadMember extends Base {
} }
/** /**
* The user that this thread member instance represents * The user associated with this thread member
* @type {?User} * @type {?User}
* @readonly * @readonly
*/ */
@@ -83,7 +83,7 @@ class ThreadMember extends Base {
} }
/** /**
* Remove this member from the thread. * Removes this member from the thread.
* @param {string} [reason] Reason for removing the member * @param {string} [reason] Reason for removing the member
* @returns {ThreadMember} * @returns {ThreadMember}
*/ */

36
typings/index.d.ts vendored
View File

@@ -1582,7 +1582,7 @@ declare module 'discord.js' {
public defaultAutoArchiveDuration?: ThreadAutoArchiveDuration; public defaultAutoArchiveDuration?: ThreadAutoArchiveDuration;
public messages: MessageManager; public messages: MessageManager;
public nsfw: boolean; public nsfw: boolean;
public threads: ThreadManager; public threads: ThreadManager<AllowedThreadTypeForNewsChannel>;
public topic: string | null; public topic: string | null;
public type: 'news'; public type: 'news';
public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise<Webhook>; public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise<Webhook>;
@@ -1936,7 +1936,7 @@ declare module 'discord.js' {
public nsfw: boolean; public nsfw: boolean;
public type: 'text'; public type: 'text';
public rateLimitPerUser: number; public rateLimitPerUser: number;
public threads: ThreadManager; public threads: ThreadManager<AllowedThreadTypeForTextChannel>;
public topic: string | null; public topic: string | null;
public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise<Webhook>; public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise<Webhook>;
public setDefaultAutoArchiveDuration( public setDefaultAutoArchiveDuration(
@@ -2655,21 +2655,12 @@ declare module 'discord.js' {
public delete(channel: StageChannel | Snowflake): Promise<void>; public delete(channel: StageChannel | Snowflake): Promise<void>;
} }
export class ThreadManager extends BaseManager<Snowflake, ThreadChannel, ThreadChannelResolvable> { export class ThreadManager<AllowedThreadType> extends BaseManager<Snowflake, ThreadChannel, ThreadChannelResolvable> {
constructor(channel: TextChannel | NewsChannel, iterable?: Iterable<any>); constructor(channel: TextChannel | NewsChannel, iterable?: Iterable<any>);
public channel: TextChannel | NewsChannel; public channel: TextChannel | NewsChannel;
public create(options: { public create(options: ThreadCreateOptions<AllowedThreadType>): Promise<ThreadChannel>;
name: string;
autoArchiveDuration: ThreadAutoArchiveDuration;
startMessage?: MessageResolvable;
type?: ThreadChannelType | number;
reason?: string;
}): Promise<ThreadChannel>;
public fetch(options: ThreadChannelResolvable, cacheOptions?: BaseFetchOptions): Promise<ThreadChannel | null>; public fetch(options: ThreadChannelResolvable, cacheOptions?: BaseFetchOptions): Promise<ThreadChannel | null>;
public fetch( public fetch(options?: FetchThreadsOptions, cacheOptions?: { cache?: boolean }): Promise<FetchedThreads>;
options?: { archived?: FetchArchivedThreadOptions; active?: boolean },
cacheOptions?: { cache?: boolean },
): Promise<FetchedThreads>;
public fetchArchived(options?: FetchArchivedThreadOptions, cache?: boolean): Promise<FetchedThreads>; public fetchArchived(options?: FetchArchivedThreadOptions, cache?: boolean): Promise<FetchedThreads>;
public fetchActive(cache?: boolean): Promise<FetchedThreads>; public fetchActive(cache?: boolean): Promise<FetchedThreads>;
} }
@@ -2790,6 +2781,10 @@ declare module 'discord.js' {
deaf?: boolean; deaf?: boolean;
} }
type AllowedThreadTypeForNewsChannel = 'news_thread' | 10;
type AllowedThreadTypeForTextChannel = 'public_thread' | 'private_thread' | 11 | 12;
interface APIErrors { interface APIErrors {
UNKNOWN_ACCOUNT: 10001; UNKNOWN_ACCOUNT: 10001;
UNKNOWN_APPLICATION: 10002; UNKNOWN_APPLICATION: 10002;
@@ -3387,6 +3382,11 @@ declare module 'discord.js' {
after?: Snowflake; after?: Snowflake;
} }
interface FetchThreadsOptions {
archived?: FetchArchivedThreadOptions;
active?: boolean;
}
interface FileOptions { interface FileOptions {
attachment: BufferResolvable | Stream; attachment: BufferResolvable | Stream;
name?: string; name?: string;
@@ -4349,6 +4349,14 @@ declare module 'discord.js' {
type ThreadChannelType = 'news_thread' | 'public_thread' | 'private_thread'; type ThreadChannelType = 'news_thread' | 'public_thread' | 'private_thread';
interface ThreadCreateOptions<AllowedThreadType> {
name: string;
autoArchiveDuration: ThreadAutoArchiveDuration;
startMessage?: MessageResolvable;
type?: AllowedThreadType;
reason?: string;
}
interface ThreadEditData { interface ThreadEditData {
name?: string; name?: string;
archived?: boolean; archived?: boolean;