distube 4.0.6 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -63,7 +63,7 @@ var require_package = __commonJS({
63
63
  "package.json"(exports, module2) {
64
64
  module2.exports = {
65
65
  name: "distube",
66
- version: "4.0.6",
66
+ version: "4.1.1",
67
67
  description: "A Discord.js module to simplify your music commands and play songs with audio filters on Discord without any API key.",
68
68
  main: "./dist/index.js",
69
69
  types: "./dist/index.d.ts",
@@ -124,45 +124,47 @@ var require_package = __commonJS({
124
124
  ],
125
125
  homepage: "https://distube.js.org/",
126
126
  dependencies: {
127
- "@distube/ytdl-core": "^4.11.17",
128
- "@distube/ytpl": "^1.1.1",
129
- "@distube/ytsr": "^1.1.9",
127
+ "@distube/ytdl-core": "^4.13.2",
128
+ "@distube/ytpl": "^1.2.1",
129
+ "@distube/ytsr": "^1.2.0",
130
130
  "prism-media": "npm:@distube/prism-media@latest",
131
131
  "tiny-typed-emitter": "^2.1.0",
132
- tslib: "^2.6.1",
133
- undici: "^5.22.1"
132
+ "tough-cookie": "^4.1.3",
133
+ tslib: "^2.6.2",
134
+ undici: "^5.27.2"
134
135
  },
135
136
  devDependencies: {
136
- "@babel/core": "^7.22.9",
137
+ "@babel/core": "^7.23.2",
137
138
  "@babel/plugin-proposal-class-properties": "^7.18.6",
138
139
  "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
139
140
  "@babel/plugin-transform-private-methods": "^7.22.5",
140
- "@babel/preset-env": "^7.22.9",
141
- "@babel/preset-typescript": "^7.22.5",
142
- "@commitlint/cli": "^17.6.7",
143
- "@commitlint/config-conventional": "^17.6.7",
141
+ "@babel/preset-env": "^7.23.2",
142
+ "@babel/preset-typescript": "^7.23.2",
143
+ "@commitlint/cli": "^18.2.0",
144
+ "@commitlint/config-conventional": "^18.1.0",
144
145
  "@discordjs/voice": "^0.16.0",
145
146
  "@distubejs/docgen": "distubejs/docgen",
146
- "@types/jest": "^29.5.3",
147
- "@types/node": "^20.4.5",
148
- "@typescript-eslint/eslint-plugin": "^6.2.0",
149
- "@typescript-eslint/parser": "^6.2.0",
150
- "babel-jest": "^29.6.2",
151
- "discord.js": "^14.11.0",
152
- eslint: "^8.45.0",
147
+ "@types/jest": "^29.5.8",
148
+ "@types/node": "^20.9.0",
149
+ "@types/tough-cookie": "^4.0.5",
150
+ "@typescript-eslint/eslint-plugin": "^6.10.0",
151
+ "@typescript-eslint/parser": "^6.10.0",
152
+ "babel-jest": "^29.7.0",
153
+ "discord.js": "^14.13.0",
154
+ eslint: "^8.53.0",
153
155
  "eslint-config-distube": "^1.6.4",
154
- "eslint-config-prettier": "^8.9.0",
155
- "eslint-plugin-deprecation": "^1.5.0",
156
- "eslint-plugin-jsdoc": "^46.4.5",
156
+ "eslint-config-prettier": "^9.0.0",
157
+ "eslint-plugin-deprecation": "^2.0.0",
158
+ "eslint-plugin-jsdoc": "^46.8.2",
157
159
  husky: "^8.0.3",
158
- jest: "^29.6.2",
160
+ jest: "^29.7.0",
159
161
  "jsdoc-babel": "^0.5.0",
160
162
  "nano-staged": "^0.8.0",
161
- "npm-check-updates": "^16.10.17",
163
+ "npm-check-updates": "^16.14.6",
162
164
  pinst: "^3.0.0",
163
- prettier: "^3.0.0",
164
- tsup: "^7.1.0",
165
- typescript: "^5.1.6"
165
+ prettier: "^3.0.3",
166
+ tsup: "^7.2.0",
167
+ typescript: "^5.2.2"
166
168
  },
167
169
  peerDependencies: {
168
170
  "@discordjs/opus": "*",
@@ -238,6 +240,7 @@ __export(src_exports, {
238
240
  isSnowflake: () => isSnowflake,
239
241
  isSupportedVoiceChannel: () => isSupportedVoiceChannel,
240
242
  isTextChannelInstance: () => isTextChannelInstance,
243
+ isTruthy: () => isTruthy,
241
244
  isURL: () => isURL,
242
245
  isVoiceChannelEmpty: () => isVoiceChannelEmpty,
243
246
  objectKeys: () => objectKeys,
@@ -441,7 +444,7 @@ var _TaskQueue = class _TaskQueue {
441
444
  * @type {boolean}
442
445
  */
443
446
  get hasResolveTask() {
444
- return !!__privateGet(this, _tasks).find((t) => t.resolveInfo);
447
+ return __privateGet(this, _tasks).some((t) => t.resolveInfo);
445
448
  }
446
449
  };
447
450
  _tasks = new WeakMap();
@@ -481,9 +484,9 @@ var _Playlist = class _Playlist {
481
484
  this.songs = playlist;
482
485
  this.name = this.songs[0].name ? `${this.songs[0].name} and ${this.songs.length - 1} more songs.` : `${this.songs.length} songs playlist`;
483
486
  this.thumbnail = this.songs[0].thumbnail;
484
- this.member = member || void 0;
487
+ this.member = member;
485
488
  } else {
486
- this.source = (playlist.source || "youtube").toLowerCase();
489
+ this.source = playlist.source.toLowerCase();
487
490
  if (!Array.isArray(playlist.songs) || !playlist.songs.length)
488
491
  throw new DisTubeError("EMPTY_PLAYLIST");
489
492
  this.songs = playlist.songs;
@@ -491,9 +494,9 @@ var _Playlist = class _Playlist {
491
494
  playlist.title || (this.songs[0].name ? `${this.songs[0].name} and ${this.songs.length - 1} more songs.` : `${this.songs.length} songs playlist`);
492
495
  this.url = playlist.url || playlist.webpage_url;
493
496
  this.thumbnail = playlist.thumbnail || this.songs[0].thumbnail;
494
- this.member = member || playlist.member || void 0;
497
+ this.member = member || playlist.member;
495
498
  }
496
- this.songs.map((s) => s.constructor.name === "Song" && (s.playlist = this));
499
+ this.songs.forEach((s) => s.constructor.name === "Song" && (s.playlist = this));
497
500
  if (properties)
498
501
  for (const [key, value] of Object.entries(properties))
499
502
  this[key] = value;
@@ -504,7 +507,7 @@ var _Playlist = class _Playlist {
504
507
  * @type {number}
505
508
  */
506
509
  get duration() {
507
- return this.songs?.reduce((prev, next) => prev + (next.duration || 0), 0) || 0;
510
+ return this.songs.reduce((prev, next) => prev + next.duration, 0);
508
511
  }
509
512
  /**
510
513
  * Formatted duration string `hh:mm:ss`.
@@ -524,7 +527,7 @@ var _Playlist = class _Playlist {
524
527
  if (!isMemberInstance(member))
525
528
  return;
526
529
  __privateSet(this, _member, member);
527
- this.songs.map((s) => s.constructor.name === "Song" && (s.member = this.member));
530
+ this.songs.forEach((s) => s.constructor.name === "Song" && (s.member = this.member));
528
531
  }
529
532
  /**
530
533
  * User requested.
@@ -538,7 +541,7 @@ var _Playlist = class _Playlist {
538
541
  }
539
542
  set metadata(metadata) {
540
543
  __privateSet(this, _metadata, metadata);
541
- this.songs.map((s) => s.constructor.name === "Song" && (s.metadata = metadata));
544
+ this.songs.forEach((s) => s.constructor.name === "Song" && (s.metadata = metadata));
542
545
  }
543
546
  };
544
547
  _metadata = new WeakMap();
@@ -676,7 +679,7 @@ var _Song = class _Song {
676
679
  const details = info.videoDetails || info;
677
680
  this.id = details.videoId || details.id;
678
681
  this.name = details.title || details.name;
679
- this.isLive = !!details.isLive;
682
+ this.isLive = Boolean(details.isLive);
680
683
  this.duration = this.isLive ? 0 : toSecond(details.lengthSeconds || details.length_seconds || details.duration);
681
684
  this.formattedDuration = this.isLive ? "Live" : formatDuration(this.duration);
682
685
  this.url = `https://www.youtube.com/watch?v=${this.id}`;
@@ -693,7 +696,7 @@ var _Song = class _Song {
693
696
  name: info.uploader?.name || details.author?.name,
694
697
  url: info.uploader?.url || details.author?.channel_url || details.author?.url
695
698
  };
696
- this.age_restricted = !!details.age_restricted;
699
+ this.age_restricted = Boolean(details.age_restricted);
697
700
  this.chapters = details.chapters || [];
698
701
  this.reposts = 0;
699
702
  }
@@ -729,7 +732,7 @@ var _Song = class _Song {
729
732
  url: info.uploader?.url
730
733
  };
731
734
  }
732
- this.age_restricted = info.age_restricted || !!info.age_limit && parseNumber(info.age_limit) >= 18;
735
+ this.age_restricted = info.age_restricted || Boolean(info.age_limit) && parseNumber(info.age_limit) >= 18;
733
736
  this.chapters = info.chapters || [];
734
737
  }
735
738
  /**
@@ -878,27 +881,23 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
878
881
  this.emit("error", error);
879
882
  });
880
883
  this.connection.on(import_voice.VoiceConnectionStatus.Disconnected, (_, newState) => {
881
- if (newState.reason === import_voice.VoiceConnectionDisconnectReason.Manual)
882
- return this.leave();
883
- if (newState.reason === import_voice.VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
884
+ if (newState.reason === import_voice.VoiceConnectionDisconnectReason.Manual) {
885
+ this.leave();
886
+ } else if (newState.reason === import_voice.VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
884
887
  (0, import_voice.entersState)(this.connection, import_voice.VoiceConnectionStatus.Connecting, 5e3).catch(() => {
885
888
  if (![import_voice.VoiceConnectionStatus.Ready, import_voice.VoiceConnectionStatus.Connecting].includes(this.connection.state.status)) {
886
889
  this.leave();
887
890
  }
888
891
  });
889
- return;
890
- }
891
- if (this.connection.rejoinAttempts < 5) {
892
+ } else if (this.connection.rejoinAttempts < 5) {
892
893
  setTimeout(
893
894
  () => {
894
895
  this.connection.rejoin();
895
896
  },
896
897
  (this.connection.rejoinAttempts + 1) * 5e3
897
898
  ).unref();
898
- return;
899
- }
900
- if (this.connection.state.status !== import_voice.VoiceConnectionStatus.Destroyed) {
901
- return this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
899
+ } else if (this.connection.state.status !== import_voice.VoiceConnectionStatus.Destroyed) {
900
+ this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
902
901
  }
903
902
  }).on(import_voice.VoiceConnectionStatus.Destroyed, () => {
904
903
  this.leave();
@@ -1041,8 +1040,9 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
1041
1040
  if (state.status !== import_voice.AudioPlayerStatus.Paused)
1042
1041
  return;
1043
1042
  if (this.audioResource && state.resource !== this.audioResource)
1044
- return this.audioPlayer.play(this.audioResource);
1045
- this.audioPlayer.unpause();
1043
+ this.audioPlayer.play(this.audioResource);
1044
+ else
1045
+ this.audioPlayer.unpause();
1046
1046
  }
1047
1047
  /**
1048
1048
  * Whether the bot is self-deafened
@@ -1116,13 +1116,7 @@ var DisTubeVoice = _DisTubeVoice;
1116
1116
  // src/core/DisTubeStream.ts
1117
1117
  var import_prism_media = require("prism-media");
1118
1118
  var import_voice2 = require("@discordjs/voice");
1119
- var chooseBestVideoFormat = /* @__PURE__ */ __name((formats, isLive = false) => {
1120
- let filter = /* @__PURE__ */ __name((format) => format.hasAudio, "filter");
1121
- if (isLive)
1122
- filter = /* @__PURE__ */ __name((format) => format.hasAudio && format.isHLS, "filter");
1123
- formats = formats.filter(filter).sort((a, b) => Number(b.audioBitrate) - Number(a.audioBitrate) || Number(a.bitrate) - Number(b.bitrate));
1124
- return formats.find((format) => !format.hasVideo) || formats.sort((a, b) => Number(a.bitrate) - Number(b.bitrate))[0];
1125
- }, "chooseBestVideoFormat");
1119
+ var chooseBestVideoFormat = /* @__PURE__ */ __name(({ duration, formats, isLive }) => formats && formats.filter((f) => f.hasAudio && (duration < 10 * 60 || f.hasVideo) && (!isLive || f.isHLS)).sort((a, b) => Number(b.audioBitrate) - Number(a.audioBitrate) || Number(a.bitrate) - Number(b.bitrate))[0], "chooseBestVideoFormat");
1126
1120
  var _DisTubeStream = class _DisTubeStream {
1127
1121
  /**
1128
1122
  * Create a DisTubeStream to play with {@link DisTubeVoice}
@@ -1168,18 +1162,20 @@ var _DisTubeStream = class _DisTubeStream {
1168
1162
  }
1169
1163
  /**
1170
1164
  * Create a stream from ytdl video formats
1171
- * @param {ytdl.videoFormat[]} formats ytdl video formats
1165
+ * @param {Song} song A YouTube Song
1172
1166
  * @param {StreamOptions} options options
1173
1167
  * @returns {DisTubeStream}
1174
1168
  * @private
1175
1169
  */
1176
- static YouTube(formats, options = {}) {
1177
- if (!formats || !formats.length)
1170
+ static YouTube(song, options = {}) {
1171
+ if (song.source !== "youtube")
1172
+ throw new DisTubeError("INVALID_TYPE", "youtube", song.source, "Song#source");
1173
+ if (!song.formats?.length)
1178
1174
  throw new DisTubeError("UNAVAILABLE_VIDEO");
1179
1175
  if (!options || typeof options !== "object" || Array.isArray(options)) {
1180
1176
  throw new DisTubeError("INVALID_TYPE", "object", options, "options");
1181
1177
  }
1182
- const bestFormat = chooseBestVideoFormat(formats, options.isLive);
1178
+ const bestFormat = chooseBestVideoFormat(song);
1183
1179
  if (!bestFormat)
1184
1180
  throw new DisTubeError("UNPLAYABLE_FORMATS");
1185
1181
  return new _DisTubeStream(bestFormat.url, options);
@@ -1207,9 +1203,12 @@ var DisTubeStream = _DisTubeStream;
1207
1203
  // src/core/DisTubeHandler.ts
1208
1204
  var import_ytpl = __toESM(require("@distube/ytpl"));
1209
1205
  var import_ytdl_core = __toESM(require("@distube/ytdl-core"));
1206
+ var import_tough_cookie = require("tough-cookie");
1207
+ var _cookie;
1210
1208
  var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1211
1209
  constructor(distube) {
1212
1210
  super(distube);
1211
+ __privateAdd(this, _cookie, "");
1213
1212
  const client = this.client;
1214
1213
  if (this.options.leaveOnEmpty) {
1215
1214
  client.on("voiceStateUpdate", (oldState) => {
@@ -1245,18 +1244,28 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1245
1244
  }
1246
1245
  get ytdlOptions() {
1247
1246
  const options = this.options.ytdlOptions;
1248
- if (this.options.youtubeCookie) {
1249
- if (!options.requestOptions)
1250
- options.requestOptions = {};
1251
- if (!options.requestOptions.headers)
1252
- options.requestOptions.headers = {};
1253
- options.requestOptions.headers.cookie = this.options.youtubeCookie;
1254
- if (this.options.youtubeIdentityToken) {
1255
- options.requestOptions.headers["x-youtube-identity-token"] = this.options.youtubeIdentityToken;
1247
+ if (this.options.youtubeCookie && this.options.youtubeCookie !== __privateGet(this, _cookie)) {
1248
+ const cookies = __privateSet(this, _cookie, this.options.youtubeCookie);
1249
+ if (typeof cookies === "string") {
1250
+ console.warn(
1251
+ "\x1B[33mWARNING:\x1B[0m You are using the old YouTube cookie format, please use the new one instead. (https://distube.js.org/#/docs/DisTube/main/general/cookie)"
1252
+ );
1253
+ options.agent = import_ytdl_core.default.createAgent(
1254
+ cookies.split(";").map((c) => import_tough_cookie.Cookie.parse(c)).filter(isTruthy)
1255
+ );
1256
+ } else {
1257
+ options.agent = import_ytdl_core.default.createAgent(cookies);
1256
1258
  }
1257
1259
  }
1258
1260
  return options;
1259
1261
  }
1262
+ get ytCookie() {
1263
+ const agent = this.ytdlOptions.agent;
1264
+ if (!agent)
1265
+ return "";
1266
+ const { jar } = agent;
1267
+ return jar.getCookieStringSync("https://www.youtube.com");
1268
+ }
1260
1269
  /**
1261
1270
  * @param {string} url url
1262
1271
  * @param {boolean} [basic=false] getBasicInfo?
@@ -1320,7 +1329,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1320
1329
  return playlist;
1321
1330
  }
1322
1331
  if (typeof playlist === "string") {
1323
- const info = await (0, import_ytpl.default)(playlist, { limit: Infinity });
1332
+ const info = await (0, import_ytpl.default)(playlist, { limit: Infinity, requestOptions: { headers: { cookie: this.ytCookie } } });
1324
1333
  const songs = info.items.filter((v) => !v.thumbnail.includes("no_thumbnail")).map((v) => new Song(v, { member, metadata }));
1325
1334
  return new Playlist(
1326
1335
  {
@@ -1378,7 +1387,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1378
1387
  async createSearchMessageCollector(message, results, query) {
1379
1388
  if (!isMessageInstance(message))
1380
1389
  throw new DisTubeError("INVALID_TYPE", "Discord.Message", message, "message");
1381
- if (!Array.isArray(results) || results.length == 0) {
1390
+ if (!Array.isArray(results) || results.length === 0) {
1382
1391
  throw new DisTubeError("INVALID_TYPE", "Array<SearchResult|Song|Playlist>", results, "results");
1383
1392
  }
1384
1393
  if (this.options.searchSongs > 1) {
@@ -1405,8 +1414,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1405
1414
  if (limit > 1) {
1406
1415
  results.splice(limit);
1407
1416
  this.emit("searchResult", message, results, query);
1408
- const c = message.channel;
1409
- const answers = await c.awaitMessages({
1417
+ const answers = await message.channel.awaitMessages({
1410
1418
  filter: (m) => m.author.id === message.author.id,
1411
1419
  max: 1,
1412
1420
  time: this.options.searchCooldown * 1e3,
@@ -1505,9 +1513,9 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1505
1513
  * @param {Song} song A Song
1506
1514
  */
1507
1515
  async attachStreamInfo(song) {
1508
- const { url, source, formats, streamURL, isLive } = song;
1516
+ const { url, source, formats, streamURL } = song;
1509
1517
  if (source === "youtube") {
1510
- if (!formats || !chooseBestVideoFormat(formats, isLive)) {
1518
+ if (!formats || !chooseBestVideoFormat(song)) {
1511
1519
  song._patchYouTube(await this.handler.getYouTubeInfo(url));
1512
1520
  }
1513
1521
  } else if (!streamURL) {
@@ -1523,6 +1531,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1523
1531
  }
1524
1532
  }
1525
1533
  };
1534
+ _cookie = new WeakMap();
1526
1535
  __name(_DisTubeHandler, "DisTubeHandler");
1527
1536
  var DisTubeHandler = _DisTubeHandler;
1528
1537
 
@@ -1541,7 +1550,6 @@ var _Options = class _Options {
1541
1550
  __publicField(this, "searchSongs");
1542
1551
  __publicField(this, "searchCooldown");
1543
1552
  __publicField(this, "youtubeCookie");
1544
- __publicField(this, "youtubeIdentityToken");
1545
1553
  __publicField(this, "customFilters");
1546
1554
  __publicField(this, "ytdlOptions");
1547
1555
  __publicField(this, "nsfw");
@@ -1562,7 +1570,6 @@ var _Options = class _Options {
1562
1570
  this.savePreviousSongs = opts.savePreviousSongs;
1563
1571
  this.searchSongs = opts.searchSongs;
1564
1572
  this.youtubeCookie = opts.youtubeCookie;
1565
- this.youtubeIdentityToken = opts.youtubeIdentityToken;
1566
1573
  this.customFilters = opts.customFilters;
1567
1574
  this.ytdlOptions = opts.ytdlOptions;
1568
1575
  this.searchCooldown = opts.searchCooldown;
@@ -1579,82 +1586,48 @@ var _Options = class _Options {
1579
1586
  };
1580
1587
  _validateOptions = new WeakSet();
1581
1588
  validateOptions_fn = /* @__PURE__ */ __name(function(options = this) {
1582
- if (typeof options.emitNewSongOnly !== "boolean") {
1583
- throw new DisTubeError("INVALID_TYPE", "boolean", options.emitNewSongOnly, "DisTubeOptions.emitNewSongOnly");
1584
- }
1585
- if (typeof options.leaveOnEmpty !== "boolean") {
1586
- throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnEmpty, "DisTubeOptions.leaveOnEmpty");
1587
- }
1588
- if (typeof options.leaveOnFinish !== "boolean") {
1589
- throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnFinish, "DisTubeOptions.leaveOnFinish");
1590
- }
1591
- if (typeof options.leaveOnStop !== "boolean") {
1592
- throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnStop, "DisTubeOptions.leaveOnStop");
1593
- }
1594
- if (typeof options.savePreviousSongs !== "boolean") {
1595
- throw new DisTubeError("INVALID_TYPE", "boolean", options.savePreviousSongs, "DisTubeOptions.savePreviousSongs");
1596
- }
1597
- if (typeof options.joinNewVoiceChannel !== "boolean") {
1598
- throw new DisTubeError(
1599
- "INVALID_TYPE",
1600
- "boolean",
1601
- options.joinNewVoiceChannel,
1602
- "DisTubeOptions.joinNewVoiceChannel"
1603
- );
1604
- }
1605
- if (typeof options.youtubeCookie !== "undefined" && typeof options.youtubeCookie !== "string") {
1606
- throw new DisTubeError("INVALID_TYPE", "string", options.youtubeCookie, "DisTubeOptions.youtubeCookie");
1607
- }
1608
- if (typeof options.youtubeIdentityToken !== "undefined" && typeof options.youtubeIdentityToken !== "string") {
1609
- throw new DisTubeError(
1610
- "INVALID_TYPE",
1611
- "string",
1612
- options.youtubeIdentityToken,
1613
- "DisTubeOptions.youtubeIdentityToken"
1614
- );
1615
- }
1616
- if (typeof options.customFilters !== "undefined" && typeof options.customFilters !== "object" || Array.isArray(options.customFilters)) {
1617
- throw new DisTubeError("INVALID_TYPE", "object", options.customFilters, "DisTubeOptions.customFilters");
1618
- }
1619
- if (typeof options.ytdlOptions !== "object" || Array.isArray(options.ytdlOptions)) {
1620
- throw new DisTubeError("INVALID_TYPE", "object", options.ytdlOptions, "DisTubeOptions.ytdlOptions");
1621
- }
1622
- if (typeof options.searchCooldown !== "number" || isNaN(options.searchCooldown)) {
1623
- throw new DisTubeError("INVALID_TYPE", "number", options.searchCooldown, "DisTubeOptions.searchCooldown");
1624
- }
1625
- if (typeof options.emptyCooldown !== "number" || isNaN(options.emptyCooldown)) {
1626
- throw new DisTubeError("INVALID_TYPE", "number", options.emptyCooldown, "DisTubeOptions.emptyCooldown");
1627
- }
1628
- if (typeof options.searchSongs !== "number" || isNaN(options.searchSongs)) {
1629
- throw new DisTubeError("INVALID_TYPE", "number", options.searchSongs, "DisTubeOptions.searchSongs");
1630
- }
1631
- if (!Array.isArray(options.plugins)) {
1632
- throw new DisTubeError("INVALID_TYPE", "Array<Plugin>", options.plugins, "DisTubeOptions.plugins");
1633
- }
1634
- if (typeof options.nsfw !== "boolean") {
1635
- throw new DisTubeError("INVALID_TYPE", "boolean", options.nsfw, "DisTubeOptions.nsfw");
1636
- }
1637
- if (typeof options.emitAddSongWhenCreatingQueue !== "boolean") {
1638
- throw new DisTubeError(
1639
- "INVALID_TYPE",
1640
- "boolean",
1641
- options.emitAddSongWhenCreatingQueue,
1642
- "DisTubeOptions.emitAddSongWhenCreatingQueue"
1643
- );
1644
- }
1645
- if (typeof options.emitAddListWhenCreatingQueue !== "boolean") {
1646
- throw new DisTubeError(
1647
- "INVALID_TYPE",
1648
- "boolean",
1649
- options.emitAddListWhenCreatingQueue,
1650
- "DisTubeOptions.emitAddListWhenCreatingQueue"
1651
- );
1652
- }
1653
- if (typeof options.streamType !== "number" || isNaN(options.streamType) || !StreamType[options.streamType]) {
1654
- throw new DisTubeError("INVALID_TYPE", "StreamType", options.streamType, "DisTubeOptions.streamType");
1655
- }
1656
- if (typeof options.directLink !== "boolean") {
1657
- throw new DisTubeError("INVALID_TYPE", "boolean", options.directLink, "DisTubeOptions.directLink");
1589
+ const booleanOptions = /* @__PURE__ */ new Set([
1590
+ "emitNewSongOnly",
1591
+ "leaveOnEmpty",
1592
+ "leaveOnFinish",
1593
+ "leaveOnStop",
1594
+ "savePreviousSongs",
1595
+ "joinNewVoiceChannel",
1596
+ "nsfw",
1597
+ "emitAddSongWhenCreatingQueue",
1598
+ "emitAddListWhenCreatingQueue",
1599
+ "directLink"
1600
+ ]);
1601
+ const numberOptions = /* @__PURE__ */ new Set(["searchCooldown", "emptyCooldown", "searchSongs"]);
1602
+ const stringOptions = /* @__PURE__ */ new Set();
1603
+ const objectOptions = /* @__PURE__ */ new Set(["customFilters", "ytdlOptions"]);
1604
+ const optionalOptions = /* @__PURE__ */ new Set(["youtubeCookie", "customFilters"]);
1605
+ for (const [key, value] of Object.entries(options)) {
1606
+ if (value === void 0 && optionalOptions.has(key))
1607
+ continue;
1608
+ if (key === "youtubeCookie" && !Array.isArray(value) && typeof value !== "string") {
1609
+ throw new DisTubeError("INVALID_TYPE", ["Array<Cookie>", "string"], value, `DisTubeOptions.${key}`);
1610
+ } else if (key === "streamType" && (typeof value !== "number" || isNaN(value) || !StreamType[value])) {
1611
+ throw new DisTubeError("INVALID_TYPE", "StreamType", value, `DisTubeOptions.${key}`);
1612
+ } else if (key === "plugins" && !Array.isArray(value)) {
1613
+ throw new DisTubeError("INVALID_TYPE", "Array<Plugin>", value, `DisTubeOptions.${key}`);
1614
+ } else if (booleanOptions.has(key)) {
1615
+ if (typeof value !== "boolean") {
1616
+ throw new DisTubeError("INVALID_TYPE", "boolean", value, `DisTubeOptions.${key}`);
1617
+ }
1618
+ } else if (numberOptions.has(key)) {
1619
+ if (typeof value !== "number" || isNaN(value)) {
1620
+ throw new DisTubeError("INVALID_TYPE", "number", value, `DisTubeOptions.${key}`);
1621
+ }
1622
+ } else if (stringOptions.has(key)) {
1623
+ if (typeof value !== "string") {
1624
+ throw new DisTubeError("INVALID_TYPE", "string", value, `DisTubeOptions.${key}`);
1625
+ }
1626
+ } else if (objectOptions.has(key)) {
1627
+ if (typeof value !== "object" || Array.isArray(value)) {
1628
+ throw new DisTubeError("INVALID_TYPE", "object", value, `DisTubeOptions.${key}`);
1629
+ }
1630
+ }
1658
1631
  }
1659
1632
  }, "#validateOptions");
1660
1633
  __name(_Options, "Options");
@@ -1789,14 +1762,14 @@ var _FilterManager = class _FilterManager extends BaseManager {
1789
1762
  add(filterOrFilters, override = false) {
1790
1763
  if (Array.isArray(filterOrFilters)) {
1791
1764
  for (const filter of filterOrFilters) {
1792
- const f = __privateMethod(this, _resolve, resolve_fn).call(this, filter);
1793
- if (override || !this.has(f))
1794
- this.collection.set(f.name, f);
1765
+ const ft = __privateMethod(this, _resolve, resolve_fn).call(this, filter);
1766
+ if (override || !this.has(ft))
1767
+ this.collection.set(ft.name, ft);
1795
1768
  }
1796
1769
  } else {
1797
- const f = __privateMethod(this, _resolve, resolve_fn).call(this, filterOrFilters);
1798
- if (override || !this.has(f))
1799
- this.collection.set(f.name, f);
1770
+ const ft = __privateMethod(this, _resolve, resolve_fn).call(this, filterOrFilters);
1771
+ if (override || !this.has(ft))
1772
+ this.collection.set(ft.name, ft);
1800
1773
  }
1801
1774
  __privateMethod(this, _apply, apply_fn).call(this);
1802
1775
  return this;
@@ -1831,7 +1804,7 @@ var _FilterManager = class _FilterManager extends BaseManager {
1831
1804
  */
1832
1805
  remove(filterOrFilters) {
1833
1806
  if (Array.isArray(filterOrFilters))
1834
- filterOrFilters.map((f) => __privateMethod(this, _removeFn, removeFn_fn).call(this, f));
1807
+ filterOrFilters.forEach((f) => __privateMethod(this, _removeFn, removeFn_fn).call(this, f));
1835
1808
  else
1836
1809
  __privateMethod(this, _removeFn, removeFn_fn).call(this, filterOrFilters);
1837
1810
  __privateMethod(this, _apply, apply_fn).call(this);
@@ -1969,15 +1942,15 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
1969
1942
  * @returns {DisTubeStream}
1970
1943
  */
1971
1944
  createStream(queue) {
1972
- const { duration, formats, isLive, source, streamURL } = queue.songs[0];
1945
+ const song = queue.songs[0];
1946
+ const { duration, source, streamURL } = song;
1973
1947
  const streamOptions = {
1974
1948
  ffmpegArgs: queue.filters.ffmpegArgs,
1975
1949
  seek: duration ? queue.beginTime : void 0,
1976
- isLive,
1977
1950
  type: this.options.streamType
1978
1951
  };
1979
1952
  if (source === "youtube")
1980
- return DisTubeStream.YouTube(formats, streamOptions);
1953
+ return DisTubeStream.YouTube(song, streamOptions);
1981
1954
  return DisTubeStream.DirectLink(streamURL, streamOptions);
1982
1955
  }
1983
1956
  /**
@@ -2241,7 +2214,7 @@ var _Queue = class _Queue extends DisTubeBase {
2241
2214
  this.songs.splice(position, 0, song);
2242
2215
  }
2243
2216
  if (Array.isArray(song))
2244
- song.map((s) => delete s.formats);
2217
+ song.forEach((s) => delete s.formats);
2245
2218
  else
2246
2219
  delete song.formats;
2247
2220
  return this;
@@ -2624,15 +2597,15 @@ function toSecond(input) {
2624
2597
  return 0;
2625
2598
  if (typeof input !== "string")
2626
2599
  return Number(input) || 0;
2627
- if (input.match(/:/g)) {
2600
+ if (input.includes(":")) {
2628
2601
  const time = input.split(":").reverse();
2629
- let s = 0;
2602
+ let seconds = 0;
2630
2603
  for (let i = 0; i < 3; i++)
2631
2604
  if (time[i])
2632
- s += Number(time[i].replace(/[^\d.]+/g, "")) * Math.pow(60, i);
2605
+ seconds += Number(time[i].replace(/[^\d.]+/g, "")) * Math.pow(60, i);
2633
2606
  if (time.length > 3)
2634
- s += Number(time[3].replace(/[^\d.]+/g, "")) * 24 * 60 * 60;
2635
- return s;
2607
+ seconds += Number(time[3].replace(/[^\d.]+/g, "")) * 24 * 60 * 60;
2608
+ return seconds;
2636
2609
  } else {
2637
2610
  return Number(input.replace(/[^\d.]+/g, "")) || 0;
2638
2611
  }
@@ -2685,23 +2658,23 @@ function isSnowflake(id) {
2685
2658
  }
2686
2659
  __name(isSnowflake, "isSnowflake");
2687
2660
  function isMemberInstance(member) {
2688
- return !!member && isSnowflake(member.id) && isSnowflake(member.guild?.id) && isSnowflake(member.user?.id) && member.id === member.user.id;
2661
+ return Boolean(member) && isSnowflake(member.id) && isSnowflake(member.guild?.id) && isSnowflake(member.user?.id) && member.id === member.user.id;
2689
2662
  }
2690
2663
  __name(isMemberInstance, "isMemberInstance");
2691
2664
  function isTextChannelInstance(channel) {
2692
- return !!channel && isSnowflake(channel.id) && isSnowflake(channel.guildId) && typeof channel.name === "string" && import_discord3.Constants.TextBasedChannelTypes.includes(channel.type) && "messages" in channel && typeof channel.send === "function";
2665
+ return Boolean(channel) && isSnowflake(channel.id) && isSnowflake(channel.guildId || channel.guild?.id) && import_discord3.Constants.TextBasedChannelTypes.includes(channel.type) && typeof channel.send === "function" && (typeof channel.nsfw === "boolean" || typeof channel.parent?.nsfw === "boolean");
2693
2666
  }
2694
2667
  __name(isTextChannelInstance, "isTextChannelInstance");
2695
2668
  function isMessageInstance(message) {
2696
- return !!message && isSnowflake(message.id) && isSnowflake(message.guildId) && isMemberInstance(message.member) && isTextChannelInstance(message.channel) && import_discord3.Constants.NonSystemMessageTypes.includes(message.type) && message.member.id === message.author?.id;
2669
+ return Boolean(message) && isSnowflake(message.id) && isSnowflake(message.guildId || message.guild?.id) && isMemberInstance(message.member) && isTextChannelInstance(message.channel) && import_discord3.Constants.NonSystemMessageTypes.includes(message.type) && message.member.id === message.author?.id;
2697
2670
  }
2698
2671
  __name(isMessageInstance, "isMessageInstance");
2699
2672
  function isSupportedVoiceChannel(channel) {
2700
- return !!channel && isSnowflake(channel.id) && isSnowflake(channel.guildId) && import_discord3.Constants.VoiceBasedChannelTypes.includes(channel.type);
2673
+ return Boolean(channel) && isSnowflake(channel.id) && isSnowflake(channel.guildId || channel.guild?.id) && import_discord3.Constants.VoiceBasedChannelTypes.includes(channel.type);
2701
2674
  }
2702
2675
  __name(isSupportedVoiceChannel, "isSupportedVoiceChannel");
2703
2676
  function isGuildInstance(guild) {
2704
- return !!guild && isSnowflake(guild.id) && isSnowflake(guild.ownerId) && typeof guild.name === "string";
2677
+ return Boolean(guild) && isSnowflake(guild.id) && isSnowflake(guild.ownerId) && typeof guild.name === "string";
2705
2678
  }
2706
2679
  __name(isGuildInstance, "isGuildInstance");
2707
2680
  function resolveGuildId(resolvable) {
@@ -2723,7 +2696,7 @@ function resolveGuildId(resolvable) {
2723
2696
  }
2724
2697
  __name(resolveGuildId, "resolveGuildId");
2725
2698
  function isClientInstance(client) {
2726
- return !!client && typeof client.login === "function";
2699
+ return Boolean(client) && typeof client.login === "function";
2727
2700
  }
2728
2701
  __name(isClientInstance, "isClientInstance");
2729
2702
  function checkInvalidKey(target, source, sourceName) {
@@ -2757,6 +2730,7 @@ function isNsfwChannel(channel) {
2757
2730
  return channel.nsfw;
2758
2731
  }
2759
2732
  __name(isNsfwChannel, "isNsfwChannel");
2733
+ var isTruthy = /* @__PURE__ */ __name((x) => Boolean(x), "isTruthy");
2760
2734
 
2761
2735
  // src/plugin/DirectLink.ts
2762
2736
  var import_undici = require("undici");
@@ -2772,8 +2746,7 @@ var _DirectLinkPlugin = class _DirectLinkPlugin extends ExtractorPlugin {
2772
2746
  }
2773
2747
  return false;
2774
2748
  }
2775
- // eslint-disable-next-line @typescript-eslint/require-await
2776
- async resolve(url, options = {}) {
2749
+ resolve(url, options = {}) {
2777
2750
  url = url.replace(/\/+$/, "");
2778
2751
  return new Song(
2779
2752
  {
@@ -2792,23 +2765,11 @@ var DirectLinkPlugin = _DirectLinkPlugin;
2792
2765
  var import_ytsr = __toESM(require("@distube/ytsr"));
2793
2766
  var import_tiny_typed_emitter2 = require("tiny-typed-emitter");
2794
2767
  var { version } = require_package();
2768
+ var _getQueue, getQueue_fn;
2795
2769
  var _DisTube = class _DisTube extends import_tiny_typed_emitter2.TypedEmitter {
2796
- /**
2797
- * Create a new DisTube class.
2798
- * @param {Discord.Client} client Discord.JS client
2799
- * @param {DisTubeOptions} [otp] Custom DisTube options
2800
- * @throws {DisTubeError}
2801
- * @example
2802
- * const Discord = require('discord.js'),
2803
- * DisTube = require('distube'),
2804
- * client = new Discord.Client();
2805
- * // Create a new DisTube
2806
- * const distube = new DisTube.default(client, { searchSongs: 10 });
2807
- * // client.DisTube = distube // make it access easily
2808
- * client.login("Your Discord Bot Token")
2809
- */
2810
2770
  constructor(client, otp = {}) {
2811
2771
  super();
2772
+ __privateAdd(this, _getQueue);
2812
2773
  __publicField(this, "handler");
2813
2774
  __publicField(this, "options");
2814
2775
  __publicField(this, "client");
@@ -2829,7 +2790,7 @@ var _DisTube = class _DisTube extends import_tiny_typed_emitter2.TypedEmitter {
2829
2790
  this.filters = { ...defaultFilters, ...this.options.customFilters };
2830
2791
  if (this.options.directLink)
2831
2792
  this.options.plugins.push(new DirectLinkPlugin());
2832
- this.options.plugins.map((p) => p.init(this));
2793
+ this.options.plugins.forEach((p) => p.init(this));
2833
2794
  this.extractorPlugins = this.options.plugins.filter((p) => p.type === "extractor");
2834
2795
  this.customPlugins = this.options.plugins.filter((p) => p.type === "custom");
2835
2796
  }
@@ -2889,7 +2850,7 @@ var _DisTube = class _DisTube extends import_tiny_typed_emitter2.TypedEmitter {
2889
2850
  throw new DisTubeError("INVALID_TYPE", "Discord.GuildMember", member, "options.member");
2890
2851
  }
2891
2852
  const queue = this.getQueue(voiceChannel);
2892
- const queuing = !!queue && !queue._taskQueue.hasResolveTask;
2853
+ const queuing = queue && !queue._taskQueue.hasResolveTask;
2893
2854
  if (queuing)
2894
2855
  await queue?._taskQueue.queuing(true);
2895
2856
  try {
@@ -2965,13 +2926,13 @@ ${e.message}`;
2965
2926
  const promises = filteredSongs.map(
2966
2927
  (song) => this.handler.resolve(song, { member, metadata }).catch(() => void 0)
2967
2928
  );
2968
- resolvedSongs = (await Promise.all(promises)).filter((s) => !!s);
2929
+ resolvedSongs = (await Promise.all(promises)).filter((s) => Boolean(s));
2969
2930
  } else {
2970
2931
  const resolved = [];
2971
2932
  for (const song of filteredSongs) {
2972
2933
  resolved.push(await this.handler.resolve(song, { member, metadata }).catch(() => void 0));
2973
2934
  }
2974
- resolvedSongs = resolved.filter((s) => !!s);
2935
+ resolvedSongs = resolved.filter((s) => Boolean(s));
2975
2936
  }
2976
2937
  return new Playlist(resolvedSongs, { member, properties, metadata });
2977
2938
  }
@@ -3000,7 +2961,7 @@ ${e.message}`;
3000
2961
  throw new DisTubeError("INVALID_TYPE", "boolean", opts.safeSearch, "options.safeSearch");
3001
2962
  }
3002
2963
  try {
3003
- const search = await (0, import_ytsr.default)(string, opts);
2964
+ const search = await (0, import_ytsr.default)(string, { ...opts, requestOptions: { headers: { cookie: this.handler.ytCookie } } });
3004
2965
  const results = search.items.map((i) => {
3005
2966
  if (i.type === "video")
3006
2967
  return new SearchResultVideo(i);
@@ -3044,10 +3005,7 @@ ${e.message}`;
3044
3005
  * @throws {Error}
3045
3006
  */
3046
3007
  pause(guild) {
3047
- const q = this.getQueue(guild);
3048
- if (!q)
3049
- throw new DisTubeError("NO_QUEUE");
3050
- return q.pause();
3008
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).pause();
3051
3009
  }
3052
3010
  /**
3053
3011
  * Resume the guild stream
@@ -3056,10 +3014,7 @@ ${e.message}`;
3056
3014
  * @throws {Error}
3057
3015
  */
3058
3016
  resume(guild) {
3059
- const q = this.getQueue(guild);
3060
- if (!q)
3061
- throw new DisTubeError("NO_QUEUE");
3062
- return q.resume();
3017
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).resume();
3063
3018
  }
3064
3019
  /**
3065
3020
  * Stop the guild stream
@@ -3078,10 +3033,7 @@ ${e.message}`;
3078
3033
  * });
3079
3034
  */
3080
3035
  stop(guild) {
3081
- const q = this.getQueue(guild);
3082
- if (!q)
3083
- throw new DisTubeError("NO_QUEUE");
3084
- return q.stop();
3036
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).stop();
3085
3037
  }
3086
3038
  /**
3087
3039
  * Set the guild stream's volume
@@ -3099,10 +3051,7 @@ ${e.message}`;
3099
3051
  * });
3100
3052
  */
3101
3053
  setVolume(guild, percent) {
3102
- const q = this.getQueue(guild);
3103
- if (!q)
3104
- throw new DisTubeError("NO_QUEUE");
3105
- return q.setVolume(percent);
3054
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).setVolume(percent);
3106
3055
  }
3107
3056
  /**
3108
3057
  * Skip the playing song if there is a next song in the queue.
@@ -3121,10 +3070,7 @@ ${e.message}`;
3121
3070
  * });
3122
3071
  */
3123
3072
  skip(guild) {
3124
- const q = this.getQueue(guild);
3125
- if (!q)
3126
- throw new DisTubeError("NO_QUEUE");
3127
- return q.skip();
3073
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).skip();
3128
3074
  }
3129
3075
  /**
3130
3076
  * Play the previous song
@@ -3141,10 +3087,7 @@ ${e.message}`;
3141
3087
  * });
3142
3088
  */
3143
3089
  previous(guild) {
3144
- const q = this.getQueue(guild);
3145
- if (!q)
3146
- throw new DisTubeError("NO_QUEUE");
3147
- return q.previous();
3090
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).previous();
3148
3091
  }
3149
3092
  /**
3150
3093
  * Shuffle the guild queue songs
@@ -3160,10 +3103,7 @@ ${e.message}`;
3160
3103
  * });
3161
3104
  */
3162
3105
  shuffle(guild) {
3163
- const q = this.getQueue(guild);
3164
- if (!q)
3165
- throw new DisTubeError("NO_QUEUE");
3166
- return q.shuffle();
3106
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).shuffle();
3167
3107
  }
3168
3108
  /**
3169
3109
  * Jump to the song number in the queue.
@@ -3184,10 +3124,7 @@ ${e.message}`;
3184
3124
  * });
3185
3125
  */
3186
3126
  jump(guild, num) {
3187
- const q = this.getQueue(guild);
3188
- if (!q)
3189
- throw new DisTubeError("NO_QUEUE");
3190
- return q.jump(num);
3127
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).jump(num);
3191
3128
  }
3192
3129
  /**
3193
3130
  * Set the repeat mode of the guild queue.\
@@ -3223,10 +3160,7 @@ ${e.message}`;
3223
3160
  * message.channel.send("Set repeat mode to `" + mode + "`");
3224
3161
  */
3225
3162
  setRepeatMode(guild, mode) {
3226
- const q = this.getQueue(guild);
3227
- if (!q)
3228
- throw new DisTubeError("NO_QUEUE");
3229
- return q.setRepeatMode(mode);
3163
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).setRepeatMode(mode);
3230
3164
  }
3231
3165
  /**
3232
3166
  * Toggle autoplay mode
@@ -3245,11 +3179,9 @@ ${e.message}`;
3245
3179
  * });
3246
3180
  */
3247
3181
  toggleAutoplay(guild) {
3248
- const q = this.getQueue(guild);
3249
- if (!q)
3250
- throw new DisTubeError("NO_QUEUE");
3251
- q.autoplay = !q.autoplay;
3252
- return q.autoplay;
3182
+ const queue = __privateMethod(this, _getQueue, getQueue_fn).call(this, guild);
3183
+ queue.autoplay = !queue.autoplay;
3184
+ return queue.autoplay;
3253
3185
  }
3254
3186
  /**
3255
3187
  * Add related song to the queue
@@ -3257,10 +3189,7 @@ ${e.message}`;
3257
3189
  * @returns {Promise<Song>} The guild queue
3258
3190
  */
3259
3191
  addRelatedSong(guild) {
3260
- const q = this.getQueue(guild);
3261
- if (!q)
3262
- throw new DisTubeError("NO_QUEUE");
3263
- return q.addRelatedSong();
3192
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).addRelatedSong();
3264
3193
  }
3265
3194
  /**
3266
3195
  * Set the playing time to another position
@@ -3277,10 +3206,7 @@ ${e.message}`;
3277
3206
  * });
3278
3207
  */
3279
3208
  seek(guild, time) {
3280
- const q = this.getQueue(guild);
3281
- if (!q)
3282
- throw new DisTubeError("NO_QUEUE");
3283
- return q.seek(time);
3209
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).seek(time);
3284
3210
  }
3285
3211
  /**
3286
3212
  * Emit error event
@@ -3300,6 +3226,13 @@ ${e.message}`;
3300
3226
  }
3301
3227
  }
3302
3228
  };
3229
+ _getQueue = new WeakSet();
3230
+ getQueue_fn = /* @__PURE__ */ __name(function(guild) {
3231
+ const queue = this.getQueue(guild);
3232
+ if (!queue)
3233
+ throw new DisTubeError("NO_QUEUE");
3234
+ return queue;
3235
+ }, "#getQueue");
3303
3236
  __name(_DisTube, "DisTube");
3304
3237
  var DisTube = _DisTube;
3305
3238
  // Annotate the CommonJS export names for ESM import in node:
@@ -3347,6 +3280,7 @@ var DisTube = _DisTube;
3347
3280
  isSnowflake,
3348
3281
  isSupportedVoiceChannel,
3349
3282
  isTextChannelInstance,
3283
+ isTruthy,
3350
3284
  isURL,
3351
3285
  isVoiceChannelEmpty,
3352
3286
  objectKeys,