Socket
Socket
Sign inDemoInstall

distube

Package Overview
Dependencies
170
Maintainers
1
Versions
193
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.0.0-beta.36 to 3.0.0-beta.37

dist/struct/__mocks__/Queue.d.ts

41

dist/constant.d.ts
import type { Filters } from ".";
/**
* Default DisTube audio filters.
* @typedef {Object} DefaultFilters
* @typedef {Object} defaultFilters
* @prop {string} 3d 3d

@@ -26,17 +26,25 @@ * @prop {string} bassboost bassboost

* @prop {Array<CustomPlugin|ExtractorPlugin>} [plugins] DisTube plugins.
* @prop {boolean} [emitNewSongOnly=false] If `true`, {@link DisTube#event:playSong} will not be emitted when looping a song or next song is the same as the previous one
* @prop {boolean} [leaveOnEmpty=true] Whether or not leaving voice channel if the voice channel is empty after {@link DisTubeOptions}.emptyCooldown seconds.
* @prop {boolean} [emitNewSongOnly=false] Whether or not emitting {@link DisTube#event:playSong} event
* when looping a song or next song is the same as the previous one
* @prop {boolean} [leaveOnEmpty=true] Whether or not leaving voice channel
* if the voice channel is empty after {@link DisTubeOptions}.emptyCooldown seconds.
* @prop {boolean} [leaveOnFinish=false] Whether or not leaving voice channel when the queue ends.
* @prop {boolean} [leaveOnStop=true] Whether or not leaving voice channel after using {@link DisTube#stop} function.
* @prop {boolean} [savePreviousSongs=true] Whether or not saving the previous songs of the queue and enable {@link DisTube#previous} method
* @prop {number} [searchSongs=0] Limit of search results emits in {@link DisTube#event:searchResult} event when {@link DisTube#play} method executed. If `searchSongs <= 1`, play the first result
* @prop {string} [youtubeCookie] YouTube cookies. Read how to get it in {@link https://github.com/fent/node-ytdl-core/blob/997efdd5dd9063363f6ef668bb364e83970756e7/example/cookies.js#L6-L12|YTDL's Example}
* @prop {string} [youtubeIdentityToken] If not given; ytdl-core will try to find it. You can find this by going to a video's watch page; viewing the source; and searching for "ID_TOKEN".
* @prop {boolean} [savePreviousSongs=true] Whether or not saving the previous songs of the queue
* and enable {@link DisTube#previous} method
* @prop {number} [searchSongs=0] Limit of search results emits in {@link DisTube#event:searchResult} event
* when {@link DisTube#play} method executed. If `searchSongs <= 1`, play the first result
* @prop {string} [youtubeCookie] YouTube cookies. Read how to get it in
* {@link https://github.com/fent/node-ytdl-core/blob/997efdd5dd9063363f6ef668bb364e83970756e7/example/cookies.js#L6-L12|YTDL's Example}
* @prop {string} [youtubeIdentityToken] If not given; ytdl-core will try to find it.
* You can find this by going to a video's watch page; viewing the source; and searching for "ID_TOKEN".
* @prop {boolean} [youtubeDL=true] Whether or not using youtube-dl.
* @prop {boolean} [updateYouTubeDL=true] Whether or not updating youtube-dl automatically.
* @prop {Filters} [customFilters] Override {@link defaultFilters} or add more ffmpeg filters. Example=`{ "Filter name"="Filter value"; "8d"="apulsator=hz=0.075" }`
* @prop {Filters} [customFilters] Override {@link defaultFilters} or add more ffmpeg filters.
* Example=`{ "Filter name"="Filter value"; "8d"="apulsator=hz=0.075" }`
* @prop {ytdl.getInfoOptions} [ytdlOptions] `ytdl-core` get info options
* @prop {number} [searchCooldown=60] Built-in search cooldown in seconds (When searchSongs is bigger than 0)
* @prop {number} [emptyCooldown=60] Built-in leave on empty cooldown in seconds (When leaveOnEmpty is true)
* @prop {boolean} [nsfw=false] Whether or not playing age-restricted content and disabling safe search in non-NSFW channel.
* @prop {boolean} [nsfw=false] Whether or not playing age-restricted content
* and disabling safe search in non-NSFW channel.
* @prop {boolean} [emitAddListWhenCreatingQueue=true] Whether or not emitting `addList` event when creating a new Queue

@@ -75,3 +83,16 @@ * @prop {boolean} [emitAddSongWhenCreatingQueue=true] Whether or not emitting `addSong` event when creating a new Queue

* - A {@link Queue}
* @typedef {Queue|Discord.Snowflake|Discord.Message|Discord.VoiceChannel|Discord.StageChannel|Discord.VoiceState|Discord.TextChannel|Discord.GuildMember|Discord.Interaction|string} GuildIDResolvable
* - A {@link DisTubeVoice}
* @typedef {
* Discord.Snowflake|
* Discord.Message|
* Discord.VoiceChannel|
* Discord.StageChannel|
* Discord.VoiceState|
* Discord.TextChannel|
* Discord.GuildMember|
* Discord.Interaction|
* DisTubeVoice|
* Queue|
* string
* } GuildIDResolvable
*/

@@ -78,0 +99,0 @@ /**

@@ -6,3 +6,3 @@ "use strict";

* Default DisTube audio filters.
* @typedef {Object} DefaultFilters
* @typedef {Object} defaultFilters
* @prop {string} 3d 3d

@@ -45,17 +45,25 @@ * @prop {string} bassboost bassboost

* @prop {Array<CustomPlugin|ExtractorPlugin>} [plugins] DisTube plugins.
* @prop {boolean} [emitNewSongOnly=false] If `true`, {@link DisTube#event:playSong} will not be emitted when looping a song or next song is the same as the previous one
* @prop {boolean} [leaveOnEmpty=true] Whether or not leaving voice channel if the voice channel is empty after {@link DisTubeOptions}.emptyCooldown seconds.
* @prop {boolean} [emitNewSongOnly=false] Whether or not emitting {@link DisTube#event:playSong} event
* when looping a song or next song is the same as the previous one
* @prop {boolean} [leaveOnEmpty=true] Whether or not leaving voice channel
* if the voice channel is empty after {@link DisTubeOptions}.emptyCooldown seconds.
* @prop {boolean} [leaveOnFinish=false] Whether or not leaving voice channel when the queue ends.
* @prop {boolean} [leaveOnStop=true] Whether or not leaving voice channel after using {@link DisTube#stop} function.
* @prop {boolean} [savePreviousSongs=true] Whether or not saving the previous songs of the queue and enable {@link DisTube#previous} method
* @prop {number} [searchSongs=0] Limit of search results emits in {@link DisTube#event:searchResult} event when {@link DisTube#play} method executed. If `searchSongs <= 1`, play the first result
* @prop {string} [youtubeCookie] YouTube cookies. Read how to get it in {@link https://github.com/fent/node-ytdl-core/blob/997efdd5dd9063363f6ef668bb364e83970756e7/example/cookies.js#L6-L12|YTDL's Example}
* @prop {string} [youtubeIdentityToken] If not given; ytdl-core will try to find it. You can find this by going to a video's watch page; viewing the source; and searching for "ID_TOKEN".
* @prop {boolean} [savePreviousSongs=true] Whether or not saving the previous songs of the queue
* and enable {@link DisTube#previous} method
* @prop {number} [searchSongs=0] Limit of search results emits in {@link DisTube#event:searchResult} event
* when {@link DisTube#play} method executed. If `searchSongs <= 1`, play the first result
* @prop {string} [youtubeCookie] YouTube cookies. Read how to get it in
* {@link https://github.com/fent/node-ytdl-core/blob/997efdd5dd9063363f6ef668bb364e83970756e7/example/cookies.js#L6-L12|YTDL's Example}
* @prop {string} [youtubeIdentityToken] If not given; ytdl-core will try to find it.
* You can find this by going to a video's watch page; viewing the source; and searching for "ID_TOKEN".
* @prop {boolean} [youtubeDL=true] Whether or not using youtube-dl.
* @prop {boolean} [updateYouTubeDL=true] Whether or not updating youtube-dl automatically.
* @prop {Filters} [customFilters] Override {@link defaultFilters} or add more ffmpeg filters. Example=`{ "Filter name"="Filter value"; "8d"="apulsator=hz=0.075" }`
* @prop {Filters} [customFilters] Override {@link defaultFilters} or add more ffmpeg filters.
* Example=`{ "Filter name"="Filter value"; "8d"="apulsator=hz=0.075" }`
* @prop {ytdl.getInfoOptions} [ytdlOptions] `ytdl-core` get info options
* @prop {number} [searchCooldown=60] Built-in search cooldown in seconds (When searchSongs is bigger than 0)
* @prop {number} [emptyCooldown=60] Built-in leave on empty cooldown in seconds (When leaveOnEmpty is true)
* @prop {boolean} [nsfw=false] Whether or not playing age-restricted content and disabling safe search in non-NSFW channel.
* @prop {boolean} [nsfw=false] Whether or not playing age-restricted content
* and disabling safe search in non-NSFW channel.
* @prop {boolean} [emitAddListWhenCreatingQueue=true] Whether or not emitting `addList` event when creating a new Queue

@@ -94,3 +102,16 @@ * @prop {boolean} [emitAddSongWhenCreatingQueue=true] Whether or not emitting `addSong` event when creating a new Queue

* - A {@link Queue}
* @typedef {Queue|Discord.Snowflake|Discord.Message|Discord.VoiceChannel|Discord.StageChannel|Discord.VoiceState|Discord.TextChannel|Discord.GuildMember|Discord.Interaction|string} GuildIDResolvable
* - A {@link DisTubeVoice}
* @typedef {
* Discord.Snowflake|
* Discord.Message|
* Discord.VoiceChannel|
* Discord.StageChannel|
* Discord.VoiceState|
* Discord.TextChannel|
* Discord.GuildMember|
* Discord.Interaction|
* DisTubeVoice|
* Queue|
* string
* } GuildIDResolvable
*/

@@ -97,0 +118,0 @@ /**

@@ -1,5 +0,3 @@

import type DisTube from "../DisTube";
import type DisTubeHandler from "./DisTubeHandler";
import type { Client, TextChannel } from "discord.js";
import type { DisTubeVoiceManager, Options, QueueManager } from ".";
import type { DisTube, DisTubeEvents, DisTubeHandler, DisTubeVoiceManager, Options, QueueManager } from "..";
/** @private */

