diff --git a/packages/discord.js/src/managers/ApplicationCommandManager.js b/packages/discord.js/src/managers/ApplicationCommandManager.js index 9a51d4079..23bddabef 100644 --- a/packages/discord.js/src/managers/ApplicationCommandManager.js +++ b/packages/discord.js/src/managers/ApplicationCommandManager.js @@ -1,5 +1,6 @@ 'use strict'; +const { isJSONEncodable } = require('@discordjs/builders'); const { Collection } = require('@discordjs/collection'); const { makeURLSearchParams } = require('@discordjs/rest'); const { Routes } = require('discord-api-types/v10'); @@ -65,6 +66,13 @@ class ApplicationCommandManager extends CachedManager { * @typedef {ApplicationCommand|Snowflake} ApplicationCommandResolvable */ + /* eslint-disable max-len */ + /** + * Data that resolves to the data of an ApplicationCommand + * @typedef {ApplicationCommandData|APIApplicationCommand|JSONEncodable} ApplicationCommandDataResolvable + */ + /* eslint-enable max-len */ + /** * Options used to fetch data from Discord * @typedef {Object} BaseFetchOptions @@ -119,7 +127,7 @@ class ApplicationCommandManager extends CachedManager { /** * Creates an application command. - * @param {ApplicationCommandData|APIApplicationCommand} command The command + * @param {ApplicationCommandDataResolvable} command The command * @param {Snowflake} [guildId] The guild's id to create this command in, * ignored when using a {@link GuildApplicationCommandManager} * @returns {Promise} @@ -141,7 +149,7 @@ class ApplicationCommandManager extends CachedManager { /** * Sets all the commands for this application or guild. - * @param {ApplicationCommandData[]|APIApplicationCommand[]} commands The commands + * @param {ApplicationCommandDataResolvable[]} commands The commands * @param {Snowflake} [guildId] The guild's id to create the commands in, * ignored when using a {@link GuildApplicationCommandManager} * @returns {Promise>} @@ -171,7 +179,7 @@ class ApplicationCommandManager extends CachedManager { /** * Edits an application command. * @param {ApplicationCommandResolvable} command The command to edit - * @param {Partial} data The data to update the command with + * @param {Partial} data The data to update the command with * @param {Snowflake} [guildId] The guild's id where the command registered, * ignored when using a {@link GuildApplicationCommandManager} * @returns {Promise} @@ -218,11 +226,13 @@ class ApplicationCommandManager extends CachedManager { /** * Transforms an {@link ApplicationCommandData} object into something that can be used with the API. - * @param {ApplicationCommandData|APIApplicationCommand} command The command to transform + * @param {ApplicationCommandDataResolvable} command The command to transform * @returns {APIApplicationCommand} * @private */ static transformCommand(command) { + if (isJSONEncodable(command)) return command.toJSON(); + let default_member_permissions; if ('default_member_permissions' in command) { diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 47fe57ba8..674e0bc2e 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -3174,7 +3174,10 @@ export abstract class CachedManager extends DataManager; export class ApplicationCommandManager< ApplicationCommandScope = ApplicationCommand<{ guild: GuildResolvable }>, @@ -3215,9 +3218,7 @@ export class ApplicationCommandManager< commands: ApplicationCommandDataResolvable[], guildId: Snowflake, ): Promise>; - private static transformCommand( - command: ApplicationCommandData, - ): Omit; + private static transformCommand(command: ApplicationCommandDataResolvable): RESTPostAPIApplicationCommandsJSONBody; } export class ApplicationCommandPermissionsManager< @@ -3304,7 +3305,7 @@ export class GuildApplicationCommandManager extends ApplicationCommandManager; public edit( command: ApplicationCommandResolvable, - data: ApplicationCommandDataResolvable, + data: Partial, ): Promise; public fetch(id: Snowflake, options?: FetchGuildApplicationCommandFetchOptions): Promise; public fetch(options: FetchGuildApplicationCommandFetchOptions): Promise>; diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index 567d41ad0..385197860 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -131,7 +131,13 @@ import { CollectedMessageInteraction, } from '.'; import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd'; -import { UnsafeButtonBuilder, UnsafeEmbedBuilder, UnsafeSelectMenuBuilder } from '@discordjs/builders'; +import { + ContextMenuCommandBuilder, + SlashCommandBuilder, + UnsafeButtonBuilder, + UnsafeEmbedBuilder, + UnsafeSelectMenuBuilder, +} from '@discordjs/builders'; // Test type transformation: declare const serialize: (value: T) => Serialized; @@ -155,6 +161,9 @@ const testUserId = '987654321098765432'; // example id const globalCommandId = '123456789012345678'; // example id const guildCommandId = '234567890123456789'; // example id +declare const slashCommandBuilder: SlashCommandBuilder; +declare const contextMenuCommandBuilder: ContextMenuCommandBuilder; + client.on('ready', async () => { console.log(`Client is logged in as ${client.user!.tag} and ready!`); @@ -171,6 +180,16 @@ client.on('ready', async () => { const guildCommandFromGlobal = await client.application?.commands.fetch(guildCommandId, { guildId: testGuildId }); const guildCommandFromGuild = await client.guilds.cache.get(testGuildId)?.commands.fetch(guildCommandId); + await client.application?.commands.create(slashCommandBuilder); + await client.application?.commands.create(contextMenuCommandBuilder); + await guild.commands.create(slashCommandBuilder); + await guild.commands.create(contextMenuCommandBuilder); + + await client.application?.commands.edit(globalCommandId, slashCommandBuilder); + await client.application?.commands.edit(globalCommandId, contextMenuCommandBuilder); + await guild.commands.edit(guildCommandId, slashCommandBuilder); + await guild.commands.edit(guildCommandId, contextMenuCommandBuilder); + await client.application?.commands.edit(globalCommandId, { defaultMemberPermissions: null }); await globalCommand?.edit({ defaultMemberPermissions: null }); await globalCommand?.setDefaultMemberPermissions(null);