Strips internal functions from api types

This commit is contained in:
amsyarasyiq 2024-03-07 22:14:17 +08:00
parent 4ffebc8671
commit 186cd79f8b
13 changed files with 53 additions and 44 deletions

View file

@ -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": {

View file

@ -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={<TableRow.Icon source={getAssetIDByName("ic_privacy_24px")} />}
onPress={toggleSafeMode}
onPress={_toggleSafeMode}
/>
<TableSwitchRow
label={Strings.DEVELOPER_SETTINGS}

View file

@ -130,7 +130,7 @@ export const createVendettaObject = (unloads: any[]): any => ({
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;

View file

@ -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!");

View file

@ -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 };

View file

@ -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);
});

View file

@ -9,7 +9,7 @@ export const dispatcher = FluxDispatcher;
type Intercept = (payload: Record<string, any> & { 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);

View file

@ -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: {

View file

@ -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);

View file

@ -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();

View file

@ -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 }) },
];

View file

@ -2,6 +2,10 @@
export type StringUnion<T> = T | (string & {});
export type OptionalKeys<T extends Array<string>> = StringUnion<T[number]>;
export type ExcludeInternalProperties<T> = {
[K in keyof T as K extends `_${string}` ? never : K]: T[K] extends object ? ExcludeInternalProperties<T[K]> : T[K];
};
export interface Author {
name: string;
id?: string;

View file

@ -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<typeof _bunnyObject>;
export type BunnyObject = ExcludeInternalProperties<ReturnType<typeof _bunnyObject>>;
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: () => { },
});