diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ac04ae142..edf25a9fb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -8,6 +8,11 @@ body: attributes: value: | Thanks for taking the time to fill out this bug report! Fill in the blanks by following the steps. 🙌 + + Please **ensure the following** before reporting a bug: + + - ✅ I am using the latest version of aoi.js (v6.6.1). + - ✅ I am using a version of NodeJS (v20.5.1 or newer). - type: dropdown id: type @@ -39,31 +44,7 @@ body: } validations: required: true - - - type: dropdown - id: aoijs-version - attributes: - label: Version of aoi.js - description: What version of aoi.js are you using? - options: - - v6.5.0 - - v6.4.0 - - v6.3.0 - validations: - required: true - - - type: dropdown - id: node-version - attributes: - label: Version of Node.js - description: Also, what version of Node.js are you using? - options: - - v16.11.0 (Lowest) - - v18.17.1 (LTS) - - v20.5.1 (Current) - validations: - required: true - + - type: textarea id: excepted attributes: diff --git a/.github/labeler.yml b/.github/labeler.yml index 2be2d7630..23c3b2ea9 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,18 +1,11 @@ -Client: - - any: ['src/structures/Client.ts', 'src/functions/discord/client/*'] - -Classes: - - src/structures/* - -Manager: - - src/manager/* - -Core: - - src/core/**/* +# See https://github.com/actions/labeler -Functions:Discord: - - src/functions/discord/**/* - -Functions:JS: - - src/functions/js/**/* +'Core': + - src/core/** + - src/classes/** + +'Function': + - src/functions/** +'Client': + - src/classes/AoiClient.js diff --git a/.github/workflows/add-feature-label.yml b/.github/workflows/add-feature-label.yml index 464aacc3a..6f3a8ae29 100644 --- a/.github/workflows/add-feature-label.yml +++ b/.github/workflows/add-feature-label.yml @@ -11,14 +11,17 @@ jobs: uses: actions/checkout@v2 - name: Find new files in src directory run: | - NEW_FILES=$(git diff --name-only HEAD^ HEAD) - CHANGED_FILES=() - for file in $NEW_FILES; do - if [[ $file == "src/"* ]]; then - CHANGED_FILES+=("$file") - fi - done - echo "::set-output name=changed_files::${CHANGED_FILES[*]}" + if [ $(git rev-list --count HEAD) -gt 1 ] + then + NEW_FILES=$(git diff --name-only HEAD^ HEAD) + CHANGED_FILES=() + for file in $NEW_FILES; do + if [[ $file == "src/"* ]]; then + CHANGED_FILES+=("$file") + fi + done + echo "::set-output name=changed_files::${CHANGED_FILES[*]}" + fi id: find-files - name: Add Feature label if: ${{ steps.find-files.outputs.changed_files != '' }} diff --git a/.github/workflows/publish-dev.yml b/.github/workflows/publish-dev.yml index 11ae3568b..3c03f79a6 100644 --- a/.github/workflows/publish-dev.yml +++ b/.github/workflows/publish-dev.yml @@ -11,17 +11,17 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - - name: Install Node v16 + - name: Install Node v20.5.1 uses: actions/setup-node@v2 with: - node-version: 16 + node-version: 20.5.1 registry-url: https://registry.npmjs.org/ - name: Install dependencies run: npm ci --ignore-scripts - name: Deprecate old versions - run: npm deprecate aoi.js@"~6.1.0-dev" "This is no longer supported" || true + run: npm deprecate aoi.js@"~6.6.1-dev" "This is no longer supported" || true env: NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} diff --git a/src/classes/AoiError.js b/src/classes/AoiError.js index 5d500eb61..83343762e 100644 --- a/src/classes/AoiError.js +++ b/src/classes/AoiError.js @@ -83,13 +83,13 @@ class AoiError { if (typeof options === "object") { options.content = options.content?.toString()?.trim() || " "; if (options.embeds && typeof options.embeds === "string") { - options.embeds = await EmbedParser(options.embeds); + options.embeds = await EmbedParser(options.embeds, d); } if (options.files && typeof options.files === "string") { - options.files = FileParser(options.files); + options.files = FileParser(options.files, d); } if (options.components && typeof options.components === "string") { - options.components = await ComponentParser(options.components, client); + options.components = await ComponentParser(options.components, d); } } else { options = { diff --git a/src/core/interpreter.js b/src/core/interpreter.js index 72e35dc53..cd28e1820 100644 --- a/src/core/interpreter.js +++ b/src/core/interpreter.js @@ -406,17 +406,28 @@ const Interpreter = async ( ); if (client.aoiOptions.suppressAllErrors) { if (client.aoiOptions.errorMessage) { - if (!message || !message.channel) { + const msg = message; + if (!msg || !msg.channel) { console.error(client.aoiOptions.errorMessage.addBrackets()); } else { - const { - makeMessageError, - } = require("../classes/AoiError.js"); - const message = await Util.errorParser(client.aoiOptions.errorMessage, d); + const { makeMessageError } = require("../classes/AoiError.js"); + + const result = await Interpreter( + client, + msg ?? data, + args ?? [], + { name: "parser", code: client.aoiOptions.errorMessage }, + client.db, + true, + msg.channel ?? [], + ); + + const message = await Util.errorParser(result.code ?? client.aoiOptions.errorMessage, d); // (?) support for parser and regular functions if (!errorOccurred) { await makeMessageError(client, channel, message.data ?? message, message.options, d); } + errorOccurred = true; } } diff --git a/src/functions/event/interactionEdit.js b/src/functions/event/interactionEdit.js index bc78a2dd5..b5d85ce35 100644 --- a/src/functions/event/interactionEdit.js +++ b/src/functions/event/interactionEdit.js @@ -4,9 +4,9 @@ module.exports = async d => { let [content = "", embeds = "", components = "", files = "", allowedMentions = "all"] = data.inside.splits; - embeds = await d.util.parsers.EmbedParser(embeds); + embeds = await d.util.parsers.EmbedParser(embeds, d); - components = await d.util.parsers.ComponentParser(components, d.client); + components = await d.util.parsers.ComponentParser(components, d); files = await d.util.parsers.FileParser(files); diff --git a/src/functions/event/interactionFollowUp.js b/src/functions/event/interactionFollowUp.js index a1d16d297..dbefb07f8 100644 --- a/src/functions/event/interactionFollowUp.js +++ b/src/functions/event/interactionFollowUp.js @@ -4,9 +4,9 @@ module.exports = async d => { let [content = "", embeds = "", components = "", files = "", ephemeral = "false"] = data.inside.splits - embeds = await d.util.parsers.EmbedParser(embeds); + embeds = await d.util.parsers.EmbedParser(embeds, d); - components = await d.util.parsers.ComponentParser(components, d.client); + components = await d.util.parsers.ComponentParser(components, d); files = await d.util.parsers.FileParser(files); diff --git a/src/functions/event/interactionReply.js b/src/functions/event/interactionReply.js index 099eaf2a1..846b82733 100644 --- a/src/functions/event/interactionReply.js +++ b/src/functions/event/interactionReply.js @@ -4,9 +4,9 @@ module.exports = async d => { let [content = "", embeds = "", components = "", files = "", allowedMentions = "all", ephemeral = "false"] = data.inside.splits - embeds = await d.util.parsers.EmbedParser(embeds); + embeds = await d.util.parsers.EmbedParser(embeds, d); - components = await d.util.parsers.ComponentParser(components, d.client); + components = await d.util.parsers.ComponentParser(components, d); files = await d.util.parsers.FileParser(files); diff --git a/src/functions/event/interactionUpdate.js b/src/functions/event/interactionUpdate.js index ed701bc23..e091b7f17 100644 --- a/src/functions/event/interactionUpdate.js +++ b/src/functions/event/interactionUpdate.js @@ -5,9 +5,9 @@ module.exports = async d => { let [content = "", embeds = "", components = "", files = ""] = data.inside.splits - embeds = await d.util.parsers.EmbedParser(embeds); + embeds = await d.util.parsers.EmbedParser(embeds, d); - components = await d.util.parsers.ComponentParser(components, d.client); + components = await d.util.parsers.ComponentParser(components, d); files = await d.util.parsers.FileParser(files); diff --git a/src/functions/info/reactionCount.js b/src/functions/info/reactionCount.js index aef3a3a62..2bd7ca699 100644 --- a/src/functions/info/reactionCount.js +++ b/src/functions/info/reactionCount.js @@ -5,22 +5,22 @@ module.exports = async (d) => { const [channelID, messageID, emojiResolver] = data.inside.splits; const channel = await d.util.getChannel(d, channelID); - if (!channel) - return d.aoiError.fnError(d, "channel", {inside: data.inside}); + if (!channel) return d.aoiError.fnError(d, "channel", { inside: data.inside }); const message = await d.util.getMessage(channel, messageID); - if (!message) - return d.aoiError.fnError(d, "message", {inside: data.inside}); + if (!message) return d.aoiError.fnError(d, "message", { inside: data.inside }); - const emoji = message.reactions.cache.find( - (x) => - x.emoji.id === emojiResolver || - x.emoji.toString().toLowerCase() === - emojiResolver.addBrackets().toLowerCase(), - ); - if (!emoji) return d.aoiError.fnError(d, "emoji", {inside: data.inside}); + let emoji; - data.result = emoji.count; + try { + emoji = message.reactions.cache.find((x) => x.emoji.id === d.util.getEmoji(d, emojiResolver).id)?.count; + } catch { + emoji = message.reactions.cache.find((x) => x.emoji.toString().toLowerCase() === emojiResolver.toLowerCase())?.count; + } finally { + emoji = emoji ?? 0; + } + + data.result = emoji; return { code: d.util.setCode(data), diff --git a/src/functions/interaction/addButton.js b/src/functions/interaction/addButton.js index 822de77f8..66d09eacd 100644 --- a/src/functions/interaction/addButton.js +++ b/src/functions/interaction/addButton.js @@ -1,31 +1,43 @@ module.exports = async (d) => { - const {code} = d.command; - const inside = d.unpack(); - const err = d.inside(inside); - if (err) return d.error(err); - let [index, label, style, custom, disabled = "false", emoji] = inside.splits; - if (isNaN(index) || Number(index) < 1) - d.aoiError.fnError(d, "custom", {inside}, "Invalid Index Provided In"); - index = Number(index) - 1; - style = isNaN(style) - ? d.util.constants.ButtonStyleOptions[style] - : Number(style); - disabled = disabled === "true"; - if (!style || style > 5 || style < 1) - d.aoiError.fnError(d, "custom", {inside}, "Invalid Style Provided In"); - if (!d.components[index]) d.components[index] = {type: 1, components: []}; - const button = { - label, - type: 2, - style, - disabled, - emoji, - }; - button[style === 5 ? "url" : "customId"] = custom; - d.components[index].components.push(button); - return { - code: d.util.setCode({function: d.func, inside, code, result: ""}), - data: { ...d.data, components: Object.assign({}, d.data.components, d.components) }, - components: d.components, - }; + const data = d.util.aoiFunc(d); + const { code } = d.command; + if (data.err) return d.error(data.err); + + let [index, label, style, custom, disabled = "false", emoji] = data.inside.splits; + + if (isNaN(index) || Number(index) < 1) return d.aoiError.fnError(d, "custom", { inside: data.inside }, "Index"); + + index = Number(index) - 1; + style = isNaN(style) ? d.util.constants.ButtonStyleOptions[style] : Number(style); + disabled = disabled === "true"; + + if (!style || style > 5 || style < 1) return d.aoiError.fnError(d, "custom", { inside: data.inside }, "Style"); + + try { + emoji = d.util.getEmoji(d, emoji.addBrackets()).id; + } catch { + emoji = emoji?.addBrackets() ?? undefined; + } + + const button = { + label, + type: 2, + style, + disabled, + emoji, + }; + + button[style === 5 ? "url" : "customId"] = custom; + + if (!d.components[index]) d.components[index] = { type: 1, components: [] }; + d.components[index].components.push(button); + + return { + code: d.util.setCode({ function: d.func, inside: data.inside, code }), + data: { + ...d.data, + components: Object.assign({}, d.data.components, d.components), + }, + components: d.components, + }; }; diff --git a/src/functions/interaction/addClientReactions.js b/src/functions/interaction/addClientReactions.js index 01db768c6..e49f5b248 100644 --- a/src/functions/interaction/addClientReactions.js +++ b/src/functions/interaction/addClientReactions.js @@ -1,15 +1,25 @@ module.exports = async (d) => { - const data = d.util.aoiFunc(d); - if (data.err) return d.error(data.err); + const data = d.util.aoiFunc(d); + if (data.err) return d.error(data.err); - let [...reactions] = data.inside.splits; + let [...reactions] = data.inside.splits; - reactions = reactions.map(x => x.addBrackets()).reverse(); + reactions = reactions.map((x) => { + try { + let emoji = d.util.getEmoji(d, x.addBrackets()); + x = emoji.id ? `:${emoji.name}:${emoji.id}` : emoji.name; + } catch { + x = x?.addBrackets() ?? undefined; + } finally { + if (x === undefined) return d.util.aoiError.fnError(d, "custom", { inside: data.inside }, "Emoji"); + } + return x; + }); - data.result = "" + data.result = ""; - return { - code: d.util.setCode(data), - reactions, - }; + return { + code: d.util.setCode(data), + reactions, + }; }; diff --git a/src/functions/interaction/addCmdReactions.js b/src/functions/interaction/addCmdReactions.js index 48c0fa07c..3238c2677 100644 --- a/src/functions/interaction/addCmdReactions.js +++ b/src/functions/interaction/addCmdReactions.js @@ -1,16 +1,25 @@ -module.exports = async d => { - const data = d.util.aoiFunc(d); - if (data.err) return d.error(data.err); +module.exports = async (d) => { + const data = d.util.aoiFunc(d); + if (data.err) return d.error(data.err); - let [...reactions] = data.inside.splits; - reactions = reactions.reverse() - for (let i = reactions.length - 1; i >= 0; i--) { - await d.message.react(reactions[i]).catch(err => d.aoiError.fnError(d, "custom", {}, err.message)) + let [...reactions] = data.inside.splits; + reactions = reactions.reverse(); + for (let i = reactions.length - 1; i >= 0; i--) { + let reaction; + try { + reaction = d.util.getEmoji(d, reactions[i].addBrackets()).id; + } catch { + reaction = reactions[i]?.addBrackets() ?? undefined; + } finally { + if (reaction === undefined) return d.util.aoiError.fnError(d, "custom", { inside: data.inside}, "Emoji"); } - data.result = ""; + await d.message.react(reaction).catch((err) => d.aoiError.fnError(d, "custom", {}, err.message)); + } - return { - code: d.util.setCode(data) - } -} \ No newline at end of file + data.result = ""; + + return { + code: d.util.setCode(data), + }; +}; diff --git a/src/functions/interaction/addMessageReactions.js b/src/functions/interaction/addMessageReactions.js index a4ab22b7e..22fa0f81a 100644 --- a/src/functions/interaction/addMessageReactions.js +++ b/src/functions/interaction/addMessageReactions.js @@ -1,23 +1,32 @@ module.exports = async (d) => { - const data = d.util.aoiFunc(d); - if (data.err) return d.error(data.err); + const data = d.util.aoiFunc(d); + if (data.err) return d.error(data.err); - let [channelID, messageID, ...reactions] = data.inside.splits; - const channel = await d.util.getChannel(d, channelID); + let [channelID, messageID, ...reactions] = data.inside.splits; + const channel = await d.util.getChannel(d, channelID); - if (!channel) return d.aoiError.fnError(d, "channel", {inside: data.inside}); - const message = await d.util.getMessage(channel, messageID); + if (!channel) + return d.aoiError.fnError(d, "channel", { inside: data.inside }); + const message = await d.util.getMessage(channel, messageID); - if (!message) return d.aoiError.fnError(d, "message", {inside: data.inside}); - reactions = reactions.reverse(); - for (let i = reactions.length - 1; i >= 0; i--) { - message - .react(reactions[i]) - .catch((err) => d.aoiError.fnError(d, "custom", {}, err.message)); + if (!message) + return d.aoiError.fnError(d, "message", { inside: data.inside }); + reactions = reactions.reverse(); + + for (let i = reactions.length - 1; i >= 0; i--) { + let reaction; + try { + reaction = d.util.getEmoji(d, reactions[i].addBrackets()).id; + } catch { + reaction = reactions[i]?.addBrackets() ?? undefined; + } finally { + if (reaction === undefined) return d.util.aoiError.fnError(d, "custom", { inside: data.inside }, "Emoji" ); } + await message.react(reaction).catch((err) => d.aoiError.fnError(d, "custom", {}, err.message)); + } - data.result = ""; - return { - code: d.util.setCode(data) - }; + data.result = ""; + return { + code: d.util.setCode(data), + }; }; diff --git a/src/functions/interaction/addSelectMenu.js b/src/functions/interaction/addSelectMenu.js index 0abeb20d9..2a9c51926 100644 --- a/src/functions/interaction/addSelectMenu.js +++ b/src/functions/interaction/addSelectMenu.js @@ -5,44 +5,25 @@ module.exports = async (d) => { const { code } = d.command; if (data.err) return d.error(data.err); - let [ index = 1, type, customId, placeHolder, minValues = 1, maxValues = 1, disabled = "false", ...options] = data.inside.splits; + let [ index = 1, type, customId, placeholder, minValues = 1, maxValues = 1, disabled = "false", ...options ] = data.inside.splits; index = Number(index) - 1; - if (isNaN(index) || index < 0) - d.aoiError.fnError(d, "custom", { inside: data.inside }, "Invalid Index Provided In"); + if (isNaN(index) || index < 0) return d.aoiError.fnError(d, "custom", { inside: data.inside }, "Index"); disabled = disabled === "true"; - placeHolder = placeHolder?.addBrackets(); + placeholder = placeholder?.addBrackets(); customId = customId?.addBrackets(); minValues = Number(minValues); maxValues = Number(maxValues); if (!options.length && type === "string") return d.aoiError.fnError(d, "custom", { inside: data.inside }, "Options Are Not Provided In"); - if (minValues > 25 || minValues < 0) - return d.aoiError.fnError( - d, - "custom", - { inside: data.inside }, - "minValues must be between 0 and 25 (both inclusive). Provided Invalid In" - ); - - if (maxValues > 25 || maxValues < 1) - return d.aoiError.fnError( - d, - "custom", - { inside: data.inside }, - "maxValues must be between 1 and 25 (both Inclusive). Provided Invalid In" - ); - - if (placeHolder.length > 100) - return d.aoiError.fnError( - d, - "custom", - {}, - "Placeholder should be at most 100 Characters long" - ); + if (minValues > 25 || minValues < 0) return d.aoiError.fnError(d, "custom", { inside: data.inside }, "minValues must be between 0 and 25 (both inclusive)."); + + if (maxValues > 25 || maxValues < 1) return d.aoiError.fnError(d, "custom", { inside: data.inside }, "maxValues must be between 1 and 25 (both Inclusive)."); + + if (placeholder.length > 100) return d.aoiError.fnError(d, "custom", {}, "Placeholder should be at most 100 Characters long"); let selectBuilder; @@ -63,12 +44,12 @@ module.exports = async (d) => { selectBuilder = new ChannelSelectMenuBuilder(); break; default: - return d.aoiError.fnError(d, "custom", { inside: data.inside }, "Invalid Select Menu Type"); + return d.aoiError.fnError(d, "custom", { inside: data.inside }, "Invalid Select Menu Type"); } selectBuilder .setCustomId(customId) - .setPlaceholder(placeHolder) + .setPlaceholder(placeholder) .setMaxValues(maxValues) .setMinValues(minValues) .setDisabled(disabled); @@ -79,8 +60,13 @@ module.exports = async (d) => { const description = option[1].addBrackets(); const value = option[2].addBrackets(); const def = option[3]?.addBrackets() === "true"; - let emoji = option[4]?.addBrackets(); - emoji = emoji === "" ? undefined : emoji; + let emoji; + + try { + emoji = d.util.getEmoji(d, option[4]?.addBrackets()).id; + } catch { + emoji = option[4]?.addBrackets() ?? undefined; + } switch (type.toLowerCase()) { case "string": @@ -103,7 +89,7 @@ module.exports = async (d) => { }); break; default: - d.aoiError.fnError(d, "custom", { inside: data.inside }, "Invalid Select Menu Type"); + d.aoiError.fnError(d, "custom", { inside: data.inside }, "Select Menu Type"); } } diff --git a/src/functions/interaction/interactionModal.js b/src/functions/interaction/interactionModal.js index 0ffba4ff6..2499eee9a 100644 --- a/src/functions/interaction/interactionModal.js +++ b/src/functions/interaction/interactionModal.js @@ -4,7 +4,7 @@ module.exports = async (d) => { const [title, customID, components] = data.inside.splits; - const parsedComponents = await d.util.parsers.ComponentParser(components, d.client); + const parsedComponents = await d.util.parsers.ComponentParser(components, d); await d.data.interaction .showModal({ diff --git a/src/functions/misc/getCooldownTime.js b/src/functions/misc/getCooldownTime.js index 4597fd5e3..ad0d99765 100644 --- a/src/functions/misc/getCooldownTime.js +++ b/src/functions/misc/getCooldownTime.js @@ -1,30 +1,28 @@ -const {Time} = require('../../utils/helpers/customParser.js'); +const { Time } = require("../../utils/helpers/customParser.js"); -module.exports = async d => { - const data = d.util.aoiFunc(d); - if (data.err) return d.error(data.err); +module.exports = async (d) => { + const data = d.util.aoiFunc(d); + if (data.err) return d.error(data.err); - let [time, type, cmdName, id] = data.inside.splits; + let [time, type, cmdName, id] = data.inside.splits; - time = Time.parse(time)?.ms - if (!time) return d.aoiError.fnError(d, 'custom', {inside: data.inside}, 'Invalid Time Provided In'); + time = Time.parse(time)?.ms; + if (!time) return d.aoiError.fnError(d, "custom", { inside: data.inside }, "Type"); - const types = { - globalUser: id, - user: `${id}_${d.message.guild.id || 'dm'}`, - server: id, - channel: id, - static: undefined, - } + const types = { + globalUser: id, + user: `${id}_${d.message.guild.id || "dm"}`, + server: id, + channel: id, + static: undefined, + }; - if (!types[type]) return d.aoiError.fnError(d, 'custom', {inside: data.inside}, 'Invalid Type Provided In'); + if (!types[type]) return d.aoiError.fnError(d, "custom", { inside: data.inside }, "Type"); - const timeEnd = await d.client.db.get(d.client.db.tables[0], 'cooldown', cmdName + "_" + types[type]); - - data.result = (timeEnd?.value || 0) - Date.now(); - - return { - code: d.util.setCode(data) - } -} + const timeEnd = await d.client.db.get("__aoijs_vars__", "cooldown", cmdName + "_" + types[type]); + data.result = ((timeEnd?.value || d) - Date.now()) < 0 ? 0 : (timeEnd?.value || d) - Date.now(); + return { + code: d.util.setCode(data), + }; +}; diff --git a/src/handler/parsers.js b/src/handler/parsers.js index ee23cbe24..a14706ea1 100644 --- a/src/handler/parsers.js +++ b/src/handler/parsers.js @@ -2,562 +2,390 @@ const Discord = require("discord.js"); const { mustEscape } = require("../utils/helpers/mustEscape.js"); const { ButtonStyleOptions } = require("../utils/Constants.js"); const SlashOption = require("./slashOption.js"); -const { Time } = require("../utils/helpers/customParser.js"); const { CreateObjectAST } = require("../utils/helpers/functions.js"); -const EmbedParser = async (msg) => { - msg = mustEscape(msg); - - const embeds = []; - - let msgs = msg.split("{newEmbed:").slice(1); - for (let rawr of msgs) { - rawr = rawr.slice(0, rawr.length - 1); - - const embed = {}; - embed.fields = []; - const Checker = (peko) => rawr.includes(`{${peko}:`); - if (Checker("author")) { - const auth = rawr.split("{author:")[1].split("}")[0].split(":"); - embed.author = { - name: auth.shift().addBrackets()?.trim() || "", - icon_url: auth.join(":").addBrackets()?.trim() || "", - }; - } - if (Checker("authorURL")) { - if (!embed.author) return console.error("{author:} was not used"); - embed.author.url = rawr - .split("{authorURL:")[1] - .split("}")[0] - .addBrackets() - .trim(); - } - if (Checker("title")) { - embed.title = rawr - .split("{title:")[1] - .split("}")[0] - .addBrackets() - .trim(); - } - if (Checker("url")) { - if (!embed.title) - return console.error( - "Title was not provided while using {url}", - ); - embed.url = rawr - .split("{url:")[1] - .split("}")[0] - .addBrackets() - .trim(); - } - if (Checker("description")) { - embed.description = rawr - .split("{description:")[1] - .split("}")[0] - .addBrackets() - .trim(); - } - if (Checker("thumbnail")) { - embed.thumbnail = { - url: rawr - .split("{thumbnail:")[1] - .split("}")[0] - .addBrackets() - .trim(), - }; - } - if (Checker("image")) { - embed.image = { - url: rawr - .split("{image:")[1] - .split("}")[0] - .addBrackets() - .trim(), - }; - } - if (Checker("footer")) { - const f = rawr.split("{footer:")[1].split("}")[0].split(":"); - embed.footer = { - text: f.shift().addBrackets().trim() || "", - icon_url: f.join(":").addBrackets().trim() || "", - }; - } - if (Checker("color")) { - embed.color = Discord.resolveColor( - rawr.split("{color:")[1].split("}")[0].addBrackets().trim(), - ); - } - if (rawr.includes("{timestamp")) { - let t = rawr - .split("{timestamp")[1] - .split("}")[0] - .replace(":", "") - .trim(); - if (t === "" || t === "ms") { - t = Date.now(); - } - embed.timestamp = new Date(t); - } - if (Checker("field")) { - const fi = rawr.split("{field:").slice(1); - for (let fo of fi) { - fo = fo.split("}")[0].split(":"); - const fon = fo.shift().addBrackets().trim(); - const foi = ["yes", "no", "true", "false"].find( - (x) => x === fo[Number(fo.length - 1)].trim(), - ) - ? fo.pop().trim() === "true" - : false; - - const fov = fo.join(":").addBrackets().trim(); - embed.fields.push({ name: fon, value: fov, inline: foi }); - } - } - if (Checker("fields")) { - const fie = rawr.split("{fields:").slice(1); - for (let fiel of fie) { - fiel = fiel.split("}")[0].split(":"); - for (let oof of fiel) { - oof = oof.split(","); - const oofn = oof.shift().addBrackets().trim(); - const oofi = ["yes", "no", "true", "false"].find( - (x) => x === oof[oof.length - 1].trim(), - ) - ? oof.pop().trim() === "true" - : false; - const oofv = oof.join(",").addBrackets().trim(); - embed.fields.push({ - name: oofn, - value: oofv, - inline: oofi, - }); - } - } - } - embeds.push(embed); +const EmbedParser = async (msg, d) => { + msg = mustEscape(msg); + + const embeds = []; + + let msgs = msg.split("{newEmbed:").slice(1); + for (let rawr of msgs) { + rawr = rawr.slice(0, rawr.length - 1); + + const embed = {}; + embed.fields = []; + const Checker = (peko) => rawr.includes(`{${peko}:`); + if (Checker("author")) { + const auth = rawr.split("{author:")[1].split("}")[0].split(":"); + embed.author = { + name: auth.shift().addBrackets()?.trim() || "", + icon_url: auth.join(":").addBrackets()?.trim() || "", + }; } - return embeds; -}; -const ComponentParser = async (msg, client) => { - msg = mustEscape(msg); - let msgs = msg.split("{actionRow:").slice(1); - const actionRows = []; - for (let aoi of msgs) { - const index = aoi.lastIndexOf("}"); - aoi = aoi.slice(0, index); - - const buttonPart = []; - const Checker = (checker) => aoi.includes("{" + checker + ":"); - if (Checker("button")) { - const inside = aoi.split("{button:").slice(1); - for (let button of inside) { - button = button?.split("}")[0]; - button = button?.split(":").map((x) => x.trim()); - - const label = button.shift().addBrackets(); - const btype = 2; - let style = isNaN(button[0]) - ? button.shift() - : Number(button.shift()); - style = ButtonStyleOptions[style] || style; - const cus = button.shift().addBrackets(); - const disable = - button - .shift() - ?.replace("yes", true) - ?.replace("no", false) - ?.replace("true", true) - ?.replace("false", false) || false; - const emoji = button.length - ? (button || []).join(":").trim().startsWith("<") - ? client.emojis.cache.find( - (x) => x.toString() === button.join(":"), - ) - : { - name: button.join(":").split(",")[0], - id: button.join(":").split(",")[1] || 0, - animated: button.join(":").split(",")[2] || false, - } - : undefined; - const d = - Number(style) === 5 - ? { - label: label, - type: btype, - style: style, - url: cus, - disabled: disable, - } - : { - label: label, - type: btype, - style: style, - custom_id: cus, - disabled: disable, - }; - if (emoji) { - const en = emoji?.name; - const eid = emoji?.id; - const ea = emoji?.animated; - d.emoji = { name: en, id: eid, animated: ea }; - } - buttonPart.push(d); - } - } - if (Checker("selectMenu")) { - let inside = aoi.split("{selectMenu:").slice(1).join(""); - inside = inside.split(":").map((c) => c.trim()); - const customID = inside.shift(); - const placeholder = inside.shift(); - const minVal = inside[0] === "" ? 0 : Number(inside.shift()); - const maxVal = inside[0] === "" ? 1 : Number(inside.shift()); - const disabled = inside.shift() === "true"; - const options = inside.join(":").trim(); - - let optArray = []; - if (options.includes("{selectMenuOptions:")) { - const opts = options.split("{selectMenuOptions:").slice(1); - - for (let opt of opts) { - opt = opt.split("}")[0].split(":"); - const label = opt.shift(); - const value = opt.shift(); - const desc = opt.shift(); - const def = opt.shift() === "true"; - const emoji = opt.length - ? (opt || "").join(":").trim().startsWith("<") - ? client.emojis.cache.find( - (x) => x.toString() === opt.join(":"), - ) - : { - name: opt.join(":").split(",")[0].trim(), - id: opt.join(":").split(",")[1]?.trim() || 0, - animated: - opt.join(":").split(",")[2]?.trim() || - false, - } - : undefined; - const ind = { - label: label, - value: value, - description: desc, - default: def, - }; - if (emoji) { - const en = emoji?.name; - const eid = emoji?.id; - const ea = emoji?.animated; - ind.emoji = { name: en, id: eid, animated: ea }; - } - - optArray.push(ind); - } - } - buttonPart.push({ - type: 3, - custom_id: customID, - placeholder: placeholder, - min_values: minVal, - max_values: maxVal, - disabled, - options: optArray, - }); - } - if (Checker("textInput")) { - let inside = aoi.split("{textInput:").slice(1); - for (let textInput of inside) { - textInput = textInput.split("}")[0].split(":"); - const label = textInput.shift().addBrackets().trim(); - let style = textInput.shift().addBrackets().trim(); - style = isNaN(style) ? style : Number(style); - const custom_id = textInput.shift().addBrackets().trim(); - const required = - textInput.shift()?.addBrackets().trim() === "true"; - const placeholder = textInput.shift()?.addBrackets().trim(); - const min_length = textInput.shift()?.addBrackets().trim(); - const max_length = textInput.shift()?.addBrackets().trim(); - const value = textInput.shift()?.addBrackets().trim(); - buttonPart.push({ - type: 4, - label, - style, - custom_id, - required, - placeholder, - min_length, - max_length, - value, - }); - } - } - actionRows.push({ type: 1, components: buttonPart }); + if (Checker("authorURL")) { + if (!embed.author) return console.error("{author:} was not used"); + embed.author.url = rawr + .split("{authorURL:")[1] + .split("}")[0] + .addBrackets() + .trim(); } - return actionRows; -}; -const EditParser = async (msg) => { - msg = msg.split("{edit:").slice(1).join("").split("}"); - msg.pop(); - msg = msg.join("}"); - const time = msg.split(":")[0].trim(); - msg = msg.split(":").slice(1).join(":").trim(); - const msgs = CreateObjectAST(msg); - const ans = { - time, - messages: [], - }; - for (let p of msgs) { - p = p.slice(1, -1); - const pps = CreateObjectAST(p); - const mmsg = { - content: " ", - embeds: [], - components: [], - files: [], - }; - for (const pp of pps) { - p = p.replace(pp, ""); - if (Checker("newEmbed")) mmsg.embeds.push(...await EmbedParser(part)); - else if (Checker("actionRow")) - mmsg.components.push(...await ComponentParser(part)); - else if (Checker("attachment") || Checker("file")) - mmsg.files.push(...FileParser(part)); - } - mmsg.content = p.trim() === "" ? " " : p.trim(); - ans.messages.push(mmsg); + if (Checker("title")) { + embed.title = rawr.split("{title:")[1].split("}")[0].addBrackets().trim(); } - return ans; -}; -const FileParser = (msg) => { - if (!msg) return; - msg = mustEscape(msg); - const Checker = (ayaya) => msg.includes("{" + ayaya + ":"); - const att = []; - if (Checker("attachment")) { - const e = msg - ?.split("{attachment:") - ?.slice(1) - .map((x) => x.trim()); - for (let o of e) { - o = o.split("}")[0]; - o = o.split(":"); - const name = o.pop().addBrackets(); - const url = o.join(":").addBrackets(); - const attachment = new Discord.AttachmentBuilder(url, name); - att.push(attachment); - } + if (Checker("url")) { + if (!embed.title) + return console.error("Title was not provided while using {url}"); + embed.url = rawr.split("{url:")[1].split("}")[0].addBrackets().trim(); } - if (Checker("file")) { - const i = msg - .split("{file:") - ?.slice(1) - .map((x) => x.trim()); - for (let u of i) { - u = u.split("}")[0]; - u = u.split(":"); - const name = u.pop().addBrackets(); - const text = u.join(":").addBrackets(); - const attachment = new Discord.AttachmentBuilder( - Buffer.from(text), - name || "txt.txt", - ); - att.push(attachment); - } + if (Checker("description")) { + embed.description = rawr + .split("{description:")[1] + .split("}")[0] + .addBrackets() + .trim(); } - return att; -}; -const errorHandler = async ( errorMessage,d, returnMsg = false, channel) => { - errorMessage = errorMessage.trim(); - const embeds = []; - let send = true; - let deleteCommand = false; - const components = []; - let interaction; - let deleteAfter; - const Checker = (parts,ayaya) => parts.includes("{" + ayaya + ":"); - let suppress = false; - let files = []; - let reactions = []; - - let edits = { - time: "0s", - messages: [], - }; - const parts = CreateObjectAST( errorMessage ); - for ( const part of parts ) - { - errorMessage = errorMessage.replace( part, "" ); - if (Checker(part,"newEmbed")) embeds.push(...await EmbedParser(part)); - else if (Checker(part, "actionRow")) - components.push(...(await ComponentParser(part))); - else if (Checker(part, "attachment") || Checker("file")) - files = FileParser(part); - else if (Checker(part, "edit")) edits = await EditParser(part); - else if (Checker(part, "suppress")) suppress = true; - else if (Checker(part,"deleteCommand")) deleteCommand = true; - else if (Checker(part, "interaction")) interaction = true; - else if (Checker(part, "deleteAfter")) - deleteAfter = part.split(":")[1].trim(); - else if (Checker(part, "reactions")) - reactions = part - .split(":")[1] - .trim().split("}")[0] - .split(",") - .map((x) => x.trim()); + if (Checker("thumbnail")) { + embed.thumbnail = { + url: rawr.split("{thumbnail:")[1].split("}")[0].addBrackets().trim(), + }; + } + if (Checker("image")) { + embed.image = { + url: rawr.split("{image:")[1].split("}")[0].addBrackets().trim(), + }; + } + if (Checker("footer")) { + const f = rawr.split("{footer:")[1].split("}")[0].split(":"); + embed.footer = { + text: f.shift().addBrackets().trim() || "", + icon_url: f.join(":").addBrackets().trim() || "", + }; } + if (Checker("color")) { + embed.color = Discord.resolveColor( + rawr.split("{color:")[1].split("}")[0].addBrackets().trim() + ); + } + if (rawr.includes("{timestamp")) { + let t = rawr.split("{timestamp")[1].split("}")[0].replace(":", "").trim(); + if (t === "" || t === "ms") { + t = Date.now(); + } + embed.timestamp = new Date(t); + } + if (Checker("field")) { + const fi = rawr.split("{field:").slice(1); + for (let fo of fi) { + fo = fo.split("}")[0].split(":"); + const fon = fo.shift().addBrackets().trim(); + const foi = ["yes", "no", "true", "false"].find( + (x) => x === fo[Number(fo.length - 1)].trim() + ) + ? fo.pop().trim() === "true" + : false; - if (!embeds.length) send = false; - - if (send && suppress) send = false; - - if (returnMsg === true) { - return { - embeds: send ? embeds : [], - components, - content: - errorMessage.addBrackets() === "" - ? " " - : errorMessage.addBrackets(), - files, - options: { - reactions: reactions.length ? reactions : undefined, - suppress, - edits, - deleteIn: deleteAfter, - deleteCommand, - }, - }; + const fov = fo.join(":").addBrackets().trim(); + embed.fields.push({ name: fon, value: fov, inline: foi }); + } } - errorMessage = errorMessage.addBrackets().trim(); - if (!(errorMessage.length || send || files.length)) return; - - const ch = channel || d.channel; - - if ( - (errorMessage.length || send || files.length) && - d && - ch && - !returnMsg - ) { - const m = await ch - .send({ - content: errorMessage.addBrackets(), - embeds: send ? embeds : [], - files: files?.length ? files : [], - }) - .catch(() => {}); - - if (!m) return; - - if (m && reactions.length) { - for (const reaction of reactions) { - await m.react(reaction).catch(console.error); - } + embeds.push(embed); + } + return embeds; +}; + +const ComponentParser = async (msg, d) => { + msg = mustEscape(msg); + let msgs = msg.split("{actionRow:").slice(1); + const actionRows = []; + + for (let aoi of msgs) { + const index = aoi.lastIndexOf("}"); + aoi = aoi.slice(0, index); + + const buttonPart = []; + const Checker = (checker) => aoi.includes("{" + checker + ":"); + if (Checker("button")) { + const inside = aoi.split("{button:").slice(1); + for (let button of inside) { + button = button?.split("}")[0]; + button = button?.split(":").map((x) => x.trim()); + + const label = button.shift().addBrackets(); + let style = isNaN(button[0]) ? button.shift() : Number(button.shift()); + style = ButtonStyleOptions[style] || style; + const cus = button.shift().addBrackets(); + const disable = + button.shift()?.replace("true", true)?.replace("false", false) || + false; + let emoji; + const dInside = + Number(style) === 5 + ? { + label: label, + type: 2, + style: style, + url: cus, + disabled: disable, + } + : { + label: label, + type: 2, + style: style, + custom_id: cus, + disabled: disable, + }; + + if (button) { + try { + emoji = d.util.getEmoji(d, button.toString().addBrackets()); + dInside.emoji = { + name: emoji.name, + id: emoji.id, + animated: emoji.animated, + }; + } catch { + emoji = emoji ?? button.toString().addBrackets(); + dInside.emoji = emoji || undefined; + } } + buttonPart.push(dInside); + } + } + if (Checker("selectMenu")) { + let inside = aoi.split("{selectMenu:").slice(1).join(""); + inside = inside.split(":").map((c) => c.trim()); + const customID = inside.shift(); + const placeholder = inside.shift(); + const minVal = inside[0] === "" ? 0 : Number(inside.shift()); + const maxVal = inside[0] === "" ? 1 : Number(inside.shift()); + const disabled = inside.shift() === "true"; + const options = inside.join(":").trim(); - if (m && edits.timeout) { - for (const code of edits.messages) { - await new Promise((e) => setTimeout(e, edits.timeout)); + let optArray = []; + if (options.includes("{selectMenuOptions:")) { + const opts = options.split("{selectMenuOptions:").slice(1); - const sender = await errorHandler(d, code, true); + for (let opt of opts) { + opt = opt.split("}")[0].split(":"); + const label = opt.shift(); + const value = opt.shift(); + const desc = opt.shift(); + const def = opt.shift() === "true"; + let emoji; - await m.suppressEmbeds(suppress); + const ind = { + label: label, + value: value, + description: desc, + default: def, + }; - await m.edit(sender.message, sender.embed).catch(() => null); + if (opt) { + try { + emoji = d.util.getEmoji(d, opt.toString().addBrackets()); + ind.emoji = { + name: emoji.name, + id: emoji.id, + animated: emoji.animated, + }; + } catch { + emoji = emoji ?? opt.toString().addBrackets(); + ind.emoji = emoji || undefined; } - } + } - if (m && deleteAfter) { - m.delete({ - timeout: deleteAfter, - }).catch(() => null); + optArray.push(ind); } + } - if (returnMsg === "id") { - return m.id; - } else if (returnMsg === "object") { - return m; - } else if (returnMsg === "withMessage") return m; + buttonPart.push({ + type: 3, + custom_id: customID, + placeholder: placeholder, + min_values: minVal, + max_values: maxVal, + disabled, + options: optArray, + }); + } + if (Checker("textInput")) { + let inside = aoi.split("{textInput:").slice(1); + for (let textInput of inside) { + textInput = textInput.split("}")[0].split(":"); + const label = textInput.shift().addBrackets().trim(); + let style = textInput.shift().addBrackets().trim(); + style = isNaN(style) ? style : Number(style); + const custom_id = textInput.shift().addBrackets().trim(); + const required = textInput.shift()?.addBrackets().trim() === "true"; + const placeholder = textInput.shift()?.addBrackets().trim(); + const min_length = textInput.shift()?.addBrackets().trim(); + const max_length = textInput.shift()?.addBrackets().trim(); + const value = textInput.shift()?.addBrackets().trim(); + buttonPart.push({ + type: 4, + label, + style, + custom_id, + required, + placeholder, + min_length, + max_length, + value, + }); + } } + actionRows.push({ type: 1, components: buttonPart }); + } + return actionRows; }; -const SlashOptionsParser = async (options) => { - options = mustEscape(options); - let Alloptions = []; - options = options.trim(); - const Checker = (msg) => options.includes("{" + msg + ":"); +const FileParser = (msg, d) => { + if (!msg) return; + msg = mustEscape(msg); + const Checker = (ayaya) => msg.includes("{" + ayaya + ":"); - if (Checker("subGroup")) { - Alloptions = Alloptions.concat(await SlashOption.subGroup(options)); - } - if (Checker("subCommand") && !Checker("subGroup")) { - Alloptions = Alloptions.concat(await SlashOption.subCommand(options)); - } - if (Checker("string") && !(Checker("subCommand") || Checker("subGroup"))) { - Alloptions = Alloptions.concat(await SlashOption.string(options)); - } - if (Checker("integer") && !(Checker("subCommand") || Checker("subGroup"))) { - Alloptions = Alloptions.concat(await SlashOption.integer(options)); - } - if (Checker("boolean") && !(Checker("subCommand") || Checker("subGroup"))) { - Alloptions = Alloptions.concat(await SlashOption.boolean(options)); - } - if (Checker("user") && !(Checker("subCommand") || Checker("subGroup"))) { - Alloptions = Alloptions.concat(await SlashOption.user(options)); - } - if (Checker("channel") && !(Checker("subCommand") || Checker("subGroup"))) { - Alloptions = Alloptions.concat(await SlashOption.channel(options)); - } - if (Checker("role") && !(Checker("subCommand") || Checker("subGroup"))) { - Alloptions = Alloptions.concat(await SlashOption.role(options)); - } - if ( - Checker("mentionable") && - !(Checker("subCommand") || Checker("subGroup")) - ) { - Alloptions = Alloptions.concat(await SlashOption.mentionable(options)); + const att = []; + if (Checker("attachment")) { + const e = msg + ?.split("{attachment:") + ?.slice(1) + .map((x) => x.trim()); + for (let o of e) { + o = o.split("}")[0]; + o = o.split(":"); + + const attachment = new Discord.AttachmentBuilder(o.pop().addBrackets(), { + name: o.join(":").toString().addBrackets() ?? "attachment.png", + }); + att.push(attachment); } - if (Checker("number") && !(Checker("subCommand") || Checker("subGroup"))) { - Alloptions = Alloptions.concat(await SlashOption.number(options)); + } + if (Checker("file")) { + const i = msg + .split("{file:") + ?.slice(1) + .map((x) => x.trim()); + for (let u of i) { + u = u.split("}")[0]; + u = u.split(":"); + + const attachment = new Discord.AttachmentBuilder( + Buffer.from(u.pop().addBrackets()), + { name: u.join(":").toString().addBrackets() ?? "file.txt" } + ); + att.push(attachment); } + } + return att; +}; + +const errorHandler = async (errorMessage, d, returnMsg = false, channel) => { + const Checker = (parts, ayaya) => parts.includes("{" + ayaya + ":"); + + errorMessage = errorMessage.trim(); + let suppress = false; + let send = true; - return Alloptions; + let files = []; + const embeds = []; + const components = []; + + const parts = CreateObjectAST(errorMessage); + for (const part of parts) { + errorMessage = errorMessage.replace(part, ""); + if (Checker(part, "newEmbed")) embeds.push(...(await EmbedParser(part, d))); + else if (Checker(part, "actionRow")) + components.push(...(await ComponentParser(part, d))); + else if (Checker(part, "attachment") || Checker(part, "file")) + files = FileParser(part, d); + else if (Checker(part, "suppress")) suppress = true; + } + + if (!embeds.length || (send && suppress)) send = false; + + if (returnMsg === true) { + return { + embeds: send ? embeds : [], + components, + content: errorMessage.addBrackets() === "" ? " " : errorMessage.addBrackets(), + files, + options: { + suppress, + }, + }; + } + + errorMessage = errorMessage.addBrackets().trim(); + if (!(errorMessage.length || send || files.length)) return; + + const ch = channel || d.channel; + + if ((errorMessage.length || send || files.length) && d && ch && !returnMsg) { + const m = await ch + .send({ + content: errorMessage.addBrackets(), + embeds: send ? embeds : [], + files: files?.length ? files : [], + }) + .catch(() => {}); + + if (!m) return; + + if (returnMsg === "id") { + return m.id; + } else if (returnMsg === "object") { + return m; + } else if (returnMsg === "withMessage") return m; + } }; -const OptionParser = async (options, d) => { - const Checker = (msg) => options.includes(msg); - const optionData = {}; - if (Checker("{edit:")) { - const editPart = options.split("{edit:")[1].split("}}")[0]; - const dur = editPart.split(":")[0]; - const msgs = editPart.split(":{").slice(1).join(":{").split("}:{"); - const messages = []; - for (const msg of msgs) { - messages.push(await errorHandler(msg.split("}:{")[0], d)); - } - optionData.edits = { time: dur, messages }; - } - if (Checker("{reactions:")) { - const react = options.split("{reactions:")[1].split("}")[0]; - optionData.reactions = react.split(",").map((x) => x.trim()); - } - if (Checker("{delete:")) { - optionData.deleteIn = Time.parse( - options.split("{delete:")[1].split("}")[0].trim(), - )?.ms; - } - if (Checker("deletecommand")) { - optionData.deleteCommand = true; - } - if (Checker("interaction")) { - optionData.interaction = true; - } - return optionData; + +const SlashOptionsParser = async (options) => { + options = mustEscape(options); + + let Alloptions = []; + options = options.trim(); + const Checker = (msg) => options.includes("{" + msg + ":"); + + if (Checker("subGroup")) { + Alloptions = Alloptions.concat(await SlashOption.subGroup(options)); + } + if (Checker("subCommand") && !Checker("subGroup")) { + Alloptions = Alloptions.concat(await SlashOption.subCommand(options)); + } + if (Checker("string") && !(Checker("subCommand") || Checker("subGroup"))) { + Alloptions = Alloptions.concat(await SlashOption.string(options)); + } + if (Checker("integer") && !(Checker("subCommand") || Checker("subGroup"))) { + Alloptions = Alloptions.concat(await SlashOption.integer(options)); + } + if (Checker("boolean") && !(Checker("subCommand") || Checker("subGroup"))) { + Alloptions = Alloptions.concat(await SlashOption.boolean(options)); + } + if (Checker("user") && !(Checker("subCommand") || Checker("subGroup"))) { + Alloptions = Alloptions.concat(await SlashOption.user(options)); + } + if (Checker("channel") && !(Checker("subCommand") || Checker("subGroup"))) { + Alloptions = Alloptions.concat(await SlashOption.channel(options)); + } + if (Checker("role") && !(Checker("subCommand") || Checker("subGroup"))) { + Alloptions = Alloptions.concat(await SlashOption.role(options)); + } + if (Checker("mentionable") && !(Checker("subCommand") || Checker("subGroup"))) { + Alloptions = Alloptions.concat(await SlashOption.mentionable(options)); + } + if (Checker("number") && !(Checker("subCommand") || Checker("subGroup"))) { + Alloptions = Alloptions.concat(await SlashOption.number(options)); + } + + return Alloptions; }; + module.exports = { - EmbedParser: EmbedParser, - ComponentParser: ComponentParser, - FileParser: FileParser, - ErrorHandler: errorHandler, - SlashOptionsParser: SlashOptionsParser, - OptionParser, -}; -/*Copyright © 2021 - 2022 @Akarui Development*/ + EmbedParser, + ComponentParser, + FileParser, + ErrorHandler: errorHandler, + SlashOptionsParser +}; \ No newline at end of file