distube 4.0.6 → 4.1.0

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.0",
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.12.1",
128
+ "@distube/ytpl": "^1.1.4",
129
+ "@distube/ytsr": "^1.1.10",
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.23.0"
134
135
  },
135
136
  devDependencies: {
136
- "@babel/core": "^7.22.9",
137
+ "@babel/core": "^7.22.11",
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.22.10",
142
+ "@babel/preset-typescript": "^7.22.11",
143
+ "@commitlint/cli": "^17.7.1",
144
+ "@commitlint/config-conventional": "^17.7.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.4",
148
+ "@types/node": "^20.5.7",
149
+ "@types/tough-cookie": "^4.0.2",
150
+ "@typescript-eslint/eslint-plugin": "^6.5.0",
151
+ "@typescript-eslint/parser": "^6.5.0",
152
+ "babel-jest": "^29.6.4",
153
+ "discord.js": "^14.13.0",
154
+ eslint: "^8.48.0",
153
155
  "eslint-config-distube": "^1.6.4",
154
- "eslint-config-prettier": "^8.9.0",
156
+ "eslint-config-prettier": "^9.0.0",
155
157
  "eslint-plugin-deprecation": "^1.5.0",
156
- "eslint-plugin-jsdoc": "^46.4.5",
158
+ "eslint-plugin-jsdoc": "^46.5.1",
157
159
  husky: "^8.0.3",
158
- jest: "^29.6.2",
160
+ jest: "^29.6.4",
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.13.2",
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
@@ -1207,9 +1207,12 @@ var DisTubeStream = _DisTubeStream;
1207
1207
  // src/core/DisTubeHandler.ts
1208
1208
  var import_ytpl = __toESM(require("@distube/ytpl"));
1209
1209
  var import_ytdl_core = __toESM(require("@distube/ytdl-core"));
1210
+ var import_tough_cookie = require("tough-cookie");
1211
+ var _cookie;
1210
1212
  var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1211
1213
  constructor(distube) {
1212
1214
  super(distube);
1215
+ __privateAdd(this, _cookie, "");
1213
1216
  const client = this.client;
1214
1217
  if (this.options.leaveOnEmpty) {
1215
1218
  client.on("voiceStateUpdate", (oldState) => {
@@ -1245,18 +1248,28 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1245
1248
  }
1246
1249
  get ytdlOptions() {
1247
1250
  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;
1251
+ if (this.options.youtubeCookie && this.options.youtubeCookie !== __privateGet(this, _cookie)) {
1252
+ const cookies = __privateSet(this, _cookie, this.options.youtubeCookie);
1253
+ if (typeof cookies === "string") {
1254
+ console.warn(
1255
+ "\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)"
1256
+ );
1257
+ options.agent = import_ytdl_core.default.createAgent(
1258
+ cookies.split(";").map((c) => import_tough_cookie.Cookie.parse(c)).filter(isTruthy)
1259
+ );
1260
+ } else {
1261
+ options.agent = import_ytdl_core.default.createAgent(cookies);
1256
1262
  }
1257
1263
  }
1258
1264
  return options;
1259
1265
  }
1266
+ get ytCookie() {
1267
+ const agent = this.ytdlOptions.agent;
1268
+ if (!agent)
1269
+ return "";
1270
+ const { jar } = agent;
1271
+ return jar.getCookieStringSync("https://www.youtube.com");
1272
+ }
1260
1273
  /**
1261
1274
  * @param {string} url url
1262
1275
  * @param {boolean} [basic=false] getBasicInfo?
@@ -1320,7 +1333,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1320
1333
  return playlist;
1321
1334
  }
1322
1335
  if (typeof playlist === "string") {
1323
- const info = await (0, import_ytpl.default)(playlist, { limit: Infinity });
1336
+ const info = await (0, import_ytpl.default)(playlist, { limit: Infinity, requestOptions: { headers: { cookie: this.ytCookie } } });
1324
1337
  const songs = info.items.filter((v) => !v.thumbnail.includes("no_thumbnail")).map((v) => new Song(v, { member, metadata }));
1325
1338
  return new Playlist(
1326
1339
  {
@@ -1378,7 +1391,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1378
1391
  async createSearchMessageCollector(message, results, query) {
1379
1392
  if (!isMessageInstance(message))
1380
1393
  throw new DisTubeError("INVALID_TYPE", "Discord.Message", message, "message");
1381
- if (!Array.isArray(results) || results.length == 0) {
1394
+ if (!Array.isArray(results) || results.length === 0) {
1382
1395
  throw new DisTubeError("INVALID_TYPE", "Array<SearchResult|Song|Playlist>", results, "results");
1383
1396
  }
1384
1397
  if (this.options.searchSongs > 1) {
@@ -1405,8 +1418,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1405
1418
  if (limit > 1) {
1406
1419
  results.splice(limit);
1407
1420
  this.emit("searchResult", message, results, query);
1408
- const c = message.channel;
1409
- const answers = await c.awaitMessages({
1421
+ const answers = await message.channel.awaitMessages({
1410
1422
  filter: (m) => m.author.id === message.author.id,
1411
1423
  max: 1,
1412
1424
  time: this.options.searchCooldown * 1e3,
@@ -1523,6 +1535,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
1523
1535
  }
1524
1536
  }
1525
1537
  };
1538
+ _cookie = new WeakMap();
1526
1539
  __name(_DisTubeHandler, "DisTubeHandler");
1527
1540
  var DisTubeHandler = _DisTubeHandler;
1528
1541
 
@@ -1541,7 +1554,6 @@ var _Options = class _Options {
1541
1554
  __publicField(this, "searchSongs");
1542
1555
  __publicField(this, "searchCooldown");
1543
1556
  __publicField(this, "youtubeCookie");
1544
- __publicField(this, "youtubeIdentityToken");
1545
1557
  __publicField(this, "customFilters");
1546
1558
  __publicField(this, "ytdlOptions");
1547
1559
  __publicField(this, "nsfw");
@@ -1562,7 +1574,6 @@ var _Options = class _Options {
1562
1574
  this.savePreviousSongs = opts.savePreviousSongs;
1563
1575
  this.searchSongs = opts.searchSongs;
1564
1576
  this.youtubeCookie = opts.youtubeCookie;
1565
- this.youtubeIdentityToken = opts.youtubeIdentityToken;
1566
1577
  this.customFilters = opts.customFilters;
1567
1578
  this.ytdlOptions = opts.ytdlOptions;
1568
1579
  this.searchCooldown = opts.searchCooldown;
@@ -1579,82 +1590,48 @@ var _Options = class _Options {
1579
1590
  };
1580
1591
  _validateOptions = new WeakSet();
1581
1592
  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");
1593
+ const booleanOptions = /* @__PURE__ */ new Set([
1594
+ "emitNewSongOnly",
1595
+ "leaveOnEmpty",
1596
+ "leaveOnFinish",
1597
+ "leaveOnStop",
1598
+ "savePreviousSongs",
1599
+ "joinNewVoiceChannel",
1600
+ "nsfw",
1601
+ "emitAddSongWhenCreatingQueue",
1602
+ "emitAddListWhenCreatingQueue",
1603
+ "directLink"
1604
+ ]);
1605
+ const numberOptions = /* @__PURE__ */ new Set(["searchCooldown", "emptyCooldown", "searchSongs"]);
1606
+ const stringOptions = /* @__PURE__ */ new Set();
1607
+ const objectOptions = /* @__PURE__ */ new Set(["customFilters", "ytdlOptions"]);
1608
+ const optionalOptions = /* @__PURE__ */ new Set(["youtubeCookie", "customFilters"]);
1609
+ for (const [key, value] of Object.entries(options)) {
1610
+ if (value === void 0 && optionalOptions.has(key))
1611
+ continue;
1612
+ if (key === "youtubeCookie" && !Array.isArray(value) && typeof value !== "string") {
1613
+ throw new DisTubeError("INVALID_TYPE", ["Array<Cookie>", "string"], value, `DisTubeOptions.${key}`);
1614
+ } else if (key === "streamType" && (typeof value !== "number" || isNaN(value) || !StreamType[value])) {
1615
+ throw new DisTubeError("INVALID_TYPE", "StreamType", value, `DisTubeOptions.${key}`);
1616
+ } else if (key === "plugins" && !Array.isArray(value)) {
1617
+ throw new DisTubeError("INVALID_TYPE", "Array<Plugin>", value, `DisTubeOptions.${key}`);
1618
+ } else if (booleanOptions.has(key)) {
1619
+ if (typeof value !== "boolean") {
1620
+ throw new DisTubeError("INVALID_TYPE", "boolean", value, `DisTubeOptions.${key}`);
1621
+ }
1622
+ } else if (numberOptions.has(key)) {
1623
+ if (typeof value !== "number" || isNaN(value)) {
1624
+ throw new DisTubeError("INVALID_TYPE", "number", value, `DisTubeOptions.${key}`);
1625
+ }
1626
+ } else if (stringOptions.has(key)) {
1627
+ if (typeof value !== "string") {
1628
+ throw new DisTubeError("INVALID_TYPE", "string", value, `DisTubeOptions.${key}`);
1629
+ }
1630
+ } else if (objectOptions.has(key)) {
1631
+ if (typeof value !== "object" || Array.isArray(value)) {
1632
+ throw new DisTubeError("INVALID_TYPE", "object", value, `DisTubeOptions.${key}`);
1633
+ }
1634
+ }
1658
1635
  }
1659
1636
  }, "#validateOptions");
1660
1637
  __name(_Options, "Options");
@@ -1789,14 +1766,14 @@ var _FilterManager = class _FilterManager extends BaseManager {
1789
1766
  add(filterOrFilters, override = false) {
1790
1767
  if (Array.isArray(filterOrFilters)) {
1791
1768
  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);
1769
+ const ft = __privateMethod(this, _resolve, resolve_fn).call(this, filter);
1770
+ if (override || !this.has(ft))
1771
+ this.collection.set(ft.name, ft);
1795
1772
  }
1796
1773
  } 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);
1774
+ const ft = __privateMethod(this, _resolve, resolve_fn).call(this, filterOrFilters);
1775
+ if (override || !this.has(ft))
1776
+ this.collection.set(ft.name, ft);
1800
1777
  }
