From 7a5134459c5f06864bf74631d83b96d9c21b72d8 Mon Sep 17 00:00:00 2001 From: Suneet Tipirneni <77477100+suneettipirneni@users.noreply.github.com> Date: Thu, 15 Dec 2022 21:04:56 -0500 Subject: [PATCH] feat: add support for nsfw commands (#7976) * chore: update * fix: add edit changes * chore: make requested changes Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../interactions/slashCommands/Assertions.ts | 4 ++++ .../slashCommands/SlashCommandBuilder.ts | 18 ++++++++++++++++++ .../src/managers/ApplicationCommandManager.js | 1 + .../src/structures/ApplicationCommand.js | 8 ++++++++ packages/discord.js/typings/index.d.ts | 2 ++ 5 files changed, 33 insertions(+) diff --git a/packages/builders/src/interactions/slashCommands/Assertions.ts b/packages/builders/src/interactions/slashCommands/Assertions.ts index 586f968a1..d61da838f 100644 --- a/packages/builders/src/interactions/slashCommands/Assertions.ts +++ b/packages/builders/src/interactions/slashCommands/Assertions.ts @@ -94,3 +94,7 @@ const memberPermissionPredicate = s.union( export function validateDefaultMemberPermissions(permissions: unknown) { return memberPermissionPredicate.parse(permissions); } + +export function validateNSFW(value: unknown): asserts value is boolean { + booleanPredicate.parse(value); +} diff --git a/packages/builders/src/interactions/slashCommands/SlashCommandBuilder.ts b/packages/builders/src/interactions/slashCommands/SlashCommandBuilder.ts index 8bdb6c49e..56e207f47 100644 --- a/packages/builders/src/interactions/slashCommands/SlashCommandBuilder.ts +++ b/packages/builders/src/interactions/slashCommands/SlashCommandBuilder.ts @@ -13,6 +13,7 @@ import { validateDMPermission, validateMaxOptionsLength, validateRequiredParameters, + validateNSFW, } from './Assertions.js'; import { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder } from './SlashCommandSubcommands.js'; import { SharedNameAndDescription } from './mixins/NameAndDescription.js'; @@ -64,6 +65,11 @@ export class SlashCommandBuilder { */ public readonly dm_permission: boolean | undefined = undefined; + /** + * Whether this command is NSFW + */ + public readonly nsfw: boolean | undefined = undefined; + /** * Returns the final data that should be sent to Discord. * @@ -134,6 +140,18 @@ export class SlashCommandBuilder { return this; } + /** + * Sets whether this command is NSFW + * + * @param nsfw - Whether this command is NSFW + */ + public setNSFW(nsfw = true) { + // Assert the value matches the conditions + validateNSFW(nsfw); + Reflect.set(this, 'nsfw', nsfw); + return this; + } + /** * Adds a new subcommand group to this command * diff --git a/packages/discord.js/src/managers/ApplicationCommandManager.js b/packages/discord.js/src/managers/ApplicationCommandManager.js index 2e9e2d8f6..7d08dc916 100644 --- a/packages/discord.js/src/managers/ApplicationCommandManager.js +++ b/packages/discord.js/src/managers/ApplicationCommandManager.js @@ -252,6 +252,7 @@ class ApplicationCommandManager extends CachedManager { name: command.name, name_localizations: command.nameLocalizations ?? command.name_localizations, description: command.description, + nsfw: command.nsfw, description_localizations: command.descriptionLocalizations ?? command.description_localizations, type: command.type, options: command.options?.map(o => ApplicationCommand.transformOption(o)), diff --git a/packages/discord.js/src/structures/ApplicationCommand.js b/packages/discord.js/src/structures/ApplicationCommand.js index afdddaca9..64374f153 100644 --- a/packages/discord.js/src/structures/ApplicationCommand.js +++ b/packages/discord.js/src/structures/ApplicationCommand.js @@ -52,6 +52,12 @@ class ApplicationCommand extends Base { */ this.type = data.type; + /** + * Whether this command is age-restricted (18+) + * @type {boolean} + */ + this.nsfw = data.nsfw ?? false; + this._patch(data); } @@ -188,6 +194,7 @@ class ApplicationCommand extends Base { * {@link ApplicationCommandType.ChatInput} * @property {Object} [nameLocalizations] The localizations for the command name * @property {string} description The description of the command, if type is {@link ApplicationCommandType.ChatInput} + * @property {boolean} [nsfw] Whether the command is age-restricted * @property {Object} [descriptionLocalizations] The localizations for the command description, * if type is {@link ApplicationCommandType.ChatInput} * @property {ApplicationCommandType} [type=ApplicationCommandType.ChatInput] The type of the command @@ -377,6 +384,7 @@ class ApplicationCommand extends Base { ('description' in command && command.description !== this.description) || ('version' in command && command.version !== this.version) || (command.type && command.type !== this.type) || + ('nsfw' in command && command.nsfw !== this.nsfw) || // Future proof for options being nullable // TODO: remove ?? 0 on each when nullable (command.options?.length ?? 0) !== (this.options?.length ?? 0) || diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index d0a5ed97e..5040d88f0 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -419,6 +419,7 @@ export class ApplicationCommand extends Base { >; public type: ApplicationCommandType; public version: Snowflake; + public nsfw: boolean; public delete(): Promise>; public edit(data: Partial): Promise>; public setName(name: string): Promise>; @@ -4169,6 +4170,7 @@ export interface BaseApplicationCommandData { nameLocalizations?: LocalizationMap; dmPermission?: boolean; defaultMemberPermissions?: PermissionResolvable | null; + nsfw?: boolean; } export interface AttachmentData {