import { EventEmitter } from "node:events"; import { WebSocket } from "ws"; //#region src/types/Filters.d.ts declare enum AudioOutput { /** * Mono output (both channels mixed equally). * @type {string} */ Mono = "mono", /** * Stereo output (normal). * @type {string} */ Stereo = "stereo", /** * Left channel only output. * @type {string} */ Left = "left", /** * Right channel only output. * @type {string} */ Right = "right" } /** * The types of filters available. */ declare enum FilterType { /** * Volume filter. * @type {string} */ Volume = "volume", /** * Low pass filter. * @type {string} */ LowPass = "lowPass", /** * Karaoke filter. * @type {string} */ Karaoke = "karaoke", /** * Rotation filter. * @type {string} */ Rotation = "rotation", /** * Tremolo filter. * @type {string} */ Tremolo = "tremolo", /** * Vibrato filter. * @type {string} */ Vibrato = "vibrato", /** * Timescale filter. * @type {string} */ Timescale = "timescale", /** * Distortion filter. * @type {string} */ Distortion = "distortion", /** * Echo filter. * @type {string} */ Echo = "echo", /** * Reverb filter. * @type {string} */ Reverb = "reverb", /** * DSPX low-pass filter. * @type {string} */ DSPXLowpass = "low-pass", /** * DSPX high-pass filter. * @type {string} */ DSPXHighpass = "high-pass", /** * DSPX echo filter. Distinct canonical name from {@link FilterType.Echo} so the registry can tell them * apart; both are written to the wire as `echo` (DSPX flat under `pluginFilters`, the filter-plugin nested). * @type {string} */ DSPXEcho = "dspx-echo", /** * DSPX normalization filter. * @type {string} */ DSPXNormalization = "normalization", /** * Channel mix filter. * @type {string} */ ChannelMix = "channelMix", /** * Equalizer filter. * @type {string} */ Equalizer = "equalizer" } /** * Options for `FilterManager.set`, controlling where the payload is written and whether the node is * checked for support. * * | given | envelope | `validate` default | * | --- | --- | --- | * | nothing, registered filter | whatever the registry resolves | `true` | * | nothing, unknown filter | `pluginFilters[name]` (flat) | `false` | * | `plugin: true` | `pluginFilters[name]` (flat) | `false` | * | `plugin: "some-plugin"` | `pluginFilters["some-plugin"][name]` | `false` | * | `top: true` | `filters[name]` (top level) | `false` | * * Passing a routing option always wins over the registry, so an explicit envelope can be forced for a * registered name too. */ interface SetFilterOptions { /** * Write the filter under `pluginFilters`: `true` places it flat, a plugin name nests it under that * plugin (the shape the Lavalink spec defines for plugin filters). * @type {string | true | undefined} */ plugin?: string | true; /** * Write the filter at the top level of the payload, next to the built-in Lavalink filters — where a * fork exposes its own filters. * * Hoshimi does not check which server it is talking to: whether a fork-specific filter is safe to send * is the node's business, so pointing a player at the right node is the caller's. Registering the * filter (scope {@link FilterScope.Core}) buys routing by name and a check against the node's * advertised list, when the fork does advertise it. * @type {boolean | undefined} */ top?: boolean; /** * Whether to check that the node advertises the filter (and installs its backing plugin) before * writing. Only meaningful for registered filters — there is nothing to check an unknown key * against. See the table above for the defaults. * @type {boolean | undefined} */ validate?: boolean; } /** * The band settings for the equalizer. */ interface EQBandSettings { /** * The band number. * @type {number} */ band: number; /** * The gain for the band. * @type {number} */ gain: number; } /** * The settings for the karaoke filter. */ interface KaraokeSettings { /** * The level of the karaoke filter. * @type {number | undefined} */ level?: number; /** * The mono level of the karaoke filter. * @type {number | undefined} */ monoLevel?: number; /** * The filter band of the karaoke filter. * @type {number | undefined} */ filterBand?: number; /** * The filter width of the karaoke filter. * @type {number | undefined} */ filterWidth?: number; } /** * The settings for the timescale filter. */ interface TimescaleSettings { /** * The speed of the timescale filter. * @type {number | undefined} */ speed?: number; /** * The pitch of the timescale filter. * @type {number | undefined} */ pitch?: number; /** * The rate of the timescale filter. * @type {number | undefined} */ rate?: number; } /** * The settings for frequency-based filters. */ interface FreqSettings { /** * The frequency of the filter. * @type {number | undefined} */ frequency?: number; /** * The depth of the filter. * @type {number | undefined} */ depth?: number; } /** * The settings for the rotation filter. */ interface RotationSettings { /** * The rotation frequency in Hz. * @type {number | undefined} */ rotationHz?: number; } /** * The settings for the distortion filter. */ interface DistortionSettings { /** * The sine offset. * @type {number | undefined} */ sinOffset?: number; /** * The sine scale. * @type {number | undefined} */ sinScale?: number; /** * The cosine offset. * @type {number | undefined} */ cosOffset?: number; /** * The cosine scale. * @type {number | undefined} */ cosScale?: number; /** * The tangent offset. * @type {number | undefined} */ tanOffset?: number; /** * The tangent scale. * @type {number | undefined} */ tanScale?: number; /** * The offset. * @type {number | undefined} */ offset?: number; /** * The scale. * @type {number | undefined} */ scale?: number; } /** * The settings for the channel mix filter. */ interface ChannelMixSettings { /** * The left to left channel mix. * @type {number | undefined} */ leftToLeft?: number; /** * The left to right channel mix. * @type {number | undefined} */ leftToRight?: number; /** * The right to left channel mix. * @type {number | undefined} */ rightToLeft?: number; /** * The right to right channel mix. * @type {number | undefined} */ rightToRight?: number; } /** * The settings for the low pass filter. */ interface LowPassSettings { /** * The smoothing of the low pass filter. * @type {number | undefined} */ smoothing?: number; } interface TremoloSettings { /** * The frequency of the tremolo effect. * @type {number} */ frequency: number; /** * The depth of the tremolo effect. * @type {number} */ depth: number; } /** * Custom top-level filter settings for Hoshimi. * * Extend this interface via module augmentation to declare typed top-level filter keys * provided by a fork (e.g. Nodelink) or by code that integrates with Hoshimi. * * Runtime registration via {@link FilterRegistry} works without augmenting this interface; * augmentation only adds compile-time autocompletion and type-checking for the new keys. * * @example * ```ts * declare module "hoshimi" { * interface CustomizableFilterSettings { * "nodelink-echo"?: { decay: number; delay: number }; * } * } * ``` */ interface CustomizableFilterSettings {} /** * The options for the filters. */ interface FilterSettings extends CustomizableFilterSettings { /** * The volume of the filter. * @type {number | undefined} */ volume?: number; /** * The equalizer settings. * @type {EQBandSettings[] | undefined} */ equalizer?: EQBandSettings[]; /** * The karaoke settings. * @type {KaraokeSettings | null} */ karaoke?: KaraokeSettings | null; /** * The timescale settings. * @type {TimescaleSettings | null} */ timescale?: TimescaleSettings | null; /** * The tremolo settings. * @type {FreqSettings | null} */ tremolo?: FreqSettings | null; /** * The vibrato settings. * @type {FreqSettings | null} */ vibrato?: FreqSettings | null; /** * The rotation settings. * @type {RotationSettings | null} */ rotation?: RotationSettings | null; /** * The distortion settings. * @type {DistortionSettings | null} */ distortion?: DistortionSettings | null; /** * The channel mix settings. * @type {ChannelMixSettings | null} */ channelMix?: ChannelMixSettings | null; /** * The low pass settings. * @type {LowPassSettings | null} */ lowPass?: LowPassSettings | null; /** * The plugin filters. * @type {PluginFilterSettings | undefined} */ pluginFilters?: PluginFilterSettings; /** * Open index for vendor-scoped (fork) filters registered at runtime via {@link FilterRegistry}. * Declared keys above (and any key augmented through {@link CustomizableFilterSettings}) keep their precise types. */ [key: string]: unknown; } /** * Custom plugin filter payloads for Hoshimi. * * Extend this interface via module augmentation to declare typed plugin payload keys * (either nested under a plugin name, e.g. `"my-plugin"`, or flat filter keys * placed directly under `pluginFilters`). * * Runtime registration via {@link FilterRegistry} works without augmenting this interface; * augmentation only adds compile-time autocompletion and type-checking for the new keys. * * @example * ```ts * declare module "hoshimi" { * interface CustomizablePluginPayloads { * "my-fork-plugin"?: { gain?: number }; * } * } * ``` */ interface CustomizablePluginPayloads {} /** * The settings for plugin filters. */ interface PluginFilterSettings extends CustomizablePluginPayloads { /** * The normalization settings. * @type {NormalizationSettings | undefined} */ normalization?: NormalizationSettings; /** * The echo settings. * @type {EchoSettings | undefined} */ echo?: EchoSettings; /** * The high pass settings. * @type {FilterPluginPassSettings | undefined} */ "high-pass"?: Partial; /** * The low pass settings. * @type {FilterPluginPassSettings | undefined} */ "low-pass"?: Partial; /** * The settings for the lavalink filter plugin. * @type {LavalinkFilterPluginSettings | undefined} */ "lavalink-filter-plugin"?: LavalinkFilterPluginSettings; /** * Open index for plugin-scoped filter payloads registered at runtime via {@link FilterRegistry}. * Declared keys above (and any key augmented through {@link CustomizablePluginPayloads}) keep their precise types. */ [key: string]: unknown; } /** * The settings for the lavalink filter plugin. */ interface LavalinkFilterPluginSettings { /** * The echo filter settings. * @type {LavalinkFilterPluginEchoSettings | undefined} */ echo?: LavalinkFilterPluginEchoSettings; /** * The reverb filter settings. * @type {LavalinkFilterPluginReverbSettings | undefined} */ reverb?: LavalinkFilterPluginReverbSettings; } /** * The settings for the echo filter. */ interface EchoSettings { /** * The length of the echo. * @type {number | undefined} */ echoLength?: number; /** * The decay of the echo. * @type {number | undefined} */ decay?: number; /** * The delay of the echo. * @type {number | undefined} */ delay?: number; } /** * The settings for the normalization filter. */ interface NormalizationSettings { /** * The maximum amplitude for normalization. * @type {number} */ maxAmplitude?: number; /** * Whether to use adaptive normalization. * @type {boolean} */ adaptive?: boolean; } /** * The settings for the echo filter in plugins. */ interface LavalinkFilterPluginEchoSettings { /** * The delay for the echo filter. * @type {number} */ delay?: number; /** * The decay for the echo filter. * @type {number} */ decay?: number; } /** * The settings for the reverb filter in plugins. */ interface LavalinkFilterPluginReverbSettings { /** * The delays for the reverb filter. * @type {number[]} */ delays?: number[]; /** * The gains for the reverb filter. * @type {number[]} */ gains?: number[]; } interface FilterPluginPassSettings { /** * The cutoff frequency for the high pass filter. * @type {number} */ cutoffFrequency: number; /** * The boost factor for the high pass filter. * @type {number} */ boostFactor: number; } /** * The payload each built-in filter takes, used to type `FilterManager.set` and `FilterManager.get`. * * Keep an entry per {@link FilterType} member. A name missing from here (and from `CustomizableFilters`) * resolves to `unknown`, which is what lets unregistered filters be set with any payload. * * Note `Echo` and `DSPXEcho` differ: both are written to the wire as `echo`, but the * `lavalink-filter-plugin` one takes `{ delay, decay }` and the `lavadspx-plugin` one `{ echoLength, decay }`. */ interface FilterPayloads { [FilterType.Volume]: number; [FilterType.Equalizer]: EQBandSettings[]; [FilterType.Karaoke]: KaraokeSettings; [FilterType.Timescale]: TimescaleSettings; [FilterType.Tremolo]: FreqSettings; [FilterType.Vibrato]: FreqSettings; [FilterType.Rotation]: RotationSettings; [FilterType.Distortion]: DistortionSettings; [FilterType.ChannelMix]: ChannelMixSettings; [FilterType.LowPass]: LowPassSettings; [FilterType.Echo]: LavalinkFilterPluginEchoSettings; [FilterType.Reverb]: LavalinkFilterPluginReverbSettings; [FilterType.DSPXLowpass]: Partial; [FilterType.DSPXHighpass]: Partial; [FilterType.DSPXEcho]: EchoSettings; [FilterType.DSPXNormalization]: NormalizationSettings; } //#endregion //#region src/classes/storage/adapters/QueueAdapter.d.ts /** * Class representing a storage manager. * @abstract * @class QueueStorageAdapter * @example * ```ts * class MyStorageManager extends QueueStorageAdapter {}; * * const storage = new MyStorageManager(); * storage.set("key", "value"); * * const value = await storage.get("key"); * console.log(value); // "value" * ``` */ declare abstract class QueueStorageAdapter { /** * The namespace of the storage. * @type {string} * @default "hoshimiqueue" * @example * ```ts * console.log(storage.namespace); // "hoshimiqueue" * ``` */ namespace: string; /** * * Get the value using the key. * @param {string} key The key to get the value from. * @returns {Awaitable} The value of the key. * @example * ```ts * const value = await storage.get("key"); * console.log(value); // "value" * ``` */ abstract get(key: string): Awaitable; /** * * Set the value using the key. * @param {string} key The key to set the value to. * @param {unknown} value The value to set. * @returns {Awaitable} Did you know this can be async? * @example * ```ts * await storage.set("key", "value"); * ``` */ abstract set(key: string, value: T): Awaitable; /** * * Delete the value using the key. * @param {string} key The key to delete the value from. * @returns {Awaitable} Returns true if the key was deleted. * @example * ```ts * const success = await storage.delete("key"); * console.log(success); // true * ``` */ abstract delete(key: string): Awaitable; /** * Clear the storage. * @returns {Awaitable} Scary, right? * @example * ```ts * await storage.clear(); * ``` */ abstract clear(): Awaitable; /** * Check if the storage has the key. * @param {string} key The key to check. * @returns {Awaitable} Return true if the key exists. * @example * ```ts * const exists = await storage.has("key"); * console.log(exists); // true * ``` */ abstract has(key: string): Awaitable; /** * * Parse the value. * @param {unknown} value The value to parse. * @returns {T} The parsed value. * @example * ```ts * const parsed = await storage.parse("{'key':'value'}"); * console.log(parsed); // { key: "value" } * ``` */ abstract parse(value: unknown): Awaitable; /** * * Stringify the value. * @param {unknown} value The value to stringify. * @returns {R} The stringified value. * @example * ```ts * const stringified = await storage.stringify({ key: "value" }); * console.log(stringified); // "{'key':'value'}" * ``` */ abstract stringify(value: unknown): Awaitable; /** * * Build a key from the given parts. * @param {string[]} parts The parts to build the key from. * @returns {string} The built key. * @example * ```ts * const key = storage.buildKey("part1", "part2", "part3"); * ``` */ buildKey(...parts: RestOrArray): string; } //#endregion //#region src/classes/node/Lyrics.d.ts /** * Class representing a LyricsManager. * @class LyricsManager */ declare class LyricsManager { /** * The node instance. * @type {NodeStructure} * @readonly */ readonly node: NodeStructure; /** * Create a new LyricsManager instance. * @param {NodeStructure} node The node instance. * @example * ```ts * const node = manager.nodeManager.get("nodeId"); * const lyricsManager = new LyricsManager(node); * ``` */ constructor(node: NodeStructure); /** * * Get the current lyrics for the current track. * @param {string} guildId The guild id to get the current lyrics for. * @param {boolean} skipSource Whether to skip the track source or not. * @returns {Promise} The lyrics result or null if not found. * @example * ```ts * const node = manager.nodeManager.get("nodeId"); * const lyrics = await node.lyricsManager.current("guildId"); * ``` */ current(guildId: string, skipSource?: boolean): Promise; /** * * Get the lyrics for a specific track. * @param {TrackStructure} track The track to get the lyrics for. * @param {boolean} skipSource Whether to skip the track source or not. * @returns {Promise} The lyrics result or null if not found. * @example * ```ts * const node = manager.nodeManager.get("nodeId"); * const lyrics = await node.lyricsManager.get(track); * ``` */ get(track: TrackStructure, skipSource?: boolean): Promise; /** * * Subscribe to the lyrics for a specific guild. * @param {string} guildId The guild id to subscribe to. * @param {boolean} skipSource Whether to skip the track source or not. * @returns {Promise} Let's start the sing session! * @example * ```ts * const node = manager.nodeManager.get("nodeId"); * await node.lyricsManager.subscribe("guildId"); * ``` */ subscribe(guildId: string, skipSource?: boolean): Promise; /** * * Unsubscribe from the lyrics for a specific guild. * @param {string} guildId The guild id to unsubscribe from. * @returns {Promise} Let's stop the sing session! * @example * ```ts * const node = manager.nodeManager.get("nodeId"); * await node.lyricsManager.unsubscribe("guildId"); * ``` */ unsubscribe(guildId: string): Promise; } //#endregion //#region src/util/collection.d.ts /** * Represents a collection that extends the built-in Map class. * @template K The type of the keys in the collection. * @template V The type of the values in the collection. */ declare class Collection extends Map { /** * Removes elements from the collection based on a filter function. * @param fn The filter function that determines which elements to remove. * @returns The number of elements removed from the collection. * @example * const collection = new Collection(); * collection.set(1, 'one'); * collection.set(2, 'two'); * collection.set(3, 'three'); * const removedCount = collection.sweep((value, key) => key % 2 === 0); * console.log(removedCount); // Output: 1 * console.log(collection.size); // Output: 2 */ sweep(fn: (value: V, key: K, collection: this) => unknown): number; /** * Creates a new array with the results of calling a provided function on every element in the collection. * @param fn The function that produces an element of the new array. * @returns A new array with the results of calling the provided function on every element in the collection. * @example * const collection = new Collection(); * collection.set(1, 'one'); * collection.set(2, 'two'); * collection.set(3, 'three'); * const mappedArray = collection.map((value, key) => `${key}: ${value}`); * console.log(mappedArray); // Output: ['1: one', '2: two', '3: three'] */ map(fn: (value: V, key: K, collection: this) => T): T[]; /** * Creates a new array with all elements that pass the test implemented by the provided function. * @param fn The function to test each element of the collection. * @returns A new array with the elements that pass the test. * @example * const collection = new Collection(); * collection.set(1, 'one'); * collection.set(2, 'two'); * collection.set(3, 'three'); * const filteredArray = collection.filter((value, key) => key % 2 === 0); * console.log(filteredArray); // Output: ['two'] */ filter(fn: (value: V, key: K, collection: this) => boolean): V[]; /** * Tests whether at least one element in the collection passes the test implemented by the provided function. * @param fn The function to test each element of the collection. * @returns `true` if the callback returns truthy for any element, otherwise `false`. * @example * const collection = new Collection(); * collection.set(1, 'one'); * collection.set(2, 'two'); * collection.set(3, 'three'); * const hasEvenKey = collection.some((_, key) => key % 2 === 0); * console.log(hasEvenKey); // Output: true */ some(fn: (value: V, key: K, collection: this) => boolean): boolean; /** * Returns the value of the first element in the collection that satisfies the provided testing function. * @param fn The function to test each element of the collection. * @returns The value of the first element that passes the test. `undefined` if no element passes the test. * @example * const collection = new Collection(); * collection.set(1, 1); * collection.set(2, 2); * collection.set(3, 3); * const firstEvenValue = collection.find(value => value % 2 === 0); * console.log(firstEvenValue); // Output: 2 */ find(fn: (value: V, key: K, collection: this) => boolean): V | undefined; } //#endregion //#region src/util/emitter.d.ts /** * The shape an event map has to satisfy. * @description Written in terms of the map's own keys instead of an index signature: interfaces never get an implicit one, and requiring a `type` alias would cost module augmentation. */ type EventMap = Record; /** * The event names a map declares. * @description The intersection keeps the merged interface assignable to the inherited signature; a bare `keyof T` may include `number` and fails with TS2430. */ type EventKey = keyof T & (string | symbol); /** * The listener of a single event, taking the parameters from the map's tuple. */ type EventListener, K extends EventKey> = (...args: T[K]) => void; /** * The typed surface of the emitter. * @description Every method is listed on purpose: any left out keeps resolving to the inherited signature, which takes any name and gives the listener `any` arguments. */ interface TypedEmitter> { on>(event: K, listener: EventListener): this; once>(event: K, listener: EventListener): this; off>(event: K, listener: EventListener): this; addListener>(event: K, listener: EventListener): this; removeListener>(event: K, listener: EventListener): this; prependListener>(event: K, listener: EventListener): this; prependOnceListener>(event: K, listener: EventListener): this; removeAllListeners(event?: EventKey): this; emit>(event: K, ...args: T[K]): boolean; listeners>(event: K): EventListener[]; rawListeners>(event: K): EventListener[]; listenerCount>(event: K, listener?: EventListener): number; eventNames(): EventKey[]; getMaxListeners(): number; setMaxListeners(count: number): this; } /** * Class representing an event emitter described by a map, where an unknown event name is a compile error and a listener's parameters are inferred. * @description Node's emitter is the runtime, untouched: the class body is empty and the merged interface only describes it. The interface merges instead of the methods being `declare` fields, which would type them as properties and break a subclass overriding `on` with method syntax. * @abstract * @class TypedEmitter * @example * ```ts * interface MyEvents { * ready: [at: number]; * } * * class MyThing extends TypedEmitter {} * * const thing = new MyThing(); * * thing.on("ready", (at) => console.log(at)); // `at` is a number * thing.emit("ready", Date.now()); * ``` */ declare abstract class TypedEmitter> extends EventEmitter {} //#endregion //#region src/classes/Hoshimi.d.ts /** * The packet type for the manager. */ type GatewayPackets = VoicePacket | VoiceServer | VoiceState | ChannelDeletePacket; /** * Class representing the Hoshimi manager. * @class Hoshimi * @extends {TypedEmitter} * @example * ```ts * import { Hoshimi, SearchSources } from "hoshimi"; * * const manager = new Hoshimi({ // or via createHoshimi() function * sendPayload: async (guildId, payload) => { * const guild = await .guilds.fetch(guildId); * if (!guild) return; * * await guild.shard.send(payload); // Adjust this line based on your library's method to send payloads * }, * nodes: [ * { * host: "localhost", * port: 2333, * password: "youshallnotpass", * secure: false, * }, * ], * }); * * manager.on("nodeReady", (node) => console.log(`Node ${node.id} is ready.`)); * manager.on("playerCreate", (player) => console.log(`Player created for guild ${player.guildId}.`)); * manager.on("error", (error) => console.error("An error occurred:", error)); * * .on("ready", () => { * manager.init({ id: .user.id, username: .user.username }); * }); * * console.log(manager); // The manager instance * ``` */ declare class Hoshimi extends TypedEmitter { /** * The options for the manager. * @type {RequiredHoshimiOptions} */ options: RequiredHoshimiOptions; /** * The players for the manager. * @type {Collection} * @readonly */ readonly players: Collection; /** * THe node manager for the manager. * @type {NodeManager} * @readonly */ readonly nodeManager: NodeManagerStructure; /** * If the manager is ready. * @type {boolean} */ ready: boolean; /** * The constructor for the manager. * @param {HoshimiOptions} options The options for the manager. * @throws {ManagerError} If the options are not provided. * @throws {OptionError} If the options are invalid. * @example * ```ts * const manager = new Hoshimi({ * nodes: [ * { * host: "localhost", * port: 2333, * password: "youshallnotpass", * secure: false, * }, * ], * client: { * id: "clientId", * username: "clientUsername", * }, * defaultSearchSource: SearchSources.Youtube, * restOptions: { * resumeTimeout: 10000, * }, * nodeOptions: { * userAgent: HoshimiAgent, * sessionOptions: { * resumable: false, * byLibrary: false, * }, * }, * queueOptions: { * maxHistory: 25, * autoplayFn: autoplayFn, * autoPlay: false, * storage: new QueueMemoryStorage(), * }, * playerOptions: { * requesterFn: defaultRequesterFn, * onDisconnect: { * autoDestroy: false, * autoReconnect: false, * autoQueue: false, * }, * onError: { * autoDestroy: false, * autoStop: false, * }, * }, * }); * * console.log(manager); // The manager instance * ``` */ constructor(options: HoshimiOptions); /** * Check if the manager is usable. * @returns {boolean} If the manager is usable. * @example * ```ts * if (manager.isUsable()) { * console.log("The manager is usable."); * } else { * console.log("The manager is not usable."); * } * ``` */ isUsable(): boolean; /** * Check if the manager is usable. * @deprecated Use {@link Hoshimi.isUsable} instead. This misspelled alias will be removed in a future release. * @returns {boolean} If the manager is usable. */ isUseable(): boolean; /** * * Emit a debug event. * @param {DebugLevels} level The debug level. * @param {string} message The debug message. * @returns {void} * @example * ```ts * manager.debug(DebugLevels.Manager, "This is a debug message."); * ``` */ debug(level: DebugLevels, message: string): void; /** * * Get the player for the guild. * @param {string} guildId The guild id to get the player. * @returns {PlayerStructure | undefined} The player for the guild. * @example * ```ts * const player = manager.getPlayer(guildId); * if (player) { * console.log(`The player for ${guildId} is ${player}`); * } else { * console.log(`The player for ${guildId} is not found.`); * } * ``` */ getPlayer(guildId: string): PlayerStructure | undefined; /** * Delete the player for the guild. * @param {string} guildId The guild id to delete the player. * @returns {boolean} If the player was deleted. * @example * ```ts * const player = manager.deletePlayer(guildId); * if (player) { * console.log(`The player for ${guildId} was deleted.`); * } else { * console.log(`The player for ${guildId} was not found.`); * } * ``` */ deletePlayer(guildId: string): boolean; /** * * Handle the raw packet for voice state and voice server updates. * @param {GatewayPackets} packet The packet to handle * @returns {Promise} * @example * ```ts * client.on("raw", (packet) => manager.updateVoiceState(packet)); * ``` */ updateVoiceState(packet: GatewayPackets): Promise; /** * * Initialize the manager. * @param {ClientInfo} info The client data to use. * @returns {void} * @example * ```ts * manager.init({ * id: "clientId", * username: "clientUsername", * }); * ``` */ init(info: ClientInfo): void; /** * * Create a new player. * @param {PlayerOptions} options The options for the player. * @returns {Player} The created player. * @example * ```ts * const player = manager.createPlayer({ * guildId: "guildId", * voiceId: "voiceId", * }); * * console.log(player); // The created player * * player.connect(); * player.play(track); * ``` */ createPlayer(options: PlayerOptions): PlayerStructure; /** * * Search for a track or playlist. * @param {SearchOptions} options The options for the search. * @returns {Promise} The search result. * @example * ```ts * const result = await manager.search({ * query: "track name", * source: SearchSources.Youtube, * }); * * console.log(result); // The search result * ``` */ search(options: SearchOptions): Promise; } /** * Create a new Hoshimi instance. * @param {ConstructorParameters} args The arguments for the constructor. * @returns {Hoshimi} The new Hoshimi instance. */ declare function createHoshimi(...args: ConstructorParameters): Hoshimi; //#endregion //#region src/classes/node/Manager.d.ts /** * Class representing a node manager. * @class NodeManager */ declare class NodeManager { /** * The manager for the node. * @type {Hoshimi} * @readonly */ readonly manager: Hoshimi; /** * The nodes for the manager. * @type {Collection} * @readonly */ readonly nodes: Collection; /** * * The constructor for the node manager. * @param {Hoshimi} manager The manager for the node. * @example * ```ts * const manager = new Hoshimi(); * const nodeManager = new NodeManager(manager); * * console.log(nodeManager.nodes.size); // 0 * ``` */ constructor(manager: Hoshimi); /** * * Delete the node. * @param {NodeIdentifier} node The node or node id to delete. * @returns {boolean} If the node was deleted. * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) manager.nodeManager.delete(node.id); // true if the node was deleted * ``` */ delete(node: NodeIdentifier): boolean; /** * * Get the node by id. * @param {NodeIdentifier} node The node or node id to get. * @returns {NodeStructure | undefined} The node or undefined if not found. * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * console.log(node.id); // node1 * } else { * console.log("Node not found"); * } * ``` */ get(node: NodeIdentifier): NodeStructure | undefined; /** * * Create a new node. * @param {NodeOptions} options The options for the node. * @returns {NodeStructure} The created node. * @example * ```ts * const node = manager.nodeManager.create({ * host: "localhost", * port: 2333, * password: "password", * secure: false, * }); * * console.log(node.id); // localhost:2333 */ create(options: NodeOptions): NodeStructure; /** * * Destroy a node. * @param {NodeIdentifier} node The node or node id to destroy. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.destroy(); * ``` */ destroy(node: NodeIdentifier): void; /** * * Reconnect a node. * @param {NodeIdentifier} node The node or node id to reconnect. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.reconnect(); * ``` */ reconnect(node: NodeIdentifier): void; /** * * Disconnect a node. * @param {NodeIdentifier} node The node or node id to disconnect. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.disconnect(); * ``` */ disconnect(node: NodeIdentifier): void; /** * * Connect a node. * @param {NodeIdentifier} node The node or node id to connect. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.connect(); * ``` */ connect(node: NodeIdentifier): void; /** * * Get the least used node. * @returns {NodeStructure} The least used node. * @example * ```ts * const node = manager.nodeManager.getLeastUsed(); * if (node) { * console.log(node.id); // node1 * console.log(node.penalties); // the penalties of the node * console.log(node.state); // the state of the node * } * ``` */ getLeastUsed(sortType?: NodeSortFilter): NodeStructure; /** * * Reconnect the nodes. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.reconnectAll(); * ``` */ reconnectAll(): void; /** * Disconnect the nodes. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.disconnectAll(); * ``` */ disconnectAll(): void; /** * Connect the nodes. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.connect(); * ``` */ connectAll(): void; /** * Destroy the nodes. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.destroy(); * ``` */ destroyAll(): void; } //#endregion //#region src/classes/node/Node.d.ts /** * Class representing a Lavalink node. * @class Node */ declare class Node { /** * The options for the node. * @type {RequiredHoshimiNodeOptions} */ readonly options: RequiredHoshimiNodeOptions; /** * The REST for the node. * @type {RestStructure} */ readonly rest: RestStructure; /** * The manager for the node. * @type {NodeManagerStructure} */ readonly nodeManager: NodeManagerStructure; /** * The lyrics manager for the node. * @type {LyricsManagerStructure} */ readonly lyricsManager: LyricsManagerStructure; /** * The delay between reconnect attempts. * @type {number} */ readonly retryDelay: number; /** * The amount of reconnect attempts left. * @type {number} */ retryAmount: number; /** * The WebSocket for the node. * @type {WebSocket | null} */ ws: WebSocket | null; /** * The state of the node. * @type {State} */ state: State; /** * The session id of the node. */ sessionId: string | null; /** * The interval for the reconnect. * @type {NodeJS.Timeout | null} */ reconnectTimeout: NodeJS.Timeout | null; /** * The public stats of the node. * @type {Stats | null} */ stats: Stats | null; /** * The public info of the node. * @type {NodeInfo | null} */ info: NodeInfo | null; /** * Interval handle for the heartbeat ping. * @type {NodeJS.Timeout | null} */ heartbeatInterval: NodeJS.Timeout | null; /** * Whether the socket responded to the last ping. Set to false when a ping * is sent, back to true when a pong arrives. If still false at the next * ping, the socket is terminated. * @type {boolean} */ isAlive: boolean; /** * The session of the node. * @type {NullableLavalinkSession} */ session: NullableLavalinkSession; /** * * Create a new Lavalink node. * @param {NodeManagerStructure} nodeManager The manager for the node. * @param {NodeOptions} options The options for the node. * @example * ```ts * const node = new Node(nodeManager, { * host: "localhost", * port: 2333, * password: "youshallnotpass", * id: "node1", * secure: false, * retryAmount: 5, * retryDelay: 20000, * restTimeout: 10000, * sessionId: null, * }); * * node.connect(); * console.log(node.id); // node1 * console.log(node.address); // ws://localhost:2333/v4/websocket * console.log(node.penalties); // the penalties of the node * console.log(node.state); // the state of the node * ``` */ constructor(nodeManager: NodeManagerStructure, options: NodeOptions); /** * * Define a custom event handler for the node. * @param {unknown} payload The payload received from the node. * @returns {Awaitable} * @example * ```ts * class CustomNode extends Node { * public async message(payload: any): Promise { * console.log("Received payload:", payload); * } * } * ``` */ message?(payload: unknown): Awaitable; /** * The decode methods for the node. * @type {DecodeMethods} * @readonly */ readonly decode: DecodeMethods; /** * The id of the node. * @type {string} * @readonly * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * console.log(node.id); // node1 * } * ``` */ get id(): string; /** * * Check if the node is a Nodelink node. * @returns {boolean} True if the node is a Nodelink node, false otherwise. * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * if (node.isNodelink()) { * console.log("The node is a Nodelink node"); * } else { * console.log("The node is a Lavalink node"); * } * } * ``` */ isNodelink(): boolean; /** * The socket address to connect the node. * @type {string} * @readonly * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * console.log(node.id); // node1 * console.log(node.address); // ws://localhost:2333/v4/websocket * } * } */ get address(): string; /** * Check if the node is ready to receive events. * @type {boolean} * @readonly * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * if (node.ready) { * console.log("The node is ready"); * } else { * console.log("The node is not ready"); * } * } * ``` */ get ready(): boolean; /** * The penalties of the node. * @type {number} * @readonly * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * console.log(node.id); // node1 * console.log(node.address); // ws://localhost:2333/v4/websocket * console.log(node.penalties); // the penalties of the node * } * ``` */ get penalties(): number; /** * * Search for a query. * @param {SearchQuery} search The query to search for. * @returns {Promise} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * const search = await node.search({ * query: "https://www.youtube.com/watch?v=dQw4w9WgXcQ", * source: SearchSources.Youtube, * }); * * console.log(search); // the search result * } * ``` */ search(search: SearchQuery): Promise; /** * Connect the node to the websocket. * @returns {void} * @throws {NodeError} If the client data is not valid * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.connect(); * ``` */ connect(): void; /** * * Stop the track in player for the guild. * @param {string} guildId The guild id to stop the player. * @returns {Promise} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * const player = await node.stopPlayer("guildId"); * console.log(player); // the lavalink player * } * ``` */ stopPlayer(guildId: string): Promise; /** * * Update the player data. * @param {Partial} data The player data to update. * @returns {Promise} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * const player = await node.updatePlayer({ * guildId: "guildId", * noReplace: true, * playerOptions: { * paused: false, * track: { encoded: "encoded track" }, * }, * }); * * console.log(player); // the lavalink player * } * ``` */ updatePlayer(data: Partial): Promise; /** * Destroy the player. * @returns {Promise} * @param {string} guildId The guild id to destroy the player. * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) await node.destroyPlayer("guildId"); * console.log("Player destroyed"); * ``` */ destroyPlayer(guildId: string): Promise; /** * * Disconnect the node from the websocket. * @param {NodeDisconnectInfo} [disconnect] The disconnect options for the node. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.disconnect(); * console.log("Node disconnected"); * ``` */ disconnect(disconnect?: NodeDisconnectInfo): void; /** * * Destroy the node. * @param {NodeDestroyInfo} [destroy] The destroy options for the node. * @returns {void} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.destroy(); * console.log("Node destroyed"); * ``` */ destroy(destroy?: NodeDestroyInfo): void; /** * * Update the session for the node * @param {SessionResumingOptions} options The session resuming options. * @returns {Promise} * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * const session = await node.updateSession({ resuming: true, timeout: 30000 }); * console.log(session); // the lavalink session * } * ``` */ updateSession(options: SessionResumingOptions): Promise; /** * Reconnect the node. * @returns {void} * @throws {NodeError} If the node is not connected * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) node.reconnect(); * console.log("Node reconnected"); * ``` */ reconnect(): void; /** * * Convert the node to JSON. * @returns {NodeJSON} The JSON representation of the node. * @example * ```ts * const node = manager.nodeManager.get("node1"); * if (node) { * const json = node.toJSON(); * console.log(json); * } * ``` */ toJSON(): NodeJSON; } //#endregion //#region src/classes/node/Rest.d.ts /** * Class representing the REST for the node. * @class Rest */ declare class Rest { /** * The URL for the REST. * @type {string} */ readonly url: string; /** * The version for the REST. * @type {string} */ readonly version: string; /** * The timeout for the REST. * @type {number} */ readonly restTimeout: number; /** * The user agent for the REST. * @type {UserAgent} */ readonly userAgent: UserAgent; /** * The node for the REST. * @type {Node} */ readonly node: NodeStructure; /** * * Create a new REST. * @param {NodeStructure} node The node for the REST. * @example * ```ts * const node = new Node({ * host: "localhost", * port: 2333, * password: "youshallnotpass", * secure: false, * }); * * const rest = new Rest(node); * console.log(rest.restUrl); // http://localhost:2333/v4 * ``` */ constructor(node: NodeStructure); /** * The REST URL to make requests. * @type {string} */ get restUrl(): string; /** * The session id of the node. * @type {string | null} */ get sessionId(): string | null; /** * * Make a request to the node. * @param {RestOptions} options The options to make the request. * @returns {Promise} The response from the node. */ request(options: RestOptions): Promise; /** * * Update the player data. * @param {Partial} data The player data to update. * @returns {LavalinkPlayer | null} The updated player data. * @example * ```ts * const player = await node.rest.updatePlayer({ * guildId: "guildId", * noReplace: true, * playerOptions: { * paused: false, * track: { encoded: "encoded track" }, * }, * }); * * console.log(player); // The updated lavalink player data * ``` */ updatePlayer(data: Partial): Promise; /** * * Stop the track in player for the guild. * @param {string} guildId The guild id to stop the player. * @returns {Promise} The updated player data. * @example * ```ts * const player = await node.rest.stopPlayer("guildId"); * if (player) console.log(player); // The lavalink player * ``` */ stopPlayer(guildId: string): Promise; /** * * Destroy the player for the guild. * @param {string} guildId The guild id to destroy the player. * @returns {Promise} * @example * ```ts * await node.rest.destroyPlayer("guildId"); * ``` */ destroyPlayer(guildId: string): Promise; /** * * Update the session for the node * @param {SessionResumingOptions} options The session resuming options. * @returns {Promise} The updated session data. * @example * ```ts * const session = await node.rest.updateSession({ resuming: true, timeout: 30000 }); * if (session) console.log(session); // The lavalink session data * ``` */ updateSession(options: SessionResumingOptions): Promise; /** * * Get all players for the current session. * @returns {Promise} The players for the current session. * @example * ```ts * const players = await node.rest.getPlayers(); * console.log(players); // The lavalink players for the current session * ``` */ getPlayers(): Promise; } //#endregion //#region src/registry/PluginRegistry.d.ts /** * Built-in plugin capabilities recognized by Hoshimi. */ declare enum PluginCapabilities { /** * Lyrics retrieval — provided by lavalyrics-plugin, java-lyrics-plugin, or lavasrc-plugin. */ Lyrics = "lyrics", /** * DSPX filter set — provided by lavadspx-plugin. */ Dspx = "dspx", /** * Extended filter effects (echo, reverb, low/high-pass) — provided by lavalink-filter-plugin. */ Filters = "filters", /** * SponsorBlock segment lookup — provided by sponsorblock-plugin. */ SponsorBlock = "sponsorblock", /** * YouTube source provider — provided by youtube-plugin. */ Youtube = "youtube", /** * LavaSearch endpoints — provided by lavasearch-plugin. */ Search = "search", /** * Extra music sources (Spotify, Apple Music, Deezer, etc.) — provided by lavasrc-plugin, jiosaavn-plugin, and similar. */ ExtraSources = "extra-sources" } /** * Registration options for a plugin. */ interface PluginRegistration { /** * The capability the plugin provides. */ capability: RegistryCapability; /** * The plugin name as reported by Lavalink's /v4/info endpoint. */ name: RegistryPluginName; } /** * Options for validating that a node has the required plugin capabilities. */ interface ValidatePluginsOptions { /** * The node to validate the plugin capabilities for. * @type {Node} */ node: Node; /** * Array of capabilities that must all be present in the node. * @type {RegistryCapability[]} * @default [] */ required?: RegistryCapability[]; /** * Array of capabilities where at least one must be present in the node. * @type {RegistryCapability[]} * @default [] */ any?: RegistryCapability[]; } /** * Custom plugin capabilities for Hoshimi. * * Extend this interface via module augmentation to provide custom capabilities. * @example * ```ts * declare module "hoshimi" { * interface CustomizablePluginCapabilities { * karaoke: "karaoke"; * } * } * ``` */ interface CustomizablePluginCapabilities {} /** * Custom plugin names for Hoshimi. * * Extend this interface via module augmentation to provide custom plugin names with autocompletion. * @example * ```ts * declare module "hoshimi" { * interface CustomizablePluginNames { * myFork: "lavasrc-fork-plugin"; * } * } * ``` */ interface CustomizablePluginNames {} /** * The custom capability keys provided by users via module augmentation. */ type CapabilityKey = keyof CustomizablePluginCapabilities; /** * The custom plugin name keys provided by users via module augmentation. */ type PluginNameKey = keyof CustomizablePluginNames; /** * The full capability identifier accepted by the plugin registry. */ type RegistryCapability = PluginCapabilities | Hint; /** * The plugin name accepted by the plugin registry. */ type RegistryPluginName = PluginNames | Hint; /** * Object representing the plugin registry for Lavalink plugins. */ declare const PluginRegistry: { /** * Register one or multiple plugin definitions under their capabilities. * @param {RestOrArray} registrations The plugin registration payloads. * @returns {string[]} The canonical plugin names registered. * @example * ```ts * PluginRegistry.register({ * capability: PluginCapabilities.Lyrics, * name: "lavasrc-fork-plugin", * }); * * PluginRegistry.register( * { capability: PluginCapabilities.Lyrics, name: "lavasrc-fork-plugin" }, * { capability: PluginCapabilities.ExtraSources, name: "lavasrc-fork-plugin" }, * ); * ``` */ readonly register: (...registrations: RestOrArray) => string[]; /** * Unregister a plugin from a specific capability, or from all capabilities if none is provided. * @param {RegistryPluginName} name The plugin name to unregister. * @param {RegistryCapability} [capability] The capability to unregister the plugin from. * @returns {void} * @example * ```ts * // Drop only the Lyrics binding, keep ExtraSources * PluginRegistry.unregister("lavasrc-fork-plugin", PluginCapabilities.Lyrics); * * // Drop the plugin from every capability it was bound to * PluginRegistry.unregister("lavasrc-fork-plugin"); * ``` */ readonly unregister: (name: RegistryPluginName, capability?: RegistryCapability) => void; /** * Get the plugin names registered under a capability. * @param {RegistryCapability} capability The capability to look up. * @returns {string[]} The plugin names that provide the capability. */ readonly getPluginsFor: (capability: RegistryCapability) => string[]; /** * Get the capabilities provided by a plugin name. * @param {RegistryPluginName} name The plugin name to look up. * @returns {string[]} The capabilities provided by the plugin. */ readonly getCapabilitiesOf: (name: RegistryPluginName) => string[]; /** * Checks whether a list of installed plugins satisfies a capability. * @param {ReadonlyArray<{ name: string }>} installedPlugins The plugins reported by the node. * @param {RegistryCapability} capability The capability to check for. * @returns {boolean} Whether at least one installed plugin provides the capability. */ readonly hasCapability: (installedPlugins: ReadonlyArray<{ name: string; }>, capability: RegistryCapability) => boolean; /** * Returns all canonical registered capabilities. * @returns {string[]} All canonical capability identifiers. */ readonly getCapabilities: () => string[]; /** * Returns all canonical registered plugin names. * @returns {string[]} All canonical plugin names. */ readonly getPlugins: () => string[]; /** * Skip plugin validation, either globally or for specific capabilities. * @param {boolean | RegistryCapability | RegistryCapability[]} value `true` to skip every validation, or one/multiple capabilities to skip selectively. * @returns {void} * @example * ```ts * // Disable all plugin validation * PluginRegistry.skipValidation(true); * * // Skip a single capability * PluginRegistry.skipValidation(PluginCapabilities.Filters); * * // Skip multiple capabilities * PluginRegistry.skipValidation([PluginCapabilities.Lyrics, PluginCapabilities.Dspx]); * ``` */ readonly skipValidation: (value: boolean | RegistryCapability | RegistryCapability[]) => void; /** * Restore plugin validation. Without arguments restores all bypassed validations; with values, restores only the given capabilities. * @param {RegistryCapability | RegistryCapability[]} [value] The capability or capabilities whose validation should be restored. * @returns {void} * @example * ```ts * // Re-enable everything * PluginRegistry.restoreValidation(); * * // Re-enable a specific capability * PluginRegistry.restoreValidation(PluginCapabilities.Filters); * ``` */ readonly restoreValidation: (value?: RegistryCapability | RegistryCapability[]) => void; /** * Checks whether plugin validation is currently skipped, either globally or for a specific capability. * @param {RegistryCapability} [capability] The capability to check; if omitted, only the global flag is checked. * @returns {boolean} Whether validation is currently skipped. * @example * ```ts * // Check if all validation is skipped * PluginRegistry.isValidationSkipped(); * * // Check if a specific capability is skipped * PluginRegistry.isValidationSkipped(PluginCapabilities.Filters); * ``` */ readonly isValidationSkipped: (capability?: RegistryCapability) => boolean; /** * Validate that a node provides the required plugin capabilities. * @param {ValidatePluginsOptions} options The validation options. * @throws {NodeError} If the node is not ready, or if it does not satisfy the required/any capabilities. * @returns {void} * @example * ```ts * // Require all listed capabilities to be present * PluginRegistry.validate({ node, required: [PluginCapabilities.Filters] }); * * // Require at least one of multiple capabilities * PluginRegistry.validate({ node, any: [PluginCapabilities.Lyrics] }); * ``` */ readonly validate: (options: ValidatePluginsOptions) => void; /** * Clear the entire registry and reset all validation skips. Intended for tests. * @returns {void} */ readonly clear: () => void; }; //#endregion //#region src/registry/FiltersRegistry.d.ts /** * The scope where a filter lives in the wire payload. */ declare enum FilterScope { /** * Filter that lives at the top level of the `filters` payload: the Lavalink built-ins, and anything a * fork exposes alongside them. */ Core = "core", /** * Filter provided by a Lavalink plugin. Lives inside `filters.pluginFilters`. * When `pluginName` is set the filter is nested under `pluginFilters[pluginName][name]` (per Lavalink spec). * When `pluginName` is omitted the filter is placed flat at `pluginFilters[name]` (legacy convention used by lavadspx-plugin and similar). */ Plugin = "plugin" } /** * Custom filters for Hoshimi: the key is the filter name, the value is the payload it takes. * * Extend this interface via module augmentation to get autocompletion for the name and a checked payload * in `FilterManager.set` / `FilterManager.get`. Registering the filter is a separate, optional step that * buys envelope routing and node validation; this only adds types. * @example * ```ts * declare module "hoshimi" { * interface CustomizableFilters { * forkEcho: { decay: number; delay: number }; * } * } * * await player.filterManager.set("forkEcho", { decay: 0.5, delay: 200 }, { top: true }); * ``` */ interface CustomizableFilters {} /** * The custom filter name keys provided by users via module augmentation. */ type FilterNameKey = keyof CustomizableFilters; /** * The full filter name accepted by the filter registry. */ type RegistryFilterName = FilterType | Hint; /** * The payload a filter takes: whatever {@link CustomizableFilters} declares for it, else the built-in * shape from {@link FilterPayloads}, else `unknown` — so a filter nobody declared accepts any payload. */ type PayloadOf = K extends keyof CustomizableFilters ? CustomizableFilters[K] : K extends keyof FilterPayloads ? FilterPayloads[K] : unknown; /** * Registration options for a filter. */ interface FilterRegistration { /** * The canonical filter name. Used as the registry identity/index key. * Unless {@link FilterRegistration.wireName} is set, it is also the key written into the wire payload. */ name: RegistryFilterName; /** * The key actually written into the wire payload, when it differs from {@link FilterRegistration.name}. * * Needed when two distinct filters share the same wire key in different envelopes — e.g. the * `lavadspx-plugin` echo (`pluginFilters.echo`, flat) and the `lavalink-filter-plugin` echo * (`pluginFilters["lavalink-filter-plugin"].echo`, nested) both write `echo` but must be registered * under different canonical names so the registry can resolve each unambiguously. * @default name */ wireName?: string; /** * Where the filter lives in the payload envelope. */ scope: FilterScope; /** * The Lavalink plugin that owns this filter — relevant when `scope === FilterScope.Plugin`. * * When provided, the filter is nested under `pluginFilters[pluginName][name]` (Lavalink spec). * When omitted on a Plugin-scoped filter, the filter is placed flat at `pluginFilters[name]`. */ pluginName?: RegistryPluginName; /** * The plugin capability that backs this filter — used to validate via {@link PluginRegistry} at apply time. * Recommended whenever `scope === FilterScope.Plugin`. */ capability?: RegistryCapability; /** * Alternative names that should resolve to this same filter (e.g. fork renames sharing the same payload shape). * Aliases that collide with an already-registered canonical name are ignored to avoid hijacking. */ aliases?: string[]; } /** * The envelope coordinates of a filter: everything needed to place its payload on the wire. * * A {@link FilterRegistration} satisfies it, and so does a synthetic route built on the fly for a * filter that was never registered (see `FilterManager.set`). */ type FilterRoute = Pick; /** * Options for validating that a node can host a registered filter. */ interface ValidateFilterOptions { /** * The node to validate the filter for. */ node: Node; /** * The filter name (or alias) to validate. */ name: RegistryFilterName; } /** * Identity helper for a single filter registration. * * @deprecated Now a plain pass-through. It existed to preserve the inferred payload type of the * `isDefault` predicate inside a batch registration; predicates are gone (a filter is active by the * presence of its key), so registrations can be passed to {@link FilterRegistry.register} as-is. * @param {FilterRegistration} registration The registration to return unchanged. * @returns {FilterRegistration} The same registration. */ declare function defineFilter(registration: FilterRegistration): FilterRegistration; /** * Object representing the filter registry for Lavalink, Lavalink-plugin, and fork-provided filters. */ declare const FilterRegistry: { /** * Register one or multiple filter definitions. * * Registration is optional: `FilterManager.set` can write any filter, and only needs the registry to * route and validate the ones it knows. Register a filter to get envelope routing by name, node * validation, alias resolution and fork gating for free. * * @param {RestOrArray} registrations The registrations, as rest args or one array. * @returns {string[]} The canonical filter names that were registered (or already present). * @example * ```ts * FilterRegistry.register({ * name: "boost", * scope: FilterScope.Plugin, * pluginName: "my-fork-plugin", * capability: "fork-filters", * }); * * FilterRegistry.register([ * { name: "forkEcho", scope: FilterScope.Core }, * { name: "forkReverb", scope: FilterScope.Core }, * ]); * ``` */ readonly register: (...registrations: RestOrArray) => string[]; /** * Unregister a filter (and all of its entries) by name or alias. * @param {RegistryFilterName} name The filter name or alias to unregister. * @returns {boolean} Whether any entry was removed. */ readonly unregister: (name: RegistryFilterName) => boolean; /** * Resolve a filter name (or alias) to the best registration for a given node, taking scope and installed plugins into account. * @param {RegistryFilterName} name The filter name or alias. * @param {Node} node The node providing the context. * @returns {FilterRegistration | null} The chosen registration, or `null` when no candidate matches. */ readonly resolve: (name: RegistryFilterName, node: Node) => FilterRegistration | null; /** * Whether the given key is the name of a plugin that owns nested filters, i.e. whether * `pluginFilters[key]` is an envelope rather than a filter payload. * @param {string} key The candidate `pluginFilters` key. * @returns {boolean} Whether any registration nests its filters under this plugin name. */ readonly isPluginName: (key: string) => boolean; /** * Whether the registry knows a name at all, regardless of node context. Distinguishes "never * registered" from "registered but not resolvable on this node". * @param {RegistryFilterName} name The filter name (or alias). * @returns {boolean} Whether any registration exists under that name. */ readonly isKnown: (name: RegistryFilterName) => boolean; /** * Whether the node can host a flat plugin filter written under `pluginFilters[wireKey]`. * Resolves the flat plugin registration by wire key and checks the node advertises its backing * capability. Returns `true` when no flat registration matches the wire key (unknown key → left untouched). * @param {Node} node The node providing the context. * @param {string} wireKey The flat key under `pluginFilters`. * @returns {boolean} Whether the node can host the filter. */ readonly canHostFlatPlugin: (node: Node, wireKey: string) => boolean; /** * Returns all canonical filter names in registration order. * @returns {string[]} All canonical filter names. */ readonly getFilters: () => string[]; /** * Skip filter validation, either globally or for specific filters. * @param {boolean | RegistryFilterName | RegistryFilterName[]} value `true` to skip every validation, or one/multiple filter names to skip selectively. * @returns {void} */ readonly skipValidation: (value: boolean | RegistryFilterName | RegistryFilterName[]) => void; /** * Restore filter validation. Without arguments restores everything; with arguments restores only the given filters. * @param {RegistryFilterName | RegistryFilterName[]} [value] The filter(s) whose validation should be restored. * @returns {void} */ readonly restoreValidation: (value?: RegistryFilterName | RegistryFilterName[]) => void; /** * Whether filter validation is currently skipped, globally or for a given filter. * @param {RegistryFilterName} [name] The filter to check; omit to check only the global flag. * @returns {boolean} Whether validation is skipped. */ readonly isValidationSkipped: (name?: RegistryFilterName) => boolean; /** * Validate that a node supports the named filter. Throws on failure. * @param {ValidateFilterOptions} options The validation options. * @throws {NodeError} If the node is not ready, the filter is unknown for this node context, or the node does not advertise the filter / required plugin. * @returns {void} */ readonly validate: (options: ValidateFilterOptions) => void; /** * Clear the entire registry and reset every validation skip. Intended for tests. * @returns {void} */ readonly clear: () => void; }; //#endregion //#region src/classes/player/filters/DSPXPlugin.d.ts /** * Thin facade over the `lavadspx-plugin` filters. * * Each setter delegates to {@link FilterManager.set}; validation, envelope routing, * and node-capability checks are handled by the {@link FilterRegistry}. * * @class DSPXPluginFilter */ declare class DSPXPluginFilter { /** * The filter manager instance. * @type {FilterManagerStructure} * @readonly */ readonly manager: FilterManagerStructure; /** * Create a new DSPXPluginFilter instance. * @param {FilterManagerStructure} manager The filter manager instance. */ constructor(manager: FilterManagerStructure); /** * Set the DSPX low-pass filter (idempotent). * @example * ```ts * await player.filterManager.dspx.setLowPass({ cutoffFrequency: 500, boostFactor: 1.5 }); * await player.filterManager.clear(FilterType.DSPXLowpass); * ``` */ setLowPass(settings?: Partial): Promise; /** * Set the DSPX high-pass filter (idempotent). */ setHighPass(settings?: Partial): Promise; /** * Set the DSPX normalization filter (idempotent). */ setNormalization(settings?: Partial): Promise; /** * Set the DSPX echo filter (idempotent). */ setEcho(settings?: Partial): Promise; } //#endregion //#region src/classes/player/filters/LavalinkPlugin.d.ts type NonLengthEchoSettings = Omit$1; /** * Thin facade over the `lavalink-filter-plugin` filters. * * Each setter delegates to {@link FilterManager.set}; validation, envelope routing, * and node-capability checks are handled by the {@link FilterRegistry}. * * @class LavalinkPluginFilter */ declare class LavalinkPluginFilter { /** * The filter manager instance. * @type {FilterManagerStructure} * @private * @readonly */ private readonly manager; /** * Creates an instance of LavalinkPluginFilter. * @param {FilterManagerStructure} filters The filter manager instance. */ constructor(filters: FilterManagerStructure); /** * Set the echo filter (idempotent). * @param {Partial>} [settings=DefaultFilterPreset.PluginEcho] Echo settings. * @returns {Promise} The filter manager. * @example * ```ts * await player.filterManager.plugin.setEcho({ decay: 0.5, delay: 200 }); * // To turn off: * await player.filterManager.clear(FilterType.Echo); * ``` */ setEcho(settings?: Partial): Promise; /** * Set the reverb filter (idempotent). * @param {Partial} [settings=DefaultFilterPreset.PluginReverb] Reverb settings. * @returns {Promise} The filter manager. * @example * ```ts * await player.filterManager.plugin.setReverb({ delays: [50, 100], gains: [0.5, 0.3] }); * // To turn off: * await player.filterManager.clear(FilterType.Reverb); * ``` */ setReverb(settings?: Partial): Promise; } //#endregion //#region src/classes/player/filters/Manager.d.ts /** * Class representing a filter manager for a player. * * A filter is active when its key is present in the payload, and inactive when it is absent: there is * no neutral "off" payload. {@link FilterManager.set} writes a key, {@link FilterManager.clear} removes * it, and {@link FilterManager.isEnabled} is presence. * * {@link FilterRegistry} routes the filters it knows to their envelope (top level, flat `pluginFilters`, * or nested under a plugin) and validates them against the node. Filters it does not know can still be * set: their envelope comes from {@link SetFilterOptions} instead, so no registration is required. * * The commit/envelope internals live in {@link FilterPayload} (util/functions/filters), which takes the * manager as an argument rather than through `this` — no private members, matching the project convention. * * @class FilterManager */ declare class FilterManager { /** * The player this filter manager belongs to. * @type {PlayerStructure} * @public * @readonly */ readonly player: PlayerStructure; /** * The bands applied to the player. Kept in sync with `data.equalizer`. * @type {EQBandSettings[]} * @readonly */ readonly bands: EQBandSettings[]; /** * The current filter payload (wire-bound). Starts empty: a key is only present while its filter is * active. Mutated by {@link FilterManager.set} and {@link FilterManager.clear}. * @type {FilterSettings} * @public */ data: FilterSettings; /** * Thin facade for filters provided by the `lavalink-filter-plugin`. * @type {LavalinkPluginFilter} * @readonly */ readonly plugin: LavalinkPluginFilter; /** * Thin facade for filters provided by the `lavadspx-plugin`. * @type {DSPXPluginFilter} * @readonly */ readonly dspx: DSPXPluginFilter; /** * Creates a new filter manager. * @param {PlayerStructure} player The player this filter manager belongs to. */ constructor(player: PlayerStructure); /** * Set a filter to `payload` and commit. * * Any filter can be set, registered or not: {@link SetFilterOptions} decides the envelope when the * registry does not know the name (or when you want to override what it resolved). Idempotent — * calling repeatedly with the same payload yields the same wire state. * The payload is checked against {@link FilterPayloads} for the built-ins and against * {@link CustomizableFilters} for anything you declared; a name neither knows takes `unknown`. * @param {RegistryFilterName} name The filter name (or alias) to set. * @param {PayloadOf} payload The payload to write. * @param {SetFilterOptions} [options={}] Envelope and validation options. * @returns {Promise} A promise that resolves to the filter manager. * @throws {PlayerError} If `plugin` and `top` are combined, or if validation was requested for a * filter the node does not advertise. * @throws {NodeError} If a registered filter is not supported by the node (unless `validate: false`). * @example * ```ts * await player.filterManager.set(FilterType.Echo, { decay: 0.5, delay: 200 }); // registry routes it * await player.filterManager.set("myFilter", { gain: 2 }); // pluginFilters.myFilter * await player.filterManager.set("boost", { gain: 2 }, { plugin: "my-plugin" }); // nested * await player.filterManager.set("forkEcho", { decay: 0.5 }, { top: true }); // top level * ``` */ set(name: K, payload: PayloadOf, options?: SetFilterOptions): Promise; /** * Commit the current filter payload to the node. * @returns {Promise} A promise that resolves to the filter manager. */ apply(): Promise; /** * Set the given filter to `payload` and commit. * @deprecated Use {@link FilterManager.set} instead, which also takes {@link SetFilterOptions}. * @param {RegistryFilterName} name The canonical filter name (or alias) to set. * @param {PayloadOf} payload The payload to write into the envelope chosen by the registry. * @returns {Promise} A promise that resolves to the filter manager. */ apply(name: K, payload: PayloadOf): Promise; /** * Remove the given filter from the payload and commit. * * Pass the same {@link SetFilterOptions} routing used to set it, so an unregistered filter is cleared * from the envelope it was written to. * @param {RegistryFilterName} name The filter name (or alias) to clear. * @param {SetFilterOptions} [options={}] The routing options used when it was set. * @returns {Promise} A promise that resolves to the filter manager. * @example * ```ts * await player.filterManager.clear(FilterType.Karaoke); * await player.filterManager.clear("boost", { plugin: "my-plugin" }); * ``` */ clear(name: RegistryFilterName, options?: SetFilterOptions): Promise; /** * Read the payload a filter is currently set to. * * Typed the same way {@link FilterManager.set} is, so there is no need to reach into * {@link FilterManager.data} and narrow by hand. * @param {RegistryFilterName} name The filter name (or alias). * @param {SetFilterOptions} [options={}] The routing options used when it was set. * @returns {PayloadOf | undefined} The payload, or `undefined` when the filter is not active. * @example * ```ts * const timescale = player.filterManager.get(FilterType.Timescale); // TimescaleSettings | undefined * const boost = player.filterManager.get("boost", { plugin: "my-plugin" }); * ``` */ get(name: K, options?: SetFilterOptions): PayloadOf | undefined; /** * Whether the given filter is currently active, i.e. whether its key is present in the payload. * @param {RegistryFilterName} name The filter name (or alias). * @param {SetFilterOptions} [options={}] The routing options used when it was set. * @returns {boolean} True if the filter has a payload, false otherwise. */ isEnabled(name: RegistryFilterName, options?: SetFilterOptions): boolean; /** * Returns every active filter name as derived from the current payload. * * Only covers registered filters; keys written for unregistered ones are not listed. * @returns {string[]} Canonical filter names present in the payload. */ getEnabled(): string[]; /** * Backward-compatible alias for {@link isEnabled}. * @param {RegistryFilterName} filter The filter to check. * @param {SetFilterOptions} [options={}] The routing options used when it was set. * @returns {boolean} True if active. */ has(filter: RegistryFilterName, options?: SetFilterOptions): boolean; /** * Drop every filter and commit an empty payload. * @returns {Promise} A promise that resolves to the filter manager. */ reset(): Promise; /** * Serialise the current filter payload. * @returns {FilterSettings} A deep clone of the wire payload (a snapshot; mutating it never touches live state). */ toJSON(): FilterSettings; /** * Set the volume. * @param {number} volume Volume between 0 and 5. */ setVolume(volume: number): Promise; /** * Set one or more equalizer bands. Keeps `this.bands` and `data.equalizer` in sync. */ setEQBand(...bands: RestOrArray): Promise; /** * Clear every equalizer band. */ clearEQBands(): Promise; /** * Set the karaoke filter. */ setKaraoke(settings?: Partial): Promise; /** * Set the tremolo filter. */ setTremolo(settings?: Partial): Promise; /** * Set the vibrato filter. */ setVibrato(settings?: Partial): Promise; /** * Set the low-pass filter. */ setLowPass(settings?: Partial): Promise; /** * Set the distortion filter. */ setDistortion(settings?: Partial): Promise; /** * Set the timescale filter explicitly. */ setTimescale(settings: Partial): Promise; /** * Adjust timescale speed only. */ setSpeed(speed?: number): Promise; /** * Adjust timescale rate only. */ setRate(rate?: number): Promise; /** * Adjust timescale pitch only. */ setPitch(pitch?: number): Promise; /** * Apply the Nightcore preset to the timescale filter. */ setNightcore(settings?: Partial): Promise; /** * Apply the Vaporwave preset to the timescale filter. */ setVaporwave(settings?: Partial): Promise; /** * Whether the timescale currently matches the Nightcore preset exactly. */ isNightcore(): boolean; /** * Whether the timescale currently matches the Vaporwave preset exactly. */ isVaporwave(): boolean; /** * Set the audio output. Writes the matching channelMix preset. */ setAudioOutput(output: AudioOutput): Promise; /** * Whether the timescale represents any non-default playback rate that is neither Nightcore nor Vaporwave. */ isCustomTimescale(): boolean; /** * The current audio output mode, derived from `data.channelMix`. */ get audioOutput(): AudioOutput; } //#endregion //#region src/classes/storage/adapters/PlayerAdapter.d.ts /** * Type representing the customizable player storage. */ type StorageKeys = Hint; /** * Type representing the customizable player storage values. */ type StorageValues = V extends keyof CustomizablePlayerStorage ? CustomizablePlayerStorage[V] : unknown; /** * Class representing a player storage adapter. * @abstract * @class PlayerStorageAdapter * @example * ```ts * class MyPlayerStorageAdapter extends PlayerStorageAdapter {}; * * const storage = new MyPlayerStorageAdapter(); * await storage.set("key", "value"); * * const value = await storage.get("key"); * console.log(value); // "value" * ``` */ declare abstract class PlayerStorageAdapter { /** * The namespace of the storage. * @type {string} * @default "hoshimiplayer" * @example * ```ts * console.log(storage.namespace); // "hoshimiplayer" * ``` */ namespace: string; /** * the guild id of the player storage adapter. This is used to identify the player storage adapter. * @type {string} * @example * ```ts * console.log(storage.guildId); // "123456789012345678" * ``` */ readonly guildId: string; /** * * Create a new player storage adapter. * @param {string} guildId The guild id of the player storage adapter. * @example * ```ts * const storage = new MyPlayerStorageAdapter("123456789012345678"); * console.log(storage.guildId); // "123456789012345678" * ``` */ constructor(guildId: string); /** * Get the prefix for the storage keys. This is used to prevent key collisions between different player storage adapters. * @type {string} * @example * ```ts * console.log(storage.prefix); // "hoshimiplayer:123456789012345678" * * const key = storage.buildKey("key"); * console.log(key); // "hoshimiplayer:123456789012345678:key" * ``` */ get prefix(): string; /** * Strip the prefix from the key. This is used to get the original key from the stored key. * @param {string} key The key to strip the prefix from. * @returns {string} The original key without the prefix. * @example * ```ts * const key = storage.buildKey("key"); * console.log(key); // "hoshimiplayer:123456789012345678:key" * * const originalKey = storage.strip(key); * console.log(originalKey); // "key" * ``` */ strip(key: string): string; /** * Check if the key is an internal key. Internal keys are used to store internal data for the player storage adapter and should not be exposed to the user. * @param {string} key The key to check. * @returns {boolean} Return true if the key is an internal key. * @example * ```ts * const internalKey = "internal_key"; * console.log(storage.isInternal(internalKey)); // true * * const userKey = "user_key"; * console.log(storage.isInternal(userKey)); // false * ``` */ isInternal(key: string): boolean; /** * * Get the value using the key. * @param {string} key The key to get the value from. * @returns {Awaitable} The value of the key. * @example * ```ts * const value = await storage.get("key"); * console.log(value); // "value" * ``` */ abstract get>(key: K): Awaitable; /** * * Set the value using the key. * @param {string} key The key to set the value to. * @param {unknown} value The value to set. * @returns {Awaitable} Did you know this can be async? * @example * ```ts * await storage.set("key", "value"); * ``` */ abstract set>(key: K, value: V): Awaitable; /** * * Delete the value using the key. * @param {string} key The key to delete the value from. * @returns {Awaitable} Returns true if the key was deleted. * @example * ```ts * const success = await storage.delete("key"); * console.log(success); // true * ``` */ abstract delete(key: K): Awaitable; /** * Clear the storage. * @returns {Awaitable} Scary, right? * @example * ```ts * await storage.clear(); * ``` */ abstract clear(): Awaitable; /** * Check if the storage has the key. * @param {string} key The key to check. * @returns {Awaitable} Return true if the key exists. * @example * ```ts * const exists = await storage.has("key"); * console.log(exists); // true * ``` */ abstract has(key: K): Awaitable; /** * Get all keys in the storage. * @returns {Awaitable} The keys in the storage. * @example * ```ts * const keys = await storage.keys(); * console.log(keys); // ["key1", "key2"] * ``` */ abstract keys(): Awaitable; /** * Get all values in the storage. * @returns {Awaitable} The values in the storage. * @example * ```ts * const values = await storage.values(); * console.log(values); // ["value1", "value2"] * ``` */ abstract values>(): Awaitable; /** * Get all entries in the storage. * @returns {Awaitable<[K, V][]>} The entries in the storage. * @example * ```ts * const entries = await storage.entries(); * console.log(entries); // [["key1", "value1"], ["key2", "value2"]] * ``` */ abstract entries>(): Awaitable<[K, V][]>; /** * Get all key-value pairs in the storage. * @returns {Awaitable>} An object containing all key-value pairs in the storage, excluding internal keys. * @example * ```ts * const all = await storage.all(); * console.log(all); // { key1: "value1", key2: "value2" } * ``` */ abstract all>(): Awaitable>; /** * Get the size of the storage. * @returns {Awaitable} The size of the storage. * @example * ```ts * const size = await storage.size(); * console.log(size); // 2 * ``` */ abstract size(): Awaitable; /** * Destroy the storage. This is called when the player is destroyed. * @returns {Awaitable} Did you know this can be async? * @example * ```ts * await storage.destroy(); * ``` */ abstract destroy(): Awaitable; /** * * Set the value if the key does not exist in the storage. * @param {K} key The key to set the value to if it does not exist. * @param {V} value The value to set if the key does not exist. * @returns {Awaitable} Returns true if the value was set, false if the key already exists. * @example * ```ts * const success = await storage.setIfAbsent("key", "value"); * console.log(success); // true * * const success2 = await storage.setIfAbsent("key", "newValue"); * console.log(success2); // false * * const value = await storage.get("key"); * console.log(value); // "value" * ``` */ abstract setIfAbsent>(key: K, value: V): Awaitable; /** * * Build a key from the given parts. * @param {string[]} parts The parts to build the key from. * @returns {string} The built key. * @example * ```ts * const key = storage.buildKey("part1", "part2", "part3"); * ``` */ buildKey(...parts: RestOrArray): string; } //#endregion //#region src/classes/player/Voice.d.ts /** * A type representing a partial update to the player's voice state. */ type NullableVoiceChannelUpdate = Partial>; /** * A type representing a partial update to the player's voice data. */ type VoiceDataUpdate = Partial>; /** * Class representing the voice connection and state of a player. * @class PlayerVoiceState */ declare class PlayerVoiceState { /** * The voice server endpoint. * @type {string | null} */ endpoint: string | null; /** * The voice session id. * @type {string | null} */ sessionId: string | null; /** * The voice server token. * @type {string | null} */ token: string | null; /** * The voice channel id. * @type {string | null} */ channelId: string | null; /** * Reference to the player structure this voice instance belongs to. * @type {PlayerStructure} * @readonly */ readonly player: PlayerStructure; /** * * Create a new PlayerVoiceState instance for a player. * @param {PlayerStructure} player The player structure to attach this voice instance to. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * const voice = new PlayerVoiceState(player); * console.log(voice.channelId); * } * ``` */ constructor(player: PlayerStructure); /** * Merge voice data from Lavalink or gateway updates. * @param {VoiceDataUpdate} data The partial voice data to update with. * @returns {this} The current PlayerVoiceState instance after patching. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * player.voice.patch({ * sessionId: "session-id", * channelId: "voice-channel-id", * }); * } * ``` */ patch(data: VoiceDataUpdate): this; /** * Reset all voice connection values. * @returns {this} The current PlayerVoiceState instance. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * player.voice.reset(); * } * ``` */ reset(): this; /** * Return the current voice values as a nullable payload. * @returns {Nullable} The current voice data as a nullable LavalinkPlayerVoice payload. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * const voice = player.voice.toJSON(); * console.log(voice.endpoint); * } * ``` */ toJSON(): Nullable; /** * Return a valid Lavalink voice payload when all required fields are present. * @returns {LavalinkPlayerVoice | null} The Lavalink voice payload or null if required fields are missing. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * const voice = player.voice.toNode(); * if (!voice) console.log("Voice payload is incomplete"); * } * ``` */ toNode(): LavalinkPlayerVoice | null; /** * Send a voice state payload to the Discord gateway. * @param {NullableVoiceChannelUpdate} options The voice state options to update. Only include fields that need to be updated, others will be kept as is. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * await player.voice.setState({ * voiceId: "new-voice-channel-id", * selfMute: false, * }); * } * ``` */ setState(options?: NullableVoiceChannelUpdate): Promise; /** * Connect the player to its configured voice channel. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * await player.voice.connect(); * } * ``` */ connect(): Promise; /** * Disconnect the player from voice. * @returns {Promise} * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * await player.voice.disconnect(); * } * ``` */ disconnect(): Promise; /** * Move the player to another voice channel. * @param {string} voiceId The id of the voice channel to move to. * @returns {Promise} The player structure after moving. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * await player.voice.move("target-voice-channel-id"); * } * ``` */ move(voiceId: string): Promise; /** * Toggle or set self mute. * @param {boolean} selfMute Whether to self mute or not. Defaults to toggling the current state. * @returns {Promise} The player structure after updating mute state. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * await player.voice.mute(true); * } * ``` */ mute(selfMute?: boolean): Promise; /** * Toggle or set self deaf. * @param {boolean} selfDeaf Whether to self deafen or not. Defaults to toggling the current state. * @returns {Promise} The player structure after updating deafen state. * @example * ```ts * const player = manager.getPlayer("guildId"); * * if (player) { * await player.voice.deaf(true); * } * ``` */ deaf(selfDeaf?: boolean): Promise; } //#endregion //#region src/classes/player/Player.d.ts /** * Class representing a Hoshimi player. * @class Player */ declare class Player { /** * Promise of the destroying player. * @type {PromiseWithResolvers["promise"] | null} */ private destroyPromise; /** * The data for the player. * @type {PlayerStorageAdapter} * @readonly */ readonly data: PlayerStorageAdapter; /** * The options for the player. * @type {PlayerOptions} * @readonly */ readonly options: PlayerOptions; /** * The manager for the player. * @type {Hoshimi} * @readonly */ readonly manager: Hoshimi; /** * The queue for the player. * @type {Queue} * @readonly */ readonly queue: QueueStructure; /** * The filter manager for the player. * @type {FilterManager} * @readonly */ readonly filterManager: FilterManager; /** * The node for the player. * @type {NodeStructure} */ node: NodeStructure; /** * Check if the player is self deafened. * @type {boolean} */ selfDeaf: boolean; /** * Check if the player is self muted. * @type {boolean} */ selfMute: boolean; /** * Loop mode of the player. * @type {LoopMode} * @default LoopMode.Off */ loop: LoopMode; /** * Check if the player is playing. * @type {boolean} * @default false */ playing: boolean; /** * Check if the player is paused. * @type {boolean} * @default false */ paused: boolean; /** * Check if the player is connected. * @type {boolean} * @default false */ connected: boolean; /** * Check if the player is destroyed. * @type {boolean} */ get destroyed(): boolean; /** * Volume of the player. * @type {number} * @default 100 */ volume: number; /** * Guild id of the player. * @type {string} */ guildId: string; /** * Voice channel id of the player. * @type {string | undefined} */ voiceId: string | undefined; /** * Text channel id of the player. * @type {string | undefined} */ textId: string | undefined; /** * The ping of the player. * @type {number} */ ping: number; /** * The timestamp when the player was created. * @type {number} */ createdTimestamp: number; /** * The last position received from Lavalink. * @type {number} */ lastPosition: number; /** * The timestamp when the last position change update happened. * @type {number | null} */ lastPositionUpdate: number | null; /** * The current calculated position of the player. * @type {number} * @readonly */ get position(): number; /** * The voice connection details. * @type {PlayerVoiceStateStructure} */ readonly voice: PlayerVoiceStateStructure; /** * * Create a new player. * @param {Hoshimi} manager The manager for the player. * @param {PlayerOptions} options The options for the player. * @example * ```ts * const player = Structures.Player(manager, { * guildId: "guildId", * voiceId: "voiceId", * textId: "textId", * selfDeaf: true, * selfMute: false, * volume: 100, * }); * * console.log(player.guildId); // guildId * console.log(player.voiceId); // voiceId * console.log(player.textId); // textId */ constructor(manager: Hoshimi, options: PlayerOptions); /** * The lyrics methods for the player. * @type {LyricsMethods} * @readonly */ readonly lyrics: LyricsMethods; /** * * Check if the player is currently playing a track. * @returns {boolean} Whether the player is currently playing a track. */ isPlaying(): boolean; /** * * Search for a track or playlist. * @param {SearchOptions} options The options for the search. * @returns {Promise} The search result. * @example * ```ts * const player = manager.getPlayer("guildId"); * const result = await player.search({ * query: "track name", * source: SearchSource.Youtube, * requester: {}, * }); * * console.log(result) // the search result * ``` */ search(options: SearchOptions): Promise; /** * Connect the player to the voice channel. * @returns {Promise} The player instance. * @example * ```ts * const player = manager.getPlayer("guildId"); * player.connect(); * ``` */ connect(): Promise; /** * * Disconnect the player from the voice channel. * @returns {Promise} The player instance. * @example * ```ts * const player = manager.getPlayer("guildId"); * player.disconnect(); * ``` */ disconnect(): Promise; /** * * Play a track in the player. * @param {Partial} [options] The options to play the track. * @returns {Promise} * @throws {PlayerError} If there are no tracks to play. * @example * ```ts * const player = manager.getPlayer("guildId"); * * player.play({ * track: track, * noReplace: true, * }); * ``` */ play(options?: Partial): Promise; /** * Stop the player from playing. * @param {Partial} [options] The options for stopping the player. * @returns {Promise} * @example * ```ts * // Stop and destroy the player (default) * const player = manager.getPlayer("guildId"); * await player.stop(); * * // Stop without destroying, only clear queue * await player.stop({ destroy: false, clearQueue: true }); * * // Stop and leave voice channel * await player.stop({ destroy: false, leaveVoice: true }); * ``` */ stop(options?: Partial): Promise; /** * * Play the next track in the queue. * @param {SkipOptions} options The options for skipping tracks. * @returns {Promise} * @throws {PlayerError} If there are no tracks to skip. * @example * ```ts * const player = manager.getPlayer("guildId"); * player.skip({ to: 2 }); // skip 2 tracks * player.skip(); // skip 1 track * ``` */ skip(options?: SkipOptions): Promise; /** * * Seek to a specific position in the current track. * @param {number} position The position to seek to in milliseconds. * @returns {Promise} * @throws {PlayerError} If the position is invalid. * @example * ```ts * const player = manager.getPlayer("guildId"); * player.seek(30000); // seek to 30 seconds * ``` */ seek(position: number): Promise; /** * * Change the node the player is connected to. * @param {NodeIdentifier} node The node to change to. * @returns {Promise} A promise that resolves when the node has been changed. * @throws {PlayerError} If the target node is not found, not connected, or missing source managers. * @example * ```ts * const player = manager.getPlayer("guildId"); * player.move("newNodeId"); * ``` */ move(node: NodeIdentifier): Promise; /** * * Destroy and disconnect the player. * @param {DestroyOptions} options The options for destroying the player. * @returns {Promise} * @example * ```ts * const player = manager.getPlayer("guildId"); * player.destroy({ reason: DestroyReasons.Stop }); * ``` */ destroy(options?: DestroyOptions): Promise; /** * * Pause or resume the player. * @param {boolean} [paused=!this.paused] Whether to pause; defaults to toggling the current state. * @returns {Promise} The resulting paused state. * @example * ```ts * const player = manager.getPlayer("guildId"); * player.setPaused(); * ``` */ setPaused(paused?: boolean): Promise; /** * * Set the volume of the player. * @param {number} volume The volume to set. * @returns {Promise} * @example * ```ts * const player = manager.getPlayer("guildId"); * player.setVolume(50); // set the volume to 50% * ``` */ setVolume(volume: number): Promise; /** * * Set the loop mode of the player. * @param {LoopMode} mode The loop mode to set. * @returns {this} The player instance. * @throws {PlayerError} If the loop mode is invalid. * @example * ```ts * const player = manager.getPlayer("guildId"); * player.setLoop(LoopMode.Track); * ``` */ setLoop(mode: LoopMode): this; /** * Set the voice of the player. * @param {NullableVoiceChannelUpdate} options The voice state to set. * @returns {Promise} * @example * ```ts * const player = manager.getPlayer("guildId"); * player.setVoice({ voiceId: "newVoiceId" }); * ``` */ setVoice(options?: NullableVoiceChannelUpdate): Promise; /** * Update the player with new data. * @param {NonGuildUpdatePlayerInfo} data The data to update the player with. * @returns {Promise} The updated player data. * @example * ```ts * const player = manager.getPlayer("guildId"); * const updatedPlayer = await player.updatePlayer({ volume: 50 }); * console.log(updatedPlayer); // the updated player data * ``` */ updatePlayer(data: NonGuildUpdatePlayerInfo): Promise; /** * * Return the player as a json object. * @returns {PlayerJSON} * @example * ```ts * const player = manager.getPlayer("guildId"); * const json = player.toJSON(); * console.log(json); // the player as a json object * ``` */ toJSON(): PlayerJSON; } /** * Type representing the update player information without guildId. */ type NonGuildUpdatePlayerInfo = Omit; /** * Interface representing the customizable player storage. */ interface CustomizablePlayerStorage {} //#endregion //#region src/classes/queue/Utils.d.ts /** * Class representing the queue utils. * @class QueueUtils */ declare class QueueUtils { /** * * Constructor of the queue utils. * @param {QueueStructure} queue The queue instance. */ constructor(queue: QueueStructure); /** * Build a track from a resolvable structure. * Automatically resolves UnresolvedTrack instances to avoid double resolution. * @param {TrackResolvableStructure | AnyLavalinkTrack | null} [track] The input track. * @param {TrackRequester} [requester] Optional requester override. * @returns {Promise} The built and resolved track. */ build(track?: TrackResolvableStructure | AnyLavalinkTrack | null, requester?: TrackRequester): Promise; /** * * Save the queue to the storage. * @returns {Awaitable} * @example * ```ts * await player.queue.utils.save(); * ``` */ save(): Awaitable; /** * * Destroy the queue, removing all stored data. * @returns {Awaitable} Whether the stored queue entry was deleted. * @example * ```ts * await player.queue.utils.destroy(); * ``` */ destroy(): Awaitable; /** * * Sync the queue with the stored data. * @param {SyncOptions} [options={}] Sync options. * @returns {Promise} The promise for the sync operation. * @example * ```ts * await player.queue.utils.sync(); * ``` */ sync(options?: SyncOptions): Promise; } //#endregion //#region src/classes/queue/Queue.d.ts /** * Class representing a queue. * @class Queue */ declare class Queue { /** * Tracks of the queue. * @type {TrackResolvableStructure[]} */ tracks: TrackResolvableStructure[]; /** * Previous tracks of the queue. * @type {TrackStructure[]} */ history: TrackStructure[]; /** * Current track of the queue. * @type {TrackStructure | null} */ current: TrackStructure | null; /** * The player instance. * @type {PlayerStructure} */ readonly player: PlayerStructure; /** * The queue utils instance. * @type {QueueUtils} * @readonly */ readonly utils: QueueUtils; /** * * Constructor of the queue. * @param {PlayerStructure} player Player instance. * @example * ```ts * const queue = Structures.Queue(player); * * console.log(queue.size); // 0 * queue.add(track); * console.log(queue.size); // 1 * ``` */ constructor(player: PlayerStructure); /** * Get the track size of the queue. * @type {number} * @returns {number} The track size of the queue. * @readonly * @example * ```ts * const queue = player.queue; * * console.log(queue.size); // 0 * queue.add(track); * * console.log(queue.size); // 1 * queue.add([track1, track2]); * * console.log(queue.size); // 3 * queue.shift(); * console.log(queue.size); // 2 * * queue.clear(); * console.log(queue.size); // 0 * ``` */ get size(): number; /** * Get the total track size of the queue (Includes the current track). * @type {number} * @returns {number} The total track size of the queue. * @readonly * @example * ```ts * const queue = player.queue; * * console.log(queue.totalSize); // 0 * queue.add(track); * * console.log(queue.totalSize); // 1 * queue.add([track1, track2]); * * console.log(queue.totalSize); // 3 * queue.shift(); * console.log(queue.totalSize); // 2 * * queue.clear(); * console.log(queue.totalSize); // 0 * ``` */ get totalSize(): number; /** * * Check if the queue is empty. * @type {boolean} * @returns {boolean} True if the queue is empty. * @readonly * @example * ```ts * const queue = player.queue; * * console.log(queue.isEmpty()); // true * queue.add(track); * * console.log(queue.isEmpty()); // false * queue.clear(); * * console.log(queue.isEmpty()); // true * ``` */ isEmpty(): boolean; /** * * Get the previous track of the queue. * @param {boolean} [remove=false] Whether to remove the track from the previous queue. * @returns {Promise} The previous track of the queue. * @example * ```ts * const queue = player.queue; * * console.log(await queue.previous()); // null * queue.add(track); * queue.add(track2); * * console.log(await queue.previous()); // track * console.log(await queue.previous(true)); // track and remove it from the previous tracks * ``` */ previous(remove?: boolean): Promise; /** * * Add a track or tracks to the queue. * @param {TrackResolvableStructure | TrackResolvableStructure[]} track The track or tracks to add. * @param {number} [position] The position to add the track or tracks. * @returns {Promise} The queue instance. * @example * ```ts * const queue = player.queue; * * console.log(queue.size); // 0 * * await queue.add(track); * console.log(queue.size); // 1 * * await queue.add([track1, track2]); * console.log(queue.size); // 3 * * await queue.add(track3, 1); * console.log(queue.size); // 4 * console.log(queue.tracks); // [track1, track3, track2, track] * ``` */ add(track: TrackResolvableStructure | TrackResolvableStructure[], position?: number): Promise; /** * * Get the first track of the queue. * @returns {Promise} The first track of the queue. * @example * ```ts * const queue = player.queue; * * console.log(await queue.shift()); // null * await queue.add(track); * * console.log(await queue.shift()); // track * await queue.add(track2); * ``` */ shift(): Promise; /** * * Add tracks to the beginning of the queue. * @param {TrackResolvableStructure[]} tracks The tracks to add. * @returns {Promise} The queue instance. * @example * ```ts * const queue = player.queue; * * console.log(queue.size); // 0 * await queue.unshift(track); * * console.log(queue.size); // 1 * await queue.unshift(track1, track2); * * console.log(queue.size); // 3 * console.log(queue.tracks); // [track1, track2, track] * ``` */ unshift(...tracks: TrackResolvableStructure[]): Promise; /** * * Shuffle the queue. * @returns {Promise} The queue instance. * @example * ```ts * const queue = player.queue; * * console.log(queue.size); // 0 * await queue.add(track); * await queue.add(track1, track2); * * console.log(queue.size); // 3 * console.log(queue.tracks); // [track, track1, track2] * * await queue.shuffle(); * console.log(queue.tracks); // [track2, track, track1] * ``` */ shuffle(): Promise; /** * Clear the queue. * @description Empties the upcoming tracks and the history and drops the stored queue. The current * track and playback are left untouched. * @returns {Promise} The queue instance. * @example * ```ts * const queue = player.queue; * * await queue.add(track1, track2); * console.log(queue.size); // 2 * * await queue.clear(); * console.log(queue.size); // 0 * ``` */ clear(): Promise; /** * * Move a track to a specific position in the queue. * @param {TrackResolvableStructure} track The track to move. * @param {number} to The position to move. * @returns {Promise} The queue instance. * @example * ```ts * const queue = player.queue; * await queue.add(track); * await queue.add(track1); * await queue.add(track2); * * console.log(queue.tracks); // [track, track1, track2] * await queue.move(track1, 0); * console.log(queue.tracks); // [track1, track, track2] * ``` */ move(track: TrackResolvableStructure, to: number): Promise; /** * * Delete tracks from the queue. * @param {number} start The start index. * @param {number} deleteCount The number of tracks to delete. * @param {TrackResolvableStructure | TrackResolvableStructure[]} [tracks] The tracks to add. * @returns {Promise} The spliced tracks. * @example * ```ts * const queue = player.queue; * await queue.add(track); * await queue.add(track1); * await queue.add(track2); * * console.log(queue.tracks); // [track, track1, track2] * await queue.splice(1, 1); * console.log(queue.tracks); // [track, track2] * ``` */ splice(start: number, deleteCount: number, tracks?: TrackResolvableStructure | TrackResolvableStructure[]): Promise; /** * * Convert the queue to a JSON object. * @returns {QueueJSON} The queue JSON object. * @example * ```ts * const queue = player.queue; * await queue.add(track); * * console.log(queue.toJSON()); // { tracks: [{ ... }, { ... }], history: [], current: null } * ``` */ toJSON(): QueueJSON; } //#endregion //#region src/types/Structures.d.ts /** * The structure for the Player class. */ type PlayerStructure = InferCustomStructure; /** * The structure for the Rest class. */ type RestStructure = InferCustomStructure; /** * The structure for the Node class. */ type NodeStructure = InferCustomStructure; /** * The structure for the Queue class. */ type QueueStructure = InferCustomStructure; /** * The structure for the LyricsManager class. */ type LyricsManagerStructure = InferCustomStructure; /** * The structure for the NodeManager class. */ type NodeManagerStructure = InferCustomStructure; /** * The structure for the FilterManager class. */ type FilterManagerStructure = InferCustomStructure; /** * The structure for the Track class. */ type TrackStructure = InferCustomStructure; /** * The structure for the UnresolvedTrack class. */ type UnresolvedTrackStructure = InferCustomStructure; /** * The structure for the PlayerVoiceState class. */ type PlayerVoiceStateStructure = InferCustomStructure; /** * The structure for the PlayerStorageAdapter class. */ type PlayerStorageAdapterStructure = InferCustomStructure; /** * Factory signatures for all overridable structures. */ interface StructureFactories { Player(...args: ConstructorParameters): PlayerStructure; Rest(...args: ConstructorParameters): RestStructure; Node(...args: ConstructorParameters): NodeStructure; Queue(...args: ConstructorParameters): QueueStructure; LyricsManager(...args: ConstructorParameters): LyricsManagerStructure; NodeManager(...args: ConstructorParameters): NodeManagerStructure; FilterManager(...args: ConstructorParameters): FilterManagerStructure; Track(...args: ConstructorParameters): TrackStructure; UnresolvedTrack(...args: ConstructorParameters): UnresolvedTrackStructure; PlayerVoiceState(...args: ConstructorParameters): PlayerVoiceStateStructure; PlayerStorageAdapter(...args: ConstructorParameters): PlayerStorageAdapterStructure; } /** * The structures of the Hoshimi classes. */ declare const Structures: StructureFactories; /** * Infers the custom structure for a given class. */ type InferCustomStructure = N extends keyof CustomizableStructures ? CustomizableStructures[N] : T; //#endregion //#region src/types/Queue.d.ts /** * The queue options. */ interface HoshimiQueueOptions { /** * The maximum amount of tracks that can be saved in the queue. * @type {number} * @default 25 */ maxHistory?: number; /** * * The function to use for autoplay. * @param {Player} player The player. * @param {TrackResolvableStructure | null} lastTrack The last track played. */ autoplayFn?(player: PlayerStructure, lastTrack: TrackResolvableStructure | null): Awaitable; /** * Enable the auto play for the queue. (By default, only supports `youtube` and `spotify`, add more with your own function) * @type {boolean} * @default false */ autoPlay?: boolean; /** * The storage manager to use for the queue. * @type {QueueStorageAdapter} * @default {QueueMemoryStorage} */ storage?: QueueStorageAdapter; } /** * The sync options for the queue. */ interface SyncOptions { /** * Whether to override the current queue with the stored one. * @type {boolean} * @default true */ override?: boolean; /** * Whether to sync the current track. * @type {boolean} * @default false */ syncCurrent?: boolean; } /** * The type for any lavalink track, including partial and unresolved tracks. */ interface TrackJSON extends LavalinkTrack { requester: TrackRequester; } /** * The queue json. */ interface QueueJSON { /** * The tracks of the queue. * @type {TrackJSON[]} */ tracks: TrackJSON[]; /** * The previous tracks of the queue. * @type {TrackJSON[]} */ history: TrackJSON[]; /** * The current track of the queue. * @type {TrackJSON | null} */ current: TrackJSON | null; } //#endregion //#region src/types/Player.d.ts /** * Partial Lavalink track type. */ type PartialLavalinkTrack = Prettify>>; /** * The base options for playing a track. */ interface BasePlayOptions { /** * The position to start the track. * @type {number | undefined} */ position?: number; /** * The position to end the track. * @type {number | undefined} */ endTime?: number; /** * The pause state of the player. * @type {boolean | undefined} */ paused?: boolean; /** * The volume of the player. * @type {number | undefined} */ volume?: number; /** * The filters for the player. * @type {Partial | undefined} */ filters?: Partial; /** * The voice settings for the player. * @type {LavalinkPlayerVoice | undefined} */ voice?: LavalinkPlayerVoice; } /** * The types of loop modes. */ declare enum LoopMode { /** * Loop mode for repeating the current track. */ Track = 1, /** * Loop mode for repeating the queue. */ Queue = 2, /** * Loop mode for repeating nothing. */ Off = 3 } /** * The player subsystem a payload is being handled by, used as the second tag of a * `[Player] -> []` debug line. */ declare enum PlayerScope { /** * Scope for the track start handling. */ Start = "Start", /** * Scope for the track end handling. */ End = "End", /** * Scope for the stuck track handling. */ Stuck = "Stuck", /** * Scope for the track exception handling. */ Error = "Error", /** * Scope for the voice state and voice server handling. */ Voice = "Voice" } /** * The types of player events. */ declare enum PlayerEventType { /** * Event type for when a track starts. */ TrackStart = "TrackStartEvent", /** * Event type for when a track ends. */ TrackEnd = "TrackEndEvent", /** * Event type for when a track encounters an exception. */ TrackException = "TrackExceptionEvent", /** * Event type for when a track gets stuck. */ TrackStuck = "TrackStuckEvent", /** * Event type for when lyrics are found. */ LyricsFound = "LyricsFoundEvent", /** * Event type for when lyrics are not found. */ LyricsNotFound = "LyricsNotFoundEvent", /** * Event type for when a lyrics line is sent. */ LyricsLine = "LyricsLineEvent", /** * Event type for when the WebSocket connection is closed. */ WebsocketClosed = "WebSocketClosedEvent" } /** * The reasons a track can end. */ declare enum TrackEndReason { /** * The track ended normally. */ Finished = "finished", /** * The track fails to load. */ LoadFailed = "loadFailed", /** * The track was stopped. */ Stopped = "stopped", /** * The track was replaced. */ Replaced = "replaced", /** * The track was cleaned up. */ Cleanup = "cleanup" } /** * The options for error actions. */ interface DisconnectPlayerActions { /** * Whether to automatically destroy the player on disconnect or error. * @type {boolean | undefined} * @default false */ autoDestroy?: boolean; /** * Whether to automatically reconnect on disconnect. * @type {boolean | undefined} * @default false */ autoReconnect?: boolean; /** * Whether to automatically add tracks back to the queue on disconnect. * @type {boolean | undefined} * @default false */ autoQueue?: boolean; } /** * The options for actions taken when a track throws an error. */ interface ErrorPlayerActions { /** * Whether to automatically destroy the player when a track errors. * Takes precedence over {@link ErrorPlayerActions.autoStop}. * @type {boolean | undefined} * @default false */ autoDestroy?: boolean; /** * Whether to stop playback and stay idle (keeping the queue) when a track errors, * instead of advancing to the next track (the default behaviour). * @type {boolean | undefined} * @default false */ autoStop?: boolean; } /** * The Hoshimi player options. */ interface HoshimiPlayerOptions { /** * * The function to use to get the requester data. * @param {TrackRequester} requester The requester of the track. */ requesterFn?(requester: TrackRequester): T; /** * The options for handling disconnects. * @type {DisconnectPlayerActions | undefined} */ onDisconnect?: DisconnectPlayerActions; /** * The options for handling track errors. * @type {ErrorPlayerActions | undefined} */ onError?: ErrorPlayerActions; } /** * The base interface for player events. */ interface PlayerEvent { /** * The type of the event. * @type {Type} */ type: Type; /** * The operation code for the event. * @type {OpCodes.Event} */ op: OpCodes.Event; /** * The guild id associated with the event. * @type {string} */ guildId: string; } /** * The event for when a track starts playing. */ interface TrackStartEvent extends PlayerEvent { /** * The track that started playing. * @type {LavalinkTrack} */ track: LavalinkTrack; } /** * The event for when a track ends. */ interface TrackEndEvent extends PlayerEvent { /** * The track that ended. * @type {LavalinkTrack} */ track: LavalinkTrack; /** * The reason the track ended. * @type {TrackEndReason} */ reason: TrackEndReason; } /** * The event for when a track gets stuck. */ interface TrackStuckEvent extends PlayerEvent { /** * The track that got stuck. * @type {LavalinkTrack} */ track: LavalinkTrack; /** * The threshold in milliseconds. * @type {number} */ thresholdMs: number; } /** * The event for when a track encounters an exception. */ interface TrackExceptionEvent extends PlayerEvent { /** * The exception that occurred. * @type {Exception} */ exception: Exception; /** * The track that encountered the exception. * @type {LavalinkTrack} */ track: LavalinkTrack; } /** * The event for when the WebSocket connection is closed. */ interface WebSocketClosedEvent extends PlayerEvent { /** * The close code. * @type {number} */ code: number; /** * Whether the connection was closed by the remote. * @type {boolean} */ byRemote: boolean; /** * The reason for the closure. * @type {string} */ reason: string; } /** * The event for when lyrics are found. */ interface LyricsFoundEvent extends PlayerEvent { /** * The guild id associated with the event. * @type {string} */ guildId: string; /** * The lyrics result of the event. * @type {LyricsResult} */ lyrics: LyricsResult; } /** * The event for when lyrics are not found. */ interface LyricsNotFoundEvent extends PlayerEvent {} /** * The event for when a lyrics line is sent. */ interface LyricsLineEvent extends PlayerEvent { /** * The guild id associated with the event. * @type {string} */ guildId: string; /** * The line index of the lyrics line. * @type {number} */ lineIndex: number; /** * The lyrics line of the event. * @type {LyricsLine} */ line: LyricsLine; /** * Returns if the line was skipped. * @type {boolean} */ skipped: boolean; } /** * The update for the player state. */ interface PlayerUpdate { /** * The operation code for the update. * @type {OpCodes.PlayerUpdate} */ op: OpCodes.PlayerUpdate; /** * The guild ID associated with the update. * @type {string} */ guildId: string; /** * The state of the player. * @type {PlayerUpdateState} */ state: PlayerUpdateState; } interface PlayerUpdateState { /** * Whether the player is connected. * @type {boolean} */ connected: boolean; /** * The position of the track. * @type {number} */ position: number; /** * The time of the update. * @type {number} */ time: number; /** * The ping of the player. * @type {number} */ ping: number; } /** * The options for the player. */ interface PlayerOptions { /** * Guild id of the player. * @type {string} */ guildId: string; /** * Voice channel id of the player. * @type {string} */ voiceId: string; /** * Volume of the player. * @type {number | undefined} * @default 100 */ volume?: number; /** * Set if the player should be deafened. * @type {boolean | undefined} * @default true */ selfDeaf?: boolean; /** * Set if the player should be muted. * @type {boolean | undefined} * @default false */ selfMute?: boolean; /** * Text channel id of the player. * @type {string | undefined} */ textId?: string; /** * Lavalink node of the player. * @type {NodeIdentifier} */ node?: NodeIdentifier; } /** * The options for playing a track with Lavalink. */ interface LavalinkPlayOptions extends BasePlayOptions { /** * Track to play. * @type {PartialLavalinkTrack | undefined} */ track?: PartialLavalinkTrack; } /** * The options for playing a track. */ interface PlayOptions extends BasePlayOptions { /** * Whether to replace the current track. * @type {boolean | undefined} * @default false */ noReplace?: boolean; /** * Track to play. * @type {TrackResolvableStructure | AnyLavalinkTrack | undefined} */ track?: TrackResolvableStructure | AnyLavalinkTrack; } interface PlayerVoice { /** * The voice server token. * @type {string} */ token: string; /** * The voice server endpoint. * @type {string} */ endpoint: string; /** * The voice server session id. * @type {string} */ sessionId: string; /** * The voice channel id. * @type {string | undefined} */ channelId?: string; /** * The voice connection state. * @type {boolean | undefined} */ connected?: boolean; /** * The voice server ping. * @type {number | undefined} */ ping?: number; } /** * The JSON representation of the player. */ interface PlayerJSON { /** * The guild id of the player. * @type {string} */ guildId: string; /** * The volume of the player. * @type {number} */ volume: number; /** * The self deaf state of the player. * @type {boolean} */ selfDeaf: boolean; /** * The self mute state of the player. * @type {boolean} */ selfMute: boolean; /** * The voice settings for the player. * @type {Nullable} */ voice: Nullable; /** * The loop mode of the player. * @type {LoopMode} */ loop: LoopMode; /** * The options for the player. * @type {PlayerOptions} */ options: PlayerOptions; /** * The paused state of the player. * @type {boolean} */ paused: boolean; /** * The playing state of the player. * @type {boolean} */ playing: boolean; /** * The voice channel id of the player. * @type {string} */ voiceId?: string; /** * The text channel id of the player. * @type {string | undefined} */ textId?: string; /** * The last position received from Lavalink. * @type {number} */ lastPosition: number; /** * The timestamp when the last position change update happened. * @type {number | null} */ lastPositionUpdate: number | null; /** * The current calculated position of the player. * @type {number} */ position: number; /** * The timestamp when the player was created. * @type {number} */ createdTimestamp: number; /** * The ping of the player. * @type {number} */ ping: number; /** * The queue of the player. * @type {QueueJSON} */ queue: QueueJSON; /** * The node of the player. * @type {NodeJSON} */ node: NodeJSON; /** * The filter settings of the player. * @type {FilterSettings} */ filters: FilterSettings; } /** * The lyrics methods for the player. */ interface LyricsMethods { /** * * Get the current lyrics for the current track. * @param {boolean} [skipSource=false] Whether to skip the source or not. * @returns {Promise} The lyrics result or null if not found. * @example * ```ts * const player = manager.getPlayer("guildId"); * const lyrics = await player.lyrics.current(); * ``` */ current(skipSource?: boolean): Promise; /** * * Get the lyrics for a specific track. * @param {TrackStructure} track The track to get the lyrics for. * @param {boolean} [skipSource=false] Whether to skip the source or not. * @returns {Promise} The lyrics result or null if not found. * @example * ```ts * const player = manager.getPlayer("guildId"); * const track = player.queue.current; * const lyrics = await player.lyrics.get(track); * ``` */ get(track: TrackStructure, skipSource?: boolean): Promise; /** * * Subscribe to the lyrics for a specific guild. * @param {boolean} [skipSource=false] Whether to skip the source or not. * @returns {Promise} Let's start the sing session! * @example * ```ts * const player = manager.getPlayer("guildId"); * await player.lyrics.subscribe(); * ``` */ subscribe(skipSource?: boolean): Promise; /** * * Unsubscribe from the lyrics for a specific guild. * @returns {Promise} Let's stop the sing session! * @example * ```ts * const player = manager.getPlayer("guildId"); * await player.lyrics.unsubscribe(); * ``` */ unsubscribe(): Promise; } interface SkipOptions { /** * The amount of tracks to skip. * @type {number | undefined} * @default 1 */ to?: number; /** * Whether to throw an error if the skip amount exceeds the queue size. * @type {boolean | undefined} * @default true */ throwError?: boolean; } interface StopOptions { /** * Whether to destroy the player after stopping. * @type {boolean | undefined} * @default true */ destroy?: boolean; /** * Wheter to clear the queue after stopping. * @type {boolean | undefined} * @default false */ clearQueue?: boolean; /** * Whether to leave the voice channel after stopping. * @type {boolean | undefined} * @default false */ leaveVoice?: boolean; } interface DestroyOptions { /** * The reason for destroying the player. * @type {DestroyReasons | undefined} * @default DestroyReasons.Stop */ reason?: DestroyReasons; /** * Whether to clear the queue after destroying. * @type {boolean | undefined} * @default true */ disconnect?: boolean; } /** * The voice channel update options. */ type VoiceChannelUpdate = Prettify>; /** * The voice settings for the player. */ type LavalinkPlayerVoice = Prettify>>; /** * The type for any lavalink track, including partial and unresolved tracks. */ type AnyLavalinkTrack = LavalinkTrack | UnresolvedLavalinkTrack; //#endregion //#region src/types/Node.d.ts /** * The states. */ declare enum State { /** * The node is connecting. */ Connecting = 1, /** * The node is connected. */ Connected = 2, /** * The node is disconnected. */ Disconnected = 3, /** * The node is reconnecting. */ Reconnecting = 4, /** * The node is reconnected. */ Reconnected = 5, /** * The node is destroyed. */ Destroyed = 6, /** * The node is idle. */ Idle = 7 } /** * The op codes for the node. */ declare enum OpCodes { /** * The op code for the ready event for the node. */ Ready = "ready", /** * The op code for the player update event for the node. */ PlayerUpdate = "playerUpdate", /** * The op code for the stats event for the node. */ Stats = "stats", /** * The op code for the event event for the node. */ Event = "event" } /** * The load types for the result. */ declare enum LoadType { /** * The load type for the track. */ Track = "track", /** * The load type for the playlist. */ Playlist = "playlist", /** * The load type for the search. */ Search = "search", /** * The load type for the empty. */ Empty = "empty", /** * The load type for the error. */ Error = "error" } /** * The sources available for the result. */ declare enum SourceNames { /** * The lavalink built-in source name for Youtube. * @description Provided by lavalink */ Youtube = "youtube", /** * The lavalink built-in source name for Youtube Music. * @description Provided by lavalink */ YoutubeMusic = "youtubemusic", /** * The lavalink built-in source name for Soundcloud. * @description Provided by lavalink */ Soundcloud = "soundcloud", /** * The lavalink built-in source name for Bandcamp. * @description Provided by lavalink */ Bandcamp = "bandcamp", /** * The lavalink built-in source name for Twitch. * @description Provided by lavalink */ Twitch = "twitch", /** * The lavalink built-in source name for Vimeo. * @description Provided by lavalink */ Vimeo = "vimeo", /** * The lavalink built-in source name for Mixer. * @description Provided by lavalink */ Mixer = "mixer", /** * The lavasrc built-in source name for Spotify. * @description Provided by lavasrc */ Spotify = "spotify", /** * The lavasrc built-in source name for Deezer. * @description Provided by lavasrc */ Deezer = "deezer", /** * The lavasrc built-in source name for VK Music. * @description Provided by lavasrc */ VKMusic = "vkmusic", /** * The lavasrc built-in source name for Tidal. * @description Provided by lavasrc */ Tidal = "tidal", /** * The lavasrc built-in source name for JioSaavn. * @description Provided by lavasrc */ JioSaavn = "jiosaavn", /** * The lavasrc built-in source name for Apple Music. * @description Provided by lavasrc */ AppleMusic = "applemusic", /** * The lavasrc built-in source name for Yandex Music. * @description Provided by lavasrc */ YandexMusic = "yandexmusic", /** * The lavasrc built-in source name for Flowery TTS. * @description Provided by lavasrc */ FloweryTTS = "flowery-tts", /** * The http source name. * @description Generic HTTP source */ HTTP = "http", /** * This is self-explanatory too. * @description Provided by skybot-lavalink-plugin. */ PornHub = "pornhub", /** * Play voice using text to speech. * @description Provided by skybot-lavalink-plugin. */ TextToSpeech = "tts", /** * Play from Clyp.it. * @description Provided by skybot-lavalink-plugin. */ Clypit = "clypit", /** * Play from Stream Deck audio. * @description Provided by skybot-lavalink-plugin. */ StreamDeckAudio = "StreamDeckAudio", /** * Play from getyarn.io. * @description Provided by skybot-lavalink-plugin. */ GetYarn = "getyarn.io", /** * Play from MixCloud. * @description Provided by skybot-lavalink-plugin. */ MixCloud = "mixcloud", /** * Play from OverClocked ReMix. * @description Provided by skybot-lavalink-plugin. */ OCRemix = "ocremix", /** * Play from PixelDrain. * @description Provided by skybot-lavalink-plugin. */ PixelDrain = "pixeldrain", /** * Play from Reddit. * @description Provided by skybot-lavalink-plugin. */ Reddit = "reddit", /** * Play from SoundGasm. * @description Provided by skybot-lavalink-plugin. */ SoundGasm = "soundgasm", /** * Play from TikTok. * @description Provided by skybot-lavalink-plugin. */ TikTok = "tiktok" } /** * Source name type supporting built-ins plus custom augmented values. */ type SourceName = SourceNames | CustomizableSources[keyof CustomizableSources]; /** * The response severity of the result. */ declare enum Severity { /** * The severity of the result is common. */ Common = "common", /** * The severity of the result is suspicious. */ Suspicious = "suspicious", /** * The severity of the result is fault. */ Fault = "fault" } /** * The plugin information type. */ declare enum PluginInfoType { /** * The plugin information type is album. */ Album = "album", /** * The plugin information type is playlist. */ Playlist = "playlist", /** * The plugin information type is artist. */ Artist = "artist", /** * The plugin information type is recommendations. */ Recommendations = "recommendations" } /** * The node destroy reason. */ declare enum NodeDestroyReasons { /** * The node is being destroyed by the user or the library. */ Destroy = "Node-Destroy", /** * The node is missing the session id. */ MissingSession = "Missing-Session" } /** * The websocket close codes. */ declare enum WebsocketCloseCodes { /** * The websocket close code for normal closure. */ NormalClosure = 1000, /** * The websocket close code for going away. */ GoingAway = 1001, /** * The websocket close code for protocol error. */ ProtocolError = 1002, /** * The websocket close code for unsupported data. */ UnsupportedData = 1003, /** * The websocket close code for no status received. */ NoStatusReceived = 1005, /** * The websocket close code for abnormal closure. */ AbnormalClosure = 1006, /** * The websocket close code for invalid frame payload data. */ InvalidFramePayloadData = 1007, /** * The websocket close code for policy violation. */ PolicyViolation = 1008, /** * The websocket close code for message too big. */ MessageTooBig = 1009, /** * The websocket close code for mandatory extension. */ MandatoryExtension = 1010, /** * The websocket close code for internal error. */ InternalError = 1011, /** * The websocket close code for service restart. */ ServiceRestart = 1012, /** * The websocket close code for try again later. */ TryAgainLater = 1013, /** * The websocket close code for bad gateway. */ BadGateway = 1014, /** * The websocket close code for TLS handshake failure. */ TLSHandshakeFailure = 1015, /** * The websocket close code for unauthorized. */ Unauthorized = 3000, /** * The websocket close code for forbidden. */ Forbidden = 3003, /** * The websocket close code for timeout. */ Timeout = 3008 } /** * The plugin names. */ declare enum PluginNames { /** * The lavasrc plugin name. * @author topi314 */ LavaSrc = "lavasrc-plugin", /** * The java lyrics plugin name. * @author duncte123 */ JavaLyrics = "java-lyrics-plugin", /** * The lava lyrics plugin name. * @author topi314 */ LavaLyrics = "lavalyrics-plugin", /** * The lavasearch plugin name. * @author topi314 */ LavaSearch = "lavasearch-plugin", /** * The sponsorblock plugin name. * @author topi314 */ SponsorBlock = "sponsorblock-plugin", /** * The lavadspx plugin name. * @author devoxin */ LavaDspx = "lavadspx-plugin", /** * The youtube source plugin name. * @author topi314, devoxin, and more... */ Youtube = "youtube-plugin", /** * The sky bot plugin name. * @author duncte123 */ Skybot = "skybot-lavalink-plugin", /** * The lava xm plugin name * @author esmBot */ LavaXm = "lava-xm-plugin", /** * The jiosaavn plugin name. * @author appujet */ Jiosaavn = "jiosaavn-plugin", /** * The lavalink filter plugin name. * @author ??? */ FilterPlugin = "lavalink-filter-plugin" } /** * The node sort types. */ declare enum NodeSortTypes { /** * Sort by memory usage. * @type {string} */ Memory = "memory", /** * Sort by cpu usage. * @type {string} */ Cpu = "cpu", /** * Sort by player count. * @type {string} */ Players = "players", /** * Sort by playing player count. * @type {string} */ PlayingPlayers = "playingPlayers", /** * Sort by system load. * @type {string} */ SystemLoad = "systemLoad", /** * Sort by lavalink load. * @type {string} */ LavalinkLoad = "lavalinkLoad", /** * Sort by penalties. * @type {string} */ Penalties = "penalties" } /** * The track result. */ interface TrackResult { /** * The load type of the result. * @type {LoadType.Track} */ loadType: LoadType.Track; /** * The track data of the result. * @type {LavalinkTrack} */ data: LavalinkTrack; } /** * The playlist result. */ interface PlaylistResult { /** * The load type of the result. * @type {LoadType.Playlist} */ loadType: LoadType.Playlist; /** * The playlist data of the result. * @type {Playlist} */ data: Playlist; } /** * The search result. */ interface SearchResult { /** * The load type of the result. * @type {LoadType.Search} */ loadType: LoadType.Search; /** * The search data of the result. * @type {LavalinkTrack[]} */ data: LavalinkTrack[]; } /** * The empty result. */ interface EmptyResult { /** * The load type of the result. * @type {LoadType.Empty} */ loadType: LoadType.Empty; /** * The empty data of the result. * @type {Record} */ data: Record; } /** * The error result. */ interface ErrorResult { /** * The load type of the result. * @type {LoadType.Error} */ loadType: LoadType.Error; /** * The error data of the result. * @type {Exception} */ data: Exception; } /** * The exception of the result. */ interface Exception { /** * The message of the exception. * @type {string} */ message: string; /** * The severity of the exception. * @type {Severity} */ severity: Severity; /** * The cause of the exception. * @type {string} */ cause: string; /** * The cause stack trace of the exception. * @type {string} */ causeStackTrace: string; } /** * The track. */ interface LavalinkTrack { /** * The base64 encoded track. * @type {string} */ encoded: string; /** * The plugin information of the track. * @type {PluginInfo} */ pluginInfo: PluginInfo; /** * The track information. * @type {TrackInfo} */ info: TrackInfo; /** * The user data of the track. * @type {TrackUserData | undefined} */ userData?: TrackUserData; } interface UnresolvedLavalinkTrack { /** * The base64 encoded track. * @type {string | undefined} */ encoded?: string; /** * The track information. * @type {UnresolvedTrackInfo} */ info: UnresolvedTrackInfo; /** * The plugin information of the track. * @type {Partial} */ pluginInfo?: Partial; /** * The user data of the track. * @type {TrackUserData | undefined} */ userData?: TrackUserData; } /** * The track information. */ interface TrackInfo { /** * The Identifier of the Track. * @type {string} */ identifier: string; /** * The track title * @type {string} */ title: string; /** * The track author.. * @type {string} */ author: string; /** * The duration of the Track. * @type {number} */ length: number; /** * The URL of the artwork if available. * @type {string | null} */ artworkUrl: string | null; /** * The URL of the track. * @type {string} */ uri: string; /** * The source name of the track. * @type {SourceName} */ sourceName: SourceName; /** * Whether the track is seekable. * @type {boolean} */ isSeekable: boolean; /** * Whether the track is a stream. * @type {boolean} */ isStream: boolean; /** * If ISRC code is available, it's provided. * @type {string | null} */ isrc: string | null; /** * The position of the track. * @type {number} */ position: number; } /** * The plugin information. */ interface PluginInfo { /** * The Type provided by a plugin. * @type {PluginInfoType | undefined} */ type?: PluginInfoType; /** * The Identifier provided by a plugin. * @type {string | undefined} */ albumName?: string; /** * The URL of the album. * @type {string | undefined} */ albumUrl?: string; /** * The URL of the album art. * @type {string | undefined} */ albumArtUrl?: string; /** * The URL of the artist. * @type {string | undefined} */ artistUrl?: string; /** * The URL of the artist artwork. * @type {string | undefined} */ artistArtworkUrl?: string; /** * The URL of the preview. * @type {string | undefined} */ previewUrl?: string; /** * Whether the track is a preview. * @type {boolean | undefined} */ isPreview?: boolean; /** * The total number of tracks in the playlist. * @type {number | undefined} */ totalTracks?: number; /** * The Identifier provided by a plugin. * @type {string | undefined} */ identifier?: string; /** * The Artwork URL provided by a plugin. * @type {string | undefined} */ artworkUrl?: string; /** * The Author Information provided by a plugin. * @type {string | undefined} */ author?: string; /** * The URL provided by a plugin. * @type {string | undefined} */ url?: string; } /** * The playlist information. */ interface Playlist { /** * The plugin information of the playlist. * @type {PluginInfo} */ pluginInfo: PluginInfo; /** * The tracks in the playlist. * @type {LavalinkTrack[]} */ tracks: LavalinkTrack[]; /** * The information of the playlist. * @type {PlaylistInfo} */ info: PlaylistInfo; } interface PlaylistInfo { /** * The name of the playlist. * @type {string} */ name: string; /** * The selected track in the playlist. * @type {number} */ selectedTrack: number; } /** * The ready event for the node. */ interface Ready { /** * The op code for the event. * @type {OpCodes.Ready} */ op: OpCodes.Ready; /** * Return if the node is resumed. * @type {boolean} */ resumed: boolean; /** * Return the session id of the node. * @type {string} */ sessionId: string; } /** * The node memory information. */ interface NodeMemory { /** * The total memory of the node. * @type {number} */ reservable: number; /** * The used memory of the node. * @type {number} */ used: number; /** * The free memory of the node. * @type {number} */ free: number; /** * The allocated memory of the node. * @type {number} */ allocated: number; } /** * The node frame stats. */ interface NodeFrameStats { /** * The amount of frames sent. * @type {number} */ sent: number; /** * The amount of frames sent between frames and the expected amount of frames. * @type {number} */ deficit: number; /** * The amount of frames nulled. * @type {number} */ nulled: number; } /** * The node cpu information. */ interface NodeCpu { /** * The amount of cores of the node. * @type {number} */ cores: number; /** * The system load of the node. * @type {number} */ systemLoad: number; /** * The lavalink load of the node. * @type {number} */ lavalinkLoad: number; } /** * The stats event for the node. */ interface Stats { /** * The op code for the event. * @type {OpCodes.Stats} */ op: OpCodes.Stats; /** * The amount of players on the node. * @type {number} */ players: number; /** * The amount of playing players on the node. * @type {number} */ playingPlayers: number; /** * The memory stats of the node. * @type {NodeMemory} */ memory: NodeMemory; /** * The frame stats of the node. * @type {NodeFrameStats | null} */ frameStats: NodeFrameStats | null; /** * The cpu stats of the node. * @type {NodeCpu} */ cpu: NodeCpu; /** * The amount of uptime of the node. * @type {number} */ uptime: number; } /** * The information of the node version. */ interface NodeInfoVersion { /** * The version of the node. * @type {string} */ semver: string; /** * The major version of the node. * @type {number} */ major: number; /** * The minor version of the node. * @type {number} */ minor: number; /** * The patch version of the node. * @type {number} */ patch: number; /** * The pre-release version of the node. * @type {string | undefined} */ preRelease?: string; /** * The build version of the node. * @type {string | undefined} */ build?: string; } /** * The git information of the node. */ interface NodeInfoGit { /** * The branch of the node. * @type {string} */ branch: string; /** * The commit of the node. * @type {string} */ commit: string; /** * The commit time of the node. * @type {number} */ commitTime: number; } /** * The plugin information of the node. */ interface NodeInfoPlugin { /** * The name of the plugin. * @type {PluginNames} */ name: PluginNames; /** * The version of the plugin. * @type {string} */ version: string; } /** * The information of the node. */ interface NodeInfo { /** * The version of the node. * @type {NodeInfoVersion} */ version: NodeInfoVersion; /** * The build time of the node. * @type {number} */ buildTime: number; /** * The git information of the node. * @type {NodeInfoGit} */ git: NodeInfoGit; /** * The build java version of the node. * @type {string} */ jvm: string; /** * The lavaplayer version of the node. * @type {string} */ lavaplayer: string; /** * The source managers available in the node. * @type {SourceName[]} */ sourceManagers: SourceName[]; /** * The filters available in the node. * @type {FilterType[]} */ filters: FilterType[]; /** * The plugins installed in the node. * @type {NodeInfoPlugin[]} */ plugins: NodeInfoPlugin[]; /** * Whether the node is a Nodelink instance. * @type {boolean} */ isNodelink: boolean; } /** * The node options. */ interface NodeOptions { /** * The node host. * @type {string} */ host: string; /** * The node port. * @type {number} */ port: number; /** * The node password. * @type {string} */ password: string; /** * The node id. * @type {string} */ id?: string; /** * Enable if the node is secure. * @type {boolean} * @default false */ secure?: boolean; /** * The timeout for the REST in milliseconds. Overrides the manager-level `restOptions.restTimeout` * for this node; when omitted, that manager default is used (falling back to `10000`). * @type {number} * @default restOptions.restTimeout */ restTimeout?: number; /** * The amount of retries to reconnect. * @type {number} * @default 5 */ retryAmount?: number; /** * The delay between retries in milliseconds. * @type {number} * @default 20000 */ retryDelay?: number; /** * The session id of the node. * @type {string} */ sessionId?: string; /** * Heartbeat options for this node. Overrides the manager-level defaults. * @type {NodeHeartbeatOptions | undefined} */ heartbeat?: NodeHeartbeatOptions; /** * Whether to close (and reconnect) the socket on a WebSocket error. * Overrides the manager-level default. * @default true */ closeOnError?: boolean; } /** * The headers for resumable requests. */ interface ResumableHeaders { /** * The name of the client. * @type {string} */ "Client-Name": string; /** * The user agent of the client. * @type {string} */ "User-Agent": string; /** * The user id of the client. * @type {string} */ "User-Id": string; /** * The session id of the client. * @type {string | undefined} */ "Session-Id"?: string; /** * The authorization of the client. * @type {string} */ Authorization: string; } /** * The search query to use. */ interface SearchQuery { /** * The query to search for. * @type {string} */ query: string; /** * The search source to use. * @type {SearchSource | SourceName | undefined} */ source?: SearchSource | SourceName; /** * The search params to use. * @type {Record | undefined} */ params?: Record; } /** * The node session options. */ interface NodeSessionOptions { /** * Make the node resumable. * @type {boolean} * @default false */ resumable?: boolean; /** * The timeout for resuming the session in seconds. * @type {number} * @default 60 */ timeout?: number; /** * Hoshimi will try to resume the players in the node if it's possible. * @type {boolean} * @default false */ byLibrary?: boolean; /** * Custom handler for `byLibrary` resume. When set, it runs instead of the built-in one; when * omitted, the built-in `resumeByLibrary` is used. Only consulted while `byLibrary` is enabled. * @param {NodeStructure} node The node whose players are being resumed. * @param {PlayerStructure[]} players The players the library holds for that node. * @returns {Awaitable} */ resumeFn?(node: NodeStructure, players: PlayerStructure[]): Awaitable; } interface NodePlayerMoveOptions { /** * The node sort type or a custom function to filter the nodes to move the players to when a node gets disconnected. * @type {NodeSortFilter | undefined} */ filterBy?: NodeSortFilter; /** * Whether to move the players to another node if the node gets disconnected. * @type {boolean} * @default false */ move?: boolean; } /** * The manager node options. */ interface HoshimiNodeOptions { /** * The user agent for the requests. * @type {UserAgent} * @example `hoshimi/v${string} (${string})` */ userAgent?: UserAgent; /** * Whether to close (and reconnect) the socket on a WebSocket error. * Overrides the manager-level default. * @default true */ closeOnError?: boolean; /** * The session options for the node. * @type {NodeSessionOptions | undefined} */ sessionOptions?: NodeSessionOptions; /** * Whether to move the players to another node if the node gets disconnected. * @type {NodePlayerMoveOptions | undefined} */ moveOptions?: NodePlayerMoveOptions; /** * The heartbeat options for liveness detection. * @type {NodeHeartbeatOptions | undefined} */ heartbeatOptions?: NodeHeartbeatOptions; } /** * The heartbeat options for liveness detection. */ interface NodeHeartbeatOptions { /** * Interval in milliseconds between WebSocket pings. Detects dead sockets * where TCP looks alive but the remote stopped responding. * Set to 0 to disable. * @default 30000 */ interval?: number; } /** * The interface of the node destroy object. */ interface NodeDestroyInfo { /** * The code for the destroy. * @type {WebsocketCloseCodes | undefined | number} */ code?: WebsocketCloseCodes | number; /** * The reason for the destroy. * @type {NodeDestroyReasons | undefined | string} */ reason?: NodeDestroyReasons | string; } /** * The interface of the node lyrics result. */ interface LyricsResult { /** * The source name of the lyric result. * @type {string} */ sourceName: string; /** * The provider name of the lyric result. * @type {string} */ provider: string; /** * The lyrics text of the result. * @type {string | null} */ text: string | null; /** * The lyrics lines of the result. * @type {LyricsLine[]} */ lines: LyricsLine[]; /** * The plugin information of the result. * @type {PluginInfo} */ plugin: PluginInfo; } /** * The interface of the node lyrics line. */ interface LyricsLine { /** * The line start time in milliseconds of the lyric line. * @type {number} */ timestamp: number; /** * The line duration in milliseconds of the lyric line. * @type {number | null} */ duration: number | null; /** * The line text of the lyric line. * @type {string} */ line: string; /** * The plugin information of the lyric line. * @type {PluginInfo} */ plugin: PluginInfo; } /** * The interface of the node json object. */ interface NodeJSON { /** * The node id. * @type {string} */ id: string; /** * The node session id. * @type {string | null} */ sessionId: string | null; /** * The node options. * @type {NodeOptions} */ options: NodeOptions; } /** * The type for the node sort function. */ type NodeSortFunction = (node: NodeStructure) => number; /** * The type for the player move filter. */ type NodeSortFilter = NodeSortTypes | NodeSortFunction; /** * The type for the unresolved track info. */ type UnresolvedTrackInfo = Prettify, "title">>; /** * The type of the node disconnect object. */ type NodeDisconnectInfo = NodeDestroyInfo; /** * The type of the user agent for the requests. */ type UserAgent = Hint<`${string}/v${string} (${string})`>; /** * The type of the payload for the socket. */ type LavalinkEventPayload = Ready | Stats | PlayerUpdate | TrackStartEvent | TrackEndEvent | TrackStuckEvent | TrackExceptionEvent | LyricsFoundEvent | LyricsNotFoundEvent | LyricsLineEvent | WebSocketClosedEvent; /** * The response of the result. */ type LavalinkSearchResponse = TrackResult | PlaylistResult | SearchResult | EmptyResult | ErrorResult; //#endregion //#region src/registry/SourceRegistry.d.ts /** * Interface representing a parsed query with an explicit source prefix. */ interface ParsedQuery { /** * The canonical source identifier parsed from the query prefix. * @type {string} */ source: string; /** * The remaining query value after removing the source prefix. * @type {string} */ value: string; } /** * The protocol strategy used to build lavalink identifiers. */ declare enum SourceProtocol { /** * Join the source and query with a colon: `source:query`. The default strategy. */ Colon = "colon", /** * Join the source and query with a scheme separator: `source://query`. */ DoubleSlash = "double-slash", /** * Use the query verbatim, without prefixing the source (e.g. local files, raw HTTP URLs). */ Raw = "raw" } /** * Registration options for a source. */ interface SourceRegistration { /** * Search source prefix used by Lavalink. */ source: RegistrySearchSource; /** * Optional track source name that resolves to the search source. */ name?: RegistrySourceName; /** * Protocol used when creating lavalink identifiers. * @default SourceProtocol.Colon */ protocol?: SourceProtocol; } /** * Custom sources for Hoshimi. * * Extend this interface via module augmentation to provide custom sources/search sources. * @example * ```ts * declare module "hoshimi" { * interface CustomizableSources { * mysearch: "my-source"; * } * } * ``` */ interface CustomizableSources {} /** * The custom search source keys provided by users via module augmentation. */ type SearchSourceKey = keyof CustomizableSources; /** * The full source identifier accepted by the source registry. */ type RegistrySearchSource = SearchSources | Hint; /** * The source name accepted by the source registry alias mapping. */ type RegistrySourceName = SourceNames | Hint; /** * Object representing the source registry for sources. */ declare const SourceRegistry: { /** * Register one or multiple source definitions. * @param {RestOrArray} registrations The source registration payloads. * @returns {string[]} The canonical source identifiers. * @example * ```ts * SourceRegistry.register({ * source: "mysearch", * name: "my-provider", * }); * * SourceRegistry.register( * { source: "mysearch" }, * { source: "mytts", protocol: SourceProtocol.DoubleSlash }, * ); * ``` */ readonly register: (...registrations: RestOrArray) => string[]; /** * Get the canonical source from an alias or source name. * @param {RegistrySearchSource} value The value to resolve. * @returns {string | undefined} The canonical source identifier. */ readonly resolve: (value: RegistrySearchSource) => string | undefined; /** * Checks whether a source is registered. * @param {RegistrySearchSource} value The value to check. * @returns {boolean} Whether the source is registered. */ readonly isRegistered: (value: RegistrySearchSource) => boolean; /** * Returns all canonical registered sources. * @returns {string[]} All canonical source identifiers. */ readonly getRegistered: () => string[]; /** * Build a lavalink identifier from a source and query. * @param {RegistrySearchSource} source The source to use. * @param {string} query The query to format. * @returns {string} The formatted lavalink identifier. */ readonly createIdentifier: (source: RegistrySearchSource, query: string) => string; /** * Tries to parse an explicit source prefix from a query. * @param {string} query The query to inspect. * @returns {ParsedQuery | null} The parsed source information. */ readonly parseQuery: (query: string) => ParsedQuery | null; }; //#endregion //#region src/types/Manager.d.ts /** * The search sources to use. */ declare enum SearchSources { /** * Search on YouTube. * @description Provided by youtube-source plugin. */ Youtube = "ytsearch", /** * Search on YouTube Music. * @description Provided by youtube-source plugin. */ YoutubeMusic = "ytmsearch", /** * Search on Spotify. * @description Provided by lava-src plugin. */ Spotify = "spsearch", /** * Search on Spotify recommendations. * @description Provided by lava-src plugin. */ SpotifyRecommendations = "sprec", /** * Search on Spotify artist recommendations. * @description Provided by lava-src plugin. */ SpotifyArtistMix = "sprec:mix:artist", /** * Search on Spotify album recommendations. * @description Provided by lava-src plugin. */ SpotifyAlbumMix = "sprec:mix:album", /** * Search on Spotify track recommendations. * @description Provided by lava-src plugin. */ SpotifyTrackMix = "sprec:mix:track", /** * Search on Spotify using ISRC code. * @description Provided by lava-src plugin. */ SpotifyISRCMix = "sprec:mix:isrc", /** * Search on SoundCloud. * @description Provided by lavalink. */ SoundCloud = "scsearch", /** * Search on Apple Music. * @description Provided by lava-src plugin. */ AppleMusic = "amsearch", /** * Search on Bandcamp. * @description Provided by lava-src plugin. */ BandCamp = "bcsearch", /** * Search on Deezer. * @description Provided by lava-src plugin. */ Deezer = "dzsearch", /** * Search on Deezer using ISRC code. * @description Provided by lava-src plugin. */ DeezerISRC = "dzisrc", /** * Search on Deezer recommendations. * @description Provided by lava-src plugin. */ DeezerRecommendations = "dzrec", /** * Search on Yandex Music. * @description Provided by lava-src plugin. */ YandexMusic = "ymsearch", /** * Search on Yandex Music for recommendations. * @description Provided by lava-src plugin. */ YandexMusicRecommendations = "ymrec", /** * Search on VK Music. * @description Provided by lava-src plugin. */ VKMusic = "vksearch", /** * Search on VK Music for recommendations. * @description Provided by lava-src plugin. */ VKMusicRecommendations = "vkrec", /** * Search on Tidal. * @description Provided by lava-src plugin. */ Tidal = "tdsearch", /** * Search on Tidal for recommendations. * @description Provided by lava-src plugin. */ TidalRecommendations = "tdrec", /** * Search on Qobuz. * @description Provided by lava-src plugin. */ Qobuz = "qbsearch", /** * Search on Qobuz using ISRC code. * @description Provided by lava-src plugin. */ QobuzISRC = "qbisrc", /** * Search on Qobuz for recommendations. * @description Provided by lava-src plugin. */ QobuzRecommendations = "qbrec", /** * Search on JioSaavn. * @description Provided by lava-src plugin. */ JioSaavn = "jssearch", /** * Search on JioSaavn using ISRC code. * @description Provided by lava-src plugin. */ JioSaavnRecommendations = "jsrec", /** * Search on Twitch. * @description Provided by lavalink. */ Twitch = "twsearch", /** * Search on Mixer. * @description Provided by lavalink. */ Mixer = "mxsearch", /** * Search on Vimeo. * @description Provided by lavalink. */ Vimeo = "vmsearch", /** * Play voice using flowery tts. */ FloweryTTS = "ftts", /** * Play a local file. */ Local = "local", /** * This is self-explanatory. * @description Provided by skybot-lavalink-plugin plugin. */ PornHub = "phsearch", /** * Play voice using text to speech. * @description Provided by skybot-lavalink-plugin plugin. */ TextToSpeech = "speak", /** * Search via http url. * @description Provided by lavalink. */ HTTP = "http" } /** * The custom search source keys provided by users. */ type CustomSearchSources = keyof CustomizableSources; /** * The custom source names provided by users. */ type CustomSourceNames = CustomizableSources[CustomSearchSources]; /** * The full source identifier accepted by the search API. */ type SearchSource = SearchSources | CustomSearchSources; /** * The debug levels for the manager. */ declare enum DebugLevels { /** * Debug level for the manager. */ Manager = 1, /** * Debug level for the node. */ Node = 2, /** * Debug level for the player. */ Player = 3, /** * Debug level for the rest. */ Rest = 4, /** * Debug level for the queue. */ Queue = 5, /** * Debug level for testing purposes. */ Test = 6 } /** * The events for the manager. */ declare enum EventNames { /** * Emitted when the manager emits a debug message. */ Debug = "debug", /** * Emitted when the manager emits an error. */ Error = "error", /** * Emitted when the node gives a response. */ NodeRaw = "nodeRaw", /** * Emitted when the node gives an error. */ NodeError = "nodeError", /** * Emitted when the node is ready. */ NodeReady = "nodeReady", /** * Emitted when the node is disconnected. */ NodeDisconnect = "nodeDisconnect", /** * Emitted when the node reconnects. */ NodeReconnecting = "nodeReconnecting", /** * Emitted when the node is destroyed. */ NodeDestroy = "nodeDestroy", /** * Emitted when the node is resumed. */ NodeResumed = "nodeResumed", /** * Emitted when the node is created. */ NodeCreate = "nodeCreate", /** * Emitted when the player is created. */ PlayerCreate = "playerCreate", /** * Emitted when the player updates. */ PlayerUpdate = "playerUpdate", /** * Emitted when the player is destroyed. */ PlayerDestroy = "playerDestroy", /** * Emitted when the player has an error. */ PlayerError = "playerError", /** * Emitted when the player is paused. */ PlayerPaused = "playerPaused", /** * Emitted when the player is resumed. */ PlayerResumed = "playerResumed", /** * Emitted when the player is disconnected from the voice channel. */ PlayerDisconnect = "playerDisconnect", /** * Emitted when the player is moved to a different voice channel. */ PlayerMove = "playerMove", /** * Emitted when a track starts playing. */ TrackStart = "trackStart", /** * Emitted when a track ends. */ TrackEnd = "trackEnd", /** * Emitted when a track is stuck. */ TrackStuck = "trackStuck", /** * Emitted when a track is errored. */ TrackError = "trackError", /** * Emitted when lyrics are found. */ LyricsFound = "lyricsFound", /** * Emitted when lyrics are not found. */ LyricsNotFound = "lyricsNotFound", /** * Emitted when a line of lyrics is updated. */ LyricsLine = "lyricsLine", /** * Emitted when the queue ends. */ QueueEnd = "queueEnd", /** * Emitted when the queue updates. */ QueueUpdate = "queueUpdate", /** * Emitted when the socket is closed. */ WebSocketClosed = "socketClosed" } /** * The destroy reasons for the player. */ declare enum DestroyReasons { /** * The player was stopped. */ Stop = "Player-Stop", /** * The player was destroyed by user request. */ Requested = "Player-Requested", /** * The player was destroyed because the queue was empty. */ Empty = "Player-Empty", /** * The player was destroyed because the node was disconnected. */ NodeDisconnected = "Player-NodeDisconnected", /** * The player was destroyed because the node was destroyed. */ NodeDestroy = "Player-NodeDestroy", /** * The player was destroyed because the voice channel was deleted. */ VoiceChannelDeleted = "Player-VoiceChannelDeleted", /** * The player was destroyed because it left the voice channel. */ VoiceChannelLeft = "Player-VoiceChannelLeft", /** * The player was destroyed because it failed to reconnect. */ ReconnectFailed = "Player-ReconnectFailed", /** * The player was destroyed because a track threw an error and `onError.autoDestroy` is enabled. */ TrackError = "Player-TrackError" } /** * The client data for the manager. */ interface ClientInfo extends Record { /** * The id of the client. * @type {string} */ id: string; /** * The username of the client. * @type {string} */ username?: string; } /** * Gateway send payload. */ interface GatewaySendPayload { /** * Payload op code. * @type {number} */ op: number; /** * Payload data. * @type {GatewayPayload} */ d: GatewayPayload; } /** * Gateway payload. */ interface GatewayPayload { /** * Payload guild id. * @type {string} */ guild_id: string; /** * Payload channel id. * @type {string | null} */ channel_id: string | null; /** * Payload self mute. * @type {boolean} */ self_mute: boolean; /** * Payload self deafen. * @type {boolean} */ self_deaf: boolean; } /** * The options for the manager. */ interface HoshimiOptions { /** * * Send the payload to discord. * @param {string} guildId The guild id to send the payload to. * @param {GatewaySendPayload} payload The payload to send. */ sendPayload(guildId: string, payload: GatewaySendPayload): Awaitable; /** * The nodes to use. * @type {NodeOptions[]} */ nodes: NodeOptions[]; /** * The client data to use. * @type {ClientInfo} */ client?: Partial; /** * The default search source to use. * @type {SearchSources} * @default SearchSources.Youtube */ defaultSearchSource?: SearchSource; /** * The queue options to use. * @type {HoshimiQueueOptions} */ queueOptions?: HoshimiQueueOptions; /** * The node options to use. * @type {HoshimiNodeOptions} */ nodeOptions?: HoshimiNodeOptions; /** * The rest options to use. * @type {HoshimiRestOptions} */ restOptions?: HoshimiRestOptions; /** * The player options to use. * @type {HoshimiPlayerOptions} */ playerOptions?: HoshimiPlayerOptions; } /** * The events for the manager. */ interface HoshimiEvents { /** * Emitted when the manager emits a debug message. * @param {DebugLevels} level The debug level of the message. * @param {string} message The message that was emitted. */ debug: [level: DebugLevels, message: string]; /** * Emitted when the manager emits an error. * @param {Error | unknown} error The error that was emitted. */ error: [error: Error | unknown]; /** * Emitted when the node gives a response. * @param {NodeStructure} node The node that emitted the event. * @param {LavalinkEventPayload} message The message that was received. */ nodeRaw: [node: NodeStructure, message: LavalinkEventPayload]; /** * Emitted when the node gives an error. * @param {NodeStructure} node The node that emitted the event. * @param {Error | unknown} error The error that was received. */ nodeError: [node: NodeStructure, error: Error | unknown]; /** * Emitted when the node is ready. * @param {NodeStructure} node The node that emitted the event. * @param {number} retries The number of retries after the node was ready. * @param {Ready} payload The payload of the event. */ nodeReady: [node: NodeStructure, retries: number, payload: Ready]; /** * Emitted when the node is disconnected. * @param {NodeStructure} node The node that was disconnected. */ nodeDisconnect: [node: NodeStructure]; /** * Emitted when the node reconnects. * @param {NodeStructure} node The node that was reconnected. * @param {number} retriesLeft The number of retries left. * @param {number} delay The delay before the next retry. */ nodeReconnecting: [node: NodeStructure, retriesLeft: number, delay: number]; /** * Emitted when the node is destroyed. * @param {NodeStructure} node The node that was destroyed. * @param {NodeDestroyInfo} options The options for the destroy. */ nodeDestroy: [node: NodeStructure, destroy: NodeDestroyInfo]; /** * Emitted when the node is resumed. * @param {NodeStructure} node The node that was resumed. * @param {LavalinkPlayer[]} players The players that were resumed. * @param {Ready} payload The payload of the event. */ nodeResumed: [node: NodeStructure, players: LavalinkPlayer[], payload: Ready]; /** * Emitted when the node is created. * @param {NodeStructure} node The node that was created. */ nodeCreate: [node: NodeStructure]; /** * Emitted when the player is created. * @param {PlayerStructure} player The player that was created. */ playerCreate: [player: PlayerStructure]; /** * Emitted when the player updates. * @param {PlayerStructure} newPlayer The new player. * @param {PlayerJSON} oldPlayer The old player. */ playerUpdate: [newPlayer: PlayerStructure, oldPlayer: PlayerJSON, payload: PlayerUpdate]; /** * Emitted when the player is destroyed. * @param {PlayerStructure} player The player that was destroyed. * @param {string} reason The reason for the destroy. */ playerDestroy: [player: PlayerStructure, reason: string]; /** * Emitted when the player has an error. * @param {PlayerStructure} player The player that emitted the event. * @param {Error | unknown} error The error that was emitted. */ playerError: [player: PlayerStructure, error: Error | unknown]; /** * Emitted when the player is paused. * @param {PlayerStructure} player The player that was paused. * @param {TrackStructure | null} track The track that was paused. */ playerPaused: [player: PlayerStructure, track: TrackStructure | null]; /** * Emitted when the player is resumed. * @param {PlayerStructure} player The player that was resumed. * @param {TrackStructure | null} track The track that was resumed. */ playerResumed: [player: PlayerStructure, track: TrackStructure | null]; /** * Emitted when the player is disconnected from the voice channel. * @param {PlayerStructure} player The player that was disconnected. */ playerDisconnect: [player: PlayerStructure]; /** * Emitted when the player is moved to a different voice channel. * @param {PlayerStructure} player The player that was moved. * @param {string} oldChannelId The voice channel id the player was moved from. * @param {string} newChannelId The voice channel id the player was moved to. */ playerMove: [player: PlayerStructure, oldChannelId: string, newChannelId: string]; /** * Emitted when a track starts playing. * @param {PlayerStructure} player The player that emitted the event. * @param {TrackStructure | null} track The track that was started. * @param {TrackStartEvent} payload The payload of the event. */ trackStart: [player: PlayerStructure, track: TrackStructure | null, payload: TrackStartEvent]; /** * Emitted when a track ends. * @param {PlayerStructure} player The player that emitted the event. * @param {TrackStructure | null} track The track that ended. * @param {TrackEndEvent} payload The payload of the event. */ trackEnd: [player: PlayerStructure, track: TrackStructure | null, payload: TrackEndEvent]; /** * Emitted when the track is stuck. * @param {PlayerStructure} player The player that emitted the event. * @param {TrackStructure | null} track The track that was stuck. * @param {TrackStuckEvent} payload The payload of the event. */ trackStuck: [player: PlayerStructure, track: TrackStructure | null, payload: TrackStuckEvent]; /** * Emitted when a track is errored. * @param {PlayerStructure} player The player that emitted the event. * @param {TrackStructure | null} track The track that was errored. * @param {TrackExceptionEvent} payload The payload of the event. */ trackError: [player: PlayerStructure, track: TrackStructure | null, payload: TrackExceptionEvent]; /** * Emitted when lyrics are found. * @param {PlayerStructure} player The player that emitted the event. * @param {TrackStructure | null} track The track that was found. * @param {LyricsFoundEvent} payload The lyrics that were found. */ lyricsFound: [player: PlayerStructure, track: TrackStructure | null, payload: LyricsFoundEvent]; /** * Emitted when lyrics are not found. * @param {PlayerStructure} player The player that emitted the event. * @param {TrackStructure | null} track The track that was not found. * @param {LyricsNotFoundEvent} payload The lyrics that were not found. */ lyricsNotFound: [player: PlayerStructure, track: TrackStructure | null, payload: LyricsNotFoundEvent]; /** * Emitted when a line of lyrics is updated. * @param {PlayerStructure} player The player that emitted the event. * @param {TrackStructure | null} track The track that was updated. * @param {LyricsLineEvent} payload The lyrics that were updated. */ lyricsLine: [player: PlayerStructure, track: TrackStructure | null, payload: LyricsLineEvent]; /** * Emitted when the queue ends. * @param {PlayerStructure} player The player that emitted the event. * @param {QueueStructure} queue The queue that ended. */ queueEnd: [player: PlayerStructure, queue: QueueStructure]; /** * Emitted when the queue updates. * @param {PlayerStructure} player The player that emitted the event. * @param {QueueStructure} queue The queue that updated. */ queueUpdate: [player: PlayerStructure, queue: QueueStructure]; /** * Emitted when the socket is closed. * @param {PlayerStructure} player The player that emitted the event. * @param {WebSocketClosedEvent} payload The payload of the event. */ socketClosed: [player: PlayerStructure, payload: WebSocketClosedEvent]; } /** * The manager search result. */ interface QueryResult { /** * The load type of the search result. * @type {LoadType} */ loadType: LoadType; /** * The playlist of the search result. * @type {Playlist | null} */ playlist: Playlist | null; /** * The exception of the search result. * @type {Exception | null} */ exception: Exception | null; /** * The tracks of the search result. * @type {TrackStructure[]} */ tracks: TrackStructure[]; /** * The plugin info of the search result. * @type {PluginInfo | null} */ pluginInfo: PluginInfo | null; } /** * The query options. */ interface SearchOptions extends SearchQuery { /** * The requester of the query. * @type {TrackRequester | null} */ requester: TrackRequester | null; /** * The node or the node id to make the query. * @type {NodeIdentifier} */ node?: NodeIdentifier; } /** * The channel deleted data packet. */ interface ChannelDelete { /** * Guild id * @type {string} */ guild_id: string; /** * Channel id * @type {string} */ id: string; } /** * The voice state packet. */ interface VoiceState { /** * The op code for the voice state. * @type {string} */ op: "voiceUpdate"; /** * The guild id of the voice state. * @type {string} */ guildId: string; /** * The voice state event. * @type {VoiceServer} */ event: VoiceServer; /** * The guild id of the voice state. * @type {string} */ guild_id: string; /** * The user id of the voice state. * @type {string} */ user_id: string; /** * The session id of the voice state. * @type {string} */ session_id: string; /** * The channel id of the voice state. * @type {string} */ channel_id: string; /** * The server mute status of the voice state. * @type {boolean} */ mute: boolean; /** * The server deaf status of the voice state. * @type {boolean} */ deaf: boolean; /** * The self deaf status of the voice state. * @type {boolean} */ self_deaf: boolean; /** * The self mute status of the voice state. * @type {boolean} */ self_mute: boolean; /** * The self video status of the voice state. * @type {boolean} */ self_video: boolean; /** * The self stream status of the voice state. * @type {boolean} */ self_stream: boolean; /** * Whatetever the user is requesting to speak in a stage channel. * @type {boolean} */ request_to_speak_timestamp: boolean; /** * The suppress status of the voice state stage channel. * @type {boolean} */ suppress: boolean; } /** * The voice server packet. */ interface VoiceServer { /** * The voice server token. * @type {string} */ token: string; /** * The voice server guild id. * @type {string} */ guild_id: string; /** * The voice server endpoint. * @description Null while Discord reallocates the guild's voice server; a fresh update with a real endpoint follows. * @type {string | null} */ endpoint: string | null; } /** * The voice packet. */ interface VoicePacket { /** * The packet type. * @type {string} */ t: "VOICE_SERVER_UPDATE" | "VOICE_STATE_UPDATE"; /** * The packet data. * @type {VoiceState | VoiceServer} */ d: VoiceState | VoiceServer; } /** * The channel delete packet. */ interface ChannelDeletePacket { /** * The packet type * @type {string} */ t: "CHANNEL_DELETE"; /** * The packet data. * @type {ChannelDelete} */ d: ChannelDelete; } /** * Make a function awaitable by returning a promise or the value. */ type Awaitable = Promise | T; /** * Create a type that infers the value of a key from an object. */ type Inferable = T extends { [key in K]: infer R; } ? R : D; /** * Create a type that infers the value of a key from an object. */ type Omit$1 = Pick>; /** * Create a type that can be a rest or an array. */ type RestOrArray = T[] | [T[]]; /** * Conditional type to check if T is true, then A, else B or A | null. */ type If = T extends true ? A : B extends null ? A | null : B; /** * A hint type that can be either the type or a string. */ type Hint = T | (string & {}); /** * Make a type required. */ type PickRequired = { [P in K]-?: T[P]; } & Omit$1; /** * Make a type nullable. */ type PickNullable = { [P in K]: T[P] | null; } & Omit$1; /** * Make a type nullable. */ type Nullable = { [P in keyof T]: T[P] | null; }; /** * The type to prettify the object. */ type Prettify = { [K in keyof T]: T[K]; } & {}; /** * Make a type required. */ type DeepRequired = T extends ((...args: any[]) => any) ? T : T extends any[] ? T : T extends Date | RegExp | string | number | boolean ? T : T extends object ? { [K in keyof T]-?: DeepRequired; } : T; /** * The required options for the manager. */ type RequiredHoshimiOptions = DeepRequired; /** * The required options for the node. */ type RequiredHoshimiNodeOptions = DeepRequired; /** * A node identifier can be either a string or a node structure. */ type NodeIdentifier = NodeStructure | string; /** * Custom structures for Hoshimi. */ interface CustomizableStructures {} //#endregion //#region src/classes/Track.d.ts /** * Class representing a Hoshimi track. * @class Track * @implements {LavalinkTrack} */ declare class Track implements LavalinkTrack { /** * The base64 encoded track. * @type {string} */ readonly encoded: string; /** * The track info. * @type {TrackInfo} */ readonly info: TrackInfo; /** * The plugin info of the track. * @type {PluginInfo} */ readonly pluginInfo: PluginInfo; /** * The track user data. * @type {TrackUserData} */ userData?: TrackUserData; /** * The requester of the track. * @type {TrackRequester} */ requester: TrackRequester; /** * The constructor for the track. * @param {LavalinkTrack | null} track The track to construct the track from. * @param {TrackRequester} requester The requester of the track. * @example * ```ts * const track = Structures.Track({ * encoded: "base64", * info: { * title: "Track Title", * uri: "https://example.com", * duration: 300000, * }, * // the rest of the track info * }, requester); * * console.log(track.encoded); // the track encoded in base64 * ``` */ constructor(track: LavalinkTrack | null, requester: TrackRequester); /** * * Get the hyperlink of the track. * @param {boolean} [embedable=true] Whether the hyperlink should be embedable or not. * @returns {string} The hyperlink of the track. * @example * ```ts * const track = queue.current; * console.log(track.toHyperlink()); // [Track Title](https://example.com) * console.log(track.toHyperlink(false)); // [Track Title]() * ``` */ toHyperlink(embedable?: boolean): string; /** * * Converts the track to a JSON object for storage. * @returns {TrackJSON} The JSON representation of the track for storage. */ toJSON(): TrackJSON; } /** * Class representing an unresolved track. * @class UnresolvedTrack * @implements {UnresolvedLavalinkTrack} */ declare class UnresolvedTrack implements UnresolvedLavalinkTrack { /** * The base64 encoded track. * @type {string | undefined} */ readonly encoded?: string; /** * The track info. * @type {UnresolvedTrackInfo} */ readonly info: UnresolvedTrackInfo; /** * The track user data. * @type {TrackUserData | undefined} */ userData?: TrackUserData; /** * The requester of the track. * @type {TrackRequester | undefined} */ requester: TrackRequester; /** * The plugin info of the track. * @type {Partial} */ readonly pluginInfo?: Partial; /** * The constructor for the track. * @param {UnresolvedLavalinkTrack} track The track to construct the track from. * @param {TrackRequester} requester The requester of the track. * @example * ```ts * const track = new UnresolvedTrack({ * encoded: "base64", * info: { * title: "Track Title", * }, * // the rest of the track info * }, requester); * * console.log(track.encoded); // the track encoded in base64 * ``` */ constructor(track: UnresolvedLavalinkTrack, requester: TrackRequester); /** * * Converts the track to a JSON object for storage. * @returns {TrackJSON} The JSON representation of the track for storage. */ toJSON(): TrackJSON; /** * Resolves the track to a playable track. * @param {PlayerStructure} player The player to resolve the track for. * @returns {Promise} The resolved track. * @throws {ResolveError} If the track cannot be resolved. */ resolve(player: PlayerStructure): Promise; } /** * Interface representing an extendable track. */ interface CustomizableTrack {} /** * Type representing a Hoshimi track, which can be either a resolved or unresolved track. */ type TrackResolvableStructure = TrackStructure | UnresolvedTrackStructure; /** * The requester of the track. */ type TrackRequester = Inferable; /** * The user data of the track. */ type TrackUserData = Inferable>; //#endregion //#region src/types/Rest.d.ts /** * The methods for http requests */ declare enum HttpMethods { /** * The GET method requests a representation of the specified resource. Requests using GET should only retrieve data. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET * @type {string} */ Get = "GET", /** * The POST method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST * @type {string} */ Post = "POST", /** * The PUT method replaces all current representations of the target resource with the request payload. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT * @type {string} */ Put = "PUT", /** * The PATCH method is used to apply partial modifications to a resource. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH * @type {string} */ Patch = "PATCH", /** * The DELETE method deletes the specified resource. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE * @type {string} */ Delete = "DELETE", /** * The HEAD method asks for a response identical to that of a GET request, but without the response body. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD * @type {string} */ Head = "HEAD" } declare enum RestPathType { /** * The raw path of the request. * @type {string} */ Raw = "/", /** * The versioned path v4 of the request. * @type {string} */ V4 = "/v4" } /** * The status codes for the REST. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status */ declare enum HttpStatusCodes { /** * The request has succeeded. * @type {number} */ OK = 200, /** * The request has been fulfilled and resulted in a new resource being created. * @type {number} */ Created = 201, /** * The request has been accepted for processing, but the processing has not been completed. * @type {number} */ Accepted = 202, /** * The server successfully processed the request, but is not returning any content. * @type {number} */ NoContent = 204, /** * The resource has been moved permanently to a new URI. * @type {number} */ MovedPermanently = 301, /** * The requested resource has been found at a different URI. * @type {number} */ Found = 302, /** * The resource has not been modified since the last request. * @type {number} */ NotModified = 304, /** * The request cannot be processed due to bad syntax. * @type {number} */ BadRequest = 400, /** * The request requires user authentication. * @type {number} */ Unauthorized = 401, /** * The request was valid, but the server is refusing action. * @type {number} */ Forbidden = 403, /** * The server cannot find the requested resource. * @type {number} */ NotFound = 404, /** * The request method is known by the server but has been disabled and cannot be used. * @type {number} */ MethodNotAllowed = 405, /** * The server timed out waiting for the request. * @type {number} */ RequestTimeout = 408, /** * The request could not be completed due to a conflict with the current state of the resource. * @type {number} */ Conflict = 409, /** * The requested resource is no longer available and will not be available again. * @type {number} */ Gone = 410, /** * The user has sent too many requests in a given amount of time. * @type {number} */ TooManyRequests = 429, /** * A generic error message, given when no more specific message is suitable. * @type {number} */ InternalServerError = 500, /** * The server does not recognize the request method or lacks the ability to fulfill it. * @type {number} */ NotImplemented = 501, /** * The server was acting as a gateway and received an invalid response. * @type {number} */ BadGateway = 502, /** * The server is currently unavailable (overloaded or down). * @type {number} */ ServiceUnavailable = 503, /** * The server did not receive a timely response from an upstream server. * @type {number} */ GatewayTimeout = 504 } /** * The REST routes. */ declare const RestRoutes: { /** * * Get the updated player endpoint. * @param {string} sessionId The session id of the node. * @param {string} guildId The guild id of the player. * @returns {RestEndpoint} The endpoint for updating the player. */ UpdatePlayer(sessionId: string, guildId: string): `/sessions/${string}/players/${string}`; /** * * Get the update session endpoint. * @param {string} sessionId The session id of the node. * @returns {RestEndpoint} The endpoint for updating the session. */ UpdateSession(sessionId: string): `/sessions/${string}`; /** * * Get the get players endpoint. * @param {string} sessionId The session id of the node. * @returns {RestEndpoint} The endpoint for getting the players. */ GetPlayers(sessionId: string): `/sessions/${string}/players`; /** * * Get the current lyrics endpoint. * @param {string} sessionId The session id of the node. * @param {string} guildId The guild id of the player. * @returns {RestEndpoint} The endpoint for getting the current lyrics. */ CurrentLyrics(sessionId: string, guildId: string): `/sessions/${string}/players/${string}/track/lyrics`; /** * * Subscribe to lyrics endpoint. * @param {string} sessionId The session id of the node. * @param {string} guildId The guild id of the player. * @returns {RestEndpoint} The endpoint for subscribing to lyrics. */ SubscribeLyrics(sessionId: string, guildId: string): `/sessions/${string}/players/${string}/lyrics/subscribe`; /** * Get the lyrics endpoint. * @type {RestEndpoint} */ GetLyrics: "/lyrics"; /** * Get the decode track endpoint. * @type {RestEndpoint} */ DecodeTrack: "/decodetrack"; /** * Get the decode tracks endpoint. * @type {RestEndpoint} */ DecodeTracks: "/decodetracks"; /** * Get the load tracks endpoint. * @type {RestEndpoint} */ LoadTracks: "/loadtracks"; /** * Get the node info endpoint. * @type {RestEndpoint} */ NodeInfo: "/info"; /** * Get the load lyrics endpoint. * @type {RestEndpoint} * @description Used in NodelinkLyricsManager, only for nodelink nodes. */ LoadLyrics: "/loadlyrics"; /** * Get the connection endpoint. * @type {RestEndpoint} * @description Used for checking the connection status of the node, only for nodelink nodes. */ Connection: "/connection"; }; /** * The options for the REST. */ interface RestOptions { /** * The endpoint for the REST. * @type {RestEndpoint} */ endpoint: RestEndpoint; /** * The method for the REST. * @type {HttpMethods} */ method?: HttpMethods; /** * The headers for the REST. * @type {Record} */ headers?: Record; /** * The body for the REST. * @type {Record | string | undefined} */ body?: Record | string; /** * The query parameters for the REST. * @type {Record} */ params?: Record; /** * The path type for the REST. * @type {RestPathType} */ pathType?: RestPathType; } /** * The fetch options for the request. */ interface FetchOptions extends Omit { /** * The signal for the request. */ signal: AbortSignal; /** * The stringified body for the request. */ body?: string; } /** * The error for the REST. */ interface LavalinkRestError { /** * The timestamp for the REST. * @type {number} */ timestamp: number; /** * The status for the REST. * @type {number} */ status: number; /** * The error for the REST. * @type {string} */ error: string; /** * The trace for the REST. * @type {string} */ trace?: string; /** * The message for the REST. * @type {string} */ message: string; /** * The path for the REST. * @type {string} */ path: string; } /** * The player response from the Lavalink REST API. */ interface LavalinkPlayer { /** * The guild ID associated with the player. * @type {string} */ guildId: string; /** * The track currently being played. * @type {LavalinkTrack} */ track?: LavalinkTrack; /** * The volume of the player. * @type {number} */ volume: number; /** * Whether the player is paused. * @type {boolean} */ paused: boolean; /** * The voice connection details. * @type {LavalinkPlayerVoice} */ voice: LavalinkPlayerVoice; /** * The filter options applied to the player. * @type {FilterSettings} */ filters: FilterSettings; /** * The state of the player. * @type {LavalinkPlayerState} */ state: LavalinkPlayerState; } /** * The state of the player. */ interface LavalinkPlayerState { /** * The time since the connection was established. * @type {number} */ time: number; /** * The position of the current track in milliseconds. * @type {number} */ position: number; /** * Whether the player is connected to the voice channel. * @type {boolean} */ connected: boolean; /** * The ping to the voice server in milliseconds. * @type {number} */ ping: number; } /** * The options to update the player. */ interface UpdatePlayerInfo { /** * The guild id associated with the player. * @type {string} */ guildId: string; /** * The options to update the player. * @type {LavalinkPlayOptions} */ playerOptions: LavalinkPlayOptions; /** * Whether to replace the current track. * @type {boolean | undefined} * @default false */ noReplace?: boolean; } /** * The updated session of the current session. */ interface LavalinkSession { /** * Whether the session is resuming. * @type {boolean} */ resuming: boolean; /** * The timeout for the session. * @type {number} */ timeout: number; } /** * The rest options. */ interface HoshimiRestOptions { /** * The amount of time to wait for the player to resume. (in milliseconds) * @type {number} * @default 10000 */ resumeTimeout?: number; /** * The default REST request timeout applied to nodes that do not set their own `restTimeout`. (in milliseconds) * @type {number} * @default 10000 */ restTimeout?: number; } /** * The methods for decoding base64 encoded tracks. */ interface DecodeMethods { /** * * Decodes a single base64 encoded track. * @param {string} track The base64 encoded track. * @param {TrackRequester} requester The requester of the track. * @returns {Promise} The decoded track. * @example * ```ts * const node = player.node; * const track = await node.decode.single("base64EncodedTrack"); * console.log(track.info.title); // Track Title * ``` */ single(track: string, requester: TrackRequester): Promise; /** * Decodes multiple base64 encoded tracks. * @param {string[]} tracks The base64 encoded tracks. * @param {TrackRequester} requester The requester of the tracks. * @returns {Promise} The decoded tracks. * @example * ```ts * const node = player.node; * const tracks = await node.decode.multiple(["base64EncodedTrack1", "base64EncodedTrack2"]); * console.log(tracks[0].info.title); // Track Title 1 * console.log(tracks[1].info.title); // Track Title 2 * ``` */ multiple(tracks: string[], requester: TrackRequester): Promise; } /** * The options for resuming a session. */ interface SessionResumingOptions { /** * Whether the session is resuming. * @type {boolean} */ resuming: boolean; /** * The timeout for resuming the session in milliseconds. * @type {number | null | undefined} */ timeout?: number | null; } /** * The session of the node. */ type NullableLavalinkSession = PickNullable; /** * The REST endpoint type. */ type RestEndpoint = `/${string}`; //#endregion //#region src/classes/Errors.d.ts /** * Error class for the manager. * @class ManagerError * @extends {Error} */ declare class ManagerError extends Error { name: string; } /** * Error class for invalid options. * @class OptionError * @extends {Error} */ declare class OptionError extends Error { name: string; } /** * Error class for the player. * @class PlayerError * @extends {Error} */ declare class PlayerError extends Error { name: string; } /** * Error class for the node. * @class NodeError * @extends {Error} */ declare class NodeError extends Error { constructor({ message, id }: NodeErrorOptions); } /** * Error class for the storage. * @class StorageError * @extends {Error} */ declare class StorageError extends Error { name: string; } /** * Error class for the node manager. * @class NodeManagerError * @extends {Error} */ declare class NodeManagerError extends Error { name: string; } /** * Error class for resolving tracks. * @class ResolveError * @extends {Error} */ declare class ResolveError extends Error { name: string; } /** * Error class for merging nodes. * @class MergeError * @extends {Error} */ declare class MergeError extends Error { name: string; } declare class QueueError extends Error { name: string; } /** * The RestError class has been taken from Shoukaku library. * A cute and epic lavalink wrapper, made in typescript. * So, all the credits goes to the original author. * @link https://github.com/shipgirlproject/Shoukaku/blob/master/src/node/Rest.ts */ /** * Class representing a REST error. * @class RestError * @extends {Error} */ declare class RestError extends Error { /** * The timestamp of the response. * @type {number} */ timestamp: number; /** * The status of the response. * @type {number} */ status: number; /** * The error of the response. * @type {string} */ error: string; /** * The path of the response. * @type {string} */ path: string; /** * The trace of the response. * @type {string} */ trace?: string; /** * * Create a new REST error. */ constructor({ timestamp, status, error, trace, message, path }: LavalinkRestError); } /** * Error options for the node. */ interface NodeErrorOptions { /** * The message of the error. * @type {string} */ message: string; /** * The id of the node. * @type {string} */ id: string; } //#endregion //#region src/classes/storage/PlayerMemory.d.ts /** * Class representing a player storage. * @class PlayerMemoryStorage * @extends {PlayerStorageAdapter} */ declare class PlayerMemoryStorage = StorageValues> extends PlayerStorageAdapter { get>(key: K): Awaitable; set>(key: K, value: V): Awaitable; has(key: K): Awaitable; delete(key: K): Awaitable; keys(): Awaitable; values>(): Awaitable; entries>(): Awaitable<[K, V][]>; all>(): Awaitable>; setIfAbsent>(key: K, value: V): boolean; clear(): Awaitable; size(): Awaitable; destroy(): Awaitable; } //#endregion //#region src/classes/storage/QueueMemory.d.ts /** * Class representing a memory storage manager. * @class QueueMemoryStorage * @extends {QueueStorageAdapter} */ declare class QueueMemoryStorage extends QueueStorageAdapter { get(key: string): T | undefined; set(key: string, value: T): void; delete(key: string): boolean; clear(): void; has(key: string): boolean; parse(value: unknown): T; stringify(value: unknown): R; } //#endregion //#region src/util/constants.d.ts /** * The auto output record type. */ type AudioOutputRecord = Record>; /** * The user agent for Hoshimi. * @type {UserAgent} */ declare const HoshimiAgent: UserAgent; /** * The url regex for Hoshimi. * @type {RegExp} */ declare const UrlRegex: RegExp; /** * The audio output data for Hoshimi. * @type {Readonly>>} */ declare const AudioOutputData: Readonly; /** * The default filter presets. */ declare const DefaultFilterPreset: Readonly<{ Karaoke: { level: number; monoLevel: number; filterBand: number; filterWidth: number; }; Vaporwave: { speed: number; pitch: number; rate: number; }; Nightcore: { speed: number; pitch: number; rate: number; }; Lowpass: { smoothing: number; }; Tremolo: { frequency: number; depth: number; }; Vibrato: { frequency: number; depth: number; }; Distortion: { cosOffset: number; sinOffset: number; tanOffset: number; offset: number; scale: number; cosScale: number; sinScale: number; tanScale: number; }; DSPXHighPass: { boostFactor: number; cutoffFrequency: number; }; DSPXLowPass: { boostFactor: number; cutoffFrequency: number; }; DSPXNormalization: { adaptive: boolean; maxAmplitude: number; }; DSPXEcho: { decay: number; echoLength: number; }; PluginEcho: { decay: number; delay: number; }; PluginReverb: { delays: number[]; gains: number[]; }; }>; /** * The valid loop mode values. * @type {LoopMode[]} */ declare const LoopValues: LoopMode[]; /** * The default options for Hoshimi. * @type {Readonly} */ declare const HoshimiDefaultOptions: Readonly; //#endregion //#region src/util/events/player.d.ts /** * * Resumes players by library. The default handler for {@link NodeSessionOptions.byLibrary}; exported * so a custom `resumeFn` can reuse or wrap it. * @param {NodeStructure} node The node that is resuming the players. * @param {PlayerStructure[]} players The players to be resumed. * @returns {Promise} */ declare function resumeByLibrary(node: NodeStructure, players: PlayerStructure[]): Promise; //#endregion //#region src/util/functions/track.d.ts /** * Check whether a track is a local Track instance (resolved). * Only returns true for Track class instances (not generic LavalinkTrack objects). * @param {TrackResolvableStructure | LavalinkTrack | UnresolvedLavalinkTrack} track The track to check. * @returns {boolean} True when the track is a local resolved Track instance. */ declare function isResolved(track: TrackResolvableStructure | AnyLavalinkTrack): track is TrackStructure; /** * Check whether a track is a local UnresolvedTrack instance (unresolved). * Only returns true for UnresolvedTrack class instances. * @param {TrackResolvableStructure | LavalinkTrack | UnresolvedLavalinkTrack} track The track to check. * @returns {boolean} True when the track is a local unresolved UnresolvedTrack instance. */ declare function isUnresolved(track: TrackResolvableStructure | AnyLavalinkTrack): track is UnresolvedTrack; /** * Check whether a track is a Lavalink-compatible resolved track (not a local Track instance). * Returns true for LavalinkTrack objects that have encoded and info but are not Track class instances. * This is for raw Lavalink track objects from the API or other sources. * @param {TrackResolvableStructure | LavalinkTrack | UnresolvedLavalinkTrack} track The track to check. * @returns {boolean} True when the track is a Lavalink resolved track (not a local Track). */ declare function isLavalinkResolved(track: TrackResolvableStructure | AnyLavalinkTrack): track is LavalinkTrack; /** * Check whether a track is a Lavalink-compatible unresolved track (not a local UnresolvedTrack instance). * Returns true for UnresolvedLavalinkTrack objects that have a resolve-like structure but are not UnresolvedTrack instances. * @param {TrackResolvableStructure | LavalinkTrack | UnresolvedLavalinkTrack} track The track to check. * @returns {boolean} True when the track is a Lavalink unresolved track (not a local UnresolvedTrack). */ declare function isLavalinkUnresolved(track: TrackResolvableStructure | AnyLavalinkTrack): track is UnresolvedLavalinkTrack; /** * Check whether a track is a stored track (has the structure of a TrackJSON object). * This is used to identify tracks that come from storage and need to be transformed back into Track instances. * @param {TrackResolvableStructure | LavalinkTrack | UnresolvedLavalinkTrack} track The track to check. * @returns {boolean} True when the track is a stored track (TrackJSON structure). */ declare function isStoredTrack(track: TrackResolvableStructure | AnyLavalinkTrack): track is TrackJSON; /** * * A collection of utility functions for track resolution and type checking. * @constant */ declare const TrackResolution: { readonly isResolved: typeof isResolved; readonly isUnresolved: typeof isUnresolved; readonly isLavalinkResolved: typeof isLavalinkResolved; readonly isLavalinkUnresolved: typeof isLavalinkUnresolved; readonly isStoredTrack: typeof isStoredTrack; }; //#endregion export { AnyLavalinkTrack, AudioOutput, AudioOutputData, Awaitable, CapabilityKey, ChannelDelete, ChannelDeletePacket, ChannelMixSettings, ClientInfo, CustomSearchSources, CustomSourceNames, CustomizableFilterSettings, CustomizableFilters, CustomizablePlayerStorage, CustomizablePluginCapabilities, CustomizablePluginNames, CustomizablePluginPayloads, CustomizableSources, CustomizableStructures, CustomizableTrack, DSPXPluginFilter, DebugLevels, DecodeMethods, DeepRequired, DefaultFilterPreset, DestroyOptions, DestroyReasons, DisconnectPlayerActions, DistortionSettings, EQBandSettings, EchoSettings, EmptyResult, ErrorPlayerActions, ErrorResult, EventKey, EventListener, EventMap, EventNames, Exception, FetchOptions, FilterManager, FilterManagerStructure, FilterNameKey, FilterPayloads, FilterPluginPassSettings, FilterRegistration, FilterRegistry, FilterRoute, FilterScope, FilterSettings, FilterType, FreqSettings, GatewayPayload, GatewaySendPayload, Hint, Hoshimi, HoshimiAgent, HoshimiDefaultOptions, HoshimiEvents, HoshimiNodeOptions, HoshimiOptions, HoshimiPlayerOptions, HoshimiQueueOptions, HoshimiRestOptions, HttpMethods, HttpStatusCodes, If, InferCustomStructure, Inferable, KaraokeSettings, LavalinkEventPayload, LavalinkFilterPluginEchoSettings, LavalinkFilterPluginReverbSettings, LavalinkFilterPluginSettings, LavalinkPlayOptions, LavalinkPlayer, LavalinkPlayerState, LavalinkPlayerVoice, LavalinkPluginFilter, LavalinkRestError, LavalinkSearchResponse, LavalinkSession, LavalinkTrack, LoadType, LoopMode, LoopValues, LowPassSettings, LyricsFoundEvent, LyricsLine, LyricsLineEvent, LyricsManager, LyricsManagerStructure, LyricsMethods, LyricsNotFoundEvent, LyricsResult, ManagerError, MergeError, Node, NodeCpu, NodeDestroyInfo, NodeDestroyReasons, NodeDisconnectInfo, NodeError, NodeFrameStats, NodeHeartbeatOptions, NodeIdentifier, NodeInfo, NodeInfoGit, NodeInfoPlugin, NodeInfoVersion, NodeJSON, NodeManager, NodeManagerError, NodeManagerStructure, NodeMemory, NodeOptions, NodePlayerMoveOptions, NodeSessionOptions, NodeSortFilter, NodeSortFunction, NodeSortTypes, NodeStructure, NormalizationSettings, Nullable, NullableLavalinkSession, NullableVoiceChannelUpdate, Omit$1 as Omit, OpCodes, OptionError, ParsedQuery, PayloadOf, PickNullable, PickRequired, PlayOptions, Player, PlayerError, PlayerEvent, PlayerEventType, PlayerJSON, PlayerMemoryStorage, PlayerOptions, PlayerScope, PlayerStorageAdapter, PlayerStorageAdapterStructure, PlayerStructure, PlayerUpdate, PlayerUpdateState, PlayerVoice, PlayerVoiceState, PlayerVoiceStateStructure, Playlist, PlaylistInfo, PlaylistResult, PluginCapabilities, PluginFilterSettings, PluginInfo, PluginInfoType, PluginNameKey, PluginNames, PluginRegistration, PluginRegistry, Prettify, QueryResult, Queue, QueueError, QueueJSON, QueueMemoryStorage, QueueStorageAdapter, QueueStructure, Ready, RegistryCapability, RegistryFilterName, RegistryPluginName, RegistrySearchSource, RegistrySourceName, RequiredHoshimiNodeOptions, RequiredHoshimiOptions, ResolveError, Rest, RestEndpoint, RestError, RestOptions, RestOrArray, RestPathType, RestRoutes, RestStructure, ResumableHeaders, RotationSettings, SearchOptions, SearchQuery, SearchResult, SearchSource, SearchSourceKey, SearchSources, SessionResumingOptions, SetFilterOptions, Severity, SkipOptions, SourceName, SourceNames, SourceProtocol, SourceRegistration, SourceRegistry, State, Stats, StopOptions, StorageError, StorageKeys, StorageValues, Structures, SyncOptions, TimescaleSettings, Track, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackInfo, TrackJSON, TrackRequester, TrackResolution, TrackResolvableStructure, TrackResult, TrackStartEvent, TrackStructure, TrackStuckEvent, TrackUserData, TremoloSettings, TypedEmitter, UnresolvedLavalinkTrack, UnresolvedTrack, UnresolvedTrackInfo, UnresolvedTrackStructure, UpdatePlayerInfo, UrlRegex, UserAgent, ValidateFilterOptions, ValidatePluginsOptions, VoiceChannelUpdate, VoiceDataUpdate, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent, WebsocketCloseCodes, createHoshimi, defineFilter, resumeByLibrary };