Merge branch 'dev' into stickercopy

This commit is contained in:
byeoon 2025-02-18 13:32:01 -05:00 committed by GitHub
commit eab586ae9a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 777 additions and 1221 deletions

View file

@ -2,30 +2,24 @@ name: Blank Issue
description: Create a blank issue. ALWAYS FIRST USE OUR SUPPORT CHANNEL! ONLY USE THIS FORM IF YOU ARE A CONTRIBUTOR OR WERE TOLD TO DO SO IN THE SUPPORT CHANNEL.
body:
- type: markdown
attributes:
value: |
# READ THIS BEFORE OPENING AN ISSUE
- type: markdown
attributes:
value: |
![Are you a developer? No? This form is not for you!](https://github.com/Vendicated/Vencord/blob/main/.github/ISSUE_TEMPLATE/developer-banner.png?raw=true)
This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS.
GitHub Issues are for development, not support! Please use our [support server](https://vencord.dev/discord) unless you are a Vencord Developer.
DO NOT USE THIS FORM, unless
- you are a vencord contributor
- you were given explicit permission to use this form by a moderator in our support server
DO NOT USE THIS FORM FOR SECURITY RELATED ISSUES. [CREATE A SECURITY ADVISORY INSTEAD.](https://github.com/Vendicated/Vencord/security/advisories/new)
- type: textarea
id: content
attributes:
label: Content
validations:
required: true
- type: checkboxes
id: agreement-check
attributes:
label: Request Agreement
options:
- label: I have read the requirements for opening an issue above
- type: textarea
id: content
attributes:
label: Content
validations:
required: true
- type: checkboxes
id: agreement-check
attributes:
label: Request Agreement
options:
- label: I have read the requirements for opening an issue above
required: true

View file

@ -4,78 +4,63 @@ labels: [bug]
title: "[Bug] <title>"
body:
- type: markdown
attributes:
value: |
# READ THIS BEFORE OPENING AN ISSUE
- type: markdown
attributes:
value: |
![Are you a developer? No? This form is not for you!](https://github.com/Vendicated/Vencord/blob/main/.github/ISSUE_TEMPLATE/developer-banner.png?raw=true)
This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS.
GitHub Issues are for development, not support! Please use our [support server](https://vencord.dev/discord) unless you are a Vencord Developer.
DO NOT USE THIS FORM, unless
- you are a vencord contributor
- you were given explicit permission to use this form by a moderator in our support server
DO NOT USE THIS FORM FOR SECURITY RELATED ISSUES. [CREATE A SECURITY ADVISORY INSTEAD.](https://github.com/Vendicated/Vencord/security/advisories/new)
- type: input
id: discord
attributes:
label: Discord Account
description: Who on Discord is making this request? Not required but encouraged for easier follow-up
placeholder: username#0000
validations:
required: false
- type: textarea
id: bug-description
attributes:
label: What happens when the bug or crash occurs?
description: Where does this bug or crash occur, when does it occur, etc.
placeholder: The bug/crash happens sometimes when I do ..., causing this to not work/the app to crash. I think it happens because of ...
validations:
required: true
- type: textarea
id: expected-behaviour
attributes:
label: What is the expected behaviour?
description: Simply detail what the expected behaviour is.
placeholder: I expect Vencord/Discord to open the ... page instead of ..., it prevents me from doing ...
validations:
required: true
- type: textarea
id: steps-to-take
attributes:
label: How do you recreate this bug or crash?
description: Give us a list of steps in order to recreate the bug or crash.
placeholder: |
1. Do ...
2. Then ...
3. Do this ..., ... and then ...
4. Observe "the bug" or "the crash"
validations:
required: true
- type: textarea
id: crash-log
attributes:
label: Errors
description: Open the Developer Console with Ctrl/Cmd + Shift + i. Then look for any red errors (Ignore network errors like Failed to load resource) and paste them between the "```".
value: |
```
Replace this text with your crash-log.
```
validations:
required: false
- type: checkboxes
id: agreement-check
attributes:
label: Request Agreement
description: We only accept reports for bugs that happen on Discord Stable. Canary and PTB are Development branches and may be unstable
options:
- label: I am using Discord Stable or tried on Stable and this bug happens there as well
- type: textarea
id: bug-description
attributes:
label: What happens when the bug or crash occurs?
description: Where does this bug or crash occur, when does it occur, etc.
placeholder: The bug/crash happens sometimes when I do ..., causing this to not work/the app to crash. I think it happens because of ...
validations:
required: true
- label: I have read the requirements for opening an issue above
- type: textarea
id: expected-behaviour
attributes:
label: What is the expected behaviour?
description: Simply detail what the expected behaviour is.
placeholder: I expect Vencord/Discord to open the ... page instead of ..., it prevents me from doing ...
validations:
required: true
- type: textarea
id: steps-to-take
attributes:
label: How do you recreate this bug or crash?
description: Give us a list of steps in order to recreate the bug or crash.
placeholder: |
1. Do ...
2. Then ...
3. Do this ..., ... and then ...
4. Observe "the bug" or "the crash"
validations:
required: true
- type: textarea
id: crash-log
attributes:
label: Errors
description: Open the Developer Console with Ctrl/Cmd + Shift + i. Then look for any red errors (Ignore network errors like Failed to load resource) and paste them between the "```".
value: |
```
Replace this text with your crash-log.
```
validations:
required: false
- type: checkboxes
id: agreement-check
attributes:
label: Request Agreement
description: We only accept reports for bugs that happen on Discord Stable. Canary and PTB are Development branches and may be unstable
options:
- label: I am using Discord Stable or tried on Stable and this bug happens there as well
required: true
- label: I am a Vencord Developer
required: true

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -42,7 +42,7 @@ jobs:
- name: Clean up obsolete files
run: |
rm -rf dist/*-unpacked dist/monaco Vencord.user.css vencordDesktopRenderer.css vencordDesktopRenderer.css.map
rm -rf dist/*-unpacked dist/vendor Vencord.user.css vencordDesktopRenderer.css vencordDesktopRenderer.css.map
- name: Get some values needed for the release
id: release_values

View file

@ -1,7 +1,7 @@
{
"name": "vencord",
"private": "true",
"version": "1.11.4",
"version": "1.11.5",
"description": "The cutest Discord client mod",
"homepage": "https://github.com/Vendicated/Vencord#readme",
"bugs": {
@ -24,7 +24,7 @@
"dev": "pnpm watch",
"watchWeb": "pnpm buildWeb --watch",
"generatePluginJson": "tsx scripts/generatePluginList.ts",
"generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types",
"generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types --allowJs false",
"inject": "node scripts/runInstaller.mjs",
"uninject": "node scripts/runInstaller.mjs",
"lint": "eslint",
@ -45,31 +45,31 @@
"virtual-merge": "^1.0.1"
},
"devDependencies": {
"@stylistic/eslint-plugin": "^2.12.1",
"@types/chrome": "^0.0.287",
"@types/diff": "^6.0.0",
"@stylistic/eslint-plugin": "^4.0.0",
"@types/chrome": "^0.0.304",
"@types/diff": "^7.0.1",
"@types/lodash": "^4.17.14",
"@types/node": "^22.10.5",
"@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@types/yazl": "^2.4.5",
"diff": "^7.0.0",
"discord-types": "^1.3.26",
"esbuild": "^0.25.0",
"eslint": "^9.17.0",
"eslint": "^9.20.1",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-path-alias": "2.1.0",
"eslint-plugin-react": "^7.37.3",
"eslint-plugin-simple-header": "^1.2.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-unused-imports": "^4.1.4",
"highlight.js": "11.7.0",
"highlight.js": "11.11.1",
"html-minifier-terser": "^7.2.0",
"moment": "^2.22.2",
"puppeteer-core": "^23.11.1",
"standalone-electron-types": "^1.0.0",
"puppeteer-core": "^24.2.1",
"standalone-electron-types": "^34.2.0",
"stylelint": "^16.12.0",
"stylelint-config-standard": "^36.0.1",
"stylelint-config-standard": "^37.0.0",
"ts-patch": "^3.3.0",
"ts-pattern": "^5.6.0",
"tsx": "^4.19.2",
@ -82,7 +82,7 @@
"packageManager": "pnpm@9.1.0",
"pnpm": {
"patchedDependencies": {
"eslint@9.17.0": "patches/eslint@9.17.0.patch",
"eslint@9.20.1": "patches/eslint@9.20.1.patch",
"eslint-plugin-path-alias@2.1.0": "patches/eslint-plugin-path-alias@2.1.0.patch"
},
"peerDependencyRules": {

View file

@ -1,7 +1,7 @@
{
"name": "@vencord/types",
"private": false,
"version": "0.1.3",
"version": "1.11.5",
"description": "",
"types": "index.d.ts",
"scripts": {
@ -13,16 +13,16 @@
"license": "GPL-3.0",
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"fs-extra": "^11.2.0",
"tsx": "^3.12.6"
"fs-extra": "^11.3.0",
"tsx": "^4.19.2"
},
"dependencies": {
"@types/lodash": "^4.14.191",
"@types/node": "^18.11.18",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.0.10",
"@types/lodash": "4.17.15",
"@types/node": "^22.13.4",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.1",
"discord-types": "^1.3.26",
"standalone-electron-types": "^1.0.0",
"type-fest": "^3.5.3"
"standalone-electron-types": "^34.2.0",
"type-fest": "^4.35.0"
}
}

1588
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -4,11 +4,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import type { Settings } from "@api/Settings";
import { PluginIpcMappings } from "@main/ipcPlugins";
import type { UserThemeHeader } from "@main/themes";
import { IpcEvents } from "@shared/IpcEvents";
import { IpcRes } from "@utils/types";
import type { Settings } from "api/Settings";
import { ipcRenderer } from "electron";
function invoke<T = any>(event: IpcEvents, ...args: any[]) {

View file

@ -78,9 +78,9 @@ async function runReporter() {
result = await Webpack.extractAndLoadChunks(code, matcher);
if (result === false) result = null;
} else if (method === "mapMangledModule") {
const [code, mapper] = args;
const [code, mapper, includeBlacklistedExports] = args;
result = Webpack.mapMangledModule(code, mapper);
result = Webpack.mapMangledModule(code, mapper, includeBlacklistedExports);
if (Object.keys(result).length !== Object.keys(mapper).length) throw new Error("Webpack Find Fail");
} else {
// @ts-ignore

View file

@ -158,6 +158,9 @@ export default definePlugin({
aboveActivity: getIntlMessage("ACTIVITY_SETTINGS")
};
if (!names[settingsLocation] || names[settingsLocation].endsWith("_SETTINGS"))
return firstChild === "PREMIUM";
return header === names[settingsLocation];
} catch {
return firstChild === "PREMIUM";

View file

@ -5,7 +5,7 @@
*/
import { CopyIcon, DeleteIcon } from "@components/Icons";
import { Alerts, Clipboard, ContextMenuApi, Menu, UserStore } from "webpack/common";
import { Alerts, Clipboard, ContextMenuApi, Menu, UserStore } from "@webpack/common";
import { Decoration } from "../../lib/api";
import { useCurrentUserDecorationsStore } from "../../lib/stores/CurrentUserDecorationsStore";

View file

@ -9,7 +9,7 @@ import { app } from "electron";
app.on("browser-window-created", (_, win) => {
win.webContents.on("frame-created", (_, { frame }) => {
frame.once("dom-ready", () => {
frame?.once("dom-ready", () => {
if (frame.url.startsWith("https://open.spotify.com/embed/")) {
const settings = RendererSettings.store.plugins?.FixSpotifyEmbeds;
if (!settings?.enabled) return;

View file

@ -9,7 +9,7 @@ import { app } from "electron";
app.on("browser-window-created", (_, win) => {
win.webContents.on("frame-created", (_, { frame }) => {
frame.once("dom-ready", () => {
frame?.once("dom-ready", () => {
if (frame.url.startsWith("https://www.youtube.com/")) {
const settings = RendererSettings.store.plugins?.FixYoutubeEmbeds;
if (!settings?.enabled) return;

View file

@ -12,7 +12,7 @@ import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins";
import definePlugin, { OptionType } from "@utils/types";
import { findStoreLazy } from "@webpack";
import { Button, Forms, showToast, TextInput, Toasts, Tooltip, useEffect, useState } from "webpack/common";
import { Button, Forms, showToast, TextInput, Toasts, Tooltip, useEffect, useState } from "@webpack/common";
const enum ActivitiesTypes {
Game,

View file

@ -96,6 +96,6 @@
.vc-shiki-root .vc-shiki-table-cell:last-child {
padding-left: 8px;
word-break: break-word;
overflow-wrap: break-word;
width: 100%;
}

View file

@ -77,7 +77,7 @@ export const SpotifyStore = proxyLazyWebpack(() => {
class SpotifyStore extends Store {
public mPosition = 0;
private start = 0;
public _start = 0;
public track: Track | null = null;
public device: Device | null = null;
@ -100,26 +100,26 @@ export const SpotifyStore = proxyLazyWebpack(() => {
public get position(): number {
let pos = this.mPosition;
if (this.isPlaying) {
pos += Date.now() - this.start;
pos += Date.now() - this._start;
}
return pos;
}
public set position(p: number) {
this.mPosition = p;
this.start = Date.now();
this._start = Date.now();
}
prev() {
this.req("post", "/previous");
this._req("post", "/previous");
}
next() {
this.req("post", "/next");
this._req("post", "/next");
}
setVolume(percent: number) {
this.req("put", "/volume", {
this._req("put", "/volume", {
query: {
volume_percent: Math.round(percent)
}
@ -131,17 +131,17 @@ export const SpotifyStore = proxyLazyWebpack(() => {
}
setPlaying(playing: boolean) {
this.req("put", playing ? "/play" : "/pause");
this._req("put", playing ? "/play" : "/pause");
}
setRepeat(state: Repeat) {
this.req("put", "/repeat", {
this._req("put", "/repeat", {
query: { state }
});
}
setShuffle(state: boolean) {
this.req("put", "/shuffle", {
this._req("put", "/shuffle", {
query: { state }
}).then(() => {
this.shuffle = state;
@ -154,7 +154,7 @@ export const SpotifyStore = proxyLazyWebpack(() => {
this.isSettingPosition = true;
return this.req("put", "/seek", {
return this._req("put", "/seek", {
query: {
position_ms: Math.round(ms)
}
@ -164,7 +164,7 @@ export const SpotifyStore = proxyLazyWebpack(() => {
});
}
private req(method: "post" | "get" | "put", route: string, data: any = {}) {
_req(method: "post" | "get" | "put", route: string, data: any = {}) {
if (this.device?.is_active)
(data.query ??= {}).device_id = this.device.id;

View file

@ -128,7 +128,7 @@ function VoiceChannelTooltip({ channel, isLocked }: VoiceChannelTooltipProps) {
);
}
interface VoiceChannelIndicatorProps {
export interface VoiceChannelIndicatorProps {
userId: string;
isActionButton?: boolean;
shouldHighlight?: boolean;

View file

@ -10,7 +10,7 @@ import adguard from "file://adguard.js?minify";
app.on("browser-window-created", (_, win) => {
win.webContents.on("frame-created", (_, { frame }) => {
frame.once("dom-ready", () => {
frame?.once("dom-ready", () => {
if (!RendererSettings.store.plugins?.YoutubeAdblock?.enabled) return;
if (frame.url.includes("youtube.com/embed/") || (frame.url.includes("discordsays") && frame.url.includes("youtube.com"))) {

View file

@ -17,7 +17,6 @@
@media(width <= 485px) {
.vc-image-modal {
display: relative;
overflow: visible;
overflow: initial;
}

View file

@ -29,7 +29,7 @@ export type GenericStore = t.FluxStore & Record<string, any>;
export const DraftType = findByPropsLazy("ChannelMessage", "SlashCommand");
export let MessageStore: Omit<Stores.MessageStore, "getMessages"> & {
export let MessageStore: Omit<Stores.MessageStore, "getMessages"> & GenericStore & {
getMessages(chanId: string): any;
};

View file

@ -496,7 +496,7 @@ export type Avatar = ComponentType<PropsWithChildren<{
}>>;
type FocusLock = ComponentType<PropsWithChildren<{
containerRef: RefObject<HTMLElement>;
containerRef: Ref<HTMLElement>;
}>>;
export type Icon = ComponentType<JSX.IntrinsicElements["svg"] & {

View file

@ -16,7 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { DraftType } from "@webpack/common";
import { Channel, Guild, Role } from "discord-types/general";
import { FluxDispatcher, FluxEvents } from "./utils";
@ -229,7 +228,7 @@ export class ThemeStore extends FluxStore {
}
export type useStateFromStores = <T>(
stores: t.FluxStore[],
stores: any[],
mapper: () => T,
dependencies?: any,
isEqual?: (old: T, newer: T) => boolean

View file

@ -58,9 +58,9 @@ export const { match, P }: Pick<typeof import("ts-pattern"), "match" | "P"> = ma
export const lodash: typeof import("lodash") = findByPropsLazy("debounce", "cloneDeep");
export const i18n = mapMangledModuleLazy('defaultLocale:"en-US"', {
t: filters.byProps(runtimeHashMessageKey("DISCORD")),
intl: filters.byProps("string", "format"),
t: filters.byProps(runtimeHashMessageKey("DISCORD"))
});
}, true);
export let SnowflakeUtils: t.SnowflakeUtils;
waitFor(["fromTimestamp", "extractTimestamp"], m => SnowflakeUtils = m);

View file

@ -12,7 +12,7 @@ import { canonicalizeReplacement } from "@utils/patches";
import { Patch, PatchReplacement } from "@utils/types";
import { traceFunctionWithResults } from "../debug/Tracer";
import { _initWebpack, _shouldIgnoreModule, factoryListeners, findModuleId, moduleListeners, waitForSubscriptions, wreq } from "./webpack";
import { _blacklistBadModules, _initWebpack, factoryListeners, findModuleId, moduleListeners, waitForSubscriptions, wreq } from "./webpack";
import { AnyModuleFactory, AnyWebpackRequire, MaybePatchedModuleFactory, ModuleExports, PatchedModuleFactory, WebpackRequire } from "./wreq.d";
export const patches = [] as Patch[];
@ -190,6 +190,20 @@ define(Function.prototype, "m", {
*/
define(this, "m", { value: proxiedModuleFactories });
// Overwrite Webpack's defineExports function to define the export descriptors configurable.
// This is needed so we can later blacklist specific exports from Webpack search by making them non-enumerable
this.d = function (exports, definition) {
for (const key in definition) {
if (Object.hasOwn(definition, key) && !Object.hasOwn(exports, key)) {
Object.defineProperty(exports, key, {
enumerable: true,
configurable: true,
get: definition[key],
});
}
}
};
};
}
});
@ -403,27 +417,17 @@ function runFactoryWithWrap(patchedFactory: PatchedModuleFactory, thisArg: unkno
}
exports = module.exports;
if (exports == null) {
return factoryReturn;
}
if (typeof require === "function") {
const shouldIgnoreModule = _shouldIgnoreModule(exports);
if (shouldIgnoreModule) {
if (require.c != null) {
Object.defineProperty(require.c, module.id, {
value: require.c[module.id],
enumerable: false,
configurable: true,
writable: true
});
}
if (typeof require === "function" && require.c) {
if (_blacklistBadModules(require.c, exports, module.id)) {
return factoryReturn;
}
}
if (exports == null) {
return factoryReturn;
}
for (const callback of moduleListeners) {
try {
callback(exports, module.id);

View file

@ -22,7 +22,8 @@ import { Logger } from "@utils/Logger";
import { canonicalizeMatch } from "@utils/patches";
import { traceFunction } from "../debug/Tracer";
import { AnyModuleFactory, ModuleExports, WebpackRequire } from "./wreq";
import { Flux } from "./common";
import { AnyModuleFactory, AnyWebpackRequire, ModuleExports, WebpackRequire } from "./wreq";
const logger = new Logger("Webpack");
@ -111,18 +112,38 @@ export function _initWebpack(webpackRequire: WebpackRequire) {
// Credits to Zerebos for implementing this in BD, thus giving the idea for us to implement it too
const TypedArray = Object.getPrototypeOf(Int8Array);
function _shouldIgnoreValue(value: any) {
const PROXY_CHECK = "is this a proxy that returns values for any key?";
function shouldIgnoreValue(value: any) {
if (value == null) return true;
if (value === window) return true;
if (value === document || value === document.documentElement) return true;
if (value[Symbol.toStringTag] === "DOMTokenList") return true;
if (value[Symbol.toStringTag] === "DOMTokenList" || value[Symbol.toStringTag] === "IntlMessagesProxy") return true;
// Discord might export a Proxy that returns non-null values for any property key which would pass all findByProps filters.
// One example of this is their i18n Proxy. However, that is already covered by the IntlMessagesProxy check above.
// As a fallback if they ever change the name or add a new Proxy, use a unique string to detect such proxies and ignore them
if (value[PROXY_CHECK] !== void 0) {
// their i18n Proxy "caches" by setting each accessed property to the return, so try to delete
Reflect.deleteProperty(value, PROXY_CHECK);
return true;
}
if (value instanceof TypedArray) return true;
return false;
}
export function _shouldIgnoreModule(exports: any) {
if (_shouldIgnoreValue(exports)) {
function makePropertyNonEnumerable(target: Record<PropertyKey, any>, key: PropertyKey) {
const descriptor = Object.getOwnPropertyDescriptor(target, key);
if (descriptor == null) return;
Reflect.defineProperty(target, key, {
...descriptor,
enumerable: false
});
}
export function _blacklistBadModules(requireCache: NonNullable<AnyWebpackRequire["c"]>, exports: ModuleExports, moduleId: PropertyKey) {
if (shouldIgnoreValue(exports)) {
makePropertyNonEnumerable(requireCache, moduleId);
return true;
}
@ -130,14 +151,16 @@ export function _shouldIgnoreModule(exports: any) {
return false;
}
let allNonEnumerable = true;
let hasOnlyBadProperties = true;
for (const exportKey in exports) {
if (!_shouldIgnoreValue(exports[exportKey])) {
allNonEnumerable = false;
if (shouldIgnoreValue(exports[exportKey])) {
makePropertyNonEnumerable(exports, exportKey);
} else {
hasOnlyBadProperties = false;
}
}
return allNonEnumerable;
return hasOnlyBadProperties;
}
let devToolsOpen = false;
@ -405,7 +428,10 @@ export function findByCodeLazy(...code: CodeFilter) {
* Find a store by its displayName
*/
export function findStore(name: StoreNameFilter) {
const res = find(filters.byStoreName(name), { isIndirect: true });
const res = Flux.Store.getAll
? Flux.Store.getAll().find(filters.byStoreName(name))
: find(filters.byStoreName(name), { isIndirect: true });
if (!res)
handleModuleNotFound("findStore", name);
return res;
@ -473,12 +499,27 @@ export function findExportedComponentLazy<T extends object = any>(...props: Prop
});
}
function getAllPropertyNames(object: Record<PropertyKey, any>, includeNonEnumerable: boolean) {
const names = new Set<PropertyKey>();
const getKeys = includeNonEnumerable ? Object.getOwnPropertyNames : Object.keys;
do {
getKeys(object).forEach(name => names.add(name));
object = Object.getPrototypeOf(object);
} while (object != null);
return names;
}
/**
* Finds a mangled module by the provided code "code" (must be unique and can be anywhere in the module)
* then maps it into an easily usable module via the specified mappers.
*
* @param code The code to look for
* @param mappers Mappers to create the non mangled exports
* @param includeBlacklistedExports Whether to include blacklisted exports in the search.
* These exports are dangerous. Accessing properties on them may throw errors
* or always return values (so a byProps filter will always return true)
* @returns Unmangled exports as specified in mappers
*
* @example mapMangledModule("headerIdIsManaged:", {
@ -486,7 +527,7 @@ export function findExportedComponentLazy<T extends object = any>(...props: Prop
* closeModal: filters.byCode("key==")
* })
*/
export const mapMangledModule = traceFunction("mapMangledModule", function mapMangledModule<S extends string>(code: string | RegExp | CodeFilter, mappers: Record<S, FilterFn>): Record<S, any> {
export const mapMangledModule = traceFunction("mapMangledModule", function mapMangledModule<S extends string>(code: string | RegExp | CodeFilter, mappers: Record<S, FilterFn>, includeBlacklistedExports = false): Record<S, any> {
const exports = {} as Record<S, any>;
const id = findModuleId(...Array.isArray(code) ? code : [code]);
@ -494,8 +535,9 @@ export const mapMangledModule = traceFunction("mapMangledModule", function mapMa
return exports;
const mod = wreq(id as any);
const keys = getAllPropertyNames(mod, includeBlacklistedExports);
outer:
for (const key in mod) {
for (const key of keys) {
const member = mod[key];
for (const newName in mappers) {
// if the current mapper matches this module
@ -509,24 +551,13 @@ export const mapMangledModule = traceFunction("mapMangledModule", function mapMa
});
/**
* {@link mapMangledModule}, lazy.
* Finds a mangled module by the provided code "code" (must be unique and can be anywhere in the module)
* then maps it into an easily usable module via the specified mappers.
*
* @param code The code to look for
* @param mappers Mappers to create the non mangled exports
* @returns Unmangled exports as specified in mappers
*
* @example mapMangledModule("headerIdIsManaged:", {
* openModal: filters.byCode("headerIdIsManaged:"),
* closeModal: filters.byCode("key==")
* })
* lazy mapMangledModule
* @see {@link mapMangledModule}
*/
export function mapMangledModuleLazy<S extends string>(code: string | RegExp | CodeFilter, mappers: Record<S, FilterFn>): Record<S, any> {
if (IS_REPORTER) lazyWebpackSearchHistory.push(["mapMangledModule", [code, mappers]]);
export function mapMangledModuleLazy<S extends string>(code: string | RegExp | CodeFilter, mappers: Record<S, FilterFn>, includeBlacklistedExports = false): Record<S, any> {
if (IS_REPORTER) lazyWebpackSearchHistory.push(["mapMangledModule", [code, mappers, includeBlacklistedExports]]);
return proxyLazy(() => mapMangledModule(code, mappers));
return proxyLazy(() => mapMangledModule(code, mappers, includeBlacklistedExports));
}
export const DefaultExtractAndLoadChunksRegex = /(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?|Promise\.resolve\(\))\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/;

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

@ -17,14 +17,11 @@ export type Module = {
/** exports can be anything, however initially it is always an empty object */
export type ModuleFactory = (this: ModuleExports, module: Module, exports: ModuleExports, require: WebpackRequire) => void;
export type WebpackQueues = unique symbol | "__webpack_queues__";
export type WebpackExports = unique symbol | "__webpack_exports__";
export type WebpackError = unique symbol | "__webpack_error__";
/** Keys here can be symbols too, but we can't properly type them */
export type AsyncModulePromise = Promise<ModuleExports> & {
[WebpackQueues]: (fnQueue: ((queue: any[]) => any)) => any;
[WebpackExports]: ModuleExports;
[WebpackError]?: any;
"__webpack_queues__": (fnQueue: ((queue: any[]) => any)) => any;
"__webpack_exports__": ModuleExports;
"__webpack_error__"?: any;
};
export type AsyncModuleBody = (
@ -152,7 +149,7 @@ export type WebpackRequire = ((moduleId: PropertyKey) => ModuleExports) & {
* }
* // exports is now { exportName: someExportedValue } (but each value is actually a getter)
*/
d: (this: WebpackRequire, exports: AnyRecord, definiton: AnyRecord) => void;
d: (this: WebpackRequire, exports: Record<PropertyKey, any>, definiton: Record<PropertyKey, () => ModuleExports>) => void;
/** The ensure chunk handlers, which are used to ensure the files of the chunks are loaded, or load if necessary */
f: EnsureChunkHandlers;
/**