summaryrefslogtreecommitdiff
path: root/node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js
diff options
context:
space:
mode:
authorsowgro <tpoke.ferrari@gmail.com>2023-09-02 19:12:47 -0400
committersowgro <tpoke.ferrari@gmail.com>2023-09-02 19:12:47 -0400
commite4450c8417624b71d779cb4f41692538f9165e10 (patch)
treeb70826542223ecdf8a7a259f61b0a1abb8a217d8 /node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js
downloadsowbot3-e4450c8417624b71d779cb4f41692538f9165e10.tar.gz
sowbot3-e4450c8417624b71d779cb4f41692538f9165e10.tar.bz2
sowbot3-e4450c8417624b71d779cb4f41692538f9165e10.zip
first commit
Diffstat (limited to 'node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js')
-rw-r--r--node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js434
1 files changed, 434 insertions, 0 deletions
diff --git a/node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js b/node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js
new file mode 100644
index 0000000..2f7279a
--- /dev/null
+++ b/node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js
@@ -0,0 +1,434 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { ApplicationCommandPermissionType, RESTJSONErrorCodes, Routes } = require('discord-api-types/v10');
+const BaseManager = require('./BaseManager');
+const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors');
+
+/**
+ * Manages API methods for permissions of Application Commands.
+ * @extends {BaseManager}
+ */
+class ApplicationCommandPermissionsManager extends BaseManager {
+ constructor(manager) {
+ super(manager.client);
+
+ /**
+ * The manager or command that this manager belongs to
+ * @type {ApplicationCommandManager|ApplicationCommand}
+ * @private
+ */
+ this.manager = manager;
+
+ /**
+ * The guild that this manager acts on
+ * @type {?Guild}
+ */
+ this.guild = manager.guild ?? null;
+
+ /**
+ * The id of the guild that this manager acts on
+ * @type {?Snowflake}
+ */
+ this.guildId = manager.guildId ?? manager.guild?.id ?? null;
+
+ /**
+ * The id of the command this manager acts on
+ * @type {?Snowflake}
+ */
+ this.commandId = manager.id ?? null;
+ }
+
+ /**
+ * The APIRouter path to the commands
+ * @param {Snowflake} guildId The guild's id to use in the path,
+ * @param {Snowflake} [commandId] The application command's id
+ * @returns {string}
+ * @private
+ */
+ permissionsPath(guildId, commandId) {
+ if (commandId) {
+ return Routes.applicationCommandPermissions(this.client.application.id, guildId, commandId);
+ }
+
+ return Routes.guildApplicationCommandsPermissions(this.client.application.id, guildId);
+ }
+
+ /* eslint-disable max-len */
+ /**
+ * The object returned when fetching permissions for an application command.
+ * @typedef {Object} ApplicationCommandPermissions
+ * @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
+ * <warn>When passing these options to a manager where `guildId` is `null`,
+ * `guild` is a required parameter</warn>
+ * @typedef {Object} BaseApplicationCommandPermissionsOptions
+ * @property {GuildResolvable} [guild] The guild to modify / check permissions for
+ * <warn>Ignored when the manager has a non-null `guildId` property</warn>
+ * @property {ApplicationCommandResolvable} [command] The command to modify / check permissions for
+ * <warn>Ignored when the manager has a non-null `commandId` property</warn>
+ */
+
+ /**
+ * 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 ${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);
+ if (commandId) {
+ const data = await this.client.rest.get(this.permissionsPath(guildId, commandId));
+ return data.permissions;
+ }
+
+ const data = await this.client.rest.get(this.permissionsPath(guildId));
+ return data.reduce((coll, perm) => coll.set(perm.id, perm.permissions), new Collection());
+ }
+
+ /**
+ * Options used to set permissions for one or more Application Commands in a guild
+ * <warn>Omitting the `command` parameter edits the guild wide permissions
+ * when the manager's `commandId` is `null`</warn>
+ * @typedef {BaseApplicationCommandPermissionsOptions} ApplicationCommandPermissionsEditOptions
+ * @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 the guild or a command overwrite.
+ * @param {ApplicationCommandPermissionsEditOptions} options Options used to set permissions
+ * @returns {Promise<ApplicationCommandPermissions[]|Collection<Snowflake, ApplicationCommandPermissions[]>>}
+ * @example
+ * // Set a permission overwrite for a command
+ * client.application.commands.permissions.set({
+ * guild: '892455839386304532',
+ * command: '123456789012345678',
+ * token: 'TotallyRealToken',
+ * permissions: [
+ * {
+ * id: '876543210987654321',
+ * type: ApplicationCommandPermissionType.User,
+ * permission: false,
+ * },
+ * ]})
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Set the permissions used for the guild (commands without overwrites)
+ * guild.commands.permissions.set({ token: 'TotallyRealToken', permissions: [
+ * {
+ * id: '123456789012345678',
+ * permissions: [{
+ * id: '876543210987654321',
+ * type: ApplicationCommandPermissionType.User,
+ * permission: false,
+ * }],
+ * },
+ * ]})
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async set({ guild, command, permissions, token } = {}) {
+ if (!token) {
+ throw new DiscordjsError(ErrorCodes.ApplicationCommandPermissionsTokenMissing);
+ }
+ let { guildId, commandId } = this._validateOptions(guild, command);
+
+ if (!Array.isArray(permissions)) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'permissions',
+ 'Array of ApplicationCommandPermissions',
+ true,
+ );
+ }
+
+ if (!commandId) {
+ commandId = this.client.user.id;
+ }
+ const data = await this.client.rest.put(this.permissionsPath(guildId, commandId), {
+ body: { permissions },
+ auth: false,
+ headers: { Authorization: `Bearer ${token}` },
+ });
+ return data.permissions;
+ }
+
+ /**
+ * Add permissions to a command.
+ * @param {ApplicationCommandPermissionsEditOptions} options Options used to add permissions
+ * @returns {Promise<ApplicationCommandPermissions[]>}
+ * @example
+ * // 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,
+ * permission: false
+ * },
+ * ]})
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async add({ guild, command, permissions, token } = {}) {
+ if (!token) {
+ throw new DiscordjsError(ErrorCodes.ApplicationCommandPermissionsTokenMissing);
+ }
+ let { guildId, commandId } = this._validateOptions(guild, command);
+ if (!commandId) {
+ commandId = this.client.user.id;
+ }
+ if (!Array.isArray(permissions)) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'permissions',
+ 'Array of ApplicationCommandPermissions',
+ true,
+ );
+ }
+
+ let existing = [];
+ try {
+ existing = await this.fetch({ guild: guildId, command: commandId });
+ } catch (error) {
+ if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error;
+ }
+
+ const newPermissions = permissions.slice();
+ for (const perm of existing) {
+ if (!newPermissions.some(x => x.id === perm.id)) {
+ newPermissions.push(perm);
+ }
+ }
+
+ 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>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 {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
+ */
+
+ /**
+ * Remove permissions from a command.
+ * @param {RemoveApplicationCommandPermissionsOptions} options Options used to remove permissions
+ * @returns {Promise<ApplicationCommandPermissions[]>}
+ * @example
+ * // Remove a user permission from this command
+ * 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'], token: 'TotallyRealToken',
+ * })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async remove({ guild, command, users, roles, channels, token } = {}) {
+ if (!token) {
+ throw new DiscordjsError(ErrorCodes.ApplicationCommandPermissionsTokenMissing);
+ }
+ let { guildId, commandId } = this._validateOptions(guild, command);
+ if (!commandId) {
+ commandId = this.client.user.id;
+ }
+
+ if (!users && !roles && !channels) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidType, '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 DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'users', user);
+ resolvedUserIds.push(userId);
+ }
+ }
+
+ let resolvedRoleIds = [];
+ if (Array.isArray(roles)) {
+ for (const role of roles) {
+ if (typeof role === 'string') {
+ resolvedRoleIds.push(role);
+ continue;
+ }
+ if (!this.guild) throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'roles');
+ const roleId = this.guild.roles.resolveId(role);
+ if (!roleId) throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'users', role);
+ resolvedRoleIds.push(roleId);
+ }
+ }
+
+ let resolvedChannelIds = [];
+ if (Array.isArray(channels)) {
+ for (const channel of channels) {
+ if (typeof channel === 'string') {
+ resolvedChannelIds.push(channel);
+ continue;
+ }
+ if (!this.guild) throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'channels');
+ const channelId = this.guild.channels.resolveId(channel);
+ if (!channelId) throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'channels', channel);
+ resolvedChannelIds.push(channelId);
+ }
+ }
+
+ let existing = [];
+ try {
+ existing = await this.fetch({ guild: guildId, command: commandId });
+ } catch (error) {
+ if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error;
+ }
+
+ 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, 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 {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, 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
+ * guild.commands.permissions.has({ command: '123456789012345678', permissionId: '876543210123456789' })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async has({ guild, command, permissionId, permissionType }) {
+ const { guildId, commandId } = this._validateOptions(guild, command);
+ if (!commandId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
+
+ if (!permissionId) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ '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 DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'roles');
+ resolvedId = this.guild.roles.resolveId(permissionId);
+ }
+ if (!resolvedId) {
+ resolvedId = this.guild.channels.resolveId(permissionId);
+ }
+ if (!resolvedId) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'permissionId',
+ 'UserResolvable, RoleResolvable, ChannelResolvable, or Permission Constant',
+ );
+ }
+ }
+
+ let existing = [];
+ try {
+ existing = await this.fetch({ guild: guildId, command: commandId });
+ } catch (error) {
+ if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error;
+ }
+
+ // 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) {
+ const guildId = this.guildId ?? this.client.guilds.resolveId(guild);
+ if (!guildId) throw new DiscordjsError(ErrorCodes.GlobalCommandPermissions);
+ let commandId = this.commandId;
+ if (command && !commandId) {
+ commandId = this.manager.resolveId?.(command);
+ if (!commandId && this.guild) {
+ commandId = this.guild.commands.resolveId(command);
+ }
+ commandId ??= this.client.application?.commands.resolveId(command);
+ if (!commandId) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable', true);
+ }
+ }
+ return { guildId, commandId };
+ }
+}
+
+module.exports = ApplicationCommandPermissionsManager;
+
+/* eslint-disable max-len */
+/**
+ * @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
+ */