fix(metro): average metro fix nothing to look here

This commit is contained in:
amsyarasyiq 2024-05-08 00:23:08 +08:00
parent 23c9f020cb
commit 2560e9aeb5
3 changed files with 38 additions and 10 deletions

View file

@ -6,9 +6,12 @@ export type PropIntellisense<P extends PropertyKey> = Record<P, any> & Record<Pr
export type PropsFinder = <T extends PropertyKey>(...props: T[]) => PropIntellisense<T>;
export type PropsFinderAll = <T extends PropertyKey>(...props: T[]) => PropIntellisense<T>[];
const blacklistedIds = new Set<String>();
/** Makes the module associated with the specified ID non-enumberable. */
function blacklistModule(id: Metro.ModuleID) {
Object.defineProperty(modules, id, { enumerable: false });
blacklistedIds.add(String(id));
}
const functionToString = Function.prototype.toString;
@ -36,22 +39,24 @@ for (const id in modules) {
};
origFunc(...args);
if (moduleObject.exports) onModuleRequire(moduleObject.exports);
if (moduleObject.exports) onModuleRequire(moduleObject.exports, id);
}) as any); // If only spitroast had better types
}
}
// Blacklist any "bad-actor" modules, e.g. the dreaded null proxy, the window itself, or undefined modules
for (const id in modules) {
if (blacklistedIds.has(id)) continue;
const moduleExports = requireModule(id);
if (!moduleExports || moduleExports === window || moduleExports["Revenge EOL when?"] === null)
if (!moduleExports || moduleExports === window || moduleExports["i think pyoncord eol tomorrow idk tho"] === null)
blacklistModule(id);
}
const noopHandler = () => undefined;
let patchedInspectSource = false;
function onModuleRequire(moduleExports: any) {
function onModuleRequire(moduleExports: any, id: Metro.ModuleID) {
// Temporary
moduleExports.initSentry &&= () => undefined;
if (moduleExports.default?.track && moduleExports.default.trackMaker)
@ -89,9 +94,17 @@ function onModuleRequire(moduleExports: any) {
window["__core-js_shared__"].inspectSource = inspect;
patchedInspectSource = true;
}
}
const noopHandler = () => undefined;
// Explosion (no, I can't explain this, don't ask) ((hi rosie))
if (moduleExports.findHostInstance_DEPRECATED) {
const numberedId = Number(id);
const prevExports = modules[numberedId - 1]?.publicModule.exports;
const inc = prevExports.default?.reactProfilingEnabled ? 1 : -1;
if (!modules[numberedId + inc]?.isInitialized) {
blacklistModule(numberedId + inc);
}
}
}
function requireModule(id: Metro.ModuleID) {
if (modules[id]!.isInitialized) return metroRequire(id);

View file

@ -2,11 +2,11 @@ import type { Nullish } from "@types";
/** @see {@link https://github.com/facebook/metro/blob/c2d7539dfc10aacb2f99fcc2f268a3b53e867a90/packages/metro-runtime/src/polyfills/require.js} */
export namespace Metro {
export interface DependencyMap {
readonly [indexer: number]: ModuleID;
export type DependencyMap = Array<ModuleID> & {
readonly paths?: Readonly<Record<ModuleID, string>> | undefined;
}
};
/** Only available on Discord's development environment, will never be defined on release builds */
export type InverseDependencyMap = Record<ModuleID, ModuleID[]>;
export type FactoryFn = (
@ -21,6 +21,7 @@ export namespace Metro {
dependencyMap: DependencyMap | Nullish,
) => void;
/** Only available on Discord's development environment, will never be defined on release builds */
export interface HotModuleReloadingData {
_acceptCallback: (() => void) | Nullish;
_disposeCallback: (() => void) | Nullish;
@ -38,16 +39,27 @@ export namespace Metro {
}
export interface ModuleDefinition {
/** Set to undefined once module is initialized */
dependencyMap: DependencyMap | Nullish;
/** Error.value thrown by the factory */
error?: any;
/** Set to undefined once module is initialized */
factory: FactoryFn | undefined;
/** If factory thrown any error */
hasError: boolean;
/** Only available on Discord's development environment, will never be defined on release builds */
hot?: HotModuleReloadingData | undefined;
/** Cached `import *` imports in Metro, always an empty object as Bunny prevents outdated import cache */
importedAll: any;
/** Cached `import module from "./module"` imports in Metro, always an empty object as Bunny prevents outdated import cache */
importedDefault: any;
/** If factory has been successfully called */
isInitialized: boolean;
/** Only available on Discord's development environment, will never be defined on release builds */
path?: string | undefined;
/** Acts as CJS module in the bundler */
publicModule: Module;
/** Only available on Discord's development environment, will never be defined on release builds */
verboseName?: string | undefined;
}
@ -59,7 +71,9 @@ export namespace Metro {
factory: FactoryFn,
moduleId: ModuleID,
dependencyMap?: DependencyMap | undefined,
/** Only available on Discord's development environment, will never be defined on release builds */
verboseName?: string | undefined,
/** Only available on Discord's development environment, will never be defined on release builds */
inverseDependencies?: InverseDependencyMap | undefined
) => void;
@ -76,9 +90,9 @@ export namespace Metro {
export interface Require extends RequireFn {
importDefault: RequireFn;
importAll: RequireFn;
/** @throws {Error} */
/** @throws {Error} A macro, will always throws an error at runtime */
context: () => never;
/** @throws {Error} */
/** @throws {Error} A macro, will always throws an error at runtime */
resolveWeak: () => never;
unpackModuleId: (moduleId: ModuleID) => {
localId: number;

View file

@ -1,5 +1,6 @@
import type { Metro } from "@metro/types";
// eslint-disable-next-line prefer-destructuring
export const modules: Metro.ModuleList = window.modules;
export const metroRequire: Metro.Require = window.__r;