diff --git a/package.json b/package.json index be87e3f..fb7a7b1 100644 --- a/package.json +++ b/package.json @@ -52,17 +52,17 @@ "homepage": "https://github.com/aiko-chan-ai/discord.js-selfbot-v13#readme", "dependencies": { "@aikochan2k6/qrcode-terminal": "^0.12.1", - "@discordjs/builders": "^1.1.0", - "@discordjs/collection": "^1.0.0", + "@discordjs/builders": "^1.2.0", + "@discordjs/collection": "^1.1.0", "@discordjs/voice": "^0.11.0", "@sapphire/async-queue": "^1.5.0", - "@sapphire/shapeshift": "^3.5.1", + "@sapphire/shapeshift": "^3.6.0", "@types/node-fetch": "^2.6.2", "@types/ws": "^8.5.3", "axios": "^0.27.2", "bignumber.js": "^9.1.0", "chalk": "^4.1.2", - "discord-api-types": "^0.37.3", + "discord-api-types": "^0.37.8", "form-data": "^4.0.0", "json-bigint": "^1.0.0", "node-fetch": "^2.6.1", @@ -83,7 +83,7 @@ "@types/node": "^16.11.12", "conventional-changelog-cli": "^2.2.2", "dtslint": "^4.2.1", - "eslint": "^8.22.0", + "eslint": "^8.23.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.2.1", @@ -94,6 +94,6 @@ "prettier": "^2.5.1", "tsd": "^0.22.0", "tslint": "^6.1.3", - "typescript": "^4.5.4" + "typescript": "^4.8.3" } } diff --git a/src/client/Client.js b/src/client/Client.js index e4b8644..fa43dd9 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -14,7 +14,7 @@ const ChannelManager = require('../managers/ChannelManager'); const ClientSettingManager = require('../managers/ClientSettingManager'); const DeveloperPortalManager = require('../managers/DeveloperPortalManager'); const GuildManager = require('../managers/GuildManager'); -const RelationshipsManager = require('../managers/RelationshipsManager'); +const RelationshipManager = require('../managers/RelationshipManager'); const SessionManager = require('../managers/SessionManager'); const UserManager = require('../managers/UserManager'); const VoiceStateManager = require('../managers/VoiceStateManager'); @@ -142,9 +142,9 @@ class Client extends BaseClient { // Patch /** * All of the relationships {@link User} - * @type {RelationshipsManager} + * @type {RelationshipManager} */ - this.relationships = new RelationshipsManager(this); + this.relationships = new RelationshipManager(this); /** * All of the settings {@link Object} * @type {ClientSettingManager} diff --git a/src/index.js b/src/index.js index 4e9685a..bb90451 100644 --- a/src/index.js +++ b/src/index.js @@ -68,7 +68,7 @@ exports.UserManager = require('./managers/UserManager'); exports.VoiceStateManager = require('./managers/VoiceStateManager'); exports.WebSocketManager = require('./client/websocket/WebSocketManager'); exports.WebSocketShard = require('./client/websocket/WebSocketShard'); -exports.RelationshipsManager = require('./managers/RelationshipsManager'); +exports.RelationshipManager = require('./managers/RelationshipManager'); // Structures exports.Activity = require('./structures/Presence').Activity; diff --git a/src/managers/GuildBanManager.js b/src/managers/GuildBanManager.js index e67fd43..e0a40d9 100644 --- a/src/managers/GuildBanManager.js +++ b/src/managers/GuildBanManager.js @@ -1,11 +1,14 @@ 'use strict'; +const process = require('node:process'); const { Collection } = require('@discordjs/collection'); const CachedManager = require('./CachedManager'); const { TypeError, Error } = require('../errors'); const GuildBan = require('../structures/GuildBan'); const { GuildMember } = require('../structures/GuildMember'); +let deprecationEmittedForDays = false; + /** * Manages API methods for GuildBans and stores their cache. * @extends {CachedManager} @@ -126,6 +129,9 @@ class GuildBanManager extends CachedManager { * Options used to ban a user from a guild. * @typedef {Object} BanOptions * @property {number} [days=0] Number of days of messages to delete, must be between 0 and 7, inclusive + * This property is deprecated. Use `deleteMessageSeconds` instead. + * @property {number} [deleteMessageSeconds=0] Number of seconds of messages to delete, + * must be between 0 and 604800 (7 days), inclusive * @property {string} [reason] The reason for the ban */ @@ -142,15 +148,30 @@ class GuildBanManager extends CachedManager { * .then(banInfo => console.log(`Banned ${banInfo.user?.tag ?? banInfo.tag ?? banInfo}`)) * .catch(console.error); */ - async create(user, options = { days: 0 }) { + async create(user, options = {}) { if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true); const id = this.client.users.resolveId(user); if (!id) throw new Error('BAN_RESOLVE_ID', true); + + if (typeof options.days !== 'undefined' && !deprecationEmittedForDays) { + process.emitWarning( + 'The days option for GuildBanManager#create() is deprecated. Use the deleteMessageSeconds option instead.', + 'DeprecationWarning', + ); + + deprecationEmittedForDays = true; + } + await this.client.api .guilds(this.guild.id) .bans(id) .put({ - data: { delete_message_days: options.days }, + data: { + delete_message_seconds: + typeof options.deleteMessageSeconds !== 'undefined' + ? options.deleteMessageSeconds + : (options.days ?? 0) * 24 * 60 * 60, + }, reason: options.reason, }); if (user instanceof GuildMember) return user; diff --git a/src/managers/GuildMemberManager.js b/src/managers/GuildMemberManager.js index 537d1b5..147cdf9 100644 --- a/src/managers/GuildMemberManager.js +++ b/src/managers/GuildMemberManager.js @@ -394,7 +394,7 @@ class GuildMemberManager extends CachedManager { * .then(banInfo => console.log(`Banned ${banInfo.user?.tag ?? banInfo.tag ?? banInfo}`)) * .catch(console.error); */ - ban(user, options = { days: 0 }) { + ban(user, options) { return this.guild.bans.create(user, options); } diff --git a/src/managers/RelationshipsManager.js b/src/managers/RelationshipManager.js similarity index 78% rename from src/managers/RelationshipsManager.js rename to src/managers/RelationshipManager.js index a0eb04c..cb4ae28 100644 --- a/src/managers/RelationshipsManager.js +++ b/src/managers/RelationshipManager.js @@ -10,7 +10,7 @@ const { RelationshipTypes } = require('../util/Constants'); /** * Manages API methods for Relationships and stores their cache. */ -class RelationshipsManager { +class RelationshipManager { constructor(client, users) { /** * The client that instantiated this manager. @@ -26,6 +26,54 @@ class RelationshipsManager { this._setup(users); } + /** + * Get all friends + * @type {Collection} + * @readonly + */ + get friendCache() { + const users = this.cache + .filter(value => value === RelationshipTypes.FRIEND) + .map((value, key) => [key, this.client.users.cache.get(key)]); + return new Collection(users); + } + + /** + * Get all blocked users + * @type {Collection} + * @readonly + */ + get blockedCache() { + const users = this.cache + .filter(value => value === RelationshipTypes.BLOCKED) + .map((value, key) => [key, this.client.users.cache.get(key)]); + return new Collection(users); + } + + /** + * Get all incoming friend requests + * @type {Collection} + * @readonly + */ + get incomingCache() { + const users = this.cache + .filter(value => value === RelationshipTypes.PENDING_INCOMING) + .map((value, key) => [key, this.client.users.cache.get(key)]); + return new Collection(users); + } + + /** + * Get all outgoing friend requests + * @type {Collection} + * @readonly + */ + get outgoingCache() { + const users = this.cache + .filter(value => value === RelationshipTypes.PENDING_OUTGOING) + .map((value, key) => [key, this.client.users.cache.get(key)]); + return new Collection(users); + } + /** * Return array of cache * @returns {Array<{id: Snowflake, type: RelationshipTypes}>} @@ -172,4 +220,4 @@ class RelationshipsManager { } } -module.exports = RelationshipsManager; +module.exports = RelationshipManager; diff --git a/src/structures/ClientApplication.js b/src/structures/ClientApplication.js index 0abb80f..d4cb84b 100644 --- a/src/structures/ClientApplication.js +++ b/src/structures/ClientApplication.js @@ -1,5 +1,6 @@ 'use strict'; +const { Collection } = require('@discordjs/collection'); const Team = require('./Team'); const Application = require('./interfaces/Application'); const ApplicationCommandManager = require('../managers/ApplicationCommandManager'); @@ -107,6 +108,17 @@ class ClientApplication extends Application { this.botPublic ??= null; } + if ('popular_application_command_ids' in data) { + /** + * List of popular command + * @type {?Collection} + */ + this.popularCommands = new Collection(); + data.popular_application_command_ids.forEach(id => { + this.popularCommands.set(id, this.commands.cache.get(id)); + }); + } + /** * The owner of this OAuth application * @type {?(User|Team)} diff --git a/src/structures/GuildMember.js b/src/structures/GuildMember.js index 0db6cc9..6fd1131 100644 --- a/src/structures/GuildMember.js +++ b/src/structures/GuildMember.js @@ -465,8 +465,8 @@ class GuildMember extends Base { * @param {BanOptions} [options] Options for the ban * @returns {Promise} * @example - * // ban a guild member - * guildMember.ban({ days: 7, reason: 'They deserved it' }) + * // Ban a guild member, deleting a week's worth of messages + * guildMember.ban({ deleteMessageSeconds: 60 * 60 * 24 * 7, reason: 'They deserved it' }) * .then(console.log) * .catch(console.error); */ diff --git a/src/util/Intents.js b/src/util/Intents.js index 359e10b..6600f59 100644 --- a/src/util/Intents.js +++ b/src/util/Intents.js @@ -40,6 +40,7 @@ class Intents extends BitField {} * * `DIRECT_MESSAGES` * * `DIRECT_MESSAGE_REACTIONS` * * `DIRECT_MESSAGE_TYPING` + * * `MESSAGE_CONTENT` * * `GUILD_SCHEDULED_EVENTS` * @type {Object} * @see {@link https://discord.com/developers/docs/topics/gateway#list-of-intents} @@ -60,6 +61,7 @@ Intents.FLAGS = { DIRECT_MESSAGES: 1 << 12, DIRECT_MESSAGE_REACTIONS: 1 << 13, DIRECT_MESSAGE_TYPING: 1 << 14, + MESSAGE_CONTENT: 1 << 15, GUILD_SCHEDULED_EVENTS: 1 << 16, }; diff --git a/typings/index.d.ts b/typings/index.d.ts index 5d3b19f..4a761c9 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -9,7 +9,6 @@ import { hyperlink, inlineCode, italic, - JSONEncodable, quote, roleMention, SlashCommandBuilder, @@ -25,14 +24,11 @@ import { VoiceConnection } from '@discordjs/voice'; import { Collection } from '@discordjs/collection'; import { APIActionRowComponent, - APIActionRowComponentTypes, - APIApplicationCommand, APIApplicationCommandInteractionData, APIApplicationCommandOption, APIApplicationCommandPermission, APIAuditLogChange, APIButtonComponent, - APIChannel, APIEmbed, APIEmoji, APIInteractionDataResolvedChannel, @@ -832,7 +828,7 @@ export class Client extends BaseClient { public application: If; // Added public setting: ClientSettingManager; - public relationships: RelationshipsManager; + public relationships: RelationshipManager; public updateCookie(): Promise; public readonly callVoice?: VoiceConnection; public voiceStates: VoiceStateManager; @@ -903,6 +899,7 @@ export class Client extends BaseClient { export class ClientApplication extends Application { private constructor(client: Client, data: RawClientApplicationData); public botPublic: boolean | null; + public popularCommands: Collection | undefined; public botRequireCodeGrant: boolean | null; public commands: ApplicationCommandManager; public cover: string | null; @@ -1943,7 +1940,8 @@ export class MessageActionRow< ? APIActionRowComponent : APIActionRowComponent, > extends BaseMessageComponent { - // @ts-ignore + // @ts-ignore (TS:2344, Caused by TypeScript 4.8) + // Fixed in DiscordJS >= 14.x / DiscordApiTypes >= 0.37.x, ignoring the type error here. public constructor(data?: MessageActionRow | MessageActionRowOptions | V); public type: 'ACTION_ROW'; public components: T[]; @@ -3998,10 +3996,14 @@ export class UserManager extends CachedManager public send(user: UserResolvable, options: string | MessagePayload | MessageOptions): Promise; } -export class RelationshipsManager { +export class RelationshipManager { private constructor(client: Client, users?: object[]); public cache: Collection; public client: Client; + public readonly friendCache: Collection; + public readonly blockedCache: Collection; + public readonly incomingCache: Collection; + public readonly outgoingCache: Collection; public fetch(user: UserResolvable, options?: BaseFetchOptions): Promise; public deleteFriend(user: UserResolvable): Promise; public deleteBlocked(user: UserResolvable): Promise; @@ -4858,7 +4860,9 @@ export interface AwaitReactionsOptions extends ReactionCollectorOptions { } export interface BanOptions { + /** @deprecated Use {@link deleteMessageSeconds} instead. */ days?: number; + deleteMessageSeconds?: number; reason?: string; } @@ -5845,6 +5849,7 @@ export type IntentsString = | 'DIRECT_MESSAGES' | 'DIRECT_MESSAGE_REACTIONS' | 'DIRECT_MESSAGE_TYPING' + | 'MESSAGE_CONTENT' | 'GUILD_SCHEDULED_EVENTS'; export interface InviteGenerationOptions {