Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy

This commit is contained in:
Nuckyz 2024-05-28 04:00:41 -03:00
commit b36d3b4385
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9

View file

@ -327,98 +327,100 @@ function patchFactory(id: PropertyKey, factory: ModuleFactory) {
if (!patch.all) patches.splice(i--, 1); if (!patch.all) patches.splice(i--, 1);
} }
// The patched factory wrapper // The patched factory wrapper, define it in an object to preserve the name after minification
const patchedFactory: PatchedModuleFactory = function (...args: Parameters<ModuleFactory>) { const patchedFactory: PatchedModuleFactory = {
// Restore the original factory in all the module factories objects, PatchedFactory(...args: Parameters<ModuleFactory>) {
// because we want to make sure the original factory is restored properly, no matter what is the Webpack instance // Restore the original factory in all the module factories objects,
for (const moduleFactories of allModuleFactories) { // because we want to make sure the original factory is restored properly, no matter what is the Webpack instance
Reflect.defineProperty(moduleFactories, id, { for (const moduleFactories of allModuleFactories) {
value: patchedFactory.$$vencordOriginal, Reflect.defineProperty(moduleFactories, id, {
configurable: true, value: patchedFactory.$$vencordOriginal,
enumerable: true, configurable: true,
writable: true enumerable: true,
}); writable: true
} });
}
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
let [module, exports, require] = args; let [module, exports, require] = args;
if (wreq == null) { if (wreq == null) {
if (!wreqFallbackApplied) { if (!wreqFallbackApplied) {
wreqFallbackApplied = true; wreqFallbackApplied = true;
// Make sure the require argument is actually the WebpackRequire function // Make sure the require argument is actually the WebpackRequire function
if (typeof require === "function" && require.m != null) { if (typeof require === "function" && require.m != null) {
const { stack } = new Error(); const { stack } = new Error();
const webpackInstanceFileName = stack?.match(/\/assets\/(.+?\.js)/)?.[1]; const webpackInstanceFileName = stack?.match(/\/assets\/(.+?\.js)/)?.[1];
logger.warn( logger.warn(
"WebpackRequire was not initialized, falling back to WebpackRequire passed to the first called patched module factory (" + "WebpackRequire was not initialized, falling back to WebpackRequire passed to the first called patched module factory (" +
`id: ${String(id)}` + interpolateIfDefined`, WebpackInstance origin: ${webpackInstanceFileName}` + `id: ${String(id)}` + interpolateIfDefined`, WebpackInstance origin: ${webpackInstanceFileName}` +
")" ")"
); );
_initWebpack(require); _initWebpack(require);
} else if (IS_DEV) { } else if (IS_DEV) {
logger.error("WebpackRequire was not initialized, running modules without patches instead."); logger.error("WebpackRequire was not initialized, running modules without patches instead.");
}
}
if (IS_DEV) {
return originalFactory.apply(this, args);
} }
} }
if (IS_DEV) { let factoryReturn: unknown;
try {
// Call the patched factory
factoryReturn = factory.apply(this, args);
} catch (err) {
// Just re-throw Discord errors
if (factory === originalFactory) throw err;
logger.error("Error in patched module factory", err);
return originalFactory.apply(this, args); return originalFactory.apply(this, args);
} }
}
let factoryReturn: unknown; // Webpack sometimes sets the value of module.exports directly, so assign exports to it to make sure we properly handle it
try { exports = module?.exports;
// Call the patched factory if (exports == null) return factoryReturn;
factoryReturn = factory.apply(this, args);
} catch (err) {
// Just re-throw Discord errors
if (factory === originalFactory) throw err;
logger.error("Error in patched module factory", err); // There are (at the time of writing) 11 modules exporting the window
return originalFactory.apply(this, args); // Make these non enumerable to improve webpack search performance
} if (exports === window && typeof require === "function" && require.c != null) {
Reflect.defineProperty(require.c, id, {
value: require.c[id],
configurable: true,
writable: true,
enumerable: false
});
return factoryReturn;
}
// Webpack sometimes sets the value of module.exports directly, so assign exports to it to make sure we properly handle it for (const callback of moduleListeners) {
exports = module?.exports; try {
if (exports == null) return factoryReturn; callback(exports, id);
} catch (err) {
logger.error("Error in Webpack module listener:\n", err, callback);
}
}
for (const [filter, callback] of waitForSubscriptions) {
try {
if (filter(exports)) {
waitForSubscriptions.delete(filter);
callback(exports);
} else if (exports.default && filter(exports.default)) {
waitForSubscriptions.delete(filter);
callback(exports.default);
}
} catch (err) {
logger.error("Error while firing callback for Webpack waitFor subscription:\n", err, filter, callback);
}
}
// There are (at the time of writing) 11 modules exporting the window
// Make these non enumerable to improve webpack search performance
if (exports === window && typeof require === "function" && require.c != null) {
Reflect.defineProperty(require.c, id, {
value: require.c[id],
configurable: true,
writable: true,
enumerable: false
});
return factoryReturn; return factoryReturn;
} }
}.PatchedFactory;
for (const callback of moduleListeners) {
try {
callback(exports, id);
} catch (err) {
logger.error("Error in Webpack module listener:\n", err, callback);
}
}
for (const [filter, callback] of waitForSubscriptions) {
try {
if (filter(exports)) {
waitForSubscriptions.delete(filter);
callback(exports);
} else if (exports.default && filter(exports.default)) {
waitForSubscriptions.delete(filter);
callback(exports.default);
}
} catch (err) {
logger.error("Error while firing callback for Webpack waitFor subscription:\n", err, filter, callback);
}
}
return factoryReturn;
};
patchedFactory.toString = originalFactory.toString.bind(originalFactory); patchedFactory.toString = originalFactory.toString.bind(originalFactory);
patchedFactory.$$vencordOriginal = originalFactory; patchedFactory.$$vencordOriginal = originalFactory;