From 186cd79f8bec6104e2af76ff020dd437c0f20c25 Mon Sep 17 00:00:00 2001 From: amsyarasyiq <82711525+amsyarasyiq@users.noreply.github.com> Date: Thu, 7 Mar 2024 22:14:17 +0800 Subject: [PATCH] Strips internal functions from api types --- packages/bunny-types/package.json | 2 +- src/core/ui/settings/pages/General.tsx | 4 ++-- src/core/vendettaObject.ts | 4 ++-- src/index.ts | 26 +++++++++++++------------- src/lib/api/assets.ts | 2 +- src/lib/api/commands/index.ts | 2 +- src/lib/api/flux/index.ts | 6 +++++- src/lib/debug.ts | 14 +++++++------- src/lib/managers/plugins.ts | 6 +++--- src/lib/managers/themes.ts | 10 +++++----- src/lib/ui/safeMode.tsx | 4 ++-- src/lib/utils/types.ts | 4 ++++ src/lib/windowObject.ts | 13 +++++++------ 13 files changed, 53 insertions(+), 44 deletions(-) diff --git a/packages/bunny-types/package.json b/packages/bunny-types/package.json index b81e139..b18caca 100644 --- a/packages/bunny-types/package.json +++ b/packages/bunny-types/package.json @@ -1,6 +1,6 @@ { "name": "bunny-types", - "version": "0.0.6", + "version": "0.0.7", "description": "Types for Bunny, a mod for Discord's mobile apps", "author": "pylixonly", "publishConfig": { diff --git a/src/core/ui/settings/pages/General.tsx b/src/core/ui/settings/pages/General.tsx index e7b2419..93e1b0a 100644 --- a/src/core/ui/settings/pages/General.tsx +++ b/src/core/ui/settings/pages/General.tsx @@ -2,7 +2,7 @@ import { Strings } from "@core/i18n"; import Version from "@core/ui/components/Version"; import { getAssetIDByName } from "@lib/api/assets"; import { useProxy } from "@lib/api/storage"; -import { getDebugInfo, toggleSafeMode } from "@lib/debug"; +import { getDebugInfo, _toggleSafeMode } from "@lib/debug"; import { settings } from "@lib/settings"; import { Stack, TableRow, TableRowGroup, TableSwitchRow } from "@lib/ui/components/discord/Redesign"; import { DISCORD_SERVER, GITHUB } from "@lib/utils/constants"; @@ -118,7 +118,7 @@ export default function General() { label={settings.safeMode?.enabled ? Strings.RELOAD_IN_NORMAL_MODE : Strings.RELOAD_IN_SAFE_MODE} subLabel={settings.safeMode?.enabled ? Strings.RELOAD_IN_NORMAL_MODE_DESC : Strings.RELOAD_IN_SAFE_MODE_DESC} icon={} - onPress={toggleSafeMode} + onPress={_toggleSafeMode} /> ({ installTheme: (id: string) => themes.installTheme(id), selectTheme: (id: string) => themes.selectTheme(id), removeTheme: (id: string) => themes.removeTheme(id), - getCurrentTheme: () => themes.getThemeFromLoader(), + getCurrentTheme: () => themes._getThemeFromLoader(), updateThemes: () => themes.updateThemes() }, commands: { @@ -159,7 +159,7 @@ export const createVendettaObject = (unloads: any[]): any => ({ trace: (...message: any) => console.trace(...message), verbose: (...message: any) => console.log(...message) }, - version: debug.versionHash, + version: debug._versionHash, unload: () => { unloads.filter(i => typeof i === "function").forEach(p => p()); delete window.vendetta; diff --git a/src/index.ts b/src/index.ts index 3f7e740..fc368d8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,13 @@ import initFixes from "@core/fixes"; import { initCorePlugins } from "@core/plugins"; import initSettings from "@core/ui/settings"; -import { patchAssets } from "@lib/api/assets"; -import { patchCommands } from "@lib/api/commands"; -import { injectFluxInterceptor } from "@lib/api/flux"; +import { _patchAssets } from "@lib/api/assets"; +import { _patchCommands } from "@lib/api/commands"; +import { _injectFluxInterceptor } from "@lib/api/flux"; import { isThemeSupported } from "@lib/api/native/loader"; -import { patchLogHook } from "@lib/debug"; -import { initPlugins } from "@lib/managers/plugins"; -import { initThemes, patchChatBackground } from "@lib/managers/themes"; +import { _patchLogHook } from "@lib/debug"; +import { _initPlugins } from "@lib/managers/plugins"; +import { _initThemes, _patchChatBackground } from "@lib/managers/themes"; import { logger } from "@lib/utils/logger"; import initWindowObject from "@lib/windowObject"; import initSafeMode from "@ui/safeMode"; @@ -16,7 +16,7 @@ export default async () => { // Themes if (isThemeSupported()) { try { - initThemes(); + _initThemes(); } catch (e) { console.error("[Bunny] Failed to initialize themes...", e); } @@ -24,11 +24,11 @@ export default async () => { // Load everything in parallel const unloads = await Promise.all([ - injectFluxInterceptor(), - patchLogHook(), - patchAssets(), - patchCommands(), - patchChatBackground(), + _injectFluxInterceptor(), + _patchLogHook(), + _patchAssets(), + _patchCommands(), + _patchChatBackground(), initFixes(), initSafeMode(), initSettings(), @@ -39,7 +39,7 @@ export default async () => { initWindowObject(unloads); // Once done, load plugins - unloads.push(await initPlugins()); + unloads.push(await _initPlugins()); // We good :) logger.log("Bunny is ready!"); diff --git a/src/lib/api/assets.ts b/src/lib/api/assets.ts index 656b2f6..9c86256 100644 --- a/src/lib/api/assets.ts +++ b/src/lib/api/assets.ts @@ -8,7 +8,7 @@ export interface Asset { id: number; } -export function patchAssets() { +export function _patchAssets() { const unpatch = after("registerAsset", assets, (args: Asset[], id: number) => { const asset = args[0]; all[asset.name] = { ...asset, id: id }; diff --git a/src/lib/api/commands/index.ts b/src/lib/api/commands/index.ts index 75a98aa..e52e9a9 100644 --- a/src/lib/api/commands/index.ts +++ b/src/lib/api/commands/index.ts @@ -4,7 +4,7 @@ import { commands as commandsModule } from "@metro/common"; let commands: ApplicationCommand[] = []; -export function patchCommands() { +export function _patchCommands() { const unpatch = after("getBuiltInCommands", commandsModule, ([type], res: ApplicationCommand[]) => { if (type === ApplicationCommandType.CHAT) return res.concat(commands); }); diff --git a/src/lib/api/flux/index.ts b/src/lib/api/flux/index.ts index ca59496..bf731a5 100644 --- a/src/lib/api/flux/index.ts +++ b/src/lib/api/flux/index.ts @@ -9,7 +9,7 @@ export const dispatcher = FluxDispatcher; type Intercept = (payload: Record & { type: string; }) => any; let intercepts: Intercept[] = []; -export function injectFluxInterceptor() { +export function _injectFluxInterceptor() { const cb = (payload: any) => { for (const intercept of intercepts) { const res = intercept(payload); @@ -33,6 +33,10 @@ export function injectFluxInterceptor() { return () => dispatcher._interceptors &&= dispatcher._interceptors.filter(v => v !== cb); } +/** + * Intercept Flux dispatches. Return type affects the end result, where + * nullish -> nothing, falsy -> block, object -> modify + */ export function intercept(cb: Intercept) { intercepts.push(cb); diff --git a/src/lib/debug.ts b/src/lib/debug.ts index 3284d40..b1c3da4 100644 --- a/src/lib/debug.ts +++ b/src/lib/debug.ts @@ -2,7 +2,7 @@ import { getAssetIDByName } from "@lib/api/assets"; import { getLoaderName, isThemeSupported } from "@lib/api/native/loader"; import { BundleUpdaterManager, ClientInfoManager, DeviceManager } from "@lib/api/native/modules"; import { after } from "@lib/api/patcher"; -import { getThemeFromLoader, selectTheme } from "@lib/managers/themes"; +import { _getThemeFromLoader, selectTheme } from "@lib/managers/themes"; import { settings } from "@lib/settings"; import { logger } from "@lib/utils/logger"; import { showToast } from "@ui/toasts"; @@ -28,10 +28,10 @@ export interface RNConstants extends PlatformConstants { systemName: string; } -export async function toggleSafeMode() { +export async function _toggleSafeMode() { settings.safeMode = { ...settings.safeMode, enabled: !settings.safeMode?.enabled }; if (isThemeSupported()) { - if (getThemeFromLoader()?.id) settings.safeMode!.currentThemeId = getThemeFromLoader()!.id; + if (_getThemeFromLoader()?.id) settings.safeMode!.currentThemeId = _getThemeFromLoader()!.id; if (settings.safeMode?.enabled) { await selectTheme("default"); } else if (settings.safeMode?.currentThemeId) { @@ -66,7 +66,7 @@ export function connectToDebugger(url: string) { }); } -export function patchLogHook() { +export function _patchLogHook() { const unpatch = after("nativeLoggingHook", globalThis, args => { if (socket?.readyState === WebSocket.OPEN) socket.send(JSON.stringify({ message: args[0], level: args[1] })); logger.log(args[0]); @@ -78,7 +78,7 @@ export function patchLogHook() { }; } -export const versionHash = version; +export const _versionHash = version; export function getDebugInfo() { // Hermes @@ -93,11 +93,11 @@ export function getDebugInfo() { return { /** @deprecated */ vendetta: { - version: versionHash, + version: _versionHash, loader: getLoaderName(), }, bunny: { - version: versionHash, + version: _versionHash, loader: getLoaderName(), }, discord: { diff --git a/src/lib/managers/plugins.ts b/src/lib/managers/plugins.ts index 3f8bb72..159caeb 100644 --- a/src/lib/managers/plugins.ts +++ b/src/lib/managers/plugins.ts @@ -74,7 +74,7 @@ export async function installPlugin(id: string, enabled = true) { if (enabled) await startPlugin(id); } -export async function evalPlugin(plugin: BunnyPlugin) { +export async function _evalPlugin(plugin: BunnyPlugin) { const vendettaForPlugins = { ...window.vendetta, plugin: { @@ -99,7 +99,7 @@ export async function startPlugin(id: string) { try { if (!settings.safeMode?.enabled) { - const pluginRet: EvaledPlugin = await evalPlugin(plugin); + const pluginRet: EvaledPlugin = await _evalPlugin(plugin); loadedPlugins[id] = pluginRet; pluginRet.onLoad?.(); } @@ -145,7 +145,7 @@ export async function removePlugin(id: string) { await purgeStorage(id); } -export async function initPlugins() { +export async function _initPlugins() { await awaitSyncWrapper(settings); await awaitSyncWrapper(plugins); const allIds = Object.keys(plugins); diff --git a/src/lib/managers/themes.ts b/src/lib/managers/themes.ts index 949d31e..83471c5 100644 --- a/src/lib/managers/themes.ts +++ b/src/lib/managers/themes.ts @@ -65,7 +65,7 @@ async function writeTheme(theme: Theme | {}) { await createFileBackend(getThemeFilePath() || "theme.json").set(theme); } -export function patchChatBackground() { +export function _patchChatBackground() { const MessagesWrapperConnected = findByName("MessagesWrapperConnected", false); if (!MessagesWrapperConnected) return; const { MessagesWrapper } = findByProps("MessagesWrapper"); @@ -195,13 +195,13 @@ export async function removeTheme(id: string) { return theme.selected; } -export function getThemeFromLoader(): Theme | null { +export function _getThemeFromLoader(): Theme | null { return getStoredTheme(); } export async function updateThemes() { await awaitSyncWrapper(themes); - const currentTheme = getThemeFromLoader(); + const currentTheme = _getThemeFromLoader(); await Promise.allSettled(Object.keys(themes).map(id => fetchTheme(id, currentTheme?.id === id))); } @@ -359,8 +359,8 @@ export function applyTheme(appliedTheme: Theme | null, fallbackTheme?: string, u } } -export async function initThemes() { - const currentTheme = getThemeFromLoader(); +export async function _initThemes() { + const currentTheme = _getThemeFromLoader(); enabled = !!currentTheme; patchColor(); diff --git a/src/lib/ui/safeMode.tsx b/src/lib/ui/safeMode.tsx index 46932fd..a43747e 100644 --- a/src/lib/ui/safeMode.tsx +++ b/src/lib/ui/safeMode.tsx @@ -1,6 +1,6 @@ import { DeviceManager } from "@lib/api/native/modules"; import { after } from "@lib/api/patcher"; -import { toggleSafeMode } from "@lib/debug"; +import { _toggleSafeMode } from "@lib/debug"; import { settings } from "@lib/settings"; import { ButtonColors } from "@lib/utils/types"; import { findByName, findByProps } from "@metro/filters"; @@ -77,7 +77,7 @@ export default () => after("render", ErrorBoundary.prototype, function (this: an // This is in the patch and not outside of it so that we can use `this`, e.g. for setting state const buttons: Button[] = [ { text: "Restart Discord", onPress: this.handleReload }, - ...!settings.safeMode?.enabled ? [{ text: "Restart in Safe Mode", onPress: toggleSafeMode }] : [], + ...!settings.safeMode?.enabled ? [{ text: "Restart in Safe Mode", onPress: _toggleSafeMode }] : [], { text: "Retry Render", color: ButtonColors.RED, onPress: () => this.setState({ info: null, error: null }) }, ]; diff --git a/src/lib/utils/types.ts b/src/lib/utils/types.ts index c36f02f..91321c3 100644 --- a/src/lib/utils/types.ts +++ b/src/lib/utils/types.ts @@ -2,6 +2,10 @@ export type StringUnion = T | (string & {}); export type OptionalKeys> = StringUnion; +export type ExcludeInternalProperties = { + [K in keyof T as K extends `_${string}` ? never : K]: T[K] extends object ? ExcludeInternalProperties : T[K]; +}; + export interface Author { name: string; id?: string; diff --git a/src/lib/windowObject.ts b/src/lib/windowObject.ts index f659193..3576515 100644 --- a/src/lib/windowObject.ts +++ b/src/lib/windowObject.ts @@ -7,6 +7,7 @@ import * as metro from "@lib/metro"; import * as settings from "@lib/settings"; import * as ui from "@lib/ui"; import * as utils from "@lib/utils"; +import { ExcludeInternalProperties } from "@lib/utils/types"; function createBunnyObject(unloads: any[]): BunnyObject { return { @@ -20,7 +21,7 @@ function createBunnyObject(unloads: any[]): BunnyObject { utils, settings, debug, - version: debug.versionHash, + version: debug._versionHash, unload: () => { unloads.filter(i => typeof i === "function").forEach(p => p()); // @ts-expect-error @@ -34,21 +35,21 @@ export default function initWindowObject(unloads: any[]) { window.bunny = createBunnyObject(unloads); } - /* (You may now worry about my mental state.) This is a hack, apparently when you destruct a star-imported module, its type is deferenced We need to do this for every module because the types bundler apparently does not support referencing star-imported modules(?) I only have realized this after getting everything set up, thinking it'd go well :) - The API should be the same even if we got alternatives in the future + The API should be the same (or easy to migrate) even if we got alternatives in the future + Another cons: JSDocs are stripped and a lot of declaration duplicates See: https://github.com/timocov/dts-bundle-generator/issues/304 */ -export type BunnyObject = ReturnType; +export type BunnyObject = ExcludeInternalProperties>; const _bunnyObject = () => ({ // this function is never used, only exists for typings api: { ...api, - flux: utils.without({ ...api.flux }, "injectFluxInterceptor"), + flux: { ...api.flux }, commands: { ...api.commands }, native: { ...api.native, @@ -101,6 +102,6 @@ const _bunnyObject = () => ({ // this function is never used, only exists for ty loaderConfig: { ...settings.loaderConfig } }, debug: { ...debug }, - version: debug.versionHash, + version: debug._versionHash, unload: () => { }, });