djs-systems
Version:
The simplest way to build complex Discord bots.
282 lines (281 loc) • 11.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculator = void 0;
const discord_js_1 = require("discord.js");
const misc_1 = require("./misc");
const error_1 = require("./error");
// ------------------------------
// ------ F U N C T I O N -------
// ------------------------------
/**
* An Unique **calculator** which can be *used inside Discord*
* @param msgOrInt
* @param options
* @link `Documentation:` https://simplyd.js.org/docs/general/calculator
* @example simplydjs.calculator(interaction)
*/
async function calculator(msgOrInt, options = {
strict: false,
buttons: {
numbers: discord_js_1.ButtonStyle.Secondary,
symbols: discord_js_1.ButtonStyle.Primary,
delete: discord_js_1.ButtonStyle.Danger
}
}) {
return new Promise(async () => {
try {
const buttons = [[], [], [], [], []];
const row = [];
const text = [
'Clear',
'(',
')',
'/',
'Back',
'7',
'8',
'9',
'*',
'%',
'4',
'5',
'6',
'-',
'^',
'1',
'2',
'3',
'+',
'π',
'.',
'0',
'00',
'=',
'Delete'
];
let current = 0;
if (!options.embed) {
options.embed = {
footer: {
text: '©️ Rahuletto. npm i simply-djs',
iconURL: 'https://i.imgur.com/XFUIwPh.png'
},
color: (0, misc_1.toRgb)('#406DBC')
};
}
const buttonStyles = {
numbers: options?.buttons?.numbers || discord_js_1.ButtonStyle.Secondary,
symbols: options?.buttons?.symbols || discord_js_1.ButtonStyle.Primary,
delete: options?.buttons?.delete || discord_js_1.ButtonStyle.Danger
};
if (buttonStyles.delete)
buttonStyles.delete = (0, misc_1.toButtonStyle)(buttonStyles.delete);
if (buttonStyles.numbers)
buttonStyles.numbers = (0, misc_1.toButtonStyle)(buttonStyles.numbers);
if (buttonStyles.symbols)
buttonStyles.symbols = (0, misc_1.toButtonStyle)(buttonStyles.symbols);
let message;
if (!msgOrInt.commandId) {
message = msgOrInt;
}
if (msgOrInt.commandId && !msgOrInt.deferred)
await msgOrInt.deferReply({
fetchReply: true
});
for (let i = 0; i < text.length; i++) {
if (buttons[current].length === 5)
current++;
buttons[current].push(createButton(text[i]));
if (i === text.length - 1) {
for (const btn of buttons)
row.push(addRow(btn));
}
}
const embed = new discord_js_1.EmbedBuilder()
.setColor(options?.embed?.color || (0, misc_1.toRgb)('#406DBC'))
.setFooter(options?.embed?.footer
? options?.embed?.footer
: {
text: '©️ Rahuletto. npm i simply-djs',
iconURL: 'https://i.imgur.com/XFUIwPh.png'
})
.setDescription('```js\n0\n// Result: 0\n```' +
(options?.embed?.description
? `\n${options?.embed?.description}`
: ''));
if (options?.embed?.fields)
embed.setFields(options.embed?.fields);
if (options?.embed?.author)
embed.setAuthor(options.embed?.author);
if (options?.embed?.image)
embed.setImage(options.embed?.image);
if (options?.embed?.thumbnail)
embed.setThumbnail(options.embed?.thumbnail);
if (options?.embed?.timestamp)
embed.setTimestamp(options.embed?.timestamp);
if (options?.embed?.title)
embed.setTitle(options.embed?.title);
if (options?.embed?.url)
embed.setURL(options.embed?.url);
let msg;
const extInteraction = msgOrInt;
const extMessage = msgOrInt;
if (!message) {
await extInteraction.followUp({
embeds: [embed],
components: row
});
msg = await extInteraction.fetchReply();
}
else if (message) {
msg = await extMessage.reply({
embeds: [embed],
components: row
});
}
let elem = '0';
const filter = (buttons) => buttons.user?.id === msgOrInt.member.user.id &&
buttons.customId.startsWith('cal-');
const collector = msg.createMessageComponentCollector({
filter: filter,
componentType: discord_js_1.ComponentType.Button,
time: (0, misc_1.ms)('5m')
});
collector.on('collect', async (buttons) => {
await buttons.deferUpdate();
const name = buttons.customId.replace('cal-', '');
if (elem === '0')
elem = '';
if (name === '=') {
embed.setDescription(`\`\`\`js\n${mathEval(elem, true)}\n\`\`\`` +
(options.embed?.description
? `\n${options.embed?.description}`
: ''));
elem = mathEval(elem);
await msg
.edit({
embeds: [embed],
components: row
})
.catch(() => { });
return;
}
if (name === 'Back')
elem = elem.slice(0, -1);
else
elem = elem + name.toString();
if (name === 'Delete')
await msg.delete().catch(() => { });
else if (name === 'Clear')
elem = '0';
if (isNaN(Number(name)) && name !== 'Back') {
embed.setDescription(`\`\`\`js\n${elem
.replaceAll('+', ' + ')
.replaceAll('*', ' * ')}\n\t\n\`\`\`` +
(options?.embed?.description
? `\n${options?.embed?.description}`
: ''));
await msg
.edit({
embeds: [embed],
components: row
})
.catch(() => { });
return;
}
embed.setDescription(`\`\`\`js\n${elem
.replaceAll('+', ' + ')
.replaceAll('*', ' * ')}\n// Result: ${mathEval(elem)
.replaceAll('^', '**')
.replaceAll('%', '/100')
.replace(' ', '')}\n\`\`\`` +
(options.embed?.description
? `\n${options.embed?.description}`
: ''));
await msg
.edit({
embeds: [embed],
components: row
})
.catch(() => { });
return;
});
setTimeout(async () => {
if (!msg)
return;
if (!msg.editable)
return;
if (msg) {
if (msg.editable) {
embed.setDescription('Your Time for using the calculator ran out (5 minutes)');
embed.setColor((0, misc_1.toRgb)('#c90000'));
await msg.edit({ embeds: [embed], components: [] }).catch(() => { });
}
}
}, (0, misc_1.ms)('5m'));
function addRow(btns) {
const row1 = new discord_js_1.ActionRowBuilder();
for (const btn of btns) {
row1.addComponents(btn);
}
return row1;
}
function createButton(label, style = buttonStyles.numbers) {
if (label === 'Clear')
style = buttonStyles.delete;
else if (label === 'Delete')
style = buttonStyles.delete;
else if (label === 'Back')
style = buttonStyles.delete;
else if (label === 'π')
style = buttonStyles.numbers;
else if (label === '%')
style = buttonStyles.numbers;
else if (label === '^')
style = buttonStyles.numbers;
else if (label === '.')
style = buttonStyles.symbols;
else if (label === '=')
style = discord_js_1.ButtonStyle.Success;
else if (isNaN(Number(label)))
style = buttonStyles.symbols;
const btn = new discord_js_1.ButtonBuilder()
.setLabel(label.toString())
.setStyle(style)
.setCustomId('cal-' + label);
return btn;
}
// Regex for calculation to avoid any malicious code injection at eval()
const evalRegex = /^[0-9π\+\%\^\-*\/\.\(\)]*$/;
function mathEval(input, result = false) {
try {
const matched = evalRegex.exec(input);
if (!matched)
return 'Invalid Expression';
if (result === false) {
// Evaluates the expressions (Security Risk | Prevented by regex testing)
return `${Function(`"use strict";let π=Math.PI;return (${input})`)()}`;
}
else
return `${input
.replaceAll('**', '^') // Evaluates the expressions (Security Risk | Prevented by regex testing)
.replaceAll('/100', '%')} = ${Function(`"use strict";let π=Math.PI;return (${input})`)()}`;
}
catch {
return 'Wrong Input';
}
}
}
catch (err) {
if (options?.strict)
throw new error_1.SimplyError({
function: 'calculator',
title: 'An Error occured when running the function ',
tip: err.stack
});
else
console.log(`SimplyError - calculator | Error: ${err.stack}`);
}
});
}
exports.calculator = calculator;