@@ -11,3 +9,2 @@ export declare class DisTubeBase {

* Emit the {@link DisTube} of this base
* @private
* @param {string} eventName Event name

@@ -17,3 +14,3 @@ * @param {...any} args arguments

*/
emit(eventName: string, ...args: any[]): boolean;
emit(eventName: keyof DisTubeEvents, ...args: any): boolean;
/**

@@ -23,3 +20,2 @@ * Emit error event

* @param {Discord.TextChannel?} channel Text channel where the error is encountered.
* @private
*/

@@ -31,3 +27,2 @@ emitError(error: Error, channel?: TextChannel): void;

* @readonly
* @private
*/

@@ -39,3 +34,2 @@ get queues(): QueueManager;

* @readonly
* @private
*/

@@ -47,3 +41,2 @@ get voices(): DisTubeVoiceManager;

* @readonly
* @private
*/

@@ -55,3 +48,2 @@ get client(): Client;

* @readonly
* @private
*/

@@ -63,3 +55,2 @@ get options(): Options;

* @readonly
* @private
*/

@@ -66,0 +57,0 @@ get handler(): DisTubeHandler;

@@ -10,3 +10,2 @@ "use strict";

* @type {DisTube}
* @private
*/

@@ -17,3 +16,2 @@ this.distube = distube;

* Emit the {@link DisTube} of this base
* @private
* @param {string} eventName Event name

@@ -30,3 +28,2 @@ * @param {...any} args arguments

* @param {Discord.TextChannel?} channel Text channel where the error is encountered.
* @private
*/

@@ -40,3 +37,2 @@ emitError(error, channel) {

* @readonly
* @private
*/

@@ -50,3 +46,2 @@ get queues() {

* @readonly
* @private
*/

@@ -60,3 +55,2 @@ get voices() {

* @readonly
* @private
*/

@@ -70,3 +64,2 @@ get client() {

* @readonly
* @private
*/

@@ -80,3 +73,2 @@ get options() {

* @readonly
* @private
*/

@@ -83,0 +75,0 @@ get handler() {

import ytdl from "@distube/ytdl-core";
import { DisTubeBase, DisTubeStream } from ".";
import { Playlist, Queue, SearchResult, Song } from "..";
import type DisTube from "../DisTube";
import type { OtherSongInfo } from "..";
import type { DisTube, OtherSongInfo } from "..";
import type { GuildMember, Message, StageChannel, TextChannel, VoiceChannel } from "discord.js";

@@ -17,3 +16,3 @@ /**

* Create a new guild queue
* @param {Discord.Message|Discord.VoiceChannel|Discord.StageChannel} message A message from guild channel | a voice channel
* @param {Discord.Message|Discord.VoiceChannel|Discord.StageChannel} message A user message | a voice channel
* @param {Song|Song[]} song Song to play

@@ -53,2 +52,8 @@ * @param {Discord.TextChannel} textChannel A text channel of the queue

* @param {boolean} [parallel=true] Whether or not fetch the songs in parallel
* @example
* const songs = ["https://www.youtube.com/watch?v=xxx", "https://www.youtube.com/watch?v=yyy"];
* const playlist = await distube.handler.createCustomPlaylist(member, songs, { name: "My playlist name" }, true);
* // Or fetching custom playlist sequentially (reduce lag for low specs)
* const playlist = await distube.handler.createCustomPlaylist(member, songs, false);
* distube.playVoiceChannel(voiceChannel, playlist, { ... });
*/

@@ -59,3 +64,3 @@ createCustomPlaylist(message: Message | GuildMember, songs: (string | Song | SearchResult)[], properties?: any, parallel?: boolean): Promise<Playlist>;

* @returns {Promise<void>}
* @param {Discord.Message|Discord.VoiceChannel|Discord.StageChannel} message A message from guild channel | a voice channel
* @param {Discord.Message|Discord.VoiceChannel|Discord.StageChannel} message A message | a voice channel
* @param {Playlist|string} playlist A YouTube playlist url | a Playlist

@@ -62,0 +67,0 @@ * @param {Discord.TextChannel|boolean} [textChannel] The default text channel of the queue

@@ -31,6 +31,38 @@ "use strict";

}
const client = this.client;
if (this.options.leaveOnEmpty) {
client.on("voiceStateUpdate", oldState => {
if (!(oldState === null || oldState === void 0 ? void 0 : oldState.channel))
return;
const queue = this.queues.get(oldState);
if (!queue) {
if ((0, __1.isVoiceChannelEmpty)(oldState)) {
setTimeout(() => {
if (!this.queues.get(oldState) && (0, __1.isVoiceChannelEmpty)(oldState))
this.voices.leave(oldState);
}, this.options.emptyCooldown * 1e3).unref();
}
return;
}
if (queue.emptyTimeout) {
clearTimeout(queue.emptyTimeout);
delete queue.emptyTimeout;
}
if ((0, __1.isVoiceChannelEmpty)(oldState)) {
queue.emptyTimeout = setTimeout(() => {
delete queue.emptyTimeout;
if ((0, __1.isVoiceChannelEmpty)(oldState)) {
queue.voice.leave();
this.emit("empty", queue);
if (queue.stopped)
queue.delete();
}
}, this.options.emptyCooldown * 1e3).unref();
}
});
}
}
/**
* Create a new guild queue
* @param {Discord.Message|Discord.VoiceChannel|Discord.StageChannel} message A message from guild channel | a voice channel
* @param {Discord.Message|Discord.VoiceChannel|Discord.StageChannel} message A user message | a voice channel
* @param {Song|Song[]} song Song to play

@@ -44,5 +76,5 @@ * @param {Discord.TextChannel} textChannel A text channel of the queue

const voice = ((_c = (_b = (_a = message) === null || _a === void 0 ? void 0 : _a.member) === null || _b === void 0 ? void 0 : _b.voice) === null || _c === void 0 ? void 0 : _c.channel) || message;
if (!voice || __1.isMessageInstance(voice))
if (!voice || (0, __1.isMessageInstance)(voice))
throw new __1.DisTubeError("NOT_IN_VOICE");
if (!__1.isSupportedVoiceChannel(voice))
if (!(0, __1.isSupportedVoiceChannel)(voice))
throw new __1.DisTubeError("NOT_SUPPORTED_VOICE");

@@ -81,3 +113,3 @@ return this.queues.create(voice, song, textChannel);

return new __1.Song(await this.getYouTubeInfo(song), member);
if (__1.isURL(song)) {
if ((0, __1.isURL)(song)) {
for (const plugin of this.distube.extractorPlugins) {

@@ -103,3 +135,3 @@ if (await plugin.validate(song))

if (typeof playlist === "string") {
solvablePlaylist = await ytpl_1.default(playlist, { limit: Infinity });
solvablePlaylist = await (0, ytpl_1.default)(playlist, { limit: Infinity });
solvablePlaylist.items = solvablePlaylist.items

@@ -121,2 +153,8 @@ .filter(v => !v.thumbnail.includes("no_thumbnail"))

* @param {boolean} [parallel=true] Whether or not fetch the songs in parallel
* @example
* const songs = ["https://www.youtube.com/watch?v=xxx", "https://www.youtube.com/watch?v=yyy"];
* const playlist = await distube.handler.createCustomPlaylist(member, songs, { name: "My playlist name" }, true);
* // Or fetching custom playlist sequentially (reduce lag for low specs)
* const playlist = await distube.handler.createCustomPlaylist(member, songs, false);
* distube.playVoiceChannel(voiceChannel, playlist, { ... });
*/

@@ -129,4 +167,4 @@ async createCustomPlaylist(message, songs, properties = {}, parallel = true) {

if (!songs.length)
throw new __1.DisTubeError("EMPTY_ARRAY");
songs = songs.filter(song => song instanceof __1.Song || (song instanceof __1.SearchResult && song.type === "video") || __1.isURL(song));
throw new __1.DisTubeError("EMPTY_ARRAY", "songs");
songs = songs.filter(song => song instanceof __1.Song || (song instanceof __1.SearchResult && song.type === "video") || (0, __1.isURL)(song));
if (!songs.length)

@@ -151,3 +189,3 @@ throw new __1.DisTubeError("NO_VALID_SONG");

* @returns {Promise<void>}
* @param {Discord.Message|Discord.VoiceChannel|Discord.StageChannel} message A message from guild channel | a voice channel
* @param {Discord.Message|Discord.VoiceChannel|Discord.StageChannel} message A message | a voice channel
* @param {Playlist|string} playlist A YouTube playlist url | a Playlist

@@ -195,7 +233,15 @@ * @param {Discord.TextChannel|boolean} [textChannel] The default text channel of the queue

if (this.options.searchSongs > 1) {
for (const evn of ["searchNoResult", "searchResult", "searchCancel", "searchInvalidAnswer", "searchDone"]) {
const searchEvents = [
"searchNoResult",
"searchResult",
"searchCancel",
"searchInvalidAnswer",
"searchDone",
];
for (const evn of searchEvents) {
if (this.distube.listenerCount(evn) === 0) {
/* eslint-disable no-console */
console.warn(`"searchSongs" option is disabled due to missing "${evn}" listener.`);
console.warn(`If you don't want to use "${evn}" event, simply add an empty listener (not recommended):\n<DisTube>.on("${evn}", () => {})`);
console.warn(`If you don't want to use "${evn}" event, simply add an empty listener (not recommended):\n` +
`<DisTube>.on("${evn}", () => {})`);
/* eslint-enable no-console */

@@ -202,0 +248,0 @@ this.options.searchSongs = 0;

import type ytdl from "@distube/ytdl-core";
import type { CustomPlugin, DisTubeOptions, ExtractorPlugin, Filters } from "..";
export declare class Options {
/** DisTube plugins.*/
plugins: (CustomPlugin | ExtractorPlugin)[];
/** If `true`, {@link DisTube#event:playSong} will not be emitted when looping a song or next song is the same as the previous one */
emitNewSongOnly: boolean;
/** Whether or not leaving voice channel when the queue finishes. */
leaveOnFinish: boolean;
/** Whether or not leaving voice channel after using {@link DisTube#stop} function. */
leaveOnStop: boolean;
/** Whether or not leaving voice channel if the voice channel is empty after {@link DisTubeOptions}.emptyCooldown seconds. */
leaveOnEmpty: boolean;
/** Built-in leave on empty cooldown in seconds (When leaveOnEmpty is true) */
emptyCooldown: number;
/** Whether or not saving the previous songs of the queue and enable {@link DisTube#previous} method */
savePreviousSongs: boolean;
/** Limit of search results emits in {@link DisTube#event:searchResult} event when {@link DisTube#play} method executed. If `searchSongs <= 1`, play the first result */
searchSongs: number;
/** Built-in search cooldown in seconds (When `searchSongs` is bigger than 0) */
searchCooldown: number;
/** YouTube cookies. Read how to get it in {@link https://github.com/fent/node-ytdl-core/blob/997efdd5dd9063363f6ef668bb364e83970756e7/example/cookies.js#L6-L12|YTDL's Example} */
youtubeCookie?: string;
/** If not given; ytdl-core will try to find it. You can find this by going to a video's watch page; viewing the source; and searching for "ID_TOKEN". */
youtubeIdentityToken?: string;
/** Whether or not using youtube-dl. */
youtubeDL: boolean;
/** Whether or not updating youtube-dl automatically. */
updateYouTubeDL: boolean;
/** Override {@link DefaultFilters} or add more ffmpeg filters. Example=`{ "Filter name"="Filter value"; "8d"="apulsator=hz=0.075" }` */
customFilters: Filters;
/** `ytdl-core` get info options */
ytdlOptions: ytdl.getInfoOptions;
/** Whether or not playing age-restricted content and disabling safe search when using {@link DisTube#play} in non-NSFW channel. */
nsfw: boolean;
/** Whether or not emitting `addList` event when creating a new Queue */
emitAddSongWhenCreatingQueue: boolean;
/** Whether or not emitting `addSong` event when creating a new Queue */
emitAddListWhenCreatingQueue: boolean;

@@ -40,0 +22,0 @@ constructor(options: DisTubeOptions);

@@ -31,3 +31,3 @@ "use strict";

this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;
__1.checkInvalidKey(opts, this, "DisTubeOptions");
(0, __1.checkInvalidKey)(opts, this, "DisTubeOptions");
this._validateOptions();

@@ -34,0 +34,0 @@ }

@@ -17,10 +17,2 @@ "use strict";

exports.chooseBestVideoFormat = chooseBestVideoFormat;
// Use ffmpeg libopus codec
// function libopusSupport(): boolean {
// try {
// return FFmpeg.getInfo().output.includes("--enable-libopus");
// } catch { }
// return false;
// }
// const supportOggOpus = libopusSupport();
/**

@@ -38,2 +30,3 @@ * Create a stream to play with {@link DisTubeVoice}

this.url = url;
this.type = voice_1.StreamType.Raw;
const args = [

@@ -56,13 +49,7 @@ "-reconnect",

"2",
"-f",
"s16le",
];
// Use ffmpeg libopus codec
// if (supportOggOpus) {
// args.push("-acodec", "libopus", "-f", "opus");
// this.type = StreamType.OggOpus;
// } else {
args.push("-f", "s16le");
this.type = voice_1.StreamType.Raw;
// }
if (typeof options.seek === "number" && options.seek > 0) {
args.push("-ss", options.seek.toString());
args.unshift("-ss", options.seek.toString());
}

@@ -86,3 +73,3 @@ if (Array.isArray(options.ffmpegArgs)) {

}
const bestFormat = exports.chooseBestVideoFormat(formats, options.isLive);
const bestFormat = (0, exports.chooseBestVideoFormat)(formats, options.isLive);
if (!bestFormat)

@@ -102,3 +89,3 @@ throw new struct_1.DisTubeError("UNPLAYABLE_FORMATS");

}
if (typeof url !== "string" || !__1.isURL(url)) {
if (typeof url !== "string" || !(0, __1.isURL)(url)) {
throw new struct_1.DisTubeError("INVALID_TYPE", "an URL", url);

@@ -105,0 +92,0 @@ }

import DisTubeBase from "../DisTubeBase";
import { Collection } from "discord.js";
import type DisTube from "../../DisTube";
import type { GuildIDResolvable } from "../..";
import type { DisTube, GuildIDResolvable } from "../..";
/**

@@ -6,0 +5,0 @@ * Manages the collection of a data model.

@@ -33,9 +33,9 @@ "use strict";

get(idOrInstance) {
return this.collection.get(__1.resolveGuildID(idOrInstance));
return this.collection.get((0, __1.resolveGuildID)(idOrInstance));
}
delete(idOrInstance) {
this.collection.delete(__1.resolveGuildID(idOrInstance));
this.collection.delete((0, __1.resolveGuildID)(idOrInstance));
}
has(idOrInstance) {
return this.collection.has(__1.resolveGuildID(idOrInstance));
return this.collection.has((0, __1.resolveGuildID)(idOrInstance));
}

@@ -42,0 +42,0 @@ }

@@ -29,4 +29,4 @@ "use strict";

this.emit("initQueue", queue);
const err = await this.queues.playSong(queue);
return err ? err : queue;
const err = await this.playSong(queue);
return err || queue;
}

@@ -50,16 +50,15 @@ finally {

_voiceEventHandler(queue) {
queue.voice
.on("disconnect", error => {
queue.delete();
if (!error)
queue.listeners = {
disconnect: error => {
queue.delete();
this.emit("disconnect", queue);
else
this.emitError(error, queue.textChannel);
})
.on("error", error => {
this._handlePlayingError(queue, error);
})
.on("finish", () => {
this._handleSongFinish(queue);
});
if (error)
this.emitError(error, queue.textChannel);
},
error: error => this._handlePlayingError(queue, error),
finish: () => this._handleSongFinish(queue),
};
for (const event of Object.keys(queue.listeners)) {
queue.voice.on(event, queue.listeners[event]);
}
}

@@ -66,0 +65,0 @@ /**

@@ -1,8 +0,9 @@

/// <reference types="node" />
import { EventEmitter } from "events";
import type DisTubeStream from "../DisTubeStream";
import type { DisTubeVoiceManager } from "./DisTubeVoiceManager";
import { TypedEmitter } from "tiny-typed-emitter";
import type { DisTubeStream, DisTubeVoiceEvents, DisTubeVoiceManager } from "../..";
import type { AudioPlayer, AudioResource, VoiceConnection } from "@discordjs/voice";
import type { Snowflake, StageChannel, VoiceChannel, VoiceState } from "discord.js";
export declare interface DisTubeVoice {
/**
* Create a voice connection to the voice channel
*/
export declare class DisTubeVoice extends TypedEmitter<DisTubeVoiceEvents> {
id: Snowflake;

@@ -14,10 +15,2 @@ voices: DisTubeVoiceManager;

emittedError: boolean;
on(event: "disconnect", listener: (error?: Error) => void): this;
on(event: "error", listener: (error: Error) => void): this;
on(event: "finish", listener: () => void): this;
}
/**
* Create a voice connection to the voice channel
*/
export declare class DisTubeVoice extends EventEmitter {
private _channel;

@@ -24,0 +17,0 @@ private _volume;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DisTubeVoice = void 0;
const events_1 = require("events");
const tiny_typed_emitter_1 = require("tiny-typed-emitter");
const __1 = require("../..");

@@ -10,6 +10,6 @@ const voice_1 = require("@discordjs/voice");

*/
class DisTubeVoice extends events_1.EventEmitter {
class DisTubeVoice extends tiny_typed_emitter_1.TypedEmitter {
constructor(voiceManager, channel) {
super();
if (!__1.isSupportedVoiceChannel(channel))
if (!(0, __1.isSupportedVoiceChannel)(channel))
throw new __1.DisTubeError("NOT_SUPPORTED_VOICE");

@@ -31,3 +31,3 @@ if (!channel.joinable) {

this._volume = 0.5;
this.audioPlayer = voice_1.createAudioPlayer()
this.audioPlayer = (0, voice_1.createAudioPlayer)()
.on(voice_1.AudioPlayerStatus.Idle, oldState => {

@@ -48,3 +48,3 @@ if (oldState.status !== voice_1.AudioPlayerStatus.Idle) {

if (newState.reason === voice_1.VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
voice_1.entersState(this.connection, voice_1.VoiceConnectionStatus.Connecting, 5e3).catch(() => {
(0, voice_1.entersState)(this.connection, voice_1.VoiceConnectionStatus.Connecting, 5e3).catch(() => {
this.leave();

@@ -78,3 +78,3 @@ });

set channel(channel) {
if (!__1.isSupportedVoiceChannel(channel))
if (!(0, __1.isSupportedVoiceChannel)(channel))
throw new __1.DisTubeError("NOT_SUPPORTED_VOICE");

@@ -87,6 +87,6 @@ if (channel.guild.id !== this.id)

_join(channel) {
return voice_1.joinVoiceChannel({
return (0, voice_1.joinVoiceChannel)({
channelId: channel.id,
guildId: this.id,
adapterCreator: channel.guild.voiceAdapterCreator || __1.createDiscordJSAdapter(channel),
adapterCreator: channel.guild.voiceAdapterCreator || (0, __1.createDiscordJSAdapter)(channel),
});

@@ -106,3 +106,3 @@ }

try {
await voice_1.entersState(this.connection, voice_1.VoiceConnectionStatus.Ready, TIMEOUT);
await (0, voice_1.entersState)(this.connection, voice_1.VoiceConnectionStatus.Ready, TIMEOUT);
}

@@ -150,3 +150,3 @@ catch {

});
this.audioResource = voice_1.createAudioResource(stream.stream, {
this.audioResource = (0, voice_1.createAudioResource)(stream.stream, {
inputType: stream.type,

@@ -153,0 +153,0 @@ inlineVolume: true,

@@ -58,3 +58,3 @@ "use strict";

else {
const connection = voice_1.getVoiceConnection(__1.resolveGuildID(guild));
const connection = (0, voice_1.getVoiceConnection)((0, __1.resolveGuildID)(guild));
if (connection && connection.state.status !== voice_1.VoiceConnectionStatus.Destroyed) {

@@ -61,0 +61,0 @@ connection.destroy();

@@ -1,7 +0,10 @@

/// <reference types="node" />
import { EventEmitter } from "events";
import { TypedEmitter } from "tiny-typed-emitter";
import { DisTubeHandler, DisTubeVoiceManager, Options, Playlist, Queue, QueueManager, SearchResult } from ".";
import type { Client, GuildMember, Message, StageChannel, TextChannel, VoiceChannel } from "discord.js";
import type { CustomPlugin, DisTubeOptions, ExtractorPlugin, Filters, GuildIDResolvable, Song } from ".";
export declare interface DisTube {
import type { CustomPlugin, DisTubeEvents, DisTubeOptions, ExtractorPlugin, Filters, GuildIDResolvable, Song } from ".";
/**
* DisTube class
* @extends EventEmitter
*/
export declare class DisTube extends TypedEmitter<DisTubeEvents> {
handler: DisTubeHandler;

@@ -15,18 +18,5 @@ options: Options;

filters: Filters;
on(event: "addList", listener: (queue: Queue, playlist: Playlist) => void): this;
on(event: "addSong" | "playSong" | "finishSong", listener: (queue: Queue, song: Song) => void): this;
on(event: "empty" | "finish" | "initQueue" | "noRelated" | "disconnect" | "deleteQueue", listener: (queue: Queue) => void): this;
on(event: "error", listener: (channel: TextChannel, error: Error) => void): this;
on(event: "searchNoResult" | "searchCancel", listener: (message: Message, query: string) => void): this;
on(event: "searchResult", listener: (message: Message, results: SearchResult[], query: string) => void): this;
on(event: "searchInvalidAnswer" | "searchDone", listener: (message: Message, answer: Message, query: string) => void): this;
}
/**
* DisTube class
* @extends EventEmitter
*/
export declare class DisTube extends EventEmitter {
/**
* Create a new DisTube class.
* @param {Discord.Client} client JS client
* @param {Discord.Client} client Discord.JS client
* @param {DisTubeOptions} [otp] Custom DisTube options

@@ -47,6 +37,8 @@ * @example

* @param {Discord.Message} message A message from guild channel
* @param {string|Song|SearchResult|Playlist} song YouTube url | Search string | {@link Song} | {@link SearchResult} | {@link Playlist}
* @param {string|Song|SearchResult|Playlist} song URL | Search string |
* {@link Song} | {@link SearchResult} | {@link Playlist}
* @param {Object} [options] Optional options
* @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue (after the playing song if exists)
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
* (after the playing song if exists)
* @example

@@ -70,6 +62,8 @@ * client.on('message', (message) => {

* @param {Discord.VoiceChannel|Discord.StageChannel} voiceChannel The voice channel will be joined
* @param {string|Song|SearchResult|Playlist} song YouTube url | Search string | {@link Song} | {@link SearchResult} | {@link Playlist}
* @param {string|Song|SearchResult|Playlist} song URL | Search string |
* {@link Song} | {@link SearchResult} | {@link Playlist}
* @param {Object} [options] Optional options
* @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue (after the playing song if exists)
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
* (after the playing song if exists)
* @param {Discord.GuildMember} [options.member] Requested user (default is your bot)

@@ -87,2 +81,7 @@ * @param {Discord.TextChannel} [options.textChannel] Default {@link Queue#textChannel} (if the queue wasn't created)

/**
* <info>Shorthand method of {@link DisTubeHandler#createCustomPlaylist} and {@link DisTube#playVoiceChannel}
*
* If you doesn't have a user message (interaction,...),
* see {@link DisTubeHandler#createCustomPlaylist} example</info>
*
* Play or add array of video urls.

@@ -98,6 +97,7 @@ * {@link DisTube#event:playSong} or {@link DisTube#event:addList} will be emitted

* @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue (after the playing song if exists)
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
* (after the playing song if exists)
* @param {boolean} [options.parallel=true] Whether or not fetch the songs in parallel
* @example
* let songs = ["https://www.youtube.com/watch?v=xxx", "https://www.youtube.com/watch?v=yyy"];
* const songs = ["https://www.youtube.com/watch?v=xxx", "https://www.youtube.com/watch?v=yyy"];
* distube.playCustomPlaylist(message, songs, { name: "My playlist name" });

@@ -115,3 +115,3 @@ * // Fetching custom playlist sequentially (reduce lag for low specs)

* You can customize how user answers instead of send a number.
* Then use {@link DisTube#play} or {@link DisTube#playSkip} to play it.
* Then use {@link DisTube#play} or {@link DisTube#playVoiceChannel} to play it.
* @param {string} string The string search for

@@ -291,3 +291,3 @@ * @param {Object} options Search options

* if (command == "autoplay") {
* let mode = distube.toggleAutoplay(message);
* const mode = distube.toggleAutoplay(message);
* message.channel.send("Set autoplay mode to `" + (mode ? "On" : "Off") + "`");

@@ -317,3 +317,3 @@ * }

* if ([`3d`, `bassboost`, `echo`, `karaoke`, `nightcore`, `vaporwave`].includes(command)) {
* let filter = distube.setFilter(message, command);
* const filter = distube.setFilter(message, command);
* message.channel.send("Current queue filter: " + (filter.join(", ") || "Off"));

@@ -349,3 +349,3 @@ * }

/**
* Emitted after DisTube add a new playlist to the playing {@link Queue}
* Emitted after DisTube add a new playlist to the playing {@link Queue}.
*

@@ -361,3 +361,3 @@ * @event DisTube#addList

/**
* Emitted after DisTube add a new song to the playing {@link Queue}
* Emitted after DisTube add a new song to the playing {@link Queue}.
*

@@ -373,5 +373,7 @@ * @event DisTube#addSong

/**
* Emitted when there is no user in the voice channel, {@link DisTubeOptions}.leaveOnEmpty is `true` and there is a playing queue.
* If there is no playing queue (stopped and {@link DisTubeOptions}.leaveOnStop is `false`), it will leave the channel without emitting this event.
* Emitted when there is no user in the voice channel,
* {@link DisTubeOptions}.leaveOnEmpty is `true` and there is a playing queue.
*
* If there is no playing queue (stopped and {@link DisTubeOptions}.leaveOnStop is `false`),
* it will leave the channel without emitting this event.
* @event DisTube#empty

@@ -383,3 +385,3 @@ * @param {Queue} queue The guild queue

/**
* Emitted when {@link DisTube} encounters an error.
* Emitted when DisTube encounters an error.
*

@@ -396,3 +398,3 @@ * @event DisTube#error

* Emitted when there is no more song in the queue and {@link Queue#autoplay} is `false`.
* DisTube will leave voice channel if {@link DisTubeOptions}.leaveOnFinish is `true`
* DisTube will leave voice channel if {@link DisTubeOptions}.leaveOnFinish is `true`.
*

@@ -416,4 +418,4 @@ * @event DisTube#finish

/**
* Emitted when {@link Queue#autoplay} is `true`, the {@link Queue#songs} is empty and
* DisTube cannot find related songs to play
* Emitted when {@link Queue#autoplay} is `true`, {@link Queue#songs} is empty,
* and DisTube cannot find related songs to play.
*

@@ -427,4 +429,6 @@ * @event DisTube#noRelated

* Emitted when DisTube play a song.
* If {@link DisTubeOptions}.emitNewSongOnly is `true`, event is not emitted when looping a song or next song is the previous one
*
* If {@link DisTubeOptions}.emitNewSongOnly is `true`,
* this event is not emitted when looping a song or next song is the previous one.
*
* @event DisTube#playSong

@@ -434,9 +438,8 @@ * @param {Queue} queue The guild queue

* @example
* const status = (queue) => `Volume: \`${queue.volume}%\` | Loop: \`${queue.repeatMode ? queue.repeatMode == 2 ? "Server Queue" : "This Song" : "Off"}\` | Autoplay: \`${queue.autoplay ? "On" : "Off"}\``;
* distube.on("playSong", (queue, song) => queue.textChannel.send(
* `Playing \`${song.name}\` - \`${song.formattedDuration}\`\nRequested by: ${song.user}\n${status(queue)}`
* `Playing \`${song.name}\` - \`${song.formattedDuration}\`\nRequested by: ${song.user}`
* ));
*/
/**
* Emitted when DisTube cannot find any results for the query
* Emitted when DisTube cannot find any results for the query.
*

@@ -450,5 +453,5 @@ * @event DisTube#searchNoResult

/**
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0
* and song param of {@link DisTube#play|play()} is invalid url.
* DisTube will wait for user's next message to choose song manually.
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0,
* and song param of {@link DisTube#playVoiceChannel} is invalid url.
* DisTube will wait for user's next message to choose a song manually.
* <info>{@link https://support.google.com/youtube/answer/7354993|Safe search} is enabled

@@ -464,8 +467,10 @@ * if {@link DisTubeOptions}.nsfw is disabled and the message's channel is not a nsfw channel.</info>

* distube.on("searchResult", (message, results) => {
* message.channel.send(`**Choose an option from below**\n${results.map((song, i) => `**${i + 1}**. ${song.name} - \`${song.formattedDuration}\``).join("\n")}\n*Enter anything else or wait 60 seconds to cancel*`);
* message.channel.send(`**Choose an option from below**\n${
* results.map((song, i) => `**${i + 1}**. ${song.name} - \`${song.formattedDuration}\``).join("\n")
* }\n*Enter anything else or wait 60 seconds to cancel*`);
* });
*/
/**
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0
* and the search canceled due to {@link DisTubeOptions|DisTubeOptions.searchTimeout}
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0,
* and the search canceled due to {@link DisTubeOptions|DisTubeOptions.searchTimeout}.
*

@@ -480,4 +485,4 @@ * @event DisTube#searchCancel

/**
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0
* and the search canceled due to user's next message is not a number or out of results range
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0,
* and the search canceled due to user's next message is not a number or out of results range.
*

@@ -493,4 +498,4 @@ * @event DisTube#searchInvalidAnswer

/**
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0
* and after the user chose a search result to play
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0,
* and after the user chose a search result to play.
*

@@ -503,3 +508,3 @@ * @event DisTube#searchDone

/**
* Emitted when the bot is disconnected to the voice channel
* Emitted when the bot is disconnected to a voice channel.
*

@@ -516,3 +521,3 @@ * @event DisTube#disconnect

/**
* Emitted when DisTube finished a song
* Emitted when DisTube finished a song.
*

@@ -519,0 +524,0 @@ * @event DisTube#finishSong

@@ -9,4 +9,4 @@ "use strict";

const ytsr_1 = __importDefault(require("@distube/ytsr"));
const events_1 = require("events");
const util_1 = require("./util");
const tiny_typed_emitter_1 = require("tiny-typed-emitter");
const _1 = require(".");

@@ -17,6 +17,6 @@ /**

*/
class DisTube extends events_1.EventEmitter {
class DisTube extends tiny_typed_emitter_1.TypedEmitter {
/**
* Create a new DisTube class.
* @param {Discord.Client} client JS client
* @param {Discord.Client} client Discord.JS client
* @param {DisTubeOptions} [otp] Custom DisTube options

@@ -35,3 +35,3 @@ * @example

this.setMaxListeners(1);
if (!_1.isClientInstance(client))
if (!(0, _1.isClientInstance)(client))
throw new _1.DisTubeError("INVALID_TYPE", "Discord.Client", client, "client");

@@ -43,4 +43,9 @@ /**

this.client = client;
util_1.checkIntents(client.options);
(0, util_1.checkIntents)(client.options);
/**
* DisTube options
* @type {DisTubeOptions}
*/
this.options = new _1.Options(otp);
/**
* Voice connections manager

@@ -51,7 +56,2 @@ * @type {DisTubeVoiceManager}

/**
* DisTube options
* @type {DisTubeOptions}
*/
this.options = new _1.Options(otp);
/**
* DisTube's Handler

@@ -72,34 +72,3 @@ * @type {DisTubeHandler}

this.filters = _1.defaultFilters;
if (typeof this.options.customFilters === "object")
Object.assign(this.filters, this.options.customFilters);
if (this.options.leaveOnEmpty) {
client.on("voiceStateUpdate", oldState => {
if (!(oldState === null || oldState === void 0 ? void 0 : oldState.channel))
return;
const queue = this.getQueue(oldState);
if (!queue) {
if (util_1.isVoiceChannelEmpty(oldState)) {
setTimeout(() => {
const guildID = oldState.guild.id;
if (!this.getQueue(oldState) && util_1.isVoiceChannelEmpty(oldState))
this.voices.leave(guildID);
}, this.options.emptyCooldown * 1e3).unref();
}
return;
}
if (queue.emptyTimeout) {
clearTimeout(queue.emptyTimeout);
delete queue.emptyTimeout;
}
if (util_1.isVoiceChannelEmpty(oldState)) {
queue.emptyTimeout = setTimeout(() => {
if (util_1.isVoiceChannelEmpty(oldState)) {
queue.voice.leave();
this.emit("empty", queue);
queue.delete();
}
}, this.options.emptyCooldown * 1e3).unref();
}
});
}
Object.assign(this.filters, this.options.customFilters);
// Default plugin

@@ -127,6 +96,8 @@ this.options.plugins.push(new _1.HTTPPlugin(), new _1.HTTPSPlugin());

* @param {Discord.Message} message A message from guild channel
* @param {string|Song|SearchResult|Playlist} song YouTube url | Search string | {@link Song} | {@link SearchResult} | {@link Playlist}
* @param {string|Song|SearchResult|Playlist} song URL | Search string |
* {@link Song} | {@link SearchResult} | {@link Playlist}
* @param {Object} [options] Optional options
* @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue (after the playing song if exists)
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
* (after the playing song if exists)
* @example

@@ -144,3 +115,3 @@ * client.on('message', (message) => {

return;
if (!_1.isMessageInstance(message))
if (!(0, _1.isMessageInstance)(message))
throw new _1.DisTubeError("INVALID_TYPE", "Discord.Message", message, "message");

@@ -169,6 +140,8 @@ if (typeof options !== "object" || Array.isArray(options)) {

* @param {Discord.VoiceChannel|Discord.StageChannel} voiceChannel The voice channel will be joined
* @param {string|Song|SearchResult|Playlist} song YouTube url | Search string | {@link Song} | {@link SearchResult} | {@link Playlist}
* @param {string|Song|SearchResult|Playlist} song URL | Search string |
* {@link Song} | {@link SearchResult} | {@link Playlist}
* @param {Object} [options] Optional options
* @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue (after the playing song if exists)
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
* (after the playing song if exists)
* @param {Discord.GuildMember} [options.member] Requested user (default is your bot)

@@ -180,3 +153,3 @@ * @param {Discord.TextChannel} [options.textChannel] Default {@link Queue#textChannel} (if the queue wasn't created)

var _a;
if (!_1.isSupportedVoiceChannel(voiceChannel))
if (!(0, _1.isSupportedVoiceChannel)(voiceChannel))
throw new _1.DisTubeError("NOT_SUPPORTED_VOICE");

@@ -191,3 +164,3 @@ if (typeof options !== "object" || Array.isArray(options)) {

}, options);
if (message && !_1.isMessageInstance(message)) {
if (message && !(0, _1.isMessageInstance)(message)) {
throw new _1.DisTubeError("INVALID_TYPE", ["Discord.Message", "a falsy value"], message, "options.message");

@@ -212,3 +185,3 @@ }

song = await this.handler.resolvePlaylist(member, song);
if (typeof song === "string" && !util_1.isURL(song)) {
if (typeof song === "string" && !(0, util_1.isURL)(song)) {
if (!message)

@@ -264,2 +237,7 @@ song = (await this.search(song, { limit: 1 }))[0];

/**
* <info>Shorthand method of {@link DisTubeHandler#createCustomPlaylist} and {@link DisTube#playVoiceChannel}
*
* If you doesn't have a user message (interaction,...),
* see {@link DisTubeHandler#createCustomPlaylist} example</info>
*
* Play or add array of video urls.

@@ -275,6 +253,7 @@ * {@link DisTube#event:playSong} or {@link DisTube#event:addList} will be emitted

* @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue (after the playing song if exists)
* @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
* (after the playing song if exists)
* @param {boolean} [options.parallel=true] Whether or not fetch the songs in parallel
* @example
* let songs = ["https://www.youtube.com/watch?v=xxx", "https://www.youtube.com/watch?v=yyy"];
* const songs = ["https://www.youtube.com/watch?v=xxx", "https://www.youtube.com/watch?v=yyy"];
* distube.playCustomPlaylist(message, songs, { name: "My playlist name" });

@@ -314,3 +293,3 @@ * // Fetching custom playlist sequentially (reduce lag for low specs)

* You can customize how user answers instead of send a number.
* Then use {@link DisTube#play} or {@link DisTube#playSkip} to play it.
* Then use {@link DisTube#play} or {@link DisTube#playVoiceChannel} to play it.
* @param {string} string The string search for

@@ -337,3 +316,3 @@ * @param {Object} options Search options

try {
const search = await ytsr_1.default(string, opts);
const search = await (0, ytsr_1.default)(string, opts);
const results = search.items.map(i => new _1.SearchResult(i));

@@ -558,3 +537,3 @@ if (results.length === 0)

* if (command == "autoplay") {
* let mode = distube.toggleAutoplay(message);
* const mode = distube.toggleAutoplay(message);
* message.channel.send("Set autoplay mode to `" + (mode ? "On" : "Off") + "`");

@@ -595,3 +574,3 @@ * }

* if ([`3d`, `bassboost`, `echo`, `karaoke`, `nightcore`, `vaporwave`].includes(command)) {
* let filter = distube.setFilter(message, command);
* const filter = distube.setFilter(message, command);
* message.channel.send("Current queue filter: " + (filter.join(", ") || "Off"));

@@ -635,3 +614,3 @@ * }

emitError(error, channel) {
if (!channel || !_1.isTextChannelInstance(channel)) {
if (!channel || !(0, _1.isTextChannelInstance)(channel)) {
console.error(error);

@@ -653,3 +632,3 @@ console.warn("This is logged because <Queue>.textChannel is undefined");

/**
* Emitted after DisTube add a new playlist to the playing {@link Queue}
* Emitted after DisTube add a new playlist to the playing {@link Queue}.
*

@@ -665,3 +644,3 @@ * @event DisTube#addList

/**
* Emitted after DisTube add a new song to the playing {@link Queue}
* Emitted after DisTube add a new song to the playing {@link Queue}.
*

@@ -677,5 +656,7 @@ * @event DisTube#addSong

/**
* Emitted when there is no user in the voice channel, {@link DisTubeOptions}.leaveOnEmpty is `true` and there is a playing queue.
* If there is no playing queue (stopped and {@link DisTubeOptions}.leaveOnStop is `false`), it will leave the channel without emitting this event.
* Emitted when there is no user in the voice channel,
* {@link DisTubeOptions}.leaveOnEmpty is `true` and there is a playing queue.
*
* If there is no playing queue (stopped and {@link DisTubeOptions}.leaveOnStop is `false`),
* it will leave the channel without emitting this event.
* @event DisTube#empty

@@ -687,3 +668,3 @@ * @param {Queue} queue The guild queue

/**
* Emitted when {@link DisTube} encounters an error.
* Emitted when DisTube encounters an error.
*

@@ -700,3 +681,3 @@ * @event DisTube#error

* Emitted when there is no more song in the queue and {@link Queue#autoplay} is `false`.
* DisTube will leave voice channel if {@link DisTubeOptions}.leaveOnFinish is `true`
* DisTube will leave voice channel if {@link DisTubeOptions}.leaveOnFinish is `true`.
*

@@ -720,4 +701,4 @@ * @event DisTube#finish

/**
* Emitted when {@link Queue#autoplay} is `true`, the {@link Queue#songs} is empty and
* DisTube cannot find related songs to play
* Emitted when {@link Queue#autoplay} is `true`, {@link Queue#songs} is empty,
* and DisTube cannot find related songs to play.
*

@@ -731,4 +712,6 @@ * @event DisTube#noRelated

* Emitted when DisTube play a song.
* If {@link DisTubeOptions}.emitNewSongOnly is `true`, event is not emitted when looping a song or next song is the previous one
*
* If {@link DisTubeOptions}.emitNewSongOnly is `true`,
* this event is not emitted when looping a song or next song is the previous one.
*
* @event DisTube#playSong

@@ -738,9 +721,8 @@ * @param {Queue} queue The guild queue

* @example
* const status = (queue) => `Volume: \`${queue.volume}%\` | Loop: \`${queue.repeatMode ? queue.repeatMode == 2 ? "Server Queue" : "This Song" : "Off"}\` | Autoplay: \`${queue.autoplay ? "On" : "Off"}\``;
* distube.on("playSong", (queue, song) => queue.textChannel.send(
* `Playing \`${song.name}\` - \`${song.formattedDuration}\`\nRequested by: ${song.user}\n${status(queue)}`
* `Playing \`${song.name}\` - \`${song.formattedDuration}\`\nRequested by: ${song.user}`
* ));
*/
/**
* Emitted when DisTube cannot find any results for the query
* Emitted when DisTube cannot find any results for the query.
*

@@ -754,5 +736,5 @@ * @event DisTube#searchNoResult

/**
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0
* and song param of {@link DisTube#play|play()} is invalid url.
* DisTube will wait for user's next message to choose song manually.
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0,
* and song param of {@link DisTube#playVoiceChannel} is invalid url.
* DisTube will wait for user's next message to choose a song manually.
* <info>{@link https://support.google.com/youtube/answer/7354993|Safe search} is enabled

@@ -768,8 +750,10 @@ * if {@link DisTubeOptions}.nsfw is disabled and the message's channel is not a nsfw channel.</info>

* distube.on("searchResult", (message, results) => {
* message.channel.send(`**Choose an option from below**\n${results.map((song, i) => `**${i + 1}**. ${song.name} - \`${song.formattedDuration}\``).join("\n")}\n*Enter anything else or wait 60 seconds to cancel*`);
* message.channel.send(`**Choose an option from below**\n${
* results.map((song, i) => `**${i + 1}**. ${song.name} - \`${song.formattedDuration}\``).join("\n")
* }\n*Enter anything else or wait 60 seconds to cancel*`);
* });
*/
/**
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0
* and the search canceled due to {@link DisTubeOptions|DisTubeOptions.searchTimeout}
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0,
* and the search canceled due to {@link DisTubeOptions|DisTubeOptions.searchTimeout}.
*

@@ -784,4 +768,4 @@ * @event DisTube#searchCancel

/**
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0
* and the search canceled due to user's next message is not a number or out of results range
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0,
* and the search canceled due to user's next message is not a number or out of results range.
*

@@ -797,4 +781,4 @@ * @event DisTube#searchInvalidAnswer

/**
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0
* and after the user chose a search result to play
* Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0,
* and after the user chose a search result to play.
*

@@ -807,3 +791,3 @@ * @event DisTube#searchDone

/**
* Emitted when the bot is disconnected to the voice channel
* Emitted when the bot is disconnected to a voice channel.
*

@@ -820,3 +804,3 @@ * @event DisTube#disconnect

/**
* Emitted when DisTube finished a song
* Emitted when DisTube finished a song.
*

@@ -823,0 +807,0 @@ * @event DisTube#finishSong

@@ -12,6 +12,6 @@ "use strict";

async validate(url) {
return __1.validateAudioURL(http_1.default, "http:", url);
return (0, __1.validateAudioURL)(http_1.default, "http:", url);
}
async resolve(url, member) {
return __1.resolveHttpSong("http", url, member);
return (0, __1.resolveHttpSong)("http", url, member);
}

@@ -18,0 +18,0 @@ }

@@ -24,3 +24,3 @@ "use strict";

}
const headers = await exports.getResponseHeaders(httpModule, url), type = headers["content-type"];
const headers = await (0, exports.getResponseHeaders)(httpModule, url), type = headers["content-type"];
if (type === null || type === void 0 ? void 0 : type.startsWith("audio")) {

@@ -43,6 +43,6 @@ return true;

async validate(url) {
return exports.validateAudioURL(https_1.default, "https:", url);
return (0, exports.validateAudioURL)(https_1.default, "https:", url);
}
async resolve(url, member) {
return exports.resolveHttpSong("https", url, member);
return (0, exports.resolveHttpSong)("https", url, member);
}

@@ -49,0 +49,0 @@ }

@@ -34,3 +34,3 @@ "use strict";

/* eslint-disable no-console */
youtube_dl_1.download()
(0, youtube_dl_1.download)()
.then((version) => console.log(`[DisTube] Updated youtube-dl to ${version}!`))

@@ -47,3 +47,3 @@ .catch(console.error)

async resolve(url, member) {
const info = await youtube_dl_1.default(url, {
const info = await (0, youtube_dl_1.default)(url, {
dumpSingleJson: true,

@@ -64,3 +64,3 @@ noWarnings: true,

async getStreamURL(url) {
const info = await youtube_dl_1.default(url, {
const info = await (0, youtube_dl_1.default)(url, {
dumpSingleJson: true,

@@ -67,0 +67,0 @@ noWarnings: true,

declare const ERROR_MESSAGES: {
INVALID_TYPE: (expected: string | string[], got: any, name?: string | undefined) => string;
INVALID_TYPE: (expected: (number | string) | (number | string)[], got: any, name?: string | undefined) => string;
NUMBER_COMPARE: (name: string, expected: string, value: number) => string;

@@ -38,5 +38,14 @@ EMPTY_ARRAY: (name: string) => string;

};
export declare class DisTubeError extends Error {
declare type ErrorMessages = typeof ERROR_MESSAGES;
declare type ErrorCodes = keyof ErrorMessages;
declare type ErrorCode = {
[K in ErrorCodes]-?: ErrorMessages[K] extends string ? K : never;
}[ErrorCodes];
declare type ErrorCodeTemplate = Exclude<keyof typeof ERROR_MESSAGES, ErrorCode>;
export declare class DisTubeError<T extends string> extends Error {
errorCode: string;
constructor(code: keyof typeof ERROR_MESSAGES, ...args: any);
constructor(code: ErrorCode);
constructor(code: T extends ErrorCodeTemplate ? T : never, ...args: Parameters<ErrorMessages[typeof code]>);
constructor(code: ErrorCodeTemplate, _: never);
constructor(code: T extends ErrorCodes ? "This is built-in error code" : T, message: string);
get name(): string;

@@ -43,0 +52,0 @@ get code(): string;

@@ -13,3 +13,3 @@ "use strict";

? `Array<${got.length}>`
: ((_a = got === null || got === void 0 ? void 0 : got.constructor) === null || _a === void 0 ? void 0 : _a.name) || typeof got}`;
: ((_a = got === null || got === void 0 ? void 0 : got.constructor) === null || _a === void 0 ? void 0 : _a.name) || typeof got} (${typeof got})`;
},

@@ -48,15 +48,14 @@ NUMBER_COMPARE: (name, expected, value) => `'${name}' must be ${expected} ${value}`,

NO_VALID_SONG: "'songs' array does not have any valid Song, SearchResult or url",
EMPTY_FILTERED_PLAYLIST: "There is no valid video in the playlist\nMaybe age-restricted contents is filtered because you are in non-NSFW channel",
EMPTY_FILTERED_PLAYLIST: "There is no valid video in the playlist\n" +
"Maybe age-restricted contents is filtered because you are in non-NSFW channel",
EMPTY_PLAYLIST: "There is no valid video in the playlist",
};
const createMessage = (msg, ...args) => {
if (typeof msg === "string")
return msg;
return msg(...args);
};
const errMsg = (msg, ...args) => (typeof msg === "string" ? msg : msg(...args));
const haveCode = (code) => Object.keys(ERROR_MESSAGES).includes(code);
class DisTubeError extends Error {
constructor(code, ...args) {
if (!Object.keys(ERROR_MESSAGES).includes(code))
throw new TypeError(`Error code '${code}' does not exist`);
super(createMessage(ERROR_MESSAGES[code], ...args));
if (haveCode(code))
super(errMsg(ERROR_MESSAGES[code], ...args));
else
super(...args);
this.errorCode = code;

@@ -67,3 +66,3 @@ if (Error.captureStackTrace)

get name() {
return `${super.name} [${this.errorCode}]`;
return `DisTubeError [${this.errorCode}]`;
}

@@ -70,0 +69,0 @@ get code() {

@@ -12,3 +12,4 @@ import Plugin from "./Plugin";

/**
* Execute if the url is validated (Not needed to add {@link Song#related} because it will be added with {@link Plugin#getRelatedSongs})
* Execute if the url is validated
* (Not needed to add {@link Song#related} because it will be added with {@link Plugin#getRelatedSongs})
* @param {string} url URL

@@ -15,0 +16,0 @@ * @param {Discord.GuildMember} member Requested user

@@ -18,3 +18,4 @@ "use strict";

/**
* Execute if the url is validated (Not needed to add {@link Song#related} because it will be added with {@link Plugin#getRelatedSongs})
* Execute if the url is validated
* (Not needed to add {@link Song#related} because it will be added with {@link Plugin#getRelatedSongs})
* @param {string} url URL

@@ -21,0 +22,0 @@ * @param {Discord.GuildMember} member Requested user

@@ -1,4 +0,3 @@

import type Song from "./Song";
import type ytpl from "@distube/ytpl";
import type { PlaylistInfo } from "..";
import type { PlaylistInfo, Song } from "..";
import type { GuildMember, User } from "discord.js";

@@ -5,0 +4,0 @@ /**

@@ -72,3 +72,3 @@ "use strict";

get formattedDuration() {
return __1.formatDuration(this.duration);
return (0, __1.formatDuration)(this.duration);
}

@@ -75,0 +75,0 @@ /**

@@ -1,4 +0,3 @@

import type DisTube from "../DisTube";
import type { Song } from ".";
import type { DisTubeHandler } from "../core";
import type { Client, TextChannel } from "discord.js";
import type { DisTube, DisTubeEvents, DisTubeHandler, DisTubeVoiceManager, Options, QueueManager, Song } from "..";
/**

@@ -9,9 +8,50 @@ * DisTube Plugin

export declare class Plugin {
/** Type of the plugin */
type: "custom" | "extractor";
distube: DisTube;
handler: DisTubeHandler;
constructor(type: "custom" | "extractor");
init(distube: DisTube): void;
/**
* Emit the {@link DisTube} of this base
* @param {string} eventName Event name
* @param {...any} args arguments
* @returns {boolean}
*/
emit(eventName: keyof DisTubeEvents, ...args: any): boolean;
/**
* Emit error event
* @param {Error} error error
* @param {Discord.TextChannel?} channel Text channel where the error is encountered.
*/
emitError(error: Error, channel?: TextChannel): void;
/**
* The queue manager
* @type {QueueManager}
* @readonly
*/
get queues(): QueueManager;
/**
* The voice manager
* @type {DisTubeVoiceManager}
* @readonly
*/
get voices(): DisTubeVoiceManager;
/**
* Discord.js client
* @type {Discord.Client}
* @readonly
*/
get client(): Client;
/**
* DisTube options
* @type {DisTubeOptions}
* @readonly
*/
get options(): Options;
/**
* DisTube handler
* @type {DisTubeHandler}
* @readonly
*/
get handler(): DisTubeHandler;
/**
* Check if the url is working with this plugin

@@ -23,3 +63,4 @@ * @param {string} url Input url

/**
* Get the stream url from {@link Song#url}. Returns {@link Song#url} by default. Not needed if the plugin plays song from YouTube.
* Get the stream url from {@link Song#url}. Returns {@link Song#url} by default.
* Not needed if the plugin plays song from YouTube.
* @param {string} url Input url

@@ -30,3 +71,4 @@ * @returns {Promise<string>}

/**
* (Optional) Get related songs from a supported url (Not needed to add {@link Song#related} and member is `null` because it will be added with this function later)
* (Optional) Get related songs from a supported url. {@link Song#member} should be `undefined`.
* Not needed to add {@link Song#related} because it will be added with this function later.
* @param {string} url Input url

@@ -33,0 +75,0 @@ * @returns {Promise<Song[]>}

@@ -22,9 +22,61 @@ "use strict";

this.distube = distube;
/**
* Handler
* @type {DisTubeHandler}
*/
this.handler = this.distube.handler;
}
/**
* Emit the {@link DisTube} of this base
* @param {string} eventName Event name
* @param {...any} args arguments
* @returns {boolean}
*/
emit(eventName, ...args) {
return this.distube.emit(eventName, ...args);
}
/**
* Emit error event
* @param {Error} error error
* @param {Discord.TextChannel?} channel Text channel where the error is encountered.
*/
emitError(error, channel) {
this.distube.emitError(error, channel);
}
/**
* The queue manager
* @type {QueueManager}
* @readonly
*/
get queues() {
return this.distube.queues;
}
/**
* The voice manager
* @type {DisTubeVoiceManager}
* @readonly
*/
get voices() {
return this.distube.voices;
}
/**
* Discord.js client
* @type {Discord.Client}
* @readonly
*/
get client() {
return this.distube.client;
}
/**
* DisTube options
* @type {DisTubeOptions}
* @readonly
*/
get options() {
return this.distube.options;
}
/**
* DisTube handler
* @type {DisTubeHandler}
* @readonly
*/
get handler() {
return this.distube.handler;
}
/**
* Check if the url is working with this plugin

@@ -38,3 +90,4 @@ * @param {string} url Input url

/**
* Get the stream url from {@link Song#url}. Returns {@link Song#url} by default. Not needed if the plugin plays song from YouTube.
* Get the stream url from {@link Song#url}. Returns {@link Song#url} by default.
* Not needed if the plugin plays song from YouTube.
* @param {string} url Input url

@@ -47,3 +100,4 @@ * @returns {Promise<string>}

/**
* (Optional) Get related songs from a supported url (Not needed to add {@link Song#related} and member is `null` because it will be added with this function later)
* (Optional) Get related songs from a supported url. {@link Song#member} should be `undefined`.
* Not needed to add {@link Song#related} because it will be added with this function later.
* @param {string} url Input url

@@ -50,0 +104,0 @@ * @returns {Promise<Song[]>}

/// <reference types="node" />
import { DisTubeBase } from "../core";
import { Song, TaskQueue } from "..";
import type DisTube from "../DisTube";
import type { SearchResult } from "..";
import type { DisTubeVoice } from "../core";
import type { GuildMember, Snowflake, TextChannel } from "discord.js";
import type { DisTube, DisTubeVoice, DisTubeVoiceEvents, SearchResult } from "..";
/**

@@ -85,2 +83,3 @@ * Represents a queue.

taskQueue: TaskQueue;
listeners?: DisTubeVoiceEvents;
/**

@@ -118,3 +117,3 @@ * Create a queue for the guild

*/
get voiceChannel(): import("discord.js").StageChannel | import("discord.js").VoiceChannel | null;
get voiceChannel(): import("discord.js").VoiceChannel | import("discord.js").StageChannel | null;
get volume(): number;

@@ -207,3 +206,5 @@ set volume(value: number);

/**
* Delete the queue
* Delete the queue from the manager
* (This does not leave the queue even if {@link DisTubeOptions|DisTubeOptions.leaveOnStop} is enabled)
* @private
*/

@@ -210,0 +211,0 @@ delete(): void;

@@ -119,2 +119,8 @@ "use strict";

this.taskQueue = new __1.TaskQueue();
/**
* DisTubeVoice listener
* @type {Object}
* @private
*/
this.listeners = undefined;
}

@@ -126,3 +132,3 @@ /**

get formattedDuration() {
return __1.formatDuration(this.duration);
return (0, __1.formatDuration)(this.duration);
}

@@ -148,3 +154,3 @@ /**

get formattedCurrentTime() {
return __1.formatDuration(this.currentTime);
return (0, __1.formatDuration)(this.currentTime);
}

@@ -448,3 +454,5 @@ /**

/**
* Delete the queue
* Delete the queue from the manager
* (This does not leave the queue even if {@link DisTubeOptions|DisTubeOptions.leaveOnStop} is enabled)
* @private
*/

@@ -455,2 +463,7 @@ delete() {

this.previousSongs = [];
if (this.listeners) {
for (const event of Object.keys(this.listeners)) {
this.voice.removeListener(event, this.listeners[event]);
}
}
this.queues.delete(this.id);

@@ -457,0 +470,0 @@ this.emit("deleteQueue", this);

@@ -50,3 +50,3 @@ "use strict";

*/
this.duration = this.isLive ? 0 : __1.toSecond(info.duration);
this.duration = this.isLive ? 0 : (0, __1.toSecond)(info.duration);
/**

@@ -56,3 +56,3 @@ * [Video only] Formatted duration string `hh:mm:ss` or `mm:ss`.

*/
this.formattedDuration = this.isLive ? "Live" : __1.formatDuration(this.duration);
this.formattedDuration = this.isLive ? "Live" : (0, __1.formatDuration)(this.duration);
/**

@@ -59,0 +59,0 @@ * [Video only] Video thumbnail.

import Playlist from "./Playlist";
import type ytdl from "@distube/ytdl-core";
import type { SearchResult } from ".";
import type { Chapter, OtherSongInfo } from "..";
import type { GuildMember, User } from "discord.js";
import type { Chapter, OtherSongInfo, SearchResult } from "..";
/**
* Class representing a song.
* <info>If {@link Song} is added from a YouTube {@link SearchResult} or {@link Playlist}, some info will be missing to save your resources.
* It will be filled when emitting {@link DisTube#playSong} event.
*
* Missing info: {@link Song#likes}, {@link Song#dislikes}, {@link Song#streamURL}, {@link Song#related}, {@link Song#chapters}, {@link Song#age_restricted}</info>
* <info>If {@link Song} is added from a YouTube {@link SearchResult} or {@link Playlist},
* some info will be missing to save your resources. It will be filled when emitting {@link DisTube#playSong} event.
*
* Missing info: {@link Song#likes}, {@link Song#dislikes}, {@link Song#streamURL},
* {@link Song#related}, {@link Song#chapters}, {@link Song#age_restricted}</info>
*/

@@ -30,7 +31,4 @@ export declare class Song {

dislikes: number;
/** Song uploader */
uploader: {
/** Uploader name */
name?: string;
/** Uploader url */
url?: string;

@@ -37,0 +35,0 @@ };

@@ -11,6 +11,8 @@ "use strict";

* Class representing a song.
* <info>If {@link Song} is added from a YouTube {@link SearchResult} or {@link Playlist}, some info will be missing to save your resources.
* It will be filled when emitting {@link DisTube#playSong} event.
*
* Missing info: {@link Song#likes}, {@link Song#dislikes}, {@link Song#streamURL}, {@link Song#related}, {@link Song#chapters}, {@link Song#age_restricted}</info>
* <info>If {@link Song} is added from a YouTube {@link SearchResult} or {@link Playlist},
* some info will be missing to save your resources. It will be filled when emitting {@link DisTube#playSong} event.
*
* Missing info: {@link Song#likes}, {@link Song#dislikes}, {@link Song#streamURL},
* {@link Song#related}, {@link Song#chapters}, {@link Song#age_restricted}</info>
*/

@@ -85,3 +87,3 @@ class Song {

*/
this.duration = this.isLive ? 0 : __1.toSecond(details.lengthSeconds || details.length_seconds || details.duration);
this.duration = this.isLive ? 0 : (0, __1.toSecond)(details.lengthSeconds || details.length_seconds || details.duration);
/**

@@ -91,3 +93,3 @@ * Formatted duration string (`hh:mm:ss`, `mm:ss` or `Live`).

*/
this.formattedDuration = this.isLive ? "Live" : __1.formatDuration(this.duration);
this.formattedDuration = this.isLive ? "Live" : (0, __1.formatDuration)(this.duration);
/**

@@ -120,3 +122,3 @@ * Song URL.

*/
this.views = __1.parseNumber(details.viewCount || details.view_count || details.views);
this.views = (0, __1.parseNumber)(details.viewCount || details.view_count || details.views);
/**

@@ -126,3 +128,3 @@ * Song like count

*/
this.likes = __1.parseNumber(details.likes);
this.likes = (0, __1.parseNumber)(details.likes);
/**

@@ -132,3 +134,3 @@ * Song dislike count

*/
this.dislikes = __1.parseNumber(details.dislikes);
this.dislikes = (0, __1.parseNumber)(details.dislikes);
/**

@@ -178,11 +180,11 @@ * Song uploader

this.isLive = Boolean(info.is_live || info.isLive);
this.duration = this.isLive ? 0 : __1.toSecond(info._duration_raw || info.duration);
this.formattedDuration = this.isLive ? "Live" : __1.formatDuration(this.duration);
this.duration = this.isLive ? 0 : (0, __1.toSecond)(info._duration_raw || info.duration);
this.formattedDuration = this.isLive ? "Live" : (0, __1.formatDuration)(this.duration);
this.url = info.webpage_url || info.url;
this.thumbnail = info.thumbnail;
this.related = info.related || [];
this.views = __1.parseNumber(info.view_count || info.views);
this.likes = __1.parseNumber(info.like_count || info.likes);
this.dislikes = __1.parseNumber(info.dislike_count || info.dislikes);
this.reposts = __1.parseNumber(info.repost_count || info.reposts);
this.views = (0, __1.parseNumber)(info.view_count || info.views);
this.likes = (0, __1.parseNumber)(info.like_count || info.likes);
this.dislikes = (0, __1.parseNumber)(info.dislike_count || info.dislikes);
this.reposts = (0, __1.parseNumber)(info.repost_count || info.reposts);
this.uploader = {

@@ -192,3 +194,3 @@ name: info.uploader,

};
this.age_restricted = info.age_restricted || (!!info.age_limit && __1.parseNumber(info.age_limit) >= 18);
this.age_restricted = info.age_restricted || (!!info.age_limit && (0, __1.parseNumber)(info.age_limit) >= 18);
this.chapters = info.chapters || [];

@@ -195,0 +197,0 @@ }

import type ytdl from "@distube/ytdl-core";
import type { CustomPlugin, ExtractorPlugin, Queue, Song } from "./struct";
import type { CustomPlugin, DisTubeVoice, ExtractorPlugin, Playlist, Queue, SearchResult, Song } from ".";
import type { Guild, GuildMember, Interaction, Message, Snowflake, StageChannel, TextChannel, User, VoiceChannel, VoiceState } from "discord.js";
declare type Awaitable = Promise<void> | void;
export declare type DisTubeVoiceEvents = {
disconnect: (error?: Error) => Awaitable;
error: (error: Error) => Awaitable;
finish: () => Awaitable;
};
export declare type DisTubeEvents = {
/** Emitted after DisTube add a new song to the playing {@link Queue}. */
addSong: (queue: Queue, song: Song) => Awaitable;
/**
* Emitted when DisTube play a song.
*
* If {@link DisTubeOptions.emitNewSongOnly} is `true`,
* this event is not emitted when looping a song or next song is the previous one.
*/
playSong: (queue: Queue, song: Song) => Awaitable;
/** Emitted when DisTube finished a song. */
finishSong: (queue: Queue, song: Song) => Awaitable;
/**
* Emitted when there is no user in the voice channel,
* {@link DisTubeOptions.leaveOnEmpty} is `true` and there is a playing queue.
*
* If there is no playing queue (stopped and {@link DisTubeOptions.leaveOnStop} is `false`),
* it will leave the channel without emitting this event.
*/
empty: (queue: Queue) => Awaitable;
/**
* Emitted when there is no more song in the queue and {@link Queue#autoplay} is `false`.
* DisTube will leave voice channel if {@link DisTubeOptions.leaveOnFinish} is `true`.
*/
finish: (queue: Queue) => Awaitable;
/** Emitted when DisTube initialize a queue to change queue default properties. */
initQueue: (queue: Queue) => Awaitable;
/**
* Emitted when {@link Queue#autoplay} is `true`, {@link Queue#songs} is empty,
* and DisTube cannot find related songs to play.
*/
noRelated: (queue: Queue) => Awaitable;
/** Emitted when the bot is disconnected to a voice channel. */
disconnect: (queue: Queue) => Awaitable;
/** Emitted when a {@link Queue} is deleted with any reasons. */
deleteQueue: (queue: Queue) => Awaitable;
/**
* Emitted when {@link DisTubeOptions.searchSongs} bigger than 0,
* and the search canceled due to {@link DisTubeOptions.searchTimeout}.
*/
searchCancel: (message: Message, query: string) => Awaitable;
/** Emitted when DisTube cannot find any results for the query. */
searchNoResult: (message: Message, query: string) => Awaitable;
/**
* Emitted when {@link DisTubeOptions.searchSongs} bigger than 0,
* and after the user chose a search result to play.
*/
searchDone: (message: Message, answer: Message, query: string) => Awaitable;
/**
* Emitted when {@link DisTubeOptions.searchSongs} bigger than 0,
* and the search canceled due to user's next message is not a number or out of results range.
*/
searchInvalidAnswer: (message: Message, answer: Message, query: string) => Awaitable;
/** Emitted when DisTube encounters an error. */
error: (channel: TextChannel, error: Error) => Awaitable;
/** Emitted after DisTube add a new playlist to the playing {@link Queue}. */
addList: (queue: Queue, playlist: Playlist) => Awaitable;
/**
* Emitted when {@link DisTubeOptions.searchSongs} bigger than 0,
* and song param of {@link DisTube#playVoiceChannel} is invalid url.
* DisTube will wait for user's next message to choose a song manually.
*
* Safe search is enabled
* if {@link DisTubeOptions.nsfw} is disabled and the message's channel is not a nsfw channel.
*/
searchResult: (message: Message, results: SearchResult[], query: string) => Awaitable;
};
export declare type Filters = Record<string, string>;
export interface DisTubeOptions {
/** DisTube plugins.*/
plugins?: (CustomPlugin | ExtractorPlugin)[];
/** If `true`, {@link DisTube#event:playSong} will not be emitted when looping a song or next song is the same as the previous one */
emitNewSongOnly?: boolean;
/** Whether or not leaving voice channel when the queue finishes. */
leaveOnFinish?: boolean;
/** Whether or not leaving voice channel after using {@link DisTube#stop} function. */
leaveOnStop?: boolean;
/** Whether or not leaving voice channel if the voice channel is empty after {@link DisTubeOptions}.emptyCooldown seconds. */
leaveOnEmpty?: boolean;
/** Built-in leave on empty cooldown in seconds (When leaveOnEmpty is true) */
emptyCooldown?: number;
/** Whether or not saving the previous songs of the queue and enable {@link DisTube#previous} method */
savePreviousSongs?: boolean;
/** Limit of search results emits in {@link DisTube#event:searchResult} event when {@link DisTube#play} method executed. If `searchSongs <= 1`, play the first result */
searchSongs?: number;
/** Built-in search cooldown in seconds (When `searchSongs` is bigger than 0) */
searchCooldown?: number;
/** YouTube cookies. Read how to get it in {@link https://github.com/fent/node-ytdl-core/blob/997efdd5dd9063363f6ef668bb364e83970756e7/example/cookies.js#L6-L12|YTDL's Example} */
youtubeCookie?: string;
/** If not given; ytdl-core will try to find it. You can find this by going to a video's watch page; viewing the source; and searching for "ID_TOKEN". */
youtubeIdentityToken?: string;
/** Whether or not using youtube-dl. */
youtubeDL?: boolean;
/** Whether or not updating youtube-dl automatically. */
updateYouTubeDL?: boolean;
/** Override {@link DefaultFilters} or add more ffmpeg filters. Example=`{ "Filter name"="Filter value"; "8d"="apulsator=hz=0.075" }` */
customFilters?: Filters;
/** `ytdl-core` options */
ytdlOptions?: ytdl.downloadOptions;
/** Whether or not playing age-restricted content and disabling safe search when using {@link DisTube#play} in non-NSFW channel. */
nsfw?: boolean;
/** Whether or not emitting `addList` event when creating a new Queue */
emitAddSongWhenCreatingQueue?: boolean;
/** Whether or not emitting `addSong` event when creating a new Queue */
emitAddListWhenCreatingQueue?: boolean;
}
export declare type GuildIDResolvable = Queue | Snowflake | Message | VoiceChannel | StageChannel | VoiceState | Guild | TextChannel | GuildMember | Interaction | string;
export declare type GuildIDResolvable = Queue | DisTubeVoice | Snowflake | Message | VoiceChannel | StageChannel | VoiceState | Guild | TextChannel | GuildMember | Interaction | string;
export interface OtherSongInfo {

@@ -103,2 +158,3 @@ src?: string;

}
export {};
//# sourceMappingURL=type.d.ts.map

@@ -94,3 +94,3 @@ "use strict";

if (!intents.has(intent))
throw new _1.DisTubeError("MISSING_INTENTS", intent);
throw new _1.DisTubeError("MISSING_INTENTS", intent.toString());
}

@@ -176,8 +176,13 @@ }

let guildID;
if (typeof resolvable === "string")
if (typeof resolvable === "string") {
guildID = resolvable;
else if ("guild" in resolvable && isGuildInstance(resolvable.guild))
guildID = resolvable.guild.id;
else if ("id" in resolvable && isGuildInstance(resolvable))
guildID = resolvable.id;
}
else if (typeof resolvable === "object") {
if (resolvable instanceof _1.Queue || resolvable instanceof _1.DisTubeVoice)
guildID = resolvable.id;
else if ("guild" in resolvable && isGuildInstance(resolvable.guild))
guildID = resolvable.guild.id;
else if ("id" in resolvable && isGuildInstance(resolvable))
guildID = resolvable.id;
}
if (!isSnowflake(guildID))

@@ -184,0 +189,0 @@ throw new _1.DisTubeError("INVALID_TYPE", "GuildIDResolvable", resolvable);

{
"name": "distube",
"version": "3.0.0-beta.36",
"version": "3.0.0-beta.37",
"description": "A Discord.js module to simplify your music commands and play songs with audio filters on Discord without any API key. Support YouTube, SoundCloud, Bandcamp, Facebook, and 700+ more sites",

@@ -9,3 +9,3 @@ "main": "dist/index.js",

"test": "jest --config .jestrc.json",
"docs": "npm run build && docgen --source dist --output docs/docs.json --custom pages/index.yml",
"docs": "docgen -s src/*.ts src/**/*.ts -o docs/docs.json -c pages/index.yml -g -j .jsconfig.json",
"lint": "eslint .",

@@ -48,6 +48,10 @@ "lint:fix": "eslint . --fix",

"@distube/ytpl": "^1.0.12",
"@distube/ytsr": "^1.1.5"
"@distube/ytsr": "^1.1.5",
"prism-media": "github:distubejs/prism-media",
"tiny-typed-emitter": "^2.1.0"
},
"devDependencies": {
"@babel/core": "^7.15.0",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-object-rest-spread": "^7.14.7",
"@babel/preset-env": "^7.15.0",

@@ -59,13 +63,14 @@ "@babel/preset-typescript": "^7.15.0",

"@distube/docgen": "distubejs/docgen",
"@types/jest": "^27.0.0",
"@types/node": "^16.4.14",
"babel-jest": "^27.0.6",
"@types/jest": "^27.0.1",
"@types/node": "^16.7.10",
"babel-jest": "^27.1.0",
"discord.js": "^13.0.1",
"eslint": "^7.32.0",
"eslint-config-distube": "^1.2.0",
"husky": "^7.0.1",
"jest": "^27.0.6",
"eslint-config-distube": "^1.3.0",
"husky": "^7.0.2",
"jest": "^27.1.0",
"jsdoc-babel": "^0.5.0",
"lint-staged": "^11.1.2",
"prettier": "^2.3.2",
"typescript": "^4.3.5"
"typescript": "^4.4.2"
},

@@ -75,16 +80,7 @@ "peerDependencies": {

"@discordjs/voice": ">=0.5.6",
"discord.js": "^12.5.0||^13.0.0"
"discord.js": "^12.5.0||^13.0.0-0||^13.1.0-0||^13.2.0-0"
},
"engines": {
"node": ">=12.0.0"
},
"lint-staged": {
"*.ts": [
"prettier --write",
"eslint"
],
"*.{js,json,yml,yaml}": [
"prettier --write"
]
}
}

@@ -42,6 +42,7 @@ <div align="center">

- Node v12 or higher
- [git](https://git-scm.com/downloads) (for install forked dependencies)
- [discord.js](https://discord.js.org) v12 or **v13 _(Recommended)_**
- [@discordjs/voice](https://github.com/discordjs/voice) - `npm install @discordjs/voice`
- [@discordjs/voice](https://github.com/discordjs/voice)
- [FFmpeg](https://www.ffmpeg.org/download.html)
- [@discordjs/opus](https://github.com/discordjs/opus) - `npm install @discordjs/opus`
- [@discordjs/opus](https://github.com/discordjs/opus)
- [sodium](https://www.npmjs.com/package/sodium) or [libsodium-wrappers](https://www.npmjs.com/package/libsodium-wrappers)

@@ -48,0 +49,0 @@ - [python](https://www.python.org/) _(Optional - For [`youtube-dl`](https://youtube-dl.org/) to support [700+ more sites](https://ytdl-org.github.io/youtube-dl/supportedsites.html).)_

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc