From 0d21cbce6875213f697978aaf73b0253151d0115 Mon Sep 17 00:00:00 2001 From: Lordex <130374125+LordexDuck3990@users.noreply.github.com> Date: Sat, 25 Nov 2023 16:52:10 +0200 Subject: [PATCH] Update parsers.js --- src/handler/parsers.js | 1297 ++++++++++++++++++++++++---------------- 1 file changed, 778 insertions(+), 519 deletions(-) diff --git a/src/handler/parsers.js b/src/handler/parsers.js index a0c9aee67..95b22c44c 100644 --- a/src/handler/parsers.js +++ b/src/handler/parsers.js @@ -1,495 +1,11 @@ const Discord = require("discord.js"); const { mustEscape } = require("../utils/helpers/mustEscape.js"); const { ButtonStyleOptions } = require("../utils/Constants.js"); +const Util = require("../classes/Util.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); - } - 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(); - // console.log({ - // type: 4, - // label, - // style, - // custom_id, - // required, - // placeholder, - // min_length, - // max_length, - // value, - // }); - buttonPart.push({ - type: 4, - label, - style, - custom_id, - required, - placeholder, - min_length, - max_length, - value, - }); - } - } - actionRows.push({ type: 1, components: buttonPart }); - } - 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); - } - 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("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); - } - } - 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 (!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, - }, - }; - } - - 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); - } - } - - if (m && edits.timeout) { - for (const code of edits.messages) { - await new Promise((e) => setTimeout(e, edits.timeout)); - - const sender = await errorHandler(d, code, true); - - await m.suppressEmbeds(suppress); - - await m.edit(sender.message, sender.embed).catch(() => null); - } - } - - if (m && deleteAfter) { - m.delete({ - timeout: deleteAfter, - }).catch(() => null); - } - - if (returnMsg === "id") { - return m.id; - } else if (returnMsg === "object") { - return m; - } else if (returnMsg === "withMessage") return m; - } -}; const SlashOptionsParser = async (options) => { options = mustEscape(options); @@ -533,42 +49,785 @@ const SlashOptionsParser = async (options) => { return Alloptions; }; -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)); + +/** + * This function check if the given text is boolean true or false. + * @param {string} text - The text to check. + * @param {boolean} orelse - The boolean to return if its not boolean. + * @returns {boolean} - The result. +*/ +let checkBoolean = (text, orelse) => { + if (orelse && typeof orelse !== "boolean") return; + if (!text || typeof text !== "string" ) return orelse; + + if ( text && text.trim() && (text.trim() === "" || text.trim() === " ") ) + return orelse; + + let yes = [ "true" ]; + let no = [ "false" ]; + + if (yes.find(x => x.toLowerCase() === text?.trim().toLowerCase())) + return true ; + + if (no .find(x => x.toLowerCase() === text?.trim().toLowerCase())) + return false; +}; + +let ctypes = { + text: 0, + voice: 2, + category: 4, + announce: 5, + announcement: 5, + "announce thread": 10, + "announcement thread": 10, + "public thread": 11, + "private thread": 12, + "stage": 13, + forum: 15, + media: 16 +}; + +module.exports = { + parsers: { + // Parsers list + EmbedParser: { + name: ["newEmbed", "Embed"], + code: async (d, data) => { + let code = mustEscape(data.part); + let nameofparserorsmtidk = "newEmbed"; + + if (data.Checker(code, "Embed")) nameofparserorsmtidk = "Embed"; + + let elements = code.split("{" + nameofparserorsmtidk + ":").slice(1); + + const embeds = []; + + for (let element of elements) { + let embed = { + fields: [], + }; + + element = element.slice(0, element.length - 1); + + const Checker = (name) => element.includes(`{${name}:`); + + if (Checker("author")) { + const params = element + .split("{author:")[1] + .split("}")[0] + .split(":"); + + embed.author = { + name: params.shift().addBrackets()?.trim() || "", + icon_url: params.join(":").addBrackets()?.trim() || "", + }; + } + + if (Checker("authorURL")) { + if (!embed.author) return console.error("{author:} was not used"); + + embed.author.url = element + .split("{authorURL:")[1] + .split("}")[0] + .addBrackets() + .trim(); + } + + if (Checker("color")) { + embed.color = Discord.resolveColor( + element.split("{color:")[1].split("}")[0].addBrackets().trim(), + ); + } + + if (Checker("title")) { + embed.title = element + .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 = element + .split("{url:")[1] + .split("}")[0] + .addBrackets() + .trim(); + } + + if (Checker("thumbnail")) { + embed.thumbnail = { + url: element + .split("{thumbnail:")[1] + .split("}")[0] + .addBrackets() + .trim(), + }; + } + + if (Checker("description")) { + embed.description = element + .split("{description:")[1] + .split("}")[0] + .addBrackets() + .trim(); + } + + if (Checker("image")) { + embed.image = { + url: element + .split("{image:")[1] + .split("}")[0] + .addBrackets() + .trim(), + }; + } + + if (Checker("footer")) { + const params = element + .split("{footer:")[1] + .split("}")[0] + .split(":"); + + embed.footer = { + text: params.shift().addBrackets().trim() || "", + icon_url: params.join(":").addBrackets().trim() || "", + }; + } + + if (element.includes("{timestamp")) { + let time = element + .split("{timestamp")[1] + .split("}")[0] + .replace(":", "") + .trim(); + + if (time === "" || time === "ms") { + time = Date.now(); + } + + embed.timestamp = new Date(time); + } + + if (Checker("field")) { + const params = element.split("{field:").slice(1); + for (let param of params) { + param = param.split("}")[0].split(":"); + const name = param.shift().addBrackets().trim(); + const inline = checkBoolean(param[Number(param.length - 1)]); + + const value = param.join(":").addBrackets().trim(); + embed.fields.push({ name: name, value: value, inline: inline }); + } + } + + embeds.push(embed); + } + + if (data && data.newMessageData && data.newMessageData.embeds) data.newMessageData.embeds.push(...embeds); + return embeds; + }, + }, + ComponentParser: { + name: ["actionRow", "Components", "newRow"], + code: async (d, data) => { + let code = mustEscape(data.part); + let nameofparserorsmtidk = "actionRow"; + + if (data.Checker(code, "Components")) + nameofparserorsmtidk = "Components"; + else if (data.Checker(code, "newRow")) + nameofparserorsmtidk = "newRow"; + + let elements = code.split("{" + nameofparserorsmtidk + ":").slice(1); + + let rows = []; + + for (var element of elements) { + element = element.slice(0, element.lastIndexOf("}")); + + const Checker = (name) => element.includes(`{${name}:`); + + let components = []; + + if (Checker("button")) { + var buttons = element.split("{button:").slice(1); + + for (let params of buttons) { + params = params?.split("}")[0]?.split(":").map((param) => param?.addBrackets()?.trim()); + + var button = { + type: 2 + }; + + var label = params?.shift(); + var style = params?.shift(); + var IDorURL = params?.shift(); + var disabled = checkBoolean(params?.shift(), false); + var emoji = params.length !== 0 ? params.join(":") : undefined; + + style = ButtonStyleOptions[style] || style; + + if (style && Number(style) === 5) + button.url = IDorURL; + else + button.custom_id = IDorURL; + + if (emoji) { + let [animated, name, id] = emoji.split(":"); + if (!name && !id) { + name = animated; + id = ""; + animated = ""; + }; + + id = id.replace(">", ""); + emoji = { + name: name, + id: id === "" ? undefined : id, + animated: animated.replace("<", "") === "a" + }; + }; + + button.label = label; + button.style = style; + button.disabled = disabled; + button.emoji = emoji; + + components.push(button); + } + } + + if (Checker("selectMenu") || Checker("stringSelectMenu")) { + let inside = Checker("stringSelectMenu") ? element.split("{stringSelectMenu:").slice(1).join("").split(":").map((param) => param.trim()) : element.split("{selectMenu:").slice(1).join("").split(":").map((param) => param.trim()); + + const ID = inside?.shift()?.addBrackets(); + const placeholder = inside?.shift()?.addBrackets(); + const minValues = inside[0] === "" ? 0 : Number(inside?.shift()?.addBrackets()); + const maxValues = inside[0] === "" ? 1 : Number(inside?.shift()?.addBrackets()); + const disabled = checkBoolean(inside?.shift()?.addBrackets(), false); + const options = inside?.join(":"); + + let stringSelectMenu = { + type: 3, + custom_id: ID, + placeholder: placeholder, + min_values: minValues, + max_values: maxValues, + disabled, + options: [] + }; + + if (options.includes("{selectMenuOptions:") || options.includes("{selectMenuOption:") || options.includes("{option:")) { + var smosORsmORo = "selectMenuOptions"; + if (options.includes("{selectMenuOption:")) + smosORsmORo = "selectMenuOption"; + else if (options.includes("{option:")) + smosORsmORo = "option"; + + const allOptions = options.split(`{${smosORsmORo}:`).slice(1); + + for (var option of allOptions) { + option = option.split("}")[0].split(":"); + + let selectMenuOption = { }; + + const label = option?.shift()?.trim(); + const value = option?.shift()?.trim(); + const description = option?.shift()?.trim(); + const def = checkBoolean(option?.shift()?.trim(), false); + const emoji = option.length !== 0 ? option?.join(":")?.trim()?.addBrackets() : undefined; + + if (emoji) { + let [animated, name, id] = emoji.split(":"); + if (!name && !id) { + name = animated; + id = ""; + animated = ""; + }; + + id = id.replace(">", ""); + emoji = { + name: name, + id: id === "" ? undefined : id, + animated: animated.replace("<", "") === "a" + }; + }; + + selectMenuOption.label = label; + selectMenuOption.value = value; + selectMenuOption.description = description; + selectMenuOption.default = def; + + if (emoji) selectMenuOption.emoji = emoji; + + stringSelectMenu.options.push(selectMenuOption); + }; + }; + + components.push(stringSelectMenu); + } + + if (Checker("userSelectMenu")) { + let inside = element.split("{userSelectMenu:").slice(1).join("").split(":").map((param) => param?.addBrackets()?.trim()); + + const ID = inside?.shift(); + const placeholder = inside?.shift(); + const minValues = inside[0] === "" ? 0 : Number(inside?.shift()); + const maxValues = inside[0] === "" ? 1 : Number(inside?.shift()); + const disabled = checkBoolean(inside?.shift(), false); + + let stringSelectMenu = { + type: 5, + custom_id: ID, + placeholder: placeholder, + min_values: minValues, + max_values: maxValues, + disabled + }; + + components.push(stringSelectMenu); + } + + if (Checker("roleSelectMenu")) { + let inside = element.split("{roleSelectMenu:").slice(1).join("").split(":").map((param) => param?.addBrackets()?.trim()); + + const ID = inside?.shift(); + const placeholder = inside?.shift(); + const minValues = inside[0] === "" ? 0 : Number(inside?.shift()); + const maxValues = inside[0] === "" ? 1 : Number(inside?.shift()); + const disabled = checkBoolean(inside?.shift(), false); + + let stringSelectMenu = { + type: 6, + custom_id: ID, + placeholder: placeholder, + min_values: minValues, + max_values: maxValues, + disabled, + }; + + components.push(stringSelectMenu); + } + + if (Checker("mentionSelectMenu")) { + let inside = element.split("{mentionSelectMenu:").slice(1).join("").split(":").map((param) => param?.addBrackets()?.trim()); + + const ID = inside?.shift(); + const placeholder = inside?.shift(); + const minValues = inside[0] === "" ? 0 : Number(inside?.shift()); + const maxValues = inside[0] === "" ? 1 : Number(inside?.shift()); + const disabled = checkBoolean(inside?.shift(), false); + + let stringSelectMenu = { + type: 7, + custom_id: ID, + placeholder: placeholder, + min_values: minValues, + max_values: maxValues, + disabled, + }; + + components.push(stringSelectMenu); + } + + if (Checker("channelSelectMenu")) { + let inside = element.split("{channelSelectMenu:").slice(1).join("").split("}")[0].split(":").map((param) => param?.addBrackets()?.trim()); + + const ID = inside?.shift(); + const placeholder = inside?.shift(); + const minValues = inside[0] === "" ? 0 : Number(inside?.shift()); + const maxValues = inside[0] === "" ? 1 : Number(inside?.shift()); + const disabled = checkBoolean(inside?.shift(), false); + var channelTypes = inside.length !== 0 ? inside?.map((type) => type.addBrackets()).map((type) => !isNaN(Number(type)) ? Number(type) : ctypes[type?.toLowerCase()]) : []; + + let stringSelectMenu = { + type: 8, + custom_id: ID, + placeholder: placeholder, + min_values: minValues, + max_values: maxValues, + channel_types: channelTypes, + disabled, + }; + + components.push(stringSelectMenu); + } + + if (Checker("textInput") || Checker("modalOption")) { + let options = Checker("modalOption") ? element.split("{modalOption:").slice(1) : element.split("{textInput:").slice(1); + + for (var option of options) { + option = option.split("}")[0].split(":").map((param) => param?.addBrackets()?.trim()); + + let modalOption = { + type: 4 + }; + + const label = option?.shift(); + var style = option?.shift(); + style = isNaN(style) ? style : Number(style); + const ID = option?.shift(); + const required = checkBoolean(option?.shift()) ?? undefined; + const placeholder = option?.shift() ?? undefined; + const min = option?.shift() ?? undefined; + const max = option?.shift() ?? undefined; + const defValue = option?.shift() ?? undefined; + + modalOption.label = label; + modalOption.style = Number(style); + modalOption.custom_id = ID; + modalOption.required = required; + modalOption.placeholder = placeholder; + modalOption.min_length = parseFloat(min); + modalOption.max_length = parseFloat(max); + modalOption.value = defValue; + + console.log(modalOption); + + components.push(modalOption); + }; + } + + rows.push({ type: 1, components: components }); + }; + + if (data && data.newMessageData && data.newMessageData.components) + data.newMessageData.components.push(...rows); + + return rows; + } + + }, + OptionParser: { + name: ["options", "extraOptions"], + code: async (d, data) => { + let code = mustEscape(data.part); + let nameofparserorsmtidk = "options"; + + if (data.Checker(code, "extraOptions")) + nameofparserorsmtidk = "extraOptions"; + + let options = code.split("{" + nameofparserorsmtidk + ":").slice(1); + + let Options = {}; + + if (data && data.newMessageData && data.newMessageData.options) + Options = data.newMessageData.options; + + for (var option of options) { + option = option.slice(0, option.length - 1); + + const Checker = (name) => option.includes(`{${name}:`); + const CheckerEmpty = (name) => option.includes(`{${name}}`); + + if (Checker("reply") || CheckerEmpty("reply")) { + const messageID = d.message.id; + + if (Checker("reply")) + messageID = option.split("{reply:")[1].split("}")[0]; + + Options.reply = { + messageReference: messageID + }; + } + + if (Checker("reactions")) { + const reactions = option + .split("{reactions:")[1] + .split("}")[0] + .split(":"); + + if (Options && !Options.reactions) + Options.reactions = []; + + Options.reactions.push(...reactions); + } + + if (Checker("interaction") || CheckerEmpty("interaction")) { + const trueorfalse = "true"; + + if (data && data.newMessageData && data.newMessageData.options) + data.newMessageData.options.interaction = checkBoolean(trueorfalse, true); + else + Options.interaction = checkBoolean(trueorfalse, true); + } + + if (Checker("ephemeral") || CheckerEmpty("ephemeral")) { + const trueorfalse = "true"; + + if (data && data.DataToReturnLol) + data.DataToReturnLol.ephemeral = checkBoolean(trueorfalse, true); + else + Options.ephemeral = checkBoolean(trueorfalse, true); + } + + if (Checker("tts") || CheckerEmpty("tts")) { + const trueorfalse = "true"; + + if (Checker("tts")) + trueorfalse = option.split("{tts:")[1].split("}")[0]; + + if (data && data.DataToReturnLol) + data.DataToReturnLol.tts = checkBoolean(trueorfalse, true); + else + Options.tts = checkBoolean(trueorfalse, true); + } + + if (Checker("allowedMentions")) { + let [subname, ...subvalues] = option.split("{allowedMentions:")[1].split("}")[0].addBrackets().split(":"); + subname = subname?.trim()?.toLowerCase(); + + if (data.DataToReturnLol) { + if (!data.DataToReturnLol.allowedMentions) + data.DataToReturnLol.allowedMentions = {}; + + if (subname === "parse") { + data.DataToReturnLol.allowedMentions.parse = subvalues; + } else if (subname === "roles") { + data.DataToReturnLol.allowedMentions.roles = subvalues; + } else if (subname === "users") { + data.DataToReturnLol.allowedMentions.users = subvalues; + } + } else { + if (!Options.allowedMentions) + Options.allowedMentions = {}; + + if (subname === "parse") { + Options.allowedMentions.parse = subvalues; + } else if (subname === "roles") { + Options.DataToReturnLol.allowedMentions.roles = subvalues; + } else if (subname === "users") { + Options.allowedMentions.users = subvalues; + } + }; + } + + if (Checker("deleteCommand") || CheckerEmpty("deleteCommand")) { + const trueorfalse = "true"; + + if (Checker("deleteCommand")) + trueorfalse = option.split("{deleteCommand:")[1].split("}")[0]; + + if (data.newMessageData && data.newMessageData.options) + data.newMessageData.options.deleteCommand = checkBoolean(trueorfalse, true); + else + Options.deleteCommand = checkBoolean(trueorfalse, true); + } + + if (Checker("fetchReply") || CheckerEmpty("fetchReply")) { + const trueorfalse = "true"; + + if (Checker("fetchReply")) + trueorfalse = option.split("{fetchReply:")[1].split("}")[0]; + + if (data && data.DataToReturnLol) + data.DataToReturnLol.fetchReply = checkBoolean(trueorfalse, true); + else + Options.fetchReply = checkBoolean(trueorfalse, true); + } + + if (Checker("deleteIn")) { + const sometime = option.split("{deleteIn:")[1].split("}")[0]; + + if (data.newMessageData && data.newMessageData.options) + data.newMessageData.options.deleteIn = sometime; + else + Options.deleteIn = sometime; + } + } + + if (data && data.newMessageData) + data.newMessageData.options = Options; + + return Options; + }, + }, + FileParser: { + name: ["file", "attachment"], + code: async (d, data) => { + let code = mustEscape(data.part); + + let Files = []; + + if (data.Checker(code, "file")) { + const files = code.split("{file:")?.slice(1)?.map((file) => file?.trim()); + + for (let file of files) { + var params = file?.split("}")[0]?.split(":"); + + console.log(params); + + const name = params?.shift()?.addBrackets(); + const content = params?.join(":")?.addBrackets(); + + const attachment = new Discord.AttachmentBuilder( + Buffer.from(content), + { name: name } + ); + + Files.push(attachment); + } + } + + if (data.Checker(code, "attachment")) { + const attachments = code?.split("{attachment:")?.slice(1).map((attachment) => attachment.trim()); + + for (let attach of attachments) { + var params = attach?.split("}")[0]?.split(":"); + + console.log(params); + + const name = params?.shift()?.addBrackets(); + const content = params?.join(":")?.addBrackets(); + + const attachment = new Discord.AttachmentBuilder(content, { name: name }); + + Files.push(attachment); + } + } + + if (data && data.newMessageData && data.newMessageData.files) + data.newMessageData.files.push(...Files); + + return Files; } - 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; + }, + + SlashOptionsParser, + + functions: { + setParser: (parser, newParserObject) => { + if (parser && typeof parser === "string" && newParserObject) + module.exports.parsers[parser] = newParserObject; + }, + deleteParser: (parser) => { + if ( + parser && + typeof parser === "string" && + module.exports.parsers[parser] + ) + delete module.exports.parsers[parser]; + }, + }, + + ErrorHandler: async (errorMessage, d, returnMsg = false, channel) => { + errorMessage = errorMessage.trim(); + + const Checker = (theparts, name) => theparts.includes("{" + name + ":"); + const parts = CreateObjectAST(errorMessage); + + let newMessageData = { + embeds: [], + components: [], + files: [], + options: {}, + suppress: true, + reply: undefined, + }; + + let DataToReturnLol = {}; + + // Running parsers + for (var part of parts) { + errorMessage = errorMessage.replace(part, ""); + + for (var parser in module.exports.parsers) { + if (module.exports.parsers[parser]) { + parser = module.exports.parsers[parser]; + if (!parser.name || !parser.code) + return console.error("No name/code in parser."); + + const names = Array.isArray(parser.name) + ? parser.name + : [parser.name]; + + let data = { + errorMessage, + returnMsg, + channel, + Checker, + parts, + parsers: module.exports.parsers, + part, + parser, + newMessageData, + parserFunctions: module.exports.functions, + DataToReturnLol + }; + + for (var name of names) { + if (Checker(part, name)) { + await parser.code(d, data); + } + } + } + } } - if (Checker("interaction")) { - optionData.interaction = true; + + let send = true; + + // Check stuff + if (!newMessageData.embeds.length || !newMessageData.suppress) send = false; + if (returnMsg) + return { + content: + errorMessage.addBrackets() === "" ? " " : errorMessage.addBrackets(), + embeds: send ? newMessageData.embeds : [], + components: newMessageData.components, + files: newMessageData.files, + options: newMessageData.options, + reply: newMessageData.reply ? newMessageData.reply : undefined, + ...DataToReturnLol, + }; + + errorMessage = errorMessage.addBrackets().trim(); + if (!(errorMessage.length || send || newMessageData.files.length)) return; + + const ch = channel || d.channel; + + if ( + (errorMessage.length || send || newMessageData.files.length) && + d && + ch && + !returnMsg + ) { + const newMessage = newMessageData.reply + ? await newMessageData.reply + .reply({ + content: errorMessage.addBrackets(), + embeds: send ? newMessageData.embeds : [], + components: newMessageData.components?.length + ? newMessageData.components + : [], + files: newMessageData.files?.length ? newMessageData.files : [], + ...DataToReturnLol, + }) + .catch(console.error) + : await ch + .send({ + content: errorMessage.addBrackets(), + embeds: send ? newMessageData.embeds : [], + components: newMessageData.components?.length + ? newMessageData.components + : [], + files: newMessageData.files?.length ? newMessageData.files : [], + ...DataToReturnLol, + }) + .catch(console.error); + + if (!newMessage) return; + + if (returnMsg === "id") { + return newMessage.id; + } else if (returnMsg === "object") { + return newMessage; + } else if (returnMsg === "withMessage") return newMessage; } - return optionData; -}; -module.exports = { - EmbedParser: EmbedParser, - ComponentParser: ComponentParser, - FileParser: FileParser, - ErrorHandler: errorHandler, - SlashOptionsParser: SlashOptionsParser, - OptionParser, + }, }; -/*Copyright © 2021 - 2022 @Akarui Development*/