feat: partially backport perms v2 for v13 (#8162)

This commit is contained in:
Almeida
2022-06-23 23:05:11 +01:00
committed by GitHub
parent c198e893c9
commit 125696fc79
4 changed files with 114 additions and 5 deletions

View File

@@ -6,6 +6,7 @@ const CachedManager = require('./CachedManager');
const { TypeError } = require('../errors'); const { TypeError } = require('../errors');
const ApplicationCommand = require('../structures/ApplicationCommand'); const ApplicationCommand = require('../structures/ApplicationCommand');
const { ApplicationCommandTypes } = require('../util/Constants'); const { ApplicationCommandTypes } = require('../util/Constants');
const Permissions = require('../util/Permissions');
/** /**
* Manages API methods for application commands and stores their cache. * Manages API methods for application commands and stores their cache.
@@ -162,7 +163,7 @@ class ApplicationCommandManager extends CachedManager {
/** /**
* Edits an application command. * Edits an application command.
* @param {ApplicationCommandResolvable} command The command to edit * @param {ApplicationCommandResolvable} command The command to edit
* @param {ApplicationCommandData|APIApplicationCommand} data The data to update the command with * @param {Partial<ApplicationCommandData|APIApplicationCommand>} data The data to update the command with
* @param {Snowflake} [guildId] The guild's id where the command registered, * @param {Snowflake} [guildId] The guild's id where the command registered,
* ignored when using a {@link GuildApplicationCommandManager} * ignored when using a {@link GuildApplicationCommandManager}
* @returns {Promise<ApplicationCommand>} * @returns {Promise<ApplicationCommand>}
@@ -214,6 +215,20 @@ class ApplicationCommandManager extends CachedManager {
* @private * @private
*/ */
static transformCommand(command) { static transformCommand(command) {
let default_member_permissions;
if ('default_member_permissions' in command) {
default_member_permissions = command.default_member_permissions
? new Permissions(BigInt(command.default_member_permissions)).bitfield.toString()
: command.default_member_permissions;
}
if ('defaultMemberPermissions' in command) {
default_member_permissions = command.defaultMemberPermissions
? new Permissions(command.defaultMemberPermissions).bitfield.toString()
: command.defaultMemberPermissions;
}
return { return {
name: command.name, name: command.name,
name_localizations: command.nameLocalizations ?? command.name_localizations, name_localizations: command.nameLocalizations ?? command.name_localizations,
@@ -222,6 +237,8 @@ class ApplicationCommandManager extends CachedManager {
type: typeof command.type === 'number' ? command.type : ApplicationCommandTypes[command.type], type: typeof command.type === 'number' ? command.type : ApplicationCommandTypes[command.type],
options: command.options?.map(o => ApplicationCommand.transformOption(o)), options: command.options?.map(o => ApplicationCommand.transformOption(o)),
default_permission: command.defaultPermission ?? command.default_permission, default_permission: command.defaultPermission ?? command.default_permission,
default_member_permissions,
dm_permission: command.dmPermission ?? command.dm_permission,
}; };
} }
} }

View File

