From ea82c2f91c4aa4ed69124e3c94e0175f6de318c8 Mon Sep 17 00:00:00 2001 From: Aaron Sandoval Date: Fri, 21 Jun 2024 15:17:13 -0700 Subject: [PATCH 1/4] fix: seyfert fix --- src/structures/client/Stelle.ts | 27 ++++++++++++--------- src/structures/utils/functions/overrides.ts | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/structures/client/Stelle.ts b/src/structures/client/Stelle.ts index 883457a..92b1aeb 100644 --- a/src/structures/client/Stelle.ts +++ b/src/structures/client/Stelle.ts @@ -15,6 +15,7 @@ import { StelleDatabase } from "./modules/Database.js"; import { StelleManager } from "./modules/Manager.js"; import { THINK_MESSAGES } from "#stelle/data/Constants.js"; +import { HandleCommand } from "seyfert/lib/commands/handle.js"; /** * Main Stelle class. @@ -57,12 +58,6 @@ export class Stelle extends Client { onPermissionsFail, onRunError, }, - argsParser: YunaParser({ - useUniqueNamedSyntaxAtSameTime: true, - enabled: { - namedOptions: ["-", "--"], - }, - }), deferReplyResponse: ({ client }) => ({ content: ` **${client.me.username}** ${ THINK_MESSAGES[Math.floor(Math.random() * THINK_MESSAGES.length)] @@ -92,13 +87,21 @@ export class Stelle extends Client { getWatermark(); this.setServices({ - middlewares: StelleMiddlewares, - langs: { - default: this.config.defaultLocale, - aliases: { - "es-419": ["es-ES"], - }, + middlewares: StelleMiddlewares, + langs: { + default: this.config.defaultLocale, + aliases: { + "es-419": ["es-ES"], }, + }, + handleCommand: class extends HandleCommand { + argsParser = YunaParser({ + useUniqueNamedSyntaxAtSameTime: true, + enabled: { + namedOptions: ["-", "--"], + }, + }); + }, }); await this.start(); diff --git a/src/structures/utils/functions/overrides.ts b/src/structures/utils/functions/overrides.ts index 0ba37a8..d2343bd 100644 --- a/src/structures/utils/functions/overrides.ts +++ b/src/structures/utils/functions/overrides.ts @@ -7,7 +7,7 @@ import { EmbedColors } from "seyfert/lib/common/index.js"; import { formatOptions } from "./formatter.js"; import { codeBlock } from "./utils.js"; -export async function onRunError(ctx: AnyContext, error: Error) { +export async function onRunError(ctx: AnyContext, error: unknown) { const { messages } = ctx.t.get(await ctx.getLocale()); ctx.client.logger.error(error); From fc6fb43a43173500cbd963761c17e3ca57fc7e6c Mon Sep 17 00:00:00 2001 From: JustEvil Date: Sun, 23 Jun 2024 19:43:35 -0600 Subject: [PATCH 2/4] :zap: update (bot :package:): Updating stelle. :pencil2: - Moved from seyfert v1 to v2. - Fixed lavalink Stelle events - Used new version of yunaforseyfert --- package.json | 6 +- pnpm-lock.yaml | 42 ++- src/commands/developer/eval.ts | 20 +- src/structures/client/Stelle.ts | 35 +- src/structures/parser/README.md | 5 - src/structures/parser/index.ts | 2 - .../parser/utils/parser/choicesResolver.ts | 47 --- .../parser/utils/parser/createConfig.ts | 318 ---------------- src/structures/parser/utils/parser/parser.ts | 353 ------------------ .../utils/classes/client/Handler.ts | 9 +- tsconfig.json | 1 - 11 files changed, 77 insertions(+), 761 deletions(-) delete mode 100644 src/structures/parser/README.md delete mode 100644 src/structures/parser/index.ts delete mode 100644 src/structures/parser/utils/parser/choicesResolver.ts delete mode 100644 src/structures/parser/utils/parser/createConfig.ts delete mode 100644 src/structures/parser/utils/parser/parser.ts diff --git a/package.json b/package.json index 92698fb..2c649cf 100644 --- a/package.json +++ b/package.json @@ -42,13 +42,14 @@ "kazagumo-spotify": "^2.1.0", "ms": "^2.1.3", "seyfert": "github:tiramisulabs/seyfert", - "shoukaku": "github:shipgirlproject/Shoukaku" + "shoukaku": "github:shipgirlproject/Shoukaku", + "yunaforseyfert": "github:SagiriIkeda/yunaforseyfert#experimental" }, "devDependencies": { "@biomejs/biome": "^1.8.2", "@types/humanize-duration": "^3.27.4", "@types/ms": "^0.7.34", - "@types/node": "^20.14.7", + "@types/node": "^20.14.8", "husky": "^9.0.11", "lint-staged": "^15.2.7", "prisma": "^5.15.1", @@ -62,7 +63,6 @@ "#stelle/middlwares": "./dist/middlewares/index.js", "#stelle/errors": "./dist/structures/utils/Errors.js", "#stelle/decorators": "./dist/structures/utils/Decorators.js", - "#stelle/parser": "./dist/structures/parser/index.js", "#stelle/index": "./dist/index.js", "#stelle/data/*": "./dist/structures/utils/data/*", "#stelle/utils/*": "./dist/structures/utils/*" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 004b1e5..8e2aec4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,10 +34,13 @@ importers: version: 2.1.3 seyfert: specifier: github:tiramisulabs/seyfert - version: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/017ccfc3bf8a12c7fb3503fb7d1ee65bce1444dc + version: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee shoukaku: specifier: github:shipgirlproject/Shoukaku version: https://codeload.github.com/shipgirlproject/Shoukaku/tar.gz/8d77908cfc903456613942f607cff207dda57b6f + yunaforseyfert: + specifier: github:SagiriIkeda/yunaforseyfert#experimental + version: https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/a38ed0f3f674035064ddbb75ceda67e6997791e6 devDependencies: '@biomejs/biome': specifier: ^1.8.2 @@ -49,8 +52,8 @@ importers: specifier: ^0.7.34 version: 0.7.34 '@types/node': - specifier: ^20.14.7 - version: 20.14.7 + specifier: ^20.14.8 + version: 20.14.8 husky: specifier: ^9.0.11 version: 9.0.11 @@ -159,8 +162,8 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - '@types/node@20.14.7': - resolution: {integrity: sha512-uTr2m2IbJJucF3KUxgnGOZvYbN0QgkGyWxG6973HCpMYFy2KfcgYuIwkJQMQkt1VbBMlvWRbpshFTLxnxCZjKQ==} + '@types/node@20.14.8': + resolution: {integrity: sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==} ansi-escapes@6.2.1: resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} @@ -340,8 +343,8 @@ packages: engines: {node: '>=18.12.0'} hasBin: true - listr2@8.2.2: - resolution: {integrity: sha512-sy0dq+JPS+RAFiFk2K8Nbub7khNmeeoFALNUJ4Wzk34wZKAzaOhEXqGWs4RA5aui0RaM6Hgn7VEKhCj0mlKNLA==} + listr2@8.2.3: + resolution: {integrity: sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==} engines: {node: '>=18.0.0'} lodash.defaults@4.2.0: @@ -449,8 +452,8 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - seyfert@https://codeload.github.com/tiramisulabs/seyfert/tar.gz/017ccfc3bf8a12c7fb3503fb7d1ee65bce1444dc: - resolution: {tarball: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/017ccfc3bf8a12c7fb3503fb7d1ee65bce1444dc} + seyfert@https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee: + resolution: {tarball: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee} version: 1.5.0 shebang-command@2.0.0: @@ -572,6 +575,10 @@ packages: engines: {node: '>= 14'} hasBin: true + yunaforseyfert@https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/a38ed0f3f674035064ddbb75ceda67e6997791e6: + resolution: {tarball: https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/a38ed0f3f674035064ddbb75ceda67e6997791e6} + version: 1.0.0 + snapshots: '@biomejs/biome@1.8.2': @@ -643,7 +650,7 @@ snapshots: '@types/ms@0.7.34': {} - '@types/node@20.14.7': + '@types/node@20.14.8': dependencies: undici-types: 5.26.5 @@ -819,7 +826,7 @@ snapshots: debug: 4.3.5 execa: 8.0.1 lilconfig: 3.1.2 - listr2: 8.2.2 + listr2: 8.2.3 micromatch: 4.0.7 pidtree: 0.6.0 string-argv: 0.3.2 @@ -827,7 +834,7 @@ snapshots: transitivePeerDependencies: - supports-color - listr2@8.2.2: + listr2@8.2.3: dependencies: cli-truncate: 4.0.0 colorette: 2.0.20 @@ -924,7 +931,7 @@ snapshots: rfdc@1.4.1: {} - seyfert@https://codeload.github.com/tiramisulabs/seyfert/tar.gz/017ccfc3bf8a12c7fb3503fb7d1ee65bce1444dc: + seyfert@https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee: dependencies: chokidar: 3.6.0 discord-api-types: 0.37.90 @@ -1042,3 +1049,12 @@ snapshots: ws@8.17.1: {} yaml@2.4.5: {} + + yunaforseyfert@https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/a38ed0f3f674035064ddbb75ceda67e6997791e6: + dependencies: + discord-api-types: 0.37.90 + seyfert: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate diff --git a/src/commands/developer/eval.ts b/src/commands/developer/eval.ts index 2596e24..2897106 100644 --- a/src/commands/developer/eval.ts +++ b/src/commands/developer/eval.ts @@ -15,9 +15,10 @@ import { StelleOptions } from "#stelle/decorators"; import { Configuration } from "#stelle/data/Configuration.js"; import { codeBlock, getDepth, sliceText } from "#stelle/utils/functions/utils.js"; +import { DeclareParserConfig, ParserRecommendedConfig, Watch, Yuna } from "yunaforseyfert"; import { SECRETS_MESSAGES, SECRETS_REGEX } from "#stelle/data/Constants.js"; -import { DeclareParserConfig, ParserRecommendedConfig } from "#stelle/parser"; +import ms from "ms"; const options = { code: createStringOption({ @@ -42,6 +43,23 @@ const options = { @StelleOptions({ onlyDeveloper: true }) @DeclareParserConfig(ParserRecommendedConfig.Eval) export default class EvalCommand extends Command { + @Watch({ + idle: ms("1min"), + beforeCreate(ctx) { + const userWatcher = Yuna.watchers.findInstances(ctx.client, { + userId: ctx.author.id, + command: this, + }); + if (!userWatcher) return; + + const [watcher] = userWatcher.instances; + + watcher?.stopAll("Another instance of command created."); + }, + onStop(reason) { + this.ctx?.editOrReply({ content: `Watcher stoped: ${reason}`, embeds: [] }); + }, + }) async run(ctx: CommandContext): Promise { const { client, options, author, member, channelId } = ctx; diff --git a/src/structures/client/Stelle.ts b/src/structures/client/Stelle.ts index 92b1aeb..464113b 100644 --- a/src/structures/client/Stelle.ts +++ b/src/structures/client/Stelle.ts @@ -4,7 +4,6 @@ import { Client, LimitedCollection } from "seyfert"; import type { InternalRuntime, InternalStelleRuntime, StelleConfiguration } from "#stelle/types"; import { StelleMiddlewares } from "#stelle/middlwares"; -import { YunaParser } from "#stelle/parser"; import { Configuration } from "#stelle/data/Configuration.js"; import { getWatermark } from "#stelle/utils/Logger.js"; @@ -14,8 +13,9 @@ import { customContext, stelleRC } from "#stelle/utils/functions/utils.js"; import { StelleDatabase } from "./modules/Database.js"; import { StelleManager } from "./modules/Manager.js"; -import { THINK_MESSAGES } from "#stelle/data/Constants.js"; import { HandleCommand } from "seyfert/lib/commands/handle.js"; +import { Yuna } from "yunaforseyfert"; +import { THINK_MESSAGES } from "#stelle/data/Constants.js"; /** * Main Stelle class. @@ -87,21 +87,24 @@ export class Stelle extends Client { getWatermark(); this.setServices({ - middlewares: StelleMiddlewares, - langs: { - default: this.config.defaultLocale, - aliases: { - "es-419": ["es-ES"], + middlewares: StelleMiddlewares, + handleCommand: class extends HandleCommand { + argsParser = Yuna.parser({ + syntax: { + namedOptions: ["-", "--"], + }, + }); + resolveCommandFromContent = Yuna.resolver({ + client: this.client, + afterPrepare: (metadata) => this.client.logger.debug(`Client - Ready to use ${metadata.commands.length} commands.`), + }); + }, + langs: { + default: this.config.defaultLocale, + aliases: { + "es-419": ["es-ES"], + }, }, - }, - handleCommand: class extends HandleCommand { - argsParser = YunaParser({ - useUniqueNamedSyntaxAtSameTime: true, - enabled: { - namedOptions: ["-", "--"], - }, - }); - }, }); await this.start(); diff --git a/src/structures/parser/README.md b/src/structures/parser/README.md deleted file mode 100644 index b29f86e..0000000 --- a/src/structures/parser/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## ARGS PARSER - -> This parser was made by a friend, you can check [the repository](https://github.com/SagiriIkeda/yunaforseyfert/) if you are interested on it. -> * Leave a ⭐ to give support. -> * *Da penwis loves taiscri 🐧🐐💪* \ No newline at end of file diff --git a/src/structures/parser/index.ts b/src/structures/parser/index.ts deleted file mode 100644 index 87035fd..0000000 --- a/src/structures/parser/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { YunaParser } from "./utils/parser/parser.js"; -export { DeclareParserConfig, ParserRecommendedConfig } from "./utils/parser/createConfig.js"; diff --git a/src/structures/parser/utils/parser/choicesResolver.ts b/src/structures/parser/utils/parser/choicesResolver.ts deleted file mode 100644 index ab6dd31..0000000 --- a/src/structures/parser/utils/parser/choicesResolver.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { CommandOption, SeyfertNumberOption, SeyfertStringOption } from "seyfert"; -import { type CommandYunaMetaDataConfig, type YunaParserCreateOptions, type YunaParserUsableCommand, keyMetadata } from "./createConfig.js"; - -const getChoicesOptions = (commandMetadata: CommandYunaMetaDataConfig) => { - const inCache = commandMetadata.choicesOptions?.decored; - if (inCache) return inCache; - - const decored: NonNullable["decored"] = {}; - - for (const option of commandMetadata.options as ((SeyfertStringOption | SeyfertNumberOption) & CommandOption)[]) { - if (!option.choices?.length) continue; - - decored[option.name] = option.choices.map(({ name, value }) => [name, name.toLowerCase(), value.toString().toLowerCase()]); - } - - if (commandMetadata.choicesOptions) commandMetadata.choicesOptions.decored = decored; - - return decored; -}; - -export const YunaParserOptionsChoicesResolver = ( - command: YunaParserUsableCommand, - namesOfOptionsWithChoices: string[], - result: Record, - config: YunaParserCreateOptions, -) => { - const commandMetadata = command[keyMetadata]; - if (!commandMetadata) return; - - const choiceOptions = getChoicesOptions(commandMetadata); - if (!choiceOptions) return; - - const canUseDirectlyValue = config.resolveCommandOptionsChoices?.canUseDirectlyValue === true; - - for (const optionName of namesOfOptionsWithChoices) { - const choices = choiceOptions?.[optionName]; - const optionValue = result[optionName]; - - if (!choices || optionValue === undefined) continue; - - const finderText = optionValue.toLowerCase(); - - const choiceName = choices?.find(([, name, value]) => name === finderText || (canUseDirectlyValue && value === finderText))?.[0]; - - if (choiceName !== undefined) result[optionName] = choiceName; - } -}; diff --git a/src/structures/parser/utils/parser/createConfig.ts b/src/structures/parser/utils/parser/createConfig.ts deleted file mode 100644 index 28eafab..0000000 --- a/src/structures/parser/utils/parser/createConfig.ts +++ /dev/null @@ -1,318 +0,0 @@ -import { ApplicationCommandOptionType } from "discord-api-types/v10"; -import type { Command, CommandOption, SeyfertNumberOption, SeyfertStringOption, SubCommand } from "seyfert"; - -type ValidLongTextTags = "'" | '"' | "`"; -type ValidNamedOptionSyntax = "-" | "--" | ":"; - -export interface YunaParserCreateOptions { - /** - * this only show console.log with the options parsed. - * @defaulst false */ - logResult?: boolean; - - enabled?: { - /** especify what longText tags you want - * - * ` " ` => `"penguin life"` - * - * ` ' ` => `'beautiful sentence'` - * - * **`** => **\`LiSA『Shouted Serenade』 is a good track\`** - * - * @default 🐧 all enabled - */ - longTextTags?: [ValidLongTextTags?, ValidLongTextTags?, ValidLongTextTags?]; - /** especify what named syntax you want - * - * ` - ` -option content value - * - * ` -- ` --option content value - * - * ` : ` option: content value - * - * @default 🐧 all enabled - */ - namedOptions?: [ValidNamedOptionSyntax?, ValidNamedOptionSyntax?, ValidNamedOptionSyntax?]; - }; - - /** - * Turning it on can be useful for when once all the options are obtained, - * the last one can take all the remaining content, ignoring any other syntax. - * @default {false} - */ - breakSearchOnConsumeAllOptions?: boolean; - - /** - * Limit that you can't use named syntax "-" and ":" at the same time, - * but only the first one used, sometimes it's useful to avoid confusion. - * @default {false} - */ - useUniqueNamedSyntaxAtSameTime?: boolean; - - /** - * This disables the use of longTextTags in the last option - * @default {false} - */ - disableLongTextTagsInLastOption?: boolean; - - /** Use Yuna's choice resolver instead of the default one, put null if you don't want it, - * - * YunaChoiceResolver allows you to search through choices regardless of case or lowercase, - * as well as allowing direct use of an choice's value, - * and not being forced to use only the name. - * - * @default enabled - */ - resolveCommandOptionsChoices?: { - /** Allow you to use the value of a choice directly, not necessarily search by name - * @default {true} - */ - canUseDirectlyValue?: boolean; - } | null; -} - -type EscapeModeType = Record; - -const RemoveNamedEscapeModeKeys = ["All", "forNamed", "forNamedDotted"]; - -export const RemoveFromCheckNextChar = (regex: RegExp, char: "\\-" | ":") => { - return new RegExp(regex.source.replace(char, ""), regex.flags); -}; - -export const RemoveNamedEscapeMode = (EscapeMode: EscapeModeType, char: "\\-" | ":") => { - for (const mode of RemoveNamedEscapeModeKeys) { - const regx = EscapeMode[mode]; - if (!regx) continue; - - const regexStr = regx.source.replace(char, ""); - - EscapeMode[mode] = new RegExp(regexStr, EscapeMode[mode]?.flags); - } - - return EscapeMode; -}; -export const RemoveLongCharEscapeMode = (EscapeMode: EscapeModeType) => { - const regx = EscapeMode.All; - if (!regx) return; - - const regexStr = regx.source.replace(/\\"|\\'|\\`/g, ""); - - EscapeMode.All = new RegExp(regexStr, EscapeMode.All?.flags); - - return EscapeMode; -}; - -export const createRegexs = ({ enabled }: YunaParserCreateOptions) => { - const hasAnyLongTextTag = (enabled?.longTextTags?.length ?? 0) >= 1; - const hasAnyNamedSyntax = (enabled?.namedOptions?.length ?? 0) >= 1; - - const hasAnyEspecialSyntax = hasAnyNamedSyntax || hasAnyLongTextTag; - - const backescape = hasAnyEspecialSyntax ? "\\\\" : ""; - - const escapeModes: EscapeModeType = {}; - - const syntaxes: string[] = []; - - const has1HaphenSyntax = enabled?.namedOptions?.includes("-"); - const has2HaphenSyntax = enabled?.namedOptions?.includes("--"); - const hasDottedSyntax = enabled?.namedOptions?.includes(":"); - - const escapedLongTextTags = - enabled?.longTextTags - ?.map((tag) => { - escapeModes[tag!] = new RegExp(`(\\\\+)([${tag}\\s]|$)`, "g"); - - return `\\${tag}`; - }) - .join("") ?? ""; - - let checkNextChar: RegExp | undefined = undefined; - - if (hasAnyEspecialSyntax) { - const extras: string[] = []; - - (has1HaphenSyntax || has2HaphenSyntax) && extras.push("\\-"); - hasDottedSyntax && extras.push(":"); - - const render = `${escapedLongTextTags}${extras.join("")}`; - - escapeModes.All = new RegExp(`(\\\\+)([${render}\\s]|$)`); - - checkNextChar = new RegExp(`[${render}\\s]|$`); - - syntaxes.push(`(?[${render}])`); - } - - syntaxes.push(`(?[^\\s\\x7F${escapedLongTextTags}${backescape}]+)`); - - if (hasAnyNamedSyntax) { - const namedSyntaxes: string[] = []; - - if (has1HaphenSyntax || has2HaphenSyntax) { - const HaphenLength = []; - - has1HaphenSyntax && HaphenLength.push(1); - has2HaphenSyntax && HaphenLength.push(2); - - namedSyntaxes.push(`(?-{${HaphenLength.join(",")}})(?[a-zA-Z_\\d]+)`); - escapeModes.forNamed = /(\\+)([\:\s\-]|$)/g; - } else { - RemoveNamedEscapeMode(escapeModes, "\\-"); - } - - if (hasDottedSyntax) { - namedSyntaxes.push("(?[a-zA-Z_\\d]+)(?:)(?!\\/\\/[^\\s\\x7F])"); - escapeModes.forNamedDotted = /(\\+)([\:\s\-\/]|$)/g; - } else { - RemoveNamedEscapeMode(escapeModes, ":"); - } - - namedSyntaxes.length && syntaxes.unshift(`(?(\\\\*)(?:${namedSyntaxes.join("|")}))`); - } - - if (backescape) { - syntaxes.push("(?\\\\+)"); - } - - return { - elementsRegex: RegExp(syntaxes.join("|"), "g"), - escapeModes: escapeModes, - checkNextChar, - }; -}; - -const removeDuplicates = (arr: A extends Array ? R[] : never[]): A => { - return [...new Set(arr)] as A; -}; - -export const createConfig = (config: YunaParserCreateOptions, isFull = true) => { - const newConfig: YunaParserCreateOptions = {}; - - if (isFull || (config.enabled && (config.enabled.longTextTags || config.enabled.namedOptions))) { - newConfig.enabled ??= {}; - - if (isFull || config?.enabled?.longTextTags) - newConfig.enabled.longTextTags = removeDuplicates(config?.enabled?.longTextTags ?? ['"', "'", "`"]); - if (isFull || config?.enabled?.namedOptions) - newConfig.enabled.namedOptions = removeDuplicates(config?.enabled?.namedOptions ?? ["-", "--", ":"]); - } - - if (isFull || "breakSearchOnConsumeAllOptions" in config) - newConfig.breakSearchOnConsumeAllOptions = config.breakSearchOnConsumeAllOptions === true; - if (isFull || "useUniqueNamedSyntaxAtSameTime" in config) - newConfig.useUniqueNamedSyntaxAtSameTime = config.useUniqueNamedSyntaxAtSameTime === true; - if (isFull || "logResult" in config) newConfig.logResult = config.logResult === true; - if (isFull || "disableLongTextTagsInLastOption" in config) - newConfig.disableLongTextTagsInLastOption = config.disableLongTextTagsInLastOption === true; - if (isFull || "resolveCommandOptionsChoices" in config) - newConfig.resolveCommandOptionsChoices = - config.resolveCommandOptionsChoices === null - ? null - : { - canUseDirectlyValue: !(config.resolveCommandOptionsChoices?.canUseDirectlyValue === false), - }; - - return newConfig; -}; - -export interface CommandYunaMetaDataConfig { - options?: CommandOption[]; - config?: YunaParserCreateOptions; - regexes?: ReturnType; - choicesOptions?: { - names: string[]; - decored?: Record; - }; -} - -export const keyMetadata = Symbol("YunaParserMetaData"); -const keyConfig = Symbol("YunaParserConfig"); - -export type YunaParserUsableCommand = (Command | SubCommand) & { - [keyMetadata]?: CommandYunaMetaDataConfig; - [keyConfig]?: YunaParserCreateOptions; -}; - -export const ParserRecommendedConfig = { - /** things that I consider necessary in an Eval command. */ - Eval: { - breakSearchOnConsumeAllOptions: true, - disableLongTextTagsInLastOption: true, - }, -} satisfies Record; - -export function DeclareParserConfig(config: YunaParserCreateOptions = {}) { - return (target: T) => { - if (!Object.keys(config).length) return target; - - return class extends target { - [keyConfig] = createConfig(config, false); - }; - }; -} - -type Object = Record; - -const isObject = (obj: unknown): obj is Object => typeof obj === "object" && obj !== null && !Array.isArray(obj); - -const mergeObjects = (obj: A, obj2: B): (A & B) | B => { - if (!(isObject(obj) && isObject(obj2))) return obj2; - - const merged = { ...obj }; - - if (!isObject(obj)) return obj2; - - for (const key of Object.keys(obj2)) { - const oldValue = merged[key]; - const value = obj2[key]; - - merged[key as keyof A & B] = mergeObjects(oldValue, value); - } - - return merged as A & B; -}; - -const InvalidOptionType = new Set([ - ApplicationCommandOptionType.Attachment, - ApplicationCommandOptionType.Subcommand, - ApplicationCommandOptionType.SubcommandGroup, -]); - -export const getYunaMetaDataFromCommand = (config: YunaParserCreateOptions, command: YunaParserUsableCommand) => { - const InCache = command[keyMetadata]; - if (InCache) return InCache; - - const metadata: CommandYunaMetaDataConfig = { - options: command.options?.filter((option) => "type" in option && !InvalidOptionType.has(option.type)) as - | CommandOption[] - | undefined, - }; - - const commandConfig = command[keyConfig]; - - if (commandConfig) { - const realConfig = mergeObjects(config, commandConfig); - - metadata.config = realConfig; - metadata.regexes = createRegexs(realConfig); - } - - if (metadata.options?.length) { - const namesOfOptionsWithChoices: string[] = []; - - for (const option of metadata.options as ((SeyfertStringOption | SeyfertNumberOption) & CommandOption)[]) { - if (!option.choices?.length) continue; - - namesOfOptionsWithChoices.push(option.name); - } - - metadata.choicesOptions = { - names: namesOfOptionsWithChoices, - }; - } - - command[keyMetadata] = metadata; - - return metadata; -}; diff --git a/src/structures/parser/utils/parser/parser.ts b/src/structures/parser/utils/parser/parser.ts deleted file mode 100644 index 316c4c7..0000000 --- a/src/structures/parser/utils/parser/parser.ts +++ /dev/null @@ -1,353 +0,0 @@ -import type { Command, SubCommand } from "seyfert"; -import { YunaParserOptionsChoicesResolver } from "./choicesResolver.js"; -import { - RemoveFromCheckNextChar, - RemoveLongCharEscapeMode, - RemoveNamedEscapeMode, - type YunaParserCreateOptions, - createConfig, - createRegexs as createRegexes, - getYunaMetaDataFromCommand, -} from "./createConfig.js"; - -const InvalidTagsToBeLong = new Set(["-", ":"]); - -const evaluateBackescapes = ( - backspaces: string, - nextChar: string, - regexToCheckNextChar: RegExp | undefined, - isDisabledLongTextTagsInLastOption?: boolean, -) => { - const isJustPair = backspaces.length % 2 === 0; - - const isPossiblyEscapingNext = - !isJustPair && (/["'`]/.test(nextChar) && isDisabledLongTextTagsInLastOption ? false : regexToCheckNextChar?.test(nextChar)); - - const strRepresentation = "\\".repeat(Math.floor(backspaces.length / 2)) + (isJustPair || isPossiblyEscapingNext ? "" : "\\"); - - return { isPossiblyEscapingNext, strRepresentation }; -}; - -const sanitizeBackescapes = (text: string, regx: RegExp | undefined, regexToCheckNextChar: RegExp | undefined) => - regx - ? text.replace(regx, (_, backescapes, next) => { - const { strRepresentation } = evaluateBackescapes(backescapes, next[0], regexToCheckNextChar); - - return strRepresentation + next; - }) - : text; - -const spacesRegex = /[\s\x7F\n]/; - -/** - * 🐧 - * @example - * ```js - * import { YunaParser } from "yunaforseyfert" - * - * new Client({ - commands: { - argsParser: YunaParser() - } - }); - * ``` - */ - -export const YunaParser = (config: YunaParserCreateOptions = {}) => { - config = createConfig(config); - - const globalRegexes = createRegexes(config); - - // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: omitting this rule the life is better - return (content: string, command: Command | SubCommand): Record => { - const { options, config: commandConfig, regexes: commandRegexes, choicesOptions } = getYunaMetaDataFromCommand(config, command); - - const realConfig = commandConfig ?? config; - - const regexes = commandRegexes ?? globalRegexes; - const { elementsRegex, escapeModes: __realEscapeModes } = regexes; - let { checkNextChar } = regexes; - - const validNamedOptionSyntaxes = Object.fromEntries(realConfig.enabled?.namedOptions?.map((t) => [t, true]) ?? []); - - const { breakSearchOnConsumeAllOptions, useUniqueNamedSyntaxAtSameTime, disableLongTextTagsInLastOption } = realConfig; - - if (!options) return {}; - - const localEscapeModes = { ...__realEscapeModes }; - - const matches = content.matchAll(elementsRegex); - - let tagOpenWith: '"' | "'" | "`" | "-" | null = null; - let tagOpenPosition: number | null = null; - let actualOptionIdx: number = 0; - let isEscapingNext = false; - let unindexedRightText = ""; - - let namedOptionTagUsed: string | undefined; - - let namedOptionInitialized: { - name: string; - start: number; - dotted: boolean; - } | null = null; - - let lastestLongWord: { start: number; name: string; unindexedRightText: string } | undefined; - - let lastOptionNameAdded: string | undefined; - let isRecentlyClosedAnyTag = false; - - const result: Record = {}; - - const aggregateNextOption = (value: string, start: number | null) => { - if (start === null && unindexedRightText) { - const savedUnindexedText = unindexedRightText; - unindexedRightText = ""; - aggregateNextOption(savedUnindexedText, null); - } - - const optionAtIndexName = options[actualOptionIdx]?.name; - - if (!optionAtIndexName) return; - - const isLastOption = actualOptionIdx === options.length - 1; - - if (isLastOption && start !== null) { - lastestLongWord = { - start, - name: optionAtIndexName, - unindexedRightText, - }; - } - - result[optionAtIndexName] = unindexedRightText + value; - unindexedRightText = ""; - - actualOptionIdx++; - - lastOptionNameAdded = optionAtIndexName; - - return lastOptionNameAdded; - }; - - const aggregateLastestLongWord = (end: number = content.length, postText = "") => { - if (!lastestLongWord) return; - - const { name, start, unindexedRightText } = lastestLongWord; - - lastestLongWord = undefined; - - if (disableLongTextTagsInLastOption) { - RemoveLongCharEscapeMode(localEscapeModes); - } - - const canUseAsLiterally = disableLongTextTagsInLastOption && breakSearchOnConsumeAllOptions && end === content.length; - - const slicedContent = content.slice(start, end); - - result[name] = ( - unindexedRightText + - (canUseAsLiterally ? slicedContent : sanitizeBackescapes(slicedContent, localEscapeModes.All, checkNextChar) + postText) - ).trim(); - return; - }; - - const aggregateUnindexedText = ( - textPosition: number, - text: string, - precedentText = "", - realText = text, - enableRight = true, - isRecentlyClosedAnyTag = false, - ) => { - if (namedOptionInitialized) return; - - const backPosition = textPosition - (precedentText.length + 1); - const nextPosition = textPosition + realText.length; - - const backChar = content[backPosition]; - const nextChar = content[nextPosition]; - - if ( - !unindexedRightText && - lastOptionNameAdded && - !isRecentlyClosedAnyTag && - backChar && - !spacesRegex.test(backChar) /* placeIsForLeft */ - ) { - result[lastOptionNameAdded] += text; - return; - } - - if (enableRight && nextChar && !spacesRegex.test(nextChar) /* placeIsForRight */) { - unindexedRightText += text; - return; - } - - aggregateNextOption(text, textPosition); - }; - - const aggregateTagLongText = (tag: string, start: number, end?: number) => { - const value = content.slice(start, end); - tagOpenWith = null; - tagOpenPosition = null; - isRecentlyClosedAnyTag = true; - const reg = localEscapeModes[tag as keyof typeof localEscapeModes]; - - aggregateNextOption(reg ? sanitizeBackescapes(value, reg, checkNextChar) : value, null); - }; - - const aggregateNextNamedOption = (end: number) => { - if (!namedOptionInitialized) return; - const { name, start, dotted } = namedOptionInitialized; - - const escapeModeType = dotted ? "forNamedDotted" : "forNamed"; - const escapeMode = localEscapeModes[escapeModeType]; - - const value = sanitizeBackescapes(content.slice(start, end).trimStart(), escapeMode, checkNextChar).trim(); - - namedOptionInitialized = null; - - if (result[name] === undefined) actualOptionIdx++; - - result[name] = value; - - lastOptionNameAdded = name; - return name; - }; - - for (const match of matches) { - if (actualOptionIdx >= options.length && breakSearchOnConsumeAllOptions) break; - - const _isRecentlyCosedAnyTag = isRecentlyClosedAnyTag; - isRecentlyClosedAnyTag = false; - - const { index = 0, groups } = match; - - const { tag, value, backescape, named } = groups ?? {}; - - if (named && !tagOpenWith) { - const { hyphens, hyphensname, dots, dotsname } = groups ?? {}; - - const [, , backescapes] = match; - - const tagName = hyphensname ?? dotsname; - - const zeroTagUsed = (hyphens ?? dots)[0] as "-" | ":"; - - const isValidTag = validNamedOptionSyntaxes[hyphens ?? dots] === true; - - if (isValidTag && !namedOptionTagUsed && realConfig.useUniqueNamedSyntaxAtSameTime) { - namedOptionTagUsed = zeroTagUsed; - const tagToDisable = zeroTagUsed === "-" ? ":" : "\\-"; - if (checkNextChar) checkNextChar = RemoveFromCheckNextChar(checkNextChar, tagToDisable); - - RemoveNamedEscapeMode(localEscapeModes, tagToDisable); - } else if (!isValidTag || (useUniqueNamedSyntaxAtSameTime && namedOptionTagUsed !== zeroTagUsed)) { - aggregateUnindexedText(index, named, undefined, named, undefined, _isRecentlyCosedAnyTag); - continue; - } - - let backescapesStrRepresentation = ""; - - if (backescapes) { - const nextChar = named[backescapes.length]; - - const { isPossiblyEscapingNext, strRepresentation } = evaluateBackescapes(backescapes, nextChar, checkNextChar); - backescapesStrRepresentation = strRepresentation; - - if (hyphensname && isPossiblyEscapingNext) { - aggregateUnindexedText(index, strRepresentation + tagName, undefined, named, undefined, _isRecentlyCosedAnyTag); - continue; - } - if (!lastestLongWord && strRepresentation) { - aggregateUnindexedText(index, strRepresentation, undefined, backescapes, false, _isRecentlyCosedAnyTag); - } - } - - aggregateNextNamedOption(index + (backescapesStrRepresentation ? backescapes.length : 0)); - - if (lastestLongWord) aggregateLastestLongWord(index, backescapesStrRepresentation); - - namedOptionInitialized = { - name: tagName, - start: index + named.length, - dotted: dotsname !== undefined, - }; - - continue; - } - - if (lastestLongWord || namedOptionInitialized) continue; - - if (backescape) { - const isDisabledLongTextTagsInLastOption = disableLongTextTagsInLastOption && actualOptionIdx >= options.length - 1; - - const { length } = backescape; - - const nextChar = content[index + length]; - - const { isPossiblyEscapingNext, strRepresentation } = evaluateBackescapes( - backescape, - nextChar, - checkNextChar, - isDisabledLongTextTagsInLastOption, - ); - - if (isPossiblyEscapingNext) isEscapingNext = true; - - strRepresentation && aggregateUnindexedText(index, strRepresentation, "", backescape, undefined, _isRecentlyCosedAnyTag); - continue; - } - - if (tag) { - const isDisabledLongTextTagsInLastOption = disableLongTextTagsInLastOption && actualOptionIdx >= options.length - 1; - const isInvalidTag = InvalidTagsToBeLong.has(tag); - - if (isEscapingNext) { - isEscapingNext = false; - if (!tagOpenWith) { - aggregateUnindexedText(index, tag, "/", undefined, undefined, _isRecentlyCosedAnyTag); - } - } else if (isInvalidTag || isDisabledLongTextTagsInLastOption) { - aggregateUnindexedText(index, tag, "", undefined, undefined, _isRecentlyCosedAnyTag); - continue; - } else if (!tagOpenWith) { - tagOpenWith = tag as unknown as typeof tagOpenWith; - tagOpenPosition = index + 1; - } else if (tagOpenWith === tag && tagOpenPosition) { - aggregateTagLongText(tag, tagOpenPosition, index); - } - - continue; - } - - if (value && tagOpenWith === null) { - const placeIsForLeft = !(_isRecentlyCosedAnyTag || unindexedRightText || spacesRegex.test(content[index - 1])); - - if (placeIsForLeft && lastOptionNameAdded) { - result[lastOptionNameAdded] += value; - continue; - } - - const aggregated = aggregateNextOption(value, index); - - if (!aggregated) break; - } - } - - aggregateLastestLongWord(); - - if (namedOptionInitialized) { - aggregateNextNamedOption(content.length); - } else if (tagOpenPosition && tagOpenWith) aggregateTagLongText(tagOpenWith, tagOpenPosition); - - if (choicesOptions?.names?.length && realConfig.resolveCommandOptionsChoices !== null) { - YunaParserOptionsChoicesResolver(command, choicesOptions.names, result, realConfig); - } - - realConfig.logResult && console.log(result); - - return result; - }; -}; diff --git a/src/structures/utils/classes/client/Handler.ts b/src/structures/utils/classes/client/Handler.ts index b221e8f..c6cf7de 100644 --- a/src/structures/utils/classes/client/Handler.ts +++ b/src/structures/utils/classes/client/Handler.ts @@ -23,11 +23,11 @@ export class StelleHandler extends BaseHandler { * Load the handler. */ public async load() { - const files = await this.loadFilesK(await this.getFiles(await this.client.getRC().then((x) => x.lavalink))); + const files = await this.loadFilesK<{ default: Lavalink }>(await this.getFiles(await this.client.getRC().then((x) => x.lavalink))); for await (const file of files) { const path = file.path.split(process.cwd()).slice(1).join(process.cwd()); - const event: Lavalink = file.file; + const event: Lavalink = file.file.default; if (!(event && event instanceof Lavalink)) { this.logger.warn(`${path} doesn't export by \`export default new Lavaink({ ... })\``); @@ -39,6 +39,11 @@ export class StelleHandler extends BaseHandler { continue; } + if (typeof event.run !== "function") { + this.logger.warn(`${path} doesn't have a \`run\` function`); + continue; + } + const run = (...args: any) => event.run(this.client, ...args); if (event.isShoukaku()) this.client.manager.shoukaku.on(event.name, run); diff --git a/tsconfig.json b/tsconfig.json index 41e004c..316dd1f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,7 +29,6 @@ "#stelle/middlwares": ["./src/middlewares/index.ts"], "#stelle/errors": ["./src/structures/utils/Errors.ts"], "#stelle/decorators": ["./src/structures/utils/Decorators.ts"], - "#stelle/parser": ["./src/structures/parser/index.ts"], "#stelle/index": ["./src/index.ts"], "#stelle/data/*": ["./src/structures/utils/data/*"], "#stelle/utils/*": ["./src/structures/utils/*"], From 0e92fff725cc549e2111342a03f13b4a752884ed Mon Sep 17 00:00:00 2001 From: JustEvil Date: Mon, 24 Jun 2024 16:57:11 -0600 Subject: [PATCH 3/4] :zap: update (bot :package:): Changed some stuff. :pencil2: --- package.json | 2 +- pnpm-lock.yaml | 20 ++++++++++---------- src/commands/guild/default/engine.ts | 2 ++ src/structures/client/Stelle.ts | 2 +- src/structures/utils/functions/overrides.ts | 4 ++-- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 2c649cf..6eea8ff 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "ms": "^2.1.3", "seyfert": "github:tiramisulabs/seyfert", "shoukaku": "github:shipgirlproject/Shoukaku", - "yunaforseyfert": "github:SagiriIkeda/yunaforseyfert#experimental" + "yunaforseyfert": "github:SagiriIkeda/yunaforseyfert#dev" }, "devDependencies": { "@biomejs/biome": "^1.8.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8e2aec4..f26d10f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,13 +34,13 @@ importers: version: 2.1.3 seyfert: specifier: github:tiramisulabs/seyfert - version: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee + version: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/ad5edad727dc6032bb7b1b7d65792ed576ac7e56 shoukaku: specifier: github:shipgirlproject/Shoukaku version: https://codeload.github.com/shipgirlproject/Shoukaku/tar.gz/8d77908cfc903456613942f607cff207dda57b6f yunaforseyfert: - specifier: github:SagiriIkeda/yunaforseyfert#experimental - version: https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/a38ed0f3f674035064ddbb75ceda67e6997791e6 + specifier: github:SagiriIkeda/yunaforseyfert#dev + version: https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/39f1b84782a800c24474cd317b117c38c261abb1 devDependencies: '@biomejs/biome': specifier: ^1.8.2 @@ -452,8 +452,8 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - seyfert@https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee: - resolution: {tarball: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee} + seyfert@https://codeload.github.com/tiramisulabs/seyfert/tar.gz/ad5edad727dc6032bb7b1b7d65792ed576ac7e56: + resolution: {tarball: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/ad5edad727dc6032bb7b1b7d65792ed576ac7e56} version: 1.5.0 shebang-command@2.0.0: @@ -575,8 +575,8 @@ packages: engines: {node: '>= 14'} hasBin: true - yunaforseyfert@https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/a38ed0f3f674035064ddbb75ceda67e6997791e6: - resolution: {tarball: https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/a38ed0f3f674035064ddbb75ceda67e6997791e6} + yunaforseyfert@https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/39f1b84782a800c24474cd317b117c38c261abb1: + resolution: {tarball: https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/39f1b84782a800c24474cd317b117c38c261abb1} version: 1.0.0 snapshots: @@ -931,7 +931,7 @@ snapshots: rfdc@1.4.1: {} - seyfert@https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee: + seyfert@https://codeload.github.com/tiramisulabs/seyfert/tar.gz/ad5edad727dc6032bb7b1b7d65792ed576ac7e56: dependencies: chokidar: 3.6.0 discord-api-types: 0.37.90 @@ -1050,10 +1050,10 @@ snapshots: yaml@2.4.5: {} - yunaforseyfert@https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/a38ed0f3f674035064ddbb75ceda67e6997791e6: + yunaforseyfert@https://codeload.github.com/SagiriIkeda/yunaforseyfert/tar.gz/39f1b84782a800c24474cd317b117c38c261abb1: dependencies: discord-api-types: 0.37.90 - seyfert: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/1cb4ab4a4600a383677106fe6757935a4876d3ee + seyfert: https://codeload.github.com/tiramisulabs/seyfert/tar.gz/ad5edad727dc6032bb7b1b7d65792ed576ac7e56 transitivePeerDependencies: - bufferutil - supports-color diff --git a/src/commands/guild/default/engine.ts b/src/commands/guild/default/engine.ts index 1f46bc3..800746a 100644 --- a/src/commands/guild/default/engine.ts +++ b/src/commands/guild/default/engine.ts @@ -1,4 +1,5 @@ import { type CommandContext, Declare, LocalesT, Options, SubCommand, createStringOption } from "seyfert"; +import { Shortcut } from "yunaforseyfert"; const engines: Record = { spotify: "Spotify", @@ -37,6 +38,7 @@ const options = { }) @Options(options) @LocalesT("locales.default.subcommands.engine.name", "locales.default.subcommands.engine.description") +@Shortcut() export default class EngineSubcommand extends SubCommand { async run(ctx: CommandContext) { const { client, options, guildId } = ctx; diff --git a/src/structures/client/Stelle.ts b/src/structures/client/Stelle.ts index 464113b..b880415 100644 --- a/src/structures/client/Stelle.ts +++ b/src/structures/client/Stelle.ts @@ -47,11 +47,11 @@ export class Stelle extends Client { }, }, commands: { + reply: () => true, prefix: async (message) => { const guildPrefix = await this.database.getPrefix(message.guildId!); return [...new Set([guildPrefix, this.config.defaultPrefix, ...this.config.prefixes])]; }, - reply: () => true, defaults: { onBotPermissionsFail, onOptionsError, diff --git a/src/structures/utils/functions/overrides.ts b/src/structures/utils/functions/overrides.ts index d2343bd..d460817 100644 --- a/src/structures/utils/functions/overrides.ts +++ b/src/structures/utils/functions/overrides.ts @@ -67,10 +67,10 @@ export async function onBotPermissionsFail(ctx: AnyContext, permissions: Permiss } export async function onOptionsError(ctx: AnyContext) { - const { messages } = ctx.t.get(await ctx.getLocale()); - if (!ctx.isChat()) return; + const { messages } = ctx.t.get(await ctx.getLocale()); + const command = ctx.command.toJSON(); const options = formatOptions(command.options, messages.events.optionTypes); From 37d9ab029819657b14cf7e58a30b50e9f2c67327 Mon Sep 17 00:00:00 2001 From: JustEvil Date: Mon, 24 Jun 2024 16:58:08 -0600 Subject: [PATCH 4/4] =?UTF-8?q?:zap:=20chore=20(release=20:robot:):=20Stel?= =?UTF-8?q?le=20v2.5=20is=20out!=20=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6eea8ff..8ead586 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stelle-music", - "version": "0.2.4-BLAZER", + "version": "0.2.5-BLAZER", "description": "A music bot.", "main": "./dist/index.js", "type": "module",