galactic-bot/structure/client/components/commands/administration/Grant.js

160 lines
5.7 KiB
JavaScript

const { Command } = require('../../../../interfaces/');
const { stripIndents } = require('common-tags');
class GrantCommand extends Command {
constructor(client) {
super(client, {
name: 'grant',
module: 'administration',
usage: "<role|user> <permissions..>",
examples: [
"\"Server Moderators\" module:moderation",
"@nolan#2887 command:kick"
],
//memberPermissions: ['ADMINISTRATOR', 'MANAGE_GUILD'],
showUsage: true,
guildOnly: true,
grantable: true,
arguments: [
{
name: 'channel',
aliases: ['channels'],
type: 'CHANNEL',
types: [
'FLAG',
'VERBAL'
],
infinite: true
}
]
});
}
async execute(message, { params, args }) {
const _permissions = await message.guild.permissions();
const [
parse,
...perms
] = params;
const resolveable = await this._parseResolveable(message, parse);
if(!resolveable) return undefined;
if(perms.length === 0) {
await message.respond(message.format('C_GRANT_MISSINGPERMPARAM'), { emoji: 'failure' });
return undefined;
}
const permissions = this.client.registry.components.filter((c) => c.type === 'command' ||
c.type === 'module');
let parsed = [];
if(perms.join(' ') === 'all') {
parsed = this.client.registry.components.filter((c) => c.type === 'command').map((c) => c.resolveable); //filter for grantable
} else {
for(const perm of perms) {
const search = permissions.filter(filterInexact(perm)).first(); //eslint-disable-line no-use-before-define
if(!search) continue;
if(search.type === 'module') {
for(const component of search.components.values()) {
if(component.type === 'command') parsed.push(component.resolveable);
}
} else {
parsed.push(search.resolveable);
}
}
}
if(!_permissions[resolveable.id]) {
_permissions[resolveable.id] = {
global: [],
channels: {}
};
}
const existing = _permissions[resolveable.id];
let granted = [];
if(args.channel) {
for(const channel of args.channel.value) {
const existingChannel = existing.channels[channel.id];
if(existingChannel) {
for(const perm of parsed) {
if(existingChannel.includes(perm)) {
continue;
} else {
existingChannel.push(perm);
granted.push(perm);
}
}
} else {
existing.channels[channel.id] = parsed;
granted = [
...granted,
...parsed
];
}
}
} else {
for(const perm of parsed) {
if(existing.global.includes(perm)) {
continue;
} else {
existing.global.push(perm);
granted.push(perm);
}
}
}
delete _permissions._id; //some bullshit..
try {
await this.client.transactionHandler.send({
provider: 'mongodb',
request: {
type: 'updateOne',
collection: 'permissions',
query: {
guildId: message.guild.id
},
data: _permissions
}
});
} catch(error) {
await message.respond(message.format('C_GRANT_DATABASEERROR'), { emoji: 'failure' });
return undefined;
}
if(granted.length > 0) {
return message.respond(stripIndents`${message.format('C_GRANT_SUCCESS', { permissions: granted.map((g) => `\`${g}\``).join(', '), resolveable: resolveable.user ? resolveable.user.tag : resolveable.name })}${args.channel ? ` ${message.format('C_GRANT_SUCCESSALT', { channels: args.channel.value.map((c) => `\`#${c.name}\``).join(', ') })}` : '.'}
${granted.length < parsed.length ? message.format('C_GRANT_SUCCESSFAILED') : ''}`, { emoji: 'success' });
}
return message.respond(message.format('C_GRANT_FAILED', { resolveable: resolveable.user ? resolveable.user.tag : resolveable.name }), { emoji: 'failure' });
}
async _parseResolveable(message, resolveable) {
let parsed = await this.client.resolver.resolveRoles(resolveable, message.guild);
if(!parsed) {
parsed = await this.client.resolver.resolveMembers(resolveable, message.guild);
if(!parsed) {
await message.respond(message.format('C_GRANT_RESOLVEERROR'), { emoji: 'failure' });
return null;
}
}
return parsed[0];
}
}
module.exports = GrantCommand;
const filterInexact = (search) => (comp) => comp.id.toLowerCase().includes(search) ||
comp.resolveable.toLowerCase().includes(search) ||
comp.aliases && (comp.aliases.some((ali) => `${comp.type}:${ali}`.toLowerCase().includes(search)) ||
comp.aliases.some((ali) => ali.toLowerCase().includes(search)));