import type { AnyFunction, CommandOptions, ContextMenuTypes, GetButtonItem, GetContextItem, ObjectExports, RepluggedCommand } from "src/types";
import { type ContextMenuProps } from "../coremods/contextMenu";
/**
* Code to run before the original function
* @param args Arguments passed to the original function
* @param self The module the injected function is on
* @returns New arguments to pass to the original function, or undefined to leave them unchanged
*/
export type BeforeCallback = (args: A, self: I) => A | undefined | void;
/**
* Code to run instead of the original function
* @param args Arguments passed to the original function
* @param orig The original function
* @param self The module the injected function is on
* @returns New result to return
*/
export type InsteadCallback = (args: A, orig: (...args: A) => R, self: I) => R | void;
/**
* Code to run after the original function
* @param args Arguments passed to the original function
* @param res Result of the original function
* @param self The module the injected function is on
* @returns New result to return, or undefined to leave it unchanged
*/
export type AfterCallback = (args: A, res: R, self: I) => R | undefined | void;
/**
* Inject code into Discord's webpack modules.
*
* @example
* ```
* import { Injector, webpack } from "replugged";
*
* const injector = new Injector();
*
* export async function start() {
* const typingMod = (await webpack.waitForModule<{
* startTyping: (channelId: string) => void;
* }>(
* webpack.filters.byProps("startTyping")
* ));
*
* injector.after(typingMod, "startTyping", ([channel]) => {
* console.log(`Typing in channel ID ${channel}`);
* });
* }
*
* export function stop() {
* injector.uninjectAll();
* }
* ```
*/
export declare class Injector {
#private;
/**
* Run code before a native module
* @param obj Module to inject to
* @param funcName Function name on that module to inject
* @param cb Code to run
* @returns Uninject function
*/
before, U extends keyof T & string, A extends unknown[] = Parameters, I = ObjectExports>(obj: T, funcName: U, cb: BeforeCallback): () => void;
/**
* Run code instead of a native module
* @param obj Module to inject to
* @param funcName Function name on that module to inject
* @param cb Code to run
* @returns Uninject function
*/
instead, U extends keyof T & string, A extends unknown[] = Parameters, R = ReturnType, I = ObjectExports>(obj: T, funcName: U, cb: InsteadCallback): () => void;
/**
* Run code after a native module
* @param obj Module to inject to
* @param funcName Function name on that module to inject
* @param cb Code to run
* @returns Uninject function
*/
after, U extends keyof T & string, A extends unknown[] = Parameters, R = ReturnType, I = ObjectExports>(obj: T, funcName: U, cb: AfterCallback): () => void;
/**
* A few utils to add stuff in frequent modules.
*/
utils: {
/**
* A utility function to add a button to any message popover.
* @param item The function that creates the button to add
* @returns Uninject Function.
*
* @example
* ```
* import { Injector, webpack } from "replugged";
*
* const injector = new Injector();
*
* export function start() {
* injector.utils.addPopoverButton((msg: Message, channel: Channel) => {
* return {
* label: "Click the button!",
* icon: myVeryCoolIcon(), // Cool icon
* onClick: () => {
* // do stuff here when someone left clicks the button
* },
* onContextMenu: () => {
* // do other stuff here when someone right clicks the button
* },
* };
* });
* }
*
* export function stop() {
* injector.uninjectAll();
* }
* ```
*/
addPopoverButton: (item: GetButtonItem) => () => void;
/**
* A utility function to add an item to any context menu.
* By default, items are placed in a group for custom items, though that can be customized with `sectionId` and `indexInSection`
* @param navId The id of the menu to add to
* @param item The function that creates the item to add
* @param sectionId — The number of the section to add to. Defaults to Replugged's section
* @param indexInSection — The index in the section to add to. Defaults to the end position
* @returns A callback to de-register the function
*
* @example
* ```
* import { Injector, components, types } from "replugged";
* const { ContextMenu: { MenuItem } } = components;
* const { ContextMenuTypes } = types;
*
* const injector = new Injector();
*
* export function start() {
* injector.utils.addMenuItem(ContextMenuTypes.UserContext, // Right-clicking a user
* (data, menu) => {
* return