From 99ad3d3866f77655e6b367e6524300e8771fb845 Mon Sep 17 00:00:00 2001 From: TrisTOON <36267812+TrisTOON@users.noreply.github.com> Date: Fri, 22 Oct 2021 15:14:31 +0200 Subject: [PATCH] Splits the `type` option of the `/raw` command into subcommands This allows to enforce different min and max values for the `identifier` option of each type. --- src/commands/raw.ts | 110 +++++++++++++++----------------------- src/compilations/raw.ts | 8 --- src/definitions.ts | 2 - src/definitions/raw.json | 10 ---- src/dependencies/raw.d.ts | 2 - 5 files changed, 44 insertions(+), 88 deletions(-) diff --git a/src/commands/raw.ts b/src/commands/raw.ts index 047f6d5..e5fcc8a 100644 --- a/src/commands/raw.ts +++ b/src/commands/raw.ts @@ -1,5 +1,5 @@ import type { - ApplicationCommandOptionChoiceData, + ApplicationCommandSubCommandData, ChatInputCommandInteraction, } from "discord.js"; import type Binding from "../bindings.js"; @@ -16,95 +16,73 @@ import { import * as bindings from "../bindings.js"; import {raw as rawCompilation} from "../compilations.js"; import {raw as rawDefinition} from "../definitions.js"; -import {composeAll, localize, resolve} from "../utils/string.js"; +import {composeAll, localize} from "../utils/string.js"; type HelpGroups = RawDependency["help"]; const { commandName, commandDescription, - typeOptionName, + // typeOptionName, typeOptionDescription, identifierOptionName, identifierOptionDescription, }: RawDefinition = rawDefinition; const { help: helpLocalizations, - noTypeReply: noTypeReplyLocalizations, - noIdentifierReply: noIdentifierReplyLocalizations, }: RawCompilation = rawCompilation; +function naiveSingularForm(pluralForm: string): string { + if (pluralForm.endsWith("ies")) { + return `${pluralForm.slice(0, -3)}y`; + } + return pluralForm.slice(0, -1); +} +function naivePluralForm(singularForm: string): string { + if (singularForm.endsWith("y")) { + return `${singularForm.slice(0, -1)}ies`; + } + return `${singularForm}s`; +} const rawCommand: Command = { register(): ApplicationCommandData { return { name: commandName, description: commandDescription["en-US"], descriptionLocalizations: commandDescription, - options: [ - { - type: ApplicationCommandOptionType.String, - name: typeOptionName, - description: typeOptionDescription["en-US"], - descriptionLocalizations: typeOptionDescription, - required: true, - choices: Object.keys(bindings).map<[string, Binding]>((bindingName: string): [string, Binding] => { - const binding: Binding = bindings[bindingName as keyof typeof bindings]; - return [bindingName, binding]; - }).filter(([bindingName, binding]: [string, Binding]): boolean => { - return binding.length !== 0; - }).map>(([bindingName, binding]: [string, Binding]): ApplicationCommandOptionChoiceData => { - return { - name: bindingName, - value: bindingName, - }; - }), - }, - { - type: ApplicationCommandOptionType.Integer, - name: identifierOptionName, - description: identifierOptionDescription["en-US"], - descriptionLocalizations: identifierOptionDescription, - required: true, - minValue: 0, - }, - ], + options: Object.keys(bindings).map<[string, Binding]>((bindingName: string): [string, Binding] => { + const binding: Binding = bindings[bindingName as keyof typeof bindings] as Binding; + return [bindingName, binding]; + }).filter(([bindingName, binding]: [string, Binding]): boolean => { + return binding.length !== 0; + }).map(([bindingName, binding]: [string, Binding]): ApplicationCommandSubCommandData => { + const subCommandName: string = naiveSingularForm(bindingName); + const subCommandDescription: Localized = commandDescription; + return { + type: ApplicationCommandOptionType.Subcommand, + name: subCommandName, + description: subCommandDescription["en-US"], + descriptionLocalizations: subCommandDescription, + options: [ + { + type: ApplicationCommandOptionType.Integer, + name: identifierOptionName, + description: identifierOptionDescription["en-US"], + descriptionLocalizations: identifierOptionDescription, + required: true, + minValue: 0, + maxValue: binding.length - 1, + }, + ], + }; + }), }; }, async interact(interaction: ApplicationUserInteraction): Promise { if (!interaction.isChatInputCommand()) { return; } - const {locale, options}: ChatInputCommandInteraction<"cached"> = interaction; - const resolvedLocale: Locale = resolve(locale); - const bindingName: string = options.getString(typeOptionName, true); - if (!(bindingName in bindings)) { - const conjunctionFormat: Intl.ListFormat = new Intl.ListFormat(resolvedLocale, { - style: "long", - type: "conjunction", - }); - await interaction.reply({ - content: noTypeReplyLocalizations[resolvedLocale]({ - typeConjunction: (): string => { - return conjunctionFormat.format(Object.keys(bindings).map((bindingName: string): string => { - return `\`${escapeMarkdown(bindingName)}\``; - })); - }, - }), - ephemeral: true, - }); - return; - } - const binding: Binding = bindings[bindingName as keyof typeof bindings]; + const {options}: ChatInputCommandInteraction<"cached"> = interaction; + const bindingName: string = naivePluralForm(options.getSubcommand(true)); + const binding: Binding = bindings[bindingName as keyof typeof bindings] as Binding; const identifier: number = options.getInteger(identifierOptionName, true); - if (identifier < 0 || identifier >= binding.length) { - const max: number = binding.length - 1; - await interaction.reply({ - content: noIdentifierReplyLocalizations[resolvedLocale]({ - max: (): string => { - return escapeMarkdown(`${max}`); - }, - }), - ephemeral: true, - }); - return; - } const datum: string = JSON.stringify(binding[identifier], null, "\t"); await interaction.reply({ content: `\`\`\`json\n${escapeMarkdown(datum)}\n\`\`\``, diff --git a/src/compilations/raw.ts b/src/compilations/raw.ts index cd58e18..efc349d 100644 --- a/src/compilations/raw.ts +++ b/src/compilations/raw.ts @@ -3,19 +3,11 @@ import type {Localized} from "../utils/string.js"; import {raw} from "../definitions.js"; import {compileAll} from "../utils/string.js"; type HelpLocalizations = Localized<(groups: Raw["help"]) => string>; -type NoTypeReplyLocalizations = Localized<(groups: Raw["noTypeReply"]) => string>; -type NoIdentifierReplyLocalizations = Localized<(groups: Raw["noIdentifierReply"]) => string>; type RawCompilation = { help: HelpLocalizations, - noTypeReply: NoTypeReplyLocalizations, - noIdentifierReply: NoIdentifierReplyLocalizations, }; const helpLocalizations: HelpLocalizations = compileAll(raw["help"]); -const noTypeReplyLocalizations: NoTypeReplyLocalizations = compileAll(raw["noTypeReply"]); -const noIdentifierReplyLocalizations: NoIdentifierReplyLocalizations = compileAll(raw["noIdentifierReply"]); const rawCompilation: RawCompilation = { help: helpLocalizations, - noTypeReply: noTypeReplyLocalizations, - noIdentifierReply: noIdentifierReplyLocalizations, }; export default rawCompilation; diff --git a/src/definitions.ts b/src/definitions.ts index 7f562f9..380cfe2 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -212,8 +212,6 @@ type Raw = { identifierOptionName: string, identifierOptionDescription: Localized, help: Localized, - noTypeReply: Localized, - noIdentifierReply: Localized, }; type Record = { hookName: string, diff --git a/src/definitions/raw.json b/src/definitions/raw.json index 042a737..89bbada 100644 --- a/src/definitions/raw.json +++ b/src/definitions/raw.json @@ -21,15 +21,5 @@ "en-US": "Type $ `$ $` to know what is the datum of `$` with `$`", "fr": "Tape $ `$ $` pour savoir quel est la donnée d'`$` avec `$`", "pt-BR": "Digite $ `$ $` pra saber qual é o Datum de `$` com `$`" - }, - "noTypeReply": { - "en-US": "I do not know any datum with this name.\nPlease give me a type among $ instead.", - "fr": "Je ne connais aucune donnée avec ce nom.\nMerci de me donner un type parmi $ à la place.", - "pt-BR": "Eu não conheço nenhum Datum com esse nome.\nPor favor, me dê um tipo entre $ em vez disso." - }, - "noIdentifierReply": { - "en-US": "I do not know any datum with this identifier.\nPlease give me an identifier between `0` and `$` instead.", - "fr": "Je ne connais aucune donnée avec cet identifiant.\nMerci de me donner un identifiant entre `0` et `$` à la place.", - "pt-BR": "Eu não conheço nenhum Datum com esse nome.\nPor favor, me dê um tipo entre `0` e `$` em vez disso." } } diff --git a/src/dependencies/raw.d.ts b/src/dependencies/raw.d.ts index b126dc9..71857ca 100644 --- a/src/dependencies/raw.d.ts +++ b/src/dependencies/raw.d.ts @@ -11,7 +11,5 @@ type NoIdentifierReplyGroups = { }; type RawDependency = { help: HelpGroups, - noTypeReply: NoTypeReplyGroups, - noIdentifierReply: NoIdentifierReplyGroups, }; export type {RawDependency as default};