2026-08-01 20:27:40 -04:00
|
|
|
import { findByProps, findByName, findByTypeName, findByStoreName, findByPropsAll, findByNameAll, find } from "@vendetta/metro";
|
2026-08-01 20:10:56 -04:00
|
|
|
import { React, ReactNative, FluxDispatcher } from "@vendetta/metro/common";
|
2026-08-01 20:27:40 -04:00
|
|
|
import { instead, before, after } from "@vendetta/patcher";
|
|
|
|
|
import { getAssetIDByName } from "@vendetta/ui/assets";
|
2026-08-01 20:10:56 -04:00
|
|
|
import { rawFind, rawFindByTypeName, rawFindByProps, rawFindByName, rawFindByStoreName } from "@shared/lib/rawFind";
|
|
|
|
|
|
|
|
|
|
declare const window: any;
|
|
|
|
|
|
|
|
|
|
function safeStringify(value: any): string {
|
|
|
|
|
if (value === undefined) return "undefined";
|
|
|
|
|
if (value === null) return "null";
|
|
|
|
|
if (typeof value === "function") return `[Function: ${value.name || "anonymous"}]`;
|
|
|
|
|
if (typeof value !== "object") return String(value);
|
|
|
|
|
|
|
|
|
|
const seen = new WeakSet();
|
|
|
|
|
try {
|
|
|
|
|
return JSON.stringify(
|
|
|
|
|
value,
|
|
|
|
|
(_key, val) => {
|
|
|
|
|
if (typeof val === "function") return `[Function: ${val.name || "anonymous"}]`;
|
|
|
|
|
if (typeof val === "symbol") return val.toString();
|
|
|
|
|
if (typeof val === "object" && val !== null) {
|
|
|
|
|
if (seen.has(val)) return "[Circular]";
|
|
|
|
|
seen.add(val);
|
|
|
|
|
}
|
|
|
|
|
return val;
|
|
|
|
|
},
|
|
|
|
|
2
|
|
|
|
|
);
|
|
|
|
|
} catch {
|
|
|
|
|
// Most live Discord/React objects (fibers, class instances, refs) have circular structure
|
|
|
|
|
// or getters that throw - falling back to a flat key listing still tells you something
|
|
|
|
|
// useful instead of just "[object Object]".
|
|
|
|
|
try {
|
|
|
|
|
return `[unserializable object, keys: ${Object.keys(value).join(", ")}]`;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return `[unserializable, and Object.keys threw: ${e}]`;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Runs arbitrary code typed into the Eval box, with this repo's own lookup helpers already in
|
|
|
|
|
* scope - built so an on-device assumption behind a fix (does this property exist, does this call
|
|
|
|
|
* behave the way decompiled source suggested) can be checked in seconds instead of a full
|
|
|
|
|
* build/push/update/test cycle. The code runs as the body of an async function, so a bare
|
|
|
|
|
* expression, a `return ...`, or `await`-ing something all work. Never runs anything on its own -
|
|
|
|
|
* only what's typed in and manually run here.
|
|
|
|
|
*/
|
|
|
|
|
export async function runEval(code: string): Promise<string> {
|
|
|
|
|
try {
|
|
|
|
|
const fn = new Function(
|
|
|
|
|
"findByProps",
|
|
|
|
|
"findByName",
|
2026-08-01 20:27:40 -04:00
|
|
|
"findByTypeName",
|
|
|
|
|
"findByStoreName",
|
|
|
|
|
"findByPropsAll",
|
|
|
|
|
"findByNameAll",
|
2026-08-01 20:10:56 -04:00
|
|
|
"find",
|
|
|
|
|
"rawFind",
|
|
|
|
|
"rawFindByTypeName",
|
|
|
|
|
"rawFindByProps",
|
|
|
|
|
"rawFindByName",
|
|
|
|
|
"rawFindByStoreName",
|
2026-08-01 20:27:40 -04:00
|
|
|
"instead",
|
|
|
|
|
"before",
|
|
|
|
|
"after",
|
|
|
|
|
"getAssetIDByName",
|
2026-08-01 20:10:56 -04:00
|
|
|
"React",
|
|
|
|
|
"ReactNative",
|
|
|
|
|
"FluxDispatcher",
|
|
|
|
|
"window",
|
|
|
|
|
`return (async () => {\n${code}\n})();`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const result = await fn(
|
|
|
|
|
findByProps,
|
|
|
|
|
findByName,
|
2026-08-01 20:27:40 -04:00
|
|
|
findByTypeName,
|
|
|
|
|
findByStoreName,
|
|
|
|
|
findByPropsAll,
|
|
|
|
|
findByNameAll,
|
2026-08-01 20:10:56 -04:00
|
|
|
find,
|
|
|
|
|
rawFind,
|
|
|
|
|
rawFindByTypeName,
|
|
|
|
|
rawFindByProps,
|
|
|
|
|
rawFindByName,
|
|
|
|
|
rawFindByStoreName,
|
2026-08-01 20:27:40 -04:00
|
|
|
instead,
|
|
|
|
|
before,
|
|
|
|
|
after,
|
|
|
|
|
getAssetIDByName,
|
2026-08-01 20:10:56 -04:00
|
|
|
React,
|
|
|
|
|
ReactNative,
|
|
|
|
|
FluxDispatcher,
|
|
|
|
|
window
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return safeStringify(result);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return `Error: ${e instanceof Error ? `${e.message}\n${e.stack ?? ""}` : String(e)}`;
|
|
|
|
|
}
|
|
|
|
|
}
|