mirror of
https://github.com/danbulant/Shasha
synced 2026-05-20 12:38:48 +00:00
117 lines
3.6 KiB
JavaScript
117 lines
3.6 KiB
JavaScript
const util = require('util');
|
|
const discord = require('discord.js');
|
|
const tags = require('common-tags');
|
|
const { escapeRegex } = require('../../node_modules/@iceprod/discord.js-commando/src/util');
|
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
|
|
|
const nl = '!!NL!!';
|
|
const nlPattern = new RegExp(nl, 'g');
|
|
|
|
module.exports = class EvalCommand extends Command {
|
|
constructor(client) {
|
|
super(client, {
|
|
name: 'eval',
|
|
group: 'owner',
|
|
memberName: 'eval',
|
|
description: 'Executes JavaScript code.',
|
|
details: 'Only the bot owner(s) may use this command.',
|
|
ownerOnly: true,
|
|
hidden: true,
|
|
|
|
args: [
|
|
{
|
|
key: 'script',
|
|
prompt: 'What code would you like to evaluate?',
|
|
type: 'string'
|
|
}
|
|
]
|
|
});
|
|
|
|
this.lastResult = null;
|
|
Object.defineProperty(this, '_sensitivePattern', { value: null, configurable: true });
|
|
}
|
|
|
|
async run(msg, args) {
|
|
// Make a bunch of helpers
|
|
/* eslint-disable no-unused-vars */
|
|
const message = msg;
|
|
const client = msg.client;
|
|
const lastResult = this.lastResult;
|
|
const doReply = val => {
|
|
if (val instanceof Error) {
|
|
msg.reply(`Callback error: \`${val}\``);
|
|
} else {
|
|
const result = this.makeResultMessages(val, process.hrtime(this.hrStart));
|
|
if (Array.isArray(result)) {
|
|
for (const item of result) msg.reply(item);
|
|
} else {
|
|
msg.reply(result);
|
|
}
|
|
}
|
|
};
|
|
/* eslint-enable no-unused-vars */
|
|
|
|
// Remove any surrounding code blocks before evaluation
|
|
if (args.script.startsWith('```') && args.script.endsWith('```')) {
|
|
args.script = args.script.replace(/(^.*?\s)|(\n.*$)/g, '');
|
|
}
|
|
|
|
// Run the code and measure its execution time
|
|
let hrDiff;
|
|
try {
|
|
const hrStart = process.hrtime();
|
|
this.lastResult = await eval(args.script);
|
|
hrDiff = process.hrtime(hrStart);
|
|
} catch (err) {
|
|
return msg.reply(`\`\`\`\n${err.stack}\`\`\``);
|
|
}
|
|
|
|
// Prepare for callback time and respond
|
|
this.hrStart = process.hrtime();
|
|
const result = this.makeResultMessages(this.lastResult, hrDiff, args.script);
|
|
if (Array.isArray(result)) {
|
|
return result.map(item => msg.reply(item));
|
|
} else {
|
|
return msg.reply(result);
|
|
}
|
|
}
|
|
|
|
makeResultMessages(result, hrDiff, input = null) {
|
|
const inspected = util.inspect(result, { depth: 0 })
|
|
.replace(nlPattern, '\n')
|
|
.replace(this.sensitivePattern, '--snip--');
|
|
const split = inspected.split('\n');
|
|
const last = inspected.length - 1;
|
|
const prependPart = inspected[0] !== '{' && inspected[0] !== '[' && inspected[0] !== "'" ? split[0] : inspected[0];
|
|
const appendPart = inspected[last] !== '}' && inspected[last] !== ']' && inspected[last] !== "'" ?
|
|
split[split.length - 1] :
|
|
inspected[last];
|
|
const prepend = `\`\`\`javascript\n${prependPart}\n`;
|
|
const append = `\n${appendPart}\n\`\`\``;
|
|
if (input) {
|
|
return discord.splitMessage(tags.stripIndents`
|
|
*Executed in ${hrDiff[0] > 0 ? `${hrDiff[0]}s ` : ''}${hrDiff[1] / 1000000}ms.*
|
|
\`\`\`javascript
|
|
${inspected}
|
|
\`\`\`
|
|
`, { maxLength: 2000, prepend, append });
|
|
} else {
|
|
return discord.splitMessage(tags.stripIndents`
|
|
*Callback executed after ${hrDiff[0] > 0 ? `${hrDiff[0]}s ` : ''}${hrDiff[1] / 1000000}ms.*
|
|
\`\`\`javascript
|
|
${inspected}
|
|
\`\`\`
|
|
`, { maxLength: 2000, prepend, append });
|
|
}
|
|
}
|
|
|
|
get sensitivePattern() {
|
|
if (!this._sensitivePattern) {
|
|
const client = this.client;
|
|
let pattern = '';
|
|
if (client.token) pattern += escapeRegex(client.token);
|
|
Object.defineProperty(this, '_sensitivePattern', { value: new RegExp(pattern, 'gi'), configurable: false });
|
|
}
|
|
return this._sensitivePattern;
|
|
}
|
|
};
|