1801
1778
  __privateMethod(this, _apply, apply_fn).call(this);
1802
1779
  return this;
@@ -1831,7 +1808,7 @@ var _FilterManager = class _FilterManager extends BaseManager {
1831
1808
  */
1832
1809
  remove(filterOrFilters) {
1833
1810
  if (Array.isArray(filterOrFilters))
1834
- filterOrFilters.map((f) => __privateMethod(this, _removeFn, removeFn_fn).call(this, f));
1811
+ filterOrFilters.forEach((f) => __privateMethod(this, _removeFn, removeFn_fn).call(this, f));
1835
1812
  else
1836
1813
  __privateMethod(this, _removeFn, removeFn_fn).call(this, filterOrFilters);
1837
1814
  __privateMethod(this, _apply, apply_fn).call(this);
@@ -2241,7 +2218,7 @@ var _Queue = class _Queue extends DisTubeBase {
2241
2218
  this.songs.splice(position, 0, song);
2242
2219
  }
2243
2220
  if (Array.isArray(song))
2244
- song.map((s) => delete s.formats);
2221
+ song.forEach((s) => delete s.formats);
2245
2222
  else
2246
2223
  delete song.formats;
2247
2224
  return this;
@@ -2624,15 +2601,15 @@ function toSecond(input) {
2624
2601
  return 0;
2625
2602
  if (typeof input !== "string")
2626
2603
  return Number(input) || 0;
2627
- if (input.match(/:/g)) {
2604
+ if (input.includes(":")) {
2628
2605
  const time = input.split(":").reverse();
2629
- let s = 0;
2606
+ let seconds = 0;
2630
2607
  for (let i = 0; i < 3; i++)
2631
2608
  if (time[i])
2632
- s += Number(time[i].replace(/[^\d.]+/g, "")) * Math.pow(60, i);
2609
+ seconds += Number(time[i].replace(/[^\d.]+/g, "")) * Math.pow(60, i);
2633
2610
  if (time.length > 3)
2634
- s += Number(time[3].replace(/[^\d.]+/g, "")) * 24 * 60 * 60;
2635
- return s;
2611
+ seconds += Number(time[3].replace(/[^\d.]+/g, "")) * 24 * 60 * 60;
2612
+ return seconds;
2636
2613
  } else {
2637
2614
  return Number(input.replace(/[^\d.]+/g, "")) || 0;
2638
2615
  }
@@ -2685,23 +2662,23 @@ function isSnowflake(id) {
2685
2662
  }
2686
2663
  __name(isSnowflake, "isSnowflake");
2687
2664
  function isMemberInstance(member) {
2688
- return !!member && isSnowflake(member.id) && isSnowflake(member.guild?.id) && isSnowflake(member.user?.id) && member.id === member.user.id;
2665
+ return Boolean(member) && isSnowflake(member.id) && isSnowflake(member.guild?.id) && isSnowflake(member.user?.id) && member.id === member.user.id;
2689
2666
  }
2690
2667
  __name(isMemberInstance, "isMemberInstance");
2691
2668
  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";
2669
+ 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
2670
  }
2694
2671
  __name(isTextChannelInstance, "isTextChannelInstance");
2695
2672
  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;
2673
+ 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
2674
  }
2698
2675
  __name(isMessageInstance, "isMessageInstance");
2699
2676
  function isSupportedVoiceChannel(channel) {
2700
- return !!channel && isSnowflake(channel.id) && isSnowflake(channel.guildId) && import_discord3.Constants.VoiceBasedChannelTypes.includes(channel.type);
2677
+ return Boolean(channel) && isSnowflake(channel.id) && isSnowflake(channel.guildId || channel.guild?.id) && import_discord3.Constants.VoiceBasedChannelTypes.includes(channel.type);
2701
2678
  }
2702
2679
  __name(isSupportedVoiceChannel, "isSupportedVoiceChannel");
2703
2680
  function isGuildInstance(guild) {
2704
- return !!guild && isSnowflake(guild.id) && isSnowflake(guild.ownerId) && typeof guild.name === "string";
2681
+ return Boolean(guild) && isSnowflake(guild.id) && isSnowflake(guild.ownerId) && typeof guild.name === "string";
2705
2682
  }
2706
2683
  __name(isGuildInstance, "isGuildInstance");
2707
2684
  function resolveGuildId(resolvable) {
@@ -2723,7 +2700,7 @@ function resolveGuildId(resolvable) {
2723
2700
  }
2724
2701
  __name(resolveGuildId, "resolveGuildId");
2725
2702
  function isClientInstance(client) {
2726
- return !!client && typeof client.login === "function";
2703
+ return Boolean(client) && typeof client.login === "function";
2727
2704
  }
2728
2705
  __name(isClientInstance, "isClientInstance");
2729
2706
  function checkInvalidKey(target, source, sourceName) {
@@ -2757,6 +2734,7 @@ function isNsfwChannel(channel) {
2757
2734
  return channel.nsfw;
2758
2735
  }
2759
2736
  __name(isNsfwChannel, "isNsfwChannel");
2737
+ var isTruthy = /* @__PURE__ */ __name((x) => Boolean(x), "isTruthy");
2760
2738
 
2761
2739
  // src/plugin/DirectLink.ts
2762
2740
  var import_undici = require("undici");
@@ -2772,8 +2750,7 @@ var _DirectLinkPlugin = class _DirectLinkPlugin extends ExtractorPlugin {
2772
2750
  }
2773
2751
  return false;
2774
2752
  }
2775
- // eslint-disable-next-line @typescript-eslint/require-await
2776
- async resolve(url, options = {}) {
2753
+ resolve(url, options = {}) {
2777
2754
  url = url.replace(/\/+$/, "");
2778
2755
  return new Song(
2779
2756
  {
@@ -2792,23 +2769,11 @@ var DirectLinkPlugin = _DirectLinkPlugin;
2792
2769
  var import_ytsr = __toESM(require("@distube/ytsr"));
2793
2770
  var import_tiny_typed_emitter2 = require("tiny-typed-emitter");
2794
2771
  var { version } = require_package();
2772
+ var _getQueue, getQueue_fn;
2795
2773
  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
2774
  constructor(client, otp = {}) {
2811
2775
  super();
2776
+ __privateAdd(this, _getQueue);
2812
2777
  __publicField(this, "handler");
2813
2778
  __publicField(this, "options");
2814
2779
  __publicField(this, "client");
@@ -2829,7 +2794,7 @@ var _DisTube = class _DisTube extends import_tiny_typed_emitter2.TypedEmitter {
2829
2794
  this.filters = { ...defaultFilters, ...this.options.customFilters };
2830
2795
  if (this.options.directLink)
2831
2796
  this.options.plugins.push(new DirectLinkPlugin());
2832
- this.options.plugins.map((p) => p.init(this));
2797
+ this.options.plugins.forEach((p) => p.init(this));
2833
2798
  this.extractorPlugins = this.options.plugins.filter((p) => p.type === "extractor");
2834
2799
  this.customPlugins = this.options.plugins.filter((p) => p.type === "custom");
2835
2800
  }
@@ -2889,7 +2854,7 @@ var _DisTube = class _DisTube extends import_tiny_typed_emitter2.TypedEmitter {
2889
2854
  throw new DisTubeError("INVALID_TYPE", "Discord.GuildMember", member, "options.member");
2890
2855
  }
2891
2856
  const queue = this.getQueue(voiceChannel);
2892
- const queuing = !!queue && !queue._taskQueue.hasResolveTask;
2857
+ const queuing = queue && !queue._taskQueue.hasResolveTask;
2893
2858
  if (queuing)
2894
2859
  await queue?._taskQueue.queuing(true);
2895
2860
  try {
@@ -2965,13 +2930,13 @@ ${e.message}`;
2965
2930
  const promises = filteredSongs.map(
2966
2931
  (song) => this.handler.resolve(song, { member, metadata }).catch(() => void 0)
2967
2932
  );
2968
- resolvedSongs = (await Promise.all(promises)).filter((s) => !!s);
2933
+ resolvedSongs = (await Promise.all(promises)).filter((s) => Boolean(s));
2969
2934
  } else {
2970
2935
  const resolved = [];
2971
2936
  for (const song of filteredSongs) {
2972
2937
  resolved.push(await this.handler.resolve(song, { member, metadata }).catch(() => void 0));
2973
2938
  }
2974
- resolvedSongs = resolved.filter((s) => !!s);
2939
+ resolvedSongs = resolved.filter((s) => Boolean(s));
2975
2940
  }
2976
2941
  return new Playlist(resolvedSongs, { member, properties, metadata });
2977
2942
  }
@@ -3000,7 +2965,7 @@ ${e.message}`;
3000
2965
  throw new DisTubeError("INVALID_TYPE", "boolean", opts.safeSearch, "options.safeSearch");
3001
2966
  }
3002
2967
  try {
3003
- const search = await (0, import_ytsr.default)(string, opts);
2968
+ const search = await (0, import_ytsr.default)(string, { ...opts, requestOptions: { headers: { cookie: this.handler.ytCookie } } });
3004
2969
  const results = search.items.map((i) => {
3005
2970
  if (i.type === "video")
3006
2971
  return new SearchResultVideo(i);
@@ -3044,10 +3009,7 @@ ${e.message}`;
3044
3009
  * @throws {Error}
3045
3010
  */
3046
3011
  pause(guild) {
3047
- const q = this.getQueue(guild);
3048
- if (!q)
3049
- throw new DisTubeError("NO_QUEUE");
3050
- return q.pause();
3012
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).pause();
3051
3013
  }
3052
3014
  /**
3053
3015
  * Resume the guild stream
@@ -3056,10 +3018,7 @@ ${e.message}`;
3056
3018
  * @throws {Error}
3057
3019
  */
3058
3020
  resume(guild) {
3059
- const q = this.getQueue(guild);
3060
- if (!q)
3061
- throw new DisTubeError("NO_QUEUE");
3062
- return q.resume();
3021
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).resume();
3063
3022
  }
3064
3023
  /**
3065
3024
  * Stop the guild stream
@@ -3078,10 +3037,7 @@ ${e.message}`;
3078
3037
  * });
3079
3038
  */
3080
3039
  stop(guild) {
3081
- const q = this.getQueue(guild);
3082
- if (!q)
3083
- throw new DisTubeError("NO_QUEUE");
3084
- return q.stop();
3040
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).stop();
3085
3041
  }
3086
3042
  /**
3087
3043
  * Set the guild stream's volume
@@ -3099,10 +3055,7 @@ ${e.message}`;
3099
3055
  * });
3100
3056
  */
3101
3057
  setVolume(guild, percent) {
3102
- const q = this.getQueue(guild);
3103
- if (!q)
3104
- throw new DisTubeError("NO_QUEUE");
3105
- return q.setVolume(percent);
3058
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).setVolume(percent);
3106
3059
  }
3107
3060
  /**
3108
3061
  * Skip the playing song if there is a next song in the queue.
@@ -3121,10 +3074,7 @@ ${e.message}`;
3121
3074
  * });
3122
3075
  */
3123
3076
  skip(guild) {
3124
- const q = this.getQueue(guild);
3125
- if (!q)
3126
- throw new DisTubeError("NO_QUEUE");
3127
- return q.skip();
3077
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).skip();
3128
3078
  }
3129
3079
  /**
3130
3080
  * Play the previous song
@@ -3141,10 +3091,7 @@ ${e.message}`;
3141
3091
  * });
3142
3092
  */
3143
3093
  previous(guild) {
3144
- const q = this.getQueue(guild);
3145
- if (!q)
3146
- throw new DisTubeError("NO_QUEUE");
3147
- return q.previous();
3094
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).previous();
3148
3095
  }
3149
3096
  /**
3150
3097
  * Shuffle the guild queue songs
@@ -3160,10 +3107,7 @@ ${e.message}`;
3160
3107
  * });
3161
3108
  */
3162
3109
  shuffle(guild) {
3163
- const q = this.getQueue(guild);
3164
- if (!q)
3165
- throw new DisTubeError("NO_QUEUE");
3166
- return q.shuffle();
3110
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).shuffle();
3167
3111
  }
3168
3112
  /**
3169
3113
  * Jump to the song number in the queue.
@@ -3184,10 +3128,7 @@ ${e.message}`;
3184
3128
  * });
3185
3129
  */
3186
3130
  jump(guild, num) {
3187
- const q = this.getQueue(guild);
3188
- if (!q)
3189
- throw new DisTubeError("NO_QUEUE");
3190
- return q.jump(num);
3131
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).jump(num);
3191
3132
  }
3192
3133
  /**
3193
3134
  * Set the repeat mode of the guild queue.\
@@ -3223,10 +3164,7 @@ ${e.message}`;
3223
3164
  * message.channel.send("Set repeat mode to `" + mode + "`");
3224
3165
  */
3225
3166
  setRepeatMode(guild, mode) {
3226
- const q = this.getQueue(guild);
3227
- if (!q)
3228
- throw new DisTubeError("NO_QUEUE");
3229
- return q.setRepeatMode(mode);
3167
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).setRepeatMode(mode);
3230
3168
  }
3231
3169
  /**
3232
3170
  * Toggle autoplay mode
@@ -3245,11 +3183,9 @@ ${e.message}`;
3245
3183
  * });
3246
3184
  */
3247
3185
  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;
3186
+ const queue = __privateMethod(this, _getQueue, getQueue_fn).call(this, guild);
3187
+ queue.autoplay = !queue.autoplay;
3188
+ return queue.autoplay;
3253
3189
  }
3254
3190
  /**
3255
3191
  * Add related song to the queue
@@ -3257,10 +3193,7 @@ ${e.message}`;
3257
3193
  * @returns {Promise<Song>} The guild queue
3258
3194
  */
3259
3195
  addRelatedSong(guild) {
3260
- const q = this.getQueue(guild);
3261
- if (!q)
3262
- throw new DisTubeError("NO_QUEUE");
3263
- return q.addRelatedSong();
3196
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).addRelatedSong();
3264
3197
  }
3265
3198
  /**
3266
3199
  * Set the playing time to another position
@@ -3277,10 +3210,7 @@ ${e.message}`;
3277
3210
  * });
3278
3211
  */
3279
3212
  seek(guild, time) {
3280
- const q = this.getQueue(guild);
3281
- if (!q)
3282
- throw new DisTubeError("NO_QUEUE");
3283
- return q.seek(time);
3213
+ return __privateMethod(this, _getQueue, getQueue_fn).call(this, guild).seek(time);
3284
3214
  }
3285
3215
  /**
3286
3216
  * Emit error event
@@ -3300,6 +3230,13 @@ ${e.message}`;
3300
3230
  }
3301
3231
  }
3302
3232
  };
3233
+ _getQueue = new WeakSet();
3234
+ getQueue_fn = /* @__PURE__ */ __name(function(guild) {
3235
+ const queue = this.getQueue(guild);
3236
+ if (!queue)
3237
+ throw new DisTubeError("NO_QUEUE");
3238
+ return queue;
3239
+ }, "#getQueue");
3303
3240
  __name(_DisTube, "DisTube");
3304
3241
  var DisTube = _DisTube;
3305
3242
  // Annotate the CommonJS export names for ESM import in node:
@@ -3347,6 +3284,7 @@ var DisTube = _DisTube;
3347
3284
  isSnowflake,
3348
3285
  isSupportedVoiceChannel,
3349
3286
  isTextChannelInstance,
3287
+ isTruthy,
3350
3288
  isURL,
3351
3289
  isVoiceChannelEmpty,
3352
3290
  objectKeys,