distube 3.0.6 → 3.2.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.
Files changed (107) hide show
  1. package/dist/DisTube.d.ts +133 -65
  2. package/dist/DisTube.d.ts.map +1 -1
  3. package/dist/DisTube.js +161 -103
  4. package/dist/DisTube.js.map +1 -1
  5. package/dist/constant.d.ts +13 -14
  6. package/dist/constant.d.ts.map +1 -1
  7. package/dist/constant.js +13 -14
  8. package/dist/constant.js.map +1 -1
  9. package/dist/core/DisTubeBase.d.ts +3 -4
  10. package/dist/core/DisTubeBase.d.ts.map +1 -1
  11. package/dist/core/DisTubeBase.js +1 -2
  12. package/dist/core/DisTubeBase.js.map +1 -1
  13. package/dist/core/DisTubeHandler.d.ts +37 -25
  14. package/dist/core/DisTubeHandler.d.ts.map +1 -1
  15. package/dist/core/DisTubeHandler.js +72 -68
  16. package/dist/core/DisTubeHandler.js.map +1 -1
  17. package/dist/core/DisTubeOptions.d.ts +1 -2
  18. package/dist/core/DisTubeOptions.d.ts.map +1 -1
  19. package/dist/core/DisTubeOptions.js +64 -58
  20. package/dist/core/DisTubeOptions.js.map +1 -1
  21. package/dist/core/DisTubeStream.d.ts +1 -1
  22. package/dist/core/DisTubeStream.d.ts.map +1 -1
  23. package/dist/core/DisTubeStream.js +0 -1
  24. package/dist/core/DisTubeStream.js.map +1 -1
  25. package/dist/core/index.d.ts +2 -2
  26. package/dist/core/index.d.ts.map +1 -1
  27. package/dist/core/index.js +2 -2
  28. package/dist/core/index.js.map +1 -1
  29. package/dist/core/manager/BaseManager.d.ts +11 -7
  30. package/dist/core/manager/BaseManager.d.ts.map +1 -1
  31. package/dist/core/manager/BaseManager.js +11 -13
  32. package/dist/core/manager/BaseManager.js.map +1 -1
  33. package/dist/core/manager/QueueManager.d.ts +11 -38
  34. package/dist/core/manager/QueueManager.d.ts.map +1 -1
  35. package/dist/core/manager/QueueManager.js +115 -129
  36. package/dist/core/manager/QueueManager.js.map +1 -1
  37. package/dist/core/voice/DJSAdapter.js +4 -7
  38. package/dist/core/voice/DJSAdapter.js.map +1 -1
  39. package/dist/core/voice/DisTubeVoice.d.ts +10 -13
  40. package/dist/core/voice/DisTubeVoice.d.ts.map +1 -1
  41. package/dist/core/voice/DisTubeVoice.js +39 -28
  42. package/dist/core/voice/DisTubeVoice.js.map +1 -1
  43. package/dist/core/voice/DisTubeVoiceManager.d.ts +10 -10
  44. package/dist/core/voice/DisTubeVoiceManager.d.ts.map +1 -1
  45. package/dist/core/voice/DisTubeVoiceManager.js +5 -5
  46. package/dist/core/voice/DisTubeVoiceManager.js.map +1 -1
  47. package/dist/index.d.ts +1 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +2 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/plugin/http.d.ts +5 -3
  52. package/dist/plugin/http.d.ts.map +1 -1
  53. package/dist/plugin/http.js +3 -5
  54. package/dist/plugin/http.js.map +1 -1
  55. package/dist/plugin/https.d.ts +10 -5
  56. package/dist/plugin/https.d.ts.map +1 -1
  57. package/dist/plugin/https.js +6 -9
  58. package/dist/plugin/https.js.map +1 -1
  59. package/dist/plugin/youtube-dl.d.ts +5 -4
  60. package/dist/plugin/youtube-dl.d.ts.map +1 -1
  61. package/dist/plugin/youtube-dl.js +6 -11
  62. package/dist/plugin/youtube-dl.js.map +1 -1
  63. package/dist/struct/CustomPlugin.d.ts +37 -17
  64. package/dist/struct/CustomPlugin.d.ts.map +1 -1
  65. package/dist/struct/CustomPlugin.js +18 -19
  66. package/dist/struct/CustomPlugin.js.map +1 -1
  67. package/dist/struct/DisTubeError.d.ts +4 -3
  68. package/dist/struct/DisTubeError.d.ts.map +1 -1
  69. package/dist/struct/DisTubeError.js +5 -7
  70. package/dist/struct/DisTubeError.js.map +1 -1
  71. package/dist/struct/ExtractorPlugin.d.ts +25 -15
  72. package/dist/struct/ExtractorPlugin.d.ts.map +1 -1
  73. package/dist/struct/ExtractorPlugin.js +14 -16
  74. package/dist/struct/ExtractorPlugin.js.map +1 -1
  75. package/dist/struct/Playlist.d.ts +24 -8
  76. package/dist/struct/Playlist.d.ts.map +1 -1
  77. package/dist/struct/Playlist.js +27 -14
  78. package/dist/struct/Playlist.js.map +1 -1
  79. package/dist/struct/Plugin.d.ts +4 -12
  80. package/dist/struct/Plugin.d.ts.map +1 -1
  81. package/dist/struct/Plugin.js +1 -11
  82. package/dist/struct/Plugin.js.map +1 -1
  83. package/dist/struct/Queue.d.ts +5 -6
  84. package/dist/struct/Queue.d.ts.map +1 -1
  85. package/dist/struct/Queue.js +5 -9
  86. package/dist/struct/Queue.js.map +1 -1
  87. package/dist/struct/SearchResult.d.ts +0 -1
  88. package/dist/struct/SearchResult.d.ts.map +1 -1
  89. package/dist/struct/SearchResult.js +2 -4
  90. package/dist/struct/SearchResult.js.map +1 -1
  91. package/dist/struct/Song.d.ts +26 -10
  92. package/dist/struct/Song.d.ts.map +1 -1
  93. package/dist/struct/Song.js +37 -25
  94. package/dist/struct/Song.js.map +1 -1
  95. package/dist/struct/TaskQueue.d.ts +1 -6
  96. package/dist/struct/TaskQueue.d.ts.map +1 -1
  97. package/dist/struct/TaskQueue.js +13 -7
  98. package/dist/struct/TaskQueue.js.map +1 -1
  99. package/dist/tsconfig.tsbuildinfo +1 -1
  100. package/dist/type.d.ts +12 -12
  101. package/dist/type.d.ts.map +1 -1
  102. package/dist/type.js.map +1 -1
  103. package/dist/util.d.ts +6 -6
  104. package/dist/util.d.ts.map +1 -1
  105. package/dist/util.js +9 -15
  106. package/dist/util.js.map +1 -1
  107. package/package.json +5 -6
