diff --git a/src/Fetcher.ts b/src/Fetcher.ts index eea2579..dc41d56 100644 --- a/src/Fetcher.ts +++ b/src/Fetcher.ts @@ -1,19 +1,23 @@ -import {Client, Collection, Guild, Message, NewsChannel, Permissions, Snowflake, TextChannel, ThreadChannel} from 'discord.js'; +//noinspection JSUnusedGlobalSymbols + +import {AnyChannel, Channel, Client, Collection, Guild, Message, NewsChannel, Permissions, Snowflake, TextChannel, ThreadChannel} from 'discord.js'; import {EventEmitter} from 'events'; export interface Events { fetch: [size: number, messages: Collection]; - fetchChannel: [channel: FetchChannel]; + fetchChannel: [channel: FetchableChannel]; fetchGuild: [guild: Guild]; - fetchThread: [thread: ThreadChannel, parentChannel: FetchChannel | null]; + fetchThread: [thread: ThreadChannel, parentChannel: FetchableChannel | null]; } /** * A fetchable TextChannel. */ -export type FetchChannel = NewsChannel | TextChannel; +export type FetchableChannel = NewsChannel | TextChannel; + +type Nullable = T | null; -function isFetchChannel(channel: any): channel is TextChannel | NewsChannel { +function isFetchChannel(channel: Nullable): channel is TextChannel | NewsChannel { return channel instanceof TextChannel || channel instanceof NewsChannel; } @@ -36,24 +40,24 @@ export class Fetcher extends EventEmitter { this.fetching = false; } - public on(event: K, listener: (...args: Events[K]) => void) { - return super.on(event, listener as (...args: any[]) => void); + public override emit(event: K, ...args: Events[K]) { + return super.emit(event, args); } - public once(event: K, listener: (...args: Events[K]) => void) { - return super.on(event, listener as (...args: any[]) => void); + public override eventNames() { + return super.eventNames() as Array; } - public emit(event: K, ...args: Events[K]) { - return super.emit(event, args); + public override off(event: K, listener: (...args: Events[K]) => void) { + return super.off(event, listener as (...args: any[]) => void); } - public eventNames() { - return super.eventNames() as Array; + public override on(event: K, listener: (...args: Events[K]) => void) { + return super.on(event, listener as (...args: any[]) => void); } - public off(event: K, listener: (...args: Events[K]) => void) { - return super.off(event, listener as (...args: any[]) => void); + public override once(event: K, listener: (...args: Events[K]) => void) { + return super.on(event, listener as (...args: any[]) => void); } /** @@ -63,7 +67,7 @@ export class Fetcher extends EventEmitter { * @param threads - If set to `true` it will fetch its threads, for now it will only fetch the active threads. * @returns - The messages fetched. */ - public async fetchChannel(channelID: Snowflake | FetchChannel, threads: boolean = false) { + public async fetchChannel(channelID: Snowflake | FetchableChannel, threads: boolean = false) { const channel = typeof channelID === 'string' ? await this.client.channels.fetch(channelID) : channelID; let messages = new Collection(); @@ -101,7 +105,7 @@ export class Fetcher extends EventEmitter { * @param threads - If set to `true` it will fetch all the threads of all the channels, for now it will only fetch the active threads. * @returns - The messages fetched. */ - public async fetchChannels(channels: Array | Collection, threads: boolean = false) { + public async fetchChannels(channels: Array | Collection, threads: boolean = false) { if (channels instanceof Collection) channels = [...channels.values()]; let messages = new Collection(); @@ -119,7 +123,7 @@ export class Fetcher extends EventEmitter { * Fetch an entire guild, fetching every TextChannels one by one because there is no other way. * * @remarks - * Can be really long and you should prefer using events than waiting for it to finish. + * Can be quite long, you should instead use events than waiting for it to finish. * * @param guildID - The guild to fetch, can be an ID or a Guild. * @param threads - If set to `true` it will fetch all the threads of the guild, for now it will only fetch the active threads. @@ -129,7 +133,7 @@ export class Fetcher extends EventEmitter { const guild = guildID instanceof Guild ? guildID : await this.client.guilds.fetch(guildID); let messages = new Collection(); if (guild) { - const channels = guild.channels.cache.filter(c => c.isText() && !c.isThread()) as Collection; + const channels = guild.channels.cache.filter(c => c.isText() && !c.isThread()) as Collection; this.emit('fetchGuild', guild); messages = await this.fetchChannels(channels, threads); } @@ -143,7 +147,7 @@ export class Fetcher extends EventEmitter { * Fetch all the guilds provided, if not all the guilds in the cache of the {@link client}. * * @remarks - * Can be really long and you should prefer using events than waiting for it to finish. + * Can be quite long, you should instead use events than waiting for it to finish. * * @param guilds - The guilds to fetch, if omitted it will fetch all the guilds cached by the client. * @param threads - If set to `true` it will fetch all the threads of the guilds, for now it will only fetch the active threads. @@ -162,24 +166,25 @@ export class Fetcher extends EventEmitter { } public async fetchThread(thread: ThreadChannel): Promise>; - public async fetchThread(threadID: Snowflake, channelID: Snowflake | FetchChannel): Promise>; + public async fetchThread(threadID: Snowflake, channelID: Snowflake | FetchableChannel): Promise>; /** * Fetch the entire list of messages from a Thread. * * @remarks * If the thread is private, the client need the `MANAGE_THREADS` permissions. * - * @param threadID - The thread ID or Thread itself, if an ID is provided you have to set the second paramter. + * @param threadID - The thread ID or Thread itself, if an ID is provided you have to set the second parameter. * @param channelID - The channel ID or Channel itself of the Thread, only necessary if you provide a Thread ID, else it is not used. * @returns The messages fetched. */ - public async fetchThread(threadID: Snowflake | ThreadChannel, channelID?: Snowflake | FetchChannel) { + public async fetchThread(threadID: Snowflake | ThreadChannel, channelID?: Snowflake | FetchableChannel) { let messages = new Collection(); if (typeof threadID === 'string' && !channelID) throw Error('channelID is required when using ThreadID.'); - let thread: ThreadChannel | null = null; - if (threadID instanceof ThreadChannel) thread = threadID; - else if (channelID) { + let thread: Nullable = null; + if (threadID instanceof ThreadChannel) { + thread = threadID; + } else if (channelID) { const channel = typeof channelID === 'string' ? await this.client.channels.fetch(channelID) : channelID; if (isFetchChannel(channel)) thread = await channel.threads.fetch(threadID); else return messages; @@ -212,25 +217,25 @@ export class Fetcher extends EventEmitter { } public async fetchThreads(channel: Guild): Promise>; - public async fetchThreads(channel: FetchChannel): Promise>; + public async fetchThreads(channel: FetchableChannel): Promise>; public async fetchThreads(threadsIDs: Array | Collection): Promise>; - public async fetchThreads(threadsIDs: Array | Collection, channelID: Snowflake | FetchChannel): Promise>; + public async fetchThreads(threadsIDs: Array | Collection, channelID: Snowflake | FetchableChannel): Promise>; /** * Fetch the entire list of messages from multiple threads or all the threads of a channel or all threads of a guild. - * For now it will only fetch the active threads. + * For now, it will only fetch the active threads. * * @remarks * If one of the thread is private, it will need the `MANAGE_THREADS` permission to be able to fetch its messages. - * Can be really long and you should prefer using events than waiting for it to finish. + * Can be quite long, you should instead use events than waiting for it to finish. * * @param threadsIDs - A list or a collection of threads or snowflakes to fetch messages from, if snowflakes are provided, you will need the second argument, or a channel where it will fetch all its channels, or a guild where it will fetch all its threads from all its channels. * @param channelID - The channel ID or the Channel itself parent to all the threads passed as snowflakes, it will fetch the threads from this channel. * @returns - All the messages fetched. */ - public async fetchThreads(threadsIDs: Array | Collection | FetchChannel | Guild, channelID?: Snowflake | FetchChannel) { + public async fetchThreads(threadsIDs: Array | Collection | FetchableChannel | Guild, channelID?: Snowflake | FetchableChannel) { let messages = new Collection(); let threads: Array = []; - let channel: FetchChannel | null = null; + let channel: Nullable = null; if (channelID) { const c = typeof channelID === 'string' ? await this.client.channels.fetch(channelID) : channelID; if (isFetchChannel(c)) channel = c; @@ -239,19 +244,21 @@ export class Fetcher extends EventEmitter { async function resolveThread(thread: Snowflake | ThreadChannel) { if (thread instanceof ThreadChannel) { threads.push(thread); - } else { - if (channel) { - const t = await channel.threads.fetch(thread); - if (t) threads.push(t); - } + } else if (channel) { + const t = await channel.threads.fetch(thread); + if (t) threads.push(t); } } if (threadsIDs instanceof Guild) { threads = (await Promise.all((await threadsIDs.channels.fetch()).filter(isFetchChannel).map(async c => [...(await c.threads.fetch()).threads.values()]))).flat(); - } else if (isFetchChannel(threadsIDs)) threads = [...(await threadsIDs.threads.fetch()).threads.values()]; - else if (threadsIDs instanceof Collection) [...threadsIDs.values()].forEach(resolveThread); - else threadsIDs.forEach(resolveThread); + } else if (threadsIDs instanceof Channel && isFetchChannel(threadsIDs)) { + threads = [...(await threadsIDs.threads.fetch()).threads.values()]; + } else if (threadsIDs instanceof Collection) { + [...threadsIDs.values()].forEach(resolveThread); + } else { + threadsIDs.forEach(resolveThread); + } for (const thread of threads) { const threadMessages = await this.fetchThread(thread);