From 718ebd56ac23d9f37989af5b17ff67b76ed0dc7b Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:39:57 -0300 Subject: [PATCH] Allow mapMangledModule to be destructured again --- src/debug/runReporter.ts | 25 +++++--- .../decor/ui/modals/CreateDecorationModal.tsx | 7 ++- src/plugins/newGuildSettings/index.tsx | 4 +- src/plugins/replyTimestamp/index.tsx | 10 ++-- src/plugins/validUser/index.tsx | 3 +- src/utils/lazy.ts | 19 ++++++ src/webpack/api.tsx | 58 ++++++++++++------- src/webpack/common/utils.ts | 2 +- 8 files changed, 87 insertions(+), 41 deletions(-) diff --git a/src/debug/runReporter.ts b/src/debug/runReporter.ts index e02e29a36..24bc138df 100644 --- a/src/debug/runReporter.ts +++ b/src/debug/runReporter.ts @@ -58,23 +58,32 @@ async function runReporter() { if (findResult != null) { if (findResult.$$vencordCallbackCalled != null && findResult.$$vencordCallbackCalled()) { result = findResult; + break; } if (findResult[SYM_PROXY_INNER_GET] != null) { result = findResult[SYM_PROXY_INNER_VALUE]; - if (result != null && searchType === "mapMangledModule") { - for (const innerMap in result) { - if (result[innerMap][SYM_PROXY_INNER_GET] != null) { - throw new Error("Webpack Find Fail"); - } - } - } + break; } if (findResult[SYM_LAZY_COMPONENT_INNER] != null) { result = findResult[SYM_LAZY_COMPONENT_INNER](); + break; } + + if (searchType === "mapMangledModule") { + result = findResult; + + for (const innerMap in result) { + if (result[innerMap][SYM_PROXY_INNER_GET] != null && result[innerMap][SYM_PROXY_INNER_VALUE] == null) { + throw new Error("Webpack Find Fail"); + } + } + } + + // This can happen if a `find` was immediately found + result = findResult; } break; @@ -125,7 +134,7 @@ async function runReporter() { const [code, mappers] = parsedArgs; const parsedFailedMappers = Object.entries(mappers) - .filter(([key]) => result == null || result[key][SYM_PROXY_INNER_GET] != null) + .filter(([key]) => result == null || (result[key][SYM_PROXY_INNER_GET] != null && result[key][SYM_PROXY_INNER_VALUE] == null)) .map(([key, filter]) => { let parsedFilter: string; diff --git a/src/plugins/decor/ui/modals/CreateDecorationModal.tsx b/src/plugins/decor/ui/modals/CreateDecorationModal.tsx index 78535d4f0..b130bee46 100644 --- a/src/plugins/decor/ui/modals/CreateDecorationModal.tsx +++ b/src/plugins/decor/ui/modals/CreateDecorationModal.tsx @@ -9,7 +9,7 @@ import { Link } from "@components/Link"; import { openInviteModal } from "@utils/discord"; import { Margins } from "@utils/margins"; import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; -import { findByProps, findComponentByCode } from "@webpack"; +import { filters, findComponentByCode, mapMangledModule } from "@webpack"; import { Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Text, TextInput, useEffect, useMemo, UserStore, useState } from "@webpack/common"; import { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from "../../lib/constants"; @@ -19,7 +19,10 @@ import { AvatarDecorationModalPreview } from "../components"; const FileUpload = findComponentByCode("fileUploadInput,"); const HelpMessage = findComponentByCode(".iconDiv,", "messageType"); -const HelpMessageTypes = findByProps("POSITIVE", "WARNING"); + +const { HelpMessageTypes } = mapMangledModule('POSITIVE=3]="POSITIVE', { + HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"), +}); function useObjectURL(object: Blob | MediaSource | null) { const [url, setUrl] = useState(null); diff --git a/src/plugins/newGuildSettings/index.tsx b/src/plugins/newGuildSettings/index.tsx index bb0e6dd16..c355839bb 100644 --- a/src/plugins/newGuildSettings/index.tsx +++ b/src/plugins/newGuildSettings/index.tsx @@ -29,7 +29,7 @@ import { Menu } from "@webpack/common"; import { Guild } from "discord-types/general"; const updateGuildNotificationSettings = findByPropsAndExtract("updateGuildNotificationSettings"); -const OnboardingChannelUtils = mapMangledModule(".onboardExistingMember(", { +const { toggleShowAllChannels } = mapMangledModule(".onboardExistingMember(", { toggleShowAllChannels: m => { const s = String(m); return s.length < 100 && !s.includes("onboardExistingMember") && !s.includes("getOptedInChannels"); @@ -111,7 +111,7 @@ function applyDefaultSettings(guildId: string | null) { }); } if (settings.store.showAllChannels && isOptInEnabledForGuild(guildId)) { - OnboardingChannelUtils.toggleShowAllChannels(guildId); + toggleShowAllChannels(guildId); } } diff --git a/src/plugins/replyTimestamp/index.tsx b/src/plugins/replyTimestamp/index.tsx index b75847bd9..9d60be973 100644 --- a/src/plugins/replyTimestamp/index.tsx +++ b/src/plugins/replyTimestamp/index.tsx @@ -14,7 +14,7 @@ import { Timestamp } from "@webpack/common"; import type { Message } from "discord-types/general"; import type { HTMLAttributes } from "react"; -const DateFormatUtils = mapMangledModule("millisecondsInUnit:", { +const { calendarFormat, dateFormat, isSameDay } = mapMangledModule("millisecondsInUnit:", { calendarFormat: filters.byCode("sameElse"), dateFormat: filters.byCode(':").concat'), isSameDay: filters.byCode("Math.abs(+"), @@ -46,14 +46,14 @@ function ReplyTimestamp({ return ( [ - {DateFormatUtils.isSameDay(refTimestamp, baseTimestamp) - ? DateFormatUtils.dateFormat(refTimestamp, "LT") - : DateFormatUtils.calendarFormat(refTimestamp) + {isSameDay(refTimestamp, baseTimestamp) + ? dateFormat(refTimestamp, "LT") + : calendarFormat(refTimestamp) } ] diff --git a/src/plugins/validUser/index.tsx b/src/plugins/validUser/index.tsx index 603657cc4..4825cdaa3 100644 --- a/src/plugins/validUser/index.tsx +++ b/src/plugins/validUser/index.tsx @@ -22,12 +22,11 @@ import { isNonNullish } from "@utils/guards"; import { sleep } from "@utils/misc"; import { Queue } from "@utils/Queue"; import definePlugin from "@utils/types"; -import { webpackDependantLazy } from "@webpack"; import { Constants, FluxDispatcher, RestAPI, UserProfileStore, UserStore, useState } from "@webpack/common"; import { type ComponentType, type ReactNode } from "react"; // LYING to the type checker here -const UserFlags = webpackDependantLazy(() => Constants.UserFlags as Record); +const UserFlags = Constants.UserFlags as Record; const badges: Record = { active_developer: { id: "active_developer", description: "Active Developer", icon: "6bdc42827a38498929a4920da12695d9", link: "https://support-dev.discord.com/hc/en-us/articles/10113997751447" }, bug_hunter_level_1: { id: "bug_hunter_level_1", description: "Discord Bug Hunter", icon: "2717692c7dca7289b35297368a940dd0", link: "https://support.discord.com/hc/en-us/articles/360046057772-Discord-Bugs" }, diff --git a/src/utils/lazy.ts b/src/utils/lazy.ts index 4001c7700..aa7bf4574 100644 --- a/src/utils/lazy.ts +++ b/src/utils/lazy.ts @@ -122,3 +122,22 @@ export function proxyLazy(factory: () => T, attempts = 5): ProxyL return proxy; } + +/** + * A string which returns the factory result every time its value is accessed. + * + * @param factory Factory returning the string to use as the value + */ +export function lazyString(factory: () => T) { + const descriptor: PropertyDescriptor = { + configurable: true, + enumerable: false, + writable: false, + value: factory + }; + + return Object.create(String.prototype, { + toString: descriptor, + valueOf: descriptor + }); +} diff --git a/src/webpack/api.tsx b/src/webpack/api.tsx index 7beba1304..c01cdc727 100644 --- a/src/webpack/api.tsx +++ b/src/webpack/api.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import { makeLazy, proxyLazy } from "@utils/lazy"; +import { lazyString, makeLazy, proxyLazy } from "@utils/lazy"; import { LazyComponent, LazyComponentType, SYM_LAZY_COMPONENT_INNER } from "@utils/lazyReact"; import { Logger } from "@utils/Logger"; import { canonicalizeMatch } from "@utils/patches"; @@ -430,37 +430,53 @@ export function findByFactoryCode(...code: string[] | [...string[ * @returns Unmangled exports as specified in mappers */ export function mapMangledModule(code: string | string[], mappers: Record) { - const result = find>(filters.byFactoryCode(...Array.isArray(code) ? code : [code]), exports => { - const mapping = {} as Record; + const mapping = {} as Record; + const setters = {} as Record void>; - outer: - for (const newName in mappers) { - const filter = mappers[newName]; + for (const newName in mappers) { + // Wrapper to select whether the parent factory filter or child mapper filter failed when the error is thrown + const errorMsgWrapper = lazyString(() => `Webpack mapMangledModule ${callbackCalled ? "mapper" : "factory"} filter matched no module. Filter: ${printFilter(callbackCalled ? mappers[newName] : factoryFilter)}`); - if (typeof exports === "object") { - for (const exportKey in exports) { - const exportValue = exports[exportKey]; + const [proxy, setInnerValue] = proxyInner(errorMsgWrapper, "Webpack find with proxy called on a primitive value."); + mapping[newName] = proxy; + setters[newName] = setInnerValue; + } - if (exportValue != null && filter(exportValue)) { - mapping[newName] = exportValue; - continue outer; - } + const factoryFilter = filters.byFactoryCode(...Array.isArray(code) ? code : [code]); + + let callbackCalled = false; + waitFor(factoryFilter, exports => { + callbackCalled = true; + + for (const exportKey in exports) { + const exportValue = exports[exportKey]; + if (exportValue == null) continue; + + for (const newName in mappers) { + const filter = mappers[newName]; + + if (filter(exportValue)) { + setters[newName](exportValue); } } - - const [proxy] = proxyInner(`Webpack mapMangledModule mapper filter matched no module. Filter: ${printFilter(filter)}`, "Webpack find with proxy called on a primitive value."); - // Use the proxy to throw errors because no export matched the filter - mapping[newName] = proxy; } - - return mapping; }, { isIndirect: true }); if (IS_REPORTER) { - webpackSearchHistory.push(["mapMangledModule", [result, code, mappers]]); + webpackSearchHistory.push(["mapMangledModule", [mapping, code, mappers]]); } - return result; + if (callbackCalled) { + for (const innerMap in mapping) { + const innerValue = mapping[innerMap]; + + if (innerValue[SYM_PROXY_INNER_VALUE] != null) { + mapping[innerMap] = innerValue[SYM_PROXY_INNER_VALUE]; + } + } + } + + return mapping; } /** diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts index c15269fd9..c0dd7b7d3 100644 --- a/src/webpack/common/utils.ts +++ b/src/webpack/common/utils.ts @@ -129,7 +129,7 @@ export const Clipboard: t.Clipboard = mapMangledModule('queryCommandEnabled("cop SUPPORTS_COPY: e => typeof e === "boolean" }); -export const NavigationRouter: t.NavigationRouter = mapMangledModule("Transitioning to ", { +export const NavigationRouter: t.NavigationRouter = mapMangledModule("aTransitioning to ", { transitionTo: filters.byCode("transitionTo -"), transitionToGuild: filters.byCode("transitionToGuild -"), back: filters.byCode("goBack()"),