diff --git a/.eslintrc.json b/.eslintrc.json index 2ee24e8b3..ab78ac85b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,9 @@ { "root": true, "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "./tsconfig.json" + }, "ignorePatterns": ["dist", "browser"], "plugins": [ "@typescript-eslint", @@ -62,7 +65,14 @@ "no-constant-condition": ["error", { "checkLoops": false }], "no-duplicate-imports": "error", "no-extra-semi": "error", - "dot-notation": "error", + "dot-notation": "off", + "@typescript-eslint/dot-notation": [ + "error", + { + "allowPrivateClassPropertyAccess": true, + "allowProtectedClassPropertyAccess": true + } + ], "no-useless-escape": [ "error", { diff --git a/scripts/generateReport.ts b/scripts/generateReport.ts index 97dc41f59..6a424ff13 100644 --- a/scripts/generateReport.ts +++ b/scripts/generateReport.ts @@ -289,10 +289,8 @@ async function runtime(token: string) { }); // Monkey patch Logger to not log with custom css - // @ts-ignore - const originalLog = Vencord.Util.Logger.prototype._log; - // @ts-ignore - Vencord.Util.Logger.prototype._log = function (level, levelColor, args) { + const originalLog = Vencord.Util.Logger.prototype["_log"]; + Vencord.Util.Logger.prototype["_log"] = function (level, levelColor, args) { if (level === "warn" || level === "error") return console[level]("[Vencord]", this.name + ":", ...args); diff --git a/src/plugins/messageLinkEmbeds/index.tsx b/src/plugins/messageLinkEmbeds/index.tsx index 726fd79cd..6659a1285 100644 --- a/src/plugins/messageLinkEmbeds/index.tsx +++ b/src/plugins/messageLinkEmbeds/index.tsx @@ -212,10 +212,9 @@ function computeWidthAndHeight(width: number, height: number) { function withEmbeddedBy(message: Message, embeddedBy: string[]) { return new Proxy(message, { - get(_, prop) { + get(target, prop, receiver) { if (prop === "vencordEmbeddedBy") return embeddedBy; - // @ts-ignore ts so bad - return Reflect.get(...arguments); + return Reflect.get(target, prop, receiver); } }); } diff --git a/src/utils/lazy.ts b/src/utils/lazy.ts index 000b96cbf..13ec46257 100644 --- a/src/utils/lazy.ts +++ b/src/utils/lazy.ts @@ -15,7 +15,11 @@ export type ProxyLazy = T & { export const proxyLazyGet = Symbol.for("vencord.lazy.get"); export const proxyLazyCache = Symbol.for("vencord.lazy.cached"); -export function makeLazy(factory: () => T, attempts = 5, { isIndirect = false }: { isIndirect?: boolean; } = {}): () => T { +export type LazyFunction = (() => T) & { + $$vencordLazyFailed: () => boolean; +}; + +export function makeLazy(factory: () => T, attempts = 5, { isIndirect = false }: { isIndirect?: boolean; } = {}): LazyFunction { let tries = 0; let cache: T; @@ -79,7 +83,6 @@ export function proxyLazy(factory: () => T, attempts = 5, isChild Object.assign(proxyDummy, { [proxyLazyGet]() { if (!proxyDummy[proxyLazyCache]) { - // @ts-ignore if (!get.$$vencordLazyFailed()) { proxyDummy[proxyLazyCache] = get(); } @@ -110,7 +113,10 @@ export function proxyLazy(factory: () => T, attempts = 5, isChild // `const { meow } = proxyLazy(() => ({ meow: [] }));` if (!isChild && isSameTick) { return proxyLazy( - () => Reflect.get(target[proxyLazyGet](), p, target[proxyLazyGet]()), + () => { + const lazyTarget = target[proxyLazyGet](); + return Reflect.get(lazyTarget, p, lazyTarget); + }, attempts, true ); diff --git a/src/utils/lazyReact.tsx b/src/utils/lazyReact.tsx index 719ce4262..74c7832d2 100644 --- a/src/utils/lazyReact.tsx +++ b/src/utils/lazyReact.tsx @@ -27,7 +27,6 @@ export function LazyComponent(factory: () => React.Compo let lazyFailedLogged = false; const LazyComponent = (props: T) => { - // @ts-ignore if (!get.$$vencordLazyFailed()) { const ResultComponent = get(); if (ResultComponent != null) { @@ -36,7 +35,6 @@ export function LazyComponent(factory: () => React.Compo } if (InnerComponent === null && !lazyFailedLogged) { - // @ts-ignore if (get.$$vencordLazyFailed()) { lazyFailedLogged = true; } diff --git a/src/webpack/webpack.tsx b/src/webpack/webpack.tsx index 527540384..01ed6a55f 100644 --- a/src/webpack/webpack.tsx +++ b/src/webpack/webpack.tsx @@ -27,21 +27,22 @@ export const onceReady = new Promise(r => _resolveReady = r); export let wreq: WebpackRequire; export let cache: WebpackRequire["c"]; -export type FilterFn = (module: ModuleExports) => boolean; +export type FilterFn = ((module: ModuleExports) => boolean) & { + $$vencordProps?: string[]; +}; export const filters = { byProps: (...props: string[]): FilterFn => { - const filter = props.length === 1 + const filter: FilterFn = props.length === 1 ? m => m?.[props[0]] !== void 0 : m => props.every(p => m?.[p] !== void 0); - // @ts-ignore filter.$$vencordProps = ["byProps", ...props]; return filter; }, byCode: (...code: string[]): FilterFn => { - const filter = m => { + const filter: FilterFn = m => { if (typeof m !== "function") return false; const s = Function.prototype.toString.call(m); for (const c of code) { @@ -55,29 +56,36 @@ export const filters = { }, byStoreName: (name: string): FilterFn => { - const filter = m => m?.constructor?.displayName === name; + const filter: FilterFn = m => m?.constructor?.displayName === name; filter.$$vencordProps = ["byStoreName", name]; return filter; }, componentByCode: (...code: string[]): FilterFn => { - const filter = filters.byCode(...code); - const wrapper = m => { - if (filter(m)) return true; - if (!m?.$$typeof) return false; - if (m?.type && m.type.render) return filter(m.type.render); // memo + forwardRef - if (m?.type) return filter(m.type); // memos - if (m?.render) return filter(m.render); // forwardRefs + const byCodeFilter = filters.byCode(...code); + const filter: FilterFn = m => { + let inner = m; + + while (inner != null) { + if (byCodeFilter(inner)) return true; + else if (!inner.$$typeof) return false; + else if (inner.type) inner = inner.type; // memos + else if (inner.render) inner = inner.render; // forwardRefs + else return false; + } + return false; }; - wrapper.$$vencordProps = ["componentByCode", ...code]; - return wrapper; + filter.$$vencordProps = ["componentByCode", ...code]; + return filter; } }; -export type ModCallbackFn = (module: ModuleExports) => void; +export type ModCallbackFn = ((module: ModuleExports) => void) & { + $$vencordCallbackCalled?: () => boolean; +}; export type ModCallbackFnWithId = (module: ModuleExports, id: PropertyKey) => void; export const waitForSubscriptions = new Map(); @@ -99,15 +107,15 @@ let devToolsOpen = false; if (IS_DEV && IS_DISCORD_DESKTOP) { // At this point in time, DiscordNative has not been exposed yet, so setImmediate is needed setTimeout(() => { - DiscordNative/* just to make sure */?.window.setDevtoolsCallbacks(() => devToolsOpen = true, () => devToolsOpen = false); + DiscordNative?.window.setDevtoolsCallbacks(() => devToolsOpen = true, () => devToolsOpen = false); }, 0); } export const webpackSearchHistory = [] as Array<["waitFor" | "find" | "findComponent" | "findExportedComponent" | "findComponentByCode" | "findByProps" | "findByCode" | "findStore" | "extractAndLoadChunks" | "webpackDependantLazy" | "webpackDependantLazyComponent", any[]]>; function printFilter(filter: FilterFn) { - if ("$$vencordProps" in filter) { - const props = filter.$$vencordProps as string[]; + if (filter.$$vencordProps != null) { + const props = filter.$$vencordProps; return `${props[0]}(${props.slice(1).map(arg => `"${arg}"`).join(", ")})`; } @@ -132,16 +140,13 @@ export function waitFor(filter: FilterFn, callback: ModCallbackFn, { isIndirect const originalCallback = callback; let callbackCalled = false; - callback = function () { + callback = function (this: unknown) { callbackCalled = true; - // @ts-ignore - originalCallback(...arguments); + Reflect.apply(originalCallback, this, arguments); }; - // @ts-ignore callback.$$vencordCallbackCalled = () => callbackCalled; - webpackSearchHistory.push(["waitFor", [callback, filter]]); } @@ -282,7 +287,7 @@ export function findExportedComponent(...props: string[] if (IS_DEV) { WrapperComponent.$$vencordInner = () => InnerComponent; - webpackSearchHistory.push(["findExportedComponent", [WrapperComponent, ...props]]); + webpackSearchHistory.push(["findExportedComponent", [WrapperComponent, ...newProps]]); } if (InnerComponent !== null) return InnerComponent; @@ -314,7 +319,7 @@ export function findComponentByCode(...code: string[] | const ComponentResult = findComponent(filters.componentByCode(...newCode), parse, { isIndirect: true }); if (IS_DEV) { - webpackSearchHistory.push(["findComponentByCode", [ComponentResult, ...code]]); + webpackSearchHistory.push(["findComponentByCode", [ComponentResult, ...newCode]]); } return ComponentResult; @@ -480,7 +485,6 @@ export const cacheFindBulk = traceFunction("cacheFindBulk", function cacheFindBu /** * Find the id of the first module factory that includes all the given code. - * @returns string or null */ export const findModuleId = traceFunction("findModuleId", function findModuleId(...code: string[]) { outer: @@ -508,7 +512,6 @@ export const findModuleId = traceFunction("findModuleId", function findModuleId( /** * Find the first module factory that includes all the given code. - * @returns The module factory or null */ export function findModuleFactory(...code: string[]) { const id = findModuleId(...code); diff --git a/tsconfig.json b/tsconfig.json index 8db0ab3c1..34750a974 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,5 +39,5 @@ } ] }, - "include": ["src/**/*", "browser/**/*", "scripts/**/*"] + "include": ["src/**/*", "browser/**/*", "scripts/**/*", "packages/**/*"] }