Clean up WebpackRequire typings

This commit is contained in:
Nuckyz 2024-05-23 03:36:53 -03:00
parent deb0f7b9c6
commit 5ca4e58fad
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
4 changed files with 35 additions and 34 deletions

View file

@ -41,7 +41,7 @@ const browser = await pup.launch({
const page = await browser.newPage();
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36");
function maybeGetError(handle: JSHandle) {
async function maybeGetError(handle: JSHandle) {
return (handle as JSHandle<Error>)?.getProperty("message")
.then(m => m.jsonValue());
}
@ -383,7 +383,7 @@ async function runtime(token: string) {
await Promise.all(
Array.from(validChunkGroups)
.map(([chunkIds]) =>
Promise.all(chunkIds.map(id => wreq.e(id as any).catch(() => { })))
Promise.all(chunkIds.map(id => wreq.e(id).catch(() => { })))
)
);
@ -395,7 +395,7 @@ async function runtime(token: string) {
continue;
}
if (wreq.m[entryPoint]) wreq(entryPoint as any);
if (wreq.m[entryPoint]) wreq(entryPoint);
} catch (err) {
console.error(err);
}
@ -460,7 +460,7 @@ async function runtime(token: string) {
// Require deferred entry points
for (const deferredRequire of deferredRequires) {
wreq(deferredRequire as any);
wreq(deferredRequire);
}
// All chunks Discord has mapped to asset files, even if they are not used anymore
@ -488,8 +488,8 @@ async function runtime(token: string) {
// Loads and requires a chunk
if (!isWasm) {
await wreq.e(id as any);
if (wreq.m[id]) wreq(id as any);
await wreq.e(id);
if (wreq.m[id]) wreq(id);
}
}));

View file

@ -24,6 +24,7 @@ const modulesProxyhandler: ProxyHandler<WebpackRequire["m"]> = {
const mod = Reflect.get(target, p);
// If the property is not a module id, return the value of it without trying to patch
// @ts-ignore
if (mod == null || mod.$$vencordOriginal != null || Number.isNaN(Number(p))) return mod;
const patchedMod = patchFactory(p, mod);
@ -90,12 +91,14 @@ Object.defineProperty(Function.prototype, "O", {
// Returns whether a chunk has been loaded
Object.defineProperty(onChunksLoaded, "j", {
configurable: true,
set(v) {
// @ts-ignore
delete onChunksLoaded.j;
onChunksLoaded.j = v;
originalOnChunksLoaded.j = v;
},
configurable: true
}
});
}
@ -113,7 +116,7 @@ Object.defineProperty(Function.prototype, "O", {
Object.defineProperty(Function.prototype, "m", {
configurable: true,
set(originalModules: any) {
set(originalModules: WebpackRequire["m"]) {
// When using react devtools or other extensions, we may also catch their webpack here.
// This ensures we actually got the right one
const { stack } = new Error();
@ -140,7 +143,7 @@ Object.defineProperty(Function.prototype, "m", {
let webpackNotInitializedLogged = false;
function patchFactory(id: string | number, mod: ModuleFactory) {
function patchFactory(id: PropertyKey, mod: ModuleFactory) {
for (const factoryListener of factoryListeners) {
try {
factoryListener(mod);
@ -192,7 +195,7 @@ function patchFactory(id: string | number, mod: ModuleFactory) {
const newCode = executePatch(replacement.match, replacement.replace as string);
if (newCode === code) {
if (!patch.noWarn) {
logger.warn(`Patch by ${patch.plugin} had no effect (Module id is ${id}): ${replacement.match}`);
logger.warn(`Patch by ${patch.plugin} had no effect (Module id is ${String(id)}): ${replacement.match}`);
if (IS_DEV) {
logger.debug("Function Source:\n", code);
}
@ -210,9 +213,9 @@ function patchFactory(id: string | number, mod: ModuleFactory) {
}
code = newCode;
mod = (0, eval)(`// Webpack Module ${id} - Patched by ${[...patchedBy].join(", ")}\n${newCode}\n//# sourceURL=WebpackModule${id}`);
mod = (0, eval)(`// Webpack Module ${String(id)} - Patched by ${[...patchedBy].join(", ")}\n${newCode}\n//# sourceURL=WebpackModule${String(id)}`);
} catch (err) {
logger.error(`Patch by ${patch.plugin} errored (Module id is ${id}): ${replacement.match}\n`, err);
logger.error(`Patch by ${patch.plugin} errored (Module id is ${String(id)}): ${replacement.match}\n`, err);
if (IS_DEV) {
const changeSize = code.length - lastCode.length;

View file

@ -36,7 +36,7 @@ export const onceReady = new Promise<void>(r => _resolveReady = r);
export let wreq: WebpackRequire;
export let cache: WebpackRequire["c"];
export type FilterFn = (mod: any) => boolean;
export type FilterFn = (module: ModuleExports) => boolean;
export const filters = {
byProps: (...props: string[]): FilterFn =>
@ -129,7 +129,7 @@ export function findAll(filter: FilterFn) {
if (typeof filter !== "function")
throw new Error("Invalid filter. Expected a function got " + typeof filter);
const ret = [] as any[];
const ret: ModuleExports[] = [];
for (const key in cache) {
const mod = cache[key];
if (!mod?.exports) continue;
@ -169,7 +169,7 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
const filters = filterFns as Array<FilterFn | undefined>;
let found = 0;
const results = Array(length);
const results: ModuleExports[] = Array(length);
outer:
for (const key in cache) {
@ -496,12 +496,12 @@ export function waitFor(filter: string | string[] | FilterFn, callback: Callback
* @returns Mapping of found modules
*/
export function search(...filters: Array<string | RegExp>) {
const results = {} as Record<number, Function>;
const results: WebpackRequire["m"] = {};
const factories = wreq.m;
outer:
for (const id in factories) {
// @ts-ignore
const factory = factories[id].original ?? factories[id];
const factory = factories[id].$$vencordOriginal ?? factories[id];
const str: string = factory.toString();
for (const filter of filters) {
if (typeof filter === "string" && !str.includes(filter)) continue outer;
@ -521,18 +521,18 @@ export function search(...filters: Array<string | RegExp>) {
* so putting breakpoints or similar will have no effect.
* @param id The id of the module to extract
*/
export function extract(id: string | number) {
const mod = wreq.m[id] as Function;
export function extract(id: PropertyKey) {
const mod = wreq.m[id];
if (!mod) return null;
const code = `
// [EXTRACTED] WebpackModule${id}
// [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,${mod.toString()}
//# sourceURL=ExtractedWebpackModule${id}
//# sourceURL=ExtractedWebpackModule${String(id)}
`;
const extracted = (0, eval)(code);
return extracted as Function;
const extracted: ModuleFactory = (0, eval)(code);
return extracted;
}

18
src/webpack/wreq.d.ts vendored
View file

@ -4,8 +4,6 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
export type AnyRecord = Record<PropertyKey, any>;
export type ModuleExports = any;
export type Module = {
@ -14,8 +12,8 @@ export type Module = {
exports: ModuleExports;
};
/** exports ({@link ModuleExports}) can be anything, however initially it is always an empty object */
export type ModuleFactory = (module: Module, exports: AnyRecord, require: WebpackRequire) => void;
/** exports can be anything, however initially it is always an empty object */
export type ModuleFactory = (module: Module, exports: ModuleExports, require: WebpackRequire) => void;
export type AsyncModuleBody = (
handleDependencies: (deps: Promise<any>[]) => Promise<any[]> & (() => void)
@ -40,7 +38,7 @@ export type ScriptLoadDone = (event: Event) => void;
export type OnChunksLoaded = ((this: WebpackRequire, result: any, chunkIds: PropertyKey[] | undefined | null, callback: () => any, priority: number) => any) & {
/** Check if a chunk has been loaded */
j: (chunkId: PropertyKey) => boolean;
j: (this: OnChunksLoaded, chunkId: PropertyKey) => boolean;
};
export type WebpackRequire = ((moduleId: PropertyKey) => Module) & {
@ -57,7 +55,7 @@ export type WebpackRequire = ((moduleId: PropertyKey) => Module) & {
* });
* @returns fromObject
*/
es: (this: WebpackRequire, fromObject: AnyRecord, toObject: AnyRecord) => AnyRecord;
es: (this: WebpackRequire, fromObject: Record<PropertyKey, any>, toObject: Record<PropertyKey, any>) => Record<PropertyKey, any>;
/**
* Creates an async module. The body function must be a async function.
* "module.exports" will be decorated with an AsyncModulePromise.
@ -91,7 +89,7 @@ export type WebpackRequire = ((moduleId: PropertyKey) => Module) & {
* Object.defineProperty(exports, key, { get: definition[key] }
* }
*/
d: (this: WebpackRequire, exports: AnyRecord, definiton: AnyRecord) => void;
d: (this: WebpackRequire, exports: Record<PropertyKey, any>, definiton: Record<PropertyKey, any>) => void;
/** The chunk handlers, which are used to ensure the files of the chunks are loaded, or load if necessary */
f: ChunkHandlers;
/**
@ -100,7 +98,7 @@ export type WebpackRequire = ((moduleId: PropertyKey) => Module) & {
*/
e: (this: WebpackRequire, chunkId: PropertyKey) => Promise<void[]>;
/** Get the filename name for the css part of a chunk */
k: (this: WebpackRequire, chunkId: PropertyKey) => `${chunkId}.css`;
k: (this: WebpackRequire, chunkId: PropertyKey) => string;
/** Get the filename for the js part of a chunk */
u: (this: WebpackRequire, chunkId: PropertyKey) => string;
/** The global object, will likely always be the window */
@ -116,7 +114,7 @@ export type WebpackRequire = ((moduleId: PropertyKey) => Module) & {
*/
l: (this: WebpackRequire, url: string, done: ScriptLoadDone, key?: string | number, chunkId?: PropertyKey) => void;
/** Defines __esModule on the exports, marking ES Modules compatibility as true */
r: (this: WebpackRequire, exports: AnyRecord) => void;
r: (this: WebpackRequire, exports: ModuleExports) => void;
/** Node.js module decorator. Decorates a module as a Node.js module */
nmd: (this: WebpackRequire, module: Module) => any;
/**
@ -135,7 +133,7 @@ export type WebpackRequire = ((moduleId: PropertyKey) => Module) & {
* Instantiate a wasm instance with source using "wasmModuleHash", and importObject "importsObj", and then assign the exports of its instance to "exports"
* @returns The exports argument, but now assigned with the exports of the wasm instance
*/
v: (this: WebpackRequire, exports: AnyRecord, wasmModuleId: any, wasmModuleHash: string, importsObj?: WebAssembly.Imports) => Promise<any>;
v: (this: WebpackRequire, exports: ModuleExports, wasmModuleId: any, wasmModuleHash: string, importsObj?: WebAssembly.Imports) => Promise<any>;
/** Bundle public path, where chunk files are stored. Used by other methods which load chunks to obtain the full asset url */
p: string;
/** Document baseURI or WebWorker location.href */