diff --git a/src/webpack/api.tsx b/src/webpack/api.tsx index f12e564a4..5251f0523 100644 --- a/src/webpack/api.tsx +++ b/src/webpack/api.tsx @@ -684,8 +684,9 @@ export type CacheFindResult = { * @param filter A function that takes an export or module exports and returns a boolean */ export const _cacheFind = traceFunction("cacheFind", function _cacheFind(filter: FilterFn): CacheFindResult { - if (typeof filter !== "function") + if (typeof filter !== "function") { throw new Error("Invalid filter. Expected a function got " + typeof filter); + } for (const key in cache) { const mod = cache[key]; @@ -742,8 +743,9 @@ export function cacheFind(filter: FilterFn) { * @returns An array of all the found export or module exports */ export function cacheFindAll(filter: FilterFn) { - if (typeof filter !== "function") + if (typeof filter !== "function") { throw new Error("Invalid filter. Expected a function got " + typeof filter); + } const ret: ModuleExports[] = []; for (const key in cache) { @@ -784,6 +786,69 @@ export function cacheFindAll(filter: FilterFn) { } /** + * Find the id of the first already loaded module factory that includes all the given code. + */ +export const cacheFindModuleId = traceFunction("cacheFindModuleId", function cacheFindModuleId(...code: CodeFilter) { + const parsedCode = code.map(canonicalizeMatch); + + for (const id in wreq.m) { + if (stringMatches(String(wreq.m[id]), parsedCode)) { + return id; + } + } +}); + +/** + * Search modules by keyword. This searches the factory methods, + * meaning you can search all sorts of things, methodName, strings somewhere in the code, etc. + * + * @param code One or more strings or regexes + * @returns Mapping of found modules + */ +export function search(...code: CodeFilter) { + code = code.map(canonicalizeMatch); + + const results: WebpackRequire["m"] = {}; + const factories = wreq.m; + + for (const id in factories) { + const factory = factories[id]; + + if (stringMatches(String(factory), code)) { + results[id] = factory; + } + } + + return results; +} + +/** + * Extract a specific module by id into its own Source File. This has no effect on + * the code, it is only useful to be able to look at a specific module without having + * to view a massive file. extract then returns the extracted module so you can jump to it. + * As mentioned above, note that this extracted module is not actually used, + * so putting breakpoints or similar will have no effect. + * + * @param id The id of the module to extract + */ +export function extract(id: PropertyKey) { + const factory = wreq.m[id]; + if (!factory) return null; + + const code = ` +// [EXTRACTED] WebpackModule${String(id)} +// WARNING: This module was extracted to be more easily readable. +// This module is NOT ACTUALLY USED! This means putting breakpoints will have NO EFFECT!! + +0,${String(factory)} +//# sourceURL=ExtractedWebpackModule${String(id)} +`; + const extracted: ModuleFactory = (0, eval)(code); + return extracted; +} + +/** + * @deprecated Use separate finds instead * Same as {@link cacheFind} but in bulk. * * @param filterFns Array of filters @@ -867,40 +932,11 @@ export const cacheFindBulk = traceFunction("cacheFindBulk", function cacheFindBu } } - if (found !== length) { - const err = new Error(`Got ${length} filters, but only found ${found} modules!`); - - if (!IS_DEV || devToolsOpen) { - logger.warn(err); - return null; - } else { - throw err; // Strict behaviour in DevBuilds to fail early and make sure the issue is found - } - } - return results; }); /** - * Find the id of the first already loaded module factory that includes all the given code. - */ -export const cacheFindModuleId = traceFunction("cacheFindModuleId", function cacheFindModuleId(...code: CodeFilter) { - const parsedCode = code.map(canonicalizeMatch); - - for (const id in wreq.m) { - if (stringMatches(String(wreq.m[id]), parsedCode)) return id; - } - - const err = new Error("Didn't find module with code(s):\n" + code.join("\n")); - - if (!IS_DEV || devToolsOpen) { - logger.warn(err); - } else { - throw err; // Strict behaviour in DevBuilds to fail early and make sure the issue is found - } -}); - -/** + * @deprecated use {@link findModuleFactory} instead * Find the first already loaded module factory that includes all the given code. */ export const cacheFindModuleFactory = traceFunction("cacheFindModuleFactory", function cacheFindModuleFactory(...code: CodeFilter) { @@ -910,55 +946,6 @@ export const cacheFindModuleFactory = traceFunction("cacheFindModuleFactory", fu return wreq.m[id]; }); -/** - * Search modules by keyword. This searches the factory methods, - * meaning you can search all sorts of things, methodName, strings somewhere in the code, etc. - * - * @param code One or more strings or regexes - * @returns Mapping of found modules - */ -export function search(...code: CodeFilter) { - code = code.map(canonicalizeMatch); - - const results: WebpackRequire["m"] = {}; - const factories = wreq.m; - - for (const id in factories) { - const factory = factories[id]; - - if (stringMatches(String(factory), code)) { - results[id] = factory; - } - } - - return results; -} - -/** - * Extract a specific module by id into its own Source File. This has no effect on - * the code, it is only useful to be able to look at a specific module without having - * to view a massive file. extract then returns the extracted module so you can jump to it. - * As mentioned above, note that this extracted module is not actually used, - * so putting breakpoints or similar will have no effect. - * - * @param id The id of the module to extract - */ -export function extract(id: PropertyKey) { - const factory = wreq.m[id]; - if (!factory) return null; - - const code = ` -// [EXTRACTED] WebpackModule${String(id)} -// WARNING: This module was extracted to be more easily readable. -// This module is NOT ACTUALLY USED! This means putting breakpoints will have NO EFFECT!! - -0,${String(factory)} -//# sourceURL=ExtractedWebpackModule${String(id)} -`; - const extracted: ModuleFactory = (0, eval)(code); - return extracted; -} - function deprecatedRedirect any>(oldMethod: string, newMethod: string, redirect: T): T { return ((...args: Parameters) => { logger.warn(`Method ${oldMethod} is deprecated. Use ${newMethod} instead. For more information read https://github.com/Vendicated/Vencord/pull/2409#issue-2277161516`);