diff --git a/package.json b/package.json index 23c2b29..6dc5d18 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "esbuild": "^0.17.16", "esbuild-plugin-alias": "^0.2.1", "moment": "2.22.2", - "typescript": "^5.0.4" + "typescript": "^5.2.2" }, "dependencies": { "@swc/helpers": "0.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 115dc8a..d062d41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,7 +41,7 @@ devDependencies: specifier: 2.22.2 version: 2.22.2 typescript: - specifier: ^5.0.4 + specifier: ^5.2.2 version: 5.2.2 packages: diff --git a/src/index.ts b/src/index.ts index d32c177..9b5684c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,7 @@ import initSafeMode from "@ui/safeMode"; import initSettings from "@ui/settings"; import initFixes from "@lib/fixes"; import logger from "@lib/logger"; -import windowObject from "@lib/windowObject"; +import initWindowObject from "@lib/windowObject"; export default async () => { // Load everything in parallel @@ -24,7 +24,7 @@ export default async () => { ]); // Assign window object - window.vendetta = await windowObject(unloads); + initWindowObject(unloads); // Once done, load plugins unloads.push(await initPlugins()); diff --git a/src/lib/loader.ts b/src/lib/loader.ts index bd9e9a1..a96867a 100644 --- a/src/lib/loader.ts +++ b/src/lib/loader.ts @@ -1,23 +1,23 @@ -import type { LoaderConfig, Theme } from "@types"; +import type { LoaderConfig, LoaderIdentity, Theme } from "@types"; // @ts-ignore -const pyonLoaderConfig = globalThis.__PYON_LOADER__; +const pyonLoaderIdentity = globalThis.__PYON_LOADER__; // @ts-ignore -const vendettaLoaderConfig = globalThis.__vendetta_loader; +const vendettaLoaderIdentity = globalThis.__vendetta_loader; export function isVendettaLoader() { - return vendettaLoaderConfig != null; + return vendettaLoaderIdentity != null; } export function isPyonLoader() { - return pyonLoaderConfig != null; + return pyonLoaderIdentity != null; } -function polyfillVendettaLoader() { +function polyfillVendettaLoaderIdentity() { if (!isPyonLoader() || isVendettaLoader()) return null; const loader = { - name: pyonLoaderConfig.loaderName, + name: pyonLoaderIdentity.loaderName, features: {} as Record } @@ -48,21 +48,21 @@ function polyfillVendettaLoader() { configurable: true }); - return loader as unknown as LoaderConfig; + return loader as LoaderIdentity; } -export function getVendettaLoader(): LoaderConfig | null { +export function getVendettaLoaderIdentity(): LoaderIdentity | null { // @ts-ignore if (globalThis.__vendetta_loader) return globalThis.__vendetta_loader; - return polyfillVendettaLoader(); + return polyfillVendettaLoaderIdentity(); } // add to __vendetta_loader anyway -getVendettaLoader(); +getVendettaLoaderIdentity(); export function getLoaderName() { - if (isPyonLoader()) return pyonLoaderConfig.loaderName; - else if (isVendettaLoader()) return vendettaLoaderConfig.name; + if (isPyonLoader()) return pyonLoaderIdentity.loaderName; + else if (isVendettaLoader()) return vendettaLoaderIdentity.name; return "Unknown"; } @@ -71,7 +71,7 @@ export function isLoaderConfigSupported() { if (isPyonLoader()) { return true; } else if (isVendettaLoader()) { - return vendettaLoaderConfig!!.features.loaderConfig; + return vendettaLoaderIdentity!!.features.loaderConfig; } return false; @@ -79,9 +79,9 @@ export function isLoaderConfigSupported() { export function isThemeSupported() { if (isPyonLoader()) { - return pyonLoaderConfig.hasThemeSupport; + return pyonLoaderIdentity.hasThemeSupport; } else if (isVendettaLoader()) { - return vendettaLoaderConfig!!.features.themes != null; + return vendettaLoaderIdentity!!.features.themes != null; } return false; @@ -89,9 +89,9 @@ export function isThemeSupported() { export function getStoredTheme(): Theme | null { if (isPyonLoader()) { - return pyonLoaderConfig.storedTheme; + return pyonLoaderIdentity.storedTheme; } else if (isVendettaLoader()) { - const themeProp = vendettaLoaderConfig!!.features.themes?.prop; + const themeProp = vendettaLoaderIdentity!!.features.themes?.prop; if (!themeProp) return null; // @ts-ignore return globalThis[themeProp] || null; @@ -113,7 +113,7 @@ export function getThemeFilePath() { export function isReactDevToolsPreloaded() { if (isPyonLoader()) return false; else if (isVendettaLoader()) { - return vendettaLoaderConfig!!.features.devtools != null; + return vendettaLoaderIdentity!!.features.devtools != null; } return false; @@ -123,7 +123,7 @@ export function getReactDevToolsProp(): string | null { if (!isReactDevToolsPreloaded()) return null; if (isVendettaLoader()) { - return vendettaLoaderConfig!!.features.devtools!!.prop; + return vendettaLoaderIdentity!!.features.devtools!!.prop; } return null; @@ -133,16 +133,16 @@ export function getReactDevToolsVersion() { if (!isReactDevToolsPreloaded()) return null; if (isVendettaLoader()) { - return vendettaLoaderConfig!!.features.devtools!!.version + return vendettaLoaderIdentity!!.features.devtools!!.version } return null; } export function isSysColorsSupported() { - if (isPyonLoader()) return pyonLoaderConfig.isSysColorsSupported; + if (isPyonLoader()) return pyonLoaderIdentity.isSysColorsSupported; else if (isVendettaLoader()) { - return vendettaLoaderConfig!!.features.syscolors != null; + return vendettaLoaderIdentity!!.features.syscolors != null; } return false; @@ -151,9 +151,9 @@ export function isSysColorsSupported() { export function getSysColors() { if (!isSysColorsSupported()) return null; if (isPyonLoader()) { - return pyonLoaderConfig.sysColors; + return pyonLoaderIdentity.sysColors; } else if (isVendettaLoader()) { - return vendettaLoaderConfig!!.features.syscolors!!.prop; + return vendettaLoaderIdentity!!.features.syscolors!!.prop; } return null; diff --git a/src/lib/vendettaObject.ts b/src/lib/vendettaObject.ts new file mode 100644 index 0000000..c6531f6 --- /dev/null +++ b/src/lib/vendettaObject.ts @@ -0,0 +1,163 @@ +import { VendettaObject } from "@types"; +import patcher from "@lib/patcher"; +import { getVendettaLoaderIdentity } from "@lib/loader"; +import settings, { loaderConfig } from "@lib/settings"; +import * as debug from "@lib/debug"; +import * as plugins from "@lib/plugins"; +import * as themes from "@lib/themes"; +import * as commands from "@lib/commands"; +import * as storage from "@lib/storage"; +import * as metro from "@metro/filters"; +import * as common from "@metro/common"; +import * as components from "@ui/components"; +import * as toasts from "@ui/toasts"; +import * as alerts from "@ui/alerts"; +import * as assets from "@ui/assets"; +import * as color from "@ui/color"; +import * as utils from "@lib/utils"; + +export const createVendettaObject = (unloads: any[]): VendettaObject => ({ + patcher: { + before: patcher.before, + after: patcher.after, + instead: patcher.instead + }, + metro: { + find: (filter) => metro.find(filter), + findAll: (filter) => metro.findAll(filter), + findByProps: (filter) => metro.findByProps(filter), + findByPropsAll: (filter) => metro.findByPropsAll(filter), + findByName: (name, defaultExp?) => metro.findByName(name, defaultExp), + findByNameAll: (name, defaultExp?) => metro.findByNameAll(name, defaultExp), + findByDisplayName: (displayName, defaultExp?) => metro.findByDisplayName(displayName, defaultExp), + findByDisplayNameAll: (displayName, defaultExp?) => metro.findByDisplayNameAll(displayName, defaultExp), + findByTypeName: (typeName, defaultExp?) => metro.findByTypeName(typeName, defaultExp), + findByTypeNameAll: (typeName, defaultExp?) => metro.findByTypeNameAll(typeName, defaultExp), + findByStoreName: (name: string) => metro.findByStoreName(name), + common: { + constants: common.constants, + channels: common.channels, + i18n: common.i18n, + url: common.url, + toasts: common.toasts, + stylesheet: common.stylesheet, + clipboard: common.clipboard, + assets: common.assets, + invites: common.invites, + commands: common.commands, + navigation: common.navigation, + navigationStack: common.navigationStack, + NavigationNative: common.NavigationNative, + Flux: common.Flux, + FluxDispatcher: common.FluxDispatcher, + React: common.React, + ReactNative: common.ReactNative, + moment: common.moment, + chroma: common.chroma, + lodash: common.lodash, + util: common.util + } + }, + constants: { + DISCORD_SERVER: "https://discord.gg/n9QQ4XhhJP", + GITHUB: "https://github.com/vendetta-mod", + PROXY_PREFIX: "https://vd-plugins.github.io/proxy", + HTTP_REGEX: /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/, + HTTP_REGEX_MULTI: /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g, + DISCORD_SERVER_ID: "1015931589865246730", + PLUGINS_CHANNEL_ID: "1091880384561684561", + THEMES_CHANNEL_ID: "1091880434939482202", + }, + utils: { + findInReactTree: (tree, filter) => utils.findInReactTree(tree, filter), + findInTree: (tree, filter, options) => utils.findInTree(tree, filter, options), + safeFetch: (input, options?, timeout?) => utils.safeFetch(input, options, timeout), + unfreeze: (obj: object) => utils.unfreeze(obj), + without: (object, ...keys) => utils.without(object, ...keys) + }, + debug: { + connectToDebugger: (url: string) => debug.connectToDebugger(url), + getDebugInfo: () => debug.getDebugInfo() + }, + ui: { + components: { + Forms: components.Forms, + General: components.General, + Alert: components.Alert, + Button: components.Button, + HelpMessage: components.HelpMessage, + SafeAreaView: components.SafeAreaView, + Summary: components.Summary, + ErrorBoundary: components.ErrorBoundary, + Codeblock: components.Codeblock, + Search: components.Search + }, + toasts: { + showToast: (content: string, asset?: number) => toasts.showToast(content, asset) + }, + alerts: { + showConfirmationAlert: (options) => alerts.showConfirmationAlert(options), + showCustomAlert: (component, props: any) => alerts.showCustomAlert(component, props), + showInputAlert: (options) => alerts.showInputAlert(options) + }, + assets: { + all: assets.all, + find: (filter: (a: any) => void) => assets.find(filter), + getAssetByName: (name: string) => assets.getAssetByName(name), + getAssetByID: (id: number) => assets.getAssetByID(id), + getAssetIDByName: (name: string) => assets.getAssetIDByName(name) + }, + semanticColors: color.semanticColors, + rawColors: color.rawColors + }, + plugins: { + plugins: plugins.plugins, + fetchPlugin: (id: string) => plugins.fetchPlugin(id), + installPlugin: (id: string, enabled?: boolean | undefined) => plugins.installPlugin(id, enabled), + startPlugin: (id: string) => plugins.startPlugin(id), + stopPlugin: (id: string, disable?: boolean | undefined) => plugins.stopPlugin(id, disable), + removePlugin: (id: string) => plugins.removePlugin(id), + getSettings: (id: string) => plugins.getSettings(id) + }, + themes: { + themes: themes.themes, + fetchTheme: (id: string, selected?: boolean) => themes.fetchTheme(id, selected), + installTheme: (id: string) => themes.installTheme(id), + selectTheme: (id: string) => themes.selectTheme(id), + removeTheme: (id: string) => themes.removeTheme(id), + getCurrentTheme: () => themes.getThemeFromLoader(), + updateThemes: () => themes.updateThemes() + }, + commands: { + registerCommand: commands.registerCommand + }, + storage: { + createProxy: (target) => storage.createProxy(target), + useProxy: (_storage: T) => storage.useProxy(_storage), + createStorage: (backend: any) => storage.createStorage(backend), + wrapSync: (store: any) => storage.wrapSync(store), + awaitSyncWrapper: (store: any) => storage.awaitSyncWrapper(store), + createMMKVBackend: (store: string) => storage.createMMKVBackend(store), + createFileBackend: (file: string) => storage.createFileBackend(file) + }, + settings, + loader: { + identity: getVendettaLoaderIdentity() ?? void 0, + config: loaderConfig, + }, + logger: { + log: (...message) => console.log(...message), + info: (...message) => console.info(...message), + warn: (...message) => console.warn(...message), + error: (...message) => console.error(...message), + time: (...message) => console.time(...message), + trace: (...message) => console.trace(...message), + verbose: (...message) => console.log(...message) + }, + version: debug.versionHash, + unload: () => { + unloads.filter(i => typeof i === "function").forEach(p => p()); + // @ts-expect-error explode + delete window.vendetta; + }, +}); diff --git a/src/lib/windowObject.ts b/src/lib/windowObject.ts index 38e01c3..cf309ce 100644 --- a/src/lib/windowObject.ts +++ b/src/lib/windowObject.ts @@ -1,49 +1,5 @@ -import { VendettaObject } from "@types"; -import patcher from "@lib/patcher"; -import logger from "@lib/logger"; -import settings, { loaderConfig } from "@lib/settings"; -import * as constants from "@lib/constants"; -import * as debug from "@lib/debug"; -import * as plugins from "@lib/plugins"; -import * as themes from "@lib/themes"; -import * as commands from "@lib/commands"; -import * as storage from "@lib/storage"; -import * as metro from "@metro/filters"; -import * as common from "@metro/common"; -import * as components from "@ui/components"; -import * as toasts from "@ui/toasts"; -import * as alerts from "@ui/alerts"; -import * as assets from "@ui/assets"; -import * as color from "@ui/color"; -import * as utils from "@lib/utils"; +import { createVendettaObject } from "./vendettaObject"; -export default async (unloads: any[]): Promise => ({ - patcher: utils.without(patcher, "unpatchAll"), - metro: { ...metro, common: { ...common } }, - constants, - utils, - debug: utils.without(debug, "versionHash", "patchLogHook", "toggleSafeMode"), - ui: { - components, - toasts, - alerts, - assets, - ...color, - }, - plugins: utils.without(plugins, "initPlugins", "evalPlugin"), - themes: utils.without(themes, "initThemes"), - commands: utils.without(commands, "patchCommands"), - storage, - settings, - loader: { - identity: window.__vendetta_loader, - config: loaderConfig, - }, - logger, - version: debug.versionHash, - unload: () => { - unloads.filter(i => typeof i === "function").forEach(p => p()); - // @ts-expect-error explode - delete window.vendetta; - }, -}); +export default function initWindowObject(unloads: any[]) { + window.vendetta = createVendettaObject(unloads); +} \ No newline at end of file