diff --git a/README.md b/README.md index 9b6f49b..ea98890 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,13 @@ The Artificer comes with a few supplemental commands to the main rolling command * `[[ra delete-all [aliasName] [verificationCode?]` * `[[ra guild delete-all [aliasName] [verificationCode?]` * Deletes all aliases from your account or the guild you are in. Can be run without a verification code to get the needed code for deletion. + * `[[ra clone [aliasName]` + * Copies the specified alias from your account to the guild you are in. + * `[[ra guild clone [aliasName]` + * Copies the specified alias from the guild you are in to your account. + * `[[ra rename [oldAliasName] [newAliasName]` + * `[[ra guild rename [oldAliasName] [newAliasName]` + * Renames the specified alias for your account or the guild you are in. * `[[ra [aliasName] [yVars?...]` * `[[ra run [aliasName] [yVars?...]` * Runs the desired personal alias with the specified yVars (if any are needed). If the alias is not found on your account, it will check the guild aliases and use a match from there if one exists. diff --git a/src/commands/aliasCmd.ts b/src/commands/aliasCmd.ts index 0e419be..27ce6cf 100644 --- a/src/commands/aliasCmd.ts +++ b/src/commands/aliasCmd.ts @@ -39,7 +39,6 @@ export const alias = (message: DiscordenoMessage, argSpaces: string[]) => { return; } - // Makes sure the user is authenticated to run the API command switch (aliasArg) { case 'help': case 'h': @@ -76,6 +75,9 @@ export const alias = (message: DiscordenoMessage, argSpaces: string[]) => { case 'copy': aliasCommands.clone(message, guildMode, argSpaces); break; + case 'rename': + aliasCommands.rename(message, guildMode, argSpaces); + break; case 'run': case 'execute': default: diff --git a/src/commands/aliasCmd/_index.ts b/src/commands/aliasCmd/_index.ts index 07ef134..b0f9433 100644 --- a/src/commands/aliasCmd/_index.ts +++ b/src/commands/aliasCmd/_index.ts @@ -3,6 +3,7 @@ import { clone } from './clone.ts'; import { deleteAll, deleteOne } from './aliasDelete.ts'; import { help } from 'commands/aliasCmd/aliasHelp.ts'; import { list } from 'commands/aliasCmd/list.ts'; +import { rename } from './rename.ts'; import { run } from 'commands/aliasCmd/run.ts'; import { view } from 'commands/aliasCmd/view.ts'; @@ -13,6 +14,7 @@ export default { deleteOne, help, list, + rename, run, update, view, diff --git a/src/commands/aliasCmd/aliasHelp.ts b/src/commands/aliasCmd/aliasHelp.ts index 8fda652..83f786d 100644 --- a/src/commands/aliasCmd/aliasHelp.ts +++ b/src/commands/aliasCmd/aliasHelp.ts @@ -72,6 +72,11 @@ To view ${guildMode ? '' : 'non-'}guild mode commands, please run \`${config.pre value: `Copies the specified alias from ${guildMode ? 'this guild' : 'your account'} to ${guildMode ? 'your account' : 'this guild'}.`, inline: true, }, + { + name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}rename [oldAliasName] [newAliasName]`, + value: `Renames the specified alias in ${guildMode ? 'this guild' : 'your account'}.`, + inline: true, + }, { name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}[alias] [yVars...?]\` or \`${config.prefix}ra ${guildMode ? 'guild ' : ''}run/execute [alias] [yVars...?]\``, value: `Runs the specified ${guildMode ? 'guild ' : ''}alias with the provided yVars. yVars are only required if the alias specified requires them.`, diff --git a/src/commands/aliasCmd/clone.ts b/src/commands/aliasCmd/clone.ts index 0662ea4..2b6ceaf 100644 --- a/src/commands/aliasCmd/clone.ts +++ b/src/commands/aliasCmd/clone.ts @@ -1,10 +1,14 @@ import { DiscordenoMessage, hasGuildPermissions } from '@discordeno'; -import { failColor, successColor } from 'embeds/colors.ts'; -import utils from 'utils/utils.ts'; -import dbClient from 'db/client.ts'; -import { generateAliasError } from 'embeds/alias.ts'; + import config from '~config'; +import dbClient from 'db/client.ts'; + +import { generateAliasError } from 'embeds/alias.ts'; +import { failColor, successColor } from 'embeds/colors.ts'; + +import utils from 'utils/utils.ts'; + interface QueryShape { aliasName: string; yVarCnt: number; diff --git a/src/commands/aliasCmd/rename.ts b/src/commands/aliasCmd/rename.ts new file mode 100644 index 0000000..dd8ec9c --- /dev/null +++ b/src/commands/aliasCmd/rename.ts @@ -0,0 +1,142 @@ +import { DiscordenoMessage, hasGuildPermissions } from '@discordeno'; + +import config from '~config'; + +import dbClient from 'db/client.ts'; + +import { generateAliasError } from 'embeds/alias.ts'; +import { failColor, successColor } from 'embeds/colors.ts'; + +import utils from 'utils/utils.ts'; + +interface QueryShape { + aliasName: string; +} + +export const rename = async (message: DiscordenoMessage, guildMode: boolean, argSpaces: string[]) => { + if (!guildMode && !(await hasGuildPermissions(message.authorId, message.guildId, ['ADMINISTRATOR']))) { + message + .send({ + embeds: [ + { + color: failColor, + title: `Error: Only Guild Owners and Admins can rename a guild aliases`, + }, + ], + }) + .catch((e: Error) => utils.commonLoggers.messageSendError('rename.ts:25', message, e)); + return; + } + + const oldAliasName = (argSpaces.shift() || '').trim().toLowerCase(); + argSpaces.shift(); + const newAliasName = (argSpaces.shift() || '').trim().toLowerCase(); + + if (!oldAliasName || !newAliasName) { + message + .send({ + embeds: [ + { + color: failColor, + title: `Error: Please specify both an alias to rename, and the new name to set it to.`, + }, + ], + }) + .catch((e: Error) => utils.commonLoggers.messageSendError('rename.ts:32', message, e)); + return; + } + + // make sure old alias exists, and new doesn't exist first + let errorOut = false; + const queryOld: QueryShape[] = await dbClient + .query( + `SELECT aliasName FROM aliases WHERE guildid = ? AND userid = ? AND aliasName = ?`, + guildMode ? [message.guildId, 0n, oldAliasName] : [0n, message.authorId, oldAliasName], + ) + .catch((e0) => { + utils.commonLoggers.dbError('rename.ts:44', 'query', e0); + message + .send(generateAliasError('DB Query Failed.', `rename-q0-${guildMode ? 't' : 'f'}-${oldAliasName}-${guildMode ? message.guildId : message.authorId}`)) + .catch((e: Error) => utils.commonLoggers.messageSendError('rename.ts:47', message, e)); + errorOut = true; + }); + if (errorOut) return; + + if (!queryOld.length) { + message + .send({ + embeds: [ + { + color: failColor, + title: `Error: \`${oldAliasName}\` does not exist as a ${guildMode ? 'guild' : 'personal'} alias.`, + description: `If you are trying to update an existing alias, but forgot the name, please run the following command to view all your ${guildMode ? 'guild ' : ''}aliases: +\`${config.prefix}ra ${guildMode ? 'guild ' : ''}list\``, + }, + ], + }) + .catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:63', message, e)); + return; + } + + const queryNew: QueryShape[] = await dbClient + .query( + `SELECT aliasName FROM aliases WHERE guildid = ? AND userid = ? AND aliasName = ?`, + guildMode ? [message.guildId, 0n, newAliasName] : [0n, message.authorId, newAliasName], + ) + .catch((e0) => { + utils.commonLoggers.dbError('rename.ts:44', 'query', e0); + message + .send(generateAliasError('DB Query Failed.', `rename-q1-${guildMode ? 't' : 'f'}-${newAliasName}-${guildMode ? message.guildId : message.authorId}`)) + .catch((e: Error) => utils.commonLoggers.messageSendError('rename.ts:47', message, e)); + errorOut = true; + }); + if (errorOut) return; + + if (queryNew.length) { + message + .send({ + embeds: [ + { + color: failColor, + title: `Error: \`${newAliasName}\` already exists as a ${guildMode ? 'guild' : 'personal'} alias.`, + description: 'Please choose a different name for this alias.', + }, + ], + }) + .catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:63', message, e)); + return; + } + + // do the rename + await dbClient + .execute('UPDATE aliases SET aliasName = ? WHERE guildid = ? AND userid = ? AND aliasName = ?', [ + newAliasName, + guildMode ? message.guildId : 0n, + guildMode ? 0n : message.authorId, + oldAliasName, + ]) + .catch((e0) => { + utils.commonLoggers.dbError('rename.ts:169', 'update', e0); + message + .send( + generateAliasError( + 'DB Update Failed.', + `rename-q2-${guildMode ? 't' : 'f'}-${oldAliasName}-${newAliasName}-${guildMode ? message.guildId : message.authorId}`, + ), + ) + .catch((e: Error) => utils.commonLoggers.messageSendError('rename.ts:170', message, e)); + errorOut = true; + }); + + message + .send({ + embeds: [ + { + color: successColor, + title: `Successfully renamed the ${guildMode ? 'guild' : 'personal'} alias \`${oldAliasName}\` to \`${newAliasName}\`!`, + description: `\`${newAliasName}\` is now available as an alias ${guildMode ? 'in this guild' : 'on your account'}.`, + }, + ], + }) + .catch((e: Error) => utils.commonLoggers.messageSendError('rename.ts:132', message, e)); +}; diff --git a/src/commands/aliasCmd/reservedWords.ts b/src/commands/aliasCmd/reservedWords.ts index 5cb0afb..445548f 100644 --- a/src/commands/aliasCmd/reservedWords.ts +++ b/src/commands/aliasCmd/reservedWords.ts @@ -18,4 +18,7 @@ export const ReservedWords = Object.freeze([ 'remove-all', 'run', 'execute', + 'clone', + 'copy', + 'rename', ]);