Add files via upload
This commit is contained in:
parent
27b0800f62
commit
029c1ee51b
4 changed files with 395 additions and 0 deletions
41
common/evaluate.js
Normal file
41
common/evaluate.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
const AsyncFunction = (async()=>{}).constructor;
|
||||
|
||||
/* Evaluates code
|
||||
* @param {string} code Code to evaluate
|
||||
* @param {boolean} aweight Whether to await the evaluation
|
||||
* @param {boolean} global Whether to assign the next argument as the "this" for the evaluation
|
||||
* @param {any} [that]
|
||||
*/
|
||||
export default async function evaluate(code, aweight = true, global = false, that = {}) {
|
||||
if (!code) throw new Error("No code to evaluate");
|
||||
|
||||
let result,
|
||||
errored = false,
|
||||
timings = [+new Date()];
|
||||
const args = [];
|
||||
if (!global) args.push(...Object.keys(that));
|
||||
|
||||
let evalFunction = new AsyncFunction(...args, code);
|
||||
Object.keys(that).forEach((name, index) => {
|
||||
args[index] = that[name];
|
||||
});
|
||||
try {
|
||||
if (aweight) {
|
||||
result = await evalFunction(...args);
|
||||
} else {
|
||||
result = evalFunction(...args);
|
||||
}
|
||||
} catch (e) {
|
||||
result = e;
|
||||
errored = true;
|
||||
}
|
||||
timings[1] = +new Date();
|
||||
|
||||
const res = { result, errored, timings };
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
evaluate.SENSITIVE_PROPS = {
|
||||
USER: ["email", "phone", "mfaEnabled", "hasBouncedEmail"]
|
||||
}
|
||||
272
common/index.js
Normal file
272
common/index.js
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
export { mSendMessage } from "./mSendMessage.js";
|
||||
export const ZWD = "\u200d",
|
||||
Promise_UNMINIFIED_PROPERTY_NAMES = ["_deferredState", "_state", "_value", "_deferreds"],
|
||||
PROMISE_STATE_NAMES = {
|
||||
0: "pending",
|
||||
1: "fulfilled",
|
||||
2: "rejected",
|
||||
3: "adopted",
|
||||
};
|
||||
|
||||
export function codeblock(text, language = "", escape = false) {
|
||||
if (!text) throw new Error("No text to wrap in a codeblock provided");
|
||||
if (escape) text = text.replaceAll("```", `\`${ZWD}\`\``);
|
||||
return `\`\`\`${language}\n${text}\n\`\`\``;
|
||||
}
|
||||
|
||||
/* Assigns the displayName property (translation) eveywhere it's needed
|
||||
* @param {object} obj The command object to assign the properties on (mutates)
|
||||
* @param {object|undefined} translations The translations to use. Must be in the same position, has to have an "s" at the end of the name and has to be an object with locale:string k,v
|
||||
* @param {string|undefined} locale The locale to use
|
||||
*
|
||||
* @returns {object} the object that was passed in the first argument
|
||||
*
|
||||
* @example
|
||||
* cmdDisplays({
|
||||
* name: "meow",
|
||||
* description: "mrrrp",
|
||||
* }, {
|
||||
* names: {
|
||||
* ru: "мяу"
|
||||
* },
|
||||
* description: {
|
||||
* ru: "муррр"
|
||||
* }
|
||||
* }, "ru")
|
||||
*/
|
||||
export function cmdDisplays(obj, translations, locale) {
|
||||
if (!obj?.name || !obj?.description) throw new Error(`No name(${obj?.name}) or description(${obj?.description}) in the passed command (command name: ${obj?.name})`);
|
||||
|
||||
obj.displayName ??= translations?.names?.[locale] ?? obj.name;
|
||||
obj.displayDescription ??= translations?.names?.[locale] ?? obj.description;
|
||||
if (obj.options) {
|
||||
if (!Array.isArray(obj.options)) throw new Error(`Options is not an array (received: ${typeof obj.options})`);
|
||||
for (var optionIndex = 0; optionIndex < obj.options.length; optionIndex++) {
|
||||
const option = obj.options[optionIndex];
|
||||
// TODO: Handle subcommands (type 1 or 2 probably i forgor)
|
||||
if (!option?.name || !option?.description) throw new Error(`No name(${option?.name}) or description(${option?.description} in the option with index ${optionIndex}`);
|
||||
option.displayName ??= translations?.options?.[optionIndex]?.names?.[locale] ?? option.name;
|
||||
option.displayDescription ??= translations?.options?.[optionIndex]?.descriptions?.[locale] ?? option.description;
|
||||
if (option?.choices) {
|
||||
if (!Array.isArray(option?.choices)) throw new Error(`Choices is not an array (received: ${typeof option.choices})`);
|
||||
for (var choiceIndex = 0; choiceIndex < option.choices.length; choiceIndex++) {
|
||||
const choice = option.choices[choiceIndex];
|
||||
if (!choice?.name) throw new Error(`No name of choice with index ${choiceIndex} in option with index ${optionIndex}`);
|
||||
choice.displayName ??= translations?.options?.[optionIndex]?.choices?.[choiceIndex]?.names?.[locale] ?? choice.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
export function generateRandomString(chars, length = 27) {
|
||||
if (typeof chars !== "string") throw new Error("Passed chars isn't a string");
|
||||
if (chars?.length <= 0) throw new Error("Invalid chars length");
|
||||
|
||||
let result = "";
|
||||
|
||||
for (let i = 0; i < length; i++) result += chars[Math.floor(Math.random() * chars.length)];
|
||||
|
||||
return result;
|
||||
}
|
||||
export function areArraysEqual(arr1, arr2) {
|
||||
if (arr1.length !== arr2.length) return false;
|
||||
for (let i = 0; i < arr1.length; i++) {
|
||||
const item1 = arr1[i];
|
||||
const item2 = arr2[i];
|
||||
|
||||
if (Array.isArray(item1) && Array.isArray(item2)) {
|
||||
if (!areArraysEqual(item1, item2)) return false;
|
||||
} else if (item1 !== null && item2 !== null && typeof item1 === "object" && typeof item2 === "object") {
|
||||
if (!areArraysEqual(Object.values(item1), Object.values(item2))) return false;
|
||||
} else if (item1 !== item2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
export function cloneWithout(value, without, replace) {
|
||||
if (typeof value !== "object") return value;
|
||||
if (without.some(($) => (Array.isArray($) ? (Array.isArray(value) ? areArraysEqual($, value) : false) : $ === value))) return replace;
|
||||
|
||||
const newObj = Array.isArray(value) ? [] : {};
|
||||
for (const key in value) {
|
||||
if (Array.isArray(value[key])) {
|
||||
newObj[key] = cloneWithout(value[key], without, replace);
|
||||
} else if (without.includes(value[key])) {
|
||||
newObj[key] = replace;
|
||||
} else {
|
||||
newObj[key] = cloneWithout(value[key], without, replace);
|
||||
}
|
||||
}
|
||||
return newObj;
|
||||
}
|
||||
|
||||
/* Calls and awaits a promise function, and returns a [result, error] array
|
||||
* @param {function} promise A function that returns a promise
|
||||
* @example
|
||||
* async function log(...messages) {
|
||||
* if (messages[0] === "error")) throw new Error() // reject(new Error)
|
||||
*
|
||||
* console.log("[log]", ...messages)
|
||||
* return messages // resolve(messages)
|
||||
* }
|
||||
* await awaitPromise(log, "meow") // [ ["meow"], null ]
|
||||
*
|
||||
* await awaitPromise(log, "error") // [ null, Error ]
|
||||
*/
|
||||
export async function awaitPromise(promiseFn, ...args) {
|
||||
let output = [null, null];
|
||||
try {
|
||||
output[0] = await promiseFn(...args);
|
||||
} catch (error) {
|
||||
output[1] = error;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
export function processRows(rows) {
|
||||
if (!Array.isArray(rows) || !rows.every((row) => Array.isArray(row) && typeof row[0] === "string")) return JSON.stringify(rows);
|
||||
|
||||
return rows
|
||||
.sort(([a], [b]) => a.length - b.length || a.localeCompare(b))
|
||||
.map((row) => (row[0] === "" ? row[1] : row.join("∶ ")))
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
/* Returns an object with the properties of a Promise but with the proper key names (hermes polyfill specific)
|
||||
* Basically UNDOes https://github.com/then/promise/blob/master/src/core.js#L16
|
||||
* @param {Promise} promise A promise object with improper key names
|
||||
* @param {boolean=false} mutate Whether to add the proper keys on the passed object itself instead of creating a new one
|
||||
* @param {boolean=false} removeOldKeys Whether to remove the old keys from the promise
|
||||
*
|
||||
* @returns {(Promise|object)}
|
||||
*/
|
||||
export function fixPromiseProps(improperPromise, mutate = false, removeOldKeys = false) {
|
||||
const originalKeys = Object.getOwnPropertyNames(improperPromise);
|
||||
if (originalKeys.length !== 4 || originalKeys.every((name, i) => Promise_UNMINIFIED_PROPERTY_NAMES[i] === name)) throw new Error("The passed promise is already proper or isn't a promise");
|
||||
|
||||
let properPromise = {};
|
||||
if (mutate) properPromise = improperPromise;
|
||||
|
||||
Promise_UNMINIFIED_PROPERTY_NAMES.forEach((name, i) => {
|
||||
properPromise[name] = improperPromise[originalKeys[i]];
|
||||
if (mutate && removeOldKeys) delete properPromise[originalKeys[i]];
|
||||
});
|
||||
Object.setPrototypeOf(properPromise, improperPromise.__proto__);
|
||||
return properPromise;
|
||||
}
|
||||
/*
|
||||
* Makes a pretty typeof-like string from a value
|
||||
* @param {any} value
|
||||
* @returns {string}
|
||||
*
|
||||
* @example
|
||||
* prettyTypeof(69_999)
|
||||
*/
|
||||
export function prettyTypeof(value) {
|
||||
const name = [value?.constructor?.name];
|
||||
name[0] ??= "Undefined";
|
||||
if (name[0] === "Promise" && Object.getOwnPropertyNames(value).length === 4) {
|
||||
const state = value["_state"] ?? value[Object.getOwnPropertyNames(value)[1]];
|
||||
const stateName = PROMISE_STATE_NAMES[state];
|
||||
if (stateName) name[1] = `(${stateName})`;
|
||||
} else if (name[0] !== "Undefined" && value?.prototype?.constructor === value && typeof value === "function") {
|
||||
name[0] = "Class";
|
||||
name[1] = `(${value.name})`;
|
||||
} else if (value === null) {
|
||||
name[1] = `(null)`;
|
||||
} else if (["symbol", "function"].includes(typeof value) && value?.name) {
|
||||
name[1] = `(${value.name})`;
|
||||
} else if (typeof value === "boolean") {
|
||||
name[1] = `(${value})`;
|
||||
} else if (typeof value === "string") {
|
||||
name[1] = `(len: ${value.length})`;
|
||||
} else if (typeof value === "number" && value !== 0) {
|
||||
const expo = value.toExponential();
|
||||
if (!expo.endsWith("e+1") && !expo.endsWith("e+0")) name[1] = `(${expo})`;
|
||||
} else if (Array.isArray(value)) {
|
||||
if (value.length !== 0) name[1] = `(len: ${value.length})`;
|
||||
}
|
||||
|
||||
return name.join(" ");
|
||||
}
|
||||
/* Makes sure that the properties from "defaults" exist on "object" (objects recursively)
|
||||
* @param {object} object Any object to apply the changes to (mutates)
|
||||
* @param {object} defaults Defaults object to apply the changes from
|
||||
*
|
||||
* @returns {object} the object that was passed in the first argument
|
||||
*
|
||||
* @example
|
||||
* const object = {};
|
||||
* makeDefaults(object, {
|
||||
* example: 6,
|
||||
* exampleTwo: {
|
||||
* example: 1
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
export function makeDefaults(object, defaults) {
|
||||
if (object === undefined) throw new Error("No object passed to make defaults for");
|
||||
if (defaults === undefined) throw new Error("No defaults object passed to make defaults off of");
|
||||
|
||||
for (const key in defaults) {
|
||||
if (typeof defaults[key] === "object" && !Array.isArray(defaults[key])) {
|
||||
if (typeof object[key] !== "object") object[key] = {};
|
||||
makeDefaults(object[key], defaults[key]);
|
||||
} else {
|
||||
object[key] ??= defaults[key];
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
export const EMOJIS = {
|
||||
getLoading() {
|
||||
return Math.random() < 0.01 ? this.aol : this.loadingDiscordSpinner;
|
||||
},
|
||||
getFailure() {
|
||||
return Math.random() < 0.01 ? this.fuckyoy : this.linuth;
|
||||
},
|
||||
getSuccess() {
|
||||
return "";
|
||||
},
|
||||
loadingDiscordSpinner: "a:loading:1105495814073229393",
|
||||
aol: "a:aol:1108834296359301161",
|
||||
linuth: ":linuth:1110531631409811547",
|
||||
fuckyoy: ":fuckyoy:1108360628302782564",
|
||||
};
|
||||
|
||||
export const AVATARS = {
|
||||
command: "https://cdn.discordapp.com/attachments/1099116247364407337/1112129955053187203/command.png",
|
||||
};
|
||||
/**
|
||||
* Generates a random number within a specified range
|
||||
* @param {number} min The minimum value of the range (inclusive)
|
||||
* @param {number} max The maximum value of the range (inclusive)
|
||||
* @param {number} [precision=0] The number of decimal places to round the result to
|
||||
*
|
||||
* @returns {number} A random number within the specified range
|
||||
* @throws {Error} If the arguments are invalid or precision is greater than 13
|
||||
*/
|
||||
export function rng(min, max, precision = 0) {
|
||||
if (typeof min !== "number" || isNaN(min)) {
|
||||
throw new Error("Invalid first argument, minimum: expected a number");
|
||||
}
|
||||
if (typeof max !== "number" || isNaN(max)) {
|
||||
throw new Error("Invalid second argument, maximum: expected a number");
|
||||
}
|
||||
if (typeof precision !== "number" || precision < 0) {
|
||||
throw new Error("Invalid third argument, precision: expected a positive number");
|
||||
}
|
||||
if (precision > 13) {
|
||||
throw new Error("Invalid third argument, precision: expected a number < 13");
|
||||
}
|
||||
if (precision !== 0 && precision % 1 !== 0) {
|
||||
throw new Error("Invalid third argument, precision: expected an integer");
|
||||
}
|
||||
const maxPrecision = Math.max((max.toString().split(".")[1] || "").length, (min.toString().split(".")[1] || "").length);
|
||||
const computedPrecision = typeof precision === "number" ? precision : maxPrecision;
|
||||
return parseFloat((Math.random() * (max - min) + min).toFixed(computedPrecision));
|
||||
}
|
||||
53
common/mSendMessage.js
Normal file
53
common/mSendMessage.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
export function mSendMessage(vendetta) {
|
||||
const {
|
||||
metro: {
|
||||
findByProps,
|
||||
findByStoreName,
|
||||
common: {
|
||||
lodash: { merge },
|
||||
},
|
||||
},
|
||||
} = vendetta;
|
||||
const Send = findByProps("_sendMessage");
|
||||
const { createBotMessage } = findByProps("createBotMessage");
|
||||
const Avatars = findByProps("BOT_AVATARS");
|
||||
const { getChannelId: getFocusedChannelId } = findByStoreName("SelectedChannelStore");
|
||||
return function (message, mod) {
|
||||
message.channelId ??= getFocusedChannelId();
|
||||
if ([null, undefined].includes(message.channelId)) throw new Error("No channel id to receive the message into (channelId)");
|
||||
let msg = message;
|
||||
if (message.really) {
|
||||
if (typeof mod === "object") msg = merge(msg, mod);
|
||||
const args = [msg, {}];
|
||||
args[0].tts ??= false;
|
||||
for (const key of ["allowedMentions", "messageReference"]) {
|
||||
if (key in args[0]) {
|
||||
args[1][key] = args[0][key];
|
||||
delete args[0][key];
|
||||
}
|
||||
}
|
||||
const overwriteKey = "overwriteSendMessageArg2"
|
||||
if (overwriteKey in args[0]) {
|
||||
// so that you can use the keys i may have missed in the for loop above
|
||||
args[1] = args[0][overwriteKey];
|
||||
delete args[0][overwriteKey];
|
||||
}
|
||||
return Send._sendMessage(message.channelId, ...args);
|
||||
}
|
||||
if (mod !== true) msg = createBotMessage(msg);
|
||||
if (typeof mod === "object") {
|
||||
msg = merge(msg, mod);
|
||||
if (typeof mod.author === "object")
|
||||
(function processAvatarURL() {
|
||||
const author = mod.author;
|
||||
if (typeof author.avatarURL === "string") {
|
||||
Avatars.BOT_AVATARS[author.avatar ?? author.avatarURL] = author.avatarURL;
|
||||
author.avatar ??= author.avatarURL
|
||||
delete author.avatarURL;
|
||||
}
|
||||
})();
|
||||
}
|
||||
Send.receiveMessage(msg.channel_id, msg);
|
||||
return msg;
|
||||
};
|
||||
}
|
||||
29
common/numberBase64.js
Normal file
29
common/numberBase64.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
const characters =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
export const characters2 = characters.replace("+/", "_-");
|
||||
|
||||
export function encode(data, discord) {
|
||||
if (typeof data !== "number")
|
||||
throw new Error(`Passed data isn't a number (received: ${typeof data})`);
|
||||
|
||||
let result = "";
|
||||
while (data > 0) {
|
||||
result = (discord ? characters2 : characters).charAt(data % 64) + result;
|
||||
data = Math.floor(data / 64);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function decode(data, discord) {
|
||||
if (typeof data !== "string")
|
||||
throw new Error(`Passed data isn't a string (received: ${typeof data})`);
|
||||
|
||||
let result = 0;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
result *= 64;
|
||||
result += (discord ? characters2 : characters).indexOf(data[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue