refactor(ApplicationCommand): permissions v2 (#7857)

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
This commit is contained in:
ckohen
2022-06-10 12:34:17 -07:00
committed by GitHub
parent c5176be14b
commit c7391db11b
13 changed files with 628 additions and 334 deletions

View File

@@ -4,6 +4,7 @@ class ActionsManager {
constructor(client) {
this.client = client;
this.register(require('./ApplicationCommandPermissionsUpdate'));
this.register(require('./ChannelCreate'));
this.register(require('./ChannelDelete'));
this.register(require('./ChannelUpdate'));

View File

@@ -0,0 +1,34 @@
'use strict';
const Action = require('./Action');
const Events = require('../../util/Events');
/**
* The data received in the {@link Client#event:applicationCommandPermissionsUpdate} event
* @typedef {Object} ApplicationCommandPermissionsUpdateData
* @property {Snowflake} id The id of the command or global entity that was updated
* @property {Snowflake} guildId The id of the guild in which permissions were updated
* @property {Snowflake} applicationId The id of the application that owns the command or entity being updated
* @property {ApplicationCommandPermissions} permissions The updated permissions
*/
class ApplicationCommandPermissionsUpdateAction extends Action {
handle(data) {
const client = this.client;
/**
* Emitted whenever permissions for an application command in a guild were updated.
* <warn>This includes permission updates for other applications in addition to the logged in client,
* check `data.applicationId` to verify which application the update is for</warn>
* @event Client#applicationCommandPermissionsUpdate
* @param {ApplicationCommandPermissionsUpdateData} data The updated permissions
*/
client.emit(Events.ApplicationCommandPermissionsUpdate, {
permissions: data.permissions,
id: data.id,
guildId: data.guild_id,
applicationId: data.application_id,
});
}
}
module.exports = ApplicationCommandPermissionsUpdateAction;

View File

@@ -0,0 +1,5 @@
'use strict';
module.exports = (client, packet) => {
client.actions.ApplicationCommandPermissionsUpdate.handle(packet.d);
};

View File

@@ -1,53 +1,57 @@
'use strict';
const handlers = Object.fromEntries([
['READY', require('./READY')],
['RESUMED', require('./RESUMED')],
['APPLICATION_COMMAND_PERMISSIONS_UPDATE', require('./APPLICATION_COMMAND_PERMISSIONS_UPDATE')],
['CHANNEL_CREATE', require('./CHANNEL_CREATE')],
['CHANNEL_DELETE', require('./CHANNEL_DELETE')],
['CHANNEL_PINS_UPDATE', require('./CHANNEL_PINS_UPDATE')],
['CHANNEL_UPDATE', require('./CHANNEL_UPDATE')],
['GUILD_BAN_ADD', require('./GUILD_BAN_ADD')],
['GUILD_BAN_REMOVE', require('./GUILD_BAN_REMOVE')],
['GUILD_CREATE', require('./GUILD_CREATE')],
['GUILD_DELETE', require('./GUILD_DELETE')],
['GUILD_UPDATE', require('./GUILD_UPDATE')],
['INVITE_CREATE', require('./INVITE_CREATE')],
['INVITE_DELETE', require('./INVITE_DELETE')],
['GUILD_EMOJIS_UPDATE', require('./GUILD_EMOJIS_UPDATE')],
['GUILD_INTEGRATIONS_UPDATE', require('./GUILD_INTEGRATIONS_UPDATE')],
['GUILD_MEMBER_ADD', require('./GUILD_MEMBER_ADD')],
['GUILD_MEMBER_REMOVE', require('./GUILD_MEMBER_REMOVE')],
['GUILD_MEMBER_UPDATE', require('./GUILD_MEMBER_UPDATE')],
['GUILD_MEMBERS_CHUNK', require('./GUILD_MEMBERS_CHUNK')],
['GUILD_INTEGRATIONS_UPDATE', require('./GUILD_INTEGRATIONS_UPDATE')],
['GUILD_MEMBER_UPDATE', require('./GUILD_MEMBER_UPDATE')],
['GUILD_ROLE_CREATE', require('./GUILD_ROLE_CREATE')],
['GUILD_ROLE_DELETE', require('./GUILD_ROLE_DELETE')],
['GUILD_ROLE_UPDATE', require('./GUILD_ROLE_UPDATE')],
['GUILD_BAN_ADD', require('./GUILD_BAN_ADD')],
['GUILD_BAN_REMOVE', require('./GUILD_BAN_REMOVE')],
['GUILD_EMOJIS_UPDATE', require('./GUILD_EMOJIS_UPDATE')],
['CHANNEL_CREATE', require('./CHANNEL_CREATE')],
['CHANNEL_DELETE', require('./CHANNEL_DELETE')],
['CHANNEL_UPDATE', require('./CHANNEL_UPDATE')],
['CHANNEL_PINS_UPDATE', require('./CHANNEL_PINS_UPDATE')],
['GUILD_STICKERS_UPDATE', require('./GUILD_STICKERS_UPDATE')],
['GUILD_UPDATE', require('./GUILD_UPDATE')],
['INTEGRATION_CREATE', require('./INTEGRATION_CREATE')],
['INTEGRATION_DELETE', require('./INTEGRATION_DELETE')],
['INTEGRATION_UPDATE', require('./INTEGRATION_UPDATE')],
['INTERACTION_CREATE', require('./INTERACTION_CREATE')],
['INVITE_CREATE', require('./INVITE_CREATE')],
['INVITE_DELETE', require('./INVITE_DELETE')],
['MESSAGE_CREATE', require('./MESSAGE_CREATE')],
['MESSAGE_DELETE', require('./MESSAGE_DELETE')],
['MESSAGE_UPDATE', require('./MESSAGE_UPDATE')],
['MESSAGE_DELETE_BULK', require('./MESSAGE_DELETE_BULK')],
['MESSAGE_REACTION_ADD', require('./MESSAGE_REACTION_ADD')],
['MESSAGE_REACTION_REMOVE', require('./MESSAGE_REACTION_REMOVE')],
['MESSAGE_REACTION_REMOVE_ALL', require('./MESSAGE_REACTION_REMOVE_ALL')],
['MESSAGE_REACTION_REMOVE_EMOJI', require('./MESSAGE_REACTION_REMOVE_EMOJI')],
['MESSAGE_UPDATE', require('./MESSAGE_UPDATE')],
['PRESENCE_UPDATE', require('./PRESENCE_UPDATE')],
['STAGE_INSTANCE_CREATE', require('./STAGE_INSTANCE_CREATE')],
['STAGE_INSTANCE_DELETE', require('./STAGE_INSTANCE_DELETE')],
['STAGE_INSTANCE_UPDATE', require('./STAGE_INSTANCE_UPDATE')],
['READY', require('./READY')],
['RESUMED', require('./RESUMED')],
['THREAD_CREATE', require('./THREAD_CREATE')],
['THREAD_UPDATE', require('./THREAD_UPDATE')],
['THREAD_DELETE', require('./THREAD_DELETE')],
['THREAD_LIST_SYNC', require('./THREAD_LIST_SYNC')],
['THREAD_MEMBER_UPDATE', require('./THREAD_MEMBER_UPDATE')],
['THREAD_MEMBERS_UPDATE', require('./THREAD_MEMBERS_UPDATE')],
['USER_UPDATE', require('./USER_UPDATE')],
['PRESENCE_UPDATE', require('./PRESENCE_UPDATE')],
['THREAD_MEMBER_UPDATE', require('./THREAD_MEMBER_UPDATE')],
['THREAD_UPDATE', require('./THREAD_UPDATE')],
['TYPING_START', require('./TYPING_START')],
['VOICE_STATE_UPDATE', require('./VOICE_STATE_UPDATE')],
['USER_UPDATE', require('./USER_UPDATE')],
['VOICE_SERVER_UPDATE', require('./VOICE_SERVER_UPDATE')],
['VOICE_STATE_UPDATE', require('./VOICE_STATE_UPDATE')],
['WEBHOOKS_UPDATE', require('./WEBHOOKS_UPDATE')],
['INTERACTION_CREATE', require('./INTERACTION_CREATE')],
['STAGE_INSTANCE_CREATE', require('./STAGE_INSTANCE_CREATE')],
['STAGE_INSTANCE_UPDATE', require('./STAGE_INSTANCE_UPDATE')],
['STAGE_INSTANCE_DELETE', require('./STAGE_INSTANCE_DELETE')],
['GUILD_STICKERS_UPDATE', require('./GUILD_STICKERS_UPDATE')],
['GUILD_SCHEDULED_EVENT_CREATE', require('./GUILD_SCHEDULED_EVENT_CREATE')],
['GUILD_SCHEDULED_EVENT_UPDATE', require('./GUILD_SCHEDULED_EVENT_UPDATE')],
['GUILD_SCHEDULED_EVENT_DELETE', require('./GUILD_SCHEDULED_EVENT_DELETE')],

View File

@@ -10,6 +10,8 @@ const Messages = {
TOKEN_INVALID: 'An invalid token was provided.',
TOKEN_MISSING: 'Request to use token, but token was unavailable to the client.',
APPLICATION_COMMAND_PERMISSIONS_TOKEN_MISSING:
'Editing application command permissions requires an OAuth2 bearer token, but none was provided.',
WS_CLOSE_REQUESTED: 'WebSocket closed due to user request.',
WS_CONNECTION_EXISTS: 'There is already an existing WebSocket connection.',
@@ -127,7 +129,7 @@ const Messages = {
GLOBAL_COMMAND_PERMISSIONS:
'Permissions for global commands may only be fetched or modified by providing a GuildResolvable ' +
"or from a guild's application command manager.",
GUILD_UNCACHED_ROLE_RESOLVE: 'Cannot resolve roles from an arbitrary guild, provide an id instead',
GUILD_UNCACHED_ENTITY_RESOLVE: type => `Cannot resolve ${type} from an arbitrary guild, provide an id instead`,
INTERACTION_ALREADY_REPLIED: 'The reply to this interaction has already been sent or deferred.',
INTERACTION_NOT_REPLIED: 'The reply to this interaction has not been sent or deferred.',

View File

@@ -6,6 +6,7 @@ const ApplicationCommandPermissionsManager = require('./ApplicationCommandPermis
const CachedManager = require('./CachedManager');
const { TypeError } = require('../errors');
const ApplicationCommand = require('../structures/ApplicationCommand');
const PermissionsBitField = require('../util/PermissionsBitField');
/**
* Manages API methods for application commands and stores their cache.
@@ -224,6 +225,20 @@ class ApplicationCommandManager extends CachedManager {
* @private
*/
static transformCommand(command) {
let default_member_permissions;
if ('default_member_permissions' in command) {
default_member_permissions = command.default_member_permissions
? new PermissionsBitField(BigInt(command.default_member_permissions)).bitfield
: command.default_member_permissions;
}
if ('defaultMemberPermissions' in command) {
default_member_permissions = command.defaultMemberPermissions
? new PermissionsBitField(command.defaultMemberPermissions).bitfield
: command.defaultMemberPermissions;
}
return {
name: command.name,
name_localizations: command.nameLocalizations ?? command.name_localizations,
@@ -231,7 +246,8 @@ class ApplicationCommandManager extends CachedManager {
description_localizations: command.descriptionLocalizations ?? command.description_localizations,
type: command.type,
options: command.options?.map(o => ApplicationCommand.transformOption(o)),
default_permission: command.defaultPermission ?? command.default_permission,
default_member_permissions,
dm_permission: command.dmPermission ?? command.dm_permission,
};
}
}

View File

@@ -1,7 +1,7 @@
'use strict';
const { Collection } = require('@discordjs/collection');
const { RESTJSONErrorCodes, Routes } = require('discord-api-types/v10');
const { ApplicationCommandPermissionType, RESTJSONErrorCodes, Routes } = require('discord-api-types/v10');
const BaseManager = require('./BaseManager');
const { Error, TypeError } = require('../errors');
@@ -54,21 +54,16 @@ class ApplicationCommandPermissionsManager extends BaseManager {
return Routes.guildApplicationCommandsPermissions(this.client.application.id, guildId);
}
/**
* Data for setting the permissions of an application command.
* @typedef {Object} ApplicationCommandPermissionData
* @property {Snowflake} id The role or user's id
* @property {ApplicationCommandPermissionType|number} type Whether this permission is for a role or a user
* @property {boolean} permission Whether the role or user has the permission to use this command
*/
/* eslint-disable max-len */
/**
* The object returned when fetching permissions for an application command.
* @typedef {Object} ApplicationCommandPermissions
* @property {Snowflake} id The role or user's id
* @property {Snowflake} id The role, user, or channel's id. Can also be a
* {@link https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permissions-constants permission constant}.
* @property {ApplicationCommandPermissionType} type Whether this permission is for a role or a user
* @property {boolean} permission Whether the role or user has the permission to use this command
*/
/* eslint-enable max-len */
/**
* Options for managing permissions for one or more Application Commands
@@ -82,19 +77,25 @@ class ApplicationCommandPermissionsManager extends BaseManager {
*/
/**
* Fetches the permissions for one or multiple commands.
* Fetches the permissions for one or multiple commands. Providing the client's id as the "command id" will fetch
* *only* the guild level permissions
* @param {BaseApplicationCommandPermissionsOptions} [options] Options used to fetch permissions
* @returns {Promise<ApplicationCommandPermissions[]|Collection<Snowflake, ApplicationCommandPermissions[]>>}
* @example
* // Fetch permissions for one command
* guild.commands.permissions.fetch({ command: '123456789012345678' })
* .then(perms => console.log(`Fetched permissions for ${perms.length} users`))
* .then(perms => console.log(`Fetched ${perms.length} overwrites`))
* .catch(console.error);
* @example
* // Fetch permissions for all commands in a guild
* client.application.commands.permissions.fetch({ guild: '123456789012345678' })
* .then(perms => console.log(`Fetched permissions for ${perms.size} commands`))
* .catch(console.error);
* @example
* // Fetch guild level permissions
* guild.commands.permissions.fetch({ command: client.user.id })
* .then(perms => console.log(`Fetched ${perms.length} guild level permissions`))
* .catch(console.error);
*/
async fetch({ guild, command } = {}) {
const { guildId, commandId } = this._validateOptions(guild, command);
@@ -107,47 +108,42 @@ class ApplicationCommandPermissionsManager extends BaseManager {
return data.reduce((coll, perm) => coll.set(perm.id, perm.permissions), new Collection());
}
/**
* Data used for overwriting the permissions for all application commands in a guild.
* @typedef {Object} GuildApplicationCommandPermissionData
* @property {Snowflake} id The command's id
* @property {ApplicationCommandPermissionData[]} permissions The permissions for this command
*/
/**
* Options used to set permissions for one or more Application Commands in a guild
* <warn>One of `command` AND `permissions`, OR `fullPermissions` is required.
* `fullPermissions` is not a valid option when passing to a manager where `commandId` is non-null</warn>
* @typedef {BaseApplicationCommandPermissionsOptions} SetApplicationCommandPermissionsOptions
* @property {ApplicationCommandPermissionData[]} [permissions] The new permissions for the command
* @property {GuildApplicationCommandPermissionData[]} [fullPermissions] The new permissions for all commands
* in a guild <warn>When this parameter is set, `permissions` and `command` are ignored</warn>
* <warn>Omitting the `command` parameter edits the guild wide permissions
* when the manager's `commandId` is `null`</warn>
* @typedef {BaseApplicationCommandPermissionsOptions} EditApplicationCommandPermissionsOptions
* @property {ApplicationCommandPermissions[]} permissions The new permissions for the guild or overwrite
* @property {string} token The bearer token to use that authorizes the permission edit
*/
/**
* Sets the permissions for one or more commands.
* @param {SetApplicationCommandPermissionsOptions} options Options used to set permissions
* Sets the permissions for the guild or a command overwrite.
* @param {EditApplicationCommandPermissionsOptions} options Options used to set permissions
* @returns {Promise<ApplicationCommandPermissions[]|Collection<Snowflake, ApplicationCommandPermissions[]>>}
* @example
* // Set the permissions for one command
* client.application.commands.permissions.set({ guild: '892455839386304532', command: '123456789012345678',
* // Set a permission overwrite for a command
* client.application.commands.permissions.set({
* guild: '892455839386304532',
* command: '123456789012345678',
* token: 'TotallyRealToken',
* permissions: [
* {
* id: '876543210987654321',
* type: ApplicationCommandOptionType.User,
* type: ApplicationCommandPermissionType.User,
* permission: false,
* },
* ]})
* .then(console.log)
* .catch(console.error);
* @example
* // Set the permissions for all commands
* guild.commands.permissions.set({ fullPermissions: [
* // Set the permissions used for the guild (commands without overwrites)
* guild.commands.permissions.set({ token: 'TotallyRealToken', permissions: [
* {
* id: '123456789012345678',
* permissions: [{
* id: '876543210987654321',
* type: ApplicationCommandOptionType.User,
* type: ApplicationCommandPermissionType.User,
* permission: false,
* }],
* },
@@ -155,39 +151,34 @@ class ApplicationCommandPermissionsManager extends BaseManager {
* .then(console.log)
* .catch(console.error);
*/
async set({ guild, command, permissions, fullPermissions } = {}) {
const { guildId, commandId } = this._validateOptions(guild, command);
async set({ guild, command, permissions, token } = {}) {
if (!token) {
throw new Error('APPLICATION_COMMAND_PERMISSIONS_TOKEN_MISSING');
}
let { guildId, commandId } = this._validateOptions(guild, command);
if (commandId) {
if (!Array.isArray(permissions)) {
throw new TypeError('INVALID_TYPE', 'permissions', 'Array of ApplicationCommandPermissionData', true);
}
const data = await this.client.rest.put(this.permissionsPath(guildId, commandId), { body: { permissions } });
return data.permissions;
if (!Array.isArray(permissions)) {
throw new TypeError('INVALID_TYPE', 'permissions', 'Array of ApplicationCommandPermissions', true);
}
if (!Array.isArray(fullPermissions)) {
throw new TypeError('INVALID_TYPE', 'fullPermissions', 'Array of GuildApplicationCommandPermissionData', true);
if (!commandId) {
commandId = this.client.user.id;
}
const data = await this.client.rest.put(this.permissionsPath(guildId), { body: fullPermissions });
return data.reduce((coll, perm) => coll.set(perm.id, perm.permissions), new Collection());
const data = await this.client.rest.put(this.permissionsPath(guildId, commandId), {
body: { permissions },
auth: false,
headers: { Authorization: `Bearer ${token}` },
});
return data.permissions;
}
/**
* Options used to add permissions to a command
* <warn>The `command` parameter is not optional when the managers `commandId` is `null`</warn>
* @typedef {BaseApplicationCommandPermissionsOptions} AddApplicationCommandPermissionsOptions
* @property {ApplicationCommandPermissionData[]} permissions The permissions to add to the command
*/
/**
* Add permissions to a command.
* @param {AddApplicationCommandPermissionsOptions} options Options used to add permissions
* @param {EditApplicationCommandPermissionsOptions} options Options used to add permissions
* @returns {Promise<ApplicationCommandPermissions[]>}
* @example
* // Block a role from the command permissions
* guild.commands.permissions.add({ command: '123456789012345678', permissions: [
* // Add a rule to block a role from using a command
* guild.commands.permissions.add({ command: '123456789012345678', token: 'TotallyRealToken', permissions: [
* {
* id: '876543211234567890',
* type: ApplicationCommandPermissionType.Role,
@@ -197,11 +188,16 @@ class ApplicationCommandPermissionsManager extends BaseManager {
* .then(console.log)
* .catch(console.error);
*/
async add({ guild, command, permissions }) {
const { guildId, commandId } = this._validateOptions(guild, command);
if (!commandId) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
async add({ guild, command, permissions, token } = {}) {
if (!token) {
throw new Error('APPLICATION_COMMAND_PERMISSIONS_TOKEN_MISSING');
}
let { guildId, commandId } = this._validateOptions(guild, command);
if (!commandId) {
commandId = this.client.user.id;
}
if (!Array.isArray(permissions)) {
throw new TypeError('INVALID_TYPE', 'permissions', 'Array of ApplicationCommandPermissionData', true);
throw new TypeError('INVALID_TYPE', 'permissions', 'Array of ApplicationCommandPermissions', true);
}
let existing = [];
@@ -218,17 +214,31 @@ class ApplicationCommandPermissionsManager extends BaseManager {
}
}
return this.set({ guild: guildId, command: commandId, permissions: newPermissions });
return this.set({ guild: guildId, command: commandId, permissions: newPermissions, token });
}
/**
* A static snowflake that identifies the everyone role for application command permissions.
* It is the same as the guild id
* @typedef {Snowflake} RolePermissionConstant
*/
/**
* A static snowflake that identifies the "all channels" entity for application command permissions.
* It will be the result of the calculation `guildId - 1`
* @typedef {Snowflake} ChannelPermissionConstant
*/
/**
* Options used to remove permissions from a command
* <warn>The `command` parameter is not optional when the managers `commandId` is `null`</warn>
* <warn>Omitting the `command` parameter removes from the guild wide permissions
* when the managers `commandId` is `null`</warn>
* <warn>At least one of `users`, `roles`, and `channels` is required</warn>
* @typedef {BaseApplicationCommandPermissionsOptions} RemoveApplicationCommandPermissionsOptions
* @property {UserResolvable|UserResolvable[]} [users] The user(s) to remove from the command permissions
* <warn>One of `users` or `roles` is required</warn>
* @property {RoleResolvable|RoleResolvable[]} [roles] The role(s) to remove from the command permissions
* <warn>One of `users` or `roles` is required</warn>
* @property {string} token The bearer token to use that authorizes the permission removal
* @property {UserResolvable[]} [users] The user(s) to remove
* @property {Array<RoleResolvable|RolePermissionConstant>} [roles] The role(s) to remove
* @property {Array<GuildChannelResolvable|ChannelPermissionConstant>} [channels] The channel(s) to remove
*/
/**
@@ -237,59 +247,66 @@ class ApplicationCommandPermissionsManager extends BaseManager {
* @returns {Promise<ApplicationCommandPermissions[]>}
* @example
* // Remove a user permission from this command
* guild.commands.permissions.remove({ command: '123456789012345678', users: '876543210123456789' })
* guild.commands.permissions.remove({
* command: '123456789012345678', users: '876543210123456789', token: 'TotallyRealToken',
* })
* .then(console.log)
* .catch(console.error);
* @example
* // Remove multiple roles from this command
* guild.commands.permissions.remove({
* command: '123456789012345678', roles: ['876543210123456789', '765432101234567890']
* command: '123456789012345678', roles: ['876543210123456789', '765432101234567890'], token: 'TotallyRealToken',
* })
* .then(console.log)
* .catch(console.error);
*/
async remove({ guild, command, users, roles }) {
const { guildId, commandId } = this._validateOptions(guild, command);
if (!commandId) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
if (!users && !roles) throw new TypeError('INVALID_TYPE', 'users OR roles', 'Array or Resolvable', true);
let resolvedIds = [];
if (Array.isArray(users)) {
users.forEach(user => {
const userId = this.client.users.resolveId(user);
if (!userId) throw new TypeError('INVALID_ELEMENT', 'Array', 'users', user);
resolvedIds.push(userId);
});
} else if (users) {
const userId = this.client.users.resolveId(users);
if (!userId) {
throw new TypeError('INVALID_TYPE', 'users', 'Array or UserResolvable');
}
resolvedIds.push(userId);
async remove({ guild, command, users, roles, channels, token } = {}) {
if (!token) {
throw new Error('APPLICATION_COMMAND_PERMISSIONS_TOKEN_MISSING');
}
let { guildId, commandId } = this._validateOptions(guild, command);
if (!commandId) {
commandId = this.client.user.id;
}
if (!users && !roles && !channels) {
throw new TypeError('INVALID_TYPE', 'users OR roles OR channels', 'Array or Resolvable', true);
}
let resolvedUserIds = [];
if (Array.isArray(users)) {
for (const user of users) {
const userId = this.client.users.resolveId(user);
if (!userId) throw new TypeError('INVALID_ELEMENT', 'Array', 'users', user);
resolvedUserIds.push(userId);
}
}
let resolvedRoleIds = [];
if (Array.isArray(roles)) {
roles.forEach(role => {
for (const role of roles) {
if (typeof role === 'string') {
resolvedIds.push(role);
return;
resolvedRoleIds.push(role);
continue;
}
if (!this.guild) throw new Error('GUILD_UNCACHED_ROLE_RESOLVE');
if (!this.guild) throw new Error('GUILD_UNCACHED_ENTITY_RESOLVE', 'roles');
const roleId = this.guild.roles.resolveId(role);
if (!roleId) throw new TypeError('INVALID_ELEMENT', 'Array', 'users', role);
resolvedIds.push(roleId);
});
} else if (roles) {
if (typeof roles === 'string') {
resolvedIds.push(roles);
} else {
if (!this.guild) throw new Error('GUILD_UNCACHED_ROLE_RESOLVE');
const roleId = this.guild.roles.resolveId(roles);
if (!roleId) {
throw new TypeError('INVALID_TYPE', 'users', 'Array or RoleResolvable');
resolvedRoleIds.push(roleId);
}
}
let resolvedChannelIds = [];
if (Array.isArray(channels)) {
for (const channel of channels) {
if (typeof channel === 'string') {
resolvedChannelIds.push(channel);
continue;
}
resolvedIds.push(roleId);
if (!this.guild) throw new Error('GUILD_UNCACHED_ENTITY_RESOLVE', 'channels');
const channelId = this.guild.channels.resolveId(channel);
if (!channelId) throw new TypeError('INVALID_ELEMENT', 'Array', 'channels', channel);
resolvedChannelIds.push(channelId);
}
}
@@ -300,22 +317,33 @@ class ApplicationCommandPermissionsManager extends BaseManager {
if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error;
}
const permissions = existing.filter(perm => !resolvedIds.includes(perm.id));
const permissions = existing.filter(perm => {
switch (perm.type) {
case ApplicationCommandPermissionType.Role:
return !resolvedRoleIds.includes(perm.id);
case ApplicationCommandPermissionType.User:
return !resolvedUserIds.includes(perm.id);
case ApplicationCommandPermissionType.Channel:
return !resolvedChannelIds.includes(perm.id);
}
return true;
});
return this.set({ guild: guildId, command: commandId, permissions });
return this.set({ guild: guildId, command: commandId, permissions, token });
}
/**
* Options used to check the existence of permissions on a command
* <warn>The `command` parameter is not optional when the managers `commandId` is `null`</warn>
* @typedef {BaseApplicationCommandPermissionsOptions} HasApplicationCommandPermissionsOptions
* @property {UserResolvable|RoleResolvable} permissionId The user or role to check if a permission exists for
* @property {ApplicationCommandPermissionIdResolvable} permissionId The entity to check if a permission exists for
* on this command.
* @property {ApplicationCommandPermissionType} [permissionType] Check for a specific type of permission
*/
/**
* Check whether a permission exists for a user or role
* @param {AddApplicationCommandPermissionsOptions} options Options used to check permissions
* Check whether a permission exists for a user, role, or channel
* @param {HasApplicationCommandPermissionsOptions} options Options used to check permissions
* @returns {Promise<boolean>}
* @example
* // Check whether a user has permission to use a command
@@ -323,20 +351,33 @@ class ApplicationCommandPermissionsManager extends BaseManager {
* .then(console.log)
* .catch(console.error);
*/
async has({ guild, command, permissionId }) {
async has({ guild, command, permissionId, permissionType }) {
const { guildId, commandId } = this._validateOptions(guild, command);
if (!commandId) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
if (!permissionId) throw new TypeError('INVALID_TYPE', 'permissionId', 'UserResolvable or RoleResolvable');
if (!permissionId) {
throw new TypeError(
'INVALID_TYPE',
'permissionId',
'UserResolvable, RoleResolvable, ChannelResolvable, or Permission Constant',
);
}
let resolvedId = permissionId;
if (typeof permissionId !== 'string') {
resolvedId = this.client.users.resolveId(permissionId);
if (!resolvedId) {
if (!this.guild) throw new Error('GUILD_UNCACHED_ROLE_RESOLVE');
if (!this.guild) throw new Error('GUILD_UNCACHED_ENTITY_RESOLVE', 'roles');
resolvedId = this.guild.roles.resolveId(permissionId);
}
if (!resolvedId) {
throw new TypeError('INVALID_TYPE', 'permissionId', 'UserResolvable or RoleResolvable');
resolvedId = this.guild.channels.resolveId(permissionId);
}
if (!resolvedId) {
throw new TypeError(
'INVALID_TYPE',
'permissionId',
'UserResolvable, RoleResolvable, ChannelResolvable, or Permission Constant',
);
}
}
@@ -347,7 +388,8 @@ class ApplicationCommandPermissionsManager extends BaseManager {
if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error;
}
return existing.some(perm => perm.id === resolvedId);
// Check permission type if provided for the single edge case where a channel id is the same as the everyone role id
return existing.some(perm => perm.id === resolvedId && (permissionType ?? perm.type) === perm.type);
}
_validateOptions(guild, command) {
@@ -375,3 +417,8 @@ module.exports = ApplicationCommandPermissionsManager;
* @external APIApplicationCommandPermissions
* @see {@link https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permissions-structure}
*/
/**
* Data that resolves to an id used for an application command permission
* @typedef {UserResolvable|RoleResolvable|GuildChannelResolvable|RolePermissionConstant|ChannelPermissionConstant} ApplicationCommandPermissionIdResolvable
*/

View File

@@ -5,6 +5,7 @@ const { ApplicationCommandOptionType } = require('discord-api-types/v10');
const isEqual = require('fast-deep-equal');
const Base = require('./Base');
const ApplicationCommandPermissionsManager = require('../managers/ApplicationCommandPermissionsManager');
const PermissionsBitField = require('../util/PermissionsBitField');
/**
* Represents an application command.
@@ -121,12 +122,27 @@ class ApplicationCommand extends Base {
this.options ??= [];
}
if ('default_permission' in data) {
if ('default_member_permissions' in data) {
/**
* Whether the command is enabled by default when the app is added to a guild
* @type {boolean}
* The default bitfield used to determine whether this command be used in a guild
* @type {?Readonly<PermissionsBitField>}
*/
this.defaultPermission = data.default_permission;
this.defaultMemberPermissions = data.default_member_permissions
? new PermissionsBitField(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|null}
*/
this.dmPermission = data.dm_permission;
} else {
this.dmPermission ??= null;
}
if ('version' in data) {
@@ -176,8 +192,9 @@ class ApplicationCommand extends Base {
* if type is {@link ApplicationCommandType.ChatInput}
* @property {ApplicationCommandType} [type=ApplicationCommandType.ChatInput] The type of the command
* @property {ApplicationCommandOptionData[]} [options] Options for the command
* @property {boolean} [defaultPermission=true] 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
*/
/**
@@ -282,12 +299,21 @@ class ApplicationCommand extends Base {
}
/**
* Edits the default permission of this ApplicationCommand
* @param {boolean} [defaultPermission=true] The default permission for this command
* Edits the default member permissions of this ApplicationCommand
* @param {PermissionResolvable} defaultMemberPermissions The default member permissions required to run this command
* @returns {Promise<ApplicationCommand>}
*/
setDefaultPermission(defaultPermission = true) {
return this.edit({ defaultPermission });
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 });
}
/**
@@ -325,6 +351,20 @@ class ApplicationCommand extends Base {
// If given an id, check if the id matches
if (command.id && this.id !== command.id) return false;
let defaultMemberPermissions = null;
if ('default_member_permissions' in command) {
defaultMemberPermissions = command.default_member_permissions
? new PermissionsBitField(BigInt(command.default_member_permissions)).bitfield
: null;
}
if ('defaultMemberPermissions' in command) {
defaultMemberPermissions = command.defaultMemberPermissions
? new PermissionsBitField(command.defaultMemberPermissions).bitfield
: null;
}
// Check top level parameters
if (
command.name !== this.name ||
@@ -335,7 +375,8 @@ class ApplicationCommand extends Base {
// Future proof for options being nullable
// TODO: remove ?? 0 on each when nullable
(command.options?.length ?? 0) !== (this.options?.length ?? 0) ||
(command.defaultPermission ?? command.default_permission ?? true) !== this.defaultPermission ||
defaultMemberPermissions !== (this.defaultMemberPermissions?.bitfield ?? null) ||
command.dmPermission !== this.dmPermission ||
!isEqual(command.nameLocalizations ?? command.name_localizations ?? {}, this.nameLocalizations ?? {}) ||
!isEqual(
command.descriptionLocalizations ?? command.description_localizations ?? {},

View File

@@ -1,6 +1,7 @@
'use strict';
const { Collection } = require('@discordjs/collection');
const ApplicationCommand = require('./ApplicationCommand');
const GuildAuditLogsEntry = require('./GuildAuditLogsEntry');
const Integration = require('./Integration');
const Webhook = require('./Webhook');
@@ -21,6 +22,7 @@ const Util = require('../util/Util');
* * Sticker
* * Thread
* * GuildScheduledEvent
* * ApplicationCommandPermission
* @typedef {string} AuditLogTargetType
*/
@@ -66,6 +68,18 @@ class GuildAuditLogs {
new Collection(),
);
/**
* Cached application commands, includes application commands from other applications
* @type {Collection<Snowflake, ApplicationCommand>}
* @private
*/
this.applicationCommands = new Collection();
if (data.application_commands) {
for (const command of data.application_commands) {
this.applicationCommands.set(command.id, new ApplicationCommand(guild.client, command, guild));
}
}
/**
* The entries for this guild's audit logs
* @type {Collection<Snowflake, GuildAuditLogsEntry>}

View File

@@ -26,6 +26,7 @@ const Targets = {
StageInstance: 'StageInstance',
Sticker: 'Sticker',
Thread: 'Thread',
ApplicationCommand: 'ApplicationCommand',
Unknown: 'Unknown',
};
@@ -44,10 +45,11 @@ const Targets = {
* * A sticker
* * A guild scheduled event
* * A thread
* * An object with an id key if target was deleted
* * An application command
* * An object with an id key if target was deleted or fake entity
* * An object where the keys represent either the new value or the old value
* @typedef {?(Object|Guild|Channel|User|Role|Invite|Webhook|GuildEmoji|Message|Integration|StageInstance|Sticker|
* GuildScheduledEvent)} AuditLogEntryTarget
* GuildScheduledEvent|ApplicationCommand)} AuditLogEntryTarget
*/
/**
@@ -110,6 +112,8 @@ class GuildAuditLogsEntry {
* An entry in the audit log representing a specific change.
* @typedef {Object} AuditLogChange
* @property {string} key The property that was changed, e.g. `nick` for nickname changes
* <warn>For application command permissions updates the key is the id of the user, channel,
* role, or a permission constant that was updated instead of an actual property name</warn>
* @property {*} [old] The old value of the change, e.g. for nicknames, the old nickname
* @property {*} [new] The new value of the change, e.g. for nicknames, the new nickname
*/
@@ -194,6 +198,13 @@ class GuildAuditLogsEntry {
};
break;
case AuditLogEvent.ApplicationCommandPermissionUpdate:
this.extra = {
applicationId: data.options.application_id,
guild: guild.client.guilds.cache.get(data.options.guild_id) ?? { id: data.options.guild_id },
};
break;
default:
break;
}
@@ -321,6 +332,8 @@ class GuildAuditLogsEntry {
{ id: data.target_id, guild_id: guild.id },
),
);
} else if (targetType === Targets.ApplicationCommand) {
this.target = logs.applicationCommands.get(data.target_id) ?? { id: data.target_id };
} else if (data.target_id) {
this.target = guild[`${targetType.toLowerCase()}s`]?.cache.get(data.target_id) ?? { id: data.target_id };
}
@@ -345,6 +358,7 @@ class GuildAuditLogsEntry {
if (target < 100) return Targets.Sticker;
if (target < 110) return Targets.GuildScheduledEvent;
if (target < 120) return Targets.Thread;
if (target < 130) return Targets.ApplicationCommand;
return Targets.Unknown;
}
@@ -417,6 +431,7 @@ class GuildAuditLogsEntry {
AuditLogEvent.StickerUpdate,
AuditLogEvent.GuildScheduledEventUpdate,
AuditLogEvent.ThreadUpdate,
AuditLogEvent.ApplicationCommandPermissionUpdate,
].includes(action)
) {
return 'Update';

View File

@@ -1,72 +1,73 @@
'use strict';
module.exports = {
ApplicationCommandPermissionsUpdate: 'applicationCommandPermissionsUpdate',
CacheSweep: 'cacheSweep',
ChannelCreate: 'channelCreate',
ChannelDelete: 'channelDelete',
ChannelPinsUpdate: 'channelPinsUpdate',
ChannelUpdate: 'channelUpdate',
ClientReady: 'ready',
Debug: 'debug',
Error: 'error',
GuildBanAdd: 'guildBanAdd',
GuildBanRemove: 'guildBanRemove',
GuildCreate: 'guildCreate',
GuildDelete: 'guildDelete',
GuildUpdate: 'guildUpdate',
GuildUnavailable: 'guildUnavailable',
GuildMemberAdd: 'guildMemberAdd',
GuildMemberRemove: 'guildMemberRemove',
GuildMemberUpdate: 'guildMemberUpdate',
GuildMemberAvailable: 'guildMemberAvailable',
GuildMembersChunk: 'guildMembersChunk',
GuildIntegrationsUpdate: 'guildIntegrationsUpdate',
GuildRoleCreate: 'roleCreate',
GuildRoleDelete: 'roleDelete',
InviteCreate: 'inviteCreate',
InviteDelete: 'inviteDelete',
GuildRoleUpdate: 'roleUpdate',
GuildEmojiCreate: 'emojiCreate',
GuildEmojiDelete: 'emojiDelete',
GuildEmojiUpdate: 'emojiUpdate',
GuildBanAdd: 'guildBanAdd',
GuildBanRemove: 'guildBanRemove',
ChannelCreate: 'channelCreate',
ChannelDelete: 'channelDelete',
ChannelUpdate: 'channelUpdate',
ChannelPinsUpdate: 'channelPinsUpdate',
GuildIntegrationsUpdate: 'guildIntegrationsUpdate',
GuildMemberAdd: 'guildMemberAdd',
GuildMemberAvailable: 'guildMemberAvailable',
GuildMemberRemove: 'guildMemberRemove',
GuildMembersChunk: 'guildMembersChunk',
GuildMemberUpdate: 'guildMemberUpdate',
GuildRoleCreate: 'roleCreate',
GuildRoleDelete: 'roleDelete',
GuildRoleUpdate: 'roleUpdate',
GuildScheduledEventCreate: 'guildScheduledEventCreate',
GuildScheduledEventDelete: 'guildScheduledEventDelete',
GuildScheduledEventUpdate: 'guildScheduledEventUpdate',
GuildScheduledEventUserAdd: 'guildScheduledEventUserAdd',
GuildScheduledEventUserRemove: 'guildScheduledEventUserRemove',
GuildStickerCreate: 'stickerCreate',
GuildStickerDelete: 'stickerDelete',
GuildStickerUpdate: 'stickerUpdate',
GuildUnavailable: 'guildUnavailable',
GuildUpdate: 'guildUpdate',
InteractionCreate: 'interactionCreate',
Invalidated: 'invalidated',
InviteCreate: 'inviteCreate',
InviteDelete: 'inviteDelete',
MessageBulkDelete: 'messageDeleteBulk',
MessageCreate: 'messageCreate',
MessageDelete: 'messageDelete',
MessageUpdate: 'messageUpdate',
MessageBulkDelete: 'messageDeleteBulk',
MessageReactionAdd: 'messageReactionAdd',
MessageReactionRemove: 'messageReactionRemove',
MessageReactionRemoveAll: 'messageReactionRemoveAll',
MessageReactionRemoveEmoji: 'messageReactionRemoveEmoji',
ThreadCreate: 'threadCreate',
ThreadDelete: 'threadDelete',
ThreadUpdate: 'threadUpdate',
ThreadListSync: 'threadListSync',
ThreadMemberUpdate: 'threadMemberUpdate',
ThreadMembersUpdate: 'threadMembersUpdate',
UserUpdate: 'userUpdate',
MessageUpdate: 'messageUpdate',
PresenceUpdate: 'presenceUpdate',
VoiceServerUpdate: 'voiceServerUpdate',
VoiceStateUpdate: 'voiceStateUpdate',
TypingStart: 'typingStart',
WebhooksUpdate: 'webhookUpdate',
InteractionCreate: 'interactionCreate',
Error: 'error',
Warn: 'warn',
Debug: 'debug',
CacheSweep: 'cacheSweep',
Raw: 'raw',
ShardDisconnect: 'shardDisconnect',
ShardError: 'shardError',
ShardReconnecting: 'shardReconnecting',
ShardReady: 'shardReady',
ShardReconnecting: 'shardReconnecting',
ShardResume: 'shardResume',
Invalidated: 'invalidated',
Raw: 'raw',
StageInstanceCreate: 'stageInstanceCreate',
StageInstanceUpdate: 'stageInstanceUpdate',
StageInstanceDelete: 'stageInstanceDelete',
GuildStickerCreate: 'stickerCreate',
GuildStickerDelete: 'stickerDelete',
GuildStickerUpdate: 'stickerUpdate',
GuildScheduledEventCreate: 'guildScheduledEventCreate',
GuildScheduledEventUpdate: 'guildScheduledEventUpdate',
GuildScheduledEventDelete: 'guildScheduledEventDelete',
GuildScheduledEventUserAdd: 'guildScheduledEventUserAdd',
GuildScheduledEventUserRemove: 'guildScheduledEventUserRemove',
StageInstanceUpdate: 'stageInstanceUpdate',
ThreadCreate: 'threadCreate',
ThreadDelete: 'threadDelete',
ThreadListSync: 'threadListSync',
ThreadMembersUpdate: 'threadMembersUpdate',
ThreadMemberUpdate: 'threadMemberUpdate',
ThreadUpdate: 'threadUpdate',
TypingStart: 'typingStart',
UserUpdate: 'userUpdate',
VoiceServerUpdate: 'voiceServerUpdate',
VoiceStateUpdate: 'voiceStateUpdate',
Warn: 'warn',
WebhooksUpdate: 'webhookUpdate',
};

View File

@@ -304,10 +304,11 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
public applicationId: Snowflake;
public get createdAt(): Date;
public get createdTimestamp(): number;
public defaultPermission: boolean;
public defaultMemberPermissions: Readonly<PermissionsBitField> | null;
public description: string;
public descriptionLocalizations: LocalizationMap | null;
public descriptionLocalized: string | null;
public dmPermission: boolean | null;
public guild: Guild | null;
public guildId: Snowflake | null;
public get manager(): ApplicationCommandManager;
@@ -317,7 +318,6 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
public nameLocalized: string | null;
public options: (ApplicationCommandOption & { nameLocalized?: string; descriptionLocalized?: string })[];
public permissions: ApplicationCommandPermissionsManager<
PermissionsFetchType,
PermissionsFetchType,
PermissionsFetchType,
Guild | null,
@@ -333,7 +333,10 @@ export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
public setDescriptionLocalizations(
descriptionLocalizations: LocalizationMap,
): Promise<ApplicationCommand<PermissionsFetchType>>;
public setDefaultPermission(defaultPermission?: boolean): Promise<ApplicationCommand<PermissionsFetchType>>;
public setDefaultMemberPermissions(
defaultMemberPermissions: PermissionResolvable,
): Promise<ApplicationCommand<PermissionsFetchType>>;
public setDMPermissoin(dmPermission?: boolean): Promise<ApplicationCommand<PermissionsFetchType>>;
public setOptions(options: ApplicationCommandOptionData[]): Promise<ApplicationCommand<PermissionsFetchType>>;
public equals(
command: ApplicationCommand | ApplicationCommandData | RawApplicationCommandData,
@@ -1173,6 +1176,7 @@ export class Guild extends AnonymousGuild {
export class GuildAuditLogs<T extends GuildAuditLogsResolvable = null> {
private constructor(guild: Guild, data: RawGuildAuditLogData);
private applicationCommands: Collection<Snowflake, ApplicationCommand>;
private webhooks: Collection<Snowflake, Webhook>;
private integrations: Collection<Snowflake | string, Integration>;
private guildScheduledEvents: Collection<Snowflake, GuildScheduledEvent>;
@@ -3016,7 +3020,6 @@ export class ApplicationCommandManager<
public permissions: ApplicationCommandPermissionsManager<
{ command?: ApplicationCommandResolvable } & PermissionsOptionsExtras,
{ command: ApplicationCommandResolvable } & PermissionsOptionsExtras,
PermissionsOptionsExtras,
PermissionsGuildType,
null
>;
@@ -3055,7 +3058,6 @@ export class ApplicationCommandManager<
export class ApplicationCommandPermissionsManager<
BaseOptions,
FetchSingleOptions,
FullPermissionsOptions,
GuildType,
CommandIdType,
> extends BaseManager {
@@ -3066,30 +3068,40 @@ export class ApplicationCommandPermissionsManager<
public guild: GuildType;
public guildId: Snowflake | null;
public add(
options: FetchSingleOptions & { permissions: ApplicationCommandPermissionData[] },
options: FetchSingleOptions & EditApplicationCommandPermissionsMixin,
): Promise<ApplicationCommandPermissions[]>;
public has(options: FetchSingleOptions & { permissionId: UserResolvable | RoleResolvable }): Promise<boolean>;
public has(
options: FetchSingleOptions & {
permissionId: ApplicationCommandPermissionIdResolvable;
permissionType?: ApplicationCommandPermissionType;
},
): Promise<boolean>;
public fetch(options: FetchSingleOptions): Promise<ApplicationCommandPermissions[]>;
public fetch(options: BaseOptions): Promise<Collection<Snowflake, ApplicationCommandPermissions[]>>;
public remove(
options:
| (FetchSingleOptions & {
users: UserResolvable | UserResolvable[];
roles?: RoleResolvable | RoleResolvable[];
token: string;
channels?: (GuildChannelResolvable | ChannelPermissionConstant)[];
roles?: (RoleResolvable | RolePermissionConstant)[];
users: UserResolvable[];
})
| (FetchSingleOptions & {
users?: UserResolvable | UserResolvable[];
roles: RoleResolvable | RoleResolvable[];
token: string;
channels?: (GuildChannelResolvable | ChannelPermissionConstant)[];
roles: (RoleResolvable | RolePermissionConstant)[];
users?: UserResolvable[];
})
| (FetchSingleOptions & {
token: string;
channels: (GuildChannelResolvable | ChannelPermissionConstant)[];
roles?: (RoleResolvable | RolePermissionConstant)[];
users?: UserResolvable[];
}),
): Promise<ApplicationCommandPermissions[]>;
public set(
options: FetchSingleOptions & { permissions: ApplicationCommandPermissionData[] },
options: FetchSingleOptions & EditApplicationCommandPermissionsMixin,
): Promise<ApplicationCommandPermissions[]>;
public set(
options: FullPermissionsOptions & {
fullPermissions: GuildApplicationCommandPermissionData[];
},
): Promise<Collection<Snowflake, ApplicationCommandPermissions[]>>;
private permissionsPath(guildId: Snowflake, commandId?: Snowflake): string;
}
@@ -3517,7 +3529,8 @@ export type AllowedThreadTypeForTextChannel = ChannelType.GuildPublicThread | Ch
export interface BaseApplicationCommandData {
name: string;
nameLocalizations?: LocalizationMap;
defaultPermission?: boolean;
dmPermission?: boolean;
defaultMemberPermissions?: PermissionResolvable;
}
export interface AttachmentData {
@@ -3682,16 +3695,35 @@ export interface ApplicationCommandOptionChoiceData {
value: string | number;
}
export interface ApplicationCommandPermissionData {
export interface ApplicationCommandPermissions {
id: Snowflake;
type: ApplicationCommandPermissionType;
permission: boolean;
}
export interface ApplicationCommandPermissions extends ApplicationCommandPermissionData {
type: ApplicationCommandPermissionType;
export interface ApplicationCommandPermissionsUpdateData {
id: Snowflake;
guildId: Snowflake;
applicationId: Snowflake;
permissions: ApplicationCommandPermissions;
}
export interface EditApplicationCommandPermissionsMixin {
permissions: ApplicationCommandPermissions[];
token: string;
}
export type ChannelPermissionConstant = Snowflake;
export type RolePermissionConstant = Snowflake;
export type ApplicationCommandPermissionIdResolvable =
| GuildChannelResolvable
| RoleResolvable
| UserResolvable
| ChannelPermissionConstant
| RolePermissionConstant;
export type ApplicationCommandResolvable = ApplicationCommand | Snowflake;
export type ApplicationFlagsString = keyof typeof ApplicationFlags;
@@ -3859,6 +3891,7 @@ export interface WebhookCreateOptions extends ChannelWebhookCreateOptions {
}
export interface ClientEvents {
applicationCommandPermissionsUpdate: [data: ApplicationCommandPermissionsUpdateData];
cacheSweep: [message: string];
channelCreate: [channel: NonThreadGuildBasedChannel];
channelDelete: [channel: DMChannel | NonThreadGuildBasedChannel];
@@ -4341,11 +4374,6 @@ export interface AttachmentPayload {
export type GlobalSweepFilter<K, V> = () => ((value: V, key: K, collection: Collection<K, V>) => boolean) | null;
export interface GuildApplicationCommandPermissionData {
id: Snowflake;
permissions: ApplicationCommandPermissionData[];
}
interface GuildAuditLogsTypes {
[AuditLogEvent.GuildUpdate]: ['Guild', 'Update'];
[AuditLogEvent.ChannelCreate]: ['Channel', 'Create'];
@@ -4394,6 +4422,7 @@ interface GuildAuditLogsTypes {
[AuditLogEvent.ThreadCreate]: ['Thread', 'Create'];
[AuditLogEvent.ThreadUpdate]: ['Thread', 'Update'];
[AuditLogEvent.ThreadDelete]: ['Thread', 'Delete'];
[AuditLogEvent.ApplicationCommandPermissionUpdate]: ['ApplicationCommand', 'Update'];
}
export type GuildAuditLogsActionType = GuildAuditLogsTypes[keyof GuildAuditLogsTypes][1] | 'All';
@@ -4424,6 +4453,7 @@ export interface GuildAuditLogsEntryExtraField {
[AuditLogEvent.StageInstanceCreate]: StageChannel | { id: Snowflake };
[AuditLogEvent.StageInstanceDelete]: StageChannel | { id: Snowflake };
[AuditLogEvent.StageInstanceUpdate]: StageChannel | { id: Snowflake };
[AuditLogEvent.ApplicationCommandPermissionUpdate]: { applicationId: Snowflake; guild: Guild | { id: Snowflake } };
}
export interface GuildAuditLogsEntryTargetField<TActionType extends GuildAuditLogsActionType> {
@@ -4438,6 +4468,7 @@ export interface GuildAuditLogsEntryTargetField<TActionType extends GuildAuditLo
StageInstance: StageInstance;
Sticker: Sticker;
GuildScheduledEvent: GuildScheduledEvent;
ApplicationCommand: ApplicationCommand;
}
export interface GuildAuditLogsFetchOptions<T extends GuildAuditLogsResolvable> {

View File

@@ -175,44 +175,55 @@ client.on('ready', async () => {
// Test command permissions
const globalPermissionsManager = client.application?.commands.permissions;
const guildPermissionsManager = client.guilds.cache.get(testGuildId)?.commands.permissions;
const originalPermissions = await client.application?.commands.permissions.fetch({ guild: testGuildId });
// Permissions from global manager
await globalPermissionsManager?.add({
command: globalCommandId,
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await globalPermissionsManager?.has({ command: globalCommandId, guild: testGuildId, permissionId: testGuildId });
await globalPermissionsManager?.fetch({ guild: testGuildId });
await globalPermissionsManager?.fetch({ command: globalCommandId, guild: testGuildId });
await globalPermissionsManager?.remove({ command: globalCommandId, guild: testGuildId, roles: [testGuildId] });
await globalPermissionsManager?.remove({ command: globalCommandId, guild: testGuildId, users: [testUserId] });
await globalPermissionsManager?.remove({
command: globalCommandId,
guild: testGuildId,
roles: [testGuildId],
token: 'VeryRealToken',
});
await globalPermissionsManager?.remove({
command: globalCommandId,
guild: testGuildId,
users: [testUserId],
token: 'VeryRealToken',
});
await globalPermissionsManager?.remove({
command: globalCommandId,
guild: testGuildId,
channels: [testGuildId],
token: 'VeryRealToken',
});
await globalPermissionsManager?.remove({
command: globalCommandId,
guild: testGuildId,
roles: [testGuildId],
users: [testUserId],
channels: [testGuildId],
token: 'VeryRealToken',
});
await globalPermissionsManager?.set({
command: globalCommandId,
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
});
await globalPermissionsManager?.set({
guild: testGuildId,
fullPermissions: [
{
id: globalCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
},
],
token: 'VeryRealToken',
});
// @ts-expect-error
await globalPermissionsManager?.add({
command: globalCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await globalPermissionsManager?.has({ command: globalCommandId, permissionId: testGuildId });
@@ -221,68 +232,72 @@ client.on('ready', async () => {
// @ts-expect-error
await globalPermissionsManager?.fetch({ command: globalCommandId });
// @ts-expect-error
await globalPermissionsManager?.remove({ command: globalCommandId, roles: [testGuildId] });
await globalPermissionsManager?.remove({ command: globalCommandId, roles: [testGuildId], token: 'VeryRealToken' });
// @ts-expect-error
await globalPermissionsManager?.remove({ command: globalCommandId, users: [testUserId] });
await globalPermissionsManager?.remove({ command: globalCommandId, users: [testUserId], token: 'VeryRealToken' });
// @ts-expect-error
await globalPermissionsManager?.remove({ command: globalCommandId, roles: [testGuildId], users: [testUserId] });
// @ts-expect-error
await globalPermissionsManager?.set({
await globalPermissionsManager?.remove({
command: globalCommandId,
permissions: [{ type: 'Role', id: testGuildId, permission: true }],
});
// @ts-expect-error
await globalPermissionsManager?.set({
fullPermissions: [{ id: globalCommandId, permissions: [{ type: 'Role', id: testGuildId, permission: true }] }],
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
// @ts-expect-error
await globalPermissionsManager?.set({
command: globalCommandId,
guild: testGuildId,
fullPermissions: [{ id: globalCommandId, permissions: [{ type: 'Role', id: testGuildId, permission: true }] }],
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await globalPermissionsManager?.add({
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await globalPermissionsManager?.has({ guild: testGuildId, permissionId: testGuildId });
// @ts-expect-error
await globalPermissionsManager?.remove({ guild: testGuildId, roles: [testGuildId] });
await globalPermissionsManager?.remove({ guild: testGuildId, roles: [testGuildId], token: 'VeryRealToken' });
// @ts-expect-error
await globalPermissionsManager?.remove({ guild: testGuildId, users: [testUserId] });
await globalPermissionsManager?.remove({ guild: testGuildId, users: [testUserId], token: 'VeryRealToken' });
// @ts-expect-error
await globalPermissionsManager?.remove({ guild: testGuildId, roles: [testGuildId], users: [testUserId] });
await globalPermissionsManager?.remove({
guild: testGuildId,
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
// @ts-expect-error
await globalPermissionsManager?.set({
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// Permissions from guild manager
await guildPermissionsManager?.add({
command: globalCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await guildPermissionsManager?.has({ command: globalCommandId, permissionId: testGuildId });
await guildPermissionsManager?.fetch({});
await guildPermissionsManager?.fetch({ command: globalCommandId });
await guildPermissionsManager?.remove({ command: globalCommandId, roles: [testGuildId] });
await guildPermissionsManager?.remove({ command: globalCommandId, users: [testUserId] });
await guildPermissionsManager?.remove({ command: globalCommandId, roles: [testGuildId], users: [testUserId] });
await guildPermissionsManager?.remove({ command: globalCommandId, roles: [testGuildId], token: 'VeryRealToken' });
await guildPermissionsManager?.remove({ command: globalCommandId, users: [testUserId], token: 'VeryRealToken' });
await guildPermissionsManager?.remove({ command: globalCommandId, channels: [testGuildId], token: 'VeryRealToken' });
await guildPermissionsManager?.remove({
command: globalCommandId,
roles: [testGuildId],
users: [testUserId],
channels: [testGuildId],
token: 'VeryRealToken',
});
await guildPermissionsManager?.set({
command: globalCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
});
await guildPermissionsManager?.set({
fullPermissions: [
{
id: globalCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
},
],
token: 'VeryRealToken',
});
await guildPermissionsManager?.add({
@@ -290,6 +305,7 @@ client.on('ready', async () => {
// @ts-expect-error
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await guildPermissionsManager?.has({ command: globalCommandId, guild: testGuildId, permissionId: testGuildId });
@@ -297,74 +313,75 @@ client.on('ready', async () => {
await guildPermissionsManager?.fetch({ guild: testGuildId });
// @ts-expect-error
await guildPermissionsManager?.fetch({ command: globalCommandId, guild: testGuildId });
// @ts-expect-error
await guildPermissionsManager?.remove({ command: globalCommandId, guild: testGuildId, roles: [testGuildId] });
// @ts-expect-error
await guildPermissionsManager?.remove({ command: globalCommandId, guild: testGuildId, users: [testUserId] });
await guildPermissionsManager?.remove({
command: globalCommandId,
// @ts-expect-error
guild: testGuildId,
roles: [testGuildId],
token: 'VeryRealToken',
});
await guildPermissionsManager?.remove({
command: globalCommandId,
// @ts-expect-error
guild: testGuildId,
users: [testUserId],
token: 'VeryRealToken',
});
await guildPermissionsManager?.remove({
command: globalCommandId,
// @ts-expect-error
guild: testGuildId,
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
// @ts-expect-error
await guildPermissionsManager?.set({
command: globalCommandId,
guild: testGuildId,
permissions: [{ type: 'Role', id: testGuildId, permission: true }],
});
await guildPermissionsManager?.set({
// @ts-expect-error
guild: testGuildId,
fullPermissions: [
{
id: globalCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
},
],
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await guildPermissionsManager?.add({
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await guildPermissionsManager?.has({ permissionId: testGuildId });
// @ts-expect-error
await guildPermissionsManager?.remove({ roles: [testGuildId] });
await guildPermissionsManager?.remove({ roles: [testGuildId], token: 'VeryRealToken' });
// @ts-expect-error
await guildPermissionsManager?.remove({ users: [testUserId] });
await guildPermissionsManager?.remove({ users: [testUserId], token: 'VeryRealToken' });
// @ts-expect-error
await guildPermissionsManager?.remove({ roles: [testGuildId], users: [testUserId] });
await guildPermissionsManager?.remove({ roles: [testGuildId], users: [testUserId], token: 'VeryRealToken' });
// @ts-expect-error
await guildPermissionsManager?.set({
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
});
// @ts-expect-error
await guildPermissionsManager?.set({
command: globalCommandId,
fullPermissions: [
{
id: globalCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
},
],
token: 'VeryRealToken',
});
// Permissions from cached global ApplicationCommand
await globalCommand?.permissions.add({
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await globalCommand?.permissions.has({ guild: testGuildId, permissionId: testGuildId });
await globalCommand?.permissions.fetch({ guild: testGuildId });
await globalCommand?.permissions.remove({ guild: testGuildId, roles: [testGuildId] });
await globalCommand?.permissions.remove({ guild: testGuildId, users: [testUserId] });
await globalCommand?.permissions.remove({ guild: testGuildId, roles: [testGuildId], users: [testUserId] });
await globalCommand?.permissions.remove({ guild: testGuildId, roles: [testGuildId], token: 'VeryRealToken' });
await globalCommand?.permissions.remove({ guild: testGuildId, users: [testUserId], token: 'VeryRealToken' });
await globalCommand?.permissions.remove({
guild: testGuildId,
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
await globalCommand?.permissions.set({
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await globalCommand?.permissions.add({
@@ -372,43 +389,62 @@ client.on('ready', async () => {
command: globalCommandId,
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await globalCommand?.permissions.has({
// @ts-expect-error
command: globalCommandId,
guild: testGuildId,
permissionId: testGuildId,
token: 'VeryRealToken',
});
// @ts-expect-error
await globalCommand?.permissions.has({ command: globalCommandId, guild: testGuildId, permissionId: testGuildId });
// @ts-expect-error
await globalCommand?.permissions.fetch({ command: globalCommandId, guild: testGuildId });
// @ts-expect-error
await globalCommand?.permissions.remove({ command: globalCommandId, guild: testGuildId, roles: [testGuildId] });
// @ts-expect-error
await globalCommand?.permissions.remove({ command: globalCommandId, guild: testGuildId, users: [testUserId] });
await globalCommand?.permissions.fetch({ command: globalCommandId, guild: testGuildId, token: 'VeryRealToken' });
await globalCommand?.permissions.remove({
// @ts-expect-error
command: globalCommandId,
guild: testGuildId,
roles: [testGuildId],
token: 'VeryRealToken',
});
await globalCommand?.permissions.remove({
// @ts-expect-error
command: globalCommandId,
guild: testGuildId,
users: [testUserId],
token: 'VeryRealToken',
});
await globalCommand?.permissions.remove({
// @ts-expect-error
command: globalCommandId,
guild: testGuildId,
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
await globalCommand?.permissions.set({
// @ts-expect-error
command: globalCommandId,
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await globalCommand?.permissions.add({
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await globalCommand?.permissions.has({ permissionId: testGuildId });
// @ts-expect-error
await globalCommand?.permissions.fetch({});
// @ts-expect-error
await globalCommand?.permissions.remove({ roles: [testGuildId] });
await globalCommand?.permissions.remove({ roles: [testGuildId], token: 'VeryRealToken' });
// @ts-expect-error
await globalCommand?.permissions.remove({ users: [testUserId] });
await globalCommand?.permissions.remove({ users: [testUserId], token: 'VeryRealToken' });
// @ts-expect-error
await globalCommand?.permissions.remove({ roles: [testGuildId], users: [testUserId] });
await globalCommand?.permissions.remove({ roles: [testGuildId], users: [testUserId], token: 'VeryRealToken' });
// @ts-expect-error
await globalCommand?.permissions.set({
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
@@ -417,115 +453,162 @@ client.on('ready', async () => {
// Permissions from cached guild ApplicationCommand
await guildCommandFromGlobal?.permissions.add({
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await guildCommandFromGlobal?.permissions.has({ permissionId: testGuildId });
await guildCommandFromGlobal?.permissions.fetch({});
await guildCommandFromGlobal?.permissions.remove({ roles: [testGuildId] });
await guildCommandFromGlobal?.permissions.remove({ users: [testUserId] });
await guildCommandFromGlobal?.permissions.remove({ roles: [testGuildId], users: [testUserId] });
await guildCommandFromGlobal?.permissions.remove({ roles: [testGuildId], token: 'VeryRealToken' });
await guildCommandFromGlobal?.permissions.remove({ users: [testUserId], token: 'VeryRealToken' });
await guildCommandFromGlobal?.permissions.remove({
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
await guildCommandFromGlobal?.permissions.set({
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await guildCommandFromGlobal?.permissions.add({
// @ts-expect-error
command: globalCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await guildCommandFromGlobal?.permissions.has({ command: guildCommandId, permissionId: testGuildId });
// @ts-expect-error
await guildCommandFromGlobal?.permissions.remove({ command: guildCommandId, roles: [testGuildId] });
// @ts-expect-error
await guildCommandFromGlobal?.permissions.remove({ command: guildCommandId, users: [testUserId] });
await guildCommandFromGlobal?.permissions.remove({
// @ts-expect-error
command: guildCommandId,
roles: [testGuildId],
token: 'VeryRealToken',
});
await guildCommandFromGlobal?.permissions.remove({
// @ts-expect-error
command: guildCommandId,
users: [testUserId],
token: 'VeryRealToken',
});
await guildCommandFromGlobal?.permissions.remove({
// @ts-expect-error
command: guildCommandId,
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
await guildCommandFromGlobal?.permissions.set({
// @ts-expect-error
command: guildCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await guildCommandFromGlobal?.permissions.add({
// @ts-expect-error
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await guildCommandFromGlobal?.permissions.has({ guild: testGuildId, permissionId: testGuildId });
await guildCommandFromGlobal?.permissions.remove({
// @ts-expect-error
guild: testGuildId,
roles: [testGuildId],
token: 'VeryRealToken',
});
// @ts-expect-error
await guildCommandFromGlobal?.permissions.remove({ guild: testGuildId, roles: [testGuildId] });
// @ts-expect-error
await guildCommandFromGlobal?.permissions.remove({ guild: testGuildId, users: [testUserId] });
// @ts-expect-error
await guildCommandFromGlobal?.permissions.remove({ guild: testGuildId, roles: [testGuildId], users: [testUserId] });
await guildCommandFromGlobal?.permissions.remove({ guild: testGuildId, users: [testUserId], token: 'VeryRealToken' });
await guildCommandFromGlobal?.permissions.remove({
// @ts-expect-error
guild: testGuildId,
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
await guildCommandFromGlobal?.permissions.set({
// @ts-expect-error
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await guildCommandFromGuild?.permissions.add({
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await guildCommandFromGuild?.permissions.has({ permissionId: testGuildId });
await guildCommandFromGuild?.permissions.fetch({});
await guildCommandFromGuild?.permissions.remove({ roles: [testGuildId] });
await guildCommandFromGuild?.permissions.remove({ users: [testUserId] });
await guildCommandFromGuild?.permissions.remove({ roles: [testGuildId], users: [testUserId] });
await guildCommandFromGuild?.permissions.remove({ roles: [testGuildId], token: 'VeryRealToken' });
await guildCommandFromGuild?.permissions.remove({ users: [testUserId], token: 'VeryRealToken' });
await guildCommandFromGuild?.permissions.remove({
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
await guildCommandFromGuild?.permissions.set({
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await guildCommandFromGuild?.permissions.add({
// @ts-expect-error
command: globalCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await guildCommandFromGuild?.permissions.has({ command: guildCommandId, permissionId: testGuildId });
// @ts-expect-error
await guildCommandFromGuild?.permissions.remove({ command: guildCommandId, roles: [testGuildId] });
// @ts-expect-error
await guildCommandFromGuild?.permissions.remove({ command: guildCommandId, users: [testUserId] });
await guildCommandFromGuild?.permissions.remove({
// @ts-expect-error
command: guildCommandId,
roles: [testGuildId],
token: 'VeryRealToken',
});
await guildCommandFromGuild?.permissions.remove({
// @ts-expect-error
command: guildCommandId,
users: [testUserId],
token: 'VeryRealToken',
});
await guildCommandFromGuild?.permissions.remove({
// @ts-expect-error
command: guildCommandId,
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
await guildCommandFromGuild?.permissions.set({
// @ts-expect-error
command: guildCommandId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
await guildCommandFromGuild?.permissions.add({
// @ts-expect-error
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
token: 'VeryRealToken',
});
// @ts-expect-error
await guildCommandFromGuild?.permissions.has({ guild: testGuildId, permissionId: testGuildId });
// @ts-expect-error
await guildCommandFromGuild?.permissions.remove({ guild: testGuildId, roles: [testGuildId] });
await guildCommandFromGuild?.permissions.remove({ guild: testGuildId, roles: [testGuildId], token: 'VeryRealToken' });
// @ts-expect-error
await guildCommandFromGuild?.permissions.remove({ guild: testGuildId, users: [testUserId] });
// @ts-expect-error
await guildCommandFromGuild?.permissions.remove({ guild: testGuildId, roles: [testGuildId], users: [testUserId] });
await guildCommandFromGuild?.permissions.remove({ guild: testGuildId, users: [testUserId], token: 'VeryRealToken' });
await guildCommandFromGuild?.permissions.remove({
// @ts-expect-error
guild: testGuildId,
roles: [testGuildId],
users: [testUserId],
token: 'VeryRealToken',
});
await guildCommandFromGuild?.permissions.set({
// @ts-expect-error
guild: testGuildId,
permissions: [{ type: ApplicationCommandPermissionType.Role, id: testGuildId, permission: true }],
});
client.application?.commands.permissions.set({
guild: testGuildId,
fullPermissions: originalPermissions?.map((permissions, id) => ({ permissions, id })) ?? [],
token: 'VeryRealToken',
});
});