Skip to content

Commit

Permalink
refactor: rewrite writeSettings
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranet committed Jul 21, 2024
1 parent 7bc2bb2 commit 0450c9c
Show file tree
Hide file tree
Showing 49 changed files with 788 additions and 898 deletions.
26 changes: 13 additions & 13 deletions src/commands/Admin/conf.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { configurableGroups, isSchemaGroup, isSchemaKey, readSettings, remove, reset, SchemaKey, set, writeSettings } from '#lib/database';
import { configurableGroups, isSchemaGroup, isSchemaKey, readSettings, remove, reset, SchemaKey, set, writeSettingsTransaction } from '#lib/database';
import { LanguageKeys } from '#lib/i18n/languageKeys';
import { SettingsMenu, SkyraSubcommand } from '#lib/structures';
import type { GuildMessage } from '#lib/types';
Expand Down Expand Up @@ -62,11 +62,11 @@ export class UserCommand extends SkyraSubcommand {

public async set(message: GuildMessage, args: SkyraSubcommand.Args) {
const [key, schemaKey] = await this.fetchKey(args);
const response = await writeSettings(message.guild, async (settings) => {
await set(settings, schemaKey, args);
return schemaKey.display(settings, args.t);
});

await using trx = await writeSettingsTransaction(message.guild);
await trx.write(await set(trx.settings, schemaKey, args)).submit();

const response = schemaKey.display(trx.settings, args.t);
return send(message, {
content: args.t(LanguageKeys.Commands.Admin.ConfUpdated, { key, response: this.getTextResponse(response) }),
allowedMentions: { users: [], roles: [] }
Expand All @@ -75,11 +75,11 @@ export class UserCommand extends SkyraSubcommand {

public async remove(message: GuildMessage, args: SkyraSubcommand.Args) {
const [key, schemaKey] = await this.fetchKey(args);
const response = await writeSettings(message.guild, async (settings) => {
await remove(settings, schemaKey, args);
return schemaKey.display(settings, args.t);
});

await using trx = await writeSettingsTransaction(message.guild);
await trx.write(await remove(trx.settings, schemaKey, args)).submit();

const response = schemaKey.display(trx.settings, args.t);
return send(message, {
content: args.t(LanguageKeys.Commands.Admin.ConfUpdated, { key, response: this.getTextResponse(response) }),
allowedMentions: { users: [], roles: [] }
Expand All @@ -88,11 +88,11 @@ export class UserCommand extends SkyraSubcommand {

public async reset(message: GuildMessage, args: SkyraSubcommand.Args) {
const [key, schemaKey] = await this.fetchKey(args);
const response = await writeSettings(message.guild, async (settings) => {
reset(settings, schemaKey);
return schemaKey.display(settings, args.t);
});

await using trx = await writeSettingsTransaction(message.guild);
await trx.write(reset(schemaKey)).submit();

const response = schemaKey.display(trx.settings, args.t);
return send(message, {
content: args.t(LanguageKeys.Commands.Admin.ConfReset, { key, value: response }),
allowedMentions: { users: [], roles: [] }
Expand Down
94 changes: 44 additions & 50 deletions src/commands/Admin/roleset.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { GuildEntity, readSettings, writeSettings, type UniqueRoleSet } from '#lib/database';
import { GuildEntity, readSettings, writeSettings, writeSettingsTransaction, type UniqueRoleSet } from '#lib/database';
import { LanguageKeys } from '#lib/i18n/languageKeys';
import { SkyraCommand, SkyraSubcommand } from '#lib/structures';
import { PermissionLevels, type GuildMessage } from '#lib/types';
import { ApplyOptions } from '@sapphire/decorators';
import { CommandOptionsRunTypeEnum } from '@sapphire/framework';
import { send } from '@sapphire/plugin-editable-commands';

const Root = LanguageKeys.Commands.Admin;

@ApplyOptions<SkyraSubcommand.Options>({
aliases: ['rs'],
description: LanguageKeys.Commands.Admin.RoleSetDescription,
detailedDescription: LanguageKeys.Commands.Admin.RoleSetExtended,
description: Root.RoleSetDescription,
detailedDescription: Root.RoleSetExtended,
permissionLevel: PermissionLevels.Administrator,
runIn: [CommandOptionsRunTypeEnum.GuildAny],
subcommands: [
Expand All @@ -32,15 +34,15 @@ export class UserCommand extends SkyraSubcommand {
const roles = await args.repeat('roleName');

// Get all rolesets from settings and check if there is an existing set with the name provided by the user
await writeSettings(message.guild, (settings) => {
await writeSettings(message.guild, (settings) => ({
// The set does exist so we want to only REMOVE provided roles from it
// Create a new array that we can use to overwrite the existing one in settings
settings.rolesUniqueRoleSets = settings.rolesUniqueRoleSets.map((set) =>
rolesUniqueRoleSets: settings.rolesUniqueRoleSets.map((set) =>
set.name === name ? { name, roles: set.roles.filter((id: string) => !roles.find((role) => role.id === id)) } : set
);
});
)
}));

return send(message, args.t(LanguageKeys.Commands.Admin.RoleSetRemoved, { name, roles: roles.map((role) => role.name) }));
return send(message, args.t(Root.RoleSetRemoved, { name, roles: roles.map((role) => role.name) }));
}

public async reset(message: GuildMessage, args: SkyraSubcommand.Args) {
Expand All @@ -49,21 +51,21 @@ export class UserCommand extends SkyraSubcommand {
// Get all rolesets from settings and check if there is an existing set with the name provided by the user
this.#getUniqueRoleSets(message)
]);
if (sets.length === 0) this.error(LanguageKeys.Commands.Admin.RoleSetResetEmpty);
if (sets.length === 0) this.error(Root.RoleSetResetEmpty);

if (!name) {
await writeSettings(message.guild, [['rolesUniqueRoleSets', []]]);
return send(message, args.t(LanguageKeys.Commands.Admin.RoleSetResetAll));
await writeSettings(message.guild, { rolesUniqueRoleSets: [] });
return send(message, args.t(Root.RoleSetResetAll));
}

const arrayIndex = sets.findIndex((set) => set.name === name);
if (arrayIndex === -1) this.error(LanguageKeys.Commands.Admin.RoleSetResetNotExists, { name });
if (arrayIndex === -1) this.error(Root.RoleSetResetNotExists, { name });

await writeSettings(message.guild, (settings) => {
settings.rolesUniqueRoleSets.splice(arrayIndex, 1);
await writeSettings(message.guild, {
rolesUniqueRoleSets: sets.toSpliced(arrayIndex, 1)
});

return send(message, args.t(LanguageKeys.Commands.Admin.RoleSetResetGroup, { name }));
return send(message, args.t(Root.RoleSetResetGroup, { name }));
}

// This subcommand will run if a user doesn't type add or remove. The bot will then add AND remove based on whether that role is in the set already.
Expand Down Expand Up @@ -92,15 +94,15 @@ export class UserCommand extends SkyraSubcommand {
return { name, roles: newRoles };
});

await writeSettings(message.guild, [['rolesUniqueRoleSets', newSets]]);
return send(message, args.t(LanguageKeys.Commands.Admin.RoleSetUpdated, { name }));
await writeSettings(message.guild, { rolesUniqueRoleSets: newSets });
return send(message, args.t(Root.RoleSetUpdated, { name }));
}

// This subcommand will show the user a list of role sets and each role in that set.
public async list(message: GuildMessage, args: SkyraCommand.Args) {
// Get all rolesets from settings
const sets = await this.#getUniqueRoleSets(message);
if (sets.length === 0) this.error(LanguageKeys.Commands.Admin.RoleSetNoRoleSets);
if (sets.length === 0) this.error(Root.RoleSetNoRoleSets);

const list = await this.handleList(message, args, sets);
return send(message, list.join('\n'));
Expand Down Expand Up @@ -135,21 +137,23 @@ export class UserCommand extends SkyraSubcommand {
if (changed) {
// If after cleaning up, all sets end up empty, reset and return error:
if (list.length === 0) {
await writeSettings(message.guild, [['rolesUniqueRoleSets', []]]);
this.error(LanguageKeys.Commands.Admin.RoleSetNoRoleSets);
await writeSettings(message.guild, { rolesUniqueRoleSets: [] });
this.error(Root.RoleSetNoRoleSets);
}

// Else, clean up:
await writeSettings(message.guild, (settings) => this.cleanRoleSets(message, settings));
await writeSettings(message.guild, (settings) => ({
rolesUniqueRoleSets: this.cleanRoleSets(message, settings)
}));
}

return list;
}

private cleanRoleSets(message: GuildMessage, settings: GuildEntity) {
private cleanRoleSets(message: GuildMessage, settings: Readonly<GuildEntity>) {
const guildRoles = message.guild.roles.cache;

settings.rolesUniqueRoleSets = settings.rolesUniqueRoleSets
return settings.rolesUniqueRoleSets
.map((set) => ({ name: set.name, roles: set.roles.filter((role) => guildRoles.has(role)) }))
.filter((set) => set.roles.length > 0);
}
Expand All @@ -158,37 +162,27 @@ export class UserCommand extends SkyraSubcommand {
const roles = await args.repeat('roleName');

// Get all rolesets from settings and check if there is an existing set with the name provided by the user
const created = await writeSettings(message.guild, (settings) => {
const allRoleSets = settings.rolesUniqueRoleSets;
const roleSet = allRoleSets.some((set) => set.name === name);

// If it does not exist we need to create a brand new set
if (!roleSet) {
allRoleSets.push({ name, roles: roles.map((role) => role.id) });
return true;
}
await using trx = await writeSettingsTransaction(message.guild);

const entries = trx.settings.rolesUniqueRoleSets;
const index = entries.findIndex((set) => set.name === name);

// If it does not exist we need to create a brand new set
if (index === -1) {
const rolesUniqueRoleSets = entries.concat({ name, roles: roles.map((role) => role.id) });
trx.write({ rolesUniqueRoleSets });
} else {
// The set does exist so we want to only ADD new roles in
// Create a new array that we can use to overwrite the existing one in settings
const sets = allRoleSets.map((set) => {
if (set.name !== name) return set;
const finalRoles = [...set.roles];
for (const role of roles) if (!finalRoles.includes(role.id)) finalRoles.push(role.id);

return { name, roles: finalRoles };
});
settings.rolesUniqueRoleSets = sets;

return false;
});
const entry = entries[index];
const rolesUniqueRoleSets = entries.with(index, { name, roles: entry.roles.concat(roles.map((role) => role.id)) });
trx.write({ rolesUniqueRoleSets });
}
await trx.submit();

return send(
message,
args.t(created ? LanguageKeys.Commands.Admin.RoleSetCreated : LanguageKeys.Commands.Admin.RoleSetAdded, {
name,
roles: roles.map((role) => role.name)
})
);
const created = index === -1;
const key = created ? Root.RoleSetCreated : Root.RoleSetAdded;
return send(message, args.t(key, { name, roles: roles.map((role) => role.name) }));
}

async #getUniqueRoleSets(message: GuildMessage) {
Expand Down
19 changes: 9 additions & 10 deletions src/commands/Management/AutoModeration/automod-words.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { readSettings, writeSettings, type GuildDataKey, type GuildDataValue, type GuildEntity } from '#lib/database';
import { writeSettingsTransaction, type GuildDataKey, type GuildDataValue, type GuildEntity } from '#lib/database';
import { LanguageKeys } from '#lib/i18n/languageKeys';
import { getSupportedUserLanguageT } from '#lib/i18n/translate';
import { AutoModerationCommand } from '#lib/moderation';
Expand Down Expand Up @@ -49,31 +49,30 @@ export class UserAutoModerationCommand extends AutoModerationCommand {
public async chatInputRunAdd(interaction: AutoModerationCommand.Interaction) {
const word = this.#getWord(interaction);
const { guild } = interaction;
const settings = await readSettings(guild);

const t = getSupportedUserLanguageT(interaction);
if (await this.#hasWord(settings, word)) {
await using trx = await writeSettingsTransaction(guild);
if (await this.#hasWord(trx.settings, word)) {
return interaction.reply({ content: t(Root.WordAddFiltered, { word }), ephemeral: true });
}

const updated = settings.selfmodFilterRaw.concat(word);
await writeSettings(guild, [['selfmodFilterRaw', updated]]);
await trx.write({ selfmodFilterRaw: trx.settings.selfmodFilterRaw.concat(word) }).submit();
return interaction.reply({ content: t(Root.EditSuccess), ephemeral: true });
}

public async chatInputRunRemove(interaction: AutoModerationCommand.Interaction) {
const word = this.#getWord(interaction);
const { guild } = interaction;
const settings = await readSettings(guild);

const t = getSupportedUserLanguageT(interaction);
const index = settings.selfmodFilterRaw.indexOf(word);
await using trx = await writeSettingsTransaction(guild);

const index = trx.settings.selfmodFilterRaw.indexOf(word);
if (index === -1) {
return interaction.reply({ content: t(Root.WordRemoveNotFiltered, { word }), ephemeral: true });
}

const updated = settings.selfmodFilterRaw.toSpliced(index, 1);
await writeSettings(guild, [['selfmodFilterRaw', updated]]);
await trx.write({ selfmodFilterRaw: trx.settings.selfmodFilterRaw.toSpliced(index, 1) }).submit();
return interaction.reply({ content: t(Root.EditSuccess), ephemeral: true });
}

Expand Down Expand Up @@ -123,7 +122,7 @@ export class UserAutoModerationCommand extends AutoModerationCommand {
return removeConfusables(interaction.options.getString('word', true).toLowerCase());
}

async #hasWord(settings: GuildEntity, word: string) {
async #hasWord(settings: Readonly<GuildEntity>, word: string) {
const words = settings.selfmodFilterRaw;
if (words.includes(word)) return true;

Expand Down
34 changes: 17 additions & 17 deletions src/commands/Management/Configuration/manage-command-auto-delete.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { readSettings, writeSettings } from '#lib/database';
import { readSettings, writeSettings, writeSettingsTransaction, type CommandAutoDelete } from '#lib/database';
import { LanguageKeys } from '#lib/i18n/languageKeys';
import { SkyraSubcommand } from '#lib/structures';
import { PermissionLevels, type GuildMessage } from '#lib/types';
Expand Down Expand Up @@ -27,38 +27,38 @@ export class UserCommand extends SkyraSubcommand {
const channel = await args.pick('textChannelName');
const time = await args.pick('timespan', { minimum: seconds(1), maximum: minutes(2) });

await writeSettings(message.guild, (settings) => {
const { commandAutoDelete } = settings;
const index = commandAutoDelete.findIndex(([id]) => id === channel.id);
const value: readonly [string, number] = [channel.id, time];
await using trx = await writeSettingsTransaction(message.guild);
const index = trx.settings.commandAutoDelete.findIndex(([id]) => id === channel.id);
const value: CommandAutoDelete = [channel.id, time];

if (index === -1) commandAutoDelete.push(value);
else commandAutoDelete[index] = value;
});
const commandAutoDelete =
index === -1 //
? trx.settings.commandAutoDelete.concat(value)
: trx.settings.commandAutoDelete.with(index, value);
await trx.write({ commandAutoDelete }).submit();

const content = args.t(LanguageKeys.Commands.Management.ManageCommandAutoDeleteAdd, { channel: channel.toString(), time });
return send(message, content);
}

public async remove(message: GuildMessage, args: SkyraSubcommand.Args) {
const channel = await args.pick('textChannelName');
await writeSettings(message.guild, (settings) => {
const { commandAutoDelete } = settings;
const index = commandAutoDelete.findIndex(([id]) => id === channel.id);

if (index === -1) {
this.error(LanguageKeys.Commands.Management.ManageCommandAutoDeleteRemoveNotSet, { channel: channel.toString() });
}
await using trx = await writeSettingsTransaction(message.guild);
const index = trx.settings.commandAutoDelete.findIndex(([id]) => id === channel.id);
if (index === -1) {
this.error(LanguageKeys.Commands.Management.ManageCommandAutoDeleteRemoveNotSet, { channel: channel.toString() });
}

commandAutoDelete.splice(index, 1);
});
const commandAutoDelete = trx.settings.commandAutoDelete.toSpliced(index, 1);
await trx.write({ commandAutoDelete }).submit();

const content = args.t(LanguageKeys.Commands.Management.ManageCommandAutoDeleteRemove, { channel: channel.toString() });
return send(message, content);
}

public async reset(message: GuildMessage, args: SkyraSubcommand.Args) {
await writeSettings(message.guild, [['commandAutoDelete', []]]);
await writeSettings(message.guild, { commandAutoDelete: [] });

const content = args.t(LanguageKeys.Commands.Management.ManageCommandAutoDeleteReset);
return send(message, content);
Expand Down
Loading

0 comments on commit 0450c9c

Please sign in to comment.