From cf72d42ea51670671ecda16b373e668301ee2c68 Mon Sep 17 00:00:00 2001 From: Almeida Date: Tue, 8 Aug 2023 07:44:27 +0100 Subject: [PATCH 1/6] ci: upload /formatters test coverage (#9753) chore: upload /formatters test coverage --- packages/actions/src/uploadCoverage/action.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/actions/src/uploadCoverage/action.yml b/packages/actions/src/uploadCoverage/action.yml index 3652a560b828..a8406ad55b81 100644 --- a/packages/actions/src/uploadCoverage/action.yml +++ b/packages/actions/src/uploadCoverage/action.yml @@ -39,6 +39,12 @@ runs: files: ./packages/discord.js/coverage/cobertura-coverage.xml flags: discord.js + - name: Upload Formatters Coverage + uses: codecov/codecov-action@v3 + with: + files: ./packages/formatters/coverage/cobertura-coverage.xml + flags: formatters + - name: Upload Next Coverage uses: codecov/codecov-action@v3 with: From 99194fc2703988693264ef4a7c2d7bb040c39fa8 Mon Sep 17 00:00:00 2001 From: Jaw0r3k Date: Wed, 9 Aug 2023 11:48:58 +0200 Subject: [PATCH 2/6] fix(create-discord-bot): add shebang in main file (#9747) * fix: no running in cmd Co-authored-by: ROB0520 * chore: delete in create-discord-bot file --------- Co-authored-by: ROB0520 Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/create-discord-bot/src/create-discord-bot.ts | 3 --- packages/create-discord-bot/src/index.ts | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/create-discord-bot/src/create-discord-bot.ts b/packages/create-discord-bot/src/create-discord-bot.ts index c7641d92d153..44e5ba8f8e2f 100755 --- a/packages/create-discord-bot/src/create-discord-bot.ts +++ b/packages/create-discord-bot/src/create-discord-bot.ts @@ -1,6 +1,3 @@ -#!/usr/bin/env node - -// eslint-disable-next-line n/shebang import { cp, stat, mkdir, readdir, readFile, writeFile } from 'node:fs/promises'; import path from 'node:path'; import process from 'node:process'; diff --git a/packages/create-discord-bot/src/index.ts b/packages/create-discord-bot/src/index.ts index dc8bce8c0089..5413fbbd75d6 100644 --- a/packages/create-discord-bot/src/index.ts +++ b/packages/create-discord-bot/src/index.ts @@ -1,3 +1,6 @@ +#!/usr/bin/env node + +// eslint-disable-next-line n/shebang import { program } from 'commander'; import prompts from 'prompts'; import { createDiscordBot } from './create-discord-bot.js'; From 0de071d0a5524ba1fbb8cab5d7e74567103f7129 Mon Sep 17 00:00:00 2001 From: Synbulat Biishev Date: Wed, 9 Aug 2023 19:15:00 +0500 Subject: [PATCH 3/6] feat: add `Client#webhooksUpdate` (#9732) * feat: add `Client#webhooksUpdate` * feat: add deprecation in the types * docs: add full stops * types: reference non-deprecated type This helps with future-proofing (deduplication). * docs(ClientEvents): fix reference link This now hyperlinks correctly with IntelliSense. --------- Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/client/actions/WebhooksUpdate.js | 21 +++++++++++++++++-- packages/discord.js/typings/index.d.ts | 4 +++- packages/discord.js/typings/index.test-d.ts | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/discord.js/src/client/actions/WebhooksUpdate.js b/packages/discord.js/src/client/actions/WebhooksUpdate.js index 914b03fb2f01..2bf41ba2702f 100644 --- a/packages/discord.js/src/client/actions/WebhooksUpdate.js +++ b/packages/discord.js/src/client/actions/WebhooksUpdate.js @@ -1,19 +1,36 @@ 'use strict'; +const process = require('node:process'); const Action = require('./Action'); -const Events = require('../../util/Events'); + +let deprecationEmitted = false; class WebhooksUpdate extends Action { handle(data) { const client = this.client; const channel = client.channels.cache.get(data.channel_id); + if (!channel) return; + + // TODO: change to Events.WebhooksUpdate in the next major version + /** + * Emitted whenever a channel has its webhooks changed. + * @event Client#webhooksUpdate + * @param {TextChannel|NewsChannel|VoiceChannel|StageChannel|ForumChannel} channel + * The channel that had a webhook update + */ + client.emit('webhooksUpdate', channel); + /** * Emitted whenever a channel has its webhooks changed. * @event Client#webhookUpdate * @param {TextChannel|NewsChannel|VoiceChannel|StageChannel|ForumChannel} channel * The channel that had a webhook update + * @deprecated Use {@link Client#event:webhooksUpdate} instead. */ - if (channel) client.emit(Events.WebhooksUpdate, channel); + if (client.emit('webhookUpdate', channel) && !deprecationEmitted) { + deprecationEmitted = true; + process.emitWarning('The webhookUpdate event is deprecated. Use webhooksUpdate instead.', 'DeprecationWarning'); + } } } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 766ff2deb2be..192881db9894 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -4861,7 +4861,9 @@ export interface ClientEvents { typingStart: [typing: Typing]; userUpdate: [oldUser: User | PartialUser, newUser: User]; voiceStateUpdate: [oldState: VoiceState, newState: VoiceState]; - webhookUpdate: [channel: TextChannel | NewsChannel | VoiceChannel | ForumChannel]; + /** @deprecated Use {@link webhooksUpdate} instead. */ + webhookUpdate: ClientEvents['webhooksUpdate']; + webhooksUpdate: [channel: TextChannel | NewsChannel | VoiceChannel | ForumChannel]; interactionCreate: [interaction: Interaction]; shardDisconnect: [closeEvent: CloseEvent, shardId: number]; shardError: [error: Error, shardId: number]; diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index 9c9f79938d44..ddcdb1114773 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -1170,7 +1170,7 @@ client.on('voiceStateUpdate', ({ client: oldClient }, { client: newClient }) => expectType>(newClient); }); -client.on('webhookUpdate', ({ client }) => expectType>(client)); +client.on('webhooksUpdate', ({ client }) => expectType>(client)); client.on('guildCreate', async g => { expectType>(g.client); From 692f0fc96d9f92161b64fb83f02b71d43d2d7c9c Mon Sep 17 00:00:00 2001 From: Almeida Date: Thu, 10 Aug 2023 21:53:54 +0100 Subject: [PATCH 4/6] feat(Attachment): add `flags` (#9686) * feat(Attachment): add `flags` * fix: import * fix: flags casing Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> --------- Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/discord.js/src/index.js | 1 + .../discord.js/src/structures/Attachment.js | 11 ++++++++ packages/discord.js/src/util/APITypes.js | 5 ++++ .../src/util/AttachmentFlagsBitField.js | 26 +++++++++++++++++++ packages/discord.js/typings/index.d.ts | 9 +++++++ 5 files changed, 52 insertions(+) create mode 100644 packages/discord.js/src/util/AttachmentFlagsBitField.js diff --git a/packages/discord.js/src/index.js b/packages/discord.js/src/index.js index 3c0dcd96319b..a7137270aa17 100644 --- a/packages/discord.js/src/index.js +++ b/packages/discord.js/src/index.js @@ -19,6 +19,7 @@ exports.DiscordjsErrorCodes = require('./errors/ErrorCodes'); // Utilities exports.ActivityFlagsBitField = require('./util/ActivityFlagsBitField'); exports.ApplicationFlagsBitField = require('./util/ApplicationFlagsBitField'); +exports.AttachmentFlagsBitField = require('./util/AttachmentFlagsBitField'); exports.BaseManager = require('./managers/BaseManager'); exports.BitField = require('./util/BitField'); exports.ChannelFlagsBitField = require('./util/ChannelFlagsBitField'); diff --git a/packages/discord.js/src/structures/Attachment.js b/packages/discord.js/src/structures/Attachment.js index 086d7a870731..2576ff59cdb1 100644 --- a/packages/discord.js/src/structures/Attachment.js +++ b/packages/discord.js/src/structures/Attachment.js @@ -1,5 +1,6 @@ 'use strict'; +const AttachmentFlagsBitField = require('../util/AttachmentFlagsBitField.js'); const { basename, flatten } = require('../util/Util'); /** @@ -121,6 +122,16 @@ class Attachment { } else { this.waveform ??= null; } + + if ('flags' in data) { + /** + * The flags of this attachment + * @type {Readonly} + */ + this.flags = new AttachmentFlagsBitField(data.flags).freeze(); + } else { + this.flags ??= new AttachmentFlagsBitField().freeze(); + } } /** diff --git a/packages/discord.js/src/util/APITypes.js b/packages/discord.js/src/util/APITypes.js index 11d468ada3a5..12c67b79ed2b 100644 --- a/packages/discord.js/src/util/APITypes.js +++ b/packages/discord.js/src/util/APITypes.js @@ -210,6 +210,11 @@ * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationRoleConnectionMetadataType} */ +/** + * @external AttachmentFlags + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/AttachmentFlags} + */ + /** * @external AutoModerationActionType * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/AutoModerationActionType} diff --git a/packages/discord.js/src/util/AttachmentFlagsBitField.js b/packages/discord.js/src/util/AttachmentFlagsBitField.js new file mode 100644 index 000000000000..f7f2bd23d0d6 --- /dev/null +++ b/packages/discord.js/src/util/AttachmentFlagsBitField.js @@ -0,0 +1,26 @@ +'use strict'; + +const { AttachmentFlags } = require('discord-api-types/v10'); +const BitField = require('./BitField'); + +/** + * Data structure that makes it easy to interact with an {@link Attachment#flags} bitfield. + * @extends {BitField} + */ +class AttachmentFlagsBitField extends BitField { + /** + * Numeric attachment flags. + * @type {AttachmentFlags} + * @memberof AttachmentFlagsBitField + */ + static Flags = AttachmentFlags; +} + +/** + * @name AttachmentFlagsBitField + * @kind constructor + * @memberof AttachmentFlagsBitField + * @param {BitFieldResolvable} [bits=0] Bit(s) to read from + */ + +module.exports = AttachmentFlagsBitField; diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 192881db9894..47cf317718e0 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -166,6 +166,7 @@ import { APIGuildOnboardingPrompt, APIGuildOnboardingPromptOption, GuildOnboardingPromptType, + AttachmentFlags, } from 'discord-api-types/v10'; import { ChildProcess } from 'node:child_process'; import { EventEmitter } from 'node:events'; @@ -2070,6 +2071,7 @@ export class Attachment { public description: string | null; public duration: number | null; public ephemeral: boolean; + public flags: AttachmentFlagsBitField; public height: number | null; public id: Snowflake; public name: string; @@ -2082,6 +2084,13 @@ export class Attachment { public toJSON(): unknown; } +export type AttachmentFlagsString = keyof typeof AttachmentFlags; + +export class AttachmentFlagsBitField extends BitField { + public static Flags: Record; + public static resolve(bit?: BitFieldResolvable): number; +} + export class MessageCollector extends Collector]> { public constructor(channel: TextBasedChannel, options?: MessageCollectorOptions); private _handleChannelDeletion(channel: NonThreadGuildBasedChannel): void; From 3b18e5b08dc3ec2aba37d3e6a55e42ce8af7dbab Mon Sep 17 00:00:00 2001 From: n1ck_pro <59617443+N1ckPro@users.noreply.github.com> Date: Thu, 10 Aug 2023 23:20:13 +0200 Subject: [PATCH 5/6] feat(Role): add `flags` (#9694) * feat(Role): add `flags` * types: use RoleFlags enum * Update packages/discord.js/typings/index.d.ts Co-authored-by: Jaw0r3k --------- Co-authored-by: Jaw0r3k --- packages/discord.js/src/index.js | 1 + packages/discord.js/src/structures/Role.js | 11 ++++++++ packages/discord.js/src/util/APITypes.js | 5 ++++ .../discord.js/src/util/RoleFlagsBitField.js | 26 +++++++++++++++++++ packages/discord.js/typings/index.d.ts | 9 +++++++ 5 files changed, 52 insertions(+) create mode 100644 packages/discord.js/src/util/RoleFlagsBitField.js diff --git a/packages/discord.js/src/index.js b/packages/discord.js/src/index.js index a7137270aa17..502133141320 100644 --- a/packages/discord.js/src/index.js +++ b/packages/discord.js/src/index.js @@ -36,6 +36,7 @@ exports.MessageFlagsBitField = require('./util/MessageFlagsBitField'); exports.Options = require('./util/Options'); exports.Partials = require('./util/Partials'); exports.PermissionsBitField = require('./util/PermissionsBitField'); +exports.RoleFlagsBitField = require('./util/RoleFlagsBitField'); exports.ShardEvents = require('./util/ShardEvents'); exports.Status = require('./util/Status'); exports.SnowflakeUtil = require('@sapphire/snowflake').DiscordSnowflake; diff --git a/packages/discord.js/src/structures/Role.js b/packages/discord.js/src/structures/Role.js index 63f10961a44c..09a2a52ca880 100644 --- a/packages/discord.js/src/structures/Role.js +++ b/packages/discord.js/src/structures/Role.js @@ -5,6 +5,7 @@ const { PermissionFlagsBits } = require('discord-api-types/v10'); const Base = require('./Base'); const { DiscordjsError, ErrorCodes } = require('../errors'); const PermissionsBitField = require('../util/PermissionsBitField'); +const RoleFlagsBitField = require('../util/RoleFlagsBitField'); /** * Represents a role on Discord. @@ -101,6 +102,16 @@ class Role extends Base { if ('unicode_emoji' in data) this.unicodeEmoji = data.unicode_emoji; + if ('flags' in data) { + /** + * The flags of this role + * @type {Readonly} + */ + this.flags = new RoleFlagsBitField(data.flags).freeze(); + } else { + this.flags ??= new RoleFlagsBitField().freeze(); + } + /** * The tags this role has * @type {?Object} diff --git a/packages/discord.js/src/util/APITypes.js b/packages/discord.js/src/util/APITypes.js index 12c67b79ed2b..e8ab25a89d13 100644 --- a/packages/discord.js/src/util/APITypes.js +++ b/packages/discord.js/src/util/APITypes.js @@ -410,6 +410,11 @@ * @see {@link https://discord-api-types.dev/api/discord-api-types-payloads/common#PermissionFlagsBits} */ +/** + * @external RoleFlags + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/RoleFlags} + */ + /** * @external RESTGetAPIGuildThreadsResult * @see {@link https://discord-api-types.dev/api/discord-api-types-v10#RESTGetAPIGuildThreadsResult} diff --git a/packages/discord.js/src/util/RoleFlagsBitField.js b/packages/discord.js/src/util/RoleFlagsBitField.js new file mode 100644 index 000000000000..1e0f89548922 --- /dev/null +++ b/packages/discord.js/src/util/RoleFlagsBitField.js @@ -0,0 +1,26 @@ +'use strict'; + +const { RoleFlags } = require('discord-api-types/v10'); +const BitField = require('./BitField'); + +/** + * Data structure that makes it easy to interact with a {@link Role#flags} bitfield. + * @extends {BitField} + */ +class RoleFlagsBitField extends BitField { + /** + * Numeric role flags. + * @type {RoleFlags} + * @memberof RoleFlagsBitField + */ + static Flags = RoleFlags; +} + +/** + * @name RoleFlagsBitField + * @kind constructor + * @memberof RoleFlagsBitField + * @param {BitFieldResolvable} [bits=0] Bit(s) to read from + */ + +module.exports = RoleFlagsBitField; diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 47cf317718e0..d5e9feee2558 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -167,6 +167,7 @@ import { APIGuildOnboardingPromptOption, GuildOnboardingPromptType, AttachmentFlags, + RoleFlags, } from 'discord-api-types/v10'; import { ChildProcess } from 'node:child_process'; import { EventEmitter } from 'node:events'; @@ -2524,6 +2525,7 @@ export class Role extends Base { public get createdAt(): Date; public get createdTimestamp(): number; public get editable(): boolean; + public flags: RoleFlagsBitField; public guild: Guild; public get hexColor(): HexColorString; public hoist: boolean; @@ -2559,6 +2561,13 @@ export class Role extends Base { public toString(): RoleMention; } +export type RoleFlagsString = keyof typeof RoleFlags; + +export class RoleFlagsBitField extends BitField { + public static Flags: typeof RoleFlags; + public static resolve(bit?: BitFieldResolvable): number; +} + export class StringSelectMenuInteraction< Cached extends CacheType = CacheType, > extends MessageComponentInteraction { From 632a9b4965cd24ffffdf0f88f1a9eedeb6b284f7 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Fri, 11 Aug 2023 08:11:13 +0100 Subject: [PATCH 6/6] feat(ClientApplication): Approximate guild count and new `GET` route (#9713) * feat: add approx guild count and get route * refactor: replace route * docs: update description of class The replacement route justifies this change. * feat(ClientApplication): add `approximateGuildCount` * refactor: revert now-unnecessary changes --- .../src/structures/ClientApplication.js | 35 +++++++++++++++++-- packages/discord.js/typings/index.d.ts | 3 ++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/discord.js/src/structures/ClientApplication.js b/packages/discord.js/src/structures/ClientApplication.js index afee47d3c353..69f51340bb5d 100644 --- a/packages/discord.js/src/structures/ClientApplication.js +++ b/packages/discord.js/src/structures/ClientApplication.js @@ -15,7 +15,7 @@ const PermissionsBitField = require('../util/PermissionsBitField'); */ /** - * Represents a Client OAuth2 Application. + * Represents a client application. * @extends {Application} */ class ClientApplication extends Application { @@ -69,6 +69,26 @@ class ClientApplication extends Application { this.flags = new ApplicationFlagsBitField(data.flags).freeze(); } + if ('approximate_guild_count' in data) { + /** + * An approximate amount of guilds this application is in. + * @type {?number} + */ + this.approximateGuildCount = data.approximate_guild_count; + } else { + this.approximateGuildCount ??= null; + } + + if ('guild_id' in data) { + /** + * The id of the guild associated with this application. + * @type {?Snowflake} + */ + this.guildId = data.guild_id; + } else { + this.guildId ??= null; + } + if ('cover_image' in data) { /** * The hash of the application's cover image @@ -130,6 +150,15 @@ class ClientApplication extends Application { : this.owner ?? null; } + /** + * The guild associated with this application. + * @type {?Guild} + * @readonly + */ + get guild() { + return this.client.guilds.cache.get(this.guildId) ?? null; + } + /** * Whether this application is partial * @type {boolean} @@ -144,8 +173,8 @@ class ClientApplication extends Application { * @returns {Promise} */ async fetch() { - const app = await this.client.rest.get(Routes.oauth2CurrentApplication()); - this._patch(app); + const data = await this.client.rest.get(Routes.currentApplication()); + this._patch(data); return this; } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index d5e9feee2558..21acbb14000a 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -1012,8 +1012,11 @@ export class ClientApplication extends Application { public botPublic: boolean | null; public botRequireCodeGrant: boolean | null; public commands: ApplicationCommandManager; + public guildId: Snowflake | null; + public get guild(): Guild | null; public cover: string | null; public flags: Readonly; + public approximateGuildCount: number | null; public tags: string[]; public installParams: ClientApplicationInstallParams | null; public customInstallURL: string | null;