package/dist/DisTube.js CHANGED
@@ -3,12 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DisTube = void 0;
6
+ exports.DisTube = exports.version = void 0;
7
7
  const ytpl_1 = __importDefault(require("@distube/ytpl"));
8
8
  const ytsr_1 = __importDefault(require("@distube/ytsr"));
9
9
  const util_1 = require("./util");
10
10
  const tiny_typed_emitter_1 = require("tiny-typed-emitter");
11
11
  const _1 = require(".");
12
+ // TODO: remove deprecated stuff on the next major version
13
+ // Cannot be `import` as it's not under TS root dir
14
+ // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
15
+ exports.version = require("../package.json").version;
12
16
  /**
13
17
  * DisTube class
14
18
  * @extends EventEmitter
@@ -83,70 +87,49 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
83
87
  */
84
88
  this.customPlugins = this.options.plugins.filter((p) => p.type === "custom");
85
89
  }
86
- /**
87
- * Shorthand method for {@link DisTube#playVoiceChannel}
88
- * @returns {Promise<void>}
89
- * @param {Discord.Message} message A message from guild channel
90
- * @param {string|Song|SearchResult|Playlist} song URL | Search string |
91
- * {@link Song} | {@link SearchResult} | {@link Playlist}
92
- * @param {Object} [options] Optional options
93
- * @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
94
- * @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
95
- * (after the playing song if exists)
96
- * @example
97
- * client.on('message', (message) => {
98
- * if (!message.content.startsWith(config.prefix)) return;
99
- * const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
100
- * const command = args.shift();
101
- * if (command == "play")
102
- * distube.play(message, args.join(" "));
103
- * });
104
- */
105
- async play(message, song, options = {}) {
106
- if (!song)
107
- throw new _1.DisTubeError("INVALID_TYPE", ["string", "Song", "SearchResult", "Playlist"], song, "song");
108
- if (!(0, _1.isMessageInstance)(message))
109
- throw new _1.DisTubeError("INVALID_TYPE", "Discord.Message", message, "message");
110
- if (typeof options !== "object" || Array.isArray(options)) {
111
- throw new _1.DisTubeError("INVALID_TYPE", "object", options, "options");
112
- }
113
- const textChannel = message.channel;
114
- const { skip, unshift } = Object.assign({ skip: false, unshift: false }, options);
115
- const member = message.member;
116
- const voiceChannel = member.voice.channel;
117
- if (!voiceChannel)
118
- throw new _1.DisTubeError("NOT_IN_VOICE");
119
- await this.playVoiceChannel(voiceChannel, song, {
120
- member,
121
- textChannel,
122
- skip,
123
- message,
124
- unshift,
125
- });
90
+ static get version() {
91
+ return exports.version;
126
92
  }
127
93
  /**
128
- * Play / add a song or playlist from url. Search and play a song if it is not a valid url.
129
- * Emit {@link DisTube#addList}, {@link DisTube#addSong} or {@link DisTube#playSong} after executing
130
- * @returns {Promise<void>}
131
- * @param {Discord.VoiceChannel|Discord.StageChannel} voiceChannel The voice channel will be joined
132
- * @param {string|Song|SearchResult|Playlist} song URL | Search string |
133
- * {@link Song} | {@link SearchResult} | {@link Playlist}
134
- * @param {Object} [options] Optional options
135
- * @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
136
- * @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
137
- * (after the playing song if exists)
138
- * @param {Discord.GuildMember} [options.member] Requested user (default is your bot)
139
- * @param {Discord.TextChannel} [options.textChannel] Default {@link Queue#textChannel} (if the queue wasn't created)
140
- * @param {Discord.Message} [options.message] Called message (For built-in search events. If this is a {@link https://developer.mozilla.org/en-US/docs/Glossary/Falsy|falsy value}, it will play the first result instead)
94
+ * DisTube version
95
+ * @type {string}
141
96
  */
142
- async playVoiceChannel(voiceChannel, song, options = {}) {
143
- var _a;
144
- if (!(0, _1.isSupportedVoiceChannel)(voiceChannel))
145
- throw new _1.DisTubeError("NOT_SUPPORTED_VOICE");
97
+ get version() {
98
+ return exports.version;
99
+ }
100
+ async play(voiceChannel, song, options = {}) {
101
+ if ((0, _1.isMessageInstance)(voiceChannel)) {
102
+ process.emitWarning("Passing Message for DisTube#play is deprecated, use VoiceBasedChannel instead.", "DeprecationWarning");
103
+ const message = voiceChannel;
104
+ if (!song)
105
+ throw new _1.DisTubeError("INVALID_TYPE", ["string", "Song", "SearchResult", "Playlist"], song, "song");
106
+ if (!(0, _1.isMessageInstance)(message))
107
+ throw new _1.DisTubeError("INVALID_TYPE", "Discord.Message", message, "message");
108
+ if (typeof options !== "object" || Array.isArray(options)) {
109
+ throw new _1.DisTubeError("INVALID_TYPE", "object", options, "options");
110
+ }
111
+ const textChannel = message.channel;
112
+ const { skip, unshift, metadata } = Object.assign({ skip: false, unshift: false }, options);
113
+ const member = message.member;
114
+ const vc = member.voice.channel;
115
+ if (!vc)
116
+ throw new _1.DisTubeError("NOT_IN_VOICE");
117
+ return this.play(vc, song, {
118
+ member,
119
+ textChannel,
120
+ skip,
121
+ message,
122
+ unshift,
123
+ metadata,
124
+ });
125
+ }
126
+ if (!(0, _1.isSupportedVoiceChannel)(voiceChannel)) {
127
+ throw new _1.DisTubeError("INVALID_TYPE", "BaseGuildVoiceChannel", voiceChannel, "voiceChannel");
128
+ }
146
129
  if (typeof options !== "object" || Array.isArray(options)) {
147
130
  throw new _1.DisTubeError("INVALID_TYPE", "object", options, "options");
148
131
  }
149
- const { textChannel, member, skip, message, unshift } = Object.assign({
132
+ const { textChannel, member, skip, message, unshift, metadata } = Object.assign({
150
133
  member: voiceChannel.guild.me,
151
134
  skip: false,
152
135
  unshift: false,
@@ -158,32 +141,33 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
158
141
  if (typeof song === "string") {
159
142
  for (const plugin of this.customPlugins) {
160
143
  if (await plugin.validate(song)) {
161
- return plugin.play(voiceChannel, song, member, textChannel, skip, unshift);
144
+ return plugin.play(voiceChannel, song, options);
162
145
  }
163
146
  }
164
147
  }
165
148
  let queue = this.getQueue(voiceChannel);
166
- const queuing = queue && !queue.taskQueue.hasResolveTask;
149
+ const queuing = !!queue && !queue.taskQueue.hasResolveTask;
167
150
  if (queuing)
168
- await (queue === null || queue === void 0 ? void 0 : queue.taskQueue.queuing(true));
151
+ await queue?.taskQueue.queuing(true);
169
152
  try {
170
153
  if (song instanceof _1.SearchResult && song.type === "playlist")
171
154
  song = song.url;
172
- if (typeof song === "string" && ytpl_1.default.validateID(song))
173
- song = await this.handler.resolvePlaylist(member, song);
155
+ if (typeof song === "string" && ytpl_1.default.validateID(song)) {
156
+ song = await this.handler.resolvePlaylist(song, { member, metadata });
157
+ }
174
158
  if (typeof song === "string" && !(0, util_1.isURL)(song)) {
175
159
  if (!message)
176
160
  song = (await this.search(song, { limit: 1 }))[0];
177
161
  else
178
162
  song = await this.handler.searchSong(message, song);
179
163
  }
180
- song = await this.handler.resolveSong(member, song);
164
+ song = await this.handler.resolveSong(song, { member, metadata });
181
165
  if (!song)
182
166
  return;
183
167
  if (song instanceof _1.Playlist) {
184
- await this.handler.handlePlaylist(voiceChannel, song, textChannel, skip, unshift);
168
+ await this.handler.handlePlaylist(voiceChannel, song, { textChannel, skip, unshift });
185
169
  }
186
- else if (!this.options.nsfw && song.age_restricted && !(textChannel === null || textChannel === void 0 ? void 0 : textChannel.nsfw)) {
170
+ else if (!this.options.nsfw && song.age_restricted && !textChannel?.nsfw) {
187
171
  throw new _1.DisTubeError("NON_NSFW");
188
172
  }
189
173
  else {
@@ -196,7 +180,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
196
180
  this.emit("addSong", queue, song);
197
181
  }
198
182
  else {
199
- const newQueue = await this.handler.createQueue(voiceChannel, song, textChannel);
183
+ const newQueue = await this.queues.create(voiceChannel, song, textChannel);
200
184
  if (newQueue instanceof _1.Queue) {
201
185
  if (this.options.emitAddSongWhenCreatingQueue)
202
186
  this.emit("addSong", newQueue, song);
@@ -207,14 +191,14 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
207
191
  }
208
192
  finally {
209
193
  if (queuing)
210
- queue === null || queue === void 0 ? void 0 : queue.taskQueue.resolve();
194
+ queue?.taskQueue.resolve();
211
195
  }
212
196
  }
213
197
  catch (e) {
214
198
  if (!(e instanceof _1.DisTubeError)) {
215
199
  try {
216
200
  e.name = "PlayError";
217
- e.message = `${((_a = song) === null || _a === void 0 ? void 0 : _a.url) || song}\n${e.message}`;
201
+ e.message = `${song?.url || song}\n${e.message}`;
218
202
  }
219
203
  catch { }
220
204
  }
@@ -222,10 +206,79 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
222
206
  }
223
207
  }
224
208
  /**
225
- * <info>Shorthand method of {@link DisTubeHandler#createCustomPlaylist} and {@link DisTube#playVoiceChannel}
209
+ * Play / add a song or playlist from url. Search and play a song if it is not a valid url.
210
+ *
211
+ * @returns {Promise<void>}
212
+ * @param {Discord.BaseGuildVoiceChannel} voiceChannel The voice channel will be joined
213
+ * @param {string|Song|SearchResult|Playlist} song URL | Search string |
214
+ * {@link Song} | {@link SearchResult} | {@link Playlist}
215
+ * @param {Object} [options] Optional options
216
+ * @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
217
+ * @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
218
+ * (after the playing song if exists)
219
+ * @param {Discord.GuildMember} [options.member] Requested user (default is your bot)
220
+ * @param {Discord.BaseGuildTextChannel} [options.textChannel] Default {@link Queue#textChannel}
221
+ * @param {Discord.Message} [options.message] Called message (For built-in search events. If this is a {@link https://developer.mozilla.org/en-US/docs/Glossary/Falsy|falsy value}, it will play the first result instead)
222
+ * @param {*} [options.metadata] Optional metadata that can be attached to the song/playlist will be played,
223
+ * This is useful for identification purposes when the song/playlist is passed around in events.
224
+ * See {@link Song#metadata} or {@link Playlist#metadata}
225
+ * @deprecated Use {@link DisTube#play} instead
226
+ */
227
+ async playVoiceChannel(voiceChannel, song, options = {}) {
228
+ process.emitWarning("DisTube#playVoiceChannel is deprecated, use DisTube#play instead.", "DeprecationWarning");
229
+ return this.play(voiceChannel, song, options);
230
+ }
231
+ /**
232
+ * Create a custom playlist
233
+ * @returns {Promise<Playlist>}
234
+ * @param {Array<string|Song|SearchResult>} songs Array of url, Song or SearchResult
235
+ * @param {Object} [options] Optional options
236
+ * @param {Discord.GuildMember} [options.message] A message from guild channel | A guild member
237
+ * @param {Object} [options.properties={}] Additional properties such as `name`
238
+ * @param {boolean} [options.parallel=true] Whether or not fetch the songs in parallel
239
+ * @param {*} [options.metadata] Metadata
240
+ * @example
241
+ * const songs = ["https://www.youtube.com/watch?v=xxx", "https://www.youtube.com/watch?v=yyy"];
242
+ * const playlist = await distube.createCustomPlaylist(songs, {
243
+ * member: message.member,
244
+ * properties: { name: "My playlist name" },
245
+ * parallel: true
246
+ * });
247
+ * distube.play(voiceChannel, playlist, { ... });
248
+ */
249
+ async createCustomPlaylist(songs, options = {}) {
250
+ const { member, properties, parallel, metadata } = Object.assign({ parallel: true }, options);
251
+ if (!Array.isArray(songs))
252
+ throw new _1.DisTubeError("INVALID_TYPE", "Array", songs, "songs");
253
+ if (!songs.length)
254
+ throw new _1.DisTubeError("EMPTY_ARRAY", "songs");
255
+ const filteredSongs = songs.filter(song => song instanceof _1.Song || (song instanceof _1.SearchResult && song.type === "video") || (0, util_1.isURL)(song));
256
+ if (!filteredSongs.length)
257
+ throw new _1.DisTubeError("NO_VALID_SONG");
258
+ if (member && !(0, _1.isMemberInstance)(member)) {
259
+ throw new _1.DisTubeError("INVALID_TYPE", "Discord.Member", member, "options.member");
260
+ }
261
+ if (!filteredSongs.length)
262
+ throw new _1.DisTubeError("NO_VALID_SONG");
263
+ let resolvedSongs;
264
+ if (parallel) {
265
+ const promises = filteredSongs.map((song) => this.handler.resolveSong(song, { member, metadata }).catch(() => undefined));
266
+ resolvedSongs = (await Promise.all(promises)).filter((s) => !!s);
267
+ }
268
+ else {
269
+ const resolved = [];
270
+ for (const song of filteredSongs) {
271
+ resolved.push(await this.handler.resolveSong(song, { member, metadata }).catch(() => undefined));
272
+ }
273
+ resolvedSongs = resolved.filter((s) => !!s);
274
+ }
275
+ return new _1.Playlist(resolvedSongs, { member, properties, metadata });
276
+ }
277
+ /**
278
+ * <info>Shorthand method of {@link DisTube#createCustomPlaylist} and {@link DisTube#play}
226
279
  *
227
280
  * If you doesn't have a user message (interaction,...),
228
- * see {@link DisTubeHandler#createCustomPlaylist} example</info>
281
+ * see {@link DisTube#createCustomPlaylist} example</info>
229
282
  *
230
283
  * Play or add array of video urls.
231
284
  * {@link DisTube#event:playSong} or {@link DisTube#event:addList} will be emitted
@@ -234,24 +287,21 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
234
287
  * @returns {Promise<void>}
235
288
  * @param {Discord.Message} message A message from guild channel
236
289
  * @param {Array<string|Song|SearchResult>} songs Array of url, Song or SearchResult
237
- * @param {Object} [properties={}] Additional properties such as `name`
290
+ * @param {Object} [properties={}] Additional properties for playlist such as `name`
238
291
  * @param {Object} [options] Optional options
239
292
  * @param {boolean} [options.skip=false] Skip the playing song (if exists) and play the added song/playlist instantly
240
293
  * @param {boolean} [options.unshift=false] Add the song/playlist to the beginning of the queue
241
294
  * (after the playing song if exists)
242
295
  * @param {boolean} [options.parallel=true] Whether or not fetch the songs in parallel
243
- * @example
244
- * const songs = ["https://www.youtube.com/watch?v=xxx", "https://www.youtube.com/watch?v=yyy"];
245
- * distube.playCustomPlaylist(message, songs, { name: "My playlist name" });
246
- * // Fetching custom playlist sequentially (reduce lag for low specs)
247
- * distube.playCustomPlaylist(message, songs, { name: "My playlist name" }, false, false);
296
+ * @deprecated Use {@link DisTube#createCustomPlaylist} and {@link DisTube#play} instead
248
297
  */
249
298
  async playCustomPlaylist(message, songs, properties = {}, options = {}) {
299
+ process.emitWarning("DisTube#playCustomPlaylist is deprecated, use DisTube#createCustomPlaylist and DisTube#play instead.", "DeprecationWarning");
250
300
  try {
251
301
  if (typeof options !== "object" || Array.isArray(options)) {
252
302
  throw new _1.DisTubeError("INVALID_TYPE", "object", options, "options");
253
303
  }
254
- const { skip, unshift, parallel } = Object.assign({
304
+ const { skip, unshift, parallel, metadata } = Object.assign({
255
305
  skip: false,
256
306
  unshift: false,
257
307
  parallel: true,
@@ -259,14 +309,22 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
259
309
  const queue = this.getQueue(message);
260
310
  const queuing = queue && !queue.taskQueue.hasResolveTask;
261
311
  if (queuing)
262
- await (queue === null || queue === void 0 ? void 0 : queue.taskQueue.queuing(true));
312
+ await queue?.taskQueue.queuing(true);
263
313
  try {
264
- const playlist = await this.handler.createCustomPlaylist(message, songs, properties, parallel);
265
- await this.handler.handlePlaylist(message, playlist, message.channel, skip, unshift);
314
+ const playlist = await this.createCustomPlaylist(songs, {
315
+ member: message.member ?? undefined,
316
+ properties,
317
+ parallel,
318
+ metadata,
319
+ });
320
+ const voice = message.member?.voice?.channel;
321
+ if (!voice)
322
+ throw new _1.DisTubeError("NOT_IN_VOICE");
323
+ await this.play(voice, playlist, { textChannel: message.channel, skip, unshift, metadata });
266
324
  }
267
325
  finally {
268
326
  if (queuing)
269
- queue === null || queue === void 0 ? void 0 : queue.taskQueue.resolve();
327
+ queue?.taskQueue.resolve();
270
328
  }
271
329
  }
272
330
  catch (e) {
@@ -274,9 +332,9 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
274
332
  }
275
333
  }
276
334
  /**
277
- * Search for a song.
278
- * You can customize how user answers instead of send a number.
279
- * Then use {@link DisTube#play} or {@link DisTube#playVoiceChannel} to play it.
335
+ * Search for a song. You can customize how user answers instead of send a number.
336
+ * Then use {@link DisTube#play} to play it.
337
+ *
280
338
  * @param {string} string The string search for
281
339
  * @param {Object} options Search options
282
340
  * @param {number} [options.limit=10] Limit the results
@@ -313,7 +371,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
313
371
  }
314
372
  /**
315
373
  * Get the guild queue
316
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
374
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
317
375
  * @returns {Queue?}
318
376
  * @throws {Error}
319
377
  * @example
@@ -334,7 +392,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
334
392
  }
335
393
  /**
336
394
  * Pause the guild stream
337
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
395
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
338
396
  * @returns {Queue} The guild queue
339
397
  * @throws {Error}
340
398
  */
@@ -346,7 +404,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
346
404
  }
347
405
  /**
348
406
  * Resume the guild stream
349
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
407
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
350
408
  * @returns {Queue} The guild queue
351
409
  * @throws {Error}
352
410
  */
@@ -358,7 +416,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
358
416
  }
359
417
  /**
360
418
  * Stop the guild stream
361
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
419
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
362
420
  * @returns {Promise<void>}
363
421
  * @throws {Error}
364
422
  * @example
@@ -380,7 +438,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
380
438
  }
381
439
  /**
382
440
  * Set the guild stream's volume
383
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
441
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
384
442
  * @param {number} percent The percentage of volume you want to set
385
443
  * @returns {Queue} The guild queue
386
444
  * @throws {Error}
@@ -403,7 +461,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
403
461
  * Skip the playing song if there is a next song in the queue.
404
462
  * <info>If {@link Queue#autoplay} is `true` and there is no up next song,
405
463
  * DisTube will add and play a related song.</info>
406
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
464
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
407
465
  * @returns {Promise<Song>} The new Song will be played
408
466
  * @throws {Error}
409
467
  * @example
@@ -423,7 +481,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
423
481
  }
424
482
  /**
425
483
  * Play the previous song
426
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
484
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
427
485
  * @returns {Promise<Song>} The new Song will be played
428
486
  * @throws {Error}
429
487
  * @example
@@ -443,7 +501,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
443
501
  }
444
502
  /**
445
503
  * Shuffle the guild queue songs
446
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
504
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
447
505
  * @returns {Promise<Queue>} The guild queue
448
506
  * @example
449
507
  * client.on('message', (message) => {
@@ -464,7 +522,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
464
522
  * Jump to the song number in the queue.
465
523
  * The next one is 1, 2,...
466
524
  * The previous one is -1, -2,...
467
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
525
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
468
526
  * @param {number} num The song number to play
469
527
  * @returns {Promise<Queue>} The guild queue
470
528
  * @throws {Error} if `num` is invalid number (0 < num < {@link Queue#songs}.length)
@@ -487,7 +545,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
487
545
  /**
488
546
  * Set the repeat mode of the guild queue.\
489
547
  * Toggle mode `(Disabled -> Song -> Queue -> Disabled ->...)` if `mode` is `undefined`
490
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
548
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
491
549
  * @param {RepeatMode?} [mode] The repeat modes (toggle if `undefined`)
492
550
  * @returns {RepeatMode} The new repeat mode
493
551
  * @example
@@ -525,7 +583,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
525
583
  }
526
584
  /**
527
585
  * Toggle autoplay mode
528
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
586
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
529
587
  * @returns {boolean} Autoplay mode state
530
588
  * @throws {Error}
531
589
  * @example
@@ -548,7 +606,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
548
606
  }
549
607
  /**
550
608
  * Add related song to the queue
551
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
609
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
552
610
  * @returns {Promise<Song>} The guild queue
553
611
  */
554
612
  addRelatedSong(queue) {
@@ -560,7 +618,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
560
618
  /**
561
619
  * Enable or disable filter(s) of the queue.
562
620
  * Available filters: {@link Filters}
563
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
621
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
564
622
  * @param {string|false} filter A filter name, `false` to clear all the filters
565
623
  * @param {boolean} [force=false] Force enable the input filter(s) even if it's enabled
566
624
  * @returns {Array<string>} Enabled filters.
@@ -583,7 +641,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
583
641
  }
584
642
  /**
585
643
  * Set the playing time to another position
586
- * @param {GuildIDResolvable} queue The type can be resolved to give a {@link Queue}
644
+ * @param {GuildIdResolvable} queue The type can be resolved to give a {@link Queue}
587
645
  * @param {number} time Time in seconds
588
646
  * @returns {Queue} Seeked queue
589
647
  * @example
@@ -605,7 +663,7 @@ class DisTube extends tiny_typed_emitter_1.TypedEmitter {
605
663
  /**
606
664
  * Emit error event
607
665
  * @param {Error} error error
608
- * @param {Discord.TextChannel?} channel Text channel where the error is encountered.
666
+ * @param {Discord.BaseGuildTextChannel} [channel] Text channel where the error is encountered.
609
667
  * @private
610
668
  */
611
669
  emitError(error, channel) {
@@ -662,7 +720,7 @@ exports.default = DisTube;
662
720
  * Emitted when DisTube encounters an error.
663
721
  *
664
722
  * @event DisTube#error
665
- * @param {Discord.TextChannel} channel Text channel where the error is encountered.
723
+ * @param {Discord.BaseGuildTextChannel} channel Text channel where the error is encountered.
666
724
  * @param {Error} error The error encountered
667
725
  * @example
668
726
  * distube.on("error", (channel, error) => channel.send(
@@ -723,7 +781,7 @@ exports.default = DisTube;
723
781
  */
724
782
  /**
725
783
  * Emitted when {@link DisTubeOptions|DisTubeOptions.searchSongs} bigger than 0,
726
- * and song param of {@link DisTube#playVoiceChannel} is invalid url.
784
+ * and song param of {@link DisTube#play} is invalid url.
727
785
  * DisTube will wait for user's next message to choose a song manually.
728
786
  * <info>{@link https://support.google.com/youtube/answer/7354993|Safe search} is enabled
729
787
  * if {@link DisTubeOptions}.nsfw is disabled and the message's channel is not a nsfw channel.</info>