Project restructuring (half-progress, untested)

This commit is contained in:
amsyarasyiq 2024-02-28 14:09:42 +08:00
parent c8cd4967de
commit a759c4d883
76 changed files with 264 additions and 226 deletions

View file

@ -37,7 +37,7 @@ try {
legalComments: "none",
alias: {
"@*": "src*",
"@types": "src/def.d.ts"
"@types": "src/utils/types.ts"
},
plugins: [
{

View file

@ -2,24 +2,32 @@
\import ./index
@bunny from BunnyObject {
patcher
api {
commands
native
storage
assets
patcher
}
managers {
plugins
themes
}
metro {
filters
common
}
constants
utils
debug
ui {
components
toasts
alerts
assets
color
toasts
}
native
plugins
themes
commands
storage
utils {
constants
types
logger
}
debug
settings
loader
}

View file

@ -1,7 +1,7 @@
import { Strings } from "@/lib/i18n";
import { Strings } from "@/core/i18n";
import { getDebugInfo } from "@lib/debug";
import { messageUtil } from "@metro/common";
import { ApplicationCommand, ApplicationCommandOptionType } from "../types";
import { ApplicationCommand, ApplicationCommandOptionType } from "@/lib/api/commands/types";
export default () => <ApplicationCommand>{
name: "debug",

View file

@ -1,7 +1,7 @@
import { findByProps } from "@metro/filters";
import { messageUtil } from "@metro/common";
import { Strings } from "@/lib/i18n";
import { ApplicationCommand, ApplicationCommandOptionType } from "../types";
import { Strings } from "@/core/i18n";
import { ApplicationCommand, ApplicationCommandOptionType } from "@/lib/api/commands/types";
const util = findByProps("inspect");
const AsyncFunction = (async () => void 0).constructor;

View file

@ -1,7 +1,7 @@
import { messageUtil } from "@metro/common";
import { plugins as pluginStorage } from "@lib/plugins";
import { Strings } from "@/lib/i18n";
import { ApplicationCommand, ApplicationCommandOptionType } from "../types";
import { plugins as pluginStorage } from "@lib/managers/plugins";
import { Strings } from "@/core/i18n";
import { ApplicationCommand, ApplicationCommandOptionType } from "@/lib/api/commands/types";
export default () => <ApplicationCommand>{
name: "plugins",

View file

@ -1,5 +1,5 @@
import { FluxDispatcher, moment } from "@metro/common";
import logger from "@lib/logger";
import logger from "@lib/utils/logger";
function onDispatch({ locale }: { locale: string }) {
// Timestamps

View file

@ -3,3 +3,6 @@ const allSettledFulfill = <T>(value: T) => ({ status: "fulfilled", value });
const allSettledReject = <T>(reason: T) => ({ status: "rejected", reason });
const mapAllSettled = <T>(item: T) => Promise.resolve(item).then(allSettledFulfill, allSettledReject);
export const allSettled = <T extends unknown[]>(iterator: T) => Promise.all(Array.from(iterator).map(mapAllSettled));
// @ts-ignore
Promise.allSettled ??= allSettled;

View file

@ -1,6 +1,6 @@
// Hoist required modules
import { isThemeSupported } from "./loader";
import { isThemeSupported } from "../lib/api/native/loader";
// This used to be in filters.ts, but things became convoluted
const basicFind = (filter: (m: any) => any | string) => {
@ -22,7 +22,7 @@ export const chroma = basicFind(m => m.brewer) as typeof import("chroma-js");
// Themes
if (isThemeSupported()) {
try {
require("@lib/themes").initThemes();
require("@lib/managers/themes").initThemes();
} catch (e) {
console.error("[Vendetta] Failed to initialize themes...", e);
}

View file

@ -1,17 +1,17 @@
import patcher from "@lib/patcher";
import { getVendettaLoaderIdentity } from "@lib/loader";
import settings, { loaderConfig } from "@lib/settings";
import patcher from "@lib/api/patcher";
import { getVendettaLoaderIdentity } from "@lib/api/native/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 plugins from "@lib/managers/plugins";
import * as themes from "@lib/managers/themes";
import * as commands from "@/lib/api/commands";
import * as storage from "@/lib/api/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 assets from "@/lib/api/assets";
import * as color from "@ui/color";
import * as utils from "@lib/utils";

View file

@ -14,7 +14,7 @@ const init = (async () => {
await import(".").then((m) => m.default());
} catch (e) {
const { ClientInfoManager } = require("@lib/native/modules");
const { ClientInfoManager } = require("@lib/api/native/modules");
const stack = e instanceof Error ? e.stack : undefined;
console.log(stack ?? e?.toString?.() ?? e);

View file

@ -1,13 +1,13 @@
import { patchLogHook } from "@lib/debug";
import { patchCommands } from "@lib/commands";
import { initPlugins } from "@lib/plugins";
import { patchChatBackground } from "@lib/themes";
import { patchAssets } from "@ui/assets";
import { patchCommands } from "@/lib/api/commands";
import { initPlugins } from "@lib/managers/plugins";
import { patchChatBackground } from "@lib/managers/themes";
import { patchAssets } from "@/lib/api/assets";
import initQuickInstall from "@ui/quickInstall";
import initSafeMode from "@ui/safeMode";
import initSettings from "@ui/settings";
import initFixes from "@lib/fixes";
import logger from "@lib/logger";
import initFixes from "@/core/fixes";
import logger from "@lib/utils/logger";
import initWindowObject from "@lib/windowObject";
export default async () => {

View file

@ -1,5 +1,5 @@
import { assets } from "@metro/common";
import { after } from "@lib/patcher";
import { after } from "@lib/api/patcher";
export const all: Record<string, Asset> = {};

View file

@ -1,5 +1,5 @@
import { commands as commandsModule } from "@metro/common";
import { after } from "@lib/patcher";
import { after } from "@lib/api/patcher";
import { ApplicationCommand, ApplicationCommandType, ApplicationCommandInputType } from "./types";
let commands: ApplicationCommand[] = [];
@ -11,9 +11,9 @@ export function patchCommands() {
// Register core commands
[
require("@lib/commands/core/eval"),
require("@lib/commands/core/debug"),
require("@lib/commands/core/plugins")
require("@/core/commands/eval"),
require("@/core/commands/debug"),
require("@/core/commands/plugins")
].forEach(r => registerCommand(r.default()));
return () => {

5
src/lib/api/index.ts Normal file
View file

@ -0,0 +1,5 @@
export * as commands from "./commands";
export * as native from "./native";
export * as storage from "./storage";
export * as assets from "./assets";
export * as patcher from "./patcher";

View file

@ -1,4 +1,4 @@
import { FileManager } from "@lib/native/modules";
import { FileManager } from "./modules";
/**
* Remove file from given path, currently no check for any failure

View file

@ -1,4 +1,4 @@
import { Theme } from "./themes";
import { Theme } from "../../managers/themes";
// @ts-ignore
const pyonLoaderIdentity = globalThis.__PYON_LOADER__;
@ -65,6 +65,16 @@ function polyfillVendettaLoaderIdentity() {
return loader as VendettaLoaderIdentity;
}
export function getLoaderIdentity() {
if (isPyonLoader()) {
return pyonLoaderIdentity;
} else if (isVendettaLoader()) {
return getVendettaLoaderIdentity();
}
return null;
}
export function getVendettaLoaderIdentity(): VendettaLoaderIdentity | null {
// @ts-ignore
if (globalThis.__vendetta_loader) return globalThis.__vendetta_loader;

View file

@ -1,5 +1,5 @@
import { MMKVManager, FileManager } from "@lib/native/modules";
import { ReactNative as RN } from "@metro/common";
import { FileManager, MMKVManager } from "../native/modules";
export interface StorageBackend {
get: () => unknown | Promise<unknown>;

View file

@ -1,5 +1,5 @@
import createEmitter, { Emitter } from "@lib/emitter";
import { StorageBackend } from "@lib/storage/backends";
import { createEmitter, Emitter } from "@lib/utils/emitter";
import { StorageBackend } from "@lib/api/storage/backends";
const emitterSymbol = Symbol.for("vendetta.storage.emitter");
const syncAwaitSymbol = Symbol.for("vendetta.storage.accessor");
@ -113,4 +113,4 @@ export function wrapSync<T extends Promise<any>>(store: T): Awaited<T> {
export const awaitSyncWrapper = (store: any) => new Promise<void>((res) => store[syncAwaitSymbol](res));
export * from "@lib/storage/backends";
export * from "@lib/api/storage/backends";

View file

@ -1,12 +1,12 @@
import { ReactNative as RN } from "@metro/common";
import { after } from "@lib/patcher";
import { getThemeFromLoader, selectTheme } from "@lib/themes";
import { ClientInfoManager, DeviceManager, BundleUpdaterManager } from "@lib/native/modules";
import { getAssetIDByName } from "@ui/assets";
import { after } from "@lib/api/patcher";
import { getThemeFromLoader, selectTheme } from "@lib/managers/themes";
import { ClientInfoManager, DeviceManager, BundleUpdaterManager } from "@lib/api/native/modules";
import { getAssetIDByName } from "@/lib/api/assets";
import { showToast } from "@ui/toasts";
import settings from "@lib/settings";
import logger from "@lib/logger";
import { getLoaderName, isThemeSupported } from "./loader";
import { settings } from "@lib/settings";
import logger from "@lib/utils/logger";
import { getLoaderName, isThemeSupported } from "./api/native/loader";
import type { PlatformConstants } from "react-native";
import { version } from "bunny-build";
export let socket: WebSocket;

View file

@ -0,0 +1,2 @@
export * as plugins from "./plugins";
export * as themes from "./themes";

View file

@ -1,9 +1,9 @@
import { safeFetch } from "@lib/utils";
import { awaitSyncWrapper, createMMKVBackend, createStorage, purgeStorage, wrapSync } from "@lib/storage";
import { allSettled } from "@lib/polyfills";
import logger, { logModule } from "@lib/logger";
import settings from "@lib/settings";
import { Author } from "./types";
import { awaitSyncWrapper, createMMKVBackend, createStorage, purgeStorage, wrapSync } from "@/lib/api/storage";
import logger, { logModule } from "@lib/utils/logger";
import { settings } from "@lib/settings";
import { Author } from "../utils/types";
import { allSettled } from "@/core/polyfills";
type EvaledPlugin = {
onLoad?(): void;

View file

@ -2,12 +2,12 @@
import { ReactNative as RN, chroma } from "@metro/common";
import { findInReactTree, safeFetch } from "@lib/utils";
import { find, findByName, findByProps, findByStoreName } from "@metro/filters";
import { after, before, instead } from "@lib/patcher";
import { createFileBackend, createMMKVBackend, createStorage, wrapSync, awaitSyncWrapper } from "@lib/storage";
import logger from "@lib/logger";
import { ThemeManager } from "@lib/native/modules";
import { getStoredTheme, getThemeFilePath } from "./loader";
import { Author } from "./types";
import { after, before, instead } from "@lib/api/patcher";
import { createFileBackend, createMMKVBackend, createStorage, wrapSync, awaitSyncWrapper } from "@/lib/api/storage";
import logger from "@lib/utils/logger";
import { ThemeManager } from "@lib/api/native/modules";
import { getStoredTheme, getThemeFilePath } from "../api/native/loader";
import { Author } from "../utils/types";
export interface ThemeData {
name: string;

View file

@ -1,5 +1,5 @@
import { find, findByProps, findByStoreName } from "@metro/filters";
import { ReactNative as RN } from "@lib/preinit";
import { ReactNative as RN } from "@/core/preinit";
import type { StyleSheet } from "react-native";
export interface DiscordStyleSheet {
@ -60,13 +60,13 @@ export const FluxDispatcher = findByProps("_currentDispatchActionType");
// React
export const React = window.React as typeof import("react");
export { ReactNative } from "@lib/preinit";
export { ReactNative } from "@/core/preinit";
// Moment
export const moment = findByProps("isMoment") as typeof import("moment");
// chroma.js
export { chroma } from "@lib/preinit";
export { chroma } from "@/core/preinit";
// Lodash
export const lodash = findByProps("forEachRight") as typeof import("lodash");

View file

@ -1,4 +1,4 @@
import { instead } from "@lib/patcher";
import { instead } from "@lib/api/patcher";
type MetroModulesIndex = `${number}` | number;

3
src/lib/metro/index.ts Normal file
View file

@ -0,0 +1,3 @@
export * from "./filters";
export * as filters from "./filters";
export * as common from "./common";

View file

@ -1,5 +1,5 @@
import { createFileBackend, createMMKVBackend, createStorage, wrapSync } from "@lib/storage";
import { getLoaderConfigPath } from "./loader";
import { createFileBackend, createMMKVBackend, createStorage, wrapSync } from "@/lib/api/storage";
import { getLoaderConfigPath } from "./api/native/loader";
export interface Settings {
debuggerUrl: string;
@ -18,7 +18,7 @@ export interface LoaderConfig {
loadReactDevTools: boolean;
}
export default wrapSync(createStorage<Settings>(createMMKVBackend("VENDETTA_SETTINGS")));
export const settings = wrapSync(createStorage<Settings>(createMMKVBackend("VENDETTA_SETTINGS")));
export const loaderConfig = wrapSync(createStorage<LoaderConfig>(
createFileBackend(getLoaderConfigPath(), {

View file

@ -1,6 +1,6 @@
import { findByProps } from "@metro/filters";
import InputAlert, { InputAlertProps } from "@ui/components/InputAlert";
import { ButtonColors } from "@/lib/types";
import { ButtonColors } from "@/lib/utils/types";
const Alerts = findByProps("openLazy", "close");

View file

@ -1,5 +1,5 @@
import { constants } from "@metro/common";
import { color } from "@lib/themes";
import { color } from "@lib/managers/themes";
//! This module is only found on 165.0+, under the assumption that iOS 165.0 is the same as Android 165.0.
//* In 167.1, most if not all traces of the old color modules were removed.

View file

@ -1,6 +1,6 @@
import { findByProps } from "@lib/metro/filters";
import { ReactNative } from "@lib/preinit";
import { instead } from "@lib/patcher";
import { ReactNative } from "@/core/preinit";
import { instead } from "@lib/api/patcher";
const { ContextMenu: _ContextMenu } = findByProps("ContextMenu");
const { AccessibilityInfo } = ReactNative

View file

@ -1,4 +1,4 @@
import { Strings } from "@/lib/i18n";
import { Strings } from "@/core/i18n";
import { React, ReactNative as RN, stylesheet } from "@metro/common";
import { Forms, Button, Codeblock } from "@ui/components";

View file

@ -1,4 +1,4 @@
import { ButtonColors } from "@/lib/types";
import { ButtonColors } from "@/lib/utils/types";
import { findByProps } from "@metro/filters";
import { Forms, Alert } from "@ui/components";

View file

@ -1,8 +1,8 @@
import { ReactNative as RN } from "@metro/common";
import { findByProps } from "@metro/filters";
import ErrorBoundary from "@ui/components/ErrorBoundary";
import { getAssetIDByName } from "@ui/assets";
import { Strings } from "@/lib/i18n";
import { getAssetIDByName } from "@/lib/api/assets";
import { Strings } from "@/core/i18n";
const { TextInput } = findByProps("TableRow");

View file

@ -1,5 +1,5 @@
import { ReactNative as RN } from "@metro/common";
import { getAssetIDByName } from "@ui/assets";
import { getAssetIDByName } from "@/lib/api/assets";
import { findByProps } from "@/lib/metro/filters";
const { FormRow } = findByProps("FormRow");

5
src/lib/ui/index.ts Normal file
View file

@ -0,0 +1,5 @@
export * as alerts from "./alerts";
export * as color from "./color";
export * as toasts from "./toasts";
export * as settings from "./settings";
export * as components from "./components";

View file

@ -1,14 +1,14 @@
import { findByName, findByProps } from "@metro/filters";
import { DISCORD_SERVER_ID, PLUGINS_CHANNEL_ID, THEMES_CHANNEL_ID, HTTP_REGEX_MULTI, PROXY_PREFIX } from "@lib/constants";
import { after } from "@lib/patcher";
import { installPlugin, plugins, removePlugin } from "@lib/plugins";
import { installTheme, removeTheme, themes } from "@lib/themes";
import { DISCORD_SERVER_ID, PLUGINS_CHANNEL_ID, THEMES_CHANNEL_ID, HTTP_REGEX_MULTI, PROXY_PREFIX } from "@lib/utils/constants";
import { after } from "@lib/api/patcher";
import { installPlugin, plugins, removePlugin } from "@lib/managers/plugins";
import { installTheme, removeTheme, themes } from "@lib/managers/themes";
import { findInReactTree } from "@lib/utils";
import { getAssetIDByName } from "@ui/assets";
import { getAssetIDByName } from "@/lib/api/assets";
import { showToast } from "@ui/toasts";
import { useProxy } from "@/lib/storage";
import { isThemeSupported } from "@/lib/loader";
import { Strings, formatStringSplit } from "@/lib/i18n";
import { useProxy } from "@/lib/api/storage";
import { isThemeSupported } from "@/lib/api/native/loader";
import { Strings, formatStringSplit } from "@/core/i18n";
type PostType = "Plugin" | "Theme";
@ -53,7 +53,7 @@ function useExtractThreadContent(thread: any, _firstMessage = null, actionSheet
let urls = firstMessage?.content?.match(HTTP_REGEX_MULTI)?.filter(postMap[postType].urlsFilter);
if (!urls || !urls[0]) return;
// Sync with lib/plugins
// Sync with lib/managers/plugins
if (postType === "Plugin" && !urls[0].endsWith("/")) urls[0] += "/";
return [postType, urls[0]];

View file

@ -1,14 +1,14 @@
import { findByProps, find } from "@metro/filters";
import { ReactNative as RN, channels, url } from "@metro/common";
import { PROXY_PREFIX, THEMES_CHANNEL_ID } from "@lib/constants";
import { after, instead } from "@lib/patcher";
import { installPlugin } from "@lib/plugins";
import { installTheme } from "@lib/themes";
import { PROXY_PREFIX, THEMES_CHANNEL_ID } from "@lib/utils/constants";
import { after, instead } from "@lib/api/patcher";
import { installPlugin } from "@lib/managers/plugins";
import { installTheme } from "@lib/managers/themes";
import { showConfirmationAlert } from "@ui/alerts";
import { getAssetIDByName } from "@ui/assets";
import { getAssetIDByName } from "@/lib/api/assets";
import { showToast } from "@ui/toasts";
import { isThemeSupported } from "@/lib/loader";
import { Strings, formatString, formatStringSplit } from "@lib/i18n";
import { isThemeSupported } from "@/lib/api/native/loader";
import { Strings, formatString, formatStringSplit } from "@/core/i18n";
const showSimpleActionSheet = find((m) => m?.showSimpleActionSheet && !Object.getOwnPropertyDescriptor(m, "showSimpleActionSheet")?.get);
const handleClick = findByProps("handleClick");

View file

@ -1,12 +1,12 @@
import { ReactNative as RN, stylesheet } from "@metro/common";
import { findByName, findByProps, findByStoreName } from "@metro/filters";
import { after } from "@lib/patcher";
import { after } from "@lib/api/patcher";
import { toggleSafeMode } from "@lib/debug";
import { DeviceManager } from "@lib/native/modules";
import { DeviceManager } from "@lib/api/native/modules";
import { semanticColors } from "@ui/color";
import { Button, Codeblock, ErrorBoundary as _ErrorBoundary, SafeAreaView } from "@ui/components";
import settings from "@lib/settings";
import { ButtonColors } from "@/lib/types";
import { settings } from "@lib/settings";
import { ButtonColors } from "@/lib/utils/types";
const ErrorBoundary = findByName("ErrorBoundary");

View file

@ -1,13 +1,13 @@
import { NavigationNative, ReactNative as RN, clipboard } from "@metro/common";
import { useProxy } from "@lib/storage";
import { useProxy } from "@/lib/api/storage";
import { HelpMessage, ErrorBoundary, Search } from "@ui/components";
import { CardWrapper } from "@ui/settings/components/Card";
import settings from "@lib/settings";
import { settings } from "@lib/settings";
import { findByProps } from "@/lib/metro/filters";
import { HTTP_REGEX_MULTI } from "@/lib/constants";
import { showInputAlert } from "@/ui/alerts";
import { getAssetIDByName } from "@/ui/assets";
import { Strings, formatString } from "@/lib/i18n";
import { HTTP_REGEX_MULTI } from "@/lib/utils/constants";
import { showInputAlert } from "@ui/alerts";
import { getAssetIDByName } from "@/lib/api/assets";
import { Strings, formatString } from "@/core/i18n";
interface AddonPageProps<T> {
title: string;

View file

@ -1,7 +1,7 @@
import { ReactNative as RN, clipboard } from "@metro/common";
import { showToast } from "@ui/toasts";
import { Forms } from "@ui/components";
import { Asset } from "@/ui/assets";
import { Asset } from "@/lib/api/assets";
interface AssetDisplayProps { asset: Asset }

View file

@ -1,7 +1,7 @@
import ContextMenu from "@/ui/components/ContextMenu";
import ContextMenu from "@ui/components/ContextMenu";
import { ReactNative as RN, stylesheet } from "@metro/common";
import { findByProps } from "@metro/filters";
import { getAssetIDByName } from "@ui/assets";
import { getAssetIDByName } from "@/lib/api/assets";
import { semanticColors } from "@ui/color";
const { TableRow, TableRowIcon, TableSwitchRow, TableCheckboxRow, TableRowGroup } = findByProps("TableRow");

View file

@ -1,9 +1,9 @@
import { ReactNative as RN, stylesheet, clipboard } from "@metro/common";
import { HTTP_REGEX_MULTI } from "@lib/constants";
import { HTTP_REGEX_MULTI } from "@lib/utils/constants";
import { showInputAlert } from "@ui/alerts";
import { getAssetIDByName } from "@ui/assets";
import { getAssetIDByName } from "@/lib/api/assets";
import { semanticColors } from "@ui/color";
import { Strings } from "@/lib/i18n";
import { Strings } from "@/core/i18n";
const styles = stylesheet.createThemedStyleSheet({
icon: {

View file

@ -1,13 +1,13 @@
import { NavigationNative, clipboard } from "@metro/common";
import { removePlugin, startPlugin, stopPlugin, getSettings, fetchPlugin, BunnyPlugin } from "@lib/plugins";
import { MMKVManager } from "@lib/native/modules";
import { getAssetIDByName } from "@ui/assets";
import { removePlugin, startPlugin, stopPlugin, getSettings, fetchPlugin, BunnyPlugin } from "@lib/managers/plugins";
import { MMKVManager } from "@lib/api/native/modules";
import { getAssetIDByName } from "@/lib/api/assets";
import { showToast } from "@ui/toasts";
import { showConfirmationAlert } from "@ui/alerts";
import Card, { CardWrapper } from "@ui/settings/components/Card";
import { useProxy } from "@/lib/storage";
import { ButtonColors } from "@/lib/types";
import { Strings, formatString } from "@/lib/i18n";
import { useProxy } from "@/lib/api/storage";
import { ButtonColors } from "@/lib/utils/types";
import { Strings, formatString } from "@/core/i18n";
async function stopThenStart(plugin: BunnyPlugin, callback: Function) {
if (plugin.enabled) stopPlugin(plugin.id, false);

View file

@ -1,10 +1,10 @@
import { NavigationNative } from "@metro/common";
import { useProxy } from "@lib/storage";
import { getAssetIDByName } from "@ui/assets";
import { useProxy } from "@/lib/api/storage";
import { getAssetIDByName } from "@/lib/api/assets";
import { getRenderableScreens } from "@ui/settings/data";
import { ErrorBoundary, Forms } from "@ui/components";
import settings from "@lib/settings";
import { Strings } from "@/lib/i18n";
import { settings } from "@lib/settings";
import { Strings } from "@/core/i18n";
const { FormRow, FormSection, FormDivider } = Forms;

View file

@ -1,14 +1,14 @@
import { clipboard } from "@metro/common";
import { Theme, applyTheme, fetchTheme, removeTheme, selectTheme, themes } from "@lib/themes";
import { useProxy } from "@lib/storage";
import { BundleUpdaterManager } from "@lib/native/modules";
import { getAssetIDByName } from "@ui/assets";
import { Theme, applyTheme, fetchTheme, removeTheme, selectTheme, themes } from "@lib/managers/themes";
import { useProxy } from "@/lib/api/storage";
import { BundleUpdaterManager } from "@lib/api/native/modules";
import { getAssetIDByName } from "@/lib/api/assets";
import { showConfirmationAlert } from "@ui/alerts";
import { showToast } from "@ui/toasts";
import settings from "@lib/settings";
import { settings } from "@lib/settings";
import Card, { CardWrapper } from "@ui/settings/components/Card";
import { ButtonColors } from "@/lib/types";
import { Strings, formatString } from "@/lib/i18n";
import { ButtonColors } from "@/lib/utils/types";
import { Strings, formatString } from "@/core/i18n";
async function selectAndApply(value: boolean, id: string) {
try {

View file

@ -1,5 +1,5 @@
import { clipboard } from "@metro/common";
import { getAssetIDByName } from "@ui/assets";
import { getAssetIDByName } from "@/lib/api/assets";
import { showToast } from "@ui/toasts";
import { Forms } from "@ui/components";
import { findByProps } from "@/lib/metro/filters";

View file

@ -1,22 +1,22 @@
import { ReactNative as RN, NavigationNative, stylesheet, lodash } from "@metro/common";
import { installPlugin } from "@lib/plugins";
import { installTheme } from "@lib/themes";
import { installPlugin } from "@lib/managers/plugins";
import { installTheme } from "@lib/managers/themes";
import { showConfirmationAlert } from "@ui/alerts";
import { semanticColors } from "@ui/color";
import { showToast } from "@ui/toasts";
import { without } from "@lib/utils";
import { getAssetIDByName } from "@ui/assets";
import settings from "@lib/settings";
import { getAssetIDByName } from "@/lib/api/assets";
import { settings } from "@lib/settings";
import ErrorBoundary from "@ui/components/ErrorBoundary";
import InstallButton from "@ui/settings/components/InstallButton";
import General from "@ui/settings/pages/General";
import Plugins from "@ui/settings/pages/Plugins";
import Themes from "@ui/settings/pages/Themes";
import Developer from "@ui/settings/pages/Developer";
import { PROXY_PREFIX } from "@/lib/constants";
import { PROXY_PREFIX } from "@/lib/utils/constants";
import { findByProps } from "@/lib/metro/filters";
import { isThemeSupported } from "@/lib/loader";
import { Strings } from "@/lib/i18n";
import { isThemeSupported } from "@/lib/api/native/loader";
import { Strings } from "@/core/i18n";
const { useSafeAreaInsets } = findByProps("useSafeAreaInsets");
@ -67,7 +67,7 @@ export const getScreens = (youKeys = false): Screen[] => [
onConfirm: () =>
installPlugin(input)
.then(() => showToast(Strings.TOASTS_INSTALLED_PLUGIN, getAssetIDByName("Check")))
.catch((x) => showToast(x?.message ?? `${x}`, getAssetIDByName("Small"))),
.catch((x: any) => showToast(x?.message ?? `${x}`, getAssetIDByName("Small"))),
cancelText: Strings.CANCEL,
}));
else return await installPlugin(input);

View file

@ -1,5 +1,5 @@
import { ReactNative as RN } from "@metro/common";
import { all } from "@ui/assets";
import { all } from "@/lib/api/assets";
import { Forms, Search, ErrorBoundary } from "@ui/components";
import AssetDisplay from "@ui/settings/components/AssetDisplay";

View file

@ -1,14 +1,14 @@
import { ReactNative as RN, NavigationNative, stylesheet } from "@metro/common";
import { findByProps } from "@metro/filters";
import { connectToDebugger } from "@lib/debug";
import { useProxy } from "@lib/storage";
import { getAssetIDByName } from "@ui/assets";
import { useProxy } from "@/lib/api/storage";
import { getAssetIDByName } from "@/lib/api/assets";
import { ErrorBoundary, Forms } from "@ui/components";
import settings, { loaderConfig } from "@lib/settings";
import { settings, loaderConfig } from "@lib/settings";
import AssetBrowser from "@ui/settings/pages/AssetBrowser";
import { semanticColors } from "@ui/color";
import { getReactDevToolsProp, getReactDevToolsVersion, isLoaderConfigSupported, isReactDevToolsPreloaded } from "@/lib/loader";
import { Strings } from "@/lib/i18n";
import { getReactDevToolsProp, getReactDevToolsVersion, isLoaderConfigSupported, isReactDevToolsPreloaded } from "@/lib/api/native/loader";
import { Strings } from "@/core/i18n";
const { Stack, TableRow, TableSwitchRow, TableRowGroup, TextInput } = findByProps("TableRow");
const { FormText } = Forms;

View file

@ -1,14 +1,14 @@
import { ReactNative as RN, stylesheet, url } from "@metro/common";
import { DISCORD_SERVER, GITHUB } from "@lib/constants";
import { DISCORD_SERVER, GITHUB } from "@lib/utils/constants";
import { getDebugInfo, toggleSafeMode } from "@lib/debug";
import { useProxy } from "@lib/storage";
import { getAssetIDByName } from "@ui/assets";
import { useProxy } from "@/lib/api/storage";
import { getAssetIDByName } from "@/lib/api/assets";
import { Summary } from "@ui/components";
import settings from "@lib/settings";
import { settings } from "@lib/settings";
import Version from "@ui/settings/components/Version";
import { findByProps } from "@lib/metro/filters";
import { semanticColors } from "@ui/color";
import { Strings } from "@/lib/i18n";
import { Strings } from "@/core/i18n";
const { Stack, TableRow, TableSwitchRow, TableRowGroup } = findByProps("TableRow");
const debugInfo = getDebugInfo() as any;

View file

@ -1,9 +1,9 @@
import { useProxy } from "@lib/storage";
import { BunnyPlugin, installPlugin, plugins } from "@lib/plugins";
import settings from "@lib/settings";
import { useProxy } from "@/lib/api/storage";
import { BunnyPlugin, installPlugin, plugins } from "@lib/managers/plugins";
import { settings } from "@lib/settings";
import AddonPage from "@ui/settings/components/AddonPage";
import PluginCard from "@ui/settings/components/PluginCard";
import { Strings } from "@/lib/i18n";
import { Strings } from "@/core/i18n";
export default function Plugins() {
useProxy(settings)

View file

@ -1,11 +1,11 @@
import { useProxy } from "@lib/storage";
import { Theme, installTheme, themes } from "@lib/themes";
import { useProxy } from "@/lib/api/storage";
import { Theme, installTheme, themes } from "@lib/managers/themes";
import { Button } from "@ui/components";
import settings from "@lib/settings";
import { settings } from "@lib/settings";
import AddonPage from "@ui/settings/components/AddonPage";
import ThemeCard from "@ui/settings/components/ThemeCard";
import { ButtonColors } from "@/lib/types";
import { Strings } from "@/lib/i18n";
import { ButtonColors } from "@/lib/utils/types";
import { Strings } from "@/core/i18n";
export default function Themes() {
useProxy(settings);

View file

@ -1,6 +1,6 @@
import { i18n } from "@metro/common";
import { findByName } from "@metro/filters";
import { after } from "@lib/patcher";
import { after } from "@lib/api/patcher";
import { findInReactTree } from "@lib/utils";
import { getPanelsScreens } from "@ui/settings/data";
import SettingsSection from "@ui/settings/components/SettingsSection";

View file

@ -1,8 +1,8 @@
import { findByProps } from "@metro/filters";
import { after, before } from "@lib/patcher";
import { after, before } from "@lib/api/patcher";
import { getRenderableScreens, getScreens, getYouData } from "@ui/settings/data";
import { i18n } from "@lib/metro/common";
import { Strings } from "@/lib/i18n";
import { Strings } from "@/core/i18n";
export default function patchYou() {
const patches = new Array<Function>;

View file

@ -1,6 +1,6 @@
import { findByProps } from "@metro/filters";
import { ReactNative, toasts } from "@metro/common";
import { getAssetIDByName } from "@ui/assets";
import { getAssetIDByName } from "@/lib/api/assets";
const { uuid4 } = findByProps("uuid4");

View file

@ -26,8 +26,7 @@ export interface Emitter {
emit: (event: EmitterEvent, data: EmitterListenerData) => void;
}
export default function createEmitter(): Emitter {
export function createEmitter(): Emitter {
return {
listeners: Object.values(Events).reduce<EmitterListeners>((acc, val: string) => ((acc[val] = new Set<EmitterListener>()), acc), {}) as EmitterListeners,

View file

@ -1,6 +1,6 @@
import { findInTree } from "@lib/utils";
import { SearchFilter } from "./findInTree";
export default (tree: { [key: string]: any }, filter: SearchFilter): any => findInTree(tree, filter, {
export const findInReactTree = (tree: { [key: string]: any }, filter: SearchFilter): any => findInTree(tree, filter, {
walkable: ["props", "children", "child", "sibling"],
});

View file

@ -40,7 +40,7 @@ function treeSearch(tree: SearchTree, filter: SearchFilter, opts: Required<FindI
}
}
export default (
export const findInTree = (
tree: SearchTree,
filter: SearchFilter,
{

View file

@ -1,7 +1,12 @@
// Makes mass-importing utils cleaner, chosen over moving utils to one file
export { default as findInReactTree } from "@lib/utils/findInReactTree";
export { default as findInTree } from "@lib/utils/findInTree";
export { default as safeFetch } from "@lib/utils/safeFetch";
export { default as unfreeze } from "@lib/utils/unfreeze";
export { default as without } from "@lib/utils/without";
export { findInReactTree } from "@lib/utils/findInReactTree";
export { findInTree } from "@lib/utils/findInTree";
export { safeFetch } from "@lib/utils/safeFetch";
export { unfreeze } from "@lib/utils/unfreeze";
export { without } from "@lib/utils/without";
export { createEmitter } from "@lib/utils/emitter";
export * as constants from "@lib/utils/constants";
export * as logger from "@lib/utils/logger";
export * as types from "@lib/utils/types";

View file

@ -1,6 +1,6 @@
// A really basic fetch wrapper which throws on non-ok response codes
export default async function safeFetch(input: RequestInfo | URL, options?: RequestInit, timeout = 10000) {
export async function safeFetch(input: RequestInfo | URL, options?: RequestInit, timeout = 10000) {
const req = await fetch(input, {
signal: timeoutSignal(timeout),
...options

View file

@ -1,6 +1,6 @@
// https://stackoverflow.com/a/68339174
export default function unfreeze(obj: object) {
export function unfreeze(obj: object) {
if (Object.isFrozen(obj)) return Object.assign({}, obj);
return obj;
}

View file

@ -1,4 +1,4 @@
export default function without<O extends object, K extends readonly (keyof O)[]>(object: O, ...keys: K): Omit<O, typeof keys[number]> {
export function without<O extends object, K extends readonly (keyof O)[]>(object: O, ...keys: K): Omit<O, typeof keys[number]> {
const cloned = { ...object };
keys.forEach((k) => delete cloned[k]);
return cloned;

View file

@ -1,59 +1,56 @@
import { createVendettaObject } from "./vendettaObject";
import * as constants from "@lib/constants";
import * as debug from "@lib/debug";
import * as native from "@lib/native";
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 { createVendettaObject } from "../core/vendettaObject";
import * as constants from "@lib/utils/constants";
import * as native from "@lib/api/native";
import * as plugins from "@lib/managers/plugins";
import * as themes from "@lib/managers/themes";
import * as commands from "@/lib/api/commands";
import * as storage from "@/lib/api/storage";
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 assets from "@/lib/api/assets";
import * as color from "@ui/color";
import logger from "./utils/logger";
import patcher from "./api/patcher";
import * as api from "@lib/api";
import * as managers from "@lib/api";
import * as metro from "@lib/metro";
import * as ui from "@lib/ui";
import * as utils from "@lib/utils";
import logger from "./logger";
import patcher from "./patcher";
import settings, { loaderConfig } from "./settings";
import * as debug from "@lib/debug";
import * as settings from "@lib/settings";
function createBunnyObject(unloads: any[]) {
return {
api: {
commands: { ...commands },
native: { ...native },
storage: { ...storage },
assets: { ...assets },
patcher: { ...patcher }
},
managers: { ...managers },
metro: { ...metro },
ui: { ...ui },
utils: { ...utils },
settings,
version: debug.versionHash,
unload: () => {
unloads.filter(i => typeof i === "function").forEach(p => p());
// @ts-expect-error
delete window.bunny;
},
}
}
const dest = { ...api };
type Y = typeof dest;
export type BunnyObject = ReturnType<typeof createBunnyObject>;
export default function initWindowObject(unloads: any[]) {
window.vendetta = createVendettaObject(unloads);
window.bunny = createBunnyObject(unloads);
}
function createBunnyObject(unloads: any[]) {
return {
patcher: utils.without(patcher, "unpatchAll"),
metro: { ...metro, common: { ...common } },
constants: { ...constants },
utils: { ...utils },
debug: utils.without({ ...debug }, "versionHash", "patchLogHook", "toggleSafeMode"),
ui: {
components: { ...components },
toasts: { ...toasts },
alerts: { ...alerts },
assets: { ...assets },
...color,
},
native: { ...native },
plugins: utils.without({ ...plugins }, "initPlugins", "evalPlugin"),
themes: utils.without({ ...themes }, "initThemes"),
commands: utils.without({ ...commands }, "patchCommands"),
storage: { ...storage },
settings: settings,
loader: {
identity: null,
config: loaderConfig,
},
logger: { ...logger },
version: debug.versionHash,
unload: () => {
unloads.filter(i => typeof i === "function").forEach(p => p());
delete window.vendetta;
},
}
}
export type BunnyObject = ReturnType<typeof createBunnyObject>;

View file

@ -19,7 +19,8 @@
"@*": ["src*"],
"@lib/*": ["src/lib/*"],
"@metro/*": ["src/lib/metro/*"],
"@ui/*": ["src/ui/*"],
"@ui/*": ["src/lib/ui/*"],
"@types": ["src/utils/types.ts"],
"bunny-build": ["src/modules.d.ts"]
},
"plugins": [