@@ -3,6 +3,7 @@
const Base = require('./Base'); const Base = require('./Base');
const ApplicationCommandPermissionsManager = require('../managers/ApplicationCommandPermissionsManager'); const ApplicationCommandPermissionsManager = require('../managers/ApplicationCommandPermissionsManager');
const { ApplicationCommandOptionTypes, ApplicationCommandTypes, ChannelTypes } = require('../util/Constants'); const { ApplicationCommandOptionTypes, ApplicationCommandTypes, ChannelTypes } = require('../util/Constants');
const Permissions = require('../util/Permissions');
const SnowflakeUtil = require('../util/SnowflakeUtil'); const SnowflakeUtil = require('../util/SnowflakeUtil');
/** /**
@@ -120,13 +121,39 @@ class ApplicationCommand extends Base {
this.options ??= []; this.options ??= [];
} }
/* eslint-disable max-len */
if ('default_permission' in data) { if ('default_permission' in data) {
/** /**
* Whether the command is enabled by default when the app is added to a guild * Whether the command is enabled by default when the app is added to a guild
* @type {boolean} * @type {boolean}
* @deprecated Use {@link ApplicationCommand.defaultMemberPermissions} and {@link ApplicationCommand.dmPermission} instead.
*/ */
this.defaultPermission = data.default_permission; this.defaultPermission = data.default_permission;
} }
/* eslint-disable max-len */
if ('default_member_permissions' in data) {
/**
* The default bitfield used to determine whether this command be used in a guild
* @type {?Readonly<Permissions>}
*/
this.defaultMemberPermissions = data.default_member_permissions
? new Permissions(BigInt(data.default_member_permissions)).freeze()
: null;
} else {
this.defaultMemberPermissions ??= null;
}
if ('dm_permission' in data) {
/**
* Whether the command can be used in DMs
* <info>This property is always `null` on guild commands</info>
* @type {?boolean}
*/
this.dmPermission = data.dm_permission;
} else {
this.dmPermission ??= null;
}
if ('version' in data) { if ('version' in data) {
/** /**
@@ -174,6 +201,9 @@ class ApplicationCommand extends Base {
* @property {ApplicationCommandType} [type] The type of the command * @property {ApplicationCommandType} [type] The type of the command
* @property {ApplicationCommandOptionData[]} [options] Options for the command * @property {ApplicationCommandOptionData[]} [options] Options for the command
* @property {boolean} [defaultPermission] Whether the command is enabled by default when the app is added to a guild * @property {boolean} [defaultPermission] Whether the command is enabled by default when the app is added to a guild
* @property {?PermissionResolvable} [defaultMemberPermissions] The bitfield used to determine the default permissions
* a member needs in order to run the command
* @property {boolean} [dmPermission] Whether the command is enabled in DMs
*/ */
/** /**
@@ -207,7 +237,7 @@ class ApplicationCommand extends Base {
/** /**
* Edits this application command. * Edits this application command.
* @param {ApplicationCommandData} data The data to update the command with * @param {Partial<ApplicationCommandData>} data The data to update the command with
* @returns {Promise<ApplicationCommand>} * @returns {Promise<ApplicationCommand>}
* @example * @example
* // Edit the description of this command * // Edit the description of this command
@@ -273,14 +303,35 @@ class ApplicationCommand extends Base {
return this.edit({ descriptionLocalizations }); return this.edit({ descriptionLocalizations });
} }
/* eslint-disable max-len */
/** /**
* Edits the default permission of this ApplicationCommand * Edits the default permission of this ApplicationCommand
* @param {boolean} [defaultPermission=true] The default permission for this command * @param {boolean} [defaultPermission=true] The default permission for this command
* @returns {Promise<ApplicationCommand>} * @returns {Promise<ApplicationCommand>}
* @deprecated Use {@link ApplicationCommand#setDefaultMemberPermissions} and {@link ApplicationCommand#setDMPermission} instead.
*/ */
setDefaultPermission(defaultPermission = true) { setDefaultPermission(defaultPermission = true) {
return this.edit({ defaultPermission }); return this.edit({ defaultPermission });
} }
/* eslint-enable max-len */
/**
* Edits the default member permissions of this ApplicationCommand
* @param {?PermissionResolvable} defaultMemberPermissions The default member permissions required to run this command
* @returns {Promise<ApplicationCommand>}
*/
setDefaultMemberPermissions(defaultMemberPermissions) {
return this.edit({ defaultMemberPermissions });
}
/**
* Edits the DM permission of this ApplicationCommand
* @param {boolean} [dmPermission=true] Whether the command can be used in DMs
* @returns {Promise<ApplicationCommand>}
*/
setDMPermission(dmPermission = true) {
return this.edit({ dmPermission });
}
/** /**
* Edits the options of this ApplicationCommand * Edits the options of this ApplicationCommand
@@ -317,6 +368,21 @@ class ApplicationCommand extends Base {
// If given an id, check if the id matches // If given an id, check if the id matches
if (command.id && this.id !== command.id) return false; if (command.id && this.id !== command.id) return false;
let defaultMemberPermissions = null;
let dmPermission = command.dmPermission ?? command.dm_permission;
if ('default_member_permissions' in command) {
defaultMemberPermissions = command.default_member_permissions
? new Permissions(BigInt(command.default_member_permissions)).bitfield
: null;
}
if ('defaultMemberPermissions' in command) {
defaultMemberPermissions = command.defaultMemberPermissions
? new Permissions(command.defaultMemberPermissions).bitfield
: null;
}
// Check top level parameters // Check top level parameters
const commandType = typeof command.type === 'string' ? command.type : ApplicationCommandTypes[command.type]; const commandType = typeof command.type === 'string' ? command.type : ApplicationCommandTypes[command.type];
if ( if (
@@ -325,6 +391,8 @@ class ApplicationCommand extends Base {
('version' in command && command.version !== this.version) || ('version' in command && command.version !== this.version) ||
('autocomplete' in command && command.autocomplete !== this.autocomplete) || ('autocomplete' in command && command.autocomplete !== this.autocomplete) ||
(commandType && commandType !== this.type) || (commandType && commandType !== this.type) ||
defaultMemberPermissions !== (this.defaultMemberPermissions?.bitfield ?? null) ||
(typeof dmPermission !== 'undefined' && dmPermission !== this.dmPermission) ||
// Future proof for options being nullable // Future proof for options being nullable
// TODO: remove ?? 0 on each when nullable // TODO: remove ?? 0 on each when nullable
(command.options?.length ?? 0) !== (this.options?.length ?? 0) || (command.options?.length ?? 0) !== (this.options?.length ?? 0) ||

17
typings/index.d.ts vendored
View File

@@ -223,10 +223,13 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
public applicationId: Snowflake; public applicationId: Snowflake;
public readonly createdAt: Date; public readonly createdAt: Date;
public readonly createdTimestamp: number; public readonly createdTimestamp: number;
/** @deprecated Use {@link defaultMemberPermissions} and {@link dmPermission} instead. */
public defaultPermission: boolean; public defaultPermission: boolean;
public defaultMemberPermissions: Readonly<Permissions> | null;
public description: string; public description: string;
public descriptionLocalizations: LocalizationMap | null; public descriptionLocalizations: LocalizationMap | null;
public descriptionLocalized: string | null; public descriptionLocalized: string | null;
public dmPermission: boolean | null;
public guild: Guild | null; public guild: Guild | null;
public guildId: Snowflake | null; public guildId: Snowflake | null;
public readonly manager: ApplicationCommandManager; public readonly manager: ApplicationCommandManager;
@@ -245,14 +248,19 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
public type: ApplicationCommandType; public type: ApplicationCommandType;
public version: Snowflake; public version: Snowflake;
public delete(): Promise<ApplicationCommand<PermissionsFetchType>>; public delete(): Promise<ApplicationCommand<PermissionsFetchType>>;
public edit(data: ApplicationCommandData): Promise<ApplicationCommand<PermissionsFetchType>>; public edit(data: Partial<ApplicationCommandData>): Promise<ApplicationCommand<PermissionsFetchType>>;
public setName(name: string): Promise<ApplicationCommand<PermissionsFetchType>>; public setName(name: string): Promise<ApplicationCommand<PermissionsFetchType>>;
public setNameLocalizations(nameLocalizations: LocalizationMap): Promise<ApplicationCommand<PermissionsFetchType>>; public setNameLocalizations(nameLocalizations: LocalizationMap): Promise<ApplicationCommand<PermissionsFetchType>>;
public setDescription(description: string): Promise<ApplicationCommand<PermissionsFetchType>>; public setDescription(description: string): Promise<ApplicationCommand<PermissionsFetchType>>;
public setDescriptionLocalizations( public setDescriptionLocalizations(
descriptionLocalizations: LocalizationMap, descriptionLocalizations: LocalizationMap,
): Promise<ApplicationCommand<PermissionsFetchType>>; ): Promise<ApplicationCommand<PermissionsFetchType>>;
/** @deprecated Use {@link setDefaultMemberPermissions} and {@link setDMPermission} instead. */
public setDefaultPermission(defaultPermission?: boolean): Promise<ApplicationCommand<PermissionsFetchType>>; public setDefaultPermission(defaultPermission?: boolean): Promise<ApplicationCommand<PermissionsFetchType>>;
public setDefaultMemberPermissions(
defaultMemberPermissions: PermissionResolvable | null,
): Promise<ApplicationCommand<PermissionsFetchType>>;
public setDMPermission(dmPermission?: boolean): Promise<ApplicationCommand<PermissionsFetchType>>;
public setOptions(options: ApplicationCommandOptionData[]): Promise<ApplicationCommand<PermissionsFetchType>>; public setOptions(options: ApplicationCommandOptionData[]): Promise<ApplicationCommand<PermissionsFetchType>>;
public equals( public equals(
command: ApplicationCommand | ApplicationCommandData | RawApplicationCommandData, command: ApplicationCommand | ApplicationCommandData | RawApplicationCommandData,
@@ -3074,11 +3082,11 @@ export class ApplicationCommandManager<
public delete(command: ApplicationCommandResolvable, guildId?: Snowflake): Promise<ApplicationCommandScope | null>; public delete(command: ApplicationCommandResolvable, guildId?: Snowflake): Promise<ApplicationCommandScope | null>;
public edit( public edit(
command: ApplicationCommandResolvable, command: ApplicationCommandResolvable,
data: ApplicationCommandDataResolvable, data: Partial<ApplicationCommandDataResolvable>,
): Promise<ApplicationCommandScope>; ): Promise<ApplicationCommandScope>;
public edit( public edit(
command: ApplicationCommandResolvable, command: ApplicationCommandResolvable,
data: ApplicationCommandDataResolvable, data: Partial<ApplicationCommandDataResolvable>,
guildId: Snowflake, guildId: Snowflake,
): Promise<ApplicationCommand>; ): Promise<ApplicationCommand>;
public fetch( public fetch(
@@ -3771,7 +3779,10 @@ export interface ApplicationAsset {
export interface BaseApplicationCommandData { export interface BaseApplicationCommandData {
name: string; name: string;
nameLocalizations?: LocalizationMap; nameLocalizations?: LocalizationMap;
/** @deprecated Use {@link defaultMemberPermissions} and {@link dmPermission} instead. */
defaultPermission?: boolean; defaultPermission?: boolean;
defaultMemberPermissions?: PermissionResolvable | null;
dmPermission?: boolean;
} }
export type CommandOptionDataTypeResolvable = ApplicationCommandOptionType | ApplicationCommandOptionTypes; export type CommandOptionDataTypeResolvable = ApplicationCommandOptionType | ApplicationCommandOptionTypes;

View File

@@ -143,6 +143,11 @@ client.on('ready', async () => {
const guildCommandFromGlobal = await client.application?.commands.fetch(guildCommandId, { guildId: testGuildId }); const guildCommandFromGlobal = await client.application?.commands.fetch(guildCommandId, { guildId: testGuildId });
const guildCommandFromGuild = await client.guilds.cache.get(testGuildId)?.commands.fetch(guildCommandId); const guildCommandFromGuild = await client.guilds.cache.get(testGuildId)?.commands.fetch(guildCommandId);
await client.application?.commands.edit(globalCommandId, { defaultMemberPermissions: null });
await globalCommand?.edit({ defaultMemberPermissions: null });
await globalCommand?.setDefaultMemberPermissions(null);
await guildCommandFromGlobal?.edit({ dmPermission: false });
// @ts-expect-error // @ts-expect-error
await client.guilds.cache.get(testGuildId)?.commands.fetch(guildCommandId, { guildId: testGuildId }); await client.guilds.cache.get(testGuildId)?.commands.fetch(guildCommandId, { guildId: testGuildId });
@@ -831,6 +836,14 @@ declare const applicationCommandManager: ApplicationCommandManager;
expectType<Promise<Collection<Snowflake, ApplicationCommand>>>( expectType<Promise<Collection<Snowflake, ApplicationCommand>>>(
applicationCommandManager.set([applicationCommandData], '0'), applicationCommandManager.set([applicationCommandData], '0'),
); );
applicationCommandManager.create({
name: 'yeet',
description: 'abc',
defaultMemberPermissions: 1n,
dmPermission: false,
type: 'CHAT_INPUT',
});
} }
declare const applicationNonChoiceOptionData: ApplicationCommandOptionData & { declare const applicationNonChoiceOptionData: ApplicationCommandOptionData & {